Skip to content

Commit

Permalink
Fix HashCode bug + added unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
joel-jeremy committed Apr 6, 2018
1 parent d4190e1 commit 99eb9ff
Show file tree
Hide file tree
Showing 7 changed files with 157 additions and 8 deletions.
2 changes: 1 addition & 1 deletion GitVersion.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
mode: ContinuousDelivery
next-version: 1.0.0
next-version: 1.0.1
branches: {}
ignore:
sha: []
12 changes: 10 additions & 2 deletions Src/Xer.DomainDriven/ValueObject.cs
Original file line number Diff line number Diff line change
Expand Up @@ -107,11 +107,19 @@ protected struct HashCode
/// <param name="fields">Value object fields.</param>
private HashCode(object[] fields)
{
if (fields == null)
{
throw new ArgumentNullException(nameof(fields));
}

if (fields.Length == 0)
_value = 0;

unchecked
{
int hash = fields.Length > 0 ? 19 : 0;
int hash = 19;

for (int i = 0; fields.Length > 0; i++)
for (int i = 0; fields.Length > i; i++)
{
hash = hash * 486187739 + fields[i]?.GetHashCode() ?? throw new ArgumentException("Cannot pass null as field.", nameof(fields));
}
Expand Down
25 changes: 25 additions & 0 deletions Tests/Xer.DomainDriven.Tests/Entities/TestVaueObject.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
namespace Xer.DomainDriven.Tests.Entities
{
public class TestValueObject : ValueObject<TestValueObject>
{
public string Data { get; }
public int Number { get; }

public TestValueObject(string data, int number)
{
Data = data;
Number = number;
}

protected override bool ValueEquals(TestValueObject other)
{
return Data == other.Data &&
Number == other.Number;
}

protected override HashCode GenerateHashCode()
{
return HashCode.From(Number, Data);
}
}
}
67 changes: 67 additions & 0 deletions Tests/Xer.DomainDriven.Tests/ValueObjectTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
using Xer.DomainDriven.Tests.Entities;
using Xunit;

namespace Xer.DomainDriven.Tests
{
public class ValueObjectTests
{
public class EqualsMethod
{
[Fact]
public void ShouldBeTrueIfValueObjectsMatchByValue()
{
TestValueObject valueObject1 = new TestValueObject("Test", 123);
TestValueObject valueObject2 = new TestValueObject("Test", 123);

Assert.True(valueObject1 == valueObject2);
}

[Fact]
public void ShouldNotBeTrueIfValueObjectsDoNotMatchByValue()
{
TestValueObject valueObject1 = new TestValueObject("Test", 123);
TestValueObject valueObject2 = new TestValueObject("Test2", 1234);

Assert.True(valueObject1 != valueObject2);
}

[Fact]
public void ShouldNotBeTrueIfComparedWithNull()
{
TestValueObject valueObject1 = new TestValueObject("Test", 123);
TestValueObject valueObject2 = null;

Assert.True(valueObject1 != valueObject2);
}
}

public class GetHashCodeMethod
{
[Fact]
public void ShouldBeSameForTheSameInstance()
{
TestValueObject valueObject1 = new TestValueObject("Test", 123);

Assert.True(valueObject1.GetHashCode() == valueObject1.GetHashCode());
}

[Fact]
public void ShouldBeSameForTheDifferentInstancesWithSameValues()
{
TestValueObject valueObject1 = new TestValueObject("Test", 123);
TestValueObject valueObject2 = new TestValueObject("Test", 123);

Assert.True(valueObject1.GetHashCode() == valueObject2.GetHashCode());
}

[Fact]
public void ShouldNotBeSameForTheDifferentInstancesWithDifferentValues()
{
TestValueObject valueObject1 = new TestValueObject("Test", 123);
TestValueObject valueObject2 = new TestValueObject("Test2", 1234);

Assert.True(valueObject1.GetHashCode() != valueObject2.GetHashCode());
}
}
}
}
20 changes: 20 additions & 0 deletions Tests/Xer.DomainDriven.Tests/Xer.DomainDriven.Tests.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netcoreapp2.0</TargetFramework>

<IsPackable>false</IsPackable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.5.0" />
<PackageReference Include="xunit" Version="2.3.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.3.1" />
<DotNetCliToolReference Include="dotnet-xunit" Version="2.3.1" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\Src\Xer.DomainDriven\Xer.DomainDriven.csproj" />
</ItemGroup>

</Project>
19 changes: 19 additions & 0 deletions Xer.DomainDriven.sln
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ VisualStudioVersion = 15.0.26124.0
MinimumVisualStudioVersion = 15.0.26124.0
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Xer.DomainDriven", "Src\Xer.DomainDriven\Xer.DomainDriven.csproj", "{B158F4B9-C157-411A-85FB-3F538432A92F}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{77122373-243D-48F3-A0DF-84F83D9467B2}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Xer.DomainDriven.Tests", "Tests\Xer.DomainDriven.Tests\Xer.DomainDriven.Tests.csproj", "{544D41FE-8042-40CC-A068-4ED39E519D9D}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand All @@ -30,5 +34,20 @@ Global
{B158F4B9-C157-411A-85FB-3F538432A92F}.Release|x64.Build.0 = Release|x64
{B158F4B9-C157-411A-85FB-3F538432A92F}.Release|x86.ActiveCfg = Release|x86
{B158F4B9-C157-411A-85FB-3F538432A92F}.Release|x86.Build.0 = Release|x86
{544D41FE-8042-40CC-A068-4ED39E519D9D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{544D41FE-8042-40CC-A068-4ED39E519D9D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{544D41FE-8042-40CC-A068-4ED39E519D9D}.Debug|x64.ActiveCfg = Debug|x64
{544D41FE-8042-40CC-A068-4ED39E519D9D}.Debug|x64.Build.0 = Debug|x64
{544D41FE-8042-40CC-A068-4ED39E519D9D}.Debug|x86.ActiveCfg = Debug|x86
{544D41FE-8042-40CC-A068-4ED39E519D9D}.Debug|x86.Build.0 = Debug|x86
{544D41FE-8042-40CC-A068-4ED39E519D9D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{544D41FE-8042-40CC-A068-4ED39E519D9D}.Release|Any CPU.Build.0 = Release|Any CPU
{544D41FE-8042-40CC-A068-4ED39E519D9D}.Release|x64.ActiveCfg = Release|x64
{544D41FE-8042-40CC-A068-4ED39E519D9D}.Release|x64.Build.0 = Release|x64
{544D41FE-8042-40CC-A068-4ED39E519D9D}.Release|x86.ActiveCfg = Release|x86
{544D41FE-8042-40CC-A068-4ED39E519D9D}.Release|x86.Build.0 = Release|x86
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{544D41FE-8042-40CC-A068-4ED39E519D9D} = {77122373-243D-48F3-A0DF-84F83D9467B2}
EndGlobalSection
EndGlobal
20 changes: 15 additions & 5 deletions build.cake
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ var configuration = Argument<string>("configuration", "Release");

var solutions = GetFiles("./**/*.sln");
var projects = GetFiles("./**/*.csproj").Select(x => x.GetDirectory());
string buildArtifactsDirectory = "./BuildArtifacts";

GitVersion gitVersion;

Expand Down Expand Up @@ -46,6 +47,13 @@ Setup(context =>
Information("Publish to myget: {0}", BuildParameters.Instance.ShouldPublishMyGet);
Information("Publish to nuget: {0}", BuildParameters.Instance.ShouldPublishNuGet);
Information("///////////////////////////////////////////////////////////////////////////////");

if (DirectoryExists(buildArtifactsDirectory))
{
// Cleanup build artifacts.
Information($"Cleaning up {buildArtifactsDirectory} directory.");
DeleteDirectory(buildArtifactsDirectory, new DeleteDirectorySettings { Recursive = true });
}
});

Teardown(context =>
Expand Down Expand Up @@ -164,7 +172,7 @@ Task("Pack")
.IsDependentOn("Test")
.Does(() =>
{
var projects = GetFiles("./src/**/*.csproj");
var projects = GetFiles("./Src/**/*.csproj");

if (projects.Count() == 0)
{
Expand All @@ -174,9 +182,9 @@ Task("Pack")

var settings = new DotNetCorePackSettings
{
OutputDirectory = "./BuildArtifacts",
NoBuild = true,
OutputDirectory = buildArtifactsDirectory,
Configuration = configuration,
NoBuild = true,
ArgumentCustomization = (args) => args
.Append("/p:Version={0}", gitVersion.LegacySemVerPadded)
.Append("/p:AssemblyVersion={0}", gitVersion.MajorMinorPatch)
Expand All @@ -195,7 +203,8 @@ Task("PublishMyGet")
.IsDependentOn("Pack")
.Does(() =>
{
var nupkgs = GetFiles("./**/*.nupkg");
// Nupkgs in BuildArtifacts folder.
var nupkgs = GetFiles(buildArtifactsDirectory + "/*.nupkg");

if (nupkgs.Count() == 0)
{
Expand All @@ -220,7 +229,8 @@ Task("PublishNuGet")
.IsDependentOn("Pack")
.Does(() =>
{
var nupkgs = GetFiles("./**/*.nupkg");
// Nupkgs in BuildArtifacts folder.
var nupkgs = GetFiles(buildArtifactsDirectory + "/*.nupkg");

if (nupkgs.Count() == 0)
{
Expand Down

0 comments on commit 99eb9ff

Please sign in to comment.