blob: 434468ff1f96841eb0707ab4de9f40966abc93d2 [file] [log] [blame]
// Copyright 2023 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package interp_test
import (
"path/filepath"
"reflect"
"strings"
"testing"
"golang.org/x/tools/internal/testenv"
)
func TestIssue69298(t *testing.T) {
testenv.NeedsGo1Point(t, 23)
goroot := makeGoroot(t)
run(t, filepath.Join("testdata", "fixedbugs", "issue69298.go"), goroot)
}
func TestRangeFunc(t *testing.T) {
testenv.NeedsGo1Point(t, 23)
goroot := makeGoroot(t)
out := run(t, filepath.Join("testdata", "rangefunc.go"), goroot)
// Check the output of the tests.
const (
RERR_DONE = "Saw expected panic: yield function called after range loop exit"
RERR_MISSING = "Saw expected panic: iterator call did not preserve panic"
RERR_EXHAUSTED = RERR_DONE // ssa does not distinguish. Same message as RERR_DONE.
CERR_DONE = "Saw expected panic: checked rangefunc error: loop iteration after body done"
CERR_EXHAUSTED = "Saw expected panic: checked rangefunc error: loop iteration after iterator exit"
CERR_MISSING = "Saw expected panic: checked rangefunc error: loop iterator swallowed panic"
panickyIterMsg = "Saw expected panic: Panicky iterator panicking"
)
expected := map[string][]string{
// rangefunc.go
"TestCheck": {"i = 45", CERR_DONE},
"TestCooperativeBadOfSliceIndex": {RERR_EXHAUSTED, "i = 36"},
"TestCooperativeBadOfSliceIndexCheck": {CERR_EXHAUSTED, "i = 36"},
"TestTrickyIterAll": {"i = 36", RERR_EXHAUSTED},
"TestTrickyIterOne": {"i = 1", RERR_EXHAUSTED},
"TestTrickyIterZero": {"i = 0", RERR_EXHAUSTED},
"TestTrickyIterZeroCheck": {"i = 0", CERR_EXHAUSTED},
"TestTrickyIterEcho": {
"first loop i=0",
"first loop i=1",
"first loop i=3",
"first loop i=6",
"i = 10",
"second loop i=0",
RERR_EXHAUSTED,
"end i=0",
},
"TestTrickyIterEcho2": {
"k=0,x=1,i=0",
"k=0,x=2,i=1",
"k=0,x=3,i=3",
"k=0,x=4,i=6",
"i = 10",
"k=1,x=1,i=0",
RERR_EXHAUSTED,
"end i=1",
},
"TestBreak1": {"[1 2 -1 1 2 -2 1 2 -3]"},
"TestBreak2": {"[1 2 -1 1 2 -2 1 2 -3]"},
"TestContinue": {"[-1 1 2 -2 1 2 -3 1 2 -4]"},
"TestBreak3": {"[100 10 2 4 200 10 2 4 20 2 4 300 10 2 4 20 2 4 30]"},
"TestBreak1BadA": {"[1 2 -1 1 2 -2 1 2 -3]", RERR_DONE},
"TestBreak1BadB": {"[1 2]", RERR_DONE},
"TestMultiCont0": {"[1000 10 2 4 2000]"},
"TestMultiCont1": {"[1000 10 2 4]", RERR_DONE},
"TestMultiCont2": {"[1000 10 2 4]", RERR_DONE},
"TestMultiCont3": {"[1000 10 2 4]", RERR_DONE},
"TestMultiBreak0": {"[1000 10 2 4]", RERR_DONE},
"TestMultiBreak1": {"[1000 10 2 4]", RERR_DONE},
"TestMultiBreak2": {"[1000 10 2 4]", RERR_DONE},
"TestMultiBreak3": {"[1000 10 2 4]", RERR_DONE},
"TestPanickyIterator1": {panickyIterMsg},
"TestPanickyIterator1Check": {panickyIterMsg},
"TestPanickyIterator2": {RERR_MISSING},
"TestPanickyIterator2Check": {CERR_MISSING},
"TestPanickyIterator3": {"[100 10 1 2 200 10 1 2]"},
"TestPanickyIterator3Check": {"[100 10 1 2 200 10 1 2]"},
"TestPanickyIterator4": {RERR_MISSING},
"TestPanickyIterator4Check": {CERR_MISSING},
"TestVeryBad1": {"[1 10]"},
"TestVeryBad2": {"[1 10]"},
"TestVeryBadCheck": {"[1 10]"},
"TestOk": {"[1 10]"},
"TestBreak1BadDefer": {RERR_DONE, "[1 2 -1 1 2 -2 1 2 -3 -30 -20 -10]"},
"TestReturns": {"[-1 1 2 -10]", "[-1 1 2 -10]", RERR_DONE, "[-1 1 2 -10]", RERR_DONE},
"TestGotoA": {"testGotoA1[-1 1 2 -2 1 2 -3 1 2 -4 -30 -20 -10]", "testGotoA2[-1 1 2 -2 1 2 -3 1 2 -4 -30 -20 -10]", RERR_DONE, "testGotoA3[-1 1 2 -10]", RERR_DONE},
"TestGotoB": {"testGotoB1[-1 1 2 999 -10]", "testGotoB2[-1 1 2 -10]", RERR_DONE, "testGotoB3[-1 1 2 -10]", RERR_DONE},
"TestPanicReturns": {
"Got expected 'f return'",
"Got expected 'g return'",
"Got expected 'h return'",
"Got expected 'k return'",
"Got expected 'j return'",
"Got expected 'm return'",
"Got expected 'n return and n closure return'",
},
}
got := make(map[string][]string)
for _, ln := range strings.Split(out, "\n") {
if ind := strings.Index(ln, " \t "); ind >= 0 {
n, m := ln[:ind], ln[ind+3:]
got[n] = append(got[n], m)
}
}
for n, es := range expected {
if gs := got[n]; !reflect.DeepEqual(es, gs) {
t.Errorf("Output of test %s did not match expected output %v. got %v", n, es, gs)
}
}
for n, gs := range got {
if expected[n] == nil {
t.Errorf("No expected output for test %s. got %v", n, gs)
}
}
}