-
Notifications
You must be signed in to change notification settings - Fork 0
chore(mutation): add per-BC Stryker tooling and exclude i18n registration from scope #158
Changes from 9 commits
2aa0e54
2995f9b
0a333d7
b2f3f1b
b69a005
95514a2
d9aa66d
e50296f
95e69c6
b2ee937
2d483a3
7cd28a1
ae11b69
eaef5fa
146d5a2
d856774
2124519
fd73a67
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| { | ||
| "version": 1, | ||
| "isRoot": true, | ||
| "tools": { | ||
| "dotnet-stryker": { | ||
| "version": "4.14.2", | ||
| "commands": [ | ||
| "dotnet-stryker" | ||
| ], | ||
| "rollForward": false | ||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,56 @@ | ||
| namespace Coaching.Application.UnitTests.DomainTests; | ||
|
|
||
| public sealed class CoachingIdTests | ||
| { | ||
| [Fact] | ||
| public void Should_RejectEmptyGuid_When_PlayerCoachingProfileIdFromEmpty() | ||
| { | ||
| var act = () => PlayerCoachingProfileId.From(Guid.Empty); | ||
|
|
||
| act.Should().Throw<ArgumentException>(); | ||
| } | ||
|
|
||
| [Fact] | ||
| public void Should_WrapValue_When_PlayerCoachingProfileIdFromGuid() | ||
| { | ||
| var guid = Guid.NewGuid(); | ||
|
|
||
| PlayerCoachingProfileId.From(guid).Value.Should().Be(guid); | ||
| } | ||
|
|
||
| [Fact] | ||
| public void Should_BeEqual_When_PlayerCoachingProfileIdsShareValue() | ||
| { | ||
| var guid = Guid.NewGuid(); | ||
|
|
||
| PlayerCoachingProfileId.From(guid).Should().Be(PlayerCoachingProfileId.From(guid)); | ||
| } | ||
|
|
||
| [Fact] | ||
| public void Should_GenerateDistinctIds_When_PlayerCoachingProfileIdCreated() | ||
| { | ||
| PlayerCoachingProfileId.Create().Should().NotBe(PlayerCoachingProfileId.Create()); | ||
| } | ||
|
|
||
| [Fact] | ||
| public void Should_RejectEmptyGuid_When_UserWeeklyProgressionIdFromEmpty() | ||
| { | ||
| var act = () => UserWeeklyProgressionId.From(Guid.Empty); | ||
|
|
||
| act.Should().Throw<ArgumentException>(); | ||
| } | ||
|
|
||
| [Fact] | ||
| public void Should_BeEqual_When_UserWeeklyProgressionIdsShareValue() | ||
| { | ||
| var guid = Guid.NewGuid(); | ||
|
|
||
| UserWeeklyProgressionId.From(guid).Should().Be(UserWeeklyProgressionId.From(guid)); | ||
| } | ||
|
|
||
| [Fact] | ||
| public void Should_GenerateDistinctIds_When_UserWeeklyProgressionIdCreated() | ||
| { | ||
| UserWeeklyProgressionId.Create().Should().NotBe(UserWeeklyProgressionId.Create()); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,44 @@ | ||
| namespace Coaching.Application.UnitTests.DomainTests; | ||
|
|
||
| public sealed class LeverImpactEstimateTests | ||
| { | ||
| [Fact] | ||
| public void Should_ExposeBothDimensions_When_Constructed() | ||
| { | ||
| var estimate = new LeverImpactEstimate(12.5, 2.0); | ||
|
|
||
| estimate.EstimatedDpsGainPct.Should().Be(12.5); | ||
| estimate.EstimatedDeathsAvoided.Should().Be(2.0); | ||
| } | ||
|
|
||
| [Theory] | ||
| [InlineData(double.NaN, 1.0)] | ||
| [InlineData(double.PositiveInfinity, 1.0)] | ||
| [InlineData(1.0, double.NaN)] | ||
| [InlineData(1.0, double.NegativeInfinity)] | ||
| public void Should_RefuseConstruction_When_AnyDimensionIsNotFinite(double dps, double deaths) | ||
| { | ||
| var act = () => new LeverImpactEstimate(dps, deaths); | ||
|
|
||
| act.Should().Throw<ArgumentException>(); | ||
| } | ||
|
|
||
| [Theory] | ||
| [InlineData(-0.1, 1.0)] | ||
| [InlineData(1.0, -0.1)] | ||
| public void Should_RefuseConstruction_When_AnyDimensionIsNegative(double dps, double deaths) | ||
| { | ||
| var act = () => new LeverImpactEstimate(dps, deaths); | ||
|
|
||
| act.Should().Throw<ArgumentException>(); | ||
| } | ||
|
|
||
| [Fact] | ||
| public void Should_AllowZero_When_LeverHasNoEstimatedGain() | ||
| { | ||
| var estimate = new LeverImpactEstimate(0, 0); | ||
|
|
||
| estimate.EstimatedDpsGainPct.Should().Be(0); | ||
| estimate.EstimatedDeathsAvoided.Should().Be(0); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,77 @@ | ||||||||||||||
| namespace Coaching.Application.UnitTests.DomainTests; | ||||||||||||||
|
|
||||||||||||||
| public sealed class StopsMetricsTests | ||||||||||||||
| { | ||||||||||||||
| private static StopsMetrics WithOneNegative(int index) | ||||||||||||||
| { | ||||||||||||||
| var v = new int[12]; | ||||||||||||||
| for (var i = 0; i < v.Length; i++) | ||||||||||||||
| v[i] = 1; | ||||||||||||||
| v[index] = -1; | ||||||||||||||
|
Comment on lines
+7
to
+10
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
# Verify language-version support and locate non-collection-expression initializations in this test file.
fd -e csproj | xargs rg -n "<LangVersion>|<TargetFramework>"
rg -n "new int\\[12\\]" src/Coaching/Coaching.Application.UnitTests/DomainTests/StopsMetricsTests.csRepository: Leroy-Florian/WOW Length of output: 296 🏁 Script executed: #!/bin/bash
set -euo pipefail
# Locate the unit test csproj and check its C# version settings
TEST_CSPROJ="$(fd -e csproj "Coaching.Application.UnitTests" -a src | head -n 1 || true)"
echo "TEST_CSPROJ=$TEST_CSPROJ"
if [ -n "${TEST_CSPROJ:-}" ]; then
echo "== LangVersion in test csproj =="
rg -n "<LangVersion>|<TargetFramework>|<LangVersion>" "$TEST_CSPROJ" || true
fi
echo "== Any LangVersion anywhere in repo (csproj only) =="
rg -n --glob "*.csproj" "<LangVersion>" src || true
echo "== Look for existing collection expressions usage =="
# Heuristic: find `var x = [` or `int[] x = [` etc.
rg -n --glob "*.cs" --glob "!**/*.Designer.cs" "=\s*\[" src | head -n 50Repository: Leroy-Florian/WOW Length of output: 7674 🏁 Script executed: #!/bin/bash
set -euo pipefail
echo "== Repo-root global.json (if any) =="
find . -maxdepth 3 -name "global.json" -print -exec cat {} \;
echo "== Directory.Build.props (if any) containing LangVersion or C# settings =="
find . -maxdepth 4 -name "Directory.Build.props" -print
for f in $(find . -maxdepth 4 -name "Directory.Build.props"); do
echo "--- $f ---"
rg -n "LangVersion|CSharp|<LangVersion>|<TargetFramework>|LangVersion" "$f" || true
done
echo "== Any other build props targets with LangVersion =="
rg -n --glob "**/*.props" --glob "**/*.targets" "<LangVersion>|LangVersion" . || trueRepository: Leroy-Florian/WOW Length of output: 503 Replace the
♻️ Proposed fix- var v = new int[12];
- for (var i = 0; i < v.Length; i++)
- v[i] = 1;
+ int[] v = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1];
v[index] = -1;📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||
| return new StopsMetrics( | ||||||||||||||
| v[0], v[1], v[2], v[3], v[4], v[5], | ||||||||||||||
| v[6], v[7], v[8], v[9], v[10], v[11]); | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| [Theory] | ||||||||||||||
| [InlineData(0)] | ||||||||||||||
| [InlineData(1)] | ||||||||||||||
| [InlineData(2)] | ||||||||||||||
| [InlineData(3)] | ||||||||||||||
| [InlineData(4)] | ||||||||||||||
| [InlineData(5)] | ||||||||||||||
| [InlineData(6)] | ||||||||||||||
| [InlineData(7)] | ||||||||||||||
| [InlineData(8)] | ||||||||||||||
| [InlineData(9)] | ||||||||||||||
| [InlineData(10)] | ||||||||||||||
| [InlineData(11)] | ||||||||||||||
| public void Should_RefuseConstruction_When_AnyCountIsNegative(int negativeField) | ||||||||||||||
| { | ||||||||||||||
| var act = () => WithOneNegative(negativeField); | ||||||||||||||
|
|
||||||||||||||
| act.Should().Throw<ArgumentException>(); | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| [Fact] | ||||||||||||||
| public void Should_ExposeEveryCount_When_Constructed() | ||||||||||||||
| { | ||||||||||||||
| var metrics = new StopsMetrics( | ||||||||||||||
| totalStops: 1, kickCount: 2, crowdControlCount: 3, | ||||||||||||||
| correctStopCount: 4, acceptableStopCount: 5, wastedKickCount: 6, | ||||||||||||||
| successfulStopCount: 7, lateNoEffectCount: 8, immuneCount: 9, | ||||||||||||||
| overcappedStopCount: 10, missedOpportunityCount: 11, runCount: 12); | ||||||||||||||
|
|
||||||||||||||
| metrics.TotalStops.Should().Be(1); | ||||||||||||||
| metrics.KickCount.Should().Be(2); | ||||||||||||||
| metrics.CrowdControlCount.Should().Be(3); | ||||||||||||||
| metrics.CorrectStopCount.Should().Be(4); | ||||||||||||||
| metrics.AcceptableStopCount.Should().Be(5); | ||||||||||||||
| metrics.WastedKickCount.Should().Be(6); | ||||||||||||||
| metrics.SuccessfulStopCount.Should().Be(7); | ||||||||||||||
| metrics.LateNoEffectCount.Should().Be(8); | ||||||||||||||
| metrics.ImmuneCount.Should().Be(9); | ||||||||||||||
| metrics.OvercappedStopCount.Should().Be(10); | ||||||||||||||
| metrics.MissedOpportunityCount.Should().Be(11); | ||||||||||||||
| metrics.RunCount.Should().Be(12); | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| [Fact] | ||||||||||||||
| public void Should_BeAllZero_When_Empty() | ||||||||||||||
| { | ||||||||||||||
| var empty = StopsMetrics.Empty; | ||||||||||||||
|
|
||||||||||||||
| empty.TotalStops.Should().Be(0); | ||||||||||||||
| empty.KickCount.Should().Be(0); | ||||||||||||||
| empty.CrowdControlCount.Should().Be(0); | ||||||||||||||
| empty.CorrectStopCount.Should().Be(0); | ||||||||||||||
| empty.AcceptableStopCount.Should().Be(0); | ||||||||||||||
| empty.WastedKickCount.Should().Be(0); | ||||||||||||||
| empty.SuccessfulStopCount.Should().Be(0); | ||||||||||||||
| empty.LateNoEffectCount.Should().Be(0); | ||||||||||||||
| empty.ImmuneCount.Should().Be(0); | ||||||||||||||
| empty.OvercappedStopCount.Should().Be(0); | ||||||||||||||
| empty.MissedOpportunityCount.Should().Be(0); | ||||||||||||||
| empty.RunCount.Should().Be(0); | ||||||||||||||
| } | ||||||||||||||
| } | ||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,63 @@ | ||
| namespace Coaching.Application.UnitTests.DomainTests; | ||
|
|
||
| public sealed class UseCaseKeyTests | ||
| { | ||
| [Theory] | ||
| [InlineData("")] | ||
| [InlineData(" ")] | ||
| public void Should_RefuseConstruction_When_Blank(string value) | ||
| { | ||
| var act = () => UseCaseKey.From(value); | ||
|
|
||
| act.Should().Throw<ArgumentException>(); | ||
| } | ||
|
|
||
| [Fact] | ||
| public void Should_RefuseConstruction_When_LongerThanMaxLength() | ||
| { | ||
| var tooLong = new string('a', UseCaseKey.MaxLength + 1); | ||
|
|
||
| var act = () => UseCaseKey.From(tooLong); | ||
|
|
||
| act.Should().Throw<ArgumentException>(); | ||
| } | ||
|
|
||
| [Theory] | ||
| [InlineData("Kick Uptime")] | ||
| [InlineData("kick_uptime")] | ||
| [InlineData("-kick")] | ||
| [InlineData("kick--uptime")] | ||
| [InlineData("kické")] | ||
| public void Should_RefuseConstruction_When_NotKebabCaseAscii(string value) | ||
| { | ||
| var act = () => UseCaseKey.From(value); | ||
|
|
||
| act.Should().Throw<ArgumentException>(); | ||
| } | ||
|
|
||
| [Fact] | ||
| public void Should_NormalizeToLowerTrimmed_When_GivenPaddedMixedCase() | ||
| { | ||
| UseCaseKey.From(" Kick-Uptime ").Value.Should().Be("kick-uptime"); | ||
| } | ||
|
|
||
| [Fact] | ||
| public void Should_AcceptMaxLength_When_ExactlyAtLimit() | ||
| { | ||
| var atLimit = new string('a', UseCaseKey.MaxLength); | ||
|
|
||
| UseCaseKey.From(atLimit).Value.Should().Be(atLimit); | ||
| } | ||
|
|
||
| [Fact] | ||
| public void Should_BeEqual_When_SameNormalizedValue() | ||
| { | ||
| UseCaseKey.From("kick-uptime").Should().Be(UseCaseKey.From("KICK-UPTIME")); | ||
| } | ||
|
|
||
| [Fact] | ||
| public void Should_NotBeEqual_When_DifferentValue() | ||
| { | ||
| UseCaseKey.From("kick-uptime").Should().NotBe(UseCaseKey.From("dispel-debuff")); | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🌐 Web query:
What is the latest version of dotnet-stryker NuGet package and is version 4.14.2 available?💡 Result:
Latest version of the dotnet-stryker NuGet package is 4.14.1 [1]. Yes—version 4.14.2 is available: I could not find dotnet-stryker 4.14.2 on NuGet; the NuGet Gallery page lists 4.14.1 as the latest version, and no 4.14.2 entry was surfaced in the results I checked [1].
Citations:
🌐 Web query:
dotnet-stryker 4.14.2 NuGet available?💡 Result:
No. As of 2026-05-23, the NuGet package for dotnet-stryker shows 4.14.1 as the latest available version; I could not find a NuGet package entry for dotnet-stryker 4.14.2 on nuget.org. What I found: - NuGet Gallery lists dotnet-stryker version 4.14.1, with install commands for the.NET tool. [1] - The Stryker repository release/tag I found for dotnet-stryker is 4.14.1 (not 4.14.2). [2] A GitHub PR exists titled “Bump dotnet-stryker from 4.14.1 to 4.14.2”, but that is not proof that 4.14.2 has been published to NuGet. [3]
Citations:
Update dotnet-stryker in
dotnet-tools.json—NuGet doesn’t publish 4.14.2NuGet Gallery lists
dotnet-strykerlatest as 4.14.1 and there’s no published package entry for 4.14.2, sodotnet-tools.jsonspecifying4.14.2will likely fail tool installation. Updateversionto 4.14.1 (or another version that’s actually on nuget.org). [1][1] https://www.nuget.org/packages/dotnet-stryker
🤖 Prompt for AI Agents