|
1 | 1 | package outline
|
2 | 2 |
|
3 | 3 | import (
|
| 4 | + "encoding/csv" |
4 | 5 | "encoding/json"
|
5 | 6 | "fmt"
|
6 | 7 | "go/parser"
|
@@ -41,6 +42,8 @@ var _ = DescribeTable("Validate outline from file with",
|
41 | 42 | Expect(err).To(BeNil(), "error reading CSV outline fixture: %s", err)
|
42 | 43 |
|
43 | 44 | Expect(gotCSV).To(Equal(string(wantCSV)))
|
| 45 | + |
| 46 | + ensureRecordsAreIdentical(csvOutlineFilename, jsonOutlineFilename) |
44 | 47 | },
|
45 | 48 | // To add a test:
|
46 | 49 | // 1. Create the input, e.g., `myspecialcase_test.go`
|
@@ -93,3 +96,111 @@ var _ = Describe("Validate position", func() {
|
93 | 96 |
|
94 | 97 | })
|
95 | 98 | })
|
| 99 | + |
| 100 | +func ensureRecordsAreIdentical(csvOutlineFilename, jsonOutlineFilename string) { |
| 101 | + csvFile, err := os.Open(filepath.Join("_testdata", csvOutlineFilename)) |
| 102 | + Expect(err).To(BeNil(), "error opening CSV outline fixture: %s", err) |
| 103 | + defer csvFile.Close() |
| 104 | + |
| 105 | + csvReader := csv.NewReader(csvFile) |
| 106 | + csvRows, err := csvReader.ReadAll() |
| 107 | + Expect(err).To(BeNil(), "error reading CSV outline fixture: %s", err) |
| 108 | + |
| 109 | + // marshal csvRows into some comparable shape |
| 110 | + csvFields := csvRows[0] |
| 111 | + var csvRecords []ginkgoMetadata |
| 112 | + for i := 1; i < len(csvRows); i++ { |
| 113 | + var record ginkgoMetadata |
| 114 | + |
| 115 | + for j, field := range csvFields { |
| 116 | + |
| 117 | + field = strings.ToLower(field) |
| 118 | + value := csvRows[i][j] |
| 119 | + |
| 120 | + switch field { |
| 121 | + case "name": |
| 122 | + record.Name = value |
| 123 | + case "text": |
| 124 | + record.Text = value |
| 125 | + case "start": |
| 126 | + start, err := strconv.Atoi(value) |
| 127 | + Expect(err).To(BeNil(), "error converting start to int: %s", err) |
| 128 | + record.Start = start |
| 129 | + case "end": |
| 130 | + end, err := strconv.Atoi(value) |
| 131 | + Expect(err).To(BeNil(), "error converting end to int: %s", err) |
| 132 | + record.End = end |
| 133 | + case "spec": |
| 134 | + spec, err := strconv.ParseBool(value) |
| 135 | + Expect(err).To(BeNil(), "error converting spec to bool: %s", err) |
| 136 | + record.Spec = spec |
| 137 | + case "focused": |
| 138 | + focused, err := strconv.ParseBool(value) |
| 139 | + Expect(err).To(BeNil(), "error converting focused to bool: %s", err) |
| 140 | + record.Focused = focused |
| 141 | + case "pending": |
| 142 | + pending, err := strconv.ParseBool(value) |
| 143 | + Expect(err).To(BeNil(), "error converting pending to bool: %s", err) |
| 144 | + record.Pending = pending |
| 145 | + case "labels": |
| 146 | + // strings.Split will return [""] for an empty string, we want [] |
| 147 | + if value == "" { |
| 148 | + record.Labels = []string{} |
| 149 | + } else { |
| 150 | + record.Labels = strings.Split(value, ", ") |
| 151 | + } |
| 152 | + default: |
| 153 | + Fail(fmt.Sprintf("unexpected field: %s", field)) |
| 154 | + } |
| 155 | + } |
| 156 | + |
| 157 | + // "By" is a special case; nil out its labels so we can compare to the parsed JSON |
| 158 | + if record.Name == "By" { |
| 159 | + record.Labels = nil |
| 160 | + } |
| 161 | + |
| 162 | + csvRecords = append(csvRecords, record) |
| 163 | + } |
| 164 | + |
| 165 | + jsonFile, err := os.Open(filepath.Join("_testdata", jsonOutlineFilename)) |
| 166 | + Expect(err).To(BeNil(), "error opening JSON outline fixture: %s", err) |
| 167 | + defer jsonFile.Close() |
| 168 | + |
| 169 | + jsonDecoder := json.NewDecoder(jsonFile) |
| 170 | + var jsonRows []ginkgoNode |
| 171 | + err = jsonDecoder.Decode(&jsonRows) |
| 172 | + Expect(err).To(BeNil(), "error reading JSON outline fixture: %s", err) |
| 173 | + |
| 174 | + // marshal jsonRows into some comparable shape - the hierarchical structure needs to be flattened |
| 175 | + var jsonRecords []ginkgoMetadata |
| 176 | + flattenNodes(jsonRows, &jsonRecords) |
| 177 | + |
| 178 | + Expect(csvRecords).To(Equal(jsonRecords)) |
| 179 | +} |
| 180 | + |
| 181 | +// flattenNodes converts the hierarchical json output into a list of records |
| 182 | +func flattenNodes(nodes []ginkgoNode, flatNodes *[]ginkgoMetadata) { |
| 183 | + for _, node := range nodes { |
| 184 | + record := ginkgoMetadata{ |
| 185 | + Name: node.Name, |
| 186 | + Text: node.Text, |
| 187 | + Start: node.Start, |
| 188 | + End: node.End, |
| 189 | + Spec: node.Spec, |
| 190 | + Focused: node.Focused, |
| 191 | + Pending: node.Pending, |
| 192 | + Labels: node.Labels, |
| 193 | + } |
| 194 | + |
| 195 | + *flatNodes = append(*flatNodes, record) |
| 196 | + |
| 197 | + // handle nested nodes |
| 198 | + if len(node.Nodes) > 0 { |
| 199 | + var nestedNodes []ginkgoNode |
| 200 | + for _, nestedNode := range node.Nodes { |
| 201 | + nestedNodes = append(nestedNodes, *nestedNode) |
| 202 | + } |
| 203 | + flattenNodes(nestedNodes, flatNodes) |
| 204 | + } |
| 205 | + } |
| 206 | +} |
0 commit comments