Showing
2 changed files
with
113 additions
and
8 deletions
1 | import 'package:flutter_test/flutter_test.dart'; | 1 | import 'package:flutter_test/flutter_test.dart'; |
2 | import 'package:get/get.dart'; | 2 | import 'package:get/get.dart'; |
3 | +import 'util/matcher.dart'; | ||
3 | 4 | ||
4 | class Mock { | 5 | class Mock { |
5 | static Future<String> test() async { | 6 | static Future<String> test() async { |
@@ -18,14 +19,6 @@ class DisposableController extends DisposableInterface { | @@ -18,14 +19,6 @@ class DisposableController extends DisposableInterface { | ||
18 | } | 19 | } |
19 | } | 20 | } |
20 | 21 | ||
21 | -class TypeMatcher<T> { | ||
22 | - /// Creates a type matcher for the given type parameter. | ||
23 | - const TypeMatcher(); | ||
24 | - | ||
25 | - /// Returns true if the given object is of type `T`. | ||
26 | - bool check(dynamic object) => object is T; | ||
27 | -} | ||
28 | - | ||
29 | abstract class Service { | 22 | abstract class Service { |
30 | String post(); | 23 | String post(); |
31 | } | 24 | } |
test/util/matcher.dart
0 → 100644
1 | +import 'package:flutter_test/flutter_test.dart'; | ||
2 | + | ||
3 | +// Copyright 2014, the Dart project authors. All rights reserved. | ||
4 | +// Redistribution and use in source and binary forms, with or without | ||
5 | +// modification, are permitted provided that the following conditions are | ||
6 | +// met: | ||
7 | + | ||
8 | +// * Redistributions of source code must retain the above copyright | ||
9 | +// notice, this list of conditions and the following disclaimer. | ||
10 | +// * Redistributions in binary form must reproduce the above | ||
11 | +// copyright notice, this list of conditions and the following | ||
12 | +// disclaimer in the documentation and/or other materials provided | ||
13 | +// with the distribution. | ||
14 | +// * Neither the name of Google Inc. nor the names of its | ||
15 | +// contributors may be used to endorse or promote products derived | ||
16 | +// from this software without specific prior written permission. | ||
17 | + | ||
18 | +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
19 | +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
20 | +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
21 | +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
22 | +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
23 | +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
24 | +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
25 | +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
26 | +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
27 | +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
28 | +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
29 | + | ||
30 | +class _FunctionMatcher<T> extends CustomMatcher { | ||
31 | + final dynamic Function(T value) _feature; | ||
32 | + | ||
33 | + _FunctionMatcher(String name, this._feature, matcher) | ||
34 | + : super('`$name`:', '`$name`', matcher); | ||
35 | + | ||
36 | + @override | ||
37 | + Object featureValueOf(covariant T actual) => _feature(actual); | ||
38 | +} | ||
39 | + | ||
40 | +class HavingMatcher<T> implements TypeMatcher<T> { | ||
41 | + final TypeMatcher<T> _parent; | ||
42 | + final List<_FunctionMatcher<T>> _functionMatchers; | ||
43 | + | ||
44 | + HavingMatcher(TypeMatcher<T> parent, String description, | ||
45 | + Object Function(T) feature, dynamic matcher, | ||
46 | + [Iterable<_FunctionMatcher<T>> existing]) | ||
47 | + : _parent = parent, | ||
48 | + _functionMatchers = [ | ||
49 | + ...?existing, | ||
50 | + _FunctionMatcher<T>(description, feature, matcher) | ||
51 | + ]; | ||
52 | + | ||
53 | + @override | ||
54 | + TypeMatcher<T> having( | ||
55 | + Object Function(T) feature, String description, dynamic matcher) => | ||
56 | + HavingMatcher(_parent, description, feature, matcher, _functionMatchers); | ||
57 | + | ||
58 | + @override | ||
59 | + bool matches(item, Map matchState) { | ||
60 | + for (var matcher in <Matcher>[_parent].followedBy(_functionMatchers)) { | ||
61 | + if (!matcher.matches(item, matchState)) { | ||
62 | + addStateInfo(matchState, {'matcher': matcher}); | ||
63 | + return false; | ||
64 | + } | ||
65 | + } | ||
66 | + return true; | ||
67 | + } | ||
68 | + | ||
69 | + @override | ||
70 | + Description describeMismatch( | ||
71 | + item, Description mismatchDescription, Map matchState, bool verbose) { | ||
72 | + var matcher = matchState['matcher'] as Matcher; | ||
73 | + matcher.describeMismatch( | ||
74 | + item, mismatchDescription, matchState['state'] as Map, verbose); | ||
75 | + return mismatchDescription; | ||
76 | + } | ||
77 | + | ||
78 | + @override | ||
79 | + Description describe(Description description) => description | ||
80 | + .add('') | ||
81 | + .addDescriptionOf(_parent) | ||
82 | + .add(' with ') | ||
83 | + .addAll('', ' and ', '', _functionMatchers); | ||
84 | +} | ||
85 | + | ||
86 | +class TypeMatcher<T> extends Matcher { | ||
87 | + const TypeMatcher(); | ||
88 | + | ||
89 | + TypeMatcher<T> having( | ||
90 | + Object Function(T) feature, String description, dynamic matcher) => | ||
91 | + HavingMatcher(this, description, feature, matcher); | ||
92 | + | ||
93 | + @override | ||
94 | + Description describe(Description description) { | ||
95 | + var name = _stripDynamic(T); | ||
96 | + return description.add("<Instance of '$name'>"); | ||
97 | + } | ||
98 | + | ||
99 | + @override | ||
100 | + bool matches(Object item, Map matchState) => item is T; | ||
101 | + | ||
102 | + @override | ||
103 | + Description describeMismatch( | ||
104 | + item, Description mismatchDescription, Map matchState, bool verbose) { | ||
105 | + var name = _stripDynamic(T); | ||
106 | + return mismatchDescription.add("is not an instance of '$name'"); | ||
107 | + } | ||
108 | +} | ||
109 | + | ||
110 | +String _stripDynamic(Type type) => | ||
111 | + type.toString().replaceAll(_dart2DynamicArgs, ''); | ||
112 | +final _dart2DynamicArgs = RegExp('<dynamic(, dynamic)*>'); |
-
Please register or login to post a comment