elvish/pkg/shell/shell_test.go

138 lines
3.5 KiB
Go

package shell
import (
"os"
"path/filepath"
"testing"
"src.elv.sh/pkg/env"
"src.elv.sh/pkg/must"
. "src.elv.sh/pkg/prog/progtest"
"src.elv.sh/pkg/testutil"
)
func TestShell_LibPath_XDGPaths(t *testing.T) {
xdgConfigHome := testutil.TempDir(t)
testutil.ApplyDirIn(testutil.Dir{
"elvish": testutil.Dir{
"lib": testutil.Dir{
"a.elv": "echo a from xdg-config-home",
},
},
}, xdgConfigHome)
testutil.Setenv(t, env.XDG_CONFIG_HOME, xdgConfigHome)
xdgDataHome := testutil.TempDir(t)
testutil.ApplyDirIn(testutil.Dir{
"elvish": testutil.Dir{
"lib": testutil.Dir{
"a.elv": "echo a from xdg-data-home",
"b.elv": "echo b from xdg-data-home",
},
},
}, xdgDataHome)
testutil.Setenv(t, env.XDG_DATA_HOME, xdgDataHome)
xdgDataDir1 := testutil.TempDir(t)
testutil.ApplyDirIn(testutil.Dir{
"elvish": testutil.Dir{
"lib": testutil.Dir{
"a.elv": "echo a from xdg-data-dir-1",
"b.elv": "echo b from xdg-data-dir-1",
"c.elv": "echo c from xdg-data-dir-1",
},
},
}, xdgDataDir1)
xdgDataDir2 := testutil.TempDir(t)
testutil.ApplyDirIn(testutil.Dir{
"elvish": testutil.Dir{
"lib": testutil.Dir{
"a.elv": "echo a from xdg-data-dir-2",
"b.elv": "echo b from xdg-data-dir-2",
"c.elv": "echo c from xdg-data-dir-2",
"d.elv": "echo d from xdg-data-dir-2",
},
},
}, xdgDataDir2)
testutil.Setenv(t, env.XDG_DATA_DIRS,
xdgDataDir1+string(filepath.ListSeparator)+xdgDataDir2)
Test(t, &Program{},
ThatElvish("-c", "use a").WritesStdout("a from xdg-config-home\n"),
ThatElvish("-c", "use b").WritesStdout("b from xdg-data-home\n"),
ThatElvish("-c", "use c").WritesStdout("c from xdg-data-dir-1\n"),
ThatElvish("-c", "use d").WritesStdout("d from xdg-data-dir-2\n"),
)
}
func TestShell_LibPath_Legacy(t *testing.T) {
home := setupCleanHomePaths(t)
must.WriteFile(filepath.Join(home, ".elvish", "lib", "a.elv"), "echo mod a")
Test(t, &Program{},
ThatElvish("-c", "use a").
WritesStdout("mod a\n").
WritesStderrContaining(legacyLibPathWarning),
)
}
// Most high-level tests against Program are specific to either script mode or
// interactive mode, and are found in script_test.go and interact_test.go.
var incSHLVLTests = []struct {
name string
old string
unset bool
wantNew string
}{
{name: "normal", old: "10", wantNew: "11"},
{name: "unset", unset: true, wantNew: "1"},
{name: "invalid", old: "invalid", wantNew: "1"},
// Other shells don't agree on what to do when SHLVL is negative:
//
// ~> E:SHLVL=-100 bash -c 'echo $SHLVL'
// 0
// ~> E:SHLVL=-100 zsh -c 'echo $SHLVL'
// -99
// ~> E:SHLVL=-100 fish -c 'echo $SHLVL'
// 1
//
// Elvish follows Zsh here.
{name: "negative", old: "-100", wantNew: "-99"},
}
func TestShell_SHLVL(t *testing.T) {
for _, test := range incSHLVLTests {
t.Run(test.name, func(t *testing.T) {
if test.unset {
testutil.Unsetenv(t, env.SHLVL)
} else {
testutil.Setenv(t, env.SHLVL, test.old)
}
Test(t, &Program{},
ThatElvish("-c", "print $E:SHLVL").WritesStdout(test.wantNew))
// Test that state of SHLVL is restored.
restored, restoredSet := os.LookupEnv(env.SHLVL)
if test.unset {
if restoredSet {
t.Errorf("SHLVL not unset")
}
} else {
if restored != test.old {
t.Errorf("SHLVL restored to %q, want %q", restored, test.old)
}
}
})
}
}
// Common test utilities.
func setupCleanHomePaths(t testutil.Cleanuper) string {
testutil.Unsetenv(t, env.XDG_CONFIG_HOME)
testutil.Unsetenv(t, env.XDG_DATA_HOME)
return testutil.TempHome(t)
}