public void when_undoing_assignment_to_property_with_no_setter()
        {
            //setup
            var baseObject = TestHelper.CreateWithNonDefaultProperties<FlatPropertyBag>();

            var controller = new PropertyBagVersionController<FlatPropertyBag>(baseObject,
                                                                               _testHelper.MakeConfiguredCloneFactoryFor<FlatPropertyBag>(),
                                                                               _testHelper.EmptyChangeSet(),
                                                                               _testHelper.MakeConfiguredVisitorFactory(),
                                                                               _testHelper.MakeConfiguredProxyFactory());
            //act
            TestDelegate act = () => controller.UndoLastAssignmentTo(self => self.PropWithoutSetter);

            //assert
            Assert.Throws<UntrackedObjectException>(act);
            A.CallTo(_testHelper.ProvidedVisitorFactory.MakeDeltaApplicationVisitor(ChangeType.Unknown, false))
             .WithAnyArguments()
             .MustNotHaveHappened();
        }
        public void when_undoing_assignment_where_no_candidate_changes_exist()
        {
            //setup
            var controller = new PropertyBagVersionController<FlatPropertyBag>(TestHelper.CreateWithNonDefaultProperties<FlatPropertyBag>(),
                                                                               _testHelper.MakeConfiguredCloneFactoryFor<FlatPropertyBag>(),
                                                                               _testHelper.EmptyChangeSet(),
                                                                               _testHelper.MakeConfiguredVisitorFactory(),
                                                                               _testHelper.MakeConfiguredProxyFactory());
            //act
            TestDelegate act = () => controller.UndoLastAssignmentTo(self => self.StringProperty);

            //assert
            Assert.Throws<VersionDeltaNotFoundException>(act);
        }
        public void when_undoing_assignment_to_grandchild()
        {
            //setup
            var baseObject = new DeepPropertyBag();
            var childObject = A.Fake<DeepPropertyBag>();
            var targetSite = baseObject.PropertyInfoFor(x => x.DeepChild).GetSetMethod();

            var controller = new PropertyBagVersionController<DeepPropertyBag>(baseObject,
                                                                               _testHelper.MakeConfiguredCloneFactoryFor<DeepPropertyBag>(),
                                                                               TestHelper.ChangeSet(childObject, targetSite, 1),
                                                                               _testHelper.MakeConfiguredVisitorFactory(),
                                                                               _testHelper.MakeConfiguredProxyFactory());
            //act
            TestDelegate act = () => controller.UndoLastAssignmentTo(self => self.DeepChild.DeepStringProperty);

            //assert
            Assert.Throws<UntrackedObjectException>(act);
            A.CallTo(() => childObject.DeepStringProperty).MustNotHaveHappened();
        }
        public void when_undoing_assignment_to_self()
        {
            //setup
            var controller = new PropertyBagVersionController<FlatPropertyBag>(TestHelper.CreateWithNonDefaultProperties<FlatPropertyBag>(),
                                                                               _testHelper.MakeConfiguredCloneFactoryFor<FlatPropertyBag>(),
                                                                               _testHelper.EmptyChangeSet(),
                                                                               _testHelper.MakeConfiguredVisitorFactory(),
                                                                               _testHelper.MakeConfiguredProxyFactory());
            //act
            TestDelegate act = () => controller.UndoLastAssignmentTo(self => self);

            //assert
            Assert.Throws<UntrackedObjectException>(act);
        }
        public void when_undoing_assignment_to_child()
        {
            //setup
            var baseObject = TestHelper.CreateWithNonDefaultProperties<FlatPropertyBag>();
            var targetSite = baseObject.PropertyInfoFor(x => x.StringProperty).GetSetMethod();
            const int targetVersion = 2;
            const string targetValue = "Two!";

            var changeSet = TestHelper.ChangeSet(new[] { "One", targetValue, "Three" },
                                                 Enumerable.Repeat(targetSite, 3),
                                                 new[] { targetVersion - 1L, targetVersion, targetVersion + 1L });

            var controller = new PropertyBagVersionController<FlatPropertyBag>(baseObject,
                                                                               _testHelper.MakeConfiguredCloneFactoryFor<FlatPropertyBag>(),
                                                                               changeSet,
                                                                               _testHelper.MakeConfiguredVisitorFactory(),
                                                                               _testHelper.MakeConfiguredProxyFactory());
            //act
            controller.UndoLastAssignmentTo(self => self.StringProperty);

            //assert
            // RunVisitorOnTree(_visitorFactory.MakeDeltaApplicationVisitor(includeDescendents: false, makeActive:false, targetSite:targetSetter));
            A.CallTo(() => _testHelper.ProvidedVisitorFactory.MakeDeltaApplicationVisitor(ChangeType.Undo, false, targetSite)).MustHaveHappened();
            A.CallTo(() => _testHelper.ProvidedDeltaApplicationVisitor.OnEntry(controller)).MustHaveHappened();

        }