From 36f76d491e7195a96a57904e55b18d786b06c2ae Mon Sep 17 00:00:00 2001 From: Johan Larsson Date: Thu, 25 Aug 2016 18:39:12 +0200 Subject: [PATCH] Track.IsDirty with inheritance - Tests for EqualBy, Diff And Track.IsDirty --- Gu.State.Tests/DiffTests/ClassesTests.cs | 38 +++++++++++ Gu.State.Tests/DiffTests/DiffTypes.cs | 25 ++++++++ Gu.State.Tests/EqualByTests/ClassesTests.cs | 63 +++++++++++++------ Gu.State.Tests/EqualByTests/EqualByTypes.cs | 15 +++++ Gu.State.Tests/Gu.State.Tests.csproj | 1 + .../DirtyTrackerTests.WithInheritance.cs | 38 +++++++++++ .../Track/Dirty/DirtyTrackerTypes.cs | 55 ++++++++++++++++ Gu.State/Track/Dirty/DirtyTrackerNode.cs | 5 ++ 8 files changed, 222 insertions(+), 18 deletions(-) create mode 100644 Gu.State.Tests/Track/Dirty/DirtyTrackerTests.WithInheritance.cs diff --git a/Gu.State.Tests/DiffTests/ClassesTests.cs b/Gu.State.Tests/DiffTests/ClassesTests.cs index 247241d1..e2e7a24a 100644 --- a/Gu.State.Tests/DiffTests/ClassesTests.cs +++ b/Gu.State.Tests/DiffTests/ClassesTests.cs @@ -152,6 +152,44 @@ this is FieldValues.Classes Assert.AreEqual(expected, result.ToString("", " ")); } + [Test] + public void EqualWhenSameType() + { + var x = new With(new Derived1 { BaseValue = 1, Derived1Value = 2 }); + var y = new With(new Derived1 { BaseValue = 1, Derived1Value = 2 }); + var result = this.DiffMethod(x, y, ReferenceHandling.Structural); + Assert.AreEqual(true, result.IsEmpty); + Assert.AreEqual("Empty", result.ToString("", " ")); + } + + [Test] + public void NotEqualWhenSameType() + { + var x = new With(new Derived1 { BaseValue = 1, Derived1Value = 2 }); + var y = new With(new Derived1 { BaseValue = 1, Derived1Value = 3 }); + var result = this.DiffMethod(x, y, ReferenceHandling.Structural); + Assert.AreEqual(false, result.IsEmpty); + var expected = this is PropertyValues.Classes + ? "With Value Derived1Value x: 2 y: 3" + : "With k__BackingField k__BackingField x: 2 y: 3"; + var actual = result.ToString("", " "); + Assert.AreEqual(expected, actual); + } + + [Test] + public void NotEqualWhenDifferentTypes() + { + var x = new With(new Derived1()); + var y = new With(new Derived2()); + var result = this.DiffMethod(x, y, ReferenceHandling.Structural); + Assert.AreEqual(false, result.IsEmpty); + var expected = this is PropertyValues.Classes + ? "With Value x: Gu.State.Tests.DiffTests.DiffTypes+Derived1 y: Gu.State.Tests.DiffTests.DiffTypes+Derived2" + : "With k__BackingField x: Gu.State.Tests.DiffTests.DiffTypes+Derived1 y: Gu.State.Tests.DiffTests.DiffTypes+Derived2"; + var actual = result.ToString("", " "); + Assert.AreEqual(expected, actual); + } + [TestCase(1, 1, null, "Empty")] [TestCase(1, 2, null, "WithReadonlyProperty x: 1 y: 2")] [TestCase(1, 1, ReferenceHandling.Throw, "Empty")] diff --git a/Gu.State.Tests/DiffTests/DiffTypes.cs b/Gu.State.Tests/DiffTests/DiffTypes.cs index 61036579..7bc95005 100644 --- a/Gu.State.Tests/DiffTests/DiffTypes.cs +++ b/Gu.State.Tests/DiffTests/DiffTypes.cs @@ -10,6 +10,16 @@ public static class DiffTypes { + public class With + { + public With(T value) + { + this.Value = value; + } + + public T Value { get; } + } + public class WithComplexValue { private string name; @@ -503,5 +513,20 @@ public override int GetHashCode() return this.HashValue; } } + + public abstract class BaseClass + { + public double BaseValue { get; set; } + } + + public class Derived1 : BaseClass + { + public double Derived1Value { get; set; } + } + + public class Derived2 : BaseClass + { + public double Derived2Value { get; set; } + } } } diff --git a/Gu.State.Tests/EqualByTests/ClassesTests.cs b/Gu.State.Tests/EqualByTests/ClassesTests.cs index d16005ca..51032093 100644 --- a/Gu.State.Tests/EqualByTests/ClassesTests.cs +++ b/Gu.State.Tests/EqualByTests/ClassesTests.cs @@ -55,6 +55,33 @@ public void WithComplexStructural(string xn, string yn, bool expected) Assert.AreEqual(expected, result); } + [Test] + public void EqualWhenSameType() + { + var x = new With(new Derived1 { BaseValue = 1, Derived1Value = 2 }); + var y = new With(new Derived1 { BaseValue = 1, Derived1Value = 2 }); + var result = this.EqualMethod(x, y, ReferenceHandling.Structural); + Assert.AreEqual(true, result); + } + + [Test] + public void NotEqualWhenSameType() + { + var x = new With(new Derived1 { BaseValue = 1, Derived1Value = 2 }); + var y = new With(new Derived1 { BaseValue = 1, Derived1Value = 3 }); + var result = this.EqualMethod(x, y, ReferenceHandling.Structural); + Assert.AreEqual(false, result); + } + + [Test] + public void NotEqualWhenDifferentTypes() + { + var x = new With(new Derived1()); + var y = new With(new Derived2()); + var result = this.EqualMethod(x, y, ReferenceHandling.Structural); + Assert.AreEqual(false, result); + } + [Test] public void WithComplexStructuralWhenNull() { @@ -98,11 +125,11 @@ public void WithComplexStructuralWhenYIsNull() public void WithComplexReferenceWhenSame() { var x = new WithComplexProperty - { - Name = "a", - Value = 1, - ComplexType = new ComplexType { Name = "b", Value = 2 } - }; + { + Name = "a", + Value = 1, + ComplexType = new ComplexType { Name = "b", Value = 2 } + }; var y = new WithComplexProperty { Name = "a", Value = 1, ComplexType = x.ComplexType }; var result = this.EqualMethod(x, y, ReferenceHandling.Structural); Assert.AreEqual(true, result); @@ -115,17 +142,17 @@ public void WithComplexReferenceWhenSame() public void WithComplexReferenceWhenNotSame() { var x = new WithComplexProperty - { - Name = "a", - Value = 1, - ComplexType = new ComplexType { Name = "b", Value = 2 } - }; + { + Name = "a", + Value = 1, + ComplexType = new ComplexType { Name = "b", Value = 2 } + }; var y = new WithComplexProperty - { - Name = "a", - Value = 1, - ComplexType = new ComplexType { Name = "b", Value = 2 } - }; + { + Name = "a", + Value = 1, + ComplexType = new ComplexType { Name = "b", Value = 2 } + }; var result = this.EqualMethod(x, y, ReferenceHandling.Structural); Assert.AreEqual(true, result); @@ -240,13 +267,13 @@ public void WithListOfComplexPropertyToLonger() { var source = new WithListProperty { Items = { new ComplexType("a", 1) } }; var target = new WithListProperty - { - Items = + { + Items = { new ComplexType("a", 1), new ComplexType("a", 1) } - }; + }; var result = this.EqualMethod(source, target, ReferenceHandling.Structural); Assert.AreEqual(false, result); } diff --git a/Gu.State.Tests/EqualByTests/EqualByTypes.cs b/Gu.State.Tests/EqualByTests/EqualByTypes.cs index 685cef92..1fd2eee2 100644 --- a/Gu.State.Tests/EqualByTests/EqualByTypes.cs +++ b/Gu.State.Tests/EqualByTests/EqualByTypes.cs @@ -599,5 +599,20 @@ public override int GetHashCode() return this.HashValue; } } + + public abstract class BaseClass + { + public double BaseValue { get; set; } + } + + public class Derived1 : BaseClass + { + public double Derived1Value { get; set; } + } + + public class Derived2 : BaseClass + { + public double Derived2Value { get; set; } + } } } diff --git a/Gu.State.Tests/Gu.State.Tests.csproj b/Gu.State.Tests/Gu.State.Tests.csproj index 51dcca0a..cbf4ea6f 100644 --- a/Gu.State.Tests/Gu.State.Tests.csproj +++ b/Gu.State.Tests/Gu.State.Tests.csproj @@ -183,6 +183,7 @@ + diff --git a/Gu.State.Tests/Track/Dirty/DirtyTrackerTests.WithInheritance.cs b/Gu.State.Tests/Track/Dirty/DirtyTrackerTests.WithInheritance.cs new file mode 100644 index 00000000..b3866f83 --- /dev/null +++ b/Gu.State.Tests/Track/Dirty/DirtyTrackerTests.WithInheritance.cs @@ -0,0 +1,38 @@ +namespace Gu.State.Tests +{ + using NUnit.Framework; + + using static DirtyTrackerTypes; + + public partial class DirtyTrackerTests + { + public class WithInheritance + { + [Test] + public void NotDirtyWhenSameType() + { + var x = new With(); + var y = new With(); + using (var tracker = Track.IsDirty(x, y)) + { + x.Value = new Derived2(); + y.Value = new Derived2(); + Assert.AreEqual(false, tracker.IsDirty); + } + } + + [Test] + public void DirtyWhenDifferentTypes() + { + var x = new With(); + var y = new With(); + using (var tracker = Track.IsDirty(x, y)) + { + x.Value = new Derived2(); + y.Value = new Derived1(); + Assert.AreEqual(true, tracker.IsDirty); + } + } + } + } +} \ No newline at end of file diff --git a/Gu.State.Tests/Track/Dirty/DirtyTrackerTypes.cs b/Gu.State.Tests/Track/Dirty/DirtyTrackerTypes.cs index 31080641..df13eb96 100644 --- a/Gu.State.Tests/Track/Dirty/DirtyTrackerTypes.cs +++ b/Gu.State.Tests/Track/Dirty/DirtyTrackerTypes.cs @@ -634,5 +634,60 @@ public virtual void OnPropertyChanged([CallerMemberName] string propertyName = n this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } } + + public abstract class BaseClass : INotifyPropertyChanged + { + private double baseDouble; + public event PropertyChangedEventHandler PropertyChanged; + + public double BaseValue + { + get { return this.baseDouble; } + set + { + if (value.Equals(this.baseDouble)) return; + this.baseDouble = value; + this.OnPropertyChanged(); + } + } + + [NotifyPropertyChangedInvocator] + protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) + { + this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } + } + + public class Derived1 : BaseClass + { + private double derived1Value; + + public double Derived1Value + { + get { return this.derived1Value; } + set + { + if (value.Equals(this.derived1Value)) return; + this.derived1Value = value; + this.OnPropertyChanged(); + } + } + } + + public class Derived2 : BaseClass + { + private double derived2Value; + + public double Derived2Value + { + get { return this.derived2Value; } + set + { + if (value.Equals(this.derived2Value)) return; + this.derived2Value = value; + this.OnPropertyChanged(); + } + } + } } } \ No newline at end of file diff --git a/Gu.State/Track/Dirty/DirtyTrackerNode.cs b/Gu.State/Track/Dirty/DirtyTrackerNode.cs index 3c85d213..6aa05350 100644 --- a/Gu.State/Track/Dirty/DirtyTrackerNode.cs +++ b/Gu.State/Track/Dirty/DirtyTrackerNode.cs @@ -177,6 +177,11 @@ private static bool IsTrackablePair(object x, object y, PropertiesSettings setti return false; } + if (x.GetType() != y.GetType()) + { + return false; + } + return !settings.IsImmutable(x.GetType()) && !settings.IsImmutable(y.GetType()); }