OLD | NEW |
| (Empty) |
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS d.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 library pub_tests; | |
6 | |
7 import 'package:scheduled_test/scheduled_test.dart'; | |
8 | |
9 import '../descriptor.dart' as d; | |
10 import '../test_pub.dart'; | |
11 import '../serve/utils.dart'; | |
12 | |
13 const MODE_TRANSFORMER = """ | |
14 import 'dart:async'; | |
15 | |
16 import 'package:barback/barback.dart'; | |
17 | |
18 class ModeTransformer extends Transformer { | |
19 final BarbackSettings _settings; | |
20 | |
21 ModeTransformer.asPlugin(this._settings); | |
22 | |
23 String get allowedExtensions => '.dart'; | |
24 | |
25 void apply(Transform transform) { | |
26 return transform.primaryInput.readAsString().then((contents) { | |
27 transform.addOutput(new Asset.fromString( | |
28 transform.primaryInput.id, | |
29 contents.replaceAll("MODE", _settings.mode.name))); | |
30 }); | |
31 } | |
32 } | |
33 """; | |
34 | |
35 const HAS_INPUT_TRANSFORMER = """ | |
36 import 'dart:async'; | |
37 | |
38 import 'package:barback/barback.dart'; | |
39 | |
40 class HasInputTransformer extends Transformer { | |
41 HasInputTransformer.asPlugin(); | |
42 | |
43 bool get allowedExtensions => '.txt'; | |
44 | |
45 Future apply(Transform transform) { | |
46 return Future.wait([ | |
47 transform.hasInput(new AssetId("foo", "lib/foo.dart")), | |
48 transform.hasInput(new AssetId("foo", "lib/does/not/exist.dart")) | |
49 ]).then((results) { | |
50 transform.addOutput(new Asset.fromString( | |
51 transform.primaryInput.id, | |
52 "lib/foo.dart: \${results.first}, " | |
53 "lib/does/not/exist.dart: \${results.last}")); | |
54 }); | |
55 } | |
56 } | |
57 """; | |
58 | |
59 main() { | |
60 initConfig(); | |
61 | |
62 integration("caches a transformed dependency", () { | |
63 servePackages((builder) { | |
64 builder.serveRepoPackage('barback'); | |
65 | |
66 builder.serve("foo", "1.2.3", | |
67 deps: {'barback': 'any'}, | |
68 pubspec: {'transformers': ['foo']}, | |
69 contents: [ | |
70 d.dir("lib", [ | |
71 d.file("transformer.dart", replaceTransformer("Hello", "Goodbye")), | |
72 d.file("foo.dart", "final message = 'Hello!';") | |
73 ]) | |
74 ]); | |
75 }); | |
76 | |
77 d.appDir({"foo": "1.2.3"}).create(); | |
78 | |
79 pubGet(output: contains("Precompiled foo.")); | |
80 | |
81 d.dir(appPath, [ | |
82 d.dir(".pub/deps/debug/foo/lib", [ | |
83 d.file("foo.dart", "final message = 'Goodbye!';") | |
84 ]) | |
85 ]).validate(); | |
86 }); | |
87 | |
88 integration("caches a dependency transformed by its dependency", () { | |
89 servePackages((builder) { | |
90 builder.serveRepoPackage('barback'); | |
91 | |
92 builder.serve("foo", "1.2.3", | |
93 deps: {'bar': '1.2.3'}, | |
94 pubspec: {'transformers': ['bar']}, | |
95 contents: [ | |
96 d.dir("lib", [ | |
97 d.file("foo.dart", "final message = 'Hello!';") | |
98 ]) | |
99 ]); | |
100 | |
101 builder.serve("bar", "1.2.3", | |
102 deps: {'barback': 'any'}, | |
103 contents: [ | |
104 d.dir("lib", [ | |
105 d.file("transformer.dart", replaceTransformer("Hello", "Goodbye")) | |
106 ]) | |
107 ]); | |
108 }); | |
109 | |
110 d.appDir({"foo": "1.2.3"}).create(); | |
111 | |
112 pubGet(output: contains("Precompiled foo.")); | |
113 | |
114 d.dir(appPath, [ | |
115 d.dir(".pub/deps/debug/foo/lib", [ | |
116 d.file("foo.dart", "final message = 'Goodbye!';") | |
117 ]) | |
118 ]).validate(); | |
119 }); | |
120 | |
121 integration("doesn't cache an untransformed dependency", () { | |
122 servePackages((builder) { | |
123 builder.serveRepoPackage('barback'); | |
124 | |
125 builder.serve("foo", "1.2.3", | |
126 contents: [ | |
127 d.dir("lib", [ | |
128 d.file("foo.dart", "final message = 'Hello!';") | |
129 ]) | |
130 ]); | |
131 }); | |
132 | |
133 d.appDir({"foo": "1.2.3"}).create(); | |
134 | |
135 pubGet(output: isNot(contains("Precompiled foo."))); | |
136 | |
137 d.dir(appPath, [d.nothing(".pub/deps")]).validate(); | |
138 }); | |
139 | |
140 integration("recaches when the dependency is updated", () { | |
141 servePackages((builder) { | |
142 builder.serveRepoPackage('barback'); | |
143 | |
144 builder.serve("foo", "1.2.3", | |
145 deps: {'barback': 'any'}, | |
146 pubspec: {'transformers': ['foo']}, | |
147 contents: [ | |
148 d.dir("lib", [ | |
149 d.file("transformer.dart", replaceTransformer("Hello", "Goodbye")), | |
150 d.file("foo.dart", "final message = 'Hello!';") | |
151 ]) | |
152 ]); | |
153 | |
154 builder.serve("foo", "1.2.4", | |
155 deps: {'barback': 'any'}, | |
156 pubspec: {'transformers': ['foo']}, | |
157 contents: [ | |
158 d.dir("lib", [ | |
159 d.file("transformer.dart", replaceTransformer("Hello", "See ya")), | |
160 d.file("foo.dart", "final message = 'Hello!';") | |
161 ]) | |
162 ]); | |
163 }); | |
164 | |
165 d.appDir({"foo": "1.2.3"}).create(); | |
166 | |
167 pubGet(output: contains("Precompiled foo.")); | |
168 | |
169 d.dir(appPath, [ | |
170 d.dir(".pub/deps/debug/foo/lib", [ | |
171 d.file("foo.dart", "final message = 'Goodbye!';") | |
172 ]) | |
173 ]).validate(); | |
174 | |
175 // Upgrade to the new version of foo. | |
176 d.appDir({"foo": "1.2.4"}).create(); | |
177 | |
178 pubGet(output: contains("Precompiled foo.")); | |
179 | |
180 d.dir(appPath, [ | |
181 d.dir(".pub/deps/debug/foo/lib", [ | |
182 d.file("foo.dart", "final message = 'See ya!';") | |
183 ]) | |
184 ]).validate(); | |
185 }); | |
186 | |
187 integration("recaches when a transitive dependency is updated", () { | |
188 servePackages((builder) { | |
189 builder.serveRepoPackage('barback'); | |
190 | |
191 builder.serve("foo", "1.2.3", | |
192 deps: { | |
193 'barback': 'any', | |
194 'bar': 'any' | |
195 }, | |
196 pubspec: {'transformers': ['foo']}, | |
197 contents: [ | |
198 d.dir("lib", [ | |
199 d.file("transformer.dart", replaceTransformer("Hello", "Goodbye")), | |
200 d.file("foo.dart", "final message = 'Hello!';") | |
201 ]) | |
202 ]); | |
203 | |
204 builder.serve("bar", "5.6.7"); | |
205 }); | |
206 | |
207 d.appDir({"foo": "1.2.3"}).create(); | |
208 pubGet(output: contains("Precompiled foo.")); | |
209 | |
210 servePackages((builder) => builder.serve("bar", "6.0.0")); | |
211 pubUpgrade(output: contains("Precompiled foo.")); | |
212 }); | |
213 | |
214 integration("doesn't recache when an unrelated dependency is updated", () { | |
215 servePackages((builder) { | |
216 builder.serveRepoPackage('barback'); | |
217 | |
218 builder.serve("foo", "1.2.3", | |
219 deps: {'barback': 'any'}, | |
220 pubspec: {'transformers': ['foo']}, | |
221 contents: [ | |
222 d.dir("lib", [ | |
223 d.file("transformer.dart", replaceTransformer("Hello", "Goodbye")), | |
224 d.file("foo.dart", "final message = 'Hello!';") | |
225 ]) | |
226 ]); | |
227 | |
228 builder.serve("bar", "5.6.7"); | |
229 }); | |
230 | |
231 d.appDir({"foo": "1.2.3"}).create(); | |
232 pubGet(output: contains("Precompiled foo.")); | |
233 | |
234 servePackages((builder) => builder.serve("bar", "6.0.0")); | |
235 pubUpgrade(output: isNot(contains("Precompiled foo."))); | |
236 }); | |
237 | |
238 integration("caches the dependency in debug mode", () { | |
239 servePackages((builder) { | |
240 builder.serveRepoPackage('barback'); | |
241 | |
242 builder.serve("foo", "1.2.3", | |
243 deps: {'barback': 'any'}, | |
244 pubspec: {'transformers': ['foo']}, | |
245 contents: [ | |
246 d.dir("lib", [ | |
247 d.file("transformer.dart", MODE_TRANSFORMER), | |
248 d.file("foo.dart", "final mode = 'MODE';") | |
249 ]) | |
250 ]); | |
251 }); | |
252 | |
253 d.appDir({"foo": "1.2.3"}).create(); | |
254 | |
255 pubGet(output: contains("Precompiled foo.")); | |
256 | |
257 d.dir(appPath, [ | |
258 d.dir(".pub/deps/debug/foo/lib", [ | |
259 d.file("foo.dart", "final mode = 'debug';") | |
260 ]) | |
261 ]).validate(); | |
262 }); | |
263 | |
264 integration("loads code from the cache", () { | |
265 servePackages((builder) { | |
266 builder.serveRepoPackage('barback'); | |
267 | |
268 builder.serve("foo", "1.2.3", | |
269 deps: {'barback': 'any'}, | |
270 pubspec: {'transformers': ['foo']}, | |
271 contents: [ | |
272 d.dir("lib", [ | |
273 d.file("transformer.dart", replaceTransformer("Hello", "Goodbye")), | |
274 d.file("foo.dart", "final message = 'Hello!';") | |
275 ]) | |
276 ]); | |
277 }); | |
278 | |
279 d.dir(appPath, [ | |
280 d.appPubspec({"foo": "1.2.3"}), | |
281 d.dir('bin', [ | |
282 d.file('script.dart', """ | |
283 import 'package:foo/foo.dart'; | |
284 | |
285 void main() => print(message);""") | |
286 ]) | |
287 ]).create(); | |
288 | |
289 pubGet(output: contains("Precompiled foo.")); | |
290 | |
291 d.dir(appPath, [ | |
292 d.dir(".pub/deps/debug/foo/lib", [ | |
293 d.file("foo.dart", "final message = 'Modified!';") | |
294 ]) | |
295 ]).create(); | |
296 | |
297 var pub = pubRun(args: ["bin/script"]); | |
298 pub.stdout.expect("Modified!"); | |
299 pub.shouldExit(); | |
300 }); | |
301 | |
302 integration("doesn't re-transform code loaded from the cache", () { | |
303 servePackages((builder) { | |
304 builder.serveRepoPackage('barback'); | |
305 | |
306 builder.serve("foo", "1.2.3", | |
307 deps: {'barback': 'any'}, | |
308 pubspec: {'transformers': ['foo']}, | |
309 contents: [ | |
310 d.dir("lib", [ | |
311 d.file("transformer.dart", replaceTransformer("Hello", "Goodbye")), | |
312 d.file("foo.dart", "final message = 'Hello!';") | |
313 ]) | |
314 ]); | |
315 }); | |
316 | |
317 d.dir(appPath, [ | |
318 d.appPubspec({"foo": "1.2.3"}), | |
319 d.dir('bin', [ | |
320 d.file('script.dart', """ | |
321 import 'package:foo/foo.dart'; | |
322 | |
323 void main() => print(message);""") | |
324 ]) | |
325 ]).create(); | |
326 | |
327 pubGet(output: contains("Precompiled foo.")); | |
328 | |
329 // Manually reset the cache to its original state to prove that the | |
330 // transformer won't be run again on it. | |
331 d.dir(appPath, [ | |
332 d.dir(".pub/deps/debug/foo/lib", [ | |
333 d.file("foo.dart", "final message = 'Hello!';") | |
334 ]) | |
335 ]).create(); | |
336 | |
337 var pub = pubRun(args: ["bin/script"]); | |
338 pub.stdout.expect("Hello!"); | |
339 pub.shouldExit(); | |
340 }); | |
341 | |
342 // Regression test for issue 21087. | |
343 integration("hasInput works for static packages", () { | |
344 servePackages((builder) { | |
345 builder.serveRepoPackage('barback'); | |
346 | |
347 builder.serve("foo", "1.2.3", | |
348 deps: {'barback': 'any'}, | |
349 pubspec: {'transformers': ['foo']}, | |
350 contents: [ | |
351 d.dir("lib", [ | |
352 d.file("transformer.dart", replaceTransformer("Hello", "Goodbye")), | |
353 d.file("foo.dart", "void main() => print('Hello!');") | |
354 ]) | |
355 ]); | |
356 }); | |
357 | |
358 d.dir(appPath, [ | |
359 d.pubspec({ | |
360 "name": "myapp", | |
361 "dependencies": {"foo": "1.2.3"}, | |
362 "transformers": ["myapp/src/transformer"] | |
363 }), | |
364 d.dir("lib", [d.dir("src", [ | |
365 d.file("transformer.dart", HAS_INPUT_TRANSFORMER) | |
366 ])]), | |
367 d.dir("web", [ | |
368 d.file("foo.txt", "foo") | |
369 ]) | |
370 ]).create(); | |
371 | |
372 pubGet(output: contains("Precompiled foo.")); | |
373 | |
374 pubServe(); | |
375 requestShouldSucceed("foo.txt", | |
376 "lib/foo.dart: true, lib/does/not/exist.dart: false"); | |
377 endPubServe(); | |
378 }); | |
379 | |
380 // Regression test for issue 21810. | |
381 integration("decaches when the dependency is updated to something " | |
382 "untransformed", () { | |
383 servePackages((builder) { | |
384 builder.serveRepoPackage('barback'); | |
385 | |
386 builder.serve("foo", "1.2.3", | |
387 deps: {'barback': 'any'}, | |
388 pubspec: {'transformers': ['foo']}, | |
389 contents: [ | |
390 d.dir("lib", [ | |
391 d.file("transformer.dart", replaceTransformer("Hello", "Goodbye")), | |
392 d.file("foo.dart", "final message = 'Hello!';") | |
393 ]) | |
394 ]); | |
395 | |
396 builder.serve("foo", "1.2.4", | |
397 deps: {'barback': 'any'}, | |
398 contents: [ | |
399 d.dir("lib", [ | |
400 d.file("foo.dart", "final message = 'Hello!';") | |
401 ]) | |
402 ]); | |
403 }); | |
404 | |
405 d.appDir({"foo": "1.2.3"}).create(); | |
406 | |
407 pubGet(output: contains("Precompiled foo.")); | |
408 | |
409 d.dir(appPath, [ | |
410 d.dir(".pub/deps/debug/foo/lib", [ | |
411 d.file("foo.dart", "final message = 'Goodbye!';") | |
412 ]) | |
413 ]).validate(); | |
414 | |
415 // Upgrade to the new version of foo. | |
416 d.appDir({"foo": "1.2.4"}).create(); | |
417 | |
418 pubGet(output: isNot(contains("Precompiled foo."))); | |
419 | |
420 d.dir(appPath, [ | |
421 d.nothing(".pub/deps/debug/foo") | |
422 ]).validate(); | |
423 }); | |
424 } | |
425 | |
426 String replaceTransformer(String input, String output) { | |
427 return """ | |
428 import 'dart:async'; | |
429 | |
430 import 'package:barback/barback.dart'; | |
431 | |
432 class ReplaceTransformer extends Transformer { | |
433 ReplaceTransformer.asPlugin(); | |
434 | |
435 String get allowedExtensions => '.dart'; | |
436 | |
437 Future apply(Transform transform) { | |
438 return transform.primaryInput.readAsString().then((contents) { | |
439 transform.addOutput(new Asset.fromString( | |
440 transform.primaryInput.id, | |
441 contents.replaceAll("$input", "$output"))); | |
442 }); | |
443 } | |
444 } | |
445 """; | |
446 } | |
OLD | NEW |