public
Created

Example of beginning to test the Io class for a Tic tac Toe game, for Phil

  • Download Gist
io_and_its_spec.rb
Ruby
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
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

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.