139 lines
4 KiB
Go
139 lines
4 KiB
Go
package main
|
||
|
||
import "testing"
|
||
|
||
func TestGoModelPlayStoneViaKey(t *testing.T) {
|
||
m := NewGoModel(9, GoDifficultyEasy)
|
||
m.cursor = GoPos{Row: 4, Col: 4}
|
||
|
||
next, _ := m.Update(key("enter"))
|
||
m = next.(GoModel)
|
||
if m.isError {
|
||
t.Fatalf("неожиданная ошибка: %s", m.message)
|
||
}
|
||
if m.game.Board[4][4] != GoBlack {
|
||
t.Fatalf("камень должен был встать в (4,4) как чёрный")
|
||
}
|
||
}
|
||
|
||
func TestGoModelCursorMovement(t *testing.T) {
|
||
m := NewGoModel(9, GoDifficultyEasy)
|
||
m.cursor = GoPos{Row: 4, Col: 4}
|
||
|
||
next, _ := m.Update(key("up"))
|
||
m = next.(GoModel)
|
||
if m.cursor.Row != 3 {
|
||
t.Errorf("курсор должен был сдвинуться вверх")
|
||
}
|
||
next, _ = m.Update(key("right"))
|
||
m = next.(GoModel)
|
||
if m.cursor.Col != 5 {
|
||
t.Errorf("курсор должен был сдвинуться вправо")
|
||
}
|
||
}
|
||
|
||
func TestGoModelCursorClampsAtEdges(t *testing.T) {
|
||
m := NewGoModel(9, GoDifficultyEasy)
|
||
m.cursor = GoPos{Row: 0, Col: 0}
|
||
|
||
next, _ := m.Update(key("up"))
|
||
m = next.(GoModel)
|
||
if m.cursor.Row != 0 {
|
||
t.Errorf("курсор не должен был уйти за верхний край")
|
||
}
|
||
next, _ = m.Update(key("left"))
|
||
m = next.(GoModel)
|
||
if m.cursor.Col != 0 {
|
||
t.Errorf("курсор не должен был уйти за левый край")
|
||
}
|
||
}
|
||
|
||
func TestGoModelPassViaKey(t *testing.T) {
|
||
m := NewGoModel(9, GoDifficultyEasy)
|
||
next, _ := m.Update(key("p"))
|
||
m = next.(GoModel)
|
||
if m.isError {
|
||
t.Fatalf("неожиданная ошибка паса: %s", m.message)
|
||
}
|
||
}
|
||
|
||
func TestGoModelInvalidMoveShowsError(t *testing.T) {
|
||
m := NewGoModel(9, GoDifficultyEasy)
|
||
m.cursor = GoPos{Row: 0, Col: 0}
|
||
m.game.Board[0][0] = GoBlack
|
||
|
||
next, _ := m.Update(key("enter"))
|
||
m = next.(GoModel)
|
||
if !m.isError {
|
||
t.Fatalf("ожидалась ошибка хода на занятую точку")
|
||
}
|
||
}
|
||
|
||
func TestGoModelQReturnsToMenu(t *testing.T) {
|
||
m := NewGoModel(9, GoDifficultyEasy)
|
||
next, _ := m.Update(key("q"))
|
||
m = next.(GoModel)
|
||
if !m.backToMenu {
|
||
t.Fatalf("ожидался флаг backToMenu после 'q'")
|
||
}
|
||
if m.quitting {
|
||
t.Fatalf("'q' не должен закрывать всё приложение")
|
||
}
|
||
}
|
||
|
||
func TestGoModelNewGameAfterResult(t *testing.T) {
|
||
m := NewGoModel(9, GoDifficultyEasy)
|
||
m.game.Result = &GoResult{Winner: GoBlack, BlackScore: 10, WhiteScore: 7.5}
|
||
|
||
next, _ := m.Update(key("n"))
|
||
m = next.(GoModel)
|
||
if m.game.Result != nil {
|
||
t.Errorf("новая партия не должна была начаться с результатом")
|
||
}
|
||
if m.game.Size != 9 {
|
||
t.Errorf("новая партия должна была сохранить размер доски")
|
||
}
|
||
}
|
||
|
||
func TestGoModelSupportsAllBoardSizes(t *testing.T) {
|
||
for _, size := range []int{9, 13, 19} {
|
||
m := NewGoModel(size, GoDifficultyMedium)
|
||
if m.game.Size != size {
|
||
t.Errorf("ожидался размер доски %d, получено %d", size, m.game.Size)
|
||
}
|
||
}
|
||
}
|
||
|
||
// TestGoModelFullAutoPlaythrough прогоняет TUI-модель от начала до
|
||
// конца на маленькой доске, где "человек" отыгрывает свои ходы
|
||
// через бота, проверяя, что весь путь через Update не паникует и
|
||
// партия завершается.
|
||
func TestGoModelFullAutoPlaythrough(t *testing.T) {
|
||
m := NewGoModel(9, GoDifficultyEasy)
|
||
helperBot := GoBot{Difficulty: GoDifficultyEasy}
|
||
rnd := m.rnd
|
||
|
||
const maxSteps = 3000
|
||
for i := 0; i < maxSteps && m.game.Result == nil; i++ {
|
||
if m.game.Turn != m.human {
|
||
next, _ := m.Update(botMoveMsg{})
|
||
m = next.(GoModel)
|
||
continue
|
||
}
|
||
pos, ok := helperBot.DecideMove(m.game, rnd)
|
||
if !ok {
|
||
next, _ := m.Update(key("p"))
|
||
m = next.(GoModel)
|
||
continue
|
||
}
|
||
m.cursor = pos
|
||
next, _ := m.Update(key("enter"))
|
||
m = next.(GoModel)
|
||
if m.isError {
|
||
t.Fatalf("неожиданная ошибка хода человеком: %s", m.message)
|
||
}
|
||
}
|
||
if m.game.Result == nil {
|
||
t.Fatalf("партия через TUI не завершилась за %d шагов", maxSteps)
|
||
}
|
||
}
|