@@ -183,12 +183,123 @@ describe('util/requireHook', () => {
183183 const pattern = requireHook . buildFileNamePattern ( [ 'node_modules' , 'express' , 'lib' , 'express.js' ] ) ;
184184 requireHook . onFileLoad ( pattern , hook ) ;
185185
186- expect ( require ( 'express' ) ) . to . be . a ( 'function' ) ;
186+ // Require the specific file that matches the pattern, not just 'express'
187+ // which loads index.js. This ensures the pattern is tested against the actual file.
188+ expect ( require ( 'express/lib/express' ) ) . to . be . a ( 'function' ) ;
187189
188190 expect ( hook . callCount ) . to . equal ( 1 ) ;
189191 expect ( hook . getCall ( 0 ) . args [ 0 ] ) . to . be . a ( 'function' ) ;
190192 expect ( hook . getCall ( 0 ) . args [ 0 ] . name ) . to . equal ( 'createApplication' ) ;
191193 } ) ;
192194 } ) ;
195+
196+ it ( 'must handle Windows paths with backslashes in onFileLoad patterns' , ( ) => {
197+ const testModule = { test : 'module' } ;
198+ const windowsPath =
199+ 'C:\\Users\\aryamohanan\\Desktop\\code\\mongo-app\\node_modules\\mongodb-core\\lib\\connection\\pool.js' ;
200+
201+ // Create a function that will be captured as origLoad
202+ const originalLoad = function ( ) {
203+ return testModule ;
204+ } ;
205+
206+ // Create a mock Module that will be used when requireHook loads
207+ const mockModule = {
208+ _load : originalLoad ,
209+ _resolveFilename : function ( ) {
210+ return windowsPath ;
211+ }
212+ } ;
213+
214+ // Use proxyquire to inject the mocked Module before requireHook loads
215+ const requireHookWithMock = proxyquire ( '../../../src/util/requireHook' , {
216+ module : mockModule
217+ } ) ;
218+
219+ requireHookWithMock . init ( { logger : testUtils . createFakeLogger ( ) } ) ;
220+ // Use a pattern similar to mongodb.js that expects forward slashes
221+ requireHookWithMock . onFileLoad ( / \/ m o n g o d b - c o r e \/ l i b \/ c o n n e c t i o n \/ p o o l \. j s / , hook ) ;
222+
223+ // After init(), mockModule._load is now patchedModuleLoad
224+ // Call it with a Windows absolute path - this should trigger the pattern match
225+ const result = mockModule . _load (
226+ 'C:\\Users\\aryamohanan\\Desktop\\code\\mongo-app\\node_modules\\mongodb-core\\lib\\connection\\pool.js'
227+ ) ;
228+
229+ // Verify the hook was called despite Windows path separators
230+ expect ( hook . callCount ) . to . equal ( 1 ) ;
231+ expect ( hook . getCall ( 0 ) . args [ 0 ] ) . to . deep . equal ( testModule ) ;
232+ expect ( hook . getCall ( 0 ) . args [ 1 ] ) . to . equal ( windowsPath ) ;
233+ expect ( result ) . to . deep . equal ( testModule ) ;
234+
235+ requireHookWithMock . teardownForTestPurposes ( ) ;
236+ } ) ;
237+
238+ it ( 'must extract module name correctly from Windows paths in onModuleLoad' , ( ) => {
239+ const path = require ( 'path' ) ;
240+ const testMssqlModule = { test : 'mssql-module' } ;
241+ // Use a Windows path that will be normalized and matched
242+ // On non-Windows systems, path.isAbsolute() may return false for Windows paths,
243+ // so we need to ensure the path is treated as absolute in the test
244+ const windowsPath = 'C:\\Users\\aryamohanan\\Desktop\\code\\mongo-app\\node_modules\\mssql\\lib\\index.js' ;
245+ const windowsModuleName = 'C:\\Users\\aryamohanan\\Desktop\\code\\mongo-app\\node_modules\\mssql\\lib\\index.js' ;
246+
247+ // Store the originalLoad function reference so we can ensure same object is returned
248+ let loadCallCount = 0 ;
249+ const originalLoad = function ( ) {
250+ loadCallCount ++ ;
251+ // Must return the same object reference each time to pass cache check
252+ return testMssqlModule ;
253+ } ;
254+
255+ // Create a mock Module that will be used when requireHook loads
256+ const mockModule = {
257+ _load : originalLoad ,
258+ _resolveFilename : function ( ) {
259+ // _resolveFilename receives the same arguments as _load was called with
260+ return windowsPath ;
261+ }
262+ } ;
263+
264+ // Mock path.isAbsolute to return true for Windows paths (even on non-Windows systems)
265+ const pathMock = {
266+ isAbsolute : function ( p ) {
267+ // Treat Windows absolute paths (C:\, D:\, etc.) as absolute
268+ if ( / ^ [ A - Z a - z ] : [ \\ / ] / . test ( p ) ) {
269+ return true ;
270+ }
271+ return path . isAbsolute ( p ) ;
272+ } ,
273+ extname : path . extname ,
274+ sep : path . sep
275+ } ;
276+
277+ // Use proxyquire to inject the mocked Module and path before requireHook loads
278+ const requireHookWithMock = proxyquire ( '../../../src/util/requireHook' , {
279+ module : mockModule ,
280+ path : pathMock
281+ } ) ;
282+
283+ requireHookWithMock . init ( { logger : testUtils . createFakeLogger ( ) } ) ;
284+ // Register hook for mssql module (similar to mssql.js)
285+ requireHookWithMock . onModuleLoad ( 'mssql' , hook ) ;
286+
287+ // After init(), mockModule._load is replaced with patchedModuleLoad
288+ // When we call it, patchedModuleLoad will:
289+ // 1. Extract module name from Windows path: 'C:\...\node_modules\mssql\lib\index.js' -> 'mssql'
290+ // 2. Call origLoad (our mock) which returns testMssqlModule
291+ // 3. Call _resolveFilename which returns windowsPath
292+ // 4. Check byModuleNameTransformers['mssql'] and call the hook
293+ const result = mockModule . _load ( windowsModuleName ) ;
294+
295+ // Verify origLoad was called
296+ expect ( loadCallCount ) . to . equal ( 1 ) ;
297+ // Verify the hook was called (module name 'mssql' should be extracted from Windows path)
298+ expect ( hook . callCount ) . to . equal ( 1 ) ;
299+ expect ( hook . getCall ( 0 ) . args [ 0 ] ) . to . deep . equal ( testMssqlModule ) ;
300+ expect ( result ) . to . deep . equal ( testMssqlModule ) ;
301+
302+ requireHookWithMock . teardownForTestPurposes ( ) ;
303+ } ) ;
193304 } ) ;
194305} ) ;
0 commit comments