1
+ import { describe , it , expect , vi , beforeEach , afterEach } from 'vitest'
2
+ import type { ResolvedResult } from 'eslint-import-context'
3
+
4
+ vi . mock ( 'eslint-import-context' , ( ) => {
5
+ let mockContext : { cwd ?: string } | null = null
6
+
7
+ return {
8
+ useRuleContext : vi . fn ( ( ) => mockContext ) ,
9
+ __setMockContext : ( context : { cwd ?: string } | null ) => {
10
+ mockContext = context
11
+ } ,
12
+ __getMockContext : ( ) => mockContext ,
13
+ }
14
+ } )
15
+
16
+ import { resolve , createTypeScriptImportResolver } from 'eslint-import-resolver-typescript'
17
+ import { useRuleContext } from 'eslint-import-context'
18
+
19
+ const mockModule = await import ( 'eslint-import-context' ) as any
20
+
21
+ describe ( 'Context-aware import resolution' , ( ) => {
22
+ const originalCwd = process . cwd ( )
23
+ const testCwd1 = '/test/project1'
24
+ const testCwd2 = '/test/project2'
25
+
26
+ beforeEach ( ( ) => {
27
+ vi . clearAllMocks ( )
28
+ mockModule . __setMockContext ( null )
29
+ } )
30
+
31
+ afterEach ( ( ) => {
32
+ mockModule . __setMockContext ( null )
33
+ } )
34
+
35
+ describe ( 'Dynamic cwd resolution' , ( ) => {
36
+ it ( 'should use context.cwd when available' , ( ) => {
37
+ const mockResolve = vi . fn ( ) . mockReturnValue ( { found : false } as ResolvedResult )
38
+ const mockResolverFactory = vi . fn ( ) . mockImplementation ( ( ) => ( { sync : mockResolve } ) )
39
+ vi . doMock ( 'unrs-resolver' , ( ) => ( { ResolverFactory : mockResolverFactory } ) )
40
+
41
+ mockModule . __setMockContext ( { cwd : testCwd1 } )
42
+
43
+ resolve ( 'some-module' , '/test/file.ts' , { } )
44
+
45
+ expect ( useRuleContext ) . toHaveBeenCalled ( )
46
+ expect ( mockResolve ) . toHaveBeenCalled ( )
47
+ } )
48
+
49
+ it ( 'should fallback to process.cwd() when context is null' , ( ) => {
50
+ const mockResolve = vi . fn ( ) . mockReturnValue ( { found : false } as ResolvedResult )
51
+ const mockResolverFactory = vi . fn ( ) . mockImplementation ( ( ) => ( { sync : mockResolve } ) )
52
+ vi . doMock ( 'unrs-resolver' , ( ) => ( { ResolverFactory : mockResolverFactory } ) )
53
+
54
+ mockModule . __setMockContext ( null )
55
+
56
+ resolve ( 'some-module' , '/test/file.ts' , { } )
57
+
58
+ expect ( useRuleContext ) . toHaveBeenCalled ( )
59
+ expect ( mockResolve ) . toHaveBeenCalled ( )
60
+ } )
61
+
62
+ it ( 'should fallback to process.cwd() when context.cwd is undefined' , ( ) => {
63
+ const mockResolve = vi . fn ( ) . mockReturnValue ( { found : false } as ResolvedResult )
64
+ const mockResolverFactory = vi . fn ( ) . mockImplementation ( ( ) => ( { sync : mockResolve } ) )
65
+ vi . doMock ( 'unrs-resolver' , ( ) => ( { ResolverFactory : mockResolverFactory } ) )
66
+
67
+ mockModule . __setMockContext ( { } )
68
+
69
+ resolve ( 'some-module' , '/test/file.ts' , { } )
70
+
71
+ expect ( useRuleContext ) . toHaveBeenCalled ( )
72
+ expect ( mockResolve ) . toHaveBeenCalled ( )
73
+ } )
74
+ } )
75
+
76
+ describe ( 'Cache key generation' , ( ) => {
77
+ it ( 'should generate cache key with null character separator' , ( ) => {
78
+ const mockResolverFactory = vi . fn ( )
79
+ vi . doMock ( 'unrs-resolver' , ( ) => ( {
80
+ ResolverFactory : mockResolverFactory . mockImplementation ( ( ) => ( {
81
+ sync : vi . fn ( ) . mockReturnValue ( { found : false } as ResolvedResult )
82
+ } ) )
83
+ } ) )
84
+
85
+ mockModule . __setMockContext ( { cwd : testCwd1 } )
86
+
87
+ resolve ( 'some-module' , '/test/file.ts' , { } )
88
+
89
+ expect ( mockResolverFactory ) . toHaveBeenCalledTimes ( 1 )
90
+ } )
91
+
92
+ it ( 'should create separate cache entries for different cwd values' , ( ) => {
93
+ const mockResolverFactory = vi . fn ( )
94
+ vi . doMock ( 'unrs-resolver' , ( ) => ( {
95
+ ResolverFactory : mockResolverFactory . mockImplementation ( ( ) => ( {
96
+ sync : vi . fn ( ) . mockReturnValue ( { found : false } as ResolvedResult )
97
+ } ) )
98
+ } ) )
99
+
100
+ // First resolution with testCwd1
101
+ mockModule . __setMockContext ( { cwd : testCwd1 } )
102
+ resolve ( 'some-module' , '/test/file.ts' , { } )
103
+
104
+ // Second resolution with testCwd2 should create new resolver
105
+ mockModule . __setMockContext ( { cwd : testCwd2 } )
106
+ resolve ( 'some-module' , '/test/file.ts' , { } )
107
+
108
+ expect ( mockResolverFactory ) . toHaveBeenCalledTimes ( 2 )
109
+ } )
110
+
111
+ it ( 'should reuse cache for same cwd and options' , ( ) => {
112
+ const mockResolverFactory = vi . fn ( )
113
+ vi . doMock ( 'unrs-resolver' , ( ) => ( {
114
+ ResolverFactory : mockResolverFactory . mockImplementation ( ( ) => ( {
115
+ sync : vi . fn ( ) . mockReturnValue ( { found : false } as ResolvedResult )
116
+ } ) )
117
+ } ) )
118
+
119
+ mockModule . __setMockContext ( { cwd : testCwd1 } )
120
+
121
+ resolve ( 'some-module' , '/test/file1.ts' , { } )
122
+ resolve ( 'another-module' , '/test/file2.ts' , { } )
123
+
124
+ expect ( mockResolverFactory ) . toHaveBeenCalledTimes ( 1 )
125
+ } )
126
+ } )
127
+
128
+ describe ( 'createTypeScriptImportResolver context switching' , ( ) => {
129
+ it ( 'should update cwd and recreate resolver when context changes' , ( ) => {
130
+ const mockResolverFactory = vi . fn ( )
131
+ const mockCloneWithOptions = vi . fn ( )
132
+
133
+ const mockResolver = {
134
+ sync : vi . fn ( ) . mockReturnValue ( { found : false } as ResolvedResult ) ,
135
+ cloneWithOptions : mockCloneWithOptions
136
+ }
137
+
138
+ vi . doMock ( 'unrs-resolver' , ( ) => ( {
139
+ ResolverFactory : mockResolverFactory . mockImplementation ( ( ) => mockResolver )
140
+ } ) )
141
+
142
+ mockModule . __setMockContext ( null )
143
+ const resolver = createTypeScriptImportResolver ( { project : [ './tsconfig.json' ] } )
144
+
145
+ resolver . resolve ( 'some-module' , '/test/file.ts' )
146
+
147
+ mockModule . __setMockContext ( { cwd : testCwd1 } )
148
+ resolver . resolve ( 'another-module' , '/test/file.ts' )
149
+
150
+ expect ( useRuleContext ) . toHaveBeenCalledTimes ( 2 )
151
+ expect ( mockCloneWithOptions ) . toHaveBeenCalled ( )
152
+ } )
153
+
154
+ it ( 'should create new resolver when no existing resolver and context changes' , ( ) => {
155
+ const mockResolverFactory = vi . fn ( )
156
+
157
+ const mockResolver = {
158
+ sync : vi . fn ( ) . mockReturnValue ( { found : false } as ResolvedResult )
159
+ }
160
+
161
+ vi . doMock ( 'unrs-resolver' , ( ) => ( {
162
+ ResolverFactory : mockResolverFactory . mockImplementation ( ( ) => mockResolver )
163
+ } ) )
164
+
165
+ mockModule . __setMockContext ( null )
166
+ const resolver = createTypeScriptImportResolver ( { project : [ './tsconfig.json' ] } )
167
+
168
+ mockModule . __setMockContext ( { cwd : testCwd1 } )
169
+ resolver . resolve ( 'some-module' , '/test/file.ts' )
170
+
171
+ expect ( mockResolverFactory ) . toHaveBeenCalled ( )
172
+ } )
173
+
174
+ it ( 'should not recreate resolver when cwd remains the same' , ( ) => {
175
+ const mockResolverFactory = vi . fn ( )
176
+ const mockCloneWithOptions = vi . fn ( )
177
+
178
+ const mockResolver = {
179
+ sync : vi . fn ( ) . mockReturnValue ( { found : false } as ResolvedResult ) ,
180
+ cloneWithOptions : mockCloneWithOptions
181
+ }
182
+
183
+ vi . doMock ( 'unrs-resolver' , ( ) => ( {
184
+ ResolverFactory : mockResolverFactory . mockImplementation ( ( ) => mockResolver )
185
+ } ) )
186
+
187
+ mockModule . __setMockContext ( { cwd : testCwd1 } )
188
+ const resolver = createTypeScriptImportResolver ( { project : [ './tsconfig.json' ] } )
189
+
190
+ resolver . resolve ( 'some-module' , '/test/file1.ts' )
191
+ resolver . resolve ( 'another-module' , '/test/file2.ts' )
192
+
193
+ expect ( useRuleContext ) . toHaveBeenCalledTimes ( 2 )
194
+ expect ( mockCloneWithOptions ) . not . toHaveBeenCalled ( )
195
+ } )
196
+
197
+ it ( 'should handle interfaceVersion and name properties correctly' , ( ) => {
198
+ mockModule . __setMockContext ( null )
199
+ const resolver = createTypeScriptImportResolver ( )
200
+
201
+ expect ( resolver . interfaceVersion ) . toBe ( 3 )
202
+ expect ( resolver . name ) . toBe ( 'eslint-import-resolver-typescript' )
203
+ } )
204
+ } )
205
+
206
+ describe ( 'Function signature compatibility' , ( ) => {
207
+ it ( 'should handle optional parameters correctly in resolve function' , ( ) => {
208
+ mockModule . __setMockContext ( { cwd : testCwd1 } )
209
+
210
+ expect ( ( ) => resolve ( 'module' , '/file.ts' , { } , null ) ) . not . toThrow ( )
211
+ expect ( ( ) => resolve ( 'module' , '/file.ts' ) ) . not . toThrow ( )
212
+ expect ( ( ) => resolve ( 'module' , '/file.ts' , undefined ) ) . not . toThrow ( )
213
+ } )
214
+
215
+ it ( 'should handle optional parameters correctly in createTypeScriptImportResolver' , ( ) => {
216
+ mockModule . __setMockContext ( null )
217
+
218
+ expect ( ( ) => createTypeScriptImportResolver ( { } ) ) . not . toThrow ( )
219
+ expect ( ( ) => createTypeScriptImportResolver ( ) ) . not . toThrow ( )
220
+ expect ( ( ) => createTypeScriptImportResolver ( null ) ) . not . toThrow ( )
221
+ } )
222
+ } )
223
+ } )
0 commit comments