Skip to content

Commit

Permalink
[New] order: added caseInsensitive as an additional option to `al…
Browse files Browse the repository at this point in the history
…phabetize`

 - imp: mutateRanksToAlphabetizeV2 added to handle case insensitive sorting
 - tests: add two test cases for alphabetize.caseInsensitive: true
 - docs: added documentation for new options: alphabetize.caseInsensitive
 - imp: merged mutateRanksToAlphabetizeV2 to original
 - changelog: updated with caseInsensitive addition
  • Loading branch information
dbrewer5 authored and ljharb committed Dec 27, 2019
1 parent 4e8960d commit c28fa7c
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 6 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Expand Up @@ -5,6 +5,9 @@ This project adheres to [Semantic Versioning](http://semver.org/).
This change log adheres to standards from [Keep a CHANGELOG](http://keepachangelog.com).

## [Unreleased]
### Added
- [`order`]: added `caseInsensitive` as an additional option to `alphabetize` ([#1586], thanks [@dbrewer5])

### Fixed
- [`no-unused-modules`]: fix usage of `import/extensions` settings ([#1560], thanks [@stekycz])

Expand Down Expand Up @@ -625,6 +628,7 @@ for info on changes for earlier releases.

[`memo-parser`]: ./memo-parser/README.md

[#1586]: https://github.com/benmosher/eslint-plugin-import/pull/1586
[#1563]: https://github.com/benmosher/eslint-plugin-import/pull/1563
[#1560]: https://github.com/benmosher/eslint-plugin-import/pull/1560
[#1551]: https://github.com/benmosher/eslint-plugin-import/pull/1551
Expand Down Expand Up @@ -1046,3 +1050,4 @@ for info on changes for earlier releases.
[@randallreedjr]: https://github.com/randallreedjr
[@Pessimistress]: https://github.com/Pessimistress
[@stekycz]: https://github.com/stekycz
[@dbrewer5]: https://github.com/dbrewer5
6 changes: 5 additions & 1 deletion docs/rules/order.md
Expand Up @@ -189,16 +189,18 @@ import index from './';
import sibling from './foo';
```

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

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`).

Example setting:
```js
alphabetize: {
order: 'asc', /* sort in ascending order. Options: ['ignore', 'asc', 'desc'] */
caseInsensitive: true /* ignore case. Options: [true, false] */
}
```

Expand All @@ -210,12 +212,14 @@ import React, { PureComponent } from 'react';
import aTypes from 'prop-types';
import { compose, apply } from 'xcompose';
import * as classnames from 'classnames';
import blist from 'BList';
```

While this will pass:

```js
/* eslint import/order: ["error", {"alphabetize": true}] */
import blist from 'BList';
import * as classnames from 'classnames';
import aTypes from 'prop-types';
import React, { PureComponent } from 'react';
Expand Down
16 changes: 11 additions & 5 deletions src/rules/order.js
Expand Up @@ -267,7 +267,7 @@ function importsSorterDesc(importA, importB) {
return 0
}

function mutateRanksToAlphabetize(imported, order) {
function mutateRanksToAlphabetize(imported, alphabetizeOptions) {
const groupedByRanks = imported.reduce(function(acc, importedItem) {
if (!Array.isArray(acc[importedItem.rank])) {
acc[importedItem.rank] = []
Expand All @@ -278,10 +278,11 @@ function mutateRanksToAlphabetize(imported, order) {

const groupRanks = Object.keys(groupedByRanks)

const sorterFn = order === 'asc' ? importsSorterAsc : importsSorterDesc
const sorterFn = alphabetizeOptions.order === 'asc' ? importsSorterAsc : importsSorterDesc
const comparator = 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(sorterFn)
groupedByRanks[groupRank].sort(comparator)
})

// assign globally unique rank to each import
Expand Down Expand Up @@ -487,8 +488,9 @@ function makeNewlinesBetweenReport (context, imported, newlinesBetweenImports) {
function getAlphabetizeConfig(options) {
const alphabetize = options.alphabetize || {}
const order = alphabetize.order || 'ignore'
const caseInsensitive = alphabetize.caseInsensitive || false

return {order}
return {order, caseInsensitive}
}

module.exports = {
Expand Down Expand Up @@ -540,6 +542,10 @@ module.exports = {
alphabetize: {
type: 'object',
properties: {
caseInsensitive: {
type: 'boolean',
default: false,
},
order: {
enum: ['ignore', 'asc', 'desc'],
default: 'ignore',
Expand Down Expand Up @@ -604,7 +610,7 @@ module.exports = {
}

if (alphabetize.order !== 'ignore') {
mutateRanksToAlphabetize(imported, alphabetize.order)
mutateRanksToAlphabetize(imported, alphabetize)
}

makeOutOfOrderReport(context, imported)
Expand Down
46 changes: 46 additions & 0 deletions tests/src/rules/order.js
Expand Up @@ -1870,5 +1870,51 @@ ruleTester.run('order', rule, {
message: '`bar` import should occur before import of `Bar`',
}],
}),
// Option alphabetize {order: 'asc': caseInsensitive: true}
test({
code: `
import b from 'foo';
import a from 'Bar';
import index from './';
`,
output: `
import a from 'Bar';
import b from 'foo';
import index from './';
`,
options: [{
groups: ['external', 'index'],
alphabetize: {order: 'asc', caseInsensitive: true},
}],
errors: [{
ruleID: 'order',
message: '`Bar` import should occur before import of `foo`',
}],
}),
// Option alphabetize {order: 'desc': caseInsensitive: true}
test({
code: `
import a from 'Bar';
import b from 'foo';
import index from './';
`,
output: `
import b from 'foo';
import a from 'Bar';
import index from './';
`,
options: [{
groups: ['external', 'index'],
alphabetize: {order: 'desc', caseInsensitive: true},
}],
errors: [{
ruleID: 'order',
message: '`foo` import should occur before import of `Bar`',
}],
}),
].filter((t) => !!t),
})

0 comments on commit c28fa7c

Please sign in to comment.