cuke_modeler 0.4.1 → 1.0.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 (252) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +17 -17
  3. data/.travis.yml +1 -1
  4. data/Gemfile +4 -0
  5. data/History.rdoc +71 -3
  6. data/LICENSE.txt +22 -22
  7. data/README.md +24 -10
  8. data/Rakefile +2 -12
  9. data/cuke_modeler.gemspec +1 -1
  10. data/features/analysis/test_comparison.feature +37 -122
  11. data/features/modeling/background_modeling.feature +77 -0
  12. data/features/modeling/background_output.feature +42 -0
  13. data/features/modeling/cell_modeling.feature +23 -0
  14. data/features/modeling/cell_output.feature +22 -0
  15. data/features/modeling/directory_modeling.feature +65 -0
  16. data/features/modeling/directory_output.feature +12 -0
  17. data/features/modeling/doc_string_modeling.feature +61 -0
  18. data/features/modeling/doc_string_output.feature +32 -0
  19. data/features/modeling/example_modeling.feature +125 -0
  20. data/features/modeling/example_output.feature +39 -0
  21. data/features/modeling/feature_file_modeling.feature +40 -0
  22. data/features/modeling/feature_file_output.feature +12 -0
  23. data/features/modeling/feature_modeling.feature +109 -0
  24. data/features/modeling/feature_output.feature +104 -0
  25. data/features/modeling/model_output.feature +22 -0
  26. data/features/modeling/model_structure.feature +48 -0
  27. data/features/modeling/outline_modeling.feature +144 -0
  28. data/features/modeling/outline_output.feature +69 -0
  29. data/features/modeling/row_modeling.feature +48 -0
  30. data/features/modeling/row_output.feature +22 -0
  31. data/features/modeling/scenario_modeling.feature +118 -0
  32. data/features/modeling/scenario_output.feature +45 -0
  33. data/features/modeling/step_modeling.feature +84 -0
  34. data/features/modeling/step_output.feature +29 -0
  35. data/features/modeling/table_modeling.feature +50 -0
  36. data/features/modeling/table_output.feature +24 -0
  37. data/features/modeling/tag_modeling.feature +43 -0
  38. data/features/modeling/tag_output.feature +22 -0
  39. data/features/step_definitions/action_steps.rb +11 -1
  40. data/features/step_definitions/background_steps.rb +1 -85
  41. data/features/step_definitions/directory_steps.rb +2 -48
  42. data/features/step_definitions/doc_string_steps.rb +1 -67
  43. data/features/step_definitions/feature_file_steps.rb +2 -37
  44. data/features/step_definitions/feature_steps.rb +4 -100
  45. data/features/step_definitions/modeling_steps.rb +44 -0
  46. data/features/step_definitions/setup_steps.rb +19 -41
  47. data/features/step_definitions/step_steps.rb +2 -166
  48. data/features/step_definitions/table_steps.rb +1 -58
  49. data/features/step_definitions/tag_steps.rb +2 -72
  50. data/features/step_definitions/verification_steps.rb +152 -4
  51. data/features/support/env.rb +4 -6
  52. data/gemfiles/{gherkin.gemfile → gherkin2.gemfile} +4 -0
  53. data/gemfiles/gherkin3.gemfile +4 -0
  54. data/gemfiles/gherkin4.gemfile +4 -0
  55. data/lib/cuke_modeler.rb +24 -22
  56. data/lib/cuke_modeler/adapters/gherkin_2_adapter.rb +103 -31
  57. data/lib/cuke_modeler/adapters/gherkin_3_adapter.rb +103 -40
  58. data/lib/cuke_modeler/adapters/gherkin_4_adapter.rb +111 -50
  59. data/lib/cuke_modeler/containing.rb +255 -4
  60. data/lib/cuke_modeler/described.rb +28 -0
  61. data/lib/cuke_modeler/models/background.rb +66 -0
  62. data/lib/cuke_modeler/models/cell.rb +48 -0
  63. data/lib/cuke_modeler/models/directory.rb +95 -0
  64. data/lib/cuke_modeler/models/doc_string.rb +59 -0
  65. data/lib/cuke_modeler/models/example.rb +167 -0
  66. data/lib/cuke_modeler/models/feature.rb +106 -0
  67. data/lib/cuke_modeler/models/feature_file.rb +64 -0
  68. data/lib/cuke_modeler/models/model.rb +32 -0
  69. data/lib/cuke_modeler/models/outline.rb +79 -0
  70. data/lib/cuke_modeler/models/row.rb +49 -0
  71. data/lib/cuke_modeler/models/scenario.rb +69 -0
  72. data/lib/cuke_modeler/models/step.rb +68 -0
  73. data/lib/cuke_modeler/models/table.rb +67 -0
  74. data/lib/cuke_modeler/models/tag.rb +46 -0
  75. data/lib/cuke_modeler/named.rb +19 -0
  76. data/lib/cuke_modeler/nested.rb +22 -15
  77. data/lib/cuke_modeler/parsed.rb +11 -0
  78. data/lib/cuke_modeler/parsing.rb +66 -83
  79. data/lib/cuke_modeler/sourceable.rb +3 -11
  80. data/lib/cuke_modeler/stepped.rb +24 -0
  81. data/lib/cuke_modeler/taggable.rb +6 -29
  82. data/lib/cuke_modeler/version.rb +2 -1
  83. data/spec/integration/background_integration_spec.rb +332 -7
  84. data/spec/integration/cell_integration_spec.rb +321 -0
  85. data/spec/integration/directory_integration_spec.rb +175 -9
  86. data/spec/integration/doc_string_integration_spec.rb +318 -7
  87. data/spec/integration/example_integration_spec.rb +602 -19
  88. data/spec/integration/feature_file_integration_spec.rb +98 -3
  89. data/spec/integration/feature_integration_spec.rb +445 -27
  90. data/spec/integration/gherkin_2_adapter_spec.rb +122 -0
  91. data/spec/integration/gherkin_3_adapter_spec.rb +125 -0
  92. data/spec/integration/gherkin_4_adapter_spec.rb +123 -0
  93. data/spec/integration/model_integration_spec.rb +15 -0
  94. data/spec/integration/nested_integration_spec.rb +91 -0
  95. data/spec/integration/outline_integration_spec.rb +485 -12
  96. data/spec/integration/parsing_integration_spec.rb +85 -0
  97. data/spec/integration/row_integration_spec.rb +221 -18
  98. data/spec/integration/scenario_integration_spec.rb +368 -14
  99. data/spec/integration/shared/models_integration_specs.rb +18 -0
  100. data/spec/integration/step_integration_spec.rb +328 -77
  101. data/spec/integration/table_integration_spec.rb +242 -20
  102. data/spec/integration/tag_integration_spec.rb +178 -13
  103. data/spec/spec_helper.rb +32 -18
  104. data/spec/unit/background_unit_spec.rb +24 -44
  105. data/spec/unit/cell_unit_spec.rb +73 -0
  106. data/spec/unit/described_unit_spec.rb +23 -0
  107. data/spec/unit/directory_unit_spec.rb +52 -62
  108. data/spec/unit/doc_string_unit_spec.rb +47 -100
  109. data/spec/unit/example_unit_spec.rb +50 -296
  110. data/spec/unit/feature_file_unit_spec.rb +53 -52
  111. data/spec/unit/feature_unit_spec.rb +39 -83
  112. data/spec/unit/model_unit_spec.rb +15 -0
  113. data/spec/unit/named_unit_spec.rb +23 -0
  114. data/spec/unit/nested_unit_spec.rb +24 -21
  115. data/spec/unit/outline_unit_spec.rb +46 -69
  116. data/spec/unit/parsed_unit_spec.rb +27 -0
  117. data/spec/unit/parsing_unit_spec.rb +2 -70
  118. data/spec/unit/row_unit_spec.rb +22 -51
  119. data/spec/unit/scenario_unit_spec.rb +27 -59
  120. data/spec/unit/{bare_bones_unit_specs.rb → shared/bare_bones_models_unit_specs.rb} +2 -2
  121. data/spec/unit/shared/containing_models_unit_specs.rb +18 -0
  122. data/spec/unit/shared/described_models_unit_specs.rb +38 -0
  123. data/spec/unit/shared/models_unit_specs.rb +15 -0
  124. data/spec/unit/shared/named_models_unit_specs.rb +39 -0
  125. data/spec/unit/shared/nested_models_unit_specs.rb +51 -0
  126. data/spec/unit/shared/parsed_models_unit_specs.rb +39 -0
  127. data/spec/unit/shared/prepopulated_models_unit_specs.rb +18 -0
  128. data/spec/unit/shared/sourced_models_unit_specs.rb +39 -0
  129. data/spec/unit/shared/stepped_models_unit_specs.rb +46 -0
  130. data/spec/unit/shared/stringifiable_models_unit_specs.rb +18 -0
  131. data/spec/unit/shared/tagged_models_unit_specs.rb +72 -0
  132. data/spec/unit/sourceable_unit_spec.rb +12 -4
  133. data/spec/unit/step_unit_spec.rb +40 -231
  134. data/spec/unit/stepped_unit_spec.rb +23 -0
  135. data/spec/unit/table_unit_spec.rb +27 -89
  136. data/spec/unit/tag_unit_spec.rb +30 -53
  137. data/spec/unit/taggable_unit_spec.rb +26 -42
  138. data/todo.txt +32 -0
  139. metadata +135 -217
  140. data/features/analysis/test_manipulation.feature +0 -37
  141. data/features/modeling/gherkin/background_modeling.feature +0 -65
  142. data/features/modeling/gherkin/background_output.feature +0 -131
  143. data/features/modeling/gherkin/directory_modeling.feature +0 -110
  144. data/features/modeling/gherkin/directory_output.feature +0 -14
  145. data/features/modeling/gherkin/doc_string_modeling.feature +0 -53
  146. data/features/modeling/gherkin/doc_string_output.feature +0 -72
  147. data/features/modeling/gherkin/example_modeling.feature +0 -101
  148. data/features/modeling/gherkin/example_output.feature +0 -193
  149. data/features/modeling/gherkin/feature_file_modeling.feature +0 -54
  150. data/features/modeling/gherkin/feature_file_output.feature +0 -14
  151. data/features/modeling/gherkin/feature_modeling.feature +0 -154
  152. data/features/modeling/gherkin/feature_output.feature +0 -245
  153. data/features/modeling/gherkin/outline_modeling.feature +0 -90
  154. data/features/modeling/gherkin/outline_output.feature +0 -198
  155. data/features/modeling/gherkin/row_modeling.feature +0 -68
  156. data/features/modeling/gherkin/row_output.feature +0 -28
  157. data/features/modeling/gherkin/scenario_modeling.feature +0 -79
  158. data/features/modeling/gherkin/scenario_output.feature +0 -148
  159. data/features/modeling/gherkin/step_modeling.feature +0 -75
  160. data/features/modeling/gherkin/step_output.feature +0 -53
  161. data/features/modeling/gherkin/table_modeling.feature +0 -42
  162. data/features/modeling/gherkin/table_output.feature +0 -43
  163. data/features/modeling/gherkin/table_row_modeling.feature +0 -57
  164. data/features/modeling/gherkin/table_row_output.feature +0 -28
  165. data/features/modeling/gherkin/tag_modeling.feature +0 -48
  166. data/features/modeling/gherkin/tag_output.feature +0 -17
  167. data/features/modeling/gherkin3/background_modeling.feature +0 -64
  168. data/features/modeling/gherkin3/background_output.feature +0 -131
  169. data/features/modeling/gherkin3/directory_modeling.feature +0 -110
  170. data/features/modeling/gherkin3/directory_output.feature +0 -14
  171. data/features/modeling/gherkin3/doc_string_modeling.feature +0 -53
  172. data/features/modeling/gherkin3/doc_string_output.feature +0 -72
  173. data/features/modeling/gherkin3/example_modeling.feature +0 -100
  174. data/features/modeling/gherkin3/example_output.feature +0 -207
  175. data/features/modeling/gherkin3/feature_file_modeling.feature +0 -54
  176. data/features/modeling/gherkin3/feature_file_output.feature +0 -14
  177. data/features/modeling/gherkin3/feature_modeling.feature +0 -155
  178. data/features/modeling/gherkin3/feature_output.feature +0 -249
  179. data/features/modeling/gherkin3/outline_modeling.feature +0 -89
  180. data/features/modeling/gherkin3/outline_output.feature +0 -255
  181. data/features/modeling/gherkin3/row_modeling.feature +0 -68
  182. data/features/modeling/gherkin3/row_output.feature +0 -28
  183. data/features/modeling/gherkin3/scenario_modeling.feature +0 -78
  184. data/features/modeling/gherkin3/scenario_output.feature +0 -148
  185. data/features/modeling/gherkin3/step_modeling.feature +0 -75
  186. data/features/modeling/gherkin3/step_output.feature +0 -53
  187. data/features/modeling/gherkin3/table_modeling.feature +0 -42
  188. data/features/modeling/gherkin3/table_output.feature +0 -43
  189. data/features/modeling/gherkin3/table_row_modeling.feature +0 -57
  190. data/features/modeling/gherkin3/table_row_output.feature +0 -28
  191. data/features/modeling/gherkin3/tag_modeling.feature +0 -49
  192. data/features/modeling/gherkin3/tag_output.feature +0 -17
  193. data/features/modeling/gherkin4/background_modeling.feature +0 -64
  194. data/features/modeling/gherkin4/background_output.feature +0 -131
  195. data/features/modeling/gherkin4/directory_modeling.feature +0 -110
  196. data/features/modeling/gherkin4/directory_output.feature +0 -14
  197. data/features/modeling/gherkin4/doc_string_modeling.feature +0 -53
  198. data/features/modeling/gherkin4/doc_string_output.feature +0 -72
  199. data/features/modeling/gherkin4/example_modeling.feature +0 -100
  200. data/features/modeling/gherkin4/example_output.feature +0 -193
  201. data/features/modeling/gherkin4/feature_file_modeling.feature +0 -54
  202. data/features/modeling/gherkin4/feature_file_output.feature +0 -14
  203. data/features/modeling/gherkin4/feature_modeling.feature +0 -153
  204. data/features/modeling/gherkin4/feature_output.feature +0 -245
  205. data/features/modeling/gherkin4/outline_modeling.feature +0 -89
  206. data/features/modeling/gherkin4/outline_output.feature +0 -198
  207. data/features/modeling/gherkin4/row_modeling.feature +0 -68
  208. data/features/modeling/gherkin4/row_output.feature +0 -28
  209. data/features/modeling/gherkin4/scenario_modeling.feature +0 -78
  210. data/features/modeling/gherkin4/scenario_output.feature +0 -148
  211. data/features/modeling/gherkin4/step_modeling.feature +0 -75
  212. data/features/modeling/gherkin4/step_output.feature +0 -53
  213. data/features/modeling/gherkin4/table_modeling.feature +0 -42
  214. data/features/modeling/gherkin4/table_output.feature +0 -43
  215. data/features/modeling/gherkin4/table_row_modeling.feature +0 -57
  216. data/features/modeling/gherkin4/table_row_output.feature +0 -28
  217. data/features/modeling/gherkin4/tag_modeling.feature +0 -48
  218. data/features/modeling/gherkin4/tag_output.feature +0 -17
  219. data/features/step_definitions/outline_steps.rb +0 -258
  220. data/features/step_definitions/test_steps.rb +0 -123
  221. data/lib/cuke_modeler/background.rb +0 -38
  222. data/lib/cuke_modeler/directory.rb +0 -83
  223. data/lib/cuke_modeler/doc_string.rb +0 -87
  224. data/lib/cuke_modeler/example.rb +0 -195
  225. data/lib/cuke_modeler/feature.rb +0 -147
  226. data/lib/cuke_modeler/feature_element.rb +0 -73
  227. data/lib/cuke_modeler/feature_file.rb +0 -77
  228. data/lib/cuke_modeler/outline.rb +0 -68
  229. data/lib/cuke_modeler/raw.rb +0 -20
  230. data/lib/cuke_modeler/row.rb +0 -64
  231. data/lib/cuke_modeler/scenario.rb +0 -45
  232. data/lib/cuke_modeler/step.rb +0 -216
  233. data/lib/cuke_modeler/table.rb +0 -90
  234. data/lib/cuke_modeler/table_row.rb +0 -64
  235. data/lib/cuke_modeler/tag.rb +0 -62
  236. data/lib/cuke_modeler/test_element.rb +0 -79
  237. data/lib/cuke_modeler/world.rb +0 -113
  238. data/spec/integration/table_row_integration_spec.rb +0 -76
  239. data/spec/integration/world_integration_spec.rb +0 -14
  240. data/spec/unit/containing_element_unit_specs.rb +0 -18
  241. data/spec/unit/feature_element_unit_spec.rb +0 -19
  242. data/spec/unit/feature_element_unit_specs.rb +0 -52
  243. data/spec/unit/nested_element_unit_specs.rb +0 -39
  244. data/spec/unit/prepopulated_unit_specs.rb +0 -14
  245. data/spec/unit/raw_element_unit_specs.rb +0 -27
  246. data/spec/unit/raw_unit_spec.rb +0 -28
  247. data/spec/unit/sourced_element_unit_specs.rb +0 -18
  248. data/spec/unit/table_row_unit_spec.rb +0 -102
  249. data/spec/unit/tagged_element_unit_specs.rb +0 -67
  250. data/spec/unit/test_element_unit_spec.rb +0 -54
  251. data/spec/unit/test_element_unit_specs.rb +0 -34
  252. data/spec/unit/world_unit_spec.rb +0 -140
@@ -0,0 +1,85 @@
1
+ require 'spec_helper'
2
+
3
+
4
+ describe 'Parsing, Integration' do
5
+
6
+ let(:nodule) { CukeModeler::Parsing }
7
+
8
+
9
+ describe 'unique behavior' do
10
+
11
+
12
+ it 'raises and error if given something to parse besides a string' do
13
+ expect { nodule.parse_text(5) }.to raise_error(ArgumentError, /Text to parse must be a String but got/)
14
+ expect { nodule.parse_text('Feature:') }.to_not raise_error
15
+ end
16
+
17
+ it 'includes the type of object provided when raising an non-string exception' do
18
+ expect { nodule.parse_text(5) }.to raise_error(ArgumentError, /Fixnum/)
19
+ end
20
+
21
+ it 'returns an Array' do
22
+ result = nodule.parse_text('Feature:')
23
+ expect(result).to be_a(Array)
24
+ end
25
+
26
+ it 'raises and error if an error is encountered while parsing text' do
27
+ expect { nodule.parse_text('bad file') }.to raise_error(ArgumentError, /Error encountered while parsing '.*'/)
28
+ end
29
+
30
+ it 'includes the file parsed in the error that it raises' do
31
+ expect { nodule.parse_text('bad file', 'file foo.txt') }.to raise_error(/'file foo\.txt'/)
32
+ end
33
+
34
+ it 'includes the underlying error message in the error that it raises' do
35
+ begin
36
+ # Custom error type in order to ensure that we are throwing the correct thing
37
+ module CukeModeler
38
+ class TestError < StandardError
39
+ end
40
+ end
41
+
42
+ # Monkey patch Gherkin to throw the error that we need for testing
43
+ if Gem.loaded_specs['gherkin'].version.version[/^3|4/]
44
+ old_method = Gherkin::Parser.instance_method(:parse)
45
+
46
+ module Gherkin
47
+ class Parser
48
+ def parse(*args)
49
+ raise(CukeModeler::TestError, 'something went wrong')
50
+ end
51
+ end
52
+ end
53
+ else
54
+ old_method = Gherkin::Parser::Parser.instance_method(:parse)
55
+
56
+ module Gherkin
57
+ module Parser
58
+ class Parser
59
+ def parse(*args)
60
+ raise(CukeModeler::TestError, 'something went wrong')
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
66
+
67
+ expect { nodule.parse_text('bad file') }.to raise_error(/CukeModeler::TestError.*something went wrong/)
68
+ ensure
69
+ # Making sure that our changes don't escape a test and ruin the rest of the suite
70
+ if Gem.loaded_specs['gherkin'].version.version[/^3|4/]
71
+ Gherkin::Parser.send(:define_method, :parse, old_method)
72
+ else
73
+ Gherkin::Parser::Parser.send(:define_method, :parse, old_method)
74
+ end
75
+ end
76
+
77
+ end
78
+
79
+ it 'has a default file name if one is not provided' do
80
+ expect { nodule.parse_text('bad file') }.to raise_error(ArgumentError, /'cuke_modeler_fake_file\.feature'/)
81
+ end
82
+
83
+ end
84
+
85
+ end
@@ -1,24 +1,76 @@
1
1
  require 'spec_helper'
2
2
 
3
- SimpleCov.command_name('Row') unless RUBY_VERSION.to_s < '1.9.0'
4
3
 
5
4
  describe 'Row, Integration' do
6
5
 
7
6
  let(:clazz) { CukeModeler::Row }
8
7
 
9
8
 
9
+ describe 'common behavior' do
10
+
11
+ it_should_behave_like 'a model, integration'
12
+
13
+ end
14
+
15
+
10
16
  describe 'unique behavior' do
11
17
 
18
+ it 'can be instantiated with the minimum viable Gherkin' do
19
+ source = '| a | row |'
20
+
21
+ expect { clazz.new(source) }.to_not raise_error
22
+ end
23
+
24
+ it 'provides a descriptive filename when being parsed from stand alone text' do
25
+ source = " |bad |row| text| \n @foo "
26
+
27
+ expect { clazz.new(source) }.to raise_error(/'cuke_modeler_stand_alone_row\.feature'/)
28
+ end
29
+
30
+ it 'stores the original data generated by the parsing adapter', :gherkin4 => true do
31
+ example_row = clazz.new("| a | row |")
32
+ data = example_row.parsing_data
33
+
34
+ expect(data.keys).to match_array([:type, :location, :cells])
35
+ expect(data[:type]).to eq(:TableRow)
36
+ end
37
+
38
+ it 'stores the original data generated by the parsing adapter', :gherkin3 => true do
39
+ example_row = clazz.new("| a | row |")
40
+ data = example_row.parsing_data
41
+
42
+ expect(data.keys).to match_array([:type, :location, :cells])
43
+ expect(data[:type]).to eq('TableRow')
44
+ end
45
+
46
+ it 'stores the original data generated by the parsing adapter', :gherkin2 => true do
47
+ example_row = clazz.new("| a | row |")
48
+ data = example_row.parsing_data
49
+
50
+ expect(data.keys).to match_array(['cells', 'line'])
51
+ expect(data['line']).to eq(4)
52
+ end
53
+
54
+ it 'properly sets its child models' do
55
+ source = '| cell 1 | cell 2 |'
56
+
57
+ row = clazz.new(source)
58
+ cell_1 = row.cells.first
59
+ cell_2 = row.cells.last
60
+
61
+ expect(cell_1.parent_model).to equal(row)
62
+ expect(cell_2.parent_model).to equal(row)
63
+ end
64
+
65
+
12
66
  describe 'getting ancestors' do
13
67
 
14
68
  before(:each) do
15
69
  source = ['Feature: Test feature',
16
70
  '',
17
- ' Scenario Outline: Test test',
18
- ' * a step',
19
- ' Examples: Test example',
20
- ' | a param |',
21
- ' | a value |']
71
+ ' Scenario: Test test',
72
+ ' * a step:',
73
+ ' | a | table |']
22
74
  source = source.join("\n")
23
75
 
24
76
  file_path = "#{@default_file_directory}/row_test_file.feature"
@@ -26,43 +78,194 @@ describe 'Row, Integration' do
26
78
  end
27
79
 
28
80
  let(:directory) { CukeModeler::Directory.new(@default_file_directory) }
29
- let(:row) { directory.feature_files.first.features.first.tests.first.examples.first.row_elements.first }
81
+ let(:row) { directory.feature_files.first.feature.tests.first.steps.first.block.rows.first }
30
82
 
31
83
 
32
84
  it 'can get its directory' do
33
85
  ancestor = row.get_ancestor(:directory)
34
86
 
35
- ancestor.should equal directory
87
+ expect(ancestor).to equal(directory)
36
88
  end
37
89
 
38
90
  it 'can get its feature file' do
39
91
  ancestor = row.get_ancestor(:feature_file)
40
92
 
41
- ancestor.should equal directory.feature_files.first
93
+ expect(ancestor).to equal(directory.feature_files.first)
42
94
  end
43
95
 
44
96
  it 'can get its feature' do
45
97
  ancestor = row.get_ancestor(:feature)
46
98
 
47
- ancestor.should equal directory.feature_files.first.features.first
99
+ expect(ancestor).to equal(directory.feature_files.first.feature)
100
+ end
101
+
102
+ it 'can get its step' do
103
+ ancestor = row.get_ancestor(:step)
104
+
105
+ expect(ancestor).to equal(directory.feature_files.first.feature.tests.first.steps.first)
106
+ end
107
+
108
+ it 'can get its table' do
109
+ ancestor = row.get_ancestor(:table)
110
+
111
+ expect(ancestor).to equal(directory.feature_files.first.feature.tests.first.steps.first.block)
112
+ end
113
+
114
+ context 'a row that is part of a scenario' do
115
+
116
+ before(:each) do
117
+ source = 'Feature: Test feature
118
+
119
+ Scenario: Test test
120
+ * a step:
121
+ | a | table |'
122
+
123
+ file_path = "#{@default_file_directory}/row_test_file.feature"
124
+ File.open(file_path, 'w') { |file| file.write(source) }
125
+ end
126
+
127
+ let(:directory) { CukeModeler::Directory.new(@default_file_directory) }
128
+ let(:row) { directory.feature_files.first.feature.tests.first.steps.first.block.rows.first }
129
+
130
+
131
+ it 'can get its scenario' do
132
+ ancestor = row.get_ancestor(:scenario)
133
+
134
+ expect(ancestor).to equal(directory.feature_files.first.feature.tests.first)
135
+ end
136
+
48
137
  end
49
138
 
50
- it 'can get its test' do
51
- ancestor = row.get_ancestor(:test)
52
139
 
53
- ancestor.should equal directory.feature_files.first.features.first.tests.first
140
+ context 'a row that is part of a background' do
141
+
142
+ before(:each) do
143
+ source = 'Feature: Test feature
144
+
145
+ Background: Test background
146
+ * a step:
147
+ | a | table |'
148
+
149
+ file_path = "#{@default_file_directory}/row_test_file.feature"
150
+ File.open(file_path, 'w') { |file| file.write(source) }
151
+ end
152
+
153
+ let(:directory) { CukeModeler::Directory.new(@default_file_directory) }
154
+ let(:row) { directory.feature_files.first.feature.background.steps.first.block.rows.first }
155
+
156
+
157
+ it 'can get its background' do
158
+ ancestor = row.get_ancestor(:background)
159
+
160
+ expect(ancestor).to equal(directory.feature_files.first.feature.background)
161
+ end
162
+
54
163
  end
55
164
 
56
- it 'can get its example' do
57
- ancestor = row.get_ancestor(:example)
165
+ context 'a row that is part of an outline' do
166
+
167
+ before(:each) do
168
+ source = 'Feature: Test feature
169
+
170
+ Scenario Outline: Test outline
171
+ * a step
172
+ Examples:
173
+ | param |
174
+ | value |'
175
+
176
+ file_path = "#{@default_file_directory}/row_test_file.feature"
177
+ File.open(file_path, 'w') { |file| file.write(source) }
178
+ end
179
+
180
+ let(:directory) { CukeModeler::Directory.new(@default_file_directory) }
181
+ let(:row) { directory.feature_files.first.feature.tests.first.examples.first.rows.first }
182
+
183
+
184
+ it 'can get its outline' do
185
+ ancestor = row.get_ancestor(:outline)
186
+
187
+ expect(ancestor).to equal(directory.feature_files.first.feature.tests.first)
188
+ end
189
+
190
+ it 'can get its example' do
191
+ ancestor = row.get_ancestor(:example)
192
+
193
+ expect(ancestor).to equal(directory.feature_files.first.feature.tests.first.examples.first)
194
+ end
58
195
 
59
- ancestor.should equal directory.feature_files.first.features.first.tests.first.examples.first
60
196
  end
61
197
 
62
198
  it 'returns nil if it does not have the requested type of ancestor' do
63
- ancestor = row.get_ancestor(:table)
199
+ ancestor = row.get_ancestor(:outline)
200
+
201
+ expect(ancestor).to be_nil
202
+ end
203
+
204
+ end
205
+
206
+
207
+ describe 'model population' do
208
+
209
+ context 'from source text' do
210
+
211
+ let(:source_text) { '| cell 1 | cell 2 |' }
212
+ let(:row) { clazz.new(source_text) }
213
+
214
+
215
+ it "models the row's cells" do
216
+ cell_values = row.cells.collect { |cell| cell.value }
217
+
218
+ expect(cell_values).to match_array(['cell 1', 'cell 2'])
219
+ end
220
+
221
+ it "models the row's source line" do
222
+ source_text = "Feature: Test feature
223
+
224
+ Scenario Outline: Test outline
225
+ * a step
226
+ Examples:
227
+ | param |
228
+ | value |"
229
+ row = CukeModeler::Feature.new(source_text).tests.first.examples.first.rows.first
230
+
231
+ expect(row.source_line).to eq(6)
232
+ end
233
+
234
+ end
235
+
236
+ end
237
+
238
+
239
+ describe 'row output' do
240
+
241
+ it 'can be remade from its own output' do
242
+ source = ['| value1 | value2 |']
243
+ source = source.join("\n")
244
+ row = clazz.new(source)
245
+
246
+ row_output = row.to_s
247
+ remade_row_output = clazz.new(row_output).to_s
248
+
249
+ expect(remade_row_output).to eq(row_output)
250
+ end
251
+
252
+
253
+ context 'from source text' do
254
+
255
+ it 'can output a row' do
256
+ source = '| some value |'
257
+ row = clazz.new(source)
258
+
259
+ expect(row.to_s).to eq('| some value |')
260
+ end
261
+
262
+ it 'can output a row with multiple cells' do
263
+ source = '| some value | some other value |'
264
+ row = clazz.new(source)
265
+
266
+ expect(row.to_s).to eq('| some value | some other value |')
267
+ end
64
268
 
65
- ancestor.should be_nil
66
269
  end
67
270
 
68
271
  end
@@ -1,15 +1,56 @@
1
1
  require 'spec_helper'
2
2
 
3
- SimpleCov.command_name('Scenario') unless RUBY_VERSION.to_s < '1.9.0'
4
3
 
5
4
  describe 'Scenario, Integration' do
6
5
 
7
6
  let(:clazz) { CukeModeler::Scenario }
8
7
 
9
8
 
9
+ describe 'common behavior' do
10
+
11
+ it_should_behave_like 'a model, integration'
12
+
13
+ end
14
+
10
15
  describe 'unique behavior' do
11
16
 
12
- it 'properly sets its child elements' do
17
+ it 'can be instantiated with the minimum viable Gherkin' do
18
+ source = 'Scenario:'
19
+
20
+ expect { clazz.new(source) }.to_not raise_error
21
+ end
22
+
23
+ it 'provides a descriptive filename when being parsed from stand alone text' do
24
+ source = "bad scenario text \n Scenario:\n And a step\n @foo "
25
+
26
+ expect { clazz.new(source) }.to raise_error(/'cuke_modeler_stand_alone_scenario\.feature'/)
27
+ end
28
+
29
+ it 'stores the original data generated by the parsing adapter', :gherkin4 => true do
30
+ scenario = clazz.new("@tag\nScenario: test scenario\ndescription\n* a step")
31
+ data = scenario.parsing_data
32
+
33
+ expect(data.keys).to match_array([:type, :tags, :location, :keyword, :name, :steps, :description])
34
+ expect(data[:type]).to eq(:Scenario)
35
+ end
36
+
37
+ it 'stores the original data generated by the parsing adapter', :gherkin3 => true do
38
+ scenario = clazz.new("@tag\nScenario: test scenario\ndescription\n* a step")
39
+ data = scenario.parsing_data
40
+
41
+ expect(data.keys).to match_array([:type, :tags, :location, :keyword, :name, :steps, :description])
42
+ expect(data[:type]).to eq(:Scenario)
43
+ end
44
+
45
+ it 'stores the original data generated by the parsing adapter', :gherkin2 => true do
46
+ scenario = clazz.new("@tag\nScenario: test scenario\ndescription\n* a step")
47
+ data = scenario.parsing_data
48
+
49
+ expect(data.keys).to match_array(['keyword', 'name', 'line', 'description', 'id', 'type', 'steps', 'tags'])
50
+ expect(data['keyword']).to eq('Scenario')
51
+ end
52
+
53
+ it 'properly sets its child models' do
13
54
  source = ['@a_tag',
14
55
  'Scenario: Test scenario',
15
56
  ' * a step']
@@ -17,10 +58,32 @@ describe 'Scenario, Integration' do
17
58
 
18
59
  scenario = clazz.new(source)
19
60
  step = scenario.steps.first
20
- tag = scenario.tag_elements.first
61
+ tag = scenario.tags.first
62
+
63
+ expect(step.parent_model).to equal(scenario)
64
+ expect(tag.parent_model).to equal(scenario)
65
+ end
21
66
 
22
- step.parent_element.should equal scenario
23
- tag.parent_element.should equal scenario
67
+ it 'trims whitespace from its source description' do
68
+ source = ['Scenario:',
69
+ ' ',
70
+ ' description line 1',
71
+ '',
72
+ ' description line 2',
73
+ ' description line 3 ',
74
+ '',
75
+ '',
76
+ '',
77
+ ' * a step']
78
+ source = source.join("\n")
79
+
80
+ scenario = clazz.new(source)
81
+ description = scenario.description.split("\n")
82
+
83
+ expect(description).to eq([' description line 1',
84
+ '',
85
+ 'description line 2',
86
+ ' description line 3'])
24
87
  end
25
88
 
26
89
 
@@ -38,42 +101,331 @@ describe 'Scenario, Integration' do
38
101
  end
39
102
 
40
103
  let(:directory) { CukeModeler::Directory.new(@default_file_directory) }
41
- let(:scenario) { directory.feature_files.first.features.first.tests.first }
104
+ let(:scenario) { directory.feature_files.first.feature.tests.first }
42
105
 
43
106
 
44
107
  it 'can get its directory' do
45
108
  ancestor = scenario.get_ancestor(:directory)
46
109
 
47
- ancestor.should equal directory
110
+ expect(ancestor).to equal(directory)
48
111
  end
49
112
 
50
113
  it 'can get its feature file' do
51
114
  ancestor = scenario.get_ancestor(:feature_file)
52
115
 
53
- ancestor.should equal directory.feature_files.first
116
+ expect(ancestor).to equal(directory.feature_files.first)
54
117
  end
55
118
 
56
119
  it 'can get its feature' do
57
120
  ancestor = scenario.get_ancestor(:feature)
58
121
 
59
- ancestor.should equal directory.feature_files.first.features.first
122
+ expect(ancestor).to equal(directory.feature_files.first.feature)
60
123
  end
61
124
 
62
125
  it 'returns nil if it does not have the requested type of ancestor' do
63
126
  ancestor = scenario.get_ancestor(:test)
64
127
 
65
- ancestor.should be_nil
128
+ expect(ancestor).to be_nil
66
129
  end
67
130
 
68
- describe 'scenario output edge cases' do
69
131
 
70
- context 'a new scenario object' do
132
+ describe 'model population' do
133
+
134
+ context 'from source text' do
135
+
136
+ it "models the scenario's source line" do
137
+ source_text = "Feature:
138
+
139
+ Scenario: foo
140
+ * step"
141
+ scenario = CukeModeler::Feature.new(source_text).tests.first
142
+
143
+ expect(scenario.source_line).to eq(3)
144
+ end
145
+
146
+
147
+ context 'a filled scenario' do
148
+
149
+ let(:source_text) { '@tag1 @tag2 @tag3
150
+ Scenario: Scenario name
151
+
152
+ Scenario description.
153
+
154
+ Some more.
155
+ Even more.
156
+
157
+ * a step
158
+ * another step' }
159
+ let(:scenario) { clazz.new(source_text) }
160
+
161
+
162
+ it "models the scenario's name" do
163
+ expect(scenario.name).to eq('Scenario name')
164
+ end
165
+
166
+ it "models the scenario's description" do
167
+ description = scenario.description.split("\n")
168
+
169
+ expect(description).to eq([' Scenario description.',
170
+ '',
171
+ 'Some more.',
172
+ ' Even more.'])
173
+ end
174
+
175
+ it "models the scenario's steps" do
176
+ step_names = scenario.steps.collect { |step| step.text }
177
+
178
+ expect(step_names).to eq(['a step', 'another step'])
179
+ end
180
+
181
+ it "models the scenario's tags" do
182
+ tag_names = scenario.tags.collect { |tag| tag.name }
183
+
184
+ expect(tag_names).to eq(['@tag1', '@tag2', '@tag3'])
185
+ end
186
+
187
+ end
188
+
189
+ context 'an empty scenario' do
190
+
191
+ let(:source_text) { 'Scenario:' }
192
+ let(:scenario) { clazz.new(source_text) }
193
+
194
+
195
+ it "models the scenario's name" do
196
+ expect(scenario.name).to eq('')
197
+ end
198
+
199
+ it "models the scenario's description" do
200
+ expect(scenario.description).to eq('')
201
+ end
202
+
203
+ it "models the scenario's steps" do
204
+ expect(scenario.steps).to eq([])
205
+ end
206
+
207
+ it "models the scenario's tags" do
208
+ expect(scenario.tags).to eq([])
209
+ end
210
+
211
+ end
212
+
213
+ end
214
+
215
+ end
216
+
217
+
218
+ describe 'comparison' do
219
+
220
+ it 'is equal to a background with the same steps' do
221
+ source = "Scenario:
222
+ * step 1
223
+ * step 2"
224
+ scenario = clazz.new(source)
225
+
226
+ source = "Background:
227
+ * step 1
228
+ * step 2"
229
+ background_1 = CukeModeler::Background.new(source)
230
+
231
+ source = "Background:
232
+ * step 2
233
+ * step 1"
234
+ background_2 = CukeModeler::Background.new(source)
235
+
236
+
237
+ expect(scenario).to eq(background_1)
238
+ expect(scenario).to_not eq(background_2)
239
+ end
240
+
241
+ it 'is equal to a scenario with the same steps' do
242
+ source = "Scenario:
243
+ * step 1
244
+ * step 2"
245
+ scenario_1 = clazz.new(source)
246
+
247
+ source = "Scenario:
248
+ * step 1
249
+ * step 2"
250
+ scenario_2 = clazz.new(source)
251
+
252
+ source = "Scenario:
253
+ * step 2
254
+ * step 1"
255
+ scenario_3 = clazz.new(source)
256
+
257
+
258
+ expect(scenario_1).to eq(scenario_2)
259
+ expect(scenario_1).to_not eq(scenario_3)
260
+ end
261
+
262
+ it 'is equal to an outline with the same steps' do
263
+ source = "Scenario:
264
+ * step 1
265
+ * step 2"
266
+ scenario = clazz.new(source)
267
+
268
+ source = "Scenario Outline:
269
+ * step 1
270
+ * step 2
271
+ Examples:
272
+ | param |
273
+ | value |"
274
+ outline_1 = CukeModeler::Outline.new(source)
275
+
276
+ source = "Scenario Outline:
277
+ * step 2
278
+ * step 1
279
+ Examples:
280
+ | param |
281
+ | value |"
282
+ outline_2 = CukeModeler::Outline.new(source)
283
+
284
+
285
+ expect(scenario).to eq(outline_1)
286
+ expect(scenario).to_not eq(outline_2)
287
+ end
288
+
289
+ end
290
+
291
+
292
+ describe 'scenario output' do
293
+
294
+ it 'can be remade from its own output' do
295
+ source = ['@tag1 @tag2 @tag3',
296
+ 'Scenario: A scenario with everything it could have',
297
+ '',
298
+ 'Including a description',
299
+ 'and then some.',
300
+ '',
301
+ ' * a step',
302
+ ' | value |',
303
+ ' * another step',
304
+ ' """',
305
+ ' some string',
306
+ ' """']
307
+ source = source.join("\n")
308
+ scenario = clazz.new(source)
309
+
310
+ scenario_output = scenario.to_s
311
+ remade_scenario_output = clazz.new(scenario_output).to_s
312
+
313
+ expect(remade_scenario_output).to eq(scenario_output)
314
+ end
315
+
316
+
317
+ context 'from source text' do
318
+
319
+ it 'can output an empty scenario' do
320
+ source = ['Scenario:']
321
+ source = source.join("\n")
322
+ scenario = clazz.new(source)
323
+
324
+ scenario_output = scenario.to_s.split("\n")
325
+
326
+ expect(scenario_output).to eq(['Scenario:'])
327
+ end
328
+
329
+ it 'can output a scenario that has a name' do
330
+ source = ['Scenario: test scenario']
331
+ source = source.join("\n")
332
+ scenario = clazz.new(source)
333
+
334
+ scenario_output = scenario.to_s.split("\n")
335
+
336
+ expect(scenario_output).to eq(['Scenario: test scenario'])
337
+ end
338
+
339
+ it 'can output a scenario that has a description' do
340
+ source = ['Scenario:',
341
+ 'Some description.',
342
+ 'Some more description.']
343
+ source = source.join("\n")
344
+ scenario = clazz.new(source)
345
+
346
+ scenario_output = scenario.to_s.split("\n")
347
+
348
+ expect(scenario_output).to eq(['Scenario:',
349
+ '',
350
+ 'Some description.',
351
+ 'Some more description.'])
352
+ end
353
+
354
+ it 'can output a scenario that has steps' do
355
+ source = ['Scenario:',
356
+ '* a step',
357
+ '|value|',
358
+ '* another step',
359
+ '"""',
360
+ 'some string',
361
+ '"""']
362
+ source = source.join("\n")
363
+ scenario = clazz.new(source)
364
+
365
+ scenario_output = scenario.to_s.split("\n")
366
+
367
+ expect(scenario_output).to eq(['Scenario:',
368
+ ' * a step',
369
+ ' | value |',
370
+ ' * another step',
371
+ ' """',
372
+ ' some string',
373
+ ' """'])
374
+ end
375
+
376
+ it 'can output a scenario that has tags' do
377
+ source = ['@tag1 @tag2',
378
+ '@tag3',
379
+ 'Scenario:']
380
+ source = source.join("\n")
381
+ scenario = clazz.new(source)
382
+
383
+ scenario_output = scenario.to_s.split("\n")
384
+
385
+ expect(scenario_output).to eq(['@tag1 @tag2 @tag3',
386
+ 'Scenario:'])
387
+ end
388
+
389
+ it 'can output a scenario that has everything' do
390
+ source = ['@tag1 @tag2 @tag3',
391
+ 'Scenario: A scenario with everything it could have',
392
+ 'Including a description',
393
+ 'and then some.',
394
+ '* a step',
395
+ '|value|',
396
+ '* another step',
397
+ '"""',
398
+ 'some string',
399
+ '"""']
400
+ source = source.join("\n")
401
+ scenario = clazz.new(source)
402
+
403
+ scenario_output = scenario.to_s.split("\n")
404
+
405
+ expect(scenario_output).to eq(['@tag1 @tag2 @tag3',
406
+ 'Scenario: A scenario with everything it could have',
407
+ '',
408
+ 'Including a description',
409
+ 'and then some.',
410
+ '',
411
+ ' * a step',
412
+ ' | value |',
413
+ ' * another step',
414
+ ' """',
415
+ ' some string',
416
+ ' """'])
417
+ end
418
+
419
+ end
420
+
421
+
422
+ context 'from abstract instantiation' do
71
423
 
72
424
  let(:scenario) { clazz.new }
73
425
 
74
426
 
75
- it 'can output a scenario that has only tag elements' do
76
- scenario.tag_elements = [CukeModeler::Tag.new]
427
+ it 'can output a scenario that has only tags' do
428
+ scenario.tags = [CukeModeler::Tag.new]
77
429
 
78
430
  expect { scenario.to_s }.to_not raise_error
79
431
  end
@@ -93,3 +445,5 @@ describe 'Scenario, Integration' do
93
445
  end
94
446
 
95
447
  end
448
+
449
+