| 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 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 76 /// functions. | 76 /// functions. |
| 77 /// | 77 /// |
| 78 /// [assets] may either be an [Iterable] or a [Map]. If it's an [Iterable], | 78 /// [assets] may either be an [Iterable] or a [Map]. If it's an [Iterable], |
| 79 /// each element may either be an [AssetId] or a string that can be parsed to | 79 /// each element may either be an [AssetId] or a string that can be parsed to |
| 80 /// one. If it's a [Map], each key should be a string that can be parsed to an | 80 /// one. If it's a [Map], each key should be a string that can be parsed to an |
| 81 /// [AssetId] and the value should be a string defining the contents of that | 81 /// [AssetId] and the value should be a string defining the contents of that |
| 82 /// asset. | 82 /// asset. |
| 83 /// | 83 /// |
| 84 /// [transformers] is a map from package names to the transformers for each | 84 /// [transformers] is a map from package names to the transformers for each |
| 85 /// package. | 85 /// package. |
| 86 void initGraph([assets, | 86 void initGraph([assets, Map<String, Iterable<Iterable>> transformers]) => |
| 87 Map<String, Iterable<Iterable<Transformer>>> transformers]) => | |
| 88 initStaticGraph(assets, transformers: transformers); | 87 initStaticGraph(assets, transformers: transformers); |
| 89 | 88 |
| 90 void initStaticGraph(assets, {Iterable<String> staticPackages, | 89 void initStaticGraph(assets, |
| 90 {Iterable<String> staticPackages, |
| 91 Map<String, Iterable<Iterable<Transformer>>> transformers}) { | 91 Map<String, Iterable<Iterable<Transformer>>> transformers}) { |
| 92 if (assets == null) assets = []; | 92 if (assets == null) assets = []; |
| 93 if (staticPackages == null) staticPackages = []; | 93 if (staticPackages == null) staticPackages = []; |
| 94 if (transformers == null) transformers = {}; | 94 if (transformers == null) transformers = {}; |
| 95 | 95 |
| 96 _provider = new MockProvider(assets, | 96 _provider = new MockProvider(assets, |
| 97 staticPackages: staticPackages, | 97 staticPackages: staticPackages, additionalPackages: transformers.keys); |
| 98 additionalPackages: transformers.keys); | |
| 99 _barback = new Barback(_provider); | 98 _barback = new Barback(_provider); |
| 100 // Add a dummy listener to the log so it doesn't print to stdout. | 99 // Add a dummy listener to the log so it doesn't print to stdout. |
| 101 _barback.log.listen((_) {}); | 100 _barback.log.listen((_) {}); |
| 102 _nextBuildResult = 0; | 101 _nextBuildResult = 0; |
| 103 _nextLog = 0; | 102 _nextLog = 0; |
| 104 | 103 |
| 105 schedule(() => transformers.forEach(_barback.updateTransformers)); | 104 schedule(() => transformers.forEach(_barback.updateTransformers)); |
| 106 | 105 |
| 107 // There should be one successful build after adding all the transformers but | 106 // There should be one successful build after adding all the transformers but |
| 108 // before adding any sources. | 107 // before adding any sources. |
| 109 if (!transformers.isEmpty) buildShouldSucceed(); | 108 if (!transformers.isEmpty) buildShouldSucceed(); |
| 110 } | 109 } |
| 111 | 110 |
| 112 /// Updates [assets] in the current [PackageProvider]. | 111 /// Updates [assets] in the current [PackageProvider]. |
| 113 /// | 112 /// |
| 114 /// Each item in the list may either be an [AssetId] or a string that can be | 113 /// Each item in the list may either be an [AssetId] or a string that can be |
| 115 /// parsed as one. | 114 /// parsed as one. |
| 116 void updateSources(Iterable assets) { | 115 void updateSources(Iterable assets) { |
| 117 var parsed = _parseAssets(assets); | 116 var parsed = _parseAssets(assets); |
| 118 schedule(() => _barback.updateSources(parsed), | 117 schedule( |
| 119 "updating ${parsed.join(', ')}"); | 118 () => _barback.updateSources(parsed), "updating ${parsed.join(', ')}"); |
| 120 } | 119 } |
| 121 | 120 |
| 122 /// Updates [assets] in the current [PackageProvider]. | 121 /// Updates [assets] in the current [PackageProvider]. |
| 123 /// | 122 /// |
| 124 /// Each item in the list may either be an [AssetId] or a string that can be | 123 /// 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 | 124 /// parsed as one. Unlike [updateSources], this is not automatically scheduled |
| 126 /// and will be run synchronously when called. | 125 /// and will be run synchronously when called. |
| 127 void updateSourcesSync(Iterable assets) => | 126 void updateSourcesSync(Iterable assets) => |
| 128 _barback.updateSources(_parseAssets(assets)); | 127 _barback.updateSources(_parseAssets(assets)); |
| 129 | 128 |
| 130 /// Removes [assets] from the current [PackageProvider]. | 129 /// Removes [assets] from the current [PackageProvider]. |
| 131 /// | 130 /// |
| 132 /// Each item in the list may either be an [AssetId] or a string that can be | 131 /// Each item in the list may either be an [AssetId] or a string that can be |
| 133 /// parsed as one. | 132 /// parsed as one. |
| 134 void removeSources(Iterable assets) { | 133 void removeSources(Iterable assets) { |
| 135 var parsed = _parseAssets(assets); | 134 var parsed = _parseAssets(assets); |
| 136 schedule(() => _barback.removeSources(parsed), | 135 schedule( |
| 137 "removing ${parsed.join(', ')}"); | 136 () => _barback.removeSources(parsed), "removing ${parsed.join(', ')}"); |
| 138 } | 137 } |
| 139 | 138 |
| 140 /// Removes [assets] from the current [PackageProvider]. | 139 /// Removes [assets] from the current [PackageProvider]. |
| 141 /// | 140 /// |
| 142 /// Each item in the list may either be an [AssetId] or a string that can be | 141 /// 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 | 142 /// parsed as one. Unlike [removeSources], this is not automatically scheduled |
| 144 /// and will be run synchronously when called. | 143 /// and will be run synchronously when called. |
| 145 void removeSourcesSync(Iterable assets) => | 144 void removeSourcesSync(Iterable assets) => |
| 146 _barback.removeSources(_parseAssets(assets)); | 145 _barback.removeSources(_parseAssets(assets)); |
| 147 | 146 |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 194 schedule(() => _provider._resume(), "resume provider"); | 193 schedule(() => _provider._resume(), "resume provider"); |
| 195 } | 194 } |
| 196 | 195 |
| 197 /// Asserts that the current build step shouldn't have finished by this point in | 196 /// Asserts that the current build step shouldn't have finished by this point in |
| 198 /// the schedule. | 197 /// the schedule. |
| 199 /// | 198 /// |
| 200 /// This uses the same build counter as [buildShouldSucceed] and | 199 /// This uses the same build counter as [buildShouldSucceed] and |
| 201 /// [buildShouldFail], so those can be used to validate build results before and | 200 /// [buildShouldFail], so those can be used to validate build results before and |
| 202 /// after this. | 201 /// after this. |
| 203 void buildShouldNotBeDone() { | 202 void buildShouldNotBeDone() { |
| 204 _futureShouldNotCompleteUntil( | 203 _futureShouldNotCompleteUntil(_barback.results.elementAt(_nextBuildResult), |
| 205 _barback.results.elementAt(_nextBuildResult), | 204 schedule(() => pumpEventQueue(), "build should not terminate"), "build"); |
| 206 schedule(() => pumpEventQueue(), "build should not terminate"), | |
| 207 "build"); | |
| 208 } | 205 } |
| 209 | 206 |
| 210 /// Expects that the next [BuildResult] is a build success. | 207 /// Expects that the next [BuildResult] is a build success. |
| 211 void buildShouldSucceed() { | 208 void buildShouldSucceed() { |
| 212 expect(_getNextBuildResult("build should succeed").then((result) { | 209 expect( |
| 213 for (var error in result.errors) { | 210 _getNextBuildResult("build should succeed").then((result) { |
| 214 currentSchedule.signalError(error); | 211 for (var error in result.errors) { |
| 215 } | 212 currentSchedule.signalError(error); |
| 216 expect(result.succeeded, isTrue); | 213 } |
| 217 }), completes); | 214 expect(result.succeeded, isTrue); |
| 215 }), |
| 216 completes); |
| 218 } | 217 } |
| 219 | 218 |
| 220 /// Expects that the next [BuildResult] emitted is a failure. | 219 /// Expects that the next [BuildResult] emitted is a failure. |
| 221 /// | 220 /// |
| 222 /// [matchers] is a list of matchers to match against the errors that caused the | 221 /// [matchers] is a list of matchers to match against the errors that caused the |
| 223 /// build to fail. Every matcher is expected to match an error, but the order of | 222 /// build to fail. Every matcher is expected to match an error, but the order of |
| 224 /// matchers is unimportant. | 223 /// matchers is unimportant. |
| 225 void buildShouldFail(List matchers) { | 224 void buildShouldFail(List matchers) { |
| 226 expect(_getNextBuildResult("build should fail").then((result) { | 225 expect( |
| 227 expect(result.succeeded, isFalse); | 226 _getNextBuildResult("build should fail").then((result) { |
| 228 expect(result.errors.length, equals(matchers.length)); | 227 expect(result.succeeded, isFalse); |
| 229 for (var matcher in matchers) { | 228 expect(result.errors.length, equals(matchers.length)); |
| 230 expect(result.errors, contains(matcher)); | 229 for (var matcher in matchers) { |
| 231 } | 230 expect(result.errors, contains(matcher)); |
| 232 }), completes); | 231 } |
| 232 }), |
| 233 completes); |
| 233 } | 234 } |
| 234 | 235 |
| 235 /// Expects that the nexted logged [LogEntry] matches [matcher] which may be | 236 /// Expects that the nexted logged [LogEntry] matches [matcher] which may be |
| 236 /// either a [Matcher] or a string to match a literal string. | 237 /// either a [Matcher] or a string to match a literal string. |
| 237 void buildShouldLog(LogLevel level, matcher) { | 238 void buildShouldLog(LogLevel level, matcher) { |
| 238 expect(_getNextLog("build should log").then((log) { | 239 expect( |
| 239 expect(log.level, equals(level)); | 240 _getNextLog("build should log").then((log) { |
| 240 expect(log.message, matcher); | 241 expect(log.level, equals(level)); |
| 241 }), completes); | 242 expect(log.message, matcher); |
| 243 }), |
| 244 completes); |
| 242 } | 245 } |
| 243 | 246 |
| 244 Future<BuildResult> _getNextBuildResult(String description) { | 247 Future<BuildResult> _getNextBuildResult(String description) { |
| 245 var result = currentSchedule.wrapFuture( | 248 var result = currentSchedule |
| 246 _barback.results.elementAt(_nextBuildResult++)); | 249 .wrapFuture(_barback.results.elementAt(_nextBuildResult++)); |
| 247 return schedule(() => result, description); | 250 return schedule(() => result, description); |
| 248 } | 251 } |
| 249 | 252 |
| 250 Future<LogEntry> _getNextLog(String description) { | 253 Future<LogEntry> _getNextLog(String description) { |
| 251 var result = currentSchedule.wrapFuture( | 254 var result = currentSchedule.wrapFuture(_barback.log.elementAt(_nextLog++)); |
| 252 _barback.log.elementAt(_nextLog++)); | |
| 253 return schedule(() => result, description); | 255 return schedule(() => result, description); |
| 254 } | 256 } |
| 255 | 257 |
| 256 /// Schedules an expectation that the graph will deliver an asset matching | 258 /// Schedules an expectation that the graph will deliver an asset matching |
| 257 /// [name] and [contents]. | 259 /// [name] and [contents]. |
| 258 /// | 260 /// |
| 259 /// [contents] may be a [String] or a [Matcher] that matches a string. If | 261 /// [contents] may be a [String] or a [Matcher] that matches a string. If |
| 260 /// [contents] is omitted, defaults to the asset's filename without an extension | 262 /// [contents] is omitted, defaults to the asset's filename without an extension |
| 261 /// (which is the same default that [initGraph] uses). | 263 /// (which is the same default that [initGraph] uses). |
| 262 void expectAsset(String name, [contents]) { | 264 void expectAsset(String name, [contents]) { |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 343 }, "get all assets should fail"); | 345 }, "get all assets should fail"); |
| 344 } | 346 } |
| 345 | 347 |
| 346 /// Schedules an expectation that a [getAssetById] call for the given asset | 348 /// Schedules an expectation that a [getAssetById] call for the given asset |
| 347 /// won't terminate at this point in the schedule. | 349 /// won't terminate at this point in the schedule. |
| 348 void expectAssetDoesNotComplete(String name) { | 350 void expectAssetDoesNotComplete(String name) { |
| 349 var id = new AssetId.parse(name); | 351 var id = new AssetId.parse(name); |
| 350 | 352 |
| 351 schedule(() { | 353 schedule(() { |
| 352 return _futureShouldNotCompleteUntil( | 354 return _futureShouldNotCompleteUntil( |
| 353 _barback.getAssetById(id), | 355 _barback.getAssetById(id), pumpEventQueue(), "asset $id"); |
| 354 pumpEventQueue(), | |
| 355 "asset $id"); | |
| 356 }, "asset $id should not complete"); | 356 }, "asset $id should not complete"); |
| 357 } | 357 } |
| 358 | 358 |
| 359 /// Returns a matcher for an [AggregateException] containing errors that match | 359 /// Returns a matcher for an [AggregateException] containing errors that match |
| 360 /// [matchers]. | 360 /// [matchers]. |
| 361 Matcher isAggregateException(Iterable<Matcher> errors) { | 361 Matcher isAggregateException(Iterable<Matcher> errors) { |
| 362 // Match the aggregate error itself. | 362 // Match the aggregate error itself. |
| 363 var matchers = [ | 363 var matchers = [ |
| 364 new isInstanceOf<AggregateException>(), | 364 new isInstanceOf<AggregateException>(), |
| 365 transform((error) => error.errors, hasLength(errors.length), | 365 transform((error) => error.errors, hasLength(errors.length), |
| 366 'errors.length == ${errors.length}') | 366 'errors.length == ${errors.length}') |
| 367 ]; | 367 ]; |
| 368 | 368 |
| 369 // Make sure its contained errors match the matchers. | 369 // Make sure its contained errors match the matchers. |
| 370 for (var error in errors) { | 370 for (var error in errors) { |
| 371 matchers.add(transform((error) => error.errors, contains(error), | 371 matchers.add( |
| 372 error.toString())); | 372 transform((error) => error.errors, contains(error), error.toString())); |
| 373 } | 373 } |
| 374 | 374 |
| 375 return allOf(matchers); | 375 return allOf(matchers); |
| 376 } | 376 } |
| 377 | 377 |
| 378 /// Returns a matcher for an [AssetNotFoundException] with the given [id]. | 378 /// Returns a matcher for an [AssetNotFoundException] with the given [id]. |
| 379 Matcher isAssetNotFoundException(String name) { | 379 Matcher isAssetNotFoundException(String name) { |
| 380 var id = new AssetId.parse(name); | 380 var id = new AssetId.parse(name); |
| 381 return allOf( | 381 return allOf(new isInstanceOf<AssetNotFoundException>(), |
| 382 new isInstanceOf<AssetNotFoundException>(), | |
| 383 predicate((error) => error.id == id, 'id == $name')); | 382 predicate((error) => error.id == id, 'id == $name')); |
| 384 } | 383 } |
| 385 | 384 |
| 386 /// Returns a matcher for an [AssetCollisionException] with the given [id]. | 385 /// Returns a matcher for an [AssetCollisionException] with the given [id]. |
| 387 Matcher isAssetCollisionException(String name) { | 386 Matcher isAssetCollisionException(String name) { |
| 388 var id = new AssetId.parse(name); | 387 var id = new AssetId.parse(name); |
| 389 return allOf( | 388 return allOf(new isInstanceOf<AssetCollisionException>(), |
| 390 new isInstanceOf<AssetCollisionException>(), | |
| 391 predicate((error) => error.id == id, 'id == $name')); | 389 predicate((error) => error.id == id, 'id == $name')); |
| 392 } | 390 } |
| 393 | 391 |
| 394 /// Returns a matcher for a [MissingInputException] with the given [id]. | 392 /// Returns a matcher for a [MissingInputException] with the given [id]. |
| 395 Matcher isMissingInputException(String name) { | 393 Matcher isMissingInputException(String name) { |
| 396 var id = new AssetId.parse(name); | 394 var id = new AssetId.parse(name); |
| 397 return allOf( | 395 return allOf(new isInstanceOf<MissingInputException>(), |
| 398 new isInstanceOf<MissingInputException>(), | |
| 399 predicate((error) => error.id == id, 'id == $name')); | 396 predicate((error) => error.id == id, 'id == $name')); |
| 400 } | 397 } |
| 401 | 398 |
| 402 /// Returns a matcher for an [InvalidOutputException] with the given id. | 399 /// Returns a matcher for an [InvalidOutputException] with the given id. |
| 403 Matcher isInvalidOutputException(String name) { | 400 Matcher isInvalidOutputException(String name) { |
| 404 var id = new AssetId.parse(name); | 401 var id = new AssetId.parse(name); |
| 405 return allOf( | 402 return allOf(new isInstanceOf<InvalidOutputException>(), |
| 406 new isInstanceOf<InvalidOutputException>(), | |
| 407 predicate((error) => error.id == id, 'id == $name')); | 403 predicate((error) => error.id == id, 'id == $name')); |
| 408 } | 404 } |
| 409 | 405 |
| 410 /// Returns a matcher for an [AssetLoadException] with the given id and a | 406 /// Returns a matcher for an [AssetLoadException] with the given id and a |
| 411 /// wrapped error that matches [error]. | 407 /// wrapped error that matches [error]. |
| 412 Matcher isAssetLoadException(String name, error) { | 408 Matcher isAssetLoadException(String name, error) { |
| 413 var id = new AssetId.parse(name); | 409 var id = new AssetId.parse(name); |
| 414 return allOf( | 410 return allOf( |
| 415 new isInstanceOf<AssetLoadException>(), | 411 new isInstanceOf<AssetLoadException>(), |
| 416 transform((error) => error.id, equals(id), 'id'), | 412 transform((error) => error.id, equals(id), 'id'), |
| 417 transform((error) => error.error, wrapMatcher(error), 'error')); | 413 transform((error) => error.error, wrapMatcher(error), 'error')); |
| 418 } | 414 } |
| 419 | 415 |
| 420 /// Returns a matcher for a [TransformerException] with a wrapped error that | 416 /// Returns a matcher for a [TransformerException] with a wrapped error that |
| 421 /// matches [error]. | 417 /// matches [error]. |
| 422 Matcher isTransformerException(error) { | 418 Matcher isTransformerException(error) { |
| 423 return allOf( | 419 return allOf(new isInstanceOf<TransformerException>(), |
| 424 new isInstanceOf<TransformerException>(), | |
| 425 transform((error) => error.error, wrapMatcher(error), 'error')); | 420 transform((error) => error.error, wrapMatcher(error), 'error')); |
| 426 } | 421 } |
| 427 | 422 |
| 428 /// Returns a matcher for a [MockLoadException] with the given [id]. | 423 /// Returns a matcher for a [MockLoadException] with the given [id]. |
| 429 Matcher isMockLoadException(String name) { | 424 Matcher isMockLoadException(String name) { |
| 430 var id = new AssetId.parse(name); | 425 var id = new AssetId.parse(name); |
| 431 return allOf( | 426 return allOf(new isInstanceOf<MockLoadException>(), |
| 432 new isInstanceOf<MockLoadException>(), | |
| 433 predicate((error) => error.id == id, 'id == $name')); | 427 predicate((error) => error.id == id, 'id == $name')); |
| 434 } | 428 } |
| 435 | 429 |
| 436 /// Returns a matcher that runs [transformation] on its input, then matches | 430 /// Returns a matcher that runs [transformation] on its input, then matches |
| 437 /// the output against [matcher]. | 431 /// the output against [matcher]. |
| 438 /// | 432 /// |
| 439 /// [description] should be a noun phrase that describes the relation of the | 433 /// [description] should be a noun phrase that describes the relation of the |
| 440 /// output of [transformation] to its input. | 434 /// output of [transformation] to its input. |
| 441 Matcher transform(transformation(value), matcher, String description) => | 435 Matcher transform(transformation(value), matcher, String description) => |
| 442 new _TransformMatcher(transformation, wrapMatcher(matcher), description); | 436 new _TransformMatcher(transformation, wrapMatcher(matcher), description); |
| 443 | 437 |
| 444 class _TransformMatcher extends Matcher { | 438 class _TransformMatcher extends Matcher { |
| 445 final Function _transformation; | 439 final Function _transformation; |
| 446 final Matcher _matcher; | 440 final Matcher _matcher; |
| 447 final String _description; | 441 final String _description; |
| 448 | 442 |
| 449 _TransformMatcher(this._transformation, this._matcher, this._description); | 443 _TransformMatcher(this._transformation, this._matcher, this._description); |
| 450 | 444 |
| 451 bool matches(item, Map matchState) => | 445 bool matches(item, Map matchState) => |
| 452 _matcher.matches(_transformation(item), matchState); | 446 _matcher.matches(_transformation(item), matchState); |
| 453 | 447 |
| 454 Description describe(Description description) => | 448 Description describe(Description description) => |
| 455 description.add(_description).add(' ').addDescriptionOf(_matcher); | 449 description.add(_description).add(' ').addDescriptionOf(_matcher); |
| 456 } | 450 } |
| 457 | 451 |
| 458 /// Asserts that [future] shouldn't complete until after [delay] completes. | 452 /// Asserts that [future] shouldn't complete until after [delay] completes. |
| 459 /// | 453 /// |
| 460 /// Once [delay] completes, the output of [future] is ignored, even if it's an | 454 /// Once [delay] completes, the output of [future] is ignored, even if it's an |
| 461 /// error. | 455 /// error. |
| 462 /// | 456 /// |
| 463 /// [description] should describe [future]. | 457 /// [description] should describe [future]. |
| 464 Future _futureShouldNotCompleteUntil(Future future, Future delay, | 458 Future _futureShouldNotCompleteUntil( |
| 465 String description) { | 459 Future future, Future delay, String description) { |
| 466 var trace = new Trace.current(); | 460 var trace = new Trace.current(); |
| 467 var cancelable = new CancelableFuture(future); | 461 var cancelable = new CancelableFuture(future); |
| 468 cancelable.then((result) { | 462 cancelable.then((result) { |
| 469 currentSchedule.signalError( | 463 currentSchedule.signalError( |
| 470 new Exception("Expected $description not to complete here, but it " | 464 new Exception("Expected $description not to complete here, but it " |
| 471 "completed with result: $result"), | 465 "completed with result: $result"), |
| 472 trace); | 466 trace); |
| 473 }).catchError((error) { | 467 }).catchError((error) { |
| 474 currentSchedule.signalError(error); | 468 currentSchedule.signalError(error); |
| 475 }); | 469 }); |
| (...skipping 29 matching lines...) Expand all Loading... |
| 505 /// Lets you test the asynchronous behavior of loading. | 499 /// Lets you test the asynchronous behavior of loading. |
| 506 void _pause() { | 500 void _pause() { |
| 507 _pauseCompleter = new Completer(); | 501 _pauseCompleter = new Completer(); |
| 508 } | 502 } |
| 509 | 503 |
| 510 void _resume() { | 504 void _resume() { |
| 511 _pauseCompleter.complete(); | 505 _pauseCompleter.complete(); |
| 512 _pauseCompleter = null; | 506 _pauseCompleter = null; |
| 513 } | 507 } |
| 514 | 508 |
| 515 MockProvider(assets, {Iterable<String> staticPackages, | 509 MockProvider(assets, |
| 516 Iterable<String> additionalPackages}) | 510 {Iterable<String> staticPackages, Iterable<String> additionalPackages}) |
| 517 : staticPackages = staticPackages == null ? new Set() : | 511 : staticPackages = |
| 518 staticPackages.toSet(), | 512 staticPackages == null ? new Set() : staticPackages.toSet(), |
| 519 _assets = _normalizeAssets(assets, additionalPackages); | 513 _assets = _normalizeAssets(assets, additionalPackages); |
| 520 | 514 |
| 521 static Map<String, AssetSet> _normalizeAssets(assets, | 515 static Map<String, AssetSet> _normalizeAssets( |
| 522 Iterable<String> additionalPackages) { | 516 assets, Iterable<String> additionalPackages) { |
| 523 Iterable<Asset> assetList; | 517 Iterable<Asset> assetList; |
| 524 if (assets is Map) { | 518 if (assets is Map) { |
| 525 assetList = assets.keys.map((asset) { | 519 assetList = assets.keys.map((asset) { |
| 526 var id = new AssetId.parse(asset); | 520 var id = new AssetId.parse(asset); |
| 527 return new _MockAsset(id, assets[asset]); | 521 return new _MockAsset(id, assets[asset]); |
| 528 }); | 522 }); |
| 529 } else if (assets is Iterable) { | 523 } else if (assets is Iterable) { |
| 530 assetList = assets.map((asset) { | 524 assetList = assets.map((asset) { |
| 531 var id = new AssetId.parse(asset); | 525 var id = new AssetId.parse(asset); |
| 532 var contents = pathos.basenameWithoutExtension(id.path); | 526 var contents = pathos.basenameWithoutExtension(id.path); |
| 533 return new _MockAsset(id, contents); | 527 return new _MockAsset(id, contents); |
| 534 }); | 528 }); |
| 535 } | 529 } |
| 536 | 530 |
| 537 var assetMap = mapMapValues( | 531 var assetMap = mapMapValues(groupBy(assetList, (asset) => asset.id.package), |
| 538 groupBy(assetList, (asset) => asset.id.package), | |
| 539 (_, assets) => new AssetSet.from(assets)); | 532 (_, assets) => new AssetSet.from(assets)); |
| 540 | 533 |
| 541 // Make sure that packages that have transformers but no assets are | 534 // Make sure that packages that have transformers but no assets are |
| 542 // considered by MockProvider to exist. | 535 // considered by MockProvider to exist. |
| 543 if (additionalPackages != null) { | 536 if (additionalPackages != null) { |
| 544 for (var package in additionalPackages) { | 537 for (var package in additionalPackages) { |
| 545 assetMap.putIfAbsent(package, () => new AssetSet()); | 538 assetMap.putIfAbsent(package, () => new AssetSet()); |
| 546 } | 539 } |
| 547 } | 540 } |
| 548 | 541 |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 600 | 593 |
| 601 _MockAsset(this.id, this.contents); | 594 _MockAsset(this.id, this.contents); |
| 602 | 595 |
| 603 Future<String> readAsString({Encoding encoding}) => | 596 Future<String> readAsString({Encoding encoding}) => |
| 604 new Future.value(contents); | 597 new Future.value(contents); |
| 605 | 598 |
| 606 Stream<List<int>> read() => throw new UnimplementedError(); | 599 Stream<List<int>> read() => throw new UnimplementedError(); |
| 607 | 600 |
| 608 String toString() => "MockAsset $id $contents"; | 601 String toString() => "MockAsset $id $contents"; |
| 609 } | 602 } |
| OLD | NEW |