Skip to content

Instantly share code, notes, and snippets.

@ryanb
Created May 15, 2009 22:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ryanb/112476 to your computer and use it in GitHub Desktop.
Save ryanb/112476 to your computer and use it in GitHub Desktop.
class MockIO
def initialize(receiver = nil)
@buffer = ""
@receiver = receiver || MockIO.new(self)
end
def gets
1000.times do |n|
sleep 0.01 if n > 800 # throttle if it seems to be taking a while
unless @buffer.empty?
content = @buffer
@buffer = ""
return content
end
end
raise "MockIO Timeout: No content was received for gets."
end
# TODO make this thread safe
def puts(str)
@receiver << "#{str}\n"
end
def <<(str)
@buffer << str
end
def start
@thread = Thread.new do
yield(@receiver)
end
end
end
# COMMUNITY CHALLENGE
#
# This solution uses MockIO which is a generic class for mocking gets/puts.
# It executes the "start" block in a separate thread which allows calls to "gets"
# to wait for input.
#
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 "mockio"
class QuizTest < Test::Unit::TestCase
def setup
@io = MockIO.new
@io.start { |io| Quiz.new(io, io).problem }
first, second = @io.gets.scan(/\d+/)
@total = first.to_i + second.to_i
end
def test_correct
@io.puts @total
assert_equal "Correct!", @io.gets.chomp
end
def test_incorrect
@io.puts @total+1
assert_equal "Incorrect!", @io.gets.chomp
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment