OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file |
| 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. |
| 4 |
| 5 /// Utilities for creating unit tests of Barback transformers. |
| 6 library code_transformers.src.test_harness; |
| 7 |
| 8 import 'dart:async'; |
| 9 |
| 10 import 'package:barback/barback.dart'; |
| 11 import 'package:stack_trace/stack_trace.dart'; |
| 12 import 'package:unittest/unittest.dart'; |
| 13 |
| 14 String idToString(AssetId id) => '${id.package}|${id.path}'; |
| 15 AssetId idFromString(String s) { |
| 16 int index = s.indexOf('|'); |
| 17 return new AssetId(s.substring(0, index), s.substring(index + 1)); |
| 18 } |
| 19 |
| 20 String _removeTrailingWhitespace(String str) => |
| 21 str.splitMapJoin('\n', |
| 22 onNonMatch: (s) => s.replaceAll(new RegExp(r'\s+$'), '')); |
| 23 |
| 24 /// A helper package provider that has files stored in memory, also wraps |
| 25 /// [Barback] to simply our tests. |
| 26 class TestHelper implements PackageProvider { |
| 27 |
| 28 /// Maps from an asset string identifier of the form 'package|path' to the |
| 29 /// file contents. |
| 30 final Map<String, String> files; |
| 31 final Iterable<String> packages; |
| 32 final List<String> messages; |
| 33 int messagesSeen = 0; |
| 34 bool errorSeen = false; |
| 35 |
| 36 Barback barback; |
| 37 var errorSubscription; |
| 38 var resultSubscription; |
| 39 var logSubscription; |
| 40 |
| 41 Future<Asset> getAsset(AssetId id) => |
| 42 new Future.value(new Asset.fromString(id, files[idToString(id)])); |
| 43 |
| 44 TestHelper(List<List<Transformer>> transformers, Map<String, String> files, |
| 45 this.messages) |
| 46 : files = files, |
| 47 packages = files.keys.map((s) => idFromString(s).package) { |
| 48 barback = new Barback(this); |
| 49 for (var p in packages) { |
| 50 barback.updateTransformers(p, transformers); |
| 51 } |
| 52 |
| 53 errorSubscription = barback.errors.listen((e) { |
| 54 var trace = null; |
| 55 if (e is Error) trace = e.stackTrace; |
| 56 if (trace != null) { |
| 57 print(Trace.format(trace)); |
| 58 } |
| 59 fail('error running barback: $e'); |
| 60 }); |
| 61 |
| 62 resultSubscription = barback.results.listen((result) { |
| 63 expect(result.succeeded, !errorSeen, reason: "${result.errors}"); |
| 64 }); |
| 65 |
| 66 logSubscription = barback.log.listen((entry) { |
| 67 // Ignore info and fine messages. |
| 68 if (entry.level == LogLevel.INFO || entry.level == LogLevel.FINE) return; |
| 69 if (entry.level == LogLevel.ERROR) errorSeen = true; |
| 70 // We only check messages when an expectation is provided. |
| 71 if (messages == null) return; |
| 72 |
| 73 var msg = '${entry.level.name.toLowerCase()}: ${entry.message}'; |
| 74 var span = entry.span; |
| 75 var spanInfo = span == null ? '' : |
| 76 ' (${span.sourceUrl} ${span.start.line} ${span.start.column})'; |
| 77 expect(messagesSeen, lessThan(messages.length), |
| 78 reason: 'more messages than expected.\nMessage seen: $msg$spanInfo'); |
| 79 expect('$msg$spanInfo', messages[messagesSeen++]); |
| 80 }); |
| 81 } |
| 82 |
| 83 void tearDown() { |
| 84 errorSubscription.cancel(); |
| 85 resultSubscription.cancel(); |
| 86 logSubscription.cancel(); |
| 87 } |
| 88 |
| 89 /// Tells barback which files have changed, and thus anything that depends on |
| 90 /// it on should be computed. By default mark all the input files. |
| 91 void run([Iterable<String> paths]) { |
| 92 if (paths == null) paths = files.keys; |
| 93 barback.updateSources(paths.map(idFromString)); |
| 94 } |
| 95 |
| 96 Future<String> operator [](String assetString){ |
| 97 return barback.getAssetById(idFromString(assetString)) |
| 98 .then((asset) => asset.readAsString()); |
| 99 } |
| 100 |
| 101 Future check(String assetIdString, String content) { |
| 102 return this[assetIdString].then((value) { |
| 103 value = _removeTrailingWhitespace(value); |
| 104 content = _removeTrailingWhitespace(content); |
| 105 expect(value, content, reason: 'Final output of $assetIdString differs.'); |
| 106 }); |
| 107 } |
| 108 |
| 109 Future checkAll(Map<String, String> files) { |
| 110 return barback.results.first.then((_) { |
| 111 if (files == null) return null; |
| 112 var futures = []; |
| 113 files.forEach((k, v) { |
| 114 futures.add(check(k, v)); |
| 115 }); |
| 116 return Future.wait(futures); |
| 117 }).then((_) { |
| 118 // We only check messages when an expectation is provided. |
| 119 if (messages == null) return; |
| 120 expect(messagesSeen, messages.length, |
| 121 reason: 'less messages than expected'); |
| 122 }); |
| 123 } |
| 124 } |
OLD | NEW |