Uh oh!
There was an error while loading. Please reload this page.
Unblock the build (header + LF migration) and fix 66 SonarCloud issues - #157
Merged
Conversation
- S2187/MSTEST0016: drop spurious [TestClass] from the static container classes UtilityTests and AdvancedUtilityTests; the nested [TestClass] types hold the actual tests and are discovered independently. - S2699: PrefixAndSuffixAttribute_ValidString_ShouldPass asserted nothing and duplicated the test below it. Renamed to PrefixAndSuffixAttribute_AppliedToType_ExposesConfiguredPrefixAndSuffix and made it verify the attribute metadata on the fixture type. - MSTEST0054: TestContext.CancellationTokenSource.Token -> TestContext.CancellationToken (4 sites).
ktsu.Sdk 2.26.1 rewrites .editorconfig on build to set file_header_template = Copyright (c) 2023-2026 ktsu-dev contributors but every source file still carried the old three-line ktsu.dev header, so IDE0073 fired on all 1168 of them and the build could not complete. This is the same migration already drafted on the stale chore/sdk-2.21.1-lf-migration branch (which is 24 commits behind main and pinned to SDK 2.21.1), redone against current main. - Replaced the three-line header with the one-line form in 523 .cs files, preserving the UTF-8 BOM on the 226 files that carry one. - GeneratorBase.WriteHeaderTo now emits the one-line header, so regenerated output matches the committed sources and the verify-generated workflow stays green. - Committed the SDK-generated .editorconfig template change. - KTSU0002: added AssemblyInfo.cs exposing internals to ktsu.Semantics.Test for Semantics.Color and Semantics.Music, matching the existing files in Semantics.Paths and Semantics.Quantities. Also normalized the working tree to LF. The repo moved to "* text=auto eol=lf" but files checked out beforehand were still CRLF on disk, which core.autocrlf=true hid from git status while IDE0055 fired on every line. Build: 0 errors, 0 warnings across all target frameworks (was 8604 errors). Tests: 1079/1079 pass.
Migrated all 36 call sites. AreSequenceEqual takes IEnumerable<T>, so the
accompanying .ToArray()/.ToList() calls became redundant (IDE0305) and the
inline new List<T> { ... } arguments became collection-expression
candidates (IDE0028); both were cleaned up, hoisting the expected values
into typed locals where the call spanned multiple lines.
One behavioural trap worth recording: AreSequenceEqual is NOT a drop-in
replacement when the element type itself implements IEnumerable.
GetAncestors_EndsAtTheRootWithoutRepeatingIt compares
AbsoluteDirectoryPath values, and SemanticString explicitly implements
IEnumerable<char>, so AreSequenceEqual recursed into each element instead
of using the record value equality that CollectionAssert.AreEqual relied
on - the assert failed while printing identical expected/actual text.
That site now compares the underlying WeakString values, matching how the
rest of the class asserts. string is special-cased by MSTest, which is why
no other site was affected.
Build clean, 1079/1079 tests pass.All 21 sites: - Assert.AreEqual(n, x.Count) -> Assert.HasCount(n, x) (11) - Assert.AreEqual(0, x.Count) -> Assert.IsEmpty(x) (3) - Assert.IsFalse(x.Any()) -> Assert.IsEmpty(x) (2) - Assert.IsTrue(a > b) -> Assert.IsGreaterThan(b, a) (4) - Assert.IsTrue(a >= b) -> Assert.IsGreaterThanOrEqualTo (1) - Assert.IsTrue(a < b) -> Assert.IsLessThan(b, a) (2) Build clean, 1079/1079 tests pass.
The SonarCloud quality gate failed on new_coverage: the only uncovered new line was in GeneratorBase.WriteHeaderTo. Semantics.SourceGenerators is 1077 lines at 0% coverage because it is a Roslyn component that runs at build time and was not referenced by any test project, so any edit to it fails the gate. Rather than excluding it from analysis - which would also have hidden ~40 real findings (S3776 x9, S2223 x3, ...) in code that produces the shipped library - this drives the generators directly through CSharpGeneratorDriver. New project Semantics.SourceGenerators.Test covering all 8 generators with the real production metadata: - every generator emits sources carrying the canonical file header, which is the regression guard for the drift this PR had to fix by hand: if WriteHeaderTo and .editorconfig file_header_template fall out of step, a test fails instead of every generated file failing IDE0073 - no generator reports diagnostics for valid metadata - QuantitiesGenerator emits a non-trivial catalogue - malformed metadata surfaces as the CONV001 diagnostic rather than throwing Two wiring notes, both captured as comments in the csproj: - it needs its own project. The generator targets netstandard2.0 and its GetDependencyTargetPaths target deliberately bundles every dependency into consumers, so referencing it from Semantics.Test dragged the System.Memory / System.Numerics.Vectors facades in and broke 142 span-using tests with CS0433. - ktsu.CodeBlocker must be referenced explicitly. The generator declares its dependencies PrivateAssets="all", so they do not flow to consumers, but the generators genuinely execute here and fail with FileNotFoundException without it. Build clean, 1089/1089 tests pass (1079 + 10 new).
…e is collected The generator tests initially lived in their own project, but KtsuBuild runs "dotnet test --coverage --coverage-output coverage.xml" once at solution level, so with two test projects both write the same coverage file and only one survives. Verified by reproducing the exact invocation locally: the merged report contained only Semantics.Test s six ktsu.Semantics.* modules and the generator assembly was silently dropped, which is why the coverage gate stayed at 0% even though the tests ran and passed. (That is a KtsuBuild limitation worth fixing upstream - any ktsu repo with more than one test project currently loses coverage for all but one of them.) Moving the tests into the single existing test project sidesteps it. Two guards make that reference safe, both documented in the project files: - BundleAnalyzerDependencies=false on the ProjectReference. The generator s GetDependencyTargetPaths target deliberately bundles every dependency into consumers so they are present at analyzer load time; for a plain library reference that pushed netstandard2.0 facades into our compile references and broke 142 span-using tests with CS0433. The target is now conditional, so the analyzer path (Semantics.Quantities) keeps the bundling it needs. - ktsu.CodeBlocker is referenced with ExcludeAssets="compile" - needed at run time because the generators actually execute, but taking its compile assets would reintroduce the same facade collision. Verified with KtsuBuild s own invocation: coverage.xml now contains Semantics.SourceGenerators.dll alongside the six library modules. Build clean, 1089/1089 tests pass.
Uh oh!
There was an error while loading. Please reload this page.
This was referenced Aug 14, 2026
This was referenced Aug 27, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for freeto join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



Unblocks the build (it currently fails on
main, locally and in CI) and fixes 66 SonarCloud issues.The build was broken — 8604 errors on
mainTwo independent problems, both from recent SDK/repo changes:
1. File headers vs. ktsu.Sdk 2.26.1 — 1168 × IDE0073. The SDK rewrites
.editorconfigon every build to setbut every source file still carried the old three-line
ktsu.devheader, so IDE0073 fired on all of them. Migrated 523.csfiles to the one-line form, preserving the UTF-8 BOM on the 226 that carry one.This is the same migration already drafted on
chore/sdk-2.21.1-lf-migration— that branch is 24 commits behindmainand pinned to SDK 2.21.1, so this redoes it against currentmain. It can be closed.Critically,
GeneratorBase.WriteHeaderToalso emits the header into generated output, so it was updated too — otherwiseverify-generatedwould fail on drift. All 226 generated files reproduce byte-identically.2. Line endings — IDE0055 on every line. The repo moved to
* text=auto eol=lf, but files checked out beforehand were still CRLF on disk (i/lf w/crlf), whichcore.autocrlf=truehid fromgit status. Normalized the working tree to LF.3. KTSU0002. Added
AssemblyInfo.csexposing internals toktsu.Semantics.TestforSemantics.ColorandSemantics.Music, matching the existing files inSemantics.PathsandSemantics.Quantities.Result: 0 errors, 0 warnings across all target frameworks.
SonarCloud fixes — 66
BLOCKERs — 3
UtilityTestsandAdvancedUtilityTestsare static container classes carrying a spurious[TestClass]; the nested[TestClass]types hold the actual tests and are discovered independently. Also clears MSTEST0016 ×2.PrefixAndSuffixAttribute_ValidString_ShouldPassasserted nothing and duplicated the test below it. Renamed toPrefixAndSuffixAttribute_AppliedToType_ExposesConfiguredPrefixAndSuffixand made it verify the attribute metadata on the fixture type.MSTEST0068 — 36
CollectionAssert.AreEqual→Assert.AreSequenceEqual. SinceAreSequenceEqualtakesIEnumerable<T>, the accompanying.ToArray()/.ToList()became redundant (IDE0305) and inlinenew List<T> { … }arguments became collection-expression candidates (IDE0028); both cleaned up.MSTEST0037 — 21
Assert.AreEqual(n, x.Count)Assert.HasCount(n, x)Assert.AreEqual(0, x.Count)Assert.IsEmpty(x)Assert.IsFalse(x.Any())Assert.IsEmpty(x)Assert.IsTrue(a > b)Assert.IsGreaterThan(b, a)Assert.IsTrue(a >= b)Assert.IsGreaterThanOrEqualTo(b, a)Assert.IsTrue(a < b)Assert.IsLessThan(b, a)MSTEST0054 — 4
TestContext.CancellationTokenSource.Token→TestContext.CancellationToken.Still open — ~94
Not addressed here, to keep this reviewable: S1192 magic strings (19), S4136 overload adjacency (10), S1133 deprecation TODOs (10), S3776 cognitive complexity (9, mostly in the source generators), S3267 (6), S1172 unused parameters (6), S6610
EndsWith(char)(6), plus a tail of smaller rules.Verification
dotnet build— 0 errors, 0 warnings, all target frameworks (was 8604 errors)dotnet test— 1079/1079 pass