diff --git a/node.go b/node.go new file mode 100644 index 0000000..ded42d2 --- /dev/null +++ b/node.go @@ -0,0 +1,16 @@ +package tea + +var lastID int + +func nextNodeID() int { + lastID++ + return lastID +} + +type node struct { + id int + test Test + name string + parents []*node + children []*node +} diff --git a/selection.go b/selection.go new file mode 100644 index 0000000..90a2334 --- /dev/null +++ b/selection.go @@ -0,0 +1,47 @@ +package tea + +import ( + "testing" +) + +func NewSelection(test Test) Selection { + n := node{test: test} + return Selection{ + nodes: []*node{&n}, + } +} + +func RunSelection(t *testing.T, s Selection) { + +} + +type Selection struct { + nodes []*node +} + +func (s Selection) Child(test Test) Selection { + child := &node{ + id: nextNodeID(), + test: test, + name: parseName(test), + parents: s.nodes, + } + for _, sn := range s.nodes { + sn.children = append(sn.children, child) + } + return Selection{nodes: []*node{child}} +} + +func (s Selection) And(other Selection) Selection { + included := make(map[int]bool) + + out := make([]*node, 0, len(s.nodes)+len(other.nodes)) + for _, n := range append(s.nodes, other.nodes...) { + if !included[n.id] { + out = append(out, n) + included[n.id] = true + } + } + + return Selection{nodes: out} +} diff --git a/selection_test.go b/selection_test.go new file mode 100644 index 0000000..f9164ac --- /dev/null +++ b/selection_test.go @@ -0,0 +1 @@ +package tea diff --git a/test.go b/test.go index 7bd6c3c..218b2f0 100644 --- a/test.go +++ b/test.go @@ -12,6 +12,18 @@ type Test interface { Run(*testing.T) } +// clone clones a test value, yielding a new test value that can be executed +// and mutated such that the original is not mutated. Tests containing pointers +// to objects that were not created by tea will probably not work right. That's +// like, kinda on you though, I can't really enforce things that the Go type +// system doesn't let me enforce. +func clone(t Test) Test { + srcV := reflect.ValueOf(t).Elem() + destV := reflect.New(srcV.Type()) + destV.Elem().Set(srcV) + return destV.Interface().(Test) +} + // After defines the interface used for performing test cleanup. If a Test // value also implements After, that test's After method will be called after // all tests are run. Tests in a sequence will have their After methods called diff --git a/tree.go b/tree.go index 4bafc79..684557a 100644 --- a/tree.go +++ b/tree.go @@ -100,15 +100,6 @@ func (t *Tree) Child(test Test) *Tree { return child } -// clone clones a test value, yielding a new test value that can be executed -// and mutated such that the original is not mutated. -func clone(t Test) Test { - srcV := reflect.ValueOf(t).Elem() - destV := reflect.New(srcV.Type()) - destV.Elem().Set(srcV) - return destV.Interface().(Test) -} - // isSaveField takes a struct field and checks its tags for a save tag, // indicating that the field's value should persist between tests func isSaveField(f reflect.StructField) bool {