cuke_modeler 2.1.0 → 3.4.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 (146) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +53 -1
  3. data/README.md +14 -16
  4. data/cuke_modeler.gemspec +33 -21
  5. data/lib/cuke_modeler.rb +2 -1
  6. data/lib/cuke_modeler/adapters/gherkin_10_adapter.rb +13 -0
  7. data/lib/cuke_modeler/adapters/gherkin_11_adapter.rb +13 -0
  8. data/lib/cuke_modeler/adapters/gherkin_12_adapter.rb +13 -0
  9. data/lib/cuke_modeler/adapters/gherkin_13_adapter.rb +13 -0
  10. data/lib/cuke_modeler/adapters/gherkin_14_adapter.rb +13 -0
  11. data/lib/cuke_modeler/adapters/gherkin_15_adapter.rb +13 -0
  12. data/lib/cuke_modeler/adapters/gherkin_9_adapter.rb +356 -4
  13. data/lib/cuke_modeler/containing.rb +41 -89
  14. data/lib/cuke_modeler/described.rb +40 -1
  15. data/lib/cuke_modeler/models/background.rb +12 -12
  16. data/lib/cuke_modeler/models/cell.rb +14 -8
  17. data/lib/cuke_modeler/models/comment.rb +6 -6
  18. data/lib/cuke_modeler/models/directory.rb +14 -18
  19. data/lib/cuke_modeler/models/doc_string.rb +11 -8
  20. data/lib/cuke_modeler/models/example.rb +64 -46
  21. data/lib/cuke_modeler/models/feature.rb +38 -20
  22. data/lib/cuke_modeler/models/feature_file.rb +6 -8
  23. data/lib/cuke_modeler/models/model.rb +2 -1
  24. data/lib/cuke_modeler/models/outline.rb +20 -15
  25. data/lib/cuke_modeler/models/row.rb +11 -8
  26. data/lib/cuke_modeler/models/rule.rb +101 -0
  27. data/lib/cuke_modeler/models/scenario.rb +18 -13
  28. data/lib/cuke_modeler/models/step.rb +41 -19
  29. data/lib/cuke_modeler/models/table.rb +10 -7
  30. data/lib/cuke_modeler/models/tag.rb +10 -6
  31. data/lib/cuke_modeler/named.rb +5 -1
  32. data/lib/cuke_modeler/nested.rb +22 -18
  33. data/lib/cuke_modeler/parsed.rb +8 -0
  34. data/lib/cuke_modeler/parsing.rb +55 -74
  35. data/lib/cuke_modeler/sourceable.rb +8 -0
  36. data/lib/cuke_modeler/stepped.rb +8 -0
  37. data/lib/cuke_modeler/taggable.rb +9 -1
  38. data/lib/cuke_modeler/version.rb +1 -1
  39. data/testing/cucumber/features/modeling/feature_modeling.feature +28 -7
  40. data/testing/cucumber/features/modeling/feature_output.feature +45 -23
  41. data/testing/cucumber/features/modeling/rule_modeling.feature +108 -0
  42. data/testing/cucumber/features/modeling/rule_output.feature +111 -0
  43. metadata +68 -161
  44. data/.gitignore +0 -18
  45. data/.simplecov +0 -7
  46. data/.travis.yml +0 -81
  47. data/Gemfile +0 -44
  48. data/Rakefile +0 -73
  49. data/appveyor.yml +0 -88
  50. data/lib/cuke_modeler/adapters/gherkin_2_adapter.rb +0 -274
  51. data/lib/cuke_modeler/adapters/gherkin_3_adapter.rb +0 -297
  52. data/lib/cuke_modeler/adapters/gherkin_4_adapter.rb +0 -309
  53. data/lib/cuke_modeler/adapters/gherkin_5_adapter.rb +0 -12
  54. data/lib/cuke_modeler/adapters/gherkin_6_adapter.rb +0 -310
  55. data/lib/cuke_modeler/adapters/gherkin_7_adapter.rb +0 -307
  56. data/lib/cuke_modeler/adapters/gherkin_8_adapter.rb +0 -12
  57. data/testing/cucumber/step_definitions/action_steps.rb +0 -13
  58. data/testing/cucumber/step_definitions/background_steps.rb +0 -1
  59. data/testing/cucumber/step_definitions/directory_steps.rb +0 -6
  60. data/testing/cucumber/step_definitions/doc_string_steps.rb +0 -1
  61. data/testing/cucumber/step_definitions/feature_file_steps.rb +0 -16
  62. data/testing/cucumber/step_definitions/feature_steps.rb +0 -7
  63. data/testing/cucumber/step_definitions/modeling_steps.rb +0 -49
  64. data/testing/cucumber/step_definitions/setup_steps.rb +0 -32
  65. data/testing/cucumber/step_definitions/step_steps.rb +0 -3
  66. data/testing/cucumber/step_definitions/table_steps.rb +0 -1
  67. data/testing/cucumber/step_definitions/tag_steps.rb +0 -3
  68. data/testing/cucumber/step_definitions/verification_steps.rb +0 -181
  69. data/testing/cucumber/support/env.rb +0 -30
  70. data/testing/dialect_helper.rb +0 -48
  71. data/testing/file_helper.rb +0 -47
  72. data/testing/gemfiles/gherkin2.gemfile +0 -33
  73. data/testing/gemfiles/gherkin3.gemfile +0 -26
  74. data/testing/gemfiles/gherkin4.gemfile +0 -27
  75. data/testing/gemfiles/gherkin5.gemfile +0 -27
  76. data/testing/gemfiles/gherkin6.gemfile +0 -10
  77. data/testing/gemfiles/gherkin7.gemfile +0 -9
  78. data/testing/gemfiles/gherkin8.gemfile +0 -9
  79. data/testing/gemfiles/gherkin9.gemfile +0 -9
  80. data/testing/helper_methods.rb +0 -23
  81. data/testing/rspec/spec/integration/adapters/gherkin_2_adapter_spec.rb +0 -166
  82. data/testing/rspec/spec/integration/adapters/gherkin_3_adapter_spec.rb +0 -166
  83. data/testing/rspec/spec/integration/adapters/gherkin_4_adapter_spec.rb +0 -165
  84. data/testing/rspec/spec/integration/adapters/gherkin_5_adapter_spec.rb +0 -165
  85. data/testing/rspec/spec/integration/adapters/gherkin_6_adapter_spec.rb +0 -159
  86. data/testing/rspec/spec/integration/adapters/gherkin_7_adapter_spec.rb +0 -162
  87. data/testing/rspec/spec/integration/adapters/gherkin_8_adapter_spec.rb +0 -162
  88. data/testing/rspec/spec/integration/adapters/gherkin_9_adapter_spec.rb +0 -162
  89. data/testing/rspec/spec/integration/models/background_integration_spec.rb +0 -438
  90. data/testing/rspec/spec/integration/models/cell_integration_spec.rb +0 -338
  91. data/testing/rspec/spec/integration/models/comment_integration_spec.rb +0 -180
  92. data/testing/rspec/spec/integration/models/directory_integration_spec.rb +0 -218
  93. data/testing/rspec/spec/integration/models/doc_string_integration_spec.rb +0 -398
  94. data/testing/rspec/spec/integration/models/example_integration_spec.rb +0 -753
  95. data/testing/rspec/spec/integration/models/feature_file_integration_spec.rb +0 -276
  96. data/testing/rspec/spec/integration/models/feature_integration_spec.rb +0 -655
  97. data/testing/rspec/spec/integration/models/model_integration_spec.rb +0 -15
  98. data/testing/rspec/spec/integration/models/outline_integration_spec.rb +0 -619
  99. data/testing/rspec/spec/integration/models/row_integration_spec.rb +0 -303
  100. data/testing/rspec/spec/integration/models/scenario_integration_spec.rb +0 -475
  101. data/testing/rspec/spec/integration/models/step_integration_spec.rb +0 -573
  102. data/testing/rspec/spec/integration/models/table_integration_spec.rb +0 -333
  103. data/testing/rspec/spec/integration/models/tag_integration_spec.rb +0 -271
  104. data/testing/rspec/spec/integration/nested_integration_spec.rb +0 -91
  105. data/testing/rspec/spec/integration/parsing_integration_spec.rb +0 -143
  106. data/testing/rspec/spec/integration/shared/models_integration_specs.rb +0 -18
  107. data/testing/rspec/spec/spec_helper.rb +0 -129
  108. data/testing/rspec/spec/unit/cuke_modeler_unit_spec.rb +0 -25
  109. data/testing/rspec/spec/unit/described_unit_spec.rb +0 -23
  110. data/testing/rspec/spec/unit/models/background_unit_spec.rb +0 -83
  111. data/testing/rspec/spec/unit/models/cell_unit_spec.rb +0 -68
  112. data/testing/rspec/spec/unit/models/comment_unit_spec.rb +0 -68
  113. data/testing/rspec/spec/unit/models/directory_unit_spec.rb +0 -127
  114. data/testing/rspec/spec/unit/models/doc_string_unit_spec.rb +0 -100
  115. data/testing/rspec/spec/unit/models/example_unit_spec.rb +0 -133
  116. data/testing/rspec/spec/unit/models/feature_file_unit_spec.rb +0 -125
  117. data/testing/rspec/spec/unit/models/feature_unit_spec.rb +0 -157
  118. data/testing/rspec/spec/unit/models/model_unit_spec.rb +0 -15
  119. data/testing/rspec/spec/unit/models/outline_unit_spec.rb +0 -117
  120. data/testing/rspec/spec/unit/models/row_unit_spec.rb +0 -68
  121. data/testing/rspec/spec/unit/models/scenario_unit_spec.rb +0 -86
  122. data/testing/rspec/spec/unit/models/step_unit_spec.rb +0 -109
  123. data/testing/rspec/spec/unit/models/table_unit_spec.rb +0 -77
  124. data/testing/rspec/spec/unit/models/tag_unit_spec.rb +0 -68
  125. data/testing/rspec/spec/unit/named_unit_spec.rb +0 -23
  126. data/testing/rspec/spec/unit/nested_unit_spec.rb +0 -43
  127. data/testing/rspec/spec/unit/parsed_unit_spec.rb +0 -27
  128. data/testing/rspec/spec/unit/parsing_unit_spec.rb +0 -54
  129. data/testing/rspec/spec/unit/shared/bare_bones_models_unit_specs.rb +0 -14
  130. data/testing/rspec/spec/unit/shared/containing_models_unit_specs.rb +0 -127
  131. data/testing/rspec/spec/unit/shared/described_models_unit_specs.rb +0 -38
  132. data/testing/rspec/spec/unit/shared/keyworded_models_unit_specs.rb +0 -58
  133. data/testing/rspec/spec/unit/shared/models_unit_specs.rb +0 -15
  134. data/testing/rspec/spec/unit/shared/named_models_unit_specs.rb +0 -39
  135. data/testing/rspec/spec/unit/shared/nested_models_unit_specs.rb +0 -51
  136. data/testing/rspec/spec/unit/shared/parsed_models_unit_specs.rb +0 -39
  137. data/testing/rspec/spec/unit/shared/prepopulated_models_unit_specs.rb +0 -18
  138. data/testing/rspec/spec/unit/shared/sourced_models_unit_specs.rb +0 -39
  139. data/testing/rspec/spec/unit/shared/stepped_models_unit_specs.rb +0 -46
  140. data/testing/rspec/spec/unit/shared/stringifiable_models_unit_specs.rb +0 -18
  141. data/testing/rspec/spec/unit/shared/tagged_models_unit_specs.rb +0 -72
  142. data/testing/rspec/spec/unit/sourceable_unit_spec.rb +0 -27
  143. data/testing/rspec/spec/unit/stepped_unit_spec.rb +0 -23
  144. data/testing/rspec/spec/unit/taggable_unit_spec.rb +0 -69
  145. data/testing/test_languages.json +0 -45
  146. data/todo.txt +0 -25
@@ -17,6 +17,9 @@ module CukeModeler
17
17
  # The Background object contained by the Feature
18
18
  attr_accessor :background
19
19
 
20
+ # The Rule objects contained by the Feature
21
+ attr_accessor :rules
22
+
20
23
  # The Scenario and Outline objects contained by the Feature
21
24
  attr_accessor :tests
22
25
 
@@ -25,21 +28,24 @@ module CukeModeler
25
28
  # object.
26
29
  def initialize(source_text = nil)
27
30
  @tags = []
31
+ @rules = []
28
32
  @tests = []
29
33
 
30
34
  super(source_text)
31
35
 
32
- if source_text
33
- parsed_feature_data = parse_source(source_text)
34
- populate_feature(self, parsed_feature_data)
35
- end
36
+ return unless source_text
37
+
38
+ parsed_feature_data = parse_source(source_text)
39
+ populate_feature(self, parsed_feature_data)
36
40
  end
37
41
 
38
42
  # Returns *true* if the feature contains a background, *false* otherwise.
39
- def has_background?
43
+ def background?
40
44
  !@background.nil?
41
45
  end
42
46
 
47
+ alias has_background? background?
48
+
43
49
  # Returns the scenario models contained in the feature.
44
50
  def scenarios
45
51
  @tests.select { |test| test.is_a? Scenario }
@@ -50,58 +56,70 @@ module CukeModeler
50
56
  @tests.select { |test| test.is_a? Outline }
51
57
  end
52
58
 
59
+ # TODO: Remove this method on next major version release
60
+ # DEPRECATED
53
61
  # Returns the number of test cases contained in the feature. A test case is a
54
62
  # single set of test values, such as an individual scenario or one example row
55
63
  # of an outline.
56
64
  def test_case_count
57
- scenarios.count + outlines.reduce(0) { |outline_sum, outline|
58
- outline_sum += outline.examples.reduce(0) { |example_sum, example|
59
- example_sum += example.argument_rows.count
60
- }
61
- }
65
+ scenarios.count + outlines.reduce(0) do |outline_sum, outline|
66
+ outline_sum + outline.examples.reduce(0) do |example_sum, example|
67
+ example_sum + example.argument_rows.count
68
+ end
69
+ end
62
70
  end
63
71
 
64
72
  # Returns the model objects that belong to this model.
65
73
  def children
66
- models = tests + tags
74
+ models = rules + tests + tags
67
75
  models << background if background
68
76
 
69
77
  models
70
78
  end
71
79
 
80
+ # Building strings just isn't pretty
81
+ # rubocop:disable Metrics/AbcSize
82
+
72
83
  # Returns a string representation of this model. For a feature model,
73
84
  # this will be Gherkin text that is equivalent to the feature being modeled.
74
85
  def to_s
75
86
  text = ''
76
87
 
77
- text << tag_output_string + "\n" unless tags.empty?
88
+ text << "#{tag_output_string}\n" unless tags.empty?
78
89
  text << "#{@keyword}:#{name_output_string}"
79
- text << "\n" + description_output_string unless (description.nil? || description.empty?)
80
- text << "\n\n" + background_output_string if background
81
- text << "\n\n" + tests_output_string unless tests.empty?
90
+ text << "\n#{description_output_string}" unless no_description_to_output?
91
+ text << "\n\n#{background_output_string}" if background
92
+ text << "\n\n#{tests_output_string}" unless tests.empty?
93
+ text << "\n\n#{rules_output_string}" unless rules.empty?
82
94
 
83
95
  text
84
96
  end
85
97
 
98
+ # rubocop:enable Metrics/AbcSize
99
+
86
100
 
87
101
  private
88
102
 
89
103
 
90
104
  def parse_source(source_text)
91
- parsed_file = Parsing::parse_text(source_text, 'cuke_modeler_stand_alone_feature.feature')
105
+ parsed_file = Parsing.parse_text(source_text, 'cuke_modeler_stand_alone_feature.feature')
92
106
 
93
- parsed_file.first['feature']
107
+ parsed_file['feature']
94
108
  end
95
109
 
96
110
  def background_output_string
97
- test_output_string(background)
111
+ child_element_output_string(background)
98
112
  end
99
113
 
100
114
  def tests_output_string
101
- tests.collect { |test| test_output_string(test) }.join("\n\n")
115
+ tests.collect { |test| child_element_output_string(test) }.join("\n\n")
116
+ end
117
+
118
+ def rules_output_string
119
+ rules.collect { |rule| child_element_output_string(rule) }.join("\n\n")
102
120
  end
103
121
 
104
- def test_output_string(model)
122
+ def child_element_output_string(model)
105
123
  model.to_s.split("\n").collect { |line| line.empty? ? '' : " #{line}" }.join("\n")
106
124
  end
107
125
 
@@ -25,13 +25,11 @@ module CukeModeler
25
25
 
26
26
  super(file_path)
27
27
 
28
- if file_path
29
- raise(ArgumentError, "Unknown file: #{file_path.inspect}") unless File.exists?(file_path)
30
-
31
- processed_feature_file_data = process_feature_file(file_path)
32
- populate_featurefile(self, processed_feature_file_data)
33
- end
28
+ return unless file_path
29
+ raise(ArgumentError, "Unknown file: #{file_path.inspect}") unless File.exist?(file_path)
34
30
 
31
+ processed_feature_file_data = process_feature_file(file_path)
32
+ populate_featurefile(self, processed_feature_file_data)
35
33
  end
36
34
 
37
35
  # Returns the name of the modeled feature file.
@@ -57,8 +55,8 @@ module CukeModeler
57
55
  def process_feature_file(file_path)
58
56
  source_text = IO.read(file_path)
59
57
 
60
- feature_file_data = Parsing::parse_text(source_text, file_path).first
61
- feature_file_data = feature_file_data.merge({'path' => file_path})
58
+ feature_file_data = Parsing.parse_text(source_text, file_path)
59
+ feature_file_data = feature_file_data.merge({ 'path' => file_path })
62
60
 
63
61
  feature_file_data
64
62
  end
@@ -11,7 +11,8 @@ module CukeModeler
11
11
  # Creates a new Model object and, if *source_text* is provided,
12
12
  # populates the object.
13
13
  def initialize(source_text = nil)
14
- raise(ArgumentError, "Can only create models from Strings but was given a #{source_text.class}.") if source_text && !source_text.is_a?(String)
14
+ error_message = "Can only create models from Strings but was given a #{source_text.class}."
15
+ raise(ArgumentError, error_message) if source_text && !source_text.is_a?(String)
15
16
 
16
17
  # This should be overridden by a child class
17
18
  end
@@ -29,17 +29,17 @@ module CukeModeler
29
29
 
30
30
  super(source_text)
31
31
 
32
- if source_text
33
- parsed_outline_data = parse_source(source_text)
34
- populate_outline(self, parsed_outline_data)
35
- end
32
+ return unless source_text
33
+
34
+ parsed_outline_data = parse_source(source_text)
35
+ populate_outline(self, parsed_outline_data)
36
36
  end
37
37
 
38
38
  # Returns *true* if the two models have equivalent steps and *false* otherwise.
39
- def ==(other_model)
40
- return false unless other_model.respond_to?(:steps)
39
+ def ==(other)
40
+ return false unless other.respond_to?(:steps)
41
41
 
42
- steps == other_model.steps
42
+ steps == other.steps
43
43
  end
44
44
 
45
45
  # Returns the model objects that belong to this model.
@@ -47,21 +47,26 @@ module CukeModeler
47
47
  examples + steps + tags
48
48
  end
49
49
 
50
+ # Building strings just isn't pretty
51
+ # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity
52
+
50
53
  # Returns a string representation of this model. For an outline model,
51
54
  # this will be Gherkin text that is equivalent to the outline being modeled.
52
55
  def to_s
53
56
  text = ''
54
57
 
55
- text << tag_output_string + "\n" unless tags.empty?
58
+ text << "#{tag_output_string}\n" unless tags.empty?
56
59
  text << "#{@keyword}:#{name_output_string}"
57
- text << "\n" + description_output_string unless (description.nil? || description.empty?)
58
- text << "\n" unless (steps.empty? || description.nil? || description.empty?)
59
- text << "\n" + steps_output_string unless steps.empty?
60
- text << "\n\n" + examples_output_string unless examples.empty?
60
+ text << "\n#{description_output_string}" unless no_description_to_output?
61
+ text << "\n" unless steps.empty? || no_description_to_output?
62
+ text << "\n#{steps_output_string}" unless steps.empty?
63
+ text << "\n\n#{examples_output_string}" unless examples.empty?
61
64
 
62
65
  text
63
66
  end
64
67
 
68
+ # rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity
69
+
65
70
 
66
71
  private
67
72
 
@@ -70,13 +75,13 @@ module CukeModeler
70
75
  base_file_string = "# language: #{Parsing.dialect}\n#{dialect_feature_keyword}: Fake feature to parse\n"
71
76
  source_text = base_file_string + source_text
72
77
 
73
- parsed_file = Parsing::parse_text(source_text, 'cuke_modeler_stand_alone_outline.feature')
78
+ parsed_file = Parsing.parse_text(source_text, 'cuke_modeler_stand_alone_outline.feature')
74
79
 
75
- parsed_file.first['feature']['elements'].first
80
+ parsed_file['feature']['elements'].first
76
81
  end
77
82
 
78
83
  def examples_output_string
79
- examples.empty? ? '' : examples.collect { |example| example.to_s }.join("\n\n")
84
+ examples.empty? ? '' : examples.join("\n\n")
80
85
  end
81
86
 
82
87
  end
@@ -19,16 +19,16 @@ module CukeModeler
19
19
 
20
20
  super(source_text)
21
21
 
22
- if source_text
23
- parsed_row_data = parse_source(source_text)
24
- populate_row(self, parsed_row_data)
25
- end
22
+ return unless source_text
23
+
24
+ parsed_row_data = parse_source(source_text)
25
+ populate_row(self, parsed_row_data)
26
26
  end
27
27
 
28
28
  # Returns a string representation of this model. For a row model,
29
29
  # this will be Gherkin text that is equivalent to the row being modeled.
30
30
  def to_s
31
- text_cells = cells.collect { |cell| cell.to_s }
31
+ text_cells = cells.map(&:to_s)
32
32
 
33
33
  "| #{text_cells.join(' | ')} |"
34
34
  end
@@ -38,12 +38,15 @@ module CukeModeler
38
38
 
39
39
 
40
40
  def parse_source(source_text)
41
- base_file_string = "# language: #{Parsing.dialect}\n#{dialect_feature_keyword}: Fake feature to parse\n#{dialect_scenario_keyword}:\n#{dialect_step_keyword} fake step\n"
41
+ base_file_string = "# language: #{Parsing.dialect}
42
+ #{dialect_feature_keyword}: Fake feature to parse
43
+ #{dialect_scenario_keyword}:
44
+ #{dialect_step_keyword} fake step\n"
42
45
  source_text = base_file_string + source_text
43
46
 
44
- parsed_file = Parsing::parse_text(source_text, 'cuke_modeler_stand_alone_row.feature')
47
+ parsed_file = Parsing.parse_text(source_text, 'cuke_modeler_stand_alone_row.feature')
45
48
 
46
- parsed_file.first['feature']['elements'].first['steps'].first['table']['rows'].first
49
+ parsed_file['feature']['elements'].first['steps'].first['table']['rows'].first
47
50
  end
48
51
 
49
52
  end
@@ -0,0 +1,101 @@
1
+ module CukeModeler
2
+
3
+ # A class modeling a rule in a Cucumber suite.
4
+
5
+ class Rule < Model
6
+
7
+ include Parsing
8
+ include Parsed
9
+ include Named
10
+ include Described
11
+ include Sourceable
12
+
13
+
14
+ # The keyword for the rule
15
+ attr_accessor :keyword
16
+
17
+ # The Background object contained by the Rule
18
+ attr_accessor :background
19
+
20
+ # The Scenario and Outline objects contained by the Rule
21
+ attr_accessor :tests
22
+
23
+
24
+ # Creates a new Rule object and, if *source_text* is provided, populates the
25
+ # object.
26
+ def initialize(source_text = nil)
27
+ @tests = []
28
+
29
+ super(source_text)
30
+
31
+ return unless source_text
32
+
33
+ parsed_rule_data = parse_source(source_text)
34
+ populate_rule(self, parsed_rule_data)
35
+ end
36
+
37
+ # Returns *true* if the rule contains a background, *false* otherwise.
38
+ def background?
39
+ !@background.nil?
40
+ end
41
+
42
+ alias has_background? background?
43
+
44
+ # Returns the scenario models contained in the rule.
45
+ def scenarios
46
+ @tests.select { |test| test.is_a? Scenario }
47
+ end
48
+
49
+ # Returns the outline models contained in the rule.
50
+ def outlines
51
+ @tests.select { |test| test.is_a? Outline }
52
+ end
53
+
54
+ # Returns the model objects that belong to this model.
55
+ def children
56
+ models = tests
57
+ models << background if background
58
+
59
+ models
60
+ end
61
+
62
+ # Returns a string representation of this model. For a rule model,
63
+ # this will be Gherkin text that is equivalent to the rule being modeled.
64
+ def to_s
65
+ text = ''
66
+
67
+ text << "#{@keyword}:#{name_output_string}"
68
+ text << "\n#{description_output_string}" unless no_description_to_output?
69
+ text << "\n\n#{background_output_string}" if background
70
+ text << "\n\n#{tests_output_string}" unless tests.empty?
71
+
72
+ text
73
+ end
74
+
75
+
76
+ private
77
+
78
+
79
+ def parse_source(source_text)
80
+ base_file_string = "# language: #{Parsing.dialect}\n#{dialect_feature_keyword}: Fake feature to parse\n"
81
+ source_text = base_file_string + source_text
82
+
83
+ parsed_file = Parsing.parse_text(source_text, 'cuke_modeler_stand_alone_rule.feature')
84
+
85
+ parsed_file['feature']['elements'].first
86
+ end
87
+
88
+ def background_output_string
89
+ test_output_string(background)
90
+ end
91
+
92
+ def tests_output_string
93
+ tests.collect { |test| test_output_string(test) }.join("\n\n")
94
+ end
95
+
96
+ def test_output_string(model)
97
+ model.to_s.split("\n").collect { |line| line.empty? ? '' : " #{line}" }.join("\n")
98
+ end
99
+
100
+ end
101
+ end
@@ -25,17 +25,17 @@ module CukeModeler
25
25
 
26
26
  super(source_text)
27
27
 
28
- if source_text
29
- parsed_scenario_data = parse_source(source_text)
30
- populate_scenario(self, parsed_scenario_data)
31
- end
28
+ return unless source_text
29
+
30
+ parsed_scenario_data = parse_source(source_text)
31
+ populate_scenario(self, parsed_scenario_data)
32
32
  end
33
33
 
34
34
  # 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)
35
+ def ==(other)
36
+ return false unless other.respond_to?(:steps)
37
37
 
38
- steps == other_model.steps
38
+ steps == other.steps
39
39
  end
40
40
 
41
41
  # Returns the model objects that belong to this model.
@@ -43,20 +43,25 @@ module CukeModeler
43
43
  steps + tags
44
44
  end
45
45
 
46
+ # Building strings just isn't pretty
47
+ # rubocop:disable Metrics/AbcSize
48
+
46
49
  # Returns a string representation of this model. For a scenario model,
47
50
  # this will be Gherkin text that is equivalent to the scenario being modeled.
48
51
  def to_s
49
52
  text = ''
50
53
 
51
- text << tag_output_string + "\n" unless tags.empty?
54
+ text << "#{tag_output_string}\n" unless tags.empty?
52
55
  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?
56
+ text << "\n#{description_output_string}" unless no_description_to_output?
57
+ text << "\n" unless steps.empty? || no_description_to_output?
58
+ text << "\n#{steps_output_string}" unless steps.empty?
56
59
 
57
60
  text
58
61
  end
59
62
 
63
+ # rubocop:enable Metrics/AbcSize
64
+
60
65
 
61
66
  private
62
67
 
@@ -65,9 +70,9 @@ module CukeModeler
65
70
  base_file_string = "# language: #{Parsing.dialect}\n#{dialect_feature_keyword}: Fake feature to parse\n"
66
71
  source_text = base_file_string + source_text
67
72
 
68
- parsed_file = Parsing::parse_text(source_text, 'cuke_modeler_stand_alone_scenario.feature')
73
+ parsed_file = Parsing.parse_text(source_text, 'cuke_modeler_stand_alone_scenario.feature')
69
74
 
70
- parsed_file.first['feature']['elements'].first
75
+ parsed_file['feature']['elements'].first
71
76
  end
72
77
 
73
78
  end
@@ -24,20 +24,20 @@ module CukeModeler
24
24
  def initialize(source_text = nil)
25
25
  super(source_text)
26
26
 
27
- if source_text
28
- parsed_step_data = parse_source(source_text)
29
- populate_step(self, parsed_step_data)
30
- end
27
+ return unless source_text
28
+
29
+ parsed_step_data = parse_source(source_text)
30
+ populate_step(self, parsed_step_data)
31
31
  end
32
32
 
33
33
  # Returns *true* if the two steps have the same base text (i.e. minus any keyword,
34
34
  # table, or doc string and *false* otherwise.
35
- def ==(other_step)
36
- return false unless other_step.is_a?(CukeModeler::Step)
35
+ def ==(other)
36
+ return false unless other.is_a?(CukeModeler::Step)
37
37
 
38
- text_matches?(other_step) &&
39
- table_matches?(other_step) &&
40
- doc_string_matches?(other_step)
38
+ text_matches?(other) &&
39
+ table_matches?(other) &&
40
+ doc_string_matches?(other)
41
41
  end
42
42
 
43
43
  # Returns the model objects that belong to this model.
@@ -49,7 +49,7 @@ module CukeModeler
49
49
  # this will be Gherkin text that is equivalent to the step being modeled.
50
50
  def to_s
51
51
  text = "#{keyword} #{self.text}"
52
- text << "\n" + block.to_s.split("\n").collect { |line| " #{line}" }.join("\n") if block
52
+ text << "\n#{block.to_s.split("\n").collect { |line| " #{line}" }.join("\n")}" if block
53
53
 
54
54
  text
55
55
  end
@@ -59,12 +59,14 @@ module CukeModeler
59
59
 
60
60
 
61
61
  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"
62
+ base_file_string = "# language: #{Parsing.dialect}
63
+ #{dialect_feature_keyword}: Fake feature to parse
64
+ #{dialect_scenario_keyword}:\n"
63
65
  source_text = base_file_string + source_text
64
66
 
65
- parsed_file = Parsing::parse_text(source_text, 'cuke_modeler_stand_alone_step.feature')
67
+ parsed_file = Parsing.parse_text(source_text, 'cuke_modeler_stand_alone_step.feature')
66
68
 
67
- parsed_file.first['feature']['elements'].first['steps'].first
69
+ parsed_file['feature']['elements'].first['steps'].first
68
70
  end
69
71
 
70
72
  def text_matches?(other_step)
@@ -72,18 +74,18 @@ module CukeModeler
72
74
  end
73
75
 
74
76
  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)
77
+ return false if only_one_step_has_table?(other_step)
78
+ return true if neither_step_has_table?(other_step)
77
79
 
78
- first_step_values = block.rows.collect { |table_row| table_row.cells.map(&:value) }
80
+ first_step_values = block.rows.collect { |table_row| table_row.cells.map(&:value) }
79
81
  second_step_values = other_step.block.rows.collect { |table_row| table_row.cells.map(&:value) }
80
82
 
81
83
  first_step_values == second_step_values
82
84
  end
83
85
 
84
86
  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)
87
+ return false if only_one_step_has_doc_string?(other_step)
88
+ return true if neither_step_has_doc_string?(other_step)
87
89
 
88
90
  first_content = block.content
89
91
  first_content_type = block.content_type
@@ -91,7 +93,27 @@ module CukeModeler
91
93
  second_content_type = other_step.block.content_type
92
94
 
93
95
  (first_content == second_content) &&
94
- (first_content_type == second_content_type)
96
+ (first_content_type == second_content_type)
97
+ end
98
+
99
+ def only_one_step_has_table?(other_step)
100
+ (!block.is_a?(CukeModeler::Table) || !other_step.block.is_a?(CukeModeler::Table)) &&
101
+ (block.is_a?(CukeModeler::Table) || other_step.block.is_a?(CukeModeler::Table))
102
+ end
103
+
104
+ def neither_step_has_table?(other_step)
105
+ !block.is_a?(CukeModeler::Table) &&
106
+ !other_step.block.is_a?(CukeModeler::Table)
107
+ end
108
+
109
+ def only_one_step_has_doc_string?(other_step)
110
+ (!block.is_a?(CukeModeler::DocString) || !other_step.block.is_a?(CukeModeler::DocString)) &&
111
+ (block.is_a?(CukeModeler::DocString) || other_step.block.is_a?(CukeModeler::DocString))
112
+ end
113
+
114
+ def neither_step_has_doc_string?(other_step)
115
+ !block.is_a?(CukeModeler::DocString) &&
116
+ !other_step.block.is_a?(CukeModeler::DocString)
95
117
  end
96
118
 
97
119
  end