OLD | NEW |
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 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 | 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 /// Utilities for creating unit tests of Barback transformers. | 5 /// Utilities for creating unit tests of Barback transformers. |
6 library code_transformers.src.test_harness; | 6 library code_transformers.src.test_harness; |
7 | 7 |
8 import 'dart:async'; | 8 import 'dart:async'; |
9 | 9 |
10 import 'package:barback/barback.dart'; | 10 import 'package:barback/barback.dart'; |
11 import 'package:stack_trace/stack_trace.dart'; | 11 import 'package:stack_trace/stack_trace.dart'; |
12 import 'package:unittest/unittest.dart'; | 12 import 'package:unittest/unittest.dart'; |
13 | 13 |
14 String idToString(AssetId id) => '${id.package}|${id.path}'; | 14 String idToString(AssetId id) => '${id.package}|${id.path}'; |
15 AssetId idFromString(String s) { | 15 AssetId idFromString(String s) { |
16 int index = s.indexOf('|'); | 16 int index = s.indexOf('|'); |
17 return new AssetId(s.substring(0, index), s.substring(index + 1)); | 17 return new AssetId(s.substring(0, index), s.substring(index + 1)); |
18 } | 18 } |
19 | 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 | 20 /// A helper package provider that has files stored in memory, also wraps |
25 /// [Barback] to simply our tests. | 21 /// [Barback] to simply our tests. |
26 class TestHelper implements PackageProvider { | 22 class TestHelper implements PackageProvider { |
27 | 23 |
28 /// Maps from an asset string identifier of the form 'package|path' to the | 24 /// Maps from an asset string identifier of the form 'package|path' to the |
29 /// file contents. | 25 /// file contents. |
30 final Map<String, String> files; | 26 final Map<String, String> files; |
31 final Iterable<String> packages; | 27 final Iterable<String> packages; |
32 final List<String> messages; | 28 final List<String> messages; |
33 int messagesSeen = 0; | 29 int messagesSeen = 0; |
34 bool errorSeen = false; | 30 bool errorSeen = false; |
35 | 31 |
36 Barback barback; | 32 Barback barback; |
37 var errorSubscription; | 33 var errorSubscription; |
38 var resultSubscription; | 34 var resultSubscription; |
39 var logSubscription; | 35 var logSubscription; |
40 | 36 |
| 37 final StringFormatter formatter; |
| 38 |
41 Future<Asset> getAsset(AssetId id) => | 39 Future<Asset> getAsset(AssetId id) => |
42 new Future.value(new Asset.fromString(id, files[idToString(id)])); | 40 new Future.value(new Asset.fromString(id, files[idToString(id)])); |
43 | 41 |
44 TestHelper(List<List<Transformer>> transformers, Map<String, String> files, | 42 TestHelper(List<List<Transformer>> transformers, Map<String, String> files, |
45 this.messages) | 43 this.messages, {this.formatter: StringFormatter.noTrailingWhitespace}) |
46 : files = files, | 44 : files = files, |
47 packages = files.keys.map((s) => idFromString(s).package) { | 45 packages = files.keys.map((s) => idFromString(s).package) { |
48 barback = new Barback(this); | 46 barback = new Barback(this); |
49 for (var p in packages) { | 47 for (var p in packages) { |
50 barback.updateTransformers(p, transformers); | 48 barback.updateTransformers(p, transformers); |
51 } | 49 } |
52 | 50 |
53 errorSubscription = barback.errors.listen((e) { | 51 errorSubscription = barback.errors.listen((e) { |
54 var trace = null; | 52 var trace = null; |
55 if (e is Error) trace = e.stackTrace; | 53 if (e is Error) trace = e.stackTrace; |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
93 barback.updateSources(paths.map(idFromString)); | 91 barback.updateSources(paths.map(idFromString)); |
94 } | 92 } |
95 | 93 |
96 Future<String> operator [](String assetString){ | 94 Future<String> operator [](String assetString){ |
97 return barback.getAssetById(idFromString(assetString)) | 95 return barback.getAssetById(idFromString(assetString)) |
98 .then((asset) => asset.readAsString()); | 96 .then((asset) => asset.readAsString()); |
99 } | 97 } |
100 | 98 |
101 Future check(String assetIdString, String content) { | 99 Future check(String assetIdString, String content) { |
102 return this[assetIdString].then((value) { | 100 return this[assetIdString].then((value) { |
103 value = _removeTrailingWhitespace(value); | 101 value = formatter.formatString(value); |
104 content = _removeTrailingWhitespace(content); | 102 content = formatter.formatString(content); |
105 expect(value, content, reason: 'Final output of $assetIdString differs.'); | 103 expect(value, content, reason: 'Final output of $assetIdString differs.'); |
106 }); | 104 }); |
107 } | 105 } |
108 | 106 |
| 107 |
| 108 |
109 Future checkAll(Map<String, String> files) { | 109 Future checkAll(Map<String, String> files) { |
110 return barback.results.first.then((_) { | 110 return barback.results.first.then((_) { |
111 if (files == null) return null; | 111 if (files == null) return null; |
112 var futures = []; | 112 var futures = []; |
113 files.forEach((k, v) { | 113 files.forEach((k, v) { |
114 futures.add(check(k, v)); | 114 futures.add(check(k, v)); |
115 }); | 115 }); |
116 return Future.wait(futures); | 116 return Future.wait(futures); |
117 }).then((_) { | 117 }).then((_) { |
118 // We only check messages when an expectation is provided. | 118 // We only check messages when an expectation is provided. |
119 if (messages == null) return; | 119 if (messages == null) return; |
120 expect(messagesSeen, messages.length, | 120 expect(messagesSeen, messages.length, |
121 reason: 'less messages than expected'); | 121 reason: 'less messages than expected'); |
122 }); | 122 }); |
123 } | 123 } |
124 } | 124 } |
| 125 |
| 126 class StringFormatter { |
| 127 // Formatting options |
| 128 final bool stripLeadingWhitespace; |
| 129 final bool stripTrailingWhitespace; |
| 130 final bool stripNewlines; |
| 131 |
| 132 // Static variations for convenience |
| 133 static const noLeadingWhitespace = |
| 134 const StringFormatter(stripLeadingWhitespace: true); |
| 135 |
| 136 static const noTrailingWhitespace = |
| 137 const StringFormatter(stripTrailingWhitespace: true); |
| 138 |
| 139 static const noSurroundingWhitespace = const StringFormatter( |
| 140 stripLeadingWhitespace: true, stripTrailingWhitespace: true); |
| 141 |
| 142 static const noNewlines = const StringFormatter(stripNewlines: true); |
| 143 |
| 144 static const noNewlinesOrSurroundingWhitespace = const StringFormatter( |
| 145 stripLeadingWhitespace: true, |
| 146 stripTrailingWhitespace: true, |
| 147 stripNewlines: true); |
| 148 |
| 149 const StringFormatter({ |
| 150 this.stripLeadingWhitespace: false, |
| 151 this.stripTrailingWhitespace: false, |
| 152 this.stripNewlines: false}); |
| 153 |
| 154 String formatString(String str) { |
| 155 if (stripLeadingWhitespace) str = _removeLeadingWhitespace(str); |
| 156 if (stripTrailingWhitespace) str = _removeTrailingWhitespace(str); |
| 157 if (stripNewlines) str = _removeNewlines(str); |
| 158 return str; |
| 159 } |
| 160 } |
| 161 |
| 162 String _removeTrailingWhitespace(String str) => |
| 163 str.splitMapJoin('\n', |
| 164 onNonMatch: (s) => s.replaceAll(new RegExp(r'\s+$'), '')); |
| 165 |
| 166 String _removeLeadingWhitespace(String str) => |
| 167 str.splitMapJoin('\n', |
| 168 onNonMatch: (s) => s.replaceAll(new RegExp(r'^\s+'), '')); |
| 169 |
| 170 String _removeNewlines(String str) => str.replaceAll('\n', ''); |
OLD | NEW |