cucumber-core 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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
+