Files
moxa/interp/interp_file_test.go
Marc Vertes 341c69d922 feat: configure stdin, stdout and stderr per interpreter
The goal is to provide greater control of input, output and error
streams of the interpreter. It is now possible to specify those
as options when creating a new interpreter. The provided values
are propagated to relevant stdlib symbols (i.e fmt.Print, etc).
Care is taken to not update the global variables os.Stdout, os.Stdin
and os.Stderr, as to not interfere with the host process.

The REPL function is now simplified. The deprecated version is removed.

The tests are updated to take advantage of the simplified access
to the interpreter output and errors.

Fixes #752.
2020-08-31 15:42:03 +02:00

99 lines
2.2 KiB
Go

package interp_test
import (
"bytes"
"go/build"
"go/parser"
"go/token"
"io/ioutil"
"os"
"path/filepath"
"strings"
"testing"
"github.com/containous/yaegi/interp"
"github.com/containous/yaegi/stdlib"
"github.com/containous/yaegi/stdlib/unsafe"
)
func TestFile(t *testing.T) {
filePath := "../_test/str.go"
runCheck(t, filePath)
baseDir := filepath.Join("..", "_test")
files, err := ioutil.ReadDir(baseDir)
if err != nil {
t.Fatal(err)
}
for _, file := range files {
if filepath.Ext(file.Name()) != ".go" {
continue
}
file := file
t.Run(file.Name(), func(t *testing.T) {
runCheck(t, filepath.Join(baseDir, file.Name()))
})
}
}
func runCheck(t *testing.T, p string) {
wanted, goPath, errWanted := wantedFromComment(p)
if wanted == "" {
t.Skip(p, "has no comment 'Output:' or 'Error:'")
}
wanted = strings.TrimSpace(wanted)
if goPath == "" {
goPath = build.Default.GOPATH
}
var stdout, stderr bytes.Buffer
i := interp.New(interp.Options{GoPath: goPath, Stdout: &stdout, Stderr: &stderr})
i.Use(interp.Symbols)
i.Use(stdlib.Symbols)
i.Use(unsafe.Symbols)
_, err := i.EvalPath(p)
if errWanted {
if err == nil {
t.Fatalf("got nil error, want: %q", wanted)
}
if res := strings.TrimSpace(err.Error()); !strings.Contains(res, wanted) {
t.Errorf("got %q, want: %q", res, wanted)
}
return
}
if err != nil {
t.Fatal(err)
}
if res := strings.TrimSpace(stdout.String()); res != wanted {
t.Errorf("\ngot: %q,\nwant: %q", res, wanted)
}
}
func wantedFromComment(p string) (res string, goPath string, err bool) {
fset := token.NewFileSet()
f, _ := parser.ParseFile(fset, p, nil, parser.ParseComments)
if len(f.Comments) == 0 {
return
}
text := f.Comments[len(f.Comments)-1].Text()
if strings.HasPrefix(text, "GOPATH:") {
parts := strings.SplitN(text, "\n", 2)
text = parts[1]
wd, err := os.Getwd()
if err != nil {
panic(err)
}
goPath = filepath.Join(wd, "../_test", strings.TrimPrefix(parts[0], "GOPATH:"))
}
if strings.HasPrefix(text, "Output:\n") {
return strings.TrimPrefix(text, "Output:\n"), goPath, false
}
if strings.HasPrefix(text, "Error:\n") {
return strings.TrimPrefix(text, "Error:\n"), goPath, true
}
return
}