cuke_modeler 1.3.0 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (90) hide show
  1. checksums.yaml +5 -5
  2. data/.travis.yml +60 -17
  3. data/CHANGELOG.md +312 -0
  4. data/Gemfile +19 -3
  5. data/LICENSE.txt +1 -1
  6. data/README.md +17 -7
  7. data/Rakefile +45 -28
  8. data/appveyor.yml +57 -17
  9. data/cuke_modeler.gemspec +6 -3
  10. data/lib/cuke_modeler/adapters/gherkin_2_adapter.rb +1 -0
  11. data/lib/cuke_modeler/adapters/gherkin_3_adapter.rb +1 -0
  12. data/lib/cuke_modeler/adapters/gherkin_4_adapter.rb +2 -1
  13. data/lib/cuke_modeler/adapters/gherkin_5_adapter.rb +12 -0
  14. data/lib/cuke_modeler/adapters/gherkin_6_adapter.rb +310 -0
  15. data/lib/cuke_modeler/adapters/gherkin_7_adapter.rb +307 -0
  16. data/lib/cuke_modeler/adapters/gherkin_8_adapter.rb +12 -0
  17. data/lib/cuke_modeler/adapters/gherkin_9_adapter.rb +12 -0
  18. data/lib/cuke_modeler/containing.rb +16 -0
  19. data/lib/cuke_modeler/described.rb +1 -0
  20. data/lib/cuke_modeler/models/step.rb +31 -2
  21. data/lib/cuke_modeler/named.rb +1 -0
  22. data/lib/cuke_modeler/nested.rb +1 -0
  23. data/lib/cuke_modeler/parsed.rb +1 -0
  24. data/lib/cuke_modeler/parsing.rb +116 -68
  25. data/lib/cuke_modeler/sourceable.rb +1 -0
  26. data/lib/cuke_modeler/stepped.rb +1 -0
  27. data/lib/cuke_modeler/taggable.rb +1 -0
  28. data/lib/cuke_modeler/version.rb +1 -1
  29. data/testing/cucumber/features/analysis/step_comparison.feature +25 -0
  30. data/testing/cucumber/features/analysis/test_comparison.feature +1 -1
  31. data/testing/cucumber/step_definitions/feature_file_steps.rb +1 -1
  32. data/testing/cucumber/step_definitions/modeling_steps.rb +7 -2
  33. data/testing/cucumber/step_definitions/verification_steps.rb +11 -2
  34. data/testing/file_helper.rb +3 -0
  35. data/testing/gemfiles/gherkin2.gemfile +8 -0
  36. data/testing/gemfiles/gherkin3.gemfile +6 -0
  37. data/testing/gemfiles/gherkin4.gemfile +7 -0
  38. data/testing/gemfiles/gherkin5.gemfile +7 -0
  39. data/testing/gemfiles/gherkin6.gemfile +10 -0
  40. data/testing/gemfiles/gherkin7.gemfile +9 -0
  41. data/testing/gemfiles/gherkin8.gemfile +9 -0
  42. data/testing/gemfiles/gherkin9.gemfile +9 -0
  43. data/testing/helper_methods.rb +23 -0
  44. data/testing/rspec/spec/integration/{gherkin_2_adapter_spec.rb → adapters/gherkin_2_adapter_spec.rb} +13 -13
  45. data/testing/rspec/spec/integration/{gherkin_3_adapter_spec.rb → adapters/gherkin_3_adapter_spec.rb} +13 -13
  46. data/testing/rspec/spec/integration/{gherkin_4_adapter_spec.rb → adapters/gherkin_4_adapter_spec.rb} +13 -13
  47. data/testing/rspec/spec/integration/adapters/gherkin_5_adapter_spec.rb +165 -0
  48. data/testing/rspec/spec/integration/adapters/gherkin_6_adapter_spec.rb +159 -0
  49. data/testing/rspec/spec/integration/adapters/gherkin_7_adapter_spec.rb +162 -0
  50. data/testing/rspec/spec/integration/adapters/gherkin_8_adapter_spec.rb +162 -0
  51. data/testing/rspec/spec/integration/adapters/gherkin_9_adapter_spec.rb +162 -0
  52. data/testing/rspec/spec/integration/{background_integration_spec.rb → models/background_integration_spec.rb} +90 -86
  53. data/testing/rspec/spec/integration/{cell_integration_spec.rb → models/cell_integration_spec.rb} +49 -38
  54. data/testing/rspec/spec/integration/{comment_integration_spec.rb → models/comment_integration_spec.rb} +31 -20
  55. data/testing/rspec/spec/integration/{directory_integration_spec.rb → models/directory_integration_spec.rb} +3 -3
  56. data/testing/rspec/spec/integration/{doc_string_integration_spec.rb → models/doc_string_integration_spec.rb} +39 -35
  57. data/testing/rspec/spec/integration/{example_integration_spec.rb → models/example_integration_spec.rb} +109 -83
  58. data/testing/rspec/spec/integration/{feature_file_integration_spec.rb → models/feature_file_integration_spec.rb} +52 -38
  59. data/testing/rspec/spec/integration/{feature_integration_spec.rb → models/feature_integration_spec.rb} +125 -112
  60. data/testing/rspec/spec/integration/{model_integration_spec.rb → models/model_integration_spec.rb} +1 -1
  61. data/testing/rspec/spec/integration/{outline_integration_spec.rb → models/outline_integration_spec.rb} +138 -129
  62. data/testing/rspec/spec/integration/{row_integration_spec.rb → models/row_integration_spec.rb} +55 -35
  63. data/testing/rspec/spec/integration/{scenario_integration_spec.rb → models/scenario_integration_spec.rb} +92 -88
  64. data/testing/rspec/spec/integration/models/step_integration_spec.rb +573 -0
  65. data/testing/rspec/spec/integration/{table_integration_spec.rb → models/table_integration_spec.rb} +38 -34
  66. data/testing/rspec/spec/integration/{tag_integration_spec.rb → models/tag_integration_spec.rb} +56 -36
  67. data/testing/rspec/spec/integration/parsing_integration_spec.rb +45 -7
  68. data/testing/rspec/spec/spec_helper.rb +79 -43
  69. data/testing/rspec/spec/unit/cuke_modeler_unit_spec.rb +25 -0
  70. data/testing/rspec/spec/unit/{background_unit_spec.rb → models/background_unit_spec.rb} +1 -1
  71. data/testing/rspec/spec/unit/{cell_unit_spec.rb → models/cell_unit_spec.rb} +1 -1
  72. data/testing/rspec/spec/unit/{comment_unit_spec.rb → models/comment_unit_spec.rb} +1 -1
  73. data/testing/rspec/spec/unit/{directory_unit_spec.rb → models/directory_unit_spec.rb} +1 -1
  74. data/testing/rspec/spec/unit/{doc_string_unit_spec.rb → models/doc_string_unit_spec.rb} +1 -1
  75. data/testing/rspec/spec/unit/{example_unit_spec.rb → models/example_unit_spec.rb} +1 -1
  76. data/testing/rspec/spec/unit/{feature_file_unit_spec.rb → models/feature_file_unit_spec.rb} +1 -1
  77. data/testing/rspec/spec/unit/{feature_unit_spec.rb → models/feature_unit_spec.rb} +1 -1
  78. data/testing/rspec/spec/unit/{model_unit_spec.rb → models/model_unit_spec.rb} +1 -1
  79. data/testing/rspec/spec/unit/{outline_unit_spec.rb → models/outline_unit_spec.rb} +1 -1
  80. data/testing/rspec/spec/unit/{row_unit_spec.rb → models/row_unit_spec.rb} +1 -1
  81. data/testing/rspec/spec/unit/{scenario_unit_spec.rb → models/scenario_unit_spec.rb} +1 -1
  82. data/testing/rspec/spec/unit/{step_unit_spec.rb → models/step_unit_spec.rb} +2 -2
  83. data/testing/rspec/spec/unit/{table_unit_spec.rb → models/table_unit_spec.rb} +1 -1
  84. data/testing/rspec/spec/unit/{tag_unit_spec.rb → models/tag_unit_spec.rb} +1 -1
  85. data/testing/rspec/spec/unit/shared/containing_models_unit_specs.rb +102 -0
  86. data/todo.txt +5 -2
  87. metadata +80 -47
  88. data/History.md +0 -186
  89. data/testing/cucumber/support/transforms.rb +0 -3
  90. data/testing/rspec/spec/integration/step_integration_spec.rb +0 -459
@@ -0,0 +1,573 @@
1
+ require "#{File.dirname(__FILE__)}/../../spec_helper"
2
+
3
+
4
+ describe 'Step, Integration' do
5
+
6
+ let(:clazz) { CukeModeler::Step }
7
+
8
+
9
+ describe 'common behavior' do
10
+
11
+ it_should_behave_like 'a model, integration'
12
+
13
+ end
14
+
15
+ describe 'unique behavior' do
16
+
17
+ it 'can be instantiated with the minimum viable Gherkin' do
18
+ source = "#{STEP_KEYWORD} a step"
19
+
20
+ expect { clazz.new(source) }.to_not raise_error
21
+ end
22
+
23
+ it 'can parse text that uses a non-default dialect' do
24
+ original_dialect = CukeModeler::Parsing.dialect
25
+ CukeModeler::Parsing.dialect = 'en-au'
26
+
27
+ begin
28
+ source_text = "Y'know a step"
29
+
30
+ expect { @model = clazz.new(source_text) }.to_not raise_error
31
+
32
+ # Sanity check in case modeling failed in a non-explosive manner
33
+ expect(@model.keyword).to eq("Y'know")
34
+ ensure
35
+ # Making sure that our changes don't escape a test and ruin the rest of the suite
36
+ CukeModeler::Parsing.dialect = original_dialect
37
+ end
38
+ end
39
+
40
+ it 'provides a descriptive filename when being parsed from stand alone text' do
41
+ source = "bad step text\n And a step\n @foo"
42
+
43
+ expect { clazz.new(source) }.to raise_error(/'cuke_modeler_stand_alone_step\.feature'/)
44
+ end
45
+
46
+ describe 'parsing data' do
47
+
48
+ it 'stores the original data generated by the parsing adapter (with a table)', :if => gherkin?(8, 9) do
49
+ step = clazz.new("#{STEP_KEYWORD} test step\n|table|")
50
+ data = step.parsing_data
51
+
52
+ expect(data.keys).to match_array([:location, :keyword, :text, :data_table, :doc_string, :id])
53
+ expect(data[:text]).to eq('test step')
54
+ end
55
+
56
+ it 'stores the original data generated by the parsing adapter (with a doc string)', :if => gherkin?(8, 9) do
57
+ step = clazz.new("#{STEP_KEYWORD} test step\n\"\"\"\na doc string\n\"\"\"")
58
+ data = step.parsing_data
59
+
60
+ expect(data.keys).to match_array([:location, :keyword, :text, :data_table, :doc_string, :id])
61
+ expect(data[:text]).to eq('test step')
62
+ end
63
+
64
+ it 'stores the original data generated by the parsing adapter (with a table)', :if => gherkin?(6, 7) do
65
+ step = clazz.new("#{STEP_KEYWORD} test step\n|table|")
66
+ data = step.parsing_data
67
+
68
+ expect(data.keys).to match_array([:location, :keyword, :text, :data_table, :doc_string])
69
+ expect(data[:text]).to eq('test step')
70
+ end
71
+
72
+ it 'stores the original data generated by the parsing adapter (with a doc string)', :if => gherkin?(6, 7) do
73
+ step = clazz.new("#{STEP_KEYWORD} test step\n\"\"\"\na doc string\n\"\"\"")
74
+ data = step.parsing_data
75
+
76
+ expect(data.keys).to match_array([:location, :keyword, :text, :data_table, :doc_string])
77
+ expect(data[:text]).to eq('test step')
78
+ end
79
+
80
+ it 'stores the original data generated by the parsing adapter (with a table)', :if => gherkin?(3, 4, 5) do
81
+ step = clazz.new("#{STEP_KEYWORD} test step\n|table|")
82
+ data = step.parsing_data
83
+
84
+ expect(data.keys).to match_array([:type, :location, :keyword, :text, :argument])
85
+ expect(data[:type]).to eq(:Step)
86
+ end
87
+
88
+ it 'stores the original data generated by the parsing adapter (with a doc string)', :if => gherkin?(3, 4, 5) do
89
+ step = clazz.new("#{STEP_KEYWORD} test step\n\"\"\"\na doc string\n\"\"\"")
90
+ data = step.parsing_data
91
+
92
+ expect(data.keys).to match_array([:type, :location, :keyword, :text, :argument])
93
+ expect(data[:type]).to eq(:Step)
94
+ end
95
+
96
+ it 'stores the original data generated by the parsing adapter (with a table)', :if => gherkin?(2) do
97
+ step = clazz.new("#{STEP_KEYWORD} test step\n|table|")
98
+ data = step.parsing_data
99
+
100
+ expect(data.keys).to match_array(['keyword', 'name', 'line', 'rows'])
101
+ expect(data['keyword']).to eq("#{STEP_KEYWORD} ")
102
+ end
103
+
104
+ it 'stores the original data generated by the parsing adapter (with a doc string)', :if => gherkin?(2) do
105
+ step = clazz.new("#{STEP_KEYWORD} test step\n\"\"\"\na doc string\n\"\"\"")
106
+ data = step.parsing_data
107
+
108
+ expect(data.keys).to match_array(['keyword', 'name', 'line', 'doc_string'])
109
+ expect(data['keyword']).to eq("#{STEP_KEYWORD} ")
110
+ end
111
+
112
+ end
113
+
114
+ describe 'model population' do
115
+
116
+ context 'from source text' do
117
+
118
+ let(:source_text) { "#{STEP_KEYWORD} a step" }
119
+ let(:step) { clazz.new(source_text) }
120
+
121
+
122
+ it "models the step's keyword" do
123
+ expect(step.keyword).to eq("#{STEP_KEYWORD}")
124
+ end
125
+
126
+ it "models the step's text" do
127
+ expect(step.text).to eq('a step')
128
+ end
129
+
130
+ it "models the step's source line" do
131
+ source_text = "#{FEATURE_KEYWORD}:
132
+
133
+ #{SCENARIO_KEYWORD}: foo
134
+ #{STEP_KEYWORD} step"
135
+ step = CukeModeler::Feature.new(source_text).tests.first.steps.first
136
+
137
+ expect(step.source_line).to eq(4)
138
+ end
139
+
140
+
141
+ context 'with no block' do
142
+
143
+ let(:source_text) { "#{STEP_KEYWORD} a step" }
144
+ let(:step) { clazz.new(source_text) }
145
+
146
+
147
+ it "models the step's block" do
148
+ expect(step.block).to be_nil
149
+ end
150
+
151
+ end
152
+
153
+ context 'a step with a table' do
154
+
155
+ let(:source_text) { "#{STEP_KEYWORD} a step
156
+ | value 1 |
157
+ | value 2 |" }
158
+ let(:step) { clazz.new(source_text) }
159
+
160
+
161
+ it "models the step's table" do
162
+ table_cell_values = step.block.rows.collect { |row| row.cells.collect { |cell| cell.value } }
163
+
164
+ expect(table_cell_values).to eq([['value 1'], ['value 2']])
165
+ end
166
+
167
+ end
168
+
169
+ context 'a step with a doc string' do
170
+
171
+ let(:source_text) { "#{STEP_KEYWORD} a step
172
+ \"\"\"
173
+ some text
174
+ \"\"\"" }
175
+ let(:step) { clazz.new(source_text) }
176
+
177
+
178
+ it "models the step's doc string" do
179
+ doc_string = step.block
180
+
181
+ expect(doc_string.content).to eq('some text')
182
+ end
183
+
184
+ end
185
+
186
+ end
187
+
188
+ end
189
+
190
+
191
+ it 'properly sets its child models' do
192
+ source_1 = "#{STEP_KEYWORD} a step
193
+ \"\"\"
194
+ a doc string
195
+ \"\"\""
196
+ source_2 = "#{STEP_KEYWORD} a step
197
+ | a block|"
198
+
199
+ step_1 = clazz.new(source_1)
200
+ step_2 = clazz.new(source_2)
201
+
202
+
203
+ doc_string = step_1.block
204
+ table = step_2.block
205
+
206
+ expect(doc_string.parent_model).to equal(step_1)
207
+ expect(table.parent_model).to equal(step_2)
208
+ end
209
+
210
+
211
+ describe 'step comparison' do
212
+
213
+ context 'a step that has text' do
214
+
215
+ let(:step_text) { "#{STEP_KEYWORD} a step" }
216
+ let(:base_step) { clazz.new(step_text) }
217
+
218
+ context 'compared to a step that has the same text' do
219
+
220
+ let(:compared_step) { clazz.new(step_text) }
221
+
222
+ it 'considers them to be equal' do
223
+ assert_bidirectional_equality(base_step, compared_step)
224
+ end
225
+
226
+ end
227
+
228
+ context 'compared to a step that has different text' do
229
+
230
+ let(:compared_step) { clazz.new(step_text + ' plus some more') }
231
+
232
+ it 'considers them to not be equal' do
233
+ assert_bidirectional_inequality(base_step, compared_step)
234
+ end
235
+
236
+ end
237
+
238
+ context 'compared to a step that has a table' do
239
+
240
+ let(:compared_step) { clazz.new(step_text + "\n | foo |") }
241
+
242
+ it 'considers them to not be equal' do
243
+ assert_bidirectional_inequality(base_step, compared_step)
244
+ end
245
+
246
+ end
247
+
248
+ context 'compared to a step that has a doc string' do
249
+
250
+ let(:compared_step) { clazz.new(step_text + "\n \"\"\"\n foo\n\"\"\"") }
251
+
252
+ it 'considers them to not be equal' do
253
+ assert_bidirectional_inequality(base_step, compared_step)
254
+ end
255
+
256
+ end
257
+
258
+
259
+ context 'and has table' do
260
+
261
+ let(:step_text) { "#{STEP_KEYWORD} a step\n | foo |" }
262
+ let(:base_step) { clazz.new(step_text) }
263
+
264
+ context 'compared to a step that has the same table' do
265
+
266
+ let(:compared_step) { clazz.new(step_text) }
267
+
268
+ it 'considers them to be equal' do
269
+ assert_bidirectional_equality(base_step, compared_step)
270
+ end
271
+
272
+ end
273
+
274
+ context 'compared to a step that has a different table' do
275
+
276
+ let(:compared_step) { clazz.new(step_text + "\n | a different table |") }
277
+
278
+ it 'considers them to not be equal' do
279
+ assert_bidirectional_inequality(base_step, compared_step)
280
+ end
281
+
282
+ end
283
+
284
+ end
285
+
286
+
287
+ context 'and has a doc string' do
288
+
289
+ let(:content) { 'foo' }
290
+ let(:base_step) { clazz.new("#{step_text}\n\"\"\"\n#{content}\n\"\"\"") }
291
+
292
+ context 'compared to a step that has the same doc string' do
293
+
294
+ let(:compared_step) { clazz.new("#{step_text}\n\"\"\"\n#{content}\n\"\"\"") }
295
+
296
+ it 'considers them to be equal' do
297
+ assert_bidirectional_equality(base_step, compared_step)
298
+ end
299
+
300
+ end
301
+
302
+ context 'compared to a step that has a different doc string' do
303
+
304
+ let(:compared_step) { clazz.new("#{step_text}\n\"\"\"\n#{content + 'different'}\n\"\"\"") }
305
+
306
+ it 'considers them to not be equal' do
307
+ assert_bidirectional_inequality(base_step, compared_step)
308
+ end
309
+
310
+ end
311
+
312
+ context 'and has a content type' do
313
+
314
+ let(:content_type) { 'foo' }
315
+ let(:base_step) { clazz.new("#{step_text}\n\"\"\" #{content_type}\n#{content}\n\"\"\"") }
316
+
317
+
318
+ context 'compared to a step that has the same content type' do
319
+
320
+ let(:compared_step) { clazz.new("#{step_text}\n\"\"\" #{content_type}\n#{content}\n\"\"\"") }
321
+
322
+ it 'considers them to be equal' do
323
+ assert_bidirectional_equality(base_step, compared_step)
324
+ end
325
+
326
+ end
327
+
328
+ context 'compared to a step that has a different content type' do
329
+
330
+ let(:compared_step) { clazz.new("#{step_text}\n\"\"\" different #{content_type}\n#{content}\n\"\"\"") }
331
+
332
+ it 'considers them to not be equal' do
333
+ assert_bidirectional_inequality(base_step, compared_step)
334
+ end
335
+
336
+ end
337
+
338
+ end
339
+
340
+ end
341
+
342
+ end
343
+
344
+ it 'ignores steps keywords when comparing steps' do
345
+ source_1 = "#{GIVEN_KEYWORD} a step"
346
+ source_2 = "#{THEN_KEYWORD} a step"
347
+
348
+ step_1 = clazz.new(source_1)
349
+ step_2 = clazz.new(source_2)
350
+
351
+
352
+ expect(step_1).to eq(step_2)
353
+ end
354
+
355
+ end
356
+
357
+
358
+ describe 'getting ancestors' do
359
+
360
+ before(:each) do
361
+ CukeModeler::FileHelper.create_feature_file(:text => source_gherkin, :name => 'step_test_file', :directory => test_directory)
362
+ end
363
+
364
+
365
+ let(:test_directory) { CukeModeler::FileHelper.create_directory }
366
+ let(:source_gherkin) { "#{FEATURE_KEYWORD}: Test feature
367
+
368
+ #{SCENARIO_KEYWORD}: Test test
369
+ #{STEP_KEYWORD} a step:"
370
+ }
371
+
372
+ let(:directory_model) { CukeModeler::Directory.new(test_directory) }
373
+ let(:step_model) { directory_model.feature_files.first.feature.tests.first.steps.first }
374
+
375
+
376
+ it 'can get its directory' do
377
+ ancestor = step_model.get_ancestor(:directory)
378
+
379
+ expect(ancestor).to equal(directory_model)
380
+ end
381
+
382
+ it 'can get its feature file' do
383
+ ancestor = step_model.get_ancestor(:feature_file)
384
+
385
+ expect(ancestor).to equal(directory_model.feature_files.first)
386
+ end
387
+
388
+ it 'can get its feature' do
389
+ ancestor = step_model.get_ancestor(:feature)
390
+
391
+ expect(ancestor).to equal(directory_model.feature_files.first.feature)
392
+ end
393
+
394
+
395
+ context 'a step that is part of a scenario' do
396
+
397
+ let(:test_directory) { CukeModeler::FileHelper.create_directory }
398
+ let(:source_gherkin) { "#{FEATURE_KEYWORD}: Test feature
399
+
400
+ #{SCENARIO_KEYWORD}: Test scenario
401
+ #{STEP_KEYWORD} a step"
402
+ }
403
+
404
+ let(:directory_model) { CukeModeler::Directory.new(test_directory) }
405
+ let(:step_model) { directory_model.feature_files.first.feature.tests.first.steps.first }
406
+
407
+
408
+ it 'can get its scenario' do
409
+ ancestor = step_model.get_ancestor(:scenario)
410
+
411
+ expect(ancestor).to equal(directory_model.feature_files.first.feature.tests.first)
412
+ end
413
+
414
+ end
415
+
416
+ context 'a step that is part of an outline' do
417
+
418
+ let(:test_directory) { CukeModeler::FileHelper.create_directory }
419
+ let(:source_gherkin) { "#{FEATURE_KEYWORD}: Test feature
420
+
421
+ #{OUTLINE_KEYWORD}: Test outline
422
+ #{STEP_KEYWORD} a step
423
+ #{EXAMPLE_KEYWORD}:
424
+ | param |
425
+ | value |"
426
+ }
427
+
428
+ let(:directory_model) { CukeModeler::Directory.new(test_directory) }
429
+ let(:step_model) { directory_model.feature_files.first.feature.tests.first.steps.first }
430
+
431
+
432
+ it 'can get its outline' do
433
+ ancestor = step_model.get_ancestor(:outline)
434
+
435
+ expect(ancestor).to equal(directory_model.feature_files.first.feature.tests.first)
436
+ end
437
+
438
+ end
439
+
440
+ context 'a step that is part of a background' do
441
+
442
+ let(:test_directory) { CukeModeler::FileHelper.create_directory }
443
+ let(:source_gherkin) { "#{FEATURE_KEYWORD}: Test feature
444
+
445
+ #{BACKGROUND_KEYWORD}: Test background
446
+ #{STEP_KEYWORD} a step"
447
+ }
448
+
449
+ let(:directory_model) { CukeModeler::Directory.new(test_directory) }
450
+ let(:step_model) { directory_model.feature_files.first.feature.background.steps.first }
451
+
452
+
453
+ it 'can get its background' do
454
+ ancestor = step_model.get_ancestor(:background)
455
+
456
+ expect(ancestor).to equal(directory_model.feature_files.first.feature.background)
457
+ end
458
+
459
+ end
460
+
461
+ it 'returns nil if it does not have the requested type of ancestor' do
462
+ ancestor = step_model.get_ancestor(:example)
463
+
464
+ expect(ancestor).to be_nil
465
+ end
466
+
467
+ end
468
+
469
+
470
+ describe 'step output' do
471
+
472
+ context 'from source text' do
473
+
474
+ context 'with no block' do
475
+
476
+ let(:source_text) { ["#{STEP_KEYWORD} a step"].join("\n") }
477
+ let(:step) { clazz.new(source_text) }
478
+
479
+ it 'can output a step' do
480
+ step_output = step.to_s.split("\n", -1)
481
+
482
+ expect(step_output).to eq(["#{STEP_KEYWORD} a step"])
483
+ end
484
+
485
+ it 'can be remade from its own output' do
486
+ step_output = step.to_s
487
+ remade_step_output = clazz.new(step_output).to_s
488
+
489
+ expect(remade_step_output).to eq(step_output)
490
+ end
491
+
492
+ end
493
+
494
+ context 'a step with a table' do
495
+
496
+ let(:source_text) { ["#{STEP_KEYWORD} a step",
497
+ ' | value1 | value2 |',
498
+ ' | value3 | value4 |'].join("\n") }
499
+ let(:step) { clazz.new(source_text) }
500
+
501
+
502
+ it 'can output a step that has a table' do
503
+ step_output = step.to_s.split("\n", -1)
504
+
505
+ expect(step_output).to eq(["#{STEP_KEYWORD} a step",
506
+ ' | value1 | value2 |',
507
+ ' | value3 | value4 |'])
508
+
509
+ end
510
+
511
+ it 'can be remade from its own output' do
512
+ step_output = step.to_s
513
+ remade_step_output = clazz.new(step_output).to_s
514
+
515
+ expect(remade_step_output).to eq(step_output)
516
+ end
517
+
518
+ end
519
+
520
+ context 'a step with a doc string' do
521
+
522
+ let(:source_text) { ["#{STEP_KEYWORD} a step",
523
+ ' """',
524
+ ' some text',
525
+ ' """'].join("\n") }
526
+ let(:step) { clazz.new(source_text) }
527
+
528
+
529
+ it 'can output a step that has a doc string' do
530
+ step_output = step.to_s.split("\n", -1)
531
+
532
+ expect(step_output).to eq(["#{STEP_KEYWORD} a step",
533
+ ' """',
534
+ ' some text',
535
+ ' """'])
536
+ end
537
+
538
+ it 'can be remade from its own output' do
539
+ step_output = step.to_s
540
+ remade_step_output = clazz.new(step_output).to_s
541
+
542
+ expect(remade_step_output).to eq(step_output)
543
+ end
544
+
545
+ end
546
+
547
+ end
548
+
549
+
550
+ context 'from abstract instantiation' do
551
+
552
+ let(:step) { clazz.new }
553
+
554
+
555
+ it 'can output a step that has only a table' do
556
+ step.block = CukeModeler::Table.new
557
+
558
+ expect { step.to_s }.to_not raise_error
559
+ end
560
+
561
+ it 'can output a step that has only a doc string' do
562
+ step.block = CukeModeler::DocString.new
563
+
564
+ expect { step.to_s }.to_not raise_error
565
+ end
566
+
567
+ end
568
+
569
+ end
570
+
571
+ end
572
+
573
+ end