Преглед на файлове

evaltest: Check that stderr is empty if PrintsStderrWith is not called.

Among other things, this will check for deprecation warnings. Also fix test code
that uses deprecated features.
Qi Xiao преди 2 години
родител
ревизия
957c8a7521

+ 1 - 1
pkg/eval/builtin_fn_cmd_unix_test.go

@@ -24,7 +24,7 @@ func TestSearchExternal(t *testing.T) {
 		// or /usr/bin. However, on all systems we currently support it will
 		// be in /bin and, possibly, /usr/bin. So ensure we limit the search
 		// to the one universal UNIX directory for basic commands.
-		That("E:PATH=/bin search-external sh").Puts("/bin/sh"),
+		That("{ tmp E:PATH = /bin;  search-external sh }").Puts("/bin/sh"),
 		// We should check for a specific error if the external command cannot
 		// be found. However, the current implementation of `search-external`
 		// returns the raw error returned by a Go runtime function over which

+ 2 - 1
pkg/eval/builtin_special_test.go

@@ -324,7 +324,8 @@ func TestTry(t *testing.T) {
 			Throws(ErrorWithMessage("final")),
 
 		// except is a deprecated synonym for catch
-		That("try { fail tr } except { put bad }").Puts("bad"),
+		That("try { fail tr } except { put bad }").
+			Puts("bad").PrintsStderrWith("deprecated"),
 		// Must have catch or finally
 		That("try { fail tr }").DoesNotCompile(),
 		// Rest variable not allowed

+ 13 - 7
pkg/eval/compile_effect_test.go

@@ -152,17 +152,23 @@ func TestCommand_Special(t *testing.T) {
 func TestCommand_LegacyTemporaryAssignment(t *testing.T) {
 	Test(t,
 		That("var a b = alice bob; {a,@b}=(put amy ben) put $a $@b; put $a $b").
-			Puts("amy", "ben", "alice", "bob"),
+			Puts("amy", "ben", "alice", "bob").PrintsStderrWith("deprecated"),
 		// Temporary assignment of list element.
-		That("var l = [a]; l[0]=x put $l[0]; put $l[0]").Puts("x", "a"),
+		That("var l = [a]; l[0]=x put $l[0]; put $l[0]").
+			Puts("x", "a").PrintsStderrWith("deprecated"),
 		// Temporary assignment of map element.
-		That("var m = [&k=v]; m[k]=v2 put $m[k]; put $m[k]").Puts("v2", "v"),
+		That("var m = [&k=v]; m[k]=v2 put $m[k]; put $m[k]").
+			Puts("v2", "v").PrintsStderrWith("deprecated"),
 		// Temporary assignment before special form.
-		That("li=[foo bar] for x $li { put $x }").Puts("foo", "bar"),
+		That("li=[foo bar] for x $li { put $x }").
+			Puts("foo", "bar").PrintsStderrWith("deprecated"),
 		// Multiple LHSs in temporary assignments.
-		That("{a b}={foo bar} put $a $b").Puts("foo", "bar"),
-		That("@a=(put a b) put $@a").Puts("a", "b"),
-		That("{a,@b}=(put a b c) put $@b").Puts("b", "c"),
+		That("{a b}={foo bar} put $a $b").
+			Puts("foo", "bar").PrintsStderrWith("deprecated"),
+		That("@a=(put a b) put $@a").
+			Puts("a", "b").PrintsStderrWith("deprecated"),
+		That("{a,@b}=(put a b c) put $@b").
+			Puts("b", "c").PrintsStderrWith("deprecated"),
 		// Using syntax of temporary assignment for non-temporary assignment no
 		// longer compiles
 		That("x=y").DoesNotCompile(),

+ 2 - 2
pkg/eval/eval_test.go

@@ -48,8 +48,8 @@ func TestEvalTimeDeprecate(t *testing.T) {
 		}))
 	},
 		That("dep").PrintsStderrWith("deprecated"),
-		// Deprecation message is only shown once.
-		That("dep 2> tmp.txt; dep").DoesNothing(),
+		// Deprecation message from the same location is only shown once.
+		That("fn f { dep }", "f 2> tmp.txt; f").DoesNothing(),
 	)
 }
 

+ 9 - 2
pkg/eval/evaltest/evaltest.go

@@ -160,8 +160,15 @@ func TestWithSetup(t *testing.T, setup func(*eval.Evaler), tests ...Case) {
 			if !bytes.Equal(tc.want.BytesOut, r.BytesOut) {
 				t.Errorf("got bytes out %q, want %q", r.BytesOut, tc.want.BytesOut)
 			}
-			if !bytes.Contains(r.StderrOut, tc.want.StderrOut) {
-				t.Errorf("got stderr out %q, want %q", r.StderrOut, tc.want.StderrOut)
+			if tc.want.StderrOut == nil {
+				if len(r.StderrOut) > 0 {
+					t.Errorf("got stderr out %q, want empty", r.StderrOut)
+				}
+			} else {
+				if !bytes.Contains(r.StderrOut, tc.want.StderrOut) {
+					t.Errorf("got stderr out %q, want output containing %q",
+						r.StderrOut, tc.want.StderrOut)
+				}
 			}
 			if !matchErr(tc.want.CompilationError, r.CompilationError) {
 				t.Errorf("got compilation error %v, want %v",

+ 2 - 1
pkg/eval/external_cmd_test.go

@@ -31,6 +31,7 @@ func TestBuiltinFnExternal(t *testing.T) {
 		//
 		// The command shouldn't be found when run so we should get an
 		// exception along the lines of "executable file not found in $PATH".
-		That("var e = (external true); E:PATH=/ $e").Throws(ErrorWithType(&exec.Error{})),
+		That("var e = (external true); { tmp E:PATH = /; $e }").
+			Throws(ErrorWithType(&exec.Error{})),
 	)
 }

+ 1 - 2
pkg/eval/frame.go

@@ -234,8 +234,7 @@ func (fm *Frame) Deprecate(msg string, ctx *diag.Context, minLevel int) {
 		return
 	}
 	if ctx == nil {
-		fmt.Fprintf(fm.ErrorFile(), "deprecation: \033[31;1m%s\033[m\n", msg)
-		return
+		ctx = fm.traceback.Head
 	}
 	if fm.Evaler.registerDeprecation(deprecation{ctx.Name, ctx.Ranging, msg}) {
 		err := diag.Error{Type: "deprecation", Message: msg, Context: *ctx}

+ 14 - 8
pkg/eval/pwd_test.go

@@ -22,8 +22,8 @@ func TestBuiltinPwd(t *testing.T) {
 	dir2 := filepath.Join(tmpHome, "dir2")
 
 	Test(t,
-		That(`pwd=dir1 put $pwd; put $pwd`).Puts(dir1, tmpHome),
-		That(`pwd=(num 1) put $pwd`).Throws(vars.ErrPathMustBeString, "pwd"),
+		That(`{ tmp pwd = dir1; put $pwd }; put $pwd`).Puts(dir1, tmpHome),
+		That(`{ tmp pwd = (num 1); put $pwd }`).Throws(vars.ErrPathMustBeString),
 	)
 
 	// We could separate these two test variants into separate unit test
@@ -31,15 +31,21 @@ func TestBuiltinPwd(t *testing.T) {
 	// equivalence between the two environments harder to see.
 	if runtime.GOOS == "windows" {
 		Test(t,
-			That(`cd $E:HOME\dir2; pwd=$E:HOME put $pwd; put $pwd`).Puts(tmpHome, dir2),
-			That(`cd $E:HOME\dir2; pwd=..\dir1 put $pwd; put $pwd`).Puts(dir1, dir2),
-			That(`cd $E:HOME\dir1; pwd=..\dir2 put $pwd; put $pwd`).Puts(dir2, dir1),
+			That(`cd $E:HOME\dir2; { tmp pwd = $E:HOME; put $pwd }; put $pwd`).
+				Puts(tmpHome, dir2),
+			That(`cd $E:HOME\dir2; { tmp pwd = ..\dir1; put $pwd }; put $pwd`).
+				Puts(dir1, dir2),
+			That(`cd $E:HOME\dir1; { tmp pwd = ..\dir2; put $pwd }; put $pwd`).
+				Puts(dir2, dir1),
 		)
 	} else {
 		Test(t,
-			That(`cd ~/dir2; pwd=~ put $pwd; put $pwd`).Puts(tmpHome, dir2),
-			That(`cd ~/dir2; pwd=~/dir1 put $pwd; put $pwd`).Puts(dir1, dir2),
-			That(`cd ~/dir1; pwd=../dir2 put $pwd; put $pwd`).Puts(dir2, dir1),
+			That(`cd ~/dir2; { tmp pwd = ~; put $pwd }; put $pwd`).
+				Puts(tmpHome, dir2),
+			That(`cd ~/dir2; { tmp pwd = ~/dir1; put $pwd }; put $pwd`).
+				Puts(dir1, dir2),
+			That(`cd ~/dir1; { tmp pwd = ../dir2; put $pwd }; put $pwd`).
+				Puts(dir2, dir1),
 		)
 	}
 }

+ 7 - 7
pkg/mods/unix/umask_test.go

@@ -24,22 +24,22 @@ func TestUmask(t *testing.T) {
 		That(`put $unix:umask`).Puts(`0o075`),
 		// Verify that a temporary umask change is reverted upon completion of
 		// the command. Both for builtin and external commands.
-		That(`unix:umask=012 put $unix:umask`).Puts(`0o012`),
-		That(`unix:umask=0o23 /bin/sh -c 'umask'`).Prints("0023\n"),
-		That(`unix:umask=56 /bin/sh -c 'umask'`).Prints("0056\n"),
+		That(`{ tmp unix:umask = 012; put $unix:umask }`).Puts(`0o012`),
+		That(`{ tmp unix:umask = 0o23; /bin/sh -c 'umask' }`).Prints("0023\n"),
+		That(`{ tmp unix:umask = 56; /bin/sh -c 'umask' }`).Prints("0056\n"),
 		That(`put $unix:umask`).Puts(`0o075`),
 		// People won't normally use non-octal bases but make sure these cases
 		// behave sensibly given that Elvish supports number literals with an
 		// explicit base.
-		That(`unix:umask=0x43 /bin/sh -c 'umask'`).Prints("0103\n"),
-		That(`unix:umask=0b001010100 sh -c 'umask'`).Prints("0124\n"),
+		That(`{ tmp unix:umask = 0x43; /bin/sh -c 'umask' }`).Prints("0103\n"),
+		That(`{ tmp unix:umask = 0b001010100; sh -c 'umask' }`).Prints("0124\n"),
 		// We should be back to our expected umask given the preceding tests
 		// applied a temporary change to that process attribute.
 		That(`put $unix:umask`).Puts(`0o075`),
 		// An explicit num (int) value is handled correctly.
-		That(`unix:umask=(num 0o123) put $unix:umask`).Puts(`0o123`),
+		That(`{ tmp unix:umask = (num 0o123); put $unix:umask }`).Puts(`0o123`),
 		// An explicit float64 value is handled correctly.
-		That(`unix:umask=(float64 0o17) put $unix:umask`).Puts(`0o017`),
+		That(`{ tmp unix:umask = (float64 0o17); put $unix:umask }`).Puts(`0o017`),
 		That(`set unix:umask = (float64 123.4)`).Throws(
 			errs.BadValue{What: "umask", Valid: validUmaskMsg, Actual: "123.4"}),