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