OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2013, 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: |
| 6 // Test on Windows. |
| 7 // Status files. |
| 8 |
| 9 library testrunner_test; |
| 10 |
| 11 import 'dart:async'; |
| 12 import 'dart:io'; |
| 13 import 'package:unittest/unittest.dart'; |
| 14 |
| 15 var dart; |
| 16 var debug = false; |
| 17 |
| 18 Future runTestrunner(command, List<String> args, |
| 19 List<String> stdout, List<String> stderr) { |
| 20 var completer = new Completer(); |
| 21 Process.run(command, args).then((ProcessResult result) { |
| 22 var lineEndings = new RegExp("\r\n|\n"); |
| 23 stdout.addAll(result.stdout.trim().split(lineEndings)); |
| 24 stderr.addAll(result.stderr.trim().split(lineEndings)); |
| 25 completer.complete(); |
| 26 }) |
| 27 .catchError((e) { |
| 28 stderr.add("Error starting process:"); |
| 29 stderr.add(" Command: $command"); |
| 30 stderr.add(" Error: ${e}"); |
| 31 completer.complete(-1); |
| 32 }); |
| 33 return completer.future; |
| 34 } |
| 35 |
| 36 // Useful utility for debugging test failures. |
| 37 void dump(label, list) { |
| 38 if (!debug) return; |
| 39 print('\n@=[ $label ]=============================\n'); |
| 40 for (var i = 0; i < list.length; i++) |
| 41 print('@ ${list[i]}\n'); |
| 42 print('------------------------------------------\n'); |
| 43 } |
| 44 |
| 45 int stringCompare(String s1, String s2) => s1.compareTo(s2); |
| 46 |
| 47 Future runTest( |
| 48 List<String> args, |
| 49 List<String> expected_stdout, |
| 50 {List<String> expected_stderr, sort: false}) { |
| 51 var stdout = new List<String>(); |
| 52 var stderr = new List<String>(); |
| 53 for (var i = 0; i < expected_stdout.length; i++) { |
| 54 expected_stdout[i] = expected_stdout[i]. |
| 55 replaceAll('/', Platform.pathSeparator); |
| 56 } |
| 57 var rtn = runTestrunner(dart, args, stdout, stderr); |
| 58 rtn.then((_) { |
| 59 dump('stderr', stderr); |
| 60 dump('stdout', stdout); |
| 61 |
| 62 if (expected_stderr != null) { |
| 63 expect(stderr.length, orderedEquals(expected_stderr)); |
| 64 } |
| 65 var i, l = 0, matched = 0; |
| 66 if (sort) { |
| 67 stdout.sort(stringCompare); |
| 68 expected_stdout.sort(stringCompare); |
| 69 } |
| 70 for (i = 0; i < stdout.length; i++) { |
| 71 if (!stdout[i].startsWith('@')) { |
| 72 if (expected_stdout.length <= l) { |
| 73 fail("Extra text in output: ${stdout[i]}"); |
| 74 return; |
| 75 } |
| 76 var actual = stdout[i].trim(); |
| 77 if (debug) { |
| 78 print("Compare <$actual> and <${expected_stdout[l]}>"); |
| 79 } |
| 80 if (expected_stdout[l].startsWith('*')) { |
| 81 expect(actual, endsWith(expected_stdout[l].substring(1))); |
| 82 } else if (expected_stdout[l].startsWith('?')) { |
| 83 var pat = expected_stdout[l].substring(1); |
| 84 if (Platform.operatingSystem == 'windows') { |
| 85 // The joys of Windows... |
| 86 pat = pat.replaceAll('\\','\\\\'); |
| 87 } |
| 88 expect(actual, matches(pat)); |
| 89 } else { |
| 90 expect(actual, expected_stdout[l]); |
| 91 } |
| 92 ++l; |
| 93 } |
| 94 } |
| 95 if (l < expected_stdout.length) { |
| 96 fail("Only matched $l of ${expected_stdout.length} lines"); |
| 97 } |
| 98 }); |
| 99 return rtn; |
| 100 } |
| 101 |
| 102 // A useful function to quickly disable a group of tests; just |
| 103 // replace group() with skip_group(). |
| 104 skip_group(_1,_2) {} |
| 105 |
| 106 main() { |
| 107 var opt = new Options(); |
| 108 dart = opt.executable; |
| 109 var idx = dart.indexOf('dart-sdk'); |
| 110 if (idx < 0) { |
| 111 print("Please run using the dart executable from the Dart SDK"); |
| 112 exit(-1); |
| 113 } |
| 114 var _ = Platform.pathSeparator; |
| 115 var testrunner = '../../testrunner/testrunner.dart' |
| 116 .replaceAll('/', Platform.pathSeparator); |
| 117 |
| 118 group("list tests", () { |
| 119 test('list file', () { |
| 120 return runTest( |
| 121 [ testrunner, |
| 122 '--list-files', |
| 123 'non_browser_tests' ], |
| 124 [ '?.*/non_browser_tests/non_browser_test.dart' ]); |
| 125 }); |
| 126 test('list files', () { |
| 127 return runTest( |
| 128 [ testrunner, |
| 129 '--recurse', |
| 130 '--sort', |
| 131 '--list-files', |
| 132 '--test-file-pattern=.dart\$' ], |
| 133 [ '*browser_tests/web/browser_test.dart', |
| 134 '*http_client_tests/http_client_test.dart', |
| 135 '*layout_tests/web/layout_test.dart', |
| 136 '*non_browser_tests/non_browser_test.dart', |
| 137 '*non_browser_tests/non_browser_toast.dart', |
| 138 '*/testrunner_test.dart' ] |
| 139 ); |
| 140 }); |
| 141 test('list files', () { |
| 142 return runTest( |
| 143 [ testrunner, |
| 144 '--list-files', |
| 145 '--test-file-pattern=.dart\$', |
| 146 'non_browser_tests' ], |
| 147 [ '*non_browser_tests/non_browser_test.dart', |
| 148 '*non_browser_tests/non_browser_toast.dart' ], |
| 149 sort:true |
| 150 ); |
| 151 }); |
| 152 test('list groups', () { |
| 153 return runTest( |
| 154 [ testrunner, |
| 155 '--list-groups', |
| 156 'non_browser_tests' ], |
| 157 [ '*non_browser_tests/non_browser_test.dart group1', |
| 158 '*non_browser_tests/non_browser_test.dart group2']); |
| 159 }); |
| 160 test('list tests', () { |
| 161 return runTest( |
| 162 [ testrunner, |
| 163 '--list-tests', |
| 164 'non_browser_tests' ], |
| 165 [ '*non_browser_tests/non_browser_test.dart group1 test1', |
| 166 '*non_browser_tests/non_browser_test.dart group2 test2' ]); |
| 167 }); |
| 168 }); |
| 169 |
| 170 group("vm", () { |
| 171 test("vm without timing info", () { |
| 172 return runTest( |
| 173 [ testrunner, |
| 174 '--recurse', |
| 175 'non_browser_tests' ], |
| 176 [ '?FAIL .*/non_browser_tests/non_browser_test.dart group1 test1' |
| 177 ' Expected: false', |
| 178 '?PASS .*/non_browser_tests/non_browser_test.dart group2 test2' ]); |
| 179 }); |
| 180 |
| 181 test("vm with timing info", () { |
| 182 return runTest( |
| 183 [ testrunner, |
| 184 '--recurse', |
| 185 '--time', |
| 186 'non_browser_tests' ], |
| 187 [ '?FAIL [0-9.]+s .*/non_browser_tests/non_browser_test.dart group1' |
| 188 ' test1 Expected: false', |
| 189 '?PASS [0-9.]+s .*/non_browser_tests/non_browser_test.dart group2' |
| 190 ' test2' ]); |
| 191 }); |
| 192 }); |
| 193 |
| 194 group("selection", () { |
| 195 test("--include", () { |
| 196 return runTest( |
| 197 [ testrunner, |
| 198 '--recurse', |
| 199 '--include=group1', |
| 200 'non_browser_tests' ], |
| 201 [ '?FAIL .*/non_browser_tests/non_browser_test.dart group1 test1 ' |
| 202 'Expected: false' ]); |
| 203 }); |
| 204 |
| 205 test("--exclude", () { |
| 206 return runTest( |
| 207 [ testrunner, |
| 208 '--recurse', |
| 209 '--exclude=group1', |
| 210 'non_browser_tests' ], |
| 211 [ '?PASS .*/non_browser_tests/non_browser_test.dart group2 test2' ]); |
| 212 }); |
| 213 |
| 214 test("test file pattern", () { |
| 215 return runTest( |
| 216 [ testrunner, |
| 217 '--recurse', |
| 218 '--test-file-pattern=toast', |
| 219 'non_browser_tests' ], |
| 220 [ '?PASS .*/non_browser_tests/non_browser_toast.dart foo bar' ]); |
| 221 }); |
| 222 }); |
| 223 |
| 224 group("stop on failure tests", () { |
| 225 test("without stop", () { |
| 226 return runTest( |
| 227 [ testrunner, |
| 228 '--recurse', |
| 229 '--sort', |
| 230 '--tasks=1', |
| 231 '--test-file-pattern=.dart\$', |
| 232 'non_browser_tests' ], |
| 233 [ '?FAIL .*/non_browser_tests/non_browser_test.dart group1 test1 ' |
| 234 'Expected: false', |
| 235 '?PASS .*/non_browser_tests/non_browser_test.dart group2 test2', |
| 236 '?PASS .*/non_browser_tests/non_browser_toast.dart foo bar' ]); |
| 237 }); |
| 238 test("with stop", () { |
| 239 return runTest( |
| 240 [ testrunner, |
| 241 '--recurse', |
| 242 '--sort', |
| 243 '--tasks=1', |
| 244 '--test-file-pattern=.dart\$', |
| 245 '--stop-on-failure', |
| 246 'non_browser_tests' ], |
| 247 [ '?FAIL .*/non_browser_tests/non_browser_test.dart group1 test1 ' |
| 248 'Expected: false', |
| 249 '?PASS .*/non_browser_tests/non_browser_test.dart group2 test2' ]); |
| 250 }); |
| 251 }); |
| 252 |
| 253 group("output control", () { |
| 254 test("summary test", () { |
| 255 return runTest( |
| 256 [ testrunner, |
| 257 '--recurse', |
| 258 '--summary', |
| 259 'non_browser_tests' ], |
| 260 [ '?FAIL .*/non_browser_tests/non_browser_test.dart group1 test1 ' |
| 261 'Expected: false', |
| 262 '?PASS .*/non_browser_tests/non_browser_test.dart group2 test2', |
| 263 '', |
| 264 '?.*/non_browser_tests/non_browser_test.dart: ' |
| 265 '1 PASSED, 1 FAILED, 0 ERRORS' ]); |
| 266 }); |
| 267 |
| 268 test('list tests with custom format', () { |
| 269 return runTest( |
| 270 [ testrunner, |
| 271 '--list-tests', |
| 272 '--list-format="<FILENAME><TESTNAME>"', |
| 273 'non_browser_tests' ], |
| 274 [ '?.*/non_browser_tests/non_browser_test.dart test1', |
| 275 '?.*/non_browser_tests/non_browser_test.dart test2' ]); |
| 276 }); |
| 277 |
| 278 test("custom message formatting", () { |
| 279 return runTest( |
| 280 [ testrunner, |
| 281 '--recurse', |
| 282 '--pass-format=YIPPEE! <GROUPNAME><TESTNAME>', |
| 283 '--fail-format=EPIC FAIL! <GROUPNAME><TESTNAME>', |
| 284 'non_browser_tests' ], |
| 285 [ 'EPIC FAIL! group1 test1', 'YIPPEE! group2 test2' ]); |
| 286 }); |
| 287 }); |
| 288 |
| 289 test("checked mode test", () { |
| 290 return runTest( |
| 291 [ testrunner, |
| 292 '--recurse', |
| 293 '--checked', |
| 294 'non_browser_tests' ], |
| 295 [ '?FAIL .*/non_browser_tests/non_browser_test.dart group1 test1 ' |
| 296 'Expected: false', |
| 297 "?FAIL .*/non_browser_tests/non_browser_test.dart group2 test2 " |
| 298 "Caught type 'int' is not a subtype of type 'bool' of 'x'." ]); |
| 299 }); |
| 300 |
| 301 group("browser", () { |
| 302 test("native test", () { |
| 303 return runTest( |
| 304 [ testrunner, |
| 305 '--recurse', |
| 306 '--runtime=drt-dart', |
| 307 'browser_tests' ], |
| 308 [ '?FAIL .*/browser_tests/web/browser_test.dart group1 test1 ' |
| 309 'Expected: false', |
| 310 '?PASS .*/browser_tests/web/browser_test.dart group2 test2' ]); |
| 311 }); |
| 312 |
| 313 test("compiled test", () { |
| 314 return runTest( |
| 315 [ testrunner, |
| 316 '--recurse', |
| 317 '--runtime=drt-js', |
| 318 'browser_tests' ], |
| 319 [ '?FAIL .*/browser_tests/web/browser_test.dart group1 test1 ' |
| 320 'Expected: false', |
| 321 '?PASS .*/browser_tests/web/browser_test.dart group2 test2' ]); |
| 322 }); |
| 323 }); |
| 324 |
| 325 group("textual layout tests", () { |
| 326 group("drt-dart", () { |
| 327 test("no baseline", () { |
| 328 var f = new File("layout_tests/web/layout_test/layout.txt"); |
| 329 if (f.existsSync()) { |
| 330 f.deleteSync(); |
| 331 } |
| 332 return runTest( |
| 333 [ testrunner, |
| 334 '--runtime=drt-dart', |
| 335 '--recurse', |
| 336 '--layout-text', |
| 337 'layout_tests' ], |
| 338 [ '?FAIL .*/layout_tests/web/layout_test.dart layout ' |
| 339 'No expectation file' ]); |
| 340 }); |
| 341 test("create baseline", () { |
| 342 return runTest( |
| 343 [ testrunner, |
| 344 '--runtime=drt-dart', |
| 345 '--recurse', |
| 346 '--layout-text', |
| 347 '--regenerate', |
| 348 'layout_tests' ], |
| 349 [ '?PASS .*/layout_tests/web/layout_test.dart layout' ]); |
| 350 }); |
| 351 test("test baseline", () { |
| 352 return runTest( |
| 353 [ testrunner, |
| 354 '--runtime=drt-dart', |
| 355 '--recurse', |
| 356 '--layout-text', |
| 357 'layout_tests' ], |
| 358 [ '?PASS .*/layout_tests/web/layout_test.dart layout' ]); |
| 359 }); |
| 360 }); |
| 361 group("drt-js", () { |
| 362 test("no baseline", () { |
| 363 var f = new File("layout_tests/web/layout_test/layout.txt"); |
| 364 if (f.existsSync()) { |
| 365 f.deleteSync(); |
| 366 } |
| 367 return runTest( |
| 368 [ testrunner, |
| 369 '--runtime=drt-js', |
| 370 '--recurse', |
| 371 '--layout-text', |
| 372 'layout_tests' ], |
| 373 [ '?FAIL .*/layout_tests/web/layout_test.dart layout ' |
| 374 'No expectation file' ]); |
| 375 }); |
| 376 test("create baseline", () { |
| 377 return runTest( |
| 378 [ testrunner, |
| 379 '--runtime=drt-js', |
| 380 '--recurse', |
| 381 '--layout-text', |
| 382 '--regenerate', |
| 383 'layout_tests' ], |
| 384 [ '?PASS .*/layout_tests/web/layout_test.dart layout' ]); |
| 385 }); |
| 386 test("test baseline", () { |
| 387 return runTest( |
| 388 [ testrunner, |
| 389 '--runtime=drt-js', |
| 390 '--recurse', |
| 391 '--layout-text', |
| 392 'layout_tests' ], |
| 393 [ '?PASS .*/layout_tests/web/layout_test.dart layout' ]); |
| 394 }); |
| 395 }); |
| 396 }); |
| 397 |
| 398 group("pixel layout tests", () { |
| 399 group("drt-dart", () { |
| 400 test("no baseline", () { |
| 401 var f = new File("layout_tests/web/layout_test/layout.png"); |
| 402 if (f.existsSync()) { |
| 403 f.deleteSync(); |
| 404 } |
| 405 return runTest( |
| 406 [ testrunner, |
| 407 '--runtime=drt-dart', |
| 408 '--recurse', |
| 409 '--layout-pixel', |
| 410 'layout_tests' ], |
| 411 [ '?FAIL .*/layout_tests/web/layout_test.dart layout ' |
| 412 'No expectation file' ]); |
| 413 }); |
| 414 test("create baseline", () { |
| 415 return runTest( |
| 416 [ testrunner, |
| 417 '--runtime=drt-dart', |
| 418 '--recurse', |
| 419 '--layout-pixel', |
| 420 '--regenerate', |
| 421 'layout_tests' ], |
| 422 [ '?PASS .*/layout_tests/web/layout_test.dart layout' ]); |
| 423 }); |
| 424 test("test baseline", () { |
| 425 return runTest( |
| 426 [ testrunner, |
| 427 '--runtime=drt-dart', |
| 428 '--recurse', |
| 429 '--layout-pixel', |
| 430 'layout_tests' ], |
| 431 [ '?PASS .*/layout_tests/web/layout_test.dart layout' ]); |
| 432 }); |
| 433 // TODO(gram): Should add a test that changes a byte of the |
| 434 // expectation .png. |
| 435 }); |
| 436 group("drt-js", () { |
| 437 test("no baseline", () { |
| 438 var f = new File("layout_tests/web/layout_test/layout.png"); |
| 439 if (f.existsSync()) { |
| 440 f.deleteSync(); |
| 441 } |
| 442 return runTest( |
| 443 [ testrunner, |
| 444 '--runtime=drt-js', |
| 445 '--recurse', |
| 446 '--layout-pixel', |
| 447 'layout_tests' ], |
| 448 [ '?FAIL .*/layout_tests/web/layout_test.dart layout ' |
| 449 'No expectation file' ]); |
| 450 }); |
| 451 test("create baseline", () { |
| 452 return runTest( |
| 453 [ testrunner, |
| 454 '--runtime=drt-js', |
| 455 '--recurse', |
| 456 '--layout-pixel', |
| 457 '--regenerate', |
| 458 'layout_tests' ], |
| 459 [ '?PASS .*/layout_tests/web/layout_test.dart layout' ]); |
| 460 }); |
| 461 test("test baseline", () { |
| 462 return runTest( |
| 463 [ testrunner, |
| 464 '--runtime=drt-js', |
| 465 '--recurse', |
| 466 '--layout-pixel', |
| 467 'layout_tests' ], |
| 468 [ '?PASS .*/layout_tests/web/layout_test.dart layout' ]); |
| 469 }); |
| 470 }); |
| 471 }); |
| 472 |
| 473 group("run in isolate", () { |
| 474 test("vm", () { |
| 475 return runTest( |
| 476 [ testrunner, |
| 477 '--runtime=vm', |
| 478 '--recurse', |
| 479 '--isolate', |
| 480 'non_browser_tests' ], |
| 481 [ '?FAIL .*/non_browser_tests/non_browser_test.dart group1 test1' |
| 482 ' Expected: false', |
| 483 '?PASS .*/non_browser_tests/non_browser_test.dart group2 test2' ]); |
| 484 }); |
| 485 test("drt-dart", () { |
| 486 return runTest( |
| 487 [ testrunner, |
| 488 '--runtime=drt-dart', |
| 489 '--recurse', |
| 490 '--isolate', |
| 491 'non_browser_tests' ], |
| 492 [ '?FAIL .*/non_browser_tests/non_browser_test.dart group1 test1' |
| 493 ' Expected: false', |
| 494 '?PASS .*/non_browser_tests/non_browser_test.dart group2 test2' ]); |
| 495 }); |
| 496 test("drt-js", () { |
| 497 return runTest( |
| 498 [ testrunner, |
| 499 '--runtime=drt-js', |
| 500 '--recurse', |
| 501 '--isolate', |
| 502 'non_browser_tests' ], |
| 503 [ '?FAIL .*/non_browser_tests/non_browser_test.dart group1 test1 ' |
| 504 'Expected: false', |
| 505 '?PASS .*/non_browser_tests/non_browser_test.dart group2 test2' ]); |
| 506 }); |
| 507 }); |
| 508 |
| 509 group("embedded server", () { |
| 510 test("get test", () { |
| 511 return runTest( |
| 512 [ testrunner, |
| 513 '--recurse', |
| 514 '--server', |
| 515 '--port=3456', |
| 516 '--root=${new Directory.current().path}', |
| 517 'http_client_tests' ], |
| 518 [ '?PASS .*/http_client_tests/http_client_test.dart test1', |
| 519 '?PASS .*/http_client_tests/http_client_test.dart test2' ]); |
| 520 }); |
| 521 }); |
| 522 } |
| 523 |
OLD | NEW |