jest-bdd-generator
Version:
Jest code generator empowered with Gherkin and BDD
318 lines (317 loc) • 11.2 kB
JavaScript
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
import React, { useState, useRef, useEffect } from "react";
import styled from "styled-components";
import { Editor } from "@monaco-editor/react";
import { TestGeneratorFromSource } from "../gherkin-to-test/TestGeneratorFromSource";
import { JestToGherkin } from "../jest-to-gherkin/JestToGherkin";
const LineWrapper = styled("div")`
display: flex;
> * {
flex: 1 1 0;
}
`;
const ColumnWrapper = styled("div")`
display: flex;
flex-direction: column;
position: relative;
`;
const CodeWrapper = styled("aside")`
position: absolute;
width: 100%;
height: 100vh;
border: solid 1px rgb(192, 230, 255);
`;
const Feature = styled("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__ */ _jsxs("table", {
children: [
/* @__PURE__ */ _jsx("thead", {
children: /* @__PURE__ */ _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__ */ _jsx("th", {
children: cell.value
}, idxCell);
})
})
}),
/* @__PURE__ */ _jsx("tbody", {
children: scenario.examples[0].tableBody.map((row, idxRow) => {
return /* @__PURE__ */ _jsx("tr", {
children: row.cells.map((cell, idxCell) => {
return /* @__PURE__ */ _jsx("td", {
children: cell.value
}, idxCell);
})
}, idxRow);
})
})
]
});
}
return /* @__PURE__ */ _jsx(_Fragment, {});
};
const ScenarioBlock = ({ featureChild, onSelectStep, className }) => {
const [selectedStep, setSelectedStep] = React.useState();
if (!featureChild) {
return /* @__PURE__ */ _jsx(_Fragment, {});
}
if (featureChild.rule) {
return /* @__PURE__ */ _jsx("div", {
children: featureChild.rule.children.map((ruleChild, idxRuleChild) => /* @__PURE__ */ _jsx("div", {
children: /* @__PURE__ */ _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__ */ _jsxs("section", {
className,
children: [
/* @__PURE__ */ _jsxs("h3", {
children: [
/* @__PURE__ */ _jsx("b", {
children: scenario === null || scenario === void 0 ? void 0 : scenario.keyword
}),
" ",
scenario === null || scenario === void 0 ? void 0 : scenario.name
]
}),
/* @__PURE__ */ _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__ */ _jsxs("p", {
className: selectedStep === s ? "active" : "",
onClick: (evt) => {
stepClick(i, evt);
},
children: [
/* @__PURE__ */ _jsx("b", {
children: s.keyword
}),
" ",
s.text
]
}, i)),
/* @__PURE__ */ _jsx(ExampleBlock, {
scenario: featureChild.scenario
})
]
});
}
};
const TestStory = ({ testsSource = "", featureSource = "" }) => {
var _gherkinSource_feature, _gherkinSource_feature1, _gherkinSource_feature2, _gherkinSource_feature3;
const [editor, setEditor] = useState();
const [gherkinSource, setGherkinSource] = useState();
const [selectedScenario, setSelectedScenario] = useState();
const [jestSource, setJestSource] = useState();
const [scrollTop, setScrollTop] = useState(5);
const fileGherkinSource = useRef(null);
const fileJestSource = useRef(null);
const readGherkin = (gherkinSource2) => {
const generator = new 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 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("");
}
}
}
};
useEffect(() => {
if (featureSource) {
readGherkin(featureSource);
}
if (testsSource) {
readJest(testsSource);
}
}, [
testsSource,
featureSource
]);
return /* @__PURE__ */ _jsxs(LineWrapper, {
children: [
/* @__PURE__ */ _jsxs(ColumnWrapper, {
children: [
/* @__PURE__ */ _jsx("label", {
children: "load Gherkin file:"
}),
/* @__PURE__ */ _jsx("input", {
ref: fileGherkinSource,
onChange: handleGherkinFile,
type: "file"
}),
/* @__PURE__ */ _jsxs(Feature, {
children: [
/* @__PURE__ */ _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__ */ _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__ */ _jsx(ScenarioBlock, {
onSelectStep: selectStep,
className: selectedScenario === featureChild.scenario ? "active" : "",
featureChild
}, idxFeatureChild))
]
})
]
}),
/* @__PURE__ */ _jsx(ColumnWrapper, {
className: "active",
children: /* @__PURE__ */ _jsxs(CodeWrapper, {
style: {
top: scrollTop - 5
},
className: "active",
children: [
/* @__PURE__ */ _jsx("label", {
children: "load Jest file:"
}),
/* @__PURE__ */ _jsx("input", {
ref: fileJestSource,
onChange: handleJestFile,
type: "file"
}),
/* @__PURE__ */ _jsx(Editor, {
height: "40vh",
language: "typescript",
onMount: (editor2) => setEditor(editor2)
})
]
})
})
]
});
};
export {
TestStory
};
//# sourceMappingURL=TestStory.js.map