using System; using System.Collections.Generic; using NUnit.Framework; using NUnit.Framework.Constraints; using UnityEngine; namespace Framework.Geometry.Areas { /// Unit tests for the 2D rectangle class [TestFixture] internal class Rectangle2Test { #region class Rectangle2Comparer /// Compares two 2D rectangles with a tolerance private class Rectangle2Comparer : IEqualityComparer { /// Default instance of the 2D rectangle comparer public static readonly Rectangle2Comparer Default = new Rectangle2Comparer(); /// Checks whether two rectangles are identical /// Rectangle that will be compared on the left side /// Rectangle that will be compared on the right side /// True if both rectangles are equal public bool Equals(Rectangle2 left, Rectangle2 right) { return FloatingPointNumerics.AreAlmostEqualUlps(left.Min.x, right.Min.x, this.MaxUlps) && FloatingPointNumerics.AreAlmostEqualUlps(left.Min.y, right.Min.y, this.MaxUlps) && FloatingPointNumerics.AreAlmostEqualUlps(left.Max.x, right.Max.x, this.MaxUlps) && FloatingPointNumerics.AreAlmostEqualUlps(left.Max.y, right.Max.y, this.MaxUlps); } /// Calculates a hash code that is the same for identical rectangles /// Rectangle for which a hash code will be calculated /// The hash code for the rectangle public int GetHashCode(Rectangle2 rectangle) { return rectangle.GetHashCode(); } /// /// Maximum number of ULPs (Units in Last Place) the rectangles may diverge when compared /// public int MaxUlps = 128; } #endregion // class Rectangle2Comparer /// /// Verifies that the named MinMax constructor assigns the corners to the rectangle /// [Test] public void IndividualMinMaxConstructorAssignsValues() { Rectangle2 rectangle = Rectangle2.FromMinMax(1.2f, 3.4f, 5.6f, 7.8f); Assert.That(rectangle.Min.x, Is.EqualTo(1.2f)); Assert.That(rectangle.Min.y, Is.EqualTo(3.4f)); Assert.That(rectangle.Max.x, Is.EqualTo(5.6f)); Assert.That(rectangle.Max.y, Is.EqualTo(7.8f)); } /// /// Verifies that the named MinMax constructor assigns the corners to the rectangle /// [Test] public void MinMaxConstructorAssignsValues() { Rectangle2 rectangle = Rectangle2.FromMinMax( new Vector2(1.2f, 3.4f), new Vector2(5.6f, 7.8f) ); Assert.That(rectangle.Min.x, Is.EqualTo(1.2f)); Assert.That(rectangle.Min.y, Is.EqualTo(3.4f)); Assert.That(rectangle.Max.x, Is.EqualTo(5.6f)); Assert.That(rectangle.Max.y, Is.EqualTo(7.8f)); } /// /// Verifies that the named PointAndSize constructor assigns the corners to the rectangle /// [Test] public void IndividualPointAndSizeConstructorAssignsValues() { Rectangle2 rectangle = Rectangle2.FromPointAndSize(1.2f, 3.4f, 5.6f, 7.8f); Assert.That(rectangle.Min.x, Is.EqualTo(1.2f)); Assert.That(rectangle.Min.y, Is.EqualTo(3.4f)); Assert.That(rectangle.Max.x, Is.EqualTo(6.8f).Within(128).Ulps); Assert.That(rectangle.Max.y, Is.EqualTo(11.2f).Within(128).Ulps); } /// /// Verifies that the named PointAndSize constructor assigns the corners to the rectangle /// [Test] public void PointAndSizeConstructorAssignsValues() { Rectangle2 rectangle = Rectangle2.FromPointAndSize( new Vector2(1.2f, 3.4f), new Vector2(5.6f, 7.8f) ); Assert.That(rectangle.Min.x, Is.EqualTo(1.2f)); Assert.That(rectangle.Min.y, Is.EqualTo(3.4f)); Assert.That(rectangle.Max.x, Is.EqualTo(6.8f).Within(128).Ulps); Assert.That(rectangle.Max.y, Is.EqualTo(11.2f).Within(128).Ulps); } /// /// Verifies that the width and height of a rectangle can be calculated /// [Test] public void WidthAndHeightCanBeCalculated() { Rectangle2 rectangle = Rectangle2.FromMinMax(-1.0f, -2.0f, 4.0f, 8.0f); Assert.That(rectangle.Width, Is.EqualTo(5.0f)); Assert.That(rectangle.Height, Is.EqualTo(10.0f)); } /// /// Verifies that the width and height of a flipped rectangle can be calculated /// [Test] public void FlippedWidthAndHeightCanBeCalculated() { Rectangle2 rectangle = Rectangle2.FromMinMax(-8.0f, -4.0f, 2.0f, 1.0f); Assert.That(rectangle.Width, Is.EqualTo(10.0f)); Assert.That(rectangle.Height, Is.EqualTo(5.0f)); } /// Verifies that the rectangle can tell its area [Test] public void AreaIsProvided() { Rectangle2 rectangle = Rectangle2.FromMinMax(250.0f, 100.0f, 50.0f, 10.0f); float expectedArea = 90.0f * 200.0f; Assert.That(rectangle.Area, Is.EqualTo(expectedArea)); } /// Verifies that the rectangle can tell its circumference [Test] public void CircumferenceIsProvided() { Rectangle2 rectangle = Rectangle2.FromMinMax(10.0f, 50.0f, 100.0f, 250.0f); float expectedCircumference = (90.0f * 2.0f) + (200.0f * 2.0f); Assert.That(rectangle.Circumference, Is.EqualTo(expectedCircumference)); } /// Verifies that vectors can be checked for equality [Test] public void EqualityCanBeChecked() { Rectangle2 rectangle = Rectangle2.FromMinMax(1.2f, 3.4f, 5.6f, 7.8f); Assert.That((rectangle == Rectangle2.FromMinMax(1.2f, 3.4f, 5.6f, 7.8f)), Is.True); Assert.That((rectangle == Rectangle2.FromMinMax(1.3f, 3.4f, 5.6f, 7.8f)), Is.False); Assert.That((rectangle == Rectangle2.FromMinMax(1.2f, 3.5f, 5.6f, 7.8f)), Is.False); Assert.That((rectangle == Rectangle2.FromMinMax(1.2f, 3.4f, 5.7f, 7.8f)), Is.False); Assert.That((rectangle == Rectangle2.FromMinMax(1.2f, 3.4f, 5.6f, 7.9f)), Is.False); } /// Verifies that vectors can be checked for inequality [Test] public void InequalityCanBeChecked() { Rectangle2 rectangle = Rectangle2.FromMinMax(1.2f, 3.4f, 5.6f, 7.8f); Assert.That((rectangle != Rectangle2.FromMinMax(1.2f, 3.4f, 5.6f, 7.8f)), Is.False); Assert.That((rectangle != Rectangle2.FromMinMax(1.3f, 3.4f, 5.6f, 7.8f)), Is.True); Assert.That((rectangle != Rectangle2.FromMinMax(1.2f, 3.5f, 5.6f, 7.8f)), Is.True); Assert.That((rectangle != Rectangle2.FromMinMax(1.2f, 3.4f, 5.7f, 7.8f)), Is.True); Assert.That((rectangle != Rectangle2.FromMinMax(1.2f, 3.4f, 5.6f, 7.9f)), Is.True); } /// Verifies that vectors can be checked for equality [Test] public void EqualsOverrideIsProvided() { Rectangle2 rectangle = Rectangle2.FromMinMax(1.2f, 3.4f, 5.6f, 7.8f); Assert.That(rectangle.Equals(Rectangle2.FromMinMax(1.2f, 3.4f, 5.6f, 7.8f)), Is.True); Assert.That(rectangle.Equals(Rectangle2.FromMinMax(1.3f, 3.4f, 5.6f, 7.8f)), Is.False); Assert.That(rectangle.Equals(Rectangle2.FromMinMax(1.2f, 3.5f, 5.6f, 7.8f)), Is.False); Assert.That(rectangle.Equals(Rectangle2.FromMinMax(1.2f, 3.4f, 5.7f, 7.8f)), Is.False); Assert.That(rectangle.Equals(Rectangle2.FromMinMax(1.2f, 3.4f, 5.6f, 7.9f)), Is.False); Assert.That(rectangle.Equals(null), Is.False); Assert.That(rectangle.Equals(new Rectangle2Test()), Is.False); } /// /// Verifies that the hash codes of two instances with identical state match /// [Test] public void HashCodeIsIdenticalIfStateIsIdentical() { Rectangle2 first = Rectangle2.FromMinMax(1.2f, 3.4f, 5.6f, 7.8f); Rectangle2 second = Rectangle2.FromMinMax(1.2f, 3.4f, 5.6f, 7.8f); Assert.That(first.GetHashCode(), Is.EqualTo(second.GetHashCode())); } /// Verifies that the 2D rectangle class can provide a describing string [Test] public void CanProvideDescribingString() { Rectangle2 rectangle = Rectangle2.FromMinMax(1.2f, 3.4f, 5.6f, 7.8f); string stringDescription = rectangle.ToString(); Assert.That(rectangle.ToString(), Is.Not.Null); Assert.That(stringDescription, Contains.Substring((1.2f).ToString())); Assert.That(stringDescription, Contains.Substring((3.4f).ToString())); Assert.That(stringDescription, Contains.Substring((5.6f).ToString())); Assert.That(stringDescription, Contains.Substring((7.8f).ToString())); } } } // namespace Framework.Geometry.Areas