init
This commit is contained in:
248
node_modules/cucumber-expressions/test/cucumber_expression_generator_test.js
generated
vendored
Normal file
248
node_modules/cucumber-expressions/test/cucumber_expression_generator_test.js
generated
vendored
Normal file
@@ -0,0 +1,248 @@
|
||||
/* eslint-env mocha */
|
||||
const assert = require('assert')
|
||||
const CucumberExpressionGenerator = require('../src/cucumber_expression_generator')
|
||||
const CucumberExpression = require('../src/cucumber_expression')
|
||||
const ParameterType = require('../src/parameter_type')
|
||||
const ParameterTypeRegistry = require('../src/parameter_type_registry')
|
||||
|
||||
class Currency {}
|
||||
|
||||
describe('CucumberExpressionGenerator', () => {
|
||||
let parameterTypeRegistry, generator
|
||||
|
||||
function assertExpression(expectedExpression, expectedArgumentNames, text) {
|
||||
const generatedExpression = generator.generateExpressions(text)[0]
|
||||
assert.deepEqual(generatedExpression.parameterNames, expectedArgumentNames)
|
||||
assert.equal(generatedExpression.source, expectedExpression)
|
||||
|
||||
const cucumberExpression = new CucumberExpression(
|
||||
generatedExpression.source,
|
||||
parameterTypeRegistry
|
||||
)
|
||||
const match = cucumberExpression.match(text)
|
||||
if (match === null) {
|
||||
assert.fail(
|
||||
`Expected text '${text}' to match generated expression '${
|
||||
generatedExpression.source
|
||||
}'`
|
||||
)
|
||||
}
|
||||
assert.equal(match.length, expectedArgumentNames.length)
|
||||
}
|
||||
|
||||
beforeEach(() => {
|
||||
parameterTypeRegistry = new ParameterTypeRegistry()
|
||||
generator = new CucumberExpressionGenerator(parameterTypeRegistry)
|
||||
})
|
||||
|
||||
it('documents expression generation', () => {
|
||||
const parameterRegistry = new ParameterTypeRegistry()
|
||||
/// [generate-expression]
|
||||
const generator = new CucumberExpressionGenerator(parameterRegistry)
|
||||
const undefinedStepText = 'I have 2 cucumbers and 1.5 tomato'
|
||||
const generatedExpression = generator.generateExpressions(
|
||||
undefinedStepText
|
||||
)[0]
|
||||
assert.equal(
|
||||
generatedExpression.source,
|
||||
'I have {int} cucumbers and {float} tomato'
|
||||
)
|
||||
assert.equal(generatedExpression.parameterNames[0], 'int')
|
||||
assert.equal(generatedExpression.parameterTypes[1].name, 'float')
|
||||
/// [generate-expression]
|
||||
})
|
||||
|
||||
it('generates expression for no args', () => {
|
||||
assertExpression('hello', [], 'hello')
|
||||
})
|
||||
|
||||
it('generates expression with escaped left parenthesis', () => {
|
||||
assertExpression('\\(iii)', [], '(iii)')
|
||||
})
|
||||
|
||||
it('generates expression with escaped left curly brace', () => {
|
||||
assertExpression('\\{iii}', [], '{iii}')
|
||||
})
|
||||
|
||||
it('generates expression with escaped slashes', () => {
|
||||
assertExpression(
|
||||
'The {int}\\/{int}\\/{int} hey',
|
||||
['int', 'int2', 'int3'],
|
||||
'The 1814/05/17 hey'
|
||||
)
|
||||
})
|
||||
|
||||
it('generates expression for int float arg', () => {
|
||||
assertExpression(
|
||||
'I have {int} cukes and {float} euro',
|
||||
['int', 'float'],
|
||||
'I have 2 cukes and 1.5 euro'
|
||||
)
|
||||
})
|
||||
|
||||
it('generates expression for strings', () => {
|
||||
assertExpression(
|
||||
'I like {string} and {string}',
|
||||
['string', 'string2'],
|
||||
'I like "bangers" and \'mash\''
|
||||
)
|
||||
})
|
||||
|
||||
it('generates expression with % sign', () => {
|
||||
assertExpression('I am {int}%% foobar', ['int'], 'I am 20%% foobar')
|
||||
})
|
||||
|
||||
it('generates expression for just int', () => {
|
||||
assertExpression('{int}', ['int'], '99999')
|
||||
})
|
||||
|
||||
it('numbers only second argument when builtin type is not reserved keyword', () => {
|
||||
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', () => {
|
||||
parameterTypeRegistry.defineParameterType(
|
||||
new ParameterType(
|
||||
'currency',
|
||||
/[A-Z]{3}/,
|
||||
Currency,
|
||||
s => 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', () => {
|
||||
parameterTypeRegistry.defineParameterType(
|
||||
new ParameterType(
|
||||
'currency',
|
||||
/cd/,
|
||||
Currency,
|
||||
s => new Currency(s),
|
||||
true,
|
||||
false
|
||||
)
|
||||
)
|
||||
parameterTypeRegistry.defineParameterType(
|
||||
new ParameterType('date', /bc/, Date, s => new Date(s), true, false)
|
||||
)
|
||||
|
||||
assertExpression('a{date}defg', ['date'], 'abcdefg')
|
||||
})
|
||||
|
||||
// TODO: prefers widest match
|
||||
|
||||
it('generates all combinations of expressions when several parameter types match', () => {
|
||||
parameterTypeRegistry.defineParameterType(
|
||||
new ParameterType(
|
||||
'currency',
|
||||
/x/,
|
||||
null,
|
||||
s => new Currency(s),
|
||||
true,
|
||||
false
|
||||
)
|
||||
)
|
||||
parameterTypeRegistry.defineParameterType(
|
||||
new ParameterType('date', /x/, null, s => new Date(s), true, false)
|
||||
)
|
||||
|
||||
const generatedExpressions = generator.generateExpressions(
|
||||
'I have x and x and another x'
|
||||
)
|
||||
const expressions = generatedExpressions.map(e => e.source)
|
||||
assert.deepEqual(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', () => {
|
||||
const expression = generator.generateExpressions(
|
||||
'I have 2 cukes and 1.5 euro'
|
||||
)[0]
|
||||
const typeNames = expression.parameterTypes.map(parameter => parameter.name)
|
||||
assert.deepEqual(typeNames, ['int', 'float'])
|
||||
})
|
||||
|
||||
it('matches parameter types with optional capture groups', () => {
|
||||
parameterTypeRegistry.defineParameterType(
|
||||
new ParameterType(
|
||||
'optional-flight',
|
||||
/(1st flight)?/,
|
||||
null,
|
||||
s => s,
|
||||
true,
|
||||
false
|
||||
)
|
||||
)
|
||||
parameterTypeRegistry.defineParameterType(
|
||||
new ParameterType(
|
||||
'optional-hotel',
|
||||
/(1st hotel)?/,
|
||||
null,
|
||||
s => s,
|
||||
true,
|
||||
false
|
||||
)
|
||||
)
|
||||
|
||||
const expression = generator.generateExpressions(
|
||||
'I reach Stage4: 1st flight-1st 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.equal(
|
||||
expression.source,
|
||||
'I reach Stage{int}: {optional-flight}{int}st hotel'
|
||||
)
|
||||
})
|
||||
|
||||
it('generates at most 256 expressions', () => {
|
||||
for (let i = 0; i < 4; i++) {
|
||||
parameterTypeRegistry.defineParameterType(
|
||||
new ParameterType('my-type-' + i, /[a-z]/, null, s => s, true, false)
|
||||
)
|
||||
}
|
||||
// This would otherwise generate 4^11=419430 expressions and consume just shy of 1.5GB.
|
||||
const expressions = generator.generateExpressions('a simple step')
|
||||
assert.equal(expressions.length, 256)
|
||||
})
|
||||
|
||||
it('prefers expression with longest non empty match', () => {
|
||||
parameterTypeRegistry.defineParameterType(
|
||||
new ParameterType('zero-or-more', /[a-z]*/, null, s => s, true, false)
|
||||
)
|
||||
parameterTypeRegistry.defineParameterType(
|
||||
new ParameterType('exactly-one', /[a-z]/, null, s => s, true, false)
|
||||
)
|
||||
|
||||
const expressions = generator.generateExpressions('a simple step')
|
||||
assert.equal(expressions.length, 2)
|
||||
assert.equal(
|
||||
expressions[0].source,
|
||||
'{exactly-one} {zero-or-more} {zero-or-more}'
|
||||
)
|
||||
assert.equal(
|
||||
expressions[1].source,
|
||||
'{zero-or-more} {zero-or-more} {zero-or-more}'
|
||||
)
|
||||
})
|
||||
})
|
Reference in New Issue
Block a user