mirror of
https://github.com/dart-lang/sdk
synced 2024-09-18 21:11:19 +00:00
Revert "Revert "Make package:expect NNBD agnostic""
Reland this CL. Change-Id: I0e7684da01d417e76be44ce07a68a21d6a623b23 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/114635 Reviewed-by: Leaf Petersen <leafp@google.com> Commit-Queue: Vijay Menon <vsm@google.com>
This commit is contained in:
parent
28f692165e
commit
b37dd729ad
|
@ -85,12 +85,12 @@ class Expect {
|
|||
* This finds the first point where two strings differ, and returns
|
||||
* a text describing the difference.
|
||||
*
|
||||
* For small strings (length less than 20) nothing is done, and null is
|
||||
* For small strings (length less than 20) nothing is done, and "" is
|
||||
* returned. Small strings can be compared visually, but for longer strings
|
||||
* only a slice containing the first difference will be shown.
|
||||
*/
|
||||
static String _stringDifference(String expected, String actual) {
|
||||
if (expected.length < 20 && actual.length < 20) return null;
|
||||
if (expected.length < 20 && actual.length < 20) return "";
|
||||
for (int i = 0; i < expected.length && i < actual.length; i++) {
|
||||
if (expected.codeUnitAt(i) != actual.codeUnitAt(i)) {
|
||||
int start = i;
|
||||
|
@ -106,18 +106,18 @@ class Expect {
|
|||
"Found: <$truncActual>";
|
||||
}
|
||||
}
|
||||
return null;
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the expected and actual values are equal (using `==`).
|
||||
*/
|
||||
static void equals(var expected, var actual, [String reason = null]) {
|
||||
static void equals(var expected, var actual, [String reason = ""]) {
|
||||
if (expected == actual) return;
|
||||
String msg = _getMessage(reason);
|
||||
if (expected is String && actual is String) {
|
||||
String stringDifference = _stringDifference(expected, actual);
|
||||
if (stringDifference != null) {
|
||||
if (stringDifference.isNotEmpty) {
|
||||
_fail("Expect.equals($stringDifference$msg) fails.");
|
||||
}
|
||||
_fail("Expect.equals(expected: <${_escapeString(expected)}>"
|
||||
|
@ -129,7 +129,7 @@ class Expect {
|
|||
/**
|
||||
* Checks whether the actual value is a bool and its value is true.
|
||||
*/
|
||||
static void isTrue(var actual, [String reason = null]) {
|
||||
static void isTrue(var actual, [String reason = ""]) {
|
||||
if (_identical(actual, true)) return;
|
||||
String msg = _getMessage(reason);
|
||||
_fail("Expect.isTrue($actual$msg) fails.");
|
||||
|
@ -138,7 +138,7 @@ class Expect {
|
|||
/**
|
||||
* Checks whether the actual value is a bool and its value is false.
|
||||
*/
|
||||
static void isFalse(var actual, [String reason = null]) {
|
||||
static void isFalse(var actual, [String reason = ""]) {
|
||||
if (_identical(actual, false)) return;
|
||||
String msg = _getMessage(reason);
|
||||
_fail("Expect.isFalse($actual$msg) fails.");
|
||||
|
@ -147,7 +147,7 @@ class Expect {
|
|||
/**
|
||||
* Checks whether [actual] is null.
|
||||
*/
|
||||
static void isNull(actual, [String reason = null]) {
|
||||
static void isNull(actual, [String reason = ""]) {
|
||||
if (null == actual) return;
|
||||
String msg = _getMessage(reason);
|
||||
_fail("Expect.isNull(actual: <$actual>$msg) fails.");
|
||||
|
@ -156,7 +156,7 @@ class Expect {
|
|||
/**
|
||||
* Checks whether [actual] is not null.
|
||||
*/
|
||||
static void isNotNull(actual, [String reason = null]) {
|
||||
static void isNotNull(actual, [String reason = ""]) {
|
||||
if (null != actual) return;
|
||||
String msg = _getMessage(reason);
|
||||
_fail("Expect.isNotNull(actual: <$actual>$msg) fails.");
|
||||
|
@ -166,7 +166,7 @@ class Expect {
|
|||
* Checks whether the expected and actual values are identical
|
||||
* (using `identical`).
|
||||
*/
|
||||
static void identical(var expected, var actual, [String reason = null]) {
|
||||
static void identical(var expected, var actual, [String reason = ""]) {
|
||||
if (_identical(expected, actual)) return;
|
||||
String msg = _getMessage(reason);
|
||||
if (expected is String && actual is String) {
|
||||
|
@ -187,17 +187,20 @@ class Expect {
|
|||
* That is, `objects[i]` is identical to objects with indices in
|
||||
* `_findEquivalences(objects)[i]`.
|
||||
*
|
||||
* Uses `null` for objects that are only identical to themselves.
|
||||
* Uses `[]` for objects that are only identical to themselves.
|
||||
*/
|
||||
static List<List<int>> _findEquivalences(List<Object> objects) {
|
||||
var equivalences = new List<List<int>>(objects.length);
|
||||
var equivalences = new List<List<int>>.generate(objects.length, (_) => []);
|
||||
for (int i = 0; i < objects.length; i++) {
|
||||
if (equivalences[i] != null) continue;
|
||||
if (equivalences[i].isNotEmpty) continue;
|
||||
var o = objects[i];
|
||||
for (int j = i + 1; j < objects.length; j++) {
|
||||
if (equivalences[j] != null) continue;
|
||||
if (equivalences[j].isNotEmpty) continue;
|
||||
if (_identical(o, objects[j])) {
|
||||
equivalences[j] = (equivalences[i] ??= <int>[i])..add(j);
|
||||
if (equivalences[i].isEmpty) {
|
||||
equivalences[i].add(i);
|
||||
}
|
||||
equivalences[j] = equivalences[i]..add(j);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -211,7 +214,7 @@ class Expect {
|
|||
buffer.write(separator);
|
||||
separator = ",";
|
||||
var equivalence = equivalences[i];
|
||||
if (equivalence == null) {
|
||||
if (equivalence.isEmpty) {
|
||||
buffer.write('_');
|
||||
} else {
|
||||
int first = equivalence[0];
|
||||
|
@ -223,12 +226,12 @@ class Expect {
|
|||
}
|
||||
}
|
||||
|
||||
static void allIdentical(Iterable<Object> objects, [String reason]) {
|
||||
static void allIdentical(List<Object> objects, [String reason = ""]) {
|
||||
if (objects.length <= 1) return;
|
||||
String msg = _getMessage(reason);
|
||||
var equivalences = _findEquivalences(objects);
|
||||
var first = equivalences[0];
|
||||
if (first != null && first.length == objects.length) return;
|
||||
if (first.isNotEmpty && first.length == objects.length) return;
|
||||
var buffer = new StringBuffer("Expect.allIdentical([");
|
||||
_writeEquivalences(objects, equivalences, buffer);
|
||||
buffer..write("]")..write(msg)..write(")");
|
||||
|
@ -239,7 +242,7 @@ class Expect {
|
|||
* Checks whether the expected and actual values are *not* identical
|
||||
* (using `identical`).
|
||||
*/
|
||||
static void notIdentical(var unexpected, var actual, [String reason = null]) {
|
||||
static void notIdentical(var unexpected, var actual, [String reason = ""]) {
|
||||
if (!_identical(unexpected, actual)) return;
|
||||
String msg = _getMessage(reason);
|
||||
_fail("Expect.notIdentical(expected and actual: <$actual>$msg) fails.");
|
||||
|
@ -248,13 +251,13 @@ class Expect {
|
|||
/**
|
||||
* Checks that no two [objects] are `identical`.
|
||||
*/
|
||||
static void allDistinct(List<Object> objects, [String reason = null]) {
|
||||
static void allDistinct(List<Object> objects, [String reason = ""]) {
|
||||
String msg = _getMessage(reason);
|
||||
var equivalences = _findEquivalences(objects);
|
||||
|
||||
bool hasEquivalence = false;
|
||||
for (int i = 0; i < equivalences.length; i++) {
|
||||
if (equivalences[i] != null) {
|
||||
if (equivalences[i].isNotEmpty) {
|
||||
hasEquivalence = true;
|
||||
break;
|
||||
}
|
||||
|
@ -278,8 +281,8 @@ class Expect {
|
|||
* value 4 significant digits smaller than the value given for expected.
|
||||
*/
|
||||
static void approxEquals(num expected, num actual,
|
||||
[num tolerance = null, String reason = null]) {
|
||||
if (tolerance == null) {
|
||||
[num tolerance = -1, String reason = ""]) {
|
||||
if (tolerance < 0) {
|
||||
tolerance = (expected / 1e4).abs();
|
||||
}
|
||||
// Note: use !( <= ) rather than > so we fail on NaNs
|
||||
|
@ -290,7 +293,7 @@ class Expect {
|
|||
'tolerance:<$tolerance>$msg) fails');
|
||||
}
|
||||
|
||||
static void notEquals(unexpected, actual, [String reason = null]) {
|
||||
static void notEquals(unexpected, actual, [String reason = ""]) {
|
||||
if (unexpected != actual) return;
|
||||
String msg = _getMessage(reason);
|
||||
_fail("Expect.notEquals(unexpected: <$unexpected>, actual:<$actual>$msg) "
|
||||
|
@ -303,7 +306,7 @@ class Expect {
|
|||
* used by the standard list implementation. It should also produce nicer
|
||||
* error messages than just calling `Expect.equals(expected, actual)`.
|
||||
*/
|
||||
static void listEquals(List expected, List actual, [String reason = null]) {
|
||||
static void listEquals(List expected, List actual, [String reason = ""]) {
|
||||
String msg = _getMessage(reason);
|
||||
int n = (expected.length < actual.length) ? expected.length : actual.length;
|
||||
for (int i = 0; i < n; i++) {
|
||||
|
@ -327,7 +330,7 @@ class Expect {
|
|||
* the semantics of [Map.containsKey] to determine what "same" means. For
|
||||
* each key, checks that the values in both maps are equal using `==`.
|
||||
*/
|
||||
static void mapEquals(Map expected, Map actual, [String reason = null]) {
|
||||
static void mapEquals(Map expected, Map actual, [String reason = ""]) {
|
||||
String msg = _getMessage(reason);
|
||||
|
||||
// Make sure all of the values are present in both, and they match.
|
||||
|
@ -352,7 +355,7 @@ class Expect {
|
|||
* this method shows where the mismatch starts and ends.
|
||||
*/
|
||||
static void stringEquals(String expected, String actual,
|
||||
[String reason = null]) {
|
||||
[String reason = ""]) {
|
||||
if (expected == actual) return;
|
||||
|
||||
String msg = _getMessage(reason);
|
||||
|
@ -435,7 +438,7 @@ class Expect {
|
|||
* every element of [actual] is also in [expected].
|
||||
*/
|
||||
static void setEquals(Iterable expected, Iterable actual,
|
||||
[String reason = null]) {
|
||||
[String reason = ""]) {
|
||||
final missingSet = new Set.from(expected);
|
||||
missingSet.removeAll(actual);
|
||||
final extraSet = new Set.from(actual);
|
||||
|
@ -517,6 +520,8 @@ class Expect {
|
|||
}
|
||||
}
|
||||
|
||||
static bool _defaultCheck([dynamic e]) => true;
|
||||
|
||||
/**
|
||||
* Calls the function [f] and verifies that it throws a `T`.
|
||||
* The optional [check] function can provide additional validation
|
||||
|
@ -533,8 +538,13 @@ class Expect {
|
|||
* exception is not caught by [Expect.throws]. The test is still considered
|
||||
* failing.
|
||||
*/
|
||||
static void throws<T>(void f(), [bool check(T error), String reason]) {
|
||||
String msg = reason == null ? "" : "($reason)";
|
||||
static void throws<T>(void f(),
|
||||
[bool check(T error) = _defaultCheck, String reason = ""]) {
|
||||
// TODO(vsm): Make check nullable. Existing tests pass null to set
|
||||
// a reason.
|
||||
check = check ?? _defaultCheck;
|
||||
reason = reason ?? "";
|
||||
String msg = reason.isEmpty ? "" : "($reason)";
|
||||
if (f is! Function()) {
|
||||
// Only throws from executing the function body should count as throwing.
|
||||
// The failure to even call `f` should throw outside the try/catch.
|
||||
|
@ -545,7 +555,7 @@ class Expect {
|
|||
} on Object catch (e, s) {
|
||||
// A test failure doesn't count as throwing.
|
||||
if (e is ExpectException) rethrow;
|
||||
if (e is T && (check == null || check(e))) return;
|
||||
if (e is T && check(e as dynamic)) return;
|
||||
// Throws something unexpected.
|
||||
String type = "";
|
||||
if (T != dynamic && T != Object) {
|
||||
|
@ -557,45 +567,44 @@ class Expect {
|
|||
_fail('Expect.throws$msg fails: Did not throw');
|
||||
}
|
||||
|
||||
static void throwsArgumentError(void f(), [String reason]) {
|
||||
Expect.throws(
|
||||
f, (error) => error is ArgumentError, reason ?? "ArgumentError");
|
||||
static void throwsArgumentError(void f(), [String reason = "ArgumentError"]) {
|
||||
Expect.throws(f, (error) => error is ArgumentError, reason);
|
||||
}
|
||||
|
||||
static void throwsAssertionError(void f(), [String reason]) {
|
||||
Expect.throws(
|
||||
f, (error) => error is AssertionError, reason ?? "AssertionError");
|
||||
static void throwsAssertionError(void f(),
|
||||
[String reason = "AssertionError"]) {
|
||||
Expect.throws(f, (error) => error is AssertionError, reason);
|
||||
}
|
||||
|
||||
static void throwsCastError(void f(), [String reason]) {
|
||||
Expect.throws(f, (error) => error is CastError, reason ?? "CastError");
|
||||
static void throwsCastError(void f(), [String reason = "CastError"]) {
|
||||
Expect.throws(f, (error) => error is CastError, reason);
|
||||
}
|
||||
|
||||
static void throwsFormatException(void f(), [String reason]) {
|
||||
Expect.throws(
|
||||
f, (error) => error is FormatException, reason ?? "FormatException");
|
||||
static void throwsFormatException(void f(),
|
||||
[String reason = "FormatException"]) {
|
||||
Expect.throws(f, (error) => error is FormatException, reason);
|
||||
}
|
||||
|
||||
static void throwsNoSuchMethodError(void f(), [String reason]) {
|
||||
Expect.throws(f, (error) => error is NoSuchMethodError,
|
||||
reason ?? "NoSuchMethodError");
|
||||
static void throwsNoSuchMethodError(void f(),
|
||||
[String reason = "NoSuchMethodError"]) {
|
||||
Expect.throws(f, (error) => error is NoSuchMethodError, reason);
|
||||
}
|
||||
|
||||
static void throwsRangeError(void f(), [String reason]) {
|
||||
Expect.throws(f, (error) => error is RangeError, reason ?? "RangeError");
|
||||
static void throwsRangeError(void f(), [String reason = "RangeError"]) {
|
||||
Expect.throws(f, (error) => error is RangeError, reason);
|
||||
}
|
||||
|
||||
static void throwsStateError(void f(), [String reason]) {
|
||||
Expect.throws(f, (error) => error is StateError, reason ?? "StateError");
|
||||
static void throwsStateError(void f(), [String reason = "StateError"]) {
|
||||
Expect.throws(f, (error) => error is StateError, reason);
|
||||
}
|
||||
|
||||
static void throwsTypeError(void f(), [String reason]) {
|
||||
Expect.throws(f, (error) => error is TypeError, reason ?? "TypeError");
|
||||
static void throwsTypeError(void f(), [String reason = "TypeError"]) {
|
||||
Expect.throws(f, (error) => error is TypeError, reason);
|
||||
}
|
||||
|
||||
static void throwsUnsupportedError(void f(), [String reason]) {
|
||||
Expect.throws(
|
||||
f, (error) => error is UnsupportedError, reason ?? "UnsupportedError");
|
||||
static void throwsUnsupportedError(void f(),
|
||||
[String reason = "UnsupportedError"]) {
|
||||
Expect.throws(f, (error) => error is UnsupportedError, reason);
|
||||
}
|
||||
|
||||
/// Reports that there is an error in the test itself and not the code under
|
||||
|
@ -608,7 +617,7 @@ class Expect {
|
|||
}
|
||||
|
||||
/// Checks that [object] has type [T].
|
||||
static void type<T>(Object object, [String reason]) {
|
||||
static void type<T>(dynamic object, [String reason = ""]) {
|
||||
if (object is T) return;
|
||||
String msg = _getMessage(reason);
|
||||
_fail("Expect.type($object is $T$msg) fails "
|
||||
|
@ -616,7 +625,7 @@ class Expect {
|
|||
}
|
||||
|
||||
/// Checks that [object] does not have type [T].
|
||||
static void notType<T>(Object object, [String reason]) {
|
||||
static void notType<T>(dynamic object, [String reason = ""]) {
|
||||
if (object is! T) return;
|
||||
String msg = _getMessage(reason);
|
||||
_fail("Expect.type($object is! $T$msg) fails"
|
||||
|
@ -648,7 +657,7 @@ class Expect {
|
|||
}
|
||||
|
||||
static String _getMessage(String reason) =>
|
||||
(reason == null) ? "" : ", '$reason'";
|
||||
(reason.isEmpty) ? "" : ", '$reason'";
|
||||
|
||||
@alwaysThrows
|
||||
static void _fail(String message) {
|
||||
|
|
|
@ -18,7 +18,7 @@ import "expect.dart" show Expect;
|
|||
|
||||
typedef Matcher = void Function(Object actual);
|
||||
|
||||
void expect(Object actual, Object expected) {
|
||||
void expect(dynamic actual, dynamic expected) {
|
||||
if (expected is Matcher) {
|
||||
expected(actual);
|
||||
} else {
|
||||
|
@ -27,7 +27,8 @@ void expect(Object actual, Object expected) {
|
|||
}
|
||||
|
||||
Matcher unorderedEquals(Iterable<Object> expected) {
|
||||
return (Object actual) => Expect.setEquals(expected, actual);
|
||||
return (Object actual) =>
|
||||
Expect.setEquals(expected, actual as Iterable<Object>);
|
||||
}
|
||||
|
||||
fail(String message) {
|
||||
|
@ -40,7 +41,7 @@ Matcher same(Object expected) {
|
|||
|
||||
Matcher equals(Object expected) {
|
||||
if (expected is String) {
|
||||
return (Object actual) => Expect.stringEquals(expected, actual);
|
||||
return (Object actual) => Expect.stringEquals(expected, actual as String);
|
||||
} else if (expected is Iterable<Object>) {
|
||||
return (dynamic actual) =>
|
||||
Expect.listEquals(expected.toList(), actual.toList());
|
||||
|
|
|
@ -90,13 +90,11 @@ void group(String description, body()) {
|
|||
void test(String description, body()) {
|
||||
// TODO(rnystrom): Do something useful with the description.
|
||||
for (var group in _groups) {
|
||||
if (group.setUpFunction != null) {
|
||||
var result = group.setUpFunction();
|
||||
if (result is Future) {
|
||||
Expect.testError("setUp() does not support asynchronous functions.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
var result = body();
|
||||
|
@ -106,12 +104,9 @@ void test(String description, body()) {
|
|||
} finally {
|
||||
for (var i = _groups.length - 1; i >= 0; i--) {
|
||||
var group = _groups[i];
|
||||
if (group.tearDownFunction != null) {
|
||||
var result = group.tearDownFunction();
|
||||
if (result is Future) {
|
||||
Expect.testError(
|
||||
"tearDown() does not support asynchronous functions.");
|
||||
}
|
||||
Expect.testError("tearDown() does not support asynchronous functions.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -119,17 +114,17 @@ void test(String description, body()) {
|
|||
|
||||
void setUp(body()) {
|
||||
// Can't define multiple setUps at the same level.
|
||||
assert(_groups.last.setUpFunction == null);
|
||||
assert(_groups.last.setUpFunction == _defaultAction);
|
||||
_groups.last.setUpFunction = body;
|
||||
}
|
||||
|
||||
void tearDown(body()) {
|
||||
// Can't define multiple tearDowns at the same level.
|
||||
assert(_groups.last.tearDownFunction == null);
|
||||
assert(_groups.last.tearDownFunction == _defaultAction);
|
||||
_groups.last.tearDownFunction = body;
|
||||
}
|
||||
|
||||
void expect(Object actual, Object expected, {String reason}) {
|
||||
void expect(Object actual, Object expected, {String reason = ""}) {
|
||||
// TODO(rnystrom): Do something useful with reason.
|
||||
if (expected is! _Expectation) {
|
||||
expected = equals(expected);
|
||||
|
@ -152,10 +147,10 @@ Object notEquals(Object value) => new _Expectation((actual) {
|
|||
});
|
||||
|
||||
Object unorderedEquals(Object value) => new _Expectation((actual) {
|
||||
Expect.setEquals(value, actual);
|
||||
Expect.setEquals(value as Iterable, actual as Iterable);
|
||||
});
|
||||
|
||||
Object predicate(bool fn(Object value), [String description]) =>
|
||||
Object predicate(bool fn(Object value), [String description = ""]) =>
|
||||
new _Expectation((actual) {
|
||||
Expect.isTrue(fn(actual), description);
|
||||
});
|
||||
|
@ -179,7 +174,7 @@ Object same(Object value) => new _Expectation((actual) {
|
|||
});
|
||||
|
||||
Object closeTo(num value, num tolerance) => new _Expectation((actual) {
|
||||
Expect.approxEquals(value, actual, tolerance);
|
||||
Expect.approxEquals(value, actual as num, tolerance);
|
||||
});
|
||||
|
||||
/// Succeeds if the actual value is any of the given strings. Unlike matcher's
|
||||
|
@ -192,13 +187,15 @@ Object anyOf(List<String> expected) => new _Expectation((actual) {
|
|||
fail("Expected $actual to be one of $expected.");
|
||||
});
|
||||
|
||||
_defaultAction() {}
|
||||
|
||||
/// One level of group() nesting to track an optional [setUp()] and [tearDown()]
|
||||
/// function for the group.
|
||||
///
|
||||
/// There is also an implicit top level group.
|
||||
class _Group {
|
||||
_Action setUpFunction;
|
||||
_Action tearDownFunction;
|
||||
_Action setUpFunction = _defaultAction;
|
||||
_Action tearDownFunction = _defaultAction;
|
||||
}
|
||||
|
||||
/// A wrapper around an expectation function.
|
||||
|
|
Loading…
Reference in a new issue