public void Simulate_ActivitySpecified_ActivityFiredAtTheAppropriateTime()
        {
            using(var context = new SimulationContext(isDefaultContextForProcess: true)){

                var notification = new TestNotification();
                var activity = new TestActivity(new List<InstructionBase>() { new RaiseNotificationInstruction<TestNotification>(notification) });
                long waitTime = 10;

                var process = new ActivityHostProcess(activity, waitTime);

                Assert.IsNotNull(process.SimulationState);
                Assert.IsTrue(process.SimulationState.IsActive);

                var registeredProcesses = context.GetByType<Process>();
                Assert.IsTrue(registeredProcesses.Contains(process));

                var enumerator = process.Simulate();

                bool couldMove = enumerator.MoveNext();
                Assert.IsTrue(couldMove);

                // first instruction should be the wait instruction
                Assert.IsTrue(enumerator.Current is WaitInstruction);
                Assert.AreEqual(waitTime, ((WaitInstruction)enumerator.Current).NumberOfPeriodsToWait);

                couldMove = enumerator.MoveNext();
                Assert.IsTrue(couldMove);

                Assert.IsTrue(enumerator.Current is RaiseNotificationInstruction<TestNotification>);
                Assert.AreEqual(notification, ((RaiseNotificationInstruction<TestNotification>)enumerator.Current).Notification);

                couldMove = enumerator.MoveNext();
                Assert.IsFalse(couldMove);
            }
        }
        public void CanComplete_BeforeAndAfterEvent_ReturnsTrueOnlyAfterEvent()
        {
            using (var context = new SimulationContext(isDefaultContextForProcess:true)){

                var waitInstruction = new WaitNotificationInstruction<object>();
                var process = new InstructionListTestProcess(new List<InstructionBase>(){ waitInstruction});

                context.MoveToTimePeriod(0);
                process.SimulationState.InstructionEnumerator = process.Simulate();
                process.SimulationState.InstructionEnumerator.MoveNext();

                var testEvent = new TestNotification();
                var raiseInstruction = new RaiseNotificationInstruction<object>(testEvent);

                long? nextTimePeriodCheck;
                bool canComplete = waitInstruction.CanComplete(context, out nextTimePeriodCheck);

                Assert.IsFalse(canComplete);
                Assert.IsNull(nextTimePeriodCheck);

                raiseInstruction.Complete(context);

                canComplete = waitInstruction.CanComplete(context, out nextTimePeriodCheck);

                Assert.IsTrue(canComplete);
                Assert.IsNull(nextTimePeriodCheck);
            }
        }
        public void CanComplete_BeforeAndAfterEventWithCondition_ReturnsTrueOnlyAfterEventMatchingCondition()
        {
            using (var context = new SimulationContext(isDefaultContextForProcess:true)){

                var waitInstruction = new WaitNotificationInstruction<TestNotification>((e)=>e.Data > 0);
                var process = new InstructionListTestProcess(new List<InstructionBase>(){ waitInstruction});
                context.MoveToTimePeriod(0);
                process.SimulationState.InstructionEnumerator = process.Simulate();
                process.SimulationState.InstructionEnumerator.MoveNext();

                var testEvent1 = new TestNotification() { Data = 0 };
                var raiseInstruction1 = new RaiseNotificationInstruction<TestNotification>(testEvent1);

                var testEvent2 = new TestNotification() { Data = 1 };
                var raiseInstruction2 = new RaiseNotificationInstruction<TestNotification>(testEvent2);

                long? nextTimePeriodCheck;
                bool canComplete = waitInstruction.CanComplete(context, out nextTimePeriodCheck);

                Assert.IsFalse(canComplete);
                Assert.IsNull(nextTimePeriodCheck);

                raiseInstruction1.Complete(context);

                canComplete = waitInstruction.CanComplete(context, out nextTimePeriodCheck);

                Assert.IsFalse(canComplete);
                Assert.IsNull(nextTimePeriodCheck);

                raiseInstruction2.Complete(context);

                canComplete = waitInstruction.CanComplete(context, out nextTimePeriodCheck);

                Assert.IsTrue(canComplete);
                Assert.IsNull(nextTimePeriodCheck);
                Assert.AreEqual(1,waitInstruction.Notifications.Count);
                Assert.IsTrue(waitInstruction.Notifications.Contains(testEvent2));
            }
        }
        public void Simulate_ActivitySpecified_ActivityFiredAtTheAppropriateTime()
        {
            using (var context = new SimulationContext(isDefaultContextForProcess: true)){
                var notification = new TestNotification();
                var activity     = new TestActivity(new List <InstructionBase>()
                {
                    new RaiseNotificationInstruction <TestNotification>(notification)
                });
                long waitTime = 10;

                var process = new ActivityHostProcess(activity, waitTime);

                Assert.IsNotNull(process.SimulationState);
                Assert.IsTrue(process.SimulationState.IsActive);

                var registeredProcesses = context.GetByType <Process>();
                Assert.IsTrue(registeredProcesses.Contains(process));

                var enumerator = process.Simulate();

                bool couldMove = enumerator.MoveNext();
                Assert.IsTrue(couldMove);

                // first instruction should be the wait instruction
                Assert.IsTrue(enumerator.Current is WaitInstruction);
                Assert.AreEqual(waitTime, ((WaitInstruction)enumerator.Current).NumberOfPeriodsToWait);

                couldMove = enumerator.MoveNext();
                Assert.IsTrue(couldMove);

                Assert.IsTrue(enumerator.Current is RaiseNotificationInstruction <TestNotification>);
                Assert.AreEqual(notification, ((RaiseNotificationInstruction <TestNotification>)enumerator.Current).Notification);

                couldMove = enumerator.MoveNext();
                Assert.IsFalse(couldMove);
            }
        }