Repository navigation
Drop contextSensitive() from self-contained JavaTemplates - #1232
Conversation
…types Without context, a type declared in the test file itself, such as a nested fixture class, is unknown to the template parser. The type-specific assertion chained onto assertThat then loses its method type.
Each recipe that still needs contextSensitive() gets a test whose actual has a type declared in the test file; it fails on missing type information once the template is made context-free. HamcrestMatcherToAssertJ and HamcrestNotMatcherToAssertJ go back to context-free templates: they pin non-java.* types to Object, so no such test can fail for them.
|
Extra safety checks, since our tests mostly assert on JDK types while customer code asserts on its own domain classes. How placeholders are typed. An untyped Scratch test with domain types. I ran 28 cases against both the context-free and the context-sensitive versions. Each case puts domain types in the actual or expected argument, declared either in another source file or as a nested class in the test.
Separate existing issue, not addressed here. In After these changes, |
contextSensitive()makes aJavaTemplatecompile inside a stub of the surrounding source file. That is slow and defeats the template cache. It is only needed when the snippet refers to code it cannot get as a typed parameter, or when a placeholder's type is declared in the file being changed. This drops it from 17 files whose templates are self-contained.Dropped from:
AssertEqualsIntegralDeltaToAssertEquals,AssertFalseEqualsToAssertNotEquals,AssertFalseNegationToAssertTrue,AssertFalseNullToAssertNotNullandAssertTrueEqualsToAssertEquals.HamcrestIsMatcherToAssertJ,HamcrestMatcherToAssertJ(2) andHamcrestNotMatcherToAssertJ(2). These already turn any type outsidejava.*into#{any(java.lang.Object)}, so the template never names a type from the project.AdoptAssertJDurationAssertions, whose actual is always ajava.time.Duration, andSimplifyAssertJInstanceOfAssertion, whoseisInstanceOfis declared onAbstractAssert.RemoveTryCatchFailBlocksand the statement template inUpdateMockWebServer.@InjectMocksand@Disabledannotation templates inPowerMockWhiteboxSetInternalStateToInjectMocksandDisableUnsupportedPowerMockTests, thecloseOnDemand()statements inScopedMocks, the try-with-resources inMockConstructionToTryWithResources, and the try/catch wrapper inWhiteboxToReflectionVisitor.Kept:
assertThat(#{any()})templates that chain an assertion specific to one kind of type:SimplifyArrayLengthAssertion,SimplifyChainedAssertJAssertion,SimplifyHasSizeFromIsEqualToAssertion,HamcrestEveryItemToAssertJ,HamcrestHasItemMatcherToAssertJandHamcrestHasPropertyToAssertJ. An untyped#{any()}compiles as__P__.<fqn>p(), using the argument's type. Without context, a type declared in the test file itself, such asstatic class Item {}, is unknown to the template parser.assertThatthen can't be resolved, andhasSize,isEmptyorhasFieldOrPropertyloses its method type. Each of these recipes now has a test with such a class, which fails ifcontextSensitive()is removed. Types from other source files lose their type with or without context; that was already the case before this PR.allSatisfy/anySatisfy(arg -> assertThat(arg, ..))templates inHamcrestEveryItemToAssertJandHamcrestHasItemMatcherToAssertJ, andHamcrestOfMatchersToAssertJ. Without context, the innerassertThatin the lambda loses its method type.MockedStatic/MockedConstructionfields inCloseUnclosedStaticMocks,ScopedMocks,MockitoWhenOnStaticToMockStaticandJMockitMockUpToMockito, the lifecycle methods fromMockitoUtils,ReplaceMockitoTestExecutionListener,UpdateMockWebServerandTemporaryFolderToTempDir, and the parameter inTestRuleToTestInfo. A context-free template compiles these inside a syntheticclass Template, so the new member's owner becomesTemplateand source-path type arguments are left undefined.verify(mock).method(..), the JMockit mock setup templates, thevarName.close()/closeOnDemand()calls inReplaceInitMockToOpenMock,CloseUnclosedStaticMocksandMockitoWhenOnStaticToMockStatic, the static stubbing inPowerMockitoMockStaticToMockito, the reflection call sites inWhiteboxToReflectionVisitor, the lambda body inJUnitTryFailToAssertThatThrownBy, and thethis.fieldand helper-method references inParameterizedRunnerToParameterized,TestRuleToTestInfoandTemporaryFolderToTempDir.Verified locally:
contextSensitive()gave the same result as before../gradlew test --testsforhamcrest.*,assertj.*andcleanup.*, with--no-build-cache --rerun: 845 tests, 0 failures.mockito.*,easymock.*,jmockit.*,junit5.*andtestng.*passed. Those files haven't changed since.Fixes item N3 of #1211.