From ab8ac6adaaf7a88e160899e7f438a4cfd655eb6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ro=C5=BCek?= Date: Fri, 15 Feb 2019 21:09:47 +0100 Subject: [PATCH] Fix: Support boundary spread elements in sort-keys (#11158) * Fix: support boundary spread elements in sort-keys * Docs: rename "boundary spread operator" term --- docs/rules/sort-keys.md | 2 +- lib/rules/sort-keys.js | 6 +++- tests/lib/rules/sort-keys.js | 58 +++++++++++++++++++++++++++++++++++- 3 files changed, 63 insertions(+), 3 deletions(-) diff --git a/docs/rules/sort-keys.md b/docs/rules/sort-keys.md index cd4b78983ac..e6c5155688e 100644 --- a/docs/rules/sort-keys.md +++ b/docs/rules/sort-keys.md @@ -53,7 +53,7 @@ let obj = {a: 1, ["c" + "d"]: 3, b: 2}; let obj = {a: 1, [`${c}`]: 3, b: 2}; let obj = {a: 1, [tag`c`]: 3, b: 2}; -// This rule ignores objects that have a spread operator in them. +// This rule does not report unsorted properties that are separated by a spread property. let obj = {b: 1, ...c, a: 2}; ``` diff --git a/lib/rules/sort-keys.js b/lib/rules/sort-keys.js index 1e8a85e3d75..08bfcdf3d83 100644 --- a/lib/rules/sort-keys.js +++ b/lib/rules/sort-keys.js @@ -129,8 +129,12 @@ module.exports = { stack = stack.upper; }, + SpreadElement() { + stack.prevName = null; + }, + Property(node) { - if (node.parent.type === "ObjectPattern" || node.parent.properties.some(n => n.type === "SpreadElement")) { + if (node.parent.type === "ObjectPattern") { return; } diff --git a/tests/lib/rules/sort-keys.js b/tests/lib/rules/sort-keys.js index 5a3a0a0571d..3106d31460b 100644 --- a/tests/lib/rules/sort-keys.js +++ b/tests/lib/rules/sort-keys.js @@ -33,9 +33,18 @@ ruleTester.run("sort-keys", rule, { // ignore non-simple computed properties. { code: "var obj = {a:1, b:3, [a + b]: -1, c:2}", options: [], parserOptions: { ecmaVersion: 6 } }, - // ignore spread properties. + // ignore properties separated by spread properties { code: "var obj = {a:1, ...z, b:1}", options: [], parserOptions: { ecmaVersion: 2018 } }, { code: "var obj = {b:1, ...z, a:1}", options: [], parserOptions: { ecmaVersion: 2018 } }, + { code: "var obj = {...a, b:1, ...c, d:1}", options: [], parserOptions: { ecmaVersion: 2018 } }, + { code: "var obj = {...a, b:1, ...d, ...c, e:2, z:5}", options: [], parserOptions: { ecmaVersion: 2018 } }, + { code: "var obj = {b:1, ...c, ...d, e:2}", options: [], parserOptions: { ecmaVersion: 2018 } }, + + // not ignore properties not separated by spread properties + { code: "var obj = {...z, a:1, b:1}", options: [], parserOptions: { ecmaVersion: 2018 } }, + { code: "var obj = {...z, ...c, a:1, b:1}", options: [], parserOptions: { ecmaVersion: 2018 } }, + { code: "var obj = {a:1, b:1, ...z}", options: [], parserOptions: { ecmaVersion: 2018 } }, + { code: "var obj = {...z, ...x, a:1, ...c, ...d, f:5, e:4}", options: ["desc"], parserOptions: { ecmaVersion: 2018 } }, // ignore destructuring patterns. { code: "let {a, b} = {}", options: [], parserOptions: { ecmaVersion: 6 } }, @@ -151,6 +160,53 @@ ruleTester.run("sort-keys", rule, { errors: ["Expected object keys to be in ascending order. 'Z' should be before 'À'."] }, + // not ignore properties not separated by spread properties + { + code: "var obj = {...z, c:1, b:1}", + options: [], + parserOptions: { ecmaVersion: 2018 }, + errors: ["Expected object keys to be in ascending order. 'b' should be before 'c'."] + }, + { + code: "var obj = {...z, ...c, d:4, b:1, ...y, ...f, e:2, a:1}", + options: [], + parserOptions: { ecmaVersion: 2018 }, + errors: [ + "Expected object keys to be in ascending order. 'b' should be before 'd'.", + "Expected object keys to be in ascending order. 'a' should be before 'e'." + ] + }, + { + code: "var obj = {c:1, b:1, ...a}", + options: [], + parserOptions: { ecmaVersion: 2018 }, + errors: ["Expected object keys to be in ascending order. 'b' should be before 'c'."] + }, + { + code: "var obj = {...z, ...a, c:1, b:1}", + options: [], + parserOptions: { ecmaVersion: 2018 }, + errors: ["Expected object keys to be in ascending order. 'b' should be before 'c'."] + }, + { + code: "var obj = {...z, b:1, a:1, ...d, ...c}", + options: [], + parserOptions: { ecmaVersion: 2018 }, + errors: ["Expected object keys to be in ascending order. 'a' should be before 'b'."] + }, + { + code: "var obj = {...z, a:2, b:0, ...x, ...c}", + options: ["desc"], + parserOptions: { ecmaVersion: 2018 }, + errors: ["Expected object keys to be in descending order. 'b' should be before 'a'."] + }, + { + code: "var obj = {...z, a:2, b:0, ...x}", + options: ["desc"], + parserOptions: { ecmaVersion: 2018 }, + errors: ["Expected object keys to be in descending order. 'b' should be before 'a'."] + }, + // not ignore simple computed properties. { code: "var obj = {a:1, b:3, [a]: -1, c:2}",