Skip to content

Commit

Permalink
Reorganize reflection code and add tests.
Browse files Browse the repository at this point in the history
Reflection tests require each test fixture to run in its own AppDomain, so each game's assemblies don't interfere. It would be better to split this into two test assemblies now.
  • Loading branch information
Gwindalmir committed Oct 12, 2021
1 parent 902c864 commit b00f8ea
Show file tree
Hide file tree
Showing 13 changed files with 580 additions and 141 deletions.
10 changes: 5 additions & 5 deletions MEWorkshopTool/MedievalGame.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,11 @@ public override int InitGame(string[] args)
var appInformation = new VRage.Engine.AppInformation("Medieval Engineers", Medieval.MyMedievalGame.ME_VERSION, "", "", "", Medieval.MyMedievalGame.VersionString);
var vrageCore = new VRage.Engine.VRageCore(appInformation, true);
var configuration = VRage.Engine.Util.CoreProgram.LoadParameters("MEWT.config");
vrageCore.GetType().GetMethod("LoadSystems", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)?.Invoke(vrageCore, new[] { configuration });
vrageCore.GetType().GetField("m_state", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)?.SetValue(vrageCore, 1);
vrageCore.GetType().GetMethod("InitSystems", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)?.Invoke(vrageCore, new object[] { configuration.SystemConfiguration, true });
vrageCore.GetType().GetMethod("LoadMetadata", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)?.Invoke(vrageCore, new[] { configuration });
vrageCore.GetType().GetMethod("InitSystems", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)?.Invoke(vrageCore, new object[] { configuration.SystemConfiguration, false });
ReflectionHelper.ReflectVRageCoreMethod("LoadSystems")?.Invoke(vrageCore, new[] { configuration });
ReflectionHelper.ReflectVRageCoreField("m_state")?.SetValue(vrageCore, 1);
ReflectionHelper.ReflectVRageCoreMethod("InitSystems")?.Invoke(vrageCore, new object[] { configuration.SystemConfiguration, true });
ReflectionHelper.ReflectVRageCoreMethod("LoadMetadata")?.Invoke(vrageCore, new[] { configuration });
ReflectionHelper.ReflectVRageCoreMethod("InitSystems")?.Invoke(vrageCore, new object[] { configuration.SystemConfiguration, false });

m_steamService = new MySteamService();
((MySteamService)(m_steamService)).Init(new VRage.Steam.MySteamService.Parameters() { Server = MySandboxGame.IsDedicated, AppId = AppId });
Expand Down
143 changes: 143 additions & 0 deletions Tests/Common/ReflectionTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
extern alias me;
using NUnit.Framework;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using M = me::Phoenix.WorkshopTool;

namespace Phoenix.WorkshopTool.Tests.Common
{
[TestFixture]
[RunInApplicationDomain]
[Category("NoSteam")]
public abstract class ReflectionTests : GameTestBase
{
[Test]
public void PublishItemBlockingTest()
{
MethodInfo method;

if(ParameterPrefix == "SE")
method = typeof(WorkshopHelper).GetMethod("ReflectPublishItemBlocking", BindingFlags.Static | BindingFlags.NonPublic);
else
method = typeof(M.WorkshopHelper).GetMethod("ReflectPublishItemBlocking", BindingFlags.Static | BindingFlags.NonPublic);

Assert.NotNull(method);

var result = method.Invoke(null, new object[] { });
Assert.NotNull(result);
}

[Test]
public void LoadScriptsTest()
{
MethodInfo method;

if (ParameterPrefix == "SE")
method = typeof(WorkshopHelper).GetMethod("ReflectLoadScripts", BindingFlags.Static | BindingFlags.NonPublic);
else
method = typeof(M.WorkshopHelper).GetMethod("ReflectLoadScripts", BindingFlags.Static | BindingFlags.NonPublic);

Assert.NotNull(method);

var result = method.Invoke(null, new object[] { });
Assert.NotNull(result);
}

[TestCase(new object[] { typeof(string), typeof(string) })]
[TestCase(new object[] { typeof(string), typeof(string), typeof(Predicate<string>) })]
public void CopyAllTest(object[] types)
{
MethodInfo method;

if (ParameterPrefix == "SE")
method = ReflectionHelper.ReflectFileCopy(types.Cast<Type>().ToArray());
else
method = M.ReflectionHelper.ReflectFileCopy(types.Cast<Type>().ToArray());

Assert.IsNotNull(method);
}

[Test]
public void UpdatePublishedItemTest()
{
MethodInfo method;

if (ParameterPrefix == "SE")
method = WorkshopHelper.ReflectSteamWorkshopItemPublisherMethod("UpdatePublishedItem", BindingFlags.Instance | BindingFlags.NonPublic);
else
method = M.WorkshopHelper.ReflectSteamWorkshopItemPublisherMethod("UpdatePublishedItem", BindingFlags.Instance | BindingFlags.Public);

Assert.IsNotNull(method);
}

[TestCase("SubmitItemUpdateResult")]
public void ItemPublisherMethodTest(string name)
{
MethodInfo method;

if (ParameterPrefix == "SE")
method = WorkshopHelper.ReflectSteamWorkshopItemPublisherMethod(name);
else
method = M.WorkshopHelper.ReflectSteamWorkshopItemPublisherMethod(name);

Assert.IsNotNull(method);
}

[TestCase("m_steamService")]
[TestCase("m_submitItemUpdateResult")]
public void ItemPublisherFieldTest(string name)
{
FieldInfo method;

if (ParameterPrefix == "SE")
method = WorkshopHelper.ReflectSteamWorkshopItemPublisherField(name);
else
method = M.WorkshopHelper.ReflectSteamWorkshopItemPublisherField(name);

Assert.IsNotNull(method);
}

[TestCase("SteamUGC")]
public void ItemPublisherPropertyTest(string name)
{
PropertyInfo method;

if (ParameterPrefix == "SE")
method = WorkshopHelper.ReflectSteamWorkshopItemPublisherProperty(name);
else
method = M.WorkshopHelper.ReflectSteamWorkshopItemPublisherProperty(name);

Assert.IsNotNull(method);
}

[Test]
public void SteamAppRunningTest()
{
MethodInfo method;

if (ParameterPrefix == "SE")
method = ReflectionHelper.ReflectSteamRestartApp();
else
method = M.ReflectionHelper.ReflectSteamRestartApp();

Assert.IsNotNull(method);
}

[Test]
public void InitSteamWorkshopTest()
{
MethodInfo method;

if (ParameterPrefix == "SE")
method = WorkshopHelper.ReflectInitSteamWorkshop();
else
method = M.WorkshopHelper.ReflectInitSteamWorkshop();

Assert.IsNotNull(method);
}
}
}
62 changes: 62 additions & 0 deletions Tests/GameTestBase.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
extern alias me;
using NUnit.Framework;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace Phoenix.WorkshopTool.Tests
{
/// <summary>
/// Represents a test fixture that requires the game assemblies.
/// </summary>
[TestFixture]
public abstract class GameTestBase
{
#region Base Setup
protected string _previousDirectory;

public GameTestBase()
{
}

internal abstract string ParameterPrefix { get; }

[OneTimeSetUp]
public virtual void OneTimeSetup()
{
if (AppDomainRunner.IsNotInTestAppDomain)
{
_previousDirectory = Environment.CurrentDirectory;
Environment.CurrentDirectory = TestContext.Parameters[$"{ParameterPrefix}.Install"];
}
else
{
if (ParameterPrefix == "ME")
AppDomain.CurrentDomain.AssemblyResolve += me::Phoenix.WorkshopTool.GameBase.CurrentDomain_AssemblyResolve;
else
AppDomain.CurrentDomain.AssemblyResolve += GameBase.CurrentDomain_AssemblyResolve;
}
}

[OneTimeTearDown]
public virtual void OneTimeTearDown()
{
if (AppDomainRunner.IsNotInTestAppDomain)
{
Environment.CurrentDirectory = _previousDirectory;
}
else
{
if (ParameterPrefix == "ME")
AppDomain.CurrentDomain.AssemblyResolve -= me::Phoenix.WorkshopTool.GameBase.CurrentDomain_AssemblyResolve;
else
AppDomain.CurrentDomain.AssemblyResolve -= GameBase.CurrentDomain_AssemblyResolve;
}
}
#endregion Base Setup
}
}
16 changes: 3 additions & 13 deletions Tests/IntegrationBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,15 @@ namespace Phoenix.WorkshopTool.Tests
[TestFixture]
[RequiresThread]
[NonParallelizable]
public abstract class IntegrationBase
public abstract class IntegrationBase : GameTestBase
{
#region Base Setup
protected string[] _extraArguments = new string[0];
protected string _previousDirectory;

public IntegrationBase()
{
}

internal abstract string ParameterPrefix { get; }
internal abstract string GameName { get; }

protected int LaunchMain(string[] args)
Expand Down Expand Up @@ -57,24 +55,16 @@ public static void SetEntryAssembly(Assembly assembly)
domainManagerField.SetValue(domain, manager);
}

[OneTimeSetUp]
public virtual void OneTimeSetup()
public override void OneTimeSetup()
{
_previousDirectory = Environment.CurrentDirectory;
Environment.CurrentDirectory = TestContext.Parameters[$"{ParameterPrefix}.Install"];
base.OneTimeSetup();

if (TestContext.Parameters.Exists($"{ParameterPrefix}.AppData"))
{
_extraArguments = new[] { "--appdata", TestContext.Parameters[$"{ParameterPrefix}.AppData"] };
}

}

[OneTimeTearDown]
public virtual void OneTimeTearDown()
{
Environment.CurrentDirectory = _previousDirectory;
}
#endregion Base Setup

#region Common Tests
Expand Down
62 changes: 62 additions & 0 deletions Tests/ME/ReflectionTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
extern alias me;

using NUnit.Framework;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using M = me::Phoenix.WorkshopTool;


namespace Phoenix.WorkshopTool.Tests.ME
{
[TestFixture]
[RunInApplicationDomain]
[Category("NoSteam")]
public class ReflectionTests : Common.ReflectionTests
{
internal override string ParameterPrefix => "ME";

[Test]
public void PublishSuccessTest()
{
dynamic method = typeof(M.WorkshopHelper).GetMethod("ReflectPublishSuccess", BindingFlags.Static | BindingFlags.NonPublic);

Assert.NotNull(method);

var result = method.Invoke(null, new object[] { });
Assert.NotNull(result);
}

[Test]
public void CompileMessagesTest()
{
var method = typeof(M.WorkshopHelper).GetMethod("ReflectCompileMessages", BindingFlags.Static | BindingFlags.NonPublic);

Assert.NotNull(method);

var result = method.Invoke(null, new object[] { });
Assert.NotNull(result);
}

[TestCase("LoadSystems")]
[TestCase("InitSystems")]
[TestCase("LoadMetadata")]
public void VRageCoreMethodTest(string name)
{
var method = M.ReflectionHelper.ReflectVRageCoreMethod(name);

Assert.NotNull(method);
}

[TestCase("m_state")]
public void VRageCoreFieldTest(string name)
{
var field = M.ReflectionHelper.ReflectVRageCoreField(name);

Assert.NotNull(field);
}
}
}
39 changes: 39 additions & 0 deletions Tests/SE/ReflectionTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
using NUnit.Framework;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace Phoenix.WorkshopTool.Tests.SE
{
[TestFixture]
[RunInApplicationDomain]
[Category("NoSteam")]
public class ReflectionTests : Common.ReflectionTests
{
internal override string ParameterPrefix => "SE";

[Test]
public void ToServiceTest()
{
var method = WorkshopHelper.ReflectToService();
Assert.IsNotNull(method);
}

[Test]
public void ToSteamTest()
{
var method = WorkshopHelper.ReflectToSteam();
Assert.IsNotNull(method);
}

[Test]
public void ModIoCreateRequestTest()
{
var method = WorkshopHelper.ReflectCreateRequest();
Assert.IsNotNull(method);
}
}
}
2 changes: 2 additions & 0 deletions Tests/Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.CSharp" Version="4.7.0" />
<PackageReference Include="NUnit" Version="3.13.2" />
<PackageReference Include="NUnit.ApplicationDomain" Version="12.0.0" />
<PackageReference Include="NUnit3TestAdapter" Version="4.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.11.0" />
</ItemGroup>
Expand Down

0 comments on commit b00f8ea

Please sign in to comment.