public AdvancedBranchingExpression(StatefulWorkflow <T> workflow,
                                    Func <T, IDictionary <string, object>, bool> condition, IWorkflow <T> current, StatefulBuilder <T> builder,
                                    ITransitionRule <T> transitionRule)
     : base(workflow, current, builder, transitionRule)
 {
     _condition = condition;
 }
예제 #2
0
        public void it_throws_a_WorkflowActionFailedException()
        {
            var wf = new StatefulWorkflow<Entity>()
                .When(x => true).Fail()
                .Yield("end");

            Assert.Throws<WorkflowActionFailedException>(() => wf.Start(new Entity()));
        }
예제 #3
0
        public void it_throws_a_WorkflowActionFailedException()
        {
            var wf = new StatefulWorkflow <Entity>()
                     .When(x => true).Fail()
                     .Yield("end");

            Assert.Throws <WorkflowActionFailedException>(() => wf.Start(new Entity()));
        }
예제 #4
0
 public AbstractBranchingCondition(StatefulWorkflow <T> workflow, IWorkflow <T> current,
                                   StatefulBuilder <T> builder, ITransitionRule <T> transitionRule)
 {
     this._workflow       = workflow;
     this._current        = current;
     this._builder        = builder;
     this._transitionRule = transitionRule;
 }
예제 #5
0
        public void NoBranchesHasOneTransition()
        {
            var wf = new StatefulWorkflow<StatefulObject>(2, gateway.Object)
                .Do(x => x);

            var transitions = wf.PossibleTransitions.ToList();
            transitions.Count.ShouldBe(1);
            transitions.Where(x => x.From == null && x.To == null).Count().ShouldBe(1);
        }
예제 #6
0
        public void NoYieldsHasOneTransition()
        {
            var wf = new StatefulWorkflow <StatefulObject>(2, gateway.Object)
                     .Do(x => x);

            var transitions = wf.PossibleTransitions.ToList();

            transitions.Count.ShouldBe(1);
            transitions.Where(x => x.From == null && x.To == null).Count().ShouldBe(1);
        }
예제 #7
0
        public void it_recognizes_that_branch_within_PossibleTransitions_collection()
        {
            var wf = new StatefulWorkflow <Entity>()
                     .Yield("broke")
                     .Yield("begin")
                     .When(x => true).BreakWithStatus("broke")
                     .Yield("didn't break");

            Assert.That(wf.PossibleTransitions.Any(x => (string)x.From == "begin" && (string)x.To == "broke"),
                        "PossibleTransitions should contain the potential transition from 'begin' to 'broke'");
        }
예제 #8
0
        public void OneYieldHasTwoTransitions()
        {
            var wf = new StatefulWorkflow<StatefulObject>(2, gateway.Object)
                .Do(x => x)
                .Yield(1);

            var transitions = wf.PossibleTransitions.ToList();
            transitions.Count.ShouldBe(2);
            transitions.Where(x => x.From == null && (int?)x.To == 1).Count().ShouldBe(1);
            transitions.Where(x => (int?)x.From == 1 && x.To == null).Count().ShouldBe(1);
        }
        public void it_recognizes_that_branch_within_PossibleTransitions_collection()
        {
            var wf = new StatefulWorkflow<Entity>()
                .Yield("broke")
                .Yield("begin")
                .When(x => true).BreakWithStatus("broke")
                .Yield("didn't break");

            Assert.That(wf.PossibleTransitions.Any(x => (string)x.From == "begin" && (string)x.To == "broke"),
                "PossibleTransitions should contain the potential transition from 'begin' to 'broke'");
        }
예제 #10
0
        public void OneYieldHasTwoTransitions()
        {
            var wf = new StatefulWorkflow <StatefulObject>(2, gateway.Object)
                     .Do(x => x)
                     .Yield(1);

            var transitions = wf.PossibleTransitions.ToList();

            transitions.Count.ShouldBe(2);
            transitions.Where(x => x.From == null && (int?)x.To == 1).Count().ShouldBe(1);
            transitions.Where(x => (int?)x.From == 1 && x.To == null).Count().ShouldBe(1);
        }
예제 #11
0
        public void OneBranchHasOneTransition()
        {
            var branch1 = Declare.Step();
            var wf = new StatefulWorkflow<StatefulObject>(2, gateway.Object)
                .Define(branch1)
                .Do(x => x)
                .When(x => true).BranchTo(branch1);

            var transitions = wf.PossibleTransitions.ToList();
            transitions.Count.ShouldBe(1);
            transitions.Where(x => x.From == null && x.To == null).Count().ShouldBe(1);
        }
예제 #12
0
        public void OneBranchHasOneTransition()
        {
            var branch1 = Declare.Step();
            var wf      = new StatefulWorkflow <StatefulObject>(2, gateway.Object)
                          .Define(branch1)
                          .Do(x => x)
                          .When(x => true).BranchTo(branch1);

            var transitions = wf.PossibleTransitions.ToList();

            transitions.Count.ShouldBe(1);
            transitions.Where(x => x.From == null && x.To == null).Count().ShouldBe(1);
        }
예제 #13
0
        public void TwoForwardReferencesHasOneTransition()
        {
            var branch1 = Declare.Step();
            var wf = new StatefulWorkflow<StatefulObject>(2, gateway.Object)
                .When(x => true, otherwise: branch1)
                .Do(x => x)
                .When(x => true, otherwise: branch1)
                .Define(defineAs: branch1);

            var transitions = wf.PossibleTransitions.ToList();
            transitions.Count.ShouldBe(1);
            transitions.Where(x => x.From == null && x.To == null).Count().ShouldBe(1);
        }
예제 #14
0
        public void Operations_work_when_using_objects()
        {
            var wf = new StatefulWorkflow <ITest>("wf");

            wf.Yield(13);
            wf.Do((x, i) => { x.Ping((int)i["i"]); });

            var test = Mock.Of <ITest>(x => (int)x.GetStateId("wf") == 13);
            var mock = Mock.Get(test);

            wf.StartWithParams(test, new { i = 42 });
            mock.Verify(x => x.SetStateId("wf", null));
            mock.Verify(x => x.Ping((int)42));
        }
예제 #15
0
 public void Simple()
 {
     var wf = new StatefulWorkflow<StatefulObject>(2, gateway.Object)
         .Yield(1)
         .Do(x => x.Feedback("middle"))
         .Yield(2)
         ;
     gateway.SetReturnsDefault<bool>(true);
     gateway.Setup(x => x.IsTransitionAllowed(
         It.Is<ITransition>(y => (int?)y.From == 1 && (int?)y.To == 2)))
         .Returns(false);
     wf.Start(obj.Object);
     Assert.Throws<UnallowedTransitionException>(() => wf.Start(obj.Object));
     obj.Verify(x => x.Feedback("middle"), Times.Never());
 }
예제 #16
0
        public void it_can_use_params_at_any_step()
        {
            string secondStep = null;
            var wf = new StatefulWorkflow<ITest>("wf");
            wf.Yield(13);
            wf.Do((x, i) => { x.Ping((int)i["i"]); });
            wf.Do((x, opts) => secondStep = (string)opts["o"]);

            var test = Mock.Of<ITest>(x => (int)x.GetStateId("wf") == 13);
            var mock = Mock.Get(test);
            wf.StartWithParams(test, new { i = 42, o = "hello" });
            mock.Verify(x => x.SetStateId("wf", null));
            mock.Verify(x => x.Ping((int)42));
            secondStep.ShouldBe("hello");
        }
        public void it_will_let_you_break_with_a_nonexistent_state()
        {
            bool branched = false;
            var wf = new StatefulWorkflow<Entity>()
                .Do(x => branched = true)
                .Yield("broke")
                .Yield("begin")
                .When(x => true).BreakWithStatus("nonexistent")
                .Yield("didn't break");

            var obj = new Entity() { state = "begin" };
            wf.Start(obj);
            obj.state.ShouldBe("nonexistent");
            Assert.That(!branched);
        }
예제 #18
0
        public void it_can_branch_using_negative_When()
        {
            var point = Declare.Step();

            var wf = new StatefulWorkflow<Entity>()
                .Define(point)
                .Yield("branched")
                .Yield("start")
                .When(x => false).BranchTo(point)
                .Yield("didn't branch");

            var obj = new Entity() { state = "start" };
            wf.Start(obj);
            Assert.That(obj.GetStateId(null), Is.EqualTo("didn't branch"));
        }
예제 #19
0
        public void it_can_branch_using_negative_Unless_with_parameters()
        {
            var point = Declare.Step();

            var wf = new StatefulWorkflow<Entity>()
                .Define(point)
                .Yield("branched")
                .Yield("start")
                .Unless((x, opts) => (bool)opts["shouldBranch"]).BranchTo(point)
                .Yield("didn't branch");

            var obj = new Entity() { state = "start" };
            wf.StartWithParams(obj, new { shouldBranch = false });
            Assert.That(obj.GetStateId(null), Is.EqualTo("branched"));
        }
예제 #20
0
        public void StartsAndEndsWithDefines()
        {
            var start = Declare.Step();
            var end = Declare.Step();
            var wf = new StatefulWorkflow<StatefulObject>(2, gateway.Object)
                .Define(start)
                .Yield(1)
                .Define(end)
                ;

            var transitions = wf.PossibleTransitions.ToList();
            transitions.Count.ShouldBe(2);
            transitions.Where(x => x.From == null && (int?)x.To == 1).Count().ShouldBe(1);
            transitions.Where(x => (int?)x.From == 1 && x.To == null).Count().ShouldBe(1);
        }
예제 #21
0
        public void failed_branches_work_with_parameters()
        {
            var jump = Declare.Step();

            var wf = new StatefulWorkflow<ITest>("wf")
                .Unless((x, opts) => (bool)opts["flag"]).BranchTo(jump)
                .Yield("it didn't jump")
                .Define(jump)
                .Yield("it jumped");

            var test = Mock.Of<ITest>();
            wf.StartWithParams(test, new { flag = true });
            Mock.Get(test).Verify(x => x.SetStateId("wf", "it jumped"), Times.Never());
            Mock.Get(test).Verify(x => x.SetStateId("wf", "it didn't jump"));
        }
예제 #22
0
        public void it_throws_a_WorkflowActionFailedException_with_a_formatted_message()
        {
            var wf = new StatefulWorkflow<Entity>()
                .When(x => true).Fail(x => x.With("{0} message", 1))
                .Yield("end");

            try
            {
                wf.Start(new Entity());
                Assert.Fail("an exception should have been thrown");
            }
            catch (WorkflowActionFailedException e)
            {
                e.Message.ShouldBe("1 message");
            }
        }
예제 #23
0
        public void failed_branches_work_with_parameters()
        {
            var jump = Declare.Step();

            var wf = new StatefulWorkflow <ITest>("wf")
                     .Unless((x, opts) => (bool)opts["flag"]).BranchTo(jump)
                     .Yield("it didn't jump")
                     .Define(jump)
                     .Yield("it jumped");

            var test = Mock.Of <ITest>();

            wf.StartWithParams(test, new { flag = true });
            Mock.Get(test).Verify(x => x.SetStateId("wf", "it jumped"), Times.Never());
            Mock.Get(test).Verify(x => x.SetStateId("wf", "it didn't jump"));
        }
예제 #24
0
        public void it_throws_a_WorkflowActionFailedException_with_a_formatted_message()
        {
            var wf = new StatefulWorkflow <Entity>()
                     .When(x => true).Fail(x => x.With("{0} message", 1))
                     .Yield("end");

            try
            {
                wf.Start(new Entity());
                Assert.Fail("an exception should have been thrown");
            }
            catch (WorkflowActionFailedException e)
            {
                e.Message.ShouldBe("1 message");
            }
        }
예제 #25
0
        public void StartsAndEndsWithDefines()
        {
            var start = Declare.Step();
            var end   = Declare.Step();
            var wf    = new StatefulWorkflow <StatefulObject>(2, gateway.Object)
                        .Define(start)
                        .Yield(1)
                        .Define(end)
            ;

            var transitions = wf.PossibleTransitions.ToList();

            transitions.Count.ShouldBe(2);
            transitions.Where(x => x.From == null && (int?)x.To == 1).Count().ShouldBe(1);
            transitions.Where(x => (int?)x.From == 1 && x.To == null).Count().ShouldBe(1);
        }
예제 #26
0
        public void Simple()
        {
            var wf = new StatefulWorkflow <StatefulObject>(2, gateway.Object)
                     .Yield(1)
                     .Do(x => x.Feedback("middle"))
                     .Yield(2)
            ;

            gateway.SetReturnsDefault <bool>(true);
            gateway.Setup(x => x.IsTransitionAllowed(
                              It.Is <ITransition>(y => (int?)y.From == 1 && (int?)y.To == 2)))
            .Returns(false);
            wf.Start(obj.Object);
            Assert.Throws <UnallowedTransitionException>(() => wf.Start(obj.Object));
            obj.Verify(x => x.Feedback("middle"), Times.Never());
        }
        public int multiple_workflow_steps_are_executed_conditionally(bool branch)
        {
            int hitInnerBranch = 0, hitOutterBranch = 0;
            var workflow = new StatefulWorkflow<Entity>()
                .When(x => branch).Do(wf =>
                {
                    wf.Do(x => hitInnerBranch++);
                    wf.Do(x => hitInnerBranch++);
                })
                .Do(x => hitOutterBranch++)
                .Yield("end");

            var obj = new Entity();
            workflow.Start(obj);
            hitOutterBranch.ShouldBe(1);
            return hitInnerBranch;
        }
예제 #28
0
        public void it_can_use_params_at_any_step()
        {
            string secondStep = null;
            var    wf         = new StatefulWorkflow <ITest>("wf");

            wf.Yield(13);
            wf.Do((x, i) => { x.Ping((int)i["i"]); });
            wf.Do((x, opts) => secondStep = (string)opts["o"]);

            var test = Mock.Of <ITest>(x => (int)x.GetStateId("wf") == 13);
            var mock = Mock.Get(test);

            wf.StartWithParams(test, new { i = 42, o = "hello" });
            mock.Verify(x => x.SetStateId("wf", null));
            mock.Verify(x => x.Ping((int)42));
            secondStep.ShouldBe("hello");
        }
예제 #29
0
        public void it_throws_the_exception_created_by_the_user()
        {
            var ex = new UserDefinedException();
            var wf = new StatefulWorkflow <Entity>()
                     .When(x => true).Fail(f => f.With(x => ex))
                     .Yield("end");

            try
            {
                wf.Start(new Entity());
                Assert.Fail("an exception should have been thrown");
            }
            catch (UserDefinedException e)
            {
                Assert.That(e, Is.SameAs(ex));
            }
        }
예제 #30
0
        public void it_can_access_info_from_lambda()
        {
            bool lambdaCalled = false;
            var wf = new StatefulWorkflow<Entity>()
                .Yield("start")
                .When(x => true).Fail(f => f.With(o =>
                {
                    lambdaCalled = true;
                    Assert.That(o, Is.Not.Null);
                    Assert.That(o.GetStateId(null), Is.EqualTo("start"));
                    return "failed successfully";
                }))
                .Yield("end");

            Assert.Throws<WorkflowActionFailedException>(() => wf.Start(new Entity() { state = "start" }));
            Assert.That(lambdaCalled, "lambda builder function should be called");
        }
예제 #31
0
        public int multiple_workflow_steps_are_executed_conditionally(bool branch)
        {
            int hitInnerBranch = 0, hitOutterBranch = 0;
            var workflow = new StatefulWorkflow <Entity>()
                           .When(x => branch).Do(wf =>
            {
                wf.Do(x => hitInnerBranch++);
                wf.Do(x => hitInnerBranch++);
            })
                           .Do(x => hitOutterBranch++)
                           .Yield("end");

            var obj = new Entity();

            workflow.Start(obj);
            hitOutterBranch.ShouldBe(1);
            return(hitInnerBranch);
        }
예제 #32
0
        public void I_can_have_2_branches_to_the_same_yield()
        {
            var branch1 = Declare.Step();
            var wf      = new StatefulWorkflow <StatefulObject>(2, gateway.Object);

            wf.Yield(1);
            wf.When(x => true).BranchTo(branch1);
            wf.Yield(2);
            wf.When(x => true).BranchTo(branch1);
            wf.Yield(3);
            wf.Define(branch1);
            wf.Yield(4);

            var transitions = wf.PossibleTransitions.ToList();

            transitions.Where(x => (int?)x.From == 1 && (int?)x.To == 4).Count().ShouldBe(1);
            transitions.Where(x => (int?)x.From == 2 && (int?)x.To == 4).Count().ShouldBe(1);
        }
예제 #33
0
        public void it_can_access_data_from_lambda()
        {
            bool lambdaCalled = false;
            var wf = new StatefulWorkflow<Entity>()
                .Yield("start")
                .When(x => true).Fail(f => f.With((o, opts) =>
                {
                    lambdaCalled = true;
                    Assert.That(opts, Is.Not.Null);
                    Assert.That(opts["option"], Is.EqualTo("this"));
                    return "failed successfully";
                }))
                .Yield("end");

            Assert.Throws<WorkflowActionFailedException>(() =>
            wf.StartWithParams(new Entity() { state = "start" }, new { option = "this" }));
            Assert.That(lambdaCalled, "lambda builder function should be called");
        }
예제 #34
0
        public void it_can_branch_using_positive_Unless_with_parameters()
        {
            var point = Declare.Step();

            var wf = new StatefulWorkflow <Entity>()
                     .Define(point)
                     .Yield("branched")
                     .Yield("start")
                     .Unless((x, opts) => (bool)opts["shouldBranch"]).BranchTo(point)
                     .Yield("didn't branch");

            var obj = new Entity()
            {
                state = "start"
            };

            wf.StartWithParams(obj, new { shouldBranch = true });
            Assert.That(obj.GetStateId(null), Is.EqualTo("didn't branch"));
        }
예제 #35
0
        public void it_can_branch_using_positive_Unless()
        {
            var point = Declare.Step();

            var wf = new StatefulWorkflow <Entity>()
                     .Define(point)
                     .Yield("branched")
                     .Yield("start")
                     .Unless(x => true).BranchTo(point)
                     .Yield("didn't branch");

            var obj = new Entity()
            {
                state = "start"
            };

            wf.Start(obj);
            Assert.That(obj.GetStateId(null), Is.EqualTo("didn't branch"));
        }
        public void it_observes_security_rules()
        {
            var security = new Mock<ITransitionGateway>();
            security.Setup(x => x.AllowTransitions(It.IsAny<IList<ITransition>>()))
                .Returns<IList<ITransition>>(x => x.Where(y => (string)y.From == "begin" && (string)y.To == "didn't break"));

            bool branched = false;
            var wf = new StatefulWorkflow<Entity>(null, security.Object)
                .Do(x => branched = true)
                .Yield("broke")
                .Yield("begin")
                .When(x => true).BreakWithStatus("broke")
                .Yield("didn't break");

            var obj = new Entity() { state = "begin" };
            Assert.Throws<UnallowedTransitionException>(() => wf.Start(obj));
            obj.state.ShouldBe("begin");
            Assert.That(!branched);
        }
예제 #37
0
        public void it_will_let_you_break_with_a_nonexistent_state()
        {
            bool branched = false;
            var  wf       = new StatefulWorkflow <Entity>()
                            .Do(x => branched = true)
                            .Yield("broke")
                            .Yield("begin")
                            .When(x => true).BreakWithStatus("nonexistent")
                            .Yield("didn't break");

            var obj = new Entity()
            {
                state = "begin"
            };

            wf.Start(obj);
            obj.state.ShouldBe("nonexistent");
            Assert.That(!branched);
        }
예제 #38
0
        public void it_can_access_info_from_lambda()
        {
            bool lambdaCalled = false;
            var  wf           = new StatefulWorkflow <Entity>()
                                .Yield("start")
                                .When(x => true).Fail(f => f.With(o =>
            {
                lambdaCalled = true;
                Assert.That(o, Is.Not.Null);
                Assert.That(o.GetStateId(null), Is.EqualTo("start"));
                return("failed successfully");
            }))
                                .Yield("end");

            Assert.Throws <WorkflowActionFailedException>(() => wf.Start(new Entity()
            {
                state = "start"
            }));
            Assert.That(lambdaCalled, "lambda builder function should be called");
        }
        public void DoubleBranchDoesNotAddDuplicate()
        {
            var branch1 = Declare.Step();
            var wf = new StatefulWorkflow<StatefulObject>(2, gateway.Object)
                .Yield(1)
                .Define(branch1)
                .Yield(2)
                .When(x => true).BranchTo(branch1)
                .When(x => true).BranchTo(branch1);

            var transitions = wf.PossibleTransitions.ToList();
            transitions.Should(Have.Count.EqualTo(4));

            transitions.Where(x => x.From == null && (int?)x.To == 1).Count().ShouldBe(1);
            transitions.Where(x => (int?)x.From == 1 && (int?)x.To == 2).Count().ShouldBe(1);
            transitions.Where(x => (int?)x.From == 2 && x.To == null).Count().ShouldBe(1);
            // as well as
            transitions.Where(x => (int?)x.From == 2 && (int?)x.To == 1).Count().ShouldBe(0);
            transitions.Where(x => (int?)x.From == 2 && (int?)x.To == 2).Count().ShouldBe(1);
        }
예제 #40
0
        public void SingleBranchBetweenFlowsAddsATransition()
        {
            var branch1 = Declare.Step();
            var wf      = new StatefulWorkflow <StatefulObject>(2, gateway.Object)
                          .Yield(1)
                          .Define(branch1)
                          .Yield(2)
                          .When(x => true).BranchTo(branch1);

            var transitions = wf.PossibleTransitions.ToList();

            transitions.Should(Have.Count.EqualTo(4));

            transitions.Should(Have.Some.Matches <ITransition>(x => x.From == null && (int?)x.To == 1));
            transitions.Should(Have.Some.Matches <ITransition>(x => (int?)x.From == 1 && (int?)x.To == 2));
            transitions.Should(Have.Some.Matches <ITransition>(x => (int?)x.From == 2 && x.To == null));
            // as well as
            transitions.Should(Have.Some.Matches <ITransition>(x => (int?)x.From == 2 && (int?)x.To == 2));
            transitions.Should(Have.None.Matches <ITransition>(x => (int?)x.From == 2 && (int?)x.To == 1));
        }
        public void ItUsesTheOriginalStateWhenCheckingSecurity()
        {
            var transitions = new[] { new Transition(null, "start", "end") };
            var security    = new DefaultTransitionGateway(transitions);

            var end = Declare.Step();
            var wf  = new StatefulWorkflow <T>(null, security)
                      .Define(end)
                      .Yield("end")
                      .Yield("start")
                      .Do(x => x.SetStateId(null, "end"))
                      .When(x => true).BranchTo(end);

            var t = new T();

            wf.Start(t);

            // Main assertion is really that it didn't throw a security exception
            Assert.That(t.GetStateId(null), Is.EqualTo("end"));
        }
예제 #42
0
        public void BranchingIntoUnallowedState()
        {
            var branch1 = Declare.Step();
            var wf      = new StatefulWorkflow <StatefulObject>(2, gateway.Object)
                          .Yield(1)
                          .Define(branch1)
                          .Do(x => x.Feedback("middle"))
                          .Yield(2)
                          .When(x => true).BranchTo(branch1)
            ;

            gateway.SetReturnsDefault <bool>(true);
            gateway.Setup(x => x.IsTransitionAllowed(
                              It.Is <ITransition>(y => object.Equals(y.From, 2) && object.Equals(y.To, 2))))
            .Returns(false);
            wf.Start(obj.Object);
            wf.Start(obj.Object);

            Assert.Throws <UnallowedTransitionException>(() => wf.Start(obj.Object));
            obj.Verify(x => x.Feedback("middle"), Times.Once()); // not twice
        }
예제 #43
0
        public void DoubleBranchDoesNotAddDuplicate()
        {
            var branch1 = Declare.Step();
            var wf      = new StatefulWorkflow <StatefulObject>(2, gateway.Object)
                          .Yield(1)
                          .Define(branch1)
                          .Yield(2)
                          .When(x => true).BranchTo(branch1)
                          .When(x => true).BranchTo(branch1);

            var transitions = wf.PossibleTransitions.ToList();

            transitions.Should(Have.Count.EqualTo(4));

            transitions.Where(x => x.From == null && (int?)x.To == 1).Count().ShouldBe(1);
            transitions.Where(x => (int?)x.From == 1 && (int?)x.To == 2).Count().ShouldBe(1);
            transitions.Where(x => (int?)x.From == 2 && x.To == null).Count().ShouldBe(1);
            // as well as
            transitions.Where(x => (int?)x.From == 2 && (int?)x.To == 1).Count().ShouldBe(0);
            transitions.Where(x => (int?)x.From == 2 && (int?)x.To == 2).Count().ShouldBe(1);
        }
예제 #44
0
        public void BranchingIntoUnallowedState()
        {
            var branch1 = Declare.Step();
            var wf = new StatefulWorkflow<StatefulObject>(2, gateway.Object)
                .Yield(1)
                .Define(branch1)
                .Do(x => x.Feedback("middle"))
                .Yield(2)
                .When(x => false, otherwise: branch1)
                ;

            gateway.SetReturnsDefault<bool>(true);
            gateway.Setup(x => x.IsTransitionAllowed(
                It.Is<ITransition>(y => object.Equals(y.From, 2) && object.Equals(y.To, 2))))
                .Returns(false);
            wf.Start(obj.Object);
            wf.Start(obj.Object);

            Assert.Throws<UnallowedTransitionException>(() => wf.Start(obj.Object));
            obj.Verify(x => x.Feedback("middle"), Times.Once()); // not twice
        }
예제 #45
0
        public void it_can_access_data_from_lambda()
        {
            bool lambdaCalled = false;
            var  wf           = new StatefulWorkflow <Entity>()
                                .Yield("start")
                                .When(x => true).Fail(f => f.With((o, opts) =>
            {
                lambdaCalled = true;
                Assert.That(opts, Is.Not.Null);
                Assert.That(opts["option"], Is.EqualTo("this"));
                return("failed successfully");
            }))
                                .Yield("end");

            Assert.Throws <WorkflowActionFailedException>(() =>
                                                          wf.StartWithParams(new Entity()
            {
                state = "start"
            }, new { option = "this" }));
            Assert.That(lambdaCalled, "lambda builder function should be called");
        }
예제 #46
0
        public void it_observes_security_rules()
        {
            var security = new Mock <ITransitionGateway>();

            security.Setup(x => x.AllowTransitions(It.IsAny <IList <ITransition> >()))
            .Returns <IList <ITransition> >(x => x.Where(y => (string)y.From == "begin" && (string)y.To == "didn't break"));

            bool branched = false;
            var  wf       = new StatefulWorkflow <Entity>(null, security.Object)
                            .Do(x => branched = true)
                            .Yield("broke")
                            .Yield("begin")
                            .When(x => true).BreakWithStatus("broke")
                            .Yield("didn't break");

            var obj = new Entity()
            {
                state = "begin"
            };

            Assert.Throws <UnallowedTransitionException>(() => wf.Start(obj));
            obj.state.ShouldBe("begin");
            Assert.That(!branched);
        }
예제 #47
0
        protected override IStatefulWorkflow <JobPosting> Define()
        {
            var createWorkgroup = Declare.Step();
            var createPosition  = Declare.Step();

            var wf = new StatefulWorkflow <JobPosting>();

            wf.Yield(JobPosting.CreationSteps.Begin);
            wf.When((post, dict) => (JobPosting.CreationSteps)dict["next"] == JobPosting.CreationSteps.CreatePosition)
            .Do(wfx => wfx.Do(x => DoThatThing(x)));

            wf.Define(createWorkgroup);
            wf.Yield(JobPosting.CreationSteps.CreateWorkgroup);

            wf.When(x => false);

            wf.Define(createPosition);
            wf.Yield(JobPosting.CreationSteps.CreatePosition);


            wf.Yield(JobPosting.CreationSteps.CreateJobPosting);
            wf.Yield(JobPosting.CreationSteps.Posted);
            return(wf);
        }
예제 #48
0
        public void it_throws_the_exception_created_by_the_user()
        {
            var ex = new UserDefinedException();
            var wf = new StatefulWorkflow<Entity>()
                .When(x => true).Fail(f => f.With(x => ex))
                .Yield("end");

            try
            {
                wf.Start(new Entity());
                Assert.Fail("an exception should have been thrown");
            }
            catch (UserDefinedException e)
            {
                Assert.That(e, Is.SameAs(ex));
            }
        }
예제 #49
0
 public BranchingExpression(StatefulWorkflow <T> workflow, Predicate <T> condition,
                            IWorkflow <T> current, StatefulBuilder <T> builder, ITransitionRule <T> transitionRule)
     : base(workflow, current, builder, transitionRule)
 {
     _condition = condition;
 }
예제 #50
0
        public void Operations_work_when_using_objects()
        {
            var wf = new StatefulWorkflow<ITest>("wf");
            wf.Yield(13);
            wf.Do((x, i) => { x.Ping((int)i["i"]); });

            var test = Mock.Of<ITest>(x => (int)x.GetStateId("wf") == 13);
            var mock = Mock.Get(test);
            wf.StartWithParams(test, new { i = 42 });
            mock.Verify(x => x.SetStateId("wf", null));
            mock.Verify(x => x.Ping((int)42));
        }
예제 #51
0
        public void SingleBranchBetweenFlowsAddsATransition_ForwardReference()
        {
            var branch1 = Declare.Step();
            var wf = new StatefulWorkflow<StatefulObject>(2, gateway.Object)
                .Yield(1)
                .When(x => true, otherwise: branch1)
                .Yield(2)
                .Define(defineAs: branch1);

            var transitions = wf.PossibleTransitions.ToList();
            transitions.Should(Have.Count.EqualTo(4));

            transitions.Where(x => x.From == null && (int?)x.To == 1).Count().ShouldBe(1);
            transitions.Where(x => (int?)x.From == 1 && (int?)x.To == 2).Count().ShouldBe(1);
            transitions.Where(x => (int?)x.From == 2 && x.To == null).Count().ShouldBe(1);
            // as well as
            transitions.Where(x => (int?)x.From == 2 && (int?)x.To == 1).Count().ShouldBe(0);
            transitions.Where(x => (int?)x.From == 1 && (int?)x.To == null).Count().ShouldBe(1);
        }
        public void I_can_have_2_branches_to_the_same_yield()
        {
            var branch1 = Declare.Step();
            var wf = new StatefulWorkflow<StatefulObject>(2, gateway.Object);
            wf.Yield(1);
            wf.When(x => true).BranchTo(branch1);
            wf.Yield(2);
            wf.When(x => true).BranchTo(branch1);
            wf.Yield(3);
            wf.Define(branch1);
            wf.Yield(4);

            var transitions = wf.PossibleTransitions.ToList();
            transitions.Where(x => (int?)x.From == 1 && (int?)x.To == 4).Count().ShouldBe(1);
            transitions.Where(x => (int?)x.From == 2 && (int?)x.To == 4).Count().ShouldBe(1);
        }
        public void SingleBranchBetweenFlowsAddsATransition()
        {
            var branch1 = Declare.Step();
            var wf = new StatefulWorkflow<StatefulObject>(2, gateway.Object)
                .Yield(1)
                .Define(branch1)
                .Yield(2)
                .When(x => true).BranchTo(branch1);

            var transitions = wf.PossibleTransitions.ToList();
            transitions.Should(Have.Count.EqualTo(4));

            transitions.Should(Have.Some.Matches<ITransition>(x => x.From == null && (int?)x.To == 1));
            transitions.Should(Have.Some.Matches<ITransition>(x => (int?)x.From == 1 && (int?)x.To == 2));
            transitions.Should(Have.Some.Matches<ITransition>(x => (int?)x.From == 2 && x.To == null));
            // as well as
            transitions.Should(Have.Some.Matches<ITransition>(x => (int?)x.From == 2 && (int?)x.To == 2));
            transitions.Should(Have.None.Matches<ITransition>(x => (int?)x.From == 2 && (int?)x.To == 1));
        }