-
-
Save mislav/112354 to your computer and use it in GitHub Desktop.
Ryan Bates community challenge solution
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
# COMMUNITY CHALLENGE | |
# | |
# How would you test this Quiz#problem method? Only two rules: | |
# | |
# 1. You must test the order the gets/puts happen. The tests should not | |
# still pass if "gets" happens before "puts", etc. | |
# | |
# 2. No changing the Quiz class implementation/structure. But you can | |
# use whatever framework you want for the tests. | |
# | |
# 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 "rubygems" | |
require "mocha" | |
# special StringIO with a separate read cursor that can | |
# be used to re-read the IO from beginning unobtrusively | |
class RereadableStringIO < StringIO | |
def initialize(*args) | |
super | |
@read_pos = pos | |
end | |
def rereading | |
old_pos = pos | |
begin | |
seek @read_pos | |
result = yield self | |
@read_pos = pos | |
return result | |
ensure | |
seek old_pos | |
end | |
end | |
def reread | |
rereading { read } | |
end | |
end | |
# mocks a STDIN; only supports `gets` | |
class FakeInput | |
def initialize | |
@responses = [] | |
end | |
def push(*args, &block) | |
val = args.empty?? block : args.first | |
@responses.push(val) | |
end | |
def gets | |
val = @responses.pop | |
val.respond_to?(:call) ? val.call : val | |
end | |
end | |
class QuizTest < Test::Unit::TestCase | |
def setup | |
@input = FakeInput.new | |
@output = RereadableStringIO.new | |
end | |
def test_correct | |
@input.push { | |
question = @output.reread | |
_, first, second = question.match(/^What is (\d+) \+ (\d+)\?\n$/).to_a | |
(first.to_i + second.to_i).to_s + $/ | |
} | |
quiz = Quiz.new(@input, @output) | |
quiz.problem | |
assert_equal "Correct!\n", @output.reread | |
end | |
def test_incorrect | |
@input.push("-1#{$/}") | |
quiz = Quiz.new(@input, @output) | |
quiz.problem | |
@output.rereading { |io| io.gets } | |
assert_equal "Incorrect!\n", @output.reread | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment