github.com/redhat-appstudio/e2e-tests@v0.0.0-20240520140907-9709f6f59323/pkg/testspecs/textspec.go (about) 1 package testspecs 2 3 import ( 4 "os" 5 "path/filepath" 6 "strings" 7 8 "k8s.io/klog/v2" 9 ) 10 11 type TextSpecTranslator struct { 12 } 13 14 // New returns a Ginkgo Spec Translator 15 func NewTextSpecTranslator() *TextSpecTranslator { 16 17 return &TextSpecTranslator{} 18 } 19 20 // FromFile generates a TestOutline from a Text outline File 21 func (tst *TextSpecTranslator) FromFile(file string) (TestOutline, error) { 22 23 var outline TestOutline 24 //var node TestSpecNode 25 outlineData, err := os.ReadFile(file) 26 if err != nil { 27 return nil, err 28 } 29 30 if err != nil { 31 return nil, err 32 } 33 outlineStr := string(outlineData) 34 // Need this bit of code in case someone writes the text spec in a google doc and exports it as plain text file 35 stringByteOrderMark := string('\uFEFF') 36 if strings.ContainsRune(outlineStr, '\uFEFF') { 37 outlineStr = strings.TrimPrefix(outlineStr, stringByteOrderMark) 38 } 39 40 for _, part := range strings.Split(outlineStr, "\n") { 41 if !strings.Contains("\n", part) { 42 node := createTestSpecNodesFromString(part) 43 outline = graphNodeToTestSpecOutline(outline, node) 44 } 45 46 } 47 48 return outline, nil 49 } 50 51 // ToFile generates a Text outline file from a TestOutline 52 func (tst *TextSpecTranslator) ToFile(destination string, outline TestOutline) error { 53 dir := filepath.Dir(destination) 54 err := os.MkdirAll(dir, 0775) 55 if err != nil { 56 klog.Errorf("failed to create package directory, %s, template with: %v", dir, err) 57 return err 58 } 59 f, err := os.Create(destination) 60 if err != nil { 61 klog.Infof("Failed to create file: %v", err) 62 return err 63 } 64 65 defer f.Close() 66 67 err = os.WriteFile(destination, []byte(outline.ToString()), 0644) 68 69 if err != nil { 70 return err 71 } 72 klog.Infof("successfully written to %s", destination) 73 74 return err 75 76 } 77 78 // createTestSpecNodesFromString takes a string line and builds 79 // a TestSpecNode that will be graphed later to form our tree 80 // outline 81 func createTestSpecNodesFromString(part string) TestSpecNode { 82 83 outlineSlice := strings.Split(part, "\n") 84 var node TestSpecNode 85 for _, o := range outlineSlice { 86 // replace the carriage return if spec outline was initially generated from Windows/GDoc 87 o := strings.Replace(o, "\r", "", -1) 88 whiteSpaces := len(o) - len(strings.TrimLeft(o, " ")) 89 //skip over empty new lines 90 if whiteSpaces == 0 && len(o) == 0 { 91 continue 92 } 93 94 node = TestSpecNode{} 95 node.Name = strings.Trim(strings.Split(o, ":")[0], " ") 96 txt := strings.Trim(strings.Split(o, ":")[1], " ") 97 if strings.Contains(txt, "@") { 98 labels := strings.Split(txt, "@")[1:] 99 for _, l := range labels { 100 noCommaL := strings.Replace(l, ",", "", -1) 101 node.Labels = append(node.Labels, strings.TrimRight(strings.TrimLeft(noCommaL, " "), " ")) 102 if strings.HasPrefix(l, "@") { 103 node.Labels = append(node.Labels, strings.TrimLeft(l[1:], " ")) 104 } 105 } 106 txt = strings.Split(txt, "@")[0] 107 } 108 109 node.Text = txt 110 node.Nodes = make(TestOutline, 0) 111 node.LineSpaceLevel = whiteSpaces 112 113 } 114 115 return node 116 117 } 118 119 // graphNodeToTestSpecOutline will take the node built and graph it within the outline 120 // to create the hierarchical tree 121 func graphNodeToTestSpecOutline(nodes TestOutline, node TestSpecNode) TestOutline { 122 123 if len(nodes) == 0 { 124 125 nodes = append(nodes, node) 126 return nodes 127 } 128 129 if len(nodes) > 0 { 130 131 if nodes[len(nodes)-1].LineSpaceLevel == node.LineSpaceLevel { 132 nodes = append(nodes, node) 133 return nodes 134 } 135 136 if nodes[len(nodes)-1].LineSpaceLevel < node.LineSpaceLevel { 137 nodes[len(nodes)-1].Nodes = graphNodeToTestSpecOutline(nodes[len(nodes)-1].Nodes, node) 138 return nodes 139 140 } 141 } 142 143 return nodes 144 }