go_games_collection/ur_tui_test.go
2026-07-10 09:12:06 +03:00

175 lines
5.2 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 (
"fmt"
"testing"
)
func TestUrModelRollViaKey(t *testing.T) {
m := NewUrModel(UrDifficultyEasy, ColorChoiceA)
m.game = NewUrGame(UrPlayerA)
m.humanColor = UrPlayerA
next, _ := m.Update(key("r"))
m = next.(UrModel)
if !m.game.Rolled && m.game.CurrentPlayer == UrPlayerA {
t.Errorf("после броска Rolled должен был выставиться (или очередь смениться, если ходов нет)")
}
}
func TestUrModelApplyMoveViaDigitKey(t *testing.T) {
m := NewUrModel(UrDifficultyEasy, ColorChoiceA)
m.game = NewUrGame(UrPlayerA)
m.humanColor = UrPlayerA
m.game.Roll(3)
if m.game.CurrentPlayer != UrPlayerA {
t.Fatalf("тест предполагает ход человека")
}
next, _ := m.Update(key("1"))
m = next.(UrModel)
if m.isError {
t.Fatalf("неожиданная ошибка: %s", m.message)
}
if m.game.Path[UrPlayerA][0] != 3 {
t.Errorf("ожидалась позиция 3 после хода, получено %d", m.game.Path[UrPlayerA][0])
}
}
func TestUrModelRejectsMoveKeyBeforeRoll(t *testing.T) {
m := NewUrModel(UrDifficultyEasy, ColorChoiceA)
m.game = NewUrGame(UrPlayerA)
m.humanColor = UrPlayerA
next, _ := m.Update(key("1"))
m = next.(UrModel)
if m.game.Path[UrPlayerA][0] != 0 {
t.Errorf("ход не должен был приняться до броска костей")
}
}
func TestUrModelBotPlaysWhenNotHumanTurn(t *testing.T) {
m := NewUrModel(UrDifficultyEasy, ColorChoiceA)
m.game = NewUrGame(UrPlayerB)
m.humanColor = UrPlayerA
next, _ := m.Update(botMoveMsg{})
m = next.(UrModel)
if m.game.CurrentPlayer != UrPlayerA {
t.Errorf("после полного хода бота (без розеток) очередь должна была перейти к человеку")
}
}
func TestUrModelIgnoresBotMoveMsgOnHumanTurn(t *testing.T) {
m := NewUrModel(UrDifficultyEasy, ColorChoiceA)
m.game = NewUrGame(UrPlayerA)
m.humanColor = UrPlayerA
next, _ := m.Update(botMoveMsg{})
m = next.(UrModel)
if m.game.Rolled {
t.Errorf("botMoveMsg не должно было ничего менять, пока сейчас ход человека")
}
}
func TestUrModelQReturnsToMenuNotQuitsApp(t *testing.T) {
m := NewUrModel(UrDifficultyEasy, ColorChoiceA)
next, _ := m.Update(key("q"))
m = next.(UrModel)
if !m.backToMenu {
t.Errorf("ожидался флаг backToMenu после 'q'")
}
if m.quitting {
t.Errorf("'q' не должно завершать приложение целиком")
}
}
func TestUrModelActionsIgnoredAfterGameOver(t *testing.T) {
m := NewUrModel(UrDifficultyEasy, ColorChoiceA)
m.game = NewUrGame(UrPlayerA)
m.humanColor = UrPlayerA
m.game.Result = &UrResult{Winner: UrPlayerA}
next, _ := m.Update(key("r"))
m = next.(UrModel)
if m.game.Rolled {
t.Errorf("действия после завершения партии не должны приниматься")
}
}
func TestUrModelFullAutoPlaythrough(t *testing.T) {
m := NewUrModel(UrDifficultyMedium, ColorChoiceA)
m.game = NewUrGame(UrPlayerA)
m.humanColor = UrPlayerA
humanBot := UrBot{Difficulty: UrDifficultyMedium}
steps := 0
for m.game.Result == nil && steps < 20000 {
steps++
if m.game.CurrentPlayer != m.humanColor {
next, _ := m.Update(botMoveMsg{})
m = next.(UrModel)
continue
}
if !m.game.Rolled {
next, _ := m.Update(key("r"))
m = next.(UrModel)
continue
}
moves := m.game.LegalMoves()
if len(moves) == 0 {
t.Fatalf("LegalMoves пуст при Rolled=true для хода человека — не должно происходить")
}
if len(moves) > 9 {
t.Fatalf("число легальных ходов превысило 9: %d", len(moves))
}
chosen := humanBot.DecideMove(m.game, m.rng)
idx := -1
for i, mv := range moves {
if mv.PieceIdx == chosen {
idx = i
break
}
}
if idx < 0 {
idx = 0
}
next, _ := m.Update(key(fmt.Sprintf("%d", idx+1)))
m = next.(UrModel)
if m.isError {
t.Fatalf("неожиданная ошибка при ходе: %s", m.message)
}
}
if m.game.Result == nil {
t.Fatalf("партия не завершилась за %d шагов", steps)
}
}
func TestNewUrModelRespectsColorChoiceA(t *testing.T) {
m := NewUrModel(UrDifficultyEasy, ColorChoiceA)
if m.humanColor != UrPlayerA {
t.Errorf("при выборе ColorChoiceA человек должен был играть за UrPlayerA, получено %v", m.humanColor)
}
}
func TestNewUrModelRespectsColorChoiceB(t *testing.T) {
m := NewUrModel(UrDifficultyEasy, ColorChoiceB)
if m.humanColor != UrPlayerB {
t.Errorf("при выборе ColorChoiceB человек должен был играть за UrPlayerB, получено %v", m.humanColor)
}
}
func TestNewUrModelRandomColorGivesValidColor(t *testing.T) {
seenA, seenB := false, false
for i := 0; i < 50 && !(seenA && seenB); i++ {
m := NewUrModel(UrDifficultyEasy, ColorChoiceRandom)
if m.humanColor == UrPlayerA {
seenA = true
} else {
seenB = true
}
}
if !seenA || !seenB {
t.Errorf("случайный выбор цвета должен был давать оба варианта за 50 попыток: A=%v B=%v", seenA, seenB)
}
}