diff options
-rw-r--r-- | src/testing/benchmark.go | 7 | ||||
-rw-r--r-- | src/testing/testing.go | 177 | ||||
-rw-r--r-- | tests/tinygotest/main_test.go | 8 |
3 files changed, 167 insertions, 25 deletions
diff --git a/src/testing/benchmark.go b/src/testing/benchmark.go index cdc2c50a0..809014547 100644 --- a/src/testing/benchmark.go +++ b/src/testing/benchmark.go @@ -1,3 +1,9 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. +// +// This file has been modified for use by the TinyGo compiler. + package testing // B is a type passed to Benchmark functions to manage benchmark timing and to @@ -6,5 +12,6 @@ package testing // TODO: Implement benchmarks. This struct allows test files containing // benchmarks to compile and run, but will not run the benchmarks themselves. type B struct { + common N int } diff --git a/src/testing/testing.go b/src/testing/testing.go index 1d7ea051d..f476514f6 100644 --- a/src/testing/testing.go +++ b/src/testing/testing.go @@ -1,3 +1,11 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. +// +// This file has been modified for use by the TinyGo compiler. +// src: https://github.com/golang/go/blob/61bb56ad/src/testing/testing.go + +// Package testing provides support for automated testing of Go packages. package testing import ( @@ -7,13 +15,143 @@ import ( "os" ) -// T is a test helper. -type T struct { - name string +// common holds the elements common between T and B and +// captures common methods such as Errorf. +type common struct { output io.Writer - // flags the test as having failed when non-zero - failed int + failed bool // Test or benchmark has failed. + skipped bool // Test of benchmark has been skipped. + finished bool // Test function has completed. + name string // Name of test or benchmark. +} + +// TB is the interface common to T and B. +type TB interface { + Error(args ...interface{}) + Errorf(format string, args ...interface{}) + Fail() + FailNow() + Failed() bool + Fatal(args ...interface{}) + Fatalf(format string, args ...interface{}) + Log(args ...interface{}) + Logf(format string, args ...interface{}) + Name() string + Skip(args ...interface{}) + SkipNow() + Skipf(format string, args ...interface{}) + Skipped() bool + // Helper() +} + +var _ TB = (*T)(nil) +var _ TB = (*B)(nil) + +// T is a type passed to Test functions to manage test state and support formatted test logs. +// Logs are accumulated during execution and dumped to standard output when done. +// +type T struct { + common +} + +// Name returns the name of the running test or benchmark. +func (c *common) Name() string { + return c.name +} + +// Fail marks the function as having failed but continues execution. +func (c *common) Fail() { + c.failed = true +} + +// Failed reports whether the function has failed. +func (c *common) Failed() bool { + failed := c.failed + return failed +} + +// FailNow marks the function as having failed and stops its execution +// by calling runtime.Goexit (which then runs all deferred calls in the +// current goroutine). +func (c *common) FailNow() { + c.Fail() + + c.finished = true + c.Error("FailNow is incomplete, requires runtime.Goexit()") +} + +// 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) +} + +// Log formats its arguments using default formatting, analogous to Println, +// and records the text in the error log. For tests, the text will be printed only if +// the test fails or the -test.v flag is set. For benchmarks, the text is always +// printed to avoid having performance depend on the value of the -test.v flag. +func (c *common) Log(args ...interface{}) { c.log(fmt.Sprintln(args...)) } + +// Logf formats its arguments according to the format, analogous to Printf, and +// records the text in the error log. A final newline is added if not provided. For +// tests, the text will be printed only if the test fails or the -test.v flag is +// set. For benchmarks, the text is always printed to avoid having performance +// depend on the value of the -test.v flag. +func (c *common) Logf(format string, args ...interface{}) { c.log(fmt.Sprintf(format, args...)) } + +// Error is equivalent to Log followed by Fail. +func (c *common) Error(args ...interface{}) { + c.log(fmt.Sprintln(args...)) + c.Fail() +} + +// Errorf is equivalent to Logf followed by Fail. +func (c *common) Errorf(format string, args ...interface{}) { + c.log(fmt.Sprintf(format, args...)) + c.Fail() +} + +// Fatal is equivalent to Log followed by FailNow. +func (c *common) Fatal(args ...interface{}) { + c.log(fmt.Sprintln(args...)) + c.FailNow() +} + +// Fatalf is equivalent to Logf followed by FailNow. +func (c *common) Fatalf(format string, args ...interface{}) { + c.log(fmt.Sprintf(format, args...)) + c.FailNow() +} + +// Skip is equivalent to Log followed by SkipNow. +func (c *common) Skip(args ...interface{}) { + c.log(fmt.Sprintln(args...)) + c.SkipNow() +} + +// Skipf is equivalent to Logf followed by SkipNow. +func (c *common) Skipf(format string, args ...interface{}) { + c.log(fmt.Sprintf(format, args...)) + c.SkipNow() +} + +// SkipNow marks the test as having been skipped and stops its execution +// by calling runtime.Goexit. +func (c *common) SkipNow() { + c.skip() + c.finished = true + c.Error("SkipNow is incomplete, requires runtime.Goexit()") +} + +func (c *common) skip() { + c.skipped = true +} + +// Skipped reports whether the test was skipped. +func (c *common) Skipped() bool { + return c.skipped } // TestToCall is a reference to a test that should be called during a test suite run. @@ -35,21 +173,25 @@ func (m *M) Run() int { failures := 0 for _, test := range m.Tests { t := &T{ - name: test.Name, - output: &bytes.Buffer{}, + common: common{ + name: test.Name, + output: &bytes.Buffer{}, + }, } fmt.Printf("=== RUN %s\n", test.Name) test.Func(t) - if t.failed == 0 { - fmt.Printf("--- PASS: %s\n", test.Name) - } else { + if t.failed { fmt.Printf("--- FAIL: %s\n", test.Name) + } else { + fmt.Printf("--- PASS: %s\n", test.Name) } fmt.Println(t.output) - failures += t.failed + if t.failed { + failures++ + } } if failures > 0 { @@ -62,16 +204,3 @@ func (m *M) Run() int { func TestMain(m *M) { os.Exit(m.Run()) } - -// Error is equivalent to Log followed by Fail -func (t *T) Error(args ...interface{}) { - // This doesn't print the same as in upstream go, but works good enough - // TODO: buffer test output like go does - fmt.Fprintf(t.output, "\t") - fmt.Fprintln(t.output, args...) - t.Fail() -} - -func (t *T) Fail() { - t.failed = 1 -} diff --git a/tests/tinygotest/main_test.go b/tests/tinygotest/main_test.go index 263aac149..e8594ac1f 100644 --- a/tests/tinygotest/main_test.go +++ b/tests/tinygotest/main_test.go @@ -9,10 +9,16 @@ func TestFail1(t *testing.T) { } func TestFail2(t *testing.T) { - t.Error("TestFail2 failed for reasons") + t.Fatalf("TestFail2 failed for %v ", "reasons") +} + +func TestFail3(t *testing.T) { + t.Fail() + t.Logf("TestFail3 failed for %v ", "reasons") } func TestPass(t *testing.T) { + t.Log("TestPass passed") } func BenchmarkNotImplemented(b *testing.B) { |