UNPKG

stylelint-vitest-rule-tester

Version:

Styelint rule tester with Vitest.

342 lines (341 loc) 9.92 kB
import { Awaitable, unindent } from "@ntnyq/utils"; import stylelint, { LinterOptions } from "stylelint"; import { Warning } from "postcss"; //#region src/types/stylelint.d.ts type StylelintLinterResult = Omit<stylelint.LinterResult, 'cwd' | 'report'>; /** * @pg */ type LintResultDeprecation = { text: string; reference?: string; }; type LintResultInvalidOptionWarning = { text: string; }; type LintResultParseError = Warning & { stylelintType: 'parseError'; }; type LintResultWarning = stylelint.Warning; /** * @pg */ type LintResultMessage = LintResultDeprecation | LintResultInvalidOptionWarning | LintResultParseError | LintResultWarning; /** * Stylelint options */ interface StylelintOptions<RuleOptions = any> { /** * linter options for `stylelint.lint(options)` */ linterOptions?: stylelint.LinterOptions; /** * rule options */ ruleOptions?: RuleOptions; /** * stylelint config */ stylelintConfig?: stylelint.Config; } //#endregion //#region src/types/test.d.ts /** * Test case options */ interface TestCasesOptions<RuleOptions = any> { /** * invalid cases */ invalid?: (string | InvalidTestCase<RuleOptions>)[]; /** * valid cases */ valid?: (string | ValidTestCase<RuleOptions>)[]; /** * callback to be called after each test case */ onResult?: (testCase: NormalizedTestCase<RuleOptions>, result: TestExecutionResult) => Promise<void> | void; } /** * Test execution result */ type TestExecutionResult = StylelintLinterResult & { /** * whether the code was fixed */ fixed?: boolean; /** * if the rule fixes in multiple steps, the result of each step is present here */ steps?: StylelintLinterResult[]; }; //#endregion //#region src/types/file.d.ts /** * default filename when not provided */ interface DefaultFilenames { css: string; less: string; postcss: string; sass: string; scss: string; styl: string; stylus: string; [key: string]: string; } //#endregion //#region src/types/tester.d.ts /** * Rule tester behavior options */ type RuleTesterBehaviorOptions = { /** * the number of times to recursively apply the rule * * @default 10 */ recursive?: false | number; /** * run verification after applying the fix * * @default true */ verifyAfterFix?: boolean; /** * verify that fix allways changes the code * * @default true */ verifyFixChanges?: boolean; }; /** * Rule tester init options */ type RuleTesterInitOptions<RuleOptions = any> = RuleTesterBehaviorOptions & StylelintOptions<RuleOptions> & { /** * rule name to test */ name: string; /** * default filenames to be used for tests */ defaultFileNames?: Partial<DefaultFilenames>; }; /** * Rule Tester * @pg */ interface RuleTester<RuleOptions = any> { /** * run multiple test cases */ run: (options: TestCasesOptions<RuleOptions>) => Promise<void>; /** * run a single test case */ each: (arg: TestCase) => Promise<{ result: TestExecutionResult; testcase: NormalizedTestCase<RuleOptions>; }>; /** * run a single invalid test case */ invalid: (arg: InvalidTestCase) => Promise<{ result: TestExecutionResult; testcase: NormalizedTestCase<RuleOptions>; }>; /** * run a single valid test case */ valid: (arg: ValidTestCase) => Promise<{ result: TestExecutionResult; testcase: NormalizedTestCase<RuleOptions>; }>; } //#endregion //#region src/types/case.d.ts /** * Invalid test case */ type InvalidTestCase<RuleOptions = any> = string | InvalidTestCaseBase<RuleOptions>; type InvalidTestCaseBase<RuleOptions = any> = ValidTestCaseBase<RuleOptions> & { /** * expect for {@link LintResultDeprecation} */ deprecations?: number | (string | LintResultDeprecation)[] | ((deprecations: LintResultDeprecation[]) => Awaitable<void>); /** * expect for {@link LintResultInvalidOptionWarning} */ invalidOptionWarnings?: number | (string | LintResultInvalidOptionWarning)[] | ((invalidOptionWarnings: LintResultInvalidOptionWarning[]) => Awaitable<void>); /** * Assert if output is expected. * Pass `null` to assert that the output is the same as the input. */ output?: string | ((output: string, input: string) => Awaitable<void>) | null; /** * expect for {@link LintResultParseError} */ parseErrors?: number | (string | LintResultParseError)[] | ((parseErrors: LintResultParseError[]) => Awaitable<void>); /** * expect for {@link LintResultWarning} */ warnings?: number | (string | LintResultWarning)[] | ((warnings: LintResultWarning[]) => Awaitable<void>); }; /** * Valid test case */ type ValidTestCase<RuleOptions = any> = string | ValidTestCaseBase<RuleOptions>; type ValidTestCaseBase<RuleOptions = any> = RuleTesterBehaviorOptions & StylelintOptions<RuleOptions> & { /** * code to test */ code: string; /** * test case description */ description?: string; /** * test case filename */ filename?: string; /** * test case name */ name?: string; /** * only run this test case */ only?: boolean; /** * skip this test case */ skip?: boolean; /** * hook after run test case */ after?: (this: NormalizedTestCase<RuleOptions>, result: TestExecutionResult) => Awaitable<void>; /** * hook before run test case */ before?: (this: NormalizedTestCase<RuleOptions>, linterOptions: LinterOptions) => Awaitable<void>; }; /** * Test case * @pg */ type TestCase<RuleOptions = any> = InvalidTestCase<RuleOptions> | ValidTestCase<RuleOptions>; /** * Normalized test case * @pg */ type NormalizedTestCase<RuleOptions = any> = InvalidTestCaseBase<RuleOptions> & { code: string; filename: string; type: 'invalid' | 'valid'; }; //#endregion //#region src/run.d.ts /** * Shortcut to run test cases for a rule */ declare function run<RuleOptions = any>(options: TestCasesOptions<RuleOptions> & RuleTesterInitOptions<RuleOptions>): Promise<void>; /** * Shortcut to run test cases for a rule in classic style */ declare function runClassic<RuleOptions = any>(ruleName: string, cases: TestCasesOptions<RuleOptions>, options?: RuleTesterInitOptions<RuleOptions>): Promise<void>; //#endregion //#region src/utils/resolveRuleMeta.d.ts /** * Resolve rule meta by tester options * @param options - tester options * @returns a promise resolved rule meta or undefined */ declare function resolveRuleMeta(options: RuleTesterInitOptions): Promise<stylelint.RuleMeta | undefined>; //#endregion //#region src/utils/normalizeTestCase.d.ts /** * Normalize test case * * @param testCase - test case * @param defaultFilenames - given default file name * @param type - case type * @returns normalized test case */ declare function normalizeTestCase<RuleOptions = any>(testCase: TestCase<RuleOptions>, defaultFilenames: Partial<DefaultFilenames>, type?: 'valid' | 'invalid'): NormalizedTestCase<RuleOptions>; //#endregion //#region src/utils/resolveRuleOptions.d.ts /** * Normalize rule options * * @param testCase - test case * @param options - tester options * @returns normalized rule option */ declare function resolveRuleOptions(testCase: NormalizedTestCase, options: RuleTesterInitOptions, ruleMeta?: stylelint.RuleMeta): any[]; //#endregion //#region src/utils/validateLintResult.d.ts declare function validateLintResult(testCase: NormalizedTestCase, lintResult: stylelint.LintResult): Promise<void>; //#endregion //#region src/utils/normalizeCaseMessage.d.ts /** * Normalize test case message * * @param message - message string or lint result * @returns normalized message */ declare function normalizeCaseMessage(message: string | LintResultMessage): Partial<LintResultMessage>; //#endregion //#region src/utils/resolveLinterOptions.d.ts /** * Resolve linter options of stylelint * * @param options - tester init options * @param testCase - normalized test case * @returns resolved linter options */ declare function resolveLinterOptions(options: RuleTesterInitOptions, testCase: NormalizedTestCase, ruleOptions: any): stylelint.LinterOptions; //#endregion //#region src/utils/normalizeLinterResult.d.ts /** * Normalize linter result * * @param result - linter result {@link Stylelint.LinterResult} */ declare function normalizeLinterResult(result: stylelint.LinterResult): { results: { deprecations: { text: string; reference?: string; }[]; invalidOptionWarnings: { text: string; }[]; parseErrors: (import("postcss").Warning & { stylelintType: Extract<stylelint.StylelintWarningType, "parseError">; })[]; errored?: boolean; warnings: stylelint.Warning[]; ignored?: boolean; autofixed?: boolean; }[]; errored: boolean; code?: string; maxWarningsExceeded?: { maxWarnings: number; foundWarnings: number; }; reportedDisables: stylelint.DisableOptionsReport; descriptionlessDisables?: stylelint.DisableOptionsReport; needlessDisables?: stylelint.DisableOptionsReport; invalidScopeDisables?: stylelint.DisableOptionsReport; ruleMetadata: { [ruleName: string]: Partial<stylelint.RuleMeta>; }; }; //#endregion //#region src/tester.d.ts declare function createRuleTester<RuleOptions = any>(options: RuleTesterInitOptions<RuleOptions>): RuleTester<RuleOptions>; //#endregion export { unindent as $, unindent, DefaultFilenames, InvalidTestCase, InvalidTestCaseBase, LintResultDeprecation, LintResultInvalidOptionWarning, LintResultMessage, LintResultParseError, LintResultWarning, NormalizedTestCase, RuleTester, RuleTesterBehaviorOptions, RuleTesterInitOptions, StylelintLinterResult, StylelintOptions, TestCase, TestCasesOptions, TestExecutionResult, ValidTestCase, ValidTestCaseBase, createRuleTester, normalizeCaseMessage, normalizeLinterResult, normalizeTestCase, resolveLinterOptions, resolveRuleMeta, resolveRuleOptions, run, runClassic, validateLintResult };