using System; using Amphora; using UnitTestSharp; using Vellum; namespace Ariadne.Vellum.UnitTests { public class RandMemberSaveTests : TestFixture { public static void TickTimes(Arc arc, int count) { var gates = new Gates(); for (int i = 0; i < count; i++) { arc.Tick(gates, TestTicks.Fresh()); } } public class ReloadTests : TestFixture { public void ArcPausedPartWayThroughItsRolls_RollsWhatAnUnsavedOneWould() { var saved = new RollingScript(new Rand(42)); var unsaved = new RollingScript(new Rand(42)); TickTimes(saved, 3); TickTimes(unsaved, 3); var loaded = ArcRecordTests.Load(ArcRecordTests.Saved(saved)); TickTimes(loaded, 4); TickTimes(unsaved, 4); CheckEqual(7, loaded.Rolls.Count); CheckEqual(unsaved.Rolls, loaded.Rolls); } public void ArcsHoldingOneRand_LoadHoldingOneRand() { var shared = new Rand(42); SaveSession saving = ArcConverterTests.Session(); SaveNode save = SaveNode.NewTable(); save.Entries["first"] = saving.ToNode(new RollingScript(shared), typeof(RollingScript)); save.Entries["second"] = saving.ToNode(new RollingScript(shared), typeof(RollingScript)); SaveNode read = LuaSaveFormat.Parse(LuaSaveFormat.Format(save)); SaveSession loading = ArcConverterTests.Session(); var first = (RollingScript)loading.FromNode(read.RequireEntry("first"), typeof(RollingScript)); var second = (RollingScript)loading.FromNode(read.RequireEntry("second"), typeof(RollingScript)); CheckTrue(ReferenceEquals(first.Rand, second.Rand)); } public void ArcsHoldingTwoRands_LoadHoldingTwo() { SaveSession saving = ArcConverterTests.Session(); SaveNode save = SaveNode.NewTable(); save.Entries["first"] = saving.ToNode(new RollingScript(new Rand(42)), typeof(RollingScript)); save.Entries["second"] = saving.ToNode(new RollingScript(new Rand(42)), typeof(RollingScript)); SaveNode read = LuaSaveFormat.Parse(LuaSaveFormat.Format(save)); SaveSession loading = ArcConverterTests.Session(); var first = (RollingScript)loading.FromNode(read.RequireEntry("first"), typeof(RollingScript)); var second = (RollingScript)loading.FromNode(read.RequireEntry("second"), typeof(RollingScript)); CheckFalse(ReferenceEquals(first.Rand, second.Rand)); } } public class EventWaitTests : TestFixture { public static TickContext At(ExceptionSandbox sandbox, Duration gameTime) { return new TickContext(sandbox, Duration.FromMilliseconds(16), gameTime); } public void WaitOnADrawnEvent_WakesWhenTheDrawSaid() { Duration wait = new Rand(42).NextEvent(Duration.FromSeconds(10)); var sandbox = new ExceptionSandbox(typeof(AriadneSites).Assembly); var script = new EventWaitScript(new Rand(42)); script.Tick(new Gates(), At(sandbox, Duration.Zero)); script.Tick(new Gates(), At(sandbox, wait - Duration.FromTicks(1))); CheckFalse(script.Woke); script.Tick(new Gates(), At(sandbox, wait)); CheckTrue(script.Woke); } public void SaveMidWait_KeepsTheDeadlineAndDrawsNothingMore() { var reference = new Rand(42); Duration wait = reference.NextEvent(Duration.FromSeconds(10)); var sandbox = new ExceptionSandbox(typeof(AriadneSites).Assembly); var script = new EventWaitScript(new Rand(42)); script.Tick(new Gates(), At(sandbox, Duration.Zero)); var loaded = ArcRecordTests.Load(ArcRecordTests.Saved(script)); loaded.Tick(new Gates(), At(sandbox, wait - Duration.FromTicks(1))); CheckFalse(loaded.Woke); loaded.Tick(new Gates(), At(sandbox, wait)); CheckTrue(loaded.Woke); CheckEqual(reference.NextUInt64(), loaded.Rand.NextUInt64()); } public void EventThatNeverComes_IsSavedAsForeverWithItsName() { var script = new EventWaitScript(new Rand(42)) { Mean = Duration.Forever }; script.Tick(new Gates(), At(new ExceptionSandbox(typeof(AriadneSites).Assembly), Duration.Zero)); string saved = ArcRecordTests.Saved(script); CheckTrue(saved.Contains("9223372036854775807")); CheckTrue(saved.Contains("Forever")); } public void EventThatNeverComes_StaysWaitingAfterALoad() { var sandbox = new ExceptionSandbox(typeof(AriadneSites).Assembly); var script = new EventWaitScript(new Rand(42)) { Mean = Duration.Forever }; script.Tick(new Gates(), At(sandbox, Duration.Zero)); var loaded = ArcRecordTests.Load(ArcRecordTests.Saved(script)); loaded.Tick(new Gates(), At(sandbox, Duration.FromDays(365.0 * 20000.0))); CheckFalse(loaded.Woke); CheckEqual(0, sandbox.Entries.Count); } } public class ForeignCallTests : TestFixture { public void PassageRunOnAnotherArc_RollsOnThatArcsRand() { var roller = new RollerScript(new Rand(2)); var caller = new CallingRollerScript(new Rand(1), roller); TickTimes(caller, 3); var expected = new Rand(2); CheckEqual(new[] { expected.NextInt(1, 7), expected.NextInt(1, 7), expected.NextInt(1, 7) }, roller.Rolls); } public void PassageRunOnAnotherArc_LeavesTheCallersRandAlone() { var caller = new CallingRollerScript(new Rand(1), new RollerScript(new Rand(2))); TickTimes(caller, 3); CheckEqual(new Rand(1).NextUInt64(), caller.Rand.NextUInt64()); } public void CallerAndCalleeHoldingOneRand_RollOneStream() { var shared = new Rand(42); var roller = new RollerScript(shared); var caller = new CallingRollerScript(shared, roller); TickTimes(caller, 2); var expected = new Rand(42); CheckEqual(new[] { expected.NextInt(1, 7), expected.NextInt(1, 7) }, roller.Rolls); CheckEqual(expected.NextUInt64(), shared.NextUInt64()); } } } }