• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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