Auto-generate the "Common application properties"

Prior to this commit, the application properties listed in the reference
documentation would be manually managed and updated.

This commit adds a new `spring-boot-configuration-docs` project that
extracts that information from the available JSON metadata and writes
Asciidoctor tables ready for inclusion in the reference documentation.

The `generateConfigurationPropertyTables.groovy` is using this library
and configures the sections and how namespaces should be organized.

Fixes gh-8237
pull/15984/head
Brian Clozel 6 years ago
parent add8c6f295
commit 2a2bfb9915

@ -192,6 +192,7 @@ jobs:
disable_checksum_uploads: true
exclude:
- "**/spring-boot-test-support/**"
- "**/spring-boot-configuration-docs/**"
- "**/*.effective-pom"
artifact_set:
- include:

@ -55,6 +55,11 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-loader-tools</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-docs</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-test</artifactId>
@ -1244,6 +1249,7 @@
<script>file:///${project.basedir}/src/main/groovy/generateAutoConfigurationClassTables.groovy</script>
<script>file:///${project.basedir}/src/main/groovy/generateStarterTables.groovy</script>
<script>file:///${project.basedir}/src/main/groovy/generateTestSlicesTable.groovy</script>
<script>file:///${project.basedir}/src/main/groovy/generateConfigurationPropertyTables.groovy</script>
</scripts>
</configuration>
<dependencies>

@ -0,0 +1,79 @@
import org.springframework.boot.configurationdocs.ConfigurationMetadataDocumentWriter
import org.springframework.boot.configurationdocs.DocumentOptions
import org.springframework.core.io.UrlResource
import java.nio.file.Path
import java.nio.file.Paths
def getConfigMetadataInputStreams() {
def mainMetadata = getClass().getClassLoader().getResources("META-INF/spring-configuration-metadata.json")
def additionalMetadata = getClass().getClassLoader().getResources("META-INF/additional-spring-configuration-metadata.json")
def streams = []
streams += mainMetadata.collect { new UrlResource(it).getInputStream() }
streams += additionalMetadata.collect { new UrlResource(it).getInputStream() }
return streams
}
def generateConfigMetadataDocumentation() {
def streams = getConfigMetadataInputStreams()
try {
Path outputPath = Paths.get(project.build.directory, 'generated-resources', 'config-docs')
def builder = DocumentOptions.builder();
builder
.addSection("core")
.withKeyPrefixes("debug", "trace", "logging", "spring.aop", "spring.application",
"spring.autoconfigure", "spring.banner", "spring.beaninfo", "spring.config",
"spring.info", "spring.jmx", "spring.main", "spring.messages", "spring.pid",
"spring.profiles", "spring.quartz", "spring.reactor", "spring.task",
"spring.mandatory-file-encoding", "info", "spring.output.ansi.enabled")
.addSection("mail")
.withKeyPrefixes("spring.mail", "spring.sendgrid")
.addSection("cache")
.withKeyPrefixes("spring.cache")
.addSection("server")
.withKeyPrefixes("server")
.addSection("web")
.withKeyPrefixes("spring.hateoas",
"spring.http", "spring.servlet", "spring.jersey",
"spring.mvc", "spring.resources", "spring.webflux")
.addSection("json")
.withKeyPrefixes("spring.jackson", "spring.gson")
.addSection("templating")
.withKeyPrefixes("spring.freemarker", "spring.groovy", "spring.mustache", "spring.thymeleaf")
.addOverride("spring.groovy.template.configuration", "See GroovyMarkupConfigurer")
.addSection("security")
.withKeyPrefixes("spring.security", "spring.ldap", "spring.session")
.addSection("data-migration")
.withKeyPrefixes("spring.flyway", "spring.liquibase")
.addSection("data")
.withKeyPrefixes("spring.couchbase", "spring.elasticsearch", "spring.h2",
"spring.influx", "spring.mongodb", "spring.redis",
"spring.dao", "spring.data", "spring.datasource", "spring.jooq",
"spring.jdbc", "spring.jpa")
.addOverride("spring.datasource.dbcp2", "Commons DBCP2 specific settings")
.addOverride("spring.datasource.tomcat", "Tomcat datasource specific settings")
.addOverride("spring.datasource.hikari", "Hikari specific settings")
.addSection("transaction")
.withKeyPrefixes("spring.jta", "spring.transaction")
.addSection("integration")
.withKeyPrefixes("spring.activemq", "spring.artemis", "spring.batch",
"spring.integration", "spring.jms", "spring.kafka", "spring.rabbitmq", "spring.hazelcast",
"spring.webservices")
.addSection("actuator")
.withKeyPrefixes("management")
.addSection("devtools")
.withKeyPrefixes("spring.devtools")
.addSection("testing")
.withKeyPrefixes("spring.test");
ConfigurationMetadataDocumentWriter writer = new ConfigurationMetadataDocumentWriter();
writer.writeDocument(outputPath, builder.build(), streams.toArray(new InputStream[0]));
}
finally {
streams.each { it.close() }
}
}
generateConfigMetadataDocumentation()

@ -17,6 +17,7 @@
<modules>
<module>spring-boot-antlib</module>
<module>spring-boot-autoconfigure-processor</module>
<module>spring-boot-configuration-docs</module>
<module>spring-boot-configuration-metadata</module>
<module>spring-boot-configuration-processor</module>
<module>spring-boot-gradle-plugin</module>

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-tools</artifactId>
<version>${revision}</version>
</parent>
<artifactId>spring-boot-configuration-docs</artifactId>
<name>Spring Boot Configuration Docs</name>
<description>Spring Boot Configuration Docs</description>
<properties>
<main.basedir>${basedir}/../../..</main.basedir>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-metadata</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-test-support</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>

@ -0,0 +1,61 @@
/*
* Copyright 2012-2019 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.boot.configurationdocs;
import java.util.Objects;
/**
* Abstract class for entries in {@link ConfigurationTable}.
*
* @author Brian Clozel
*/
abstract class AbstractConfigurationEntry
implements Comparable<AbstractConfigurationEntry> {
protected static final String NEWLINE = System.lineSeparator();
protected String key;
public String getKey() {
return this.key;
}
public abstract void writeAsciidoc(StringBuilder builder);
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
AbstractConfigurationEntry that = (AbstractConfigurationEntry) o;
return this.key.equals(that.key);
}
@Override
public int hashCode() {
return Objects.hash(this.key);
}
@Override
public int compareTo(AbstractConfigurationEntry other) {
return this.key.compareTo(other.getKey());
}
}

@ -0,0 +1,55 @@
/*
* Copyright 2012-2019 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.boot.configurationdocs;
import java.util.Set;
import java.util.TreeSet;
import java.util.stream.Stream;
import org.springframework.boot.configurationmetadata.ConfigurationMetadataProperty;
/**
* Table entry regrouping a list of configuration properties sharing the same description.
*
* @author Brian Clozel
*/
class CompoundKeyEntry extends AbstractConfigurationEntry {
private Set<String> configurationKeys;
private String description;
CompoundKeyEntry(String key, String description) {
this.key = key;
this.description = description;
this.configurationKeys = new TreeSet<>();
}
void addConfigurationKeys(ConfigurationMetadataProperty... properties) {
Stream.of(properties)
.forEach((property) -> this.configurationKeys.add(property.getId()));
}
@Override
public void writeAsciidoc(StringBuilder builder) {
builder.append("|`+++");
this.configurationKeys.forEach((key) -> builder.append(key).append(NEWLINE));
builder.append("+++`").append(NEWLINE).append("|").append(NEWLINE).append("|+++")
.append(this.description).append("+++").append(NEWLINE);
}
}

@ -0,0 +1,143 @@
/*
* Copyright 2012-2019 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.boot.configurationdocs;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import org.springframework.boot.configurationmetadata.ConfigurationMetadataProperty;
import org.springframework.boot.configurationmetadata.ConfigurationMetadataRepository;
import org.springframework.boot.configurationmetadata.ConfigurationMetadataRepositoryJsonBuilder;
/**
* Write Asciidoc documents with configuration properties listings.
*
* @author Brian Clozel
*/
public class ConfigurationMetadataDocumentWriter {
public void writeDocument(Path outputDirPath, DocumentOptions options,
InputStream... metadataInput) throws IOException {
if (outputDirPath == null) {
throw new IllegalArgumentException("output path should not be null");
}
if (Files.exists(outputDirPath) && !Files.isDirectory(outputDirPath)) {
throw new IllegalArgumentException(
"output path already exists and is not a directory");
}
else if (!Files.exists(outputDirPath)) {
Files.createDirectory(outputDirPath);
}
if (metadataInput == null || metadataInput.length < 1) {
throw new IllegalArgumentException("missing input metadata");
}
ConfigurationMetadataRepository configRepository = ConfigurationMetadataRepositoryJsonBuilder
.create(metadataInput).build();
Map<String, ConfigurationMetadataProperty> allProperties = configRepository
.getAllProperties();
List<ConfigurationTable> tables = createConfigTables(allProperties, options);
for (ConfigurationTable table : tables) {
Path outputFilePath = outputDirPath.resolve(table.getId() + ".adoc");
Files.deleteIfExists(outputFilePath);
Files.createFile(outputFilePath);
try (OutputStream outputStream = Files.newOutputStream(outputFilePath)) {
outputStream
.write(table.toAsciidocTable().getBytes(StandardCharsets.UTF_8));
}
}
}
private List<ConfigurationTable> createConfigTables(
Map<String, ConfigurationMetadataProperty> allProperties,
DocumentOptions options) {
final List<ConfigurationTable> tables = new ArrayList<>();
final List<String> unmappedKeys = allProperties.values().stream()
.filter((prop) -> !prop.isDeprecated()).map((prop) -> prop.getId())
.collect(Collectors.toList());
final Map<String, CompoundKeyEntry> overrides = getOverrides(allProperties,
unmappedKeys, options);
options.getMetadataSections().forEach((id, keyPrefixes) -> {
ConfigurationTable table = new ConfigurationTable(id);
tables.add(table);
for (String keyPrefix : keyPrefixes) {
List<String> matchingOverrides = overrides.keySet().stream()
.filter((overrideKey) -> overrideKey.startsWith(keyPrefix))
.collect(Collectors.toList());
matchingOverrides.forEach((match) -> {
table.addEntry(overrides.remove(match));
});
}
List<String> matchingKeys = unmappedKeys.stream()
.filter((key) -> keyPrefixes.stream().anyMatch(key::startsWith))
.collect(Collectors.toList());
for (String matchingKey : matchingKeys) {
ConfigurationMetadataProperty property = allProperties.get(matchingKey);
table.addEntry(new SingleKeyEntry(property));
}
unmappedKeys.removeAll(matchingKeys);
});
if (!unmappedKeys.isEmpty()) {
throw new IllegalStateException(
"The following keys were not written to the documentation: "
+ String.join(", ", unmappedKeys));
}
if (!overrides.isEmpty()) {
throw new IllegalStateException(
"The following keys were not written to the documentation: "
+ String.join(", ", overrides.keySet()));
}
return tables;
}
private Map<String, CompoundKeyEntry> getOverrides(
Map<String, ConfigurationMetadataProperty> allProperties,
List<String> unmappedKeys, DocumentOptions options) {
final Map<String, CompoundKeyEntry> overrides = new HashMap<>();
options.getOverrides().forEach((keyPrefix, description) -> {
final CompoundKeyEntry entry = new CompoundKeyEntry(keyPrefix, description);
List<String> matchingKeys = unmappedKeys.stream()
.filter((key) -> key.startsWith(keyPrefix))
.collect(Collectors.toList());
for (String matchingKey : matchingKeys) {
entry.addConfigurationKeys(allProperties.get(matchingKey));
}
overrides.put(keyPrefix, entry);
unmappedKeys.removeAll(matchingKeys);
});
return overrides;
}
}

@ -0,0 +1,61 @@
/*
* Copyright 2012-2019 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.boot.configurationdocs;
import java.util.Arrays;
import java.util.Set;
import java.util.TreeSet;
/**
* Asciidoctor table listing configuration properties sharing to a common theme.
*
* @author Brian Clozel
*/
class ConfigurationTable {
private static final String NEWLINE = System.lineSeparator();
private final String id;
private final Set<AbstractConfigurationEntry> entries;
ConfigurationTable(String id) {
this.id = id;
this.entries = new TreeSet<>();
}
public String getId() {
return this.id;
}
void addEntry(AbstractConfigurationEntry... entries) {
this.entries.addAll(Arrays.asList(entries));
}
String toAsciidocTable() {
final StringBuilder builder = new StringBuilder();
builder.append("[cols=\"1,1,2\", options=\"header\"]").append(NEWLINE);
builder.append("|===").append(NEWLINE).append("|Key|Default Value|Description")
.append(NEWLINE).append(NEWLINE);
this.entries.forEach((entry) -> {
entry.writeAsciidoc(builder);
builder.append(NEWLINE);
});
return builder.append("|===").append(NEWLINE).toString();
}
}

@ -0,0 +1,98 @@
/*
* Copyright 2012-2019 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.boot.configurationdocs;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Options for generating documentation for configuration properties.
*
* @author Brian Clozel
*/
public final class DocumentOptions {
private final Map<String, List<String>> metadataSections;
private final Map<String, String> overrides;
private DocumentOptions(Map<String, List<String>> metadataSections,
Map<String, String> overrides) {
this.metadataSections = metadataSections;
this.overrides = overrides;
}
Map<String, List<String>> getMetadataSections() {
return this.metadataSections;
}
Map<String, String> getOverrides() {
return this.overrides;
}
static Builder builder() {
return new Builder();
}
/**
* Builder for DocumentOptions.
*/
public static class Builder {
Map<String, List<String>> metadataSections = new HashMap<>();
Map<String, String> overrides = new HashMap<>();
SectionSpec addSection(String name) {
return new SectionSpec(this, name);
}
Builder addOverride(String keyPrefix, String description) {
this.overrides.put(keyPrefix, description);
return this;
}
DocumentOptions build() {
return new DocumentOptions(this.metadataSections, this.overrides);
}
}
/**
* Configuration for a documentation section listing properties for a specific theme.
*/
public static class SectionSpec {
private final String name;
private final Builder builder;
SectionSpec(Builder builder, String name) {
this.builder = builder;
this.name = name;
}
Builder withKeyPrefixes(String... keyPrefixes) {
this.builder.metadataSections.put(this.name, Arrays.asList(keyPrefixes));
return this.builder;
}
}
}

@ -0,0 +1,83 @@
/*
* Copyright 2012-2019 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.boot.configurationdocs;
import java.util.Arrays;
import java.util.stream.Collectors;
import org.springframework.boot.configurationmetadata.ConfigurationMetadataProperty;
/**
* Table entry containing a single configuration property.
*
* @author Brian Clozel
*/
class SingleKeyEntry extends AbstractConfigurationEntry {
private String defaultValue;
private String description;
SingleKeyEntry(ConfigurationMetadataProperty property) {
this.key = property.getId();
if (property.getType() != null
&& property.getType().startsWith("java.util.Map")) {
this.key += ".*";
}
this.description = property.getDescription();
if (property.getDefaultValue() != null) {
if (property.getDefaultValue().getClass().isArray()) {
this.defaultValue = Arrays.stream((Object[]) property.getDefaultValue())
.map(Object::toString).collect(Collectors.joining("," + NEWLINE));
}
else {
this.defaultValue = property.getDefaultValue().toString();
}
}
}
@Override
public void writeAsciidoc(StringBuilder builder) {
builder.append("|`+").append(this.key).append("+`").append(NEWLINE);
String defaultValue = processDefaultValue();
if (defaultValue.length() > 0) {
builder.append("|`+").append(defaultValue).append("+`").append(NEWLINE);
}
else {
builder.append("|").append(NEWLINE);
}
if (this.description != null) {
builder.append("|+++").append(this.description).append("+++");
}
else {
builder.append("|");
}
builder.append(NEWLINE);
}
private String processDefaultValue() {
if (this.defaultValue != null && this.defaultValue.length() > 0) {
return this.defaultValue.replace("\\", "\\\\").replace("|",
"{vbar}" + NEWLINE);
}
return "";
}
}

@ -0,0 +1,57 @@
/*
* Copyright 2012-2019 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.boot.configurationdocs;
import org.junit.Test;
import org.springframework.boot.configurationmetadata.ConfigurationMetadataProperty;
import static org.assertj.core.api.Assertions.assertThat;
/**
* @author Brian Clozel
*/
public class CompoundKeyEntryTests {
private static String NEWLINE = System.lineSeparator();
@Test
public void simpleProperty() {
ConfigurationMetadataProperty firstProp = new ConfigurationMetadataProperty();
firstProp.setId("spring.test.first");
firstProp.setType("java.lang.String");
ConfigurationMetadataProperty secondProp = new ConfigurationMetadataProperty();
secondProp.setId("spring.test.second");
secondProp.setType("java.lang.String");
ConfigurationMetadataProperty thirdProp = new ConfigurationMetadataProperty();
thirdProp.setId("spring.test.third");
thirdProp.setType("java.lang.String");
CompoundKeyEntry entry = new CompoundKeyEntry("spring.test",
"This is a description.");
entry.addConfigurationKeys(firstProp, secondProp, thirdProp);
StringBuilder builder = new StringBuilder();
entry.writeAsciidoc(builder);
assertThat(builder.toString()).isEqualTo("|`+++spring.test.first" + NEWLINE
+ "spring.test.second" + NEWLINE + "spring.test.third" + NEWLINE + "+++`"
+ NEWLINE + "|" + NEWLINE + "|+++This is a description.+++" + NEWLINE);
}
}

@ -0,0 +1,61 @@
/*
* Copyright 2012-2019 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.boot.configurationdocs;
import org.junit.Test;
import org.springframework.boot.configurationmetadata.ConfigurationMetadataProperty;
import static org.assertj.core.api.Assertions.assertThat;
/**
* @author Brian Clozel
*/
public class ConfigurationTableTests {
private static String NEWLINE = System.lineSeparator();
@Test
public void simpleTable() {
ConfigurationTable table = new ConfigurationTable("test");
ConfigurationMetadataProperty first = new ConfigurationMetadataProperty();
first.setId("spring.test.prop");
first.setDefaultValue("something");
first.setDescription("This is a description.");
first.setType("java.lang.String");
ConfigurationMetadataProperty second = new ConfigurationMetadataProperty();
second.setId("spring.test.other");
second.setDefaultValue("other value");
second.setDescription("This is another description.");
second.setType("java.lang.String");
table.addEntry(new SingleKeyEntry(first));
table.addEntry(new SingleKeyEntry(second));
assertThat(table.toAsciidocTable())
.isEqualTo("[cols=\"1,1,2\", options=\"header\"]" + NEWLINE + "|==="
+ NEWLINE + "|Key|Default Value|Description" + NEWLINE + NEWLINE
+ "|`+spring.test.other+`" + NEWLINE + "|`+other value+`"
+ NEWLINE + "|+++This is another description.+++" + NEWLINE
+ NEWLINE + "|`+spring.test.prop+`" + NEWLINE + "|`+something+`"
+ NEWLINE + "|+++This is a description.+++" + NEWLINE + NEWLINE
+ "|===" + NEWLINE);
}
}

@ -0,0 +1,130 @@
/*
* Copyright 2012-2019 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.boot.configurationdocs;
import org.junit.Test;
import org.springframework.boot.configurationmetadata.ConfigurationMetadataProperty;
import static org.assertj.core.api.Assertions.assertThat;
/**
* @author Brian Clozel
*/
public class SingleKeyEntryTests {
private static String NEWLINE = System.lineSeparator();
@Test
public void simpleProperty() {
ConfigurationMetadataProperty property = new ConfigurationMetadataProperty();
property.setId("spring.test.prop");
property.setDefaultValue("something");
property.setDescription("This is a description.");
property.setType("java.lang.String");
SingleKeyEntry entry = new SingleKeyEntry(property);
StringBuilder builder = new StringBuilder();
entry.writeAsciidoc(builder);
assertThat(builder.toString()).isEqualTo("|`+spring.test.prop+`" + NEWLINE
+ "|`+something+`" + NEWLINE + "|+++This is a description.+++" + NEWLINE);
}
@Test
public void noDefaultValue() {
ConfigurationMetadataProperty property = new ConfigurationMetadataProperty();
property.setId("spring.test.prop");
property.setDescription("This is a description.");
property.setType("java.lang.String");
SingleKeyEntry entry = new SingleKeyEntry(property);
StringBuilder builder = new StringBuilder();
entry.writeAsciidoc(builder);
assertThat(builder.toString()).isEqualTo("|`+spring.test.prop+`" + NEWLINE + "|"
+ NEWLINE + "|+++This is a description.+++" + NEWLINE);
}
@Test
public void defaultValueWithPipes() {
ConfigurationMetadataProperty property = new ConfigurationMetadataProperty();
property.setId("spring.test.prop");
property.setDefaultValue("first|second");
property.setDescription("This is a description.");
property.setType("java.lang.String");
SingleKeyEntry entry = new SingleKeyEntry(property);
StringBuilder builder = new StringBuilder();
entry.writeAsciidoc(builder);
assertThat(builder.toString()).isEqualTo("|`+spring.test.prop+`" + NEWLINE
+ "|`+first{vbar}" + NEWLINE + "second+`" + NEWLINE
+ "|+++This is a description.+++" + NEWLINE);
}
@Test
public void defaultValueWithBackslash() {
ConfigurationMetadataProperty property = new ConfigurationMetadataProperty();
property.setId("spring.test.prop");
property.setDefaultValue("first\\second");
property.setDescription("This is a description.");
property.setType("java.lang.String");
SingleKeyEntry entry = new SingleKeyEntry(property);
StringBuilder builder = new StringBuilder();
entry.writeAsciidoc(builder);
assertThat(builder.toString())
.isEqualTo("|`+spring.test.prop+`" + NEWLINE + "|`+first\\\\second+`"
+ NEWLINE + "|+++This is a description.+++" + NEWLINE);
}
@Test
public void mapProperty() {
ConfigurationMetadataProperty property = new ConfigurationMetadataProperty();
property.setId("spring.test.prop");
property.setDescription("This is a description.");
property.setType("java.util.Map<java.lang.String,java.lang.String>");
SingleKeyEntry entry = new SingleKeyEntry(property);
StringBuilder builder = new StringBuilder();
entry.writeAsciidoc(builder);
assertThat(builder.toString()).isEqualTo("|`+spring.test.prop.*+`" + NEWLINE + "|"
+ NEWLINE + "|+++This is a description.+++" + NEWLINE);
}
@Test
public void listProperty() {
String[] defaultValue = new String[] { "first", "second", "third" };
ConfigurationMetadataProperty property = new ConfigurationMetadataProperty();
property.setId("spring.test.prop");
property.setDescription("This is a description.");
property.setType("java.util.List<java.lang.String>");
property.setDefaultValue(defaultValue);
SingleKeyEntry entry = new SingleKeyEntry(property);
StringBuilder builder = new StringBuilder();
entry.writeAsciidoc(builder);
assertThat(builder.toString()).isEqualTo("|`+spring.test.prop+`" + NEWLINE
+ "|`+first," + NEWLINE + "second," + NEWLINE + "third+`" + NEWLINE
+ "|+++This is a description.+++" + NEWLINE);
}
}
Loading…
Cancel
Save