Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MonoModder support multi mods patch same method #208

Open
wants to merge 5 commits into
base: reorganize
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Add unit test about MonoModPatch
  • Loading branch information
MikiraSora committed Dec 30, 2024
commit 86fb803813b837a58a79af0395c068eb1b1b3090
114 changes: 114 additions & 0 deletions src/MonoMod.UnitTest/MomoModPatch/MonoModPatchTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
using System;
using System.IO;
using System.Reflection;
using Xunit;
using Xunit.Abstractions;

namespace MonoMod.UnitTest.MomoModPatch
{
public class MonoModPatchTest : TestBase
{
private readonly string aModDllPath;
private readonly string bModDllPath;
private readonly string targetDllPath;

public MonoModPatchTest(ITestOutputHelper helper) : base(helper)
{
var resourcePath = Path.Combine(Path.GetDirectoryName(typeof(MonoModPatchTest).Assembly.Location),
"MomoModPatch", "Resources");

//ILSpy can view source code.
targetDllPath = Path.Combine(resourcePath, "DemoLib.dll");
aModDllPath = Path.Combine(resourcePath, "DemoLib.ModA.mm.dll");
bModDllPath = Path.Combine(resourcePath, "DemoLib.ModB.mm.dll");
}

private MonoModder BuildMonoModder(string targetDllPath, params string[] modDllPaths)
{
var modder = new MonoModder();
modder.InputPath = targetDllPath;
modder.MissingDependencyThrow = false; //disable because target and mods built by .netfx35

modder.Read();

foreach (var modDllPath in modDllPaths)
{
modder.ReadMod(modDllPath);
}

return modder;
}

private Assembly LoadPatchedAssembly(MonoModder modder)
{
var filePath = Path.GetTempFileName() + ".dll";
modder.Write(default, filePath);
//Console.WriteLine($"patched dll saved at {filePath}");
var patchedAssembly = Assembly.LoadFile(filePath);
return patchedAssembly;
}

private object CreateMyLibObject(MonoModder modder, out Type type)
{
//patch by ModA
modder.MapDependencies();
modder.AutoPatch();

//load patched
var patchedAssembly = LoadPatchedAssembly(modder);

type = patchedAssembly.GetType("DemoLib.MyLib");
var obj = Activator.CreateInstance(type);

Assert.NotNull(obj);
return obj;
}

[Fact]
public void OneModNormalTest()
{
//patch by ModA
using var modder = BuildMonoModder(targetDllPath, aModDllPath);
var obj = CreateMyLibObject(modder, out var type);

//do asset
var ctorResult = type.GetProperty("CtorResult").GetValue(obj) as string;
Assert.Equal(ctorResult, "50A");

var calcResult = (int)type.GetMethod("Calculate").Invoke(obj, new object[] {1, 5});
Assert.Equal(calcResult, (1 + 5) * 10);
}

[Fact]
public void TwoModButNotCombineTest()
{
//patch by ModA and ModB
using var modder = BuildMonoModder(targetDllPath, aModDllPath, bModDllPath);
//modder.CombineSameMethodMultiModPatches = false; //default false
var obj = CreateMyLibObject(modder, out var type);

//do asset
var ctorResult = type.GetProperty("CtorResult").GetValue(obj) as string;
Assert.Contains(ctorResult, new[] {"50A", "B50"});

var calcResult = (int)type.GetMethod("Calculate").Invoke(obj, new object[] {1, 5});
Assert.Contains(calcResult, new[] {(1 + 5) * 10, 10000000 + 1 + 5});
}

[Fact]
public void TwoModButCombineTest()
{
//patch by ModA and ModB
using var modder = BuildMonoModder(targetDllPath, aModDllPath, bModDllPath);
modder.CombineSameMethodMultiModPatches = true; //combine
var obj = CreateMyLibObject(modder, out var type);

//do asset
var ctorResult = type.GetProperty("CtorResult").GetValue(obj) as string;
Assert.Equal(ctorResult, "B50A");

var calcResult = (int)type.GetMethod("Calculate").Invoke(obj, new object[] {1, 5});
Assert.Contains(calcResult, new[] {(1 + 5) * 10 + 1000000, (1000000 + 1 + 5) * 10});
}
}
}
Binary file not shown.
Empty file.
Binary file not shown.
Empty file.
Binary file not shown.
Empty file.
20 changes: 20 additions & 0 deletions src/MonoMod.UnitTest/MonoMod.UnitTest.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -76,5 +76,25 @@
<PackageReference Include="Microsoft.TestPlatform.TestHost" Version="17.3.3" />
<PackageReference Include="Microsoft.TestPlatform.ObjectModel" Version="17.3.3" />
</ItemGroup>
<ItemGroup>
<None Update="MomoModPatch\Resources\DemoLib.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="MomoModPatch\Resources\DemoLib.pdb">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="MomoModPatch\Resources\DemoLib.ModA.mm.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="MomoModPatch\Resources\DemoLib.ModA.mm.pdb">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="MomoModPatch\Resources\DemoLib.ModB.mm.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="MomoModPatch\Resources\DemoLib.ModB.mm.pdb">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>

</Project>
Loading