File: cucumber_expression_spec.rb

package info (click to toggle)
ruby-cucumber-expressions 8.0.0-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, bullseye, forky, sid, trixie
  • size: 248 kB
  • sloc: ruby: 1,594; sh: 15; makefile: 4
file content (196 lines) | stat: -rw-r--r-- 7,181 bytes parent folder | download
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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
require 'cucumber/cucumber_expressions/cucumber_expression'
require 'cucumber/cucumber_expressions/parameter_type_registry'

module Cucumber
  module CucumberExpressions
    describe CucumberExpression do
      it "documents match arguments" do
        parameter_registry = ParameterTypeRegistry.new

        ### [capture-match-arguments]
        expr = "I have {int} cuke(s)"
        expression = CucumberExpression.new(expr, parameter_registry)
        args = expression.match("I have 7 cukes")
        expect(args[0].value(nil)).to eq(7)
        ### [capture-match-arguments]
      end

      it "matches word" do
        expect(match("three {word} mice", "three blind mice")).to eq(['blind'])
      end

      it('matches double quoted string') do
        expect(match('three {string} mice', 'three "blind" mice')).to eq(['blind'])
      end

      it('matches multiple double quoted strings') do
        expect(match('three {string} and {string} mice', 'three "blind" and "crippled" mice')).to eq(['blind', 'crippled'])
      end

      it('matches single quoted string') do
        expect(match('three {string} mice', "three 'blind' mice")).to eq(['blind'])
      end

      it('matches multiple single quoted strings') do
        expect(match('three {string} and {string} mice', "three 'blind' and 'crippled' mice")).to eq(['blind', 'crippled'])
      end

      it('does not match misquoted string') do
        expect(match('three {string} mice', 'three "blind\' mice')).to eq(nil)
      end

      it('matches single quoted string with double quotes') do
        expect(match('three {string} mice', 'three \'"blind"\' mice')).to eq(['"blind"'])
      end

      it('matches double quoted string with single quotes') do
        expect(match('three {string} mice', 'three "\'blind\'" mice')).to eq(["'blind'"])
      end

      it('matches double quoted string with escaped double quote') do
        expect(match('three {string} mice', 'three "bl\\"nd" mice')).to eq(['bl"nd'])
      end

      it('matches single quoted string with escaped single quote') do
        expect(match('three {string} mice', "three 'bl\\'nd' mice")).to eq(["bl'nd"])
      end

      it 'matches escaped parentheses' do
        expect(match('three \\(exceptionally) {string} mice', 'three (exceptionally) "blind" mice')).to eq(['blind'])
      end

      it "matches escaped slash" do
        expect(match("12\\/2020", "12/2020")).to eq([])
      end

      it "matches int" do
        expect(match("{int}", "22")).to eq([22])
      end

      it "doesn't match float as int" do
        expect(match("{int}", "1.22")).to be_nil
      end

      it "matches int as float" do
        expect(match("{float}", "0")).to eq([0.0])
      end

      it "matches float" do
        expect(match("{float}", "")).to eq(nil)
        expect(match("{float}", ".")).to eq(nil)
        expect(match("{float}", ",")).to eq(nil)
        expect(match("{float}", "-")).to eq(nil)
        expect(match("{float}", "E")).to eq(nil)
        expect(match("{float}", "1,")).to eq(nil)
        expect(match("{float}", ",1")).to eq(nil)
        expect(match("{float}", "1.")).to eq(nil)

        expect(match("{float}", "1")).to eq([1])
        expect(match("{float}", "-1")).to eq([-1])
        expect(match("{float}", "1.1")).to eq([1.1])
        expect(match("{float}", "1,000")).to eq(nil)
        expect(match("{float}", "1,000,0")).to eq(nil)
        expect(match("{float}", "1,000.1")).to eq(nil)
        expect(match("{float}", "1,000,10")).to eq(nil)
        expect(match("{float}", "1,0.1")).to eq(nil)
        expect(match("{float}", "1,000,000.1")).to eq(nil)
        expect(match("{float}", "-1.1")).to eq([-1.1])

        expect(match("{float}", ".1")).to eq([0.1])
        expect(match("{float}", "-.1")).to eq([-0.1])
        expect(match("{float}", "-.1000001")).to eq([-0.1000001])
        expect(match("{float}", "1E1")).to eq([10.0])
        expect(match("{float}", ".1E1")).to eq([1])
        expect(match("{float}", "E1")).to eq(nil)
        expect(match("{float}", "-.1E-1")).to eq([-0.01])
        expect(match("{float}", "-.1E-2")).to eq([-0.001])
        expect(match("{float}", "-.1E+1")).to eq([-1])
        expect(match("{float}", "-.1E+2")).to eq([-10])
        expect(match("{float}", "-.1E1")).to eq([-1])
        expect(match("{float}", "-.1E2")).to eq([-10])
      end

      it "matches anonymous" do
        expect(match("{}", "0.22")).to eq(["0.22"])
      end

      '[]()$.|?*+'.split('').each do |char|
        it "does not allow parameter type with #{char}" do
          expect {match("{#{char}string}", "something")}.to raise_error("Illegal character '#{char}' in parameter name {#{char}string}")
        end
      end

      it "throws unknown parameter type" do
        expect {match("{unknown}", "something")}.to raise_error('Undefined parameter type {unknown}')
      end

      it "does not allow optional parameter types" do
        expect {match("({int})", "3")}.to raise_error('Parameter types cannot be optional: ({int})')
      end

      it "does allow escaped optional parameter types" do
        expect(match("\\({int})", "(3)")).to eq([3])
      end

      it "does not allow text/parameter type alternation" do
        expect {match("x/{int}", "3")}.to raise_error('Parameter types cannot be alternative: x/{int}')
      end

      it "does not allow parameter type/text alternation" do
        expect {match("{int}/x", "3")}.to raise_error('Parameter types cannot be alternative: {int}/x')
      end

      it "exposes source" do
        expr = "I have {int} cuke(s)"
        expect(CucumberExpression.new(expr, ParameterTypeRegistry.new).source).to eq(expr)
      end

      it "delegates transform to custom object" do
        parameter_type_registry = ParameterTypeRegistry.new
        parameter_type_registry.define_parameter_type(
          ParameterType.new(
                  'widget',
                  /\w+/,
                  Object,
                  -> (s) {
                    self.create_widget(s)
                  },
                  false,
                  true
              )
        )
        expression = CucumberExpression.new(
          'I have a {widget}',
          parameter_type_registry
        )

        class World
          def create_widget(s)
            "widget:#{s}"
          end
        end

        args = expression.match("I have a bolt")
        expect(args[0].value(World.new)).to eq('widget:bolt')
      end

      describe "escapes special characters" do
        %w(\\ [ ] ^ $ . | ? * +).each do |character|
          it "escapes #{character}" do
            expr = "I have {int} cuke(s) and #{character}"
            expression = CucumberExpression.new(expr, ParameterTypeRegistry.new)
            arg1 = expression.match("I have 800 cukes and #{character}")[0]
            expect(arg1.value(nil)).to eq(800)
          end
        end
      end

      def match(expression, text)
        cucumber_expression = CucumberExpression.new(expression, ParameterTypeRegistry.new)
        args = cucumber_expression.match(text)
        return nil if args.nil?
        args.map {|arg| arg.value(nil)}
      end
    end
  end
end