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
import "fmt"
var lastID int
func nextNodeID() int {
@ -14,38 +16,133 @@ func nextNodeID() int {
type lnode struct {
id int
name string
xnodes []*xnode
xnodes []xnode
test Test
parents []*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
// receiver, 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 i, x := range l.xnodes {
xchild := x.child(t)
xchild.lnode = c
xchild.id = [2]int{l.id, i + 1}
c.xnodes = append(c.xnodes, xchild)
}
panic("nuh")
//c.parents = append(c.parents, l)
//l.children = append(l.children, c)
//for i, x := range l.xnodes {
// xchild := x.child(t)
// xchild.lnode = c
// xchild.id = i
// 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 {
id [2]int
lnode *lnode
test Test
id int // id within the parent lnode
lnode *lnode // corresponding node in the logical test graph
parent *xnode
children []*xnode
}
// func newXNode(L *lnode
func (x *xnode) child(t Test) *xnode {
child := &xnode{test: t, parent: x}
x.children = append(x.children, child)
return child
panic("no")
// child := &xnode{test: t, parent: x}
// 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"
)
func TestXNodeDot(t *testing.T) {
func TestXLabels(t *testing.T) {
}

@ -1,23 +1,7 @@
package tea
import (
"io"
)
func NewSelection(test Test) Selection {
x := xnode{
test: clone(test),
}
l := lnode{
id: nextNodeID(),
name: parseName(test),
xnodes: []*xnode{&x},
}
x.lnode = &l
return Selection{
nodes: []*lnode{&l},
}
return Selection{nodes: []*lnode{newLNode(test)}}
}
// Selection represents a set of nodes in our graph.
@ -26,11 +10,8 @@ type Selection struct {
}
func (s Selection) Child(test Test) Selection {
child := &lnode{id: nextNodeID(), name: parseName(test)}
for _, l := range s.nodes {
l.child(child, test)
}
return Selection{nodes: []*lnode{child}}
node := newLNode(test, s.nodes...)
return Selection{nodes: []*lnode{node}}
}
func (s Selection) And(other Selection) Selection {
@ -47,6 +28,17 @@ func (s Selection) And(other Selection) Selection {
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 {
total := 0
for _, child := range s.nodes {
@ -55,6 +47,17 @@ func (s Selection) countXNodes() int {
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