Skip to content

Commit 0e6460d

Browse files
authored
Implements test file_path.dart?name="test name" (#1603)
fixes #1598
1 parent 2a062cf commit 0e6460d

File tree

13 files changed

+381
-29
lines changed

13 files changed

+381
-29
lines changed

pkgs/test/CHANGELOG.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
1-
## 1.18.3-dev
1+
## 1.19.0-dev
22

3+
* Support query parameters `name` and `full-name` on test paths, which will
4+
apply the filters to only those test suites.
5+
* All specified filters must match for a test to run.
6+
* Global filters (ie: `--name`) are also still respected and must match.
37
* Give a better exception when using `markTestSkipped` outside of a test.
48

59
## 1.18.2

pkgs/test/README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,10 @@ description (including any group descriptions) match that regular expression
173173
will be run. You can also use the `-N` flag to run tests whose names contain a
174174
plain-text string.
175175

176+
Alternatively, you can filter tests by name only for a specific file/directory
177+
by specifying a query on a path: `dart test "path/to/test.dart?name=test name"`.
178+
That ensures that the name filters applies to one path but not others.
179+
176180
By default, tests are run in the Dart VM, but you can run them in the browser as
177181
well by passing `dart test -p chrome path/to/test.dart`. `test` will take
178182
care of starting the browser and loading the tests, and all the results will be

pkgs/test/pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name: test
2-
version: 1.18.3-dev
2+
version: 1.19.0-dev
33
description: >-
44
A full featured library for writing and running Dart tests across platforms.
55
repository: https://github.com/dart-lang/test/blob/master/pkgs/test

pkgs/test/test/runner/configuration/configuration_test.dart

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import 'package:path/path.dart' as p;
77
import 'package:test/test.dart';
88

9+
import 'package:test_core/src/runner/configuration.dart';
910
import 'package:test_core/src/runner/configuration/reporters.dart';
1011
import 'package:test_core/src/util/io.dart';
1112

@@ -29,7 +30,7 @@ void main() {
2930
expect(merged.shardIndex, isNull);
3031
expect(merged.totalShards, isNull);
3132
expect(merged.testRandomizeOrderingSeed, isNull);
32-
expect(merged.paths, equals(['test']));
33+
expect(merged.paths.single.testPath, 'test');
3334
});
3435

3536
test("if only the old configuration's is defined, uses it", () {
@@ -47,7 +48,7 @@ void main() {
4748
shardIndex: 3,
4849
totalShards: 10,
4950
testRandomizeOrderingSeed: 123,
50-
paths: ['bar']).merge(configuration());
51+
paths: [PathConfiguration(testPath: 'bar')]).merge(configuration());
5152

5253
expect(merged.help, isTrue);
5354
expect(merged.version, isTrue);
@@ -62,7 +63,7 @@ void main() {
6263
expect(merged.shardIndex, equals(3));
6364
expect(merged.totalShards, equals(10));
6465
expect(merged.testRandomizeOrderingSeed, 123);
65-
expect(merged.paths, equals(['bar']));
66+
expect(merged.paths.single.testPath, 'bar');
6667
});
6768

6869
test("if only the new configuration's is defined, uses it", () {
@@ -80,7 +81,7 @@ void main() {
8081
shardIndex: 3,
8182
totalShards: 10,
8283
testRandomizeOrderingSeed: 123,
83-
paths: ['bar']));
84+
paths: [PathConfiguration(testPath: 'bar')]));
8485

8586
expect(merged.help, isTrue);
8687
expect(merged.version, isTrue);
@@ -95,7 +96,7 @@ void main() {
9596
expect(merged.shardIndex, equals(3));
9697
expect(merged.totalShards, equals(10));
9798
expect(merged.testRandomizeOrderingSeed, 123);
98-
expect(merged.paths, equals(['bar']));
99+
expect(merged.paths.single.testPath, 'bar');
99100
});
100101

101102
test(
@@ -115,7 +116,7 @@ void main() {
115116
shardIndex: 2,
116117
totalShards: 4,
117118
testRandomizeOrderingSeed: 0,
118-
paths: ['bar']);
119+
paths: [PathConfiguration(testPath: 'bar')]);
119120
var newer = configuration(
120121
help: false,
121122
version: true,
@@ -130,7 +131,7 @@ void main() {
130131
shardIndex: 3,
131132
totalShards: 10,
132133
testRandomizeOrderingSeed: 123,
133-
paths: ['blech']);
134+
paths: [PathConfiguration(testPath: 'blech')]);
134135
var merged = older.merge(newer);
135136

136137
expect(merged.help, isFalse);
@@ -146,7 +147,7 @@ void main() {
146147
expect(merged.shardIndex, equals(3));
147148
expect(merged.totalShards, equals(10));
148149
expect(merged.testRandomizeOrderingSeed, 123);
149-
expect(merged.paths, equals(['blech']));
150+
expect(merged.paths.single.testPath, 'blech');
150151
});
151152
});
152153

pkgs/test/test/runner/name_test.dart

Lines changed: 283 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,289 @@ import 'package:test/test.dart';
1212
import '../io.dart';
1313

1414
void main() {
15+
group('with test.dart?name="name" query', () {
16+
test('selects tests with matching names', () async {
17+
await d.file('test.dart', '''
18+
import 'package:test/test.dart';
19+
20+
void main() {
21+
test("selected 1", () {});
22+
test("nope", () => throw TestFailure("oh no"));
23+
test("selected 2", () {});
24+
}
25+
''').create();
26+
27+
var test = await runTest(['test.dart?name=selected']);
28+
29+
expect(
30+
test.stdout,
31+
emitsThrough(contains('+2: All tests passed!')),
32+
);
33+
34+
await test.shouldExit(0);
35+
});
36+
37+
test('supports RegExp syntax', () async {
38+
await d.file('test.dart', '''
39+
import 'package:test/test.dart';
40+
41+
void main() {
42+
test("test 1", () {});
43+
test("test 2", () => throw TestFailure("oh no"));
44+
test("test 3", () {});
45+
}
46+
''').create();
47+
48+
var test = await runTest(['test.dart?name=test [13]']);
49+
50+
expect(
51+
test.stdout,
52+
emitsThrough(contains('+2: All tests passed!')),
53+
);
54+
55+
await test.shouldExit(0);
56+
});
57+
58+
test('applies only to the associated file', () async {
59+
await d.file('test.dart', '''
60+
import 'package:test/test.dart';
61+
62+
void main() {
63+
test("selected 1", () {});
64+
test("selected 2", () => throw TestFailure("oh no"));
65+
}
66+
''').create();
67+
68+
await d.file('test2.dart', '''
69+
import 'package:test/test.dart';
70+
71+
void main() {
72+
test("selected 1", () => throw TestFailure("oh no"));
73+
test("selected 2", () {});
74+
}
75+
''').create();
76+
77+
var test = await runTest(
78+
['test.dart?name=selected 1', 'test2.dart?name=selected 2'],
79+
);
80+
81+
expect(
82+
test.stdout,
83+
emitsThrough(contains('+2: All tests passed!')),
84+
);
85+
await test.shouldExit(0);
86+
});
87+
88+
test('selects more narrowly when passed multiple times', () async {
89+
await d.file('test.dart', '''
90+
import 'package:test/test.dart';
91+
92+
void main() {
93+
test("selected 1", () {});
94+
test("nope", () => throw TestFailure("oh no"));
95+
test("selected 2", () {});
96+
}
97+
''').create();
98+
99+
var test = await runTest(['test.dart?name=selected&name=1']);
100+
101+
expect(
102+
test.stdout,
103+
emitsThrough(contains('+1: All tests passed!')),
104+
);
105+
await test.shouldExit(0);
106+
});
107+
108+
test('applies to directories', () async {
109+
await d.dir('dir', [
110+
d.file('first_test.dart', '''
111+
import 'package:test/test.dart';
112+
113+
void main() {
114+
test("selected 1", () {});
115+
test("selected 2", () => throw TestFailure("oh no"));
116+
}
117+
'''),
118+
d.file('second_test.dart', '''
119+
import 'package:test/test.dart';
120+
121+
void main() {
122+
test("selected 1", () {});
123+
test("selected 2", () => throw TestFailure("oh no"));
124+
}
125+
''')
126+
]).create();
127+
128+
var test = await runTest(['dir?name=selected 1']);
129+
130+
expect(
131+
test.stdout,
132+
emitsThrough(contains('+2: All tests passed!')),
133+
);
134+
await test.shouldExit(0);
135+
});
136+
137+
test('produces an error when no tests match', () async {
138+
await d.file('test.dart', '''
139+
import 'package:test/test.dart';
140+
141+
void main() {
142+
test("test", () {});
143+
}
144+
''').create();
145+
146+
var test = await runTest(['test.dart?name=no']);
147+
148+
expect(
149+
test.stderr,
150+
emitsThrough(contains('No tests were found.')),
151+
);
152+
153+
await test.shouldExit(exit_codes.noTestsRan);
154+
});
155+
156+
test("doesn't filter out load exceptions", () async {
157+
var test = await runTest(['file?name=name']);
158+
expect(
159+
test.stdout,
160+
containsInOrder([
161+
'-1: loading file [E]',
162+
' Failed to load "file": Does not exist.'
163+
]),
164+
);
165+
166+
await test.shouldExit(1);
167+
});
168+
});
169+
170+
group('with test.dart?full-name query,', () {
171+
test('matches with the complete test name', () async {
172+
await d.file('test.dart', '''
173+
import 'package:test/test.dart';
174+
175+
void main() {
176+
test("selected", () {});
177+
test("nope", () => throw TestFailure("oh no"));
178+
test("selected nope", () => throw TestFailure("oh no"));
179+
}
180+
''').create();
181+
182+
var test = await runTest(['test.dart?full-name=selected']);
183+
184+
expect(
185+
test.stdout,
186+
emitsThrough(contains('+1: All tests passed!')),
187+
);
188+
await test.shouldExit(0);
189+
});
190+
191+
test("doesn't support RegExp syntax", () async {
192+
await d.file('test.dart', '''
193+
import 'package:test/test.dart';
194+
195+
void main() {
196+
test("test 1", () => throw TestFailure("oh no"));
197+
test("test 2", () => throw TestFailure("oh no"));
198+
test("test [12]", () {});
199+
}
200+
''').create();
201+
202+
var test = await runTest(['test.dart?full-name=test [12]']);
203+
204+
expect(
205+
test.stdout,
206+
emitsThrough(contains('+1: All tests passed!')),
207+
);
208+
await test.shouldExit(0);
209+
});
210+
211+
test('applies only to the associated file', () async {
212+
await d.file('test.dart', '''
213+
import 'package:test/test.dart';
214+
215+
void main() {
216+
test("selected 1", () {});
217+
test("selected 2", () => throw TestFailure("oh no"));
218+
}
219+
''').create();
220+
221+
await d.file('test2.dart', '''
222+
import 'package:test/test.dart';
223+
224+
void main() {
225+
test("selected 1", () => throw TestFailure("oh no"));
226+
test("selected 2", () {});
227+
}
228+
''').create();
229+
230+
var test = await runTest(
231+
['test.dart?full-name=selected 1', 'test2.dart?full-name=selected 2'],
232+
);
233+
234+
expect(
235+
test.stdout,
236+
emitsThrough(contains('+2: All tests passed!')),
237+
);
238+
await test.shouldExit(0);
239+
});
240+
241+
test('produces an error when no tests match', () async {
242+
await d.file('test.dart', '''
243+
import 'package:test/test.dart';
244+
245+
void main() {
246+
test("test", () {});
247+
}
248+
''').create();
249+
250+
var test = await runTest(['test.dart?full-name=no match']);
251+
252+
expect(
253+
test.stderr,
254+
emitsThrough(contains('No tests were found.')),
255+
);
256+
await test.shouldExit(exit_codes.noTestsRan);
257+
});
258+
});
259+
260+
test('test?name="name" and --name narrow the selection', () async {
261+
await d.file('test.dart', '''
262+
import 'package:test/test.dart';
263+
264+
void main() {
265+
test("selected 1", () {});
266+
test("nope 1", () => throw TestFailure("oh no"));
267+
test("selected 2", () => throw TestFailure("oh no"));
268+
test("nope 2", () => throw TestFailure("oh no"));
269+
}
270+
''').create();
271+
272+
var test = await runTest(['--name', '1', 'test.dart?name=selected']);
273+
274+
expect(
275+
test.stdout,
276+
emitsThrough(contains('+1: All tests passed!')),
277+
);
278+
await test.shouldExit(0);
279+
});
280+
281+
test('test?name="name" and test?full-name="name" throws', () async {
282+
await d.file('test.dart', '''
283+
import 'package:test/test.dart';
284+
285+
void main() {
286+
test("selected 1", () {});
287+
test("nope 1", () => throw TestFailure("oh no"));
288+
test("selected 2", () => throw TestFailure("oh no"));
289+
test("nope 2", () => throw TestFailure("oh no"));
290+
}
291+
''').create();
292+
293+
var test = await runTest(['test.dart?name=selected&full-name=selected 1']);
294+
295+
await test.shouldExit(255);
296+
});
297+
15298
group('with the --name flag,', () {
16299
test('selects tests with matching names', () async {
17300
await d.file('test.dart', '''

0 commit comments

Comments
 (0)