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

Side by Side 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, 5 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « pkg/barback/test/asset_graph/transform_test.dart ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 library barback.test.utils; 5 library barback.test.utils;
6 6
7 import 'dart:async'; 7 import 'dart:async';
8 import 'dart:collection';
8 9
9 import 'package:barback/barback.dart'; 10 import 'package:barback/barback.dart';
10 import 'package:barback/src/asset_graph.dart'; 11 import 'package:barback/src/asset_graph.dart';
11 import 'package:pathos/path.dart' as pathos; 12 import 'package:pathos/path.dart' as pathos;
12 import 'package:scheduled_test/scheduled_test.dart'; 13 import 'package:scheduled_test/scheduled_test.dart';
13 14
14 // TODO(rnystrom): Get rid of this or find a better path for it. 15 // TODO(rnystrom): Get rid of this or find a better path for it.
15 import '../../../sdk/lib/_internal/pub/test/command_line_config.dart'; 16 import '../../../sdk/lib/_internal/pub/test/command_line_config.dart';
16 17
17 var _configured = false; 18 var _configured = false;
18 19
20 MockProvider _provider;
21 AssetGraph _graph;
22
23 /// Calls to [buildShouldSucceed] and [buildShouldFail] set expectations on
24 /// successive [BuildResult]s from [_graph]. This keeps track of how many calls
25 /// have already been made so later calls know which result to look for.
26 int _nextBuildResult;
27
19 void initConfig() { 28 void initConfig() {
20 if (_configured) return; 29 if (_configured) return;
21 _configured = true; 30 _configured = true;
22 unittestConfiguration = new CommandLineConfiguration(); 31 unittestConfiguration = new CommandLineConfiguration();
23 } 32 }
24 33
25 /// Expects that [graph] will return an asset matching [name] and [contents]. 34 /// Creates a new [AssetProvider] and [AssetGraph] with the given [assets] and
26 void expectAsset(AssetGraph graph, String name, [String contents]) { 35 /// [transformers].
36 ///
37 /// This graph is used internally by most of the other functions in this
38 /// library so you must call it in the test before calling any of the other
39 /// functions.
40 ///
41 /// [assets] may either be an [Iterable] or a [Map]. If it's an [Iterable],
42 /// each element may either be an [AssetId] or a string that can be parsed to
43 /// one. If it's a [Map], each key should be a string that can be parsed to an
44 /// [AssetId] and the value should be a string defining the contents of that
45 /// asset.
46 void initGraph([assets, Iterable<Iterable<Transformer>> transformers]) {
47 if (assets == null) assets = [];
48 if (transformers == null) transformers = [];
49
50 _provider = new MockProvider(assets);
51 _graph = new AssetGraph(_provider, transformers);
52 _nextBuildResult = 0;
53 }
54
55 /// Updates [assets] in the current [AssetProvider].
56 ///
57 /// Each item in the list may either be an [AssetId] or a string that can be
58 /// parsed as one. Note that this method is not automatically scheduled.
59 void updateSources(Iterable assets) {
60 // Allow strings as asset IDs.
61 assets = assets.map((asset) {
62 if (asset is String) return new AssetId.parse(asset);
63 return asset;
64 });
65
66 _graph.updateSources(assets);
67 }
68
69 /// Removes [assets] from the current [AssetProvider].
70 ///
71 /// Each item in the list may either be an [AssetId] or a string that can be
72 /// parsed as one. Note that this method is not automatically scheduled.
73 void removeSources(Iterable assets) {
74 // Allow strings as asset IDs.
75 assets = assets.map((asset) {
76 if (asset is String) return new AssetId.parse(asset);
77 return asset;
78 });
79
80 _graph.removeSources(assets);
81 }
82
83 /// Schedules a change to the contents of an asset identified by [name] to
84 /// [contents].
85 ///
86 /// Does not update it in the graph.
87 void modifyAsset(String name, String contents) {
88 schedule(() {
89 _provider._modifyAsset(name, contents);
90 }, "modify asset $name");
91 }
92
93 /// Schedules a pause of the internally created [AssetProvider].
94 ///
95 /// All asset requests that the [AssetGraph] makes to the provider after this
96 /// will not complete until [resumeProvider] is called.
97 void pauseProvider() {
98 schedule(() =>_provider._pause(), "pause provider");
99 }
100
101 /// Schedules an unpause of the provider after a call to [pauseProvider] and
102 /// allows all pending asset loads to finish.
103 void resumeProvider() {
104 schedule(() => _provider._resume(), "resume provider");
105 }
106
107 /// Expects that the next [BuildResult] is a build success.
108 void buildShouldSucceed([void callback()]) {
109 expect(_graph.results.elementAt(_nextBuildResult++).then((result) {
110 expect(result.succeeded, isTrue);
111 if (callback != null) callback();
112 }), completes);
113 }
114
115 /// Expects that the next [BuildResult] emitted is a failure.
116 ///
117 /// Invokes [callback] with the error (not the result) so that it can provide
118 /// more precise expectations.
119 void buildShouldFail(void callback(error)) {
120 expect(_graph.results.elementAt(_nextBuildResult++).then((result) {
121 expect(result.succeeded, isFalse);
122 callback(result.error);
123 }), completes);
124 }
125
126 /// Pauses the schedule until the currently running build completes.
127 ///
128 /// Validates that the build completed successfully.
129 void waitForBuild() {
130 schedule(() {
131 return _graph.results.first.then((result) {
132 expect(result.succeeded, isTrue);
133 });
134 });
135 }
136
137 /// Schedules an expectation that the graph will deliver an asset matching
138 /// [name] and [contents].
139 ///
140 /// If [contents] is omitted, defaults to the asset's filename without an
141 /// extension (which is the same default that [initGraph] uses).
142 void expectAsset(String name, [String contents]) {
27 var id = new AssetId.parse(name); 143 var id = new AssetId.parse(name);
28 144
29 if (contents == null) { 145 if (contents == null) {
30 contents = pathos.basenameWithoutExtension(id.path); 146 contents = pathos.basenameWithoutExtension(id.path);
31 } 147 }
32 148
33 schedule(() { 149 schedule(() {
34 return graph.getAssetById(id).then((asset) { 150 return _graph.getAssetById(id).then((asset) {
35 // TODO(rnystrom): Make an actual Matcher class for this. 151 // TODO(rnystrom): Make an actual Matcher class for this.
36 expect(asset, new isInstanceOf<MockAsset>()); 152 expect(asset, new isInstanceOf<MockAsset>());
37 expect(asset._id.package, equals(id.package)); 153 expect(asset._id.package, equals(id.package));
38 expect(asset._id.path, equals(id.path)); 154 expect(asset._id.path, equals(id.path));
39 expect(asset._contents, equals(contents)); 155 expect(asset._contents, equals(contents));
40 }); 156 });
41 }, "get asset $name"); 157 }, "get asset $name");
42 } 158 }
43 159
44 /// Expects that [graph] will not find an asset matching [name]. 160 /// Schedules an expectation that the graph will not find an asset matching
45 void expectNoAsset(AssetGraph graph, String name) { 161 /// [name].
162 void expectNoAsset(String name) {
46 var id = new AssetId.parse(name); 163 var id = new AssetId.parse(name);
47 164
48 // Make sure the future gets the error. 165 // Make sure the future gets the error.
49 schedule(() { 166 schedule(() {
50 return graph.getAssetById(id).then((asset) { 167 return _graph.getAssetById(id).then((asset) {
51 fail("Should have thrown error but got $asset."); 168 fail("Should have thrown error but got $asset.");
52 }).catchError((error) { 169 }).catchError((error) {
53 expect(error, new isInstanceOf<AssetNotFoundException>()); 170 expect(error, new isInstanceOf<AssetNotFoundException>());
54 expect(error.id, equals(id)); 171 expect(error.id, equals(id));
55 }); 172 });
56 }, "get asset $name"); 173 }, "get asset $name");
57 } 174 }
58 175
59 /// Expects that [graph] will have an output file collision error on an asset 176 /// Expects that the next [BuildResult] is an output file collision error on an
60 /// matching [name]. 177 /// asset matching [name].
61 Future expectCollision(AssetGraph graph, String name) { 178 Future expectCollision(String name) {
62 var id = new AssetId.parse(name); 179 var id = new AssetId.parse(name);
63 return schedule(() { 180 _graph.results.first.then(wrapAsync((result) {
64 return graph.results.first.then((result) { 181 expect(result.error, new isInstanceOf<AssetCollisionException>());
65 expect(result.error, new isInstanceOf<AssetCollisionException>()); 182 expect(result.error.id, equals(id));
66 expect(result.error.id, equals(id)); 183 }));
67 });
68 }, "get collision on $name");
69 } 184 }
70 185
71 /// Expects that [graph] will have an error on an asset matching [name] for 186 /// Schedules an expectation that [graph] will have an error on an asset
72 /// missing [input]. 187 /// matching [name] for missing [input].
73 Future expectMissingInput(AssetGraph graph, String name, String input) { 188 Future expectMissingInput(AssetGraph graph, String name, String input) {
74 var missing = new AssetId.parse(input); 189 var missing = new AssetId.parse(input);
75 190
76 // Make sure the future gets the error. 191 // Make sure the future gets the error.
77 schedule(() { 192 schedule(() {
78 return graph.getAssetById(new AssetId.parse(name)).then((asset) { 193 return graph.getAssetById(new AssetId.parse(name)).then((asset) {
79 fail("Should have thrown error but got $asset."); 194 fail("Should have thrown error but got $asset.");
80 }).catchError((error) { 195 }).catchError((error) {
81 expect(error, new isInstanceOf<MissingInputException>()); 196 expect(error, new isInstanceOf<MissingInputException>());
82 expect(error.id, equals(missing)); 197 expect(error.id, equals(missing));
83 }); 198 });
84 }, "get missing input on $name"); 199 }, "get missing input on $name");
85 } 200 }
86 201
87 /// An [AssetProvider] that provides the given set of assets. 202 /// An [AssetProvider] that provides the given set of assets.
88 class MockProvider implements AssetProvider { 203 class MockProvider implements AssetProvider {
89 Iterable<String> get packages => _packages.keys; 204 Iterable<String> get packages => _packages.keys;
90 205
91 final _packages = new Map<String, List<MockAsset>>(); 206 final _packages = new Map<String, List<MockAsset>>();
92 207
93 /// The completer that [getAsset()] is waiting on to complete. 208 /// The completer that [getAsset()] is waiting on to complete when paused.
94 /// 209 ///
95 /// If `null` it will return the asset immediately. 210 /// If `null` it will return the asset immediately.
96 Completer _wait; 211 Completer _pauseCompleter;
97 212
98 /// Tells the provider to wait during [getAsset] until [complete()] 213 /// Tells the provider to wait during [getAsset] until [complete()]
99 /// is called. 214 /// is called.
100 /// 215 ///
101 /// Lets you test the asynchronous behavior of loading. 216 /// Lets you test the asynchronous behavior of loading.
102 void wait() { 217 void _pause() {
103 _wait = new Completer(); 218 _pauseCompleter = new Completer();
104 } 219 }
105 220
106 void complete() { 221 void _resume() {
107 _wait.complete(); 222 _pauseCompleter.complete();
108 _wait = null; 223 _pauseCompleter = null;
109 } 224 }
110 225
111 MockProvider(assets) { 226 MockProvider(assets) {
112 if (assets is Map) { 227 if (assets is Map) {
113 assets.forEach((asset, contents) { 228 assets.forEach((asset, contents) {
114 var id = new AssetId.parse(asset); 229 var id = new AssetId.parse(asset);
115 var package = _packages.putIfAbsent(id.package, () => []); 230 var package = _packages.putIfAbsent(id.package, () => []);
116 package.add(new MockAsset(id, contents)); 231 package.add(new MockAsset(id, contents));
117 }); 232 });
118 } else if (assets is Iterable) { 233 } else if (assets is Iterable) {
119 for (var asset in assets) { 234 for (var asset in assets) {
120 var id = new AssetId.parse(asset); 235 var id = new AssetId.parse(asset);
121 var package = _packages.putIfAbsent(id.package, () => []); 236 var package = _packages.putIfAbsent(id.package, () => []);
122 var contents = pathos.basenameWithoutExtension(id.path); 237 var contents = pathos.basenameWithoutExtension(id.path);
123 package.add(new MockAsset(id, contents)); 238 package.add(new MockAsset(id, contents));
124 } 239 }
125 } 240 }
126 } 241 }
127 242
128 void modifyAsset(String name, String contents) { 243 void _modifyAsset(String name, String contents) {
129 var id = new AssetId.parse(name); 244 var id = new AssetId.parse(name);
130 var asset = _packages[id.package].firstWhere((a) => a._id == id); 245 var asset = _packages[id.package].firstWhere((a) => a._id == id);
131 asset._contents = contents; 246 asset._contents = contents;
132 } 247 }
133 248
134 List<AssetId> listAssets(String package, {String within}) { 249 List<AssetId> listAssets(String package, {String within}) {
135 if (within != null) { 250 if (within != null) {
136 throw new UnimplementedError("Doesn't handle 'within' yet."); 251 throw new UnimplementedError("Doesn't handle 'within' yet.");
137 } 252 }
138 253
139 return _packages[package].map((asset) => asset.id); 254 return _packages[package].map((asset) => asset.id);
140 } 255 }
141 256
142 Future<Asset> getAsset(AssetId id) { 257 Future<Asset> getAsset(AssetId id) {
143 var future; 258 var future;
144 if (_wait != null) { 259 if (_pauseCompleter != null) {
145 future = _wait.future; 260 future = _pauseCompleter.future;
146 } else { 261 } else {
147 future = new Future.value(); 262 future = new Future.value();
148 } 263 }
149 264
150 return future.then((_) { 265 return future.then((_) {
151 var package = _packages[id.package]; 266 var package = _packages[id.package];
152 if (package == null) throw new AssetNotFoundException(id); 267 if (package == null) throw new AssetNotFoundException(id);
153 268
154 return package.firstWhere((asset) => asset._id == id, 269 return package.firstWhere((asset) => asset._id == id,
155 orElse: () => throw new AssetNotFoundException(id)); 270 orElse: () => throw new AssetNotFoundException(id));
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after
333 448
334 MockAsset(this._id, this._contents); 449 MockAsset(this._id, this._contents);
335 450
336 String readAsString() => _contents; 451 String readAsString() => _contents;
337 Stream<List<int>> read() => throw new UnimplementedError(); 452 Stream<List<int>> read() => throw new UnimplementedError();
338 453
339 serialize() => throw new UnimplementedError(); 454 serialize() => throw new UnimplementedError();
340 455
341 String toString() => "MockAsset $_id $_contents"; 456 String toString() => "MockAsset $_id $_contents";
342 } 457 }
OLDNEW
« 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