Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 55 additions & 0 deletions src/StrongTypes.Tests/Collections/ExceptNullsTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#nullable enable

using System;
using System.Collections.Generic;
using System.Linq;
using Xunit;

namespace StrongTypes.Tests;

public class ExceptNullsTests
{
[Fact]
public void ExceptNulls_NullableStruct()
{
var guid1 = Guid.NewGuid();
var guid2 = Guid.NewGuid();
var list = new List<Guid?> { null, guid1, null, guid2, null };

Guid[] result = list.ExceptNulls().ToArray();

Assert.Equal(new[] { guid1, guid2 }, result);
}

[Fact]
public void ExceptNulls_NullableReference()
{
var list = new List<string?> { null, "1 potato", null, "2 potatoes", null };

string[] result = list.ExceptNulls().ToArray();

Assert.Equal(new[] { "1 potato", "2 potatoes" }, result);
}

[Fact]
public void ExceptNulls_AllNull_ReturnsEmpty()
{
Assert.Empty(new int?[] { null, null, null }.ExceptNulls());
Assert.Empty(new string?[] { null, null, null }.ExceptNulls());
}

[Fact]
public void ExceptNulls_NoNulls_ReturnsAll()
{
Assert.Equal(new[] { 1, 2, 3 }, new int?[] { 1, 2, 3 }.ExceptNulls());
Assert.Equal(new[] { "a", "b" }, new string?[] { "a", "b" }.ExceptNulls());
}

[Fact]
public void ExceptNulls_ReferenceResult_IsStronglyTyped()
{
IEnumerable<string?> source = new[] { "x", null, "y" };
IEnumerable<string> result = source.ExceptNulls();
Assert.Equal(new[] { "x", "y" }, result);
}
}
31 changes: 0 additions & 31 deletions src/StrongTypes.Tests/Collections_Old/ExceptNullsTests_Old.cs

This file was deleted.

44 changes: 44 additions & 0 deletions src/StrongTypes.Tests/Digits/DigitExtensionsTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#nullable enable

using System.Linq;
using FsCheck.Xunit;
using Xunit;

namespace StrongTypes.Tests;

public class DigitExtensionsTests
{
[Property]
public void AsDigit_DelegatesToTryCreate(char c)
{
Assert.Equal(Digit.TryCreate(c), c.AsDigit());
}

[Fact]
public void FilterDigits_ExtractsDigitsInOrder()
{
Assert.Equal(
new byte[] { 1, 2, 3, 8, 7, 6, 5, 9 },
"ASD 1 some spaces 2 with numbers 38 7 in between .6 ?:`'!@(#*&$%&^!@)$_ them59"
.FilterDigits()
.Select(d => d.Value));
}

[Fact]
public void FilterDigits_ReturnsEmpty_ForNull()
{
Assert.Empty(((string?)null).FilterDigits());
}

[Fact]
public void FilterDigits_ReturnsEmpty_ForEmptyString()
{
Assert.Empty("".FilterDigits());
}

[Fact]
public void FilterDigits_ReturnsEmpty_ForNonDigitsOnly()
{
Assert.Empty("abc XYZ !@#".FilterDigits());
}
}
207 changes: 207 additions & 0 deletions src/StrongTypes.Tests/Digits/DigitTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,207 @@
#nullable enable

using System;
using FsCheck.Xunit;
using Xunit;

namespace StrongTypes.Tests;

public class DigitTests
{
[Theory]
[InlineData('0', (byte)0)]
[InlineData('1', (byte)1)]
[InlineData('2', (byte)2)]
[InlineData('3', (byte)3)]
[InlineData('4', (byte)4)]
[InlineData('5', (byte)5)]
[InlineData('6', (byte)6)]
[InlineData('7', (byte)7)]
[InlineData('8', (byte)8)]
[InlineData('9', (byte)9)]
public void TryCreate_Succeeds_ForAsciiDigits(char input, byte expected)
{
var digit = Digit.TryCreate(input);
Assert.NotNull(digit);
Assert.Equal(expected, digit!.Value.Value);
}

[Theory]
[InlineData('a')]
[InlineData('z')]
[InlineData('B')]
[InlineData(' ')]
[InlineData('.')]
[InlineData(char.MinValue)]
[InlineData(char.MaxValue)]
public void TryCreate_ReturnsNull_ForNonDigits(char input)
{
Assert.Null(Digit.TryCreate(input));
}

[Fact]
public void Create_Throws_ForNonDigit()
{
Assert.Throws<ArgumentException>(() => Digit.Create('a'));
}

[Fact]
public void Create_Succeeds_ForDigit()
{
Assert.Equal((byte)7, Digit.Create('7').Value);
}

[Fact]
public void Default_IsZero()
{
Assert.Equal((byte)0, default(Digit).Value);
}

[Property]
public void TryCreate_AgreesWith_CharIsDigit(char c)
{
var result = Digit.TryCreate(c);
Assert.Equal(char.IsDigit(c), result.HasValue);
}

[Property]
public void AllIntegerFirstDigits_Succeed(int number)
{
var firstDigit = Math.Abs(number).ToString()[0];
Assert.NotNull(Digit.TryCreate(firstDigit));
}

[Fact]
public void Equality_Digit()
{
Assert.Equal(Digit.Create('5'), Digit.Create('5'));
Assert.NotEqual(Digit.Create('5'), Digit.Create('6'));
Assert.True(Digit.Create('5') == Digit.Create('5'));
Assert.True(Digit.Create('5') != Digit.Create('6'));
}

[Fact]
public void Equality_Byte()
{
var digit = Digit.Create('5');
Assert.True(digit.Equals((byte)5));
Assert.False(digit.Equals((byte)6));
Assert.True(digit.Equals((object)(byte)5));

Assert.True(digit == (byte)5);
Assert.True((byte)5 == digit);
Assert.True(digit != (byte)6);
Assert.True((byte)6 != digit);
}

[Fact]
public void Equality_Int()
{
var digit = Digit.Create('5');
Assert.True(digit.Equals(5));
Assert.False(digit.Equals(6));
Assert.False(digit.Equals(500));
Assert.True(digit.Equals((object)5));

Assert.True(digit == 5);
Assert.True(5 == digit);
Assert.True(digit != 500);
Assert.True(500 != digit);
}

[Property]
public void GetHashCode_MatchesByteHashCode(char c)
{
var digit = Digit.TryCreate(c);
if (digit is null)
{
return;
}
Assert.Equal(digit.Value.Value.GetHashCode(), digit.Value.GetHashCode());
}

[Fact]
public void Comparison_Digit()
{
var three = Digit.Create('3');
var seven = Digit.Create('7');

Assert.True(three.CompareTo(seven) < 0);
Assert.True(seven.CompareTo(three) > 0);
Assert.Equal(0, three.CompareTo(three));

Assert.True(three < seven);
Assert.True(three <= seven);
Assert.True(seven > three);
Assert.True(seven >= three);
var threeAgain = Digit.Create('3');
Assert.True(three <= threeAgain);
Assert.True(three >= threeAgain);
}

[Fact]
public void Comparison_Byte()
{
var digit = Digit.Create('5');
Assert.True(digit.CompareTo((byte)4) > 0);
Assert.True(digit.CompareTo((byte)6) < 0);
Assert.Equal(0, digit.CompareTo((byte)5));

Assert.True(digit > (byte)4);
Assert.True(digit >= (byte)5);
Assert.True(digit < (byte)6);
Assert.True(digit <= (byte)5);

Assert.True((byte)4 < digit);
Assert.True((byte)5 <= digit);
Assert.True((byte)6 > digit);
Assert.True((byte)5 >= digit);
}

[Fact]
public void Comparison_Int()
{
var digit = Digit.Create('5');
Assert.True(digit.CompareTo(-1) > 0);
Assert.True(digit.CompareTo(1000) < 0);
Assert.Equal(0, digit.CompareTo(5));

Assert.True(digit > -1);
Assert.True(digit >= 5);
Assert.True(digit < 1000);
Assert.True(digit <= 5);

Assert.True(-1 < digit);
Assert.True(5 <= digit);
Assert.True(1000 > digit);
Assert.True(5 >= digit);
}

[Fact]
public void Comparison_NonGeneric()
{
IComparable digit = Digit.Create('5');
Assert.True(digit.CompareTo(null) > 0);
Assert.True(digit.CompareTo(Digit.Create('3')) > 0);
Assert.True(digit.CompareTo((byte)3) > 0);
Assert.True(digit.CompareTo(3) > 0);
Assert.Throws<ArgumentException>(() => digit.CompareTo("not a digit"));
}

[Fact]
public void ImplicitConversions()
{
byte b = Digit.Create('5');
int i = Digit.Create('9');

Assert.Equal((byte)5, b);
Assert.Equal(9, i);
}

[Fact]
public void ToString_IsDecimalValue()
{
Assert.Equal("0", Digit.Create('0').ToString());
Assert.Equal("9", Digit.Create('9').ToString());
}
}
Loading
Loading