test(quantities): generator-output invariants — no duplicate signatures, commutative * (closes #57)#74
Merged
Conversation
…es, commutative * (closes #57) Adds Semantics.Test/Quantities/GeneratorOutputInvariantTests.cs with two reflection-based invariant tests against the compiled generator output: 1. NoDuplicatePublicStaticMethodsOrOperatorsPerGeneratedType For every generated type implementing IVector0..IVector4 in ktsu.Semantics.Quantities, no two public static methods (including operator overloads) share the same name + parameter type list. The C# compiler already enforces this when the generator emits — the test makes the property explicit and regression-proof if QuantitiesGenerator's dedup keys ever change. 2. EveryCrossDimensionalMultiplicationHasBothOperandOrders For every observed `op_Multiply(A, B) -> C` across the generated surface, the corresponding `op_Multiply(B, A) -> C` must also exist. This locks in the commutativity property the generator builds via the AddOp pair in CollectAllOperators (forward + commutative). A dedup-key regression that drops one direction would cause user code like `accel * mass` to stop compiling — this test catches it before it reaches a downstream consumer. Same-type operators (T * T -> U, e.g. Length * Length = Area) are exempt because the swap is identity. Cross/Dot products are not checked here: cross is anti-commutative by design, and dot is emitted as A.Dot(B) / B.Dot(A) on separate types rather than as operator pairs.
|
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 free
to 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.




Summary
Closes #57.
The original concern was that
QuantitiesGenerator's string-keyed dedup ({op}:{left}:{right}:{ret}etc.) could let two methods with the same name + parameter types land on the same generated type, or could let one direction of a commutative cross-dimensional multiplication get silently dropped. The C# compiler catches identical signatures at build time, but neither property was tested explicitly.This PR adds two reflection-based invariant tests in
Semantics.Test/Quantities/GeneratorOutputInvariantTests.cs:NoDuplicatePublicStaticMethodsOrOperatorsPerGeneratedType— for every generated type implementingIVector0..IVector4inktsu.Semantics.Quantities, no two public static methods (including operator overloads) share the same name + parameter type list. Walks the runtime assembly so the test sees what consumers would see.EveryCrossDimensionalMultiplicationHasBothOperandOrders— for every observedop_Multiply(A, B) → C, the swapped pairop_Multiply(B, A) → Cmust also exist. Locks in the commutativity thatCollectAllOperatorsalready emits via theAddOpforward+commutative pair. A regression that drops one direction would meanaccel * massstops compiling — this test catches that before users do.Same-type operators (
Length * Length = Area) are exempt from the second test because the swap is identity. Cross/dot products aren't covered here: cross is anti-commutative by design (A × B ≠ B × A), and dot products are emitted asA.Dot(B)/B.Dot(A)on separate types rather than operator pairs.Test plan
dotnet build Semantics.SourceGeneratorsanddotnet build Semantics.Quantitiesare clean.dotnet test—Semantics.Testcannot restore in this sandbox (Microsoft.NETCore.App.Host.ubuntu.24.04-x64not in feeds); both tests are reflection-only with no extra dependencies, so CI is the validator.Why two tests instead of one
The first test would silently always pass on a successful build (the compiler already enforces unique signatures). The second test asserts an actual generator-behaviour invariant that is expressible at runtime — both directions of every cross-dim multiplication exist. Together they cover both halves of #57's concern: "no duplicates" and "no missing pairs".
https://claude.ai/code/session_01Tj63Rddvs9frqLUgsjNEP5
Generated by Claude Code