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

Side by Side Diff: pkg/barback/test/utils.dart

Issue 5695057915019264: Make barback more package-aware. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Code review changes. 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 import 'dart:collection';
9 import 'dart:io'; 9 import 'dart:io';
10 10
11 import 'package:barback/barback.dart'; 11 import 'package:barback/barback.dart';
12 import 'package:barback/src/asset_graph.dart'; 12 import 'package:barback/src/asset_graph.dart';
13 import 'package:barback/src/asset_graph_manager.dart';
14 import 'package:barback/src/utils.dart';
13 import 'package:pathos/path.dart' as pathos; 15 import 'package:pathos/path.dart' as pathos;
14 import 'package:scheduled_test/scheduled_test.dart'; 16 import 'package:scheduled_test/scheduled_test.dart';
17 import 'package:stack_trace/stack_trace.dart';
15 18
16 // TODO(rnystrom): Get rid of this or find a better path for it. 19 // TODO(rnystrom): Get rid of this or find a better path for it.
17 import '../../../sdk/lib/_internal/pub/test/command_line_config.dart'; 20 import '../../../sdk/lib/_internal/pub/test/command_line_config.dart';
18 21
19 var _configured = false; 22 var _configured = false;
20 23
21 MockProvider _provider; 24 MockProvider _provider;
22 AssetGraph _graph; 25 AssetGraphManager _graphManager;
23 26
24 /// Calls to [buildShouldSucceed] and [buildShouldFail] set expectations on 27 /// Calls to [buildShouldSucceed] and [buildShouldFail] set expectations on
25 /// successive [BuildResult]s from [_graph]. This keeps track of how many calls 28 /// successive [BuildResult]s from [_graph]. This keeps track of how many calls
26 /// have already been made so later calls know which result to look for. 29 /// have already been made so later calls know which result to look for.
27 int _nextBuildResult; 30 int _nextBuildResult;
28 31
29 void initConfig() { 32 void initConfig() {
30 if (_configured) return; 33 if (_configured) return;
31 _configured = true; 34 _configured = true;
32 unittestConfiguration = new CommandLineConfiguration(); 35 unittestConfiguration = new CommandLineConfiguration();
33 } 36 }
34 37
35 /// Creates a new [AssetProvider] and [AssetGraph] with the given [assets] and 38 /// Creates a new [AssetProvider] and [AssetGraph] with the given [assets] and
36 /// [transformers]. 39 /// [transformers].
37 /// 40 ///
38 /// This graph is used internally by most of the other functions in this 41 /// This graph is used internally by most of the other functions in this
39 /// library so you must call it in the test before calling any of the other 42 /// library so you must call it in the test before calling any of the other
40 /// functions. 43 /// functions.
41 /// 44 ///
42 /// [assets] may either be an [Iterable] or a [Map]. If it's an [Iterable], 45 /// [assets] may either be an [Iterable] or a [Map]. If it's an [Iterable],
43 /// each element may either be an [AssetId] or a string that can be parsed to 46 /// each element may either be an [AssetId] or a string that can be parsed to
44 /// one. If it's a [Map], each key should be a string that can be parsed to an 47 /// one. If it's a [Map], each key should be a string that can be parsed to an
45 /// [AssetId] and the value should be a string defining the contents of that 48 /// [AssetId] and the value should be a string defining the contents of that
46 /// asset. 49 /// asset.
47 void initGraph([assets, Iterable<Iterable<Transformer>> transformers]) { 50 ///
51 /// [transformers] is a map from package names to the transformers for each
52 /// package.
53 void initGraph([assets,
54 Map<String, Iterable<Iterable<Transformer>>> transformers]) {
48 if (assets == null) assets = []; 55 if (assets == null) assets = [];
49 if (transformers == null) transformers = []; 56 if (transformers == null) transformers = {};
50 57
51 _provider = new MockProvider(assets); 58 _provider = new MockProvider(assets, transformers);
52 _graph = new AssetGraph(_provider, transformers); 59 _graphManager = new AssetGraphManager(_provider);
53 _nextBuildResult = 0; 60 _nextBuildResult = 0;
54 } 61 }
55 62
56 /// Updates [assets] in the current [AssetProvider]. 63 /// Updates [assets] in the current [AssetProvider].
57 /// 64 ///
58 /// Each item in the list may either be an [AssetId] or a string that can be 65 /// Each item in the list may either be an [AssetId] or a string that can be
59 /// parsed as one. Note that this method is not automatically scheduled. 66 /// parsed as one. Note that this method is not automatically scheduled.
60 void updateSources(Iterable assets) { 67 void updateSources(Iterable assets) {
61 // Allow strings as asset IDs. 68 // Allow strings as asset IDs.
62 assets = assets.map((asset) { 69 assets = assets.map((asset) {
63 if (asset is String) return new AssetId.parse(asset); 70 if (asset is String) return new AssetId.parse(asset);
64 return asset; 71 return asset;
65 }); 72 });
66 73
67 _graph.updateSources(assets); 74 _graphManager.updateSources(assets);
68 } 75 }
69 76
70 /// Removes [assets] from the current [AssetProvider]. 77 /// Removes [assets] from the current [AssetProvider].
71 /// 78 ///
72 /// Each item in the list may either be an [AssetId] or a string that can be 79 /// Each item in the list may either be an [AssetId] or a string that can be
73 /// parsed as one. Note that this method is not automatically scheduled. 80 /// parsed as one. Note that this method is not automatically scheduled.
74 void removeSources(Iterable assets) { 81 void removeSources(Iterable assets) {
75 // Allow strings as asset IDs. 82 // Allow strings as asset IDs.
76 assets = assets.map((asset) { 83 assets = assets.map((asset) {
77 if (asset is String) return new AssetId.parse(asset); 84 if (asset is String) return new AssetId.parse(asset);
78 return asset; 85 return asset;
79 }); 86 });
80 87
81 _graph.removeSources(assets); 88 _graphManager.removeSources(assets);
82 } 89 }
83 90
84 /// Schedules a change to the contents of an asset identified by [name] to 91 /// Schedules a change to the contents of an asset identified by [name] to
85 /// [contents]. 92 /// [contents].
86 /// 93 ///
87 /// Does not update it in the graph. 94 /// Does not update it in the graph.
88 void modifyAsset(String name, String contents) { 95 void modifyAsset(String name, String contents) {
89 schedule(() { 96 schedule(() {
90 _provider._modifyAsset(name, contents); 97 _provider._modifyAsset(name, contents);
91 }, "modify asset $name"); 98 }, "modify asset $name");
92 } 99 }
93 100
94 /// Schedules a pause of the internally created [AssetProvider]. 101 /// Schedules a pause of the internally created [AssetProvider].
95 /// 102 ///
96 /// All asset requests that the [AssetGraph] makes to the provider after this 103 /// All asset requests that the [AssetGraph] makes to the provider after this
97 /// will not complete until [resumeProvider] is called. 104 /// will not complete until [resumeProvider] is called.
98 void pauseProvider() { 105 void pauseProvider() {
99 schedule(() =>_provider._pause(), "pause provider"); 106 schedule(() => _provider._pause(), "pause provider");
100 } 107 }
101 108
102 /// Schedules an unpause of the provider after a call to [pauseProvider] and 109 /// Schedules an unpause of the provider after a call to [pauseProvider] and
103 /// allows all pending asset loads to finish. 110 /// allows all pending asset loads to finish.
104 void resumeProvider() { 111 void resumeProvider() {
105 schedule(() => _provider._resume(), "resume provider"); 112 schedule(() => _provider._resume(), "resume provider");
106 } 113 }
107 114
115 /// Asserts that the current build step shouldn't have finished by this point in
116 /// the schedule.
117 ///
118 /// This uses the same build counter as [buildShouldSucceed] and
119 /// [buildShouldFail], so those can be used to validate build results before and
120 /// after this.
121 void buildShouldNotBeDone() {
122 var resultAllowed = false;
123 var trace = new Trace.current();
124 _graphManager.results.elementAt(_nextBuildResult).then((result) {
125 if (resultAllowed) return;
126
127 currentSchedule.signalError(
128 new Exception("Expected build not to terminate "
129 "here, but it terminated with result: $result"), trace);
130 }).catchError((error) {
131 if (resultAllowed) return;
132 currentSchedule.signalError(error);
133 });
134
135 schedule(() {
136 // Pump the event queue in case the build completes out-of-band after we get
137 // here. If it does, we want to signal an error.
138 return pumpEventQueue().then((_) {
139 resultAllowed = true;
140 });
141 }, "ensuring build doesn't terminate");
142 }
143
108 /// Expects that the next [BuildResult] is a build success. 144 /// Expects that the next [BuildResult] is a build success.
109 void buildShouldSucceed() { 145 void buildShouldSucceed() {
110 expect(_graph.results.elementAt(_nextBuildResult++).then((result) { 146 expect(_getNextBuildResult().then((result) {
111 expect(result.succeeded, isTrue); 147 expect(result.succeeded, isTrue);
112 }), completes); 148 }), completes);
113 } 149 }
114 150
115 /// Expects that the next [BuildResult] emitted is a failure. 151 /// Expects that the next [BuildResult] emitted is a failure.
116 /// 152 ///
117 /// [matchers] is a list of matchers to match against the errors that caused the 153 /// [matchers] is a list of matchers to match against the errors that caused the
118 /// build to fail. Every matcher is expected to match an error, but the order of 154 /// build to fail. Every matcher is expected to match an error, but the order of
119 /// matchers is unimportant. 155 /// matchers is unimportant.
120 void buildShouldFail(List matchers) { 156 void buildShouldFail(List matchers) {
121 expect(_graph.results.elementAt(_nextBuildResult++).then((result) { 157 expect(_getNextBuildResult().then((result) {
122 expect(result.succeeded, isFalse); 158 expect(result.succeeded, isFalse);
123 expect(result.errors.length, equals(matchers.length)); 159 expect(result.errors.length, equals(matchers.length));
124 for (var matcher in matchers) { 160 for (var matcher in matchers) {
125 expect(result.errors, contains(matcher)); 161 expect(result.errors, contains(matcher));
126 } 162 }
127 }), completes); 163 }), completes);
128 } 164 }
129 165
166 Future<BuildResult> _getNextBuildResult() =>
167 _graphManager.results.elementAt(_nextBuildResult++);
168
130 /// Pauses the schedule until the currently running build completes. 169 /// Pauses the schedule until the currently running build completes.
131 /// 170 ///
132 /// Validates that the build completed successfully. 171 /// Validates that the build completed successfully.
133 void waitForBuild() { 172 void waitForBuild() {
134 schedule(() { 173 schedule(() {
135 return _graph.results.first.then((result) { 174 return _graphManager.results.first.then((result) {
136 expect(result.succeeded, isTrue); 175 expect(result.succeeded, isTrue);
137 }); 176 });
138 }, "wait for build"); 177 }, "wait for build");
139 } 178 }
140 179
141 /// Schedules an expectation that the graph will deliver an asset matching 180 /// Schedules an expectation that the graph will deliver an asset matching
142 /// [name] and [contents]. 181 /// [name] and [contents].
143 /// 182 ///
144 /// If [contents] is omitted, defaults to the asset's filename without an 183 /// If [contents] is omitted, defaults to the asset's filename without an
145 /// extension (which is the same default that [initGraph] uses). 184 /// extension (which is the same default that [initGraph] uses).
146 void expectAsset(String name, [String contents]) { 185 void expectAsset(String name, [String contents]) {
147 var id = new AssetId.parse(name); 186 var id = new AssetId.parse(name);
148 187
149 if (contents == null) { 188 if (contents == null) {
150 contents = pathos.basenameWithoutExtension(id.path); 189 contents = pathos.basenameWithoutExtension(id.path);
151 } 190 }
152 191
153 schedule(() { 192 schedule(() {
154 return _graph.getAssetById(id).then((asset) { 193 return _graphManager.getAssetById(id).then((asset) {
155 // TODO(rnystrom): Make an actual Matcher class for this. 194 // TODO(rnystrom): Make an actual Matcher class for this.
156 expect(asset, new isInstanceOf<MockAsset>()); 195 expect(asset, new isInstanceOf<MockAsset>());
157 expect(asset.id, equals(id)); 196 expect(asset.id, equals(id));
158 expect(asset.contents, equals(contents)); 197 expect(asset.contents, equals(contents));
159 }); 198 });
160 }, "get asset $name"); 199 }, "get asset $name");
161 } 200 }
162 201
163 /// Schedules an expectation that the graph will not find an asset matching 202 /// Schedules an expectation that the graph will not find an asset matching
164 /// [name]. 203 /// [name].
165 void expectNoAsset(String name) { 204 void expectNoAsset(String name) {
166 var id = new AssetId.parse(name); 205 var id = new AssetId.parse(name);
167 206
168 // Make sure the future gets the error. 207 // Make sure the future gets the error.
169 schedule(() { 208 schedule(() {
170 return _graph.getAssetById(id).then((asset) { 209 return _graphManager.getAssetById(id).then((asset) {
171 fail("Should have thrown error but got $asset."); 210 fail("Should have thrown error but got $asset.");
172 }).catchError((error) { 211 }).catchError((error) {
173 expect(error, new isInstanceOf<AssetNotFoundException>()); 212 expect(error, new isInstanceOf<AssetNotFoundException>());
174 expect(error.id, equals(id)); 213 expect(error.id, equals(id));
175 }); 214 });
176 }, "get asset $name"); 215 }, "get asset $name");
177 } 216 }
178 217
179 /// Schedules an expectation that [graph] will have an error on an asset
180 /// matching [name] for missing [input].
181 Future expectMissingInput(AssetGraph graph, String name, String input) {
182 var missing = new AssetId.parse(input);
183
184 // Make sure the future gets the error.
185 schedule(() {
186 return graph.getAssetById(new AssetId.parse(name)).then((asset) {
187 fail("Should have thrown error but got $asset.");
188 }).catchError((error) {
189 expect(error, new isInstanceOf<MissingInputException>());
190 expect(error.id, equals(missing));
191 });
192 }, "get missing input on $name");
193 }
194
195 /// Returns a matcher for an [AssetNotFoundException] with the given [id]. 218 /// Returns a matcher for an [AssetNotFoundException] with the given [id].
196 Matcher isAssetNotFoundException(String name) { 219 Matcher isAssetNotFoundException(String name) {
197 var id = new AssetId.parse(name); 220 var id = new AssetId.parse(name);
198 return allOf( 221 return allOf(
199 new isInstanceOf<AssetNotFoundException>(), 222 new isInstanceOf<AssetNotFoundException>(),
200 predicate((error) => error.id == id, 'id is $name')); 223 predicate((error) => error.id == id, 'id is $name'));
201 } 224 }
202 225
203 /// Returns a matcher for an [AssetCollisionException] with the given [id]. 226 /// Returns a matcher for an [AssetCollisionException] with the given [id].
204 Matcher isAssetCollisionException(String name) { 227 Matcher isAssetCollisionException(String name) {
205 var id = new AssetId.parse(name); 228 var id = new AssetId.parse(name);
206 return allOf( 229 return allOf(
207 new isInstanceOf<AssetCollisionException>(), 230 new isInstanceOf<AssetCollisionException>(),
208 predicate((error) => error.id == id, 'id is $name')); 231 predicate((error) => error.id == id, 'id is $name'));
209 } 232 }
210 233
211 /// Returns a matcher for a [MissingInputException] with the given [id]. 234 /// Returns a matcher for a [MissingInputException] with the given [id].
212 Matcher isMissingInputException(String name) { 235 Matcher isMissingInputException(String name) {
213 var id = new AssetId.parse(name); 236 var id = new AssetId.parse(name);
214 return allOf( 237 return allOf(
215 new isInstanceOf<MissingInputException>(), 238 new isInstanceOf<MissingInputException>(),
216 predicate((error) => error.id == id, 'id is $name')); 239 predicate((error) => error.id == id, 'id is $name'));
217 } 240 }
218 241
242 /// Returns a matcher for an [InvalidOutputException] with the given id and
243 /// package name.
244 Matcher isInvalidOutputException(String package, String name) {
245 var id = new AssetId.parse(name);
246 return allOf(
247 new isInstanceOf<InvalidOutputException>(),
248 predicate((error) => error.package == package, 'package is $package'),
249 predicate((error) => error.id == id, 'id is $name'));
250 }
251
219 /// An [AssetProvider] that provides the given set of assets. 252 /// An [AssetProvider] that provides the given set of assets.
220 class MockProvider implements AssetProvider { 253 class MockProvider implements AssetProvider {
221 Iterable<String> get packages => _packages.keys; 254 Iterable<String> get packages => _packages.keys;
222 255
223 final _packages = new Map<String, List<MockAsset>>(); 256 Map<String, _MockPackage> _packages;
224 257
225 /// The completer that [getAsset()] is waiting on to complete when paused. 258 /// The completer that [getAsset()] is waiting on to complete when paused.
226 /// 259 ///
227 /// If `null` it will return the asset immediately. 260 /// If `null` it will return the asset immediately.
228 Completer _pauseCompleter; 261 Completer _pauseCompleter;
229 262
230 /// Tells the provider to wait during [getAsset] until [complete()] 263 /// Tells the provider to wait during [getAsset] until [complete()]
231 /// is called. 264 /// is called.
232 /// 265 ///
233 /// Lets you test the asynchronous behavior of loading. 266 /// Lets you test the asynchronous behavior of loading.
234 void _pause() { 267 void _pause() {
235 _pauseCompleter = new Completer(); 268 _pauseCompleter = new Completer();
236 } 269 }
237 270
238 void _resume() { 271 void _resume() {
239 _pauseCompleter.complete(); 272 _pauseCompleter.complete();
240 _pauseCompleter = null; 273 _pauseCompleter = null;
241 } 274 }
242 275
243 MockProvider(assets) { 276 MockProvider(assets,
277 Map<String, Iterable<Iterable<Transformer>>> transformers) {
278 var assetList;
244 if (assets is Map) { 279 if (assets is Map) {
245 assets.forEach((asset, contents) { 280 assetList = assets.keys.map((asset) {
246 var id = new AssetId.parse(asset); 281 var id = new AssetId.parse(asset);
247 var package = _packages.putIfAbsent(id.package, () => []); 282 return new MockAsset(id, assets[asset]);
248 package.add(new MockAsset(id, contents));
249 }); 283 });
250 } else if (assets is Iterable) { 284 } else if (assets is Iterable) {
251 for (var asset in assets) { 285 assetList = assets.map((asset) {
252 var id = new AssetId.parse(asset); 286 var id = new AssetId.parse(asset);
253 var package = _packages.putIfAbsent(id.package, () => []);
254 var contents = pathos.basenameWithoutExtension(id.path); 287 var contents = pathos.basenameWithoutExtension(id.path);
255 package.add(new MockAsset(id, contents)); 288 return new MockAsset(id, contents);
256 } 289 });
257 } 290 }
291
292 _packages = mapMapValues(groupBy(assetList, (asset) => asset.id.package),
293 (package, assets) {
294 var packageTransformers = transformers[package];
295 if (packageTransformers == null) packageTransformers = [];
296 return new _MockPackage(assets, packageTransformers.toList());
297 });
298
299 // If there are no assets or transformers, add a dummy package. This better
300 // simulates the real world, where there'll always be at least the
301 // entrypoint package.
302 if (_packages.isEmpty) _packages = {"app": new _MockPackage([], [])};
258 } 303 }
259 304
260 void _modifyAsset(String name, String contents) { 305 void _modifyAsset(String name, String contents) {
261 var id = new AssetId.parse(name); 306 var id = new AssetId.parse(name);
262 var asset = _packages[id.package].firstWhere((a) => a.id == id); 307 var asset = _packages[id.package].assets.firstWhere((a) => a.id == id);
263 asset.contents = contents; 308 asset.contents = contents;
264 } 309 }
265 310
266 List<AssetId> listAssets(String package, {String within}) { 311 List<AssetId> listAssets(String package, {String within}) {
267 if (within != null) { 312 if (within != null) {
268 throw new UnimplementedError("Doesn't handle 'within' yet."); 313 throw new UnimplementedError("Doesn't handle 'within' yet.");
269 } 314 }
270 315
271 return _packages[package].map((asset) => asset.id); 316 return _packages[package].assets.map((asset) => asset.id);
317 }
318
319 Iterable<Iterable<Transformer>> getTransformers(String package) {
320 var mockPackage = _packages[package];
321 if (mockPackage == null) {
322 throw new ArgumentError("No package named $package.");
323 }
324 return mockPackage.transformers;
272 } 325 }
273 326
274 Future<Asset> getAsset(AssetId id) { 327 Future<Asset> getAsset(AssetId id) {
275 var future; 328 var future;
276 if (_pauseCompleter != null) { 329 if (_pauseCompleter != null) {
277 future = _pauseCompleter.future; 330 future = _pauseCompleter.future;
278 } else { 331 } else {
279 future = new Future.value(); 332 future = new Future.value();
280 } 333 }
281 334
282 return future.then((_) { 335 return future.then((_) {
283 var package = _packages[id.package]; 336 var package = _packages[id.package];
284 if (package == null) throw new AssetNotFoundException(id); 337 if (package == null) throw new AssetNotFoundException(id);
285 338
286 return package.firstWhere((asset) => asset.id == id, 339 return package.assets.firstWhere((asset) => asset.id == id,
287 orElse: () => throw new AssetNotFoundException(id)); 340 orElse: () => throw new AssetNotFoundException(id));
288 }); 341 });
289 } 342 }
290 } 343 }
291 344
345 /// Used by [MockProvider] to keep track of which assets and transformers exist
346 /// for each package.
347 class _MockPackage {
348 final List<MockAsset> assets;
349 final List<List<Transformer>> transformers;
350
351 _MockPackage(this.assets, Iterable<Iterable<Transformer>> transformers)
352 : transformers = transformers.map((phase) => phase.toList()).toList();
353 }
354
292 /// A [Transformer] that takes assets ending with one extension and generates 355 /// A [Transformer] that takes assets ending with one extension and generates
293 /// assets with a given extension. 356 /// assets with a given extension.
294 /// 357 ///
295 /// Appends the output extension to the contents of the input file. 358 /// Appends the output extension to the contents of the input file.
296 class RewriteTransformer extends Transformer { 359 class RewriteTransformer extends Transformer {
297 final String from; 360 final String from;
298 final String to; 361 final String to;
299 362
300 /// The number of times the transformer has been applied. 363 /// The number of times the transformer has been applied.
301 int numRuns = 0; 364 int numRuns = 0;
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
461 var id = new AssetId.parse(output); 524 var id = new AssetId.parse(output);
462 transform.addOutput(new MockAsset(id, output)); 525 transform.addOutput(new MockAsset(id, output));
463 } 526 }
464 527
465 // Then fail. 528 // Then fail.
466 throw ERROR; 529 throw ERROR;
467 }); 530 });
468 } 531 }
469 } 532 }
470 533
534 /// A transformer that outputs an asset with the given id.
535 class CreateAssetTransformer extends Transformer {
536 final String output;
537
538 CreateAssetTransformer(this.output);
539
540 Future<bool> isPrimary(Asset asset) => new Future.value(true);
541
542 Future apply(Transform transform) {
543 return new Future(() {
544 transform.addOutput(new MockAsset(new AssetId.parse(output), output));
545 });
546 }
547 }
548
471 /// An implementation of [Asset] that never hits the file system. 549 /// An implementation of [Asset] that never hits the file system.
472 class MockAsset implements Asset { 550 class MockAsset implements Asset {
473 final AssetId id; 551 final AssetId id;
474 String contents; 552 String contents;
475 553
476 MockAsset(this.id, this.contents); 554 MockAsset(this.id, this.contents);
477 555
478 Future<String> readAsString({Encoding encoding}) => 556 Future<String> readAsString({Encoding encoding}) =>
479 new Future.value(contents); 557 new Future.value(contents);
480 558
481 Stream<List<int>> read() => throw new UnimplementedError(); 559 Stream<List<int>> read() => throw new UnimplementedError();
482 560
483 String toString() => "MockAsset $id $contents"; 561 String toString() => "MockAsset $id $contents";
484 } 562 }
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