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 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 id int
test Test
name string name string
parents []*node xnodes []*xnode
children []*node 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 package tea
import (
"testing"
)
func NewSelection(test Test) Selection { func NewSelection(test Test) Selection {
n := node{test: test} x := xnode{
return Selection{ test: clone(test),
nodes: []*node{&n},
} }
} l := lnode{
id: nextNodeID(),
func RunSelection(t *testing.T, s Selection) { 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 { type Selection struct {
nodes []*node nodes []*lnode
} }
func (s Selection) Child(test Test) Selection { func (s Selection) Child(test Test) Selection {
child := &node{ child := &lnode{id: nextNodeID(), name: parseName(test)}
id: nextNodeID(), for _, l := range s.nodes {
test: test, l.child(child, test)
name: parseName(test),
parents: s.nodes,
}
for _, sn := range s.nodes {
sn.children = append(sn.children, child)
} }
return Selection{nodes: []*node{child}} return Selection{nodes: []*lnode{child}}
} }
func (s Selection) And(other Selection) Selection { func (s Selection) And(other Selection) Selection {
included := make(map[int]bool) 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...) { for _, n := range append(s.nodes, other.nodes...) {
if !included[n.id] { if !included[n.id] {
out = append(out, n) out = append(out, n)

@ -1 +1,21 @@
package tea 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 // like, kinda on you though, I can't really enforce things that the Go type
// system doesn't let me enforce. // system doesn't let me enforce.
func clone(t Test) Test { func clone(t Test) Test {
srcV := reflect.ValueOf(t).Elem() v := reflect.ValueOf(t)
destV := reflect.New(srcV.Type()) switch v.Kind() {
destV.Elem().Set(srcV) case reflect.Ptr:
v = v.Elem()
}
destV := reflect.New(v.Type())
destV.Elem().Set(v)
return destV.Interface().(Test) return destV.Interface().(Test)
} }

Loading…
Cancel
Save