2023-03-31 11:52:04 +02:00
|
|
|
package state
|
|
|
|
|
|
|
|
import (
|
2023-04-01 00:25:05 +02:00
|
|
|
"bytes"
|
2023-03-31 11:52:04 +02:00
|
|
|
"testing"
|
|
|
|
)
|
|
|
|
|
2023-04-01 00:17:44 +02:00
|
|
|
// Check creation
|
|
|
|
func TestNewState(t *testing.T) {
|
2023-03-31 14:06:59 +02:00
|
|
|
st := NewState(5)
|
2023-04-01 23:19:12 +02:00
|
|
|
if len(st.Flags) != 2 {
|
2023-03-31 11:52:04 +02:00
|
|
|
t.Errorf("invalid state flag length: %v", len(st.Flags))
|
|
|
|
}
|
2023-03-31 14:06:59 +02:00
|
|
|
st = NewState(8)
|
2023-04-01 23:19:12 +02:00
|
|
|
if len(st.Flags) != 2 {
|
2023-03-31 11:52:04 +02:00
|
|
|
t.Errorf("invalid state flag length: %v", len(st.Flags))
|
|
|
|
}
|
2023-03-31 14:06:59 +02:00
|
|
|
st = NewState(17)
|
2023-04-01 23:19:12 +02:00
|
|
|
if len(st.Flags) != 4 {
|
2023-03-31 11:52:04 +02:00
|
|
|
t.Errorf("invalid state flag length: %v", len(st.Flags))
|
2023-04-01 00:17:44 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestStateFlags(t *testing.T) {
|
2023-04-01 23:19:12 +02:00
|
|
|
st := NewState(9)
|
2023-04-01 00:17:44 +02:00
|
|
|
v, err := st.GetFlag(2)
|
|
|
|
if err != nil {
|
|
|
|
t.Error(err)
|
|
|
|
}
|
|
|
|
if v {
|
|
|
|
t.Errorf("Expected bit 2 not to be set")
|
|
|
|
}
|
|
|
|
v, err = st.SetFlag(2)
|
|
|
|
if err != nil {
|
|
|
|
t.Error(err)
|
|
|
|
}
|
|
|
|
if !v {
|
|
|
|
t.Errorf("Expected change to be set for bit 2")
|
|
|
|
}
|
|
|
|
v, err = st.GetFlag(2)
|
|
|
|
if err != nil {
|
|
|
|
t.Error(err)
|
|
|
|
}
|
|
|
|
if !v {
|
|
|
|
t.Errorf("Expected bit 2 to be set")
|
|
|
|
}
|
|
|
|
v, err = st.SetFlag(10)
|
|
|
|
if err != nil {
|
|
|
|
t.Error(err)
|
|
|
|
}
|
|
|
|
if !v {
|
|
|
|
t.Errorf("Expected change to be set for bit 10")
|
|
|
|
}
|
|
|
|
v, err = st.GetFlag(10)
|
|
|
|
if err != nil {
|
|
|
|
t.Error(err)
|
|
|
|
}
|
|
|
|
if !v {
|
|
|
|
t.Errorf("Expected bit 10 to be set")
|
|
|
|
}
|
|
|
|
v, err = st.ResetFlag(2)
|
|
|
|
if err != nil {
|
|
|
|
t.Error(err)
|
|
|
|
}
|
|
|
|
if !v {
|
|
|
|
t.Errorf("Expected change to be set for bit 10")
|
|
|
|
}
|
|
|
|
v, err = st.GetFlag(2)
|
|
|
|
if err != nil {
|
|
|
|
t.Error(err)
|
|
|
|
}
|
|
|
|
if v {
|
|
|
|
t.Errorf("Expected bit 2 not to be set")
|
|
|
|
}
|
|
|
|
v, err = st.GetFlag(10)
|
|
|
|
if err != nil {
|
|
|
|
t.Error(err)
|
|
|
|
}
|
|
|
|
if !v {
|
|
|
|
t.Errorf("Expected bit 10 to be set")
|
|
|
|
}
|
|
|
|
v, err = st.SetFlag(10)
|
|
|
|
if err != nil {
|
|
|
|
t.Error(err)
|
|
|
|
}
|
|
|
|
if v {
|
|
|
|
t.Errorf("Expected change not to be set for bit 10")
|
2023-03-31 11:52:04 +02:00
|
|
|
}
|
2023-04-01 00:25:05 +02:00
|
|
|
v, err = st.SetFlag(2)
|
|
|
|
if err != nil {
|
|
|
|
t.Error(err)
|
|
|
|
}
|
2023-04-01 09:36:26 +02:00
|
|
|
v, err = st.SetFlag(16)
|
2023-04-01 00:25:05 +02:00
|
|
|
if err != nil {
|
|
|
|
t.Error(err)
|
|
|
|
}
|
2023-04-01 09:36:26 +02:00
|
|
|
v, err = st.SetFlag(17)
|
|
|
|
if err == nil {
|
|
|
|
t.Errorf("Expected out of range for bit index 17")
|
|
|
|
}
|
|
|
|
if !bytes.Equal(st.Flags[:3], []byte{0x04, 0x04, 0x01}) {
|
|
|
|
t.Errorf("Expected 0x040401, got %v", st.Flags[:3])
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestStateFlagFromSlice(t *testing.T) {
|
|
|
|
st := NewState(15)
|
|
|
|
_, _= st.SetFlag(2)
|
|
|
|
v := st.GetIndex([]byte{})
|
|
|
|
if v {
|
|
|
|
t.Errorf("Expected no match on empty compare")
|
|
|
|
}
|
|
|
|
v = st.GetIndex([]byte{0x01})
|
|
|
|
if v {
|
|
|
|
t.Errorf("Expected 0x01 not to match")
|
|
|
|
}
|
|
|
|
v = st.GetIndex([]byte{0x04})
|
|
|
|
if !v {
|
|
|
|
t.Errorf("Expected 0x04 to match")
|
|
|
|
}
|
|
|
|
_, _= st.SetFlag(12)
|
|
|
|
v = st.GetIndex([]byte{0x04})
|
|
|
|
if !v {
|
|
|
|
t.Errorf("Expected 0x04 to match")
|
|
|
|
}
|
|
|
|
v = st.GetIndex([]byte{0x00, 0x10})
|
|
|
|
if !v {
|
|
|
|
t.Errorf("Expected 0x1000 to match")
|
|
|
|
}
|
|
|
|
v, _ = st.ResetFlag(2)
|
|
|
|
v = st.GetIndex([]byte{0x00, 0x10})
|
|
|
|
if !v {
|
|
|
|
t.Errorf("Expected 0x1000 to matck")
|
2023-04-01 00:25:05 +02:00
|
|
|
}
|
2023-03-31 11:52:04 +02:00
|
|
|
}
|
|
|
|
|
2023-03-31 23:35:13 +02:00
|
|
|
//
|
2023-03-31 11:52:04 +02:00
|
|
|
func TestNewStateCache(t *testing.T) {
|
2023-03-31 14:06:59 +02:00
|
|
|
st := NewState(17)
|
2023-03-31 11:52:04 +02:00
|
|
|
if st.CacheSize != 0 {
|
|
|
|
t.Errorf("cache size not 0")
|
|
|
|
}
|
|
|
|
st = st.WithCacheSize(102525)
|
|
|
|
if st.CacheSize != 102525 {
|
|
|
|
t.Errorf("cache size not 102525")
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
2023-03-31 11:59:55 +02:00
|
|
|
|
|
|
|
func TestStateCacheUse(t *testing.T) {
|
2023-03-31 14:06:59 +02:00
|
|
|
st := NewState(17)
|
2023-03-31 13:56:11 +02:00
|
|
|
st = st.WithCacheSize(10)
|
2023-03-31 16:03:54 +02:00
|
|
|
st.Down("foo")
|
|
|
|
err := st.Add("bar", "baz", 0)
|
2023-03-31 13:56:11 +02:00
|
|
|
if err != nil {
|
|
|
|
t.Error(err)
|
|
|
|
}
|
2023-03-31 16:03:54 +02:00
|
|
|
err = st.Add("inky", "pinky", 0)
|
2023-03-31 13:56:11 +02:00
|
|
|
if err != nil {
|
|
|
|
t.Error(err)
|
|
|
|
}
|
2023-03-31 16:03:54 +02:00
|
|
|
err = st.Add("blinky", "clyde", 0)
|
2023-03-31 13:56:11 +02:00
|
|
|
if err == nil {
|
|
|
|
t.Errorf("expected capacity error")
|
|
|
|
}
|
2023-03-31 11:59:55 +02:00
|
|
|
}
|
2023-03-31 14:06:59 +02:00
|
|
|
|
2023-03-31 16:03:54 +02:00
|
|
|
func TestStateDownUp(t *testing.T) {
|
2023-03-31 14:06:59 +02:00
|
|
|
st := NewState(17)
|
2023-03-31 16:03:54 +02:00
|
|
|
st.Down("one")
|
2023-04-08 09:14:14 +02:00
|
|
|
st.Down("two")
|
2023-03-31 16:03:54 +02:00
|
|
|
err := st.Add("foo", "bar", 0)
|
2023-03-31 14:06:59 +02:00
|
|
|
if err != nil {
|
|
|
|
t.Error(err)
|
|
|
|
}
|
2023-03-31 16:03:54 +02:00
|
|
|
err = st.Add("baz", "xyzzy", 0)
|
2023-03-31 14:06:59 +02:00
|
|
|
if err != nil {
|
|
|
|
t.Error(err)
|
|
|
|
}
|
|
|
|
if st.CacheUseSize != 8 {
|
|
|
|
t.Errorf("expected cache use size 8 got %v", st.CacheUseSize)
|
|
|
|
}
|
2023-04-08 09:14:14 +02:00
|
|
|
s, err := st.Up()
|
2023-03-31 14:06:59 +02:00
|
|
|
if err != nil {
|
|
|
|
t.Error(err)
|
|
|
|
}
|
2023-04-08 09:14:14 +02:00
|
|
|
if s != "one" {
|
|
|
|
t.Errorf("expected sym 'one', got '%s'", s)
|
|
|
|
}
|
|
|
|
s, err = st.Up()
|
2023-03-31 16:24:29 +02:00
|
|
|
if err != nil {
|
|
|
|
t.Error(err)
|
|
|
|
}
|
2023-04-08 09:14:14 +02:00
|
|
|
if s != "" {
|
|
|
|
t.Errorf("expected sym '', got '%s'", s)
|
|
|
|
}
|
|
|
|
s, err = st.Up()
|
2023-03-31 14:06:59 +02:00
|
|
|
if err == nil {
|
|
|
|
t.Errorf("expected out of top frame error")
|
|
|
|
}
|
|
|
|
}
|
2023-03-31 15:04:08 +02:00
|
|
|
|
|
|
|
func TestStateReset(t *testing.T) {
|
|
|
|
st := NewState(17)
|
2023-03-31 16:03:54 +02:00
|
|
|
st.Down("one")
|
|
|
|
err := st.Add("foo", "bar", 0)
|
2023-03-31 15:04:08 +02:00
|
|
|
if err != nil {
|
|
|
|
t.Error(err)
|
|
|
|
}
|
2023-03-31 16:03:54 +02:00
|
|
|
err = st.Add("baz", "xyzzy", 0)
|
2023-03-31 15:04:08 +02:00
|
|
|
if err != nil {
|
|
|
|
t.Error(err)
|
|
|
|
}
|
2023-03-31 16:03:54 +02:00
|
|
|
st.Down("two")
|
|
|
|
st.Down("three")
|
2023-03-31 15:04:08 +02:00
|
|
|
st.Reset()
|
|
|
|
if st.CacheUseSize != 0 {
|
|
|
|
t.Errorf("expected cache use size 0, got %v", st.CacheUseSize)
|
|
|
|
}
|
|
|
|
if st.Depth() != 1 {
|
|
|
|
t.Errorf("expected depth 1, got %v", st.Depth())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestStateLoadDup(t *testing.T) {
|
|
|
|
st := NewState(17)
|
2023-03-31 16:03:54 +02:00
|
|
|
st.Down("one")
|
|
|
|
err := st.Add("foo", "bar", 0)
|
2023-03-31 15:04:08 +02:00
|
|
|
if err != nil {
|
|
|
|
t.Error(err)
|
|
|
|
}
|
2023-03-31 16:03:54 +02:00
|
|
|
st.Down("two")
|
|
|
|
err = st.Add("foo", "baz", 0)
|
2023-03-31 15:04:08 +02:00
|
|
|
if err == nil {
|
|
|
|
t.Errorf("expected fail on duplicate load")
|
|
|
|
}
|
2023-04-03 08:34:09 +02:00
|
|
|
st.Up()
|
|
|
|
err = st.Add("foo", "xyzzy", 0)
|
|
|
|
if err != nil {
|
|
|
|
t.Error(err)
|
|
|
|
}
|
2023-03-31 15:04:08 +02:00
|
|
|
}
|
2023-03-31 21:42:13 +02:00
|
|
|
|
|
|
|
func TestStateCurrentSize(t *testing.T) {
|
|
|
|
st := NewState(17)
|
|
|
|
st.Down("one")
|
|
|
|
err := st.Add("foo", "bar", 0)
|
|
|
|
if err != nil {
|
|
|
|
t.Error(err)
|
|
|
|
}
|
|
|
|
st.Down("two")
|
|
|
|
err = st.Add("bar", "xyzzy", 10)
|
|
|
|
if err != nil {
|
|
|
|
t.Error(err)
|
|
|
|
}
|
|
|
|
err = st.Map("bar")
|
|
|
|
if err != nil {
|
|
|
|
t.Error(err)
|
|
|
|
}
|
2023-03-31 22:08:06 +02:00
|
|
|
err = st.Add("baz", "inkypinkyblinkyclyde", 51)
|
2023-03-31 21:42:13 +02:00
|
|
|
if err != nil {
|
|
|
|
t.Error(err)
|
|
|
|
}
|
|
|
|
err = st.Map("baz")
|
|
|
|
if err != nil {
|
|
|
|
t.Error(err)
|
|
|
|
}
|
|
|
|
l, c := st.Size()
|
|
|
|
if l != 25 {
|
|
|
|
t.Errorf("expected actual length 25, got %v", l)
|
|
|
|
}
|
2023-03-31 22:08:06 +02:00
|
|
|
if c != 36 {
|
2023-03-31 21:42:13 +02:00
|
|
|
t.Errorf("expected actual length 50, got %v", c)
|
|
|
|
}
|
|
|
|
}
|
2023-03-31 22:08:06 +02:00
|
|
|
|
|
|
|
func TestStateMapSink(t *testing.T) {
|
|
|
|
st := NewState(17)
|
|
|
|
st.Down("one")
|
|
|
|
err := st.Add("foo", "bar", 0)
|
|
|
|
if err != nil {
|
|
|
|
t.Error(err)
|
|
|
|
}
|
|
|
|
st.Down("two")
|
|
|
|
err = st.Add("bar", "xyzzy", 6)
|
|
|
|
if err != nil {
|
|
|
|
t.Error(err)
|
|
|
|
}
|
|
|
|
err = st.Add("baz", "bazbaz", 18)
|
|
|
|
if err != nil {
|
|
|
|
t.Error(err)
|
|
|
|
}
|
|
|
|
err = st.Add("xyzzy", "plugh", 0)
|
|
|
|
if err != nil {
|
|
|
|
t.Error(err)
|
|
|
|
}
|
|
|
|
err = st.Map("foo")
|
|
|
|
if err != nil {
|
|
|
|
t.Error(err)
|
|
|
|
}
|
|
|
|
err = st.Map("xyzzy")
|
|
|
|
if err == nil {
|
|
|
|
t.Errorf("Expected fail on duplicate sink")
|
|
|
|
}
|
|
|
|
err = st.Map("baz")
|
|
|
|
if err != nil {
|
|
|
|
t.Error(err)
|
|
|
|
}
|
|
|
|
st.Down("three")
|
|
|
|
err = st.Map("foo")
|
|
|
|
if err != nil {
|
|
|
|
t.Error(err)
|
|
|
|
}
|
|
|
|
st.Up()
|
|
|
|
err = st.Map("foo")
|
|
|
|
if err != nil {
|
|
|
|
t.Error(err)
|
|
|
|
}
|
|
|
|
}
|