github.com/nuvolaris/goja@v0.0.0-20230825100449-967811910c6d/object_gomap_reflect_test.go (about) 1 package goja 2 3 import ( 4 "testing" 5 ) 6 7 func TestGoMapReflectGetSet(t *testing.T) { 8 const SCRIPT = ` 9 m.c = m.a + m.b; 10 ` 11 12 vm := New() 13 m := map[string]string{ 14 "a": "4", 15 "b": "2", 16 } 17 vm.Set("m", m) 18 19 _, err := vm.RunString(SCRIPT) 20 if err != nil { 21 t.Fatal(err) 22 } 23 24 if c := m["c"]; c != "42" { 25 t.Fatalf("Unexpected value: '%s'", c) 26 } 27 } 28 29 func TestGoMapReflectIntKey(t *testing.T) { 30 const SCRIPT = ` 31 m[2] = m[0] + m[1]; 32 ` 33 34 vm := New() 35 m := map[int]int{ 36 0: 40, 37 1: 2, 38 } 39 vm.Set("m", m) 40 41 _, err := vm.RunString(SCRIPT) 42 if err != nil { 43 t.Fatal(err) 44 } 45 46 if c := m[2]; c != 42 { 47 t.Fatalf("Unexpected value: '%d'", c) 48 } 49 } 50 51 func TestGoMapReflectDelete(t *testing.T) { 52 const SCRIPT = ` 53 delete m.a; 54 ` 55 56 vm := New() 57 m := map[string]string{ 58 "a": "4", 59 "b": "2", 60 } 61 vm.Set("m", m) 62 63 _, err := vm.RunString(SCRIPT) 64 if err != nil { 65 t.Fatal(err) 66 } 67 68 if _, exists := m["a"]; exists { 69 t.Fatal("a still exists") 70 } 71 72 if b := m["b"]; b != "2" { 73 t.Fatalf("Unexpected b: '%s'", b) 74 } 75 } 76 77 func TestGoMapReflectJSON(t *testing.T) { 78 const SCRIPT = ` 79 function f(m) { 80 return JSON.stringify(m); 81 } 82 ` 83 84 vm := New() 85 m := map[string]string{ 86 "t": "42", 87 } 88 _, err := vm.RunString(SCRIPT) 89 if err != nil { 90 t.Fatal(err) 91 } 92 f := vm.Get("f") 93 if call, ok := AssertFunction(f); ok { 94 v, err := call(nil, ([]Value{vm.ToValue(m)})...) 95 if err != nil { 96 t.Fatal(err) 97 } 98 if !v.StrictEquals(asciiString(`{"t":"42"}`)) { 99 t.Fatalf("Unexpected value: %v", v) 100 } 101 } else { 102 t.Fatalf("Not a function: %v", f) 103 } 104 } 105 106 func TestGoMapReflectProto(t *testing.T) { 107 const SCRIPT = ` 108 m.hasOwnProperty("t"); 109 ` 110 111 vm := New() 112 m := map[string]string{ 113 "t": "42", 114 } 115 vm.Set("m", m) 116 v, err := vm.RunString(SCRIPT) 117 if err != nil { 118 t.Fatal(err) 119 } 120 if !v.StrictEquals(valueTrue) { 121 t.Fatalf("Expected true, got %v", v) 122 } 123 } 124 125 type gomapReflect_noMethods map[string]interface{} 126 type gomapReflect_withMethods map[string]interface{} 127 128 func (m gomapReflect_withMethods) Method() bool { 129 return true 130 } 131 132 func TestGoMapReflectNoMethods(t *testing.T) { 133 const SCRIPT = ` 134 typeof m === "object" && m.hasOwnProperty("t") && m.t === 42; 135 ` 136 137 vm := New() 138 m := make(gomapReflect_noMethods) 139 m["t"] = 42 140 vm.Set("m", m) 141 v, err := vm.RunString(SCRIPT) 142 if err != nil { 143 t.Fatal(err) 144 } 145 if !v.StrictEquals(valueTrue) { 146 t.Fatalf("Expected true, got %v", v) 147 } 148 149 } 150 151 func TestGoMapReflectWithMethods(t *testing.T) { 152 const SCRIPT = ` 153 typeof m === "object" && !m.hasOwnProperty("t") && m.hasOwnProperty("Method") && m.Method(); 154 ` 155 156 vm := New() 157 m := make(gomapReflect_withMethods) 158 m["t"] = 42 159 vm.Set("m", m) 160 v, err := vm.RunString(SCRIPT) 161 if err != nil { 162 t.Fatal(err) 163 } 164 if !v.StrictEquals(valueTrue) { 165 t.Fatalf("Expected true, got %v", v) 166 } 167 168 } 169 170 func TestGoMapReflectWithProto(t *testing.T) { 171 vm := New() 172 m := map[string]string{ 173 "t": "42", 174 } 175 vm.Set("m", m) 176 vm.testScriptWithTestLib(` 177 (function() { 178 'use strict'; 179 var proto = {}; 180 var getterAllowed = false; 181 var setterAllowed = false; 182 var tHolder = "proto t"; 183 Object.defineProperty(proto, "t", { 184 get: function() { 185 if (!getterAllowed) throw new Error("getter is called"); 186 return tHolder; 187 }, 188 set: function(v) { 189 if (!setterAllowed) throw new Error("setter is called"); 190 tHolder = v; 191 } 192 }); 193 var t1Holder; 194 Object.defineProperty(proto, "t1", { 195 get: function() { 196 return t1Holder; 197 }, 198 set: function(v) { 199 t1Holder = v; 200 } 201 }); 202 Object.setPrototypeOf(m, proto); 203 assert.sameValue(m.t, "42"); 204 m.t = 43; 205 assert.sameValue(m.t, "43"); 206 t1Holder = "test"; 207 assert.sameValue(m.t1, "test"); 208 m.t1 = "test1"; 209 assert.sameValue(m.t1, "test1"); 210 delete m.t; 211 getterAllowed = true; 212 assert.sameValue(m.t, "proto t", "after delete"); 213 setterAllowed = true; 214 m.t = true; 215 assert.sameValue(m.t, true, "m.t === true"); 216 assert.sameValue(tHolder, true, "tHolder === true"); 217 Object.preventExtensions(m); 218 assert.throws(TypeError, function() { 219 m.t2 = 1; 220 }); 221 m.t1 = "test2"; 222 assert.sameValue(m.t1, "test2"); 223 })(); 224 `, _undefined, t) 225 } 226 227 func TestGoMapReflectProtoProp(t *testing.T) { 228 const SCRIPT = ` 229 (function() { 230 "use strict"; 231 var proto = {}; 232 Object.defineProperty(proto, "ro", {value: 42}); 233 Object.setPrototypeOf(m, proto); 234 assert.throws(TypeError, function() { 235 m.ro = 43; 236 }); 237 Object.defineProperty(m, "ro", {value: 43}); 238 assert.sameValue(m.ro, "43"); 239 })(); 240 ` 241 242 r := New() 243 r.Set("m", map[string]string{}) 244 r.testScriptWithTestLib(SCRIPT, _undefined, t) 245 } 246 247 func TestGoMapReflectUnicode(t *testing.T) { 248 const SCRIPT = ` 249 Object.setPrototypeOf(m, s); 250 if (m.Тест !== "passed") { 251 throw new Error("m.Тест: " + m.Тест); 252 } 253 m["é"]; 254 ` 255 type S struct { 256 Тест string 257 } 258 vm := New() 259 m := map[string]int{ 260 "é": 42, 261 } 262 s := S{ 263 Тест: "passed", 264 } 265 vm.Set("m", m) 266 vm.Set("s", &s) 267 res, err := vm.RunString(SCRIPT) 268 if err != nil { 269 t.Fatal(err) 270 } 271 if res == nil || !res.StrictEquals(valueInt(42)) { 272 t.Fatalf("Unexpected value: %v", res) 273 } 274 } 275 276 func TestGoMapReflectStruct(t *testing.T) { 277 type S struct { 278 Test int 279 } 280 281 m := map[string]S{ 282 "1": {Test: 1}, 283 } 284 285 vm := New() 286 vm.Set("m", m) 287 res, err := vm.RunString("m[1].Test = 2; m[1].Test") 288 if err != nil { 289 t.Fatal(err) 290 } 291 if res.Export() != int64(1) { 292 t.Fatal(res) 293 } 294 } 295 296 func TestGoMapReflectElt(t *testing.T) { 297 type mapping map[string]interface{} 298 299 const SCRIPT = `a.s() && a.t === null && a.t1 === undefined;` 300 301 r := New() 302 303 r.Set("a", mapping{ 304 "s": func() bool { return true }, 305 "t": nil, 306 }) 307 308 r.testScript(SCRIPT, valueTrue, t) 309 }