| Index: pkg/barback/test/utils.dart
|
| diff --git a/pkg/barback/test/utils.dart b/pkg/barback/test/utils.dart
|
| index 23f8e2a1267320b4297299264186dd5f615bde8f..6542eccfdd6f8c8de9c19ac6a5705f6bd174fe30 100644
|
| --- a/pkg/barback/test/utils.dart
|
| +++ b/pkg/barback/test/utils.dart
|
| @@ -5,6 +5,7 @@
|
| library barback.test.utils;
|
|
|
| import 'dart:async';
|
| +import 'dart:collection';
|
|
|
| import 'package:barback/barback.dart';
|
| import 'package:barback/src/asset_graph.dart';
|
| @@ -16,14 +17,129 @@ import '../../../sdk/lib/_internal/pub/test/command_line_config.dart';
|
|
|
| var _configured = false;
|
|
|
| +MockProvider _provider;
|
| +AssetGraph _graph;
|
| +
|
| +/// Calls to [buildShouldSucceed] and [buildShouldFail] set expectations on
|
| +/// successive [BuildResult]s from [_graph]. This keeps track of how many calls
|
| +/// have already been made so later calls know which result to look for.
|
| +int _nextBuildResult;
|
| +
|
| 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]) {
|
| +/// Creates a new [AssetProvider] and [AssetGraph] with the given [assets] and
|
| +/// [transformers].
|
| +///
|
| +/// This graph is used internally by most of the other functions in this
|
| +/// library so you must call it in the test before calling any of the other
|
| +/// functions.
|
| +///
|
| +/// [assets] may either be an [Iterable] or a [Map]. If it's an [Iterable],
|
| +/// each element may either be an [AssetId] or a string that can be parsed to
|
| +/// one. If it's a [Map], each key should be a string that can be parsed to an
|
| +/// [AssetId] and the value should be a string defining the contents of that
|
| +/// asset.
|
| +void initGraph([assets, Iterable<Iterable<Transformer>> transformers]) {
|
| + if (assets == null) assets = [];
|
| + if (transformers == null) transformers = [];
|
| +
|
| + _provider = new MockProvider(assets);
|
| + _graph = new AssetGraph(_provider, transformers);
|
| + _nextBuildResult = 0;
|
| +}
|
| +
|
| +/// Updates [assets] in the current [AssetProvider].
|
| +///
|
| +/// Each item in the list may either be an [AssetId] or a string that can be
|
| +/// parsed as one. Note that this method is not automatically scheduled.
|
| +void updateSources(Iterable assets) {
|
| + // Allow strings as asset IDs.
|
| + assets = assets.map((asset) {
|
| + if (asset is String) return new AssetId.parse(asset);
|
| + return asset;
|
| + });
|
| +
|
| + _graph.updateSources(assets);
|
| +}
|
| +
|
| +/// Removes [assets] from the current [AssetProvider].
|
| +///
|
| +/// Each item in the list may either be an [AssetId] or a string that can be
|
| +/// parsed as one. Note that this method is not automatically scheduled.
|
| +void removeSources(Iterable assets) {
|
| + // Allow strings as asset IDs.
|
| + assets = assets.map((asset) {
|
| + if (asset is String) return new AssetId.parse(asset);
|
| + return asset;
|
| + });
|
| +
|
| + _graph.removeSources(assets);
|
| +}
|
| +
|
| +/// Schedules a change to the contents of an asset identified by [name] to
|
| +/// [contents].
|
| +///
|
| +/// Does not update it in the graph.
|
| +void modifyAsset(String name, String contents) {
|
| + schedule(() {
|
| + _provider._modifyAsset(name, contents);
|
| + }, "modify asset $name");
|
| +}
|
| +
|
| +/// Schedules a pause of the internally created [AssetProvider].
|
| +///
|
| +/// All asset requests that the [AssetGraph] makes to the provider after this
|
| +/// will not complete until [resumeProvider] is called.
|
| +void pauseProvider() {
|
| + schedule(() =>_provider._pause(), "pause provider");
|
| +}
|
| +
|
| +/// Schedules an unpause of the provider after a call to [pauseProvider] and
|
| +/// allows all pending asset loads to finish.
|
| +void resumeProvider() {
|
| + schedule(() => _provider._resume(), "resume provider");
|
| +}
|
| +
|
| +/// Expects that the next [BuildResult] is a build success.
|
| +void buildShouldSucceed([void callback()]) {
|
| + expect(_graph.results.elementAt(_nextBuildResult++).then((result) {
|
| + expect(result.succeeded, isTrue);
|
| + if (callback != null) callback();
|
| + }), completes);
|
| +}
|
| +
|
| +/// Expects that the next [BuildResult] emitted is a failure.
|
| +///
|
| +/// Invokes [callback] with the error (not the result) so that it can provide
|
| +/// more precise expectations.
|
| +void buildShouldFail(void callback(error)) {
|
| + expect(_graph.results.elementAt(_nextBuildResult++).then((result) {
|
| + expect(result.succeeded, isFalse);
|
| + callback(result.error);
|
| + }), completes);
|
| +}
|
| +
|
| +/// Pauses the schedule until the currently running build completes.
|
| +///
|
| +/// Validates that the build completed successfully.
|
| +void waitForBuild() {
|
| + schedule(() {
|
| + return _graph.results.first.then((result) {
|
| + expect(result.succeeded, isTrue);
|
| + });
|
| + });
|
| +}
|
| +
|
| +/// Schedules an expectation that the graph will deliver an asset matching
|
| +/// [name] and [contents].
|
| +///
|
| +/// If [contents] is omitted, defaults to the asset's filename without an
|
| +/// extension (which is the same default that [initGraph] uses).
|
| +void expectAsset(String name, [String contents]) {
|
| var id = new AssetId.parse(name);
|
|
|
| if (contents == null) {
|
| @@ -31,7 +147,7 @@ void expectAsset(AssetGraph graph, String name, [String contents]) {
|
| }
|
|
|
| schedule(() {
|
| - return graph.getAssetById(id).then((asset) {
|
| + return _graph.getAssetById(id).then((asset) {
|
| // TODO(rnystrom): Make an actual Matcher class for this.
|
| expect(asset, new isInstanceOf<MockAsset>());
|
| expect(asset._id.package, equals(id.package));
|
| @@ -41,13 +157,14 @@ void expectAsset(AssetGraph graph, String name, [String contents]) {
|
| }, "get asset $name");
|
| }
|
|
|
| -/// Expects that [graph] will not find an asset matching [name].
|
| -void expectNoAsset(AssetGraph graph, String name) {
|
| +/// Schedules an expectation that the graph will not find an asset matching
|
| +/// [name].
|
| +void expectNoAsset(String name) {
|
| var id = new AssetId.parse(name);
|
|
|
| // Make sure the future gets the error.
|
| schedule(() {
|
| - return graph.getAssetById(id).then((asset) {
|
| + return _graph.getAssetById(id).then((asset) {
|
| fail("Should have thrown error but got $asset.");
|
| }).catchError((error) {
|
| expect(error, new isInstanceOf<AssetNotFoundException>());
|
| @@ -56,20 +173,18 @@ void expectNoAsset(AssetGraph graph, String name) {
|
| }, "get asset $name");
|
| }
|
|
|
| -/// Expects that [graph] will have an output file collision error on an asset
|
| -/// matching [name].
|
| -Future expectCollision(AssetGraph graph, String name) {
|
| +/// Expects that the next [BuildResult] is an output file collision error on an
|
| +/// asset matching [name].
|
| +Future expectCollision(String name) {
|
| var id = new AssetId.parse(name);
|
| - return schedule(() {
|
| - return graph.results.first.then((result) {
|
| - expect(result.error, new isInstanceOf<AssetCollisionException>());
|
| - expect(result.error.id, equals(id));
|
| - });
|
| - }, "get collision on $name");
|
| + _graph.results.first.then(wrapAsync((result) {
|
| + expect(result.error, new isInstanceOf<AssetCollisionException>());
|
| + expect(result.error.id, equals(id));
|
| + }));
|
| }
|
|
|
| -/// Expects that [graph] will have an error on an asset matching [name] for
|
| -/// missing [input].
|
| +/// Schedules an expectation that [graph] will have an error on an asset
|
| +/// matching [name] for missing [input].
|
| Future expectMissingInput(AssetGraph graph, String name, String input) {
|
| var missing = new AssetId.parse(input);
|
|
|
| @@ -90,22 +205,22 @@ class MockProvider implements AssetProvider {
|
|
|
| final _packages = new Map<String, List<MockAsset>>();
|
|
|
| - /// The completer that [getAsset()] is waiting on to complete.
|
| + /// The completer that [getAsset()] is waiting on to complete when paused.
|
| ///
|
| /// If `null` it will return the asset immediately.
|
| - Completer _wait;
|
| + Completer _pauseCompleter;
|
|
|
| /// Tells the provider to wait during [getAsset] until [complete()]
|
| /// is called.
|
| ///
|
| /// Lets you test the asynchronous behavior of loading.
|
| - void wait() {
|
| - _wait = new Completer();
|
| + void _pause() {
|
| + _pauseCompleter = new Completer();
|
| }
|
|
|
| - void complete() {
|
| - _wait.complete();
|
| - _wait = null;
|
| + void _resume() {
|
| + _pauseCompleter.complete();
|
| + _pauseCompleter = null;
|
| }
|
|
|
| MockProvider(assets) {
|
| @@ -125,7 +240,7 @@ class MockProvider implements AssetProvider {
|
| }
|
| }
|
|
|
| - void modifyAsset(String name, String contents) {
|
| + void _modifyAsset(String name, String contents) {
|
| var id = new AssetId.parse(name);
|
| var asset = _packages[id.package].firstWhere((a) => a._id == id);
|
| asset._contents = contents;
|
| @@ -141,8 +256,8 @@ class MockProvider implements AssetProvider {
|
|
|
| Future<Asset> getAsset(AssetId id) {
|
| var future;
|
| - if (_wait != null) {
|
| - future = _wait.future;
|
| + if (_pauseCompleter != null) {
|
| + future = _pauseCompleter.future;
|
| } else {
|
| future = new Future.value();
|
| }
|
|
|