tests/SmartPort/Parser/CompiledFixtureTests.cs
using HumanoidRetargeter.Editor;
using HumanoidRetargeter.Target;
using Xunit;
namespace SmartPort.Parser.Tests;
public sealed class CompiledFixtureFactAttribute : FactAttribute
{
public CompiledFixtureFactAttribute()
{
if (string.IsNullOrEmpty(Environment.GetEnvironmentVariable("HR_SMART_PORT_FIXTURE")))
Skip = "Set HR_SMART_PORT_FIXTURE to an installed sboxmp.frank_mp package directory.";
}
}
public class CompiledFixtureTests
{
[CompiledFixtureFact]
public void EmbeddedRecoveryKeepsSequencesEventsAndActualGraph()
{
var fixture = Environment.GetEnvironmentVariable("HR_SMART_PORT_FIXTURE")!;
var output = Path.Combine(Path.GetTempPath(), "hr-smart-port-parser-" + Guid.NewGuid().ToString("N"));
var paths = Directory.GetFiles(fixture, "*_c", SearchOption.AllDirectories)
.ToDictionary(p => Path.GetRelativePath(fixture, p)[..^2].Replace('\\', '/'), p => p, StringComparer.OrdinalIgnoreCase);
const string model = "models/player/human/frank_mp.vmdl";
const string graph = "models/player/mplayer/mplayer_animgraph.vanmgrph";
// Leave artifacts outside the source tree for native compiler verification.
var recovered = CompiledAssetRecovery.Recover(paths[model], model, output, "recovered", paths, default);
Directory.CreateDirectory(output);
File.WriteAllText(Path.Combine(output, "recovered.vmdl"), recovered);
var graphText = CompiledAssetRecovery.Recover(paths[graph], graph, output, "recovered", paths, default);
var copiedGraph = StockAnimationGraph.CopyForModel(graphText, "recovered/model.vmdl");
File.WriteAllText(Path.Combine(output, "recovered.vanmgrph"), copiedGraph);
var doc = Kv3.Parse(recovered);
var root = (KvObject)((KvObject)doc.Root)["rootNode"];
var children = (KvArray)root["children"];
var animations = children.Items.OfType<KvObject>().Single(n => n["_class"] is KvString s && s.Value == "AnimationList");
Assert.Equal(391, CountClips(animations));
Assert.Contains("AnimEvent", recovered);
Assert.Contains("CAnimationGraph", copiedGraph);
Assert.Contains("recovered/model.vmdl", copiedGraph);
Assert.Equal(398, Directory.GetFiles(output, "*.dmx", SearchOption.AllDirectories).Length);
Assert.DoesNotContain("AnimIncludeModel", recovered);
}
static int CountClips(KvObject node) =>
(node["_class"] is KvString s && s.Value == "AnimFile" ? 1 : 0)
+ (node.GetOrNull("children") is KvArray a ? a.Items.OfType<KvObject>().Sum(CountClips) : 0);
}