| OLD | NEW |
| 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 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. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 @TestOn("vm") | 5 @TestOn("vm") |
| 6 | 6 |
| 7 import 'dart:io'; | 7 import 'dart:io'; |
| 8 | 8 |
| 9 import 'package:path/path.dart' as p; | 9 import 'package:path/path.dart' as p; |
| 10 import 'package:test/src/util/io.dart'; | 10 import 'package:test/src/util/io.dart'; |
| 11 import 'package:test/test.dart'; | 11 import 'package:test/test.dart'; |
| 12 | 12 |
| 13 import '../io.dart'; | 13 import '../io.dart'; |
| 14 | 14 |
| 15 void main() { | 15 void main() { |
| 16 test("reports when no tests are run", () { | 16 test("reports when no tests are run", () { |
| 17 return withTempDir((path) { | 17 return withTempDir((path) { |
| 18 new File(p.join(path, "test.dart")).writeAsStringSync("void main() {}"); | 18 new File(p.join(path, "test.dart")).writeAsStringSync("void main() {}"); |
| 19 var result = runTest(["test.dart"], workingDirectory: path); | 19 var result = runTest(["-r", "expanded", "test.dart"], |
| 20 workingDirectory: path); |
| 20 expect(result.stdout, equals("No tests ran.\n")); | 21 expect(result.stdout, equals("No tests ran.\n")); |
| 21 }); | 22 }); |
| 22 }); | 23 }); |
| 23 | 24 |
| 24 test("runs several successful tests and reports when each completes", () { | 25 test("runs several successful tests and reports when each completes", () { |
| 25 _expectReport(""" | 26 _expectReport(""" |
| 26 test('success 1', () {}); | 27 test('success 1', () {}); |
| 27 test('success 2', () {}); | 28 test('success 2', () {}); |
| 28 test('success 3', () {});""", | 29 test('success 3', () {});""", |
| 29 """ | 30 """ |
| 30 +0: success 1 | 31 +0: success 1 |
| 31 +1: success 1 | |
| 32 +1: success 2 | 32 +1: success 2 |
| 33 +2: success 2 | |
| 34 +2: success 3 | 33 +2: success 3 |
| 35 +3: success 3 | |
| 36 +3: All tests passed!"""); | 34 +3: All tests passed!"""); |
| 37 }); | 35 }); |
| 38 | 36 |
| 39 test("runs several failing tests and reports when each fails", () { | 37 test("runs several failing tests and reports when each fails", () { |
| 40 _expectReport(""" | 38 _expectReport(""" |
| 41 test('failure 1', () => throw new TestFailure('oh no')); | 39 test('failure 1', () => throw new TestFailure('oh no')); |
| 42 test('failure 2', () => throw new TestFailure('oh no')); | 40 test('failure 2', () => throw new TestFailure('oh no')); |
| 43 test('failure 3', () => throw new TestFailure('oh no'));""", | 41 test('failure 3', () => throw new TestFailure('oh no'));""", |
| 44 """ | 42 """ |
| 45 +0: failure 1 | 43 +0: failure 1 |
| 46 +0 -1: failure 1 | 44 +0 -1: failure 1 |
| 47 oh no | 45 oh no |
| 48 test.dart 6:33 main.<fn> | 46 test.dart 6:33 main.<fn> |
| 49 | 47 |
| 50 | |
| 51 +0 -1: failure 2 | 48 +0 -1: failure 2 |
| 52 +0 -2: failure 2 | 49 +0 -2: failure 2 |
| 53 oh no | 50 oh no |
| 54 test.dart 7:33 main.<fn> | 51 test.dart 7:33 main.<fn> |
| 55 | 52 |
| 56 | |
| 57 +0 -2: failure 3 | 53 +0 -2: failure 3 |
| 58 +0 -3: failure 3 | 54 +0 -3: failure 3 |
| 59 oh no | 55 oh no |
| 60 test.dart 8:33 main.<fn> | 56 test.dart 8:33 main.<fn> |
| 61 | 57 |
| 62 | |
| 63 +0 -3: Some tests failed."""); | 58 +0 -3: Some tests failed."""); |
| 64 }); | 59 }); |
| 65 | 60 |
| 66 test("runs failing tests along with successful tests", () { | 61 test("runs failing tests along with successful tests", () { |
| 67 _expectReport(""" | 62 _expectReport(""" |
| 68 test('failure 1', () => throw new TestFailure('oh no')); | 63 test('failure 1', () => throw new TestFailure('oh no')); |
| 69 test('success 1', () {}); | 64 test('success 1', () {}); |
| 70 test('failure 2', () => throw new TestFailure('oh no')); | 65 test('failure 2', () => throw new TestFailure('oh no')); |
| 71 test('success 2', () {});""", | 66 test('success 2', () {});""", |
| 72 """ | 67 """ |
| 73 +0: failure 1 | 68 +0: failure 1 |
| 74 +0 -1: failure 1 | 69 +0 -1: failure 1 |
| 75 oh no | 70 oh no |
| 76 test.dart 6:33 main.<fn> | 71 test.dart 6:33 main.<fn> |
| 77 | 72 |
| 78 | |
| 79 +0 -1: success 1 | 73 +0 -1: success 1 |
| 80 +1 -1: success 1 | |
| 81 +1 -1: failure 2 | 74 +1 -1: failure 2 |
| 82 +1 -2: failure 2 | 75 +1 -2: failure 2 |
| 83 oh no | 76 oh no |
| 84 test.dart 8:33 main.<fn> | 77 test.dart 8:33 main.<fn> |
| 85 | 78 |
| 86 | |
| 87 +1 -2: success 2 | 79 +1 -2: success 2 |
| 88 +2 -2: success 2 | |
| 89 +2 -2: Some tests failed."""); | 80 +2 -2: Some tests failed."""); |
| 90 }); | 81 }); |
| 91 | 82 |
| 92 test("gracefully handles multiple test failures in a row", () { | 83 test("gracefully handles multiple test failures in a row", () { |
| 93 _expectReport(""" | 84 _expectReport(""" |
| 94 // This completer ensures that the test isolate isn't killed until all | 85 // This completer ensures that the test isolate isn't killed until all |
| 95 // errors have been thrown. | 86 // errors have been thrown. |
| 96 var completer = new Completer(); | 87 var completer = new Completer(); |
| 97 test('failures', () { | 88 test('failures', () { |
| 98 new Future.microtask(() => throw 'first error'); | 89 new Future.microtask(() => throw 'first error'); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 115 ===== asynchronous gap =========================== | 106 ===== asynchronous gap =========================== |
| 116 dart:async Future.Future.microtask | 107 dart:async Future.Future.microtask |
| 117 test.dart 11:15 main.<fn> | 108 test.dart 11:15 main.<fn> |
| 118 | 109 |
| 119 third error | 110 third error |
| 120 test.dart 12:38 main.<fn>.<fn> | 111 test.dart 12:38 main.<fn>.<fn> |
| 121 ===== asynchronous gap =========================== | 112 ===== asynchronous gap =========================== |
| 122 dart:async Future.Future.microtask | 113 dart:async Future.Future.microtask |
| 123 test.dart 12:15 main.<fn> | 114 test.dart 12:15 main.<fn> |
| 124 | 115 |
| 125 | |
| 126 +0 -1: wait | 116 +0 -1: wait |
| 127 +1 -1: wait | |
| 128 +1 -1: Some tests failed."""); | 117 +1 -1: Some tests failed."""); |
| 129 }); | 118 }); |
| 130 | 119 |
| 131 group("print:", () { | 120 group("print:", () { |
| 132 test("handles multiple prints", () { | 121 test("handles multiple prints", () { |
| 133 _expectReport(""" | 122 _expectReport(""" |
| 134 test('test', () { | 123 test('test', () { |
| 135 print("one"); | 124 print("one"); |
| 136 print("two"); | 125 print("two"); |
| 137 print("three"); | 126 print("three"); |
| 138 print("four"); | 127 print("four"); |
| 139 });""", | 128 });""", |
| 140 """ | 129 """ |
| 141 +0: test | 130 +0: test |
| 142 one | 131 one |
| 143 two | 132 two |
| 144 three | 133 three |
| 145 four | 134 four |
| 146 | |
| 147 +1: test | |
| 148 +1: All tests passed!"""); | 135 +1: All tests passed!"""); |
| 149 }); | 136 }); |
| 150 | 137 |
| 151 test("handles a print after the test completes", () { | 138 test("handles a print after the test completes", () { |
| 152 _expectReport(""" | 139 _expectReport(""" |
| 153 // This completer ensures that the test isolate isn't killed until all | 140 // This completer ensures that the test isolate isn't killed until all |
| 154 // prints have happened. | 141 // prints have happened. |
| 155 var testDone = new Completer(); | 142 var testDone = new Completer(); |
| 156 var waitStarted = new Completer(); | 143 var waitStarted = new Completer(); |
| 157 test('test', () { | 144 test('test', () { |
| 158 waitStarted.future.then((_) { | 145 waitStarted.future.then((_) { |
| 159 new Future(() => print("one")); | 146 new Future(() => print("one")); |
| 160 new Future(() => print("two")); | 147 new Future(() => print("two")); |
| 161 new Future(() => print("three")); | 148 new Future(() => print("three")); |
| 162 new Future(() => print("four")); | 149 new Future(() => print("four")); |
| 163 new Future(testDone.complete); | 150 new Future(testDone.complete); |
| 164 }); | 151 }); |
| 165 }); | 152 }); |
| 166 | 153 |
| 167 test('wait', () { | 154 test('wait', () { |
| 168 waitStarted.complete(); | 155 waitStarted.complete(); |
| 169 return testDone.future; | 156 return testDone.future; |
| 170 });""", """ | 157 });""", """ |
| 171 +0: test | 158 +0: test |
| 172 +1: test | |
| 173 +1: wait | 159 +1: wait |
| 174 +1: test | 160 +1: test |
| 175 one | 161 one |
| 176 two | 162 two |
| 177 three | 163 three |
| 178 four | 164 four |
| 179 | |
| 180 +2: wait | |
| 181 +2: All tests passed!"""); | 165 +2: All tests passed!"""); |
| 182 }); | 166 }); |
| 183 | 167 |
| 184 test("interleaves prints and errors", () { | 168 test("interleaves prints and errors", () { |
| 185 _expectReport(""" | 169 _expectReport(""" |
| 186 // This completer ensures that the test isolate isn't killed until all | 170 // This completer ensures that the test isolate isn't killed until all |
| 187 // prints have happened. | 171 // prints have happened. |
| 188 var completer = new Completer(); | 172 var completer = new Completer(); |
| 189 test('test', () { | 173 test('test', () { |
| 190 scheduleMicrotask(() { | 174 scheduleMicrotask(() { |
| (...skipping 11 matching lines...) Expand all Loading... |
| 202 print("one"); | 186 print("one"); |
| 203 print("two"); | 187 print("two"); |
| 204 throw "first error"; | 188 throw "first error"; |
| 205 }); | 189 }); |
| 206 | 190 |
| 207 test('wait', () => completer.future);""", | 191 test('wait', () => completer.future);""", |
| 208 """ | 192 """ |
| 209 +0: test | 193 +0: test |
| 210 one | 194 one |
| 211 two | 195 two |
| 212 | |
| 213 +0 -1: test | 196 +0 -1: test |
| 214 first error | 197 first error |
| 215 test.dart 24:11 main.<fn> | 198 test.dart 24:11 main.<fn> |
| 216 | 199 |
| 217 three | 200 three |
| 218 four | 201 four |
| 219 second error | 202 second error |
| 220 test.dart 13:13 main.<fn>.<fn> | 203 test.dart 13:13 main.<fn>.<fn> |
| 221 ===== asynchronous gap =========================== | 204 ===== asynchronous gap =========================== |
| 222 dart:async scheduleMicrotask | 205 dart:async scheduleMicrotask |
| 223 test.dart 10:11 main.<fn> | 206 test.dart 10:11 main.<fn> |
| 224 | 207 |
| 225 five | 208 five |
| 226 six | 209 six |
| 227 | |
| 228 +0 -1: wait | 210 +0 -1: wait |
| 229 +1 -1: wait | |
| 230 +1 -1: Some tests failed."""); | 211 +1 -1: Some tests failed."""); |
| 231 }); | 212 }); |
| 232 }); | 213 }); |
| 233 | 214 |
| 234 group("skip:", () { | 215 group("skip:", () { |
| 235 test("displays skipped tests separately", () { | 216 test("displays skipped tests separately", () { |
| 236 _expectReport(""" | 217 _expectReport(""" |
| 237 test('skip 1', () {}, skip: true); | 218 test('skip 1', () {}, skip: true); |
| 238 test('skip 2', () {}, skip: true); | 219 test('skip 2', () {}, skip: true); |
| 239 test('skip 3', () {}, skip: true);""", | 220 test('skip 3', () {}, skip: true);""", |
| 240 """ | 221 """ |
| 241 +0: skip 1 | 222 +0: skip 1 |
| 242 +0 ~1: skip 1 | |
| 243 +0 ~1: skip 2 | 223 +0 ~1: skip 2 |
| 244 +0 ~2: skip 2 | |
| 245 +0 ~2: skip 3 | 224 +0 ~2: skip 3 |
| 246 +0 ~3: skip 3 | |
| 247 +0 ~3: All tests skipped."""); | 225 +0 ~3: All tests skipped."""); |
| 248 }); | 226 }); |
| 249 | 227 |
| 250 test("runs skipped tests along with successful tests", () { | 228 test("runs skipped tests along with successful tests", () { |
| 251 _expectReport(""" | 229 _expectReport(""" |
| 252 test('skip 1', () {}, skip: true); | 230 test('skip 1', () {}, skip: true); |
| 253 test('success 1', () {}); | 231 test('success 1', () {}); |
| 254 test('skip 2', () {}, skip: true); | 232 test('skip 2', () {}, skip: true); |
| 255 test('success 2', () {});""", | 233 test('success 2', () {});""", |
| 256 """ | 234 """ |
| 257 +0: skip 1 | 235 +0: skip 1 |
| 258 +0 ~1: skip 1 | |
| 259 +0 ~1: success 1 | 236 +0 ~1: success 1 |
| 260 +1 ~1: success 1 | |
| 261 +1 ~1: skip 2 | 237 +1 ~1: skip 2 |
| 262 +1 ~2: skip 2 | |
| 263 +1 ~2: success 2 | 238 +1 ~2: success 2 |
| 264 +2 ~2: success 2 | |
| 265 +2 ~2: All tests passed!"""); | 239 +2 ~2: All tests passed!"""); |
| 266 }); | 240 }); |
| 267 | 241 |
| 268 test("runs skipped tests along with successful and failing tests", () { | 242 test("runs skipped tests along with successful and failing tests", () { |
| 269 _expectReport(""" | 243 _expectReport(""" |
| 270 test('failure 1', () => throw new TestFailure('oh no')); | 244 test('failure 1', () => throw new TestFailure('oh no')); |
| 271 test('skip 1', () {}, skip: true); | 245 test('skip 1', () {}, skip: true); |
| 272 test('success 1', () {}); | 246 test('success 1', () {}); |
| 273 test('failure 2', () => throw new TestFailure('oh no')); | 247 test('failure 2', () => throw new TestFailure('oh no')); |
| 274 test('skip 2', () {}, skip: true); | 248 test('skip 2', () {}, skip: true); |
| 275 test('success 2', () {});""", | 249 test('success 2', () {});""", |
| 276 """ | 250 """ |
| 277 +0: failure 1 | 251 +0: failure 1 |
| 278 +0 -1: failure 1 | 252 +0 -1: failure 1 |
| 279 oh no | 253 oh no |
| 280 test.dart 6:35 main.<fn> | 254 test.dart 6:35 main.<fn> |
| 281 | 255 |
| 282 | |
| 283 +0 -1: skip 1 | 256 +0 -1: skip 1 |
| 284 +0 ~1 -1: skip 1 | |
| 285 +0 ~1 -1: success 1 | 257 +0 ~1 -1: success 1 |
| 286 +1 ~1 -1: success 1 | |
| 287 +1 ~1 -1: failure 2 | 258 +1 ~1 -1: failure 2 |
| 288 +1 ~1 -2: failure 2 | 259 +1 ~1 -2: failure 2 |
| 289 oh no | 260 oh no |
| 290 test.dart 9:35 main.<fn> | 261 test.dart 9:35 main.<fn> |
| 291 | 262 |
| 292 | |
| 293 +1 ~1 -2: skip 2 | 263 +1 ~1 -2: skip 2 |
| 294 +1 ~2 -2: skip 2 | |
| 295 +1 ~2 -2: success 2 | 264 +1 ~2 -2: success 2 |
| 296 +2 ~2 -2: success 2 | |
| 297 +2 ~2 -2: Some tests failed."""); | 265 +2 ~2 -2: Some tests failed."""); |
| 298 }); | 266 }); |
| 299 | 267 |
| 300 test("displays the skip reason if available", () { | 268 test("displays the skip reason if available", () { |
| 301 _expectReport(""" | 269 _expectReport(""" |
| 302 test('skip 1', () {}, skip: 'some reason'); | 270 test('skip 1', () {}, skip: 'some reason'); |
| 303 test('skip 2', () {}, skip: 'or another');""", | 271 test('skip 2', () {}, skip: 'or another');""", |
| 304 """ | 272 """ |
| 305 +0: skip 1 | 273 +0: skip 1 |
| 306 +0 ~1: skip 1 | 274 +0 ~1: skip 1 |
| 307 Skip: some reason | 275 Skip: some reason |
| 308 | |
| 309 +0 ~1: skip 2 | 276 +0 ~1: skip 2 |
| 310 +0 ~2: skip 2 | 277 +0 ~2: skip 2 |
| 311 Skip: or another | 278 Skip: or another |
| 312 | |
| 313 +0 ~2: All tests skipped."""); | 279 +0 ~2: All tests skipped."""); |
| 314 }); | 280 }); |
| 315 }); | 281 }); |
| 316 } | 282 } |
| 317 | 283 |
| 318 void _expectReport(String tests, String expected, {List<String> args, | 284 void _expectReport(String tests, String expected, {List<String> args, |
| 319 int concurrency}) { | 285 int concurrency}) { |
| 320 if (concurrency == null) concurrency = 1; | 286 if (concurrency == null) concurrency = 1; |
| 321 | 287 |
| 322 var dart = """ | 288 var dart = """ |
| 323 import 'dart:async'; | 289 import 'dart:async'; |
| 324 | 290 |
| 325 import 'package:test/test.dart'; | 291 import 'package:test/test.dart'; |
| 326 | 292 |
| 327 void main() { | 293 void main() { |
| 328 $tests | 294 $tests |
| 329 } | 295 } |
| 330 """; | 296 """; |
| 331 | 297 |
| 332 expect(withTempDir((path) { | 298 expect(withTempDir((path) { |
| 333 new File(p.join(path, "test.dart")).writeAsStringSync(dart); | 299 new File(p.join(path, "test.dart")).writeAsStringSync(dart); |
| 334 if (args == null) args = []; | 300 if (args == null) args = []; |
| 335 args = args.toList()..add("test.dart"); | 301 args = args.toList() |
| 336 args.add("--concurrency=$concurrency"); | 302 ..add("test.dart") |
| 303 ..add("--concurrency=$concurrency") |
| 304 ..add("--reporter=expanded"); |
| 337 var result = runTest(args, workingDirectory: path); | 305 var result = runTest(args, workingDirectory: path); |
| 338 | 306 |
| 339 // Convert CRs into newlines, remove excess trailing whitespace, and trim | 307 // Remove excess trailing whitespace and trim off timestamps. |
| 340 // off timestamps. | 308 var actual = result.stdout.trim().split("\n").map((line) { |
| 341 var actual = result.stdout.trim().split(new RegExp(r"[\r\n]")).map((line) { | |
| 342 if (line.startsWith(" ") || line.isEmpty) return line.trimRight(); | 309 if (line.startsWith(" ") || line.isEmpty) return line.trimRight(); |
| 343 return line.trim().replaceFirst(new RegExp("^[0-9]{2}:[0-9]{2} "), ""); | 310 return line.trim().replaceFirst(new RegExp("^[0-9]{2}:[0-9]{2} "), ""); |
| 344 }).join("\n"); | 311 }).join("\n"); |
| 345 | 312 |
| 346 // Un-indent the expected string. | 313 // Un-indent the expected string. |
| 347 var indentation = expected.indexOf(new RegExp("[^ ]")); | 314 var indentation = expected.indexOf(new RegExp("[^ ]")); |
| 348 expected = expected.split("\n").map((line) { | 315 expected = expected.split("\n").map((line) { |
| 349 if (line.isEmpty) return line; | 316 if (line.isEmpty) return line; |
| 350 return line.substring(indentation); | 317 return line.substring(indentation); |
| 351 }).join("\n"); | 318 }).join("\n"); |
| 352 | 319 |
| 353 expect(actual, equals(expected)); | 320 expect(actual, equals(expected)); |
| 354 }), completes); | 321 }), completes); |
| 355 } | 322 } |
| OLD | NEW |