From 7b916722321cde4a76ea62a3d53cc58ce7306741 Mon Sep 17 00:00:00 2001 From: Guillaume Caya-Letourneau Date: Tue, 31 Oct 2023 10:16:37 -0400 Subject: [PATCH] Review fixes --- README.md | 3 ++- ... => ContainsNonEmptyGuidAttributeTests.cs} | 20 ++++++++++--------- ...te.cs => ContainsNonEmptyGuidAttribute.cs} | 8 ++++---- .../PublicAPI.Shipped.txt | 6 +++--- 4 files changed, 20 insertions(+), 17 deletions(-) rename src/Workleap.ComponentModel.DataAnnotations.Tests/{ContainsValidGuidAttributeTests.cs => ContainsNonEmptyGuidAttributeTests.cs} (82%) rename src/Workleap.ComponentModel.DataAnnotations/{ContainsValidGuidAttribute.cs => ContainsNonEmptyGuidAttribute.cs} (80%) diff --git a/README.md b/README.md index fc5c21d..15839a1 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,8 @@ The most useful validation attribute here is probably `ValidatePropertiesAttribu | Attribute | Description | |-------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | `GuidAttribute` | Validates that a string property is a well-formatted GUID with an optional format | -| `NotEmptyAttribute` | Validate that an enumerable property is not empty | +| `ContainsNonEmptyGuidAttribute` | Validates that a Guid enumerable property contains at least one non-empty Guid | +| `NotEmptyAttribute` | Validates that an enumerable property is not empty | | `ValidatePropertiesAttribute` | Validates **all properties of a complex type property** (nested object validation) | | `TimeSpanAttribute` | Validates that a string property is a well-formatted TimeSpan with an optional format | | `UrlOfKindAttribute` | Validates that a string or `Uri` property is a well-formatted url of the specified `UriKind` | diff --git a/src/Workleap.ComponentModel.DataAnnotations.Tests/ContainsValidGuidAttributeTests.cs b/src/Workleap.ComponentModel.DataAnnotations.Tests/ContainsNonEmptyGuidAttributeTests.cs similarity index 82% rename from src/Workleap.ComponentModel.DataAnnotations.Tests/ContainsValidGuidAttributeTests.cs rename to src/Workleap.ComponentModel.DataAnnotations.Tests/ContainsNonEmptyGuidAttributeTests.cs index 0dd34cc..c05b1b1 100644 --- a/src/Workleap.ComponentModel.DataAnnotations.Tests/ContainsValidGuidAttributeTests.cs +++ b/src/Workleap.ComponentModel.DataAnnotations.Tests/ContainsNonEmptyGuidAttributeTests.cs @@ -6,13 +6,13 @@ namespace Workleap.ComponentModel.DataAnnotations.Tests; -public class ContainsValidGuidAttributeTests +public sealed class ContainsNonEmptyGuidAttributeTests { [Theory] [ClassData(typeof(ValidData))] public void Given_ValidGuids_When_Validate_Then_Valid(object? inputs) { - var attr = new ContainsValidGuidAttribute(); + var attr = new ContainsNonEmptyGuidAttribute(); Assert.True(attr.IsValid(inputs)); } @@ -20,7 +20,7 @@ public void Given_ValidGuids_When_Validate_Then_Valid(object? inputs) [ClassData(typeof(InvalidData))] public void Given_InvalidGuids_When_Validate_Then_Invalid(object? inputs) { - var attr = new ContainsValidGuidAttribute(); + var attr = new ContainsNonEmptyGuidAttribute(); Assert.False(attr.IsValid(inputs)); } @@ -28,7 +28,7 @@ public void Given_InvalidGuids_When_Validate_Then_Invalid(object? inputs) public void Validator_TryValidateObject_Returns_The_Expected_Error_Message_When_Validation_Fails() { var something = new SomeClass(); - var expectedErrorMessage = string.Format(CultureInfo.InvariantCulture, ContainsValidGuidAttribute.ErrorMessageFormat, nameof(SomeClass.Values)); + var expectedErrorMessage = string.Format(CultureInfo.InvariantCulture, ContainsNonEmptyGuidAttribute.ErrorMessageFormat, nameof(SomeClass.Values)); var results = new List(); var context = new ValidationContext(something, serviceProvider: null, items: null); @@ -40,10 +40,11 @@ public void Validator_TryValidateObject_Returns_The_Expected_Error_Message_When_ Assert.Equal(expectedErrorMessage, result.ErrorMessage); } - private class ValidData : IEnumerable + private class ValidData : IEnumerable { - public IEnumerator GetEnumerator() + public IEnumerator GetEnumerator() { + yield return new object?[] { null }; yield return new object[] { new Guid[] { new("f8daff85-4393-42ae-9ab5-8620ab20c8da") } }; yield return new object[] { new string[] { "d78b48f9-37b8-47dd-8e47-0325dd3e7899" } }; yield return new object[] { new Guid[] { default, new("846398d2-416d-4f05-86b0-431e11117abc") } }; @@ -57,9 +58,9 @@ public IEnumerator GetEnumerator() IEnumerator IEnumerable.GetEnumerator() => this.GetEnumerator(); } - private class InvalidData : IEnumerable + private class InvalidData : IEnumerable { - public IEnumerator GetEnumerator() + public IEnumerator GetEnumerator() { yield return new object[] { new Guid[] { default } }; yield return new object[] { new Guid?[] { default } }; @@ -67,6 +68,7 @@ public IEnumerator GetEnumerator() yield return new object[] { new string?[] { default } }; yield return new object[] { new Guid[] { Guid.Empty } }; yield return new object[] { new string[] { "00000000-0000-0000-0000-000000000000" } }; + yield return new object[] { new int[] { 0 } }; } IEnumerator IEnumerable.GetEnumerator() => this.GetEnumerator(); @@ -74,7 +76,7 @@ public IEnumerator GetEnumerator() private class SomeClass { - [ContainsValidGuid] + [ContainsNonEmptyGuid] public Guid?[] Values { get; set; } = Array.Empty(); } } \ No newline at end of file diff --git a/src/Workleap.ComponentModel.DataAnnotations/ContainsValidGuidAttribute.cs b/src/Workleap.ComponentModel.DataAnnotations/ContainsNonEmptyGuidAttribute.cs similarity index 80% rename from src/Workleap.ComponentModel.DataAnnotations/ContainsValidGuidAttribute.cs rename to src/Workleap.ComponentModel.DataAnnotations/ContainsNonEmptyGuidAttribute.cs index e8b2549..9b82591 100644 --- a/src/Workleap.ComponentModel.DataAnnotations/ContainsValidGuidAttribute.cs +++ b/src/Workleap.ComponentModel.DataAnnotations/ContainsNonEmptyGuidAttribute.cs @@ -6,17 +6,17 @@ namespace Workleap.ComponentModel.DataAnnotations; [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter)] -public sealed class ContainsValidGuidAttribute : ValidationAttribute +public sealed class ContainsNonEmptyGuidAttribute : ValidationAttribute { - internal const string ErrorMessageFormat = "The field {0} must be an enumerable that contains at least one valid GUID"; + internal const string ErrorMessageFormat = "The field {0} must be an collection that contains at least one non-empty GUID"; - public ContainsValidGuidAttribute() : base(ErrorMessageFormat) + public ContainsNonEmptyGuidAttribute() : base(ErrorMessageFormat) { } public override bool IsValid(object? value) => value switch { - null => false, + null => true, IEnumerable enumerable => enumerable.Any(this.IsValidGuid), IEnumerable enumerable => enumerable.Any(x => x != null && this.IsValidGuid(x.Value)), IEnumerable enumerable => enumerable.Any(this.IsValidGuid), diff --git a/src/Workleap.ComponentModel.DataAnnotations/PublicAPI.Shipped.txt b/src/Workleap.ComponentModel.DataAnnotations/PublicAPI.Shipped.txt index f3b5afc..4f4fb8a 100644 --- a/src/Workleap.ComponentModel.DataAnnotations/PublicAPI.Shipped.txt +++ b/src/Workleap.ComponentModel.DataAnnotations/PublicAPI.Shipped.txt @@ -2,8 +2,8 @@ abstract Workleap.ComponentModel.DataAnnotations.TextBasedValidationAttribute.IsValid(string! value) -> bool Workleap.ComponentModel.DataAnnotations.ContainsAttribute Workleap.ComponentModel.DataAnnotations.ContainsAttribute.ContainsAttribute(string! text) -> void -Workleap.ComponentModel.DataAnnotations.ContainsValidGuidAttribute -Workleap.ComponentModel.DataAnnotations.ContainsValidGuidAttribute.ContainsValidGuidAttribute() -> void +Workleap.ComponentModel.DataAnnotations.ContainsNonEmptyGuidAttribute +Workleap.ComponentModel.DataAnnotations.ContainsNonEmptyGuidAttribute.ContainsNonEmptyGuidAttribute() -> void Workleap.ComponentModel.DataAnnotations.EndsWithAttribute Workleap.ComponentModel.DataAnnotations.EndsWithAttribute.EndsWithAttribute(string! text) -> void Workleap.ComponentModel.DataAnnotations.GuidAttribute @@ -45,7 +45,7 @@ Workleap.ComponentModel.DataAnnotations.UrlOfKindAttribute.Kind.get -> System.Ur Workleap.ComponentModel.DataAnnotations.UrlOfKindAttribute.UrlOfKindAttribute(System.UriKind kind) -> void Workleap.ComponentModel.DataAnnotations.ValidatePropertiesAttribute Workleap.ComponentModel.DataAnnotations.ValidatePropertiesAttribute.ValidatePropertiesAttribute() -> void -override Workleap.ComponentModel.DataAnnotations.ContainsValidGuidAttribute.IsValid(object? value) -> bool +override Workleap.ComponentModel.DataAnnotations.ContainsNonEmptyGuidAttribute.IsValid(object? value) -> bool override Workleap.ComponentModel.DataAnnotations.GuidAttribute.FormatErrorMessage(string! name) -> string! override Workleap.ComponentModel.DataAnnotations.GuidAttribute.IsValid(object? value) -> bool override Workleap.ComponentModel.DataAnnotations.NotEmptyAttribute.IsValid(object? value) -> bool