refactor: init cypress-cucumber-preprocessor install.
This commit is contained in:
42
node_modules/cucumber-expressions/dist/src/argument.js
generated
vendored
Normal file
42
node_modules/cucumber-expressions/dist/src/argument.js
generated
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
"use strict";
|
||||
|
||||
const {
|
||||
CucumberExpressionError
|
||||
} = require('./errors');
|
||||
|
||||
class Argument {
|
||||
static build(treeRegexp, text, parameterTypes) {
|
||||
const group = treeRegexp.match(text);
|
||||
if (!group) return null;
|
||||
const argGroups = group.children;
|
||||
|
||||
if (argGroups.length !== parameterTypes.length) {
|
||||
throw new CucumberExpressionError(`Expression ${treeRegexp.regexp} has ${argGroups.length} capture groups (${argGroups.map(g => g.value)}), but there were ${parameterTypes.length} parameter types (${parameterTypes.map(p => p.name)})`);
|
||||
}
|
||||
|
||||
return parameterTypes.map((parameterType, i) => new Argument(argGroups[i], parameterType));
|
||||
}
|
||||
|
||||
constructor(group, parameterType) {
|
||||
this._group = group;
|
||||
this._parameterType = parameterType;
|
||||
}
|
||||
|
||||
get group() {
|
||||
return this._group;
|
||||
}
|
||||
/**
|
||||
* Get the value returned by the parameter type's transformer function.
|
||||
*
|
||||
* @param thisObj the object in which the transformer function is applied.
|
||||
*/
|
||||
|
||||
|
||||
getValue(thisObj) {
|
||||
let groupValues = this._group ? this._group.values : null;
|
||||
return this._parameterType.transform(thisObj, groupValues);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
module.exports = Argument;
|
48
node_modules/cucumber-expressions/dist/src/combinatorial_generated_expression_factory.js
generated
vendored
Normal file
48
node_modules/cucumber-expressions/dist/src/combinatorial_generated_expression_factory.js
generated
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
"use strict";
|
||||
|
||||
const GeneratedExpression = require('./generated_expression'); // 256 generated expressions ought to be enough for anybody
|
||||
|
||||
|
||||
const MAX_EXPRESSIONS = 256;
|
||||
|
||||
class CombinatorialGeneratedExpressionFactory {
|
||||
constructor(expressionTemplate, parameterTypeCombinations) {
|
||||
this._expressionTemplate = expressionTemplate;
|
||||
this._parameterTypeCombinations = parameterTypeCombinations;
|
||||
}
|
||||
|
||||
generateExpressions() {
|
||||
const generatedExpressions = [];
|
||||
|
||||
this._generatePermutations(generatedExpressions, 0, []);
|
||||
|
||||
return generatedExpressions;
|
||||
}
|
||||
|
||||
_generatePermutations(generatedExpressions, depth, currentParameterTypes) {
|
||||
if (generatedExpressions.length >= MAX_EXPRESSIONS) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (depth === this._parameterTypeCombinations.length) {
|
||||
generatedExpressions.push(new GeneratedExpression(this._expressionTemplate, currentParameterTypes));
|
||||
return;
|
||||
}
|
||||
|
||||
for (let i = 0; i < this._parameterTypeCombinations[depth].length; ++i) {
|
||||
// Avoid recursion if no elements can be added.
|
||||
if (generatedExpressions.length >= MAX_EXPRESSIONS) {
|
||||
return;
|
||||
}
|
||||
|
||||
const newCurrentParameterTypes = currentParameterTypes.slice(); // clone
|
||||
|
||||
newCurrentParameterTypes.push(this._parameterTypeCombinations[depth][i]);
|
||||
|
||||
this._generatePermutations(generatedExpressions, depth + 1, newCurrentParameterTypes);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
module.exports = CombinatorialGeneratedExpressionFactory;
|
125
node_modules/cucumber-expressions/dist/src/cucumber_expression.js
generated
vendored
Normal file
125
node_modules/cucumber-expressions/dist/src/cucumber_expression.js
generated
vendored
Normal file
@@ -0,0 +1,125 @@
|
||||
"use strict";
|
||||
|
||||
const Argument = require('./argument');
|
||||
|
||||
const TreeRegexp = require('./tree_regexp');
|
||||
|
||||
const ParameterType = require('./parameter_type');
|
||||
|
||||
const {
|
||||
UndefinedParameterTypeError,
|
||||
CucumberExpressionError
|
||||
} = require('./errors'); // RegExps with the g flag are stateful in JavaScript. In order to be able
|
||||
// to reuse them we have to wrap them in a function.
|
||||
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/test
|
||||
// Does not include (){} characters because they have special meaning
|
||||
|
||||
|
||||
const ESCAPE_REGEXP = () => /([\\^[$.|?*+])/g;
|
||||
|
||||
const PARAMETER_REGEXP = () => /(\\\\)?{([^}]*)}/g;
|
||||
|
||||
const OPTIONAL_REGEXP = () => /(\\\\)?\(([^)]+)\)/g;
|
||||
|
||||
const ALTERNATIVE_NON_WHITESPACE_TEXT_REGEXP = () => /([^\s^/]+)((\/[^\s^/]+)+)/g;
|
||||
|
||||
const DOUBLE_ESCAPE = '\\\\';
|
||||
const PARAMETER_TYPES_CANNOT_BE_ALTERNATIVE = 'Parameter types cannot be alternative: ';
|
||||
const PARAMETER_TYPES_CANNOT_BE_OPTIONAL = 'Parameter types cannot be optional: ';
|
||||
|
||||
class CucumberExpression {
|
||||
/**
|
||||
* @param expression
|
||||
* @param parameterTypeRegistry
|
||||
*/
|
||||
constructor(expression, parameterTypeRegistry) {
|
||||
this._expression = expression;
|
||||
this._parameterTypes = [];
|
||||
expression = this.processEscapes(expression);
|
||||
expression = this.processOptional(expression);
|
||||
expression = this.processAlternation(expression);
|
||||
expression = this.processParameters(expression, parameterTypeRegistry);
|
||||
expression = `^${expression}$`;
|
||||
this._treeRegexp = new TreeRegexp(expression);
|
||||
}
|
||||
|
||||
processEscapes(expression) {
|
||||
return expression.replace(ESCAPE_REGEXP(), '\\$1');
|
||||
}
|
||||
|
||||
processOptional(expression) {
|
||||
return expression.replace(OPTIONAL_REGEXP(), (match, p1, p2) => {
|
||||
if (p1 === DOUBLE_ESCAPE) {
|
||||
return `\\(${p2}\\)`;
|
||||
}
|
||||
|
||||
this._checkNoParameterType(p2, PARAMETER_TYPES_CANNOT_BE_OPTIONAL);
|
||||
|
||||
return `(?:${p2})?`;
|
||||
});
|
||||
}
|
||||
|
||||
processAlternation(expression) {
|
||||
return expression.replace(ALTERNATIVE_NON_WHITESPACE_TEXT_REGEXP(), match => {
|
||||
// replace \/ with /
|
||||
// replace / with |
|
||||
const replacement = match.replace(/\//g, '|').replace(/\\\|/g, '/');
|
||||
|
||||
if (replacement.indexOf('|') !== -1) {
|
||||
for (const part of replacement.split(/\|/)) {
|
||||
this._checkNoParameterType(part, PARAMETER_TYPES_CANNOT_BE_ALTERNATIVE);
|
||||
}
|
||||
|
||||
return `(?:${replacement})`;
|
||||
} else {
|
||||
return replacement;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
processParameters(expression, parameterTypeRegistry) {
|
||||
return expression.replace(PARAMETER_REGEXP(), (match, p1, p2) => {
|
||||
if (p1 === DOUBLE_ESCAPE) return `\\{${p2}\\}`;
|
||||
const typeName = p2;
|
||||
ParameterType.checkParameterTypeName(typeName);
|
||||
const parameterType = parameterTypeRegistry.lookupByTypeName(typeName);
|
||||
if (!parameterType) throw new UndefinedParameterTypeError(typeName);
|
||||
|
||||
this._parameterTypes.push(parameterType);
|
||||
|
||||
return buildCaptureRegexp(parameterType.regexps);
|
||||
});
|
||||
}
|
||||
|
||||
match(text) {
|
||||
return Argument.build(this._treeRegexp, text, this._parameterTypes);
|
||||
}
|
||||
|
||||
get regexp() {
|
||||
return this._treeRegexp.regexp;
|
||||
}
|
||||
|
||||
get source() {
|
||||
return this._expression;
|
||||
}
|
||||
|
||||
_checkNoParameterType(s, message) {
|
||||
if (s.match(PARAMETER_REGEXP())) {
|
||||
throw new CucumberExpressionError(message + this.source);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function buildCaptureRegexp(regexps) {
|
||||
if (regexps.length === 1) {
|
||||
return `(${regexps[0]})`;
|
||||
}
|
||||
|
||||
const captureGroups = regexps.map(group => {
|
||||
return `(?:${group})`;
|
||||
});
|
||||
return `(${captureGroups.join('|')})`;
|
||||
}
|
||||
|
||||
module.exports = CucumberExpression;
|
110
node_modules/cucumber-expressions/dist/src/cucumber_expression_generator.js
generated
vendored
Normal file
110
node_modules/cucumber-expressions/dist/src/cucumber_expression_generator.js
generated
vendored
Normal 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;
|
45
node_modules/cucumber-expressions/dist/src/errors.js
generated
vendored
Normal file
45
node_modules/cucumber-expressions/dist/src/errors.js
generated
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
"use strict";
|
||||
|
||||
class CucumberExpressionError extends Error {}
|
||||
|
||||
class AmbiguousParameterTypeError extends CucumberExpressionError {
|
||||
static forConstructor(keyName, keyValue, parameterTypes, generatedExpressions) {
|
||||
return new this(`parameter type with ${keyName}=${keyValue} is used by several parameter types: ${parameterTypes}, ${generatedExpressions}`);
|
||||
}
|
||||
|
||||
static forRegExp(parameterTypeRegexp, expressionRegexp, parameterTypes, generatedExpressions) {
|
||||
return new this(`Your Regular Expression ${expressionRegexp}
|
||||
matches multiple parameter types with regexp ${parameterTypeRegexp}:
|
||||
${this._parameterTypeNames(parameterTypes)}
|
||||
|
||||
I couldn't decide which one to use. You have two options:
|
||||
|
||||
1) Use a Cucumber Expression instead of a Regular Expression. Try one of these:
|
||||
${this._expressions(generatedExpressions)}
|
||||
|
||||
2) Make one of the parameter types preferential and continue to use a Regular Expression.
|
||||
`);
|
||||
}
|
||||
|
||||
static _parameterTypeNames(parameterTypes) {
|
||||
return parameterTypes.map(p => `{${p.name}}`).join('\n ');
|
||||
}
|
||||
|
||||
static _expressions(generatedExpressions) {
|
||||
return generatedExpressions.map(e => e.source).join('\n ');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class UndefinedParameterTypeError extends CucumberExpressionError {
|
||||
constructor(typeName) {
|
||||
super(`Undefined parameter type {${typeName}}`);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
AmbiguousParameterTypeError,
|
||||
UndefinedParameterTypeError,
|
||||
CucumberExpressionError
|
||||
};
|
43
node_modules/cucumber-expressions/dist/src/generated_expression.js
generated
vendored
Normal file
43
node_modules/cucumber-expressions/dist/src/generated_expression.js
generated
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
"use strict";
|
||||
|
||||
const util = require('util');
|
||||
|
||||
class GeneratedExpression {
|
||||
constructor(expressionTemplate, parameterTypes) {
|
||||
this._expressionTemplate = expressionTemplate;
|
||||
this._parameterTypes = parameterTypes;
|
||||
}
|
||||
|
||||
get source() {
|
||||
return util.format(this._expressionTemplate, ...this._parameterTypes.map(t => t.name));
|
||||
}
|
||||
/**
|
||||
* Returns an array of parameter names to use in generated function/method signatures
|
||||
*
|
||||
* @returns {Array.<String>}
|
||||
*/
|
||||
|
||||
|
||||
get parameterNames() {
|
||||
const usageByTypeName = {};
|
||||
return this._parameterTypes.map(t => getParameterName(t.name, usageByTypeName));
|
||||
}
|
||||
/**
|
||||
* @returns {Array.<ParameterType>}
|
||||
*/
|
||||
|
||||
|
||||
get parameterTypes() {
|
||||
return this._parameterTypes;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function getParameterName(typeName, usageByTypeName) {
|
||||
let count = usageByTypeName[typeName];
|
||||
count = count ? count + 1 : 1;
|
||||
usageByTypeName[typeName] = count;
|
||||
return count === 1 ? typeName : `${typeName}${count}`;
|
||||
}
|
||||
|
||||
module.exports = GeneratedExpression;
|
33
node_modules/cucumber-expressions/dist/src/group.js
generated
vendored
Normal file
33
node_modules/cucumber-expressions/dist/src/group.js
generated
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
"use strict";
|
||||
|
||||
class Group {
|
||||
constructor(value, start, end, children) {
|
||||
this._value = value;
|
||||
this._start = start;
|
||||
this._end = end;
|
||||
this._children = children;
|
||||
}
|
||||
|
||||
get value() {
|
||||
return this._value;
|
||||
}
|
||||
|
||||
get start() {
|
||||
return this._start;
|
||||
}
|
||||
|
||||
get end() {
|
||||
return this._end;
|
||||
}
|
||||
|
||||
get children() {
|
||||
return this._children;
|
||||
}
|
||||
|
||||
get values() {
|
||||
return (this.children.length === 0 ? [this] : this.children).map(g => g.value).filter(v => v !== undefined);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
module.exports = Group;
|
41
node_modules/cucumber-expressions/dist/src/group_builder.js
generated
vendored
Normal file
41
node_modules/cucumber-expressions/dist/src/group_builder.js
generated
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
"use strict";
|
||||
|
||||
const Group = require('./group');
|
||||
|
||||
class GroupBuilder {
|
||||
constructor() {
|
||||
this._groupBuilders = [];
|
||||
this._capturing = true;
|
||||
}
|
||||
|
||||
add(groupBuilder) {
|
||||
this._groupBuilders.push(groupBuilder);
|
||||
}
|
||||
|
||||
build(match, nextGroupIndex) {
|
||||
const groupIndex = nextGroupIndex();
|
||||
|
||||
const children = this._groupBuilders.map(gb => gb.build(match, nextGroupIndex));
|
||||
|
||||
return new Group(match[groupIndex], match.index[groupIndex], match.index[groupIndex] + (match[groupIndex] || '').length, children);
|
||||
}
|
||||
|
||||
setNonCapturing() {
|
||||
this._capturing = false;
|
||||
}
|
||||
|
||||
get capturing() {
|
||||
return this._capturing;
|
||||
}
|
||||
|
||||
get children() {
|
||||
return this._groupBuilders;
|
||||
}
|
||||
|
||||
moveChildrenTo(groupBuilder) {
|
||||
this._groupBuilders.forEach(child => groupBuilder.add(child));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
module.exports = GroupBuilder;
|
19
node_modules/cucumber-expressions/dist/src/index.js
generated
vendored
Normal file
19
node_modules/cucumber-expressions/dist/src/index.js
generated
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
"use strict";
|
||||
|
||||
const CucumberExpression = require('./cucumber_expression');
|
||||
|
||||
const RegularExpression = require('./regular_expression');
|
||||
|
||||
const CucumberExpressionGenerator = require('./cucumber_expression_generator');
|
||||
|
||||
const ParameterTypeRegistry = require('./parameter_type_registry');
|
||||
|
||||
const ParameterType = require('./parameter_type');
|
||||
|
||||
module.exports = {
|
||||
CucumberExpression,
|
||||
RegularExpression,
|
||||
CucumberExpressionGenerator,
|
||||
ParameterTypeRegistry,
|
||||
ParameterType
|
||||
};
|
106
node_modules/cucumber-expressions/dist/src/parameter_type.js
generated
vendored
Normal file
106
node_modules/cucumber-expressions/dist/src/parameter_type.js
generated
vendored
Normal file
@@ -0,0 +1,106 @@
|
||||
"use strict";
|
||||
|
||||
const {
|
||||
CucumberExpressionError
|
||||
} = require('./errors');
|
||||
|
||||
const ILLEGAL_PARAMETER_NAME_PATTERN = /([[\]()$.|?*+])/;
|
||||
|
||||
const UNESCAPE_PATTERN = () => /(\\([[$.|?*+\]]))/g;
|
||||
|
||||
class ParameterType {
|
||||
static compare(pt1, pt2) {
|
||||
if (pt1.preferForRegexpMatch && !pt2.preferForRegexpMatch) return -1;
|
||||
if (pt2.preferForRegexpMatch && !pt1.preferForRegexpMatch) return 1;
|
||||
return pt1.name.localeCompare(pt2.name);
|
||||
}
|
||||
|
||||
static checkParameterTypeName(typeName) {
|
||||
const unescapedTypeName = typeName.replace(UNESCAPE_PATTERN(), '$2');
|
||||
const match = unescapedTypeName.match(ILLEGAL_PARAMETER_NAME_PATTERN);
|
||||
if (match) throw new CucumberExpressionError(`Illegal character '${match[1]}' in parameter name {${unescapedTypeName}}`);
|
||||
}
|
||||
/**
|
||||
* @param name {String} the name of the type
|
||||
* @param regexps {Array.<RegExp>,RegExp,Array.<String>,String} that matches the type
|
||||
* @param type {Function} the prototype (constructor) of the type. May be null.
|
||||
* @param transform {Function} function transforming string to another type. May be null.
|
||||
* @param useForSnippets {boolean} true if this should be used for snippets. Defaults to true.
|
||||
* @param preferForRegexpMatch {boolean} true if this is a preferential type. Defaults to false.
|
||||
*/
|
||||
|
||||
|
||||
constructor(name, regexps, type, transform, useForSnippets, preferForRegexpMatch) {
|
||||
if (transform === undefined) transform = s => s;
|
||||
if (useForSnippets === undefined) useForSnippets = true;
|
||||
if (preferForRegexpMatch === undefined) preferForRegexpMatch = false;
|
||||
if (name) ParameterType.checkParameterTypeName(name);
|
||||
this._name = name;
|
||||
this._regexps = stringArray(regexps);
|
||||
this._type = type;
|
||||
this._transform = transform;
|
||||
this._useForSnippets = useForSnippets;
|
||||
this._preferForRegexpMatch = preferForRegexpMatch;
|
||||
}
|
||||
|
||||
get name() {
|
||||
return this._name;
|
||||
}
|
||||
|
||||
get regexps() {
|
||||
return this._regexps;
|
||||
}
|
||||
|
||||
get type() {
|
||||
return this._type;
|
||||
}
|
||||
|
||||
get preferForRegexpMatch() {
|
||||
return this._preferForRegexpMatch;
|
||||
}
|
||||
|
||||
get useForSnippets() {
|
||||
return this._useForSnippets;
|
||||
}
|
||||
|
||||
transform(thisObj, groupValues) {
|
||||
return this._transform.apply(thisObj, groupValues);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function stringArray(regexps) {
|
||||
const array = Array.isArray(regexps) ? regexps : [regexps];
|
||||
return array.map(r => typeof r === 'string' ? r : regexpSource(r));
|
||||
}
|
||||
|
||||
function regexpSource(regexp) {
|
||||
const flags = regexpFlags(regexp);
|
||||
|
||||
for (const flag of ['g', 'i', 'm', 'y']) {
|
||||
if (flags.indexOf(flag) !== -1) throw new CucumberExpressionError(`ParameterType Regexps can't use flag '${flag}'`);
|
||||
}
|
||||
|
||||
return regexp.source;
|
||||
} // Backport RegExp.flags for Node 4.x
|
||||
// https://github.com/nodejs/node/issues/8390
|
||||
//
|
||||
// For some strange reason this is not needed for
|
||||
// `./mocha dist/test`, but it is needed for
|
||||
// `./mocha dist/test/parameter_type_test.js`
|
||||
|
||||
|
||||
function regexpFlags(regexp) {
|
||||
let flags = regexp.flags;
|
||||
|
||||
if (flags === undefined) {
|
||||
flags = '';
|
||||
if (regexp.ignoreCase) flags += 'i';
|
||||
if (regexp.global) flags += 'g';
|
||||
if (regexp.multiline) flags += 'm';
|
||||
}
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
module.exports = ParameterType;
|
51
node_modules/cucumber-expressions/dist/src/parameter_type_matcher.js
generated
vendored
Normal file
51
node_modules/cucumber-expressions/dist/src/parameter_type_matcher.js
generated
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
"use strict";
|
||||
|
||||
class ParameterTypeMatcher {
|
||||
constructor(parameter, regexp, text, matchPosition) {
|
||||
this._parameterType = parameter;
|
||||
this._treeRegexp = regexp;
|
||||
this._text = text;
|
||||
this._matchPosition = matchPosition || 0;
|
||||
const captureGroupRegexp = new RegExp(`(${regexp})`);
|
||||
this._match = captureGroupRegexp.exec(text.slice(this._matchPosition));
|
||||
}
|
||||
|
||||
get parameterType() {
|
||||
return this._parameterType;
|
||||
}
|
||||
|
||||
advanceTo(newMatchPosition) {
|
||||
for (let advancedPos = newMatchPosition; advancedPos < this._text.length; advancedPos++) {
|
||||
let matcher = new ParameterTypeMatcher(this._parameterType, this._treeRegexp, this._text, advancedPos);
|
||||
|
||||
if (matcher.find) {
|
||||
return matcher;
|
||||
}
|
||||
}
|
||||
|
||||
return new ParameterTypeMatcher(this._parameterType, this._treeRegexp, this._text, this._text.length);
|
||||
}
|
||||
|
||||
get find() {
|
||||
return this._match && this.group !== '';
|
||||
}
|
||||
|
||||
get start() {
|
||||
return this._matchPosition + this._match.index;
|
||||
}
|
||||
|
||||
get group() {
|
||||
return this._match[0];
|
||||
}
|
||||
|
||||
static compare(a, b) {
|
||||
const posComparison = a.start - b.start;
|
||||
if (posComparison !== 0) return posComparison;
|
||||
const lengthComparison = b.group.length - a.group.length;
|
||||
if (lengthComparison !== 0) return lengthComparison;
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
module.exports = ParameterTypeMatcher;
|
83
node_modules/cucumber-expressions/dist/src/parameter_type_registry.js
generated
vendored
Normal file
83
node_modules/cucumber-expressions/dist/src/parameter_type_registry.js
generated
vendored
Normal file
@@ -0,0 +1,83 @@
|
||||
"use strict";
|
||||
|
||||
const ParameterType = require('./parameter_type');
|
||||
|
||||
const CucumberExpressionGenerator = require('./cucumber_expression_generator.js');
|
||||
|
||||
const {
|
||||
CucumberExpressionError,
|
||||
AmbiguousParameterTypeError
|
||||
} = require('./errors');
|
||||
|
||||
const INTEGER_REGEXPS = [/-?\d+/, /\d+/];
|
||||
const FLOAT_REGEXP = /-?\d*\.\d+/;
|
||||
const WORD_REGEXP = /[^\s]+/;
|
||||
const STRING_REGEXP = /"([^"\\]*(\\.[^"\\]*)*)"|'([^'\\]*(\\.[^'\\]*)*)'/;
|
||||
const ANONYMOUS_REGEXP = /.*/;
|
||||
|
||||
class ParameterTypeRegistry {
|
||||
constructor() {
|
||||
this._parameterTypeByName = new Map();
|
||||
this._parameterTypesByRegexp = new Map();
|
||||
this.defineParameterType(new ParameterType('int', INTEGER_REGEXPS, Number, s => s && parseInt(s), true, true));
|
||||
this.defineParameterType(new ParameterType('float', FLOAT_REGEXP, Number, s => s && parseFloat(s), true, false));
|
||||
this.defineParameterType(new ParameterType('word', WORD_REGEXP, String, s => s, false, false));
|
||||
this.defineParameterType(new ParameterType('string', STRING_REGEXP, String, s => s.replace(/\\"/g, '"').replace(/\\'/g, "'"), true, false));
|
||||
this.defineParameterType(new ParameterType('', ANONYMOUS_REGEXP, String, s => s, false, true));
|
||||
}
|
||||
|
||||
get parameterTypes() {
|
||||
return this._parameterTypeByName.values();
|
||||
}
|
||||
|
||||
lookupByTypeName(typeName) {
|
||||
return this._parameterTypeByName.get(typeName);
|
||||
}
|
||||
|
||||
lookupByRegexp(parameterTypeRegexp, expressionRegexp, text) {
|
||||
const parameterTypes = this._parameterTypesByRegexp.get(parameterTypeRegexp);
|
||||
|
||||
if (!parameterTypes) return null;
|
||||
|
||||
if (parameterTypes.length > 1 && !parameterTypes[0].preferForRegexpMatch) {
|
||||
// We don't do this check on insertion because we only want to restrict
|
||||
// ambiguiuty when we look up by Regexp. Users of CucumberExpression should
|
||||
// not be restricted.
|
||||
const generatedExpressions = new CucumberExpressionGenerator(this).generateExpressions(text);
|
||||
throw new AmbiguousParameterTypeError.forRegExp(parameterTypeRegexp, expressionRegexp, parameterTypes, generatedExpressions);
|
||||
}
|
||||
|
||||
return parameterTypes[0];
|
||||
}
|
||||
|
||||
defineParameterType(parameterType) {
|
||||
if (parameterType.name !== undefined) {
|
||||
if (this._parameterTypeByName.has(parameterType.name)) if (parameterType.name.length === 0) throw new Error(`The anonymous parameter type has already been defined`);else throw new Error(`There is already a parameter type with name ${parameterType.name}`);
|
||||
|
||||
this._parameterTypeByName.set(parameterType.name, parameterType);
|
||||
}
|
||||
|
||||
for (const parameterTypeRegexp of parameterType.regexps) {
|
||||
if (!this._parameterTypesByRegexp.has(parameterTypeRegexp)) {
|
||||
this._parameterTypesByRegexp.set(parameterTypeRegexp, []);
|
||||
}
|
||||
|
||||
const parameterTypes = this._parameterTypesByRegexp.get(parameterTypeRegexp);
|
||||
|
||||
const existingParameterType = parameterTypes[0];
|
||||
|
||||
if (parameterTypes.length > 0 && existingParameterType.preferForRegexpMatch && parameterType.preferForRegexpMatch) {
|
||||
throw new CucumberExpressionError('There can only be one preferential parameter type per regexp. ' + `The regexp /${parameterTypeRegexp}/ is used for two preferential parameter types, {${existingParameterType.name}} and {${parameterType.name}}`);
|
||||
}
|
||||
|
||||
if (parameterTypes.indexOf(parameterType) === -1) {
|
||||
parameterTypes.push(parameterType);
|
||||
|
||||
this._parameterTypesByRegexp.set(parameterTypeRegexp, parameterTypes.sort(ParameterType.compare));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
module.exports = ParameterTypeRegistry;
|
35
node_modules/cucumber-expressions/dist/src/regular_expression.js
generated
vendored
Normal file
35
node_modules/cucumber-expressions/dist/src/regular_expression.js
generated
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
"use strict";
|
||||
|
||||
const Argument = require('./argument');
|
||||
|
||||
const TreeRegexp = require('./tree_regexp');
|
||||
|
||||
const ParameterType = require('./parameter_type');
|
||||
|
||||
class RegularExpression {
|
||||
constructor(expressionRegexp, parameterTypeRegistry) {
|
||||
this._expressionRegexp = expressionRegexp;
|
||||
this._parameterTypeRegistry = parameterTypeRegistry;
|
||||
this._treeRegexp = new TreeRegexp(expressionRegexp);
|
||||
}
|
||||
|
||||
match(text) {
|
||||
const parameterTypes = this._treeRegexp.groupBuilder.children.map(groupBuilder => {
|
||||
const parameterTypeRegexp = groupBuilder.source;
|
||||
return this._parameterTypeRegistry.lookupByRegexp(parameterTypeRegexp, this._treeRegexp, text) || new ParameterType(null, parameterTypeRegexp, String, s => s, false, false);
|
||||
});
|
||||
|
||||
return Argument.build(this._treeRegexp, text, parameterTypes);
|
||||
}
|
||||
|
||||
get regexp() {
|
||||
return this._expressionRegexp;
|
||||
}
|
||||
|
||||
get source() {
|
||||
return this._expressionRegexp.source;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
module.exports = RegularExpression;
|
74
node_modules/cucumber-expressions/dist/src/tree_regexp.js
generated
vendored
Normal file
74
node_modules/cucumber-expressions/dist/src/tree_regexp.js
generated
vendored
Normal file
@@ -0,0 +1,74 @@
|
||||
"use strict";
|
||||
|
||||
const Regex = require('becke-ch--regex--s0-0-v1--base--pl--lib');
|
||||
|
||||
const GroupBuilder = require('./group_builder');
|
||||
|
||||
class TreeRegexp {
|
||||
constructor(regexp) {
|
||||
this._re = 'string' === typeof regexp ? new RegExp(regexp) : regexp;
|
||||
this._regex = new Regex(this._re.source, this._re.flags);
|
||||
const stack = [new GroupBuilder()];
|
||||
const groupStartStack = [];
|
||||
let last = null;
|
||||
let escaping = false;
|
||||
let nonCapturingMaybe = false;
|
||||
let charClass = false;
|
||||
|
||||
this._re.source.split('').forEach((c, n) => {
|
||||
if (c == '[' && !escaping) {
|
||||
charClass = true;
|
||||
} else if (c == ']' && !escaping) {
|
||||
charClass = false;
|
||||
} else if (c === '(' && !escaping && !charClass) {
|
||||
stack.push(new GroupBuilder());
|
||||
groupStartStack.push(n + 1);
|
||||
nonCapturingMaybe = false;
|
||||
} else if (c === ')' && !escaping && !charClass) {
|
||||
const gb = stack.pop();
|
||||
const groupStart = groupStartStack.pop();
|
||||
|
||||
if (gb.capturing) {
|
||||
gb.source = this._re.source.substring(groupStart, n);
|
||||
stack[stack.length - 1].add(gb);
|
||||
} else {
|
||||
gb.moveChildrenTo(stack[stack.length - 1]);
|
||||
}
|
||||
|
||||
nonCapturingMaybe = false;
|
||||
} else if (c === '?' && last === '(') {
|
||||
nonCapturingMaybe = true;
|
||||
} else if (c === ':' && nonCapturingMaybe) {
|
||||
stack[stack.length - 1].setNonCapturing();
|
||||
nonCapturingMaybe = false;
|
||||
}
|
||||
|
||||
escaping = c === '\\' && !escaping;
|
||||
last = c;
|
||||
});
|
||||
|
||||
this._groupBuilder = stack.pop();
|
||||
}
|
||||
|
||||
get regexp() {
|
||||
return this._re;
|
||||
}
|
||||
|
||||
get groupBuilder() {
|
||||
return this._groupBuilder;
|
||||
}
|
||||
|
||||
match(s) {
|
||||
const match = this._regex.exec(s);
|
||||
|
||||
if (!match) return null;
|
||||
let groupIndex = 0;
|
||||
|
||||
const nextGroupIndex = () => groupIndex++;
|
||||
|
||||
return this._groupBuilder.build(match, nextGroupIndex);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
module.exports = TreeRegexp;
|
Reference in New Issue
Block a user