cucumber-expressions 2.0.1 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c8c5e8a795eb6fea91f46e61cc01985a8af0572d
4
- data.tar.gz: 92fa95001cddb0f9d931a02602c0e2d793678d53
3
+ metadata.gz: 8ec8564fdc53d2078266f3cfb82f7eb8db6e8957
4
+ data.tar.gz: 2bb4c9234813e74029bd93c6448ff41ae1a85abb
5
5
  SHA512:
6
- metadata.gz: 7baf62e65277d441049bce8133cc50a6b44a48027cdf53a921b14006cac39358b45ba838890d43d1b1f7ec0edd8a74197e32b2979bfe8885bc5c4b1c963f0c12
7
- data.tar.gz: 44b4dd881b1b7d8649f185b4f60a31ecf91f4ff1ccf6b7934ecd9d1b143200bf0c2ee74f4913c3f4ea308457943ffbacf02d3bfede92dca31746cc698e522749
6
+ metadata.gz: a3c592d0e6e4fad991e45fd27e1f54c466f418f204ba2f65f304c9f9400d9c5289b9472712e19a71637a71fedc762ccea4ef4bf3e00a7600d68dba2c02992dc4
7
+ data.tar.gz: 26195cf45a0624e6920e44fb1a6c99e05300603ec053be5cb13f99df70d55e48a98ecdfda78fb085cbeadaddc394ddceb2149bb244399d1bfde199ad498550d0
@@ -1,7 +1,7 @@
1
1
  # -*- encoding: utf-8 -*-
2
2
  Gem::Specification.new do |s|
3
3
  s.name = 'cucumber-expressions'
4
- s.version = '2.0.1'
4
+ s.version = '3.0.0'
5
5
  s.authors = ["Aslak Hellesøy"]
6
6
  s.description = 'Cucumber Expressions - a simpler alternative to Regular Expressions'
7
7
  s.summary = "cucumber-expressions-#{s.version}"
@@ -3,12 +3,12 @@ module Cucumber
3
3
  class Argument
4
4
  attr_reader :offset, :value
5
5
 
6
- def initialize(offset, value, parameter)
7
- @offset, @value, @parameter = offset, value, parameter
6
+ def initialize(offset, value, parameter_type)
7
+ @offset, @value, @parameter_type = offset, value, parameter_type
8
8
  end
9
9
 
10
10
  def transformed_value
11
- @parameter.transform(@value)
11
+ @parameter_type.transform(@value)
12
12
  end
13
13
  end
14
14
  end
@@ -3,13 +3,13 @@ require 'cucumber/cucumber_expressions/argument'
3
3
  module Cucumber
4
4
  module CucumberExpressions
5
5
  class ArgumentBuilder
6
- def self.build_arguments(regexp, text, parameters)
6
+ def self.build_arguments(regexp, text, parameter_types)
7
7
  m = regexp.match(text)
8
8
  return nil if m.nil?
9
9
  (1...m.length).map do |index|
10
10
  value = m[index]
11
- parameter = parameters[index-1]
12
- Argument.new(m.offset(index)[0], value, parameter)
11
+ parameter_type = parameter_types[index-1]
12
+ Argument.new(m.offset(index)[0], value, parameter_type)
13
13
  end
14
14
  end
15
15
  end
@@ -1,58 +1,62 @@
1
1
  require 'cucumber/cucumber_expressions/argument_builder'
2
- require 'cucumber/cucumber_expressions/parameter'
2
+ require 'cucumber/cucumber_expressions/parameter_type'
3
3
 
4
4
  module Cucumber
5
5
  module CucumberExpressions
6
6
  class CucumberExpression
7
- PARAMETER_PATTERN = /\{([^}:]+)(:([^}]+))?}/
8
- OPTIONAL_PATTERN = /\(([^)]+)\)/
7
+ PARAMETER_REGEXP = /\{([^}:]+)(:([^}]+))?}/
8
+ OPTIONAL_REGEXP = /\(([^)]+)\)/
9
+ ALTERNATIVE_WORD_REGEXP = /([[:alpha:]]+)((\/[[:alpha:]]+)+)/
9
10
 
10
11
  attr_reader :source
11
12
 
12
- def initialize(expression, types, parameter_registry)
13
+ def initialize(expression, types, parameter_type_registry)
13
14
  @source = expression
14
- @parameters = []
15
+ @parameter_types = []
15
16
  regexp = "^"
16
17
  type_index = 0
17
- match = nil
18
18
  match_offset = 0
19
19
 
20
- # Does not include (){} because they have special meaning
20
+ # Escape Does not include (){} because they have special meaning
21
21
  expression = expression.gsub(/([\\\^\[$.|?*+\]])/, '\\\\\1')
22
22
 
23
23
  # Create non-capturing, optional capture groups from parenthesis
24
- expression = expression.gsub(OPTIONAL_PATTERN, '(?:\1)?')
24
+ expression = expression.gsub(OPTIONAL_REGEXP, '(?:\1)?')
25
+
26
+ expression = expression.gsub(ALTERNATIVE_WORD_REGEXP) do |_|
27
+ "(?:#{$1}#{$2.tr('/', '|')})"
28
+ end
25
29
 
26
30
  loop do
27
- match = PARAMETER_PATTERN.match(expression, match_offset)
31
+ match = PARAMETER_REGEXP.match(expression, match_offset)
28
32
  break if match.nil?
29
33
 
30
34
  parameter_name = match[1]
31
- type_name = match[3]
32
- if type_name
33
- $stderr.puts("Cucumber expression parameter syntax {#{parameter_name}:#{type_name}} is deprecated. Please use {#{type_name}} instead.")
35
+ parameter_type_name = match[3]
36
+ if parameter_type_name
37
+ $stderr.puts("Cucumber expression parameter syntax {#{parameter_name}:#{parameter_type_name}} is deprecated. Please use {#{parameter_type_name}} instead.")
34
38
  end
35
39
 
36
40
  type = types.length <= type_index ? nil : types[type_index]
37
41
  type_index += 1
38
42
 
39
- parameter = nil
43
+ parameter_type = nil
40
44
  if type
41
- parameter = parameter_registry.lookup_by_type(type)
45
+ parameter_type = parameter_type_registry.lookup_by_type(type)
42
46
  end
43
- if parameter.nil? && type_name
44
- parameter = parameter_registry.lookup_by_type_name(type_name)
47
+ if parameter_type.nil? && parameter_type_name
48
+ parameter_type = parameter_type_registry.lookup_by_name(parameter_type_name)
45
49
  end
46
- if parameter.nil?
47
- parameter = parameter_registry.lookup_by_type_name(parameter_name)
50
+ if parameter_type.nil?
51
+ parameter_type = parameter_type_registry.lookup_by_name(parameter_name)
48
52
  end
49
- if parameter.nil?
50
- parameter = parameter_registry.create_anonymous_lookup(lambda {|s| s})
53
+ if parameter_type.nil?
54
+ parameter_type = parameter_type_registry.create_anonymous_lookup(lambda {|s| s})
51
55
  end
52
- @parameters.push(parameter)
56
+ @parameter_types.push(parameter_type)
53
57
 
54
58
  text = expression.slice(match_offset...match.offset(0)[0])
55
- capture_regexp = capture_group_regexp(parameter.capture_group_regexps)
59
+ capture_regexp = regexp(parameter_type.regexps)
56
60
  match_offset = match.offset(0)[1]
57
61
  regexp += text
58
62
  regexp += capture_regexp
@@ -63,14 +67,14 @@ module Cucumber
63
67
  end
64
68
 
65
69
  def match(text)
66
- ArgumentBuilder.build_arguments(@regexp, text, @parameters)
70
+ ArgumentBuilder.build_arguments(@regexp, text, @parameter_types)
67
71
  end
68
72
 
69
73
  private
70
74
 
71
- def capture_group_regexp(capture_group_regexps)
72
- return "(#{capture_group_regexps[0]})" if capture_group_regexps.size == 1
73
- capture_groups = capture_group_regexps.map { |group| "(?:#{group})" }
75
+ def regexp(regexps)
76
+ return "(#{regexps[0]})" if regexps.size == 1
77
+ capture_groups = regexps.map { |group| "(?:#{group})" }
74
78
  "(#{capture_groups.join('|')})"
75
79
  end
76
80
  end
@@ -1,44 +1,44 @@
1
- require 'cucumber/cucumber_expressions/parameter_matcher'
1
+ require 'cucumber/cucumber_expressions/parameter_type_matcher'
2
2
  require 'cucumber/cucumber_expressions/generated_expression'
3
3
 
4
4
  module Cucumber
5
5
  module CucumberExpressions
6
6
  class CucumberExpressionGenerator
7
- def initialize(parameter_registry)
8
- @parameter_registry = parameter_registry
7
+ def initialize(parameter_type_registry)
8
+ @parameter_type_registry = parameter_type_registry
9
9
  end
10
10
 
11
11
  def generate_expression(text)
12
12
  parameter_names = []
13
- parameter_matchers = create_parameter_matchers(text)
14
- parameters = []
15
- usage_by_type_name = Hash.new(0)
13
+ parameter_type_matchers = create_parameter_type_matchers(text)
14
+ parameter_types = []
15
+ usage_by_name = Hash.new(0)
16
16
 
17
17
  expression = ""
18
18
  pos = 0
19
19
 
20
20
  loop do
21
- matching_parameter_matchers = []
22
- parameter_matchers.each do |parameter_matcher|
23
- advanced_parameter_matcher = parameter_matcher.advance_to(pos)
24
- if advanced_parameter_matcher.find
25
- matching_parameter_matchers.push(advanced_parameter_matcher)
21
+ matching_parameter_type_matchers = []
22
+ parameter_type_matchers.each do |parameter_type_matcher|
23
+ advanced_parameter_type_matcher = parameter_type_matcher.advance_to(pos)
24
+ if advanced_parameter_type_matcher.find
25
+ matching_parameter_type_matchers.push(advanced_parameter_type_matcher)
26
26
  end
27
27
  end
28
28
 
29
- if matching_parameter_matchers.any?
30
- matching_parameter_matchers = matching_parameter_matchers.sort
31
- best_parameter_matcher = matching_parameter_matchers[0]
32
- parameter = best_parameter_matcher.parameter
33
- parameters.push(parameter)
29
+ if matching_parameter_type_matchers.any?
30
+ matching_parameter_type_matchers = matching_parameter_type_matchers.sort
31
+ best_parameter_type_matcher = matching_parameter_type_matchers[0]
32
+ parameter_type = best_parameter_type_matcher.parameter
33
+ parameter_types.push(parameter_type)
34
34
 
35
- parameter_name = get_parameter_name(parameter.type_name, usage_by_type_name)
35
+ parameter_name = get_parameter_name(parameter_type.name, usage_by_name)
36
36
  parameter_names.push(parameter_name)
37
37
 
38
- expression += text.slice(pos...best_parameter_matcher.start)
39
- expression += "{#{parameter.type_name}}"
38
+ expression += text.slice(pos...best_parameter_type_matcher.start)
39
+ expression += "{#{parameter_type.name}}"
40
40
 
41
- pos = best_parameter_matcher.start + best_parameter_matcher.group.length
41
+ pos = best_parameter_type_matcher.start + best_parameter_type_matcher.group.length
42
42
  else
43
43
  break
44
44
  end
@@ -49,30 +49,30 @@ module Cucumber
49
49
  end
50
50
 
51
51
  expression += text.slice(pos..-1)
52
- GeneratedExpression.new(expression, parameter_names, parameters)
52
+ GeneratedExpression.new(expression, parameter_names, parameter_types)
53
53
  end
54
54
 
55
55
  private
56
56
 
57
- def get_parameter_name(type_name, usage_by_type_name)
58
- count = (usage_by_type_name[type_name] += 1)
59
- count == 1 ? type_name : "#{type_name}#{count}"
57
+ def get_parameter_name(name, usage_by_name)
58
+ count = (usage_by_name[name] += 1)
59
+ count == 1 ? name : "#{name}#{count}"
60
60
  end
61
61
 
62
- def create_parameter_matchers(text)
62
+ def create_parameter_type_matchers(text)
63
63
  parameter_matchers = []
64
- @parameter_registry.parameters.each do |parameter|
65
- parameter_matchers += create_parameter_matchers2(parameter, text)
64
+ @parameter_type_registry.parameter_types.each do |parameter_type|
65
+ parameter_matchers += create_parameter_type_matchers2(parameter_type, text)
66
66
  end
67
67
  parameter_matchers
68
68
  end
69
69
 
70
- def create_parameter_matchers2(parameter, text)
70
+ def create_parameter_type_matchers2(parameter_type, text)
71
71
  result = []
72
- capture_group_regexps = parameter.capture_group_regexps
73
- capture_group_regexps.each do |capture_group_regexp|
74
- regexp = Regexp.new("(#{capture_group_regexp})")
75
- result.push(ParameterMatcher.new(parameter, regexp, text))
72
+ regexps = parameter_type.regexps
73
+ regexps.each do |regexp|
74
+ regexp = Regexp.new("(#{regexp})")
75
+ result.push(ParameterTypeMatcher.new(parameter_type, regexp, text))
76
76
  end
77
77
  result
78
78
  end
@@ -1,10 +1,10 @@
1
1
  module Cucumber
2
2
  module CucumberExpressions
3
3
  class GeneratedExpression
4
- attr_reader :source, :parameter_names, :parameters
4
+ attr_reader :source, :parameter_names, :parameter_types
5
5
 
6
- def initialize(source, parameter_names, parameters)
7
- @source, @parameter_names, @parameters = source, parameter_names, parameters
6
+ def initialize(source, parameter_names, parameters_types)
7
+ @source, @parameter_names, @parameter_types = source, parameter_names, parameters_types
8
8
  end
9
9
  end
10
10
  end
@@ -0,0 +1,29 @@
1
+ module Cucumber
2
+ module CucumberExpressions
3
+ class ParameterType
4
+ attr_reader :name, :type, :regexps
5
+
6
+ # Create a new Parameter
7
+ #
8
+ # @param name the name of the parameter type
9
+ # @param regexps [Array] list of regexps for capture groups. A single regexp can also be used.
10
+ # @param transformer lambda that transforms a String to (possibly) another type
11
+ #
12
+ def initialize(name, type, regexp, transformer)
13
+ @name, @type, @transformer = name, type, transformer
14
+ @regexps = string_array(regexp)
15
+ end
16
+
17
+ def transform(value)
18
+ @transformer ? @transformer.call(value) : value
19
+ end
20
+
21
+ private
22
+
23
+ def string_array(regexp)
24
+ array = regexp.is_a?(Array) ? regexp : [regexp]
25
+ array.map { |r| r.is_a?(String) ? r : r.source }
26
+ end
27
+ end
28
+ end
29
+ end
@@ -1,6 +1,6 @@
1
1
  module Cucumber
2
2
  module CucumberExpressions
3
- class ParameterMatcher
3
+ class ParameterTypeMatcher
4
4
  attr_reader :parameter
5
5
 
6
6
  def initialize(parameter, regexp, text, match_position=0)
@@ -0,0 +1,82 @@
1
+ require 'cucumber/cucumber_expressions/parameter_type'
2
+
3
+ module Cucumber
4
+ module CucumberExpressions
5
+ class ParameterTypeRegistry
6
+ INTEGER_REGEXPS = [/-?\d+/, /\d+/]
7
+ FLOAT_REGEXP = /-?\d*\.?\d+/
8
+
9
+ def initialize
10
+ @parameter_types_by_name = {}
11
+ @parameter_types_by_regexp = {}
12
+ @parameter_types_by_class = {}
13
+
14
+ define_predefined_parameter_type(ParameterType.new('int', Integer, INTEGER_REGEXPS, lambda { |s| s.to_i }))
15
+ define_predefined_parameter_type(ParameterType.new('float', Float, FLOAT_REGEXP, lambda { |s| s.to_f }))
16
+ end
17
+
18
+ def lookup_by_type(type)
19
+ if type.is_a?(Class)
20
+ lookup_by_class(type)
21
+ elsif type.is_a?(String)
22
+ lookup_by_name(type)
23
+ else
24
+ raise Exception.new("Type must be string or class, but was #{type} of type #{type.class}")
25
+ end
26
+ end
27
+
28
+ def lookup_by_class(clazz)
29
+ parameter = @parameter_types_by_class[clazz]
30
+ if parameter.nil?
31
+ create_anonymous_lookup(lambda { |s| clazz.new(s) })
32
+ else
33
+ parameter
34
+ end
35
+ end
36
+
37
+ def lookup_by_name(name)
38
+ @parameter_types_by_name[name]
39
+ end
40
+
41
+ def lookup_by_regexp(regexp)
42
+ @parameter_types_by_regexp[regexp]
43
+ end
44
+
45
+ def create_anonymous_lookup(proc)
46
+ ParameterType.new(nil, nil, ['.+'], proc)
47
+ end
48
+
49
+ def parameter_types
50
+ @parameter_types_by_name.values
51
+ end
52
+
53
+ def define_parameter_type(parameter_type)
54
+ define_parameter_type0(parameter_type, true)
55
+ end
56
+
57
+ private
58
+
59
+ def define_predefined_parameter_type(parameter_type)
60
+ define_parameter_type0(parameter_type, false)
61
+ end
62
+
63
+ def define_parameter_type0(parameter_type, check_conflicts)
64
+ if parameter_type.type
65
+ put(@parameter_types_by_class, parameter_type.type, parameter_type, "type", check_conflicts)
66
+ end
67
+ put(@parameter_types_by_name, parameter_type.name, parameter_type, "type name", check_conflicts)
68
+
69
+ parameter_type.regexps.each do |regexp|
70
+ put(@parameter_types_by_regexp, regexp, parameter_type, "regexp", check_conflicts)
71
+ end
72
+ end
73
+
74
+ def put(map, key, parameter, prop, check_conflicts)
75
+ if check_conflicts && map.has_key?(key)
76
+ raise "There is already a parameter with #{prop} #{key}"
77
+ end
78
+ map[key] = parameter
79
+ end
80
+ end
81
+ end
82
+ end
@@ -5,9 +5,9 @@ module Cucumber
5
5
  class RegularExpression
6
6
  CAPTURE_GROUP_PATTERN = /\(([^(]+)\)/
7
7
 
8
- def initialize(regexp, types, parameter_registry)
8
+ def initialize(regexp, types, parameter_type_registry)
9
9
  @regexp = regexp
10
- @parameters = []
10
+ @parameter_types = []
11
11
 
12
12
  type_index = 0
13
13
  match = nil
@@ -21,24 +21,24 @@ module Cucumber
21
21
  type = types.length <= type_index ? nil : types[type_index]
22
22
  type_index += 1
23
23
 
24
- parameter = nil
24
+ parameter_type = nil
25
25
  if (type)
26
- parameter = parameter_registry.lookup_by_type(type)
26
+ parameter_type = parameter_type_registry.lookup_by_type(type)
27
27
  end
28
- if (parameter.nil?)
29
- parameter = parameter_registry.lookup_by_capture_group_regexp(capture_group_pattern)
28
+ if (parameter_type.nil?)
29
+ parameter_type = parameter_type_registry.lookup_by_regexp(capture_group_pattern)
30
30
  end
31
- if (parameter.nil?)
32
- parameter = parameter_registry.create_anonymous_lookup(lambda {|s| s})
31
+ if (parameter_type.nil?)
32
+ parameter_type = parameter_type_registry.create_anonymous_lookup(lambda {|s| s})
33
33
  end
34
34
 
35
- @parameters.push(parameter)
35
+ @parameter_types.push(parameter_type)
36
36
  match_offset = match.offset(0)[1]
37
37
  end
38
38
  end
39
39
 
40
40
  def match(text)
41
- ArgumentBuilder.build_arguments(@regexp, text, @parameters)
41
+ ArgumentBuilder.build_arguments(@regexp, text, @parameter_types)
42
42
  end
43
43
 
44
44
  def source
@@ -1,6 +1,6 @@
1
1
  require 'cucumber/cucumber_expressions/cucumber_expression_generator'
2
- require 'cucumber/cucumber_expressions/parameter'
3
- require 'cucumber/cucumber_expressions/parameter_registry'
2
+ require 'cucumber/cucumber_expressions/parameter_type'
3
+ require 'cucumber/cucumber_expressions/parameter_type_registry'
4
4
 
5
5
  module Cucumber
6
6
  module CucumberExpressions
@@ -9,18 +9,18 @@ module Cucumber
9
9
  end
10
10
 
11
11
  before do
12
- @parameter_registry = ParameterRegistry.new
13
- @generator = CucumberExpressionGenerator.new(@parameter_registry)
12
+ @parameter_type_registry = ParameterTypeRegistry.new
13
+ @generator = CucumberExpressionGenerator.new(@parameter_type_registry)
14
14
  end
15
15
 
16
16
  it "documents expression generation" do
17
- parameter_registry = ParameterRegistry.new
17
+ parameter_registry = ParameterTypeRegistry.new
18
18
  ### [generate-expression]
19
19
  generator = CucumberExpressionGenerator.new(parameter_registry)
20
20
  undefined_step_text = "I have 2 cucumbers and 1.5 tomato"
21
21
  generated_expression = generator.generate_expression(undefined_step_text)
22
22
  expect(generated_expression.source).to eq("I have {int} cucumbers and {float} tomato")
23
- expect(generated_expression.parameters[1].type).to eq(Float)
23
+ expect(generated_expression.parameter_types[1].type).to eq(Float)
24
24
  ### [generate-expression]
25
25
  end
26
26
 
@@ -47,7 +47,7 @@ module Cucumber
47
47
  end
48
48
 
49
49
  it "numbers only second argument when type is not reserved keyword" do
50
- @parameter_registry.add_parameter(Parameter.new(
50
+ @parameter_type_registry.define_parameter_type(ParameterType.new(
51
51
  'currency',
52
52
  Currency,
53
53
  '[A-Z]{3}',
@@ -61,7 +61,7 @@ module Cucumber
61
61
 
62
62
  it "exposes parameters in generated expression" do
63
63
  expression = @generator.generate_expression("I have 2 cukes and 1.5 euro")
64
- types = expression.parameters.map(&:type)
64
+ types = expression.parameter_types.map(&:type)
65
65
  expect(types).to eq([Integer, Float])
66
66
  end
67
67
 
@@ -1,12 +1,12 @@
1
1
  require 'cucumber/cucumber_expressions/cucumber_expression'
2
- require 'cucumber/cucumber_expressions/parameter_registry'
2
+ require 'cucumber/cucumber_expressions/parameter_type_registry'
3
3
 
4
4
  module Cucumber
5
5
  module CucumberExpressions
6
6
  describe CucumberExpression do
7
7
  context "Regexp translation" do
8
8
  def assert_regexp(expression, regexp)
9
- cucumber_expression = CucumberExpression.new(expression, [], ParameterRegistry.new)
9
+ cucumber_expression = CucumberExpression.new(expression, [], ParameterTypeRegistry.new)
10
10
  expect(regexp).to eq(cucumber_expression.instance_variable_get('@regexp'))
11
11
  end
12
12
 
@@ -17,6 +17,13 @@ module Cucumber
17
17
  )
18
18
  end
19
19
 
20
+ it "translates alternation" do
21
+ assert_regexp(
22
+ "I had/have a great/nice/charming friend",
23
+ /^I (?:had|have) a (?:great|nice|charming) friend$/
24
+ )
25
+ end
26
+
20
27
  it "translates two untyped arguments" do
21
28
  assert_regexp(
22
29
  "I have {n} cukes in my {bodypart} now",
@@ -1,11 +1,11 @@
1
1
  require 'cucumber/cucumber_expressions/cucumber_expression'
2
- require 'cucumber/cucumber_expressions/parameter_registry'
2
+ require 'cucumber/cucumber_expressions/parameter_type_registry'
3
3
 
4
4
  module Cucumber
5
5
  module CucumberExpressions
6
6
  describe CucumberExpression do
7
7
  it "documents match arguments" do
8
- parameter_registry = ParameterRegistry.new
8
+ parameter_registry = ParameterTypeRegistry.new
9
9
 
10
10
  ### [capture-match-arguments]
11
11
  expr = "I have {n} cuke(s) in my {bodypart} now"
@@ -58,12 +58,12 @@ module Cucumber
58
58
 
59
59
  it "exposes source" do
60
60
  expr = "I have {int} cuke(s) in my {bodypart} now"
61
- expect(CucumberExpression.new(expr, [], ParameterRegistry.new).source).to eq(expr)
61
+ expect(CucumberExpression.new(expr, [], ParameterTypeRegistry.new).source).to eq(expr)
62
62
  end
63
63
 
64
64
  it "exposes offset and value" do
65
65
  expr = "I have {int} cuke(s) in my {bodypart} now"
66
- expression = CucumberExpression.new(expr, [], ParameterRegistry.new)
66
+ expression = CucumberExpression.new(expr, [], ParameterTypeRegistry.new)
67
67
  arg1 = expression.match("I have 800 cukes in my brain now")[0]
68
68
  expect(arg1.offset).to eq(7)
69
69
  expect(arg1.value).to eq("800")
@@ -73,7 +73,7 @@ module Cucumber
73
73
  %w(\\ [ ] ^ $ . | ? * +).each do |character|
74
74
  it "escapes #{character}" do
75
75
  expr = "I have {int} cuke(s) and #{character}"
76
- expression = CucumberExpression.new(expr, [], ParameterRegistry.new)
76
+ expression = CucumberExpression.new(expr, [], ParameterTypeRegistry.new)
77
77
  arg1 = expression.match("I have 800 cukes and #{character}")[0]
78
78
  expect(arg1.offset).to eq(7)
79
79
  expect(arg1.value).to eq("800")
@@ -82,7 +82,7 @@ module Cucumber
82
82
  end
83
83
 
84
84
  def match(expression, text, types = [])
85
- cucumber_expression = CucumberExpression.new(expression, types, ParameterRegistry.new)
85
+ cucumber_expression = CucumberExpression.new(expression, types, ParameterTypeRegistry.new)
86
86
  args = cucumber_expression.match(text)
87
87
  return nil if args.nil?
88
88
  args.map { |arg| arg.transformed_value }
@@ -0,0 +1,164 @@
1
+ require 'cucumber/cucumber_expressions/cucumber_expression'
2
+ require 'cucumber/cucumber_expressions/regular_expression'
3
+ require 'cucumber/cucumber_expressions/parameter_type_registry'
4
+
5
+ module Cucumber
6
+ module CucumberExpressions
7
+ class Color
8
+ attr_reader :name
9
+
10
+ ### [color-constructor]
11
+ def initialize(name)
12
+ @name = name
13
+ end
14
+ ### [color-constructor]
15
+
16
+ def ==(other)
17
+ other.is_a?(Color) && other.name == name
18
+ end
19
+ end
20
+
21
+ describe "Custom parameter" do
22
+ before do
23
+ parameter_registry = ParameterTypeRegistry.new
24
+ ### [add-color-parameter]
25
+ parameter_registry.define_parameter_type(ParameterType.new(
26
+ 'color',
27
+ Color,
28
+ /red|blue|yellow/,
29
+ lambda { |s| Color.new(s) }
30
+ ))
31
+ ### [add-color-parameter]
32
+ @parameter_type_registry = parameter_registry
33
+ end
34
+
35
+ describe CucumberExpression do
36
+ it "matches parameters with custom parameter type" do
37
+ expression = CucumberExpression.new("I have a {color} ball", [], @parameter_type_registry)
38
+ transformed_argument_value = expression.match("I have a red ball")[0].transformed_value
39
+ expect( transformed_argument_value ).to eq(Color.new('red'))
40
+ end
41
+
42
+ it "matches parameters with custom parameter type using optional capture group" do
43
+ parameter_registry = ParameterTypeRegistry.new
44
+ parameter_registry.define_parameter_type(ParameterType.new(
45
+ 'color',
46
+ Color,
47
+ [/red|blue|yellow/, /(?:dark|light) (?:red|blue|yellow)/],
48
+ lambda { |s| Color.new(s) }
49
+ ))
50
+ expression = CucumberExpression.new("I have a {color} ball", [], parameter_registry)
51
+ transformed_argument_value = expression.match("I have a dark red ball")[0].transformed_value
52
+ expect( transformed_argument_value ).to eq(Color.new('dark red'))
53
+ end
54
+
55
+ it "matches parameters with custom parameter type without constructor function and transform" do
56
+ parameter_registry = ParameterTypeRegistry.new
57
+ parameter_registry.define_parameter_type(ParameterType.new(
58
+ 'color',
59
+ nil,
60
+ /red|blue|yellow/,
61
+ nil
62
+ ))
63
+ expression = CucumberExpression.new("I have a {color} ball", [], parameter_registry)
64
+ transformed_argument_value = expression.match("I have a red ball")[0].transformed_value
65
+ expect( transformed_argument_value ).to eq('red')
66
+ end
67
+
68
+ it "matches parameters with explicit type" do
69
+ expression = CucumberExpression.new("I have a {color} ball", [Color], @parameter_type_registry)
70
+ transformed_argument_value = expression.match("I have a red ball")[0].transformed_value
71
+ expect( transformed_argument_value ).to eq(Color.new('red'))
72
+ end
73
+
74
+ it "matches parameters with explicit type that isn't registered" do
75
+ expression = CucumberExpression.new("I have a {color} ball", [Color], ParameterTypeRegistry.new)
76
+ transformed_argument_value = expression.match("I have a red ball")[0].transformed_value
77
+ expect( transformed_argument_value ).to eq(Color.new('red'))
78
+ end
79
+
80
+ it "defers transformation until queried from argument" do
81
+ @parameter_type_registry.define_parameter_type(ParameterType.new(
82
+ 'throwing',
83
+ String,
84
+ /bad/,
85
+ lambda { |s| raise "Can't transform [#{s}]" }
86
+ ))
87
+ expression = CucumberExpression.new("I have a {throwing} parameter", [], @parameter_type_registry)
88
+ args = expression.match("I have a bad parameter")
89
+ expect { args[0].transformed_value }.to raise_error("Can't transform [bad]")
90
+ end
91
+
92
+ describe "conflicting parameter type" do
93
+ it "is detected for type name" do
94
+ expect {
95
+ @parameter_type_registry.define_parameter_type(ParameterType.new(
96
+ 'color',
97
+ String,
98
+ /.*/,
99
+ lambda { |s| s }
100
+ ))
101
+ }.to raise_error("There is already a parameter with type name color")
102
+ end
103
+
104
+ it "is detected for type" do
105
+ expect {
106
+ @parameter_type_registry.define_parameter_type(ParameterType.new(
107
+ 'color2',
108
+ Color,
109
+ /.*/,
110
+ lambda { |s| Color.new(s) }
111
+ ))
112
+ }.to raise_error("There is already a parameter with type Cucumber::CucumberExpressions::Color")
113
+ end
114
+
115
+ it "is detected for regexp" do
116
+ expect {
117
+ @parameter_type_registry.define_parameter_type(ParameterType.new(
118
+ 'color2',
119
+ String,
120
+ /red|blue|yellow/,
121
+ lambda { |s| s }
122
+ ))
123
+ }.to raise_error("There is already a parameter with regexp red|blue|yellow")
124
+ end
125
+
126
+ it "is not detected when type is nil" do
127
+ @parameter_type_registry.define_parameter_type(ParameterType.new(
128
+ 'foo',
129
+ nil,
130
+ /foo/,
131
+ lambda { |s| s }
132
+ ))
133
+ @parameter_type_registry.define_parameter_type(ParameterType.new(
134
+ 'bar',
135
+ nil,
136
+ /bar/,
137
+ lambda { |s| s }
138
+ ))
139
+ end
140
+ end
141
+ end
142
+
143
+ describe RegularExpression do
144
+ it "matches parameters with explicit constructor" do
145
+ expression = RegularExpression.new(/I have a (red|blue|yellow) ball/, [Color], @parameter_type_registry)
146
+ transformed_argument_value = expression.match("I have a red ball")[0].transformed_value
147
+ expect( transformed_argument_value ).to eq(Color.new('red'))
148
+ end
149
+
150
+ it "matches parameters without explicit constructor" do
151
+ expression = RegularExpression.new(/I have a (red|blue|yellow) ball/, [], @parameter_type_registry)
152
+ transformed_argument_value = expression.match("I have a red ball")[0].transformed_value
153
+ expect( transformed_argument_value ).to eq(Color.new('red'))
154
+ end
155
+
156
+ it "matches parameters with explicit type that isn't registered" do
157
+ expression = RegularExpression.new(/I have a (red|blue|yellow) ball/, [Color], ParameterTypeRegistry.new)
158
+ transformed_argument_value = expression.match("I have a red ball")[0].transformed_value
159
+ expect( transformed_argument_value ).to eq(Color.new('red'))
160
+ end
161
+ end
162
+ end
163
+ end
164
+ end
@@ -1,6 +1,6 @@
1
1
  require 'cucumber/cucumber_expressions/cucumber_expression'
2
2
  require 'cucumber/cucumber_expressions/regular_expression'
3
- require 'cucumber/cucumber_expressions/parameter_registry'
3
+ require 'cucumber/cucumber_expressions/parameter_type_registry'
4
4
  require 'json'
5
5
 
6
6
  module Cucumber
@@ -8,8 +8,8 @@ module Cucumber
8
8
  describe 'examples.txt' do
9
9
  def match(expression_text, text)
10
10
  expression = expression_text =~ /\/(.*)\// ?
11
- RegularExpression.new(Regexp.new($1), [], ParameterRegistry.new) :
12
- CucumberExpression.new(expression_text, [], ParameterRegistry.new)
11
+ RegularExpression.new(Regexp.new($1), [], ParameterTypeRegistry.new) :
12
+ CucumberExpression.new(expression_text, [], ParameterTypeRegistry.new)
13
13
 
14
14
  arguments = expression.match(text)
15
15
  return nil if arguments.nil?
@@ -1,16 +1,16 @@
1
1
  require 'cucumber/cucumber_expressions/regular_expression'
2
- require 'cucumber/cucumber_expressions/parameter_registry'
2
+ require 'cucumber/cucumber_expressions/parameter_type_registry'
3
3
 
4
4
  module Cucumber
5
5
  module CucumberExpressions
6
6
  describe RegularExpression do
7
7
  it "documents match arguments" do
8
- parameter_registry = ParameterRegistry.new
8
+ parameter_type_registry = ParameterTypeRegistry.new
9
9
 
10
10
  ### [capture-match-arguments]
11
11
  expr = /I have (\d+) cukes? in my (\w*) now/
12
12
  types = ['int', nil]
13
- expression = RegularExpression.new(expr, types, parameter_registry)
13
+ expression = RegularExpression.new(expr, types, parameter_type_registry)
14
14
  args = expression.match("I have 7 cukes in my belly now")
15
15
  expect( args[0].transformed_value ).to eq(7)
16
16
  expect( args[1].transformed_value ).to eq("belly")
@@ -57,11 +57,11 @@ module Cucumber
57
57
 
58
58
  it "exposes source" do
59
59
  expr = /I have (\d+) cukes? in my (\+) now/
60
- expect(RegularExpression.new(expr, [], ParameterRegistry.new).source).to eq(expr)
60
+ expect(RegularExpression.new(expr, [], ParameterTypeRegistry.new).source).to eq(expr)
61
61
  end
62
62
 
63
63
  def match(expression, text, types = [])
64
- regular_expression = RegularExpression.new(expression, types, ParameterRegistry.new)
64
+ regular_expression = RegularExpression.new(expression, types, ParameterTypeRegistry.new)
65
65
  arguments = regular_expression.match(text)
66
66
  return nil if arguments.nil?
67
67
  arguments.map { |arg| arg.transformed_value }
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cucumber-expressions
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.1
4
+ version: 3.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Aslak Hellesøy
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-02-17 00:00:00.000000000 Z
11
+ date: 2017-03-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -86,16 +86,16 @@ files:
86
86
  - lib/cucumber/cucumber_expressions/cucumber_expression.rb
87
87
  - lib/cucumber/cucumber_expressions/cucumber_expression_generator.rb
88
88
  - lib/cucumber/cucumber_expressions/generated_expression.rb
89
- - lib/cucumber/cucumber_expressions/parameter.rb
90
- - lib/cucumber/cucumber_expressions/parameter_matcher.rb
91
- - lib/cucumber/cucumber_expressions/parameter_registry.rb
89
+ - lib/cucumber/cucumber_expressions/parameter_type.rb
90
+ - lib/cucumber/cucumber_expressions/parameter_type_matcher.rb
91
+ - lib/cucumber/cucumber_expressions/parameter_type_registry.rb
92
92
  - lib/cucumber/cucumber_expressions/regular_expression.rb
93
93
  - spec/capture_warnings.rb
94
94
  - spec/coverage.rb
95
95
  - spec/cucumber/cucumber_expressions/cucumber_expression_generator_spec.rb
96
96
  - spec/cucumber/cucumber_expressions/cucumber_expression_regexp_spec.rb
97
97
  - spec/cucumber/cucumber_expressions/cucumber_expression_spec.rb
98
- - spec/cucumber/cucumber_expressions/custom_parameter_spec.rb
98
+ - spec/cucumber/cucumber_expressions/custom_parameter_type_spec.rb
99
99
  - spec/cucumber/cucumber_expressions/expression_examples_spec.rb
100
100
  - spec/cucumber/cucumber_expressions/regular_expression_spec.rb
101
101
  homepage: https://github.com/cucumber/cucumber-expressions-ruby#readme
@@ -122,13 +122,13 @@ rubyforge_project:
122
122
  rubygems_version: 2.5.2
123
123
  signing_key:
124
124
  specification_version: 4
125
- summary: cucumber-expressions-2.0.1
125
+ summary: cucumber-expressions-3.0.0
126
126
  test_files:
127
127
  - spec/capture_warnings.rb
128
128
  - spec/coverage.rb
129
129
  - spec/cucumber/cucumber_expressions/cucumber_expression_generator_spec.rb
130
130
  - spec/cucumber/cucumber_expressions/cucumber_expression_regexp_spec.rb
131
131
  - spec/cucumber/cucumber_expressions/cucumber_expression_spec.rb
132
- - spec/cucumber/cucumber_expressions/custom_parameter_spec.rb
132
+ - spec/cucumber/cucumber_expressions/custom_parameter_type_spec.rb
133
133
  - spec/cucumber/cucumber_expressions/expression_examples_spec.rb
134
134
  - spec/cucumber/cucumber_expressions/regular_expression_spec.rb
@@ -1,29 +0,0 @@
1
- module Cucumber
2
- module CucumberExpressions
3
- class Parameter
4
- attr_reader :type_name, :type, :capture_group_regexps
5
-
6
- # Create a new Parameter
7
- #
8
- # @param type_name [Array] array of class or type name to use in {arg:type_name}
9
- # @param capture_group_regexps [Array] list of regexps for capture groups.
10
- # @param transformer lambda that transforms a String to (possibly) another type
11
- #
12
- def initialize(type_name, type, capture_group_regexps, transformer)
13
- @type_name, @type, @transformer = type_name, type, transformer
14
- @capture_group_regexps = string_array(capture_group_regexps)
15
- end
16
-
17
- def transform(value)
18
- @transformer.call(value)
19
- end
20
-
21
- private
22
-
23
- def string_array(capture_group_regexps)
24
- array = capture_group_regexps.is_a?(Array) ? capture_group_regexps : [capture_group_regexps]
25
- array.map { |r| r.is_a?(String) ? r : r.source }
26
- end
27
- end
28
- end
29
- end
@@ -1,64 +0,0 @@
1
- require 'cucumber/cucumber_expressions/parameter'
2
-
3
- module Cucumber
4
- module CucumberExpressions
5
- class ParameterRegistry
6
- INTEGER_REGEXPS = [/-?\d+/, /\d+/]
7
- FLOAT_REGEXPS = [/-?\d*\.?\d+/]
8
-
9
- def initialize
10
- @parameters_by_type_name = {}
11
- @parameters_by_capture_group_regexp = {}
12
- @parameters_by_class = {}
13
-
14
- add_parameter(Parameter.new('int', Integer, INTEGER_REGEXPS, lambda {|s| s.to_i}))
15
- add_parameter(Parameter.new('float', Float, FLOAT_REGEXPS, lambda {|s| s.to_f}))
16
- end
17
-
18
- def lookup_by_type(type)
19
- if type.is_a?(Class)
20
- lookup_by_class(type)
21
- elsif type.is_a?(String)
22
- lookup_by_type_name(type)
23
- else
24
- raise Exception.new("Type must be string or class, but was #{type} of type #{type.class}")
25
- end
26
- end
27
-
28
- def lookup_by_class(clazz)
29
- parameter = @parameters_by_class[clazz]
30
- if parameter.nil?
31
- create_anonymous_lookup(lambda {|s| clazz.new(s)})
32
- else
33
- parameter
34
- end
35
- end
36
-
37
- def lookup_by_type_name(type_name)
38
- @parameters_by_type_name[type_name]
39
- end
40
-
41
- def lookup_by_capture_group_regexp(capture_group_regexp)
42
- @parameters_by_capture_group_regexp[capture_group_regexp]
43
- end
44
-
45
- def create_anonymous_lookup(proc)
46
- Parameter.new(nil, nil, ['.+'], proc)
47
- end
48
-
49
- def add_parameter(parameter)
50
- @parameters_by_type_name[parameter.type_name] = parameter
51
- @parameters_by_class[parameter.type] = parameter
52
-
53
- parameter.capture_group_regexps.each do |capture_group_regexp|
54
- @parameters_by_capture_group_regexp[capture_group_regexp] = parameter
55
- end
56
- end
57
-
58
- def parameters
59
- @parameters_by_type_name.values
60
- end
61
-
62
- end
63
- end
64
- end
@@ -1,100 +0,0 @@
1
- require 'cucumber/cucumber_expressions/cucumber_expression'
2
- require 'cucumber/cucumber_expressions/regular_expression'
3
- require 'cucumber/cucumber_expressions/parameter_registry'
4
-
5
- module Cucumber
6
- module CucumberExpressions
7
- class Color
8
- attr_reader :name
9
-
10
- ### [color-constructor]
11
- def initialize(name)
12
- @name = name
13
- end
14
- ### [color-constructor]
15
-
16
- def ==(other)
17
- other.is_a?(Color) && other.name == name
18
- end
19
- end
20
-
21
- describe "Custom parameter" do
22
- before do
23
- ### [add-color-parameter]
24
- parameter_registry = ParameterRegistry.new
25
- parameter_registry.add_parameter(Parameter.new(
26
- 'color',
27
- Color,
28
- [/red|blue|yellow/, /(?:dark|light) (?:red|blue|yellow)/],
29
- lambda { |s| Color.new(s) }
30
- ))
31
- ### [add-color-parameter]
32
- @parameter_registry = parameter_registry
33
- end
34
-
35
- describe CucumberExpression do
36
- it "matches typed parameters" do
37
- expression = CucumberExpression.new("I have a {color} ball", [], @parameter_registry)
38
- transformed_argument_value = expression.match("I have a red ball")[0].transformed_value
39
- expect( transformed_argument_value ).to eq(Color.new('red'))
40
- end
41
-
42
- it "matches typed parameters with optional group" do
43
- expression = CucumberExpression.new("I have a {color} ball", [], @parameter_registry)
44
- transformed_argument_value = expression.match("I have a dark red ball")[0].transformed_value
45
- expect( transformed_argument_value ).to eq(Color.new('dark red'))
46
- end
47
-
48
- it "matches untyped parameters with explicit type" do
49
- expression = CucumberExpression.new("I have a {color} ball", [Color], @parameter_registry)
50
- transformed_argument_value = expression.match("I have a red ball")[0].transformed_value
51
- expect( transformed_argument_value ).to eq(Color.new('red'))
52
- end
53
-
54
- it "matches untyped parameters with same name as type" do
55
- expression = CucumberExpression.new("I have a {color} ball", [], @parameter_registry)
56
- transformed_argument_value = expression.match("I have a red ball")[0].transformed_value
57
- expect( transformed_argument_value ).to eq(Color.new('red'))
58
- end
59
-
60
- it "matches parameters with explicit type that isn't registered" do
61
- expression = CucumberExpression.new("I have a {color} ball", [Color], ParameterRegistry.new)
62
- transformed_argument_value = expression.match("I have a red ball")[0].transformed_value
63
- expect( transformed_argument_value ).to eq(Color.new('red'))
64
- end
65
-
66
- it("defers transformation until queried from argument") do
67
- @parameter_registry.add_parameter(Parameter.new(
68
- 'throwing',
69
- String,
70
- /bad/,
71
- lambda { |s| raise "Can't transform [#{s}]" }
72
- ))
73
- expression = CucumberExpression.new("I have a {throwing} parameter", [], @parameter_registry)
74
- args = expression.match("I have a bad parameter")
75
- expect { args[0].transformed_value }.to raise_error("Can't transform [bad]")
76
- end
77
- end
78
-
79
- describe RegularExpression do
80
- it "matches parameters with explicit constructor" do
81
- expression = RegularExpression.new(/I have a (red|blue|yellow) ball/, [Color], @parameter_registry)
82
- transformed_argument_value = expression.match("I have a red ball")[0].transformed_value
83
- expect( transformed_argument_value ).to eq(Color.new('red'))
84
- end
85
-
86
- it "matches parameters without explicit constructor" do
87
- expression = RegularExpression.new(/I have a (red|blue|yellow) ball/, [], @parameter_registry)
88
- transformed_argument_value = expression.match("I have a red ball")[0].transformed_value
89
- expect( transformed_argument_value ).to eq(Color.new('red'))
90
- end
91
-
92
- it "matches parameters with explicit type that isn't registered" do
93
- expression = RegularExpression.new(/I have a (red|blue|yellow) ball/, [Color], ParameterRegistry.new)
94
- transformed_argument_value = expression.match("I have a red ball")[0].transformed_value
95
- expect( transformed_argument_value ).to eq(Color.new('red'))
96
- end
97
- end
98
- end
99
- end
100
- end