/
sql.go
140 lines (119 loc) · 3.36 KB
/
sql.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
// Runes a SQL statement against the DB
//
// When I run SQL "UPDATE connectors SET connector_type_id='foo' WHERE id = '${connector_id}';" expect 1 row to be affected.
//
// Runes a SQL statement against the DB and check the results
//
// And I run SQL "SELECT count(*) from connector_deployments where connector_id='${connector_id}'" gives results:
// | count |
// | 0 |
package cucumber
import (
"fmt"
"github.com/nexodus-io/nexodus/internal/util"
"reflect"
"strings"
"github.com/cucumber/godog"
"github.com/olekukonko/tablewriter"
"github.com/pmezard/go-difflib/difflib"
)
func init() {
StepModules = append(StepModules, func(ctx *godog.ScenarioContext, s *TestScenario) {
ctx.Step(`^I run SQL "([^"]*)" expect (\d+) row to be affected\.$`, s.iRunSQLExpectRowToBeAffected)
ctx.Step(`^I run SQL "([^"]*)" gives results:$`, s.iRunSQLGivesResults)
})
}
func (s *TestScenario) iRunSQLExpectRowToBeAffected(sql string, expected int64) error {
var err error
sql, err = s.Expand(sql)
if err != nil {
return err
}
gorm := s.Suite.DB
exec := gorm.Exec(sql)
if exec.Error != nil {
return exec.Error
}
if exec.RowsAffected != expected {
return fmt.Errorf("expected %d rows to be affected but %d were affected", expected, exec.RowsAffected)
}
return nil
}
//type TableRow = messages.PickleStepArgument_PickleTable_PickleTableRow
//type TableCell = messages.PickleStepArgument_PickleTable_PickleTableRow_PickleTableCell
func (s *TestScenario) iRunSQLGivesResults(sql string, expected *godog.Table) error {
var err error
sql, err = s.Expand(sql)
if err != nil {
return err
}
gorm := s.Suite.DB
rows, err := gorm.Raw(sql).Rows()
if err != nil {
return err
}
defer util.IgnoreError(rows.Close)
var actualTable [][]string
cols, err := rows.Columns()
if err != nil {
return err
}
actualTable = append(actualTable, cols)
// add the header rows.
for rows.Next() {
columns := make([]interface{}, len(cols))
columnsPtr := make([]interface{}, len(cols))
for i := range columns {
columnsPtr[i] = &columns[i]
}
err = rows.Scan(columnsPtr...)
if err != nil {
return err
}
var rowString []string
for _, c := range columns {
cell := fmt.Sprintf("%v", c)
rowString = append(rowString, cell)
}
actualTable = append(actualTable, rowString)
}
expectedTable := GodogTableToStringTable(expected)
if !reflect.DeepEqual(expectedTable, actualTable) {
expected := StringTableToCucumberTable(expectedTable)
actual := StringTableToCucumberTable(actualTable)
diff, _ := difflib.GetUnifiedDiffString(difflib.UnifiedDiff{
A: difflib.SplitLines(expected),
B: difflib.SplitLines(actual),
FromFile: "Expected",
FromDate: "",
ToFile: "Actual",
ToDate: "",
Context: 1,
})
return fmt.Errorf("actual does not match expected, diff:\n%s", diff)
}
return nil
}
func GodogTableToStringTable(table *godog.Table) [][]string {
data := make([][]string, len(table.Rows))
for r, row := range table.Rows {
data[r] = make([]string, len(row.Cells))
for c, cell := range row.Cells {
data[r][c] = cell.Value
}
}
return data
}
func StringTableToCucumberTable(data [][]string) string {
buf := &strings.Builder{}
table := tablewriter.NewWriter(buf)
table.SetBorders(tablewriter.Border{
Left: true,
Right: true,
Top: false,
Bottom: false,
})
table.AppendBulk(data)
table.Render()
return buf.String()
}