Commit c6dbaf49 authored by gwenn's avatar gwenn

Improve test coverage.

parent 64972f0c
......@@ -44,7 +44,7 @@ type UnixTime time.Time
// Scan implements the database/sql/Scanner interface.
func (t *UnixTime) Scan(src interface{}) error {
if src == nil {
//t = nil
*t = UnixTime{}
return nil
} else if unixepoch, ok := src.(int64); ok {
*t = UnixTime(time.Unix(unixepoch, 0)) // local time
......@@ -67,7 +67,10 @@ type JulianTime time.Time
// Scan implements the database/sql/Scanner interface.
func (t *JulianTime) Scan(src interface{}) error {
if src == nil {
//t = nil
*t = JulianTime{}
return nil
} else if jd, ok := src.(int64); ok {
*t = JulianTime(JulianDayToLocalTime(float64(jd))) // local time
return nil
} else if jd, ok := src.(float64); ok {
*t = JulianTime(JulianDayToLocalTime(jd)) // local time
......@@ -90,7 +93,7 @@ type TimeStamp time.Time
// Scan implements the database/sql/Scanner interface.
func (t *TimeStamp) Scan(src interface{}) error {
if src == nil {
//t = nil
*t = TimeStamp{}
return nil
} else if txt, ok := src.(string); ok {
v, err := time.Parse("2006-01-02T15:04:05.000Z07:00", txt)
......
......@@ -160,6 +160,8 @@ func TestJulianTime(t *testing.T) {
now := time.Now()
id, err := is.Insert(JulianTime(now))
checkNoError(t, err, "error inserting JulianTime: %s")
_, err = is.Insert(JulianTime{})
checkNoError(t, err, "error inserting JulianTime: %s")
checkFinalize(is, t)
// the format used to persist has a max precision of 1s.
......@@ -169,6 +171,17 @@ func TestJulianTime(t *testing.T) {
err = db.OneValue("SELECT time FROM test where ROWID = ?", &jt, id)
checkNoError(t, err, "error selecting JulianTime: %s")
assert.Equal(t, now, time.Time(jt))
err = db.OneValue("SELECT null", &jt)
checkNoError(t, err, "%s")
assert.T(t, ((time.Time)(jt)).IsZero())
err = db.OneValue("SELECT 0", &jt)
checkNoError(t, err, "%s")
err = db.OneValue("SELECT 'bim'", &jt)
assert.T(t, err != nil)
//println(err.Error())
}
func TestTimeStamp(t *testing.T) {
......@@ -183,6 +196,8 @@ func TestTimeStamp(t *testing.T) {
now := time.Now()
id, err := is.Insert(TimeStamp(now))
checkNoError(t, err, "error inserting TimeStamp: %s")
_, err = is.Insert(TimeStamp{})
checkNoError(t, err, "error inserting TimeStamp: %s")
checkFinalize(is, t)
// the format used to persist has a max precision of 1ms.
......@@ -192,6 +207,18 @@ func TestTimeStamp(t *testing.T) {
err = db.OneValue("SELECT time FROM test where ROWID = ?", &ts, id)
checkNoError(t, err, "error selecting TimeStamp: %s")
assert.Equal(t, now, time.Time(ts))
err = db.OneValue("SELECT null", &ts)
checkNoError(t, err, "%s")
assert.T(t, ((time.Time)(ts)).IsZero())
err = db.OneValue("SELECT 'bim'", &ts)
assert.T(t, err != nil)
//println(err.Error())
err = db.OneValue("SELECT 0", &ts)
assert.T(t, err != nil)
//println(err.Error())
}
func TestUnixTime(t *testing.T) {
......@@ -206,6 +233,8 @@ func TestUnixTime(t *testing.T) {
now := time.Now()
id, err := is.Insert(UnixTime(now))
checkNoError(t, err, "error inserting UnixTime: %s")
_, err = is.Insert(UnixTime{})
checkNoError(t, err, "error inserting UnixTime: %s")
checkFinalize(is, t)
// the format used to persist has a max precision of 1s.
......@@ -215,4 +244,12 @@ func TestUnixTime(t *testing.T) {
err = db.OneValue("SELECT time FROM test where ROWID = ?", &ut, id)
checkNoError(t, err, "error selecting UnixTime: %s")
assert.Equal(t, now, time.Time(ut))
err = db.OneValue("SELECT null", &ut)
checkNoError(t, err, "%s")
assert.T(t, ((time.Time)(ut)).IsZero())
err = db.OneValue("SELECT 'bim'", &ut)
assert.T(t, err != nil)
//println(err.Error())
}
......@@ -229,6 +229,30 @@ func TestScanTimeFromView(t *testing.T) {
assert.Tf(t, err != nil, "scan error expected")
}
func TestScanNumericalAsTime(t *testing.T) {
db := sqlOpen(t)
defer checkSqlDbClose(db, t)
now := time.Now()
_, err := db.Exec("CREATE TABLE test (ms TIMESTAMP); INSERT INTO test VALUES (?)", now)
checkNoError(t, err, "%s")
row := db.QueryRow("SELECT ms FROM test")
now = now.Truncate(time.Millisecond)
var ms time.Time
err = row.Scan(&ms)
checkNoError(t, err, "%s")
//fmt.Printf("%v <=> %v\n", now, ms)
assert.Equal(t, now, ms)
_, err = db.Exec("DELETE FROM test; INSERT INTO test VALUES (?)", "bim")
checkNoError(t, err, "%s")
row = db.QueryRow("SELECT ms FROM test")
err = row.Scan(&ms)
assert.T(t, err != nil)
//println(err.Error())
}
// Adapted from https://github.com/bradfitz/go-sql-test/blob/master/src/sqltest/sql_test.go
func TestBlobs(t *testing.T) {
db := sqlOpen(t)
......
......@@ -62,7 +62,7 @@ func TestViews(t *testing.T) {
assert.Equal(t, 0, len(views), "table count")
err = db.FastExec("CREATE VIEW myview AS SELECT 1")
checkNoError(t, err, "error creating view: %s")
views, err = db.Views("", false)
views, err = db.Views("main", false)
checkNoError(t, err, "error looking for views: %s")
assert.Equal(t, 1, len(views), "table count")
assert.Equal(t, "myview", views[0], "table name")
......@@ -84,6 +84,9 @@ func TestIndexes(t *testing.T) {
tbl, ok := indexes["idx"]
assert.T(t, ok, "no index")
assert.Equalf(t, "test", tbl, "got: %s; want: %s", tbl, "test")
indexes, err = db.Indexes("main", false)
checkNoError(t, err, "error looking for indexes: %s")
}
func TestColumns(t *testing.T) {
......@@ -147,6 +150,9 @@ func TestForeignKeys(t *testing.T) {
if fk.From[0] != "parentId" || fk.Table != "parent" || fk.To[0] != "id" {
t.Errorf("unexpected FK data: %#v", fk)
}
fks, err = db.ForeignKeys("main", "child")
checkNoError(t, err, "error listing FKs: %s")
}
func TestTableIndexes(t *testing.T) {
......@@ -171,6 +177,11 @@ func TestTableIndexes(t *testing.T) {
}
column := columns[0]
assert.Equal(t, "a_string", column.Name, "column name")
indexes, err = db.TableIndexes("main", "test")
checkNoError(t, err, "error listing indexes: %s")
columns, err = db.IndexColumns("main", "test_index")
checkNoError(t, err, "error listing index columns: %s")
}
func TestColumnMetadata(t *testing.T) {
......@@ -236,3 +247,19 @@ func TestColumnMetadataOnExpr(t *testing.T) {
affinity := s.ColumnTypeAffinity(0)
assert.Equal(t, None, affinity, "affinity")
}
func TestColumnTypeAffinity(t *testing.T) {
db := open(t)
defer checkClose(db, t)
checkNoError(t, db.FastExec("CREATE TABLE test (i INT, f REAL, n NUM, b BLOB, t TEXT, v);"), "%s")
s, err := db.Prepare("SELECT i, f, n, b, t, v FROM test")
checkNoError(t, err, "%s")
defer checkFinalize(s, t)
assert.Equal(t, Integral, s.ColumnTypeAffinity(0), "affinity")
assert.Equal(t, Real, s.ColumnTypeAffinity(1), "affinity")
assert.Equal(t, Numerical, s.ColumnTypeAffinity(2), "affinity")
assert.Equal(t, None, s.ColumnTypeAffinity(3), "affinity")
assert.Equal(t, Textual, s.ColumnTypeAffinity(4), "affinity")
assert.Equal(t, None, s.ColumnTypeAffinity(5), "affinity")
}
......@@ -158,7 +158,7 @@ func (c *Conn) ForeignKeyCheck(dbName, table string) ([]FkViolation, error) {
}
} else {
if len(table) == 0 {
pragma = Mprintf("PRAGMA %Q.foreign_key_check", table)
pragma = Mprintf("PRAGMA %Q.foreign_key_check", dbName)
} else {
pragma = Mprintf2("PRAGMA %Q.foreign_key_check(%Q)", dbName, table)
}
......
......@@ -16,6 +16,7 @@ func TestIntegrityCheck(t *testing.T) {
db := open(t)
defer checkClose(db, t)
checkNoError(t, db.IntegrityCheck("", 1, true), "Error checking integrity of database: %s")
checkNoError(t, db.IntegrityCheck("", 1, false), "Error checking integrity of database: %s")
}
func TestEncoding(t *testing.T) {
......@@ -151,4 +152,16 @@ func TestForeignKeyCheck(t *testing.T) {
fk, ok := fks[v.FkId]
assert.Tf(t, ok, "no FK with id: %d", v.FkId)
assert.Equal(t, &ForeignKey{Table: "tree", From: []string{"parentId"}, To: []string{"id"}}, fk)
mvs, err := db.ForeignKeyCheck("main", "tree")
checkNoError(t, err, "error while checking FK: %s")
assert.Equal(t, vs, mvs)
mvs, err = db.ForeignKeyCheck("main", "")
checkNoError(t, err, "error while checking FK: %s")
assert.Equal(t, vs, mvs)
mvs, err = db.ForeignKeyCheck("", "")
checkNoError(t, err, "error while checking FK: %s")
assert.Equal(t, vs, mvs)
}
......@@ -130,6 +130,18 @@ func TestExists(t *testing.T) {
assert.T(t, !b, "no row expected")
b = Must(db.Exists("SELECT 1 WHERE 1 = 1"))
assert.T(t, b, "one row expected")
_, err := db.Exists("SELECT 1", 1)
assert.T(t, err != nil)
//println(err.Error())
_, err = db.Exists("SELECT 1 FROM test")
assert.T(t, err != nil)
//println(err.Error())
_, err = db.Exists("PRAGMA shrink_memory")
assert.T(t, err != nil)
//println(err.Error())
}
func TestInsert(t *testing.T) {
......@@ -294,3 +306,42 @@ func TestCommitMisuse(t *testing.T) {
}
assert.Equal(t, err, db.LastError())
}
func TestNilDb(t *testing.T) {
var db *Conn
err := db.Exec("DROP TABLE IF EXISTS test")
assert.T(t, err != nil)
//fmt.Println(err.Error())
err = db.Close()
assert.T(t, err != nil)
//fmt.Println(err.Error())
}
func TestError(t *testing.T) {
err := ErrMisuse
assert.T(t, err.Error() != "")
}
func TestOneValueMisuse(t *testing.T) {
db := open(t)
defer checkClose(db, t)
var value interface{}
err := db.OneValue("SELECT 1", &value, 1)
assert.T(t, err != nil)
//println(err.Error())
err = db.OneValue("SELECT 1 FROM test", &value)
assert.T(t, err != nil)
//println(err.Error())
err = db.OneValue("PRAGMA shrink_memory", &value)
assert.T(t, err != nil)
//println(err.Error())
err = db.OneValue("SELECT 1 LIMIT 0", &value)
assert.T(t, err != nil)
//println(err.Error())
}
......@@ -6,6 +6,7 @@ package sqlite_test
import (
"math"
"os"
"reflect"
"testing"
"time"
......@@ -113,6 +114,10 @@ func TestScanColumn(t *testing.T) {
null = Must(s.ScanByIndex(2, &i3))
assert.T(t, !null, "expected not null value")
assert.Equal(t, 0, i3)
err = s.Scan(i1, i2, i3, nil)
assert.T(t, err != nil)
//println(err.Error())
}
func TestNamedScanColumn(t *testing.T) {
......@@ -143,6 +148,10 @@ func TestNamedScanColumn(t *testing.T) {
err = s.NamedScan("invalid", &i1)
assert.T(t, err != nil, "expected invalid name")
//println(err.Error())
err = s.NamedScan("i1", i1)
assert.T(t, err != nil, "expected invalid type")
//println(err.Error())
}
func TestScanCheck(t *testing.T) {
......@@ -279,12 +288,17 @@ func TestCloseTwice(t *testing.T) {
func TestStmtMisuse(t *testing.T) {
db := open(t)
defer checkClose(db, t)
createTable(db, t)
s, err := db.Prepare("MISUSE")
assert.T(t, s == nil && err != nil, "error expected")
//println(err.Error())
err = s.Finalize()
assert.T(t, err != nil, "error expected")
_, err = db.Prepare("INSERT INTO test VALUES (?, ?, ?, ?)", os.ErrInvalid, nil, nil, nil)
assert.T(t, err != nil)
//println(err.Error())
}
func TestStmtWithClosedDb(t *testing.T) {
......@@ -327,7 +341,7 @@ func TestStmtExecWithSelect(t *testing.T) {
checkNoError(t, err, "prepare error: %s")
defer s1.Finalize()
err = s.Exec()
err = s1.Exec()
assert.T(t, err != nil, "error expected")
//println(err.Error())
}
......@@ -398,6 +412,8 @@ func TestNamedBind(t *testing.T) {
assert.T(t, err != nil, "missing params")
err = is.NamedBind(byt, ":b")
assert.T(t, err != nil, "invalid param name")
err = is.NamedBind(":b", byt, ":blob", os.ErrInvalid)
assert.T(t, err != nil, "invalid param type")
checkFinalize(is, t)
s, err := db.Prepare("SELECT data AS bs, byte AS b FROM test")
......@@ -433,7 +449,10 @@ func TestBind(t *testing.T) {
_, err = is.Next()
checkNoError(t, err, "step error: %s")
err = is.Bind(nil, db)
err = is.Bind(int32(1), float32(273.1))
checkNoError(t, err, "bind error: %s")
err = is.Bind(nil, os.ErrInvalid)
assert.T(t, err != nil, "unsupported type error expected")
}
......@@ -577,6 +596,10 @@ func TestBlankQuery(t *testing.T) {
defer checkFinalize(s, t)
assert.T(t, s.Empty(), "empty stmt expected")
assert.Equal(t, "", s.Tail(), "empty tail expected")
_, err = s.SelectOneRow()
assert.T(t, err != nil, "error expected")
//fmt.Println(err.Error())
}
func TestNilStmt(t *testing.T) {
......@@ -634,4 +657,54 @@ func TestBindAndScanReflect(t *testing.T) {
assert.Equal(t, Enum(1), enum)
checkNoError(t, is.BindReflect(1, enum), "bind error: %s")
type Amount float64
var amount Amount
null, err = s.ScanReflect(0, &amount)
checkNoError(t, err, "scan error: %s")
assert.Equal(t, Amount(1), amount)
checkNoError(t, is.BindReflect(1, amount), "bind error: %s")
}
func TestSelect(t *testing.T) {
db := open(t)
defer checkClose(db, t)
s, err := db.Prepare("SELECT 1 LIMIT ?")
checkNoError(t, err, "prepare error: %s")
defer checkFinalize(s, t)
err = s.Select(func(s *Stmt) error {
return s.Scan(nil)
}, 1)
checkNoError(t, err, "select error: %s")
}
func TestStmtCache(t *testing.T) {
db := open(t)
defer checkClose(db, t)
s, err := db.Prepare("SELECT 1 LIMIT ?")
checkNoError(t, err, "prepare error: %s")
s.Finalize()
s, err = db.Prepare("SELECT 1 LIMIT ?", 0)
checkNoError(t, err, "prepare error: %s")
defer checkFinalize(s, t)
}
func TestCheckTypeMismatch(t *testing.T) {
db := open(t)
defer checkClose(db, t)
var i int
err := db.OneValue("SELECT 3.14", &i)
assert.T(t, err != nil)
//println(err.Error())
var f float64
err = db.OneValue("SELECT X'53514C697465'", &f)
assert.T(t, err != nil)
//println(err.Error())
}
......@@ -130,6 +130,13 @@ func TestExplainQueryPlan(t *testing.T) {
defer checkFinalize(s, t)
w, err := os.Open(os.DevNull)
checkNoError(t, err, "couldn't open /dev/null: %s")
defer w.Close()
err = s.ExplainQueryPlan(w)
checkNoError(t, err, "error while explaining query plan: %s")
e, err := db.Prepare("")
checkNoError(t, err, "error while preparing stmt: %s")
defer checkFinalize(e, t)
err = e.ExplainQueryPlan(w)
assert.T(t, err != nil)
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment