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 |