public void ShouldTreatNullCollectionsAsEmpty()
        {
            CollectionEntityConfiguration          config  = new CollectionEntityConfiguration();
            EntityChangeTracker <CollectionEntity> tracker = new EntityChangeTracker <CollectionEntity>(config);
            CollectionEntity entity = new CollectionEntity()
            {
                Values = null
            };

            tracker.Attach(entity);

            entity.Values = new List <int>()
            {
                4
            };

            var additionDetails = tracker.DetectCollectionChanges(entity, x => x.Values, ElementState.Added);
            var additions       = additionDetails.GetChanges();

            Assert.AreEqual(1, additions.Count, "Only one addition to the collection should have been detected.");
            var addition = additions.Single();

            Assert.AreEqual(4, addition.Item, "The wrong value was detected as changed.");
            Assert.AreEqual(ElementState.Added, addition.State, "The item should have been added.");
        }
        public void ShouldSeeChangeToBasePropertyWhenBaseObject()
        {
            var           detector = new DerivedChangeDetector();
            var           tracker  = new EntityChangeTracker <TestEntity>(detector);
            DerivedEntity entity   = new DerivedEntity()
            {
                IntValue = 123
            };

            tracker.Attach(entity);

            entity.IntValue = 234;

            var changes = tracker.DetectChanges();

            Assert.AreEqual(1, changes.Count(), "The wrong number of changes were detected.");
            IEntityChange <TestEntity> change = changes.Single();

            Assert.AreSame(entity, change.Entity, "A change was detected on the wrong entity.");
            Assert.AreEqual(EntityState.Modified, change.State, "The entity should have been modified.");

            Assert.AreEqual(1, change.GetChanges().Count(), "The wrong number of properties were seen as changed.");
            var propertyChange = change.GetChanges().Single();

            Assert.AreEqual(TestEntityChangeDetector.IntDescription, propertyChange.DisplayName, "The wrong property was recorded.");

            bool hasBaseChange = change.HasChange(x => x.IntValue);

            Assert.IsTrue(hasBaseChange, "The change was not detected.");

            bool hasDerivedChange = change.As <DerivedEntity>().HasChange(x => x.IntValue);

            Assert.IsTrue(hasDerivedChange, "The change was not detected.");
        }
        public void ShouldDetectModifiedRecordsInCollection()
        {
            CollectionEntityConfiguration          config  = new CollectionEntityConfiguration();
            EntityChangeTracker <CollectionEntity> tracker = new EntityChangeTracker <CollectionEntity>(config);
            CollectionEntity entity = new CollectionEntity()
            {
                Values = new List <int>()
                {
                    1, 2, 3
                }
            };

            tracker.Attach(entity);

            entity.Values.Remove(1);
            entity.Values.Add(4);

            var additionDetails = tracker.DetectCollectionChanges(entity, x => x.Values, ElementState.Added);
            var additions       = additionDetails.GetChanges();

            Assert.AreEqual(1, additions.Count, "Only one addition to the collection should have been detected.");
            var addition = additions.Single();

            Assert.AreEqual(4, addition.Item, "The wrong value was detected as changed.");
            Assert.AreEqual(ElementState.Added, addition.State, "The item should have been added.");

            var removalDetails = tracker.DetectCollectionChanges(entity, x => x.Values, ElementState.Removed);
            var removals       = removalDetails.GetChanges();

            Assert.AreEqual(1, removals.Count, "Only one removal from the collection should have been detected.");
            var removal = removals.Single();

            Assert.AreEqual(1, removal.Item, "The wrong value was detected as changed.");
            Assert.AreEqual(ElementState.Removed, removal.State, "The item should have been removed.");
        }
        public void ShouldDetectMostRecentChangesForRemoved()
        {
            var detector = new TestEntityChangeDetector();
            EntityChangeTracker <TestEntity> tracker = new EntityChangeTracker <TestEntity>(detector);

            TestEntity entity = new TestEntity()
            {
                IntValue = 123
            };

            tracker.Attach(entity);
            tracker.Remove(entity);

            entity.IntValue = 234;

            var change = tracker.DetectChanges(entity);

            Assert.AreEqual(EntityState.Removed, change.State, "The entity should have remained Added.");
            Assert.IsTrue(change.HasChange(x => x.IntValue), "The IntValue should have changed.");

            var propertyChange = change.GetChange(x => x.IntValue);

            Assert.IsNotNull(propertyChange, "The change was null after detecting its prescence.");
            Assert.AreEqual(234, propertyChange.OriginalValue, "The latest value was not returned.");
        }
        public void ShouldRetainModificationIfAttachedTwice()
        {
            var detector = new TestEntityChangeDetector();
            EntityChangeTracker <TestEntity> tracker = new EntityChangeTracker <TestEntity>(detector);

            TestEntity entity = new TestEntity()
            {
                IntValue = 123
            };

            tracker.Attach(entity);
            var before = tracker.DetectChanges(entity);

            Assert.AreEqual(EntityState.Unmodified, before.State, "The entity should have been Unmodified to start with.");

            entity.IntValue = 234;

            tracker.Attach(entity); // Should not wipe out changes
            var after = tracker.DetectChanges(entity);

            Assert.AreEqual(EntityState.Modified, after.State, "The entity should have become Modified.");
        }
        public void ShouldLeaveUnmodifedAfterAttachingRemovedEntity()
        {
            var detector = new TestEntityChangeDetector();
            EntityChangeTracker <TestEntity> tracker = new EntityChangeTracker <TestEntity>(detector);

            TestEntity entity = new TestEntity();

            tracker.Remove(entity);
            tracker.Attach(entity);

            var change = tracker.DetectChanges(entity);

            Assert.AreEqual(EntityState.Unmodified, change.State, "Attaching a Removed entity should make it Unmodified.");
        }
        public void ShouldDetachUnmodifiedEntity()
        {
            var detector = new TestEntityChangeDetector();
            EntityChangeTracker <TestEntity> tracker = new EntityChangeTracker <TestEntity>(detector);

            TestEntity entity = new TestEntity();

            tracker.Attach(entity);
            tracker.Detach(entity);

            var change = tracker.DetectChanges(entity);

            Assert.AreEqual(EntityState.Detached, change.State, "Detaching an Unmodified entity should make it Detached.");
        }
        public void ShouldMarkRemovedAsDetachedAfterCommitting()
        {
            var detector = new TestEntityChangeDetector();
            EntityChangeTracker <TestEntity> tracker = new EntityChangeTracker <TestEntity>(detector);

            TestEntity entity = new TestEntity();

            tracker.Attach(entity);
            tracker.Remove(entity);

            tracker.CommitChanges();
            var change = tracker.DetectChanges(entity);

            Assert.AreEqual(EntityState.Detached, change.State, "The entity should be Detached after committing.");
        }
        public void ShouldAllowRetrievingUnmodifiedEntities()
        {
            var detector = new TestEntityChangeDetector();
            EntityChangeTracker <TestEntity> tracker = new EntityChangeTracker <TestEntity>(detector);

            TestEntity entity = new TestEntity();

            tracker.Attach(entity);

            var changes = tracker.DetectChanges(EntityState.Unmodified);

            Assert.AreEqual(1, changes.Count(), "The entity should have been seen as changed.");
            var change = changes.Single();

            Assert.AreSame(entity, change.Entity, "The wrong entity was returned.");
            Assert.AreEqual(EntityState.Unmodified, change.State, "The entity was not unmodified.");
        }
        public void ShouldNotDetectChangesAfterCommitting()
        {
            var detector = new TestEntityChangeDetector();
            EntityChangeTracker <TestEntity> tracker = new EntityChangeTracker <TestEntity>(detector);

            TestEntity entity = new TestEntity()
            {
                IntValue = 1234
            };

            tracker.Attach(entity);
            entity.IntValue = 234;  // Should make the entity Modified

            tracker.CommitChanges();
            var change = tracker.DetectChanges(entity);

            Assert.AreEqual(EntityState.Unmodified, change.State, "The entity should be Unmodified after committing.");
        }
        public void ShouldDetectRemovedByDefault()
        {
            var detector = new TestEntityChangeDetector();
            EntityChangeTracker <TestEntity> tracker = new EntityChangeTracker <TestEntity>(detector);

            TestEntity entity = new TestEntity();

            tracker.Attach(entity);
            tracker.Remove(entity);

            var changes = tracker.DetectChanges();

            Assert.AreEqual(1, changes.Count(), "The entity should have been seen as changed.");
            var change = changes.Single();

            Assert.AreSame(entity, change.Entity, "The wrong entity was returned.");
            Assert.AreEqual(EntityState.Removed, change.State, "The entity was not removed.");
        }
        public void ShouldRemainRemovedAfterRemovingTwice()
        {
            var detector = new TestEntityChangeDetector();
            EntityChangeTracker <TestEntity> tracker = new EntityChangeTracker <TestEntity>(detector);

            TestEntity entity = new TestEntity();

            tracker.Attach(entity);
            tracker.Remove(entity);
            var before = tracker.DetectChanges(entity);

            Assert.AreEqual(EntityState.Removed, before.State, "The entity should have been Removed to start with.");

            tracker.Remove(entity);
            var after = tracker.DetectChanges(entity);

            Assert.AreEqual(EntityState.Removed, after.State, "The entity should have remained Removed.");
        }
        public void ShouldDetectChanges_Modified()
        {
            var detector = new TestEntityChangeDetector();
            EntityChangeTracker <TestEntity> tracker = new EntityChangeTracker <TestEntity>(detector);

            TestEntity entity = new TestEntity()
            {
                BooleanValue  = false,
                DateTimeValue = new DateTime(2015, 07, 29),
                GuidValue     = Guid.NewGuid(),
                IntValue      = 123,
                MoneyValue    = 12.34m,
                PercentValue  = 12.5m,
                StringValue   = "Hello"
            };

            tracker.Attach(entity);

            entity.BooleanValue  = true;
            entity.DateTimeValue = new DateTime(2015, 07, 30);
            entity.GuidValue     = Guid.NewGuid();
            entity.IntValue      = 234;
            entity.MoneyValue    = 10m;
            entity.PercentValue  = 15m;
            entity.StringValue   = "Goodbye";

            var changes = tracker.DetectChanges();

            Assert.AreEqual(1, changes.Count(), "The wrong number of changed entities were detected.");
            var change = changes.Single();

            Assert.AreSame(entity, change.Entity, "The wrong entity was returned.");
            Assert.AreEqual(EntityState.Modified, change.State, "The entity was not marked as modified.");
            Assert.AreEqual(7, change.GetChanges().Count(), "The wrong number of changes were detected.");

            Assert.IsTrue(change.HasChange(e => e.BooleanValue), "Boolean value should be changed.");
            Assert.IsTrue(change.HasChange(e => e.DateTimeValue), "DateTime value should be changed.");
            Assert.IsTrue(change.HasChange(e => e.GuidValue), "Guid value should be changed.");
            Assert.IsTrue(change.HasChange(e => e.IntValue), "Int value should be changed.");
            Assert.IsTrue(change.HasChange(e => e.MoneyValue), "Money value should be changed.");
            Assert.IsTrue(change.HasChange(e => e.PercentValue), "Percent value should be changed.");
            Assert.IsTrue(change.HasChange(e => e.StringValue), "String value should be changed.");
        }
        public void ShouldDetectChangeToDerivedPropertyWhenRemoving()
        {
            var           detector = new DerivedChangeDetector();
            var           tracker  = new EntityChangeTracker <TestEntity>(detector);
            DerivedEntity entity   = new DerivedEntity()
            {
                DerivedValue = 123
            };

            tracker.Attach(entity);
            tracker.Remove(entity);

            var changes = tracker.DetectChanges();

            Assert.AreEqual(1, changes.Count(), "The wrong number of changes were detected.");
            IEntityChange <TestEntity> change = changes.Single();

            Assert.AreSame(entity, change.Entity, "A change was detected on the wrong entity.");
            Assert.AreEqual(EntityState.Removed, change.State, "The entity should have been modified.");
            Assert.AreEqual(1, change.GetChanges().Count(), "The wrong number of properties were seen as changed.");
        }
        public void ShouldLeaveModifiedWhenAddingRemovedEntity()
        {
            var detector = new TestEntityChangeDetector();
            EntityChangeTracker <TestEntity> tracker = new EntityChangeTracker <TestEntity>(detector);

            TestEntity entity = new TestEntity()
            {
                IntValue = 123
            };

            tracker.Attach(entity);
            tracker.Remove(entity);
            tracker.Add(entity);

            entity.IntValue = 234;

            var change = tracker.DetectChanges(entity);

            Assert.AreEqual(EntityState.Modified, change.State, "Adding a Removed entity that was changed should make it Modified.");
            Assert.IsTrue(change.HasChange(x => x.IntValue), "The modified value does not reflect the latest value.");
        }