github.com/onsi/ginkgo@v1.16.6-0.20211118180735-4e1925ba4c95/internal/tree.go (about) 1 package internal 2 3 import "github.com/onsi/ginkgo/types" 4 5 type TreeNode struct { 6 Node Node 7 Parent *TreeNode 8 Children TreeNodes 9 } 10 11 func (tn *TreeNode) AppendChild(child *TreeNode) { 12 tn.Children = append(tn.Children, child) 13 child.Parent = tn 14 } 15 16 func (tn *TreeNode) AncestorNodeChain() Nodes { 17 if tn.Parent == nil || tn.Parent.Node.IsZero() { 18 return Nodes{tn.Node} 19 } 20 return append(tn.Parent.AncestorNodeChain(), tn.Node) 21 } 22 23 type TreeNodes []*TreeNode 24 25 func (tn TreeNodes) Nodes() Nodes { 26 out := make(Nodes, len(tn)) 27 for i := range tn { 28 out[i] = tn[i].Node 29 } 30 return out 31 } 32 33 func (tn TreeNodes) WithID(id uint) *TreeNode { 34 for i := range tn { 35 if tn[i].Node.ID == id { 36 return tn[i] 37 } 38 } 39 40 return nil 41 } 42 43 func GenerateSpecsFromTreeRoot(tree *TreeNode) Specs { 44 var walkTree func(nestingLevel int, lNodes Nodes, rNodes Nodes, trees TreeNodes) Specs 45 walkTree = func(nestingLevel int, lNodes Nodes, rNodes Nodes, trees TreeNodes) Specs { 46 tests := Specs{} 47 48 nodes := make(Nodes, len(trees)) 49 for i := range trees { 50 nodes[i] = trees[i].Node 51 nodes[i].NestingLevel = nestingLevel 52 } 53 54 for i := range nodes { 55 if !nodes[i].NodeType.Is(types.NodeTypesForContainerAndIt) { 56 continue 57 } 58 leftNodes, rightNodes := nodes.SplitAround(nodes[i]) 59 leftNodes = leftNodes.WithoutType(types.NodeTypesForContainerAndIt) 60 rightNodes = rightNodes.WithoutType(types.NodeTypesForContainerAndIt) 61 62 leftNodes = lNodes.CopyAppend(leftNodes...) 63 rightNodes = rightNodes.CopyAppend(rNodes...) 64 65 if nodes[i].NodeType.Is(types.NodeTypeIt) { 66 tests = append(tests, Spec{Nodes: leftNodes.CopyAppend(nodes[i]).CopyAppend(rightNodes...)}) 67 } else { 68 treeNode := trees.WithID(nodes[i].ID) 69 tests = append(tests, walkTree(nestingLevel+1, leftNodes.CopyAppend(nodes[i]), rightNodes, treeNode.Children)...) 70 } 71 } 72 73 return tests 74 } 75 76 return walkTree(0, Nodes{}, Nodes{}, tree.Children) 77 }