...
1 package internal
2
3 import "github.com/onsi/ginkgo/v2/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 }
78
View as plain text