jest-bdd-generator
Version:
Jest code generator empowered with Gherkin and BDD
352 lines (351 loc) • 13.9 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 TestStory_exports = {};
__export(TestStory_exports, {
TestStory: () => TestStory
});
module.exports = __toCommonJS(TestStory_exports);
var import_jsx_runtime = require("react/jsx-runtime");
var import_react = __toESM(require("react"));
var import_styled_components = __toESM(require("styled-components"));
var import_react2 = require("@monaco-editor/react");
var import_TestGeneratorFromSource = require("../gherkin-to-test/TestGeneratorFromSource");
var import_JestToGherkin = require("../jest-to-gherkin/JestToGherkin");
const LineWrapper = (0, import_styled_components.default)("div")`
display: flex;
> * {
flex: 1 1 0;
}
`;
const ColumnWrapper = (0, import_styled_components.default)("div")`
display: flex;
flex-direction: column;
position: relative;
`;
const CodeWrapper = (0, import_styled_components.default)("aside")`
position: absolute;
width: 100%;
height: 100vh;
border: solid 1px rgb(192, 230, 255);
`;
const Feature = (0, import_styled_components.default)("a")`
.feature {
}
.feature h1,
h2,
h3,
b,
th {
font-weight: 700;
color: #06a;
}
.feature h1 {
font-size: 20px;
}
.feature h2 {
font-size: 18px;
}
.feature h3 {
font-size: 16px;
}
.feature section {
margin: 0 0 1em 1em;
}
.feature p {
font-size: 14px;
text-indent: 1em;
}
.feature table {
font-size: 12px;
text-align: center;
min-width: 50%;
}
.feature table td {
text-align: center;
}
.feature .active .active {
/* box-shadow: inset 0px -1px 0px 0px #fa0 */
background-color: rgb(192, 230, 255);
}
`;
const mapKeyword = (scenario, idxStep) => {
const keyGherkin = scenario === null || scenario === void 0 ? void 0 : scenario.steps[idxStep].keywordType;
switch (keyGherkin) {
case "Context":
return "Given";
case "Action":
return "When";
case "Outcome":
return "Then";
case "Conjunction":
return mapKeyword(scenario, idxStep - 1);
default:
return "";
}
};
const ExampleBlock = ({ scenario }) => {
var _scenario_examples;
if (scenario === null || scenario === void 0 ? void 0 : (_scenario_examples = scenario.examples) === null || _scenario_examples === void 0 ? void 0 : _scenario_examples[0]) {
var _scenario_examples__tableHeader;
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("table", {
children: [
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("thead", {
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("tr", {
children: (_scenario_examples__tableHeader = scenario.examples[0].tableHeader) === null || _scenario_examples__tableHeader === void 0 ? void 0 : _scenario_examples__tableHeader.cells.map((cell, idxCell) => {
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", {
children: cell.value
}, idxCell);
})
})
}),
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("tbody", {
children: scenario.examples[0].tableBody.map((row, idxRow) => {
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("tr", {
children: row.cells.map((cell, idxCell) => {
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", {
children: cell.value
}, idxCell);
})
}, idxRow);
})
})
]
});
}
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, {});
};
const ScenarioBlock = ({ featureChild, onSelectStep, className }) => {
const [selectedStep, setSelectedStep] = import_react.default.useState();
if (!featureChild) {
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, {});
}
if (featureChild.rule) {
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
children: featureChild.rule.children.map((ruleChild, idxRuleChild) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ScenarioBlock, {
featureChild: ruleChild
})
}, idxRuleChild))
});
} else {
var _featureChild_scenario;
const scenario = (_featureChild_scenario = featureChild.scenario) !== null && _featureChild_scenario !== void 0 ? _featureChild_scenario : featureChild.background;
const stepClick = (idxStep, evt) => {
setSelectedStep(scenario === null || scenario === void 0 ? void 0 : scenario.steps[idxStep]);
if (onSelectStep && scenario) {
onSelectStep(scenario, idxStep, evt);
}
};
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", {
className,
children: [
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("h3", {
children: [
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("b", {
children: scenario === null || scenario === void 0 ? void 0 : scenario.keyword
}),
" ",
scenario === null || scenario === void 0 ? void 0 : scenario.name
]
}),
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
children: scenario === null || scenario === void 0 ? void 0 : scenario.description
}),
scenario === null || scenario === void 0 ? void 0 : scenario.steps.map((s, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", {
className: selectedStep === s ? "active" : "",
onClick: (evt) => {
stepClick(i, evt);
},
children: [
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("b", {
children: s.keyword
}),
" ",
s.text
]
}, i)),
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ExampleBlock, {
scenario: featureChild.scenario
})
]
});
}
};
const TestStory = ({ testsSource = "", featureSource = "" }) => {
var _gherkinSource_feature, _gherkinSource_feature1, _gherkinSource_feature2, _gherkinSource_feature3;
const [editor, setEditor] = (0, import_react.useState)();
const [gherkinSource, setGherkinSource] = (0, import_react.useState)();
const [selectedScenario, setSelectedScenario] = (0, import_react.useState)();
const [jestSource, setJestSource] = (0, import_react.useState)();
const [scrollTop, setScrollTop] = (0, import_react.useState)(5);
const fileGherkinSource = (0, import_react.useRef)(null);
const fileJestSource = (0, import_react.useRef)(null);
const readGherkin = (gherkinSource2) => {
const generator = new import_TestGeneratorFromSource.TestGeneratorFromSource();
const ret = generator.compileGherkinFromSource(gherkinSource2);
setGherkinSource(ret);
};
const handleGherkinFile = (evt) => {
if (!evt.target.files) {
return;
}
const file = evt.target.files[0];
void file.text().then((val) => {
readGherkin(val);
});
};
const readJest = (jestSource2) => {
const transpiler = new import_JestToGherkin.JestToGherkin();
transpiler.transpile(jestSource2, {
fileName: "a.test.ts"
});
setJestSource(transpiler.output);
};
const handleJestFile = (evt) => {
if (!evt.target.files) {
return;
}
const file = evt.target.files[0];
void file.text().then((val) => {
readJest(val);
});
};
const selectStep = (scenario, idxStep, evt) => {
setSelectedScenario(scenario);
if (evt === null || evt === void 0 ? void 0 : evt.target) {
const target = evt.target;
setScrollTop(target.offsetTop);
}
if (jestSource) {
const signature = {
key: mapKeyword(scenario, idxStep),
value: scenario.steps[idxStep].text,
parent: scenario.name
};
const searchResults = jestSource.filter((s) => s.value === signature.value && s.key === signature.key);
if (searchResults) {
const searchResult = searchResults.find((s) => s.parent === signature.parent);
if (searchResult === null || searchResult === void 0 ? void 0 : searchResult.sourceCode) {
var _searchResult_sourceCode_imports, _searchResult_sourceCode_exports, _searchResult_sourceCode_statements;
const head = `/**
imports [${(_searchResult_sourceCode_imports = searchResult.sourceCode.imports) === null || _searchResult_sourceCode_imports === void 0 ? void 0 : _searchResult_sourceCode_imports.join(", ")}]
exports [${(_searchResult_sourceCode_exports = searchResult.sourceCode.exports) === null || _searchResult_sourceCode_exports === void 0 ? void 0 : _searchResult_sourceCode_exports.join(", ")}]
*/`;
const tail = `/**
Appearances in other Scenarios: [${searchResults.map((s) => s.parent).join(", ")}]
*/`;
const body = (_searchResult_sourceCode_statements = searchResult.sourceCode.statements) === null || _searchResult_sourceCode_statements === void 0 ? void 0 : _searchResult_sourceCode_statements.map(
(statement) => statement.getFullText()
//.replace(/\n\s+/g, '\n')
).join("");
editor === null || editor === void 0 ? void 0 : editor.setValue(`${head}
${body}
${tail}`);
} else {
editor === null || editor === void 0 ? void 0 : editor.setValue("");
}
}
}
};
(0, import_react.useEffect)(() => {
if (featureSource) {
readGherkin(featureSource);
}
if (testsSource) {
readJest(testsSource);
}
}, [
testsSource,
featureSource
]);
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(LineWrapper, {
children: [
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(ColumnWrapper, {
children: [
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("label", {
children: "load Gherkin file:"
}),
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", {
ref: fileGherkinSource,
onChange: handleGherkinFile,
type: "file"
}),
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Feature, {
children: [
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("h1", {
children: [
gherkinSource === null || gherkinSource === void 0 ? void 0 : (_gherkinSource_feature = gherkinSource.feature) === null || _gherkinSource_feature === void 0 ? void 0 : _gherkinSource_feature.keyword,
" ",
gherkinSource === null || gherkinSource === void 0 ? void 0 : (_gherkinSource_feature1 = gherkinSource.feature) === null || _gherkinSource_feature1 === void 0 ? void 0 : _gherkinSource_feature1.name
]
}),
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("section", {
children: gherkinSource === null || gherkinSource === void 0 ? void 0 : (_gherkinSource_feature2 = gherkinSource.feature) === null || _gherkinSource_feature2 === void 0 ? void 0 : _gherkinSource_feature2.description
}),
gherkinSource === null || gherkinSource === void 0 ? void 0 : (_gherkinSource_feature3 = gherkinSource.feature) === null || _gherkinSource_feature3 === void 0 ? void 0 : _gherkinSource_feature3.children.map((featureChild, idxFeatureChild) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ScenarioBlock, {
onSelectStep: selectStep,
className: selectedScenario === featureChild.scenario ? "active" : "",
featureChild
}, idxFeatureChild))
]
})
]
}),
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ColumnWrapper, {
className: "active",
children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(CodeWrapper, {
style: {
top: scrollTop - 5
},
className: "active",
children: [
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("label", {
children: "load Jest file:"
}),
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", {
ref: fileJestSource,
onChange: handleJestFile,
type: "file"
}),
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react2.Editor, {
height: "40vh",
language: "typescript",
onMount: (editor2) => setEditor(editor2)
})
]
})
})
]
});
};
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
TestStory
});
//# sourceMappingURL=TestStory.js.map