182 lines
6.4 KiB
Go
182 lines
6.4 KiB
Go
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)
|
||
}
|
||
}
|