Created
December 10, 2012 00:16
-
-
Save cupakromer/4247624 to your computer and use it in GitHub Desktop.
Simple RSpec
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ruby | |
#encoding: UTF-8 | |
################################################################################ | |
################################################################################ | |
################################################################################ | |
# Overly simplistic implementation of how a RSpec test works # | |
################################################################################ | |
def describe(object_under_test, &block) | |
@obj_under_test = object_under_test | |
@test_group = block | |
end | |
def subject | |
if @obj_under_test.is_a? Class | |
@subject ||= @obj_under_test.new | |
else | |
@obj_under_test | |
end | |
end | |
def before(&block) @before_hooks << block end | |
def after(&block) @after_hooks << block end | |
def it(description = nil, &block) | |
@examples << Example.new(description, block) | |
end | |
Example = Struct.new(:description, :test) do | |
attr_accessor :result | |
def call | |
@result = if test | |
begin | |
test.call | |
:passed | |
rescue => e | |
@failure = e | |
:failed | |
end | |
else | |
:pending | |
end | |
end | |
end | |
# Setup some variables to keep track of hooks | |
@before_hooks = [] | |
@after_hooks = [] | |
@examples = [] | |
# Allow a very simply TestUnit style assert for ease of testing | |
def assert(truthy) | |
truthy or raise Error.new("Test failed.") | |
end | |
################################################################################ | |
################################################################################ | |
################################################################################ | |
# A simplistic view of how tests are run # | |
################################################################################ | |
def run | |
raise 'No object under test defined.' unless @obj_under_test | |
puts @obj_under_test | |
return unless @test_group | |
# Find out what tests need to be run | |
@test_group.call | |
# Run the tests | |
@examples.each_with_index do |example, index| | |
@subject = nil | |
puts "\n\nEXAMPLE #{index+1}:" | |
begin | |
@before_hooks.each(&:call) | |
example.call | |
puts "\n #{example.description} => #{example.result.upcase}\n" | |
rescue => e | |
puts "\n #{example.description} => failed\n" | |
ensure | |
@after_hooks.reverse_each(&:call) | |
end | |
end | |
end | |
################################################################################ | |
################################################################################ | |
################################################################################ | |
# Here's our sample RSpec example # | |
################################################################################ | |
class Thing | |
attr_reader :my_value | |
def initialize | |
@my_value = rand 5 | |
end | |
end | |
describe Thing do | |
before { puts "BEFORE_BLOCK:: First before block" } | |
after do | |
print "AFTER_BLOCK:: should be called last!" | |
print " Reset @tmp_value(#{@tmp_value.inspect}) => " | |
@tmp_value = nil | |
puts "@tmp_value(#{@tmp_value.inspect})" | |
end | |
it 'has access to subject' do | |
p subject | |
assert subject.my_value < 5 | |
end | |
it 'subject changes only between tests' do | |
p subject | |
assert subject.equal?(subject) | |
end | |
it "fails on error" do | |
raise Error.new 'Sad face' | |
end | |
it 'works!' do | |
assert @tmp_value == 'test' | |
end | |
before do | |
@tmp_value = 'test' | |
print "BEFORE_BLOCK:: Another before block" | |
puts " Set @tmp_value(#{@tmp_value.inspect})" | |
end | |
it 'is pending' | |
after { puts "AFTER_BLOCK:: should be called first!!" } | |
end | |
################################################################################ | |
################################################################################ | |
# Now we run the example | |
run |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Output of the tests | |
Thing | |
EXAMPLE 1: | |
BEFORE_BLOCK:: First before block | |
BEFORE_BLOCK:: Another before block Set @tmp_value("test") | |
#<Thing:0x007fcd110a26a8 @my_value=3> | |
has access to subject => PASSED | |
AFTER_BLOCK:: should be called first!! | |
AFTER_BLOCK:: should be called last! Reset @tmp_value("test") => @tmp_value(nil) | |
EXAMPLE 2: | |
BEFORE_BLOCK:: First before block | |
BEFORE_BLOCK:: Another before block Set @tmp_value("test") | |
#<Thing:0x007fcd110a2220 @my_value=4> | |
subject changes only between tests => PASSED | |
AFTER_BLOCK:: should be called first!! | |
AFTER_BLOCK:: should be called last! Reset @tmp_value("test") => @tmp_value(nil) | |
EXAMPLE 3: | |
BEFORE_BLOCK:: First before block | |
BEFORE_BLOCK:: Another before block Set @tmp_value("test") | |
fails on error => FAILED | |
AFTER_BLOCK:: should be called first!! | |
AFTER_BLOCK:: should be called last! Reset @tmp_value("test") => @tmp_value(nil) | |
EXAMPLE 4: | |
BEFORE_BLOCK:: First before block | |
BEFORE_BLOCK:: Another before block Set @tmp_value("test") | |
works! => PASSED | |
AFTER_BLOCK:: should be called first!! | |
AFTER_BLOCK:: should be called last! Reset @tmp_value("test") => @tmp_value(nil) | |
EXAMPLE 5: | |
BEFORE_BLOCK:: First before block | |
BEFORE_BLOCK:: Another before block Set @tmp_value("test") | |
is pending => PENDING | |
AFTER_BLOCK:: should be called first!! | |
AFTER_BLOCK:: should be called last! Reset @tmp_value("test") => @tmp_value(nil) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment