public void OnReplaceA()
        {
            //Arrange
            ObservableCollection <A>                    sourceCollectionA  = FilledCollectionA;
            ObservableCollection <B>                    sourceCollectionB  = FilledCollectionB;
            WrappingObservableReadOnlyList <A>          wrappedCollectionA = new WrappingObservableReadOnlyList <A>(sourceCollectionA);
            WrappingObservableReadOnlyList <B>          wrappedCollectionB = new WrappingObservableReadOnlyList <B>(sourceCollectionB);
            ConcatenatingObservableReadOnlyList <Super> readOnlyList       =
                new ConcatenatingObservableReadOnlyList <Super>(wrappedCollectionA, wrappedCollectionB);
            A   replacingA   = new A();
            int replaceIndex = 1;
            A   replacedA    = (A)readOnlyList[replaceIndex];

            readOnlyList.CollectionChanged += (sender, args) =>
            {
                Assert.Equal(NotifyCollectionChangedAction.Replace, args.Action);
                Assert.Equal(replaceIndex, args.OldStartingIndex);
                Assert.Equal(replaceIndex, args.NewStartingIndex);
                Assert.Same(replacingA, args.NewItems[0]);
            };

            //Act
            sourceCollectionA[replaceIndex] = replacingA;

            //Assert
            Assert.NotSame(replacedA, readOnlyList[replaceIndex]);
            StandardCheck(sourceCollectionA, sourceCollectionB, readOnlyList);
        }
        public MainWindowViewModel()
        {
            _models.Add(new Model(_i++));
            _models.Add(new Model(_i++));
            _models.Add(new Model(_i++));
            _models.Add(new Model(_i++));
            ViewModels = new TransformingObservableReadOnlyList <Model, ViewModel>(_models, model => new ViewModel(model));
            _models.Add(new Model(_i++));
            _models.Add(new Model(_i++));

            ModelsA = new ObservableCollection <ModelA>();
            ModelsB = new ObservableCollection <ModelB>();
            ModelsA.Add(new ModelA(_a++));
            ModelsA.Add(new ModelA(_a++));
            ModelsA.Add(new ModelA(_a++));
            ModelsA.Add(new ModelA(_a++));
            ModelsB.Add(new ModelB(_b++));
            ModelsB.Add(new ModelB(_b++));
            WrappingObservableReadOnlyList <ModelA> wrapA = new WrappingObservableReadOnlyList <ModelA>(ModelsA);
            WrappingObservableReadOnlyList <ModelB> wrapB = new WrappingObservableReadOnlyList <ModelB>(ModelsB);

            ModelsA.Add(new ModelA(_a++));
            ModelsB.Add(new ModelB(_b++));
            TransformingObservableReadOnlyList <ModelA, ViewModelA> transA =
                new TransformingObservableReadOnlyList <ModelA, ViewModelA>(wrapA, a => new ViewModelA(a));
            TransformingObservableReadOnlyList <ModelB, ViewModelB> transB =
                new TransformingObservableReadOnlyList <ModelB, ViewModelB>(wrapB, b => new ViewModelB(b));

            ModelsA.Add(new ModelA(_a++));
            ModelsB.Add(new ModelB(_b++));
            ViewModelsAB = new ConcatenatingObservableReadOnlyList <ViewModel>(transA, transB);
            ModelsA.Add(new ModelA(_a++));
            ModelsB.Add(new ModelB(_b++));
        }
        private static void StandardCheck(ObservableCollection <A> filledCollection,
                                          WrappingObservableReadOnlyList <A> readOnlyList)
        {
            Assert.Equal(filledCollection.Count, readOnlyList.Count);
            int index = 0;

            foreach (A a in readOnlyList)
            {
                Assert.Same(a, filledCollection[index++]);
            }
        }
        public void FilledCollection()
        {
            //Arrange
            ObservableCollection <A>           filledCollection = FilledSourceCollection;
            WrappingObservableReadOnlyList <A> readOnlyList     = new WrappingObservableReadOnlyList <A>(filledCollection);

            //Act


            //Assert
            StandardCheck(filledCollection, readOnlyList);
        }
        public void OnReset()
        {
            //Arrange
            ObservableCollection <A>           filledCollection = FilledSourceCollection;
            WrappingObservableReadOnlyList <A> readOnlyList     = new WrappingObservableReadOnlyList <A>(filledCollection);

            readOnlyList.CollectionChanged += (sender, args) =>
            {
                Assert.Equal(NotifyCollectionChangedAction.Reset, args.Action);
            };

            //Act
            filledCollection.Clear();

            //Assert
            StandardCheck(filledCollection, readOnlyList);
        }
        public void OnAddition()
        {
            //Arrange
            ObservableCollection <A>           filledCollection = FilledSourceCollection;
            WrappingObservableReadOnlyList <A> readOnlyList     = new WrappingObservableReadOnlyList <A>(filledCollection);
            A addedA = new A();

            readOnlyList.CollectionChanged += (sender, args) =>
            {
                Assert.Equal(NotifyCollectionChangedAction.Add, args.Action);
                Assert.Equal(readOnlyList.Count - 1, args.NewStartingIndex);
                Assert.Same(addedA, args.NewItems[0]);
            };

            //Act
            filledCollection.Add(addedA);

            //Assert
            StandardCheck(filledCollection, readOnlyList);
        }
        public void OnRemoveAt()
        {
            //Arrange
            ObservableCollection <A>           filledCollection = FilledSourceCollection;
            WrappingObservableReadOnlyList <A> readOnlyList     = new WrappingObservableReadOnlyList <A>(filledCollection);
            int removedIndex = 1;
            A   removedA     = filledCollection[removedIndex];

            readOnlyList.CollectionChanged += (sender, args) =>
            {
                Assert.Equal(NotifyCollectionChangedAction.Remove, args.Action);
                Assert.Equal(removedIndex, args.OldStartingIndex);
                Assert.Same(removedA, args.OldItems[0]);
            };

            //Act
            filledCollection.RemoveAt(removedIndex);

            //Assert
            StandardCheck(filledCollection, readOnlyList);
        }
        public void OnMove()
        {
            //Arrange
            ObservableCollection <A>           filledCollection = FilledSourceCollection;
            WrappingObservableReadOnlyList <A> readOnlyList     = new WrappingObservableReadOnlyList <A>(filledCollection);
            int moveFromIndex = 1;
            int moveToIndex   = 3;
            A   movedA        = filledCollection[moveFromIndex];

            readOnlyList.CollectionChanged += (sender, args) =>
            {
                Assert.Equal(NotifyCollectionChangedAction.Move, args.Action);
                Assert.Equal(moveFromIndex, args.OldStartingIndex);
                Assert.Equal(moveToIndex, args.NewStartingIndex);
                Assert.Same(movedA, args.NewItems[0]);
            };

            //Act
            filledCollection.Move(moveFromIndex, moveToIndex);

            //Assert
            StandardCheck(filledCollection, readOnlyList);
        }