| 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 /// A helper package provider that has files stored in memory, also wraps | |
| 21 /// [Barback] to simply our tests. | |
| 22 class TestHelper implements PackageProvider { | |
| 23 | |
| 24 /// Maps from an asset string identifier of the form 'package|path' to the | |
| 25 /// file contents. | |
| 26 final Map<String, String> files; | |
| 27 final Iterable<String> packages; | |
| 28 final List<String> messages; | |
| 29 int messagesSeen = 0; | |
| 30 bool errorSeen = false; | |
| 31 | |
| 32 Barback barback; | |
| 33 var errorSubscription; | |
| 34 var resultSubscription; | |
| 35 var logSubscription; | |
| 36 | |
| 37 final StringFormatter formatter; | |
| 38 | |
| 39 Future<Asset> getAsset(AssetId id) => | |
| 40 new Future.value(new Asset.fromString(id, files[idToString(id)])); | |
| 41 | |
| 42 TestHelper(List<List<Transformer>> transformers, Map<String, String> files, | |
| 43 this.messages, {this.formatter: StringFormatter.noTrailingWhitespace}) | |
| 44 : files = files, | |
| 45 packages = files.keys.map((s) => idFromString(s).package) { | |
| 46 barback = new Barback(this); | |
| 47 for (var p in packages) { | |
| 48 barback.updateTransformers(p, transformers); | |
| 49 } | |
| 50 | |
| 51 errorSubscription = barback.errors.listen((e) { | |
| 52 var trace = null; | |
| 53 if (e is Error) trace = e.stackTrace; | |
| 54 if (trace != null) { | |
| 55 print(Trace.format(trace)); | |
| 56 } | |
| 57 fail('error running barback: $e'); | |
| 58 }); | |
| 59 | |
| 60 resultSubscription = barback.results.listen((result) { | |
| 61 expect(result.succeeded, !errorSeen, reason: "${result.errors}"); | |
| 62 }); | |
| 63 | |
| 64 logSubscription = barback.log.listen((entry) { | |
| 65 // Ignore info and fine messages. | |
| 66 if (entry.level == LogLevel.INFO || entry.level == LogLevel.FINE) return; | |
| 67 if (entry.level == LogLevel.ERROR) errorSeen = true; | |
| 68 // We only check messages when an expectation is provided. | |
| 69 if (messages == null) return; | |
| 70 | |
| 71 var msg = '${entry.level.name.toLowerCase()}: ${entry.message}'; | |
| 72 var span = entry.span; | |
| 73 var spanInfo = span == null | |
| 74 ? '' | |
| 75 : ' (${span.sourceUrl} ${span.start.line} ${span.start.column})'; | |
| 76 expect(messagesSeen, lessThan(messages.length), | |
| 77 reason: 'more messages than expected.\nMessage seen: $msg$spanInfo'); | |
| 78 expect('$msg$spanInfo', messages[messagesSeen++]); | |
| 79 }); | |
| 80 } | |
| 81 | |
| 82 void tearDown() { | |
| 83 errorSubscription.cancel(); | |
| 84 resultSubscription.cancel(); | |
| 85 logSubscription.cancel(); | |
| 86 } | |
| 87 | |
| 88 /// Tells barback which files have changed, and thus anything that depends on | |
| 89 /// it on should be computed. By default mark all the input files. | |
| 90 void run([Iterable<String> paths]) { | |
| 91 if (paths == null) paths = files.keys; | |
| 92 barback.updateSources(paths.map(idFromString)); | |
| 93 } | |
| 94 | |
| 95 Future<String> operator [](String assetString) { | |
| 96 return barback | |
| 97 .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 = formatter.formatString(value); | |
| 104 content = formatter.formatString(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( | |
| 121 messagesSeen, messages.length, reason: 'less messages than expected'); | |
| 122 }); | |
| 123 } | |
| 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({this.stripLeadingWhitespace: false, | |
| 150 this.stripTrailingWhitespace: false, this.stripNewlines: false}); | |
| 151 | |
| 152 String formatString(String str) { | |
| 153 if (stripLeadingWhitespace) str = _removeLeadingWhitespace(str); | |
| 154 if (stripTrailingWhitespace) str = _removeTrailingWhitespace(str); | |
| 155 if (stripNewlines) str = _removeNewlines(str); | |
| 156 return str; | |
| 157 } | |
| 158 } | |
| 159 | |
| 160 String _removeTrailingWhitespace(String str) => str.splitMapJoin('\n', | |
| 161 onNonMatch: (s) => s.replaceAll(new RegExp(r'\s+$'), '')); | |
| 162 | |
| 163 String _removeLeadingWhitespace(String str) => str.splitMapJoin('\n', | |
| 164 onNonMatch: (s) => s.replaceAll(new RegExp(r'^\s+'), '')); | |
| 165 | |
| 166 String _removeNewlines(String str) => str.replaceAll('\n', ''); | |
| OLD | NEW |