using System; using UnitTestSharp; namespace Amphora.UnitTests { public class ScriptedGeneratorTests : TestFixture { public class CtorTests : TestFixture { public void NullWords_Throws() { CheckThrow(typeof(ArgumentNullException)); new ScriptedGenerator(null); } } public class NextUInt64Tests : TestFixture { public void ReturnsTheWordsInOrder() { var generator = new ScriptedGenerator(7UL, 0UL, ulong.MaxValue); CheckEqual(7UL, generator.NextUInt64()); CheckEqual(0UL, generator.NextUInt64()); CheckEqual(ulong.MaxValue, generator.NextUInt64()); } public void PastTheLastWord_Throws() { var generator = new ScriptedGenerator(1UL); generator.NextUInt64(); CheckThrow(typeof(InvalidOperationException)); generator.NextUInt64(); } public void WithNoWords_Throws() { var generator = new ScriptedGenerator(); CheckThrow(typeof(InvalidOperationException)); generator.NextUInt64(); } } public class NextUInt32Tests : TestFixture { public void IsTheTopHalfOfTheNextWord() { var generator = new ScriptedGenerator(0x1234567800000001UL, 0x00000002FFFFFFFFUL); CheckEqual(0x12345678U, generator.NextUInt32()); CheckEqual(2U, generator.NextUInt32()); } public void UsesUpOneWord() { var generator = new ScriptedGenerator(1UL, 2UL); generator.NextUInt32(); CheckEqual(1, generator.Remaining); } public void PastTheLastWord_Throws() { var generator = new ScriptedGenerator(); CheckThrow(typeof(InvalidOperationException)); generator.NextUInt32(); } } public class RemainingTests : TestFixture { public void CountsTheWordsNotYetTaken() { var generator = new ScriptedGenerator(1UL, 2UL, 3UL); CheckEqual(3, generator.Remaining); generator.NextUInt64(); CheckEqual(2, generator.Remaining); generator.NextUInt64(); generator.NextUInt64(); CheckEqual(0, generator.Remaining); } public void AfterADoubleDraw_CountsTheWordsLeft() { var rand = ScriptedGenerator.OfUnits(0.25, 0.5, 0.75); rand.NextDouble(); CheckEqual(2, rand.Remaining); } } public class WordForUnitTests : TestFixture { public void Zero_MakesNextDoubleZero() { var rand = new ScriptedGenerator(ScriptedGenerator.WordForUnit(0.0)); CheckEqual(0.0, rand.NextDouble()); } public void AnExactBinaryFraction_MakesNextDoubleReturnIt() { var rand = new ScriptedGenerator(ScriptedGenerator.WordForUnit(0.375)); CheckEqual(0.375, rand.NextDouble()); } public void TheLargestUnit_MakesNextDoubleReturnIt() { double largest = 1.0 - 1.0 / 9007199254740992.0; var rand = new ScriptedGenerator(ScriptedGenerator.WordForUnit(largest)); CheckEqual(largest, rand.NextDouble()); } public void One_Throws() { CheckThrow(typeof(ArgumentOutOfRangeException)); ScriptedGenerator.WordForUnit(1.0); } public void Negative_Throws() { CheckThrow(typeof(ArgumentOutOfRangeException)); ScriptedGenerator.WordForUnit(-0.5); } public void NotANumber_Throws() { CheckThrow(typeof(ArgumentOutOfRangeException)); ScriptedGenerator.WordForUnit(double.NaN); } public void AUnitBetweenTwoGridPoints_RoundsDown() { double step = Math.Pow(2, -53); var rand = ScriptedGenerator.OfUnits(step / 2, step * 1.5); CheckEqual(0.0, rand.NextDouble()); CheckEqual(step, rand.NextDouble()); } } public class WordForIndexTests : TestFixture { public void MakesABoundedDrawReturnTheIndex() { for (ulong index = 0; index < 5; ++index) { var rand = new ScriptedGenerator(ScriptedGenerator.WordForIndex(index, count: 5)); CheckEqual(index, rand.NextUInt64(5UL)); } } public void ForACountPastTheThirtyTwoBitRange_MakesABoundedDrawReturnTheIndex() { const ulong count = 1000000007UL * 1000; var rand = new ScriptedGenerator(ScriptedGenerator.WordForIndex(count - 1, count)); CheckEqual(count - 1, rand.NextUInt64(count)); } public void IndexAtTheCount_Throws() { CheckThrow(typeof(ArgumentOutOfRangeException)); ScriptedGenerator.WordForIndex(5, count: 5); } } public class OfUnitsTests : TestFixture { public void MakesNextDoubleReturnTheUnitsInOrder() { var rand = ScriptedGenerator.OfUnits(0.25, 0.0, 0.875); CheckEqual(0.25, rand.NextDouble()); CheckEqual(0.0, rand.NextDouble()); CheckEqual(0.875, rand.NextDouble()); } public void NoUnits_IsAnEmptyScript() { CheckEqual(0, ScriptedGenerator.OfUnits().Remaining); } public void AnUnreachableUnit_Throws() { CheckThrow(typeof(ArgumentOutOfRangeException)); ScriptedGenerator.OfUnits(0.5, 1.0); } } } }