Give packs an identity so create can refuse missing deps and load in a stable order.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -57,6 +57,20 @@ public class CatalogLoaderTests
|
||||
Assert.Contains(log.Warnings, warning => warning.Contains("Sit") && warning.Contains("addon"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void UnlabelledDef_WarnsButLoads()
|
||||
{
|
||||
var log = new RecordingLog();
|
||||
var catalog = _loader.Load(
|
||||
[CatalogLoader.CorePackId],
|
||||
[PackDocuments.Def(CatalogLoader.CorePackId, "things", "lamp", """{ "defName": "Lamp", "actions": [] }""")],
|
||||
log);
|
||||
|
||||
Assert.True(catalog.Things.ContainsKey("Lamp"));
|
||||
Assert.Equal("Lamp", catalog.Label("ru", catalog.Things["Lamp"]));
|
||||
Assert.Contains(log.Warnings, warning => warning.Contains("Lamp", StringComparison.Ordinal));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Text_FallsBackToTheKeyWhenMissing()
|
||||
{
|
||||
|
||||
@@ -21,6 +21,9 @@ internal static class PackDocuments
|
||||
public static ContentDocument Map(string packId, string jsonc) =>
|
||||
new(packId, "maps/default.jsonc", jsonc);
|
||||
|
||||
public static ContentDocument Manifest(string packId, string jsonc) =>
|
||||
new(packId, "pack.jsonc", jsonc);
|
||||
|
||||
public static IReadOnlyList<ContentDocument> FromDirectory(string packId, string packRoot)
|
||||
{
|
||||
var documents = new List<ContentDocument>();
|
||||
|
||||
@@ -0,0 +1,114 @@
|
||||
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<string, PackManifest>(StringComparer.OrdinalIgnoreCase)
|
||||
{
|
||||
[CatalogLoader.CorePackId] = PackManifest.Empty,
|
||||
["furniture"] = PackManifest.Parse("furniture", """{ "version": "1", "requires": ["base"] }"""),
|
||||
};
|
||||
|
||||
var ex = Assert.Throws<PackDependencyException>(() => 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<string, PackManifest>(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<string, PackManifest>(StringComparer.OrdinalIgnoreCase)
|
||||
{
|
||||
[CatalogLoader.CorePackId] = PackManifest.Empty,
|
||||
["left"] = PackManifest.Parse("left", """{ "requires": ["right"] }"""),
|
||||
["right"] = PackManifest.Parse("right", """{ "requires": ["left"] }"""),
|
||||
};
|
||||
|
||||
var ex = Assert.Throws<PackDependencyException>(() => 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);
|
||||
}
|
||||
}
|
||||
@@ -115,6 +115,7 @@ public class VanillaCoreTests
|
||||
keys.AddRange(Names(catalog.DayFrames.Values));
|
||||
keys.AddRange(Names(catalog.Holidays.Values));
|
||||
keys.AddRange(Names(catalog.Behavior.Values));
|
||||
keys.AddRange(catalog.PackIds);
|
||||
|
||||
// Derived in code, so no def carries them.
|
||||
keys.Add(BodyBuilds.Attribute);
|
||||
|
||||
Reference in New Issue
Block a user