public void ThrowsError_WhenCircularDependency()
        {
            var registry = new CommandBindRegistry();
            var bkf      = new BoundKeyFunction("test");

            var aHandler1 = new TestInputCmdHandler();
            var aHandler2 = new TestInputCmdHandler();
            var bHandler1 = new TestInputCmdHandler();
            var bHandler2 = new TestInputCmdHandler();
            var cHandler1 = new TestInputCmdHandler();
            var cHandler2 = new TestInputCmdHandler();

            CommandBinds.Builder
            .Bind(bkf, aHandler1)
            .BindAfter(bkf, aHandler2, typeof(TypeB), typeof(TypeC))
            .Register <TypeA>(registry);
            CommandBinds.Builder
            .Bind(bkf, bHandler1)
            .Bind(bkf, bHandler2)
            .Register <TypeB>(registry);

            Assert.Throws <InvalidOperationException>(() =>
                                                      CommandBinds.Builder
                                                      .Bind(bkf, cHandler1)
                                                      .BindAfter(bkf, cHandler2, typeof(TypeA))
                                                      .Register <TypeC>(registry));
        }
        public void ResolvesHandlers_WithDependency(bool before, bool after)
        {
            var registry = new CommandBindRegistry();
            var bkf      = new BoundKeyFunction("test");

            var aHandler1 = new TestInputCmdHandler( );
            var aHandler2 = new TestInputCmdHandler();
            var bHandler1 = new TestInputCmdHandler();
            var bHandler2 = new TestInputCmdHandler();
            var cHandler1 = new TestInputCmdHandler();
            var cHandler2 = new TestInputCmdHandler();

            // a handler 2 should run after both b and c handlers for all the below cases
            if (before && after)
            {
                CommandBinds.Builder
                .Bind(bkf, aHandler1)
                .BindAfter(bkf, aHandler2, typeof(TypeB), typeof(TypeC))
                .Register <TypeA>(registry);
                CommandBinds.Builder
                .BindBefore(bkf, bHandler1, typeof(TypeA))
                .BindBefore(bkf, bHandler2, typeof(TypeA))
                .Register <TypeB>(registry);
                CommandBinds.Builder
                .BindBefore(bkf, cHandler1, typeof(TypeA))
                .BindBefore(bkf, cHandler2, typeof(TypeA))
                .Register <TypeC>(registry);
            }
            else if (before)
            {
                CommandBinds.Builder
                .Bind(bkf, aHandler1)
                .Bind(bkf, aHandler2)
                .Register <TypeA>(registry);
                CommandBinds.Builder
                .BindBefore(bkf, bHandler1, typeof(TypeA))
                .BindBefore(bkf, bHandler2, typeof(TypeA))
                .Register <TypeB>(registry);
                CommandBinds.Builder
                .BindBefore(bkf, cHandler1, typeof(TypeA))
                .BindBefore(bkf, cHandler2, typeof(TypeA))
                .Register <TypeC>(registry);
            }
            else if (after)
            {
                CommandBinds.Builder
                .Bind(bkf, aHandler1)
                .BindAfter(bkf, aHandler2, typeof(TypeB), typeof(TypeC))
                .Register <TypeA>(registry);
                CommandBinds.Builder
                .Bind(bkf, bHandler1)
                .Bind(bkf, bHandler2)
                .Register <TypeB>(registry);
                CommandBinds.Builder
                .Bind(bkf, cHandler1)
                .Bind(bkf, cHandler2)
                .Register <TypeC>(registry);
            }


            var returnedHandlers = registry.GetHandlers(bkf);

            // b1 , b2, c1, c2 should be fired before a2
            bool foundB1 = false, foundB2 = false, foundC1 = false, foundC2 = false;

            foreach (var returnedHandler in returnedHandlers)
            {
                if (returnedHandler == bHandler1)
                {
                    foundB1 = true;
                }
                else if (returnedHandler == bHandler2)
                {
                    foundB2 = true;
                }
                else if (returnedHandler == cHandler1)
                {
                    foundC1 = true;
                }
                else if (returnedHandler == cHandler2)
                {
                    foundC2 = true;
                }
                else if (returnedHandler == aHandler2)
                {
                    Assert.True(foundB1 && foundB2 && foundC1 && foundC2, "bind registry didn't respect" +
                                " handler dependency order");
                }
            }

            var expectedHandlers =
                new [] { aHandler1, aHandler2, bHandler1, bHandler2, cHandler1, cHandler2 };
            var returnedHandlerSet = new HashSet <InputCmdHandler>(returnedHandlers);

            foreach (var expectedHandler in expectedHandlers)
            {
                Assert.True(returnedHandlerSet.Contains(expectedHandler));
            }
        }