Line data Source code
1 : // Copyright (c) 2012, 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 'interfaces.dart';
6 : import 'util.dart';
7 :
8 : /// Returns a matcher that inverts [valueOrMatcher] to its logical negation.
9 0 : Matcher isNot(Object? valueOrMatcher) => _IsNot(wrapMatcher(valueOrMatcher));
10 :
11 : class _IsNot extends Matcher {
12 : final Matcher _matcher;
13 :
14 0 : const _IsNot(this._matcher);
15 :
16 0 : @override
17 : bool matches(dynamic item, Map matchState) =>
18 0 : !_matcher.matches(item, matchState);
19 :
20 0 : @override
21 : Description describe(Description description) =>
22 0 : description.add('not ').addDescriptionOf(_matcher);
23 : }
24 :
25 : /// This returns a matcher that matches if all of the matchers passed as
26 : /// arguments (up to 7) match.
27 : ///
28 : /// Instead of passing the matchers separately they can be passed as a single
29 : /// List argument. Any argument that is not a matcher is implicitly wrapped in a
30 : /// Matcher to check for equality.
31 0 : Matcher allOf(Object? arg0,
32 : [Object? arg1,
33 : Object? arg2,
34 : Object? arg3,
35 : Object? arg4,
36 : Object? arg5,
37 : Object? arg6]) {
38 0 : return _AllOf(_wrapArgs(arg0, arg1, arg2, arg3, arg4, arg5, arg6));
39 : }
40 :
41 : class _AllOf extends Matcher {
42 : final List<Matcher> _matchers;
43 :
44 0 : const _AllOf(this._matchers);
45 :
46 0 : @override
47 : bool matches(dynamic item, Map matchState) {
48 0 : for (var matcher in _matchers) {
49 0 : if (!matcher.matches(item, matchState)) {
50 0 : addStateInfo(matchState, {'matcher': matcher});
51 : return false;
52 : }
53 : }
54 : return true;
55 : }
56 :
57 0 : @override
58 : Description describeMismatch(dynamic item, Description mismatchDescription,
59 : Map matchState, bool verbose) {
60 0 : var matcher = matchState['matcher'];
61 0 : matcher.describeMismatch(
62 0 : item, mismatchDescription, matchState['state'], verbose);
63 : return mismatchDescription;
64 : }
65 :
66 0 : @override
67 : Description describe(Description description) =>
68 0 : description.addAll('(', ' and ', ')', _matchers);
69 : }
70 :
71 : /// Matches if any of the given matchers evaluate to true.
72 : ///
73 : /// The arguments can be a set of matchers as separate parameters
74 : /// (up to 7), or a List of matchers.
75 : ///
76 : /// The matchers are evaluated from left to right using short-circuit
77 : /// evaluation, so evaluation stops as soon as a matcher returns true.
78 : ///
79 : /// Any argument that is not a matcher is implicitly wrapped in a
80 : /// Matcher to check for equality.
81 5 : Matcher anyOf(Object? arg0,
82 : [Object? arg1,
83 : Object? arg2,
84 : Object? arg3,
85 : Object? arg4,
86 : Object? arg5,
87 : Object? arg6]) {
88 10 : return _AnyOf(_wrapArgs(arg0, arg1, arg2, arg3, arg4, arg5, arg6));
89 : }
90 :
91 : class _AnyOf extends Matcher {
92 : final List<Matcher> _matchers;
93 :
94 5 : const _AnyOf(this._matchers);
95 :
96 5 : @override
97 : bool matches(dynamic item, Map matchState) {
98 10 : for (var matcher in _matchers) {
99 5 : if (matcher.matches(item, matchState)) {
100 : return true;
101 : }
102 : }
103 : return false;
104 : }
105 :
106 0 : @override
107 : Description describe(Description description) =>
108 0 : description.addAll('(', ' or ', ')', _matchers);
109 : }
110 :
111 5 : List<Matcher> _wrapArgs(Object? arg0, Object? arg1, Object? arg2, Object? arg3,
112 : Object? arg4, Object? arg5, Object? arg6) {
113 : Iterable args;
114 5 : if (arg0 is List) {
115 : if (arg1 != null ||
116 : arg2 != null ||
117 : arg3 != null ||
118 : arg4 != null ||
119 : arg5 != null ||
120 : arg6 != null) {
121 0 : throw ArgumentError('If arg0 is a List, all other arguments must be'
122 : ' null.');
123 : }
124 :
125 : args = arg0;
126 : } else {
127 0 : args = [arg0, arg1, arg2, arg3, arg4, arg5, arg6].where((e) => e != null);
128 : }
129 :
130 10 : return args.map(wrapMatcher).toList();
131 : }
|