diff options
Diffstat (limited to 'transaction_test.go')
-rw-r--r-- | transaction_test.go | 123 |
1 files changed, 123 insertions, 0 deletions
diff --git a/transaction_test.go b/transaction_test.go index 6041f2f..b59d9b2 100644 --- a/transaction_test.go +++ b/transaction_test.go @@ -1,7 +1,11 @@ package bolt import ( + "fmt" + "os" + "sort" "testing" + "testing/quick" "github.com/stretchr/testify/assert" ) @@ -33,3 +37,122 @@ func TestTransactionGetMissing(t *testing.T) { assert.Nil(t, value) }) } + +// Ensure that a Transaction cursor can iterate over an empty bucket without error. +func TestTransactionCursorEmptyBucket(t *testing.T) { + withOpenDB(func(db *DB, path string) { + db.CreateBucket("widgets") + txn, _ := db.Transaction() + c := txn.Cursor("widgets") + k, v := c.First() + assert.Nil(t, k) + assert.Nil(t, v) + txn.Close() + }) +} + +// Ensure that a Transaction returns a nil when a bucket doesn't exist. +func TestTransactionCursorMissingBucket(t *testing.T) { + withOpenDB(func(db *DB, path string) { + db.CreateBucket("widgets") + txn, _ := db.Transaction() + assert.Nil(t, txn.Cursor("woojits")) + txn.Close() + }) +} + +// Ensure that a Transaction cursor can iterate over a single root with a couple elements. +func TestTransactionCursorLeafRoot(t *testing.T) { + withOpenDB(func(db *DB, path string) { + db.CreateBucket("widgets") + db.Put("widgets", []byte("baz"), []byte{}) + db.Put("widgets", []byte("foo"), []byte{0}) + db.Put("widgets", []byte("bar"), []byte{1}) + txn, _ := db.Transaction() + c := txn.Cursor("widgets") + + k, v := c.First() + assert.Equal(t, string(k), "bar") + assert.Equal(t, v, []byte{1}) + + k, v = c.Next() + assert.Equal(t, string(k), "baz") + assert.Equal(t, v, []byte{}) + + k, v = c.Next() + assert.Equal(t, string(k), "foo") + assert.Equal(t, v, []byte{0}) + + k, v = c.Next() + assert.Nil(t, k) + assert.Nil(t, v) + + k, v = c.Next() + assert.Nil(t, k) + assert.Nil(t, v) + + txn.Close() + }) +} + +// Ensure that a Transaction cursor can restart from the beginning. +func TestTransactionCursorRestart(t *testing.T) { + withOpenDB(func(db *DB, path string) { + db.CreateBucket("widgets") + db.Put("widgets", []byte("bar"), []byte{}) + db.Put("widgets", []byte("foo"), []byte{}) + + txn, _ := db.Transaction() + c := txn.Cursor("widgets") + + k, _ := c.First() + assert.Equal(t, string(k), "bar") + + k, _ = c.Next() + assert.Equal(t, string(k), "foo") + + k, _ = c.First() + assert.Equal(t, string(k), "bar") + + k, _ = c.Next() + assert.Equal(t, string(k), "foo") + + txn.Close() + }) +} + +// Ensure that a transaction can iterate over all elements in a bucket. +func TestTransactionCursorIterate(t *testing.T) { + f := func(items testdata) bool { + withOpenDB(func(db *DB, path string) { + // Bulk insert all values. + db.CreateBucket("widgets") + rwtxn, _ := db.RWTransaction() + for _, item := range items { + assert.NoError(t, rwtxn.Put("widgets", item.Key, item.Value)) + } + assert.NoError(t, rwtxn.Commit()) + + // Sort test data. + sort.Sort(items) + + // Iterate over all items and check consistency. + var index = 0 + txn, _ := db.Transaction() + c := txn.Cursor("widgets") + for k, v := c.First(); k != nil && index < len(items); k, v = c.Next() { + assert.Equal(t, k, items[index].Key) + assert.Equal(t, v, items[index].Value) + index++ + } + assert.Equal(t, len(items), index) + txn.Close() + }) + fmt.Fprint(os.Stderr, ".") + return true + } + if err := quick.Check(f, qconfig()); err != nil { + t.Error(err) + } + fmt.Fprint(os.Stderr, "\n") +} |