env uses layers

g-counter
Jordan Orelli 4 years ago
parent decbb52f26
commit 1e1bbcd3d9

@ -0,0 +1,7 @@
/*
Package tea provides a tree structure for writing stateful tests, such that
child tests may utilize the side-effects of their ancestors.
*/
package tea

@ -6,8 +6,7 @@ import (
)
type env struct {
key string
value interface{}
data map[string]interface{}
parent *env
}
@ -17,7 +16,8 @@ func mkenv(test Test) *env {
}
// save looks at the Test t and saves the values of its fields marked with a
// save tag
// save tag. All of the fields for that tests are stored together as a data
// layer.
func (e *env) save(test Test) *env {
V := reflect.ValueOf(test)
if V.Type().Kind() == reflect.Ptr {
@ -25,6 +25,7 @@ func (e *env) save(test Test) *env {
}
T := V.Type()
saved := make(map[string]interface{})
for i := 0; i < T.NumField(); i++ {
f := T.Field(i)
if !isSaveField(f) {
@ -32,9 +33,11 @@ func (e *env) save(test Test) *env {
}
fv := V.Field(i)
e = &env{
key: f.Name,
value: fv.Interface(),
saved[f.Name] = fv.Interface()
}
if len(saved) > 0 {
return &env{
data: saved,
parent: e,
}
}
@ -55,15 +58,18 @@ func (e *env) load(dest Test) error {
set := false
for e := e; e != nil; e = e.parent {
if e.key == f.Name {
ev := reflect.ValueOf(e.value)
v, ok := e.data[f.Name]
if !ok {
continue
}
ev := reflect.ValueOf(v)
if ev.Type().AssignableTo(fv.Type()) {
set = true
fv.Set(ev)
break
}
}
}
if !set {
return fmt.Errorf("failed to set required field: %q", f.Name)

@ -41,12 +41,13 @@ func TestSave(t *testing.T) {
t.Fatalf("saw nil env when expecting a valid env")
}
if e.key != "Foo" {
t.Errorf("expected key %q but saw %q instead", "Foo", e.key)
foo, ok := e.data["Foo"]
if !ok {
t.Errorf("expected field Foo to be saved but was not saved")
}
if e.value != 5 {
t.Errorf("expected value %v but saw %v instead", 5, e.value)
if foo != 5 {
t.Errorf("expected value %v but saw %v instead", 5, foo)
}
})

@ -1 +0,0 @@
package tea
Loading…
Cancel
Save