cucumber-core 4.0.0 → 5.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,40 @@
1
+ require 'cucumber/core/event'
2
+
3
+ module Cucumber
4
+ module Core
5
+ describe Event do
6
+
7
+ describe ".new" do
8
+ it "generates new types of events" do
9
+ my_event_type = Event.new
10
+ my_event = my_event_type.new
11
+ expect(my_event).to be_kind_of(Core::Event)
12
+ end
13
+
14
+ it "generates events with attributes" do
15
+ my_event_type = Event.new(:foo, :bar)
16
+ my_event = my_event_type.new(1,2)
17
+ expect(my_event.attributes).to eq [1, 2]
18
+ expect(my_event.foo).to eq 1
19
+ expect(my_event.bar).to eq 2
20
+ end
21
+ end
22
+
23
+ describe "a generated event" do
24
+ class MyEventType < Event.new(:foo, :bar)
25
+ end
26
+
27
+ it "can be converted to a hash" do
28
+ my_event = MyEventType.new(1,2)
29
+ expect(my_event.to_h).to eq foo: 1, bar: 2
30
+ end
31
+
32
+ it "has an event_id" do
33
+ expect(MyEventType.event_id).to eq :my_event_type
34
+ expect(MyEventType.new(1,2).event_id).to eq :my_event_type
35
+ end
36
+ end
37
+ end
38
+
39
+ end
40
+ end
@@ -0,0 +1,101 @@
1
+ # frozen_string_literal: true
2
+ require 'cucumber/core/gherkin/writer'
3
+ require 'cucumber/core'
4
+ require 'cucumber/core/filter'
5
+
6
+ module Cucumber::Core
7
+ describe Filter do
8
+ include Cucumber::Core::Gherkin::Writer
9
+ include Cucumber::Core
10
+
11
+ describe ".new" do
12
+ let(:receiver) { double.as_null_object }
13
+
14
+ let(:doc) {
15
+ gherkin do
16
+ feature do
17
+ scenario 'x' do
18
+ step 'a step'
19
+ end
20
+
21
+ scenario 'y' do
22
+ step 'a step'
23
+ end
24
+ end
25
+ end
26
+ }
27
+
28
+ it "creates a filter class that can pass-through by default" do
29
+ my_filter_class = Filter.new
30
+ my_filter = my_filter_class.new
31
+ expect(receiver).to receive(:test_case) { |test_case|
32
+ expect(test_case.test_steps.length).to eq 1
33
+ expect(test_case.test_steps.first.text).to eq 'a step'
34
+ }.exactly(2).times
35
+ compile [doc], receiver, [my_filter]
36
+ end
37
+
38
+ context "customizing by subclassing" do
39
+
40
+ # Each filter imlicitly gets a :receiver attribute
41
+ # that you need to call with the new test case
42
+ # once you've received yours and modified it.
43
+ class BasicBlankingFilter < Filter.new
44
+ def test_case(test_case)
45
+ test_case.with_steps([]).describe_to(receiver)
46
+ end
47
+ end
48
+
49
+ # You can pass the names of attributes when building a
50
+ # filter, allowing you to have custom attributes.
51
+ class NamedBlankingFilter < Filter.new(:name_pattern)
52
+ def test_case(test_case)
53
+ if test_case.name =~ name_pattern
54
+ test_case.with_steps([]).describe_to(receiver)
55
+ else
56
+ test_case.describe_to(receiver) # or just call `super`
57
+ end
58
+ self
59
+ end
60
+ end
61
+
62
+ it "can override methods from the base class" do
63
+ expect(receiver).to receive(:test_case) { |test_case|
64
+ expect(test_case.test_steps.length).to eq 0
65
+ }.exactly(2).times
66
+ run BasicBlankingFilter.new
67
+ end
68
+
69
+ it "can take arguments" do
70
+ expect(receiver).to receive(:test_case) { |test_case|
71
+ expect(test_case.test_steps.length).to eq 0
72
+ }.once.ordered
73
+ expect(receiver).to receive(:test_case) { |test_case|
74
+ expect(test_case.test_steps.length).to eq 1
75
+ }.once.ordered
76
+ run NamedBlankingFilter.new(/x/)
77
+ end
78
+
79
+ end
80
+
81
+ context "customizing by using a block" do
82
+ BlockBlankingFilter = Filter.new do
83
+ def test_case(test_case)
84
+ test_case.with_steps([]).describe_to(receiver)
85
+ end
86
+ end
87
+
88
+ it "allows methods to be overridden" do
89
+ expect(receiver).to receive(:test_case) { |test_case|
90
+ expect(test_case.test_steps.length).to eq 0
91
+ }.exactly(2).times
92
+ run BlockBlankingFilter.new
93
+ end
94
+ end
95
+
96
+ def run(filter)
97
+ compile [doc], receiver, [filter]
98
+ end
99
+ end
100
+ end
101
+ end
@@ -0,0 +1,95 @@
1
+ # -*- encoding: utf-8 -*-
2
+ # frozen_string_literal: true
3
+ require 'cucumber/core/gherkin/parser'
4
+ require 'cucumber/core/gherkin/writer'
5
+
6
+ module Cucumber
7
+ module Core
8
+ module Gherkin
9
+ describe Parser do
10
+ let(:receiver) { double }
11
+ let(:event_bus) { double }
12
+ let(:parser) { Parser.new(receiver, event_bus) }
13
+ let(:visitor) { double }
14
+
15
+ before do
16
+ allow( event_bus ).to receive(:gherkin_source_parsed)
17
+ end
18
+
19
+ def parse
20
+ parser.document(source)
21
+ end
22
+
23
+ context "for invalid gherkin" do
24
+ let(:source) { Gherkin::Document.new(path, "\nnot gherkin\n\nFeature: \n") }
25
+ let(:path) { 'path_to/the.feature' }
26
+
27
+ it "raises an error" do
28
+ expect { parse }.to raise_error(ParseError) do |error|
29
+ expect( error.message ).to match(/not gherkin/)
30
+ expect( error.message ).to match(/#{path}/)
31
+ end
32
+ end
33
+ end
34
+
35
+ context "for valid gherkin" do
36
+ let(:source) { Gherkin::Document.new(path, 'Feature:') }
37
+ let(:path) { 'path_to/the.feature' }
38
+
39
+ it "issues a gherkin_source_parsed event" do
40
+ expect( event_bus ).to receive(:gherkin_source_parsed)
41
+ parse
42
+ end
43
+ end
44
+
45
+ context "for empty files" do
46
+ let(:source) { Gherkin::Document.new(path, '') }
47
+ let(:path) { 'path_to/the.feature' }
48
+
49
+ it "passes on no pickles" do
50
+ expect( receiver ).not_to receive(:pickle)
51
+ parse
52
+ end
53
+ end
54
+
55
+ include Writer
56
+ def self.source(&block)
57
+ let(:source) { gherkin(&block) }
58
+ end
59
+
60
+ RSpec::Matchers.define :pickle_with_language do |language|
61
+ match { |actual| actual.language == language }
62
+ end
63
+
64
+ context "when the Gherkin has a language header" do
65
+ source do
66
+ feature(language: 'ja', keyword: '機能') do
67
+ scenario(keyword: 'シナリオ')
68
+ end
69
+ end
70
+
71
+ it "the pickles have the correct language" do
72
+ expect( receiver ).to receive(:pickle).with(pickle_with_language('ja'))
73
+ parse
74
+ end
75
+ end
76
+
77
+ context "when the Gherkin produces one pickle" do
78
+ source do
79
+ feature do
80
+ scenario do
81
+ step 'text'
82
+ end
83
+ end
84
+ end
85
+
86
+ it "passes on the pickle" do
87
+ expect( receiver ).to receive(:pickle)
88
+ parse
89
+ end
90
+ end
91
+
92
+ end
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,333 @@
1
+ # frozen_string_literal: true
2
+ require 'cucumber/core/gherkin/writer'
3
+ require 'unindent'
4
+
5
+ module Cucumber::Core::Gherkin
6
+ describe Writer do
7
+ include Writer
8
+
9
+ context 'specifying uri' do
10
+ it 'generates a uri by default' do
11
+ source = gherkin { feature }
12
+ expect( source.uri ).to eq 'features/test.feature'
13
+ end
14
+
15
+ it 'allows you to specify a URI' do
16
+ source = gherkin('features/path/to/my.feature') { feature }
17
+ expect( source.uri ).to eq 'features/path/to/my.feature'
18
+ end
19
+ end
20
+
21
+ context 'a feature' do
22
+
23
+ it 'generates the feature statement' do
24
+ source = gherkin { feature }
25
+ expect( source ).to eq "Feature:\n"
26
+ end
27
+
28
+ context 'when a name is provided' do
29
+ it 'includes the name in the feature statement' do
30
+ source = gherkin do
31
+ feature "A Feature\n"
32
+ end
33
+ expect( source ).to eq "Feature: A Feature\n"
34
+ end
35
+ end
36
+
37
+ context 'when a description is provided' do
38
+ it 'includes the description in the feature statement' do
39
+ source = gherkin do
40
+ feature "A Feature", description: <<-END
41
+ This is the description
42
+ which can span
43
+ multiple lines.
44
+ END
45
+ end
46
+ expected = <<-END
47
+ Feature: A Feature
48
+ This is the description
49
+ which can span
50
+ multiple lines.
51
+ END
52
+
53
+ expect( source ).to eq expected.unindent
54
+ end
55
+ end
56
+
57
+ context 'when a keyword is provided' do
58
+ it 'uses the supplied keyword' do
59
+ source = gherkin do
60
+ feature "A Feature", keyword: "Business Need"
61
+ end
62
+ expect( source ).to eq "Business Need: A Feature\n"
63
+ end
64
+ end
65
+
66
+ context 'when a language is supplied' do
67
+ it 'inserts a language statement' do
68
+ source = gherkin do
69
+ feature language: 'ru'
70
+ end
71
+
72
+ expect( source ).to eq "# language: ru\nFeature:\n"
73
+ end
74
+ end
75
+
76
+ context 'when a comment is supplied' do
77
+ it 'inserts a comment' do
78
+ source = gherkin do
79
+ comment 'wow'
80
+ comment 'great'
81
+ feature
82
+ end
83
+
84
+ expect( source.to_s ).to eq "# wow\n# great\nFeature:\n"
85
+ end
86
+ end
87
+
88
+ context 'with a scenario' do
89
+ it 'includes the scenario statement' do
90
+ source = gherkin do
91
+ feature "A Feature" do
92
+ scenario
93
+ end
94
+ end
95
+
96
+ expect( source.to_s ).to match(/Scenario:/)
97
+ end
98
+
99
+ context 'when a comment is provided' do
100
+ it 'includes the comment in the scenario statement' do
101
+ source = gherkin do
102
+ feature do
103
+ comment 'wow'
104
+ scenario
105
+ end
106
+ end
107
+ expect( source.to_s ).to eq <<-END.unindent
108
+ Feature:
109
+
110
+ # wow
111
+ Scenario:
112
+ END
113
+ end
114
+ end
115
+
116
+ context 'when a description is provided' do
117
+ it 'includes the description in the scenario statement' do
118
+ source = gherkin do
119
+ feature do
120
+ scenario description: <<-END
121
+ This is the description
122
+ which can span
123
+ multiple lines.
124
+ END
125
+ end
126
+ end
127
+
128
+ expect( source ).to eq <<-END.unindent
129
+ Feature:
130
+
131
+ Scenario:
132
+ This is the description
133
+ which can span
134
+ multiple lines.
135
+ END
136
+ end
137
+ end
138
+
139
+ context 'with a step' do
140
+ it 'includes the step statement' do
141
+ source = gherkin do
142
+ feature "A Feature" do
143
+ scenario do
144
+ step 'passing'
145
+ end
146
+ end
147
+ end
148
+
149
+ expect( source.to_s ).to match(/Given passing\Z/m)
150
+ end
151
+
152
+ context 'when a docstring is provided' do
153
+ it 'includes the content type when provided' do
154
+ source = gherkin do
155
+ feature do
156
+ scenario do
157
+ step 'failing' do
158
+ doc_string 'some text', 'text/plain'
159
+ end
160
+ end
161
+ end
162
+
163
+ end
164
+
165
+ expect( source ).to eq <<-END.unindent
166
+ Feature:
167
+
168
+ Scenario:
169
+ Given failing
170
+ """text/plain
171
+ some text
172
+ """
173
+ END
174
+ end
175
+ end
176
+ end
177
+ end
178
+
179
+ context 'with a background' do
180
+ it 'can have a description' do
181
+ source = gherkin do
182
+ feature do
183
+ background description: "One line,\nand two.."
184
+ end
185
+ end
186
+
187
+ expect( source ).to eq <<-END.unindent
188
+ Feature:
189
+
190
+ Background:
191
+ One line,
192
+ and two..
193
+ END
194
+ end
195
+ end
196
+
197
+ context 'with a scenario outline' do
198
+ it 'can have a description' do
199
+ source = gherkin do
200
+ feature do
201
+ scenario_outline description: "Doesn't need to be multi-line."
202
+ end
203
+ end
204
+
205
+ expect( source ).to eq <<-END.unindent
206
+ Feature:
207
+
208
+ Scenario Outline:
209
+ Doesn't need to be multi-line.
210
+ END
211
+ end
212
+
213
+ context 'and examples table' do
214
+ it 'can have a description' do
215
+ source = gherkin do
216
+ feature do
217
+ scenario_outline do
218
+ examples description: "Doesn't need to be multi-line." do
219
+
220
+ end
221
+ end
222
+ end
223
+ end
224
+
225
+ expect( source ).to eq <<-END.unindent
226
+ Feature:
227
+
228
+ Scenario Outline:
229
+
230
+ Examples:
231
+ Doesn't need to be multi-line.
232
+ END
233
+ end
234
+ end
235
+ end
236
+ end
237
+
238
+ it 'generates a complex feature' do
239
+ source = gherkin do
240
+ comment 'wow'
241
+ feature 'Fully featured', language: 'en', tags: '@always' do
242
+ comment 'cool'
243
+ background do
244
+ step 'passing'
245
+ end
246
+
247
+ scenario do
248
+ step 'passing'
249
+ end
250
+
251
+ comment 'here'
252
+ scenario 'with doc string', tags: '@first @second' do
253
+ comment 'and here'
254
+ step 'passing'
255
+ step 'failing', keyword: 'When' do
256
+ doc_string <<-END
257
+ I wish I was a little bit taller.
258
+ I wish I was a baller.
259
+ END
260
+ end
261
+ end
262
+
263
+ scenario 'with a table...' do
264
+ step 'passes:' do
265
+ table do
266
+ row 'name', 'age', 'location'
267
+ row 'Janine', '43', 'Antarctica'
268
+ end
269
+ end
270
+ end
271
+
272
+ comment 'yay'
273
+ scenario_outline 'eating' do
274
+ step 'there are <start> cucumbers'
275
+ step 'I eat <eat> cucumbers', keyword: 'When'
276
+ step 'I should have <left> cucumbers', keyword: 'Then'
277
+
278
+ comment 'hmmm'
279
+ examples do
280
+ row 'start', 'eat', 'left'
281
+ row '12', '5', '7'
282
+ row '20', '5', '15'
283
+ end
284
+ end
285
+ end
286
+ end
287
+
288
+ expect( source.to_s ).to eq <<-END.unindent
289
+ # language: en
290
+ # wow
291
+ @always
292
+ Feature: Fully featured
293
+
294
+ # cool
295
+ Background:
296
+ Given passing
297
+
298
+ Scenario:
299
+ Given passing
300
+
301
+ # here
302
+ @first @second
303
+ Scenario: with doc string
304
+ # and here
305
+ Given passing
306
+ When failing
307
+ """
308
+ I wish I was a little bit taller.
309
+ I wish I was a baller.
310
+ """
311
+
312
+ Scenario: with a table...
313
+ Given passes:
314
+ | name | age | location |
315
+ | Janine | 43 | Antarctica |
316
+
317
+ # yay
318
+ Scenario Outline: eating
319
+ Given there are <start> cucumbers
320
+ When I eat <eat> cucumbers
321
+ Then I should have <left> cucumbers
322
+
323
+ # hmmm
324
+ Examples:
325
+ | start | eat | left |
326
+ | 12 | 5 | 7 |
327
+ | 20 | 5 | 15 |
328
+ END
329
+
330
+ end
331
+ end
332
+ end
333
+