2021-01-20 07:17:56 +08:00
|
|
|
package eval_test
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bytes"
|
|
|
|
"strings"
|
|
|
|
"testing"
|
|
|
|
|
2022-12-11 22:21:09 +08:00
|
|
|
"github.com/google/go-cmp/cmp"
|
2021-01-27 09:28:38 +08:00
|
|
|
. "src.elv.sh/pkg/eval"
|
2022-11-30 09:38:50 +08:00
|
|
|
. "src.elv.sh/pkg/eval/evaltest"
|
2021-01-27 09:28:38 +08:00
|
|
|
"src.elv.sh/pkg/parse"
|
2022-04-12 04:45:57 +08:00
|
|
|
"src.elv.sh/pkg/prog"
|
|
|
|
"src.elv.sh/pkg/testutil"
|
2021-01-20 07:17:56 +08:00
|
|
|
)
|
|
|
|
|
|
|
|
func TestDeprecatedBuiltin(t *testing.T) {
|
2024-01-02 23:11:38 +08:00
|
|
|
testCompileTimeDeprecation(t, "eawk", `the "eawk" command is deprecated`, 20)
|
2022-01-03 07:23:52 +08:00
|
|
|
|
2021-01-20 07:17:56 +08:00
|
|
|
// Deprecations of other builtins are implemented in the same way, so we
|
|
|
|
// don't test them repeatedly
|
|
|
|
}
|
|
|
|
|
|
|
|
func testCompileTimeDeprecation(t *testing.T, code, wantWarning string, level int) {
|
2021-04-09 06:57:40 +08:00
|
|
|
t.Helper()
|
2022-04-12 04:45:57 +08:00
|
|
|
testutil.Set(t, &prog.DeprecationLevel, level)
|
2021-01-20 07:17:56 +08:00
|
|
|
|
|
|
|
ev := NewEvaler()
|
|
|
|
errOutput := new(bytes.Buffer)
|
|
|
|
|
2022-12-11 22:21:09 +08:00
|
|
|
parseErr, _, compileErr := ev.Check(parse.Source{Name: "[test]", Code: code}, errOutput)
|
2021-01-20 07:17:56 +08:00
|
|
|
if parseErr != nil {
|
|
|
|
t.Errorf("got parse err %v", parseErr)
|
|
|
|
}
|
|
|
|
if compileErr != nil {
|
|
|
|
t.Errorf("got compile err %v", compileErr)
|
|
|
|
}
|
|
|
|
|
|
|
|
warning := errOutput.String()
|
|
|
|
if !strings.Contains(warning, wantWarning) {
|
|
|
|
t.Errorf("got warning %q, want warning containing %q", warning, wantWarning)
|
|
|
|
}
|
|
|
|
}
|
2022-11-30 09:38:50 +08:00
|
|
|
|
|
|
|
func TestMultipleCompileationErrors(t *testing.T) {
|
|
|
|
Test(t,
|
|
|
|
That("echo $x; echo $y").DoesNotCompile(
|
|
|
|
"variable $x not found",
|
|
|
|
"variable $y not found"),
|
|
|
|
)
|
|
|
|
}
|
2022-12-11 22:21:09 +08:00
|
|
|
|
|
|
|
var autofixTests = []struct {
|
|
|
|
Name string
|
|
|
|
Code string
|
|
|
|
|
|
|
|
WantAutofixes []string
|
|
|
|
}{
|
|
|
|
{
|
|
|
|
Name: "get variable from unimported builtin module",
|
|
|
|
Code: "echo $mod1:foo",
|
|
|
|
|
|
|
|
WantAutofixes: []string{"use mod1"},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Name: "set variable from unimported builtin module",
|
|
|
|
Code: "set mod1:foo = bar",
|
|
|
|
|
|
|
|
WantAutofixes: []string{"use mod1"},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Name: "tmp set variable from unimported builtin module",
|
|
|
|
Code: "tmp mod1:foo = bar",
|
|
|
|
|
|
|
|
WantAutofixes: []string{"use mod1"},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Name: "call command from unimported builtin module",
|
|
|
|
Code: "mod1:foo",
|
|
|
|
|
|
|
|
WantAutofixes: []string{"use mod1"},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Name: "no autofix for using variable from imported module",
|
|
|
|
Code: "use mod1; echo $mod1:foo",
|
|
|
|
|
|
|
|
WantAutofixes: nil,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Name: "no autofix for using variable from non-builtin module",
|
|
|
|
Code: "echo $mod-external:foo",
|
|
|
|
|
|
|
|
WantAutofixes: nil,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestAutofix(t *testing.T) {
|
|
|
|
ev := NewEvaler()
|
|
|
|
ev.AddModule("mod1", &Ns{})
|
|
|
|
for _, tc := range autofixTests {
|
|
|
|
t.Run(tc.Name, func(t *testing.T) {
|
|
|
|
_, autofixes, _ := ev.Check(parse.Source{Name: "[test]", Code: tc.Code}, nil)
|
|
|
|
if diff := cmp.Diff(tc.WantAutofixes, autofixes); diff != "" {
|
|
|
|
t.Errorf("autofixes (-want +got):\n%s", diff)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|