All files parameter_type_registry.js

93.48% Statements 43/46
84% Branches 21/25
100% Functions 10/10
93.33% Lines 42/45

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 1311x 1x       1x   1x 1x 1x 1x 1x       111x 111x   111x         27x         111x         2x         111x 2x   111x         12x         111x 7x         17x       67x       30x 30x 15x                           15x       592x 592x 1x         1x     591x     591x 703x 693x   703x     703x 703x         1x             702x 702x 702x                 1x  
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
    Iif (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) {
    Eif (parameterType.name !== undefined) {
      if (this._parameterTypeByName.has(parameterType.name))
        Iif (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}}`
        )
      }
      Eif (parameterTypes.indexOf(parameterType) === -1) {
        parameterTypes.push(parameterType)
        this._parameterTypesByRegexp.set(
          parameterTypeRegexp,
          parameterTypes.sort(ParameterType.compare)
        )
      }
    }
  }
}
 
module.exports = ParameterTypeRegistry