cucumber_analytics 1.4.2 → 1.5.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 (84) hide show
  1. data/History.rdoc +7 -0
  2. data/README.rdoc +4 -0
  3. data/Rakefile +1 -1
  4. data/cucumber_analytics.gemspec +3 -1
  5. data/features/modeling/background_modeling.feature +27 -13
  6. data/features/modeling/background_output.feature +130 -0
  7. data/features/modeling/directory_modeling.feature +11 -6
  8. data/features/modeling/directory_output.feature +13 -0
  9. data/features/modeling/doc_string_modeling.feature +18 -11
  10. data/features/modeling/doc_string_output.feature +71 -0
  11. data/features/modeling/example_modeling.feature +30 -19
  12. data/features/modeling/example_output.feature +192 -0
  13. data/features/modeling/feature_file_modeling.feature +9 -4
  14. data/features/modeling/feature_file_output.feature +13 -0
  15. data/features/modeling/feature_modeling.feature +33 -20
  16. data/features/modeling/feature_output.feature +244 -0
  17. data/features/modeling/outline_modeling.feature +29 -16
  18. data/features/modeling/outline_output.feature +197 -0
  19. data/features/modeling/row_modeling.feature +9 -4
  20. data/features/modeling/row_output.feature +27 -0
  21. data/features/modeling/scenario_modeling.feature +27 -14
  22. data/features/modeling/scenario_output.feature +147 -0
  23. data/features/modeling/step_modeling.feature +13 -8
  24. data/features/modeling/step_output.feature +52 -0
  25. data/features/modeling/table_modeling.feature +9 -4
  26. data/features/modeling/table_output.feature +42 -0
  27. data/features/modeling/table_row_modeling.feature +9 -4
  28. data/features/modeling/table_row_output.feature +27 -0
  29. data/features/modeling/tag_modeling.feature +10 -5
  30. data/features/modeling/tag_output.feature +16 -0
  31. data/features/step_definitions/action_steps.rb +3 -0
  32. data/features/step_definitions/background_steps.rb +17 -4
  33. data/features/step_definitions/directory_steps.rb +11 -0
  34. data/features/step_definitions/doc_string_steps.rb +18 -15
  35. data/features/step_definitions/feature_file_steps.rb +12 -1
  36. data/features/step_definitions/feature_steps.rb +23 -6
  37. data/features/step_definitions/outline_steps.rb +70 -9
  38. data/features/step_definitions/step_steps.rb +9 -1
  39. data/features/step_definitions/table_steps.rb +35 -2
  40. data/features/step_definitions/tag_steps.rb +8 -0
  41. data/features/step_definitions/test_steps.rb +14 -3
  42. data/features/step_definitions/verification_steps.rb +9 -0
  43. data/features/support/env.rb +1 -0
  44. data/lib/cucumber_analytics/background.rb +12 -0
  45. data/lib/cucumber_analytics/directory.rb +5 -0
  46. data/lib/cucumber_analytics/doc_string.rb +22 -0
  47. data/lib/cucumber_analytics/example.rb +55 -0
  48. data/lib/cucumber_analytics/feature.rb +26 -0
  49. data/lib/cucumber_analytics/feature_element.rb +25 -1
  50. data/lib/cucumber_analytics/feature_file.rb +5 -0
  51. data/lib/cucumber_analytics/outline.rb +18 -0
  52. data/lib/cucumber_analytics/parsing.rb +3 -1
  53. data/lib/cucumber_analytics/row.rb +5 -0
  54. data/lib/cucumber_analytics/scenario.rb +13 -0
  55. data/lib/cucumber_analytics/step.rb +8 -0
  56. data/lib/cucumber_analytics/table.rb +21 -0
  57. data/lib/cucumber_analytics/table_row.rb +5 -0
  58. data/lib/cucumber_analytics/tag.rb +5 -0
  59. data/lib/cucumber_analytics/taggable.rb +4 -0
  60. data/lib/cucumber_analytics/test_element.rb +8 -0
  61. data/lib/cucumber_analytics/version.rb +1 -1
  62. data/spec/integration/background_integration_spec.rb +12 -0
  63. data/spec/integration/example_integration_spec.rb +21 -0
  64. data/spec/integration/feature_integration_spec.rb +29 -0
  65. data/spec/integration/outline_integration_spec.rb +22 -0
  66. data/spec/integration/scenario_integration_spec.rb +16 -0
  67. data/spec/integration/step_integration_spec.rb +20 -0
  68. data/spec/integration/table_integration_spec.rb +11 -0
  69. data/spec/unit/background_unit_spec.rb +28 -0
  70. data/spec/unit/directory_unit_spec.rb +12 -0
  71. data/spec/unit/doc_string_unit_spec.rb +43 -3
  72. data/spec/unit/example_unit_spec.rb +53 -0
  73. data/spec/unit/feature_element_unit_specs.rb +9 -2
  74. data/spec/unit/feature_file_unit_spec.rb +12 -0
  75. data/spec/unit/feature_unit_spec.rb +30 -0
  76. data/spec/unit/outline_unit_spec.rb +30 -0
  77. data/spec/unit/row_unit_spec.rb +19 -7
  78. data/spec/unit/scenario_unit_spec.rb +30 -0
  79. data/spec/unit/step_unit_spec.rb +25 -1
  80. data/spec/unit/table_row_unit_spec.rb +12 -0
  81. data/spec/unit/table_unit_spec.rb +25 -0
  82. data/spec/unit/tag_unit_spec.rb +12 -0
  83. metadata +165 -86
  84. checksums.yaml +0 -15
@@ -148,4 +148,12 @@ Then /^(?:the )?(?:feature "([^"]*)" )?(?:test(?: "([^"]*)")? )?step(?: "([^"]*)
148
148
  actual = @parsed_files[file - 1].feature.tests[test - 1].steps[step - 1].block.row_elements[row - 1].cells
149
149
 
150
150
  assert(actual == expected, "Expected: #{expected}\n but was: #{actual}")
151
- end
151
+ end
152
+
153
+ Given(/^a step element based on the following gherkin:$/) do |step_text|
154
+ @element = CucumberAnalytics::Step.new(step_text)
155
+ end
156
+
157
+ Then(/^the step has convenient output$/) do
158
+ @parsed_files.first.feature.tests.first.steps.first.method(:to_s).owner.should == CucumberAnalytics::Step
159
+ end
@@ -4,9 +4,10 @@ Then /^(?:the )?(?:feature "([^"]*)" )?(?:test(?: "([^"]*)")? )?(?:step(?: "([^"
4
4
  step ||= 1
5
5
 
6
6
  expected = contents.raw
7
- actual = @parsed_files[file - 1].feature.tests[test - 1].steps[step - 1].block.row_elements.collect{|row| row.cells}
8
7
 
9
- assert(actual == expected, "Expected: #{expected}\n but was: #{actual}")
8
+ @parsed_files[file - 1].feature.tests[test - 1].steps[step - 1].block.row_elements.collect { |row| row.cells }.should == expected
9
+ # todo - remove once #contents is no longer supported
10
+ @parsed_files[file - 1].feature.tests[test - 1].steps[step - 1].block.contents.should == expected
10
11
  end
11
12
 
12
13
  Then /^(?:the )?(?:feature "([^"]*)" )?(?:test(?: "([^"]*)")? )?(?:step(?: "([^"]*)") )?table correctly stores its underlying implementation$/ do |file, test, step|
@@ -19,3 +20,35 @@ Then /^(?:the )?(?:feature "([^"]*)" )?(?:test(?: "([^"]*)")? )?(?:step(?: "([^"
19
20
  raw_element.is_a?(Array).should be_true
20
21
  raw_element.each { |row| row.has_key?('cells').should be_true }
21
22
  end
23
+
24
+ Given(/^a table row element$/) do
25
+ @element = CucumberAnalytics::TableRow.new
26
+ end
27
+
28
+ When(/^the table row element has no cells$/) do
29
+ @element.cells = []
30
+ end
31
+
32
+ Given(/^a table row element based on the following gherkin:$/) do |row_text|
33
+ @element = CucumberAnalytics::TableRow.new(row_text)
34
+ end
35
+
36
+ Then(/^the table row has convenient output$/) do
37
+ @parsed_files.first.feature.tests.first.steps.first.block.row_elements.first.method(:to_s).owner.should == CucumberAnalytics::TableRow
38
+ end
39
+
40
+ Given(/^a table element$/) do
41
+ @element = CucumberAnalytics::Table.new
42
+ end
43
+
44
+ When(/^the table element has no rows$/) do
45
+ @element.row_elements = []
46
+ end
47
+
48
+ Then(/^the table has convenient output$/) do
49
+ @parsed_files.first.feature.tests.first.steps.first.block.method(:to_s).owner.should == CucumberAnalytics::Table
50
+ end
51
+
52
+ Given(/^a table element based on the following gherkin:$/) do |table_text|
53
+ @element = CucumberAnalytics::Table.new(table_text)
54
+ end
@@ -51,3 +51,11 @@ When(/^the example tag source line "([^"]*)"$/) do |line|
51
51
 
52
52
  tag.source_line.should == line
53
53
  end
54
+
55
+ Then(/^the tag has convenient output$/) do
56
+ @parsed_files.first.feature.tag_elements.first.method(:to_s).owner.should == CucumberAnalytics::Tag
57
+ end
58
+
59
+ Given(/^a tag element based on the following gherkin:$/) do |tag_text|
60
+ @element = CucumberAnalytics::Tag.new(tag_text)
61
+ end
@@ -9,12 +9,15 @@ Then /^(?:the )?(?:feature "([^"]*)" )?test(?: "([^"]*)")? is found to have the
9
9
  end
10
10
  end
11
11
 
12
- Then /^(?:the )?(?:feature "([^"]*)" )?test(?: "([^"]*)")? descriptive lines are as follows:$/ do |file, test, lines|
12
+ Then /^(?:the )?(?:feature "([^"]*)" )?test(?: "([^"]*)")? has the following description:$/ do |file, test, text|
13
13
  file ||= 1
14
14
  test ||= 1
15
- lines = lines.raw.flatten
16
15
 
17
- assert @parsed_files[file - 1].feature.tests[test - 1].description == lines
16
+ new_description = @parsed_files[file - 1].feature.tests[test - 1].description_text
17
+ old_description = @parsed_files[file - 1].feature.tests[test - 1].description
18
+
19
+ new_description.should == text
20
+ old_description.should == remove_whitespace(text)
18
21
  end
19
22
 
20
23
  Then /^(?:the )?(?:feature "([^"]*)" )?test(?: "([^"]*)")? steps are as follows:$/ do |file, test, steps|
@@ -101,3 +104,11 @@ Then /^(?:the )?(?:feature "([^"]*)" )?test(?: "([^"]*)")? correctly stores its
101
104
 
102
105
  expected.include?(actual).should be_true
103
106
  end
107
+
108
+ Then(/^the scenario has convenient output$/) do
109
+ @parsed_files.first.feature.tests.first.method(:to_s).owner.should == CucumberAnalytics::Scenario
110
+ end
111
+
112
+ Given(/^a scenario element based on the following gherkin:$/) do |scenario_text|
113
+ @element = CucumberAnalytics::Scenario.new(scenario_text)
114
+ end
@@ -0,0 +1,9 @@
1
+ Then(/^the following text is provided:$/) do |expected_text|
2
+ expected_text.sub!('path_to', @default_file_directory)
3
+
4
+ @output.should == expected_text
5
+ end
6
+
7
+ Then(/^the text provided is "(.*)"$/) do |text_string|
8
+ @output.should == text_string.gsub('\n', "\n")
9
+ end
@@ -3,6 +3,7 @@ unless RUBY_VERSION.to_s < '1.9.0'
3
3
  SimpleCov.command_name('cucumber_tests')
4
4
  end
5
5
 
6
+ require 'test/unit/assertions'
6
7
  include Test::Unit::Assertions
7
8
 
8
9
  require File.dirname(__FILE__) + '/../../lib/cucumber_analytics'
@@ -14,6 +14,18 @@ module CucumberAnalytics
14
14
  build_background(parsed_background) if parsed_background
15
15
  end
16
16
 
17
+ # Returns gherkin representation of the background.
18
+ def to_s
19
+ text = ''
20
+
21
+ text << "Background:#{name_output_string}"
22
+ text << "\n" + description_output_string unless description_text.empty?
23
+ text << "\n" unless steps.empty? || description_text.empty?
24
+ text << "\n" + steps_output_string unless steps.empty?
25
+
26
+ text
27
+ end
28
+
17
29
 
18
30
  private
19
31
 
@@ -55,6 +55,11 @@ module CucumberAnalytics
55
55
  @feature_files + @directories
56
56
  end
57
57
 
58
+ # Returns the path of the directory.
59
+ def to_s
60
+ path.to_s
61
+ end
62
+
58
63
 
59
64
  private
60
65
 
@@ -11,20 +11,33 @@ module CucumberAnalytics
11
11
  # The content type associated with the doc string
12
12
  attr_accessor :content_type
13
13
 
14
+ # Deprecated
15
+ #
14
16
  # The contents of the doc string
15
17
  attr_accessor :contents
16
18
 
19
+ # The contents of the doc string
20
+ attr_accessor :contents_text
21
+
17
22
 
18
23
  # Creates a new DocString object and, if *source* is provided, populates
19
24
  # the object.
20
25
  def initialize(source = nil)
21
26
  @contents = []
27
+ @contents_text = ''
22
28
 
23
29
  parsed_doc_string = process_source(source)
24
30
 
25
31
  build_doc_string(parsed_doc_string) if parsed_doc_string
26
32
  end
27
33
 
34
+ # Returns a gherkin representation of the doc string.
35
+ def to_s
36
+ text = "\"\"\"#{content_type_output_string}\n"
37
+ text << contents_output_string
38
+ text << '"""'
39
+ end
40
+
28
41
 
29
42
  private
30
43
 
@@ -59,6 +72,15 @@ module CucumberAnalytics
59
72
 
60
73
  def populate_contents(doc_string)
61
74
  @contents = doc_string['value'].split($/, -1)
75
+ @contents_text = doc_string['value']
76
+ end
77
+
78
+ def content_type_output_string
79
+ content_type ? " #{content_type}" : ''
80
+ end
81
+
82
+ def contents_output_string
83
+ contents_text.empty? ? '' : contents_text.gsub('"""', '\"\"\"') + "\n"
62
84
  end
63
85
 
64
86
  end
@@ -9,6 +9,9 @@ module CucumberAnalytics
9
9
 
10
10
 
11
11
  # The argument rows in the example table
12
+ #
13
+ # todo - Make this a read only method that derives the rows from
14
+ # the row elements
12
15
  attr_accessor :rows
13
16
 
14
17
  # The parameters for the example table
@@ -66,6 +69,7 @@ module CucumberAnalytics
66
69
  raise(ArgumentError, "Can only remove row from a Hash or an Array but received #{row.class}")
67
70
  end
68
71
 
72
+ #todo - remove once Hash rows are no longer supported
69
73
  @rows.delete_at(location) if location
70
74
  @row_elements.delete_at(location + 1) if location
71
75
  end
@@ -75,6 +79,20 @@ module CucumberAnalytics
75
79
  @row_elements
76
80
  end
77
81
 
82
+ # Returns a gherkin representation of the example.
83
+ def to_s
84
+ text = ''
85
+
86
+ text << tag_output_string + "\n" unless tags.empty?
87
+ text << "Examples:#{name_output_string}"
88
+ text << "\n" + description_output_string unless description_text.empty?
89
+ text << "\n" unless description_text.empty?
90
+ text << "\n" + parameters_output_string
91
+ text << "\n" + rows_output_string unless rows.empty?
92
+
93
+ text
94
+ end
95
+
78
96
 
79
97
  private
80
98
 
@@ -122,8 +140,45 @@ module CucumberAnalytics
122
140
  end
123
141
  end
124
142
 
143
+ def determine_buffer_size(index)
144
+ row_elements.collect { |row| row.cells[index].length }.max || 0
145
+ end
146
+
147
+ def parameters_output_string
148
+ text = ''
149
+
150
+ unless parameters.empty?
151
+ text << " |"
152
+ parameters.count.times { |index| text << " #{string_for(parameters, index)} |" }
153
+ end
154
+
155
+ text
156
+ end
157
+
158
+ def rows_output_string
159
+ text = ''
160
+
161
+ unless rows.empty?
162
+
163
+ rows.each do |row|
164
+ text << " |"
165
+ row.values.count.times { |index| text << " #{string_for(ordered_row_values(row), index)} |" }
166
+ text << "\n"
167
+ end
168
+
169
+ text.chomp!
170
+ end
171
+
172
+ text
173
+ end
174
+
175
+ def string_for(cells, index)
176
+ cells[index] ? cells[index].ljust(determine_buffer_size(index)) : ''
177
+ end
178
+
125
179
  def ordered_row_values(row_hash)
126
180
  @parameters.collect { |parameter| row_hash[parameter] }
127
181
  end
182
+
128
183
  end
129
184
  end
@@ -75,6 +75,20 @@ module CucumberAnalytics
75
75
  end
76
76
 
77
77
 
78
+ # Returns gherkin representation of the feature.
79
+ def to_s
80
+ text = ''
81
+
82
+ text << tag_output_string + "\n" unless tags.empty?
83
+ text << "Feature:#{name_output_string}"
84
+ text << "\n" + description_output_string unless description_text.empty?
85
+ text << "\n\n" + background_output_string if background
86
+ text << "\n\n" + tests_output_string unless tests.empty?
87
+
88
+ text
89
+ end
90
+
91
+
78
92
  private
79
93
 
80
94
 
@@ -117,5 +131,17 @@ module CucumberAnalytics
117
131
  end
118
132
  end
119
133
 
134
+ def background_output_string
135
+ test_element_output_string(background)
136
+ end
137
+
138
+ def tests_output_string
139
+ tests.collect { |test| test_element_output_string(test) }.join("\n\n")
140
+ end
141
+
142
+ def test_element_output_string(test_element)
143
+ test_element.to_s.split("\n").collect { |line| line.empty? ? '' : " #{line}" }.join("\n")
144
+ end
145
+
120
146
  end
121
147
  end
@@ -12,15 +12,21 @@ module CucumberAnalytics
12
12
  # The name of the FeatureElement
13
13
  attr_accessor :name
14
14
 
15
+ # Deprecated
16
+ #
15
17
  # The description of the FeatureElement
16
18
  attr_accessor :description
17
19
 
20
+ # The description of the FeatureElement
21
+ attr_accessor :description_text
22
+
18
23
 
19
24
  # Creates a new FeatureElement object and, if *parsed_element* is provided,
20
25
  # populates the object.
21
26
  def initialize(parsed_element = nil)
22
27
  @name = ''
23
- @description =[]
28
+ @description = []
29
+ @description_text = ''
24
30
 
25
31
  build_feature_element(parsed_element) if parsed_element
26
32
  end
@@ -41,9 +47,27 @@ module CucumberAnalytics
41
47
  end
42
48
 
43
49
  def populate_feature_element_description(parsed_element)
50
+ @description_text = parsed_element['description']
44
51
  @description = parsed_element['description'].split("\n").collect { |line| line.strip }
45
52
  @description.delete('')
46
53
  end
47
54
 
55
+ def name_output_string
56
+ name.empty? ? '' : " #{name}"
57
+ end
58
+
59
+ def description_output_string
60
+ text = ''
61
+
62
+ unless description_text.empty?
63
+ description_lines = description_text.split("\n")
64
+
65
+ text << " \n" if description_lines.first =~ /\S/
66
+ text << description_lines.collect { |line| " #{line}" }.join("\n")
67
+ end
68
+
69
+ text
70
+ end
71
+
48
72
  end
49
73
  end
@@ -52,6 +52,11 @@ module CucumberAnalytics
52
52
  @features.first
53
53
  end
54
54
 
55
+ # Returns the path of the feature file.
56
+ def to_s
57
+ path.to_s
58
+ end
59
+
55
60
 
56
61
  private
57
62
 
@@ -31,6 +31,20 @@ module CucumberAnalytics
31
31
  @examples + @steps
32
32
  end
33
33
 
34
+ # Returns a gherkin representation of the outline.
35
+ def to_s
36
+ text = ''
37
+
38
+ text << tag_output_string + "\n" unless tags.empty?
39
+ text << "Scenario Outline:#{name_output_string}"
40
+ text << "\n" + description_output_string unless description_text.empty?
41
+ text << "\n" unless steps.empty? || description_text.empty?
42
+ text << "\n" + steps_output_string unless steps.empty?
43
+ text << "\n\n" + examples_output_string unless examples.empty?
44
+
45
+ text
46
+ end
47
+
34
48
 
35
49
  private
36
50
 
@@ -46,5 +60,9 @@ module CucumberAnalytics
46
60
  end
47
61
  end
48
62
 
63
+ def examples_output_string
64
+ examples.empty? ? '' : examples.collect { |example| example.to_s }.join("\n\n")
65
+ end
66
+
49
67
  end
50
68
  end
@@ -1,6 +1,8 @@
1
1
  require 'stringio'
2
2
  require 'gherkin/formatter/json_formatter'
3
3
  require 'gherkin'
4
+ require 'json'
5
+ require 'multi_json'
4
6
 
5
7
  module CucumberAnalytics
6
8
 
@@ -21,7 +23,7 @@ module CucumberAnalytics
21
23
  parser.parse(source_text, 'fake_file.txt', 0)
22
24
  formatter.done
23
25
 
24
- JSON.parse(io.string)
26
+ MultiJson.load(io.string)
25
27
  end
26
28
 
27
29
  end
@@ -23,6 +23,11 @@ module CucumberAnalytics
23
23
  build_row(parsed_row) if parsed_row
24
24
  end
25
25
 
26
+ # Returns a gherkin representation of the row.
27
+ def to_s
28
+ "| #{cells.join(' | ')} |"
29
+ end
30
+
26
31
 
27
32
  private
28
33