feat: accept Filtered.Types selections as dependency targets for architecture rules#325
Merged
Merged
Conversation
🚀 Benchmark ResultsDetails
|
👽 Mutation ResultsaweXpect.ReflectionDetails
The final mutation score is 79.95%Coverage Thresholds: high:80 low:60 break:0 |
0f82606 to
fcedf25
Compare
…itecture rules A reusable Filtered.Types selection (a "layer") can now act as a dependency target alongside the namespace and specific-type forms: - ThatType: DependsOn / DoesNotDependOn / DependsOnlyOn(Filtered.Types target, params Filtered.Types[] additional) - ThatTypes: DependOn / DoNotDependOn / DependOnlyOn (IEnumerable and IAsyncEnumerable subjects) - TypeFilters: WhichDependOn / WhichDoNotDependOn / WhichDependOnlyOn - All results and the filter result chain with OrOn(params Filtered.Types[]) to widen the targeted/allowed selections (Or is the inherited AndOrResult property and must not be hidden). Each target selection is resolved once per assertion into the union set; membership is by type identity, with a generic type definition in the set matching any of its constructions. The only-on family keeps the own-namespace allowance and the framework rule, so an empty selection allows exactly the own namespace and framework dependencies. All dependency resolution still goes through TypeHelpers.ResolveDependencies, so a customized resolver applies automatically. The first target is a regular parameter instead of params, because a pure params Filtered.Types[] overload would make the existing zero-argument calls (e.g. DependsOn()) ambiguous with the params IEnumerable<string> namespace overloads (CS0121); this also enforces "at least one target" at compile time. The README gains an "Architecture rules" section documenting the pattern: layers as reusable selections, combining rules with Expect.ThatAll, the aggregated failure shape, and exemptions via the Except filter.
- Normalize the resolved target set via the shared StripElementTypes, so array/by-ref/pointer types in a target selection match their element type, mirroring the specific-type overloads (an array target in DoesNotDependOn no longer passes silently). - Report type-set violations deduplicated by type identity and qualify distinct violators sharing a simple name with their namespace, so they no longer collapse into one indistinguishable entry. - Validate widening targets fully before mutating the shared options and report the actual parameter name of the caller (additional/targets). - Share the violation-collection core and the framework/own-namespace exemption predicate between the namespace-based and type-set-based helpers, so the two families cannot drift apart. - Factor the null-item predicates of the type-set collection constraints into static helpers, mirroring the namespace-based siblings.
- DependsOnlyOn/DependOnlyOn/WhichDependOnlyOn with Filtered.Types targets return new only-on results exposing ExcludingOwnSubNamespaces, mirroring the namespace family (the own-sub-namespace exemption was hard-coded) - TypeSetDependencyOptions.Resolve returns a ResolvedTypeSet that performs all matching, so matching against an unresolved target set is unrepresentable; the assertion CancellationToken is forwarded - share the constructed-generic matching rule between MatchesType and the type-set matcher via TypeHelpers.GetGenericTypeDefinitionOfConstruction - parenthesize the target description in the type-set filter suffixes, so the target scope no longer runs into the subject collection scope - drop a provably dead Distinct() in GetDependencyTypeSetViolations - make all WhichDependOn/WhichDoNotDependOn/DependOn/DoNotDependOn overloads adjacent (Sonar S4136) - README: promote type dependencies and architecture rules into their own top-level section and avoid em-dashes
…les' Updated section headers for clarity and consistency.
b83cc5f to
8404108
Compare
|
|
This is addressed in release v2.0.0. |
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.



A reusable Filtered.Types selection (a "layer") can now act as a dependency target alongside the namespace and specific-type forms:
Each target selection is resolved once per assertion into the union set; membership is by type identity, with a generic type definition in the set matching any of its constructions. The only-on family keeps the own-namespace allowance and the framework rule, so an empty selection allows exactly the own namespace and framework dependencies. All dependency resolution still goes through TypeHelpers.ResolveDependencies, so a customized resolver applies automatically.
The first target is a regular parameter instead of params, because a pure params Filtered.Types[] overload would make the existing zero-argument calls (e.g. DependsOn()) ambiguous with the params IEnumerable namespace overloads (CS0121); this also enforces "at least one target" at compile time.
The README gains an "Architecture rules" section documenting the pattern: layers as reusable selections, combining rules with Expect.ThatAll, the aggregated failure shape, and exemptions via the Except filter.