mirror of
https://github.com/dart-lang/sdk
synced 2024-10-14 08:31:29 +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.
|
||||
|
||||
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 {
|
||||
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.
|
||||
dependencies:
|
||||
analyzer: any
|
||||
meta: any
|
||||
path: 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