jest-bdd-generator
Version:
Jest code generator empowered with Gherkin and BDD
340 lines (339 loc) • 12.8 kB
JavaScript
;
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var delegate_jest_exports = {};
__export(delegate_jest_exports, {
DelegateJest: () => DelegateJest,
default: () => delegate_jest_default
});
module.exports = __toCommonJS(delegate_jest_exports);
var cucumber = __toESM(require("@cucumber/cucumber"));
var import_jest = require("jest");
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
try {
var info = gen[key](arg);
var value = info.value;
} catch (error) {
reject(error);
return;
}
if (info.done) {
resolve(value);
} else {
Promise.resolve(value).then(_next, _throw);
}
}
function _async_to_generator(fn) {
return function() {
var self = this, args = arguments;
return new Promise(function(resolve, reject) {
var gen = fn.apply(self, args);
function _next(value) {
asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
}
function _throw(err) {
asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
}
_next(void 0);
});
};
}
function _define_property(obj, key, value) {
if (key in obj) {
Object.defineProperty(obj, key, {
value,
enumerable: true,
configurable: true,
writable: true
});
} else {
obj[key] = value;
}
return obj;
}
function escapableWrapper(wrapper) {
const start = wrapper.charAt(0);
var _wrapper_charAt;
const end = (_wrapper_charAt = wrapper.charAt(1)) !== null && _wrapper_charAt !== void 0 ? _wrapper_charAt : start;
return `${start}(?:[^${end}]|\\\\${end})+[^\\\\]${end}`;
}
class DelegateJest {
jesting(projects, target) {
const options = {
_: projects
};
if (target) {
options.testNamePattern = target;
}
return (0, import_jest.runCLI)(options, [
process.cwd()
]);
}
main(gherkinMap = []) {
var _this = this;
return _async_to_generator(function* () {
const { results } = yield _this.jesting([
_this.filename
]);
return _this.transformResult(results, gherkinMap);
})();
}
transformResult(aggregatedResult, gherkinMap = []) {
if (!aggregatedResult) {
return [];
}
const resultInGherkin = [];
aggregatedResult.testResults.forEach((result) => result.testResults.forEach((assertionResult) => {
resultInGherkin.push(assertionResult);
}));
return resultInGherkin;
}
markStepsStatus(relatedSteps, status) {
relatedSteps.forEach((step) => {
step.status = status;
});
}
traceErrorFromMessage(msg, step) {
const lines = msg.split("\n");
for (let i = 0; i < lines.length; i++) {
const line = lines[i];
const stackPosition = line.match(/\s+at .*?(\S+):(\d+:\d+)\)*?$/);
if (!stackPosition) {
continue;
} else {
var _stackPosition__split, _stackPosition_;
const fileName = stackPosition[1];
if (!fileName.match(this.filename)) {
continue;
}
var _ref;
const [lineNumber, colNumber] = (_ref = (_stackPosition_ = stackPosition[2]) === null || _stackPosition_ === void 0 ? void 0 : (_stackPosition__split = _stackPosition_.split(":")) === null || _stackPosition__split === void 0 ? void 0 : _stackPosition__split.map((v) => Number(v) - 1)) !== null && _ref !== void 0 ? _ref : [
0,
0
];
if (step.pos.end.line < lineNumber || step.pos.end.line === lineNumber && step.pos.end.character < colNumber) {
return "passed";
} else if (step.pos.start.line < lineNumber || step.pos.start.line === lineNumber && step.pos.start.character <= colNumber) {
return "failed";
} else {
return "passed";
}
}
}
}
sanitizeTitle(title, params) {
const stepParams = title.match(new RegExp(escapableWrapper("<>"), "g"));
let cucumberStepKey = title.replace(/\(/g, "\\(").replace(")", "\\)");
stepParams === null || stepParams === void 0 ? void 0 : stepParams.forEach((p, i) => {
var _params_;
const valKey = p.replace(/<|>/g, "");
stepParams[i] = valKey;
const examplesValue = params === null || params === void 0 ? void 0 : (_params_ = params[0]) === null || _params_ === void 0 ? void 0 : _params_[valKey];
if (examplesValue !== void 0) {
const typeOfValue = typeof examplesValue === "number" ? "{float}" : "{string}";
cucumberStepKey = cucumberStepKey.replace(p, typeOfValue);
}
});
return {
cucumberStepKey,
stepParams
};
}
matchStepName(jestStep, pickleSteps, callback) {
const regexText = jestStep.sanitizedTitle.replace(/\{string\}/g, `(${escapableWrapper('"')}|${escapableWrapper("'")})`).replace(/\{float\}/g, `((-)?d+(.d+)?)`);
const regex = new RegExp(`^${regexText}$`);
for (let i = 0; i < pickleSteps.length; i++) {
const pickleStep = pickleSteps[i];
const matchExp = pickleStep.text.match(regex);
if (matchExp) {
const [_fullText, ...values] = matchExp;
if (callback(values, i)) {
return;
}
}
}
}
dedupeStepName(dedupe) {
const paramSteps = [
...dedupe.filter((v) => v.step.stepParams)
];
paramSteps.forEach(({ step }) => {
this.matchStepName(step, dedupe, (values, idx) => {
var _step_stepParams;
dedupe[idx].step.sanitizedTitle = step.sanitizedTitle;
var _dedupe_idx_step_stepParams;
dedupe[idx].step.stepParams = (_dedupe_idx_step_stepParams = dedupe[idx].step.stepParams) !== null && _dedupe_idx_step_stepParams !== void 0 ? _dedupe_idx_step_stepParams : new Array((_step_stepParams = step.stepParams) === null || _step_stepParams === void 0 ? void 0 : _step_stepParams.length);
});
});
return dedupe.filter((v, i) => i === dedupe.findIndex((predicate) => predicate.step.sanitizedTitle === v.step.sanitizedTitle));
}
delegateTo(steps) {
const cachedResult = this.main(steps);
const matchStepName = this.matchStepName;
cucumber.Before(function() {
var _ref = _async_to_generator(function* (scenario) {
var _jestScenario_examples;
const jestScenario = steps.find((step) => step.key === "Scenario" && step.value === scenario.pickle.name);
const examplesScenario = {};
const pickleSteps = [
...scenario.pickle.steps
];
const relatedSteps = steps.filter((s) => s.parent === scenario.pickle.name);
relatedSteps.forEach((jestStep) => {
if (!jestStep.stepParams) {
return;
}
const jStep = jestStep;
matchStepName(jStep, pickleSteps, (values, idx) => {
const keys = jStep.stepParams;
values.forEach((v, i) => {
if (keys[i]) {
examplesScenario[keys[i]] = JSON.parse(v);
}
});
pickleSteps.splice(idx, 1);
return true;
});
});
const exampleIndex = jestScenario === null || jestScenario === void 0 ? void 0 : (_jestScenario_examples = jestScenario.examples) === null || _jestScenario_examples === void 0 ? void 0 : _jestScenario_examples.findIndex((v) => {
for (const k in examplesScenario) {
if (v[k] !== examplesScenario[k]) {
return false;
}
}
return true;
});
const result = yield cachedResult;
const arrJestMappedResult = result.filter((r) => {
return r.title === scenario.pickle.name;
});
const jestMappedResult = arrJestMappedResult[exampleIndex !== null && exampleIndex !== void 0 ? exampleIndex : 0];
this.jest = this.jest || {
stepIndex: {},
exampleIndex,
parent: scenario.pickle.name,
jestMappedResult
};
});
return function(scenario) {
return _ref.apply(this, arguments);
};
}());
const dedupe = [];
const scenarios = steps.filter((step) => step.key === "Scenario");
steps.forEach((step) => {
const keyword = step.key;
const title = step.value;
if (cucumber[keyword]) {
const parent = scenarios.find((s) => s.key === "Scenario" && s.value === step.parent);
const { cucumberStepKey, stepParams } = this.sanitizeTitle(title, parent === null || parent === void 0 ? void 0 : parent.examples);
step.sanitizedTitle = cucumberStepKey;
step.stepParams = stepParams;
dedupe.push({
text: cucumberStepKey,
step
});
}
});
this.dedupeStepName(dedupe).forEach(({ step }) => {
this.registerStepDefinition(step, steps);
});
}
registerStepDefinition(step, allSteps) {
const traceErrorFromMessage = this.traceErrorFromMessage.bind(this);
const keyword = step.key;
const fnStepDefinition = cucumber[keyword];
const cucumberStepKey = step.sanitizedTitle;
const callback = function() {
var _ref = _async_to_generator(function* (...args) {
var _this_jest_stepIndex_cucumberStepKey;
this.jest.stepIndex[cucumberStepKey] = ((_this_jest_stepIndex_cucumberStepKey = this.jest.stepIndex[cucumberStepKey]) !== null && _this_jest_stepIndex_cucumberStepKey !== void 0 ? _this_jest_stepIndex_cucumberStepKey : -1) + 1;
const stepInScenario = allSteps.filter((s) => {
var _this_jest;
return s.parent === ((_this_jest = this.jest) === null || _this_jest === void 0 ? void 0 : _this_jest.parent) && s.sanitizedTitle === cucumberStepKey;
})[this.jest.stepIndex[cucumberStepKey]];
if (!stepInScenario) {
return "pending";
}
const { jestMappedResult } = this.jest;
if (!jestMappedResult) {
return "pending";
} else if (jestMappedResult.status === "failed") {
if (stepInScenario.host) {
for (let idxMsg = 0; idxMsg < jestMappedResult.failureMessages.length; idxMsg++) {
const status = traceErrorFromMessage(jestMappedResult.failureMessages[idxMsg], stepInScenario);
if (status === "failed") {
throw errorBuilder(jestMappedResult.failureMessages[idxMsg]);
}
if (status) {
return status;
}
}
return "pending";
} else {
throw errorBuilder(jestMappedResult.failureMessages[0]);
}
} else {
return jestMappedResult.status;
}
});
return function callback2() {
return _ref.apply(this, arguments);
};
}();
if (step.stepParams) {
Object.defineProperty(callback, "length", {
value: step.stepParams.length
});
}
fnStepDefinition(cucumberStepKey, callback);
}
constructor(filename) {
_define_property(this, "filename", void 0);
_define_property(this, "jestMappedResult", []);
this.filename = filename;
}
}
function errorBuilder(msg) {
const matched = msg.match(/Error: ([^\n]+)\n(.+)/);
const err = new Error();
if (!matched) {
err.message = msg;
} else {
err.message = matched[1];
err.stack = matched[2];
}
err.message = err.message.replace(/\[\d+m/g, "");
return err;
}
var delegate_jest_default = DelegateJest;
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
DelegateJest
});
//# sourceMappingURL=delegate-jest.js.map