cucumber-core 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. checksums.yaml +7 -0
  2. data/.coveralls.yml +1 -0
  3. data/.rspec +1 -0
  4. data/.ruby-gemset +1 -0
  5. data/.travis.yml +16 -0
  6. data/Gemfile +2 -0
  7. data/LICENSE +20 -0
  8. data/README.md +9 -0
  9. data/Rakefile +24 -0
  10. data/cucumber-core.gemspec +32 -0
  11. data/lib/cucumber/core.rb +37 -0
  12. data/lib/cucumber/core/ast.rb +13 -0
  13. data/lib/cucumber/core/ast/background.rb +33 -0
  14. data/lib/cucumber/core/ast/comment.rb +17 -0
  15. data/lib/cucumber/core/ast/data_table.rb +326 -0
  16. data/lib/cucumber/core/ast/describes_itself.rb +16 -0
  17. data/lib/cucumber/core/ast/doc_string.rb +83 -0
  18. data/lib/cucumber/core/ast/empty_background.rb +12 -0
  19. data/lib/cucumber/core/ast/examples_table.rb +95 -0
  20. data/lib/cucumber/core/ast/feature.rb +62 -0
  21. data/lib/cucumber/core/ast/location.rb +140 -0
  22. data/lib/cucumber/core/ast/multiline_argument.rb +33 -0
  23. data/lib/cucumber/core/ast/names.rb +19 -0
  24. data/lib/cucumber/core/ast/outline_step.rb +51 -0
  25. data/lib/cucumber/core/ast/scenario.rb +43 -0
  26. data/lib/cucumber/core/ast/scenario_outline.rb +44 -0
  27. data/lib/cucumber/core/ast/step.rb +38 -0
  28. data/lib/cucumber/core/ast/tag.rb +14 -0
  29. data/lib/cucumber/core/compiler.rb +136 -0
  30. data/lib/cucumber/core/gherkin/ast_builder.rb +315 -0
  31. data/lib/cucumber/core/gherkin/document.rb +20 -0
  32. data/lib/cucumber/core/gherkin/parser.rb +45 -0
  33. data/lib/cucumber/core/gherkin/writer.rb +220 -0
  34. data/lib/cucumber/core/gherkin/writer/helpers.rb +178 -0
  35. data/lib/cucumber/core/platform.rb +30 -0
  36. data/lib/cucumber/core/test/case.rb +143 -0
  37. data/lib/cucumber/core/test/filters.rb +48 -0
  38. data/lib/cucumber/core/test/filters/tag_filter.rb +110 -0
  39. data/lib/cucumber/core/test/hook_compiler.rb +109 -0
  40. data/lib/cucumber/core/test/mapper.rb +56 -0
  41. data/lib/cucumber/core/test/mapping.rb +67 -0
  42. data/lib/cucumber/core/test/result.rb +191 -0
  43. data/lib/cucumber/core/test/runner.rb +149 -0
  44. data/lib/cucumber/core/test/step.rb +69 -0
  45. data/lib/cucumber/core/test/timer.rb +31 -0
  46. data/lib/cucumber/core/version.rb +9 -0
  47. data/lib/cucumber/initializer.rb +18 -0
  48. data/spec/capture_warnings.rb +68 -0
  49. data/spec/coverage.rb +10 -0
  50. data/spec/cucumber/core/ast/data_table_spec.rb +139 -0
  51. data/spec/cucumber/core/ast/doc_string_spec.rb +77 -0
  52. data/spec/cucumber/core/ast/examples_table_spec.rb +87 -0
  53. data/spec/cucumber/core/ast/location_spec.rb +105 -0
  54. data/spec/cucumber/core/ast/outline_step_spec.rb +77 -0
  55. data/spec/cucumber/core/ast/step_spec.rb +44 -0
  56. data/spec/cucumber/core/compiler_spec.rb +249 -0
  57. data/spec/cucumber/core/gherkin/parser_spec.rb +182 -0
  58. data/spec/cucumber/core/gherkin/writer_spec.rb +332 -0
  59. data/spec/cucumber/core/test/case_spec.rb +416 -0
  60. data/spec/cucumber/core/test/hook_compiler_spec.rb +78 -0
  61. data/spec/cucumber/core/test/mapper_spec.rb +68 -0
  62. data/spec/cucumber/core/test/mapping_spec.rb +103 -0
  63. data/spec/cucumber/core/test/result_spec.rb +178 -0
  64. data/spec/cucumber/core/test/runner_spec.rb +265 -0
  65. data/spec/cucumber/core/test/step_spec.rb +58 -0
  66. data/spec/cucumber/core/test/timer_spec.rb +13 -0
  67. data/spec/cucumber/core_spec.rb +419 -0
  68. data/spec/cucumber/initializer_spec.rb +49 -0
  69. metadata +221 -0
@@ -0,0 +1,182 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require 'cucumber/initializer'
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(:parser) { Parser.new(receiver) }
12
+ let(:visitor) { double }
13
+
14
+ def parse
15
+ parser.document(source)
16
+ end
17
+
18
+ context "for invalid gherkin" do
19
+ let(:source) { Gherkin::Document.new(path, 'not gherkin') }
20
+ let(:path) { 'path_to/the.feature' }
21
+
22
+ it "raises an error" do
23
+ expect { parse }.to raise_error(ParseError) do |error|
24
+ expect( error.message ).to match(/not gherkin/)
25
+ expect( error.message ).to match(/#{path}/)
26
+ end
27
+ end
28
+ end
29
+
30
+ include Writer
31
+ def self.source(&block)
32
+ let(:source) { gherkin(&block) }
33
+ end
34
+
35
+ def feature
36
+ result = nil
37
+ receiver.stub(:feature) { |feature| result = feature }
38
+ parse
39
+ result
40
+ end
41
+
42
+ context "when the Gherkin has a language header" do
43
+ source do
44
+ feature(language: 'ja', keyword: '機能')
45
+ end
46
+
47
+ it "sets the language from the Gherkin" do
48
+ feature.language.iso_code.should == 'ja'
49
+ end
50
+ end
51
+
52
+ context "a Scenario with a DocString" do
53
+ source do
54
+ feature do
55
+ scenario do
56
+ step do
57
+ doc_string("content")
58
+ end
59
+ end
60
+ end
61
+ end
62
+
63
+ it "parses doc strings without error" do
64
+ visitor.stub(:feature).and_yield
65
+ visitor.stub(:scenario).and_yield
66
+ visitor.stub(:step).and_yield
67
+
68
+ location = double
69
+ expected = Ast::DocString.new("content", "", location)
70
+ expect( visitor ).to receive(:doc_string).with(expected)
71
+ feature.describe_to(visitor)
72
+ end
73
+
74
+ end
75
+
76
+ context "a Scenario with a DataTable" do
77
+ source do
78
+ feature do
79
+ scenario do
80
+ step do
81
+ table do
82
+ row "name", "surname"
83
+ row "rob", "westgeest"
84
+ end
85
+ end
86
+ end
87
+ end
88
+ end
89
+
90
+ it "parses the DataTable" do
91
+ visitor = double
92
+ visitor.stub(:feature).and_yield
93
+ visitor.stub(:scenario).and_yield
94
+ visitor.stub(:step).and_yield
95
+
96
+ expected = Ast::DataTable.new([['name', 'surname'], ['rob', 'westgeest']], Ast::Location.new('foo.feature', 23))
97
+ expect( visitor ).to receive(:table).with(expected)
98
+ feature.describe_to(visitor)
99
+ end
100
+ end
101
+
102
+ context "a Scenario with a Comment" do
103
+ source do
104
+ feature do
105
+ comment 'wow'
106
+ scenario
107
+ end
108
+ end
109
+
110
+ it "parses the comment into the AST" do
111
+ visitor = double
112
+ visitor.stub(:feature).and_yield
113
+ expect( visitor ).to receive(:scenario) do |scenario|
114
+ expect( scenario.comments.join ).to eq "# wow"
115
+ end
116
+ feature.describe_to(visitor)
117
+ end
118
+ end
119
+
120
+ context "a Scenario Outline" do
121
+ source do
122
+ feature do
123
+ scenario_outline 'outline name' do
124
+ step 'passing <arg>'
125
+
126
+ examples do
127
+ row 'arg'
128
+ row '1'
129
+ row '2'
130
+ end
131
+
132
+ examples do
133
+ row 'arg'
134
+ row 'a'
135
+ end
136
+ end
137
+ end
138
+ end
139
+
140
+ it "creates a scenario outline node" do
141
+ visitor.stub(:feature).and_yield
142
+ expect( visitor ).to receive(:scenario_outline) do |outline|
143
+ expect( outline.name ).to eq 'outline name'
144
+ end
145
+ feature.describe_to(visitor)
146
+ end
147
+
148
+ it "creates a step node for each step of the scenario outline" do
149
+ visitor.stub(:feature).and_yield
150
+ visitor.stub(:scenario_outline).and_yield
151
+ visitor.stub(:examples_table)
152
+ expect( visitor ).to receive(:outline_step) do |step|
153
+ expect( step.name ).to eq 'passing <arg>'
154
+ end
155
+ feature.describe_to(visitor)
156
+ end
157
+
158
+ it "creates an examples table node for each examples table" do
159
+ visitor.stub(:feature).and_yield
160
+ visitor.stub(:scenario_outline).and_yield
161
+ visitor.stub(:outline_step)
162
+ expect( visitor ).to receive(:examples_table).exactly(2).times.and_yield
163
+ expect( visitor ).to receive(:examples_table_row) do |row|
164
+ expect( row.number ).to eq 1
165
+ expect( row.values ).to eq ['1']
166
+ end.once.ordered
167
+ expect( visitor ).to receive(:examples_table_row) do |row|
168
+ expect( row.number ).to eq 2
169
+ expect( row.values ).to eq ['2']
170
+ end.once.ordered
171
+ expect( visitor ).to receive(:examples_table_row) do |row|
172
+ expect( row.number ).to eq 1
173
+ expect( row.values ).to eq ['a']
174
+ end.once.ordered
175
+ feature.describe_to(visitor)
176
+ end
177
+
178
+ end
179
+ end
180
+ end
181
+ end
182
+ end
@@ -0,0 +1,332 @@
1
+ require 'cucumber/core/gherkin/writer'
2
+ require 'unindent'
3
+
4
+ module Cucumber::Core::Gherkin
5
+ describe Writer do
6
+ include Writer
7
+
8
+ context 'specifying uri' do
9
+ it 'generates a uri by default' do
10
+ source = gherkin { feature }
11
+ expect( source.uri ).to eq 'features/test.feature'
12
+ end
13
+
14
+ it 'allows you to specify a URI' do
15
+ source = gherkin('features/path/to/my.feature') { feature }
16
+ expect( source.uri ).to eq 'features/path/to/my.feature'
17
+ end
18
+ end
19
+
20
+ context 'a feature' do
21
+
22
+ it 'generates the feature statement' do
23
+ source = gherkin { feature }
24
+ expect( source ).to eq "Feature:\n"
25
+ end
26
+
27
+ context 'when a name is provided' do
28
+ it 'includes the name in the feature statement' do
29
+ source = gherkin do
30
+ feature "A Feature\n"
31
+ end
32
+ expect( source ).to eq "Feature: A Feature\n"
33
+ end
34
+ end
35
+
36
+ context 'when a description is provided' do
37
+ it 'includes the description in the feature statement' do
38
+ source = gherkin do
39
+ feature "A Feature", description: <<-END
40
+ This is the description
41
+ which can span
42
+ multiple lines.
43
+ END
44
+ end
45
+ expected = <<-END
46
+ Feature: A Feature
47
+ This is the description
48
+ which can span
49
+ multiple lines.
50
+ END
51
+
52
+ expect( source ).to eq expected.unindent
53
+ end
54
+ end
55
+
56
+ context 'when a keyword is provided' do
57
+ it 'uses the supplied keyword' do
58
+ source = gherkin do
59
+ feature "A Feature", keyword: "Business Need"
60
+ end
61
+ expect( source ).to eq "Business Need: A Feature\n"
62
+ end
63
+ end
64
+
65
+ context 'when a language is supplied' do
66
+ it 'inserts a language statement' do
67
+ source = gherkin do
68
+ feature language: 'ru'
69
+ end
70
+
71
+ expect( source ).to eq "# language: ru\nFeature:\n"
72
+ end
73
+ end
74
+
75
+ context 'when a comment is supplied' do
76
+ it 'inserts a comment' do
77
+ source = gherkin do
78
+ comment 'wow'
79
+ comment 'great'
80
+ feature
81
+ end
82
+
83
+ expect( source.to_s ).to eq "# wow\n# great\nFeature:\n"
84
+ end
85
+ end
86
+
87
+ context 'with a scenario' do
88
+ it 'includes the scenario statement' do
89
+ source = gherkin do
90
+ feature "A Feature" do
91
+ scenario
92
+ end
93
+ end
94
+
95
+ expect( source.to_s ).to match(/Scenario:/)
96
+ end
97
+
98
+ context 'when a comment is provided' do
99
+ it 'includes the comment in the scenario statement' do
100
+ source = gherkin do
101
+ feature do
102
+ comment 'wow'
103
+ scenario
104
+ end
105
+ end
106
+ expect( source.to_s ).to eq <<-END.unindent
107
+ Feature:
108
+
109
+ # wow
110
+ Scenario:
111
+ END
112
+ end
113
+ end
114
+
115
+ context 'when a description is provided' do
116
+ it 'includes the description in the scenario statement' do
117
+ source = gherkin do
118
+ feature do
119
+ scenario description: <<-END
120
+ This is the description
121
+ which can span
122
+ multiple lines.
123
+ END
124
+ end
125
+ end
126
+
127
+ expect( source ).to eq <<-END.unindent
128
+ Feature:
129
+
130
+ Scenario:
131
+ This is the description
132
+ which can span
133
+ multiple lines.
134
+ END
135
+ end
136
+ end
137
+
138
+ context 'with a step' do
139
+ it 'includes the step statement' do
140
+ source = gherkin do
141
+ feature "A Feature" do
142
+ scenario do
143
+ step 'passing'
144
+ end
145
+ end
146
+ end
147
+
148
+ expect( source.to_s ).to match(/Given passing\Z/m)
149
+ end
150
+
151
+ context 'when a docstring is provided' do
152
+ it 'includes the content type when provided' do
153
+ source = gherkin do
154
+ feature do
155
+ scenario do
156
+ step 'failing' do
157
+ doc_string 'some text', 'text/plain'
158
+ end
159
+ end
160
+ end
161
+
162
+ end
163
+
164
+ expect( source ).to eq <<-END.unindent
165
+ Feature:
166
+
167
+ Scenario:
168
+ Given failing
169
+ """text/plain
170
+ some text
171
+ """
172
+ END
173
+ end
174
+ end
175
+ end
176
+ end
177
+
178
+ context 'with a background' do
179
+ it 'can have a description' do
180
+ source = gherkin do
181
+ feature do
182
+ background description: "One line,\nand two.."
183
+ end
184
+ end
185
+
186
+ expect( source ).to eq <<-END.unindent
187
+ Feature:
188
+
189
+ Background:
190
+ One line,
191
+ and two..
192
+ END
193
+ end
194
+ end
195
+
196
+ context 'with a scenario outline' do
197
+ it 'can have a description' do
198
+ source = gherkin do
199
+ feature do
200
+ scenario_outline description: "Doesn't need to be multi-line."
201
+ end
202
+ end
203
+
204
+ expect( source ).to eq <<-END.unindent
205
+ Feature:
206
+
207
+ Scenario Outline:
208
+ Doesn't need to be multi-line.
209
+ END
210
+ end
211
+
212
+ context 'and examples table' do
213
+ it 'can have a description' do
214
+ source = gherkin do
215
+ feature do
216
+ scenario_outline do
217
+ examples description: "Doesn't need to be multi-line." do
218
+
219
+ end
220
+ end
221
+ end
222
+ end
223
+
224
+ expect( source ).to eq <<-END.unindent
225
+ Feature:
226
+
227
+ Scenario Outline:
228
+
229
+ Examples:
230
+ Doesn't need to be multi-line.
231
+ END
232
+ end
233
+ end
234
+ end
235
+ end
236
+
237
+ it 'generates a complex feature' do
238
+ source = gherkin do
239
+ comment 'wow'
240
+ feature 'Fully featured', language: 'en', tags: '@always' do
241
+ comment 'cool'
242
+ background do
243
+ step 'passing'
244
+ end
245
+
246
+ scenario do
247
+ step 'passing'
248
+ end
249
+
250
+ comment 'here'
251
+ scenario 'with doc string', tags: '@first @second' do
252
+ comment 'and here'
253
+ step 'passing'
254
+ step 'failing', keyword: 'When' do
255
+ doc_string <<-END
256
+ I wish I was a little bit taller.
257
+ I wish I was a baller.
258
+ END
259
+ end
260
+ end
261
+
262
+ scenario 'with a table...' do
263
+ step 'passes:' do
264
+ table do
265
+ row 'name', 'age', 'location'
266
+ row 'Janine', '43', 'Antarctica'
267
+ end
268
+ end
269
+ end
270
+
271
+ comment 'yay'
272
+ scenario_outline 'eating' do
273
+ step 'there are <start> cucumbers'
274
+ step 'I eat <eat> cucumbers', keyword: 'When'
275
+ step 'I should have <left> cucumbers', keyword: 'Then'
276
+
277
+ comment 'hmmm'
278
+ examples do
279
+ row 'start', 'eat', 'left'
280
+ row '12', '5', '7'
281
+ row '20', '5', '15'
282
+ end
283
+ end
284
+ end
285
+ end
286
+
287
+ expect( source.to_s ).to eq <<-END.unindent
288
+ # language: en
289
+ # wow
290
+ @always
291
+ Feature: Fully featured
292
+
293
+ # cool
294
+ Background:
295
+ Given passing
296
+
297
+ Scenario:
298
+ Given passing
299
+
300
+ # here
301
+ @first @second
302
+ Scenario: with doc string
303
+ # and here
304
+ Given passing
305
+ When failing
306
+ """
307
+ I wish I was a little bit taller.
308
+ I wish I was a baller.
309
+ """
310
+
311
+ Scenario: with a table...
312
+ Given passes:
313
+ | name | age | location |
314
+ | Janine | 43 | Antarctica |
315
+
316
+ # yay
317
+ Scenario Outline: eating
318
+ Given there are <start> cucumbers
319
+ When I eat <eat> cucumbers
320
+ Then I should have <left> cucumbers
321
+
322
+ # hmmm
323
+ Examples:
324
+ | start | eat | left |
325
+ | 12 | 5 | 7 |
326
+ | 20 | 5 | 15 |
327
+ END
328
+
329
+ end
330
+ end
331
+ end
332
+