Skip to content

Commit

Permalink
Using rule tester hooks (#35)
Browse files Browse the repository at this point in the history
* Using canary build of typescript-eslint.

* REF: using native RuleTester instead of custom TestRunner.

* Minor: naming.
  • Loading branch information
Anna Bocharova authored Oct 13, 2024
1 parent 5085619 commit b0bf341
Show file tree
Hide file tree
Showing 6 changed files with 125 additions and 166 deletions.
Binary file modified bun.lockb
Binary file not shown.
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,13 +53,13 @@
"@types/bun": "latest",
"@types/ramda": "^0.30.2",
"@types/semver": "^7.5.8",
"@typescript-eslint/rule-tester": "^8.8.1",
"@typescript-eslint/rule-tester": "^8.8.2-alpha.12",
"eslint": "^9.12.0",
"json-schema-to-ts": "^3.1.1",
"semver": "^7.6.3",
"tsup": "^8.3.0",
"typescript": "^5.6.3",
"typescript-eslint": "^8.8.1"
"typescript-eslint": "^8.8.2-alpha.12"
},
"peerDependencies": {
"eslint": "^9.0.0",
Expand Down
219 changes: 123 additions & 96 deletions src/rule.spec.ts
Original file line number Diff line number Diff line change
@@ -1,101 +1,128 @@
import { afterAll, describe, it } from "bun:test";
import parser from "@typescript-eslint/parser";
import { RuleTester } from "@typescript-eslint/rule-tester";
import { readerMock } from "../mocks/fs.ts";
import { Runner } from "../test-runner";
import { rule } from "./rule";

const makeSetup = (env: object) => () =>
const makeBefore = (env: object) => () =>
readerMock.mockReturnValueOnce(JSON.stringify(env));

new Runner("dependencies", rule, {
// Valid
"regular import of prod dependency": {
code: `import {} from "eslint"`,
setup: makeSetup({ dependencies: { eslint: "" } }),
},
"regular import of explicitly enabled prod dependencies": {
code: `import {} from "eslint"`,
options: [{ production: true }],
setup: makeSetup({ dependencies: { eslint: "" } }),
},
"regular import of required peer dependency": {
code: `import {} from "eslint"`,
setup: makeSetup({ peerDependencies: { eslint: "" } }),
},
"type import of optional peer dependency": {
code: `import type {} from "eslint"`,
setup: makeSetup({
peerDependencies: { eslint: "" },
peerDependenciesMeta: { eslint: { optional: true } },
}),
},
"type import of unlisted type only dependency": {
code: `import type {} from "eslint"`,
options: [{ typeOnly: ["eslint"] }],
setup: makeSetup({ dependencies: {} }),
},
"type import of prod dependency": {
code: `import type {} from "eslint"`,
setup: makeSetup({ dependencies: { eslint: "" } }),
},
"import a path of prod dependency": {
code: `import {} from "eslint/something/useful.js"`,
setup: makeSetup({ dependencies: { eslint: "" } }),
},
"import of scoped required peer dependency": {
code: `import {} from "@eslint/js/something"`,
setup: makeSetup({ peerDependencies: { "@eslint/js": "" } }),
},
"import of local path": {
code: `import {} from "./some/path.js"`,
setup: makeSetup({}),
},
"import of built-in module": {
code: `import { readFileSync } from "node:fs"`,
setup: makeSetup({}),
},
"import of something explicitly ignored by regex": {
code: `import {} from "fancy-module"`,
options: [{ ignore: ["^fancy-\\w+$"] }],
setup: makeSetup({}),
},
// Invalid
"regular import of unlisted dependency": {
code: `import {} from "eslint"`,
setup: makeSetup({ dependencies: {} }),
errors: [{ messageId: "prohibited" }],
},
"regular import of explicitly disabled prod dependency": {
code: `import {} from "eslint"`,
options: [{ production: false }],
setup: makeSetup({ dependencies: { eslint: "" } }),
errors: [{ messageId: "prohibited" }],
},
"regular import of optional peer dependency": {
code: `import {} from "eslint"`,
setup: makeSetup({
peerDependencies: { eslint: "" },
peerDependenciesMeta: { eslint: { optional: true } },
}),
errors: [{ messageId: "typeOnly" }],
},
"regular import of unlisted type only dependency": {
code: `import {} from "eslint"`,
options: [{ typeOnly: ["eslint"] }],
setup: makeSetup({}),
errors: [{ messageId: "typeOnly" }],
},
"import of built-in module when missing in ignore list": {
code: `import {} from "node:fs"`,
options: [{ ignore: ["^fancy-\\w+$"] }],
setup: makeSetup({}),
errors: [{ messageId: "prohibited" }],
},
demo: {
code: `import {factory} from "typescript"; import {format} from "prettier";`,
setup: makeSetup({
devDependencies: { typescript: "^5" },
peerDependencies: { prettier: "^3" },
peerDependenciesMeta: { prettier: { optional: true } },
}),
errors: [{ messageId: "prohibited" }, { messageId: "typeOnly" }],
},
}).run();
RuleTester.afterAll = afterAll;
RuleTester.describe = describe;
RuleTester.it = it;

const tester = new RuleTester({ languageOptions: { parser } });

tester.run("dependencies", rule, {
valid: [
{
name: "regular import of prod dependency",
code: `import {} from "eslint"`,
before: makeBefore({ dependencies: { eslint: "" } }),
},
{
name: "regular import of explicitly enabled prod dependencies",
code: `import {} from "eslint"`,
options: [{ production: true }],
before: makeBefore({ dependencies: { eslint: "" } }),
},
{
name: "regular import of required peer dependency",
code: `import {} from "eslint"`,
before: makeBefore({ peerDependencies: { eslint: "" } }),
},
{
name: "type import of optional peer dependency",
code: `import type {} from "eslint"`,
before: makeBefore({
peerDependencies: { eslint: "" },
peerDependenciesMeta: { eslint: { optional: true } },
}),
},
{
name: "type import of unlisted type only dependency",
code: `import type {} from "eslint"`,
options: [{ typeOnly: ["eslint"] }],
before: makeBefore({ dependencies: {} }),
},
{
name: "type import of prod dependency",
code: `import type {} from "eslint"`,
before: makeBefore({ dependencies: { eslint: "" } }),
},
{
name: "import a path of prod dependency",
code: `import {} from "eslint/something/useful.js"`,
before: makeBefore({ dependencies: { eslint: "" } }),
},
{
name: "import of scoped required peer dependency",
code: `import {} from "@eslint/js/something"`,
before: makeBefore({ peerDependencies: { "@eslint/js": "" } }),
},
{
name: "import of local path",
code: `import {} from "./some/path.js"`,
before: makeBefore({}),
},
{
name: "import of built-in module",
code: `import { readFileSync } from "node:fs"`,
before: makeBefore({}),
},
{
name: "import of something explicitly ignored by regex",
code: `import {} from "fancy-module"`,
options: [{ ignore: ["^fancy-\\w+$"] }],
before: makeBefore({}),
},
],
invalid: [
{
name: "regular import of unlisted dependency",
code: `import {} from "eslint"`,
before: makeBefore({ dependencies: {} }),
errors: [{ messageId: "prohibited" }],
},
{
name: "regular import of explicitly disabled prod dependency",
code: `import {} from "eslint"`,
options: [{ production: false }],
before: makeBefore({ dependencies: { eslint: "" } }),
errors: [{ messageId: "prohibited" }],
},
{
name: "regular import of optional peer dependency",
code: `import {} from "eslint"`,
before: makeBefore({
peerDependencies: { eslint: "" },
peerDependenciesMeta: { eslint: { optional: true } },
}),
errors: [{ messageId: "typeOnly" }],
},
{
name: "regular import of unlisted type only dependency",
code: `import {} from "eslint"`,
options: [{ typeOnly: ["eslint"] }],
before: makeBefore({}),
errors: [{ messageId: "typeOnly" }],
},
{
name: "import of built-in module when missing in ignore list",
code: `import {} from "node:fs"`,
options: [{ ignore: ["^fancy-\\w+$"] }],
before: makeBefore({}),
errors: [{ messageId: "prohibited" }],
},
{
name: "demo",
code: `import {factory} from "typescript"; import {format} from "prettier";`,
before: makeBefore({
devDependencies: { typescript: "^5" },
peerDependencies: { prettier: "^3" },
peerDependenciesMeta: { prettier: { optional: true } },
}),
errors: [{ messageId: "prohibited" }, { messageId: "typeOnly" }],
},
],
});
19 changes: 0 additions & 19 deletions test-runner/helpers.ts

This file was deleted.

35 changes: 0 additions & 35 deletions test-runner/index.ts

This file was deleted.

14 changes: 0 additions & 14 deletions test-runner/types.ts

This file was deleted.

0 comments on commit b0bf341

Please sign in to comment.