bit of refactoring

actually made it longer but it's easier to read now. also the xnodes are
now directly inside of the lnodes, removing a bit of pointer
indirection.
selection
Jordan Orelli 4 years ago
parent 75849b2f36
commit 4d5a33dbdb

@ -1,5 +1,7 @@
package tea package tea
import "fmt"
var lastID int var lastID int
func nextNodeID() int { func nextNodeID() int {
@ -14,38 +16,133 @@ func nextNodeID() int {
type lnode struct { type lnode struct {
id int id int
name string name string
xnodes []*xnode xnodes []xnode
test Test
parents []*lnode parents []*lnode
children []*lnode children []*lnode
} }
// newLNode greates a new lnode with the provided test and the list of parents.
// If there are no parents, the lnode is a root node, and the provided test is
// run once. Otherwise, the provided test is used to create xnodes that are
// children of all of the provided parent nodes' xnodes.
func newLNode(test Test, parents ...*lnode) *lnode {
if len(parents) == 0 {
return rootLNode(test)
}
id := nextNodeID()
node := lnode{
id: id,
name: parseName(test),
test: test,
parents: parents,
}
xID := 0
for _, parent := range parents {
for i, _ := range parent.xnodes {
node.xnodes = append(node.xnodes, xnode{
id: xID,
lnode: &node,
parent: &parent.xnodes[i],
})
xID++
}
}
for i, _ := range node.xnodes {
xparent := node.xnodes[i]
xparent.children = append(xparent.children, &node.xnodes[i])
}
return &node
}
func rootLNode(test Test) *lnode {
id := nextNodeID()
node := lnode{
id: id,
name: parseName(test),
test: test,
}
node.xnodes = []xnode{{id: 0, lnode: &node}}
return &node
}
// child adds an lnode as a child of the receiver. For every xnode in this // child adds an lnode as a child of the receiver. For every xnode in this
// receiver, the child lnode has a component xnode whose parent is the // receiver, the child lnode has a component xnode whose parent is the
// corresponding xnode in this lnode. // corresponding xnode in this lnode.
func (l *lnode) child(c *lnode, t Test) { func (l *lnode) child(c *lnode, t Test) {
c.parents = append(c.parents, l) panic("nuh")
l.children = append(l.children, c) //c.parents = append(c.parents, l)
for i, x := range l.xnodes { //l.children = append(l.children, c)
xchild := x.child(t) //for i, x := range l.xnodes {
xchild.lnode = c // xchild := x.child(t)
xchild.id = [2]int{l.id, i + 1} // xchild.lnode = c
c.xnodes = append(c.xnodes, xchild) // xchild.id = i
} // c.xnodes = append(c.xnodes, xchild)
//}
} }
// xnode is a node in the execution graph, representing one instance of a test // 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 // to be executed. xnode is the unit test in tea. every xnode is either
// unparented or has one parent. // unparented or has one parent.
type xnode struct { type xnode struct {
id [2]int id int // id within the parent lnode
lnode *lnode lnode *lnode // corresponding node in the logical test graph
test Test
parent *xnode parent *xnode
children []*xnode children []*xnode
} }
// func newXNode(L *lnode
func (x *xnode) child(t Test) *xnode { func (x *xnode) child(t Test) *xnode {
child := &xnode{test: t, parent: x} panic("no")
x.children = append(x.children, child) // child := &xnode{test: t, parent: x}
return child // x.children = append(x.children, child)
// return child
}
func (x *xnode) isOnlyTestInLNode() bool {
return len(x.lnode.children) == 1
}
func (x *xnode) label() string {
if x.isOnlyTestInLNode() {
return x.lnode.name
}
switch {
case len(x.lnode.children) < 10:
return fmt.Sprintf("%s:%d", x.lnode.name, x.id)
case len(x.lnode.children) < 100:
return fmt.Sprintf("%s:%02d", x.lnode.name, x.id)
case len(x.lnode.children) < 1000:
return fmt.Sprintf("%s:%03d", x.lnode.name, x.id)
default:
return fmt.Sprintf("%s:%04d", x.lnode.name, x.id)
}
}
// ancestry gives a slice of xnodes beginning at the root of the x graph and
// terminating at the receiver xnode.
func (x *xnode) ancestry() []*xnode {
if x.parent == nil {
return []*xnode{x}
}
return append(x.parent.ancestry(), x)
}
// descendents gives a slice of all xnodes whose ancestry includes the receiver
// xnode, in depth-first order.
func (x *xnode) descendents() []*xnode {
if len(x.children) == 0 {
return nil
}
descendents := make([]*xnode, 0, len(x.children))
for _, c := range x.children {
descendents = append(descendents, c)
descendents = append(descendents, c.descendents()...)
}
return descendents
} }

@ -4,6 +4,5 @@ import (
"testing" "testing"
) )
func TestXNodeDot(t *testing.T) { func TestXLabels(t *testing.T) {
} }

@ -1,23 +1,7 @@
package tea package tea
import (
"io"
)
func NewSelection(test Test) Selection { func NewSelection(test Test) Selection {
x := xnode{ return Selection{nodes: []*lnode{newLNode(test)}}
test: clone(test),
}
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. // Selection represents a set of nodes in our graph.
@ -26,11 +10,8 @@ type Selection struct {
} }
func (s Selection) Child(test Test) Selection { func (s Selection) Child(test Test) Selection {
child := &lnode{id: nextNodeID(), name: parseName(test)} node := newLNode(test, s.nodes...)
for _, l := range s.nodes { return Selection{nodes: []*lnode{node}}
l.child(child, test)
}
return Selection{nodes: []*lnode{child}}
} }
func (s Selection) And(other Selection) Selection { func (s Selection) And(other Selection) Selection {
@ -47,6 +28,17 @@ func (s Selection) And(other Selection) Selection {
return Selection{nodes: out} return Selection{nodes: out}
} }
// xnodes represents all xnodes in the selected lnodes
func (s Selection) xnodes() []*xnode {
xnodes := make([]*xnode, 0, s.countXNodes())
for _, L := range s.nodes {
for _, x := range L.xnodes {
xnodes = append(xnodes, &x)
}
}
return xnodes
}
func (s Selection) countXNodes() int { func (s Selection) countXNodes() int {
total := 0 total := 0
for _, child := range s.nodes { for _, child := range s.nodes {
@ -55,6 +47,17 @@ func (s Selection) countXNodes() int {
return total return total
} }
func (s Selection) writeDOT(w io.Writer) { // func (s Selection) writeXDOT(w io.Writer) {
// xnodes := s.xnodes()
} //
// type xedge [2]string
// included := make(map[xedge]bool)
// edges := make([]xedge, 0, len(xnodes))
//
// for _, X := range xnodes {
//
// for p := X; p != nil; p = p.parent {
//
// }
// }
// }

Loading…
Cancel
Save