res 1.0.1 → 1.1.0.pre

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 30b35dcb30d280879775b9e15a0ec5bd0d55e289
4
- data.tar.gz: fc1cbd5e304e11af6ba7ae4f406dd93c7ce4aeda
3
+ metadata.gz: b731804b20181480f549059eeac6337968d79bd1
4
+ data.tar.gz: 62d01690d6f05bcb121c3c62dc9242a7ad1b9e08
5
5
  SHA512:
6
- metadata.gz: ca7bd13c3a9312fd8b9c4f0cd1aa1f7a20d810adb037b86ccd37f2ebd04e1efdf322eb0f4271a6ec6015a334e74d47238a6c94072a286bc574a0f8208c89c17d
7
- data.tar.gz: ffa22f1b34b2e2c7df830c7a7e607c7a411f854613e66b51fc0a261b88df3b2706151c725718d430cf804d00778a93b1253aa8022b57ba77c4190b701107c32d
6
+ metadata.gz: d2a33ffd4cb61a2905bcf0b21826d3f5fd5cedbf2f47a97eea6208f804591a57b61b7c39153fa1066ab66806a507f1dcc3b75737b1c2bf95efff9ed43108deaa
7
+ data.tar.gz: 475f54415d79992efaa03a5be29e644e91d6d13fd661437b111033457ae845ddb91cbbf576fba040c74919a04cd6e933a8d13fd01c0781192505c1533938ef9f
@@ -0,0 +1,140 @@
1
+ require 'rspec/core/formatters'
2
+ require 'res/ir'
3
+
4
+ module Res
5
+ module Formatters
6
+ class Rspec
7
+
8
+ attr_accessor :output, :result
9
+ RSpec::Core::Formatters.register self, :start,
10
+ :example_group_started, :example_passed, :example_failed, :example_pending,
11
+ :stop, :start_dump
12
+
13
+
14
+ def initialize output
15
+ @io = output
16
+ @result = Array.new
17
+ end
18
+
19
+ # Called when rspec starts execution
20
+ def start notification
21
+ @count = 0
22
+ @child = 0
23
+ end
24
+
25
+ # Called Once per example group
26
+ def example_group_started group_notification
27
+ if @child == 0
28
+ result[@count] = format_structure(group_notification.group)
29
+ @child += 1
30
+ i = 0
31
+ if result[@count].has_key?(:children)
32
+ index = result[@count][:children].count
33
+ else
34
+ index =0
35
+ end
36
+ while i < group_notification.group.examples.count
37
+ result[@count][:children] = Array.new if !result[@count].has_key?(:children)
38
+ result[@count][:children][index] = Hash.new
39
+ result[@count][:children][index] = add_result(group_notification.group.examples[i].metadata)
40
+ index += 1
41
+ i += 1
42
+ end
43
+ @count += 1
44
+ end
45
+ @child -= 1
46
+ end
47
+
48
+ # Called One of these per example, depending on outcome
49
+ def example_passed(passed_example_notification)
50
+ status = passed_example_notification.example.metadata[:execution_result].status.to_s
51
+ test = passed_example_notification.example
52
+ set_status(result, test.metadata[:location], status)
53
+ end
54
+
55
+ def example_failed(failed_example_notification)
56
+ status = failed_example_notification.example.metadata[:execution_result].status.to_s
57
+ test = failed_example_notification.example
58
+ set_status(result, test.metadata[:location], status)
59
+ end
60
+
61
+ def example_pending(pending_example_notification)
62
+ status = "skipped"
63
+ test = pending_example_notification.example
64
+ set_status(result, test.metadata[:location], status)
65
+ end
66
+
67
+ def add_result(test)
68
+ return {
69
+ "type": "Rspec::Test",
70
+ "name": test[:description],
71
+ "urn": test[:location],
72
+ }
73
+ end
74
+
75
+ def format_structure(group)
76
+
77
+ result = Hash.new
78
+ result[:type] = "Rspec::Describe"
79
+ result[:name] = group.description
80
+ result[:urn] = group.location
81
+ if !group.children.empty?
82
+ result[:children] = Array.new
83
+ i = 0
84
+ while i < group.children.count
85
+
86
+ result[:children][i] = format_structure(group.children[i])
87
+ @child += 1
88
+
89
+ k = 0
90
+ j = i
91
+ while k < group.children[i].examples.count
92
+ if k == 0
93
+ result[:children][j][:children] = Array.new
94
+ result[:children][j][:children][k] = Hash.new
95
+ end
96
+ result[:children][j][:children][k] = add_result(group.children[j].examples[k].metadata)
97
+ k += 1
98
+ end
99
+ i += 1
100
+ end
101
+ end
102
+
103
+ result
104
+ end
105
+
106
+ def set_status(result, urn, status)
107
+ result.each do |r|
108
+ if r[:type] == "Rspec::Describe"
109
+ set_status(r[:children], urn, status)
110
+ elsif r[:type] == "Rspec::Test"
111
+ if r[:urn] == urn
112
+ r[:status] = status
113
+ break;
114
+ end
115
+ end
116
+ end
117
+ end
118
+
119
+
120
+ # Called At the end of the suite
121
+ def stop(stop_notification)
122
+ @ir = ::Res::IR.new( :type => 'Rspec',
123
+ :started => '',
124
+ :results => result,
125
+ :finished => Time.now(),
126
+ )
127
+ end
128
+
129
+
130
+ def start_dump(start_dump_notification)
131
+ @io = File.open("./rspec.res", "w") if @io.class.to_s != "File"
132
+ @io.puts @ir.json
133
+ @io.close
134
+ end
135
+
136
+ end
137
+ end
138
+ end
139
+
140
+
@@ -3,19 +3,17 @@
3
3
  require 'fileutils'
4
4
  require 'res/ir'
5
5
  require 'cucumber/formatter/io'
6
+ require 'cucumber/formatter/summary'
6
7
 
7
8
  module Res
8
9
  module Formatters
9
10
  class RubyCucumber
10
11
  include FileUtils
11
12
  include ::Cucumber::Formatter::Io
12
-
13
+
13
14
  def initialize(runtime, path_or_io, options)
14
- cucumber_version = %x(cucumber --version)
15
- @cucumber_version = cucumber_version.gsub("\n","")
16
-
17
15
  @runtime = runtime
18
- @io = ensure_io(path_or_io, "reporter")
16
+ @io = ensure_io(path_or_io)
19
17
  @options = options
20
18
  @exceptions = []
21
19
  @indent = 0
@@ -44,13 +42,7 @@ module Res
44
42
  @_context = {}
45
43
  @_feature[:started] = Time.now()
46
44
  begin
47
- if @cucumber_version.to_f < 1.3.to_f
48
- uri = feature.file.to_s
49
- else
50
- uri = feature.location.to_s
51
- end
52
-
53
- hash = RubyCucumber.split_uri( uri )
45
+ hash = RubyCucumber.split_uri( feature.location.to_s )
54
46
  @_feature[:file] = hash[:file]
55
47
  @_feature[:line] = hash[:line]
56
48
  @_feature[:urn] = hash[:urn]
@@ -98,12 +90,7 @@ module Res
98
90
  @_context = {}
99
91
  @_feature_element[:started] = Time.now
100
92
  begin
101
- if @cucumber_version.to_f < 1.3.to_f
102
- uri = feature_element.file_colon_line
103
- else
104
- uri = feature_element.location.to_s
105
- end
106
- hash = RubyCucumber.split_uri( uri )
93
+ hash = RubyCucumber.split_uri( feature_element.location.to_s )
107
94
  @_feature_element[:file] = hash[:file]
108
95
  @_feature_element[:line] = hash[:line]
109
96
  @_feature_element[:urn] = hash[:urn]
@@ -122,9 +109,24 @@ module Res
122
109
  def after_feature_element(feature_element)
123
110
  @_context = {}
124
111
 
125
- if feature_element.respond_to? :status
126
- @_feature_element[:status] = feature_element.status
112
+ scenario_class = Cucumber::Formatter::LegacyApi::Ast::Scenario
113
+ example_table_class = Cucumber::Core::Ast::Location
114
+
115
+ fail = @runtime.scenarios(:failed).select do |s|
116
+ [scenario_class, example_table_class].include?(s.class)
117
+ end.map do |s|
118
+ if s.location == feature_element.location
119
+ s
120
+ end
121
+ end
122
+
123
+ if fail.compact.empty? and feature_element.respond_to? :status
124
+ @_feature_element[:status] = feature_element.status if feature_element.status.to_s != "skipped"
125
+ else
126
+ fail = fail.compact
127
+ @_feature_element[:status] = fail[0].status
127
128
  end
129
+
128
130
  @_feature_element[:finished] = Time.now
129
131
  end
130
132
 
@@ -138,24 +140,9 @@ module Res
138
140
  def background_name(keyword, name, file_colon_line, source_indent)
139
141
  end
140
142
 
141
- # def before_examples_array(examples_array)
142
- # @indent = 4
143
- # @io.puts
144
- # @visiting_first_example_name = true
145
- # end
146
- #
147
-
148
143
  def examples_name(keyword, name)
149
- # @io.puts unless @visiting_first_example_name
150
- # @visiting_first_example_name = false
151
- # names = name.strip.empty? ? [name.strip] : name.split("\n")
152
- # @io.puts(" #{keyword}: #{names[0]}")
153
- # names[1..-1].each {|s| @io.puts " #{s}" } unless names.empty?
154
- # @io.flush
155
- # @indent = 6
156
- # @scenario_indent = 6
157
144
  end
158
- #
145
+
159
146
 
160
147
  def scenario_name(keyword, name, file_colon_line, source_indent)
161
148
  @_context[:type] = "Cucumber::" + keyword.gsub(/\s+/, "")
@@ -176,23 +163,6 @@ module Res
176
163
  @_context = @_step
177
164
  end
178
165
 
179
- # def before_step_result(keyword, step_match, multiline_arg, status, exception, source_indent, background, file_colon_line)
180
- # @hide_this_step = false
181
- # if exception
182
- # if @exceptions.include?(exception)
183
- # @hide_this_step = true
184
- # return
185
- # end
186
- # @exceptions << exception
187
- # end
188
- # if status != :failed && @in_background ^ background
189
- # @hide_this_step = true
190
- # return
191
- # end
192
- # @status = status
193
- # end
194
-
195
- # Argument list changed after cucumber 1.4, hence the *args
196
166
  def step_name(keyword, step_match, status, source_indent, background, *args)
197
167
 
198
168
  file_colon_line = args[0] if args[0]
@@ -205,23 +175,12 @@ module Res
205
175
  @_step[:type] = "Cucumber::Step"
206
176
 
207
177
  end
208
-
209
- # def doc_string(string)
210
- # return if @options[:no_multiline] || @hide_this_step
211
- # s = %{"""\n#{string}\n"""}.indent(@indent)
212
- # s = s.split("\n").map{|l| l =~ /^\s+$/ ? '' : l}.join("\n")
213
- # @io.puts(format_string(s, @current_step.status))
214
- # @io.flush
215
- # end
216
- #
217
178
 
218
179
  def exception(exception, status)
219
180
  @_context[:message] = exception.to_s
220
181
  end
221
182
 
222
183
  def before_multiline_arg(multiline_arg)
223
- # return if @options[:no_multiline] || @hide_this_step
224
- # @table = multiline_arg
225
184
  end
226
185
 
227
186
  def after_multiline_arg(multiline_arg)
@@ -251,14 +210,17 @@ module Res
251
210
  end
252
211
 
253
212
  def after_table_row(table_row)
254
- if table_row.class == Cucumber::Ast::OutlineTable::ExampleRow
213
+ if table_row.class == Cucumber::Formatter::LegacyApi::Ast::ExampleTableRow
214
+
255
215
  @_current_table_row[:name] = table_row.name
256
216
  if table_row.exception
257
217
  @_current_table_row[:message] = table_row.exception.to_s
258
218
  end
259
- if table_row.scenario_outline
219
+
220
+ if table_row.status and table_row.status != "skipped" and table_row.status != nil
260
221
  @_current_table_row[:status] = table_row.status
261
222
  end
223
+
262
224
  @_current_table_row[:line] = table_row.line
263
225
  @_current_table_row[:urn] = @_feature_element[:file] + ":" + table_row.line.to_s
264
226
  @_table << @_current_table_row
@@ -0,0 +1,239 @@
1
+ # Formatter for ruby cucumber
2
+
3
+ require 'fileutils'
4
+ require 'res/ir'
5
+ require 'cucumber/formatter/io'
6
+
7
+ module Res
8
+ module Formatters
9
+ class RubyCucumberLegacy
10
+ include FileUtils
11
+ include ::Cucumber::Formatter::Io
12
+
13
+ def initialize(runtime, path_or_io, options)
14
+ cucumber_version = %x(cucumber --version)
15
+ @cucumber_version = cucumber_version.gsub("\n","")
16
+
17
+ @runtime = runtime
18
+ @io = ensure_io(path_or_io, "reporter")
19
+ @options = options
20
+ @exceptions = []
21
+ @indent = 0
22
+ @prefixes = options[:prefixes] || {}
23
+ @delayed_messages = []
24
+ @_start_time = Time.now
25
+ end
26
+
27
+ def before_features(features)
28
+ @_features = []
29
+ end
30
+
31
+ # Once everything has run -- whack it in a ResultIR object and
32
+ # dump it as json
33
+ def after_features(features)
34
+ results = @_features
35
+ ir = ::Res::IR.new( :started => @_start_time,
36
+ :finished => Time.now(),
37
+ :results => results,
38
+ :type => 'Cucumber' )
39
+ @io.puts ir.json
40
+ end
41
+
42
+ def before_feature(feature)
43
+ @_feature = {}
44
+ @_context = {}
45
+ @_feature[:started] = Time.now()
46
+ begin
47
+ if @cucumber_version.to_f < 1.3.to_f
48
+ uri = feature.file.to_s
49
+ else
50
+ uri = feature.location.to_s
51
+ end
52
+
53
+ hash = RubyCucumberLegacy.split_uri( uri )
54
+ @_feature[:file] = hash[:file]
55
+ @_feature[:line] = hash[:line]
56
+ @_feature[:urn] = hash[:urn]
57
+ rescue
58
+ @_feature[:uri] = 'unknown'
59
+ end
60
+ @_features << @_feature
61
+ @_context = @_feature
62
+ end
63
+
64
+ def comment_line(comment_line)
65
+ @_context[:comments] = [] if !@_context[:comments]
66
+ @_context[:comments] << comment_line
67
+ end
68
+
69
+ def after_tags(tags)
70
+ end
71
+
72
+ def tag_name(tag_name)
73
+ @_context[:tags] = [] if !@_context[:tag]
74
+ # Strip @ from tags
75
+ @_context[:tags] << tag_name[1..-1]
76
+ end
77
+
78
+ # { :type => 'Feature',
79
+ # :name => 'Feature name',
80
+ # :description => "As a blah\nAs a blah\n" }
81
+ def feature_name(keyword, name)
82
+ @_feature[:type] = "Cucumber::" + keyword.gsub(/\s+/, "")
83
+
84
+ lines = name.split("\n")
85
+ lines = lines.collect { |l| l.strip }
86
+
87
+ @_feature[:name] = lines.shift
88
+ @_feature[:description] = lines.join("\n")
89
+ end
90
+
91
+ def after_feature(feature)
92
+ @_feature[:finished] = Time.now()
93
+ end
94
+
95
+ def before_feature_element(feature_element)
96
+
97
+ @_feature_element = {}
98
+ @_context = {}
99
+ @_feature_element[:started] = Time.now
100
+ begin
101
+ if @cucumber_version.to_f < 1.3.to_f
102
+ uri = feature_element.file_colon_line
103
+ else
104
+ uri = feature_element.location.to_s
105
+ end
106
+ hash = RubyCucumberLegacy.split_uri( uri )
107
+ @_feature_element[:file] = hash[:file]
108
+ @_feature_element[:line] = hash[:line]
109
+ @_feature_element[:urn] = hash[:urn]
110
+ rescue => e
111
+ @_feature_element[:error] = e.message
112
+ @_feature_element[:file] = 'unknown'
113
+ end
114
+
115
+ @_feature[:children] = [] if ! @_feature[:children]
116
+
117
+ @_feature[:children] << @_feature_element
118
+ @_context = @_feature_element
119
+ end
120
+
121
+ # After a scenario
122
+ def after_feature_element(feature_element)
123
+ @_context = {}
124
+
125
+ if feature_element.respond_to? :status
126
+ @_feature_element[:status] = feature_element.status
127
+ end
128
+ @_feature_element[:finished] = Time.now
129
+ end
130
+
131
+ def before_background(background)
132
+ end
133
+
134
+ def after_background(background)
135
+ end
136
+
137
+ def background_name(keyword, name, file_colon_line, source_indent)
138
+ end
139
+
140
+ def examples_name(keyword, name)
141
+ end
142
+
143
+ def scenario_name(keyword, name, file_colon_line, source_indent)
144
+ @_context[:type] = "Cucumber::" + keyword.gsub(/\s+/, "")
145
+ @_context[:name] = name || ''
146
+ end
147
+
148
+ def before_step(step)
149
+ @_step = {}
150
+
151
+ # Background steps can appear totally divorced from scenerios (feature
152
+ # elements). Need to make sure we're not including them as children
153
+ # to scenario that don't exist
154
+ return if @_feature_element && @_feature_element[:finished]
155
+
156
+ @_feature_element = {} if !@_feature_element
157
+ @_feature_element[:children] = [] if !@_feature_element[:children]
158
+ @_feature_element[:children] << @_step
159
+ @_context = @_step
160
+ end
161
+
162
+ # Argument list changed after cucumber 1.4, hence the *args
163
+ def step_name(keyword, step_match, status, source_indent, background, *args)
164
+
165
+ file_colon_line = args[0] if args[0]
166
+
167
+ @_step[:type] = "Cucumber::Step"
168
+ name = keyword + step_match.format_args(lambda{|param| %{#{param}}})
169
+ @_step[:name] = name
170
+ @_step[:status] = status
171
+ @_step[:type] = "Cucumber::Step"
172
+
173
+ end
174
+
175
+ def exception(exception, status)
176
+ @_context[:message] = exception.to_s
177
+ end
178
+
179
+ def before_multiline_arg(multiline_arg)
180
+ end
181
+
182
+ def after_multiline_arg(multiline_arg)
183
+ @_context[:args] = multiline_arg.to_s.gsub(/\e\[(\d+)m/, '')
184
+ @_table = nil
185
+ end
186
+
187
+ # Before a scenario outline is encountered
188
+ def before_outline_table(outline_table)
189
+ # Scenario outlines appear as children like normal scenarios,
190
+ # but really we just want to construct normal-looking children
191
+ # from them
192
+ @_outlines = @_feature_element[:children]
193
+ @_table = []
194
+ end
195
+
196
+ def after_outline_table(outline_table)
197
+ headings = @_table.shift
198
+ description = @_outlines.collect{ |o| o[:name] }.join("\n") + "\n" + headings[:name]
199
+ @_feature_element[:children] = @_table
200
+ @_feature_element[:description] = description
201
+ end
202
+
203
+ def before_table_row(table_row)
204
+ @_current_table_row = { :type => 'Cucumber::ScenarioOutline::Example' }
205
+ @_table = [] if !@_table
206
+ end
207
+
208
+ def after_table_row(table_row)
209
+ if table_row.class == Cucumber::Ast::OutlineTable::ExampleRow
210
+ @_current_table_row[:name] = table_row.name
211
+ if table_row.exception
212
+ @_current_table_row[:message] = table_row.exception.to_s
213
+ end
214
+ if table_row.scenario_outline
215
+ @_current_table_row[:status] = table_row.status
216
+ end
217
+ @_current_table_row[:line] = table_row.line
218
+ @_current_table_row[:urn] = @_feature_element[:file] + ":" + table_row.line.to_s
219
+ @_table << @_current_table_row
220
+ end
221
+ end
222
+
223
+ def after_table_cell(cell)
224
+ end
225
+
226
+ def table_cell_value(value, status)
227
+ @_current_table_row[:children] = [] if !@_current_table_row[:children]
228
+ @_current_table_row[:children] << { :type => "Cucumber::ScenarioOutline::Parameter",
229
+ :name => value, :status => status }
230
+ end
231
+
232
+ def self.split_uri(uri)
233
+ strings = uri.rpartition(/:/)
234
+ { :file => strings[0], :line => strings[2].to_i, :urn => uri }
235
+ end
236
+
237
+ end
238
+ end
239
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: res
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 1.1.0.pre
5
5
  platform: ruby
6
6
  authors:
7
7
  - BBC
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2015-10-12 00:00:00.000000000 Z
13
+ date: 2015-11-03 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: json
@@ -79,7 +79,9 @@ files:
79
79
  - README.md
80
80
  - lib/res.rb
81
81
  - lib/res/config.rb
82
+ - lib/res/formatters/rspec.rb
82
83
  - lib/res/formatters/ruby_cucumber.rb
84
+ - lib/res/formatters/ruby_cucumber_legacy.rb
83
85
  - lib/res/ir.rb
84
86
  - lib/res/mappings.rb
85
87
  - lib/res/parsers/junit.rb
@@ -101,9 +103,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
101
103
  version: '0'
102
104
  required_rubygems_version: !ruby/object:Gem::Requirement
103
105
  requirements:
104
- - - ">="
106
+ - - ">"
105
107
  - !ruby/object:Gem::Version
106
- version: '0'
108
+ version: 1.3.1
107
109
  requirements: []
108
110
  rubyforge_project:
109
111
  rubygems_version: 2.4.8
@@ -111,4 +113,3 @@ signing_key:
111
113
  specification_version: 4
112
114
  summary: Test Result report libraries
113
115
  test_files: []
114
- has_rdoc: