Skip to content

Commit

Permalink
[Fix] no-unused-modules: ignore flow type imports
Browse files Browse the repository at this point in the history
Fixes #1564.
  • Loading branch information
nicolashenry authored and ljharb committed Sep 21, 2020
1 parent c51b6a9 commit 5ade156
Show file tree
Hide file tree
Showing 17 changed files with 157 additions and 54 deletions.
4 changes: 0 additions & 4 deletions src/rules/no-unused-modules.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,6 @@ const IMPORT_DEFAULT_SPECIFIER = 'ImportDefaultSpecifier'
const VARIABLE_DECLARATION = 'VariableDeclaration'
const FUNCTION_DECLARATION = 'FunctionDeclaration'
const CLASS_DECLARATION = 'ClassDeclaration'
const INTERFACE_DECLARATION = 'InterfaceDeclaration'
const TYPE_ALIAS = 'TypeAlias'
const TS_INTERFACE_DECLARATION = 'TSInterfaceDeclaration'
const TS_TYPE_ALIAS_DECLARATION = 'TSTypeAliasDeclaration'
const TS_ENUM_DECLARATION = 'TSEnumDeclaration'
Expand All @@ -75,8 +73,6 @@ function forEachDeclarationIdentifier(declaration, cb) {
if (
declaration.type === FUNCTION_DECLARATION ||
declaration.type === CLASS_DECLARATION ||
declaration.type === INTERFACE_DECLARATION ||
declaration.type === TYPE_ALIAS ||
declaration.type === TS_INTERFACE_DECLARATION ||
declaration.type === TS_TYPE_ALIAS_DECLARATION ||
declaration.type === TS_ENUM_DECLARATION
Expand Down
1 change: 1 addition & 0 deletions tests/files/no-unused-modules/flow/flow-0.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import { type FooType, type FooInterface } from './flow-2';
3 changes: 3 additions & 0 deletions tests/files/no-unused-modules/flow/flow-1.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// @flow strict
export type Bar = number;
export interface BarInterface {};
3 changes: 3 additions & 0 deletions tests/files/no-unused-modules/flow/flow-2.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// @flow strict
export type FooType = string;
export interface FooInterface {};
1 change: 1 addition & 0 deletions tests/files/no-unused-modules/flow/flow-3.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import type { FooType, FooInterface } from './flow-4';
3 changes: 3 additions & 0 deletions tests/files/no-unused-modules/flow/flow-4.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// @flow strict
export type FooType = string;
export interface FooInterface {};
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import type {b} from './file-ts-b-used-as-type';
import type {c} from './file-ts-c-used-as-type';
import type {d} from './file-ts-d-used-as-type';
import type {e} from './file-ts-e-used-as-type';

const a: typeof b = 2;
const a2: c = {};
const a3: d = {};
const a4: typeof e = undefined;
6 changes: 3 additions & 3 deletions tests/files/no-unused-modules/typescript/file-ts-a.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@ import {c} from './file-ts-c';
import {d} from './file-ts-d';
import {e} from './file-ts-e';

export const a = b + 1 + e.f;
export const a2: c = {};
export const a3: d = {};
const a = b + 1 + e.f;
const a2: c = {};
const a3: d = {};
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const b = 2;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const b = 2;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export interface c {};
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export interface c {};
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export type d = {};
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export type d = {};
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export enum e { f };
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export enum e { f };
173 changes: 126 additions & 47 deletions tests/src/rules/no-unused-modules.js
Original file line number Diff line number Diff line change
Expand Up @@ -744,65 +744,96 @@ describe('Avoid errors if re-export all from umd compiled library', () => {
})
})

describe('correctly work with Typescript only files', () => {
typescriptRuleTester.run('no-unused-modules', rule, {
valid: [
test({
options: unusedExportsTypescriptOptions,
code: 'import a from "file-ts-a";',
parser: require.resolve('babel-eslint'),
filename: testFilePath('./no-unused-modules/typescript/file-ts-a.ts'),
}),
],
invalid: [
test({
options: unusedExportsTypescriptOptions,
code: `export const b = 2;`,
parser: require.resolve('babel-eslint'),
filename: testFilePath('./no-unused-modules/typescript/file-ts-b.ts'),
errors: [
error(`exported declaration 'b' not used within other modules`),
],
}),
test({
options: unusedExportsTypescriptOptions,
code: `export interface c {};`,
parser: require.resolve('babel-eslint'),
filename: testFilePath('./no-unused-modules/typescript/file-ts-c.ts'),
errors: [
error(`exported declaration 'c' not used within other modules`),
],
}),
test({
options: unusedExportsTypescriptOptions,
code: `export type d = {};`,
parser: require.resolve('babel-eslint'),
filename: testFilePath('./no-unused-modules/typescript/file-ts-d.ts'),
errors: [
error(`exported declaration 'd' not used within other modules`),
],
}),
],
})
})

context('TypeScript', function () {
getTSParsers().forEach((parser) => {
typescriptRuleTester.run('no-unused-modules', rule, {
valid: [
test({
options: unusedExportsTypescriptOptions,
code: 'import a from "file-ts-a";',
code: `
import {b} from './file-ts-b';
import {c} from './file-ts-c';
import {d} from './file-ts-d';
import {e} from './file-ts-e';
const a = b + 1 + e.f;
const a2: c = {};
const a3: d = {};
`,
parser: parser,
filename: testFilePath('./no-unused-modules/typescript/file-ts-a.ts'),
}),
test({
options: unusedExportsTypescriptOptions,
code: `export const b = 2;`,
parser: parser,
filename: testFilePath('./no-unused-modules/typescript/file-ts-b.ts'),
}),
test({
options: unusedExportsTypescriptOptions,
code: `export interface c {};`,
parser: parser,
filename: testFilePath('./no-unused-modules/typescript/file-ts-c.ts'),
}),
test({
options: unusedExportsTypescriptOptions,
code: `export type d = {};`,
parser: parser,
filename: testFilePath('./no-unused-modules/typescript/file-ts-d.ts'),
}),
test({
options: unusedExportsTypescriptOptions,
code: `export enum e { f };`,
parser: parser,
filename: testFilePath('./no-unused-modules/typescript/file-ts-e.ts'),
}),
test({
options: unusedExportsTypescriptOptions,
code: `
import type {b} from './file-ts-b-used-as-type';
import type {c} from './file-ts-c-used-as-type';
import type {d} from './file-ts-d-used-as-type';
import type {e} from './file-ts-e-used-as-type';
const a: typeof b = 2;
const a2: c = {};
const a3: d = {};
const a4: typeof e = undefined;
`,
parser: parser,
filename: testFilePath('./no-unused-modules/typescript/file-ts-a-import-type.ts'),
}),
test({
options: unusedExportsTypescriptOptions,
code: `export const b = 2;`,
parser: parser,
filename: testFilePath('./no-unused-modules/typescript/file-ts-b-used-as-type.ts'),
}),
test({
options: unusedExportsTypescriptOptions,
code: `export interface c {};`,
parser: parser,
filename: testFilePath('./no-unused-modules/typescript/file-ts-c-used-as-type.ts'),
}),
test({
options: unusedExportsTypescriptOptions,
code: `export type d = {};`,
parser: parser,
filename: testFilePath('./no-unused-modules/typescript/file-ts-d-used-as-type.ts'),
}),
test({
options: unusedExportsTypescriptOptions,
code: `export enum e { f };`,
parser: parser,
filename: testFilePath('./no-unused-modules/typescript/file-ts-e-used-as-type.ts'),
}),
],
invalid: [
test({
options: unusedExportsTypescriptOptions,
code: `export const b = 2;`,
parser: parser,
filename: testFilePath('./no-unused-modules/typescript/file-ts-b.ts'),
filename: testFilePath('./no-unused-modules/typescript/file-ts-b-unused.ts'),
errors: [
error(`exported declaration 'b' not used within other modules`),
],
Expand All @@ -811,7 +842,7 @@ context('TypeScript', function () {
options: unusedExportsTypescriptOptions,
code: `export interface c {};`,
parser: parser,
filename: testFilePath('./no-unused-modules/typescript/file-ts-c.ts'),
filename: testFilePath('./no-unused-modules/typescript/file-ts-c-unused.ts'),
errors: [
error(`exported declaration 'c' not used within other modules`),
],
Expand All @@ -820,7 +851,7 @@ context('TypeScript', function () {
options: unusedExportsTypescriptOptions,
code: `export type d = {};`,
parser: parser,
filename: testFilePath('./no-unused-modules/typescript/file-ts-d.ts'),
filename: testFilePath('./no-unused-modules/typescript/file-ts-d-unused.ts'),
errors: [
error(`exported declaration 'd' not used within other modules`),
],
Expand All @@ -829,7 +860,7 @@ context('TypeScript', function () {
options: unusedExportsTypescriptOptions,
code: `export enum e { f };`,
parser: parser,
filename: testFilePath('./no-unused-modules/typescript/file-ts-e.ts'),
filename: testFilePath('./no-unused-modules/typescript/file-ts-e-unused.ts'),
errors: [
error(`exported declaration 'e' not used within other modules`),
],
Expand Down Expand Up @@ -862,3 +893,51 @@ describe('correctly work with JSX only files', () => {
],
})
})

describe('ignore flow types', () => {
ruleTester.run('no-unused-modules', rule, {
valid: [
test({
options: unusedExportsOptions,
code: 'import { type FooType, type FooInterface } from "./flow-2";',
parser: require.resolve('babel-eslint'),
filename: testFilePath('./no-unused-modules/flow/flow-0.js'),
}),
test({
options: unusedExportsOptions,
code: `// @flow strict
export type FooType = string;
export interface FooInterface {};
`,
parser: require.resolve('babel-eslint'),
filename: testFilePath('./no-unused-modules/flow/flow-2.js'),
}),
test({
options: unusedExportsOptions,
code: 'import type { FooType, FooInterface } from "./flow-4";',
parser: require.resolve('babel-eslint'),
filename: testFilePath('./no-unused-modules/flow/flow-3.js'),
}),
test({
options: unusedExportsOptions,
code: `// @flow strict
export type FooType = string;
export interface FooInterface {};
`,
parser: require.resolve('babel-eslint'),
filename: testFilePath('./no-unused-modules/flow/flow-4.js'),
}),
test({
options: unusedExportsOptions,
code: `// @flow strict
export type Bar = number;
export interface BarInterface {};
`,
parser: require.resolve('babel-eslint'),
filename: testFilePath('./no-unused-modules/flow/flow-1.js'),
}),
],
invalid: [],
})
})

0 comments on commit 5ade156

Please sign in to comment.