| // 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 'feature_matcher.dart'; | |
| 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]. | |
| /// {@example /example/numeric/close_to.dart} | |
| Matcher closeTo(num value, num delta) => _IsCloseTo(value, delta); | |
| class _IsCloseTo extends FeatureMatcher<num> { | |
| final num _value, _delta; | |
| const _IsCloseTo(this._value, this._delta); | |
| @override | |
| bool typedMatches(num item, Map matchState) { | |
| var diff = item - _value; | |
| if (diff < 0) diff = -diff; | |
| return diff <= _delta; | |
| } | |
| @override | |
| Description describe(Description description) => description | |
| .add('a numeric value within ') | |
| .addDescriptionOf(_delta) | |
| .add(' of ') | |
| .addDescriptionOf(_value); | |
| @override | |
| Description describeTypedMismatch( | |
| num item, | |
| Description mismatchDescription, | |
| Map matchState, | |
| bool verbose, | |
| ) { | |
| 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]. | |
| /// {@example /example/numeric/in_inclusive_range.dart} | |
| Matcher inInclusiveRange(num low, num high) => _InRange(low, high, true, true); | |
| /// Returns a matcher which matches if the match argument is greater | |
| /// than [low] and less than [high]. | |
| /// {@example /example/numeric/in_exclusive_range.dart} | |
| Matcher inExclusiveRange(num low, num high) => | |
| _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]. | |
| /// {@example /example/numeric/in_open_closed_range.dart} | |
| Matcher inOpenClosedRange(num low, num high) => | |
| _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]. | |
| /// {@example /example/numeric/in_closed_open_range.dart} | |
| Matcher inClosedOpenRange(num low, num high) => | |
| _InRange(low, high, true, false); | |
| class _InRange extends FeatureMatcher<num> { | |
| final num _low, _high; | |
| final bool _lowMatchValue, _highMatchValue; | |
| const _InRange( | |
| this._low, | |
| this._high, | |
| this._lowMatchValue, | |
| this._highMatchValue, | |
| ); | |
| @override | |
| bool typedMatches(num value, Map matchState) { | |
| if (value < _low || value > _high) { | |
| return false; | |
| } | |
| if (value == _low) { | |
| return _lowMatchValue; | |
| } | |
| if (value == _high) { | |
| return _highMatchValue; | |
| } | |
| // Value may still be outside if range if it can't be compared. | |
| return value > _low && value < _high; | |
| } | |
| @override | |
| Description describe(Description description) => description.add( | |
| 'be in range from ' | |
| "$_low (${_lowMatchValue ? 'inclusive' : 'exclusive'}) to " | |
| "$_high (${_highMatchValue ? 'inclusive' : 'exclusive'})", | |
| ); | |
| } |