github.com/nuvolaris/goja@v0.0.0-20230825100449-967811910c6d/builtin_map_test.go (about) 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 // Output: [][2]interface {}, [[1 true] [2 false]] 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 // Output: map[1:true 2:false] 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 // Output: [[1 true] [2 false]] 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 // Output: [[1 true] [2 false]] 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 }