testLintConfigAndJsPlugins

tcmts.cli.test.e2e.lint.testLintConfigAndJsPlugins · #7efq3j6v · term

Lint: a lint.config definition sets rules, and the packages it imports are JS plugins.

import { setUp } from "#codebase/tcmts/cli/test/e2e/lint";
import assert from "node:assert/strict";

export const testLintConfigAndJsPlugins = () => {
  const { run, tcm, write } = setUp();
  tcm("add", "ui.tsx");
  write("cfg.ts", `// tcm: namespace lint\nimport noOnlyTests from "eslint-plugin-no-only-tests";\n\nexport const config = {\n  jsPlugins: [noOnlyTests],\n  rules: { "no-debugger": "error", "no-only-tests/no-only-tests": "error" },\n};\n`);
  assert.match(tcm("add", "cfg.ts"), /eslint-plugin-no-only-tests has no types .*typed as any/, "an untyped plugin is fine, with a warning");
  // the configuration changed, so everything is linted against it
  const r = run("lint");
  assert.equal(r.status, 1);
  assert.match(r.out, /ui\.half #\w+\n {2}2:3 {2}error {2}`debugger` statement is not allowed/);
  assert.match(r.out, /1 error\(s\), 1 warning\(s\) in 3 definition\(s\)/);

  // an error stops a save; the plugin's rule works like a built-in one
  write("only.ts", `// tcm: namespace ui\nexport const testOnly = () => {\n  const describe = { only: (_name: string, fn: () => void) => fn() };\n  describe.only("x", () => {});\n};\n`);
  const blocked = run("add", "only.ts");
  assert.notEqual(blocked.status, 0);
  assert.match(blocked.out, /4:12 {2}error {2}describe\.only not permitted no-only-tests\(no-only-tests\)/);
  assert.match(blocked.out, /only\.ts has lint errors; nothing was saved/);
  assert.match(tcm("ls", "ui"), /^(?![\s\S]*testOnly)/, "nothing was saved");
}

uses