Skip to content

Commit

Permalink
Merge pull request #4 from pfpack/release/v1.0.0
Browse files Browse the repository at this point in the history
release/v1.0.0
  • Loading branch information
andreise authored Feb 26, 2023
2 parents 47f2fee + 9f32d3d commit 0b93047
Show file tree
Hide file tree
Showing 38 changed files with 1,491 additions and 12 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
using System;
using System.Collections.Generic;
using Xunit;

namespace PrimeFuncPack.Collections.Generic.EqualityComparers.Tests.ArrayEqualityComparer;

public static class EqualityComparerTestsFactory
{
private static Type ComparerType => typeof(ArrayEqualityComparer<object>);

[Theory]
[MemberData(nameof(Test_Factory_ExpectItemComparer_Cases))]
public static void Test_Factory_ExpectItemComparer(ArrayEqualityComparer<object> comparer, object expectedItemComparer)
=>
FactoryTestHelper.AssertItemComparerMatch(ComparerType, comparer, expectedItemComparer);

public static IEnumerable<object[]> Test_Factory_ExpectItemComparer_Cases()
{
yield return new object[]
{
ArrayEqualityComparer<object>.Default,
EqualityComparer<object>.Default
};
yield return new object[]
{
ArrayEqualityComparer<object>.Create(),
EqualityComparer<object>.Default
};
yield return new object[]
{
ArrayEqualityComparer<object>.Create(null),
EqualityComparer<object>.Default
};
yield return new object[]
{
ArrayEqualityComparer<object>.Create(EqualityComparer<object>.Default),
EqualityComparer<object>.Default
};
yield return new object[]
{
ArrayEqualityComparer<object>.Create(CustomEqualityComparer<object>.Default),
CustomEqualityComparer<object>.Default
};
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using System.Collections.Generic;
using Xunit;

namespace PrimeFuncPack.Collections.Generic.EqualityComparers.Tests.ArrayEqualityComparer;

public static class EqualityComparerTestsGeneral
{
private static readonly ArrayEqualityComparer<object> comparer
= ArrayEqualityComparer<object>.Create(CustomEqualityComparer<object>.Default);

[Fact]
public static void Test_GetHashCode_SourceIsNull_ExpectZero()
{
object[]? nullObj = null;
var actual = comparer.GetHashCode(nullObj);
Assert.StrictEqual(0, actual);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
using System.Collections.Generic;
using Xunit;

namespace PrimeFuncPack.Collections.Generic.EqualityComparers.Tests.ArrayEqualityComparer;

public static class EqualityComparerTestsRef
{
private static readonly ArrayEqualityComparer<string?> comparer
= ArrayEqualityComparer<string?>.Create(CustomEqualityComparer<string?>.Default);

[Theory]
[MemberData(nameof(SourceAreEqualCases))]
public static void Test_GetHashCode_SourceAreEqual_ExpectHashCodesAreEqual(CaseParamOfArray<string?> source1, CaseParamOfArray<string?> source2)
{
var hashCode1 = comparer.GetHashCode(source1.Items);
var hashCode2 = comparer.GetHashCode(source2.Items);
Assert.StrictEqual(hashCode1, hashCode2);
}

[Theory]
[MemberData(nameof(SourceAreEqualCases))]
public static void Test_Equals_SourceAreEqual_ExpectTrue(CaseParamOfArray<string?> source1, CaseParamOfArray<string?> source2)
{
var actualEquals = comparer.Equals(source1.Items, source2.Items);
Assert.True(actualEquals);
}

[Theory]
[MemberData(nameof(SourceAreNotEqualCases))]
public static void Test_Equals_SourceAreNotEqual_ExpectTrue(CaseParamOfArray<string?> source1, CaseParamOfArray<string?> source2)
{
var actualEquals = comparer.Equals(source1.Items, source2.Items);
Assert.False(actualEquals);
}

public static IEnumerable<object[]> SourceAreEqualCases()
=>
CaseSourcesArrayRef.SourceAreEqualCases();

public static IEnumerable<object[]> SourceAreNotEqualCases()
=>
CaseSourcesArrayRef.SourceAreNotEqualCases();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
using System.Collections.Generic;
using Xunit;

namespace PrimeFuncPack.Collections.Generic.EqualityComparers.Tests.ArrayEqualityComparer;

public static class EqualityComparerTestsStruct
{
private static readonly ArrayEqualityComparer<int?> comparer
= ArrayEqualityComparer<int?>.Create(CustomEqualityComparer<int?>.Default);

[Theory]
[MemberData(nameof(SourceAreEqualCases))]
public static void Test_GetHashCode_SourceAreEqual_ExpectHashCodesAreEqual(CaseParamOfArray<int?> source1, CaseParamOfArray<int?> source2)
{
var hashCode1 = comparer.GetHashCode(source1.Items);
var hashCode2 = comparer.GetHashCode(source2.Items);
Assert.StrictEqual(hashCode1, hashCode2);
}

[Theory]
[MemberData(nameof(SourceAreEqualCases))]
public static void Test_Equals_SourceAreEqual_ExpectTrue(CaseParamOfArray<int?> source1, CaseParamOfArray<int?> source2)
{
var actualEquals = comparer.Equals(source1.Items, source2.Items);
Assert.True(actualEquals);
}

[Theory]
[MemberData(nameof(SourceAreNotEqualCases))]
public static void Test_Equals_SourceAreNotEqual_ExpectTrue(CaseParamOfArray<int?> source1, CaseParamOfArray<int?> source2)
{
var actualEquals = comparer.Equals(source1.Items, source2.Items);
Assert.False(actualEquals);
}

public static IEnumerable<object[]> SourceAreEqualCases()
=>
CaseSourcesArrayStruct.SourceAreEqualCases();

public static IEnumerable<object[]> SourceAreNotEqualCases()
=>
CaseSourcesArrayStruct.SourceAreNotEqualCases();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;

namespace PrimeFuncPack.Collections.Generic.EqualityComparers.Tests;

internal static class CaseMapper
{
internal static CaseParamOfIReadOnlyList<T>[] MapToOfIReadOnlyList<T>(params CaseParamOfArray<T>[] @case)
=>
@case.Select(param => CaseParamMapper.MapToOfIReadOnlyList(param)).ToArray();

internal static CaseParamOfIList<T>[] MapToOfIList<T>(params CaseParamOfArray<T>[] @case)
=>
@case.Select(param => CaseParamMapper.MapToOfIList(param)).ToArray();

internal static CaseParamOfList<T>[] MapToOfList<T>(params CaseParamOfArray<T>[] @case)
{
var defaultEmpty = new List<T>(); // the empty per case
return @case.Select(param => CaseParamMapper.MapToOfList(param, () => defaultEmpty)).ToArray();
}

internal static CaseParamOfImmutableArray<T>[] MapToOfImmutableArray<T>(params CaseParamOfArray<T>[] @case)
=>
@case.Select(param => CaseParamMapper.MapToOfImmutableArray(param)).ToArray();

internal static IEnumerable<CaseParamOfImmutableArrayNullable<T>[]> MapToOfImmutableArrayNullable<T>(
params CaseParamOfArray<T>[] @case)
{
var param0 = @case[0];
var param1 = @case[1];

yield return new[]
{
CaseParamMapper.MapToOfImmutableArrayNullable(param0),
CaseParamMapper.MapToOfImmutableArrayNullable(param1)
};

switch (param0.Items, param1.Items)
{
case (null, null):
yield return new[]
{
BuildWrappedDefaultCase(),
BuildWrappedDefaultCase()
};
yield break;

case (null, _):
yield return new[]
{
BuildWrappedDefaultCase(),
CaseParamMapper.MapToOfImmutableArrayNullable(param1)
};
yield break;

case (_, null):
yield return new[]
{
CaseParamMapper.MapToOfImmutableArrayNullable(param0),
BuildWrappedDefaultCase()
};
yield break;
}

static CaseParamOfImmutableArrayNullable<T> BuildWrappedDefaultCase()
=>
new(new ImmutableArray<T>?(default));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using System.Collections.Generic;
using System.Collections.Immutable;

namespace PrimeFuncPack.Collections.Generic.EqualityComparers.Tests;

// This classes in intended to make xUnit not to merge test cases of collections equal by value.
// There is a difference between the test cases with collections equal by value and by reference.

public sealed record class CaseParamOfArray<T>(T[]? Items);

public sealed record class CaseParamOfIReadOnlyList<T>(IReadOnlyList<T>? Items);

public sealed record class CaseParamOfIList<T>(IList<T>? Items);

public sealed record class CaseParamOfList<T>(List<T>? Items);

public sealed record class CaseParamOfImmutableArray<T>(ImmutableArray<T> Items);

public sealed record class CaseParamOfImmutableArrayNullable<T>(ImmutableArray<T>? Items);
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;

namespace PrimeFuncPack.Collections.Generic.EqualityComparers.Tests;

internal static class CaseParamMapper
{
internal static CaseParamOfIReadOnlyList<T> MapToOfIReadOnlyList<T>(CaseParamOfArray<T> param)
=>
new(InnerMapCase(
param.Items,
() => null,
() => CustomReadOnlyList<T>.Empty,
items => new CustomReadOnlyList<T>(items)));

internal static CaseParamOfIList<T> MapToOfIList<T>(CaseParamOfArray<T> param)
=>
new(InnerMapCase(
param.Items,
() => null,
() => CustomList<T>.Empty,
items => new CustomList<T>(items)));

internal static CaseParamOfList<T> MapToOfList<T>(CaseParamOfArray<T> param, Func<List<T>> defaultEmptySupplier)
=>
new(InnerMapCase(
param.Items,
() => null,
defaultEmptySupplier,
items => new List<T>(items)));

internal static CaseParamOfImmutableArray<T> MapToOfImmutableArray<T>(CaseParamOfArray<T> param)
=>
new(InnerMapCase(
param.Items,
() => default,
() => ImmutableArray<T>.Empty,
items => ImmutableArray.Create(items)));

internal static CaseParamOfImmutableArrayNullable<T> MapToOfImmutableArrayNullable<T>(CaseParamOfArray<T> param)
=>
new(InnerMapCase(
param.Items,
() => default(ImmutableArray<T>?),
() => ImmutableArray<T>.Empty,
items => ImmutableArray.Create(items)));

private static TResult? InnerMapCase<T, TResult>(
T[]? items,
Func<TResult?> nullSupplier,
Func<TResult> defaultEmptySupplier,
Func<T[], TResult> map)
=>
items switch
{
null => nullSupplier.Invoke(),
_ when ReferenceEquals(items, EmptyArray<T>.Value) => defaultEmptySupplier.Invoke(),
_ => map.Invoke(items)
};
}
Loading

0 comments on commit 0b93047

Please sign in to comment.