diff --git a/_test/m1/main.go b/_test/m1/main.go new file mode 100644 index 000000000..6cc630e34 --- /dev/null +++ b/_test/m1/main.go @@ -0,0 +1,14 @@ +package main + +import ( + "fmt" + "testing" +) + +func main() { + fmt.Println("vim-go") +} + +func TestWeird(t *testing.T) { + fmt.Println("in TestWeird") +} diff --git a/_test/m1/main_test.go b/_test/m1/main_test.go new file mode 100644 index 000000000..9c5627cc1 --- /dev/null +++ b/_test/m1/main_test.go @@ -0,0 +1,17 @@ +package main + +import ( + "fmt" + "math/rand" + "testing" +) + +func TestMain(t *testing.T) { + fmt.Println("in test") +} + +func BenchmarkMain(b *testing.B) { + for i := 0; i < b.N; i++ { + rand.Int() + } +} diff --git a/cmd/goexports/goexports.go b/cmd/goexports/goexports.go index 48dd48433..ee350d16c 100644 --- a/cmd/goexports/goexports.go +++ b/cmd/goexports/goexports.go @@ -108,9 +108,9 @@ func main() { var oFile string if pkgIdent == "syscall" { - oFile = strings.Replace(importPath, "/", "_", -1) + "_" + goos + "_" + goarch + ".go" + oFile = strings.ReplaceAll(importPath, "/", "_") + "_" + goos + "_" + goarch + ".go" } else { - oFile = strings.Replace(importPath, "/", "_", -1) + ".go" + oFile = strings.ReplaceAll(importPath, "/", "_") + ".go" } prefix := runtime.Version() diff --git a/cmd/yaegi/extract.go b/cmd/yaegi/extract.go index 3603a7310..7f2bc37ab 100644 --- a/cmd/yaegi/extract.go +++ b/cmd/yaegi/extract.go @@ -58,7 +58,7 @@ func extractCmd(arg []string) error { continue } - oFile := strings.Replace(importPath, "/", "_", -1) + ".go" + oFile := strings.ReplaceAll(importPath, "/", "_") + ".go" f, err := os.Create(oFile) if err != nil { return err diff --git a/cmd/yaegi/help.go b/cmd/yaegi/help.go index 15057a12a..dd195f315 100644 --- a/cmd/yaegi/help.go +++ b/cmd/yaegi/help.go @@ -36,7 +36,7 @@ func help(arg []string) error { case Run: return run([]string{"-h"}) case Test: - return fmt.Errorf("help: test not implemented") + return test([]string{"-h"}) default: return fmt.Errorf("help: invalid yaegi command: %v", cmd) } diff --git a/cmd/yaegi/run.go b/cmd/yaegi/run.go index 15cb5494d..f08841fe6 100644 --- a/cmd/yaegi/run.go +++ b/cmd/yaegi/run.go @@ -57,11 +57,13 @@ func run(arg []string) error { if cmd != "" { _, err = i.Eval(cmd) + showError(err) } if len(args) == 0 { if interactive || cmd == "" { _, err = i.REPL() + showError(err) } return err } @@ -71,40 +73,27 @@ func run(arg []string) error { os.Args = arg[1:] flag.CommandLine = flag.NewFlagSet(path, flag.ExitOnError) - if isPackageName(path) { - err = runPackage(i, path) + if isFile(path) { + err = runFile(i, path) } else { - if isDir(path) { - err = runDir(i, path) - } else { - err = runFile(i, path) - } + _, err = i.EvalPath(path) } + showError(err) + if err != nil { return err } if interactive { _, err = i.REPL() + showError(err) } return err } -func isPackageName(path string) bool { - return !strings.HasPrefix(path, "/") && !strings.HasPrefix(path, "./") && !strings.HasPrefix(path, "../") && !strings.HasSuffix(path, ".go") -} - -func isDir(path string) bool { - fi, err := os.Lstat(path) - return err == nil && fi.IsDir() -} - -func runPackage(i *interp.Interpreter, path string) error { - return fmt.Errorf("runPackage not implemented") -} - -func runDir(i *interp.Interpreter, path string) error { - return fmt.Errorf("runDir not implemented") +func isFile(path string) bool { + fi, err := os.Stat(path) + return err == nil && fi.Mode().IsRegular() } func runFile(i *interp.Interpreter, path string) error { @@ -117,15 +106,20 @@ func runFile(i *interp.Interpreter, path string) error { // Allow executable go scripts, Have the same behavior as in interactive mode. s = strings.Replace(s, "#!", "//", 1) _, err = i.Eval(s) - } else { - // Files not starting with "#!" are supposed to be pure Go, directly Evaled. - _, err := i.EvalPath(path) - if err != nil { - fmt.Println(err) - if p, ok := err.(interp.Panic); ok { - fmt.Println(string(p.Stack)) - } - } + return err } + + // Files not starting with "#!" are supposed to be pure Go, directly Evaled. + _, err = i.EvalPath(path) return err } + +func showError(err error) { + if err == nil { + return + } + fmt.Fprintln(os.Stderr, err) + if p, ok := err.(interp.Panic); ok { + fmt.Fprintln(os.Stderr, string(p.Stack)) + } +} diff --git a/cmd/yaegi/test.go b/cmd/yaegi/test.go new file mode 100644 index 000000000..2b7d4500d --- /dev/null +++ b/cmd/yaegi/test.go @@ -0,0 +1,131 @@ +package main + +import ( + "flag" + "fmt" + "go/build" + "os" + "regexp" + "strings" + "testing" + + "github.com/containous/yaegi/interp" + "github.com/containous/yaegi/stdlib" + "github.com/containous/yaegi/stdlib/syscall" + "github.com/containous/yaegi/stdlib/unrestricted" + "github.com/containous/yaegi/stdlib/unsafe" +) + +func test(arg []string) (err error) { + var ( + bench string + benchmem bool + benchtime string + count string + cpu string + failfast bool + run string + short bool + tags string + useUnrestricted bool + useUnsafe bool + useSyscall bool + timeout string + verbose bool + ) + + tflag := flag.NewFlagSet("test", flag.ContinueOnError) + tflag.StringVar(&bench, "bench", "", "Run only those benchmarks matching a regular expression.") + tflag.BoolVar(&benchmem, "benchmem", false, "Print memory allocation statistics for benchmarks.") + tflag.StringVar(&benchtime, "benchtime", "", "Run enough iterations of each benchmark to take t.") + tflag.StringVar(&count, "count", "", "Run each test and benchmark n times (default 1).") + tflag.StringVar(&cpu, "cpu", "", "Specify a list of GOMAXPROCS values for which the tests or benchmarks should be executed.") + tflag.BoolVar(&failfast, "failfast", false, "Do not start new tests after the first test failure.") + tflag.StringVar(&run, "run", "", "Run only those tests matching a regular expression.") + tflag.BoolVar(&short, "short", false, "Tell long-running tests to shorten their run time.") + tflag.StringVar(&tags, "tags", "", "Set a list of build tags.") + tflag.StringVar(&timeout, "timeout", "", "If a test binary runs longer than duration d, panic.") + tflag.BoolVar(&useUnrestricted, "unrestricted", false, "Include unrestricted symbols.") + tflag.BoolVar(&useUnsafe, "unsafe", false, "Include usafe symbols.") + tflag.BoolVar(&useSyscall, "syscall", false, "Include syscall symbols.") + tflag.BoolVar(&verbose, "v", false, "Verbose output: log all tests as they are run.") + tflag.Usage = func() { + fmt.Println("Usage: yaegi test [options] [path]") + fmt.Println("Options:") + tflag.PrintDefaults() + } + if err = tflag.Parse(arg); err != nil { + return err + } + args := tflag.Args() + path := "." + if len(args) > 0 { + path = args[0] + } + + // Overwrite os.Args with correct flags to setup testing.Init. + tf := []string{""} + if bench != "" { + tf = append(tf, "-test.bench", bench) + } + if benchmem { + tf = append(tf, "-test.benchmem") + } + if benchtime != "" { + tf = append(tf, "-test.benchtime", benchtime) + } + if count != "" { + tf = append(tf, "-test.count", count) + } + if cpu != "" { + tf = append(tf, "-test.cpu", cpu) + } + if failfast { + tf = append(tf, "-test.failfast") + } + if run != "" { + tf = append(tf, "-test.run", run) + } + if short { + tf = append(tf, "-test.short") + } + if timeout != "" { + tf = append(tf, "-test.timeout", timeout) + } + if verbose { + tf = append(tf, "-test.v") + } + testing.Init() + os.Args = tf + flag.Parse() + + i := interp.New(interp.Options{GoPath: build.Default.GOPATH, BuildTags: strings.Split(tags, ",")}) + i.Use(stdlib.Symbols) + i.Use(interp.Symbols) + if useSyscall { + i.Use(syscall.Symbols) + } + if useUnrestricted { + i.Use(unrestricted.Symbols) + } + if useUnsafe { + i.Use(unsafe.Symbols) + } + if err = i.EvalTest(path); err != nil { + return err + } + + benchmarks := []testing.InternalBenchmark{} + tests := []testing.InternalTest{} + for name, sym := range i.Symbols(path) { + switch fun := sym.Interface().(type) { + case func(*testing.B): + benchmarks = append(benchmarks, testing.InternalBenchmark{name, fun}) + case func(*testing.T): + tests = append(tests, testing.InternalTest{name, fun}) + } + } + + testing.Main(regexp.MatchString, tests, benchmarks, nil) + return nil +} diff --git a/cmd/yaegi/yaegi.go b/cmd/yaegi/yaegi.go index b50615d58..7377e78f3 100644 --- a/cmd/yaegi/yaegi.go +++ b/cmd/yaegi/yaegi.go @@ -118,7 +118,7 @@ func main() { case Run: err = run(os.Args[2:]) case Test: - err = fmt.Errorf("test not implemented") + err = test(os.Args[2:]) default: // If no command is given, fallback to default "run" command. // This allows scripts starting with "#!/usr/bin/env yaegi", diff --git a/interp/build.go b/interp/build.go index 17b837561..1f28f1fc6 100644 --- a/interp/build.go +++ b/interp/build.go @@ -5,6 +5,7 @@ import ( "go/build" "go/parser" "path" + "path/filepath" "strconv" "strings" ) @@ -129,12 +130,15 @@ func goMinorVersion(ctx *build.Context) int { } // skipFile returns true if file should be skipped. -func skipFile(ctx *build.Context, p string) bool { +func skipFile(ctx *build.Context, p string, skipTest bool) bool { if !strings.HasSuffix(p, ".go") { return true } p = strings.TrimSuffix(path.Base(p), ".go") - if strings.HasSuffix(p, "_test") { + if pp := filepath.Base(p); strings.HasPrefix(pp, "_") || strings.HasPrefix(pp, ".") { + return true + } + if skipTest && strings.HasSuffix(p, "_test") { return true } i := strings.Index(p, "_") diff --git a/interp/build_test.go b/interp/build_test.go index 2388f8355..8c89d9ac9 100644 --- a/interp/build_test.go +++ b/interp/build_test.go @@ -74,7 +74,7 @@ func TestBuildFile(t *testing.T) { for _, test := range tests { test := test t.Run(test.src, func(t *testing.T) { - if r := skipFile(&ctx, test.src); r != test.res { + if r := skipFile(&ctx, test.src, NoTest); r != test.res { t.Errorf("got %v, want %v", r, test.res) } }) diff --git a/interp/dot.go b/interp/dot.go index 3e90b3c7d..5222b045b 100644 --- a/interp/dot.go +++ b/interp/dot.go @@ -19,7 +19,7 @@ func (n *node) astDot(out io.Writer, name string) { var label string switch n.kind { case basicLit, identExpr: - label = strings.Replace(n.ident, "\"", "\\\"", -1) + label = strings.ReplaceAll(n.ident, "\"", "\\\"") default: if n.action != aNop { label = n.action.String() diff --git a/interp/gta.go b/interp/gta.go index 53aa05d31..963ae0d7e 100644 --- a/interp/gta.go +++ b/interp/gta.go @@ -216,7 +216,7 @@ func (interp *Interpreter) gta(root *node, rpath, importPath string) ([]*node, e err = n.cfgErrorf("%s redeclared in this block", name) return false } - } else if pkgName, err = interp.importSrc(rpath, ipath); err == nil { + } else if pkgName, err = interp.importSrc(rpath, ipath, NoTest); err == nil { sc.types = interp.universe.types switch name { case "_": // no import of symbols diff --git a/interp/interp.go b/interp/interp.go index 021e1da8f..4c26e2b0b 100644 --- a/interp/interp.go +++ b/interp/interp.go @@ -157,6 +157,11 @@ const ( // source file has not been specified for an Eval. // TODO(mpl): something even more special as a name? DefaultSourceName = "_.go" + + // Test is the value to pass to EvalPath to activate evaluation of test functions. + Test = false + // NoTest is the value to pass to EvalPath to skip evaluation of test functions. + NoTest = true ) // Symbols exposes interpreter values. @@ -361,25 +366,21 @@ func (interp *Interpreter) resizeFrame() { interp.frame.data = data } -func (interp *Interpreter) main() *node { - interp.mutex.RLock() - defer interp.mutex.RUnlock() - if m, ok := interp.scopes[mainID]; ok && m.sym[mainID] != nil { - return m.sym[mainID].node - } - return nil -} - // Eval evaluates Go code represented as a string. Eval returns the last result // computed by the interpreter, and a non nil error in case of failure. func (interp *Interpreter) Eval(src string) (res reflect.Value, err error) { return interp.eval(src, "", true) } -// EvalPath evaluates Go code located at path. EvalPath returns the last result -// computed by the interpreter, and a non nil error in case of failure. +// EvalPath evaluates Go code located at path and returns the last result computed +// by the interpreter, and a non nil error in case of failure. +// The main function of the main package is executed if present. func (interp *Interpreter) EvalPath(path string) (res reflect.Value, err error) { - // TODO(marc): implement eval of a directory, package and tests. + if !isFile(path) { + _, err := interp.importSrc(mainID, path, NoTest) + return res, err + } + b, err := ioutil.ReadFile(path) if err != nil { return res, err @@ -387,6 +388,49 @@ func (interp *Interpreter) EvalPath(path string) (res reflect.Value, err error) return interp.eval(string(b), path, false) } +// EvalTest evaluates Go code located at path, including test files with "_test.go" suffix. +// A non nil error is returned in case of failure. +// The main function, test functions and benchmark functions are internally compiled but not +// executed. Test functions can be retrieved using the Symbol() method. +func (interp *Interpreter) EvalTest(path string) error { + _, err := interp.importSrc(mainID, path, Test) + return err +} + +// Symbols returns a map of interpreter exported symbol values for the given path. +func (interp *Interpreter) Symbols(path string) map[string]reflect.Value { + m := map[string]reflect.Value{} + + interp.mutex.RLock() + if interp.scopes[path] == nil { + interp.mutex.RUnlock() + return m + } + sym := interp.scopes[path].sym + interp.mutex.RUnlock() + + for n, s := range sym { + if !canExport(n) { + // Skip private non-exported symbols. + continue + } + switch s.kind { + case constSym: + m[n] = s.rval + case funcSym: + m[n] = genFunctionWrapper(s.node)(interp.frame) + case varSym: + m[n] = interp.frame.data[s.index] + } + } + return m +} + +func isFile(path string) bool { + fi, err := os.Stat(path) + return err == nil && fi.Mode().IsRegular() +} + func (interp *Interpreter) eval(src, name string, inc bool) (res reflect.Value, err error) { if name != "" { interp.name = name @@ -426,7 +470,7 @@ func (interp *Interpreter) eval(src, name string, inc bool) (res reflect.Value, return res, err } - // Annotate AST with CFG infos + // Annotate AST with CFG informations. initNodes, err := interp.cfg(root, pkgName) if err != nil { if interp.cfgDot { @@ -439,25 +483,25 @@ func (interp *Interpreter) eval(src, name string, inc bool) (res reflect.Value, return res, err } - // Add main to list of functions to run, after all inits - if m := interp.main(); m != nil { - initNodes = append(initNodes, m) - } - if root.kind != fileStmt { - // REPL may skip package statement + // REPL may skip package statement. setExec(root.start) } interp.mutex.Lock() + gs := interp.scopes[pkgName] if interp.universe.sym[pkgName] == nil { - // Make the package visible under a path identical to its name - // TODO(mpl): srcPkg is supposed to be keyed by importPath. Verify it is necessary, and implement. - interp.srcPkg[pkgName] = interp.scopes[pkgName].sym + // Make the package visible under a path identical to its name. + interp.srcPkg[pkgName] = gs.sym interp.universe.sym[pkgName] = &symbol{kind: pkgSym, typ: &itype{cat: srcPkgT, path: pkgName}} interp.pkgNames[pkgName] = pkgName } interp.mutex.Unlock() + // Add main to list of functions to run, after all inits. + if m := gs.sym[mainID]; pkgName == mainID && m != nil { + initNodes = append(initNodes, m.node) + } + if interp.cfgDot { dotCmd := interp.dotCmd if dotCmd == "" { @@ -470,21 +514,21 @@ func (interp *Interpreter) eval(src, name string, inc bool) (res reflect.Value, return res, err } - // Generate node exec closures + // Generate node exec closures. if err = genRun(root); err != nil { return res, err } - // Init interpreter execution memory frame + // Init interpreter execution memory frame. interp.frame.setrunid(interp.runid()) interp.frame.mutex.Lock() interp.resizeFrame() interp.frame.mutex.Unlock() - // Execute node closures + // Execute node closures. interp.run(root, nil) - // Wire and execute global vars + // Wire and execute global vars. n, err := genGlobalVars([]*node{root}, interp.scopes[pkgName]) if err != nil { return res, err @@ -497,7 +541,7 @@ func (interp *Interpreter) eval(src, name string, inc bool) (res reflect.Value, v := genValue(root) res = v(interp.frame) - // If result is an interpreter node, wrap it in a runtime callable function + // If result is an interpreter node, wrap it in a runtime callable function. if res.IsValid() { if n, ok := res.Interface().(*node); ok { res = genFunctionWrapper(n)(interp.frame) diff --git a/interp/src.go b/interp/src.go index 0bbc6e665..7f0c12f8d 100644 --- a/interp/src.go +++ b/interp/src.go @@ -11,7 +11,7 @@ import ( // importSrc calls gta on the source code for the package identified by // importPath. rPath is the relative path to the directory containing the source // code for the package. It can also be "main" as a special value. -func (interp *Interpreter) importSrc(rPath, importPath string) (string, error) { +func (interp *Interpreter) importSrc(rPath, importPath string, skipTest bool) (string, error) { var dir string var err error @@ -68,7 +68,7 @@ func (interp *Interpreter) importSrc(rPath, importPath string) (string, error) { // Parse source files. for _, file := range files { name := file.Name() - if skipFile(&interp.context, name) { + if skipFile(&interp.context, name, skipTest) { continue } @@ -95,7 +95,7 @@ func (interp *Interpreter) importSrc(rPath, importPath string) (string, error) { } if pkgName == "" { pkgName = pname - } else if pkgName != pname { + } else if pkgName != pname && skipTest { return "", fmt.Errorf("found packages %s and %s in %s", pkgName, pname, dir) } rootNodes = append(rootNodes, root) @@ -116,7 +116,7 @@ func (interp *Interpreter) importSrc(rPath, importPath string) (string, error) { } } - // Generate control flow graphs + // Generate control flow graphs. for _, root := range rootNodes { var nodes []*node if nodes, err = interp.cfg(root, importPath); err != nil { @@ -128,7 +128,8 @@ func (interp *Interpreter) importSrc(rPath, importPath string) (string, error) { // Register source package in the interpreter. The package contains only // the global symbols in the package scope. interp.mutex.Lock() - interp.srcPkg[importPath] = interp.scopes[importPath].sym + gs := interp.scopes[importPath] + interp.srcPkg[importPath] = gs.sym interp.pkgNames[importPath] = pkgName interp.frame.mutex.Lock() @@ -136,7 +137,7 @@ func (interp *Interpreter) importSrc(rPath, importPath string) (string, error) { interp.frame.mutex.Unlock() interp.mutex.Unlock() - // Once all package sources have been parsed, execute entry points then init functions + // Once all package sources have been parsed, execute entry points then init functions. for _, n := range rootNodes { if err = genRun(n); err != nil { return "", err @@ -144,16 +145,16 @@ func (interp *Interpreter) importSrc(rPath, importPath string) (string, error) { interp.run(n, nil) } - // Wire and execute global vars - n, err := genGlobalVars(rootNodes, interp.scopes[importPath]) + // Wire and execute global vars in global scope gs. + n, err := genGlobalVars(rootNodes, gs) if err != nil { return "", err } interp.run(n, nil) - // Add main to list of functions to run, after all inits - if m := interp.main(); m != nil { - initNodes = append(initNodes, m) + // Add main to list of functions to run, after all inits. + if m := gs.sym[mainID]; pkgName == mainID && m != nil && skipTest { + initNodes = append(initNodes, m.node) } for _, n := range initNodes { diff --git a/stdlib/go1_14_testing.go b/stdlib/go1_14_testing.go new file mode 100644 index 000000000..1605b19db --- /dev/null +++ b/stdlib/go1_14_testing.go @@ -0,0 +1,82 @@ +// Code generated by 'github.com/containous/yaegi/extract testing'. DO NOT EDIT. + +// +build go1.14,!go1.15 + +package stdlib + +import ( + "reflect" + "testing" +) + +func init() { + Symbols["testing"] = map[string]reflect.Value{ + // function, constant and variable definitions + "AllocsPerRun": reflect.ValueOf(testing.AllocsPerRun), + "Benchmark": reflect.ValueOf(testing.Benchmark), + "CoverMode": reflect.ValueOf(testing.CoverMode), + "Coverage": reflect.ValueOf(testing.Coverage), + "Init": reflect.ValueOf(testing.Init), + "Main": reflect.ValueOf(testing.Main), + "MainStart": reflect.ValueOf(testing.MainStart), + "RegisterCover": reflect.ValueOf(testing.RegisterCover), + "RunBenchmarks": reflect.ValueOf(testing.RunBenchmarks), + "RunExamples": reflect.ValueOf(testing.RunExamples), + "RunTests": reflect.ValueOf(testing.RunTests), + "Short": reflect.ValueOf(testing.Short), + "Verbose": reflect.ValueOf(testing.Verbose), + + // type definitions + "B": reflect.ValueOf((*testing.B)(nil)), + "BenchmarkResult": reflect.ValueOf((*testing.BenchmarkResult)(nil)), + "Cover": reflect.ValueOf((*testing.Cover)(nil)), + "CoverBlock": reflect.ValueOf((*testing.CoverBlock)(nil)), + "InternalBenchmark": reflect.ValueOf((*testing.InternalBenchmark)(nil)), + "InternalExample": reflect.ValueOf((*testing.InternalExample)(nil)), + "InternalTest": reflect.ValueOf((*testing.InternalTest)(nil)), + "M": reflect.ValueOf((*testing.M)(nil)), + "PB": reflect.ValueOf((*testing.PB)(nil)), + "T": reflect.ValueOf((*testing.T)(nil)), + "TB": reflect.ValueOf((*testing.TB)(nil)), + + // interface wrapper definitions + "_TB": reflect.ValueOf((*_testing_TB)(nil)), + } +} + +// _testing_TB is an interface wrapper for TB type +type _testing_TB struct { + WCleanup func(a0 func()) + WError func(args []interface{}) + WErrorf func(format string, args []interface{}) + WFail func() + WFailNow func() + WFailed func() bool + WFatal func(args []interface{}) + WFatalf func(format string, args []interface{}) + WHelper func() + WLog func(args []interface{}) + WLogf func(format string, args []interface{}) + WName func() string + WSkip func(args []interface{}) + WSkipNow func() + WSkipf func(format string, args []interface{}) + WSkipped func() bool +} + +func (W _testing_TB) Cleanup(a0 func()) { W.WCleanup(a0) } +func (W _testing_TB) Error(args []interface{}) { W.WError(args) } +func (W _testing_TB) Errorf(format string, args []interface{}) { W.WErrorf(format, args) } +func (W _testing_TB) Fail() { W.WFail() } +func (W _testing_TB) FailNow() { W.WFailNow() } +func (W _testing_TB) Failed() bool { return W.WFailed() } +func (W _testing_TB) Fatal(args []interface{}) { W.WFatal(args) } +func (W _testing_TB) Fatalf(format string, args []interface{}) { W.WFatalf(format, args) } +func (W _testing_TB) Helper() { W.WHelper() } +func (W _testing_TB) Log(args []interface{}) { W.WLog(args) } +func (W _testing_TB) Logf(format string, args []interface{}) { W.WLogf(format, args) } +func (W _testing_TB) Name() string { return W.WName() } +func (W _testing_TB) Skip(args []interface{}) { W.WSkip(args) } +func (W _testing_TB) SkipNow() { W.WSkipNow() } +func (W _testing_TB) Skipf(format string, args []interface{}) { W.WSkipf(format, args) } +func (W _testing_TB) Skipped() bool { return W.WSkipped() } diff --git a/stdlib/go1_14_testing_iotest.go b/stdlib/go1_14_testing_iotest.go new file mode 100644 index 000000000..54630c204 --- /dev/null +++ b/stdlib/go1_14_testing_iotest.go @@ -0,0 +1,24 @@ +// Code generated by 'github.com/containous/yaegi/extract testing/iotest'. DO NOT EDIT. + +// +build go1.14,!go1.15 + +package stdlib + +import ( + "reflect" + "testing/iotest" +) + +func init() { + Symbols["testing/iotest"] = map[string]reflect.Value{ + // function, constant and variable definitions + "DataErrReader": reflect.ValueOf(iotest.DataErrReader), + "ErrTimeout": reflect.ValueOf(&iotest.ErrTimeout).Elem(), + "HalfReader": reflect.ValueOf(iotest.HalfReader), + "NewReadLogger": reflect.ValueOf(iotest.NewReadLogger), + "NewWriteLogger": reflect.ValueOf(iotest.NewWriteLogger), + "OneByteReader": reflect.ValueOf(iotest.OneByteReader), + "TimeoutReader": reflect.ValueOf(iotest.TimeoutReader), + "TruncateWriter": reflect.ValueOf(iotest.TruncateWriter), + } +} diff --git a/stdlib/go1_14_testing_quick.go b/stdlib/go1_14_testing_quick.go new file mode 100644 index 000000000..fcab8d3e7 --- /dev/null +++ b/stdlib/go1_14_testing_quick.go @@ -0,0 +1,39 @@ +// Code generated by 'github.com/containous/yaegi/extract testing/quick'. DO NOT EDIT. + +// +build go1.14,!go1.15 + +package stdlib + +import ( + "math/rand" + "reflect" + "testing/quick" +) + +func init() { + Symbols["testing/quick"] = map[string]reflect.Value{ + // function, constant and variable definitions + "Check": reflect.ValueOf(quick.Check), + "CheckEqual": reflect.ValueOf(quick.CheckEqual), + "Value": reflect.ValueOf(quick.Value), + + // type definitions + "CheckEqualError": reflect.ValueOf((*quick.CheckEqualError)(nil)), + "CheckError": reflect.ValueOf((*quick.CheckError)(nil)), + "Config": reflect.ValueOf((*quick.Config)(nil)), + "Generator": reflect.ValueOf((*quick.Generator)(nil)), + "SetupError": reflect.ValueOf((*quick.SetupError)(nil)), + + // interface wrapper definitions + "_Generator": reflect.ValueOf((*_testing_quick_Generator)(nil)), + } +} + +// _testing_quick_Generator is an interface wrapper for Generator type +type _testing_quick_Generator struct { + WGenerate func(rand *rand.Rand, size int) reflect.Value +} + +func (W _testing_quick_Generator) Generate(rand *rand.Rand, size int) reflect.Value { + return W.WGenerate(rand, size) +} diff --git a/stdlib/go1_15_testing.go b/stdlib/go1_15_testing.go new file mode 100644 index 000000000..630f3791f --- /dev/null +++ b/stdlib/go1_15_testing.go @@ -0,0 +1,84 @@ +// Code generated by 'github.com/containous/yaegi/extract testing'. DO NOT EDIT. + +// +build go1.15,!go1.16 + +package stdlib + +import ( + "reflect" + "testing" +) + +func init() { + Symbols["testing"] = map[string]reflect.Value{ + // function, constant and variable definitions + "AllocsPerRun": reflect.ValueOf(testing.AllocsPerRun), + "Benchmark": reflect.ValueOf(testing.Benchmark), + "CoverMode": reflect.ValueOf(testing.CoverMode), + "Coverage": reflect.ValueOf(testing.Coverage), + "Init": reflect.ValueOf(testing.Init), + "Main": reflect.ValueOf(testing.Main), + "MainStart": reflect.ValueOf(testing.MainStart), + "RegisterCover": reflect.ValueOf(testing.RegisterCover), + "RunBenchmarks": reflect.ValueOf(testing.RunBenchmarks), + "RunExamples": reflect.ValueOf(testing.RunExamples), + "RunTests": reflect.ValueOf(testing.RunTests), + "Short": reflect.ValueOf(testing.Short), + "Verbose": reflect.ValueOf(testing.Verbose), + + // type definitions + "B": reflect.ValueOf((*testing.B)(nil)), + "BenchmarkResult": reflect.ValueOf((*testing.BenchmarkResult)(nil)), + "Cover": reflect.ValueOf((*testing.Cover)(nil)), + "CoverBlock": reflect.ValueOf((*testing.CoverBlock)(nil)), + "InternalBenchmark": reflect.ValueOf((*testing.InternalBenchmark)(nil)), + "InternalExample": reflect.ValueOf((*testing.InternalExample)(nil)), + "InternalTest": reflect.ValueOf((*testing.InternalTest)(nil)), + "M": reflect.ValueOf((*testing.M)(nil)), + "PB": reflect.ValueOf((*testing.PB)(nil)), + "T": reflect.ValueOf((*testing.T)(nil)), + "TB": reflect.ValueOf((*testing.TB)(nil)), + + // interface wrapper definitions + "_TB": reflect.ValueOf((*_testing_TB)(nil)), + } +} + +// _testing_TB is an interface wrapper for TB type +type _testing_TB struct { + WCleanup func(a0 func()) + WError func(args []interface{}) + WErrorf func(format string, args []interface{}) + WFail func() + WFailNow func() + WFailed func() bool + WFatal func(args []interface{}) + WFatalf func(format string, args []interface{}) + WHelper func() + WLog func(args []interface{}) + WLogf func(format string, args []interface{}) + WName func() string + WSkip func(args []interface{}) + WSkipNow func() + WSkipf func(format string, args []interface{}) + WSkipped func() bool + WTempDir func() string +} + +func (W _testing_TB) Cleanup(a0 func()) { W.WCleanup(a0) } +func (W _testing_TB) Error(args []interface{}) { W.WError(args) } +func (W _testing_TB) Errorf(format string, args []interface{}) { W.WErrorf(format, args) } +func (W _testing_TB) Fail() { W.WFail() } +func (W _testing_TB) FailNow() { W.WFailNow() } +func (W _testing_TB) Failed() bool { return W.WFailed() } +func (W _testing_TB) Fatal(args []interface{}) { W.WFatal(args) } +func (W _testing_TB) Fatalf(format string, args []interface{}) { W.WFatalf(format, args) } +func (W _testing_TB) Helper() { W.WHelper() } +func (W _testing_TB) Log(args []interface{}) { W.WLog(args) } +func (W _testing_TB) Logf(format string, args []interface{}) { W.WLogf(format, args) } +func (W _testing_TB) Name() string { return W.WName() } +func (W _testing_TB) Skip(args []interface{}) { W.WSkip(args) } +func (W _testing_TB) SkipNow() { W.WSkipNow() } +func (W _testing_TB) Skipf(format string, args []interface{}) { W.WSkipf(format, args) } +func (W _testing_TB) Skipped() bool { return W.WSkipped() } +func (W _testing_TB) TempDir() string { return W.WTempDir() } diff --git a/stdlib/go1_15_testing_iotest.go b/stdlib/go1_15_testing_iotest.go new file mode 100644 index 000000000..0dc25af3c --- /dev/null +++ b/stdlib/go1_15_testing_iotest.go @@ -0,0 +1,24 @@ +// Code generated by 'github.com/containous/yaegi/extract testing/iotest'. DO NOT EDIT. + +// +build go1.15,!go1.16 + +package stdlib + +import ( + "reflect" + "testing/iotest" +) + +func init() { + Symbols["testing/iotest"] = map[string]reflect.Value{ + // function, constant and variable definitions + "DataErrReader": reflect.ValueOf(iotest.DataErrReader), + "ErrTimeout": reflect.ValueOf(&iotest.ErrTimeout).Elem(), + "HalfReader": reflect.ValueOf(iotest.HalfReader), + "NewReadLogger": reflect.ValueOf(iotest.NewReadLogger), + "NewWriteLogger": reflect.ValueOf(iotest.NewWriteLogger), + "OneByteReader": reflect.ValueOf(iotest.OneByteReader), + "TimeoutReader": reflect.ValueOf(iotest.TimeoutReader), + "TruncateWriter": reflect.ValueOf(iotest.TruncateWriter), + } +} diff --git a/stdlib/go1_15_testing_quick.go b/stdlib/go1_15_testing_quick.go new file mode 100644 index 000000000..ec092f34b --- /dev/null +++ b/stdlib/go1_15_testing_quick.go @@ -0,0 +1,39 @@ +// Code generated by 'github.com/containous/yaegi/extract testing/quick'. DO NOT EDIT. + +// +build go1.15,!go1.16 + +package stdlib + +import ( + "math/rand" + "reflect" + "testing/quick" +) + +func init() { + Symbols["testing/quick"] = map[string]reflect.Value{ + // function, constant and variable definitions + "Check": reflect.ValueOf(quick.Check), + "CheckEqual": reflect.ValueOf(quick.CheckEqual), + "Value": reflect.ValueOf(quick.Value), + + // type definitions + "CheckEqualError": reflect.ValueOf((*quick.CheckEqualError)(nil)), + "CheckError": reflect.ValueOf((*quick.CheckError)(nil)), + "Config": reflect.ValueOf((*quick.Config)(nil)), + "Generator": reflect.ValueOf((*quick.Generator)(nil)), + "SetupError": reflect.ValueOf((*quick.SetupError)(nil)), + + // interface wrapper definitions + "_Generator": reflect.ValueOf((*_testing_quick_Generator)(nil)), + } +} + +// _testing_quick_Generator is an interface wrapper for Generator type +type _testing_quick_Generator struct { + WGenerate func(rand *rand.Rand, size int) reflect.Value +} + +func (W _testing_quick_Generator) Generate(rand *rand.Rand, size int) reflect.Value { + return W.WGenerate(rand, size) +} diff --git a/stdlib/stdlib.go b/stdlib/stdlib.go index 1d25df812..da5b6952c 100644 --- a/stdlib/stdlib.go +++ b/stdlib/stdlib.go @@ -47,5 +47,6 @@ func init() { //go:generate ../cmd/goexports/goexports path path/filepath reflect regexp regexp/syntax //go:generate ../cmd/goexports/goexports runtime runtime/debug runtime/pprof runtime/trace //go:generate ../cmd/goexports/goexports sort strconv strings sync sync/atomic +//go:generate ../cmd/goexports/goexports testing testing/iotest testing/quick //go:generate ../cmd/goexports/goexports text/scanner text/tabwriter text/template text/template/parse //go:generate ../cmd/goexports/goexports time unicode unicode/utf16 unicode/utf8