| 
									
										
										
										
											2017-01-18 22:24:20 +08:00
										 |  |  | "use strict"; | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-22 15:27:52 +08:00
										 |  |  | const BasicEvaluatedExpression = require("../lib/javascript/BasicEvaluatedExpression"); | 
					
						
							| 
									
										
										
										
											2019-10-11 21:46:57 +08:00
										 |  |  | const JavascriptParser = require("../lib/javascript/JavascriptParser"); | 
					
						
							| 
									
										
										
										
											2017-01-18 22:24:20 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-03 16:15:48 +08:00
										 |  |  | describe("JavascriptParser", () => { | 
					
						
							| 
									
										
										
										
											2017-11-15 21:08:11 +08:00
										 |  |  | 	/* eslint-disable no-undef */ | 
					
						
							|  |  |  | 	/* eslint-disable no-unused-vars */ | 
					
						
							|  |  |  | 	/* eslint-disable no-inner-declarations */ | 
					
						
							| 
									
										
										
										
											2017-01-18 22:24:20 +08:00
										 |  |  | 	const testCases = { | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 		"call ident": [ | 
					
						
							| 
									
										
										
										
											2020-03-29 06:10:15 +08:00
										 |  |  | 			function () { | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 				abc("test"); | 
					
						
							| 
									
										
										
										
											2018-02-25 18:46:17 +08:00
										 |  |  | 			}, | 
					
						
							|  |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 				abc: ["test"] | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		], | 
					
						
							|  |  |  | 		"call member": [ | 
					
						
							| 
									
										
										
										
											2020-03-29 06:10:15 +08:00
										 |  |  | 			function () { | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 				cde.abc("membertest"); | 
					
						
							| 
									
										
										
										
											2018-02-25 18:46:17 +08:00
										 |  |  | 			}, | 
					
						
							|  |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 				cdeabc: ["membertest"] | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		], | 
					
						
							| 
									
										
										
										
											2016-06-04 18:06:10 +08:00
										 |  |  | 		"call member using bracket notation": [ | 
					
						
							| 
									
										
										
										
											2020-03-29 06:10:15 +08:00
										 |  |  | 			function () { | 
					
						
							| 
									
										
										
										
											2016-06-04 18:06:10 +08:00
										 |  |  | 				cde["abc"]("membertest"); | 
					
						
							| 
									
										
										
										
											2018-02-25 18:46:17 +08:00
										 |  |  | 			}, | 
					
						
							|  |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2016-06-04 18:06:10 +08:00
										 |  |  | 				cdeabc: ["membertest"] | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		], | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 		"call inner member": [ | 
					
						
							| 
									
										
										
										
											2020-03-29 06:10:15 +08:00
										 |  |  | 			function () { | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 				cde.ddd.abc("inner"); | 
					
						
							| 
									
										
										
										
											2018-02-25 18:46:17 +08:00
										 |  |  | 			}, | 
					
						
							|  |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 				cdedddabc: ["inner"] | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		], | 
					
						
							| 
									
										
										
										
											2016-06-04 18:06:10 +08:00
										 |  |  | 		"call inner member using bracket notation": [ | 
					
						
							| 
									
										
										
										
											2020-03-29 06:10:15 +08:00
										 |  |  | 			function () { | 
					
						
							| 
									
										
										
										
											2016-06-04 18:06:10 +08:00
										 |  |  | 				cde.ddd["abc"]("inner"); | 
					
						
							| 
									
										
										
										
											2018-02-25 18:46:17 +08:00
										 |  |  | 			}, | 
					
						
							|  |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2016-06-04 18:06:10 +08:00
										 |  |  | 				cdedddabc: ["inner"] | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		], | 
					
						
							| 
									
										
										
										
											2018-02-25 18:46:17 +08:00
										 |  |  | 		expression: [ | 
					
						
							| 
									
										
										
										
											2020-03-29 06:10:15 +08:00
										 |  |  | 			function () { | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 				fgh; | 
					
						
							| 
									
										
										
										
											2018-02-25 18:46:17 +08:00
										 |  |  | 			}, | 
					
						
							|  |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 				fgh: [""] | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		], | 
					
						
							|  |  |  | 		"expression sub": [ | 
					
						
							| 
									
										
										
										
											2020-03-29 06:10:15 +08:00
										 |  |  | 			function () { | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 				fgh.sub; | 
					
						
							| 
									
										
										
										
											2018-02-25 18:46:17 +08:00
										 |  |  | 			}, | 
					
						
							|  |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 				fghsub: ["notry"] | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		], | 
					
						
							| 
									
										
										
										
											2014-12-16 15:00:05 +08:00
										 |  |  | 		"member expression": [ | 
					
						
							| 
									
										
										
										
											2020-03-29 06:10:15 +08:00
										 |  |  | 			function () { | 
					
						
							| 
									
										
										
										
											2017-11-15 21:08:11 +08:00
										 |  |  | 				test[memberExpr]; | 
					
						
							|  |  |  | 				test[+memberExpr]; | 
					
						
							| 
									
										
										
										
											2018-02-25 18:46:17 +08:00
										 |  |  | 			}, | 
					
						
							|  |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2014-12-16 15:00:05 +08:00
										 |  |  | 				expressions: ["memberExpr", "memberExpr"] | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		], | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 		"in function definition": [ | 
					
						
							| 
									
										
										
										
											2020-03-29 06:10:15 +08:00
										 |  |  | 			function () { | 
					
						
							|  |  |  | 				(function (abc, cde, fgh) { | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 					abc("test"); | 
					
						
							|  |  |  | 					cde.abc("test"); | 
					
						
							|  |  |  | 					cde.ddd.abc("test"); | 
					
						
							|  |  |  | 					fgh; | 
					
						
							|  |  |  | 					fgh.sub; | 
					
						
							|  |  |  | 				})(); | 
					
						
							| 
									
										
										
										
											2018-02-25 18:46:17 +08:00
										 |  |  | 			}, | 
					
						
							|  |  |  | 			{} | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 		], | 
					
						
							| 
									
										
										
										
											2017-01-18 22:24:20 +08:00
										 |  |  | 		"const definition": [ | 
					
						
							| 
									
										
										
										
											2020-03-29 06:10:15 +08:00
										 |  |  | 			function () { | 
					
						
							| 
									
										
										
										
											2017-01-18 22:24:20 +08:00
										 |  |  | 				let abc, cde, fgh; | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 				abc("test"); | 
					
						
							|  |  |  | 				cde.abc("test"); | 
					
						
							|  |  |  | 				cde.ddd.abc("test"); | 
					
						
							|  |  |  | 				fgh; | 
					
						
							|  |  |  | 				fgh.sub; | 
					
						
							| 
									
										
										
										
											2018-02-25 18:46:17 +08:00
										 |  |  | 			}, | 
					
						
							|  |  |  | 			{} | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 		], | 
					
						
							| 
									
										
										
										
											2017-01-24 17:39:17 +08:00
										 |  |  | 		"var definition": [ | 
					
						
							| 
									
										
										
										
											2020-03-29 06:10:15 +08:00
										 |  |  | 			function () { | 
					
						
							| 
									
										
										
										
											2017-01-25 20:43:17 +08:00
										 |  |  | 				var abc, cde, fgh; | 
					
						
							| 
									
										
										
										
											2017-01-24 17:39:17 +08:00
										 |  |  | 				abc("test"); | 
					
						
							|  |  |  | 				cde.abc("test"); | 
					
						
							|  |  |  | 				cde.ddd.abc("test"); | 
					
						
							|  |  |  | 				fgh; | 
					
						
							|  |  |  | 				fgh.sub; | 
					
						
							| 
									
										
										
										
											2018-02-25 18:46:17 +08:00
										 |  |  | 			}, | 
					
						
							|  |  |  | 			{} | 
					
						
							| 
									
										
										
										
											2017-01-24 17:39:17 +08:00
										 |  |  | 		], | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 		"function definition": [ | 
					
						
							| 
									
										
										
										
											2020-03-29 06:10:15 +08:00
										 |  |  | 			function () { | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 				function abc() {} | 
					
						
							| 
									
										
										
										
											2015-08-09 18:42:43 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 				function cde() {} | 
					
						
							| 
									
										
										
										
											2015-08-09 18:42:43 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 				function fgh() {} | 
					
						
							|  |  |  | 				abc("test"); | 
					
						
							|  |  |  | 				cde.abc("test"); | 
					
						
							|  |  |  | 				cde.ddd.abc("test"); | 
					
						
							|  |  |  | 				fgh; | 
					
						
							|  |  |  | 				fgh.sub; | 
					
						
							| 
									
										
										
										
											2018-02-25 18:46:17 +08:00
										 |  |  | 			}, | 
					
						
							|  |  |  | 			{} | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 		], | 
					
						
							| 
									
										
										
										
											2017-12-30 23:27:17 +08:00
										 |  |  | 		"class definition": [ | 
					
						
							| 
									
										
										
										
											2020-03-29 06:10:15 +08:00
										 |  |  | 			function () { | 
					
						
							| 
									
										
										
										
											2017-12-30 23:27:17 +08:00
										 |  |  | 				class memberExpr { | 
					
						
							|  |  |  | 					cde() { | 
					
						
							|  |  |  | 						abc("cde"); | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 					static fgh() { | 
					
						
							|  |  |  | 						abc("fgh"); | 
					
						
							|  |  |  | 						fgh(); | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2018-02-25 18:46:17 +08:00
										 |  |  | 			}, | 
					
						
							|  |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2017-12-30 23:27:17 +08:00
										 |  |  | 				abc: ["cde", "fgh"], | 
					
						
							|  |  |  | 				fgh: ["memberExpr"] | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		], | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 		"in try": [ | 
					
						
							| 
									
										
										
										
											2020-03-29 06:10:15 +08:00
										 |  |  | 			function () { | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 				try { | 
					
						
							|  |  |  | 					fgh.sub; | 
					
						
							|  |  |  | 					fgh; | 
					
						
							| 
									
										
										
										
											2015-08-09 18:42:43 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 					function test(ttt) { | 
					
						
							|  |  |  | 						fgh.sub; | 
					
						
							|  |  |  | 						fgh; | 
					
						
							|  |  |  | 					} | 
					
						
							| 
									
										
										
										
											2018-02-25 18:46:17 +08:00
										 |  |  | 				} catch (e) { | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 					fgh.sub; | 
					
						
							|  |  |  | 					fgh; | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2018-02-25 18:46:17 +08:00
										 |  |  | 			}, | 
					
						
							|  |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 				fghsub: ["try", "notry", "notry"], | 
					
						
							| 
									
										
										
										
											2017-04-13 13:52:05 +08:00
										 |  |  | 				fgh: ["test", "test ttt", "test e"] | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		], | 
					
						
							| 
									
										
										
										
											2017-01-18 22:24:20 +08:00
										 |  |  | 		"renaming with const": [ | 
					
						
							| 
									
										
										
										
											2020-03-29 06:10:15 +08:00
										 |  |  | 			function () { | 
					
						
							| 
									
										
										
										
											2017-01-18 22:24:20 +08:00
										 |  |  | 				const xyz = abc; | 
					
						
							| 
									
										
										
										
											2014-01-31 17:57:28 +08:00
										 |  |  | 				xyz("test"); | 
					
						
							| 
									
										
										
										
											2018-02-25 18:46:17 +08:00
										 |  |  | 			}, | 
					
						
							|  |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2014-01-31 17:57:28 +08:00
										 |  |  | 				abc: ["test"] | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		], | 
					
						
							| 
									
										
										
										
											2017-01-24 17:39:17 +08:00
										 |  |  | 		"renaming with var": [ | 
					
						
							| 
									
										
										
										
											2020-03-29 06:10:15 +08:00
										 |  |  | 			function () { | 
					
						
							| 
									
										
										
										
											2017-01-25 20:43:17 +08:00
										 |  |  | 				var xyz = abc; | 
					
						
							| 
									
										
										
										
											2017-01-24 17:39:17 +08:00
										 |  |  | 				xyz("test"); | 
					
						
							| 
									
										
										
										
											2018-02-25 18:46:17 +08:00
										 |  |  | 			}, | 
					
						
							|  |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2017-01-24 17:39:17 +08:00
										 |  |  | 				abc: ["test"] | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		], | 
					
						
							| 
									
										
										
										
											2014-01-31 17:57:28 +08:00
										 |  |  | 		"renaming with assignment": [ | 
					
						
							| 
									
										
										
										
											2020-03-29 06:10:15 +08:00
										 |  |  | 			function () { | 
					
						
							| 
									
										
										
										
											2017-01-18 22:24:20 +08:00
										 |  |  | 				const xyz = abc; | 
					
						
							| 
									
										
										
										
											2014-01-31 17:57:28 +08:00
										 |  |  | 				xyz("test"); | 
					
						
							| 
									
										
										
										
											2018-02-25 18:46:17 +08:00
										 |  |  | 			}, | 
					
						
							|  |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2014-01-31 17:57:28 +08:00
										 |  |  | 				abc: ["test"] | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		], | 
					
						
							|  |  |  | 		"renaming with IIFE": [ | 
					
						
							| 
									
										
										
										
											2020-03-29 06:10:15 +08:00
										 |  |  | 			function () { | 
					
						
							|  |  |  | 				!(function (xyz) { | 
					
						
							| 
									
										
										
										
											2014-01-31 17:57:28 +08:00
										 |  |  | 					xyz("test"); | 
					
						
							| 
									
										
										
										
											2018-02-25 18:46:17 +08:00
										 |  |  | 				})(abc); | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2014-01-31 17:57:28 +08:00
										 |  |  | 				abc: ["test"] | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		], | 
					
						
							| 
									
										
										
										
											2017-06-16 21:31:45 +08:00
										 |  |  | 		"renaming arguments with IIFE (called)": [ | 
					
						
							| 
									
										
										
										
											2020-03-29 06:10:15 +08:00
										 |  |  | 			function () { | 
					
						
							|  |  |  | 				!function (xyz) { | 
					
						
							| 
									
										
										
										
											2014-01-31 17:57:28 +08:00
										 |  |  | 					xyz("test"); | 
					
						
							|  |  |  | 				}.call(fgh, abc); | 
					
						
							| 
									
										
										
										
											2018-02-25 18:46:17 +08:00
										 |  |  | 			}, | 
					
						
							|  |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2014-01-31 17:57:28 +08:00
										 |  |  | 				abc: ["test"], | 
					
						
							|  |  |  | 				fgh: [""] | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		], | 
					
						
							| 
									
										
										
										
											2017-06-16 21:31:45 +08:00
										 |  |  | 		"renaming this's properties with IIFE (called)": [ | 
					
						
							| 
									
										
										
										
											2020-03-29 06:10:15 +08:00
										 |  |  | 			function () { | 
					
						
							|  |  |  | 				!function () { | 
					
						
							| 
									
										
										
										
											2017-06-16 21:31:45 +08:00
										 |  |  | 					this.sub; | 
					
						
							|  |  |  | 				}.call(ijk); | 
					
						
							| 
									
										
										
										
											2018-02-25 18:46:17 +08:00
										 |  |  | 			}, | 
					
						
							|  |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2017-06-16 21:31:45 +08:00
										 |  |  | 				ijksub: ["test"] | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		], | 
					
						
							| 
									
										
										
										
											2017-07-12 00:12:15 +08:00
										 |  |  | 		"renaming this's properties with nested IIFE (called)": [ | 
					
						
							| 
									
										
										
										
											2020-03-29 06:10:15 +08:00
										 |  |  | 			function () { | 
					
						
							|  |  |  | 				!function () { | 
					
						
							|  |  |  | 					!function () { | 
					
						
							| 
									
										
										
										
											2017-07-12 00:12:15 +08:00
										 |  |  | 						this.sub; | 
					
						
							|  |  |  | 					}.call(this); | 
					
						
							|  |  |  | 				}.call(ijk); | 
					
						
							| 
									
										
										
										
											2018-02-25 18:46:17 +08:00
										 |  |  | 			}, | 
					
						
							|  |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2017-07-12 00:12:15 +08:00
										 |  |  | 				ijksub: ["test"] | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		], | 
					
						
							| 
									
										
										
										
											2017-12-05 10:03:50 +08:00
										 |  |  | 		"new Foo(...)": [ | 
					
						
							| 
									
										
										
										
											2020-03-29 06:10:15 +08:00
										 |  |  | 			function () { | 
					
						
							| 
									
										
										
										
											2017-12-05 10:40:23 +08:00
										 |  |  | 				new xyz("membertest"); | 
					
						
							| 
									
										
										
										
											2018-02-25 18:46:17 +08:00
										 |  |  | 			}, | 
					
						
							|  |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2017-12-05 10:03:50 +08:00
										 |  |  | 				xyz: ["membertest"] | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		], | 
					
						
							| 
									
										
										
										
											2017-12-30 23:27:17 +08:00
										 |  |  | 		"spread calls/literals": [ | 
					
						
							| 
									
										
										
										
											2020-03-29 06:10:15 +08:00
										 |  |  | 			function () { | 
					
						
							| 
									
										
										
										
											2017-12-30 23:27:17 +08:00
										 |  |  | 				var xyz = [...abc("xyz"), cde]; | 
					
						
							|  |  |  | 				Math.max(...fgh); | 
					
						
							| 
									
										
										
										
											2018-02-25 18:46:17 +08:00
										 |  |  | 			}, | 
					
						
							|  |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2017-12-30 23:27:17 +08:00
										 |  |  | 				abc: ["xyz"], | 
					
						
							|  |  |  | 				fgh: ["xyz"] | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		] | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 	}; | 
					
						
							| 
									
										
										
										
											2017-11-15 21:08:11 +08:00
										 |  |  | 	/* eslint-enable no-undef */ | 
					
						
							|  |  |  | 	/* eslint-enable no-unused-vars */ | 
					
						
							|  |  |  | 	/* eslint-enable no-inner-declarations */ | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-25 18:46:17 +08:00
										 |  |  | 	Object.keys(testCases).forEach(name => { | 
					
						
							| 
									
										
										
										
											2017-01-18 22:24:20 +08:00
										 |  |  | 		it("should parse " + name, () => { | 
					
						
							|  |  |  | 			let source = testCases[name][0].toString(); | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 			source = source.substr(13, source.length - 14).trim(); | 
					
						
							| 
									
										
										
										
											2017-01-18 22:24:20 +08:00
										 |  |  | 			const state = testCases[name][1]; | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-03 16:15:48 +08:00
										 |  |  | 			const testParser = new JavascriptParser({}); | 
					
						
							| 
									
										
										
										
											2019-07-24 16:51:04 +08:00
										 |  |  | 			testParser.hooks.canRename | 
					
						
							|  |  |  | 				.for("abc") | 
					
						
							|  |  |  | 				.tap("JavascriptParserTest", expr => true); | 
					
						
							|  |  |  | 			testParser.hooks.canRename | 
					
						
							|  |  |  | 				.for("ijk") | 
					
						
							|  |  |  | 				.tap("JavascriptParserTest", expr => true); | 
					
						
							|  |  |  | 			testParser.hooks.call.for("abc").tap("JavascriptParserTest", expr => { | 
					
						
							| 
									
										
										
										
											2018-02-25 18:46:17 +08:00
										 |  |  | 				if (!testParser.state.abc) testParser.state.abc = []; | 
					
						
							| 
									
										
										
										
											2017-01-18 22:24:20 +08:00
										 |  |  | 				testParser.state.abc.push(testParser.parseString(expr.arguments[0])); | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 				return true; | 
					
						
							|  |  |  | 			}); | 
					
						
							| 
									
										
										
										
											2019-07-24 16:51:04 +08:00
										 |  |  | 			testParser.hooks.call.for("cde.abc").tap("JavascriptParserTest", expr => { | 
					
						
							| 
									
										
										
										
											2018-02-25 18:46:17 +08:00
										 |  |  | 				if (!testParser.state.cdeabc) testParser.state.cdeabc = []; | 
					
						
							| 
									
										
										
										
											2017-01-18 22:24:20 +08:00
										 |  |  | 				testParser.state.cdeabc.push(testParser.parseString(expr.arguments[0])); | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 				return true; | 
					
						
							|  |  |  | 			}); | 
					
						
							| 
									
										
										
										
											2019-07-24 16:51:04 +08:00
										 |  |  | 			testParser.hooks.call | 
					
						
							|  |  |  | 				.for("cde.ddd.abc") | 
					
						
							|  |  |  | 				.tap("JavascriptParserTest", expr => { | 
					
						
							|  |  |  | 					if (!testParser.state.cdedddabc) testParser.state.cdedddabc = []; | 
					
						
							|  |  |  | 					testParser.state.cdedddabc.push( | 
					
						
							|  |  |  | 						testParser.parseString(expr.arguments[0]) | 
					
						
							|  |  |  | 					); | 
					
						
							|  |  |  | 					return true; | 
					
						
							|  |  |  | 				}); | 
					
						
							|  |  |  | 			testParser.hooks.expression | 
					
						
							|  |  |  | 				.for("fgh") | 
					
						
							|  |  |  | 				.tap("JavascriptParserTest", expr => { | 
					
						
							|  |  |  | 					if (!testParser.state.fgh) testParser.state.fgh = []; | 
					
						
							|  |  |  | 					testParser.state.fgh.push( | 
					
						
							|  |  |  | 						Array.from(testParser.scope.definitions.asSet()).join(" ") | 
					
						
							|  |  |  | 					); | 
					
						
							|  |  |  | 					return true; | 
					
						
							|  |  |  | 				}); | 
					
						
							|  |  |  | 			testParser.hooks.expression | 
					
						
							|  |  |  | 				.for("fgh.sub") | 
					
						
							|  |  |  | 				.tap("JavascriptParserTest", expr => { | 
					
						
							| 
									
										
										
										
											2018-07-03 16:15:48 +08:00
										 |  |  | 					if (!testParser.state.fghsub) testParser.state.fghsub = []; | 
					
						
							|  |  |  | 					testParser.state.fghsub.push( | 
					
						
							|  |  |  | 						testParser.scope.inTry ? "try" : "notry" | 
					
						
							|  |  |  | 					); | 
					
						
							|  |  |  | 					return true; | 
					
						
							| 
									
										
										
										
											2019-07-24 16:51:04 +08:00
										 |  |  | 				}); | 
					
						
							|  |  |  | 			testParser.hooks.expression | 
					
						
							|  |  |  | 				.for("ijk.sub") | 
					
						
							|  |  |  | 				.tap("JavascriptParserTest", expr => { | 
					
						
							| 
									
										
										
										
											2018-07-03 16:15:48 +08:00
										 |  |  | 					if (!testParser.state.ijksub) testParser.state.ijksub = []; | 
					
						
							|  |  |  | 					testParser.state.ijksub.push("test"); | 
					
						
							|  |  |  | 					return true; | 
					
						
							| 
									
										
										
										
											2019-07-24 16:51:04 +08:00
										 |  |  | 				}); | 
					
						
							|  |  |  | 			testParser.hooks.expression | 
					
						
							|  |  |  | 				.for("memberExpr") | 
					
						
							|  |  |  | 				.tap("JavascriptParserTest", expr => { | 
					
						
							| 
									
										
										
										
											2018-07-03 16:15:48 +08:00
										 |  |  | 					if (!testParser.state.expressions) testParser.state.expressions = []; | 
					
						
							|  |  |  | 					testParser.state.expressions.push(expr.name); | 
					
						
							|  |  |  | 					return true; | 
					
						
							| 
									
										
										
										
											2019-07-24 16:51:04 +08:00
										 |  |  | 				}); | 
					
						
							| 
									
										
										
										
											2018-07-03 16:15:48 +08:00
										 |  |  | 			testParser.hooks.new.tap("xyz", "JavascriptParserTest", expr => { | 
					
						
							| 
									
										
										
										
											2018-02-25 18:46:17 +08:00
										 |  |  | 				if (!testParser.state.xyz) testParser.state.xyz = []; | 
					
						
							| 
									
										
										
										
											2017-12-05 10:03:50 +08:00
										 |  |  | 				testParser.state.xyz.push(testParser.parseString(expr.arguments[0])); | 
					
						
							|  |  |  | 				return true; | 
					
						
							|  |  |  | 			}); | 
					
						
							| 
									
										
										
										
											2019-11-30 03:24:13 +08:00
										 |  |  | 			const actual = testParser.parse(source, {}); | 
					
						
							| 
									
										
										
										
											2018-01-24 20:17:21 +08:00
										 |  |  | 			expect(typeof actual).toBe("object"); | 
					
						
							|  |  |  | 			expect(actual).toEqual(state); | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 		}); | 
					
						
							|  |  |  | 	}); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-18 22:24:20 +08:00
										 |  |  | 	it("should parse comments", () => { | 
					
						
							|  |  |  | 		const source = "//comment1\n/*comment2*/"; | 
					
						
							| 
									
										
										
										
											2018-02-25 18:46:17 +08:00
										 |  |  | 		const state = [ | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				type: "Line", | 
					
						
							|  |  |  | 				value: "comment1" | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				type: "Block", | 
					
						
							|  |  |  | 				value: "comment2" | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		]; | 
					
						
							| 
									
										
										
										
											2016-09-09 02:52:53 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-03 16:15:48 +08:00
										 |  |  | 		const testParser = new JavascriptParser({}); | 
					
						
							| 
									
										
										
										
											2016-09-09 02:52:53 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-03 16:15:48 +08:00
										 |  |  | 		testParser.hooks.program.tap("JavascriptParserTest", (ast, comments) => { | 
					
						
							| 
									
										
										
										
											2018-02-25 18:46:17 +08:00
										 |  |  | 			if (!testParser.state.comments) testParser.state.comments = comments; | 
					
						
							| 
									
										
										
										
											2016-09-09 02:52:53 +08:00
										 |  |  | 			return true; | 
					
						
							|  |  |  | 		}); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-30 03:24:13 +08:00
										 |  |  | 		const actual = testParser.parse(source, {}); | 
					
						
							| 
									
										
										
										
											2018-01-24 20:17:21 +08:00
										 |  |  | 		expect(typeof actual).toBe("object"); | 
					
						
							|  |  |  | 		expect(typeof actual.comments).toBe("object"); | 
					
						
							| 
									
										
										
										
											2017-01-18 22:24:20 +08:00
										 |  |  | 		actual.comments.forEach((element, index) => { | 
					
						
							| 
									
										
										
										
											2018-01-24 20:17:21 +08:00
										 |  |  | 			expect(typeof element.type).toBe("string"); | 
					
						
							|  |  |  | 			expect(typeof element.value).toBe("string"); | 
					
						
							|  |  |  | 			expect(element.type).toBe(state[index].type); | 
					
						
							|  |  |  | 			expect(element.value).toBe(state[index].value); | 
					
						
							| 
									
										
										
										
											2016-09-09 02:52:53 +08:00
										 |  |  | 		}); | 
					
						
							|  |  |  | 	}); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-18 22:24:20 +08:00
										 |  |  | 	describe("expression evaluation", () => { | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 		function evaluateInParser(source) { | 
					
						
							| 
									
										
										
										
											2018-07-03 16:15:48 +08:00
										 |  |  | 			const parser = new JavascriptParser(); | 
					
						
							| 
									
										
										
										
											2019-07-24 16:51:04 +08:00
										 |  |  | 			parser.hooks.call.for("test").tap("JavascriptParserTest", expr => { | 
					
						
							| 
									
										
										
										
											2017-01-18 22:24:20 +08:00
										 |  |  | 				parser.state.result = parser.evaluateExpression(expr.arguments[0]); | 
					
						
							| 
									
										
										
										
											2014-12-16 15:12:30 +08:00
										 |  |  | 			}); | 
					
						
							| 
									
										
										
										
											2019-07-23 15:35:25 +08:00
										 |  |  | 			parser.hooks.evaluateIdentifier | 
					
						
							|  |  |  | 				.for("aString") | 
					
						
							| 
									
										
										
										
											2019-07-24 16:51:04 +08:00
										 |  |  | 				.tap("JavascriptParserTest", expr => | 
					
						
							| 
									
										
										
										
											2018-07-03 16:15:48 +08:00
										 |  |  | 					new BasicEvaluatedExpression() | 
					
						
							|  |  |  | 						.setString("aString") | 
					
						
							|  |  |  | 						.setRange(expr.range) | 
					
						
							| 
									
										
										
										
											2019-07-23 15:35:25 +08:00
										 |  |  | 				); | 
					
						
							|  |  |  | 			parser.hooks.evaluateIdentifier | 
					
						
							|  |  |  | 				.for("b.Number") | 
					
						
							| 
									
										
										
										
											2019-07-24 16:51:04 +08:00
										 |  |  | 				.tap("JavascriptParserTest", expr => | 
					
						
							| 
									
										
										
										
											2018-07-03 16:15:48 +08:00
										 |  |  | 					new BasicEvaluatedExpression().setNumber(123).setRange(expr.range) | 
					
						
							| 
									
										
										
										
											2019-07-23 15:35:25 +08:00
										 |  |  | 				); | 
					
						
							| 
									
										
										
										
											2019-11-30 03:24:13 +08:00
										 |  |  | 			return parser.parse("test(" + source + ");", {}).result; | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-18 22:24:20 +08:00
										 |  |  | 		const testCases = { | 
					
						
							| 
									
										
										
										
											2020-03-02 19:16:36 +08:00
										 |  |  | 			true: "bool=true", | 
					
						
							|  |  |  | 			false: "bool=false", | 
					
						
							|  |  |  | 			"!true": "bool=false", | 
					
						
							|  |  |  | 			"!false": "bool=true", | 
					
						
							| 
									
										
										
										
											2018-02-25 18:46:17 +08:00
										 |  |  | 			'"strrring"': "string=strrring", | 
					
						
							|  |  |  | 			'"strr" + "ring"': "string=strrring", | 
					
						
							|  |  |  | 			'"s" + ("trr" + "rin") + "g"': "string=strrring", | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 			"'S' + (\"strr\" + \"ring\") + 'y'": "string=Sstrrringy", | 
					
						
							| 
									
										
										
										
											2017-04-13 20:52:49 +08:00
										 |  |  | 			"/abc/": "regExp=/abc/", | 
					
						
							| 
									
										
										
										
											2020-09-01 17:30:46 +08:00
										 |  |  | 			1: "number=1", | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 			"1 + 3": "number=4", | 
					
						
							| 
									
										
										
										
											2017-04-13 20:52:49 +08:00
										 |  |  | 			"3 - 1": "number=2", | 
					
						
							| 
									
										
										
										
											2017-12-06 00:11:53 +08:00
										 |  |  | 			"2 * 3": "number=6", | 
					
						
							|  |  |  | 			"8 / 2": "number=4", | 
					
						
							|  |  |  | 			"2 ** 3": "number=8", | 
					
						
							|  |  |  | 			"12 & 5": "number=4", | 
					
						
							|  |  |  | 			"12 | 5": "number=13", | 
					
						
							|  |  |  | 			"12 ^ 5": "number=9", | 
					
						
							|  |  |  | 			"9 >>> 2": "number=2", | 
					
						
							|  |  |  | 			"9 >> 2": "number=2", | 
					
						
							|  |  |  | 			"9 << 2": "number=36", | 
					
						
							|  |  |  | 			"~3": "number=-4", | 
					
						
							| 
									
										
										
										
											2017-04-13 20:52:49 +08:00
										 |  |  | 			"1 == 1": "bool=true", | 
					
						
							|  |  |  | 			"1 === 1": "bool=true", | 
					
						
							|  |  |  | 			"3 != 1": "bool=true", | 
					
						
							|  |  |  | 			"3 !== 1": "bool=true", | 
					
						
							|  |  |  | 			"3 == 1": "bool=false", | 
					
						
							|  |  |  | 			"3 === 1": "bool=false", | 
					
						
							|  |  |  | 			"1 != 1": "bool=false", | 
					
						
							|  |  |  | 			"1 !== 1": "bool=false", | 
					
						
							| 
									
										
										
										
											2020-09-01 17:30:46 +08:00
										 |  |  | 			100.25: "number=100.25", | 
					
						
							| 
									
										
										
										
											2020-03-02 21:47:04 +08:00
										 |  |  | 			"!100.25": "bool=false", | 
					
						
							|  |  |  | 			"!+100.25": "bool=false", | 
					
						
							|  |  |  | 			"!-100.25": "bool=false", | 
					
						
							| 
									
										
										
										
											2020-09-01 17:30:46 +08:00
										 |  |  | 			0: "number=0", | 
					
						
							| 
									
										
										
										
											2020-03-02 21:47:04 +08:00
										 |  |  | 			"!0": "bool=true", | 
					
						
							|  |  |  | 			"!-0": "bool=true", | 
					
						
							|  |  |  | 			"!+0": "bool=true", | 
					
						
							| 
									
										
										
										
											2020-02-29 01:09:59 +08:00
										 |  |  | 			"20n": "bigint=20", | 
					
						
							|  |  |  | 			"10n + 10n": "bigint=20", | 
					
						
							|  |  |  | 			"10n - 5n": "bigint=5", | 
					
						
							|  |  |  | 			"10n * 5n": "bigint=50", | 
					
						
							|  |  |  | 			"10n / 5n": "bigint=2", | 
					
						
							|  |  |  | 			"5n ** 2n": "bigint=25", | 
					
						
							|  |  |  | 			"5n == 5n": "bool=true", | 
					
						
							|  |  |  | 			"5n === 5n": "bool=true", | 
					
						
							|  |  |  | 			"5n != 5n": "bool=false", | 
					
						
							|  |  |  | 			"5n !== 5n": "bool=false", | 
					
						
							|  |  |  | 			"5n != 1n": "bool=true", | 
					
						
							|  |  |  | 			"5n !== 1n": "bool=true", | 
					
						
							|  |  |  | 			"5n & 3n": "bigint=1", | 
					
						
							|  |  |  | 			"5n | 2n": "bigint=7", | 
					
						
							|  |  |  | 			"5n ^ 2n": "bigint=7", | 
					
						
							|  |  |  | 			"5n >> 2n": "bigint=1", | 
					
						
							|  |  |  | 			"5n << 2n": "bigint=20", | 
					
						
							|  |  |  | 			"null == null": "bool=true", | 
					
						
							|  |  |  | 			"null === null": "bool=true", | 
					
						
							|  |  |  | 			"null != null": "bool=false", | 
					
						
							|  |  |  | 			"null !== null": "bool=false", | 
					
						
							| 
									
										
										
										
											2017-04-13 20:52:49 +08:00
										 |  |  | 			"true === false": "bool=false", | 
					
						
							|  |  |  | 			"false !== false": "bool=false", | 
					
						
							|  |  |  | 			"true == true": "bool=true", | 
					
						
							|  |  |  | 			"false != true": "bool=true", | 
					
						
							|  |  |  | 			"!'a'": "bool=false", | 
					
						
							|  |  |  | 			"!''": "bool=true", | 
					
						
							| 
									
										
										
										
											2020-03-02 19:16:36 +08:00
										 |  |  | 			"!null": "bool=true", | 
					
						
							| 
									
										
										
										
											2015-02-28 08:42:09 +08:00
										 |  |  | 			"'pre' + a": "wrapped=['pre' string=pre]+[null]", | 
					
						
							|  |  |  | 			"a + 'post'": "wrapped=[null]+['post' string=post]", | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 			"'pre' + a + 'post'": "wrapped=['pre' string=pre]+['post' string=post]", | 
					
						
							|  |  |  | 			"1 + a + 2": "", | 
					
						
							| 
									
										
										
										
											2015-02-28 08:42:09 +08:00
										 |  |  | 			"1 + a + 'post'": "wrapped=[null]+['post' string=post]", | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 			"'' + 1 + a + 2": "wrapped=['' + 1 string=1]+[2 string=2]", | 
					
						
							|  |  |  | 			"'' + 1 + a + 2 + 3": "wrapped=['' + 1 string=1]+[2 + 3 string=23]", | 
					
						
							|  |  |  | 			"'' + 1 + a + (2 + 3)": "wrapped=['' + 1 string=1]+[2 + 3 string=5]", | 
					
						
							| 
									
										
										
										
											2018-02-25 18:46:17 +08:00
										 |  |  | 			"'pre' + (1 + a) + (2 + 3)": | 
					
						
							|  |  |  | 				"wrapped=['pre' string=pre]+[2 + 3 string=5]", | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 			"a ? 'o1' : 'o2'": "options=['o1' string=o1],['o2' string=o2]", | 
					
						
							| 
									
										
										
										
											2018-02-25 18:46:17 +08:00
										 |  |  | 			"a ? 'o1' : b ? 'o2' : 'o3'": | 
					
						
							|  |  |  | 				"options=['o1' string=o1],['o2' string=o2],['o3' string=o3]", | 
					
						
							|  |  |  | 			"a ? (b ? 'o1' : 'o2') : 'o3'": | 
					
						
							|  |  |  | 				"options=['o1' string=o1],['o2' string=o2],['o3' string=o3]", | 
					
						
							|  |  |  | 			"a ? (b ? 'o1' : 'o2') : c ? 'o3' : 'o4'": | 
					
						
							|  |  |  | 				"options=['o1' string=o1],['o2' string=o2],['o3' string=o3],['o4' string=o4]", | 
					
						
							|  |  |  | 			"a ? 'o1' : b ? 'o2' : c ? 'o3' : 'o4'": | 
					
						
							|  |  |  | 				"options=['o1' string=o1],['o2' string=o2],['o3' string=o3],['o4' string=o4]", | 
					
						
							|  |  |  | 			"a ? 'o1' : b ? b : c ? 'o3' : c": | 
					
						
							|  |  |  | 				"options=['o1' string=o1],[b],['o3' string=o3],[c]", | 
					
						
							|  |  |  | 			"['i1', 'i2', 3, a, b ? 4 : 5]": | 
					
						
							|  |  |  | 				"items=['i1' string=i1],['i2' string=i2],[3 number=3],[a],[b ? 4 : 5 options=[4 number=4],[5 number=5]]", | 
					
						
							| 
									
										
										
										
											2014-12-16 15:12:30 +08:00
										 |  |  | 			"typeof 'str'": "string=string", | 
					
						
							|  |  |  | 			"typeof aString": "string=string", | 
					
						
							|  |  |  | 			"typeof b.Number": "string=number", | 
					
						
							| 
									
										
										
										
											2016-06-04 18:06:10 +08:00
										 |  |  | 			"typeof b['Number']": "string=number", | 
					
						
							| 
									
										
										
										
											2014-12-16 15:12:30 +08:00
										 |  |  | 			"typeof b[Number]": "", | 
					
						
							| 
									
										
										
										
											2020-02-29 01:09:59 +08:00
										 |  |  | 			"typeof true": "string=boolean", | 
					
						
							|  |  |  | 			"typeof null": "string=object", | 
					
						
							|  |  |  | 			"typeof 1": "string=number", | 
					
						
							|  |  |  | 			"typeof 1n": "string=bigint", | 
					
						
							| 
									
										
										
										
											2014-12-16 15:12:30 +08:00
										 |  |  | 			"b.Number": "number=123", | 
					
						
							| 
									
										
										
										
											2016-06-04 18:06:10 +08:00
										 |  |  | 			"b['Number']": "number=123", | 
					
						
							| 
									
										
										
										
											2014-12-16 15:12:30 +08:00
										 |  |  | 			"b[Number]": "", | 
					
						
							| 
									
										
										
										
											2017-09-15 02:35:33 +08:00
										 |  |  | 			"'str'.concat()": "string=str", | 
					
						
							|  |  |  | 			"'str'.concat('one')": "string=strone", | 
					
						
							|  |  |  | 			"'str'.concat('one').concat('two')": "string=stronetwo", | 
					
						
							|  |  |  | 			"'str'.concat('one').concat('two', 'three')": "string=stronetwothree", | 
					
						
							|  |  |  | 			"'str'.concat('one', 'two')": "string=stronetwo", | 
					
						
							|  |  |  | 			"'str'.concat('one', 'two').concat('three')": "string=stronetwothree", | 
					
						
							| 
									
										
										
										
											2018-02-25 18:46:17 +08:00
										 |  |  | 			"'str'.concat('one', 'two').concat('three', 'four')": | 
					
						
							|  |  |  | 				"string=stronetwothreefour", | 
					
						
							| 
									
										
										
										
											2017-09-15 02:35:33 +08:00
										 |  |  | 			"'str'.concat('one', obj)": "wrapped=['str' string=str]+[null]", | 
					
						
							|  |  |  | 			"'str'.concat('one', obj).concat()": "wrapped=['str' string=str]+[null]", | 
					
						
							| 
									
										
										
										
											2018-02-25 18:46:17 +08:00
										 |  |  | 			"'str'.concat('one', obj, 'two')": | 
					
						
							|  |  |  | 				"wrapped=['str' string=str]+['two' string=two]", | 
					
						
							|  |  |  | 			"'str'.concat('one', obj, 'two').concat()": | 
					
						
							|  |  |  | 				"wrapped=['str' string=str]+['two' string=two]", | 
					
						
							|  |  |  | 			"'str'.concat('one', obj, 'two').concat('three')": | 
					
						
							|  |  |  | 				"wrapped=['str' string=str]+['three' string=three]", | 
					
						
							| 
									
										
										
										
											2017-09-15 02:35:33 +08:00
										 |  |  | 			"'str'.concat(obj)": "wrapped=['str' string=str]+[null]", | 
					
						
							|  |  |  | 			"'str'.concat(obj).concat()": "wrapped=['str' string=str]+[null]", | 
					
						
							| 
									
										
										
										
											2018-02-25 18:46:17 +08:00
										 |  |  | 			"'str'.concat(obj).concat('one', 'two')": | 
					
						
							|  |  |  | 				"wrapped=['str' string=str]+['one', 'two' string=onetwo]", | 
					
						
							|  |  |  | 			"'str'.concat(obj).concat(obj, 'one')": | 
					
						
							|  |  |  | 				"wrapped=['str' string=str]+['one' string=one]", | 
					
						
							|  |  |  | 			"'str'.concat(obj).concat(obj, 'one', 'two')": | 
					
						
							|  |  |  | 				"wrapped=['str' string=str]+['one', 'two' string=onetwo]", | 
					
						
							|  |  |  | 			"'str'.concat(obj).concat('one', obj, 'one')": | 
					
						
							|  |  |  | 				"wrapped=['str' string=str]+['one' string=one]", | 
					
						
							|  |  |  | 			"'str'.concat(obj).concat('one', obj, 'two', 'three')": | 
					
						
							|  |  |  | 				"wrapped=['str' string=str]+['two', 'three' string=twothree]", | 
					
						
							|  |  |  | 			"'str'.concat(obj, 'one')": | 
					
						
							|  |  |  | 				"wrapped=['str' string=str]+['one' string=one]", | 
					
						
							|  |  |  | 			"'str'.concat(obj, 'one').concat()": | 
					
						
							|  |  |  | 				"wrapped=['str' string=str]+['one' string=one]", | 
					
						
							|  |  |  | 			"'str'.concat(obj, 'one').concat('two', 'three')": | 
					
						
							|  |  |  | 				"wrapped=['str' string=str]+['two', 'three' string=twothree]", | 
					
						
							|  |  |  | 			"'str'.concat(obj, 'one').concat(obj, 'two', 'three')": | 
					
						
							|  |  |  | 				"wrapped=['str' string=str]+['two', 'three' string=twothree]", | 
					
						
							|  |  |  | 			"'str'.concat(obj, 'one').concat('two', obj, 'three')": | 
					
						
							|  |  |  | 				"wrapped=['str' string=str]+['three' string=three]", | 
					
						
							|  |  |  | 			"'str'.concat(obj, 'one').concat('two', obj, 'three', 'four')": | 
					
						
							|  |  |  | 				"wrapped=['str' string=str]+['three', 'four' string=threefour]", | 
					
						
							|  |  |  | 			"'str'.concat(obj, 'one', 'two')": | 
					
						
							|  |  |  | 				"wrapped=['str' string=str]+['one', 'two' string=onetwo]", | 
					
						
							|  |  |  | 			"'str'.concat(obj, 'one', 'two').concat()": | 
					
						
							|  |  |  | 				"wrapped=['str' string=str]+['one', 'two' string=onetwo]", | 
					
						
							|  |  |  | 			"'str'.concat(obj, 'one', 'two').concat('three', 'four')": | 
					
						
							|  |  |  | 				"wrapped=['str' string=str]+['three', 'four' string=threefour]", | 
					
						
							|  |  |  | 			"'str'.concat(obj, 'one', 'two').concat(obj, 'three', 'four')": | 
					
						
							|  |  |  | 				"wrapped=['str' string=str]+['three', 'four' string=threefour]", | 
					
						
							|  |  |  | 			"'str'.concat(obj, 'one', 'two').concat('three', obj, 'four')": | 
					
						
							|  |  |  | 				"wrapped=['str' string=str]+['four' string=four]", | 
					
						
							|  |  |  | 			"'str'.concat(obj, 'one', 'two').concat('three', obj, 'four', 'five')": | 
					
						
							|  |  |  | 				"wrapped=['str' string=str]+['four', 'five' string=fourfive]", | 
					
						
							| 
									
										
										
										
											2018-04-12 02:31:43 +08:00
										 |  |  | 			// eslint-disable-next-line no-template-curly-in-string
 | 
					
						
							| 
									
										
										
										
											2018-02-25 18:46:17 +08:00
										 |  |  | 			"`start${obj}mid${obj2}end`": | 
					
						
							| 
									
										
										
										
											2018-04-12 02:31:43 +08:00
										 |  |  | 				"template=[start string=start],[mid string=mid],[end string=end]", | 
					
						
							|  |  |  | 			// eslint-disable-next-line no-template-curly-in-string
 | 
					
						
							| 
									
										
										
										
											2018-02-25 18:46:17 +08:00
										 |  |  | 			"`start${'str'}mid${obj2}end`": | 
					
						
							| 
									
										
										
										
											2018-04-12 02:31:43 +08:00
										 |  |  | 				// eslint-disable-next-line no-template-curly-in-string
 | 
					
						
							|  |  |  | 				"template=[start${'str'}mid string=startstrmid],[end string=end]", | 
					
						
							| 
									
										
										
										
											2014-12-16 15:12:30 +08:00
										 |  |  | 			"'abc'.substr(1)": "string=bc", | 
					
						
							| 
									
										
										
										
											2017-04-13 20:52:49 +08:00
										 |  |  | 			"'abcdef'.substr(2, 3)": "string=cde", | 
					
						
							|  |  |  | 			"'abcdef'.substring(2, 3)": "string=c", | 
					
						
							|  |  |  | 			"'abcdef'.substring(2, 3, 4)": "", | 
					
						
							| 
									
										
										
										
											2016-06-04 18:06:10 +08:00
										 |  |  | 			"'abc'[\"substr\"](1)": "string=bc", | 
					
						
							| 
									
										
										
										
											2014-12-16 15:12:30 +08:00
										 |  |  | 			"'abc'[substr](1)": "", | 
					
						
							| 
									
										
										
										
											2017-04-13 20:52:49 +08:00
										 |  |  | 			"'1,2+3'.split(/[,+]/)": "array=[1],[2],[3]", | 
					
						
							|  |  |  | 			"'1,2+3'.split(expr)": "", | 
					
						
							|  |  |  | 			"'a' + (expr + 'c')": "wrapped=['a' string=a]+['c' string=c]", | 
					
						
							|  |  |  | 			"1 + 'a'": "string=1a", | 
					
						
							|  |  |  | 			"'a' + 1": "string=a1", | 
					
						
							| 
									
										
										
										
											2018-02-25 18:46:17 +08:00
										 |  |  | 			"'a' + expr + 1": "wrapped=['a' string=a]+[1 string=1]" | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 		}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-25 18:46:17 +08:00
										 |  |  | 		Object.keys(testCases).forEach(key => { | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 			function evalExprToString(evalExpr) { | 
					
						
							| 
									
										
										
										
											2018-02-25 18:46:17 +08:00
										 |  |  | 				if (!evalExpr) { | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 					return "null"; | 
					
						
							|  |  |  | 				} else { | 
					
						
							| 
									
										
										
										
											2017-01-18 22:24:20 +08:00
										 |  |  | 					const result = []; | 
					
						
							| 
									
										
										
										
											2018-02-25 18:46:17 +08:00
										 |  |  | 					if (evalExpr.isString()) result.push("string=" + evalExpr.string); | 
					
						
							|  |  |  | 					if (evalExpr.isNumber()) result.push("number=" + evalExpr.number); | 
					
						
							| 
									
										
										
										
											2020-02-29 01:09:59 +08:00
										 |  |  | 					if (evalExpr.isBigInt()) result.push("bigint=" + evalExpr.bigint); | 
					
						
							| 
									
										
										
										
											2018-02-25 18:46:17 +08:00
										 |  |  | 					if (evalExpr.isBoolean()) result.push("bool=" + evalExpr.bool); | 
					
						
							|  |  |  | 					if (evalExpr.isRegExp()) result.push("regExp=" + evalExpr.regExp); | 
					
						
							|  |  |  | 					if (evalExpr.isConditional()) | 
					
						
							|  |  |  | 						result.push( | 
					
						
							|  |  |  | 							"options=[" + | 
					
						
							|  |  |  | 								evalExpr.options.map(evalExprToString).join("],[") + | 
					
						
							|  |  |  | 								"]" | 
					
						
							|  |  |  | 						); | 
					
						
							|  |  |  | 					if (evalExpr.isArray()) | 
					
						
							|  |  |  | 						result.push( | 
					
						
							|  |  |  | 							"items=[" + evalExpr.items.map(evalExprToString).join("],[") + "]" | 
					
						
							|  |  |  | 						); | 
					
						
							|  |  |  | 					if (evalExpr.isConstArray()) | 
					
						
							|  |  |  | 						result.push("array=[" + evalExpr.array.join("],[") + "]"); | 
					
						
							|  |  |  | 					if (evalExpr.isTemplateString()) | 
					
						
							|  |  |  | 						result.push( | 
					
						
							|  |  |  | 							"template=[" + | 
					
						
							|  |  |  | 								evalExpr.quasis.map(evalExprToString).join("],[") + | 
					
						
							|  |  |  | 								"]" | 
					
						
							|  |  |  | 						); | 
					
						
							|  |  |  | 					if (evalExpr.isWrapped()) | 
					
						
							|  |  |  | 						result.push( | 
					
						
							|  |  |  | 							"wrapped=[" + | 
					
						
							|  |  |  | 								evalExprToString(evalExpr.prefix) + | 
					
						
							|  |  |  | 								"]+[" + | 
					
						
							|  |  |  | 								evalExprToString(evalExpr.postfix) + | 
					
						
							|  |  |  | 								"]" | 
					
						
							|  |  |  | 						); | 
					
						
							|  |  |  | 					if (evalExpr.range) { | 
					
						
							| 
									
										
										
										
											2017-01-18 22:24:20 +08:00
										 |  |  | 						const start = evalExpr.range[0] - 5; | 
					
						
							|  |  |  | 						const end = evalExpr.range[1] - 5; | 
					
						
							| 
									
										
										
										
											2018-02-25 18:46:17 +08:00
										 |  |  | 						return ( | 
					
						
							|  |  |  | 							key.substr(start, end - start) + | 
					
						
							|  |  |  | 							(result.length > 0 ? " " + result.join(" ") : "") | 
					
						
							|  |  |  | 						); | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 					} | 
					
						
							|  |  |  | 					return result.join(" "); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2015-08-09 18:42:43 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-18 22:24:20 +08:00
										 |  |  | 			it("should eval " + key, () => { | 
					
						
							|  |  |  | 				const evalExpr = evaluateInParser(key); | 
					
						
							| 
									
										
										
										
											2018-02-25 18:46:17 +08:00
										 |  |  | 				expect(evalExprToString(evalExpr)).toBe( | 
					
						
							|  |  |  | 					testCases[key] ? key + " " + testCases[key] : key | 
					
						
							|  |  |  | 				); | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 			}); | 
					
						
							|  |  |  | 		}); | 
					
						
							|  |  |  | 	}); | 
					
						
							| 
									
										
										
										
											2016-10-31 09:48:33 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-18 22:24:20 +08:00
										 |  |  | 	describe("async/await support", () => { | 
					
						
							|  |  |  | 		describe("should accept", () => { | 
					
						
							|  |  |  | 			const cases = { | 
					
						
							| 
									
										
										
										
											2016-10-31 09:48:33 +08:00
										 |  |  | 				"async function": "async function x() {}", | 
					
						
							|  |  |  | 				"async arrow function": "async () => {}", | 
					
						
							| 
									
										
										
										
											2018-02-07 17:39:06 +08:00
										 |  |  | 				"await expression": "async function x(y) { await y }", | 
					
						
							|  |  |  | 				"await iteration": "async function f() { for await (x of xs); }" | 
					
						
							| 
									
										
										
										
											2016-10-31 09:48:33 +08:00
										 |  |  | 			}; | 
					
						
							| 
									
										
										
										
											2018-07-03 16:15:48 +08:00
										 |  |  | 			const parser = new JavascriptParser(); | 
					
						
							| 
									
										
										
										
											2018-02-25 18:46:17 +08:00
										 |  |  | 			Object.keys(cases).forEach(name => { | 
					
						
							| 
									
										
										
										
											2017-01-18 22:24:20 +08:00
										 |  |  | 				const expr = cases[name]; | 
					
						
							|  |  |  | 				it(name, () => { | 
					
						
							| 
									
										
										
										
											2019-11-30 03:24:13 +08:00
										 |  |  | 					const actual = parser.parse(expr, {}); | 
					
						
							| 
									
										
										
										
											2018-01-24 20:17:21 +08:00
										 |  |  | 					expect(typeof actual).toBe("object"); | 
					
						
							| 
									
										
										
										
											2016-10-31 09:48:33 +08:00
										 |  |  | 				}); | 
					
						
							|  |  |  | 			}); | 
					
						
							|  |  |  | 		}); | 
					
						
							| 
									
										
										
										
											2017-01-18 22:24:20 +08:00
										 |  |  | 		describe("should parse await", () => { | 
					
						
							|  |  |  | 			const cases = { | 
					
						
							| 
									
										
										
										
											2018-02-25 18:46:17 +08:00
										 |  |  | 				require: [ | 
					
						
							|  |  |  | 					"async function x() { await require('y'); }", | 
					
						
							|  |  |  | 					{ | 
					
						
							| 
									
										
										
										
											2016-10-31 09:48:33 +08:00
										 |  |  | 						param: "y" | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				], | 
					
						
							| 
									
										
										
										
											2018-02-25 18:46:17 +08:00
										 |  |  | 				import: [ | 
					
						
							|  |  |  | 					"async function x() { const y = await import('z'); }", | 
					
						
							|  |  |  | 					{ | 
					
						
							| 
									
										
										
										
											2016-10-31 09:48:33 +08:00
										 |  |  | 						param: "z" | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				] | 
					
						
							|  |  |  | 			}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-03 16:15:48 +08:00
										 |  |  | 			const parser = new JavascriptParser(); | 
					
						
							| 
									
										
										
										
											2019-07-24 16:51:04 +08:00
										 |  |  | 			parser.hooks.call.for("require").tap("JavascriptParserTest", expr => { | 
					
						
							| 
									
										
										
										
											2017-01-18 22:24:20 +08:00
										 |  |  | 				const param = parser.evaluateExpression(expr.arguments[0]); | 
					
						
							|  |  |  | 				parser.state.param = param.string; | 
					
						
							| 
									
										
										
										
											2016-10-31 09:48:33 +08:00
										 |  |  | 			}); | 
					
						
							| 
									
										
										
										
											2018-07-03 16:15:48 +08:00
										 |  |  | 			parser.hooks.importCall.tap("JavascriptParserTest", expr => { | 
					
						
							| 
									
										
										
										
											2019-08-14 20:42:07 +08:00
										 |  |  | 				const param = parser.evaluateExpression(expr.source); | 
					
						
							| 
									
										
										
										
											2017-01-18 22:24:20 +08:00
										 |  |  | 				parser.state.param = param.string; | 
					
						
							| 
									
										
										
										
											2016-10-31 09:48:33 +08:00
										 |  |  | 			}); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-25 18:46:17 +08:00
										 |  |  | 			Object.keys(cases).forEach(name => { | 
					
						
							| 
									
										
										
										
											2017-01-18 22:24:20 +08:00
										 |  |  | 				it(name, () => { | 
					
						
							| 
									
										
										
										
											2019-11-30 03:24:13 +08:00
										 |  |  | 					const actual = parser.parse(cases[name][0], {}); | 
					
						
							| 
									
										
										
										
											2018-01-24 20:17:21 +08:00
										 |  |  | 					expect(actual).toEqual(cases[name][1]); | 
					
						
							| 
									
										
										
										
											2016-10-31 09:48:33 +08:00
										 |  |  | 				}); | 
					
						
							|  |  |  | 			}); | 
					
						
							|  |  |  | 		}); | 
					
						
							| 
									
										
										
										
											2017-01-18 22:24:20 +08:00
										 |  |  | 	}); | 
					
						
							| 
									
										
										
										
											2018-02-07 17:39:06 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	describe("object rest/spread support", () => { | 
					
						
							|  |  |  | 		describe("should accept", () => { | 
					
						
							|  |  |  | 			const cases = { | 
					
						
							|  |  |  | 				"object spread": "({...obj})", | 
					
						
							|  |  |  | 				"object rest": "({...obj} = foo)" | 
					
						
							|  |  |  | 			}; | 
					
						
							| 
									
										
										
										
											2018-02-25 18:46:17 +08:00
										 |  |  | 			Object.keys(cases).forEach(name => { | 
					
						
							| 
									
										
										
										
											2018-02-07 17:39:06 +08:00
										 |  |  | 				const expr = cases[name]; | 
					
						
							|  |  |  | 				it(name, () => { | 
					
						
							| 
									
										
										
										
											2020-08-28 08:33:06 +08:00
										 |  |  | 					const actual = JavascriptParser._parse(expr, {}); | 
					
						
							| 
									
										
										
										
											2018-02-25 18:41:05 +08:00
										 |  |  | 					expect(typeof actual).toBe("object"); | 
					
						
							| 
									
										
										
										
											2018-02-07 17:39:06 +08:00
										 |  |  | 				}); | 
					
						
							|  |  |  | 			}); | 
					
						
							|  |  |  | 		}); | 
					
						
							| 
									
										
										
										
											2019-04-25 21:42:01 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		it("should collect definitions from identifiers introduced in object patterns", () => { | 
					
						
							|  |  |  | 			let definitions; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-20 20:46:31 +08:00
										 |  |  | 			const parser = new JavascriptParser(); | 
					
						
							| 
									
										
										
										
											2019-04-25 21:42:01 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-20 20:46:31 +08:00
										 |  |  | 			parser.hooks.statement.tap("JavascriptParserTest", expr => { | 
					
						
							| 
									
										
										
										
											2019-04-25 21:42:01 +08:00
										 |  |  | 				definitions = parser.scope.definitions; | 
					
						
							|  |  |  | 				return true; | 
					
						
							|  |  |  | 			}); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-30 03:24:13 +08:00
										 |  |  | 			parser.parse("const { a, ...rest } = { a: 1, b: 2 };", {}); | 
					
						
							| 
									
										
										
										
											2019-04-25 21:42:01 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			expect(definitions.has("a")).toBe(true); | 
					
						
							|  |  |  | 			expect(definitions.has("rest")).toBe(true); | 
					
						
							|  |  |  | 		}); | 
					
						
							| 
									
										
										
										
											2018-02-07 17:39:06 +08:00
										 |  |  | 	}); | 
					
						
							| 
									
										
										
										
											2018-06-04 20:03:38 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	describe("optional catch binding support", () => { | 
					
						
							|  |  |  | 		describe("should accept", () => { | 
					
						
							|  |  |  | 			const cases = { | 
					
						
							|  |  |  | 				"optional binding": "try {} catch {}" | 
					
						
							|  |  |  | 			}; | 
					
						
							|  |  |  | 			Object.keys(cases).forEach(name => { | 
					
						
							|  |  |  | 				const expr = cases[name]; | 
					
						
							|  |  |  | 				it(name, () => { | 
					
						
							| 
									
										
										
										
											2020-08-28 08:33:06 +08:00
										 |  |  | 					const actual = JavascriptParser._parse(expr); | 
					
						
							| 
									
										
										
										
											2018-06-04 20:03:38 +08:00
										 |  |  | 					expect(typeof actual).toBe("object"); | 
					
						
							|  |  |  | 				}); | 
					
						
							|  |  |  | 			}); | 
					
						
							|  |  |  | 		}); | 
					
						
							|  |  |  | 	}); | 
					
						
							| 
									
										
										
										
											2020-08-15 17:25:41 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	describe("BasicEvaluatedExpression", () => { | 
					
						
							|  |  |  | 		/** @type [string, boolean][] */ | 
					
						
							|  |  |  | 		const tests = [ | 
					
						
							|  |  |  | 			...["i", "g", "m", "y"].reduce((acc, flag) => { | 
					
						
							|  |  |  | 				acc.push([flag, true]); | 
					
						
							|  |  |  | 				acc.push([flag + flag, false]); | 
					
						
							|  |  |  | 				return acc; | 
					
						
							|  |  |  | 			}, []), | 
					
						
							|  |  |  | 			["", true], | 
					
						
							|  |  |  | 			["igm", true], | 
					
						
							|  |  |  | 			["igmy", true], | 
					
						
							|  |  |  | 			["igmyi", false], | 
					
						
							|  |  |  | 			["igmya", false], | 
					
						
							|  |  |  | 			["ai", false], | 
					
						
							|  |  |  | 			["ia", false] | 
					
						
							|  |  |  | 		]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		tests.forEach(([suite, expected]) => { | 
					
						
							|  |  |  | 			it(`BasicEvaluatedExpression.isValidRegExpFlags(${JSON.stringify( | 
					
						
							|  |  |  | 				suite | 
					
						
							|  |  |  | 			)})`, () => {
 | 
					
						
							|  |  |  | 				expect(BasicEvaluatedExpression.isValidRegExpFlags(suite)).toBe( | 
					
						
							|  |  |  | 					expected | 
					
						
							|  |  |  | 				); | 
					
						
							|  |  |  | 			}); | 
					
						
							|  |  |  | 		}); | 
					
						
							|  |  |  | 	}); | 
					
						
							| 
									
										
										
										
											2015-08-09 18:42:43 +08:00
										 |  |  | }); |