UNPKG

vitest-stylelint-utils

Version:
135 lines (133 loc) 4.51 kB
import util from "node:util"; import stylelint from "stylelint"; import { describe, expect, it } from "vitest"; //#region src/get-test-rule.ts const { lint } = stylelint; /** * Create a `testRule()` function with any specified plugins. */ function getTestRule(options = {}) { return function testRule(schema) { describe(`${schema.ruleName}`, () => { const stylelintConfig = { plugins: options.plugins || schema.plugins, rules: { [schema.ruleName]: schema.config } }; setupTestCases({ name: "accept", cases: schema.accept, schema, comparisons(testCase) { return async function() { const stylelintOptions = { code: testCase.code, config: stylelintConfig, customSyntax: schema.customSyntax, codeFilename: schema.codeFilename }; const output = await lint(stylelintOptions); expect(output.results[0].warnings).toEqual([]); expect(output.results[0].parseErrors).toEqual([]); expect(output.results[0].invalidOptionWarnings).toEqual([]); if (!schema.fix) return; const outputAfterFix = await lint({ ...stylelintOptions, fix: true }); const fixedCode = getOutputCss(outputAfterFix); expect(fixedCode).toBe(testCase.code); }; } }); setupTestCases({ name: "reject", cases: schema.reject, schema, comparisons(testCase) { return async function() { const stylelintOptions = { code: testCase.code, config: stylelintConfig, customSyntax: schema.customSyntax, codeFilename: schema.codeFilename }; const outputAfterLint = await lint(stylelintOptions); const actualWarnings = [...outputAfterLint.results[0].invalidOptionWarnings, ...outputAfterLint.results[0].warnings]; expect(outputAfterLint.results[0]).toMatchObject({ parseErrors: [] }); expect(actualWarnings).toHaveLength(testCase.warnings ? testCase.warnings.length : 1); const warnings = testCase.warnings || [testCase]; warnings.forEach((warning, index) => { expect(warning.message, "Expected \"reject\" test case to have a \"message\" property").toBeDefined(); const expectedWarning = { text: warning.message, line: warning.line, column: warning.column, endLine: warning.endLine, endColumn: warning.endColumn }; Object.entries(expectedWarning).forEach(([key, value]) => { if (value === void 0) delete expectedWarning[key]; }); expect(actualWarnings[index]).toMatchObject(expectedWarning); }); if (!schema.fix) return; if (schema.fix && !testCase.fixed && testCase.fixed !== "" && !testCase.unfixable) throw new Error("If using { fix: true } in test schema, all reject cases must have { fixed: .. }"); const outputAfterFix = await lint({ ...stylelintOptions, fix: true }); const fixedCode = getOutputCss(outputAfterFix); if (testCase.unfixable) { if (testCase.fixed) expect(fixedCode).toBe(testCase.fixed); expect(fixedCode).toBe(testCase.code); } else { expect(fixedCode).toBe(testCase.fixed); expect(fixedCode).not.toBe(testCase.code); } const outputAfterLintOnFixedCode = await lint({ ...stylelintOptions, code: fixedCode, fix: testCase.unfixable }); expect(outputAfterLintOnFixedCode.results[0]).toMatchObject({ warnings: outputAfterFix.results[0].warnings, parseErrors: [] }); }; } }); }); }; } function setupTestCases({ name, cases, schema, comparisons }) { if (cases && cases.length > 0) { const testGroup = (() => { if (schema.only) return describe.only; if (schema.skip) return describe.skip; return describe; })(); testGroup(`${name}`, () => { cases.forEach((testCase) => { if (testCase) { const spec = (() => { if (testCase.only) return it.only; if (testCase.skip) return it.skip; return it; })(); describe(`${util.inspect(schema.config)}`, () => { describe(`${util.inspect(testCase.code)}`, () => { spec(testCase.description || "no description", comparisons(testCase)); }); }); } }); }); } } function getOutputCss(output) { const result = output.results[0]._postcssResult; if (result && result.root && result.opts) return result.root.toString(result.opts.syntax); throw new TypeError("Invalid result"); } //#endregion export { getTestRule };