using AcDream.Core.Plugins; using AcDream.Plugin.Abstractions; namespace AcDream.Core.Tests.Plugins; public class PluginLoaderTests { private static string FixturePluginPath() { // walk up from the test bin dir to the repo root, then into the fixture's build output var baseDir = AppContext.BaseDirectory; var configuration = new DirectoryInfo(baseDir).Parent!.Name; // Debug / Release var repoRoot = FindRepoRoot(baseDir); return Path.Combine( repoRoot, "tests", "AcDream.Core.Tests.Fixtures.HelloPlugin", "bin", configuration, "net10.0", "AcDream.Core.Tests.Fixtures.HelloPlugin.dll"); } private static string FindRepoRoot(string startDir) { var dir = new DirectoryInfo(startDir); while (dir is not null && !File.Exists(Path.Combine(dir.FullName, "AcDream.slnx"))) dir = dir.Parent; return dir?.FullName ?? throw new InvalidOperationException("repo root not found"); } private sealed class StubHost : IPluginHost { public IPluginLogger Log { get; } = new StubLogger(); } private sealed class StubLogger : IPluginLogger { public void Info(string message) { } public void Warn(string message) { } public void Error(string message, Exception? exception = null) { } } [Fact] public void Load_FixtureDll_InstantiatesPluginAndCallsInitialize() { var dllPath = FixturePluginPath(); Assert.True(File.Exists(dllPath), $"fixture dll not found: {dllPath}"); var host = new StubHost(); var manifest = new PluginManifest( Id: "acdream.test.hello", DisplayName: "Hello", Version: "0.0.1", EntryDll: Path.GetFileName(dllPath), ApiVersion: 1, Dependencies: Array.Empty()); var loaded = PluginLoader.Load( pluginDirectory: Path.GetDirectoryName(dllPath)!, manifest: manifest, host: host); Assert.True(loaded.Success); Assert.NotNull(loaded.Plugin); Assert.Equal("HelloPlugin", loaded.Plugin!.GetType().Name); } [Fact] public void Load_MissingDll_ReturnsFailure() { var host = new StubHost(); var manifest = new PluginManifest( Id: "x", DisplayName: "X", Version: "0.0.1", EntryDll: "nope.dll", ApiVersion: 1, Dependencies: Array.Empty()); var loaded = PluginLoader.Load("/does/not/exist", manifest, host); Assert.False(loaded.Success); Assert.NotNull(loaded.Error); } [Fact] public void Load_DllWithNoPluginImpl_ReturnsFailure() { // Use AcDream.Core.dll itself — it has no IAcDreamPlugin impl var coreDllDir = AppContext.BaseDirectory; var host = new StubHost(); var manifest = new PluginManifest( Id: "x", DisplayName: "X", Version: "0.0.1", EntryDll: "AcDream.Core.dll", ApiVersion: 1, Dependencies: Array.Empty()); var loaded = PluginLoader.Load(coreDllDir, manifest, host); Assert.False(loaded.Success); Assert.Contains("IAcDreamPlugin", loaded.Error!.Message); } }