cucumber-expressions 5.0.13 → 5.0.14

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: e37bfd25d2fa6ce81bb76f2a0e4b155b23d7c243
4
- data.tar.gz: a843eb27ff496f5744bb8fc9b7ff2993640a029a
3
+ metadata.gz: f0bf6d072730fe70e07cee26eb6ad35ea6da0395
4
+ data.tar.gz: 81fe11dab1fe72475a6d59902c42c83b9c9cf3c5
5
5
  SHA512:
6
- metadata.gz: 7a9c2d12d144a509ff625e72c67cf1b1e2504a2ecab38086f85aa019150e59437ee06807efb5d65c398f7314c52f1677cb7429d75ff442316c043c0d0987d4f3
7
- data.tar.gz: 8a9e6c44e79d1c713ff2dac7b6b5a2327001615df1ae4e8a356dcc682b7ac71a06629a9f0f5ac5f8d6f053380c5223657eb60ae007a3c0668bdc2a08f30996e4
6
+ metadata.gz: 48d4cee7861530cd5643c7737c7ee0aa1ac18c5c573b47eaa6a1ecce1efce1dd3f2d4eed4303d1347e9522f65557f322295dd4c7dd17f28b1c4825ce0e1ebbe3
7
+ data.tar.gz: 32c6108014efbf5ae47e260580bd919057d08f04c00c90866408d957c6c0525968c2bfb9c9b6a8d833869c0c27775b5eb7cb28faf054e357e348803dd09d4031
data/.travis.yml CHANGED
@@ -3,10 +3,12 @@
3
3
  #
4
4
  # source scripts/functions.sh && rsync_files
5
5
  #
6
+ sudo: false
6
7
  language: ruby
7
8
 
8
9
  rvm:
9
- - 2.4.2
10
- - 2.3.5
11
- - 2.2.8
12
- - jruby-9.1.13.0
10
+ - "2.5.0"
11
+ - "2.4.3"
12
+ - "2.3.6"
13
+ - "2.2.9"
14
+ - "jruby-9.1.13.0"
@@ -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 = '5.0.13'
4
+ s.version = '5.0.14'
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}"
@@ -7,46 +7,24 @@ module Cucumber
7
7
  class CucumberExpression
8
8
  # Does not include (){} characters because they have special meaning
9
9
  ESCAPE_REGEXP = /([\\^\[$.|?*+\]])/
10
- PARAMETER_REGEXP = /{([^}]+)}/
11
- OPTIONAL_REGEXP = /\(([^)]+)\)/
10
+ PARAMETER_REGEXP = /(\\\\)?{([^}]+)}/
11
+ OPTIONAL_REGEXP = /(\\\\)?\(([^)]+)\)/
12
12
  ALTERNATIVE_NON_WHITESPACE_TEXT_REGEXP = /([^\s^\/]+)((\/[^\s^\/]+)+)/
13
+ DOUBLE_ESCAPE = '\\\\'
13
14
 
14
15
  attr_reader :source
15
16
 
16
17
  def initialize(expression, parameter_type_registry)
17
18
  @source = expression
18
19
  @parameter_types = []
19
- regexp = '^'
20
- match_offset = 0
20
+
21
+ expression = process_escapes(expression)
22
+ expression = process_optional(expression)
23
+ expression = process_alternation(expression)
24
+ expression = process_parameters(expression, parameter_type_registry)
25
+ expression = "^#{expression}$"
21
26
 
22
- expression = expression.gsub(ESCAPE_REGEXP, '\\\\\1')
23
-
24
- # Create non-capturing, optional capture groups from parenthesis
25
- expression = expression.gsub(OPTIONAL_REGEXP, '(?:\1)?')
26
-
27
- expression = expression.gsub(ALTERNATIVE_NON_WHITESPACE_TEXT_REGEXP) do |_|
28
- "(?:#{$1}#{$2.tr('/', '|')})"
29
- end
30
-
31
- loop do
32
- match = PARAMETER_REGEXP.match(expression, match_offset)
33
- break if match.nil?
34
-
35
- type_name = match[1]
36
-
37
- parameter_type = parameter_type_registry.lookup_by_type_name(type_name)
38
- raise UndefinedParameterTypeError.new(type_name) if parameter_type.nil?
39
- @parameter_types.push(parameter_type)
40
-
41
- text = expression.slice(match_offset...match.offset(0)[0])
42
- capture_regexp = build_capture_regexp(parameter_type.regexps)
43
- match_offset = match.offset(0)[1]
44
- regexp += text
45
- regexp += capture_regexp
46
- end
47
- regexp += expression.slice(match_offset..-1)
48
- regexp += '$'
49
- @tree_regexp = TreeRegexp.new(regexp)
27
+ @tree_regexp = TreeRegexp.new(expression)
50
28
  end
51
29
 
52
30
  def match(text)
@@ -63,6 +41,40 @@ module Cucumber
63
41
 
64
42
  private
65
43
 
44
+ def process_escapes(expression)
45
+ expression.gsub(ESCAPE_REGEXP, '\\\\\1')
46
+ end
47
+
48
+ def process_optional(expression)
49
+ # Create non-capturing, optional capture groups from parenthesis
50
+ expression.gsub(OPTIONAL_REGEXP) do
51
+ # look for double-escaped parentheses
52
+ $1 == DOUBLE_ESCAPE ? "\\(#{$2}\\)" : "(?:#{$2})?"
53
+ end
54
+ end
55
+
56
+ def process_alternation(expression)
57
+ expression.gsub(ALTERNATIVE_NON_WHITESPACE_TEXT_REGEXP) do
58
+ "(?:#{$1}#{$2.tr('/', '|')})"
59
+ end
60
+ end
61
+
62
+ def process_parameters(expression, parameter_type_registry)
63
+ # Create non-capturing, optional capture groups from parenthesis
64
+ expression.gsub(PARAMETER_REGEXP) do
65
+ if ($1 == DOUBLE_ESCAPE)
66
+ "\\{#{$2}\\}"
67
+ else
68
+ type_name = $2
69
+ parameter_type = parameter_type_registry.lookup_by_type_name(type_name)
70
+ raise UndefinedParameterTypeError.new(type_name) if parameter_type.nil?
71
+ @parameter_types.push(parameter_type)
72
+
73
+ build_capture_regexp(parameter_type.regexps)
74
+ end
75
+ end
76
+ end
77
+
66
78
  def build_capture_regexp(regexps)
67
79
  return "(#{regexps[0]})" if regexps.size == 1
68
80
  capture_groups = regexps.map { |group| "(?:#{group})" }
@@ -51,7 +51,7 @@ module Cucumber
51
51
 
52
52
  parameter_type_combinations.push(parameter_types)
53
53
 
54
- expression_template += escape_for_sprintf(text.slice(pos...best_parameter_type_matcher.start))
54
+ expression_template += escape(text.slice(pos...best_parameter_type_matcher.start))
55
55
  expression_template += "{%s}"
56
56
 
57
57
  pos = best_parameter_type_matcher.start + best_parameter_type_matcher.group.length
@@ -64,7 +64,7 @@ module Cucumber
64
64
  end
65
65
  end
66
66
 
67
- expression_template += escape_for_sprintf(text.slice(pos..-1))
67
+ expression_template += escape(text.slice(pos..-1))
68
68
 
69
69
  CombinatorialGeneratedExpressionFactory.new(
70
70
  expression_template,
@@ -94,8 +94,10 @@ module Cucumber
94
94
  result
95
95
  end
96
96
 
97
- def escape_for_sprintf(s)
97
+ def escape(s)
98
98
  s.gsub(/%/, '%%')
99
+ .gsub(/\(/, '\\(')
100
+ .gsub(/\{/, '\\{')
99
101
  end
100
102
  end
101
103
  end
@@ -1,4 +1,5 @@
1
1
  require 'cucumber/cucumber_expressions/group_builder'
2
+ require 'cucumber/cucumber_expressions/errors'
2
3
 
3
4
  module Cucumber
4
5
  module CucumberExpressions
@@ -33,6 +34,8 @@ module Cucumber
33
34
  elsif c == ':' && non_capturing_maybe
34
35
  stack.last.set_non_capturing!
35
36
  non_capturing_maybe = false
37
+ elsif c == '<' && non_capturing_maybe
38
+ raise CucumberExpressionError.new("Named capture groups are not supported. See https://github.com/cucumber/cucumber/issues/329")
36
39
  end
37
40
 
38
41
  escaping = c == '\\' && !escaping
@@ -1,4 +1,5 @@
1
1
  require 'cucumber/cucumber_expressions/cucumber_expression_generator'
2
+ require 'cucumber/cucumber_expressions/cucumber_expression'
2
3
  require 'cucumber/cucumber_expressions/parameter_type'
3
4
  require 'cucumber/cucumber_expressions/parameter_type_registry'
4
5
 
@@ -28,6 +29,18 @@ module Cucumber
28
29
  assert_expression("hello", [], "hello")
29
30
  end
30
31
 
32
+ it "generates expression with escaped left parenthesis" do
33
+ assert_expression(
34
+ "\\(iii)", [],
35
+ "(iii)")
36
+ end
37
+
38
+ it "generates expression with escaped left curly brace" do
39
+ assert_expression(
40
+ "\\{iii}", [],
41
+ "{iii}")
42
+ end
43
+
31
44
  it "generates expression for int float arg" do
32
45
  assert_expression(
33
46
  "I have {int} cukes and {float} euro", ["int", "float"],
@@ -105,6 +118,10 @@ module Cucumber
105
118
  generated_expression = @generator.generate_expression(text)
106
119
  expect(generated_expression.parameter_names).to eq(expected_argument_names)
107
120
  expect(generated_expression.source).to eq(expected_expression)
121
+
122
+ cucumber_expression = CucumberExpression.new(generated_expression.source, @parameter_type_registry)
123
+ match = cucumber_expression.match(text)
124
+ expect(match.length).to eq(expected_argument_names.length)
108
125
  end
109
126
  end
110
127
  end
@@ -26,7 +26,7 @@ module Cucumber
26
26
  it('matches multiple double quoted strings') do
27
27
  expect(match('three {string} and {string} mice', 'three "blind" and "crippled" mice')).to eq(['blind', 'crippled'])
28
28
  end
29
-
29
+
30
30
  it('matches single quoted string') do
31
31
  expect(match('three {string} mice', "three 'blind' mice")).to eq(['blind'])
32
32
  end
@@ -55,6 +55,10 @@ module Cucumber
55
55
  expect(match('three {string} mice', "three 'bl\\'nd' mice")).to eq(["bl'nd"])
56
56
  end
57
57
 
58
+ it 'matches escaped parentheses' do
59
+ expect(match('three \\(exceptionally) {string} mice', 'three (exceptionally) "blind" mice')).to eq(['blind'])
60
+ end
61
+
58
62
  it "matches int" do
59
63
  expect(match("{int}", "22")).to eq([22])
60
64
  end
@@ -84,6 +84,13 @@ module Cucumber
84
84
  group = tr.match("hello")
85
85
  expect(group.value).to eq("hello")
86
86
  end
87
+
88
+ it 'throws an error when there are named capture groups because they are buggy in Ruby' do
89
+ # https://github.com/cucumber/cucumber/issues/329
90
+ expect {
91
+ TreeRegexp.new(/^I am a person( named "(?<first_name>.+) (?<last_name>.+)")?$/)
92
+ }.to raise_error(/Named capture groups are not supported/)
93
+ end
87
94
  end
88
95
  end
89
96
  end
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: 5.0.13
4
+ version: 5.0.14
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: 2018-01-21 00:00:00.000000000 Z
11
+ date: 2018-04-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -131,7 +131,7 @@ rubyforge_project:
131
131
  rubygems_version: 2.6.8
132
132
  signing_key:
133
133
  specification_version: 4
134
- summary: cucumber-expressions-5.0.13
134
+ summary: cucumber-expressions-5.0.14
135
135
  test_files:
136
136
  - spec/capture_warnings.rb
137
137
  - spec/coverage.rb