public void When_testing_global_on_message_event()
        {
            var hub = new MessageHub();

            hub.ClearSubscriptions();

            var msgOne = 0;

            hub.RegisterGlobalHandler((type, msg) =>
            {
                type.ShouldBe(typeof(string));
                msg.ShouldBeOfType <string>();
                msgOne++;
            });

            hub.Publish("A");

            msgOne.ShouldBe(1);

            hub.ClearSubscriptions();
            hub.Publish("B");

            msgOne.ShouldBe(2);

            var msgTwo = 0;

            hub.RegisterGlobalHandler((type, msg) =>
            {
                type.ShouldBe(typeof(string));
                msg.ShouldBeOfType <string>();
                msgTwo++;
            });

            hub.RegisterGlobalHandler((type, msg) =>
            {
                type.ShouldBe(typeof(string));
                msg.ShouldBeOfType <string>();
                msgTwo++;
            });

            hub.Publish("C");

            msgTwo.ShouldBe(1);

            hub.RegisterGlobalHandler((type, msg) =>
            {
                type.ShouldBe(typeof(string));
                msg.ShouldBeOfType <string>();
                // do nothing with the message
            });

            hub.Publish("D");

            msgOne.ShouldBe(2, "No handler would increment this value");
            msgTwo.ShouldBe(1, "No handler would increment this value");
        }
        public void When_operating_on_a_disposed_hub()
        {
            var totalMessages = 0;
            var hub           = new MessageHub();

            hub.RegisterGlobalHandler((type, msg) =>
            {
                type.ShouldBe(typeof(string));
                msg.ShouldBeOfType <string>();
                Interlocked.Increment(ref totalMessages);
            });

            var queue = new ConcurrentQueue <string>();

            Action <string> handler = msg => queue.Enqueue(msg);

            var token = hub.Subscribe(handler);

            hub.Dispose();

            Should.NotThrow(() => hub.Subscribe(handler));
            Should.NotThrow(() => hub.Unsubscribe(token));
            Should.NotThrow(() => hub.IsSubscribed(token));
            Should.NotThrow(() => hub.ClearSubscriptions());

            totalMessages.ShouldBe(0);
        }
        public void When_testing_multiple_subscribers_with_filters_and_publisher_on_current_thread()
        {
            var hub = new MessageHub();

            hub.ClearSubscriptions();

            var queueOne = new List <string>();
            var queueTwo = new List <string>();

            var predicateOne = new Predicate <string>(x => x.Length > 3);
            var predicateTwo = new Predicate <string>(x => x.Length < 3);

            Action <string> subscriberOne = msg =>
            {
                if (predicateOne(msg))
                {
                    queueOne.Add("Sub1-" + msg);
                }
            };

            Action <string> subscriberTwo = msg =>
            {
                if (predicateTwo(msg))
                {
                    queueTwo.Add("Sub2-" + msg);
                }
            };

            hub.Subscribe(subscriberOne);
            hub.Subscribe(subscriberTwo);

            hub.Publish("MessageA");

            queueOne.Count.ShouldBe(1);
            queueTwo.Count.ShouldBe(0);
            queueOne[0].ShouldBe("Sub1-MessageA");

            hub.Publish("MA");

            queueTwo.Count.ShouldBe(1);
            queueOne.Count.ShouldBe(1);
            queueTwo[0].ShouldBe("Sub2-MA");

            hub.Publish("MMM");

            queueOne.Count.ShouldBe(1);
            queueTwo.Count.ShouldBe(1);

            hub.Publish("MessageB");

            queueOne.Count.ShouldBe(2);
            queueTwo.Count.ShouldBe(1);
            queueOne[1].ShouldBe("Sub1-MessageB");

            hub.Publish("MB");

            queueTwo.Count.ShouldBe(2);
            queueOne.Count.ShouldBe(2);
            queueTwo[1].ShouldBe("Sub2-MB");
        }
        public void When_testing_multiple_subscribers_with_publisher_on_current_thread()
        {
            var hub = new MessageHub();

            hub.ClearSubscriptions();

            var queueOne = new List <string>();
            var queueTwo = new List <string>();

            Action <string> subscriberOne = msg => queueOne.Add("Sub1-" + msg);
            Action <string> subscriberTwo = msg => queueTwo.Add("Sub2-" + msg);

            hub.Subscribe(subscriberOne);
            hub.Subscribe(subscriberTwo);

            hub.Publish("MessageA");

            queueOne.Count.ShouldBe(1);
            queueTwo.Count.ShouldBe(1);

            queueOne[0].ShouldBe("Sub1-MessageA");
            queueTwo[0].ShouldBe("Sub2-MessageA");

            hub.Publish("MessageB");

            queueOne.Count.ShouldBe(2);
            queueTwo.Count.ShouldBe(2);

            queueOne[1].ShouldBe("Sub1-MessageB");
            queueTwo[1].ShouldBe("Sub2-MessageB");
        }
        public void When_testing_handler_exists()
        {
            var hub = new MessageHub();

            hub.ClearSubscriptions();

            Action <string> subscriberOne = msg => { };
            var             tokenOne      = hub.Subscribe(subscriberOne);

            hub.IsSubscribed(tokenOne).ShouldBeTrue();

            Action <string> subscriberTwo = msg => { };
            var             tokenTwo      = hub.Subscribe(subscriberTwo);

            hub.IsSubscribed(tokenTwo).ShouldBeTrue();

            Action <string> subscriberThree = msg => { };
            var             tokenThree      = hub.Subscribe(subscriberThree);

            hub.IsSubscribed(tokenThree).ShouldBeTrue();

            Action <string> subscriberFour = msg => { };
            var             tokenFour      = hub.Subscribe(subscriberFour);

            hub.IsSubscribed(tokenFour).ShouldBeTrue();

            hub.Unsubscribe(tokenThree);
            hub.IsSubscribed(tokenThree).ShouldBeFalse();

            hub.Unsubscribe(tokenFour);
            hub.IsSubscribed(tokenFour).ShouldBeFalse();

            hub.IsSubscribed(tokenTwo).ShouldBeTrue();
            hub.IsSubscribed(tokenOne).ShouldBeTrue();

            hub.ClearSubscriptions();

            hub.IsSubscribed(tokenOne).ShouldBeFalse();
            hub.IsSubscribed(tokenTwo).ShouldBeFalse();
            hub.IsSubscribed(tokenThree).ShouldBeFalse();
            hub.IsSubscribed(tokenFour).ShouldBeFalse();

            // now let's add back one subscription
            tokenFour = hub.Subscribe(subscriberFour);
            hub.IsSubscribed(tokenFour).ShouldBeTrue();
        }
        public void When_testing_multiple_subscribers_with_one_subscriber_unsubscribing_then_resubscribing()
        {
            var totalMessages = 0;
            var hub           = new MessageHub();

            hub.ClearSubscriptions();

            hub.RegisterGlobalHandler((type, msg) =>
            {
                type.ShouldBe(typeof(string));
                msg.ShouldBeOfType <string>();
                Interlocked.Increment(ref totalMessages);
            });

            var queue = new List <string>();

            Action <string> subscriberOne = msg => queue.Add("Sub1-" + msg);
            Action <string> subscriberTwo = msg => queue.Add("Sub2-" + msg);

            var tokenOne = hub.Subscribe(subscriberOne);

            hub.Subscribe(subscriberTwo);

            hub.Publish("A");

            queue.Count.ShouldBe(2);
            queue[0].ShouldBe("Sub1-A");
            queue[1].ShouldBe("Sub2-A");

            hub.Unsubscribe(tokenOne);

            hub.Publish("B");

            queue.Count.ShouldBe(3);
            queue[2].ShouldBe("Sub2-B");

            hub.Subscribe(subscriberOne);

            hub.Publish("C");

            queue.Count.ShouldBe(5);
            queue[3].ShouldBe("Sub2-C");
            queue[4].ShouldBe("Sub1-C");

            Thread.Sleep(TimeSpan.FromSeconds(1));
            totalMessages.ShouldBe(3);
        }
        public void When_testing_single_subscriber_with_publisher_on_current_thread()
        {
            var hub = new MessageHub();

            hub.ClearSubscriptions();

            var queue = new List <string>();

            Action <string> subscriber = msg => queue.Add(msg);

            hub.Subscribe(subscriber);

            hub.Publish("MessageA");

            queue.Count.ShouldBe(1);
            queue[0].ShouldBe("MessageA");

            hub.Publish("MessageB");

            queue.Count.ShouldBe(2);
            queue[1].ShouldBe("MessageB");
        }