public IEnumerator MultipleFinallyOrder()
        {
            using (var test = StartTest())
            {
                var results = new List <string>();

                var beforeProcess = new ActionTask(test.TaskManager, _ => results.Add("BeforeProcess"))
                {
                    Name = "BeforeProcess"
                };
                var processTask = new HelperProcessTask(test.TaskManager, test.ProcessManager, TestApp, "-x")
                {
                    Name = "Process"
                };

                // this will never run because the process throws an exception
                var processOutputTask = new FuncTask <string, int>(test.TaskManager, (success, previous) => {
                    results.Add(previous);
                    results.Add("ProcessOutput");
                    return(1234);
                });

                var innerChain = processTask.Then(processOutputTask).Finally((b, exception) => results.Add("ProcessFinally"), "ProcessFinally");
                var outerChain = beforeProcess.Then(innerChain).Finally((b, exception) => results.Add("AfterProcessFinally"), "AfterProcessFinally");

                // wait for the tasks to finish
                foreach (var frame in StartAndWaitForCompletion(innerChain, outerChain))
                {
                    yield return(frame);
                }

                results.MatchesUnsorted(new[] { "BeforeProcess", "ProcessFinally", "AfterProcessFinally" });
                Assert.AreEqual("BeforeProcess", results[0]);

                var expected = new List <string> {
                    "ProcessFinally", "AfterProcessFinally"
                };
                results.Skip(1).MatchesUnsorted(expected);
            }
        }
        public IEnumerator ProcessOnStartOnEndTaskOrder()
        {
            using (var test = StartTest())
            {
                var    values        = new List <string>();
                string process1Value = null;
                string process2Value = null;

                var process1Task = new HelperProcessTask(test.TaskManager, test.ProcessManager, TestApp, @"--sleep 100 -d process1")
                                   .Configure(test.ProcessManager)
                                   .Then(s => {
                    process1Value = s;
                    values.Add(s);
                });

                var process2Task = new HelperProcessTask(test.TaskManager, test.ProcessManager, TestApp, @"---sleep 100 -d process2")
                                   .Configure(test.ProcessManager)
                                   .Then(s => {
                    process2Value = s;
                    values.Add(s);
                });

                var combinedTask = process1Task.Then(process2Task);

                combinedTask.OnStart += task => { values.Add("OnStart"); };

                combinedTask.OnEnd += (task, success, ex) => { values.Add("OnEnd"); };

                // wait for the tasks to finish
                foreach (var frame in StartAndWaitForCompletion(combinedTask))
                {
                    yield return(frame);
                }

                Assert.AreEqual(process1Value, "process1");
                Assert.AreEqual(process2Value, "process2");
                Assert.True(values.SequenceEqual(new[] { "process1", "OnStart", "process2", "OnEnd" }));
            }
        }
        public IEnumerator NestedProcessShouldChainCorrectly()
        {
            using (var test = StartTest())
            {
                var expected = new List <string> {
                    "BeforeProcess", "ok", "AfterProcess", "ProcessFinally", "AfterProcessFinally"
                };

                var results = new List <string>();

                var beforeProcess = new ActionTask(test.TaskManager, _ => results.Add("BeforeProcess"))
                {
                    Name = "BeforeProcess"
                };
                var processTask = new HelperProcessTask(test.TaskManager, test.ProcessManager, TestApp, @"--sleep 1000 --data ""ok""");

                var processOutputTask = new FuncTask <string, int>(test.TaskManager, (b, previous) => {
                    results.Add(previous);
                    results.Add("AfterProcess");
                    return(1234);
                })
                {
                    Name = "AfterProcess"
                };

                var innerChain = processTask.Then(processOutputTask).Finally((b, exception) => results.Add("ProcessFinally"), "ProcessFinally");

                var outerChain = beforeProcess.Then(innerChain).Finally((b, exception) => results.Add("AfterProcessFinally"), "AfterProcessFinally");

                // wait for the tasks to finish
                foreach (var frame in StartAndWaitForCompletion(innerChain, outerChain))
                {
                    yield return(frame);
                }

                results.Matches(expected);
            }
        }