diff options
Diffstat (limited to 'spec/mspec/spec/runner/formatters')
-rw-r--r-- | spec/mspec/spec/runner/formatters/describe_spec.rb | 67 | ||||
-rw-r--r-- | spec/mspec/spec/runner/formatters/dotted_spec.rb | 285 | ||||
-rw-r--r-- | spec/mspec/spec/runner/formatters/file_spec.rb | 84 | ||||
-rw-r--r-- | spec/mspec/spec/runner/formatters/html_spec.rb | 217 | ||||
-rw-r--r-- | spec/mspec/spec/runner/formatters/junit_spec.rb | 147 | ||||
-rw-r--r-- | spec/mspec/spec/runner/formatters/method_spec.rb | 178 | ||||
-rw-r--r-- | spec/mspec/spec/runner/formatters/multi_spec.rb | 68 | ||||
-rw-r--r-- | spec/mspec/spec/runner/formatters/specdoc_spec.rb | 106 | ||||
-rw-r--r-- | spec/mspec/spec/runner/formatters/spinner_spec.rb | 83 | ||||
-rw-r--r-- | spec/mspec/spec/runner/formatters/summary_spec.rb | 26 | ||||
-rw-r--r-- | spec/mspec/spec/runner/formatters/unit_spec.rb | 74 | ||||
-rw-r--r-- | spec/mspec/spec/runner/formatters/yaml_spec.rb | 125 |
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 |