OLD | NEW |
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:convert' show Encoding; | 8 import 'dart:convert' show Encoding; |
9 | 9 |
10 import 'package:barback/barback.dart'; | 10 import 'package:barback/barback.dart'; |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
107 // There should be one successful build after adding all the transformers but | 107 // There should be one successful build after adding all the transformers but |
108 // before adding any sources. | 108 // before adding any sources. |
109 if (!transformers.isEmpty) buildShouldSucceed(); | 109 if (!transformers.isEmpty) buildShouldSucceed(); |
110 } | 110 } |
111 | 111 |
112 /// Updates [assets] in the current [PackageProvider]. | 112 /// Updates [assets] in the current [PackageProvider]. |
113 /// | 113 /// |
114 /// Each item in the list may either be an [AssetId] or a string that can be | 114 /// Each item in the list may either be an [AssetId] or a string that can be |
115 /// parsed as one. | 115 /// parsed as one. |
116 void updateSources(Iterable assets) { | 116 void updateSources(Iterable assets) { |
117 assets = _parseAssets(assets); | 117 var parsed = _parseAssets(assets); |
118 schedule(() => _barback.updateSources(assets), | 118 schedule(() => _barback.updateSources(parsed), |
119 "updating ${assets.join(', ')}"); | 119 "updating ${parsed.join(', ')}"); |
120 } | 120 } |
121 | 121 |
122 /// Updates [assets] in the current [PackageProvider]. | 122 /// Updates [assets] in the current [PackageProvider]. |
123 /// | 123 /// |
124 /// Each item in the list may either be an [AssetId] or a string that can be | 124 /// Each item in the list may either be an [AssetId] or a string that can be |
125 /// parsed as one. Unlike [updateSources], this is not automatically scheduled | 125 /// parsed as one. Unlike [updateSources], this is not automatically scheduled |
126 /// and will be run synchronously when called. | 126 /// and will be run synchronously when called. |
127 void updateSourcesSync(Iterable assets) => | 127 void updateSourcesSync(Iterable assets) => |
128 _barback.updateSources(_parseAssets(assets)); | 128 _barback.updateSources(_parseAssets(assets)); |
129 | 129 |
130 /// Removes [assets] from the current [PackageProvider]. | 130 /// Removes [assets] from the current [PackageProvider]. |
131 /// | 131 /// |
132 /// Each item in the list may either be an [AssetId] or a string that can be | 132 /// Each item in the list may either be an [AssetId] or a string that can be |
133 /// parsed as one. | 133 /// parsed as one. |
134 void removeSources(Iterable assets) { | 134 void removeSources(Iterable assets) { |
135 assets = _parseAssets(assets); | 135 var parsed = _parseAssets(assets); |
136 schedule(() => _barback.removeSources(assets), | 136 schedule(() => _barback.removeSources(parsed), |
137 "removing ${assets.join(', ')}"); | 137 "removing ${parsed.join(', ')}"); |
138 } | 138 } |
139 | 139 |
140 /// Removes [assets] from the current [PackageProvider]. | 140 /// Removes [assets] from the current [PackageProvider]. |
141 /// | 141 /// |
142 /// Each item in the list may either be an [AssetId] or a string that can be | 142 /// Each item in the list may either be an [AssetId] or a string that can be |
143 /// parsed as one. Unlike [removeSources], this is not automatically scheduled | 143 /// parsed as one. Unlike [removeSources], this is not automatically scheduled |
144 /// and will be run synchronously when called. | 144 /// and will be run synchronously when called. |
145 void removeSourcesSync(Iterable assets) => | 145 void removeSourcesSync(Iterable assets) => |
146 _barback.removeSources(_parseAssets(assets)); | 146 _barback.removeSources(_parseAssets(assets)); |
147 | 147 |
148 /// Sets the transformers for [package] to [transformers]. | 148 /// Sets the transformers for [package] to [transformers]. |
149 void updateTransformers(String package, Iterable<Iterable> transformers) { | 149 void updateTransformers(String package, Iterable<Iterable> transformers) { |
150 schedule(() => _barback.updateTransformers(package, transformers), | 150 schedule(() => _barback.updateTransformers(package, transformers), |
151 "updating transformers for $package"); | 151 "updating transformers for $package"); |
152 } | 152 } |
153 | 153 |
154 /// Parse a list of strings or [AssetId]s into a list of [AssetId]s. | 154 /// Parse a list of strings or [AssetId]s into a list of [AssetId]s. |
155 List<AssetId> _parseAssets(Iterable assets) { | 155 List<AssetId> _parseAssets(Iterable assets) { |
156 return assets.map((asset) { | 156 return assets.map((asset) { |
157 if (asset is String) return new AssetId.parse(asset); | 157 if (asset is String) return new AssetId.parse(asset); |
158 return asset; | 158 return asset as AssetId; |
159 }).toList(); | 159 }).toList(); |
160 } | 160 } |
161 | 161 |
162 /// Schedules a change to the contents of an asset identified by [name] to | 162 /// Schedules a change to the contents of an asset identified by [name] to |
163 /// [contents]. | 163 /// [contents]. |
164 /// | 164 /// |
165 /// Does not update it in the graph. | 165 /// Does not update it in the graph. |
166 void modifyAsset(String name, String contents) { | 166 void modifyAsset(String name, String contents) { |
167 schedule(() { | 167 schedule(() { |
168 _provider._modifyAsset(name, contents); | 168 _provider._modifyAsset(name, contents); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
203 void buildShouldNotBeDone() { | 203 void buildShouldNotBeDone() { |
204 _futureShouldNotCompleteUntil( | 204 _futureShouldNotCompleteUntil( |
205 _barback.results.elementAt(_nextBuildResult), | 205 _barback.results.elementAt(_nextBuildResult), |
206 schedule(() => pumpEventQueue(), "build should not terminate"), | 206 schedule(() => pumpEventQueue(), "build should not terminate"), |
207 "build"); | 207 "build"); |
208 } | 208 } |
209 | 209 |
210 /// Expects that the next [BuildResult] is a build success. | 210 /// Expects that the next [BuildResult] is a build success. |
211 void buildShouldSucceed() { | 211 void buildShouldSucceed() { |
212 expect(_getNextBuildResult("build should succeed").then((result) { | 212 expect(_getNextBuildResult("build should succeed").then((result) { |
213 result.errors.forEach(currentSchedule.signalError); | 213 for (var error in result.errors) { |
| 214 currentSchedule.signalError(error); |
| 215 } |
214 expect(result.succeeded, isTrue); | 216 expect(result.succeeded, isTrue); |
215 }), completes); | 217 }), completes); |
216 } | 218 } |
217 | 219 |
218 /// Expects that the next [BuildResult] emitted is a failure. | 220 /// Expects that the next [BuildResult] emitted is a failure. |
219 /// | 221 /// |
220 /// [matchers] is a list of matchers to match against the errors that caused the | 222 /// [matchers] is a list of matchers to match against the errors that caused the |
221 /// build to fail. Every matcher is expected to match an error, but the order of | 223 /// build to fail. Every matcher is expected to match an error, but the order of |
222 /// matchers is unimportant. | 224 /// matchers is unimportant. |
223 void buildShouldFail(List matchers) { | 225 void buildShouldFail(List matchers) { |
(...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
511 } | 513 } |
512 | 514 |
513 MockProvider(assets, {Iterable<String> staticPackages, | 515 MockProvider(assets, {Iterable<String> staticPackages, |
514 Iterable<String> additionalPackages}) | 516 Iterable<String> additionalPackages}) |
515 : staticPackages = staticPackages == null ? new Set() : | 517 : staticPackages = staticPackages == null ? new Set() : |
516 staticPackages.toSet(), | 518 staticPackages.toSet(), |
517 _assets = _normalizeAssets(assets, additionalPackages); | 519 _assets = _normalizeAssets(assets, additionalPackages); |
518 | 520 |
519 static Map<String, AssetSet> _normalizeAssets(assets, | 521 static Map<String, AssetSet> _normalizeAssets(assets, |
520 Iterable<String> additionalPackages) { | 522 Iterable<String> additionalPackages) { |
521 var assetList; | 523 Iterable<Asset> assetList; |
522 if (assets is Map) { | 524 if (assets is Map) { |
523 assetList = assets.keys.map((asset) { | 525 assetList = assets.keys.map((asset) { |
524 var id = new AssetId.parse(asset); | 526 var id = new AssetId.parse(asset); |
525 return new _MockAsset(id, assets[asset]); | 527 return new _MockAsset(id, assets[asset]); |
526 }); | 528 }); |
527 } else if (assets is Iterable) { | 529 } else if (assets is Iterable) { |
528 assetList = assets.map((asset) { | 530 assetList = assets.map((asset) { |
529 var id = new AssetId.parse(asset); | 531 var id = new AssetId.parse(asset); |
530 var contents = pathos.basenameWithoutExtension(id.path); | 532 var contents = pathos.basenameWithoutExtension(id.path); |
531 return new _MockAsset(id, contents); | 533 return new _MockAsset(id, contents); |
532 }); | 534 }); |
533 } | 535 } |
534 | 536 |
535 var assetMap = mapMapValues(groupBy(assetList, (asset) => asset.id.package), | 537 var assetMap = mapMapValues( |
536 (package, assets) => new AssetSet.from(assets)); | 538 groupBy(assetList, (asset) => asset.id.package), |
| 539 (_, assets) => new AssetSet.from(assets)); |
537 | 540 |
538 // Make sure that packages that have transformers but no assets are | 541 // Make sure that packages that have transformers but no assets are |
539 // considered by MockProvider to exist. | 542 // considered by MockProvider to exist. |
540 if (additionalPackages != null) { | 543 if (additionalPackages != null) { |
541 for (var package in additionalPackages) { | 544 for (var package in additionalPackages) { |
542 assetMap.putIfAbsent(package, () => new AssetSet()); | 545 assetMap.putIfAbsent(package, () => new AssetSet()); |
543 } | 546 } |
544 } | 547 } |
545 | 548 |
546 // If there are no assets or transformers, add a dummy package. This better | 549 // If there are no assets or transformers, add a dummy package. This better |
547 // simulates the real world, where there'll always be at least the | 550 // simulates the real world, where there'll always be at least the |
548 // entrypoint package. | 551 // entrypoint package. |
549 return assetMap.isEmpty ? {"app": new AssetSet()} : assetMap; | 552 return assetMap.isEmpty ? {"app": new AssetSet()} : assetMap; |
550 } | 553 } |
551 | 554 |
552 void _modifyAsset(String name, String contents) { | 555 void _modifyAsset(String name, String contents) { |
553 var id = new AssetId.parse(name); | 556 var id = new AssetId.parse(name); |
554 _errors.remove(id); | 557 _errors.remove(id); |
555 _syncErrors.remove(id); | 558 _syncErrors.remove(id); |
556 (_assets[id.package][id] as _MockAsset).contents = contents; | 559 (_assets[id.package][id] as _MockAsset).contents = contents; |
557 } | 560 } |
558 | 561 |
559 void _setAssetError(String name, bool async) { | 562 void _setAssetError(String name, bool async) { |
560 (async ? _errors : _syncErrors).add(new AssetId.parse(name)); | 563 (async ? _errors : _syncErrors).add(new AssetId.parse(name)); |
561 } | 564 } |
562 | 565 |
563 Stream<AssetId> getAllAssetIds(String package) => | 566 Stream<AssetId> getAllAssetIds(String package) => |
564 new Stream.fromIterable(_assets[package].map((asset) => asset.id)); | 567 new Stream.fromIterable(_assets[package].map((asset) => asset.id)); |
565 | 568 |
566 Future<Asset> getAsset(AssetId id) { | 569 Future<Asset> getAsset(AssetId id) async { |
567 // Eagerly load the asset so we can test an asset's value changing between | 570 // Eagerly load the asset so we can test an asset's value changing between |
568 // when a load starts and when it finishes. | 571 // when a load starts and when it finishes. |
569 var assets = _assets[id.package]; | 572 var assets = _assets[id.package]; |
570 var asset; | 573 var asset; |
571 if (assets != null) asset = assets[id]; | 574 if (assets != null) asset = assets[id]; |
572 | 575 |
573 if (_syncErrors.contains(id)) throw new MockLoadException(id); | 576 if (_syncErrors.contains(id)) throw new MockLoadException(id); |
574 var hasError = _errors.contains(id); | 577 var hasError = _errors.contains(id); |
575 | 578 |
576 var future; | 579 if (_pauseCompleter != null) await _pauseCompleter.future; |
577 if (_pauseCompleter != null) { | |
578 future = _pauseCompleter.future; | |
579 } else { | |
580 future = new Future.value(); | |
581 } | |
582 | 580 |
583 return future.then((_) { | 581 if (hasError) throw new MockLoadException(id); |
584 if (hasError) throw new MockLoadException(id); | 582 if (asset == null) throw new AssetNotFoundException(id); |
585 if (asset == null) throw new AssetNotFoundException(id); | 583 return asset; |
586 return asset; | |
587 }); | |
588 } | 584 } |
589 } | 585 } |
590 | 586 |
591 /// Error thrown for assets with [setAssetError] set. | 587 /// Error thrown for assets with [setAssetError] set. |
592 class MockLoadException implements Exception { | 588 class MockLoadException implements Exception { |
593 final AssetId id; | 589 final AssetId id; |
594 | 590 |
595 MockLoadException(this.id); | 591 MockLoadException(this.id); |
596 | 592 |
597 String toString() => "Error loading $id."; | 593 String toString() => "Error loading $id."; |
598 } | 594 } |
599 | 595 |
600 /// An implementation of [Asset] that never hits the file system. | 596 /// An implementation of [Asset] that never hits the file system. |
601 class _MockAsset implements Asset { | 597 class _MockAsset implements Asset { |
602 final AssetId id; | 598 final AssetId id; |
603 String contents; | 599 String contents; |
604 | 600 |
605 _MockAsset(this.id, this.contents); | 601 _MockAsset(this.id, this.contents); |
606 | 602 |
607 Future<String> readAsString({Encoding encoding}) => | 603 Future<String> readAsString({Encoding encoding}) => |
608 new Future.value(contents); | 604 new Future.value(contents); |
609 | 605 |
610 Stream<List<int>> read() => throw new UnimplementedError(); | 606 Stream<List<int>> read() => throw new UnimplementedError(); |
611 | 607 |
612 String toString() => "MockAsset $id $contents"; | 608 String toString() => "MockAsset $id $contents"; |
613 } | 609 } |
OLD | NEW |