open Lean open System.Uri ------------------------------------------------------------------------------ -- see https://github.com/python/cpython/blob/main/Lib/test/test_urllib.py def testEscaping := /- Uri character escaping includes UTF-8 encoding for the 😵 char! -/ assert! (pathToUri "/temp/test.xml?😵=2022") == "file:///temp/test.xml%3F%F0%9F%98%B5%3D2022" /- tilde is NOT escaped -/ assert! (pathToUri "~/git/lean4") == "file:///~/git/lean4" true def testNeverEscape := let do_not_quote := String.join ["ABCDEFGHIJKLMNOPQRSTUVWXYZ", "abcdefghijklmnopqrstuvwxyz", "0123456789", "_.-~<>\"{}|\\^`"] let result := escapeUri do_not_quote assert! result == do_not_quote true def testShouldEscape := let controls := String.mk ((List.range 31).map (fun c => Char.ofNat c)) let should_quote := String.join [controls, "#%[]", (Char.ofNat 127).toString] -- for 0x7F assert! should_quote.data.all (λ c => let x := (escapeUri c.toString) x.length == 3 && x.take 1 == "%") true def testPartialEscape := assert! (escapeUri "ab[]cd") == "ab%5B%5Dcd" true def testSpaceEscape := assert! (escapeUri " ") == "%20" true def testUnicodeEscape := assert! (escapeUri "😵") == "%F0%9F%98%B5" assert! (escapeUri "\u6f22\u5b57") == "%E6%BC%A2%E5%AD%97" true def testRoundTrip := assert! (fileUriToPath? (pathToUri "/temp/test.xml?😵=2022")) == "/temp/test.xml?😵=2022" true def testInvalidFileUri := assert! (fileUriToPath? "invalid") == none true def testUnescapePercent := assert! (unescapeUri "/temp/test%25.xml") == "/temp/test%.xml" true def testUnescapeSinglePercent := assert! (unescapeUri "%") == "%" true def testUnescapeBadHex := assert! (unescapeUri "%xab") == "%xab" assert! (unescapeUri "file://test%W9/%3Fa%3D123") == "file://test%W9/?a=123" true def testTruncatedEscape := assert! (unescapeUri "lean%4") == "lean%4" true def testUnescapeUnicode := assert! (unescapeUri "%F0%9F%98%B5") == "😵" assert! (unescapeUri "br%C3%BCckner") == "brückner" assert! (unescapeUri "br%C3%BCckner") == "brückner" assert! (unescapeUri "\u6f22%C3%BC") == "\u6f22\u00fc" true def testUnescapeMixedCase := assert! (unescapeUri "\u00Ab\u006A") == "«j" true def testShouldUnescape := let controls := String.mk ((List.range 31).map (fun c => Char.ofNat c)) let should_quote := String.join [controls, "#%[]", (Char.ofNat 127).toString] -- for 0x7F assert! should_quote == unescapeUri (escapeUri should_quote) true def testWindowsDriveLetter := if System.Platform.isWindows then assert! pathToUri ("c:" / "temp") == "file:///c%3A/temp" true else true def testWindowsDriveLetterRoundTrip := if System.Platform.isWindows then let x : System.FilePath := "c:" / "temp" / "test.lean" let r := pathToUri x let result := if r == "file:///c%3A/temp/test.lean" then match fileUriToPath? r with | none => "testWindowsDriveLetterEscaping fileUriToPath? returned none" | some y => if y.normalize.toString == x.normalize.toString then "" else s!"testWindowsDriveLetterEscaping '{x.normalize.toString}' != '{y.normalize.toString}'" else s!"testWindowsDriveLetterEscaping escaped to {r}" assert! result == "" true else true def TestUncRoundTrip := let results := ["file:///c:", "file:////folder/test", "file:///c:/foo/bar/spam.foo"].map (fun p => let result := (match fileUriToPath? p with | some uri => unescapeUri (pathToUri uri) | none => "fileUriToPath? failed") if result == p then "ok" else s!"mismatch {result} != {p}") let ok := (results.all (λ c => c == "ok")) assert! ok -- s!"the results are not as expected: {results}" true #eval testEscaping && testNeverEscape && testShouldEscape && testRoundTrip && testPartialEscape && testSpaceEscape && testUnicodeEscape && testInvalidFileUri && testUnescapePercent && testUnescapeSinglePercent && testUnescapeBadHex && testTruncatedEscape && testUnescapeUnicode && testUnescapeMixedCase && testShouldUnescape && testWindowsDriveLetterRoundTrip