| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
* Make generated annotation marking idempotent * Add failing schema rebuild repros for issue 3384 * Fix type collection for resolved schema references * Add schema rebuild coverage for union and interface references * Remove issue annotations from schema rebuild tests * Rename schema rebuild test helpers
Test ReportTest Results
|
Sorry, something went wrong.
…o-26.x # Conflicts: # build.gradle
| Back | FazBrowse Home | New Git URL |
Backport of #4390 to the 26.x maintenance branch.
Summary
Fixes #3384.
The core issue is that a built GraphQLSchema can contain two views of the same relationship:
In the #3384 repro, Person was originally created with .withInterface(typeRef("Node")). During schema build, that reference is resolved and Person.getInterfaces() starts returning the real Node interface. Later, when the mutation root is removed, Node is no longer reachable through the deleted mutation field. The rebuilt schema still reaches Person from Query, and Person still implements Node, so Node must remain in the rebuilt type map.
The catch is that schema build collection intentionally traverses getChildrenWithTypeReferences(). For Person, that traversal sees the original GraphQLTypeReference("Node"), not the already-resolved Node object returned by Person.getInterfaces(). So the collector can visit Person without collecting the resolved Node interface. Later, GraphQLTypeResolvingVisitor uses Person.getInterfaces(), looks up Node in the rebuilt type map, and fails because Node was missed during collection.
This is what the code calls an indirect strong reference:
GraphQLTypeCollectingVisitor already handled this pattern for field, argument, input field, and applied directive argument types. This PR extends the same collection logic to:
The same original-reference versus resolved-accessor split exists for unions and interface inheritance:
This does not keep every deleted-path extra type alive. It only preserves resolved named types that are still referenced by a schema element that remains reachable in the rebuilt schema.
Repro Coverage
Adds #3384 Spock coverage for these schema rebuild cases:
The object/interface case is covered through both paths:
The union and interface-inheritance cases specifically prove why GraphQLTypeCollectingVisitor needs to follow getTypes() and getInterfaces(), not just field/argument/input references.
Before the collector change, these cases fail during rebuild with an NPE in GraphQLTypeResolvingVisitor; they now pass.
Local Test Stability
This PR also keeps the local build cleanup from the previous version of #4390: markGeneratedEqualsHashCode now cleans classes-jacoco before rewriting and does not append duplicate graphql.coverage.Generated annotations. That prevents local-only ArchUnit failures in JMHForkArchRuleTest after interrupted or repeated incremental runs.
Verification
Also ran: