| OLD | NEW |
| (Empty) |
| 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 // TODO(gram): | |
| 6 // Unfortunately I can't seem to test anything that involves timeouts, e.g. | |
| 7 // insufficient callbacks, because the timeout is controlled externally | |
| 8 // (test.dart?), and we would need to use a shorter timeout for the inner tests | |
| 9 // so the outer timeout doesn't fire. So I removed all such tests. | |
| 10 // I'd like to revisit this at some point. | |
| 11 | |
| 12 #library('unittestTest'); | |
| 13 #import('dart:isolate'); | |
| 14 #import('../../../pkg/unittest/unittest.dart'); | |
| 15 | |
| 16 var tests; // array of test names | |
| 17 var expected; // array of test expected results (from buildStatusString) | |
| 18 var actual; // actual test results (from buildStatusString in config.onDone) | |
| 19 var _testconfig; // test configuration to capture onDone | |
| 20 | |
| 21 _defer(void fn()) { | |
| 22 // Exploit isolate ports as a platform-independent mechanism to queue a | |
| 23 // message at the end of the event loop. Stolen from unittest.dart. | |
| 24 final port = new ReceivePort(); | |
| 25 port.receive((msg, reply) { | |
| 26 fn(); | |
| 27 port.close(); | |
| 28 }); | |
| 29 port.toSendPort().send(null, null); | |
| 30 } | |
| 31 | |
| 32 String buildStatusString(int passed, int failed, int errors, | |
| 33 var results, | |
| 34 [int count = 0, | |
| 35 String setup = '', String teardown = '', | |
| 36 String uncaughtError = null, | |
| 37 String message = '']) { | |
| 38 var totalTests = 0; | |
| 39 String testDetails = ''; | |
| 40 if (results is String) { | |
| 41 totalTests = passed + failed + errors; | |
| 42 testDetails = ':$results:$message'; | |
| 43 } else { | |
| 44 totalTests = results.length; | |
| 45 for (var i = 0; i < results.length; i++) { | |
| 46 testDetails = '$testDetails:${results[i].description}:' | |
| 47 '${collapseWhitespace(results[i].message)}'; | |
| 48 } | |
| 49 } | |
| 50 var result = '$passed:$failed:$errors:$totalTests:$count:' | |
| 51 '$setup:$teardown:$uncaughtError$testDetails'; | |
| 52 return result; | |
| 53 } | |
| 54 | |
| 55 class TestConfiguration extends Configuration { | |
| 56 | |
| 57 // Some test state that is captured | |
| 58 int count = 0; // a count of callbacks | |
| 59 String setup = ''; // the name of the test group setup function, if any | |
| 60 String teardown = ''; // the name of the test group teardown function, if any | |
| 61 | |
| 62 // The port to communicate with the parent isolate | |
| 63 SendPort _port; | |
| 64 | |
| 65 TestConfiguration(this._port); | |
| 66 | |
| 67 void onDone(int passed, int failed, int errors, List<TestCase> results, | |
| 68 String uncaughtError) { | |
| 69 var result = buildStatusString(passed, failed, errors, results, count, | |
| 70 setup, teardown, uncaughtError); | |
| 71 _port.send(result); | |
| 72 } | |
| 73 } | |
| 74 runTest() { | |
| 75 port.receive((testName, sendport) { | |
| 76 configure(_testconfig = new TestConfiguration(sendport)); | |
| 77 if (testName == 'single correct test') { | |
| 78 test(testName, () => expect(2 + 3, equals(5))); | |
| 79 } else if (testName == 'single failing test') { | |
| 80 test(testName, () => expect(2 + 2, equals(5))); | |
| 81 } else if (testName == 'exception test') { | |
| 82 test(testName, () { throw new Exception('Fail.'); }); | |
| 83 } else if (testName == 'group name test') { | |
| 84 group('a', () { | |
| 85 test('a', () {}); | |
| 86 group('b', () { | |
| 87 test('b', () {}); | |
| 88 }); | |
| 89 }); | |
| 90 } else if (testName == 'setup test') { | |
| 91 group('a', () { | |
| 92 setUp(() { _testconfig.setup = 'setup'; }); | |
| 93 test(testName, () {}); | |
| 94 }); | |
| 95 } else if (testName == 'teardown test') { | |
| 96 group('a', () { | |
| 97 tearDown(() { _testconfig.teardown = 'teardown'; }); | |
| 98 test(testName, () {}); | |
| 99 }); | |
| 100 } else if (testName == 'setup and teardown test') { | |
| 101 group('a', () { | |
| 102 setUp(() { _testconfig.setup = 'setup'; }); | |
| 103 tearDown(() { _testconfig.teardown = 'teardown'; }); | |
| 104 test(testName, () {}); | |
| 105 }); | |
| 106 } else if (testName == 'correct callback test') { | |
| 107 test(testName, | |
| 108 () =>_defer(expectAsync0((){ ++_testconfig.count;}))); | |
| 109 } else if (testName == 'excess callback test') { | |
| 110 test(testName, () { | |
| 111 var _callback = expectAsync0((){ ++_testconfig.count;}); | |
| 112 _defer(_callback); | |
| 113 _defer(_callback); | |
| 114 }); | |
| 115 } else if (testName == 'completion test') { | |
| 116 test(testName, () { | |
| 117 var _callback; | |
| 118 _callback = expectAsyncUntil0(() { | |
| 119 if (++_testconfig.count < 10) { | |
| 120 _defer(_callback); | |
| 121 } | |
| 122 }, | |
| 123 () => (_testconfig.count == 10)); | |
| 124 _defer(_callback); | |
| 125 }); | |
| 126 } else if (testName == 'async exception test') { | |
| 127 test(testName, () { | |
| 128 expectAsync0(() {}); | |
| 129 _defer(() => guardAsync(() { throw "error!"; })); | |
| 130 }); | |
| 131 } else if (testName == 'late exception test') { | |
| 132 test('testOne', () { | |
| 133 var f = expectAsync0(() {}); | |
| 134 _defer(protectAsync0(() { | |
| 135 _defer(protectAsync0(() => expect(false))); | |
| 136 expect(false); | |
| 137 })); | |
| 138 }); | |
| 139 test('testTwo', () { | |
| 140 _defer(expectAsync0(() {})); | |
| 141 }); | |
| 142 } | |
| 143 }); | |
| 144 } | |
| 145 | |
| 146 void nextTest(int testNum) { | |
| 147 SendPort sport = spawnFunction(runTest); | |
| 148 sport.call(tests[testNum]).then((msg) { | |
| 149 actual.add(msg); | |
| 150 if (actual.length == expected.length) { | |
| 151 for (var i = 0; i < tests.length; i++) { | |
| 152 test(tests[i], () => expect(actual[i].trim(), equals(expected[i]))); | |
| 153 } | |
| 154 } else { | |
| 155 nextTest(testNum+1); | |
| 156 } | |
| 157 }); | |
| 158 } | |
| 159 | |
| 160 main() { | |
| 161 tests = [ | |
| 162 'single correct test', | |
| 163 'single failing test', | |
| 164 'exception test', | |
| 165 'group name test', | |
| 166 'setup test', | |
| 167 'teardown test', | |
| 168 'setup and teardown test', | |
| 169 'correct callback test', | |
| 170 'excess callback test', | |
| 171 'completion test', | |
| 172 'async exception test', | |
| 173 'late exception test' | |
| 174 ]; | |
| 175 | |
| 176 expected = [ | |
| 177 buildStatusString(1, 0, 0, tests[0]), | |
| 178 buildStatusString(0, 1, 0, tests[1], | |
| 179 message: 'Expected: <5> but: was <4>.'), | |
| 180 buildStatusString(0, 1, 0, tests[2], message: 'Caught Exception: Fail.'), | |
| 181 buildStatusString(2, 0, 0, 'a a::a b b'), | |
| 182 buildStatusString(1, 0, 0, 'a ${tests[4]}', 0, 'setup'), | |
| 183 buildStatusString(1, 0, 0, 'a ${tests[5]}', 0, '', 'teardown'), | |
| 184 buildStatusString(1, 0, 0, 'a ${tests[6]}', 0, | |
| 185 'setup', 'teardown'), | |
| 186 buildStatusString(1, 0, 0, tests[7], 1), | |
| 187 buildStatusString(0, 0, 1, tests[8], 1, | |
| 188 message: 'Callback called more times than expected (2 > 1).'), | |
| 189 buildStatusString(1, 0, 0, tests[9], 10), | |
| 190 buildStatusString(0, 1, 0, tests[10], message: 'Caught error!'), | |
| 191 buildStatusString(1, 0, 1, 'testOne', message: 'Callback called after alread
y being marked as done (1).:testTwo:') | |
| 192 ]; | |
| 193 | |
| 194 actual = []; | |
| 195 | |
| 196 nextTest(0); | |
| 197 } | |
| 198 | |
| OLD | NEW |