Line data Source code
1 : // Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file 2 : // for details. All rights reserved. Use of this source code is governed by a 3 : // BSD-style license that can be found in the LICENSE file. 4 : 5 : import 'custom_matcher.dart'; 6 : import 'interfaces.dart'; 7 : import 'type_matcher.dart'; 8 : import 'util.dart'; 9 : 10 : /// A package-private [TypeMatcher] implementation that handles is returned 11 : /// by calls to [TypeMatcher.having]. 12 : class HavingMatcher<T> implements TypeMatcher<T> { 13 : final TypeMatcher<T> _parent; 14 : final List<_FunctionMatcher<T>> _functionMatchers; 15 : 16 0 : HavingMatcher(TypeMatcher<T> parent, String description, 17 : Object? Function(T) feature, dynamic matcher, 18 : [Iterable<_FunctionMatcher<T>>? existing]) 19 : : _parent = parent, 20 0 : _functionMatchers = [ 21 0 : ...?existing, 22 0 : _FunctionMatcher<T>(description, feature, matcher) 23 : ]; 24 : 25 0 : @override 26 : TypeMatcher<T> having( 27 : Object? Function(T) feature, String description, dynamic matcher) => 28 0 : HavingMatcher(_parent, description, feature, matcher, _functionMatchers); 29 : 30 0 : @override 31 : bool matches(dynamic item, Map matchState) { 32 0 : for (var matcher in <Matcher>[_parent].followedBy(_functionMatchers)) { 33 0 : if (!matcher.matches(item, matchState)) { 34 0 : addStateInfo(matchState, {'matcher': matcher}); 35 : return false; 36 : } 37 : } 38 : return true; 39 : } 40 : 41 0 : @override 42 : Description describeMismatch(Object? item, Description mismatchDescription, 43 : Map matchState, bool verbose) { 44 0 : var matcher = matchState['matcher'] as Matcher; 45 0 : matcher.describeMismatch( 46 0 : item, mismatchDescription, matchState['state'] as Map, verbose); 47 : return mismatchDescription; 48 : } 49 : 50 0 : @override 51 : Description describe(Description description) => description 52 0 : .add('') 53 0 : .addDescriptionOf(_parent) 54 0 : .add(' with ') 55 0 : .addAll('', ' and ', '', _functionMatchers); 56 : } 57 : 58 : class _FunctionMatcher<T> extends CustomMatcher { 59 : final Object? Function(T value) _feature; 60 : 61 0 : _FunctionMatcher(String name, this._feature, Object? matcher) 62 0 : : super('`$name`:', '`$name`', matcher); 63 : 64 0 : @override 65 0 : Object? featureValueOf(covariant T actual) => _feature(actual); 66 : }