cuke_modeler 1.1.1 → 1.2.0

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