Skip to content

Commit

Permalink
Add Length validator (#44)
Browse files Browse the repository at this point in the history
  • Loading branch information
viceroypenguin authored May 30, 2024
1 parent 4a329a3 commit 3c43b40
Show file tree
Hide file tree
Showing 5 changed files with 101 additions and 13 deletions.
35 changes: 35 additions & 0 deletions src/Immediate.Validations.Shared/Validators/LengthAttribute.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
using System.Diagnostics.CodeAnalysis;

namespace Immediate.Validations.Shared;

/// <summary>
/// Applied to a <see cref="string"/> property to indicate that the value should have a length of exactly <paramref
/// name="length"/>.
/// </summary>
/// <param name="length">
/// The maximum length of the <see cref="string"/>.
/// </param>
public sealed class LengthAttribute(
[TargetType]
object length
) : ValidatorAttribute
{
/// <summary>
/// Validates that the <see cref="string"/> has a length of exactly <paramref name="length"/>.
/// </summary>
/// <param name="target">
/// The value to validate.
/// </param>
/// <param name="length">
/// The valid length for the string <paramref name="target"/>.
/// </param>
/// <returns>
/// A <see cref="ValueTuple{T1, T2}"/> indicating whether the property is valid or not, along with an error
/// message if the property is not valid.
/// </returns>
[SuppressMessage("Design", "CA1062:Validate arguments of public methods", Justification = "Will already by validated by IV first.")]
public static (bool Invalid, string? Message) ValidateProperty(string target, int length) =>
target.Length == length
? default
: (true, $"String is of length '{target.Length}', which is {(target.Length < length ? "shorter" : "longer")} than the allowed length of '{length}'.");
}
9 changes: 0 additions & 9 deletions src/Immediate.Validations.Shared/Validators/MatchAttribute.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,6 @@ public sealed class MatchAttribute(
object? regex = null
) : ValidatorAttribute
{
/// <summary>
///
/// </summary>
public object? Expr { get; } = expr;
/// <summary>
///
/// </summary>
public object? Regex { get; } = regex;

/// <summary>
/// Validates that the <see cref="string"/> matches a particular <see cref="Regex"/> pattern.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@ object length
) : ValidatorAttribute
{
/// <summary>
/// Validates that the <see cref="string"/> is less than <paramref name="length"/>.
/// Validates that the value should have a length at most <paramref name="length"/>.
/// </summary>
/// <param name="target">
/// The value to validate.
/// </param>
/// <param name="length">
/// The maximum valid length for the string <paramref name="target"/>.
/// The maximum valid length for the string <paramref name="target"/>.
/// </param>
/// <returns>
/// A <see cref="ValueTuple{T1, T2}"/> indicating whether the property is valid or not, along with an error
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@ object length
{

/// <summary>
/// Validates that the <see cref="string"/> is less than <paramref name="length"/>.
/// Validates that the value should have a length at least <paramref name="length"/>.
/// </summary>
/// <param name="target">
/// The value to validate.
/// </param>
/// <param name="length">
/// The minimum valid length for the string <paramref name="target"/>.
/// The minimum valid length for the string <paramref name="target"/>.
/// </param>
/// <returns>
/// A <see cref="ValueTuple{T1, T2}"/> indicating whether the property is valid or not, along with an error
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
using Immediate.Validations.Shared;
using Xunit;

namespace Immediate.Validations.FunctionalTests.Validators;

public sealed partial class LengthTests
{
[Validate]
public partial record StringRecord : IValidationTarget<StringRecord>
{
[Length(12)]
public required string StringValue { get; init; }
}

[Fact]
public void LengthWhenShort()
{
var instance = new StringRecord { StringValue = "Hello" };

var errors = StringRecord.Validate(instance);

Assert.Equal(
[
new()
{
PropertyName = nameof(StringRecord.StringValue),
ErrorMessage = "String is of length '5', which is shorter than the allowed length of '12'.",
}
],
errors
);
}

[Fact]
public void LengthWhenEqual()
{
var instance = new StringRecord { StringValue = "Hello World!" };

var errors = StringRecord.Validate(instance);

Assert.Empty(errors);
}

[Fact]
public void LengthWhenLong()
{
var instance = new StringRecord { StringValue = "Hello World! Hello World! Hello World!" };

var errors = StringRecord.Validate(instance);

Assert.Equal(
[
new()
{
PropertyName = nameof(StringRecord.StringValue),
ErrorMessage = "String is of length '38', which is longer than the allowed length of '12'.",
}
],
errors
);
}
}

0 comments on commit 3c43b40

Please sign in to comment.