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 messages. | |
68 if (entry.level == LogLevel.INFO) 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(messages.length, messagesSeen, | |
121 reason: 'less messages than expected'); | |
122 }); | |
123 } | |
124 } | |
OLD | NEW |