Allow custom templates to be provided for a specific template format

Previously, custom snippet templates were loaded from
org/springframework/restdocs/templates and the default templates were
loaded from org/springframework/restdocs/templates/{$formatId}.
Without relying on the ordering of the classpath, this made it
impossible to provide a custom template for a specific format.

This commit updates the locations that are checked for snippet
templates. The following locations are now checked in order:

1. org/springframework/restdocs/templates/${formatId}/${name}.snippet
2. org/springframework/restdocs/templates/${name}.snippet
3. org/springframework/restdocs/templates/${formatId}/default-${name}.snippet

The second location is provided largely for backwards compatibility
with 1.0. Users are expected to use the first location to provide
any custom templates, with Spring REST Docs provided templates for
all of the built-in snippets in the third location.

Closes gh-196
Closes gh-197
This commit is contained in:
Andy Wilkinson
2016-02-08 13:41:24 +00:00
parent 83b72f7962
commit 6578f42730
26 changed files with 108 additions and 41 deletions

View File

@@ -47,29 +47,17 @@ public class StandardTemplateResourceResolverTests {
private final TestClassLoader classLoader = new TestClassLoader();
@Test
public void customSnippetResolution() throws Exception {
this.classLoader.addResource(
"org/springframework/restdocs/templates/test.snippet", getClass()
.getResource("test.snippet"));
Resource snippet = doWithThreadContextClassLoader(this.classLoader,
new Callable<Resource>() {
@Override
public Resource call() {
return StandardTemplateResourceResolverTests.this.resolver
.resolveTemplateResource("test");
}
});
assertThat(snippet.getURL(), is(equalTo(getClass().getResource("test.snippet"))));
}
@Test
public void fallsBackToDefaultSnippet() throws Exception {
public void formatSpecificCustomSnippetHasHighestPrecedence() throws Exception {
this.classLoader.addResource(
"org/springframework/restdocs/templates/asciidoctor/test.snippet",
getClass().getResource("test.snippet"));
getClass().getResource("test-format-specific-custom.snippet"));
this.classLoader.addResource(
"org/springframework/restdocs/templates/test.snippet", getClass()
.getResource("test-custom.snippet"));
this.classLoader
.addResource(
"org/springframework/restdocs/templates/asciidoctor/default-test.snippet",
getClass().getResource("test-default.snippet"));
Resource snippet = doWithThreadContextClassLoader(this.classLoader,
new Callable<Resource>() {
@@ -81,11 +69,59 @@ public class StandardTemplateResourceResolverTests {
});
assertThat(snippet.getURL(), is(equalTo(getClass().getResource("test.snippet"))));
assertThat(
snippet.getURL(),
is(equalTo(getClass().getResource("test-format-specific-custom.snippet"))));
}
@Test
public void failsIfCustomAndDefaultSnippetDoNotExist() throws Exception {
public void generalCustomSnippetIsUsedInAbsenceOfFormatSpecificCustomSnippet()
throws Exception {
this.classLoader.addResource(
"org/springframework/restdocs/templates/test.snippet", getClass()
.getResource("test-custom.snippet"));
this.classLoader
.addResource(
"org/springframework/restdocs/templates/asciidoctor/default-test.snippet",
getClass().getResource("test-default.snippet"));
Resource snippet = doWithThreadContextClassLoader(this.classLoader,
new Callable<Resource>() {
@Override
public Resource call() {
return StandardTemplateResourceResolverTests.this.resolver
.resolveTemplateResource("test");
}
});
assertThat(snippet.getURL(),
is(equalTo(getClass().getResource("test-custom.snippet"))));
}
@Test
public void defaultSnippetIsUsedInAbsenceOfCustomSnippets() throws Exception {
this.classLoader
.addResource(
"org/springframework/restdocs/templates/asciidoctor/default-test.snippet",
getClass().getResource("test-default.snippet"));
Resource snippet = doWithThreadContextClassLoader(this.classLoader,
new Callable<Resource>() {
@Override
public Resource call() {
return StandardTemplateResourceResolverTests.this.resolver
.resolveTemplateResource("test");
}
});
assertThat(snippet.getURL(),
is(equalTo(getClass().getResource("test-default.snippet"))));
}
@Test
public void failsIfCustomAndDefaultSnippetsDoNotExist() throws Exception {
this.thrown.expect(IllegalStateException.class);
this.thrown.expectMessage(equalTo("Template named 'test' could not be resolved"));
doWithThreadContextClassLoader(this.classLoader, new Callable<Resource>() {