196 lines
5.5 KiB
Go
196 lines
5.5 KiB
Go
//
|
|
// dialect_mysql_test.go
|
|
// Copyright (C) 2023 tiglog <me@tiglog.com>
|
|
//
|
|
// Distributed under terms of the MIT license.
|
|
//
|
|
|
|
//go:build !integration
|
|
// +build !integration
|
|
|
|
package sqldb_test
|
|
|
|
import (
|
|
"database/sql"
|
|
"errors"
|
|
"fmt"
|
|
"reflect"
|
|
"testing"
|
|
"time"
|
|
|
|
"git.hexq.cn/tiglog/golib/gdb/sqldb"
|
|
"github.com/poy/onpar"
|
|
"github.com/poy/onpar/expect"
|
|
"github.com/poy/onpar/matchers"
|
|
)
|
|
|
|
func TestMySQLDialect(t *testing.T) {
|
|
// o := onpar.New(t)
|
|
// defer o.Run()
|
|
|
|
type testContext struct {
|
|
t *testing.T
|
|
dialect sqldb.MySQLDialect
|
|
}
|
|
|
|
o := onpar.BeforeEach(onpar.New(t), func(t *testing.T) testContext {
|
|
return testContext{
|
|
t: t,
|
|
dialect: sqldb.MySQLDialect{Engine: "foo", Encoding: "bar"},
|
|
}
|
|
})
|
|
defer o.Run()
|
|
|
|
o.Group("ToSqlType", func() {
|
|
tests := []struct {
|
|
name string
|
|
value interface{}
|
|
maxSize int
|
|
autoIncr bool
|
|
expected string
|
|
}{
|
|
{"bool", true, 0, false, "boolean"},
|
|
{"int8", int8(1), 0, false, "tinyint"},
|
|
{"uint8", uint8(1), 0, false, "tinyint unsigned"},
|
|
{"int16", int16(1), 0, false, "smallint"},
|
|
{"uint16", uint16(1), 0, false, "smallint unsigned"},
|
|
{"int32", int32(1), 0, false, "int"},
|
|
{"int (treated as int32)", int(1), 0, false, "int"},
|
|
{"uint32", uint32(1), 0, false, "int unsigned"},
|
|
{"uint (treated as uint32)", uint(1), 0, false, "int unsigned"},
|
|
{"int64", int64(1), 0, false, "bigint"},
|
|
{"uint64", uint64(1), 0, false, "bigint unsigned"},
|
|
{"float32", float32(1), 0, false, "double"},
|
|
{"float64", float64(1), 0, false, "double"},
|
|
{"[]uint8", []uint8{1}, 0, false, "mediumblob"},
|
|
{"NullInt64", sql.NullInt64{}, 0, false, "bigint"},
|
|
{"NullFloat64", sql.NullFloat64{}, 0, false, "double"},
|
|
{"NullBool", sql.NullBool{}, 0, false, "tinyint"},
|
|
{"Time", time.Time{}, 0, false, "datetime"},
|
|
{"default-size string", "", 0, false, "varchar(255)"},
|
|
{"sized string", "", 50, false, "varchar(50)"},
|
|
{"large string", "", 1024, false, "text"},
|
|
}
|
|
for _, t := range tests {
|
|
o.Spec(t.name, func(tt testContext) {
|
|
typ := reflect.TypeOf(t.value)
|
|
sqlType := tt.dialect.ToSqlType(typ, t.maxSize, t.autoIncr)
|
|
expect.Expect(tt.t, sqlType).To(matchers.Equal(t.expected))
|
|
})
|
|
}
|
|
})
|
|
|
|
o.Spec("AutoIncrStr", func(tt testContext) {
|
|
expect.Expect(t, tt.dialect.AutoIncrStr()).To(matchers.Equal("auto_increment"))
|
|
})
|
|
|
|
o.Spec("AutoIncrBindValue", func(tt testContext) {
|
|
expect.Expect(t, tt.dialect.AutoIncrBindValue()).To(matchers.Equal("null"))
|
|
})
|
|
|
|
o.Spec("AutoIncrInsertSuffix", func(tt testContext) {
|
|
expect.Expect(t, tt.dialect.AutoIncrInsertSuffix(nil)).To(matchers.Equal(""))
|
|
})
|
|
|
|
o.Group("CreateTableSuffix", func() {
|
|
o.Group("with an empty engine", func() {
|
|
o1 := onpar.BeforeEach(o, func(tt testContext) testContext {
|
|
tt.dialect.Encoding = ""
|
|
return tt
|
|
})
|
|
o1.Spec("panics", func(tt testContext) {
|
|
expect.Expect(t, func() { tt.dialect.CreateTableSuffix() }).To(Panic())
|
|
})
|
|
})
|
|
|
|
o.Group("with an empty encoding", func() {
|
|
o2 := onpar.BeforeEach(o, func(tt testContext) testContext {
|
|
tt.dialect.Encoding = ""
|
|
return tt
|
|
})
|
|
o2.Spec("panics", func(tt testContext) {
|
|
expect.Expect(t, func() { tt.dialect.CreateTableSuffix() }).To(Panic())
|
|
})
|
|
})
|
|
|
|
o.Spec("with an engine and an encoding", func(tt testContext) {
|
|
expect.Expect(t, tt.dialect.CreateTableSuffix()).To(matchers.Equal(" engine=foo charset=bar"))
|
|
})
|
|
})
|
|
|
|
o.Spec("CreateIndexSuffix", func(tt testContext) {
|
|
expect.Expect(t, tt.dialect.CreateIndexSuffix()).To(matchers.Equal("using"))
|
|
})
|
|
|
|
o.Spec("DropIndexSuffix", func(tt testContext) {
|
|
expect.Expect(t, tt.dialect.DropIndexSuffix()).To(matchers.Equal("on"))
|
|
})
|
|
|
|
o.Spec("TruncateClause", func(tt testContext) {
|
|
expect.Expect(t, tt.dialect.TruncateClause()).To(matchers.Equal("truncate"))
|
|
})
|
|
|
|
o.Spec("SleepClause", func(tt testContext) {
|
|
expect.Expect(t, tt.dialect.SleepClause(1*time.Second)).To(matchers.Equal("sleep(1.000000)"))
|
|
expect.Expect(t, tt.dialect.SleepClause(100*time.Millisecond)).To(matchers.Equal("sleep(0.100000)"))
|
|
})
|
|
|
|
o.Spec("BindVar", func(tt testContext) {
|
|
expect.Expect(t, tt.dialect.BindVar(0)).To(matchers.Equal("?"))
|
|
})
|
|
|
|
o.Spec("QuoteField", func(tt testContext) {
|
|
expect.Expect(t, tt.dialect.QuoteField("foo")).To(matchers.Equal("`foo`"))
|
|
})
|
|
|
|
o.Group("QuotedTableForQuery", func() {
|
|
o.Spec("using the default schema", func(tt testContext) {
|
|
expect.Expect(t, tt.dialect.QuotedTableForQuery("", "foo")).To(matchers.Equal("`foo`"))
|
|
})
|
|
|
|
o.Spec("with a supplied schema", func(tt testContext) {
|
|
expect.Expect(t, tt.dialect.QuotedTableForQuery("foo", "bar")).To(matchers.Equal("foo.`bar`"))
|
|
})
|
|
})
|
|
|
|
o.Spec("IfSchemaNotExists", func(tt testContext) {
|
|
expect.Expect(t, tt.dialect.IfSchemaNotExists("foo", "bar")).To(matchers.Equal("foo if not exists"))
|
|
})
|
|
|
|
o.Spec("IfTableExists", func(tt testContext) {
|
|
expect.Expect(t, tt.dialect.IfTableExists("foo", "bar", "baz")).To(matchers.Equal("foo if exists"))
|
|
})
|
|
|
|
o.Spec("IfTableNotExists", func(tt testContext) {
|
|
expect.Expect(t, tt.dialect.IfTableNotExists("foo", "bar", "baz")).To(matchers.Equal("foo if not exists"))
|
|
})
|
|
}
|
|
|
|
type panicMatcher struct {
|
|
}
|
|
|
|
func Panic() panicMatcher {
|
|
return panicMatcher{}
|
|
}
|
|
|
|
func (m panicMatcher) Match(actual interface{}) (resultValue interface{}, err error) {
|
|
switch f := actual.(type) {
|
|
case func():
|
|
panicked := false
|
|
func() {
|
|
defer func() {
|
|
if r := recover(); r != nil {
|
|
panicked = true
|
|
}
|
|
}()
|
|
f()
|
|
}()
|
|
if panicked {
|
|
return f, nil
|
|
}
|
|
return f, errors.New("function did not panic")
|
|
default:
|
|
return f, fmt.Errorf("%T is not func()", f)
|
|
}
|
|
}
|