Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(775)

Unified Diff: pkg/barback/test/utils.dart

Issue 17507003: Clean up barback tests. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Revise. Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « pkg/barback/test/asset_graph/transform_test.dart ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/barback/test/utils.dart
diff --git a/pkg/barback/test/utils.dart b/pkg/barback/test/utils.dart
index 23f8e2a1267320b4297299264186dd5f615bde8f..d49adeaaea1813b582119c6d48bb703bd1e31205 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,157 @@ import '../../../sdk/lib/_internal/pub/test/command_line_config.dart';
var _configured = false;
+MockProvider _provider;
+AssetGraph _graph;
+
+/// [BuildResult]s that have been output by the graph before an expectation has
+/// consumed them.
+///
+/// Since [AssetGraph] starts building immediately in the background, results
+/// may start streaming before we've set an explicit expectation. When that
+/// occurs, we just queue them up here.
+final _buildResults = new Queue<BuildResult>();
+
+/// The expectations we have on upcoming [BuildResult]s.
+final _buildExpectations = new Queue<Completer<BuildResult>>();
+
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. These other functions are automatically scheduled, with the
nweiz 2013/06/27 00:19:25 "These other functions" is unclear, especially sin
Bob Nystrom 2013/06/27 17:55:14 Done.
+/// exception of [updateSources] and [removeSources].
+///
+/// [assets] may either be an [Iterable] or a [Map]. If an [Iterable], each
nweiz 2013/06/27 00:19:25 "If an" -> "If it's an"
Bob Nystrom 2013/06/27 17:55:14 Done.
+/// 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 is a string defining the contents of that asset.
nweiz 2013/06/27 00:19:25 "value is" -> "value should be"
Bob Nystrom 2013/06/27 17:55:14 Done.
+void initGraph([assets, Iterable<Iterable<Transformer>> transformers]) {
+ if (assets == null) assets = [];
+ if (transformers == null) transformers = [];
+
+ _provider = new MockProvider(assets);
+ _graph = new AssetGraph(_provider, transformers);
+
+ _graph.results.listen(wrapAsync((result) {
+ if (_buildExpectations.isEmpty) {
+ // We aren't waiting for a result yet, so just queue it up for later.
+ _buildResults.add(result);
+ } else {
+ // See if it meets the expectation.
+ _buildExpectations.removeFirst().complete(result);
+ }
+ }));
+
+ currentSchedule.onComplete.schedule(() {
+ // Discard any unused results. It's OK for a test to not care about some
+ // build results.
+ _buildResults.clear();
+ }, "clear unused build results");
+
+ // This library should ensure that you can't move to the next test until all
+ // build expectations are processed.
+ assert(_buildExpectations.isEmpty);
+}
+
+/// 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, so you
+/// will typically wrap it in a call to [schedule] yourself.
nweiz 2013/06/27 00:19:25 "you will typically wrap it" is confusing. Most of
Bob Nystrom 2013/06/27 17:55:14 Done.
+///
+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, so you
+/// will typically wrap it in a call to [schedule] yourself.
+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);
+}
+
+/// Changes 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");
+}
+
+/// Pauses the internally created [AssetProvider]. All asset requests that the
nweiz 2013/06/27 00:19:25 Paragraph break
Bob Nystrom 2013/06/27 17:55:14 Done.
+/// [AssetGraph] makes to the provider after this will not complete until
+/// [resumeProvider] is called.
+void pauseProvider() {
+ schedule(() =>_provider._pause(), "resume provider");
nweiz 2013/06/27 00:19:25 "resume" -> "pause"
Bob Nystrom 2013/06/27 17:55:14 Done.
+}
+
+/// Unpauses the provider after a call to [pauseProvider] and allows all
+/// pending asset loads to finish.
+void resumeProvider() {
+ schedule(() => _provider._resume(), "pause provider");
nweiz 2013/06/27 00:19:25 "pause" -> "resume"
Bob Nystrom 2013/06/27 17:55:14 Done.
+}
+
+/// Waits for the next [BuildResult] to be emitted and asserts that it is a
+/// build success.
+void buildShouldSucceed() {
+ schedule(() {
+ return _getNextBuildResult().then((result) {
+ expect(result.succeeded, isTrue);
+ });
+ }, "wait for build to succeed");
+}
+
+/// Waits for the next [BuildResult] to be emitted and asserts that it is a
+/// build failure. Invokes [callback] with the error (not the result) so that
+/// it can provide more precise expectations.
+void buildShouldFail(void callback(error)) {
+ schedule(() {
+ return _getNextBuildResult().then((result) {
+ expect(result.succeeded, isFalse);
+ callback(result.error);
+ });
+ }, "wait for build error");
+}
+
+Future<BuildResult> _getNextBuildResult() {
+ if (_buildResults.isNotEmpty) {
+ return new Future.value(_buildResults.removeFirst());
+ }
+
+ // We don't have any results yet, so enqueue the expectation.
+ var completer = new Completer<BuildResult>();
+ _buildExpectations.add(completer);
+ return completer.future;
+}
+
+/// Expects 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 +175,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 +185,13 @@ 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) {
+/// Expects 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,12 +200,12 @@ void expectNoAsset(AssetGraph graph, String name) {
}, "get asset $name");
}
-/// Expects that [graph] will have an output file collision error on an asset
+/// Expects that the graph will have an output file collision error on an asset
/// matching [name].
-Future expectCollision(AssetGraph graph, String name) {
+Future expectCollision(String name) {
var id = new AssetId.parse(name);
return schedule(() {
- return graph.results.first.then((result) {
+ return _graph.results.first.then((result) {
expect(result.error, new isInstanceOf<AssetCollisionException>());
expect(result.error.id, equals(id));
});
@@ -90,22 +234,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 +269,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 +285,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();
}
« no previous file with comments | « pkg/barback/test/asset_graph/transform_test.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698