@@ -31,6 +31,7 @@ function normalizeIndent(strings) {
3131// }
3232// ***************************************************
3333
34+ // Tests that are valid/invalid across all parsers
3435const tests = {
3536 valid : [
3637 {
@@ -1322,16 +1323,6 @@ const tests = {
13221323 }
13231324 ` ,
13241325 } ,
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- } ,
13351326 // Ignore arguments keyword for arrow functions.
13361327 {
13371328 code : normalizeIndent `
@@ -7466,24 +7457,7 @@ const tests = {
74667457 } ,
74677458 ] ,
74687459 } ,
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+
74877461 {
74887462 code : normalizeIndent `
74897463 function Foo() {
@@ -7532,6 +7506,43 @@ const tests = {
75327506 ] ,
75337507} ;
75347508
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
75357546const testsTypescript = {
75367547 valid : [
75377548 {
@@ -7928,15 +7939,56 @@ const testsTypescript = {
79287939 ] ,
79297940} ;
79307941
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+
79317979// For easier local testing
79327980if ( ! process . env . CI ) {
79337981 let only = [ ] ;
79347982 let skipped = [ ] ;
79357983 [
79367984 ...tests . valid ,
79377985 ...tests . invalid ,
7986+ ...testsFlow . valid ,
7987+ ...testsFlow . invalid ,
79387988 ...testsTypescript . valid ,
79397989 ...testsTypescript . invalid ,
7990+ ...testsTypescriptEslintParserV4 . valid ,
7991+ ...testsTypescriptEslintParserV4 . invalid ,
79407992 ] . forEach ( t => {
79417993 if ( t . skip ) {
79427994 delete t . skip ;
@@ -7958,33 +8010,52 @@ if (!process.env.CI) {
79588010 } ;
79598011 tests . valid = tests . valid . filter ( predicate ) ;
79608012 tests . invalid = tests . invalid . filter ( predicate ) ;
8013+ testsFlow . valid = testsFlow . valid . filter ( predicate ) ;
8014+ testsFlow . invalid = testsFlow . invalid . filter ( predicate ) ;
79618015 testsTypescript . valid = testsTypescript . valid . filter ( predicate ) ;
79628016 testsTypescript . invalid = testsTypescript . invalid . filter ( predicate ) ;
79638017}
79648018
79658019describe ( 'react-hooks' , ( ) => {
79668020 const parserOptions = {
8021+ ecmaFeatures : {
8022+ jsx : true ,
8023+ } ,
79678024 ecmaVersion : 6 ,
79688025 sourceType : 'module' ,
79698026 } ;
79708027
8028+ const testsBabelEslint = {
8029+ valid : [ ...testsFlow . valid , ...tests . valid ] ,
8030+ invalid : [ ...testsFlow . invalid , ...tests . invalid ] ,
8031+ } ;
8032+
79718033 new ESLintTester ( {
79728034 parser : require . resolve ( 'babel-eslint' ) ,
79738035 parserOptions,
7974- } ) . run ( 'parser: babel-eslint' , ReactHooksESLintRule , tests ) ;
8036+ } ) . run ( 'parser: babel-eslint' , ReactHooksESLintRule , testsBabelEslint ) ;
79758037
79768038 new ESLintTester ( {
79778039 parser : require . resolve ( '@babel/eslint-parser' ) ,
79788040 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+ } ;
79808051
79818052 new ESLintTester ( {
79828053 parser : require . resolve ( '@typescript-eslint/parser-v2' ) ,
79838054 parserOptions,
79848055 } ) . run (
79858056 'parser: @typescript-eslint/parser@2.x' ,
79868057 ReactHooksESLintRule ,
7987- testsTypescript
8058+ testsTypescriptEslintParser
79888059 ) ;
79898060
79908061 new ESLintTester ( {
@@ -7993,15 +8064,20 @@ describe('react-hooks', () => {
79938064 } ) . run (
79948065 'parser: @typescript-eslint/parser@3.x' ,
79958066 ReactHooksESLintRule ,
7996- testsTypescript
8067+ testsTypescriptEslintParser
79978068 ) ;
79988069
79998070 new ESLintTester ( {
80008071 parser : require . resolve ( '@typescript-eslint/parser-v4' ) ,
80018072 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+ } ) ;
80078083} ) ;
0 commit comments