Import Debian changes 20180207-1
[hcoop/debian/mlton.git] / regression / unixpath.sml
CommitLineData
7f918cf1
CE
1(* Auxiliary functions for test cases *)
2
3infix 1 seq
4fun e1 seq e2 = e2;
5fun check b = if b then "OK" else "WRONG";
6fun check' f = (if f () then "OK" else "WRONG") handle _ => "EXN";
7
8fun 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
14fun checkrange bounds = check o range bounds;
15
16fun tst0 s s' = print (s ^ " \t" ^ s' ^ "\n");
17fun tst s b = tst0 s (check b);
18fun tst' s f = tst0 s (check' f);
19
20fun tstrange s bounds = (tst s) o range bounds
21
22(* test/unixpath.sml 6 -- for Unix, 1995-05-23 *)
23
24val _ = print "\nFile unixpath.sml: Testing structure Path...\n"
25
26local
27 open OS.Path
28
29val test1a =
30 tst' "test1a" (fn _ => fromString "" = {isAbs=false, vol = "", arcs = []});
31val test1b =
32 tst' "test1b" (fn _ => fromString "/" = {isAbs=true, vol="", arcs=[""]});
33val test1c =
34 tst' "test1c" (fn _ => fromString "//" = {isAbs=true, vol="", arcs=["", ""]});
35val test1d =
36 tst' "test1d" (fn _ => fromString "a" = {isAbs=false, vol = "", arcs = ["a"]});
37val test1e =
38 tst' "test1e" (fn _ => fromString "/a" = {isAbs=true, vol="", arcs=["a"]});
39val test1f =
40 tst' "test1f" (fn _ => fromString "//a" = {isAbs=true, vol="", arcs=["","a"]});
41val test1g =
42 tst' "test1g" (fn _ => fromString "a/" = {isAbs=false, vol = "", arcs = ["a", ""]});
43val test1h =
44 tst' "test1h" (fn _ => fromString "a//" = {isAbs=false, vol = "", arcs = ["a", "", ""]});
45val test1i =
46 tst' "test1i" (fn _ => fromString "a/b" = {isAbs=false, vol = "", arcs = ["a", "b"]});
47val test1j =
48 tst' "test1j" (fn _ => fromString "a.b/c" = {isAbs=false, vol = "", arcs = ["a.b", "c"]});
49val test1k =
50 tst' "test1k" (fn _ => fromString "a.b/c/" = {isAbs=false, vol = "", arcs = ["a.b", "c", ""]});
51val test1l =
52 tst' "test1l" (fn _ => fromString "a/./c" = {isAbs=false, vol = "", arcs = ["a", ".", "c"]});
53val test1m =
54 tst' "test1m" (fn _ => fromString "a/../c" = {isAbs=false, vol = "", arcs = ["a", "..", "c"]});
55val test1n =
56 tst' "test1n" (fn _ => fromString "." = {isAbs=false, vol = "", arcs = ["."]});
57
58val test2a =
59 tst' "test2a" (fn _ => toString {isAbs=false, vol = "", arcs = []} = "");
60val test2b =
61 tst' "test2b" (fn _ => toString {isAbs=true, vol="", arcs=[]} = "/");
62val test2c =
63 tst' "test2c" (fn _ => toString {isAbs=true, vol="", arcs=["", ""]} = "//");
64val test2d =
65 tst' "test2d" (fn _ => toString {isAbs=false, vol = "", arcs = ["a"]} = "a");
66val test2e =
67 tst' "test2e" (fn _ => toString {isAbs=true, vol="", arcs=["a"]} = "/a");
68val test2f =
69 tst' "test2f" (fn _ => toString {isAbs=true, vol="", arcs=["","a"]} = "//a");
70val test2g =
71 tst' "test2g" (fn _ => toString {isAbs=false, vol = "", arcs = ["a", ""]} = "a/");
72val test2h =
73 tst' "test2h" (fn _ => toString {isAbs=false, vol = "", arcs = ["a", "", ""]} = "a//");
74val test2i =
75 tst' "test2i" (fn _ => toString {isAbs=false, vol = "", arcs = ["a", "b"]} = "a/b");
76val test2j =
77 tst' "test2j" (fn _ => toString {isAbs=false, vol = "", arcs = ["a.b", "c"]} = "a.b/c");
78val test2k =
79 tst' "test2k" (fn _ => toString {isAbs=false, vol = "", arcs = ["a.b", "c", ""]} = "a.b/c/");
80val test2l =
81 tst' "test2l" (fn _ => toString {isAbs=false, vol = "", arcs = ["a", ".", "c"]} = "a/./c");
82val test2m =
83 tst' "test2m" (fn _ => toString {isAbs=false, vol = "", arcs = ["a", "..", "c"]} = "a/../c");
84val test2n =
85 tst' "test2n" (fn _ => toString {isAbs=true, vol="", arcs=["a", "..", "c"]} = "/a/../c");
86val test2o = tst0 "test2o" ((toString {isAbs=false, vol = "", arcs = ["", "a"]} seq "WRONG")
87 handle Path => "OK" | _ => "WRONG")
88val test2p = tst0 "test2p" ((toString {isAbs=true, vol = "C:", arcs = ["windows"]} seq "WRONG")
89 handle Path => "OK" | _ => "WRONG")
90
91val test3b =
92 tst' "test3b" (fn _ => getVolume "/" = "");
93val test3c =
94 tst' "test3c" (fn _ => getVolume "//" = "");
95val test3d =
96 tst' "test3d" (fn _ => getVolume "a//b/c/" = "");
97val test3e =
98 tst' "test3e" (fn _ => getVolume "./" = "");
99val test3f =
100 tst' "test3f" (fn _ => getVolume "../" = "");
101val test3g =
102 tst' "test3g" (fn _ => getVolume "" = "");
103val test3h =
104 tst' "test3h" (fn _ => getVolume "C:" = "");
105
106val test4a =
107 tst' "test4a" (fn _ =>
108 List.all isRelative ["", ".", "..", "a//"]
109 andalso not (List.exists isRelative ["/", "/a", "//"]));
110val test4b =
111 tst' "test4b" (fn _ =>
112 List.all isAbsolute ["/", "/a", "//", "/.", "/.."]
113 andalso not (List.exists isAbsolute ["", ".", "..", "a//"]));
114
115val 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
131val 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");
143val test6b = tst0 "test6b" ((concat ("a", "/b") seq "WRONG")
144 handle Path => "OK" | _ => "WRONG")
145
146val mkAbsolute = fn (p, r) => mkAbsolute {path = p, relativeTo = r}
147
148val 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");
153val test7b = tst0 "test7b" ((mkAbsolute("a", "c/d") seq "WRONG")
154 handle Path => "OK" | _ => "WRONG")
155val test7c = tst0 "test7c" ((mkAbsolute("/a", "c/d") seq "WRONG")
156 handle Path => "OK" | _ => "WRONG")
157
158val mkRelative = fn (p, r) => mkRelative {path = p, relativeTo = r}
159
160val 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");
176val test8b = tst0 "test8b" ((mkRelative("/a", "c/d") seq "WRONG")
177 handle Path => "OK" | _ => "WRONG")
178val test8c = tst0 "test8c" ((mkRelative("a", "c/d") seq "WRONG")
179 handle Path => "OK" | _ => "WRONG")
180
181val 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
214val 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
226val 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(*
242val test11b = (splitDirFile "" seq "WRONG")
243 handle Path => "OK" | _ => "WRONG";
244*)
245
246val 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
261val 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
273val 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
285val 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
302val 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
317val 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
335val 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
354val 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=" "}));
363in
364end