Skip to content

Commit 6233367

Browse files
committed
Add run-coverage.sh, improve Combinations logic, and enhance tests
1 parent 11c5ca5 commit 6233367

8 files changed

Lines changed: 80 additions & 26 deletions

File tree

DotNetExtensions.slnx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
<File Path=".github\workflows\codeql.yml" />
44
<File Path=".github\workflows\dotnet.yml" />
55
<File Path="global.json" />
6+
<File Path="run-coverage.sh" />
67
</Folder>
78
<Project Path="DotNetExtensions\DotNetExtensions.csproj" />
89
<Project Path="DotNetExtensionsTests\DotNetExtensionsTests.csproj" />

DotNetExtensions/Collections/Combinations.cs

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,19 +22,21 @@ public static IEnumerable<List<T>> Combinations<T>(this IEnumerable<T> source, i
2222
ArgumentNullException.ThrowIfNull(source);
2323
ArgumentOutOfRangeException.ThrowIfNegative(length);
2424

25+
if (length == 0)
26+
return [[]];
27+
28+
if (source.TryGetNonEnumeratedCount(out var count))
29+
{
30+
if (length > count) return [];
31+
if (length == count) return [source.ToList()];
32+
}
33+
2534
return CombinationsInternal(source, length);
2635
}
2736

2837
private static IEnumerable<List<T>> CombinationsInternal<T>(IEnumerable<T> source, int length)
2938
{
30-
var array = source as IList<T> ?? source.ToArray();
31-
32-
if (length == 0)
33-
{
34-
yield return [];
35-
yield break;
36-
}
37-
39+
var array = source as IList<T> ?? source.ToList();
3840
if (length > array.Count)
3941
yield break;
4042

DotNetExtensions/DotNetExtensions.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
</PropertyGroup>
1414

1515
<PropertyGroup>
16-
<Version>5.13.1</Version>
16+
<Version>5.13.2</Version>
1717
<Authors>Diogo Medeiros</Authors>
1818
<Company>Diogo Medeiros</Company>
1919
<Description>This is a collection of extension methods for .NET Core.</Description>

DotNetExtensionsTests/Collections/CombinationsTests.cs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,11 +65,20 @@ public async Task Combinations_LengthThree_ReturnsAllThreeElementCombinations()
6565
await Assert.That(result[9]).IsEquivalentTo([3, 4, 5]);
6666
}
6767

68+
[Test]
69+
public async Task Combinations_LengthEqualsSource_ReturnsWholeSourceAsCombination()
70+
{
71+
var result = _defaultSource.Combinations(_defaultSource.Length).ToList();
72+
await Assert.That(result).HasSingleItem();
73+
await Assert.That(result[0]).IsEquivalentTo(_defaultSource);
74+
}
75+
6876
[Test]
6977
public async Task Combinations_LengthGreaterThanSource_ReturnsEmpty()
7078
{
71-
var result = _defaultSource.Combinations(6).ToList();
72-
await Assert.That(result).IsEmpty();
79+
using var _ = Assert.Multiple();
80+
await Assert.That(_defaultSource.Combinations(6)).IsEmpty();
81+
await Assert.That(Numbers().Combinations(6).ToList()).IsEmpty();
7382
}
7483

7584
[Test]

DotNetExtensionsTests/Collections/EnumerableExtensionsTests.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,13 @@ public partial class EnumerableExtensionsTests
66

77
[Before(Class)]
88
public static void Setup() => _defaultSource = [1, 2, 3, 4, 5];
9+
10+
private static IEnumerable<int> Numbers()
11+
{
12+
yield return 1;
13+
yield return 2;
14+
yield return 3;
15+
yield return 4;
16+
yield return 5;
17+
}
918
}

DotNetExtensionsTests/Collections/SkipAtTests.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@ public async Task SkipAt_ValidIndex_RemovesElementAtIndex()
1414
[Test]
1515
public void SkipAt_IndexOutOfRange_ThrowsArgumentOutOfRangeException()
1616
{
17-
Assert.ThrowsExactly<ArgumentOutOfRangeException>(() => _ = _defaultSource.SkipAt(5).ToList());
17+
using var multiple = Assert.Multiple();
18+
Assert.ThrowsExactly<ArgumentOutOfRangeException>(() => _ = _defaultSource.SkipAt(5));
19+
Assert.ThrowsExactly<ArgumentOutOfRangeException>(() => _ = Numbers().SkipAt(5).ToList());
1820
}
1921

2022
[Test]
@@ -27,7 +29,7 @@ public void SkipAt_NegativeIndex_ThrowsArgumentOutOfRangeException()
2729
public void SkipAt_EmptySource_ThrowsArgumentOutOfRangeException()
2830
{
2931
int[] source = [];
30-
Assert.ThrowsExactly<ArgumentOutOfRangeException>(() => _ = source.SkipAt(0).ToList());
32+
Assert.ThrowsExactly<ArgumentOutOfRangeException>(() => _ = source.SkipAt(0));
3133
}
3234

3335
[Test]
Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,19 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22

3-
<PropertyGroup>
4-
<ImplicitUsings>enable</ImplicitUsings>
5-
<Nullable>enable</Nullable>
6-
<OutputType>Exe</OutputType>
7-
<TargetFramework>net10.0</TargetFramework>
8-
</PropertyGroup>
3+
<PropertyGroup>
4+
<TargetFramework>net10.0</TargetFramework>
5+
<OutputType>Exe</OutputType>
6+
<Nullable>enable</Nullable>
7+
<ImplicitUsings>enable</ImplicitUsings>
8+
<LangVersion>latest</LangVersion>
9+
</PropertyGroup>
910

10-
<ItemGroup>
11-
<PackageReference Include="TUnit" Version="1.*" />
12-
</ItemGroup>
11+
<ItemGroup>
12+
<PackageReference Include="TUnit" Version="1.53.0" />
13+
</ItemGroup>
1314

14-
<ItemGroup>
15-
<ProjectReference Include="..\DotNetExtensions\DotNetExtensions.csproj" />
16-
</ItemGroup>
15+
<ItemGroup>
16+
<ProjectReference Include="..\DotNetExtensions\DotNetExtensions.csproj" />
17+
</ItemGroup>
1718

18-
</Project>
19+
</Project>

run-coverage.sh

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
4+
RESULTS_DIR="TestResults"
5+
REPORT_DIR="$RESULTS_DIR/report"
6+
7+
rm -rf "$RESULTS_DIR"
8+
mkdir -p "$RESULTS_DIR"
9+
10+
dotnet test \
11+
--coverage \
12+
--results-directory "$RESULTS_DIR" \
13+
--coverage-output-format xml \
14+
--verbosity quiet
15+
16+
COVERAGE_FILE="$(find "$RESULTS_DIR" -maxdepth 1 -type f -name '*.xml' | head -n 1)"
17+
18+
if [ -z "$COVERAGE_FILE" ]; then
19+
echo "No coverage XML file was generated."
20+
exit 1
21+
fi
22+
23+
reportgenerator \
24+
-reports:"$COVERAGE_FILE" \
25+
-targetdir:"$REPORT_DIR" \
26+
-verbosity:Warning
27+
28+
echo "Coverage report generated at: $REPORT_DIR"
29+
30+
open "$REPORT_DIR/index.html"

0 commit comments

Comments
 (0)