2019-07-29 18:08:53 +02:00
|
|
|
package testutils
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"bytes"
|
|
|
|
|
"encoding/json"
|
|
|
|
|
"fmt"
|
2020-06-27 18:48:19 +02:00
|
|
|
"github.com/go-jet/jet/v2/internal/jet"
|
2021-07-27 17:39:21 +02:00
|
|
|
"github.com/go-jet/jet/v2/internal/utils/throw"
|
2020-06-27 18:48:19 +02:00
|
|
|
"github.com/go-jet/jet/v2/qrm"
|
2020-05-02 22:15:38 +02:00
|
|
|
"github.com/google/uuid"
|
2021-05-03 18:48:15 +02:00
|
|
|
"github.com/stretchr/testify/assert"
|
2020-04-12 18:53:57 +02:00
|
|
|
"github.com/stretchr/testify/require"
|
2019-07-29 18:08:53 +02:00
|
|
|
"io/ioutil"
|
2019-08-08 10:51:59 +02:00
|
|
|
"os"
|
|
|
|
|
"path/filepath"
|
2019-07-29 18:08:53 +02:00
|
|
|
"runtime"
|
|
|
|
|
"testing"
|
2020-05-02 22:15:38 +02:00
|
|
|
"time"
|
2020-02-11 10:25:13 +01:00
|
|
|
|
|
|
|
|
"github.com/google/go-cmp/cmp"
|
2019-07-29 18:08:53 +02:00
|
|
|
)
|
|
|
|
|
|
2021-10-21 13:39:24 +02:00
|
|
|
// UnixTimeComparer will compare time equality while ignoring time zone
|
|
|
|
|
var UnixTimeComparer = cmp.Comparer(func(t1, t2 time.Time) bool {
|
|
|
|
|
return t1.Unix() == t2.Unix()
|
|
|
|
|
})
|
|
|
|
|
|
2019-08-17 18:32:01 +02:00
|
|
|
// AssertExec assert statement execution for successful execution and number of rows affected
|
2019-09-27 11:46:31 +02:00
|
|
|
func AssertExec(t *testing.T, stmt jet.Statement, db qrm.DB, rowsAffected ...int64) {
|
2019-08-02 11:08:24 +02:00
|
|
|
res, err := stmt.Exec(db)
|
|
|
|
|
|
2020-05-03 20:46:21 +02:00
|
|
|
require.NoError(t, err)
|
2019-08-02 11:08:24 +02:00
|
|
|
rows, err := res.RowsAffected()
|
2020-05-03 20:46:21 +02:00
|
|
|
require.NoError(t, err)
|
2019-08-02 11:08:24 +02:00
|
|
|
|
|
|
|
|
if len(rowsAffected) > 0 {
|
2020-06-01 20:30:09 +02:00
|
|
|
require.Equal(t, rowsAffected[0], rows)
|
2019-08-02 11:08:24 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-08-17 18:32:01 +02:00
|
|
|
// AssertExecErr assert statement execution for failed execution with error string errorStr
|
2019-09-27 11:46:31 +02:00
|
|
|
func AssertExecErr(t *testing.T, stmt jet.Statement, db qrm.DB, errorStr string) {
|
2019-08-02 11:08:24 +02:00
|
|
|
_, err := stmt.Exec(db)
|
|
|
|
|
|
2020-05-09 11:00:22 +02:00
|
|
|
require.Error(t, err, errorStr)
|
2019-08-02 11:08:24 +02:00
|
|
|
}
|
|
|
|
|
|
2019-08-08 10:51:59 +02:00
|
|
|
func getFullPath(relativePath string) string {
|
2020-06-27 18:48:19 +02:00
|
|
|
path, _ := os.Getwd()
|
|
|
|
|
return filepath.Join(path, "../", relativePath)
|
2019-08-08 10:51:59 +02:00
|
|
|
}
|
|
|
|
|
|
2019-08-17 18:32:01 +02:00
|
|
|
// PrintJson print v as json
|
2019-08-08 10:51:59 +02:00
|
|
|
func PrintJson(v interface{}) {
|
|
|
|
|
jsonText, _ := json.MarshalIndent(v, "", "\t")
|
|
|
|
|
fmt.Println(string(jsonText))
|
|
|
|
|
}
|
|
|
|
|
|
2022-01-05 18:00:20 +01:00
|
|
|
// ToJSON converts v into json string
|
|
|
|
|
func ToJSON(v interface{}) string {
|
|
|
|
|
jsonText, _ := json.MarshalIndent(v, "", "\t")
|
|
|
|
|
return string(jsonText)
|
|
|
|
|
}
|
|
|
|
|
|
2019-08-17 18:32:01 +02:00
|
|
|
// AssertJSON check if data json output is the same as expectedJSON
|
2019-08-06 11:41:45 +02:00
|
|
|
func AssertJSON(t *testing.T, data interface{}, expectedJSON string) {
|
2019-07-29 18:08:53 +02:00
|
|
|
jsonData, err := json.MarshalIndent(data, "", "\t")
|
2020-05-09 11:00:22 +02:00
|
|
|
require.NoError(t, err)
|
2019-07-29 18:08:53 +02:00
|
|
|
|
2022-02-09 12:41:58 +01:00
|
|
|
dataJson := "\n" + string(jsonData) + "\n"
|
|
|
|
|
require.Equal(t, dataJson, expectedJSON)
|
2019-07-29 18:08:53 +02:00
|
|
|
}
|
|
|
|
|
|
2019-08-17 18:32:01 +02:00
|
|
|
// SaveJSONFile saves v as json at testRelativePath
|
|
|
|
|
func SaveJSONFile(v interface{}, testRelativePath string) {
|
2019-08-08 10:51:59 +02:00
|
|
|
jsonText, _ := json.MarshalIndent(v, "", "\t")
|
|
|
|
|
|
|
|
|
|
filePath := getFullPath(testRelativePath)
|
|
|
|
|
err := ioutil.WriteFile(filePath, jsonText, 0644)
|
|
|
|
|
|
2021-07-27 17:39:21 +02:00
|
|
|
throw.OnError(err)
|
2019-08-08 10:51:59 +02:00
|
|
|
}
|
|
|
|
|
|
2019-08-17 18:32:01 +02:00
|
|
|
// AssertJSONFile check if data json representation is the same as json at testRelativePath
|
2019-08-08 10:51:59 +02:00
|
|
|
func AssertJSONFile(t *testing.T, data interface{}, testRelativePath string) {
|
|
|
|
|
|
|
|
|
|
filePath := getFullPath(testRelativePath)
|
|
|
|
|
fileJSONData, err := ioutil.ReadFile(filePath)
|
2020-05-09 11:00:22 +02:00
|
|
|
require.NoError(t, err)
|
2019-07-29 18:08:53 +02:00
|
|
|
|
|
|
|
|
if runtime.GOOS == "windows" {
|
|
|
|
|
fileJSONData = bytes.Replace(fileJSONData, []byte("\r\n"), []byte("\n"), -1)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
jsonData, err := json.MarshalIndent(data, "", "\t")
|
2020-05-09 11:00:22 +02:00
|
|
|
require.NoError(t, err)
|
2019-07-29 18:08:53 +02:00
|
|
|
|
2020-05-09 11:00:22 +02:00
|
|
|
require.True(t, string(fileJSONData) == string(jsonData))
|
2020-02-11 10:25:13 +01:00
|
|
|
//AssertDeepEqual(t, string(fileJSONData), string(jsonData))
|
2019-07-29 18:08:53 +02:00
|
|
|
}
|
|
|
|
|
|
2019-08-17 18:32:01 +02:00
|
|
|
// AssertStatementSql check if statement Sql() is the same as expectedQuery and expectedArgs
|
2019-07-29 18:08:53 +02:00
|
|
|
func AssertStatementSql(t *testing.T, query jet.Statement, expectedQuery string, expectedArgs ...interface{}) {
|
2019-08-13 13:57:26 +02:00
|
|
|
queryStr, args := query.Sql()
|
2021-05-09 17:17:14 +02:00
|
|
|
assertQueryString(t, queryStr, expectedQuery)
|
2019-07-30 15:04:36 +02:00
|
|
|
|
2019-07-31 13:02:30 +02:00
|
|
|
if len(expectedArgs) == 0 {
|
|
|
|
|
return
|
|
|
|
|
}
|
2020-02-11 10:25:13 +01:00
|
|
|
AssertDeepEqual(t, args, expectedArgs)
|
2019-07-30 11:18:12 +02:00
|
|
|
}
|
|
|
|
|
|
2019-08-17 18:32:01 +02:00
|
|
|
// AssertStatementSqlErr checks if statement Sql() panics with errorStr
|
2019-08-12 12:11:16 +02:00
|
|
|
func AssertStatementSqlErr(t *testing.T, stmt jet.Statement, errorStr string) {
|
2019-08-13 13:57:26 +02:00
|
|
|
defer func() {
|
|
|
|
|
r := recover()
|
2020-05-09 11:00:22 +02:00
|
|
|
require.Equal(t, r, errorStr)
|
2019-08-13 13:57:26 +02:00
|
|
|
}()
|
2019-08-12 12:11:16 +02:00
|
|
|
|
2019-08-13 13:57:26 +02:00
|
|
|
stmt.Sql()
|
2019-08-12 12:11:16 +02:00
|
|
|
}
|
|
|
|
|
|
2019-08-17 18:32:01 +02:00
|
|
|
// AssertDebugStatementSql check if statement Sql() is the same as expectedQuery
|
2019-07-30 11:18:12 +02:00
|
|
|
func AssertDebugStatementSql(t *testing.T, query jet.Statement, expectedQuery string, expectedArgs ...interface{}) {
|
2019-08-13 13:57:26 +02:00
|
|
|
_, args := query.Sql()
|
|
|
|
|
|
2019-08-06 10:29:04 +02:00
|
|
|
if len(expectedArgs) > 0 {
|
2021-10-21 13:39:24 +02:00
|
|
|
AssertDeepEqual(t, args, expectedArgs)
|
2019-08-06 10:29:04 +02:00
|
|
|
}
|
2019-07-29 18:08:53 +02:00
|
|
|
|
2021-05-15 11:54:41 +02:00
|
|
|
debugSql := query.DebugSql()
|
|
|
|
|
assertQueryString(t, debugSql, expectedQuery)
|
2019-07-29 18:08:53 +02:00
|
|
|
}
|
|
|
|
|
|
2020-04-12 18:53:57 +02:00
|
|
|
// AssertSerialize checks if clause serialize produces expected query and args
|
|
|
|
|
func AssertSerialize(t *testing.T, dialect jet.Dialect, serializer jet.Serializer, query string, args ...interface{}) {
|
2019-08-17 18:32:01 +02:00
|
|
|
out := jet.SQLBuilder{Dialect: dialect}
|
2020-04-12 18:53:57 +02:00
|
|
|
jet.Serialize(serializer, jet.SelectStatementType, &out)
|
2019-07-31 18:43:54 +02:00
|
|
|
|
2019-08-12 12:11:16 +02:00
|
|
|
//fmt.Println(out.Buff.String())
|
2019-07-31 18:43:54 +02:00
|
|
|
|
2020-02-11 10:25:13 +01:00
|
|
|
AssertDeepEqual(t, out.Buff.String(), query)
|
2019-08-13 10:16:26 +02:00
|
|
|
|
|
|
|
|
if len(args) > 0 {
|
2020-02-11 10:25:13 +01:00
|
|
|
AssertDeepEqual(t, out.Args, args)
|
2019-08-13 10:16:26 +02:00
|
|
|
}
|
2019-07-31 18:43:54 +02:00
|
|
|
}
|
|
|
|
|
|
2021-05-15 11:54:41 +02:00
|
|
|
// AssertDebugSerialize checks if clause serialize produces expected debug query and args
|
|
|
|
|
func AssertDebugSerialize(t *testing.T, dialect jet.Dialect, clause jet.Serializer, query string, args ...interface{}) {
|
|
|
|
|
out := jet.SQLBuilder{Dialect: dialect, Debug: true}
|
|
|
|
|
jet.Serialize(clause, jet.SelectStatementType, &out)
|
2020-04-12 18:53:57 +02:00
|
|
|
|
2021-05-15 11:54:41 +02:00
|
|
|
AssertDeepEqual(t, out.Buff.String(), query)
|
2020-04-12 18:53:57 +02:00
|
|
|
|
|
|
|
|
if len(args) > 0 {
|
|
|
|
|
AssertDeepEqual(t, out.Args, args)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-15 11:54:41 +02:00
|
|
|
// AssertClauseSerialize checks if clause serialize produces expected query and args
|
|
|
|
|
func AssertClauseSerialize(t *testing.T, dialect jet.Dialect, clause jet.Clause, query string, args ...interface{}) {
|
|
|
|
|
out := jet.SQLBuilder{Dialect: dialect}
|
|
|
|
|
clause.Serialize(jet.SelectStatementType, &out)
|
2019-12-01 18:25:30 +01:00
|
|
|
|
2021-05-15 11:54:41 +02:00
|
|
|
require.Equal(t, out.Buff.String(), query)
|
2019-12-01 18:25:30 +01:00
|
|
|
|
|
|
|
|
if len(args) > 0 {
|
2020-02-11 10:25:13 +01:00
|
|
|
AssertDeepEqual(t, out.Args, args)
|
2019-12-01 18:25:30 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// AssertPanicErr checks if running a function fun produces a panic with errorStr string
|
|
|
|
|
func AssertPanicErr(t *testing.T, fun func(), errorStr string) {
|
|
|
|
|
defer func() {
|
|
|
|
|
r := recover()
|
2020-05-09 11:00:22 +02:00
|
|
|
require.Equal(t, r, errorStr)
|
2019-12-01 18:25:30 +01:00
|
|
|
}()
|
|
|
|
|
|
|
|
|
|
fun()
|
|
|
|
|
}
|
|
|
|
|
|
2020-04-12 18:53:57 +02:00
|
|
|
// AssertSerializeErr check if clause serialize panics with errString
|
|
|
|
|
func AssertSerializeErr(t *testing.T, dialect jet.Dialect, clause jet.Serializer, errString string) {
|
2019-08-13 13:57:26 +02:00
|
|
|
defer func() {
|
|
|
|
|
r := recover()
|
2020-05-09 11:00:22 +02:00
|
|
|
require.Equal(t, r, errString)
|
2019-08-13 13:57:26 +02:00
|
|
|
}()
|
2019-07-31 18:43:54 +02:00
|
|
|
|
2019-08-17 18:32:01 +02:00
|
|
|
out := jet.SQLBuilder{Dialect: dialect}
|
2019-08-13 13:57:26 +02:00
|
|
|
jet.Serialize(clause, jet.SelectStatementType, &out)
|
2019-07-31 18:43:54 +02:00
|
|
|
}
|
|
|
|
|
|
2019-08-17 18:32:01 +02:00
|
|
|
// AssertProjectionSerialize check if projection serialize produces expected query and args
|
2019-08-12 12:11:16 +02:00
|
|
|
func AssertProjectionSerialize(t *testing.T, dialect jet.Dialect, projection jet.Projection, query string, args ...interface{}) {
|
2019-08-17 18:32:01 +02:00
|
|
|
out := jet.SQLBuilder{Dialect: dialect}
|
2019-08-13 13:57:26 +02:00
|
|
|
jet.SerializeForProjection(projection, jet.SelectStatementType, &out)
|
2019-07-31 18:43:54 +02:00
|
|
|
|
2020-02-11 10:25:13 +01:00
|
|
|
AssertDeepEqual(t, out.Buff.String(), query)
|
|
|
|
|
AssertDeepEqual(t, out.Args, args)
|
2019-07-31 18:43:54 +02:00
|
|
|
}
|
2019-08-13 13:57:26 +02:00
|
|
|
|
2019-08-17 18:32:01 +02:00
|
|
|
// AssertQueryPanicErr check if statement Query execution panics with error errString
|
2019-09-27 11:46:31 +02:00
|
|
|
func AssertQueryPanicErr(t *testing.T, stmt jet.Statement, db qrm.DB, dest interface{}, errString string) {
|
2019-08-13 13:57:26 +02:00
|
|
|
defer func() {
|
|
|
|
|
r := recover()
|
2020-05-09 11:00:22 +02:00
|
|
|
require.Equal(t, r, errString)
|
2019-08-13 13:57:26 +02:00
|
|
|
}()
|
|
|
|
|
|
2021-05-09 17:17:14 +02:00
|
|
|
_ = stmt.Query(db, dest)
|
2019-08-13 13:57:26 +02:00
|
|
|
}
|
2019-09-20 12:53:52 +02:00
|
|
|
|
2019-09-20 13:55:07 +02:00
|
|
|
// AssertFileContent check if file content at filePath contains expectedContent text.
|
2020-04-13 10:18:14 +02:00
|
|
|
func AssertFileContent(t *testing.T, filePath string, expectedContent string) {
|
2019-09-20 12:53:52 +02:00
|
|
|
enumFileData, err := ioutil.ReadFile(filePath)
|
|
|
|
|
|
2020-04-13 10:18:14 +02:00
|
|
|
require.NoError(t, err)
|
2019-09-20 12:53:52 +02:00
|
|
|
|
2020-04-13 10:18:14 +02:00
|
|
|
require.Equal(t, "\n"+string(enumFileData), expectedContent)
|
2019-09-20 12:53:52 +02:00
|
|
|
}
|
|
|
|
|
|
2019-09-20 13:55:07 +02:00
|
|
|
// AssertFileNamesEqual check if all filesInfos are contained in fileNames
|
2019-09-20 12:53:52 +02:00
|
|
|
func AssertFileNamesEqual(t *testing.T, fileInfos []os.FileInfo, fileNames ...string) {
|
2020-05-09 11:00:22 +02:00
|
|
|
require.Equal(t, len(fileInfos), len(fileNames))
|
2019-09-20 12:53:52 +02:00
|
|
|
|
|
|
|
|
fileNamesMap := map[string]bool{}
|
|
|
|
|
|
|
|
|
|
for _, fileInfo := range fileInfos {
|
|
|
|
|
fileNamesMap[fileInfo.Name()] = true
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for _, fileName := range fileNames {
|
2020-05-09 11:00:22 +02:00
|
|
|
require.True(t, fileNamesMap[fileName], fileName+" does not exist.")
|
2019-09-20 12:53:52 +02:00
|
|
|
}
|
|
|
|
|
}
|
2020-02-11 10:25:13 +01:00
|
|
|
|
2020-02-16 10:25:21 +01:00
|
|
|
// AssertDeepEqual checks if actual and expected objects are deeply equal.
|
2021-10-21 13:39:24 +02:00
|
|
|
func AssertDeepEqual(t *testing.T, actual, expected interface{}, option ...cmp.Option) {
|
|
|
|
|
if !assert.True(t, cmp.Equal(actual, expected, option...)) {
|
|
|
|
|
printDiff(actual, expected, option...)
|
2021-05-14 12:15:35 +02:00
|
|
|
t.FailNow()
|
2021-05-09 17:17:14 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func assertQueryString(t *testing.T, actual, expected string) {
|
|
|
|
|
if !assert.Equal(t, actual, expected) {
|
|
|
|
|
printDiff(actual, expected)
|
2021-05-14 12:15:35 +02:00
|
|
|
t.FailNow()
|
2021-05-09 17:17:14 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-10-21 13:39:24 +02:00
|
|
|
func printDiff(actual, expected interface{}, options ...cmp.Option) {
|
|
|
|
|
fmt.Println(cmp.Diff(actual, expected, options...))
|
2021-05-09 17:17:14 +02:00
|
|
|
fmt.Println("Actual: ")
|
|
|
|
|
fmt.Println(actual)
|
|
|
|
|
fmt.Println("Expected: ")
|
|
|
|
|
fmt.Println(expected)
|
2020-02-11 10:25:13 +01:00
|
|
|
}
|
2020-05-02 22:15:38 +02:00
|
|
|
|
|
|
|
|
// BoolPtr returns address of bool parameter
|
|
|
|
|
func BoolPtr(b bool) *bool {
|
|
|
|
|
return &b
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Int8Ptr returns address of int8 parameter
|
|
|
|
|
func Int8Ptr(i int8) *int8 {
|
|
|
|
|
return &i
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// UInt8Ptr returns address of uint8 parameter
|
|
|
|
|
func UInt8Ptr(i uint8) *uint8 {
|
|
|
|
|
return &i
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Int16Ptr returns address of int16 parameter
|
|
|
|
|
func Int16Ptr(i int16) *int16 {
|
|
|
|
|
return &i
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// UInt16Ptr returns address of uint16 parameter
|
|
|
|
|
func UInt16Ptr(i uint16) *uint16 {
|
|
|
|
|
return &i
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Int32Ptr returns address of int32 parameter
|
|
|
|
|
func Int32Ptr(i int32) *int32 {
|
|
|
|
|
return &i
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// UInt32Ptr returns address of uint32 parameter
|
|
|
|
|
func UInt32Ptr(i uint32) *uint32 {
|
|
|
|
|
return &i
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Int64Ptr returns address of int64 parameter
|
|
|
|
|
func Int64Ptr(i int64) *int64 {
|
|
|
|
|
return &i
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// UInt64Ptr returns address of uint64 parameter
|
|
|
|
|
func UInt64Ptr(i uint64) *uint64 {
|
|
|
|
|
return &i
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// StringPtr returns address of string parameter
|
|
|
|
|
func StringPtr(s string) *string {
|
|
|
|
|
return &s
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// TimePtr returns address of time.Time parameter
|
|
|
|
|
func TimePtr(t time.Time) *time.Time {
|
|
|
|
|
return &t
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ByteArrayPtr returns address of []byte parameter
|
|
|
|
|
func ByteArrayPtr(arr []byte) *[]byte {
|
|
|
|
|
return &arr
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Float32Ptr returns address of float32 parameter
|
|
|
|
|
func Float32Ptr(f float32) *float32 {
|
|
|
|
|
return &f
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Float64Ptr returns address of float64 parameter
|
|
|
|
|
func Float64Ptr(f float64) *float64 {
|
|
|
|
|
return &f
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// UUIDPtr returns address of uuid.UUID
|
|
|
|
|
func UUIDPtr(u string) *uuid.UUID {
|
|
|
|
|
newUUID := uuid.MustParse(u)
|
|
|
|
|
|
|
|
|
|
return &newUUID
|
|
|
|
|
}
|