using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using UnitTestSharp; namespace Foundations.UnitTests { public class ModifierContextTests : TestFixture { public class CallModifier : TestFixture { public void ModifiesState() { var state = new FauxSimulationState(); var context = new ModifierContext(_state => _state.Integer = 7); context.CallModifier(state, CallsiteContext.Render); CheckEqual(7, state.Integer); } public void CallsiteOverloadAlsoModifiersState() { var state = new FauxSimulationState(); var context = new ModifierContext((_state, callsite) => _state.Integer = 7); context.CallModifier(state, CallsiteContext.Render); CheckEqual(7, state.Integer); } public void CallsiteOverloadReturnsCorrectCallsiteContext() { CallsiteContext callsite = CallsiteContext.Simulation; var context = new ModifierContext((_state, _callsite) => callsite = _callsite); context.CallModifier(null, CallsiteContext.Render); CheckEqual(CallsiteContext.Render, callsite); } public void CrashInSimulationPreventsFurtherCallsInSimulation() { bool? calledTwice = null; var context = new ModifierContext(state => { if (calledTwice == null) { calledTwice = false; throw new InvalidOperationException("sim"); } else { calledTwice = true; } }); context.CallModifier(null, CallsiteContext.Simulation); context.CallModifier(null, CallsiteContext.Simulation); CheckEqual(false, calledTwice); } public void CrashInRenderPreventsFurtherCallsInRender() { bool? calledTwice = null; var context = new ModifierContext(state => { if (calledTwice == null) { calledTwice = false; throw new InvalidOperationException("sim"); } else { calledTwice = true; } }); context.CallModifier(null, CallsiteContext.Render); context.CallModifier(null, CallsiteContext.Render); CheckEqual(false, calledTwice); } public void CrashInSimulationDoesNotPreventsFurtherCallsInRender() { bool? calledTwice = null; var context = new ModifierContext(state => { if (calledTwice == null) { calledTwice = false; throw new InvalidOperationException("sim"); } else { calledTwice = true; } }); context.CallModifier(null, CallsiteContext.Simulation); context.CallModifier(null, CallsiteContext.Render); CheckEqual(true, calledTwice); } public void CrashInRenderDoesNotPreventsFurtherCallsInSimulation() { bool? calledTwice = null; var context = new ModifierContext(state => { if (calledTwice == null) { calledTwice = false; throw new InvalidOperationException("sim"); } else { calledTwice = true; } }); context.CallModifier(null, CallsiteContext.Render); context.CallModifier(null, CallsiteContext.Simulation); CheckEqual(true, calledTwice); } } public class MarkAsDone : TestFixture { public void NotCompleteBeforeMarkAsDone() { var context = new ModifierContext( state => { throw new InvalidOperationException(); }); context.CallModifier(null, CallsiteContext.Render); CheckFalse(context.Task.IsCompleted); } public void SuccessfulRunMarksAsCompleted() { var context = new ModifierContext(state => { }); context.CallModifier(null, CallsiteContext.Render); context.MarkAsDone(); Check(context.Task.IsCompleted); CheckFalse(context.Task.IsFaulted); } public void CrashInSimulationIsRecorded() { var exception = new InvalidOperationException("foo"); var context = new ModifierContext(state => { throw exception; }); context.CallModifier(null, CallsiteContext.Simulation); context.MarkAsDone(); Check(context.Task.IsFaulted); CheckEqual("foo", context.Task.Exception.InnerException.Message); } public void CrashInRenderIsRecorded() { var exception = new InvalidOperationException("foo"); var context = new ModifierContext(state => { throw exception; }); context.CallModifier(null, CallsiteContext.Render); context.MarkAsDone(); Check(context.Task.IsFaulted); CheckEqual("foo", context.Task.Exception.InnerException.Message); } public void CrashInSimulationOverridesCrashInRender() { var simException = new InvalidOperationException("sim"); var renderException = new InvalidOperationException("render"); var context = new ModifierContext((state, callsite) => { if (callsite == CallsiteContext.Simulation) { throw simException; } else { throw renderException; } }); context.CallModifier(null, CallsiteContext.Simulation); context.CallModifier(null, CallsiteContext.Render); context.MarkAsDone(); Check(context.Task.IsFaulted); CheckEqual("sim", context.Task.Exception.InnerException.Message); } public void SimulationStateIsRecordedInException() { var state = new FauxSimulationState { Integer = 7 }; var context = new ModifierContext( _ => { throw new InvalidOperationException("sim"); }); context.CallModifier(state, CallsiteContext.Simulation); context.MarkAsDone(); CheckEqual("7", context.Task.Exception.InnerException.Data["State"]); } public void CrashInSimulationStateRecordingDuringCrashHandlingIsRecorded() { var state = new FauxSimulationState { Integer = 7 }; state.CrashOnSerialize = true; var context = new ModifierContext( _ => { throw new InvalidOperationException("sim"); }); context.CallModifier(state, CallsiteContext.Simulation); context.MarkAsDone(); Exception exception = (Exception)context.Task.Exception.InnerException.Data["StateSerializeException"]; CheckEqual("Foo", exception.Message); } } } }