| Index: pkg/barback/test/utils.dart
|
| diff --git a/pkg/barback/test/utils.dart b/pkg/barback/test/utils.dart
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..d53db181c2f7ba82c341e1ba4a98d14150c1353b
|
| --- /dev/null
|
| +++ b/pkg/barback/test/utils.dart
|
| @@ -0,0 +1,255 @@
|
| +// Copyright (c) 2013, 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.
|
| +
|
| +import 'dart:async';
|
| +
|
| +import 'package:barback/barback.dart';
|
| +import 'package:barback/transformer.dart';
|
| +import 'package:barback/src/asset_graph.dart';
|
| +import 'package:scheduled_test/scheduled_test.dart';
|
| +
|
| +// TODO(rnystrom): Get rid of this or find a better path for it.
|
| +import '../../../sdk/lib/_internal/pub/test/command_line_config.dart';
|
| +
|
| +var configured = false;
|
| +void initConfig() {
|
| + if (configured) return;
|
| + configured = true;
|
| + unittestConfiguration = new CommandLineConfiguration();
|
| +}
|
| +
|
| +/// Expects that [graph] will return an asset matching [name] and [contents].
|
| +void expectAsset(AssetGraph graph, String name, [String contents = ""]) {
|
| + var id = AssetId.parse(name);
|
| + schedule(() {
|
| + return graph.getAssetById(id).then((asset) {
|
| + // TODO(rnystrom): Make an actual Matcher class for this.
|
| + expect(asset is MockAsset, isTrue);
|
| + expect(asset._id.package, equals(id.package));
|
| + expect(asset._id.path, equals(id.path));
|
| + expect(asset._contents, equals(contents));
|
| + });
|
| + }, "get asset $name");
|
| +}
|
| +
|
| +/// Expects that [graph] will not find an asset matching [name].
|
| +void expectNoAsset(AssetGraph graph, String name) {
|
| + var id = AssetId.parse(name);
|
| +
|
| + // Make sure the future gets the error.
|
| + schedule(() {
|
| + return graph.getAssetById(id).then((asset) {
|
| + fail("Should have thrown error but got $asset.");
|
| + }).catchError((error) {
|
| + expect(error is AssetNotFoundException, isTrue);
|
| + expect(error.id, equals(id));
|
| + });
|
| + }, "get asset $name");
|
| +
|
| + // And we get it from the build results too.
|
| + schedule(() {
|
| + return graph.results.first.then((result) {
|
| + expect(result.error is AssetNotFoundException, isTrue);
|
| + expect(result.error.id, equals(id));
|
| + });
|
| + }, "get build result for error");
|
| +}
|
| +
|
| +/// Expects that [graph] will have an output file collision error on an asset
|
| +/// matching [name].
|
| +Future expectCollision(AssetGraph graph, String name) {
|
| + var id = AssetId.parse(name);
|
| + return schedule(() {
|
| + return graph.results.first.then((result) {
|
| + expect(result.error is AssetCollisionException, isTrue);
|
| + expect(result.error.id, equals(id));
|
| + });
|
| + }, "get collision on $name");
|
| +}
|
| +
|
| +/// Expects that [graph] will have an error on an asset matching [name] for
|
| +/// missing [input].
|
| +Future expectMissingInput(AssetGraph graph, String name, String input) {
|
| + var missing = AssetId.parse(input);
|
| +
|
| + // Make sure the future gets the error.
|
| + schedule(() {
|
| + return graph.getAssetById(AssetId.parse(name)).then((asset) {
|
| + fail("Should have thrown error but got $asset.");
|
| + }).catchError((error) {
|
| + expect(error is MissingInputException, isTrue);
|
| + expect(error.id, equals(missing));
|
| + });
|
| + }, "get missing input on $name");
|
| +
|
| + // And we get it from the build results too.
|
| + return schedule(() {
|
| + return graph.results.first.then((result) {
|
| + expect(result.error is MissingInputException, isTrue);
|
| + expect(result.error.id, equals(missing));
|
| + });
|
| + }, "get missing input on $name");
|
| +}
|
| +
|
| +/// An [AssetProvider] that provides the given set of assets.
|
| +class MockProvider implements AssetProvider {
|
| + Iterable<String> get packages => _packages.keys;
|
| +
|
| + final _packages = new Map<String, List<MockAsset>>();
|
| +
|
| + MockProvider(assets) {
|
| + if (assets is Map) {
|
| + assets.forEach((asset, contents) {
|
| + var id = AssetId.parse(asset);
|
| + var package = _packages.putIfAbsent(id.package, () => []);
|
| + package.add(new MockAsset(id, contents));
|
| + });
|
| + } else if (assets is Iterable) {
|
| + for (var asset in assets) {
|
| + var id = AssetId.parse(asset);
|
| + var package = _packages.putIfAbsent(id.package, () => []);
|
| + package.add(new MockAsset(id, ""));
|
| + }
|
| + }
|
| + }
|
| +
|
| + void modifyAsset(String name, String contents) {
|
| + var id = AssetId.parse(name);
|
| + var asset = _packages[id.package].firstWhere((a) => a._id == id);
|
| + asset._contents = contents;
|
| + }
|
| +
|
| + List<String> listFiles(String package, {String within}) {
|
| + if (within != null) {
|
| + throw new UnimplementedError("Doesn't handle 'within' yet.");
|
| + }
|
| +
|
| + return _packages[package].map((asset) => asset.path);
|
| + }
|
| +
|
| + Future<Asset> loadAsset(AssetId id) {
|
| + return new Future(() {
|
| + var package = _packages[id.package];
|
| + if (package == null) throw new AssetNotFoundException(id);
|
| +
|
| + return package.firstWhere((asset) => asset._id == id,
|
| + orElse: () => throw new AssetNotFoundException(id));
|
| + });
|
| + }
|
| +}
|
| +
|
| +/// A [Transformer] that takes assets ending with one extension and generates
|
| +/// assets with a given extension. Appends the output extension to the contents
|
| +/// of the input file.
|
| +class RewriteTransformer extends Transformer {
|
| + final String from;
|
| + final String to;
|
| +
|
| + /// The number of times the transformer has been applied.
|
| + int numRuns = 0;
|
| +
|
| + /// Creates a transformer that rewrites assets whose extension is [from] to
|
| + /// one whose extension is [to].
|
| + ///
|
| + /// [to] may be a space-separated list in which case multiple outputs will be
|
| + /// created for each input.
|
| + RewriteTransformer(this.from, this.to);
|
| +
|
| + Future<bool> isPrimary(AssetId asset) {
|
| + return new Future.value(asset.extension == ".$from");
|
| + }
|
| +
|
| + Future apply(Transform transform) {
|
| + numRuns++;
|
| + return transform.primaryInput.then((input) {
|
| + for (var extension in to.split(" ")) {
|
| + var id = transform.primaryId.changeExtension(".$extension");
|
| + var content = input.readAsString() + ".$extension";
|
| + transform.addOutput(id, new MockAsset(id, content));
|
| + }
|
| + });
|
| + }
|
| +
|
| + String toString() => "$from->$to";
|
| +}
|
| +
|
| +/// A [Transformer] that takes an input asset that contains a comma-separated
|
| +/// list of paths and outputs a file for each path.
|
| +class OneToManyTransformer extends Transformer {
|
| + final String extension;
|
| +
|
| + /// The number of times the transformer has been applied.
|
| + int numRuns = 0;
|
| +
|
| + /// Creates a transformer that consumes assets with [extension]. That file
|
| + /// contains a comma-separated list of paths and it will output files at
|
| + /// each of those paths.
|
| + OneToManyTransformer(this.extension);
|
| +
|
| + Future<bool> isPrimary(AssetId asset) {
|
| + return new Future.value(asset.extension == ".$extension");
|
| + }
|
| +
|
| + Future apply(Transform transform) {
|
| + numRuns++;
|
| + return transform.primaryInput.then((input) {
|
| + for (var line in input.readAsString().split(",")) {
|
| + var id = new AssetId(transform.primaryId.package, line);
|
| + transform.addOutput(id, new MockAsset(id, "spread $extension"));
|
| + }
|
| + });
|
| + }
|
| +
|
| + String toString() => "1->many $extension";
|
| +}
|
| +
|
| +/// A transformer that uses the contents of a file to define the other inputs.
|
| +/// Outputs a file with the same name as the primary but with an "out"
|
| +/// extension containing the concatenated contents of all non-primary inputs.
|
| +class ManyToOneTransformer extends Transformer {
|
| + final String extension;
|
| +
|
| + /// Creates a transformer that consumes assets with [extension]. That file
|
| + /// contains a comma-separated list of paths and it will input files at
|
| + /// each of those paths.
|
| + ManyToOneTransformer(this.extension);
|
| +
|
| + Future<bool> isPrimary(AssetId asset) {
|
| + return new Future.value(asset.extension == ".$extension");
|
| + }
|
| +
|
| + Future apply(Transform transform) {
|
| + return transform.primaryInput.then((primary) {
|
| + // Get all of the included inputs.
|
| + var inputs = primary.readAsString().split(",").map((path) {
|
| + var id = new AssetId(transform.primaryId.package, path);
|
| + return transform.getInput(id);
|
| + });
|
| +
|
| + // Concatenate them to one output.
|
| + return Future.wait(inputs).then((inputs) {
|
| + var id = transform.primaryId.changeExtension(".out");
|
| + var contents = inputs.map((input) => input.readAsString()).join();
|
| + transform.addOutput(id, new MockAsset(id, contents));
|
| + });
|
| + });
|
| + }
|
| +
|
| + String toString() => "many->1 $extension";
|
| +}
|
| +
|
| +/// An implementation of [Asset] that never hits the file system.
|
| +class MockAsset implements Asset {
|
| + final AssetId _id;
|
| + String _contents;
|
| +
|
| + MockAsset(this._id, this._contents);
|
| +
|
| + String readAsString() => _contents;
|
| + Stream<List<int>> read() => throw new UnimplementedError();
|
| +
|
| + serialize() => throw new UnimplementedError();
|
| +
|
| + String toString() => "MockAsset $_id $_contents";
|
| +}
|
|
|