cuke_modeler 3.2.0 → 3.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +48 -3
  3. data/LICENSE.txt +1 -1
  4. data/README.md +7 -7
  5. data/cuke_modeler.gemspec +35 -16
  6. data/lib/cuke_modeler.rb +1 -2
  7. data/lib/cuke_modeler/adapters/gherkin_10_adapter.rb +2 -1
  8. data/lib/cuke_modeler/adapters/gherkin_11_adapter.rb +2 -1
  9. data/lib/cuke_modeler/adapters/gherkin_12_adapter.rb +2 -1
  10. data/lib/cuke_modeler/adapters/gherkin_13_adapter.rb +2 -1
  11. data/lib/cuke_modeler/adapters/gherkin_14_adapter.rb +2 -1
  12. data/lib/cuke_modeler/adapters/gherkin_15_adapter.rb +13 -0
  13. data/lib/cuke_modeler/adapters/gherkin_16_adapter.rb +13 -0
  14. data/lib/cuke_modeler/adapters/gherkin_17_adapter.rb +13 -0
  15. data/lib/cuke_modeler/adapters/gherkin_9_adapter.rb +261 -243
  16. data/lib/cuke_modeler/containing.rb +47 -90
  17. data/lib/cuke_modeler/described.rb +40 -2
  18. data/lib/cuke_modeler/models/background.rb +11 -12
  19. data/lib/cuke_modeler/models/cell.rb +13 -8
  20. data/lib/cuke_modeler/models/comment.rb +5 -6
  21. data/lib/cuke_modeler/models/directory.rb +13 -18
  22. data/lib/cuke_modeler/models/doc_string.rb +10 -8
  23. data/lib/cuke_modeler/models/example.rb +63 -46
  24. data/lib/cuke_modeler/models/feature.rb +23 -17
  25. data/lib/cuke_modeler/models/feature_file.rb +5 -8
  26. data/lib/cuke_modeler/models/model.rb +2 -3
  27. data/lib/cuke_modeler/models/outline.rb +19 -15
  28. data/lib/cuke_modeler/models/row.rb +15 -8
  29. data/lib/cuke_modeler/models/rule.rb +11 -10
  30. data/lib/cuke_modeler/models/scenario.rb +17 -13
  31. data/lib/cuke_modeler/models/step.rb +40 -19
  32. data/lib/cuke_modeler/models/table.rb +9 -7
  33. data/lib/cuke_modeler/models/tag.rb +9 -6
  34. data/lib/cuke_modeler/named.rb +5 -2
  35. data/lib/cuke_modeler/nested.rb +22 -19
  36. data/lib/cuke_modeler/parsed.rb +8 -1
  37. data/lib/cuke_modeler/parsing.rb +38 -29
  38. data/lib/cuke_modeler/sourceable.rb +8 -1
  39. data/lib/cuke_modeler/stepped.rb +8 -1
  40. data/lib/cuke_modeler/taggable.rb +9 -2
  41. data/lib/cuke_modeler/version.rb +1 -1
  42. metadata +91 -36
@@ -1,7 +1,6 @@
1
1
  module CukeModeler
2
2
 
3
3
  # A class modeling a rule in a Cucumber suite.
4
-
5
4
  class Rule < Model
6
5
 
7
6
  include Parsing
@@ -28,17 +27,19 @@ module CukeModeler
28
27
 
29
28
  super(source_text)
30
29
 
31
- if source_text
32
- parsed_rule_data = parse_source(source_text)
33
- populate_rule(self, parsed_rule_data)
34
- end
30
+ return unless source_text
31
+
32
+ parsed_rule_data = parse_source(source_text)
33
+ populate_rule(self, parsed_rule_data)
35
34
  end
36
35
 
37
36
  # Returns *true* if the rule contains a background, *false* otherwise.
38
- def has_background?
37
+ def background?
39
38
  !@background.nil?
40
39
  end
41
40
 
41
+ alias has_background? background?
42
+
42
43
  # Returns the scenario models contained in the rule.
43
44
  def scenarios
44
45
  @tests.select { |test| test.is_a? Scenario }
@@ -63,9 +64,9 @@ module CukeModeler
63
64
  text = ''
64
65
 
65
66
  text << "#{@keyword}:#{name_output_string}"
66
- text << "\n" + description_output_string unless (description.nil? || description.empty?)
67
- text << "\n\n" + background_output_string if background
68
- text << "\n\n" + tests_output_string unless tests.empty?
67
+ text << "\n#{description_output_string}" unless no_description_to_output?
68
+ text << "\n\n#{background_output_string}" if background
69
+ text << "\n\n#{tests_output_string}" unless tests.empty?
69
70
 
70
71
  text
71
72
  end
@@ -78,7 +79,7 @@ module CukeModeler
78
79
  base_file_string = "# language: #{Parsing.dialect}\n#{dialect_feature_keyword}: Fake feature to parse\n"
79
80
  source_text = base_file_string + source_text
80
81
 
81
- parsed_file = Parsing::parse_text(source_text, 'cuke_modeler_stand_alone_rule.feature')
82
+ parsed_file = Parsing.parse_text(source_text, 'cuke_modeler_stand_alone_rule.feature')
82
83
 
83
84
  parsed_file['feature']['elements'].first
84
85
  end
@@ -1,7 +1,6 @@
1
1
  module CukeModeler
2
2
 
3
3
  # A class modeling an individual scenario of a Cucumber suite.
4
-
5
4
  class Scenario < Model
6
5
 
7
6
  include Parsing
@@ -25,17 +24,17 @@ module CukeModeler
25
24
 
26
25
  super(source_text)
27
26
 
28
- if source_text
29
- parsed_scenario_data = parse_source(source_text)
30
- populate_scenario(self, parsed_scenario_data)
31
- end
27
+ return unless source_text
28
+
29
+ parsed_scenario_data = parse_source(source_text)
30
+ populate_scenario(self, parsed_scenario_data)
32
31
  end
33
32
 
34
33
  # Returns *true* if the two models have equivalent steps and *false* otherwise.
35
- def ==(other_model)
36
- return false unless other_model.respond_to?(:steps)
34
+ def ==(other)
35
+ return false unless other.respond_to?(:steps)
37
36
 
38
- steps == other_model.steps
37
+ steps == other.steps
39
38
  end
40
39
 
41
40
  # Returns the model objects that belong to this model.
@@ -43,20 +42,25 @@ module CukeModeler
43
42
  steps + tags
44
43
  end
45
44
 
45
+ # Building strings just isn't pretty
46
+ # rubocop:disable Metrics/AbcSize
47
+
46
48
  # Returns a string representation of this model. For a scenario model,
47
49
  # this will be Gherkin text that is equivalent to the scenario being modeled.
48
50
  def to_s
49
51
  text = ''
50
52
 
51
- text << tag_output_string + "\n" unless tags.empty?
53
+ text << "#{tag_output_string}\n" unless tags.empty?
52
54
  text << "#{@keyword}:#{name_output_string}"
53
- text << "\n" + description_output_string unless (description.nil? || description.empty?)
54
- text << "\n" unless (steps.empty? || description.nil? || description.empty?)
55
- text << "\n" + steps_output_string unless steps.empty?
55
+ text << "\n#{description_output_string}" unless no_description_to_output?
56
+ text << "\n" unless steps.empty? || no_description_to_output?
57
+ text << "\n#{steps_output_string}" unless steps.empty?
56
58
 
57
59
  text
58
60
  end
59
61
 
62
+ # rubocop:enable Metrics/AbcSize
63
+
60
64
 
61
65
  private
62
66
 
@@ -65,7 +69,7 @@ module CukeModeler
65
69
  base_file_string = "# language: #{Parsing.dialect}\n#{dialect_feature_keyword}: Fake feature to parse\n"
66
70
  source_text = base_file_string + source_text
67
71
 
68
- parsed_file = Parsing::parse_text(source_text, 'cuke_modeler_stand_alone_scenario.feature')
72
+ parsed_file = Parsing.parse_text(source_text, 'cuke_modeler_stand_alone_scenario.feature')
69
73
 
70
74
  parsed_file['feature']['elements'].first
71
75
  end
@@ -1,7 +1,6 @@
1
1
  module CukeModeler
2
2
 
3
3
  # A class modeling a single step of a background, scenario, or outline.
4
-
5
4
  class Step < Model
6
5
 
7
6
  include Sourceable
@@ -24,20 +23,20 @@ module CukeModeler
24
23
  def initialize(source_text = nil)
25
24
  super(source_text)
26
25
 
27
- if source_text
28
- parsed_step_data = parse_source(source_text)
29
- populate_step(self, parsed_step_data)
30
- end
26
+ return unless source_text
27
+
28
+ parsed_step_data = parse_source(source_text)
29
+ populate_step(self, parsed_step_data)
31
30
  end
32
31
 
33
32
  # Returns *true* if the two steps have the same base text (i.e. minus any keyword,
34
33
  # table, or doc string and *false* otherwise.
35
- def ==(other_step)
36
- return false unless other_step.is_a?(CukeModeler::Step)
34
+ def ==(other)
35
+ return false unless other.is_a?(CukeModeler::Step)
37
36
 
38
- text_matches?(other_step) &&
39
- table_matches?(other_step) &&
40
- doc_string_matches?(other_step)
37
+ text_matches?(other) &&
38
+ table_matches?(other) &&
39
+ doc_string_matches?(other)
41
40
  end
42
41
 
43
42
  # Returns the model objects that belong to this model.
@@ -49,7 +48,7 @@ module CukeModeler
49
48
  # this will be Gherkin text that is equivalent to the step being modeled.
50
49
  def to_s
51
50
  text = "#{keyword} #{self.text}"
52
- text << "\n" + block.to_s.split("\n").collect { |line| " #{line}" }.join("\n") if block
51
+ text << "\n#{block.to_s.split("\n").collect { |line| " #{line}" }.join("\n")}" if block
53
52
 
54
53
  text
55
54
  end
@@ -59,10 +58,12 @@ module CukeModeler
59
58
 
60
59
 
61
60
  def parse_source(source_text)
62
- base_file_string = "# language: #{Parsing.dialect}\n#{dialect_feature_keyword}: Fake feature to parse\n#{dialect_scenario_keyword}:\n"
61
+ base_file_string = "# language: #{Parsing.dialect}
62
+ #{dialect_feature_keyword}: Fake feature to parse
63
+ #{dialect_scenario_keyword}:\n"
63
64
  source_text = base_file_string + source_text
64
65
 
65
- parsed_file = Parsing::parse_text(source_text, 'cuke_modeler_stand_alone_step.feature')
66
+ parsed_file = Parsing.parse_text(source_text, 'cuke_modeler_stand_alone_step.feature')
66
67
 
67
68
  parsed_file['feature']['elements'].first['steps'].first
68
69
  end
@@ -72,18 +73,18 @@ module CukeModeler
72
73
  end
73
74
 
74
75
  def table_matches?(other_step)
75
- return false if (!block.is_a?(CukeModeler::Table) || !other_step.block.is_a?(CukeModeler::Table)) && (block.is_a?(CukeModeler::Table) || other_step.block.is_a?(CukeModeler::Table))
76
- return true unless block.is_a?(CukeModeler::Table) && other_step.block.is_a?(CukeModeler::Table)
76
+ return false if only_one_step_has_table?(other_step)
77
+ return true if neither_step_has_table?(other_step)
77
78
 
78
- first_step_values = block.rows.collect { |table_row| table_row.cells.map(&:value) }
79
+ first_step_values = block.rows.collect { |table_row| table_row.cells.map(&:value) }
79
80
  second_step_values = other_step.block.rows.collect { |table_row| table_row.cells.map(&:value) }
80
81
 
81
82
  first_step_values == second_step_values
82
83
  end
83
84
 
84
85
  def doc_string_matches?(other_step)
85
- return false if (!block.is_a?(CukeModeler::DocString) || !other_step.block.is_a?(CukeModeler::DocString)) && (block.is_a?(CukeModeler::DocString) || other_step.block.is_a?(CukeModeler::DocString))
86
- return true unless block.is_a?(CukeModeler::DocString) && other_step.block.is_a?(CukeModeler::DocString)
86
+ return false if only_one_step_has_doc_string?(other_step)
87
+ return true if neither_step_has_doc_string?(other_step)
87
88
 
88
89
  first_content = block.content
89
90
  first_content_type = block.content_type
@@ -91,7 +92,27 @@ module CukeModeler
91
92
  second_content_type = other_step.block.content_type
92
93
 
93
94
  (first_content == second_content) &&
94
- (first_content_type == second_content_type)
95
+ (first_content_type == second_content_type)
96
+ end
97
+
98
+ def only_one_step_has_table?(other_step)
99
+ (!block.is_a?(CukeModeler::Table) || !other_step.block.is_a?(CukeModeler::Table)) &&
100
+ (block.is_a?(CukeModeler::Table) || other_step.block.is_a?(CukeModeler::Table))
101
+ end
102
+
103
+ def neither_step_has_table?(other_step)
104
+ !block.is_a?(CukeModeler::Table) &&
105
+ !other_step.block.is_a?(CukeModeler::Table)
106
+ end
107
+
108
+ def only_one_step_has_doc_string?(other_step)
109
+ (!block.is_a?(CukeModeler::DocString) || !other_step.block.is_a?(CukeModeler::DocString)) &&
110
+ (block.is_a?(CukeModeler::DocString) || other_step.block.is_a?(CukeModeler::DocString))
111
+ end
112
+
113
+ def neither_step_has_doc_string?(other_step)
114
+ !block.is_a?(CukeModeler::DocString) &&
115
+ !other_step.block.is_a?(CukeModeler::DocString)
95
116
  end
96
117
 
97
118
  end
@@ -1,7 +1,6 @@
1
1
  module CukeModeler
2
2
 
3
3
  # A class modeling a step's table.
4
-
5
4
  class Table < Model
6
5
 
7
6
  include Parsing
@@ -20,10 +19,10 @@ module CukeModeler
20
19
 
21
20
  super(source_text)
22
21
 
23
- if source_text
24
- parsed_table_data = parse_source(source_text)
25
- populate_table(self, parsed_table_data)
26
- end
22
+ return unless source_text
23
+
24
+ parsed_table_data = parse_source(source_text)
25
+ populate_table(self, parsed_table_data)
27
26
  end
28
27
 
29
28
  # Returns the model objects that belong to this model.
@@ -42,10 +41,13 @@ module CukeModeler
42
41
 
43
42
 
44
43
  def parse_source(source_text)
45
- base_file_string = "# language: #{Parsing.dialect}\n#{dialect_feature_keyword}:\n#{dialect_scenario_keyword}:\n#{dialect_step_keyword} step\n"
44
+ base_file_string = "# language: #{Parsing.dialect}
45
+ #{dialect_feature_keyword}:
46
+ #{dialect_scenario_keyword}:
47
+ #{dialect_step_keyword} step\n"
46
48
  source_text = base_file_string + source_text
47
49
 
48
- parsed_file = Parsing::parse_text(source_text, 'cuke_modeler_stand_alone_table.feature')
50
+ parsed_file = Parsing.parse_text(source_text, 'cuke_modeler_stand_alone_table.feature')
49
51
 
50
52
  parsed_file['feature']['elements'].first['steps'].first['table']
51
53
  end
@@ -1,7 +1,6 @@
1
1
  module CukeModeler
2
2
 
3
3
  # A class modeling a tag.
4
-
5
4
  class Tag < Model
6
5
 
7
6
  include Parsing
@@ -18,10 +17,10 @@ module CukeModeler
18
17
  def initialize(source_text = nil)
19
18
  super(source_text)
20
19
 
21
- if source_text
22
- parsed_tag_data = parse_source(source_text)
23
- populate_tag(self, parsed_tag_data)
24
- end
20
+ return unless source_text
21
+
22
+ parsed_tag_data = parse_source(source_text)
23
+ populate_tag(self, parsed_tag_data)
25
24
  end
26
25
 
27
26
  # Returns a string representation of this model. For a tag model,
@@ -38,10 +37,14 @@ module CukeModeler
38
37
  base_file_string = "\n#{dialect_feature_keyword}: Fake feature to parse"
39
38
  source_text = "# language: #{Parsing.dialect}\n" + source_text + base_file_string
40
39
 
41
- parsed_file = Parsing::parse_text(source_text, 'cuke_modeler_stand_alone_tag.feature')
40
+ parsed_file = Parsing.parse_text(source_text, 'cuke_modeler_stand_alone_tag.feature')
42
41
 
43
42
  parsed_file['feature']['tags'].first
44
43
  end
45
44
 
45
+ def populate_name(model, parsed_model_data)
46
+ model.name = parsed_model_data['name']
47
+ end
48
+
46
49
  end
47
50
  end
@@ -2,7 +2,6 @@ module CukeModeler
2
2
 
3
3
  # NOT A PART OF THE PUBLIC API
4
4
  # A mix-in module containing methods used by models that represent an element that has a name.
5
-
6
5
  module Named
7
6
 
8
7
  # The name of the element
@@ -13,7 +12,11 @@ module CukeModeler
13
12
 
14
13
 
15
14
  def name_output_string
16
- (name.nil? || name.empty?) ? '' : " #{name}"
15
+ name.nil? || name.empty? ? '' : " #{name}"
16
+ end
17
+
18
+ def populate_name(model, parsed_model_data)
19
+ model.name = parsed_model_data['name']
17
20
  end
18
21
 
19
22
  end
@@ -3,7 +3,6 @@ module CukeModeler
3
3
  # NOT A PART OF THE PUBLIC API
4
4
  # A mix-in module containing methods used by models that are nested inside
5
5
  # of other models.
6
-
7
6
  module Nested
8
7
 
9
8
  # The parent model that contains this model
@@ -12,30 +11,34 @@ module CukeModeler
12
11
 
13
12
  # Returns the ancestor model of this model that matches the given type.
14
13
  def get_ancestor(ancestor_type)
15
- target_type = {:directory => [Directory],
16
- :feature_file => [FeatureFile],
17
- :feature => [Feature],
18
- :test => [Scenario, Outline, Background],
19
- :background => [Background],
20
- :scenario => [Scenario],
21
- :outline => [Outline],
22
- :step => [Step],
23
- :table => [Table],
24
- :example => [Example],
25
- :row => [Row]
26
- }[ancestor_type]
14
+ target_classes = classes_for_type(ancestor_type)
27
15
 
28
- raise(ArgumentError, "Unknown ancestor type '#{ancestor_type}'.") if target_type.nil?
16
+ raise(ArgumentError, "Unknown ancestor type '#{ancestor_type}'.") if target_classes.nil?
29
17
 
18
+ ancestor = parent_model
19
+ ancestor = ancestor.parent_model until target_classes.include?(ancestor.class) || ancestor.nil?
30
20
 
31
- ancestor = self.parent_model
21
+ ancestor
22
+ end
32
23
 
33
- until target_type.include?(ancestor.class) || ancestor.nil?
34
- ancestor = ancestor.parent_model
35
- end
36
24
 
25
+ private
37
26
 
38
- ancestor
27
+
28
+ def classes_for_type(type)
29
+ {
30
+ directory: [Directory],
31
+ feature_file: [FeatureFile],
32
+ feature: [Feature],
33
+ test: [Scenario, Outline, Background],
34
+ background: [Background],
35
+ scenario: [Scenario],
36
+ outline: [Outline],
37
+ step: [Step],
38
+ table: [Table],
39
+ example: [Example],
40
+ row: [Row]
41
+ }[type]
39
42
  end
40
43
 
41
44
  end
@@ -2,11 +2,18 @@ module CukeModeler
2
2
 
3
3
  # NOT A PART OF THE PUBLIC API
4
4
  # A mix-in module containing methods used by models that are parsed from source text.
5
-
6
5
  module Parsed
7
6
 
8
7
  # The parsing data for this element that was generated by the parsing engine (i.e. the *gherkin* gem)
9
8
  attr_accessor :parsing_data
10
9
 
10
+
11
+ private
12
+
13
+
14
+ def populate_parsing_data(model, parsed_model_data)
15
+ model.parsing_data = parsed_model_data['cuke_modeler_parsing_data']
16
+ end
17
+
11
18
  end
12
19
  end
@@ -1,13 +1,6 @@
1
1
  # Have to at least load some version of the gem before which version of the gem has been loaded can
2
- # be determined and the rest of the needed files can be loaded. The entry points vary across versions,
3
- # so try them all until one of them works.
4
- begin
5
- # Gherkin 9.x
6
- require 'gherkin'
7
- rescue LoadError => e
8
- # Add other entry points again if things change again
9
- raise e
10
- end
2
+ # be determined and the rest of the needed files can be loaded.
3
+ require 'gherkin'
11
4
 
12
5
 
13
6
  # The *cucumber-gherkin* gem loads differently and has different grammar rules across major versions. Parsing
@@ -16,12 +9,16 @@ end
16
9
  gherkin_version = Gem.loaded_specs['cucumber-gherkin'].version.version
17
10
  gherkin_major_version = gherkin_version.match(/^(\d+)\./)[1].to_i
18
11
 
12
+ # Previous versions of the gem did not use the conventional entry point, so I'm leaving this here in case it
13
+ # changes again
14
+ # rubocop:disable Lint/EmptyWhen
19
15
  case gherkin_major_version
20
- when 9, 10, 11, 12, 13, 14
16
+ when 9, 10, 11, 12, 13, 14, 15, 16, 17
21
17
  # Currently nothing else to load beyond the entry point to the gem
22
18
  else
23
19
  raise("Unknown Gherkin version: '#{gherkin_version}'")
24
20
  end
21
+ # rubocop:enable Lint/EmptyWhen
25
22
 
26
23
  require "cuke_modeler/adapters/gherkin_#{gherkin_major_version}_adapter"
27
24
 
@@ -29,7 +26,6 @@ require "cuke_modeler/adapters/gherkin_#{gherkin_major_version}_adapter"
29
26
  module CukeModeler
30
27
 
31
28
  # A module providing source text parsing functionality.
32
-
33
29
  module Parsing
34
30
 
35
31
  class << self
@@ -45,18 +41,16 @@ module CukeModeler
45
41
 
46
42
  # The dialects currently known by the gherkin gem
47
43
  def dialects
48
- unless @dialects
49
- @dialects = Gherkin::DIALECTS
50
- end
51
-
52
- @dialects
44
+ @dialects ||= Gherkin::DIALECTS
53
45
  end
54
46
 
55
47
  # Parses the Cucumber feature given in *source_text* and returns a hash representation of
56
48
  # its logical structure. This is a standardized AST that should remain consistent across
57
49
  # different versions of `cucumber-gherkin`
58
50
  def parse_text(source_text, filename = 'cuke_modeler_fake_file.feature')
59
- raise(ArgumentError, "Text to parse must be a String but got #{source_text.class}") unless source_text.is_a?(String)
51
+ unless source_text.is_a?(String)
52
+ raise(ArgumentError, "Text to parse must be a String but got #{source_text.class}")
53
+ end
60
54
 
61
55
  begin
62
56
  parsed_result = parsing_method(source_text.encode('UTF-8'), filename)
@@ -71,13 +65,20 @@ module CukeModeler
71
65
  gherkin_version = Gem.loaded_specs['cucumber-gherkin'].version.version
72
66
  gherkin_major_version = gherkin_version.match(/^(\d+)\./)[1].to_i
73
67
 
68
+ # Previous versions of the gem had more variation between their parsing methods and so it was more
69
+ # understandable to have different methods instead of a single method with lots of conditional statements
70
+ # inside of it, so I'm leaving this here in case it changes again
71
+ # rubocop:disable Lint/DuplicateMethods
74
72
  case gherkin_major_version
75
- when 13, 14
76
- # todo - make these methods private?
73
+ when 13, 14, 15, 16, 17
74
+ # TODO: make these methods private?
77
75
  # NOT A PART OF THE PUBLIC API
78
76
  # The method to use for parsing Gherkin text
79
77
  def parsing_method(source_text, filename)
80
- messages = Gherkin.from_source(filename, source_text, { :include_gherkin_document => true }).to_a.map(&:to_hash)
78
+ messages = Gherkin.from_source(filename,
79
+ source_text,
80
+ { include_gherkin_document: true })
81
+ .to_a.map(&:to_hash)
81
82
 
82
83
  error_message = messages.find { |message| message[:parse_error] }
83
84
  gherkin_ast_message = messages.find { |message| message[:gherkin_document] }
@@ -87,33 +88,39 @@ module CukeModeler
87
88
  gherkin_ast_message[:gherkin_document]
88
89
  end
89
90
  when 12
90
- # todo - make these methods private?
91
+ # TODO: make these methods private?
91
92
  # NOT A PART OF THE PUBLIC API
92
93
  # The method to use for parsing Gherkin text
93
94
  def parsing_method(source_text, filename)
94
- messages = Gherkin.from_source(filename, source_text, { :include_gherkin_document => true }).to_a.map(&:to_hash)
95
+ messages = Gherkin.from_source(filename,
96
+ source_text,
97
+ { include_gherkin_document: true })
98
+ .to_a.map(&:to_hash)
95
99
 
96
100
  potential_error_message = messages.find { |message| message[:attachment] }
97
101
  gherkin_ast_message = messages.find { |message| message[:gherkin_document] }
98
102
 
99
- if potential_error_message
100
- raise potential_error_message[:attachment][:body] if potential_error_message[:attachment][:body] =~ /expected.*got/
103
+ if potential_error_message && potential_error_message[:attachment][:body] =~ /expected.*got/
104
+ raise potential_error_message[:attachment][:body]
101
105
  end
102
106
 
103
107
  gherkin_ast_message[:gherkin_document]
104
108
  end
105
109
  when 9, 10, 11
106
- # todo - make these methods private?
110
+ # TODO: make these methods private?
107
111
  # NOT A PART OF THE PUBLIC API
108
112
  # The method to use for parsing Gherkin text
109
113
  def parsing_method(source_text, filename)
110
- messages = Gherkin.from_source(filename, source_text, { :include_gherkin_document => true }).to_a.map(&:to_hash)
114
+ messages = Gherkin.from_source(filename,
115
+ source_text,
116
+ { include_gherkin_document: true })
117
+ .to_a.map(&:to_hash)
111
118
 
112
119
  potential_error_message = messages.find { |message| message[:attachment] }
113
120
  gherkin_ast_message = messages.find { |message| message[:gherkin_document] }
114
121
 
115
- if potential_error_message
116
- raise potential_error_message[:attachment][:text] if potential_error_message[:attachment][:text] =~ /expected.*got/
122
+ if potential_error_message && potential_error_message[:attachment][:text] =~ /expected.*got/
123
+ raise potential_error_message[:attachment][:text]
117
124
  end
118
125
 
119
126
  gherkin_ast_message[:gherkin_document]
@@ -121,6 +128,7 @@ module CukeModeler
121
128
  else
122
129
  raise("Unknown Gherkin version: '#{gherkin_version}'")
123
130
  end
131
+ # rubocop:enable Lint/DuplicateMethods
124
132
 
125
133
  # NOT A PART OF THE PUBLIC API
126
134
  # The adapter to use when converting an AST to a standard internal shape
@@ -143,7 +151,8 @@ module CukeModeler
143
151
  end
144
152
 
145
153
  def dialect_outline_keyword
146
- get_word(Parsing.dialects[Parsing.dialect]['scenarioOutline'] || Parsing.dialects[Parsing.dialect]['scenario_outline'])
154
+ get_word(Parsing.dialects[Parsing.dialect]['scenarioOutline'] ||
155
+ Parsing.dialects[Parsing.dialect]['scenario_outline'])
147
156
  end
148
157
 
149
158
  def dialect_step_keyword