diff --git a/build.gradle b/build.gradle index 330e8355..fc664c7e 100644 --- a/build.gradle +++ b/build.gradle @@ -67,6 +67,7 @@ subprojects { dependency 'javax.servlet:javax.servlet-api:3.1.0' dependency 'javax.validation:validation-api:1.1.0.Final' dependency 'junit:junit:4.12' + dependency 'org.asciidoctor:asciidoctorj:1.5.3.1' dependency 'org.hamcrest:hamcrest-core:1.3' dependency 'org.hamcrest:hamcrest-library:1.3' dependency 'org.hibernate:hibernate-validator:5.2.2.Final' diff --git a/config/checkstyle/checkstyle-suppressions.xml b/config/checkstyle/checkstyle-suppressions.xml index 2c9a1795..f74d9234 100644 --- a/config/checkstyle/checkstyle-suppressions.xml +++ b/config/checkstyle/checkstyle-suppressions.xml @@ -5,5 +5,4 @@ - diff --git a/docs/src/docs/asciidoc/getting-started.adoc b/docs/src/docs/asciidoc/getting-started.adoc index 9b0040ab..a282bf46 100644 --- a/docs/src/docs/asciidoc/getting-started.adoc +++ b/docs/src/docs/asciidoc/getting-started.adoc @@ -94,13 +94,9 @@ the configuration are described below. test - <2> - ${project.build.directory}/generated-snippets - - - <3> + <2> org.apache.maven.plugins maven-surefire-plugin @@ -109,26 +105,30 @@ the configuration are described below. - <4> + <3> org.asciidoctor asciidoctor-maven-plugin - 1.5.2 + 1.5.3 generate-docs - prepare-package <6> + prepare-package <4> process-asciidoc html book - - ${snippetsDirectory} <5> - + + <5> + org.springframework.restdocs + spring-restdocs-asciidoctor + {project-version} + + @@ -136,49 +136,50 @@ the configuration are described below. <1> Add a dependency on `spring-restdocs-mockmvc` in the `test` scope. If you want to use REST Assured rather than MockMvc, add a dependency on `spring-restdocs-restassured` instead. -<2> Configure a property to define the output location for generated snippets. -<3> Add the SureFire plugin and configure it to include files whose names end with +<2> Add the SureFire plugin and configure it to include files whose names end with `Documentation.java`. -<4> Add the Asciidoctor plugin -<5> Define an attribute named `snippets` that can be used when including the generated - snippets in your documentation. -<6> Using `prepare-package` allows the documentation to be +<3> Add the Asciidoctor plugin. +<4> Using `prepare-package` allows the documentation to be <>. +<5> Add `spring-restdocs-asciidoctor` as a dependency of the Asciidoctor plugin. This + will automatically configure the `snippets` attribute for use in your `.adoc` files to + point to `target/generated-snippets`. [source,groovy,indent=0,subs="verbatim,attributes",role="secondary"] .Gradle ---- plugins { <1> - id "org.asciidoctor.convert" version "1.5.2" + id "org.asciidoctor.convert" version "1.5.3" } - dependencies { <2> - testCompile 'org.springframework.restdocs:spring-restdocs-mockmvc:{project-version}' + dependencies { + asciidoctor 'org.springframework.restdocs:spring-restdocs-asciidoctor:{project-version}' <2> + testCompile 'org.springframework.restdocs:spring-restdocs-mockmvc:{project-version}' <3> } - ext { <3> + ext { <4> snippetsDir = file('build/generated-snippets') } - test { <4> + test { <5> outputs.dir snippetsDir } - asciidoctor { <5> - attributes 'snippets': snippetsDir <6> + asciidoctor { <6> inputs.dir snippetsDir <7> dependsOn test <8> } ---- <1> Apply the Asciidoctor plugin. -<2> Add a dependency on `spring-restdocs-mockmvc` in the `testCompile` configuration. If +<2> Add a dependency on `spring-restdocs-asciidoctor` in the `asciidoctor` configuration. + This will automatically configure the `snippets` attribute for use in your `.adoc` + files to point to `build/generated-snippets`. +<3> Add a dependency on `spring-restdocs-mockmvc` in the `testCompile` configuration. If you want to use REST Assured rather than MockMvc, add a dependency on `spring-restdocs-restassured` instead. -<3> Configure a property to define the output location for generated snippets. -<4> Configure the `test` task to add the snippets directory as an output. -<5> Configure the `asciidoctor` task -<6> Define an attribute named `snippets` that can be used when including the generated - snippets in your documentation. +<4> Configure a property to define the output location for generated snippets. +<5> Configure the `test` task to add the snippets directory as an output. +<6> Configure the `asciidoctor` task <7> Configure the snippets directory as an input. <8> Make the task depend on the test task so that the tests are run before the documentation is created. @@ -271,28 +272,38 @@ are also supported although slightly more setup is required. ===== Setting up your JUnit tests When using JUnit, the first step in generating documentation snippets is to declare a -`public` `JUnitRestDocumentation` field that's annotated as a JUnit `@Rule`. The -`JUnitRestDocumentation` rule is configured with the output directory into which generated -snippets should be written. This output directory should match the snippets directory that -you have configured in your `build.gradle` or `pom.xml` file. +`public` `JUnitRestDocumentation` field that's annotated as a JUnit `@Rule`. -For Maven (`pom.xml`) that will typically be `target/generated-snippets` and for -Gradle (`build.gradle`) it will typically be `build/generated-snippets`: -[source,java,indent=0,role="primary"] -.Maven +[source,java,indent=0] ---- @Rule -public JUnitRestDocumentation restDocumentation = - new JUnitRestDocumentation("target/generated-snippets"); +public JUnitRestDocumentation restDocumentation = new JUnitRestDocumentation(); ---- -[source,java,indent=0,role="secondary"] -.Gradle + +By default, the `JUnitRestDocumentation` rule is automatically configured with an output +directory based on your project's build tool: + +[cols="2,5"] +|=== +| Build tool | Output directory + +| Maven +| `target/generated-snippets` + +| Gradle +| `build/generated-snippets` + +|=== + +The default can be overridden by providing an output directory when creating the +`JUnitRestDocumentation` instance: + +[source,java,indent=0] ---- @Rule -public JUnitRestDocumentation restDocumentation = - new JUnitRestDocumentation("build/generated-snippets"); +public JUnitRestDocumentation restDocumentation = new JUnitRestDocumentation("custom"); ---- Next, provide an `@Before` method to configure MockMvc or REST Assured: @@ -331,18 +342,9 @@ illustrates the approach. The first difference is that `ManualRestDocumentation` should be used in place of `JUnitRestDocumentation` and there's no need for the `@Rule` annotation: -[source,java,indent=0,role="primary"] -.Maven +[source,java,indent=0] ---- -private ManualRestDocumentation restDocumentation = - new ManualRestDocumentation("target/generated-snippets"); ----- - -[source,java,indent=0,role="secondary"] -.Gradle ----- -private ManualRestDocumentation restDocumentation = - new ManualRestDocumentation("build/generated-snippets"); +private ManualRestDocumentation restDocumentation = new ManualRestDocumentation(); ---- Secondly, `ManualRestDocumentation.beforeTest(Class, String)` @@ -441,7 +443,8 @@ the resulting HTML files depends on whether you are using Maven or Gradle: The generated snippets can then be included in the manually created Asciidoctor file from above using the http://asciidoctor.org/docs/asciidoc-syntax-quick-reference/#include-files[include macro]. -The `snippets` attribute specified in the <> can be used to reference the snippets output directory. For example: [source,adoc,indent=0] diff --git a/docs/src/docs/asciidoc/working-with-asciidoctor.adoc b/docs/src/docs/asciidoc/working-with-asciidoctor.adoc index b3981dfe..283afcdf 100644 --- a/docs/src/docs/asciidoc/working-with-asciidoctor.adoc +++ b/docs/src/docs/asciidoc/working-with-asciidoctor.adoc @@ -17,10 +17,11 @@ relevant to Spring REST Docs. [[working-with-asciidoctor-including-snippets]] === Including snippets -The http://asciidoctor.org/docs/asciidoc-syntax-quick-reference/#include-files[include +The http://asciidoctor.org/docs/asciidoc-syntax-quick-reference/#include-files[include macro] is used to include generated snippets in your documentation. The `snippets` -attribute specified in the <> -can be used to reference the snippets output directory, for example: +attribute that is automatically set by `spring-restdocs-asciidoctor` configured in the +<> can be used to reference the +snippets output directory. For example: [source,adoc,indent=0] ---- diff --git a/samples/rest-assured/build.gradle b/samples/rest-assured/build.gradle index ea67c861..b8776d37 100644 --- a/samples/rest-assured/build.gradle +++ b/samples/rest-assured/build.gradle @@ -37,6 +37,7 @@ dependencies { compile 'org.springframework.boot:spring-boot-starter-web' testCompile 'org.springframework.boot:spring-boot-starter-test' testCompile "org.springframework.restdocs:spring-restdocs-restassured:${project.ext['spring-restdocs.version']}" + asciidoctor "org.springframework.restdocs:spring-restdocs-asciidoctor:${project.ext['spring-restdocs.version']}" } test { @@ -44,7 +45,6 @@ test { } asciidoctor { - attributes 'snippets': snippetsDir inputs.dir snippetsDir dependsOn test } diff --git a/samples/rest-notes-grails/.gitignore b/samples/rest-notes-grails/.gitignore index a521ca89..18afeb78 100644 --- a/samples/rest-notes-grails/.gitignore +++ b/samples/rest-notes-grails/.gitignore @@ -11,7 +11,4 @@ classes/ .settings .classpath gradlew* -gradle/wrapper - - -src/docs/generated-snippets +gradle/wrapper \ No newline at end of file diff --git a/samples/rest-notes-grails/build.gradle b/samples/rest-notes-grails/build.gradle index 52ef8395..64e2e6d8 100644 --- a/samples/rest-notes-grails/build.gradle +++ b/samples/rest-notes-grails/build.gradle @@ -44,6 +44,7 @@ repositories { dependencyManagement { dependencies { dependency "org.springframework.restdocs:spring-restdocs-restassured:$restDocsVersion" + dependency "org.springframework.restdocs:spring-restdocs-asciidoctor:$restDocsVersion" } imports { mavenBom "org.grails:grails-bom:$grailsVersion" @@ -53,6 +54,8 @@ dependencyManagement { } dependencies { + asciidoctor "org.springframework.restdocs:spring-restdocs-asciidoctor" + compile "org.springframework.boot:spring-boot-starter-logging" compile "org.springframework.boot:spring-boot-starter-actuator" compile "org.springframework.boot:spring-boot-autoconfigure" @@ -85,24 +88,16 @@ task wrapper(type: Wrapper) { } ext { - snippetsDir = file('src/docs/generated-snippets') -} - -task cleanTempDirs(type: Delete) { - delete fileTree(dir: 'src/docs/generated-snippets') + snippetsDir = file('build/generated-snippets') } test { - dependsOn cleanTempDirs outputs.dir snippetsDir } asciidoctor { dependsOn integrationTest inputs.dir snippetsDir - sourceDir = file('src/docs') - separateOutputDirs = false - attributes 'snippets': snippetsDir } build.dependsOn asciidoctor diff --git a/samples/rest-notes-grails/src/docs/index.adoc b/samples/rest-notes-grails/src/docs/asciidoc/index.adoc similarity index 100% rename from samples/rest-notes-grails/src/docs/index.adoc rename to samples/rest-notes-grails/src/docs/asciidoc/index.adoc diff --git a/samples/rest-notes-grails/src/integration-test/groovy/com/example/ApiDocumentationSpec.groovy b/samples/rest-notes-grails/src/integration-test/groovy/com/example/ApiDocumentationSpec.groovy index 3f0da9ca..2c014fc0 100644 --- a/samples/rest-notes-grails/src/integration-test/groovy/com/example/ApiDocumentationSpec.groovy +++ b/samples/rest-notes-grails/src/integration-test/groovy/com/example/ApiDocumentationSpec.groovy @@ -45,7 +45,7 @@ import spock.lang.Specification class ApiDocumentationSpec extends Specification { @Rule - JUnitRestDocumentation restDocumentation = new JUnitRestDocumentation('src/docs/generated-snippets') + JUnitRestDocumentation restDocumentation = new JUnitRestDocumentation() @Value('${local.server.port}') Integer serverPort diff --git a/samples/rest-notes-spring-data-rest/pom.xml b/samples/rest-notes-spring-data-rest/pom.xml index cae3b9a8..022c1922 100644 --- a/samples/rest-notes-spring-data-rest/pom.xml +++ b/samples/rest-notes-spring-data-rest/pom.xml @@ -84,12 +84,16 @@ html book - - ${project.build.directory}/generated-snippets - + + + org.springframework.restdocs + spring-restdocs-asciidoctor + ${spring-restdocs.version} + + maven-resources-plugin diff --git a/samples/rest-notes-spring-hateoas/build.gradle b/samples/rest-notes-spring-hateoas/build.gradle index 89a45741..a44f3f94 100644 --- a/samples/rest-notes-spring-hateoas/build.gradle +++ b/samples/rest-notes-spring-hateoas/build.gradle @@ -34,6 +34,8 @@ ext['spring.version']='4.3.1.RELEASE' ext['spring-restdocs.version'] = '1.2.0.BUILD-SNAPSHOT' dependencies { + asciidoctor "org.springframework.restdocs:spring-restdocs-asciidoctor:${project.ext['spring-restdocs.version']}" + compile 'org.springframework.boot:spring-boot-starter-data-jpa' compile 'org.springframework.boot:spring-boot-starter-hateoas' @@ -50,7 +52,6 @@ test { } asciidoctor { - attributes 'snippets': snippetsDir inputs.dir snippetsDir dependsOn test } diff --git a/samples/testng/build.gradle b/samples/testng/build.gradle index b0be8697..3be74243 100644 --- a/samples/testng/build.gradle +++ b/samples/testng/build.gradle @@ -34,7 +34,10 @@ ext['spring.version']='4.3.1.RELEASE' ext['spring-restdocs.version'] = '1.2.0.BUILD-SNAPSHOT' dependencies { + asciidoctor "org.springframework.restdocs:spring-restdocs-asciidoctor:${project.ext['spring-restdocs.version']}" + compile 'org.springframework.boot:spring-boot-starter-web' + testCompile('org.springframework:spring-test') { exclude group: 'junit', module: 'junit;' } @@ -48,7 +51,6 @@ test { } asciidoctor { - attributes 'snippets': snippetsDir inputs.dir snippetsDir dependsOn test } diff --git a/settings.gradle b/settings.gradle index a31b3171..94b5f9b1 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,7 +1,7 @@ rootProject.name = 'spring-restdocs' include 'docs' -include 'spring-restdocs-asciidoctor-extensions' +include 'spring-restdocs-asciidoctor' include 'spring-restdocs-core' include 'spring-restdocs-mockmvc' include 'spring-restdocs-restassured' diff --git a/spring-restdocs-asciidoctor-extensions/build.gradle b/spring-restdocs-asciidoctor-extensions/build.gradle deleted file mode 100644 index 4c24e8b3..00000000 --- a/spring-restdocs-asciidoctor-extensions/build.gradle +++ /dev/null @@ -1,6 +0,0 @@ -description = 'Spring REST Docs Asciidoctor Extensions' - -dependencies { - compile 'org.asciidoctor:asciidoctorj:1.5.2' - optional 'junit:junit' -} diff --git a/spring-restdocs-asciidoctor-extensions/src/main/java/org/springframework/restdocs/asciidoctor/extensions/RestDocsSnippetBlockMacro.java b/spring-restdocs-asciidoctor-extensions/src/main/java/org/springframework/restdocs/asciidoctor/extensions/RestDocsSnippetBlockMacro.java deleted file mode 100644 index 896133f3..00000000 --- a/spring-restdocs-asciidoctor-extensions/src/main/java/org/springframework/restdocs/asciidoctor/extensions/RestDocsSnippetBlockMacro.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright 2014-2016 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.restdocs.asciidoctor.extensions; - -import java.io.File; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.Map; - -import org.asciidoctor.Asciidoctor; -import org.asciidoctor.OptionsBuilder; -import org.asciidoctor.ast.AbstractBlock; -import org.asciidoctor.extension.BlockMacroProcessor; - -/** - * Block macro to include snippets generated by Spring Rest Docs in a convenient way. - * Defaults to build (gradle) or target directory to look for the generated-snippets folder and its content. - * - * @author Gerrit Meier - */ -class RestDocsSnippetBlockMacro extends BlockMacroProcessor { - - private static final String GENERATED_SNIPPETS_PATH = "generated-snippets"; - private static final String MAVEN_TARGET_PATH = "target" + File.separator + GENERATED_SNIPPETS_PATH; - private static final String GRADLE_BUILD_PATH = "build" + File.separator + GENERATED_SNIPPETS_PATH; - private static final String MAVEN_POM = "pom.xml"; - - public RestDocsSnippetBlockMacro(String macroName, Map config) { - super(macroName, config); - } - - @Override - protected Object process(AbstractBlock parent, String fileToInclude, Map attributes) { - String generatedSnippetPath = getDefaultOutputDirectory() + File.separator + fileToInclude; - - // since 'pass' context does not convert the content, we have to do this manually - String convertedContent = Asciidoctor.Factory.create().convertFile( - new File(generatedSnippetPath), - OptionsBuilder.options().toFile(false).inPlace(false).get()); - - return createBlock(parent, "pass", convertedContent, attributes, getConfig()); - } - - private static String getDefaultOutputDirectory() { - String executingDirectory = Paths.get(".").toFile().getAbsolutePath(); - - if (Files.exists(Paths.get(MAVEN_POM))) { - return executingDirectory + File.separator + MAVEN_TARGET_PATH; - } - return executingDirectory + File.separator + GRADLE_BUILD_PATH; - } -} diff --git a/spring-restdocs-asciidoctor-extensions/src/main/resources/META-INF/services/org.asciidoctor.extension.spi.ExtensionRegistry b/spring-restdocs-asciidoctor-extensions/src/main/resources/META-INF/services/org.asciidoctor.extension.spi.ExtensionRegistry deleted file mode 100644 index 084eaa64..00000000 --- a/spring-restdocs-asciidoctor-extensions/src/main/resources/META-INF/services/org.asciidoctor.extension.spi.ExtensionRegistry +++ /dev/null @@ -1 +0,0 @@ -org.springframework.restdocs.asciidoctor.extensions.RestDocsExtensionRegistry \ No newline at end of file diff --git a/spring-restdocs-asciidoctor-extensions/src/test/java/org/springframework/restdocs/asciidoctor/extensions/RestDocsSnippetBlockMacroTest.java b/spring-restdocs-asciidoctor-extensions/src/test/java/org/springframework/restdocs/asciidoctor/extensions/RestDocsSnippetBlockMacroTest.java deleted file mode 100644 index 9876af57..00000000 --- a/spring-restdocs-asciidoctor-extensions/src/test/java/org/springframework/restdocs/asciidoctor/extensions/RestDocsSnippetBlockMacroTest.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2014-2016 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.restdocs.asciidoctor.extensions; - -import java.nio.file.Files; -import java.nio.file.Paths; -import java.nio.file.StandardCopyOption; - -import org.asciidoctor.Asciidoctor; -import org.asciidoctor.Options; -import org.junit.Before; -import org.junit.Test; - -import static org.hamcrest.CoreMatchers.equalTo; -import static org.junit.Assert.assertThat; - -/** - * Tests for {@link RestDocsSnippetBlockMacro}. - * - * @author Gerrit Meier - */ -public class RestDocsSnippetBlockMacroTest { - - @Before - public void prepareIncludeFiles() throws Exception { - Files.createDirectories(Paths.get("build/generated-snippets/")); - Files.copy(Paths.get("src/test/resources/rest_docs_macro.adoc"), - Paths.get("build/generated-snippets/rest_docs_macro.adoc"), StandardCopyOption.REPLACE_EXISTING); - } - - @Test - public void replaceRestDocsSnippetBlockWithFile() { - Asciidoctor asciidoctor = Asciidoctor.Factory.create(); - asciidoctor.javaExtensionRegistry().blockMacro("snippet", RestDocsSnippetBlockMacro.class); - - assertThat(asciidoctor.convert("snippet::rest_docs_macro.adoc[]", new Options()), - equalTo("
\n

test text

\n
")); - } - -} diff --git a/spring-restdocs-asciidoctor-extensions/src/test/resources/rest_docs_macro.adoc b/spring-restdocs-asciidoctor-extensions/src/test/resources/rest_docs_macro.adoc deleted file mode 100644 index 276e7895..00000000 --- a/spring-restdocs-asciidoctor-extensions/src/test/resources/rest_docs_macro.adoc +++ /dev/null @@ -1 +0,0 @@ -test text \ No newline at end of file diff --git a/spring-restdocs-asciidoctor/build.gradle b/spring-restdocs-asciidoctor/build.gradle new file mode 100644 index 00000000..6897242e --- /dev/null +++ b/spring-restdocs-asciidoctor/build.gradle @@ -0,0 +1,7 @@ +description = 'Asciidoctor extensions for Spring REST Docs' + +dependencies { + compileOnly 'org.asciidoctor:asciidoctorj' + testCompile 'junit:junit' + testCompile 'org.asciidoctor:asciidoctorj' +} diff --git a/spring-restdocs-asciidoctor/src/main/java/org/springframework/restdocs/asciidoctor/DefaultAttributesPreprocessor.java b/spring-restdocs-asciidoctor/src/main/java/org/springframework/restdocs/asciidoctor/DefaultAttributesPreprocessor.java new file mode 100644 index 00000000..7caa35f9 --- /dev/null +++ b/spring-restdocs-asciidoctor/src/main/java/org/springframework/restdocs/asciidoctor/DefaultAttributesPreprocessor.java @@ -0,0 +1,43 @@ +/* + * Copyright 2014-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.restdocs.asciidoctor; + +import java.io.File; + +import org.asciidoctor.ast.Document; +import org.asciidoctor.extension.Preprocessor; +import org.asciidoctor.extension.PreprocessorReader; + +/** + * {@link Preprocessor} that sets defaults for REST Docs-related {@link Document} + * attributes. + * + * @author Andy Wilkinson + */ +final class DefaultAttributesPreprocessor extends Preprocessor { + + private final SnippetsDirectoryResolver snippetsDirectoryResolver = new SnippetsDirectoryResolver( + new File(".")); + + @Override + public PreprocessorReader process(Document document, PreprocessorReader reader) { + document.setAttr("snippets", this.snippetsDirectoryResolver + .getSnippetsDirectory(document.getAttributes()), false); + return reader; + } + +} diff --git a/spring-restdocs-asciidoctor-extensions/src/main/java/org/springframework/restdocs/asciidoctor/extensions/RestDocsExtensionRegistry.java b/spring-restdocs-asciidoctor/src/main/java/org/springframework/restdocs/asciidoctor/RestDocsExtensionRegistry.java similarity index 53% rename from spring-restdocs-asciidoctor-extensions/src/main/java/org/springframework/restdocs/asciidoctor/extensions/RestDocsExtensionRegistry.java rename to spring-restdocs-asciidoctor/src/main/java/org/springframework/restdocs/asciidoctor/RestDocsExtensionRegistry.java index 82a8e60b..15bca154 100644 --- a/spring-restdocs-asciidoctor-extensions/src/main/java/org/springframework/restdocs/asciidoctor/extensions/RestDocsExtensionRegistry.java +++ b/spring-restdocs-asciidoctor/src/main/java/org/springframework/restdocs/asciidoctor/RestDocsExtensionRegistry.java @@ -14,32 +14,22 @@ * limitations under the License. */ -package org.springframework.restdocs.asciidoctor.extensions; +package org.springframework.restdocs.asciidoctor; import org.asciidoctor.Asciidoctor; import org.asciidoctor.extension.spi.ExtensionRegistry; /** - * ExtensionRegistry for the Spring Rest Docs macros to get registered - * in all projects that include this asciidoctor extension module. - *

- * Macros provided: - *

    - *
  • {@link RestDocsSnippetBlockMacro}
  • - *
+ * Asciidoctor {@link ExtensionRegistry} for Spring REST Docs. * - * @author Gerrit Meier + * @author Andy Wilkinson */ -public class RestDocsExtensionRegistry implements ExtensionRegistry { - - /** - * the name that identifies the block macro in the asciidoctor document - * (e.g.
snippet::file_to_include[]
) - */ - private static final String SNIPPET_BLOCK_NAME = "snippet"; +public final class RestDocsExtensionRegistry implements ExtensionRegistry { @Override public void register(Asciidoctor asciidoctor) { - asciidoctor.javaExtensionRegistry().blockMacro(SNIPPET_BLOCK_NAME, RestDocsSnippetBlockMacro.class); + asciidoctor.javaExtensionRegistry() + .preprocessor(new DefaultAttributesPreprocessor()); } + } diff --git a/spring-restdocs-asciidoctor/src/main/java/org/springframework/restdocs/asciidoctor/SnippetsDirectoryResolver.java b/spring-restdocs-asciidoctor/src/main/java/org/springframework/restdocs/asciidoctor/SnippetsDirectoryResolver.java new file mode 100644 index 00000000..dd6829ad --- /dev/null +++ b/spring-restdocs-asciidoctor/src/main/java/org/springframework/restdocs/asciidoctor/SnippetsDirectoryResolver.java @@ -0,0 +1,58 @@ +/* + * Copyright 2014-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.restdocs.asciidoctor; + +import java.io.File; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Map; + +/** + * Resolves the directory from which snippets can be read for inclusion in an Asciidoctor + * document. The resolved directory is relative to the {@code docdir} of the Asciidoctor + * document that it being rendered. + * + * @author Andy Wilkinson + */ +class SnippetsDirectoryResolver { + + private final File root; + + SnippetsDirectoryResolver(File root) { + this.root = root; + } + + File getSnippetsDirectory(Map attributes) { + if (new File(this.root, "pom.xml").exists()) { + return getMavenSnippetsDirectory(attributes); + } + return getGradleSnippetsDirectory(attributes); + } + + private File getMavenSnippetsDirectory(Map attributes) { + Path rootPath = Paths.get(this.root.getAbsolutePath()); + Path docDirPath = Paths.get((String) attributes.get("docdir")); + Path relativePath = docDirPath.relativize(rootPath); + return new File(relativePath.toFile(), "target/generated-snippets"); + } + + private File getGradleSnippetsDirectory(Map attributes) { + return new File((String) attributes.get("projectdir"), + "build/generated-snippets"); + } + +} diff --git a/spring-restdocs-asciidoctor/src/main/resources/META-INF/services/org.asciidoctor.extension.spi.ExtensionRegistry b/spring-restdocs-asciidoctor/src/main/resources/META-INF/services/org.asciidoctor.extension.spi.ExtensionRegistry new file mode 100644 index 00000000..7c790a30 --- /dev/null +++ b/spring-restdocs-asciidoctor/src/main/resources/META-INF/services/org.asciidoctor.extension.spi.ExtensionRegistry @@ -0,0 +1 @@ +org.springframework.restdocs.asciidoctor.RestDocsExtensionRegistry \ No newline at end of file diff --git a/spring-restdocs-asciidoctor/src/test/java/org/springframework/restdocs/asciidoctor/DefaultAttributesPreprocessorTests.java b/spring-restdocs-asciidoctor/src/test/java/org/springframework/restdocs/asciidoctor/DefaultAttributesPreprocessorTests.java new file mode 100644 index 00000000..699bb49a --- /dev/null +++ b/spring-restdocs-asciidoctor/src/test/java/org/springframework/restdocs/asciidoctor/DefaultAttributesPreprocessorTests.java @@ -0,0 +1,58 @@ +/* + * Copyright 2014-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.restdocs.asciidoctor; + +import org.asciidoctor.Asciidoctor; +import org.asciidoctor.Attributes; +import org.asciidoctor.Options; +import org.junit.Test; + +import static org.hamcrest.CoreMatchers.containsString; +import static org.junit.Assert.assertThat; + +/** + * Tests for {@link DefaultAttributesPreprocessor}. + * + * @author Andy Wilkinson + */ +public class DefaultAttributesPreprocessorTests { + + @Test + public void snippetsAttributeIsSet() { + String converted = Asciidoctor.Factory.create().convert("{snippets}", + new Options()); + assertThat(converted, containsString("build/generated-snippets")); + } + + @Test + public void snippetsAttributeFromConvertArgumentIsNotOverridden() { + Options options = new Options(); + options.setAttributes(new Attributes("snippets=custom")); + String converted = Asciidoctor.Factory.create().convert("{snippets}", options); + assertThat(converted, containsString("custom")); + } + + @Test + public void snippetsAttributeFromDocumentPreambleIsNotOverridden() { + Options options = new Options(); + options.setAttributes(new Attributes("snippets=custom")); + String converted = Asciidoctor.Factory.create() + .convert(":snippets: custom\n{snippets}", options); + assertThat(converted, containsString("custom")); + } + +} diff --git a/spring-restdocs-asciidoctor/src/test/java/org/springframework/restdocs/asciidoctor/SnippetsDirectoryResolverTests.java b/spring-restdocs-asciidoctor/src/test/java/org/springframework/restdocs/asciidoctor/SnippetsDirectoryResolverTests.java new file mode 100644 index 00000000..f998caf4 --- /dev/null +++ b/spring-restdocs-asciidoctor/src/test/java/org/springframework/restdocs/asciidoctor/SnippetsDirectoryResolverTests.java @@ -0,0 +1,68 @@ +/* + * Copyright 2014-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.restdocs.asciidoctor; + +import java.io.File; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +/** + * Tests for {@link SnippetsDirectoryResolver}. + * + * @author Andy Wilkinson + */ +public class SnippetsDirectoryResolverTests { + + @Rule + public TemporaryFolder temporaryFolder = new TemporaryFolder(); + + @Test + public void mavenProjectsUseTargetGeneratedSnippetsRelativeToDocDir() + throws IOException { + this.temporaryFolder.newFile("pom.xml"); + Map attributes = new HashMap<>(); + attributes.put("docdir", + new File(this.temporaryFolder.getRoot(), "src/main/asciidoc") + .getAbsolutePath()); + File snippetsDirectory = new SnippetsDirectoryResolver( + this.temporaryFolder.getRoot()).getSnippetsDirectory(attributes); + assertThat(snippetsDirectory.isAbsolute(), is(false)); + assertThat(snippetsDirectory, + equalTo(new File("../../../target/generated-snippets"))); + } + + @Test + public void gradleProjectsUseBuildGeneratedSnippetsBeneathProjectDir() + throws IOException { + Map attributes = new HashMap<>(); + attributes.put("projectdir", "project/dir"); + File snippetsDirectory = new SnippetsDirectoryResolver( + this.temporaryFolder.getRoot()).getSnippetsDirectory(attributes); + assertThat(snippetsDirectory, + equalTo(new File("project/dir/build/generated-snippets"))); + } + +} diff --git a/spring-restdocs-asciidoctor/src/test/resources/sample-snippet.adoc b/spring-restdocs-asciidoctor/src/test/resources/sample-snippet.adoc new file mode 100644 index 00000000..0a3d1fa7 --- /dev/null +++ b/spring-restdocs-asciidoctor/src/test/resources/sample-snippet.adoc @@ -0,0 +1,4 @@ +[source,bash] +---- +$ curl 'http://localhost:8080/' -i -H 'Accept: application/hal+json' +---- \ No newline at end of file diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/ManualRestDocumentation.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/ManualRestDocumentation.java index 19a8188c..472832ff 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/ManualRestDocumentation.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/ManualRestDocumentation.java @@ -17,8 +17,6 @@ package org.springframework.restdocs; import java.io.File; -import java.nio.file.Files; -import java.nio.file.Paths; /** * {@code ManualRestDocumentation} is used to manually manage the @@ -33,11 +31,6 @@ import java.nio.file.Paths; */ public final class ManualRestDocumentation implements RestDocumentationContextProvider { - private static final String GENERATED_SNIPPETS_PATH = "generated-snippets"; - private static final String MAVEN_TARGET_PATH = "target" + File.separator + GENERATED_SNIPPETS_PATH; - private static final String GRADLE_BUILD_PATH = "build" + File.separator + GENERATED_SNIPPETS_PATH; - private static final String MAVEN_POM = "pom.xml"; - private final File outputDirectory; private RestDocumentationContext context; @@ -57,7 +50,11 @@ public final class ManualRestDocumentation implements RestDocumentationContextPr * @param outputDirectory the output directory */ public ManualRestDocumentation(String outputDirectory) { - this.outputDirectory = new File(outputDirectory); + this(new File(outputDirectory)); + } + + private ManualRestDocumentation(File outputDirectory) { + this.outputDirectory = outputDirectory; } /** @@ -94,12 +91,11 @@ public final class ManualRestDocumentation implements RestDocumentationContextPr return this.context; } - private static String getDefaultOutputDirectory() { - String executingDirectory = Paths.get(".").toFile().getAbsolutePath(); - - if (Files.exists(Paths.get(MAVEN_POM))) { - return executingDirectory + File.separator + MAVEN_TARGET_PATH; + private static File getDefaultOutputDirectory() { + if (new File("pom.xml").exists()) { + return new File("target/generated-snippets"); } - return executingDirectory + File.separator + GRADLE_BUILD_PATH; + return new File("build/generated-snippets"); } + } diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/config/RestDocumentationConfigurerTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/config/RestDocumentationConfigurerTests.java index 0692cf61..995a6ffb 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/config/RestDocumentationConfigurerTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/config/RestDocumentationConfigurerTests.java @@ -195,7 +195,8 @@ public class RestDocumentationConfigurerTests { } private RestDocumentationContext createContext() { - ManualRestDocumentation manualRestDocumentation = new ManualRestDocumentation("build"); + ManualRestDocumentation manualRestDocumentation = new ManualRestDocumentation( + "build"); manualRestDocumentation.beforeTest(null, null); RestDocumentationContext context = manualRestDocumentation.beforeOperation(); return context; diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/snippet/RestDocumentationContextPlaceholderResolverTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/snippet/RestDocumentationContextPlaceholderResolverTests.java index 7fa1d1c4..83f96e61 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/snippet/RestDocumentationContextPlaceholderResolverTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/snippet/RestDocumentationContextPlaceholderResolverTests.java @@ -83,7 +83,8 @@ public class RestDocumentationContextPlaceholderResolverTests { } private RestDocumentationContext createContext(String methodName) { - ManualRestDocumentation manualRestDocumentation = new ManualRestDocumentation("build"); + ManualRestDocumentation manualRestDocumentation = new ManualRestDocumentation( + "build"); manualRestDocumentation.beforeTest(getClass(), methodName); RestDocumentationContext context = manualRestDocumentation.beforeOperation(); return context; diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/snippet/StandardWriterResolverTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/snippet/StandardWriterResolverTests.java index 49bdd4cc..a4d3460d 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/snippet/StandardWriterResolverTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/snippet/StandardWriterResolverTests.java @@ -70,7 +70,8 @@ public class StandardWriterResolverTests { } private RestDocumentationContext createContext(String outputDir) { - ManualRestDocumentation manualRestDocumentation = new ManualRestDocumentation(outputDir); + ManualRestDocumentation manualRestDocumentation = new ManualRestDocumentation( + outputDir); manualRestDocumentation.beforeTest(getClass(), null); RestDocumentationContext context = manualRestDocumentation.beforeOperation(); return context; diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/test/OperationBuilder.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/test/OperationBuilder.java index 154c59e2..698a80da 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/test/OperationBuilder.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/test/OperationBuilder.java @@ -123,7 +123,8 @@ public class OperationBuilder extends OperationTestRule { } private RestDocumentationContext createContext() { - ManualRestDocumentation manualRestDocumentation = new ManualRestDocumentation(this.outputDirectory.getAbsolutePath()); + ManualRestDocumentation manualRestDocumentation = new ManualRestDocumentation( + this.outputDirectory.getAbsolutePath()); manualRestDocumentation.beforeTest(null, null); RestDocumentationContext context = manualRestDocumentation.beforeOperation(); return context;