Skip to content

Instantly share code, notes, and snippets.

@botanicus
Created March 29, 2011 14:02
Show Gist options
  • Select an option

  • Save botanicus/892414 to your computer and use it in GitHub Desktop.

Select an option

Save botanicus/892414 to your computer and use it in GitHub Desktop.
Pending Examples via NotImplementedError in rSpec. Check http://blog.101ideas.cz/posts/pending-examples-via-not-implemented-error-in-rspec.html
--color
--format nested

About

This little hack change all NotImplementedError exceptions to be pending examples rather than failures.

HelloWorld
#from_london
should work
#from_alasca
should work (FAILED - 1)
#from_turkey
should work (PENDING: Jeez, I have to learn Turkish first!)
Pending:
HelloWorld#from_turkey should work
# Jeez, I have to learn Turkish first!
# ./spec/test_spec.rb:36
Failures:
1) HelloWorld#from_alasca should work
Failure/Error: raise Errno::ECONNREFUSED.new("Sorry, no network available here, here are only bears!")
Errno::ECONNREFUSED:
Connection refused - Sorry, no network available here, here are only bears!
# ./spec/test_spec.rb:11:in `from_alasca'
# ./spec/test_spec.rb:30:in `block (3 levels) in <top (required)>'
Finished in 0.00904 seconds
3 examples, 1 failure, 1 pending
# encoding: utf-8
# Now it gets a bit complicated, I know, but it can handle --backtrace now:
# because pending examples don't have backtrace, but in fact when we raise
# NotImplementedError, we want to know where it comes from. Nifty, right?
RSpec::Core::Example.send(:include, Module.new {
def self.included(base)
base.class_eval do
alias_method :__finish__, :finish
remove_method :finish
end
end
attr_reader :not_implemented_error
def from_not_implemented_error?
!! @not_implemented_error
end
def finish(reporter)
if @exception.is_a?(NotImplementedError)
@not_implemented_error = @exception
message = "#{@exception.message} (from #{@exception.backtrace[0]})"
self.metadata[:pending] = true
@pending_declared_in_example = message
@exception = nil
end
__finish__(reporter)
end
})
RSpec::Core::Formatters::BaseTextFormatter.send(:include, Module.new {
def self.included(base)
base.class_eval do
remove_method :dump_pending
remove_method :dump_backtrace
end
end
def dump_pending
unless pending_examples.empty?
output.puts
output.puts "Pending:"
pending_examples.each do |pending_example|
output.puts yellow(" #{pending_example.full_description}")
output.puts grey(" # #{pending_example.execution_result[:pending_message]}")
output.puts grey(" # #{format_caller(pending_example.location)}")
if pending_example.from_not_implemented_error? && RSpec.configuration.backtrace_clean_patterns.empty?
dump_backtrace(pending_example, pending_example.not_implemented_error.backtrace)
end
end
end
end
def dump_backtrace(example, backtrace = example.execution_result[:exception].backtrace)
format_backtrace(backtrace, example).each do |backtrace_info|
output.puts grey("#{long_padding}# #{backtrace_info}")
end
end
})
# encoding: utf-8
require "spec_helper"
class HelloWorld
def from_london
"Hello World from London!"
end
def from_alasca
raise Errno::ECONNREFUSED.new("Sorry, no network available here, here are only bears!")
end
def from_turkey
raise NotImplementedError.new("Jeez, I have to learn Turkish first!")
end
end
describe HelloWorld do
# This is supposed to work.
context "#from_london" do
it "should work" do
subject.from_london
end
end
# This is supposed to fail.
context "#from_alasca" do
it "should work" do
subject.from_alasca
end
end
# And this is supposed to be pending.
context "#from_turkey" do
it "should work" do
subject.from_turkey
end
end
end
@michaelklishin
Copy link
Copy Markdown

This "technique" is broken with rspec core 2.6.4. Any code that relies on #remove_method must raise red flags immediately.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment