cuke_modeler 3.20.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 (51) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +12 -1
  3. data/README.md +5 -6
  4. data/lib/cuke_modeler/adapters/gherkin_10_adapter.rb +5 -5
  5. data/lib/cuke_modeler/adapters/gherkin_11_adapter.rb +5 -5
  6. data/lib/cuke_modeler/adapters/gherkin_12_adapter.rb +5 -5
  7. data/lib/cuke_modeler/adapters/gherkin_13_adapter.rb +5 -5
  8. data/lib/cuke_modeler/adapters/gherkin_14_adapter.rb +5 -5
  9. data/lib/cuke_modeler/adapters/gherkin_15_adapter.rb +5 -5
  10. data/lib/cuke_modeler/adapters/gherkin_16_adapter.rb +5 -5
  11. data/lib/cuke_modeler/adapters/gherkin_17_adapter.rb +5 -5
  12. data/lib/cuke_modeler/adapters/gherkin_18_adapter.rb +5 -2
  13. data/lib/cuke_modeler/adapters/gherkin_19_adapter.rb +5 -2
  14. data/lib/cuke_modeler/adapters/gherkin_20_adapter.rb +5 -2
  15. data/lib/cuke_modeler/adapters/gherkin_21_adapter.rb +5 -5
  16. data/lib/cuke_modeler/adapters/gherkin_22_adapter.rb +5 -5
  17. data/lib/cuke_modeler/adapters/gherkin_23_adapter.rb +5 -5
  18. data/lib/cuke_modeler/adapters/gherkin_24_adapter.rb +5 -5
  19. data/lib/cuke_modeler/adapters/gherkin_25_adapter.rb +5 -5
  20. data/lib/cuke_modeler/adapters/gherkin_26_adapter.rb +5 -5
  21. data/lib/cuke_modeler/adapters/gherkin_27_adapter.rb +5 -5
  22. data/lib/cuke_modeler/adapters/gherkin_9_adapter.rb +5 -2
  23. data/lib/cuke_modeler/adapters/gherkin_base_adapter.rb +5 -2
  24. data/lib/cuke_modeler/containing.rb +43 -210
  25. data/lib/cuke_modeler/described.rb +8 -4
  26. data/lib/cuke_modeler/models/background.rb +53 -11
  27. data/lib/cuke_modeler/models/cell.rb +36 -8
  28. data/lib/cuke_modeler/models/comment.rb +35 -8
  29. data/lib/cuke_modeler/models/directory.rb +58 -10
  30. data/lib/cuke_modeler/models/doc_string.rb +41 -9
  31. data/lib/cuke_modeler/models/example.rb +94 -17
  32. data/lib/cuke_modeler/models/feature.rb +73 -11
  33. data/lib/cuke_modeler/models/feature_file.rb +56 -12
  34. data/lib/cuke_modeler/models/model.rb +50 -7
  35. data/lib/cuke_modeler/models/outline.rb +59 -10
  36. data/lib/cuke_modeler/models/row.rb +45 -9
  37. data/lib/cuke_modeler/models/rule.rb +59 -9
  38. data/lib/cuke_modeler/models/scenario.rb +51 -10
  39. data/lib/cuke_modeler/models/step.rb +61 -11
  40. data/lib/cuke_modeler/models/table.rb +45 -9
  41. data/lib/cuke_modeler/models/tag.rb +30 -14
  42. data/lib/cuke_modeler/named.rb +7 -4
  43. data/lib/cuke_modeler/nested.rb +19 -4
  44. data/lib/cuke_modeler/parsed.rb +10 -5
  45. data/lib/cuke_modeler/parsing.rb +25 -13
  46. data/lib/cuke_modeler/sourceable.rb +11 -5
  47. data/lib/cuke_modeler/stepped.rb +7 -5
  48. data/lib/cuke_modeler/taggable.rb +22 -4
  49. data/lib/cuke_modeler/version.rb +1 -1
  50. data/testing/cucumber/features/modeling/base_model.feature +3 -0
  51. metadata +3 -2
@@ -14,31 +14,55 @@ module CukeModeler
14
14
 
15
15
  # Creates a new Table object and, if *source_text* is provided, populates
16
16
  # the object.
17
+ #
18
+ # @example
19
+ # Table.new
20
+ # Table.new("|value_1|value_2|\n|value_3|value_4|")
21
+ #
22
+ # @param source_text [String] The Gherkin text that will be used to populate the model
23
+ # @raise [ArgumentError] If *source_text* is not a String
24
+ # @return [Table] A new Table instance
17
25
  def initialize(source_text = nil)
18
26
  @rows = []
19
27
 
20
28
  super(source_text)
21
-
22
- return unless source_text
23
-
24
- parsed_table_data = parse_source(source_text)
25
- populate_table(self, parsed_table_data)
26
29
  end
27
30
 
28
- # Returns the model objects that belong to this model.
31
+ # Returns the model objects that are children of this model. For a
32
+ # Table model, these would be any associated Row models.
33
+ #
34
+ # @example
35
+ # table.children
36
+ #
37
+ # @return [Array<Row>] A collection of child models
29
38
  def children
30
39
  rows
31
40
  end
32
41
 
33
- # Returns a string representation of this model. For a table model,
42
+ # Returns a string representation of this model. For a Table model,
34
43
  # this will be Gherkin text that is equivalent to the table being modeled.
44
+ #
45
+ # @example
46
+ # table.to_s
47
+ #
48
+ # @return [String] A string representation of this model
35
49
  def to_s
36
50
  rows.empty? ? '' : rows.collect { |row| row_output_string(row) }.join("\n")
37
51
  end
38
52
 
39
53
  # See `Object#inspect`. Returns some basic information about the
40
54
  # object, including its class, object ID, and its most meaningful
41
- # attribute. For a table model, this will be the rows of the table.
55
+ # attribute. For a Table model, this will be the rows of the table.
56
+ # If *verbose* is true, provides default Ruby inspection behavior
57
+ # instead.
58
+ #
59
+ # @example
60
+ # table.inspect
61
+ # table.inspect(verbose: true)
62
+ #
63
+ # @param verbose [Boolean] Whether or not to return the full details of
64
+ # the object. Defaults to false.
65
+ # @return [String] A string representation of this model
42
66
  def inspect(verbose: false)
43
67
  return super(verbose: verbose) if verbose
44
68
 
@@ -51,7 +75,7 @@ module CukeModeler
51
75
  private
52
76
 
53
77
 
54
- def parse_source(source_text)
78
+ def process_source(source_text)
55
79
  base_file_string = "# language: #{Parsing.dialect}
56
80
  #{dialect_feature_keyword}:
57
81
  #{dialect_scenario_keyword}:
@@ -63,6 +87,18 @@ module CukeModeler
63
87
  parsed_file['feature']['elements'].first['steps'].first['table']
64
88
  end
65
89
 
90
+ def populate_model(parsed_table_data)
91
+ populate_row_models(parsed_table_data)
92
+ populate_parsing_data(parsed_table_data)
93
+ populate_source_location(parsed_table_data)
94
+ end
95
+
96
+ def populate_row_models(parsed_table_data)
97
+ parsed_table_data['rows'].each do |row_data|
98
+ @rows << build_child_model(Row, row_data)
99
+ end
100
+ end
101
+
66
102
  def row_output_string(row)
67
103
  row_text = '|'
68
104
 
@@ -6,32 +6,46 @@ module CukeModeler
6
6
  include Parsing
7
7
  include Parsed
8
8
  include Sourceable
9
-
10
-
11
- # The name of the tag
12
- attr_accessor :name
9
+ include Named
13
10
 
14
11
 
15
12
  # Creates a new Tag object and, if *source_text* is provided, populates the
16
13
  # object.
14
+ #
15
+ # @example
16
+ # Tag.new
17
+ # Tag.new('@a_tag')
18
+ #
19
+ # @param source_text [String] The Gherkin text that will be used to populate the model
20
+ # @raise [ArgumentError] If *source_text* is not a String
21
+ # @return [Tag] A new Tag instance
17
22
  def initialize(source_text = nil)
18
23
  super(source_text)
19
-
20
- return unless source_text
21
-
22
- parsed_tag_data = parse_source(source_text)
23
- populate_tag(self, parsed_tag_data)
24
24
  end
25
25
 
26
- # Returns a string representation of this model. For a tag model,
26
+ # Returns a string representation of this model. For a Tag model,
27
27
  # this will be Gherkin text that is equivalent to the tag being modeled.
28
+ #
29
+ # @example
30
+ # tag.to_s
31
+ #
32
+ # @return [String] A string representation of this model
28
33
  def to_s
29
34
  name || ''
30
35
  end
31
36
 
32
37
  # See `Object#inspect`. Returns some basic information about the
33
38
  # object, including its class, object ID, and its most meaningful
34
- # attribute. For a tag model, this will be the name of the tag.
39
+ # attribute. For a Tag model, this will be the name of the tag. If
40
+ # *verbose* is true, provides default Ruby inspection behavior instead.
41
+ #
42
+ # @example
43
+ # tag.inspect
44
+ # tag.inspect(verbose: true)
45
+ #
46
+ # @param verbose [Boolean] Whether or not to return the full details of
47
+ # the object. Defaults to false.
48
+ # @return [String] A string representation of this model
35
49
  def inspect(verbose: false)
36
50
  return super(verbose: verbose) if verbose
37
51
 
@@ -42,7 +56,7 @@ module CukeModeler
42
56
  private
43
57
 
44
58
 
45
- def parse_source(source_text)
59
+ def process_source(source_text)
46
60
  base_file_string = "\n#{dialect_feature_keyword}: Fake feature to parse"
47
61
  source_text = "# language: #{Parsing.dialect}\n" + source_text + base_file_string
48
62
 
@@ -51,8 +65,10 @@ module CukeModeler
51
65
  parsed_file['feature']['tags'].first
52
66
  end
53
67
 
54
- def populate_name(model, parsed_model_data)
55
- model.name = parsed_model_data['name']
68
+ def populate_model(processed_tag_data)
69
+ populate_name(processed_tag_data)
70
+ populate_parsing_data(processed_tag_data)
71
+ populate_source_location(processed_tag_data)
56
72
  end
57
73
 
58
74
  end
@@ -1,9 +1,12 @@
1
1
  module CukeModeler
2
2
 
3
- # NOT A PART OF THE PUBLIC API
4
- # A mix-in module containing methods used by models that represent an element that has a name.
3
+ # @api private
4
+ #
5
+ # A mix-in module containing methods used by models that represent an element that has a name. Internal helper class.
5
6
  module Named
6
7
 
8
+ # @api
9
+ #
7
10
  # The name of the element
8
11
  attr_accessor :name
9
12
 
@@ -15,8 +18,8 @@ module CukeModeler
15
18
  name.nil? || name.empty? ? '' : " #{name}"
16
19
  end
17
20
 
18
- def populate_name(model, parsed_model_data)
19
- model.name = parsed_model_data['name']
21
+ def populate_name(parsed_model_data)
22
+ @name = parsed_model_data['name']
20
23
  end
21
24
 
22
25
  end
@@ -1,15 +1,30 @@
1
1
  module CukeModeler
2
2
 
3
- # NOT A PART OF THE PUBLIC API
3
+ # @api private
4
+ #
4
5
  # A mix-in module containing methods used by models that are nested inside
5
- # of other models.
6
+ # of other models. Internal helper class.
6
7
  module Nested
7
8
 
9
+ # @api
10
+ #
8
11
  # The parent model that contains this model
9
12
  attr_accessor :parent_model
10
13
 
11
-
12
- # Returns the ancestor model of this model that matches the given type.
14
+ # TODO: Use an Enum type instead of symbols as arguments?
15
+
16
+ # @api
17
+ #
18
+ # Returns the ancestor model of this model that matches the given type. Available
19
+ # types are simply snake_case versions of the model Class names. Additionally, a
20
+ # special type *:test* will return either a Scenario or an Outline model.
21
+ #
22
+ # @example
23
+ # model.get_ancestor(:directory)
24
+ #
25
+ # @param ancestor_type [Symbol] The ancestor type to get
26
+ # @raise [ArgumentError] If the passed type is not a valid model type
27
+ # @return [Model, nil] The ancestor model, if one is found
13
28
  def get_ancestor(ancestor_type)
14
29
  target_classes = classes_for_type(ancestor_type)
15
30
 
@@ -1,18 +1,23 @@
1
1
  module CukeModeler
2
2
 
3
- # NOT A PART OF THE PUBLIC API
4
- # A mix-in module containing methods used by models that are parsed from source text.
3
+ # @api private
4
+ #
5
+ # A mix-in module containing methods used by models that are parsed from
6
+ # source text. Internal helper class.
5
7
  module Parsed
6
8
 
7
- # The parsing data for this element that was generated by the parsing engine (i.e. the *gherkin* gem)
9
+ # @api
10
+ #
11
+ # The parsing data for this element that was generated by
12
+ # the parsing engine (i.e. the *cucumber-gherkin* gem)
8
13
  attr_accessor :parsing_data
9
14
 
10
15
 
11
16
  private
12
17
 
13
18
 
14
- def populate_parsing_data(model, parsed_model_data)
15
- model.parsing_data = parsed_model_data['cuke_modeler_parsing_data']
19
+ def populate_parsing_data(parsed_model_data)
20
+ @parsing_data = parsed_model_data['cuke_modeler_parsing_data']
16
21
  end
17
22
 
18
23
  end
@@ -28,18 +28,38 @@ module CukeModeler
28
28
 
29
29
 
30
30
  # The dialect that will be used to parse snippets of Gherkin text
31
+ #
32
+ # @example
33
+ # Parsing.dialect
34
+ #
35
+ # @return [String] The current dialect. Defaults to 'en'.
31
36
  def dialect
32
37
  @dialect || 'en'
33
38
  end
34
39
 
35
- # The dialects currently known by the gherkin gem
40
+ # The dialects currently known by the cucumber-gherkin gem. See *Gherkin::DIALECTS*.
41
+ #
42
+ # @example
43
+ # Parsing.dialects
44
+ #
45
+ # @return [Hash] The dialect data
36
46
  def dialects
37
47
  Gherkin::DIALECTS
38
48
  end
39
49
 
40
- # Parses the Cucumber feature given in *source_text* and returns a hash representation of
50
+ # Parses the Cucumber feature given in *source_text* and returns a Hash representation of
41
51
  # its logical structure. This is a standardized AST that should remain consistent across
42
52
  # different versions of `cucumber-gherkin`
53
+ #
54
+ # @example
55
+ # Parsing.parse_text('Feature: Some feature')
56
+ # Parsing.parse_text('Feature: Some feature', 'my.feature')
57
+ #
58
+ # @param source_text [String] The Gherkin text to parse
59
+ # @param filename [String] The file name associated with the parsed text. Used for error messages.
60
+ # @raise [ArgumentError] If *source_text* is not a String
61
+ # @raise [ArgumentError] If *source_text* does not parse cleanly
62
+ # @return [Hash] An AST of the text
43
63
  def parse_text(source_text, filename = 'cuke_modeler_fake_file.feature')
44
64
  unless source_text.is_a?(String)
45
65
  raise(ArgumentError, "Text to parse must be a String but got #{source_text.class}")
@@ -55,6 +75,9 @@ module CukeModeler
55
75
  end
56
76
 
57
77
 
78
+ private
79
+
80
+
58
81
  gherkin_version = Gem.loaded_specs['cucumber-gherkin'].version.version
59
82
  gherkin_major_version = gherkin_version.match(/^(\d+)\./)[1].to_i
60
83
 
@@ -64,8 +87,6 @@ module CukeModeler
64
87
  # rubocop:disable Lint/DuplicateMethods
65
88
  case gherkin_major_version
66
89
  when 20, 21, 22, 23, 24, 25, 26, 27
67
- # TODO: make these methods private?
68
- # NOT A PART OF THE PUBLIC API
69
90
  # The method to use for parsing Gherkin text
70
91
  def parsing_method(source_text, filename)
71
92
  messages = Gherkin.from_source(filename,
@@ -81,8 +102,6 @@ module CukeModeler
81
102
  gherkin_ast_message.gherkin_document
82
103
  end
83
104
  when 19
84
- # TODO: make these methods private?
85
- # NOT A PART OF THE PUBLIC API
86
105
  # The method to use for parsing Gherkin text
87
106
  def parsing_method(source_text, filename)
88
107
  messages = Gherkin.from_source(filename,
@@ -98,8 +117,6 @@ module CukeModeler
98
117
  gherkin_ast_message[:gherkinDocument]
99
118
  end
100
119
  when 13, 14, 15, 16, 17, 18
101
- # TODO: make these methods private?
102
- # NOT A PART OF THE PUBLIC API
103
120
  # The method to use for parsing Gherkin text
104
121
  def parsing_method(source_text, filename)
105
122
  messages = Gherkin.from_source(filename,
@@ -115,8 +132,6 @@ module CukeModeler
115
132
  gherkin_ast_message[:gherkin_document]
116
133
  end
117
134
  when 12
118
- # TODO: make these methods private?
119
- # NOT A PART OF THE PUBLIC API
120
135
  # The method to use for parsing Gherkin text
121
136
  def parsing_method(source_text, filename)
122
137
  messages = Gherkin.from_source(filename,
@@ -134,8 +149,6 @@ module CukeModeler
134
149
  gherkin_ast_message[:gherkin_document]
135
150
  end
136
151
  when 9, 10, 11
137
- # TODO: make these methods private?
138
- # NOT A PART OF THE PUBLIC API
139
152
  # The method to use for parsing Gherkin text
140
153
  def parsing_method(source_text, filename)
141
154
  messages = Gherkin.from_source(filename,
@@ -155,7 +168,6 @@ module CukeModeler
155
168
  end
156
169
  # rubocop:enable Lint/DuplicateMethods
157
170
 
158
- # NOT A PART OF THE PUBLIC API
159
171
  # The adapter to use when converting an AST to a standard internal shape
160
172
  define_method('adapter_class') do
161
173
  CukeModeler.const_get("Gherkin#{gherkin_major_version}Adapter")
@@ -1,22 +1,28 @@
1
1
  module CukeModeler
2
2
 
3
- # NOT A PART OF THE PUBLIC API
3
+ # @api private
4
+ #
4
5
  # A mix-in module containing methods used by models that know from which line of
5
- # source code they originate.
6
+ # source code they originate. Internal helper class.
6
7
  module Sourceable
7
8
 
9
+ # @api
10
+ #
8
11
  # The line number where the element began in the source code
9
12
  attr_accessor :source_line
10
13
 
14
+ # @api
15
+ #
11
16
  # The column number where the element began in the source code
12
17
  attr_accessor :source_column
13
18
 
19
+
14
20
  private
15
21
 
16
22
 
17
- def populate_source_location(model, parsed_model_data)
18
- model.source_line = parsed_model_data['line']
19
- model.source_column = parsed_model_data['column']
23
+ def populate_source_location(parsed_model_data)
24
+ @source_line = parsed_model_data['line']
25
+ @source_column = parsed_model_data['column']
20
26
  end
21
27
 
22
28
  end
@@ -1,10 +1,12 @@
1
1
  module CukeModeler
2
2
 
3
- # NOT A PART OF THE PUBLIC API
4
- # A mix-in module containing methods used by models that represent an element that has steps.
3
+ # @api private
4
+ #
5
+ # A mix-in module containing methods used by models that represent an element that has steps. Internal helper class.
5
6
  module Stepped
6
7
 
7
-
8
+ # @api
9
+ #
8
10
  # The step models contained by this model
9
11
  attr_accessor :steps
10
12
 
@@ -20,11 +22,11 @@ module CukeModeler
20
22
  step.to_s.split("\n").collect { |line| " #{line}" }.join("\n")
21
23
  end
22
24
 
23
- def populate_steps(model, parsed_model_data)
25
+ def populate_steps(parsed_model_data)
24
26
  return unless parsed_model_data['steps']
25
27
 
26
28
  parsed_model_data['steps'].each do |step_data|
27
- model.steps << build_child_model(Step, step_data)
29
+ @steps << build_child_model(Step, step_data)
28
30
  end
29
31
  end
30
32
 
@@ -1,20 +1,38 @@
1
1
  module CukeModeler
2
2
 
3
- # NOT A PART OF THE PUBLIC API
4
- # A mix-in module containing methods used by models that represent an element that can be tagged.
3
+ # @api private
4
+ #
5
+ # A mix-in module containing methods used by models that represent an element that can be
6
+ # tagged. Internal helper class.
5
7
  module Taggable
6
8
 
9
+ # @api
10
+ #
7
11
  # The models for tags which are directly assigned to the element
8
12
  attr_accessor :tags
9
13
 
10
14
 
15
+ # @api
16
+ #
11
17
  # Returns the models for tags which are indirectly assigned to the element (i.e. they
12
18
  # have been inherited from a parent element).
19
+ #
20
+ # @example
21
+ # model.applied_tags
22
+ #
23
+ # @return [Array<Tag>] Applied tag models
13
24
  def applied_tags
14
25
  parent_model.respond_to?(:all_tags) ? parent_model.all_tags : []
15
26
  end
16
27
 
28
+ # @api
29
+ #
17
30
  # Returns models for all of the tags which are applicable to the element.
31
+ #
32
+ # @example
33
+ # model.all_tags
34
+ #
35
+ # @return [Array<Tag>] All tag models
18
36
  def all_tags
19
37
  applied_tags + @tags
20
38
  end
@@ -27,11 +45,11 @@ module CukeModeler
27
45
  tags.map(&:name).join(' ')
28
46
  end
29
47
 
30
- def populate_tags(model, parsed_model_data)
48
+ def populate_tags(parsed_model_data)
31
49
  return unless parsed_model_data['tags']
32
50
 
33
51
  parsed_model_data['tags'].each do |tag|
34
- model.tags << build_child_model(Tag, tag)
52
+ @tags << build_child_model(Tag, tag)
35
53
  end
36
54
  end
37
55
 
@@ -1,4 +1,4 @@
1
1
  module CukeModeler
2
2
  # The gem version
3
- VERSION = '3.20.0'.freeze
3
+ VERSION = '3.20.1'.freeze
4
4
  end
@@ -0,0 +1,3 @@
1
+ # TODO: demo the base model class and generic model usage (it's not abstract, just situationally useful)
2
+ @wip
3
+ Feature:
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cuke_modeler
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.20.0
4
+ version: 3.20.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Eric Kessler
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-09-22 00:00:00.000000000 Z
11
+ date: 2023-10-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: cucumber-gherkin
@@ -266,6 +266,7 @@ files:
266
266
  - testing/cucumber/features/analysis/test_comparison.feature
267
267
  - testing/cucumber/features/modeling/background_modeling.feature
268
268
  - testing/cucumber/features/modeling/background_output.feature
269
+ - testing/cucumber/features/modeling/base_model.feature
269
270
  - testing/cucumber/features/modeling/cell_modeling.feature
270
271
  - testing/cucumber/features/modeling/cell_output.feature
271
272
  - testing/cucumber/features/modeling/comment_modeling.feature