All files cucumber_expression_generator.js

95.74% Statements 45/47
100% Branches 10/10
75% Functions 6/8
95.74% Lines 45/47

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 1211x 1x 1x 1x       18x       17x 17x 17x 17x     17x 49x   49x 266x 266x 106x       49x 37x         37x 37x 106x                 37x 37x 83x     74x     37x   37x   37x     37x   37x     12x     37x 5x       17x 17x                                 17x 17x 98x 64x         17x         64x 64x 81x   64x         54x             1x  
const util = require('util')
const ParameterTypeMatcher = require('./parameter_type_matcher')
const ParameterType = require('./parameter_type')
const CombinatorialGeneratedExpressionFactory = require('./combinatorial_generated_expression_factory')
 
class CucumberExpressionGenerator {
  constructor(parameterTypeRegistry) {
    this._parameterTypeRegistry = parameterTypeRegistry
  }
 
  generateExpressions(text) {
    const parameterTypeCombinations = []
    const parameterTypeMatchers = this._createParameterTypeMatchers(text)
    let expressionTemplate = ''
    let pos = 0
 
    // eslint-disable-next-line no-constant-condition
    while (true) {
      let matchingParameterTypeMatchers = []
 
      for (const parameterTypeMatcher of parameterTypeMatchers) {
        const advancedParameterTypeMatcher = parameterTypeMatcher.advanceTo(pos)
        if (advancedParameterTypeMatcher.find) {
          matchingParameterTypeMatchers.push(advancedParameterTypeMatcher)
        }
      }
 
      if (matchingParameterTypeMatchers.length > 0) {
        matchingParameterTypeMatchers = matchingParameterTypeMatchers.sort(
          ParameterTypeMatcher.compare
        )
 
        // Find all the best parameter type matchers, they are all candidates.
        const bestParameterTypeMatcher = matchingParameterTypeMatchers[0]
        const bestParameterTypeMatchers = matchingParameterTypeMatchers.filter(
          m => ParameterTypeMatcher.compare(m, bestParameterTypeMatcher) === 0
        )
 
        // Build a list of parameter types without duplicates. The reason there
        // might be duplicates is that some parameter types have more than one regexp,
        // which means multiple ParameterTypeMatcher objects will have a reference to the
        // same ParameterType.
        // We're sorting the list so preferential parameter types are listed first.
        // Users are most likely to want these, so they should be listed at the top.
        let parameterTypes = []
        for (const parameterTypeMatcher of bestParameterTypeMatchers) {
          if (
            parameterTypes.indexOf(parameterTypeMatcher.parameterType) === -1
          ) {
            parameterTypes.push(parameterTypeMatcher.parameterType)
          }
        }
        parameterTypes = parameterTypes.sort(ParameterType.compare)
 
        parameterTypeCombinations.push(parameterTypes)
 
        expressionTemplate += escape(
          text.slice(pos, bestParameterTypeMatcher.start)
        )
        expressionTemplate += '{%s}'
 
        pos =
          bestParameterTypeMatcher.start + bestParameterTypeMatcher.group.length
      } else {
        break
      }
 
      if (pos >= text.length) {
        break
      }
    }
 
    expressionTemplate += escape(text.slice(pos))
    return new CombinatorialGeneratedExpressionFactory(
      expressionTemplate,
      parameterTypeCombinations
    ).generateExpressions()
  }
 
  /**
   * @deprecated
   */
  generateExpression(text) {
    return util.deprecate(
      () => this.generateExpressions(text)[0],
      'CucumberExpressionGenerator.generateExpression: Use CucumberExpressionGenerator.generateExpressions instead'
    )()
  }
 
  _createParameterTypeMatchers(text) {
    let parameterMatchers = []
    for (const parameterType of this._parameterTypeRegistry.parameterTypes) {
      if (parameterType.useForSnippets) {
        parameterMatchers = parameterMatchers.concat(
          this._createParameterTypeMatchers2(parameterType, text)
        )
      }
    }
    return parameterMatchers
  }
 
  _createParameterTypeMatchers2(parameterType, text) {
    // TODO: [].map
    const result = []
    for (const regexp of parameterType.regexps) {
      result.push(new ParameterTypeMatcher(parameterType, regexp, text))
    }
    return result
  }
}
 
function escape(s) {
  return s
    .replace(/%/g, '%%') // for util.format
    .replace(/\(/g, '\\(')
    .replace(/{/g, '\\{')
    .replace(/\//g, '\\/')
}
 
module.exports = CucumberExpressionGenerator