diff --git a/lib/rules/key-spacing.js b/lib/rules/key-spacing.js index b764b7282ef..083a7e62898 100644 --- a/lib/rules/key-spacing.js +++ b/lib/rules/key-spacing.js @@ -334,6 +334,19 @@ module.exports = { const sourceCode = context.getSourceCode(); + /** + * Determines if the given property is key-value property. + * @param {ASTNode} property Property node to check. + * @returns {boolean} Whether the property is a key-value property. + */ + function isKeyValueProperty(property) { + return !( + (property.method || + property.shorthand || + property.kind !== "init" || property.type !== "Property") // Could be "ExperimentalSpreadProperty" or "SpreadElement" + ); + } + /** * Checks whether a property is a member of the property group it follows. * @param {ASTNode} lastMember The last Property known to be in the group. @@ -342,9 +355,9 @@ module.exports = { */ function continuesPropertyGroup(lastMember, candidate) { const groupEndLine = lastMember.loc.start.line, - candidateStartLine = candidate.loc.start.line; + candidateValueStartLine = (isKeyValueProperty(candidate) ? candidate.value : candidate).loc.start.line; - if (candidateStartLine - groupEndLine <= 1) { + if (candidateValueStartLine - groupEndLine <= 1) { return true; } @@ -358,7 +371,7 @@ module.exports = { if ( leadingComments.length && leadingComments[0].loc.start.line - groupEndLine <= 1 && - candidateStartLine - last(leadingComments).loc.end.line <= 1 + candidateValueStartLine - last(leadingComments).loc.end.line <= 1 ) { for (let i = 1; i < leadingComments.length; i++) { if (leadingComments[i].loc.start.line - leadingComments[i - 1].loc.end.line > 1) { @@ -371,19 +384,6 @@ module.exports = { return false; } - /** - * Determines if the given property is key-value property. - * @param {ASTNode} property Property node to check. - * @returns {boolean} Whether the property is a key-value property. - */ - function isKeyValueProperty(property) { - return !( - (property.method || - property.shorthand || - property.kind !== "init" || property.type !== "Property") // Could be "ExperimentalSpreadProperty" or "SpreadElement" - ); - } - /** * Starting from the given a node (a property.key node here) looks forward * until it finds the last token before a colon punctuator and returns it. diff --git a/tests/lib/rules/key-spacing.js b/tests/lib/rules/key-spacing.js index dd0fcbc4dcf..bd2d5111851 100644 --- a/tests/lib/rules/key-spacing.js +++ b/tests/lib/rules/key-spacing.js @@ -278,7 +278,9 @@ ruleTester.run("key-spacing", rule, { " method() {", " return 42;", " },", - " baz: 456", + " baz: 456,", + " 10: ", + " 10", "};" ].join("\n"), options: [{ align: "value" }], @@ -360,6 +362,10 @@ ruleTester.run("key-spacing", rule, { " bat: function() {", " return this.a;", " },", + " barfoo:", + " [", + " 1", + " ],", " baz: 42", "};" ].join("\n"), @@ -633,6 +639,10 @@ ruleTester.run("key-spacing", rule, { " internalGroup: {", " internal : true,", " ext : false", + " },", + " func3:", + " function () {", + " var test3 = true;", " }", "})" ].join("\n"), @@ -971,6 +981,80 @@ ruleTester.run("key-spacing", rule, { } }], parserOptions: { ecmaVersion: 6 } + }, + + // https://github.com/eslint/eslint/issues/16490 + { + code: ` + var foo = + { + id: 1, + code: 2, + [n]: 3, + message: + "some value on the next line", + }; + `, + options: [{ + align: "value" + }], + parserOptions: { ecmaVersion: 6 } + }, + { + code: ` + var foo = + { + id : 1, + code : 2, + message : + "some value on the next line", + }; + `, + options: [{ + align: "colon", + beforeColon: true + }] + }, + { + code: ` + ({ + a: 1, + // different group + bcd: + 2 + }) + `, + options: [{ + align: "value" + }] + }, + { + code: ` + ({ + foo : 1, + bar : 2, + foobar : + 3 + }) + `, + options: [{ + align: "value", + beforeColon: true, + mode: "minimum" + }] + }, + { + code: ` + ({ + oneLine: 1, + ["some key " + + "spanning multiple lines"]: 2 + }) + `, + options: [{ + align: "value" + }], + parserOptions: { ecmaVersion: 6 } }], invalid: [{ code: "var a ={'key' : value };", @@ -1464,7 +1548,9 @@ ruleTester.run("key-spacing", rule, { " method() {", " return 42;", " },", - " baz: 456", + " baz: 456,", + " 10: ", + " 10", "};" ].join("\n"), output: [ @@ -1473,7 +1559,9 @@ ruleTester.run("key-spacing", rule, { " method() {", " return 42;", " },", - " baz: 456", + " baz: 456,", + " 10: ", + " 10", "};" ].join("\n"), options: [{ align: "value" }], @@ -2374,6 +2462,123 @@ ruleTester.run("key-spacing", rule, { { messageId: "extraValue", data: { computed: "", key: "🎁" }, line: 4, column: 21, type: "Literal" }, { messageId: "extraValue", data: { computed: "", key: "🇮🇳" }, line: 5, column: 23, type: "Literal" } ] - } - ] + }, + + // https://github.com/eslint/eslint/issues/16490 + { + code: ` + var foo = + { + id: 1, + code: 2, + [n]: 3, + message: + "some value on the next line", + }; + `, + output: ` + var foo = + { + id: 1, + code: 2, + [n]: 3, + message: + "some value on the next line", + }; + `, + options: [{ + align: "value" + }], + parserOptions: { ecmaVersion: 6 }, + errors: [ + { messageId: "extraValue", data: { computed: "", key: "id" }, line: 4, column: 19, type: "Literal" }, + { messageId: "extraValue", data: { computed: "", key: "code" }, line: 5, column: 21, type: "Literal" }, + { messageId: "extraValue", data: { computed: "computed ", key: "n" }, line: 6, column: 20, type: "Literal" } + ] + }, + { + code: ` + var foo = + { + id : 1, + code : 2, + message : + "some value on the next line", + }; + `, + output: ` + var foo = + { + id : 1, + code : 2, + message : + "some value on the next line", + }; + `, + options: [{ + align: "colon", + beforeColon: true + }], + errors: [ + { messageId: "extraKey", data: { computed: "", key: "id" }, line: 4, column: 19, type: "Identifier" }, + { messageId: "extraKey", data: { computed: "", key: "code" }, line: 5, column: 21, type: "Identifier" } + ] + }, + { + code: ` + ({ + a: 1, + // different group + bcd: + 2 + }) + `, + output: ` + ({ + a: 1, + // different group + bcd: + 2 + }) + `, + options: [{ + align: "value" + }], + errors: [ + { messageId: "extraValue", data: { computed: "", key: "a" }, line: 3, column: 18, type: "Literal" } + ] + }, + { + code: [ + "({", + " singleLine : 10,", + " newGroup :", + " function() {", + " var test3 = true;", + " }", + "})" + ].join("\n"), + output: [ + "({", + " singleLine: 10,", + " newGroup:", + " function() {", + " var test3 = true;", + " }", + "})" + ].join("\n"), + options: [{ + multiLine: { + beforeColon: false + }, + align: { + on: "colon", + beforeColon: true + } + }], + errors: [ + { messageId: "extraKey", data: { computed: "", key: "singleLine" }, line: 2, column: 15, type: "Identifier" }, + { messageId: "extraKey", data: { computed: "", key: "newGroup" }, line: 3, column: 13, type: "Identifier" } + ] + }] });