1
1
import { ESLintUtils , TSESTree } from '@typescript-eslint/experimental-utils' ;
2
2
import { getDocsUrl } from '../utils' ;
3
3
import {
4
- isCallExpression ,
5
4
isIdentifier ,
6
5
isMemberExpression ,
7
6
isObjectPattern ,
@@ -22,7 +21,7 @@ export default ESLintUtils.RuleCreator(getDocsUrl)({
22
21
} ,
23
22
messages : {
24
23
noContainer :
25
- 'Unexpected use of container methods . Prefer the use of "screen.someMethod ()". ' ,
24
+ 'Avoid using container to query for elements . Prefer using query methods from Testing Library, such as "getByRole ()"' ,
26
25
} ,
27
26
fixable : null ,
28
27
schema : [
@@ -44,7 +43,9 @@ export default ESLintUtils.RuleCreator(getDocsUrl)({
44
43
45
44
create ( context , [ options ] ) {
46
45
const { renderFunctions } = options ;
47
- let destructuredContainerName = '' ;
46
+ let containerName = '' ;
47
+ let renderWrapperName = '' ;
48
+ let hasPropertyContainer = false ;
48
49
49
50
return {
50
51
VariableDeclarator ( node ) {
@@ -56,25 +57,45 @@ export default ESLintUtils.RuleCreator(getDocsUrl)({
56
57
isIdentifier ( property . key ) &&
57
58
property . key . name === 'container'
58
59
) ;
59
- if ( containerIndex !== - 1 ) {
60
- const nodeValue = node . id . properties [ containerIndex ] . value ;
61
- destructuredContainerName =
62
- isIdentifier ( nodeValue ) && nodeValue . name ;
63
- }
60
+ const nodeValue =
61
+ containerIndex !== - 1 && node . id . properties [ containerIndex ] . value ;
62
+ containerName = isIdentifier ( nodeValue ) && nodeValue . name ;
63
+ } else {
64
+ renderWrapperName = isIdentifier ( node . id ) && node . id . name ;
64
65
}
65
66
}
66
67
} ,
67
68
68
69
CallExpression ( node : TSESTree . CallExpression ) {
69
- if (
70
- isMemberExpression ( node . callee ) &&
71
- isIdentifier ( node . callee . object ) &&
72
- node . callee . object . name === destructuredContainerName
70
+ function showErrorForChainedContainerMethod (
71
+ innerNode : TSESTree . MemberExpression
73
72
) {
74
- context . report ( {
75
- node,
76
- messageId : 'noContainer' ,
77
- } ) ;
73
+ if ( isMemberExpression ( innerNode ) ) {
74
+ if ( isIdentifier ( innerNode . object ) ) {
75
+ const isScreen = innerNode . object . name === 'screen' ;
76
+ const isContainerName = innerNode . object . name === containerName ;
77
+ const isRenderWrapper =
78
+ innerNode . object . name === renderWrapperName ;
79
+
80
+ hasPropertyContainer =
81
+ isIdentifier ( innerNode . property ) &&
82
+ innerNode . property . name === 'container' &&
83
+ ( isScreen || isRenderWrapper ) ;
84
+
85
+ if ( isContainerName || hasPropertyContainer ) {
86
+ context . report ( {
87
+ node,
88
+ messageId : 'noContainer' ,
89
+ } ) ;
90
+ }
91
+ }
92
+ showErrorForChainedContainerMethod (
93
+ innerNode . object as TSESTree . MemberExpression
94
+ ) ;
95
+ }
96
+ }
97
+ if ( isMemberExpression ( node . callee ) ) {
98
+ showErrorForChainedContainerMethod ( node . callee ) ;
78
99
}
79
100
} ,
80
101
} ;
0 commit comments