UNPKG

cucumber-expressions

Version:

Cucumber Expressions - a simpler alternative to Regular Expressions

254 lines (231 loc) 7.38 kB
'use strict' import assert from 'assert' import assertThrows from './assert_throws' import CucumberExpression from '../src/CucumberExpression' import RegularExpression from '../src/RegularExpression' import ParameterTypeRegistry from '../src/ParameterTypeRegistry' import ParameterType from '../src/ParameterType' class Color { /// [color-constructor] constructor(public readonly name: string) {} /// [color-constructor] } class CssColor { constructor(public readonly name: string) {} } describe('Custom parameter type', () => { let parameterTypeRegistry: ParameterTypeRegistry beforeEach(() => { parameterTypeRegistry = new ParameterTypeRegistry() /* eslint-disable prettier/prettier */ /// [add-color-parameter-type] parameterTypeRegistry.defineParameterType( new ParameterType( 'color', // name /red|blue|yellow/, // regexp Color, // type s => new Color(s), // transformer false, // useForSnippets true // preferForRegexpMatch ) ) /// [add-color-parameter-type] /* eslint-enable prettier/prettier */ }) describe('CucumberExpression', () => { it('throws exception for illegal character in parameter name', () => { assertThrows( () => new ParameterType('[string]', /.*/, String, s => s, false, true), "Illegal character '[' in parameter name {[string]}" ) }) it('matches parameters with custom parameter type', () => { const expression = new CucumberExpression( 'I have a {color} ball', parameterTypeRegistry ) const value = expression.match('I have a red ball')[0].getValue(null) assert.strictEqual(value.name, 'red') }) it('matches parameters with multiple capture groups', () => { class Coordinate { constructor( public readonly x: number, public readonly y: number, public readonly z: number ) {} } parameterTypeRegistry.defineParameterType( new ParameterType( 'coordinate', /(\d+),\s*(\d+),\s*(\d+)/, Coordinate, (x: string, y: string, z: string) => new Coordinate(Number(x), Number(y), Number(z)), true, true ) ) const expression = new CucumberExpression( 'A {int} thick line from {coordinate} to {coordinate}', parameterTypeRegistry ) const args = expression.match('A 5 thick line from 10,20,30 to 40,50,60') const thick = args[0].getValue(null) assert.strictEqual(thick, 5) const from = args[1].getValue(null) assert.strictEqual(from.x, 10) assert.strictEqual(from.y, 20) assert.strictEqual(from.z, 30) const to = args[2].getValue(null) assert.strictEqual(to.x, 40) assert.strictEqual(to.y, 50) assert.strictEqual(to.z, 60) }) it('matches parameters with custom parameter type using optional capture group', () => { parameterTypeRegistry = new ParameterTypeRegistry() parameterTypeRegistry.defineParameterType( new ParameterType( 'color', [/red|blue|yellow/, /(?:dark|light) (?:red|blue|yellow)/], Color, s => new Color(s), false, true ) ) const expression = new CucumberExpression( 'I have a {color} ball', parameterTypeRegistry ) const value = expression.match('I have a dark red ball')[0].getValue(null) assert.strictEqual(value.name, 'dark red') }) it('defers transformation until queried from argument', () => { parameterTypeRegistry.defineParameterType( new ParameterType( 'throwing', /bad/, null, s => { throw new Error(`Can't transform [${s}]`) }, false, true ) ) const expression = new CucumberExpression( 'I have a {throwing} parameter', parameterTypeRegistry ) const args = expression.match('I have a bad parameter') assertThrows(() => args[0].getValue(null), "Can't transform [bad]") }) describe('conflicting parameter type', () => { it('is detected for type name', () => { assertThrows( () => parameterTypeRegistry.defineParameterType( new ParameterType( 'color', /.*/, CssColor, s => new CssColor(s), false, true ) ), 'There is already a parameter type with name color' ) }) it('is not detected for type', () => { parameterTypeRegistry.defineParameterType( new ParameterType( 'whatever', /.*/, Color, s => new Color(s), false, false ) ) }) it('is not detected for regexp', () => { parameterTypeRegistry.defineParameterType( new ParameterType( 'css-color', /red|blue|yellow/, CssColor, s => new CssColor(s), true, false ) ) assert.strictEqual( new CucumberExpression( 'I have a {css-color} ball', parameterTypeRegistry ) .match('I have a blue ball')[0] .getValue(null).constructor, CssColor ) assert.strictEqual( new CucumberExpression( 'I have a {css-color} ball', parameterTypeRegistry ) .match('I have a blue ball')[0] .getValue(null).name, 'blue' ) assert.strictEqual( new CucumberExpression('I have a {color} ball', parameterTypeRegistry) .match('I have a blue ball')[0] .getValue(null).constructor, Color ) assert.strictEqual( new CucumberExpression('I have a {color} ball', parameterTypeRegistry) .match('I have a blue ball')[0] .getValue(null).name, 'blue' ) }) }) // JavaScript-specific it('creates arguments using async transform', async () => { parameterTypeRegistry = new ParameterTypeRegistry() /// [add-async-parameter-type] parameterTypeRegistry.defineParameterType( new ParameterType( 'asyncColor', /red|blue|yellow/, Color, async s => new Color(s), false, true ) ) /// [add-async-parameter-type] const expression = new CucumberExpression( 'I have a {asyncColor} ball', parameterTypeRegistry ) const args = await expression.match('I have a red ball') const value = await args[0].getValue(null) assert.strictEqual(value.name, 'red') }) }) describe('RegularExpression', () => { it('matches arguments with custom parameter type', () => { const expression = new RegularExpression( /I have a (red|blue|yellow) ball/, parameterTypeRegistry ) const value = expression.match('I have a red ball')[0].getValue(null) assert.strictEqual(value.constructor, Color) assert.strictEqual(value.name, 'red') }) }) })