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
44 changes: 44 additions & 0 deletions CodeLineCounter.Tests/HashUtilsMockTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
using CodeLineCounter.Utils;
using Moq;

namespace CodeLineCounter.Tests
{
public class HashUtilsMockTests : TestBase
{
private readonly Mock<IHashUtils> _mockHashUtils;
private readonly IHashUtils _originalImplementation;

public HashUtilsMockTests()
{
_originalImplementation = HashUtils.Implementation;
_mockHashUtils = new Mock<IHashUtils>();
HashUtils.Implementation = _mockHashUtils.Object;
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
HashUtils.Implementation = _originalImplementation;
}

base.Dispose(disposing);

}

[Fact]
public void ComputeHash_WithMockedImplementation_CallsMockMethod()
{
// Arrange
string input = "Test";
string expected = "mocked-hash";
_mockHashUtils.Setup(m => m.ComputeHash(input)).Returns(expected);

// Act
string result = HashUtils.ComputeHash(input);

// Assert
Assert.Equal(expected, result);
_mockHashUtils.Verify(m => m.ComputeHash(input), Times.Once);
}
}
}
69 changes: 69 additions & 0 deletions CodeLineCounter.Tests/HashUtilsServiceTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
using CodeLineCounter.Utils;

namespace CodeLineCounter.Tests
{
public class HashUtilsServiceTests
{
private readonly HashUtilsService _hashUtils;

public HashUtilsServiceTests()
{
_hashUtils = new HashUtilsService();
}

[Fact]
public void ComputeHash_EmptyString_ReturnsEmptyString()
{
// Arrange
string input = "";

// Act
string result = _hashUtils.ComputeHash(input);

// Assert
Assert.Equal("", result);
}

[Fact]
public void ComputeHash_NullString_ReturnsEmptyString()
{
// Arrange
string? input = null;

// Act
string result = _hashUtils.ComputeHash(input);

// Assert
Assert.Equal("", result);
}

[Fact]
public void ComputeHash_ValidString_ReturnsHash()
{
// Arrange
string input = "Hello, World!";

// Act
string result = _hashUtils.ComputeHash(input);

// Assert
Assert.NotEmpty(result);
Assert.IsType<string>(result);
}

[Fact]
public void ComputeHash_DuplicateStrings_ReturnSameHash()
{
// Arrange
string input1 = "Hello, World!";
string input2 = "Hello, World!";

// Act
string result1 = _hashUtils.ComputeHash(input1);
string result2 = _hashUtils.ComputeHash(input2);

// Assert
Assert.Equal(result1, result2);
}
}
}
10 changes: 9 additions & 1 deletion CodeLineCounter.Tests/HashUtilsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
namespace CodeLineCounter.Tests
{
public class HashUtilsTests
{
{
[Fact]
public void ComputeHash_EmptyString_ReturnsEmptyString()
{
Expand Down Expand Up @@ -62,5 +62,13 @@ public void ComputeHash_DuplicateStrings_ReturnSameHash()
// Assert
Assert.Equal(result1, result2);
}

[Fact]
public void Implementation_IsInitializedByDefault()
{
// Act & Assert
Assert.NotNull(HashUtils.Implementation);
Assert.IsType<IHashUtils>(HashUtils.Implementation, exactMatch: false);
}
}
}
3 changes: 3 additions & 0 deletions CodeLineCounter/AssemblyInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
using System.Runtime.CompilerServices;

[assembly: InternalsVisibleTo("CodeLineCounter.Tests")]
21 changes: 5 additions & 16 deletions CodeLineCounter/Utils/HashUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,12 @@ namespace CodeLineCounter.Utils
{
public static class HashUtils
{
private static readonly IHashUtils _defaultImplementation = new HashUtilsService();

internal static IHashUtils Implementation { get; set; } = _defaultImplementation;
public static string ComputeHash(string? input)
{
if (string.IsNullOrEmpty(input))
{
return "";
}

byte[] bytes = SHA256.HashData(Encoding.UTF8.GetBytes(input));

return string.Create(bytes.Length * 2, bytes, static (span, byteArray) =>
{
const string format = "x2";
for (int i = 0; i < byteArray.Length; i++)
{
byteArray[i].TryFormat(span.Slice(i * 2, 2), out _, format);
}
});
return Implementation.ComputeHash(input);
}
}
}
}
27 changes: 27 additions & 0 deletions CodeLineCounter/Utils/HashUtilsService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using System.Security.Cryptography;
using System.Text;

namespace CodeLineCounter.Utils
{
public class HashUtilsService : IHashUtils
{
public string ComputeHash(string? input)
{
if (string.IsNullOrEmpty(input))
{
return string.Empty;
}

byte[] bytes = SHA256.HashData(Encoding.UTF8.GetBytes(input));

return string.Create(bytes.Length * 2, bytes, static (span, byteArray) =>
{
const string format = "x2";
for (int i = 0; i < byteArray.Length; i++)
{
byteArray[i].TryFormat(span.Slice(i * 2, 2), out _, format);
}
});
}
}
}
7 changes: 7 additions & 0 deletions CodeLineCounter/Utils/IHashUtils.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace CodeLineCounter.Utils
{
public interface IHashUtils
{
string ComputeHash(string? input);
}
}
Loading