diff --git a/src/Papst.EventStore/Aggregation/EventAggregatorBase.cs b/src/Papst.EventStore/Aggregation/EventAggregatorBase.cs index 72503fc..6465962 100644 --- a/src/Papst.EventStore/Aggregation/EventAggregatorBase.cs +++ b/src/Papst.EventStore/Aggregation/EventAggregatorBase.cs @@ -42,6 +42,20 @@ protected void Update(TProperty? value, Action setter) whe } } + /// + /// Executes the action when .HasValue is true + /// + /// + /// + /// + protected void Update(TProperty? value, Action setter) where TProperty : struct + { + if (value.HasValue) + { + setter.Invoke(value); + } + } + /// /// Executes the action when is not null /// @@ -71,6 +85,21 @@ protected void SetIfNotNull(Action setter, TProperty? valu } } + /// + /// This overload is for nullable value types. + /// Executes the action when .HasValue is true. + /// + /// + /// + /// + protected void SetIfNotNull(Action setter, TProperty? value) where TProperty : struct + { + if (value.HasValue) + { + setter(value); + } + } + /// /// Returns the given Entity wrapped in a Task /// diff --git a/tests/Papst.EventStore.Tests/EventAggregatorBaseTests.cs b/tests/Papst.EventStore.Tests/EventAggregatorBaseTests.cs index 8be9c84..67f753d 100644 --- a/tests/Papst.EventStore.Tests/EventAggregatorBaseTests.cs +++ b/tests/Papst.EventStore.Tests/EventAggregatorBaseTests.cs @@ -17,7 +17,7 @@ public void SetIfNotNull_ShouldInvokeSetter_WhenNullableStructHasValue() int result = 0; int? value = 42; - _sut.CallSetIfNotNull(v => result = v, value); + _sut.CallSetIfNotNull(v => result = v, value); result.ShouldBe(42); } @@ -28,7 +28,7 @@ public void SetIfNotNull_ShouldNotInvokeSetter_WhenNullableStructIsNull() int result = 0; int? value = null; - _sut.CallSetIfNotNull(v => result = v, value); + _sut.CallSetIfNotNull(v => result = v, value); result.ShouldBe(0); } @@ -39,7 +39,7 @@ public void SetIfNotNull_ShouldInvokeSetter_WhenNullableDateTimeHasValue() DateTime result = default; DateTime? value = new DateTime(2025, 1, 1, 0, 0, 0, DateTimeKind.Utc); - _sut.CallSetIfNotNull(v => result = v, value); + _sut.CallSetIfNotNull(v => result = v, value); result.ShouldBe(new DateTime(2025, 1, 1, 0, 0, 0, DateTimeKind.Utc)); } @@ -50,7 +50,7 @@ public void SetIfNotNull_ShouldNotInvokeSetter_WhenNullableDateTimeIsNull() DateTime result = default; DateTime? value = null; - _sut.CallSetIfNotNull(v => result = v, value); + _sut.CallSetIfNotNull(v => result = v, value); result.ShouldBe(default(DateTime)); } @@ -62,7 +62,7 @@ public void SetIfNotNull_ShouldInvokeSetter_WhenNullableGuidHasValue() Guid expected = Guid.NewGuid(); Guid? value = expected; - _sut.CallSetIfNotNull(v => result = v, value); + _sut.CallSetIfNotNull(v => result = v, value); result.ShouldBe(expected); } @@ -73,7 +73,74 @@ public void SetIfNotNull_ShouldNotInvokeSetter_WhenNullableGuidIsNull() Guid result = Guid.Empty; Guid? value = null; - _sut.CallSetIfNotNull(v => result = v, value); + _sut.CallSetIfNotNull(v => result = v, value); + + result.ShouldBe(Guid.Empty); + } + + [Fact] + public void SetIfNotNull_ShouldInvokeSetterForNullable_WhenNullableStructHasValue() + { + int? result = 0; + int? value = 42; + + _sut.CallSetIfNotNull((Action)(v => result = v), value); + + result.ShouldBe(42); + } + + [Fact] + public void SetIfNotNull_ShouldNotInvokeSetterForNullable_WhenNullableStructIsNull() + { + int? result = 0; + int? value = null; + + _sut.CallSetIfNotNull((Action)(v => result = v), value); + + result.ShouldBe(0); + } + + [Fact] + public void SetIfNotNull_ShouldInvokeSetterForNullable_WhenNullableDateTimeHasValue() + { + DateTime? result = null; + DateTime? value = new DateTime(2025, 1, 1, 0, 0, 0, DateTimeKind.Utc); + + _sut.CallSetIfNotNull((Action)(v => result = v), value); + + result.ShouldBe(new DateTime(2025, 1, 1, 0, 0, 0, DateTimeKind.Utc)); + } + + [Fact] + public void SetIfNotNull_ShouldNotInvokeSetterForNullable_WhenNullableDateTimeIsNull() + { + DateTime? result = default(DateTime); + DateTime? value = null; + + _sut.CallSetIfNotNull((Action)(v => result = v), value); + + result.ShouldBe(default(DateTime)); + } + + [Fact] + public void SetIfNotNull_ShouldInvokeSetterForNullable_WhenNullableGuidHasValue() + { + Guid? result = Guid.Empty; + Guid expected = new Guid(); + Guid? value = expected; + + _sut.CallSetIfNotNull((Action)(v => result = v), value); + + result.ShouldBe(expected); + } + + [Fact] + public void SetIfNotNull_ShouldNotInvokeSetterForNullable_WhenNullableGuidIsNull() + { + Guid? result = Guid.Empty; + Guid? value = null; + + _sut.CallSetIfNotNull((Action)(v => result = v), value); result.ShouldBe(Guid.Empty); } @@ -84,7 +151,7 @@ public void Update_ShouldInvokeSetter_WhenNullableStructHasValue() int result = 0; int? value = 42; - _sut.CallUpdate(value, v => result = v); + _sut.CallUpdate(value, v => result = v); result.ShouldBe(42); } @@ -95,7 +162,7 @@ public void Update_ShouldNotInvokeSetter_WhenNullableStructIsNull() int result = 0; int? value = null; - _sut.CallUpdate(value, v => result = v); + _sut.CallUpdate(value, v => result = v); result.ShouldBe(0); } @@ -106,7 +173,7 @@ public void Update_ShouldInvokeSetter_WhenNullableDateTimeHasValue() DateTime result = default; DateTime? value = new DateTime(2025, 1, 1, 0, 0, 0, DateTimeKind.Utc); - _sut.CallUpdate(value, v => result = v); + _sut.CallUpdate(value, v => result = v); result.ShouldBe(new DateTime(2025, 1, 1, 0, 0, 0, DateTimeKind.Utc)); } @@ -117,7 +184,7 @@ public void Update_ShouldNotInvokeSetter_WhenNullableDateTimeIsNull() DateTime result = default; DateTime? value = null; - _sut.CallUpdate(value, v => result = v); + _sut.CallUpdate(value, v => result = v); result.ShouldBe(default(DateTime)); } @@ -129,7 +196,7 @@ public void Update_ShouldInvokeSetter_WhenNullableGuidHasValue() Guid expected = Guid.NewGuid(); Guid? value = expected; - _sut.CallUpdate(value, v => result = v); + _sut.CallUpdate(value, v => result = v); result.ShouldBe(expected); } @@ -140,7 +207,74 @@ public void Update_ShouldNotInvokeSetter_WhenNullableGuidIsNull() Guid result = Guid.Empty; Guid? value = null; - _sut.CallUpdate(value, v => result = v); + _sut.CallUpdate(value, v => result = v); + + result.ShouldBe(Guid.Empty); + } + + [Fact] + public void Update_ShouldInvokeSetterForNullable_WhenNullableStructHasValue() + { + int? result = 0; + int? value = 42; + + _sut.CallUpdate(value,(Action)(v => result = v)); + + result.ShouldBe(42); + } + + [Fact] + public void Update_ShouldNotInvokeSetterForNullable_WhenNullableStructIsNull() + { + int? result = 0; + int? value = null; + + _sut.CallUpdate(value, (Action)(v => result = v)); + + result.ShouldBe(0); + } + + [Fact] + public void Update_ShouldInvokeSetterForNullable_WhenNullableDateTimeHasValue() + { + DateTime? result = null; + DateTime? value = new DateTime(2025, 1, 1, 0, 0, 0, DateTimeKind.Utc); + + _sut.CallUpdate(value, (Action)(v => result = v)); + + result.ShouldBe(new DateTime(2025, 1, 1, 0, 0, 0, DateTimeKind.Utc)); + } + + [Fact] + public void Update_ShouldNotInvokeSetterForNullable_WhenNullableDateTimeIsNull() + { + DateTime? result = default(DateTime); + DateTime? value = null; + + _sut.CallUpdate(value, (Action)(v => result = v)); + + result.ShouldBe(default(DateTime)); + } + + [Fact] + public void Update_ShouldInvokeSetterForNullable_WhenNullableGuidHasValue() + { + Guid? result = Guid.Empty; + Guid expected = Guid.NewGuid(); + Guid? value = expected; + + _sut.CallUpdate(value, (Action)(v => result = v)); + + result.ShouldBe(expected); + } + + [Fact] + public void Update_ShouldNotInvokeSetterForNullable_WhenNullableGuidIsNull() + { + Guid? result = Guid.Empty; + Guid? value = null; + + _sut.CallUpdate(value, (Action)(v => result = v)); result.ShouldBe(Guid.Empty); } @@ -159,8 +293,14 @@ private class TestAggregator : EventAggregatorBase public void CallSetIfNotNull(Action setter, T? value) where T : struct => SetIfNotNull(setter, value); - + + public void CallSetIfNotNull(Action setter, T? value) where T : struct + => SetIfNotNull(setter, value); + public void CallUpdate(T? value, Action setter) where T : struct => Update(value, setter); + + public void CallUpdate(T? value, Action setter) where T : struct + => Update(value, setter); } }