119 lines
4.3 KiB
Go
119 lines
4.3 KiB
Go
package main
|
||
|
||
import "testing"
|
||
|
||
func TestTicTacToeModelPlaceMarkViaDigitKey(t *testing.T) {
|
||
m := NewTicTacToeModel(TicTacToeDifficultyEasy)
|
||
m.game = NewTicTacToeGame(TicTacToeX) // фиксируем: человек играет крестиками, сейчас его ход
|
||
|
||
next, _ := m.Update(key("5"))
|
||
m = next.(TicTacToeModel)
|
||
if m.game.Board[4] != TicTacToeX {
|
||
t.Fatalf("ожидался крестик в клетке 5 (индекс 4), доска: %v", m.game.Board)
|
||
}
|
||
if m.isError {
|
||
t.Errorf("неожиданная ошибка: %s", m.message)
|
||
}
|
||
}
|
||
|
||
func TestTicTacToeModelCursorMovementAndEnter(t *testing.T) {
|
||
m := NewTicTacToeModel(TicTacToeDifficultyEasy)
|
||
m.game = NewTicTacToeGame(TicTacToeX)
|
||
m.cursor = 4 // центр
|
||
|
||
next, _ := m.Update(key("up"))
|
||
m = next.(TicTacToeModel)
|
||
if m.cursor != 1 {
|
||
t.Fatalf("ожидался курсор на клетке 1 (индекс 1) после 'up' из центра, получено %d", m.cursor)
|
||
}
|
||
|
||
next, _ = m.Update(key("enter"))
|
||
m = next.(TicTacToeModel)
|
||
if m.game.Board[1] != TicTacToeX {
|
||
t.Errorf("ожидался крестик в клетке под курсором (индекс 1), доска: %v", m.game.Board)
|
||
}
|
||
}
|
||
|
||
func TestTicTacToeModelRejectsMoveWhenNotHumanTurn(t *testing.T) {
|
||
m := NewTicTacToeModel(TicTacToeDifficultyEasy)
|
||
m.game = NewTicTacToeGame(TicTacToeO) // человек — нолики, сейчас ход бота (крестиков)
|
||
|
||
next, _ := m.Update(key("5"))
|
||
m = next.(TicTacToeModel)
|
||
if m.game.MovesPlayed != 0 {
|
||
t.Errorf("ход не должен был приняться — сейчас очередь бота, а не человека")
|
||
}
|
||
}
|
||
|
||
func TestTicTacToeModelBotMovesFirstWhenHumanIsO(t *testing.T) {
|
||
m := NewTicTacToeModel(TicTacToeDifficultyHard)
|
||
m.game = NewTicTacToeGame(TicTacToeO)
|
||
|
||
next, _ := m.Update(botMoveMsg{})
|
||
m = next.(TicTacToeModel)
|
||
if m.game.MovesPlayed != 1 {
|
||
t.Fatalf("бот должен был сходить первым, MovesPlayed=%d", m.game.MovesPlayed)
|
||
}
|
||
if m.game.CurrentTurn != TicTacToeO {
|
||
t.Errorf("после хода бота должна была наступить очередь человека (ноликов)")
|
||
}
|
||
}
|
||
|
||
func TestTicTacToeModelRejectsOccupiedCellWithError(t *testing.T) {
|
||
m := NewTicTacToeModel(TicTacToeDifficultyEasy)
|
||
m.game = NewTicTacToeGame(TicTacToeX)
|
||
m.game.Board[0] = TicTacToeO
|
||
m.game.Board[8] = TicTacToeX // клетки заняты вручную, ход всё ещё X
|
||
|
||
next, _ := m.Update(key("1"))
|
||
m = next.(TicTacToeModel)
|
||
if !m.isError {
|
||
t.Errorf("ожидалась ошибка при попытке сходить в занятую клетку")
|
||
}
|
||
}
|
||
|
||
func TestTicTacToeModelNewGameAfterOver(t *testing.T) {
|
||
m := NewTicTacToeModel(TicTacToeDifficultyEasy)
|
||
m.game = NewTicTacToeGame(TicTacToeX)
|
||
m.game.Board = [9]TicTacToeMark{
|
||
TicTacToeX, TicTacToeX, TicTacToeX,
|
||
TicTacToeO, TicTacToeO, TicTacToeEmpty,
|
||
TicTacToeEmpty, TicTacToeEmpty, TicTacToeEmpty,
|
||
}
|
||
m.game.Phase = TicTacToePhaseOver
|
||
m.game.Result = &TicTacToeResult{Winner: TicTacToeX, Line: [3]int{0, 1, 2}}
|
||
|
||
next, _ := m.Update(key("n"))
|
||
next2 := next.(TicTacToeModel)
|
||
if next2.game.Phase != TicTacToePhasePlay {
|
||
t.Errorf("после 'n' должна была начаться новая партия")
|
||
}
|
||
if next2.game == m.game {
|
||
t.Errorf("новая партия должна была получить новое состояние, а не переиспользовать старое")
|
||
}
|
||
}
|
||
|
||
func TestTicTacToeModelQReturnsToMenuNotQuitsApp(t *testing.T) {
|
||
m := NewTicTacToeModel(TicTacToeDifficultyEasy)
|
||
next, _ := m.Update(key("q"))
|
||
m = next.(TicTacToeModel)
|
||
if !m.backToMenu {
|
||
t.Errorf("ожидался флаг backToMenu после 'q'")
|
||
}
|
||
if m.quitting {
|
||
t.Errorf("'q' не должно завершать приложение целиком — только возвращать в меню")
|
||
}
|
||
}
|
||
|
||
func TestTicTacToeModelActionsIgnoredAfterGameOver(t *testing.T) {
|
||
m := NewTicTacToeModel(TicTacToeDifficultyEasy)
|
||
m.game = NewTicTacToeGame(TicTacToeX)
|
||
m.game.Phase = TicTacToePhaseOver
|
||
m.game.Result = &TicTacToeResult{Draw: true}
|
||
|
||
next, _ := m.Update(key("5"))
|
||
m = next.(TicTacToeModel)
|
||
if m.game.MovesPlayed != 0 {
|
||
t.Errorf("ход не должен был приниматься после завершения партии")
|
||
}
|
||
}
|