public void IsTrackingResetsReturnsCorrectValue()
        {
            // given
            using (var observableDictionary = new ObservableDictionary<int, string>())
            {
                // when
                using (observableDictionary.SuppressResetNotifications())
                {
                    observableDictionary.IsTrackingResets.Should().BeFalse();
                }

                observableDictionary.IsTrackingResets.Should().BeTrue();
            }
        }
        public void SuppressResetNotificationsSuppressesResetNotifications()
        {
            // given
            var scheduler = new TestScheduler();
            var observer = scheduler.CreateObserver<IObservableDictionaryChange<int, string>>();
            var resetsObserver = scheduler.CreateObserver<Unit>();

            using (var observableDictionary = new ObservableDictionary<int, string>(scheduler: scheduler))
            {
                // when
                observableDictionary.ThresholdAmountWhenChangesAreNotifiedAsReset = int.MaxValue;

                IDisposable dictionaryChangesSubscription = null;
                IDisposable resetsSubscription = null;

                try
                {
                    dictionaryChangesSubscription = observableDictionary.DictionaryChanges.Subscribe(observer);
                    resetsSubscription = observableDictionary.Resets.Subscribe(resetsObserver);

                    using (observableDictionary.SuppressResetNotifications(false))
                    {
                        observableDictionary.Reset();

                        scheduler.AdvanceBy(2);
                    }

                    scheduler.AdvanceBy(2);

                    // then
                    observer.Messages.Should().BeEmpty();
                    resetsObserver.Messages.Should().BeEmpty();
                }
                finally
                {
                    dictionaryChangesSubscription?.Dispose();
                    resetsSubscription?.Dispose();
                }
            }
        }
        public void SuppressResetNotificationsPreventsMultipleSuppressions()
        {
            // given
            using (var observableDictionary = new ObservableDictionary<int, string>())
            {
                // when
                using (observableDictionary.SuppressResetNotifications())
                {
                    Action action = () => { var secondSuppression = observableDictionary.SuppressResetNotifications(); };

                    action
                        .ShouldThrow<InvalidOperationException>()
                        .WithMessage("A Reset(s) Notification Suppression is currently already ongoing, multiple concurrent suppressions are not supported.");
                }
            }
        }
        public void SuppressResetNotificationsShouldThrowObjectDisposedExceptionAfterDictionaryDisposal()
        {
            // given
            var observableDictionary = new ObservableDictionary<int, string>();
            observableDictionary.Dispose();

            // when
            Action action = () => { var suppression = observableDictionary.SuppressResetNotifications(); };

            action
                .ShouldThrow<ObjectDisposedException>()
                .WithMessage($"Cannot access a disposed object.\r\nObject name: '{observableDictionary.GetType().Name}'.");
        }
        public void SuppressResetNotificationsNotifiesResetWhenSuppressionIsDisposedIfRequested()
        {
            // given
            var scheduler = new TestScheduler();
            var observer = scheduler.CreateObserver<IObservableDictionaryChange<int, string>>();
            var resetsObserver = scheduler.CreateObserver<Unit>();

            using (var observableDictionary = new ObservableDictionary<int, string>(scheduler: scheduler))
            {
                // when
                observableDictionary.ThresholdAmountWhenChangesAreNotifiedAsReset = int.MaxValue;

                IDisposable dictionaryChangesSubscription = null;
                IDisposable resetsSubscription = null;

                try
                {
                    dictionaryChangesSubscription = observableDictionary.DictionaryChanges.Subscribe(observer);
                    resetsSubscription = observableDictionary.Resets.Subscribe(resetsObserver);

                    using (observableDictionary.SuppressResetNotifications(true))
                    {
                        observableDictionary.Reset();
                        observableDictionary.Reset();
                        observableDictionary.Reset();

                        scheduler.AdvanceBy(6);
                    }

                    scheduler.AdvanceBy(2);

                    // then
                    resetsObserver.Messages.Count.Should().Be(1);
                    observer.Messages.Count.Should().Be(1);

                    observer.Messages.First().Value.Value.ChangeType.Should().Be(ObservableDictionaryChangeType.Reset);
                    observer.Messages.First().Value.Value.Key.Should().Be(default(int));
                    observer.Messages.First().Value.Value.Value.Should().Be(default(string));
                    observer.Messages.First().Value.Value.OldValue.Should().Be(default(string));
                    observer.Messages.First().Value.Value.ChangedPropertyName.Should().BeEmpty();
                }
                finally
                {
                    dictionaryChangesSubscription?.Dispose();
                    resetsSubscription?.Dispose();
                }
            }
        }