6 Commits

5 changed files with 658 additions and 1 deletions

View File

@@ -0,0 +1,271 @@
using Syntriax.Engine.Core;
using Syntriax.Engine.Core.Exceptions;
namespace Engine.Tests;
public class BehaviourController_Tests
{
[Fact]
public void GetRequiredBehaviour()
{
IBehaviourController behaviourController = CreateUniverseObject().BehaviourController;
behaviourController.AddBehaviour<BehaviourX>();
Assert.NotNull(behaviourController.GetRequiredBehaviour<BehaviourX>());
}
[Fact]
public void GetRequiredBehaviourRaisesExceptionIfNotFound()
{
IBehaviourController behaviourController = CreateUniverseObject().BehaviourController;
Assert.Throws<BehaviourNotFoundException>(behaviourController.GetRequiredBehaviour<BehaviourX>);
}
[Fact]
public void AddSingleBehaviour()
{
IBehaviourController behaviourController = CreateUniverseObject().BehaviourController;
Assert.NotNull(behaviourController.AddBehaviour<BehaviourX>());
Assert.NotNull(behaviourController.GetBehaviour<BehaviourX>());
}
[Fact]
public void AddMultipleBehaviours()
{
IBehaviourController behaviourController = CreateUniverseObject().BehaviourController;
BehaviourX behaviourX = behaviourController.AddBehaviour<BehaviourX>();
BehaviourY behaviourY = behaviourController.AddBehaviour<BehaviourY>();
bool isXFound = false;
bool isYFound = false;
foreach (IBehaviour behaviour in behaviourController.GetBehaviours<IBehaviour>())
{
if (behaviour == behaviourX) isXFound = true;
if (behaviour == behaviourY) isYFound = true;
}
Assert.True(isXFound && isYFound);
}
[Fact]
public void AddThenRemoveBehaviour()
{
IBehaviourController behaviourController = CreateUniverseObject().BehaviourController;
behaviourController.AddBehaviour<BehaviourX>();
behaviourController.RemoveBehaviour<BehaviourX>();
Assert.Null(behaviourController.GetBehaviour<BehaviourX>());
}
[Fact]
public void GetOrAddBehaviourExtension()
{
IBehaviourController behaviourController = CreateUniverseObject().BehaviourController;
Assert.Null(behaviourController.GetBehaviour<BehaviourX>());
Assert.NotNull(behaviourController.GetOrAddBehaviour<BehaviourX>());
}
[Fact]
public void GetOrAddBehaviourExtensionFallback()
{
IBehaviourController behaviourController = CreateUniverseObject().BehaviourController;
Assert.Null(behaviourController.GetBehaviour<IBehaviour>());
Assert.NotNull(behaviourController.GetOrAddBehaviour<IBehaviour, BehaviourX>());
}
[Fact]
public void RemoveSpecificBehaviourViaGeneric()
{
IBehaviourController behaviourController = CreateUniverseObject().BehaviourController;
behaviourController.AddBehaviour<BehaviourX>();
behaviourController.AddBehaviour<BehaviourY>();
behaviourController.RemoveBehaviour<BehaviourY>();
Assert.NotNull(behaviourController.GetBehaviour<BehaviourX>());
Assert.Null(behaviourController.GetBehaviour<BehaviourY>());
}
[Fact]
public void RemoveSpecificBehaviourViaReference()
{
IBehaviourController behaviourController = CreateUniverseObject().BehaviourController;
behaviourController.AddBehaviour<BehaviourX>();
BehaviourY behaviourYFirst = behaviourController.AddBehaviour<BehaviourY>();
BehaviourY behaviourYSecond = behaviourController.AddBehaviour<BehaviourY>();
behaviourController.RemoveBehaviour(behaviourYFirst);
Assert.Equal(behaviourController.GetBehaviour<BehaviourY>(), behaviourYSecond);
Assert.NotNull(behaviourController.GetBehaviour<BehaviourX>());
}
[Fact]
public void AddBehaviourSameTypeCreatesSeparateInstances()
{
IBehaviourController behaviourController = CreateUniverseObject().BehaviourController;
BehaviourY first = behaviourController.AddBehaviour<BehaviourY>();
BehaviourY second = behaviourController.AddBehaviour<BehaviourY>();
Assert.NotSame(first, second);
}
[Fact]
public void BehaviourAddedEvents()
{
IBehaviourController behaviourController = CreateUniverseObject().BehaviourController;
IBehaviourController? sender = null;
IBehaviourController.BehaviourAddedArguments? arguments = null;
behaviourController.OnBehaviourAdded.AddListener((s, a) =>
{
sender = s;
arguments = a;
});
BehaviourX behaviour = behaviourController.AddBehaviour<BehaviourX>();
Assert.NotNull(sender);
Assert.NotNull(arguments);
Assert.Equal(behaviourController, sender);
Assert.Equal(behaviour, arguments.Value.BehaviourAdded);
}
[Fact]
public void BehaviourRemovedEvents()
{
IBehaviourController behaviourController = CreateUniverseObject().BehaviourController;
IBehaviourController? sender = null;
IBehaviourController.BehaviourRemovedArguments? arguments = null;
behaviourController.OnBehaviourRemoved.AddListener((s, a) =>
{
sender = s;
arguments = a;
});
BehaviourX behaviour = behaviourController.AddBehaviour<BehaviourX>();
behaviourController.RemoveBehaviour<BehaviourX>();
Assert.NotNull(sender);
Assert.NotNull(arguments);
Assert.Equal(behaviourController, sender);
Assert.Equal(behaviour, arguments.Value.BehaviourRemoved);
}
#region Hierarchy Structure
private static IUniverseObject CreateUniverseObject()
{
UniverseObject universeObject = new();
BehaviourController behaviourController = new();
universeObject.Assign(new StateEnable());
universeObject.StateEnable.Assign(universeObject);
behaviourController.Assign(new StateEnable());
behaviourController.StateEnable.Assign(behaviourController);
behaviourController.Assign(universeObject);
universeObject.Assign(behaviourController);
universeObject.Initialize();
behaviourController.Initialize();
return universeObject;
}
public static IUniverseObject CreateParentChildScenario()
{
IUniverseObject parentUO = CreateUniverseObject().SetUniverseObject("Parent");
IUniverseObject middleUO = CreateUniverseObject().SetUniverseObject("Middle", parentUO);
IUniverseObject childUO = CreateUniverseObject().SetUniverseObject("Child", middleUO);
parentUO.BehaviourController.AddBehaviour<BehaviourY>();
middleUO.BehaviourController.AddBehaviour<BehaviourX>();
childUO.BehaviourController.AddBehaviour<BehaviourY>();
return middleUO;
}
[Fact]
public void ParentChildScenarioGetBehaviourInParent()
{
IUniverseObject universeObject = CreateParentChildScenario();
Assert.NotNull(universeObject.BehaviourController.GetBehaviourInParent<BehaviourY>());
}
[Fact]
public void ParentChildScenarioGetBehaviourInChildren()
{
IUniverseObject universeObject = CreateParentChildScenario();
Assert.NotNull(universeObject.BehaviourController.GetBehaviourInChildren<BehaviourY>());
}
[Fact]
public void ParentChildScenarioGetBehaviourInChildrenOnSameObject()
{
IUniverseObject universeObject = CreateParentChildScenario();
Assert.NotNull(universeObject.BehaviourController.GetBehaviourInChildren<BehaviourX>());
}
[Fact]
public void ParentChildScenarioGetBehaviourInParentOnSameObject()
{
IUniverseObject universeObject = CreateParentChildScenario();
Assert.NotNull(universeObject.BehaviourController.GetBehaviourInParent<BehaviourX>());
}
[Fact]
public void ParentChildScenarioGetBehaviourInParentRaisesExceptionIfNotFound()
{
IUniverseObject universeObject = CreateParentChildScenario();
Assert.Throws<BehaviourNotFoundException>(universeObject.BehaviourController.GetRequiredBehaviourInParent<BehaviourZ>);
}
[Fact]
public void ParentChildScenarioGetBehaviourInChildrenRaisesExceptionIfNotFound()
{
IUniverseObject universeObject = CreateParentChildScenario();
Assert.Throws<BehaviourNotFoundException>(universeObject.BehaviourController.GetRequiredBehaviourInChildren<BehaviourZ>);
}
[Fact]
public void ParentChildScenarioGetBehaviourInChildrenOnSameObjectRaisesExceptionIfNotFound()
{
IUniverseObject universeObject = CreateParentChildScenario();
Assert.Throws<BehaviourNotFoundException>(universeObject.BehaviourController.GetRequiredBehaviourInChildren<BehaviourZ>);
}
[Fact]
public void ParentChildScenarioGetBehaviourInParentOnSameObjectRaisesExceptionIfNotFound()
{
IUniverseObject universeObject = CreateParentChildScenario();
Assert.Throws<BehaviourNotFoundException>(universeObject.BehaviourController.GetRequiredBehaviourInParent<BehaviourZ>);
}
#endregion
private class BehaviourX : BehaviourBase;
private class BehaviourY : BehaviourBase;
private class BehaviourZ : BehaviourBase;
}

View File

@@ -0,0 +1,72 @@
using Syntriax.Engine.Core;
namespace Engine.Tests;
public class Behaviour_Tests
{
private static IUniverseObject CreateUniverseObject()
{
UniverseObject universeObject = new();
BehaviourController behaviourController = new();
universeObject.Assign(new StateEnable());
universeObject.StateEnable.Assign(universeObject);
behaviourController.Assign(new StateEnable());
behaviourController.StateEnable.Assign(behaviourController);
behaviourController.Assign(universeObject);
universeObject.Assign(behaviourController);
universeObject.Initialize();
behaviourController.Initialize();
return universeObject;
}
[Fact]
public void BehaviourActive()
{
IUniverseObject universeObject = CreateUniverseObject();
BehaviourX behaviourX = universeObject.BehaviourController.AddBehaviour<BehaviourX>();
behaviourX.StateEnable.Enabled = true;
Assert.True(behaviourX.IsActive);
}
[Fact]
public void BehaviourNotActiveOnDisabled()
{
IUniverseObject universeObject = CreateUniverseObject();
BehaviourX behaviourX = universeObject.BehaviourController.AddBehaviour<BehaviourX>();
behaviourX.StateEnable.Enabled = false;
Assert.False(behaviourX.IsActive);
}
[Fact]
public void BehaviourNotActiveOnBehaviourControllerDisabled()
{
IUniverseObject universeObject = CreateUniverseObject();
BehaviourX behaviourX = universeObject.BehaviourController.AddBehaviour<BehaviourX>();
universeObject.BehaviourController.StateEnable.Enabled = false;
Assert.False(behaviourX.IsActive);
}
[Fact]
public void BehaviourNotActiveOnUniverseObjectDisabled()
{
IUniverseObject universeObject = CreateUniverseObject();
BehaviourX behaviourX = universeObject.BehaviourController.AddBehaviour<BehaviourX>();
universeObject.StateEnable.Enabled = false;
Assert.False(behaviourX.IsActive);
}
public class BehaviourX : BehaviourBase;
}

View File

@@ -0,0 +1,272 @@
using Syntriax.Engine.Core;
namespace Engine.Tests;
public class UniverseObject_Tests
{
private static IUniverseObject CreateUniverseObject()
{
UniverseObject universeObject = new();
BehaviourController behaviourController = new();
universeObject.Assign(new StateEnable());
behaviourController.Assign(new StateEnable());
behaviourController.StateEnable.Assign(behaviourController);
behaviourController.Assign(universeObject);
universeObject.Assign(behaviourController);
universeObject.Initialize();
behaviourController.Initialize();
return universeObject;
}
[Fact]
public void AddChildren()
{
IUniverseObject parentUO = CreateUniverseObject();
IUniverseObject childUO = CreateUniverseObject();
parentUO.AddChild(childUO);
Assert.NotEmpty(parentUO.Children);
Assert.Equal(parentUO.Children[0], childUO);
Assert.Equal(childUO.Parent, parentUO);
}
[Fact]
public void RemoveChildren()
{
IUniverseObject parentUO = CreateUniverseObject();
IUniverseObject childUO = CreateUniverseObject();
parentUO.AddChild(childUO);
Assert.NotEmpty(parentUO.Children);
Assert.Contains(childUO, parentUO.Children);
Assert.Equal(childUO.Parent, parentUO);
parentUO.RemoveChild(childUO);
Assert.Empty(parentUO.Children);
Assert.Null(childUO.Parent);
}
[Fact]
public void SetParentValue()
{
IUniverseObject parentUO = CreateUniverseObject();
IUniverseObject childUO = CreateUniverseObject();
childUO.Parent = parentUO;
Assert.Contains(childUO, parentUO.Children);
Assert.Equal(childUO.Parent, parentUO);
}
[Fact]
public void SetParentNull()
{
IUniverseObject parentUO = CreateUniverseObject();
IUniverseObject childUO = CreateUniverseObject();
parentUO.AddChild(childUO);
childUO.Parent = null;
Assert.Empty(parentUO.Children);
Assert.Null(childUO.Parent);
}
[Fact]
public void AddChildrenEvents()
{
IUniverseObject parentUO = CreateUniverseObject();
IUniverseObject childUO = CreateUniverseObject();
IUniverseObject? sender = null;
IUniverseObject.ChildrenAddedArguments? arguments = null;
parentUO.OnChildrenAdded.AddListener((s, a) =>
{
sender = s;
arguments = a;
});
parentUO.AddChild(childUO);
Assert.NotNull(sender);
Assert.NotNull(arguments);
Assert.Equal(parentUO, sender);
Assert.Equal(childUO, arguments.Value.ChildrenAdded);
}
[Fact]
public void RemoveChildrenEvents()
{
IUniverseObject parentUO = CreateUniverseObject();
IUniverseObject childUO = CreateUniverseObject();
IUniverseObject? sender = null;
IUniverseObject.ChildrenRemovedArguments? arguments = null;
parentUO.AddChild(childUO);
parentUO.OnChildrenRemoved.AddListener((s, a) =>
{
sender = s;
arguments = a;
});
parentUO.RemoveChild(childUO);
Assert.NotNull(sender);
Assert.NotNull(arguments);
Assert.Equal(parentUO, sender);
Assert.Equal(childUO, arguments.Value.ChildrenRemoved);
}
[Fact]
public void SetParentEvents()
{
IUniverseObject parentUO = CreateUniverseObject();
IUniverseObject childUO = CreateUniverseObject();
IUniverseObject? sender = null;
IUniverseObject.ParentChangedArguments? arguments = null;
childUO.OnParentChanged.AddListener((s, a) =>
{
sender = s;
arguments = a;
});
childUO.Parent = parentUO;
Assert.NotNull(sender);
Assert.NotNull(arguments);
Assert.Equal(childUO, sender);
Assert.Null(arguments.Value.PreviousParent);
Assert.Equal(parentUO, arguments.Value.CurrentParent);
}
[Fact]
public void UnsetParentEvents()
{
IUniverseObject parentUO = CreateUniverseObject();
IUniverseObject childUO = CreateUniverseObject();
IUniverseObject? sender = null;
IUniverseObject.ParentChangedArguments? arguments = null;
childUO.Parent = parentUO;
childUO.OnParentChanged.AddListener((s, a) =>
{
sender = s;
arguments = a;
});
childUO.Parent = null;
Assert.NotNull(sender);
Assert.NotNull(arguments);
Assert.Equal(childUO, sender);
Assert.Equal(parentUO, arguments.Value.PreviousParent);
Assert.Null(arguments.Value.CurrentParent);
}
[Fact]
public void Active()
{
IUniverseObject universeObject = CreateUniverseObject();
universeObject.StateEnable.Enabled = true;
Assert.True(universeObject.IsActive);
}
[Fact]
public void NotActiveWhenDisabled()
{
IUniverseObject universeObject = CreateUniverseObject();
universeObject.StateEnable.Enabled = false;
Assert.False(universeObject.IsActive);
}
[Fact]
public void ActiveEvents()
{
IUniverseObject universeObject = CreateUniverseObject();
universeObject.StateEnable.Enabled = true;
IActive? sender = null;
IActive.ActiveChangedArguments? arguments = null;
universeObject.OnActiveChanged.AddListener((s, a) =>
{
sender = s;
arguments = a;
});
universeObject.StateEnable.Enabled = false;
Assert.NotNull(sender);
Assert.NotNull(arguments);
Assert.False(universeObject.IsActive);
Assert.True(arguments.Value.PreviousState);
}
[Fact]
public void NotActiveEvents()
{
IUniverseObject universeObject = CreateUniverseObject();
universeObject.StateEnable.Enabled = false;
IActive? sender = null;
IActive.ActiveChangedArguments? arguments = null;
universeObject.OnActiveChanged.AddListener((s, a) =>
{
sender = s;
arguments = a;
});
universeObject.StateEnable.Enabled = true;
Assert.NotNull(sender);
Assert.NotNull(arguments);
Assert.True(universeObject.IsActive);
Assert.False(arguments.Value.PreviousState);
}
[Fact]
public void SetName()
{
IUniverseObject universeObject = CreateUniverseObject();
universeObject.Name = "Test";
Assert.Equal("Test", universeObject.Name);
}
[Fact]
public void SetNameEvents()
{
IUniverseObject universeObject = CreateUniverseObject();
universeObject.Name = "Previous";
INameable? sender = null;
INameable.NameChangedArguments? arguments = null;
universeObject.OnNameChanged.AddListener((s, a) =>
{
sender = s;
arguments = a;
});
universeObject.Name = "Test";
Assert.NotNull(sender);
Assert.NotNull(arguments);
Assert.Equal("Test", universeObject.Name);
Assert.Equal("Previous", arguments.Value.PreviousName);
}
}

View File

@@ -0,0 +1,28 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="coverlet.collector" Version="6.0.2" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.12.0" />
<PackageReference Include="xunit" Version="2.9.2" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.8.2" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Engine\Engine.csproj" />
<ProjectReference Include="..\Engine.Core\Engine.Core.csproj" />
<ProjectReference Include="..\Engine.Physics2D\Engine.Physics2D.csproj" />
<ProjectReference Include="..\Engine.Systems\Engine.Systems.csproj" />
</ItemGroup>
<ItemGroup>
<Using Include="Xunit" />
</ItemGroup>
</Project>

View File

@@ -19,7 +19,9 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "YamlDotNet", "Engine.Serial
EndProject EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Integration", "Integration", "{823D4020-332D-2C13-F261-6F510F11A57E}" Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Integration", "Integration", "{823D4020-332D-2C13-F261-6F510F11A57E}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MonoGame", "Engine.Integration\Engine.Integration.MonoGame\Engine.Integration.MonoGame.csproj", "{C3438D33-0879-44E4-9DF0-D29F5621C44C}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Engine.Integration.MonoGame", "Engine.Integration\Engine.Integration.MonoGame\Engine.Integration.MonoGame.csproj", "{C3438D33-0879-44E4-9DF0-D29F5621C44C}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Engine.Tests", "Engine.Tests\Engine.Tests.csproj", "{5FAE9C0F-39B9-4470-9E6B-08F764A03A08}"
EndProject EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -115,6 +117,18 @@ Global
{C3438D33-0879-44E4-9DF0-D29F5621C44C}.Release|x64.Build.0 = Release|Any CPU {C3438D33-0879-44E4-9DF0-D29F5621C44C}.Release|x64.Build.0 = Release|Any CPU
{C3438D33-0879-44E4-9DF0-D29F5621C44C}.Release|x86.ActiveCfg = Release|Any CPU {C3438D33-0879-44E4-9DF0-D29F5621C44C}.Release|x86.ActiveCfg = Release|Any CPU
{C3438D33-0879-44E4-9DF0-D29F5621C44C}.Release|x86.Build.0 = Release|Any CPU {C3438D33-0879-44E4-9DF0-D29F5621C44C}.Release|x86.Build.0 = Release|Any CPU
{5FAE9C0F-39B9-4470-9E6B-08F764A03A08}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5FAE9C0F-39B9-4470-9E6B-08F764A03A08}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5FAE9C0F-39B9-4470-9E6B-08F764A03A08}.Debug|x64.ActiveCfg = Debug|Any CPU
{5FAE9C0F-39B9-4470-9E6B-08F764A03A08}.Debug|x64.Build.0 = Debug|Any CPU
{5FAE9C0F-39B9-4470-9E6B-08F764A03A08}.Debug|x86.ActiveCfg = Debug|Any CPU
{5FAE9C0F-39B9-4470-9E6B-08F764A03A08}.Debug|x86.Build.0 = Debug|Any CPU
{5FAE9C0F-39B9-4470-9E6B-08F764A03A08}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5FAE9C0F-39B9-4470-9E6B-08F764A03A08}.Release|Any CPU.Build.0 = Release|Any CPU
{5FAE9C0F-39B9-4470-9E6B-08F764A03A08}.Release|x64.ActiveCfg = Release|Any CPU
{5FAE9C0F-39B9-4470-9E6B-08F764A03A08}.Release|x64.Build.0 = Release|Any CPU
{5FAE9C0F-39B9-4470-9E6B-08F764A03A08}.Release|x86.ActiveCfg = Release|Any CPU
{5FAE9C0F-39B9-4470-9E6B-08F764A03A08}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE