switch from FluentAssertions to Shouldly
This commit is contained in:
@@ -15,13 +15,19 @@ jobs:
|
|||||||
test:
|
test:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
strategy:
|
||||||
- uses: actions/checkout@v3
|
matrix:
|
||||||
|
dotnet-version: [ '8.x', '9.x' ]
|
||||||
|
env:
|
||||||
|
DOTNET_CLI_TELEMETRY_OPTOUT: 'true'
|
||||||
|
|
||||||
- name: Setup .NET
|
steps:
|
||||||
uses: https://github.com/actions/setup-dotnet@v3
|
- uses: actions/checkout@v5
|
||||||
|
|
||||||
|
- name: Setup .NET ${{ matrix.dotnet-version }}
|
||||||
|
uses: https://github.com/actions/setup-dotnet@v4
|
||||||
with:
|
with:
|
||||||
dotnet-version: 9.x
|
dotnet-version: ${{ matrix.dotnet-version }}
|
||||||
|
|
||||||
- name: Restore dependencies
|
- name: Restore dependencies
|
||||||
run: dotnet restore
|
run: dotnet restore
|
||||||
@@ -30,12 +36,12 @@ jobs:
|
|||||||
run: dotnet build --no-restore
|
run: dotnet build --no-restore
|
||||||
|
|
||||||
- name: Test
|
- name: Test
|
||||||
run: dotnet test --no-build --verbosity normal --logger trx --results-directory "TestResults-9.x"
|
run: dotnet test --no-build --verbosity normal --logger trx --results-directory "TestResults-${{ matrix.dotnet-version }}"
|
||||||
|
|
||||||
- name: Upload dotnet test results
|
- name: Upload dotnet test results
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: dotnet-results-9.x
|
name: dotnet-results-${{ matrix.dotnet-version }}
|
||||||
path: TestResults-9.x
|
path: TestResults-${{ matrix.dotnet-version }}
|
||||||
if: ${{ always() }}
|
if: ${{ always() }}
|
||||||
retention-days: 30
|
retention-days: 30
|
||||||
|
|||||||
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
@@ -1,4 +1,5 @@
|
|||||||
{
|
{
|
||||||
"dotnet.defaultSolution": "JustDotNet.Core.sln",
|
"dotnet.defaultSolution": "JustDotNet.Core.sln",
|
||||||
"dotnetAcquisitionExtension.enableTelemetry": false
|
"dotnetAcquisitionExtension.enableTelemetry": false,
|
||||||
|
"dotnet.testWindow.useTestingPlatformProtocol": true
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ public class Decode
|
|||||||
var resultString = Base32.Encode(testBytes);
|
var resultString = Base32.Encode(testBytes);
|
||||||
var resultBytes = Base32.Decode(resultString);
|
var resultBytes = Base32.Decode(resultString);
|
||||||
|
|
||||||
resultBytes.Should().BeEquivalentTo(testBytes);
|
resultBytes.ShouldBeEquivalentTo(testBytes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -34,7 +34,7 @@ public class Decode
|
|||||||
public void WhenCalledWithValidString_ShouldReturnValidByteArray(string str, byte[] expected)
|
public void WhenCalledWithValidString_ShouldReturnValidByteArray(string str, byte[] expected)
|
||||||
{
|
{
|
||||||
var actualBytesArray = Base32.Decode(str);
|
var actualBytesArray = Base32.Decode(str);
|
||||||
actualBytesArray.Should().Equal(expected);
|
actualBytesArray.ShouldBe(expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
@@ -44,7 +44,7 @@ public class Decode
|
|||||||
public void WhenCalledWithValidStringThatEndsWithPaddingSign_ShouldReturnValidByteArray(string testString, byte[] expected)
|
public void WhenCalledWithValidStringThatEndsWithPaddingSign_ShouldReturnValidByteArray(string testString, byte[] expected)
|
||||||
{
|
{
|
||||||
var actualBytesArray = Base32.Decode(testString);
|
var actualBytesArray = Base32.Decode(testString);
|
||||||
actualBytesArray.Should().Equal(expected);
|
actualBytesArray.ShouldBe(expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
@@ -54,7 +54,7 @@ public class Decode
|
|||||||
public void WhenCalledWithValidStringWithoutPaddingSign_ShouldReturnValidByteArray(string testString, byte[] expected)
|
public void WhenCalledWithValidStringWithoutPaddingSign_ShouldReturnValidByteArray(string testString, byte[] expected)
|
||||||
{
|
{
|
||||||
var actualBytesArray = Base32.Decode(testString);
|
var actualBytesArray = Base32.Decode(testString);
|
||||||
actualBytesArray.Should().Equal(expected);
|
actualBytesArray.ShouldBe(expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
@@ -66,7 +66,7 @@ public class Decode
|
|||||||
public void WhenCalledWithNotValidString_ShouldThrowFormatException(string testString)
|
public void WhenCalledWithNotValidString_ShouldThrowFormatException(string testString)
|
||||||
{
|
{
|
||||||
Action action = () => Base32.Decode(testString);
|
Action action = () => Base32.Decode(testString);
|
||||||
action.Should().Throw<FormatException>();
|
action.ShouldThrow<FormatException>();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
@@ -74,6 +74,6 @@ public class Decode
|
|||||||
[InlineData("")]
|
[InlineData("")]
|
||||||
public void WhenCalledWithNullString_ShouldReturnEmptyArray(string? testString)
|
public void WhenCalledWithNullString_ShouldReturnEmptyArray(string? testString)
|
||||||
{
|
{
|
||||||
Base32.Decode(testString).Should().BeEmpty();
|
Base32.Decode(testString).ShouldBeEmpty();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ public class Encode
|
|||||||
var resultBytes = Base32.Decode(testString);
|
var resultBytes = Base32.Decode(testString);
|
||||||
var resultString = Base32.Encode(resultBytes);
|
var resultString = Base32.Encode(resultBytes);
|
||||||
|
|
||||||
resultString.Should().Be(testString);
|
resultString.ShouldBe(testString);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
@@ -47,7 +47,7 @@ public class Encode
|
|||||||
public void WhenCalledWithNotEmptyByteArray_ShouldReturnValidString(string expected, byte[] testArray)
|
public void WhenCalledWithNotEmptyByteArray_ShouldReturnValidString(string expected, byte[] testArray)
|
||||||
{
|
{
|
||||||
var str = Base32.Encode(testArray);
|
var str = Base32.Encode(testArray);
|
||||||
str.Should().Be(expected);
|
str.ShouldBe(expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
@@ -56,7 +56,7 @@ public class Encode
|
|||||||
public void WhenCalledWithEmptyByteArray_ShouldReturnEmptyString(byte[]? testArray)
|
public void WhenCalledWithEmptyByteArray_ShouldReturnEmptyString(byte[]? testArray)
|
||||||
{
|
{
|
||||||
var actualBase32 = Base32.Encode(testArray);
|
var actualBase32 = Base32.Encode(testArray);
|
||||||
actualBase32.Should().Be(string.Empty);
|
actualBase32.ShouldBe(string.Empty);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
@@ -68,7 +68,7 @@ public class Encode
|
|||||||
|
|
||||||
var charsWritten = Base32.Encode(testArray, output);
|
var charsWritten = Base32.Encode(testArray, output);
|
||||||
|
|
||||||
charsWritten.Should().Be(0);
|
charsWritten.ShouldBe(0);
|
||||||
output.Should().Equal(['1', '2', '3', '4']);
|
output.ShouldBe(['1', '2', '3', '4']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ public class Decode
|
|||||||
var resultString = Base64Url.Encode(testBytes);
|
var resultString = Base64Url.Encode(testBytes);
|
||||||
var resultBytes = Base64Url.Decode(resultString);
|
var resultBytes = Base64Url.Decode(resultString);
|
||||||
|
|
||||||
resultBytes.Should().BeEquivalentTo(testBytes);
|
resultBytes.ShouldBeEquivalentTo(testBytes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -39,7 +39,7 @@ public class Decode
|
|||||||
var resultString = Base64Url.Encode(testLong);
|
var resultString = Base64Url.Encode(testLong);
|
||||||
var resultLong = Base64Url.DecodeLong(resultString);
|
var resultLong = Base64Url.DecodeLong(resultString);
|
||||||
|
|
||||||
resultLong.Should().Be(testLong);
|
resultLong.ShouldBe(testLong);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -57,7 +57,7 @@ public class Decode
|
|||||||
public void WhenCalled_ShouldReturnValidLong(string testString, long expected)
|
public void WhenCalled_ShouldReturnValidLong(string testString, long expected)
|
||||||
{
|
{
|
||||||
var result = Base64Url.DecodeLong(testString);
|
var result = Base64Url.DecodeLong(testString);
|
||||||
result.Should().Be(expected);
|
result.ShouldBe(expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
@@ -70,7 +70,7 @@ public class Decode
|
|||||||
{
|
{
|
||||||
var result = Base64Url.DecodeGuid(testString);
|
var result = Base64Url.DecodeGuid(testString);
|
||||||
var expected = Guid.Parse(expectedStr);
|
var expected = Guid.Parse(expectedStr);
|
||||||
result.Should().Be(expected);
|
result.ShouldBe(expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
@@ -85,7 +85,7 @@ public class Decode
|
|||||||
public void WhenCalled_ShouldReturnValidBytes(string testString, byte[] expected)
|
public void WhenCalled_ShouldReturnValidBytes(string testString, byte[] expected)
|
||||||
{
|
{
|
||||||
var result = Base64Url.Decode(testString);
|
var result = Base64Url.Decode(testString);
|
||||||
result.Should().BeEquivalentTo(expected);
|
result.ShouldBeEquivalentTo(expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
@@ -97,7 +97,7 @@ public class Decode
|
|||||||
public void WhenCalledWithInvalidString_ShouldThrowFormatException(string testString)
|
public void WhenCalledWithInvalidString_ShouldThrowFormatException(string testString)
|
||||||
{
|
{
|
||||||
Action action = () => Base64Url.Decode(testString);
|
Action action = () => Base64Url.Decode(testString);
|
||||||
action.Should().Throw<FormatException>();
|
action.ShouldThrow<FormatException>();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
@@ -109,7 +109,7 @@ public class Decode
|
|||||||
public void WhenCalledWithInvalidGuidString_ShouldThrowFormatException(string testString)
|
public void WhenCalledWithInvalidGuidString_ShouldThrowFormatException(string testString)
|
||||||
{
|
{
|
||||||
Action action = () => Base64Url.DecodeGuid(testString);
|
Action action = () => Base64Url.DecodeGuid(testString);
|
||||||
action.Should().Throw<FormatException>();
|
action.ShouldThrow<FormatException>();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
@@ -122,7 +122,7 @@ public class Decode
|
|||||||
public void WhenCalledWithInvalidLongString_ShouldThrowFormatException(string testString)
|
public void WhenCalledWithInvalidLongString_ShouldThrowFormatException(string testString)
|
||||||
{
|
{
|
||||||
Action action = () => Base64Url.DecodeLong(testString);
|
Action action = () => Base64Url.DecodeLong(testString);
|
||||||
action.Should().Throw<FormatException>();
|
action.ShouldThrow<FormatException>();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
@@ -130,6 +130,6 @@ public class Decode
|
|||||||
[InlineData("")]
|
[InlineData("")]
|
||||||
public void WhenCalledWithNullString_ShouldReturnEmptyArray(string? testString)
|
public void WhenCalledWithNullString_ShouldReturnEmptyArray(string? testString)
|
||||||
{
|
{
|
||||||
Base64Url.Decode(testString).Should().BeEmpty();
|
Base64Url.Decode(testString).ShouldBeEmpty();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ public class Encode
|
|||||||
{
|
{
|
||||||
var testGuid = Guid.Parse(testGuidString);
|
var testGuid = Guid.Parse(testGuidString);
|
||||||
var result = Base64Url.Encode(testGuid);
|
var result = Base64Url.Encode(testGuid);
|
||||||
result.Should().Be(expected);
|
result.ShouldBe(expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
@@ -29,7 +29,7 @@ public class Encode
|
|||||||
public void WhenCalledWithLong_ShouldReturnValidString(string expected, long testLong)
|
public void WhenCalledWithLong_ShouldReturnValidString(string expected, long testLong)
|
||||||
{
|
{
|
||||||
var result = Base64Url.Encode(testLong);
|
var result = Base64Url.Encode(testLong);
|
||||||
result.Should().Be(expected);
|
result.ShouldBe(expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
@@ -44,7 +44,7 @@ public class Encode
|
|||||||
public void WhenCalled_ShouldReturnValidString(string expected, byte[] testBytes)
|
public void WhenCalled_ShouldReturnValidString(string expected, byte[] testBytes)
|
||||||
{
|
{
|
||||||
var result = Base64Url.Encode(testBytes);
|
var result = Base64Url.Encode(testBytes);
|
||||||
result.Should().Be(expected);
|
result.ShouldBe(expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
@@ -53,7 +53,7 @@ public class Encode
|
|||||||
public void WhenCalledWithEmptyByteArray_ShouldReturnEmptyString(byte[]? testArray)
|
public void WhenCalledWithEmptyByteArray_ShouldReturnEmptyString(byte[]? testArray)
|
||||||
{
|
{
|
||||||
var actualBase32 = Base64Url.Encode(testArray);
|
var actualBase32 = Base64Url.Encode(testArray);
|
||||||
actualBase32.Should().Be(string.Empty);
|
actualBase32.ShouldBe(string.Empty);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
@@ -65,7 +65,7 @@ public class Encode
|
|||||||
|
|
||||||
var charsWritten = Base64Url.Encode(testArray, output);
|
var charsWritten = Base64Url.Encode(testArray, output);
|
||||||
|
|
||||||
charsWritten.Should().Be(0);
|
charsWritten.ShouldBe(0);
|
||||||
output.Should().Equal(['1', '2', '3', '4']);
|
output.ShouldBe((char[])['1', '2', '3', '4']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net9.0</TargetFramework>
|
<TargetFrameworks>net8.0;net9.0</TargetFrameworks>
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
|
||||||
<AssemblyName>Just.Core.Tests</AssemblyName>
|
<AssemblyName>Just.Core.Tests</AssemblyName>
|
||||||
<RootNamespace>Just.Core.Tests</RootNamespace>
|
<RootNamespace>Just.Core.Tests</RootNamespace>
|
||||||
|
|
||||||
@@ -14,13 +15,8 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="FluentAssertions" Version="6.12.0" />
|
<PackageReference Include="Shouldly" Version="4.3.0" />
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.14.1" />
|
<PackageReference Include="xunit.v3" Version="3.2.0" />
|
||||||
<PackageReference Include="xunit" Version="2.9.3" />
|
|
||||||
<PackageReference Include="xunit.runner.visualstudio" Version="3.1.3">
|
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
|
||||||
<PrivateAssets>all</PrivateAssets>
|
|
||||||
</PackageReference>
|
|
||||||
<PackageReference Include="coverlet.collector" Version="6.0.4">
|
<PackageReference Include="coverlet.collector" Version="6.0.4">
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
global using Xunit;
|
global using Xunit;
|
||||||
global using FluentAssertions;
|
global using Shouldly;
|
||||||
|
|||||||
@@ -14,8 +14,19 @@ public class NewGuid
|
|||||||
{
|
{
|
||||||
var timestamp = referenceTime.AddSeconds(rng.Next());
|
var timestamp = referenceTime.AddSeconds(rng.Next());
|
||||||
var result = GuidV8.NewGuid(timestamp, entropy);
|
var result = GuidV8.NewGuid(timestamp, entropy);
|
||||||
result.Version.Should().Be(8);
|
|
||||||
(result.Variant & 0b1100).Should().Be(0b1000);
|
#if NET9_0_OR_GREATER
|
||||||
|
result.Version.ShouldBe(8);
|
||||||
|
(result.Variant & 0b1100).ShouldBe(0b1000);
|
||||||
|
#else
|
||||||
|
var bytes = result.ToByteArray();
|
||||||
|
// Check version (bits 4-7 of the 7th byte)
|
||||||
|
var version = (bytes[7] >> 4) & 0x0F;
|
||||||
|
version.ShouldBe(8); // UUID version 8
|
||||||
|
// Check variant (bits 6-7 of the 8th byte)
|
||||||
|
var variant = bytes[8] >> 6;
|
||||||
|
variant.ShouldBe(0b10); // Standard UUID variant
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -86,11 +97,11 @@ public class NewGuid
|
|||||||
var sut = expected.Values.ToArray();
|
var sut = expected.Values.ToArray();
|
||||||
rng.Shuffle(sut);
|
rng.Shuffle(sut);
|
||||||
|
|
||||||
sut.Order().Should().Equal(expected.Select(x => x.Value));
|
sut.Order().ShouldBe(expected.Select(x => x.Value));
|
||||||
sut.OrderBy(x => x.ToString()).Should().Equal(expected.Select(x => x.Value));
|
sut.OrderBy(x => x.ToString()).ShouldBe(expected.Select(x => x.Value));
|
||||||
|
|
||||||
sut.OrderDescending().Should().Equal(expected.Reverse().Select(x => x.Value));
|
sut.OrderDescending().ShouldBe(expected.Reverse().Select(x => x.Value));
|
||||||
sut.OrderByDescending(x => x.ToString()).Should().Equal(expected.Reverse().Select(x => x.Value));
|
sut.OrderByDescending(x => x.ToString()).ShouldBe(expected.Reverse().Select(x => x.Value));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
@@ -160,11 +171,11 @@ public class NewGuid
|
|||||||
var sut = expected.Values.ToArray();
|
var sut = expected.Values.ToArray();
|
||||||
rng.Shuffle(sut);
|
rng.Shuffle(sut);
|
||||||
|
|
||||||
sut.Order().Should().Equal(expected.Select(x => x.Value));
|
sut.Order().ShouldBe(expected.Select(x => x.Value));
|
||||||
sut.OrderBy(x => x.ToString()).Should().Equal(expected.Select(x => x.Value));
|
sut.OrderBy(x => x.ToString()).ShouldBe(expected.Select(x => x.Value));
|
||||||
|
|
||||||
sut.OrderDescending().Should().Equal(expected.Reverse().Select(x => x.Value));
|
sut.OrderDescending().ShouldBe(expected.Reverse().Select(x => x.Value));
|
||||||
sut.OrderByDescending(x => x.ToString()).Should().Equal(expected.Reverse().Select(x => x.Value));
|
sut.OrderByDescending(x => x.ToString()).ShouldBe(expected.Reverse().Select(x => x.Value));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
@@ -234,10 +245,10 @@ public class NewGuid
|
|||||||
var sut = expected.Values.ToArray();
|
var sut = expected.Values.ToArray();
|
||||||
rng.Shuffle(sut);
|
rng.Shuffle(sut);
|
||||||
|
|
||||||
sut.Order().Should().Equal(expected.Select(x => x.Value));
|
sut.Order().ShouldBe(expected.Select(x => x.Value));
|
||||||
sut.OrderBy(x => x.ToString()).Should().Equal(expected.Select(x => x.Value));
|
sut.OrderBy(x => x.ToString()).ShouldBe(expected.Select(x => x.Value));
|
||||||
|
|
||||||
sut.OrderDescending().Should().Equal(expected.Reverse().Select(x => x.Value));
|
sut.OrderDescending().ShouldBe(expected.Reverse().Select(x => x.Value));
|
||||||
sut.OrderByDescending(x => x.ToString()).Should().Equal(expected.Reverse().Select(x => x.Value));
|
sut.OrderByDescending(x => x.ToString()).ShouldBe(expected.Reverse().Select(x => x.Value));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
|
||||||
namespace Just.Core.Tests.SeqIdTests;
|
namespace Just.Core.Tests.SeqIdTests;
|
||||||
|
|
||||||
public class NextId
|
public class NextId
|
||||||
@@ -25,9 +26,9 @@ public class NextId
|
|||||||
long sequencePart = (id >> SeqShift) & SeqMask;
|
long sequencePart = (id >> SeqShift) & SeqMask;
|
||||||
long randomPart = id & RandMask;
|
long randomPart = id & RandMask;
|
||||||
|
|
||||||
timestampPart.Should().Be(500);
|
timestampPart.ShouldBe(500);
|
||||||
sequencePart.Should().Be(0);
|
sequencePart.ShouldBe(0);
|
||||||
randomPart.Should().BeInRange(0, RandMask);
|
randomPart.ShouldBeInRange(0, RandMask);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
@@ -44,7 +45,7 @@ public class NextId
|
|||||||
long sequence1 = (id1 >> SeqShift) & SeqMask;
|
long sequence1 = (id1 >> SeqShift) & SeqMask;
|
||||||
long sequence2 = (id2 >> SeqShift) & SeqMask;
|
long sequence2 = (id2 >> SeqShift) & SeqMask;
|
||||||
|
|
||||||
sequence2.Should().Be(sequence1 + 1);
|
sequence2.ShouldBe(sequence1 + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
@@ -61,7 +62,7 @@ public class NextId
|
|||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
long sequence = (id >> SeqShift) & SeqMask;
|
long sequence = (id >> SeqShift) & SeqMask;
|
||||||
sequence.Should().Be(0);
|
sequence.ShouldBe(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
@@ -74,7 +75,7 @@ public class NextId
|
|||||||
// Act & Assert
|
// Act & Assert
|
||||||
_seqId.Next(time1); // First call sets last timestamp
|
_seqId.Next(time1); // First call sets last timestamp
|
||||||
Action act = () => _seqId.Next(time2);
|
Action act = () => _seqId.Next(time2);
|
||||||
act.Should().Throw<InvalidOperationException>()
|
act.ShouldThrow<InvalidOperationException>()
|
||||||
.WithMessage("Refused to create new SeqId. Last timestamp is in the future.");
|
.WithMessage("Refused to create new SeqId. Last timestamp is in the future.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -90,7 +91,7 @@ public class NextId
|
|||||||
_seqId.Next(time); // Exhauste sequence
|
_seqId.Next(time); // Exhauste sequence
|
||||||
}
|
}
|
||||||
Action act = () => _seqId.Next(time);
|
Action act = () => _seqId.Next(time);
|
||||||
act.Should().Throw<IndexOutOfRangeException>()
|
act.ShouldThrow<IndexOutOfRangeException>()
|
||||||
.WithMessage("Refused to create new SeqId. Sequence exhausted.");
|
.WithMessage("Refused to create new SeqId. Sequence exhausted.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -105,7 +106,7 @@ public class NextId
|
|||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
long randomPart = id & RandMask;
|
long randomPart = id & RandMask;
|
||||||
randomPart.Should().BeInRange(0, RandMask);
|
randomPart.ShouldBeInRange(0, RandMask);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
@@ -119,7 +120,7 @@ public class NextId
|
|||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
long randomPart = id & RandMask;
|
long randomPart = id & RandMask;
|
||||||
randomPart.Should().BeInRange(0, RandMask);
|
randomPart.ShouldBeInRange(0, RandMask);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
@@ -127,14 +128,14 @@ public class NextId
|
|||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var now = DateTime.UtcNow;
|
var now = DateTime.UtcNow;
|
||||||
var defaultEpoch = new DateTime(2025, 1, 1, 0, 0, 0, DateTimeKind.Utc);
|
var defaultEpoch = SeqId.DefaultEpoch;
|
||||||
long expectedTimestamp = (long)(now - defaultEpoch).TotalMilliseconds;
|
long expectedTimestamp = ((long)(now - defaultEpoch).TotalMilliseconds) & TimestampMask; // Mask handles overflow
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
long id = SeqId.NextId();
|
long id = SeqId.NextId();
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
long timestampPart = (id >> TimestampShift) & TimestampMask;
|
long timestampPart = (id >> TimestampShift) & TimestampMask;
|
||||||
timestampPart.Should().BeCloseTo(expectedTimestamp & TimestampMask, 1); // Mask handles overflow
|
timestampPart.ShouldBeInRange(expectedTimestamp, expectedTimestamp + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
11
Core.Tests/ShouldlyExtensions.cs
Normal file
11
Core.Tests/ShouldlyExtensions.cs
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
namespace Just.Core.Tests;
|
||||||
|
|
||||||
|
public static class ShouldlyExtensions
|
||||||
|
{
|
||||||
|
public static TException WithMessage<TException>(this TException exception, string expectedMessage, string? customMessage = null)
|
||||||
|
where TException : Exception
|
||||||
|
{
|
||||||
|
exception.Message.ShouldBe(expectedMessage, customMessage: customMessage);
|
||||||
|
return exception;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -23,7 +23,7 @@ public class Populate
|
|||||||
|
|
||||||
stream.Populate(buffer, offset, length);
|
stream.Populate(buffer, offset, length);
|
||||||
|
|
||||||
buffer.Skip(offset).Take(length).Should().Equal(streamContent.Take(length));
|
buffer.Skip(offset).Take(length).ShouldBe(streamContent.Take(length));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
@@ -38,7 +38,7 @@ public class Populate
|
|||||||
|
|
||||||
stream.Populate(buffer);
|
stream.Populate(buffer);
|
||||||
|
|
||||||
buffer.Should().Equal(streamContent.Take(bufferSize));
|
buffer.ShouldBe(streamContent.Take(bufferSize));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
@@ -53,6 +53,6 @@ public class Populate
|
|||||||
|
|
||||||
Action action = () => stream.Populate(buffer);
|
Action action = () => stream.Populate(buffer);
|
||||||
|
|
||||||
action.Should().Throw<EndOfStreamException>();
|
action.ShouldThrow<EndOfStreamException>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ public class PopulateAsync
|
|||||||
Func<Task> action = async () => await stream.PopulateAsync(buffer, cts.Token);
|
Func<Task> action = async () => await stream.PopulateAsync(buffer, cts.Token);
|
||||||
cts.Cancel();
|
cts.Cancel();
|
||||||
|
|
||||||
await action.Should().ThrowAsync<OperationCanceledException>();
|
await action.ShouldThrowAsync<OperationCanceledException>();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
@@ -31,13 +31,14 @@ public class PopulateAsync
|
|||||||
[InlineData(5, 5)]
|
[InlineData(5, 5)]
|
||||||
public async Task WhenCalled_ShouldPopulateSpecifiedRange(int offset, int length)
|
public async Task WhenCalled_ShouldPopulateSpecifiedRange(int offset, int length)
|
||||||
{
|
{
|
||||||
|
using var cts = new CancellationTokenSource(TimeSpan.FromMilliseconds(50));
|
||||||
byte[] streamContent = [0x01, 0x02, 0x03, 0x04, 0x05,];
|
byte[] streamContent = [0x01, 0x02, 0x03, 0x04, 0x05,];
|
||||||
using var stream = new MemoryStream(streamContent);
|
using var stream = new MemoryStream(streamContent);
|
||||||
var buffer = new byte[10];
|
var buffer = new byte[10];
|
||||||
|
|
||||||
await stream.PopulateAsync(buffer, offset, length);
|
await stream.PopulateAsync(buffer, offset, length, cts.Token);
|
||||||
|
|
||||||
buffer.Skip(offset).Take(length).Should().Equal(streamContent.Take(length));
|
buffer.Skip(offset).Take(length).ShouldBe(streamContent.Take(length));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
@@ -47,12 +48,13 @@ public class PopulateAsync
|
|||||||
[InlineData(new byte[]{ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, }, 5)]
|
[InlineData(new byte[]{ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, }, 5)]
|
||||||
public async Task WhenStreamContainsSameOrGreaterAmmountOfItems_ShouldPopulateBuffer(byte[] streamContent, int bufferSize)
|
public async Task WhenStreamContainsSameOrGreaterAmmountOfItems_ShouldPopulateBuffer(byte[] streamContent, int bufferSize)
|
||||||
{
|
{
|
||||||
|
using var cts = new CancellationTokenSource(TimeSpan.FromMilliseconds(50));
|
||||||
using var stream = new MemoryStream(streamContent);
|
using var stream = new MemoryStream(streamContent);
|
||||||
var buffer = new byte[bufferSize];
|
var buffer = new byte[bufferSize];
|
||||||
|
|
||||||
await stream.PopulateAsync(buffer);
|
await stream.PopulateAsync(buffer, cts.Token);
|
||||||
|
|
||||||
buffer.Should().Equal(streamContent.Take(bufferSize));
|
buffer.ShouldBe(streamContent.Take(bufferSize));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
@@ -67,6 +69,6 @@ public class PopulateAsync
|
|||||||
|
|
||||||
Func<Task> action = async () => await stream.PopulateAsync(buffer);
|
Func<Task> action = async () => await stream.PopulateAsync(buffer);
|
||||||
|
|
||||||
await action.Should().ThrowAsync<EndOfStreamException>();
|
await action.ShouldThrowAsync<EndOfStreamException>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user