public void VisitSendPipeline()
        {
            var sut = new SendPipelineImpl();

            // workaround Moq's inability to verify that calls have proceeded in a prescribed order. following recursive
            // setups simply ensure the calls are made in a specific order; as first call is matched we setup the second
            // call in the first call's callback, then when second call is matched we setup the third call in the second
            // call's callback, and so on and on... until we have setup all the expected calls. notice that for this
            // workaround to work the Mock's behavior must be *MockBehavior.Strict* or else any call missed would be
            // unnoticed (and all its consecutive calls as well since they would not have been setup via its callback).
            var visitor = new Mock <IPipelineVisitor>(MockBehavior.Strict);

            // ReSharper disable ImplicitlyCapturedClosure
            visitor.Setup(v => v.VisitPipeline(sut))
            // ReSharper restore ImplicitlyCapturedClosure
            .Callback(
                () => visitor.Setup(v => v.VisitStage(sut.Stages.PreAssemble))
                .Callback(
                    () => visitor.Setup(v => v.VisitStage(sut.Stages.Assemble))
                    .Callback(
                        () => visitor.Setup(v => v.VisitStage(sut.Stages.Encode))
                        )
                    )
                );

            ((IVisitable <IPipelineVisitor>)sut).Accept(visitor.Object);

            visitor.Verify();
        }
        public void WalkVisitorAccordingToPrescribedPathForSendPipeline()
        {
            var sut = new SendPipelineImpl();

            var visitor  = new Mock <IPipelineVisitor>(MockBehavior.Strict);
            var sequence = new MockSequence();

            visitor.InSequence(sequence).Setup(v => v.VisitPipeline(sut));
            visitor.InSequence(sequence).Setup(v => v.VisitStage(sut.Stages.PreAssemble));
            visitor.InSequence(sequence).Setup(v => v.VisitStage(sut.Stages.Assemble));
            visitor.InSequence(sequence).Setup(v => v.VisitStage(sut.Stages.Encode));

            ((IVisitable <IPipelineVisitor>)sut).Accept(visitor.Object);

            visitor.Verify();
        }