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 // Test the Path class in dart:io. | |
6 | |
7 import "package:expect/expect.dart"; | |
8 import "dart:io"; | |
9 | |
10 void main() { | |
11 testBaseFunctions(); | |
12 testRaw(); | |
13 testToNativePath(); | |
14 testCanonicalize(); | |
15 testJoinAppend(); | |
16 testRelativeTo(); | |
17 testWindowsShare(); | |
18 testWindowsDrive(); | |
19 } | |
20 | |
21 void testBaseFunctions() { | |
22 testGetters(new Path("/foo/bar/fisk.hest"), | |
23 ['/foo/bar', 'fisk.hest', 'fisk', 'hest'], | |
24 'absolute canonical'); | |
25 testGetters(new Path(''), | |
26 ['', '', '', ''], | |
27 'empty'); | |
28 // This corner case leaves a trailing slash for the root. | |
29 testGetters(new Path('/'), | |
30 ['/', '', '', ''], | |
31 'absolute canonical trailing'); | |
32 testGetters(new Path('.'), | |
33 ['', '.', '.', ''], | |
34 'canonical'); | |
35 testGetters(new Path('..'), | |
36 ['', '..', '..', ''], | |
37 'canonical'); | |
38 testGetters(new Path('/ab,;- .c.d'), | |
39 ['/', 'ab,;- .c.d', 'ab,;- .c', 'd'], | |
40 'absolute canonical'); | |
41 | |
42 // Canonical and non-canonical cases | |
43 testGetters(new Path("a/b/../c/./d/e"), | |
44 ['a/b/../c/./d', 'e', 'e', ''], | |
45 ''); | |
46 testGetters(new Path("a./b../..c/.d/e"), | |
47 ['a./b../..c/.d', 'e', 'e', ''], | |
48 'canonical'); | |
49 // .. is allowed at the beginning of a canonical relative path. | |
50 testGetters(new Path("../../a/b/c/d/"), | |
51 ['../../a/b/c/d', '', '', ''], | |
52 'canonical trailing'); | |
53 | |
54 // '.' at the end of a path is not considered an extension. | |
55 testGetters(new Path("a/b.c/."), | |
56 ['a/b.c', '.', '.', ''], | |
57 ''); | |
58 // '..' at the end of a path is not considered an extension. | |
59 testGetters(new Path("a/bc/../.."), | |
60 ['a/bc/..', '..', '..', ''], | |
61 ''); | |
62 | |
63 // Test the special path cleaning operations on the Windows platform. | |
64 if (Platform.operatingSystem == 'windows') { | |
65 testGetters(new Path(r"c:\foo\bar\fisk.hest"), | |
66 ['/c:/foo/bar', 'fisk.hest', 'fisk', 'hest'], | |
67 'absolute canonical'); | |
68 testGetters(new Path("\\foo\\bar\\"), | |
69 ['/foo/bar', '', '', ''], | |
70 'absolute canonical trailing'); | |
71 testGetters(new Path("\\foo\\bar\\hest"), | |
72 ['/foo/bar', 'hest', 'hest', ''], | |
73 'absolute canonical'); | |
74 testGetters(new Path(r"foo/bar\hest/.fisk"), | |
75 ['foo/bar/hest', '.fisk', '', 'fisk'], | |
76 'canonical'); | |
77 testGetters(new Path(r"foo//bar\\hest/\/.fisk."), | |
78 ['foo//bar//hest', '.fisk.', '.fisk', ''], | |
79 ''); | |
80 } else { | |
81 // Make sure that backslashes are uninterpreted on other platforms. | |
82 testGetters(new Path(r"c:\foo\bar\fisk.hest"), | |
83 ['', r'c:\foo\bar\fisk.hest', r'c:\foo\bar\fisk', 'hest'], | |
84 'canonical'); | |
85 testGetters(new Path(r"/foo\bar/bif/fisk.hest"), | |
86 [r'/foo\bar/bif', 'fisk.hest', 'fisk', 'hest'], | |
87 'absolute canonical'); | |
88 testGetters(new Path(r"//foo\bar///bif////fisk.hest"), | |
89 [r'//foo\bar///bif', 'fisk.hest', 'fisk', 'hest'], | |
90 'absolute'); | |
91 testGetters(new Path(r"/foo\ bar/bif/gule\ fisk.hest"), | |
92 [r'/foo\ bar/bif', r'gule\ fisk.hest', r'gule\ fisk', 'hest'], | |
93 'absolute canonical'); | |
94 } | |
95 } | |
96 | |
97 | |
98 void testGetters(Path path, List components, String properties) { | |
99 final int DIRNAME = 0; | |
100 final int FILENAME = 1; | |
101 final int FILENAME_NO_EXTENSION = 2; | |
102 final int EXTENSION = 3; | |
103 Expect.equals(components[DIRNAME], path.directoryPath.toString()); | |
104 Expect.equals(components[FILENAME], path.filename); | |
105 Expect.equals(components[FILENAME_NO_EXTENSION], | |
106 path.filenameWithoutExtension); | |
107 Expect.equals(components[EXTENSION], path.extension); | |
108 | |
109 Expect.equals(path.isCanonical, properties.contains('canonical')); | |
110 Expect.equals(path.isAbsolute, properties.contains('absolute')); | |
111 Expect.equals(path.hasTrailingSeparator, properties.contains('trailing')); | |
112 } | |
113 | |
114 void testRaw() { | |
115 Expect.equals(new Path.raw('c:\\foo/bar bad').toString(), 'c:\\foo/bar bad'); | |
116 Expect.equals(new Path.raw('').toString(), ''); | |
117 Expect.equals(new Path.raw('\\bar\u2603\n.').toString(), '\\bar\u2603\n.'); | |
118 } | |
119 | |
120 void testToNativePath() { | |
121 Expect.equals('.', new Path('').toNativePath()); | |
122 Expect.equals('.', new Path('.').toNativePath()); | |
123 Expect.equals('.', new Path('a_file').directoryPath.toNativePath()); | |
124 } | |
125 | |
126 void testCanonicalize() { | |
127 Function t = (input, canonicalized) { | |
128 Expect.equals(canonicalized, new Path(input).canonicalize().toString()); | |
129 }; | |
130 | |
131 t('.', '.'); | |
132 t('./.', '.'); | |
133 t('foo/..', '.'); | |
134 t('../foo', '../foo'); | |
135 t('/../foo', '/foo'); | |
136 t('/foo/..', '/'); | |
137 t('/foo/../', '/'); | |
138 t('/c:/../foo', '/c:/foo'); | |
139 t('/c:/foo/..', '/c:/'); | |
140 t('/c:/foo/../', '/c:/'); | |
141 t('/c:/foo/../..', '/c:/'); | |
142 t('/c:/foo/../../', '/c:/'); | |
143 t('..', '..'); | |
144 t('', '.'); | |
145 t('/', '/'); | |
146 t('../foo/bar/..', '../foo'); | |
147 t('/../foo/bar/..', '/foo'); | |
148 t('foo/bar/../../../joe/../..', '../..'); | |
149 t('a/b/c/../../..d/./.e/f././', 'a/..d/.e/f./'); | |
150 t('/%:/foo/../..', '/%:/'); | |
151 if (Platform.operatingSystem == 'windows') { | |
152 t('c:/foo/../../..', '/c:/'); | |
153 t('c:/foo/../../bad/dad/./..', '/c:/bad'); | |
154 } else { | |
155 t('c:/foo/../../..', '..'); | |
156 t('c:/foo/../../bad/dad/./..', 'bad'); | |
157 } | |
158 } | |
159 | |
160 void testJoinAppend() { | |
161 void testJoin(String a, String b, String c) { | |
162 Expect.equals(new Path(a).join(new Path(b)).toString(), c); | |
163 } | |
164 | |
165 testJoin('/a/b', 'c/d', '/a/b/c/d'); | |
166 testJoin('a/', 'b/c/', 'a/b/c/'); | |
167 testJoin('a/b/./c/..//', 'd/.././..//e/f//', 'a/e/f/'); | |
168 testJoin('a/b', 'c/../../../..', '..'); | |
169 testJoin('a/b', 'c/../../../', '.'); | |
170 testJoin('/a/b', 'c/../../../..', '/'); | |
171 testJoin('/a/b', 'c/../../../', '/'); | |
172 testJoin('a/b', 'c/../../../../../', '../../'); | |
173 testJoin('a/b/c', '../../d', 'a/d'); | |
174 testJoin('/a/b/c', '../../d', '/a/d'); | |
175 testJoin('/a/b/c', '../../d/', '/a/d/'); | |
176 testJoin('a/b/c', '../../d/', 'a/d/'); | |
177 | |
178 void testAppend(String a, String b, String c) { | |
179 Expect.equals(new Path(a).append(b).toString(), c); | |
180 } | |
181 | |
182 testAppend('/a/b', 'c', '/a/b/c'); | |
183 testAppend('a/b/', 'cd', 'a/b/cd'); | |
184 testAppend('.', '..', './..'); | |
185 testAppend('a/b', '/c/d', 'a/b//c/d'); | |
186 testAppend('', 'foo/bar', 'foo/bar'); | |
187 testAppend('/foo', '', '/foo/'); | |
188 | |
189 // .join can only join a relative path to a path. | |
190 // It cannot join an absolute path to a path. | |
191 Expect.throws(() => new Path('/a/b/').join(new Path('/c/d'))); | |
192 } | |
193 | |
194 void testRelativeTo() { | |
195 // Cases where the arguments are absolute paths. | |
196 Expect.equals('c/d', | |
197 new Path('/a/b/c/d').relativeTo(new Path('/a/b')).toString()); | |
198 Expect.equals('c/d', | |
199 new Path('/a/b/c/d').relativeTo(new Path('/a/b/')).toString()); | |
200 Expect.equals('.', | |
201 new Path('/a').relativeTo(new Path('/a')).toString()); | |
202 | |
203 // Trailing slash in the base path has no effect. This matches Path.join | |
204 // semantics, but not URL join semantics. | |
205 Expect.equals('../../z/x/y', | |
206 new Path('/a/b/z/x/y').relativeTo(new Path('/a/b/c/d/')).toString()); | |
207 Expect.equals('../../z/x/y', | |
208 new Path('/a/b/z/x/y').relativeTo(new Path('/a/b/c/d')).toString()); | |
209 Expect.equals('../../z/x/y/', | |
210 new Path('/a/b/z/x/y/').relativeTo(new Path('/a/b/c/d')).toString()); | |
211 | |
212 Expect.equals('../../../z/x/y', | |
213 new Path('/z/x/y').relativeTo(new Path('/a/b/c')).toString()); | |
214 Expect.equals('../../../z/x/y', | |
215 new Path('/z/x/y').relativeTo(new Path('/a/b/c/')).toString()); | |
216 | |
217 // Cases where the arguments are relative paths. | |
218 Expect.equals('c/d', | |
219 new Path('a/b/c/d').relativeTo(new Path('a/b')).toString()); | |
220 Expect.equals('c/d', | |
221 new Path('/a/b/c/d').relativeTo(new Path('/a/b/')).toString()); | |
222 Expect.equals('.', | |
223 new Path('a/b/c').relativeTo(new Path('a/b/c')).toString()); | |
224 Expect.equals('.', | |
225 new Path('').relativeTo(new Path('')).toString()); | |
226 Expect.equals('.', | |
227 new Path('.').relativeTo(new Path('.')).toString()); | |
228 Expect.equals('a', | |
229 new Path('a').relativeTo(new Path('.')).toString()); | |
230 Expect.equals('..', | |
231 new Path('..').relativeTo(new Path('.')).toString()); | |
232 Expect.equals('..', | |
233 new Path('.').relativeTo(new Path('a')).toString()); | |
234 Expect.equals('.', | |
235 new Path('..').relativeTo(new Path('..')).toString()); | |
236 Expect.equals('./', | |
237 new Path('a/b/f/../c/').relativeTo(new Path('a/e/../b/c')).toString()); | |
238 Expect.equals('d', | |
239 new Path('a/b/f/../c/d').relativeTo(new Path('a/e/../b/c')).toString()); | |
240 Expect.equals('..', | |
241 new Path('a/b/f/../c').relativeTo(new Path('a/e/../b/c/e/')).toString()); | |
242 Expect.equals('../..', | |
243 new Path('').relativeTo(new Path('a/b/')).toString()); | |
244 Expect.equals('../../..', | |
245 new Path('..').relativeTo(new Path('a/b')).toString()); | |
246 Expect.equals('../b/c/d/', | |
247 new Path('b/c/d/').relativeTo(new Path('a/')).toString()); | |
248 Expect.equals('../a/b/c', | |
249 new Path('x/y/a//b/./f/../c').relativeTo(new Path('x//y/z')).toString()); | |
250 | |
251 // Case where base is a substring of relative: | |
252 Expect.equals('a/b', | |
253 new Path('/x/y//a/b').relativeTo(new Path('/x/y/')).toString()); | |
254 Expect.equals('a/b', | |
255 new Path('x/y//a/b').relativeTo(new Path('x/y/')).toString()); | |
256 Expect.equals('../ya/b', | |
257 new Path('/x/ya/b').relativeTo(new Path('/x/y')).toString()); | |
258 Expect.equals('../ya/b', | |
259 new Path('x/ya/b').relativeTo(new Path('x/y')).toString()); | |
260 Expect.equals('../b', | |
261 new Path('x/y/../b').relativeTo(new Path('x/y/.')).toString()); | |
262 Expect.equals('a/b/c', | |
263 new Path('x/y/a//b/./f/../c').relativeTo(new Path('x/y')).toString()); | |
264 Expect.equals('.', | |
265 new Path('/x/y//').relativeTo(new Path('/x/y/')).toString()); | |
266 Expect.equals('.', | |
267 new Path('/x/y/').relativeTo(new Path('/x/y')).toString()); | |
268 | |
269 // Should always throw - no relative path can be constructed. | |
270 Expect.throws(() => | |
271 new Path('a/b').relativeTo(new Path('../../d'))); | |
272 // Should always throw - relative and absolute paths are compared. | |
273 Expect.throws(() => | |
274 new Path('/a/b').relativeTo(new Path('c/d'))); | |
275 | |
276 Expect.throws(() => | |
277 new Path('a/b').relativeTo(new Path('/a/b'))); | |
278 | |
279 } | |
280 | |
281 // Test that Windows share information is maintained through | |
282 // Path operations. | |
283 void testWindowsShare() { | |
284 // Windows share information only makes sense on Windows. | |
285 if (Platform.operatingSystem != 'windows') return; | |
286 var path = new Path(r'\\share\a\b\..\c'); | |
287 Expect.isTrue(path.isAbsolute); | |
288 Expect.isTrue(path.isWindowsShare); | |
289 Expect.isFalse(path.hasTrailingSeparator); | |
290 var canonical = path.canonicalize(); | |
291 Expect.isTrue(canonical.isAbsolute); | |
292 Expect.isTrue(canonical.isWindowsShare); | |
293 Expect.isFalse(path.isCanonical); | |
294 Expect.isTrue(canonical.isCanonical); | |
295 var joined = canonical.join(new Path('d/e/f')); | |
296 Expect.isTrue(joined.isAbsolute); | |
297 Expect.isTrue(joined.isWindowsShare); | |
298 var relativeTo = joined.relativeTo(canonical); | |
299 Expect.isFalse(relativeTo.isAbsolute); | |
300 Expect.isFalse(relativeTo.isWindowsShare); | |
301 var nonShare = new Path('/share/a/c/d/e'); | |
302 Expect.throws(() => nonShare.relativeTo(canonical)); | |
303 Expect.isTrue(canonical.toString().startsWith('/share/a')); | |
304 Expect.isTrue(canonical.toNativePath().startsWith(r'\\share\a')); | |
305 Expect.listEquals(['share', 'a', 'c'], canonical.segments()); | |
306 var appended = canonical.append('d'); | |
307 Expect.isTrue(appended.isAbsolute); | |
308 Expect.isTrue(appended.isWindowsShare); | |
309 var directoryPath = canonical.directoryPath; | |
310 Expect.isTrue(directoryPath.isAbsolute); | |
311 Expect.isTrue(directoryPath.isWindowsShare); | |
312 } | |
313 | |
314 // Test that Windows drive information is handled correctly in relative | |
315 // Path operations. | |
316 void testWindowsDrive() { | |
317 // Windows drive information only makes sense on Windows. | |
318 if (Platform.operatingSystem != 'windows') return; | |
319 // Test that case of drive letters is ignored, and that drive letters | |
320 // are treated specially. | |
321 var CPath = new Path(r'C:\a\b\..\c'); | |
322 var cPath = new Path(r'c:\a\b\d'); | |
323 var C2Path = new Path(r'C:\a\b\d'); | |
324 var C3Path = new Path(r'C:\a\b'); | |
325 var C4Path = new Path(r'C:\'); | |
326 var c4Path = new Path(r'c:\'); | |
327 var DPath = new Path(r'D:\a\b\d\e'); | |
328 var NoPath = new Path(r'\a\b\c\.'); | |
329 | |
330 Expect.throws(() => CPath.relativeTo(DPath)); | |
331 Expect.throws(() => CPath.relativeTo(NoPath)); | |
332 Expect.throws(() => NoPath.relativeTo(CPath)); | |
333 Expect.equals('../../c', CPath.relativeTo(cPath).toString()); | |
334 Expect.equals('../b/d', cPath.relativeTo(CPath).toString()); | |
335 Expect.equals('.', DPath.relativeTo(DPath).toString()); | |
336 Expect.equals('.', NoPath.relativeTo(NoPath).toString()); | |
337 Expect.equals('.', C2Path.relativeTo(cPath).toString()); | |
338 Expect.equals('..', C3Path.relativeTo(cPath).toString()); | |
339 Expect.equals('d', cPath.relativeTo(C3Path).toString()); | |
340 Expect.equals('a/b/d', cPath.relativeTo(C4Path).toString()); | |
341 Expect.equals('../../../', C4Path.relativeTo(cPath).toString()); | |
342 Expect.equals('a/b', C3Path.relativeTo(c4Path).toString()); | |
343 } | |
OLD | NEW |