just build both graphs at the same time.

selection
Jordan Orelli 4 years ago
parent acb92cc4d6
commit 8659b230c8

@ -7,10 +7,43 @@ func nextNodeID() int {
return lastID
}
type node struct {
// lnode is a node in the logical graph. Developers create a logical graph in
// which nodes may have more than one parent. Each test value written by a
// developer appears as one logical node in the logical graph. The public
// documentation refers to the logical graph as simply the test graph.
type lnode struct {
id int
test Test
name string
parents []*node
children []*node
xnodes []*xnode
parents []*lnode
children []*lnode
}
// child adds an lnode as a child of the receiver. For every xnode in this
// lnode, the child lnode has a component xnode whose parent is the
// corresponding xnode in this lnode.
func (l *lnode) child(c *lnode, t Test) {
c.parents = append(c.parents, l)
l.children = append(l.children, c)
for _, x := range l.xnodes {
xchild := x.child(t)
xchild.lnode = c
c.xnodes = append(c.xnodes, xchild)
}
}
// xnode is a node in the execution graph, representing one instance of a test
// to be executed. xnode is the unit test in tea. every xnode is either
// unparented or has one parent.
type xnode struct {
lnode *lnode
test Test
parent *xnode
children []*xnode
}
func (x *xnode) child(t Test) *xnode {
child := &xnode{test: t, parent: x}
x.children = append(x.children, child)
return child
}

@ -1,41 +1,38 @@
package tea
import (
"testing"
)
func NewSelection(test Test) Selection {
n := node{test: test}
return Selection{
nodes: []*node{&n},
x := xnode{
test: clone(test),
}
}
func RunSelection(t *testing.T, s Selection) {
l := lnode{
id: nextNodeID(),
name: parseName(test),
xnodes: []*xnode{&x},
}
x.lnode = &l
return Selection{
nodes: []*lnode{&l},
}
}
// Selection represents a set of nodes in our graph.
type Selection struct {
nodes []*node
nodes []*lnode
}
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)
child := &lnode{id: nextNodeID(), name: parseName(test)}
for _, l := range s.nodes {
l.child(child, test)
}
return Selection{nodes: []*node{child}}
return Selection{nodes: []*lnode{child}}
}
func (s Selection) And(other Selection) Selection {
included := make(map[int]bool)
out := make([]*node, 0, len(s.nodes)+len(other.nodes))
out := make([]*lnode, 0, len(s.nodes)+len(other.nodes))
for _, n := range append(s.nodes, other.nodes...) {
if !included[n.id] {
out = append(out, n)

@ -1 +1,21 @@
package tea
import (
"testing"
)
func TestNewSelection(t *testing.T) {
s := NewSelection(Passing("A"))
if len(s.nodes) != 1 {
t.Fatalf("expected 1 node in new selection, saw %d", len(s.nodes))
}
l := s.nodes[0]
if len(l.children) != 0 {
t.Fatalf("new selection should not have any children, but has %d", len(l.children))
}
if len(l.xnodes) != 1 {
t.Fatalf("expected 1 xnode in lnode, saw %d", len(l.xnodes))
}
}

@ -18,9 +18,13 @@ type Test interface {
// 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)
v := reflect.ValueOf(t)
switch v.Kind() {
case reflect.Ptr:
v = v.Elem()
}
destV := reflect.New(v.Type())
destV.Elem().Set(v)
return destV.Interface().(Test)
}

Loading…
Cancel
Save