using Engine.Kernel.Diagnostics;
using Engine.Kernel.Events;
using Engine.Kernel.Plugins;
using Engine.Kernel.Scheduling;
using Engine.Kernel.Services;
using Engine.Kernel.World;
using Sandbox.Echo.Contracts;
namespace Engine.ConformanceHarness;
///
/// Closes the loop this whole exercise was for: a plugin loaded from a real
/// collectible ALC registers a system with Schedule, Schedule actually
/// invokes that cross-ALC delegate, and it correctly mutates a component
/// living in the Default-ALC-owned World. If PluginLoadContext resolved
/// Sandbox.Echo.Contracts incorrectly (a second, distinct copy instead of
/// deferring to the one this project references directly — see the note on
/// that ProjectReference in the .csproj), the Ping instance this test
/// constructs wouldn't be a Ping as far as EchoPlugin's Tick sees it, and
/// world.Query<Ping>() inside the plugin would find nothing.
///
public class PluginSystemTests
{
private static string PluginDirectory =>
Path.Combine(AppContext.BaseDirectory, "plugins", "sandbox.echo");
[Fact]
public void Loaded_Plugin_System_Runs_And_Mutates_A_Component_It_Declared()
{
var world = new GameWorld();
var schedule = new Schedule();
var host = new PluginHost(world, new ServiceRegistry(), schedule, new EventBus(), new Time());
var ping = world.CreateGameObject("Pinger").AddComponent();
var id = host.Load(PluginDirectory);
schedule.RunStage(Stage.Update, world);
schedule.RunStage(Stage.Update, world);
Assert.Equal(2, ping.Count);
host.Unload(id);
}
[Fact]
public void Unloading_The_Plugin_Stops_Its_System_From_Running()
{
var world = new GameWorld();
var schedule = new Schedule();
var host = new PluginHost(world, new ServiceRegistry(), schedule, new EventBus(), new Time());
var ping = world.CreateGameObject("Pinger").AddComponent();
var id = host.Load(PluginDirectory);
host.Unload(id);
schedule.RunStage(Stage.Update, world);
Assert.Equal(0, ping.Count);
}
[Fact]
public void Loading_A_Plugin_Publishes_PluginLoaded_With_Its_Id()
{
var world = new GameWorld();
var events = new EventBus();
var host = new PluginHost(world, new ServiceRegistry(), new Schedule(), events, new Time());
string? observedId = null;
events.Subscribe(e => observedId = e.PluginId);
var id = host.Load(PluginDirectory);
Assert.Equal("sandbox.echo", observedId);
host.Unload(id);
}
[Fact]
public void Unloading_A_Plugin_Publishes_PluginUnloaded_With_Its_Id()
{
var world = new GameWorld();
var events = new EventBus();
var host = new PluginHost(world, new ServiceRegistry(), new Schedule(), events, new Time());
var id = host.Load(PluginDirectory);
string? observedId = null;
events.Subscribe(e => observedId = e.PluginId);
host.Unload(id);
Assert.Equal("sandbox.echo", observedId);
}
}