package preset import ( "strings" "testing" "github.com/mrleo1nid/pzmanager/internal/pzconfig" ) // sandboxCFG повторяет то, как пресет выглядит у игры: комментарии с решёткой, // расшифровки значений со знаком равенства внутри и точки вместо вложенности. const sandboxCFG = `Version=6 # Changing this also sets the "Population Multiplier" in Advanced Zombie Options. Default = Normal -- 1 = Insane -- 4 = Normal Zombies=4 # Controls whether some randomization is applied. ZombieVoronoiNoise=true DayLength=3 XpMultiplier=1.5 StatsDecrease=3 Temperature=3 Rain=3 LootRespawn=1 FoodRotSpeed=5 Nutrition=true WorldItemRemovalList=Base.Hat, Base.Glasses ZombieLore.Speed=2 ZombieLore.Strength=2 KDOT.SpecialVehicleChance=4.0 ` func TestParseSandboxPreset(t *testing.T) { p := ParseSandboxPreset([]byte(sandboxCFG)) if p.Version != "6" { t.Errorf("версия = %q", p.Version) } // Строки «-- 4 = Normal» тоже содержат знак равенства, и параметрами они // не являются. for key := range p.Values { if !sandboxKeyRe.MatchString(key) { t.Errorf("в значения попал мусор: %q", key) } } want := map[string]string{ "Zombies": "4", "ZombieVoronoiNoise": "true", "XpMultiplier": "1.5", "ZombieLore.Speed": "2", "KDOT.SpecialVehicleChance": "4.0", "WorldItemRemovalList": `"Base.Hat, Base.Glasses"`, } for key, value := range want { if got := p.Values[key]; got != value { t.Errorf("%s = %q, ожидалось %q", key, got, value) } } if _, ok := p.Values["Version"]; ok { t.Error("Version не должен попадать в значения: у файла сервера свой VERSION") } } // Сгенерированный файл читает и сама игра, и парсер панели — второе проверить // можно прямо здесь. func TestSandboxPresetLuaRoundTrip(t *testing.T) { p := ParseSandboxPreset([]byte(sandboxCFG)) lua := p.Lua() parsed := pzconfig.ParseSandbox(lua) if got, ok := parsed.Get("VERSION"); !ok || got != "6" { t.Errorf("VERSION = %q (%v)", got, ok) } for key, want := range p.Values { got, ok := parsed.Get(key) if !ok { t.Errorf("параметр %s не читается обратно:\n%s", key, lua) continue } if got != want { t.Errorf("%s = %q, ожидалось %q", key, got, want) } } // Вложенность должна быть настоящей: «ZombieLore.Speed = 2» внутри таблицы // Lua не примет. if strings.Contains(string(lua), "ZombieLore.Speed =") { t.Errorf("точка осталась в имени параметра:\n%s", lua) } } // Пути бывают глубже одного уровня — файл должен остаться разбираемым. func TestSandboxPresetDeepPath(t *testing.T) { p := ParseSandboxPreset([]byte("A.B.C=7\nZombies=1\nDayLength=3\nRain=2\n")) parsed := pzconfig.ParseSandbox(p.Lua()) if got, ok := parsed.Get("A.B.C"); !ok || got != "7" { t.Fatalf("A.B.C = %q (%v)\n%s", got, ok, p.Lua()) } } func TestLooksLikeSandboxPreset(t *testing.T) { if !looksLikeSandboxPreset([]byte(sandboxCFG)) { t.Error("пресет песочницы не опознан") } // В том же архиве лежат списки модов и настройки папок с тем же // расширением .cfg. modFolders := "version=2\nnext=15\nfolder=3|1|4D,61,70,73\n" if looksLikeSandboxPreset([]byte(modFolders)) { t.Error("настройки папок приняты за пресет песочницы") } modList := "!fav!:\nSophie-42-v2:ModA;ModB;ModC\n" if looksLikeSandboxPreset([]byte(modList)) { t.Error("список модов принят за пресет песочницы") } }