Skip to content

Commit

Permalink
Impl SortedMoneySet.TransformValues with nullable outputs, add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
mikernet committed Mar 7, 2024
1 parent 22fe1c2 commit c5435f4
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 5 deletions.
31 changes: 30 additions & 1 deletion Source/Singulink.Globalization.Currency/SortedMoneySet.cs
Original file line number Diff line number Diff line change
Expand Up @@ -409,6 +409,8 @@ public void TransformValues(Func<Money, decimal> transform)
if (Count == 0)
return;

// TODO: Optimize if no values change.

foreach (var kvp in _amountLookup.ToList())
{
decimal newAmount = transform(new Money(kvp.Value, kvp.Key));
Expand All @@ -420,6 +422,31 @@ public void TransformValues(Func<Money, decimal> transform)
}
}

/// <summary>
/// Applies the specified transformation to each value's amount in this set. Values transformed to a <see langword="null"/> amount are removed.
/// </summary>
public void TransformValues(Func<Money, decimal?> transform)
{
if (Count == 0)
return;

// TODO: Optimize if no values change.

foreach (var kvp in _amountLookup.ToList())
{
decimal? newAmountOrNull = transform(new Money(kvp.Value, kvp.Key));

if (newAmountOrNull is not decimal newAmount)
{
_amountLookup.Remove(kvp.Key);
}
else if (newAmount != kvp.Value)
{
_amountLookup[kvp.Key] = newAmount;
}
}
}

/// <summary>
/// Applies the specified transformation to each value's amount in this set.
/// </summary>
Expand All @@ -428,6 +455,8 @@ public void TransformAmounts(Func<decimal, decimal> transform)
if (Count == 0)
return;

// TODO: Optimize if no values change.

foreach (var kvp in _amountLookup.ToList())
{
decimal oldAmount = kvp.Value;
Expand Down Expand Up @@ -472,7 +501,7 @@ public int TrimZeroAmounts()
{
List<Currency> currenciesToRemove = null;

foreach (var kvp in _amountLookup.ToList())
foreach (var kvp in _amountLookup)
{
if (kvp.Value == 0)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,25 +11,56 @@ public class TransformValues
private readonly SortedMoneySet _set = ImmutableSet.ToSet();

[TestMethod]
public void AllAmountsTransformed_UpdatesValues()
public void NonNullOutput_AllAmountsTransformed_UpdatesValue()
{
_set.TransformValues(x => x.Amount * 2);
_set.Count.ShouldBe(3);
_set.ShouldBe([new(200m, "USD"), new(100m, "CAD"), new(50m, "EUR")]);
}

[TestMethod]
public void IdentityTransform_NoChange()
public void NonNullOutput_IdentityTransform_NoChange()
{
_set.TransformValues(x => x.Amount);
_set.ShouldBe(ImmutableSet);
}

[TestMethod]
public void EmptySet_NoChange()
public void NonNullOutput_EmptySet_NoChange()
{
SortedMoneySet emptySet = [];
emptySet.TransformValues(x => x.Amount * 2);
emptySet.Count.ShouldBe(0);
}
}

[TestMethod]
public void NullableOutput_AllAmountsTransformed_UpdatesValue()
{
_set.TransformValues(x => (decimal?)x.Amount * 2);
_set.Count.ShouldBe(3);
_set.ShouldBe([new(200m, "USD"), new(100m, "CAD"), new(50m, "EUR")]);
}

[TestMethod]
public void NullableOutput_IdentityTransform_NoChange()
{
_set.TransformValues(x => (decimal?)x.Amount);
_set.ShouldBe(ImmutableSet);
}

[TestMethod]
public void NullableOutput_EmptySet_NoChange()
{
SortedMoneySet emptySet = [];
emptySet.TransformValues(x => (decimal?)x.Amount * 2);
emptySet.Count.ShouldBe(0);
}

[TestMethod]
public void NullableOutput_NullTransform_RemovesNullValues()
{
_set.TransformValues(x => x.Amount == 100m ? null : x.Amount);
_set.Count.ShouldBe(2);
_set.ShouldBe([new(50m, "CAD"), new(25m, "EUR")]);
}
}

0 comments on commit c5435f4

Please sign in to comment.