From 4b9ce4bc6c985dc213e0aae959d1697b38c2c1fa Mon Sep 17 00:00:00 2001 From: Johnny Zabala Date: Wed, 1 Jul 2020 20:05:30 -0400 Subject: [PATCH] fix(jsx-newline): add suggested changes --- README.md | 1 + index.js | 4 +-- lib/rules/jsx-newline.js | 6 ++-- tests/lib/rules/jsx-newline.js | 59 +++++++++++++++++++++++----------- 4 files changed, 47 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index 3a06ef705d..33679c1079 100644 --- a/README.md +++ b/README.md @@ -171,6 +171,7 @@ Enable the rules that you would like to use. * [react/jsx-key](docs/rules/jsx-key.md): Report missing `key` props in iterators/collection literals * [react/jsx-max-depth](docs/rules/jsx-max-depth.md): Validate JSX maximum depth * [react/jsx-max-props-per-line](docs/rules/jsx-max-props-per-line.md): Limit maximum of props on a single line in JSX (fixable) +* [react/jsx-newline](docs/rules/jsx-newline.md): Enforce a new line after jsx elements and expressions (fixable) * [react/jsx-no-bind](docs/rules/jsx-no-bind.md): Prevents usage of Function.prototype.bind and arrow functions in React component props * [react/jsx-no-comment-textnodes](docs/rules/jsx-no-comment-textnodes.md): Comments inside children section of tag should be placed inside braces * [react/jsx-no-duplicate-props](docs/rules/jsx-no-duplicate-props.md): Enforce no duplicate props diff --git a/index.js b/index.js index 7f2b7e7d9e..a533fe3e8f 100644 --- a/index.js +++ b/index.js @@ -31,6 +31,7 @@ const allRules = { 'jsx-key': require('./lib/rules/jsx-key'), 'jsx-max-depth': require('./lib/rules/jsx-max-depth'), 'jsx-max-props-per-line': require('./lib/rules/jsx-max-props-per-line'), + 'jsx-newline': require('./lib/rules/jsx-newline'), 'jsx-no-bind': require('./lib/rules/jsx-no-bind'), 'jsx-no-comment-textnodes': require('./lib/rules/jsx-no-comment-textnodes'), 'jsx-no-duplicate-props': require('./lib/rules/jsx-no-duplicate-props'), @@ -91,8 +92,7 @@ const allRules = { 'state-in-constructor': require('./lib/rules/state-in-constructor'), 'static-property-placement': require('./lib/rules/static-property-placement'), 'style-prop-object': require('./lib/rules/style-prop-object'), - 'void-dom-elements-no-children': require('./lib/rules/void-dom-elements-no-children'), - 'jsx-newline': require('./lib/rules/jsx-newline') + 'void-dom-elements-no-children': require('./lib/rules/void-dom-elements-no-children') }; /* eslint-enable */ diff --git a/lib/rules/jsx-newline.js b/lib/rules/jsx-newline.js index bf6f2e4f51..f0a1f1cca5 100644 --- a/lib/rules/jsx-newline.js +++ b/lib/rules/jsx-newline.js @@ -5,7 +5,6 @@ 'use strict'; -const arrayIncludes = require('array-includes'); const docsUrl = require('../util/docsUrl'); // ------------------------------------------------------------------------------ @@ -29,13 +28,13 @@ module.exports = { 'Program:exit'() { jsxElementParents.forEach((parent) => { parent.children.forEach((element, index, elements) => { - if (arrayIncludes(['JSXElement', 'JSXExpressionContainer'], element.type)) { + if (element.type === 'JSXElement' || element.type === 'JSXExpressionContainer') { const firstAdjacentSibling = elements[index + 1]; const secondAdjacentSibling = elements[index + 2]; if ( firstAdjacentSibling && secondAdjacentSibling - && arrayIncludes(['Literal', 'JSXText'], firstAdjacentSibling.type) + && (firstAdjacentSibling.type === 'Literal' || firstAdjacentSibling.type === 'JSXText') // Check adjacent sibling has the proper amount of newlines && !/\n\s*\n/.test(firstAdjacentSibling.value) ) { @@ -45,6 +44,7 @@ module.exports = { fix(fixer) { return fixer.replaceText( firstAdjacentSibling, + // double the last newline. sourceCode.getText(firstAdjacentSibling) .replace(/(\n)(?!.*\1)/g, '\n\n') ); diff --git a/tests/lib/rules/jsx-newline.js b/tests/lib/rules/jsx-newline.js index 6eba504fb0..1fb6beceb7 100644 --- a/tests/lib/rules/jsx-newline.js +++ b/tests/lib/rules/jsx-newline.js @@ -11,7 +11,6 @@ const RuleTester = require('eslint').RuleTester; const rule = require('../../../lib/rules/jsx-newline'); - const parsers = require('../../helpers/parsers'); const parserOptions = { @@ -26,8 +25,7 @@ const parserOptions = { // Tests // ------------------------------------------------------------------------------ -const ruleTester = new RuleTester({parserOptions}); -ruleTester.run('jsx-newline', rule, { +const tests = { valid: [ `
@@ -52,18 +50,7 @@ ruleTester.run('jsx-newline', rule, { )}
- `, - { - code: ` - <> - - Test - - Should be in new line - - `, - parser: parsers.BABEL_ESLINT - } + ` ], invalid: [ { @@ -179,7 +166,24 @@ ruleTester.run('jsx-newline', rule, { {message: 'JSX element should start in a new line'}, {message: 'JSX element should start in a new line'} ] - }, + } + ] +}; + +const advanceFeatTest = { + valid: [ + { + code: ` + <> + + Test + + Should be in new line + + ` + } + ], + invalid: [ { code: ` <> @@ -198,8 +202,27 @@ ruleTester.run('jsx-newline', rule, { `, errors: [ {message: 'JSX element should start in a new line'} - ], - parser: parsers.BABEL_ESLINT + ] } ] +}; + +// Run tests with default parser +new RuleTester({parserOptions}).run('jsx-newline', rule, tests); + +// Run tests with babel parser +let ruleTester = new RuleTester({parserOptions, parser: parsers.BABEL_ESLINT}); +ruleTester.run('jsx-newline', rule, tests); +ruleTester.run('jsx-newline', rule, advanceFeatTest); + +// Run tests with typescript parser +ruleTester = new RuleTester({parserOptions, parser: parsers.TYPESCRIPT_ESLINT}); +ruleTester.run('jsx-newline', rule, tests); +ruleTester.run('jsx-newline', rule, advanceFeatTest); + +ruleTester = new RuleTester({parserOptions, parser: parsers['@TYPESCRIPT_ESLINT']}); +ruleTester.run('jsx-newline', rule, tests); +ruleTester.run('jsx-newline', rule, { + valid: [].concat(parsers.TS(advanceFeatTest.valid)), + invalid: [].concat(parsers.TS(advanceFeatTest.invalid)) });