Commit | Line | Data |
---|---|---|
7f918cf1 CE |
1 | (* Auxiliary functions for test cases *) |
2 | ||
3 | infix 1 seq | |
4 | fun e1 seq e2 = e2; | |
5 | fun check b = if b then "OK" else "WRONG"; | |
6 | fun check' f = (if f () then "OK" else "WRONG") handle _ => "EXN"; | |
7 | ||
8 | fun range (from, to) p = | |
9 | let open Int | |
10 | in | |
11 | (from > to) orelse (p from) andalso (range (from+1, to) p) | |
12 | end; | |
13 | ||
14 | fun checkrange bounds = check o range bounds; | |
15 | ||
16 | fun tst0 s s' = print (s ^ " \t" ^ s' ^ "\n"); | |
17 | fun tst s b = tst0 s (check b); | |
18 | fun tst' s f = tst0 s (check' f); | |
19 | ||
20 | fun tstrange s bounds = (tst s) o range bounds | |
21 | ||
22 | (* test/unixpath.sml 6 -- for Unix, 1995-05-23 *) | |
23 | ||
24 | val _ = print "\nFile unixpath.sml: Testing structure Path...\n" | |
25 | ||
26 | local | |
27 | open OS.Path | |
28 | ||
29 | val test1a = | |
30 | tst' "test1a" (fn _ => fromString "" = {isAbs=false, vol = "", arcs = []}); | |
31 | val test1b = | |
32 | tst' "test1b" (fn _ => fromString "/" = {isAbs=true, vol="", arcs=[""]}); | |
33 | val test1c = | |
34 | tst' "test1c" (fn _ => fromString "//" = {isAbs=true, vol="", arcs=["", ""]}); | |
35 | val test1d = | |
36 | tst' "test1d" (fn _ => fromString "a" = {isAbs=false, vol = "", arcs = ["a"]}); | |
37 | val test1e = | |
38 | tst' "test1e" (fn _ => fromString "/a" = {isAbs=true, vol="", arcs=["a"]}); | |
39 | val test1f = | |
40 | tst' "test1f" (fn _ => fromString "//a" = {isAbs=true, vol="", arcs=["","a"]}); | |
41 | val test1g = | |
42 | tst' "test1g" (fn _ => fromString "a/" = {isAbs=false, vol = "", arcs = ["a", ""]}); | |
43 | val test1h = | |
44 | tst' "test1h" (fn _ => fromString "a//" = {isAbs=false, vol = "", arcs = ["a", "", ""]}); | |
45 | val test1i = | |
46 | tst' "test1i" (fn _ => fromString "a/b" = {isAbs=false, vol = "", arcs = ["a", "b"]}); | |
47 | val test1j = | |
48 | tst' "test1j" (fn _ => fromString "a.b/c" = {isAbs=false, vol = "", arcs = ["a.b", "c"]}); | |
49 | val test1k = | |
50 | tst' "test1k" (fn _ => fromString "a.b/c/" = {isAbs=false, vol = "", arcs = ["a.b", "c", ""]}); | |
51 | val test1l = | |
52 | tst' "test1l" (fn _ => fromString "a/./c" = {isAbs=false, vol = "", arcs = ["a", ".", "c"]}); | |
53 | val test1m = | |
54 | tst' "test1m" (fn _ => fromString "a/../c" = {isAbs=false, vol = "", arcs = ["a", "..", "c"]}); | |
55 | val test1n = | |
56 | tst' "test1n" (fn _ => fromString "." = {isAbs=false, vol = "", arcs = ["."]}); | |
57 | ||
58 | val test2a = | |
59 | tst' "test2a" (fn _ => toString {isAbs=false, vol = "", arcs = []} = ""); | |
60 | val test2b = | |
61 | tst' "test2b" (fn _ => toString {isAbs=true, vol="", arcs=[]} = "/"); | |
62 | val test2c = | |
63 | tst' "test2c" (fn _ => toString {isAbs=true, vol="", arcs=["", ""]} = "//"); | |
64 | val test2d = | |
65 | tst' "test2d" (fn _ => toString {isAbs=false, vol = "", arcs = ["a"]} = "a"); | |
66 | val test2e = | |
67 | tst' "test2e" (fn _ => toString {isAbs=true, vol="", arcs=["a"]} = "/a"); | |
68 | val test2f = | |
69 | tst' "test2f" (fn _ => toString {isAbs=true, vol="", arcs=["","a"]} = "//a"); | |
70 | val test2g = | |
71 | tst' "test2g" (fn _ => toString {isAbs=false, vol = "", arcs = ["a", ""]} = "a/"); | |
72 | val test2h = | |
73 | tst' "test2h" (fn _ => toString {isAbs=false, vol = "", arcs = ["a", "", ""]} = "a//"); | |
74 | val test2i = | |
75 | tst' "test2i" (fn _ => toString {isAbs=false, vol = "", arcs = ["a", "b"]} = "a/b"); | |
76 | val test2j = | |
77 | tst' "test2j" (fn _ => toString {isAbs=false, vol = "", arcs = ["a.b", "c"]} = "a.b/c"); | |
78 | val test2k = | |
79 | tst' "test2k" (fn _ => toString {isAbs=false, vol = "", arcs = ["a.b", "c", ""]} = "a.b/c/"); | |
80 | val test2l = | |
81 | tst' "test2l" (fn _ => toString {isAbs=false, vol = "", arcs = ["a", ".", "c"]} = "a/./c"); | |
82 | val test2m = | |
83 | tst' "test2m" (fn _ => toString {isAbs=false, vol = "", arcs = ["a", "..", "c"]} = "a/../c"); | |
84 | val test2n = | |
85 | tst' "test2n" (fn _ => toString {isAbs=true, vol="", arcs=["a", "..", "c"]} = "/a/../c"); | |
86 | val test2o = tst0 "test2o" ((toString {isAbs=false, vol = "", arcs = ["", "a"]} seq "WRONG") | |
87 | handle Path => "OK" | _ => "WRONG") | |
88 | val test2p = tst0 "test2p" ((toString {isAbs=true, vol = "C:", arcs = ["windows"]} seq "WRONG") | |
89 | handle Path => "OK" | _ => "WRONG") | |
90 | ||
91 | val test3b = | |
92 | tst' "test3b" (fn _ => getVolume "/" = ""); | |
93 | val test3c = | |
94 | tst' "test3c" (fn _ => getVolume "//" = ""); | |
95 | val test3d = | |
96 | tst' "test3d" (fn _ => getVolume "a//b/c/" = ""); | |
97 | val test3e = | |
98 | tst' "test3e" (fn _ => getVolume "./" = ""); | |
99 | val test3f = | |
100 | tst' "test3f" (fn _ => getVolume "../" = ""); | |
101 | val test3g = | |
102 | tst' "test3g" (fn _ => getVolume "" = ""); | |
103 | val test3h = | |
104 | tst' "test3h" (fn _ => getVolume "C:" = ""); | |
105 | ||
106 | val test4a = | |
107 | tst' "test4a" (fn _ => | |
108 | List.all isRelative ["", ".", "..", "a//"] | |
109 | andalso not (List.exists isRelative ["/", "/a", "//"])); | |
110 | val test4b = | |
111 | tst' "test4b" (fn _ => | |
112 | List.all isAbsolute ["/", "/a", "//", "/.", "/.."] | |
113 | andalso not (List.exists isAbsolute ["", ".", "..", "a//"])); | |
114 | ||
115 | val test5a = | |
116 | tst' "test5a" (fn _ => | |
117 | getParent "/" = "/" | |
118 | andalso getParent "a" = "." | |
119 | andalso getParent "a/" = "a/.." | |
120 | andalso getParent "a///" = "a///.." | |
121 | andalso getParent "a/b" = "a" | |
122 | andalso getParent "a/b/" = "a/b/.." | |
123 | andalso getParent "/a/b" = "/a" | |
124 | andalso getParent "/a/b/" = "/a/b/.." | |
125 | andalso getParent ".." = "../.." | |
126 | andalso getParent "." = ".." | |
127 | andalso getParent "../" = "../.." | |
128 | andalso getParent "./" = "./.." | |
129 | andalso getParent "" = ".."); | |
130 | ||
131 | val test6a = | |
132 | tst' "test6a" (fn _ => | |
133 | concat("a", "b") = "a/b" | |
134 | andalso concat("a", "b/c") = "a/b/c" | |
135 | andalso concat("/", "b/c") = "/b/c" | |
136 | andalso concat("", "b/c") = "b/c" | |
137 | andalso concat("/a", "b/c") = "/a/b/c" | |
138 | andalso concat("a/", "b/c") = "a/b/c" | |
139 | andalso concat("a//", "b/c") = "a//b/c" | |
140 | andalso concat(".", "b/c") = "./b/c" | |
141 | andalso concat("a/b", "..") = "a/b/.." | |
142 | andalso concat("a/b", "../c") = "a/b/../c"); | |
143 | val test6b = tst0 "test6b" ((concat ("a", "/b") seq "WRONG") | |
144 | handle Path => "OK" | _ => "WRONG") | |
145 | ||
146 | val mkAbsolute = fn (p, r) => mkAbsolute {path = p, relativeTo = r} | |
147 | ||
148 | val test7a = | |
149 | tst' "test7a" (fn _ => | |
150 | mkAbsolute("/a/b", "/c/d") = "/a/b" | |
151 | andalso mkAbsolute("/", "/c/d") = "/" | |
152 | andalso mkAbsolute("a/b", "/c/d") = "/c/d/a/b"); | |
153 | val test7b = tst0 "test7b" ((mkAbsolute("a", "c/d") seq "WRONG") | |
154 | handle Path => "OK" | _ => "WRONG") | |
155 | val test7c = tst0 "test7c" ((mkAbsolute("/a", "c/d") seq "WRONG") | |
156 | handle Path => "OK" | _ => "WRONG") | |
157 | ||
158 | val mkRelative = fn (p, r) => mkRelative {path = p, relativeTo = r} | |
159 | ||
160 | val test8a = | |
161 | tst' "test8a" (fn _ => | |
162 | mkRelative("a/b", "/c/d") = "a/b" | |
163 | andalso mkRelative("/", "/a/b/c") = "../../.." | |
164 | andalso mkRelative("/a/", "/a/b/c") = "../../" | |
165 | andalso mkRelative("/a/b/", "/a/c") = "../b/" | |
166 | andalso mkRelative("/a/b", "/a/c/") = "../b" | |
167 | andalso mkRelative("/a/b/", "/a/c/") = "../b/" | |
168 | andalso mkRelative("/", "/") = "." | |
169 | andalso mkRelative("/", "/.") = "." | |
170 | andalso mkRelative("/", "/..") = "." | |
171 | andalso mkRelative("/", "/a") = ".." | |
172 | andalso mkRelative("/a/b/../c", "/a/d") = "../b/../c" | |
173 | andalso mkRelative("/a/b", "/c/d") = "../../a/b" | |
174 | andalso mkRelative("/c/a/b", "/c/d") = "../a/b" | |
175 | andalso mkRelative("/c/d/a/b", "/c/d") = "a/b"); | |
176 | val test8b = tst0 "test8b" ((mkRelative("/a", "c/d") seq "WRONG") | |
177 | handle Path => "OK" | _ => "WRONG") | |
178 | val test8c = tst0 "test8c" ((mkRelative("a", "c/d") seq "WRONG") | |
179 | handle Path => "OK" | _ => "WRONG") | |
180 | ||
181 | val test9a = let | |
182 | fun chkCanon (a, b) = | |
183 | (mkCanonical a = b) | |
184 | andalso (mkCanonical b = b) | |
185 | andalso (isCanonical b) | |
186 | in | |
187 | tst' "test9a" (fn _ => | |
188 | chkCanon("", ".") | |
189 | andalso chkCanon(".", ".") | |
190 | andalso chkCanon("./.", ".") | |
191 | andalso chkCanon("/.", "/") | |
192 | andalso chkCanon("..", "..") | |
193 | andalso chkCanon("../..", "../..") | |
194 | andalso chkCanon("b", "b") | |
195 | andalso chkCanon("a/b", "a/b") | |
196 | andalso chkCanon("/a/b", "/a/b") | |
197 | andalso chkCanon("a/b/", "a/b") | |
198 | andalso chkCanon("a/b//", "a/b") | |
199 | andalso chkCanon("a/../b", "b") | |
200 | andalso chkCanon("a/..", ".") | |
201 | andalso chkCanon("a/.", "a") | |
202 | andalso chkCanon("a/", "a") | |
203 | andalso chkCanon("/a/../b/", "/b") | |
204 | andalso chkCanon("/..", "/") | |
205 | andalso chkCanon("/../../a/b", "/a/b") | |
206 | andalso chkCanon("/./../../a/b", "/a/b") | |
207 | andalso chkCanon("/./../..", "/") | |
208 | andalso chkCanon("a/../b", "b") | |
209 | andalso chkCanon("a/./b", "a/b") | |
210 | andalso chkCanon("a////b", "a/b") | |
211 | andalso chkCanon("a////b", "a/b")) | |
212 | end | |
213 | ||
214 | val test10a = | |
215 | tst' "test10a" (fn _ => | |
216 | not (isCanonical "./." | |
217 | orelse isCanonical "/.." | |
218 | orelse isCanonical "/." | |
219 | orelse isCanonical "//" | |
220 | orelse isCanonical "a/.." | |
221 | orelse isCanonical "a//b" | |
222 | orelse isCanonical "a/." | |
223 | orelse isCanonical "a/b/" | |
224 | orelse isCanonical "a/..")) | |
225 | ||
226 | val test11a = | |
227 | tst' "test11a" (fn _ => | |
228 | splitDirFile "" = {dir = "", file = ""} | |
229 | andalso splitDirFile "." = {dir = "", file = "."} | |
230 | andalso splitDirFile ".." = {dir = "", file = ".."} | |
231 | andalso splitDirFile "b" = {dir = "", file = "b"} | |
232 | andalso splitDirFile "b/" = {dir = "b", file = ""} | |
233 | andalso splitDirFile "a/b" = {dir = "a", file = "b"} | |
234 | andalso splitDirFile "/a" = {dir = "/", file = "a"} | |
235 | andalso splitDirFile "/a/b" = {dir = "/a", file = "b"} | |
236 | andalso splitDirFile "/c/a/b" = {dir = "/c/a", file = "b"} | |
237 | andalso splitDirFile "/c/a/b/" = {dir = "/c/a/b", file = ""} | |
238 | andalso splitDirFile "/c/a/b.foo.bar" = {dir = "/c/a", file="b.foo.bar"} | |
239 | andalso splitDirFile "/c/a/b.foo" = {dir = "/c/a", file = "b.foo"}); | |
240 | ||
241 | (* | |
242 | val test11b = (splitDirFile "" seq "WRONG") | |
243 | handle Path => "OK" | _ => "WRONG"; | |
244 | *) | |
245 | ||
246 | val test12 = | |
247 | tst' "test12" (fn _ => | |
248 | List.all (fn (res, dir, file) => | |
249 | res = joinDirFile {dir = dir, file = file}) | |
250 | [("", "", ""), | |
251 | ("b", "", "b"), | |
252 | ("/", "/", ""), | |
253 | ("/b", "/", "b"), | |
254 | ("a/b", "a", "b"), | |
255 | ("/a/b", "/a", "b"), | |
256 | ("/c/a/b", "/c/a", "b"), | |
257 | ("/c/a/b/", "/c/a/b", ""), | |
258 | ("/c/a/b.foo.bar", "/c/a","b.foo.bar"), | |
259 | ("/c/a/b.foo", "/c/a", "b.foo")]) | |
260 | ||
261 | val test13 = | |
262 | tst' "test13" (fn _ => | |
263 | dir "b" = "" | |
264 | andalso dir "a/b" = "a" | |
265 | andalso dir "/" = "/" | |
266 | andalso dir "/b" = "/" | |
267 | andalso dir "/a/b" = "/a" | |
268 | andalso dir "/c/a/b" = "/c/a" | |
269 | andalso dir "/c/a/b/" = "/c/a/b" | |
270 | andalso dir "/c/a/b.foo.bar" = "/c/a" | |
271 | andalso dir "/c/a/b.foo" = "/c/a"); | |
272 | ||
273 | val test14 = | |
274 | tst' "test14" (fn _ => | |
275 | file "b" = "b" | |
276 | andalso file "a/b" = "b" | |
277 | andalso file "/" = "" | |
278 | andalso file "/b" = "b" | |
279 | andalso file "/a/b" = "b" | |
280 | andalso file "/c/a/b" = "b" | |
281 | andalso file "/c/a/b/" = "" | |
282 | andalso file "/c/a/b.foo.bar" = "b.foo.bar" | |
283 | andalso file "/c/a/b.foo" = "b.foo"); | |
284 | ||
285 | val test15 = | |
286 | tst' "test15" (fn _ => | |
287 | splitBaseExt "" = {base = "", ext = NONE} | |
288 | andalso splitBaseExt ".login" = {base = ".login", ext = NONE} | |
289 | andalso splitBaseExt "/.login" = {base = "/.login", ext = NONE} | |
290 | andalso splitBaseExt "a" = {base = "a", ext = NONE} | |
291 | andalso splitBaseExt "a." = {base = "a.", ext = NONE} | |
292 | andalso splitBaseExt "a.b" = {base = "a", ext = SOME "b"} | |
293 | andalso splitBaseExt "a.b.c" = {base = "a.b", ext = SOME "c"} | |
294 | andalso splitBaseExt "/a.b" = {base = "/a", ext = SOME "b"} | |
295 | andalso splitBaseExt "/c/a.b" = {base = "/c/a", ext = SOME "b"} | |
296 | andalso splitBaseExt "/c/a/b/.d" = {base = "/c/a/b/.d", ext = NONE} | |
297 | andalso splitBaseExt "/c.a/b.d" = {base = "/c.a/b", ext = SOME "d"} | |
298 | andalso splitBaseExt "/c.a/bd" = {base = "/c.a/bd", ext = NONE} | |
299 | andalso splitBaseExt "/c/a/b.foo.bar" = {base="/c/a/b.foo",ext=SOME "bar"} | |
300 | andalso splitBaseExt "/c/a/b.foo" = {base = "/c/a/b", ext = SOME "foo"}); | |
301 | ||
302 | val test16 = | |
303 | tst' "test16" (fn _ => | |
304 | "" = joinBaseExt {base = "", ext = NONE} | |
305 | andalso ".login" = joinBaseExt {base = ".login", ext = NONE} | |
306 | andalso "a" = joinBaseExt {base = "a", ext = NONE} | |
307 | andalso "a" = joinBaseExt {base = "a", ext = SOME ""} | |
308 | andalso "a.b" = joinBaseExt {base = "a", ext = SOME "b"} | |
309 | andalso "a.b.c" = joinBaseExt {base = "a.b", ext = SOME "c"} | |
310 | andalso "a.b.c.d" = joinBaseExt {base = "a.b", ext = SOME "c.d"} | |
311 | andalso "/a.b" = joinBaseExt {base = "/a", ext = SOME "b"} | |
312 | andalso "/c/a.b" = joinBaseExt {base = "/c/a", ext = SOME "b"} | |
313 | andalso "/c/a/b/.d" = joinBaseExt {base = "/c/a/b/", ext = SOME "d"} | |
314 | andalso "/c/a/b.foo.bar" = joinBaseExt {base="/c/a/b",ext=SOME "foo.bar"} | |
315 | andalso "/c/a/b.foo" = joinBaseExt {base = "/c/a/b", ext = SOME "foo"}); | |
316 | ||
317 | val test17 = | |
318 | tst' "test17" (fn _ => | |
319 | ext "" = NONE | |
320 | andalso ext ".login" = NONE | |
321 | andalso ext "/.login" = NONE | |
322 | andalso ext "a" = NONE | |
323 | andalso ext "a." = NONE | |
324 | andalso ext "a.b" = SOME "b" | |
325 | andalso ext "a.b.c" = SOME "c" | |
326 | andalso ext "a.b.c.d" = SOME "d" | |
327 | andalso ext "/a.b" = SOME "b" | |
328 | andalso ext "/c/a.b" = SOME "b" | |
329 | andalso ext "/c/a/b/.d" = NONE | |
330 | andalso ext "/c.a/b.d" = SOME "d" | |
331 | andalso ext "/c.a/bd" = NONE | |
332 | andalso ext "/c/a/b.foo.bar" = SOME "bar" | |
333 | andalso ext "/c/a/b.foo" = SOME "foo"); | |
334 | ||
335 | val test18 = | |
336 | tst' "test18" (fn _ => | |
337 | base "" = "" | |
338 | andalso base ".d" = ".d" | |
339 | andalso base ".login" = ".login" | |
340 | andalso base "/.login" = "/.login" | |
341 | andalso base "a" = "a" | |
342 | andalso base "a." = "a." | |
343 | andalso base "a.b" = "a" | |
344 | andalso base "a.b.c" = "a.b" | |
345 | andalso base "a.b.c.d" = "a.b.c" | |
346 | andalso base "/a.b" = "/a" | |
347 | andalso base "/c/a.b" = "/c/a" | |
348 | andalso base "/c/a/b/.d" = "/c/a/b/.d" | |
349 | andalso base "/c.a/b.d" = "/c.a/b" | |
350 | andalso base "/c.a/bd" = "/c.a/bd" | |
351 | andalso base "/c/a/b.foo.bar" = "/c/a/b.foo" | |
352 | andalso base "/c/a/b.foo" = "/c/a/b"); | |
353 | ||
354 | val test19 = | |
355 | tst' "test19" (fn () => validVolume{isAbs=false, vol=""} | |
356 | andalso validVolume{isAbs=true, vol=""} | |
357 | andalso not (validVolume{isAbs=true, vol="/"} | |
358 | orelse validVolume{isAbs=false, vol="/"} | |
359 | orelse validVolume{isAbs=true, vol="C:"} | |
360 | orelse validVolume{isAbs=false, vol="C:"} | |
361 | orelse validVolume{isAbs=true, vol=" "} | |
362 | orelse validVolume{isAbs=false, vol=" "})); | |
363 | in | |
364 | end |