using System; namespace Amphora.UnitTests { public class Xoshiro128PlusPlusTests : UnitTestSharp.TestFixture { public static Xoshiro128PlusPlus OneTwoThreeFour() { return new Xoshiro128PlusPlus(state0: 1, state1: 2, state2: 3, state3: 4); } public class SeedCtorTests : UnitTestSharp.TestFixture { public void FillsTheStateWithTwoSplitMix64DrawsLowerHalfFirst() { var seeder = new SplitMix64(42); ulong first = seeder.NextUInt64(); ulong second = seeder.NextUInt64(); var generator = new Xoshiro128PlusPlus(42); CheckEqual((uint)first, generator.State0); CheckEqual((uint)(first >> 32), generator.State1); CheckEqual((uint)second, generator.State2); CheckEqual((uint)(second >> 32), generator.State3); } public void MatchesTheReferenceSeededFrom42() { var generator = new Xoshiro128PlusPlus(42); CheckEqual(0x9d9452c1U, generator.NextUInt32()); CheckEqual(0x6909d440U, generator.NextUInt32()); CheckEqual(0x6148a68fU, generator.NextUInt32()); CheckEqual(0x54829a5bU, generator.NextUInt32()); } } public class StateCtorTests : UnitTestSharp.TestFixture { public void KeepsTheStateAsGiven() { Xoshiro128PlusPlus generator = OneTwoThreeFour(); CheckEqual(1U, generator.State0); CheckEqual(2U, generator.State1); CheckEqual(3U, generator.State2); CheckEqual(4U, generator.State3); } public void AcceptsOneNonzeroWord() { var generator = new Xoshiro128PlusPlus(state0: 0, state1: 0, state2: 1, state3: 0); CheckEqual(1U, generator.State2); } public void RejectsAnAllZeroState() { CheckThrow(typeof(ArgumentException)); new Xoshiro128PlusPlus(state0: 0, state1: 0, state2: 0, state3: 0); } } public class NextUInt32Tests : UnitTestSharp.TestFixture { public void MatchesTheReference() { Xoshiro128PlusPlus generator = OneTwoThreeFour(); CheckEqual(0x00000281U, generator.NextUInt32()); CheckEqual(0x00180387U, generator.NextUInt32()); CheckEqual(0xc0183387U, generator.NextUInt32()); CheckEqual(0xd1ae3b02U, generator.NextUInt32()); CheckEqual(0x31e2310aU, generator.NextUInt32()); CheckEqual(0xfd275ab0U, generator.NextUInt32()); CheckEqual(0xe67f7cecU, generator.NextUInt32()); CheckEqual(0x50d07f0fU, generator.NextUInt32()); } public void TheDefaultValueDrawsOnlyZeros() { var generator = default(Xoshiro128PlusPlus); CheckEqual(0U, generator.NextUInt32()); CheckEqual(0U, generator.NextUInt32()); } } public class NextUInt64Tests : UnitTestSharp.TestFixture { public void PutsTheFirst32BitDrawInTheUpperHalf() { Xoshiro128PlusPlus generator = OneTwoThreeFour(); CheckEqual(0x0000028100180387UL, generator.NextUInt64()); CheckEqual(0xc0183387d1ae3b02UL, generator.NextUInt64()); } } public class JumpTests : UnitTestSharp.TestFixture { public void MatchesTheReferenceDrawsAfterward() { Xoshiro128PlusPlus generator = OneTwoThreeFour(); generator.Jump(); CheckEqual(0xba8c0ddcU, generator.NextUInt32()); CheckEqual(0x06a228ceU, generator.NextUInt32()); CheckEqual(0x4506c342U, generator.NextUInt32()); CheckEqual(0x6d64b9f6U, generator.NextUInt32()); } } public class LongJumpTests : UnitTestSharp.TestFixture { public void MatchesTheReferenceDrawsAfterward() { Xoshiro128PlusPlus generator = OneTwoThreeFour(); generator.LongJump(); CheckEqual(0x99cc2935U, generator.NextUInt32()); CheckEqual(0x7f4f19b6U, generator.NextUInt32()); CheckEqual(0x09b914e1U, generator.NextUInt32()); CheckEqual(0x6de722e8U, generator.NextUInt32()); } } } }