using System; using UnitTestSharp; namespace Blacklight.Bezier.UnitTests { public class AccuracyStatisticsTests : TestFixture { // Below the vertex the floor is 1.5 float steps of 2, so a measurement k steps off has ratio k / 1.5. public static readonly ShellSample BelowVertex = ShellSample.FromPosition(0, -2, 10); public static readonly ReferenceResult BelowVertexReference = new ReferenceResult(2, 0); public static float StepsAbove(int steps) { return (float)(2 + steps * Math.Pow(2, -22)); } public static AccuracyStatistics MeasureBelowVertex(params int[] steps) { var measured = new float[steps.Length]; var samples = new ShellSample[steps.Length]; var references = new ReferenceResult[steps.Length]; for (int i = 0; i < steps.Length; i++) { measured[i] = StepsAbove(steps[i]); samples[i] = BelowVertex; references[i] = BelowVertexReference; } return AccuracyStatistics.Measure(measured, samples, references); } public class CtorTests : TestFixture { public void AssignsEveryField() { var statistics = new AccuracyStatistics(worstRatio: 1, medianRatio: 2, shareAboveTen: 3, worstIndex: 4, compared: 5); CheckEqual(1.0, statistics.WorstRatio); CheckEqual(2.0, statistics.MedianRatio); CheckEqual(3.0, statistics.ShareAboveTen); CheckEqual(4, statistics.WorstIndex); CheckEqual(5, statistics.Compared); } } public class RatioTests : TestFixture { public void ExactMeasurement_IsZero() { CheckEqual(0.0, AccuracyStatistics.Ratio(2, BelowVertex, BelowVertexReference)); } public void Error_IsScaledByTheInputFloor() { CheckEqual(2.0 / 3, AccuracyStatistics.Ratio(StepsAbove(1), BelowVertex, BelowVertexReference)); } public void NaN_IsInfinitelyWrong() { CheckEqual(double.PositiveInfinity, AccuracyStatistics.Ratio(float.NaN, BelowVertex, BelowVertexReference)); } public void Infinity_IsInfinitelyWrong() { CheckEqual(double.PositiveInfinity, AccuracyStatistics.Ratio(float.PositiveInfinity, BelowVertex, BelowVertexReference)); } } public class MeasureTests : TestFixture { public void PerfectMeasurements_AreAllZero() { AccuracyStatistics statistics = MeasureBelowVertex(0, 0, 0); CheckEqual(0.0, statistics.WorstRatio); CheckEqual(0.0, statistics.MedianRatio); CheckEqual(0.0, statistics.ShareAboveTen); CheckEqual(3, statistics.Compared); } public void WorstIndex_PointsAtTheLargestRatio() { AccuracyStatistics statistics = MeasureBelowVertex(3, 30, 0); CheckEqual(20.0, statistics.WorstRatio); CheckEqual(1, statistics.WorstIndex); } public void Median_IsTheMiddleRatio() { CheckEqual(2.0, MeasureBelowVertex(30, 0, 3).MedianRatio); } public void ShareAboveTen_CountsOnlyRatiosAboveTen() { CheckEqual(0.25, MeasureBelowVertex(0, 3, 15, 30).ShareAboveTen); } public void SamplesOnTheCurve_AreSkipped() { var measured = new[] { StepsAbove(3), 1000f }; var samples = new[] { BelowVertex, ShellSample.FromPosition(2, 2, 10) }; var references = new[] { BelowVertexReference, new ReferenceResult(0, 2) }; AccuracyStatistics statistics = AccuracyStatistics.Measure(measured, samples, references); CheckEqual(1, statistics.Compared); CheckEqual(2.0, statistics.WorstRatio); } public void NothingToCompare_HasNoWorstIndex() { AccuracyStatistics statistics = AccuracyStatistics.Measure(new float[0], new ShellSample[0], new ReferenceResult[0]); CheckEqual(0, statistics.Compared); CheckEqual(-1, statistics.WorstIndex); } } } }