OLD | NEW |
| (Empty) |
1 // Copyright (c) 2013, 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 import 'dart:io'; | |
6 import 'dart:uri'; | |
7 | |
8 import 'package:pathos/path.dart' as pathos; | |
9 import 'package:unittest/unittest.dart'; | |
10 | |
11 import '../lib/src/export_map.dart'; | |
12 import '../lib/src/dartdoc/utils.dart'; | |
13 | |
14 String tempDir; | |
15 | |
16 main() { | |
17 group('ExportMap', () { | |
18 setUp(createTempDir); | |
19 tearDown(deleteTempDir); | |
20 | |
21 test('with an empty library', () { | |
22 createLibrary('lib.dart'); | |
23 var map = parse(['lib.dart']); | |
24 | |
25 var expectedExports = {}; | |
26 expectedExports[libPath('lib.dart')] = []; | |
27 expect(map.exports, equals(expectedExports)); | |
28 expect(map.allExportedFiles, isEmpty); | |
29 expect(map.transitiveExports(libPath('lib.dart')), isEmpty); | |
30 expect(map.transitiveExports(libPath('nonexistent.dart')), isEmpty); | |
31 }); | |
32 | |
33 test('with one library with one export', () { | |
34 createLibrary('a.dart', 'export "b.dart";'); | |
35 createLibrary('b.dart'); | |
36 var map = parse(['a.dart']); | |
37 | |
38 expect(map.exports[libPath('a.dart')], unorderedEquals([ | |
39 new Export(libPath('a.dart'), libPath('b.dart')) | |
40 ])); | |
41 | |
42 expect(map.transitiveExports(libPath('a.dart')), unorderedEquals([ | |
43 new Export(libPath('a.dart'), libPath('b.dart')) | |
44 ])); | |
45 | |
46 expect(map.allExportedFiles, unorderedEquals([libPath('b.dart')])); | |
47 | |
48 expect(map.exports[libPath('b.dart')], isEmpty); | |
49 expect(map.transitiveExports(libPath('b.dart')), isEmpty); | |
50 }); | |
51 | |
52 test('with one library with multiple exports', () { | |
53 createLibrary('a.dart', 'export "b.dart";\nexport "c.dart";'); | |
54 createLibrary('b.dart'); | |
55 createLibrary('c.dart'); | |
56 var map = parse(['a.dart']); | |
57 | |
58 expect(map.exports[libPath('a.dart')], unorderedEquals([ | |
59 new Export(libPath('a.dart'), libPath('b.dart')), | |
60 new Export(libPath('a.dart'), libPath('c.dart')) | |
61 ])); | |
62 | |
63 expect(map.transitiveExports(libPath('a.dart')), unorderedEquals([ | |
64 new Export(libPath('a.dart'), libPath('b.dart')), | |
65 new Export(libPath('a.dart'), libPath('c.dart')) | |
66 ])); | |
67 | |
68 expect(map.allExportedFiles, unorderedEquals([ | |
69 libPath('b.dart'), libPath('c.dart') | |
70 ])); | |
71 | |
72 expect(map.exports[libPath('b.dart')], isEmpty); | |
73 expect(map.transitiveExports(libPath('b.dart')), isEmpty); | |
74 expect(map.exports[libPath('c.dart')], isEmpty); | |
75 expect(map.transitiveExports(libPath('c.dart')), isEmpty); | |
76 }); | |
77 | |
78 test('with two libraries each with one export', () { | |
79 createLibrary('a.dart', 'export "a_export.dart";'); | |
80 createLibrary('b.dart', 'export "b_export.dart";'); | |
81 createLibrary('a_export.dart'); | |
82 createLibrary('b_export.dart'); | |
83 var map = parse(['a.dart', 'b.dart']); | |
84 | |
85 expect(map.exports[libPath('a.dart')], unorderedEquals([ | |
86 new Export(libPath('a.dart'), libPath('a_export.dart')), | |
87 ])); | |
88 expect(map.transitiveExports(libPath('a.dart')), unorderedEquals([ | |
89 new Export(libPath('a.dart'), libPath('a_export.dart')), | |
90 ])); | |
91 | |
92 expect(map.transitiveExports(libPath('b.dart')), unorderedEquals([ | |
93 new Export(libPath('b.dart'), libPath('b_export.dart')), | |
94 ])); | |
95 expect(map.exports[libPath('b.dart')], unorderedEquals([ | |
96 new Export(libPath('b.dart'), libPath('b_export.dart')) | |
97 ])); | |
98 | |
99 expect(map.allExportedFiles, unorderedEquals([ | |
100 libPath('a_export.dart'), libPath('b_export.dart') | |
101 ])); | |
102 | |
103 expect(map.exports[libPath('a_export.dart')], isEmpty); | |
104 expect(map.transitiveExports(libPath('a_export.dart')), isEmpty); | |
105 expect(map.exports[libPath('b_export.dart')], isEmpty); | |
106 expect(map.transitiveExports(libPath('b_export.dart')), isEmpty); | |
107 }); | |
108 | |
109 test('with a transitive export', () { | |
110 createLibrary('a.dart', 'export "b.dart";'); | |
111 createLibrary('b.dart', 'export "c.dart";'); | |
112 createLibrary('c.dart'); | |
113 var map = parse(['a.dart']); | |
114 | |
115 expect(map.exports[libPath('a.dart')], unorderedEquals([ | |
116 new Export(libPath('a.dart'), libPath('b.dart')), | |
117 ])); | |
118 expect(map.transitiveExports(libPath('a.dart')), unorderedEquals([ | |
119 new Export(libPath('a.dart'), libPath('b.dart')), | |
120 new Export(libPath('a.dart'), libPath('c.dart')), | |
121 ])); | |
122 | |
123 expect(map.exports[libPath('b.dart')], unorderedEquals([ | |
124 new Export(libPath('b.dart'), libPath('c.dart')), | |
125 ])); | |
126 expect(map.transitiveExports(libPath('b.dart')), unorderedEquals([ | |
127 new Export(libPath('b.dart'), libPath('c.dart')), | |
128 ])); | |
129 | |
130 expect(map.allExportedFiles, unorderedEquals([ | |
131 libPath('b.dart'), libPath('c.dart') | |
132 ])); | |
133 | |
134 expect(map.exports[libPath('c.dart')], isEmpty); | |
135 expect(map.transitiveExports(libPath('c.dart')), isEmpty); | |
136 }); | |
137 | |
138 test('with an export through an import', () { | |
139 createLibrary('a.dart', 'import "b.dart";'); | |
140 createLibrary('b.dart', 'export "c.dart";'); | |
141 createLibrary('c.dart'); | |
142 var map = parse(['a.dart']); | |
143 | |
144 expect(map.exports[libPath('b.dart')], unorderedEquals([ | |
145 new Export(libPath('b.dart'), libPath('c.dart')), | |
146 ])); | |
147 expect(map.transitiveExports(libPath('b.dart')), unorderedEquals([ | |
148 new Export(libPath('b.dart'), libPath('c.dart')), | |
149 ])); | |
150 | |
151 expect(map.allExportedFiles, unorderedEquals([libPath('c.dart')])); | |
152 | |
153 expect(map.exports[libPath('a.dart')], isEmpty); | |
154 expect(map.exports[libPath('c.dart')], isEmpty); | |
155 expect(map.transitiveExports(libPath('a.dart')), isEmpty); | |
156 expect(map.transitiveExports(libPath('c.dart')), isEmpty); | |
157 }); | |
158 | |
159 test('with an export with a show combinator', () { | |
160 createLibrary('a.dart', 'export "b.dart" show x, y;'); | |
161 createLibrary('b.dart'); | |
162 var map = parse(['a.dart']); | |
163 | |
164 expect(map.exports[libPath('a.dart')], unorderedEquals([ | |
165 new Export(libPath('a.dart'), libPath('b.dart'), show: ['x', 'y']) | |
166 ])); | |
167 }); | |
168 | |
169 test('with an export with a hide combinator', () { | |
170 createLibrary('a.dart', 'export "b.dart" hide x, y;'); | |
171 createLibrary('b.dart'); | |
172 var map = parse(['a.dart']); | |
173 | |
174 expect(map.exports[libPath('a.dart')], unorderedEquals([ | |
175 new Export(libPath('a.dart'), libPath('b.dart'), hide: ['x', 'y']) | |
176 ])); | |
177 }); | |
178 | |
179 test('with an export with a show and a hide combinator', () { | |
180 createLibrary('a.dart', 'export "b.dart" show x, y hide y, z;'); | |
181 createLibrary('b.dart'); | |
182 var map = parse(['a.dart']); | |
183 | |
184 expect(map.exports[libPath('a.dart')], unorderedEquals([ | |
185 new Export(libPath('a.dart'), libPath('b.dart'), show: ['x']) | |
186 ])); | |
187 }); | |
188 | |
189 test('composes transitive exports', () { | |
190 createLibrary('a.dart', 'export "b.dart" hide x;'); | |
191 createLibrary('b.dart', 'export "c.dart" hide y;'); | |
192 createLibrary('c.dart'); | |
193 var map = parse(['a.dart']); | |
194 | |
195 expect(map.transitiveExports(libPath('a.dart')), unorderedEquals([ | |
196 new Export(libPath('a.dart'), libPath('b.dart'), hide: ['x']), | |
197 new Export(libPath('a.dart'), libPath('c.dart'), hide: ['x', 'y']) | |
198 ])); | |
199 }); | |
200 | |
201 test('merges adjacent exports', () { | |
202 createLibrary('a.dart', ''' | |
203 export "b.dart" show x, y; | |
204 export "b.dart" hide y, z; | |
205 '''); | |
206 createLibrary('b.dart'); | |
207 var map = parse(['a.dart']); | |
208 | |
209 expect(map.exports[libPath('a.dart')], unorderedEquals([ | |
210 new Export(libPath('a.dart'), libPath('b.dart'), hide: ['z']), | |
211 ])); | |
212 expect(map.transitiveExports(libPath('a.dart')), unorderedEquals([ | |
213 new Export(libPath('a.dart'), libPath('b.dart'), hide: ['z']), | |
214 ])); | |
215 }); | |
216 | |
217 test('merges adjacent exports transitively', () { | |
218 createLibrary('a.dart', 'export "b.dart";\nexport "c.dart";'); | |
219 createLibrary('b.dart', 'export "d.dart" show x, y;'); | |
220 createLibrary('c.dart', 'export "d.dart" hide y, z;'); | |
221 createLibrary('d.dart'); | |
222 var map = parse(['a.dart']); | |
223 | |
224 expect(map.exports[libPath('a.dart')], unorderedEquals([ | |
225 new Export(libPath('a.dart'), libPath('b.dart')), | |
226 new Export(libPath('a.dart'), libPath('c.dart')), | |
227 ])); | |
228 expect(map.transitiveExports(libPath('a.dart')), unorderedEquals([ | |
229 new Export(libPath('a.dart'), libPath('b.dart')), | |
230 new Export(libPath('a.dart'), libPath('c.dart')), | |
231 new Export(libPath('a.dart'), libPath('d.dart'), hide: ['z']), | |
232 ])); | |
233 }); | |
234 | |
235 test('resolves package: exports', () { | |
236 createLibrary('a.dart', 'export "package:b/b.dart";'); | |
237 var bPath = pathos.join('packages', 'b', 'b.dart'); | |
238 createLibrary(bPath); | |
239 var map = parse(['a.dart']); | |
240 | |
241 expect(map.exports[libPath('a.dart')], unorderedEquals([ | |
242 new Export(libPath('a.dart'), libPath(bPath)) | |
243 ])); | |
244 }); | |
245 | |
246 test('ignores dart: exports', () { | |
247 createLibrary('a.dart', 'export "dart:async";'); | |
248 var map = parse(['a.dart']); | |
249 expect(map.exports[libPath('a.dart')], isEmpty); | |
250 }); | |
251 | |
252 test('.parse() resolves package: imports', () { | |
253 var aPath = pathos.join('packages', 'a', 'a.dart'); | |
254 createLibrary(aPath, 'export "package:b/b.dart";'); | |
255 var bPath = pathos.join('packages', 'b', 'b.dart'); | |
256 createLibrary(bPath); | |
257 var map = new ExportMap.parse( | |
258 [Uri.parse('package:a/a.dart')], | |
259 pathos.join(tempDir, 'packages')); | |
260 | |
261 expect(map.exports[libPath(aPath)], unorderedEquals([ | |
262 new Export(libPath(aPath), libPath(bPath)) | |
263 ])); | |
264 }); | |
265 | |
266 test('.parse() ignores dart: imports', () { | |
267 var map = new ExportMap.parse( | |
268 [Uri.parse('dart:async')], | |
269 pathos.join(tempDir, 'packages')); | |
270 expect(map.exports, isEmpty); | |
271 }); | |
272 }); | |
273 | |
274 group('Export', () { | |
275 test('normalizes hide and show', () { | |
276 expect(new Export('', '', show: ['x', 'y'], hide: ['y', 'z']), | |
277 equals(new Export('', '', show: ['x']))); | |
278 }); | |
279 | |
280 test("doesn't care about the order of show or hide", () { | |
281 expect(new Export('', '', show: ['x', 'y']), | |
282 equals(new Export('', '', show: ['y', 'x']))); | |
283 expect(new Export('', '', hide: ['x', 'y']), | |
284 equals(new Export('', '', hide: ['y', 'x']))); | |
285 }); | |
286 | |
287 test('with no combinators considers anything visible', () { | |
288 var export = new Export('', ''); | |
289 expect(export.isMemberVisible('x'), isTrue); | |
290 expect(export.isMemberVisible('y'), isTrue); | |
291 expect(export.isMemberVisible('z'), isTrue); | |
292 }); | |
293 | |
294 test('with hide combinators considers anything not hidden visible', () { | |
295 var export = new Export('', '', hide: ['x', 'y']); | |
296 expect(export.isMemberVisible('x'), isFalse); | |
297 expect(export.isMemberVisible('y'), isFalse); | |
298 expect(export.isMemberVisible('z'), isTrue); | |
299 }); | |
300 | |
301 test('with show combinators considers anything not shown invisible', () { | |
302 var export = new Export('', '', show: ['x', 'y']); | |
303 expect(export.isMemberVisible('x'), isTrue); | |
304 expect(export.isMemberVisible('y'), isTrue); | |
305 expect(export.isMemberVisible('z'), isFalse); | |
306 }); | |
307 | |
308 test('composing uses the parent exporter and child path', () { | |
309 expect(new Export('exporter1.dart', 'path1.dart') | |
310 .compose(new Export('exporter2.dart', 'path2.dart')), | |
311 equals(new Export('exporter1.dart', 'path2.dart'))); | |
312 }); | |
313 | |
314 test('composing show . show takes the intersection', () { | |
315 expect(new Export('', '', show: ['x', 'y']) | |
316 .compose(new Export('', '', show: ['y', 'z'])), | |
317 equals(new Export('', '', show: ['y']))); | |
318 }); | |
319 | |
320 test('composing show . hide takes the difference', () { | |
321 expect(new Export('', '', show: ['x', 'y']) | |
322 .compose(new Export('', '', hide: ['y', 'z'])), | |
323 equals(new Export('', '', show: ['x']))); | |
324 }); | |
325 | |
326 test('composing hide . show takes the reverse difference', () { | |
327 expect(new Export('', '', hide: ['x', 'y']) | |
328 .compose(new Export('', '', show: ['y', 'z'])), | |
329 equals(new Export('', '', show: ['z']))); | |
330 }); | |
331 | |
332 test('composing hide . hide takes the union', () { | |
333 expect(new Export('', '', hide: ['x', 'y']) | |
334 .compose(new Export('', '', hide: ['y', 'z'])), | |
335 equals(new Export('', '', hide: ['x', 'y', 'z']))); | |
336 }); | |
337 | |
338 test('merging requires identical exporters and paths', () { | |
339 expect(() => new Export('exporter1.dart', '') | |
340 .merge(new Export('exporter2.dart', '')), | |
341 throwsA(isArgumentError)); | |
342 expect(() => new Export('', 'path1.dart') | |
343 .merge(new Export('', 'path2.dart')), | |
344 throwsA(isArgumentError)); | |
345 expect(new Export('', '').merge(new Export('', '')), | |
346 equals(new Export('', ''))); | |
347 }); | |
348 | |
349 test('merging show + show takes the union', () { | |
350 expect(new Export('', '', show: ['x', 'y']) | |
351 .merge(new Export('', '', show: ['y', 'z'])), | |
352 equals(new Export('', '', show: ['x', 'y', 'z']))); | |
353 }); | |
354 | |
355 test('merging show + hide takes the difference', () { | |
356 expect(new Export('', '', show: ['x', 'y']) | |
357 .merge(new Export('', '', hide: ['y', 'z'])), | |
358 equals(new Export('', '', hide: ['z']))); | |
359 }); | |
360 | |
361 test('merging hide + show takes the difference', () { | |
362 expect(new Export('', '', hide: ['x', 'y']) | |
363 .merge(new Export('', '', show: ['y', 'z'])), | |
364 equals(new Export('', '', hide: ['x']))); | |
365 }); | |
366 | |
367 test('merging hide + hide takes the intersection', () { | |
368 expect(new Export('', '', hide: ['x', 'y']) | |
369 .merge(new Export('', '', hide: ['y', 'z'])), | |
370 equals(new Export('', '', hide: ['y']))); | |
371 }); | |
372 }); | |
373 } | |
374 | |
375 ExportMap parse(List<String> libraries) { | |
376 return new ExportMap.parse( | |
377 libraries.map(libPath) | |
378 .map(pathToFileUri), | |
379 pathos.join(tempDir, 'packages')); | |
380 } | |
381 | |
382 void createLibrary(String name, [String contents]) { | |
383 if (contents == null) contents = ''; | |
384 new Directory(pathos.dirname(libPath(name))).createSync(recursive: true); | |
385 new File(libPath(name)).writeAsStringSync(''' | |
386 library ${pathos.basename(name)}; | |
387 $contents | |
388 '''); | |
389 } | |
390 | |
391 String libPath(String name) => pathos.normalize(pathos.join(tempDir, name)); | |
392 | |
393 void createTempDir() { | |
394 tempDir = new Directory('').createTempSync().path; | |
395 new Directory(pathos.join(tempDir, 'packages')).createSync(); | |
396 } | |
397 | |
398 void deleteTempDir() { | |
399 new Directory(tempDir).deleteSync(recursive: true); | |
400 } | |
OLD | NEW |