public void When_pressing_next_competitor_while_others_are_entering_current_competitor_it_must_ignore()
        {
            // Arrange
            var filter = new NumberEntryFilter();
            filter.HandleModifierKeyDown(OtherRemoteControl, RemoteKeyModifier.EnterCurrentCompetitor);

            // Act
            using (var listener = new FilterEventListener(filter))
            {
                filter.HandleModifierKeyDown(ThisRemoteControl, RemoteKeyModifier.EnterNextCompetitor);

                // Assert
                listener.EventsCollected.Should().BeEmpty();
            }
        }
        public void When_pressing_current_competitor_it_must_start_number_building()
        {
            // Arrange
            var filter = new NumberEntryFilter();

            // Act
            using (var listener = new FilterEventListener(filter))
            {
                filter.HandleModifierKeyDown(ThisRemoteControl, RemoteKeyModifier.EnterCurrentCompetitor);

                // Assert
                listener.EventsCollected.Should().HaveCount(1);
                listener.EventsCollected[0].ShouldBeNotifyCompetitorSelecting(true);
            }
        }
            public void Dispose()
            {
                if (source != null)
                {
                    DetachFilterHandlers();

                    source = null;
                }
            }
            public FilterEventListener([NotNull] NumberEntryFilter source)
            {
                Guard.NotNull(source, nameof(source));

                this.source = source;

                AttachFilterHandlers();
            }
        public void When_no_time_and_no_keys_are_included_it_should_accept_command()
        {
            var filter = new NumberEntryFilter();

            using (var listener = new FilterEventListener(filter))
            {
                filter.HandleMissingKey(ThisRemoteControl, NullTime);

                listener.EventsCollected.Should().HaveCount(1);
                listener.EventsCollected[0].ShouldBeNotifyUnknownAction(ThisRemoteControl, null, NullTime);
            }
        }
            When_releasing_current_competitor_while_others_are_building_current_competitor_number_it_must_end_number_building
            ()
        {
            // Arrange
            var filter = new NumberEntryFilter();
            filter.HandleModifierKeyDown(OtherRemoteControl, RemoteKeyModifier.EnterCurrentCompetitor);
            filter.HandleKeyDown(OtherRemoteControl, RemoteKey.Key4, NullTime);
            filter.HandleModifierKeyDown(ThisRemoteControl, RemoteKeyModifier.EnterCurrentCompetitor);

            // Act
            using (var listener = new FilterEventListener(filter))
            {
                filter.HandleModifierKeyUp(ThisRemoteControl, RemoteKeyModifier.EnterCurrentCompetitor);

                // Assert
                listener.EventsCollected.Should().HaveCount(1);
                listener.EventsCollected[0].ShouldBeNotifyCompetitorSelected(true, 4);
            }
        }
        public void When_releasing_next_competitor_while_number_entry_is_no_longer_active_it_must_ignore()
        {
            // Arrange
            var filter = new NumberEntryFilter();
            filter.HandleModifierKeyDown(OtherRemoteControl, RemoteKeyModifier.EnterNextCompetitor);
            filter.HandleModifierKeyDown(ThisRemoteControl, RemoteKeyModifier.EnterNextCompetitor);
            filter.HandleModifierKeyUp(OtherRemoteControl, RemoteKeyModifier.EnterNextCompetitor);

            // Act
            using (var listener = new FilterEventListener(filter))
            {
                filter.HandleModifierKeyUp(ThisRemoteControl, RemoteKeyModifier.EnterNextCompetitor);

                // Assert
                listener.EventsCollected.Should().BeEmpty();
            }
        }
        public void When_pressing_command_only_key_while_number_building_is_active_it_must_accept_command()
        {
            // Arrange
            var filter = new NumberEntryFilter();
            filter.HandleModifierKeyDown(ThisRemoteControl, RemoteKeyModifier.EnterCurrentCompetitor);

            // Act
            using (var listener = new FilterEventListener(filter))
            {
                filter.HandleKeyDown(ThisRemoteControl, RemoteKey.PassStart, OneMinute);

                // Assert
                listener.EventsCollected.Should().HaveCount(1);
                listener.EventsCollected[0].ShouldBeNotifyUnknownAction(ThisRemoteControl, RemoteKey.PassStart,
                    OneMinute);
            }
        }
        public void When_entering_multiple_digits_a_number_must_be_cooperatively_formed()
        {
            // Arrange
            var filter = new NumberEntryFilter();
            filter.HandleModifierKeyDown(OtherRemoteControl, RemoteKeyModifier.EnterCurrentCompetitor);
            filter.HandleModifierKeyDown(ThisRemoteControl, RemoteKeyModifier.EnterCurrentCompetitor);

            // Act
            using (var listener = new FilterEventListener(filter))
            {
                filter.HandleKeyDown(ThisRemoteControl, RemoteKey.Key7, NullTime);
                filter.HandleKeyDown(OtherRemoteControl, RemoteKey.Key8OrDecreaseFaults, NullTime);
                filter.HandleKeyDown(ThisRemoteControl, RemoteKey.Key9OrIncreaseFaults, NullTime);

                // Assert
                listener.EventsCollected.Should().HaveCount(3);
                listener.EventsCollected[0].ShouldBeNotifyDigitReceived(true, 7);
                listener.EventsCollected[1].ShouldBeNotifyDigitReceived(true, 78);
                listener.EventsCollected[2].ShouldBeNotifyDigitReceived(true, 789);
            }
        }
            When_pressing_multi_functional_key_while_no_modifiers_are_down_but_others_are_entering_current_competitor_it_must_accept_command
            ()
        {
            // Arrange
            var filter = new NumberEntryFilter();
            filter.HandleModifierKeyDown(OtherRemoteControl, RemoteKeyModifier.EnterCurrentCompetitor);

            // Act
            using (var listener = new FilterEventListener(filter))
            {
                filter.HandleKeyDown(ThisRemoteControl, RemoteKey.Key2OrPassIntermediate, OneMinute);

                // Assert
                listener.EventsCollected.Should().HaveCount(1);
                listener.EventsCollected[0].ShouldBeNotifyUnknownAction(ThisRemoteControl,
                    RemoteKey.Key2OrPassIntermediate, OneMinute);
            }
        }
        public void When_pressing_multi_functional_key_while_number_building_is_not_active_it_must_accept_command()
        {
            // Arrange
            var filter = new NumberEntryFilter();

            // Act
            using (var listener = new FilterEventListener(filter))
            {
                filter.HandleKeyDown(ThisRemoteControl, RemoteKey.Key2OrPassIntermediate, OneMinute);

                // Assert
                listener.EventsCollected.Should().HaveCount(1);
                listener.EventsCollected[0].ShouldBeNotifyUnknownAction(ThisRemoteControl,
                    RemoteKey.Key2OrPassIntermediate, OneMinute);
            }
        }
        public void When_pressing_multi_functional_key_while_compatible_with_number_entry_of_others_it_must_accept_digit
            ()
        {
            // Arrange
            var filter = new NumberEntryFilter();
            filter.HandleModifierKeyDown(OtherRemoteControl, RemoteKeyModifier.EnterCurrentCompetitor);
            filter.HandleModifierKeyDown(ThisRemoteControl, RemoteKeyModifier.EnterNextCompetitor);
            filter.HandleModifierKeyDown(ThisRemoteControl, RemoteKeyModifier.EnterCurrentCompetitor);

            // Act
            using (var listener = new FilterEventListener(filter))
            {
                filter.HandleKeyDown(ThisRemoteControl, RemoteKey.Key7, NullTime);

                // Assert
                listener.EventsCollected.Should().HaveCount(1);
                listener.EventsCollected[0].ShouldBeNotifyDigitReceived(true, 7);
            }
        }
        public void When_pressing_multi_functional_key_while_others_are_building_a_different_number_it_must_ignore()
        {
            // Arrange
            var filter = new NumberEntryFilter();
            filter.HandleModifierKeyDown(OtherRemoteControl, RemoteKeyModifier.EnterCurrentCompetitor);
            filter.HandleModifierKeyDown(ThisRemoteControl, RemoteKeyModifier.EnterNextCompetitor);

            // Act
            using (var listener = new FilterEventListener(filter))
            {
                filter.HandleKeyDown(ThisRemoteControl, RemoteKey.Key2OrPassIntermediate, OneMinute);

                // Assert
                listener.EventsCollected.Should().BeEmpty();
            }
        }
        public void When_pressing_multi_functional_key_while_number_building_is_active_it_must_accept_digit()
        {
            // Arrange
            var filter = new NumberEntryFilter();
            filter.HandleModifierKeyDown(ThisRemoteControl, RemoteKeyModifier.EnterCurrentCompetitor);

            // Act
            using (var listener = new FilterEventListener(filter))
            {
                filter.HandleKeyDown(ThisRemoteControl, RemoteKey.Key2OrPassIntermediate, OneMinute);

                // Assert
                listener.EventsCollected.Should().HaveCount(1);
                listener.EventsCollected[0].ShouldBeNotifyDigitReceived(true, 2);
            }
        }
        public void When_pressing_command_only_key_while_others_are_building_a_number_it_must_accept_command()
        {
            // Arrange
            var filter = new NumberEntryFilter();
            filter.HandleModifierKeyDown(OtherRemoteControl, RemoteKeyModifier.EnterNextCompetitor);

            // Act
            using (var listener = new FilterEventListener(filter))
            {
                filter.HandleKeyDown(ThisRemoteControl, RemoteKey.ResetRun, NullTime);

                // Assert
                listener.EventsCollected.Should().HaveCount(1);
                listener.EventsCollected[0].ShouldBeNotifyUnknownAction(ThisRemoteControl, RemoteKey.ResetRun, NullTime);
            }
        }
        public void When_entering_more_than_four_digits_the_additional_digits_must_be_ignored()
        {
            // Arrange
            var filter = new NumberEntryFilter();
            filter.HandleModifierKeyDown(ThisRemoteControl, RemoteKeyModifier.EnterCurrentCompetitor);
            filter.HandleKeyDown(ThisRemoteControl, RemoteKey.Key1OrPlaySoundA, NullTime);
            filter.HandleKeyDown(ThisRemoteControl, RemoteKey.Key2OrPassIntermediate, NullTime);
            filter.HandleKeyDown(ThisRemoteControl, RemoteKey.Key3OrToggleElimination, NullTime);
            filter.HandleKeyDown(ThisRemoteControl, RemoteKey.Key4, NullTime);

            // Act
            using (var listener = new FilterEventListener(filter))
            {
                filter.HandleKeyDown(ThisRemoteControl, RemoteKey.Key0OrMuteSound, NullTime);

                // Assert
                listener.EventsCollected.Should().BeEmpty();
            }
        }
        public void When_pressing_next_competitor_while_others_are_entering_next_competitor_it_must_join_number_building
            ()
        {
            // Arrange
            var filter = new NumberEntryFilter();
            filter.HandleModifierKeyDown(OtherRemoteControl, RemoteKeyModifier.EnterNextCompetitor);
            filter.HandleModifierKeyDown(ThisRemoteControl, RemoteKeyModifier.EnterNextCompetitor);

            // Act
            using (var listener = new FilterEventListener(filter))
            {
                filter.HandleKeyDown(ThisRemoteControl, RemoteKey.Key7, NullTime);

                // Assert
                listener.EventsCollected.Should().HaveCount(1);
                listener.EventsCollected[0].ShouldBeNotifyDigitReceived(false, 7);
            }
        }
        public void When_pressing_digit_only_key_while_number_building_is_not_active_it_must_ignore()
        {
            // Arrange
            var filter = new NumberEntryFilter();

            // Act
            using (var listener = new FilterEventListener(filter))
            {
                filter.HandleKeyDown(ThisRemoteControl, RemoteKey.Key4, NullTime);

                // Assert
                listener.EventsCollected.Should().BeEmpty();
            }
        }