using Friflo.Engine.ECS; using MrGameEng.Inspector; using Xunit; namespace MrGameEng.Inspector.Tests; public class EcsInspectorTests { private enum Mode { Idle, Run, } private struct Probe : IComponent { public int Count; public bool Active; public Mode State; } private struct Marker : IComponent { public int Value; } [Fact] public void Archetypes_GroupsEntitiesByComponentSet() { var store = new EntityStore(); store.CreateEntity(new Probe { Count = 1 }); store.CreateEntity(new Probe { Count = 2 }); store.CreateEntity(new Marker { Value = 9 }); var inspector = new EcsInspector(store); var rows = inspector.Archetypes(); var probeRow = Single(rows, r => r.Signature.Contains("Probe")); Assert.Equal(2, probeRow.Count); Assert.Contains(rows, r => r.Signature.Contains("Marker") && r.Count == 1); } [Fact] public void EntitiesOf_ReturnsIdsOfArchetype() { var store = new EntityStore(); var a = store.CreateEntity(new Probe { Count = 1 }); var b = store.CreateEntity(new Probe { Count = 2 }); var inspector = new EcsInspector(store); var probeRow = Single(inspector.Archetypes(), r => r.Signature.Contains("Probe")); var ids = inspector.EntitiesOf(probeRow.Index); Assert.Contains(a.Id, ids); Assert.Contains(b.Id, ids); Assert.Equal(2, ids.Count); } [Fact] public void Inspect_ReturnsComponentFields() { var store = new EntityStore(); var entity = store.CreateEntity( new Probe { Count = 5, Active = true, State = Mode.Run, } ); var inspector = new EcsInspector(store); var view = Single(inspector.Inspect(entity.Id), c => c.TypeName == "Probe"); Assert.Equal("5", Field(view, "Count").Value); Assert.Equal("true", Field(view, "Active").Value); Assert.Equal("Run", Field(view, "State").Value); } [Fact] public void SetField_WritesValueBackToEntity() { var store = new EntityStore(); var entity = store.CreateEntity(new Probe { Count = 5 }); var inspector = new EcsInspector(store); var ok = inspector.SetField(entity.Id, typeof(Probe), "Count", "42"); Assert.True(ok); Assert.Equal(42, entity.GetComponent().Count); } [Fact] public void SetField_RejectsInvalidValue() { var store = new EntityStore(); var entity = store.CreateEntity(new Probe { Count = 5 }); var inspector = new EcsInspector(store); Assert.False(inspector.SetField(entity.Id, typeof(Probe), "Count", "bad")); Assert.Equal(5, entity.GetComponent().Count); } [Fact] public void Search_FiltersArchetypesBySignature() { var store = new EntityStore(); store.CreateEntity(new Probe()); store.CreateEntity(new Marker()); var inspector = new EcsInspector(store); inspector.SetSearch("Marker"); var rows = inspector.Archetypes(); Assert.Single(rows); Assert.Contains("Marker", rows[0].Signature); } private static T Single(IReadOnlyList items, Func predicate) { foreach (var item in items) { if (predicate(item)) { return item; } } throw new Xunit.Sdk.XunitException("no matching item"); } private static FieldRow Field(ComponentView view, string name) { foreach (var row in view.Fields) { if (row.Name == name) { return row; } } throw new Xunit.Sdk.XunitException($"field {name} not found"); } }