Skip to content

📝 CodeRabbit Chat: Add unit test file context-aware.spec.ts #454

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
256 changes: 256 additions & 0 deletions tests/unit/context-aware.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,256 @@
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'
import type { ResolvedResult } from 'eslint-import-context'

vi.mock('eslint-import-context', () => {
let mockContext: { cwd?: string } | null = null

return {
useRuleContext: vi.fn(() => mockContext),
__setMockContext: (context: { cwd?: string } | null) => {
mockContext = context
},
__getMockContext: () => mockContext,
}
})

import {
resolve,
createTypeScriptImportResolver,
} from 'eslint-import-resolver-typescript'
import { useRuleContext } from 'eslint-import-context'

const mockModule = (await import('eslint-import-context')) as any

describe('Context-aware import resolution', () => {
const originalCwd = process.cwd()

Check failure on line 25 in tests/unit/context-aware.spec.ts

View workflow job for this annotation

GitHub Actions / Lint and Test with Node.js 20 on windows-latest

'originalCwd' is declared but its value is never read.

Check failure on line 25 in tests/unit/context-aware.spec.ts

View workflow job for this annotation

GitHub Actions / Lint and Test with Node.js 20 on windows-latest

'originalCwd' is declared but its value is never read.

Check failure on line 25 in tests/unit/context-aware.spec.ts

View workflow job for this annotation

GitHub Actions / Lint and Test with Node.js 18 on windows-latest

'originalCwd' is declared but its value is never read.

Check failure on line 25 in tests/unit/context-aware.spec.ts

View workflow job for this annotation

GitHub Actions / Lint and Test with Node.js 22 on windows-latest

'originalCwd' is declared but its value is never read.

Check failure on line 25 in tests/unit/context-aware.spec.ts

View workflow job for this annotation

GitHub Actions / Lint and Test with Node.js 22 on ubuntu-latest

'originalCwd' is declared but its value is never read.
const testCwd1 = '/test/project1'
const testCwd2 = '/test/project2'

beforeEach(() => {
vi.clearAllMocks()
mockModule.__setMockContext(null)
})

afterEach(() => {
mockModule.__setMockContext(null)
})

describe('Dynamic cwd resolution', () => {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@coderabbitai CI is broken.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are on the CodeRabbit Free Plan. In order to use the Chat feature, please upgrade to CodeRabbit Pro.

it('should use context.cwd when available', () => {
const mockResolve = vi
.fn()
.mockReturnValue({ found: false } as ResolvedResult)
const mockResolverFactory = vi
.fn()
.mockImplementation(() => ({ sync: mockResolve }))
vi.doMock('unrs-resolver', () => ({
ResolverFactory: mockResolverFactory,
}))

mockModule.__setMockContext({ cwd: testCwd1 })

resolve('some-module', '/test/file.ts', {})

expect(useRuleContext).toHaveBeenCalled()
expect(mockResolve).toHaveBeenCalled()
})

it('should fallback to process.cwd() when context is null', () => {
const mockResolve = vi
.fn()
.mockReturnValue({ found: false } as ResolvedResult)
const mockResolverFactory = vi
.fn()
.mockImplementation(() => ({ sync: mockResolve }))
vi.doMock('unrs-resolver', () => ({
ResolverFactory: mockResolverFactory,
}))

mockModule.__setMockContext(null)

resolve('some-module', '/test/file.ts', {})

expect(useRuleContext).toHaveBeenCalled()
expect(mockResolve).toHaveBeenCalled()
})

it('should fallback to process.cwd() when context.cwd is undefined', () => {
const mockResolve = vi
.fn()
.mockReturnValue({ found: false } as ResolvedResult)
const mockResolverFactory = vi
.fn()
.mockImplementation(() => ({ sync: mockResolve }))
vi.doMock('unrs-resolver', () => ({
ResolverFactory: mockResolverFactory,
}))

mockModule.__setMockContext({})

resolve('some-module', '/test/file.ts', {})

expect(useRuleContext).toHaveBeenCalled()
expect(mockResolve).toHaveBeenCalled()
})
})

describe('Cache key generation', () => {
it('should generate cache key with null character separator', () => {
const mockResolverFactory = vi.fn()
vi.doMock('unrs-resolver', () => ({
ResolverFactory: mockResolverFactory.mockImplementation(() => ({
sync: vi.fn().mockReturnValue({ found: false } as ResolvedResult),
})),
}))

mockModule.__setMockContext({ cwd: testCwd1 })

resolve('some-module', '/test/file.ts', {})

expect(mockResolverFactory).toHaveBeenCalledTimes(1)
})

it('should create separate cache entries for different cwd values', () => {
const mockResolverFactory = vi.fn()
vi.doMock('unrs-resolver', () => ({
ResolverFactory: mockResolverFactory.mockImplementation(() => ({
sync: vi.fn().mockReturnValue({ found: false } as ResolvedResult),
})),
}))

// First resolution with testCwd1
mockModule.__setMockContext({ cwd: testCwd1 })
resolve('some-module', '/test/file.ts', {})

// Second resolution with testCwd2 should create new resolver
mockModule.__setMockContext({ cwd: testCwd2 })
resolve('some-module', '/test/file.ts', {})

expect(mockResolverFactory).toHaveBeenCalledTimes(2)
})

it('should reuse cache for same cwd and options', () => {
const mockResolverFactory = vi.fn()
vi.doMock('unrs-resolver', () => ({
ResolverFactory: mockResolverFactory.mockImplementation(() => ({
sync: vi.fn().mockReturnValue({ found: false } as ResolvedResult),
})),
}))

mockModule.__setMockContext({ cwd: testCwd1 })

resolve('some-module', '/test/file1.ts', {})
resolve('another-module', '/test/file2.ts', {})

expect(mockResolverFactory).toHaveBeenCalledTimes(1)
})
})

describe('createTypeScriptImportResolver context switching', () => {
it('should update cwd and recreate resolver when context changes', () => {
const mockResolverFactory = vi.fn()
const mockCloneWithOptions = vi.fn()

const mockResolver = {
sync: vi.fn().mockReturnValue({ found: false } as ResolvedResult),
cloneWithOptions: mockCloneWithOptions,
}

vi.doMock('unrs-resolver', () => ({
ResolverFactory: mockResolverFactory.mockImplementation(
() => mockResolver,
),
}))

mockModule.__setMockContext(null)
const resolver = createTypeScriptImportResolver({
project: ['./tsconfig.json'],
})

resolver.resolve('some-module', '/test/file.ts')

mockModule.__setMockContext({ cwd: testCwd1 })
resolver.resolve('another-module', '/test/file.ts')

expect(useRuleContext).toHaveBeenCalledTimes(2)
expect(mockCloneWithOptions).toHaveBeenCalled()
})

it('should create new resolver when no existing resolver and context changes', () => {
const mockResolverFactory = vi.fn()

const mockResolver = {
sync: vi.fn().mockReturnValue({ found: false } as ResolvedResult),
}

vi.doMock('unrs-resolver', () => ({
ResolverFactory: mockResolverFactory.mockImplementation(
() => mockResolver,
),
}))

mockModule.__setMockContext(null)
const resolver = createTypeScriptImportResolver({
project: ['./tsconfig.json'],
})

mockModule.__setMockContext({ cwd: testCwd1 })
resolver.resolve('some-module', '/test/file.ts')

expect(mockResolverFactory).toHaveBeenCalled()
})

it('should not recreate resolver when cwd remains the same', () => {
const mockResolverFactory = vi.fn()
const mockCloneWithOptions = vi.fn()

const mockResolver = {
sync: vi.fn().mockReturnValue({ found: false } as ResolvedResult),
cloneWithOptions: mockCloneWithOptions,
}

vi.doMock('unrs-resolver', () => ({
ResolverFactory: mockResolverFactory.mockImplementation(
() => mockResolver,
),
}))

mockModule.__setMockContext({ cwd: testCwd1 })
const resolver = createTypeScriptImportResolver({
project: ['./tsconfig.json'],
})

resolver.resolve('some-module', '/test/file1.ts')
resolver.resolve('another-module', '/test/file2.ts')

expect(useRuleContext).toHaveBeenCalledTimes(2)
expect(mockCloneWithOptions).not.toHaveBeenCalled()
})

it('should handle interfaceVersion and name properties correctly', () => {
mockModule.__setMockContext(null)
const resolver = createTypeScriptImportResolver()

expect(resolver.interfaceVersion).toBe(3)
expect(resolver.name).toBe('eslint-import-resolver-typescript')
})
})

describe('Function signature compatibility', () => {
it('should handle optional parameters correctly in resolve function', () => {
mockModule.__setMockContext({ cwd: testCwd1 })

expect(() => resolve('module', '/file.ts', {}, null)).not.toThrow()
expect(() => resolve('module', '/file.ts')).not.toThrow()
expect(() => resolve('module', '/file.ts', undefined)).not.toThrow()
})

it('should handle optional parameters correctly in createTypeScriptImportResolver', () => {
mockModule.__setMockContext(null)

expect(() => createTypeScriptImportResolver({})).not.toThrow()
expect(() => createTypeScriptImportResolver()).not.toThrow()
expect(() => createTypeScriptImportResolver(null)).not.toThrow()
})
})
})
Loading