Add automatic testing functionality

This commit is contained in:
NGnius (Graham) 2020-06-17 21:04:40 -04:00
parent c912f3ba64
commit 78122ee445
7 changed files with 903 additions and 64 deletions

View file

@ -9,12 +9,15 @@ Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
Test|Any CPU = Test|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{7FD5A7D8-4F3E-426A-B07D-7DC70442A4DF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7FD5A7D8-4F3E-426A-B07D-7DC70442A4DF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7FD5A7D8-4F3E-426A-B07D-7DC70442A4DF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7FD5A7D8-4F3E-426A-B07D-7DC70442A4DF}.Release|Any CPU.Build.0 = Release|Any CPU
{7FD5A7D8-4F3E-426A-B07D-7DC70442A4DF}.Test|Any CPU.ActiveCfg = Test|Any CPU
{7FD5A7D8-4F3E-426A-B07D-7DC70442A4DF}.Test|Any CPU.Build.0 = Test|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

View file

@ -1,5 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net472</TargetFramework>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
@ -14,19 +13,403 @@
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Test|AnyCPU' ">
<DefineConstants>DEBUG;TEST;TRACE</DefineConstants>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Lib.Harmony" Version="2.0.0.10" />
</ItemGroup>
<ItemGroup>
<Reference Include="Microsoft.CSharp" />
<Reference Include="Analytics">
<HintPath>..\..\ref\Gamecraft_Data\Managed\Analytics.dll</HintPath>
</Reference>
<Reference Include="Assembly-CSharp-firstpass">
<HintPath>..\..\ref\Gamecraft_Data\Managed\Assembly-CSharp-firstpass.dll</HintPath>
</Reference>
<Reference Include="Assembly-CSharp">
<HintPath>..\..\ref\Gamecraft_Data\Managed\Assembly-CSharp.dll</HintPath>
</Reference>
<Reference Include="Authentication">
<HintPath>..\..\ref\Gamecraft_Data\Managed\Authentication.dll</HintPath>
</Reference>
<Reference Include="BlockEntityFactory">
<HintPath>..\..\ref\Gamecraft_Data\Managed\BlockEntityFactory.dll</HintPath>
</Reference>
<Reference Include="Blocks.HUDFeedbackBlocks">
<HintPath>..\..\ref\Gamecraft_Data\Managed\Blocks.HUDFeedbackBlocks.dll</HintPath>
</Reference>
<Reference Include="ClusterToWireConversion.Mock">
<HintPath>..\..\ref\Gamecraft_Data\Managed\ClusterToWireConversion.Mock.dll</HintPath>
</Reference>
<Reference Include="CommandLine">
<HintPath>..\..\ref\Gamecraft_Data\Managed\CommandLine.dll</HintPath>
</Reference>
<Reference Include="DataLoader">
<HintPath>..\..\ref\Gamecraft_Data\Managed\DataLoader.dll</HintPath>
</Reference>
<Reference Include="DDNA">
<HintPath>..\..\ref\Gamecraft_Data\Managed\DDNA.dll</HintPath>
</Reference>
<Reference Include="FMOD">
<HintPath>..\..\ref\Gamecraft_Data\Managed\FMOD.dll</HintPath>
</Reference>
<Reference Include="FullGame">
<HintPath>..\..\ref\Gamecraft_Data\Managed\FullGame.dll</HintPath>
</Reference>
<Reference Include="Gamecraft.AudioBlocks">
<HintPath>..\..\ref\Gamecraft_Data\Managed\Gamecraft.AudioBlocks.dll</HintPath>
</Reference>
<Reference Include="Gamecraft.Blocks.ConsoleBlock">
<HintPath>..\..\ref\Gamecraft_Data\Managed\Gamecraft.Blocks.ConsoleBlock.dll</HintPath>
</Reference>
<Reference Include="Gamecraft.Blocks.DamagingSurfaceBlock">
<HintPath>..\..\ref\Gamecraft_Data\Managed\Gamecraft.Blocks.DamagingSurfaceBlock.dll</HintPath>
</Reference>
<Reference Include="Gamecraft.Blocks.GenericPhysicsBlocks">
<HintPath>..\..\ref\Gamecraft_Data\Managed\Gamecraft.Blocks.GenericPhysicsBlocks.dll</HintPath>
</Reference>
<Reference Include="Gamecraft.Blocks.LogicBlock">
<HintPath>..\..\ref\Gamecraft_Data\Managed\Gamecraft.Blocks.LogicBlock.dll</HintPath>
</Reference>
<Reference Include="GameCraft.Blocks.ProjectileBlock">
<HintPath>..\..\ref\Gamecraft_Data\Managed\GameCraft.Blocks.ProjectileBlock.dll</HintPath>
</Reference>
<Reference Include="Gamecraft.Blocks.TimerBlock">
<HintPath>..\..\ref\Gamecraft_Data\Managed\Gamecraft.Blocks.TimerBlock.dll</HintPath>
</Reference>
<Reference Include="Gamecraft.CharacterVulnerability">
<HintPath>..\..\ref\Gamecraft_Data\Managed\Gamecraft.CharacterVulnerability.dll</HintPath>
</Reference>
<Reference Include="Gamecraft.CharacterVulnerabilityGui">
<HintPath>..\..\ref\Gamecraft_Data\Managed\Gamecraft.CharacterVulnerabilityGui.dll</HintPath>
</Reference>
<Reference Include="Gamecraft.Effects">
<HintPath>..\..\ref\Gamecraft_Data\Managed\Gamecraft.Effects.dll</HintPath>
</Reference>
<Reference Include="Gamecraft.GUI.ConsoleBlock">
<HintPath>..\..\ref\Gamecraft_Data\Managed\Gamecraft.GUI.ConsoleBlock.dll</HintPath>
</Reference>
<Reference Include="Gamecraft.GUI.GraphicsScreen">
<HintPath>..\..\ref\Gamecraft_Data\Managed\Gamecraft.GUI.GraphicsScreen.dll</HintPath>
</Reference>
<Reference Include="Gamecraft.GUI.HUDFeedbackBlocks">
<HintPath>..\..\ref\Gamecraft_Data\Managed\Gamecraft.GUI.HUDFeedbackBlocks.dll</HintPath>
</Reference>
<Reference Include="Gamecraft.GUI.Tweaks">
<HintPath>..\..\ref\Gamecraft_Data\Managed\Gamecraft.GUI.Tweaks.dll</HintPath>
</Reference>
<Reference Include="Gamecraft.GUI.Wires">
<HintPath>..\..\ref\Gamecraft_Data\Managed\Gamecraft.GUI.Wires.dll</HintPath>
</Reference>
<Reference Include="Gamecraft.GUI.Wires.Mockup">
<HintPath>..\..\ref\Gamecraft_Data\Managed\Gamecraft.GUI.Wires.Mockup.dll</HintPath>
</Reference>
<Reference Include="Gamecraft.GUI.WorldSpaceGuis">
<HintPath>..\..\ref\Gamecraft_Data\Managed\Gamecraft.GUI.WorldSpaceGuis.dll</HintPath>
</Reference>
<Reference Include="Gamecraft.Music">
<HintPath>..\..\ref\Gamecraft_Data\Managed\Gamecraft.Music.dll</HintPath>
</Reference>
<Reference Include="Gamecraft.PerformanceWarnings">
<HintPath>..\..\ref\Gamecraft_Data\Managed\Gamecraft.PerformanceWarnings.dll</HintPath>
</Reference>
<Reference Include="Gamecraft.Tweaks">
<HintPath>..\..\ref\Gamecraft_Data\Managed\Gamecraft.Tweaks.dll</HintPath>
</Reference>
<Reference Include="Gamecraft.Tweaks.Mockup">
<HintPath>..\..\ref\Gamecraft_Data\Managed\Gamecraft.Tweaks.Mockup.dll</HintPath>
</Reference>
<Reference Include="Gamecraft.VisualEffects">
<HintPath>..\..\ref\Gamecraft_Data\Managed\Gamecraft.VisualEffects.dll</HintPath>
</Reference>
<Reference Include="Gamecraft.Wires">
<HintPath>..\..\ref\Gamecraft_Data\Managed\Gamecraft.Wires.dll</HintPath>
</Reference>
<Reference Include="Gamecraft.Wires.Input">
<HintPath>..\..\ref\Gamecraft_Data\Managed\Gamecraft.Wires.Input.dll</HintPath>
</Reference>
<Reference Include="Gamecraft.Wires.Mockup">
<HintPath>..\..\ref\Gamecraft_Data\Managed\Gamecraft.Wires.Mockup.dll</HintPath>
</Reference>
<Reference Include="GameState">
<HintPath>..\..\ref\Gamecraft_Data\Managed\GameState.dll</HintPath>
</Reference>
<Reference Include="GPUInstancer">
<HintPath>..\..\ref\Gamecraft_Data\Managed\GPUInstancer.dll</HintPath>
</Reference>
<Reference Include="Havok.Physics">
<HintPath>..\..\ref\Gamecraft_Data\Managed\Havok.Physics.dll</HintPath>
</Reference>
<Reference Include="Havok.Physics.Hybrid">
<HintPath>..\..\ref\Gamecraft_Data\Managed\Havok.Physics.Hybrid.dll</HintPath>
</Reference>
<Reference Include="LZ4">
<HintPath>..\..\ref\Gamecraft_Data\Managed\LZ4.dll</HintPath>
</Reference>
<Reference Include="MultiplayerNetworking">
<HintPath>..\..\ref\Gamecraft_Data\Managed\MultiplayerNetworking.dll</HintPath>
</Reference>
<Reference Include="MultiplayerTest">
<HintPath>..\..\ref\Gamecraft_Data\Managed\MultiplayerTest.dll</HintPath>
</Reference>
<Reference Include="RCX.ScreenshotTaker">
<HintPath>..\..\ref\Gamecraft_Data\Managed\RCX.ScreenshotTaker.dll</HintPath>
</Reference>
<Reference Include="RobocraftECS">
<HintPath>..\..\ref\Gamecraft_Data\Managed\RobocraftECS.dll</HintPath>
</Reference>
<Reference Include="RobocraftX.AccountPreferences">
<HintPath>..\..\ref\Gamecraft_Data\Managed\RobocraftX.AccountPreferences.dll</HintPath>
</Reference>
<Reference Include="RobocraftX.Blocks">
<HintPath>..\..\ref\Gamecraft_Data\Managed\RobocraftX.Blocks.dll</HintPath>
</Reference>
<Reference Include="RobocraftX.Blocks.Ghost">
<HintPath>..\..\ref\Gamecraft_Data\Managed\RobocraftX.Blocks.Ghost.dll</HintPath>
</Reference>
<Reference Include="RobocraftX.Blocks.Triggers">
<HintPath>..\..\ref\Gamecraft_Data\Managed\RobocraftX.Blocks.Triggers.dll</HintPath>
</Reference>
<Reference Include="RobocraftX.Building.BoxSelect">
<HintPath>..\..\ref\Gamecraft_Data\Managed\RobocraftX.Building.BoxSelect.dll</HintPath>
</Reference>
<Reference Include="RobocraftX.Building.Jobs">
<HintPath>..\..\ref\Gamecraft_Data\Managed\RobocraftX.Building.Jobs.dll</HintPath>
</Reference>
<Reference Include="RobocraftX.Character">
<HintPath>..\..\ref\Gamecraft_Data\Managed\RobocraftX.Character.dll</HintPath>
</Reference>
<Reference Include="RobocraftX.ClusterToWireConversion">
<HintPath>..\..\ref\Gamecraft_Data\Managed\RobocraftX.ClusterToWireConversion.dll</HintPath>
</Reference>
<Reference Include="RobocraftX.Common">
<HintPath>..\..\ref\Gamecraft_Data\Managed\RobocraftX.Common.dll</HintPath>
</Reference>
<Reference Include="RobocraftX.ControlsScreen">
<HintPath>..\..\ref\Gamecraft_Data\Managed\RobocraftX.ControlsScreen.dll</HintPath>
</Reference>
<Reference Include="RobocraftX.Crosshair">
<HintPath>..\..\ref\Gamecraft_Data\Managed\RobocraftX.Crosshair.dll</HintPath>
</Reference>
<Reference Include="RobocraftX.FrontEnd">
<HintPath>..\..\ref\Gamecraft_Data\Managed\RobocraftX.FrontEnd.dll</HintPath>
</Reference>
<Reference Include="RobocraftX.GUI.BlockLabel">
<HintPath>..\..\ref\Gamecraft_Data\Managed\RobocraftX.GUI.BlockLabel.dll</HintPath>
</Reference>
<Reference Include="RobocraftX.GUI.DebugDisplay">
<HintPath>..\..\ref\Gamecraft_Data\Managed\RobocraftX.GUI.DebugDisplay.dll</HintPath>
</Reference>
<Reference Include="RobocraftX.GUI">
<HintPath>..\..\ref\Gamecraft_Data\Managed\RobocraftX.GUI.dll</HintPath>
</Reference>
<Reference Include="RobocraftX.GUI.RemoveBlock">
<HintPath>..\..\ref\Gamecraft_Data\Managed\RobocraftX.GUI.RemoveBlock.dll</HintPath>
</Reference>
<Reference Include="RobocraftX.GUI.ScaleGhost">
<HintPath>..\..\ref\Gamecraft_Data\Managed\RobocraftX.GUI.ScaleGhost.dll</HintPath>
</Reference>
<Reference Include="RobocraftX.GUIs.WorkshopPrefabs">
<HintPath>..\..\ref\Gamecraft_Data\Managed\RobocraftX.GUIs.WorkshopPrefabs.dll</HintPath>
</Reference>
<Reference Include="RobocraftX.Input">
<HintPath>..\..\ref\Gamecraft_Data\Managed\RobocraftX.Input.dll</HintPath>
</Reference>
<Reference Include="RobocraftX.MachineEditor">
<HintPath>..\..\ref\Gamecraft_Data\Managed\RobocraftX.MachineEditor.dll</HintPath>
</Reference>
<Reference Include="RobocraftX.MainGame">
<HintPath>..\..\ref\Gamecraft_Data\Managed\RobocraftX.MainGame.dll</HintPath>
</Reference>
<Reference Include="RobocraftX.MainSimulation">
<HintPath>..\..\ref\Gamecraft_Data\Managed\RobocraftX.MainSimulation.dll</HintPath>
</Reference>
<Reference Include="RobocraftX.MockCharacter">
<HintPath>..\..\ref\Gamecraft_Data\Managed\RobocraftX.MockCharacter.dll</HintPath>
</Reference>
<Reference Include="RobocraftX.Multiplayer">
<HintPath>..\..\ref\Gamecraft_Data\Managed\RobocraftX.Multiplayer.dll</HintPath>
</Reference>
<Reference Include="RobocraftX.Multiplayer.NetworkEntityStream">
<HintPath>..\..\ref\Gamecraft_Data\Managed\RobocraftX.Multiplayer.NetworkEntityStream.dll</HintPath>
</Reference>
<Reference Include="RobocraftX.MultiplayerInput">
<HintPath>..\..\ref\Gamecraft_Data\Managed\RobocraftX.MultiplayerInput.dll</HintPath>
</Reference>
<Reference Include="Robocraftx.ObjectIdBlocks">
<HintPath>..\..\ref\Gamecraft_Data\Managed\Robocraftx.ObjectIdBlocks.dll</HintPath>
</Reference>
<Reference Include="RobocraftX.Party">
<HintPath>..\..\ref\Gamecraft_Data\Managed\RobocraftX.Party.dll</HintPath>
</Reference>
<Reference Include="RobocraftX.PartyGui">
<HintPath>..\..\ref\Gamecraft_Data\Managed\RobocraftX.PartyGui.dll</HintPath>
</Reference>
<Reference Include="RobocraftX.Physics">
<HintPath>..\..\ref\Gamecraft_Data\Managed\RobocraftX.Physics.dll</HintPath>
</Reference>
<Reference Include="RobocraftX.PilotSeat">
<HintPath>..\..\ref\Gamecraft_Data\Managed\RobocraftX.PilotSeat.dll</HintPath>
</Reference>
<Reference Include="RobocraftX.Player">
<HintPath>..\..\ref\Gamecraft_Data\Managed\RobocraftX.Player.dll</HintPath>
</Reference>
<Reference Include="RobocraftX.Rendering">
<HintPath>..\..\ref\Gamecraft_Data\Managed\RobocraftX.Rendering.dll</HintPath>
</Reference>
<Reference Include="RobocraftX.Rendering.Mock">
<HintPath>..\..\ref\Gamecraft_Data\Managed\RobocraftX.Rendering.Mock.dll</HintPath>
</Reference>
<Reference Include="RobocraftX.SaveAndLoad">
<HintPath>..\..\ref\Gamecraft_Data\Managed\RobocraftX.SaveAndLoad.dll</HintPath>
</Reference>
<Reference Include="RobocraftX.SaveGameDialog">
<HintPath>..\..\ref\Gamecraft_Data\Managed\RobocraftX.SaveGameDialog.dll</HintPath>
</Reference>
<Reference Include="RobocraftX.Serializers">
<HintPath>..\..\ref\Gamecraft_Data\Managed\RobocraftX.Serializers.dll</HintPath>
</Reference>
<Reference Include="RobocraftX.Services">
<HintPath>..\..\ref\Gamecraft_Data\Managed\RobocraftX.Services.dll</HintPath>
</Reference>
<Reference Include="RobocraftX.SignalHandling">
<HintPath>..\..\ref\Gamecraft_Data\Managed\RobocraftX.SignalHandling.dll</HintPath>
</Reference>
<Reference Include="RobocraftX.StateSync">
<HintPath>..\..\ref\Gamecraft_Data\Managed\RobocraftX.StateSync.dll</HintPath>
</Reference>
<Reference Include="RobocraftX_SpawnPoints">
<HintPath>..\..\ref\Gamecraft_Data\Managed\RobocraftX_SpawnPoints.dll</HintPath>
</Reference>
<Reference Include="RobocraftX_TextBlock">
<HintPath>..\..\ref\Gamecraft_Data\Managed\RobocraftX_TextBlock.dll</HintPath>
</Reference>
<Reference Include="RobocratX.SimulationCompositionRoot">
<HintPath>..\..\ref\Gamecraft_Data\Managed\RobocratX.SimulationCompositionRoot.dll</HintPath>
</Reference>
<Reference Include="StringFormatter">
<HintPath>..\..\ref\Gamecraft_Data\Managed\StringFormatter.dll</HintPath>
</Reference>
<Reference Include="Svelto.Common_3">
<HintPath>..\..\ref\Gamecraft_Data\Managed\Svelto.Common_3.dll</HintPath>
</Reference>
<Reference Include="Svelto.ECS">
<HintPath>..\..\ref\Gamecraft_Data\Managed\Svelto.ECS.dll</HintPath>
</Reference>
<Reference Include="Svelto.Services">
<HintPath>..\..\ref\Gamecraft_Data\Managed\Svelto.Services.dll</HintPath>
</Reference>
<Reference Include="Svelto.Tasks">
<HintPath>..\..\ref\Gamecraft_Data\Managed\Svelto.Tasks.dll</HintPath>
</Reference>
<Reference Include="Unity.Addressables">
<HintPath>..\..\ref\Gamecraft_Data\Managed\Unity.Addressables.dll</HintPath>
</Reference>
<Reference Include="Unity.Build.SlimPlayerRuntime">
<HintPath>..\..\ref\Gamecraft_Data\Managed\Unity.Build.SlimPlayerRuntime.dll</HintPath>
</Reference>
<Reference Include="Unity.Burst">
<HintPath>..\..\ref\Gamecraft_Data\Managed\Unity.Burst.dll</HintPath>
</Reference>
<Reference Include="Unity.Collections">
<HintPath>..\..\ref\Gamecraft_Data\Managed\Unity.Collections.dll</HintPath>
</Reference>
<Reference Include="Unity.Deformations">
<HintPath>..\..\ref\Gamecraft_Data\Managed\Unity.Deformations.dll</HintPath>
</Reference>
<Reference Include="Unity.Entities">
<HintPath>..\..\ref\Gamecraft_Data\Managed\Unity.Entities.dll</HintPath>
</Reference>
<Reference Include="Unity.Entities.Hybrid">
<HintPath>..\..\ref\Gamecraft_Data\Managed\Unity.Entities.Hybrid.dll</HintPath>
</Reference>
<Reference Include="Unity.Jobs">
<HintPath>..\..\ref\Gamecraft_Data\Managed\Unity.Jobs.dll</HintPath>
</Reference>
<Reference Include="Unity.Mathematics">
<HintPath>..\..\ref\Gamecraft_Data\Managed\Unity.Mathematics.dll</HintPath>
</Reference>
<Reference Include="Unity.Mathematics.Extensions">
<HintPath>..\..\ref\Gamecraft_Data\Managed\Unity.Mathematics.Extensions.dll</HintPath>
</Reference>
<Reference Include="Unity.Mathematics.Extensions.Hybrid">
<HintPath>..\..\ref\Gamecraft_Data\Managed\Unity.Mathematics.Extensions.Hybrid.dll</HintPath>
</Reference>
<Reference Include="Unity.Physics">
<HintPath>..\..\ref\Gamecraft_Data\Managed\Unity.Physics.dll</HintPath>
</Reference>
<Reference Include="Unity.Physics.Hybrid">
<HintPath>..\..\ref\Gamecraft_Data\Managed\Unity.Physics.Hybrid.dll</HintPath>
</Reference>
<Reference Include="Unity.Platforms.Common">
<HintPath>..\..\ref\Gamecraft_Data\Managed\Unity.Platforms.Common.dll</HintPath>
</Reference>
<Reference Include="Unity.Postprocessing.Runtime">
<HintPath>..\..\ref\Gamecraft_Data\Managed\Unity.Postprocessing.Runtime.dll</HintPath>
</Reference>
<Reference Include="Unity.Properties">
<HintPath>..\..\ref\Gamecraft_Data\Managed\Unity.Properties.dll</HintPath>
</Reference>
<Reference Include="Unity.Properties.Reflection">
<HintPath>..\..\ref\Gamecraft_Data\Managed\Unity.Properties.Reflection.dll</HintPath>
</Reference>
<Reference Include="Unity.Properties.UI">
<HintPath>..\..\ref\Gamecraft_Data\Managed\Unity.Properties.UI.dll</HintPath>
</Reference>
<Reference Include="Unity.RenderPipeline.Universal.ShaderLibrary">
<HintPath>..\..\ref\Gamecraft_Data\Managed\Unity.RenderPipeline.Universal.ShaderLibrary.dll</HintPath>
</Reference>
<Reference Include="Unity.RenderPipelines.Core.Runtime">
<HintPath>..\..\ref\Gamecraft_Data\Managed\Unity.RenderPipelines.Core.Runtime.dll</HintPath>
</Reference>
<Reference Include="Unity.RenderPipelines.Core.ShaderLibrary">
<HintPath>..\..\ref\Gamecraft_Data\Managed\Unity.RenderPipelines.Core.ShaderLibrary.dll</HintPath>
</Reference>
<Reference Include="Unity.RenderPipelines.ShaderGraph.ShaderGraphLibrary">
<HintPath>..\..\ref\Gamecraft_Data\Managed\Unity.RenderPipelines.ShaderGraph.ShaderGraphLibrary.dll</HintPath>
</Reference>
<Reference Include="Unity.RenderPipelines.Universal.Runtime">
<HintPath>..\..\ref\Gamecraft_Data\Managed\Unity.RenderPipelines.Universal.Runtime.dll</HintPath>
</Reference>
<Reference Include="Unity.RenderPipelines.Universal.Shaders">
<HintPath>..\..\ref\Gamecraft_Data\Managed\Unity.RenderPipelines.Universal.Shaders.dll</HintPath>
</Reference>
<Reference Include="Unity.ResourceManager">
<HintPath>..\..\ref\Gamecraft_Data\Managed\Unity.ResourceManager.dll</HintPath>
</Reference>
<Reference Include="Unity.Scenes.Hybrid">
<HintPath>..\..\ref\Gamecraft_Data\Managed\Unity.Scenes.Hybrid.dll</HintPath>
</Reference>
<Reference Include="Unity.ScriptableBuildPipeline">
<HintPath>..\..\ref\Gamecraft_Data\Managed\Unity.ScriptableBuildPipeline.dll</HintPath>
</Reference>
<Reference Include="Unity.Serialization">
<HintPath>..\..\ref\Gamecraft_Data\Managed\Unity.Serialization.dll</HintPath>
</Reference>
<Reference Include="Unity.TextMeshPro">
<HintPath>..\..\ref\Gamecraft_Data\Managed\Unity.TextMeshPro.dll</HintPath>
</Reference>
<Reference Include="Unity.Timeline">
<HintPath>..\..\ref\Gamecraft_Data\Managed\Unity.Timeline.dll</HintPath>
</Reference>
<Reference Include="Unity.Transforms">
<HintPath>..\..\ref\Gamecraft_Data\Managed\Unity.Transforms.dll</HintPath>
</Reference>
<Reference Include="Unity.Transforms.Hybrid">
<HintPath>..\..\ref\Gamecraft_Data\Managed\Unity.Transforms.Hybrid.dll</HintPath>
</Reference>
<Reference Include="UnityEngine.UI">
<HintPath>..\..\ref\Gamecraft_Data\Managed\UnityEngine.UI.dll</HintPath>
</Reference>
<Reference Include="uREPL">
<HintPath>..\..\ref\Gamecraft_Data\Managed\uREPL.dll</HintPath>
</Reference>
<Reference Include="VisualProfiler">
<HintPath>..\..\ref\Gamecraft_Data\Managed\VisualProfiler.dll</HintPath>
</Reference>
</ItemGroup>
<!--Start Dependencies-->
<!--Start Dependencies-->
<ItemGroup>
<Reference Include="IllusionInjector">
<HintPath>..\ref\Gamecraft_Data\Managed\IllusionInjector.dll</HintPath>
@ -833,6 +1216,5 @@
<HintPath>..\..\ref\Gamecraft_Data\Managed\VisualProfiler.dll</HintPath>
</Reference>
</ItemGroup>
<!--End Dependencies-->
</Project>
<!--End Dependencies-->
</Project>

View file

@ -0,0 +1,45 @@
using System;
namespace GamecraftModdingAPI.Tests
{
public enum TestType
{
Menu,
Game,
SimulationMode,
EditMode,
}
[AttributeUsage(AttributeTargets.Class)]
public class APITestClassAttribute : Attribute
{
internal string Name;
public APITestClassAttribute(string name = "")
{
this.Name = name;
}
}
[AttributeUsage(AttributeTargets.Method)]
public class APITestCaseAttribute : Attribute
{
internal TestType TestType;
public APITestCaseAttribute(TestType testType)
{
this.TestType = testType;
}
}
[AttributeUsage(AttributeTargets.Method)]
public class APITestStartUpAttribute : Attribute
{
}
[AttributeUsage(AttributeTargets.Method)]
public class APITestTearDownAttribute : Attribute
{
}
}

View file

@ -0,0 +1,64 @@
using System;
using System.Collections.Concurrent;
using System.IO;
using System.Runtime.CompilerServices;
namespace GamecraftModdingAPI.Tests
{
public static class Assert
{
private static StreamWriter logFile = null;
private static ConcurrentDictionary<string, string> callbacks = new ConcurrentDictionary<string, string>();
private const string PASS = "SUCCESS: ";
private const string FAIL = "FAILURE: ";
private const string WARN = "WARNING: ";
private const string INFO = "DEBUG: ";
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Log(string msg, string end = "\n")
{
if (logFile == null) openTestLog();
logFile.Write(msg + end);
logFile.Flush();
}
public static EventHandler<T> CallsBack<T>(string eventName, string eventMsg = null)
{
if (eventMsg == null) eventMsg = $"expected callback to {eventName} but it never occurred...";
callbacks[eventName] = eventMsg;
return (sender, args) =>
{
string value = null;
if (!callbacks.TryRemove(eventName, out value)) { Log(WARN + $"callback to {eventName} occurred again or a related error occurred... (Received '{args.ToString()}' from '{(sender == null ? (string)sender : sender.ToString())}')"); }
Log(PASS + $"callback to {eventName} occurred... (Received '{args.ToString()}' from '{(sender == null ? (string)sender : sender.ToString())}')");
TestRoot.TestsPassed = true;
};
}
internal static void CallsComplete()
{
foreach(string key in callbacks.Keys)
{
Log(FAIL + callbacks[key]);
TestRoot.TestsPassed = false;
}
}
internal static void CloseLog()
{
if (logFile != null) logFile.Close();
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void openTestLog()
{
logFile = File.CreateText(TestRoot.ReportFile);
}
}
}

View file

@ -48,11 +48,11 @@ namespace GamecraftModdingAPI.Tests
GamecraftModdingAPI.Main.Shutdown();
}
public void OnApplicationStart()
{
public void OnApplicationStart()
{
FileLog.Reset();
Harmony.DEBUG = true;
GamecraftModdingAPI.Main.Init();
GamecraftModdingAPI.Main.Init();
Logging.MetaDebugLog($"Version group id {(uint)ApiExclusiveGroups.versionGroup}");
// in case Steam is not installed/running
// this will crash the game slightly later during startup
@ -62,7 +62,7 @@ namespace GamecraftModdingAPI.Tests
// disable some Gamecraft analytics
//AnalyticsDisablerPatch.DisableAnalytics = true;
// disable background music
Logging.MetaDebugLog("Audio Mixers: "+string.Join(",", AudioTools.GetMixers()));
Logging.MetaDebugLog("Audio Mixers: " + string.Join(",", AudioTools.GetMixers()));
//AudioTools.SetVolume(0.0f, "Music"); // The game now sets this from settings again after this is called :(
//Utility.VersionTracking.Enable();//(very) unstable
@ -76,60 +76,68 @@ namespace GamecraftModdingAPI.Tests
HandlerBuilder.Builder("menuact API debug")
.Handle(EventType.Menu)
.OnActivation(() => { Logging.Log("Menu Activated event!"); })
.OnActivation(() => { Logging.Log("Menu Activated event!"); })
.OnDestruction(() => { Logging.Log("Menu Destroyed event!"); })
.Build();
HandlerBuilder.Builder("menuswitch API debug")
.Handle(EventType.MenuSwitchedTo)
.OnActivation(() => { Logging.Log("Menu Switched To event!"); })
.Build();
.Handle(EventType.MenuSwitchedTo)
.OnActivation(() => { Logging.Log("Menu Switched To event!"); })
.Build();
HandlerBuilder.Builder("gameact API debug")
.Handle(EventType.Menu)
.OnActivation(() => { Logging.Log("Game Activated event!"); })
.OnDestruction(() => { Logging.Log("Game Destroyed event!"); })
.Build();
.Handle(EventType.Menu)
.OnActivation(() => { Logging.Log("Game Activated event!"); })
.OnDestruction(() => { Logging.Log("Game Destroyed event!"); })
.Build();
HandlerBuilder.Builder("gamerel API debug")
.Handle(EventType.GameReloaded)
.OnActivation(() => { Logging.Log("Game Reloaded event!"); })
.Build();
.Handle(EventType.GameReloaded)
.OnActivation(() => { Logging.Log("Game Reloaded event!"); })
.Build();
HandlerBuilder.Builder("gameswitch API debug")
.Handle(EventType.GameSwitchedTo)
.OnActivation(() => { Logging.Log("Game Switched To event!"); })
.Build();
.Handle(EventType.GameSwitchedTo)
.OnActivation(() => { Logging.Log("Game Switched To event!"); })
.Build();
HandlerBuilder.Builder("simulationswitch API debug")
.Handle(EventType.SimulationSwitchedTo)
.OnActivation(() => { Logging.Log("Game Mode Simulation Switched To event!"); })
.Build();
.Handle(EventType.SimulationSwitchedTo)
.OnActivation(() => { Logging.Log("Game Mode Simulation Switched To event!"); })
.Build();
HandlerBuilder.Builder("buildswitch API debug")
.Handle(EventType.BuildSwitchedTo)
.OnActivation(() => { Logging.Log("Game Mode Build Switched To event!"); })
.Build();
.Handle(EventType.BuildSwitchedTo)
.OnActivation(() => { Logging.Log("Game Mode Build Switched To event!"); })
.Build();
HandlerBuilder.Builder("menu activated API error thrower test")
.Handle(EventType.Menu)
.OnActivation(() => { throw new Exception("Event Handler always throws an exception!"); })
.Build();
// debug/test commands
/*HandlerBuilder.Builder("enter game from menu test")
.Handle(EventType.Menu)
.OnActivation(() =>
{
Tasks.Scheduler.Schedule(new Tasks.Repeatable(enterGame, shouldRetry, 0.2f));
})
.Build();*/
// debug/test commands
if (Dependency.Hell("ExtraCommands"))
{
CommandBuilder.Builder()
.Name("Exit")
.Description("Close Gamecraft immediately, without any prompts")
.Action(() => { UnityEngine.Application.Quit(); })
.Build();
.Name("Exit")
.Description("Close Gamecraft immediately, without any prompts")
.Action(() => { UnityEngine.Application.Quit(); })
.Build();
CommandBuilder.Builder()
.Name("SetFOV")
.Description("Set the player camera's field of view")
.Action((float d) => { UnityEngine.Camera.main.fieldOfView = d; })
.Build();
.Name("SetFOV")
.Description("Set the player camera's field of view")
.Action((float d) => { UnityEngine.Camera.main.fieldOfView = d; })
.Build();
CommandBuilder.Builder()
.Name("MoveLastBlock")
@ -144,14 +152,14 @@ namespace GamecraftModdingAPI.Tests
}).Build();
CommandBuilder.Builder()
.Name("PlaceAluminium")
.Description("Place a block of aluminium at the given coordinates")
.Action((float x, float y, float z) =>
{
var block = Block.PlaceNew(BlockIDs.AluminiumCube, new float3(x, y, z));
Logging.CommandLog("Block placed with type: " + block.Type);
})
.Build();
.Name("PlaceAluminium")
.Description("Place a block of aluminium at the given coordinates")
.Action((float x, float y, float z) =>
{
var block = Block.PlaceNew(BlockIDs.AluminiumCube, new float3(x, y, z));
Logging.CommandLog("Block placed with type: " + block.Type);
})
.Build();
CommandBuilder.Builder()
.Name("PlaceAluminiumLots")
@ -161,8 +169,8 @@ namespace GamecraftModdingAPI.Tests
Logging.CommandLog("Starting...");
var sw = Stopwatch.StartNew();
for (int i = 0; i < 100; i++)
for (int j = 0; j < 100; j++)
Block.PlaceNew(BlockIDs.AluminiumCube, new float3(x + i, y, z + j));
for (int j = 0; j < 100; j++)
Block.PlaceNew(BlockIDs.AluminiumCube, new float3(x + i, y, z + j));
//Block.Sync();
sw.Stop();
Logging.CommandLog("Finished in " + sw.ElapsedMilliseconds + "ms");
@ -171,10 +179,10 @@ namespace GamecraftModdingAPI.Tests
//With Sync(): 1135ms
//Without Sync(): 134ms
//Async: 348 794ms, doesn't freeze game
//Without Sync() but wait for submission: 530ms
//With Sync() at the end: 380ms
//Without Sync() but wait for submission: 530ms
//With Sync() at the end: 380ms
Block b = null;
Block b = null;
CommandBuilder.Builder("moveBlockInSim", "Run in build mode first while looking at a block, then in sim to move it up")
.Action(() =>
{
@ -204,7 +212,7 @@ namespace GamecraftModdingAPI.Tests
return;
}
new Player(PlayerType.Local).GetBlockLookedAt().Color =
new BlockColor {Color = color};
new BlockColor { Color = color };
Logging.CommandLog("Colored block to " + color);
}).Build();
@ -230,7 +238,7 @@ namespace GamecraftModdingAPI.Tests
Block.Removed += (sender, args) =>
Logging.MetaDebugLog("Removed block " + args.Type + " with ID " + args.ID);
/*
/*
CommandManager.AddCommand(new SimpleCustomCommandEngine<float>((float d) => { UnityEngine.Camera.main.fieldOfView = d; },
"SetFOV", "Set the player camera's field of view"));
CommandManager.AddCommand(new SimpleCustomCommandEngine<float, float, float>(
@ -274,8 +282,8 @@ namespace GamecraftModdingAPI.Tests
*/
}
// dependency test
if (Dependency.Hell("GamecraftScripting", new Version("0.0.1.0")))
// dependency test
if (Dependency.Hell("GamecraftScripting", new Version("0.0.1.0")))
{
Logging.LogWarning("You're in GamecraftScripting dependency hell");
}
@ -283,7 +291,11 @@ namespace GamecraftModdingAPI.Tests
{
Logging.Log("Compatible GamecraftScripting detected");
}
}
#if TEST
TestRoot.RunTests();
#endif
}
private string modsString;
private string InstalledMods()
@ -295,6 +307,40 @@ namespace GamecraftModdingAPI.Tests
return modsString = sb.ToString();
}
private bool retry = true;
private bool shouldRetry()
{
return retry;
}
private void enterGame()
{
App.Client app = new App.Client();
App.Game[] myGames = app.MyGames;
Logging.MetaDebugLog($"MyGames count {myGames.Length}");
if (myGames.Length != 0)
{
Logging.MetaDebugLog($"MyGames[0] EGID {myGames[0].EGID}");
retry = false;
try
{
//myGames[0].Description = "test msg pls ignore"; // make sure game exists first
Logging.MetaDebugLog($"Entering game {myGames[0].Name}");
myGames[0].EnterGame();
}
catch (Exception e)
{
Logging.MetaDebugLog($"Failed to enter game; exception: {e}");
retry = true;
}
}
else
{
Logging.MetaDebugLog("MyGames not populated yet :(");
}
}
public void OnFixedUpdate() { }
public void OnLateUpdate() { }

View file

@ -0,0 +1,247 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Linq; // welcome to the dark side
using Svelto.Tasks;
using Svelto.Tasks.Lean;
using Svelto.Tasks.Enumerators;
using UnityEngine;
using GamecraftModdingAPI.App;
using GamecraftModdingAPI.Tasks;
using GamecraftModdingAPI.Utility;
namespace GamecraftModdingAPI.Tests
{
public static class TestRoot
{
public static bool AutoShutdown = true;
public const string ReportFile = "GamecraftModdingAPI_tests.log";
private static bool _testsPassed = false;
private static uint _testsCount = 0;
private static uint _testsCountPassed = 0;
private static uint _testsCountFailed = 0;
private static string state = "StartingUp";
private static Stopwatch timer;
private static List<Type> testTypes = null;
public static bool TestsPassed
{
get => _testsPassed;
set
{
_testsPassed = _testsPassed && value;
_testsCount++;
if (value)
{
_testsCountPassed++;
}
else
{
_testsCountFailed++;
}
}
}
private static void StartUp()
{
// init
timer = Stopwatch.StartNew();
_testsPassed = true;
_testsCount = 0;
_testsCountPassed = 0;
_testsCountFailed = 0;
// flow control
Game.Enter += (sender, args) => { GameTests().RunOn(RobocraftX.Schedulers.Lean.EveryFrameStepRunner_RUNS_IN_TIME_STOPPED_AND_RUNNING); };
Game.Exit += (s, a) => state = "ReturningFromGame";
Client.EnterMenu += (sender, args) =>
{
if (state == "EnteringMenu")
{
MenuTests().RunOn(Scheduler.leanRunner);
state = "EnteringGame";
}
if (state == "ReturningFromGame")
{
TearDown().RunOn(Scheduler.leanRunner);
state = "ShuttingDown";
}
};
// init tests here
foreach (Type t in testTypes)
{
foreach (MethodBase m in t.GetMethods())
{
if (m.GetCustomAttribute<APITestStartUpAttribute>() != null)
{
m.Invoke(null, new object[0]);
}
}
}
state = "EnteringMenu";
}
private static IEnumerator<TaskContract> MenuTests()
{
yield return Yield.It;
// menu tests
foreach (Type t in testTypes)
{
foreach (MethodBase m in t.GetMethods())
{
APITestCaseAttribute a = m.GetCustomAttribute<APITestCaseAttribute>();
if (a != null && a.TestType == TestType.Menu)
{
m.Invoke(null, new object[0]);
yield return Yield.It;
}
}
}
// load game
yield return GoToGameTests().Continue();
}
private static IEnumerator<TaskContract> GoToGameTests()
{
Client app = new Client();
int oldLength = 0;
while (app.MyGames.Length == 0 || oldLength != app.MyGames.Length)
{
oldLength = app.MyGames.Length;
yield return new WaitForSecondsEnumerator(1).Continue();
}
yield return Yield.It;
app.MyGames[0].EnterGame();
// returning from a new game without saving will hard lock GC (it's an invalid state)
//Game newGame = Game.NewGame();
//yield return new WaitForSecondsEnumerator(5).Continue(); // wait for sync
//newGame.EnterGame();
}
private static IEnumerator<TaskContract> GameTests()
{
yield return Yield.It;
Game currentGame = Game.CurrentGame();
// in-game tests
yield return new WaitForSecondsEnumerator(5).Continue(); // wait for game to finish loading
foreach (Type t in testTypes)
{
foreach (MethodBase m in t.GetMethods())
{
APITestCaseAttribute a = m.GetCustomAttribute<APITestCaseAttribute>();
if (a != null && a.TestType == TestType.Game)
{
m.Invoke(null, new object[0]);
yield return Yield.It;
}
}
}
currentGame.ToggleTimeMode();
yield return new WaitForSecondsEnumerator(5).Continue();
// simulation tests
foreach (Type t in testTypes)
{
foreach (MethodBase m in t.GetMethods())
{
APITestCaseAttribute a = m.GetCustomAttribute<APITestCaseAttribute>();
if (a != null && a.TestType == TestType.SimulationMode)
{
m.Invoke(null, new object[0]);
yield return Yield.It;
}
}
}
currentGame.ToggleTimeMode();
yield return new WaitForSecondsEnumerator(5).Continue();
// build tests
foreach (Type t in testTypes)
{
foreach (MethodBase m in t.GetMethods())
{
APITestCaseAttribute a = m.GetCustomAttribute<APITestCaseAttribute>();
if (a != null && a.TestType == TestType.EditMode)
{
m.Invoke(null, new object[0]);
yield return Yield.It;
}
}
}
// exit game
yield return new WaitForSecondsEnumerator(5).Continue();
yield return ReturnToMenu().Continue();
}
private static IEnumerator<TaskContract> ReturnToMenu()
{
Logging.MetaLog("Returning to main menu");
yield return Yield.It;
Game.CurrentGame().ExitGame();
}
private static IEnumerator<TaskContract> TearDown()
{
yield return new WaitForSecondsEnumerator(5).Continue();
Logging.MetaLog("Tearing down test run");
// dispose tests here
foreach (Type t in testTypes)
{
foreach (MethodBase m in t.GetMethods())
{
if (m.GetCustomAttribute<APITestTearDownAttribute>() != null)
{
m.Invoke(null, new object[0]);
yield return Yield.It;
}
}
}
// finish up
Assert.CallsComplete();
timer.Stop();
string verdict = _testsPassed ? "--- PASSED :) ---" : "--- FAILED :( ---";
Assert.Log($"VERDICT: {verdict} ({_testsCountPassed}/{_testsCountFailed}/{_testsCount} P/F/T in {timer.ElapsedMilliseconds}ms)");
yield return Yield.It;
// end game
Logging.MetaLog("Completed test run: " + verdict);
yield return Yield.It;
Assert.CloseLog();
if (AutoShutdown) Application.Quit();
}
private static void FindTests(Assembly asm)
{
testTypes = new List<Type>();
foreach (Type t in asm.GetTypes())
{
if (t.GetCustomAttribute<APITestClassAttribute>() != null)
{
testTypes.Add(t);
}
}
}
public static void RunTests(Assembly asm = null)
{
if (asm == null) asm = Assembly.GetExecutingAssembly();
FindTests(asm);
Logging.MetaLog("Starting test run");
// log metadata
Assert.Log($"Unity {Application.unityVersion}");
Assert.Log($"Gamecraft {Application.version}");
Assert.Log($"GamecraftModdingAPI {Assembly.GetExecutingAssembly().GetName().Version}");
Assert.Log($"Testing {asm.GetName().Name} {asm.GetName().Version}");
Assert.Log($"START: --- {DateTime.Now.ToString()} --- ({testTypes.Count} tests classes detected)");
StartUp();
Logging.MetaLog("Test StartUp complete");
}
}
}

View file

@ -0,0 +1,52 @@
using System;
using System.Reflection;
using HarmonyLib;
namespace GamecraftModdingAPI.Tests
{
#if TEST
/// <summary>
/// Test test test.
/// </summary>
[APITestClass]
public static class TestTest
{
public static event EventHandler<TestEventArgs> StartUp;
public static event EventHandler<TestEventArgs> Test;
public static event EventHandler<TestEventArgs> TearDown;
[APITestStartUp]
public static void Init()
{
StartUp += Assert.CallsBack<TestEventArgs>("TestStartUp");
Test += Assert.CallsBack<TestEventArgs>("TestCase");
TearDown += Assert.CallsBack<TestEventArgs>("TestTearDown");
StartUp(null, default(TestEventArgs));
}
[APITestCase(TestType.Menu)]
public static void RunTest()
{
Test(null, default(TestEventArgs));
}
[APITestTearDown]
public static void End()
{
TearDown(null, default(TestEventArgs));
}
}
public struct TestEventArgs
{
public override string ToString()
{
return "TestEventArgs{}";
}
}
#endif
}