using System; using UnitTestSharp; namespace Glass.UnitTests { public class NumberGridTests : TestFixture { /// /// The ParamName of the ArgumentException Validate throws, or null when it doesn't throw. /// public static string ParamNameRejectedBy(NumberGrid grid) { try { grid.Validate(); } catch (ArgumentException thrown) { return thrown.ParamName; } return null; } public class ResolutionTests : TestFixture { public void DefaultsToOne() { CheckEqual(1m, new NumberGrid().Resolution); } public void Explicit_IsKept() { CheckEqual(0.25m, new NumberGrid { Resolution = 0.25m }.Resolution); } } public class StepTests : TestFixture { public void DefaultsToResolution() { CheckEqual(0.25m, new NumberGrid { Resolution = 0.25m }.Step); } public void Explicit_OverridesResolution() { CheckEqual(0.75m, new NumberGrid { Resolution = 0.25m, Step = 0.75m }.Step); } } public class DecimalPlacesTests : TestFixture { public void WholeResolution_IsZero() { CheckEqual(0, new NumberGrid { Max = 10 }.DecimalPlaces); } public void FractionalResolution_CountsItsPlaces() { CheckEqual(3, new NumberGrid { Max = 1, Resolution = 0.001m }.DecimalPlaces); } public void TrailingZeros_DontCount() { CheckEqual(3, new NumberGrid { Max = 1, Resolution = 0.0010m }.DecimalPlaces); } public void MinFinerThanResolution_CountsMinsPlaces() { CheckEqual(2, new NumberGrid { Min = 0.05m, Max = 0.95m, Resolution = 0.1m }.DecimalPlaces); } } public class ValidateTests : TestFixture { public void DefaultGrid_IsValid() { CheckNull(ParamNameRejectedBy(new NumberGrid())); } public void FullyConfiguredGrid_IsValid() { CheckNull(ParamNameRejectedBy( new NumberGrid { Min = -1, Max = 1, Resolution = 0.001m, Step = 0.1m })); } public void ZeroResolution_IsRejected() { CheckEqual(nameof(NumberGrid.Resolution), ParamNameRejectedBy( new NumberGrid { Resolution = 0, Step = 1 })); } public void ZeroStep_IsRejected() { CheckEqual(nameof(NumberGrid.Step), ParamNameRejectedBy(new NumberGrid { Step = 0 })); } public void StepNotAWholeMultipleOfResolution_IsRejected() { CheckEqual(nameof(NumberGrid.Step), ParamNameRejectedBy( new NumberGrid { Resolution = 0.5m, Step = 0.75m })); } public void MinAboveMax_IsRejected() { CheckEqual(nameof(NumberGrid.Max), ParamNameRejectedBy(new NumberGrid { Min = 1, Max = 0 })); } public void MinEqualToMax_IsValid() { CheckNull(ParamNameRejectedBy(new NumberGrid { Min = 5, Max = 5 })); } public void RangeWiderThanDecimalCanHold_IsRejected() { CheckEqual(nameof(NumberGrid.Max), ParamNameRejectedBy( new NumberGrid { Min = decimal.MinValue, Max = decimal.MaxValue })); } public void MaxOffTheResolutionGrid_IsRejected() { CheckEqual(nameof(NumberGrid.Max), ParamNameRejectedBy( new NumberGrid { Max = 1, Resolution = 0.3m })); } public void MaxOffTheStepLattice_IsValid() { CheckNull(ParamNameRejectedBy(new NumberGrid { Max = 1, Resolution = 0.1m, Step = 0.3m })); } } public class SnapTests : TestFixture { private static readonly NumberGrid HalvesToTen = new NumberGrid { Max = 10, Resolution = 0.5m }; public void OnGridValue_IsUnchanged() { CheckEqual(2.5m, HalvesToTen.Snap(2.5m)); } public void BelowMidpoint_RoundsDown() { CheckEqual(2.5m, HalvesToTen.Snap(2.7m)); } public void AboveMidpoint_RoundsUp() { CheckEqual(3m, HalvesToTen.Snap(2.8m)); } public void Midpoint_RoundsUp() { CheckEqual(3m, HalvesToTen.Snap(2.75m)); } public void NegativeMidpoint_RoundsTowardMaxNotAwayFromZero() { var grid = new NumberGrid { Min = -10, Max = 10, Resolution = 0.5m }; CheckEqual(0m, grid.Snap(-0.25m)); } public void MinOffZero_GridCountsFromMin() { var grid = new NumberGrid { Min = 0.03m, Max = 0.93m, Resolution = 0.1m }; CheckEqual(0.13m, grid.Snap(0.1m)); } public void BelowMin_ClampsToMin() { CheckEqual(0m, HalvesToTen.Snap(-3)); } public void AboveMax_ClampsToMax() { CheckEqual(10m, HalvesToTen.Snap(13)); } public void DecimalMaxValue_ClampsWithoutOverflowing() { var grid = new NumberGrid { Min = -1, Max = 1 }; CheckEqual(1m, grid.Snap(decimal.MaxValue)); } } public class StepFromTests : TestFixture { private static readonly NumberGrid PointThreeStepsToOne = new NumberGrid { Max = 1, Resolution = 0.05m, Step = 0.3m }; public void ZeroSteps_SnapsToTheResolutionGrid() { CheckEqual(0.35m, PointThreeStepsToOne.StepFrom(0.33m, steps: 0)); } public void OnLattice_Up_MovesWholeSteps() { CheckEqual(0.9m, PointThreeStepsToOne.StepFrom(0.3m, steps: 2)); } public void OnLattice_Down_MovesWholeSteps() { CheckEqual(0.3m, PointThreeStepsToOne.StepFrom(0.9m, steps: -2)); } public void OffLattice_Up_FirstStepLandsOnTheNextLatticePoint() { CheckEqual(0.6m, PointThreeStepsToOne.StepFrom(0.4m, steps: 1)); } public void OffLattice_Down_FirstStepLandsOnThePreviousLatticePoint() { CheckEqual(0.3m, PointThreeStepsToOne.StepFrom(0.4m, steps: -1)); } public void OffLattice_StepsAfterTheFirstAreWhole() { CheckEqual(0.9m, PointThreeStepsToOne.StepFrom(0.4m, steps: 2)); } public void PastMax_ClampsToMaxEvenOffTheLattice() { CheckEqual(1m, PointThreeStepsToOne.StepFrom(0.9m, steps: 1)); } public void FromMaxOffTheLattice_Down_LandsBackOnTheLattice() { CheckEqual(0.9m, PointThreeStepsToOne.StepFrom(1m, steps: -1)); } public void PastMin_ClampsToMin() { CheckEqual(0m, PointThreeStepsToOne.StepFrom(0.3m, steps: -5)); } public void FromAboveMax_StepsFromMax() { CheckEqual(0.9m, PointThreeStepsToOne.StepFrom(5m, steps: -1)); } public void FromBelowMin_StepsFromMin() { CheckEqual(0.3m, PointThreeStepsToOne.StepFrom(-5m, steps: 1)); } public void MinOffZero_LatticeCountsFromMin() { var grid = new NumberGrid { Min = 0.1m, Max = 2, Resolution = 0.1m, Step = 0.5m }; CheckEqual(0.6m, grid.StepFrom(0.1m, steps: 1)); } public void HugeStepCount_ClampsWithoutOverflowing() { var grid = new NumberGrid { Max = 1e27m, Resolution = 1e20m }; CheckEqual(1e27m, grid.StepFrom(0, steps: int.MaxValue)); } } } }