export a Passing type

I keep writing these one-off when I actually use tea. It seems like it's
worth including. It's especially useful for the root test, where you
don't necessarily want to create a test, but want to create a starting
environment. Exporting a type that always passes is preferrable to
making an explicit environment type, since we can maintain our
guarantees that our environment isn't an invalid value.
g-counter
Jordan Orelli 4 years ago
parent 7f8a3d64b9
commit a3346f59cc

@ -25,6 +25,10 @@ func (e *env) save(test Test) *env {
} }
T := V.Type() T := V.Type()
if T.Kind() != reflect.Struct {
return e
}
saved := make(map[string]interface{}) saved := make(map[string]interface{})
for i := 0; i < T.NumField(); i++ { for i := 0; i < T.NumField(); i++ {
f := T.Field(i) f := T.Field(i)

@ -6,7 +6,7 @@ import (
func TestSave(t *testing.T) { func TestSave(t *testing.T) {
t.Run("empty begets nil", func(t *testing.T) { t.Run("empty begets nil", func(t *testing.T) {
e := mkenv(new(empty)) e := mkenv(Pass)
if e != nil { if e != nil {
t.Errorf("saw unexpected env value looking for nil: %v", e) t.Errorf("saw unexpected env value looking for nil: %v", e)
} }
@ -14,7 +14,7 @@ func TestSave(t *testing.T) {
t.Run("unexported fields are ignored", func(t *testing.T) { t.Run("unexported fields are ignored", func(t *testing.T) {
type test struct { type test struct {
empty Passing
foo int `tea:"save"` foo int `tea:"save"`
} }
@ -25,7 +25,7 @@ func TestSave(t *testing.T) {
t.Run("create an env from a test", func(t *testing.T) { t.Run("create an env from a test", func(t *testing.T) {
test := struct { test := struct {
empty Passing
Foo int `tea:"save"` Foo int `tea:"save"`
}{ }{
Foo: 5, Foo: 5,
@ -48,7 +48,7 @@ func TestSave(t *testing.T) {
t.Run("update an existing env", func(t *testing.T) { t.Run("update an existing env", func(t *testing.T) {
test := struct { test := struct {
empty Passing
Foo int `tea:"save"` Foo int `tea:"save"`
}{ }{
Foo: 5, Foo: 5,
@ -77,7 +77,7 @@ func TestLoad(t *testing.T) {
} }
var test struct { var test struct {
empty Passing
Foo int `tea:"load"` Foo int `tea:"load"`
} }
@ -95,7 +95,7 @@ func TestLoad(t *testing.T) {
} }
var test struct { var test struct {
empty Passing
Foo int `tea:"load"` Foo int `tea:"load"`
} }
@ -110,7 +110,7 @@ func TestLoad(t *testing.T) {
} }
var test struct { var test struct {
empty Passing
Foo int `tea:"load"` Foo int `tea:"load"`
} }
test.Foo = 5 test.Foo = 5
@ -131,7 +131,7 @@ func TestMatch(t *testing.T) {
} }
var test struct { var test struct {
empty Passing
Name string `tea:"match"` Name string `tea:"match"`
Foo int `tea:"load"` Foo int `tea:"load"`
} }
@ -150,7 +150,7 @@ func TestMatch(t *testing.T) {
} }
var test struct { var test struct {
empty Passing
Name string `tea:"match"` Name string `tea:"match"`
Foo int `tea:"load"` Foo int `tea:"load"`
} }
@ -170,7 +170,7 @@ func TestMatch(t *testing.T) {
} }
var test struct { var test struct {
empty Passing
Name string `tea:"match"` Name string `tea:"match"`
Foo int `tea:"load"` Foo int `tea:"load"`
} }
@ -199,7 +199,7 @@ func TestMatch(t *testing.T) {
} }
var test struct { var test struct {
empty Passing
Name string `tea:"match"` Name string `tea:"match"`
Foo int `tea:"load"` Foo int `tea:"load"`
} }

@ -12,6 +12,9 @@ type response struct {
Hits int `json:"hits"` Hits int `json:"hits"`
} }
// server implements an http hit-counter server. The hit-count server responds
// to GET requests with the number of responses it has seen for that path,
// inclusive of the request itself (i.e., starting at 1).
type server struct { type server struct {
sync.Mutex sync.Mutex
counters map[string]int counters map[string]int

@ -33,12 +33,14 @@ func (f failure) Run(t *testing.T) {
t.Error(f.cause.Error()) t.Error(f.cause.Error())
} }
// empty is an empty test. It does nothing when run, it's just used as a // Pass is a Test value that always passes.
// sentinel value to create notes in the test graph and for ... testing the tea const Pass = Passing("test passed")
// package itself.
type empty struct{}
func (e empty) Run(t *testing.T) {} // Passing is a Test type that always passes. Every value of the Passing type,
// including the zero value, is a test that will always pass.
type Passing string
func (p Passing) Run(t *testing.T) {}
// parseName parses the name for a given test // parseName parses the name for a given test
func parseName(test Test) string { func parseName(test Test) string {

@ -53,10 +53,10 @@ func exec(t *testing.T, tree *Tree) ([]Test, *env) {
history, e := exec(t, tree.parent) history, e := exec(t, tree.parent)
test := clone(tree.test) test := clone(tree.test)
if err := e.load(test); err != nil { if err := e.load(test); err != nil {
// TODO: figure out how to handle load failures like this. t.Errorf("test plan failed: %s", err)
panic("load failure: " + err.Error()) } else {
test.Run(t)
} }
test.Run(t)
return append([]Test{test}, history...), e.save(test) return append([]Test{test}, history...), e.save(test)
} }

Loading…
Cancel
Save