public void Clear()
        {
            List <char> initial = new List <char> ();

            initial.Add('A');
            initial.Add('B');
            initial.Add('C');

            ObservableCollection <char> collection = new ObservableCollection <char> (initial);
            bool          propertyChanged          = false;
            List <string> changedProps             = new List <string> ();
            NotifyCollectionChangedEventArgs args  = null;

            ((INotifyPropertyChanged)collection).PropertyChanged += delegate(object sender, PropertyChangedEventArgs e) {
                propertyChanged = true;
                changedProps.Add(e.PropertyName);
            };

            collection.CollectionChanged += delegate(object sender, NotifyCollectionChangedEventArgs e) {
                args = e;
            };

            collection.Clear();

            Assert.IsTrue(propertyChanged, "CLEAR_1");
            Assert.IsTrue(changedProps.Contains("Count"), "CLEAR_2");
            Assert.IsTrue(changedProps.Contains("Item[]"), "CLEAR_3");

            CollectionChangedEventValidators.ValidateResetOperation(args, "CLEAR_4");
        }
        public void Add()
        {
            ObservableCollection <char> collection = new ObservableCollection <char> ();
            bool          propertyChanged          = false;
            List <string> changedProps             = new List <string> ();
            NotifyCollectionChangedEventArgs args  = null;

            ((INotifyPropertyChanged)collection).PropertyChanged += delegate(object sender, PropertyChangedEventArgs e)
            {
                propertyChanged = true;
                changedProps.Add(e.PropertyName);
            };

            collection.CollectionChanged += delegate(object sender, NotifyCollectionChangedEventArgs e)
            {
                args = e;
            };

            collection.Add('A');

            Assert.IsTrue(propertyChanged, "ADD_1");
            Assert.IsTrue(changedProps.Contains("Count"), "ADD_2");
            Assert.IsTrue(changedProps.Contains("Item[]"), "ADD_3");

            CollectionChangedEventValidators.ValidateAddOperation(args, new char [] { 'A' }, 0, "ADD_4");
        }
Example #3
0
        public void Set()
        {
            var collection      = new ObservableCollection <char>();
            var propertyChanged = false;
            var changedProps    = new List <string>();
            NotifyCollectionChangedEventArgs args = null;

            collection.Add('A');
            collection.Add('B');
            collection.Add('C');

            ((INotifyPropertyChanged)collection).PropertyChanged += (sender, e) =>
            {
                No.Op(sender);
                propertyChanged = true;
                changedProps.Add(e.PropertyName);
            };

            collection.CollectionChanged += (sender, e) =>
            {
                No.Op(sender);
                args = e;
            };

            collection[2] = 'I';

            Assert.IsTrue(propertyChanged, "SET_1");
            Assert.IsTrue(changedProps.Contains("Item[]"), "SET_2");

            CollectionChangedEventValidators.ValidateReplaceOperation(args, new[] { 'C' }, new[] { 'I' }, 2, "SET_3");
        }
Example #4
0
        public void Add()
        {
            var collection      = new ObservableCollection <char>();
            var propertyChanged = false;
            var changedProps    = new List <string>();
            NotifyCollectionChangedEventArgs args = null;

            ((INotifyPropertyChanged)collection).PropertyChanged += (sender, e) =>
            {
                No.Op(sender);
                propertyChanged = true;
                changedProps.Add(e.PropertyName);
            };

            collection.CollectionChanged += (sender, e) =>
            {
                No.Op(sender);
                args = e;
            };

            collection.Add('A');

            Assert.IsTrue(propertyChanged, "ADD_1");
            Assert.IsTrue(changedProps.Contains("Count"), "ADD_2");
            Assert.IsTrue(changedProps.Contains("Item[]"), "ADD_3");

            CollectionChangedEventValidators.ValidateAddOperation(args, new[] { 'A' }, 0, "ADD_4");
        }
        public void Set()
        {
            ObservableCollection <char> collection = new ObservableCollection <char> ();
            bool          propertyChanged          = false;
            List <string> changedProps             = new List <string> ();
            NotifyCollectionChangedEventArgs args  = null;

            collection.Add('A');
            collection.Add('B');
            collection.Add('C');

            ((INotifyPropertyChanged)collection).PropertyChanged += delegate(object sender, PropertyChangedEventArgs e) {
                propertyChanged = true;
                changedProps.Add(e.PropertyName);
            };

            collection.CollectionChanged += delegate(object sender, NotifyCollectionChangedEventArgs e) {
                args = e;
            };

            collection [2] = 'I';

            Assert.IsTrue(propertyChanged, "SET_1");
            Assert.IsTrue(changedProps.Contains("Item[]"), "SET_2");

            CollectionChangedEventValidators.ValidateReplaceOperation(args, new char [] { 'C' }, new char [] { 'I' }, 2, "SET_3");
        }
Example #6
0
        public void ObservableCollection_Remove()
        {
            var collection      = new ObservableCollection <char>();
            var propertyChanged = false;
            var changedProps    = new List <string>();
            NotifyCollectionChangedEventArgs args = null;

            collection.Add('A');
            collection.Add('B');
            collection.Add('C');

            ((INotifyPropertyChanged)collection).PropertyChanged += (object sender, PropertyChangedEventArgs e) =>
            {
                GC.KeepAlive(sender);
                propertyChanged = true;
                changedProps.Add(e.PropertyName);
            };

            collection.CollectionChanged += (object sender, NotifyCollectionChangedEventArgs e) =>
            {
                GC.KeepAlive(sender);
                args = e;
            };

            collection.Remove('B');

            Assert.IsTrue(propertyChanged, "REM_1");
            Assert.IsTrue(changedProps.Contains("Count"), "REM_2");
            Assert.IsTrue(changedProps.Contains("Item[]"), "REM_3");

            CollectionChangedEventValidators.ValidateRemoveOperation(args, new char[] { 'B' }, 1, "REM_4");
        }
Example #7
0
        public void ObservableCollection_Clear()
        {
            var initial = new List <char>
            {
                'A',
                'B',
                'C'
            };

            var collection      = new ObservableCollection <char>(initial);
            var propertyChanged = false;
            var changedProps    = new List <string>();
            NotifyCollectionChangedEventArgs args = null;

            ((INotifyPropertyChanged)collection).PropertyChanged += (object sender, PropertyChangedEventArgs e) =>
            {
                GC.KeepAlive(sender);
                propertyChanged = true;
                changedProps.Add(e.PropertyName);
            };

            collection.CollectionChanged += (object sender, NotifyCollectionChangedEventArgs e) =>
            {
                GC.KeepAlive(sender);
                args = e;
            };

            collection.Clear();

            Assert.IsTrue(propertyChanged, "CLEAR_1");
            Assert.IsTrue(changedProps.Contains("Count"), "CLEAR_2");
            Assert.IsTrue(changedProps.Contains("Item[]"), "CLEAR_3");

            CollectionChangedEventValidators.ValidateResetOperation(args, "CLEAR_4");
        }
        public void NotifyCollectionChangedEventArgsConstructor1Test()
        {
            /* Expected Behavior:
             *
             * If action is Reset, success.
             * If action is not Reset, throw an ArgumentException
             */

            // Trying with Reset
            var args = new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset);

            CollectionChangedEventValidators.ValidateResetOperation(args, "#A01");

            // Trying with Add
            try
            {
                GC.KeepAlive(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add));
                Assert.Fail("Should not be able to call .ctor with NotifyCollectionChangedAction.Add.");
            }
            catch (ArgumentException ex)
            {
                No.Op(ex);
            }

            // Trying with Remove
            try
            {
                GC.KeepAlive(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove));
                Assert.Fail("Should not be able to call .ctor with NotifyCollectionChangedAction.Remove.");
            }
            catch (ArgumentException ex)
            {
                No.Op(ex);
            }

            // Trying with Move
            try
            {
                GC.KeepAlive(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Move));
                Assert.Fail("Should not be able to call .ctor with NotifyCollectionChangedAction.Move.");
            }
            catch (ArgumentException ex)
            {
                No.Op(ex);
            }

            // Trying with Replace
            try
            {
                GC.KeepAlive(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace));
                Assert.Fail("Should not be able to call .ctor with NotifyCollectionChangedAction.Replace.");
            }
            catch (ArgumentException ex)
            {
                No.Op(ex);
            }
        }
Example #9
0
            internal void DoubleEnterReentrant()
            {
                var object1 = BlockReentrancy();
                var object2 = BlockReentrancy();

                Assert.AreSame(object1, object2);

                //With double block, try the reentrant:
                NotifyCollectionChangedEventArgs args = null;

                CollectionChanged += (object sender, NotifyCollectionChangedEventArgs e) =>
                {
                    GC.KeepAlive(sender);
                    args = e;
                };

                // We need a second callback for reentrancy to matter
                CollectionChanged += (object sender, NotifyCollectionChangedEventArgs e) =>
                {
                    GC.KeepAlive(sender);
                    GC.KeepAlive(e);
                    // Doesn't need to do anything; just needs more than one callback registered.
                };

                // Try adding - this should cause reentrancy, and fail
                try
                {
                    Add('I');
                    Assert.Fail("Reentrancy should not be allowed. -- #2");
                }
                catch (InvalidOperationException ex)
                {
                    GC.KeepAlive(ex);
                }

                // Release the first reentrant
                object1.Dispose();

                // Try adding again - this should cause reentrancy, and fail again
                try
                {
                    Add('J');
                    Assert.Fail("Reentrancy should not be allowed. -- #3");
                }
                catch (InvalidOperationException ex)
                {
                    GC.KeepAlive(ex);
                }

                // Release the reentrant a second time
                object1.Dispose();

                // This last add should work fine.
                Add('K');
                CollectionChangedEventValidators.ValidateAddOperation(args, new char[] { 'K' }, 0, "REENTHELP_1");
            }
Example #10
0
        public void ClassTest()
        {
            // Because the collection cannot change, check to make sure exceptions are thrown for modifications.

            List <char> initial = new List <char> ();

            initial.Add('A');
            initial.Add('B');
            initial.Add('C');

            ObservableCollection <char>         collection         = new ObservableCollection <char> (initial);
            ReadOnlyObservableCollection <char> readOnlyCollection = new ReadOnlyObservableCollection <char> (collection);

            // Test the events

            PropertyChangedEventHandler pceh = delegate(object sender, PropertyChangedEventArgs e) {
                Assert.Fail("No properties should change.");
            };

            NotifyCollectionChangedEventHandler ncceh = delegate(object sender, NotifyCollectionChangedEventArgs e) {
                Assert.Fail("The collection should not change.");
            };

            ((INotifyPropertyChanged)readOnlyCollection).PropertyChanged += pceh;

            ((INotifyCollectionChanged)readOnlyCollection).CollectionChanged += ncceh;

            // Done with the events.
            ((INotifyPropertyChanged)readOnlyCollection).PropertyChanged -= pceh;

            ((INotifyCollectionChanged)readOnlyCollection).CollectionChanged -= ncceh;

            Assert.AreEqual(3, readOnlyCollection.Count, "RO_1");
            CollectionChangedEventValidators.AssertEquivalentLists(initial, readOnlyCollection, "RO_2");

            // Modifying the underlying collection

            bool propChanged = false;

            pceh = delegate(object sender, PropertyChangedEventArgs e) {
                propChanged = true;
            };

            ncceh = delegate(object sender, NotifyCollectionChangedEventArgs e) {
                CollectionChangedEventValidators.ValidateAddOperation(e, new char [] { 'I' }, 3, "RO_3");
            };

            ((INotifyPropertyChanged)readOnlyCollection).PropertyChanged += pceh;

            ((INotifyCollectionChanged)readOnlyCollection).CollectionChanged += ncceh;

            // In theory, this will cause the properties to change.
            collection.Add('I');

            Assert.IsTrue(propChanged, "RO_4");
        }
        public void NotifyCollectionChangedEventArgsConstructor11Test()
        {
            var       newItem    = new object();
            var       oldItem    = new object();
            const int startIndex = 5;

            // Trying with Replace
            var args = new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace, newItem, oldItem, startIndex);

            CollectionChangedEventValidators.ValidateReplaceOperation(args, new[] { oldItem }, new[] { newItem }, startIndex, "#K01");

            // Trying with Reset
            try
            {
                GC.KeepAlive(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset, newItem, oldItem, startIndex));
                Assert.Fail("Should not be able to call .ctor with NotifyCollectionChangedAction.Reset.");
            }
            catch (ArgumentException ex)
            {
                No.Op(ex);
            }

            // Trying with Move
            try
            {
                GC.KeepAlive(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Move, newItem, oldItem, startIndex));
                Assert.Fail("Should not be able to call .ctor with NotifyCollectionChangedAction.Move.");
            }
            catch (ArgumentException ex)
            {
                GC.KeepAlive(ex);
            }

            // Trying with Add
            try
            {
                GC.KeepAlive(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, newItem, oldItem, startIndex));
                Assert.Fail("Should not be able to call .ctor with NotifyCollectionChangedAction.Add.");
            }
            catch (ArgumentException ex)
            {
                No.Op(ex);
            }

            // Trying with Remove
            try
            {
                GC.KeepAlive(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, newItem, oldItem));
                Assert.Fail("Should not be able to call .ctor with NotifyCollectionChangedAction.Remove.");
            }
            catch (ArgumentException ex)
            {
                No.Op(ex);
            }
        }
Example #12
0
        public void ObservableCollection_Reentrant()
        {
            var collection      = new ObservableCollection <char>();
            var propertyChanged = false;
            var changedProps    = new List <string>();
            NotifyCollectionChangedEventArgs args = null;

            collection.Add('A');
            collection.Add('B');
            collection.Add('C');

            PropertyChangedEventHandler pceh = (object sender, PropertyChangedEventArgs e) =>
            {
                GC.KeepAlive(sender);
                propertyChanged = true;
                changedProps.Add(e.PropertyName);
            };

            // Adding a PropertyChanged event handler
            ((INotifyPropertyChanged)collection).PropertyChanged += pceh;

            collection.CollectionChanged += (object sender, NotifyCollectionChangedEventArgs e) =>
            {
                GC.KeepAlive(sender);
                args = e;
            };

            collection.CollectionChanged += (object sender, NotifyCollectionChangedEventArgs e) =>
            {
                GC.KeepAlive(sender);
                GC.KeepAlive(e);
                // This one will attempt to break reentrancy
                try
                {
                    collection.Add('X');
                    Assert.Fail("Reentrancy should not be allowed.");
                }
                catch (InvalidOperationException ex)
                {
                    GC.KeepAlive(ex);
                }
            };

            collection[2] = 'I';

            Assert.IsTrue(propertyChanged, "REENT_1");
            Assert.IsTrue(changedProps.Contains("Item[]"), "REENT_2");

            CollectionChangedEventValidators.ValidateReplaceOperation(args, new char[] { 'C' }, new char[] { 'I' }, 2, "REENT_3");

            // Removing the PropertyChanged event handler should work as well:
            ((INotifyPropertyChanged)collection).PropertyChanged -= pceh;
        }
        public void NotifyCollectionChangedEventArgsConstructor3Test()
        {
            /* Expected Behavior:
             *
             * If action is Add, success.
             * If action is Remove, success.
             * If action is Reset:
             *    If changedItem is null, success.
             *    If changedItem is non-null, throw an Argument Exception
             * If action is Move or Replace, throw an Argument Exception
             */

            var changedItem = new object();

            // Trying with Add
            var args = new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, changedItem);

            CollectionChangedEventValidators.ValidateAddOperation(args, new[] { changedItem }, "#C01");

            // Trying with Remove
            args = new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, changedItem);

            CollectionChangedEventValidators.ValidateRemoveOperation(args, new[] { changedItem }, "#C02");

            // Trying with Reset

            args = new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset, (object)null);

            CollectionChangedEventValidators.ValidateResetOperation(args, "#C03");

            try
            {
                GC.KeepAlive(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset, changedItem));
                Assert.Fail("Should not be able to call .ctor with NotifyCollectionChangedAction.Reset.");
            }
            catch (ArgumentException ex)
            {
                No.Op(ex);
            }

            // Trying with Move
            try
            {
                GC.KeepAlive(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Move, changedItem));
                Assert.Fail("Should not be able to call .ctor with NotifyCollectionChangedAction.Move.");
            }
            catch (ArgumentException ex)
            {
                No.Op(ex);
            }

            // Trying with Replace
            try
            {
                GC.KeepAlive(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace, changedItem));
                Assert.Fail("Should not be able to call .ctor with NotifyCollectionChangedAction.Replace.");
            }
            catch (ArgumentException ex)
            {
                No.Op(ex);
            }
        }
        public void NotifyCollectionChangedEventArgsConstructor10Test()
        {
            var       changed  = new object();
            const int newIndex = 2;
            const int oldIndex = 5;

            // Trying with Replace
            var args = new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Move, changed, newIndex, oldIndex);

            CollectionChangedEventValidators.ValidateMoveOperation(args, new[] { changed }, newIndex, oldIndex, "#J01");

            // Trying with newIndex < 0.
            try
            {
                GC.KeepAlive(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Move, changed, -5, oldIndex));
                Assert.Fail("The newIndex argument cannot be less than 0.");
            }
            catch (ArgumentException ex)
            {
                GC.KeepAlive(ex);
            }

            // Trying with Reset
            try
            {
                GC.KeepAlive(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset, changed, newIndex, oldIndex));
                Assert.Fail("Should not be able to call .ctor with NotifyCollectionChangedAction.Reset.");
            }
            catch (ArgumentException ex)
            {
                No.Op(ex);
            }

            // Trying with Replace
            try
            {
                GC.KeepAlive(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace, changed, newIndex, oldIndex));
                Assert.Fail("Should not be able to call .ctor with NotifyCollectionChangedAction.Replace.");
            }
            catch (ArgumentException ex)
            {
                No.Op(ex);
            }

            // Trying with Add
            try
            {
                GC.KeepAlive(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, changed, newIndex, oldIndex));
                Assert.Fail("Should not be able to call .ctor with NotifyCollectionChangedAction.Add.");
            }
            catch (ArgumentException ex)
            {
                No.Op(ex);
            }

            // Trying with Remove
            try
            {
                GC.KeepAlive(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, changed, newIndex, oldIndex));
                Assert.Fail("Should not be able to call .ctor with NotifyCollectionChangedAction.Remove.");
            }
            catch (ArgumentException ex)
            {
                No.Op(ex);
            }
        }
        public void NotifyCollectionChangedEventArgsConstructor4Test()
        {
            /* Expected Behavior:
             *
             * If action is Replace:
             *    If newItems is null, throw an ArgumentNullException.
             *    If oldItems is null, throw an ArgumentNullException
             *    Otherwise, success.
             * If action is not Replace, throw an ArgumentException
             */

            IList newItems = new List <object>();
            IList oldItems = new List <object>();

            // Trying with Replace
            var args = new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace, newItems, oldItems);

            CollectionChangedEventValidators.ValidateReplaceOperation(args, oldItems, newItems, "#D01");

            // Add some items to test this one.
            newItems.Add(new object());
            newItems.Add(new object());
            newItems.Add(new object());

            // Trying with Replace again
            args = new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace, newItems, oldItems);

            CollectionChangedEventValidators.ValidateReplaceOperation(args, oldItems, newItems, "#D02");

            // Add some more items to test this one.
            oldItems.Add(new object());
            oldItems.Add(new object());
            oldItems.Add(new object());

            // Trying with Replace again
            args = new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace, newItems, oldItems);

            CollectionChangedEventValidators.ValidateReplaceOperation(args, oldItems, newItems, "#D03");

            // Trying with null arguments.
            try
            {
                // ReSharper disable once AssignNullToNotNullAttribute
                GC.KeepAlive(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace, null, oldItems));
                Assert.Fail("The newItems argument cannot be null.");
            }
            catch (ArgumentNullException ex)
            {
                No.Op(ex);
            }

            try
            {
                // ReSharper disable once AssignNullToNotNullAttribute
                GC.KeepAlive(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace, newItems, null));
                Assert.Fail("The oldItems argument cannot be null.");
            }
            catch (ArgumentNullException ex)
            {
                No.Op(ex);
            }

            // Trying with Reset
            try
            {
                GC.KeepAlive(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset, newItems, oldItems));
                Assert.Fail("Should not be able to call .ctor with NotifyCollectionChangedAction.Reset.");
            }
            catch (ArgumentException ex)
            {
                No.Op(ex);
            }

            // Trying with Move
            try
            {
                GC.KeepAlive(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Move, newItems, oldItems));
                Assert.Fail("Should not be able to call .ctor with NotifyCollectionChangedAction.Move.");
            }
            catch (ArgumentException ex)
            {
                No.Op(ex);
            }

            // Trying with Add
            try
            {
                GC.KeepAlive(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, newItems, oldItems));
                Assert.Fail("Should not be able to call .ctor with NotifyCollectionChangedAction.Add.");
            }
            catch (ArgumentException ex)
            {
                No.Op(ex);
            }

            // Trying with Remove
            try
            {
                GC.KeepAlive(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, newItems, oldItems));
                Assert.Fail("Should not be able to call .ctor with NotifyCollectionChangedAction.Remove.");
            }
            catch (ArgumentException ex)
            {
                No.Op(ex);
            }
        }
        public void NotifyCollectionChangedEventArgsConstructor2Test()
        {
            /* Expected Behavior:
             *
             * If action is Add, success.
             * If action is Remove, success.
             * If action is Reset:
             *    If changedItems is null, success.
             *    If changedItems is non-null, throw an Argument Exception
             * If action is Move or Replace, throw an Argument Exception
             */

            IList changedItems = new List <object>();

            // Trying with Add
            var args = new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, changedItems);

            CollectionChangedEventValidators.ValidateAddOperation(args, changedItems, "#B01");

            // Trying to add a null array
            try
            {
                GC.KeepAlive(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, null));
                Assert.Fail("Cannot call .ctor if changedItems is null.");
            }
            catch (ArgumentNullException ex)
            {
                No.Op(ex);
            }

            // Trying with Remove
            args = new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, changedItems);

            CollectionChangedEventValidators.ValidateRemoveOperation(args, changedItems, "#B02");

            // Trying with Reset (works if changedItems is null)
            args = new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset, null);

            CollectionChangedEventValidators.ValidateResetOperation(args, "#B03");

            try
            {
                args = new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset, changedItems);
                GC.KeepAlive(args);
                Assert.Fail("Should not be able to call .ctor with NotifyCollectionChangedAction.Reset.");
            }
            catch (ArgumentException ex)
            {
                No.Op(ex);
            }

            // Trying with Move
            try
            {
                GC.KeepAlive(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Move, changedItems));
                Assert.Fail("Should not be able to call .ctor with NotifyCollectionChangedAction.Move.");
            }
            catch (ArgumentException ex)
            {
                No.Op(ex);
            }

            // Trying with Replace
            try
            {
                GC.KeepAlive(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace, changedItems));
                Assert.Fail("Should not be able to call .ctor with NotifyCollectionChangedAction.Replace.");
            }
            catch (ArgumentException ex)
            {
                No.Op(ex);
            }

            // Add some items, and repeat
            changedItems.Add(new object());
            changedItems.Add(new object());
            changedItems.Add(new object());

            // Trying with Add
            args = new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, changedItems);

            CollectionChangedEventValidators.ValidateAddOperation(args, changedItems, "#B04");

            // Trying with Remove
            args = new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, changedItems);

            CollectionChangedEventValidators.ValidateRemoveOperation(args, changedItems, "#B05");
        }
        public void NotifyCollectionChangedEventArgsConstructor5Test()
        {
            /* Expected Behavior:
             *
             * If action is Add or Remove:
             *    If changedItems is null, throw an ArgumentNullException.
             *    If startingIndex < -1, throw an ArgumentException
             *    Otherwise, success.
             * If action is Reset:
             *    If changedItems is non-null, throw an ArgumentException
             *    If startingIndex != 0, throw an ArgumentException
             *    Otherwise, success.
             * If action is Move or Replace, throw an ArgumentException
             */

            IList     changedItems  = new List <object>();
            const int startingIndex = 5; // Doesn't matter what the value of this is.

            // Trying with Add
            var args = new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, changedItems, startingIndex);

            CollectionChangedEventValidators.ValidateAddOperation(args, changedItems, startingIndex, "#E01");

            // Trying with Remove
            args = new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, changedItems, startingIndex);

            CollectionChangedEventValidators.ValidateRemoveOperation(args, changedItems, startingIndex, "#E02");

            // Add some items to test this one.
            changedItems.Add(new object());
            changedItems.Add(new object());
            changedItems.Add(new object());

            // Trying with Add
            args = new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, changedItems, startingIndex);

            CollectionChangedEventValidators.ValidateAddOperation(args, changedItems, startingIndex, "#E03");

            try
            {
                GC.KeepAlive(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, changedItems, -5));
                Assert.Fail("Should not be able to call .ctor with NotifyCollectionChangedAction.Add if startingIndex < -1.");
            }
            catch (ArgumentException ex)
            {
                No.Op(ex);
            }

            try
            {
                GC.KeepAlive(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, null, startingIndex));
                Assert.Fail("Should not be able to call .ctor with NotifyCollectionChangedAction.Add if changedItems is null.");
            }
            catch (ArgumentNullException ex)
            {
                No.Op(ex);
            }

            // Trying with Remove
            args = new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, changedItems, startingIndex);

            CollectionChangedEventValidators.ValidateRemoveOperation(args, changedItems, startingIndex, "#E04");

            try
            {
                GC.KeepAlive(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, changedItems, -5));
                Assert.Fail("Should not be able to call .ctor with NotifyCollectionChangedAction.Remove if startingIndex < -1.");
            }
            catch (ArgumentException ex)
            {
                No.Op(ex);
            }

            try
            {
                GC.KeepAlive(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, null, startingIndex));
                Assert.Fail("Should not be able to call .ctor with NotifyCollectionChangedAction.Remove if changedItems is null.");
            }
            catch (ArgumentNullException ex)
            {
                No.Op(ex);
            }

            // Trying with Reset
            GC.KeepAlive(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset, null, -1));

            try
            {
                GC.KeepAlive(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset, changedItems, -1));
                Assert.Fail("Should not be able to call .ctor with NotifyCollectionChangedAction.Reset unless changeItems is null");
            }
            catch (ArgumentException ex)
            {
                No.Op(ex);
            }

            try
            {
                GC.KeepAlive(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset, null, 1));
                Assert.Fail("Should not be able to call .ctor with NotifyCollectionChangedAction.Reset unless startingIndex is -1");
            }
            catch (ArgumentException ex)
            {
                No.Op(ex);
            }

            try
            {
                GC.KeepAlive(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset, changedItems, startingIndex));
                Assert.Fail("Should not be able to call .ctor with NotifyCollectionChangedAction.Reset.");
            }
            catch (ArgumentException ex)
            {
                No.Op(ex);
            }

            // Trying with Move
            try
            {
                GC.KeepAlive(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Move, changedItems, startingIndex));
                Assert.Fail("Should not be able to call .ctor with NotifyCollectionChangedAction.Move.");
            }
            catch (ArgumentException ex)
            {
                No.Op(ex);
            }

            // Trying with Replace
            try
            {
                GC.KeepAlive(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace, changedItems, startingIndex));
                Assert.Fail("Should not be able to call .ctor with NotifyCollectionChangedAction.Replace.");
            }
            catch (ArgumentException ex)
            {
                No.Op(ex);
            }
        }
        public void NotifyCollectionChangedEventArgsConstructor7Test()
        {
            var oldItem = new object();
            var newItem = new object(); // Doesn't matter what the value of this is.

            // Trying with Add
            var args = new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace, newItem, oldItem);

            CollectionChangedEventValidators.ValidateReplaceOperation(args, new[] { oldItem }, new[] { newItem }, "#G01");

            // Trying null items
            args = new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace, null, oldItem);
            CollectionChangedEventValidators.ValidateReplaceOperation(args, new[] { oldItem }, new object[] { null }, "#G02");

            args = new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace, newItem, null);
            CollectionChangedEventValidators.ValidateReplaceOperation(args, new object[] { null }, new[] { newItem }, "#G03");

            // Trying with Reset
            try
            {
                GC.KeepAlive(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset, newItem, oldItem));
                Assert.Fail("Should not be able to call .ctor with NotifyCollectionChangedAction.Reset.");
            }
            catch (ArgumentException ex)
            {
                No.Op(ex);
            }

            // Trying with Move
            try
            {
                GC.KeepAlive(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Move, newItem, oldItem));
                Assert.Fail("Should not be able to call .ctor with NotifyCollectionChangedAction.Move.");
            }
            catch (ArgumentException ex)
            {
                No.Op(ex);
            }

            // Trying with Add
            try
            {
                GC.KeepAlive(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, newItem, oldItem));
                Assert.Fail("Should not be able to call .ctor with NotifyCollectionChangedAction.Add.");
            }
            catch (ArgumentException ex)
            {
                No.Op(ex);
            }

            // Trying with Remove
            try
            {
                GC.KeepAlive(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, newItem, oldItem));
                Assert.Fail("Should not be able to call .ctor with NotifyCollectionChangedAction.Remove.");
            }
            catch (ArgumentException ex)
            {
                No.Op(ex);
            }
        }
        public void NotifyCollectionChangedEventArgsConstructor6Test()
        {
            var       changedItem   = new object();
            const int startingIndex = 5; // Doesn't matter what the value of this is.

            // Trying with Add
            var args = new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, changedItem, startingIndex);

            CollectionChangedEventValidators.ValidateAddOperation(args, new[] { changedItem }, startingIndex, "#F01");

            // Trying with Remove
            args = new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, changedItem, startingIndex);

            CollectionChangedEventValidators.ValidateRemoveOperation(args, new[] { changedItem }, startingIndex, "#F02");

            // Trying with Reset
            args = new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset, (object)null, -1);

            CollectionChangedEventValidators.ValidateResetOperation(args, "#F03");

            try
            {
                GC.KeepAlive(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset, changedItem, -1));
                Assert.Fail("Should not be able to call .ctor with NotifyCollectionChangedAction.Reset unless changeItems is null");
            }
            catch (ArgumentException ex)
            {
                No.Op(ex);
            }

            try
            {
                GC.KeepAlive(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset, (object)null, 1));
                Assert.Fail("Should not be able to call .ctor with NotifyCollectionChangedAction.Reset unless startingIndex is -1");
            }
            catch (ArgumentException ex)
            {
                No.Op(ex);
            }

            try
            {
                GC.KeepAlive(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset, changedItem, startingIndex));
                Assert.Fail("Should not be able to call .ctor with NotifyCollectionChangedAction.Reset.");
            }
            catch (ArgumentException ex)
            {
                No.Op(ex);
            }

            // Trying with Move
            try
            {
                GC.KeepAlive(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Move, changedItem, startingIndex));
                Assert.Fail("Should not be able to call .ctor with NotifyCollectionChangedAction.Move.");
            }
            catch (ArgumentException ex)
            {
                No.Op(ex);
            }

            // Trying with Replace
            try
            {
                GC.KeepAlive(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace, changedItem, startingIndex));
                Assert.Fail("Should not be able to call .ctor with NotifyCollectionChangedAction.Replace.");
            }
            catch (ArgumentException ex)
            {
                No.Op(ex);
            }
        }
        public void NotifyCollectionChangedEventArgsConstructor8Test()
        {
            IList     newItems   = new List <object>();
            IList     oldItems   = new List <object>();
            const int startIndex = 5;

            // Trying with Replace
            var args = new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace, newItems, oldItems, startIndex);

            CollectionChangedEventValidators.ValidateReplaceOperation(args, oldItems, newItems, startIndex, "#H01");

            // Add some items to test this one.
            newItems.Add(new object());
            newItems.Add(new object());
            newItems.Add(new object());

            // Trying with Replace again
            args = new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace, newItems, oldItems, startIndex);

            CollectionChangedEventValidators.ValidateReplaceOperation(args, oldItems, newItems, startIndex, "#H02");

            // Add some more items to test this one.
            oldItems.Add(new object());
            oldItems.Add(new object());
            oldItems.Add(new object());

            // Trying with Replace again
            args = new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace, newItems, oldItems, startIndex);

            CollectionChangedEventValidators.ValidateReplaceOperation(args, oldItems, newItems, startIndex, "#H03");

            // Trying with null arguments.
            try
            {
                // ReSharper disable once AssignNullToNotNullAttribute
                GC.KeepAlive(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace, null, oldItems, startIndex));
                Assert.Fail("The newItems argument cannot be null.");
            }
            catch (ArgumentNullException ex)
            {
                No.Op(ex);
            }

            try
            {
                // ReSharper disable once AssignNullToNotNullAttribute
                GC.KeepAlive(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace, newItems, null, startIndex));
                Assert.Fail("The oldItems argument cannot be null.");
            }
            catch (ArgumentNullException ex)
            {
                No.Op(ex);
            }

            // Trying with Reset
            try
            {
                GC.KeepAlive(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset, newItems, oldItems, startIndex));
                Assert.Fail("Should not be able to call .ctor with NotifyCollectionChangedAction.Reset.");
            }
            catch (ArgumentException ex)
            {
                No.Op(ex);
            }

            // Trying with Move
            try
            {
                GC.KeepAlive(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Move, newItems, oldItems, startIndex));
                Assert.Fail("Should not be able to call .ctor with NotifyCollectionChangedAction.Move.");
            }
            catch (ArgumentException ex)
            {
                No.Op(ex);
            }

            // Trying with Add
            try
            {
                GC.KeepAlive(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, newItems, oldItems, startIndex));
                Assert.Fail("Should not be able to call .ctor with NotifyCollectionChangedAction.Add.");
            }
            catch (ArgumentException ex)
            {
                No.Op(ex);
            }

            // Trying with Remove
            try
            {
                GC.KeepAlive(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, newItems, oldItems));
                Assert.Fail("Should not be able to call .ctor with NotifyCollectionChangedAction.Remove.");
            }
            catch (ArgumentException ex)
            {
                No.Op(ex);
            }
        }
        public void NotifyCollectionChangedEventArgsConstructor9Test()
        {
            IList     changed  = new List <object>();
            const int newIndex = 2;
            const int oldIndex = 5;

            // Trying with Replace
            var args = new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Move, changed, newIndex, oldIndex);

            CollectionChangedEventValidators.ValidateMoveOperation(args, changed, newIndex, oldIndex, "#I01");

            // Add some items to test this one.
            changed.Add(new object());
            changed.Add(new object());
            changed.Add(new object());

            // Trying with Replace again
            args = new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Move, changed, newIndex, oldIndex);

            CollectionChangedEventValidators.ValidateMoveOperation(args, changed, newIndex, oldIndex, "#I02");

            // Trying with newIndex < 0.
            try
            {
                GC.KeepAlive(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Move, changed, -5, oldIndex));
                Assert.Fail("The index argument cannot be less than 0.");
            }
            catch (ArgumentException ex)
            {
                No.Op(ex);
            }

            // Trying with Reset
            try
            {
                GC.KeepAlive(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset, changed, newIndex, oldIndex));
                Assert.Fail("Should not be able to call .ctor with NotifyCollectionChangedAction.Reset.");
            }
            catch (ArgumentException ex)
            {
                No.Op(ex);
            }

            // Trying with Replace
            try
            {
                GC.KeepAlive(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace, changed, newIndex, oldIndex));
                Assert.Fail("Should not be able to call .ctor with NotifyCollectionChangedAction.Replace.");
            }
            catch (ArgumentException ex)
            {
                No.Op(ex);
            }

            // Trying with Add
            try
            {
                GC.KeepAlive(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, changed, newIndex, oldIndex));
                Assert.Fail("Should not be able to call .ctor with NotifyCollectionChangedAction.Add.");
            }
            catch (ArgumentException ex)
            {
                No.Op(ex);
            }

            // Trying with Remove
            try
            {
                GC.KeepAlive(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, changed, newIndex, oldIndex));
                Assert.Fail("Should not be able to call .ctor with NotifyCollectionChangedAction.Remove.");
            }
            catch (ArgumentException ex)
            {
                No.Op(ex);
            }
        }