cucumber_analytics 1.4.2 → 1.5.0

Sign up to get free protection for your applications and to get access to all the features.
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