Skip to content

Commit 8c69efb

Browse files
committed
feat(keep-unique): new command
1 parent 3b8ffd6 commit 8c69efb

22 files changed

+420
-228
lines changed

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@
9494
"bumpp": "^9.4.1",
9595
"eslint": "^9.2.0",
9696
"eslint-define-config": "^2.1.0",
97+
"eslint-vitest-rule-tester": "^0.1.1",
9798
"esno": "^4.7.0",
9899
"fast-glob": "^3.3.2",
99100
"lint-staged": "^15.2.2",

pnpm-lock.yaml

Lines changed: 15 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/commands/_test-utils.ts

Lines changed: 18 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,22 @@
1-
import { RuleTester } from 'eslint'
21
import * as tsParser from '@typescript-eslint/parser'
2+
import type { TestCase } from 'eslint-vitest-rule-tester'
3+
import { createRuleTester } from 'eslint-vitest-rule-tester'
34
import { createRuleWithCommands } from '../rule'
45
import type { Command } from '../types'
56

6-
export function d(str: TemplateStringsArray) {
7-
const lines = str[0].split('\n')
8-
const commonIndent = lines.slice(1).reduce((min, line) => {
9-
if (/^\s*$/.test(line))
10-
return min
11-
const indent = line.match(/^\s*/)?.[0].length
12-
return indent === undefined ? min : Math.min(min, indent)
13-
}, Number.POSITIVE_INFINITY)
14-
return lines.map(line => line.slice(commonIndent)).join('\n')
15-
}
16-
17-
type Arrayable<T> = T | T[]
7+
export { unindent as $ } from 'eslint-vitest-rule-tester'
188

19-
export interface TestCase extends RuleTester.ValidTestCase {
20-
output?: string | null
21-
errors?: Arrayable<string | RuleTester.TestCaseError>
22-
}
9+
export function run(command: Command | Command[], ...cases: (TestCase | string)[]) {
10+
const commands = Array.isArray(command) ? command : [command]
2311

24-
export function run(command: Command, ...cases: (TestCase | string)[]) {
25-
const ruleTester: RuleTester = new RuleTester({
26-
languageOptions: {
27-
parser: tsParser,
12+
const ruleTester = createRuleTester({
13+
name: commands[0].name,
14+
rule: createRuleWithCommands(commands) as any,
15+
configs: {
16+
languageOptions: {
17+
parser: tsParser,
18+
},
19+
files: ['**/*.ts', '**/*.js'],
2820
},
2921
})
3022

@@ -34,29 +26,12 @@ export function run(command: Command, ...cases: (TestCase | string)[]) {
3426
for (const c of cases) {
3527
if (typeof c === 'string')
3628
validCases.push(c)
37-
else if (c.errors)
38-
invalidCases.push(c)
3929
else
40-
validCases.push(c)
30+
invalidCases.push(c)
4131
}
4232

43-
ruleTester.run(
44-
command.name,
45-
createRuleWithCommands([command]) as any,
46-
{
47-
valid: validCases,
48-
invalid: invalidCases.map(i => ({
49-
...i,
50-
code: i.code,
51-
output: i.output ?? null,
52-
errors: (Array.isArray(i.errors) ? i.errors : [i.errors])
53-
.filter(notFalsy)
54-
.map(id => typeof id === 'string' ? ({ messageId: id }) : id),
55-
})),
56-
},
57-
)
58-
}
59-
60-
function notFalsy<T>(value: T): value is Exclude<T, null | undefined | false> {
61-
return !!value
33+
ruleTester.run({
34+
valid: validCases,
35+
invalid: invalidCases,
36+
})
6237
}

src/commands/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,13 @@ import { inlineArrow } from './inline-arrow'
1010
import { toPromiseAll } from './to-promise-all'
1111
import { noShorthand } from './no-shorthand'
1212
import { noType } from './no-type'
13+
import { keepUnique } from './keep-unique'
1314

1415
// @keep-sorted
1516
export {
1617
inlineArrow,
1718
keepSorted,
19+
keepUnique,
1820
noShorthand,
1921
noType,
2022
toArrow,
@@ -31,6 +33,7 @@ export {
3133
export const builtinCommands = [
3234
inlineArrow,
3335
keepSorted,
36+
keepUnique,
3437
noShorthand,
3538
noType,
3639
toArrow,

src/commands/inline-arrow.test.ts

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
11
import { inlineArrow as command } from './inline-arrow'
2-
import { d, run } from './_test-utils'
2+
import { $, run } from './_test-utils'
33

44
run(
55
command,
66
// no arrow function
77
{
8-
code: d`
8+
code: $`
99
///inline-arrow
1010
const a = 1`,
1111
output: null,
1212
errors: 'command-error',
1313
},
1414
// multi statement
1515
{
16-
code: d`
16+
code: $`
1717
/// inline-arrow
1818
export const foo = arg => {
1919
const a = 1
@@ -23,30 +23,30 @@ run(
2323
errors: 'command-error',
2424
},
2525
{
26-
code: d`
26+
code: $`
2727
/// inline-arrow
2828
export const foo = <T = 1>(arg: Z): Bar => {
2929
return arg
3030
}`,
31-
output: d`
31+
output: $`
3232
export const foo = <T = 1>(arg: Z): Bar => arg`,
3333
errors: ['command-removal', 'command-fix'],
3434
},
3535
// no return statement
3636
{
37-
code: d`
37+
code: $`
3838
///inline-arrow
3939
const foo = () => {}`,
40-
output: d`
40+
output: $`
4141
const foo = () => undefined`,
4242
errors: ['command-removal', 'command-fix'],
4343
},
4444
// without return argument
4545
{
46-
code: d`
46+
code: $`
4747
// /ia
4848
export default <T = 1>(arg: Z): Bar => { return }`,
49-
output: d`
49+
output: $`
5050
export default <T = 1>(arg: Z): Bar => undefined`,
5151
errors: ['command-removal', 'command-fix'],
5252
},

0 commit comments

Comments
 (0)