This commit is contained in:
Simon Priet
2021-09-05 22:53:58 +02:00
commit 9e2991e668
17888 changed files with 1263126 additions and 0 deletions

View File

@@ -0,0 +1,110 @@
"use strict";
const util = require('util');
const ParameterTypeMatcher = require('./parameter_type_matcher');
const ParameterType = require('./parameter_type');
const CombinatorialGeneratedExpressionFactory = require('./combinatorial_generated_expression_factory');
class CucumberExpressionGenerator {
constructor(parameterTypeRegistry) {
this._parameterTypeRegistry = parameterTypeRegistry;
}
generateExpressions(text) {
const parameterTypeCombinations = [];
const parameterTypeMatchers = this._createParameterTypeMatchers(text);
let expressionTemplate = '';
let pos = 0; // eslint-disable-next-line no-constant-condition
while (true) {
let matchingParameterTypeMatchers = [];
for (const parameterTypeMatcher of parameterTypeMatchers) {
const advancedParameterTypeMatcher = parameterTypeMatcher.advanceTo(pos);
if (advancedParameterTypeMatcher.find) {
matchingParameterTypeMatchers.push(advancedParameterTypeMatcher);
}
}
if (matchingParameterTypeMatchers.length > 0) {
matchingParameterTypeMatchers = matchingParameterTypeMatchers.sort(ParameterTypeMatcher.compare); // Find all the best parameter type matchers, they are all candidates.
const bestParameterTypeMatcher = matchingParameterTypeMatchers[0];
const bestParameterTypeMatchers = matchingParameterTypeMatchers.filter(m => ParameterTypeMatcher.compare(m, bestParameterTypeMatcher) === 0); // Build a list of parameter types without duplicates. The reason there
// might be duplicates is that some parameter types have more than one regexp,
// which means multiple ParameterTypeMatcher objects will have a reference to the
// same ParameterType.
// We're sorting the list so preferential parameter types are listed first.
// Users are most likely to want these, so they should be listed at the top.
let parameterTypes = [];
for (const parameterTypeMatcher of bestParameterTypeMatchers) {
if (parameterTypes.indexOf(parameterTypeMatcher.parameterType) === -1) {
parameterTypes.push(parameterTypeMatcher.parameterType);
}
}
parameterTypes = parameterTypes.sort(ParameterType.compare);
parameterTypeCombinations.push(parameterTypes);
expressionTemplate += escape(text.slice(pos, bestParameterTypeMatcher.start));
expressionTemplate += '{%s}';
pos = bestParameterTypeMatcher.start + bestParameterTypeMatcher.group.length;
} else {
break;
}
if (pos >= text.length) {
break;
}
}
expressionTemplate += escape(text.slice(pos));
return new CombinatorialGeneratedExpressionFactory(expressionTemplate, parameterTypeCombinations).generateExpressions();
}
/**
* @deprecated
*/
generateExpression(text) {
return util.deprecate(() => this.generateExpressions(text)[0], 'CucumberExpressionGenerator.generateExpression: Use CucumberExpressionGenerator.generateExpressions instead')();
}
_createParameterTypeMatchers(text) {
let parameterMatchers = [];
for (const parameterType of this._parameterTypeRegistry.parameterTypes) {
if (parameterType.useForSnippets) {
parameterMatchers = parameterMatchers.concat(this._createParameterTypeMatchers2(parameterType, text));
}
}
return parameterMatchers;
}
_createParameterTypeMatchers2(parameterType, text) {
// TODO: [].map
const result = [];
for (const regexp of parameterType.regexps) {
result.push(new ParameterTypeMatcher(parameterType, regexp, text));
}
return result;
}
}
function escape(s) {
return s.replace(/%/g, '%%') // for util.format
.replace(/\(/g, '\\(').replace(/{/g, '\\{').replace(/\//g, '\\/');
}
module.exports = CucumberExpressionGenerator;