tinygo: support -run for tests

Fixes #2294
Этот коммит содержится в:
Damian Gryski 2021-11-19 14:14:21 -08:00 коммит произвёл Ron Evans
родитель 18242bc26a
коммит a536ddcda8
3 изменённых файлов: 52 добавлений и 10 удалений

16
main.go
Просмотреть файл

@ -177,7 +177,7 @@ func Build(pkgName, outpath string, options *compileopts.Options) error {
// Test runs the tests in the given package. Returns whether the test passed and
// possibly an error if the test failed to run.
func Test(pkgName string, options *compileopts.Options, testCompileOnly, testVerbose, testShort bool, outpath string) (bool, error) {
func Test(pkgName string, options *compileopts.Options, testCompileOnly, testVerbose, testShort bool, testRunRegexp string, outpath string) (bool, error) {
options.TestConfig.CompileTestBinary = true
config, err := builder.NewConfig(options)
if err != nil {
@ -203,7 +203,7 @@ func Test(pkgName string, options *compileopts.Options, testCompileOnly, testVer
// Run the test.
start := time.Now()
var err error
passed, err = runPackageTest(config, result, testVerbose, testShort)
passed, err = runPackageTest(config, result, testVerbose, testShort, testRunRegexp)
if err != nil {
return err
}
@ -229,7 +229,7 @@ func Test(pkgName string, options *compileopts.Options, testCompileOnly, testVer
// runPackageTest runs a test binary that was previously built. The return
// values are whether the test passed and any errors encountered while trying to
// run the binary.
func runPackageTest(config *compileopts.Config, result builder.BuildResult, testVerbose, testShort bool) (bool, error) {
func runPackageTest(config *compileopts.Config, result builder.BuildResult, testVerbose, testShort bool, testRunRegexp string) (bool, error) {
var cmd *exec.Cmd
if len(config.Target.Emulator) == 0 {
// Run directly.
@ -240,6 +240,9 @@ func runPackageTest(config *compileopts.Config, result builder.BuildResult, test
if testShort {
flags = append(flags, "-test.short")
}
if testRunRegexp != "" {
flags = append(flags, "-test.run="+testRunRegexp)
}
cmd = executeCommand(config.Options, result.Binary, flags...)
cmd.Dir = result.MainDir
} else {
@ -255,6 +258,9 @@ func runPackageTest(config *compileopts.Config, result builder.BuildResult, test
if testShort {
args = append(args, "-test.short")
}
if testRunRegexp != "" {
args = append(args, "-test.run="+testRunRegexp)
}
}
cmd = executeCommand(config.Options, config.Target.Emulator[0], args...)
}
@ -1150,10 +1156,12 @@ func main() {
flag.StringVar(&outpath, "o", "", "output filename")
}
var testCompileOnlyFlag, testVerboseFlag, testShortFlag *bool
var testRunRegexp *string
if command == "help" || command == "test" {
testCompileOnlyFlag = flag.Bool("c", false, "compile the test binary but do not run it")
testVerboseFlag = flag.Bool("v", false, "verbose: print additional output")
testShortFlag = flag.Bool("short", false, "short: run smaller test suite to save time")
testRunRegexp = flag.String("run", "", "run: regexp of tests to run")
}
// Early command processing, before commands are interpreted by the Go flag
@ -1336,7 +1344,7 @@ func main() {
allTestsPassed := true
for _, pkgName := range pkgNames {
// TODO: parallelize building the test binaries
passed, err := Test(pkgName, options, *testCompileOnlyFlag, *testVerboseFlag, *testShortFlag, outpath)
passed, err := Test(pkgName, options, *testCompileOnlyFlag, *testVerboseFlag, *testShortFlag, *testRunRegexp, outpath)
handleCompilerError(err)
if !passed {
allTestsPassed = false

Просмотреть файл

@ -18,8 +18,9 @@ import (
// Testing flags.
var (
flagVerbose bool
flagShort bool
flagVerbose bool
flagShort bool
flagRunRegexp string
)
var initRan bool
@ -33,6 +34,7 @@ func Init() {
flag.BoolVar(&flagVerbose, "test.v", false, "verbose: print additional output")
flag.BoolVar(&flagShort, "test.short", false, "short: run smaller test suite to save time")
flag.StringVar(&flagRunRegexp, "test.run", "", "run: regexp of tests to run")
}
// common holds the elements common between T and B and
@ -242,19 +244,42 @@ type InternalTest struct {
type M struct {
// tests is a list of the test names to execute
Tests []InternalTest
deps testDeps
}
// Run the test suite.
func (m *M) Run() int {
if len(m.Tests) == 0 {
fmt.Fprintln(os.Stderr, "testing: warning: no tests to run")
}
if !flag.Parsed() {
flag.Parse()
}
failures := 0
if flagRunRegexp != "" {
var filtered []InternalTest
// pre-test the regexp; we don't want to bother logging one failure for every test name if the regexp is broken
if _, err := m.deps.MatchString(flagRunRegexp, "some-test-name"); err != nil {
fmt.Println("testing: invalid regexp for -test.run:", err.Error())
failures++
}
// filter the list of tests before we try to run them
for _, test := range m.Tests {
// ignore the error; we already tested that the regexp compiles fine above
if match, _ := m.deps.MatchString(flagRunRegexp, test.Name); match {
filtered = append(filtered, test)
}
}
m.Tests = filtered
}
if len(m.Tests) == 0 {
fmt.Fprintln(os.Stderr, "testing: warning: no tests to run")
}
for _, test := range m.Tests {
t := &T{
common: common{
@ -326,10 +351,15 @@ func TestMain(m *M) {
os.Exit(m.Run())
}
type testDeps interface {
MatchString(pat, s string) (bool, error)
}
func MainStart(deps interface{}, tests []InternalTest, benchmarks []InternalBenchmark, examples []InternalExample) *M {
Init()
return &M{
Tests: tests,
deps: deps.(testDeps),
}
}

6
testdata/testing.go предоставленный
Просмотреть файл

@ -34,9 +34,13 @@ var benchmarks = []testing.InternalBenchmark{}
var examples = []testing.InternalExample{}
func main() {
m := testing.MainStart(nil, tests, benchmarks, examples)
m := testing.MainStart(testdeps{}, tests, benchmarks, examples)
exitcode := m.Run()
if exitcode != 0 {
println("exitcode:", exitcode)
}
}
type testdeps struct{}
func (testdeps) MatchString(pat, str string) (bool, error) { return true, nil }