| 
									
										
										
										
											2020-07-05 17:26:26 -07:00
										 |  |  | describe("correct behavior", () => { | 
					
						
							| 
									
										
										
										
											2020-07-06 07:37:45 -07:00
										 |  |  |     test("iterate through array", () => { | 
					
						
							|  |  |  |         const a = []; | 
					
						
							|  |  |  |         for (const num of [1, 2, 3]) { | 
					
						
							|  |  |  |             a.push(num); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         expect(a).toEqual([1, 2, 3]); | 
					
						
							|  |  |  |     }); | 
					
						
							| 
									
										
										
										
											2020-04-21 19:21:26 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-06 07:37:45 -07:00
										 |  |  |     test("iterate through string", () => { | 
					
						
							|  |  |  |         const a = []; | 
					
						
							|  |  |  |         for (const char of "hello") { | 
					
						
							|  |  |  |             a.push(char); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         expect(a).toEqual(["h", "e", "l", "l", "o"]); | 
					
						
							|  |  |  |     }); | 
					
						
							| 
									
										
										
										
											2020-04-21 19:21:26 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-06 07:37:45 -07:00
										 |  |  |     test("iterate through string object", () => { | 
					
						
							|  |  |  |         const a = []; | 
					
						
							|  |  |  |         for (const char of new String("hello")) { | 
					
						
							|  |  |  |             a.push(char); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         expect(a).toEqual(["h", "e", "l", "l", "o"]); | 
					
						
							|  |  |  |     }); | 
					
						
							| 
									
										
										
										
											2020-04-21 19:21:26 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-06 07:37:45 -07:00
										 |  |  |     test("use already-declared variable", () => { | 
					
						
							|  |  |  |         var char; | 
					
						
							|  |  |  |         for (char of "abc"); | 
					
						
							|  |  |  |         expect(char).toBe("c"); | 
					
						
							|  |  |  |     }); | 
					
						
							| 
									
										
										
										
											2020-07-13 08:27:20 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     test("respects custom Symbol.iterator method", () => { | 
					
						
							|  |  |  |         const o = { | 
					
						
							|  |  |  |             [Symbol.iterator]() { | 
					
						
							|  |  |  |                 return { | 
					
						
							|  |  |  |                     i: 0, | 
					
						
							|  |  |  |                     next() { | 
					
						
							|  |  |  |                         if (this.i++ == 3) { | 
					
						
							|  |  |  |                             return { done: true }; | 
					
						
							|  |  |  |                         } | 
					
						
							|  |  |  |                         return { value: this.i, done: false }; | 
					
						
							|  |  |  |                     }, | 
					
						
							|  |  |  |                 }; | 
					
						
							|  |  |  |             }, | 
					
						
							|  |  |  |         }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         const a = []; | 
					
						
							|  |  |  |         for (const k of o) { | 
					
						
							|  |  |  |             a.push(k); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         expect(a).toEqual([1, 2, 3]); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     test("loops through custom iterator if there is an exception thrown part way through", () => { | 
					
						
							|  |  |  |         // This tests against the way custom iterators used to be implemented, where the values
 | 
					
						
							|  |  |  |         // were all collected at once before the for-of body was executed, instead of getting
 | 
					
						
							|  |  |  |         // the values one at a time
 | 
					
						
							|  |  |  |         const o = { | 
					
						
							|  |  |  |             [Symbol.iterator]() { | 
					
						
							|  |  |  |                 return { | 
					
						
							|  |  |  |                     i: 0, | 
					
						
							|  |  |  |                     next() { | 
					
						
							|  |  |  |                         if (this.i++ === 3) { | 
					
						
							|  |  |  |                             throw new Error(); | 
					
						
							|  |  |  |                         } | 
					
						
							|  |  |  |                         return { value: this.i }; | 
					
						
							|  |  |  |                     }, | 
					
						
							|  |  |  |                 }; | 
					
						
							|  |  |  |             }, | 
					
						
							|  |  |  |         }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         const a = []; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         try { | 
					
						
							|  |  |  |             for (let k of o) { | 
					
						
							|  |  |  |                 a.push(k); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             expect().fail(); | 
					
						
							|  |  |  |         } catch (e) { | 
					
						
							|  |  |  |             expect(a).toEqual([1, 2, 3]); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     }); | 
					
						
							| 
									
										
										
										
											2020-07-05 17:26:26 -07:00
										 |  |  | }); | 
					
						
							| 
									
										
										
										
											2020-04-21 19:21:26 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-05 17:26:26 -07:00
										 |  |  | describe("errors", () => { | 
					
						
							| 
									
										
										
										
											2020-07-06 07:37:45 -07:00
										 |  |  |     test("right hand side is a primitive", () => { | 
					
						
							|  |  |  |         expect(() => { | 
					
						
							|  |  |  |             for (const _ of 123) { | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2020-07-13 08:27:20 -07:00
										 |  |  |         }).toThrowWithMessage(TypeError, "123 is not iterable"); | 
					
						
							| 
									
										
										
										
											2020-07-06 07:37:45 -07:00
										 |  |  |     }); | 
					
						
							| 
									
										
										
										
											2020-04-21 19:21:26 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-06 07:37:45 -07:00
										 |  |  |     test("right hand side is an object", () => { | 
					
						
							|  |  |  |         expect(() => { | 
					
						
							|  |  |  |             for (const _ of { foo: 1, bar: 2 }) { | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2020-07-13 08:27:20 -07:00
										 |  |  |         }).toThrowWithMessage(TypeError, "[object Object] is not iterable"); | 
					
						
							| 
									
										
										
										
											2020-07-06 07:37:45 -07:00
										 |  |  |     }); | 
					
						
							| 
									
										
										
										
											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
										 |  |  |     let counter = 0; | 
					
						
							|  |  |  |     for (let [a, b] of [ | 
					
						
							|  |  |  |         [1, 2], | 
					
						
							|  |  |  |         [3, 4], | 
					
						
							|  |  |  |         [5, 6], | 
					
						
							|  |  |  |     ]) { | 
					
						
							|  |  |  |         expect(a + 1).toBe(b); | 
					
						
							|  |  |  |         counter++; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     expect(counter).toBe(3); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | test("allow member expression as variable", () => { | 
					
						
							|  |  |  |     const f = {}; | 
					
						
							|  |  |  |     for (f.a of "abc"); | 
					
						
							|  |  |  |     expect(f.a).toBe("c"); | 
					
						
							| 
									
										
										
										
											2021-07-02 14:55:53 +04:30
										 |  |  | }); |