| 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:collection'; | 8 import 'dart:collection'; |
| 9 | 9 |
| 10 import 'package:barback/barback.dart'; | 10 import 'package:barback/barback.dart'; |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 124 } | 124 } |
| 125 | 125 |
| 126 /// Pauses the schedule until the currently running build completes. | 126 /// Pauses the schedule until the currently running build completes. |
| 127 /// | 127 /// |
| 128 /// Validates that the build completed successfully. | 128 /// Validates that the build completed successfully. |
| 129 void waitForBuild() { | 129 void waitForBuild() { |
| 130 schedule(() { | 130 schedule(() { |
| 131 return _graph.results.first.then((result) { | 131 return _graph.results.first.then((result) { |
| 132 expect(result.succeeded, isTrue); | 132 expect(result.succeeded, isTrue); |
| 133 }); | 133 }); |
| 134 }); | 134 }, "wait for build"); |
| 135 } | 135 } |
| 136 | 136 |
| 137 /// Schedules an expectation that the graph will deliver an asset matching | 137 /// Schedules an expectation that the graph will deliver an asset matching |
| 138 /// [name] and [contents]. | 138 /// [name] and [contents]. |
| 139 /// | 139 /// |
| 140 /// If [contents] is omitted, defaults to the asset's filename without an | 140 /// If [contents] is omitted, defaults to the asset's filename without an |
| 141 /// extension (which is the same default that [initGraph] uses). | 141 /// extension (which is the same default that [initGraph] uses). |
| 142 void expectAsset(String name, [String contents]) { | 142 void expectAsset(String name, [String contents]) { |
| 143 var id = new AssetId.parse(name); | 143 var id = new AssetId.parse(name); |
| 144 | 144 |
| 145 if (contents == null) { | 145 if (contents == null) { |
| 146 contents = pathos.basenameWithoutExtension(id.path); | 146 contents = pathos.basenameWithoutExtension(id.path); |
| 147 } | 147 } |
| 148 | 148 |
| 149 schedule(() { | 149 schedule(() { |
| 150 return _graph.getAssetById(id).then((asset) { | 150 return _graph.getAssetById(id).then((asset) { |
| 151 // TODO(rnystrom): Make an actual Matcher class for this. | 151 // TODO(rnystrom): Make an actual Matcher class for this. |
| 152 expect(asset, new isInstanceOf<MockAsset>()); | 152 expect(asset, new isInstanceOf<MockAsset>()); |
| 153 expect(asset._id.package, equals(id.package)); | 153 expect(asset.id, equals(id)); |
| 154 expect(asset._id.path, equals(id.path)); | |
| 155 expect(asset._contents, equals(contents)); | 154 expect(asset._contents, equals(contents)); |
| 156 }); | 155 }); |
| 157 }, "get asset $name"); | 156 }, "get asset $name"); |
| 158 } | 157 } |
| 159 | 158 |
| 160 /// Schedules an expectation that the graph will not find an asset matching | 159 /// Schedules an expectation that the graph will not find an asset matching |
| 161 /// [name]. | 160 /// [name]. |
| 162 void expectNoAsset(String name) { | 161 void expectNoAsset(String name) { |
| 163 var id = new AssetId.parse(name); | 162 var id = new AssetId.parse(name); |
| 164 | 163 |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 235 var id = new AssetId.parse(asset); | 234 var id = new AssetId.parse(asset); |
| 236 var package = _packages.putIfAbsent(id.package, () => []); | 235 var package = _packages.putIfAbsent(id.package, () => []); |
| 237 var contents = pathos.basenameWithoutExtension(id.path); | 236 var contents = pathos.basenameWithoutExtension(id.path); |
| 238 package.add(new MockAsset(id, contents)); | 237 package.add(new MockAsset(id, contents)); |
| 239 } | 238 } |
| 240 } | 239 } |
| 241 } | 240 } |
| 242 | 241 |
| 243 void _modifyAsset(String name, String contents) { | 242 void _modifyAsset(String name, String contents) { |
| 244 var id = new AssetId.parse(name); | 243 var id = new AssetId.parse(name); |
| 245 var asset = _packages[id.package].firstWhere((a) => a._id == id); | 244 var asset = _packages[id.package].firstWhere((a) => a.id == id); |
| 246 asset._contents = contents; | 245 asset._contents = contents; |
| 247 } | 246 } |
| 248 | 247 |
| 249 List<AssetId> listAssets(String package, {String within}) { | 248 List<AssetId> listAssets(String package, {String within}) { |
| 250 if (within != null) { | 249 if (within != null) { |
| 251 throw new UnimplementedError("Doesn't handle 'within' yet."); | 250 throw new UnimplementedError("Doesn't handle 'within' yet."); |
| 252 } | 251 } |
| 253 | 252 |
| 254 return _packages[package].map((asset) => asset.id); | 253 return _packages[package].map((asset) => asset.id); |
| 255 } | 254 } |
| 256 | 255 |
| 257 Future<Asset> getAsset(AssetId id) { | 256 Future<Asset> getAsset(AssetId id) { |
| 258 var future; | 257 var future; |
| 259 if (_pauseCompleter != null) { | 258 if (_pauseCompleter != null) { |
| 260 future = _pauseCompleter.future; | 259 future = _pauseCompleter.future; |
| 261 } else { | 260 } else { |
| 262 future = new Future.value(); | 261 future = new Future.value(); |
| 263 } | 262 } |
| 264 | 263 |
| 265 return future.then((_) { | 264 return future.then((_) { |
| 266 var package = _packages[id.package]; | 265 var package = _packages[id.package]; |
| 267 if (package == null) throw new AssetNotFoundException(id); | 266 if (package == null) throw new AssetNotFoundException(id); |
| 268 | 267 |
| 269 return package.firstWhere((asset) => asset._id == id, | 268 return package.firstWhere((asset) => asset.id == id, |
| 270 orElse: () => throw new AssetNotFoundException(id)); | 269 orElse: () => throw new AssetNotFoundException(id)); |
| 271 }); | 270 }); |
| 272 } | 271 } |
| 273 } | 272 } |
| 274 | 273 |
| 275 /// A [Transformer] that takes assets ending with one extension and generates | 274 /// A [Transformer] that takes assets ending with one extension and generates |
| 276 /// assets with a given extension. | 275 /// assets with a given extension. |
| 277 /// | 276 /// |
| 278 /// Appends the output extension to the contents of the input file. | 277 /// Appends the output extension to the contents of the input file. |
| 279 class RewriteTransformer extends Transformer { | 278 class RewriteTransformer extends Transformer { |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 311 /// Lets you test the asynchronous behavior of transformers. | 310 /// Lets you test the asynchronous behavior of transformers. |
| 312 void wait() { | 311 void wait() { |
| 313 _wait = new Completer(); | 312 _wait = new Completer(); |
| 314 } | 313 } |
| 315 | 314 |
| 316 void complete() { | 315 void complete() { |
| 317 _wait.complete(); | 316 _wait.complete(); |
| 318 _wait = null; | 317 _wait = null; |
| 319 } | 318 } |
| 320 | 319 |
| 321 Future<bool> isPrimary(AssetId asset) { | 320 Future<bool> isPrimary(Asset asset) { |
| 322 return new Future.value(asset.extension == ".$from"); | 321 return new Future.value(asset.id.extension == ".$from"); |
| 323 } | 322 } |
| 324 | 323 |
| 325 Future apply(Transform transform) { | 324 Future apply(Transform transform) { |
| 326 numRuns++; | 325 numRuns++; |
| 327 if (!_started.isCompleted) _started.complete(); | 326 if (!_started.isCompleted) _started.complete(); |
| 328 _runningTransforms++; | 327 _runningTransforms++; |
| 329 return transform.primaryInput.then((input) { | 328 return transform.primaryInput.then((input) { |
| 330 for (var extension in to.split(" ")) { | 329 for (var extension in to.split(" ")) { |
| 331 var id = transform.primaryId.changeExtension(".$extension"); | 330 var id = transform.primaryId.changeExtension(".$extension"); |
| 332 var content = input.readAsString() + ".$extension"; | 331 var content = input.readAsString() + ".$extension"; |
| 333 transform.addOutput(id, new MockAsset(id, content)); | 332 transform.addOutput(new MockAsset(id, content)); |
| 334 | |
| 335 } | 333 } |
| 336 | 334 |
| 337 if (_wait != null) return _wait.future; | 335 if (_wait != null) return _wait.future; |
| 338 }).whenComplete(() { | 336 }).whenComplete(() { |
| 339 _runningTransforms--; | 337 _runningTransforms--; |
| 340 }); | 338 }); |
| 341 } | 339 } |
| 342 | 340 |
| 343 String toString() => "$from->$to"; | 341 String toString() => "$from->$to"; |
| 344 } | 342 } |
| 345 | 343 |
| 346 /// A [Transformer] that takes an input asset that contains a comma-separated | 344 /// A [Transformer] that takes an input asset that contains a comma-separated |
| 347 /// list of paths and outputs a file for each path. | 345 /// list of paths and outputs a file for each path. |
| 348 class OneToManyTransformer extends Transformer { | 346 class OneToManyTransformer extends Transformer { |
| 349 final String extension; | 347 final String extension; |
| 350 | 348 |
| 351 /// The number of times the transformer has been applied. | 349 /// The number of times the transformer has been applied. |
| 352 int numRuns = 0; | 350 int numRuns = 0; |
| 353 | 351 |
| 354 /// Creates a transformer that consumes assets with [extension]. | 352 /// Creates a transformer that consumes assets with [extension]. |
| 355 /// | 353 /// |
| 356 /// That file contains a comma-separated list of paths and it will output | 354 /// That file contains a comma-separated list of paths and it will output |
| 357 /// files at each of those paths. | 355 /// files at each of those paths. |
| 358 OneToManyTransformer(this.extension); | 356 OneToManyTransformer(this.extension); |
| 359 | 357 |
| 360 Future<bool> isPrimary(AssetId asset) { | 358 Future<bool> isPrimary(Asset asset) { |
| 361 return new Future.value(asset.extension == ".$extension"); | 359 return new Future.value(asset.id.extension == ".$extension"); |
| 362 } | 360 } |
| 363 | 361 |
| 364 Future apply(Transform transform) { | 362 Future apply(Transform transform) { |
| 365 numRuns++; | 363 numRuns++; |
| 366 return transform.primaryInput.then((input) { | 364 return transform.primaryInput.then((input) { |
| 367 for (var line in input.readAsString().split(",")) { | 365 for (var line in input.readAsString().split(",")) { |
| 368 var id = new AssetId(transform.primaryId.package, line); | 366 var id = new AssetId(transform.primaryId.package, line); |
| 369 transform.addOutput(id, new MockAsset(id, "spread $extension")); | 367 transform.addOutput(new MockAsset(id, "spread $extension")); |
| 370 } | 368 } |
| 371 }); | 369 }); |
| 372 } | 370 } |
| 373 | 371 |
| 374 String toString() => "1->many $extension"; | 372 String toString() => "1->many $extension"; |
| 375 } | 373 } |
| 376 | 374 |
| 377 /// A transformer that uses the contents of a file to define the other inputs. | 375 /// A transformer that uses the contents of a file to define the other inputs. |
| 378 /// | 376 /// |
| 379 /// Outputs a file with the same name as the primary but with an "out" | 377 /// Outputs a file with the same name as the primary but with an "out" |
| 380 /// extension containing the concatenated contents of all non-primary inputs. | 378 /// extension containing the concatenated contents of all non-primary inputs. |
| 381 class ManyToOneTransformer extends Transformer { | 379 class ManyToOneTransformer extends Transformer { |
| 382 final String extension; | 380 final String extension; |
| 383 | 381 |
| 384 /// The number of times the transformer has been applied. | 382 /// The number of times the transformer has been applied. |
| 385 int numRuns = 0; | 383 int numRuns = 0; |
| 386 | 384 |
| 387 /// Creates a transformer that consumes assets with [extension]. | 385 /// Creates a transformer that consumes assets with [extension]. |
| 388 /// | 386 /// |
| 389 /// That file contains a comma-separated list of paths and it will input | 387 /// That file contains a comma-separated list of paths and it will input |
| 390 /// files at each of those paths. | 388 /// files at each of those paths. |
| 391 ManyToOneTransformer(this.extension); | 389 ManyToOneTransformer(this.extension); |
| 392 | 390 |
| 393 Future<bool> isPrimary(AssetId asset) { | 391 Future<bool> isPrimary(Asset asset) { |
| 394 return new Future.value(asset.extension == ".$extension"); | 392 return new Future.value(asset.id.extension == ".$extension"); |
| 395 } | 393 } |
| 396 | 394 |
| 397 Future apply(Transform transform) { | 395 Future apply(Transform transform) { |
| 398 numRuns++; | 396 numRuns++; |
| 399 return transform.primaryInput.then((primary) { | 397 return transform.primaryInput.then((primary) { |
| 400 // Get all of the included inputs. | 398 // Get all of the included inputs. |
| 401 var inputs = primary.readAsString().split(",").map((path) { | 399 var inputs = primary.readAsString().split(",").map((path) { |
| 402 var id = new AssetId(transform.primaryId.package, path); | 400 var id = new AssetId(transform.primaryId.package, path); |
| 403 return transform.getInput(id); | 401 return transform.getInput(id); |
| 404 }); | 402 }); |
| 405 | 403 |
| 406 // Concatenate them to one output. | 404 // Concatenate them to one output. |
| 407 return Future.wait(inputs).then((inputs) { | 405 return Future.wait(inputs).then((inputs) { |
| 408 var id = transform.primaryId.changeExtension(".out"); | 406 var id = transform.primaryId.changeExtension(".out"); |
| 409 var contents = inputs.map((input) => input.readAsString()).join(); | 407 var contents = inputs.map((input) => input.readAsString()).join(); |
| 410 transform.addOutput(id, new MockAsset(id, contents)); | 408 transform.addOutput(new MockAsset(id, contents)); |
| 411 }); | 409 }); |
| 412 }); | 410 }); |
| 413 } | 411 } |
| 414 | 412 |
| 415 String toString() => "many->1 $extension"; | 413 String toString() => "many->1 $extension"; |
| 416 } | 414 } |
| 417 | 415 |
| 418 /// A transformer that throws an exception when run, after generating the | 416 /// A transformer that throws an exception when run, after generating the |
| 419 /// given outputs. | 417 /// given outputs. |
| 420 class BadTransformer extends Transformer { | 418 class BadTransformer extends Transformer { |
| 421 /// The error it throws. | 419 /// The error it throws. |
| 422 static const ERROR = "I am a bad transformer!"; | 420 static const ERROR = "I am a bad transformer!"; |
| 423 | 421 |
| 424 /// The list of asset names that it should output. | 422 /// The list of asset names that it should output. |
| 425 final List<String> outputs; | 423 final List<String> outputs; |
| 426 | 424 |
| 427 BadTransformer(this.outputs); | 425 BadTransformer(this.outputs); |
| 428 | 426 |
| 429 Future<bool> isPrimary(AssetId asset) => new Future.value(true); | 427 Future<bool> isPrimary(Asset asset) => new Future.value(true); |
| 430 Future apply(Transform transform) { | 428 Future apply(Transform transform) { |
| 431 return new Future(() { | 429 return new Future(() { |
| 432 // Create the outputs first. | 430 // Create the outputs first. |
| 433 for (var output in outputs) { | 431 for (var output in outputs) { |
| 434 var id = new AssetId.parse(output); | 432 var id = new AssetId.parse(output); |
| 435 transform.addOutput(id, new MockAsset(id, output)); | 433 transform.addOutput(new MockAsset(id, output)); |
| 436 } | 434 } |
| 437 | 435 |
| 438 // Then fail. | 436 // Then fail. |
| 439 throw ERROR; | 437 throw ERROR; |
| 440 }); | 438 }); |
| 441 } | 439 } |
| 442 } | 440 } |
| 443 | 441 |
| 444 /// An implementation of [Asset] that never hits the file system. | 442 /// An implementation of [Asset] that never hits the file system. |
| 445 class MockAsset implements Asset { | 443 class MockAsset implements Asset { |
| 446 final AssetId _id; | 444 final AssetId id; |
| 447 String _contents; | 445 String _contents; |
| 448 | 446 |
| 449 MockAsset(this._id, this._contents); | 447 MockAsset(this.id, this._contents); |
| 450 | 448 |
| 451 String readAsString() => _contents; | 449 String readAsString() => _contents; |
| 452 Stream<List<int>> read() => throw new UnimplementedError(); | 450 Stream<List<int>> read() => throw new UnimplementedError(); |
| 453 | 451 |
| 454 serialize() => throw new UnimplementedError(); | 452 serialize() => throw new UnimplementedError(); |
| 455 | 453 |
| 456 String toString() => "MockAsset $_id $_contents"; | 454 String toString() => "MockAsset $id $_contents"; |
| 457 } | 455 } |
| OLD | NEW |