| 
									
										
										
										
											2017-10-12 14:47:17 +08:00
										 |  |  | "use strict"; | 
					
						
							| 
									
										
										
										
											2018-01-24 20:17:21 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-13 00:13:53 +08:00
										 |  |  | const { createFsFromVolume, Volume } = require("memfs"); | 
					
						
							| 
									
										
										
										
											2017-10-12 14:47:17 +08:00
										 |  |  | const ContextModuleFactory = require("../lib/ContextModuleFactory"); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-24 20:17:21 +08:00
										 |  |  | describe("ContextModuleFactory", () => { | 
					
						
							|  |  |  | 	describe("resolveDependencies", () => { | 
					
						
							| 
									
										
										
										
											2024-07-31 09:56:53 +08:00
										 |  |  | 		let factory; | 
					
						
							|  |  |  | 		let memfs; | 
					
						
							| 
									
										
										
										
											2018-01-24 20:17:21 +08:00
										 |  |  | 		beforeEach(() => { | 
					
						
							| 
									
										
										
										
											2017-10-12 14:47:17 +08:00
										 |  |  | 			factory = new ContextModuleFactory([]); | 
					
						
							| 
									
										
										
										
											2020-02-15 13:54:52 +08:00
										 |  |  | 			memfs = createFsFromVolume(new Volume()); | 
					
						
							| 
									
										
										
										
											2017-10-12 14:47:17 +08:00
										 |  |  | 		}); | 
					
						
							| 
									
										
										
										
											2018-02-25 18:46:17 +08:00
										 |  |  | 		it("should not report an error when ENOENT errors happen", done => { | 
					
						
							| 
									
										
										
										
											2017-10-12 14:47:17 +08:00
										 |  |  | 			memfs.readdir = (dir, callback) => { | 
					
						
							|  |  |  | 				setTimeout(() => callback(null, ["/file"])); | 
					
						
							|  |  |  | 			}; | 
					
						
							|  |  |  | 			memfs.stat = (file, callback) => { | 
					
						
							| 
									
										
										
										
											2024-07-31 04:09:42 +08:00
										 |  |  | 				const err = new Error("fake ENOENT error"); | 
					
						
							| 
									
										
										
										
											2017-10-12 14:47:17 +08:00
										 |  |  | 				err.code = "ENOENT"; | 
					
						
							|  |  |  | 				setTimeout(() => callback(err, null)); | 
					
						
							|  |  |  | 			}; | 
					
						
							| 
									
										
										
										
											2018-02-25 18:46:17 +08:00
										 |  |  | 			factory.resolveDependencies( | 
					
						
							|  |  |  | 				memfs, | 
					
						
							|  |  |  | 				{ | 
					
						
							|  |  |  | 					resource: "/", | 
					
						
							|  |  |  | 					recursive: true, | 
					
						
							|  |  |  | 					regExp: /.*/ | 
					
						
							|  |  |  | 				}, | 
					
						
							|  |  |  | 				(err, res) => { | 
					
						
							|  |  |  | 					expect(err).toBeFalsy(); | 
					
						
							|  |  |  | 					expect(Array.isArray(res)).toBe(true); | 
					
						
							|  |  |  | 					expect(res.length).toBe(0); | 
					
						
							|  |  |  | 					done(); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			); | 
					
						
							| 
									
										
										
										
											2017-10-12 14:47:17 +08:00
										 |  |  | 		}); | 
					
						
							| 
									
										
										
										
											2018-02-25 18:46:17 +08:00
										 |  |  | 		it("should report an error when non-ENOENT errors happen", done => { | 
					
						
							| 
									
										
										
										
											2017-10-12 14:47:17 +08:00
										 |  |  | 			memfs.readdir = (dir, callback) => { | 
					
						
							|  |  |  | 				setTimeout(() => callback(null, ["/file"])); | 
					
						
							|  |  |  | 			}; | 
					
						
							|  |  |  | 			memfs.stat = (file, callback) => { | 
					
						
							| 
									
										
										
										
											2024-07-31 04:09:42 +08:00
										 |  |  | 				const err = new Error("fake EACCES error"); | 
					
						
							| 
									
										
										
										
											2017-10-12 14:47:17 +08:00
										 |  |  | 				err.code = "EACCES"; | 
					
						
							|  |  |  | 				setTimeout(() => callback(err, null)); | 
					
						
							|  |  |  | 			}; | 
					
						
							| 
									
										
										
										
											2018-02-25 18:46:17 +08:00
										 |  |  | 			factory.resolveDependencies( | 
					
						
							|  |  |  | 				memfs, | 
					
						
							|  |  |  | 				{ | 
					
						
							|  |  |  | 					resource: "/", | 
					
						
							|  |  |  | 					recursive: true, | 
					
						
							|  |  |  | 					regExp: /.*/ | 
					
						
							|  |  |  | 				}, | 
					
						
							|  |  |  | 				(err, res) => { | 
					
						
							|  |  |  | 					expect(err).toBeInstanceOf(Error); | 
					
						
							|  |  |  | 					expect(res).toBeFalsy(); | 
					
						
							|  |  |  | 					done(); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			); | 
					
						
							| 
									
										
										
										
											2017-10-12 14:47:17 +08:00
										 |  |  | 		}); | 
					
						
							| 
									
										
										
										
											2020-09-03 00:29:45 +08:00
										 |  |  | 		it("should return callback with [] if circular symlinks exist", done => { | 
					
						
							|  |  |  | 			let statDirStatus = 0; | 
					
						
							|  |  |  | 			memfs.readdir = (dir, callback) => { | 
					
						
							|  |  |  | 				statDirStatus++; | 
					
						
							|  |  |  | 				setTimeout(() => callback(null, ["/A"])); | 
					
						
							|  |  |  | 			}; | 
					
						
							|  |  |  | 			memfs.stat = (file, callback) => { | 
					
						
							|  |  |  | 				const resolvedValue = { | 
					
						
							|  |  |  | 					isDirectory: () => statDirStatus === 1, | 
					
						
							|  |  |  | 					isFile: () => statDirStatus !== 1 | 
					
						
							|  |  |  | 				}; | 
					
						
							|  |  |  | 				setTimeout(() => callback(null, resolvedValue)); | 
					
						
							|  |  |  | 			}; | 
					
						
							|  |  |  | 			memfs.realpath = (dir, callback) => { | 
					
						
							|  |  |  | 				const realPath = dir.split("/"); | 
					
						
							|  |  |  | 				setTimeout(() => callback(null, realPath[realPath.length - 1])); | 
					
						
							|  |  |  | 			}; | 
					
						
							|  |  |  | 			factory.resolveDependencies( | 
					
						
							|  |  |  | 				memfs, | 
					
						
							|  |  |  | 				{ | 
					
						
							|  |  |  | 					resource: "/A", | 
					
						
							|  |  |  | 					recursive: true, | 
					
						
							|  |  |  | 					regExp: /.*/ | 
					
						
							|  |  |  | 				}, | 
					
						
							|  |  |  | 				(err, res) => { | 
					
						
							|  |  |  | 					expect(res).toStrictEqual([]); | 
					
						
							|  |  |  | 					done(); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			); | 
					
						
							|  |  |  | 		}); | 
					
						
							|  |  |  | 		it("should not return callback with [] if there are no circular symlinks", done => { | 
					
						
							|  |  |  | 			let statDirStatus = 0; | 
					
						
							|  |  |  | 			memfs.readdir = (dir, callback) => { | 
					
						
							|  |  |  | 				statDirStatus++; | 
					
						
							|  |  |  | 				setTimeout(() => callback(null, ["/B"])); | 
					
						
							|  |  |  | 			}; | 
					
						
							|  |  |  | 			memfs.stat = (file, callback) => { | 
					
						
							|  |  |  | 				const resolvedValue = { | 
					
						
							|  |  |  | 					isDirectory: () => statDirStatus === 1, | 
					
						
							|  |  |  | 					isFile: () => statDirStatus !== 1 | 
					
						
							|  |  |  | 				}; | 
					
						
							|  |  |  | 				setTimeout(() => callback(null, resolvedValue)); | 
					
						
							|  |  |  | 			}; | 
					
						
							|  |  |  | 			memfs.realpath = (dir, callback) => { | 
					
						
							|  |  |  | 				const realPath = dir.split("/"); | 
					
						
							|  |  |  | 				setTimeout(() => callback(null, realPath[realPath.length - 1])); | 
					
						
							|  |  |  | 			}; | 
					
						
							|  |  |  | 			factory.resolveDependencies( | 
					
						
							|  |  |  | 				memfs, | 
					
						
							|  |  |  | 				{ | 
					
						
							|  |  |  | 					resource: "/A", | 
					
						
							|  |  |  | 					recursive: true, | 
					
						
							|  |  |  | 					regExp: /.*/ | 
					
						
							|  |  |  | 				}, | 
					
						
							|  |  |  | 				(err, res) => { | 
					
						
							|  |  |  | 					expect(res).not.toStrictEqual([]); | 
					
						
							|  |  |  | 					expect(Array.isArray(res)).toBe(true); | 
					
						
							|  |  |  | 					expect(res.length).toBe(1); | 
					
						
							|  |  |  | 					done(); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			); | 
					
						
							|  |  |  | 		}); | 
					
						
							| 
									
										
										
										
											2022-02-21 16:58:44 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		it("should resolve correctly several resources", done => { | 
					
						
							|  |  |  | 			memfs.readdir = (dir, callback) => { | 
					
						
							|  |  |  | 				if (dir === "/a") setTimeout(() => callback(null, ["/B"])); | 
					
						
							|  |  |  | 				if (dir === "/b") setTimeout(() => callback(null, ["/A"])); | 
					
						
							|  |  |  | 				if (dir === "/a/B") setTimeout(() => callback(null, ["a"])); | 
					
						
							|  |  |  | 				if (dir === "/b/A") setTimeout(() => callback(null, ["b"])); | 
					
						
							|  |  |  | 			}; | 
					
						
							|  |  |  | 			memfs.stat = (file, callback) => { | 
					
						
							|  |  |  | 				const resolvedValue = { | 
					
						
							|  |  |  | 					isDirectory: () => file !== "/a/B/a" && file !== "/b/A/b", | 
					
						
							|  |  |  | 					isFile: () => file === "/a/B/a" || file === "/b/A/b" | 
					
						
							|  |  |  | 				}; | 
					
						
							|  |  |  | 				setTimeout(() => callback(null, resolvedValue)); | 
					
						
							|  |  |  | 			}; | 
					
						
							|  |  |  | 			memfs.realpath = undefined; | 
					
						
							|  |  |  | 			factory.resolveDependencies( | 
					
						
							|  |  |  | 				memfs, | 
					
						
							|  |  |  | 				{ | 
					
						
							|  |  |  | 					resource: ["/a", "/b"], | 
					
						
							|  |  |  | 					resourceFragment: "#hash", | 
					
						
							|  |  |  | 					resourceQuery: "?query", | 
					
						
							|  |  |  | 					recursive: true, | 
					
						
							|  |  |  | 					regExp: /.*/ | 
					
						
							|  |  |  | 				}, | 
					
						
							|  |  |  | 				(err, res) => { | 
					
						
							|  |  |  | 					expect(res).not.toStrictEqual([]); | 
					
						
							|  |  |  | 					expect(Array.isArray(res)).toBe(true); | 
					
						
							|  |  |  | 					expect(res.map(r => r.request)).toEqual([ | 
					
						
							| 
									
										
										
										
											2022-03-25 21:28:18 +08:00
										 |  |  | 						"./B/a?query#hash", | 
					
						
							|  |  |  | 						"./A/b?query#hash" | 
					
						
							| 
									
										
										
										
											2022-02-21 16:58:44 +08:00
										 |  |  | 					]); | 
					
						
							| 
									
										
										
										
											2022-03-25 21:28:18 +08:00
										 |  |  | 					expect(res.map(r => r.getContext())).toEqual(["/a", "/b"]); | 
					
						
							| 
									
										
										
										
											2022-02-21 16:58:44 +08:00
										 |  |  | 					expect(res.map(r => r.userRequest)).toEqual(["./B/a", "./A/b"]); | 
					
						
							|  |  |  | 					done(); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			); | 
					
						
							|  |  |  | 		}); | 
					
						
							| 
									
										
										
										
											2017-10-12 14:47:17 +08:00
										 |  |  | 	}); | 
					
						
							|  |  |  | }); |