using System; using System.Collections.Generic; using System.Linq; using Chernobyl.Mathematics.Movement; using Chernobyl.Mathematics.Vectors; using NUnit.Framework; namespace Chernobyl.Mathematics.Geometry { /// /// A helper test fixture base class that is used to test types that /// implement interface. /// public abstract class ArcTests { [Test, Description("A test to ensure that the IArc throws an " + "ArgumentOutOfRangeException if client code attempts to construct " + "the IArc with zero points.")] public void ZeroPointsArgumentOutOfRangeException() { Assert.Throws(() => CreateArc(new ITransform[0])); } [Test, Description("A test to ensure that the IArc throws an " + "ArgumentOutOfRangeException if client code attempts to construct " + "the IArc with one point.")] public void OnePointArgumentOutOfRangeException() { Assert.Throws(() => CreateArc(new ITransform[1])); } [Test, Description("A test to ensure that the IArc is properly constructed " + "if given two points.")] public void TwoPointsCreation() { IArc arc = CreateArc(new ITransform[2]); Assert.AreEqual(2, arc.Count(), "Unexpected number of " + "ITransform instances in the returned IArc."); } [Test, Description("A test to ensure that the IArc throws an " + "ArgumentOutOfRangeException if client code attempts to construct " + "the IArc with less than one line segments.")] public void ZeroLineSegmentsArgumentOutOfRangeException() { Assert.Throws(() => CreateArc((IEnumerable)new ILineSegment[0])); } [Test, Description("A test to ensure that the IArc throws an " + "ArgumentException if client code attempts to construct " + "the IArc with line segments that do not connect together.")] public void UnconnectedLineSegmentsArgumentException() { ITransform point1 = new MatrixTransform(); point1.Position = new Vector3(0, 0, 0); ITransform point2 = new MatrixTransform(); point2.Position = new Vector3(5, 0, 0); ITransform point3 = new MatrixTransform(); point3.Position = new Vector3(6, 0, 0); ITransform point4 = new MatrixTransform(); point4.Position = new Vector3(10, 0, 0); ILineSegment[] lines = { new LineSegment(point1, point2), new LineSegment(point3, point4), }; Assert.Throws(() => CreateArc((IEnumerable)lines)); } [Test, Description("A test to ensure that the IArc is created " + "properly when given only one line segment.")] public void OneLineSegmentsConstruction() { const int uniquePointCount = 2; ITransform point1 = new MatrixTransform(); point1.Position = new Vector3(0, 0, 0); ITransform point2 = new MatrixTransform(); point2.Position = new Vector3(5, 0, 0); ILineSegment[] lines = { new LineSegment(point1, point2) }; IArc arc = CreateArc((IEnumerable)lines); Assert.AreEqual(uniquePointCount, arc.Count(), "The are too few or too many points in the arc."); Assert.AreEqual(point1.Position, arc.ElementAt(0).Position, "The first arc point is not the point that was expected."); Assert.AreEqual(point2.Position, arc.ElementAt(1).Position, "The second arc point is not the point that was expected."); } [Test, Description("A test to ensure that the IArc places " + "the points in the proper order even if it is given line " + "segments that are out of order.")] public void OrderedPointsGivenOutOfOrderLineSegments() { const int uniquePointCount = 4; ITransform point1 = new MatrixTransform(); point1.Position = new Vector3(0, 0, 0); ITransform point2 = new MatrixTransform(); point2.Position = new Vector3(5, 0, 0); ITransform point3 = new MatrixTransform(); point3.Position = new Vector3(5, 0, 0); ITransform point4 = new MatrixTransform(); point4.Position = new Vector3(10, 0, 0); ITransform point5 = new MatrixTransform(); point5.Position = new Vector3(10, 0, 0); ITransform point6 = new MatrixTransform(); point6.Position = new Vector3(15, 0, 0); ILineSegment[] lines = { new LineSegment(point1, point2), new LineSegment(point5, point6), new LineSegment(point3, point4), }; IArc arc = CreateArc((IEnumerable)lines); // Compare the points. Remember that although we used 6 points to // compose the line segments above, only 4 of those points are unique // so only 4 points should be in the arc. Assert.AreEqual(uniquePointCount, arc.Count(), "The are too few or too many points in the arc."); Assert.AreEqual(point1.Position, arc.ElementAt(0).Position, "The first arc point is not the point that was expected."); Assert.AreEqual(point3.Position, arc.ElementAt(1).Position, "The second arc point is not the point that was expected."); Assert.AreEqual(point5.Position, arc.ElementAt(2).Position, "The third arc point is not the point that was expected."); Assert.AreEqual(point6.Position, arc.ElementAt(3).Position, "The fourth arc point is not the point that was expected."); } [Test, Description("A test to ensure that the IArc places " + "the points in the proper order even if it is given line " + "segments that are arranged in a loop.")] public void OrderedPointsGivenLoopedLineSegments() { const int uniquePointCount = 5; const float top = 10; const float bottom = 0; const float left = 0; const float right = 10; ITransform topLeft = new MatrixTransform(); topLeft.Position = new Vector3(left, top, 0); ITransform topRight = new MatrixTransform(); topRight.Position = new Vector3(right, top, 0); ITransform bottomRight = new MatrixTransform(); bottomRight.Position = new Vector3(right, bottom, 0); ITransform bottomLeft = new MatrixTransform(); bottomLeft.Position = new Vector3(left, bottom, 0); ILineSegment[] lines = { new LineSegment(topLeft, topRight), // top new LineSegment(topRight, bottomRight), // right new LineSegment(topLeft, bottomLeft), // left new LineSegment(bottomLeft, bottomRight) // bottom }; IArc arc = CreateArc((IEnumerable)lines); // Compare the points. Remember that although we used 4 points to // compose the line segments above, the segments looped around so // there should be 5 to show this. Assert.AreEqual(uniquePointCount, arc.Count(), "The are too few or too many points in the arc."); Assert.AreEqual(topLeft.Position, arc.ElementAt(0).Position, "The first arc point is not the point that was expected."); Assert.AreEqual(topRight.Position, arc.ElementAt(1).Position, "The second arc point is not the point that was expected."); Assert.AreEqual(bottomRight.Position, arc.ElementAt(2).Position, "The third arc point is not the point that was expected."); Assert.AreEqual(bottomLeft.Position, arc.ElementAt(3).Position, "The fourth arc point is not the point that was expected."); Assert.AreEqual(topLeft.Position, arc.ElementAt(4).Position, "The fifth arc point is not the point that was expected."); } /// /// Creates the instance that is to be tested. This /// method should not return the same instance more /// than once. /// /// The points that make up the arc. /// The instance that is to be tested. protected abstract IArc CreateArc(IEnumerable points); /// /// Creates the instance that is to be tested. This /// method should not return the same instance more /// than once. /// /// The instances that /// make up the arc. /// The instance that is to be tested. protected abstract IArc CreateArc(IEnumerable lines); } }