generated from VLADIMIR/template
storytelling
This commit is contained in:
@@ -26,3 +26,5 @@ go.work
|
||||
go.sum
|
||||
|
||||
.env
|
||||
|
||||
.VSCodeCounter/
|
||||
|
||||
Vendored
+1
@@ -1,5 +1,6 @@
|
||||
{
|
||||
"cSpell.words": [
|
||||
"Аркхема",
|
||||
"pgxpool",
|
||||
"timestamppb"
|
||||
]
|
||||
|
||||
@@ -4,12 +4,20 @@ go 1.25.0
|
||||
|
||||
require (
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0
|
||||
github.com/stretchr/testify v1.11.1
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240513163218-0867130af1f8
|
||||
google.golang.org/grpc v1.64.0
|
||||
google.golang.org/protobuf v1.34.1
|
||||
)
|
||||
|
||||
require github.com/vearutop/statigz v1.4.0 // indirect
|
||||
require (
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/kr/text v0.2.0 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/rogpeppe/go-internal v1.15.0 // indirect
|
||||
github.com/vearutop/statigz v1.4.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/golang-jwt/jwt/v5 v5.3.1
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
package storytelling
|
||||
|
||||
type IStory interface {
|
||||
GetStory(scenario *Story, codes []string) *Story
|
||||
}
|
||||
|
||||
// История - это набор точек
|
||||
type Story struct {
|
||||
|
||||
// Список точек
|
||||
Places []*Place `json:"places"`
|
||||
}
|
||||
|
||||
// Точка - что-то куда можно сходить
|
||||
// Это может быть место - аптека, остановка, площадь...
|
||||
// Это может быть персонаж - пострадавший, продавец, полицейский...
|
||||
// Это может быть описание действия игрока - ответ на вопрос, реакция на выбитую дверь...
|
||||
type Place struct {
|
||||
|
||||
// Код - то что вбивает игрок
|
||||
Code string `json:"code"`
|
||||
|
||||
// Название места, имя персонажа, заданный игроком вопрос...
|
||||
Name string `json:"name"`
|
||||
|
||||
// Текст - получаемая текстовая информация
|
||||
Text string `json:"text"`
|
||||
|
||||
// Картинка - получаемая визуальная информация
|
||||
Image string `json:"image"`
|
||||
|
||||
// Признак скрытой карточки - некоторые места изначально не доступны
|
||||
Hidden bool `json:"hidden"`
|
||||
|
||||
// Приложения - получаемые улики
|
||||
Applications []*Application `json:"applications,omitempty"`
|
||||
|
||||
// Двери к другим точкам - действия или диалоги, открывающие другие точки
|
||||
Doors []*Door `json:"doors"`
|
||||
|
||||
// Получаемые ключи - ключи используются для получения доступа к скрытым дверям
|
||||
Keys []*Key `json:"keys"`
|
||||
}
|
||||
|
||||
// Приложение - улика
|
||||
// Это может быть оружие, отпечатки, фотография...
|
||||
type Application struct {
|
||||
|
||||
// Название улики
|
||||
Name string `json:"name"`
|
||||
|
||||
// Картинка
|
||||
Image string `json:"image"`
|
||||
}
|
||||
|
||||
// Дверь - действие или диалог
|
||||
type Door struct {
|
||||
|
||||
// Код
|
||||
Code string `json:"code"`
|
||||
|
||||
// Название - заданный вопрос, проделанное действие...
|
||||
Name string `json:"name"`
|
||||
|
||||
// Некоторые двери изначально не доступны
|
||||
// Ключи требуемые для получения доступа к скрытым дверям
|
||||
// Если указаны ключи то дверь считается скрытой
|
||||
Keys []*Key `json:"keys"`
|
||||
}
|
||||
|
||||
// Аналог карт допуска в "Тайны Аркхема"
|
||||
type Key struct {
|
||||
|
||||
// Название
|
||||
Name string `json:"name"`
|
||||
}
|
||||
@@ -0,0 +1,172 @@
|
||||
package storytelling
|
||||
|
||||
type story struct{}
|
||||
|
||||
func NewStory() IStory {
|
||||
return &story{}
|
||||
}
|
||||
|
||||
func (s *story) GetStory(
|
||||
scenario *Story,
|
||||
codes []string,
|
||||
) *Story {
|
||||
story := &Story{}
|
||||
keys := map[string]struct{}{}
|
||||
codesWithUseActions := map[string]struct{}{}
|
||||
codesHidden := map[string]struct{}{}
|
||||
for i, code := range codes {
|
||||
var prevPlace *Place
|
||||
if i > 0 {
|
||||
prevPlace, _ = s.findPlace(scenario, codes[i-1])
|
||||
}
|
||||
currentPlace, _ := s.findPlace(scenario, codes[i])
|
||||
var nextPlace *Place
|
||||
if i < len(codes)-1 {
|
||||
nextPlace, _ = s.findPlace(scenario, codes[i+1])
|
||||
}
|
||||
// Если следующая точка это открытие двери в текущей точке, то текущая точка считается использованной для действия
|
||||
if nextPlace != nil && currentPlace != nil {
|
||||
openDoor := false
|
||||
for _, door := range currentPlace.Doors {
|
||||
if door.Code == nextPlace.Code {
|
||||
codesWithUseActions[currentPlace.Code] = struct{}{}
|
||||
openDoor = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if openDoor {
|
||||
// Запрещаем смотреть не выбранные действия
|
||||
for _, door := range currentPlace.Doors {
|
||||
if door.Code != nextPlace.Code {
|
||||
codesHidden[door.Code] = struct{}{}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Собираем ключи
|
||||
if currentPlace != nil {
|
||||
for _, key := range currentPlace.Keys {
|
||||
keys[key.Name] = struct{}{}
|
||||
}
|
||||
}
|
||||
place, ok := s.findResultPlace(scenario, code, prevPlace, codesHidden)
|
||||
if !ok {
|
||||
story.Places = append(story.Places, s.buildNotFoundPlace(code))
|
||||
continue
|
||||
}
|
||||
story.Places = append(
|
||||
story.Places,
|
||||
s.mapPlace(place, nextPlace, codesWithUseActions, keys),
|
||||
)
|
||||
}
|
||||
return story
|
||||
}
|
||||
|
||||
func (s *story) findPlace(
|
||||
scenario *Story,
|
||||
code string,
|
||||
) (*Place, bool) {
|
||||
for _, place := range scenario.Places {
|
||||
if place.Code == code {
|
||||
return place, true
|
||||
}
|
||||
}
|
||||
return nil, false
|
||||
}
|
||||
|
||||
func (s *story) findResultPlace(
|
||||
scenario *Story,
|
||||
code string,
|
||||
prevPlace *Place,
|
||||
codesHidden map[string]struct{},
|
||||
) (*Place, bool) {
|
||||
if _, ok := codesHidden[code]; ok {
|
||||
return nil, false
|
||||
}
|
||||
open := false
|
||||
if prevPlace != nil {
|
||||
for _, door := range prevPlace.Doors {
|
||||
if door.Code == code {
|
||||
open = true
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
for _, place := range scenario.Places {
|
||||
if place.Code == code {
|
||||
if place.Hidden && !open {
|
||||
return nil, false
|
||||
}
|
||||
return place, true
|
||||
}
|
||||
}
|
||||
return nil, false
|
||||
}
|
||||
|
||||
func (s *story) buildNotFoundPlace(code string) *Place {
|
||||
return &Place{
|
||||
Code: code,
|
||||
Name: "Не найдено",
|
||||
Text: "Такой точки не существует.",
|
||||
}
|
||||
}
|
||||
|
||||
func (s *story) mapPlace(
|
||||
place *Place,
|
||||
nextPlace *Place,
|
||||
codesWithUseActions map[string]struct{},
|
||||
keys map[string]struct{},
|
||||
) *Place {
|
||||
var applications []*Application
|
||||
if len(place.Applications) > 0 {
|
||||
applications = make([]*Application, 0, len(place.Applications))
|
||||
for _, application := range place.Applications {
|
||||
applications = append(
|
||||
applications,
|
||||
&Application{
|
||||
Name: application.Name,
|
||||
Image: application.Image,
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
var doors []*Door
|
||||
_, useAction := codesWithUseActions[place.Code]
|
||||
if len(place.Doors) > 0 && !useAction {
|
||||
doors = make([]*Door, 0, len(place.Doors))
|
||||
for _, door := range place.Doors {
|
||||
if nextPlace != nil {
|
||||
if door.Code != nextPlace.Code {
|
||||
continue
|
||||
}
|
||||
}
|
||||
hasKeys := true
|
||||
for _, doorKey := range door.Keys {
|
||||
if _, ok := keys[doorKey.Name]; !ok {
|
||||
hasKeys = false
|
||||
}
|
||||
}
|
||||
if !hasKeys {
|
||||
continue
|
||||
}
|
||||
doors = append(
|
||||
doors,
|
||||
&Door{
|
||||
Code: door.Code,
|
||||
Name: door.Name,
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
if len(doors) == 0 {
|
||||
doors = nil
|
||||
}
|
||||
return &Place{
|
||||
Code: place.Code,
|
||||
Name: place.Name,
|
||||
Text: place.Text,
|
||||
Image: place.Image,
|
||||
Applications: applications,
|
||||
Doors: doors,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,677 @@
|
||||
package storytelling
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func Test_story_GetStory(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
scenario *Story
|
||||
codes []string
|
||||
want *Story
|
||||
}{
|
||||
{
|
||||
name: "Попытка получить несуществующую точку",
|
||||
scenario: &Story{},
|
||||
codes: []string{"Ы"},
|
||||
want: &Story{
|
||||
Places: []*Place{
|
||||
{
|
||||
Code: "Ы",
|
||||
Name: "Не найдено",
|
||||
Text: "Такой точки не существует.",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Получение точки",
|
||||
scenario: &Story{
|
||||
Places: []*Place{
|
||||
{
|
||||
Code: "Ы",
|
||||
Name: "Название точки",
|
||||
Text: "Текст точки.",
|
||||
},
|
||||
},
|
||||
},
|
||||
codes: []string{"Ы"},
|
||||
want: &Story{
|
||||
Places: []*Place{
|
||||
{
|
||||
Code: "Ы",
|
||||
Name: "Название точки",
|
||||
Text: "Текст точки.",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Получение 2 точек",
|
||||
scenario: &Story{
|
||||
Places: []*Place{
|
||||
{
|
||||
Code: "Ы",
|
||||
Name: "Название точки Ы",
|
||||
Text: "Текст точки Ы.",
|
||||
},
|
||||
{
|
||||
Code: "Д",
|
||||
Name: "Название точки Д",
|
||||
Text: "Текст точки Д.",
|
||||
},
|
||||
},
|
||||
},
|
||||
codes: []string{"Ы", "Д"},
|
||||
want: &Story{
|
||||
Places: []*Place{
|
||||
{
|
||||
Code: "Ы",
|
||||
Name: "Название точки Ы",
|
||||
Text: "Текст точки Ы.",
|
||||
},
|
||||
{
|
||||
Code: "Д",
|
||||
Name: "Название точки Д",
|
||||
Text: "Текст точки Д.",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Получение точки с картинкой",
|
||||
scenario: &Story{
|
||||
Places: []*Place{
|
||||
{
|
||||
Code: "Ы",
|
||||
Name: "Название точки",
|
||||
Text: "Текст точки.",
|
||||
Image: "image.png",
|
||||
},
|
||||
},
|
||||
},
|
||||
codes: []string{"Ы"},
|
||||
want: &Story{
|
||||
Places: []*Place{
|
||||
{
|
||||
Code: "Ы",
|
||||
Name: "Название точки",
|
||||
Text: "Текст точки.",
|
||||
Image: "image.png",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Попытка получить скрытую точку",
|
||||
scenario: &Story{
|
||||
Places: []*Place{
|
||||
{
|
||||
Code: "Ы",
|
||||
Name: "Название точки",
|
||||
Text: "Текст точки.",
|
||||
Hidden: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
codes: []string{"Ы"},
|
||||
want: &Story{
|
||||
Places: []*Place{
|
||||
{
|
||||
Code: "Ы",
|
||||
Name: "Не найдено",
|
||||
Text: "Такой точки не существует.",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Получение точки с уликой",
|
||||
scenario: &Story{
|
||||
Places: []*Place{
|
||||
{
|
||||
Code: "Ы",
|
||||
Name: "Название точки",
|
||||
Text: "Текст точки.",
|
||||
Applications: []*Application{
|
||||
{
|
||||
Name: "Название улики",
|
||||
Image: "image.png",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
codes: []string{"Ы"},
|
||||
want: &Story{
|
||||
Places: []*Place{
|
||||
{
|
||||
Code: "Ы",
|
||||
Name: "Название точки",
|
||||
Text: "Текст точки.",
|
||||
Applications: []*Application{
|
||||
{
|
||||
Name: "Название улики",
|
||||
Image: "image.png",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Получение точки с действием",
|
||||
scenario: &Story{
|
||||
Places: []*Place{
|
||||
{
|
||||
Code: "Ы",
|
||||
Name: "Название точки",
|
||||
Text: "Текст точки.",
|
||||
Doors: []*Door{
|
||||
{
|
||||
Code: "Ы-1",
|
||||
Name: "Действие 1",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
codes: []string{"Ы"},
|
||||
want: &Story{
|
||||
Places: []*Place{
|
||||
{
|
||||
Code: "Ы",
|
||||
Name: "Название точки",
|
||||
Text: "Текст точки.",
|
||||
Doors: []*Door{
|
||||
{
|
||||
Code: "Ы-1",
|
||||
Name: "Действие 1",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Не открываем скрытую точку действием",
|
||||
scenario: &Story{
|
||||
Places: []*Place{
|
||||
{
|
||||
Code: "Ы",
|
||||
Name: "Название точки",
|
||||
Text: "Текст точки.",
|
||||
Doors: []*Door{
|
||||
{
|
||||
Code: "Ы-1",
|
||||
Name: "Действие 1",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Code: "Д",
|
||||
Name: "Название точки",
|
||||
Text: "Текст точки.",
|
||||
},
|
||||
},
|
||||
},
|
||||
codes: []string{"Ы", "Д"},
|
||||
want: &Story{
|
||||
Places: []*Place{
|
||||
{
|
||||
Code: "Ы",
|
||||
Name: "Название точки",
|
||||
Text: "Текст точки.",
|
||||
},
|
||||
{
|
||||
Code: "Д",
|
||||
Name: "Название точки",
|
||||
Text: "Текст точки.",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Открываем скрытую точку действием",
|
||||
scenario: &Story{
|
||||
Places: []*Place{
|
||||
{
|
||||
Code: "Ы",
|
||||
Name: "Название точки",
|
||||
Text: "Текст точки.",
|
||||
Doors: []*Door{
|
||||
{
|
||||
Code: "Ы-1",
|
||||
Name: "Действие 1",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Code: "Ы-1",
|
||||
Name: "Название точки",
|
||||
Text: "Текст точки.",
|
||||
Hidden: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
codes: []string{"Ы", "Ы-1"},
|
||||
want: &Story{
|
||||
Places: []*Place{
|
||||
{
|
||||
Code: "Ы",
|
||||
Name: "Название точки",
|
||||
Text: "Текст точки.",
|
||||
},
|
||||
{
|
||||
Code: "Ы-1",
|
||||
Name: "Название точки",
|
||||
Text: "Текст точки.",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Не открываем скрытую точку действием, а потом возвращаемся",
|
||||
scenario: &Story{
|
||||
Places: []*Place{
|
||||
{
|
||||
Code: "Ы",
|
||||
Name: "Название точки",
|
||||
Text: "Текст точки.",
|
||||
Doors: []*Door{
|
||||
{
|
||||
Code: "Ы-1",
|
||||
Name: "Действие 1",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Code: "Д",
|
||||
Name: "Название точки",
|
||||
Text: "Текст точки.",
|
||||
},
|
||||
},
|
||||
},
|
||||
codes: []string{"Ы", "Д", "Ы"},
|
||||
want: &Story{
|
||||
Places: []*Place{
|
||||
{
|
||||
Code: "Ы",
|
||||
Name: "Название точки",
|
||||
Text: "Текст точки.",
|
||||
},
|
||||
{
|
||||
Code: "Д",
|
||||
Name: "Название точки",
|
||||
Text: "Текст точки.",
|
||||
},
|
||||
{
|
||||
Code: "Ы",
|
||||
Name: "Название точки",
|
||||
Text: "Текст точки.",
|
||||
Doors: []*Door{
|
||||
{
|
||||
Code: "Ы-1",
|
||||
Name: "Действие 1",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Открываем скрытую точку действием, а потом возвращаемся",
|
||||
scenario: &Story{
|
||||
Places: []*Place{
|
||||
{
|
||||
Code: "Ы",
|
||||
Name: "Название точки",
|
||||
Text: "Текст точки.",
|
||||
Doors: []*Door{
|
||||
{
|
||||
Code: "Ы-1",
|
||||
Name: "Действие 1",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Code: "Ы-1",
|
||||
Name: "Название точки",
|
||||
Text: "Текст точки.",
|
||||
Hidden: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
codes: []string{"Ы", "Ы-1", "Ы"},
|
||||
want: &Story{
|
||||
Places: []*Place{
|
||||
{
|
||||
Code: "Ы",
|
||||
Name: "Название точки",
|
||||
Text: "Текст точки.",
|
||||
},
|
||||
{
|
||||
Code: "Ы-1",
|
||||
Name: "Название точки",
|
||||
Text: "Текст точки.",
|
||||
},
|
||||
{
|
||||
Code: "Ы",
|
||||
Name: "Название точки",
|
||||
Text: "Текст точки.",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Получение точки со скрытым действием",
|
||||
scenario: &Story{
|
||||
Places: []*Place{
|
||||
{
|
||||
Code: "Ы",
|
||||
Name: "Название точки",
|
||||
Text: "Текст точки.",
|
||||
Doors: []*Door{
|
||||
{
|
||||
Code: "Ы-1",
|
||||
Name: "Действие 1",
|
||||
Keys: []*Key{
|
||||
{
|
||||
Name: "ключ",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
codes: []string{"Ы"},
|
||||
want: &Story{
|
||||
Places: []*Place{
|
||||
{
|
||||
Code: "Ы",
|
||||
Name: "Название точки",
|
||||
Text: "Текст точки.",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Получение точки с ключом",
|
||||
scenario: &Story{
|
||||
Places: []*Place{
|
||||
{
|
||||
Code: "Ы",
|
||||
Name: "Название точки",
|
||||
Text: "Текст точки.",
|
||||
Keys: []*Key{
|
||||
{
|
||||
Name: "ключ",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
codes: []string{"Ы"},
|
||||
want: &Story{
|
||||
Places: []*Place{
|
||||
{
|
||||
Code: "Ы",
|
||||
Name: "Название точки",
|
||||
Text: "Текст точки.",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Получение ключа и открытие скрытого действия",
|
||||
scenario: &Story{
|
||||
Places: []*Place{
|
||||
{
|
||||
Code: "Ы",
|
||||
Name: "Название точки",
|
||||
Text: "Текст точки.",
|
||||
Keys: []*Key{
|
||||
{
|
||||
Name: "ключ",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Code: "Д",
|
||||
Name: "Название точки",
|
||||
Text: "Текст точки.",
|
||||
Doors: []*Door{
|
||||
{
|
||||
Code: "Ы-1",
|
||||
Name: "Действие 1",
|
||||
Keys: []*Key{
|
||||
{
|
||||
Name: "ключ",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
codes: []string{"Ы", "Д"},
|
||||
want: &Story{
|
||||
Places: []*Place{
|
||||
{
|
||||
Code: "Ы",
|
||||
Name: "Название точки",
|
||||
Text: "Текст точки.",
|
||||
},
|
||||
{
|
||||
Code: "Д",
|
||||
Name: "Название точки",
|
||||
Text: "Текст точки.",
|
||||
Doors: []*Door{
|
||||
{
|
||||
Code: "Ы-1",
|
||||
Name: "Действие 1",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "После выбора одного из действий остальные не доступны",
|
||||
scenario: &Story{
|
||||
Places: []*Place{
|
||||
{
|
||||
Code: "Ы",
|
||||
Name: "Название точки",
|
||||
Text: "Текст точки.",
|
||||
Doors: []*Door{
|
||||
{
|
||||
Code: "Ы-1",
|
||||
Name: "Действие 1",
|
||||
},
|
||||
{
|
||||
Code: "Ы-2",
|
||||
Name: "Действие 1",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Code: "Ы-1",
|
||||
Name: "Название точки",
|
||||
Text: "Текст точки.",
|
||||
Hidden: true,
|
||||
},
|
||||
{
|
||||
Code: "Ы-2",
|
||||
Name: "Название точки",
|
||||
Text: "Текст точки.",
|
||||
Hidden: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
codes: []string{"Ы", "Ы-1", "Ы-2", "Ы", "Ы-2"},
|
||||
want: &Story{
|
||||
Places: []*Place{
|
||||
{
|
||||
Code: "Ы",
|
||||
Name: "Название точки",
|
||||
Text: "Текст точки.",
|
||||
},
|
||||
{
|
||||
Code: "Ы-1",
|
||||
Name: "Название точки",
|
||||
Text: "Текст точки.",
|
||||
},
|
||||
{
|
||||
Code: "Ы-2",
|
||||
Name: "Не найдено",
|
||||
Text: "Такой точки не существует.",
|
||||
},
|
||||
{
|
||||
Code: "Ы",
|
||||
Name: "Название точки",
|
||||
Text: "Текст точки.",
|
||||
},
|
||||
{
|
||||
Code: "Ы-2",
|
||||
Name: "Не найдено",
|
||||
Text: "Такой точки не существует.",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Если ключей не хватает то скрытые двери не видим",
|
||||
scenario: &Story{
|
||||
Places: []*Place{
|
||||
{
|
||||
Code: "Ы-1",
|
||||
Name: "Название точки",
|
||||
Text: "Текст точки.",
|
||||
Keys: []*Key{
|
||||
{
|
||||
Name: "ключ 1",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Code: "Ы",
|
||||
Name: "Название точки",
|
||||
Text: "Текст точки.",
|
||||
Doors: []*Door{
|
||||
{
|
||||
Code: "Д",
|
||||
Name: "Действие",
|
||||
Keys: []*Key{
|
||||
{
|
||||
Name: "ключ 1",
|
||||
},
|
||||
{
|
||||
Name: "ключ 2",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
codes: []string{"Ы-1", "Ы"},
|
||||
want: &Story{
|
||||
Places: []*Place{
|
||||
{
|
||||
Code: "Ы-1",
|
||||
Name: "Название точки",
|
||||
Text: "Текст точки.",
|
||||
},
|
||||
{
|
||||
Code: "Ы",
|
||||
Name: "Название точки",
|
||||
Text: "Текст точки.",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Собираем ключи и видим скрытые двери",
|
||||
scenario: &Story{
|
||||
Places: []*Place{
|
||||
{
|
||||
Code: "Ы-1",
|
||||
Name: "Название точки",
|
||||
Text: "Текст точки.",
|
||||
Keys: []*Key{
|
||||
{
|
||||
Name: "ключ 1",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Code: "Ы-2",
|
||||
Name: "Название точки",
|
||||
Text: "Текст точки.",
|
||||
Keys: []*Key{
|
||||
{
|
||||
Name: "ключ 2",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Code: "Ы",
|
||||
Name: "Название точки",
|
||||
Text: "Текст точки.",
|
||||
Doors: []*Door{
|
||||
{
|
||||
Code: "Д",
|
||||
Name: "Действие",
|
||||
Keys: []*Key{
|
||||
{
|
||||
Name: "ключ 1",
|
||||
},
|
||||
{
|
||||
Name: "ключ 2",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
codes: []string{"Ы-1", "Ы-2", "Ы"},
|
||||
want: &Story{
|
||||
Places: []*Place{
|
||||
{
|
||||
Code: "Ы-1",
|
||||
Name: "Название точки",
|
||||
Text: "Текст точки.",
|
||||
},
|
||||
{
|
||||
Code: "Ы-2",
|
||||
Name: "Название точки",
|
||||
Text: "Текст точки.",
|
||||
},
|
||||
{
|
||||
Code: "Ы",
|
||||
Name: "Название точки",
|
||||
Text: "Текст точки.",
|
||||
Doors: []*Door{
|
||||
{
|
||||
Code: "Д",
|
||||
Name: "Действие",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got := NewStory().GetStory(tt.scenario, tt.codes)
|
||||
assert.Equal(t, got, tt.want)
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user