Support default package for TypeReference in ResourceHintsPredicates

Prior to this commit, if the TypeReference supplied to
ResourceHintsPredicates.forResource(TypeReference,String) was for a
class declared in the default package (i.e., without a package), the
resolveAbsoluteResourceName() method incorrectly prepended two leading
slashes (//) to the absolute resource name, causing correct matches to
fail.

This commit fixes this by adding special handling for a TypeReference
without a package name. In addition, this commit introduces lenient
handling of resource names by consistently removing a leading slash in
ResourceHintsPredicates.forResource(*) methods. The latter aligns with
absolute resource path handling in other places in the framework, such
as ClassPathResource.

Closes gh-29086
This commit is contained in:
Sam Brannen
2022-09-06 11:53:09 +02:00
parent 135f9070c5
commit 97b98c3378
3 changed files with 49 additions and 23 deletions

View File

@@ -18,7 +18,6 @@ package org.springframework.aot.hint.predicate;
import java.util.function.Predicate;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.aot.hint.RuntimeHints;
@@ -30,40 +29,54 @@ import static org.assertj.core.api.Assertions.assertThat;
* Tests for {@link ReflectionHintsPredicates}.
*
* @author Brian Clozel
* @author Sam Brannen
*/
class ResourceHintsPredicatesTests {
private final ResourceHintsPredicates resources = new ResourceHintsPredicates();
private RuntimeHints runtimeHints;
private final RuntimeHints runtimeHints = new RuntimeHints();
@BeforeEach
void setup() {
this.runtimeHints = new RuntimeHints();
}
@Test
void resourcePatternMatchesResourceName() {
this.runtimeHints.resources().registerPattern("/test/*");
this.runtimeHints.resources().registerPattern("test/*");
assertPredicateMatches(resources.forResource("/test/spring.properties"));
}
@Test
void resourcePatternDoesNotMatchResourceName() {
this.runtimeHints.resources().registerPattern("/test/spring.*");
this.runtimeHints.resources().registerPattern("test/spring.*");
assertPredicateDoesNotMatch(resources.forResource("/test/other.properties"));
}
@Test
void resourcePatternMatchesTypeAndResourceName() {
this.runtimeHints.resources().registerPattern("/org/springframework/aot/hint/predicate/spring.*");
this.runtimeHints.resources().registerPattern("org/springframework/aot/hint/predicate/spring.*");
assertPredicateMatches(resources.forResource(TypeReference.of(getClass()), "spring.properties"));
}
@Test
void resourcePatternMatchesTypeAndAbsoluteResourceName() {
this.runtimeHints.resources().registerPattern("spring.*");
assertPredicateMatches(resources.forResource(TypeReference.of(getClass()), "/spring.properties"));
}
@Test
void resourcePatternMatchesTypeInDefaultPackageAndResourceName() {
this.runtimeHints.resources().registerPattern("spring.*");
assertPredicateMatches(resources.forResource(TypeReference.of("DummyClass"), "spring.properties"));
}
@Test
void resourcePatternMatchesTypeInDefaultPackageAndAbsoluteResourceName() {
this.runtimeHints.resources().registerPattern("spring.*");
assertPredicateMatches(resources.forResource(TypeReference.of("DummyClass"), "/spring.properties"));
}
@Test
void resourcePatternDoesNotMatchTypeAndResourceName() {
this.runtimeHints.resources().registerPattern("/spring.*");
this.runtimeHints.resources().registerPattern("spring.*");
assertPredicateDoesNotMatch(resources.forResource(TypeReference.of(getClass()), "spring.properties"));
}
@@ -81,11 +94,11 @@ class ResourceHintsPredicatesTests {
private void assertPredicateMatches(Predicate<RuntimeHints> predicate) {
assertThat(predicate.test(this.runtimeHints)).isTrue();
assertThat(predicate).accepts(this.runtimeHints);
}
private void assertPredicateDoesNotMatch(Predicate<RuntimeHints> predicate) {
assertThat(predicate.test(this.runtimeHints)).isFalse();
assertThat(predicate).rejects(this.runtimeHints);
}
}