build
build copied to clipboard
Add a testPostProcessingBuilder helper to build_test
While testing builders I noticed that testBuilder
only work for normal builders, but not for PostProcessBuilder
. Having a testPostProcessingBuilder
would be a nice addition. We have something like this in our code right now:
Future testPostProcessingBuilder(PostProcessBuilder builder,
Map<String, /*String|List<int>*/ dynamic> sourceAssets,
{Set<String> generateFor,
bool Function(String assetId) isInput,
String rootPackage,
MultiPackageAssetReader reader,
RecordingAssetWriter writer,
Map<
String,
/*String|List<int>|Matcher<String|List<int>>*/
dynamic>
outputs,
void Function(LogRecord log) onLog}) async {
writer ??= InMemoryAssetWriter();
final inMemoryReader = InMemoryAssetReader(rootPackage: rootPackage);
if (reader != null) {
reader = MultiAssetReader([inMemoryReader, reader]);
} else {
reader = inMemoryReader;
}
var inputIds = <AssetId>[];
sourceAssets.forEach((serializedId, contents) {
var id = makeAssetId(serializedId);
if (contents is String) {
inMemoryReader.cacheStringAsset(id, contents);
} else if (contents is List<int>) {
inMemoryReader.cacheBytesAsset(id, contents);
}
inputIds.add(id);
});
var allPackages = inMemoryReader.assets.keys.map((a) => a.package).toSet();
for (var pkg in allPackages) {
for (var dir in const ['lib', 'web', 'test']) {
var asset = AssetId(pkg, '$dir/\$$dir\$');
inputIds.add(asset);
}
}
isInput ??= generateFor?.contains ?? (_) => true;
inputIds = inputIds.where((id) => isInput('$id')).toList();
var writerSpy = AssetWriterSpy(writer);
var logger = Logger('testPostProcessingBuilder');
var logSubscription = logger.onRecord.listen(onLog);
var actualOutputs = {for (var i in inputIds) i.path: i};
for (var inputId in inputIds) {
await runPostProcessBuilder(builder, inputId, reader, writerSpy, logger,
addAsset: (a) => actualOutputs[a.path] = a,
deleteAsset: (a) => actualOutputs.remove(a.path));
}
await logSubscription.cancel();
writerSpy.assetsWritten.forEach((a) => actualOutputs[a.path] = a);
checkOutputs(outputs, actualOutputs.values, writer);
}
Which can be used like:
await testPostProcessingBuilder(
builder,
{
'builders|test/delete.txt': 'delete.txt',
'builders|test/keep.txt': 'keep.txt',
'builders|delete/test.json': 'delete.json',
},
outputs: {'builders|test/keep.txt': isNull},
onLog: print);
Do you think this is worth a PR? How do you test post processing builders, did I miss something?
@Fox32 this seems reasonable to me - I think we just rely on integration testing for our post processing builders (we have very few and they do very little).
But some unit testing helpers would definitely be good!
I will prepare a PR 🙂
I will prepare a PR 🙂
Did you ever manage to finish your PR?
Actually not 😆 I was working on it and noticed that is a bit more complex than I expected. On the other hand I noticed that I also might lack understanding of the internals to really implement a test harness that works as the real code. The code I posted above is wrong on so many levels 😆