aboutsummaryrefslogtreecommitdiff
path: root/transaction_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'transaction_test.go')
-rw-r--r--transaction_test.go123
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")
+}