Skip to content

Commit 0a8244d

Browse files
committed
Add invalidation test coverage for other inputs.
1 parent 0a20e64 commit 0a8244d

File tree

2 files changed

+122
-3
lines changed

2 files changed

+122
-3
lines changed
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
// Copyright (c) 2025, 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+
import 'package:test/test.dart';
6+
7+
import 'invalidation_tester.dart';
8+
9+
/// Invalidation tests in which the inputs are individually read arbitrary assets.
10+
void main() {
11+
late InvalidationTester tester;
12+
13+
setUp(() {
14+
tester = InvalidationTester();
15+
});
16+
17+
group('a+(z) <-- a.1', () {
18+
setUp(() {
19+
tester.sources(['a', 'z']);
20+
tester.builder(from: '', to: '.1')
21+
..readsOther('z')
22+
..writes('.1');
23+
});
24+
25+
test('a.1 is built', () async {
26+
expect(await tester.build(), Result(written: ['a.1', 'z.1']));
27+
});
28+
29+
test('change z, a.1 is rebuilt', () async {
30+
await tester.build();
31+
expect(await tester.build(change: 'z'), Result(written: ['a.1', 'z.1']));
32+
});
33+
34+
test('delete z, a.1 is rebuilt', () async {
35+
await tester.build();
36+
expect(
37+
await tester.build(delete: 'z'),
38+
// TODO(davidmorgan): a.1 should be rebuilt, but it's not. This is a
39+
// regression since the last version on pub: fix it!
40+
// Result(written: ['a.1'], deleted: ['z.1'])
41+
Result(deleted: ['z.1']),
42+
);
43+
});
44+
45+
test('create z, a.1 is rebuilt', () async {
46+
tester.sources(['a']);
47+
expect(await tester.build(), Result(written: ['a.1']));
48+
expect(await tester.build(create: 'z'), Result(written: ['a.1', 'z.1']));
49+
});
50+
});
51+
52+
group('a.1 <== a.2, b.3+(a.2) <== b.4', () {
53+
setUp(() {
54+
tester.sources(['a.1', 'b.3']);
55+
tester.builder(from: '.1', to: '.2')
56+
..reads('.1')
57+
..writes('.2');
58+
tester.builder(from: '.3', to: '.4')
59+
..reads('.3')
60+
..readsOther('a.2')
61+
..writes('.4');
62+
});
63+
64+
test('a.4 is built', () async {
65+
expect(await tester.build(), Result(written: ['a.2', 'b.4']));
66+
});
67+
68+
test('change a.1, a.2+b.4 are rebuilt', () async {
69+
await tester.build();
70+
expect(
71+
await tester.build(change: 'a.1'),
72+
Result(written: ['a.2', 'b.4']),
73+
);
74+
});
75+
76+
test('delete a.1, a.2+b.4 are rebuilt', () async {
77+
await tester.build();
78+
expect(
79+
await tester.build(delete: 'a.1'),
80+
// TODO(davidmorgan): a.1 should be rebuilt, but it's not. This is a
81+
// regression since the last version on pub: fix it!
82+
// Result(written: ['a.2', 'b.4']),
83+
Result(deleted: ['a.2']),
84+
);
85+
});
86+
87+
test('create a.1, a.2+b.4 are rebuilt', () async {
88+
tester.sources(['b.3']);
89+
await tester.build();
90+
expect(
91+
await tester.build(create: 'a.1'),
92+
Result(written: ['a.2', 'b.4']),
93+
);
94+
});
95+
});
96+
}

build_runner_core/test/invalidation/invalidation_tester.dart

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import 'dart:async';
66
import 'dart:convert';
77

88
import 'package:build/build.dart';
9+
import 'package:build_runner_core/src/changes/asset_updates.dart';
910
import 'package:build_test/build_test.dart';
1011
import 'package:built_collection/built_collection.dart';
1112
import 'package:crypto/crypto.dart';
@@ -254,6 +255,11 @@ class TestBuilderBuilder {
254255
_builder.reads.add('$extension.dart');
255256
}
256257

258+
/// Test setup: the builder will read the asset with [name].
259+
void readsOther(String name) {
260+
_builder.otherReads.add(name);
261+
}
262+
257263
/// Test setup: the builder will write the asset that is [extension] applied
258264
/// to the primary input.
259265
///
@@ -273,10 +279,19 @@ class TestBuilder implements Builder {
273279

274280
final InvalidationTester _tester;
275281

276-
/// Assets that the builder will read.
282+
/// Extensions of assets that the builder will read.
283+
///
284+
/// The extensions are applied to the primary input asset ID with
285+
/// [AssetIdExtension.replaceAllPathExtensions].
277286
List<String> reads = [];
278287

279-
/// Assets that the builder will write.
288+
/// Names of assets that the builder will read.
289+
List<String> otherReads = [];
290+
291+
/// Extensions of assets that the builder will write.
292+
///
293+
/// The extensions are applied to the primary input asset ID with
294+
/// [AssetIdExtension.replaceAllPathExtensions].
280295
List<String> writes = [];
281296

282297
TestBuilder(this._tester, String from, Iterable<String> to, this.isOptional)
@@ -288,7 +303,15 @@ class TestBuilder implements Builder {
288303
for (final read in reads) {
289304
final readId = buildStep.inputId.replaceAllPathExtensions(read);
290305
content.add(read.toString());
291-
content.add(await buildStep.readAsString(readId));
306+
if (await buildStep.canRead(readId)) {
307+
content.add(await buildStep.readAsString(readId));
308+
}
309+
}
310+
for (final read in otherReads) {
311+
content.add(read.assetId.toString());
312+
if (await buildStep.canRead(read.assetId)) {
313+
content.add(await buildStep.readAsString(read.assetId));
314+
}
292315
}
293316
for (final write in writes) {
294317
final writeId = buildStep.inputId.replaceAllPathExtensions(write);

0 commit comments

Comments
 (0)