Commit e08c3c3b authored by Ian Hickson's avatar Ian Hickson Committed by GitHub

moreOrLessEquals matcher for floating point numbers (#7358)

```dart
expect(x, moreOrLessEquals(0.0));
```

...for those cases where `x` might be 1e-11 or whatever.

Also, be more resilient when dumping the tree from inside the test framework.
Also, add an assert that helped me debug something the other day.
parent 7f3dc76b
......@@ -49,6 +49,7 @@ class _DepthFirstChildIterator implements Iterator<Element> {
}
static Iterable<Element> _reverseChildrenOf(Element element, bool skipOffstage) {
assert(element != null);
final List<Element> children = <Element>[];
if (skipOffstage) {
element.visitChildrenForSemantics(children.add);
......
......@@ -334,7 +334,12 @@ abstract class TestWidgetsFlutterBinding extends BindingBase
// _this_ zone, the test framework would find this zone was the current
// zone and helpfully throw the error in this zone, causing us to be
// directly called again.
final String treeDump = renderViewElement?.toStringDeep() ?? '<no tree>';
String treeDump;
try {
treeDump = renderViewElement?.toStringDeep() ?? '<no tree>';
} catch (exception) {
treeDump = '<additional error caught while dumping tree: $exception>';
}
final StringBuffer expectLine = new StringBuffer();
final int stackLinesToOmit = reportExpectCall(stack, expectLine);
FlutterError.reportError(new FlutterErrorDetails(
......
......@@ -66,6 +66,17 @@ const Matcher isNotInCard = const _IsNotInCard();
/// empty.
const Matcher hasOneLineDescription = const _HasOneLineDescription();
/// Asserts that two [double]s are equal, within some tolerated error.
///
/// Two values are considered equal if the difference between them is within
/// 1e-10 of the larger one. This is an arbitrary value which can be adjusted
/// using the `epsilon` argument. This matcher is intended to compare floating
/// point numbers that are the result of different sequences of operations, such
/// that they may have accumulated slightly different errors.
Matcher moreOrLessEquals(double value, { double epsilon: 1e-10 }) {
return new _MoreOrLessEquals(value, epsilon);
}
class _FindsWidgetMatcher extends Matcher {
const _FindsWidgetMatcher(this.min, this.max);
......@@ -237,3 +248,23 @@ class _HasOneLineDescription extends Matcher {
@override
Description describe(Description description) => description.add('one line description');
}
class _MoreOrLessEquals extends Matcher {
const _MoreOrLessEquals(this.value, this.epsilon);
final double value;
final double epsilon;
@override
bool matches(Object object, Map<dynamic, dynamic> matchState) {
if (object is! double)
return false;
if (object == value)
return true;
final double test = object;
return (test - value).abs() <= epsilon;
}
@override
Description describe(Description description) => description.add('$value$epsilon)');
}
\ No newline at end of file
// Copyright 2016 The Chromium Authors. 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:flutter_test/flutter_test.dart';
void main() {
test('moreOrLessEquals', () {
expect(0.0, moreOrLessEquals(1e-11));
expect(1e-11, moreOrLessEquals(0.0));
expect(-1e-11, moreOrLessEquals(0.0));
expect(0.0, isNot(moreOrLessEquals(1e11)));
expect(1e11, isNot(moreOrLessEquals(0.0)));
expect(-1e11, isNot(moreOrLessEquals(0.0)));
expect(0.0, isNot(moreOrLessEquals(1.0)));
expect(1.0, isNot(moreOrLessEquals(0.0)));
expect(-1.0, isNot(moreOrLessEquals(0.0)));
expect(1e-11, moreOrLessEquals(-1e-11));
expect(-1e-11, moreOrLessEquals(1e-11));
expect(11.0, isNot(moreOrLessEquals(-11.0, epsilon: 1.0)));
expect(-11.0, isNot(moreOrLessEquals(11.0, epsilon: 1.0)));
expect(11.0, moreOrLessEquals(-11.0, epsilon: 100.0));
expect(-11.0, moreOrLessEquals(11.0, epsilon: 100.0));
});
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment