Resolve type variables in generic test class hierarchies#320
Resolve type variables in generic test class hierarchies#320amondnet wants to merge 4 commits intoAutoParams:mainAutoParams/AutoParams:mainfrom amondnet:fix/issue-277-generic-test-class-type-resolutionamondnet/AutoParams:fix/issue-277-generic-test-class-type-resolutionCopy head branch name to clipboard
Conversation
When test methods are inherited from abstract generic test classes, parameter types appear as TypeVariable at runtime instead of their concrete types. This caused AutoParams to fail with "Object cannot be created" errors. This change enhances TestResolutionContext to detect TypeVariable parameters and resolve them using the test class's generic superclass information, mapping type variables to their actual type arguments. Fixes AutoParams#277
Improve type variable resolution to handle complex inheritance hierarchies and generic interfaces. The original implementation only checked the immediate superclass, which failed for: - Multi-level generic inheritance - Generic interfaces - Nested type variable chains Changes: - Add defensive type checking before ClassCastException-prone casts - Walk entire class hierarchy to find type variable mappings - Check generic interfaces at each level - Handle recursive type variable resolution - Add comprehensive test coverage for edge cases This enhancement addresses code review findings while maintaining backward compatibility with the existing single-level inheritance use case.
Address critical silent failure issues identified in code review: 1. Add explicit warning when type variable resolution falls back to bounds or Object.class, providing users with actionable guidance on how to fix their test class hierarchy 2. Add test for unresolvable type variables (ConcreteUnboundTest) to verify fallback behavior works correctly 3. Add test for nested type variable chains (ThreeLevelTest with BaseLevel<A> -> MiddleLevel<B> -> HigherLevel<C> -> Category) to ensure recursive resolution handles multi-level mappings These changes ensure users receive clear feedback when type resolution fails instead of silently getting wrong types, making debugging configuration issues straightforward. Addresses PR review findings: silent-failure-hunter issues #1, AutoParams#2, AutoParams#3 and pr-test-analyzer critical gaps #1, AutoParams#2.
|
Remaining
|
Enhance type variable resolution with comprehensive diagnostic logging and protection against infinite recursion, improving debuggability and robustness. Add recursion depth tracking with configurable maximum depth (50 levels) to prevent stack overflow from circular type variable references. When exceeded, throw IllegalStateException with clear error message. Add diagnostic logging controlled by system property 'autoparams.debug.typeResolution'. When enabled, log: - Type resolution initiation and completion - Class hierarchy traversal at each depth level - Type matching success with mapping details - Types skipped due to type guards (non-parameterized, non-class) This helps developers understand and debug complex generic type hierarchies without needing to step through with a debugger.
There was a problem hiding this comment.
Pull Request Overview
This PR fixes issue #277 by implementing type variable resolution for generic test class hierarchies, enabling AutoParams to correctly resolve type parameters when test methods are inherited from abstract generic test classes.
Key Changes:
- Enhanced
TestResolutionContextto resolveTypeVariableparameters by traversing the test class hierarchy and mapping type variables to their concrete types - Added comprehensive test coverage in
SpecsForGenericTestClass.javafor single-level, multi-level inheritance, and generic interface scenarios - Implemented depth limits and debug logging for type resolution with fallback to type bounds when resolution fails
Reviewed Changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
TestResolutionContext.java |
Added type variable resolution logic with hierarchy traversal, recursive resolution, and safeguards against infinite recursion |
SpecsForGenericTestClass.java |
New test file covering single/multi-level inheritance, generic interfaces, and edge cases for type variable resolution |
| TypeFormatter.format(fallbackType, false) | ||
| ); | ||
|
|
||
| System.err.println("WARNING: " + message); |
There was a problem hiding this comment.
Consider using a proper logging framework (e.g., SLF4J, java.util.logging) instead of System.err.println for warning messages. This would provide better control over log levels, formatting, and output destinations in production environments.
| } | ||
|
|
||
| private void debugLog(String format, Object... args) { | ||
| System.err.println("DEBUG [TypeResolution]: " + String.format(format, args)); |
There was a problem hiding this comment.
Consider using a proper logging framework instead of System.err.println for debug logging. This would integrate better with existing logging infrastructure and allow proper configuration of debug levels.
Summary
Fixes #277 by implementing type variable resolution for generic test class hierarchies. When test methods are inherited from abstract generic test classes, AutoParams can now correctly resolve type parameters to their concrete types.
Problem
Previously, when a test class like
CategoryTest extends HierarchyEntityTest<Category>inherited test methods with generic parametersT, AutoParams failed with:This occurred because
parameter.getParameterizedType()returnedTypeVariableinstead of the concrete typeCategory.Solution
Enhanced
TestResolutionContextto:TypeVariableparameters in test methodsChanges
Modified:
TestResolutionContext.javaresolveTypeVariable()- Main entry point for type resolutionresolveTypeVariableFromClass()- Walks class hierarchy recursivelyresolveTypeVariableFromType()- Resolves from parameterized types with safe castingAdded:
SpecsForGenericTestClass.javaCategoryTest extends HierarchyEntityTest<Category>)ProductTest extends MiddleEntityTest<Product> extends HierarchyEntityTest)CategoryRepositoryTestwith multiple type parameters)Test Coverage
All new tests pass, covering:
Build Status
Example Usage
Impact
Review Notes
This PR addresses:
Ready for review and testing.