public void ClearSource_ShoudClear()
        {
            NotifyCollectionChangedEventArgs collectionChangedEventArgs = null;
            var collectionChangedEventsCount      = 0;
            var isCountPropertyChangedEventRaised = false;
            var aItemsList = new[] { 1, 2, 3 };
            var bItemsList = new[] { 2, 4, 6 };
            var groups     = new List <IGrouping <string, int> >
            {
                new IntGroup("A", aItemsList),
                new IntGroup("B", bItemsList),
            };
            var source        = new ObservableGroupedCollection <string, int>(groups);
            var readOnlyGroup = new ReadOnlyObservableGroupedCollection <string, int>(source);

            ((INotifyCollectionChanged)readOnlyGroup).CollectionChanged += (s, e) =>
            {
                collectionChangedEventArgs = e;
                collectionChangedEventsCount++;
            };
            ((INotifyPropertyChanged)readOnlyGroup).PropertyChanged += (s, e) => isCountPropertyChangedEventRaised = isCountPropertyChangedEventRaised || e.PropertyName == nameof(readOnlyGroup.Count);

            source.Clear();

            readOnlyGroup.Should().BeEmpty();
            readOnlyGroup.Count.Should().Be(0);

            isCountPropertyChangedEventRaised.Should().BeTrue();
            collectionChangedEventArgs.Should().NotBeNull();
            collectionChangedEventsCount.Should().Be(1);
            IsResetEventValid(collectionChangedEventArgs).Should().BeTrue();
        }
        public void InsertGroupInSource_ShouldAddGroup(int insertionIndex)
        {
            NotifyCollectionChangedEventArgs collectionChangedEventArgs = null;
            var collectionChangedEventsCount      = 0;
            var isCountPropertyChangedEventRaised = false;
            var itemsList = new[] { 1, 2, 3 };
            var source    = new ObservableGroupedCollection <string, int>
            {
                new ObservableGroup <string, int>("Group0", new[] { 10, 20, 30 }),
                new ObservableGroup <string, int>("Group1", new[] { 40, 50, 60 })
            };
            var readOnlyGroup = new ReadOnlyObservableGroupedCollection <string, int>(source);

            ((INotifyCollectionChanged)readOnlyGroup).CollectionChanged += (s, e) =>
            {
                collectionChangedEventArgs = e;
                collectionChangedEventsCount++;
            };
            ((INotifyPropertyChanged)readOnlyGroup).PropertyChanged += (s, e) => isCountPropertyChangedEventRaised = isCountPropertyChangedEventRaised || e.PropertyName == nameof(readOnlyGroup.Count);

            source.Insert(insertionIndex, new ObservableGroup <string, int>("Add", itemsList));

            readOnlyGroup.Should().HaveCount(3);
            readOnlyGroup.Count.Should().Be(3);
            readOnlyGroup.ElementAt(insertionIndex).Key.Should().Be("Add");
            readOnlyGroup.ElementAt(insertionIndex).Should().BeEquivalentTo(itemsList, o => o.WithoutStrictOrdering());

            isCountPropertyChangedEventRaised.Should().BeTrue();
            collectionChangedEventArgs.Should().NotBeNull();
            collectionChangedEventsCount.Should().Be(1);
            IsAddEventValid(collectionChangedEventArgs, itemsList, addIndex: insertionIndex).Should().BeTrue();
        }
        public void RemoveGroupInSource_ShoudRemoveGroup()
        {
            NotifyCollectionChangedEventArgs collectionChangedEventArgs = null;
            var collectionChangedEventsCount      = 0;
            var isCountPropertyChangedEventRaised = false;
            var aItemsList = new[] { 1, 2, 3 };
            var bItemsList = new[] { 2, 4, 6 };
            var groups     = new List <IGrouping <string, int> >
            {
                new IntGroup("A", aItemsList),
                new IntGroup("B", bItemsList),
            };
            var source        = new ObservableGroupedCollection <string, int>(groups);
            var readOnlyGroup = new ReadOnlyObservableGroupedCollection <string, int>(source);

            ((INotifyCollectionChanged)readOnlyGroup).CollectionChanged += (s, e) =>
            {
                collectionChangedEventArgs = e;
                collectionChangedEventsCount++;
            };
            ((INotifyPropertyChanged)readOnlyGroup).PropertyChanged += (s, e) => isCountPropertyChangedEventRaised = isCountPropertyChangedEventRaised || e.PropertyName == nameof(readOnlyGroup.Count);

            source.RemoveAt(1);

            readOnlyGroup.Should().ContainSingle();
            readOnlyGroup.Count.Should().Be(1);
            readOnlyGroup.ElementAt(0).Key.Should().Be("A");
            readOnlyGroup.ElementAt(0).Should().BeEquivalentTo(aItemsList, o => o.WithoutStrictOrdering());

            isCountPropertyChangedEventRaised.Should().BeTrue();
            collectionChangedEventArgs.Should().NotBeNull();
            collectionChangedEventsCount.Should().Be(1);
            IsRemoveEventValid(collectionChangedEventArgs, bItemsList, 1).Should().BeTrue();
        }
        public void AddGroupInSource_ShouldAddGroup(int sourceInitialItemsCount, int expectedInsertionIndex)
        {
            NotifyCollectionChangedEventArgs collectionChangedEventArgs = null;
            var collectionChangedEventsCount      = 0;
            var isCountPropertyChangedEventRaised = false;
            var itemsList = new[] { 1, 2, 3 };
            var source    = new ObservableGroupedCollection <string, int>();

            for (var i = 0; i < sourceInitialItemsCount; i++)
            {
                source.Add(new ObservableGroup <string, int>($"group {i}", Enumerable.Empty <int>()));
            }

            var readOnlyGroup = new ReadOnlyObservableGroupedCollection <string, int>(source);

            ((INotifyCollectionChanged)readOnlyGroup).CollectionChanged += (s, e) =>
            {
                collectionChangedEventArgs = e;
                collectionChangedEventsCount++;
            };
            ((INotifyPropertyChanged)readOnlyGroup).PropertyChanged += (s, e) => isCountPropertyChangedEventRaised = isCountPropertyChangedEventRaised || e.PropertyName == nameof(readOnlyGroup.Count);

            source.Add(new ObservableGroup <string, int>("Add", itemsList));

            var expectedReadOnlyGroupCount = sourceInitialItemsCount + 1;

            readOnlyGroup.Should().HaveCount(expectedReadOnlyGroupCount);
            readOnlyGroup.Count.Should().Be(expectedReadOnlyGroupCount);
            readOnlyGroup.Last().Key.Should().Be("Add");
            readOnlyGroup.Last().Should().BeEquivalentTo(itemsList, o => o.WithoutStrictOrdering());

            isCountPropertyChangedEventRaised.Should().BeTrue();
            collectionChangedEventArgs.Should().NotBeNull();
            collectionChangedEventsCount.Should().Be(1);
            IsAddEventValid(collectionChangedEventArgs, itemsList, expectedInsertionIndex).Should().BeTrue();
        }