cucumber-expressions
Version:
Cucumber Expressions - a simpler alternative to Regular Expressions
160 lines • 11.2 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
var assert_1 = __importDefault(require("assert"));
var CucumberExpressionGenerator_1 = __importDefault(require("../src/CucumberExpressionGenerator"));
var CucumberExpression_1 = __importDefault(require("../src/CucumberExpression"));
var ParameterType_1 = __importDefault(require("../src/ParameterType"));
var ParameterTypeRegistry_1 = __importDefault(require("../src/ParameterTypeRegistry"));
var Currency = /** @class */ (function () {
function Currency(s) {
this.s = s;
}
return Currency;
}());
describe('CucumberExpressionGenerator', function () {
var parameterTypeRegistry;
var generator;
function assertExpression(expectedExpression, expectedArgumentNames, text) {
var generatedExpression = generator.generateExpressions(text)[0];
assert_1.default.deepStrictEqual(generatedExpression.parameterNames, expectedArgumentNames);
assert_1.default.strictEqual(generatedExpression.source, expectedExpression);
var cucumberExpression = new CucumberExpression_1.default(generatedExpression.source, parameterTypeRegistry);
var match = cucumberExpression.match(text);
if (match === null) {
assert_1.default.fail("Expected text '" + text + "' to match generated expression '" + generatedExpression.source + "'");
}
assert_1.default.strictEqual(match.length, expectedArgumentNames.length);
}
beforeEach(function () {
parameterTypeRegistry = new ParameterTypeRegistry_1.default();
generator = new CucumberExpressionGenerator_1.default(parameterTypeRegistry);
});
it('documents expression generation', function () {
parameterTypeRegistry = new ParameterTypeRegistry_1.default();
generator = new CucumberExpressionGenerator_1.default(parameterTypeRegistry);
var undefinedStepText = 'I have 2 cucumbers and 1.5 tomato';
var generatedExpression = generator.generateExpressions(undefinedStepText)[0];
assert_1.default.strictEqual(generatedExpression.source, 'I have {int} cucumbers and {float} tomato');
assert_1.default.strictEqual(generatedExpression.parameterNames[0], 'int');
assert_1.default.strictEqual(generatedExpression.parameterTypes[1].name, 'float');
});
it('generates expression for no args', function () {
assertExpression('hello', [], 'hello');
});
it('generates expression with escaped left parenthesis', function () {
assertExpression('\\(iii)', [], '(iii)');
});
it('generates expression with escaped left curly brace', function () {
assertExpression('\\{iii}', [], '{iii}');
});
it('generates expression with escaped slashes', function () {
assertExpression('The {int}\\/{int}\\/{int} hey', ['int', 'int2', 'int3'], 'The 1814/05/17 hey');
});
it('generates expression for int float arg', function () {
assertExpression('I have {int} cukes and {float} euro', ['int', 'float'], 'I have 2 cukes and 1.5 euro');
});
it('generates expression for strings', function () {
assertExpression('I like {string} and {string}', ['string', 'string2'], 'I like "bangers" and \'mash\'');
});
it('generates expression with % sign', function () {
assertExpression('I am {int}%% foobar', ['int'], 'I am 20%% foobar');
});
it('generates expression for just int', function () {
assertExpression('{int}', ['int'], '99999');
});
it('numbers only second argument when builtin type is not reserved keyword', function () {
assertExpression('I have {float} cukes and {float} euro', ['float', 'float2'], 'I have 2.5 cukes and 1.5 euro');
});
it('generates expression for custom type', function () {
parameterTypeRegistry.defineParameterType(new ParameterType_1.default('currency', /[A-Z]{3}/, Currency, function (s) { return new Currency(s); }, true, false));
assertExpression('I have a {currency} account', ['currency'], 'I have a EUR account');
});
it('prefers leftmost match when there is overlap', function () {
parameterTypeRegistry.defineParameterType(new ParameterType_1.default('currency', /c d/, Currency, function (s) { return new Currency(s); }, true, false));
parameterTypeRegistry.defineParameterType(new ParameterType_1.default('date', /b c/, Date, function (s) { return new Date(s); }, true, false));
assertExpression('a {date} d e f g', ['date'], 'a b c d e f g');
});
// TODO: prefers widest match
it('generates all combinations of expressions when several parameter types match', function () {
parameterTypeRegistry.defineParameterType(new ParameterType_1.default('currency', /x/, null, function (s) { return new Currency(s); }, true, false));
parameterTypeRegistry.defineParameterType(new ParameterType_1.default('date', /x/, null, function (s) { return new Date(s); }, true, false));
var generatedExpressions = generator.generateExpressions('I have x and x and another x');
var expressions = generatedExpressions.map(function (e) { return e.source; });
assert_1.default.deepStrictEqual(expressions, [
'I have {currency} and {currency} and another {currency}',
'I have {currency} and {currency} and another {date}',
'I have {currency} and {date} and another {currency}',
'I have {currency} and {date} and another {date}',
'I have {date} and {currency} and another {currency}',
'I have {date} and {currency} and another {date}',
'I have {date} and {date} and another {currency}',
'I have {date} and {date} and another {date}',
]);
});
it('exposes parameter type names in generated expression', function () {
var expression = generator.generateExpressions('I have 2 cukes and 1.5 euro')[0];
var typeNames = expression.parameterTypes.map(function (parameter) { return parameter.name; });
assert_1.default.deepStrictEqual(typeNames, ['int', 'float']);
});
it('matches parameter types with optional capture groups', function () {
parameterTypeRegistry.defineParameterType(new ParameterType_1.default('optional-flight', /(1st flight)?/, null, function (s) { return s; }, true, false));
parameterTypeRegistry.defineParameterType(new ParameterType_1.default('optional-hotel', /(1 hotel)?/, null, function (s) { return s; }, true, false));
var expression = generator.generateExpressions('I reach Stage 4: 1st flight -1 hotel')[0];
// While you would expect this to be `I reach Stage {int}: {optional-flight} -{optional-hotel}` the `-1` causes
// {int} to match just before {optional-hotel}.
assert_1.default.strictEqual(expression.source, 'I reach Stage {int}: {optional-flight} {int} hotel');
});
it('generates at most 256 expressions', function () {
for (var i = 0; i < 4; i++) {
parameterTypeRegistry.defineParameterType(new ParameterType_1.default('my-type-' + i, /([a-z] )*?[a-z]/, null, function (s) { return s; }, true, false));
}
// This would otherwise generate 4^11=419430 expressions and consume just shy of 1.5GB.
var expressions = generator.generateExpressions('a s i m p l e s t e p');
assert_1.default.strictEqual(expressions.length, 256);
});
it('prefers expression with longest non empty match', function () {
parameterTypeRegistry.defineParameterType(new ParameterType_1.default('zero-or-more', /[a-z]*/, null, function (s) { return s; }, true, false));
parameterTypeRegistry.defineParameterType(new ParameterType_1.default('exactly-one', /[a-z]/, null, function (s) { return s; }, true, false));
var expressions = generator.generateExpressions('a simple step');
assert_1.default.strictEqual(expressions.length, 2);
assert_1.default.strictEqual(expressions[0].source, '{exactly-one} {zero-or-more} {zero-or-more}');
assert_1.default.strictEqual(expressions[1].source, '{zero-or-more} {zero-or-more} {zero-or-more}');
});
it('does not suggest parameter included at the beginning of a word', function () {
parameterTypeRegistry.defineParameterType(new ParameterType_1.default('direction', /(up|down)/, null, function (s) { return s; }, true, false));
var expressions = generator.generateExpressions('I download a picture');
assert_1.default.strictEqual(expressions.length, 1);
assert_1.default.notEqual(expressions[0].source, 'I {direction}load a picture');
assert_1.default.strictEqual(expressions[0].source, 'I download a picture');
});
it('does not suggest parameter included inside a word', function () {
parameterTypeRegistry.defineParameterType(new ParameterType_1.default('direction', /(up|down)/, null, function (s) { return s; }, true, false));
var expressions = generator.generateExpressions('I watch the muppet show');
assert_1.default.strictEqual(expressions.length, 1);
assert_1.default.notEqual(expressions[0].source, 'I watch the m{direction}pet show');
assert_1.default.strictEqual(expressions[0].source, 'I watch the muppet show');
});
it('does not suggest parameter at the end of a word', function () {
parameterTypeRegistry.defineParameterType(new ParameterType_1.default('direction', /(up|down)/, null, function (s) { return s; }, true, false));
var expressions = generator.generateExpressions('I create a group');
assert_1.default.strictEqual(expressions.length, 1);
assert_1.default.notEqual(expressions[0].source, 'I create a gro{direction}');
assert_1.default.strictEqual(expressions[0].source, 'I create a group');
});
it('does suggest parameter that are a full word', function () {
parameterTypeRegistry.defineParameterType(new ParameterType_1.default('direction', /(up|down)/, null, function (s) { return s; }, true, false));
assert_1.default.strictEqual(generator.generateExpressions('When I go down the road')[0].source, 'When I go {direction} the road');
assert_1.default.strictEqual(generator.generateExpressions('When I walk up the hill')[0].source, 'When I walk {direction} the hill');
assert_1.default.strictEqual(generator.generateExpressions('up the hill, the road goes down')[0]
.source, '{direction} the hill, the road goes {direction}');
});
it('does not consider punctuation as being part of a word', function () {
parameterTypeRegistry.defineParameterType(new ParameterType_1.default('direction', /(up|down)/, null, function (s) { return s; }, true, false));
assert_1.default.strictEqual(generator.generateExpressions('direction is:down')[0].source, 'direction is:{direction}');
assert_1.default.strictEqual(generator.generateExpressions('direction is down.')[0].source, 'direction is {direction}.');
});
});
//# sourceMappingURL=CucumberExpressionGeneratorTest.js.map