tic_tac_toes 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,175 @@
1
+ require 'tic_tac_toes/board'
2
+ require 'tic_tac_toes/io_interface'
3
+ require 'tic_tac_toes/spec_helper'
4
+ require 'tic_tac_toes/strings'
5
+
6
+ describe TicTacToes::IOInterface do
7
+ let(:strings) { TicTacToes::Strings }
8
+ let(:io) { double("io", solicit_input: 0, display: true, display_red: true) }
9
+ let(:io_interface) { TicTacToes::IOInterface.new(io) }
10
+
11
+
12
+ describe '#make_move' do
13
+ it "displays a move solicitation" do
14
+ expect(io_interface).to receive(:move_solicitation)
15
+ io_interface.make_move("_board", "_players")
16
+ end
17
+
18
+ context 'when given not-integer-like input' do
19
+ let(:not_integer_like) { "string" }
20
+ let(:integer_like) { "100" }
21
+
22
+ it "displays a not an integer error" do
23
+ allow(io).to receive(:solicit_input).and_return(not_integer_like, integer_like)
24
+
25
+ expect(io_interface).to receive(:not_an_integer_error).once
26
+ io_interface.make_move("_board", "_players")
27
+ end
28
+
29
+ it "only returns a move (converted to integer) once it gets integer-like input" do
30
+ allow(io).to receive(:solicit_input).and_return(not_integer_like, integer_like)
31
+
32
+ expect(io_interface.make_move("_board", "_players")).to eq(100)
33
+ end
34
+ end
35
+ end
36
+
37
+
38
+ describe '#get_row_size' do
39
+ it "displays a row size solicitation" do
40
+ expect(io_interface).to receive(:row_size_solicitation)
41
+ io_interface.get_row_size
42
+ end
43
+
44
+ context 'when given not-integer-like input' do
45
+ let(:not_integer_like) { "string" }
46
+ let(:integer_like) { "100" }
47
+
48
+ it "displays a not an integer error" do
49
+ allow(io).to receive(:solicit_input).and_return(not_integer_like, integer_like)
50
+
51
+ expect(io_interface).to receive(:not_an_integer_error).once
52
+ io_interface.get_row_size
53
+ end
54
+
55
+ it "only returns a row size (converted to integer) once it gets integer-like input" do
56
+ allow(io).to receive(:solicit_input).and_return(not_integer_like, integer_like)
57
+
58
+ expect(io_interface.get_row_size).to eq(100)
59
+ end
60
+ end
61
+ end
62
+
63
+
64
+ describe '#get_token' do
65
+ let(:player) { double("player") }
66
+
67
+ it "displays a token solicitation with the name of the player whose token is to be set" do
68
+ expect(io_interface).to receive(:token_solicitation).with(player)
69
+ io_interface.get_token(player)
70
+ end
71
+
72
+ it "returns the user input" do
73
+ token = "X"
74
+ allow(io).to receive(:solicit_input) { token }
75
+
76
+ expect(io_interface.get_token(player)).to equal(token)
77
+ end
78
+ end
79
+
80
+
81
+ describe '#get_difficulty' do
82
+ let(:difficulty) { "HARD" }
83
+
84
+ it "displays a difficulty solicitation" do
85
+ allow(io).to receive(:solicit_input) { difficulty }
86
+
87
+ expect(io_interface).to receive(:difficulty_solicitation)
88
+ io_interface.get_difficulty
89
+ end
90
+
91
+ it "returns the user input (downcased and converted into a symbol)" do
92
+ allow(io).to receive(:solicit_input) { difficulty }
93
+
94
+ expect(io_interface.get_difficulty).to equal(:hard)
95
+ end
96
+ end
97
+
98
+
99
+ describe '#draw_board' do
100
+ it "displays a board string" do
101
+ board = TicTacToes::Board.new
102
+ board_string = strings.board(board)
103
+
104
+ expect(io).to receive(:display).with(board_string)
105
+ io_interface.draw_board(board)
106
+ end
107
+ end
108
+
109
+
110
+ describe '#invalid_row_size_error' do
111
+ it "displays a red invalid row size message" do
112
+ expect(io).to receive(:display_red).with(strings::INVALID_ROW_SIZE)
113
+ io_interface.invalid_row_size_error
114
+ end
115
+ end
116
+
117
+
118
+ describe '#invalid_token_error' do
119
+ it "displays a red invalid token message" do
120
+ expect(io).to receive(:display_red).with(strings::INVALID_TOKEN)
121
+ io_interface.invalid_token_error
122
+ end
123
+ end
124
+
125
+
126
+ describe '#invalid_difficulty_error' do
127
+ it "displays a red invalid difficulty message" do
128
+ expect(io).to receive(:display_red).with(strings::INVALID_DIFFICULTY)
129
+ io_interface.invalid_difficulty_error
130
+ end
131
+ end
132
+
133
+
134
+ describe '#invalid_move_error' do
135
+ it "displays a red invalid move message" do
136
+ expect(io).to receive(:display_red).with(strings::INVALID_MOVE)
137
+ io_interface.invalid_move_error
138
+ end
139
+ end
140
+
141
+
142
+ describe '#thinking_notification' do
143
+ it "displays a red thinking message" do
144
+ expect(io).to receive(:display_red).with(strings::THINKING)
145
+ io_interface.thinking_notification
146
+ end
147
+ end
148
+
149
+
150
+ describe '#game_over_notification' do
151
+ it "displays a game over message with the name of the winner" do
152
+ winner = :X
153
+ game_over_message = strings.game_over_notification(winner)
154
+
155
+ expect(io).to receive(:display).with(game_over_message)
156
+ io_interface.game_over_notification(winner)
157
+ end
158
+ end
159
+
160
+
161
+ describe '#red' do
162
+ it "calls its IO's red method with the passed message" do
163
+ expect(io).to receive(:red).with("message")
164
+ io_interface.red("message")
165
+ end
166
+ end
167
+
168
+
169
+ describe '#blue' do
170
+ it "calls its IO's blue method with the passed message" do
171
+ expect(io).to receive(:blue).with("message")
172
+ io_interface.blue("message")
173
+ end
174
+ end
175
+ end
@@ -0,0 +1,22 @@
1
+ require 'tic_tac_toes/medium_ai'
2
+ require 'tic_tac_toes/spec_helper'
3
+
4
+ describe TicTacToes::MediumAI do
5
+ let(:ai) { TicTacToes::MediumAI }
6
+ let(:x) { TicTacToes::Player.new("decider", "x", false, "interface") }
7
+ let(:o) { TicTacToes::Player.new(ai, "o", true, "interface") }
8
+ let(:players) { [x, o] }
9
+
10
+ describe '#make_move' do
11
+ it "makes a valid move (based on either EasyAI or HardAI)" do
12
+ structure = [ o, o, x,
13
+ nil, x, nil,
14
+ nil, x, nil]
15
+ board = generate_board(structure)
16
+ valid_moves = [3, 5, 6, 8]
17
+
18
+ move = ai.make_move(board, players)
19
+ expect(valid_moves).to include(move)
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,34 @@
1
+ require 'command_line/io'
2
+ require 'tic_tac_toes/io_interface'
3
+ require 'tic_tac_toes/medium_ai'
4
+ require 'tic_tac_toes/player_factory'
5
+ require 'tic_tac_toes/spec_helper'
6
+
7
+ describe TicTacToes::PlayerFactory do
8
+ let(:io) { CommandLine::IO }
9
+ let(:io_interface) { TicTacToes::IOInterface.new(io) }
10
+ let(:player_factory) { TicTacToes::PlayerFactory.new(io_interface) }
11
+
12
+
13
+ describe '#generate_human_player' do
14
+ it "returns a player with the correct token and decider" do
15
+ token = "X"
16
+
17
+ human_player = player_factory.generate_human_player(token)
18
+ expect(human_player.decider).to be_a TicTacToes::IOInterface
19
+ expect(human_player.token).to eq(token)
20
+ end
21
+ end
22
+
23
+
24
+ describe '#generate_computer_player' do
25
+ it "returns a player with the correct token and decider when given a valid difficulty" do
26
+ token = "O"
27
+ difficulty = :medium
28
+
29
+ computer_player = player_factory.generate_computer_player(token, difficulty)
30
+ expect(computer_player.decider).to eql(TicTacToes::MediumAI)
31
+ expect(computer_player.token).to eq(token)
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,34 @@
1
+ require 'tic_tac_toes/board'
2
+ require 'tic_tac_toes/io_interface'
3
+ require 'tic_tac_toes/player'
4
+ require 'tic_tac_toes/spec_helper'
5
+
6
+ describe TicTacToes::Player do
7
+ let(:board) { TicTacToes::Board.new(row_size: 3) }
8
+ let(:io_interface) { double("io_interface", invalid_move_error: true) }
9
+ let(:players) { double("players") }
10
+
11
+ describe '#make_move' do
12
+ let(:decider) { double("decider") }
13
+ let(:token) { "X" }
14
+ let(:needs_to_think) { false }
15
+
16
+ let(:player) { TicTacToes::Player.new(decider, token, needs_to_think, io_interface) }
17
+
18
+ it "only returns a move once it receives a valid move" do
19
+ invalid_space, valid_space = 9, 0
20
+ allow(decider).to receive(:make_move).and_return(invalid_space, valid_space)
21
+
22
+ player.make_move(board, players)
23
+ expect(board.space(valid_space)).to eq(player)
24
+ end
25
+
26
+ it "displays an invalid move error when given an invalid move" do
27
+ invalid_space, valid_space = 9, 0
28
+ allow(decider).to receive(:make_move).and_return(invalid_space, valid_space)
29
+
30
+ expect(io_interface).to receive(:invalid_move_error)
31
+ player.make_move(board, players)
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,159 @@
1
+ require 'tic_tac_toes/spec_helper'
2
+ require 'tic_tac_toes/rules'
3
+
4
+ describe TicTacToes::Rules do
5
+ let(:rules) { TicTacToes::Rules }
6
+ let(:x) { double("human player", token: "x") }
7
+ let(:o) { double("computer player", token: "o") }
8
+ let(:players) { [x, o] }
9
+
10
+ describe '#row_size_valid?' do
11
+ it "returns false if the row size is outside the range 2 to 10" do
12
+ invalid_row_size = 11
13
+
14
+ expect(rules.row_size_valid?(invalid_row_size)).to be false
15
+ end
16
+
17
+ it "returns true if the row size is in the range 2 to 10" do
18
+ valid_row_size = 10
19
+
20
+ expect(rules.row_size_valid?(valid_row_size)).to be true
21
+ end
22
+ end
23
+
24
+
25
+ describe '#token_valid?' do
26
+ it "returns false if the token is not a single character" do
27
+ long_token, taken_tokens = :long, []
28
+
29
+ expect(rules.token_valid?(long_token, taken_tokens)).to be false
30
+ end
31
+
32
+ it "returns false if the token is already taken" do
33
+ taken_token, taken_tokens = :X, [:X]
34
+
35
+ expect(rules.token_valid?(taken_token, taken_tokens)).to be false
36
+ end
37
+
38
+ it "returns true if the token is a single character and untaken" do
39
+ valid_token, taken_tokens = :O, [:X]
40
+
41
+ expect(rules.token_valid?(valid_token, taken_tokens)).to be true
42
+ end
43
+ end
44
+
45
+
46
+ describe '#difficulty_valid?' do
47
+ it "returns false if the difficulty is not a key in AI_DIFFICULTIES" do
48
+ invalid_difficulty = :invalid
49
+
50
+ expect(rules.difficulty_valid?(invalid_difficulty)).to be false
51
+ end
52
+
53
+ it "returns true if the difficulty is a key in AI_DIFFICULTIES" do
54
+ valid_difficulty = :medium
55
+
56
+ expect(rules.difficulty_valid?(valid_difficulty)).to be true
57
+ end
58
+ end
59
+
60
+
61
+ describe '#game_over?' do
62
+ it "returns false if there is not yet a winner and the board is not full" do
63
+ structure = [x, x, o,
64
+ o, o, nil,
65
+ x, o, x]
66
+ board = generate_board(structure)
67
+
68
+ expect(rules.game_over?(board, players)).to be false
69
+ end
70
+
71
+ it "returns true if any player has won" do
72
+ structure = [ x, nil, nil,
73
+ nil, x, nil,
74
+ nil, nil, x]
75
+ board = generate_board(structure)
76
+
77
+ expect(rules.game_over?(board, players)).to be true
78
+ end
79
+
80
+ it "returns true if the board is full" do
81
+ structure = [x, x, o,
82
+ o, o, x,
83
+ x, o, x]
84
+ board = generate_board(structure)
85
+
86
+ expect(rules.game_over?(board, players)).to be true
87
+ end
88
+ end
89
+
90
+
91
+ describe '#determine_winner' do
92
+ it "returns the winning token when there is a winner" do
93
+ structure = [ o, nil, nil,
94
+ nil, o, nil,
95
+ nil, nil, o]
96
+ board = generate_board(structure)
97
+ winning_token = "o"
98
+
99
+ expect(rules.determine_winner(board, players)).to eql(winning_token)
100
+ end
101
+
102
+ it "returns nil if there is not a winner" do
103
+ structure = [x, x, o,
104
+ o, o, nil,
105
+ x, o, x]
106
+ board = generate_board(structure)
107
+
108
+ expect(rules.determine_winner(board, players)).to be_nil
109
+ end
110
+ end
111
+
112
+
113
+ describe '#win?' do
114
+ it "returns false if the given token has not won" do
115
+ structure = [x, x, o,
116
+ o, o, nil,
117
+ x, o, x]
118
+ board = generate_board(structure)
119
+
120
+ expect(rules.win?(board, x)).to be false
121
+ end
122
+
123
+ it "returns true if the given token has achieved a back diagonal win" do
124
+ structure = [ x, nil, nil,
125
+ nil, x, nil,
126
+ nil, nil, x]
127
+ board = generate_board(structure)
128
+
129
+ expect(rules.win?(board, x)).to be true
130
+ end
131
+
132
+ it "returns true if the given token has achieved a front diagonal win" do
133
+ structure = [nil, nil, x,
134
+ nil, x, nil,
135
+ x, nil, nil]
136
+ board = generate_board(structure)
137
+
138
+ expect(rules.win?(board, x)).to be true
139
+ end
140
+
141
+ it "returns true if the given token has achieved a horizonatal win" do
142
+ structure = [nil, nil, nil,
143
+ x, x, x,
144
+ nil, nil, nil]
145
+ board = generate_board(structure)
146
+
147
+ expect(rules.win?(board, x)).to be true
148
+ end
149
+
150
+ it "returns true if the given token has achieved a vertical win" do
151
+ structure = [nil, x, nil,
152
+ nil, x, nil,
153
+ nil, x, nil]
154
+ board = generate_board(structure)
155
+
156
+ expect(rules.win?(board, x)).to be true
157
+ end
158
+ end
159
+ end
@@ -0,0 +1,13 @@
1
+ require 'tic_tac_toes/board'
2
+
3
+ def generate_board(structure)
4
+ board_size = structure.count
5
+ row_size = Math.sqrt(board_size)
6
+ board = TicTacToes::Board.new(row_size: row_size)
7
+
8
+ structure.each_with_index do |player, index|
9
+ board.place(player, index)
10
+ end
11
+
12
+ board
13
+ end
@@ -0,0 +1,50 @@
1
+ require 'tic_tac_toes/board'
2
+ require 'tic_tac_toes/rules'
3
+ require 'tic_tac_toes/spec_helper'
4
+ require 'tic_tac_toes/strings'
5
+
6
+ describe TicTacToes::Strings do
7
+ let(:strings) { TicTacToes::Strings }
8
+
9
+ describe '#invalid_row_size' do
10
+ it "returns a string containing the minimum and maximum allowed row sizes" do
11
+ smallest_row_size = TicTacToes::Rules::ROW_SIZE_RANGE.min.to_s
12
+ largest_row_size = TicTacToes::Rules::ROW_SIZE_RANGE.max.to_s
13
+
14
+ expect(strings::INVALID_ROW_SIZE).to include(smallest_row_size, largest_row_size)
15
+ end
16
+ end
17
+
18
+ describe '#token_solicitation' do
19
+ it "returns a string containing the name of the player whose token is being picked" do
20
+ player = "human"
21
+ expect(strings.token_solicitation(player)).to include(player)
22
+ end
23
+ end
24
+
25
+ describe '#game_over_notification' do
26
+ it "returns a string containing the name of the winner" do
27
+ winner = "X"
28
+ expect(strings.game_over_notification(winner)).to include(winner)
29
+ end
30
+ end
31
+
32
+ describe '#board' do
33
+ it "returns a board string" do
34
+ board = TicTacToes::Board.new(row_size: 3)
35
+
36
+ leading_spaces_regexp = /^[[:blank:]]+/
37
+ board_string = <<-END.gsub(leading_spaces_regexp, '')
38
+
39
+ [0]|[1]|[2]
40
+ -----------
41
+ [3]|[4]|[5]
42
+ -----------
43
+ [6]|[7]|[8]
44
+
45
+ END
46
+
47
+ expect(strings.board(board)).to eql(board_string)
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,24 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'tic_tac_toes/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "tic_tac_toes"
8
+ spec.version = TicTacToes::VERSION
9
+ spec.authors = ["Ben Spatafora"]
10
+ spec.email = ["benjamin.spatafora@gmail.com"]
11
+ spec.summary = %q{The game Tic-tac-toe, featuring an unbeatable AI}
12
+ spec.homepage = "http://github.com/bspatafora/tic_tac_toes"
13
+ spec.license = "MIT"
14
+
15
+ spec.files = `git ls-files -z`.split("\x0")
16
+ spec.executables = ["tic_tac_toes"]
17
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
18
+ spec.require_paths = ["lib"]
19
+
20
+ spec.add_development_dependency "bundler", "~> 1.6"
21
+ spec.add_development_dependency "rake"
22
+ spec.add_development_dependency "rspec"
23
+ spec.add_dependency "pg"
24
+ end
metadata ADDED
@@ -0,0 +1,151 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: tic_tac_toes
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Ben Spatafora
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-06-16 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.6'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.6'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: pg
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ description:
70
+ email:
71
+ - benjamin.spatafora@gmail.com
72
+ executables:
73
+ - tic_tac_toes
74
+ extensions: []
75
+ extra_rdoc_files: []
76
+ files:
77
+ - ".gitignore"
78
+ - Gemfile
79
+ - LICENSE.txt
80
+ - README.md
81
+ - Rakefile
82
+ - bin/tic_tac_toes
83
+ - lib/command_line/io.rb
84
+ - lib/command_line/menu.rb
85
+ - lib/command_line/runner.rb
86
+ - lib/database/pg_wrapper.rb
87
+ - lib/tic_tac_toes/board.rb
88
+ - lib/tic_tac_toes/easy_ai.rb
89
+ - lib/tic_tac_toes/hard_ai.rb
90
+ - lib/tic_tac_toes/history.rb
91
+ - lib/tic_tac_toes/io_interface.rb
92
+ - lib/tic_tac_toes/medium_ai.rb
93
+ - lib/tic_tac_toes/player.rb
94
+ - lib/tic_tac_toes/player_factory.rb
95
+ - lib/tic_tac_toes/rules.rb
96
+ - lib/tic_tac_toes/strings.rb
97
+ - lib/tic_tac_toes/version.rb
98
+ - spec/command_line/menu_spec.rb
99
+ - spec/command_line/runner_spec.rb
100
+ - spec/database/pg_wrapper_spec.rb
101
+ - spec/tic_tac_toes/board_spec.rb
102
+ - spec/tic_tac_toes/easy_ai_spec.rb
103
+ - spec/tic_tac_toes/hard_ai_spec.rb
104
+ - spec/tic_tac_toes/history_spec.rb
105
+ - spec/tic_tac_toes/io_interface_spec.rb
106
+ - spec/tic_tac_toes/medium_ai_spec.rb
107
+ - spec/tic_tac_toes/player_factory_spec.rb
108
+ - spec/tic_tac_toes/player_spec.rb
109
+ - spec/tic_tac_toes/rules_spec.rb
110
+ - spec/tic_tac_toes/spec_helper.rb
111
+ - spec/tic_tac_toes/strings_spec.rb
112
+ - tic_tac_toes.gemspec
113
+ homepage: http://github.com/bspatafora/tic_tac_toes
114
+ licenses:
115
+ - MIT
116
+ metadata: {}
117
+ post_install_message:
118
+ rdoc_options: []
119
+ require_paths:
120
+ - lib
121
+ required_ruby_version: !ruby/object:Gem::Requirement
122
+ requirements:
123
+ - - ">="
124
+ - !ruby/object:Gem::Version
125
+ version: '0'
126
+ required_rubygems_version: !ruby/object:Gem::Requirement
127
+ requirements:
128
+ - - ">="
129
+ - !ruby/object:Gem::Version
130
+ version: '0'
131
+ requirements: []
132
+ rubyforge_project:
133
+ rubygems_version: 2.2.2
134
+ signing_key:
135
+ specification_version: 4
136
+ summary: The game Tic-tac-toe, featuring an unbeatable AI
137
+ test_files:
138
+ - spec/command_line/menu_spec.rb
139
+ - spec/command_line/runner_spec.rb
140
+ - spec/database/pg_wrapper_spec.rb
141
+ - spec/tic_tac_toes/board_spec.rb
142
+ - spec/tic_tac_toes/easy_ai_spec.rb
143
+ - spec/tic_tac_toes/hard_ai_spec.rb
144
+ - spec/tic_tac_toes/history_spec.rb
145
+ - spec/tic_tac_toes/io_interface_spec.rb
146
+ - spec/tic_tac_toes/medium_ai_spec.rb
147
+ - spec/tic_tac_toes/player_factory_spec.rb
148
+ - spec/tic_tac_toes/player_spec.rb
149
+ - spec/tic_tac_toes/rules_spec.rb
150
+ - spec/tic_tac_toes/spec_helper.rb
151
+ - spec/tic_tac_toes/strings_spec.rb