From 6c207d6a05305ee82cf764f4742388211c4e14cd Mon Sep 17 00:00:00 2001 From: Olaf Merkert Date: Mon, 7 Jan 2019 20:15:15 +0100 Subject: [PATCH 01/14] new rule jsx-curly-brace-presence * basic test cases for enforcing absence --- src/rules/jsxCurlyBracePresenceRule.ts | 50 +++++++++++++++++++ .../jsx-curly-brace-presence/test.tsx.lint | 6 +++ .../jsx-curly-brace-presence/tslint.json | 5 ++ 3 files changed, 61 insertions(+) create mode 100644 src/rules/jsxCurlyBracePresenceRule.ts create mode 100644 test/rules/jsx-curly-brace-presence/test.tsx.lint create mode 100644 test/rules/jsx-curly-brace-presence/tslint.json diff --git a/src/rules/jsxCurlyBracePresenceRule.ts b/src/rules/jsxCurlyBracePresenceRule.ts new file mode 100644 index 0000000..9d56eb4 --- /dev/null +++ b/src/rules/jsxCurlyBracePresenceRule.ts @@ -0,0 +1,50 @@ +/** + * @license + * Copyright 2019 Palantir Technologies, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import * as Lint from "tslint"; +import { isJsxAttribute, isJsxExpression, isStringLiteral} from "tsutils"; +import * as ts from "typescript"; + +export class Rule extends Lint.Rules.AbstractRule { + public static FAILURE_STRING = "some error"; + + public apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] { + return this.applyWithFunction(sourceFile, walk); + } +} + +function walk(ctx: Lint.WalkContext): void { + return ts.forEachChild(ctx.sourceFile, cb); + + function cb(node: ts.Node): void { + if (isJsxAttribute(node)) { + const { initializer} = node; + + if (initializer !== undefined) { + // const hasStringInitializer = initializer.kind === ts.SyntaxKind.StringLiteral; + const hasStringExpressionInitializer = isJsxExpression(initializer) + && initializer.expression !== undefined + && (isStringLiteral(initializer.expression)); + + if (hasStringExpressionInitializer) { + ctx.addFailureAtNode(initializer, Rule.FAILURE_STRING); + } + } + } + return ts.forEachChild(node, cb); + } +} diff --git a/test/rules/jsx-curly-brace-presence/test.tsx.lint b/test/rules/jsx-curly-brace-presence/test.tsx.lint new file mode 100644 index 0000000..3b610b3 --- /dev/null +++ b/test/rules/jsx-curly-brace-presence/test.tsx.lint @@ -0,0 +1,6 @@ +const e1 = (

some text

); + ~~~~~~~ [0] + +const e2 = (

some text

); + +[0]: some error \ No newline at end of file diff --git a/test/rules/jsx-curly-brace-presence/tslint.json b/test/rules/jsx-curly-brace-presence/tslint.json new file mode 100644 index 0000000..9874e42 --- /dev/null +++ b/test/rules/jsx-curly-brace-presence/tslint.json @@ -0,0 +1,5 @@ +{ + "rules": { + "jsx-curly-brace-presence": true + } +} From ea5951bf676add6d0db7ca0ebfef20bd3a3bf117 Mon Sep 17 00:00:00 2001 From: Olaf Merkert Date: Mon, 7 Jan 2019 20:51:32 +0100 Subject: [PATCH 02/14] add presence enforcing to jsx-curly-brace-presence rule --- src/rules/jsxCurlyBracePresenceRule.ts | 74 +++++++++++++++---- .../always/test.tsx.lint | 6 ++ .../always/tslint.json | 5 ++ .../never/test.tsx.lint | 11 +++ .../never/tslint.json | 5 ++ .../jsx-curly-brace-presence/test.tsx.lint | 6 -- .../jsx-curly-brace-presence/tslint.json | 5 -- 7 files changed, 86 insertions(+), 26 deletions(-) create mode 100644 test/rules/jsx-curly-brace-presence/always/test.tsx.lint create mode 100644 test/rules/jsx-curly-brace-presence/always/tslint.json create mode 100644 test/rules/jsx-curly-brace-presence/never/test.tsx.lint create mode 100644 test/rules/jsx-curly-brace-presence/never/tslint.json delete mode 100644 test/rules/jsx-curly-brace-presence/test.tsx.lint delete mode 100644 test/rules/jsx-curly-brace-presence/tslint.json diff --git a/src/rules/jsxCurlyBracePresenceRule.ts b/src/rules/jsxCurlyBracePresenceRule.ts index 9d56eb4..7383404 100644 --- a/src/rules/jsxCurlyBracePresenceRule.ts +++ b/src/rules/jsxCurlyBracePresenceRule.ts @@ -16,35 +16,79 @@ */ import * as Lint from "tslint"; -import { isJsxAttribute, isJsxExpression, isStringLiteral} from "tsutils"; +import { isJsxAttribute, isJsxExpression, isStringLiteral, isTextualLiteral } from "tsutils"; import * as ts from "typescript"; +const OPTION_ALWAYS = "always"; +const OPTION_NEVER = "never"; +const CURLY_PRESENCE_VALUES = [OPTION_ALWAYS, OPTION_NEVER]; +const CURLY_PRESENCE_OBJECT = { + enum: CURLY_PRESENCE_VALUES, + type: "string", +}; + export class Rule extends Lint.Rules.AbstractRule { - public static FAILURE_STRING = "some error"; + /* tslint:disable:object-literal-sort-keys */ + public static metadata: Lint.IRuleMetadata = { + ruleName: "jsx-curly-brace-presence", + description: "Enforce curly braces or disallow unnecessary curly braces in JSX props", + optionsDescription: Lint.Utils.dedent` +One of the following two options must be provided: + +* \`"${OPTION_ALWAYS}"\` requires JSX attributes to have curly braces around string literal values +* \`"${OPTION_NEVER}"\` requires JSX attributes to NOT have curly braces around string literal values`, + options: { + type: "array", + items: [CURLY_PRESENCE_OBJECT], + minLength: 1, + maxLength: 1, + }, + optionExamples: [ + `[true, "${OPTION_ALWAYS}"]`, + `[true, "${OPTION_NEVER}"]`, + ], + type: "style", + typescriptOnly: false, + }; + /* tslint:enable:object-literal-sort-keys */ + + public static FAILURE_CURLY_PRESENT = "JSX attribute must NOT have curly braces around string literal"; + public static FAILURE_CURLY_MISSING = "JSX attribute must have curly braces around string literal"; public apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] { - return this.applyWithFunction(sourceFile, walk); + const option = Array.isArray(this.ruleArguments) ? this.ruleArguments[0] : undefined; + + return this.applyWithFunction(sourceFile, walk, option); } } -function walk(ctx: Lint.WalkContext): void { - return ts.forEachChild(ctx.sourceFile, cb); +function walk(ctx: Lint.WalkContext): void { + return ts.forEachChild(ctx.sourceFile, validateCurlyBraces); - function cb(node: ts.Node): void { + function validateCurlyBraces(node: ts.Node): void { if (isJsxAttribute(node)) { - const { initializer} = node; + if (ctx.options === OPTION_ALWAYS) { + const { initializer} = node; - if (initializer !== undefined) { - // const hasStringInitializer = initializer.kind === ts.SyntaxKind.StringLiteral; - const hasStringExpressionInitializer = isJsxExpression(initializer) - && initializer.expression !== undefined - && (isStringLiteral(initializer.expression)); + if (initializer !== undefined) { + const hasStringInitializer = initializer.kind === ts.SyntaxKind.StringLiteral; + if (hasStringInitializer) { + ctx.addFailureAtNode(initializer, Rule.FAILURE_CURLY_MISSING); + } + } + } else if (ctx.options === OPTION_NEVER) { + const { initializer} = node; + if (initializer !== undefined) { + const hasStringExpressionInitializer = isJsxExpression(initializer) + && initializer.expression !== undefined + && (isStringLiteral(initializer.expression) || isTextualLiteral(initializer.expression)); - if (hasStringExpressionInitializer) { - ctx.addFailureAtNode(initializer, Rule.FAILURE_STRING); + if (hasStringExpressionInitializer) { + ctx.addFailureAtNode(initializer, Rule.FAILURE_CURLY_PRESENT); + } } } } - return ts.forEachChild(node, cb); + return ts.forEachChild(node, validateCurlyBraces); } } diff --git a/test/rules/jsx-curly-brace-presence/always/test.tsx.lint b/test/rules/jsx-curly-brace-presence/always/test.tsx.lint new file mode 100644 index 0000000..58a18a4 --- /dev/null +++ b/test/rules/jsx-curly-brace-presence/always/test.tsx.lint @@ -0,0 +1,6 @@ +const e1 = (

some text

); + +const e2 = (

some text

); + ~~~~~ [0] + +[0]: JSX attribute must have curly braces around string literal \ No newline at end of file diff --git a/test/rules/jsx-curly-brace-presence/always/tslint.json b/test/rules/jsx-curly-brace-presence/always/tslint.json new file mode 100644 index 0000000..fd65c07 --- /dev/null +++ b/test/rules/jsx-curly-brace-presence/always/tslint.json @@ -0,0 +1,5 @@ +{ + "rules": { + "jsx-curly-brace-presence": [true, "always"] + } +} diff --git a/test/rules/jsx-curly-brace-presence/never/test.tsx.lint b/test/rules/jsx-curly-brace-presence/never/test.tsx.lint new file mode 100644 index 0000000..e8acf19 --- /dev/null +++ b/test/rules/jsx-curly-brace-presence/never/test.tsx.lint @@ -0,0 +1,11 @@ +const e1 = (

some text

); + ~~~~~~~ [0] + +const e2 = (

some text

); + +const e3 = (

some text

); + +const e4 = (

some text

); + ~~~~~~~ [0] + +[0]: JSX attribute must NOT have curly braces around string literal \ No newline at end of file diff --git a/test/rules/jsx-curly-brace-presence/never/tslint.json b/test/rules/jsx-curly-brace-presence/never/tslint.json new file mode 100644 index 0000000..8da9c54 --- /dev/null +++ b/test/rules/jsx-curly-brace-presence/never/tslint.json @@ -0,0 +1,5 @@ +{ + "rules": { + "jsx-curly-brace-presence": [true, "never"] + } +} diff --git a/test/rules/jsx-curly-brace-presence/test.tsx.lint b/test/rules/jsx-curly-brace-presence/test.tsx.lint deleted file mode 100644 index 3b610b3..0000000 --- a/test/rules/jsx-curly-brace-presence/test.tsx.lint +++ /dev/null @@ -1,6 +0,0 @@ -const e1 = (

some text

); - ~~~~~~~ [0] - -const e2 = (

some text

); - -[0]: some error \ No newline at end of file diff --git a/test/rules/jsx-curly-brace-presence/tslint.json b/test/rules/jsx-curly-brace-presence/tslint.json deleted file mode 100644 index 9874e42..0000000 --- a/test/rules/jsx-curly-brace-presence/tslint.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "rules": { - "jsx-curly-brace-presence": true - } -} From 1bf3112dc7dcfb826663d3b69e3691877eb0f3e1 Mon Sep 17 00:00:00 2001 From: Olaf Merkert Date: Mon, 7 Jan 2019 21:09:59 +0100 Subject: [PATCH 03/14] implement autofix for never option of jsx-curly-brace-presence rule --- src/rules/jsxCurlyBracePresenceRule.ts | 16 ++++++++++------ .../jsx-curly-brace-presence/never/test.tsx.fix | 7 +++++++ 2 files changed, 17 insertions(+), 6 deletions(-) create mode 100644 test/rules/jsx-curly-brace-presence/never/test.tsx.fix diff --git a/src/rules/jsxCurlyBracePresenceRule.ts b/src/rules/jsxCurlyBracePresenceRule.ts index 7383404..2a148cf 100644 --- a/src/rules/jsxCurlyBracePresenceRule.ts +++ b/src/rules/jsxCurlyBracePresenceRule.ts @@ -78,13 +78,17 @@ function walk(ctx: Lint.WalkContext): void { } } else if (ctx.options === OPTION_NEVER) { const { initializer} = node; - if (initializer !== undefined) { - const hasStringExpressionInitializer = isJsxExpression(initializer) - && initializer.expression !== undefined - && (isStringLiteral(initializer.expression) || isTextualLiteral(initializer.expression)); + if (initializer !== undefined + && isJsxExpression(initializer) + && initializer.expression !== undefined) { + if (isStringLiteral(initializer.expression)) { + + const fix = Lint.Replacement.replaceNode(initializer, initializer.expression.getText()); - if (hasStringExpressionInitializer) { - ctx.addFailureAtNode(initializer, Rule.FAILURE_CURLY_PRESENT); + ctx.addFailureAtNode(initializer, Rule.FAILURE_CURLY_PRESENT, fix); + } else if (isTextualLiteral(initializer.expression)) { + const fix = Lint.Replacement.replaceNode(initializer, `"${initializer.expression.text}"`); + ctx.addFailureAtNode(initializer, Rule.FAILURE_CURLY_PRESENT, fix); } } } diff --git a/test/rules/jsx-curly-brace-presence/never/test.tsx.fix b/test/rules/jsx-curly-brace-presence/never/test.tsx.fix new file mode 100644 index 0000000..5aba86b --- /dev/null +++ b/test/rules/jsx-curly-brace-presence/never/test.tsx.fix @@ -0,0 +1,7 @@ +const e1 = (

some text

); + +const e2 = (

some text

); + +const e3 = (

some text

); + +const e4 = (

some text

); From 1474e10d9242d8cc3a133d5a2e06ceb96401f440 Mon Sep 17 00:00:00 2001 From: Olaf Merkert Date: Mon, 7 Jan 2019 21:13:56 +0100 Subject: [PATCH 04/14] implement autofix for always option of jsx-curly-brace-presence rule --- src/rules/jsxCurlyBracePresenceRule.ts | 3 ++- test/rules/jsx-curly-brace-presence/always/test.tsx.fix | 3 +++ 2 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 test/rules/jsx-curly-brace-presence/always/test.tsx.fix diff --git a/src/rules/jsxCurlyBracePresenceRule.ts b/src/rules/jsxCurlyBracePresenceRule.ts index 2a148cf..a5aa86a 100644 --- a/src/rules/jsxCurlyBracePresenceRule.ts +++ b/src/rules/jsxCurlyBracePresenceRule.ts @@ -73,7 +73,8 @@ function walk(ctx: Lint.WalkContext): void { if (initializer !== undefined) { const hasStringInitializer = initializer.kind === ts.SyntaxKind.StringLiteral; if (hasStringInitializer) { - ctx.addFailureAtNode(initializer, Rule.FAILURE_CURLY_MISSING); + const fix = Lint.Replacement.replaceNode(initializer, `{${initializer.getText()}}`); + ctx.addFailureAtNode(initializer, Rule.FAILURE_CURLY_MISSING, fix); } } } else if (ctx.options === OPTION_NEVER) { diff --git a/test/rules/jsx-curly-brace-presence/always/test.tsx.fix b/test/rules/jsx-curly-brace-presence/always/test.tsx.fix new file mode 100644 index 0000000..d8cbc68 --- /dev/null +++ b/test/rules/jsx-curly-brace-presence/always/test.tsx.fix @@ -0,0 +1,3 @@ +const e1 = (

some text

); + +const e2 = (

some text

); From 20e1ae983c9f86e34f8dc27d188c5e1ea82e711a Mon Sep 17 00:00:00 2001 From: Olaf Merkert Date: Mon, 7 Jan 2019 21:24:57 +0100 Subject: [PATCH 05/14] refactor jsx-curly-brace-presence rule --- src/rules/jsxCurlyBracePresenceRule.ts | 51 +++++++++++++++----------- 1 file changed, 29 insertions(+), 22 deletions(-) diff --git a/src/rules/jsxCurlyBracePresenceRule.ts b/src/rules/jsxCurlyBracePresenceRule.ts index a5aa86a..ca5ac68 100644 --- a/src/rules/jsxCurlyBracePresenceRule.ts +++ b/src/rules/jsxCurlyBracePresenceRule.ts @@ -68,32 +68,39 @@ function walk(ctx: Lint.WalkContext): void { function validateCurlyBraces(node: ts.Node): void { if (isJsxAttribute(node)) { if (ctx.options === OPTION_ALWAYS) { - const { initializer} = node; - - if (initializer !== undefined) { - const hasStringInitializer = initializer.kind === ts.SyntaxKind.StringLiteral; - if (hasStringInitializer) { - const fix = Lint.Replacement.replaceNode(initializer, `{${initializer.getText()}}`); - ctx.addFailureAtNode(initializer, Rule.FAILURE_CURLY_MISSING, fix); - } - } + validateCurlyBracesArePresent(node); } else if (ctx.options === OPTION_NEVER) { - const { initializer} = node; - if (initializer !== undefined - && isJsxExpression(initializer) - && initializer.expression !== undefined) { - if (isStringLiteral(initializer.expression)) { + validateCurlyBracesAreMissing(node); + } + } + return ts.forEachChild(node, validateCurlyBraces); + } - const fix = Lint.Replacement.replaceNode(initializer, initializer.expression.getText()); + function validateCurlyBracesArePresent(node: ts.JsxAttribute) { + const { initializer } = node; + if (initializer !== undefined) { + const hasStringInitializer = initializer.kind === ts.SyntaxKind.StringLiteral; + if (hasStringInitializer) { + const fix = Lint.Replacement.replaceNode(initializer, `{${initializer.getText()}}`); + ctx.addFailureAtNode(initializer, Rule.FAILURE_CURLY_MISSING, fix); + } + } + } - ctx.addFailureAtNode(initializer, Rule.FAILURE_CURLY_PRESENT, fix); - } else if (isTextualLiteral(initializer.expression)) { - const fix = Lint.Replacement.replaceNode(initializer, `"${initializer.expression.text}"`); - ctx.addFailureAtNode(initializer, Rule.FAILURE_CURLY_PRESENT, fix); - } - } + function validateCurlyBracesAreMissing(node: ts.JsxAttribute) { + const { initializer } = node; + if (initializer !== undefined + && isJsxExpression(initializer) + && initializer.expression !== undefined) { + if (isStringLiteral(initializer.expression)) { + const stringLiteralWithoutCurlies: string = initializer.expression.getText(); + const fix = Lint.Replacement.replaceNode(initializer, stringLiteralWithoutCurlies); + ctx.addFailureAtNode(initializer, Rule.FAILURE_CURLY_PRESENT, fix); + } else if (isTextualLiteral(initializer.expression)) { + const textualLiteralContent = initializer.expression.text; + const fix = Lint.Replacement.replaceNode(initializer, `"${textualLiteralContent}"`); + ctx.addFailureAtNode(initializer, Rule.FAILURE_CURLY_PRESENT, fix); } } - return ts.forEachChild(node, validateCurlyBraces); } } From 2a041b9609c261ca5ce40024948fa9215ae67fe5 Mon Sep 17 00:00:00 2001 From: Olaf Merkert Date: Sat, 16 Mar 2019 21:20:15 +0100 Subject: [PATCH 06/14] use object type instead of array for curly brace presence rule --- src/rules/jsxCurlyBracePresenceRule.ts | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/rules/jsxCurlyBracePresenceRule.ts b/src/rules/jsxCurlyBracePresenceRule.ts index ca5ac68..e947655 100644 --- a/src/rules/jsxCurlyBracePresenceRule.ts +++ b/src/rules/jsxCurlyBracePresenceRule.ts @@ -32,16 +32,19 @@ export class Rule extends Lint.Rules.AbstractRule { public static metadata: Lint.IRuleMetadata = { ruleName: "jsx-curly-brace-presence", description: "Enforce curly braces or disallow unnecessary curly braces in JSX props", + hasFix: true, optionsDescription: Lint.Utils.dedent` -One of the following two options must be provided: +One of the following two options may be provided: * \`"${OPTION_ALWAYS}"\` requires JSX attributes to have curly braces around string literal values -* \`"${OPTION_NEVER}"\` requires JSX attributes to NOT have curly braces around string literal values`, +* \`"${OPTION_NEVER}"\` requires JSX attributes to NOT have curly braces around string literal values + +If no option is provided, "${OPTION_NEVER}" is chosen as default.`, options: { - type: "array", - items: [CURLY_PRESENCE_OBJECT], - minLength: 1, - maxLength: 1, + type: "object", + properties: { + props: CURLY_PRESENCE_OBJECT, + }, }, optionExamples: [ `[true, "${OPTION_ALWAYS}"]`, From 6afb30680ab6bbf13d66e5da41276a458d6d58b7 Mon Sep 17 00:00:00 2001 From: Olaf Merkert Date: Sat, 16 Mar 2019 21:23:37 +0100 Subject: [PATCH 07/14] default to never in curly brace presence rule; improve naming --- src/rules/jsxCurlyBracePresenceRule.ts | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/rules/jsxCurlyBracePresenceRule.ts b/src/rules/jsxCurlyBracePresenceRule.ts index e947655..3a94522 100644 --- a/src/rules/jsxCurlyBracePresenceRule.ts +++ b/src/rules/jsxCurlyBracePresenceRule.ts @@ -55,8 +55,8 @@ If no option is provided, "${OPTION_NEVER}" is chosen as default.`, }; /* tslint:enable:object-literal-sort-keys */ - public static FAILURE_CURLY_PRESENT = "JSX attribute must NOT have curly braces around string literal"; - public static FAILURE_CURLY_MISSING = "JSX attribute must have curly braces around string literal"; + public static FAILURE_CURLY_BRACE_SUPERFLUOUS = "JSX attribute must NOT have curly braces around string literal"; + public static FAILURE_CURLY_BRACE_MISSING = "JSX attribute must have curly braces around string literal"; public apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] { const option = Array.isArray(this.ruleArguments) ? this.ruleArguments[0] : undefined; @@ -72,8 +72,8 @@ function walk(ctx: Lint.WalkContext): void { if (isJsxAttribute(node)) { if (ctx.options === OPTION_ALWAYS) { validateCurlyBracesArePresent(node); - } else if (ctx.options === OPTION_NEVER) { - validateCurlyBracesAreMissing(node); + } else { + validateCurlyBracesAreNotPresent(node); } } return ts.forEachChild(node, validateCurlyBraces); @@ -85,12 +85,12 @@ function walk(ctx: Lint.WalkContext): void { const hasStringInitializer = initializer.kind === ts.SyntaxKind.StringLiteral; if (hasStringInitializer) { const fix = Lint.Replacement.replaceNode(initializer, `{${initializer.getText()}}`); - ctx.addFailureAtNode(initializer, Rule.FAILURE_CURLY_MISSING, fix); + ctx.addFailureAtNode(initializer, Rule.FAILURE_CURLY_BRACE_MISSING, fix); } } } - function validateCurlyBracesAreMissing(node: ts.JsxAttribute) { + function validateCurlyBracesAreNotPresent(node: ts.JsxAttribute) { const { initializer } = node; if (initializer !== undefined && isJsxExpression(initializer) @@ -98,11 +98,11 @@ function walk(ctx: Lint.WalkContext): void { if (isStringLiteral(initializer.expression)) { const stringLiteralWithoutCurlies: string = initializer.expression.getText(); const fix = Lint.Replacement.replaceNode(initializer, stringLiteralWithoutCurlies); - ctx.addFailureAtNode(initializer, Rule.FAILURE_CURLY_PRESENT, fix); + ctx.addFailureAtNode(initializer, Rule.FAILURE_CURLY_BRACE_SUPERFLUOUS, fix); } else if (isTextualLiteral(initializer.expression)) { const textualLiteralContent = initializer.expression.text; const fix = Lint.Replacement.replaceNode(initializer, `"${textualLiteralContent}"`); - ctx.addFailureAtNode(initializer, Rule.FAILURE_CURLY_PRESENT, fix); + ctx.addFailureAtNode(initializer, Rule.FAILURE_CURLY_BRACE_SUPERFLUOUS, fix); } } } From ca6bc8a4f0a359d37dcdb655caee703683332c9a Mon Sep 17 00:00:00 2001 From: Olaf Merkert Date: Sat, 16 Mar 2019 21:52:46 +0100 Subject: [PATCH 08/14] update tests for curly brace presence rule to use object parameter --- src/rules/jsxCurlyBracePresenceRule.ts | 8 ++++---- test/rules/jsx-curly-brace-presence/always/tslint.json | 2 +- test/rules/jsx-curly-brace-presence/never/tslint.json | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/rules/jsxCurlyBracePresenceRule.ts b/src/rules/jsxCurlyBracePresenceRule.ts index 3a94522..e0b3712 100644 --- a/src/rules/jsxCurlyBracePresenceRule.ts +++ b/src/rules/jsxCurlyBracePresenceRule.ts @@ -47,8 +47,8 @@ If no option is provided, "${OPTION_NEVER}" is chosen as default.`, }, }, optionExamples: [ - `[true, "${OPTION_ALWAYS}"]`, - `[true, "${OPTION_NEVER}"]`, + `[true, { props: "${OPTION_ALWAYS}" }]`, + `[true, { props: "${OPTION_NEVER}" }]`, ], type: "style", typescriptOnly: false, @@ -65,12 +65,12 @@ If no option is provided, "${OPTION_NEVER}" is chosen as default.`, } } -function walk(ctx: Lint.WalkContext): void { +function walk(ctx: Lint.WalkContext<{ props: string } | undefined>): void { return ts.forEachChild(ctx.sourceFile, validateCurlyBraces); function validateCurlyBraces(node: ts.Node): void { if (isJsxAttribute(node)) { - if (ctx.options === OPTION_ALWAYS) { + if (typeof ctx.options === "object" && ctx.options.props === OPTION_ALWAYS) { validateCurlyBracesArePresent(node); } else { validateCurlyBracesAreNotPresent(node); diff --git a/test/rules/jsx-curly-brace-presence/always/tslint.json b/test/rules/jsx-curly-brace-presence/always/tslint.json index fd65c07..22e0909 100644 --- a/test/rules/jsx-curly-brace-presence/always/tslint.json +++ b/test/rules/jsx-curly-brace-presence/always/tslint.json @@ -1,5 +1,5 @@ { "rules": { - "jsx-curly-brace-presence": [true, "always"] + "jsx-curly-brace-presence": [true, { "props": "always" }] } } diff --git a/test/rules/jsx-curly-brace-presence/never/tslint.json b/test/rules/jsx-curly-brace-presence/never/tslint.json index 8da9c54..c6ad04a 100644 --- a/test/rules/jsx-curly-brace-presence/never/tslint.json +++ b/test/rules/jsx-curly-brace-presence/never/tslint.json @@ -1,5 +1,5 @@ { "rules": { - "jsx-curly-brace-presence": [true, "never"] + "jsx-curly-brace-presence": [true, { "props": "never" }] } } From a2dfb7cd5222164f44c56c0ff1269243d4bd5bad Mon Sep 17 00:00:00 2001 From: Olaf Merkert Date: Sat, 16 Mar 2019 21:53:35 +0100 Subject: [PATCH 09/14] add test for default behaviour of curly brace presence rule --- test/rules/jsx-curly-brace-presence/default/test.tsx.fix | 1 + test/rules/jsx-curly-brace-presence/default/test.tsx.lint | 4 ++++ test/rules/jsx-curly-brace-presence/default/tslint.json | 5 +++++ 3 files changed, 10 insertions(+) create mode 100644 test/rules/jsx-curly-brace-presence/default/test.tsx.fix create mode 100644 test/rules/jsx-curly-brace-presence/default/test.tsx.lint create mode 100644 test/rules/jsx-curly-brace-presence/default/tslint.json diff --git a/test/rules/jsx-curly-brace-presence/default/test.tsx.fix b/test/rules/jsx-curly-brace-presence/default/test.tsx.fix new file mode 100644 index 0000000..f4b4831 --- /dev/null +++ b/test/rules/jsx-curly-brace-presence/default/test.tsx.fix @@ -0,0 +1 @@ +const e1 = (

some text

); diff --git a/test/rules/jsx-curly-brace-presence/default/test.tsx.lint b/test/rules/jsx-curly-brace-presence/default/test.tsx.lint new file mode 100644 index 0000000..ec56d91 --- /dev/null +++ b/test/rules/jsx-curly-brace-presence/default/test.tsx.lint @@ -0,0 +1,4 @@ +const e1 = (

some text

); + ~~~~~~~ [0] + +[0]: JSX attribute must NOT have curly braces around string literal \ No newline at end of file diff --git a/test/rules/jsx-curly-brace-presence/default/tslint.json b/test/rules/jsx-curly-brace-presence/default/tslint.json new file mode 100644 index 0000000..9874e42 --- /dev/null +++ b/test/rules/jsx-curly-brace-presence/default/tslint.json @@ -0,0 +1,5 @@ +{ + "rules": { + "jsx-curly-brace-presence": true + } +} From 5bd5e39a310b6c9001cd564b053ad8050fb9dde5 Mon Sep 17 00:00:00 2001 From: Adi Dahiya Date: Wed, 27 Mar 2019 20:44:25 +0100 Subject: [PATCH 10/14] Update src/rules/jsxCurlyBracePresenceRule.ts Co-Authored-By: OlafMerkert --- src/rules/jsxCurlyBracePresenceRule.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rules/jsxCurlyBracePresenceRule.ts b/src/rules/jsxCurlyBracePresenceRule.ts index e0b3712..7bfbe8d 100644 --- a/src/rules/jsxCurlyBracePresenceRule.ts +++ b/src/rules/jsxCurlyBracePresenceRule.ts @@ -47,7 +47,7 @@ If no option is provided, "${OPTION_NEVER}" is chosen as default.`, }, }, optionExamples: [ - `[true, { props: "${OPTION_ALWAYS}" }]`, + `{ props: "${OPTION_ALWAYS}" }`, `[true, { props: "${OPTION_NEVER}" }]`, ], type: "style", From de0745dfaf34f28a599b63fc49fd5181d94eacf2 Mon Sep 17 00:00:00 2001 From: Adi Dahiya Date: Wed, 27 Mar 2019 20:44:32 +0100 Subject: [PATCH 11/14] Update src/rules/jsxCurlyBracePresenceRule.ts Co-Authored-By: OlafMerkert --- src/rules/jsxCurlyBracePresenceRule.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rules/jsxCurlyBracePresenceRule.ts b/src/rules/jsxCurlyBracePresenceRule.ts index 7bfbe8d..ae70e7e 100644 --- a/src/rules/jsxCurlyBracePresenceRule.ts +++ b/src/rules/jsxCurlyBracePresenceRule.ts @@ -34,7 +34,7 @@ export class Rule extends Lint.Rules.AbstractRule { description: "Enforce curly braces or disallow unnecessary curly braces in JSX props", hasFix: true, optionsDescription: Lint.Utils.dedent` -One of the following two options may be provided: +One of the following options may be provided under the "props" key: * \`"${OPTION_ALWAYS}"\` requires JSX attributes to have curly braces around string literal values * \`"${OPTION_NEVER}"\` requires JSX attributes to NOT have curly braces around string literal values From d05e4af9da907a2d8a0c2d44901d1c5325e6baa9 Mon Sep 17 00:00:00 2001 From: Adi Dahiya Date: Wed, 27 Mar 2019 20:44:40 +0100 Subject: [PATCH 12/14] Update test/rules/jsx-curly-brace-presence/always/tslint.json Co-Authored-By: OlafMerkert --- test/rules/jsx-curly-brace-presence/always/tslint.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/rules/jsx-curly-brace-presence/always/tslint.json b/test/rules/jsx-curly-brace-presence/always/tslint.json index 22e0909..e6e7812 100644 --- a/test/rules/jsx-curly-brace-presence/always/tslint.json +++ b/test/rules/jsx-curly-brace-presence/always/tslint.json @@ -1,5 +1,5 @@ { "rules": { - "jsx-curly-brace-presence": [true, { "props": "always" }] + "jsx-curly-brace-presence": { "props": "always" } } } From 6468f7e818c3f48376c11eee55022a39a110c72f Mon Sep 17 00:00:00 2001 From: Adi Dahiya Date: Wed, 27 Mar 2019 20:44:46 +0100 Subject: [PATCH 13/14] Update test/rules/jsx-curly-brace-presence/never/tslint.json Co-Authored-By: OlafMerkert --- test/rules/jsx-curly-brace-presence/never/tslint.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/rules/jsx-curly-brace-presence/never/tslint.json b/test/rules/jsx-curly-brace-presence/never/tslint.json index c6ad04a..fed8749 100644 --- a/test/rules/jsx-curly-brace-presence/never/tslint.json +++ b/test/rules/jsx-curly-brace-presence/never/tslint.json @@ -1,5 +1,5 @@ { "rules": { - "jsx-curly-brace-presence": [true, { "props": "never" }] + "jsx-curly-brace-presence": { "props": "never" } } } From 4df206fc3722ae0ec9a4362b7f682d68b68d4ab9 Mon Sep 17 00:00:00 2001 From: Olaf Merkert Date: Thu, 28 Mar 2019 19:49:57 +0100 Subject: [PATCH 14/14] rule parameter must be in "options" property --- src/rules/jsxCurlyBracePresenceRule.ts | 2 +- test/rules/jsx-curly-brace-presence/always/tslint.json | 2 +- test/rules/jsx-curly-brace-presence/never/tslint.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/rules/jsxCurlyBracePresenceRule.ts b/src/rules/jsxCurlyBracePresenceRule.ts index ae70e7e..33a799b 100644 --- a/src/rules/jsxCurlyBracePresenceRule.ts +++ b/src/rules/jsxCurlyBracePresenceRule.ts @@ -48,7 +48,7 @@ If no option is provided, "${OPTION_NEVER}" is chosen as default.`, }, optionExamples: [ `{ props: "${OPTION_ALWAYS}" }`, - `[true, { props: "${OPTION_NEVER}" }]`, + `{ props: "${OPTION_NEVER}" }`, ], type: "style", typescriptOnly: false, diff --git a/test/rules/jsx-curly-brace-presence/always/tslint.json b/test/rules/jsx-curly-brace-presence/always/tslint.json index e6e7812..e32bf4d 100644 --- a/test/rules/jsx-curly-brace-presence/always/tslint.json +++ b/test/rules/jsx-curly-brace-presence/always/tslint.json @@ -1,5 +1,5 @@ { "rules": { - "jsx-curly-brace-presence": { "props": "always" } + "jsx-curly-brace-presence": { "options": { "props": "always" } } } } diff --git a/test/rules/jsx-curly-brace-presence/never/tslint.json b/test/rules/jsx-curly-brace-presence/never/tslint.json index fed8749..75dfdcd 100644 --- a/test/rules/jsx-curly-brace-presence/never/tslint.json +++ b/test/rules/jsx-curly-brace-presence/never/tslint.json @@ -1,5 +1,5 @@ { "rules": { - "jsx-curly-brace-presence": { "props": "never" } + "jsx-curly-brace-presence": { "options": { "props": "never" } } } }