mirror of
https://github.com/space-wizards/RobustToolbox.git
synced 2026-02-14 19:29:36 +01:00
Split up test project
Robust.UnitTesting was both ALL tests for RT, and also API surface for content tests. Tests are now split into separate projects as appropriate, and the API side has also been split off.
This commit is contained in:
171
Robust.Shared.Maths.Tests/Angle_Test.cs
Normal file
171
Robust.Shared.Maths.Tests/Angle_Test.cs
Normal file
@@ -0,0 +1,171 @@
|
||||
using System.Numerics;
|
||||
using NUnit.Framework;
|
||||
using Robust.UnitTesting;
|
||||
|
||||
namespace Robust.Shared.Maths.Tests
|
||||
{
|
||||
[Parallelizable(ParallelScope.All | ParallelScope.Fixtures)]
|
||||
[TestFixture]
|
||||
[TestOf(typeof(Angle))]
|
||||
internal sealed class Angle_Test
|
||||
{
|
||||
private const double Epsilon = 1.0e-8;
|
||||
|
||||
private static IEnumerable<(float, float, Direction, double)> Sources => new(float, float, Direction, double)[]
|
||||
{
|
||||
(1, 0, Direction.East, 0.0),
|
||||
(1, 1, Direction.NorthEast, System.Math.PI / 4.0),
|
||||
(0, 1, Direction.North, System.Math.PI / 2.0),
|
||||
(-1, 1, Direction.NorthWest, 3 * System.Math.PI / 4.0),
|
||||
(-1, 0, Direction.West, System.Math.PI),
|
||||
(-1, -1, Direction.SouthWest, -3 * System.Math.PI / 4.0),
|
||||
(0, -1, Direction.South, -System.Math.PI / 2.0),
|
||||
(1, -1, Direction.SouthEast, -System.Math.PI / 4.0),
|
||||
|
||||
(0.92387953251128674f, -0.38268343236508978f, Direction.East, -System.Math.PI / 8.0)
|
||||
};
|
||||
|
||||
[Test]
|
||||
public void TestAngleDegrees()
|
||||
{
|
||||
const double degrees = 75d;
|
||||
var angle = Angle.FromDegrees(degrees);
|
||||
Assert.That(angle.Degrees, Is.EqualTo(degrees));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestAngleZero()
|
||||
{
|
||||
Assert.That(Angle.Zero.Theta, Is.AtMost(Epsilon));
|
||||
Assert.That(Angle.Zero.Degrees, Is.AtMost(Epsilon));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestAngleEqualsApprox([ValueSource(nameof(Sources))] (float, float, Direction, double) test)
|
||||
{
|
||||
var control = new Angle(new Vector2(test.Item1, test.Item2));
|
||||
var target = new Angle(test.Item4);
|
||||
Angle targetPlusRev = target + MathHelper.TwoPi;
|
||||
Angle targetMinusRev = target - MathHelper.TwoPi;
|
||||
|
||||
Assert.That(target.EqualsApprox(control));
|
||||
Assert.That(targetPlusRev.EqualsApprox(control));
|
||||
Assert.That(targetMinusRev.EqualsApprox(control));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestAngleEqualsApproxWithTolerance([ValueSource(nameof(Sources))] (float, float, Direction, double) test)
|
||||
{
|
||||
var control = new Angle(new Vector2(test.Item1, test.Item2));
|
||||
var target = new Angle(test.Item4);
|
||||
Angle targetPlusRev = target + MathHelper.TwoPi;
|
||||
Angle targetMinusRev = target - MathHelper.TwoPi;
|
||||
|
||||
Assert.That(target.EqualsApprox(control, 0.00001));
|
||||
Assert.That(targetPlusRev.EqualsApprox(control, 0.00001));
|
||||
Assert.That(targetMinusRev.EqualsApprox(control, 0.00001));
|
||||
|
||||
Angle targetWithLargeDelta = target + 1;
|
||||
Angle targetWithSmallDelta = target + 0.01;
|
||||
|
||||
// Large delta shouldn't be accepted, even with a large tolerance.
|
||||
Assert.That(targetWithLargeDelta.EqualsApprox(control, 0.1), Is.False);
|
||||
|
||||
// Small detla should be accepted with a large tolerance, but not with small tolerance.
|
||||
Assert.That(targetWithSmallDelta.EqualsApprox(control, 0.1));
|
||||
Assert.That(targetWithSmallDelta.EqualsApprox(control, 0.00001), Is.False);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestAngleFromDegrees([ValueSource(nameof(Sources))] (float, float, Direction, double) test)
|
||||
{
|
||||
var rads = test.Item4;
|
||||
var degrees = MathHelper.RadiansToDegrees(rads);
|
||||
|
||||
var target = Angle.FromDegrees(degrees);
|
||||
var control = new Angle(rads);
|
||||
|
||||
Assert.That(target.EqualsApprox(control));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestAngleToDoubleImplicitConversion([ValueSource(nameof(Sources))] (float, float, Direction, double) test)
|
||||
{
|
||||
var control = new Angle(new Vector2(test.Item1, test.Item2));
|
||||
|
||||
double impl = control;
|
||||
var expl = (double) control;
|
||||
|
||||
Assert.That(impl, Is.EqualTo(expl).Within(Epsilon));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestDoubleToAngleImplicitConversion([ValueSource(nameof(Sources))] (float, float, Direction, double) test)
|
||||
{
|
||||
var rads = test.Item4;
|
||||
|
||||
Angle impl = rads;
|
||||
var expl = new Angle(rads);
|
||||
|
||||
Assert.That(impl.EqualsApprox(expl));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestFloatToAngleImplicitConversion([ValueSource(nameof(Sources))] (float, float, Direction, double) test)
|
||||
{
|
||||
var rads = (float) test.Item4;
|
||||
|
||||
Angle impl = rads;
|
||||
var expl = new Angle(rads);
|
||||
|
||||
Assert.That(impl.EqualsApprox(expl));
|
||||
}
|
||||
|
||||
[Test]
|
||||
[Sequential]
|
||||
public void TestAngleToVector2([ValueSource(nameof(Sources))] (float, float, Direction, double) test)
|
||||
{
|
||||
var control = new Vector2(test.Item1, test.Item2).Normalized();
|
||||
var target = new Angle(test.Item4);
|
||||
|
||||
Assert.That((control - target.ToVec()).LengthSquared, Is.AtMost(Epsilon));
|
||||
}
|
||||
|
||||
[Test]
|
||||
[TestCase(MathHelper.PiOver2, ExpectedResult = Direction.East)]
|
||||
[TestCase(0, ExpectedResult = Direction.South)]
|
||||
[TestCase(-MathHelper.PiOver2, ExpectedResult = Direction.West)]
|
||||
[TestCase(Math.PI, ExpectedResult = Direction.North)]
|
||||
public Direction TestAngleToCardinal(double angle)
|
||||
{
|
||||
return new Angle(angle).GetCardinalDir();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestAngleRotateVec()
|
||||
{
|
||||
var angle = new Angle(MathHelper.Pi / 6);
|
||||
var vec = new Vector2(0.5f, 0.5f);
|
||||
|
||||
var result = angle.RotateVec(vec);
|
||||
|
||||
Assert.That(result, new ApproxEqualityConstraint(new Vector2(0.183013f, 0.683013f), 0.001));
|
||||
}
|
||||
|
||||
[TestCase(0, 4, ExpectedResult = 0f)]
|
||||
[TestCase(30, 4, ExpectedResult = 30f)]
|
||||
[TestCase(45, 4, ExpectedResult = -45f)]
|
||||
[TestCase(90, 4, ExpectedResult = 0f)]
|
||||
[TestCase(120, 4, ExpectedResult = 30f)]
|
||||
[TestCase(135, 4, ExpectedResult = -45f)]
|
||||
public float UnwindClamp(float theta, int divisions)
|
||||
{
|
||||
var segSize = 360f / (divisions * 2);
|
||||
var segments = (int)(theta / segSize);
|
||||
var odd = segments % 2;
|
||||
var result = theta - (segments * segSize) - (odd * segSize);
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
3
Robust.Shared.Maths.Tests/AssemblyInfo.cs
Normal file
3
Robust.Shared.Maths.Tests/AssemblyInfo.cs
Normal file
@@ -0,0 +1,3 @@
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
[assembly: InternalsVisibleTo("Robust.Shared.Tests")]
|
||||
135
Robust.Shared.Maths.Tests/Box2Rotated_Test.cs
Normal file
135
Robust.Shared.Maths.Tests/Box2Rotated_Test.cs
Normal file
@@ -0,0 +1,135 @@
|
||||
using System.Numerics;
|
||||
using NUnit.Framework;
|
||||
using Robust.UnitTesting;
|
||||
|
||||
namespace Robust.Shared.Maths.Tests
|
||||
{
|
||||
[TestFixture]
|
||||
[TestOf(typeof(Box2Rotated))]
|
||||
internal sealed class Box2Rotated_Test
|
||||
{
|
||||
private static IEnumerable<Box2[]> BoxRotations = new[]
|
||||
{
|
||||
new[]
|
||||
{
|
||||
new Box2(0.5f, -0.2f, 0.5f, 0.5f),
|
||||
new Box2(-0.5f, 0.5f, 0.2f, 0.5f),
|
||||
new Box2(-0.5f, -0.5f, -0.5f, 0.2f),
|
||||
new Box2(-0.2f, -0.5f, 0.5f, -0.5f)
|
||||
},
|
||||
new[]
|
||||
{
|
||||
new Box2(0.5f, 0.5f, 0.5f, 0.5f),
|
||||
new Box2(-0.5f, 0.5f, -0.5f, 0.5f),
|
||||
new Box2(-0.5f, -0.5f, -0.5f, -0.5f),
|
||||
new Box2(0.5f, -0.5f, 0.5f, -0.5f)
|
||||
}
|
||||
};
|
||||
|
||||
[Test]
|
||||
public void FullRotationTest([ValueSource(nameof(BoxRotations))] Box2[] boxes)
|
||||
{
|
||||
var rotatedBox = new Box2Rotated(boxes[0], Angle.FromDegrees(0));
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
Assert.That(rotatedBox.CalcBoundingBox(), NUnit.Framework.Is.EqualTo(boxes[i]));
|
||||
rotatedBox.Rotation += Angle.FromDegrees(90);
|
||||
}
|
||||
|
||||
Assert.That(rotatedBox.CalcBoundingBox(), NUnit.Framework.Is.EqualTo(boxes[0]));
|
||||
}
|
||||
|
||||
private static readonly float Cos45Deg = MathF.Cos(MathF.PI / 4);
|
||||
private static readonly float Sqrt2 = MathF.Sqrt(2);
|
||||
|
||||
public static IEnumerable<(Box2 baseBox, Vector2 origin, Angle rotation, Box2 expected)> CalcBoundingBoxData =>
|
||||
new (Box2, Vector2, Angle, Box2)[]
|
||||
{
|
||||
(new Box2(0, 0, 1, 1), new Vector2(0, 0), 0, new Box2(0, 0, 1, 1)),
|
||||
(new Box2(0, 0, 1, 1), new Vector2(0, 0), Math.PI, new Box2(-1, -1, 0, 0)),
|
||||
(new Box2(0, 0, 1, 1), new Vector2(1, 0), Math.PI, new Box2(1, -1, 2, 0)),
|
||||
(new Box2(0, 0, 1, 1), new Vector2(1, 1), Math.PI, new Box2(1, 1, 2, 2)),
|
||||
(new Box2(1, 1, 2, 2), new Vector2(1, 1), Math.PI/4, new Box2(1 - Cos45Deg, 1, 1 + Cos45Deg, 1 + Sqrt2)),
|
||||
(new Box2(-1, 1, 1, 2), new Vector2(0, 0), -Math.PI/2, new Box2(1, -1, 2, 1)),
|
||||
(Box2.UnitCentered, new Vector2(1, Sqrt2), Angle.FromDegrees(30), new Box2(0.158069f, -0.993544f, 1.52409f,0.372481f)),
|
||||
};
|
||||
|
||||
private static TestCaseData[] MatrixBox2Cases =
|
||||
[
|
||||
new TestCaseData(Matrix3x2.Identity,
|
||||
Box2Rotated.UnitCentered,
|
||||
Box2Rotated.UnitCentered.CalcBoundingBox()),
|
||||
new TestCaseData(Matrix3x2.CreateRotation(MathF.PI),
|
||||
Box2Rotated.UnitCentered,
|
||||
new Box2Rotated(new Vector2(0.5f, 0.5f), new Vector2(-0.5f, -0.5f)).CalcBoundingBox()),
|
||||
new TestCaseData(Matrix3x2.CreateTranslation(Vector2.One),
|
||||
Box2Rotated.UnitCentered,
|
||||
new Box2Rotated(new Vector2(0.5f, 0.5f), new Vector2(1.5f, 1.5f)).CalcBoundingBox()),
|
||||
new TestCaseData(Matrix3x2.CreateTranslation(new Vector2(-1, -Sqrt2))
|
||||
* Matrix3Helpers.CreateTransform(new Vector2(1, Sqrt2), Angle.FromDegrees(30)),
|
||||
new Box2Rotated(Box2.UnitCentered),
|
||||
new Box2(0.158069f, -0.993544f, 1.52409f, 0.372481f)),
|
||||
new TestCaseData(Matrix3x2.CreateTranslation(new Vector2(-1, -Sqrt2))
|
||||
* Matrix3Helpers.CreateTransform(new Vector2(1, Sqrt2), Angle.FromDegrees(30)),
|
||||
new Box2Rotated(Box2.UnitCentered, -Angle.FromDegrees(30), new Vector2(1, Sqrt2)),
|
||||
Box2.UnitCentered)
|
||||
];
|
||||
|
||||
/// <summary>
|
||||
/// Tests that transforming a Box2Rotated into a Box2 works.
|
||||
/// </summary>
|
||||
[Test, TestCaseSource(nameof(MatrixBox2Cases))]
|
||||
public void TestBox2Matrices(Matrix3x2 matrix, Box2Rotated bounds, Box2 result)
|
||||
{
|
||||
Assert.That(matrix.TransformBox(bounds), Is.Approximately(result));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestCalcBoundingBox([ValueSource(nameof(CalcBoundingBoxData))]
|
||||
(Box2 baseBox, Vector2 origin, Angle rotation, Box2 expected) dat)
|
||||
{
|
||||
var (baseBox, origin, rotation, expected) = dat;
|
||||
|
||||
var rotated = new Box2Rotated(baseBox, rotation, origin);
|
||||
Assert.That(rotated.CalcBoundingBox(), Is.Approximately(expected));
|
||||
}
|
||||
|
||||
// Offset it just to make sure the rotation is also gucci.
|
||||
private static readonly Vector2 Offset = new Vector2(10.0f, 10.0f);
|
||||
private static readonly Angle Rotation = Angle.FromDegrees(45);
|
||||
|
||||
// Box centered at [10, 10] rotated 45 degrees around (0,0) becomes a box centered on the y-axis at y =
|
||||
// sqrt(2)*10.
|
||||
private static Box2Rotated IntersectionBox = new(Box2.UnitCentered.Translated(Offset), Rotation);
|
||||
private static readonly Vector2 IntersectionBoxCenter = Rotation.RotateVec(Offset);
|
||||
|
||||
private static IEnumerable<Vector2> InboundPoints => new Vector2[]
|
||||
{
|
||||
IntersectionBoxCenter, // center of box
|
||||
IntersectionBoxCenter - new Vector2(-0.7f, 0.0f), // lowest point of box (just short of sqrt(0.5) below center)
|
||||
IntersectionBoxCenter + new Vector2(0.353f, 0.353f), // close to upper-right flat-edge of box, just shy of 0.5 units from the center
|
||||
};
|
||||
|
||||
[Test]
|
||||
public void TestPointIntersect([ValueSource(nameof(InboundPoints))] Vector2 point)
|
||||
{
|
||||
Assert.That(IntersectionBox.Contains(point), $"Rotated box doesn't contain {point}");
|
||||
}
|
||||
|
||||
// for the points outside of the box, take the 4 corners that would normally be inside the box if it weren't
|
||||
// rotated
|
||||
private static IEnumerable<Vector2> OutboundPoints => new Vector2[]
|
||||
{
|
||||
IntersectionBoxCenter + new Vector2(-0.48f, -0.48f),
|
||||
IntersectionBoxCenter + new Vector2(-0.48f, 0.48f),
|
||||
IntersectionBoxCenter + new Vector2(0.48f, 0.48f),
|
||||
IntersectionBoxCenter + new Vector2(0.48f, -0.48f),
|
||||
};
|
||||
|
||||
[Test]
|
||||
public void TestPointNoIntersect([ValueSource(nameof(OutboundPoints))] Vector2 point)
|
||||
{
|
||||
Assert.That(!IntersectionBox.Contains(point), $"Rotated box contains {point}");
|
||||
}
|
||||
}
|
||||
}
|
||||
470
Robust.Shared.Maths.Tests/Box2_Test.cs
Normal file
470
Robust.Shared.Maths.Tests/Box2_Test.cs
Normal file
@@ -0,0 +1,470 @@
|
||||
using System.Numerics;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace Robust.Shared.Maths.Tests
|
||||
{
|
||||
[Parallelizable(ParallelScope.All | ParallelScope.Fixtures)]
|
||||
[TestFixture]
|
||||
[TestOf(typeof(Box2))]
|
||||
internal sealed class Box2_Test
|
||||
{
|
||||
private static IEnumerable<(float left, float bottom, float right, float top)> Sources =>
|
||||
new (float, float, float, float)[]
|
||||
{
|
||||
(0, 0, 0, 0),
|
||||
(0, 0, 0, 1),
|
||||
(0, 0, 1, 0),
|
||||
(0, 0, 1, 1),
|
||||
(0, -1, 0, 0),
|
||||
(0, -1, 0, 1),
|
||||
(0, -1, 1, 0),
|
||||
(0, -1, 1, 1),
|
||||
(-1, 0, 0, 0),
|
||||
(-1, 0, 0, 1),
|
||||
(-1, 0, 1, 0),
|
||||
(-1, 0, 1, 1),
|
||||
(-1, -1, 0, 0),
|
||||
(-1, -1, 0, 1),
|
||||
(-1, -1, 1, 0),
|
||||
(-1, -1, 1, 1)
|
||||
};
|
||||
|
||||
private static IEnumerable<(float x, float y)> SmallTranslations => new[]
|
||||
{
|
||||
(0, 0.1f),
|
||||
(0.1f, 0),
|
||||
(0.1f, 0.1f),
|
||||
(0, -0.1f),
|
||||
(0.1f, -0.1f),
|
||||
(-0.1f, 0),
|
||||
(-0.1f, 0.1f),
|
||||
(-0.1f, -0.1f)
|
||||
};
|
||||
|
||||
private static IEnumerable<(float x, float y)> LargeTranslations => new (float, float)[]
|
||||
{
|
||||
(0, 5),
|
||||
(5, 0),
|
||||
(5, 5),
|
||||
(0, -5),
|
||||
(5, -5),
|
||||
(-5, 0),
|
||||
(-5, 5),
|
||||
(-5, -5)
|
||||
};
|
||||
|
||||
private static IEnumerable<float> Scalars => new[]
|
||||
{
|
||||
0.0f,
|
||||
0.1f,
|
||||
1.0f,
|
||||
5.0f,
|
||||
10.0f
|
||||
};
|
||||
|
||||
private static TestCaseData[] MatrixCases = new[]
|
||||
{
|
||||
new TestCaseData(Matrix3x2.Identity,
|
||||
Box2.UnitCentered,
|
||||
Box2.UnitCentered),
|
||||
new TestCaseData(Matrix3x2.CreateRotation(MathF.PI),
|
||||
Box2.UnitCentered,
|
||||
new Box2(new Vector2(-0.5f, -0.5f), new Vector2(0.5f, 0.5f))),
|
||||
new TestCaseData(Matrix3x2.CreateTranslation(Vector2.One),
|
||||
Box2.UnitCentered,
|
||||
new Box2(new Vector2(0.5f, 0.5f), new Vector2(1.5f, 1.5f))),
|
||||
};
|
||||
|
||||
[Test, TestCaseSource(nameof(MatrixCases))]
|
||||
public void TestBox2Matrices(Matrix3x2 matrix, Box2 bounds, Box2 result)
|
||||
{
|
||||
Assert.That(matrix.TransformBox(bounds), Is.EqualTo(result));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check whether the sources list has correct data.
|
||||
/// That is, no boxes where left > right or top > bottom.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void AssertSourcesValid([ValueSource(nameof(Sources))] (float, float, float, float) test)
|
||||
{
|
||||
var (left, bottom, right, top) = test;
|
||||
Assert.That(right, Is.GreaterThanOrEqualTo(left));
|
||||
Assert.That(top, Is.GreaterThanOrEqualTo(bottom));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Box2VectorConstructor([ValueSource(nameof(Sources))] (float, float, float, float) test)
|
||||
{
|
||||
var (left, bottom, right, top) = test;
|
||||
var box = new Box2(new Vector2(left, bottom), new Vector2(right, top));
|
||||
|
||||
Assert.That(box.Left, Is.EqualTo(left));
|
||||
Assert.That(box.Top, Is.EqualTo(top));
|
||||
Assert.That(box.Right, Is.EqualTo(right));
|
||||
Assert.That(box.Bottom, Is.EqualTo(bottom));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Box2EdgesConstructor([ValueSource(nameof(Sources))] (float, float, float, float) test)
|
||||
{
|
||||
var (left, bottom, right, top) = test;
|
||||
var box = new Box2(left, bottom, right, top);
|
||||
|
||||
Assert.That(box.Left, Is.EqualTo(left));
|
||||
Assert.That(box.Top, Is.EqualTo(top));
|
||||
Assert.That(box.Right, Is.EqualTo(right));
|
||||
Assert.That(box.Bottom, Is.EqualTo(bottom));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Box2CornerVectorProperties([ValueSource(nameof(Sources))] (float, float, float, float) test)
|
||||
{
|
||||
var (left, bottom, right, top) = test;
|
||||
var box = new Box2(left, bottom, right, top);
|
||||
|
||||
var br = new Vector2(right, bottom);
|
||||
var tl = new Vector2(left, top);
|
||||
var tr = new Vector2(right, top);
|
||||
var bl = new Vector2(left, bottom);
|
||||
|
||||
Assert.That(box.BottomRight, Is.EqualTo(br));
|
||||
Assert.That(box.TopLeft, Is.EqualTo(tl));
|
||||
Assert.That(box.TopRight, Is.EqualTo(tr));
|
||||
Assert.That(box.BottomLeft, Is.EqualTo(bl));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Box2FromDimensionsFloats([ValueSource(nameof(Sources))] (float, float, float, float) test)
|
||||
{
|
||||
var (left, bottom, right, top) = test;
|
||||
|
||||
var width = Math.Abs(left - right);
|
||||
var height = Math.Abs(top - bottom);
|
||||
|
||||
var box = Box2.FromDimensions(left, bottom, width, height);
|
||||
|
||||
Assert.That(box.Left, Is.EqualTo(left));
|
||||
Assert.That(box.Bottom, Is.EqualTo(bottom));
|
||||
Assert.That(box.Right, Is.EqualTo(left + width));
|
||||
Assert.That(box.Top, Is.EqualTo(bottom + height));
|
||||
|
||||
Assert.That(box.Width, Is.EqualTo(width));
|
||||
Assert.That(box.Height, Is.EqualTo(height));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Box2FromDimensionsVectors([ValueSource(nameof(Sources))] (float, float, float, float) test)
|
||||
{
|
||||
var (left, bottom, right, top) = test;
|
||||
|
||||
var width = Math.Abs(left - right);
|
||||
var height = Math.Abs(top - bottom);
|
||||
var size = new Vector2(width, height);
|
||||
|
||||
var box = Box2.FromDimensions(new Vector2(left, bottom), size);
|
||||
|
||||
Assert.That(box.Left, Is.EqualTo(left));
|
||||
Assert.That(box.Top, Is.EqualTo(top));
|
||||
Assert.That(box.Right, Is.EqualTo(left + width));
|
||||
Assert.That(box.Top, Is.EqualTo(bottom + height));
|
||||
|
||||
Assert.That(box.Size, Is.EqualTo(size));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Box2IntersectsSelf([ValueSource(nameof(Sources))] (float, float, float, float) test)
|
||||
{
|
||||
var (left, bottom, right, top) = test;
|
||||
|
||||
var box = new Box2(left, bottom, right, top);
|
||||
|
||||
Assert.That(box.Intersects(box));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Box2IntersectsWithSmallTranslation([ValueSource(nameof(SmallTranslations))]
|
||||
(float, float) test)
|
||||
{
|
||||
var (x, y) = test;
|
||||
|
||||
var box = new Box2(-1, -1, 1, 1);
|
||||
var translatedBox = box.Translated(new Vector2(x, y));
|
||||
|
||||
Assert.That(box.Intersects(translatedBox));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Box2NotIntersectsWithLargeTranslation([ValueSource(nameof(LargeTranslations))]
|
||||
(float, float) test)
|
||||
{
|
||||
var (x, y) = test;
|
||||
|
||||
var box = new Box2(-1, -1, 1, 1);
|
||||
var translatedBox = box.Translated(new Vector2(x, y));
|
||||
|
||||
Assert.That(box.Intersects(translatedBox), Is.False);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Box2Intersect()
|
||||
{
|
||||
var boxOne = new Box2(-1, -1, 1, 1);
|
||||
var boxTwo = new Box2(0, 0, 2, 2);
|
||||
|
||||
var result = boxOne.Intersect(boxTwo);
|
||||
|
||||
Assert.That(result.Left, Is.EqualTo(0f));
|
||||
Assert.That(result.Bottom, Is.EqualTo(0f));
|
||||
Assert.That(result.Right, Is.EqualTo(1f));
|
||||
Assert.That(result.Top, Is.EqualTo(1f));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Box2NotIntersect()
|
||||
{
|
||||
var boxOne = new Box2(-1, -1, 0, 0);
|
||||
var boxTwo = new Box2(0, 0, 2, 2);
|
||||
|
||||
var result = boxOne.Intersect(boxTwo);
|
||||
|
||||
Assert.That(result.Left, Is.EqualTo(0f));
|
||||
Assert.That(result.Bottom, Is.EqualTo(0f));
|
||||
Assert.That(result.Right, Is.EqualTo(0f));
|
||||
Assert.That(result.Top, Is.EqualTo(0f));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Box2Union()
|
||||
{
|
||||
var boxOne = new Box2(-1, -1, 1, 1);
|
||||
var boxTwo = new Box2(0, 0, 2, 2);
|
||||
|
||||
var result = boxOne.Union(boxTwo);
|
||||
|
||||
Assert.That(result.Left, Is.EqualTo(-1f));
|
||||
Assert.That(result.Bottom, Is.EqualTo(-1f));
|
||||
Assert.That(result.Right, Is.EqualTo(2f));
|
||||
Assert.That(result.Top, Is.EqualTo(2f));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Box2IsEmpty()
|
||||
{
|
||||
var degenerateBox = new Box2(0, 0, 0, 0);
|
||||
|
||||
Assert.That(degenerateBox.IsEmpty());
|
||||
|
||||
var tallDegenBox = new Box2(0, -1, 0, 1);
|
||||
var wideDegenBox = new Box2(-1, 0, 1, 0);
|
||||
var meatyBox = new Box2(-1, -1, 1, 1);
|
||||
|
||||
Assert.That(tallDegenBox.IsEmpty(), Is.False);
|
||||
Assert.That(wideDegenBox.IsEmpty(), Is.False);
|
||||
Assert.That(meatyBox.IsEmpty(), Is.False);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Box2NotEnclosesSelf()
|
||||
{
|
||||
var box = new Box2(-1, -1, 1, 1);
|
||||
|
||||
Assert.That(box.Encloses(box), Is.False);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Box2ScaledEncloses()
|
||||
{
|
||||
var box = new Box2(-1, -1, 1, 1);
|
||||
var smallBox = box.Scale(0.5f);
|
||||
var bigBox = box.Scale(2.0f);
|
||||
|
||||
Assert.That(box.Encloses(smallBox));
|
||||
Assert.That(box.Encloses(bigBox), Is.False);
|
||||
Assert.That(smallBox.Encloses(box), Is.False);
|
||||
Assert.That(bigBox.Encloses(box));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Box2TranslatedNotEncloses([ValueSource(nameof(LargeTranslations))]
|
||||
(float, float) test)
|
||||
{
|
||||
var (x, y) = test;
|
||||
|
||||
var box = new Box2(-1, -1, 1, 1);
|
||||
var translatedBox = box.Translated(new Vector2(x, y));
|
||||
|
||||
Assert.That(box.Encloses(translatedBox), Is.False);
|
||||
Assert.That(translatedBox.Encloses(box), Is.False);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Box2NotContainsSelfOpen()
|
||||
{
|
||||
var box = new Box2(-1, -1, 1, 1);
|
||||
|
||||
Assert.That(box.Contains(box.BottomLeft, false), Is.False);
|
||||
Assert.That(box.Contains(box.TopLeft, false), Is.False);
|
||||
Assert.That(box.Contains(box.TopRight, false), Is.False);
|
||||
Assert.That(box.Contains(box.BottomRight, false), Is.False);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Box2ContainsSelfClosed()
|
||||
{
|
||||
var box = new Box2(-1, -1, 1, 1);
|
||||
|
||||
Assert.That(box.Contains(box.BottomLeft));
|
||||
Assert.That(box.Contains(box.TopLeft));
|
||||
Assert.That(box.Contains(box.TopRight));
|
||||
Assert.That(box.Contains(box.BottomRight));
|
||||
|
||||
var bl = box.BottomLeft;
|
||||
var tl = box.TopLeft;
|
||||
var tr = box.TopRight;
|
||||
var br = box.BottomRight;
|
||||
|
||||
Assert.That(box.Contains(bl.X, bl.Y));
|
||||
Assert.That(box.Contains(tl.X, tl.Y));
|
||||
Assert.That(box.Contains(tr.X, tr.Y));
|
||||
Assert.That(box.Contains(br.X, br.Y));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Box2Contains([ValueSource(nameof(SmallTranslations))]
|
||||
(float, float) test)
|
||||
{
|
||||
var (x, y) = test;
|
||||
var vec = new Vector2(x, y);
|
||||
|
||||
var box = new Box2(-1, -1, 1, 1);
|
||||
|
||||
Assert.That(box.Contains(x, y));
|
||||
Assert.That(box.Contains(vec));
|
||||
Assert.That(box.Contains(vec, false));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Box2NotContains([ValueSource(nameof(LargeTranslations))]
|
||||
(float, float) test)
|
||||
{
|
||||
var (x, y) = test;
|
||||
var vec = new Vector2(x, y);
|
||||
|
||||
var box = new Box2(-1, -1, 1, 1);
|
||||
|
||||
Assert.That(box.Contains(x, y), Is.False);
|
||||
Assert.That(box.Contains(vec), Is.False);
|
||||
Assert.That(box.Contains(vec, false), Is.False);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Box2Scale([ValueSource(nameof(Scalars))] float scalar)
|
||||
{
|
||||
var box = new Box2(-1, -1, 1, 1);
|
||||
var scaledBox = box.Scale(scalar);
|
||||
|
||||
Assert.That(scaledBox.Center, Is.EqualTo(box.Center));
|
||||
Assert.That(scaledBox.Size, Is.EqualTo(box.Size * scalar));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Box2ScaleNegativeException()
|
||||
{
|
||||
var box = new Box2(-1, -1, 1, 1);
|
||||
Assert.That(() => box.Scale(-1), Throws.Exception);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Box2Translated([ValueSource(nameof(LargeTranslations))]
|
||||
(float, float) test)
|
||||
{
|
||||
var (x, y) = test;
|
||||
var vec = new Vector2(x, y);
|
||||
|
||||
var box = new Box2(-1, -1, 1, 1);
|
||||
var scaledBox = box.Translated(vec);
|
||||
|
||||
Assert.That(scaledBox.Left, Is.EqualTo(box.Left + x));
|
||||
Assert.That(scaledBox.Top, Is.EqualTo(box.Top + y));
|
||||
Assert.That(scaledBox.Bottom, Is.EqualTo(box.Bottom + y));
|
||||
Assert.That(scaledBox.Right, Is.EqualTo(box.Right + x));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Box2Equals([ValueSource(nameof(Sources))] (float, float, float, float) test)
|
||||
{
|
||||
var (left, top, right, bottom) = test;
|
||||
|
||||
var controlBox = new Box2(left, bottom, right, top);
|
||||
var differentBox = new Box2(-MathHelper.Pi, -MathHelper.Pi, MathHelper.Pi, MathHelper.Pi);
|
||||
var sameBox = new Box2(left, bottom, right, top);
|
||||
Object sameBoxAsObject = sameBox;
|
||||
Box2? nullBox = null;
|
||||
Vector2 notBox = new Vector2(left, top);
|
||||
|
||||
Assert.That(controlBox.Equals(controlBox));
|
||||
Assert.That(controlBox.Equals(differentBox), Is.False);
|
||||
Assert.That(controlBox.Equals(sameBox));
|
||||
Assert.That(controlBox.Equals(sameBoxAsObject));
|
||||
// ReSharper disable once ExpressionIsAlwaysNull
|
||||
Assert.That(controlBox.Equals(nullBox), Is.False);
|
||||
// ReSharper disable once SuspiciousTypeConversion.Global
|
||||
Assert.That(controlBox.Equals(notBox), Is.False);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Box2EqualsOperator([ValueSource(nameof(Sources))] (float, float, float, float) test)
|
||||
{
|
||||
var (left, top, right, bottom) = test;
|
||||
|
||||
var controlBox = new Box2(left, bottom, right, top);
|
||||
var differentBox = new Box2(-MathHelper.Pi, -MathHelper.Pi, MathHelper.Pi, MathHelper.Pi);
|
||||
var sameBox = new Box2(left, bottom, right, top);
|
||||
|
||||
#pragma warning disable CS1718 // Comparison made to same variable
|
||||
// ReSharper disable once EqualExpressionComparison
|
||||
Assert.That(controlBox == controlBox);
|
||||
#pragma warning restore CS1718 // Comparison made to same variable
|
||||
Assert.That(controlBox == differentBox, Is.False);
|
||||
Assert.That(controlBox == sameBox);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Box2InequalsOperator([ValueSource(nameof(Sources))] (float, float, float, float) test)
|
||||
{
|
||||
var (left, top, right, bottom) = test;
|
||||
|
||||
var controlBox = new Box2(left, bottom, right, top);
|
||||
var differentBox = new Box2(-MathHelper.Pi, -MathHelper.Pi, MathHelper.Pi, MathHelper.Pi);
|
||||
var sameBox = new Box2(left, bottom, right, top);
|
||||
|
||||
#pragma warning disable CS1718 // Comparison made to same variable
|
||||
// ReSharper disable once EqualExpressionComparison
|
||||
Assert.That(controlBox != controlBox, Is.False);
|
||||
#pragma warning restore CS1718 // Comparison made to same variable
|
||||
Assert.That(controlBox != differentBox);
|
||||
Assert.That(controlBox != sameBox, Is.False);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Box2CenteredAround()
|
||||
{
|
||||
var center = new Vector2(1, 1);
|
||||
var size = new Vector2(1, 1);
|
||||
|
||||
var box = Box2.CenteredAround(center, size);
|
||||
|
||||
Assert.That(box.Center, Is.EqualTo(center));
|
||||
Assert.That(box.Size, Is.EqualTo(size));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Enlarged()
|
||||
{
|
||||
var box = new Box2(1, 1, 2, 2).Enlarged(1);
|
||||
|
||||
Assert.That(box, Is.EqualTo(new Box2(0, 0, 3, 3)));
|
||||
}
|
||||
}
|
||||
}
|
||||
38
Robust.Shared.Maths.Tests/Box2i_Test.cs
Normal file
38
Robust.Shared.Maths.Tests/Box2i_Test.cs
Normal file
@@ -0,0 +1,38 @@
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace Robust.Shared.Maths.Tests
|
||||
{
|
||||
[TestFixture, Parallelizable, TestOf(typeof(Box2i))]
|
||||
internal sealed class Box2i_Test
|
||||
{
|
||||
[Test]
|
||||
public void Box2iUnion()
|
||||
{
|
||||
var boxOne = new Box2i(-1, -1, 1, 1);
|
||||
var boxTwo = new Box2i(0, 0, 2, 2);
|
||||
|
||||
var result = boxOne.Union(boxTwo);
|
||||
|
||||
Assert.That(result.Left, Is.EqualTo(-1));
|
||||
Assert.That(result.Bottom, Is.EqualTo(-1));
|
||||
Assert.That(result.Right, Is.EqualTo(2));
|
||||
Assert.That(result.Top, Is.EqualTo(2));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Box2iVector2iUnion()
|
||||
{
|
||||
var box = new Box2i();
|
||||
Assert.That(box, Is.EqualTo(Box2i.Empty));
|
||||
|
||||
box = box.UnionTile(Vector2i.Zero);
|
||||
Assert.That(box.Right, Is.EqualTo(1));
|
||||
|
||||
box = box.UnionTile(Vector2i.One);
|
||||
Assert.That(box.Top, Is.EqualTo(2));
|
||||
|
||||
box = box.Union(new Vector2i(2, 0));
|
||||
Assert.That(box.Right, Is.EqualTo(2));
|
||||
}
|
||||
}
|
||||
}
|
||||
194
Robust.Shared.Maths.Tests/Circle_Test.cs
Normal file
194
Robust.Shared.Maths.Tests/Circle_Test.cs
Normal file
@@ -0,0 +1,194 @@
|
||||
using System.Numerics;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace Robust.Shared.Maths.Tests
|
||||
{
|
||||
[Parallelizable(ParallelScope.All | ParallelScope.Fixtures)]
|
||||
[TestFixture]
|
||||
[TestOf(typeof(Circle))]
|
||||
internal sealed class Circle_Test
|
||||
{
|
||||
private static IEnumerable<float> Coordinates => new float[] { -1, 0, 1 };
|
||||
|
||||
// Like coordinate x coordinate, except without (0, 0)
|
||||
private static IEnumerable<(float, float)> Offsets => new (float, float)[]
|
||||
{
|
||||
(0, -1),
|
||||
(0, 1),
|
||||
(1, 0),
|
||||
(1, -1),
|
||||
(1, 1),
|
||||
(-1, 0),
|
||||
(-1, -1),
|
||||
(-1, 1)
|
||||
};
|
||||
|
||||
private static IEnumerable<float> Radii => new float[]
|
||||
{
|
||||
0.1f,
|
||||
1f,
|
||||
5f,
|
||||
10f
|
||||
};
|
||||
|
||||
[Test]
|
||||
public void CircleConstructor([ValueSource(nameof(Coordinates))] float x,
|
||||
[ValueSource(nameof(Coordinates))] float y,
|
||||
[ValueSource(nameof(Radii))] float radius)
|
||||
{
|
||||
var centerVec = new Vector2(x, y);
|
||||
var circle = new Circle(centerVec, radius);
|
||||
|
||||
Assert.That(circle.Position, Is.EqualTo(centerVec));
|
||||
Assert.That(circle.Radius, Is.EqualTo(radius));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CircleDegenerateContains([ValueSource(nameof(Coordinates))] float x,
|
||||
[ValueSource(nameof(Coordinates))] float y)
|
||||
{
|
||||
var centerVec = new Vector2(x, y);
|
||||
var circle = new Circle(centerVec, 0);
|
||||
|
||||
Assert.That(circle.Contains(centerVec));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CircleContains([ValueSource(nameof(Coordinates))] float x,
|
||||
[ValueSource(nameof(Coordinates))] float y,
|
||||
[ValueSource(nameof(Radii))] float radius,
|
||||
[ValueSource(nameof(Offsets))] (float, float) offset)
|
||||
{
|
||||
var centerVec = new Vector2(x, y);
|
||||
var circle = new Circle(centerVec, radius);
|
||||
|
||||
Assert.That(circle.Contains(centerVec));
|
||||
|
||||
var (offX, offY) = offset;
|
||||
|
||||
var offsetDirection = new Vector2(offX, offY).Normalized();
|
||||
var pointInside = centerVec + offsetDirection * (radius * 0.5f);
|
||||
var pointOn = centerVec + offsetDirection * radius;
|
||||
var pointOutside = centerVec + offsetDirection * (radius * 1.5f);
|
||||
|
||||
Assert.That(circle.Contains(pointInside));
|
||||
Assert.That(circle.Contains(pointOn));
|
||||
Assert.That(circle.Contains(pointOutside), Is.False);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CircleIntersectsCircle([ValueSource(nameof(Coordinates))] float x,
|
||||
[ValueSource(nameof(Coordinates))] float y,
|
||||
[ValueSource(nameof(Radii))] float radius,
|
||||
[ValueSource(nameof(Offsets))] (float, float) offset)
|
||||
{
|
||||
var centerVec = new Vector2(x, y);
|
||||
var circle = new Circle(centerVec, radius);
|
||||
|
||||
Assert.That(circle.Intersects(circle));
|
||||
|
||||
var (offX, offY) = offset;
|
||||
|
||||
var offsetDirection = new Vector2(offX, offY).Normalized();
|
||||
var pointOn = centerVec + offsetDirection * radius;
|
||||
var pointFar = centerVec + offsetDirection * (radius * 4);
|
||||
|
||||
var circleOn = new Circle(pointOn, radius);
|
||||
var circleFar = new Circle(pointFar, radius);
|
||||
|
||||
Assert.That(circle.Intersects(circleOn));
|
||||
Assert.That(circle.Intersects(circleFar), Is.False);
|
||||
|
||||
Assert.That(circleOn.Intersects(circle));
|
||||
Assert.That(circleFar.Intersects(circle), Is.False);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CircleIntersectsBox2([ValueSource(nameof(Coordinates))] float x,
|
||||
[ValueSource(nameof(Coordinates))] float y,
|
||||
[ValueSource(nameof(Radii))] float radius,
|
||||
[ValueSource(nameof(Offsets))] (float, float) offset)
|
||||
{
|
||||
var centerVec = new Vector2(x, y);
|
||||
var circle = new Circle(centerVec, radius);
|
||||
|
||||
var boxDim = 1f;
|
||||
|
||||
var (offX, offY) = offset;
|
||||
var offsetDirection = new Vector2(offX, offY).Normalized();
|
||||
|
||||
var boxCenterOn = centerVec + offsetDirection * radius;
|
||||
var boxCenterFar = centerVec + offsetDirection * (radius * 20);
|
||||
|
||||
var boxIn = Box2.FromDimensions(boxCenterOn.X - boxDim / 2f, boxCenterOn.Y - boxDim / 2f, boxDim, boxDim);
|
||||
var boxOut = Box2.FromDimensions(boxCenterFar.X - boxDim / 2f, boxCenterFar.Y - boxDim / 2f, boxDim, boxDim);
|
||||
|
||||
Assert.That(circle.Intersects(boxIn));
|
||||
Assert.That(circle.Intersects(boxOut), Is.False);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Box2Equals([ValueSource(nameof(Coordinates))] float x,
|
||||
[ValueSource(nameof(Coordinates))] float y,
|
||||
[ValueSource(nameof(Radii))] float radius)
|
||||
{
|
||||
var centerVec = new Vector2(x, y);
|
||||
|
||||
var controlCircle = new Circle(centerVec, radius);
|
||||
var circleDifferentRadius = new Circle(centerVec, 100);
|
||||
var circleDifferentPosition = new Circle(new Vector2(100, 0), radius);
|
||||
var sameCircle = new Circle(centerVec, radius);
|
||||
Object sameCircleAsObject = sameCircle;
|
||||
Circle? nullCircle = null;
|
||||
Vector2 notCircle = centerVec;
|
||||
|
||||
Assert.That(controlCircle.Equals(controlCircle));
|
||||
Assert.That(controlCircle.Equals(circleDifferentRadius), Is.False);
|
||||
Assert.That(controlCircle.Equals(circleDifferentPosition), Is.False);
|
||||
Assert.That(controlCircle.Equals(sameCircle));
|
||||
Assert.That(controlCircle.Equals(sameCircleAsObject));
|
||||
Assert.That(controlCircle.Equals(nullCircle), Is.False);
|
||||
Assert.That(controlCircle.Equals(notCircle), Is.False);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Box2EqualsOperator([ValueSource(nameof(Coordinates))] float x,
|
||||
[ValueSource(nameof(Coordinates))] float y,
|
||||
[ValueSource(nameof(Radii))] float radius)
|
||||
{
|
||||
var centerVec = new Vector2(x, y);
|
||||
|
||||
var controlCircle = new Circle(centerVec, radius);
|
||||
var circleDifferentRadius = new Circle(centerVec, 100);
|
||||
var circleDifferentPosition = new Circle(new Vector2(100, 0), radius);
|
||||
var sameCircle = new Circle(centerVec, radius);
|
||||
|
||||
#pragma warning disable CS1718 // Comparison made to same variable
|
||||
Assert.That(controlCircle == controlCircle);
|
||||
#pragma warning restore CS1718 // Comparison made to same variable
|
||||
Assert.That(controlCircle == circleDifferentRadius, Is.False);
|
||||
Assert.That(controlCircle == circleDifferentPosition, Is.False);
|
||||
Assert.That(controlCircle == sameCircle);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Box2InequalsOperator([ValueSource(nameof(Coordinates))] float x,
|
||||
[ValueSource(nameof(Coordinates))] float y,
|
||||
[ValueSource(nameof(Radii))] float radius)
|
||||
{
|
||||
var centerVec = new Vector2(x, y);
|
||||
|
||||
var controlCircle = new Circle(centerVec, radius);
|
||||
var circleDifferentRadius = new Circle(centerVec, 100);
|
||||
var circleDifferentPosition = new Circle(new Vector2(100, 0), radius);
|
||||
var sameCircle = new Circle(centerVec, radius);
|
||||
|
||||
#pragma warning disable CS1718 // Comparison made to same variable
|
||||
Assert.That(controlCircle != controlCircle, Is.False);
|
||||
#pragma warning restore CS1718 // Comparison made to same variable
|
||||
Assert.That(controlCircle != circleDifferentRadius);
|
||||
Assert.That(controlCircle != circleDifferentPosition);
|
||||
Assert.That(controlCircle != sameCircle, Is.False);
|
||||
}
|
||||
}
|
||||
}
|
||||
58
Robust.Shared.Maths.Tests/ColorUtils_Test.cs
Normal file
58
Robust.Shared.Maths.Tests/ColorUtils_Test.cs
Normal file
@@ -0,0 +1,58 @@
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace Robust.Shared.Maths.Tests
|
||||
{
|
||||
[Parallelizable(ParallelScope.All | ParallelScope.Fixtures)]
|
||||
[TestFixture]
|
||||
internal sealed class ColorUtils_Test
|
||||
{
|
||||
[Test]
|
||||
public void TestInterpolateBetween()
|
||||
{
|
||||
var black = Color.Black;
|
||||
var white = Color.White;
|
||||
|
||||
Assert.That(Color.InterpolateBetween(black, white, 1), Is.EqualTo(white));
|
||||
Assert.That(Color.InterpolateBetween(black, white, 0), Is.EqualTo(black));
|
||||
// Should be grey but floating points hate us so...
|
||||
// The byte conversion shouldn't have issues because the error marging should be small enough.
|
||||
var grey = Color.InterpolateBetween(black, white, 0.5f);
|
||||
Assert.That(grey.RByte, Is.EqualTo(127));
|
||||
Assert.That(grey.GByte, Is.EqualTo(127));
|
||||
Assert.That(grey.BByte, Is.EqualTo(127));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestWithAlpha()
|
||||
{
|
||||
Assert.That(Color.White.WithAlpha(128), Is.EqualTo(new Color(255, 255, 255, 128)));
|
||||
Assert.That(Color.White.WithAlpha(0.5f), Is.EqualTo(new Color(1, 1, 1, 0.5f)));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestFromHex()
|
||||
{
|
||||
// Test fallback.
|
||||
Assert.That(Color.FromHex("honk", Color.AliceBlue), Is.EqualTo(Color.AliceBlue));
|
||||
Assert.That(() => Color.FromHex("honk"), Throws.ArgumentException);
|
||||
Assert.That(() => Color.FromHex("#FFFFFFFF00"), Throws.ArgumentException);
|
||||
|
||||
Assert.That(Color.FromHex("#FFFFFF"), Is.EqualTo(Color.White));
|
||||
Assert.That(Color.FromHex("#FFFFFFFF"), Is.EqualTo(Color.White));
|
||||
Assert.That(Color.FromHex("#FFFFFF69"), Is.EqualTo(Color.White.WithAlpha(0x69)));
|
||||
Assert.That(Color.FromHex("#FFF"), Is.EqualTo(Color.White));
|
||||
Assert.That(Color.FromHex("#FFF8"), Is.EqualTo(Color.White.WithAlpha(0x88)));
|
||||
Assert.That(Color.FromHex("#ABCDEF"), Is.EqualTo(new Color(0xAB, 0xCD, 0xEF)));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestByteParts()
|
||||
{
|
||||
var color = new Color(23, 38, 18, 20);
|
||||
Assert.That(color.RByte, Is.EqualTo(23));
|
||||
Assert.That(color.GByte, Is.EqualTo(38));
|
||||
Assert.That(color.BByte, Is.EqualTo(18));
|
||||
Assert.That(color.AByte, Is.EqualTo(20));
|
||||
}
|
||||
}
|
||||
}
|
||||
442
Robust.Shared.Maths.Tests/Color_Test.cs
Normal file
442
Robust.Shared.Maths.Tests/Color_Test.cs
Normal file
@@ -0,0 +1,442 @@
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace Robust.Shared.Maths.Tests
|
||||
{
|
||||
[Parallelizable(ParallelScope.All | ParallelScope.Fixtures)]
|
||||
[TestFixture]
|
||||
[TestOf(typeof(Color))]
|
||||
internal sealed class Color_Test
|
||||
{
|
||||
static IEnumerable<byte> BytesSource = new byte[]
|
||||
{
|
||||
0,
|
||||
1,
|
||||
31,
|
||||
32,
|
||||
63,
|
||||
64,
|
||||
127,
|
||||
128,
|
||||
254,
|
||||
255
|
||||
};
|
||||
|
||||
static IEnumerable<(byte, byte, byte, byte)> FourBytesSource = BytesSource.SelectMany(b => new (byte, byte, byte, byte)[] {
|
||||
(b, 0, 0, 0),
|
||||
(0, b, 0, 0),
|
||||
(0, 0, b, 0),
|
||||
(0, 0, 0, b)
|
||||
}).Distinct();
|
||||
|
||||
static IEnumerable<float> FloatsSource = BytesSource.Select(i => i / (float) byte.MaxValue);
|
||||
|
||||
static IEnumerable<(float, float, float, float)> FourFloatsSource = FloatsSource.SelectMany(f => new (float, float, float, float)[] {
|
||||
(f, 0, 0, 0),
|
||||
(0, f, 0, 0),
|
||||
(0, 0, f, 0),
|
||||
(0, 0, 0, f)
|
||||
}).Distinct();
|
||||
|
||||
private static IEnumerable<(string hex, Color expected)> HexColorsParsingSource = new[]
|
||||
{
|
||||
("#FFFFFFFF", new Color(0xff, 0xff, 0xff)),
|
||||
("#FFFFFF", new Color(0xff, 0xff, 0xff)),
|
||||
("#12345678", new Color(0x12, 0x34, 0x56, 0x78)),
|
||||
("#123456", new Color(0x12, 0x34, 0x56)),
|
||||
("#FFF", new Color(0xff, 0xff, 0xff)),
|
||||
("#AAA", new Color(0xaa, 0xaa, 0xaa)),
|
||||
("#963", new Color(0x99, 0x66, 0x33)),
|
||||
};
|
||||
|
||||
[Test, Sequential]
|
||||
public void ColorConstructorFloat([ValueSource(nameof(FourFloatsSource))] (float, float, float, float) floats,
|
||||
[ValueSource(nameof(FourBytesSource))] (byte, byte, byte, byte) bytes)
|
||||
{
|
||||
var (rf, gf, bf, af) = floats;
|
||||
var (rb, gb, bb, ab) = bytes;
|
||||
|
||||
var color = new Color(rf, gf, bf, af);
|
||||
|
||||
Assert.That(color.R, Is.EqualTo(rf));
|
||||
Assert.That(color.G, Is.EqualTo(gf));
|
||||
Assert.That(color.B, Is.EqualTo(bf));
|
||||
Assert.That(color.A, Is.EqualTo(af));
|
||||
|
||||
Assert.That(color.RByte, Is.EqualTo(rb));
|
||||
Assert.That(color.GByte, Is.EqualTo(gb));
|
||||
Assert.That(color.BByte, Is.EqualTo(bb));
|
||||
Assert.That(color.AByte, Is.EqualTo(ab));
|
||||
}
|
||||
|
||||
[Test, Sequential]
|
||||
public void ColorConstructorByte([ValueSource(nameof(FourFloatsSource))] (float, float, float, float) floats,
|
||||
[ValueSource(nameof(FourBytesSource))] (byte, byte, byte, byte) bytes)
|
||||
{
|
||||
var (rf, gf, bf, af) = floats;
|
||||
var (rb, gb, bb, ab) = bytes;
|
||||
|
||||
var color = new Color(rb, gb, bb, ab);
|
||||
|
||||
Assert.That(color.R, Is.EqualTo(rf));
|
||||
Assert.That(color.G, Is.EqualTo(gf));
|
||||
Assert.That(color.B, Is.EqualTo(bf));
|
||||
Assert.That(color.A, Is.EqualTo(af));
|
||||
|
||||
Assert.That(color.RByte, Is.EqualTo(rb));
|
||||
Assert.That(color.GByte, Is.EqualTo(gb));
|
||||
Assert.That(color.BByte, Is.EqualTo(bb));
|
||||
Assert.That(color.AByte, Is.EqualTo(ab));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ToArgb([ValueSource(nameof(FourBytesSource))] (byte, byte, byte, byte) bytes)
|
||||
{
|
||||
var (rb, gb, bb, ab) = bytes;
|
||||
|
||||
var color = new Color(rb, gb, bb, ab);
|
||||
|
||||
var argb = (uint) color.ToArgb();
|
||||
|
||||
var aMask = (uint) byte.MaxValue << 24;
|
||||
var rMask = (uint) byte.MaxValue << 16;
|
||||
var gMask = (uint) byte.MaxValue << 8;
|
||||
var bMask = (uint) byte.MaxValue;
|
||||
|
||||
Assert.That((argb & aMask) >> 24, Is.EqualTo(ab));
|
||||
Assert.That((argb & rMask) >> 16, Is.EqualTo(rb));
|
||||
Assert.That((argb & gMask) >> 8, Is.EqualTo(gb));
|
||||
Assert.That((argb & bMask), Is.EqualTo(bb));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ColorEquals([ValueSource(nameof(FourFloatsSource))] (float, float, float, float) floats)
|
||||
{
|
||||
var (rf, gf, bf, af) = floats;
|
||||
|
||||
var controlColor = new Color(rf, gf, bf, af);
|
||||
var colorDiffRed = new Color(byte.MaxValue - rf, gf, bf, af);
|
||||
var colorDiffGreen = new Color(rf, byte.MaxValue - gf, bf, af);
|
||||
var colorDiffBlue = new Color(rf, gf, byte.MaxValue - bf, af);
|
||||
var colorDiffAlpha = new Color(rf, gf, bf, byte.MaxValue - af);
|
||||
var sameColor = new Color(rf, gf, bf, af);
|
||||
object sameColorAsObject = sameColor;
|
||||
Color? nullColor = null;
|
||||
UIBox2 notColor = new UIBox2(rf, gf, bf, af);
|
||||
|
||||
#pragma warning disable NUnit2009
|
||||
// This tests that .Equals actually works so ignoring the warning is fine.
|
||||
Assert.That(controlColor, Is.EqualTo(controlColor));
|
||||
#pragma warning restore NUnit2009
|
||||
Assert.That(controlColor, Is.Not.EqualTo(colorDiffRed));
|
||||
Assert.That(controlColor, Is.Not.EqualTo(colorDiffGreen));
|
||||
Assert.That(controlColor, Is.Not.EqualTo(colorDiffBlue));
|
||||
Assert.That(controlColor, Is.Not.EqualTo(colorDiffAlpha));
|
||||
Assert.That(controlColor, Is.EqualTo(sameColor));
|
||||
Assert.That(controlColor, Is.EqualTo(sameColorAsObject));
|
||||
Assert.That(controlColor, Is.Not.EqualTo(nullColor));
|
||||
// NUnit's analyzer literally disallows this because it knows it's bogus, so...
|
||||
// Assert.That(controlColor, Is.Not.EqualTo(notColor));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ColorEqualsOperator([ValueSource(nameof(FourFloatsSource))] (float, float, float, float) floats)
|
||||
{
|
||||
var (rf, gf, bf, af) = floats;
|
||||
|
||||
var controlColor = new Color(rf, gf, bf, af);
|
||||
var colorDiffRed = new Color(byte.MaxValue - rf, gf, bf, af);
|
||||
var colorDiffGreen = new Color(rf, byte.MaxValue - gf, bf, af);
|
||||
var colorDiffBlue = new Color(rf, gf, byte.MaxValue - bf, af);
|
||||
var colorDiffAlpha = new Color(rf, gf, bf, byte.MaxValue - af);
|
||||
var sameColor = new Color(rf, gf, bf, af);
|
||||
Color? nullColor = null;
|
||||
|
||||
#pragma warning disable CS1718 // Comparison made to same variable
|
||||
Assert.That(controlColor == controlColor);
|
||||
#pragma warning restore CS1718 // Comparison made to same variable
|
||||
Assert.That(controlColor == colorDiffRed, Is.False);
|
||||
Assert.That(controlColor == colorDiffGreen, Is.False);
|
||||
Assert.That(controlColor == colorDiffBlue, Is.False);
|
||||
Assert.That(controlColor == colorDiffAlpha, Is.False);
|
||||
Assert.That(controlColor == sameColor);
|
||||
Assert.That(controlColor == nullColor, Is.False);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ColorInequalsOperator([ValueSource(nameof(FourFloatsSource))] (float, float, float, float) floats)
|
||||
{
|
||||
var (rf, gf, bf, af) = floats;
|
||||
|
||||
var controlColor = new Color(rf, gf, bf, af);
|
||||
var colorDiffRed = new Color(byte.MaxValue - rf, gf, bf, af);
|
||||
var colorDiffGreen = new Color(rf, byte.MaxValue - gf, bf, af);
|
||||
var colorDiffBlue = new Color(rf, gf, byte.MaxValue - bf, af);
|
||||
var colorDiffAlpha = new Color(rf, gf, bf, byte.MaxValue - af);
|
||||
var sameColor = new Color(rf, gf, bf, af);
|
||||
Color? nullColor = null;
|
||||
|
||||
#pragma warning disable CS1718 // Comparison made to same variable
|
||||
Assert.That(controlColor != controlColor, Is.False);
|
||||
#pragma warning restore CS1718 // Comparison made to same variable
|
||||
Assert.That(controlColor != colorDiffRed);
|
||||
Assert.That(controlColor != colorDiffGreen);
|
||||
Assert.That(controlColor != colorDiffBlue);
|
||||
Assert.That(controlColor != colorDiffAlpha);
|
||||
Assert.That(controlColor != sameColor, Is.False);
|
||||
Assert.That(controlColor != nullColor);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ColorToSystemDrawingColor([ValueSource(nameof(FourFloatsSource))] (float, float, float, float) floats)
|
||||
{
|
||||
var (rf, gf, bf, af) = floats;
|
||||
|
||||
var color = new Color(rf, gf, bf, af);
|
||||
var sysColor = System.Drawing.Color.FromArgb(color.ToArgb());
|
||||
|
||||
Assert.That(color, Is.EqualTo((Color) sysColor));
|
||||
Assert.That(sysColor, Is.EqualTo((System.Drawing.Color) color));
|
||||
}
|
||||
|
||||
static IEnumerable<string> DefaultColorNames => Color.GetAllDefaultColors()
|
||||
.Where(e => System.Drawing.Color.FromName(e.Key).IsKnownColor)
|
||||
.Select(e => e.Key);
|
||||
|
||||
[Test]
|
||||
public void GetAllDefaultColorsFromName([ValueSource(nameof(DefaultColorNames))] string colorName)
|
||||
{
|
||||
var color = Color.FromName(colorName);
|
||||
var sysColor = System.Drawing.Color.FromName(colorName);
|
||||
|
||||
Assert.That(color, Is.EqualTo((Color) sysColor));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetColorFromNameExceptions()
|
||||
{
|
||||
const string name = "Definitely not a color name";
|
||||
|
||||
Assert.Throws<KeyNotFoundException>(() => Color.FromName(name));
|
||||
Assert.DoesNotThrow(() => Color.TryFromName(name, out _));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void WithRedFloat([ValueSource(nameof(FourFloatsSource))] (float, float, float, float) floats)
|
||||
{
|
||||
var (rf, gf, bf, af) = floats;
|
||||
var f = byte.MaxValue - rf;
|
||||
|
||||
var color = new Color(rf, gf, bf, af);
|
||||
var controlColor = new Color(f, gf, bf, af);
|
||||
|
||||
var colorWithRed = color.WithRed(f);
|
||||
|
||||
Assert.That(colorWithRed, Is.EqualTo(controlColor));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void WithGreenFloat([ValueSource(nameof(FourFloatsSource))] (float, float, float, float) floats)
|
||||
{
|
||||
var (rf, gf, bf, af) = floats;
|
||||
var f = byte.MaxValue - gf;
|
||||
|
||||
var color = new Color(rf, gf, bf, af);
|
||||
var controlColor = new Color(rf, f, bf, af);
|
||||
|
||||
var colorWithGreen = color.WithGreen(f);
|
||||
|
||||
Assert.That(colorWithGreen, Is.EqualTo(controlColor));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void WithBlueFloat([ValueSource(nameof(FourFloatsSource))] (float, float, float, float) floats)
|
||||
{
|
||||
var (rf, gf, bf, af) = floats;
|
||||
var f = byte.MaxValue - bf;
|
||||
|
||||
var color = new Color(rf, gf, bf, af);
|
||||
var controlColor = new Color(rf, gf, f, af);
|
||||
|
||||
var colorWithBlue = color.WithBlue(f);
|
||||
|
||||
Assert.That(colorWithBlue, Is.EqualTo(controlColor));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void WithAlphaFloat([ValueSource(nameof(FourFloatsSource))] (float, float, float, float) floats)
|
||||
{
|
||||
var (rf, gf, bf, af) = floats;
|
||||
var f = byte.MaxValue - af;
|
||||
|
||||
var color = new Color(rf, gf, bf, af);
|
||||
var controlColor = new Color(rf, gf, bf, f);
|
||||
|
||||
var colorWithAlpha = color.WithAlpha(f);
|
||||
|
||||
Assert.That(colorWithAlpha, Is.EqualTo(controlColor));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void WithRedByte([ValueSource(nameof(FourBytesSource))] (byte, byte, byte, byte) bytes)
|
||||
{
|
||||
var (rb, gb, bb, ab) = bytes;
|
||||
var b = (byte)(byte.MaxValue - rb);
|
||||
|
||||
var color = new Color(rb, gb, bb, ab);
|
||||
var controlColor = new Color(b, gb, bb, ab);
|
||||
|
||||
var colorWithRed = color.WithRed(b);
|
||||
|
||||
Assert.That(colorWithRed, Is.EqualTo(controlColor));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void WithGreenByte([ValueSource(nameof(FourBytesSource))] (byte, byte, byte, byte) bytes)
|
||||
{
|
||||
var (rb, gb, bb, ab) = bytes;
|
||||
var b = (byte)(byte.MaxValue - gb);
|
||||
|
||||
var color = new Color(rb, gb, bb, ab);
|
||||
var controlColor = new Color(rb, b, bb, ab);
|
||||
|
||||
var colorWithGreen = color.WithGreen(b);
|
||||
|
||||
Assert.That(colorWithGreen, Is.EqualTo(controlColor));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void WithBlueByte([ValueSource(nameof(FourBytesSource))] (byte, byte, byte, byte) bytes)
|
||||
{
|
||||
var (rb, gb, bb, ab) = bytes;
|
||||
var b = (byte)(byte.MaxValue - bb);
|
||||
|
||||
var color = new Color(rb, gb, bb, ab);
|
||||
var controlColor = new Color(rb, gb, b, ab);
|
||||
|
||||
var colorWithBlue = color.WithBlue(b);
|
||||
|
||||
Assert.That(colorWithBlue, Is.EqualTo(controlColor));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void WithAlphaByte([ValueSource(nameof(FourBytesSource))] (byte, byte, byte, byte) bytes)
|
||||
{
|
||||
var (rb, gb, bb, ab) = bytes;
|
||||
var b = (byte) (byte.MaxValue - ab);
|
||||
|
||||
var color = new Color(rb, gb, bb, ab);
|
||||
var controlColor = new Color(rb, gb, bb, b);
|
||||
|
||||
var colorWithAlpha = color.WithAlpha(b);
|
||||
|
||||
Assert.That(colorWithAlpha, Is.EqualTo(controlColor));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ToFromSrgb([ValueSource(nameof(FourFloatsSource))] (float, float, float, float) floats)
|
||||
{
|
||||
var (rf, gf, bf, af) = floats;
|
||||
|
||||
var controlColor = new Color(rf, gf, bf, af);
|
||||
var color = Color.FromSrgb(Color.ToSrgb(controlColor));
|
||||
|
||||
Assert.That(MathHelper.CloseToPercent(color, controlColor));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ToFromHsl([ValueSource(nameof(FourFloatsSource))] (float, float, float, float) floats)
|
||||
{
|
||||
var (rf, gf, bf, af) = floats;
|
||||
|
||||
var controlColor = new Color(rf, gf, bf, af);
|
||||
var color = Color.FromHsl(Color.ToHsl(controlColor));
|
||||
|
||||
Assert.That(MathHelper.CloseToPercent(color, controlColor));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ToFromHsv([ValueSource(nameof(FourFloatsSource))] (float, float, float, float) floats)
|
||||
{
|
||||
var (rf, gf, bf, af) = floats;
|
||||
|
||||
var controlColor = new Color(rf, gf, bf, af);
|
||||
var color = Color.FromHsv(Color.ToHsv(controlColor));
|
||||
|
||||
Assert.That(MathHelper.CloseToPercent(color, controlColor));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ToFromXyz([ValueSource(nameof(FourFloatsSource))] (float, float, float, float) floats)
|
||||
{
|
||||
const float tolerance = 1e-4f;
|
||||
|
||||
var (rf, gf, bf, af) = floats;
|
||||
|
||||
var controlColor = new Color(rf, gf, bf, af);
|
||||
var color = Color.FromXyz(Color.ToXyz(controlColor));
|
||||
|
||||
Assert.That(color.R, Is.EqualTo(controlColor.R).Within(tolerance));
|
||||
Assert.That(color.G, Is.EqualTo(controlColor.G).Within(tolerance));
|
||||
Assert.That(color.B, Is.EqualTo(controlColor.B).Within(tolerance));
|
||||
Assert.That(color.A, Is.EqualTo(controlColor.A).Within(tolerance));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ToFromYcbcr([ValueSource(nameof(FourFloatsSource))] (float, float, float, float) floats)
|
||||
{
|
||||
var (rf, gf, bf, af) = floats;
|
||||
|
||||
var controlColor = new Color(rf, gf, bf, af);
|
||||
var color = Color.FromYcbcr(Color.ToYcbcr(controlColor));
|
||||
|
||||
Assert.That(MathHelper.CloseToPercent(color, controlColor));
|
||||
}
|
||||
|
||||
static IEnumerable<float> InterpolationValues => new float[]
|
||||
{
|
||||
0f,
|
||||
0.2f,
|
||||
0.4f,
|
||||
0.6f,
|
||||
0.8f,
|
||||
1f
|
||||
};
|
||||
|
||||
[Test]
|
||||
public void InterpolateBetween([ValueSource(nameof(FourFloatsSource))] (float, float, float, float) floats,
|
||||
[ValueSource(nameof(InterpolationValues))] float interpolation)
|
||||
{
|
||||
var (r1, g1, b1, a1) = floats;
|
||||
var (b2, a2, r2, g2) = floats;
|
||||
|
||||
var color1 = new Color(r1, g1, b1, a1);
|
||||
var color2 = new Color(r2, g2, b2, a2);
|
||||
|
||||
var interColor = Color.InterpolateBetween(color1, color2, interpolation);
|
||||
var inverseInterColor = Color.InterpolateBetween(color2, color1, 1 - interpolation);
|
||||
|
||||
Assert.That(MathHelper.CloseToPercent(interColor, inverseInterColor));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void FromHexThrows()
|
||||
{
|
||||
Assert.Throws<ArgumentException>(() => Color.FromHex(" "));
|
||||
Assert.Throws<ArgumentException>(() => Color.FromHex("#aaaaaaaaa"));
|
||||
Assert.Throws<ArgumentException>(() => Color.FromHex("#aaaaaaa"));
|
||||
Assert.Throws<ArgumentException>(() => Color.FromHex("#aaaaa"));
|
||||
Assert.Throws<ArgumentException>(() => Color.FromHex("#aa"));
|
||||
Assert.Throws<ArgumentException>(() => Color.FromHex("#a"));
|
||||
Assert.Throws<ArgumentException>(() => Color.FromHex("#"));
|
||||
Assert.Throws<ArgumentException>(() => Color.FromHex(""));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void FromHex([ValueSource(nameof(HexColorsParsingSource))] (string hex, Color expected) data)
|
||||
{
|
||||
var (hex, expected) = data;
|
||||
|
||||
Assert.That(Color.FromHex(hex), Is.EqualTo(expected));
|
||||
}
|
||||
}
|
||||
}
|
||||
92
Robust.Shared.Maths.Tests/Direction_Test.cs
Normal file
92
Robust.Shared.Maths.Tests/Direction_Test.cs
Normal file
@@ -0,0 +1,92 @@
|
||||
using System.Numerics;
|
||||
using NUnit.Framework;
|
||||
using Robust.UnitTesting;
|
||||
|
||||
namespace Robust.Shared.Maths.Tests
|
||||
{
|
||||
[Parallelizable(ParallelScope.All | ParallelScope.Fixtures)]
|
||||
[TestFixture]
|
||||
internal sealed class DirectionTest
|
||||
{
|
||||
private const double Epsilon = 1.0e-8;
|
||||
|
||||
private static IEnumerable<TestCaseData> Sources()
|
||||
{
|
||||
yield return new TestCaseData(1, 0, Direction.East, Angle.FromDegrees(90));
|
||||
yield return new TestCaseData(1, 1, Direction.NorthEast, Angle.FromDegrees(135));
|
||||
yield return new TestCaseData(0, 1, Direction.North, Angle.FromDegrees(180));
|
||||
yield return new TestCaseData(-1, 1, Direction.NorthWest, Angle.FromDegrees(-135));
|
||||
yield return new TestCaseData(-1, 0, Direction.West, Angle.FromDegrees(-90));
|
||||
yield return new TestCaseData(-1, -1, Direction.SouthWest, Angle.FromDegrees(-45));
|
||||
yield return new TestCaseData(0, -1, Direction.South, Angle.FromDegrees(0));
|
||||
yield return new TestCaseData(1, -1, Direction.SouthEast, Angle.FromDegrees(45));
|
||||
}
|
||||
|
||||
[Test]
|
||||
[TestCaseSource(nameof(Sources))]
|
||||
[Parallelizable]
|
||||
public void TestDirectionToAngle(float x, float y, Direction dir, Angle angle)
|
||||
{
|
||||
double control = angle;
|
||||
var val = dir.ToAngle();
|
||||
|
||||
Assert.That(val.Theta, Is.EqualTo(control).Within(Epsilon));
|
||||
}
|
||||
|
||||
[Test]
|
||||
[TestCaseSource(nameof(Sources))]
|
||||
[Parallelizable]
|
||||
public void TestDirectionToVec(float x, float y, Direction dir, Angle _)
|
||||
{
|
||||
var control = new Vector2(x, y).Normalized();
|
||||
var controlInt = new Vector2i((int)x, (int)y);
|
||||
var val = dir.ToVec();
|
||||
var intVec = dir.ToIntVec();
|
||||
|
||||
Assert.That(val, Is.Approximately(control));
|
||||
Assert.That(intVec, Is.EqualTo(controlInt));
|
||||
}
|
||||
|
||||
[Test]
|
||||
[Parallelizable]
|
||||
public void TestDirectionOffset()
|
||||
{
|
||||
var v = new Vector2i(1, 1);
|
||||
var expected = new Vector2i(2, 2);
|
||||
var dir = Direction.NorthEast;
|
||||
|
||||
Assert.That(v.Offset(dir), Is.EqualTo(expected));
|
||||
}
|
||||
|
||||
[Test]
|
||||
[TestCaseSource(nameof(Sources))]
|
||||
[Parallelizable]
|
||||
public void TestVecToAngle(float x, float y, Direction dir, Angle angle)
|
||||
{
|
||||
var target = new Vector2(x, y).Normalized();
|
||||
|
||||
Assert.That(target.ToWorldAngle().Reduced(), Is.Approximately(new Angle(angle)));
|
||||
}
|
||||
|
||||
[Test]
|
||||
[TestCaseSource(nameof(Sources))]
|
||||
[Parallelizable]
|
||||
public void TestVector2ToDirection(float x, float y, Direction dir, Angle angle)
|
||||
{
|
||||
var target = new Vector2(x, y).Normalized();
|
||||
|
||||
Assert.That(target.GetDir(), Is.EqualTo(dir));
|
||||
}
|
||||
|
||||
[Test]
|
||||
[TestCaseSource(nameof(Sources))]
|
||||
[Parallelizable]
|
||||
public void TestAngleToDirection(float x, float y, Direction dir, Angle angle)
|
||||
{
|
||||
var target = new Angle(angle);
|
||||
|
||||
Assert.That(target.GetDir(), Is.EqualTo(dir));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
172
Robust.Shared.Maths.Tests/Matrix3_Test.cs
Normal file
172
Robust.Shared.Maths.Tests/Matrix3_Test.cs
Normal file
@@ -0,0 +1,172 @@
|
||||
using System.Numerics;
|
||||
using NUnit.Framework;
|
||||
using Robust.UnitTesting;
|
||||
|
||||
namespace Robust.Shared.Maths.Tests
|
||||
{
|
||||
[TestFixture]
|
||||
[Parallelizable(ParallelScope.All | ParallelScope.Fixtures)]
|
||||
[TestOf(typeof(Matrix3x2))]
|
||||
internal sealed class Matrix3_Test
|
||||
{
|
||||
private static readonly TestCaseData[] Rotations = new TestCaseData[]
|
||||
{
|
||||
new(Matrix3x2.Identity, Angle.Zero),
|
||||
new(Matrix3x2.CreateRotation(MathF.PI / 2f), new Angle(Math.PI / 2)),
|
||||
new(Matrix3x2.CreateRotation(MathF.PI), new Angle(Math.PI)),
|
||||
};
|
||||
|
||||
[Test, TestCaseSource(nameof(Rotations))]
|
||||
public void GetRotationTest(Matrix3x2 matrix, Angle angle)
|
||||
{
|
||||
Assert.That(angle, Is.EqualTo(matrix.Rotation()));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TranslationTest()
|
||||
{
|
||||
var control = new Vector2(1, 1);
|
||||
var matrix = Matrix3Helpers.CreateTranslation(control);
|
||||
|
||||
var origin = new Vector2(0, 0);
|
||||
var result = Vector2.Transform(origin, matrix);
|
||||
|
||||
Assert.That(control, Is.EqualTo(result), result.ToString);
|
||||
}
|
||||
|
||||
private static readonly IEnumerable<(Vector2, double)> _rotationTests = new[]
|
||||
{
|
||||
(new Vector2( 1, 0).Normalized(), 0.0),
|
||||
(new Vector2( 1, 1).Normalized(), 1 * System.Math.PI / 4.0),
|
||||
(new Vector2( 0, 1).Normalized(), 1 * System.Math.PI / 2.0),
|
||||
(new Vector2(-1, 1).Normalized(), 3 * System.Math.PI / 4.0),
|
||||
(new Vector2(-1, 0).Normalized(), 1 * System.Math.PI / 1.0),
|
||||
(new Vector2(-1,-1).Normalized(), 5 * System.Math.PI / 4.0),
|
||||
(new Vector2( 0,-1).Normalized(), 3 * System.Math.PI / 2.0),
|
||||
(new Vector2( 1,-1).Normalized(), 7 * System.Math.PI / 4.0),
|
||||
};
|
||||
|
||||
[Test]
|
||||
[Sequential]
|
||||
public void RotationTest([ValueSource(nameof(_rotationTests))] (Vector2, double) testCase)
|
||||
{
|
||||
var angle = testCase.Item2;
|
||||
|
||||
var matrix = Matrix3Helpers.CreateRotation((float)angle);
|
||||
|
||||
var test = new Vector2(1, 0);
|
||||
var result = Vector2.Transform(test, matrix);
|
||||
|
||||
var control = testCase.Item1;
|
||||
|
||||
Assert.That(MathHelper.CloseToPercent(control.X, result.X), Is.True, result.ToString);
|
||||
Assert.That(MathHelper.CloseToPercent(control.Y, result.Y), Is.True, result.ToString);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void MultiplyTransformOrder()
|
||||
{
|
||||
var startPoint = new Vector2(1, 0);
|
||||
|
||||
Vector2 scale = new Vector2(2, 2);
|
||||
Angle angle = new Angle(System.MathF.PI / 2);
|
||||
Vector2 offset = new Vector2(-5, -3);
|
||||
|
||||
var scaleMatrix = Matrix3Helpers.CreateScale(scale);
|
||||
var rotateMatrix = Matrix3Helpers.CreateRotation(angle);
|
||||
var translateMatrix = Matrix3Helpers.CreateTranslation(offset);
|
||||
|
||||
// 1. Take the start point -> ( 1, 0)
|
||||
// 2. Scale it by 2 -> ( 2, 0)
|
||||
// 3. Rotate by +90 degrees -> ( 0, 2)
|
||||
// 4. Translate by (-5, -3) -> (-5,-1)
|
||||
var result = Vector2.Transform(startPoint, scaleMatrix * rotateMatrix * translateMatrix);
|
||||
|
||||
Assert.That(result.X, Is.Approximately(-5f));
|
||||
Assert.That(result.Y, Is.Approximately(-1f));
|
||||
|
||||
// repeat but with CreateTransform()
|
||||
var transform = Matrix3Helpers.CreateTransform(offset, angle, scale);
|
||||
result = Vector2.Transform(startPoint, transform);
|
||||
Assert.That(result.X, Is.Approximately(-5f));
|
||||
Assert.That(result.Y, Is.Approximately(-1f));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void InverseTransformTest()
|
||||
{
|
||||
Vector2 scale = new Vector2(2.32f, 2);
|
||||
Angle angle = new Angle(System.MathF.PI / 2.21f);
|
||||
Vector2 offset = new Vector2(-5, 3);
|
||||
|
||||
var transform = Matrix3Helpers.CreateTransform(offset, angle, scale);
|
||||
var expectedInv = Matrix3Helpers.CreateInverseTransform(offset, angle, scale);
|
||||
|
||||
Matrix3x2.Invert(transform, out var invTransform);
|
||||
Assert.That(invTransform.EqualsApprox(expectedInv));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TranslateMultiplyTest()
|
||||
{
|
||||
// Arrange
|
||||
var mat1 = Matrix3Helpers.CreateTranslation(new Vector2(1, 1));
|
||||
var mat2 = Matrix3Helpers.CreateTranslation(new Vector2(-2, -2));
|
||||
var mat3 = Matrix3Helpers.CreateTranslation(new Vector2(3, 3));
|
||||
|
||||
var res2 = Matrix3x2.Multiply(mat1, mat2);
|
||||
var res3 = Matrix3x2.Multiply(res2, mat3);
|
||||
|
||||
// Act
|
||||
Vector2 test = new Vector2(0, 0);
|
||||
var result = Vector2.Transform(test, res3);
|
||||
|
||||
// Assert
|
||||
Assert.That(MathHelper.CloseToPercent(result.X, 2), result.ToString);
|
||||
Assert.That(MathHelper.CloseToPercent(result.Y, 2), result.ToString);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SpaceSwitchTest()
|
||||
{
|
||||
// Arrange
|
||||
var startPoint = new Vector2(2, 0);
|
||||
var rotateMatrix = Matrix3Helpers.CreateRotation((float)(System.Math.PI / 6.3967));
|
||||
var translateMatrix = Matrix3Helpers.CreateTranslation(new Vector2(5.357f, -37.53854f));
|
||||
|
||||
// NOTE: Matrix Product is NOT commutative. OpenTK (and this) uses pre-multiplication, OpenGL and all the tutorials
|
||||
// you will read about it use post-multiplication. So in OpenTK MVP = M*V*P; in OpenGL it is MVP = P*V*M.
|
||||
var transformMatrix = Matrix3x2.Multiply(rotateMatrix, translateMatrix);
|
||||
|
||||
// Act
|
||||
var localPoint = Vector2.Transform(startPoint, transformMatrix);
|
||||
|
||||
Matrix3x2.Invert(transformMatrix, out var invMatrix);
|
||||
var result = Vector2.Transform(localPoint, invMatrix);
|
||||
|
||||
// Assert
|
||||
Assert.That(MathHelper.CloseToPercent(startPoint.X, result.X), Is.True, result.ToString);
|
||||
Assert.That(MathHelper.CloseToPercent(startPoint.Y, result.Y), Is.True, result.ToString);
|
||||
}
|
||||
|
||||
private static readonly (Box2, Box2)[] TestTransformBoxData =
|
||||
{
|
||||
(new Box2(-1, -1, 1, 1), new Box2(8.718287f, 8.718287f, 11.281713f, 11.281713f)),
|
||||
(new Box2(0, 0, 1, 1), new Box2(10, 9.65798f, 11.281713f, 10.9396925f)),
|
||||
};
|
||||
|
||||
[Test]
|
||||
public void TestTransformBox([ValueSource(nameof(TestTransformBoxData))] (Box2 box, Box2 expected) set)
|
||||
{
|
||||
var (box, expected) = set;
|
||||
|
||||
var matrix = Matrix3Helpers.CreateRotation(Angle.FromDegrees(-20));
|
||||
matrix.M31 += 10;
|
||||
matrix.M32 += 10;
|
||||
|
||||
var transformed = matrix.TransformBox(box);
|
||||
|
||||
Assert.That(transformed, Is.Approximately(expected));
|
||||
}
|
||||
}
|
||||
}
|
||||
1003
Robust.Shared.Maths.Tests/NumericsHelpers_Test.cs
Normal file
1003
Robust.Shared.Maths.Tests/NumericsHelpers_Test.cs
Normal file
File diff suppressed because it is too large
Load Diff
26
Robust.Shared.Maths.Tests/Ray_Test.cs
Normal file
26
Robust.Shared.Maths.Tests/Ray_Test.cs
Normal file
@@ -0,0 +1,26 @@
|
||||
using System.Numerics;
|
||||
using NUnit.Framework;
|
||||
using Robust.Shared.Physics;
|
||||
|
||||
namespace Robust.Shared.Maths.Tests
|
||||
{
|
||||
[TestFixture]
|
||||
[Parallelizable(ParallelScope.All | ParallelScope.Fixtures)]
|
||||
[TestOf(typeof(Ray))]
|
||||
internal sealed class Ray_Test
|
||||
{
|
||||
[Test]
|
||||
public void RayIntersectsBoxTest()
|
||||
{
|
||||
var box = new Box2(new Vector2(5, 5), new Vector2(10, -5));
|
||||
var ray = new Ray(new Vector2(0, 1), Vector2.UnitX);
|
||||
|
||||
var result = ray.Intersects(box, out var dist, out var hitPos);
|
||||
|
||||
Assert.That(result, Is.True);
|
||||
Assert.That(dist, Is.EqualTo(5));
|
||||
Assert.That(hitPos.X, Is.EqualTo(5));
|
||||
Assert.That(hitPos.Y, Is.EqualTo(1));
|
||||
}
|
||||
}
|
||||
}
|
||||
24
Robust.Shared.Maths.Tests/Robust.Shared.Maths.Tests.csproj
Normal file
24
Robust.Shared.Maths.Tests/Robust.Shared.Maths.Tests.csproj
Normal file
@@ -0,0 +1,24 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Import Project="..\MSBuild\Robust.Engine.props"/>
|
||||
|
||||
<PropertyGroup>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="JetBrains.Annotations"/>
|
||||
<PackageReference Include="Microsoft.DotNet.RemoteExecutor" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk"/>
|
||||
<PackageReference Include="NUnit"/>
|
||||
<PackageReference Include="NUnit3TestAdapter"/>
|
||||
<PackageReference Include="NUnit.Analyzers"/>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Robust.Shared.Maths\Robust.Shared.Maths.csproj"/>
|
||||
<ProjectReference Include="..\Robust.Shared.Maths.Testing\Robust.Shared.Maths.Testing.csproj" />
|
||||
<ProjectReference Include="..\Robust.Shared\Robust.Shared.csproj"/>
|
||||
</ItemGroup>
|
||||
|
||||
<Import Project="..\MSBuild\Robust.Properties.targets"/>
|
||||
</Project>
|
||||
34
Robust.Shared.Maths.Tests/SimdHelpersTest.cs
Normal file
34
Robust.Shared.Maths.Tests/SimdHelpersTest.cs
Normal file
@@ -0,0 +1,34 @@
|
||||
using System.Runtime.Intrinsics;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace Robust.Shared.Maths.Tests;
|
||||
|
||||
[TestFixture]
|
||||
[Parallelizable]
|
||||
[TestOf(typeof(SimdHelpers))]
|
||||
internal sealed class SimdHelpersTest
|
||||
{
|
||||
[Test]
|
||||
public void TestAddHorizontal128()
|
||||
{
|
||||
var vec = Vector128.Create(1f, 2f, 3f, 4f);
|
||||
|
||||
var sum = SimdHelpers.AddHorizontal128(vec);
|
||||
|
||||
var scalar = sum.GetElement(0);
|
||||
|
||||
Assert.That(scalar, Is.EqualTo(10).Within(0.001f));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestAddHorizontal256()
|
||||
{
|
||||
var vec = Vector256.Create(1f, 2f, 3f, 4f, 5f, 6f, 7f, 8f);
|
||||
|
||||
var sum = SimdHelpers.AddHorizontal256(vec);
|
||||
|
||||
var scalar = sum.GetElement(0);
|
||||
|
||||
Assert.That(scalar, Is.EqualTo(36).Within(0.001f));
|
||||
}
|
||||
}
|
||||
382
Robust.Shared.Maths.Tests/UIBox2_Test.cs
Normal file
382
Robust.Shared.Maths.Tests/UIBox2_Test.cs
Normal file
@@ -0,0 +1,382 @@
|
||||
using System.Numerics;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace Robust.Shared.Maths.Tests
|
||||
{
|
||||
[Parallelizable(ParallelScope.All | ParallelScope.Fixtures)]
|
||||
[TestFixture]
|
||||
[TestOf(typeof(UIBox2))]
|
||||
internal sealed class UIBox2_Test
|
||||
{
|
||||
private static IEnumerable<(float left, float top, float right, float bottom)> Sources => new (float, float, float, float)[]
|
||||
{
|
||||
(0, 0, 0, 0),
|
||||
(0, 0, 0, 1),
|
||||
(0, 0, 1, 0),
|
||||
(0, 0, 1, 1),
|
||||
(0, -1, 0, 0),
|
||||
(0, -1, 0, 1),
|
||||
(0, -1, 1, 0),
|
||||
(0, -1, 1, 1),
|
||||
(-1, 0, 0, 0),
|
||||
(-1, 0, 0, 1),
|
||||
(-1, 0, 1, 0),
|
||||
(-1, 0, 1, 1),
|
||||
(-1, -1, 0, 0),
|
||||
(-1, -1, 0, 1),
|
||||
(-1, -1, 1, 0),
|
||||
(-1, -1, 1, 1)
|
||||
};
|
||||
|
||||
private static IEnumerable<(float x, float y)> SmallTranslations => new []
|
||||
{
|
||||
(0, 0.1f),
|
||||
(0.1f, 0),
|
||||
(0.1f, 0.1f),
|
||||
(0, -0.1f),
|
||||
(0.1f, -0.1f),
|
||||
(-0.1f, 0),
|
||||
(-0.1f, 0.1f),
|
||||
(-0.1f, -0.1f)
|
||||
};
|
||||
|
||||
private static IEnumerable<(float x, float y)> LargeTranslations => new (float, float)[]
|
||||
{
|
||||
(0, 5),
|
||||
(5, 0),
|
||||
(5, 5),
|
||||
(0, -5),
|
||||
(5, -5),
|
||||
(-5, 0),
|
||||
(-5, 5),
|
||||
(-5, -5)
|
||||
};
|
||||
|
||||
private static IEnumerable<float> Scalars => new []
|
||||
{
|
||||
0.0f,
|
||||
0.1f,
|
||||
1.0f,
|
||||
5.0f,
|
||||
10.0f
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Check whether the sources list has correct data.
|
||||
/// That is, no boxes where left > right or top > bottom.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void AssertSourcesValid([ValueSource(nameof(Sources))] (float, float, float, float) test)
|
||||
{
|
||||
var (left, top, right, bottom) = test;
|
||||
Assert.That(right, Is.GreaterThanOrEqualTo(left));
|
||||
Assert.That(bottom, Is.GreaterThanOrEqualTo(top));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Box2VectorConstructor([ValueSource(nameof(Sources))] (float, float, float, float) test)
|
||||
{
|
||||
var (left, top, right, bottom) = test;
|
||||
var box = new UIBox2(new Vector2(left, top), new Vector2(right, bottom));
|
||||
|
||||
Assert.That(box.Left, Is.EqualTo(left));
|
||||
Assert.That(box.Top, Is.EqualTo(top));
|
||||
Assert.That(box.Right, Is.EqualTo(right));
|
||||
Assert.That(box.Bottom, Is.EqualTo(bottom));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Box2EdgesConstructor([ValueSource(nameof(Sources))] (float, float, float, float) test)
|
||||
{
|
||||
var (left, top, right, bottom) = test;
|
||||
var box = new UIBox2(left, top, right, bottom);
|
||||
|
||||
Assert.That(box.Left, Is.EqualTo(left));
|
||||
Assert.That(box.Top, Is.EqualTo(top));
|
||||
Assert.That(box.Right, Is.EqualTo(right));
|
||||
Assert.That(box.Bottom, Is.EqualTo(bottom));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Box2CornerVectorProperties([ValueSource(nameof(Sources))] (float, float, float, float) test)
|
||||
{
|
||||
var (left, top, right, bottom) = test;
|
||||
var box = new UIBox2(left, top, right, bottom);
|
||||
|
||||
var br = new Vector2(right, bottom);
|
||||
var tl = new Vector2(left, top);
|
||||
var tr = new Vector2(right, top);
|
||||
var bl = new Vector2(left, bottom);
|
||||
|
||||
Assert.That(box.BottomRight, Is.EqualTo(br));
|
||||
Assert.That(box.TopLeft, Is.EqualTo(tl));
|
||||
Assert.That(box.TopRight, Is.EqualTo(tr));
|
||||
Assert.That(box.BottomLeft, Is.EqualTo(bl));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Box2FromDimensionsFloats([ValueSource(nameof(Sources))] (float, float, float, float) test)
|
||||
{
|
||||
var (left, top, right, bottom) = test;
|
||||
|
||||
var width = Math.Abs(left - right);
|
||||
var height = Math.Abs(top - bottom);
|
||||
|
||||
var box = UIBox2.FromDimensions(left, top, width, height);
|
||||
|
||||
Assert.That(box.Left, Is.EqualTo(left));
|
||||
Assert.That(box.Top, Is.EqualTo(top));
|
||||
Assert.That(box.Right, Is.EqualTo(left + width));
|
||||
Assert.That(box.Bottom, Is.EqualTo(top + height));
|
||||
|
||||
Assert.That(box.Width, Is.EqualTo(width));
|
||||
Assert.That(box.Height, Is.EqualTo(height));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Box2FromDimensionsVectors([ValueSource(nameof(Sources))] (float, float, float, float) test)
|
||||
{
|
||||
var (left, top, right, bottom) = test;
|
||||
|
||||
var width = Math.Abs(left - right);
|
||||
var height = Math.Abs(top - bottom);
|
||||
var size = new Vector2(width, height);
|
||||
|
||||
var box = UIBox2.FromDimensions(new Vector2(left, top), size);
|
||||
|
||||
Assert.That(box.Left, Is.EqualTo(left));
|
||||
Assert.That(box.Top, Is.EqualTo(top));
|
||||
Assert.That(box.Right, Is.EqualTo(left + width));
|
||||
Assert.That(box.Bottom, Is.EqualTo(top + height));
|
||||
|
||||
Assert.That(box.Size, Is.EqualTo(size));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Box2IntersectsSelf([ValueSource(nameof(Sources))] (float, float, float, float) test)
|
||||
{
|
||||
var (left, top, right, bottom) = test;
|
||||
|
||||
var box = new UIBox2(left, top, right, bottom);
|
||||
|
||||
Assert.That(box.Intersects(box));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Box2IntersectsWithSmallTranslation([ValueSource(nameof(SmallTranslations))] (float, float) test)
|
||||
{
|
||||
var (x, y) = test;
|
||||
|
||||
var box = new UIBox2(-1, -1, 1, 1);
|
||||
var translatedBox = box.Translated(new Vector2(x, y));
|
||||
|
||||
Assert.That(box.Intersects(translatedBox));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Box2NotIntersectsWithLargeTranslation([ValueSource(nameof(LargeTranslations))] (float, float) test)
|
||||
{
|
||||
var (x, y) = test;
|
||||
|
||||
var box = new UIBox2(-1, -1, 1, 1);
|
||||
var translatedBox = box.Translated(new Vector2(x, y));
|
||||
|
||||
Assert.That(box.Intersects(translatedBox), Is.False);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Box2IsEmpty()
|
||||
{
|
||||
var degenerateBox = new UIBox2(0, 0, 0, 0);
|
||||
|
||||
Assert.That(degenerateBox.IsEmpty());
|
||||
|
||||
var tallDegenBox = new UIBox2(0, -1, 0, 1);
|
||||
var wideDegenBox = new UIBox2(-1, 0, 1, 0);
|
||||
var meatyBox = new UIBox2(-1, -1, 1, 1);
|
||||
|
||||
Assert.That(tallDegenBox.IsEmpty(), Is.False);
|
||||
Assert.That(wideDegenBox.IsEmpty(), Is.False);
|
||||
Assert.That(meatyBox.IsEmpty(), Is.False);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Box2NotEnclosesSelf()
|
||||
{
|
||||
var box = new UIBox2(-1, -1, 1, 1);
|
||||
|
||||
Assert.That(box.Encloses(box), Is.False);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Box2ScaledEncloses()
|
||||
{
|
||||
var box = new UIBox2(-1, -1, 1, 1);
|
||||
var smallBox = box.Scale(0.5f);
|
||||
var bigBox = box.Scale(2.0f);
|
||||
|
||||
Assert.That(box.Encloses(smallBox));
|
||||
Assert.That(box.Encloses(bigBox), Is.False);
|
||||
Assert.That(smallBox.Encloses(box), Is.False);
|
||||
Assert.That(bigBox.Encloses(box));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Box2TranslatedNotEncloses([ValueSource(nameof(LargeTranslations))] (float, float) test)
|
||||
{
|
||||
var (x, y) = test;
|
||||
|
||||
var box = new UIBox2(-1, -1, 1, 1);
|
||||
var translatedBox = box.Translated(new Vector2(x, y));
|
||||
|
||||
Assert.That(box.Encloses(translatedBox), Is.False);
|
||||
Assert.That(translatedBox.Encloses(box), Is.False);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Box2NotContainsSelfOpen()
|
||||
{
|
||||
var box = new UIBox2(-1, -1, 1, 1);
|
||||
|
||||
Assert.That(box.Contains(box.BottomLeft, false), Is.False);
|
||||
Assert.That(box.Contains(box.TopLeft, false), Is.False);
|
||||
Assert.That(box.Contains(box.TopRight, false), Is.False);
|
||||
Assert.That(box.Contains(box.BottomRight, false), Is.False);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Box2ContainsSelfClosed()
|
||||
{
|
||||
var box = new UIBox2(-1, -1, 1, 1);
|
||||
|
||||
Assert.That(box.Contains(box.BottomLeft));
|
||||
Assert.That(box.Contains(box.TopLeft));
|
||||
Assert.That(box.Contains(box.TopRight));
|
||||
Assert.That(box.Contains(box.BottomRight));
|
||||
|
||||
var bl = box.BottomLeft;
|
||||
var tl = box.TopLeft;
|
||||
var tr = box.TopRight;
|
||||
var br = box.BottomRight;
|
||||
|
||||
Assert.That(box.Contains(bl.X, bl.Y));
|
||||
Assert.That(box.Contains(tl.X, tl.Y));
|
||||
Assert.That(box.Contains(tr.X, tr.Y));
|
||||
Assert.That(box.Contains(br.X, br.Y));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Box2Contains([ValueSource(nameof(SmallTranslations))] (float, float) test)
|
||||
{
|
||||
var (x, y) = test;
|
||||
var vec = new Vector2(x, y);
|
||||
|
||||
var box = new UIBox2(-1, -1, 1, 1);
|
||||
|
||||
Assert.That(box.Contains(x, y));
|
||||
Assert.That(box.Contains(vec));
|
||||
Assert.That(box.Contains(vec, false));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Box2NotContains([ValueSource(nameof(LargeTranslations))] (float, float) test)
|
||||
{
|
||||
var (x, y) = test;
|
||||
var vec = new Vector2(x, y);
|
||||
|
||||
var box = new UIBox2(-1, -1, 1, 1);
|
||||
|
||||
Assert.That(box.Contains(x, y), Is.False);
|
||||
Assert.That(box.Contains(vec), Is.False);
|
||||
Assert.That(box.Contains(vec, false), Is.False);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Box2Scale([ValueSource(nameof(Scalars))] float scalar)
|
||||
{
|
||||
var box = new UIBox2(-1, -1, 1, 1);
|
||||
var scaledBox = box.Scale(scalar);
|
||||
|
||||
Assert.That(scaledBox.Center, Is.EqualTo(box.Center));
|
||||
Assert.That(scaledBox.Size, Is.EqualTo(box.Size * scalar));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Box2ScaleNegativeException()
|
||||
{
|
||||
var box = new UIBox2(-1, -1, 1, 1);
|
||||
Assert.That(() => box.Scale(-1), Throws.Exception);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Box2Translated([ValueSource(nameof(LargeTranslations))] (float, float) test)
|
||||
{
|
||||
var (x, y) = test;
|
||||
var vec = new Vector2(x, y);
|
||||
|
||||
var box = new UIBox2(-1, -1, 1, 1);
|
||||
var scaledBox = box.Translated(vec);
|
||||
|
||||
Assert.That(scaledBox.Left, Is.EqualTo(box.Left + x));
|
||||
Assert.That(scaledBox.Top, Is.EqualTo(box.Top + y));
|
||||
Assert.That(scaledBox.Bottom, Is.EqualTo(box.Bottom + y));
|
||||
Assert.That(scaledBox.Right, Is.EqualTo(box.Right + x));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Box2Equals([ValueSource(nameof(Sources))] (float, float, float, float) test)
|
||||
{
|
||||
var (left, top, right, bottom) = test;
|
||||
|
||||
var controlBox = new UIBox2(left, top, right, bottom);
|
||||
var differentBox = new UIBox2(-MathHelper.Pi, -MathHelper.Pi, MathHelper.Pi, MathHelper.Pi);
|
||||
var sameBox = new UIBox2(left, top, right, bottom);
|
||||
Object sameBoxAsObject = sameBox;
|
||||
UIBox2? nullBox = null;
|
||||
Vector2 notBox = new Vector2(left, top);
|
||||
|
||||
Assert.That(controlBox.Equals(controlBox));
|
||||
Assert.That(controlBox.Equals(differentBox), Is.False);
|
||||
Assert.That(controlBox.Equals(sameBox));
|
||||
Assert.That(controlBox.Equals(sameBoxAsObject));
|
||||
// ReSharper disable once ExpressionIsAlwaysNull
|
||||
Assert.That(controlBox.Equals(nullBox), Is.False);
|
||||
// ReSharper disable once SuspiciousTypeConversion.Global
|
||||
Assert.That(controlBox.Equals(notBox), Is.False);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Box2EqualsOperator([ValueSource(nameof(Sources))] (float, float, float, float) test)
|
||||
{
|
||||
var (left, top, right, bottom) = test;
|
||||
|
||||
var controlBox = new UIBox2(left, top, right, bottom);
|
||||
var differentBox = new UIBox2(-MathHelper.Pi, -MathHelper.Pi, MathHelper.Pi, MathHelper.Pi);
|
||||
var sameBox = new UIBox2(left, top, right, bottom);
|
||||
|
||||
#pragma warning disable CS1718 // Comparison made to same variable
|
||||
// ReSharper disable once EqualExpressionComparison
|
||||
Assert.That(controlBox == controlBox);
|
||||
#pragma warning restore CS1718 // Comparison made to same variable
|
||||
Assert.That(controlBox == differentBox, Is.False);
|
||||
Assert.That(controlBox == sameBox);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Box2InequalsOperator([ValueSource(nameof(Sources))] (float, float, float, float) test)
|
||||
{
|
||||
var (left, top, right, bottom) = test;
|
||||
|
||||
var controlBox = new UIBox2(left, top, right, bottom);
|
||||
var differentBox = new UIBox2(-MathHelper.Pi, -MathHelper.Pi, MathHelper.Pi, MathHelper.Pi);
|
||||
var sameBox = new UIBox2(left, top, right, bottom);
|
||||
|
||||
#pragma warning disable CS1718 // Comparison made to same variable
|
||||
// ReSharper disable once EqualExpressionComparison
|
||||
Assert.That(controlBox != controlBox, Is.False);
|
||||
#pragma warning restore CS1718 // Comparison made to same variable
|
||||
Assert.That(controlBox != differentBox);
|
||||
Assert.That(controlBox != sameBox, Is.False);
|
||||
}
|
||||
}
|
||||
}
|
||||
249
Robust.Shared.Maths.Tests/UIBox2i_Test.cs
Normal file
249
Robust.Shared.Maths.Tests/UIBox2i_Test.cs
Normal file
@@ -0,0 +1,249 @@
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace Robust.Shared.Maths.Tests
|
||||
{
|
||||
[Parallelizable(ParallelScope.All | ParallelScope.Fixtures)]
|
||||
[TestFixture]
|
||||
[TestOf(typeof(UIBox2i))]
|
||||
internal sealed class UIBox2i_Test
|
||||
{
|
||||
private static IEnumerable<(int left, int top, int right, int bottom)> Sources => new (int, int, int, int)[]
|
||||
{
|
||||
(0, 0, 0, 0),
|
||||
(0, 0, 0, 10),
|
||||
(0, 0, 10, 0),
|
||||
(0, 0, 10, 10),
|
||||
(0, -10, 0, 0),
|
||||
(0, -10, 0, 10),
|
||||
(0, -10, 10, 0),
|
||||
(0, -10, 10, 10),
|
||||
(-10, 0, 0, 0),
|
||||
(-10, 0, 0, 10),
|
||||
(-10, 0, 10, 0),
|
||||
(-10, 0, 10, 10),
|
||||
(-10, -10, 0, 0),
|
||||
(-10, -10, 0, 10),
|
||||
(-10, -10, 10, 0),
|
||||
(-10, -10, 10, 10)
|
||||
};
|
||||
|
||||
private static IEnumerable<(int x, int y)> SmallTranslations => new (int, int)[]
|
||||
{
|
||||
(0, 1),
|
||||
(1, 0),
|
||||
(1, 1),
|
||||
(0, -1),
|
||||
(1, -1),
|
||||
(-1, 0),
|
||||
(-1, 1),
|
||||
(-1, -1)
|
||||
};
|
||||
|
||||
private static IEnumerable<(int x, int y)> LargeTranslations => new (int, int)[]
|
||||
{
|
||||
(0, 20),
|
||||
(20, 0),
|
||||
(20, 20),
|
||||
(0, -20),
|
||||
(20, -20),
|
||||
(-20, 0),
|
||||
(-20, 20),
|
||||
(-20, -20)
|
||||
};
|
||||
|
||||
private static IEnumerable<(UIBox2i a, UIBox2i b, UIBox2i? expected)> Intersections =>
|
||||
new (UIBox2i, UIBox2i, UIBox2i?)[]
|
||||
{
|
||||
(new UIBox2i(0, 0, 5, 5), new UIBox2i(2, 2, 4, 4), new UIBox2i(2, 2, 4, 4)),
|
||||
(new UIBox2i(0, 0, 5, 5), new UIBox2i(3, 3, 7, 7), new UIBox2i(3, 3, 5, 5)),
|
||||
(new UIBox2i(2, 0, 5, 5), new UIBox2i(0, 3, 4, 7), new UIBox2i(2, 3, 4, 5)),
|
||||
(new UIBox2i(2, 0, 5, 5), new UIBox2i(6, 6, 10, 10), null),
|
||||
};
|
||||
|
||||
[Test]
|
||||
public void Box2iVectorConstructor([ValueSource(nameof(Sources))] (int, int, int, int) test)
|
||||
{
|
||||
var (left, top, right, bottom) = test;
|
||||
var box = new UIBox2i(new Vector2i(left, top), new Vector2i(right, bottom));
|
||||
|
||||
Assert.That(box.Left, Is.EqualTo(left));
|
||||
Assert.That(box.Top, Is.EqualTo(top));
|
||||
Assert.That(box.Right, Is.EqualTo(right));
|
||||
Assert.That(box.Bottom, Is.EqualTo(bottom));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Box2iEdgesConstructor([ValueSource(nameof(Sources))] (int, int, int, int) test)
|
||||
{
|
||||
var (left, top, right, bottom) = test;
|
||||
var box = new UIBox2i(left, top, right, bottom);
|
||||
|
||||
Assert.That(box.Left, Is.EqualTo(left));
|
||||
Assert.That(box.Top, Is.EqualTo(top));
|
||||
Assert.That(box.Right, Is.EqualTo(right));
|
||||
Assert.That(box.Bottom, Is.EqualTo(bottom));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Box2iCornerVectorProperties([ValueSource(nameof(Sources))] (int, int, int, int) test)
|
||||
{
|
||||
var (left, top, right, bottom) = test;
|
||||
var box = new UIBox2i(left, top, right, bottom);
|
||||
|
||||
var br = new Vector2i(right, bottom);
|
||||
var tl = new Vector2i(left, top);
|
||||
var tr = new Vector2i(right, top);
|
||||
var bl = new Vector2i(left, bottom);
|
||||
|
||||
Assert.That(box.BottomRight, Is.EqualTo(br));
|
||||
Assert.That(box.TopLeft, Is.EqualTo(tl));
|
||||
Assert.That(box.TopRight, Is.EqualTo(tr));
|
||||
Assert.That(box.BottomLeft, Is.EqualTo(bl));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Box2iFromDimensionsInt([ValueSource(nameof(Sources))] (int, int, int, int) test)
|
||||
{
|
||||
var (left, top, right, bottom) = test;
|
||||
|
||||
var width = Math.Abs(left - right);
|
||||
var height = Math.Abs(top - bottom);
|
||||
|
||||
var box = UIBox2i.FromDimensions(left, top, width, height);
|
||||
|
||||
Assert.That(box.Left, Is.EqualTo(left));
|
||||
Assert.That(box.Top, Is.EqualTo(top));
|
||||
Assert.That(box.Right, Is.EqualTo(left + width));
|
||||
Assert.That(box.Bottom, Is.EqualTo(top + height));
|
||||
|
||||
Assert.That(box.Width, Is.EqualTo(width));
|
||||
Assert.That(box.Height, Is.EqualTo(height));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Box2iFromDimensionsVectors([ValueSource(nameof(Sources))] (int, int, int, int) test)
|
||||
{
|
||||
var (left, top, right, bottom) = test;
|
||||
|
||||
var width = Math.Abs(left - right);
|
||||
var height = Math.Abs(top - bottom);
|
||||
var size = new Vector2i(width, height);
|
||||
|
||||
var box = UIBox2i.FromDimensions(new Vector2i(left, top), size);
|
||||
|
||||
Assert.That(box.Left, Is.EqualTo(left));
|
||||
Assert.That(box.Top, Is.EqualTo(top));
|
||||
Assert.That(box.Right, Is.EqualTo(left + width));
|
||||
Assert.That(box.Bottom, Is.EqualTo(top + height));
|
||||
|
||||
Assert.That(box.Size, Is.EqualTo(size));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Box2iNotContainsSelfOpen()
|
||||
{
|
||||
var box = new UIBox2i(-1, -1, 1, 1);
|
||||
|
||||
Assert.That(box.Contains(box.BottomLeft, false), Is.False);
|
||||
Assert.That(box.Contains(box.TopLeft, false), Is.False);
|
||||
Assert.That(box.Contains(box.TopRight, false), Is.False);
|
||||
Assert.That(box.Contains(box.BottomRight, false), Is.False);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Box2iContainsSelfClosed()
|
||||
{
|
||||
var box = new UIBox2i(-1, -1, 1, 1);
|
||||
|
||||
Assert.That(box.Contains(box.BottomLeft));
|
||||
Assert.That(box.Contains(box.TopLeft));
|
||||
Assert.That(box.Contains(box.TopRight));
|
||||
Assert.That(box.Contains(box.BottomRight));
|
||||
|
||||
var bl = box.BottomLeft;
|
||||
var tl = box.TopLeft;
|
||||
var tr = box.TopRight;
|
||||
var br = box.BottomRight;
|
||||
|
||||
Assert.That(box.Contains(bl.X, bl.Y));
|
||||
Assert.That(box.Contains(tl.X, tl.Y));
|
||||
Assert.That(box.Contains(tr.X, tr.Y));
|
||||
Assert.That(box.Contains(br.X, br.Y));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Box2iContains([ValueSource(nameof(SmallTranslations))]
|
||||
(int, int) test)
|
||||
{
|
||||
var (x, y) = test;
|
||||
var vec = new Vector2i(x, y);
|
||||
|
||||
var box = new UIBox2i(-2, -2, 2, 2);
|
||||
|
||||
Assert.That(box.Contains(x, y));
|
||||
Assert.That(box.Contains(vec));
|
||||
Assert.That(box.Contains(vec, false));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Box2iNotContains([ValueSource(nameof(LargeTranslations))]
|
||||
(int, int) test)
|
||||
{
|
||||
var (x, y) = test;
|
||||
var vec = new Vector2i(x, y);
|
||||
|
||||
var box = new UIBox2i(-2, -2, 2, 2);
|
||||
|
||||
Assert.That(box.Contains(x, y), Is.False);
|
||||
Assert.That(box.Contains(vec), Is.False);
|
||||
Assert.That(box.Contains(vec, false), Is.False);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Box2iTranslated([ValueSource(nameof(LargeTranslations))]
|
||||
(int, int) test)
|
||||
{
|
||||
var (x, y) = test;
|
||||
var vec = new Vector2i(x, y);
|
||||
|
||||
var box = new UIBox2i(-1, -1, 1, 1);
|
||||
var scaledBox = box.Translated(vec);
|
||||
|
||||
Assert.That(scaledBox.Left, Is.EqualTo(box.Left + x));
|
||||
Assert.That(scaledBox.Top, Is.EqualTo(box.Top + y));
|
||||
Assert.That(scaledBox.Bottom, Is.EqualTo(box.Bottom + y));
|
||||
Assert.That(scaledBox.Right, Is.EqualTo(box.Right + x));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Box2iEquals([ValueSource(nameof(Sources))] (int, int, int, int) test)
|
||||
{
|
||||
var (left, top, right, bottom) = test;
|
||||
|
||||
var controlBox = new UIBox2i(left, top, right, bottom);
|
||||
var differentBox = new UIBox2i(-3, -3, 3, 3);
|
||||
var sameBox = new UIBox2i(left, top, right, bottom);
|
||||
Object sameBoxAsObject = sameBox;
|
||||
UIBox2i? nullBox = null;
|
||||
Vector2i notBox = new Vector2i(left, top);
|
||||
|
||||
Assert.That(controlBox.Equals(controlBox));
|
||||
Assert.That(controlBox.Equals(differentBox), Is.False);
|
||||
Assert.That(controlBox.Equals(sameBox));
|
||||
Assert.That(controlBox.Equals(sameBoxAsObject));
|
||||
Assert.That(controlBox.Equals(nullBox), Is.False);
|
||||
Assert.That(controlBox.Equals(notBox), Is.False);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void UIBox2iIntersection(
|
||||
[ValueSource(nameof(Intersections))] (UIBox2i a, UIBox2i b, UIBox2i? expected) value)
|
||||
{
|
||||
var (a, b, expected) = value;
|
||||
|
||||
// This should be a symmetric operation.
|
||||
Assert.That(a.Intersection(b), Is.EqualTo(expected));
|
||||
Assert.That(b.Intersection(a), Is.EqualTo(expected));
|
||||
}
|
||||
}
|
||||
}
|
||||
90
Robust.Shared.Maths.Tests/Vector2_Test.cs
Normal file
90
Robust.Shared.Maths.Tests/Vector2_Test.cs
Normal file
@@ -0,0 +1,90 @@
|
||||
using System.Numerics;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace Robust.Shared.Maths.Tests
|
||||
{
|
||||
[TestFixture]
|
||||
[Parallelizable(ParallelScope.All | ParallelScope.Fixtures)]
|
||||
[TestOf(typeof(Vector2))]
|
||||
internal sealed class Vector2_Test
|
||||
{
|
||||
[Test]
|
||||
[Sequential]
|
||||
public void ConstructorTest([Random(-1.0f, 1.0f, 5)] float x,
|
||||
[Random(-1.0f, 1.0f, 5)] float y)
|
||||
{
|
||||
var vec = new Vector2(x, y);
|
||||
Assert.That(vec.X, Is.EqualTo(x));
|
||||
Assert.That(vec.Y, Is.EqualTo(y));
|
||||
|
||||
Assert.That(Vector2.One, Is.EqualTo(new Vector2(1, 1)));
|
||||
Assert.That(Vector2.Zero, Is.EqualTo(new Vector2(0, 0)));
|
||||
Assert.That(new Vector2(), Is.EqualTo(new Vector2(0, 0)));
|
||||
}
|
||||
|
||||
// Testing basic operators: +, -, *, /
|
||||
[Test]
|
||||
[Sequential]
|
||||
public void ArithmeticTest([Random(-1.0f, 1.0f, 5)] float x1,
|
||||
[Random(-1.0f, 1.0f, 5)] float y1,
|
||||
[Random(-1.0f, 1.0f, 5)] float x2,
|
||||
[Random(-1.0f, 1.0f, 5)] float y2,
|
||||
[Random(-1.0f, 1.0f, 5)] float scale)
|
||||
{
|
||||
var vec1 = new Vector2(x1, y1);
|
||||
var vec2 = new Vector2(x2, y2);
|
||||
|
||||
var add = vec1 + vec2;
|
||||
Assert.That(add.X, Is.EqualTo(x1 + x2));
|
||||
Assert.That(add.Y, Is.EqualTo(y1 + y2));
|
||||
|
||||
var sub = vec1 - vec2;
|
||||
Assert.That(sub.X, Is.EqualTo(x1 - x2));
|
||||
Assert.That(sub.Y, Is.EqualTo(y1 - y2));
|
||||
|
||||
var neg = -vec1;
|
||||
Assert.That(neg.X, Is.EqualTo(-x1));
|
||||
Assert.That(neg.Y, Is.EqualTo(-y1));
|
||||
|
||||
var mul = vec1 * vec2;
|
||||
Assert.That(mul.X, Is.EqualTo(x1 * x2));
|
||||
Assert.That(mul.Y, Is.EqualTo(y1 * y2));
|
||||
|
||||
var muls = vec1 * scale;
|
||||
Assert.That(muls.X, Is.EqualTo(x1 * scale));
|
||||
Assert.That(muls.Y, Is.EqualTo(y1 * scale));
|
||||
|
||||
var div = vec1 / vec2;
|
||||
Assert.That(div.X, Is.EqualTo(x1 / x2));
|
||||
Assert.That(div.Y, Is.EqualTo(y1 / y2));
|
||||
|
||||
var divs = vec1 / scale;
|
||||
Assert.That(divs.X, Is.EqualTo(x1 / scale));
|
||||
Assert.That(divs.Y, Is.EqualTo(y1 / scale));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ComponentMinMaxTest()
|
||||
{
|
||||
var vec1 = new Vector2(-1, 1);
|
||||
var vec2 = new Vector2(1, -1);
|
||||
|
||||
Assert.That(Vector2.Min(vec1, vec2), Is.EqualTo(new Vector2(-1, -1)));
|
||||
Assert.That(Vector2.Max(vec1, vec2), Is.EqualTo(new Vector2(1, 1)));
|
||||
}
|
||||
|
||||
[Test]
|
||||
[Sequential]
|
||||
public void OpenTKConversionTest([Random(-1.0f, 1.0f, 5)] float x,
|
||||
[Random(-1.0f, 1.0f, 5)] float y)
|
||||
{
|
||||
var vec = new Vector2(x, y);
|
||||
Vector2 ovec = vec;
|
||||
|
||||
Assert.That(ovec.X, Is.EqualTo(x));
|
||||
Assert.That(ovec.Y, Is.EqualTo(y));
|
||||
|
||||
Assert.That(ovec, Is.EqualTo(vec));
|
||||
}
|
||||
}
|
||||
}
|
||||
20
Robust.Shared.Maths.Tests/Vector2u_Test.cs
Normal file
20
Robust.Shared.Maths.Tests/Vector2u_Test.cs
Normal file
@@ -0,0 +1,20 @@
|
||||
using System.Text.Json;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace Robust.Shared.Maths.Tests
|
||||
{
|
||||
[TestFixture]
|
||||
[Parallelizable]
|
||||
[TestOf(typeof(Vector2u))]
|
||||
internal sealed class Vector2u_Test
|
||||
{
|
||||
// This test basically only exists because RSI loading needs it.
|
||||
[Test]
|
||||
public void TestJsonDeserialization()
|
||||
{
|
||||
Assert.That(
|
||||
JsonSerializer.Deserialize<Vector2u>("{\"x\": 10, \"y\": 10}",
|
||||
new JsonSerializerOptions(JsonSerializerDefaults.Web)), Is.EqualTo(new Vector2u(10, 10)));
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user