cuke_modeler 3.27.0 → 3.28.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +579 -572
- data/LICENSE.txt +22 -22
- data/README.md +135 -135
- data/cuke_modeler.gemspec +59 -59
- data/lib/cuke_modeler/adapters/gherkin_10_adapter.rb +13 -13
- data/lib/cuke_modeler/adapters/gherkin_11_adapter.rb +13 -13
- data/lib/cuke_modeler/adapters/gherkin_12_adapter.rb +13 -13
- data/lib/cuke_modeler/adapters/gherkin_13_adapter.rb +13 -13
- data/lib/cuke_modeler/adapters/gherkin_14_adapter.rb +13 -13
- data/lib/cuke_modeler/adapters/gherkin_15_adapter.rb +13 -13
- data/lib/cuke_modeler/adapters/gherkin_16_adapter.rb +13 -13
- data/lib/cuke_modeler/adapters/gherkin_17_adapter.rb +13 -13
- data/lib/cuke_modeler/adapters/gherkin_18_adapter.rb +27 -27
- data/lib/cuke_modeler/adapters/gherkin_19_adapter.rb +64 -64
- data/lib/cuke_modeler/adapters/gherkin_20_adapter.rb +359 -359
- data/lib/cuke_modeler/adapters/gherkin_21_adapter.rb +13 -13
- data/lib/cuke_modeler/adapters/gherkin_22_adapter.rb +13 -13
- data/lib/cuke_modeler/adapters/gherkin_23_adapter.rb +13 -13
- data/lib/cuke_modeler/adapters/gherkin_24_adapter.rb +13 -13
- data/lib/cuke_modeler/adapters/gherkin_25_adapter.rb +13 -13
- data/lib/cuke_modeler/adapters/gherkin_26_adapter.rb +13 -13
- data/lib/cuke_modeler/adapters/gherkin_27_adapter.rb +13 -13
- data/lib/cuke_modeler/adapters/gherkin_28_adapter.rb +13 -13
- data/lib/cuke_modeler/adapters/gherkin_29_adapter.rb +13 -13
- data/lib/cuke_modeler/adapters/gherkin_30_adapter.rb +13 -13
- data/lib/cuke_modeler/adapters/gherkin_31_adapter.rb +13 -13
- data/lib/cuke_modeler/adapters/gherkin_32_adapter.rb +13 -13
- data/lib/cuke_modeler/adapters/gherkin_33_adapter.rb +13 -13
- data/lib/cuke_modeler/adapters/gherkin_34_adapter.rb +13 -13
- data/lib/cuke_modeler/adapters/gherkin_35_adapter.rb +13 -13
- data/lib/cuke_modeler/adapters/gherkin_36_adapter.rb +13 -13
- data/lib/cuke_modeler/adapters/gherkin_37_adapter.rb +13 -13
- data/lib/cuke_modeler/adapters/gherkin_38_adapter.rb +13 -0
- data/lib/cuke_modeler/adapters/gherkin_9_adapter.rb +375 -375
- data/lib/cuke_modeler/adapters/gherkin_base_adapter.rb +17 -17
- data/lib/cuke_modeler/containing.rb +105 -105
- data/lib/cuke_modeler/described.rb +71 -71
- data/lib/cuke_modeler/models/background.rb +122 -122
- data/lib/cuke_modeler/models/cell.rb +88 -88
- data/lib/cuke_modeler/models/comment.rb +82 -82
- data/lib/cuke_modeler/models/directory.rb +143 -143
- data/lib/cuke_modeler/models/doc_string.rb +104 -104
- data/lib/cuke_modeler/models/example.rb +274 -274
- data/lib/cuke_modeler/models/feature.rb +200 -200
- data/lib/cuke_modeler/models/feature_file.rb +116 -116
- data/lib/cuke_modeler/models/model.rb +87 -87
- data/lib/cuke_modeler/models/outline.rb +145 -145
- data/lib/cuke_modeler/models/row.rb +104 -104
- data/lib/cuke_modeler/models/rule.rb +162 -162
- data/lib/cuke_modeler/models/scenario.rb +128 -128
- data/lib/cuke_modeler/models/step.rb +178 -178
- data/lib/cuke_modeler/models/table.rb +117 -117
- data/lib/cuke_modeler/models/tag.rb +75 -75
- data/lib/cuke_modeler/named.rb +26 -26
- data/lib/cuke_modeler/nested.rb +61 -61
- data/lib/cuke_modeler/parsed.rb +24 -24
- data/lib/cuke_modeler/parsing.rb +208 -208
- data/lib/cuke_modeler/sourceable.rb +29 -29
- data/lib/cuke_modeler/stepped.rb +34 -34
- data/lib/cuke_modeler/taggable.rb +57 -57
- data/lib/cuke_modeler/version.rb +4 -4
- data/lib/cuke_modeler.rb +32 -32
- data/testing/cucumber/features/analysis/step_comparison.feature +25 -25
- data/testing/cucumber/features/analysis/test_comparison.feature +35 -35
- data/testing/cucumber/features/modeling/background_modeling.feature +105 -105
- data/testing/cucumber/features/modeling/background_output.feature +60 -60
- data/testing/cucumber/features/modeling/cell_modeling.feature +68 -68
- data/testing/cucumber/features/modeling/cell_output.feature +36 -36
- data/testing/cucumber/features/modeling/comment_modeling.feature +62 -62
- data/testing/cucumber/features/modeling/comment_output.feature +40 -40
- data/testing/cucumber/features/modeling/directory_modeling.feature +62 -62
- data/testing/cucumber/features/modeling/directory_output.feature +33 -33
- data/testing/cucumber/features/modeling/doc_string_modeling.feature +85 -85
- data/testing/cucumber/features/modeling/doc_string_output.feature +50 -50
- data/testing/cucumber/features/modeling/example_modeling.feature +155 -155
- data/testing/cucumber/features/modeling/example_output.feature +57 -57
- data/testing/cucumber/features/modeling/feature_file_modeling.feature +49 -49
- data/testing/cucumber/features/modeling/feature_file_output.feature +33 -33
- data/testing/cucumber/features/modeling/feature_modeling.feature +149 -149
- data/testing/cucumber/features/modeling/feature_output.feature +144 -144
- data/testing/cucumber/features/modeling/model_output.feature +61 -61
- data/testing/cucumber/features/modeling/model_structure.feature +42 -42
- data/testing/cucumber/features/modeling/outline_modeling.feature +175 -175
- data/testing/cucumber/features/modeling/outline_output.feature +87 -87
- data/testing/cucumber/features/modeling/row_modeling.feature +70 -70
- data/testing/cucumber/features/modeling/row_output.feature +40 -40
- data/testing/cucumber/features/modeling/rule_modeling.feature +171 -171
- data/testing/cucumber/features/modeling/rule_output.feature +136 -136
- data/testing/cucumber/features/modeling/scenario_modeling.feature +146 -146
- data/testing/cucumber/features/modeling/scenario_output.feature +63 -63
- data/testing/cucumber/features/modeling/step_modeling.feature +105 -105
- data/testing/cucumber/features/modeling/step_output.feature +47 -47
- data/testing/cucumber/features/modeling/table_modeling.feature +73 -73
- data/testing/cucumber/features/modeling/table_output.feature +42 -42
- data/testing/cucumber/features/modeling/tag_modeling.feature +62 -62
- data/testing/cucumber/features/modeling/tag_output.feature +40 -40
- metadata +6 -8
|
@@ -1,274 +1,274 @@
|
|
|
1
|
-
# I'll take extra class length due to extra helper methods over having fewer but more complex methods
|
|
2
|
-
# rubocop:disable Metrics/ClassLength
|
|
3
|
-
|
|
4
|
-
module CukeModeler
|
|
5
|
-
|
|
6
|
-
# A class modeling an example table of an outline.
|
|
7
|
-
class Example < Model
|
|
8
|
-
|
|
9
|
-
include Parsing
|
|
10
|
-
include Parsed
|
|
11
|
-
include Named
|
|
12
|
-
include Described
|
|
13
|
-
include Sourceable
|
|
14
|
-
include Taggable
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
# The example's keyword
|
|
18
|
-
attr_accessor :keyword
|
|
19
|
-
|
|
20
|
-
# The row models in the example table
|
|
21
|
-
attr_accessor :rows
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
# Creates a new Example object and, if *source_text* is provided,
|
|
25
|
-
# populates the object.
|
|
26
|
-
#
|
|
27
|
-
# @example
|
|
28
|
-
# Example.new
|
|
29
|
-
# Example.new("|param_1|param_2|\n|value_1|value_2|")
|
|
30
|
-
#
|
|
31
|
-
# @param source_text [String] The Gherkin text that will be used to populate the model
|
|
32
|
-
# @raise [ArgumentError] If *source_text* is not a String
|
|
33
|
-
# @return [Example] A new Example instance
|
|
34
|
-
def initialize(source_text = nil)
|
|
35
|
-
@tags = []
|
|
36
|
-
@rows = []
|
|
37
|
-
|
|
38
|
-
super
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
# TODO: Deprecate using symbol keys in a Hash
|
|
42
|
-
|
|
43
|
-
# Adds a row to the example table. The row can be given as a Hash of
|
|
44
|
-
# parameters and their corresponding values or as an Array of values which
|
|
45
|
-
# will be assigned in order.
|
|
46
|
-
#
|
|
47
|
-
# @example
|
|
48
|
-
# example.add_row({'param1' => 'value1', 'param2' => 'value2'})
|
|
49
|
-
# example.add_row({param1: 'value1', param2: 'value2'})
|
|
50
|
-
# example.add_row(['value1', 'value2'])
|
|
51
|
-
#
|
|
52
|
-
# @param row [Hash, Array<String>] The the cell values to use for the added row
|
|
53
|
-
# @raise [ArgumentError] If *row* is not a Hash or Array
|
|
54
|
-
# @raise [Exception] If the model has no initial parameter row
|
|
55
|
-
def add_row(row)
|
|
56
|
-
raise('Cannot add a row. No parameters have been set.') if rows.empty?
|
|
57
|
-
|
|
58
|
-
# A quick 'deep clone' so that the input isn't modified
|
|
59
|
-
row = Marshal.load(Marshal.dump(row))
|
|
60
|
-
|
|
61
|
-
values = if row.is_a?(Array)
|
|
62
|
-
row
|
|
63
|
-
elsif row.is_a?(Hash)
|
|
64
|
-
# There is no guarantee that the user built up their hash with the keys in the same order as
|
|
65
|
-
# the parameter row and so the values have to be ordered by us. Additionally, the hash needs
|
|
66
|
-
# to have string keys in order for #order_row_values to work
|
|
67
|
-
ordered_row_values(stringify_keys(row))
|
|
68
|
-
else
|
|
69
|
-
raise(ArgumentError, "Can only add row from a Hash or an Array but received #{row.class}")
|
|
70
|
-
end
|
|
71
|
-
|
|
72
|
-
@rows << Row.new("|#{values.join('|')}|")
|
|
73
|
-
end
|
|
74
|
-
|
|
75
|
-
# TODO: Add exception if using symbol keys in a Hash
|
|
76
|
-
|
|
77
|
-
# Removes a row from the example table. The row can be given as a Hash of
|
|
78
|
-
# parameters and their corresponding values or as an Array of values
|
|
79
|
-
# which will be assigned in order.
|
|
80
|
-
#
|
|
81
|
-
# @example
|
|
82
|
-
# example.remove_row({'param1' => 'value1', 'param2' => 'value2'})
|
|
83
|
-
# example.remove_row(['value1', 'value2'])
|
|
84
|
-
#
|
|
85
|
-
# @param row [Hash, Array<String>] The the cell values to use for the added row
|
|
86
|
-
# @raise [ArgumentError] If *row* is not a Hash or Array
|
|
87
|
-
def remove_row(row)
|
|
88
|
-
return if argument_rows.empty?
|
|
89
|
-
|
|
90
|
-
values = if row.is_a?(Array)
|
|
91
|
-
row
|
|
92
|
-
elsif row.is_a?(Hash)
|
|
93
|
-
# There is no guarantee that the user built up their hash with the keys in the same order as
|
|
94
|
-
# the parameter row and so the values have to be ordered by us.
|
|
95
|
-
ordered_row_values(row)
|
|
96
|
-
else
|
|
97
|
-
raise(ArgumentError, "Can only remove row from a Hash or an Array but received #{row.class}")
|
|
98
|
-
end
|
|
99
|
-
|
|
100
|
-
location = index_for_values(values.map(&:to_s).map(&:strip))
|
|
101
|
-
@rows.delete_at(location + 1) if location
|
|
102
|
-
end
|
|
103
|
-
|
|
104
|
-
# Returns the Row models associated with the argument rows
|
|
105
|
-
# in the example table
|
|
106
|
-
#
|
|
107
|
-
# @example
|
|
108
|
-
# example.argument_rows
|
|
109
|
-
#
|
|
110
|
-
# @return [Array<Row>] The argument row models
|
|
111
|
-
def argument_rows
|
|
112
|
-
rows[1..rows.count] || []
|
|
113
|
-
end
|
|
114
|
-
|
|
115
|
-
# Returns the Row model associated with the parameter row
|
|
116
|
-
# in the example table
|
|
117
|
-
#
|
|
118
|
-
# @example
|
|
119
|
-
# example.parameter_row
|
|
120
|
-
#
|
|
121
|
-
# @return [Row, nil] The parameter row model
|
|
122
|
-
def parameter_row
|
|
123
|
-
rows.first
|
|
124
|
-
end
|
|
125
|
-
|
|
126
|
-
# Returns the parameters of the example table
|
|
127
|
-
#
|
|
128
|
-
# @example
|
|
129
|
-
# example.parameters #=> ['param_1', 'param_2']
|
|
130
|
-
#
|
|
131
|
-
# @return [Array<String>] The parameters
|
|
132
|
-
def parameters
|
|
133
|
-
parameter_row ? parameter_row.cells.map(&:value) : []
|
|
134
|
-
end
|
|
135
|
-
|
|
136
|
-
# Returns the model objects that are children of this model. For an
|
|
137
|
-
# Example model, these would be any associated Row or Tag models.
|
|
138
|
-
#
|
|
139
|
-
# @example
|
|
140
|
-
# example.children
|
|
141
|
-
#
|
|
142
|
-
# @return [Array<Row, Tag>] A collection of child models
|
|
143
|
-
def children
|
|
144
|
-
rows + tags
|
|
145
|
-
end
|
|
146
|
-
|
|
147
|
-
# Building strings just isn't pretty
|
|
148
|
-
# rubocop:disable Metrics/AbcSize
|
|
149
|
-
|
|
150
|
-
# Returns a string representation of this model. For an Example model,
|
|
151
|
-
# this will be Gherkin text that is equivalent to the example being modeled.
|
|
152
|
-
#
|
|
153
|
-
# @example
|
|
154
|
-
# example.to_s
|
|
155
|
-
#
|
|
156
|
-
# @return [String] A string representation of this model
|
|
157
|
-
def to_s
|
|
158
|
-
text = ''
|
|
159
|
-
|
|
160
|
-
text << "#{tag_output_string}\n" unless tags.empty?
|
|
161
|
-
text << "#{@keyword}:#{name_output_string}"
|
|
162
|
-
text << "\n#{description_output_string}" unless no_description_to_output?
|
|
163
|
-
text << "\n" unless rows.empty? || no_description_to_output?
|
|
164
|
-
text << "\n#{parameters_output_string}" if parameter_row
|
|
165
|
-
text << "\n#{rows_output_string}" unless argument_rows.empty?
|
|
166
|
-
|
|
167
|
-
text
|
|
168
|
-
end
|
|
169
|
-
|
|
170
|
-
# rubocop:enable Metrics/AbcSize
|
|
171
|
-
|
|
172
|
-
# See `Object#inspect`. Returns some basic information about the
|
|
173
|
-
# object, including its class, object ID, and its most meaningful
|
|
174
|
-
# attribute. For an Example model, this will be the name of the
|
|
175
|
-
# example. If *verbose* is true, provides default Ruby inspection
|
|
176
|
-
# behavior instead.
|
|
177
|
-
#
|
|
178
|
-
# @example
|
|
179
|
-
# example.inspect
|
|
180
|
-
# example.inspect(verbose: true)
|
|
181
|
-
#
|
|
182
|
-
# @param verbose [Boolean] Whether or not to return the full details of
|
|
183
|
-
# the object. Defaults to false.
|
|
184
|
-
# @return [String] A string representation of this model
|
|
185
|
-
def inspect(verbose: false)
|
|
186
|
-
return super if verbose
|
|
187
|
-
|
|
188
|
-
"#{super.chop} @name: #{name.inspect}>"
|
|
189
|
-
end
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
private
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
def process_source(source_text)
|
|
196
|
-
base_file_string = "# language: #{Parsing.dialect}
|
|
197
|
-
#{dialect_feature_keyword}: Fake feature to parse
|
|
198
|
-
#{dialect_outline_keyword}:
|
|
199
|
-
#{dialect_step_keyword} fake step\n"
|
|
200
|
-
source_text = base_file_string + source_text
|
|
201
|
-
|
|
202
|
-
parsed_file = Parsing.parse_text(source_text, 'cuke_modeler_stand_alone_example.feature')
|
|
203
|
-
|
|
204
|
-
parsed_file['feature']['elements'].first['examples'].first
|
|
205
|
-
end
|
|
206
|
-
|
|
207
|
-
def populate_model(parsed_example_data)
|
|
208
|
-
populate_parsing_data(parsed_example_data)
|
|
209
|
-
populate_keyword(parsed_example_data)
|
|
210
|
-
populate_source_location(parsed_example_data)
|
|
211
|
-
populate_name(parsed_example_data)
|
|
212
|
-
populate_description(parsed_example_data)
|
|
213
|
-
populate_tags(parsed_example_data)
|
|
214
|
-
populate_example_rows(parsed_example_data)
|
|
215
|
-
end
|
|
216
|
-
|
|
217
|
-
def populate_example_rows(parsed_example_data)
|
|
218
|
-
parsed_example_data['rows'].each do |row_data|
|
|
219
|
-
@rows << build_child_model(Row, row_data)
|
|
220
|
-
end
|
|
221
|
-
end
|
|
222
|
-
|
|
223
|
-
def determine_buffer_size(index)
|
|
224
|
-
rows.collect { |row| row.cells[index].to_s.length }.max || 0
|
|
225
|
-
end
|
|
226
|
-
|
|
227
|
-
def parameters_output_string
|
|
228
|
-
text = ''
|
|
229
|
-
|
|
230
|
-
unless parameter_row.nil?
|
|
231
|
-
text << ' |'
|
|
232
|
-
parameter_row.cells.count.times { |index| text << " #{string_for(parameter_row.cells, index)} |" }
|
|
233
|
-
end
|
|
234
|
-
|
|
235
|
-
text
|
|
236
|
-
end
|
|
237
|
-
|
|
238
|
-
def rows_output_string
|
|
239
|
-
text = ''
|
|
240
|
-
|
|
241
|
-
unless argument_rows.empty?
|
|
242
|
-
|
|
243
|
-
argument_rows.each do |row|
|
|
244
|
-
text << ' |'
|
|
245
|
-
row.cells.count.times { |index| text << " #{string_for(row.cells, index)} |" }
|
|
246
|
-
text << "\n"
|
|
247
|
-
end
|
|
248
|
-
|
|
249
|
-
text.chomp!
|
|
250
|
-
end
|
|
251
|
-
|
|
252
|
-
text
|
|
253
|
-
end
|
|
254
|
-
|
|
255
|
-
def string_for(cells, index)
|
|
256
|
-
cells[index] ? cells[index].to_s.ljust(determine_buffer_size(index)) : ''
|
|
257
|
-
end
|
|
258
|
-
|
|
259
|
-
def ordered_row_values(row_hash)
|
|
260
|
-
parameter_row.cells.map(&:value).collect { |parameter| row_hash[parameter] }
|
|
261
|
-
end
|
|
262
|
-
|
|
263
|
-
def stringify_keys(hash)
|
|
264
|
-
hash.each_with_object({}) { |(key, value), new_hash| new_hash[key.to_s] = value }
|
|
265
|
-
end
|
|
266
|
-
|
|
267
|
-
def index_for_values(values)
|
|
268
|
-
argument_rows.index { |row| row.cells.map(&:value) == values }
|
|
269
|
-
end
|
|
270
|
-
|
|
271
|
-
end
|
|
272
|
-
end
|
|
273
|
-
|
|
274
|
-
# rubocop:enable Metrics/ClassLength
|
|
1
|
+
# I'll take extra class length due to extra helper methods over having fewer but more complex methods
|
|
2
|
+
# rubocop:disable Metrics/ClassLength
|
|
3
|
+
|
|
4
|
+
module CukeModeler
|
|
5
|
+
|
|
6
|
+
# A class modeling an example table of an outline.
|
|
7
|
+
class Example < Model
|
|
8
|
+
|
|
9
|
+
include Parsing
|
|
10
|
+
include Parsed
|
|
11
|
+
include Named
|
|
12
|
+
include Described
|
|
13
|
+
include Sourceable
|
|
14
|
+
include Taggable
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
# The example's keyword
|
|
18
|
+
attr_accessor :keyword
|
|
19
|
+
|
|
20
|
+
# The row models in the example table
|
|
21
|
+
attr_accessor :rows
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
# Creates a new Example object and, if *source_text* is provided,
|
|
25
|
+
# populates the object.
|
|
26
|
+
#
|
|
27
|
+
# @example
|
|
28
|
+
# Example.new
|
|
29
|
+
# Example.new("|param_1|param_2|\n|value_1|value_2|")
|
|
30
|
+
#
|
|
31
|
+
# @param source_text [String] The Gherkin text that will be used to populate the model
|
|
32
|
+
# @raise [ArgumentError] If *source_text* is not a String
|
|
33
|
+
# @return [Example] A new Example instance
|
|
34
|
+
def initialize(source_text = nil)
|
|
35
|
+
@tags = []
|
|
36
|
+
@rows = []
|
|
37
|
+
|
|
38
|
+
super
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# TODO: Deprecate using symbol keys in a Hash
|
|
42
|
+
|
|
43
|
+
# Adds a row to the example table. The row can be given as a Hash of
|
|
44
|
+
# parameters and their corresponding values or as an Array of values which
|
|
45
|
+
# will be assigned in order.
|
|
46
|
+
#
|
|
47
|
+
# @example
|
|
48
|
+
# example.add_row({'param1' => 'value1', 'param2' => 'value2'})
|
|
49
|
+
# example.add_row({param1: 'value1', param2: 'value2'})
|
|
50
|
+
# example.add_row(['value1', 'value2'])
|
|
51
|
+
#
|
|
52
|
+
# @param row [Hash, Array<String>] The the cell values to use for the added row
|
|
53
|
+
# @raise [ArgumentError] If *row* is not a Hash or Array
|
|
54
|
+
# @raise [Exception] If the model has no initial parameter row
|
|
55
|
+
def add_row(row)
|
|
56
|
+
raise('Cannot add a row. No parameters have been set.') if rows.empty?
|
|
57
|
+
|
|
58
|
+
# A quick 'deep clone' so that the input isn't modified
|
|
59
|
+
row = Marshal.load(Marshal.dump(row))
|
|
60
|
+
|
|
61
|
+
values = if row.is_a?(Array)
|
|
62
|
+
row
|
|
63
|
+
elsif row.is_a?(Hash)
|
|
64
|
+
# There is no guarantee that the user built up their hash with the keys in the same order as
|
|
65
|
+
# the parameter row and so the values have to be ordered by us. Additionally, the hash needs
|
|
66
|
+
# to have string keys in order for #order_row_values to work
|
|
67
|
+
ordered_row_values(stringify_keys(row))
|
|
68
|
+
else
|
|
69
|
+
raise(ArgumentError, "Can only add row from a Hash or an Array but received #{row.class}")
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
@rows << Row.new("|#{values.join('|')}|")
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
# TODO: Add exception if using symbol keys in a Hash
|
|
76
|
+
|
|
77
|
+
# Removes a row from the example table. The row can be given as a Hash of
|
|
78
|
+
# parameters and their corresponding values or as an Array of values
|
|
79
|
+
# which will be assigned in order.
|
|
80
|
+
#
|
|
81
|
+
# @example
|
|
82
|
+
# example.remove_row({'param1' => 'value1', 'param2' => 'value2'})
|
|
83
|
+
# example.remove_row(['value1', 'value2'])
|
|
84
|
+
#
|
|
85
|
+
# @param row [Hash, Array<String>] The the cell values to use for the added row
|
|
86
|
+
# @raise [ArgumentError] If *row* is not a Hash or Array
|
|
87
|
+
def remove_row(row)
|
|
88
|
+
return if argument_rows.empty?
|
|
89
|
+
|
|
90
|
+
values = if row.is_a?(Array)
|
|
91
|
+
row
|
|
92
|
+
elsif row.is_a?(Hash)
|
|
93
|
+
# There is no guarantee that the user built up their hash with the keys in the same order as
|
|
94
|
+
# the parameter row and so the values have to be ordered by us.
|
|
95
|
+
ordered_row_values(row)
|
|
96
|
+
else
|
|
97
|
+
raise(ArgumentError, "Can only remove row from a Hash or an Array but received #{row.class}")
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
location = index_for_values(values.map(&:to_s).map(&:strip))
|
|
101
|
+
@rows.delete_at(location + 1) if location
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
# Returns the Row models associated with the argument rows
|
|
105
|
+
# in the example table
|
|
106
|
+
#
|
|
107
|
+
# @example
|
|
108
|
+
# example.argument_rows
|
|
109
|
+
#
|
|
110
|
+
# @return [Array<Row>] The argument row models
|
|
111
|
+
def argument_rows
|
|
112
|
+
rows[1..rows.count] || []
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
# Returns the Row model associated with the parameter row
|
|
116
|
+
# in the example table
|
|
117
|
+
#
|
|
118
|
+
# @example
|
|
119
|
+
# example.parameter_row
|
|
120
|
+
#
|
|
121
|
+
# @return [Row, nil] The parameter row model
|
|
122
|
+
def parameter_row
|
|
123
|
+
rows.first
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
# Returns the parameters of the example table
|
|
127
|
+
#
|
|
128
|
+
# @example
|
|
129
|
+
# example.parameters #=> ['param_1', 'param_2']
|
|
130
|
+
#
|
|
131
|
+
# @return [Array<String>] The parameters
|
|
132
|
+
def parameters
|
|
133
|
+
parameter_row ? parameter_row.cells.map(&:value) : []
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
# Returns the model objects that are children of this model. For an
|
|
137
|
+
# Example model, these would be any associated Row or Tag models.
|
|
138
|
+
#
|
|
139
|
+
# @example
|
|
140
|
+
# example.children
|
|
141
|
+
#
|
|
142
|
+
# @return [Array<Row, Tag>] A collection of child models
|
|
143
|
+
def children
|
|
144
|
+
rows + tags
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
# Building strings just isn't pretty
|
|
148
|
+
# rubocop:disable Metrics/AbcSize
|
|
149
|
+
|
|
150
|
+
# Returns a string representation of this model. For an Example model,
|
|
151
|
+
# this will be Gherkin text that is equivalent to the example being modeled.
|
|
152
|
+
#
|
|
153
|
+
# @example
|
|
154
|
+
# example.to_s
|
|
155
|
+
#
|
|
156
|
+
# @return [String] A string representation of this model
|
|
157
|
+
def to_s
|
|
158
|
+
text = ''
|
|
159
|
+
|
|
160
|
+
text << "#{tag_output_string}\n" unless tags.empty?
|
|
161
|
+
text << "#{@keyword}:#{name_output_string}"
|
|
162
|
+
text << "\n#{description_output_string}" unless no_description_to_output?
|
|
163
|
+
text << "\n" unless rows.empty? || no_description_to_output?
|
|
164
|
+
text << "\n#{parameters_output_string}" if parameter_row
|
|
165
|
+
text << "\n#{rows_output_string}" unless argument_rows.empty?
|
|
166
|
+
|
|
167
|
+
text
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
# rubocop:enable Metrics/AbcSize
|
|
171
|
+
|
|
172
|
+
# See `Object#inspect`. Returns some basic information about the
|
|
173
|
+
# object, including its class, object ID, and its most meaningful
|
|
174
|
+
# attribute. For an Example model, this will be the name of the
|
|
175
|
+
# example. If *verbose* is true, provides default Ruby inspection
|
|
176
|
+
# behavior instead.
|
|
177
|
+
#
|
|
178
|
+
# @example
|
|
179
|
+
# example.inspect
|
|
180
|
+
# example.inspect(verbose: true)
|
|
181
|
+
#
|
|
182
|
+
# @param verbose [Boolean] Whether or not to return the full details of
|
|
183
|
+
# the object. Defaults to false.
|
|
184
|
+
# @return [String] A string representation of this model
|
|
185
|
+
def inspect(verbose: false)
|
|
186
|
+
return super if verbose
|
|
187
|
+
|
|
188
|
+
"#{super.chop} @name: #{name.inspect}>"
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
private
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
def process_source(source_text)
|
|
196
|
+
base_file_string = "# language: #{Parsing.dialect}
|
|
197
|
+
#{dialect_feature_keyword}: Fake feature to parse
|
|
198
|
+
#{dialect_outline_keyword}:
|
|
199
|
+
#{dialect_step_keyword} fake step\n"
|
|
200
|
+
source_text = base_file_string + source_text
|
|
201
|
+
|
|
202
|
+
parsed_file = Parsing.parse_text(source_text, 'cuke_modeler_stand_alone_example.feature')
|
|
203
|
+
|
|
204
|
+
parsed_file['feature']['elements'].first['examples'].first
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
def populate_model(parsed_example_data)
|
|
208
|
+
populate_parsing_data(parsed_example_data)
|
|
209
|
+
populate_keyword(parsed_example_data)
|
|
210
|
+
populate_source_location(parsed_example_data)
|
|
211
|
+
populate_name(parsed_example_data)
|
|
212
|
+
populate_description(parsed_example_data)
|
|
213
|
+
populate_tags(parsed_example_data)
|
|
214
|
+
populate_example_rows(parsed_example_data)
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
def populate_example_rows(parsed_example_data)
|
|
218
|
+
parsed_example_data['rows'].each do |row_data|
|
|
219
|
+
@rows << build_child_model(Row, row_data)
|
|
220
|
+
end
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
def determine_buffer_size(index)
|
|
224
|
+
rows.collect { |row| row.cells[index].to_s.length }.max || 0
|
|
225
|
+
end
|
|
226
|
+
|
|
227
|
+
def parameters_output_string
|
|
228
|
+
text = ''
|
|
229
|
+
|
|
230
|
+
unless parameter_row.nil?
|
|
231
|
+
text << ' |'
|
|
232
|
+
parameter_row.cells.count.times { |index| text << " #{string_for(parameter_row.cells, index)} |" }
|
|
233
|
+
end
|
|
234
|
+
|
|
235
|
+
text
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
def rows_output_string
|
|
239
|
+
text = ''
|
|
240
|
+
|
|
241
|
+
unless argument_rows.empty?
|
|
242
|
+
|
|
243
|
+
argument_rows.each do |row|
|
|
244
|
+
text << ' |'
|
|
245
|
+
row.cells.count.times { |index| text << " #{string_for(row.cells, index)} |" }
|
|
246
|
+
text << "\n"
|
|
247
|
+
end
|
|
248
|
+
|
|
249
|
+
text.chomp!
|
|
250
|
+
end
|
|
251
|
+
|
|
252
|
+
text
|
|
253
|
+
end
|
|
254
|
+
|
|
255
|
+
def string_for(cells, index)
|
|
256
|
+
cells[index] ? cells[index].to_s.ljust(determine_buffer_size(index)) : ''
|
|
257
|
+
end
|
|
258
|
+
|
|
259
|
+
def ordered_row_values(row_hash)
|
|
260
|
+
parameter_row.cells.map(&:value).collect { |parameter| row_hash[parameter] }
|
|
261
|
+
end
|
|
262
|
+
|
|
263
|
+
def stringify_keys(hash)
|
|
264
|
+
hash.each_with_object({}) { |(key, value), new_hash| new_hash[key.to_s] = value }
|
|
265
|
+
end
|
|
266
|
+
|
|
267
|
+
def index_for_values(values)
|
|
268
|
+
argument_rows.index { |row| row.cells.map(&:value) == values }
|
|
269
|
+
end
|
|
270
|
+
|
|
271
|
+
end
|
|
272
|
+
end
|
|
273
|
+
|
|
274
|
+
# rubocop:enable Metrics/ClassLength
|