UNPKG

gherkin-lint-ts

Version:

Gherkin features linter written in Typescript

100 lines 4.55 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.run = exports.name = void 0; const chalk_1 = __importDefault(require("chalk")); exports.name = "no-unused-variables"; function run(feature) { var _a; if (!feature) { return []; } const errors = []; const stepVariableRegex = /<([^>]*)>/gu; (_a = feature.children) === null || _a === void 0 ? void 0 : _a.forEach(child => { var _a, _b; if (!child.scenario) { // Variables are a feature of Scenarios (as of Gherkin 9?) and Scenario Outlines only return; } const examples = child.scenario.examples; if (!(examples === null || examples === void 0 ? void 0 : examples.length)) { // If there is no examples table, the rule doesn't apply return; } // Maps of variableName -> lineNo const examplesVariables = {}; const scenarioVariables = {}; let match; // Collect all the entries of the examples table examples.forEach(example => { if (example.tableHeader && example.tableHeader.cells) { example.tableHeader.cells.forEach(cell => { var _a; if (cell.value) { examplesVariables[cell.value] = (_a = cell.location) === null || _a === void 0 ? void 0 : _a.line; } }); } }); // Collect the variables used in the scenario outline // Scenario names can include variables while ((match = stepVariableRegex.exec(child.scenario.name || "")) != null) { scenarioVariables[match[1]] = (_a = child.scenario.location) === null || _a === void 0 ? void 0 : _a.line; } (_b = child.scenario.steps) === null || _b === void 0 ? void 0 : _b.forEach(step => { var _a, _b, _c; // Steps can take arguments and their argument can include variables. // The arguments can be of type: // - DocString // - DataTable // For more details, see https://docs.cucumber.io/gherkin/reference/#step-arguments // Collect variables from step arguments if (step.dataTable) { (_a = step.dataTable.rows) === null || _a === void 0 ? void 0 : _a.forEach(row => { var _a; (_a = row.cells) === null || _a === void 0 ? void 0 : _a.forEach(cell => { var _a; if (cell.value) { while ((match = stepVariableRegex.exec(cell.value)) != null) { scenarioVariables[match[1]] = (_a = cell.location) === null || _a === void 0 ? void 0 : _a.line; } } }); }); } else if (step.docString) { while ((match = stepVariableRegex.exec(step.docString.content || "")) != null) { scenarioVariables[match[1]] = (_b = step.location) === null || _b === void 0 ? void 0 : _b.line; } } // Collect variables from the steps themselves while ((match = stepVariableRegex.exec(step.text || "")) != null) { scenarioVariables[match[1]] = (_c = step.location) === null || _c === void 0 ? void 0 : _c.line; } }); for (const exampleVariable in examplesVariables) { if (!scenarioVariables[exampleVariable]) { errors.push({ message: `Examples table variable "${chalk_1.default.yellow(exampleVariable)}" is not used in any step`, rule: exports.name, line: examplesVariables[exampleVariable], }); } } for (const scenarioVariable in scenarioVariables) { if (!examplesVariables[scenarioVariable]) { errors.push({ message: `Step variable "${chalk_1.default.yellow(scenarioVariable)}" does not exist in the examples table`, rule: exports.name, line: scenarioVariables[scenarioVariable], }); } } }); return errors; } exports.run = run; //# sourceMappingURL=no-unused-variables.js.map