mirror of
https://github.com/dart-lang/sdk
synced 2024-09-05 16:41:07 +00:00
Remove fluent check().
Change-Id: I6f41efb2432ebd4a6a03638d5db0937f20386200 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/261440 Commit-Queue: Konstantin Shcheglov <scheglov@google.com> Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
This commit is contained in:
parent
798c57bef9
commit
dd63e54e2c
|
@ -3,16 +3,6 @@
|
||||||
// BSD-style license that can be found in the LICENSE file.
|
// BSD-style license that can be found in the LICENSE file.
|
||||||
|
|
||||||
import 'package:analysis_server/src/protocol_server.dart';
|
import 'package:analysis_server/src/protocol_server.dart';
|
||||||
import 'package:analyzer/dart/ast/token.dart';
|
|
||||||
import 'package:analyzer_utilities/check/check.dart';
|
|
||||||
import 'package:meta/meta.dart';
|
|
||||||
|
|
||||||
typedef CompletionSuggestionChecker = void Function(
|
|
||||||
CompletionSuggestionTarget suggestion,
|
|
||||||
);
|
|
||||||
|
|
||||||
typedef CompletionSuggestionTarget
|
|
||||||
= CheckTarget<CompletionSuggestionForTesting>;
|
|
||||||
|
|
||||||
class CompletionResponseForTesting {
|
class CompletionResponseForTesting {
|
||||||
final int requestOffset;
|
final int requestOffset;
|
||||||
|
@ -42,602 +32,3 @@ class CompletionResponseForTesting {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A completion suggestion with the response for context.
|
|
||||||
class CompletionSuggestionForTesting {
|
|
||||||
final CompletionResponseForTesting response;
|
|
||||||
final CompletionSuggestion suggestion;
|
|
||||||
|
|
||||||
CompletionSuggestionForTesting({
|
|
||||||
required this.response,
|
|
||||||
required this.suggestion,
|
|
||||||
});
|
|
||||||
|
|
||||||
/// Return the effective replacement length.
|
|
||||||
int get replacementLength =>
|
|
||||||
suggestion.replacementLength ?? response.replacementLength;
|
|
||||||
|
|
||||||
/// Return the effective replacement offset.
|
|
||||||
int get replacementOffset =>
|
|
||||||
suggestion.replacementOffset ?? response.replacementOffset;
|
|
||||||
|
|
||||||
@override
|
|
||||||
String toString() => '(completion: ${suggestion.completion})';
|
|
||||||
}
|
|
||||||
|
|
||||||
extension CompletionResponseExtension
|
|
||||||
on CheckTarget<CompletionResponseForTesting> {
|
|
||||||
@useResult
|
|
||||||
CheckTarget<bool> get isIncomplete {
|
|
||||||
return nest(
|
|
||||||
value.isIncomplete,
|
|
||||||
(selected) => 'has isIncomplete ${valueStr(selected)}',
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@useResult
|
|
||||||
CheckTarget<int> get replacementLength {
|
|
||||||
return nest(
|
|
||||||
value.replacementLength,
|
|
||||||
(selected) => 'has replacementLength ${valueStr(selected)}',
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@useResult
|
|
||||||
CheckTarget<int> get replacementOffset {
|
|
||||||
return nest(
|
|
||||||
value.replacementOffset,
|
|
||||||
(selected) => 'has replacementOffset ${valueStr(selected)}',
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@useResult
|
|
||||||
CheckTarget<List<CompletionSuggestionForTesting>> get suggestions {
|
|
||||||
var suggestions = value.suggestions.map((e) {
|
|
||||||
return CompletionSuggestionForTesting(
|
|
||||||
response: value,
|
|
||||||
suggestion: e,
|
|
||||||
);
|
|
||||||
}).toList();
|
|
||||||
return nest(
|
|
||||||
suggestions,
|
|
||||||
(selected) => 'suggestions ${valueStr(selected)}',
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
void assertComplete() {
|
|
||||||
isIncomplete.isFalse;
|
|
||||||
}
|
|
||||||
|
|
||||||
void assertIncomplete() {
|
|
||||||
isIncomplete.isTrue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Check that the replacement offset is the completion request offset,
|
|
||||||
/// and the length of the replacement is zero.
|
|
||||||
void hasEmptyReplacement() {
|
|
||||||
hasReplacement(left: 0, right: 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Check that the replacement offset is the completion request offset
|
|
||||||
/// minus [left], and the length of the replacement is `left + right`.
|
|
||||||
void hasReplacement({int left = 0, int right = 0}) {
|
|
||||||
replacementOffset.isEqualTo(value.requestOffset - left);
|
|
||||||
replacementLength.isEqualTo(left + right);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extension CompletionSuggestionExtension
|
|
||||||
on CheckTarget<CompletionSuggestionForTesting> {
|
|
||||||
@useResult
|
|
||||||
CheckTarget<String> get completion {
|
|
||||||
return nest(
|
|
||||||
value.suggestion.completion,
|
|
||||||
(selected) => 'has completion ${valueStr(selected)}',
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@useResult
|
|
||||||
CheckTarget<String?> get defaultArgumentListString {
|
|
||||||
return nest(
|
|
||||||
value.suggestion.defaultArgumentListString,
|
|
||||||
(selected) => 'has defaultArgumentListString ${valueStr(selected)}',
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@useResult
|
|
||||||
CheckTarget<List<int>?> get defaultArgumentListTextRanges {
|
|
||||||
return nest(
|
|
||||||
value.suggestion.defaultArgumentListTextRanges,
|
|
||||||
(selected) => 'has defaultArgumentListTextRanges ${valueStr(selected)}',
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@useResult
|
|
||||||
CheckTarget<String?> get displayText {
|
|
||||||
return nest(
|
|
||||||
value.suggestion.displayText,
|
|
||||||
(selected) => 'has displayText ${valueStr(selected)}',
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@useResult
|
|
||||||
CheckTarget<String?> get docComplete {
|
|
||||||
return nest(
|
|
||||||
value.suggestion.docComplete,
|
|
||||||
(selected) => 'has docComplete ${valueStr(selected)}',
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@useResult
|
|
||||||
CheckTarget<String?> get docSummary {
|
|
||||||
return nest(
|
|
||||||
value.suggestion.docSummary,
|
|
||||||
(selected) => 'has docSummary ${valueStr(selected)}',
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@useResult
|
|
||||||
CheckTarget<Element?> get element {
|
|
||||||
return nest(
|
|
||||||
value.suggestion.element,
|
|
||||||
(selected) => 'has element ${valueStr(selected)}',
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@useResult
|
|
||||||
CheckTarget<bool?> get hasNamedParameters {
|
|
||||||
return nest(
|
|
||||||
value.suggestion.hasNamedParameters,
|
|
||||||
(selected) => 'has hasNamedParameters ${valueStr(selected)}',
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
void get isClass {
|
|
||||||
kind.isIdentifier;
|
|
||||||
element.isNotNull.kind.isClass;
|
|
||||||
}
|
|
||||||
|
|
||||||
void get isConstructorInvocation {
|
|
||||||
kind.isInvocation;
|
|
||||||
element.isNotNull.kind.isConstructor;
|
|
||||||
}
|
|
||||||
|
|
||||||
void get isEnum {
|
|
||||||
kind.isIdentifier;
|
|
||||||
element.isNotNull.kind.isEnum;
|
|
||||||
}
|
|
||||||
|
|
||||||
void get isEnumConstant {
|
|
||||||
kind.isIdentifier;
|
|
||||||
element.isNotNull.kind.isEnumConstant;
|
|
||||||
}
|
|
||||||
|
|
||||||
void get isField {
|
|
||||||
kind.isIdentifier;
|
|
||||||
element.isNotNull.kind.isField;
|
|
||||||
}
|
|
||||||
|
|
||||||
void get isFunctionReference {
|
|
||||||
kind.isIdentifier;
|
|
||||||
element.isNotNull.kind.isFunction;
|
|
||||||
}
|
|
||||||
|
|
||||||
void get isGetter {
|
|
||||||
kind.isIdentifier;
|
|
||||||
element.isNotNull.kind.isGetter;
|
|
||||||
}
|
|
||||||
|
|
||||||
void get isImport {
|
|
||||||
kind.isImport;
|
|
||||||
}
|
|
||||||
|
|
||||||
void get isImportPrefix {
|
|
||||||
kind.isIdentifier;
|
|
||||||
element.isNotNull.kind.isPrefix;
|
|
||||||
}
|
|
||||||
|
|
||||||
void get isKeywordAny {
|
|
||||||
kind.isKeyword;
|
|
||||||
}
|
|
||||||
|
|
||||||
void get isMethodInvocation {
|
|
||||||
kind.isInvocation;
|
|
||||||
element.isNotNull.kind.isMethod;
|
|
||||||
}
|
|
||||||
|
|
||||||
void get isMixin {
|
|
||||||
kind.isIdentifier;
|
|
||||||
element.isNotNull.kind.isMixin;
|
|
||||||
}
|
|
||||||
|
|
||||||
void get isNamedArgument {
|
|
||||||
kind.isNamedArgument;
|
|
||||||
element.isNull;
|
|
||||||
}
|
|
||||||
|
|
||||||
@useResult
|
|
||||||
CheckTarget<bool?> get isNotImported {
|
|
||||||
return nest(
|
|
||||||
value.suggestion.isNotImported,
|
|
||||||
(selected) => 'has isNotImported ${valueStr(selected)}',
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
void get isParameter {
|
|
||||||
kind.isIdentifier;
|
|
||||||
element.isNotNull.kind.isParameter;
|
|
||||||
}
|
|
||||||
|
|
||||||
void get isRecordField {
|
|
||||||
kind.isIdentifier;
|
|
||||||
element.isNull;
|
|
||||||
}
|
|
||||||
|
|
||||||
void get isSetter {
|
|
||||||
kind.isIdentifier;
|
|
||||||
element.isNotNull.kind.isSetter;
|
|
||||||
}
|
|
||||||
|
|
||||||
void get isStatic {
|
|
||||||
element.isNotNull.isStatic.isTrue;
|
|
||||||
}
|
|
||||||
|
|
||||||
void get isStaticField {
|
|
||||||
isStatic;
|
|
||||||
isField;
|
|
||||||
}
|
|
||||||
|
|
||||||
void get isStaticGetter {
|
|
||||||
isStatic;
|
|
||||||
isGetter;
|
|
||||||
}
|
|
||||||
|
|
||||||
void get isTopLevelVariable {
|
|
||||||
kind.isIdentifier;
|
|
||||||
element.isNotNull.kind.isTopLevelVariable;
|
|
||||||
}
|
|
||||||
|
|
||||||
@useResult
|
|
||||||
CheckTarget<CompletionSuggestionKind> get kind {
|
|
||||||
return nest(
|
|
||||||
value.suggestion.kind,
|
|
||||||
(selected) => 'has kind ${valueStr(selected)}',
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@useResult
|
|
||||||
CheckTarget<String?> get libraryUri {
|
|
||||||
return nest(
|
|
||||||
value.suggestion.libraryUri,
|
|
||||||
(selected) => 'has libraryUri ${valueStr(selected)}',
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@useResult
|
|
||||||
CheckTarget<String?> get libraryUriToImport {
|
|
||||||
return nest(
|
|
||||||
value.suggestion.isNotImported == true
|
|
||||||
? value.suggestion.libraryUri
|
|
||||||
: null,
|
|
||||||
(selected) => 'has libraryUriToImport ${valueStr(selected)}',
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@useResult
|
|
||||||
CheckTarget<List<String>?> get parameterNames {
|
|
||||||
return nest(
|
|
||||||
value.suggestion.parameterNames,
|
|
||||||
(selected) => 'has parameterNames ${valueStr(selected)}',
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@useResult
|
|
||||||
CheckTarget<String?> get parameterType {
|
|
||||||
return nest(
|
|
||||||
value.suggestion.parameterType,
|
|
||||||
(selected) => 'has parameterType ${valueStr(selected)}',
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@useResult
|
|
||||||
CheckTarget<List<String>?> get parameterTypes {
|
|
||||||
return nest(
|
|
||||||
value.suggestion.parameterTypes,
|
|
||||||
(selected) => 'has parameterTypes ${valueStr(selected)}',
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Return the effective replacement length.
|
|
||||||
@useResult
|
|
||||||
CheckTarget<int> get replacementLength {
|
|
||||||
return nest(
|
|
||||||
value.replacementLength,
|
|
||||||
(selected) => 'has replacementLength ${valueStr(selected)}',
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Return the effective replacement offset.
|
|
||||||
@useResult
|
|
||||||
CheckTarget<int> get replacementOffset {
|
|
||||||
return nest(
|
|
||||||
value.replacementOffset,
|
|
||||||
(selected) => 'has replacementOffset ${valueStr(selected)}',
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@useResult
|
|
||||||
CheckTarget<int?> get requiredParameterCount {
|
|
||||||
return nest(
|
|
||||||
value.suggestion.requiredParameterCount,
|
|
||||||
(selected) => 'has requiredParameterCount ${valueStr(selected)}',
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@useResult
|
|
||||||
CheckTarget<String?> get returnType {
|
|
||||||
return nest(
|
|
||||||
value.suggestion.returnType,
|
|
||||||
(selected) => 'has returnType ${valueStr(selected)}',
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@useResult
|
|
||||||
CheckTarget<int> get selectionLength {
|
|
||||||
return nest(
|
|
||||||
value.suggestion.selectionLength,
|
|
||||||
(selected) => 'has selectionLength ${valueStr(selected)}',
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@useResult
|
|
||||||
CheckTarget<int> get selectionOffset {
|
|
||||||
return nest(
|
|
||||||
value.suggestion.selectionOffset,
|
|
||||||
(selected) => 'has selectionOffset ${valueStr(selected)}',
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Check that the effective replacement offset is the completion request
|
|
||||||
/// offset, and the length of the replacement is zero.
|
|
||||||
void hasEmptyReplacement() {
|
|
||||||
hasReplacement(left: 0, right: 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Check that the effective replacement offset is the completion request
|
|
||||||
/// offset minus [left], and the length of the replacement is `left + right`.
|
|
||||||
void hasReplacement({int left = 0, int right = 0}) {
|
|
||||||
replacementOffset.isEqualTo(value.response.requestOffset - left);
|
|
||||||
replacementLength.isEqualTo(left + right);
|
|
||||||
}
|
|
||||||
|
|
||||||
void hasSelection({required int offset, int length = 0}) {
|
|
||||||
selectionOffset.isEqualTo(offset);
|
|
||||||
selectionLength.isEqualTo(length);
|
|
||||||
}
|
|
||||||
|
|
||||||
void isKeyword(Keyword keyword) {
|
|
||||||
kind.isKeyword;
|
|
||||||
completion.isEqualTo(keyword.lexeme);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extension CompletionSuggestionKindExtension
|
|
||||||
on CheckTarget<CompletionSuggestionKind> {
|
|
||||||
void get isIdentifier {
|
|
||||||
isEqualTo(CompletionSuggestionKind.IDENTIFIER);
|
|
||||||
}
|
|
||||||
|
|
||||||
void get isImport {
|
|
||||||
isEqualTo(CompletionSuggestionKind.IMPORT);
|
|
||||||
}
|
|
||||||
|
|
||||||
void get isInvocation {
|
|
||||||
isEqualTo(CompletionSuggestionKind.INVOCATION);
|
|
||||||
}
|
|
||||||
|
|
||||||
void get isKeyword {
|
|
||||||
isEqualTo(CompletionSuggestionKind.KEYWORD);
|
|
||||||
}
|
|
||||||
|
|
||||||
void get isNamedArgument {
|
|
||||||
isEqualTo(CompletionSuggestionKind.NAMED_ARGUMENT);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extension CompletionSuggestionsExtension
|
|
||||||
on CheckTarget<Iterable<CompletionSuggestionForTesting>> {
|
|
||||||
@useResult
|
|
||||||
CheckTarget<List<String>> get completions {
|
|
||||||
return nest(
|
|
||||||
value.map((e) => e.suggestion.completion).toList(),
|
|
||||||
(selected) => 'completions ${valueStr(selected)}',
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@useResult
|
|
||||||
CheckTarget<Iterable<CompletionSuggestionForTesting>> get fields {
|
|
||||||
var result = value
|
|
||||||
.where((suggestion) =>
|
|
||||||
suggestion.suggestion.kind == CompletionSuggestionKind.IDENTIFIER &&
|
|
||||||
suggestion.suggestion.element?.kind == ElementKind.FIELD)
|
|
||||||
.toList();
|
|
||||||
return nest(
|
|
||||||
result,
|
|
||||||
(selected) => 'fields ${valueStr(selected)}',
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@useResult
|
|
||||||
CheckTarget<Iterable<CompletionSuggestionForTesting>> get getters {
|
|
||||||
var result = value
|
|
||||||
.where((suggestion) =>
|
|
||||||
suggestion.suggestion.kind == CompletionSuggestionKind.IDENTIFIER &&
|
|
||||||
suggestion.suggestion.element?.kind == ElementKind.GETTER)
|
|
||||||
.toList();
|
|
||||||
return nest(
|
|
||||||
result,
|
|
||||||
(selected) => 'getters ${valueStr(selected)}',
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@useResult
|
|
||||||
CheckTarget<Iterable<CompletionSuggestionForTesting>> get methods {
|
|
||||||
var result = value
|
|
||||||
.where((suggestion) =>
|
|
||||||
suggestion.suggestion.kind == CompletionSuggestionKind.IDENTIFIER &&
|
|
||||||
suggestion.suggestion.element?.kind == ElementKind.METHOD)
|
|
||||||
.toList();
|
|
||||||
return nest(
|
|
||||||
result,
|
|
||||||
(selected) => 'setters ${valueStr(selected)}',
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@useResult
|
|
||||||
CheckTarget<Iterable<CompletionSuggestionForTesting>> get namedArguments {
|
|
||||||
var result = value
|
|
||||||
.where((suggestion) =>
|
|
||||||
suggestion.suggestion.kind ==
|
|
||||||
CompletionSuggestionKind.NAMED_ARGUMENT)
|
|
||||||
.toList();
|
|
||||||
return nest(
|
|
||||||
result,
|
|
||||||
(selected) => 'named arguments ${valueStr(selected)}',
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@useResult
|
|
||||||
CheckTarget<Iterable<CompletionSuggestionForTesting>> get overrides {
|
|
||||||
var result = value
|
|
||||||
.where((suggestion) =>
|
|
||||||
suggestion.suggestion.kind == CompletionSuggestionKind.OVERRIDE)
|
|
||||||
.toList();
|
|
||||||
return nest(
|
|
||||||
result,
|
|
||||||
(selected) => 'overrides ${valueStr(selected)}',
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@useResult
|
|
||||||
CheckTarget<Iterable<CompletionSuggestionForTesting>> get setters {
|
|
||||||
var result = value
|
|
||||||
.where((suggestion) =>
|
|
||||||
suggestion.suggestion.kind == CompletionSuggestionKind.IDENTIFIER &&
|
|
||||||
suggestion.suggestion.element?.kind == ElementKind.SETTER)
|
|
||||||
.toList();
|
|
||||||
return nest(
|
|
||||||
result,
|
|
||||||
(selected) => 'setters ${valueStr(selected)}',
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@useResult
|
|
||||||
CheckTarget<Iterable<CompletionSuggestionForTesting>> get withElementClass {
|
|
||||||
return nest(
|
|
||||||
value.where((e) {
|
|
||||||
return e.suggestion.element?.kind == ElementKind.CLASS;
|
|
||||||
}).toList(),
|
|
||||||
(selected) => 'withElementClass ${valueStr(selected)}',
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@useResult
|
|
||||||
CheckTarget<Iterable<CompletionSuggestionForTesting>> get withKindKeyword {
|
|
||||||
var result = value
|
|
||||||
.where((suggestion) =>
|
|
||||||
suggestion.suggestion.kind == CompletionSuggestionKind.KEYWORD)
|
|
||||||
.toList();
|
|
||||||
return nest(
|
|
||||||
result,
|
|
||||||
(selected) => 'withKindKeyword ${valueStr(selected)}',
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extension ElementExtension on CheckTarget<Element> {
|
|
||||||
@useResult
|
|
||||||
CheckTarget<bool> get isStatic {
|
|
||||||
return nest(
|
|
||||||
value.isStatic,
|
|
||||||
(selected) => 'isStatic ${valueStr(selected)}',
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@useResult
|
|
||||||
CheckTarget<ElementKind> get kind {
|
|
||||||
return nest(
|
|
||||||
value.kind,
|
|
||||||
(selected) => 'has kind ${valueStr(selected)}',
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@useResult
|
|
||||||
CheckTarget<String> get name {
|
|
||||||
return nest(
|
|
||||||
value.name,
|
|
||||||
(selected) => 'has name ${valueStr(selected)}',
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extension ElementKindExtension on CheckTarget<ElementKind> {
|
|
||||||
void get isClass {
|
|
||||||
isEqualTo(ElementKind.CLASS);
|
|
||||||
}
|
|
||||||
|
|
||||||
void get isConstructor {
|
|
||||||
isEqualTo(ElementKind.CONSTRUCTOR);
|
|
||||||
}
|
|
||||||
|
|
||||||
void get isEnum {
|
|
||||||
isEqualTo(ElementKind.ENUM);
|
|
||||||
}
|
|
||||||
|
|
||||||
void get isEnumConstant {
|
|
||||||
isEqualTo(ElementKind.ENUM_CONSTANT);
|
|
||||||
}
|
|
||||||
|
|
||||||
void get isField {
|
|
||||||
isEqualTo(ElementKind.FIELD);
|
|
||||||
}
|
|
||||||
|
|
||||||
void get isFunction {
|
|
||||||
isEqualTo(ElementKind.FUNCTION);
|
|
||||||
}
|
|
||||||
|
|
||||||
void get isGetter {
|
|
||||||
isEqualTo(ElementKind.GETTER);
|
|
||||||
}
|
|
||||||
|
|
||||||
void get isMethod {
|
|
||||||
isEqualTo(ElementKind.METHOD);
|
|
||||||
}
|
|
||||||
|
|
||||||
void get isMixin {
|
|
||||||
isEqualTo(ElementKind.MIXIN);
|
|
||||||
}
|
|
||||||
|
|
||||||
void get isParameter {
|
|
||||||
isEqualTo(ElementKind.PARAMETER);
|
|
||||||
}
|
|
||||||
|
|
||||||
void get isPrefix {
|
|
||||||
isEqualTo(ElementKind.PREFIX);
|
|
||||||
}
|
|
||||||
|
|
||||||
void get isSetter {
|
|
||||||
isEqualTo(ElementKind.SETTER);
|
|
||||||
}
|
|
||||||
|
|
||||||
void get isTopLevelVariable {
|
|
||||||
isEqualTo(ElementKind.TOP_LEVEL_VARIABLE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extension KeywordsExtension on Iterable<Keyword> {
|
|
||||||
List<CompletionSuggestionChecker> get asKeywordChecks {
|
|
||||||
return map((e) => (CompletionSuggestionTarget suggestion) =>
|
|
||||||
suggestion.isKeyword(e)).toList();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,32 +0,0 @@
|
||||||
// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
|
|
||||||
// for details. All rights reserved. Use of this source code is governed by a
|
|
||||||
// BSD-style license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
import 'package:analysis_server/src/protocol_server.dart';
|
|
||||||
import 'package:analyzer_utilities/check/check.dart';
|
|
||||||
import 'package:meta/meta.dart';
|
|
||||||
|
|
||||||
extension SourceChangeExtension on CheckTarget<SourceChange> {
|
|
||||||
@useResult
|
|
||||||
CheckTarget<List<SourceFileEdit>> get edits {
|
|
||||||
return nest(value.edits, (value) => 'has edits ${valueStr(value)}');
|
|
||||||
}
|
|
||||||
|
|
||||||
CheckTarget<SourceFileEdit> hasFileEdit(String path) {
|
|
||||||
return nest(
|
|
||||||
value.edits.singleWhere((e) => e.file == path),
|
|
||||||
(selected) => 'has edit ${valueStr(selected)}',
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extension SourceFileEditExtension on CheckTarget<SourceFileEdit> {
|
|
||||||
@useResult
|
|
||||||
CheckTarget<String> appliedTo(String applyTo) {
|
|
||||||
var actual = SourceEdit.applySequence(applyTo, value.edits);
|
|
||||||
return nest(
|
|
||||||
actual,
|
|
||||||
(selected) => 'produces ${valueStr(selected)}',
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,19 +0,0 @@
|
||||||
// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
|
|
||||||
// for details. All rights reserved. Use of this source code is governed by a
|
|
||||||
// BSD-style license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
import 'package:analyzer_utilities/check/check.dart';
|
|
||||||
|
|
||||||
extension BoolExtension on CheckTarget<bool> {
|
|
||||||
void get isFalse {
|
|
||||||
if (value) {
|
|
||||||
fail('is not false');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void get isTrue {
|
|
||||||
if (!value) {
|
|
||||||
fail('is not true');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,20 +0,0 @@
|
||||||
// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
|
|
||||||
// for details. All rights reserved. Use of this source code is governed by a
|
|
||||||
// BSD-style license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
import 'package:analyzer_utilities/check/check_target.dart';
|
|
||||||
import 'package:meta/meta.dart';
|
|
||||||
|
|
||||||
export 'package:analyzer_utilities/check/bool.dart';
|
|
||||||
export 'package:analyzer_utilities/check/check_target.dart';
|
|
||||||
export 'package:analyzer_utilities/check/equality.dart';
|
|
||||||
export 'package:analyzer_utilities/check/int.dart';
|
|
||||||
export 'package:analyzer_utilities/check/iterable.dart';
|
|
||||||
export 'package:analyzer_utilities/check/nullability.dart';
|
|
||||||
export 'package:analyzer_utilities/check/string.dart';
|
|
||||||
export 'package:analyzer_utilities/check/type.dart';
|
|
||||||
|
|
||||||
@useResult
|
|
||||||
CheckTarget<T> check<T>(T value) {
|
|
||||||
return CheckTarget(value, 0, () => '$value');
|
|
||||||
}
|
|
|
@ -1,45 +0,0 @@
|
||||||
// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
|
|
||||||
// for details. All rights reserved. Use of this source code is governed by a
|
|
||||||
// BSD-style license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
import 'package:test/test.dart' as test_package;
|
|
||||||
|
|
||||||
class CheckTarget<T> {
|
|
||||||
final T value;
|
|
||||||
final int _depth;
|
|
||||||
|
|
||||||
/// The function that return the description of the value, and of the
|
|
||||||
/// chain how we arrived to this value.
|
|
||||||
final String Function() _describe;
|
|
||||||
|
|
||||||
CheckTarget(this.value, this._depth, this._describe);
|
|
||||||
|
|
||||||
String get _indent => ' ' * (_depth + 1);
|
|
||||||
|
|
||||||
Never fail(String message) {
|
|
||||||
test_package.fail('${_describe()}\n$_indent$message');
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Chains to the given [value]; if a subsequent check fails, [describe]
|
|
||||||
/// will be invoked to describe the [value].
|
|
||||||
CheckTarget<U> nest<U>(
|
|
||||||
U value,
|
|
||||||
String Function(U value) describe,
|
|
||||||
) {
|
|
||||||
return CheckTarget(value, _depth + 1, () {
|
|
||||||
return '${_describe()}\n$_indent${describe(value)}';
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
String valueStr(value) {
|
|
||||||
if (value is String) {
|
|
||||||
return "'$value'";
|
|
||||||
}
|
|
||||||
return '$value';
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Use this if multiple checks are required on the value.
|
|
||||||
void which(void Function(CheckTarget<T> e) checker) {
|
|
||||||
checker(this);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,25 +0,0 @@
|
||||||
// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
|
|
||||||
// for details. All rights reserved. Use of this source code is governed by a
|
|
||||||
// BSD-style license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
import 'package:analyzer_utilities/check/check.dart';
|
|
||||||
|
|
||||||
extension EqualityExtension<T> on CheckTarget<T> {
|
|
||||||
void isEqualTo(Object? other) {
|
|
||||||
if (value != other) {
|
|
||||||
fail('is not equal to $other');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void isIdenticalTo(Object? other) {
|
|
||||||
if (!identical(value, other)) {
|
|
||||||
fail('is not identical to $other');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void isNotEqualTo(Object? other) {
|
|
||||||
if (value == other) {
|
|
||||||
fail('is equal to $other');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,19 +0,0 @@
|
||||||
// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
|
|
||||||
// for details. All rights reserved. Use of this source code is governed by a
|
|
||||||
// BSD-style license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
import 'package:analyzer_utilities/check/check.dart';
|
|
||||||
|
|
||||||
extension IntExtension on CheckTarget<int> {
|
|
||||||
void get isZero {
|
|
||||||
if (value != 0) {
|
|
||||||
fail('is not zero');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void isGreaterThan(int other) {
|
|
||||||
if (!(value > other)) {
|
|
||||||
fail('is not greater than $other');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,199 +0,0 @@
|
||||||
// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
|
|
||||||
// for details. All rights reserved. Use of this source code is governed by a
|
|
||||||
// BSD-style license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
import 'package:analyzer_utilities/check/check.dart';
|
|
||||||
import 'package:meta/meta.dart';
|
|
||||||
import 'package:test/test.dart' as test_package;
|
|
||||||
|
|
||||||
extension IterableExtension<T> on CheckTarget<Iterable<T>> {
|
|
||||||
void get isEmpty {
|
|
||||||
if (value.isNotEmpty) {
|
|
||||||
fail('is not empty');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void get isNotEmpty {
|
|
||||||
if (value.isEmpty) {
|
|
||||||
fail('is empty');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Succeeds if there is an element that matches the [matcher],
|
|
||||||
void containsMatch(void Function(CheckTarget<T> element) matcher) {
|
|
||||||
var elementList = value.toList();
|
|
||||||
for (var i = 0; i < elementList.length; i++) {
|
|
||||||
if (_matches(elementList, i, matcher)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fail('Does not contain at least one element that matches');
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Fails if for any matcher there is an element that matches.
|
|
||||||
void excludesAll(
|
|
||||||
Iterable<void Function(CheckTarget<T> element)> matchers,
|
|
||||||
) {
|
|
||||||
var elementList = value.toList();
|
|
||||||
var matcherList = matchers.toList();
|
|
||||||
var included = <int>[];
|
|
||||||
for (var i = 0; i < matcherList.length; i++) {
|
|
||||||
var matcher = matcherList[i];
|
|
||||||
for (var j = 0; j < elementList.length; j++) {
|
|
||||||
if (_matches(elementList, j, matcher)) {
|
|
||||||
included.add(i);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (included.isNotEmpty) {
|
|
||||||
fail('Unexpectedly includes matchers at ${valueStr(included)}');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@UseResult.unless(parameterDefined: 'expected')
|
|
||||||
CheckTarget<int> hasLength([int? expected]) {
|
|
||||||
var actual = value.length;
|
|
||||||
|
|
||||||
if (expected != null && actual != expected) {
|
|
||||||
fail('does not have length ${valueStr(expected)}');
|
|
||||||
}
|
|
||||||
|
|
||||||
return nest(actual, (length) => 'has length $length');
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Succeeds if for each matcher in [matchers] there is at least one
|
|
||||||
/// matching element.
|
|
||||||
void includesAll(
|
|
||||||
Iterable<void Function(CheckTarget<T> element)> matchers,
|
|
||||||
) {
|
|
||||||
var elementList = value.toList();
|
|
||||||
var matcherList = matchers.toList();
|
|
||||||
var notIncluded = <int>[];
|
|
||||||
for (var i = 0; i < matcherList.length; i++) {
|
|
||||||
var matcher = matcherList[i];
|
|
||||||
notIncluded.add(i);
|
|
||||||
for (var j = 0; j < elementList.length; j++) {
|
|
||||||
if (_matches(elementList, j, matcher)) {
|
|
||||||
notIncluded.removeLast();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (notIncluded.isNotEmpty) {
|
|
||||||
fail('Does not include matchers at ${valueStr(notIncluded)}');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Succeeds if for each matcher there is exactly one matching element,
|
|
||||||
/// in the same relative order.
|
|
||||||
void includesAllInOrder(
|
|
||||||
Iterable<void Function(CheckTarget<T> element)> matchers,
|
|
||||||
) {
|
|
||||||
var elementList = value.toList();
|
|
||||||
var matcherList = matchers.toList();
|
|
||||||
var elementIndex = 0;
|
|
||||||
for (var i = 0; i < matcherList.length; i++) {
|
|
||||||
var matcher = matcherList[i];
|
|
||||||
var hasMatch = false;
|
|
||||||
for (; elementIndex < elementList.length; elementIndex++) {
|
|
||||||
if (_matches(elementList, elementIndex, matcher)) {
|
|
||||||
hasMatch = true;
|
|
||||||
for (var j = elementIndex + 1; j < elementList.length; j++) {
|
|
||||||
if (_matches(elementList, j, matcher)) {
|
|
||||||
fail(
|
|
||||||
'Matcher at ${valueStr(i)} matches elements at '
|
|
||||||
'${valueStr(elementIndex)} and ${valueStr(j)}',
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
} else {}
|
|
||||||
}
|
|
||||||
if (!hasMatch) {
|
|
||||||
fail('Does not include matcher at ${valueStr(i)}');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Succeeds if the number of [matchers] is exactly the same as the number
|
|
||||||
/// of elements in [value], and each matcher matches the element at the
|
|
||||||
/// corresponding index.
|
|
||||||
void matches(
|
|
||||||
Iterable<void Function(CheckTarget<T> element)> matchers,
|
|
||||||
) {
|
|
||||||
var elementList = value.toList();
|
|
||||||
var matcherList = matchers.toList();
|
|
||||||
if (elementList.length != matcherList.length) {
|
|
||||||
fail('Expected ${valueStr(matcherList.length)} elements, '
|
|
||||||
'actually ${valueStr(elementList.length)}');
|
|
||||||
}
|
|
||||||
|
|
||||||
for (var index = 0; index < matcherList.length; index++) {
|
|
||||||
var element = elementList[index];
|
|
||||||
var matcher = matcherList[index];
|
|
||||||
matcher(
|
|
||||||
nest(
|
|
||||||
element,
|
|
||||||
(element) => 'element ${valueStr(element)} at ${valueStr(index)}',
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Succeeds if the number of [matchers] is exactly the same as the number
|
|
||||||
/// of elements in [value], and for each matcher there is exactly one element
|
|
||||||
/// that matches.
|
|
||||||
void matchesInAnyOrder(
|
|
||||||
Iterable<void Function(CheckTarget<T> element)> matchers,
|
|
||||||
) {
|
|
||||||
var elementList = value.toList();
|
|
||||||
var matcherList = matchers.toList();
|
|
||||||
if (elementList.length != matcherList.length) {
|
|
||||||
fail('Expected ${valueStr(matcherList.length)} elements, '
|
|
||||||
'actually ${valueStr(elementList.length)}');
|
|
||||||
}
|
|
||||||
|
|
||||||
for (var matcherIndex = 0;
|
|
||||||
matcherIndex < matcherList.length;
|
|
||||||
matcherIndex++) {
|
|
||||||
var matcher = matcherList[matcherIndex];
|
|
||||||
T? matchedElement;
|
|
||||||
for (var elementIndex = 0;
|
|
||||||
elementIndex < elementList.length;
|
|
||||||
elementIndex++) {
|
|
||||||
var element = elementList[elementIndex];
|
|
||||||
if (!_matches(elementList, elementIndex, matcher)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// The element matches, check that it is unique.
|
|
||||||
if (matchedElement == null) {
|
|
||||||
matchedElement = element;
|
|
||||||
} else {
|
|
||||||
fail('Already matched ${valueStr(matchedElement)}, '
|
|
||||||
'found ${valueStr(element)}');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (matchedElement == null) {
|
|
||||||
fail('No match at ${valueStr(matcherIndex)}');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool _matches(
|
|
||||||
List<T> elementList,
|
|
||||||
int index,
|
|
||||||
void Function(CheckTarget<T> element) matcher,
|
|
||||||
) {
|
|
||||||
var elementTarget = nest(
|
|
||||||
elementList[index],
|
|
||||||
(element) => 'element ${valueStr(element)} at ${valueStr(index)}',
|
|
||||||
);
|
|
||||||
try {
|
|
||||||
matcher(elementTarget);
|
|
||||||
return true;
|
|
||||||
} on test_package.TestFailure {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,21 +0,0 @@
|
||||||
// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
|
|
||||||
// for details. All rights reserved. Use of this source code is governed by a
|
|
||||||
// BSD-style license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
import 'package:analyzer_utilities/check/check.dart';
|
|
||||||
|
|
||||||
extension NullabilityExtension<T> on CheckTarget<T?> {
|
|
||||||
CheckTarget<T> get isNotNull {
|
|
||||||
final value = this.value;
|
|
||||||
if (value == null) {
|
|
||||||
fail('is null');
|
|
||||||
}
|
|
||||||
return nest(value, (value) => 'is not null');
|
|
||||||
}
|
|
||||||
|
|
||||||
void get isNull {
|
|
||||||
if (value != null) {
|
|
||||||
fail('is not null');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,31 +0,0 @@
|
||||||
// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
|
|
||||||
// for details. All rights reserved. Use of this source code is governed by a
|
|
||||||
// BSD-style license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
import 'package:analyzer_utilities/check/check.dart';
|
|
||||||
import 'package:meta/meta.dart';
|
|
||||||
|
|
||||||
extension StringExtension on CheckTarget<String> {
|
|
||||||
void contains(Pattern other) {
|
|
||||||
if (!value.contains(other)) {
|
|
||||||
fail('does not contain ${valueStr(other)}');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@UseResult.unless(parameterDefined: 'expected')
|
|
||||||
CheckTarget<int> hasLength([int? expected]) {
|
|
||||||
var actual = value.length;
|
|
||||||
|
|
||||||
if (expected != null && actual != expected) {
|
|
||||||
fail('does not have length ${valueStr(expected)}');
|
|
||||||
}
|
|
||||||
|
|
||||||
return nest(actual, (length) => 'has length $length');
|
|
||||||
}
|
|
||||||
|
|
||||||
void startsWith(Pattern other) {
|
|
||||||
if (!value.startsWith(other)) {
|
|
||||||
fail('does not start with ${valueStr(other)}');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,25 +0,0 @@
|
||||||
// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
|
|
||||||
// for details. All rights reserved. Use of this source code is governed by a
|
|
||||||
// BSD-style license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
import 'package:analyzer_utilities/check/check.dart';
|
|
||||||
|
|
||||||
extension IsExtension<T> on CheckTarget<T> {
|
|
||||||
CheckTarget<U> hasExactType<U extends T>() {
|
|
||||||
final value = this.value;
|
|
||||||
if (value.runtimeType == U) {
|
|
||||||
return nest(value as U, (_) => 'is of type $U');
|
|
||||||
} else {
|
|
||||||
fail('is not of type $U');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CheckTarget<U> isA<U extends T>() {
|
|
||||||
final value = this.value;
|
|
||||||
if (value is U) {
|
|
||||||
return nest(value, (_) => 'is of type $U');
|
|
||||||
} else {
|
|
||||||
fail('is not of type $U');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -8,7 +8,6 @@ environment:
|
||||||
# Use 'any' constraints here; we get our versions from the DEPS file.
|
# Use 'any' constraints here; we get our versions from the DEPS file.
|
||||||
dependencies:
|
dependencies:
|
||||||
analyzer: any
|
analyzer: any
|
||||||
meta: any
|
|
||||||
path: any
|
path: any
|
||||||
test: any
|
test: any
|
||||||
|
|
||||||
|
|
|
@ -1,366 +0,0 @@
|
||||||
// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
|
|
||||||
// for details. All rights reserved. Use of this source code is governed by a
|
|
||||||
// BSD-style license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
import 'package:analyzer_utilities/check/check.dart';
|
|
||||||
import 'package:test/test.dart';
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
group('type', () {
|
|
||||||
group('bool', () {
|
|
||||||
test('isEqualTo', () {
|
|
||||||
check(true).isEqualTo(true);
|
|
||||||
check(false).isEqualTo(false);
|
|
||||||
_fails(() => check(true).isEqualTo(false));
|
|
||||||
_fails(() => check(false).isEqualTo(true));
|
|
||||||
});
|
|
||||||
test('isFalse', () {
|
|
||||||
check(false).isFalse;
|
|
||||||
_fails(() => check(true).isFalse);
|
|
||||||
});
|
|
||||||
test('isNotEqualTo', () {
|
|
||||||
check(true).isNotEqualTo(false);
|
|
||||||
check(false).isNotEqualTo(true);
|
|
||||||
_fails(() => check(true).isNotEqualTo(true));
|
|
||||||
_fails(() => check(false).isNotEqualTo(false));
|
|
||||||
});
|
|
||||||
test('isTrue', () {
|
|
||||||
check(true).isTrue;
|
|
||||||
_fails(() => check(false).isTrue);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
group('equality', () {
|
|
||||||
test('isIdenticalTo', () {
|
|
||||||
final a = Object();
|
|
||||||
final b = Object();
|
|
||||||
check(a).isIdenticalTo(a);
|
|
||||||
_fails(() => check(a).isIdenticalTo(b));
|
|
||||||
});
|
|
||||||
});
|
|
||||||
group('int', () {
|
|
||||||
test('isEqualTo', () {
|
|
||||||
check(0).isEqualTo(0);
|
|
||||||
check(1).isEqualTo(1);
|
|
||||||
check(2).isEqualTo(2);
|
|
||||||
_fails(() => check(0).isEqualTo(1));
|
|
||||||
_fails(() => check(1).isEqualTo(0));
|
|
||||||
});
|
|
||||||
test('isGreaterThan', () {
|
|
||||||
check(2).isGreaterThan(1);
|
|
||||||
check(1).isGreaterThan(0);
|
|
||||||
check(-1).isGreaterThan(-2);
|
|
||||||
_fails(() => check(0).isGreaterThan(0));
|
|
||||||
_fails(() => check(0).isGreaterThan(1));
|
|
||||||
_fails(() => check(1).isGreaterThan(2));
|
|
||||||
_fails(() => check(-2).isGreaterThan(-1));
|
|
||||||
});
|
|
||||||
test('isNotEqualTo', () {
|
|
||||||
check(0).isNotEqualTo(1);
|
|
||||||
check(1).isNotEqualTo(0);
|
|
||||||
check(1).isNotEqualTo(2);
|
|
||||||
check(2).isNotEqualTo(1);
|
|
||||||
_fails(() => check(0).isNotEqualTo(0));
|
|
||||||
_fails(() => check(1).isNotEqualTo(1));
|
|
||||||
_fails(() => check(2).isNotEqualTo(2));
|
|
||||||
});
|
|
||||||
test('isZero', () {
|
|
||||||
check(0).isZero;
|
|
||||||
_fails(() => check(1).isZero);
|
|
||||||
_fails(() => check(-1).isZero);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
group('Iterable', () {
|
|
||||||
test('containsMatch', () {
|
|
||||||
check(<int>[0]).containsMatch((e) => e.isZero);
|
|
||||||
check(<int>[1, 0, 2]).containsMatch((e) => e.isZero);
|
|
||||||
_fails(() => check(<int>[]).containsMatch((e) => e.isZero));
|
|
||||||
_fails(() => check(<int>[1]).containsMatch((e) => e.isZero));
|
|
||||||
});
|
|
||||||
test('excludesAll', () {
|
|
||||||
check(<int>[]).excludesAll([
|
|
||||||
(e) => e.isEqualTo(0),
|
|
||||||
]);
|
|
||||||
check([1]).excludesAll([
|
|
||||||
(e) => e.isEqualTo(0),
|
|
||||||
(e) => e.isEqualTo(2),
|
|
||||||
]);
|
|
||||||
// Fails if any match.
|
|
||||||
_fails(() {
|
|
||||||
check(<int>[0]).excludesAll([
|
|
||||||
(e) => e.isEqualTo(0),
|
|
||||||
]);
|
|
||||||
});
|
|
||||||
_fails(() {
|
|
||||||
check(<int>[0]).excludesAll([
|
|
||||||
(e) => e.isZero,
|
|
||||||
]);
|
|
||||||
});
|
|
||||||
_fails(() {
|
|
||||||
check(<int>[0]).excludesAll([
|
|
||||||
(e) => e.isEqualTo(2),
|
|
||||||
(e) => e.isEqualTo(1),
|
|
||||||
(e) => e.isEqualTo(0),
|
|
||||||
]);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
test('hasLength', () {
|
|
||||||
check(<int>[]).hasLength().isZero;
|
|
||||||
check(<int>[0]).hasLength().isEqualTo(1);
|
|
||||||
check(<int>[0]).hasLength(1);
|
|
||||||
check(<int>[0, 1]).hasLength().isEqualTo(2);
|
|
||||||
check(<int>[0, 1]).hasLength(2);
|
|
||||||
check(<int>{}).hasLength().isZero;
|
|
||||||
check(<int>{0}).hasLength().isEqualTo(1);
|
|
||||||
check(<int>{0}).hasLength(1);
|
|
||||||
check(<int>{0, 1}).hasLength().isEqualTo(2);
|
|
||||||
check(<int>{0, 1}).hasLength(2);
|
|
||||||
_fails(() => check(<int>[]).hasLength(1));
|
|
||||||
_fails(() => check(<int>[]).hasLength(2));
|
|
||||||
_fails(() => check(<int>{}).hasLength(1));
|
|
||||||
_fails(() => check(<int>{}).hasLength(2));
|
|
||||||
_fails(() => check(<int>[]).hasLength().isEqualTo(1));
|
|
||||||
_fails(() => check(<int>[0]).hasLength().isEqualTo(0));
|
|
||||||
});
|
|
||||||
test('includesAll', () {
|
|
||||||
// Extra elements are OK.
|
|
||||||
check([0, 1, 2]).includesAll([
|
|
||||||
(e) => e.isEqualTo(0),
|
|
||||||
(e) => e.isEqualTo(1),
|
|
||||||
]);
|
|
||||||
// Order does not matter.
|
|
||||||
check([0, 1, 2]).includesAll([
|
|
||||||
(e) => e.isEqualTo(1),
|
|
||||||
(e) => e.isEqualTo(0),
|
|
||||||
]);
|
|
||||||
// Must have all elements.
|
|
||||||
_fails(() {
|
|
||||||
check(<int>[]).includesAll([
|
|
||||||
(e) => e.isEqualTo(0),
|
|
||||||
]);
|
|
||||||
});
|
|
||||||
_fails(() {
|
|
||||||
check([0]).includesAll([
|
|
||||||
(e) => e.isEqualTo(0),
|
|
||||||
(e) => e.isEqualTo(1),
|
|
||||||
]);
|
|
||||||
});
|
|
||||||
_fails(() {
|
|
||||||
check([1]).includesAll([
|
|
||||||
(e) => e.isEqualTo(0),
|
|
||||||
(e) => e.isEqualTo(1),
|
|
||||||
]);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
test('includesAllInOrder', () {
|
|
||||||
// Extra elements are OK.
|
|
||||||
check([0, 1, 2, 3, 4]).includesAllInOrder([
|
|
||||||
(e) => e.isEqualTo(0),
|
|
||||||
(e) => e.isEqualTo(3),
|
|
||||||
]);
|
|
||||||
// Exactly one element should match.
|
|
||||||
_fails(() {
|
|
||||||
check([0, 1, 0, 2]).includesAllInOrder([
|
|
||||||
(e) => e.isZero,
|
|
||||||
]);
|
|
||||||
});
|
|
||||||
// Must be in the requested order.
|
|
||||||
_fails(() {
|
|
||||||
check([0, 1, 2]).includesAllInOrder([
|
|
||||||
(e) => e.isEqualTo(1),
|
|
||||||
(e) => e.isEqualTo(0),
|
|
||||||
]);
|
|
||||||
});
|
|
||||||
// Must have all elements.
|
|
||||||
_fails(() {
|
|
||||||
check(<int>[]).includesAllInOrder([
|
|
||||||
(e) => e.isEqualTo(0),
|
|
||||||
]);
|
|
||||||
});
|
|
||||||
_fails(() {
|
|
||||||
check([0]).includesAllInOrder([
|
|
||||||
(e) => e.isEqualTo(0),
|
|
||||||
(e) => e.isEqualTo(1),
|
|
||||||
]);
|
|
||||||
});
|
|
||||||
_fails(() {
|
|
||||||
check([1]).includesAllInOrder([
|
|
||||||
(e) => e.isEqualTo(0),
|
|
||||||
(e) => e.isEqualTo(1),
|
|
||||||
]);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
test('isEmpty', () {
|
|
||||||
check(<int>[]).isEmpty;
|
|
||||||
check(<int>{}).isEmpty;
|
|
||||||
_fails(() => check([0]).isEmpty);
|
|
||||||
_fails(() => check([0, 1]).isEmpty);
|
|
||||||
_fails(() => check({0}).isEmpty);
|
|
||||||
_fails(() => check({0, 1}).isEmpty);
|
|
||||||
});
|
|
||||||
test('isNotEmpty', () {
|
|
||||||
check([0]).isNotEmpty;
|
|
||||||
check([0, 1]).isNotEmpty;
|
|
||||||
check({0}).isNotEmpty;
|
|
||||||
check({0, 1}).isNotEmpty;
|
|
||||||
_fails(() => check(<int>[]).isNotEmpty);
|
|
||||||
_fails(() => check(<int>{}).isNotEmpty);
|
|
||||||
});
|
|
||||||
test('matches', () {
|
|
||||||
check(<int>[]).matches([]);
|
|
||||||
check(<int>[0]).matches([
|
|
||||||
(e) => e.isEqualTo(0),
|
|
||||||
]);
|
|
||||||
check(<int>[0, 1]).matches([
|
|
||||||
(e) => e.isEqualTo(0),
|
|
||||||
(e) => e.isEqualTo(1),
|
|
||||||
]);
|
|
||||||
// Order is important.
|
|
||||||
_fails(
|
|
||||||
() => check([0, 1]).matches([
|
|
||||||
(e) => e.isEqualTo(1),
|
|
||||||
(e) => e.isEqualTo(0),
|
|
||||||
]),
|
|
||||||
);
|
|
||||||
// Too few matchers.
|
|
||||||
_fails(
|
|
||||||
() => check([0, 1]).matches([
|
|
||||||
(e) => e.isEqualTo(0),
|
|
||||||
]),
|
|
||||||
);
|
|
||||||
// Too many matchers.
|
|
||||||
_fails(
|
|
||||||
() => check([0]).matches([
|
|
||||||
(e) => e.isEqualTo(0),
|
|
||||||
(e) => e.isEqualTo(1),
|
|
||||||
]),
|
|
||||||
);
|
|
||||||
});
|
|
||||||
test('matchesInAnyOrder', () {
|
|
||||||
// Order does not matter.
|
|
||||||
check([0, 1]).matchesInAnyOrder([
|
|
||||||
(e) => e.isEqualTo(0),
|
|
||||||
(e) => e.isEqualTo(1),
|
|
||||||
]);
|
|
||||||
check([0, 1]).matchesInAnyOrder([
|
|
||||||
(e) => e.isEqualTo(1),
|
|
||||||
(e) => e.isEqualTo(0),
|
|
||||||
]);
|
|
||||||
// Matchers can be different.
|
|
||||||
check([0, 1]).matchesInAnyOrder([
|
|
||||||
(e) => e.isZero,
|
|
||||||
(e) => e.isEqualTo(1),
|
|
||||||
]);
|
|
||||||
check([0, 10]).matchesInAnyOrder([
|
|
||||||
(e) => e.isZero,
|
|
||||||
(e) => e.isGreaterThan(5),
|
|
||||||
]);
|
|
||||||
// Wrong number of matchers.
|
|
||||||
_fails(
|
|
||||||
() => check([0, 1]).matchesInAnyOrder([
|
|
||||||
(e) => e.isZero,
|
|
||||||
]),
|
|
||||||
);
|
|
||||||
// The first matcher accepts more than one element.
|
|
||||||
_fails(
|
|
||||||
() => check([1, 2]).matchesInAnyOrder([
|
|
||||||
(e) => e.isGreaterThan(0),
|
|
||||||
(e) => e.isEqualTo(2),
|
|
||||||
]),
|
|
||||||
);
|
|
||||||
// The second matcher accepts more than one element.
|
|
||||||
_fails(
|
|
||||||
() => check([1, 2]).matchesInAnyOrder([
|
|
||||||
(e) => e.isEqualTo(2),
|
|
||||||
(e) => e.isGreaterThan(0),
|
|
||||||
]),
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
group('nullability', () {
|
|
||||||
// ignore: unnecessary_nullable_for_final_variable_declarations
|
|
||||||
const int? notNullable = 0;
|
|
||||||
const int? nullable = null;
|
|
||||||
test('isNotNull', () {
|
|
||||||
check(notNullable).isNotNull;
|
|
||||||
_fails(() => check(nullable).isNotNull.isZero);
|
|
||||||
});
|
|
||||||
test('isNull', () {
|
|
||||||
check(nullable).isNull;
|
|
||||||
_fails(() => check(notNullable).isNull);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
group('String', () {
|
|
||||||
test('contains', () {
|
|
||||||
check('abc').contains('a');
|
|
||||||
check('abc').contains('b');
|
|
||||||
check('abc').contains('c');
|
|
||||||
check('abc').contains('ab');
|
|
||||||
check('abc').contains('bc');
|
|
||||||
check('abc').contains(RegExp('a'));
|
|
||||||
check('abc').contains(RegExp('a.'));
|
|
||||||
check('abc').contains(RegExp('a.c'));
|
|
||||||
check('abc').contains(RegExp('.b.'));
|
|
||||||
_fails(() => check('abc').contains('x'));
|
|
||||||
_fails(() => check('abc').contains('ac'));
|
|
||||||
_fails(() => check('abc').contains(RegExp('ac.')));
|
|
||||||
});
|
|
||||||
test('hasLength', () {
|
|
||||||
check('').hasLength().isZero;
|
|
||||||
check('').hasLength(0);
|
|
||||||
check('a').hasLength().isEqualTo(1);
|
|
||||||
check('a').hasLength(1);
|
|
||||||
check('abc').hasLength().isEqualTo(3);
|
|
||||||
check('abc').hasLength(3);
|
|
||||||
_fails(() => check('abc').hasLength(0));
|
|
||||||
_fails(() => check('abc').hasLength(1));
|
|
||||||
_fails(() => check('abc').hasLength(2));
|
|
||||||
});
|
|
||||||
test('isEqualTo', () {
|
|
||||||
check('').isEqualTo('');
|
|
||||||
check('abc').isEqualTo('abc');
|
|
||||||
check('foobar').isEqualTo('foobar');
|
|
||||||
_fails(() => check('abc').isEqualTo('ab'));
|
|
||||||
_fails(() => check('abc').isEqualTo('xyz'));
|
|
||||||
});
|
|
||||||
test('isNotEqualTo', () {
|
|
||||||
check('abc').isNotEqualTo('ab');
|
|
||||||
check('abc').isNotEqualTo('xyz');
|
|
||||||
_fails(() => check('abc').isNotEqualTo('abc'));
|
|
||||||
_fails(() => check('foobar').isNotEqualTo('foobar'));
|
|
||||||
});
|
|
||||||
test('startsWith', () {
|
|
||||||
check('abc').startsWith('a');
|
|
||||||
check('abc').startsWith('ab');
|
|
||||||
check('abc').startsWith('abc');
|
|
||||||
check('abc').startsWith(RegExp('..c'));
|
|
||||||
check('abc').startsWith(RegExp('.*c'));
|
|
||||||
_fails(() => check('abc').startsWith('b'));
|
|
||||||
_fails(() => check('abc').startsWith('x'));
|
|
||||||
_fails(() => check('abc').startsWith(RegExp('.c')));
|
|
||||||
});
|
|
||||||
});
|
|
||||||
group('type', () {
|
|
||||||
test('hasExactType', () {
|
|
||||||
check(42).hasExactType<int>();
|
|
||||||
_fails(() => check(42 as dynamic).hasExactType<num>());
|
|
||||||
});
|
|
||||||
test('isA', () {
|
|
||||||
check(0).isA<int>();
|
|
||||||
_fails(() => check('abc' as dynamic).isA<int>());
|
|
||||||
});
|
|
||||||
});
|
|
||||||
test('which', () {
|
|
||||||
check(0).which((e) => e.isZero);
|
|
||||||
_fails(() => check(1).which((e) => e.isZero));
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void _fails(void Function() f) {
|
|
||||||
try {
|
|
||||||
f();
|
|
||||||
} on TestFailure {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
fail('expected to fail');
|
|
||||||
}
|
|
Loading…
Reference in a new issue