gitlab.com/ethan.reesor/vscode-notebooks/yaegi@v0.0.0-20220417214422-5c573557938e/interp/interp_file_test.go (about) 1 package interp_test 2 3 import ( 4 "bytes" 5 "go/build" 6 "go/parser" 7 "go/token" 8 "os" 9 "path/filepath" 10 "strings" 11 "testing" 12 13 "gitlab.com/ethan.reesor/vscode-notebooks/yaegi/interp" 14 "gitlab.com/ethan.reesor/vscode-notebooks/yaegi/stdlib" 15 "gitlab.com/ethan.reesor/vscode-notebooks/yaegi/stdlib/unsafe" 16 ) 17 18 func TestFile(t *testing.T) { 19 filePath := "../_test/str.go" 20 runCheck(t, filePath) 21 22 defer func() { 23 _ = os.Setenv("YAEGI_SPECIAL_STDIO", "0") 24 }() 25 _ = os.Setenv("YAEGI_SPECIAL_STDIO", "1") 26 27 baseDir := filepath.Join("..", "_test") 28 files, err := os.ReadDir(baseDir) 29 if err != nil { 30 t.Fatal(err) 31 } 32 for _, file := range files { 33 if filepath.Ext(file.Name()) != ".go" { 34 continue 35 } 36 file := file 37 t.Run(file.Name(), func(t *testing.T) { 38 runCheck(t, filepath.Join(baseDir, file.Name())) 39 }) 40 } 41 } 42 43 func runCheck(t *testing.T, p string) { 44 t.Helper() 45 46 wanted, goPath, errWanted := wantedFromComment(p) 47 if wanted == "" { 48 t.Skip(p, "has no comment 'Output:' or 'Error:'") 49 } 50 wanted = strings.TrimSpace(wanted) 51 52 if goPath == "" { 53 goPath = build.Default.GOPATH 54 } 55 var stdout, stderr bytes.Buffer 56 i := interp.New(interp.Options{GoPath: goPath, Stdout: &stdout, Stderr: &stderr}) 57 if err := i.Use(interp.Symbols); err != nil { 58 t.Fatal(err) 59 } 60 if err := i.Use(stdlib.Symbols); err != nil { 61 t.Fatal(err) 62 } 63 if err := i.Use(unsafe.Symbols); err != nil { 64 t.Fatal(err) 65 } 66 67 _, err := i.EvalPath(p) 68 if errWanted { 69 if err == nil { 70 t.Fatalf("got nil error, want: %q", wanted) 71 } 72 if res := strings.TrimSpace(err.Error()); !strings.Contains(res, wanted) { 73 t.Errorf("got %q, want: %q", res, wanted) 74 } 75 return 76 } 77 78 if err != nil { 79 t.Fatal(err) 80 } 81 82 if res := strings.TrimSpace(stdout.String()); res != wanted { 83 t.Errorf("\ngot: %q,\nwant: %q", res, wanted) 84 } 85 } 86 87 func wantedFromComment(p string) (res string, goPath string, err bool) { 88 fset := token.NewFileSet() 89 f, _ := parser.ParseFile(fset, p, nil, parser.ParseComments) 90 if len(f.Comments) == 0 { 91 return 92 } 93 text := f.Comments[len(f.Comments)-1].Text() 94 if strings.HasPrefix(text, "GOPATH:") { 95 parts := strings.SplitN(text, "\n", 2) 96 text = parts[1] 97 wd, err := os.Getwd() 98 if err != nil { 99 panic(err) 100 } 101 goPath = filepath.Join(wd, "../_test", strings.TrimPrefix(parts[0], "GOPATH:")) 102 } 103 if strings.HasPrefix(text, "Output:\n") { 104 return strings.TrimPrefix(text, "Output:\n"), goPath, false 105 } 106 if strings.HasPrefix(text, "Error:\n") { 107 return strings.TrimPrefix(text, "Error:\n"), goPath, true 108 } 109 return 110 }