1 package goja
2
3 import (
4 "hash/maphash"
5 "math"
6 "strconv"
7 "testing"
8 )
9
10 func testMapHashVal(v1, v2 Value, expected bool, t *testing.T) {
11 var h maphash.Hash
12 actual := v1.hash(&h) == v2.hash(&h)
13 if actual != expected {
14 t.Fatalf("testMapHashVal failed for %v, %v", v1, v2)
15 }
16 }
17
18 func TestMapHash(t *testing.T) {
19 testMapHashVal(_NaN, _NaN, true, t)
20 testMapHashVal(valueTrue, valueFalse, false, t)
21 testMapHashVal(valueTrue, valueTrue, true, t)
22 testMapHashVal(intToValue(0), _negativeZero, true, t)
23 testMapHashVal(asciiString("Test"), asciiString("Test"), true, t)
24 testMapHashVal(newStringValue("Тест"), newStringValue("Тест"), true, t)
25 testMapHashVal(floatToValue(1.2345), floatToValue(1.2345), true, t)
26 testMapHashVal(SymIterator, SymToStringTag, false, t)
27 testMapHashVal(SymIterator, SymIterator, true, t)
28
29
30
31
32
33 }
34
35 func TestOrderedMap(t *testing.T) {
36 m := newOrderedMap(&maphash.Hash{})
37 for i := int64(0); i < 50; i++ {
38 m.set(intToValue(i), asciiString(strconv.FormatInt(i, 10)))
39 }
40 if m.size != 50 {
41 t.Fatalf("Unexpected size: %d", m.size)
42 }
43
44 for i := int64(0); i < 50; i++ {
45 expected := asciiString(strconv.FormatInt(i, 10))
46 actual := m.get(intToValue(i))
47 if !expected.SameAs(actual) {
48 t.Fatalf("Wrong value for %d", i)
49 }
50 }
51
52 for i := int64(0); i < 50; i += 2 {
53 if !m.remove(intToValue(i)) {
54 t.Fatalf("remove(%d) return false", i)
55 }
56 }
57 if m.size != 25 {
58 t.Fatalf("Unexpected size: %d", m.size)
59 }
60
61 iter := m.newIter()
62 count := 0
63 for {
64 entry := iter.next()
65 if entry == nil {
66 break
67 }
68 m.remove(entry.key)
69 count++
70 }
71
72 if count != 25 {
73 t.Fatalf("Unexpected iter count: %d", count)
74 }
75
76 if m.size != 0 {
77 t.Fatalf("Unexpected size: %d", m.size)
78 }
79 }
80
81 func TestOrderedMapCollision(t *testing.T) {
82 m := newOrderedMap(&maphash.Hash{})
83 n1 := uint64(123456789)
84 n2 := math.Float64frombits(n1)
85 n1Key := intToValue(int64(n1))
86 n2Key := floatToValue(n2)
87 m.set(n1Key, asciiString("n1"))
88 m.set(n2Key, asciiString("n2"))
89 if m.size == len(m.hashTable) {
90 t.Fatal("Expected a collision but there wasn't one")
91 }
92 if n2Val := m.get(n2Key); !asciiString("n2").SameAs(n2Val) {
93 t.Fatalf("unexpected n2Val: %v", n2Val)
94 }
95 if n1Val := m.get(n1Key); !asciiString("n1").SameAs(n1Val) {
96 t.Fatalf("unexpected nVal: %v", n1Val)
97 }
98
99 if !m.remove(n1Key) {
100 t.Fatal("removing n1Key returned false")
101 }
102 if n2Val := m.get(n2Key); !asciiString("n2").SameAs(n2Val) {
103 t.Fatalf("2: unexpected n2Val: %v", n2Val)
104 }
105 }
106
107 func TestOrderedMapIter(t *testing.T) {
108 m := newOrderedMap(&maphash.Hash{})
109 iter := m.newIter()
110 ent := iter.next()
111 if ent != nil {
112 t.Fatal("entry should be nil")
113 }
114 iter1 := m.newIter()
115 m.set(intToValue(1), valueTrue)
116 ent = iter.next()
117 if ent != nil {
118 t.Fatal("2: entry should be nil")
119 }
120 ent = iter1.next()
121 if ent == nil {
122 t.Fatal("entry is nil")
123 }
124 if !intToValue(1).SameAs(ent.key) {
125 t.Fatal("unexpected key")
126 }
127 if !valueTrue.SameAs(ent.value) {
128 t.Fatal("unexpected value")
129 }
130 }
131
132 func TestOrderedMapIterVisitAfterReAdd(t *testing.T) {
133 m := newOrderedMap(&maphash.Hash{})
134 one := intToValue(1)
135 two := intToValue(2)
136
137 m.set(one, valueTrue)
138 m.set(two, valueTrue)
139 iter := m.newIter()
140 entry := iter.next()
141 if !one.SameAs(entry.key) {
142 t.Fatalf("1: unexpected key: %v", entry.key)
143 }
144 if !m.remove(one) {
145 t.Fatal("remove returned false")
146 }
147 entry = iter.next()
148 if !two.SameAs(entry.key) {
149 t.Fatalf("2: unexpected key: %v", entry.key)
150 }
151 m.set(one, valueTrue)
152 entry = iter.next()
153 if entry == nil {
154 t.Fatal("entry is nil")
155 }
156 if !one.SameAs(entry.key) {
157 t.Fatalf("3: unexpected key: %v", entry.key)
158 }
159 }
160
161 func TestOrderedMapIterAddAfterClear(t *testing.T) {
162 m := newOrderedMap(&maphash.Hash{})
163 one := intToValue(1)
164 m.set(one, valueTrue)
165 iter := m.newIter()
166 iter.next()
167 m.clear()
168 m.set(one, valueTrue)
169 entry := iter.next()
170 if entry == nil {
171 t.Fatal("entry is nil")
172 }
173 if entry.key != one {
174 t.Fatalf("unexpected key: %v", entry.key)
175 }
176 entry = iter.next()
177 if entry != nil {
178 t.Fatalf("entry is not nil: %v", entry)
179 }
180 }
181
182 func TestOrderedMapIterDeleteCurrent(t *testing.T) {
183 m := newOrderedMap(&maphash.Hash{})
184 one := intToValue(1)
185 two := intToValue(2)
186 iter := m.newIter()
187 m.set(one, valueTrue)
188 m.set(two, valueTrue)
189 entry := iter.next()
190 if entry.key != one {
191 t.Fatalf("unexpected key: %v", entry.key)
192 }
193 m.remove(one)
194 entry = iter.next()
195 if entry.key != two {
196 t.Fatalf("2: unexpected key: %v", entry.key)
197 }
198 }
199
View as plain text