| 
									
										
										
										
											2020-07-05 17:26:26 -07:00
										 |  |  | test("iterate through empty string", () => { | 
					
						
							| 
									
										
										
										
											2020-07-06 07:37:45 -07:00
										 |  |  |     const a = []; | 
					
						
							|  |  |  |     for (const property in "") { | 
					
						
							|  |  |  |         a.push(property); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     expect(a).toEqual([]); | 
					
						
							| 
									
										
										
										
											2020-07-05 17:26:26 -07:00
										 |  |  | }); | 
					
						
							| 
									
										
										
										
											2020-04-21 19:21:26 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-05 17:26:26 -07:00
										 |  |  | test("iterate through number", () => { | 
					
						
							| 
									
										
										
										
											2020-07-06 07:37:45 -07:00
										 |  |  |     const a = []; | 
					
						
							|  |  |  |     for (const property in 123) { | 
					
						
							|  |  |  |         a.push(property); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     expect(a).toEqual([]); | 
					
						
							| 
									
										
										
										
											2020-07-05 17:26:26 -07:00
										 |  |  | }); | 
					
						
							| 
									
										
										
										
											2020-04-21 19:21:26 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-05 17:26:26 -07:00
										 |  |  | test("iterate through empty object", () => { | 
					
						
							| 
									
										
										
										
											2020-07-06 07:37:45 -07:00
										 |  |  |     const a = []; | 
					
						
							|  |  |  |     for (const property in {}) { | 
					
						
							|  |  |  |         a.push(property); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     expect(a).toEqual([]); | 
					
						
							| 
									
										
										
										
											2020-07-05 17:26:26 -07:00
										 |  |  | }); | 
					
						
							| 
									
										
										
										
											2020-04-21 19:21:26 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-05 17:26:26 -07:00
										 |  |  | test("iterate through string", () => { | 
					
						
							| 
									
										
										
										
											2020-07-06 07:37:45 -07:00
										 |  |  |     const a = []; | 
					
						
							|  |  |  |     for (const property in "hello") { | 
					
						
							|  |  |  |         a.push(property); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     expect(a).toEqual(["0", "1", "2", "3", "4"]); | 
					
						
							| 
									
										
										
										
											2020-07-05 17:26:26 -07:00
										 |  |  | }); | 
					
						
							| 
									
										
										
										
											2020-04-21 19:21:26 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-05 17:26:26 -07:00
										 |  |  | test("iterate through object", () => { | 
					
						
							| 
									
										
										
										
											2020-07-06 07:37:45 -07:00
										 |  |  |     const a = []; | 
					
						
							|  |  |  |     for (const property in { a: 1, b: 2, c: 2 }) { | 
					
						
							|  |  |  |         a.push(property); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     expect(a).toEqual(["a", "b", "c"]); | 
					
						
							| 
									
										
										
										
											2020-07-05 17:26:26 -07:00
										 |  |  | }); | 
					
						
							| 
									
										
										
										
											2020-04-21 19:21:26 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-10 18:47:18 +02:00
										 |  |  | test("iterate through undefined", () => { | 
					
						
							|  |  |  |     for (const property in undefined) { | 
					
						
							|  |  |  |         expect.fail(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-05 17:26:26 -07:00
										 |  |  | test("use already-declared variable", () => { | 
					
						
							| 
									
										
										
										
											2020-07-06 07:37:45 -07:00
										 |  |  |     var property; | 
					
						
							|  |  |  |     for (property in "abc"); | 
					
						
							|  |  |  |     expect(property).toBe("2"); | 
					
						
							| 
									
										
										
										
											2020-07-05 17:26:26 -07:00
										 |  |  | }); | 
					
						
							| 
									
										
										
										
											2021-07-02 14:55:53 +04:30
										 |  |  | 
 | 
					
						
							|  |  |  | test("allow binding patterns", () => { | 
					
						
							| 
									
										
										
										
											2021-09-22 12:44:56 +02:00
										 |  |  |     const expected = [ | 
					
						
							|  |  |  |         ["1", "3", []], | 
					
						
							|  |  |  |         ["s", undefined, []], | 
					
						
							|  |  |  |         ["l", "n", ["g", "N", "a", "m", "e"]], | 
					
						
							|  |  |  |     ]; | 
					
						
							|  |  |  |     let counter = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (let [a, , b, ...c] in { 123: 1, sm: 2, longName: 3 }) { | 
					
						
							|  |  |  |         expect(a).toBe(expected[counter][0]); | 
					
						
							|  |  |  |         expect(b).toBe(expected[counter][1]); | 
					
						
							|  |  |  |         expect(c).toEqual(expected[counter][2]); | 
					
						
							|  |  |  |         counter++; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     expect(counter).toBe(3); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-17 01:23:10 +01:00
										 |  |  | describe("special left hand sides", () => { | 
					
						
							|  |  |  |     test("allow member expression as variable", () => { | 
					
						
							|  |  |  |         const f = {}; | 
					
						
							|  |  |  |         for (f.a in "abc"); | 
					
						
							|  |  |  |         expect(f.a).toBe("2"); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     test("allow member expression of function call", () => { | 
					
						
							|  |  |  |         const b = {}; | 
					
						
							|  |  |  |         function f() { | 
					
						
							|  |  |  |             return b; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for (f().a in "abc"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         expect(f().a).toBe("2"); | 
					
						
							|  |  |  |         expect(b.a).toBe("2"); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-09 15:14:05 -04:00
										 |  |  |     test.xfail("call function is allowed in parsing but fails in runtime", () => { | 
					
						
							|  |  |  |         function f() { | 
					
						
							|  |  |  |             expect().fail(); | 
					
						
							| 
									
										
										
										
											2022-02-17 01:23:10 +01:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2023-08-09 15:14:05 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |         // Does not fail since it does not iterate
 | 
					
						
							|  |  |  |         expect("for (f() in []);").toEvalTo(undefined); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         expect(() => { | 
					
						
							|  |  |  |             eval("for (f() in [0]) { expect().fail() }"); | 
					
						
							|  |  |  |         }).toThrowWithMessage(ReferenceError, "Invalid left-hand side in assignment"); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-17 21:53:48 +12:00
										 |  |  |     test("Cannot change constant declaration in body", () => { | 
					
						
							| 
									
										
										
										
											2023-08-09 15:14:05 -04:00
										 |  |  |         const vals = []; | 
					
						
							|  |  |  |         for (const v in [1, 2]) { | 
					
						
							|  |  |  |             expect(() => v++).toThrowWithMessage(TypeError, "Invalid assignment to const variable"); | 
					
						
							|  |  |  |             vals.push(v); | 
					
						
							| 
									
										
										
										
											2022-11-30 01:45:35 +01:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2023-08-09 15:14:05 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |         expect(vals).toEqual(["0", "1"]); | 
					
						
							|  |  |  |     }); | 
					
						
							| 
									
										
										
										
											2021-07-02 14:55:53 +04:30
										 |  |  | }); | 
					
						
							| 
									
										
										
										
											2022-03-29 00:18:39 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | test("remove properties while iterating", () => { | 
					
						
							|  |  |  |     const from = [1, 2, 3]; | 
					
						
							|  |  |  |     const to = []; | 
					
						
							|  |  |  |     for (const prop in from) { | 
					
						
							|  |  |  |         to.push(prop); | 
					
						
							|  |  |  |         from.pop(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     expect(to).toEqual(["0", "1"]); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | test("duplicated properties in prototype", () => { | 
					
						
							|  |  |  |     const object = { a: 1 }; | 
					
						
							|  |  |  |     const proto = { a: 2 }; | 
					
						
							|  |  |  |     Object.setPrototypeOf(object, proto); | 
					
						
							|  |  |  |     const a = []; | 
					
						
							|  |  |  |     for (const prop in object) { | 
					
						
							|  |  |  |         a.push(prop); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     expect(a).toEqual(["a"]); | 
					
						
							|  |  |  | }); |