public void When_registering_weak_event_then_it_should_still_be_here_when_target_referenced()
        {
            //// Arrange
            var eventCalled = false;
            var target = new MockEventTargetClass(() =>
            {
                eventCalled = true;
            });
            var obj = new MockObservableObject();

            //// Act
            WeakEvent.RegisterEvent<MockObservableObject, PropertyChangedEventArgs>(obj, "PropertyChanged", target.Callback);

            obj.Name = "test1";
            Assert.IsTrue(eventCalled);

            GC.Collect();
            GC.WaitForPendingFinalizers();
            GC.Collect();

            eventCalled = false;
            obj.Name = "test2";

            //// Assert
            Assert.IsTrue(eventCalled);
            target.Action = null;
        }
        public void When_raising_property_changed_event_externally_then_event_should_be_triggered()
        {
            //// Arrange
            var list = new List<string>();
            var obj = new MockObservableObject();
            obj.PropertyChanged += (sender, args) => list.Add(args.PropertyName);

            //// Act
            obj.RaisePropertyChanged<MockObservableObject>(i => i.Name);

            //// Assert
            Assert.AreEqual(1, list.Count);
            Assert.IsTrue(list.Contains("Name"));
        }
        public void When_serializing_an_object_then_round_trip_should_work()
        {
            //// Arrange
            var obj = new MockObservableObject();
            obj.Name = "a";

            //// Act
            var xml = XmlSerialization.Serialize(obj);
            var obj2 = XmlSerialization.Deserialize<MockObservableObject>(xml);
            var xml2 = XmlSerialization.Serialize(obj2); 

            //// Assert
            Assert.AreEqual(xml, xml2);
        }
        public void When_changing_property_then_event_should_be_triggered()
        {
            //// Arrange
            var list = new List<string>();
            var obj = new MockObservableObject();
            obj.PropertyChanged += (sender, args) => list.Add(args.PropertyName);

            //// Act
            obj.Name = "A";

            //// Assert
            Assert.AreEqual(2, list.Count);
            Assert.IsTrue(list.Contains("Name"));
            Assert.IsTrue(list.Contains("FullName"));
        }
        public void When_changing_a_scalar_property_then_redo_should_not_work()
        {
            //// Arrange
            var obj = new MockObservableObject();
            obj.Name = "A";
            var undoRedoManager = new UndoRedoManager(obj, new MockDispatcher());

            Assert.IsFalse(undoRedoManager.CanRedo);
            Assert.IsFalse(undoRedoManager.CanUndo);

            //// Act
            obj.Name = "B";
            undoRedoManager.Undo();

            Assert.IsTrue(undoRedoManager.CanRedo);
            obj.Name = "C";

            //// Assert
            Assert.IsFalse(undoRedoManager.CanRedo);
        }
        public void When_adding_object_to_list_then_undo_should_work()
        {
            //// Arrange
            var obj = new MockObservableObject();
            obj.List.Add(new MockObservableObject());

            var undoRedoManager = new UndoRedoManager(obj, new MockDispatcher());
            Assert.IsFalse(undoRedoManager.CanUndo);
            Assert.AreEqual(1, obj.List.Count);

            //// Act
            obj.List.Add(new MockObservableObject());

            Assert.AreEqual(2, obj.List.Count);
            Assert.IsTrue(undoRedoManager.CanUndo);

            undoRedoManager.Undo();

            //// Assert
            Assert.AreEqual(1, obj.List.Count);
        }
        public void When_registering_typed_weak_event_then_it_should_still_be_here_when_target_referenced()
        {
            //// Arrange
            var eventCalled = false;
            var target = new MockEventTargetClass(() =>
            {
                eventCalled = true;
            });
            var obj = new MockObservableObject();

            //// Act
            WeakEvent.RegisterEvent<MockEventTargetClass, PropertyChangedEventHandler, PropertyChangedEventArgs>(
                target,
                h => obj.PropertyChanged += h,
                h => obj.PropertyChanged -= h,
                h => (o, e) => h(o, e),
                (t, sender, args) => t.Callback(sender, args));

            obj.Name = "test1";
            Assert.IsTrue(eventCalled);

            GC.Collect();
            GC.WaitForPendingFinalizers();
            GC.Collect();

            eventCalled = false;
            obj.Name = "test2";

            //// Assert
            Assert.IsTrue(eventCalled);
            target.Action = null;
        }
        public void When_changing_property_of_excluded_child_type_then_undo_should_not_work()
        {
            //// Arrange
            var obj = new MockObservableObject();
            obj.AddExcludedChildType(typeof(ObservableObject));
            obj.Child = new MockObservableObject { Name = "A" };

            var undoRedoManager = new UndoRedoManager(obj, new MockDispatcher());
            Assert.IsFalse(undoRedoManager.CanUndo);

            //// Act
            obj.Child.Name = "B";

            Assert.AreEqual("B", obj.Child.Name);

            //// Assert
            Assert.IsFalse(undoRedoManager.CanUndo);
        }
        public void When_changing_a_collection_then_event_should_be_triggered()
        {
            //// Arrange
            var list = new List<PropertyChangedEventArgs>();

            var child = new MockObservableObject();
            var obj = new MockObservableObject();
            obj.List.Add(child);
            obj.GraphPropertyChanged += (sender, args) => list.Add(args);

            //// Act
            obj.List.Add(child);

            //// Assert
            Assert.AreEqual(1, list.OfType<IExtendedNotifyCollectionChangedEventArgs>().Count());
        }
        public void When_changing_property_in_cyclic_graph_then_event_should_occur_only_once()
        {
            //// Arrange
            var list = new List<PropertyChangedEventArgs>();

            var objA = new MockObservableObject();
            objA.Name = "A";

            var objB = new MockObservableObject();
            objB.Name = "B";
            objB.Child = objA;
            objA.Child = objB;

            objA.GraphPropertyChanged += (sender, args) => list.Add(args);

            //// Act
            objB.Name = "C";

            //// Assert
            Assert.AreEqual(2, list.Count);
        }
        public void When_changing_a_property_then_old_value_should_be_provided()
        {
            //// Arrange
            var list = new List<PropertyChangedEventArgs>();

            var obj = new MockObservableObject();
            obj.Name = "A";
            obj.GraphPropertyChanged += (sender, args) => list.Add(args);

            //// Act
            obj.Name = "B";

            //// Assert
            Assert.AreEqual(2, list.Count);
            Assert.AreEqual("A", ((GraphPropertyChangedEventArgs)list[0]).OldValue);
            Assert.AreEqual("B", ((GraphPropertyChangedEventArgs)list[0]).NewValue);
        }