using System.Text.Json; using NUnit.Framework; using ShrinkSDK.Inspect; using Index = ShrinkSDK.Inspect.Index; public class IdentityTests { [TestCase("a", true)] [TestCase("b", false)] [TestCase("", false)] public void SnapshotNeedsMatchingVerifiedBuild(string build, bool accepted) { var path = Path.GetTempFileName(); try { File.WriteAllText(path, "{\"BuildId\":\"a\",\"Relations\":[{\"From\":\"type:Request\",\"To\":\"M:Handler.Run\",\"Kind\":\"handler\",\"Scope\":\"server\"}]}"); var index = new Index { BuildId = build }; InspectCommand.AttachSnapshot(index, path); Assert.That(index.Relations.Count, Is.EqualTo(accepted ? 1 : 0)); if (accepted) Assert.That(index.Relations[0].Evidence, Is.EqualTo("runtime-bound")); else Assert.That(index.Coverage, Is.Not.Empty); } finally { File.Delete(path); } } [Test] public async Task ChangedSourceInvalidatesRuntimeMerge() { var dir = Path.Combine(Path.GetTempPath(), "ShrinkInspectIdentity", Guid.NewGuid().ToString("N")); Directory.CreateDirectory(dir); try { var source = Path.Combine(dir, "A.cs"); File.WriteAllText(source, "class A {}"); var manifest = new CompilationManifest { Root = dir, BuildId = "a", Assemblies = [new() { Name = "A", Sources = [source] }], SourceTicks = new() { [source] = 0 } }; var path = Path.Combine(dir, "compilation.json"); File.WriteAllText(path, JsonSerializer.Serialize(manifest)); var index = new Index { Root = dir }; await SemanticIndex.Build(index, path, null); Assert.That(index.BuildId, Is.Empty); Assert.That(index.Coverage.Any(c => c.Contains("Stale"))); } finally { Directory.Delete(dir, true); } } [Test] public void MatchingSnapshotExposesBoundedStateItems() { var path = Path.GetTempFileName(); try { File.WriteAllText(path, """{"BuildId":"a","State":{"app":{"Fibers":[{"Name":"wait","Status":"Waiting"},{"Name":"ready","Status":"Active"}]}}} """); var index = new Index { BuildId = "a" }; InspectCommand.AttachSnapshot(index, path); Assert.That(index.RuntimeStates.Count, Is.EqualTo(2)); Assert.That(index.RuntimeStates[0].Value.GetProperty("Name").GetString(), Is.EqualTo("wait")); } finally { File.Delete(path); } } }