diff --git a/tests/DotValid.PropertyTests/AllocationProperties.cs b/tests/DotValid.PropertyTests/AllocationProperties.cs
index cdd76dd..d0a39aa 100644
--- a/tests/DotValid.PropertyTests/AllocationProperties.cs
+++ b/tests/DotValid.PropertyTests/AllocationProperties.cs
@@ -10,12 +10,13 @@ namespace DotValid.PropertyTests;
///
///
/// Skipped in Debug builds (see ); CI runs them in Release.
-/// Not covered on purpose: creating an invalid case, mapping its errors or accumulating errors (each builds an array of
-/// errors), Equals(object) (boxes
-/// its argument), and validated is null / is not null on an initialized validation (the compiler reads the
-/// union's Value, which boxes the case). Reading an existing invalid case allocates nothing. Sequences
-/// (Sequence, Traverse, Values, Errors, Partition) allocate like LINQ (enumerators
-/// and the lists they return; see CollectionBenchmarks).
+/// Every public member has a line here or is listed now (V9 audit, M7). Not covered on purpose: ToString (it
+/// builds a string); creating an invalid case, mapping its errors or accumulating errors, including
+/// Ensure/Check when the predicate fails and FromNullable for (each builds
+/// an array of errors); Equals(object) (boxes its argument); validated is null / is not null on an
+/// initialized validation (the compiler reads the union's Value, which boxes the case); and sequences
+/// (Sequence, Traverse, Values, Errors, Partition), which allocate like LINQ (see
+/// CollectionBenchmarks). Reading and comparing an existing invalid case allocates nothing.
///
public sealed class AllocationProperties
{
@@ -92,6 +93,19 @@ public void Combining_valid_validations_allocates_nothing(int value, int other)
Allocations.AssertNone("Apply", () => _ = function.Apply(second));
Allocations.AssertNone("Combine(2)", () => _ = Validated.Combine(validated, second, static (a, b) => a + b));
Allocations.AssertNone("Combine(3)", () => _ = Validated.Combine(validated, second, validated, static (a, b, c) => a + b + c));
+ Allocations.AssertNone("Combine(4)", () => _ = Validated.Combine(validated, second, validated, second, static (a, b, c, d) => a + b + c + d));
+ Allocations.AssertNone(
+ "Combine(5)",
+ () => _ = Validated.Combine(validated, second, validated, second, validated, static (a, b, c, d, e) => a + b + c + d + e));
+ Allocations.AssertNone(
+ "Combine(6)",
+ () => _ = Validated.Combine(
+ validated, second, validated, second, validated, second, static (a, b, c, d, e, f) => a + b + c + d + e + f));
+ Allocations.AssertNone(
+ "Combine(7)",
+ () => _ = Validated.Combine(
+ validated, second, validated, second, validated, second, validated,
+ static (a, b, c, d, e, f, g) => a + b + c + d + e + f + g));
Allocations.AssertNone(
"Combine(8)",
() => _ = Validated.Combine(
@@ -109,6 +123,7 @@ public void Building_blocks_on_the_valid_path_allocate_nothing(int value)
Allocations.AssertNone("FromNullable (present)", () => _ = Validated.FromNullable(present, -1));
Allocations.AssertNone("FromNullable(factory) (present)", () => _ = Validated.FromNullable(present, static () => -1));
Allocations.AssertNone("FromNullable (reference)", () => _ = Validated.FromNullable(Text, -1));
+ Allocations.AssertNone("FromNullable(factory) (reference)", () => _ = Validated.FromNullable(Text, static () => -1));
Allocations.AssertNone("ValidationError", () => _ = new ValidationError("Name", "is empty"));
}
@@ -126,6 +141,28 @@ public void Async_members_with_completed_tasks_allocate_nothing(Validated _ = Validated.CombineAsync(CompletedValidOne, CompletedValidOne, static (a, b) => a + b).IsCompleted);
+ Allocations.AssertNone(
+ "CombineAsync(3)",
+ () => _ = Validated.CombineAsync(CompletedValidOne, CompletedValidOne, CompletedValidOne, static (a, b, c) => a + b + c).IsCompleted);
+ Allocations.AssertNone(
+ "CombineAsync(4)",
+ () => _ = Validated.CombineAsync(
+ CompletedValidOne, CompletedValidOne, CompletedValidOne, CompletedValidOne, static (a, b, c, d) => a + b + c + d).IsCompleted);
+ Allocations.AssertNone(
+ "CombineAsync(5)",
+ () => _ = Validated.CombineAsync(
+ CompletedValidOne, CompletedValidOne, CompletedValidOne, CompletedValidOne, CompletedValidOne,
+ static (a, b, c, d, e) => a + b + c + d + e).IsCompleted);
+ Allocations.AssertNone(
+ "CombineAsync(6)",
+ () => _ = Validated.CombineAsync(
+ CompletedValidOne, CompletedValidOne, CompletedValidOne, CompletedValidOne, CompletedValidOne, CompletedValidOne,
+ static (a, b, c, d, e, f) => a + b + c + d + e + f).IsCompleted);
+ Allocations.AssertNone(
+ "CombineAsync(7)",
+ () => _ = Validated.CombineAsync(
+ CompletedValidOne, CompletedValidOne, CompletedValidOne, CompletedValidOne, CompletedValidOne, CompletedValidOne,
+ CompletedValidOne, static (a, b, c, d, e, f, g) => a + b + c + d + e + f + g).IsCompleted);
Allocations.AssertNone(
"CombineAsync(8)",
() => _ = Validated.CombineAsync(
@@ -142,6 +179,41 @@ public void Comparing_allocates_nothing(Validated validated, Validated
Allocations.AssertNone("!=", () => _ = validated != other);
Allocations.AssertNone("GetHashCode", () => _ = validated.GetHashCode());
Allocations.AssertNone("Valid ==", () => _ = new Valid(1) == new Valid(2));
+ Allocations.AssertNone("Valid !=", () => _ = new Valid(1) != new Valid(2));
+ Allocations.AssertNone("Valid Equals", () => _ = new Valid(1).Equals(new Valid(2)));
+ Allocations.AssertNone("Valid GetHashCode", () => _ = new Valid(1).GetHashCode());
+ Allocations.AssertNone("Valid Value and Deconstruct", () =>
+ {
+ var success = new Valid(1);
+ success.Deconstruct(out var value);
+ _ = success.Value + value;
+ });
+ }
+
+ [Property(Skip = Allocations.SkipInDebug)]
+ public void Reading_and_comparing_existing_invalid_cases_allocates_nothing(int first, int second)
+ {
+ var failure = new Invalid(first, second);
+ var other = new Invalid(second);
+ var error = new ValidationError("Name", "is empty");
+ var otherError = new ValidationError("Age", "is negative");
+
+ Allocations.AssertNone("Invalid ==", () => _ = failure == other);
+ Allocations.AssertNone("Invalid !=", () => _ = failure != other);
+ Allocations.AssertNone("Invalid Equals", () => _ = failure.Equals(other));
+ Allocations.AssertNone("Invalid GetHashCode", () => _ = failure.GetHashCode());
+ Allocations.AssertNone("Invalid Errors and Deconstruct", () =>
+ {
+ failure.Deconstruct(out var errors);
+ _ = failure.Errors.Length + errors[0];
+ });
+ Allocations.AssertNone("ValidationError ==", () => _ = error == otherError);
+ Allocations.AssertNone("ValidationError GetHashCode", () => _ = error.GetHashCode());
+ Allocations.AssertNone("ValidationError Deconstruct", () =>
+ {
+ var (property, message) = error;
+ _ = property.Length + message.Length;
+ });
}
private const string? Text = "text";