| // 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 'package:test_descriptor/test_descriptor.dart' as d; |
| |
| import 'package:test/test.dart'; |
| |
| import '../io.dart'; |
| |
| void main() { |
| setUp(() async { |
| await d.file("test.dart", """ |
| import 'package:test/test.dart'; |
| |
| void main() { |
| test("no tags", () {}); |
| test("a", () {}, tags: "a"); |
| test("b", () {}, tags: "b"); |
| test("bc", () {}, tags: ["b", "c"]); |
| } |
| """).create(); |
| }); |
| |
| group("--tags", () { |
| test("runs all tests when no tags are specified", () async { |
| var test = await runTest(["test.dart"]); |
| expect(test.stdout, tagWarnings(['a', 'b', 'c'])); |
| expect(test.stdout, emitsThrough(contains(": no tags"))); |
| expect(test.stdout, emitsThrough(contains(": a"))); |
| expect(test.stdout, emitsThrough(contains(": b"))); |
| expect(test.stdout, emitsThrough(contains(": bc"))); |
| expect(test.stdout, emitsThrough(contains("+4: All tests passed!"))); |
| await test.shouldExit(0); |
| }); |
| |
| test("runs a test with only a specified tag", () async { |
| var test = await runTest(["--tags=a", "test.dart"]); |
| expect(test.stdout, tagWarnings(['b', 'c'])); |
| expect(test.stdout, emitsThrough(contains(": a"))); |
| expect(test.stdout, emitsThrough(contains("+1: All tests passed!"))); |
| await test.shouldExit(0); |
| }); |
| |
| test("runs a test with a specified tag among others", () async { |
| var test = await runTest(["--tags=c", "test.dart"]); |
| expect(test.stdout, tagWarnings(['a', 'b'])); |
| expect(test.stdout, emitsThrough(contains(": bc"))); |
| expect(test.stdout, emitsThrough(contains("+1: All tests passed!"))); |
| await test.shouldExit(0); |
| }); |
| |
| test("with multiple tags, runs only tests matching all of them", () async { |
| var test = await runTest(["--tags=b,c", "test.dart"]); |
| expect(test.stdout, tagWarnings(['a'])); |
| expect(test.stdout, emitsThrough(contains(": bc"))); |
| expect(test.stdout, emitsThrough(contains("+1: All tests passed!"))); |
| await test.shouldExit(0); |
| }); |
| |
| test("supports boolean selector syntax", () async { |
| var test = await runTest(["--tags=b || c", "test.dart"]); |
| expect(test.stdout, tagWarnings(['a'])); |
| expect(test.stdout, emitsThrough(contains(": b"))); |
| expect(test.stdout, emitsThrough(contains(": bc"))); |
| expect(test.stdout, emitsThrough(contains("+2: All tests passed!"))); |
| await test.shouldExit(0); |
| }); |
| |
| test("prints no warnings when all tags are specified", () async { |
| var test = await runTest(["--tags=a,b,c", "test.dart"]); |
| expect(test.stdout, emitsThrough(contains("No tests ran."))); |
| await test.shouldExit(0); |
| }); |
| }); |
| |
| group("--exclude-tags", () { |
| test("dosn't run a test with only an excluded tag", () async { |
| var test = await runTest(["--exclude-tags=a", "test.dart"]); |
| expect(test.stdout, tagWarnings(['b', 'c'])); |
| expect(test.stdout, emitsThrough(contains(": no tags"))); |
| expect(test.stdout, emitsThrough(contains(": b"))); |
| expect(test.stdout, emitsThrough(contains(": bc"))); |
| expect(test.stdout, emitsThrough(contains("+3: All tests passed!"))); |
| await test.shouldExit(0); |
| }); |
| |
| test("doesn't run a test with an exluded tag among others", () async { |
| var test = await runTest(["--exclude-tags=c", "test.dart"]); |
| expect(test.stdout, tagWarnings(['a', 'b'])); |
| expect(test.stdout, emitsThrough(contains(": no tags"))); |
| expect(test.stdout, emitsThrough(contains(": a"))); |
| expect(test.stdout, emitsThrough(contains(": b"))); |
| expect(test.stdout, emitsThrough(contains("+3: All tests passed!"))); |
| await test.shouldExit(0); |
| }); |
| |
| test("dosn't load a suite with an excluded tag", () async { |
| await d.file("test.dart", """ |
| @Tags(const ["a"]) |
| |
| import 'package:test/test.dart'; |
| |
| void main() { |
| throw "error"; |
| } |
| """).create(); |
| |
| var test = await runTest(["--exclude-tags=a", "test.dart"]); |
| expect(test.stdout, emits("No tests ran.")); |
| await test.shouldExit(0); |
| }); |
| |
| test("allows unused tags", () async { |
| var test = await runTest(["--exclude-tags=b,z", "test.dart"]); |
| expect(test.stdout, tagWarnings(['a', 'c'])); |
| expect(test.stdout, emitsThrough(contains(": no tags"))); |
| expect(test.stdout, emitsThrough(contains(": a"))); |
| expect(test.stdout, emitsThrough(contains("+2: All tests passed!"))); |
| await test.shouldExit(0); |
| }); |
| |
| test("supports boolean selector syntax", () async { |
| var test = await runTest(["--exclude-tags=b && c", "test.dart"]); |
| expect(test.stdout, tagWarnings(['a'])); |
| expect(test.stdout, emitsThrough(contains(": no tags"))); |
| expect(test.stdout, emitsThrough(contains(": a"))); |
| expect(test.stdout, emitsThrough(contains(": b"))); |
| expect(test.stdout, emitsThrough(contains("+3: All tests passed!"))); |
| await test.shouldExit(0); |
| }); |
| |
| test("prints no warnings when all tags are specified", () async { |
| var test = await runTest(["--exclude-tags=a,b,c", "test.dart"]); |
| expect(test.stdout, emitsThrough(contains(": no tags"))); |
| expect(test.stdout, emitsThrough(contains("+1: All tests passed!"))); |
| await test.shouldExit(0); |
| }); |
| }); |
| |
| group("with a tagged group", () { |
| setUp(() async { |
| await d.file("test.dart", """ |
| import 'package:test/test.dart'; |
| |
| void main() { |
| group("a", () { |
| test("in", () {}); |
| }, tags: "a"); |
| |
| test("out", () {}); |
| } |
| """).create(); |
| }); |
| |
| test("includes tags specified on the group", () async { |
| var test = await runTest(["-x", "a", "test.dart"]); |
| expect(test.stdout, emitsThrough(contains(": out"))); |
| expect(test.stdout, emitsThrough(contains("+1: All tests passed!"))); |
| await test.shouldExit(0); |
| }); |
| |
| test("excludes tags specified on the group", () async { |
| var test = await runTest(["-t", "a", "test.dart"]); |
| expect(test.stdout, emitsThrough(contains(": a in"))); |
| expect(test.stdout, emitsThrough(contains("+1: All tests passed!"))); |
| await test.shouldExit(0); |
| }); |
| }); |
| |
| test('respects top-level @Tags annotations', () async { |
| await d.file("test.dart", """ |
| @Tags(const ['a']) |
| import 'package:test/test.dart'; |
| |
| void main() { |
| test("foo", () {}); |
| } |
| """).create(); |
| |
| var test = await runTest(["-x", "a", "test.dart"]); |
| expect(test.stdout, emitsThrough(contains("No tests ran"))); |
| await test.shouldExit(0); |
| }); |
| |
| group("warning formatting", () { |
| test("for multiple tags", () async { |
| await d.file("test.dart", """ |
| import 'package:test/test.dart'; |
| |
| void main() { |
| test("foo", () {}, tags: ["a", "b"]); |
| } |
| """).create(); |
| |
| var test = await runTest(["test.dart"]); |
| expect( |
| test.stdout, |
| emitsThrough(lines( |
| 'Warning: Tags were used that weren\'t specified in dart_test.yaml.\n' |
| ' a was used in the test "foo"\n' |
| ' b was used in the test "foo"'))); |
| await test.shouldExit(0); |
| }); |
| |
| test("for multiple tests", () async { |
| await d.file("test.dart", """ |
| import 'package:test/test.dart'; |
| |
| void main() { |
| test("foo", () {}, tags: "a"); |
| test("bar", () {}, tags: "a"); |
| } |
| """).create(); |
| |
| var test = await runTest(["test.dart"]); |
| expect( |
| test.stdout, |
| emitsThrough(lines( |
| 'Warning: A tag was used that wasn\'t specified in dart_test.yaml.\n' |
| ' a was used in:\n' |
| ' the test "foo"\n' |
| ' the test "bar"'))); |
| await test.shouldExit(0); |
| }); |
| |
| test("for groups", () async { |
| await d.file("test.dart", """ |
| import 'package:test/test.dart'; |
| |
| void main() { |
| group("group", () { |
| test("foo", () {}); |
| test("bar", () {}); |
| }, tags: "a"); |
| } |
| """).create(); |
| |
| var test = await runTest(["test.dart"]); |
| expect( |
| test.stdout, |
| emitsThrough(lines( |
| 'Warning: A tag was used that wasn\'t specified in dart_test.yaml.\n' |
| ' a was used in the group "group"'))); |
| await test.shouldExit(0); |
| }); |
| |
| test("for suites", () async { |
| await d.file("test.dart", """ |
| @Tags(const ["a"]) |
| import 'package:test/test.dart'; |
| |
| void main() { |
| test("foo", () {}); |
| test("bar", () {}); |
| } |
| """).create(); |
| |
| var test = await runTest(["test.dart"]); |
| expect( |
| test.stdout, |
| emitsThrough(lines( |
| 'Warning: A tag was used that wasn\'t specified in dart_test.yaml.\n' |
| ' a was used in the suite itself'))); |
| await test.shouldExit(0); |
| }); |
| |
| test("doesn't double-print a tag warning", () async { |
| await d.file("test.dart", """ |
| import 'package:test/test.dart'; |
| |
| void main() { |
| test("foo", () {}, tags: "a"); |
| } |
| """).create(); |
| |
| var test = await runTest(["-p", "vm,content-shell", "test.dart"]); |
| expect( |
| test.stdout, |
| emitsThrough(lines( |
| 'Warning: A tag was used that wasn\'t specified in dart_test.yaml.\n' |
| ' a was used in the test "foo"'))); |
| expect(test.stdout, neverEmits(startsWith("Warning:"))); |
| await test.shouldExit(0); |
| }, tags: "content-shell"); |
| }); |
| |
| group("invalid tags", () { |
| test("are disallowed by test()", () async { |
| await d.file("test.dart", """ |
| import 'package:test/test.dart'; |
| |
| void main() { |
| test("foo", () {}, tags: "a b"); |
| } |
| """).create(); |
| |
| var test = await runTest(["test.dart"]); |
| expect( |
| test.stdout, |
| emitsThrough( |
| ' Failed to load "test.dart": Invalid argument(s): Invalid tag "a ' |
| 'b". Tags must be (optionally hyphenated) Dart identifiers.')); |
| await test.shouldExit(1); |
| }); |
| |
| test("are disallowed by group()", () async { |
| await d.file("test.dart", """ |
| import 'package:test/test.dart'; |
| |
| void main() { |
| group("group", () { |
| test("foo", () {}); |
| }, tags: "a b"); |
| } |
| """).create(); |
| |
| var test = await runTest(["test.dart"]); |
| expect( |
| test.stdout, |
| emitsThrough( |
| ' Failed to load "test.dart": Invalid argument(s): Invalid tag "a ' |
| 'b". Tags must be (optionally hyphenated) Dart identifiers.')); |
| await test.shouldExit(1); |
| }); |
| |
| test("are disallowed by @Tags()", () async { |
| await d.file("test.dart", """ |
| @Tags(const ["a b"]) |
| |
| import 'package:test/test.dart'; |
| |
| void main() { |
| test("foo", () {}); |
| } |
| """).create(); |
| |
| var test = await runTest(["test.dart"]); |
| expect( |
| test.stdout, |
| emitsThrough(lines(' Failed to load "test.dart":\n' |
| ' Error on line 1, column 22: Invalid tag name. Tags must be ' |
| '(optionally hyphenated) Dart identifiers.'))); |
| await test.shouldExit(1); |
| }); |
| }); |
| } |
| |
| /// Returns a [StreamMatcher] that asserts that a test emits warnings for [tags] |
| /// in order. |
| StreamMatcher tagWarnings(List<String> tags) => emitsInOrder(() sync* { |
| yield emitsThrough( |
| "Warning: ${tags.length == 1 ? 'A tag was' : 'Tags were'} used that " |
| "${tags.length == 1 ? "wasn't" : "weren't"} specified in " |
| "dart_test.yaml."); |
| |
| for (var tag in tags) { |
| yield emitsThrough(startsWith(" $tag was used in")); |
| } |
| |
| // Consume until the end of the warning block, and assert that it has no |
| // further tags than the ones we specified. |
| yield mayEmitMultiple(isNot(anyOf([contains(" was used in"), isEmpty]))); |
| yield isEmpty; |
| }()); |
| |
| /// Returns a [StreamMatcher] that matches the lines of [string] in order. |
| StreamMatcher lines(String string) => emitsInOrder(string.split("\n")); |