1/* 2 * Copyright (c) 2024 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16/* 17 * @tc.name:builtinsreflect 18 * @tc.desc:test builtins reflect 19 * @tc.type: FUNC 20 * @tc.require: issueI8SXHD 21 */ 22print("builtins reflect start"); 23 24// test1 -- reflect set length 25var y = []; 26Object.defineProperty(y, 1, { value: 42, configurable: false }); 27var tag1 = Reflect.set(y, 'length', 0); 28var tag2 = Reflect.set(y, 'length', 5); 29print(tag1); 30print(tag2); 31 32const v0 = 102630708; 33let v55 = []; 34let v56 = Object.create(v55) 35Reflect.set(v56, "length", v0) 36Reflect.set(v55, "length", v0, v56) 37print("v56.length",v56.length) 38 39var global = this; 40var sym = Symbol("gaga"); 41var objects = [ 42 {}, 43 [], 44 function() {}, 45 function() { 46 return arguments; 47 }(), 48 Object(1), 49 Object(true), 50 Object('bla'), 51 new Date, 52 new RegExp, 53 new Set, 54 new Map, 55 new WeakMap, 56 new WeakSet, 57 new ArrayBuffer(10), 58 new Int32Array(5), 59 Object, 60 Function, 61 Date, 62 RegExp, 63 global 64]; 65 66function prepare(target) { 67 target["bla"] = true; 68 target[4] = 42; 69 target[sym] = "foo"; 70 target["noconf"] = 43; 71 Object.defineProperty(target, "noconf", 72 { configurable: false }); 73 Object.defineProperty(target, "nowrite", 74 { writable: false, configurable: true, value: 44 }); 75 Object.defineProperty(target, "getter", 76 { get: function () {return this.bla}, configurable: true }); 77 Object.defineProperty(target, "setter", 78 { set: function (x) {this.gaga = x}, configurable: true }); 79 Object.defineProperty(target, "setter2", 80 { set: function (x) {}, configurable: true }); 81} 82 83(function testReflectGetOnObject() { 84 let i = 0; 85 for (let target of objects) { 86 prepare(target); 87 if (true == Reflect.get(target, "bla") && 88 42 == Reflect.get(target, 4) && 89 42 == Reflect.get(target, "4") && 90 "foo" == Reflect.get(target, sym) && 91 43 == Reflect.get(target, "noconf") && 92 true == Reflect.get(target, "getter") && 93 undefined == Reflect.get(target, "setter") && 94 undefined == Reflect.get(target, "foo") && 95 undefined == Reflect.get(target, 333)) { 96 print(i + "success_1"); 97 } 98 let proto = target.__proto__; 99 target.__proto__ = { get foo() {return this.bla} }; 100 if (true == Reflect.get(target, "foo")) { 101 print(i + "success_2"); 102 } 103 target.__proto__ = proto; 104 i++; 105 } 106})(); 107let obj = {name:"tom"}; 108let pxobj = new Proxy(obj,{}); 109print(Reflect.get(pxobj,"name")) 110 111{ 112 try { 113 let arr=[1,2,3,4]; 114 arr.length=102600; 115 Reflect.set(arr,"length","aaa",arr); 116 } catch (error) { 117 print(error.name) 118 } 119 try { 120 let arr=[1,2,3,4]; 121 arr.length=102600; 122 Reflect.set(arr,"length","aaa"); 123 } catch (error) { 124 print(error.name) 125 } 126} 127 128// reflect set ir 129print("Reflect.set Ir test") 130{ 131 // special test 132 try { 133 Reflect.set(undefined,"fail","fail") 134 } catch (error) { 135 print("Reflect.set undefined test pass") 136 } 137 138 try { 139 Reflect.set(null,"fail","fail") 140 } catch (error) { 141 print("Reflect.set null test pass") 142 } 143 144 { 145 let arrKey = [1,2,3] 146 let testObj = {} 147 Reflect.set(testObj,arrKey,"key is array") 148 print(testObj[arrKey]) 149 } 150 151 { 152 let bigThenMaxKey = 2147483645; 153 let testObj = {} 154 Reflect.set(testObj,bigThenMaxKey,"key is over int32 max") 155 print(testObj[bigThenMaxKey]) 156 } 157 158 { 159 let minusOne = -1; 160 let testObj = {} 161 Reflect.set(testObj,minusOne,"key is minusOne") 162 print(testObj[minusOne]) 163 } 164 165 { 166 let lessThanInt32Min = -2147483648 167 let testObj = {} 168 Reflect.set(testObj,lessThanInt32Min,"key is lessThanInt32Min") 169 print(testObj[lessThanInt32Min]) 170 } 171 172 { 173 let strKeyNumber = "5" 174 let testObj = {} 175 Reflect.set(testObj,strKeyNumber,"key is strKeyNumber") 176 print(testObj[strKeyNumber]) 177 } 178 179 { 180 let strKeyNumberMinusOne = "-1" 181 let testObj = {} 182 Reflect.set(testObj,strKeyNumberMinusOne,"key is strKeyNumberMinusOne") 183 print(testObj[strKeyNumberMinusOne]) 184 } 185 186 { 187 let strKeyNumberOverInt32 = "2147483645" 188 let testObj = {} 189 Reflect.set(testObj,strKeyNumberOverInt32,"key is strKeyNumberOverInt32") 190 print(testObj[strKeyNumberOverInt32]) 191 } 192 193 { 194 let strKeyNumberLessInt32Min = "-2147483648" 195 let testObj = {} 196 Reflect.set(testObj,strKeyNumberLessInt32Min,"key is strKeyNumberLessInt32Min") 197 print(testObj[strKeyNumberLessInt32Min]) 198 } 199 200 { 201 try { 202 let objToStringThrowError = { 203 toString(){ 204 throw new Error("toString error") 205 } 206 } 207 let testObj = {} 208 Reflect.set(testObj,objToStringThrowError,"fail!") 209 } catch (error) { 210 print(error.message) 211 } 212 } 213 214 { 215 const testObj = { 216 t: "origin" 217 } 218 const proxy = new Proxy(testObj,{}) 219 Reflect.set(proxy,"t","normal proxy") 220 print(testObj["t"]) 221 } 222 223 { 224 const testObj = { 225 t: "origin" 226 } 227 const proxy = new Proxy(testObj,{ 228 set(target,key,value){ 229 if (value === "nothrow proxy") { 230 target[key] = value 231 return true 232 } else if (value === "return false proxy") { 233 target[key] = value 234 return false 235 } else if (value === "throw proxy") { 236 target[key] = value 237 throw new Error("throw error in proxy") 238 } 239 240 } 241 }) 242 Reflect.set(proxy,"t","return false proxy") 243 print(testObj["t"]) 244 Reflect.set(proxy,"t","nothrow proxy") 245 print(testObj["t"]) 246 try { 247 Reflect.set(proxy,"t","throw proxy") 248 } catch (error) { 249 print(testObj["t"]) 250 print(error.message) 251 } 252 } 253 254 { 255 const dynamicHandler = new Proxy({}, { 256 get(target, prop) { 257 if (prop === "set") { 258 return null; 259 } 260 return Reflect.get(target, prop); 261 } 262 }); 263 264 const target = {}; 265 const proxy = new Proxy(target, dynamicHandler); 266 267 Reflect.set(proxy, "a", 1); 268 } 269 270 // SetPropertyByIndex 271 { 272 let tArr = new Uint8Array(1) 273 let sym = Symbol("error symbol") 274 try { 275 Reflect.set(tArr,"1",sym) 276 } catch (error) { 277 print("sym to number fail") 278 } 279 } 280 281 { 282 let arr = [] 283 arr[1] = 1 284 Object.preventExtensions(arr) 285 Reflect.set(arr,"2",2) 286 print("shoud not throw arr not Extensions") 287 } 288 289 { 290 let arr = [] 291 arr[1] = 1 292 Object.defineProperty(arr,"length",{writable:false}) 293 Reflect.set(arr,"5",2) 294 print("don't throw error if length not writeable") 295 } 296 297 { 298 let arr = [] 299 arr[1] = 1 300 Object.defineProperty(arr,"2",{configurable:false}) 301 Reflect.set(arr,"2",2) 302 print("don't throw error if value not configurable") 303 } 304 305 { 306 let arr = [] 307 arr[0] = 5 308 arr[1025] = 1025 309 Object.defineProperty(arr,"length",{writable:false}) 310 Reflect.set(arr,"1026",1026) 311 print("no exception or dictionary arr") 312 } 313 314 const setterNothrow = { 315 set x(v){ 316 print("setterNothrow call setter") 317 this.t = v 318 } 319 } 320 const setterNothrowObj = Object.create(setterNothrow); 321 Reflect.set(setterNothrowObj,"x","setterNothrow good") 322 print(setterNothrowObj.t) 323 324 const setterthrow = { 325 set x(v){ 326 print("setterthrow call setter") 327 throw new Error("error in setter") 328 } 329 } 330 const setterthrowObj = Object.create(setterthrow); 331 try { 332 Reflect.set(setterthrowObj,"x","setterThrow good") 333 } catch (error) { 334 print(error.message) 335 } 336 337 const setterReturnFalse = { 338 set x(v){ 339 print("setterReturnFalse call setter") 340 return false 341 } 342 } 343 const setterReturnFalseObj = Object.create(setterReturnFalse) 344 Reflect.set(setterReturnFalseObj,"x","setterReturnFalse good"); 345 346 // normal test 347 (function testSetProperty() { 348 const obj = { foo: 42 }; 349 const result = Reflect.set(obj, "foo", 100); 350 print("testSetProperty: ", obj.foo === 100 && result === true); 351 })(); 352 353 354 (function testSetNonExistentProperty() { 355 const obj = { foo: 42 }; 356 const result = Reflect.set(obj, "bar", 123); 357 print("testSetNonExistentProperty: ", obj.bar === 123 && result === true); 358 })(); 359 360 361 (function testSetInProxy() { 362 const obj = { foo: 42 }; 363 const proxy = new Proxy(obj, { 364 set(target, prop, value, receiver) { 365 if (prop === "foo") { 366 target[prop] = value + 1; // 在 Proxy 中对 foo 做一些修改 367 return true; 368 } 369 return Reflect.set(target, prop, value, receiver); 370 } 371 }); 372 373 const result = Reflect.set(proxy, "foo", 100); 374 print("testSetInProxy:", obj.foo === 101 && result === true); 375 })(); 376 377 378 (function testSetWithSymbol() { 379 const sym = Symbol("bar"); 380 const obj = {}; 381 const result = Reflect.set(obj, sym, 200); 382 print("testSetWithSymbol:", obj[sym] === 200 && result === true); 383 })(); 384 385 386 (function testSetReceiver() { 387 const obj = { foo: 42 }; 388 const receiver = { foo: 100 }; 389 const result = Reflect.set(obj, "foo", 50, receiver); 390 print("testSetReceiver:", obj.foo === 50 && receiver.foo === 100 && result === true); 391 })(); 392 393 394 (function testSetPropertyAndCheckExists() { 395 const obj = {}; 396 const result1 = Reflect.set(obj, "foo", 42); 397 const result2 = Reflect.has(obj, "foo"); 398 print("testSetPropertyAndCheckExists:", result1 === true && result2 === true); 399 })(); 400 401 402 (function testSetInProxyThrowsException() { 403 const obj = { foo: 42 }; 404 const proxy = new Proxy(obj, { 405 set(target, prop, value, receiver) { 406 if (prop === "foo") { 407 throw new Error("Can't set foo!"); 408 } 409 return Reflect.set(target, prop, value, receiver); 410 } 411 }); 412 413 try { 414 Reflect.set(proxy, "foo", 100); 415 } catch (e) { 416 print("testSetInProxyThrowsException:", e.message === "Can't set foo!"); 417 } 418 })(); 419 420 421 (function testSetThrowsError() { 422 const obj = {}; 423 try { 424 Reflect.set(obj, "foo", undefined); 425 print("testSetThrowsError: undefined assignment allowed"); 426 } catch (e) { 427 print("testSetThrowsError: Error while setting undefined"); 428 } 429 })(); 430 431 432 (function testSetNestedObjectProperty() { 433 const obj = { nested: { foo: 42 } }; 434 const result = Reflect.set(obj.nested, "foo", 100); 435 print("testSetNestedObjectProperty:", obj.nested.foo === 100 && result === true); 436 })(); 437 438 439 (function testSetNestedPropertyInProxy() { 440 const obj = { nested: { foo: 42 } }; 441 const proxy = new Proxy(obj, { 442 set(target, prop, value, receiver) { 443 if (prop === "nested") { 444 target[prop].foo = value; 445 return true; 446 } 447 return Reflect.set(target, prop, value, receiver); 448 } 449 }); 450 451 const result = Reflect.set(proxy, "nested", { foo: 100 }); 452 print("testSetNestedPropertyInProxy:", obj.nested.foo === 100 && result === true); 453 })(); 454 455 456 (function testSetNonConfigurableProperty() { 457 const obj = {}; 458 Object.defineProperty(obj, "foo", { 459 value: 42, 460 writable: true, 461 configurable: false 462 }); 463 464 try { 465 Reflect.set(obj, "foo", 100); 466 print("testSetNonConfigurableProperty: No error for non-configurable"); 467 } catch (e) { 468 print("testSetNonConfigurableProperty: Error for non-configurable property"); 469 } 470 })(); 471 472 473 (function testSetPrototypeProperty() { 474 const proto = { foo: 42 }; 475 const obj = Object.create(proto); 476 const result = Reflect.set(obj, "foo", 100); 477 print("testSetPrototypeProperty:", obj.foo === 100 && result === true); 478 })(); 479 480 481 (function testSetAccessorPropertyInProxy() { 482 const obj = { 483 get foo() { 484 return 42; 485 }, 486 set foo(value) { 487 this._foo = value; 488 } 489 }; 490 491 const proxy = new Proxy(obj, { 492 set(target, prop, value, receiver) { 493 if (prop === "foo") { 494 target[prop] = value + 1; 495 return true; 496 } 497 return Reflect.set(target, prop, value, receiver); 498 } 499 }); 500 501 const result = Reflect.set(proxy, "foo", 100); 502 print("testSetAccessorPropertyInProxy:", obj._foo === 101 && result === true); 503 })(); 504} 505 506// reflect get ir test 507print("Reflect.get Ir test") 508{ 509 510 (function testGetterUsesReceiverThis() { 511 const obj = { 512 get val() { 513 return this.x + 1; 514 } 515 }; 516 517 const receiver = { x: 10 }; 518 const result = Reflect.get(obj, "val", receiver); 519 print("testGetterUsesReceiverThis:", result === 11); 520 })(); 521 522 523 (function testReceiverIsNull() { 524 const obj = { 525 get val() { 526 return this.x; 527 } 528 }; 529 530 try { 531 Reflect.get(obj, "val", null); 532 } catch (e) { 533 print("testReceiverIsNull:", e instanceof TypeError); 534 } 535 })(); 536 537 538 (function testReceiverIsPrimitive() { 539 const obj = { 540 get val() { 541 return this.length; 542 } 543 }; 544 545 const result = Reflect.get(obj, "val", "hello"); 546 print("testReceiverIsPrimitive:", result === 5); 547 })(); 548 549 550 (function testReceiverMissingFields() { 551 const obj = { 552 get val() { 553 return this.foo + 1; 554 } 555 }; 556 557 const receiver = {}; 558 const result = Reflect.get(obj, "val", receiver); 559 print("testReceiverMissingFields:", Number.isNaN(result)); 560 })(); 561 562 563 (function testReceiverWithOwnFields() { 564 const obj = { 565 get val() { 566 return this.foo * 2; 567 } 568 }; 569 570 const receiver = { foo: 21 }; 571 const result = Reflect.get(obj, "val", receiver); 572 print("testReceiverWithOwnFields:", result === 42); 573 })(); 574 575 576 (function testReceiverInheritance() { 577 const base = { 578 get foo() { 579 return this.x; 580 } 581 }; 582 583 const receiver = Object.create({ x: 123 }); 584 const result = Reflect.get(base, "foo", receiver); 585 print("testReceiverInheritance:", result === 123); 586 })(); 587 588 589 (function testReceiverIsSameAsTarget() { 590 const obj = { 591 get x() { 592 return this === obj; 593 } 594 }; 595 596 const result = Reflect.get(obj, "x", obj); 597 print("testReceiverIsSameAsTarget:", result === true); 598 })(); 599 600 601 (function testReceiverArrayLength() { 602 const obj = { 603 get lastIndex() { 604 return this.length - 1; 605 } 606 }; 607 608 const result = Reflect.get(obj, "lastIndex", [1, 2, 3, 4]); 609 print("testReceiverArrayLength:", result === 3); 610 })(); 611 612 613 (function testReceiverIsProxy() { 614 const obj = { 615 get val() { 616 return this.x; 617 } 618 }; 619 620 const proxy = new Proxy({ x: 42 }, { 621 get(target, prop, receiver) { 622 return Reflect.get(...arguments); 623 } 624 }); 625 626 const result = Reflect.get(obj, "val", proxy); 627 print("testReceiverIsProxy:", result === 42); 628 })(); 629 630 631 (function testReceiverIsClassInstance() { 632 class MyClass { 633 constructor(x) { 634 this.x = x; 635 } 636 get val() { 637 return this.x; 638 } 639 } 640 641 const obj = new MyClass(100); 642 const receiver = new MyClass(42); 643 const result = Reflect.get(obj, "val", receiver); 644 print("testReceiverIsClassInstance:", result === 42); // receiver 的 val 优先 645 })(); 646 647 648 (function testReceiverIsInPrototypeChain() { 649 const base = { 650 get val() { 651 return this.x; 652 } 653 }; 654 655 const proto = { x: 100 }; 656 const receiver = Object.create(proto); 657 const result = Reflect.get(base, "val", receiver); 658 print("testReceiverIsInPrototypeChain:", result === 100); 659 })(); 660 661 662 (function testReceiverIsNull() { 663 const obj = { 664 get val() { 665 return this.x; 666 } 667 }; 668 669 try { 670 Reflect.get(obj, "val", null); 671 } catch (e) { 672 print("testReceiverIsNull:", e instanceof TypeError); 673 } 674 })(); 675 676 677 (function testReceiverIsUndefined() { 678 const obj = { 679 get val() { 680 return this.x; 681 } 682 }; 683 684 try { 685 Reflect.get(obj, "val", undefined); 686 } catch (e) { 687 print("testReceiverIsUndefined:", e instanceof TypeError); 688 } 689 })(); 690 691 692 (function testReceiverModifiedBySet() { 693 const obj = { 694 get val() { 695 return this.x; 696 } 697 }; 698 699 const receiver = { x: 42 }; 700 Reflect.set(receiver, "x", 100); 701 const result = Reflect.get(obj, "val", receiver); 702 print("testReceiverModifiedBySet:", result === 100); 703 })(); 704 705} 706 707print("Reflect.has Ir test") 708{ 709 (function testHasPropertyExists() { 710 const obj = { foo: 42 }; 711 const result = Reflect.has(obj, "foo"); 712 print("testHasPropertyExists:", result === true); 713 })(); 714 715 716 (function testHasPropertyDoesNotExist() { 717 const obj = { foo: 42 }; 718 const result = Reflect.has(obj, "bar"); 719 print("testHasPropertyDoesNotExist:", result === false); 720 })(); 721 722 723 (function testHasPropertyInPrototypeChain() { 724 const proto = { foo: 42 }; 725 const obj = Object.create(proto); 726 const result = Reflect.has(obj, "foo"); 727 print("testHasPropertyInPrototypeChain:", result === true); 728 })(); 729 730 731 (function testHasWithNull() { 732 try { 733 Reflect.has(null, "foo"); 734 } catch (e) { 735 print("testHasWithNull:", e instanceof TypeError); 736 } 737 })(); 738 739 (function testHasWithUndefined() { 740 try { 741 Reflect.has(undefined, "foo"); 742 } catch (e) { 743 print("testHasWithUndefined:", e instanceof TypeError); 744 } 745 })(); 746 747 748 (function testHasInProxy() { 749 const obj = { foo: 42 }; 750 const proxy = new Proxy(obj, { 751 has(target, prop) { 752 return prop === "foo"; 753 } 754 }); 755 756 const result1 = Reflect.has(proxy, "foo"); 757 const result2 = Reflect.has(proxy, "bar"); 758 print("testHasInProxy: foo exists:", result1 === true); 759 print("testHasInProxy: bar exists:", result2 === false); 760 })(); 761 762 763 (function testHasAndGetCombination() { 764 const obj = { foo: 42 }; 765 766 const hasFoo = Reflect.has(obj, "foo"); 767 const getFoo = hasFoo ? Reflect.get(obj, "foo") : undefined; 768 print("testHasAndGetCombination:", getFoo === 42); 769 })(); 770 771 772 (function testHasInProxyWithNonExistentProperty() { 773 const obj = {}; 774 const proxy = new Proxy(obj, { 775 has(target, prop) { 776 return prop === "foo"; 777 } 778 }); 779 780 const result = Reflect.has(proxy, "bar"); 781 print("testHasInProxyWithNonExistentProperty:", result === false); 782 })(); 783 784 785 (function testHasVsInOperator() { 786 const obj = { foo: 42 }; 787 788 const resultReflect = Reflect.has(obj, "foo"); 789 const resultIn = "foo" in obj; 790 print("testHasVsInOperator:", resultReflect === resultIn); 791 })(); 792 793 794 (function testHasWithSymbol() { 795 const sym = Symbol("bar"); 796 const obj = { [sym]: 123 }; 797 798 const result = Reflect.has(obj, sym); 799 print("testHasWithSymbol:", result === true); 800 })(); 801 802 803 (function testHasWithNonExistentSymbol() { 804 const sym = Symbol("bar"); 805 const obj = { foo: 42 }; 806 807 const result = Reflect.has(obj, sym); 808 print("testHasWithNonExistentSymbol:", result === false); 809 })(); 810} 811 812print("builtins reflect end"); 813