Skip to content
This repository was archived by the owner on Mar 8, 2025. It is now read-only.

Commit 8ca8698

Browse files
authored
Merge dev (#9)
* Upgrade to MSTest SDK v17 * Drop < .Net 6.0 * Improve CI, impl build-config matrix, drop < .NET 6.0 * Update GH workflow * Fix CI workflow * Random filters by exclusions
1 parent 2b4f154 commit 8ca8698

File tree

6 files changed

+79
-24
lines changed

6 files changed

+79
-24
lines changed

.github/workflows/dotnet-core.yml

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1-
name: .NET Core Builds
1+
name: .NET CI
22

33
on:
44
push:
5-
branches: [ master ]
5+
branches: [ "*" ]
66
pull_request:
7-
branches: [ dev ]
7+
branches: [ master ]
8+
89

910
jobs:
1011
build:
@@ -15,14 +16,14 @@ jobs:
1516
runs-on: ubuntu-latest
1617

1718
steps:
18-
- uses: actions/checkout@v2
19+
- uses: actions/checkout@v3
1920
- name: Setup .NET 6.0
20-
uses: actions/setup-dotnet@v1
21+
uses: actions/setup-dotnet@v3
2122
with:
22-
dotnet-version: 6.0.100
23-
- name: Install dependencies
23+
dotnet-version: 6.0.x
24+
- name: Restore dependencies
2425
run: dotnet restore
25-
- name: Build Mutant
26+
- name: Build
2627
run: dotnet build --configuration ${{ matrix.build-config }} --no-restore
27-
- name: Test Mutant
28+
- name: Test
2829
run: dotnet test --configuration ${{ matrix.build-config }} --no-restore --verbosity normal ./test/test.csproj

AMT.LinqExtensions/Exceptions.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
namespace AMT.LinqExtensions
2+
{
3+
public class AllElementsExcluded : System.Exception
4+
{
5+
public AllElementsExcluded(string message = DEFAULT_MESSAGE) : base(message) {}
6+
7+
8+
private const string DEFAULT_MESSAGE = "No unexcluded elements remain.";
9+
}
10+
}

AMT.LinqExtensions/LinqExtensions.cs

Lines changed: 35 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
using System;
2-
using System.Collections;
32
using System.Collections.Generic;
43
using System.Linq;
54

@@ -15,25 +14,48 @@ public static class LinqRandomizer
1514

1615
#region Public LINQ methods
1716

18-
///<summary>Returns a random element from a collection</summary>
19-
///<typeparam name="T">The element type of the collection</typeparam>
20-
///<param cref="elements">An ICollection of the specified type <seealso cref="T" /></param>
21-
///<exception cref="System.ArgumentOutOfRangeException">Thrown when the list is empty</exception>
22-
public static T Random<T> (this ICollection<T> elements)
17+
///<summary>Returns a random element from a collection.</summary>
18+
///<typeparam name="T">The element type of the collection.</typeparam>
19+
///<param cref="elements">An ICollection of the specified type <seealso cref="T" />.</param>
20+
///<exception cref="System.ArgumentOutOfRangeException">Thrown if the ICollection is empty.</exception>
21+
///<exception cref="AMT.LinqExtensions.AllElementsExcluded">Thrown if all elements have been excluded.</exception>
22+
public static T Random<T> (this ICollection<T> elements, IEnumerable<T> exclusions = null)
2323
{
2424
// Delegate to overload taking IEnumerable
25-
return Random<T>(elements as IEnumerable<T>);
25+
return Random<T>(elements as IEnumerable<T>, exclusions);
2626
}
2727

28-
///<summary>Returns a random element using an enumerable</summary>
29-
///<typeparam name="T">The element type of the enumerable</typeparam>
30-
///<param cref="elements">An IEnumerable of the specified type <seealso cref="T" /></param>
31-
///<exception cref="System.ArgumentOutOfRangeException">Thrown when the list is empty</exception>
32-
public static T Random<T> (this IEnumerable<T> elements)
28+
29+
///<summary>Returns a random element using an enumerable.</summary>
30+
///<typeparam name="T">The element type of the enumerable.</typeparam>
31+
///<param cref="elements">An IEnumerable of the specified type <seealso cref="T" />.</param>
32+
///<exception cref="System.ArgumentOutOfRangeException">Thrown if the IEnumerable is empty.</exception>
33+
///<exception cref="AMT.LinqExtensions.AllElementsExcluded">Thrown if all elements have been excluded.</exception>
34+
public static T Random<T>(this IEnumerable<T> elements, IEnumerable<T> exclusions = null)
3335
{
34-
return elements.ElementAt(_randomizer.Next(0, elements.Count() - 1));
36+
exclusions ??= new List<T>();
37+
38+
T result;
39+
int iterations = 0;
40+
do
41+
{
42+
result = elements.ElementAt(_randomizer.Next(0, elements.Count() - 1));
43+
++iterations;
44+
} while (exclusions.Contains<T>(result) && iterations < elements.Count());
45+
46+
// TODO: this approach assumes that each element has been considered. If the randomizer
47+
// repeats some values, not all elements will be considered.
48+
49+
// Reached the end of the collection (possibly) without finding an element that is not excluded.
50+
if (iterations == elements.Count() && exclusions.Contains(result))
51+
{
52+
throw new AllElementsExcluded();
53+
}
54+
55+
return result;
3556
}
3657

58+
3759
#endregion Public LINQ methods
3860
}
3961

common.props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
<!-- Assembly version & attribute controls -->
1212
<PropertyGroup>
13-
<VersionPrefix>4.0.0</VersionPrefix>
13+
<VersionPrefix>4.1.0</VersionPrefix>
1414

1515
<GenerateAssemblyConfigurationAttribute>true</GenerateAssemblyConfigurationAttribute>
1616
<GenerateAssemblyCompanyAttribute>true</GenerateAssemblyCompanyAttribute>

test/IntListRandomizerTests.cs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,29 @@ public void verify_excp_on_empty_list()
129129
act.Should().Throw<ArgumentOutOfRangeException>();
130130
}
131131

132+
133+
[Fact]
134+
public void verify_excp_after_all_excluded()
135+
{
136+
// Build a list and copy it to exclusions
137+
List<string> list = new List<string>();
138+
list.Add("one");
139+
list.Add("two");
140+
string[] exclusions = new string[list.Count];
141+
list.CopyTo(exclusions);
142+
143+
// Since all the list values will be excluded, the
144+
// exception will occur.
145+
146+
// Test via the method taking ICollection
147+
Action act = () => list.Random(exclusions);
148+
act.Should().Throw<AllElementsExcluded>();
149+
150+
// Test via the method taking IEnumerable
151+
act = () => (list as IEnumerable<string>).Random(exclusions);
152+
act.Should().Throw<AllElementsExcluded>();
153+
}
154+
132155
#endregion Negative tests
133156

134157
}

test/IntListTestFixture.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
using System;
22
using System.Collections.Generic;
3-
using Xunit;
43

54

65
namespace Test.AMT.LinqExtensions

0 commit comments

Comments
 (0)