travis, codecov, more tests

This commit is contained in:
Pavel 2019-09-19 14:16:52 +03:00
parent bd5de124be
commit dba7552731
12 changed files with 699 additions and 33 deletions

12
.travis.yml Normal file
View File

@ -0,0 +1,12 @@
language: go
go:
- '1.8'
- '1.9'
- '1.10'
- '1.11'
before_install:
- go get -t -v ./...
script:
- go test ./... -v -cpu 2 -race -cover -coverprofile=coverage.txt -covermode=atomic
after_success:
- bash <(curl -s https://codecov.io/bash)

View File

@ -24,7 +24,6 @@ type ConfigInterface interface {
GetVersion() string GetVersion() string
GetSentryDSN() string GetSentryDSN() string
GetLogLevel() logging.Level GetLogLevel() logging.Level
GetDebug() bool
GetHTTPConfig() HTTPServerConfig GetHTTPConfig() HTTPServerConfig
GetDBConfig() DatabaseConfig GetDBConfig() DatabaseConfig
GetAWSConfig() ConfigAWS GetAWSConfig() ConfigAWS
@ -72,12 +71,12 @@ type ConfigAWS struct {
// DatabaseConfig struct // DatabaseConfig struct
type DatabaseConfig struct { type DatabaseConfig struct {
Connection string `yaml:"connection"` Connection interface{} `yaml:"connection"`
Logging bool `yaml:"logging"` Logging bool `yaml:"logging"`
TablePrefix string `yaml:"table_prefix"` TablePrefix string `yaml:"table_prefix"`
MaxOpenConnections int `yaml:"max_open_connections"` MaxOpenConnections int `yaml:"max_open_connections"`
MaxIdleConnections int `yaml:"max_idle_connections"` MaxIdleConnections int `yaml:"max_idle_connections"`
ConnectionLifetime int `yaml:"connection_lifetime"` ConnectionLifetime int `yaml:"connection_lifetime"`
} }
// HTTPServerConfig struct // HTTPServerConfig struct
@ -144,8 +143,8 @@ func (c Config) GetTransportInfo() InfoInterface {
return c.TransportInfo return c.TransportInfo
} }
// GetDebug debug flag // IsDebug debug flag
func (c Config) GetDebug() bool { func (c Config) IsDebug() bool {
return c.Debug return c.Debug
} }

View File

@ -85,8 +85,8 @@ func (c *ConfigTest) Test_GetLogLevel() {
assert.Equal(c.T(), logging.Level(5), c.config.GetLogLevel()) assert.Equal(c.T(), logging.Level(5), c.config.GetLogLevel())
} }
func (c *ConfigTest) Test_GetDebug() { func (c *ConfigTest) Test_IsDebug() {
assert.Equal(c.T(), true, c.config.GetDebug()) assert.Equal(c.T(), true, c.config.IsDebug())
} }
func (c *ConfigTest) Test_GetUpdateInterval() { func (c *ConfigTest) Test_GetUpdateInterval() {

View File

@ -36,14 +36,14 @@ func New() *Engine {
} }
func (e *Engine) initGin() { func (e *Engine) initGin() {
if !e.Config.GetDebug() { if !e.Config.IsDebug() {
gin.SetMode(gin.ReleaseMode) gin.SetMode(gin.ReleaseMode)
} }
r := gin.New() r := gin.New()
r.Use(gin.Recovery()) r.Use(gin.Recovery())
if e.Config.GetDebug() { if e.Config.IsDebug() {
r.Use(gin.Logger()) r.Use(gin.Logger())
} }
@ -76,7 +76,7 @@ func (e *Engine) Prepare() *Engine {
e.LoadTranslations() e.LoadTranslations()
e.createDB(e.Config.GetDBConfig()) e.createDB(e.Config.GetDBConfig())
e.createRavenClient(e.Config.GetSentryDSN()) e.createRavenClient(e.Config.GetSentryDSN())
e.resetUtils(e.Config.GetAWSConfig(), e.Config.GetDebug(), 0) e.resetUtils(e.Config.GetAWSConfig(), e.Config.IsDebug(), 0)
e.Logger = NewLogger(e.Config.GetTransportInfo().GetCode(), e.Config.GetLogLevel(), e.LogFormatter) e.Logger = NewLogger(e.Config.GetTransportInfo().GetCode(), e.Config.GetLogLevel(), e.LogFormatter)
e.Sentry.Localizer = &e.Localizer e.Sentry.Localizer = &e.Localizer
e.Utils.Logger = e.Logger e.Utils.Logger = e.Logger

160
core/engine_test.go Normal file
View File

@ -0,0 +1,160 @@
package core
import (
"database/sql"
"html/template"
"io/ioutil"
"os"
"testing"
"github.com/DATA-DOG/go-sqlmock"
"github.com/gin-gonic/gin"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite"
)
type EngineTest struct {
suite.Suite
engine *Engine
}
func (e *EngineTest) SetupTest() {
var (
db *sql.DB
err error
)
e.engine = New()
require.NotNil(e.T(), e.engine)
db, _, err = sqlmock.New()
require.NoError(e.T(), err)
if _, err := os.Stat(testTranslationsDir); err != nil && os.IsNotExist(err) {
err := os.Mkdir(testTranslationsDir, os.ModePerm)
require.Nil(e.T(), err)
data := []byte("message: Test message\nmessage_template: Test message with {{.data}}")
err = ioutil.WriteFile(testLangFile, data, os.ModePerm)
require.Nil(e.T(), err)
}
e.engine.Config = Config{
Version: "1",
LogLevel: 5,
Database: DatabaseConfig{
Connection: db,
Logging: true,
TablePrefix: "",
MaxOpenConnections: 10,
MaxIdleConnections: 10,
ConnectionLifetime: 60,
},
SentryDSN: "sentry dsn",
HTTPServer: HTTPServerConfig{
Host: "0.0.0.0",
Listen: ":3001",
},
Debug: true,
UpdateInterval: 30,
ConfigAWS: ConfigAWS{},
TransportInfo: Info{
Name: "test",
Code: "test",
LogoPath: "/test.svg",
},
}
}
func (e *EngineTest) Test_Prepare_Twice() {
defer func() {
r := recover()
require.NotNil(e.T(), r)
assert.Equal(e.T(), "engine already initialized", r.(string))
}()
engine := New()
engine.prepared = true
engine.Prepare()
}
func (e *EngineTest) Test_Prepare_NoConfig() {
defer func() {
r := recover()
require.NotNil(e.T(), r)
assert.Equal(e.T(), "engine.Config must be loaded before initializing", r.(string))
}()
engine := New()
engine.prepared = false
engine.Config = nil
engine.Prepare()
}
func (e *EngineTest) Test_Prepare() {
defer func() {
require.Nil(e.T(), recover())
}()
e.engine.TranslationsPath = testTranslationsDir
e.engine.Prepare()
assert.True(e.T(), e.engine.prepared)
}
func (e *EngineTest) Test_initGin_Release() {
engine := New()
engine.Config = Config{Debug: false}
engine.initGin()
assert.NotNil(e.T(), engine.ginEngine)
}
func (e *EngineTest) Test_TemplateFuncMap() {
assert.NotNil(e.T(), e.engine.TemplateFuncMap(template.FuncMap{
"test": func() string {
return "test"
},
}))
}
func (e *EngineTest) Test_CreateRenderer() {
e.engine.CreateRenderer(func(r *Renderer) {
assert.NotNil(e.T(), r)
}, template.FuncMap{})
}
func (e *EngineTest) Test_Router_Fail() {
defer func() {
r := recover()
require.NotNil(e.T(), r)
assert.Equal(e.T(), "prepare engine first", r.(string))
}()
engine := New()
engine.Router()
}
func (e *EngineTest) Test_Router() {
e.engine.TranslationsPath = testTranslationsDir
e.engine.Prepare()
assert.NotNil(e.T(), e.engine.Router())
}
func (e *EngineTest) Test_ConfigureRouter() {
e.engine.TranslationsPath = testTranslationsDir
e.engine.Prepare()
e.engine.ConfigureRouter(func(engine *gin.Engine) {
assert.NotNil(e.T(), engine)
})
}
func (e *EngineTest) Test_Run_Fail() {
defer func() {
assert.NotNil(e.T(), recover())
}()
_ = New().Run()
}
func TestEngine_Suite(t *testing.T) {
suite.Run(t, new(EngineTest))
}

View File

@ -1,6 +1,7 @@
package core package core
import ( import (
"fmt"
"sort" "sort"
"github.com/jinzhu/gorm" "github.com/jinzhu/gorm"
@ -78,6 +79,10 @@ func (m *Migrate) Rollback() error {
return err return err
} }
if m.first == nil {
return errors.New("abnormal termination: first migration is nil")
}
if err := m.GORMigrate.RollbackTo(m.first.ID); err == nil { if err := m.GORMigrate.RollbackTo(m.first.ID); err == nil {
if err := m.GORMigrate.RollbackMigration(m.first); err == nil { if err := m.GORMigrate.RollbackMigration(m.first); err == nil {
return nil return nil
@ -115,10 +120,10 @@ func (m *Migrate) MigrateNextTo(version string) error {
if next, err := m.NextFrom(version); err == nil { if next, err := m.NextFrom(version); err == nil {
current := m.Current() current := m.Current()
switch { switch {
case current > next:
return m.GORMigrate.RollbackTo(next)
case current < next: case current < next:
return m.GORMigrate.MigrateTo(next) return m.GORMigrate.MigrateTo(next)
case current > next:
return errors.New(fmt.Sprintf("current migration version '%s' is higher than fetched version '%s'", current, next))
default: default:
return nil return nil
} }
@ -139,7 +144,9 @@ func (m *Migrate) MigratePreviousTo(version string) error {
case current > prev: case current > prev:
return m.GORMigrate.RollbackTo(prev) return m.GORMigrate.RollbackTo(prev)
case current < prev: case current < prev:
return m.GORMigrate.MigrateTo(prev) return errors.New(fmt.Sprintf("current migration version '%s' is lower than fetched version '%s'", current, prev))
case prev == "0":
return m.GORMigrate.RollbackMigration(m.first)
default: default:
return nil return nil
} }
@ -162,17 +169,24 @@ func (m *Migrate) Current() string {
var migrationInfo MigrationInfo var migrationInfo MigrationInfo
if m.db == nil { if m.db == nil {
fmt.Println("warning => db is nil - cannot return migration version")
return "0" return "0"
} }
if !m.db.HasTable(MigrationInfo{}) { if !m.db.HasTable(MigrationInfo{}) {
m.db.CreateTable(MigrationInfo{}) if err := m.db.CreateTable(MigrationInfo{}).Error; err == nil {
fmt.Println("info => created migrations table")
} else {
panic(err.Error())
}
return "0" return "0"
} }
if err := m.db.Last(&migrationInfo).Error; err == nil { if err := m.db.Last(&migrationInfo).Error; err == nil {
return migrationInfo.ID return migrationInfo.ID
} else { } else {
fmt.Printf("warning => cannot fetch migration version: %s\n", err.Error())
return "0" return "0"
} }
} }
@ -199,7 +213,7 @@ func (m *Migrate) PreviousFrom(version string) (string, error) {
if key > 0 { if key > 0 {
return m.versions[key-1], nil return m.versions[key-1], nil
} else { } else {
return "", errors.New("this is first migration") return "0", nil
} }
} }
} }

View File

@ -7,6 +7,7 @@ import (
"github.com/DATA-DOG/go-sqlmock" "github.com/DATA-DOG/go-sqlmock"
"github.com/jinzhu/gorm" "github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/postgres"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite" "github.com/stretchr/testify/suite"
@ -29,13 +30,16 @@ type MigrateTest struct {
} }
func (m *MigrateTest) SetupSuite() { func (m *MigrateTest) SetupSuite() {
require.NotEmpty(m.T(), (MigrationInfo{}).TableName())
m.RefreshMigrate()
}
func (m *MigrateTest) RefreshMigrate() {
var ( var (
db *sql.DB db *sql.DB
err error err error
) )
require.NotEmpty(m.T(), (MigrationInfo{}).TableName())
db, m.mock, err = sqlmock.New() db, m.mock, err = sqlmock.New()
require.NoError(m.T(), err) require.NoError(m.T(), err)
@ -43,11 +47,6 @@ func (m *MigrateTest) SetupSuite() {
require.NoError(m.T(), err) require.NoError(m.T(), err)
m.DB.LogMode(true) m.DB.LogMode(true)
m.RefreshMigrate()
m.Migrate.SetDB(m.DB)
}
func (m *MigrateTest) RefreshMigrate() {
m.Migrate = &Migrate{ m.Migrate = &Migrate{
db: m.DB, db: m.DB,
prepared: false, prepared: false,
@ -55,7 +54,7 @@ func (m *MigrateTest) RefreshMigrate() {
} }
} }
func (m *MigrateTest) Migration_TestModel() *gormigrate.Migration { func (m *MigrateTest) Migration_TestModelFirst() *gormigrate.Migration {
return &gormigrate.Migration{ return &gormigrate.Migration{
ID: "1", ID: "1",
Migrate: func(db *gorm.DB) error { Migrate: func(db *gorm.DB) error {
@ -67,15 +66,28 @@ func (m *MigrateTest) Migration_TestModel() *gormigrate.Migration {
} }
} }
func (m *MigrateTest) Migration_TestModelSecond() *gormigrate.Migration {
return &gormigrate.Migration{
ID: "2",
Migrate: func(db *gorm.DB) error {
return db.Model(TestModel{}).ModifyColumn("name", "varchar(100)").Error
},
Rollback: func(db *gorm.DB) error {
return db.Model(TestModel{}).ModifyColumn("name", "varchar(70)").Error
},
}
}
func (m *MigrateTest) Test_Add() { func (m *MigrateTest) Test_Add() {
m.RefreshMigrate() m.RefreshMigrate()
m.Migrate.Add(nil) m.Migrate.Add(nil)
m.Migrate.Add(m.Migration_TestModel()) m.Migrate.Add(m.Migration_TestModelFirst())
assert.Equal(m.T(), 1, len(m.Migrate.migrations)) assert.Equal(m.T(), 1, len(m.Migrate.migrations))
i, ok := m.Migrate.migrations["1"] i, ok := m.Migrate.migrations["1"]
require.True(m.T(), ok) require.True(m.T(), ok)
assert.Equal(m.T(), "1", i.ID) assert.Equal(m.T(), "1", i.ID)
assert.NoError(m.T(), m.mock.ExpectationsWereMet())
} }
func (m *MigrateTest) Test_prepareMigrations_NilDB() { func (m *MigrateTest) Test_prepareMigrations_NilDB() {
@ -85,6 +97,7 @@ func (m *MigrateTest) Test_prepareMigrations_NilDB() {
require.Error(m.T(), err) require.Error(m.T(), err)
assert.Equal(m.T(), "db must not be nil", err.Error()) assert.Equal(m.T(), "db must not be nil", err.Error())
assert.NoError(m.T(), m.mock.ExpectationsWereMet())
} }
func (m *MigrateTest) Test_prepareMigrations_AlreadyPrepared() { func (m *MigrateTest) Test_prepareMigrations_AlreadyPrepared() {
@ -94,21 +107,57 @@ func (m *MigrateTest) Test_prepareMigrations_AlreadyPrepared() {
require.NoError(m.T(), err) require.NoError(m.T(), err)
assert.Nil(m.T(), m.Migrate.GORMigrate) assert.Nil(m.T(), m.Migrate.GORMigrate)
assert.NoError(m.T(), m.mock.ExpectationsWereMet())
} }
func (m *MigrateTest) Test_prepareMigrations_OK() { func (m *MigrateTest) Test_prepareMigrations_OK() {
m.RefreshMigrate() m.RefreshMigrate()
m.Migrate.Add(m.Migration_TestModel()) m.Migrate.Add(m.Migration_TestModelFirst())
err := m.Migrate.prepareMigrations() err := m.Migrate.prepareMigrations()
require.NoError(m.T(), err) require.NoError(m.T(), err)
assert.True(m.T(), m.Migrate.prepared) assert.True(m.T(), m.Migrate.prepared)
assert.NotNil(m.T(), m.Migrate.GORMigrate) assert.NotNil(m.T(), m.Migrate.GORMigrate)
assert.NoError(m.T(), m.mock.ExpectationsWereMet())
} }
func (m *MigrateTest) Test_Migrate() { func (m *MigrateTest) Test_Migrate_Fail_NilDB() {
m.RefreshMigrate() m.RefreshMigrate()
m.Migrate.Add(m.Migration_TestModel()) m.Migrate.SetDB(nil)
m.Migrate.Add(m.Migration_TestModelFirst())
err := m.Migrate.Migrate()
assert.Error(m.T(), err)
assert.NoError(m.T(), m.mock.ExpectationsWereMet())
}
func (m *MigrateTest) Test_Migrate_Success_NoMigrations() {
m.RefreshMigrate()
m.Migrate.Add(m.Migration_TestModelFirst())
m.mock.ExpectBegin()
m.mock.
ExpectExec(regexp.QuoteMeta(`CREATE TABLE migrations (id VARCHAR(255) PRIMARY KEY)`)).
WillReturnResult(sqlmock.NewResult(1, 1))
m.mock.
ExpectQuery(regexp.QuoteMeta(`SELECT id FROM migrations`)).
WillReturnRows(sqlmock.NewRows([]string{"1"}))
m.mock.
ExpectQuery(regexp.QuoteMeta(`SELECT count(*) FROM "migrations" WHERE (id = $1)`)).
WithArgs("1").
WillReturnRows(sqlmock.NewRows([]string{"count"}).AddRow(1))
m.mock.ExpectCommit()
err := m.Migrate.Migrate()
assert.NoError(m.T(), err)
assert.NoError(m.T(), m.mock.ExpectationsWereMet())
}
func (m *MigrateTest) Test_Migrate_Success() {
m.RefreshMigrate()
m.Migrate.Add(m.Migration_TestModelFirst())
m.mock.ExpectBegin() m.mock.ExpectBegin()
m.mock. m.mock.
@ -133,6 +182,184 @@ func (m *MigrateTest) Test_Migrate() {
err := m.Migrate.Migrate() err := m.Migrate.Migrate()
assert.NoError(m.T(), err) assert.NoError(m.T(), err)
assert.NoError(m.T(), m.mock.ExpectationsWereMet())
}
func (m *MigrateTest) Test_Rollback_Fail_NilDB() {
m.RefreshMigrate()
m.Migrate.SetDB(nil)
m.Migrate.Add(m.Migration_TestModelFirst())
err := m.Migrate.Rollback()
assert.Error(m.T(), err)
assert.NoError(m.T(), m.mock.ExpectationsWereMet())
}
func (m *MigrateTest) Test_Rollback_Fail_NoMigrations() {
m.RefreshMigrate()
m.Migrate.first = m.Migration_TestModelFirst()
err := m.Migrate.Rollback()
assert.Error(m.T(), err)
assert.NoError(m.T(), m.mock.ExpectationsWereMet())
}
func (m *MigrateTest) Test_Rollback_Fail_NoFirstMigration() {
m.RefreshMigrate()
m.Migrate.Add(m.Migration_TestModelFirst())
m.Migrate.first = nil
err := m.Migrate.Rollback()
assert.Error(m.T(), err)
assert.NoError(m.T(), m.mock.ExpectationsWereMet())
}
func (m *MigrateTest) Test_MigrateTo_Fail_NilDB() {
m.RefreshMigrate()
m.Migrate.SetDB(nil)
err := m.Migrate.MigrateTo("version")
assert.Error(m.T(), err)
assert.NoError(m.T(), m.mock.ExpectationsWereMet())
}
func (m *MigrateTest) Test_MigrateTo_DoNothing() {
m.RefreshMigrate()
m.Migrate.Add(m.Migration_TestModelFirst())
m.mock.
ExpectExec(regexp.QuoteMeta(`CREATE TABLE "migrations" ("id" varchar(255) , PRIMARY KEY ("id"))`)).
WillReturnResult(sqlmock.NewResult(1, 1))
m.mock.ExpectBegin()
m.mock.
ExpectExec(regexp.QuoteMeta(`CREATE TABLE migrations (id VARCHAR(255) PRIMARY KEY)`)).
WillReturnResult(sqlmock.NewResult(1, 1))
m.mock.
ExpectQuery(regexp.QuoteMeta(`SELECT id FROM migrations`)).
WillReturnRows(sqlmock.NewRows([]string{"1"}))
m.mock.
ExpectQuery(regexp.QuoteMeta(`SELECT count(*) FROM "migrations" WHERE (id = $1)`)).
WithArgs("1").
WillReturnRows(sqlmock.NewRows([]string{"count"}).AddRow(1))
m.mock.ExpectCommit()
err := m.Migrate.MigrateTo(m.Migration_TestModelFirst().ID)
assert.NoError(m.T(), err)
assert.NoError(m.T(), m.mock.ExpectationsWereMet())
}
func (m *MigrateTest) Test_MigrateTo() {
m.RefreshMigrate()
m.Migrate.Add(m.Migration_TestModelFirst())
m.mock.
ExpectExec(regexp.QuoteMeta(`CREATE TABLE "migrations" ("id" varchar(255) , PRIMARY KEY ("id"))`)).
WillReturnResult(sqlmock.NewResult(1, 1))
m.mock.ExpectBegin()
m.mock.
ExpectExec(regexp.QuoteMeta(`CREATE TABLE migrations (id VARCHAR(255) PRIMARY KEY)`)).
WillReturnResult(sqlmock.NewResult(1, 1))
m.mock.
ExpectQuery(regexp.QuoteMeta(`SELECT id FROM migrations`)).
WillReturnRows(sqlmock.NewRows([]string{"1"}))
m.mock.
ExpectQuery(regexp.QuoteMeta(`SELECT count(*) FROM "migrations" WHERE (id = $1)`)).
WithArgs("1").
WillReturnRows(sqlmock.NewRows([]string{"count"}).AddRow(0))
m.mock.
ExpectExec(regexp.QuoteMeta(`CREATE TABLE "test_model" ("name" varchar(70) )`)).
WillReturnResult(sqlmock.NewResult(1, 1))
m.mock.
ExpectExec(regexp.QuoteMeta(`INSERT INTO migrations (id) VALUES ($1)`)).
WithArgs("1").
WillReturnResult(sqlmock.NewResult(1, 1))
m.mock.ExpectCommit()
err := m.Migrate.MigrateTo(m.Migration_TestModelFirst().ID)
assert.NoError(m.T(), err)
assert.NoError(m.T(), m.mock.ExpectationsWereMet())
}
func (m *MigrateTest) Test_RollbackTo() {
m.RefreshMigrate()
m.Migrate.Add(m.Migration_TestModelFirst())
m.Migrate.Add(m.Migration_TestModelSecond())
m.mock.ExpectBegin()
m.mock.ExpectCommit()
err := m.Migrate.RollbackTo(m.Migration_TestModelSecond().ID)
assert.NoError(m.T(), err)
assert.NoError(m.T(), m.mock.ExpectationsWereMet())
}
func (m *MigrateTest) Test_MigrateNextTo() {
m.RefreshMigrate()
m.Migrate.Add(m.Migration_TestModelFirst())
m.Migrate.Add(m.Migration_TestModelSecond())
m.mock.
ExpectExec(regexp.QuoteMeta(`CREATE TABLE "migrations" ("id" varchar(255) , PRIMARY KEY ("id"))`)).
WillReturnResult(sqlmock.NewResult(1, 1))
m.mock.ExpectBegin()
m.mock.
ExpectExec(regexp.QuoteMeta(`CREATE TABLE migrations (id VARCHAR(255) PRIMARY KEY)`)).
WillReturnResult(sqlmock.NewResult(1, 1))
m.mock.
ExpectQuery(regexp.QuoteMeta(`SELECT id FROM migrations`)).
WillReturnRows(sqlmock.NewRows([]string{"1"}))
m.mock.
ExpectQuery(regexp.QuoteMeta(`SELECT count(*) FROM "migrations" WHERE (id = $1)`)).
WithArgs("1").
WillReturnRows(sqlmock.NewRows([]string{"count"}).AddRow(1))
m.mock.
ExpectQuery(regexp.QuoteMeta(`SELECT count(*) FROM "migrations" WHERE (id = $1)`)).
WithArgs("2").
WillReturnRows(sqlmock.NewRows([]string{"count"}).AddRow(0))
m.mock.
ExpectExec(regexp.QuoteMeta(`ALTER TABLE "test_model" ALTER COLUMN "name" TYPE varchar(100)`)).
WillReturnResult(sqlmock.NewResult(1, 1))
m.mock.
ExpectExec(regexp.QuoteMeta(`INSERT INTO migrations (id) VALUES ($1)`)).
WithArgs("2").
WillReturnResult(sqlmock.NewResult(1, 1))
m.mock.ExpectCommit()
err := m.Migrate.MigrateNextTo(m.Migration_TestModelFirst().ID)
assert.NoError(m.T(), err)
assert.NoError(m.T(), m.mock.ExpectationsWereMet())
}
func (m *MigrateTest) Test_MigratePreviousTo() {
m.RefreshMigrate()
m.Migrate.Add(m.Migration_TestModelFirst())
m.Migrate.Add(m.Migration_TestModelSecond())
m.mock.
ExpectExec(regexp.QuoteMeta(`CREATE TABLE "migrations" ("id" varchar(255) , PRIMARY KEY ("id"))`)).
WillReturnResult(sqlmock.NewResult(1, 1))
err := m.Migrate.MigratePreviousTo(m.Migration_TestModelSecond().ID)
assert.Error(m.T(), err)
assert.NoError(m.T(), m.mock.ExpectationsWereMet())
}
func (m *MigrateTest) Test_Close() {
m.RefreshMigrate()
m.mock.ExpectClose()
err := m.Migrate.Close()
assert.NoError(m.T(), err)
assert.NoError(m.T(), m.mock.ExpectationsWereMet())
} }
func TestMigrate_Migrate(t *testing.T) { func TestMigrate_Migrate(t *testing.T) {

11
core/models_test.go Normal file
View File

@ -0,0 +1,11 @@
package core
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestModels_TableName(t *testing.T) {
assert.NotEmpty(t, (User{}).TableName())
}

73
core/orm_test.go Normal file
View File

@ -0,0 +1,73 @@
package core
import (
"database/sql"
"testing"
"github.com/DATA-DOG/go-sqlmock"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestORM_NewORM(t *testing.T) {
var (
db *sql.DB
err error
)
defer func() {
require.Nil(t, recover())
}()
db, _, err = sqlmock.New()
require.NoError(t, err)
config := DatabaseConfig{
Connection: db,
Logging: true,
TablePrefix: "",
MaxOpenConnections: 10,
MaxIdleConnections: 10,
ConnectionLifetime: 100,
}
_ = NewORM(config)
}
func TestORM_createDB_Fail(t *testing.T) {
defer func() {
assert.NotNil(t, recover())
}()
NewORM(DatabaseConfig{Connection: nil})
}
func TestORM_CloseDB(t *testing.T) {
var (
db *sql.DB
dbMock sqlmock.Sqlmock
err error
)
defer func() {
require.Nil(t, recover())
}()
db, dbMock, err = sqlmock.New()
require.NoError(t, err)
config := DatabaseConfig{
Connection: db,
Logging: true,
TablePrefix: "",
MaxOpenConnections: 10,
MaxIdleConnections: 10,
ConnectionLifetime: 100,
}
dbMock.ExpectClose()
orm := NewORM(config)
orm.CloseDB()
assert.NoError(t, dbMock.ExpectationsWereMet())
}

View File

@ -287,7 +287,7 @@ func (t *SentryTaggedStruct) GetProperty(v interface{}, property string) (name s
err = fmt.Errorf("cannot find property `%s`", property) err = fmt.Errorf("cannot find property `%s`", property)
} }
field := val.FieldByName(property) field := reflect.Indirect(val.FieldByName(property))
if !field.IsValid() { if !field.IsValid() {
err = fmt.Errorf("invalid property, got %s", field.String()) err = fmt.Errorf("invalid property, got %s", field.String())
return return
@ -477,4 +477,4 @@ func getErrorCause(err error) error {
return nil return nil
} }
return cer.Cause() return cer.Cause()
} }

114
core/sentry_test.go Normal file
View File

@ -0,0 +1,114 @@
package core
import (
"errors"
"testing"
"github.com/getsentry/raven-go"
pkgErrors "github.com/pkg/errors"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite"
)
type SampleStruct struct {
ID int
Pointer *int
Field string
}
type SentryTest struct {
suite.Suite
sentry *Sentry
structTags *SentryTaggedStruct
scalarTags *SentryTaggedScalar
}
func (s *SentryTest) SetupTest() {
s.structTags = NewTaggedStruct(SampleStruct{}, "struct", map[string]string{"fake": "prop"})
s.scalarTags = NewTaggedScalar("", "scalar", "Scalar")
require.Equal(s.T(), "struct", s.structTags.GetContextKey())
require.Equal(s.T(), "scalar", s.scalarTags.GetContextKey())
require.Equal(s.T(), "", s.structTags.GetName())
require.Equal(s.T(), "Scalar", s.scalarTags.GetName())
s.structTags.Tags = map[string]string{}
}
func (s *SentryTest) TestStruct_AddTag() {
s.structTags.AddTag("test field", "Field")
require.NotEmpty(s.T(), s.structTags.GetTags())
tags, err := s.structTags.BuildTags(SampleStruct{Field: "value"})
require.NoError(s.T(), err)
require.NotEmpty(s.T(), tags)
i, ok := tags["test field"]
require.True(s.T(), ok)
assert.Equal(s.T(), "value", i)
}
func (s *SentryTest) TestStruct_GetProperty() {
s.structTags.AddTag("test field", "Field")
name, value, err := s.structTags.GetProperty(SampleStruct{Field: "test"}, "Field")
require.NoError(s.T(), err)
assert.Equal(s.T(), "test field", name)
assert.Equal(s.T(), "test", value)
}
func (s *SentryTest) TestStruct_GetProperty_InvalidStruct() {
_, _, err := s.structTags.GetProperty(nil, "Field")
require.Error(s.T(), err)
assert.Equal(s.T(), "invalid value provided", err.Error())
}
func (s *SentryTest) TestStruct_GetProperty_GotScalar() {
_, _, err := s.structTags.GetProperty("str", "Field")
require.Error(s.T(), err)
assert.Equal(s.T(), "passed value must be struct, str provided", err.Error())
}
func (s *SentryTest) TestStruct_GetProperty_InvalidType() {
_, _, err := s.structTags.GetProperty(Sentry{}, "Field")
require.Error(s.T(), err)
assert.Equal(s.T(), "passed value should be of type `core.SampleStruct`, got `core.Sentry` instead", err.Error())
}
func (s *SentryTest) TestStruct_GetProperty_CannotFindProperty() {
_, _, err := s.structTags.GetProperty(SampleStruct{ID: 1}, "ID")
require.Error(s.T(), err)
assert.Equal(s.T(), "cannot find property `ID`", err.Error())
}
func (s *SentryTest) TestStruct_GetProperty_InvalidProperty() {
s.structTags.AddTag("test invalid", "Pointer")
_, _, err := s.structTags.GetProperty(SampleStruct{Pointer: nil}, "Pointer")
require.Error(s.T(), err)
assert.Equal(s.T(), "invalid property, got <invalid Value>", err.Error())
}
func TestSentry_newRavenStackTrace_Fail(t *testing.T) {
defer func() {
assert.NotNil(t, recover())
}()
newRavenStackTrace(nil, errors.New("error"), 0)
}
func TestSentry_newRavenStackTrace(t *testing.T) {
st := newRavenStackTrace(&raven.Client{}, errors.New("error"), 0)
require.NotNil(t, st)
assert.NotEmpty(t, st.Frames)
}
func TestSentry_newRavenStackTrace_ErrorsPkg(t *testing.T) {
err := pkgErrors.New("error")
st := newRavenStackTrace(&raven.Client{}, err, 0)
require.NotNil(t, st)
assert.NotEmpty(t, st.Frames)
}
func TestSentry_Suite(t *testing.T) {
suite.Run(t, new(SentryTest))
}

56
core/template_test.go Normal file
View File

@ -0,0 +1,56 @@
package core
import (
"fmt"
"html/template"
"io/ioutil"
"os"
"path"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite"
)
var (
testTemplatesDir = path.Join(os.TempDir(), "templates_test_dir")
testTemplatesFile = path.Join(testTemplatesDir, "tpl%d.html")
)
type TemplateTest struct {
suite.Suite
renderer Renderer
}
func (t *TemplateTest) SetupTest() {
if _, err := os.Stat(testTemplatesDir); err != nil && os.IsNotExist(err) {
err := os.Mkdir(testTemplatesDir, os.ModePerm)
require.Nil(t.T(), err)
data1 := []byte(`data {{template "body" .}}`)
data2 := []byte(`{{define "body"}}test {{"test" | trans}}{{end}}`)
err1 := ioutil.WriteFile(fmt.Sprintf(testTemplatesFile, 1), data1, os.ModePerm)
err2 := ioutil.WriteFile(fmt.Sprintf(testTemplatesFile, 2), data2, os.ModePerm)
require.Nil(t.T(), err1)
require.Nil(t.T(), err2)
}
t.renderer = NewRenderer(template.FuncMap{
"trans": func(data string) string {
if data == "test" {
return "ok"
}
return "fail"
},
})
}
func (t *TemplateTest) Test_Push() {
tpl := t.renderer.Push("index", fmt.Sprintf(testTemplatesFile, 1), fmt.Sprintf(testTemplatesFile, 2))
assert.Equal(t.T(), 3, len(tpl.Templates()))
}
func TestTemplate_Suite(t *testing.T) {
suite.Run(t, new(TemplateTest))
}