Skip to content

Commit

Permalink
New: no-unused-modules rule - added default src, more comprehensive…
Browse files Browse the repository at this point in the history
… sanity checks

Signed-off-by: René Fermann <rene.fermann@gmx.de>
  • Loading branch information
rfermann committed Aug 5, 2018
1 parent 230122b commit aa7253b
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 28 deletions.
59 changes: 40 additions & 19 deletions src/rules/no-unused-modules.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,17 @@

import Exports from '../ExportMap'
import { makeOptionsSchema } from 'eslint-module-utils/moduleVisitor'
import { listFilesToProcess } from 'eslint/lib/util/glob-util'
import resolve from 'eslint-module-utils/resolve'
import docsUrl from '../docsUrl'

// eslint/lib/util/glob-util has been moved to eslint/lib/util/glob-utils with version 5.3
let listFilesToProcess
try {
listFilesToProcess = require('eslint/lib/util/glob-util').listFilesToProcess
} catch (err) {
listFilesToProcess = require('eslint/lib/util/glob-utils').listFilesToProcess
}

const EXPORT_DEFAULT_DECLARATION = 'ExportDefaultDeclaration'
const EXPORT_NAMED_DECLARATION = 'ExportNamedDeclaration'
const IMPORT_DECLARATION = 'ImportDeclaration'
Expand Down Expand Up @@ -113,6 +120,13 @@ const determineUsage = () => {
})
}

const getSrc = src => {
if (src) {
return src
}
return [process.cwd()]
}

/**
* prepare the lists of existing imports and exports - should only be executed once at
* the start of a new eslint run
Expand All @@ -121,32 +135,38 @@ const doPreparation = (src, ignore, context) => {
const { id } = context

// do some sanity checks
if (!Array.isArray(src)) {
if (typeof src !== UNDEFINED && !Array.isArray(src)) {
throw new Error(`Rule ${id}: src option must be an array`)
}

if (!Array.isArray(ignore)) {
if (typeof ignore !== UNDEFINED && !Array.isArray(ignore)) {
throw new Error(`Rule ${id}: ignore option must be an array`)
}

if (src.length < 1) {
throw new Error(`Rule ${id}: src option must be defined`)
}

// no empty patterns for paths, as this will cause issues during path resolution
src.forEach(file => {
if (file.length < 1) {
throw new Error(`Rule ${id}: src option must not contain empty strings`)
}
})

ignore.forEach(file => {
if (file.length < 1) {
throw new Error(`Rule ${id}: ignore option must not contain empty strings`)
}
})
if (src) {
src.forEach(file => {
if (typeof file !== 'string') {
throw new Error(`Rule ${id}: src option must not contain values other than strings`)
}
if (file.length < 1) {
throw new Error(`Rule ${id}: src option must not contain empty strings`)
}
})
}

if (ignore) {
ignore.forEach(file => {
if (typeof file !== 'string') {
throw new Error(`Rule ${id}: ignore option must not contain values other than strings`)
}
if (file.length < 1) {
throw new Error(`Rule ${id}: ignore option must not contain empty strings`)
}
})
}

const srcFiles = resolveFiles(src, ignore)
const srcFiles = resolveFiles(getSrc(src), ignore)
prepareImportsAndExports(srcFiles, context)
determineUsage()
preparationDone = true
Expand All @@ -168,6 +188,7 @@ const newDefaultImportExists = specifiers => {

module.exports = {
doPreparation,
getSrc,
meta: {
docs: { url: docsUrl('no-unused-modules') },
schema: [
Expand Down
43 changes: 34 additions & 9 deletions tests/src/rules/no-unused-modules.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { test, testFilePath } from '../utils'

import { RuleTester } from 'eslint'
import { expect } from 'chai';
import { expect } from 'chai'

const doPreparation = require( '../../../src/rules/no-unused-modules').doPreparation
const getSrc = require( '../../../src/rules/no-unused-modules').getSrc

const ruleTester = new RuleTester()
, rule = require('rules/no-unused-modules')
Expand All @@ -21,22 +22,46 @@ const unusedExportsOptions = [{
}]

describe('doPreparation throws correct errors', () => {
// const fn = doPreparation()
const context = {id: 'no-unused-modules' }
const context = { id: 'no-unused-modules' }
it('should throw an error, if src is not an array', () => {
expect(doPreparation.bind(doPreparation, null, null, context)).to.throw(`Rule ${context.id}: src option must be an array`)
})
it('should throw an error, if ignore is not an array', () => {
expect(doPreparation.bind(doPreparation, [], null, context)).to.throw(`Rule ${context.id}: ignore option must be an array`)
})
it('should throw an error, if src is empty', () => {
expect(doPreparation.bind(doPreparation, [], [], context)).to.throw(`Rule ${context.id}: src option must be defined`)
it('should throw an error, if src contains empty strings', () => {
expect(doPreparation.bind(doPreparation, [''], [], context)).to.throw(`Rule ${context.id}: src option must not contain empty strings`)
})
it('should throw an error, if src is empty', () => {
expect(doPreparation.bind(doPreparation, [""], [], context)).to.throw(`Rule ${context.id}: src option must not contain empty strings`)
it('should throw an error, if src contains values other than strings', () => {
expect(doPreparation.bind(doPreparation, [false], [], context)).to.throw(`Rule ${context.id}: src option must not contain values other than strings`)
})
it('should throw an error, if src is empty', () => {
expect(doPreparation.bind(doPreparation, ["src"], [""], context)).to.throw(`Rule ${context.id}: ignore option must not contain empty strings`)
it('should throw an error, if src contains values other than strings', () => {
expect(doPreparation.bind(doPreparation, [null], [], context)).to.throw(`Rule ${context.id}: src option must not contain values other than strings`)
})
it('should throw an error, if src contains values other than strings', () => {
expect(doPreparation.bind(doPreparation, [undefined], [], context)).to.throw(`Rule ${context.id}: src option must not contain values other than strings`)
})
it('should throw an error, if ignore contains empty strings', () => {
expect(doPreparation.bind(doPreparation, ['src'], [''], context)).to.throw(`Rule ${context.id}: ignore option must not contain empty strings`)
})
it('should throw an error, if ignore contains values other than strings', () => {
expect(doPreparation.bind(doPreparation, ['src'], [false], context)).to.throw(`Rule ${context.id}: ignore option must not contain values other than strings`)
})
it('should throw an error, if ignore contains values other than strings', () => {
expect(doPreparation.bind(doPreparation, ['src'], [null], context)).to.throw(`Rule ${context.id}: ignore option must not contain values other than strings`)
})
it('should throw an error, if ignore contains values other than strings', () => {
expect(doPreparation.bind(doPreparation, ['src'], [undefined], context)).to.throw(`Rule ${context.id}: ignore option must not contain values other than strings`)
})
})

describe('getSrc returns correct source', () => {
it('if src is provided', () => {
const src = ['file-a.js']
expect(getSrc(src)).to.eq(src)
})
it('if src is not provided', () => {
expect(getSrc()).to.eql([process.cwd()])
})
})

Expand Down

0 comments on commit aa7253b

Please sign in to comment.