1import type { CreateRule, Fix, Fixer, Visitor } from "@oxlint/plugins"
2
3export interface ReportedError {
4 node: unknown
5 message: string
6 fix?: (fixer: Pick<Fixer, "replaceTextRange">) => Fix
7}
8
9export interface TestContextOptions {
10 sourceCode?: string
11 filename?: string
12 cwd?: string
13 ruleOptions?: Array<unknown>
14}
15
16export const createTestContext = (options: TestContextOptions = {}) => {
17 const {
18 sourceCode = "",
19 filename = "/test/file.ts",
20 cwd = "/test",
21 ruleOptions = []
22 } = options
23
24 const errors: Array<ReportedError> = []
25 const context = {
26 id: "test/rule",
27 filename,
28 physicalFilename: filename,
29 cwd,
30 options: ruleOptions,
31 getFilename: () => filename,
32 getCwd: () => cwd,
33 report(reportOptions: ReportedError) {
34 errors.push(reportOptions)
35 },
36 sourceCode: {
37 text: sourceCode,
38 getText(node?: { range?: [number, number] } | null) {
39 if (node?.range) {
40 return sourceCode.slice(node.range[0], node.range[1])
41 }
42 return sourceCode
43 }
44 }
45 }
46 return { errors, context }
47}
48
49export const runRule = (
50 rule: CreateRule,
51 visitor: keyof Visitor,
52 node: unknown,
53 options: TestContextOptions = {}
54): Array<ReportedError> => {
55 const { context, errors } = createTestContext(options)
56 const visitors = rule.create(context as never)
57 const handler = visitors[visitor]
58 if (handler) {
59 ;(handler as (node: unknown) => void)(node)
60 }
61 return errors
62}