Files

463 lines
9.7 KiB
Go

// Copyright (C) 2020-2025, Lux Industries Inc. All rights reserved.
// See the file LICENSE for licensing terms.
package linkeddb
import (
"testing"
"github.com/stretchr/testify/require"
database "github.com/luxfi/database"
"github.com/luxfi/database/memdb"
)
func TestLinkedDB(t *testing.T) {
require := require.New(t)
db := memdb.New()
ldb := NewDefault(db)
key := []byte("hello")
value := []byte("world")
has, err := ldb.Has(key)
require.NoError(err)
require.False(has)
_, err = ldb.Get(key)
require.Equal(database.ErrNotFound, err)
require.NoError(ldb.Delete(key))
require.NoError(ldb.Put(key, value))
has, err = ldb.Has(key)
require.NoError(err)
require.True(has)
v, err := ldb.Get(key)
require.NoError(err)
require.Equal(value, v)
require.NoError(ldb.Delete(key))
has, err = ldb.Has(key)
require.NoError(err)
require.False(has)
_, err = ldb.Get(key)
require.Equal(database.ErrNotFound, err)
iterator := ldb.NewIterator()
require.False(iterator.Next())
iterator.Release()
}
func TestLinkedDBDuplicatedPut(t *testing.T) {
require := require.New(t)
db := memdb.New()
ldb := NewDefault(db)
key := []byte("hello")
value1 := []byte("world1")
value2 := []byte("world2")
require.NoError(ldb.Put(key, value1))
require.NoError(ldb.Put(key, value2))
v, err := ldb.Get(key)
require.NoError(err)
require.Equal(value2, v)
require.NoError(ldb.Delete(key))
iterator := ldb.NewIterator()
require.False(iterator.Next())
iterator.Release()
}
func TestLinkedDBMultiplePuts(t *testing.T) {
require := require.New(t)
db := memdb.New()
ldb := NewDefault(db)
key1 := []byte("hello1")
key2 := []byte("hello2")
key3 := []byte("hello3")
value1 := []byte("world1")
value2 := []byte("world2")
value3 := []byte("world3")
require.NoError(ldb.Put(key1, value1))
require.NoError(ldb.Put(key2, value2))
v, err := ldb.Get(key1)
require.NoError(err)
require.Equal(value1, v)
v, err = ldb.Get(key2)
require.NoError(err)
require.Equal(value2, v)
require.NoError(ldb.Delete(key2))
require.NoError(ldb.Put(key2, value2))
require.NoError(ldb.Put(key3, value3))
require.NoError(ldb.Delete(key2))
require.NoError(ldb.Delete(key1))
require.NoError(ldb.Delete(key3))
iterator := ldb.NewIterator()
next := iterator.Next()
require.False(next, "database should be empty")
iterator.Release()
}
func TestEmptyLinkedDBIterator(t *testing.T) {
require := require.New(t)
db := memdb.New()
ldb := NewDefault(db)
iterator := ldb.NewIterator()
next := iterator.Next()
require.False(next, "The iterator should now be exhausted")
k := iterator.Key()
require.Nil(k, "The iterator returned the wrong key")
v := iterator.Value()
require.Nil(v, "The iterator returned the wrong value")
require.NoError(iterator.Error())
iterator.Release()
}
func TestLinkedDBLoadHeadKey(t *testing.T) {
require := require.New(t)
db := memdb.New()
ldb := NewDefault(db)
key := []byte("hello")
value := []byte("world")
require.NoError(ldb.Put(key, value))
ldb = NewDefault(db)
iterator := ldb.NewIterator()
next := iterator.Next()
require.True(next, "The iterator shouldn't be exhausted yet")
k := iterator.Key()
require.Equal(key, k, "The iterator returned the wrong key")
v := iterator.Value()
require.Equal(value, v, "The iterator returned the wrong value")
next = iterator.Next()
require.False(next, "The iterator should now be exhausted")
k = iterator.Key()
require.Nil(k, "The iterator returned the wrong key")
v = iterator.Value()
require.Nil(v, "The iterator returned the wrong value")
require.NoError(iterator.Error())
iterator.Release()
}
func TestSingleLinkedDBIterator(t *testing.T) {
require := require.New(t)
db := memdb.New()
ldb := NewDefault(db)
key := []byte("hello")
value := []byte("world")
require.NoError(ldb.Put(key, value))
iterator := ldb.NewIterator()
next := iterator.Next()
require.True(next, "The iterator shouldn't be exhausted yet")
k := iterator.Key()
require.Equal(key, k, "The iterator returned the wrong key")
v := iterator.Value()
require.Equal(value, v, "The iterator returned the wrong value")
next = iterator.Next()
require.False(next, "The iterator should now be exhausted")
k = iterator.Key()
require.Nil(k, "The iterator returned the wrong key")
v = iterator.Value()
require.Nil(v, "The iterator returned the wrong value")
require.NoError(iterator.Error())
iterator.Release()
}
func TestMultipleLinkedDBIterator(t *testing.T) {
require := require.New(t)
db := memdb.New()
ldb := NewDefault(db)
key0 := []byte("hello0")
key1 := []byte("hello1")
value0 := []byte("world0")
value1 := []byte("world1")
require.NoError(ldb.Put(key0, value0))
require.NoError(ldb.Put(key1, value1))
iterator := ldb.NewIterator()
next := iterator.Next()
require.True(next, "The iterator shouldn't be exhausted yet")
k := iterator.Key()
require.Equal(key1, k, "The iterator returned the wrong key")
v := iterator.Value()
require.Equal(value1, v, "The iterator returned the wrong value")
next = iterator.Next()
require.True(next, "The iterator shouldn't be exhausted yet")
k = iterator.Key()
require.Equal(key0, k, "The iterator returned the wrong key")
v = iterator.Value()
require.Equal(value0, v, "The iterator returned the wrong value")
next = iterator.Next()
require.False(next, "The iterator should now be exhausted")
require.NoError(iterator.Error())
iterator.Release()
}
func TestMultipleLinkedDBIteratorStart(t *testing.T) {
require := require.New(t)
db := memdb.New()
ldb := NewDefault(db)
key0 := []byte("hello0")
key1 := []byte("hello1")
value0 := []byte("world0")
value1 := []byte("world1")
require.NoError(ldb.Put(key0, value0))
require.NoError(ldb.Put(key1, value1))
iterator := ldb.NewIteratorWithStart(key1)
next := iterator.Next()
require.True(next, "The iterator shouldn't be exhausted yet")
k := iterator.Key()
require.Equal(key1, k, "The iterator returned the wrong key")
v := iterator.Value()
require.Equal(value1, v, "The iterator returned the wrong value")
next = iterator.Next()
require.True(next, "The iterator shouldn't be exhausted yet")
k = iterator.Key()
require.Equal(key0, k, "The iterator returned the wrong key")
v = iterator.Value()
require.Equal(value0, v, "The iterator returned the wrong value")
next = iterator.Next()
require.False(next, "The iterator should now be exhausted")
require.NoError(iterator.Error())
iterator.Release()
}
func TestSingleLinkedDBIteratorStart(t *testing.T) {
require := require.New(t)
db := memdb.New()
ldb := NewDefault(db)
key0 := []byte("hello0")
key1 := []byte("hello1")
value0 := []byte("world0")
value1 := []byte("world1")
require.NoError(ldb.Put(key0, value0))
require.NoError(ldb.Put(key1, value1))
iterator := ldb.NewIteratorWithStart(key0)
next := iterator.Next()
require.True(next, "The iterator shouldn't be exhausted yet")
k := iterator.Key()
require.Equal(key0, k, "The iterator returned the wrong key")
v := iterator.Value()
require.Equal(value0, v, "The iterator returned the wrong value")
next = iterator.Next()
require.False(next, "The iterator should now be exhausted")
require.NoError(iterator.Error())
iterator.Release()
}
// Test that if we call NewIteratorWithStart with a key that is not
// in the database, the iterator will start at the head
func TestEmptyLinkedDBIteratorStart(t *testing.T) {
require := require.New(t)
db := memdb.New()
ldb := NewDefault(db)
key0 := []byte("hello0")
key1 := []byte("hello1")
key2 := []byte("hello2")
value0 := []byte("world0")
value1 := []byte("world1")
require.NoError(ldb.Put(key0, value0))
require.NoError(ldb.Put(key1, value1))
iter := ldb.NewIteratorWithStart(key2)
i := 0
for iter.Next() {
require.Contains([][]byte{key0, key1}, iter.Key())
require.Contains([][]byte{value0, value1}, iter.Value())
i++
}
require.Equal(2, i)
require.NoError(iter.Error())
iter.Release()
}
func TestLinkedDBIsEmpty(t *testing.T) {
require := require.New(t)
db := memdb.New()
ldb := NewDefault(db)
isEmpty, err := ldb.IsEmpty()
require.NoError(err)
require.True(isEmpty)
key := []byte("hello")
value := []byte("world")
require.NoError(ldb.Put(key, value))
isEmpty, err = ldb.IsEmpty()
require.NoError(err)
require.False(isEmpty)
require.NoError(ldb.Delete(key))
isEmpty, err = ldb.IsEmpty()
require.NoError(err)
require.True(isEmpty)
}
func TestLinkedDBHeadKey(t *testing.T) {
require := require.New(t)
db := memdb.New()
ldb := NewDefault(db)
_, err := ldb.HeadKey()
require.Equal(database.ErrNotFound, err)
key0 := []byte("hello0")
value0 := []byte("world0")
key1 := []byte("hello1")
value1 := []byte("world1")
require.NoError(ldb.Put(key0, value0))
headKey, err := ldb.HeadKey()
require.NoError(err)
require.Equal(key0, headKey)
require.NoError(ldb.Put(key1, value1))
headKey, err = ldb.HeadKey()
require.NoError(err)
require.Equal(key1, headKey)
require.NoError(ldb.Delete(key1))
headKey, err = ldb.HeadKey()
require.NoError(err)
require.Equal(key0, headKey)
}
func TestLinkedDBHead(t *testing.T) {
require := require.New(t)
db := memdb.New()
ldb := NewDefault(db)
_, _, err := ldb.Head()
require.Equal(database.ErrNotFound, err)
key0 := []byte("hello0")
value0 := []byte("world0")
key1 := []byte("hello1")
value1 := []byte("world1")
require.NoError(ldb.Put(key0, value0))
headKey, headVal, err := ldb.Head()
require.NoError(err)
require.Equal(key0, headKey)
require.Equal(value0, headVal)
require.NoError(ldb.Put(key1, value1))
headKey, headVal, err = ldb.Head()
require.NoError(err)
require.Equal(key1, headKey)
require.Equal(value1, headVal)
require.NoError(ldb.Delete(key1))
headKey, headVal, err = ldb.Head()
require.NoError(err)
require.Equal(key0, headKey)
require.Equal(value0, headVal)
}