using UnitTestSharp; namespace Ariadne.Generator.UnitTests { /// /// Classes that hold passages for the scripts deriving from them, with no Run of their own. /// public class HostClassTests : TestFixture { public const string Steps = @" public abstract partial class Steps : Arc { public int Held; protected void Hold(World world) { int seen = 0; wait: while (!world.Open.Contains(""go"")) { seen++; Yield(); } Held += seen; } } "; public const string Mission = @" public partial class Mission : Steps { protected override void Run(World world) { first: Hold(world); } } "; public class WriteTests : TestFixture { public void ClassWithPassagesAndNoRun_CompilesWithoutComplaint() { GeneratorRun run = GeneratorRun.Of(("Steps.cs", Steps), ("Mission.cs", Mission)); CheckEqual(0, run.Reported.Count); CheckEqual(0, run.Compiled.Count); } public void ClassWithPassagesAndNoRun_WritesItsPassagesButNothingToResume() { GeneratorRun run = GeneratorRun.Of(("Steps.cs", Steps), ("Mission.cs", Mission)); string steps = run.CodeBehinds["Steps.CodeBehind.cs"]; CheckTrue(steps.Contains("protected bool Hold__Passage(__Frame __frame, global::Ariadne.TickTime __time, World world)")); CheckTrue(steps.Contains("public int Hold__seen;")); CheckFalse(steps.Contains("__Resume")); CheckFalse(steps.Contains("__SaveLocals")); } public void ClassWithPassagesAndNoRun_SavesItsLocalsInItsOwnFrame() { GeneratorRun run = GeneratorRun.Of(("Steps.cs", Steps), ("Mission.cs", Mission)); string steps = run.CodeBehinds["Steps.CodeBehind.cs"]; CheckTrue(steps.Contains("case \"Hold.seen\":")); CheckTrue(steps.Contains("lister.Local(\"Hold.seen\");")); } public void ScriptCallingAnInheritedPassage_RunsItOnItsOwnFrame() { GeneratorRun run = GeneratorRun.Of(("Steps.cs", Steps), ("Mission.cs", Mission)); string mission = run.CodeBehinds["Mission.CodeBehind.cs"]; CheckTrue(mission.Contains( "using (__frame.Enter(\"first\")) { if (!Hold__Passage(__frame, __time, world)) { return false; } }")); } public void ScriptCallingAnInheritedPassage_SavesItsLocalsToo() { GeneratorRun run = GeneratorRun.Of(("Steps.cs", Steps), ("Mission.cs", Mission)); string mission = run.CodeBehinds["Mission.CodeBehind.cs"]; CheckTrue(mission.Contains("Hold__LocalsToSave(__frame, depth + 1, writer);")); } public void ScriptCallingAnInheritedPassageThroughBase_RunsItTheSameWay() { GeneratorRun run = GeneratorRun.Of(("Steps.cs", Steps), ("Mission.cs", @" public partial class Mission : Steps { protected override void Run(World world) { first: base.Hold(world); } }")); CheckEqual(0, run.Reported.Count); CheckEqual(0, run.Compiled.Count); CheckTrue(run.CodeBehinds["Mission.CodeBehind.cs"].Contains("Hold__Passage(__frame, __time, world)")); } public void PassageOfTheBaseOfABase_IsInheritedThroughBothFrames() { GeneratorRun run = GeneratorRun.Of(("Steps.cs", Steps), ("Middle.cs", @" public abstract partial class Middle : Steps { public int Extra; }"), ("Mission.cs", @" public partial class Mission : Middle { protected override void Run(World world) { first: Hold(world); } }")); CheckEqual(0, run.Reported.Count); CheckEqual(0, run.Compiled.Count); CheckTrue(run.CodeBehinds["Mission.CodeBehind.cs"].Contains( "public partial class __Frame : global::Middle.__Frame")); } public void PassageOfAHostCallingAnother_IsAPassageToo() { GeneratorRun run = GeneratorRun.Of(@" public abstract partial class Steps : Arc { protected void Wait(World world) { wait: while (!world.Open.Contains(""go"")) { Yield(); } } protected void Twice(World world) { one: Wait(world); two: Wait(world); } }"); CheckEqual(0, run.Reported.Count); CheckEqual(0, run.Compiled.Count); CheckTrue(run.CodeBehind.Contains("protected bool Twice__Passage(")); } public void PassageNamedLikeAnInheritedOne_IsReported() { GeneratorRun run = GeneratorRun.Of(("Steps.cs", Steps), ("Mission.cs", @" public partial class Mission : Steps { private void Hold(World world, int times) { wait: while (times > 0) { times--; Yield(); } } protected override void Run(World world) { Hold(world, 2); } }")); CheckTrue(run.Reported.Contains("ARI0012:Hold")); } public void ClassWithPassagesThatIsntPartial_IsReported() { GeneratorRun run = GeneratorRun.Of(@" public abstract class Steps : Arc { protected void Hold(World world) { wait: while (!world.Open.Contains(""go"")) { Yield(); } } }"); CheckEqual(new[] { "ARI0018:Steps" }, run.Reported); } public void ClassWithNoRunAndNoPassages_IsNotAHost() { GeneratorRun run = GeneratorRun.Of(@" public abstract partial class Plain : Arc { public int Reward; }"); CheckEqual(0, run.Reported.Count); CheckFalse(run.CodeBehind.Contains("Passage")); } } } }