UNPKG

react-ats-scripts

Version:

Configuration and scripts for Create React App with Storybook, TypeScript, Babel and Sass.

178 lines (160 loc) 6.32 kB
'use strict'; const IGNORE_TAG = "@ignore"; const IGNORE_OTHER_TAG = "@ignoreOthers"; const Gherkin = require('gherkin'); const parser = new Gherkin.Parser(new Gherkin.AstBuilder()); const fs = require('fs'); const path = require('path'); class GherkinFilePreprocessor { process(content, file) { let feature = parser.parse(new Gherkin.TokenScanner(content), new Gherkin.TokenMatcher()).feature; let featureSpec = `import * as gherkinApi from 'gherkin-specs-api'; gherkinApi.feature('${this.getFeatureTitle(feature)}')`; if(this.hasTag(feature.tags, IGNORE_OTHER_TAG)){ featureSpec += "\n\t.ignoreOthers()"; } if (this.hasTag(feature.tags, IGNORE_TAG)) { featureSpec += "\n\t.ignore()"; } feature.children.forEach((scenario) => { let scenarioTemplate = this.getScenarioTemplate(scenario, feature.background); featureSpec += this.formatScenarioTemplateWithSamples(scenario, scenarioTemplate); }); let impl = this.getFeatureFileImpl(feature, file); if (impl !== null) { return ` import '${impl.slice(0, -3)}'; ${featureSpec}; gherkinApi.featureRunner().run(); `; } return `xit("", () => {})`; } formatScenarioTemplateWithSamples(scenario, scenarioTemplate) { if (scenario.examples) { let scenarii = ''; scenario.examples[0].tableBody.forEach((exemple) => { let exempleTemplate = scenarioTemplate; for (let i = 0; i < exemple.cells.length; i++) { let paramName = scenario.examples[0].tableHeader.cells[i].value; let value = exemple.cells[i].value; let re = new RegExp("<" + paramName.replace("'","\\\\'") + ">", "g"); exempleTemplate = exempleTemplate.replace(re, value); } scenarii += exempleTemplate; }); return scenarii; } else { return scenarioTemplate; } } getScenarioTemplate(scenario, background) { let scenarioTemplate = "\n\t.scenario('" + this.sanitizeString(scenario.name) + "')"; if(this.hasTag(scenario.tags, IGNORE_OTHER_TAG)){ scenarioTemplate += "\n\t.ignoreOthers()"; } if (this.hasTag(scenario.tags, IGNORE_TAG)) { scenarioTemplate += "\n\t.ignore()"; } let previousKeyword = null; let steps = scenario.steps; if (background && background.steps){ steps = background.steps.concat(scenario.steps); } steps.forEach((step) => { let keyword = step.keyword.toLowerCase().trim(); switch (keyword) { case "given": case "when": case "then": if (previousKeyword === keyword) { keyword = "and"; } else { previousKeyword = keyword; } break; default: // And / But / ... keyword = "and"; } scenarioTemplate += "\n\t\t." + keyword + "('" + this.sanitizeString(step.text) + "'"; var tableArgObj = this.createTableArgumentsObj(step); if (tableArgObj !== null) { scenarioTemplate += "," + JSON.stringify(tableArgObj); } scenarioTemplate += ")"; }); return scenarioTemplate; } createTableArgumentsObj(step) { if (step.argument) { if (step.argument.type === "DocString") { return step.argument.content; } else if (step.argument.rows.length > 0) { var tableArg = []; var properties = []; step.argument.rows[0].cells.forEach((cell) => { properties.push(cell.value); }) for (var j = 1; j < step.argument.rows.length; j++) { var row = step.argument.rows[j]; var argument = {}; for (var k = 0; k < row.cells.length; k++) { argument[properties[k]] = row.cells[k].value; } tableArg.push(argument); } return tableArg; } } return null; } getFeatureTitle(feature) { var featureTitle = feature.name; if (feature.description) { featureTitle += "\r" + feature.description; } return this.sanitizeString(featureTitle); } sanitizeString(str) { return str.replace(/'/g, '\\\'').replace(/[\ \t]*[\n\r]+[\ \t]*/g, "\\n\\r' + \n\r\t'"); } hasTag(tags, tagNames) { return tags.some((tag) => { return tagNames.indexOf(tag.name) >= 0 }); } getFeatureImpl(feature, filename) { let source = feature.tags.filter((tag) => { return tag.name.startsWith('@source '); }).map(x => x.name); if (source.length > 0 && source[0].split(' ').length > 1){ let fileImpl = source[0].split(' ')[1]; var paths = filename.split(path.sep); paths.pop(); var fullImplPath = paths.join(path.sep) + path.sep + fileImpl; let testContent = fs.readFileSync(fullImplPath, 'utf-8'); return { filename: fullImplPath, src: testContent, fileImpl: fileImpl }; } return null; } getFeatureFileImpl(feature, filename) { let source = feature.tags.filter((tag) => { return tag.name.startsWith('@source '); }).map(x => x.name); if (source.length > 0 && source[0].split(' ').length > 1){ let fileImpl = source[0].split(' ')[1]; return fileImpl; } return this.getLocalUrl(filename); } getLocalUrl(filename) { const dirs = filename.split(path.sep); const file = dirs[dirs.length-1]; return `./${file}.impl.ts`; } } module.exports = GherkinFilePreprocessor;