using System;
using System.IO;
using System.Reflection;
using Xunit;
namespace TeslaConsole.DiffTests
{
///
/// Shared per-test-class fixture that spins up one child AppDomain per assembly
/// (original + recovered), each rooted at that assembly's own directory so the CLR
/// probes for any dependencies next to it. The Invoker proxy in each domain loads
/// and exercises that assembly.
///
public sealed class DifferentialFixture : IDisposable
{
private readonly AppDomain _originalDomain;
private readonly AppDomain _recoveredDomain;
public Invoker Original { get; }
public Invoker Recovered { get; }
public DifferentialFixture()
{
Assert.True(File.Exists(AssemblyPaths.OriginalExe),
"Original baseline not found: " + AssemblyPaths.OriginalExe);
Assert.True(File.Exists(AssemblyPaths.RecoveredExe),
"Recovered build not found (build TeslaConsole.csproj -c Release first): " +
AssemblyPaths.RecoveredExe);
_originalDomain = CreateDomain("Original", AssemblyPaths.OriginalExe);
_recoveredDomain = CreateDomain("Recovered", AssemblyPaths.RecoveredExe);
Original = CreateInvoker(_originalDomain, AssemblyPaths.OriginalExe);
Recovered = CreateInvoker(_recoveredDomain, AssemblyPaths.RecoveredExe);
}
private static AppDomain CreateDomain(string name, string exePath)
{
var setup = new AppDomainSetup
{
ApplicationBase = Path.GetDirectoryName(exePath),
};
return AppDomain.CreateDomain("TeslaDiff_" + name, null, setup);
}
private static Invoker CreateInvoker(AppDomain domain, string exePath)
{
// Probe directory = recovered output, which ships every dependency DLL.
string probeDir = Path.GetDirectoryName(AssemblyPaths.RecoveredExe);
return (Invoker)domain.CreateInstanceFromAndUnwrap(
typeof(Invoker).Assembly.Location,
typeof(Invoker).FullName,
false,
BindingFlags.Default,
null,
new object[] { exePath, probeDir },
null,
null);
}
/// Run a case in both domains and return (original, recovered).
public (string Original, string Recovered) RunBoth(string caseName, params string[] args)
{
return (Original.Run(caseName, args), Recovered.Run(caseName, args));
}
public void Dispose()
{
if (_originalDomain != null) AppDomain.Unload(_originalDomain);
if (_recoveredDomain != null) AppDomain.Unload(_recoveredDomain);
}
}
}