#lang planet chongkai/sml
(* Auxiliary functions for test cases *)
infix 1 seq
fun e1 seq e2 = e2fun check b = if b then "OK" else "WRONG"fun check' f = (if f () then "OK" else "WRONG") handle _ => "EXN"
fun range (from, to) p =
let open Int
in
(from > to) orelse (p from) andalso (range (from+1, to) p)
end
fun checkrange bounds = check o range bounds
fun tst0 s s' = print (s ^ " \t" ^ s' ^ "\n")fun tst s b = tst0 s (check b)fun tst' s f = tst0 s (check' f)
fun tstrange s bounds = (tst s) o range bounds
(* test/unixpath.sml 6 -- for Unix, 1995-05-23 *)
val _ = print "\nFile unixpath.sml: Testing structure Path...\n"
local
open Path
val test1a =
tst' "test1a" (fn _ => fromString "" = {isAbs=false, vol = "", arcs = []})val test1b =
tst' "test1b" (fn _ => fromString "/" = {isAbs=true, vol="", arcs=[""]})val test1c =
tst' "test1c" (fn _ => fromString "//" = {isAbs=true, vol="", arcs=["", ""]})val test1d =
tst' "test1d" (fn _ => fromString "a" = {isAbs=false, vol = "", arcs = ["a"]})val test1e =
tst' "test1e" (fn _ => fromString "/a" = {isAbs=true, vol="", arcs=["a"]})val test1f =
tst' "test1f" (fn _ => fromString "//a" = {isAbs=true, vol="", arcs=["","a"]})val test1g =
tst' "test1g" (fn _ => fromString "a/" = {isAbs=false, vol = "", arcs = ["a", ""]})val test1h =
tst' "test1h" (fn _ => fromString "a//" = {isAbs=false, vol = "", arcs = ["a", "", ""]})val test1i =
tst' "test1i" (fn _ => fromString "a/b" = {isAbs=false, vol = "", arcs = ["a", "b"]})val test1j =
tst' "test1j" (fn _ => fromString "a.b/c" = {isAbs=false, vol = "", arcs = ["a.b", "c"]})val test1k =
tst' "test1k" (fn _ => fromString "a.b/c/" = {isAbs=false, vol = "", arcs = ["a.b", "c", ""]})val test1l =
tst' "test1l" (fn _ => fromString "a/./c" = {isAbs=false, vol = "", arcs = ["a", ".", "c"]})val test1m =
tst' "test1m" (fn _ => fromString "a/../c" = {isAbs=false, vol = "", arcs = ["a", "..", "c"]})val test1n =
tst' "test1n" (fn _ => fromString "." = {isAbs=false, vol = "", arcs = ["."]})
val test2a =
tst' "test2a" (fn _ => toString {isAbs=false, vol = "", arcs = []} = "")val test2b =
tst' "test2b" (fn _ => toString {isAbs=true, vol="", arcs=[]} = "/")val test2c =
tst' "test2c" (fn _ => toString {isAbs=true, vol="", arcs=["", ""]} = "//")val test2d =
tst' "test2d" (fn _ => toString {isAbs=false, vol = "", arcs = ["a"]} = "a")val test2e =
tst' "test2e" (fn _ => toString {isAbs=true, vol="", arcs=["a"]} = "/a")val test2f =
tst' "test2f" (fn _ => toString {isAbs=true, vol="", arcs=["","a"]} = "//a")val test2g =
tst' "test2g" (fn _ => toString {isAbs=false, vol = "", arcs = ["a", ""]} = "a/")val test2h =
tst' "test2h" (fn _ => toString {isAbs=false, vol = "", arcs = ["a", "", ""]} = "a//")val test2i =
tst' "test2i" (fn _ => toString {isAbs=false, vol = "", arcs = ["a", "b"]} = "a/b")val test2j =
tst' "test2j" (fn _ => toString {isAbs=false, vol = "", arcs = ["a.b", "c"]} = "a.b/c")val test2k =
tst' "test2k" (fn _ => toString {isAbs=false, vol = "", arcs = ["a.b", "c", ""]} = "a.b/c/")val test2l =
tst' "test2l" (fn _ => toString {isAbs=false, vol = "", arcs = ["a", ".", "c"]} = "a/./c")val test2m =
tst' "test2m" (fn _ => toString {isAbs=false, vol = "", arcs = ["a", "..", "c"]} = "a/../c")val test2n =
tst' "test2n" (fn _ => toString {isAbs=true, vol="", arcs=["a", "..", "c"]} = "/a/../c")val test2o = tst0 "test2o" ((toString {isAbs=false, vol = "", arcs = ["", "a"]} seq "WRONG")
handle Path => "OK" | _ => "WRONG")
val test2p = tst0 "test2p" ((toString {isAbs=true, vol = "C:", arcs = ["windows"]} seq "WRONG")
handle Path => "OK" | _ => "WRONG")
val test3b =
tst' "test3b" (fn _ => getVolume "/" = "")val test3c =
tst' "test3c" (fn _ => getVolume "//" = "")val test3d =
tst' "test3d" (fn _ => getVolume "a//b/c/" = "")val test3e =
tst' "test3e" (fn _ => getVolume "./" = "")val test3f =
tst' "test3f" (fn _ => getVolume "../" = "")val test3g =
tst' "test3g" (fn _ => getVolume "" = "")val test3h =
tst' "test3h" (fn _ => getVolume "C:" = "")
val test4a =
tst' "test4a" (fn _ =>
List.all isRelative ["", ".", "..", "a//"]
andalso not (List.exists isRelative ["/", "/a", "//"]))val test4b =
tst' "test4b" (fn _ =>
List.all isAbsolute ["/", "/a", "//", "/.", "/.."]
andalso not (List.exists isAbsolute ["", ".", "..", "a//"]))
val test5a =
tst' "test5a" (fn _ =>
getParent "/" = "/"
andalso getParent "a" = "."
andalso getParent "a/" = "a/.."
andalso getParent "a///" = "a///.."
andalso getParent "a/b" = "a"
andalso getParent "a/b/" = "a/b/.."
andalso getParent "/a/b" = "/a"
andalso getParent "/a/b/" = "/a/b/.."
andalso getParent ".." = "../.."
andalso getParent "." = ".."
andalso getParent "../" = "../.."
andalso getParent "./" = "./.."
andalso getParent "" = "..")
val test6a =
tst' "test6a" (fn _ =>
concat("a", "b") = "a/b"
andalso concat("a", "b/c") = "a/b/c"
andalso concat("/", "b/c") = "/b/c"
andalso concat("", "b/c") = "b/c"
andalso concat("/a", "b/c") = "/a/b/c"
andalso concat("a/", "b/c") = "a/b/c"
andalso concat("a//", "b/c") = "a//b/c"
andalso concat(".", "b/c") = "./b/c"
andalso concat("a/b", "..") = "a/b/.."
andalso concat("a/b", "../c") = "a/b/../c")val test6b = tst0 "test6b" ((concat ("a", "/b") seq "WRONG")
handle Path => "OK" | _ => "WRONG")
val test7a =
tst' "test7a" (fn _ =>
mkAbsolute{path="/a/b", relativeTo="/c/d"} = "/a/b"
andalso mkAbsolute{path="/", relativeTo="/c/d"} = "/"
andalso mkAbsolute{path="a/b", relativeTo="/c/d"} = "/c/d/a/b")val test7b = tst0 "test7b" ((mkAbsolute{path="a", relativeTo="c/d"} seq "WRONG")
handle Path => "OK" | _ => "WRONG")
val test7c = tst0 "test7c" ((mkAbsolute{path="/a", relativeTo="c/d"} seq "WRONG")
handle Path => "OK" | _ => "WRONG")
val test8a =
tst' "test8a" (fn _ =>
mkRelative{path="a/b", relativeTo="/c/d"} = "a/b"
andalso mkRelative{path="/", relativeTo="/a/b/c"} = "../../.."
andalso mkRelative{path="/a/", relativeTo="/a/b/c"} = "../../"
andalso mkRelative{path="/a/b/", relativeTo="/a/c"} = "../b/"
andalso mkRelative{path="/a/b", relativeTo="/a/c/"} = "../b"
andalso mkRelative{path="/a/b/", relativeTo="/a/c/"} = "../b/"
andalso mkRelative{path="/", relativeTo="/"} = "."
andalso mkRelative{path="/", relativeTo="/."} = "."
andalso mkRelative{path="/", relativeTo="/.."} = "."
andalso mkRelative{path="/", relativeTo="/a"} = ".."
andalso mkRelative{path="/a/b/../c", relativeTo="/a/d"} = "../b/../c"
andalso mkRelative{path="/a/b", relativeTo="/c/d"} = "../../a/b"
andalso mkRelative{path="/c/a/b", relativeTo="/c/d"} = "../a/b"
andalso mkRelative{path="/c/d/a/b", relativeTo="/c/d"} = "a/b")val test8b = tst0 "test8b" ((mkRelative{path="/a", relativeTo="c/d"} seq "WRONG")
handle Path => "OK" | _ => "WRONG")
val test8c = tst0 "test8c" ((mkRelative{path="a", relativeTo="c/d"} seq "WRONG")
handle Path => "OK" | _ => "WRONG")
val test9a = let
fun chkCanon (a, b) =
(mkCanonical a = b)
andalso (mkCanonical b = b)
andalso (isCanonical b)
in
tst' "test9a" (fn _ =>
chkCanon("", ".")
andalso chkCanon(".", ".")
andalso chkCanon("./.", ".")
andalso chkCanon("/.", "/")
andalso chkCanon("..", "..")
andalso chkCanon("../..", "../..")
andalso chkCanon("b", "b")
andalso chkCanon("a/b", "a/b")
andalso chkCanon("/a/b", "/a/b")
andalso chkCanon("a/b/", "a/b")
andalso chkCanon("a/b//", "a/b")
andalso chkCanon("a/../b", "b")
andalso chkCanon("a/..", ".")
andalso chkCanon("a/.", "a")
andalso chkCanon("a/", "a")
andalso chkCanon("/a/../b/", "/b")
andalso chkCanon("/..", "/")
andalso chkCanon("/../../a/b", "/a/b")
andalso chkCanon("/./../../a/b", "/a/b")
andalso chkCanon("/./../..", "/")
andalso chkCanon("a/../b", "b")
andalso chkCanon("a/./b", "a/b")
andalso chkCanon("a////b", "a/b")
andalso chkCanon("a////b", "a/b"))
end
val test10a =
tst' "test10a" (fn _ =>
not (isCanonical "./."
orelse isCanonical "/.."
orelse isCanonical "/."
orelse isCanonical "//"
orelse isCanonical "a/.."
orelse isCanonical "a//b"
orelse isCanonical "a/."
orelse isCanonical "a/b/"
orelse isCanonical "a/.."))
val test11a =
tst' "test11a" (fn _ =>
splitDirFile "" = {dir = "", file = ""}
andalso splitDirFile "." = {dir = "", file = "."}
andalso splitDirFile ".." = {dir = "", file = ".."}
andalso splitDirFile "b" = {dir = "", file = "b"}
andalso splitDirFile "b/" = {dir = "b", file = ""}
andalso splitDirFile "a/b" = {dir = "a", file = "b"}
andalso splitDirFile "/a" = {dir = "/", file = "a"}
andalso splitDirFile "/a/b" = {dir = "/a", file = "b"}
andalso splitDirFile "/c/a/b" = {dir = "/c/a", file = "b"}
andalso splitDirFile "/c/a/b/" = {dir = "/c/a/b", file = ""}
andalso splitDirFile "/c/a/b.foo.bar" = {dir = "/c/a", file="b.foo.bar"}
andalso splitDirFile "/c/a/b.foo" = {dir = "/c/a", file = "b.foo"})
(*
val test11b = (splitDirFile "" seq "WRONG")
handle Path => "OK" | _ => "WRONG"*)
val test12 =
tst' "test12" (fn _ =>
"" = joinDirFile {dir = "", file = ""}
andalso "b" = joinDirFile {dir = "", file = "b"}
andalso "/" = joinDirFile {dir = "/", file = ""}
andalso "/b" = joinDirFile {dir = "/", file = "b"}
andalso "a/b" = joinDirFile {dir = "a", file = "b"}
andalso "/a/b" = joinDirFile {dir = "/a", file = "b"}
andalso "/c/a/b" = joinDirFile {dir = "/c/a", file = "b"}
andalso "/c/a/b/" = joinDirFile {dir = "/c/a/b", file = ""}
andalso "/c/a/b.foo.bar" = joinDirFile {dir = "/c/a", file="b.foo.bar"}
andalso "/c/a/b.foo" = joinDirFile {dir = "/c/a", file = "b.foo"})
val test13 =
tst' "test13" (fn _ =>
dir "b" = ""
andalso dir "a/b" = "a"
andalso dir "/" = "/"
andalso dir "/b" = "/"
andalso dir "/a/b" = "/a"
andalso dir "/c/a/b" = "/c/a"
andalso dir "/c/a/b/" = "/c/a/b"
andalso dir "/c/a/b.foo.bar" = "/c/a"
andalso dir "/c/a/b.foo" = "/c/a")
val test14 =
tst' "test14" (fn _ =>
file "b" = "b"
andalso file "a/b" = "b"
andalso file "/" = ""
andalso file "/b" = "b"
andalso file "/a/b" = "b"
andalso file "/c/a/b" = "b"
andalso file "/c/a/b/" = ""
andalso file "/c/a/b.foo.bar" = "b.foo.bar"
andalso file "/c/a/b.foo" = "b.foo")
val test15 =
tst' "test15" (fn _ =>
splitBaseExt "" = {base = "", ext = NONE}
andalso splitBaseExt ".login" = {base = ".login", ext = NONE}
andalso splitBaseExt "/.login" = {base = "/.login", ext = NONE}
andalso splitBaseExt "a" = {base = "a", ext = NONE}
andalso splitBaseExt "a." = {base = "a.", ext = NONE}
andalso splitBaseExt "a.b" = {base = "a", ext = SOME "b"}
andalso splitBaseExt "a.b.c" = {base = "a.b", ext = SOME "c"}
andalso splitBaseExt "/a.b" = {base = "/a", ext = SOME "b"}
andalso splitBaseExt "/c/a.b" = {base = "/c/a", ext = SOME "b"}
andalso splitBaseExt "/c/a/b/.d" = {base = "/c/a/b/.d", ext = NONE}
andalso splitBaseExt "/c.a/b.d" = {base = "/c.a/b", ext = SOME "d"}
andalso splitBaseExt "/c.a/bd" = {base = "/c.a/bd", ext = NONE}
andalso splitBaseExt "/c/a/b.foo.bar" = {base="/c/a/b.foo",ext=SOME "bar"}
andalso splitBaseExt "/c/a/b.foo" = {base = "/c/a/b", ext = SOME "foo"})
val test16 =
tst' "test16" (fn _ =>
"" = joinBaseExt {base = "", ext = NONE}
andalso ".login" = joinBaseExt {base = ".login", ext = NONE}
andalso "a" = joinBaseExt {base = "a", ext = NONE}
andalso "a" = joinBaseExt {base = "a", ext = SOME ""}
andalso "a.b" = joinBaseExt {base = "a", ext = SOME "b"}
andalso "a.b.c" = joinBaseExt {base = "a.b", ext = SOME "c"}
andalso "a.b.c.d" = joinBaseExt {base = "a.b", ext = SOME "c.d"}
andalso "/a.b" = joinBaseExt {base = "/a", ext = SOME "b"}
andalso "/c/a.b" = joinBaseExt {base = "/c/a", ext = SOME "b"}
andalso "/c/a/b/.d" = joinBaseExt {base = "/c/a/b/", ext = SOME "d"}
andalso "/c/a/b.foo.bar" = joinBaseExt {base="/c/a/b",ext=SOME "foo.bar"}
andalso "/c/a/b.foo" = joinBaseExt {base = "/c/a/b", ext = SOME "foo"})
val test17 =
tst' "test17" (fn _ =>
ext "" = NONE
andalso ext ".login" = NONE
andalso ext "/.login" = NONE
andalso ext "a" = NONE
andalso ext "a." = NONE
andalso ext "a.b" = SOME "b"
andalso ext "a.b.c" = SOME "c"
andalso ext "a.b.c.d" = SOME "d"
andalso ext "/a.b" = SOME "b"
andalso ext "/c/a.b" = SOME "b"
andalso ext "/c/a/b/.d" = NONE
andalso ext "/c.a/b.d" = SOME "d"
andalso ext "/c.a/bd" = NONE
andalso ext "/c/a/b.foo.bar" = SOME "bar"
andalso ext "/c/a/b.foo" = SOME "foo")
val test18 =
tst' "test18" (fn _ =>
base "" = ""
andalso base ".d" = ".d"
andalso base ".login" = ".login"
andalso base "/.login" = "/.login"
andalso base "a" = "a"
andalso base "a." = "a."
andalso base "a.b" = "a"
andalso base "a.b.c" = "a.b"
andalso base "a.b.c.d" = "a.b.c"
andalso base "/a.b" = "/a"
andalso base "/c/a.b" = "/c/a"
andalso base "/c/a/b/.d" = "/c/a/b/.d"
andalso base "/c.a/b.d" = "/c.a/b"
andalso base "/c.a/bd" = "/c.a/bd"
andalso base "/c/a/b.foo.bar" = "/c/a/b.foo"
andalso base "/c/a/b.foo" = "/c/a/b")
val test19 =
tst' "test19" (fn () => validVolume{isAbs=false, vol=""}
andalso validVolume{isAbs=true, vol=""}
andalso not (validVolume{isAbs=true, vol="/"}
orelse validVolume{isAbs=false, vol="/"}
orelse validVolume{isAbs=true, vol="C:"}
orelse validVolume{isAbs=false, vol="C:"}
orelse validVolume{isAbs=true, vol=" "}
orelse validVolume{isAbs=false, vol=" "}))in
end