All files parameter_type.js

77.36% Statements 41/53
68.75% Branches 22/32
86.67% Functions 13/15
87.8% Lines 36/41

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 1141x   1x 565x       50x 46x 45x       565x 565x 565x 11x                                             614x 614x 614x   614x   613x 613x 612x 612x 612x 612x       1960x       721x               117x       98x       77x         613x 725x       710x   710x 2838x 1x       709x                   710x 710x           710x     1x  
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
  ) {
    Iif (transform === undefined) transform = s => s
    Iif (useForSnippets === undefined) useForSnippets = true
    Iif (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
  Iif (flags === undefined) {
    flags = ''
    if (regexp.ignoreCase) flags += 'i'
    if (regexp.global) flags += 'g'
    if (regexp.multiline) flags += 'm'
  }
  return flags
}
 
module.exports = ParameterType