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.
- data/History.rdoc +7 -0
- data/README.rdoc +4 -0
- data/Rakefile +1 -1
- data/cucumber_analytics.gemspec +3 -1
- data/features/modeling/background_modeling.feature +27 -13
- data/features/modeling/background_output.feature +130 -0
- data/features/modeling/directory_modeling.feature +11 -6
- data/features/modeling/directory_output.feature +13 -0
- data/features/modeling/doc_string_modeling.feature +18 -11
- data/features/modeling/doc_string_output.feature +71 -0
- data/features/modeling/example_modeling.feature +30 -19
- data/features/modeling/example_output.feature +192 -0
- data/features/modeling/feature_file_modeling.feature +9 -4
- data/features/modeling/feature_file_output.feature +13 -0
- data/features/modeling/feature_modeling.feature +33 -20
- data/features/modeling/feature_output.feature +244 -0
- data/features/modeling/outline_modeling.feature +29 -16
- data/features/modeling/outline_output.feature +197 -0
- data/features/modeling/row_modeling.feature +9 -4
- data/features/modeling/row_output.feature +27 -0
- data/features/modeling/scenario_modeling.feature +27 -14
- data/features/modeling/scenario_output.feature +147 -0
- data/features/modeling/step_modeling.feature +13 -8
- data/features/modeling/step_output.feature +52 -0
- data/features/modeling/table_modeling.feature +9 -4
- data/features/modeling/table_output.feature +42 -0
- data/features/modeling/table_row_modeling.feature +9 -4
- data/features/modeling/table_row_output.feature +27 -0
- data/features/modeling/tag_modeling.feature +10 -5
- data/features/modeling/tag_output.feature +16 -0
- data/features/step_definitions/action_steps.rb +3 -0
- data/features/step_definitions/background_steps.rb +17 -4
- data/features/step_definitions/directory_steps.rb +11 -0
- data/features/step_definitions/doc_string_steps.rb +18 -15
- data/features/step_definitions/feature_file_steps.rb +12 -1
- data/features/step_definitions/feature_steps.rb +23 -6
- data/features/step_definitions/outline_steps.rb +70 -9
- data/features/step_definitions/step_steps.rb +9 -1
- data/features/step_definitions/table_steps.rb +35 -2
- data/features/step_definitions/tag_steps.rb +8 -0
- data/features/step_definitions/test_steps.rb +14 -3
- data/features/step_definitions/verification_steps.rb +9 -0
- data/features/support/env.rb +1 -0
- data/lib/cucumber_analytics/background.rb +12 -0
- data/lib/cucumber_analytics/directory.rb +5 -0
- data/lib/cucumber_analytics/doc_string.rb +22 -0
- data/lib/cucumber_analytics/example.rb +55 -0
- data/lib/cucumber_analytics/feature.rb +26 -0
- data/lib/cucumber_analytics/feature_element.rb +25 -1
- data/lib/cucumber_analytics/feature_file.rb +5 -0
- data/lib/cucumber_analytics/outline.rb +18 -0
- data/lib/cucumber_analytics/parsing.rb +3 -1
- data/lib/cucumber_analytics/row.rb +5 -0
- data/lib/cucumber_analytics/scenario.rb +13 -0
- data/lib/cucumber_analytics/step.rb +8 -0
- data/lib/cucumber_analytics/table.rb +21 -0
- data/lib/cucumber_analytics/table_row.rb +5 -0
- data/lib/cucumber_analytics/tag.rb +5 -0
- data/lib/cucumber_analytics/taggable.rb +4 -0
- data/lib/cucumber_analytics/test_element.rb +8 -0
- data/lib/cucumber_analytics/version.rb +1 -1
- data/spec/integration/background_integration_spec.rb +12 -0
- data/spec/integration/example_integration_spec.rb +21 -0
- data/spec/integration/feature_integration_spec.rb +29 -0
- data/spec/integration/outline_integration_spec.rb +22 -0
- data/spec/integration/scenario_integration_spec.rb +16 -0
- data/spec/integration/step_integration_spec.rb +20 -0
- data/spec/integration/table_integration_spec.rb +11 -0
- data/spec/unit/background_unit_spec.rb +28 -0
- data/spec/unit/directory_unit_spec.rb +12 -0
- data/spec/unit/doc_string_unit_spec.rb +43 -3
- data/spec/unit/example_unit_spec.rb +53 -0
- data/spec/unit/feature_element_unit_specs.rb +9 -2
- data/spec/unit/feature_file_unit_spec.rb +12 -0
- data/spec/unit/feature_unit_spec.rb +30 -0
- data/spec/unit/outline_unit_spec.rb +30 -0
- data/spec/unit/row_unit_spec.rb +19 -7
- data/spec/unit/scenario_unit_spec.rb +30 -0
- data/spec/unit/step_unit_spec.rb +25 -1
- data/spec/unit/table_row_unit_spec.rb +12 -0
- data/spec/unit/table_unit_spec.rb +25 -0
- data/spec/unit/tag_unit_spec.rb +12 -0
- metadata +165 -86
- 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
|
-
|
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(?: "([^"]*)")?
|
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
|
-
|
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
|
data/features/support/env.rb
CHANGED
@@ -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
|
|
@@ -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
|
@@ -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
|
-
|
26
|
+
MultiJson.load(io.string)
|
25
27
|
end
|
26
28
|
|
27
29
|
end
|