@@ -21,6 +21,12 @@ class InvalidationTester {
21
21
/// The source assets on disk before the first build.
22
22
final Set <AssetId > _sourceAssets = {};
23
23
24
+ /// Import statements.
25
+ ///
26
+ /// If an asset has an entry here then sources and generated sources will
27
+ /// start with the import statements specified.
28
+ final Map <String , List <String >> _importGraph = {};
29
+
24
30
/// The builders that will run.
25
31
final List <TestBuilder > _builders = [];
26
32
@@ -43,6 +49,9 @@ class InvalidationTester {
43
49
/// The build number for "printOnFailure" output.
44
50
int _buildNumber = 0 ;
45
51
52
+ /// Output number, for writing outputs that are different.
53
+ int _outputNumber = 0 ;
54
+
46
55
/// Sets the assets that will be on disk before the first build.
47
56
///
48
57
/// See the note on "names" in the class dartdoc.
@@ -53,6 +62,12 @@ class InvalidationTester {
53
62
}
54
63
}
55
64
65
+ // Sets the import graph for source files and generated files.
66
+ void importGraph (Map <String , List <String >> importGraph) {
67
+ _importGraph.clear ();
68
+ _importGraph.addAll (importGraph);
69
+ }
70
+
56
71
/// Adds a builder to the test.
57
72
///
58
73
/// [from] and [to] are the input and output extension of the builder,
@@ -106,6 +121,13 @@ class InvalidationTester {
106
121
_failureStrategies[name.assetId] = FailureStrategy .succeed;
107
122
}
108
123
124
+ String _imports (AssetId id) {
125
+ final imports = _importGraph[_assetIdToName (id)];
126
+ return imports == null
127
+ ? ''
128
+ : imports.map ((i) => "import '${i .pathForImport }';" ).join ('\n ' );
129
+ }
130
+
109
131
/// Does a build.
110
132
///
111
133
/// For the initial build, do not pass [change] [delete] or [create] .
@@ -120,7 +142,7 @@ class InvalidationTester {
120
142
throw StateError ('Do a build without change, delete or create first.' );
121
143
}
122
144
for (final id in _sourceAssets) {
123
- assets[id] = '// initial source' ;
145
+ assets[id] = '${ _imports ( id )} // initial source' ;
124
146
}
125
147
} else {
126
148
// Create the new filesystem from the previous build state.
@@ -131,7 +153,8 @@ class InvalidationTester {
131
153
132
154
// Make the requested updates.
133
155
if (change != null ) {
134
- assets[change.assetId] = '${assets [change .assetId ]}\n // changed' ;
156
+ assets[change.assetId] =
157
+ '${_imports (change .assetId )}}\n // ${++_outputNumber }' ;
135
158
}
136
159
if (delete != null ) {
137
160
if (assets.containsKey (delete.assetId)) {
@@ -148,7 +171,7 @@ class InvalidationTester {
148
171
if (assets.containsKey (create.assetId)) {
149
172
throw StateError ('Asset $create to create already exists in: $assets ' );
150
173
}
151
- assets[create.assetId] = '// initial source' ;
174
+ assets[create.assetId] = '${ _imports ( create . assetId )} // initial source' ;
152
175
}
153
176
154
177
// Build and check what changed.
@@ -259,6 +282,11 @@ class TestBuilderBuilder {
259
282
_builder.otherReads.add (name);
260
283
}
261
284
285
+ /// Test setup: the builder will parse the Dart source asset with [name] .
286
+ void resolvesOther (String name) {
287
+ _builder.otherResolves.add (name);
288
+ }
289
+
262
290
/// Test setup: the builder will write the asset that is [extension] applied
263
291
/// to the primary input.
264
292
///
@@ -287,6 +315,9 @@ class TestBuilder implements Builder {
287
315
/// Names of assets that the builder will read.
288
316
List <String > otherReads = [];
289
317
318
+ /// Names of assets that the builder will resolve.
319
+ List <String > otherResolves = [];
320
+
290
321
/// Extensions of assets that the builder will write.
291
322
///
292
323
/// The extensions are applied to the primary input asset ID with
@@ -312,14 +343,21 @@ class TestBuilder implements Builder {
312
343
content.add (await buildStep.readAsString (read.assetId));
313
344
}
314
345
}
346
+ for (final resolve in otherResolves) {
347
+ content.add (resolve.assetId.toString ());
348
+ await buildStep.resolver.libraryFor (resolve.assetId);
349
+ }
315
350
for (final write in writes) {
316
351
final writeId = buildStep.inputId.replaceAllPathExtensions (write);
317
352
final outputStrategy =
318
353
_tester._outputStrategies[writeId] ?? OutputStrategy .inputDigest;
354
+ final inputHash = base64.encode (
355
+ md5.convert (utf8.encode (content.join ('\n\n ' ))).bytes,
356
+ );
319
357
final output = switch (outputStrategy) {
320
- OutputStrategy .fixed => '' ,
358
+ OutputStrategy .fixed => _tester. _imports (writeId) ,
321
359
OutputStrategy .inputDigest =>
322
- '// ${ base64 . encode ( md5 . convert ( utf8 . encode ( content . join ( ' \n\n ' ))). bytes )} ' ,
360
+ '${ _tester . _imports ( writeId )} \n // $ inputHash ' ,
323
361
OutputStrategy .none => null ,
324
362
};
325
363
if (output != null ) {
@@ -354,6 +392,9 @@ extension StringExtension on String {
354
392
AssetId get generatedAssetId =>
355
393
AssetId ('pkg' , '.dart_tool/build/generated/pkg/lib/$this .dart' );
356
394
395
+ /// Maps "names" to relative import path.
396
+ String get pathForImport => '$this .dart' ;
397
+
357
398
/// Displays trimmed and with two space indent.
358
399
String get trimAndIndent => ' ${toString ().trim ().replaceAll ('\n ' , '\n ' )}' ;
359
400
}
0 commit comments