Index: mojo/public/dart/third_party/test/test/runner/runner_test.dart |
diff --git a/mojo/public/dart/third_party/test/test/runner/runner_test.dart b/mojo/public/dart/third_party/test/test/runner/runner_test.dart |
new file mode 100644 |
index 0000000000000000000000000000000000000000..8817b8b17001f2dff58a35dd28ed0ddb58a6b988 |
--- /dev/null |
+++ b/mojo/public/dart/third_party/test/test/runner/runner_test.dart |
@@ -0,0 +1,682 @@ |
+// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file |
+// for details. All rights reserved. Use of this source code is governed by a |
+// BSD-style license that can be found in the LICENSE file. |
+ |
+@TestOn("vm") |
+ |
+import 'dart:io'; |
+import 'dart:math' as math; |
+ |
+import 'package:path/path.dart' as p; |
+import 'package:scheduled_test/descriptor.dart' as d; |
+import 'package:scheduled_test/scheduled_stream.dart'; |
+import 'package:scheduled_test/scheduled_test.dart'; |
+import 'package:test/src/util/exit_codes.dart' as exit_codes; |
+ |
+import '../io.dart'; |
+ |
+final _success = """ |
+import 'dart:async'; |
+ |
+import 'package:test/test.dart'; |
+ |
+void main() { |
+ test("success", () {}); |
+} |
+"""; |
+ |
+final _failure = """ |
+import 'dart:async'; |
+ |
+import 'package:test/test.dart'; |
+ |
+void main() { |
+ test("failure", () => throw new TestFailure("oh no")); |
+} |
+"""; |
+ |
+final _defaultConcurrency = math.max(1, Platform.numberOfProcessors ~/ 2); |
+ |
+final _browsers = |
+ "[vm (default), dartium, content-shell, chrome, phantomjs, firefox" + |
+ (Platform.isMacOS ? ", safari" : "") + |
+ (Platform.isWindows ? ", ie" : "") + "]"; |
+ |
+final _usage = """ |
+Usage: pub run test:test [files or directories...] |
+ |
+-h, --help Shows this usage information. |
+ --version Shows the package's version. |
+-n, --name A substring of the name of the test to run. |
+ Regular expression syntax is supported. |
+ |
+-N, --plain-name A plain-text substring of the name of the test to run. |
+-p, --platform The platform(s) on which to run the tests. |
+ $_browsers |
+ |
+-j, --concurrency=<threads> The number of concurrent test suites run. |
+ (defaults to $_defaultConcurrency) |
+ |
+ --pub-serve=<port> The port of a pub serve instance serving "test/". |
+ --pause-after-load Pauses for debugging before any tests execute. |
+ Implies --concurrency=1. |
+ Currently only supported for browser tests. |
+ |
+-r, --reporter The runner used to print test results. |
+ |
+ [compact] A single line, updated continuously. |
+ [expanded] A separate line for each update. |
+ |
+ --verbose-trace Whether to emit stack traces with core library frames. |
+ --js-trace Whether to emit raw JavaScript stack traces for browser tests. |
+ --[no-]color Whether to use terminal colors. |
+ (auto-detected by default) |
+"""; |
+ |
+void main() { |
+ useSandbox(); |
+ |
+ test("prints help information", () { |
+ var test = runTest(["--help"]); |
+ expectStdoutEquals(test, """ |
+Runs tests in this package. |
+ |
+$_usage"""); |
+ test.shouldExit(0); |
+ }); |
+ |
+ group("fails gracefully if", () { |
+ test("an invalid option is passed", () { |
+ var test = runTest(["--asdf"]); |
+ expectStderrEquals(test, """ |
+Could not find an option named "asdf". |
+ |
+$_usage"""); |
+ test.shouldExit(exit_codes.usage); |
+ }); |
+ |
+ test("a non-existent file is passed", () { |
+ var test = runTest(["file"]); |
+ test.stdout.expect(containsInOrder([ |
+ '-1: loading file', |
+ 'Failed to load "file": Does not exist.' |
+ ])); |
+ test.shouldExit(1); |
+ }); |
+ |
+ test("the default directory doesn't exist", () { |
+ var test = runTest([]); |
+ expectStderrEquals(test, """ |
+No test files were passed and the default "test/" directory doesn't exist. |
+ |
+$_usage"""); |
+ test.shouldExit(exit_codes.data); |
+ }); |
+ |
+ test("a test file fails to load", () { |
+ d.file("test.dart", "invalid Dart file").create(); |
+ var test = runTest(["test.dart"]); |
+ |
+ test.stdout.expect(containsInOrder([ |
+ '-1: loading test.dart', |
+ 'Failed to load "test.dart":', |
+ "line 1 pos 1: unexpected token 'invalid'", |
+ "invalid Dart file", |
+ "^" |
+ ])); |
+ test.shouldExit(1); |
+ }); |
+ |
+ // This syntax error is detected lazily, and so requires some extra |
+ // machinery to support. |
+ test("a test file fails to parse due to a missing semicolon", () { |
+ d.file("test.dart", "void main() {foo}").create(); |
+ var test = runTest(["test.dart"]); |
+ |
+ test.stdout.expect(containsInOrder([ |
+ '-1: loading test.dart', |
+ 'Failed to load "test.dart":', |
+ 'line 1 pos 17: semicolon expected', |
+ 'void main() {foo}', |
+ ' ^' |
+ ])); |
+ test.shouldExit(1); |
+ }); |
+ |
+ // This is slightly different from the above test because it's an error |
+ // that's caught first by the analyzer when it's used to parse the file. |
+ test("a test file fails to parse", () { |
+ d.file("test.dart", "@TestOn)").create(); |
+ var test = runTest(["test.dart"]); |
+ |
+ test.stdout.expect(containsInOrder([ |
+ '-1: loading test.dart', |
+ 'Failed to load "test.dart":', |
+ "line 1 pos 8: unexpected token ')'", |
+ "@TestOn)", |
+ " ^" |
+ ])); |
+ test.shouldExit(1); |
+ }); |
+ |
+ test("an annotation's structure is invalid", () { |
+ d.file("test.dart", "@TestOn()\nlibrary foo;").create(); |
+ var test = runTest(["test.dart"]); |
+ |
+ test.stdout.expect(containsInOrder([ |
+ '-1: loading test.dart', |
+ 'Failed to load "test.dart":', |
+ "Error on line 1, column 8: TestOn takes 1 argument.", |
+ "@TestOn()", |
+ " ^^" |
+ ])); |
+ test.shouldExit(1); |
+ }); |
+ |
+ test("an annotation's contents are invalid", () { |
+ d.file("test.dart", "@TestOn('zim')\nlibrary foo;").create(); |
+ var test = runTest(["test.dart"]); |
+ |
+ test.stdout.expect(containsInOrder([ |
+ '-1: loading test.dart', |
+ 'Failed to load "test.dart":', |
+ "Error on line 1, column 10: Undefined variable.", |
+ "@TestOn('zim')", |
+ " ^^^" |
+ ])); |
+ test.shouldExit(1); |
+ }); |
+ |
+ test("a test file throws", () { |
+ d.file("test.dart", "void main() => throw 'oh no';").create(); |
+ var test = runTest(["test.dart"]); |
+ |
+ test.stdout.expect(containsInOrder([ |
+ '-1: loading test.dart', |
+ 'Failed to load "test.dart": oh no' |
+ ])); |
+ test.shouldExit(1); |
+ }); |
+ |
+ test("a test file doesn't have a main defined", () { |
+ d.file("test.dart", "void foo() {}").create(); |
+ var test = runTest(["test.dart"]); |
+ |
+ test.stdout.expect(containsInOrder([ |
+ '-1: loading test.dart', |
+ 'Failed to load "test.dart": No top-level main() function defined.' |
+ ])); |
+ test.shouldExit(1); |
+ }); |
+ |
+ test("a test file has a non-function main", () { |
+ d.file("test.dart", "int main;").create(); |
+ var test = runTest(["test.dart"]); |
+ |
+ test.stdout.expect(containsInOrder([ |
+ '-1: loading test.dart', |
+ 'Failed to load "test.dart": Top-level main getter is not a function.' |
+ ])); |
+ test.shouldExit(1); |
+ }); |
+ |
+ test("a test file has a main with arguments", () { |
+ d.file("test.dart", "void main(arg) {}").create(); |
+ var test = runTest(["test.dart"]); |
+ |
+ test.stdout.expect(containsInOrder([ |
+ '-1: loading test.dart', |
+ 'Failed to load "test.dart": Top-level main() function takes arguments.' |
+ ])); |
+ test.shouldExit(1); |
+ }); |
+ |
+ test("multiple load errors occur", () { |
+ d.file("test.dart", "invalid Dart file").create(); |
+ var test = runTest(["test.dart", "nonexistent.dart"]); |
+ |
+ test.stdout.expect(containsInOrder([ |
+ 'loading nonexistent.dart', |
+ 'Failed to load "nonexistent.dart": Does not exist.', |
+ 'loading test.dart', |
+ 'Failed to load "test.dart":', |
+ "line 1 pos 1: unexpected token 'invalid'", |
+ "invalid Dart file", |
+ "^" |
+ ])); |
+ test.shouldExit(1); |
+ }); |
+ |
+ // TODO(nweiz): test what happens when a test file is unreadable once issue |
+ // 15078 is fixed. |
+ }); |
+ |
+ group("runs successful tests", () { |
+ test("defined in a single file", () { |
+ d.file("test.dart", _success).create(); |
+ var test = runTest(["test.dart"]); |
+ test.stdout.expect(consumeThrough(contains("+1: All tests passed!"))); |
+ test.shouldExit(0); |
+ }); |
+ |
+ test("defined in a directory", () { |
+ for (var i = 0; i < 3; i++) { |
+ d.file("${i}_test.dart", _success).create(); |
+ } |
+ |
+ var test = runTest(["."]); |
+ test.stdout.expect(consumeThrough(contains("+3: All tests passed!"))); |
+ test.shouldExit(0); |
+ }); |
+ |
+ test("defaulting to the test directory", () { |
+ d.dir("test", new Iterable.generate(3, (i) { |
+ return d.file("${i}_test.dart", _success); |
+ })).create(); |
+ |
+ var test = runTest([]); |
+ test.stdout.expect(consumeThrough(contains("+3: All tests passed!"))); |
+ test.shouldExit(0); |
+ }); |
+ |
+ test("directly", () { |
+ d.file("test.dart", _success).create(); |
+ var test = runDart([ |
+ "--package-root=${p.join(packageDir, 'packages')}", |
+ "test.dart" |
+ ]); |
+ |
+ test.stdout.expect(consumeThrough(contains("All tests passed!"))); |
+ test.shouldExit(0); |
+ }); |
+ |
+ // Regression test; this broke in 0.12.0-beta.9. |
+ test("on a file in a subdirectory", () { |
+ d.dir("dir", [d.file("test.dart", _success)]).create(); |
+ |
+ var test = runTest(["dir/test.dart"]); |
+ test.stdout.expect(consumeThrough(contains("+1: All tests passed!"))); |
+ test.shouldExit(0); |
+ }); |
+ }); |
+ |
+ group("runs failing tests", () { |
+ test("defined in a single file", () { |
+ d.file("test.dart", _failure).create(); |
+ |
+ var test = runTest(["test.dart"]); |
+ test.stdout.expect(consumeThrough(contains("-1: Some tests failed."))); |
+ test.shouldExit(1); |
+ }); |
+ |
+ test("defined in a directory", () { |
+ for (var i = 0; i < 3; i++) { |
+ d.file("${i}_test.dart", _failure).create(); |
+ } |
+ |
+ var test = runTest(["."]); |
+ test.stdout.expect(consumeThrough(contains("-3: Some tests failed."))); |
+ test.shouldExit(1); |
+ }); |
+ |
+ test("defaulting to the test directory", () { |
+ d.dir("test", new Iterable.generate(3, (i) { |
+ return d.file("${i}_test.dart", _failure); |
+ })).create(); |
+ |
+ var test = runTest([]); |
+ test.stdout.expect(consumeThrough(contains("-3: Some tests failed."))); |
+ test.shouldExit(1); |
+ }); |
+ |
+ test("directly", () { |
+ d.file("test.dart", _failure).create(); |
+ var test = runDart([ |
+ "--package-root=${p.join(packageDir, 'packages')}", |
+ "test.dart" |
+ ]); |
+ test.stdout.expect(consumeThrough(contains("Some tests failed."))); |
+ test.shouldExit(255); |
+ }); |
+ }); |
+ |
+ test("runs tests even when a file fails to load", () { |
+ d.file("test.dart", _success).create(); |
+ |
+ var test = runTest(["test.dart", "nonexistent.dart"]); |
+ test.stdout.expect(consumeThrough(contains("+1 -1: Some tests failed."))); |
+ test.shouldExit(1); |
+ }); |
+ |
+ test("respects top-level @Timeout declarations", () { |
+ d.file("test.dart", ''' |
+@Timeout(const Duration(seconds: 0)) |
+ |
+import 'dart:async'; |
+ |
+import 'package:test/test.dart'; |
+ |
+void main() { |
+ test("timeout", () {}); |
+} |
+''').create(); |
+ |
+ var test = runTest(["test.dart"]); |
+ test.stdout.expect(containsInOrder([ |
+ "Test timed out after 0 seconds.", |
+ "-1: Some tests failed." |
+ ])); |
+ test.shouldExit(1); |
+ }); |
+ |
+ test("respects top-level @Skip declarations", () { |
+ d.file("test.dart", ''' |
+@Skip() |
+ |
+import 'dart:async'; |
+ |
+import 'package:test/test.dart'; |
+ |
+void main() { |
+ test("fail", () => throw 'oh no'); |
+} |
+''').create(); |
+ |
+ var test = runTest(["test.dart"]); |
+ test.stdout.expect(consumeThrough(contains("+0 ~1: All tests skipped."))); |
+ test.shouldExit(0); |
+ }); |
+ |
+ group("with onPlatform", () { |
+ test("respects matching Skips", () { |
+ d.file("test.dart", ''' |
+import 'dart:async'; |
+ |
+import 'package:test/test.dart'; |
+ |
+void main() { |
+ test("fail", () => throw 'oh no', onPlatform: {"vm": new Skip()}); |
+} |
+''').create(); |
+ |
+ var test = runTest(["test.dart"]); |
+ test.stdout.expect(consumeThrough(contains("+0 ~1: All tests skipped."))); |
+ test.shouldExit(0); |
+ }); |
+ |
+ test("ignores non-matching Skips", () { |
+ d.file("test.dart", ''' |
+import 'dart:async'; |
+ |
+import 'package:test/test.dart'; |
+ |
+void main() { |
+ test("success", () {}, onPlatform: {"chrome": new Skip()}); |
+} |
+''').create(); |
+ |
+ var test = runTest(["test.dart"]); |
+ test.stdout.expect(consumeThrough(contains("+1: All tests passed!"))); |
+ test.shouldExit(0); |
+ }); |
+ |
+ test("respects matching Timeouts", () { |
+ d.file("test.dart", ''' |
+import 'dart:async'; |
+ |
+import 'package:test/test.dart'; |
+ |
+void main() { |
+ test("fail", () => throw 'oh no', onPlatform: { |
+ "vm": new Timeout(new Duration(seconds: 0)) |
+ }); |
+} |
+''').create(); |
+ |
+ var test = runTest(["test.dart"]); |
+ test.stdout.expect(containsInOrder([ |
+ "Test timed out after 0 seconds.", |
+ "-1: Some tests failed." |
+ ])); |
+ test.shouldExit(1); |
+ }); |
+ |
+ test("ignores non-matching Timeouts", () { |
+ d.file("test.dart", ''' |
+import 'dart:async'; |
+ |
+import 'package:test/test.dart'; |
+ |
+void main() { |
+ test("success", () {}, onPlatform: { |
+ "chrome": new Timeout(new Duration(seconds: 0)) |
+ }); |
+} |
+''').create(); |
+ |
+ var test = runTest(["test.dart"]); |
+ test.stdout.expect(consumeThrough(contains("+1: All tests passed!"))); |
+ test.shouldExit(0); |
+ }); |
+ |
+ test("applies matching platforms in order", () { |
+ d.file("test.dart", ''' |
+import 'dart:async'; |
+ |
+import 'package:test/test.dart'; |
+ |
+void main() { |
+ test("success", () {}, onPlatform: { |
+ "vm": new Skip("first"), |
+ "vm || windows": new Skip("second"), |
+ "vm || linux": new Skip("third"), |
+ "vm || mac-os": new Skip("fourth"), |
+ "vm || android": new Skip("fifth") |
+ }); |
+} |
+''').create(); |
+ |
+ var test = runTest(["test.dart"]); |
+ test.stdout.fork().expect(never(contains("Skip: first"))); |
+ test.stdout.fork().expect(never(contains("Skip: second"))); |
+ test.stdout.fork().expect(never(contains("Skip: third"))); |
+ test.stdout.fork().expect(never(contains("Skip: fourth"))); |
+ test.stdout.expect(consumeThrough(contains("Skip: fifth"))); |
+ test.shouldExit(0); |
+ }); |
+ }); |
+ |
+ group("with an @OnPlatform annotation", () { |
+ test("respects matching Skips", () { |
+ d.file("test.dart", ''' |
+@OnPlatform(const {"vm": const Skip()}) |
+ |
+import 'dart:async'; |
+ |
+import 'package:test/test.dart'; |
+ |
+void main() { |
+ test("fail", () => throw 'oh no'); |
+} |
+''').create(); |
+ |
+ var test = runTest(["test.dart"]); |
+ test.stdout.expect(consumeThrough(contains("+0 ~1: All tests skipped."))); |
+ test.shouldExit(0); |
+ }); |
+ |
+ test("ignores non-matching Skips", () { |
+ d.file("test.dart", ''' |
+@OnPlatform(const {"chrome": const Skip()}) |
+ |
+import 'dart:async'; |
+ |
+import 'package:test/test.dart'; |
+ |
+void main() { |
+ test("success", () {}); |
+} |
+''').create(); |
+ |
+ var test = runTest(["test.dart"]); |
+ test.stdout.expect(consumeThrough(contains("+1: All tests passed!"))); |
+ test.shouldExit(0); |
+ }); |
+ |
+ test("respects matching Timeouts", () { |
+ d.file("test.dart", ''' |
+@OnPlatform(const { |
+ "vm": const Timeout(const Duration(seconds: 0)) |
+}) |
+ |
+import 'dart:async'; |
+ |
+import 'package:test/test.dart'; |
+ |
+void main() { |
+ test("fail", () => throw 'oh no'); |
+} |
+''').create(); |
+ |
+ var test = runTest(["test.dart"]); |
+ test.stdout.expect(containsInOrder([ |
+ "Test timed out after 0 seconds.", |
+ "-1: Some tests failed." |
+ ])); |
+ test.shouldExit(1); |
+ }); |
+ |
+ test("ignores non-matching Timeouts", () { |
+ d.file("test.dart", ''' |
+@OnPlatform(const { |
+ "chrome": const Timeout(const Duration(seconds: 0)) |
+}) |
+ |
+import 'dart:async'; |
+ |
+import 'package:test/test.dart'; |
+ |
+void main() { |
+ test("success", () {}); |
+} |
+''').create(); |
+ |
+ var test = runTest(["test.dart"]); |
+ test.stdout.expect(consumeThrough(contains("+1: All tests passed!"))); |
+ test.shouldExit(0); |
+ }); |
+ }); |
+ |
+ group("flags:", () { |
+ test("with the --color flag, uses colors", () { |
+ d.file("test.dart", _failure).create(); |
+ var test = runTest(["--color", "test.dart"]); |
+ // This is the color code for red. |
+ test.stdout.expect(consumeThrough(contains("\u001b[31m"))); |
+ test.shouldExit(); |
+ }); |
+ |
+ group("with the --name flag,", () { |
+ test("selects tests with matching names", () { |
+ d.file("test.dart", """ |
+import 'dart:async'; |
+ |
+import 'package:test/test.dart'; |
+ |
+void main() { |
+ test("selected 1", () {}); |
+ test("nope", () => throw new TestFailure("oh no")); |
+ test("selected 2", () {}); |
+} |
+""").create(); |
+ |
+ var test = runTest(["--name", "selected", "test.dart"]); |
+ test.stdout.expect(consumeThrough(contains("+2: All tests passed!"))); |
+ test.shouldExit(0); |
+ }); |
+ |
+ test("supports RegExp syntax", () { |
+ d.file("test.dart", """ |
+import 'dart:async'; |
+ |
+import 'package:test/test.dart'; |
+ |
+void main() { |
+ test("test 1", () {}); |
+ test("test 2", () => throw new TestFailure("oh no")); |
+ test("test 3", () {}); |
+} |
+""").create(); |
+ |
+ var test = runTest(["--name", "test [13]", "test.dart"]); |
+ test.stdout.expect(consumeThrough(contains("+2: All tests passed!"))); |
+ test.shouldExit(0); |
+ }); |
+ |
+ test("produces an error when no tests match", () { |
+ d.file("test.dart", _success).create(); |
+ |
+ var test = runTest(["--name", "no match", "test.dart"]); |
+ test.stderr.expect(consumeThrough( |
+ contains('No tests match regular expression "no match".'))); |
+ test.shouldExit(exit_codes.data); |
+ }); |
+ |
+ test("doesn't filter out load exceptions", () { |
+ var test = runTest(["--name", "name", "file"]); |
+ test.stdout.expect(containsInOrder([ |
+ '-1: loading file', |
+ ' Failed to load "file": Does not exist.' |
+ ])); |
+ test.shouldExit(1); |
+ }); |
+ }); |
+ |
+ group("with the --plain-name flag,", () { |
+ test("selects tests with matching names", () { |
+ d.file("test.dart", """ |
+import 'dart:async'; |
+ |
+import 'package:test/test.dart'; |
+ |
+void main() { |
+ test("selected 1", () {}); |
+ test("nope", () => throw new TestFailure("oh no")); |
+ test("selected 2", () {}); |
+} |
+""").create(); |
+ |
+ var test = runTest(["--plain-name", "selected", "test.dart"]); |
+ test.stdout.expect(consumeThrough(contains("+2: All tests passed!"))); |
+ test.shouldExit(0); |
+ }); |
+ |
+ test("doesn't support RegExp syntax", () { |
+ d.file("test.dart", """ |
+import 'dart:async'; |
+ |
+import 'package:test/test.dart'; |
+ |
+void main() { |
+ test("test 1", () => throw new TestFailure("oh no")); |
+ test("test 2", () => throw new TestFailure("oh no")); |
+ test("test [12]", () {}); |
+} |
+""").create(); |
+ |
+ var test = runTest(["--plain-name", "test [12]", "test.dart"]); |
+ test.stdout.expect(consumeThrough(contains("+1: All tests passed!"))); |
+ test.shouldExit(0); |
+ }); |
+ |
+ test("produces an error when no tests match", () { |
+ d.file("test.dart", _success).create(); |
+ |
+ var test = runTest(["--plain-name", "no match", "test.dart"]); |
+ test.stderr.expect( |
+ consumeThrough(contains('No tests match "no match".'))); |
+ test.shouldExit(exit_codes.data); |
+ }); |
+ }); |
+ }); |
+} |