97 lines
2.8 KiB
JavaScript
97 lines
2.8 KiB
JavaScript
/**
|
|
* @fileoverview Rule to flag use of .only in tests, preventing focused tests being committed accidentally
|
|
* @author Levi Buzolic
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
//------------------------------------------------------------------------------
|
|
// Rule Definition
|
|
//------------------------------------------------------------------------------
|
|
|
|
const defaultOptions = {
|
|
block: ['describe', 'it', 'context', 'test', 'tape', 'fixture', 'serial', 'Feature', 'Scenario', 'Given', 'And', 'When', 'Then'],
|
|
focus: ['only'],
|
|
fix: false,
|
|
};
|
|
|
|
module.exports = {
|
|
meta: {
|
|
docs: {
|
|
description: 'disallow .only blocks in tests',
|
|
category: 'Possible Errors',
|
|
recommended: true,
|
|
url: 'https://github.com/levibuzolic/eslint-plugin-no-only-tests',
|
|
},
|
|
fixable: true,
|
|
schema: [
|
|
{
|
|
type: 'object',
|
|
properties: {
|
|
block: {
|
|
type: 'array',
|
|
items: {
|
|
type: 'string',
|
|
},
|
|
uniqueItems: true,
|
|
default: defaultOptions.block,
|
|
},
|
|
focus: {
|
|
type: 'array',
|
|
items: {
|
|
type: 'string',
|
|
},
|
|
uniqueItems: true,
|
|
default: defaultOptions.focus,
|
|
},
|
|
fix: {
|
|
type: 'boolean',
|
|
default: defaultOptions.fix,
|
|
},
|
|
},
|
|
additionalProperties: false,
|
|
},
|
|
],
|
|
},
|
|
create(context) {
|
|
const options = Object.assign({}, defaultOptions, context.options[0]);
|
|
const blocks = options.block || [];
|
|
const focus = options.focus || [];
|
|
const fix = !!options.fix;
|
|
|
|
return {
|
|
Identifier(node) {
|
|
const parentObject = node.parent && node.parent.object;
|
|
if (parentObject == null) return;
|
|
if (focus.indexOf(node.name) === -1) return;
|
|
|
|
const callPath = getCallPath(node.parent).join('.');
|
|
|
|
// comparison guarantees that matching is done with the beginning of call path
|
|
if (
|
|
blocks.find(block => {
|
|
// Allow wildcard tail matching of blocks when ending in a `*`
|
|
if (block.endsWith('*')) return callPath.startsWith(block.replace(/\*$/, ''));
|
|
return callPath.startsWith(`${block}.`);
|
|
})
|
|
) {
|
|
context.report({
|
|
node,
|
|
message: callPath + ' not permitted',
|
|
fix: fix ? fixer => fixer.removeRange([node.range[0] - 1, node.range[1]]) : undefined,
|
|
});
|
|
}
|
|
},
|
|
};
|
|
},
|
|
};
|
|
|
|
function getCallPath(node, path = []) {
|
|
if (node) {
|
|
const nodeName = node.name || (node.property && node.property.name);
|
|
if (node.object) return getCallPath(node.object, [nodeName, ...path]);
|
|
if (node.callee) return getCallPath(node.callee, path);
|
|
return [nodeName, ...path];
|
|
}
|
|
return path;
|
|
}
|