ci_reporter_rspec 0.0.1 → 0.0.2

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