Skip to content

Commit f479c98

Browse files
committed
move getAttrValue into utils method
1 parent 5cfaa00 commit f479c98

3 files changed

Lines changed: 132 additions & 47 deletions

File tree

packages/eslint-plugin/src/rules/a11y/consistent_is_invalid_props.test.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,22 @@
1+
/*
2+
* Licensed to Elasticsearch B.V. under one or more contributor
3+
* license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright
5+
* ownership. Elasticsearch B.V. licenses this file to you under
6+
* the Apache License, Version 2.0 (the "License"); you may
7+
* not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
120
import dedent from 'dedent';
221
import { RuleTester } from '@typescript-eslint/rule-tester';
322
import { ConsistentIsInvalidProps } from './consistent_is_invalid_props';
Lines changed: 58 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,24 @@
1-
import { type TSESTree, ESLintUtils } from '@typescript-eslint/utils';
1+
/*
2+
* Licensed to Elasticsearch B.V. under one or more contributor
3+
* license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright
5+
* ownership. Elasticsearch B.V. licenses this file to you under
6+
* the Apache License, Version 2.0 (the "License"); you may
7+
* not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
219

20+
import { type TSESTree, ESLintUtils } from '@typescript-eslint/utils';
21+
import { getAttrValue } from '../../utils/get_attr_value';
322
const formControlComponent = 'EuiFormRow';
423

524
const formControlChildComponents = [
@@ -10,38 +29,11 @@ const formControlChildComponents = [
1029
'EuiTextArea',
1130
'EuiFormControlLayoutDelimited',
1231
'SingleFieldSelect',
13-
'EuiSelect'
32+
'EuiSelect',
1433
];
1534

1635
export const ConsistentIsInvalidProps = ESLintUtils.RuleCreator.withoutDocs({
1736
create(context) {
18-
function getAttrValue(attributes: TSESTree.JSXOpeningElement["attributes"], attrName: string): string | undefined {
19-
const attr = attributes.find(
20-
(attr): attr is TSESTree.JSXAttribute =>
21-
attr.type === 'JSXAttribute' &&
22-
attr.name.type === 'JSXIdentifier' &&
23-
attr.name.name === attrName
24-
);
25-
26-
if (!attr?.value) return undefined;
27-
28-
if (attr.value.type === 'Literal') {
29-
return String(attr.value.value);
30-
}
31-
32-
if (attr.value.type === 'JSXExpressionContainer') {
33-
const expression = attr.value.expression;
34-
35-
if (expression.type === 'Literal') {
36-
return String(expression.value);
37-
}
38-
39-
return context.sourceCode.getText(expression);
40-
}
41-
42-
return undefined;
43-
}
44-
4537
return {
4638
JSXElement(node) {
4739
const openingElement = node.openingElement;
@@ -54,8 +46,15 @@ export const ConsistentIsInvalidProps = ESLintUtils.RuleCreator.withoutDocs({
5446
return;
5547
}
5648

57-
const formRowIsInvalid = getAttrValue(openingElement.attributes, 'isInvalid');
58-
if (formRowIsInvalid === undefined) return;
49+
const formRowIsInvalid = getAttrValue(
50+
context,
51+
openingElement.attributes,
52+
'isInvalid'
53+
);
54+
55+
if (formRowIsInvalid === undefined) {
56+
return;
57+
}
5958

6059
const childElement = node.children.find(
6160
(child): child is TSESTree.JSXElement =>
@@ -68,24 +67,34 @@ export const ConsistentIsInvalidProps = ESLintUtils.RuleCreator.withoutDocs({
6867
return;
6968
}
7069

71-
const childIsInvalid = getAttrValue(childElement.openingElement.attributes, 'isInvalid');
70+
const childIsInvalid = getAttrValue(
71+
context,
72+
childElement.openingElement.attributes,
73+
'isInvalid'
74+
);
7275

7376
if (childIsInvalid !== formRowIsInvalid) {
74-
const componentName = (childElement.openingElement.name as TSESTree.JSXIdentifier).name;
77+
const componentName = (
78+
childElement.openingElement.name as TSESTree.JSXIdentifier
79+
).name;
7580

7681
context.report({
7782
node: childElement,
7883
messageId: 'inconsistentIsInvalid',
7984
fix: (fixer) => {
80-
const childIsInvalidAttr = childElement.openingElement.attributes.find(
81-
(attr): attr is TSESTree.JSXAttribute =>
82-
attr.type === 'JSXAttribute' &&
83-
attr.name.type === 'JSXIdentifier' &&
84-
attr.name.name === 'isInvalid'
85-
);
85+
const childIsInvalidAttr =
86+
childElement.openingElement.attributes.find(
87+
(attr): attr is TSESTree.JSXAttribute =>
88+
attr.type === 'JSXAttribute' &&
89+
attr.name.type === 'JSXIdentifier' &&
90+
attr.name.name === 'isInvalid'
91+
);
8692

8793
if (childIsInvalidAttr) {
88-
return fixer.replaceText(childIsInvalidAttr, `isInvalid={${formRowIsInvalid}}`);
94+
return fixer.replaceText(
95+
childIsInvalidAttr,
96+
`isInvalid={${formRowIsInvalid}}`
97+
);
8998
}
9099

91100
const insertPosition = childElement.openingElement.name.range[1];
@@ -95,23 +104,25 @@ export const ConsistentIsInvalidProps = ESLintUtils.RuleCreator.withoutDocs({
95104
` isInvalid={${formRowIsInvalid}}`
96105
);
97106
},
98-
data: { formControlComponent: formControlComponent, component: componentName},
107+
data: {
108+
formControlComponent: formControlComponent,
109+
component: componentName,
110+
},
99111
});
100112
}
101-
}
113+
},
102114
};
103115
},
104116
meta: {
105117
type: 'problem',
106118
docs: {
107-
description: `Ensure {{component}} inherit "isInvalid" prop from parent {{formControlComponent}}`
119+
description: `Ensure {{component}} inherit "isInvalid" prop from parent {{formControlComponent}}`,
108120
},
109121
fixable: 'code',
110122
schema: [],
111123
messages: {
112-
inconsistentIsInvalid:
113-
`{{component}} should have the same "isInvalid" prop value as its parent {{formControlComponent}}.`
114-
}
124+
inconsistentIsInvalid: `{{component}} should have the same "isInvalid" prop value as its parent {{formControlComponent}}.`,
125+
},
115126
},
116-
defaultOptions: []
127+
defaultOptions: [],
117128
});
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/*
2+
* Licensed to Elasticsearch B.V. under one or more contributor
3+
* license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright
5+
* ownership. Elasticsearch B.V. licenses this file to you under
6+
* the Apache License, Version 2.0 (the "License"); you may
7+
* not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
import { type TSESTree, type TSESLint} from '@typescript-eslint/utils';
21+
22+
export function getAttrValue<
23+
TContext extends TSESLint.RuleContext<string, unknown[]>
24+
>(
25+
context: TContext,
26+
attributes: TSESTree.JSXOpeningElement['attributes'],
27+
attrName: string
28+
): string | undefined {
29+
const attr = attributes.find(
30+
(attr): attr is TSESTree.JSXAttribute =>
31+
attr.type === 'JSXAttribute' &&
32+
attr.name.type === 'JSXIdentifier' &&
33+
attr.name.name === attrName
34+
);
35+
36+
if (!attr?.value) {
37+
return undefined;
38+
}
39+
40+
if (attr.value.type === 'Literal') {
41+
return String(attr.value.value);
42+
}
43+
44+
if (attr.value.type === 'JSXExpressionContainer') {
45+
const expression = attr.value.expression;
46+
47+
if (expression.type === 'Literal') {
48+
return String(expression.value);
49+
}
50+
51+
return context.sourceCode.getText(expression);
52+
}
53+
54+
return undefined;
55+
}

0 commit comments

Comments
 (0)