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:
Konstantin Shcheglov 2022-09-27 19:15:55 +00:00 committed by Commit Queue
parent 798c57bef9
commit dd63e54e2c
13 changed files with 0 additions and 1412 deletions

View file

@ -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();
}
}

View file

@ -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)}',
);
}
}

View file

@ -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');
}
}
}

View file

@ -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');
}

View file

@ -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);
}
}

View file

@ -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');
}
}
}

View file

@ -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');
}
}
}

View file

@ -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;
}
}
}

View file

@ -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');
}
}
}

View file

@ -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)}');
}
}
}

View file

@ -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');
}
}
}

View file

@ -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

View file

@ -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');
}