Skip to content Search Apps Documentation Source Content File Folder Download Copy Actions State String Boolean Number Struct Map Slice Pointer Function Closure Reference Nil Package Type Interface Unknown

Community realm. Read the code first. Community realm, deployed by its author. Read the code before you interact or send coins.

orderedmap_test.gno

3.30 Kb · 147 lines
  1package orderedmap
  2
  3import (
  4	"strings"
  5	"testing"
  6
  7	"gno.land/p/nt/uassert/v0"
  8)
  9
 10func TestSetGetOrder(t *testing.T) {
 11	o := New()
 12	o.Set("z", "1")
 13	o.Set("a", "2")
 14	o.Set("m", "3")
 15	uassert.Equal(t, "z,a,m", strings.Join(o.Keys(), ","))   // insertion, not sorted
 16	uassert.Equal(t, "1,2,3", strings.Join(o.Values(), ",")) // values follow keys
 17	v, ok := o.Get("a")
 18	uassert.True(t, ok)
 19	uassert.Equal(t, "2", v)
 20	uassert.Equal(t, 3, o.Len())
 21}
 22
 23// Insertion order means FIRST insertion: updating must not move a key.
 24func TestUpdateKeepsPosition(t *testing.T) {
 25	o := New()
 26	o.Set("a", "1")
 27	o.Set("b", "2")
 28	o.Set("a", "99")
 29	uassert.Equal(t, "a,b", strings.Join(o.Keys(), ","))
 30	v, _ := o.Get("a")
 31	uassert.Equal(t, "99", v)
 32	uassert.Equal(t, 2, o.Len())
 33}
 34
 35func TestDeletePreservesOrder(t *testing.T) {
 36	o := New()
 37	for _, k := range []string{"a", "b", "c", "d"} {
 38		o.Set(k, k)
 39	}
 40	uassert.True(t, o.Delete("b"))
 41	uassert.Equal(t, "a,c,d", strings.Join(o.Keys(), ","))
 42	uassert.False(t, o.Has("b"))
 43	uassert.False(t, o.Delete("b")) // already gone
 44	uassert.Equal(t, 3, o.Len())
 45}
 46
 47// Re-inserting after a delete appends at the END — it is a new insertion.
 48func TestReinsertAfterDeleteGoesLast(t *testing.T) {
 49	o := New()
 50	for _, k := range []string{"a", "b", "c"} {
 51		o.Set(k, k)
 52	}
 53	o.Delete("a")
 54	o.Set("a", "again")
 55	uassert.Equal(t, "b,c,a", strings.Join(o.Keys(), ","))
 56}
 57
 58func TestMissingKey(t *testing.T) {
 59	o := New()
 60	v, ok := o.Get("nope")
 61	uassert.False(t, ok)
 62	uassert.Equal(t, "", v)
 63	uassert.False(t, o.Has("nope"))
 64}
 65
 66func TestAt(t *testing.T) {
 67	o := New()
 68	o.Set("x", "1")
 69	o.Set("y", "2")
 70	k, v, ok := o.At(1)
 71	uassert.True(t, ok)
 72	uassert.Equal(t, "y", k)
 73	uassert.Equal(t, "2", v)
 74	_, _, ok = o.At(2)
 75	uassert.False(t, ok)
 76	_, _, ok = o.At(-1)
 77	uassert.False(t, ok)
 78}
 79
 80func TestIterateStopsEarly(t *testing.T) {
 81	o := New()
 82	for _, k := range []string{"a", "b", "c"} {
 83		o.Set(k, k)
 84	}
 85	seen := []string{}
 86	o.Iterate(func(k, v string) bool {
 87		seen = append(seen, k)
 88		return k == "b" // stop after b
 89	})
 90	uassert.Equal(t, "a,b", strings.Join(seen, ","))
 91}
 92
 93// The whole point: the order is stable across identical builds, where a
 94// built-in map gives no such guarantee.
 95func TestOrderIsStable(t *testing.T) {
 96	build := func() string {
 97		o := New()
 98		for _, k := range []string{"delta", "alpha", "charlie", "bravo"} {
 99			o.Set(k, k)
100		}
101		return strings.Join(o.Keys(), ",")
102	}
103	first := build()
104	for i := 0; i < 20; i++ {
105		uassert.Equal(t, first, build())
106	}
107	uassert.Equal(t, "delta,alpha,charlie,bravo", first)
108}
109
110func TestKeysIsACopy(t *testing.T) {
111	o := New()
112	o.Set("a", "1")
113	ks := o.Keys()
114	ks[0] = "mutated"
115	uassert.Equal(t, "a", strings.Join(o.Keys(), ","))
116}
117
118func TestCloneIsIndependent(t *testing.T) {
119	o := New()
120	o.Set("a", "1")
121	c := o.Clone()
122	c.Set("b", "2")
123	uassert.Equal(t, "a", strings.Join(o.Keys(), ","))
124	uassert.Equal(t, "a,b", strings.Join(c.Keys(), ","))
125}
126
127func TestFullMapRejectsNewKeys(t *testing.T) {
128	o := New()
129	for i := 0; i < MaxKeys; i++ {
130		uassert.True(t, o.Set(itoa(i), "v"))
131	}
132	uassert.False(t, o.Set("overflow", "v")) // new key refused
133	uassert.True(t, o.Set("0", "updated"))   // existing key still updatable
134	uassert.Equal(t, MaxKeys, o.Len())
135}
136
137func itoa(i int) string {
138	if i == 0 {
139		return "0"
140	}
141	var b []byte
142	for i > 0 {
143		b = append([]byte{byte('0' + i%10)}, b...)
144		i /= 10
145	}
146	return string(b)
147}