summaryrefslogtreecommitdiff
path: root/spec/mspec/spec/runner/formatters
diff options
context:
space:
mode:
Diffstat (limited to 'spec/mspec/spec/runner/formatters')
-rw-r--r--spec/mspec/spec/runner/formatters/describe_spec.rb67
-rw-r--r--spec/mspec/spec/runner/formatters/dotted_spec.rb285
-rw-r--r--spec/mspec/spec/runner/formatters/file_spec.rb84
-rw-r--r--spec/mspec/spec/runner/formatters/html_spec.rb217
-rw-r--r--spec/mspec/spec/runner/formatters/junit_spec.rb147
-rw-r--r--spec/mspec/spec/runner/formatters/method_spec.rb178
-rw-r--r--spec/mspec/spec/runner/formatters/multi_spec.rb68
-rw-r--r--spec/mspec/spec/runner/formatters/specdoc_spec.rb106
-rw-r--r--spec/mspec/spec/runner/formatters/spinner_spec.rb83
-rw-r--r--spec/mspec/spec/runner/formatters/summary_spec.rb26
-rw-r--r--spec/mspec/spec/runner/formatters/unit_spec.rb74
-rw-r--r--spec/mspec/spec/runner/formatters/yaml_spec.rb125
12 files changed, 1460 insertions, 0 deletions
diff --git a/spec/mspec/spec/runner/formatters/describe_spec.rb b/spec/mspec/spec/runner/formatters/describe_spec.rb
new file mode 100644
index 0000000000..415ced71fb
--- /dev/null
+++ b/spec/mspec/spec/runner/formatters/describe_spec.rb
@@ -0,0 +1,67 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+require 'mspec/runner/formatters/describe'
+require 'mspec/runner/example'
+
+describe DescribeFormatter, "#finish" do
+ before :each do
+ MSpec.stub(:register)
+ MSpec.stub(:unregister)
+
+ @timer = double("timer").as_null_object
+ TimerAction.stub(:new).and_return(@timer)
+ @timer.stub(:format).and_return("Finished in 2.0 seconds")
+
+ $stdout = @out = IOStub.new
+ context = ContextState.new "Class#method"
+ @state = ExampleState.new(context, "runs")
+
+ @formatter = DescribeFormatter.new
+ @formatter.register
+
+ @tally = @formatter.tally
+ @counter = @tally.counter
+
+ @counter.files!
+ @counter.examples!
+ @counter.expectations! 2
+ end
+
+ after :each do
+ $stdout = STDOUT
+ end
+
+ it "prints a summary of elapsed time" do
+ @formatter.finish
+ @out.should =~ /^Finished in 2.0 seconds$/
+ end
+
+ it "prints a tally of counts" do
+ @formatter.finish
+ @out.should =~ /^1 file, 1 example, 2 expectations, 0 failures, 0 errors, 0 tagged$/
+ end
+
+ it "does not print exceptions" do
+ @formatter.finish
+ @out.should == %[
+
+Finished in 2.0 seconds
+
+1 file, 1 example, 2 expectations, 0 failures, 0 errors, 0 tagged
+]
+ end
+
+ it "prints a summary of failures and errors for each describe block" do
+ exc = ExceptionState.new @state, nil, MSpecExampleError.new("broken")
+ exc.stub(:backtrace).and_return("path/to/some/file.rb:35:in method")
+ @formatter.exception exc
+ @formatter.finish
+ @out.should == %[
+
+Class#method 0 failures, 1 error
+
+Finished in 2.0 seconds
+
+1 file, 1 example, 2 expectations, 0 failures, 0 errors, 0 tagged
+]
+ end
+end
diff --git a/spec/mspec/spec/runner/formatters/dotted_spec.rb b/spec/mspec/spec/runner/formatters/dotted_spec.rb
new file mode 100644
index 0000000000..1e9b06f6e1
--- /dev/null
+++ b/spec/mspec/spec/runner/formatters/dotted_spec.rb
@@ -0,0 +1,285 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+require 'mspec/runner/formatters/dotted'
+require 'mspec/runner/mspec'
+require 'mspec/runner/example'
+require 'mspec/utils/script'
+
+describe DottedFormatter, "#initialize" do
+ it "permits zero arguments" do
+ DottedFormatter.new
+ end
+
+ it "accepts one argument" do
+ DottedFormatter.new nil
+ end
+end
+
+describe DottedFormatter, "#register" do
+ before :each do
+ @formatter = DottedFormatter.new
+ MSpec.stub(:register)
+ end
+
+ it "registers self with MSpec for appropriate actions" do
+ MSpec.should_receive(:register).with(:exception, @formatter)
+ MSpec.should_receive(:register).with(:before, @formatter)
+ MSpec.should_receive(:register).with(:after, @formatter)
+ MSpec.should_receive(:register).with(:finish, @formatter)
+ @formatter.register
+ end
+
+ it "creates TimerAction and TallyAction" do
+ timer = double("timer")
+ tally = double("tally")
+ timer.should_receive(:register)
+ tally.should_receive(:register)
+ tally.should_receive(:counter)
+ TimerAction.should_receive(:new).and_return(timer)
+ TallyAction.should_receive(:new).and_return(tally)
+ @formatter.register
+ end
+end
+
+describe DottedFormatter, "#print" do
+ before :each do
+ $stdout = IOStub.new
+ end
+
+ after :each do
+ $stdout = STDOUT
+ end
+
+ it "writes to $stdout by default" do
+ formatter = DottedFormatter.new
+ formatter.print "begonias"
+ $stdout.should == "begonias"
+ end
+
+ it "writes to the file specified when the formatter was created" do
+ out = IOStub.new
+ File.should_receive(:open).with("some/file", "w").and_return(out)
+ formatter = DottedFormatter.new "some/file"
+ formatter.print "begonias"
+ out.should == "begonias"
+ end
+
+ it "flushes the IO output" do
+ $stdout.should_receive(:flush)
+ formatter = DottedFormatter.new
+ formatter.print "begonias"
+ end
+end
+
+describe DottedFormatter, "#exception" do
+ before :each do
+ @formatter = DottedFormatter.new
+ @failure = ExceptionState.new nil, nil, SpecExpectationNotMetError.new("failed")
+ @error = ExceptionState.new nil, nil, MSpecExampleError.new("boom!")
+ end
+
+ it "sets the #failure? flag" do
+ @formatter.exception @failure
+ @formatter.failure?.should be_true
+ @formatter.exception @error
+ @formatter.failure?.should be_false
+ end
+
+ it "sets the #exception? flag" do
+ @formatter.exception @error
+ @formatter.exception?.should be_true
+ @formatter.exception @failure
+ @formatter.exception?.should be_true
+ end
+
+ it "addes the exception to the list of exceptions" do
+ @formatter.exceptions.should == []
+ @formatter.exception @error
+ @formatter.exception @failure
+ @formatter.exceptions.should == [@error, @failure]
+ end
+end
+
+describe DottedFormatter, "#exception?" do
+ before :each do
+ @formatter = DottedFormatter.new
+ @failure = ExceptionState.new nil, nil, SpecExpectationNotMetError.new("failed")
+ @error = ExceptionState.new nil, nil, MSpecExampleError.new("boom!")
+ end
+
+ it "returns false if there have been no exceptions" do
+ @formatter.exception?.should be_false
+ end
+
+ it "returns true if any exceptions are errors" do
+ @formatter.exception @failure
+ @formatter.exception @error
+ @formatter.exception?.should be_true
+ end
+
+ it "returns true if all exceptions are failures" do
+ @formatter.exception @failure
+ @formatter.exception @failure
+ @formatter.exception?.should be_true
+ end
+
+ it "returns true if all exceptions are errors" do
+ @formatter.exception @error
+ @formatter.exception @error
+ @formatter.exception?.should be_true
+ end
+end
+
+describe DottedFormatter, "#failure?" do
+ before :each do
+ @formatter = DottedFormatter.new
+ @failure = ExceptionState.new nil, nil, SpecExpectationNotMetError.new("failed")
+ @error = ExceptionState.new nil, nil, MSpecExampleError.new("boom!")
+ end
+
+ it "returns false if there have been no exceptions" do
+ @formatter.failure?.should be_false
+ end
+
+ it "returns false if any exceptions are errors" do
+ @formatter.exception @failure
+ @formatter.exception @error
+ @formatter.failure?.should be_false
+ end
+
+ it "returns true if all exceptions are failures" do
+ @formatter.exception @failure
+ @formatter.exception @failure
+ @formatter.failure?.should be_true
+ end
+end
+
+describe DottedFormatter, "#before" do
+ before :each do
+ @state = ExampleState.new ContextState.new("describe"), "it"
+ @formatter = DottedFormatter.new
+ @formatter.exception ExceptionState.new(nil, nil, SpecExpectationNotMetError.new("Failed!"))
+ end
+
+ it "resets the #failure? flag to false" do
+ @formatter.failure?.should be_true
+ @formatter.before @state
+ @formatter.failure?.should be_false
+ end
+
+ it "resets the #exception? flag to false" do
+ @formatter.exception?.should be_true
+ @formatter.before @state
+ @formatter.exception?.should be_false
+ end
+end
+
+describe DottedFormatter, "#after" do
+ before :each do
+ $stdout = @out = IOStub.new
+ @formatter = DottedFormatter.new
+ @state = ExampleState.new ContextState.new("describe"), "it"
+ end
+
+ after :each do
+ $stdout = STDOUT
+ end
+
+ it "prints a '.' if there was no exception raised" do
+ @formatter.after(@state)
+ @out.should == "."
+ end
+
+ it "prints an 'F' if there was an expectation failure" do
+ exc = SpecExpectationNotMetError.new "failed"
+ @formatter.exception ExceptionState.new(@state, nil, exc)
+ @formatter.after(@state)
+ @out.should == "F"
+ end
+
+ it "prints an 'E' if there was an exception other than expectation failure" do
+ exc = MSpecExampleError.new("boom!")
+ @formatter.exception ExceptionState.new(@state, nil, exc)
+ @formatter.after(@state)
+ @out.should == "E"
+ end
+
+ it "prints an 'E' if there are mixed exceptions and exepctation failures" do
+ exc = SpecExpectationNotMetError.new "failed"
+ @formatter.exception ExceptionState.new(@state, nil, exc)
+ exc = MSpecExampleError.new("boom!")
+ @formatter.exception ExceptionState.new(@state, nil, exc)
+ @formatter.after(@state)
+ @out.should == "E"
+ end
+end
+
+describe DottedFormatter, "#finish" do
+ before :each do
+ @tally = double("tally").as_null_object
+ TallyAction.stub(:new).and_return(@tally)
+ @timer = double("timer").as_null_object
+ TimerAction.stub(:new).and_return(@timer)
+
+ $stdout = @out = IOStub.new
+ context = ContextState.new "Class#method"
+ @state = ExampleState.new(context, "runs")
+ MSpec.stub(:register)
+ @formatter = DottedFormatter.new
+ @formatter.register
+ end
+
+ after :each do
+ $stdout = STDOUT
+ end
+
+ it "prints a failure message for an exception" do
+ exc = ExceptionState.new @state, nil, MSpecExampleError.new("broken")
+ @formatter.exception exc
+ @formatter.after @state
+ @formatter.finish
+ @out.should =~ /^1\)\nClass#method runs ERROR$/
+ end
+
+ it "prints a backtrace for an exception" do
+ exc = ExceptionState.new @state, nil, MSpecExampleError.new("broken")
+ exc.stub(:backtrace).and_return("path/to/some/file.rb:35:in method")
+ @formatter.exception exc
+ @formatter.after @state
+ @formatter.finish
+ @out.should =~ %r[path/to/some/file.rb:35:in method$]
+ end
+
+ it "prints a summary of elapsed time" do
+ @timer.should_receive(:format).and_return("Finished in 2.0 seconds")
+ @formatter.finish
+ @out.should =~ /^Finished in 2.0 seconds$/
+ end
+
+ it "prints a tally of counts" do
+ @tally.should_receive(:format).and_return("1 example, 0 failures")
+ @formatter.finish
+ @out.should =~ /^1 example, 0 failures$/
+ end
+
+ it "prints errors, backtraces, elapsed time, and tallies" do
+ exc = ExceptionState.new @state, nil, MSpecExampleError.new("broken")
+ exc.stub(:backtrace).and_return("path/to/some/file.rb:35:in method")
+ @formatter.exception exc
+ @timer.should_receive(:format).and_return("Finished in 2.0 seconds")
+ @tally.should_receive(:format).and_return("1 example, 1 failure")
+ @formatter.after @state
+ @formatter.finish
+ @out.should ==
+%[E
+
+1)
+Class#method runs ERROR
+MSpecExampleError: broken
+path/to/some/file.rb:35:in method
+
+Finished in 2.0 seconds
+
+1 example, 1 failure
+]
+ end
+end
diff --git a/spec/mspec/spec/runner/formatters/file_spec.rb b/spec/mspec/spec/runner/formatters/file_spec.rb
new file mode 100644
index 0000000000..946683ad58
--- /dev/null
+++ b/spec/mspec/spec/runner/formatters/file_spec.rb
@@ -0,0 +1,84 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+require 'mspec/runner/formatters/file'
+require 'mspec/runner/mspec'
+require 'mspec/runner/example'
+
+describe FileFormatter, "#register" do
+ before :each do
+ @formatter = FileFormatter.new
+ MSpec.stub(:register)
+ MSpec.stub(:unregister)
+ end
+
+ it "registers self with MSpec for :load, :unload actions" do
+ MSpec.should_receive(:register).with(:load, @formatter)
+ MSpec.should_receive(:register).with(:unload, @formatter)
+ @formatter.register
+ end
+
+ it "unregisters self with MSpec for :before, :after actions" do
+ MSpec.should_receive(:unregister).with(:before, @formatter)
+ MSpec.should_receive(:unregister).with(:after, @formatter)
+ @formatter.register
+ end
+end
+
+describe FileFormatter, "#load" do
+ before :each do
+ @state = ExampleState.new ContextState.new("describe"), "it"
+ @formatter = FileFormatter.new
+ @formatter.exception ExceptionState.new(nil, nil, SpecExpectationNotMetError.new("Failed!"))
+ end
+
+ it "resets the #failure? flag to false" do
+ @formatter.failure?.should be_true
+ @formatter.load @state
+ @formatter.failure?.should be_false
+ end
+
+ it "resets the #exception? flag to false" do
+ @formatter.exception?.should be_true
+ @formatter.load @state
+ @formatter.exception?.should be_false
+ end
+end
+
+describe FileFormatter, "#unload" do
+ before :each do
+ $stdout = @out = IOStub.new
+ @formatter = FileFormatter.new
+ @state = ExampleState.new ContextState.new("describe"), "it"
+ end
+
+ after :each do
+ $stdout = STDOUT
+ end
+
+ it "prints a '.' if there was no exception raised" do
+ @formatter.unload(@state)
+ @out.should == "."
+ end
+
+ it "prints an 'F' if there was an expectation failure" do
+ exc = SpecExpectationNotMetError.new "failed"
+ @formatter.exception ExceptionState.new(@state, nil, exc)
+ @formatter.unload(@state)
+ @out.should == "F"
+ end
+
+ it "prints an 'E' if there was an exception other than expectation failure" do
+ exc = MSpecExampleError.new("boom!")
+ @formatter.exception ExceptionState.new(@state, nil, exc)
+ @formatter.unload(@state)
+ @out.should == "E"
+ end
+
+ it "prints an 'E' if there are mixed exceptions and exepctation failures" do
+ exc = SpecExpectationNotMetError.new "failed"
+ @formatter.exception ExceptionState.new(@state, nil, exc)
+ exc = MSpecExampleError.new("boom!")
+ @formatter.exception ExceptionState.new(@state, nil, exc)
+ @formatter.unload(@state)
+ @out.should == "E"
+ end
+end
diff --git a/spec/mspec/spec/runner/formatters/html_spec.rb b/spec/mspec/spec/runner/formatters/html_spec.rb
new file mode 100644
index 0000000000..d2aff1b2a7
--- /dev/null
+++ b/spec/mspec/spec/runner/formatters/html_spec.rb
@@ -0,0 +1,217 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+require 'mspec/utils/ruby_name'
+require 'mspec/guards/guard'
+require 'mspec/runner/formatters/html'
+require 'mspec/runner/mspec'
+require 'mspec/runner/example'
+require 'mspec/utils/script'
+
+describe HtmlFormatter do
+ before :each do
+ @formatter = HtmlFormatter.new
+ end
+
+ it "responds to #register by registering itself with MSpec for appropriate actions" do
+ MSpec.stub(:register)
+ MSpec.should_receive(:register).with(:start, @formatter)
+ MSpec.should_receive(:register).with(:enter, @formatter)
+ MSpec.should_receive(:register).with(:leave, @formatter)
+ @formatter.register
+ end
+end
+
+describe HtmlFormatter, "#start" do
+ before :each do
+ $stdout = @out = IOStub.new
+ @formatter = HtmlFormatter.new
+ end
+
+ after :each do
+ $stdout = STDOUT
+ end
+
+ it "prints the HTML head" do
+ @formatter.start
+ ruby_name = RUBY_NAME
+ ruby_name.should =~ /^#{ruby_name}/
+ @out.should ==
+%[<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+ "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+<title>Spec Output For #{ruby_name} (#{RUBY_VERSION})</title>
+<style type="text/css">
+ul {
+ list-style: none;
+}
+.fail {
+ color: red;
+}
+.pass {
+ color: green;
+}
+#details :target {
+ background-color: #ffffe0;
+}
+</style>
+</head>
+<body>
+]
+ end
+end
+
+describe HtmlFormatter, "#enter" do
+ before :each do
+ $stdout = @out = IOStub.new
+ @formatter = HtmlFormatter.new
+ end
+
+ after :each do
+ $stdout = STDOUT
+ end
+
+ it "prints the #describe string" do
+ @formatter.enter "describe"
+ @out.should == "<div><p>describe</p>\n<ul>\n"
+ end
+end
+
+describe HtmlFormatter, "#leave" do
+ before :each do
+ $stdout = @out = IOStub.new
+ @formatter = HtmlFormatter.new
+ end
+
+ after :each do
+ $stdout = STDOUT
+ end
+
+ it "prints the closing tags for the #describe string" do
+ @formatter.leave
+ @out.should == "</ul>\n</div>\n"
+ end
+end
+
+describe HtmlFormatter, "#exception" do
+ before :each do
+ $stdout = @out = IOStub.new
+ @formatter = HtmlFormatter.new
+ @formatter.register
+ @state = ExampleState.new ContextState.new("describe"), "it"
+ end
+
+ after :each do
+ $stdout = STDOUT
+ end
+
+ it "prints the #it string once for each exception raised" do
+ exc = ExceptionState.new @state, nil, SpecExpectationNotMetError.new("disappointing")
+ @formatter.exception exc
+ exc = ExceptionState.new @state, nil, MSpecExampleError.new("painful")
+ @formatter.exception exc
+ @out.should ==
+%[<li class="fail">- it (<a href="#details-1">FAILED - 1</a>)</li>
+<li class="fail">- it (<a href="#details-2">ERROR - 2</a>)</li>
+]
+ end
+end
+
+describe HtmlFormatter, "#after" do
+ before :each do
+ $stdout = @out = IOStub.new
+ @formatter = HtmlFormatter.new
+ @formatter.register
+ @state = ExampleState.new ContextState.new("describe"), "it"
+ end
+
+ after :each do
+ $stdout = STDOUT
+ end
+
+ it "prints the #it once when there are no exceptions raised" do
+ @formatter.after @state
+ @out.should == %[<li class="pass">- it</li>\n]
+ end
+
+ it "does not print any output if an exception is raised" do
+ exc = ExceptionState.new @state, nil, SpecExpectationNotMetError.new("disappointing")
+ @formatter.exception exc
+ out = @out.dup
+ @formatter.after @state
+ @out.should == out
+ end
+end
+
+describe HtmlFormatter, "#finish" do
+ before :each do
+ @tally = double("tally").as_null_object
+ TallyAction.stub(:new).and_return(@tally)
+ @timer = double("timer").as_null_object
+ TimerAction.stub(:new).and_return(@timer)
+
+ $stdout = @out = IOStub.new
+ context = ContextState.new "describe"
+ @state = ExampleState.new(context, "it")
+ MSpec.stub(:register)
+ @formatter = HtmlFormatter.new
+ @formatter.register
+ @exception = MSpecExampleError.new("broken")
+ @exception.stub(:backtrace).and_return(["file.rb:1", "file.rb:2"])
+ end
+
+ after :each do
+ $stdout = STDOUT
+ end
+
+ it "prints a failure message for an exception" do
+ exc = ExceptionState.new @state, nil, @exception
+ @formatter.exception exc
+ @formatter.finish
+ @out.should include "<p>describe it ERROR</p>"
+ end
+
+ it "prints a backtrace for an exception" do
+ exc = ExceptionState.new @state, nil, @exception
+ exc.stub(:backtrace).and_return("path/to/some/file.rb:35:in method")
+ @formatter.exception exc
+ @formatter.finish
+ @out.should =~ %r[<pre>.*path/to/some/file.rb:35:in method.*</pre>]m
+ end
+
+ it "prints a summary of elapsed time" do
+ @timer.should_receive(:format).and_return("Finished in 2.0 seconds")
+ @formatter.finish
+ @out.should include "<p>Finished in 2.0 seconds</p>\n"
+ end
+
+ it "prints a tally of counts" do
+ @tally.should_receive(:format).and_return("1 example, 0 failures")
+ @formatter.finish
+ @out.should include '<p class="pass">1 example, 0 failures</p>'
+ end
+
+ it "prints errors, backtraces, elapsed time, and tallies" do
+ exc = ExceptionState.new @state, nil, @exception
+ exc.stub(:backtrace).and_return("path/to/some/file.rb:35:in method")
+ @formatter.exception exc
+
+ @timer.should_receive(:format).and_return("Finished in 2.0 seconds")
+ @tally.should_receive(:format).and_return("1 example, 1 failures")
+ @formatter.finish
+ @out.should ==
+%[<li class=\"fail\">- it (<a href=\"#details-1\">ERROR - 1</a>)</li>
+<hr>
+<ol id="details">
+<li id="details-1"><p>describe it ERROR</p>
+<p>MSpecExampleError: broken</p>
+<pre>
+path/to/some/file.rb:35:in method</pre>
+</li>
+</ol>
+<p>Finished in 2.0 seconds</p>
+<p class="fail">1 example, 1 failures</p>
+</body>
+</html>
+]
+ end
+end
diff --git a/spec/mspec/spec/runner/formatters/junit_spec.rb b/spec/mspec/spec/runner/formatters/junit_spec.rb
new file mode 100644
index 0000000000..66e7d70e92
--- /dev/null
+++ b/spec/mspec/spec/runner/formatters/junit_spec.rb
@@ -0,0 +1,147 @@
+# -*- coding: utf-8 -*-
+require File.dirname(__FILE__) + '/../../spec_helper'
+require 'mspec/runner/formatters/junit'
+require 'mspec/runner/example'
+
+describe JUnitFormatter, "#initialize" do
+ it "permits zero arguments" do
+ lambda { JUnitFormatter.new }.should_not raise_error
+ end
+
+ it "accepts one argument" do
+ lambda { JUnitFormatter.new nil }.should_not raise_error
+ end
+end
+
+describe JUnitFormatter, "#print" do
+ before :each do
+ $stdout = IOStub.new
+ @out = IOStub.new
+ File.stub(:open).and_return(@out)
+ @formatter = JUnitFormatter.new "some/file"
+ end
+
+ after :each do
+ $stdout = STDOUT
+ end
+
+ it "writes to $stdout if #switch has not been called" do
+ @formatter.print "begonias"
+ $stdout.should == "begonias"
+ @out.should == ""
+ end
+
+ it "writes to the file passed to #initialize once #switch has been called" do
+ @formatter.switch
+ @formatter.print "begonias"
+ $stdout.should == ""
+ @out.should == "begonias"
+ end
+
+ it "writes to $stdout once #switch is called if no file was passed to #initialize" do
+ formatter = JUnitFormatter.new
+ formatter.switch
+ formatter.print "begonias"
+ $stdout.should == "begonias"
+ @out.should == ""
+ end
+end
+
+describe JUnitFormatter, "#finish" do
+ before :each do
+ @tally = double("tally").as_null_object
+ @counter = double("counter").as_null_object
+ @tally.stub(:counter).and_return(@counter)
+ TallyAction.stub(:new).and_return(@tally)
+
+ @timer = double("timer").as_null_object
+ TimerAction.stub(:new).and_return(@timer)
+
+ $stdout = IOStub.new
+ context = ContextState.new "describe"
+ @state = ExampleState.new(context, "it")
+
+ @formatter = JUnitFormatter.new
+ @formatter.stub(:backtrace).and_return("")
+ MSpec.stub(:register)
+ @formatter.register
+
+ exc = ExceptionState.new @state, nil, MSpecExampleError.new("broken")
+ exc.stub(:backtrace).and_return("path/to/some/file.rb:35:in method")
+ @formatter.exception exc
+ @formatter.after @state
+ end
+
+ after :each do
+ $stdout = STDOUT
+ end
+
+ it "calls #switch" do
+ @formatter.should_receive(:switch)
+ @formatter.finish
+ end
+
+ it "outputs a failure message and backtrace" do
+ @formatter.finish
+ $stdout.should include 'message="error in describe it" type="error"'
+ $stdout.should include "MSpecExampleError: broken\n"
+ $stdout.should include "path/to/some/file.rb:35:in method"
+ end
+
+ it "encodes message and backtrace in latin1 for jenkins" do
+ exc = ExceptionState.new @state, nil, MSpecExampleError.new("broken…")
+ exc.stub(:backtrace).and_return("path/to/some/file.rb:35:in methød")
+ @formatter.exception exc
+ @formatter.finish
+ $stdout.should =~ /MSpecExampleError: broken((\.\.\.)|\?)\n/
+ $stdout.should =~ /path\/to\/some\/file\.rb:35:in meth(\?|o)d/
+ end
+
+ it "outputs an elapsed time" do
+ @timer.should_receive(:elapsed).and_return(4.2)
+ @formatter.finish
+ $stdout.should include 'time="4.2"'
+ end
+
+ it "outputs overall elapsed time" do
+ @timer.should_receive(:elapsed).and_return(4.2)
+ @formatter.finish
+ $stdout.should include 'timeCount="4.2"'
+ end
+
+ it "outputs the number of examples as test count" do
+ @counter.should_receive(:examples).and_return(9)
+ @formatter.finish
+ $stdout.should include 'tests="9"'
+ end
+
+ it "outputs overall number of examples as test count" do
+ @counter.should_receive(:examples).and_return(9)
+ @formatter.finish
+ $stdout.should include 'testCount="9"'
+ end
+
+ it "outputs a failure count" do
+ @counter.should_receive(:failures).and_return(2)
+ @formatter.finish
+ $stdout.should include 'failureCount="2"'
+ end
+
+ it "outputs overall failure count" do
+ @counter.should_receive(:failures).and_return(2)
+ @formatter.finish
+ $stdout.should include 'failures="2"'
+ end
+
+ it "outputs an error count" do
+ @counter.should_receive(:errors).and_return(1)
+ @formatter.finish
+ $stdout.should include 'errors="1"'
+ end
+
+ it "outputs overall error count" do
+ @counter.should_receive(:errors).and_return(1)
+ @formatter.finish
+ $stdout.should include 'errorCount="1"'
+ end
+end
diff --git a/spec/mspec/spec/runner/formatters/method_spec.rb b/spec/mspec/spec/runner/formatters/method_spec.rb
new file mode 100644
index 0000000000..77204f74c5
--- /dev/null
+++ b/spec/mspec/spec/runner/formatters/method_spec.rb
@@ -0,0 +1,178 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+require 'mspec/runner/formatters/method'
+require 'mspec/runner/mspec'
+require 'mspec/runner/example'
+require 'mspec/utils/script'
+
+describe MethodFormatter, "#method_type" do
+ before :each do
+ @formatter = MethodFormatter.new
+ end
+
+ it "returns 'class' if the separator is '.' or '::'" do
+ @formatter.method_type('.').should == "class"
+ @formatter.method_type('::').should == "class"
+ end
+
+ it "returns 'instance' if the separator is '#'" do
+ @formatter.method_type('#').should == "instance"
+ end
+
+ it "returns 'unknown' for all other cases" do
+ @formatter.method_type(nil).should == "unknown"
+ end
+end
+
+describe MethodFormatter, "#before" do
+ before :each do
+ @formatter = MethodFormatter.new
+ MSpec.stub(:register)
+ @formatter.register
+ end
+
+ it "resets the tally counters to 0" do
+ @formatter.tally.counter.examples = 3
+ @formatter.tally.counter.expectations = 4
+ @formatter.tally.counter.failures = 2
+ @formatter.tally.counter.errors = 1
+
+ state = ExampleState.new ContextState.new("describe"), "it"
+ @formatter.before state
+ @formatter.tally.counter.examples.should == 0
+ @formatter.tally.counter.expectations.should == 0
+ @formatter.tally.counter.failures.should == 0
+ @formatter.tally.counter.errors.should == 0
+ end
+
+ it "records the class, method if available" do
+ state = ExampleState.new ContextState.new("Some#method"), "it"
+ @formatter.before state
+ key = "Some#method"
+ @formatter.methods.keys.should include(key)
+ h = @formatter.methods[key]
+ h[:class].should == "Some"
+ h[:method].should == "method"
+ h[:description].should == "Some#method it"
+ end
+
+ it "does not record class, method unless both are available" do
+ state = ExampleState.new ContextState.new("Some method"), "it"
+ @formatter.before state
+ key = "Some method"
+ @formatter.methods.keys.should include(key)
+ h = @formatter.methods[key]
+ h[:class].should == ""
+ h[:method].should == ""
+ h[:description].should == "Some method it"
+ end
+
+ it "sets the method type to unknown if class and method are not available" do
+ state = ExampleState.new ContextState.new("Some method"), "it"
+ @formatter.before state
+ key = "Some method"
+ h = @formatter.methods[key]
+ h[:type].should == "unknown"
+ end
+
+ it "sets the method type based on the class, method separator" do
+ [["C#m", "instance"], ["C.m", "class"], ["C::m", "class"]].each do |k, t|
+ state = ExampleState.new ContextState.new(k), "it"
+ @formatter.before state
+ h = @formatter.methods[k]
+ h[:type].should == t
+ end
+ end
+
+ it "clears the list of exceptions" do
+ state = ExampleState.new ContextState.new("describe"), "it"
+ @formatter.exceptions << "stuff"
+ @formatter.before state
+ @formatter.exceptions.should be_empty
+ end
+end
+
+describe MethodFormatter, "#after" do
+ before :each do
+ @formatter = MethodFormatter.new
+ MSpec.stub(:register)
+ @formatter.register
+ end
+
+ it "sets the tally counts" do
+ state = ExampleState.new ContextState.new("Some#method"), "it"
+ @formatter.before state
+
+ @formatter.tally.counter.examples = 3
+ @formatter.tally.counter.expectations = 4
+ @formatter.tally.counter.failures = 2
+ @formatter.tally.counter.errors = 1
+
+ @formatter.after state
+ h = @formatter.methods["Some#method"]
+ h[:examples].should == 3
+ h[:expectations].should == 4
+ h[:failures].should == 2
+ h[:errors].should == 1
+ end
+
+ it "renders the list of exceptions" do
+ state = ExampleState.new ContextState.new("Some#method"), "it"
+ @formatter.before state
+
+ exc = SpecExpectationNotMetError.new "failed"
+ @formatter.exception ExceptionState.new(state, nil, exc)
+ @formatter.exception ExceptionState.new(state, nil, exc)
+
+ @formatter.after state
+ h = @formatter.methods["Some#method"]
+ h[:exceptions].should == [
+ %[failed\n\n],
+ %[failed\n\n]
+ ]
+ end
+end
+
+describe MethodFormatter, "#after" do
+ before :each do
+ $stdout = IOStub.new
+ context = ContextState.new "Class#method"
+ @state = ExampleState.new(context, "runs")
+ @formatter = MethodFormatter.new
+ MSpec.stub(:register)
+ @formatter.register
+ end
+
+ after :each do
+ $stdout = STDOUT
+ end
+
+ it "prints a summary of the results of an example in YAML format" do
+ @formatter.before @state
+ @formatter.tally.counter.examples = 3
+ @formatter.tally.counter.expectations = 4
+ @formatter.tally.counter.failures = 2
+ @formatter.tally.counter.errors = 1
+
+ exc = SpecExpectationNotMetError.new "failed"
+ @formatter.exception ExceptionState.new(@state, nil, exc)
+ @formatter.exception ExceptionState.new(@state, nil, exc)
+
+ @formatter.after @state
+ @formatter.finish
+ $stdout.should ==
+%[---
+"Class#method":
+ class: "Class"
+ method: "method"
+ type: instance
+ description: "Class#method runs"
+ examples: 3
+ expectations: 4
+ failures: 2
+ errors: 1
+ exceptions:
+ - "failed\\n\\n"
+ - "failed\\n\\n"
+]
+ end
+end
diff --git a/spec/mspec/spec/runner/formatters/multi_spec.rb b/spec/mspec/spec/runner/formatters/multi_spec.rb
new file mode 100644
index 0000000000..afcc7e9cea
--- /dev/null
+++ b/spec/mspec/spec/runner/formatters/multi_spec.rb
@@ -0,0 +1,68 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+require 'mspec/runner/formatters/multi'
+require 'mspec/runner/example'
+
+describe MultiFormatter, "#aggregate_results" do
+ before :each do
+ @stdout, $stdout = $stdout, IOStub.new
+
+ @file = double("file").as_null_object
+
+ File.stub(:delete)
+ YAML.stub(:load)
+
+ @hash = { "files"=>1, "examples"=>1, "expectations"=>2, "failures"=>0, "errors"=>0 }
+ File.stub(:open).and_yield(@file).and_return(@hash)
+
+ @formatter = MultiFormatter.new
+ @formatter.timer.stub(:format).and_return("Finished in 42 seconds")
+ end
+
+ after :each do
+ $stdout = @stdout
+ end
+
+ it "outputs a summary without errors" do
+ @formatter.aggregate_results(["a", "b"])
+ @formatter.finish
+ $stdout.should ==
+%[
+
+Finished in 42 seconds
+
+2 files, 2 examples, 4 expectations, 0 failures, 0 errors, 0 tagged
+]
+ end
+
+ it "outputs a summary with errors" do
+ @hash["exceptions"] = [
+ "Some#method works real good FAILED\nExpected real good\n to equal fail\n\nfoo.rb:1\nfoo.rb:2",
+ "Some#method never fails ERROR\nExpected 5\n to equal 3\n\nfoo.rb:1\nfoo.rb:2"
+ ]
+ @formatter.aggregate_results(["a"])
+ @formatter.finish
+ $stdout.should ==
+%[
+
+1)
+Some#method works real good FAILED
+Expected real good
+ to equal fail
+
+foo.rb:1
+foo.rb:2
+
+2)
+Some#method never fails ERROR
+Expected 5
+ to equal 3
+
+foo.rb:1
+foo.rb:2
+
+Finished in 42 seconds
+
+1 file, 1 example, 2 expectations, 0 failures, 0 errors, 0 tagged
+]
+ end
+end
diff --git a/spec/mspec/spec/runner/formatters/specdoc_spec.rb b/spec/mspec/spec/runner/formatters/specdoc_spec.rb
new file mode 100644
index 0000000000..edb439fc11
--- /dev/null
+++ b/spec/mspec/spec/runner/formatters/specdoc_spec.rb
@@ -0,0 +1,106 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+require 'mspec/runner/formatters/specdoc'
+require 'mspec/runner/example'
+
+describe SpecdocFormatter do
+ before :each do
+ @formatter = SpecdocFormatter.new
+ end
+
+ it "responds to #register by registering itself with MSpec for appropriate actions" do
+ MSpec.stub(:register)
+ MSpec.should_receive(:register).with(:enter, @formatter)
+ @formatter.register
+ end
+end
+
+describe SpecdocFormatter, "#enter" do
+ before :each do
+ $stdout = @out = IOStub.new
+ @formatter = SpecdocFormatter.new
+ end
+
+ after :each do
+ $stdout = STDOUT
+ end
+
+ it "prints the #describe string" do
+ @formatter.enter("describe")
+ @out.should == "\ndescribe\n"
+ end
+end
+
+describe SpecdocFormatter, "#before" do
+ before :each do
+ $stdout = @out = IOStub.new
+ @formatter = SpecdocFormatter.new
+ @state = ExampleState.new ContextState.new("describe"), "it"
+ end
+
+ after :each do
+ $stdout = STDOUT
+ end
+
+ it "prints the #it string" do
+ @formatter.before @state
+ @out.should == "- it"
+ end
+
+ it "resets the #exception? flag" do
+ exc = ExceptionState.new @state, nil, SpecExpectationNotMetError.new("disappointing")
+ @formatter.exception exc
+ @formatter.exception?.should be_true
+ @formatter.before @state
+ @formatter.exception?.should be_false
+ end
+end
+
+describe SpecdocFormatter, "#exception" do
+ before :each do
+ $stdout = @out = IOStub.new
+ @formatter = SpecdocFormatter.new
+ context = ContextState.new "describe"
+ @state = ExampleState.new context, "it"
+ end
+
+ after :each do
+ $stdout = STDOUT
+ end
+
+ it "prints 'ERROR' if an exception is not an SpecExpectationNotMetError" do
+ exc = ExceptionState.new @state, nil, MSpecExampleError.new("painful")
+ @formatter.exception exc
+ @out.should == " (ERROR - 1)"
+ end
+
+ it "prints 'FAILED' if an exception is an SpecExpectationNotMetError" do
+ exc = ExceptionState.new @state, nil, SpecExpectationNotMetError.new("disappointing")
+ @formatter.exception exc
+ @out.should == " (FAILED - 1)"
+ end
+
+ it "prints the #it string if an exception has already been raised" do
+ exc = ExceptionState.new @state, nil, SpecExpectationNotMetError.new("disappointing")
+ @formatter.exception exc
+ exc = ExceptionState.new @state, nil, MSpecExampleError.new("painful")
+ @formatter.exception exc
+ @out.should == " (FAILED - 1)\n- it (ERROR - 2)"
+ end
+end
+
+describe SpecdocFormatter, "#after" do
+ before :each do
+ $stdout = @out = IOStub.new
+ @formatter = SpecdocFormatter.new
+ @state = ExampleState.new "describe", "it"
+ end
+
+ after :each do
+ $stdout = STDOUT
+ end
+
+ it "prints a newline character" do
+ @formatter.after @state
+ @out.should == "\n"
+ end
+end
diff --git a/spec/mspec/spec/runner/formatters/spinner_spec.rb b/spec/mspec/spec/runner/formatters/spinner_spec.rb
new file mode 100644
index 0000000000..a122620e39
--- /dev/null
+++ b/spec/mspec/spec/runner/formatters/spinner_spec.rb
@@ -0,0 +1,83 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+require 'mspec/runner/formatters/spinner'
+require 'mspec/runner/mspec'
+require 'mspec/runner/example'
+
+describe SpinnerFormatter, "#initialize" do
+ it "permits zero arguments" do
+ SpinnerFormatter.new
+ end
+
+ it "accepts one argument" do
+ SpinnerFormatter.new nil
+ end
+end
+
+describe SpinnerFormatter, "#register" do
+ before :each do
+ @formatter = SpinnerFormatter.new
+ MSpec.stub(:register)
+ end
+
+ it "registers self with MSpec for appropriate actions" do
+ MSpec.should_receive(:register).with(:start, @formatter)
+ MSpec.should_receive(:register).with(:unload, @formatter)
+ MSpec.should_receive(:register).with(:after, @formatter)
+ MSpec.should_receive(:register).with(:finish, @formatter)
+ @formatter.register
+ end
+
+ it "creates TimerAction and TallyAction" do
+ timer = double("timer")
+ tally = double("tally")
+ timer.should_receive(:register)
+ tally.should_receive(:register)
+ tally.should_receive(:counter)
+ TimerAction.should_receive(:new).and_return(timer)
+ TallyAction.should_receive(:new).and_return(tally)
+ @formatter.register
+ end
+end
+
+describe SpinnerFormatter, "#print" do
+ after :each do
+ $stdout = STDOUT
+ end
+
+ it "ignores the argument to #initialize and writes to $stdout" do
+ $stdout = IOStub.new
+ formatter = SpinnerFormatter.new "some/file"
+ formatter.print "begonias"
+ $stdout.should == "begonias"
+ end
+end
+
+describe SpinnerFormatter, "#after" do
+ before :each do
+ $stdout = IOStub.new
+ MSpec.store(:files, ["a", "b", "c", "d"])
+ @formatter = SpinnerFormatter.new
+ @formatter.register
+ @state = ExampleState.new("describe", "it")
+ end
+
+ after :each do
+ $stdout = STDOUT
+ end
+
+ it "updates the spinner" do
+ @formatter.start
+ @formatter.after @state
+ @formatter.unload
+
+ if ENV["TERM"] != "dumb"
+ green = "\e[0;32m"
+ reset = "\e[0m"
+ end
+
+ output = "\r[/ | 0% | 00:00:00] #{green} 0F #{green} 0E#{reset} " \
+ "\r[- | 0% | 00:00:00] #{green} 0F #{green} 0E#{reset} " \
+ "\r[\\ | ========== 25% | 00:00:00] #{green} 0F #{green} 0E#{reset} "
+ $stdout.should == output
+ end
+end
diff --git a/spec/mspec/spec/runner/formatters/summary_spec.rb b/spec/mspec/spec/runner/formatters/summary_spec.rb
new file mode 100644
index 0000000000..16a156b695
--- /dev/null
+++ b/spec/mspec/spec/runner/formatters/summary_spec.rb
@@ -0,0 +1,26 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+require 'mspec/runner/formatters/summary'
+require 'mspec/runner/example'
+
+describe SummaryFormatter, "#after" do
+ before :each do
+ $stdout = @out = IOStub.new
+ @formatter = SummaryFormatter.new
+ @formatter.register
+ context = ContextState.new "describe"
+ @state = ExampleState.new(context, "it")
+ end
+
+ after :each do
+ $stdout = STDOUT
+ end
+
+ it "does not print anything" do
+ exc = ExceptionState.new @state, nil, SpecExpectationNotMetError.new("disappointing")
+ @formatter.exception exc
+ exc = ExceptionState.new @state, nil, MSpecExampleError.new("painful")
+ @formatter.exception exc
+ @formatter.after(@state)
+ @out.should == ""
+ end
+end
diff --git a/spec/mspec/spec/runner/formatters/unit_spec.rb b/spec/mspec/spec/runner/formatters/unit_spec.rb
new file mode 100644
index 0000000000..c8ba406f51
--- /dev/null
+++ b/spec/mspec/spec/runner/formatters/unit_spec.rb
@@ -0,0 +1,74 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+require 'mspec/runner/formatters/unit'
+require 'mspec/runner/example'
+require 'mspec/utils/script'
+
+describe UnitdiffFormatter, "#finish" do
+ before :each do
+ @tally = double("tally").as_null_object
+ TallyAction.stub(:new).and_return(@tally)
+ @timer = double("timer").as_null_object
+ TimerAction.stub(:new).and_return(@timer)
+
+ $stdout = @out = IOStub.new
+ context = ContextState.new "describe"
+ @state = ExampleState.new(context, "it")
+ MSpec.stub(:register)
+ @formatter = UnitdiffFormatter.new
+ @formatter.register
+ end
+
+ after :each do
+ $stdout = STDOUT
+ end
+
+ it "prints a failure message for an exception" do
+ exc = ExceptionState.new @state, nil, MSpecExampleError.new("broken")
+ @formatter.exception exc
+ @formatter.after @state
+ @formatter.finish
+ @out.should =~ /^1\)\ndescribe it ERROR$/
+ end
+
+ it "prints a backtrace for an exception" do
+ exc = ExceptionState.new @state, nil, Exception.new("broken")
+ exc.stub(:backtrace).and_return("path/to/some/file.rb:35:in method")
+ @formatter.exception exc
+ @formatter.finish
+ @out.should =~ %r[path/to/some/file.rb:35:in method$]
+ end
+
+ it "prints a summary of elapsed time" do
+ @timer.should_receive(:format).and_return("Finished in 2.0 seconds")
+ @formatter.finish
+ @out.should =~ /^Finished in 2.0 seconds$/
+ end
+
+ it "prints a tally of counts" do
+ @tally.should_receive(:format).and_return("1 example, 0 failures")
+ @formatter.finish
+ @out.should =~ /^1 example, 0 failures$/
+ end
+
+ it "prints errors, backtraces, elapsed time, and tallies" do
+ exc = ExceptionState.new @state, nil, Exception.new("broken")
+ exc.stub(:backtrace).and_return("path/to/some/file.rb:35:in method")
+ @formatter.exception exc
+ @formatter.after @state
+ @timer.should_receive(:format).and_return("Finished in 2.0 seconds")
+ @tally.should_receive(:format).and_return("1 example, 0 failures")
+ @formatter.finish
+ @out.should ==
+%[E
+
+Finished in 2.0 seconds
+
+1)
+describe it ERROR
+Exception: broken:
+path/to/some/file.rb:35:in method
+
+1 example, 0 failures
+]
+ end
+end
diff --git a/spec/mspec/spec/runner/formatters/yaml_spec.rb b/spec/mspec/spec/runner/formatters/yaml_spec.rb
new file mode 100644
index 0000000000..eb4d99f74c
--- /dev/null
+++ b/spec/mspec/spec/runner/formatters/yaml_spec.rb
@@ -0,0 +1,125 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+require 'mspec/runner/formatters/yaml'
+require 'mspec/runner/example'
+
+describe YamlFormatter, "#initialize" do
+ it "permits zero arguments" do
+ YamlFormatter.new
+ end
+
+ it "accepts one argument" do
+ YamlFormatter.new nil
+ end
+end
+
+describe YamlFormatter, "#print" do
+ before :each do
+ $stdout = IOStub.new
+ @out = IOStub.new
+ File.stub(:open).and_return(@out)
+ @formatter = YamlFormatter.new "some/file"
+ end
+
+ after :each do
+ $stdout = STDOUT
+ end
+
+ it "writes to $stdout if #switch has not been called" do
+ @formatter.print "begonias"
+ $stdout.should == "begonias"
+ @out.should == ""
+ end
+
+ it "writes to the file passed to #initialize once #switch has been called" do
+ @formatter.switch
+ @formatter.print "begonias"
+ $stdout.should == ""
+ @out.should == "begonias"
+ end
+
+ it "writes to $stdout once #switch is called if no file was passed to #initialize" do
+ formatter = YamlFormatter.new
+ formatter.switch
+ formatter.print "begonias"
+ $stdout.should == "begonias"
+ @out.should == ""
+ end
+end
+
+describe YamlFormatter, "#finish" do
+ before :each do
+ @tally = double("tally").as_null_object
+ @counter = double("counter").as_null_object
+ @tally.stub(:counter).and_return(@counter)
+ TallyAction.stub(:new).and_return(@tally)
+
+ @timer = double("timer").as_null_object
+ TimerAction.stub(:new).and_return(@timer)
+
+ $stdout = IOStub.new
+ context = ContextState.new "describe"
+ @state = ExampleState.new(context, "it")
+
+ @formatter = YamlFormatter.new
+ @formatter.stub(:backtrace).and_return("")
+ MSpec.stub(:register)
+ @formatter.register
+
+ exc = ExceptionState.new @state, nil, MSpecExampleError.new("broken")
+ exc.stub(:backtrace).and_return("path/to/some/file.rb:35:in method")
+ @formatter.exception exc
+ @formatter.after @state
+ end
+
+ after :each do
+ $stdout = STDOUT
+ end
+
+ it "calls #switch" do
+ @formatter.should_receive(:switch)
+ @formatter.finish
+ end
+
+ it "outputs a failure message and backtrace" do
+ @formatter.finish
+ $stdout.should include "describe it ERROR"
+ $stdout.should include "MSpecExampleError: broken\\n"
+ $stdout.should include "path/to/some/file.rb:35:in method"
+ end
+
+ it "outputs an elapsed time" do
+ @timer.should_receive(:elapsed).and_return(4.2)
+ @formatter.finish
+ $stdout.should include "time: 4.2"
+ end
+
+ it "outputs a file count" do
+ @counter.should_receive(:files).and_return(3)
+ @formatter.finish
+ $stdout.should include "files: 3"
+ end
+
+ it "outputs an example count" do
+ @counter.should_receive(:examples).and_return(3)
+ @formatter.finish
+ $stdout.should include "examples: 3"
+ end
+
+ it "outputs an expectation count" do
+ @counter.should_receive(:expectations).and_return(9)
+ @formatter.finish
+ $stdout.should include "expectations: 9"
+ end
+
+ it "outputs a failure count" do
+ @counter.should_receive(:failures).and_return(2)
+ @formatter.finish
+ $stdout.should include "failures: 2"
+ end
+
+ it "outputs an error count" do
+ @counter.should_receive(:errors).and_return(1)
+ @formatter.finish
+ $stdout.should include "errors: 1"
+ end
+end