Skip to content

Commit

Permalink
Merge pull request #56 from JustSkiv/add-mysql-support-fixtures
Browse files Browse the repository at this point in the history
Add mysql support in fixtures
  • Loading branch information
Denis authored Sep 3, 2020
2 parents 15b8a86 + cc25451 commit 526496b
Show file tree
Hide file tree
Showing 11 changed files with 1,410 additions and 540 deletions.
518 changes: 43 additions & 475 deletions fixtures/loader.go

Large diffs are not rendered by default.

554 changes: 554 additions & 0 deletions fixtures/mysql/mysql.go

Large diffs are not rendered by default.

237 changes: 237 additions & 0 deletions fixtures/mysql/mysql_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,237 @@
package mysql

import (
"database/sql"
"database/sql/driver"
"fmt"
"io/ioutil"
"strings"
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"gopkg.in/DATA-DOG/go-sqlmock.v1"
)

func TestBuildInsertQuery(t *testing.T) {

ymlFile, err := ioutil.ReadFile("../testdata/table.yaml")
require.NoError(t, err)

expected := []string{
"INSERT INTO `table` (`field1`, `field2`) VALUES ('value1', 1)",
"INSERT INTO `table` (`field1`, `field2`, `field3`) VALUES ('value2', 2, 2.5699477736545666)",
"INSERT INTO `table` (`field1`, `field4`, `field5`) VALUES ('\"', false, NULL)",
"INSERT INTO `table` (`field1`, `field5`) VALUES ('''', '[1,\"2\"]')",
}

ctx := loadContext{
refsDefinition: make(map[string]row),
refsInserted: make(map[string]row),
}

l := New(&sql.DB{}, "", false)

require.NoError(t,
l.loadYml(ymlFile, &ctx),
)

for i, row := range ctx.tables[0].Rows {
query, err := l.buildInsertQuery(&ctx, "table", row)
require.NoError(t, err)

assert.Equal(t, expected[i], query)
}
}

func TestLoadTablesShouldResolveRefs(t *testing.T) {
yml, err := ioutil.ReadFile("../testdata/table_refs.yaml")
require.NoError(t, err)

db, mock, err := sqlmock.New()
if err != nil {
t.Fatalf("an error '%s' was not expected when opening a stub database connection", err)
}
defer func() { _ = db.Close() }()

ctx := loadContext{
refsDefinition: make(map[string]row),
refsInserted: make(map[string]row),
}

l := New(db, "", true)

if err = l.loadYml(yml, &ctx); err != nil {
t.Error(err)
t.Fail()
}

mock.ExpectBegin()

expectTruncate(mock, "table1")
expectTruncate(mock, "table2")
expectTruncate(mock, "table3")

// table1
expectInsert(t, mock,
"table1",
[]string{"f1", "f2"},
"\\('value1', 'value2'\\)",
[]string{"value1", "value2"},
)

// table2
expectInsert(t, mock,
"table2",
[]string{"f1", "f2"},
"\\('value2', 'value1'\\)",
[]string{"value2", "value1"},
)

// table1
expectInsert(t, mock,
"table3",
[]string{"f1", "f2"},
"\\('value1', 'value2'\\)",
[]string{"value1", "value2"},
)

mock.ExpectCommit()

err = l.loadTables(&ctx)
if err != nil {
t.Error(err)
t.Fail()
}

if err := mock.ExpectationsWereMet(); err != nil {
t.Errorf("there were unfulfilled expectations: %s", err)
t.Fail()
}
}

func TestLoadTablesShouldExtendRows(t *testing.T) {
yml, err := ioutil.ReadFile("../testdata/table_extend.yaml")
require.NoError(t, err)

db, mock, err := sqlmock.New()
if err != nil {
t.Fatalf("an error '%s' was not expected when opening a stub database connection", err)
}
defer func() { _ = db.Close() }()

ctx := loadContext{
refsDefinition: make(map[string]row),
refsInserted: make(map[string]row),
}

l := New(db, "", true)

if err = l.loadYml(yml, &ctx); err != nil {
t.Error(err)
t.Fail()
}

mock.ExpectBegin()

expectTruncate(mock, "table1")
expectTruncate(mock, "table2")
expectTruncate(mock, "table3")

// table1
expectInsert(t, mock,
"table1",
[]string{"f1", "f2"},
"\\('value1', 'value2'\\)",
[]string{"value1", "value2"},
)

// table2
expectInsert(t, mock,
"table2",
[]string{"f1", "f2", "f3"},
"\\('value1 overwritten', 'value2', "+`\("1" \|\| "2" \|\| 3 \+ 5\)\)$`,
[]string{"value1 overwritten", "value2", `1`},
)

// table3, data 1
expectInsert(t, mock,
"table3",
[]string{"f1", "f2", "f3"},
"\\('value1 overwritten', 'value2', "+`\("1" \|\| "2" \|\| 3 \+ 5\)\)$`,
[]string{"value1 overwritten", "value2", `1`},
)

// table3, data 2
expectInsert(t, mock,
"table3",
[]string{"f1", "f2"},
"\\('tplVal1', 'tplVal2'\\)",
[]string{"tplVal1", "tplVal2"},
)

mock.ExpectCommit()

err = l.loadTables(&ctx)
if err != nil {
t.Error(err)
t.Fail()
}

if err := mock.ExpectationsWereMet(); err != nil {
t.Errorf("there were unfulfilled expectations: %s", err)
t.Fail()
}
}

var idCounter int64

func expectInsert(
t *testing.T,
mock sqlmock.Sqlmock,
table string,
fields []string,
valuesToInsert string,
valuesResult []string,
) {

t.Helper()

idCounter++

mock.ExpectExec(
fmt.Sprintf("^INSERT INTO `%s` %s VALUES %s$",
table,
fieldsToDbStr(fields),
valuesToInsert,
),
).
WillReturnResult(sqlmock.NewResult(idCounter, 1))

var valuesRow []driver.Value
for _, v := range valuesResult {
valuesRow = append(valuesRow, driver.Value(v))
}

mock.ExpectQuery(fmt.Sprintf("^SELECT \\* FROM `%s` WHERE `id` = \\?$", table)).
WithArgs(idCounter).
WillReturnRows(
sqlmock.NewRows(fields).
AddRow(valuesRow...),
)
}

func expectTruncate(mock sqlmock.Sqlmock, table string) {
mock.ExpectExec(fmt.Sprintf("^TRUNCATE TABLE `%s`$", table)).
WillReturnResult(sqlmock.NewResult(0, 0))
}

func fieldsToDbStr(values []string) string {
quotedVals := make([]string, len(values))

for i, val := range values {
quotedVals[i] = "`" + val + "`"
}

return "\\(" + strings.Join(quotedVals, ", ") + "\\)"
}
Loading

0 comments on commit 526496b

Please sign in to comment.