Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Allow ESLint rules to override extensions and glob patterns
  • Loading branch information
novemberborn committed Jun 10, 2019
1 parent 7366a9d commit b3c9ea7
Show file tree
Hide file tree
Showing 5 changed files with 139 additions and 11 deletions.
33 changes: 26 additions & 7 deletions eslint-plugin-helper.js
Expand Up @@ -4,15 +4,34 @@ const normalizeExtensions = require('./lib/extensions');
const {hasExtension, normalizeGlobs, classify} = require('./lib/globs');
const loadConfig = require('./lib/load-config');

const cache = new Map();
const configCache = new Map();
const helperCache = new Map();

function load(projectDir) {
if (cache.has(projectDir)) {
return cache.get(projectDir);
function load(projectDir, overrides) {
const cacheKey = `${JSON.stringify(overrides)}\n${projectDir}`;
if (helperCache.has(cacheKey)) {
return helperCache.get(cacheKey);
}

let conf;
let babelConfig;
if (configCache.has(projectDir)) {
({conf, babelConfig} = configCache.get(projectDir));
} else {
conf = loadConfig(projectDir);
babelConfig = babelPipeline.validate(conf.babel);
configCache.set(projectDir, {conf, babelConfig});
}

if (overrides) {
conf = {...conf, ...overrides};
if (overrides.extensions) {
// Ignore extensions from the Babel config. Assume all extensions are
// provided in the override.
babelConfig = null;
}
}

const conf = loadConfig(projectDir);
const babelConfig = babelPipeline.validate(conf.babel);
const extensions = normalizeExtensions(conf.extensions || [], babelConfig);
const globs = {cwd: projectDir, ...normalizeGlobs(conf.files, conf.helpers, conf.sources, extensions.all)};

Expand All @@ -30,7 +49,7 @@ function load(projectDir) {
return classify(`${importPath}.${globs.extensions[0]}`, globs);
}
});
cache.set(projectDir, helper);
helperCache.set(cacheKey, helper);
return helper;
}

Expand Down
104 changes: 102 additions & 2 deletions test/eslint-plugin-helper.js
Expand Up @@ -5,11 +5,16 @@ const {test} = require('tap');
const {load} = require('../eslint-plugin-helper');

const projectDir = path.join(__dirname, 'fixture/eslint-plugin-helper');
const overrideDir = path.join(__dirname, 'fixture/eslint-plugin-helper/for-overriding');

test('caches loaded configuration', t => {
const expected = load(projectDir);
const actual = load(projectDir);
t.is(expected, actual);
t.is(expected, load(projectDir));

const withOverride = load(projectDir, {});
t.not(expected, withOverride);
t.is(withOverride, load(projectDir, {}));

t.end();
});

Expand Down Expand Up @@ -43,6 +48,41 @@ test('classifies files according to the configuration', t => {
t.end();
});

test('classifies files according to configuration override', t => {
const helper = load(overrideDir, {
extensions: ['foo'],
files: ['tests/**/*'],
helpers: ['helpers/*'],
sources: ['source.*']
});
t.deepEqual(helper.classifyFile(path.join(overrideDir, 'tests/test.foo')), {
isHelper: false,
isSource: false,
isTest: true
});
t.deepEqual(helper.classifyFile(path.join(overrideDir, 'tests/_helper.foo')), {
isHelper: true,
isSource: false,
isTest: false
});
t.deepEqual(helper.classifyFile(path.join(overrideDir, 'helpers/helper.foo')), {
isHelper: true,
isSource: false,
isTest: false
});
t.deepEqual(helper.classifyFile(path.join(overrideDir, 'source.foo')), {
isHelper: false,
isSource: true,
isTest: false
});
t.deepEqual(helper.classifyFile(path.join(overrideDir, 'tests/test.js')), {
isHelper: false,
isSource: false,
isTest: false
});
t.end();
});

test('classifies imports with extension according to the configuration', t => {
const helper = load(projectDir);
t.deepEqual(helper.classifyImport(path.join(projectDir, 'tests/test.foo')), {
Expand All @@ -68,6 +108,36 @@ test('classifies imports with extension according to the configuration', t => {
t.end();
});

test('classifies imports with extension according to the override', t => {
const helper = load(overrideDir, {
extensions: ['foo'],
files: ['tests/**/*'],
helpers: ['helpers/*'],
sources: ['source.*']
});
t.deepEqual(helper.classifyImport(path.join(overrideDir, 'tests/test.foo')), {
isHelper: false,
isSource: false,
isTest: true
});
t.deepEqual(helper.classifyImport(path.join(overrideDir, 'tests/_helper.foo')), {
isHelper: true,
isSource: false,
isTest: false
});
t.deepEqual(helper.classifyImport(path.join(overrideDir, 'helpers/helper.foo')), {
isHelper: true,
isSource: false,
isTest: false
});
t.deepEqual(helper.classifyImport(path.join(overrideDir, 'source.foo')), {
isHelper: false,
isSource: true,
isTest: false
});
t.end();
});

test('classifies imports without extension according to the configuration', t => {
const helper = load(projectDir);
t.deepEqual(helper.classifyImport(path.join(projectDir, 'tests/test')), {
Expand All @@ -92,3 +162,33 @@ test('classifies imports without extension according to the configuration', t =>
});
t.end();
});

test('classifies imports without extension according to the override', t => {
const helper = load(overrideDir, {
extensions: ['foo'],
files: ['tests/**/*'],
helpers: ['helpers/*'],
sources: ['source.*']
});
t.deepEqual(helper.classifyImport(path.join(overrideDir, 'tests/test')), {
isHelper: false,
isSource: false,
isTest: true
});
t.deepEqual(helper.classifyImport(path.join(overrideDir, 'tests/_helper')), {
isHelper: true,
isSource: false,
isTest: false
});
t.deepEqual(helper.classifyImport(path.join(overrideDir, 'helpers/helper')), {
isHelper: true,
isSource: false,
isTest: false
});
t.deepEqual(helper.classifyImport(path.join(overrideDir, 'source')), {
isHelper: false,
isSource: true,
isTest: false
});
t.end();
});
4 changes: 2 additions & 2 deletions test/fixture/eslint-plugin-helper/ava.config.js
@@ -1,6 +1,6 @@
export default {
babel: false,
extensions: ['foo'],
files: ['tests/**/*'],
helpers: ['helpers/*'],
extensions: ['foo']
helpers: ['helpers/*']
};
@@ -0,0 +1,8 @@
export default {
babel: {
extensions: ['bar']
},
files: ['build/tests/**/*'],
helpers: ['build/helpers/*'],
sources: ['src/**/*']
};
@@ -0,0 +1 @@
{}

0 comments on commit b3c9ea7

Please sign in to comment.