OLD | NEW |
| (Empty) |
1 // Copyright (c) 2012, 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 library io_test; | |
6 | |
7 import 'dart:async'; | |
8 import 'dart:io'; | |
9 | |
10 import 'package:path/path.dart' as path; | |
11 import 'package:unittest/unittest.dart'; | |
12 | |
13 import '../lib/src/io.dart'; | |
14 import 'test_pub.dart'; | |
15 | |
16 main() { | |
17 initConfig(); | |
18 | |
19 group('listDir', () { | |
20 test('ignores hidden files by default', () { | |
21 expect(withTempDir((temp) { | |
22 writeTextFile(path.join(temp, 'file1.txt'), ''); | |
23 writeTextFile(path.join(temp, 'file2.txt'), ''); | |
24 writeTextFile(path.join(temp, '.file3.txt'), ''); | |
25 createDir(path.join(temp, '.subdir')); | |
26 writeTextFile(path.join(temp, '.subdir', 'file3.txt'), ''); | |
27 | |
28 expect(listDir(temp, recursive: true), unorderedEquals([ | |
29 path.join(temp, 'file1.txt'), | |
30 path.join(temp, 'file2.txt') | |
31 ])); | |
32 }), completes); | |
33 }); | |
34 | |
35 test('includes hidden files when told to', () { | |
36 expect(withTempDir((temp) { | |
37 writeTextFile(path.join(temp, 'file1.txt'), ''); | |
38 writeTextFile(path.join(temp, 'file2.txt'), ''); | |
39 writeTextFile(path.join(temp, '.file3.txt'), ''); | |
40 createDir(path.join(temp, '.subdir')); | |
41 writeTextFile(path.join(temp, '.subdir', 'file3.txt'), ''); | |
42 | |
43 expect(listDir(temp, recursive: true, includeHidden: true), | |
44 unorderedEquals([ | |
45 path.join(temp, 'file1.txt'), | |
46 path.join(temp, 'file2.txt'), | |
47 path.join(temp, '.file3.txt'), | |
48 path.join(temp, '.subdir'), | |
49 path.join(temp, '.subdir', 'file3.txt') | |
50 ])); | |
51 }), completes); | |
52 }); | |
53 | |
54 test("doesn't ignore hidden files above the directory being listed", () { | |
55 expect(withTempDir((temp) { | |
56 var dir = path.join(temp, '.foo', 'bar'); | |
57 ensureDir(dir); | |
58 writeTextFile(path.join(dir, 'file1.txt'), ''); | |
59 writeTextFile(path.join(dir, 'file2.txt'), ''); | |
60 writeTextFile(path.join(dir, 'file3.txt'), ''); | |
61 | |
62 expect(listDir(dir, recursive: true), unorderedEquals([ | |
63 path.join(dir, 'file1.txt'), | |
64 path.join(dir, 'file2.txt'), | |
65 path.join(dir, 'file3.txt') | |
66 ])); | |
67 }), completes); | |
68 }); | |
69 }); | |
70 | |
71 group('canonicalize', () { | |
72 test('resolves a non-link', () { | |
73 expect(withCanonicalTempDir((temp) { | |
74 var filePath = path.join(temp, 'file'); | |
75 writeTextFile(filePath, ''); | |
76 expect(canonicalize(filePath), equals(filePath)); | |
77 }), completes); | |
78 }); | |
79 | |
80 test('resolves a non-existent file', () { | |
81 expect(withCanonicalTempDir((temp) { | |
82 expect(canonicalize(path.join(temp, 'nothing')), | |
83 equals(path.join(temp, 'nothing'))); | |
84 }), completes); | |
85 }); | |
86 | |
87 test('resolves a symlink', () { | |
88 expect(withCanonicalTempDir((temp) { | |
89 createDir(path.join(temp, 'linked-dir')); | |
90 createSymlink( | |
91 path.join(temp, 'linked-dir'), | |
92 path.join(temp, 'dir')); | |
93 expect( | |
94 canonicalize(path.join(temp, 'dir')), | |
95 equals(path.join(temp, 'linked-dir'))); | |
96 }), completes); | |
97 }); | |
98 | |
99 test('resolves a relative symlink', () { | |
100 expect(withCanonicalTempDir((temp) { | |
101 createDir(path.join(temp, 'linked-dir')); | |
102 createSymlink( | |
103 path.join(temp, 'linked-dir'), | |
104 path.join(temp, 'dir'), | |
105 relative: true); | |
106 expect( | |
107 canonicalize(path.join(temp, 'dir')), | |
108 equals(path.join(temp, 'linked-dir'))); | |
109 }), completes); | |
110 }); | |
111 | |
112 test('resolves a single-level horizontally recursive symlink', () { | |
113 expect(withCanonicalTempDir((temp) { | |
114 var linkPath = path.join(temp, 'foo'); | |
115 createSymlink(linkPath, linkPath); | |
116 expect(canonicalize(linkPath), equals(linkPath)); | |
117 }), completes); | |
118 }); | |
119 | |
120 test('resolves a multi-level horizontally recursive symlink', () { | |
121 expect(withCanonicalTempDir((temp) { | |
122 var fooPath = path.join(temp, 'foo'); | |
123 var barPath = path.join(temp, 'bar'); | |
124 var bazPath = path.join(temp, 'baz'); | |
125 createSymlink(barPath, fooPath); | |
126 createSymlink(bazPath, barPath); | |
127 createSymlink(fooPath, bazPath); | |
128 expect(canonicalize(fooPath), equals(fooPath)); | |
129 expect(canonicalize(barPath), equals(barPath)); | |
130 expect(canonicalize(bazPath), equals(bazPath)); | |
131 | |
132 createSymlink(fooPath, path.join(temp, 'outer')); | |
133 expect(canonicalize(path.join(temp, 'outer')), equals(fooPath)); | |
134 }), completes); | |
135 }); | |
136 | |
137 test('resolves a broken symlink', () { | |
138 expect(withCanonicalTempDir((temp) { | |
139 createSymlink(path.join(temp, 'nonexistent'), path.join(temp, 'foo')); | |
140 expect( | |
141 canonicalize(path.join(temp, 'foo')), | |
142 equals(path.join(temp, 'nonexistent'))); | |
143 }), completes); | |
144 }); | |
145 | |
146 test('resolves multiple nested symlinks', () { | |
147 expect(withCanonicalTempDir((temp) { | |
148 var dir1 = path.join(temp, 'dir1'); | |
149 var dir2 = path.join(temp, 'dir2'); | |
150 var subdir1 = path.join(dir1, 'subdir1'); | |
151 var subdir2 = path.join(dir2, 'subdir2'); | |
152 createDir(dir2); | |
153 createDir(subdir2); | |
154 createSymlink(dir2, dir1); | |
155 createSymlink(subdir2, subdir1); | |
156 expect( | |
157 canonicalize(path.join(subdir1, 'file')), | |
158 equals(path.join(subdir2, 'file'))); | |
159 }), completes); | |
160 }); | |
161 | |
162 test('resolves a nested vertical symlink', () { | |
163 expect(withCanonicalTempDir((temp) { | |
164 var dir1 = path.join(temp, 'dir1'); | |
165 var dir2 = path.join(temp, 'dir2'); | |
166 var subdir = path.join(dir1, 'subdir'); | |
167 createDir(dir1); | |
168 createDir(dir2); | |
169 createSymlink(dir2, subdir); | |
170 expect( | |
171 canonicalize(path.join(subdir, 'file')), | |
172 equals(path.join(dir2, 'file'))); | |
173 }), completes); | |
174 }); | |
175 | |
176 test('resolves a vertically recursive symlink', () { | |
177 expect(withCanonicalTempDir((temp) { | |
178 var dir = path.join(temp, 'dir'); | |
179 var subdir = path.join(dir, 'subdir'); | |
180 createDir(dir); | |
181 createSymlink(dir, subdir); | |
182 expect( | |
183 canonicalize(path.join(temp, 'dir', 'subdir', 'subdir', 'subdir', | |
184 'subdir', 'file')), | |
185 equals(path.join(dir, 'file'))); | |
186 }), completes); | |
187 }); | |
188 | |
189 test('resolves a symlink that links to a path that needs more resolving', | |
190 () { | |
191 expect(withCanonicalTempDir((temp) { | |
192 var dir = path.join(temp, 'dir'); | |
193 var linkdir = path.join(temp, 'linkdir'); | |
194 var linkfile = path.join(dir, 'link'); | |
195 createDir(dir); | |
196 createSymlink(dir, linkdir); | |
197 createSymlink(path.join(linkdir, 'file'), linkfile); | |
198 expect( | |
199 canonicalize(linkfile), | |
200 equals(path.join(dir, 'file'))); | |
201 }), completes); | |
202 }); | |
203 | |
204 test('resolves a pair of pathologically-recursive symlinks', () { | |
205 expect(withCanonicalTempDir((temp) { | |
206 var foo = path.join(temp, 'foo'); | |
207 var subfoo = path.join(foo, 'subfoo'); | |
208 var bar = path.join(temp, 'bar'); | |
209 var subbar = path.join(bar, 'subbar'); | |
210 createSymlink(subbar, foo); | |
211 createSymlink(subfoo, bar); | |
212 expect( | |
213 canonicalize(subfoo), | |
214 equals(path.join(subfoo, 'subbar', 'subfoo'))); | |
215 }), completes); | |
216 }); | |
217 }); | |
218 | |
219 testExistencePredicate("entryExists", entryExists, | |
220 forFile: true, | |
221 forFileSymlink: true, | |
222 forMultiLevelFileSymlink: true, | |
223 forDirectory: true, | |
224 forDirectorySymlink: true, | |
225 forMultiLevelDirectorySymlink: true, | |
226 forBrokenSymlink: true, | |
227 forMultiLevelBrokenSymlink: true); | |
228 | |
229 testExistencePredicate("linkExists", linkExists, | |
230 forFile: false, | |
231 forFileSymlink: true, | |
232 forMultiLevelFileSymlink: true, | |
233 forDirectory: false, | |
234 forDirectorySymlink: true, | |
235 forMultiLevelDirectorySymlink: true, | |
236 forBrokenSymlink: true, | |
237 forMultiLevelBrokenSymlink: true); | |
238 | |
239 testExistencePredicate("fileExists", fileExists, | |
240 forFile: true, | |
241 forFileSymlink: true, | |
242 forMultiLevelFileSymlink: true, | |
243 forDirectory: false, | |
244 forDirectorySymlink: false, | |
245 forMultiLevelDirectorySymlink: false, | |
246 forBrokenSymlink: false, | |
247 forMultiLevelBrokenSymlink: false); | |
248 | |
249 testExistencePredicate("dirExists", dirExists, | |
250 forFile: false, | |
251 forFileSymlink: false, | |
252 forMultiLevelFileSymlink: false, | |
253 forDirectory: true, | |
254 forDirectorySymlink: true, | |
255 forMultiLevelDirectorySymlink: true, | |
256 forBrokenSymlink: false, | |
257 forMultiLevelBrokenSymlink: false); | |
258 } | |
259 | |
260 void testExistencePredicate(String name, bool predicate(String path), | |
261 {bool forFile, | |
262 bool forFileSymlink, | |
263 bool forMultiLevelFileSymlink, | |
264 bool forDirectory, | |
265 bool forDirectorySymlink, | |
266 bool forMultiLevelDirectorySymlink, | |
267 bool forBrokenSymlink, | |
268 bool forMultiLevelBrokenSymlink}) { | |
269 group(name, () { | |
270 test('returns $forFile for a file', () { | |
271 expect(withTempDir((temp) { | |
272 var file = path.join(temp, "test.txt"); | |
273 writeTextFile(file, "contents"); | |
274 expect(predicate(file), equals(forFile)); | |
275 }), completes); | |
276 }); | |
277 | |
278 test('returns $forDirectory for a directory', () { | |
279 expect(withTempDir((temp) { | |
280 var file = path.join(temp, "dir"); | |
281 createDir(file); | |
282 expect(predicate(file), equals(forDirectory)); | |
283 }), completes); | |
284 }); | |
285 | |
286 test('returns $forDirectorySymlink for a symlink to a directory', () { | |
287 expect(withTempDir((temp) { | |
288 var targetPath = path.join(temp, "dir"); | |
289 var symlinkPath = path.join(temp, "linkdir"); | |
290 createDir(targetPath); | |
291 createSymlink(targetPath, symlinkPath); | |
292 expect(predicate(symlinkPath), equals(forDirectorySymlink)); | |
293 }), completes); | |
294 }); | |
295 | |
296 test('returns $forMultiLevelDirectorySymlink for a multi-level symlink to ' | |
297 'a directory', () { | |
298 expect(withTempDir((temp) { | |
299 var targetPath = path.join(temp, "dir"); | |
300 var symlink1Path = path.join(temp, "link1dir"); | |
301 var symlink2Path = path.join(temp, "link2dir"); | |
302 createDir(targetPath); | |
303 createSymlink(targetPath, symlink1Path); | |
304 createSymlink(symlink1Path, symlink2Path); | |
305 expect(predicate(symlink2Path), | |
306 equals(forMultiLevelDirectorySymlink)); | |
307 }), completes); | |
308 }); | |
309 | |
310 test('returns $forBrokenSymlink for a broken symlink', () { | |
311 expect(withTempDir((temp) { | |
312 var targetPath = path.join(temp, "dir"); | |
313 var symlinkPath = path.join(temp, "linkdir"); | |
314 createDir(targetPath); | |
315 createSymlink(targetPath, symlinkPath); | |
316 deleteEntry(targetPath); | |
317 expect(predicate(symlinkPath), equals(forBrokenSymlink)); | |
318 }), completes); | |
319 }); | |
320 | |
321 test('returns $forMultiLevelBrokenSymlink for a multi-level broken symlink', | |
322 () { | |
323 expect(withTempDir((temp) { | |
324 var targetPath = path.join(temp, "dir"); | |
325 var symlink1Path = path.join(temp, "link1dir"); | |
326 var symlink2Path = path.join(temp, "link2dir"); | |
327 createDir(targetPath); | |
328 createSymlink(targetPath, symlink1Path); | |
329 createSymlink(symlink1Path, symlink2Path); | |
330 deleteEntry(targetPath); | |
331 expect(predicate(symlink2Path), equals(forMultiLevelBrokenSymlink)); | |
332 }), completes); | |
333 }); | |
334 | |
335 // Windows doesn't support symlinking to files. | |
336 if (Platform.operatingSystem != 'windows') { | |
337 test('returns $forFileSymlink for a symlink to a file', () { | |
338 expect(withTempDir((temp) { | |
339 var targetPath = path.join(temp, "test.txt"); | |
340 var symlinkPath = path.join(temp, "link.txt"); | |
341 writeTextFile(targetPath, "contents"); | |
342 createSymlink(targetPath, symlinkPath); | |
343 expect(predicate(symlinkPath), equals(forFileSymlink)); | |
344 }), completes); | |
345 }); | |
346 | |
347 test('returns $forMultiLevelFileSymlink for a multi-level symlink to a ' | |
348 'file', () { | |
349 expect(withTempDir((temp) { | |
350 var targetPath = path.join(temp, "test.txt"); | |
351 var symlink1Path = path.join(temp, "link1.txt"); | |
352 var symlink2Path = path.join(temp, "link2.txt"); | |
353 writeTextFile(targetPath, "contents"); | |
354 createSymlink(targetPath, symlink1Path); | |
355 createSymlink(symlink1Path, symlink2Path); | |
356 expect(predicate(symlink2Path), equals(forMultiLevelFileSymlink)); | |
357 }), completes); | |
358 }); | |
359 } | |
360 }); | |
361 } | |
362 | |
363 /// Like [withTempDir], but canonicalizes the path before passing it to [fn]. | |
364 Future withCanonicalTempDir(Future fn(String path)) => | |
365 withTempDir((temp) => fn(canonicalize(temp))); | |
OLD | NEW |