blob: 909c1189dcfd9bf63c9363f6f6fb6b83a91fbc58 [file] [log] [blame]
// 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.
import 'interfaces.dart';
/// Returns a matcher which matches if the match argument is within [delta]
/// of some [value].
///
/// In other words, this matches if the match argument is greater than
/// than or equal [value]-[delta] and less than or equal to [value]+[delta].
Matcher closeTo(num value, num delta) => new _IsCloseTo(value, delta);
class _IsCloseTo extends Matcher {
final num _value, _delta;
const _IsCloseTo(this._value, this._delta);
bool matches(item, Map matchState) {
if (item is! num) return false;
var diff = item - _value;
if (diff < 0) diff = -diff;
return (diff <= _delta);
}
Description describe(Description description) => description
.add('a numeric value within ')
.addDescriptionOf(_delta)
.add(' of ')
.addDescriptionOf(_value);
Description describeMismatch(
item, Description mismatchDescription, Map matchState, bool verbose) {
if (item is! num) {
return mismatchDescription.add(' not numeric');
} else {
var diff = item - _value;
if (diff < 0) diff = -diff;
return mismatchDescription.add(' differs by ').addDescriptionOf(diff);
}
}
}
/// Returns a matcher which matches if the match argument is greater
/// than or equal to [low] and less than or equal to [high].
Matcher inInclusiveRange(num low, num high) =>
new _InRange(low, high, true, true);
/// Returns a matcher which matches if the match argument is greater
/// than [low] and less than [high].
Matcher inExclusiveRange(num low, num high) =>
new _InRange(low, high, false, false);
/// Returns a matcher which matches if the match argument is greater
/// than [low] and less than or equal to [high].
Matcher inOpenClosedRange(num low, num high) =>
new _InRange(low, high, false, true);
/// Returns a matcher which matches if the match argument is greater
/// than or equal to a [low] and less than [high].
Matcher inClosedOpenRange(num low, num high) =>
new _InRange(low, high, true, false);
class _InRange extends Matcher {
final num _low, _high;
final bool _lowMatchValue, _highMatchValue;
const _InRange(
this._low, this._high, this._lowMatchValue, this._highMatchValue);
bool matches(value, Map matchState) {
if (value is! num) {
return false;
}
if (value < _low || value > _high) {
return false;
}
if (value == _low) {
return _lowMatchValue;
}
if (value == _high) {
return _highMatchValue;
}
return true;
}
Description describe(Description description) => description.add(
"be in range from "
"$_low (${_lowMatchValue ? 'inclusive' : 'exclusive'}) to "
"$_high (${_highMatchValue ? 'inclusive' : 'exclusive'})");
Description describeMismatch(
item, Description mismatchDescription, Map matchState, bool verbose) {
if (item is! num) {
return mismatchDescription.addDescriptionOf(item).add(' not numeric');
} else {
return super.describeMismatch(
item, mismatchDescription, matchState, verbose);
}
}
}