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