go.ketch.com/lib/goja@v0.0.1/typedarrays_test.go (about) 1 package goja 2 3 import "testing" 4 5 func TestUint16ArrayObject(t *testing.T) { 6 vm := New() 7 buf := vm._newArrayBuffer(vm.global.ArrayBufferPrototype, nil) 8 buf.data = make([]byte, 16) 9 if nativeEndian == littleEndian { 10 buf.data[2] = 0xFE 11 buf.data[3] = 0xCA 12 } else { 13 buf.data[2] = 0xCA 14 buf.data[3] = 0xFE 15 } 16 a := vm.newUint16ArrayObject(buf, 1, 1, nil) 17 v := a.getIdx(valueInt(0), nil) 18 if v != valueInt(0xCAFE) { 19 t.Fatalf("v: %v", v) 20 } 21 } 22 23 func TestArrayBufferGoWrapper(t *testing.T) { 24 vm := New() 25 data := []byte{0xAA, 0xBB} 26 buf := vm.NewArrayBuffer(data) 27 vm.Set("buf", buf) 28 _, err := vm.RunString(` 29 var a = new Uint8Array(buf); 30 if (a.length !== 2 || a[0] !== 0xAA || a[1] !== 0xBB) { 31 throw new Error(a); 32 } 33 `) 34 if err != nil { 35 t.Fatal(err) 36 } 37 ret, err := vm.RunString(` 38 var b = Uint8Array.of(0xCC, 0xDD); 39 b.buffer; 40 `) 41 if err != nil { 42 t.Fatal(err) 43 } 44 buf1 := ret.Export().(ArrayBuffer) 45 data1 := buf1.Bytes() 46 if len(data1) != 2 || data1[0] != 0xCC || data1[1] != 0xDD { 47 t.Fatal(data1) 48 } 49 if buf1.Detached() { 50 t.Fatal("buf1.Detached() returned true") 51 } 52 if !buf1.Detach() { 53 t.Fatal("buf1.Detach() returned false") 54 } 55 if !buf1.Detached() { 56 t.Fatal("buf1.Detached() returned false") 57 } 58 _, err = vm.RunString(` 59 if (b[0] !== undefined) { 60 throw new Error("b[0] !== undefined"); 61 } 62 `) 63 if err != nil { 64 t.Fatal(err) 65 } 66 } 67 68 func TestTypedArrayIdx(t *testing.T) { 69 const SCRIPT = ` 70 var a = new Uint8Array(1); 71 72 // 32-bit integer overflow, should not panic on 32-bit architectures 73 if (a[4294967297] !== undefined) { 74 throw new Error("4294967297"); 75 } 76 77 // Canonical non-integer 78 a["Infinity"] = 8; 79 if (a["Infinity"] !== undefined) { 80 throw new Error("Infinity"); 81 } 82 a["NaN"] = 1; 83 if (a["NaN"] !== undefined) { 84 throw new Error("NaN"); 85 } 86 87 // Non-canonical integer 88 a["00"] = "00"; 89 if (a["00"] !== "00") { 90 throw new Error("00"); 91 } 92 93 // Non-canonical non-integer 94 a["1e-3"] = "1e-3"; 95 if (a["1e-3"] !== "1e-3") { 96 throw new Error("1e-3"); 97 } 98 if (a["0.001"] !== undefined) { 99 throw new Error("0.001"); 100 } 101 102 // Negative zero 103 a["-0"] = 88; 104 if (a["-0"] !== undefined) { 105 throw new Error("-0"); 106 } 107 108 if (a[0] !== 0) { 109 throw new Error("0"); 110 } 111 112 a["9007199254740992"] = 1; 113 if (a["9007199254740992"] !== undefined) { 114 throw new Error("9007199254740992"); 115 } 116 a["-9007199254740992"] = 1; 117 if (a["-9007199254740992"] !== undefined) { 118 throw new Error("-9007199254740992"); 119 } 120 121 // Safe integer overflow, not canonical (Number("9007199254740993") === 9007199254740992) 122 a["9007199254740993"] = 1; 123 if (a["9007199254740993"] !== 1) { 124 throw new Error("9007199254740993"); 125 } 126 a["-9007199254740993"] = 1; 127 if (a["-9007199254740993"] !== 1) { 128 throw new Error("-9007199254740993"); 129 } 130 131 // Safe integer overflow, canonical Number("9007199254740994") == 9007199254740994 132 a["9007199254740994"] = 1; 133 if (a["9007199254740994"] !== undefined) { 134 throw new Error("9007199254740994"); 135 } 136 a["-9007199254740994"] = 1; 137 if (a["-9007199254740994"] !== undefined) { 138 throw new Error("-9007199254740994"); 139 } 140 ` 141 142 testScript(SCRIPT, _undefined, t) 143 } 144 145 func TestTypedArraySetDetachedBuffer(t *testing.T) { 146 const SCRIPT = ` 147 let sample = new Uint8Array([42]); 148 $DETACHBUFFER(sample.buffer); 149 sample[0] = 1; 150 151 assert.sameValue(sample[0], undefined, 'sample[0] = 1 is undefined'); 152 sample['1.1'] = 1; 153 assert.sameValue(sample['1.1'], undefined, 'sample[\'1.1\'] = 1 is undefined'); 154 sample['-0'] = 1; 155 assert.sameValue(sample['-0'], undefined, 'sample[\'-0\'] = 1 is undefined'); 156 sample['-1'] = 1; 157 assert.sameValue(sample['-1'], undefined, 'sample[\'-1\'] = 1 is undefined'); 158 sample['1'] = 1; 159 assert.sameValue(sample['1'], undefined, 'sample[\'1\'] = 1 is undefined'); 160 sample['2'] = 1; 161 assert.sameValue(sample['2'], undefined, 'sample[\'2\'] = 1 is undefined'); 162 ` 163 vm := New() 164 vm.Set("$DETACHBUFFER", func(buf *ArrayBuffer) { 165 buf.Detach() 166 }) 167 vm.testScriptWithTestLib(SCRIPT, _undefined, t) 168 } 169 170 func TestTypedArrayDefinePropDetachedBuffer(t *testing.T) { 171 const SCRIPT = ` 172 var desc = { 173 value: 0, 174 configurable: false, 175 enumerable: true, 176 writable: true 177 }; 178 179 var obj = { 180 valueOf: function() { 181 throw new Error("valueOf() was called"); 182 } 183 }; 184 let sample = new Uint8Array(42); 185 $DETACHBUFFER(sample.buffer); 186 187 assert.sameValue( 188 Reflect.defineProperty(sample, "0", desc), 189 false, 190 'Reflect.defineProperty(sample, "0", {value: 0, configurable: false, enumerable: true, writable: true} ) must return false' 191 ); 192 193 assert.sameValue( 194 Reflect.defineProperty(sample, "-1", desc), 195 false, 196 'Reflect.defineProperty(sample, "-1", {value: 0, configurable: false, enumerable: true, writable: true} ) must return false' 197 ); 198 199 assert.sameValue( 200 Reflect.defineProperty(sample, "1.1", desc), 201 false, 202 'Reflect.defineProperty(sample, "1.1", {value: 0, configurable: false, enumerable: true, writable: true} ) must return false' 203 ); 204 205 assert.sameValue( 206 Reflect.defineProperty(sample, "-0", desc), 207 false, 208 'Reflect.defineProperty(sample, "-0", {value: 0, configurable: false, enumerable: true, writable: true} ) must return false' 209 ); 210 211 assert.sameValue( 212 Reflect.defineProperty(sample, "2", { 213 configurable: true, 214 enumerable: true, 215 writable: true, 216 value: obj 217 }), 218 false, 219 'Reflect.defineProperty(sample, "2", {configurable: true, enumerable: true, writable: true, value: obj}) must return false' 220 ); 221 222 assert.sameValue( 223 Reflect.defineProperty(sample, "3", { 224 configurable: false, 225 enumerable: false, 226 writable: true, 227 value: obj 228 }), 229 false, 230 'Reflect.defineProperty(sample, "3", {configurable: false, enumerable: false, writable: true, value: obj}) must return false' 231 ); 232 233 assert.sameValue( 234 Reflect.defineProperty(sample, "4", { 235 writable: false, 236 configurable: false, 237 enumerable: true, 238 value: obj 239 }), 240 false, 241 'Reflect.defineProperty("new TA(42)", "4", {writable: false, configurable: false, enumerable: true, value: obj}) must return false' 242 ); 243 244 assert.sameValue( 245 Reflect.defineProperty(sample, "42", desc), 246 false, 247 'Reflect.defineProperty(sample, "42", {value: 0, configurable: false, enumerable: true, writable: true} ) must return false' 248 ); 249 250 assert.sameValue( 251 Reflect.defineProperty(sample, "43", desc), 252 false, 253 'Reflect.defineProperty(sample, "43", {value: 0, configurable: false, enumerable: true, writable: true} ) must return false' 254 ); 255 256 assert.sameValue( 257 Reflect.defineProperty(sample, "5", { 258 get: function() {} 259 }), 260 false, 261 'Reflect.defineProperty(sample, "5", {get: function() {}}) must return false' 262 ); 263 264 assert.sameValue( 265 Reflect.defineProperty(sample, "6", { 266 configurable: false, 267 enumerable: true, 268 writable: true 269 }), 270 false, 271 'Reflect.defineProperty(sample, "6", {configurable: false, enumerable: true, writable: true}) must return false' 272 ); 273 ` 274 vm := New() 275 vm.Set("$DETACHBUFFER", func(buf *ArrayBuffer) { 276 buf.Detach() 277 }) 278 vm.testScriptWithTestLib(SCRIPT, _undefined, t) 279 } 280 281 func TestTypedArrayDefineProperty(t *testing.T) { 282 const SCRIPT = ` 283 var a = new Uint8Array(1); 284 285 assert.throws(TypeError, function() { 286 Object.defineProperty(a, "1", {value: 1}); 287 }); 288 assert.sameValue(Reflect.defineProperty(a, "1", {value: 1}), false, "1"); 289 290 assert.throws(TypeError, function() { 291 Object.defineProperty(a, "Infinity", {value: 8}); 292 }); 293 assert.sameValue(Reflect.defineProperty(a, "Infinity", {value: 8}), false, "Infinity"); 294 295 Object.defineProperty(a, "test", {value: "passed"}); 296 assert.sameValue(a.test, "passed", "string property"); 297 298 assert.throws(TypeError, function() { 299 Object.defineProperty(a, "0", {value: 1, writable: false}); 300 }, "define non-writable"); 301 302 assert.throws(TypeError, function() { 303 Object.defineProperty(a, "0", {get() { return 1; }}); 304 }, "define accessor"); 305 306 var sample = new Uint8Array([42, 42]); 307 308 assert.sameValue( 309 Reflect.defineProperty(sample, "0", { 310 value: 8, 311 configurable: true, 312 enumerable: true, 313 writable: true 314 }), 315 true 316 ); 317 318 assert.sameValue(sample[0], 8, "property value was set"); 319 let descriptor0 = Object.getOwnPropertyDescriptor(sample, "0"); 320 assert.sameValue(descriptor0.value, 8); 321 assert.sameValue(descriptor0.configurable, true, "configurable"); 322 assert.sameValue(descriptor0.enumerable, true); 323 assert.sameValue(descriptor0.writable, true); 324 ` 325 testScriptWithTestLib(SCRIPT, _undefined, t) 326 } 327 328 func TestTypedArrayGetInvalidIndex(t *testing.T) { 329 const SCRIPT = ` 330 var TypedArray = Object.getPrototypeOf(Int8Array); 331 var proto = TypedArray.prototype; 332 Object.defineProperty(proto, "1", { 333 get: function() { 334 throw new Error("OrdinaryGet was called!"); 335 } 336 }); 337 var a = new Uint8Array(1); 338 assert.sameValue(a[1], undefined); 339 assert.sameValue(a["1"], undefined); 340 ` 341 testScriptWithTestLib(SCRIPT, _undefined, t) 342 }