| 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('../../../lib/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 |
| 75 runTest() { |
| 76 port.receive((testName, sendport) { |
| 77 configure(_testconfig = new TestConfiguration(sendport)); |
| 78 if (testName == 'single correct test') { |
| 79 test(testName, () => expect(2 + 3, equals(5))); |
| 80 } else if (testName == 'single failing test') { |
| 81 test(testName, () => expect(2 + 2, equals(5))); |
| 82 } else if (testName == 'exception test') { |
| 83 test(testName, () { throw new Exception('fail'); }); |
| 84 } else if (testName == 'group name test') { |
| 85 group('a', () { |
| 86 test('a', () {}); |
| 87 group('b', () { |
| 88 test('b', () {}); |
| 89 }); |
| 90 }); |
| 91 } else if (testName == 'setup test') { |
| 92 group('a', () { |
| 93 setUp(() { _testconfig.setup = 'setup'; }); |
| 94 test(testName, () {}); |
| 95 }); |
| 96 } else if (testName == 'teardown test') { |
| 97 group('a', () { |
| 98 tearDown(() { _testconfig.teardown = 'teardown'; }); |
| 99 test(testName, () {}); |
| 100 }); |
| 101 } else if (testName == 'setup and teardown test') { |
| 102 group('a', () { |
| 103 setUp(() { _testconfig.setup = 'setup'; }); |
| 104 tearDown(() { _testconfig.teardown = 'teardown'; }); |
| 105 test(testName, () {}); |
| 106 }); |
| 107 } else if (testName == 'correct callback test') { |
| 108 test(testName, |
| 109 () =>_defer(expectAsync0((){ ++_testconfig.count;}))); |
| 110 } else if (testName == 'excess callback test') { |
| 111 test(testName, () { |
| 112 var _callback = expectAsync0((){ ++_testconfig.count;}); |
| 113 _defer(_callback); |
| 114 _defer(_callback); |
| 115 }); |
| 116 } else if (testName == 'completion test') { |
| 117 test(testName, () { |
| 118 var _callback; |
| 119 _callback = expectAsyncUntil0(() { |
| 120 if (++_testconfig.count < 10) { |
| 121 _defer(_callback); |
| 122 } |
| 123 }, |
| 124 () => (_testconfig.count == 10)); |
| 125 _defer(_callback); |
| 126 }); |
| 127 } |
| 128 }); |
| 129 } |
| 130 |
| 131 void nextTest(int testNum) { |
| 132 SendPort sport = spawnFunction(runTest); |
| 133 sport.call(tests[testNum]).then((msg) { |
| 134 actual.add(msg); |
| 135 if (actual.length == expected.length) { |
| 136 for (var i = 0; i < tests.length; i++) { |
| 137 test(tests[i], () => expect(actual[i], equals(expected[i]))); |
| 138 } |
| 139 } else { |
| 140 nextTest(testNum+1); |
| 141 } |
| 142 }); |
| 143 } |
| 144 |
| 145 main() { |
| 146 tests = [ |
| 147 'single correct test', |
| 148 'single failing test', |
| 149 'exception test', |
| 150 'group name test', |
| 151 'setup test', |
| 152 'teardown test', |
| 153 'setup and teardown test', |
| 154 'correct callback test', |
| 155 'excess callback test', |
| 156 'completion test' |
| 157 ]; |
| 158 |
| 159 expected = [ |
| 160 buildStatusString(1, 0, 0, tests[0]), |
| 161 buildStatusString(0, 1, 0, tests[1], message: 'Expected: <5> but: was <4>'), |
| 162 buildStatusString(0, 1, 0, tests[2], message: 'Caught Exception: fail'), |
| 163 buildStatusString(2, 0, 0, 'a a::a b b'), |
| 164 buildStatusString(1, 0, 0, 'a ${tests[4]}', 0, 'setup'), |
| 165 buildStatusString(1, 0, 0, 'a ${tests[5]}', 0, '', 'teardown'), |
| 166 buildStatusString(1, 0, 0, 'a ${tests[6]}', 0, |
| 167 'setup', 'teardown'), |
| 168 buildStatusString(1, 0, 0, tests[7], 1), |
| 169 buildStatusString(0, 0, 1, tests[8], 1, |
| 170 message: 'Callback called more times than expected (2 > 1)'), |
| 171 buildStatusString(1, 0, 0, tests[9], 10) |
| 172 ]; |
| 173 |
| 174 actual = []; |
| 175 |
| 176 nextTest(0); |
| 177 } |
| 178 |
| OLD | NEW |