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
22 changes: 22 additions & 0 deletions PolyShim.Tests/Net60/RandomNumberGeneratorTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using System.Security.Cryptography;
using FluentAssertions;
using Xunit;

namespace PolyShim.Tests.Net60;

public class RandomNumberGeneratorTests
{
[Fact]
public void GetBytes_Static_Test()
{
for (var i = 0; i < 100; i++)
{
// Act
var data = RandomNumberGenerator.GetBytes(16);
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is act


// Assert
data.Should().HaveCount(16);
data.Should().Contain(b => b != 0);
Comment on lines +18 to +19
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is assert

}
}
}
108 changes: 108 additions & 0 deletions PolyShim.Tests/Net80/RandomNumberGeneratorTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
using System;
using System.Security.Cryptography;
using FluentAssertions;
using Xunit;

namespace PolyShim.Tests.Net80;

public class RandomNumberGeneratorTests
{
[Fact]
public void GetHexString_Test()
{
// Act & assert
for (var i = 0; i < 100; i++)
{
RandomNumberGenerator.GetHexString(16).Should().MatchRegex("^[0-9A-F]{16}$");
RandomNumberGenerator.GetHexString(16, true).Should().MatchRegex("^[0-9a-f]{16}$");
RandomNumberGenerator.GetHexString(15).Should().MatchRegex("^[0-9A-F]{15}$");
}
}

[Fact]
public void GetString_Test()
{
// Arrange
var choices = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789".AsSpan();

for (var i = 0; i < 100; i++)
{
// Act
var str = RandomNumberGenerator.GetString(choices, 16);
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is act


// Assert
str.Length.Should().Be(16);

foreach (var ch in str)
{
choices.ToArray().Should().Contain(ch);
}
}
}

[Fact]
public void GetItems_Test()
{
// Arrange
var choices = new[] { 1, 2, 3, 4, 5 }.AsSpan();

for (var i = 0; i < 100; i++)
{
// Act
var items = RandomNumberGenerator.GetItems(choices, 3);
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is act


// Assert
items.Should().HaveCount(3);

foreach (var item in items)
{
choices.ToArray().Should().Contain(item);
}
}
}

[Fact]
public void GetItems_Span_Test()
{
// Arrange
var choices = new[] { 1, 2, 3, 4, 5 }.AsSpan();
var destination = new Span<int>(new int[3]);

for (var i = 0; i < 100; i++)
{
// Act
RandomNumberGenerator.GetItems(choices, destination);
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is act


// Assert
destination.Length.Should().Be(3);

foreach (var item in destination)
{
choices.ToArray().Should().Contain(item);
}
}
}

[Fact]
public void Shuffle_Test()
{
// Arrange
var originalItems = new[] { 1, 2, 3, 4, 5 };

for (var i = 0; i < 100; i++)
{
// Act
var items = new Span<int>((int[])originalItems.Clone());
RandomNumberGenerator.Shuffle(items);
Comment on lines +95 to +96
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is act


// Assert
items.Length.Should().Be(originalItems.Length);
items.ToArray().Should().BeEquivalentTo(originalItems);

foreach (var item in items)
{
originalItems.Should().Contain(item);
}
}
}
}
60 changes: 60 additions & 0 deletions PolyShim.Tests/NetCore20/RandomNumberGeneratorTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
using System;
using System.Linq;
using System.Security.Cryptography;
using FluentAssertions;
using Xunit;

namespace PolyShim.Tests.NetCore20;

public class RandomNumberGeneratorTests
{
[Fact]
public void GetBytes_PartialArray_Test()
{
for (var i = 0; i < 100; i++)
{
// Arrange
using var rng = RandomNumberGenerator.Create();
var data = new byte[20];
Comment on lines +17 to +18
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is arrange


// Act
rng.GetBytes(data, 5, 10);
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is act


// Assert
data.Take(5).Should().OnlyContain(b => b == 0);
data.Skip(5).Take(10).Should().Contain(b => b != 0);
data.Skip(15).Should().OnlyContain(b => b == 0);
Comment on lines +24 to +26
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is assert

}
}

[Fact]
public void GetBytes_EmptyCount_Test()
{
// Arrange
using var rng = RandomNumberGenerator.Create();
var data = new byte[10];

// Act
rng.GetBytes(data, 0, 0);

// Assert
data.Should().OnlyContain(b => b == 0);
}

[Fact]
public void GetNonZeroBytes_Array_Test()
{
for (var i = 0; i < 100; i++)
{
// Arrange
using var rng = RandomNumberGenerator.Create();
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is arrange

var data = new byte[10];

// Act
rng.GetNonZeroBytes(data);
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is act


// Assert
data.Should().NotContain((byte)0);
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is assert

}
}
}
67 changes: 58 additions & 9 deletions PolyShim.Tests/NetCore21/RandomNumberGeneratorTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,20 @@ public class RandomNumberGeneratorTests
[Fact]
public void Fill_Span_Test()
{
// Arrange
var span = new Span<byte>(new byte[16]);
for (var i = 0; i < 100; i++)
{
// Arrange
var span = new Span<byte>(new byte[16]);
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is arrange


// Act
RandomNumberGenerator.Fill(span);
// Act
RandomNumberGenerator.Fill(span);
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is act


// Assert
// Verify that not all bytes are zero (cryptographic RNG should produce non-zero data).
// Note: Theoretically, a crypto RNG could produce all zeros (probability: 2^-128),
// but this is astronomically unlikely in practice.
span.ToArray().Should().Contain(b => b != 0);
// Assert
// Verify that not all bytes are zero (cryptographic RNG should produce non-zero data).
// Note: Theoretically, a crypto RNG could produce all zeros (probability: 2^-128),
// but this is astronomically unlikely in practice.
span.ToArray().Should().Contain(b => b != 0);
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is assert

}
}

[Fact]
Expand All @@ -33,4 +36,50 @@ public void Fill_EmptySpan_Test()
// Should not throw and should return immediately
RandomNumberGenerator.Fill(span);
}

[Fact]
public void GetBytes_Span_Test()
{
for (var i = 0; i < 100; i++)
{
// Arrange
using var rng = RandomNumberGenerator.Create();
var span = new Span<byte>(new byte[16]);

// Act
rng.GetBytes(span);

// Assert
span.ToArray().Should().Contain(b => b != 0);
}
}

[Fact]
public void GetBytes_EmptySpan_Test()
{
// Arrange
using var rng = RandomNumberGenerator.Create();
var span = new Span<byte>();

// Act & Assert
// Should not throw and should return immediately
rng.GetBytes(span);
}

[Fact]
public void GetNonZeroBytes_Span_Test()
{
for (var i = 0; i < 100; i++)
{
// Arrange
using var rng = RandomNumberGenerator.Create();
var data = new Span<byte>(new byte[10]);

// Act
rng.GetNonZeroBytes(data);

// Assert
data.ToArray().Should().NotContain((byte)0);
}
}
}
34 changes: 34 additions & 0 deletions PolyShim.Tests/NetCore30/RandomNumberGeneratorTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
using System.Security.Cryptography;
using FluentAssertions;
using Xunit;

namespace PolyShim.Tests.NetCore30;

public class RandomNumberGeneratorTests
{
[Fact]
public void GetInt32_MaxValue_Test()
{
for (var i = 0; i < 100; i++)
{
// Act
var value = RandomNumberGenerator.GetInt32(10);

// Assert
value.Should().BeInRange(0, 9);
}
}

[Fact]
public void GetInt32_Range_Test()
{
for (var i = 0; i < 100; i++)
{
// Act
var value = RandomNumberGenerator.GetInt32(10, 20);

// Assert
value.Should().BeInRange(10, 19);
}
}
}
26 changes: 26 additions & 0 deletions PolyShim/Net60/RandomNumberGenerator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#if (NETCOREAPP && !NET6_0_OR_GREATER) || (NETFRAMEWORK) || (NETSTANDARD)
#nullable enable
// ReSharper disable RedundantUsingDirective
// ReSharper disable CheckNamespace
// ReSharper disable InconsistentNaming
// ReSharper disable PartialTypeWithSinglePart

using System;
using System.Diagnostics.CodeAnalysis;
using System.Security.Cryptography;

[ExcludeFromCodeCoverage]
internal static class MemberPolyfills_Net60_RandomNumberGenerator
{
extension(RandomNumberGenerator)
{
// https://learn.microsoft.com/dotnet/api/system.security.cryptography.randomnumbergenerator.getbytes#system-security-cryptography-randomnumbergenerator-getbytes(system-int32)
public static byte[] GetBytes(int count)
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method was added in net 6

{
var data = new byte[count];
RandomNumberGenerator.Fill(data);
return data;
}
}
}
#endif
Loading
Loading