Skip to content

Commit f856d09

Browse files
📝 CodeRabbit Chat: Add unit test file context-aware.spec.ts
1 parent 2b346d7 commit f856d09

File tree

1 file changed

+223
-0
lines changed

1 file changed

+223
-0
lines changed

tests/unit/context-aware.spec.ts

Lines changed: 223 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,223 @@
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

Comments
 (0)