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}