Skip to content

Commit

Permalink
[New] order: add caseInsensitive: 'invert' option
Browse files Browse the repository at this point in the history
  • Loading branch information
forivall committed Mar 3, 2021
1 parent e871a9a commit dbb6506
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 5 deletions.
4 changes: 2 additions & 2 deletions docs/rules/order.md
Original file line number Diff line number Diff line change
Expand Up @@ -216,12 +216,12 @@ import index from './';
import sibling from './foo';
```

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

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

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

Example setting:
```js
Expand Down
20 changes: 17 additions & 3 deletions src/rules/order.js
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,15 @@ function getSorter(ascending) {
};
}

function swapCase(input) {
let result = '';
for (let i = 0; i < input.length; i++) {
const lower = input[i].toLowerCase();
result += input[i] === lower ? input[i].toUpperCase() : lower;
}
return result;
}

function mutateRanksToAlphabetize(imported, alphabetizeOptions) {
const groupedByRanks = imported.reduce(function(acc, importedItem) {
if (!Array.isArray(acc[importedItem.rank])) {
Expand All @@ -272,7 +281,10 @@ function mutateRanksToAlphabetize(imported, alphabetizeOptions) {
const groupRanks = Object.keys(groupedByRanks);

const sorterFn = getSorter(alphabetizeOptions.order === 'asc');
const comparator = alphabetizeOptions.caseInsensitive ? (a, b) => sorterFn(String(a).toLowerCase(), String(b).toLowerCase()) : (a, b) => sorterFn(a, b);
const comparator =
alphabetizeOptions.caseInsensitive === 'invert' ? (a, b) => sorterFn(swapCase(String(a)), swapCase(String(b)))
: alphabetizeOptions.caseInsensitive ? (a, b) => sorterFn(String(a).toLowerCase(), String(b).toLowerCase())
: (a, b) => sorterFn(a, b);
// sort imports locally within their group
groupRanks.forEach(function(groupRank) {
groupedByRanks[groupRank].sort(comparator);
Expand Down Expand Up @@ -556,8 +568,10 @@ module.exports = {
type: 'object',
properties: {
caseInsensitive: {
type: 'boolean',
default: false,
anyOf: [
{ type: 'boolean', default: false },
{ type: 'string', enum: ['invert'] },
],
},
order: {
enum: ['ignore', 'asc', 'desc'],
Expand Down
48 changes: 48 additions & 0 deletions tests/src/rules/order.js
Original file line number Diff line number Diff line change
Expand Up @@ -2121,6 +2121,54 @@ ruleTester.run('order', rule, {
message: '`foo` import should occur before import of `Bar`',
}],
}),
// Option alphabetize {order: 'asc': caseInsensitive: 'invert'}
test({
code: `
import a from 'bar';
import b from 'Foo';
import c from 'foo';
import index from './';
`,
output: `
import a from 'bar';
import c from 'foo';
import b from 'Foo';
import index from './';
`,
options: [{
groups: ['external', 'index'],
alphabetize: { order: 'asc', caseInsensitive: 'invert' },
}],
errors: [{
message: '`foo` import should occur before import of `Foo`',
}],
}),
// Option alphabetize {order: 'desc': caseInsensitive: 'invert'}
test({
code: `
import a from 'foo';
import b from 'Foo';
import c from 'bar';
import index from './';
`,
output: `
import b from 'Foo';
import a from 'foo';
import c from 'bar';
import index from './';
`,
options: [{
groups: ['external', 'index'],
alphabetize: { order: 'desc', caseInsensitive: 'invert' },
}],
errors: [{
message: '`Foo` import should occur before import of `foo`',
}],
}),
// Alphabetize with parent paths
test({
code: `
Expand Down

0 comments on commit dbb6506

Please sign in to comment.