From 6291dde6dd6342066b003b9958a5518119b4fec2 Mon Sep 17 00:00:00 2001 From: AleksandrZhukov Date: Sat, 13 Oct 2018 18:50:31 +0300 Subject: [PATCH] Fixes for no-raw-text rule - added support for StyledComponents - added check for whitespaces - added `skip` option for customizing this rule --- docs/rules/no-raw-text.md | 4 ++ lib/rules/no-raw-text.js | 35 ++++++++++++++--- tests/lib/rules/no-raw-text.js | 69 ++++++++++++++++++++++++++++++++++ 3 files changed, 102 insertions(+), 6 deletions(-) diff --git a/docs/rules/no-raw-text.md b/docs/rules/no-raw-text.md index c5a038e..2e0bd42 100644 --- a/docs/rules/no-raw-text.md +++ b/docs/rules/no-raw-text.md @@ -24,3 +24,7 @@ The following patterns are not considered warnings: const text = 'some text'; {`${text}`} ``` + +####This rule has an object option: + +- "skip" – allow to skip checking for the array of custom components diff --git a/lib/rules/no-raw-text.js b/lib/rules/no-raw-text.js index 4c1340c..719c7e2 100644 --- a/lib/rules/no-raw-text.js +++ b/lib/rules/no-raw-text.js @@ -6,6 +6,8 @@ 'use strict'; module.exports = (context) => { + const options = context.options[0] || {}; + const elementName = node => ( node.openingElement && node.openingElement.name && @@ -16,21 +18,29 @@ module.exports = (context) => { const report = (node) => { const errorValue = node.type === 'TemplateLiteral' ? `TemplateLiteral: ${node.expressions[0].name}` - : node.value; + : node.value.trim(); + + const formattedErrorValue = errorValue.length > 0 + ? `Raw text (${errorValue})` + : 'Whitespace(s)'; + context.report({ node, - message: `Raw text (${errorValue.trim()}) cannot be used outside of a tag`, + message: `${formattedErrorValue} cannot be used outside of a tag`, }); }; - const getValidation = node => elementName(node.parent) !== 'Text'; + const skippedElements = options.skip ? options.skip : []; + const allowedElements = ['Text', 'TSpan', 'StyledText'].concat(skippedElements); + + const getValidation = node => !allowedElements.includes(elementName(node.parent)); return { Literal(node) { const parentType = node.parent.type; const onlyFor = ['JSXExpressionContainer', 'JSXElement']; - if (/^[\s]+$/.test(node.value) || - typeof node.value !== 'string' || + if (typeof node.value !== 'string' || + /^[\r\n\t\f\v]+$/.test(node.value.replace(/ /g, '')) || !onlyFor.includes(parentType) || (node.parent.parent && node.parent.parent.type === 'JSXAttribute') ) return; @@ -60,4 +70,17 @@ module.exports = (context) => { }; }; -module.exports.schema = []; +module.exports.schema = [ + { + type: 'object', + properties: { + skip: { + type: 'array', + items: { + type: 'string', + }, + }, + }, + additionalProperties: false, + }, +]; diff --git a/tests/lib/rules/no-raw-text.js b/tests/lib/rules/no-raw-text.js index dc25f8b..d2633be 100644 --- a/tests/lib/rules/no-raw-text.js +++ b/tests/lib/rules/no-raw-text.js @@ -50,6 +50,53 @@ const tests = { } `, }, + { + code: ` + export default class MyComponent extends Component { + render() { + return ( + + some text + + ); + } + } + `, + }, + { + code: ` + export default class MyComponent extends Component { + render() { + return ( + + + some text + + + ); + } + } + `, + }, + { + code: ` + const StyledText = styled.Text\` + color: red; + \` + export default class MyComponent extends Component { + render() { + return (some text); + } + } + `, + }, + { + code: ` + const Title = ({ children }) => ({children}); + This is the title + `, + options: [{ skip: ['Title'] }], + }, ], invalid: [ { @@ -89,6 +136,28 @@ const tests = { message: 'Raw text (some text) cannot be used outside of a tag', }], }, + { + code: ` + export default class MyComponent extends Component { + render() { + return ( ); + } + } + `, + errors: [{ + message: 'Whitespace(s) cannot be used outside of a tag', + }], + }, + { + code: ` + const Component = ({ children }) => ({children}); + some text + `, + options: [{ skip: ['Title'] }], + errors: [{ + message: 'Raw text (some text) cannot be used outside of a tag', + }], + }, ], };