cuke_modeler 1.1.1 → 1.2.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 (40) hide show
  1. checksums.yaml +4 -4
  2. data/History.md +5 -0
  3. data/lib/cuke_modeler/adapters/gherkin_2_adapter.rb +77 -22
  4. data/lib/cuke_modeler/adapters/gherkin_3_adapter.rb +25 -1
  5. data/lib/cuke_modeler/adapters/gherkin_4_adapter.rb +25 -1
  6. data/lib/cuke_modeler/containing.rb +15 -0
  7. data/lib/cuke_modeler/models/background.rb +1 -1
  8. data/lib/cuke_modeler/models/cell.rb +1 -1
  9. data/lib/cuke_modeler/models/comment.rb +47 -0
  10. data/lib/cuke_modeler/models/directory.rb +2 -5
  11. data/lib/cuke_modeler/models/doc_string.rb +1 -1
  12. data/lib/cuke_modeler/models/example.rb +1 -1
  13. data/lib/cuke_modeler/models/feature.rb +1 -1
  14. data/lib/cuke_modeler/models/feature_file.rb +8 -5
  15. data/lib/cuke_modeler/models/outline.rb +1 -1
  16. data/lib/cuke_modeler/models/row.rb +1 -1
  17. data/lib/cuke_modeler/models/scenario.rb +1 -1
  18. data/lib/cuke_modeler/models/step.rb +1 -1
  19. data/lib/cuke_modeler/models/table.rb +1 -1
  20. data/lib/cuke_modeler/models/tag.rb +1 -1
  21. data/lib/cuke_modeler/version.rb +1 -1
  22. data/lib/cuke_modeler.rb +1 -0
  23. data/testing/cucumber/features/modeling/comment_modeling.feature +43 -0
  24. data/testing/cucumber/features/modeling/comment_output.feature +27 -0
  25. data/testing/cucumber/features/modeling/feature_file_modeling.feature +11 -0
  26. data/testing/cucumber/features/modeling/model_structure.feature +2 -2
  27. data/testing/cucumber/features/modeling/tag_output.feature +1 -1
  28. data/testing/cucumber/step_definitions/feature_file_steps.rb +10 -0
  29. data/testing/cucumber/step_definitions/setup_steps.rb +6 -0
  30. data/testing/cucumber/step_definitions/verification_steps.rb +7 -1
  31. data/testing/rspec/spec/integration/comment_integration_spec.rb +168 -0
  32. data/testing/rspec/spec/integration/feature_file_integration_spec.rb +124 -0
  33. data/testing/rspec/spec/integration/gherkin_2_adapter_spec.rb +36 -3
  34. data/testing/rspec/spec/integration/gherkin_3_adapter_spec.rb +28 -4
  35. data/testing/rspec/spec/integration/gherkin_4_adapter_spec.rb +28 -3
  36. data/testing/rspec/spec/integration/parsing_integration_spec.rb +1 -0
  37. data/testing/rspec/spec/unit/comment_unit_spec.rb +74 -0
  38. data/testing/rspec/spec/unit/feature_file_unit_spec.rb +18 -0
  39. data/todo.txt +2 -0
  40. metadata +7 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 75c21d56686546ac790c590dda83628ca4eadd92
4
- data.tar.gz: 6094f26c8873cfbf4040318ca163a34370432f20
3
+ metadata.gz: ae2a37ad321f1cf9ea164210a52981ed565a2f5c
4
+ data.tar.gz: 2eaf5c8db10ddfba8c9ff2a0a0b61198929d98f7
5
5
  SHA512:
6
- metadata.gz: 78783c9af83fb27735e80bc5f327320224e6ee53260fed2ad89dbf925c4086eb6baac5c2bcbd0157ba6f93f3601b6a9d560c47a68437baa56eee779810d21ff3
7
- data.tar.gz: d55ff4646b883721cba7cd0d0210657f39e874cf10a8795ba85061c026dbe4851edce5197d3c2f0ed977273a258959eda9f8276baedf5c54c1db0d10fef8a06e
6
+ metadata.gz: 9e43d4812d7bb826cc7fabc0a957c6ffd7f8a0b54f518c9ecdea9ebd24e7dd96f63ffb565ecbf58c487eb4c55d5c3953edbcaec7e2a8dce276a88e7bd2b23dd7
7
+ data.tar.gz: 738a51078b7c0b4551f5a31670f7c42ec5dece16a8d23ac272d2e25d16bd06244926cfb385f25abf4636b1b371c426ba941bd8009aab9b07438bb179208fbb14
data/History.md CHANGED
@@ -1,3 +1,8 @@
1
+ ### Version 1.2.0 / 2016-11-23
2
+
3
+ * The comments in a feature file are now a modeled element.
4
+
5
+
1
6
  ### Version 1.1.1 / 2016-10-28
2
7
 
3
8
  * Bug fix - Abstract instantiation of models when using a non-default dialect
@@ -6,14 +6,30 @@ module CukeModeler
6
6
 
7
7
  # Adapts the given AST into the shape that this gem expects
8
8
  def adapt(parsed_ast)
9
+ parsed_data = {}
10
+
11
+ # The entire AST is just an array with one feature and we don't want to save any child data so...an empty array
12
+ parsed_data['cuke_modeler_parsing_data'] = []
13
+
14
+ # Comments are stored on child elements in gherkin 2.x
15
+ comments = []
16
+
9
17
  # An AST is just one feature
10
- adapt_feature!(parsed_ast.first) if parsed_ast.first
18
+ adapt_feature!(parsed_ast.first, comments) if parsed_ast.first
19
+ parsed_data['feature'] = parsed_ast.first
20
+
21
+ # Adapt and store comments once they have all been gathered
22
+ comments.each do |comment|
23
+ adapt_comment!(comment)
24
+ end
25
+ parsed_data['comments'] = comments
11
26
 
12
- parsed_ast
27
+
28
+ [parsed_data]
13
29
  end
14
30
 
15
31
  # Adapts the AST sub-tree that is rooted at the given feature node.
16
- def adapt_feature!(parsed_feature)
32
+ def adapt_feature!(parsed_feature, gathered_comments)
17
33
  # Saving off the original data
18
34
  parsed_feature['cuke_modeler_parsing_data'] = Marshal::load(Marshal.dump(parsed_feature))
19
35
 
@@ -21,8 +37,12 @@ module CukeModeler
21
37
  parsed_feature['cuke_modeler_parsing_data']['tags'] = nil
22
38
  parsed_feature['cuke_modeler_parsing_data']['elements'] = nil
23
39
 
40
+ if parsed_feature['comments']
41
+ parsed_feature['cuke_modeler_parsing_data']['comments'] = nil
42
+ gathered_comments.concat(parsed_feature['comments'])
43
+ end
24
44
 
25
- adapt_child_elements!(parsed_feature)
45
+ adapt_child_elements!(parsed_feature, gathered_comments)
26
46
 
27
47
  if parsed_feature['tags']
28
48
  parsed_feature['tags'].each do |tag|
@@ -32,22 +52,27 @@ module CukeModeler
32
52
  end
33
53
 
34
54
  # Adapts the AST sub-tree that is rooted at the given background node.
35
- def adapt_background!(parsed_background)
55
+ def adapt_background!(parsed_background, gathered_comments)
36
56
  # Saving off the original data
37
57
  parsed_background['cuke_modeler_parsing_data'] = Marshal::load(Marshal.dump(parsed_background))
38
58
 
39
59
  # Removing parsed data for child elements in order to avoid duplicating data
40
60
  parsed_background['cuke_modeler_parsing_data']['steps'] = nil
41
61
 
62
+ if parsed_background['comments']
63
+ parsed_background['cuke_modeler_parsing_data']['comments'] = nil
64
+ gathered_comments.concat(parsed_background['comments'])
65
+ end
66
+
42
67
  if parsed_background['steps']
43
68
  parsed_background['steps'].each do |step|
44
- adapt_step!(step)
69
+ adapt_step!(step, gathered_comments)
45
70
  end
46
71
  end
47
72
  end
48
73
 
49
74
  # Adapts the AST sub-tree that is rooted at the given scenario node.
50
- def adapt_scenario!(parsed_scenario)
75
+ def adapt_scenario!(parsed_scenario, gathered_comments)
51
76
  # Saving off the original data
52
77
  parsed_scenario['cuke_modeler_parsing_data'] = Marshal::load(Marshal.dump(parsed_scenario))
53
78
 
@@ -55,6 +80,10 @@ module CukeModeler
55
80
  parsed_scenario['cuke_modeler_parsing_data']['tags'] = nil
56
81
  parsed_scenario['cuke_modeler_parsing_data']['steps'] = nil
57
82
 
83
+ if parsed_scenario['comments']
84
+ parsed_scenario['cuke_modeler_parsing_data']['comments'] = nil
85
+ gathered_comments.concat(parsed_scenario['comments'])
86
+ end
58
87
 
59
88
  if parsed_scenario['tags']
60
89
  parsed_scenario['tags'].each do |tag|
@@ -64,13 +93,13 @@ module CukeModeler
64
93
 
65
94
  if parsed_scenario['steps']
66
95
  parsed_scenario['steps'].each do |step|
67
- adapt_step!(step)
96
+ adapt_step!(step, gathered_comments)
68
97
  end
69
98
  end
70
99
  end
71
100
 
72
101
  # Adapts the AST sub-tree that is rooted at the given outline node.
73
- def adapt_outline!(parsed_outline)
102
+ def adapt_outline!(parsed_outline, gathered_comments)
74
103
  # Saving off the original data
75
104
  parsed_outline['cuke_modeler_parsing_data'] = Marshal::load(Marshal.dump(parsed_outline))
76
105
 
@@ -79,6 +108,10 @@ module CukeModeler
79
108
  parsed_outline['cuke_modeler_parsing_data']['steps'] = nil
80
109
  parsed_outline['cuke_modeler_parsing_data']['examples'] = nil
81
110
 
111
+ if parsed_outline['comments']
112
+ parsed_outline['cuke_modeler_parsing_data']['comments'] = nil
113
+ gathered_comments.concat(parsed_outline['comments'])
114
+ end
82
115
 
83
116
  if parsed_outline['tags']
84
117
  parsed_outline['tags'].each do |tag|
@@ -88,19 +121,19 @@ module CukeModeler
88
121
 
89
122
  if parsed_outline['steps']
90
123
  parsed_outline['steps'].each do |step|
91
- adapt_step!(step)
124
+ adapt_step!(step, gathered_comments)
92
125
  end
93
126
  end
94
127
 
95
128
  if parsed_outline['examples']
96
129
  parsed_outline['examples'].each do |example|
97
- adapt_example!(example)
130
+ adapt_example!(example, gathered_comments)
98
131
  end
99
132
  end
100
133
  end
101
134
 
102
135
  # Adapts the AST sub-tree that is rooted at the given example node.
103
- def adapt_example!(parsed_example)
136
+ def adapt_example!(parsed_example, gathered_comments)
104
137
  # Saving off the original data
105
138
  parsed_example['cuke_modeler_parsing_data'] = Marshal::load(Marshal.dump(parsed_example))
106
139
 
@@ -108,9 +141,13 @@ module CukeModeler
108
141
  parsed_example['cuke_modeler_parsing_data']['tags'] = nil
109
142
  parsed_example['cuke_modeler_parsing_data']['rows'] = nil
110
143
 
144
+ if parsed_example['comments']
145
+ parsed_example['cuke_modeler_parsing_data']['comments'] = nil
146
+ gathered_comments.concat(parsed_example['comments'])
147
+ end
111
148
 
112
149
  parsed_example['rows'].each do |row|
113
- adapt_table_row!(row)
150
+ adapt_table_row!(row, gathered_comments)
114
151
  end
115
152
 
116
153
  if parsed_example['tags']
@@ -126,8 +163,17 @@ module CukeModeler
126
163
  parsed_tag['cuke_modeler_parsing_data'] = Marshal::load(Marshal.dump(parsed_tag))
127
164
  end
128
165
 
166
+ # Adapts the AST sub-tree that is rooted at the given comment node.
167
+ def adapt_comment!(parsed_comment)
168
+ # Saving off the original data
169
+ parsed_comment['cuke_modeler_parsing_data'] = Marshal::load(Marshal.dump(parsed_comment))
170
+
171
+ parsed_comment['text'] = parsed_comment.delete('value')
172
+ parsed_comment['line'] = parsed_comment.delete('line')
173
+ end
174
+
129
175
  # Adapts the AST sub-tree that is rooted at the given step node.
130
- def adapt_step!(parsed_step)
176
+ def adapt_step!(parsed_step, gathered_comments)
131
177
  # Saving off the original data
132
178
  parsed_step['cuke_modeler_parsing_data'] = Marshal::load(Marshal.dump(parsed_step))
133
179
 
@@ -135,12 +181,16 @@ module CukeModeler
135
181
  parsed_step['cuke_modeler_parsing_data']['rows'] = nil if parsed_step['cuke_modeler_parsing_data']['rows']
136
182
  parsed_step['cuke_modeler_parsing_data']['doc_string'] = nil if parsed_step['cuke_modeler_parsing_data']['doc_string']
137
183
 
184
+ if parsed_step['comments']
185
+ parsed_step['cuke_modeler_parsing_data']['comments'] = nil
186
+ gathered_comments.concat(parsed_step['comments'])
187
+ end
138
188
 
139
189
  adapt_doc_string!(parsed_step['doc_string']) if parsed_step['doc_string']
140
190
 
141
191
  if parsed_step['rows']
142
192
  parsed_step['table'] = {'rows' => parsed_step['rows']}
143
- adapt_step_table!(parsed_step['table'])
193
+ adapt_step_table!(parsed_step['table'], gathered_comments)
144
194
  end
145
195
  end
146
196
 
@@ -151,7 +201,7 @@ module CukeModeler
151
201
  end
152
202
 
153
203
  # Adapts the AST sub-tree that is rooted at the given table node.
154
- def adapt_step_table!(parsed_step_table)
204
+ def adapt_step_table!(parsed_step_table, gathered_comments)
155
205
  # Saving off the original data
156
206
  parsed_step_table['cuke_modeler_parsing_data'] = Marshal::load(Marshal.dump(parsed_step_table['rows']))
157
207
 
@@ -162,18 +212,23 @@ module CukeModeler
162
212
  parsed_step_table['line'] = parsed_step_table['rows'].first['line']
163
213
 
164
214
  parsed_step_table['rows'].each do |row|
165
- adapt_table_row!(row)
215
+ adapt_table_row!(row, gathered_comments)
166
216
  end
167
217
  end
168
218
 
169
219
  # Adapts the AST sub-tree that is rooted at the given row node.
170
- def adapt_table_row!(parsed_table_row)
220
+ def adapt_table_row!(parsed_table_row, gathered_comments)
171
221
  # Saving off the original data
172
222
  parsed_table_row['cuke_modeler_parsing_data'] = Marshal::load(Marshal.dump(parsed_table_row))
173
223
 
174
224
  # Removing parsed data for child elements in order to avoid duplicating data which the child elements will themselves include
175
225
  parsed_table_row['cuke_modeler_parsing_data']['cells'] = nil
176
226
 
227
+ if parsed_table_row['comments']
228
+ parsed_table_row['cuke_modeler_parsing_data']['comments'] = nil
229
+ gathered_comments.concat(parsed_table_row['comments'])
230
+ end
231
+
177
232
  parsed_table_row['cells'].collect! do |cell|
178
233
  create_cell_for(cell, parsed_table_row['line'])
179
234
  end
@@ -197,16 +252,16 @@ module CukeModeler
197
252
  private
198
253
 
199
254
 
200
- def adapt_child_elements!(parsed_feature)
255
+ def adapt_child_elements!(parsed_feature, gathered_comments)
201
256
  if parsed_feature['elements']
202
257
  parsed_feature['elements'].each do |element|
203
258
  case element['type']
204
259
  when 'background'
205
- adapt_background!(element)
260
+ adapt_background!(element, gathered_comments)
206
261
  when 'scenario'
207
- adapt_scenario!(element)
262
+ adapt_scenario!(element, gathered_comments)
208
263
  when 'scenario_outline'
209
- adapt_outline!(element)
264
+ adapt_outline!(element, gathered_comments)
210
265
  else
211
266
  raise("Unknown element type: #{element['type']}")
212
267
  end
@@ -6,10 +6,24 @@ module CukeModeler
6
6
 
7
7
  # Adapts the given AST into the shape that this gem expects
8
8
  def adapt(parsed_ast)
9
+ parsed_data = {}
10
+
11
+ # No data exists stored above feature level
12
+ parsed_data['cuke_modeler_parsing_data'] = nil
13
+
14
+ # Comments are stored on the feature in gherkin 3.x
15
+ parsed_data['comments'] = []
16
+ parsed_ast[:comments].each do |comment|
17
+ adapt_comment!(comment)
18
+ end
19
+ parsed_data['comments'].concat(parsed_ast.delete(:comments))
20
+
9
21
  # An AST is just one feature
10
22
  adapt_feature!(parsed_ast)
11
23
 
12
- [parsed_ast]
24
+ parsed_data['feature'] = parsed_ast
25
+
26
+ [parsed_data]
13
27
  end
14
28
 
15
29
  # Adapts the AST sub-tree that is rooted at the given feature node.
@@ -21,6 +35,7 @@ module CukeModeler
21
35
  parsed_feature['cuke_modeler_parsing_data'][:tags] = nil
22
36
  parsed_feature['cuke_modeler_parsing_data'][:scenarioDefinitions] = nil
23
37
  parsed_feature['cuke_modeler_parsing_data'][:background] = nil
38
+ parsed_feature['cuke_modeler_parsing_data'][:comments] = nil
24
39
 
25
40
  parsed_feature['keyword'] = parsed_feature.delete(:keyword)
26
41
  parsed_feature['name'] = parsed_feature.delete(:name)
@@ -154,6 +169,15 @@ module CukeModeler
154
169
  parsed_tag['line'] = parsed_tag.delete(:location)[:line]
155
170
  end
156
171
 
172
+ # Adapts the AST sub-tree that is rooted at the given comment node.
173
+ def adapt_comment!(parsed_comment)
174
+ # Saving off the original data
175
+ parsed_comment['cuke_modeler_parsing_data'] = Marshal::load(Marshal.dump(parsed_comment))
176
+
177
+ parsed_comment['text'] = parsed_comment.delete(:text)
178
+ parsed_comment['line'] = parsed_comment.delete(:location)[:line]
179
+ end
180
+
157
181
  # Adapts the AST sub-tree that is rooted at the given step node.
158
182
  def adapt_step!(parsed_step)
159
183
  # Saving off the original data
@@ -6,9 +6,24 @@ module CukeModeler
6
6
 
7
7
  # Adapts the given AST into the shape that this gem expects
8
8
  def adapt(parsed_ast)
9
+ # Saving off the original data
10
+ parsed_ast['cuke_modeler_parsing_data'] = Marshal::load(Marshal.dump(parsed_ast))
11
+
12
+ # Removing parsed data for child elements in order to avoid duplicating data
13
+ parsed_ast['cuke_modeler_parsing_data'][:feature] = nil
14
+ parsed_ast['cuke_modeler_parsing_data'][:comments] = nil
15
+
16
+ # Comments are stored on the feature file in gherkin 4.x
17
+ parsed_ast['comments'] = []
18
+ parsed_ast[:comments].each do |comment|
19
+ adapt_comment!(comment)
20
+ end
21
+ parsed_ast['comments'].concat(parsed_ast.delete(:comments))
22
+
9
23
  adapt_feature!(parsed_ast[:feature]) if parsed_ast[:feature]
24
+ parsed_ast['feature'] = parsed_ast.delete(:feature)
10
25
 
11
- [parsed_ast[:feature]].compact
26
+ [parsed_ast]
12
27
  end
13
28
 
14
29
  # Adapts the AST sub-tree that is rooted at the given feature node.
@@ -157,6 +172,15 @@ module CukeModeler
157
172
  parsed_tag['line'] = parsed_tag.delete(:location)[:line]
158
173
  end
159
174
 
175
+ # Adapts the AST sub-tree that is rooted at the given comment node.
176
+ def adapt_comment!(parsed_comment)
177
+ # Saving off the original data
178
+ parsed_comment['cuke_modeler_parsing_data'] = Marshal::load(Marshal.dump(parsed_comment))
179
+
180
+ parsed_comment['text'] = parsed_comment.delete(:text)
181
+ parsed_comment['line'] = parsed_comment.delete(:location)[:line]
182
+ end
183
+
160
184
  # Adapts the AST sub-tree that is rooted at the given step node.
161
185
  def adapt_step!(parsed_step)
162
186
  # Saving off the original data
@@ -133,9 +133,14 @@ module CukeModeler
133
133
  end
134
134
 
135
135
  def populate_featurefile(feature_file_object, processed_feature_file_data)
136
+ populate_parsing_data(feature_file_object, processed_feature_file_data)
136
137
  feature_file_object.path = processed_feature_file_data['path']
137
138
 
138
139
  feature_file_object.feature = build_child_model(Feature, processed_feature_file_data['feature']) unless processed_feature_file_data['feature'].nil?
140
+
141
+ processed_feature_file_data['comments'].each do |comment_data|
142
+ feature_file_object.comments << build_child_model(Comment, comment_data)
143
+ end
139
144
  end
140
145
 
141
146
  def populate_tag(tag_object, processed_tag_data)
@@ -144,6 +149,16 @@ module CukeModeler
144
149
  populate_source_line(tag_object, processed_tag_data)
145
150
  end
146
151
 
152
+ def populate_comment(comment_object, processed_comment_data)
153
+ populate_comment_text(comment_object, processed_comment_data)
154
+ populate_parsing_data(comment_object, processed_comment_data)
155
+ populate_source_line(comment_object, processed_comment_data)
156
+ end
157
+
158
+ def populate_comment_text(comment_model, parsed_comment_data)
159
+ comment_model.text = parsed_comment_data['text'].strip
160
+ end
161
+
147
162
  def populate_text(step_model, parsed_step_data)
148
163
  step_model.text = parsed_step_data['name']
149
164
  end
@@ -64,7 +64,7 @@ module CukeModeler
64
64
 
65
65
  parsed_file = Parsing::parse_text(source_text, 'cuke_modeler_stand_alone_background.feature')
66
66
 
67
- parsed_file.first['elements'].first
67
+ parsed_file.first['feature']['elements'].first
68
68
  end
69
69
 
70
70
  end
@@ -41,7 +41,7 @@ module CukeModeler
41
41
 
42
42
  parsed_file = Parsing::parse_text(source_text, 'cuke_modeler_stand_alone_cell.feature')
43
43
 
44
- parsed_file.first['elements'].first['steps'].first['table']['rows'].first['cells'].first
44
+ parsed_file.first['feature']['elements'].first['steps'].first['table']['rows'].first['cells'].first
45
45
  end
46
46
 
47
47
  end
@@ -0,0 +1,47 @@
1
+ module CukeModeler
2
+
3
+ # A class modeling a comment in a feature file.
4
+
5
+ class Comment < Model
6
+
7
+ include Parsing
8
+ include Parsed
9
+ include Sourceable
10
+
11
+
12
+ # The text of the comment
13
+ attr_accessor :text
14
+
15
+
16
+ # Creates a new Comment object and, if *source_text* is provided, populates the
17
+ # object.
18
+ def initialize(source_text = nil)
19
+ super(source_text)
20
+
21
+ if source_text
22
+ parsed_comment_data = parse_source(source_text)
23
+ populate_comment(self, parsed_comment_data)
24
+ end
25
+ end
26
+
27
+ # Returns a string representation of this model. For a comment model,
28
+ # this will be Gherkin text that is equivalent to the comment being modeled.
29
+ def to_s
30
+ text || ''
31
+ end
32
+
33
+
34
+ private
35
+
36
+
37
+ def parse_source(source_text)
38
+ base_file_string = "\n#{dialect_feature_keyword}: Fake feature to parse"
39
+ source_text = "# language: #{Parsing.dialect}\n" + source_text + base_file_string
40
+
41
+ parsed_file = Parsing::parse_text(source_text, 'cuke_modeler_stand_alone_comment.feature')
42
+
43
+ parsed_file.first['comments'].last
44
+ end
45
+
46
+ end
47
+ end