Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JUnitFormatter works with RSpec 3 #1

Merged
merged 5 commits into from
Mar 26, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 12 additions & 15 deletions lib/rspec-extra-formatters/junit_formatter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
require "rspec/core/formatters/base_formatter"

class JUnitFormatter < RSpec::Core::Formatters::BaseFormatter
RSpec::Core::Formatters.register self, :example_passed, :example_failed, :example_pending, :dump_summary

attr_reader :test_results

Expand All @@ -38,36 +39,32 @@ def initialize(output)
@test_results = { :failures => [], :successes => [], :skipped => [] }
end

def example_passed(example)
super(example)
@test_results[:successes].push(example)
def example_passed(notification)
@test_results[:successes].push(notification.example)
end

def example_pending(example)
super(example)
@test_results[:skipped].push(example)
def example_pending(notification)
@test_results[:skipped].push(notification.example)
end

def example_failed(example)
super(example)
@test_results[:failures].push(example)
def example_failed(notification)
@test_results[:failures].push(notification.example)
end

def read_failure(t)
exception = t.metadata[:execution_result][:exception_encountered] || t.metadata[:execution_result][:exception]
def read_failure(example)
exception = example.metadata[:execution_result][:exception_encountered] || example.metadata[:execution_result][:exception]
message = ""
unless (exception.nil?)
message = exception.message
message += "\n"
message += format_backtrace(exception.backtrace, t).join("\n")
message += format_backtrace(exception.backtrace, example).join("\n")
end
return(message)
end

def dump_summary(duration, example_count, failure_count, pending_count)
super(duration, example_count, failure_count, pending_count)
def dump_summary(summary)
output.puts("<?xml version=\"1.0\" encoding=\"utf-8\" ?>")
output.puts("<testsuite errors=\"0\" failures=\"#{failure_count}\" skipped=\"#{pending_count}\" tests=\"#{example_count}\" time=\"#{duration}\" timestamp=\"#{Time.now.iso8601}\">")
output.puts("<testsuite errors=\"0\" failures=\"#{summary.failure_count}\" skipped=\"#{summary.pending_count}\" tests=\"#{summary.example_count}\" time=\"#{summary.duration}\" timestamp=\"#{Time.now.iso8601}\">")
output.puts(" <properties />")
@test_results[:successes].each do |t|
md = t.metadata
Expand Down
28 changes: 10 additions & 18 deletions lib/rspec-extra-formatters/tap_formatter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
require "rspec/core/formatters/base_formatter"

class TapFormatter < RSpec::Core::Formatters::BaseFormatter
RSpec::Core::Formatters.register self, :example_passed, :example_failed, :example_pending

attr_reader :total
$VERBOSE = nil
Expand All @@ -42,37 +43,28 @@ def initialize(output)
@total = 0
end

def start(example_count)
super(example_count)
def start(example_count_notification)
output.puts("TAP version 13")
output.puts("1.." + example_count.to_s)

output.puts("1.." + example_count_notification.count.to_s)
end

def example_passed(example)
super(example)
tap_example_output(OK, example)
def example_passed(notification)
tap_example_output(OK, notification.example)
end

def example_pending(example)
super(example)
tap_example_output(NOT_OK, example, SKIP)
def example_pending(notification)
tap_example_output(NOT_OK, notification.example, SKIP)
end

def example_failed(example)
super(example)
tap_example_output(NOT_OK, example)
def example_failed(notification)
tap_example_output(NOT_OK, notification.example)
output.puts(" ---")
my_exception = example.exception.to_s
my_exception = notification.example.exception.to_s
my_exception.gsub! /"/, ''
output.puts(" #{my_exception} ")
output.puts(" ...")
end

def dump_summary(duration, example_count, failure_count, pending_count)
super(duration, example_count, failure_count, pending_count)
end

private
def tap_example_output(ok, example, modifier='')
@total += 1
Expand Down
2 changes: 1 addition & 1 deletion rspec-extra-formatters.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,5 @@ Gem::Specification.new do |spec|
rspec-extra-formatters Provides TAP and JUnit formatters for rspec
EOF

spec.add_development_dependency("rspec")
spec.add_development_dependency("rspec", "3.0.0.beta2")
end
152 changes: 94 additions & 58 deletions spec/rspec-extra-formatters/junit_formatter_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,25 +27,38 @@
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

require "stringio"
require "rspec/core/notifications"
require File.expand_path(File.dirname(__FILE__) + "/../spec_helper.rb")

describe JUnitFormatter do

def example_notification(description, opts={})
metadata = {
:execution_result => {:run_time => 0.01},
:full_description => description,
:file_path => "./spec/rspec-extra-formatters/junit_formatter_spec.rb"
}.merge(opts)
dummy_example = double(:dummy_example)
allow(dummy_example).to receive(:metadata).and_return(metadata)
RSpec::Core::Notifications::ExampleNotification.new(dummy_example)
end

before(:each) do
@now = Time.now
Time.stub(:now).and_return(@now)
allow(Time).to receive(:now).and_return(@now)
end

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

noise

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you think I should leave it?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In some places you changed the whitespace around examples and groups, in others you did not. Either way, I suppose.

(I'm assuming we're going to open a PR upstream?)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair enough, I'll make it consistent.

it "should initialize the tests with failures and success" do
JUnitFormatter.new(StringIO.new).test_results.should eql({:failures=>[], :successes=>[], :skipped=>[]})
expect(JUnitFormatter.new(StringIO.new).test_results).to eql({:failures=>[], :successes=>[], :skipped=>[]})
end

describe "example_passed" do

it "should push the example obj into success list" do
f = JUnitFormatter.new(StringIO.new)
f.example_passed("foobar")
f.test_results[:successes].should eql(["foobar"])
notification = example_notification("foobar")
f.example_passed(notification)
expect(f.test_results[:successes]).to eql([notification.example])
end

end
Expand All @@ -54,8 +67,9 @@

it "should push the example obj into failures list" do
f = JUnitFormatter.new(StringIO.new)
f.example_failed("foobar")
f.test_results[:failures].should eql(["foobar"])
notification = example_notification("foobar")
f.example_failed(notification)
expect(f.test_results[:failures]).to eql([notification.example])
end

end
Expand All @@ -64,87 +78,102 @@

it "should push the example obj into the skipped list" do
f = JUnitFormatter.new(StringIO.new)
f.example_pending("foobar")
f.test_results[:skipped].should eql(["foobar"])
notification = example_notification("foobar")
f.example_pending(notification)
expect(f.test_results[:skipped]).to eql([notification.example])
end

end

describe "read_failure" do

it "should ignore if there is no exception" do
example = mock("example")
example.should_receive(:metadata).exactly(2).times.and_return({:execution_result => { :exception_encountered => nil \
, :exception => nil \
}})
notification = example_notification("example", {
:execution_result => {
:exception_encountered => nil,
:exception => nil
}
})
f = JUnitFormatter.new(StringIO.new)
f.read_failure(example).should eql("")
expect(f.read_failure(notification.example)).to eql("")
end

it "should attempt to read exception if exception encountered is nil" do
strace = mock("stacktrace")
strace.should_receive(:message).and_return("foobar")
strace.should_receive(:backtrace).and_return(["foo","bar"])
strace = double("stacktrace")
expect(strace).to receive(:message).and_return("foobar")
expect(strace).to receive(:backtrace).and_return(["foo","bar"])

example = mock("example")
example.should_receive(:metadata).exactly(3).times.and_return({:execution_result => { :exception_encountered => nil \
, :exception => strace \
}})
notification = example_notification("example", {
:execution_result => {
:exception_encountered => nil,
:exception => strace
}
})

f = JUnitFormatter.new(StringIO.new)
f.read_failure(example).should eql("foobar\nfoo\nbar")
expect(f.read_failure(notification.example)).to eql("foobar\nfoo\nbar")
end

it "should read message and backtrace from the example" do
strace = mock("stacktrace")
strace.should_receive(:message).and_return("foobar")
strace.should_receive(:backtrace).and_return(["foo","bar"])
strace = double("stacktrace")
expect(strace).to receive(:message).and_return("foobar")
expect(strace).to receive(:backtrace).and_return(["foo","bar"])

example = mock("example")
example.should_receive(:metadata).exactly(2).times.and_return({:execution_result => {:exception_encountered => strace}})
notification = example_notification("example", {
:execution_result => {:exception_encountered => strace}
}
)

f = JUnitFormatter.new(StringIO.new)
f.read_failure(example).should eql("foobar\nfoo\nbar")
expect(f.read_failure(notification.example)).to eql("foobar\nfoo\nbar")
end

end

describe "dump_summary" do

it "should print the junit xml" do
strace = mock("stacktrace")
strace.should_receive(:message).and_return("foobar")
strace.should_receive(:backtrace).and_return(["foo","bar"])
strace = double("stacktrace")
expect(strace).to receive(:message).and_return("foobar")
expect(strace).to receive(:backtrace).and_return(["foo","bar"])

example0 = mock("example-0")
example0.should_receive(:metadata).and_return({ :full_description => "foobar-success" \
, :file_path => "lib/foobar-s.rb" \
, :execution_result => { :run_time => 0.1 } \
})
example0 = example_notification("example-0", {
:full_description => "foobar-success",
:file_path => "lib/foobar-s.rb",
:execution_result => { :run_time => 0.1 }
})

example1 = mock("example-1")
example1.should_receive(:metadata).exactly(3).times.and_return({ :full_description => "foobar-failure" \
, :file_path => "lib/foobar-f.rb" \
, :execution_result => { :exception_encountered => strace \
, :run_time => 0.1 \
}
})

example2 = mock("example-2")
example2.should_receive(:metadata).and_return({ :full_description => "foobar-pending" \
, :file_path => "lib/foobar-s.rb" \
, :execution_result => { :run_time => 0.1 } \
})
example1 = example_notification("example-1", {
:full_description => "foobar-failure",
:file_path => "lib/foobar-f.rb",
:execution_result => {
:exception_encountered => strace,
:run_time => 0.1
}
})

example2 = example_notification("example-2", {
:full_description => "foobar-pending",
:file_path => "lib/foobar-s.rb",
:execution_result => { :run_time => 0.1 }
})


summary = double(
:summary,
:failure_count => 1,
:pending_count => 1,
:example_count => 3,
:duration => "0.1"
)
output = StringIO.new
f = JUnitFormatter.new(output)
f.example_passed(example0)
f.example_failed(example1)
f.example_pending(example2)
f.dump_summary("0.1", 3, 1, 1)
f.dump_summary(summary)

output.string.should == <<-EOF
expect(output.string).to eq(<<-EOF)
<?xml version="1.0" encoding="utf-8" ?>
<testsuite errors="0" failures="1" skipped="1" tests="3" time="0.1" timestamp="#{@now.iso8601}">
<properties />
Expand All @@ -162,18 +191,25 @@
end

it "should escape characteres <,>,&,\" before building xml" do
example0 = mock("example-0")
example0.should_receive(:metadata).and_return({ :full_description => "foobar-success >>> &\"& <<<" \
, :file_path => "lib/>foobar-s.rb" \
, :execution_result => { :run_time => 0.1 } \
})

example0 = example_notification("example-0", {
:full_description => "foobar-success >>> &\"& <<<",
:file_path => "lib/>foobar-s.rb",
:execution_result => { :run_time => 0.1 }
})

summary = double(
:summary,
:failure_count => 1,
:pending_count => 0,
:example_count => 2,
:duration => "0.1"
)
output = StringIO.new
f = JUnitFormatter.new(output)
f.example_passed(example0)
f.dump_summary("0.1", 2, 1, 0)
f.dump_summary(summary)

output.string.should == <<-EOF
expect(output.string).to eq(<<-EOF)
<?xml version="1.0" encoding="utf-8" ?>
<testsuite errors="0" failures="1" skipped="0" tests="2" time="0.1" timestamp="#{@now.iso8601}">
<properties />
Expand Down
Loading