Skip to content

Commit 6013f1b

Browse files
committed
[New] order: add caseInsensitive: 'invert' option
1 parent 92caa35 commit 6013f1b

File tree

3 files changed

+68
-6
lines changed

3 files changed

+68
-6
lines changed

docs/rules/order.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -211,12 +211,12 @@ import index from './';
211211
import sibling from './foo';
212212
```
213213

214-
### `alphabetize: {order: asc|desc|ignore, caseInsensitive: true|false}`:
214+
### `alphabetize: {order: asc|desc|ignore, caseInsensitive: true|false|'invert'}`:
215215

216216
Sort the order within each group in alphabetical manner based on **import path**:
217217

218218
- `order`: use `asc` to sort in ascending order, and `desc` to sort in descending order (default: `ignore`).
219-
- `caseInsensitive`: use `true` to ignore case, and `false` to consider case (default: `false`).
219+
- `caseInsensitive`: use `true` to ignore case, `false` to consider case, and `'invert'` to sort lowercase before uppercase (default: `false`).
220220

221221
Example setting:
222222
```js

src/rules/order.js

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,15 @@ function importsSorterDesc(importA, importB) {
267267
return 0
268268
}
269269

270+
function swapCase(input) {
271+
let result = ''
272+
for (let i = 0; i < input.length; i++) {
273+
const lower = input[i].toLowerCase()
274+
result += input[i] === lower ? input[i].toUpperCase() : lower
275+
}
276+
return result
277+
}
278+
270279
function mutateRanksToAlphabetize(imported, alphabetizeOptions) {
271280
const groupedByRanks = imported.reduce(function(acc, importedItem) {
272281
if (!Array.isArray(acc[importedItem.rank])) {
@@ -279,7 +288,10 @@ function mutateRanksToAlphabetize(imported, alphabetizeOptions) {
279288
const groupRanks = Object.keys(groupedByRanks)
280289

281290
const sorterFn = alphabetizeOptions.order === 'asc' ? importsSorterAsc : importsSorterDesc
282-
const comparator = alphabetizeOptions.caseInsensitive ? (a, b) => sorterFn(String(a).toLowerCase(), String(b).toLowerCase()) : (a, b) => sorterFn(a, b)
291+
const comparator =
292+
alphabetizeOptions.caseInsensitive === 'invert' ? (a, b) => sorterFn(swapCase(String(a)), swapCase(String(b)))
293+
: alphabetizeOptions.caseInsensitive ? (a, b) => sorterFn(String(a).toLowerCase(), String(b).toLowerCase())
294+
: (a, b) => sorterFn(a, b)
283295
// sort imports locally within their group
284296
groupRanks.forEach(function(groupRank) {
285297
groupedByRanks[groupRank].sort(comparator)
@@ -546,8 +558,10 @@ module.exports = {
546558
type: 'object',
547559
properties: {
548560
caseInsensitive: {
549-
type: 'boolean',
550-
default: false,
561+
anyOf: [
562+
{ type: 'boolean', default: false },
563+
{ type: 'string', enum: ['invert'] },
564+
],
551565
},
552566
order: {
553567
enum: ['ignore', 'asc', 'desc'],

tests/src/rules/order.js

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1981,6 +1981,54 @@ ruleTester.run('order', rule, {
19811981
message: '`foo` import should occur before import of `Bar`',
19821982
}],
19831983
}),
1984+
// Option alphabetize {order: 'asc': caseInsensitive: 'invert'}
1985+
test({
1986+
code: `
1987+
import a from 'bar';
1988+
import b from 'Foo';
1989+
import c from 'foo';
1990+
1991+
import index from './';
1992+
`,
1993+
output: `
1994+
import a from 'bar';
1995+
import c from 'foo';
1996+
import b from 'Foo';
1997+
1998+
import index from './';
1999+
`,
2000+
options: [{
2001+
groups: ['external', 'index'],
2002+
alphabetize: {order: 'asc', caseInsensitive: 'invert'},
2003+
}],
2004+
errors: [{
2005+
message: '`foo` import should occur before import of `Foo`',
2006+
}],
2007+
}),
2008+
// Option alphabetize {order: 'desc': caseInsensitive: 'invert'}
2009+
test({
2010+
code: `
2011+
import a from 'foo';
2012+
import b from 'Foo';
2013+
import c from 'bar';
2014+
2015+
import index from './';
2016+
`,
2017+
output: `
2018+
import b from 'Foo';
2019+
import a from 'foo';
2020+
import c from 'bar';
2021+
2022+
import index from './';
2023+
`,
2024+
options: [{
2025+
groups: ['external', 'index'],
2026+
alphabetize: {order: 'desc', caseInsensitive: 'invert'},
2027+
}],
2028+
errors: [{
2029+
message: '`Foo` import should occur before import of `foo`',
2030+
}],
2031+
}),
19842032
// Alphabetize with parent paths
19852033
test({
19862034
code: `
@@ -2013,7 +2061,7 @@ ruleTester.run('order', rule, {
20132061
const { cello } = require('./cello');
20142062
const blah = require('./blah');
20152063
import { hello } from './hello';
2016-
`,
2064+
`,
20172065
errors: [{
20182066
message: '`./int` import should occur before import of `./cello`',
20192067
}, {

0 commit comments

Comments
 (0)