go_games_collection/tictactoe_tui_test.go

119 lines
4.3 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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("ход не должен был приниматься после завершения партии")
}
}