cuke_modeler 3.19.0 → 3.20.1

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 (68) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +26 -1
  3. data/README.md +5 -6
  4. data/cuke_modeler.gemspec +5 -3
  5. data/lib/cuke_modeler/adapters/gherkin_10_adapter.rb +5 -5
  6. data/lib/cuke_modeler/adapters/gherkin_11_adapter.rb +5 -5
  7. data/lib/cuke_modeler/adapters/gherkin_12_adapter.rb +5 -5
  8. data/lib/cuke_modeler/adapters/gherkin_13_adapter.rb +5 -5
  9. data/lib/cuke_modeler/adapters/gherkin_14_adapter.rb +5 -5
  10. data/lib/cuke_modeler/adapters/gherkin_15_adapter.rb +5 -5
  11. data/lib/cuke_modeler/adapters/gherkin_16_adapter.rb +5 -5
  12. data/lib/cuke_modeler/adapters/gherkin_17_adapter.rb +5 -5
  13. data/lib/cuke_modeler/adapters/gherkin_18_adapter.rb +5 -2
  14. data/lib/cuke_modeler/adapters/gherkin_19_adapter.rb +5 -2
  15. data/lib/cuke_modeler/adapters/gherkin_20_adapter.rb +5 -2
  16. data/lib/cuke_modeler/adapters/gherkin_21_adapter.rb +5 -5
  17. data/lib/cuke_modeler/adapters/gherkin_22_adapter.rb +5 -5
  18. data/lib/cuke_modeler/adapters/gherkin_23_adapter.rb +5 -5
  19. data/lib/cuke_modeler/adapters/gherkin_24_adapter.rb +5 -5
  20. data/lib/cuke_modeler/adapters/gherkin_25_adapter.rb +5 -5
  21. data/lib/cuke_modeler/adapters/gherkin_26_adapter.rb +5 -5
  22. data/lib/cuke_modeler/adapters/gherkin_27_adapter.rb +13 -0
  23. data/lib/cuke_modeler/adapters/gherkin_9_adapter.rb +5 -2
  24. data/lib/cuke_modeler/adapters/gherkin_base_adapter.rb +5 -2
  25. data/lib/cuke_modeler/containing.rb +43 -210
  26. data/lib/cuke_modeler/described.rb +8 -4
  27. data/lib/cuke_modeler/models/background.rb +61 -9
  28. data/lib/cuke_modeler/models/cell.rb +44 -7
  29. data/lib/cuke_modeler/models/comment.rb +43 -7
  30. data/lib/cuke_modeler/models/directory.rb +66 -8
  31. data/lib/cuke_modeler/models/doc_string.rb +49 -7
  32. data/lib/cuke_modeler/models/example.rb +103 -17
  33. data/lib/cuke_modeler/models/feature.rb +81 -10
  34. data/lib/cuke_modeler/models/feature_file.rb +64 -10
  35. data/lib/cuke_modeler/models/model.rb +57 -6
  36. data/lib/cuke_modeler/models/outline.rb +67 -9
  37. data/lib/cuke_modeler/models/row.rb +55 -8
  38. data/lib/cuke_modeler/models/rule.rb +67 -8
  39. data/lib/cuke_modeler/models/scenario.rb +59 -9
  40. data/lib/cuke_modeler/models/step.rb +69 -10
  41. data/lib/cuke_modeler/models/table.rb +55 -8
  42. data/lib/cuke_modeler/models/tag.rb +38 -13
  43. data/lib/cuke_modeler/named.rb +7 -4
  44. data/lib/cuke_modeler/nested.rb +19 -4
  45. data/lib/cuke_modeler/parsed.rb +10 -5
  46. data/lib/cuke_modeler/parsing.rb +28 -16
  47. data/lib/cuke_modeler/sourceable.rb +11 -5
  48. data/lib/cuke_modeler/stepped.rb +7 -5
  49. data/lib/cuke_modeler/taggable.rb +22 -4
  50. data/lib/cuke_modeler/version.rb +1 -1
  51. data/testing/cucumber/features/modeling/background_output.feature +19 -5
  52. data/testing/cucumber/features/modeling/base_model.feature +3 -0
  53. data/testing/cucumber/features/modeling/cell_output.feature +18 -4
  54. data/testing/cucumber/features/modeling/comment_output.feature +19 -5
  55. data/testing/cucumber/features/modeling/directory_output.feature +21 -4
  56. data/testing/cucumber/features/modeling/doc_string_output.feature +19 -5
  57. data/testing/cucumber/features/modeling/example_output.feature +21 -7
  58. data/testing/cucumber/features/modeling/feature_file_output.feature +21 -4
  59. data/testing/cucumber/features/modeling/feature_output.feature +20 -6
  60. data/testing/cucumber/features/modeling/model_output.feature +53 -5
  61. data/testing/cucumber/features/modeling/outline_output.feature +19 -5
  62. data/testing/cucumber/features/modeling/row_output.feature +19 -5
  63. data/testing/cucumber/features/modeling/rule_output.feature +27 -6
  64. data/testing/cucumber/features/modeling/scenario_output.feature +19 -5
  65. data/testing/cucumber/features/modeling/step_output.feature +19 -5
  66. data/testing/cucumber/features/modeling/table_output.feature +18 -4
  67. data/testing/cucumber/features/modeling/tag_output.feature +19 -5
  68. metadata +8 -6
@@ -16,40 +16,86 @@ module CukeModeler
16
16
 
17
17
  # Creates a new Directory object and, if *directory_path* is provided,
18
18
  # populates the object.
19
+ #
20
+ # @example
21
+ # Directory.new
22
+ # Directory.new('some/directory/path')
23
+ #
24
+ # @param directory_path [String] The directory path that will be used to populate the model
25
+ # @raise [ArgumentError] If *directory_path* is not a String
26
+ # @raise [ArgumentError] If the directory path does not exist
27
+ # @return [Directory] A new Directory instance
19
28
  def initialize(directory_path = nil)
20
29
  @path = directory_path
21
30
  @feature_files = []
22
31
  @directories = []
23
32
 
24
33
  super(directory_path)
25
-
26
- return unless directory_path
27
- raise(ArgumentError, "Unknown directory: #{directory_path.inspect}") unless File.exist?(directory_path)
28
-
29
- processed_directory_data = process_directory(directory_path)
30
- populate_directory(self, processed_directory_data)
31
34
  end
32
35
 
33
36
  # Returns the name of the modeled directory.
37
+ #
38
+ # @example
39
+ # d = Directory.new('some/directory/foo')
40
+ # d.name #=> 'foo'
41
+ #
42
+ # @return [String, nil] The name of the directory
34
43
  def name
35
44
  File.basename(@path.gsub('\\', '/')) if @path
36
45
  end
37
46
 
38
- # Returns the model objects that belong to this model.
47
+ # Returns the model objects that are children of this model. For a
48
+ # Directory model, these would be any associated Directory and FeatureFile
49
+ # models.
50
+ #
51
+ # @example
52
+ # directory.children
53
+ #
54
+ # @return [Array<Directory, FeatureFile>] A collection of child models
39
55
  def children
40
56
  @feature_files + @directories
41
57
  end
42
58
 
43
- # Returns a string representation of this model. For a directory
59
+ # Returns a string representation of this model. For a Directory
44
60
  # model, this will be the path of the modeled directory.
61
+ #
62
+ # @example
63
+ # directory.to_s #=> 'some/directory/path'
64
+ #
65
+ # @return [String] A string representation of this model
45
66
  def to_s
46
67
  path.to_s
47
68
  end
48
69
 
70
+ # See `Object#inspect`. Returns some basic information about the
71
+ # object, including its class, object ID, and its most meaningful
72
+ # attribute. For a Directory model, this will be the path of the
73
+ # directory. If *verbose* is true, provides default Ruby inspection
74
+ # behavior instead.
75
+ #
76
+ # @example
77
+ # directory.inspect
78
+ # directory.inspect(verbose: true)
79
+ #
80
+ # @param verbose [Boolean] Whether or not to return the full details of
81
+ # the object. Defaults to false.
82
+ # @return [String] A string representation of this model
83
+ def inspect(verbose: false)
84
+ return super(verbose: verbose) if verbose
85
+
86
+ "#{super.chop} @path: #{@path.inspect}>"
87
+ end
88
+
49
89
 
50
90
  private
51
91
 
52
92
 
93
+ def process_source(directory_path)
94
+ raise(ArgumentError, "Unknown directory: #{directory_path.inspect}") unless File.exist?(directory_path)
95
+
96
+ process_directory(directory_path)
97
+ end
98
+
53
99
  def process_directory(directory_path)
54
100
  directory_data = { 'path' => directory_path,
55
101
  'directories' => [],
@@ -81,5 +127,17 @@ module CukeModeler
81
127
  feature_file_data.merge({ 'path' => file_path })
82
128
  end
83
129
 
130
+ def populate_model(processed_directory_data)
131
+ @path = processed_directory_data['path']
132
+
133
+ processed_directory_data['directories'].each do |directory_data|
134
+ @directories << build_child_model(Directory, directory_data)
135
+ end
136
+
137
+ processed_directory_data['feature_files'].each do |feature_file_data|
138
+ @feature_files << build_child_model(FeatureFile, feature_file_data)
139
+ end
140
+ end
141
+
84
142
  end
85
143
  end
@@ -17,28 +17,55 @@ module CukeModeler
17
17
 
18
18
  # Creates a new DocString object and, if *source_text* is provided, populates
19
19
  # the object.
20
+ #
21
+ # @example
22
+ # DocString.new
23
+ # DocString.new("\"\"\" some_type\n foo\n\"\"\"")
24
+ #
25
+ # @param source_text [String] The Gherkin text that will be used to populate the model
26
+ # @raise [ArgumentError] If *source_text* is not a String
27
+ # @return [DocString] A new DocString instance
20
28
  def initialize(source_text = nil)
21
29
  super(source_text)
22
-
23
- return unless source_text
24
-
25
- parsed_doc_string_data = parse_source(source_text)
26
- populate_docstring(self, parsed_doc_string_data)
27
30
  end
28
31
 
29
- # Returns a string representation of this model. For a doc string model,
32
+ # Returns a string representation of this model. For a DocString model,
30
33
  # this will be Gherkin text that is equivalent to the doc string being modeled.
34
+ #
35
+ # @example
36
+ # doc_string.to_s
37
+ #
38
+ # @return [String] A string representation of this model
31
39
  def to_s
32
40
  text = "\"\"\"#{content_type_output_string}\n"
33
41
  text << content_output_string
34
42
  text << '"""'
35
43
  end
36
44
 
45
+ # See `Object#inspect`. Returns some basic information about the
46
+ # object, including its class, object ID, and its most meaningful
47
+ # attribute. For a DocString model, this will be the content of the
48
+ # doc string. If *verbose* is true, provides default Ruby inspection
49
+ # behavior instead.
50
+ #
51
+ # @example
52
+ # doc_string.inspect
53
+ # doc_string.inspect(verbose: true)
54
+ #
55
+ # @param verbose [Boolean] Whether or not to return the full details of
56
+ # the object. Defaults to false.
57
+ # @return [String] A string representation of this model
58
+ def inspect(verbose: false)
59
+ return super(verbose: verbose) if verbose
60
+
61
+ "#{super.chop} @content: #{content.inspect}>"
62
+ end
63
+
37
64
 
38
65
  private
39
66
 
40
67
 
41
- def parse_source(source_text)
68
+ def process_source(source_text)
42
69
  base_file_string = "# language: #{Parsing.dialect}
43
70
  #{dialect_feature_keyword}:
44
71
  #{dialect_scenario_keyword}:
@@ -50,6 +77,21 @@ module CukeModeler
50
77
  parsed_file['feature']['elements'].first['steps'].first['doc_string']
51
78
  end
52
79
 
80
+ def populate_model(parsed_doc_string_data)
81
+ populate_content_type(parsed_doc_string_data)
82
+ populate_content(parsed_doc_string_data)
83
+ populate_parsing_data(parsed_doc_string_data)
84
+ populate_source_location(parsed_doc_string_data)
85
+ end
86
+
87
+ def populate_content_type(parsed_doc_string_data)
88
+ @content_type = parsed_doc_string_data['content_type']
89
+ end
90
+
91
+ def populate_content(parsed_doc_string_data)
92
+ @content = parsed_doc_string_data['value']
93
+ end
94
+
53
95
  def content_type_output_string
54
96
  content_type ? " #{content_type}" : ''
55
97
  end
@@ -23,28 +23,42 @@ module CukeModeler
23
23
 
24
24
  # Creates a new Example object and, if *source_text* is provided,
25
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
26
34
  def initialize(source_text = nil)
27
35
  @tags = []
28
36
  @rows = []
29
37
 
30
38
  super(source_text)
31
-
32
- return unless source_text
33
-
34
- parsed_example_data = parse_source(source_text)
35
- populate_example(self, parsed_example_data)
36
39
  end
37
40
 
41
+ # TODO: Deprecate using symbol keys in a Hash
42
+
38
43
  # Adds a row to the example table. The row can be given as a Hash of
39
44
  # parameters and their corresponding values or as an Array of values which
40
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
41
55
  def add_row(row)
42
56
  raise('Cannot add a row. No parameters have been set.') if rows.empty?
43
57
 
44
58
  # A quick 'deep clone' so that the input isn't modified
45
59
  row = Marshal.load(Marshal.dump(row))
46
60
 
47
- values = if row.is_a?(Array) # rubocop:disable Style/CaseLikeIf # False positive
61
+ values = if row.is_a?(Array)
48
62
  row
49
63
  elsif row.is_a?(Hash)
50
64
  # There is no guarantee that the user built up their hash with the keys in the same order as
@@ -58,42 +72,74 @@ module CukeModeler
58
72
  @rows << Row.new("|#{values.join('|')}|")
59
73
  end
60
74
 
75
+ # TODO: Add exception if using symbol keys in a Hash
76
+
61
77
  # Removes a row from the example table. The row can be given as a Hash of
62
78
  # parameters and their corresponding values or as an Array of values
63
79
  # which will be assigned in order.
64
- def remove_row(row_removed)
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)
65
88
  return if argument_rows.empty?
66
89
 
67
- values = if row_removed.is_a?(Array) # rubocop:disable Style/CaseLikeIf # False positive
68
- row_removed
69
- elsif row_removed.is_a?(Hash)
90
+ values = if row.is_a?(Array)
91
+ row
92
+ elsif row.is_a?(Hash)
70
93
  # There is no guarantee that the user built up their hash with the keys in the same order as
71
94
  # the parameter row and so the values have to be ordered by us.
72
- ordered_row_values(row_removed)
95
+ ordered_row_values(row)
73
96
  else
74
- raise(ArgumentError, "Can only remove row from a Hash or an Array but received #{row_removed.class}")
97
+ raise(ArgumentError, "Can only remove row from a Hash or an Array but received #{row.class}")
75
98
  end
76
99
 
77
100
  location = index_for_values(values.map(&:to_s).map(&:strip))
78
101
  @rows.delete_at(location + 1) if location
79
102
  end
80
103
 
81
- # The argument rows in the example table
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
82
111
  def argument_rows
83
112
  rows[1..rows.count] || []
84
113
  end
85
114
 
86
- # The parameter row for the example table
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
87
122
  def parameter_row
88
123
  rows.first
89
124
  end
90
125
 
91
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
92
132
  def parameters
93
133
  parameter_row ? parameter_row.cells.map(&:value) : []
94
134
  end
95
135
 
96
- # Returns the model objects that belong to this model.
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
97
143
  def children
98
144
  rows + tags
99
145
  end
@@ -101,8 +147,13 @@ module CukeModeler
101
147
  # Building strings just isn't pretty
102
148
  # rubocop:disable Metrics/AbcSize
103
149
 
104
- # Returns a string representation of this model. For an example model,
150
+ # Returns a string representation of this model. For an Example model,
105
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
106
157
  def to_s
107
158
  text = ''
108
159
 
@@ -118,11 +169,30 @@ module CukeModeler
118
169
 
119
170
  # rubocop:enable Metrics/AbcSize
120
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(verbose: verbose) if verbose
187
+
188
+ "#{super.chop} @name: #{name.inspect}>"
189
+ end
190
+
121
191
 
122
192
  private
123
193
 
124
194
 
125
- def parse_source(source_text)
195
+ def process_source(source_text)
126
196
  base_file_string = "# language: #{Parsing.dialect}
127
197
  #{dialect_feature_keyword}: Fake feature to parse
128
198
  #{dialect_outline_keyword}:
@@ -134,6 +204,22 @@ module CukeModeler
134
204
  parsed_file['feature']['elements'].first['examples'].first
135
205
  end
136
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
+
137
223
  def determine_buffer_size(index)
138
224
  rows.collect { |row| row.cells[index].to_s.length }.max || 0
139
225
  end
@@ -28,20 +28,28 @@ module CukeModeler
28
28
 
29
29
  # Creates a new Feature object and, if *source_text* is provided, populates the
30
30
  # object.
31
+ #
32
+ # @example
33
+ # Feature.new
34
+ # Feature.new("Feature:\nThis is a feature")
35
+ #
36
+ # @param source_text [String] The Gherkin text that will be used to populate the model
37
+ # @raise [ArgumentError] If *source_text* is not a String
38
+ # @return [Feature] A new Feature instance
31
39
  def initialize(source_text = nil)
32
40
  @tags = []
33
41
  @rules = []
34
42
  @tests = []
35
43
 
36
44
  super(source_text)
37
-
38
- return unless source_text
39
-
40
- parsed_feature_data = parse_source(source_text)
41
- populate_feature(self, parsed_feature_data)
42
45
  end
43
46
 
44
47
  # Returns *true* if the feature contains a background, *false* otherwise.
48
+ #
49
+ # @example
50
+ # feature.background?
51
+ #
52
+ # @return [Boolean] Whether the feature contains a background
45
53
  def background?
46
54
  !@background.nil?
47
55
  end
@@ -49,20 +57,37 @@ module CukeModeler
49
57
  alias has_background? background?
50
58
 
51
59
  # Returns the scenario models contained in the feature.
60
+ #
61
+ # @example
62
+ # feature.scenarios
63
+ #
64
+ # @return [Array<Scenario>] Child Scenario models
52
65
  def scenarios
53
66
  @tests.select { |test| test.is_a? Scenario }
54
67
  end
55
68
 
56
69
  # Returns the outline models contained in the feature.
70
+ #
71
+ # @example
72
+ # feature.outlines
73
+ #
74
+ # @return [Array<Outline>] Child Outline models
57
75
  def outlines
58
76
  @tests.select { |test| test.is_a? Outline }
59
77
  end
60
78
 
61
- # TODO: Remove this method on next major version release
62
- # DEPRECATED
79
+ # TODO: Remove this and other deprecated methods on next major version release
80
+
81
+ # @deprecated See CHANGELOG
82
+ #
63
83
  # Returns the number of test cases contained in the feature. A test case is a
64
84
  # single set of test values, such as an individual scenario or one example row
65
85
  # of an outline.
86
+ #
87
+ # @example
88
+ # feature.test_case_count
89
+ #
90
+ # @return [Integer] The count of test cases
66
91
  def test_case_count
67
92
  scenarios.count + outlines.reduce(0) do |outline_sum, outline|
68
93
  outline_sum + outline.examples.reduce(0) do |example_sum, example|
@@ -71,7 +96,14 @@ module CukeModeler
71
96
  end
72
97
  end
73
98
 
74
- # Returns the model objects that belong to this model.
99
+ # Returns the model objects that are children of this model. For a
100
+ # Feature model, these would be any associated Rule, Background,
101
+ # Scenario, Outline, or Tag models.
102
+ #
103
+ # @example
104
+ # feature.children
105
+ #
106
+ # @return [Array<Rule, Background, Scenario, Outline, Tag>] A collection of child models
75
107
  def children
76
108
  models = rules + tests + tags
77
109
  models << background if background
@@ -82,8 +114,13 @@ module CukeModeler
82
114
  # Building strings just isn't pretty
83
115
  # rubocop:disable Metrics/AbcSize
84
116
 
85
- # Returns a string representation of this model. For a feature model,
117
+ # Returns a string representation of this model. For a Feature model,
86
118
  # this will be Gherkin text that is equivalent to the feature being modeled.
119
+ #
120
+ # @example
121
+ # feature.to_s
122
+ #
123
+ # @return [String] A string representation of this model
87
124
  def to_s
88
125
  text = ''
89
126
 
@@ -99,16 +136,50 @@ module CukeModeler
99
136
 
100
137
  # rubocop:enable Metrics/AbcSize
101
138
 
139
+ # See `Object#inspect`. Returns some basic information about the
140
+ # object, including its class, object ID, and its most meaningful
141
+ # attribute. For a Feature model, this will be the name of the
142
+ # feature. If *verbose* is true, provides default Ruby inspection
143
+ # behavior instead.
144
+ #
145
+ # @example
146
+ # feature.inspect
147
+ # feature.inspect(verbose: true)
148
+ #
149
+ # @param verbose [Boolean] Whether or not to return the full details of
150
+ # the object. Defaults to false.
151
+ # @return [String] A string representation of this model
152
+ def inspect(verbose: false)
153
+ return super(verbose: verbose) if verbose
154
+
155
+ "#{super.chop} @name: #{name.inspect}>"
156
+ end
157
+
102
158
 
103
159
  private
104
160
 
105
161
 
106
- def parse_source(source_text)
162
+ def process_source(source_text)
107
163
  parsed_file = Parsing.parse_text(source_text, 'cuke_modeler_stand_alone_feature.feature')
108
164
 
109
165
  parsed_file['feature']
110
166
  end
111
167
 
168
+ def populate_model(parsed_feature_data)
169
+ populate_parsing_data(parsed_feature_data)
170
+ populate_source_location(parsed_feature_data)
171
+ populate_language(parsed_feature_data)
172
+ populate_keyword(parsed_feature_data)
173
+ populate_name(parsed_feature_data)
174
+ populate_description(parsed_feature_data)
175
+ populate_tags(parsed_feature_data)
176
+ populate_children(parsed_feature_data)
177
+ end
178
+
179
+ def populate_language(parsed_feature_data)
180
+ @language = parsed_feature_data['language']
181
+ end
182
+
112
183
  def background_output_string
113
184
  child_element_output_string(background)
114
185
  end
@@ -18,45 +18,99 @@ module CukeModeler
18
18
 
19
19
  # Creates a new FeatureFile object and, if *file_path* is provided,
20
20
  # populates the object.
21
+ #
22
+ # @example
23
+ # FeatureFile.new
24
+ # FeatureFile.new('path/to/some.feature')
25
+ #
26
+ # @param file_path [String] The file path that will be used to populate the model
27
+ # @raise [ArgumentError] If *file_path* is not a String
28
+ # @raise [ArgumentError] If the file path does not exist
29
+ # @return [FeatureFile] A new FeatureFile instance
21
30
  def initialize(file_path = nil)
22
31
  @path = file_path
23
32
  @comments = []
24
33
 
25
34
  super(file_path)
26
-
27
- return unless file_path
28
- raise(ArgumentError, "Unknown file: #{file_path.inspect}") unless File.exist?(file_path)
29
-
30
- processed_feature_file_data = process_feature_file(file_path)
31
- populate_featurefile(self, processed_feature_file_data)
32
35
  end
33
36
 
34
37
  # Returns the name of the modeled feature file.
38
+ #
39
+ # @example
40
+ # f = FeatureFile.new('path/to/some.feature')
41
+ # f.name #=> 'some.feature'
42
+ #
43
+ # @return [String] The name of the file
35
44
  def name
36
45
  File.basename(@path.gsub('\\', '/')) if @path
37
46
  end
38
47
 
39
- # Returns the model objects that belong to this model.
48
+ # Returns the model objects that are children of this model. For a
49
+ # FeatureFile model, this would be any associated Feature model.
50
+ #
51
+ # @example
52
+ # feature_file.children
53
+ #
54
+ # @return [Array<Feature>] A collection of child models
40
55
  def children
41
56
  @feature ? [@feature] : []
42
57
  end
43
58
 
44
- # Returns a string representation of this model. For a feature file
59
+ # Returns a string representation of this model. For a FeatureFile
45
60
  # model, this will be the path of the modeled feature file.
61
+ #
62
+ # @example
63
+ # feature_file.to_s #=> 'path/to/some.feature'
64
+ #
65
+ # @return [String] A string representation of this model
46
66
  def to_s
47
67
  path.to_s
48
68
  end
49
69
 
70
+ # See `Object#inspect`. Returns some basic information about the
71
+ # object, including its class, object ID, and its most meaningful
72
+ # attribute. For a FeatureFile model, this will be the path of
73
+ # the feature file. If *verbose* is true, provides default Ruby
74
+ # inspection behavior instead.
75
+ #
76
+ # @example
77
+ # feature_file.inspect
78
+ # feature_file.inspect(verbose: true)
79
+ #
80
+ # @param verbose [Boolean] Whether or not to return the full details of
81
+ # the object. Defaults to false.
82
+ # @return [String] A string representation of this model
83
+ def inspect(verbose: false)
84
+ return super(verbose: verbose) if verbose
85
+
86
+ "#{super.chop} @path: #{@path.inspect}>"
87
+ end
88
+
50
89
 
51
90
  private
52
91
 
53
92
 
54
- def process_feature_file(file_path)
55
- source_text = File.read(file_path)
93
+ def process_source(file_path)
94
+ raise(ArgumentError, "Unknown file: #{file_path.inspect}") unless File.exist?(file_path)
95
+
96
+ source_text = File.read(file_path)
56
97
  feature_file_data = Parsing.parse_text(source_text, file_path)
57
98
 
58
99
  feature_file_data.merge({ 'path' => file_path })
59
100
  end
60
101
 
102
+ def populate_model(processed_feature_file_data)
103
+ populate_parsing_data(processed_feature_file_data)
104
+ @path = processed_feature_file_data['path']
105
+
106
+ if processed_feature_file_data['feature']
107
+ @feature = build_child_model(Feature, processed_feature_file_data['feature'])
108
+ end
109
+
110
+ processed_feature_file_data['comments'].each do |comment_data|
111
+ @comments << build_child_model(Comment, comment_data)
112
+ end
113
+ end
114
+
61
115
  end
62
116
  end