Skip to content

Instantly share code, notes, and snippets.

@chapados
Forked from ryanb/quiz.rb
Created May 15, 2009 20:23
Show Gist options
  • Save chapados/112420 to your computer and use it in GitHub Desktop.
Save chapados/112420 to your computer and use it in GitHub Desktop.
# COMMUNITY CHALLENGE
#
# How would you test this Quiz#problem method? Only two rules:
#
# 1. The tests should fail if any part of the application breaks.
# For example: If "gets" is moved before "puts" then the tests should
# fail since that breaks the application.
#
# 2. You cannot change the Quiz class. But you can use whatever framework
# and tools you want for the tests. (RSpec, Cucumber, etc.)
#
# Note: The first rule used to be "no mocking" but I changed it. If you
# can accomplish the first rule with mocks then go ahead. I'm looking
# for the simplest/cleanest solution whatever that may be.
#
class Quiz
def initialize(input = STDIN, output = STDOUT)
@input = input
@output = output
end
def problem
first = rand(10)
second = rand(10)
@output.puts "What is #{first} + #{second}?"
answer = @input.gets
if answer.to_i == first + second
@output.puts "Correct!"
else
@output.puts "Incorrect!"
end
end
end
require "test/unit"
require "stringio"
require "delegate"
class QuizIORecorder < DelegateClass(StringIO)
attr_accessor :io, :log
def initialize(log = [])
@io = StringIO.new
@log = log
super(@io)
end
def gets
s = @io.gets
@log << [:gets, s]
s
end
def puts(s)
r = @io.puts(s)
@log << [:puts, s]
r
end
end
class QuizTest < Test::Unit::TestCase
def setup
@seed = 42
srand(@seed)
@log = Array.new
@input = QuizIORecorder.new(@log)
@output = QuizIORecorder.new(@log)
@quiz = Quiz.new(@input, @output)
end
def correct_answer
srand(@seed)
first = rand(10)
second = rand(10)
srand(@seed)
first + second
end
def test_correct
@input << correct_answer.to_s
@input.rewind
@quiz.problem
assert_equal([:puts, :gets, :puts], @log.map { |e| e.first },
"Quiz procedure occurred in the wrong order: gets occurred before puts")
@output.rewind
assert_equal("Correct!\n", @output.readlines.last, "Quiz did not report a correct response")
end
def test_incorrect
@input << "-1"
@input.rewind
@quiz.problem
assert_equal([:puts, :gets, :puts], @log.map { |e| e.first },
"Quiz procedure occurred in the wrong order: gets occurred before puts")
@output.rewind
assert_equal("Incorrect!\n", @output.readlines.last, "Quiz did not report an incorrect response")
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment