OLD | NEW |
| (Empty) |
1 // Copyright (c) 2016, 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 /// A minimal, dependency-free emulation layer for a subset of the | |
6 /// unittest/test API used by the language and core library (especially HTML) | |
7 /// tests. | |
8 /// | |
9 /// A number of our language and core library tests were written against the | |
10 /// unittest package, which is now deprecated in favor of the new test package. | |
11 /// The latter is much better feature-wise, but is also quite complex and has | |
12 /// many dependencies. For low-level language and core library tests, we don't | |
13 /// want to have to pull in a large number of dependencies and be able to run | |
14 /// them correctly in order to run a test, so we want to test them against | |
15 /// something simpler. | |
16 /// | |
17 /// When possible, we just use the tiny expect library. But to avoid rewriting | |
18 /// all of the existing tests that use unittest, they can instead use this, | |
19 /// which shims the unittest API with as little code as possible and calls into | |
20 /// expect. | |
21 /// | |
22 /// Eventually, it would be good to refactor those tests to use the expect | |
23 /// package directly and remove this. | |
24 | |
25 import 'package:expect/expect.dart'; | |
26 | |
27 typedef void _Action(); | |
28 typedef void _ExpectationFunction(Object actual); | |
29 | |
30 final List<_Group> _groups = [new _Group()]; | |
31 | |
32 final Object isFalse = new _Expectation(Expect.isFalse); | |
33 final Object isNotNull = new _Expectation(Expect.isNotNull); | |
34 final Object isNull = new _Expectation(Expect.isNull); | |
35 final Object isTrue = new _Expectation(Expect.isTrue); | |
36 | |
37 final Object returnsNormally = new _Expectation((actual) { | |
38 try { | |
39 (actual as _Action)(); | |
40 } catch (error) { | |
41 Expect.fail("Expected function to return normally, but threw:\n$error"); | |
42 } | |
43 }); | |
44 | |
45 final Object throws = new _Expectation((actual) { | |
46 Expect.throws(actual as _Action); | |
47 }); | |
48 | |
49 final Object throwsArgumentError = new _Expectation((actual) { | |
50 Expect.throws(actual as _Action, (error) => error is ArgumentError); | |
51 }); | |
52 | |
53 final Object throwsNoSuchMethodError = new _Expectation((actual) { | |
54 Expect.throws(actual as _Action, (error) => error is NoSuchMethodError); | |
55 }); | |
56 | |
57 final Object throwsRangeError = new _Expectation((actual) { | |
58 Expect.throws(actual as _Action, (error) => error is RangeError); | |
59 }); | |
60 | |
61 final Object throwsStateError = new _Expectation((actual) { | |
62 Expect.throws(actual as _Action, (error) => error is StateError); | |
63 }); | |
64 | |
65 final Object throwsUnsupportedError = new _Expectation((actual) { | |
66 Expect.throws(actual as _Action, (error) => error is UnsupportedError); | |
67 }); | |
68 | |
69 /// The test runner should call this once after running a test file. | |
70 void finishTests() { | |
71 _groups.clear(); | |
72 _groups.add(new _Group()); | |
73 } | |
74 | |
75 void group(String description, body()) { | |
76 // TODO(rnystrom): Do something useful with the description. | |
77 _groups.add(new _Group()); | |
78 | |
79 try { | |
80 body(); | |
81 } finally { | |
82 _groups.removeLast(); | |
83 } | |
84 } | |
85 | |
86 void test(String description, body()) { | |
87 // TODO(rnystrom): Do something useful with the description. | |
88 for (var group in _groups) { | |
89 if (group.setUpFunction != null) group.setUpFunction(); | |
90 } | |
91 | |
92 try { | |
93 body(); | |
94 } finally { | |
95 for (var i = _groups.length - 1; i >= 0; i--) { | |
96 var group = _groups[i]; | |
97 if (group.tearDownFunction != null) group.tearDownFunction(); | |
98 } | |
99 } | |
100 } | |
101 | |
102 void setUp(body()) { | |
103 // Can't define multiple setUps at the same level. | |
104 assert(_groups.last.setUpFunction == null); | |
105 _groups.last.setUpFunction = body; | |
106 } | |
107 | |
108 void tearDown(body()) { | |
109 // Can't define multiple tearDowns at the same level. | |
110 assert(_groups.last.tearDownFunction == null); | |
111 _groups.last.tearDownFunction = body; | |
112 } | |
113 | |
114 void expect(Object actual, Object expected, {String reason}) { | |
115 // TODO(rnystrom): Do something useful with reason. | |
116 if (expected is! _Expectation) { | |
117 expected = equals(expected); | |
118 } | |
119 | |
120 var expectation = expected as _Expectation; | |
121 expectation.function(actual); | |
122 } | |
123 | |
124 void fail(String message) { | |
125 Expect.fail(message); | |
126 } | |
127 | |
128 Object equals(Object value) => new _Expectation((actual) { | |
129 Expect.deepEquals(value, actual); | |
130 }); | |
131 | |
132 Object notEquals(Object value) => new _Expectation((actual) { | |
133 Expect.notEquals(value, actual); | |
134 }); | |
135 | |
136 Object unorderedEquals(Object value) => new _Expectation((actual) { | |
137 Expect.setEquals(value, actual); | |
138 }); | |
139 | |
140 // TODO(bob): Do something useful with the description. | |
141 Object predicate(bool fn(Object value), [String description]) => | |
142 new _Expectation((actual) { | |
143 Expect.isTrue(fn(actual)); | |
144 }); | |
145 | |
146 Object inInclusiveRange(num min, num max) => new _Expectation((actual) { | |
147 var actualNum = actual as num; | |
148 if (actualNum < min || actualNum > max) { | |
149 fail("Expected $actualNum to be in the inclusive range [$min, $max]."); | |
150 } | |
151 }); | |
152 | |
153 Object greaterThan(num value) => new _Expectation((actual) { | |
154 var actualNum = actual as num; | |
155 if (actualNum <= value) { | |
156 fail("Expected $actualNum to be greater than $value."); | |
157 } | |
158 }); | |
159 | |
160 Object same(Object value) => new _Expectation((actual) { | |
161 Expect.identical(value, actual); | |
162 }); | |
163 | |
164 /// One level of group() nesting to track an optional [setUp()] and [tearDown()] | |
165 /// function for the group. | |
166 /// | |
167 /// There is also an implicit top level group. | |
168 class _Group { | |
169 _Action setUpFunction; | |
170 _Action tearDownFunction; | |
171 } | |
172 | |
173 /// A wrapper around an expectation function. | |
174 /// | |
175 /// This function is passed the actual value and should throw an | |
176 /// [ExpectException] if the value doesn't match the expectation. | |
177 class _Expectation { | |
178 final _ExpectationFunction function; | |
179 | |
180 _Expectation(this.function); | |
181 } | |
OLD | NEW |