Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1445)

Unified Diff: lib/unittest/numeric_matchers.dart

Issue 10441104: New expectation functions plus convert old tests to use these. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: lib/unittest/numeric_matchers.dart
===================================================================
--- lib/unittest/numeric_matchers.dart (revision 0)
+++ lib/unittest/numeric_matchers.dart (revision 0)
@@ -0,0 +1,241 @@
+// Copyright (c) 2012, 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.
+
+/**
+ * Returns a matcher which matches if the match argument is greater
+ * than the given [value].
+ */
+IMatcher greaterThan(value) =>
+ new _OrderingComparison(value, false, false, true, 'greater than');
+
+/**
+ * Returns a matcher which matches if the match argument is greater
+ * than or equal to the given [value].
+ */
+IMatcher greaterThanOrEqualTo(value) =>
+ new _OrderingComparison(value, true, false, true, 'greater than or equal to');
+
+/**
+ * Returns a matcher which matches if the match argument is less
+ * than the given [value].
+ */
+IMatcher lessThan(value) =>
+ new _OrderingComparison(value, false, true, false, 'less than');
+
+/**
+ * Returns a matcher which matches if the match argument is less
+ * than or equal to the given [value].
+ */
+IMatcher lessThanOrEqualTo(value) =>
Bob Nystrom 2012/05/30 23:23:51 Is this really better than doing: expect(foo > ba
gram 2012/06/01 17:33:15 It gives better error messages. Either can be used
+ new _OrderingComparison(value, true, true, false, 'less than or equal to');
+
+/**
+ * Returns a matcher which matches if the match argument is zero.
+ */
+IMatcher isZero() {
Bob Nystrom 2012/05/30 23:23:51 Make these constants.
gram 2012/06/01 17:33:15 Done.
+ return new _OrderingComparison(0, true, false, false, 'equal to');
+}
+
+/**
+ * Returns a matcher which matches if the match argument is non-zero.
+ */
+IMatcher isNonZero() {
+ return new _OrderingComparison(0, false, true, true, 'not equal to');
+}
+
+/**
+ * Returns a matcher which matches if the match argument is positive
+ * (0 inclusive).
+ */
+IMatcher isPositive() {
+ return new _OrderingComparison(0, true, false, true, 'positive', false);
+}
+
+/**
+ * Returns a matcher which matches if the match argument is negative
+ * (0 exclusive).
+ */
+IMatcher isNegative() {
+ return new _OrderingComparison(0, false, true, false, 'negative', false);
+}
+
+bool _isNumeric(value) {
+ return value is int || value is double;
Bob Nystrom 2012/05/30 23:23:51 "is num" But I would just get rid of this. You ca
gram 2012/06/01 17:33:15 This isn't a matcher - it's a utility function use
Bob Nystrom 2012/06/01 18:22:22 Oh, right. Sorry. In either case, you can still si
+}
+
+class _OrderingComparison extends _NumericMatcher {
+
+ var _value; // Expected value.
Bob Nystrom 2012/05/30 23:23:51 Make these doc comments. Make the fields final.
gram 2012/06/01 17:33:15 Done.
+ bool _equalValue; // Return this if values are equal.
+ bool _lessThanValue; // Return this if test value < expected.
+ bool _greaterThanValue; // Return this if test value > expected.
+ String _comparisonDescription; // Textual name of inequality.
+ bool _valueInDescription; // include value in description?
+
+ _OrderingComparison(
+ this._value,
+ bool this._equalValue,
Bob Nystrom 2012/05/30 23:23:51 Remove these type annotations.
gram 2012/06/01 17:33:15 Done.
+ bool this._lessThanValue,
+ bool this._greaterThanValue,
+ String this._comparisonDescription,
+ [bool this._valueInDescription = true]) {
+ if (!_isNumeric(_value)) {
+ throw new IllegalArgumentException(
+ 'Expected value for ${_comparisonDescription} must be numeric');
+ }
+ }
+
+ bool matches(item) {
+ if (!_isNumeric(item)) {
Bob Nystrom 2012/05/30 23:23:51 Should we allow this on user-defined types that im
gram 2012/06/01 17:33:15 Done.
+ return false;
+ }
+ if (item == _value) {
+ return _equalValue;
+ } else if (item < _value) {
+ return _lessThanValue;
+ } else {
+ return _greaterThanValue;
+ }
+ }
+
+ IDescription describe(IDescription description) =>
Bob Nystrom 2012/05/30 23:23:51 I would use a {} body here.
gram 2012/06/01 17:33:15 Done.
+ description.append('a value ').
+ append(_comparisonDescription).
+ append(' ').
+ appendDescriptionOf(_value);
+}
+
+/**
+ * Returns a matcher which matches if the match argument is within [delta]
+ * of some [value]; i.e. if the match argument is greater than
+ * than or equal [value]-[delta] and less than or equal to [value]+[delta].
+ */
+IMatcher closeTo(value, delta) => new _IsCloseTo(value, delta);
+
+class _IsCloseTo extends _NumericMatcher {
+
+ var _value, _delta;
+
+ _IsCloseTo(this._value, this._delta) {
+ if (!_isNumeric(_value)) {
+ throw new IllegalArgumentException('IsCloseTo value must be numeric');
+ }
+ if (!_isNumeric(_delta)) {
+ throw new IllegalArgumentException('IsCloseTo delta must be numeric');
+ }
+ }
+
+ bool matches(item) {
+ if (!_isNumeric(item)) {
+ return false;
+ }
+ var diff = item - _value;
+ if (diff < 0) diff = -diff;
Bob Nystrom 2012/05/30 23:23:51 var diff = Math.abs(item - _value);
gram 2012/06/01 17:33:15 There is no Math.abs
Bob Nystrom 2012/06/01 18:22:22 Heh, whoops! Every now and then, the corelib desig
+ return (diff <= _delta);
+ }
+
+ IDescription describeMismatch(item, IDescription mismatchDescription) {
+ if (_isNumeric(item)) {
+ var diff = item - _value;
+ if (diff < 0) diff = -diff;
+ return mismatchDescription.
+ appendDescriptionOf(item).
+ append(' differed by ').
+ appendDescriptionOf(diff);
+ } else {
+ return super.describeMismatch(item, mismatchDescription);
+ }
+ }
+
+ IDescription describe(IDescription description) =>
+ description.append('a numeric value within ').
+ appendDescriptionOf(_delta).
+ append(' of ').
+ appendDescriptionOf(_value);
+}
+
+/**
+ * Returns a matcher which matches if the match argument is greater
+ * than or equal to a [low] and less than or equal to [high].
Bob Nystrom 2012/05/30 23:23:51 "to a" -> "to"
gram 2012/06/01 17:33:15 Done.
+ */
+IMatcher inInclusiveRange(low, high) => new _InRange(low, high, false, false);
+
+/**
+ * Returns a matcher which matches if the match argument is greater
+ * than [low] and less than [high].
+ */
+IMatcher inExclusiveRange(low, high) => new _InRange(low, high, true, true);
Bob Nystrom 2012/05/30 23:23:51 Add a blank line after each member.
gram 2012/06/01 17:33:15 Done.
+/**
+ * Returns a matcher which matches if the match argument is greater
+ * than [low] and less than or equal to [high].
+ */
+IMatcher inOpenClosedRange(low, high) => new _InRange(low, high, true, false);
+/**
+ * Returns a matcher which matches if the match argument is greater
+ * than or equal to a [low] and less than [high].
+ */
+IMatcher inClosedOpenRange(low, high) => new _InRange(low, high, false, true);
+
+
+class _InRange extends _NumericMatcher {
+ num _low, _high;
+ bool _lowExclusive, _highExclusive;
+
+ _InRange(num this._low, num this._high,
+ bool this._lowExclusive, bool this._highExclusive) {
+ if (!_isNumeric(_low) || !_isNumeric(_high)) {
Bob Nystrom 2012/05/30 23:23:51 Delete these checks. That's what checked mode is f
gram 2012/06/01 17:33:15 Done.
+ throw new
+ IllegalArgumentException('IsRange range arguments must be numeric');
+ }
+ if (!(_lowExclusive is bool) || !(_highExclusive is bool)) {
+ throw new IllegalArgumentException('IsRange flag arguments must be bool');
+ }
+ }
+
+ bool matches(value) {
+ if (!_isNumeric(value)) {
+ return false;
+ }
+ if (value < _low || value > _high) {
+ return false;
+ }
+ if (_lowExclusive && value == _low) {
+ return false;
+ }
+ if (_highExclusive && value == _high) {
+ return false;
+ }
+ return true;
+ }
+
+ IDescription describe(IDescription description) =>
+ description.append("be in range from "
+ "$_low (${_lowExclusive?'exclusive':'inclusive'}) to "
Bob Nystrom 2012/05/30 23:23:51 Spaces around ? and :
gram 2012/06/01 17:33:15 Done.
+ "$_high (${_highExclusive?'exclusive':'inclusive'})");
+
+ IDescription describeMismatch(item, IDescription mismatchDescription) {
+ if (!_isNumeric(item)) {
+ return mismatchDescription.
+ appendDescriptionOf(item).
+ append(' not numeric');
+ } else {
+ return super.describeMismatch(item, mismatchDescription);
+ }
+ }
+}
+
+
+// Numeric matchers match against a number. We add this intermediate
+// class to give better mismatch error messages than the base Matcher class.
+class _NumericMatcher extends Matcher {
+ IDescription describeMismatch(item, IDescription mismatchDescription) {
+ if (!_isNumeric(item)) {
+ return mismatchDescription.
+ appendDescriptionOf(item).
+ append(' not numeric');
+ } else {
+ return super.describeMismatch(item, mismatchDescription);
+ }
+ }
+}

Powered by Google App Engine
This is Rietveld 408576698