ci_reporter_rspec 0.0.1 → 0.0.2

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: c5782dda8a0c0bda589fb30fb0dff6af461a3b6c
4
- data.tar.gz: 50004c58bab2655617aec6e18a2bfc7eced4ec5a
3
+ metadata.gz: a33ed2d94b91f22678eb86c1bc7bcdf4e678cd50
4
+ data.tar.gz: 9b68fabf8d01213ef97062205b5f36036be93c80
5
5
  SHA512:
6
- metadata.gz: 7f1550786b9be743b0bbf452204001eb2f7a424129d4916439ebf8654b044c0ea94d972c07ef36c79d625ba853617fbfe9aef4ba158b9dd828e4a20fdab0b36a
7
- data.tar.gz: b813f2e977a9c41d546784207090330f0ca74dbb795b74c7afcf888e0b378c17469eea16a5a5f79b2788cf73aac48515b8cfda775e47d1795bf0260e65ed9328
6
+ metadata.gz: b311d9e867b79555cbda704ee86cf18c208a92089d3dd6e941df793cf862e7ef47f8363d506fd0754c44e289cc3e5a2cdbc7d4088329899c2c65a6c64187c33f
7
+ data.tar.gz: ee3e68cf1c0942c749ad0ae5e58396638ab4ae3b501c2f6e645c06c9741bd46dbd638d9f4fa648300fea07b160642b2d1fe1cd1ebd88f6da4cdde243a4eb64ed
data/.travis.yml CHANGED
@@ -7,3 +7,4 @@ rvm:
7
7
  gemfile:
8
8
  - Gemfile
9
9
  - gemfiles/Gemfile.2.14
10
+ - gemfiles/Gemfile.2.99
data/README.md CHANGED
@@ -3,6 +3,11 @@
3
3
  Connects [RSpec][rspec] to [CI::Reporter][ci], and then to your CI
4
4
  system.
5
5
 
6
+ [![Gem Version](https://badge.fury.io/rb/ci_reporter_rspec.svg)](http://badge.fury.io/rb/ci_reporter_rspec)
7
+ [![Build Status](https://travis-ci.org/ci-reporter/ci_reporter_rspec.svg?branch=master)](https://travis-ci.org/ci-reporter/ci_reporter_rspec)
8
+ [![Dependency Status](https://gemnasium.com/ci-reporter/ci_reporter_rspec.svg)](https://gemnasium.com/ci-reporter/ci_reporter_rspec)
9
+ [![Code Climate](https://codeclimate.com/github/ci-reporter/ci_reporter_rspec.png)](https://codeclimate.com/github/ci-reporter/ci_reporter_rspec)
10
+
6
11
  [rspec]: https://www.relishapp.com/rspec
7
12
  [ci]: https://github.com/ci-reporter/ci_reporter
8
13
 
data/Rakefile CHANGED
@@ -1,6 +1,6 @@
1
1
  require "bundler/gem_tasks"
2
- require 'ci/reporter/internal'
3
- include CI::Reporter::Internal
2
+ require 'ci/reporter/test_utils/rake'
3
+ include CI::Reporter::TestUtils::Rake
4
4
 
5
5
  namespace :generate do
6
6
  task :clean do
@@ -9,7 +9,7 @@ namespace :generate do
9
9
 
10
10
  task :rspec do
11
11
  rspec = "#{Gem.loaded_specs['rspec-core'].gem_dir}/exe/rspec"
12
- run_ruby_acceptance "-S #{rspec} --require ci/reporter/rake/rspec_loader --format CI::Reporter::RSpec acceptance/rspec_example_spec.rb"
12
+ run_ruby_acceptance "-S #{rspec} --require ci/reporter/rake/rspec_loader --format CI::Reporter::RSpecFormatter acceptance/rspec_example_spec.rb"
13
13
  end
14
14
 
15
15
  task :all => [:clean, :rspec]
@@ -1,17 +1,48 @@
1
- describe "RSpec example" do
2
- it "should succeed" do
1
+ RSpec.configure do |config|
2
+ config.expect_with :rspec do |c|
3
+ c.syntax = [:should, :expect]
4
+ end
5
+ end
6
+
7
+ describe "a passing example" do
8
+ it "passes" do
3
9
  true.should be true
4
- nil.should be_nil
5
10
  end
11
+ end
6
12
 
7
- it "should fail" do
13
+ describe "a failing example" do
14
+ it "fails" do
8
15
  true.should be false
9
16
  end
17
+ end
18
+
19
+ describe "an errored example" do
20
+ it "errors" do
21
+ raise "What happened?"
22
+ end
23
+ end
24
+
25
+ describe "a pending example" do
26
+ it "is not run"
27
+ end
10
28
 
11
- it "should be pending"
29
+ describe "a failure in a before block" do
30
+ before do
31
+ true.should be false
32
+ end
33
+
34
+ it "doesn't matter" do
35
+ true.should be true
36
+ end
37
+ end
38
+
39
+ describe "outer context" do
40
+ it "passes" do
41
+ true.should be true
42
+ end
12
43
 
13
- describe "nested" do
14
- it "should succeed" do
44
+ describe "inner context" do
45
+ it "passes" do
15
46
  true.should be true
16
47
  end
17
48
  end
@@ -1,33 +1,132 @@
1
1
  require 'rexml/document'
2
+ require 'ci/reporter/test_utils/accessor'
3
+ require 'ci/reporter/test_utils/shared_examples'
4
+ begin
5
+ require 'rspec/collection_matchers'
6
+ rescue LoadError
7
+ # This gem doesn't support all versions of RSpec
8
+ end
2
9
 
3
10
  REPORTS_DIR = File.dirname(__FILE__) + '/reports'
4
11
 
12
+ shared_examples "assertions are not tracked" do
13
+ describe "the assertion count" do
14
+ subject { result.assertions_count }
15
+ it { should eql 0 }
16
+ end
17
+ end
18
+
5
19
  describe "RSpec acceptance" do
6
- it "should generate two XML files" do
7
- File.exist?(File.join(REPORTS_DIR, 'SPEC-RSpec-example.xml')).should == true
8
- File.exist?(File.join(REPORTS_DIR, 'SPEC-RSpec-example-nested.xml')).should == true
20
+ include CI::Reporter::TestUtils::SharedExamples
21
+ Accessor = CI::Reporter::TestUtils::Accessor
22
+
23
+ let(:passing_report_path) { File.join(REPORTS_DIR, 'SPEC-a-passing-example.xml') }
24
+ let(:failing_report_path) { File.join(REPORTS_DIR, 'SPEC-a-failing-example.xml') }
25
+ let(:errored_report_path) { File.join(REPORTS_DIR, 'SPEC-an-errored-example.xml') }
26
+ let(:pending_report_path) { File.join(REPORTS_DIR, 'SPEC-a-pending-example.xml') }
27
+ let(:failure_in_before_report_path) { File.join(REPORTS_DIR, 'SPEC-a-failure-in-a-before-block.xml') }
28
+ let(:nested_outer_report_path) { File.join(REPORTS_DIR, 'SPEC-outer-context.xml') }
29
+ let(:nested_inner_report_path) { File.join(REPORTS_DIR, 'SPEC-outer-context-inner-context.xml') }
30
+
31
+ describe "the passing test" do
32
+ subject(:result) { Accessor.new(load_xml_result(passing_report_path)) }
33
+
34
+ it { should have(0).errors }
35
+ it { should have(0).failures }
36
+ it { should have(1).testcases }
37
+
38
+ it_behaves_like "a report with consistent attribute counts"
39
+ it_behaves_like "assertions are not tracked"
40
+ it_behaves_like "nothing was output"
9
41
  end
10
42
 
11
- it "should have two tests and one failure" do
12
- doc = File.open(File.join(REPORTS_DIR, 'SPEC-RSpec-example.xml')) do |f|
13
- REXML::Document.new(f)
43
+ describe "the failing test" do
44
+ subject(:result) { Accessor.new(load_xml_result(failing_report_path)) }
45
+
46
+ it { should have(0).errors }
47
+ it { should have(1).failures }
48
+ it { should have(1).testcases }
49
+
50
+ describe "the failure" do
51
+ subject(:failure) { result.failures.first }
52
+ it "indicates the type" do
53
+ failure.attributes['type'].should =~ /ExpectationNotMetError/
54
+ end
55
+ end
56
+
57
+ it_behaves_like "a report with consistent attribute counts"
58
+ it_behaves_like "assertions are not tracked"
59
+ it_behaves_like "nothing was output"
60
+ end
61
+
62
+ describe "the errored test" do
63
+ subject(:result) { Accessor.new(load_xml_result(errored_report_path)) }
64
+
65
+ it { should have(1).errors }
66
+ it { should have(0).failures }
67
+ it { should have(1).testcases }
68
+
69
+ it_behaves_like "a report with consistent attribute counts"
70
+ it_behaves_like "assertions are not tracked"
71
+ it_behaves_like "nothing was output"
72
+ end
73
+
74
+ describe "the pending test" do
75
+ subject(:result) { Accessor.new(load_xml_result(pending_report_path)) }
76
+
77
+ it { should have(0).errors }
78
+ it { should have(0).failures }
79
+ it { should have(1).testcases }
80
+
81
+ describe "the skipped count" do
82
+ subject { result.skipped_count }
83
+ it { should eql 1 }
14
84
  end
15
- doc.root.attributes["errors"].should == "0"
16
- doc.root.attributes["failures"].should == "1"
17
- doc.root.attributes["tests"].should == "3"
18
- doc.root.elements.to_a("/testsuite/testcase").size.should == 3
19
- failures = doc.root.elements.to_a("/testsuite/testcase/failure")
20
- failures.size.should == 1
21
- failures.first.attributes["type"].should =~ /ExpectationNotMetError/
85
+
86
+ it_behaves_like "a report with consistent attribute counts"
87
+ it_behaves_like "assertions are not tracked"
88
+ it_behaves_like "nothing was output"
89
+ end
90
+
91
+ describe "the test that fails in a before block" do
92
+ subject(:result) { Accessor.new(load_xml_result(failure_in_before_report_path)) }
93
+
94
+ it { should have(0).errors }
95
+ it { should have(1).failures }
96
+ it { should have(1).testcases }
97
+
98
+ it_behaves_like "a report with consistent attribute counts"
99
+ it_behaves_like "assertions are not tracked"
100
+ it_behaves_like "nothing was output"
101
+ end
102
+
103
+ describe "the outer context" do
104
+ subject(:result) { Accessor.new(load_xml_result(nested_outer_report_path)) }
105
+
106
+ it { should have(0).errors }
107
+ it { should have(0).failures }
108
+ it { should have(1).testcases }
109
+
110
+ it_behaves_like "a report with consistent attribute counts"
111
+ it_behaves_like "assertions are not tracked"
112
+ it_behaves_like "nothing was output"
113
+ end
114
+
115
+ describe "the inner context" do
116
+ subject(:result) { Accessor.new(load_xml_result(nested_inner_report_path)) }
117
+
118
+ it { should have(0).errors }
119
+ it { should have(0).failures }
120
+ it { should have(1).testcases }
121
+
122
+ it_behaves_like "a report with consistent attribute counts"
123
+ it_behaves_like "assertions are not tracked"
124
+ it_behaves_like "nothing was output"
22
125
  end
23
126
 
24
- it "should have one test in the nested example report" do
25
- doc = File.open(File.join(REPORTS_DIR, 'SPEC-RSpec-example-nested.xml')) do |f|
127
+ def load_xml_result(path)
128
+ File.open(path) do |f|
26
129
  REXML::Document.new(f)
27
130
  end
28
- doc.root.attributes["errors"].should == "0"
29
- doc.root.attributes["failures"].should == "0"
30
- doc.root.attributes["tests"].should == "1"
31
- doc.root.elements.to_a("/testsuite/testcase").size.should == 1
32
131
  end
33
132
  end
@@ -17,9 +17,11 @@ Gem::Specification.new do |spec|
17
17
  spec.test_files = spec.files.grep(%r{^(test|spec|features|acceptance)/})
18
18
  spec.require_paths = ["lib"]
19
19
 
20
- spec.add_dependency "rspec", "~> 2.14"
21
- spec.add_dependency "ci_reporter", "2.0.0.alpha1"
20
+ spec.add_dependency "rspec", ">= 2.14", "< 4"
21
+ spec.add_dependency "ci_reporter", "2.0.0.alpha2"
22
22
 
23
23
  spec.add_development_dependency "bundler", "~> 1.6"
24
24
  spec.add_development_dependency "rake"
25
+ spec.add_development_dependency "ci_reporter_test_utils"
26
+ spec.add_development_dependency "rspec-collection_matchers"
25
27
  end
@@ -3,3 +3,7 @@ source 'https://rubygems.org'
3
3
  gem 'rake'
4
4
  gem 'rspec', '~> 2.14.0'
5
5
  gem 'ci_reporter_rspec', path: '..'
6
+
7
+ group :test do
8
+ gem 'ci_reporter_test_utils'
9
+ end
@@ -0,0 +1,9 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'rake'
4
+ gem 'rspec', '~> 2.99.0'
5
+ gem 'ci_reporter_rspec', path: '..'
6
+
7
+ group :test do
8
+ gem 'ci_reporter_test_utils'
9
+ end
@@ -6,22 +6,26 @@ namespace :ci do
6
6
  rm_rf ENV["CI_REPORTS"] || "spec/reports"
7
7
  end
8
8
 
9
- task :rspec => :spec_report_cleanup do
10
- spec_opts = ["--require", CI::Reporter.maybe_quote_filename("#{File.dirname(__FILE__)}/rspec_loader.rb"),
11
- "--format", "CI::Reporter::RSpec"].join(" ")
9
+ def setup_spec_opts(*extra_options)
10
+ base_opts = [
11
+ "--require", CI::Reporter.maybe_quote_filename("#{File.dirname(__FILE__)}/rspec_loader.rb"),
12
+ "--format", "CI::Reporter::RSpecFormatter"
13
+ ]
14
+
15
+ spec_opts = (base_opts + extra_options).join(" ")
12
16
  ENV["SPEC_OPTS"] = "#{ENV['SPEC_OPTS']} #{spec_opts}"
13
17
  end
14
18
 
19
+ task :rspec => :spec_report_cleanup do
20
+ setup_spec_opts("--format", "progress")
21
+ end
22
+
15
23
  task :rspecdoc => :spec_report_cleanup do
16
- spec_opts = ["--require", CI::Reporter.maybe_quote_filename("#{File.dirname(__FILE__)}/rspec_loader.rb"),
17
- "--format", "CI::Reporter::RSpecDoc"].join(" ")
18
- ENV["SPEC_OPTS"] = "#{ENV['SPEC_OPTS']} #{spec_opts}"
24
+ setup_spec_opts("--format", "documentation")
19
25
  end
20
26
 
21
27
  task :rspecbase => :spec_report_cleanup do
22
- spec_opts = ["--require", CI::Reporter.maybe_quote_filename("#{File.dirname(__FILE__)}/rspec_loader.rb"),
23
- "--format", "CI::Reporter::RSpecBase"].join(" ")
24
- ENV["SPEC_OPTS"] = "#{ENV['SPEC_OPTS']} #{spec_opts}"
28
+ setup_spec_opts
25
29
  end
26
30
  end
27
31
  end
@@ -1,173 +1,15 @@
1
1
  require 'ci/reporter/core'
2
2
 
3
- module CI
4
- module Reporter
5
- module RSpecFormatters
6
- require 'rspec/core/formatters/base_formatter'
7
- require 'rspec/core/formatters/progress_formatter'
8
- require 'rspec/core/formatters/documentation_formatter'
9
- BaseFormatter = ::RSpec::Core::Formatters::BaseFormatter
10
- ProgressFormatter = ::RSpec::Core::Formatters::ProgressFormatter
11
- DocFormatter = ::RSpec::Core::Formatters::DocumentationFormatter
12
- # See https://github.com/nicksieger/ci_reporter/issues/76 and
13
- # https://github.com/nicksieger/ci_reporter/issues/80
14
- require 'rspec/core/version'
15
- RSpec_2_12_0_bug = (::RSpec::Core::Version::STRING == '2.12.0' &&
16
- !BaseFormatter.instance_methods(false).map(&:to_s).include?("format_backtrace"))
17
- end
18
-
19
- # Wrapper around a <code>RSpec</code> error or failure to be used by the test suite to interpret results.
20
- class RSpec2Failure
21
- attr_reader :exception
22
-
23
- def initialize(example, formatter)
24
- @formatter = formatter
25
- @example = example
26
- if @example.respond_to?(:execution_result)
27
- @exception = @example.execution_result[:exception] || @example.execution_result[:exception_encountered]
28
- else
29
- @exception = @example.metadata[:execution_result][:exception]
30
- end
31
- end
32
-
33
- def name
34
- @exception.class.name
35
- end
36
-
37
- def message
38
- @exception.message
39
- end
40
-
41
- def failure?
42
- exception.is_a?(::RSpec::Expectations::ExpectationNotMetError)
43
- end
44
-
45
- def error?
46
- !failure?
47
- end
48
-
49
- def location
50
- output = []
51
- output.push "#{exception.class.name << ":"}" unless exception.class.name =~ /RSpec/
52
- output.push @exception.message
53
-
54
- format_metadata = RSpecFormatters::RSpec_2_12_0_bug ? @example.metadata : @example
55
-
56
- [@formatter.format_backtrace(@exception.backtrace, format_metadata)].flatten.each do |backtrace_info|
57
- backtrace_info.lines.each do |line|
58
- output.push " #{line}"
59
- end
60
- end
61
- output.join "\n"
62
- end
63
- end
64
-
65
- # Custom +RSpec+ formatter used to hook into the spec runs and capture results.
66
- class RSpec
67
- attr_accessor :report_manager
68
- attr_accessor :formatter
69
- def initialize(*args)
70
- @formatter ||= RSpecFormatters::ProgressFormatter.new(*args)
71
- @report_manager = ReportManager.new("spec")
72
- @suite = nil
73
- end
74
-
75
- def example_group_started(example_group)
76
- @formatter.example_group_started(example_group)
77
- new_suite(description_for(example_group))
78
- end
79
-
80
- def example_started(name_or_example)
81
- @formatter.example_started(name_or_example)
82
- spec = TestCase.new
83
- @suite.testcases << spec
84
- spec.start
85
- end
86
-
87
- def example_failed(name_or_example, *rest)
88
- @formatter.example_failed(name_or_example, *rest)
89
-
90
- # In case we fail in before(:all)
91
- example_started(name_or_example) if @suite.testcases.empty?
92
-
93
- failure = RSpec2Failure.new(name_or_example, @formatter)
94
-
95
- spec = @suite.testcases.last
96
- spec.finish
97
- spec.name = description_for(name_or_example)
98
- spec.failures << failure
99
- end
100
-
101
- def example_passed(name_or_example)
102
- @formatter.example_passed(name_or_example)
103
- spec = @suite.testcases.last
104
- spec.finish
105
- spec.name = description_for(name_or_example)
106
- end
107
-
108
- def example_pending(*args)
109
- @formatter.example_pending(*args)
110
- name = description_for(args[0])
111
- spec = @suite.testcases.last
112
- spec.finish
113
- spec.name = "#{name} (PENDING)"
114
- spec.skipped = true
115
- end
116
-
117
- def dump_summary(*args)
118
- @formatter.dump_summary(*args)
119
- write_report
120
- @formatter.dump_failures
121
- end
122
-
123
- def respond_to?(*args)
124
- @formatter.respond_to?(*args)
125
- end
126
-
127
- # Pass through other methods to RSpec formatter for compatibility
128
- def method_missing(meth,*args,&block)
129
- @formatter.send(meth,*args,&block)
130
- end
131
-
132
- private
133
- def description_for(name_or_example)
134
- if name_or_example.respond_to?(:full_description)
135
- name_or_example.full_description
136
- elsif name_or_example.respond_to?(:metadata)
137
- name_or_example.metadata[:example_group][:full_description]
138
- elsif name_or_example.respond_to?(:description)
139
- name_or_example.description
140
- else
141
- "UNKNOWN"
142
- end
143
- end
144
-
145
- def write_report
146
- if @suite
147
- @suite.finish
148
- @report_manager.write_report(@suite)
149
- end
150
- end
151
-
152
- def new_suite(name)
153
- write_report if @suite
154
- @suite = TestSuite.new name
155
- @suite.start
156
- end
157
- end
158
-
159
- class RSpecDoc < RSpec
160
- def initialize(*args)
161
- @formatter = RSpecFormatters::DocFormatter.new(*args)
162
- super
163
- end
164
- end
165
-
166
- class RSpecBase < RSpec
167
- def initialize(*args)
168
- @formatter = RSpecFormatters::BaseFormatter.new(*args)
169
- super
170
- end
171
- end
3
+ module CI::Reporter
4
+ rspec_version = Gem::Version.new(::RSpec::Core::Version::STRING)
5
+ rspec_3 = Gem::Version.new('3.0.0')
6
+ RSPEC_3_AVAILABLE = rspec_version >= rspec_3
7
+
8
+ if RSPEC_3_AVAILABLE
9
+ require 'ci/reporter/rspec3/formatter'
10
+ RSpecFormatter = CI::Reporter::RSpec3::Formatter
11
+ else
12
+ require 'ci/reporter/rspec2/formatter'
13
+ RSpecFormatter = CI::Reporter::RSpec2::Formatter
172
14
  end
173
15
  end
@@ -1,7 +1,7 @@
1
1
  module CI
2
2
  module Reporter
3
- class RSpec
4
- VERSION = "0.0.1"
3
+ module RSpec
4
+ VERSION = "0.0.2"
5
5
  end
6
6
  end
7
7
  end
@@ -0,0 +1,46 @@
1
+ module CI::Reporter
2
+ module RSpec2
3
+ class Failure
4
+ attr_reader :exception
5
+
6
+ def initialize(example, formatter)
7
+ @formatter = formatter
8
+ @example = example
9
+ if @example.respond_to?(:execution_result)
10
+ @exception = @example.execution_result[:exception] || @example.execution_result[:exception_encountered]
11
+ else
12
+ @exception = @example.metadata[:execution_result][:exception]
13
+ end
14
+ end
15
+
16
+ def name
17
+ @exception.class.name
18
+ end
19
+
20
+ def message
21
+ @exception.message
22
+ end
23
+
24
+ def failure?
25
+ exception.is_a?(::RSpec::Expectations::ExpectationNotMetError)
26
+ end
27
+
28
+ def error?
29
+ !failure?
30
+ end
31
+
32
+ def location
33
+ output = []
34
+ output.push "#{exception.class.name << ":"}" unless exception.class.name =~ /RSpec/
35
+ output.push @exception.message
36
+
37
+ [@formatter.format_backtrace(@exception.backtrace, @example)].flatten.each do |backtrace_info|
38
+ backtrace_info.lines.each do |line|
39
+ output.push " #{line}"
40
+ end
41
+ end
42
+ output.join "\n"
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,80 @@
1
+ require 'rspec/core/formatters/base_formatter'
2
+ require 'ci/reporter/rspec2/failure'
3
+
4
+ module CI::Reporter
5
+ module RSpec2
6
+ class Formatter < ::RSpec::Core::Formatters::BaseFormatter
7
+ attr_accessor :report_manager
8
+ def initialize(*args)
9
+ @report_manager = ReportManager.new("spec")
10
+ @suite = nil
11
+ end
12
+
13
+ def example_group_started(example_group)
14
+ new_suite(description_for(example_group))
15
+ end
16
+
17
+ def example_started(name_or_example)
18
+ spec = TestCase.new
19
+ @suite.testcases << spec
20
+ spec.start
21
+ end
22
+
23
+ def example_failed(name_or_example, *rest)
24
+ # In case we fail in before(:all)
25
+ example_started(name_or_example) if @suite.testcases.empty?
26
+
27
+ failure = Failure.new(name_or_example, self)
28
+
29
+ spec = @suite.testcases.last
30
+ spec.finish
31
+ spec.name = description_for(name_or_example)
32
+ spec.failures << failure
33
+ end
34
+
35
+ def example_passed(name_or_example)
36
+ spec = @suite.testcases.last
37
+ spec.finish
38
+ spec.name = description_for(name_or_example)
39
+ end
40
+
41
+ def example_pending(*args)
42
+ name = description_for(args[0])
43
+ spec = @suite.testcases.last
44
+ spec.finish
45
+ spec.name = "#{name} (PENDING)"
46
+ spec.skipped = true
47
+ end
48
+
49
+ def dump_summary(*args)
50
+ write_report
51
+ end
52
+
53
+ private
54
+ def description_for(name_or_example)
55
+ if name_or_example.respond_to?(:full_description)
56
+ name_or_example.full_description
57
+ elsif name_or_example.respond_to?(:metadata)
58
+ name_or_example.metadata[:example_group][:full_description]
59
+ elsif name_or_example.respond_to?(:description)
60
+ name_or_example.description
61
+ else
62
+ "UNKNOWN"
63
+ end
64
+ end
65
+
66
+ def write_report
67
+ if @suite
68
+ @suite.finish
69
+ @report_manager.write_report(@suite)
70
+ end
71
+ end
72
+
73
+ def new_suite(name)
74
+ write_report if @suite
75
+ @suite = TestSuite.new name
76
+ @suite.start
77
+ end
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,37 @@
1
+ module CI::Reporter
2
+ module RSpec3
3
+ class Failure
4
+ def initialize(example)
5
+ @example = example
6
+ end
7
+
8
+ def name
9
+ exception.class.name
10
+ end
11
+
12
+ def message
13
+ exception.message
14
+ end
15
+
16
+ def failure?
17
+ exception.is_a?(::RSpec::Expectations::ExpectationNotMetError)
18
+ end
19
+
20
+ def error?
21
+ !failure?
22
+ end
23
+
24
+ def location
25
+ output = []
26
+ output.push "#{name}:" unless name =~ /RSpec/
27
+ output.push message
28
+ output.push @example.formatted_backtrace
29
+ output.join "\n"
30
+ end
31
+
32
+ def exception
33
+ @example.exception
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,76 @@
1
+ require 'ci/reporter/core'
2
+ require 'ci/reporter/rspec3/failure'
3
+
4
+ module CI::Reporter
5
+ module RSpec3
6
+ class Formatter
7
+ attr_accessor :report_manager
8
+
9
+ def initialize(*args)
10
+ @report_manager = ReportManager.new("spec")
11
+ end
12
+
13
+ def example_group_started(notification)
14
+ new_suite(notification.group.metadata[:full_description])
15
+ end
16
+
17
+ def example_started(notification)
18
+ spec = TestCase.new
19
+ @suite.testcases << spec
20
+ spec.start
21
+ end
22
+
23
+ def example_failed(notification)
24
+ # In case we fail in before(:all)
25
+ example_started(nil) if @suite.testcases.empty?
26
+
27
+ failure = Failure.new(notification)
28
+
29
+ current_spec.finish
30
+ current_spec.name = notification.example.full_description
31
+ current_spec.failures << failure
32
+ end
33
+
34
+ def example_passed(notification)
35
+ current_spec.finish
36
+ current_spec.name = notification.example.full_description
37
+ end
38
+
39
+ def example_pending(notification)
40
+ current_spec.finish
41
+ current_spec.name = "#{notification.example.full_description} (PENDING)"
42
+ current_spec.skipped = true
43
+ end
44
+
45
+ def stop(notification)
46
+ write_report
47
+ end
48
+
49
+ private
50
+
51
+ def current_spec
52
+ @suite.testcases.last
53
+ end
54
+
55
+ def write_report
56
+ return unless @suite
57
+ @suite.finish
58
+ @report_manager.write_report(@suite)
59
+ end
60
+
61
+ def new_suite(name)
62
+ write_report
63
+ @suite = TestSuite.new(name)
64
+ @suite.start
65
+ end
66
+ end
67
+
68
+ ::RSpec::Core::Formatters.register Formatter,
69
+ :example_group_started,
70
+ :example_started,
71
+ :example_passed,
72
+ :example_failed,
73
+ :example_pending,
74
+ :stop
75
+ end
76
+ end
@@ -1,42 +1,62 @@
1
1
  require File.dirname(__FILE__) + "/../../../spec_helper.rb"
2
2
  require 'rake'
3
+ require 'ci/reporter/test_utils/unit'
3
4
 
4
- require 'ci/reporter/internal'
5
- include CI::Reporter::Internal
5
+ describe "Rake tasks" do
6
+ include CI::Reporter::TestUtils::Unit
7
+
8
+ let (:rake) { Rake::Application.new }
6
9
 
7
- describe "ci_reporter ci:setup:rspec task" do
8
10
  before(:each) do
9
- @rake = Rake::Application.new
10
- Rake.application = @rake
11
+ Rake.application = rake
11
12
  load CI_REPORTER_LIB + '/ci/reporter/rake/rspec.rb'
12
13
  save_env "CI_REPORTS"
13
14
  save_env "SPEC_OPTS"
14
15
  ENV["CI_REPORTS"] = "some-bogus-nonexistent-directory-that-wont-fail-rm_rf"
15
16
  end
17
+
16
18
  after(:each) do
17
19
  restore_env "SPEC_OPTS"
18
20
  restore_env "CI_REPORTS"
19
21
  Rake.application = nil
20
22
  end
21
23
 
22
- it "should set ENV['SPEC_OPTS'] to include rspec formatter args" do
23
- @rake["ci:setup:rspec"].invoke
24
- ENV["SPEC_OPTS"].should =~ /--require.*rspec_loader.*--format.*CI::Reporter::RSpec/
24
+ subject(:spec_opts) { ENV["SPEC_OPTS"] }
25
+
26
+ context "ci:setup:rspec" do
27
+ before do
28
+ rake["ci:setup:rspec"].invoke
29
+ end
30
+
31
+ it { should match(/--require\s+\S+rspec_loader/) }
32
+ it { should match(/--format\s+CI::Reporter::RSpecFormatter\b/) }
33
+ it { should match(/--format\s+progress/) }
25
34
  end
26
35
 
27
- it "should set ENV['SPEC_OPTS'] to include rspec doc formatter if task is ci:setup:rspecdoc" do
28
- @rake["ci:setup:rspecdoc"].invoke
29
- ENV["SPEC_OPTS"].should =~ /--require.*rspec_loader.*--format.*CI::Reporter::RSpecDoc/
36
+ context "ci:setup:rspecdoc" do
37
+ before do
38
+ rake["ci:setup:rspecdoc"].invoke
39
+ end
40
+
41
+ it { should match(/--require\s+\S+rspec_loader/) }
42
+ it { should match(/--format\s+CI::Reporter::RSpecFormatter\b/) }
43
+ it { should match(/--format\s+documentation/) }
30
44
  end
31
45
 
32
- it "should set ENV['SPEC_OPTS'] to include rspec base formatter if task is ci:setup:rspecbase" do
33
- @rake["ci:setup:rspecbase"].invoke
34
- ENV["SPEC_OPTS"].should =~ /--require.*rspec_loader.*--format.*CI::Reporter::RSpecBase/
46
+ context "ci:setup:rspecbase" do
47
+ before do
48
+ rake["ci:setup:rspecbase"].invoke
49
+ end
50
+
51
+ it { should match(/--require\s+\S+rspec_loader/) }
52
+ it { should match(/--format\s+CI::Reporter::RSpecFormatter\b/) }
35
53
  end
36
54
 
37
- it "should append to ENV['SPEC_OPTS'] if it already contains a value" do
38
- ENV["SPEC_OPTS"] = "somevalue".freeze
39
- @rake["ci:setup:rspec"].invoke
40
- ENV["SPEC_OPTS"].should =~ /somevalue.*--require.*rspec_loader.*--format.*CI::Reporter::RSpec/
55
+ context "with existing options" do
56
+ it "appends new options" do
57
+ ENV["SPEC_OPTS"] = "previous-value".freeze
58
+ rake["ci:setup:rspec"].invoke
59
+ spec_opts.should match(/previous-value.*CI::Reporter::RSpecFormatter\b/)
60
+ end
41
61
  end
42
62
  end
@@ -0,0 +1,36 @@
1
+ require File.dirname(__FILE__) + "/../../../spec_helper.rb"
2
+ require File.dirname(__FILE__) + "/../../../support/rspec2"
3
+ require 'ci/reporter/rspec'
4
+ require 'ci/reporter/rspec2/failure'
5
+
6
+ module CI::Reporter::RSpec2
7
+ describe Failure do
8
+ include RSpec2Helpers
9
+
10
+ before(:each) do
11
+ skip "RSpec 3 present, skipping RSpec 2 tests" if CI::Reporter::RSPEC_3_AVAILABLE
12
+ end
13
+
14
+ before(:each) do
15
+ @formatter = Formatter.new
16
+ @rspec20_example = double('RSpec2.0 Example',
17
+ :execution_result => {:exception_encountered => StandardError.new('rspec2.0 ftw')},
18
+ :metadata => {})
19
+
20
+ @rspec22_example = rspec2_failing_example('rspec2.2 ftw')
21
+ end
22
+
23
+ it 'should handle rspec (< 2.2) execution results' do
24
+ failure = Failure.new(@rspec20_example, @formatter)
25
+ failure.name.should_not be_nil
26
+ failure.message.should == 'rspec2.0 ftw'
27
+ failure.location.should_not be_nil
28
+ end
29
+ it 'should handle rspec (>= 2.2) execution results' do
30
+ failure = Failure.new(@rspec22_example, @formatter)
31
+ failure.name.should_not be_nil
32
+ failure.message.should == 'rspec2.2 ftw'
33
+ failure.location.should_not be_nil
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,82 @@
1
+ require File.dirname(__FILE__) + "/../../../spec_helper.rb"
2
+ require File.dirname(__FILE__) + "/../../../support/rspec2"
3
+ require 'ci/reporter/rspec'
4
+ require 'ci/reporter/rspec2/formatter'
5
+ require 'stringio'
6
+
7
+ module CI::Reporter::RSpec2
8
+ describe Formatter do
9
+ include RSpec2Helpers
10
+
11
+ before(:each) do
12
+ skip "RSpec 3 present, skipping RSpec 2 tests" if CI::Reporter::RSPEC_3_AVAILABLE
13
+ end
14
+
15
+ before(:each) do
16
+ @error = double("error")
17
+ @error.stub(:expectation_not_met?).and_return(false)
18
+ @error.stub(:pending_fixed?).and_return(false)
19
+ @error.stub(:exception).and_return(StandardError.new)
20
+ @report_mgr = double("report manager")
21
+ @options = double("options")
22
+ @args = [@options, StringIO.new("")]
23
+ @fmt = Formatter.new *@args
24
+ @fmt.report_manager = @report_mgr
25
+ end
26
+
27
+ it "should create a test suite with one success, one failure, and one pending" do
28
+ @report_mgr.should_receive(:write_report) do |suite|
29
+ suite.testcases.length.should == 3
30
+ suite.testcases[0].should_not be_failure
31
+ suite.testcases[0].should_not be_error
32
+ suite.testcases[1].should be_error
33
+ suite.testcases[2].name.should =~ /\(PENDING\)/
34
+ end
35
+
36
+ example_group = double "example group"
37
+ example_group.stub(:description).and_return "A context"
38
+
39
+ @fmt.start(3)
40
+ @fmt.example_group_started(example_group)
41
+ @fmt.example_started("should pass")
42
+ @fmt.example_passed("should pass")
43
+ @fmt.example_started("should fail")
44
+ @fmt.example_failed(rspec2_failing_example("should fail"), 1, @error)
45
+ @fmt.example_started("should be pending")
46
+ @fmt.example_pending("A context", "should be pending", "Not Yet Implemented")
47
+ @fmt.start_dump
48
+ @fmt.dump_summary(0.1, 3, 1, 1)
49
+ @fmt.dump_pending
50
+ @fmt.close
51
+ end
52
+
53
+ it "should use the example #description method when available" do
54
+ group = double "example group"
55
+ group.stub(:description).and_return "group description"
56
+ example = double "example"
57
+ example.stub(:description).and_return "should do something"
58
+
59
+ @report_mgr.should_receive(:write_report) do |suite|
60
+ suite.testcases.last.name.should == "should do something"
61
+ end
62
+
63
+ @fmt.start(2)
64
+ @fmt.example_group_started(group)
65
+ @fmt.example_started(example)
66
+ @fmt.example_passed(example)
67
+ @fmt.dump_summary(0.1, 1, 0, 0)
68
+ end
69
+
70
+ it "should create a test suite with failure in before(:all)" do
71
+ example_group = double "example group"
72
+ example_group.stub(:description).and_return "A context"
73
+
74
+ @report_mgr.should_receive(:write_report)
75
+
76
+ @fmt.start(2)
77
+ @fmt.example_group_started(example_group)
78
+ @fmt.example_failed(rspec2_failing_example("should fail"), 1, @error)
79
+ @fmt.dump_summary(0.1, 1, 0, 0)
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,13 @@
1
+ module RSpec2Helpers
2
+ def rspec2_failing_example(exception_text)
3
+ double('RSpec2.2 Example',
4
+ :execution_result => {
5
+ :exception => StandardError.new(exception_text)
6
+ },
7
+ :metadata => {
8
+ :example_group => {
9
+ :full_description => "description"
10
+ }
11
+ })
12
+ end
13
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ci_reporter_rspec
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nick Sieger
@@ -9,36 +9,42 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-06-13 00:00:00.000000000 Z
12
+ date: 2014-07-02 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec
16
16
  requirement: !ruby/object:Gem::Requirement
17
17
  requirements:
18
- - - "~>"
18
+ - - ">="
19
19
  - !ruby/object:Gem::Version
20
20
  version: '2.14'
21
+ - - "<"
22
+ - !ruby/object:Gem::Version
23
+ version: '4'
21
24
  type: :runtime
22
25
  prerelease: false
23
26
  version_requirements: !ruby/object:Gem::Requirement
24
27
  requirements:
25
- - - "~>"
28
+ - - ">="
26
29
  - !ruby/object:Gem::Version
27
30
  version: '2.14'
31
+ - - "<"
32
+ - !ruby/object:Gem::Version
33
+ version: '4'
28
34
  - !ruby/object:Gem::Dependency
29
35
  name: ci_reporter
30
36
  requirement: !ruby/object:Gem::Requirement
31
37
  requirements:
32
38
  - - '='
33
39
  - !ruby/object:Gem::Version
34
- version: 2.0.0.alpha1
40
+ version: 2.0.0.alpha2
35
41
  type: :runtime
36
42
  prerelease: false
37
43
  version_requirements: !ruby/object:Gem::Requirement
38
44
  requirements:
39
45
  - - '='
40
46
  - !ruby/object:Gem::Version
41
- version: 2.0.0.alpha1
47
+ version: 2.0.0.alpha2
42
48
  - !ruby/object:Gem::Dependency
43
49
  name: bundler
44
50
  requirement: !ruby/object:Gem::Requirement
@@ -67,6 +73,34 @@ dependencies:
67
73
  - - ">="
68
74
  - !ruby/object:Gem::Version
69
75
  version: '0'
76
+ - !ruby/object:Gem::Dependency
77
+ name: ci_reporter_test_utils
78
+ requirement: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ type: :development
84
+ prerelease: false
85
+ version_requirements: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ - !ruby/object:Gem::Dependency
91
+ name: rspec-collection_matchers
92
+ requirement: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ type: :development
98
+ prerelease: false
99
+ version_requirements: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
70
104
  description:
71
105
  email:
72
106
  - nick@nicksieger.com
@@ -87,13 +121,20 @@ files:
87
121
  - ci_reporter_rspec.gemspec
88
122
  - gemfiles/.gitignore
89
123
  - gemfiles/Gemfile.2.14
124
+ - gemfiles/Gemfile.2.99
90
125
  - lib/ci/reporter/rake/rspec.rb
91
126
  - lib/ci/reporter/rake/rspec_loader.rb
92
127
  - lib/ci/reporter/rspec.rb
93
128
  - lib/ci/reporter/rspec/version.rb
129
+ - lib/ci/reporter/rspec2/failure.rb
130
+ - lib/ci/reporter/rspec2/formatter.rb
131
+ - lib/ci/reporter/rspec3/failure.rb
132
+ - lib/ci/reporter/rspec3/formatter.rb
94
133
  - spec/ci/reporter/rake/rake_tasks_spec.rb
95
- - spec/ci/reporter/rspec_spec.rb
134
+ - spec/ci/reporter/rspec2/failure_spec.rb
135
+ - spec/ci/reporter/rspec2/formatter_spec.rb
96
136
  - spec/spec_helper.rb
137
+ - spec/support/rspec2.rb
97
138
  homepage: https://github.com/ci-reporter/ci_reporter_rspec
98
139
  licenses:
99
140
  - MIT
@@ -123,5 +164,7 @@ test_files:
123
164
  - acceptance/rspec_example_spec.rb
124
165
  - acceptance/verification_spec.rb
125
166
  - spec/ci/reporter/rake/rake_tasks_spec.rb
126
- - spec/ci/reporter/rspec_spec.rb
167
+ - spec/ci/reporter/rspec2/failure_spec.rb
168
+ - spec/ci/reporter/rspec2/formatter_spec.rb
127
169
  - spec/spec_helper.rb
170
+ - spec/support/rspec2.rb
@@ -1,148 +0,0 @@
1
- require File.dirname(__FILE__) + "/../../spec_helper.rb"
2
- require 'ci/reporter/rspec'
3
- require 'stringio'
4
-
5
- describe "The RSpec reporter" do
6
- before(:each) do
7
- @error = double("error")
8
- @error.stub(:expectation_not_met?).and_return(false)
9
- @error.stub(:pending_fixed?).and_return(false)
10
- @error.stub(:exception).and_return(StandardError.new)
11
- @report_mgr = double("report manager")
12
- @options = double("options")
13
- @args = [@options, StringIO.new("")]
14
- @args.shift unless defined?(::Spec) && ::Spec::VERSION::MAJOR == 1 && ::Spec::VERSION::MINOR >= 1
15
- @fmt = CI::Reporter::RSpec.new *@args
16
- @fmt.report_manager = @report_mgr
17
- @formatter = double("formatter")
18
- @fmt.formatter = @formatter
19
- end
20
-
21
- it "should use a progress bar formatter by default" do
22
- fmt = CI::Reporter::RSpec.new *@args
23
- fmt.formatter.should be_instance_of(CI::Reporter::RSpecFormatters::ProgressFormatter)
24
- end
25
-
26
- it "should use a specdoc formatter for RSpecDoc" do
27
- fmt = CI::Reporter::RSpecDoc.new *@args
28
- fmt.formatter.should be_instance_of(CI::Reporter::RSpecFormatters::DocFormatter)
29
- end
30
-
31
- def rspec2_failing_example(exception_text)
32
- double('RSpec2.2 Example',
33
- :execution_result => {
34
- :exception => StandardError.new(exception_text)
35
- },
36
- :metadata => {
37
- :example_group => {
38
- :full_description => "description"
39
- }
40
- })
41
- end
42
-
43
- it "should create a test suite with one success, one failure, and one pending" do
44
- @report_mgr.should_receive(:write_report) do |suite|
45
- suite.testcases.length.should == 3
46
- suite.testcases[0].should_not be_failure
47
- suite.testcases[0].should_not be_error
48
- suite.testcases[1].should be_error
49
- suite.testcases[2].name.should =~ /\(PENDING\)/
50
- end
51
-
52
- example_group = double "example group"
53
- example_group.stub(:description).and_return "A context"
54
-
55
- @formatter.should_receive(:start).with(3)
56
- @formatter.should_receive(:example_group_started).with(example_group)
57
- @formatter.should_receive(:example_started).exactly(3).times
58
- @formatter.should_receive(:example_passed).once
59
- @formatter.should_receive(:example_failed).once
60
- @formatter.should_receive(:example_pending).once
61
- @formatter.should_receive(:start_dump).once
62
- @formatter.should_receive(:dump_failure).once
63
- @formatter.should_receive(:dump_summary).once
64
- @formatter.should_receive(:dump_pending).once
65
- @formatter.should_receive(:dump_failures).once
66
- @formatter.should_receive(:close).once
67
-
68
- @fmt.start(3)
69
- @fmt.example_group_started(example_group)
70
- @fmt.example_started("should pass")
71
- @fmt.example_passed("should pass")
72
- @fmt.example_started("should fail")
73
- @fmt.example_failed(rspec2_failing_example("should fail"), 1, @error)
74
- @fmt.example_started("should be pending")
75
- @fmt.example_pending("A context", "should be pending", "Not Yet Implemented")
76
- @fmt.start_dump
77
- @fmt.dump_failure(1, double("failure"))
78
- @fmt.dump_summary(0.1, 3, 1, 1)
79
- @fmt.dump_pending
80
- @fmt.close
81
- end
82
-
83
- it "should use the example #description method when available" do
84
- group = double "example group"
85
- group.stub(:description).and_return "group description"
86
- example = double "example"
87
- example.stub(:description).and_return "should do something"
88
-
89
- @formatter.should_receive(:start)
90
- @formatter.should_receive(:example_group_started).with(group)
91
- @formatter.should_receive(:example_started).with(example).once
92
- @formatter.should_receive(:example_passed).once
93
- @formatter.should_receive(:dump_summary)
94
- @formatter.should_receive(:dump_failures).once
95
- @report_mgr.should_receive(:write_report) do |suite|
96
- suite.testcases.last.name.should == "should do something"
97
- end
98
-
99
- @fmt.start(2)
100
- @fmt.example_group_started(group)
101
- @fmt.example_started(example)
102
- @fmt.example_passed(example)
103
- @fmt.dump_summary(0.1, 1, 0, 0)
104
- end
105
-
106
- it "should create a test suite with failure in before(:all)" do
107
- example_group = double "example group"
108
- example_group.stub(:description).and_return "A context"
109
-
110
- @formatter.should_receive(:start)
111
- @formatter.should_receive(:example_group_started).with(example_group)
112
- @formatter.should_receive(:example_started).once
113
- @formatter.should_receive(:example_failed).once
114
- @formatter.should_receive(:dump_summary)
115
- @formatter.should_receive(:dump_failures).once
116
- @report_mgr.should_receive(:write_report)
117
-
118
- @fmt.start(2)
119
- @fmt.example_group_started(example_group)
120
- @fmt.example_failed(rspec2_failing_example("should fail"), 1, @error)
121
- @fmt.dump_summary(0.1, 1, 0, 0)
122
- end
123
-
124
- describe 'RSpec2Failure' do
125
- before(:each) do
126
- @formatter = double "formatter"
127
- @formatter.should_receive(:format_backtrace).and_return("backtrace")
128
- @rspec20_example = double('RSpec2.0 Example',
129
- :execution_result => {:exception_encountered => StandardError.new('rspec2.0 ftw')},
130
- :metadata => {})
131
-
132
- @rspec22_example = rspec2_failing_example('rspec2.2 ftw')
133
- end
134
-
135
- it 'should handle rspec (< 2.2) execution results' do
136
- failure = CI::Reporter::RSpec2Failure.new(@rspec20_example, @formatter)
137
- failure.name.should_not be_nil
138
- failure.message.should == 'rspec2.0 ftw'
139
- failure.location.should_not be_nil
140
- end
141
- it 'should handle rspec (>= 2.2) execution results' do
142
- failure = CI::Reporter::RSpec2Failure.new(@rspec22_example, @formatter)
143
- failure.name.should_not be_nil
144
- failure.message.should == 'rspec2.2 ftw'
145
- failure.location.should_not be_nil
146
- end
147
- end
148
- end