| 
									
										
										
										
											2020-07-04 10:09:48 -07:00
										 |  |  | describe("normal functionality", () => { | 
					
						
							| 
									
										
										
										
											2020-07-07 21:39:36 -07:00
										 |  |  |     let s = Symbol("foo"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     test("non-configurable string property", () => { | 
					
						
							| 
									
										
										
										
											2020-07-06 07:37:45 -07:00
										 |  |  |         let o = {}; | 
					
						
							|  |  |  |         Object.defineProperty(o, "foo", { value: 1, writable: false, enumerable: false }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         expect(o.foo).toBe(1); | 
					
						
							|  |  |  |         o.foo = 2; | 
					
						
							|  |  |  |         expect(o.foo).toBe(1); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         expect(o).not.toHaveConfigurableProperty("foo"); | 
					
						
							|  |  |  |         expect(o).not.toHaveEnumerableProperty("foo"); | 
					
						
							|  |  |  |         expect(o).not.toHaveWritableProperty("foo"); | 
					
						
							|  |  |  |         expect(o).toHaveValueProperty("foo", 1); | 
					
						
							| 
									
										
										
										
											2020-04-19 23:01:45 +01:00
										 |  |  |     }); | 
					
						
							| 
									
										
										
										
											2020-07-06 07:37:45 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-07 21:39:36 -07:00
										 |  |  |     test("non-configurable symbol property", () => { | 
					
						
							|  |  |  |         let o = {}; | 
					
						
							|  |  |  |         Object.defineProperty(o, s, { value: 1, writable: false, enumerable: false }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         expect(o[s]).toBe(1); | 
					
						
							|  |  |  |         o[s] = 2; | 
					
						
							|  |  |  |         expect(o[s]).toBe(1); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         expect(o).not.toHaveConfigurableProperty(s); | 
					
						
							|  |  |  |         expect(o).not.toHaveEnumerableProperty(s); | 
					
						
							|  |  |  |         expect(o).not.toHaveWritableProperty(s); | 
					
						
							|  |  |  |         expect(o).toHaveValueProperty(s, 1); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-06 07:37:45 -07:00
										 |  |  |     test("array index getter", () => { | 
					
						
							|  |  |  |         let o = {}; | 
					
						
							|  |  |  |         Object.defineProperty(o, 2, { | 
					
						
							|  |  |  |             get() { | 
					
						
							|  |  |  |                 return 10; | 
					
						
							|  |  |  |             }, | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |         expect(o[2]).toBe(10); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-07 21:39:36 -07:00
										 |  |  |     test("symbol property getter", () => { | 
					
						
							|  |  |  |         let o = {}; | 
					
						
							|  |  |  |         Object.defineProperty(o, s, { | 
					
						
							|  |  |  |             get() { | 
					
						
							|  |  |  |                 return 10; | 
					
						
							|  |  |  |             }, | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |         expect(o[s]).toBe(10); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     test("configurable string property", () => { | 
					
						
							| 
									
										
										
										
											2020-07-06 07:37:45 -07:00
										 |  |  |         let o = {}; | 
					
						
							|  |  |  |         Object.defineProperty(o, "foo", { value: "hi", writable: true, enumerable: true }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         expect(o.foo).toBe("hi"); | 
					
						
							|  |  |  |         o.foo = "ho"; | 
					
						
							|  |  |  |         expect(o.foo).toBe("ho"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         expect(o).not.toHaveConfigurableProperty("foo"); | 
					
						
							|  |  |  |         expect(o).toHaveEnumerableProperty("foo"); | 
					
						
							|  |  |  |         expect(o).toHaveWritableProperty("foo"); | 
					
						
							|  |  |  |         expect(o).toHaveValueProperty("foo", "ho"); | 
					
						
							| 
									
										
										
										
											2020-05-21 11:14:23 -07:00
										 |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-07 21:39:36 -07:00
										 |  |  |     test("configurable symbol property", () => { | 
					
						
							|  |  |  |         let o = {}; | 
					
						
							|  |  |  |         Object.defineProperty(o, s, { value: "hi", writable: true, enumerable: true }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         expect(o[s]).toBe("hi"); | 
					
						
							|  |  |  |         o[s] = "ho"; | 
					
						
							|  |  |  |         expect(o[s]).toBe("ho"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         expect(o).not.toHaveConfigurableProperty(s); | 
					
						
							|  |  |  |         expect(o).toHaveEnumerableProperty(s); | 
					
						
							|  |  |  |         expect(o).toHaveWritableProperty(s); | 
					
						
							|  |  |  |         expect(o).toHaveValueProperty(s, "ho"); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     test("reconfigure configurable string property", () => { | 
					
						
							| 
									
										
										
										
											2020-07-06 07:37:45 -07:00
										 |  |  |         let o = {}; | 
					
						
							|  |  |  |         Object.defineProperty(o, "foo", { value: 9, configurable: true, writable: false }); | 
					
						
							|  |  |  |         Object.defineProperty(o, "foo", { configurable: true, writable: true }); | 
					
						
							| 
									
										
										
										
											2020-05-21 11:14:23 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-06 07:37:45 -07:00
										 |  |  |         expect(o).toHaveConfigurableProperty("foo"); | 
					
						
							|  |  |  |         expect(o).toHaveWritableProperty("foo"); | 
					
						
							|  |  |  |         expect(o).not.toHaveEnumerableProperty("foo"); | 
					
						
							|  |  |  |         expect(o).toHaveValueProperty("foo", 9); | 
					
						
							|  |  |  |     }); | 
					
						
							| 
									
										
										
										
											2020-07-04 10:09:48 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-07 21:39:36 -07:00
										 |  |  |     test("reconfigure configurable symbol property", () => { | 
					
						
							|  |  |  |         let o = {}; | 
					
						
							|  |  |  |         Object.defineProperty(o, s, { value: 9, configurable: true, writable: false }); | 
					
						
							|  |  |  |         Object.defineProperty(o, s, { configurable: true, writable: true }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         expect(o).toHaveConfigurableProperty(s); | 
					
						
							|  |  |  |         expect(o).toHaveWritableProperty(s); | 
					
						
							|  |  |  |         expect(o).not.toHaveEnumerableProperty(s); | 
					
						
							|  |  |  |         expect(o).toHaveValueProperty(s, 9); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     test("define string accessor", () => { | 
					
						
							| 
									
										
										
										
											2020-07-06 07:37:45 -07:00
										 |  |  |         let o = {}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         Object.defineProperty(o, "foo", { | 
					
						
							|  |  |  |             configurable: true, | 
					
						
							|  |  |  |             get() { | 
					
						
							|  |  |  |                 return o.secret_foo + 1; | 
					
						
							|  |  |  |             }, | 
					
						
							|  |  |  |             set(value) { | 
					
						
							|  |  |  |                 this.secret_foo = value + 1; | 
					
						
							|  |  |  |             }, | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         o.foo = 10; | 
					
						
							|  |  |  |         expect(o.foo).toBe(12); | 
					
						
							|  |  |  |         o.foo = 20; | 
					
						
							|  |  |  |         expect(o.foo).toBe(22); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         Object.defineProperty(o, "foo", { configurable: true, value: 4 }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         expect(o.foo).toBe(4); | 
					
						
							|  |  |  |         expect((o.foo = 5)).toBe(5); | 
					
						
							|  |  |  |         expect((o.foo = 4)).toBe(4); | 
					
						
							|  |  |  |     }); | 
					
						
							| 
									
										
										
										
											2020-07-07 21:39:36 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     test("define symbol accessor", () => { | 
					
						
							|  |  |  |         let o = {}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         Object.defineProperty(o, s, { | 
					
						
							|  |  |  |             configurable: true, | 
					
						
							|  |  |  |             get() { | 
					
						
							|  |  |  |                 return o.secret_foo + 1; | 
					
						
							|  |  |  |             }, | 
					
						
							|  |  |  |             set(value) { | 
					
						
							|  |  |  |                 this.secret_foo = value + 1; | 
					
						
							|  |  |  |             }, | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         o[s] = 10; | 
					
						
							|  |  |  |         expect(o[s]).toBe(12); | 
					
						
							|  |  |  |         o[s] = 20; | 
					
						
							|  |  |  |         expect(o[s]).toBe(22); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         Object.defineProperty(o, s, { configurable: true, value: 4 }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         expect(o[s]).toBe(4); | 
					
						
							|  |  |  |         expect((o[s] = 5)).toBe(5); | 
					
						
							|  |  |  |         expect((o[s] = 4)).toBe(4); | 
					
						
							|  |  |  |     }); | 
					
						
							| 
									
										
										
										
											2020-10-10 14:42:23 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     test("issue #3735, reconfiguring property in unique shape", () => { | 
					
						
							|  |  |  |         const o = {}; | 
					
						
							|  |  |  |         // In LibJS an object with more than 100 properties gets a unique shape
 | 
					
						
							|  |  |  |         for (let i = 0; i < 101; ++i) { | 
					
						
							|  |  |  |             o[`property${i}`] = i; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         Object.defineProperty(o, "x", { configurable: true }); | 
					
						
							|  |  |  |         Object.defineProperty(o, "x", { configurable: false }); | 
					
						
							|  |  |  |     }); | 
					
						
							| 
									
										
										
										
											2020-07-04 10:09:48 -07:00
										 |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | describe("errors", () => { | 
					
						
							| 
									
										
										
										
											2020-07-06 07:37:45 -07:00
										 |  |  |     test("redefine non-configurable property", () => { | 
					
						
							|  |  |  |         let o = {}; | 
					
						
							|  |  |  |         Object.defineProperty(o, "foo", { value: 1, writable: true, enumerable: true }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         expect(() => { | 
					
						
							|  |  |  |             Object.defineProperty(o, "foo", { value: 2, writable: false, enumerable: true }); | 
					
						
							|  |  |  |         }).toThrowWithMessage( | 
					
						
							|  |  |  |             TypeError, | 
					
						
							|  |  |  |             "Cannot change attributes of non-configurable property 'foo'" | 
					
						
							|  |  |  |         ); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-07 21:39:36 -07:00
										 |  |  |     test("redefine non-configurable symbol property", () => { | 
					
						
							|  |  |  |         let o = {}; | 
					
						
							|  |  |  |         let s = Symbol("foo"); | 
					
						
							|  |  |  |         Object.defineProperty(o, s, { value: 1, writable: true, enumerable: true }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         expect(() => { | 
					
						
							|  |  |  |             Object.defineProperty(o, s, { value: 2, writable: false, enumerable: true }); | 
					
						
							|  |  |  |         }).toThrowWithMessage( | 
					
						
							|  |  |  |             TypeError, | 
					
						
							|  |  |  |             "Cannot change attributes of non-configurable property 'Symbol(foo)'" | 
					
						
							|  |  |  |         ); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-06 07:37:45 -07:00
										 |  |  |     test("cannot define 'value' and 'get' in the same descriptor", () => { | 
					
						
							|  |  |  |         let o = {}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         expect(() => { | 
					
						
							|  |  |  |             Object.defineProperty(o, "a", { | 
					
						
							|  |  |  |                 get() {}, | 
					
						
							|  |  |  |                 value: 9, | 
					
						
							|  |  |  |             }); | 
					
						
							|  |  |  |         }).toThrowWithMessage( | 
					
						
							|  |  |  |             TypeError, | 
					
						
							|  |  |  |             "Accessor property descriptor cannot specify a value or writable key" | 
					
						
							|  |  |  |         ); | 
					
						
							| 
									
										
										
										
											2020-05-21 11:14:23 -07:00
										 |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-06 07:37:45 -07:00
										 |  |  |     test("cannot define 'value' and 'set' in the same descriptor", () => { | 
					
						
							|  |  |  |         let o = {}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         expect(() => { | 
					
						
							|  |  |  |             Object.defineProperty(o, "a", { | 
					
						
							|  |  |  |                 set() {}, | 
					
						
							|  |  |  |                 writable: true, | 
					
						
							|  |  |  |             }); | 
					
						
							|  |  |  |         }).toThrowWithMessage( | 
					
						
							|  |  |  |             TypeError, | 
					
						
							|  |  |  |             "Accessor property descriptor cannot specify a value or writable key" | 
					
						
							|  |  |  |         ); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     test("redefine non-configurable accessor", () => { | 
					
						
							|  |  |  |         let o = {}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         Object.defineProperty(o, "foo", { | 
					
						
							|  |  |  |             configurable: false, | 
					
						
							|  |  |  |             get() { | 
					
						
							|  |  |  |                 return this.secret_foo + 2; | 
					
						
							|  |  |  |             }, | 
					
						
							|  |  |  |             set(value) { | 
					
						
							|  |  |  |                 o.secret_foo = value + 2; | 
					
						
							|  |  |  |             }, | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         expect(() => { | 
					
						
							|  |  |  |             Object.defineProperty(o, "foo", { | 
					
						
							|  |  |  |                 configurable: false, | 
					
						
							|  |  |  |                 get() { | 
					
						
							|  |  |  |                     return this.secret_foo + 2; | 
					
						
							|  |  |  |                 }, | 
					
						
							|  |  |  |             }); | 
					
						
							|  |  |  |         }).toThrowWithMessage( | 
					
						
							|  |  |  |             TypeError, | 
					
						
							|  |  |  |             "Cannot change attributes of non-configurable property 'foo'" | 
					
						
							|  |  |  |         ); | 
					
						
							|  |  |  |     }); | 
					
						
							| 
									
										
										
										
											2020-07-04 10:09:48 -07:00
										 |  |  | }); |