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  }