Tools live under tools/<role>/<domain> (checks, generate, release, ci, dev), every tool is a workspace named @open-pencil/<domain>-tools, a shared tools/tsconfig.json backs the new check:tools gate that fixed 55 latent type errors, test:tools runs through bun --filter, the placement check is its own checks/test-homes package, and every tool resolves the repository through resolveWorkspaceRoot. Bun, Node, and mdast types live in a tools-root workspace so they never reach the app program.
34 lines
1.4 KiB
TypeScript
34 lines
1.4 KiB
TypeScript
import { describe, expect, test } from 'bun:test'
|
|
|
|
import { lint, ruleDiagnostics } from './helpers/lint.ts'
|
|
|
|
const rule = 'no-module-mocking'
|
|
const rules = { [`open-pencil/${rule}`]: 'error' }
|
|
|
|
describe('no-module-mocking', () => {
|
|
test.each([
|
|
"vi.mock('./store')",
|
|
"jest['doMock']('./store')",
|
|
"jest.unstable_mockModule('./store')",
|
|
"import { vi as testAPI } from 'vitest'; testAPI.mock('./store')",
|
|
"import { jest } from '@jest/globals'; jest.mock('./store')",
|
|
"import { mock } from 'bun:test'; mock.module('./store', () => ({}))",
|
|
"import { jest } from 'bun:test'; jest.mock('./store')",
|
|
"import { jest as testAPI } from 'bun:test'; testAPI.mock('./store')",
|
|
"import { vitest } from 'vitest'; vitest.mock('./store')",
|
|
"import { mock as bunMock } from 'bun:test'; bunMock['module']('./store', () => ({}))"
|
|
])('rejects module registry mocking: %s', async (source) => {
|
|
expect(ruleDiagnostics(await lint(source, rules), rule)).toHaveLength(1)
|
|
})
|
|
|
|
test.each([
|
|
"vi.spyOn(store, 'save')",
|
|
'const vi = { mock() {} }; vi.mock()',
|
|
'function test(jest: { mock(): void }) { jest.mock() }',
|
|
"import { vi as localVi } from './helpers'; localVi.mock('./store')",
|
|
'const mock = { module() {} }; mock.module()'
|
|
])('accepts scoped replacements and shadowed framework names: %s', async (source) => {
|
|
expect(ruleDiagnostics(await lint(source, rules), rule)).toHaveLength(0)
|
|
})
|
|
})
|