Skip to content
This repository has been archived by the owner on Jul 5, 2023. It is now read-only.

Commit

Permalink
Year implementation (#54)
Browse files Browse the repository at this point in the history
* Year implementation

* Tests

* Name convention

* Including YearTypeOptions

* Update src/Nox.Types/Types/Year/TypeOptions/YearTypeOptions.cs

Co-authored-by: Ricardo Rocha <rochar@users.noreply.github.com>

* Name consistent

* Change to FluentAssertions

* Tests changes

---------

Co-authored-by: Ricardo Rocha <rochar@users.noreply.github.com>
Co-authored-by: Denis Vieira dos Anjos <denis@Deniss-MacBook-Pro.local>
  • Loading branch information
3 people committed Jul 4, 2023
1 parent 09bc632 commit 24c34f2
Show file tree
Hide file tree
Showing 4 changed files with 195 additions and 5 deletions.
8 changes: 8 additions & 0 deletions src/Nox.Types.EntityFramework/Types/Year/YearConverter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;

namespace Nox.Types.EntityFramework.Types;

public class YearToUShortConverter : ValueConverter<Year, ushort>
{
public YearToUShortConverter() : base(year => year.Value, n => Year.From(n)) { }
}
11 changes: 11 additions & 0 deletions src/Nox.Types/Types/Year/TypeOptions/YearTypeOptions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@

namespace Nox.Types;

public class YearTypeOptions
{
public static readonly ushort DefaultMinValue= 1900;
public static readonly ushort DefaultMaxValue = 3000;
public ushort MinValue { get; set; } = DefaultMinValue;
public ushort MaxValue { get; set; } = DefaultMaxValue;
public bool AllowFutureOnly { get; set; } = false;
}
68 changes: 65 additions & 3 deletions src/Nox.Types/Types/Year/Year.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,71 @@
using System;

namespace Nox.Types;

/// <summary>
/// Represents a Nox <see cref="Year"/> type and value object.
/// </summary>
public sealed class Year : ValueObject<ushort, Year>
{
private YearTypeOptions _yearTypeOptions = new();

public Year() { Value = 0; }

/// <summary>
/// Represents a Nox <see cref="Year"/> type and value object.
/// Creates a new instance of <see cref="Year"/> using the specified <see cref="YearTypeOptions"/>
/// </summary>
/// <remarks>Placeholder, needs to be implemented</remarks>
public sealed class Year : ValueObject<ushort, Year>
/// <param name="value">The number to create the <see cref="Year"/> with</param>
/// <param name="options">The <see cref="YearTypeOptions"/> containing constraints for the value object</param>
/// <returns></returns>
/// <exception cref="ValidationException"></exception>
public static Year From(ushort value, YearTypeOptions options)
{
var newObject = new Year
{
Value = value,
_yearTypeOptions = options
};

var validationResult = newObject.Validate();

if (!validationResult.IsValid)
{
throw new TypeValidationException(validationResult.Errors);
}

return newObject;
}

/// <summary>
/// Validates the <see cref="Year"/> object.
/// </summary>
/// <returns>A validation result indicating whether the <see cref="Year"/> object is valid or not.</returns>
internal override ValidationResult Validate()
{
var result = base.Validate();

if (Value < _yearTypeOptions.MinValue)
{
result.Errors.Add(new ValidationFailure(nameof(Value), $"Could not create a Nox Year type as value {Value} is less than the minimum specified value of {_yearTypeOptions.MinValue}"));
}

if (Value > _yearTypeOptions.MaxValue)
{
result.Errors.Add(new ValidationFailure(nameof(Value), $"Could not create a Nox Year type a value {Value} is greater than the maximum specified value of {_yearTypeOptions.MaxValue}"));
}

if (_yearTypeOptions.AllowFutureOnly && Value < DateTime.Now.Year)
{
result.Errors.Add(new ValidationFailure(nameof(Value), $"Could not create a Nox Year type a value {Value} is less than the current year"));
}


return result;
}

/// <inheritdoc />
public override string ToString()
{
return Value.ToString("0000");
}
}
113 changes: 111 additions & 2 deletions tests/Nox.Types.Tests/Types/Year/YearTests.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,120 @@
// ReSharper disable once CheckNamespace
using FluentAssertions;

namespace Nox.Types.Tests.Types;

public class YearTests
{
[Fact]
public void When_Create_Should()
public void Year_Constructor_ReturnsSameValue()
{
var testYear = (ushort)1900;

var number = Year.From(testYear);

number.Value.Should().Be(testYear);
}

[Theory]
[InlineData((ushort)0)]
[InlineData((ushort)(100))]
[InlineData((ushort)(1889))]
[InlineData((ushort)(1880))]
public void Year_Constructor_WithValueLess_ThanMinimiunSpecified_ThrowsValidationException(ushort value)
{
// Arrange & Act
var action = () => Year.From(value);

// Assert
action.Should().Throw<TypeValidationException>().And.Errors.Should().BeEquivalentTo(new[] { new ValidationFailure("Value", $"Could not create a Nox Year type as value {value} is less than the minimum specified value of 1900") });
}

[Theory]
[InlineData((ushort)3001)]
[InlineData((ushort)(4001))]
[InlineData((ushort)(5000))]
[InlineData((ushort)(9999))]
public void Year_Constructor_WithValueGreater_ThanMaximunSpecified_ThrowsValidationException(ushort value)
{
// Arrange & Act
var action = () => Year.From(value);

// Assert
action.Should().Throw<TypeValidationException>().And.Errors.Should().BeEquivalentTo(new[] { new ValidationFailure("Value", $"Could not create a Nox Year type a value {value} is greater than the maximum specified value of 3000") });
}

[Fact]
public void Year_Equal_Tests()
{
// Arrange
var year1 = Year.From(1900);

var year2 = Year.From(1900);

// Assert
year1.Should().Be(year2);
}

[Fact]
public void Year_NotEqual_Tests()
{
// Arrange
var year1 = Year.From(2000);

var year2 = Year.From(2002);

// Assert
year1.Should().NotBe(year2);
}


[Fact]
public void Year_ToString_ReturnsString()
{
// Arrange
var year = Year.From(1900);
var year2 = Year.From(1990);

// Assert
year.ToString().Should().Be("1900");
year2.ToString().Should().Be("1990");
}

[Fact]
public void Year_Constructor_SpecifyingAllowFutureOnly_WithPassYearInput_ThrowsException()
{
// Arrange
var yearValue = (ushort)2020;

// Act
var action = () => Year.From(yearValue, new YearTypeOptions { AllowFutureOnly = true });

// Assert
action.Should().Throw<TypeValidationException>().And.Errors.Should().BeEquivalentTo(new[] { new ValidationFailure("Value", $"Could not create a Nox Year type a value 2020 is less than the current year") });
}

[Fact]
public void Year_Constructor_SpecifyingMaxValue_WithGreaterValueInput_ThrowsException()
{
// Arrange
var yearValue = (ushort)1900;

// Act
var action = () => Year.From(yearValue, new YearTypeOptions { MaxValue = 10 });

// Assert
action.Should().Throw<TypeValidationException>().And.Errors.Should().BeEquivalentTo(new[] { new ValidationFailure("Value", $"Could not create a Nox Year type a value 1900 is greater than the maximum specified value of 10") });
}

[Fact]
public void Year_Constructor_SpecifyingMinValue_WithLesserValueInput_ThrowsException()
{
// Arrange
var yearValue = (ushort)1;

// Act
var action = () => Year.From(yearValue, new YearTypeOptions { MinValue = 50 });

// Assert
action.Should().Throw<TypeValidationException>().And.Errors.Should().BeEquivalentTo(new[] { new ValidationFailure("Value", $"Could not create a Nox Year type as value 1 is less than the minimum specified value of 50") });
}
}

0 comments on commit 24c34f2

Please sign in to comment.