github.com/kolbycrouch/elvish@v0.14.1-0.20210614162631-215b9ac1c423/pkg/eval/mods/path/path_test.go (about) 1 package path 2 3 import ( 4 "os" 5 "path/filepath" 6 "regexp" 7 "testing" 8 9 "src.elv.sh/pkg/eval" 10 "src.elv.sh/pkg/eval/errs" 11 . "src.elv.sh/pkg/eval/evaltest" 12 "src.elv.sh/pkg/testutil" 13 ) 14 15 var testDir = testutil.Dir{ 16 "d": testutil.Dir{ 17 "f": "", 18 }, 19 } 20 21 // A regular expression fragment to match the directory part of an absolute 22 // path. QuoteMeta is needed since on Windows filepath.Separator is '\\'. 23 var anyDir = "^.*" + regexp.QuoteMeta(string(filepath.Separator)) 24 25 func TestPath(t *testing.T) { 26 tmpdir, cleanup := testutil.InTestDir() 27 defer cleanup() 28 testutil.ApplyDir(testDir) 29 30 absPath, err := filepath.Abs("a/b/c.png") 31 if err != nil { 32 panic("unable to convert a/b/c.png to an absolute path") 33 } 34 35 TestWithSetup(t, importPathModule, 36 // This block of tests is not meant to be comprehensive. Their primary purpose is to simply 37 // ensure the Elvish command is correctly mapped to the relevant Go function. We assume the 38 // Go function behaves correctly. 39 That("path:abs a/b/c.png").Puts(absPath), 40 That("path:base a/b/d.png").Puts("d.png"), 41 That("path:clean ././x").Puts("x"), 42 That("path:clean a/b/.././c").Puts(filepath.Join("a", "c")), 43 That("path:dir a/b/d.png").Puts(filepath.Join("a", "b")), 44 That("path:ext a/b/e.png").Puts(".png"), 45 That("path:ext a/b/s").Puts(""), 46 That("path:is-abs a/b/s").Puts(false), 47 That("path:is-abs "+absPath).Puts(true), 48 49 // Elvish "path:" module functions that are not trivial wrappers around a Go stdlib function 50 // should have comprehensive tests below this comment. 51 That("path:is-dir "+tmpdir).Puts(true), 52 That("path:is-dir d").Puts(true), 53 That("path:is-dir d/f").Puts(false), 54 That("path:is-dir bad").Puts(false), 55 56 That("path:is-regular "+tmpdir).Puts(false), 57 That("path:is-regular d").Puts(false), 58 That("path:is-regular d/f").Puts(true), 59 That("path:is-regular bad").Puts(false), 60 61 // Verify the commands for creating temporary filesystem objects work correctly. 62 That("x = (path:temp-dir)", "rmdir $x", "put $x").Puts( 63 MatchingRegexp{Pattern: anyDir + `elvish-.*$`}), 64 That("x = (path:temp-dir 'x-*.y')", "rmdir $x", "put $x").Puts( 65 MatchingRegexp{Pattern: anyDir + `x-.*\.y$`}), 66 That("x = (path:temp-dir &dir=. 'x-*.y')", "rmdir $x", "put $x").Puts( 67 MatchingRegexp{Pattern: `^x-.*\.y$`}), 68 That("x = (path:temp-dir &dir=.)", "rmdir $x", "put $x").Puts( 69 MatchingRegexp{Pattern: `^elvish-.*$`}), 70 That("path:temp-dir a b").Throws( 71 errs.ArityMismatch{What: "arguments here", ValidLow: 0, ValidHigh: 1, Actual: 2}, 72 "path:temp-dir a b"), 73 74 That("f = (path:temp-file)", "fclose $f", "put $f[fd]", "rm $f[name]"). 75 Puts(-1), 76 That("f = (path:temp-file)", "put $f[name]", "fclose $f", "rm $f[name]"). 77 Puts(MatchingRegexp{Pattern: anyDir + `elvish-.*$`}), 78 That("f = (path:temp-file 'x-*.y')", "put $f[name]", "fclose $f", "rm $f[name]"). 79 Puts(MatchingRegexp{Pattern: anyDir + `x-.*\.y$`}), 80 That("f = (path:temp-file &dir=. 'x-*.y')", "put $f[name]", "fclose $f", "rm $f[name]"). 81 Puts(MatchingRegexp{Pattern: `^x-.*\.y$`}), 82 That("f = (path:temp-file &dir=.)", "put $f[name]", "fclose $f", "rm $f[name]"). 83 Puts(MatchingRegexp{Pattern: `^elvish-.*$`}), 84 That("path:temp-file a b").Throws( 85 errs.ArityMismatch{What: "arguments here", ValidLow: 0, ValidHigh: 1, Actual: 2}, 86 "path:temp-file a b"), 87 ) 88 } 89 90 var symlinks = []struct { 91 path string 92 target string 93 }{ 94 {"d/s-f", "f"}, 95 {"s-d", "d"}, 96 {"s-d-f", "d/f"}, 97 {"s-bad", "bad"}, 98 } 99 100 func TestPath_Symlink(t *testing.T) { 101 _, cleanup := testutil.InTestDir() 102 defer cleanup() 103 testutil.ApplyDir(testDir) 104 // testutil.ApplyDir(testDirSymlinks) 105 for _, link := range symlinks { 106 err := os.Symlink(link.target, link.path) 107 if err != nil { 108 // Creating symlinks requires a special permission on Windows. If 109 // the user doesn't have that permission, just skip the whole test. 110 t.Skip(err) 111 } 112 } 113 114 TestWithSetup(t, importPathModule, 115 That("path:eval-symlinks d/f").Puts(filepath.Join("d", "f")), 116 That("path:eval-symlinks d/s-f").Puts(filepath.Join("d", "f")), 117 That("path:eval-symlinks s-d/f").Puts(filepath.Join("d", "f")), 118 That("path:eval-symlinks s-bad").Throws(AnyError), 119 120 That("path:is-dir s-d").Puts(false), 121 That("path:is-dir s-d &follow-symlink").Puts(true), 122 That("path:is-dir s-d-f").Puts(false), 123 That("path:is-dir s-d-f &follow-symlink").Puts(false), 124 That("path:is-dir s-bad").Puts(false), 125 That("path:is-dir s-bad &follow-symlink").Puts(false), 126 That("path:is-dir bad").Puts(false), 127 That("path:is-dir bad &follow-symlink").Puts(false), 128 129 That("path:is-regular s-d").Puts(false), 130 That("path:is-regular s-d &follow-symlink").Puts(false), 131 That("path:is-regular s-d-f").Puts(false), 132 That("path:is-regular s-d-f &follow-symlink").Puts(true), 133 That("path:is-regular s-bad").Puts(false), 134 That("path:is-regular s-bad &follow-symlink").Puts(false), 135 That("path:is-regular bad").Puts(false), 136 That("path:is-regular bad &follow-symlink").Puts(false), 137 ) 138 } 139 140 func importPathModule(ev *eval.Evaler) { 141 ev.AddGlobal(eval.NsBuilder{}.AddNs("path", Ns).Ns()) 142 }