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);
}
}