go_games_collection/wayfarer_quest_state_test.go

182 lines
6.4 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"
// withTestQuest временно подменяет WayfarerQuestDefs на один
// тестовый квест с двумя шагами и восстанавливает оригинал по
// завершении теста.
func withTestQuest(t *testing.T) {
t.Helper()
original := WayfarerQuestDefs
WayfarerQuestDefs = []WayfarerQuestDef{
{
Key: "test.quest",
TitleKey: "test.title",
BriefKey: "test.brief",
Steps: []WayfarerQuestStep{
{
TextKey: "test.step0",
Choices: []WayfarerQuestChoice{
{LabelKey: "test.choice.a", NextStep: 1},
{LabelKey: "test.choice.b", Terminal: true, Success: false, CreditsDelta: -50},
},
},
{
TextKey: "test.step1",
Choices: []WayfarerQuestChoice{
{LabelKey: "test.choice.c", Terminal: true, Success: true, CreditsDelta: 500, HullDelta: -10},
},
},
},
},
}
t.Cleanup(func() { WayfarerQuestDefs = original })
}
func TestStartQuestSetsActiveState(t *testing.T) {
withTestQuest(t)
s := NewWayfarerShip(WayfarerSystemID{})
if err := s.StartQuest("test.quest"); err != nil {
t.Fatalf("неожиданная ошибка старта квеста: %v", err)
}
if s.ActiveQuest == nil || s.ActiveQuest.Key != "test.quest" || s.ActiveQuest.Step != 0 {
t.Fatalf("ожидалось активное состояние квеста на шаге 0, получено: %+v", s.ActiveQuest)
}
}
func TestCannotStartQuestWhileAnotherActive(t *testing.T) {
withTestQuest(t)
s := NewWayfarerShip(WayfarerSystemID{})
s.StartQuest("test.quest")
if err := s.StartQuest("test.quest"); err != errWayfarerQuestAlreadyActive {
t.Errorf("ожидалась ошибка уже активного квеста, получено: %v", err)
}
}
func TestCannotStartUnknownQuest(t *testing.T) {
withTestQuest(t)
s := NewWayfarerShip(WayfarerSystemID{})
if err := s.StartQuest("no.such.quest"); err != errWayfarerQuestNotFound {
t.Errorf("ожидалась ошибка ненайденного квеста, получено: %v", err)
}
}
func TestChooseQuestOptionAdvancesToNextStep(t *testing.T) {
withTestQuest(t)
s := NewWayfarerShip(WayfarerSystemID{})
s.StartQuest("test.quest")
choice, err := s.ChooseQuestOption(0) // "a" -> шаг 1
if err != nil {
t.Fatalf("неожиданная ошибка выбора: %v", err)
}
if choice.LabelKey != "test.choice.a" {
t.Errorf("ожидался выбор 'a', получено %s", choice.LabelKey)
}
if s.ActiveQuest == nil || s.ActiveQuest.Step != 1 {
t.Fatalf("ожидался переход на шаг 1, получено: %+v", s.ActiveQuest)
}
step, ok := s.CurrentQuestStep()
if !ok || step.TextKey != "test.step1" {
t.Fatalf("ожидался текст шага 1, получено: %+v", step)
}
}
func TestChooseTerminalChoiceEndsQuestSuccessfully(t *testing.T) {
withTestQuest(t)
s := NewWayfarerShip(WayfarerSystemID{})
s.StartQuest("test.quest")
s.ChooseQuestOption(0) // на шаг 1
before := s.Credits
beforeHull := s.Hull
if _, err := s.ChooseQuestOption(0); err != nil { // "c" -> успешное завершение
t.Fatalf("неожиданная ошибка: %v", err)
}
if s.ActiveQuest != nil {
t.Errorf("активный квест должен был сброситься после завершения")
}
if !s.CompletedQuests["test.quest"] {
t.Errorf("квест должен был отметиться как завершённый успешно")
}
if s.Credits != before+500 {
t.Errorf("ожидалось начисление 500 кредитов, получено %v (было %v)", s.Credits, before)
}
if s.Hull != beforeHull-10 {
t.Errorf("ожидалось повреждение корпуса на 10, получено %d (было %d)", s.Hull, beforeHull)
}
}
func TestChooseTerminalChoiceCanEndQuestInFailure(t *testing.T) {
withTestQuest(t)
s := NewWayfarerShip(WayfarerSystemID{})
s.StartQuest("test.quest")
before := s.Credits
if _, err := s.ChooseQuestOption(1); err != nil { // "b" -> немедленный провал
t.Fatalf("неожиданная ошибка: %v", err)
}
if s.ActiveQuest != nil {
t.Errorf("активный квест должен был сброситься после провала")
}
if !s.FailedQuests["test.quest"] {
t.Errorf("квест должен был отметиться как провальный")
}
if s.Credits != before-50 {
t.Errorf("ожидалось списание 50 кредитов, получено %v (было %v)", s.Credits, before)
}
}
func TestCannotRestartCompletedQuest(t *testing.T) {
withTestQuest(t)
s := NewWayfarerShip(WayfarerSystemID{})
s.StartQuest("test.quest")
s.ChooseQuestOption(0)
s.ChooseQuestOption(0)
if err := s.StartQuest("test.quest"); err != errWayfarerQuestAlreadyDone {
t.Errorf("ожидалась ошибка уже завершённого квеста, получено: %v", err)
}
}
func TestChooseQuestOptionInvalidIndex(t *testing.T) {
withTestQuest(t)
s := NewWayfarerShip(WayfarerSystemID{})
s.StartQuest("test.quest")
if _, err := s.ChooseQuestOption(99); err != errWayfarerInvalidChoice {
t.Errorf("ожидалась ошибка недопустимого выбора, получено: %v", err)
}
}
func TestChooseQuestOptionWithNoActiveQuest(t *testing.T) {
withTestQuest(t)
s := NewWayfarerShip(WayfarerSystemID{})
if _, err := s.ChooseQuestOption(0); err != errWayfarerNoActiveQuest {
t.Errorf("ожидалась ошибка отсутствия активного квеста, получено: %v", err)
}
}
func TestAbandonQuestAllowsRestartLater(t *testing.T) {
withTestQuest(t)
s := NewWayfarerShip(WayfarerSystemID{})
s.StartQuest("test.quest")
s.AbandonQuest()
if s.ActiveQuest != nil {
t.Errorf("активный квест должен был обнулиться после отказа")
}
if err := s.StartQuest("test.quest"); err != nil {
t.Errorf("после отказа квест должен быть доступен для повторного старта, получено: %v", err)
}
}
func TestQuestCreditsAndCargoNeverGoNegative(t *testing.T) {
withTestQuest(t)
s := NewWayfarerShip(WayfarerSystemID{})
s.Credits = 10
s.StartQuest("test.quest")
s.ChooseQuestOption(1) // -50 кредитов при балансе 10
if s.Credits < 0 {
t.Errorf("кредиты не должны уходить в минус, получено %v", s.Credits)
}
}