From e997f6c1bfcf62aee34274364f0766173ffc2829 Mon Sep 17 00:00:00 2001 From: Alex Zherdev Date: Thu, 3 Jan 2019 10:09:37 -0800 Subject: [PATCH] [Fix] avoid crashing on self-closing fragments --- lib/rules/jsx-fragments.js | 16 ++++++++++---- tests/lib/rules/jsx-fragments.js | 37 ++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 4 deletions(-) diff --git a/lib/rules/jsx-fragments.js b/lib/rules/jsx-fragments.js index 6a68697f27..10060036e4 100644 --- a/lib/rules/jsx-fragments.js +++ b/lib/rules/jsx-fragments.js @@ -71,10 +71,18 @@ module.exports = { function getFixerToShort(jsxElement) { return function(fixer) { let source = sourceCode.getText(); - source = replaceNode(source, jsxElement.closingElement, closeFragShort); - source = replaceNode(source, jsxElement.openingElement, openFragShort); - const lengthDiff = sourceCode.getText(jsxElement.openingElement).length - openFragShort.length - + sourceCode.getText(jsxElement.closingElement).length - closeFragShort.length; + let lengthDiff; + if (jsxElement.closingElement) { + source = replaceNode(source, jsxElement.closingElement, closeFragShort); + source = replaceNode(source, jsxElement.openingElement, openFragShort); + lengthDiff = sourceCode.getText(jsxElement.openingElement).length - openFragShort.length + + sourceCode.getText(jsxElement.closingElement).length - closeFragShort.length; + } else { + source = replaceNode(source, jsxElement.openingElement, `${openFragShort}${closeFragShort}`); + lengthDiff = sourceCode.getText(jsxElement.openingElement).length - openFragShort.length + - closeFragShort.length; + } + const range = jsxElement.range; return fixer.replaceTextRange(range, source.slice(range[0], range[1] - lengthDiff)); }; diff --git a/tests/lib/rules/jsx-fragments.js b/tests/lib/rules/jsx-fragments.js index 640f029c7a..b0d06dd924 100644 --- a/tests/lib/rules/jsx-fragments.js +++ b/tests/lib/rules/jsx-fragments.js @@ -49,6 +49,10 @@ ruleTester.run('jsx-fragments', rule, { code: '', options: ['element'], settings + }, { + code: '', + options: ['element'], + settings }, { code: ` import Act, { Frag as F } from 'react'; @@ -81,6 +85,10 @@ ruleTester.run('jsx-fragments', rule, { code: '', options: ['syntax'], settings + }, { + code: '', + options: ['syntax'], + settings }], invalid: [{ @@ -98,6 +106,13 @@ ruleTester.run('jsx-fragments', rule, { message: 'Fragments are only supported starting from React v16.2. ' + 'Please disable the `react/jsx-fragments` rule in ESLint settings or upgrade your version of React.' }] + }, { + code: '', + settings: settingsOld, + errors: [{ + message: 'Fragments are only supported starting from React v16.2. ' + + 'Please disable the `react/jsx-fragments` rule in ESLint settings or upgrade your version of React.' + }] }, { code: '<>', parser: 'babel-eslint', @@ -115,6 +130,28 @@ ruleTester.run('jsx-fragments', rule, { message: 'Prefer fragment shorthand over Act.Frag' }], output: '<>' + }, { + code: '', + options: ['syntax'], + settings, + errors: [{ + message: 'Prefer fragment shorthand over Act.Frag' + }], + output: '<>' + }, { + code: ` + import Act, { Frag as F } from 'react'; + ; + `, + options: ['syntax'], + settings, + errors: [{ + message: 'Prefer fragment shorthand over Act.Frag' + }], + output: ` + import Act, { Frag as F } from 'react'; + <>; + ` }, { code: ` import Act, { Frag as F } from 'react';