Skip to content

Commit

Permalink
feat: add element value pattern filter for properties in sort-classes
Browse files Browse the repository at this point in the history
  • Loading branch information
hugop95 authored Oct 8, 2024
1 parent 7dfcb8e commit 4e7e5ad
Show file tree
Hide file tree
Showing 5 changed files with 116 additions and 2 deletions.
3 changes: 3 additions & 0 deletions docs/content/rules/sort-classes.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -491,6 +491,7 @@ interface CustomGroupDefinition {
selector?: string
modifiers?: string[]
elementNamePattern?: string
elementValuePattern?: string
decoratorNamePattern?: string
}
```
Expand All @@ -507,6 +508,7 @@ interface CustomGroupBlockDefinition {
selector?: string
modifiers?: string[]
elementNamePattern?: string
elementValuePattern?: string
decoratorNamePattern?: string
}>
}
Expand All @@ -520,6 +522,7 @@ A class member will match a `CustomGroupBlockDefinition` group if it matches all
- `selector`: Filter on the `selector` of the element.
- `modifiers`: Filter on the `modifiers` of the element. (All the modifiers of the element must be present in that list)
- `elementNamePattern`: If entered, will check that the name of the element matches the pattern entered.
- `elementValuePattern`: Only for non-function properties. If entered, will check that the value of the property matches the pattern entered.
- `decoratorNamePattern`: If entered, will check that at least one `decorator` matches the pattern entered.
- `type`: Overrides the sort type for that custom group. `unsorted` will not sort the group.
- `order`: Overrides the sort order for that custom group
Expand Down
15 changes: 15 additions & 0 deletions rules/sort-classes-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { matches } from '../utils/matches'

interface CustomGroupMatchesProps {
customGroup: SingleCustomGroup | CustomGroupBlock
elementValue: undefined | string
matcher: 'minimatch' | 'regex'
selectors: Selector[]
modifiers: Modifier[]
Expand Down Expand Up @@ -195,6 +196,20 @@ export const customGroupMatches = (props: CustomGroupMatchesProps): boolean => {
}
}

if (
'elementValuePattern' in props.customGroup &&
props.customGroup.elementValuePattern
) {
let matchesElementValuePattern: boolean = matches(
props.elementValue ?? '',
props.customGroup.elementValuePattern,
props.matcher,
)
if (!matchesElementValuePattern) {
return false
}
}

if (
'decoratorNamePattern' in props.customGroup &&
props.customGroup.decoratorNamePattern
Expand Down
10 changes: 8 additions & 2 deletions rules/sort-classes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -428,6 +428,7 @@ export default createEslintRule<SortClassesOptions, MESSAGE_ID>({
}
}

let memberValue: undefined | string
let modifiers: Modifier[] = []
let selectors: Selector[] = []
if (
Expand Down Expand Up @@ -568,6 +569,10 @@ export default createEslintRule<SortClassesOptions, MESSAGE_ID>({
selectors.push('function-property')
}

if (!isFunctionProperty && member.value) {
memberValue = sourceCode.getText(member.value)
}

selectors.push('property')

if (
Expand All @@ -593,6 +598,7 @@ export default createEslintRule<SortClassesOptions, MESSAGE_ID>({
customGroupMatches({
customGroup,
elementName: name,
elementValue: memberValue,
modifiers,
selectors,
decorators,
Expand All @@ -619,7 +625,7 @@ export default createEslintRule<SortClassesOptions, MESSAGE_ID>({
.find(overloadSignatures => overloadSignatures.includes(member))
?.at(-1)

let value: SortingNodeWithDependencies = {
let sortingNode: SortingNodeWithDependencies = {
size: overloadSignatureGroupMember
? rangeToDiff(overloadSignatureGroupMember.range)
: rangeToDiff(member.range),
Expand All @@ -633,7 +639,7 @@ export default createEslintRule<SortClassesOptions, MESSAGE_ID>({
),
}

accumulator.at(-1)!.push(value)
accumulator.at(-1)!.push(sortingNode)

return accumulator
},
Expand Down
5 changes: 5 additions & 0 deletions rules/sort-classes.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ interface BaseSingleCustomGroup<T extends Selector> {

type AdvancedSingleCustomGroup<T extends Selector> = {
decoratorNamePattern?: string
elementValuePattern?: string
elementNamePattern?: string
} & BaseSingleCustomGroup<T>

Expand Down Expand Up @@ -263,6 +264,10 @@ export const singleCustomGroupJsonSchema: Record<string, JSONSchema4> = {
description: 'Element name pattern filter.',
type: 'string',
},
elementValuePattern: {
description: 'Element value pattern filter for properties.',
type: 'string',
},
decoratorNamePattern: {
description: 'Decorator name pattern filter.',
type: 'string',
Expand Down
85 changes: 85 additions & 0 deletions test/sort-classes.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6324,6 +6324,58 @@ describe(ruleName, () => {
],
})

ruleTester.run(`${ruleName}: filters on elementValuePattern`, rule, {
valid: [],
invalid: [
{
code: dedent`
class Class {
a = computed(A)
b = inject(B)
y = inject(Y)
z = computed(Z)
c() {}
}
`,
output: dedent`
class Class {
a = computed(A)
z = computed(Z)
b = inject(B)
y = inject(Y)
c() {}
}
`,
options: [
{
groups: ['computed', 'inject', 'unknown'],
customGroups: [
{
groupName: 'inject',
elementValuePattern: 'inject*',
},
{
groupName: 'computed',
elementValuePattern: 'computed*',
},
],
},
],
errors: [
{
messageId: 'unexpectedClassesGroupOrder',
data: {
left: 'y',
leftGroup: 'inject',
right: 'z',
rightGroup: 'computed',
},
},
],
},
],
})

ruleTester.run(`${ruleName}: filters on decoratorNamePattern`, rule, {
valid: [],
invalid: [
Expand Down Expand Up @@ -6775,6 +6827,39 @@ describe(ruleName, () => {
},
)

ruleTester.run(
`${ruleName}: allows to use regex matcher for element values in custom groups with new API`,
rule,
{
valid: [
{
code: dedent`
class Class {
x = "iHaveFooInMyName"
z = "MeTooIHaveFoo"
a = "a"
b = "b"
}
`,
options: [
{
type: 'alphabetical',
matcher: 'regex',
groups: ['unknown', 'elementsWithoutFoo'],
customGroups: [
{
groupName: 'elementsWithoutFoo',
elementValuePattern: '^(?!.*Foo).*$',
},
],
},
],
},
],
invalid: [],
},
)

ruleTester.run(
`${ruleName}: allows to use regex matcher for decorator names in custom groups with new API`,
rule,
Expand Down

0 comments on commit 4e7e5ad

Please sign in to comment.