@@ -31,6 +31,7 @@ function normalizeIndent(strings) {
31
31
// }
32
32
// ***************************************************
33
33
34
+ // Tests that are valid/invalid across all parsers
34
35
const tests = {
35
36
valid : [
36
37
{
@@ -1322,16 +1323,6 @@ const tests = {
1322
1323
}
1323
1324
` ,
1324
1325
} ,
1325
- // Ignore Generic Type Variables for arrow functions
1326
- {
1327
- code : normalizeIndent `
1328
- function Example({ prop }) {
1329
- const bar = useEffect(<T>(a: T): Hello => {
1330
- prop();
1331
- }, [prop]);
1332
- }
1333
- ` ,
1334
- } ,
1335
1326
// Ignore arguments keyword for arrow functions.
1336
1327
{
1337
1328
code : normalizeIndent `
@@ -7466,24 +7457,7 @@ const tests = {
7466
7457
} ,
7467
7458
] ,
7468
7459
} ,
7469
- {
7470
- code : normalizeIndent `
7471
- function Foo() {
7472
- const foo = ({}: any);
7473
- useMemo(() => {
7474
- console.log(foo);
7475
- }, [foo]);
7476
- }
7477
- ` ,
7478
- errors : [
7479
- {
7480
- message :
7481
- "The 'foo' object makes the dependencies of useMemo Hook (at line 6) change on every render. " +
7482
- "Move it inside the useMemo callback. Alternatively, wrap the initialization of 'foo' in its own useMemo() Hook." ,
7483
- suggestions : undefined ,
7484
- } ,
7485
- ] ,
7486
- } ,
7460
+
7487
7461
{
7488
7462
code : normalizeIndent `
7489
7463
function Foo() {
@@ -7532,6 +7506,43 @@ const tests = {
7532
7506
] ,
7533
7507
} ;
7534
7508
7509
+ // Tests that are only valid/invalid across parsers supporting Flow
7510
+ const testsFlow = {
7511
+ valid : [
7512
+ // Ignore Generic Type Variables for arrow functions
7513
+ {
7514
+ code : normalizeIndent `
7515
+ function Example({ prop }) {
7516
+ const bar = useEffect(<T>(a: T): Hello => {
7517
+ prop();
7518
+ }, [prop]);
7519
+ }
7520
+ ` ,
7521
+ } ,
7522
+ ] ,
7523
+ invalid : [
7524
+ {
7525
+ code : normalizeIndent `
7526
+ function Foo() {
7527
+ const foo = ({}: any);
7528
+ useMemo(() => {
7529
+ console.log(foo);
7530
+ }, [foo]);
7531
+ }
7532
+ ` ,
7533
+ errors : [
7534
+ {
7535
+ message :
7536
+ "The 'foo' object makes the dependencies of useMemo Hook (at line 6) change on every render. " +
7537
+ "Move it inside the useMemo callback. Alternatively, wrap the initialization of 'foo' in its own useMemo() Hook." ,
7538
+ suggestions : undefined ,
7539
+ } ,
7540
+ ] ,
7541
+ } ,
7542
+ ] ,
7543
+ } ;
7544
+
7545
+ // Tests that are only valid/invalid across parsers supporting TypeScript
7535
7546
const testsTypescript = {
7536
7547
valid : [
7537
7548
{
@@ -7928,15 +7939,56 @@ const testsTypescript = {
7928
7939
] ,
7929
7940
} ;
7930
7941
7942
+ // Tests that are only valid/invalid for `@typescript-eslint/parser@4.x`
7943
+ const testsTypescriptEslintParserV4 = {
7944
+ valid : [ ] ,
7945
+ invalid : [
7946
+ // TODO: Should also be invalid as part of the JS test suite i.e. be invalid with babel eslint parsers.
7947
+ // It doesn't use any explicit types but any JS is still valid TS.
7948
+ {
7949
+ code : normalizeIndent `
7950
+ function Foo({ Component }) {
7951
+ React.useEffect(() => {
7952
+ console.log(<Component />);
7953
+ }, []);
7954
+ };
7955
+ ` ,
7956
+ errors : [
7957
+ {
7958
+ message :
7959
+ "React Hook React.useEffect has a missing dependency: 'Component'. " +
7960
+ 'Either include it or remove the dependency array.' ,
7961
+ suggestions : [
7962
+ {
7963
+ desc : 'Update the dependencies array to be: [Component]' ,
7964
+ output : normalizeIndent `
7965
+ function Foo({ Component }) {
7966
+ React.useEffect(() => {
7967
+ console.log(<Component />);
7968
+ }, [Component]);
7969
+ };
7970
+ ` ,
7971
+ } ,
7972
+ ] ,
7973
+ } ,
7974
+ ] ,
7975
+ } ,
7976
+ ] ,
7977
+ } ;
7978
+
7931
7979
// For easier local testing
7932
7980
if ( ! process . env . CI ) {
7933
7981
let only = [ ] ;
7934
7982
let skipped = [ ] ;
7935
7983
[
7936
7984
...tests . valid ,
7937
7985
...tests . invalid ,
7986
+ ...testsFlow . valid ,
7987
+ ...testsFlow . invalid ,
7938
7988
...testsTypescript . valid ,
7939
7989
...testsTypescript . invalid ,
7990
+ ...testsTypescriptEslintParserV4 . valid ,
7991
+ ...testsTypescriptEslintParserV4 . invalid ,
7940
7992
] . forEach ( t => {
7941
7993
if ( t . skip ) {
7942
7994
delete t . skip ;
@@ -7958,33 +8010,52 @@ if (!process.env.CI) {
7958
8010
} ;
7959
8011
tests . valid = tests . valid . filter ( predicate ) ;
7960
8012
tests . invalid = tests . invalid . filter ( predicate ) ;
8013
+ testsFlow . valid = testsFlow . valid . filter ( predicate ) ;
8014
+ testsFlow . invalid = testsFlow . invalid . filter ( predicate ) ;
7961
8015
testsTypescript . valid = testsTypescript . valid . filter ( predicate ) ;
7962
8016
testsTypescript . invalid = testsTypescript . invalid . filter ( predicate ) ;
7963
8017
}
7964
8018
7965
8019
describe ( 'react-hooks' , ( ) => {
7966
8020
const parserOptions = {
8021
+ ecmaFeatures : {
8022
+ jsx : true ,
8023
+ } ,
7967
8024
ecmaVersion : 6 ,
7968
8025
sourceType : 'module' ,
7969
8026
} ;
7970
8027
8028
+ const testsBabelEslint = {
8029
+ valid : [ ...testsFlow . valid , ...tests . valid ] ,
8030
+ invalid : [ ...testsFlow . invalid , ...tests . invalid ] ,
8031
+ } ;
8032
+
7971
8033
new ESLintTester ( {
7972
8034
parser : require . resolve ( 'babel-eslint' ) ,
7973
8035
parserOptions,
7974
- } ) . run ( 'parser: babel-eslint' , ReactHooksESLintRule , tests ) ;
8036
+ } ) . run ( 'parser: babel-eslint' , ReactHooksESLintRule , testsBabelEslint ) ;
7975
8037
7976
8038
new ESLintTester ( {
7977
8039
parser : require . resolve ( '@babel/eslint-parser' ) ,
7978
8040
parserOptions,
7979
- } ) . run ( 'parser: @babel/eslint-parser' , ReactHooksESLintRule , tests ) ;
8041
+ } ) . run (
8042
+ 'parser: @babel/eslint-parser' ,
8043
+ ReactHooksESLintRule ,
8044
+ testsBabelEslint
8045
+ ) ;
8046
+
8047
+ const testsTypescriptEslintParser = {
8048
+ valid : [ ...testsTypescript . valid , ...tests . valid ] ,
8049
+ invalid : [ ...testsTypescript . invalid , ...tests . invalid ] ,
8050
+ } ;
7980
8051
7981
8052
new ESLintTester ( {
7982
8053
parser : require . resolve ( '@typescript-eslint/parser-v2' ) ,
7983
8054
parserOptions,
7984
8055
} ) . run (
7985
8056
'parser: @typescript-eslint/parser@2.x' ,
7986
8057
ReactHooksESLintRule ,
7987
- testsTypescript
8058
+ testsTypescriptEslintParser
7988
8059
) ;
7989
8060
7990
8061
new ESLintTester ( {
@@ -7993,15 +8064,20 @@ describe('react-hooks', () => {
7993
8064
} ) . run (
7994
8065
'parser: @typescript-eslint/parser@3.x' ,
7995
8066
ReactHooksESLintRule ,
7996
- testsTypescript
8067
+ testsTypescriptEslintParser
7997
8068
) ;
7998
8069
7999
8070
new ESLintTester ( {
8000
8071
parser : require . resolve ( '@typescript-eslint/parser-v4' ) ,
8001
8072
parserOptions,
8002
- } ) . run (
8003
- 'parser: @typescript-eslint/parser@4.x' ,
8004
- ReactHooksESLintRule ,
8005
- testsTypescript
8006
- ) ;
8073
+ } ) . run ( 'parser: @typescript-eslint/parser@4.x' , ReactHooksESLintRule , {
8074
+ valid : [
8075
+ ...testsTypescriptEslintParserV4 . valid ,
8076
+ ...testsTypescriptEslintParser . valid ,
8077
+ ] ,
8078
+ invalid : [
8079
+ ...testsTypescriptEslintParserV4 . invalid ,
8080
+ ...testsTypescriptEslintParser . invalid ,
8081
+ ] ,
8082
+ } ) ;
8007
8083
} ) ;
0 commit comments