134 lines
3.9 KiB
Go
134 lines
3.9 KiB
Go
package main
|
||
|
||
import "testing"
|
||
|
||
func TestCheckersModelSelectAndMoveViaKeys(t *testing.T) {
|
||
m := NewCheckersModel(0)
|
||
m.cursor = CheckersPos{Row: 5, Col: 2}
|
||
|
||
next, _ := m.Update(key("enter"))
|
||
m = next.(CheckersModel)
|
||
if m.isError {
|
||
t.Fatalf("неожиданная ошибка выбора: %s", m.message)
|
||
}
|
||
if m.selected == nil {
|
||
t.Fatalf("ожидался выбор шашки")
|
||
}
|
||
|
||
m.cursor = CheckersPos{Row: 4, Col: 1}
|
||
next, _ = m.Update(key("enter"))
|
||
m = next.(CheckersModel)
|
||
if m.isError {
|
||
t.Fatalf("неожиданная ошибка хода: %s", m.message)
|
||
}
|
||
if m.game.Board[4][1] == nil {
|
||
t.Fatalf("шашка должна была переместиться")
|
||
}
|
||
if m.selected != nil {
|
||
t.Errorf("выбор должен был сброситься после хода")
|
||
}
|
||
}
|
||
|
||
func TestCheckersModelCursorMovement(t *testing.T) {
|
||
m := NewCheckersModel(0)
|
||
m.cursor = CheckersPos{Row: 4, Col: 4}
|
||
|
||
next, _ := m.Update(key("up"))
|
||
m = next.(CheckersModel)
|
||
if m.cursor.Row != 3 {
|
||
t.Errorf("курсор должен был сдвинуться вверх")
|
||
}
|
||
next, _ = m.Update(key("right"))
|
||
m = next.(CheckersModel)
|
||
if m.cursor.Col != 5 {
|
||
t.Errorf("курсор должен был сдвинуться вправо")
|
||
}
|
||
}
|
||
|
||
func TestCheckersModelEscClearsSelection(t *testing.T) {
|
||
m := NewCheckersModel(0)
|
||
m.cursor = CheckersPos{Row: 5, Col: 2}
|
||
next, _ := m.Update(key("enter"))
|
||
m = next.(CheckersModel)
|
||
if m.selected == nil {
|
||
t.Fatalf("ожидался выбор")
|
||
}
|
||
|
||
next, _ = m.Update(key("esc"))
|
||
m = next.(CheckersModel)
|
||
if m.selected != nil {
|
||
t.Errorf("esc должен был сбросить выбор")
|
||
}
|
||
}
|
||
|
||
func TestCheckersModelCannotSelectEmptySquare(t *testing.T) {
|
||
m := NewCheckersModel(0)
|
||
m.cursor = CheckersPos{Row: 3, Col: 2}
|
||
|
||
next, _ := m.Update(key("enter"))
|
||
m = next.(CheckersModel)
|
||
if !m.isError {
|
||
t.Fatalf("ожидалась ошибка выбора пустой клетки")
|
||
}
|
||
}
|
||
|
||
func TestCheckersModelQReturnsToMenu(t *testing.T) {
|
||
m := NewCheckersModel(0)
|
||
next, _ := m.Update(key("q"))
|
||
m = next.(CheckersModel)
|
||
if !m.backToMenu {
|
||
t.Fatalf("ожидался флаг backToMenu после 'q'")
|
||
}
|
||
if m.quitting {
|
||
t.Fatalf("'q' не должен закрывать всё приложение")
|
||
}
|
||
}
|
||
|
||
func TestCheckersModelNewGameAfterResult(t *testing.T) {
|
||
m := NewCheckersModel(0)
|
||
m.game.Result = &CheckersResult{Winner: CheckersWhite}
|
||
|
||
next, _ := m.Update(key("n"))
|
||
m = next.(CheckersModel)
|
||
if m.game.Result != nil {
|
||
t.Errorf("новая партия не должна была начаться с результатом")
|
||
}
|
||
}
|
||
|
||
// TestCheckersModelFullAutoPlaythrough прогоняет TUI-модель от
|
||
// начала до конца, где "человек" отыгрывает свои ходы через бота
|
||
// (небольшая глубина — ради скорости), проверяя, что весь путь
|
||
// через Update не паникует и партия завершается.
|
||
func TestCheckersModelFullAutoPlaythrough(t *testing.T) {
|
||
m := NewCheckersModel(0)
|
||
m.bot = CheckersBot{Depth: 2}
|
||
helperBot := CheckersBot{Depth: 2}
|
||
|
||
const maxSteps = 400
|
||
for i := 0; i < maxSteps && m.game.Result == nil; i++ {
|
||
if m.game.Turn != m.human {
|
||
next, _ := m.Update(botMoveMsg{})
|
||
m = next.(CheckersModel)
|
||
continue
|
||
}
|
||
mv, ok := helperBot.DecideMove(m.game)
|
||
if !ok {
|
||
break
|
||
}
|
||
m.cursor = mv.From
|
||
next, _ := m.Update(key("enter"))
|
||
m = next.(CheckersModel)
|
||
if m.isError {
|
||
t.Fatalf("неожиданная ошибка выбора хода человеком: %s", m.message)
|
||
}
|
||
m.cursor = mv.To
|
||
next, _ = m.Update(key("enter"))
|
||
m = next.(CheckersModel)
|
||
if m.isError {
|
||
t.Fatalf("неожиданная ошибка хода человеком: %s", m.message)
|
||
}
|
||
}
|
||
if m.game.Result == nil {
|
||
t.Fatalf("партия через TUI не завершилась за %d шагов", maxSteps)
|
||
}
|
||
}
|