namespace HSchool.Content.Tests; public class PackIdentityTests { [Fact] public void PackWithoutManifest_UsesIdAsLabelAndHasNoRequires() { var documents = new[] { PackDocuments.Def("addon", "traits", "shy", """{ "defName": "Shy", "abstract": true }"""), }; var manifest = PackManifest.FromDocuments("addon", documents); Assert.Equal(string.Empty, manifest.Version); Assert.Empty(manifest.Requires); Assert.Equal("addon", PackManifest.Label("addon", "ru", documents)); Assert.Equal("addon", PackManifest.Label("addon", "en", documents)); } [Fact] public void PackLabel_ComesFromTheRequestedLocale() { var documents = new[] { PackDocuments.Manifest(CatalogLoader.CorePackId, """{ "version": "1.0", "requires": [] }"""), PackDocuments.Locale(CatalogLoader.CorePackId, "ru", """{ "core": "Базовая игра" }"""), PackDocuments.Locale(CatalogLoader.CorePackId, "en", """{ "core": "Core" }"""), }; Assert.Equal("Базовая игра", PackManifest.Label(CatalogLoader.CorePackId, "ru", documents)); Assert.Equal("Core", PackManifest.Label(CatalogLoader.CorePackId, "en", documents)); Assert.Equal("1.0", PackManifest.FromDocuments(CatalogLoader.CorePackId, documents).Version); } [Fact] public void VanillaCore_HasManifestAndLocalizedName() { var root = Path.Combine(AppContext.BaseDirectory, "vanilla"); var documents = PackDocuments.FromDirectory(CatalogLoader.CorePackId, root); var manifest = PackManifest.FromDocuments(CatalogLoader.CorePackId, documents); Assert.False(string.IsNullOrWhiteSpace(manifest.Version)); Assert.Empty(manifest.Requires); Assert.Equal("Базовая игра", PackManifest.Label(CatalogLoader.CorePackId, "ru", documents)); Assert.Equal("Core", PackManifest.Label(CatalogLoader.CorePackId, "en", documents)); } } public class PackLoadOrderTests { [Fact] public void MissingRequirement_NamesTheMissingPack() { var selected = CatalogLoader.NormalizePackOrder(["furniture"]); var manifests = new Dictionary(StringComparer.OrdinalIgnoreCase) { [CatalogLoader.CorePackId] = PackManifest.Empty, ["furniture"] = PackManifest.Parse("furniture", """{ "version": "1", "requires": ["base"] }"""), }; var ex = Assert.Throws(() => PackLoadOrder.Resolve(selected, manifests)); Assert.Equal(PackDependencyException.MissingCode, ex.Code); Assert.Equal("base", ex.MissingPackId); Assert.Contains("base", ex.Message, StringComparison.Ordinal); } [Fact] public void DependencyListedAfterDependent_StillLoadsFirst() { var selected = CatalogLoader.NormalizePackOrder(["furniture", "base"]); Assert.Equal([CatalogLoader.CorePackId, "furniture", "base"], selected); var manifests = new Dictionary(StringComparer.OrdinalIgnoreCase) { [CatalogLoader.CorePackId] = PackManifest.Empty, ["furniture"] = PackManifest.Parse("furniture", """{ "requires": ["base"] }"""), ["base"] = PackManifest.Empty, }; var order = PackLoadOrder.Resolve(selected, manifests); Assert.Equal([CatalogLoader.CorePackId, "base", "furniture"], order); } [Fact] public void Cycle_IsRejected() { var selected = CatalogLoader.NormalizePackOrder(["left", "right"]); var manifests = new Dictionary(StringComparer.OrdinalIgnoreCase) { [CatalogLoader.CorePackId] = PackManifest.Empty, ["left"] = PackManifest.Parse("left", """{ "requires": ["right"] }"""), ["right"] = PackManifest.Parse("right", """{ "requires": ["left"] }"""), }; var ex = Assert.Throws(() => PackLoadOrder.Resolve(selected, manifests)); Assert.Equal(PackDependencyException.CycleCode, ex.Code); Assert.Null(ex.MissingPackId); } [Fact] public void PlayerOrder_IsKeptWhenRequiresDoNotConstrainIt() { var selected = CatalogLoader.NormalizePackOrder(["zebra", "apple"]); var manifests = PackLoadOrder.ManifestsFrom(selected, []); var order = PackLoadOrder.Resolve(selected, manifests); Assert.Equal([CatalogLoader.CorePackId, "zebra", "apple"], order); } }