Skip to content

Commit fc3090c

Browse files
committed
Add testing framework
1 parent af4b5c0 commit fc3090c

File tree

4 files changed

+62
-2
lines changed

4 files changed

+62
-2
lines changed

validator/README.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ If all is well, the output will be minimal, and the process will exit cleanly.
2525

2626
ESLint also maintains [integrations](https://eslint.org/docs/latest/use/integrations#editors) for most common code editors to provide instant inline feedback as you modify files.
2727

28-
## Writing new linter rules
28+
## Writing custom rules
2929

3030
Each rule should be written in a separate JavaScript file (e.g. `single-key-dictionary-key-is-string.js`) following the format of a custom rule [as defined by the typescript-eslint docs](https://typescript-eslint.io/developers/custom-rules).
3131
Within a rule's `create` function, return an object whose keys are the names of [AST node types](https://typescript-eslint.io/packages/typescript-estree/ast-spec) and whose values are functions that validate that node type.
@@ -35,6 +35,13 @@ To get a familiar the different node types possible within a TypeScript AST, pas
3535

3636
To add your rule to the spec validator ESLint plugin, import it into [the plugin file](./eslint-plugin-es-spec.js) and add it to the `rules` object with an appropriate key.
3737

38+
### Unit testing rules
39+
40+
Add a file `<your rule name>.test.js` to the `test/` directory, and construct your test using the [typescript-eslint `RuleTester`](https://typescript-eslint.io/packages/rule-tester/) format.
41+
42+
To run the entire test suite, run `npm test`.
43+
To run just one test file, run `npm test -- test/your-file.js`
44+
3845
### ESM format
3946

4047
The validator project is written in standard JavaScript rather than TypeScript, and uses the new [ESM](https://nodejs.org/api/esm.html) module format for managing module imports and exports.

validator/package.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
"main": "eslint-plugin-es-spec.js",
66
"type": "module",
77
"scripts": {
8-
"test": "echo \"Error: no test specified\" && exit 1"
8+
"test": "node --import ./test/_setup.js --test"
99
},
1010
"peerDependencies": {
1111
"eslint": ">=9.0.0"
@@ -15,5 +15,8 @@
1515
"dependencies": {
1616
"@typescript-eslint/utils": "^8.32.1",
1717
"typescript": "^5.8.3"
18+
},
19+
"devDependencies": {
20+
"@typescript-eslint/rule-tester": "^8.32.1"
1821
}
1922
}

validator/test/_setup.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import * as test from 'node:test'
2+
import { RuleTester } from '@typescript-eslint/rule-tester'
3+
4+
RuleTester.afterAll = test.after
5+
RuleTester.describe = test.describe
6+
RuleTester.it = test.it
7+
RuleTester.itOnly = test.it.only
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import { RuleTester } from '@typescript-eslint/rule-tester'
2+
import rule from '../rules/single-key-dictionary-key-is-string.js'
3+
4+
const ruleTester = new RuleTester({
5+
languageOptions: {
6+
parserOptions: {
7+
projectService: {
8+
allowDefaultProject: ['*.ts*'],
9+
},
10+
tsconfigRootDir: import.meta.dirname,
11+
},
12+
},
13+
})
14+
15+
ruleTester.run('single-key-dictionary-key-is-string', rule, {
16+
valid: [
17+
`type MyDict = SingleKeyDictionary<string, object>`,
18+
`type MyDict = SingleKeyDictionary<string, any>`,
19+
`type MyDict = SingleKeyDictionary<string, number>`,
20+
`enum MyEnum { foo, bar, baz }
21+
type MyDict = SingleKeyDictionary<MyEnum, object>`,
22+
],
23+
invalid: [
24+
{
25+
code:
26+
`type MyKey = string | boolean
27+
type MyDict = SingleKeyDictionary<MyKey, any>`,
28+
errors: [{ messageId: 'stringKey' }]
29+
},
30+
{
31+
code: `type MyDict = SingleKeyDictionary<string | number, any>`,
32+
errors: [{ messageId: 'stringKey' }]
33+
},
34+
{
35+
code: `type MyDict = SingleKeyDictionary<boolean, any>`,
36+
errors: [{ messageId: 'stringKey' }]
37+
},
38+
{
39+
code: `type MyDict = SingleKeyDictionary<object, any>`,
40+
errors: [{ messageId: 'stringKey' }]
41+
}
42+
],
43+
})

0 commit comments

Comments
 (0)