Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Struct equality implemented properly. #163

Merged
merged 5 commits into from
Jan 4, 2024
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
16 changes: 16 additions & 0 deletions src/FuncSharp.Tests/Numeric/DigitTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,22 @@ internal void AsDigit()
OptionAssert.IsEmpty(char.MaxValue.AsDigit());
}

[Fact]
internal void Equality()
{
Assert.Equal('0'.AsDigit(), '0'.AsDigit());
Assert.Equal('1'.AsDigit(), '1'.AsDigit());
Assert.Equal('2'.AsDigit(), '2'.AsDigit());
Assert.Equal('3'.AsDigit(), '3'.AsDigit());
Assert.Equal('4'.AsDigit(), '4'.AsDigit());

Assert.NotEqual('0'.AsDigit(), '9'.AsDigit());
Assert.NotEqual('1'.AsDigit(), '8'.AsDigit());
Assert.NotEqual('2'.AsDigit(), '7'.AsDigit());
Assert.NotEqual('3'.AsDigit(), '6'.AsDigit());
Assert.NotEqual('4'.AsDigit(), '5'.AsDigit());
}

[Fact]
internal void FilterDigits()
{
Expand Down
13 changes: 13 additions & 0 deletions src/FuncSharp.Tests/Numeric/NonNegativeDecimalTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,4 +60,17 @@ internal void AsUnsafeNonNegative(decimal number)
Assert.Throws<ArgumentException>(() => number.AsUnsafeNonNegative());
}
}

[Property]
internal void Equality(decimal first, decimal second)
{
var numbersAreEqual = first == second;
var firstOption = first.AsNonNegative();
var secondOption = second.AsNonNegative();
var bothOptionsEmpty = firstOption.IsEmpty && secondOption.IsEmpty;
if (!bothOptionsEmpty)
{
Assert.Equal(numbersAreEqual, firstOption == secondOption);
}
}
}
13 changes: 13 additions & 0 deletions src/FuncSharp.Tests/Numeric/NonNegativeIntTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,4 +60,17 @@ internal void AsUnsafeNonNegative(int number)
Assert.Throws<ArgumentException>(() => number.AsUnsafeNonNegative());
}
}

[Property]
internal void Equality(int first, int second)
{
var numbersAreEqual = first == second;
var firstOption = first.AsNonNegative();
var secondOption = second.AsNonNegative();
var bothOptionsEmpty = firstOption.IsEmpty && secondOption.IsEmpty;
if (!bothOptionsEmpty)
{
Assert.Equal(numbersAreEqual, firstOption == secondOption);
}
}
}
13 changes: 13 additions & 0 deletions src/FuncSharp.Tests/Numeric/NonNegativeLongTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,4 +60,17 @@ internal void AsUnsafeNonNegative(long number)
Assert.Throws<ArgumentException>(() => number.AsUnsafeNonNegative());
}
}

[Property]
internal void Equality(long first, long second)
{
var numbersAreEqual = first == second;
var firstOption = first.AsNonNegative();
var secondOption = second.AsNonNegative();
var bothOptionsEmpty = firstOption.IsEmpty && secondOption.IsEmpty;
if (!bothOptionsEmpty)
{
Assert.Equal(numbersAreEqual, firstOption == secondOption);
}
}
}
13 changes: 13 additions & 0 deletions src/FuncSharp.Tests/Numeric/NonNegativeShortTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,4 +60,17 @@ internal void AsUnsafeNonNegative(short number)
Assert.Throws<ArgumentException>(() => number.AsUnsafeNonNegative());
}
}

[Property]
internal void Equality(short first, short second)
{
var numbersAreEqual = first == second;
var firstOption = first.AsNonNegative();
var secondOption = second.AsNonNegative();
var bothOptionsEmpty = firstOption.IsEmpty && secondOption.IsEmpty;
if (!bothOptionsEmpty)
{
Assert.Equal(numbersAreEqual, firstOption == secondOption);
}
}
}
13 changes: 13 additions & 0 deletions src/FuncSharp.Tests/Numeric/NonPositiveDecimalTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,4 +60,17 @@ internal void AsUnsafeNonPositive(decimal number)
Assert.Throws<ArgumentException>(() => number.AsUnsafeNonPositive());
}
}

[Property]
internal void Equality(decimal first, decimal second)
{
var numbersAreEqual = first == second;
var firstOption = first.AsNonPositive();
var secondOption = second.AsNonPositive();
var bothOptionsEmpty = firstOption.IsEmpty && secondOption.IsEmpty;
if (!bothOptionsEmpty)
{
Assert.Equal(numbersAreEqual, firstOption == secondOption);
}
}
}
13 changes: 13 additions & 0 deletions src/FuncSharp.Tests/Numeric/NonPositiveIntTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,4 +60,17 @@ internal void AsUnsafeNonPositive(int number)
Assert.Throws<ArgumentException>(() => number.AsUnsafeNonPositive());
}
}

[Property]
internal void Equality(int first, int second)
{
var numbersAreEqual = first == second;
var firstOption = first.AsNonPositive();
var secondOption = second.AsNonPositive();
var bothOptionsEmpty = firstOption.IsEmpty && secondOption.IsEmpty;
if (!bothOptionsEmpty)
{
Assert.Equal(numbersAreEqual, firstOption == secondOption);
}
}
}
13 changes: 13 additions & 0 deletions src/FuncSharp.Tests/Numeric/NonPositiveLongTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,4 +60,17 @@ internal void AsUnsafeNonPositive(long number)
Assert.Throws<ArgumentException>(() => number.AsUnsafeNonPositive());
}
}

[Property]
internal void Equality(long first, long second)
{
var numbersAreEqual = first == second;
var firstOption = first.AsNonPositive();
var secondOption = second.AsNonPositive();
var bothOptionsEmpty = firstOption.IsEmpty && secondOption.IsEmpty;
if (!bothOptionsEmpty)
{
Assert.Equal(numbersAreEqual, firstOption == secondOption);
}
}
}
13 changes: 13 additions & 0 deletions src/FuncSharp.Tests/Numeric/NonPositiveShortTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,4 +60,17 @@ internal void AsUnsafeNonPositive(short number)
Assert.Throws<ArgumentException>(() => number.AsUnsafeNonPositive());
}
}

[Property]
internal void Equality(short first, short second)
{
var numbersAreEqual = first == second;
var firstOption = first.AsNonPositive();
var secondOption = second.AsNonPositive();
var bothOptionsEmpty = firstOption.IsEmpty && secondOption.IsEmpty;
if (!bothOptionsEmpty)
{
Assert.Equal(numbersAreEqual, firstOption == secondOption);
}
}
}
13 changes: 13 additions & 0 deletions src/FuncSharp.Tests/Numeric/PositiveDecimalTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,4 +60,17 @@ internal void AsUnsafePositive(decimal number)
Assert.Throws<ArgumentException>(() => number.AsUnsafePositive());
}
}

[Property]
internal void Equality(decimal first, decimal second)
{
var numbersAreEqual = first == second;
var firstOption = first.AsPositive();
var secondOption = second.AsPositive();
var bothOptionsEmpty = firstOption.IsEmpty && secondOption.IsEmpty;
if (!bothOptionsEmpty)
{
Assert.Equal(numbersAreEqual, firstOption == secondOption);
}
}
}
13 changes: 13 additions & 0 deletions src/FuncSharp.Tests/Numeric/PositiveIntTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,4 +60,17 @@ internal void AsUnsafePositive(int number)
Assert.Throws<ArgumentException>(() => number.AsUnsafePositive());
}
}

[Property]
internal void Equality(int first, int second)
{
var numbersAreEqual = first == second;
var firstOption = first.AsPositive();
var secondOption = second.AsPositive();
var bothOptionsEmpty = firstOption.IsEmpty && secondOption.IsEmpty;
if (!bothOptionsEmpty)
{
Assert.Equal(numbersAreEqual, firstOption == secondOption);
}
}
}
13 changes: 13 additions & 0 deletions src/FuncSharp.Tests/Numeric/PositiveLongTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,4 +60,17 @@ internal void AsUnsafePositive(long number)
Assert.Throws<ArgumentException>(() => number.AsUnsafePositive());
}
}

[Property]
internal void Equality(long first, long second)
{
var numbersAreEqual = first == second;
var firstOption = first.AsPositive();
var secondOption = second.AsPositive();
var bothOptionsEmpty = firstOption.IsEmpty && secondOption.IsEmpty;
if (!bothOptionsEmpty)
{
Assert.Equal(numbersAreEqual, firstOption == secondOption);
}
}
}
13 changes: 13 additions & 0 deletions src/FuncSharp.Tests/Numeric/PositiveShortTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,4 +60,17 @@ internal void AsUnsafePositive(short number)
Assert.Throws<ArgumentException>(() => number.AsUnsafePositive());
}
}

[Property]
internal void Equality(short first, short second)
{
var numbersAreEqual = first == second;
var firstOption = first.AsPositive();
var secondOption = second.AsPositive();
var bothOptionsEmpty = firstOption.IsEmpty && secondOption.IsEmpty;
if (!bothOptionsEmpty)
{
Assert.Equal(numbersAreEqual, firstOption == secondOption);
}
}
}
27 changes: 23 additions & 4 deletions src/FuncSharp.Tests/Strings/NonEmptyStringEqualityTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,21 +43,40 @@ public void EqualityTest()

string text = "ASDF123";
NonEmptyString nonEmptyString = NonEmptyString.CreateUnsafe("ASDF123");
NonEmptyString nonEmptyStringWithSameValue = NonEmptyString.CreateUnsafe("ASDF123");
Assert.True(text == nonEmptyString);
Assert.False(text != nonEmptyString);
Assert.True(nonEmptyString == text);
Assert.False(nonEmptyString != text);
Assert.True(nonEmptyString == nonEmptyStringWithSameValue);
Assert.False(nonEmptyString != nonEmptyStringWithSameValue);

Assert.True(text.Equals(nonEmptyString));
Assert.True(nonEmptyString.Equals(text));
Assert.True(nonEmptyString.Equals(nonEmptyStringWithSameValue));

Assert.False(object.Equals(text, nonEmptyString)); // Unfortunately string doesn't override the default Equals method to compare with IEquatable<string> therefore this is false.
Assert.True(object.Equals(nonEmptyString, text));
Assert.True(object.Equals(nonEmptyString, nonEmptyStringWithSameValue));

string differentString = "Text14";
NonEmptyString differentNonEmptyString = NonEmptyString.CreateUnsafe("Totally different text here.");
Assert.False(differentNonEmptyString.Equals(differentString));
Assert.False(differentString.Equals(differentNonEmptyString));
Assert.False(differentNonEmptyString == differentString);
NonEmptyString differentNonEmptyString2 = NonEmptyString.CreateUnsafe("And completely different again.");

Assert.False(differentString == differentNonEmptyString);
Assert.False(object.Equals(differentNonEmptyString, differentString));
Assert.True(differentString != differentNonEmptyString);
Assert.False(differentNonEmptyString == differentString);
Assert.True(differentNonEmptyString != differentString);
Assert.False(differentNonEmptyString == differentNonEmptyString2);
Assert.True(differentNonEmptyString != differentNonEmptyString2);

Assert.False(differentString.Equals(differentNonEmptyString));
Assert.False(differentNonEmptyString.Equals(differentString));
Assert.False(differentNonEmptyString.Equals(differentNonEmptyString2));

Assert.False(object.Equals(differentString, differentNonEmptyString));
Assert.False(object.Equals(differentNonEmptyString, differentString));
Assert.False(object.Equals(differentNonEmptyString, differentNonEmptyString2));

NonEmptyString null1 = null;
string null2 = null;
Expand Down
8 changes: 4 additions & 4 deletions src/FuncSharp/FuncSharp.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
<PropertyGroup>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<NoWarn>CS1591</NoWarn>
<Version>9.0.1</Version>
<AssemblyVersion>9.0.1</AssemblyVersion>
<FileVersion>9.0.1</FileVersion>
<Version>9.0.2</Version>
<AssemblyVersion>9.0.2</AssemblyVersion>
<FileVersion>9.0.2</FileVersion>
<PackageId>FuncSharp</PackageId>
<Description>A C# library with main purpose to reduce boilerplate code and avoid bugs thanks to stronger typing. Utilizes many concepts from functional programming languages that are also applicable in C#. Originally written by Honza Široký.</Description>
<Authors>Mews, Honza Široký</Authors>
Expand All @@ -13,7 +13,7 @@
<PackageProjectUrl>https://github.com/MewsSystems/FuncSharp</PackageProjectUrl>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<PackageRequireLicenseAcceptance>false</PackageRequireLicenseAcceptance>
<PackageReleaseNotes>Prevented boxing of options when checking for equality.</PackageReleaseNotes>
<PackageReleaseNotes>All the structs now have proper equality implementation.</PackageReleaseNotes>
<RepositoryType>git</RepositoryType>
<RepositoryUrl>https://github.com/MewsSystems/FuncSharp</RepositoryUrl>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
Expand Down
25 changes: 18 additions & 7 deletions src/FuncSharp/Numeric/Digit.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace FuncSharp;

public readonly struct Digit
public readonly struct Digit : IEquatable<Digit>
{
private Digit(byte value)
{
Expand All @@ -13,10 +13,6 @@ private Digit(byte value)
public static implicit operator byte(Digit i) => i.Value;
public static implicit operator int(Digit i) => i.Value;

public static bool operator ==(Digit left, Digit right) => left.Equals(right);

public static bool operator !=(Digit left, Digit right) => !left.Equals(right);

public static Option<Digit> Create(char value)
{
return CreateNullable(value).ToOption();
Expand All @@ -36,9 +32,24 @@ public static Digit CreateUnsafe(char value)
: null;
}

public override bool Equals(object obj) => obj is Digit other && Value == other.Value;
public static bool operator ==(Digit left, Digit right) => left.Equals(right);

public static bool operator !=(Digit left, Digit right) => !left.Equals(right);

public override int GetHashCode() => Value.GetHashCode();
public override bool Equals(object obj)
{
return obj is Digit other && Equals(other);
}

public bool Equals(Digit other)
{
return Value == other.Value;
}

public override int GetHashCode()
{
return Value.GetHashCode();
}

public override string ToString()
{
Expand Down
Loading
Loading