#region CPL License /* Nuclex Framework Copyright (C) 2002-2009 Nuclex Development Labs This library is free software; you can redistribute it and/or modify it under the terms of the IBM Common Public License as published by the IBM Corporation; either version 1.0 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the IBM Common Public License for more details. You should have received a copy of the IBM Common Public License along with this library */ #endregion #if UNITTEST using System; using System.Collections.Generic; using Microsoft.Xna.Framework; using NUnit.Framework; using Nuclex.Support; namespace Nuclex.Geometry { /// Unit Test for the NUnit assertion helper [TestFixture] public class GeoAssertHelperTest { /// Tests whether the almost equal check works with vectors [Test] public void TestAlmostEqualWithVectors() { Vector3 exactVector = new Vector3(exactFloat, exactFloat, exactFloat); Vector3 minusOneVector = new Vector3(minusOneFloat, minusOneFloat, minusOneFloat); Vector3 plusOneVector = new Vector3(plusOneFloat, plusOneFloat, plusOneFloat); GeoAssertHelper.AreAlmostEqual(exactVector, minusOneVector, 1); GeoAssertHelper.AreAlmostEqual(exactVector, plusOneVector, 1); } /// /// Tests whether the almost equal check detects an X component in a vector that /// is just barely too low /// [Test] public void TestThrowOnAlmostEqualWithTooLowXInVector() { Vector3 exactVector = new Vector3(exactFloat, exactFloat, exactFloat); Vector3 minusTwoVector = new Vector3(minusTwoFloat, exactFloat, exactFloat); Assert.Throws( delegate() { GeoAssertHelper.AreAlmostEqual(exactVector, minusTwoVector, 1); } ); } /// /// Tests whether the almost equal check detects an X component in a vector that /// is just barely too high /// [Test] public void TestThrowOnAlmostEqualWithTooHighXInVector() { Vector3 exactVector = new Vector3(exactFloat, exactFloat, exactFloat); Vector3 plusTwoVector = new Vector3(plusTwoFloat, exactFloat, exactFloat); Assert.Throws( delegate() { GeoAssertHelper.AreAlmostEqual(exactVector, plusTwoVector, 1); } ); } /// /// Tests whether the almost equal check detects an Y component in a vector that /// is just barely too low /// [Test] public void TestThrowOnAlmostEqualWithTooLowYInVector() { Vector3 exactVector = new Vector3(exactFloat, exactFloat, exactFloat); Vector3 minusTwoVector = new Vector3(exactFloat, minusTwoFloat, exactFloat); Assert.Throws( delegate() { GeoAssertHelper.AreAlmostEqual(exactVector, minusTwoVector, 1); } ); } /// /// Tests whether the almost equal check detects an Y component in a vector that /// is just barely too high /// [Test] public void TestThrowOnAlmostEqualWithTooHighYInVector() { Vector3 exactVector = new Vector3(exactFloat, exactFloat, exactFloat); Vector3 plusTwoVector = new Vector3(exactFloat, plusTwoFloat, exactFloat); Assert.Throws( delegate() { GeoAssertHelper.AreAlmostEqual(exactVector, plusTwoVector, 1); } ); } /// /// Tests whether the almost equal check detects an Z component in a vector that /// is just barely too low /// [Test] public void TestThrowOnAlmostEqualWithTooLowZInVector() { Vector3 exactVector = new Vector3(exactFloat, exactFloat, exactFloat); Vector3 minusTwoVector = new Vector3(exactFloat, exactFloat, minusTwoFloat); Assert.Throws( delegate() { GeoAssertHelper.AreAlmostEqual(exactVector, minusTwoVector, 1); } ); } /// /// Tests whether the almost equal check detects an Z component in a vector that /// is just barely too high /// [Test] public void TestThrowOnAlmostEqualWithTooHighZInVector() { Vector3 exactVector = new Vector3(exactFloat, exactFloat, exactFloat); Vector3 plusTwoVector = new Vector3(exactFloat, exactFloat, plusTwoFloat); Assert.Throws( delegate() { GeoAssertHelper.AreAlmostEqual(exactVector, plusTwoVector, 1); } ); } /// /// Verifies that the AreAlmostEqual() helper works correctly when comparing /// two axis aligned boxes /// [Test] public void TestAlmostEqualWithAxisAlignedBoxes() { Vector3 exactVector = new Vector3(exactFloat, exactFloat, exactFloat); Vector3 minusOneVector = new Vector3(minusOneFloat, minusOneFloat, minusOneFloat); Vector3 plusOneVector = new Vector3(plusOneFloat, plusOneFloat, plusOneFloat); Volumes.AxisAlignedBox3 oneOffAabb = new Volumes.AxisAlignedBox3( minusOneVector, plusOneVector ); Volumes.AxisAlignedBox3 exactAabb = new Volumes.AxisAlignedBox3( exactVector, exactVector ); GeoAssertHelper.AreAlmostEqual(exactAabb, oneOffAabb, 1); } /// /// Verifies that the AreAlmostEqual() helper throws an exception when the compared /// boxes differ by more than the allowed amount /// [Test] public void TestThrowOnAlmostEqualWithTooLargeAxisAlignedBox() { Vector3 exactVector = new Vector3(exactFloat, exactFloat, exactFloat); Vector3 minusTwoVector = new Vector3(minusTwoFloat, minusTwoFloat, minusTwoFloat); Vector3 plusTwoVector = new Vector3(plusTwoFloat, plusTwoFloat, plusTwoFloat); Volumes.AxisAlignedBox3 twoOffAabb = new Volumes.AxisAlignedBox3( minusTwoVector, plusTwoVector ); Volumes.AxisAlignedBox3 exactAabb = new Volumes.AxisAlignedBox3( exactVector, exactVector ); Assert.Throws( delegate() { GeoAssertHelper.AreAlmostEqual(exactAabb, twoOffAabb, 1); } ); } /// /// Adjusts a floating point value by the specified amount of neighbouring /// representable values /// /// Floating point value to be adjusted /// Numbers of neighbouring representable values to step /// The adjusted floating point value private static float adjust(float value, int ulps) { return FloatHelper.ReinterpretAsFloat(FloatHelper.ReinterpretAsInt(value) + ulps); } /// /// Adjusts a double precision floating point value by the specified amount of /// neighbouring representable values /// /// Double precision floating point value to be adjusted /// Numbers of neighbouring representable values to step /// The adjusted double precision floating point value private static double adjust(double value, long ulps) { return FloatHelper.ReinterpretAsDouble(FloatHelper.ReinterpretAsLong(value) + ulps); } /// The exact test value as a float private static readonly float exactFloat = 1234.5678f; /// The second next possible smaller float from the test value private static readonly float minusTwoFloat = adjust(exactFloat, -2); /// The next possible smaller float from the test value private static readonly float minusOneFloat = adjust(exactFloat, -1); /// The next possible greater float from the test value private static readonly float plusOneFloat = adjust(exactFloat, +1); /// The second next possible greater float from the test value private static readonly float plusTwoFloat = adjust(exactFloat, +2); /// The exact test value as a float private static readonly double exactDouble = 1234.5678f; /// The second next possible smaller float from the test value private static readonly double minusTwoDouble = adjust(exactDouble, -2); /// The next possible smaller float from the test value private static readonly double minusOneDouble = adjust(exactDouble, -1); /// The next possible greater float from the test value private static readonly double plusOneDouble = adjust(exactDouble, +1); /// The second next possible greater float from the test value private static readonly double plusTwoDouble = adjust(exactDouble, +2); } } // namespace Nuclex.Geometry #endif // UNITTEST