From 8f695d224522109226259fe5200bfc60de8cf964 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ro=C5=BCek?= Date: Wed, 5 Dec 2018 00:23:59 +0100 Subject: [PATCH 1/2] Fix: support boundary spread elements in sort-keys --- 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..9b8f5e68a84 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 ignores objects that have a non-boundary spread operator in them. let obj = {b: 1, ...c, a: 2}; ``` diff --git a/lib/rules/sort-keys.js b/lib/rules/sort-keys.js index 0668e617d3c..496241b25ba 100644 --- a/lib/rules/sort-keys.js +++ b/lib/rules/sort-keys.js @@ -127,8 +127,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..a419753f717 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 non-boundary 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 } }, + + // boundary 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 boundary 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}", From 79484c1ad3f1623bdd3ccba6e2816462b58ea0ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ro=C5=BCek?= Date: Sat, 8 Dec 2018 14:24:05 +0100 Subject: [PATCH 2/2] Docs: rename "boundary spread operator" term --- docs/rules/sort-keys.md | 2 +- tests/lib/rules/sort-keys.js | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/rules/sort-keys.md b/docs/rules/sort-keys.md index 9b8f5e68a84..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 non-boundary 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/tests/lib/rules/sort-keys.js b/tests/lib/rules/sort-keys.js index a419753f717..3106d31460b 100644 --- a/tests/lib/rules/sort-keys.js +++ b/tests/lib/rules/sort-keys.js @@ -33,14 +33,14 @@ 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 non-boundary 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 } }, - // boundary spread properties + // 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 } }, @@ -160,7 +160,7 @@ ruleTester.run("sort-keys", rule, { errors: ["Expected object keys to be in ascending order. 'Z' should be before 'À'."] }, - // not ignore boundary spread properties + // not ignore properties not separated by spread properties { code: "var obj = {...z, c:1, b:1}", options: [],