using System; using System.Linq; using UnitTestSharp; using Vellum; namespace Ariadne.Vellum.UnitTests { /// /// Saves an arc paused inside a passage of another arc, whose locals are saved with the caller's. /// public class ForeignCallSaveTests : TestFixture { public static OperatorScript PausedInside(Gates gates, int ticks) { var returnMe = new OperatorScript { Plant = new PlantScript() }; for (int i = 0; i < ticks; ++i) { returnMe.Tick(gates, TestTicks.Fresh()); } return returnMe; } public class ToNodeTests : TestFixture { public void CalleesLocals_AreSavedInATableInsideTheCallersNamedForTheCall() { SaveSession session = ArcConverterTests.Session(); OperatorScript paused = PausedInside(new Gates(), ticks: 2); SaveNode node = session.ToNode(paused, typeof(OperatorScript)); SaveNode locals = node.RequireEntry(ArcRecord.LocalsKey); CheckEqual(new[] { "Run.before", "Run.update/" }, locals.Entries.Keys.OrderBy(key => key, StringComparer.Ordinal).ToArray()); SaveNode call = locals.RequireEntry("Run.update/"); CheckEqual(new[] { "Update.waited", "receiver" }, call.Entries.Keys.OrderBy(key => key, StringComparer.Ordinal).ToArray()); CheckEqual("2", call.RequireEntry("Update.waited").Text); } } public class FromNodeTests : TestFixture { public void Reloaded_ResumesTheCallWithItsLocalsOnTheSameArc() { SaveSession session = ArcConverterTests.Session(); var gates = new Gates(); OperatorScript paused = PausedInside(gates, ticks: 2); var loaded = (OperatorScript)session.FromNode( session.ToNode(paused, typeof(OperatorScript)), typeof(OperatorScript)); gates.Open.Add("go"); loaded.Tick(gates, TestTicks.Fresh()); CheckEqual("done 7 2", loaded.Result); CheckEqual("updated after 2", loaded.Plant.Note); CheckEqual(0, paused.Plant.Updates); CheckTrue(loaded.Finished); } public void ReloadedAndSavedAgainBeforeTicking_KeepsTheCallsLocals() { SaveSession session = ArcConverterTests.Session(); var gates = new Gates(); SaveNode once = session.ToNode(PausedInside(gates, ticks: 2), typeof(OperatorScript)); var loaded = (OperatorScript)session.FromNode(once, typeof(OperatorScript)); var again = (OperatorScript)session.FromNode( session.ToNode(loaded, typeof(OperatorScript)), typeof(OperatorScript)); gates.Open.Add("go"); again.Tick(gates, TestTicks.Fresh()); CheckEqual("updated after 2", again.Plant.Note); } } } }