Skip to content

Commit

Permalink
feature/crypto-named-hash (#54) (#55)
Browse files Browse the repository at this point in the history
* Added `NamedHash`, new pre-condition checks, and extension methods.

* Updated version to 8.2.0
  • Loading branch information
MrMatthewLayton authored May 30, 2024
1 parent fdb839c commit 1a1b02e
Show file tree
Hide file tree
Showing 13 changed files with 495 additions and 30 deletions.
21 changes: 21 additions & 0 deletions OnixLabs.Core.UnitTests.Data/Shape.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Copyright 2020 ONIXLabs
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

namespace OnixLabs.Core.UnitTests.Data;

public enum Shape
{
Square,
Circle
}
32 changes: 31 additions & 1 deletion OnixLabs.Core.UnitTests/ObjectExtensionTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,37 @@ namespace OnixLabs.Core.UnitTests;

public sealed class ObjectExtensionTests
{
[Fact(DisplayName = "Object.ToRecordString should produce a record formatted string")]
[Theory(DisplayName = "IsWithinRangeInclusive should produce the expected result")]
[InlineData(2, 1, 3, true)]
[InlineData(1, 1, 3, true)]
[InlineData(3, 1, 3, true)]
[InlineData(0, 1, 3, false)]
[InlineData(4, 1, 3, false)]
public void IsWithinRangeInclusiveShouldProduceExpectedResult(int value, int min, int max, bool expected)
{
// When
bool actual = value.IsWithinRangeInclusive(min, max);

// Then
Assert.Equal(expected, actual);
}

[Theory(DisplayName = "IsWithinRangeExclusive should produce the expected result")]
[InlineData(2, 1, 3, true)]
[InlineData(1, 1, 3, false)]
[InlineData(3, 1, 3, false)]
[InlineData(0, 1, 3, false)]
[InlineData(4, 1, 3, false)]
public void IsWithinRangeExclusiveShouldProduceExpectedResult(int value, int min, int max, bool expected)
{
// When
bool actual = value.IsWithinRangeExclusive(min, max);

// Then
Assert.Equal(expected, actual);
}

[Fact(DisplayName = "ToRecordString should produce a record formatted string")]
public void ToRecordStringShouldProduceExpectedResult()
{
// Given
Expand Down
161 changes: 146 additions & 15 deletions OnixLabs.Core.UnitTests/PreconditionTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,59 +13,190 @@
// limitations under the License.

using System;
using OnixLabs.Core.UnitTests.Data;
using Xunit;

namespace OnixLabs.Core.UnitTests;

public sealed class PreconditionTests
{
[Fact(DisplayName = "Check should throw an ArgumentException when the condition is false")]
public void CheckShouldProduceExpectedResult()
[Fact(DisplayName = "Check should throw an InvalidOperationException when the condition is false")]
public void CheckShouldThrowInvalidOperationExceptionWhenConditionIsFalse()
{
// When
InvalidOperationException exception = Assert.Throws<InvalidOperationException>(() => Check(false));
Exception exception = Assert.Throws<InvalidOperationException>(() => Check(false));

// Then
Assert.Equal("Check failed.", exception.Message);
Assert.Equal("Argument must satisfy the specified condition.", exception.Message);
}

[Fact(DisplayName = "CheckNotNull should throw an ArgumentNullException when the condition is null")]
public void CheckNotNullShouldProduceExpectedResult()
[Fact(DisplayName = "CheckNotNull should throw an InvalidOperationException when the condition is null")]
public void CheckNotNullShouldThrowInvalidOperationExceptionWhenConditionIsNull()
{
// When
InvalidOperationException exception = Assert.Throws<InvalidOperationException>(() => CheckNotNull<object>(null));
Exception exception = Assert.Throws<InvalidOperationException>(() => CheckNotNull<object>(null));

// Then
Assert.Equal("Argument must not be null.", exception.Message);
}

[Fact(DisplayName = "CheckNotNullOrEmpty should throw an InvalidOperationException when the value is null")]
public void CheckNotNullOrEmptyShouldThrowInvalidOperationExceptionWhenValueIsNull()
{
// When
Exception exception = Assert.Throws<InvalidOperationException>(() => CheckNotNullOrEmpty(null));

// Then
Assert.Equal("Argument must not be null or empty.", exception.Message);
}

[Fact(DisplayName = "CheckNotNullOrEmpty should throw an InvalidOperationException when the value is empty")]
public void CheckNotNullOrEmptyShouldThrowInvalidOperationExceptionWhenValueIsEmpty()
{
// When
Exception exception = Assert.Throws<InvalidOperationException>(() => CheckNotNullOrEmpty(string.Empty));

// Then
Assert.Equal("Argument must not be null or empty.", exception.Message);
}

[Fact(DisplayName = "CheckNotNullOrWhiteSpace should throw an InvalidOperationException when the value is null")]
public void CheckNotNullOrWhiteSpaceShouldThrowInvalidOperationExceptionWhenValueIsNull()
{
// When
Exception exception = Assert.Throws<InvalidOperationException>(() => CheckNotNullOrWhiteSpace(null));

// Then
Assert.Equal("Argument must not be null or whitespace.", exception.Message);
}

[Fact(DisplayName = "CheckNotNullOrWhiteSpace should throw an InvalidOperationException when the value is whitespace")]
public void CheckNotNullOrWhiteSpaceShouldThrowInvalidOperationExceptionWhenValueIsWhiteSpace()
{
// When
Exception exception = Assert.Throws<InvalidOperationException>(() => CheckNotNullOrWhiteSpace(" "));

// Then
Assert.Equal("Argument must not be null or whitespace.", exception.Message);
}

[Fact(DisplayName = "Require should throw an ArgumentException when the condition is false")]
public void RequireShouldProduceExpectedResult()
public void RequireShouldThrowArgumentExceptionWhenConditionIsFalse()
{
// When
ArgumentException exception = Assert.Throws<ArgumentException>(() => Require(false));
Exception exception = Assert.Throws<ArgumentException>(() => Require(false));

// Then
Assert.Equal("Argument requirement failed.", exception.Message);
Assert.Equal("Argument must satisfy the specified condition.", exception.Message);
}

[Fact(DisplayName = "RequireWithinRange should throw an ArgumentOutOfRangeException when the condition is false")]
public void RequireWithinRangeShouldProduceExpectedResult()
public void RequireWithinRangeShouldThrowArgumentOutOfRangeExceptionWhenConditionIsFalse()
{
// When
ArgumentOutOfRangeException exception = Assert.Throws<ArgumentOutOfRangeException>(() => RequireWithinRange(false));
Exception exception = Assert.Throws<ArgumentOutOfRangeException>(() => RequireWithinRange(false));

// Then
Assert.Equal("Argument must be within range.", exception.Message);
}

[Fact(DisplayName = "RequireWithinRangeInclusive should throw an ArgumentOutOfRangeException when the value falls below the specified range")]
public void RequireWithinRangeInclusiveShouldThrowArgumentOutOfRangeExceptionWhenValueFallsBelowSpecifiedRange()
{
// Given
Exception exception = Assert.Throws<ArgumentOutOfRangeException>(() => RequireWithinRangeInclusive(1, 2, 3));

// Then
Assert.Equal("Argument must be within range.", exception.Message);
}

[Fact(DisplayName = "RequireWithinRangeInclusive should throw an ArgumentOutOfRangeException when the value falls above the specified range")]
public void RequireWithinRangeInclusiveShouldThrowArgumentOutOfRangeExceptionWhenValueFallsAboveSpecifiedRange()
{
// Given
Exception exception = Assert.Throws<ArgumentOutOfRangeException>(() => RequireWithinRangeInclusive(4, 2, 3));

// Then
Assert.Equal("Argument must be within range.", exception.Message);
}

[Fact(DisplayName = "RequireWithinRangeExclusive should throw an ArgumentOutOfRangeException when the value falls below the specified range")]
public void RequireWithinRangeExclusiveShouldThrowArgumentOutOfRangeExceptionWhenValueFallsBelowSpecifiedRange()
{
// Given
Exception exception = Assert.Throws<ArgumentOutOfRangeException>(() => RequireWithinRangeExclusive(2, 2, 4));

// Then
Assert.Equal("Argument must be within range.", exception.Message);
}

[Fact(DisplayName = "RequireWithinRangeExclusive should throw an ArgumentOutOfRangeException when the value falls above the specified range")]
public void RequireWithinRangeExclusiveShouldThrowArgumentOutOfRangeExceptionWhenValueFallsAboveSpecifiedRange()
{
// Given
Exception exception = Assert.Throws<ArgumentOutOfRangeException>(() => RequireWithinRangeExclusive(4, 2, 4));

// Then
Assert.Equal("Argument is out of range.", exception.Message);
Assert.Equal("Argument must be within range.", exception.Message);
}

[Fact(DisplayName = "RequireNotNull should throw an ArgumentNullException when the condition is null")]
public void RequireNotNullShouldProduceExpectedResult()
public void RequireNotNullShouldThrowArgumentNullExceptionWhenConditionIsNull()
{
// When
ArgumentNullException exception = Assert.Throws<ArgumentNullException>(() => RequireNotNull<object>(null));
Exception exception = Assert.Throws<ArgumentNullException>(() => RequireNotNull<object>(null));

// Then
Assert.Equal("Argument must not be null.", exception.Message);
}

[Fact(DisplayName = "RequireNotNullOrEmpty should throw an ArgumentException when the value is null")]
public void RequireNotNullOrEmptyShouldThrowArgumentExceptionWhenValueIsNull()
{
// When
Exception exception = Assert.Throws<ArgumentException>(() => RequireNotNullOrEmpty(null));

// Then
Assert.Equal("Argument must not be null or empty.", exception.Message);
}

[Fact(DisplayName = "RequireNotNullOrEmpty should throw an ArgumentException when the value is empty")]
public void RequireNotNullOrEmptyShouldThrowArgumentExceptionWhenValueIsEmpty()
{
// When
Exception exception = Assert.Throws<ArgumentException>(() => RequireNotNullOrEmpty(string.Empty));

// Then
Assert.Equal("Argument must not be null or empty.", exception.Message);
}

[Fact(DisplayName = "RequireNotNullOrWhiteSpace should throw an ArgumentException when the value is null")]
public void RequireNotNullOrWhiteSpaceShouldThrowArgumentExceptionWhenValueIsNull()
{
// When
Exception exception = Assert.Throws<ArgumentException>(() => RequireNotNullOrWhiteSpace(null));

// Then
Assert.Equal("Argument must not be null or whitespace.", exception.Message);
}

[Fact(DisplayName = "RequireNotNullOrWhiteSpace should throw an ArgumentException when the value is whitespace")]
public void RequireNotNullOrWhiteSpaceShouldThrowArgumentExceptionWhenValueIsWhiteSpace()
{
// When
Exception exception = Assert.Throws<ArgumentException>(() => RequireNotNullOrWhiteSpace(" "));

// Then
Assert.Equal("Argument must not be null or whitespace.", exception.Message);
}

[Fact(DisplayName = "RequireIsDefined should throw an ArgumentOutOfRangeException when the specified enum value is not defined")]
public void RequireIsDefinedShouldThrowArgumentOutOfRangeExceptionWhenSpecifiedEnumValueIsNotDefined()
{
// When
Exception exception = Assert.Throws<ArgumentOutOfRangeException>(() => RequireIsDefined((Shape)2));

// Then
Assert.Equal("Invalid Shape enum value: 2. Valid values include: Square, Circle.", exception.Message);
}
}
32 changes: 32 additions & 0 deletions OnixLabs.Core/Extensions.Object.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,38 @@ namespace OnixLabs.Core;
[EditorBrowsable(EditorBrowsableState.Never)]
public static class ObjectExtensions
{
/// <summary>
/// Determines whether the current <see cref="IComparable{T}"/> value falls within range, inclusive of the specified minimum and maximum values.
/// </summary>
/// <param name="value">The value to test.</param>
/// <param name="min">The inclusive minimum value.</param>
/// <param name="max">The inclusive maximum value.</param>
/// <typeparam name="T">The underlying <see cref="IComparable{T}"/> type.</typeparam>
/// <returns>
/// Returns <see langword="true"/> if the current <see cref="IComparable{T}"/> value falls within range,
/// inclusive of the specified minimum and maximum values; otherwise, <see langword="false"/>.
/// </returns>
public static bool IsWithinRangeInclusive<T>(this T value, T min, T max) where T : IComparable<T>
{
return value.CompareTo(min) is 0 or 1 && value.CompareTo(max) is 0 or -1;
}

/// <summary>
/// Determines whether the current <see cref="IComparable{T}"/> value falls within range, exclusive of the specified minimum and maximum values.
/// </summary>
/// <param name="value">The value to test.</param>
/// <param name="min">The exclusive minimum value.</param>
/// <param name="max">The exclusive maximum value.</param>
/// <typeparam name="T">The underlying <see cref="IComparable{T}"/> type.</typeparam>
/// <returns>
/// Returns <see langword="true"/> if the current <see cref="IComparable{T}"/> value falls within range,
/// exclusive of the specified minimum and maximum values; otherwise, <see langword="false"/>.
/// </returns>
public static bool IsWithinRangeExclusive<T>(this T value, T min, T max) where T : IComparable<T>
{
return value.CompareTo(min) is 1 && value.CompareTo(max) is -1;
}

/// <summary>
/// Compares the current <see cref="IComparable{T}"/> instance with the specified <see cref="Object"/> instance.
/// </summary>
Expand Down
2 changes: 1 addition & 1 deletion OnixLabs.Core/OnixLabs.Core.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
<NeutralLanguage>en</NeutralLanguage>
<Copyright>Copyright © ONIXLabs 2020</Copyright>
<RepositoryUrl>https://github.com/onix-labs/onixlabs-dotnet</RepositoryUrl>
<PackageVersion>8.1.0</PackageVersion>
<PackageVersion>8.2.0</PackageVersion>
<PackageLicenseUrl></PackageLicenseUrl>
</PropertyGroup>
<PropertyGroup>
Expand Down
Loading

0 comments on commit 1a1b02e

Please sign in to comment.