UNPKG

eslint-plugin-mocha

Version:

Eslint rules for mocha.

114 lines 4.6 kB
import { createMochaVisitors } from "../ast/mocha-visitors.js"; import { expectNodeRange } from "../ast/node-location.js"; import { isBlockStatement } from "../ast/node-types.js"; import { getLastOrThrow } from "../list.js"; import { getTopLevelMochaExpression, isDirectStatementInScope } from "./direct-mocha-statement.js"; const minimumAmountOfLinesBetweenNeeded = 2; function containsNode(nodeA, nodeB) { const rangeA = expectNodeRange(nodeA); const rangeB = expectNodeRange(nodeB); return rangeB[1] <= rangeA[1] && rangeB[0] >= rangeA[0]; } function isFirstStatementInScope(scopeNode, node) { const [firstNode] = scopeNode.body; return firstNode === undefined || containsNode(firstNode, node); } function getSpacingCheck(currentLayer, entity) { const { statementNode, beforeToken } = entity; const statementNodeLocation = statementNode.loc; if (beforeToken === null || statementNodeLocation === null || statementNodeLocation === undefined || isFirstStatementInScope(currentLayer.scopeNode, statementNode)) { return undefined; } return { beforeToken, linesBetween: statementNodeLocation.start.line - beforeToken.loc.end.line, reportNode: entity.reportNode }; } export const consistentSpacingBetweenBlocksRule = { meta: { type: 'suggestion', docs: { description: 'Require consistent spacing between blocks', recommended: false, url: 'https://github.com/lo1tuma/eslint-plugin-mocha/blob/main/documentation/rules/' + 'consistent-spacing-between-blocks.md' }, fixable: 'whitespace', schema: [], messages: { expectedLineBreak: 'Expected line break before this statement.' }, languages: ['js/js'] }, create(context) { const layers = []; const { sourceCode } = context; function addEntityToCurrentLayer(visitorContext) { const currentLayer = getLastOrThrow(layers); if (isDirectStatementInScope(currentLayer.scopeNode, visitorContext.node)) { const statementNode = getTopLevelMochaExpression(visitorContext.node); layers[layers.length - 1] = { ...currentLayer, entities: [ ...currentLayer.entities, { reportNode: visitorContext.node, statementNode, beforeToken: sourceCode.getTokenBefore(statementNode, { includeComments: false }) } ] }; } } function checkCurrentLayer() { const currentLayer = getLastOrThrow(layers); for (const entity of currentLayer.entities) { const spacingCheck = getSpacingCheck(currentLayer, entity); if (spacingCheck !== undefined && spacingCheck.linesBetween < minimumAmountOfLinesBetweenNeeded) { context.report({ node: spacingCheck.reportNode, messageId: 'expectedLineBreak', fix(fixer) { return fixer.insertTextAfter(spacingCheck.beforeToken, spacingCheck.linesBetween === 0 ? '\n\n' : '\n'); } }); } } } return createMochaVisitors(context, { suite(visitorContext) { addEntityToCurrentLayer(visitorContext); }, suiteCallback(visitorContext) { const { node } = visitorContext; if (isBlockStatement(node.body)) { layers.push({ entities: [], scopeNode: node.body }); } }, 'suiteCallback:exit'(visitorContext) { if (isBlockStatement(visitorContext.node.body)) { checkCurrentLayer(); layers.pop(); } }, Program(node) { layers.push({ entities: [], scopeNode: node }); }, 'Program:exit'() { checkCurrentLayer(); }, testCase(visitorContext) { addEntityToCurrentLayer(visitorContext); }, hook(visitorContext) { addEntityToCurrentLayer(visitorContext); } }); } }; //# sourceMappingURL=consistent-spacing-between-blocks.js.map