Commit 64972f0c authored by gwenn's avatar gwenn

Improve test coverage.

parent 0a97f252
......@@ -48,4 +48,8 @@ func TestBackupMisuse(t *testing.T) {
err = bck.Run(10, 0, nil)
assert.T(t, err != nil, "misuse expected")
//println(err.Error())
bck, err = NewBackup(db, "", nil, "")
assert.T(t, err != nil, "error expected")
//println(err.Error())
}
......@@ -6,6 +6,7 @@ package sqlite_test
import (
"io"
"os"
"testing"
"github.com/bmizerany/assert"
......@@ -61,6 +62,9 @@ func TestBlob(t *testing.T) {
err = br.Reopen(rowid)
checkNoError(t, err, "blob reopen error: %s")
_, err = br.Seek(0, os.SEEK_SET)
checkNoError(t, err, "blob seek error: %s")
br.Close()
}
......
......@@ -135,7 +135,7 @@ func TestBindTimeAsNumeric(t *testing.T) {
checkNoError(t, err, "error inserting JulianTime: %s")
checkFinalize(is, t)
// And the format used to persist has a max precision of 1s.
// the format used to persist has a max precision of 1s.
now = now.Truncate(time.Second)
var tim time.Time
......@@ -147,3 +147,72 @@ func TestBindTimeAsNumeric(t *testing.T) {
checkNoError(t, err, "error selecting JulianTime: %s")
assert.Equal(t, now, tim)
}
func TestJulianTime(t *testing.T) {
db := open(t)
defer checkClose(db, t)
err := db.Exec("CREATE TABLE test (time NUMERIC)")
checkNoError(t, err, "exec error: %s")
is, err := db.Prepare("INSERT INTO test (time) VALUES (?)")
checkNoError(t, err, "prepare error: %s")
now := time.Now()
id, err := is.Insert(JulianTime(now))
checkNoError(t, err, "error inserting JulianTime: %s")
checkFinalize(is, t)
// the format used to persist has a max precision of 1s.
now = now.Truncate(time.Second)
var jt JulianTime
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))
}
func TestTimeStamp(t *testing.T) {
db := open(t)
defer checkClose(db, t)
err := db.Exec("CREATE TABLE test (time NUMERIC)")
checkNoError(t, err, "exec error: %s")
is, err := db.Prepare("INSERT INTO test (time) VALUES (?)")
checkNoError(t, err, "prepare error: %s")
now := time.Now()
id, err := is.Insert(TimeStamp(now))
checkNoError(t, err, "error inserting TimeStamp: %s")
checkFinalize(is, t)
// the format used to persist has a max precision of 1ms.
now = now.Truncate(time.Millisecond)
var ts TimeStamp
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))
}
func TestUnixTime(t *testing.T) {
db := open(t)
defer checkClose(db, t)
err := db.Exec("CREATE TABLE test (time NUMERIC)")
checkNoError(t, err, "exec error: %s")
is, err := db.Prepare("INSERT INTO test (time) VALUES (?)")
checkNoError(t, err, "prepare error: %s")
now := time.Now()
id, err := is.Insert(UnixTime(now))
checkNoError(t, err, "error inserting UnixTime: %s")
checkFinalize(is, t)
// the format used to persist has a max precision of 1s.
now = now.Truncate(time.Second)
var ut UnixTime
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))
}
......@@ -129,6 +129,11 @@ func TestSqlTx(t *testing.T) {
checkNoError(t, err, "Error while begining tx: %s")
err = tx.Rollback()
checkNoError(t, err, "Error while rollbacking tx: %s")
tx, err = db.Begin()
checkNoError(t, err, "Error while begining tx: %s")
err = tx.Commit()
checkNoError(t, err, "Error while commiting tx: %s")
}
func TestSqlPrepare(t *testing.T) {
......@@ -191,10 +196,24 @@ func TestCustomRegister(t *testing.T) {
defer checkSqlDbClose(db, t)
conn := sqlite.Unwrap(db)
ro, err := conn.Readonly("main")
checkNoError(t, err, "Error while setting reverse_unordered_selects status: %s")
checkNoError(t, err, "Error while reading readonly status: %s")
assert.Tf(t, ro, "readonly = %t; want %t", ro, true)
}
func TestCustomRegister2(t *testing.T) {
sql.Register("sqlite3FK", sqlite.NewDriver(nil, func(c *sqlite.Conn) error {
_, err := c.EnableFKey(true)
return err
}))
db, err := sql.Open("sqlite3FK", ":memory:")
checkNoError(t, err, "Error while opening customized db: %s")
defer checkSqlDbClose(db, t)
conn := sqlite.Unwrap(db)
fk, err := conn.IsFKeyEnabled()
checkNoError(t, err, "Error while reading foreign_keys status: %s")
assert.Tf(t, fk, "foreign_keys = %t; want %t", fk, true)
}
// sql: Scan error on column index 0: unsupported driver -> Scan pair: []uint8 -> *time.Time
func TestScanTimeFromView(t *testing.T) {
db := sqlCreate("CREATE VIEW v AS SELECT strftime('%Y-%m-%d %H:%M:%f', 'now') AS tic", t)
......
// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package sqlite_test
import (
"fmt"
"testing"
. "github.com/gwenn/gosqlite"
)
func commitHook(d interface{}) bool {
if t, ok := d.(*testing.T); ok {
t.Log("CMT")
} else {
fmt.Println(d)
}
return false
}
func rollbackHook(d interface{}) {
if t, ok := d.(*testing.T); ok {
t.Log("RBK")
} else {
fmt.Println(d)
}
}
func updateHook(d interface{}, a Action, dbName, tableName string, rowId int64) {
if t, ok := d.(*testing.T); ok {
t.Logf("UPD: %d, %s.%s.%d\n", a, dbName, tableName, rowId)
} else {
fmt.Printf("%s: %d, %s.%s.%d\n", d, a, dbName, tableName, rowId)
}
}
func TestNoHook(t *testing.T) {
db := open(t)
defer checkClose(db, t)
db.CommitHook(nil, nil)
db.RollbackHook(nil, nil)
db.UpdateHook(nil, nil)
}
func TestCommitHook(t *testing.T) {
db := open(t)
defer checkClose(db, t)
db.CommitHook(commitHook, t)
checkNoError(t, db.Begin(), "%s")
createTable(db, t)
checkNoError(t, db.Commit(), "%s")
}
func TestRollbackHook(t *testing.T) {
db := open(t)
defer checkClose(db, t)
db.RollbackHook(rollbackHook, t)
checkNoError(t, db.Begin(), "%s")
createTable(db, t)
checkNoError(t, db.Rollback(), "%s")
}
func TestUpdateHook(t *testing.T) {
db := open(t)
defer checkClose(db, t)
createTable(db, t)
db.UpdateHook(updateHook, t)
checkNoError(t, db.Exec("INSERT INTO test VALUES (1, 273.1, 0, 'data')"), "%s")
}
......@@ -47,6 +47,10 @@ func TestTables(t *testing.T) {
tables, err = db.Tables("", true)
checkNoError(t, err, "error looking for tables: %s")
assert.Equal(t, 0, len(tables), "table count")
tables, err = db.Tables("bim", false)
assert.T(t, err != nil, "error expected")
//println(err.Error())
}
func TestViews(t *testing.T) {
......@@ -72,10 +76,14 @@ func TestIndexes(t *testing.T) {
db := open(t)
defer checkClose(db, t)
createTable(db, t)
checkNoError(t, db.Exec("CREATE INDEX idx ON test(a_string)"), "%s")
indexes, err := db.Indexes("", false)
checkNoError(t, err, "error looking for indexes: %s")
assert.Equal(t, 0, len(indexes), "table count")
assert.Equal(t, 1, len(indexes), "index count")
tbl, ok := indexes["idx"]
assert.T(t, ok, "no index")
assert.Equalf(t, "test", tbl, "got: %s; want: %s", tbl, "test")
}
func TestColumns(t *testing.T) {
......@@ -93,6 +101,14 @@ func TestColumns(t *testing.T) {
columns, err = db.Columns("main", "test")
checkNoError(t, err, "error listing columns: %s")
columns, err = db.Columns("bim", "test")
assert.T(t, err != nil, "expected error")
//println(err.Error())
columns, err = db.Columns("", "bim")
assert.T(t, err != nil, "expected error")
//println(err.Error())
}
func TestColumn(t *testing.T) {
......@@ -108,6 +124,10 @@ func TestColumn(t *testing.T) {
column, err = db.Column("main", "test", "id")
checkNoError(t, err, "error getting column metadata: %s")
column, err = db.Column("", "test", "bim")
assert.T(t, err != nil, "expected error")
//println(err.Error())
}
func TestForeignKeys(t *testing.T) {
......
......@@ -138,9 +138,9 @@ func (c *Conn) SetSynchronous(dbName string, mode int) error {
// FkViolation is the description of one foreign key constraint violation.
type FkViolation struct {
Table string
Rowid int64
RowId int64
Parent string
Fkid int
FkId int
}
// ForeignKeyCheck checks the database, or the table, for foreign key constraints that are violated
......@@ -172,7 +172,7 @@ func (c *Conn) ForeignKeyCheck(dbName, table string) ([]FkViolation, error) {
var violations = make([]FkViolation, 0, 20)
err = s.Select(func(s *Stmt) (err error) {
v := FkViolation{}
if err = s.Scan(&v.Table, &v.Rowid, &v.Parent, &v.Fkid); err != nil {
if err = s.Scan(&v.Table, &v.RowId, &v.Parent, &v.FkId); err != nil {
return
}
violations = append(violations, v)
......
......@@ -9,6 +9,7 @@ import (
"testing"
"github.com/bmizerany/assert"
. "github.com/gwenn/gosqlite"
)
func TestIntegrityCheck(t *testing.T) {
......@@ -98,3 +99,56 @@ func TestQueryOnly(t *testing.T) {
assert.T(t, err != nil, "expected error")
//println(err.Error())
}
func TestApplicationId(t *testing.T) {
if VersionNumber() < 3007017 {
return
}
db := open(t)
defer checkClose(db, t)
appId, err := db.ApplicationId("")
checkNoError(t, err, "error getting application Id: %s")
assert.Equalf(t, 0, appId, "got: %d; want: %d", appId, 0)
err = db.SetApplicationId("", 123)
checkNoError(t, err, "error setting application Id: %s")
appId, err = db.ApplicationId("")
checkNoError(t, err, "error getting application Id: %s")
assert.Equalf(t, 123, appId, "got: %d; want: %d", appId, 123)
}
func TestForeignKeyCheck(t *testing.T) {
if VersionNumber() < 3007016 {
return
}
db := open(t)
defer checkClose(db, t)
checkNoError(t, db.Exec(`
CREATE TABLE tree (
id INTEGER PRIMARY KEY NOT NULL,
parentId INTEGER,
name TEXT NOT NULL,
FOREIGN KEY (parentId) REFERENCES tree(id)
);
INSERT INTO tree VALUES (0, NULL, 'root'),
(1, 0, 'node1'),
(2, 0, 'node2'),
(3, 1, 'leaf'),
(4, 5, 'orphan')
;
`), "%s")
vs, err := db.ForeignKeyCheck("", "tree")
checkNoError(t, err, "error while checking FK: %s")
assert.Equal(t, 1, len(vs), "one FK violation expected")
v := vs[0]
assert.Equal(t, FkViolation{Table: "tree", RowId: 4, Parent: "tree", FkId: 0}, v)
fks, err := db.ForeignKeys("", "tree")
checkNoError(t, err, "error while loading FK: %s")
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)
}
......@@ -175,6 +175,12 @@ func Version() string {
return C.GoString(p)
}
// VersionNumber returns the run-time library version number as 300X00Y
// (See http://sqlite.org/c3ref/libversion.html)
func VersionNumber() int32 {
return int32(C.sqlite3_libversion_number())
}
// OpenFlag enumerates flags for file open operations
type OpenFlag int32
......@@ -455,13 +461,11 @@ func (c *Conn) BeginTransaction(t TransactionType) error {
// Commit commits transaction
func (c *Conn) Commit() error {
// TODO Check autocommit?
return c.FastExec("COMMIT")
}
// Rollback rollbacks transaction
func (c *Conn) Rollback() error {
// TODO Check autocommit?
return c.FastExec("ROLLBACK")
}
......@@ -529,6 +533,7 @@ func (c *Conn) RollbackSavepoint(name string) error {
return c.FastExec(Mprintf("ROLLBACK TO SAVEPOINT %Q", name))
}
/*
func (c *Conn) exec(cmd string) error {
s, err := c.prepare(cmd)
if err != nil {
......@@ -541,6 +546,7 @@ func (c *Conn) exec(cmd string) error {
}
return nil
}
*/
// FastExec executes one or many non-parameterized statement(s) (separated by semi-colon) with no control and no stmt cache.
func (c *Conn) FastExec(cmd string) error {
......
......@@ -250,6 +250,10 @@ func TestExecMisuse(t *testing.T) {
err := db.Exec("INSERT INTO test VALUES (?, ?, ?, ?); INSERT INTO test VALUES (?, ?, ?, ?)", 0, 273.1, 1, "test")
assert.T(t, err != nil, "exec misuse expected")
//println(err.Error())
err = db.Exec("CREATE FUNCTION incr(i INT) RETURN i+1;")
assert.T(t, err != nil, "syntax error expected")
//println(err.Error())
}
func TestExecTwice(t *testing.T) {
......@@ -275,3 +279,18 @@ func TestTransaction(t *testing.T) {
})
checkNoError(t, err, "error: %s")
}
func TestCommitMisuse(t *testing.T) {
db := open(t)
defer checkClose(db, t)
err := db.Commit()
assert.T(t, err != nil, "error expected")
if cerr, ok := err.(*ConnError); ok {
assert.Equal(t, ErrError, cerr.Code())
assert.Equal(t, 1, cerr.ExtendedCode())
} else {
t.Errorf("got %s; want ConnError", reflect.TypeOf(err))
}
assert.Equal(t, err, db.LastError())
}
......@@ -139,6 +139,10 @@ func TestNamedScanColumn(t *testing.T) {
_, err = s.ScanByName("invalid", &i1)
assert.T(t, err != nil, "expected invalid name")
//println(err.Error())
err = s.NamedScan("invalid", &i1)
assert.T(t, err != nil, "expected invalid name")
//println(err.Error())
}
func TestScanCheck(t *testing.T) {
......@@ -180,6 +184,36 @@ func TestScanNull(t *testing.T) {
null = Must(s.ScanByIndex(0, &ps))
assert.T(t, null, "expected null value")
assert.Equal(t, (*string)(nil), ps, "expected nil")
i, null, err := s.ScanInt64(0)
checkNoError(t, err, "scan error: %s")
assert.T(t, null, "expected null value")
assert.Equal(t, (int64)(0), i, "expected zero")
var i32 int32
null, err = s.ScanByIndex(0, &i32)
checkNoError(t, err, "scan error: %s")
assert.T(t, null, "expected null value")
assert.Equal(t, (int32)(0), i32, "expected zero")
f, null, err := s.ScanDouble(0)
checkNoError(t, err, "scan error: %s")
assert.T(t, null, "expected null value")
assert.Equal(t, (float64)(0), f, "expected zero")
b, null, err := s.ScanByte(0)
checkNoError(t, err, "scan error: %s")
assert.T(t, null, "expected null value")
assert.Equal(t, (byte)(0), b, "expected zero")
bo, null, err := s.ScanBool(0)
checkNoError(t, err, "scan error: %s")
assert.T(t, null, "expected null value")
assert.Equal(t, false, bo, "expected false")
rb, null := s.ScanRawBytes(0)
assert.T(t, null, "expected null value")
assert.Equal(t, 0, len(rb), "expected empty")
}
func TestScanNotNull(t *testing.T) {
......@@ -200,6 +234,16 @@ func TestScanNotNull(t *testing.T) {
null = Must(s.ScanByIndex(0, &ps))
assert.T(t, !null, "expected not null value")
assert.Equal(t, "1", *ps)
rb, null := s.ScanRawBytes(0)
assert.T(t, !null, "expected not null value")
assert.Equal(t, 1, len(rb), "expected not empty")
var i32 int32
null, err = s.ScanByIndex(0, &i32)
checkNoError(t, err, "scan error: %s")
assert.T(t, !null, "expected not null value")
assert.Equal(t, (int32)(1), i32)
}
/*
......@@ -278,6 +322,31 @@ func TestStmtExecWithSelect(t *testing.T) {
} else {
t.Errorf("got %s; want StmtError", reflect.TypeOf(err))
}
s1, err := db.Prepare("SELECT 1 LIMIT 0")
checkNoError(t, err, "prepare error: %s")
defer s1.Finalize()
err = s.Exec()
assert.T(t, err != nil, "error expected")
//println(err.Error())
}
func TestSelectOneRow(t *testing.T) {
db := open(t)
defer checkClose(db, t)
s, err := db.Prepare("SELECT 1")
checkNoError(t, err, "prepare error: %s")
defer s.Finalize()
exists, err := s.SelectOneRow(nil)
checkNoError(t, err, "select error: %s")
assert.T(t, exists)
exists, err = s.SelectOneRow(nil)
checkNoError(t, err, "select error: %s")
assert.T(t, !exists)
}
func TestStmtSelectWithInsert(t *testing.T) {
......@@ -506,4 +575,63 @@ func TestBlankQuery(t *testing.T) {
s, err := db.Prepare("")
checkNoError(t, err, "prepare error: %s")
defer checkFinalize(s, t)
assert.T(t, s.Empty(), "empty stmt expected")
assert.Equal(t, "", s.Tail(), "empty tail expected")
}
func TestNilStmt(t *testing.T) {
var s *Stmt
err := s.Finalize()
assert.T(t, err != nil, "error expected")
}
func TestBindAndScanReflect(t *testing.T) {
db := open(t)
defer checkClose(db, t)
s, err := db.Prepare("SELECT 1")
checkNoError(t, err, "prepare error: %s")
defer checkFinalize(s, t)
ok, err := s.Next()
checkNoError(t, err, "step error: %s")
assert.T(t, ok)
is, err := db.Prepare("SELECT ?")
checkNoError(t, err, "prepare error: %s")
defer checkFinalize(is, t)
type Flag bool
var bo Flag
null, err := s.ScanReflect(0, bo)
assert.T(t, err != nil, "scan error expected")
null, err = s.ScanReflect(0, &bo)
checkNoError(t, err, "scan error: %s")
assert.T(t, !null)
assert.Equal(t, Flag(true), bo)
checkNoError(t, is.BindReflect(1, bo), "bind error: %s")
type Type string
var typ Type
null, err = s.ScanReflect(0, &typ)
checkNoError(t, err, "scan error: %s")
assert.Equal(t, Type("1"), typ)
checkNoError(t, is.BindReflect(1, typ), "bind error: %s")
type Code int
var code Code
null, err = s.ScanReflect(0, &code)
checkNoError(t, err, "scan error: %s")
assert.Equal(t, Code(1), code)
checkNoError(t, is.BindReflect(1, code), "bind error: %s")
type Enum uint
var enum Enum
null, err = s.ScanReflect(0, &enum)
checkNoError(t, err, "scan error: %s")
assert.Equal(t, Enum(1), enum)
checkNoError(t, is.BindReflect(1, enum), "bind error: %s")
}
......@@ -79,31 +79,6 @@ func progressHandler(d interface{}) bool {
return false
}
func commitHook(d interface{}) bool {
if t, ok := d.(*testing.T); ok {
t.Log("CMT")
} else {
fmt.Println(d)
}
return false
}
func rollbackHook(d interface{}) {
if t, ok := d.(*testing.T); ok {
t.Log("RBK")
} else {
fmt.Println(d)
}
}
func updateHook(d interface{}, a Action, dbName, tableName string, rowId int64) {
if t, ok := d.(*testing.T); ok {
t.Logf("UPD: %d, %s.%s.%d\n", a, dbName, tableName, rowId)
} else {
fmt.Printf("%s: %d, %s.%s.%d\n", d, a, dbName, tableName, rowId)
}
}
func TestNoTrace(t *testing.T) {
db := open(t)
defer checkClose(db, t)
......@@ -112,9 +87,6 @@ func TestNoTrace(t *testing.T) {
db.Profile(nil, nil)
db.ProgressHandler(nil, 0, nil)
db.BusyHandler(nil, nil)
db.CommitHook(nil, nil)
db.RollbackHook(nil, nil)
db.UpdateHook(nil, nil)
}
func TestTrace(t *testing.T) {
......@@ -125,12 +97,17 @@ func TestTrace(t *testing.T) {
checkNoError(t, err, "couldn't set an authorizer: %s")
db.Profile(profile, t)
db.ProgressHandler(progressHandler, 1, t)
db.CommitHook(commitHook, t)
db.RollbackHook(rollbackHook, t)
db.UpdateHook(updateHook, t)
db.Exists("SELECT 1 WHERE 1 = ?", 1)
}
func TestProfile(t *testing.T) {
db := open(t)
defer checkClose(db, t)
db.Profile(profile, t)
defer db.Profile(nil, nil)
createTable(db, t)
}
func TestLog(t *testing.T) {
Log(0, "One message")
}
......
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