Skip to content

Commit

Permalink
[New] no-unresolved: add caseSensitiveStrict option
Browse files Browse the repository at this point in the history
Fixes #1259.
  • Loading branch information
sergei-startsev authored and ljharb committed Aug 23, 2021
1 parent 2a8891f commit 35bd977
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 8 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Expand Up @@ -7,6 +7,7 @@ This change log adheres to standards from [Keep a CHANGELOG](http://keepachangel
## [Unreleased]

### Added
- [`no-unresolved`]: add `caseSensitiveStrict` option ([#1262], thanks [@sergei-startsev])
- [`no-unused-modules`]: add eslint v8 support ([#2194], thanks [@coderaiser])
- [`no-restricted-paths`]: add/restore glob pattern support ([#2219], thanks [@stropho])

Expand Down Expand Up @@ -1053,6 +1054,7 @@ for info on changes for earlier releases.
[#1294]: https://github.com/import-js/eslint-plugin-import/pull/1294
[#1290]: https://github.com/import-js/eslint-plugin-import/pull/1290
[#1277]: https://github.com/import-js/eslint-plugin-import/pull/1277
[#1262]: https://github.com/import-js/eslint-plugin-import/pull/1262
[#1257]: https://github.com/import-js/eslint-plugin-import/pull/1257
[#1253]: https://github.com/import-js/eslint-plugin-import/pull/1253
[#1248]: https://github.com/import-js/eslint-plugin-import/pull/1248
Expand Down
19 changes: 17 additions & 2 deletions docs/rules/no-unresolved.md
Expand Up @@ -76,10 +76,25 @@ By default, this rule will report paths whose case do not match the underlying f
const { default: x } = require('./foo') // reported if './foo' is actually './Foo' and caseSensitive: true
```

#### `caseSensitiveStrict`

The `caseSensitive` option does not detect case for the current working directory. The `caseSensitiveStrict` option allows checking `cwd` in resolved path. By default, the option is disabled.


```js
/*eslint import/no-unresolved: [2, { caseSensitiveStrict: true }]*/

// Absolute paths
import Foo from `/Users/fOo/bar/file.js` // reported, /Users/foo/bar/file.js
import Foo from `d:/fOo/bar/file.js` // reported, d:/foo/bar/file.js

// Relative paths, cwd is Users/foo/
import Foo from `./../fOo/bar/file.js` // reported
```

## When Not To Use It

If you're using a module bundler other than Node or Webpack, you may end up with
a lot of false positive reports of missing dependencies.
If you're using a module bundler other than Node or Webpack, you may end up with a lot of false positive reports of missing dependencies.

## Further Reading

Expand Down
13 changes: 8 additions & 5 deletions src/rules/no-unresolved.js
Expand Up @@ -18,14 +18,17 @@ module.exports = {
schema: [
makeOptionsSchema({
caseSensitive: { type: 'boolean', default: true },
caseSensitiveStrict: { type: 'boolean', default: false },
}),
],
},

create(context) {
const options = context.options[0] || {};

function checkSourceValue(source) {
const shouldCheckCase = !CASE_SENSITIVE_FS
&& (!context.options[0] || context.options[0].caseSensitive !== false);
const caseSensitive = !CASE_SENSITIVE_FS && options.caseSensitive !== false;
const caseSensitiveStrict = !CASE_SENSITIVE_FS && options.caseSensitiveStrict;

const resolvedPath = resolve(source.value, context);

Expand All @@ -34,9 +37,9 @@ module.exports = {
source,
`Unable to resolve path to module '${source.value}'.`
);
} else if (shouldCheckCase) {
} else if (caseSensitive || caseSensitiveStrict) {
const cacheSettings = ModuleCache.getSettings(context.settings);
if (!fileExistsWithCaseSync(resolvedPath, cacheSettings)) {
if (!fileExistsWithCaseSync(resolvedPath, cacheSettings, caseSensitiveStrict)) {
context.report(
source,
`Casing of ${source.value} does not match the underlying filesystem.`
Expand All @@ -45,6 +48,6 @@ module.exports = {
}
}

return moduleVisitor(checkSourceValue, context.options[0]);
return moduleVisitor(checkSourceValue, options);
},
};
29 changes: 28 additions & 1 deletion tests/src/rules/no-unresolved.js
Expand Up @@ -15,7 +15,7 @@ function runResolverTests(resolver) {
function rest(specs) {
specs.settings = Object.assign({},
specs.settings,
{ 'import/resolver': resolver },
{ 'import/resolver': resolver, 'import/cache': { lifetime: 0 } },
);

return test(specs);
Expand Down Expand Up @@ -227,6 +227,10 @@ function runResolverTests(resolver) {
});

if (!CASE_SENSITIVE_FS) {
const relativePath = './tests/files/jsx/MyUnCoolComponent.jsx';
const cwd = process.cwd();
const mismatchedPath = path.join(cwd.toUpperCase(), relativePath).replace(/\\/g, '/');

ruleTester.run('case sensitivity', rule, {
valid: [
rest({ // test with explicit flag
Expand All @@ -247,6 +251,29 @@ function runResolverTests(resolver) {
}),
],
});

ruleTester.run('case sensitivity strict', rule, {
valid: [
// #1259 issue
rest({ // caseSensitiveStrict is disabled by default
code: `import foo from "${mismatchedPath}"`,
}),
],

invalid: [
// #1259 issue
rest({ // test with enabled caseSensitiveStrict option
code: `import foo from "${mismatchedPath}"`,
options: [{ caseSensitiveStrict: true }],
errors: [`Casing of ${mismatchedPath} does not match the underlying filesystem.`],
}),
rest({ // test with enabled caseSensitiveStrict option and disabled caseSensitive
code: `import foo from "${mismatchedPath}"`,
options: [{ caseSensitiveStrict: true, caseSensitive: false }],
errors: [`Casing of ${mismatchedPath} does not match the underlying filesystem.`],
}),
],
});
}

}
Expand Down

0 comments on commit 35bd977

Please sign in to comment.