public void AbortShouldThrowObjectDisposed()
        {
            // Arrange
            TestTrace.Arrange();
            var activity = new Sequence();
            var workflow = new WorkflowP1(activity);

            try
            {
                // Act
                TestTrace.Act();
                workflow.Dispose();

                // Assert
                TestTrace.Assert();
                AssertHelper.Throws<ObjectDisposedException>(() => workflow.Abort());
            }
            finally
            {
                TestTrace.Finally();

                // Trace things here
            }
        }
        public void TraceOptionsSetShouldThrowObjectDisposed()
        {
            // Arrange
            TestTrace.Arrange();
            var activity = new Sequence();
            var workflow = new WorkflowP1(activity);
            workflow.RunAsync().Wait();

            try
            {
                // Act
                TestTrace.Act();
                workflow.Dispose();

                // Assert
                TestTrace.Assert();
                AssertHelper.Throws<ObjectDisposedException>(() => workflow.TraceOptions = WorkflowTraceOptions.Debug);
            }
            finally
            {
                TestTrace.Finally();

                // Trace things here
            }
        }
        public void RunWithInvalidArgShouldThrow()
        {
            // Arrange
            TestTrace.Arrange();
            var activity = new EchoArg<int>();
            using (var workflow = new WorkflowP1(activity) { Extensions = { new ListTrackingParticipant() } })
            {
                // Intentionally used wrong name
                workflow.Inputs.Input1 = 123;

                try
                {
                    // Act 
                    TestTrace.Act();

                    // Assert
                    TestTrace.Assert();
                    AssertHelper.Throws<ArgumentException>(workflow.RunAsync());
                }
                finally
                {
                    TestTrace.Finally();
                    workflow.Trace();
                }
            }
        }
        public void RunTwiceShouldThrow()
        {
            // Arrange
            TestTrace.Arrange();
            var activity = new Sequence();
            var workflow = new WorkflowP1(activity);

            try
            {
                // Act / Assert
                TestTrace.Act();
                workflow.RunAsync().Wait();

                // Assert
                TestTrace.Assert();
                AssertHelper.Throws<AggregateException>(() => workflow.RunAsync().Wait(), typeof(WorkflowApplicationCompletedException));
            }
            finally
            {
                TestTrace.Finally();

                // Trace objects here
            }
        }
        public void RunWithArgsSimple()
        {
            var activity = new EchoArg<int>();

            var workflow = new WorkflowP1(activity);

            // Setup EchoArg.Value in argument
            workflow.Inputs.Value = 123;

            var result = workflow.Until.Complete.Run();

            // Access EchoArg.Result out argument
            Assert.AreEqual(123, result.Outputs.Result);
        }
        public void RunSimple()
        {
            var activity = new Sequence();

            // Workflow owns disposable members
            using (var workflow = new WorkflowP1(activity))
            {
                workflow.RunAsync().Wait();
            }
        }
        public void RunShouldThrowIfDisposed()
        {
            // Arrange
            TestTrace.Arrange();
            var activity = new Sequence();
            using (var workflow = new WorkflowP1(activity) { Timeout = Constants.Timeout })
            {
                Exception exception = null;
                try
                {
                    // Act
                    TestTrace.Act();
                    workflow.Dispose();

                    // ReSharper disable AccessToDisposedClosure
                    // Testing dispose behavior
                    exception = AssertHelper.Throws<ObjectDisposedException>(() => workflow.RunAsync().Wait());

                    // ReSharper restore AccessToDisposedClosure

                    // Assert
                    TestTrace.Assert();
                }
                finally
                {
                    TestTrace.Finally();
                    exception.Trace();
                }
            }
        }
        public void CancelWithTokenSource()
        {
            // Arrange
            TestTrace.Arrange();
            var activity = new Delay { Duration = TimeSpan.FromMilliseconds(200) };
            var workflow = new WorkflowP1(activity)
                {
                    Timeout = Constants.Timeout,
                    Extensions =
                        {
                            new ListTrackingParticipant()
                        }
                };
            var delayExecuting = new AutoResetEvent(false);
            var source = new CancellationTokenSource(Constants.Timeout);

            // When the workflow is idle set an event to trigger the test to cancel
            workflow.When.Idle += (sender, args) => delayExecuting.Set();

            try
            {
                // Act
                TestTrace.Act();

                // Start the workflow async
                var task = workflow.RunAsync(source.Token);

                TestTrace.Write("Waiting for Delay activity to start executing");
                var delayIsExecuting = delayExecuting.WaitOne(Constants.Timeout);


                if (delayIsExecuting)
                {
                    TestTrace.Write("Cancelling workflow via token source");
                    source.Cancel();
                }


                // Assert
                TestTrace.Assert();
                Assert.IsTrue(delayIsExecuting);

                AssertHelper.Throws<AggregateException>(task.Wait, typeof(TaskCanceledException));

                // Canceled tasks can run to completion
                Assert.IsTrue(task.IsCanceled, "The task was not canceled");
                Assert.IsTrue(task.IsCompleted, "Task was not completed, task status is " + task.Status.ToString());
            }
            finally
            {
                TestTrace.Finally();

                workflow.Trace();
            }
        }
        public void RunShouldRunWorkflowToCompletion()
        {
            // Arrange
            TestTrace.Arrange();
            var activity = new Sequence();
            using (var workflow = new WorkflowP1(activity) { Timeout = Constants.Timeout })
            {
                try
                {
                    // Act
                    TestTrace.Act();
                    var result = workflow.RunAsync().Result as WorkflowCompletedResult;

                    // Assert
                    TestTrace.Assert();
                    Assert.IsNotNull(result);
                }
                finally
                {
                    TestTrace.Finally();
                    workflow.Trace();
                }
            }
        }
        public void ResumeAsyncWithTokenShouldThrowObjectDisposed()
        {
            // Arrange
            TestTrace.Arrange();
            var activity = new Sequence();
            var workflow = new WorkflowP1(activity);
            workflow.RunAsync().Wait();

            try
            {
                // Act
                TestTrace.Act();
                workflow.Dispose();

                // Assert
                TestTrace.Assert();
                AssertHelper.Throws<ObjectDisposedException>(() => workflow.ResumeAsync("Foo").Wait());
            }
            finally
            {
                TestTrace.Finally();

                // Trace things here
            }
        }
        public void PersistableIdleGetShouldThrowObjectDisposed()
        {
            // Arrange
            TestTrace.Arrange();
            var activity = new Sequence();
            var workflow = new WorkflowP1(activity);
            workflow.RunAsync().Wait();

            try
            {
                // Act
                TestTrace.Act();
                workflow.Dispose();

                // Assert
                TestTrace.Assert();
                AssertHelper.Throws<ObjectDisposedException>(() => AssertHelper.GetProperty(workflow.PersistableIdle));
            }
            finally
            {
                TestTrace.Finally();

                // Trace things here
            }
        }
        public void CancelTaskAsyncActivityViaToken()
        {
            // Arrange
            TestTrace.Arrange();
            var spinExecuting = new ManualResetEvent(false);
            var completedEvent = new ManualResetEvent(false);
            var notify = new SpinNotify { LoopComplete = (loops, iterations) => spinExecuting.Set() };
            var cancellationHandlerClosed = new AutoResetEvent(false);
            var activity = CreateSequenceWithSpinWaiter(typeof(TaskSpinWaiter));

            var tracking = new ListTrackingParticipant();

            var workflow = new WorkflowP1(activity)
            {
                Timeout = Constants.Timeout,
                Extensions =
                        {
                            tracking, 
                            notify
                        }
            };

            workflow.When.Activity.Name("CancellationHandler").Closed +=
                (sender, args) => cancellationHandlerClosed.Set();

            workflow.When.Completed += (sender, args) => completedEvent.Set();

            var source = new CancellationTokenSource(Constants.Timeout);

            try
            {
                // Act
                TestTrace.Act();
                var task = workflow.RunAsync(source.Token);

                TestTrace.Write("Waiting for AsyncSpinWaiter to start executing");
                Assert.IsTrue(spinExecuting.WaitOne(Constants.Timeout));

                TestTrace.Write("Cancelling workflow with token");
                source.Cancel();

                TestTrace.Write("Waiting for workflow to execute cancellation handler");
                Assert.IsTrue(cancellationHandlerClosed.WaitOne(Constants.Timeout));

                TestTrace.Write("Waiting for workflow");

                // Assert
                TestTrace.Assert();
                AssertHelper.Throws<AggregateException>(task.Wait, typeof(TaskCanceledException));
                Assert.IsTrue(
                    tracking.Records.Any(ActivityInstanceState.Closed, "CancellationHandler"),
                    "The cancellation handler was not invoked");
                Assert.IsTrue(task.IsCanceled);
                Assert.IsTrue(task.IsCompleted);
            }
            finally
            {
                TestTrace.Finally();

                workflow.Trace();
            }
        }
        public void CancelWithTokenSimple()
        {
            var activity = new Delay() { Duration = TimeSpan.FromSeconds(10) };
            var workflow = new WorkflowP1(activity);
            var cancellationTokenSource = new CancellationTokenSource(Constants.Timeout);

            // Run until idle
            var task = workflow.Until.Idle.RunAsync(cancellationTokenSource.Token);

            // Cancel with the token source
            cancellationTokenSource.Cancel();

            // If you try to do anything with the task, you get an exception
            AssertHelper.Throws<AggregateException>(
                task.Wait,
                typeof(TaskCanceledException),
                "The task should be canceled");
            Assert.IsTrue(task.IsCanceled);
        }
        public void CancelWithAsyncActivityWillCancel()
        {
            // Arrange
            TestTrace.Arrange();
            var spinExecuting = new AutoResetEvent(false);
            var notify = new SpinNotify { LoopComplete = (loops, iterations) => spinExecuting.Set() };
            var cancellationHandlerClosed = new AutoResetEvent(false);
            var activity = CreateSequenceWithSpinWaiter(typeof(AsyncSpinWaiter));

            var tracking = new ListTrackingParticipant();

            var workflow = new WorkflowP1(activity)
            {
                Timeout = Constants.Timeout,
                Extensions =
                        {
                            tracking, 
                            notify
                        }
            };

            workflow.When.Activity.Name("CancellationHandler").Closed +=
                (sender, args) => cancellationHandlerClosed.Set();

            var source = new CancellationTokenSource(Constants.Timeout);

            try
            {
                // Act
                TestTrace.Act();
                workflow.Until.Idle.RunAsync(source.Token);

                TestTrace.Write("Waiting for AsyncSpinWaiter to start executing");
                var spinWait = spinExecuting.WaitOne(TimeSpan.FromSeconds(10));

                TestTrace.Write("Cancelling workflow");
                source.Cancel();

                var cancelInvoked = cancellationHandlerClosed.WaitOne(Constants.Timeout);

                // Assert
                TestTrace.Assert();
                Assert.IsTrue(spinWait, "The spinExecuting event was not set");
                Assert.IsTrue(cancelInvoked);
                Assert.IsTrue(
                    tracking.Records.Any(ActivityInstanceState.Closed, "CancellationHandler"),
                    "The cancellation handler was not invoked");
            }
            finally
            {
                TestTrace.Finally();

                workflow.Trace();
            }
        }