Skip to content

Commit

Permalink
Merge pull request #4 from forivall/feat/all-caps-first
Browse files Browse the repository at this point in the history
  • Loading branch information
forivall committed Oct 24, 2022
2 parents d5ae674 + c5b454d commit 59cddd3
Show file tree
Hide file tree
Showing 2 changed files with 120 additions and 62 deletions.
155 changes: 103 additions & 52 deletions __tests__/lib/rules/sort-keys.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ const test = {
{ code: "var obj = {'#':1, 'Z':2, À:3, è:4}", options: ['asc'] },

// asc, minKeys should ignore unsorted keys when number of keys is less than minKeys
// { code: "var obj = {a:1, c:2, b:3}", options: ["asc", { minKeys: 4 }] },
{ code: 'var obj = {a:1, c:2, b:3}', options: ['asc', { minKeys: 4 }] },

// asc, insensitive
{ code: 'var obj = {_:2, a:1, b:3} // asc, insensitive', options: ['asc', { caseSensitive: false }] },
Expand All @@ -89,7 +89,7 @@ const test = {
{ code: "var obj = {'#':1, 'Z':2, À:3, è:4}", options: ['asc', { caseSensitive: false }] },

// asc, insensitive, minKeys should ignore unsorted keys when number of keys is less than minKeys
// { code: "var obj = {$:1, A:3, _:2, a:4}", options: ["asc", { caseSensitive: false, minKeys: 5 }] },
{ code: 'var obj = {$:1, A:3, _:2, a:4}', options: ['asc', { caseSensitive: false, minKeys: 5 }] },

// asc, natural
{ code: 'var obj = {_:2, a:1, b:3} // asc, natural', options: ['asc', { natural: true }] },
Expand All @@ -101,7 +101,7 @@ const test = {
{ code: "var obj = {'#':1, 'Z':2, À:3, è:4}", options: ['asc', { natural: true }] },

// asc, natural, minKeys should ignore unsorted keys when number of keys is less than minKeys
// { code: "var obj = {b_:1, a:2, b:3}", options: ["asc", { natural: true, minKeys: 4 }] },
{ code: 'var obj = {b_:1, a:2, b:3}', options: ['asc', { natural: true, minKeys: 4 }] },

// asc, natural, insensitive
{
Expand All @@ -117,7 +117,7 @@ const test = {
{ code: "var obj = {'#':1, 'Z':2, À:3, è:4}", options: ['asc', { natural: true, caseSensitive: false }] },

// asc, natural, insensitive, minKeys should ignore unsorted keys when number of keys is less than minKeys
// { code: "var obj = {a:1, _:2, b:3}", options: ["asc", { natural: true, caseSensitive: false, minKeys: 4 }] },
{ code: 'var obj = {a:1, _:2, b:3}', options: ['asc', { natural: true, caseSensitive: false, minKeys: 4 }] },

// desc
{ code: 'var obj = {b:3, a:1, _:2} // desc', options: ['desc'] },
Expand All @@ -129,7 +129,7 @@ const test = {
{ code: "var obj = {è:4, À:3, 'Z':2, '#':1}", options: ['desc'] },

// desc, minKeys should ignore unsorted keys when number of keys is less than minKeys
// { code: "var obj = {a:1, c:2, b:3}", options: ["desc", { minKeys: 4 }] },
{ code: 'var obj = {a:1, c:2, b:3}', options: ['desc', { minKeys: 4 }] },

// desc, insensitive
{ code: 'var obj = {b:3, a:1, _:2} // desc, insensitive', options: ['desc', { caseSensitive: false }] },
Expand All @@ -142,7 +142,7 @@ const test = {
{ code: "var obj = {è:4, À:3, 'Z':2, '#':1}", options: ['desc', { caseSensitive: false }] },

// desc, insensitive, minKeys should ignore unsorted keys when number of keys is less than minKeys
// { code: "var obj = {$:1, _:2, A:3, a:4}", options: ["desc", { caseSensitive: false, minKeys: 5 }] },
{ code: 'var obj = {$:1, _:2, A:3, a:4}', options: ['desc', { caseSensitive: false, minKeys: 5 }] },

// desc, natural
{ code: 'var obj = {b:3, a:1, _:2} // desc, natural', options: ['desc', { natural: true }] },
Expand All @@ -154,7 +154,7 @@ const test = {
{ code: "var obj = {è:4, À:3, 'Z':2, '#':1}", options: ['desc', { natural: true }] },

// desc, natural, minKeys should ignore unsorted keys when number of keys is less than minKeys
// { code: "var obj = {b_:1, a:2, b:3}", options: ["desc", { natural: true, minKeys: 4 }] },
{ code: 'var obj = {b_:1, a:2, b:3}', options: ['desc', { natural: true, minKeys: 4 }] },

// desc, natural, insensitive
{
Expand All @@ -170,7 +170,13 @@ const test = {
{ code: "var obj = {è:4, À:3, 'Z':2, '#':1}", options: ['desc', { natural: true, caseSensitive: false }] },

// desc, natural, insensitive, minKeys should ignore unsorted keys when number of keys is less than minKeys
// { code: "var obj = {a:1, _:2, b:3}", options: ["desc", { natural: true, caseSensitive: false, minKeys: 4 }] }
{ code: 'var obj = {a:1, _:2, b:3}', options: ['desc', { natural: true, caseSensitive: false, minKeys: 4 }] },

// ALL_CAPS first
{ code: 'var obj = {CA: 0, b_:1, Ca:3, ca:2}', options: ['asc', { caseSensitive: false, allCaps: 'first' }] },
{ code: 'var obj = {CA: 0, b_:1, ca:3, Ca:2}', options: ['asc', { caseSensitive: false, allCaps: 'first' }] },
{ code: 'var obj = {C:2, b_:1, c:3}', options: ['asc', { natural: true, allCaps: 'first' }] },
{ code: 'var obj = {B:1, a:2}', options: ['asc', { natural: true, allCaps: 'first' }] },

// overrides
{
Expand Down Expand Up @@ -389,11 +395,12 @@ const test = {
},

// asc, minKeys should error when number of keys is greater than or equal to minKeys
// {
// code: 'var obj = {a:1, _:2, b:3}',
// options: ['asc', { minKeys: 3 }],
// errors: ["Expected object keys to be in ascending order. '_' should be before 'a'."],
// },
{
code: 'var obj = {a:1, _:2, b:3}',
options: ['asc', { minKeys: 3 }],
errors: ["Expected object keys to be in ascending order. '_' should be before 'a'."],
output: 'var obj = {_:2, a:1, b:3}',
},

// asc, insensitive
{
Expand Down Expand Up @@ -434,11 +441,12 @@ const test = {
},

// asc, insensitive, minKeys should error when number of keys is greater than or equal to minKeys
// {
// code: 'var obj = {a:1, _:2, b:3}',
// options: ['asc', { caseSensitive: false, minKeys: 3 }],
// errors: ["Expected object keys to be in insensitive ascending order. '_' should be before 'a'."],
// },
{
code: 'var obj = {a:1, _:2, b:3}',
options: ['asc', { caseSensitive: false, minKeys: 3 }],
errors: ["Expected object keys to be in insensitive ascending order. '_' should be before 'a'."],
output: 'var obj = {_:2, a:1, b:3}',
},

// asc, natural
{
Expand Down Expand Up @@ -485,11 +493,12 @@ const test = {
},

// asc, natural, minKeys should error when number of keys is greater than or equal to minKeys
// {
// code: 'var obj = {a:1, _:2, b:3}',
// options: ['asc', { natural: true, minKeys: 2 }],
// errors: ["Expected object keys to be in natural ascending order. '_' should be before 'a'."],
// },
{
code: 'var obj = {a:1, _:2, b:3}',
options: ['asc', { natural: true, minKeys: 2 }],
errors: ["Expected object keys to be in natural ascending order. '_' should be before 'a'."],
output: 'var obj = {_:2, a:1, b:3}',
},

// asc, natural, insensitive
{
Expand Down Expand Up @@ -530,11 +539,12 @@ const test = {
},

// asc, natural, insensitive, minKeys should error when number of keys is greater than or equal to minKeys
// {
// code: 'var obj = {a:1, _:2, b:3}',
// options: ['asc', { natural: true, caseSensitive: false, minKeys: 3 }],
// errors: ["Expected object keys to be in natural insensitive ascending order. '_' should be before 'a'."],
// },
{
code: 'var obj = {a:1, _:2, b:3}',
options: ['asc', { natural: true, caseSensitive: false, minKeys: 3 }],
errors: ["Expected object keys to be in natural insensitive ascending order. '_' should be before 'a'."],
output: 'var obj = {_:2, a:1, b:3}',
},

// desc
{
Expand Down Expand Up @@ -590,11 +600,12 @@ const test = {
},

// desc, minKeys should error when number of keys is greater than or equal to minKeys
// {
// code: 'var obj = {a:1, _:2, b:3}',
// options: ['desc', { minKeys: 3 }],
// errors: ["Expected object keys to be in descending order. 'b' should be before '_'."],
// },
{
code: 'var obj = {a:1, _:2, b:3}',
options: ['desc', { minKeys: 3 }],
errors: ["Expected object keys to be in descending order. 'b' should be before '_'."],
output: 'var obj = {a:1, b:3, _:2}',
},

// desc, insensitive
{
Expand Down Expand Up @@ -650,11 +661,12 @@ const test = {
},

// desc, insensitive should error when number of keys is greater than or equal to minKeys
// {
// code: 'var obj = {a:1, _:2, b:3}',
// options: ['desc', { caseSensitive: false, minKeys: 2 }],
// errors: ["Expected object keys to be in insensitive descending order. 'b' should be before '_'."],
// },
{
code: 'var obj = {a:1, _:2, b:3}',
options: ['desc', { caseSensitive: false, minKeys: 2 }],
errors: ["Expected object keys to be in insensitive descending order. 'b' should be before '_'."],
output: 'var obj = {a:1, b:3, _:2}',
},

// desc, natural
{
Expand Down Expand Up @@ -711,11 +723,12 @@ const test = {
},

// desc, natural should error when number of keys is greater than or equal to minKeys
// {
// code: 'var obj = {a:1, _:2, b:3}',
// options: ['desc', { natural: true, minKeys: 3 }],
// errors: ["Expected object keys to be in natural descending order. 'b' should be before '_'."],
// },
{
code: 'var obj = {a:1, _:2, b:3}',
options: ['desc', { natural: true, minKeys: 3 }],
errors: ["Expected object keys to be in natural descending order. 'b' should be before '_'."],
output: 'var obj = {a:1, b:3, _:2}',
},

// desc, natural, insensitive
{
Expand Down Expand Up @@ -772,11 +785,12 @@ const test = {
},

// desc, natural, insensitive should error when number of keys is greater than or equal to minKeys
// {
// code: 'var obj = {a:1, _:2, b:3}',
// options: ['desc', { natural: true, caseSensitive: false, minKeys: 2 }],
// errors: ["Expected object keys to be in natural insensitive descending order. 'b' should be before '_'."],
// },
{
code: 'var obj = {a:1, _:2, b:3}',
options: ['desc', { natural: true, caseSensitive: false, minKeys: 2 }],
errors: ["Expected object keys to be in natural insensitive descending order. 'b' should be before '_'."],
output: 'var obj = {a:1, b:3, _:2}',
},

// overrides
{
Expand All @@ -793,10 +807,47 @@ const test = {
],
},
],
errors: [
"CUSTOM_MESSAGE 'y' should be before '$'.",
],
output: "var obj = {a:1, b:{y:1, $:1, a:1}, c:1}",
errors: ["CUSTOM_MESSAGE 'y' should be before '$'."],
output: 'var obj = {a:1, b:{y:1, $:1, a:1}, c:1}',
},

// ALL_CAPS first
{
code: 'var obj = {b_:1, c:3, C:2}',
options: ['asc', { caseSensitive: false, allCaps: 'first' }],
errors: ["Expected all caps keys to be first. 'C' should be before 'c'."],
output: 'var obj = {b_:1, C:2, c:3}',
},
{
code: 'var obj = {b_:1, C:3, c:2}',
options: ['asc', { natural: true, caseSensitive: false, allCaps: 'first' }],
errors: ["Expected all caps keys to be first. 'C' should be before 'b_'."],
output: 'var obj = {C:3, b_:1, c:2}',
},
{
code: 'var obj = {b_:1, c:3, C:2}',
options: ['asc', { natural: true, caseSensitive: false, allCaps: 'first' }],
errors: ["Expected all caps keys to be first. 'C' should be before 'c'."],
output: 'var obj = {b_:1, C:2, c:3}',
},
// ALL_CAPS last
{
code: 'var obj = {b_:1, C:3, c:2}',
options: ['asc', { natural: true, caseSensitive: false, allCaps: 'last' }],
errors: ["Expected all caps keys to be first. 'c' should be before 'C'."],
output: 'var obj = {b_:1, c:2, C:3}',
},
{
code: 'var obj = {$:1, _:2, A:3, a:4}',
options: ['asc', { natural: true, caseSensitive: false, allCaps: 'last' }],
errors: ["Expected all caps keys to be first. 'a' should be before 'A'."],
output: 'var obj = {$:1, _:2, a:4, A:3}',
},
{
code: "var obj = {'#':1, 'Z':2, À:3, è:4}",
options: ['asc', { natural: true, caseSensitive: false, allCaps: 'last' }],
errors: ["Expected all caps keys to be first. 'è' should be before 'À'."],
output: "var obj = {'#':1, 'Z':2, è:4, À:3}",
},
],
}
Expand Down
27 changes: 17 additions & 10 deletions lib/rules/sort-keys.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,14 @@ const astUtils = require('./utils/ast-utils'),
* @property {string[]} [properties] Name of parent property to apply this override to. If omitted, the object's keys
* must be a total subset of the properties defined in order
*/
/**
* @typedef Options
* @property {boolean} [caseSensitive] Use case sensitive sorting
* @property {boolean} [natural] Use natural sorting
* @property {number} [minKeys] Minimum Keys
* @property {'first' | 'last' | 'ignore'} [allCaps] All Caps option
* @property {Override[]} [overrides] Overrides options
*/

/**
* Combinatorial combination fn
Expand Down Expand Up @@ -207,7 +215,8 @@ module.exports = {
default: 2,
},
allCaps: {
enum: ['first', 'last'],
enum: ['first', 'last', 'ignore'],
default: 'ignore',
},
overrides: {
type: 'array',
Expand Down Expand Up @@ -247,11 +256,12 @@ module.exports = {
// Parse options.
/** @type {'asc' | 'desc'} */
const order = context.options[0] || 'asc'
/** @type {Options | undefined} */
const options = context.options[1]
const insensitive = options && options.caseSensitive === false
const natural = options && options.natural
const minKeys = (options && options.minKeys) || 2
const allCaps = options.allCaps
const allCaps = (options && options.allCaps) || 'ignore'
/** @type {Override[]} */
const overrides = (options && options.overrides) || []
/** @type {Map<string | undefined, Override>} */
Expand All @@ -278,12 +288,9 @@ module.exports = {
})
})
const isValidOrderBase = isValidOrders[`${order}${insensitive ? 'I' : ''}${natural ? 'N' : ''}`]
// eslint-disable-next-line no-nested-ternary
const isValidOrderAllCaps = allCaps
? allCaps === 'last'
? (a, b) => isValidAllCapsTest(b, a)
: isValidAllCapsTest
: () => null
const isValidOrderAllCaps =
// eslint-disable-next-line no-nested-ternary
allCaps === 'ignore' ? () => null : allCaps === 'last' ? (a, b) => isValidAllCapsTest(b, a) : isValidAllCapsTest

// The stack to save the previous property's name for each object literals.
let stack = null
Expand Down Expand Up @@ -365,7 +372,7 @@ module.exports = {
const isValidAllCaps = isValidOrderAllCaps(prevName, thisName)

if (isValidAllCaps) {
return;
return
}
if (isValidAllCaps === false) {
context.report({
Expand All @@ -378,7 +385,7 @@ module.exports = {
},
fix: createFixer(context, node, prevNode),
})
return;
return
}

if (!stack.isValidOrder(prevName, thisName)) {
Expand Down

0 comments on commit 59cddd3

Please sign in to comment.