Skip to content

Instantly share code, notes, and snippets.

@JoshCheek
Created May 11, 2013 19:07
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JoshCheek/5561023 to your computer and use it in GitHub Desktop.
Save JoshCheek/5561023 to your computer and use it in GitHub Desktop.
Example of beginning to test the Io class for a Tic tac Toe game, for Phil
require 'stringio'
class Io
attr_accessor :instream, :outstream
def initialize(instream, outstream)
self.instream = instream
self.outstream = outstream
end
def get_opponent
get_input(
prompt: "Should your opponent be human or computer?",
validation: /\A(human|computer)\Z/
).to_sym
end
def get_board_size
get_input(
prompt: "What size should the board be?",
validation: /\A\d+\Z/
).to_i
end
def get_player_move(valid_moves)
get_input(
prompt: "Where would you like to move?",
validation: /\A[#{valid_moves.join('')}]\Z/
).to_i
end
def display_board(board)
outstream.puts board_as_string(board)
end
def print_winner(winner)
outstream.puts "The winner is #{winner}!"
end
private
def get_input(options)
prompt options[:prompt]
result = instream.gets.chomp
return result if result =~ options[:validation]
invalid_input result
get_input options
end
def board_as_string(board)
board.map { |e| e || ' ' }
.each_slice(3)
.map { |a, b, c| " #{a} | #{b} | #{c} \n" }
.join("---|---|---\n")
end
def invalid_input(input)
outstream.puts "You said #{input.inspect}, which is invalid"
end
def prompt(message)
outstream.print message, ' '
end
end
RSpec.configure { |config| config.fail_fast = true }
describe Io do
def output
@output_stream.string
end
def io(input='')
instream = StringIO.new input
@output_stream = StringIO.new
described_class.new instream, @output_stream
end
describe 'asking whether opponent is human or computer' do
it 'can be told human' do
io('human').get_opponent.should == :human
output.should include 'human or computer'
output.should_not include 'invalid'
end
it 'can be told computer' do
io('computer').get_opponent.should == :computer
output.should include 'human or computer'
output.should_not include 'invalid'
end
it 'reprompts for human or computer' do
io("nonsense\ncomputer").get_opponent.should == :computer
output.should include 'human or computer'
output.should include 'invalid'
end
end
describe 'asking for the board size' do
it 'accepts integers' do
io('1').get_board_size.should == 1
output.should include 'size'
end
it 'reprompts for the board size when given an invalid value' do
io("x\n1x\n2").get_board_size.should == 2
output.scan(/size/).size.should == 3
output.scan(/invalid/).size.should == 2
end
end
it 'displays the board' do
empty_board = Array.new(9) { nil }
io.display_board(empty_board)
output.should == " | | \n"\
"---|---|---\n"\
" | | \n"\
"---|---|---\n"\
" | | \n"
one_through_nine = [*1..9]
io.display_board(one_through_nine)
output.should == " 1 | 2 | 3 \n"\
"---|---|---\n"\
" 4 | 5 | 6 \n"\
"---|---|---\n"\
" 7 | 8 | 9 \n"
one_through_nine.should == [*1..9]
end
it 'prints a winner message' do
io.print_winner 'X'
output.should include 'X'
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment