aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--main.go18
-rw-r--r--main_test.go1
-rw-r--r--src/testing/testing.go78
-rw-r--r--testdata/testing.go42
-rw-r--r--testdata/testing.txt16
5 files changed, 133 insertions, 22 deletions
diff --git a/main.go b/main.go
index c9fd0c042..612ad0747 100644
--- a/main.go
+++ b/main.go
@@ -158,7 +158,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 bool, outpath string) (bool, error) {
+func Test(pkgName string, options *compileopts.Options, testCompileOnly, testVerbose bool, outpath string) (bool, error) {
options.TestConfig.CompileTestBinary = true
config, err := builder.NewConfig(options)
if err != nil {
@@ -184,7 +184,7 @@ func Test(pkgName string, options *compileopts.Options, testCompileOnly bool, ou
// Run the test.
start := time.Now()
var err error
- passed, err = runPackageTest(config, result)
+ passed, err = runPackageTest(config, result, testVerbose)
if err != nil {
return err
}
@@ -210,10 +210,14 @@ func Test(pkgName string, options *compileopts.Options, testCompileOnly bool, ou
// 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) (bool, error) {
+func runPackageTest(config *compileopts.Config, result builder.BuildResult, testVerbose bool) (bool, error) {
if len(config.Target.Emulator) == 0 {
// Run directly.
- cmd := executeCommand(config.Options, result.Binary)
+ var flags []string
+ if testVerbose {
+ flags = append(flags, "-test.v")
+ }
+ cmd := executeCommand(config.Options, result.Binary, flags...)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
cmd.Dir = result.MainDir
@@ -229,6 +233,7 @@ func runPackageTest(config *compileopts.Config, result builder.BuildResult) (boo
return true, nil
} else {
// Run in an emulator.
+ // TODO: pass the -test.v flag if needed.
args := append(config.Target.Emulator[1:], result.Binary)
cmd := executeCommand(config.Options, config.Target.Emulator[0], args...)
buf := &bytes.Buffer{}
@@ -1038,9 +1043,10 @@ func main() {
if command == "help" || command == "build" || command == "build-library" || command == "test" {
flag.StringVar(&outpath, "o", "", "output filename")
}
- var testCompileOnlyFlag *bool
+ var testCompileOnlyFlag, testVerboseFlag *bool
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")
}
// Early command processing, before commands are interpreted by the Go flag
@@ -1201,7 +1207,7 @@ func main() {
allTestsPassed := true
for _, pkgName := range pkgNames {
// TODO: parallelize building the test binaries
- passed, err := Test(pkgName, options, *testCompileOnlyFlag, outpath)
+ passed, err := Test(pkgName, options, *testCompileOnlyFlag, *testVerboseFlag, outpath)
handleCompilerError(err)
if !passed {
allTestsPassed = false
diff --git a/main_test.go b/main_test.go
index a502115e4..f47b43398 100644
--- a/main_test.go
+++ b/main_test.go
@@ -51,6 +51,7 @@ func TestCompiler(t *testing.T) {
"stdlib.go",
"string.go",
"structs.go",
+ "testing.go",
"zeroalloc.go",
}
diff --git a/src/testing/testing.go b/src/testing/testing.go
index 88e751ffb..c15ddab53 100644
--- a/src/testing/testing.go
+++ b/src/testing/testing.go
@@ -10,15 +10,34 @@ package testing
import (
"bytes"
+ "flag"
"fmt"
- "io"
"os"
+ "strings"
)
+// Testing flags.
+var (
+ flagVerbose bool
+)
+
+var initRan bool
+
+// Init registers testing flags. It has no effect if it has already run.
+func Init() {
+ if initRan {
+ return
+ }
+ initRan = true
+
+ flag.BoolVar(&flagVerbose, "test.v", false, "verbose: print additional output")
+}
+
// common holds the elements common between T and B and
// captures common methods such as Errorf.
type common struct {
- output io.Writer
+ output bytes.Buffer
+ indent string
failed bool // Test or benchmark has failed.
skipped bool // Test of benchmark has been skipped.
@@ -53,7 +72,6 @@ var _ TB = (*B)(nil)
//
type T struct {
common
- indent string
}
// Name returns the name of the running test or benchmark.
@@ -85,8 +103,22 @@ func (c *common) FailNow() {
// log generates the output.
func (c *common) log(s string) {
// This doesn't print the same as in upstream go, but works for now.
- fmt.Fprintf(c.output, "\t")
- fmt.Fprintln(c.output, s)
+ if len(s) != 0 && s[len(s)-1] == '\n' {
+ s = s[:len(s)-1]
+ }
+ lines := strings.Split(s, "\n")
+ // First line.
+ c.output.WriteString(c.indent)
+ c.output.WriteString(" ") // 4 spaces
+ c.output.WriteString(lines[0])
+ c.output.WriteByte('\n')
+ // More lines.
+ for _, line := range lines[1:] {
+ c.output.WriteString(c.indent)
+ c.output.WriteString(" ") // 8 spaces
+ c.output.WriteString(line)
+ c.output.WriteByte('\n')
+ }
}
// Log formats its arguments using default formatting, analogous to Println,
@@ -165,25 +197,30 @@ func (c *common) Helper() {
func (t *T) Run(name string, f func(t *T)) bool {
// Create a subtest.
sub := T{
- indent: t.indent + " ",
common: common{
name: t.name + "/" + name,
- output: &bytes.Buffer{},
+ indent: t.indent + " ",
},
}
// Run the test.
- fmt.Printf("=== RUN %s\n", sub.name)
+ if flagVerbose {
+ fmt.Fprintf(&t.output, "=== RUN %s\n", sub.name)
+
+ }
f(&sub)
// Process the result (pass or fail).
if sub.failed {
t.failed = true
- fmt.Printf(sub.indent+"--- FAIL: %s\n", sub.name)
+ fmt.Fprintf(&t.output, sub.indent+"--- FAIL: %s\n", sub.name)
+ t.output.Write(sub.output.Bytes())
} else {
- fmt.Printf(sub.indent+"--- PASS: %s\n", sub.name)
+ if flagVerbose {
+ fmt.Fprintf(&t.output, sub.indent+"--- PASS: %s\n", sub.name)
+ t.output.Write(sub.output.Bytes())
+ }
}
- fmt.Print(sub.output)
return !sub.failed
}
@@ -205,24 +242,32 @@ func (m *M) Run() int {
fmt.Fprintln(os.Stderr, "testing: warning: no tests to run")
}
+ if !flag.Parsed() {
+ flag.Parse()
+ }
+
failures := 0
for _, test := range m.Tests {
t := &T{
common: common{
- name: test.Name,
- output: &bytes.Buffer{},
+ name: test.Name,
},
}
- fmt.Printf("=== RUN %s\n", test.Name)
+ if flagVerbose {
+ fmt.Printf("=== RUN %s\n", test.Name)
+ }
test.F(t)
if t.failed {
fmt.Printf("--- FAIL: %s\n", test.Name)
+ os.Stdout.Write(t.output.Bytes())
} else {
- fmt.Printf("--- PASS: %s\n", test.Name)
+ if flagVerbose {
+ fmt.Printf("--- PASS: %s\n", test.Name)
+ os.Stdout.Write(t.output.Bytes())
+ }
}
- fmt.Print(t.output)
if t.failed {
failures++
@@ -242,6 +287,7 @@ func TestMain(m *M) {
}
func MainStart(deps interface{}, tests []InternalTest, benchmarks []InternalBenchmark, examples []InternalExample) *M {
+ Init()
return &M{
Tests: tests,
}
diff --git a/testdata/testing.go b/testdata/testing.go
new file mode 100644
index 000000000..ba952f34d
--- /dev/null
+++ b/testdata/testing.go
@@ -0,0 +1,42 @@
+package main
+
+// TODO: also test the verbose version.
+
+import (
+ "testing"
+)
+
+func TestFoo(t *testing.T) {
+ t.Log("log Foo.a")
+ t.Log("log Foo.b")
+}
+
+func TestBar(t *testing.T) {
+ t.Log("log Bar")
+ t.Log("log g\nh\ni\n")
+ t.Run("Bar1", func(t *testing.T) {})
+ t.Run("Bar2", func(t *testing.T) {
+ t.Log("log Bar2\na\nb\nc")
+ t.Error("failed")
+ t.Log("after failed")
+ })
+ t.Run("Bar3", func(t *testing.T) {})
+ t.Log("log Bar end")
+}
+
+var tests = []testing.InternalTest{
+ {"TestFoo", TestFoo},
+ {"TestBar", TestBar},
+}
+
+var benchmarks = []testing.InternalBenchmark{}
+
+var examples = []testing.InternalExample{}
+
+func main() {
+ m := testing.MainStart(nil, tests, benchmarks, examples)
+ exitcode := m.Run()
+ if exitcode != 0 {
+ println("exitcode:", exitcode)
+ }
+}
diff --git a/testdata/testing.txt b/testdata/testing.txt
new file mode 100644
index 000000000..816246c2e
--- /dev/null
+++ b/testdata/testing.txt
@@ -0,0 +1,16 @@
+--- FAIL: TestBar
+ log Bar
+ log g
+ h
+ i
+
+ --- FAIL: TestBar/Bar2
+ log Bar2
+ a
+ b
+ c
+ failed
+ after failed
+ log Bar end
+FAIL
+exitcode: 1