1 package goja
2
3 import (
4 "fmt"
5 "hash/maphash"
6 "testing"
7 )
8
9 func TestMapEvilIterator(t *testing.T) {
10 const SCRIPT = `
11 'use strict';
12 var o = {};
13
14 function Iter(value) {
15 this.value = value;
16 this.idx = 0;
17 }
18
19 Iter.prototype.next = function() {
20 var idx = this.idx;
21 if (idx === 0) {
22 this.idx++;
23 return this.value;
24 }
25 return {done: true};
26 }
27
28 o[Symbol.iterator] = function() {
29 return new Iter({});
30 }
31
32 assert.throws(TypeError, function() {
33 new Map(o);
34 });
35
36 o[Symbol.iterator] = function() {
37 return new Iter({value: []});
38 }
39
40 function t(prefix) {
41 var m = new Map(o);
42 assert.sameValue(1, m.size, prefix+": m.size");
43 assert.sameValue(true, m.has(undefined), prefix+": m.has(undefined)");
44 assert.sameValue(undefined, m.get(undefined), prefix+": m.get(undefined)");
45 }
46
47 t("standard adder");
48
49 var count = 0;
50 var origSet = Map.prototype.set;
51
52 Map.prototype.set = function() {
53 count++;
54 origSet.apply(this, arguments);
55 }
56
57 t("custom adder");
58 assert.sameValue(1, count, "count");
59
60 undefined;
61 `
62 testScriptWithTestLib(SCRIPT, _undefined, t)
63 }
64
65 func TestMapExportToNilMap(t *testing.T) {
66 vm := New()
67 var m map[int]interface{}
68 res, err := vm.RunString("new Map([[1, true]])")
69 if err != nil {
70 t.Fatal(err)
71 }
72 err = vm.ExportTo(res, &m)
73 if err != nil {
74 t.Fatal(err)
75 }
76 if len(m) != 1 {
77 t.Fatal(m)
78 }
79 if _, exists := m[1]; !exists {
80 t.Fatal(m)
81 }
82 }
83
84 func TestMapExportToNonNilMap(t *testing.T) {
85 vm := New()
86 m := map[int]interface{}{
87 2: true,
88 }
89 res, err := vm.RunString("new Map([[1, true]])")
90 if err != nil {
91 t.Fatal(err)
92 }
93 err = vm.ExportTo(res, &m)
94 if err != nil {
95 t.Fatal(err)
96 }
97 if len(m) != 1 {
98 t.Fatal(m)
99 }
100 if _, exists := m[1]; !exists {
101 t.Fatal(m)
102 }
103 }
104
105 func TestMapGetAdderGetIteratorOrder(t *testing.T) {
106 const SCRIPT = `
107 let getterCalled = 0;
108
109 class M extends Map {
110 get set() {
111 getterCalled++;
112 return null;
113 }
114 }
115
116 let getIteratorCalled = 0;
117
118 let iterable = {};
119 iterable[Symbol.iterator] = () => {
120 getIteratorCalled++
121 return {
122 next: 1
123 };
124 }
125
126 let thrown = false;
127
128 try {
129 new M(iterable);
130 } catch (e) {
131 if (e instanceof TypeError) {
132 thrown = true;
133 } else {
134 throw e;
135 }
136 }
137
138 thrown && getterCalled === 1 && getIteratorCalled === 0;
139 `
140 testScript(SCRIPT, valueTrue, t)
141 }
142
143 func ExampleObject_Export_map() {
144 vm := New()
145 m, err := vm.RunString(`
146 new Map([[1, true], [2, false]]);
147 `)
148 if err != nil {
149 panic(err)
150 }
151 exp := m.Export()
152 fmt.Printf("%T, %v\n", exp, exp)
153
154 }
155
156 func ExampleRuntime_ExportTo_mapToMap() {
157 vm := New()
158 m, err := vm.RunString(`
159 new Map([[1, true], [2, false]]);
160 `)
161 if err != nil {
162 panic(err)
163 }
164 exp := make(map[int]bool)
165 err = vm.ExportTo(m, &exp)
166 if err != nil {
167 panic(err)
168 }
169 fmt.Println(exp)
170
171 }
172
173 func ExampleRuntime_ExportTo_mapToSlice() {
174 vm := New()
175 m, err := vm.RunString(`
176 new Map([[1, true], [2, false]]);
177 `)
178 if err != nil {
179 panic(err)
180 }
181 exp := make([][]interface{}, 0)
182 err = vm.ExportTo(m, &exp)
183 if err != nil {
184 panic(err)
185 }
186 fmt.Println(exp)
187
188 }
189
190 func ExampleRuntime_ExportTo_mapToTypedSlice() {
191 vm := New()
192 m, err := vm.RunString(`
193 new Map([[1, true], [2, false]]);
194 `)
195 if err != nil {
196 panic(err)
197 }
198 exp := make([][2]interface{}, 0)
199 err = vm.ExportTo(m, &exp)
200 if err != nil {
201 panic(err)
202 }
203 fmt.Println(exp)
204
205 }
206
207 func BenchmarkMapDelete(b *testing.B) {
208 var key1 Value = asciiString("a")
209 var key2 Value = asciiString("b")
210 one := intToValue(1)
211 two := intToValue(2)
212 for i := 0; i < b.N; i++ {
213 m := newOrderedMap(&maphash.Hash{})
214 m.set(key1, one)
215 m.set(key2, two)
216 if !m.remove(key1) {
217 b.Fatal("remove() returned false")
218 }
219 }
220 }
221
222 func BenchmarkMapDeleteJS(b *testing.B) {
223 prg, err := Compile("test.js", `
224 var m = new Map([['a',1], ['b', 2]]);
225
226 var result = m.delete('a');
227
228 if (!result || m.size !== 1) {
229 throw new Error("Fail!");
230 }
231 `,
232 false)
233 if err != nil {
234 b.Fatal(err)
235 }
236 b.ResetTimer()
237 for i := 0; i < b.N; i++ {
238 vm := New()
239 _, err := vm.RunProgram(prg)
240 if err != nil {
241 b.Fatal(err)
242 }
243 }
244 }
245
View as plain text