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

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

Issue 23311006: Add the ability to dynamically modify transforms to barback. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Code review changes. Created 7 years, 4 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
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
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
54 /// [AssetId] and the value should be a string defining the contents of that 54 /// [AssetId] and the value should be a string defining the contents of that
55 /// asset. 55 /// asset.
56 /// 56 ///
57 /// [transformers] is a map from package names to the transformers for each 57 /// [transformers] is a map from package names to the transformers for each
58 /// package. 58 /// package.
59 void initGraph([assets, 59 void initGraph([assets,
60 Map<String, Iterable<Iterable<Transformer>>> transformers]) { 60 Map<String, Iterable<Iterable<Transformer>>> transformers]) {
61 if (assets == null) assets = []; 61 if (assets == null) assets = [];
62 if (transformers == null) transformers = {}; 62 if (transformers == null) transformers = {};
63 63
64 _provider = new MockProvider(assets, transformers); 64 var assetList;
65 if (assets is Map) {
66 assetList = assets.keys.map((asset) {
67 var id = new AssetId.parse(asset);
68 return new _MockAsset(id, assets[asset]);
69 });
70 } else if (assets is Iterable) {
71 assetList = assets.map((asset) {
72 var id = new AssetId.parse(asset);
73 var contents = pathos.basenameWithoutExtension(id.path);
74 return new _MockAsset(id, contents);
75 });
76 }
77
78 var assetMap = mapMapValues(groupBy(assetList, (asset) => asset.id.package),
79 (package, assets) => new AssetSet.from(assets));
80
81 // Make sure that packages that have transformers but no assets are considered
82 // by MockProvider to exist.
83 for (var package in transformers.keys) {
84 assetMap.putIfAbsent(package, () => new AssetSet());
85 }
86
87 _provider = new MockProvider(assetMap);
65 _barback = new Barback(_provider); 88 _barback = new Barback(_provider);
66 _nextBuildResult = 0; 89 _nextBuildResult = 0;
90
91 transformers.forEach(_barback.updateTransformers);
92
93 // There should be one successful build after adding all the transformers but
94 // before adding any sources.
95 if (!transformers.isEmpty) buildShouldSucceed();
67 } 96 }
68 97
69 /// Updates [assets] in the current [PackageProvider]. 98 /// Updates [assets] in the current [PackageProvider].
70 /// 99 ///
71 /// Each item in the list may either be an [AssetId] or a string that can be 100 /// Each item in the list may either be an [AssetId] or a string that can be
72 /// parsed as one. 101 /// parsed as one.
73 void updateSources(Iterable assets) { 102 void updateSources(Iterable assets) {
74 assets = _parseAssets(assets); 103 assets = _parseAssets(assets);
75 schedule(() => _barback.updateSources(assets), 104 schedule(() => _barback.updateSources(assets),
76 "updating ${assets.join(', ')}"); 105 "updating ${assets.join(', ')}");
(...skipping 18 matching lines...) Expand all
95 } 124 }
96 125
97 /// Removes [assets] from the current [PackageProvider]. 126 /// Removes [assets] from the current [PackageProvider].
98 /// 127 ///
99 /// Each item in the list may either be an [AssetId] or a string that can be 128 /// Each item in the list may either be an [AssetId] or a string that can be
100 /// parsed as one. Unlike [removeSources], this is not automatically scheduled 129 /// parsed as one. Unlike [removeSources], this is not automatically scheduled
101 /// and will be run synchronously when called. 130 /// and will be run synchronously when called.
102 void removeSourcesSync(Iterable assets) => 131 void removeSourcesSync(Iterable assets) =>
103 _barback.removeSources(_parseAssets(assets)); 132 _barback.removeSources(_parseAssets(assets));
104 133
134 /// Sets the transformers for [package] to [transformers].
135 void updateTransformers(String package,
136 Iterable<Iterable<Transformers>> transformers) {
137 schedule(() => _barback.updateTransformers(package, transformers),
138 "updating transformers for $package");
139 }
140
105 /// Parse a list of strings or [AssetId]s into a list of [AssetId]s. 141 /// Parse a list of strings or [AssetId]s into a list of [AssetId]s.
106 List<AssetId> _parseAssets(Iterable assets) { 142 List<AssetId> _parseAssets(Iterable assets) {
107 return assets.map((asset) { 143 return assets.map((asset) {
108 if (asset is String) return new AssetId.parse(asset); 144 if (asset is String) return new AssetId.parse(asset);
109 return asset; 145 return asset;
110 }).toList(); 146 }).toList();
111 } 147 }
112 148
113 /// Schedules a change to the contents of an asset identified by [name] to 149 /// Schedules a change to the contents of an asset identified by [name] to
114 /// [contents]. 150 /// [contents].
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after
333 trace); 369 trace);
334 }).catchError((error) { 370 }).catchError((error) {
335 currentSchedule.signalError(error); 371 currentSchedule.signalError(error);
336 }); 372 });
337 373
338 return delay.then((_) => cancelable.cancel()); 374 return delay.then((_) => cancelable.cancel());
339 } 375 }
340 376
341 /// An [AssetProvider] that provides the given set of assets. 377 /// An [AssetProvider] that provides the given set of assets.
342 class MockProvider implements PackageProvider { 378 class MockProvider implements PackageProvider {
343 Iterable<String> get packages => _packages.keys; 379 Iterable<String> get packages => _assets.keys;
344 380
345 Map<String, _MockPackage> _packages; 381 Map<String, AssetSet> _assets;
346 382
347 /// The set of assets for which [MockLoadException]s should be emitted if 383 /// The set of assets for which [MockLoadException]s should be emitted if
348 /// they're loaded. 384 /// they're loaded.
349 final _errors = new Set<AssetId>(); 385 final _errors = new Set<AssetId>();
350 386
351 /// The completer that [getAsset()] is waiting on to complete when paused. 387 /// The completer that [getAsset()] is waiting on to complete when paused.
352 /// 388 ///
353 /// If `null` it will return the asset immediately. 389 /// If `null` it will return the asset immediately.
354 Completer _pauseCompleter; 390 Completer _pauseCompleter;
355 391
356 /// Tells the provider to wait during [getAsset] until [complete()] 392 /// Tells the provider to wait during [getAsset] until [complete()]
357 /// is called. 393 /// is called.
358 /// 394 ///
359 /// Lets you test the asynchronous behavior of loading. 395 /// Lets you test the asynchronous behavior of loading.
360 void _pause() { 396 void _pause() {
361 _pauseCompleter = new Completer(); 397 _pauseCompleter = new Completer();
362 } 398 }
363 399
364 void _resume() { 400 void _resume() {
365 _pauseCompleter.complete(); 401 _pauseCompleter.complete();
366 _pauseCompleter = null; 402 _pauseCompleter = null;
367 } 403 }
368 404
369 MockProvider(assets, 405 MockProvider(this._assets) {
370 Map<String, Iterable<Iterable<Transformer>>> transformers) {
371 var assetList;
372 if (assets is Map) {
373 assetList = assets.keys.map((asset) {
374 var id = new AssetId.parse(asset);
375 return new _MockAsset(id, assets[asset]);
376 });
377 } else if (assets is Iterable) {
378 assetList = assets.map((asset) {
379 var id = new AssetId.parse(asset);
380 var contents = pathos.basenameWithoutExtension(id.path);
381 return new _MockAsset(id, contents);
382 });
383 }
384
385 _packages = mapMapValues(groupBy(assetList, (asset) => asset.id.package),
386 (package, assets) {
387 var packageTransformers = transformers[package];
388 if (packageTransformers == null) packageTransformers = [];
389 return new _MockPackage(
390 new AssetSet.from(assets), packageTransformers.toList());
391 });
392
393 // If there are no assets or transformers, add a dummy package. This better 406 // If there are no assets or transformers, add a dummy package. This better
394 // simulates the real world, where there'll always be at least the 407 // simulates the real world, where there'll always be at least the
395 // entrypoint package. 408 // entrypoint package.
396 if (_packages.isEmpty) { 409 if (_assets.isEmpty) {
397 _packages = {"app": new _MockPackage(new AssetSet(), [])}; 410 _assets = {"app": new AssetSet()};
398 } 411 }
399 } 412 }
400 413
401 void _modifyAsset(String name, String contents) { 414 void _modifyAsset(String name, String contents) {
402 var id = new AssetId.parse(name); 415 var id = new AssetId.parse(name);
403 _errors.remove(id); 416 _errors.remove(id);
404 _packages[id.package].assets[id].contents = contents; 417 _assets[id.package][id].contents = contents;
405 } 418 }
406 419
407 void _setAssetError(String name) => _errors.add(new AssetId.parse(name)); 420 void _setAssetError(String name) => _errors.add(new AssetId.parse(name));
408 421
409 List<AssetId> listAssets(String package, {String within}) { 422 List<AssetId> listAssets(String package, {String within}) {
410 if (within != null) { 423 if (within != null) {
411 throw new UnimplementedError("Doesn't handle 'within' yet."); 424 throw new UnimplementedError("Doesn't handle 'within' yet.");
412 } 425 }
413 426
414 return _packages[package].assets.map((asset) => asset.id); 427 return _assets[package].map((asset) => asset.id);
415 }
416
417 Iterable<Iterable<Transformer>> getTransformers(String package) {
418 var mockPackage = _packages[package];
419 if (mockPackage == null) {
420 throw new ArgumentError("No package named $package.");
421 }
422 return mockPackage.transformers;
423 } 428 }
424 429
425 Future<Asset> getAsset(AssetId id) { 430 Future<Asset> getAsset(AssetId id) {
426 // Eagerly load the asset so we can test an asset's value changing between 431 // Eagerly load the asset so we can test an asset's value changing between
427 // when a load starts and when it finishes. 432 // when a load starts and when it finishes.
428 var package = _packages[id.package]; 433 var assets = _assets[id.package];
429 var asset; 434 var asset;
430 if (package != null) asset = package.assets[id]; 435 if (assets != null) asset = assets[id];
431 436
432 var hasError = _errors.contains(id); 437 var hasError = _errors.contains(id);
433 438
434 var future; 439 var future;
435 if (_pauseCompleter != null) { 440 if (_pauseCompleter != null) {
436 future = _pauseCompleter.future; 441 future = _pauseCompleter.future;
437 } else { 442 } else {
438 future = new Future.value(); 443 future = new Future.value();
439 } 444 }
440 445
441 return future.then((_) { 446 return future.then((_) {
442 if (hasError) throw new MockLoadException(id); 447 if (hasError) throw new MockLoadException(id);
443 if (asset == null) throw new AssetNotFoundException(id); 448 if (asset == null) throw new AssetNotFoundException(id);
444 return asset; 449 return asset;
445 }); 450 });
446 } 451 }
447 } 452 }
448 453
449 /// Error thrown for assets with [setAssetError] set. 454 /// Error thrown for assets with [setAssetError] set.
450 class MockLoadException implements Exception { 455 class MockLoadException implements Exception {
451 final AssetId id; 456 final AssetId id;
452 457
453 MockLoadException(this.id); 458 MockLoadException(this.id);
454 459
455 String toString() => "Error loading $id."; 460 String toString() => "Error loading $id.";
456 } 461 }
457 462
458 /// Used by [MockProvider] to keep track of which assets and transformers exist
459 /// for each package.
460 class _MockPackage {
461 final AssetSet assets;
462 final List<List<Transformer>> transformers;
463
464 _MockPackage(this.assets, Iterable<Iterable<Transformer>> transformers)
465 : transformers = transformers.map((phase) => phase.toList()).toList();
466 }
467
468 /// An implementation of [Asset] that never hits the file system. 463 /// An implementation of [Asset] that never hits the file system.
469 class _MockAsset implements Asset { 464 class _MockAsset implements Asset {
470 final AssetId id; 465 final AssetId id;
471 String contents; 466 String contents;
472 467
473 _MockAsset(this.id, this.contents); 468 _MockAsset(this.id, this.contents);
474 469
475 Future<String> readAsString({Encoding encoding}) => 470 Future<String> readAsString({Encoding encoding}) =>
476 new Future.value(contents); 471 new Future.value(contents);
477 472
478 Stream<List<int>> read() => throw new UnimplementedError(); 473 Stream<List<int>> read() => throw new UnimplementedError();
479 474
480 String toString() => "MockAsset $id $contents"; 475 String toString() => "MockAsset $id $contents";
481 } 476 }
OLDNEW
« no previous file with comments | « pkg/barback/test/package_graph/transform_test.dart ('k') | sdk/lib/_internal/pub/lib/src/pub_package_provider.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698