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