From 9aaf91f814d5b3ee3d9ce7d4120bc7a0b54285a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathias=20D=C3=BCsterh=C3=B6ft?= Date: Mon, 29 Oct 2018 09:43:54 +0100 Subject: [PATCH 001/502] restdocs-openapi renamed to restdocs-api-spec `restdocs-openapi` has been renamed to restdocs-api-spec and will offer support for more API specification formats soon. `restdocs-raml` is no longer actively maintained and is archived. --- README.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 23f67f331..9228c8e37 100644 --- a/README.md +++ b/README.md @@ -40,8 +40,7 @@ There are several that you can contribute to Spring REST Docs: | [restdocs-wiremock][17] | Auto-generate [WireMock][18] stubs as part of documenting your RESTful API | | [restdocsext-jersey][19] | Enables Spring REST Docs to be used with [Jersey's test framework][20] | | [spring-auto-restdocs][21] | Uses introspection and Javadoc to automatically document request and response parameters | -| [restdocs-raml][22] | A Spring REST Docs extension that adds RAML support | -| [restdocs-openapi][23] | A Spring REST Docs extension that adds [OpenAPI 2.0][24] support | +| [restdocs-api-spec][23] | A Spring REST Docs extension that adds API specification support. It currently supports [OpenAPI 2][24] and [OpenAPI 3][25] | ## Licence @@ -68,6 +67,6 @@ Spring REST Docs is open source software released under the [Apache 2.0 license] [19]: https://github.com/RESTDocsEXT/restdocsext-jersey [20]: https://jersey.java.net/documentation/latest/test-framework.html [21]: https://github.com/ScaCap/spring-auto-restdocs -[22]: https://github.com/ePages-de/restdocs-raml -[23]: https://github.com/ePages-de/restdocs-openapi +[23]: https://github.com/ePages-de/restdocs-api-spec [24]: https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md +[25]: https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md From e23c6b45d4c0d26fd846603c38b6b142bc3716ff Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Thu, 1 Nov 2018 07:03:29 +0000 Subject: [PATCH 002/502] Stop flagging documented field beneath option null field as missing Closes gh-557 --- .../restdocs/payload/JsonContentHandler.java | 2 +- .../restdocs/payload/JsonContentHandlerTests.java | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/JsonContentHandler.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/JsonContentHandler.java index e64a91d11..1fbc2b5f1 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/JsonContentHandler.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/JsonContentHandler.java @@ -86,7 +86,7 @@ private boolean isMissing(FieldDescriptor candidate, Object payload) { } ExtractedField extracted = this.fieldProcessor.extract(candidate.getPath(), payload); - return isEmptyCollection(extracted.getValue()); + return extracted.getValue() == null || isEmptyCollection(extracted.getValue()); } private boolean isEmptyCollection(Object value) { diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/JsonContentHandlerTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/JsonContentHandlerTests.java index bfb6eb8fa..efe6cc70d 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/JsonContentHandlerTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/JsonContentHandlerTests.java @@ -183,4 +183,13 @@ public void describedMissingFieldThatIsChildOfNestedOptionalArrayThatContainsAnO assertThat(missingFields.get(0).getPath()).isEqualTo("a.[].b.[].c"); } + @Test + public void describedMissingFieldThatIsChildOfOptionalObjectThatIsNullIsNotConsideredMissing() { + List missingFields = new JsonContentHandler( + "{\"a\":null}".getBytes()).findMissingFields( + Arrays.asList(new FieldDescriptor("a").optional(), + new FieldDescriptor("a.b"))); + assertThat(missingFields.size()).isEqualTo(0); + } + } From ada273ba9eadb00705263fba0489086a965076b1 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 21 Nov 2018 13:03:24 +0000 Subject: [PATCH 003/502] Rework JsonFieldTypeResolver to only discover the field types See gh-549 --- .../restdocs/payload/JsonContentHandler.java | 12 +- .../restdocs/payload/JsonFieldProcessor.java | 17 +- .../restdocs/payload/JsonFieldTypes.java | 57 ++++ ...ver.java => JsonFieldTypesDiscoverer.java} | 56 ++-- .../payload/JsonFieldProcessorTests.java | 39 ++- .../payload/JsonFieldTypeResolverTests.java | 263 ------------------ .../JsonFieldTypesDiscovererTests.java | 209 ++++++++++++++ .../restdocs/payload/JsonFieldTypesTests.java | 63 +++++ 8 files changed, 402 insertions(+), 314 deletions(-) create mode 100644 spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/JsonFieldTypes.java rename spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/{JsonFieldTypeResolver.java => JsonFieldTypesDiscoverer.java} (58%) delete mode 100644 spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/JsonFieldTypeResolverTests.java create mode 100644 spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/JsonFieldTypesDiscovererTests.java create mode 100644 spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/JsonFieldTypesTests.java diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/JsonContentHandler.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/JsonContentHandler.java index 1fbc2b5f1..1ea884625 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/JsonContentHandler.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/JsonContentHandler.java @@ -37,7 +37,7 @@ class JsonContentHandler implements ContentHandler { private final JsonFieldProcessor fieldProcessor = new JsonFieldProcessor(); - private final JsonFieldTypeResolver fieldTypeResolver = new JsonFieldTypeResolver(); + private final JsonFieldTypesDiscoverer fieldTypesDiscoverer = new JsonFieldTypesDiscoverer(); private final ObjectMapper objectMapper = new ObjectMapper() .enable(SerializationFeature.INDENT_OUTPUT); @@ -147,16 +147,18 @@ private boolean isEmpty(Object object) { @Override public Object determineFieldType(FieldDescriptor fieldDescriptor) { if (fieldDescriptor.getType() == null) { - return this.fieldTypeResolver.resolveFieldType(fieldDescriptor, - readContent()); + return this.fieldTypesDiscoverer + .discoverFieldTypes(fieldDescriptor.getPath(), readContent()) + .coalesce(fieldDescriptor.isOptional()); } if (!(fieldDescriptor.getType() instanceof JsonFieldType)) { return fieldDescriptor.getType(); } JsonFieldType descriptorFieldType = (JsonFieldType) fieldDescriptor.getType(); try { - JsonFieldType actualFieldType = this.fieldTypeResolver - .resolveFieldType(fieldDescriptor, readContent()); + JsonFieldType actualFieldType = this.fieldTypesDiscoverer + .discoverFieldTypes(fieldDescriptor.getPath(), readContent()) + .coalesce(fieldDescriptor.isOptional()); if (descriptorFieldType == JsonFieldType.VARIES || descriptorFieldType == actualFieldType || (fieldDescriptor.isOptional() diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/JsonFieldProcessor.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/JsonFieldProcessor.java index 74b1f6a6c..9f50fcc0e 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/JsonFieldProcessor.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/JsonFieldProcessor.java @@ -41,20 +41,25 @@ boolean hasField(String path, Object payload) { ExtractedField extract(String path, Object payload) { JsonFieldPath compiledPath = JsonFieldPath.compile(path); - final List matches = new ArrayList<>(); + final List values = new ArrayList<>(); traverse(new ProcessingContext(payload, compiledPath), new MatchCallback() { @Override public void foundMatch(Match match) { - matches.add(match.getValue()); + values.add(match.getValue()); + } + + @Override + public void absent() { + values.add(ExtractedField.ABSENT); } }); - if (matches.isEmpty()) { - throw new FieldDoesNotExistException(path); + if (values.isEmpty()) { + values.add(ExtractedField.ABSENT); } return new ExtractedField( - (compiledPath.getType() != PathType.SINGLE) ? matches : matches.get(0), + (compiledPath.getType() != PathType.SINGLE) ? values : values.get(0), compiledPath.getType()); } @@ -427,6 +432,8 @@ private ProcessingContext descend(Object payload, Match match) { */ static class ExtractedField { + static final Object ABSENT = new Object(); + private final Object value; private final PathType type; diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/JsonFieldTypes.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/JsonFieldTypes.java new file mode 100644 index 000000000..7584b12b4 --- /dev/null +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/JsonFieldTypes.java @@ -0,0 +1,57 @@ +/* + * Copyright 2014-2018 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.payload; + +import java.util.Collections; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + +/** + * {@link JsonFieldType Types} for a field discovered in a JSON payload. + * + * @author Andy Wilkinson + */ +class JsonFieldTypes implements Iterable { + + private final Set fieldTypes; + + JsonFieldTypes(JsonFieldType fieldType) { + this(Collections.singleton(fieldType)); + } + + JsonFieldTypes(Set fieldTypes) { + this.fieldTypes = fieldTypes; + } + + JsonFieldType coalesce(boolean optional) { + Set types = new HashSet<>(this.fieldTypes); + if (optional && types.size() > 1) { + types.remove(JsonFieldType.NULL); + } + if (types.size() == 1) { + return types.iterator().next(); + } + return JsonFieldType.VARIES; + } + + @Override + public Iterator iterator() { + return this.fieldTypes.iterator(); + } + +} diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/JsonFieldTypeResolver.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/JsonFieldTypesDiscoverer.java similarity index 58% rename from spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/JsonFieldTypeResolver.java rename to spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/JsonFieldTypesDiscoverer.java index a577bc654..607498330 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/JsonFieldTypeResolver.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/JsonFieldTypesDiscoverer.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2017 the original author or authors. + * Copyright 2014-2018 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. @@ -17,50 +17,45 @@ package org.springframework.restdocs.payload; import java.util.Collection; +import java.util.HashSet; import java.util.Map; +import java.util.Set; import org.springframework.restdocs.payload.JsonFieldPath.PathType; import org.springframework.restdocs.payload.JsonFieldProcessor.ExtractedField; /** - * Resolves the type of a field in a JSON request or response payload. + * Discovers the types of the fields found at a path in a JSON request or response + * payload. * * @author Andy Wilkinson */ -class JsonFieldTypeResolver { +class JsonFieldTypesDiscoverer { private final JsonFieldProcessor fieldProcessor = new JsonFieldProcessor(); - JsonFieldType resolveFieldType(FieldDescriptor fieldDescriptor, Object payload) { - ExtractedField extractedField = this.fieldProcessor - .extract(fieldDescriptor.getPath(), payload); + JsonFieldTypes discoverFieldTypes(String path, Object payload) { + ExtractedField extractedField = this.fieldProcessor.extract(path, payload); Object value = extractedField.getValue(); if (value instanceof Collection && extractedField.getType() == PathType.MULTI) { - JsonFieldType commonType = null; - for (Object item : (Collection) value) { - JsonFieldType fieldType = determineFieldType(item); - if (commonType == null) { - commonType = fieldType; - } - else if (fieldType != commonType) { - if (!fieldDescriptor.isOptional()) { - return JsonFieldType.VARIES; - } - if (commonType == JsonFieldType.NULL) { - commonType = fieldType; - } - else if (fieldType != JsonFieldType.NULL) { - return JsonFieldType.VARIES; - } - } + Collection values = (Collection) value; + if (allAbsent(values)) { + throw new FieldDoesNotExistException(path); } - return commonType; + Set fieldTypes = new HashSet<>(); + for (Object item : values) { + fieldTypes.add(determineFieldType(item)); + } + return new JsonFieldTypes(fieldTypes); + } + if (value == ExtractedField.ABSENT) { + throw new FieldDoesNotExistException(path); } - return determineFieldType(value); + return new JsonFieldTypes(determineFieldType(value)); } private JsonFieldType determineFieldType(Object fieldValue) { - if (fieldValue == null) { + if (fieldValue == null || fieldValue == ExtractedField.ABSENT) { return JsonFieldType.NULL; } if (fieldValue instanceof String) { @@ -78,4 +73,13 @@ private JsonFieldType determineFieldType(Object fieldValue) { return JsonFieldType.NUMBER; } + private boolean allAbsent(Collection values) { + for (Object value : values) { + if (value != ExtractedField.ABSENT) { + return false; + } + } + return true; + } + } diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/JsonFieldProcessorTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/JsonFieldProcessorTests.java index c8733b814..a8632d493 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/JsonFieldProcessorTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/JsonFieldProcessorTests.java @@ -28,6 +28,8 @@ import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.Test; +import org.springframework.restdocs.payload.JsonFieldProcessor.ExtractedField; + import static org.assertj.core.api.Assertions.assertThat; /** @@ -109,7 +111,7 @@ public void extractOccasionallyAbsentFieldFromItemsInArray() { new HashMap()); payload.put("a", alpha); assertThat(this.fieldProcessor.extract("a[].b", payload).getValue()) - .isEqualTo(Arrays.asList("bravo")); + .isEqualTo(Arrays.asList("bravo", ExtractedField.ABSENT)); } @Test @@ -165,54 +167,61 @@ public void extractArraysFromItemsInNestedArray() { Arrays.asList(4))); } - @Test(expected = FieldDoesNotExistException.class) + @Test public void nonExistentTopLevelField() { - this.fieldProcessor.extract("a", Collections.emptyMap()); + assertThat(this.fieldProcessor.extract("a", Collections.emptyMap()).getValue()) + .isEqualTo(ExtractedField.ABSENT); } - @Test(expected = FieldDoesNotExistException.class) + @Test public void nonExistentNestedField() { HashMap payload = new HashMap<>(); payload.put("a", new HashMap()); - this.fieldProcessor.extract("a.b", payload); + assertThat(this.fieldProcessor.extract("a.b", payload).getValue()) + .isEqualTo(ExtractedField.ABSENT); } - @Test(expected = FieldDoesNotExistException.class) + @Test public void nonExistentNestedFieldWhenParentIsNotAMap() { HashMap payload = new HashMap<>(); payload.put("a", 5); - this.fieldProcessor.extract("a.b", payload); + assertThat(this.fieldProcessor.extract("a.b", payload).getValue()) + .isEqualTo(ExtractedField.ABSENT); } - @Test(expected = FieldDoesNotExistException.class) + @Test public void nonExistentFieldWhenParentIsAnArray() { HashMap payload = new HashMap<>(); HashMap alpha = new HashMap<>(); alpha.put("b", Arrays.asList(new HashMap())); payload.put("a", alpha); - this.fieldProcessor.extract("a.b.c", payload); + assertThat(this.fieldProcessor.extract("a.b.c", payload).getValue()) + .isEqualTo(ExtractedField.ABSENT); } - @Test(expected = FieldDoesNotExistException.class) + @Test public void nonExistentArrayField() { HashMap payload = new HashMap<>(); - this.fieldProcessor.extract("a[]", payload); + assertThat(this.fieldProcessor.extract("a[]", payload).getValue()) + .isEqualTo(ExtractedField.ABSENT); } - @Test(expected = FieldDoesNotExistException.class) + @Test public void nonExistentArrayFieldAsTypeDoesNotMatch() { HashMap payload = new HashMap<>(); payload.put("a", 5); - this.fieldProcessor.extract("a[]", payload); + assertThat(this.fieldProcessor.extract("a[]", payload).getValue()) + .isEqualTo(ExtractedField.ABSENT); } - @Test(expected = FieldDoesNotExistException.class) + @Test public void nonExistentFieldBeneathAnArray() { HashMap payload = new HashMap<>(); HashMap alpha = new HashMap<>(); alpha.put("b", Arrays.asList(new HashMap())); payload.put("a", alpha); - this.fieldProcessor.extract("a.b[].id", payload); + assertThat(this.fieldProcessor.extract("a.b[].id", payload).getValue()) + .isEqualTo(Arrays.asList(ExtractedField.ABSENT)); } @Test diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/JsonFieldTypeResolverTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/JsonFieldTypeResolverTests.java deleted file mode 100644 index 3ebb74cf5..000000000 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/JsonFieldTypeResolverTests.java +++ /dev/null @@ -1,263 +0,0 @@ -/* - * Copyright 2014-2018 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.payload; - -import java.io.IOException; -import java.util.List; -import java.util.Map; - -import com.fasterxml.jackson.databind.ObjectMapper; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link JsonFieldTypeResolver}. - * - * @author Andy Wilkinson - */ -public class JsonFieldTypeResolverTests { - - private final JsonFieldTypeResolver fieldTypeResolver = new JsonFieldTypeResolver(); - - @Rule - public ExpectedException thrownException = ExpectedException.none(); - - @Test - public void arrayField() throws IOException { - assertFieldType(JsonFieldType.ARRAY, "[]"); - } - - @Test - public void topLevelArray() throws IOException { - assertThat(this.fieldTypeResolver.resolveFieldType(new FieldDescriptor("[]"), - new ObjectMapper().readValue("[{\"a\":\"alpha\"}]", List.class))) - .isEqualTo(JsonFieldType.ARRAY); - } - - @Test - public void nestedArray() throws IOException { - assertThat(this.fieldTypeResolver.resolveFieldType(new FieldDescriptor("a[]"), - createPayload("{\"a\": [{\"b\":\"bravo\"}]}"))) - .isEqualTo(JsonFieldType.ARRAY); - } - - @Test - public void arrayNestedBeneathAnArray() throws IOException { - assertThat(this.fieldTypeResolver.resolveFieldType(new FieldDescriptor("a[].b[]"), - createPayload("{\"a\": [{\"b\": [ 1, 2 ]}]}"))) - .isEqualTo(JsonFieldType.ARRAY); - } - - @Test - public void specificFieldOfObjectInArrayNestedBeneathAnArray() throws IOException { - assertThat( - this.fieldTypeResolver.resolveFieldType(new FieldDescriptor("a[].b[].c"), - createPayload("{\"a\": [{\"b\": [ {\"c\": 5}, {\"c\": 5}]}]}"))) - .isEqualTo(JsonFieldType.NUMBER); - } - - @Test - public void booleanField() throws IOException { - assertFieldType(JsonFieldType.BOOLEAN, "true"); - } - - @Test - public void objectField() throws IOException { - assertFieldType(JsonFieldType.OBJECT, "{}"); - } - - @Test - public void nullField() throws IOException { - assertFieldType(JsonFieldType.NULL, "null"); - } - - @Test - public void numberField() throws IOException { - assertFieldType(JsonFieldType.NUMBER, "1.2345"); - } - - @Test - public void stringField() throws IOException { - assertFieldType(JsonFieldType.STRING, "\"Foo\""); - } - - @Test - public void nestedField() throws IOException { - assertThat(this.fieldTypeResolver.resolveFieldType(new FieldDescriptor("a.b.c"), - createPayload("{\"a\":{\"b\":{\"c\":{}}}}"))) - .isEqualTo(JsonFieldType.OBJECT); - } - - @Test - public void multipleFieldsWithSameType() throws IOException { - assertThat(this.fieldTypeResolver.resolveFieldType(new FieldDescriptor("a[].id"), - createPayload("{\"a\":[{\"id\":1},{\"id\":2}]}"))) - .isEqualTo(JsonFieldType.NUMBER); - } - - @Test - public void multipleFieldsWithDifferentTypes() throws IOException { - assertThat(this.fieldTypeResolver.resolveFieldType(new FieldDescriptor("a[].id"), - createPayload("{\"a\":[{\"id\":1},{\"id\":true}]}"))) - .isEqualTo(JsonFieldType.VARIES); - } - - @Test - public void multipleFieldsWithDifferentTypesAndSometimesAbsent() throws IOException { - assertThat(this.fieldTypeResolver.resolveFieldType(new FieldDescriptor("a[].id"), - createPayload("{\"a\":[{\"id\":1},{\"id\":true}, { }]}"))) - .isEqualTo(JsonFieldType.VARIES); - } - - @Test - public void multipleFieldsWithDifferentTypesAndSometimesAbsentWhenOptionalResolvesToVaries() - throws IOException { - assertThat(this.fieldTypeResolver.resolveFieldType( - new FieldDescriptor("a[].id").optional(), - createPayload("{\"a\":[{\"id\":1},{\"id\":true}, { }]}"))) - .isEqualTo(JsonFieldType.VARIES); - } - - @Test - public void multipleFieldsWhenSometimesAbsent() throws IOException { - assertThat(this.fieldTypeResolver.resolveFieldType(new FieldDescriptor("a[].id"), - createPayload("{\"a\":[{\"id\":1},{ }]}"))) - .isEqualTo(JsonFieldType.NUMBER); - } - - @Test - public void multipleFieldsWithDifferentTypesAndSometimesNull() throws IOException { - assertThat(this.fieldTypeResolver.resolveFieldType(new FieldDescriptor("a[].id"), - createPayload("{\"a\":[{\"id\":1},{\"id\":true}, {\"id\":null}]}"))) - .isEqualTo(JsonFieldType.VARIES); - } - - @Test - public void multipleFieldsWhenNotNullThenNullWhenRequiredHasVariesType() - throws IOException { - assertThat(this.fieldTypeResolver.resolveFieldType(new FieldDescriptor("a[].id"), - createPayload("{\"a\":[{\"id\":1},{\"id\":null}]}"))) - .isEqualTo(JsonFieldType.VARIES); - } - - @Test - public void multipleFieldsWhenNotNullThenNullWhenOptionalHasSpecificType() - throws IOException { - assertThat(this.fieldTypeResolver.resolveFieldType( - new FieldDescriptor("a[].id").optional(), - createPayload("{\"a\":[{\"id\":1},{\"id\":null}]}"))) - .isEqualTo(JsonFieldType.NUMBER); - } - - @Test - public void multipleFieldsWhenNullThenNotNullWhenRequiredHasVariesType() - throws IOException { - assertThat(this.fieldTypeResolver.resolveFieldType(new FieldDescriptor("a[].id"), - createPayload("{\"a\":[{\"id\":null},{\"id\":1}]}"))) - .isEqualTo(JsonFieldType.VARIES); - } - - @Test - public void multipleFieldsWhenNullThenNotNullWhenOptionalHasSpecificType() - throws IOException { - assertThat(this.fieldTypeResolver.resolveFieldType( - new FieldDescriptor("a[].id").optional(), - createPayload("{\"a\":[{\"id\":null},{\"id\":1}]}"))) - .isEqualTo(JsonFieldType.NUMBER); - } - - @Test - public void multipleFieldsWhenEitherNullOrAbsent() throws IOException { - assertThat(this.fieldTypeResolver.resolveFieldType(new FieldDescriptor("a[].id"), - createPayload("{\"a\":[{},{\"id\":null}]}"))) - .isEqualTo(JsonFieldType.NULL); - } - - @Test - public void multipleFieldsThatAreAllNull() throws IOException { - assertThat(this.fieldTypeResolver.resolveFieldType(new FieldDescriptor("a[].id"), - createPayload("{\"a\":[{\"id\":null},{\"id\":null}]}"))) - .isEqualTo(JsonFieldType.NULL); - } - - @Test - public void nonExistentSingleFieldProducesFieldDoesNotExistException() - throws IOException { - this.thrownException.expect(FieldDoesNotExistException.class); - this.thrownException.expectMessage( - "The payload does not contain a field with the path 'a.b'"); - this.fieldTypeResolver.resolveFieldType(new FieldDescriptor("a.b"), - createPayload("{\"a\":{}}")); - } - - @Test - public void nonExistentMultipleFieldsProducesFieldDoesNotExistException() - throws IOException { - this.thrownException.expect(FieldDoesNotExistException.class); - this.thrownException.expectMessage( - "The payload does not contain a field with the path 'a[].b'"); - this.fieldTypeResolver.resolveFieldType(new FieldDescriptor("a[].b"), - createPayload("{\"a\":[{\"c\":1},{\"c\":2}]}")); - } - - @Test - public void leafWildcardWithCommonType() throws IOException { - assertThat(this.fieldTypeResolver.resolveFieldType(new FieldDescriptor("a.*"), - createPayload("{\"a\": {\"b\": 5, \"c\": 6}}"))) - .isEqualTo(JsonFieldType.NUMBER); - } - - @Test - public void leafWildcardWithVaryingType() throws IOException { - assertThat(this.fieldTypeResolver.resolveFieldType(new FieldDescriptor("a.*"), - createPayload("{\"a\": {\"b\": 5, \"c\": \"six\"}}"))) - .isEqualTo(JsonFieldType.VARIES); - } - - @Test - public void intermediateWildcardWithCommonType() throws IOException { - assertThat(this.fieldTypeResolver.resolveFieldType(new FieldDescriptor("a.*.d"), - createPayload("{\"a\": {\"b\": {\"d\": 4}, \"c\": {\"d\": 5}}}}"))) - .isEqualTo(JsonFieldType.NUMBER); - } - - @Test - public void intermediateWildcardWithVaryingType() throws IOException { - assertThat(this.fieldTypeResolver.resolveFieldType(new FieldDescriptor("a.*.d"), - createPayload("{\"a\": {\"b\": {\"d\": 4}, \"c\": {\"d\": \"four\"}}}}"))) - .isEqualTo(JsonFieldType.VARIES); - } - - private void assertFieldType(JsonFieldType expectedType, String jsonValue) - throws IOException { - assertThat(this.fieldTypeResolver.resolveFieldType(new FieldDescriptor("field"), - createSimplePayload(jsonValue))).isEqualTo(expectedType); - } - - private Map createSimplePayload(String value) throws IOException { - return createPayload("{\"field\":" + value + "}"); - } - - @SuppressWarnings("unchecked") - private Map createPayload(String json) throws IOException { - return new ObjectMapper().readValue(json, Map.class); - } - -} diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/JsonFieldTypesDiscovererTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/JsonFieldTypesDiscovererTests.java new file mode 100644 index 000000000..1d05fac68 --- /dev/null +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/JsonFieldTypesDiscovererTests.java @@ -0,0 +1,209 @@ +/* + * Copyright 2014-2018 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.payload; + +import java.io.IOException; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link JsonFieldTypesDiscoverer}. + * + * @author Andy Wilkinson + */ +public class JsonFieldTypesDiscovererTests { + + private final JsonFieldTypesDiscoverer fieldTypeDiscoverer = new JsonFieldTypesDiscoverer(); + + @Rule + public ExpectedException thrownException = ExpectedException.none(); + + @Test + public void arrayField() throws IOException { + assertThat(discoverFieldTypes("[]")).containsExactly(JsonFieldType.ARRAY); + } + + @Test + public void topLevelArray() throws IOException { + assertThat(discoverFieldTypes("[]", "[{\"a\":\"alpha\"}]")) + .containsExactly(JsonFieldType.ARRAY); + } + + @Test + public void nestedArray() throws IOException { + assertThat(discoverFieldTypes("a[]", "{\"a\": [{\"b\":\"bravo\"}]}")) + .containsExactly(JsonFieldType.ARRAY); + } + + @Test + public void arrayNestedBeneathAnArray() throws IOException { + assertThat(discoverFieldTypes("a[].b[]", "{\"a\": [{\"b\": [ 1, 2 ]}]}")) + .containsExactly(JsonFieldType.ARRAY); + } + + @Test + public void specificFieldOfObjectInArrayNestedBeneathAnArray() throws IOException { + assertThat(discoverFieldTypes("a[].b[].c", + "{\"a\": [{\"b\": [ {\"c\": 5}, {\"c\": 5}]}]}")) + .containsExactly(JsonFieldType.NUMBER); + } + + @Test + public void booleanField() throws IOException { + assertThat(discoverFieldTypes("true")).containsExactly(JsonFieldType.BOOLEAN); + } + + @Test + public void objectField() throws IOException { + assertThat(discoverFieldTypes("{}")).containsExactly(JsonFieldType.OBJECT); + } + + @Test + public void nullField() throws IOException { + assertThat(discoverFieldTypes("null")).containsExactly(JsonFieldType.NULL); + } + + @Test + public void numberField() throws IOException { + assertThat(discoverFieldTypes("1.2345")).containsExactly(JsonFieldType.NUMBER); + } + + @Test + public void stringField() throws IOException { + assertThat(discoverFieldTypes("\"Foo\"")).containsExactly(JsonFieldType.STRING); + } + + @Test + public void nestedField() throws IOException { + assertThat(discoverFieldTypes("a.b.c", "{\"a\":{\"b\":{\"c\":{}}}}")) + .containsExactly(JsonFieldType.OBJECT); + } + + @Test + public void multipleFieldsWithSameType() throws IOException { + assertThat(discoverFieldTypes("a[].id", "{\"a\":[{\"id\":1},{\"id\":2}]}")) + .containsExactly(JsonFieldType.NUMBER); + } + + @Test + public void multipleFieldsWithDifferentTypes() throws IOException { + assertThat(discoverFieldTypes("a[].id", "{\"a\":[{\"id\":1},{\"id\":true}]}")) + .containsExactlyInAnyOrder(JsonFieldType.NUMBER, JsonFieldType.BOOLEAN); + } + + @Test + public void multipleFieldsWithDifferentTypesAndSometimesAbsent() throws IOException { + assertThat(discoverFieldTypes("a[].id", "{\"a\":[{\"id\":1},{\"id\":true}, {}]}")) + .containsExactlyInAnyOrder(JsonFieldType.NUMBER, JsonFieldType.BOOLEAN, + JsonFieldType.NULL); + } + + @Test + public void multipleFieldsWhenSometimesAbsent() throws IOException { + assertThat(discoverFieldTypes("a[].id", "{\"a\":[{\"id\":1},{\"id\":2}, {}]}")) + .containsExactlyInAnyOrder(JsonFieldType.NUMBER, JsonFieldType.NULL); + } + + @Test + public void multipleFieldsWhenSometimesNull() throws IOException { + assertThat(discoverFieldTypes("a[].id", + "{\"a\":[{\"id\":1},{\"id\":2}, {\"id\":null}]}")) + .containsExactlyInAnyOrder(JsonFieldType.NUMBER, + JsonFieldType.NULL); + } + + @Test + public void multipleFieldsWithDifferentTypesAndSometimesNull() throws IOException { + assertThat(discoverFieldTypes("a[].id", + "{\"a\":[{\"id\":1},{\"id\":true}, {\"id\":null}]}")) + .containsExactlyInAnyOrder(JsonFieldType.NUMBER, + JsonFieldType.BOOLEAN, JsonFieldType.NULL); + } + + @Test + public void multipleFieldsWhenEitherNullOrAbsent() throws IOException { + assertThat(discoverFieldTypes("a[].id", "{\"a\":[{},{\"id\":null}]}")) + .containsExactlyInAnyOrder(JsonFieldType.NULL); + } + + @Test + public void multipleFieldsThatAreAllNull() throws IOException { + assertThat(discoverFieldTypes("a[].id", "{\"a\":[{\"id\":null},{\"id\":null}]}")) + .containsExactlyInAnyOrder(JsonFieldType.NULL); + } + + @Test + public void nonExistentSingleFieldProducesFieldDoesNotExistException() + throws IOException { + this.thrownException.expect(FieldDoesNotExistException.class); + this.thrownException.expectMessage( + "The payload does not contain a field with the path 'a.b'"); + discoverFieldTypes("a.b", "{\"a\":{}}"); + } + + @Test + public void nonExistentMultipleFieldsProducesFieldDoesNotExistException() + throws IOException { + this.thrownException.expect(FieldDoesNotExistException.class); + this.thrownException.expectMessage( + "The payload does not contain a field with the path 'a[].b'"); + discoverFieldTypes("a[].b", "{\"a\":[{\"c\":1},{\"c\":2}]}"); + } + + @Test + public void leafWildcardWithCommonType() throws IOException { + assertThat(discoverFieldTypes("a.*", "{\"a\": {\"b\": 5, \"c\": 6}}")) + .containsExactlyInAnyOrder(JsonFieldType.NUMBER); + } + + @Test + public void leafWildcardWithVaryingType() throws IOException { + assertThat(discoverFieldTypes("a.*", "{\"a\": {\"b\": 5, \"c\": \"six\"}}")) + .containsExactlyInAnyOrder(JsonFieldType.NUMBER, JsonFieldType.STRING); + } + + @Test + public void intermediateWildcardWithCommonType() throws IOException { + assertThat(discoverFieldTypes("a.*.d", + "{\"a\": {\"b\": {\"d\": 4}, \"c\": {\"d\": 5}}}}")) + .containsExactlyInAnyOrder(JsonFieldType.NUMBER); + } + + @Test + public void intermediateWildcardWithVaryingType() throws IOException { + assertThat(discoverFieldTypes("a.*.d", + "{\"a\": {\"b\": {\"d\": 4}, \"c\": {\"d\": \"four\"}}}}")) + .containsExactlyInAnyOrder(JsonFieldType.NUMBER, + JsonFieldType.STRING); + } + + private JsonFieldTypes discoverFieldTypes(String value) throws IOException { + return discoverFieldTypes("field", "{\"field\":" + value + "}"); + } + + private JsonFieldTypes discoverFieldTypes(String path, String json) + throws IOException { + return this.fieldTypeDiscoverer.discoverFieldTypes(path, + new ObjectMapper().readValue(json, Object.class)); + } + +} diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/JsonFieldTypesTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/JsonFieldTypesTests.java new file mode 100644 index 000000000..01d4b5e54 --- /dev/null +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/JsonFieldTypesTests.java @@ -0,0 +1,63 @@ +/* + * Copyright 2014-2018 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.payload; + +import java.util.EnumSet; + +import org.junit.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link JsonFieldTypes}. + * + * @author Andy Wilkinson + */ +public class JsonFieldTypesTests { + + @Test + public void singleTypeCoalescesToThatType() { + assertThat(new JsonFieldTypes(JsonFieldType.NUMBER).coalesce(false)) + .isEqualTo(JsonFieldType.NUMBER); + } + + @Test + public void singleTypeCoalescesToThatTypeWhenOptional() { + assertThat(new JsonFieldTypes(JsonFieldType.NUMBER).coalesce(true)) + .isEqualTo(JsonFieldType.NUMBER); + } + + @Test + public void multipleTypesCoalescesToVaries() { + assertThat( + new JsonFieldTypes(EnumSet.of(JsonFieldType.ARRAY, JsonFieldType.NUMBER)) + .coalesce(false)).isEqualTo(JsonFieldType.VARIES); + } + + @Test + public void nullAndNonNullTypesCoalescesToVaries() { + assertThat(new JsonFieldTypes(EnumSet.of(JsonFieldType.ARRAY, JsonFieldType.NULL)) + .coalesce(false)).isEqualTo(JsonFieldType.VARIES); + } + + @Test + public void nullAndNonNullTypesCoalescesToNonNullTypeWhenOptional() { + assertThat(new JsonFieldTypes(EnumSet.of(JsonFieldType.ARRAY, JsonFieldType.NULL)) + .coalesce(true)).isEqualTo(JsonFieldType.ARRAY); + } + +} From 4453fde23cb0d1ad9f81ef23b8f329af7f7c2f06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathias=20D=C3=BCsterh=C3=B6ft?= Date: Wed, 5 Sep 2018 21:55:39 +0200 Subject: [PATCH 004/502] Provide a public API for resolving the type of a field See gh-549 --- .../payload/AbstractFieldsSnippet.java | 35 +----------- .../restdocs/payload/ContentHandler.java | 30 ++++++++-- .../restdocs/payload/FieldTypeResolver.java | 48 ++++++++++++++++ .../restdocs/payload/JsonContentHandler.java | 5 +- .../restdocs/payload/XmlContentHandler.java | 2 +- .../payload/FieldTypeResolverTests.java | 55 +++++++++++++++++++ .../payload/JsonContentHandlerTests.java | 17 +++--- .../payload/XmlContentHandlerTests.java | 1 + 8 files changed, 144 insertions(+), 49 deletions(-) create mode 100644 spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/FieldTypeResolver.java create mode 100644 spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/FieldTypeResolverTests.java diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/AbstractFieldsSnippet.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/AbstractFieldsSnippet.java index fafde4a04..990cd2bb6 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/AbstractFieldsSnippet.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/AbstractFieldsSnippet.java @@ -38,6 +38,7 @@ * * @author Andreas Evers * @author Andy Wilkinson + * @author Mathias Düsterhöft */ public abstract class AbstractFieldsSnippet extends TemplatedSnippet { @@ -160,7 +161,7 @@ protected Map createModel(Operation operation) { content = verifyContent( this.subsectionExtractor.extractSubsection(content, contentType)); } - ContentHandler contentHandler = getContentHandler(content, contentType); + ContentHandler contentHandler = ContentHandler.forContent(content, contentType); validateFieldDocumentation(contentHandler); @@ -168,7 +169,7 @@ protected Map createModel(Operation operation) { for (FieldDescriptor descriptor : this.fieldDescriptors) { if (!descriptor.isIgnored()) { try { - Object type = contentHandler.determineFieldType(descriptor); + Object type = contentHandler.resolveFieldType(descriptor); descriptorsToDocument.add(copyWithType(descriptor, type)); } catch (FieldDoesNotExistException ex) { @@ -200,36 +201,6 @@ private byte[] verifyContent(byte[] content) { return content; } - private ContentHandler getContentHandler(byte[] content, MediaType contentType) { - ContentHandler contentHandler = createJsonContentHandler(content); - if (contentHandler == null) { - contentHandler = createXmlContentHandler(content); - if (contentHandler == null) { - throw new PayloadHandlingException("Cannot handle " + contentType - + " content as it could not be parsed as JSON or XML"); - } - } - return contentHandler; - } - - private ContentHandler createJsonContentHandler(byte[] content) { - try { - return new JsonContentHandler(content); - } - catch (Exception ex) { - return null; - } - } - - private ContentHandler createXmlContentHandler(byte[] content) { - try { - return new XmlContentHandler(content); - } - catch (Exception ex) { - return null; - } - } - private void validateFieldDocumentation(ContentHandler payloadHandler) { List missingFields = payloadHandler .findMissingFields(this.fieldDescriptors); diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/ContentHandler.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/ContentHandler.java index 32bed30bd..9349ee88c 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/ContentHandler.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/ContentHandler.java @@ -18,12 +18,15 @@ import java.util.List; +import org.springframework.http.MediaType; + /** * A handler for the content of a request or response. * * @author Andy Wilkinson + * @author Mathias Düsterhöft */ -interface ContentHandler { +interface ContentHandler extends FieldTypeResolver { /** * Finds the fields that are missing from the handler's payload. A field is missing if @@ -48,11 +51,26 @@ interface ContentHandler { String getUndocumentedContent(List fieldDescriptors); /** - * Returns the type of the field that is described by the given - * {@code fieldDescriptor} based on the content of the payload. - * @param fieldDescriptor the field descriptor - * @return the type of the field + * Create a {@link ContentHandler} for the given content type and payload. + * @param content the payload + * @param contentType the content type + * @return the ContentHandler + * @throws PayloadHandlingException if no known ContentHandler can handle the content */ - Object determineFieldType(FieldDescriptor fieldDescriptor); + static ContentHandler forContent(byte[] content, MediaType contentType) { + + try { + return new JsonContentHandler(content); + } + catch (Exception je) { + try { + return new XmlContentHandler(content); + } + catch (Exception xe) { + throw new PayloadHandlingException("Cannot handle " + contentType + + " content as it could not be parsed as JSON or XML"); + } + } + } } diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/FieldTypeResolver.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/FieldTypeResolver.java new file mode 100644 index 000000000..af7aa8596 --- /dev/null +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/FieldTypeResolver.java @@ -0,0 +1,48 @@ +/* + * Copyright 2014-2018 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.payload; + +import org.springframework.http.MediaType; + +/** + * Public abstraction for external access to field type determination for xml and json + * payloads. + * + * @author Mathias Düsterhöft + * @since 2.0.3 + */ +public interface FieldTypeResolver { + + /** + * Create a FieldTypeResolver for the given content and contentType. + * @param content the payload that the {@link FieldTypeResolver} should handle + * @param contentType the content type of the payload + * @return the {@link FieldTypeResolver} + */ + static FieldTypeResolver forContent(byte[] content, MediaType contentType) { + return ContentHandler.forContent(content, contentType); + } + + /** + * Returns the type of the field that is described by the given + * {@code fieldDescriptor} based on the content of the payload. + * @param fieldDescriptor the field descriptor + * @return the type of the field + */ + Object resolveFieldType(FieldDescriptor fieldDescriptor); + +} diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/JsonContentHandler.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/JsonContentHandler.java index 1ea884625..b4d0e1fb2 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/JsonContentHandler.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/JsonContentHandler.java @@ -32,8 +32,9 @@ * A {@link ContentHandler} for JSON content. * * @author Andy Wilkinson + * @author Mathias Düsterhöft */ -class JsonContentHandler implements ContentHandler { +class JsonContentHandler implements ContentHandler, FieldTypeResolver { private final JsonFieldProcessor fieldProcessor = new JsonFieldProcessor(); @@ -145,7 +146,7 @@ private boolean isEmpty(Object object) { } @Override - public Object determineFieldType(FieldDescriptor fieldDescriptor) { + public Object resolveFieldType(FieldDescriptor fieldDescriptor) { if (fieldDescriptor.getType() == null) { return this.fieldTypesDiscoverer .discoverFieldTypes(fieldDescriptor.getPath(), readContent()) diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/XmlContentHandler.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/XmlContentHandler.java index 45c088468..c82ebb782 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/XmlContentHandler.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/XmlContentHandler.java @@ -190,7 +190,7 @@ private String prettyPrint(Document document) { } @Override - public Object determineFieldType(FieldDescriptor fieldDescriptor) { + public Object resolveFieldType(FieldDescriptor fieldDescriptor) { if (fieldDescriptor.getType() != null) { return fieldDescriptor.getType(); } diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/FieldTypeResolverTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/FieldTypeResolverTests.java new file mode 100644 index 000000000..0ed8780c4 --- /dev/null +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/FieldTypeResolverTests.java @@ -0,0 +1,55 @@ +/* + * Copyright 2014-2018 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.payload; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; + +import org.springframework.http.MediaType; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link FieldTypeResolver}. + * + * @author Mathias Düsterhöft + */ +public class FieldTypeResolverTests { + + @Rule + public ExpectedException thrownException = ExpectedException.none(); + + @Test + public void returnJsonFieldTypeResolver() { + assertThat(FieldTypeResolver.forContent("{\"field\": \"value\"}".getBytes(), + MediaType.APPLICATION_JSON)).isInstanceOf(JsonContentHandler.class); + } + + @Test + public void returnXmlContentHandler() { + assertThat(FieldTypeResolver.forContent("5".getBytes(), + MediaType.APPLICATION_XML)).isInstanceOf(XmlContentHandler.class); + } + + @Test + public void throwOnInvalidContent() { + this.thrownException.expect(PayloadHandlingException.class); + FieldTypeResolver.forContent("some".getBytes(), MediaType.APPLICATION_XML); + } + +} diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/JsonContentHandlerTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/JsonContentHandlerTests.java index efe6cc70d..67114e0b2 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/JsonContentHandlerTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/JsonContentHandlerTests.java @@ -29,6 +29,7 @@ * Tests for {@link JsonContentHandler}. * * @author Andy Wilkinson + * @author Mathias Düsterhöft */ public class JsonContentHandlerTests { @@ -39,14 +40,14 @@ public class JsonContentHandlerTests { public void typeForFieldWithNullValueMustMatch() { this.thrown.expect(FieldTypesDoNotMatchException.class); new JsonContentHandler("{\"a\": null}".getBytes()) - .determineFieldType(new FieldDescriptor("a").type(JsonFieldType.STRING)); + .resolveFieldType(new FieldDescriptor("a").type(JsonFieldType.STRING)); } @Test public void typeForFieldWithNotNullAndThenNullValueMustMatch() { this.thrown.expect(FieldTypesDoNotMatchException.class); new JsonContentHandler("{\"a\":[{\"id\":1},{\"id\":null}]}".getBytes()) - .determineFieldType( + .resolveFieldType( new FieldDescriptor("a[].id").type(JsonFieldType.STRING)); } @@ -54,7 +55,7 @@ public void typeForFieldWithNotNullAndThenNullValueMustMatch() { public void typeForFieldWithNullAndThenNotNullValueMustMatch() { this.thrown.expect(FieldTypesDoNotMatchException.class); new JsonContentHandler("{\"a\":[{\"id\":null},{\"id\":1}]}".getBytes()) - .determineFieldType( + .resolveFieldType( new FieldDescriptor("a.[].id").type(JsonFieldType.STRING)); } @@ -62,7 +63,7 @@ public void typeForFieldWithNullAndThenNotNullValueMustMatch() { public void typeForOptionalFieldWithNumberAndThenNullValueIsNumber() { Object fieldType = new JsonContentHandler( "{\"a\":[{\"id\":1},{\"id\":null}]}\"".getBytes()) - .determineFieldType(new FieldDescriptor("a[].id").optional()); + .resolveFieldType(new FieldDescriptor("a[].id").optional()); assertThat((JsonFieldType) fieldType).isEqualTo(JsonFieldType.NUMBER); } @@ -70,7 +71,7 @@ public void typeForOptionalFieldWithNumberAndThenNullValueIsNumber() { public void typeForOptionalFieldWithNullAndThenNumberIsNumber() { Object fieldType = new JsonContentHandler( "{\"a\":[{\"id\":null},{\"id\":1}]}".getBytes()) - .determineFieldType(new FieldDescriptor("a[].id").optional()); + .resolveFieldType(new FieldDescriptor("a[].id").optional()); assertThat((JsonFieldType) fieldType).isEqualTo(JsonFieldType.NUMBER); } @@ -78,7 +79,7 @@ public void typeForOptionalFieldWithNullAndThenNumberIsNumber() { public void typeForFieldWithNumberAndThenNullValueIsVaries() { Object fieldType = new JsonContentHandler( "{\"a\":[{\"id\":1},{\"id\":null}]}\"".getBytes()) - .determineFieldType(new FieldDescriptor("a[].id")); + .resolveFieldType(new FieldDescriptor("a[].id")); assertThat((JsonFieldType) fieldType).isEqualTo(JsonFieldType.VARIES); } @@ -86,14 +87,14 @@ public void typeForFieldWithNumberAndThenNullValueIsVaries() { public void typeForFieldWithNullAndThenNumberIsVaries() { Object fieldType = new JsonContentHandler( "{\"a\":[{\"id\":null},{\"id\":1}]}".getBytes()) - .determineFieldType(new FieldDescriptor("a[].id")); + .resolveFieldType(new FieldDescriptor("a[].id")); assertThat((JsonFieldType) fieldType).isEqualTo(JsonFieldType.VARIES); } @Test public void typeForOptionalFieldWithNullValueCanBeProvidedExplicitly() { Object fieldType = new JsonContentHandler("{\"a\": null}".getBytes()) - .determineFieldType( + .resolveFieldType( new FieldDescriptor("a").type(JsonFieldType.STRING).optional()); assertThat((JsonFieldType) fieldType).isEqualTo(JsonFieldType.STRING); } diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/XmlContentHandlerTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/XmlContentHandlerTests.java index 904093b8c..511c86212 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/XmlContentHandlerTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/XmlContentHandlerTests.java @@ -30,6 +30,7 @@ * Tests for {@link XmlContentHandler}. * * @author Andy Wilkinson + * @author Mathias Düsterhöft */ public class XmlContentHandlerTests { From 64ea9c29f5c884d6930e5dd7a8898ca97578aec5 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 21 Nov 2018 14:17:03 +0000 Subject: [PATCH 005/502] Polish "Provide a public API for resolving the type of a field" Closes gh-549 --- .../restdocs/payload/FieldTypeResolver.java | 13 +++++++------ .../restdocs/payload/JsonContentHandler.java | 2 +- .../restdocs/payload/XmlContentHandlerTests.java | 1 - 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/FieldTypeResolver.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/FieldTypeResolver.java index af7aa8596..32aa4fc02 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/FieldTypeResolver.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/FieldTypeResolver.java @@ -19,26 +19,27 @@ import org.springframework.http.MediaType; /** - * Public abstraction for external access to field type determination for xml and json - * payloads. + * Resolves the type of a field in a request or response payload. * * @author Mathias Düsterhöft + * @author Andy Wilkinson * @since 2.0.3 */ public interface FieldTypeResolver { /** - * Create a FieldTypeResolver for the given content and contentType. - * @param content the payload that the {@link FieldTypeResolver} should handle + * Create a {@code FieldTypeResolver} for the given {@code content} and + * {@code contentType}. + * @param content the payload that the {@code FieldTypeResolver} should handle * @param contentType the content type of the payload - * @return the {@link FieldTypeResolver} + * @return the {@code FieldTypeResolver} */ static FieldTypeResolver forContent(byte[] content, MediaType contentType) { return ContentHandler.forContent(content, contentType); } /** - * Returns the type of the field that is described by the given + * Resolves the type of the field that is described by the given * {@code fieldDescriptor} based on the content of the payload. * @param fieldDescriptor the field descriptor * @return the type of the field diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/JsonContentHandler.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/JsonContentHandler.java index b4d0e1fb2..08875e41e 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/JsonContentHandler.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/JsonContentHandler.java @@ -34,7 +34,7 @@ * @author Andy Wilkinson * @author Mathias Düsterhöft */ -class JsonContentHandler implements ContentHandler, FieldTypeResolver { +class JsonContentHandler implements ContentHandler { private final JsonFieldProcessor fieldProcessor = new JsonFieldProcessor(); diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/XmlContentHandlerTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/XmlContentHandlerTests.java index 511c86212..904093b8c 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/XmlContentHandlerTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/XmlContentHandlerTests.java @@ -30,7 +30,6 @@ * Tests for {@link XmlContentHandler}. * * @author Andy Wilkinson - * @author Mathias Düsterhöft */ public class XmlContentHandlerTests { From 1966640520afb2a0c640f3cbcb59520a093336d3 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 21 Nov 2018 15:03:48 +0000 Subject: [PATCH 006/502] Only attempt parameter resolution in a test method context Previously, RestDocumenationExtension would attempt parameter resolution for any use RestDocumentationContextProvider. Due to the provider being method-scoped, this could lead to a NullPointerException when it was resolved in the context of a class. This commit updates RestDocumentationExtension so that it only supports parameter resolution for RestDocumentationContextProvider in the context of a test method. Closes gh-538 --- .../restdocs/RestDocumentationExtension.java | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/RestDocumentationExtension.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/RestDocumentationExtension.java index f384255ab..2ad54a20f 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/RestDocumentationExtension.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/RestDocumentationExtension.java @@ -47,8 +47,11 @@ public void afterEach(ExtensionContext context) throws Exception { @Override public boolean supportsParameter(ParameterContext parameterContext, ExtensionContext extensionContext) { - return RestDocumentationContextProvider.class - .isAssignableFrom(parameterContext.getParameter().getType()); + if (isTestMethodContext(extensionContext)) { + return RestDocumentationContextProvider.class + .isAssignableFrom(parameterContext.getParameter().getType()); + } + return false; } @Override @@ -58,6 +61,10 @@ public Object resolveParameter(ParameterContext parameterContext, .beforeOperation(); } + private boolean isTestMethodContext(ExtensionContext context) { + return context.getTestClass().isPresent() && context.getTestMethod().isPresent(); + } + private ManualRestDocumentation getDelegate(ExtensionContext context) { Namespace namespace = Namespace.create(getClass(), context.getUniqueId()); return context.getStore(namespace).getOrComputeIfAbsent( From b694298720aeaae9b523e762ea18f3266f87343f Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 21 Nov 2018 15:17:51 +0000 Subject: [PATCH 007/502] Prepare for Asciidoctor Gradle Plugin 2.0 by looking for gradle-projectdir Closes gh-562 --- .../SnippetsDirectoryResolver.java | 13 ++++++++- .../SnippetsDirectoryResolverTests.java | 27 +++++++++++++++++-- 2 files changed, 37 insertions(+), 3 deletions(-) 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 index 4e9c53eaf..5f927a838 100644 --- 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 @@ -21,6 +21,7 @@ import java.nio.file.Path; import java.nio.file.Paths; import java.util.Map; +import java.util.function.Supplier; /** * Resolves the directory from which snippets can be read for inclusion in an Asciidoctor @@ -57,13 +58,23 @@ private Path findPom(Path docdir) { } private File getGradleSnippetsDirectory(Map attributes) { - return new File(getRequiredAttribute(attributes, "projectdir"), + return new File( + getRequiredAttribute(attributes, "gradle-projectdir", + () -> getRequiredAttribute(attributes, "projectdir")), "build/generated-snippets"); } private String getRequiredAttribute(Map attributes, String name) { + return getRequiredAttribute(attributes, name, null); + } + + private String getRequiredAttribute(Map attributes, String name, + Supplier fallback) { String attribute = (String) attributes.get(name); if (attribute == null || attribute.length() == 0) { + if (fallback != null) { + return fallback.get(); + } throw new IllegalStateException(name + " attribute not found"); } return attribute; 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 index 711408be6..6e5383a83 100644 --- 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 @@ -78,7 +78,30 @@ public void illegalStateWhenDocdirAttributeIsNotSetInMavenProject() } @Test - public void gradleProjectsUseBuildGeneratedSnippetsBeneathProjectDir() + public void gradleProjectsUseBuildGeneratedSnippetsBeneathGradleProjectdir() + throws IOException { + Map attributes = new HashMap<>(); + attributes.put("gradle-projectdir", "project/dir"); + File snippetsDirectory = new SnippetsDirectoryResolver() + .getSnippetsDirectory(attributes); + assertThat(snippetsDirectory) + .isEqualTo(new File("project/dir/build/generated-snippets")); + } + + @Test + public void gradleProjectsUseBuildGeneratedSnippetsBeneathGradleProjectdirWhenBothItAndProjectdirAreSet() + throws IOException { + Map attributes = new HashMap<>(); + attributes.put("gradle-projectdir", "project/dir"); + attributes.put("projectdir", "fallback/dir"); + File snippetsDirectory = new SnippetsDirectoryResolver() + .getSnippetsDirectory(attributes); + assertThat(snippetsDirectory) + .isEqualTo(new File("project/dir/build/generated-snippets")); + } + + @Test + public void gradleProjectsUseBuildGeneratedSnippetsBeneathProjectdirWhenGradleProjectdirIsNotSet() throws IOException { Map attributes = new HashMap<>(); attributes.put("projectdir", "project/dir"); @@ -89,7 +112,7 @@ public void gradleProjectsUseBuildGeneratedSnippetsBeneathProjectDir() } @Test - public void illegalStateWhenProjectdirAttributeIsNotSetInGradleProject() + public void illegalStateWhenGradleProjectdirAndProjectdirAttributesAreNotSetInGradleProject() throws IOException { Map attributes = new HashMap<>(); this.thrown.expect(IllegalStateException.class); From 5b493977cce11b28ae4d37208cf660972c21b19c Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 21 Nov 2018 16:33:33 +0000 Subject: [PATCH 008/502] Update Slate sample's dependencies Closes gh-563 --- samples/rest-notes-slate/slate/Gemfile.lock | 71 +++++++++++---------- 1 file changed, 36 insertions(+), 35 deletions(-) diff --git a/samples/rest-notes-slate/slate/Gemfile.lock b/samples/rest-notes-slate/slate/Gemfile.lock index adacad9a8..0cdee1461 100644 --- a/samples/rest-notes-slate/slate/Gemfile.lock +++ b/samples/rest-notes-slate/slate/Gemfile.lock @@ -1,42 +1,42 @@ GEM remote: https://rubygems.org/ specs: - activesupport (5.0.1) + activesupport (5.0.7) concurrent-ruby (~> 1.0, >= 1.0.2) - i18n (~> 0.7) + i18n (>= 0.7, < 2) minitest (~> 5.1) tzinfo (~> 1.1) - addressable (2.5.0) - public_suffix (~> 2.0, >= 2.0.2) - autoprefixer-rails (6.6.1) + addressable (2.5.2) + public_suffix (>= 2.0.2, < 4.0) + autoprefixer-rails (6.7.7.2) execjs - backports (3.6.8) + backports (3.11.4) coffee-script (2.4.1) coffee-script-source execjs coffee-script-source (1.12.2) compass-import-once (1.0.5) sass (>= 3.2, < 3.5) - concurrent-ruby (1.0.4) + concurrent-ruby (1.1.3) contracts (0.13.0) - dotenv (2.2.0) + dotenv (2.5.0) erubis (2.7.0) execjs (2.7.0) fast_blank (1.0.0) - fastimage (2.0.1) - addressable (~> 2) - ffi (1.9.17) - haml (4.0.7) + fastimage (2.1.4) + ffi (1.9.25) + haml (5.0.4) + temple (>= 0.8.0) tilt hamster (3.0.0) concurrent-ruby (~> 1.0) - hashie (3.5.1) + hashie (3.6.0) i18n (0.7.0) - kramdown (1.13.2) + kramdown (1.17.0) listen (3.0.8) rb-fsevent (~> 0.9, >= 0.9.4) rb-inotify (~> 0.9, >= 0.9.7) - memoist (0.15.0) + memoist (0.16.0) middleman (4.2.1) coffee-script (~> 2.2) compass-import-once (= 1.0.5) @@ -73,38 +73,39 @@ GEM servolux tilt (~> 2.0) uglifier (~> 3.0) - middleman-sprockets (4.1.0) + middleman-sprockets (4.1.1) middleman-core (~> 4.0) sprockets (>= 3.0) middleman-syntax (3.0.0) middleman-core (>= 3.2) rouge (~> 2.0) - minitest (5.10.1) - padrino-helpers (0.13.3.3) + minitest (5.11.3) + padrino-helpers (0.13.3.4) i18n (~> 0.6, >= 0.6.7) - padrino-support (= 0.13.3.3) + padrino-support (= 0.13.3.4) tilt (>= 1.4.1, < 3) - padrino-support (0.13.3.3) + padrino-support (0.13.3.4) activesupport (>= 3.1) - parallel (1.10.0) - public_suffix (2.0.5) - rack (2.0.1) - rb-fsevent (0.9.8) - rb-inotify (0.9.8) - ffi (>= 0.5.0) + parallel (1.12.1) + public_suffix (3.0.3) + rack (2.0.6) + rb-fsevent (0.10.3) + rb-inotify (0.9.10) + ffi (>= 0.5.0, < 2) redcarpet (3.4.0) rouge (2.0.7) - sass (3.4.23) - servolux (0.12.0) - sprockets (3.7.1) + sass (3.4.25) + servolux (0.13.0) + sprockets (3.7.2) concurrent-ruby (~> 1.0) rack (> 1, < 3) - thor (0.19.4) - thread_safe (0.3.5) - tilt (2.0.6) - tzinfo (1.2.2) + temple (0.8.0) + thor (0.20.3) + thread_safe (0.3.6) + tilt (2.0.8) + tzinfo (1.2.5) thread_safe (~> 0.1) - uglifier (3.0.4) + uglifier (3.2.0) execjs (>= 0.3.0, < 3) PLATFORMS @@ -119,4 +120,4 @@ DEPENDENCIES rouge (~> 2.0.5) BUNDLED WITH - 1.14.3 + 1.17.1 From 9e1ba8a92291f7f91d858ca7fc76d67e61f57066 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Thu, 22 Nov 2018 11:00:23 +0000 Subject: [PATCH 009/502] Improve beneathPath to work with multiple matches with common structure Closes gh-473 --- .../FieldPathPayloadSubsectionExtractor.java | 26 +++-- .../restdocs/payload/JsonFieldPaths.java | 92 +++++++++++++++ ...ldPathPayloadSubsectionExtractorTests.java | 50 ++++---- .../restdocs/payload/JsonFieldPathsTests.java | 107 ++++++++++++++++++ .../payload/ResponseFieldsSnippetTests.java | 13 +++ 5 files changed, 260 insertions(+), 28 deletions(-) create mode 100644 spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/JsonFieldPaths.java create mode 100644 spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/JsonFieldPathsTests.java diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/FieldPathPayloadSubsectionExtractor.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/FieldPathPayloadSubsectionExtractor.java index 69b07cbb5..9b0b0fbb1 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/FieldPathPayloadSubsectionExtractor.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/FieldPathPayloadSubsectionExtractor.java @@ -17,12 +17,13 @@ package org.springframework.restdocs.payload; import java.io.IOException; +import java.util.ArrayList; import java.util.List; +import java.util.Set; import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.http.MediaType; -import org.springframework.restdocs.payload.JsonFieldPath.PathType; import org.springframework.restdocs.payload.JsonFieldProcessor.ExtractedField; /** @@ -44,7 +45,7 @@ public class FieldPathPayloadSubsectionExtractor /** * Creates a new {@code FieldPathPayloadSubsectionExtractor} that will extract the - * subsection of the JSON payload found at the given {@code fieldPath}. The + * subsection of the JSON payload beneath the given {@code fieldPath}. The * {@code fieldPath} prefixed with {@code beneath-} with be used as the subsection ID. * @param fieldPath the path of the field */ @@ -54,8 +55,8 @@ protected FieldPathPayloadSubsectionExtractor(String fieldPath) { /** * Creates a new {@code FieldPathPayloadSubsectionExtractor} that will extract the - * subsection of the JSON payload found at the given {@code fieldPath} and that will - * us the given {@code subsectionId} to identify the subsection. + * subsection of the JSON payload beneath the given {@code fieldPath} and that will + * use the given {@code subsectionId} to identify the subsection. * @param fieldPath the path of the field * @param subsectionId the ID of the subsection */ @@ -70,14 +71,23 @@ public byte[] extractSubsection(byte[] payload, MediaType contentType) { ExtractedField extractedField = new JsonFieldProcessor().extract( this.fieldPath, objectMapper.readValue(payload, Object.class)); Object value = extractedField.getValue(); - if (value instanceof List && extractedField.getType() == PathType.MULTI) { + if (value instanceof List) { List extractedList = (List) value; - if (extractedList.size() == 1) { + Set uncommonPaths = JsonFieldPaths.from(extractedList) + .getUncommon(); + if (uncommonPaths.isEmpty()) { value = extractedList.get(0); } else { - throw new PayloadHandlingException(this.fieldPath - + " does not uniquely identify a subsection of the payload"); + String message = this.fieldPath + " identifies multiple sections of " + + "the payload and they do not have a common structure. The " + + "following uncommon paths were found: "; + List prefixedPaths = new ArrayList<>(); + for (String uncommonPath : uncommonPaths) { + prefixedPaths.add(this.fieldPath + "." + uncommonPath); + } + message += prefixedPaths; + throw new PayloadHandlingException(message); } } return objectMapper.writeValueAsBytes(value); diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/JsonFieldPaths.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/JsonFieldPaths.java new file mode 100644 index 000000000..cfd622bf5 --- /dev/null +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/JsonFieldPaths.java @@ -0,0 +1,92 @@ +/* + * Copyright 2014-2018 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.payload; + +import java.util.Collection; +import java.util.HashSet; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; + +/** + * {@code JsonFieldPaths} provides support for extracting fields paths from JSON + * structures and identifying uncommon paths. + * + * @author Andy Wilkinson + */ +final class JsonFieldPaths { + + private final Set uncommonFieldPaths; + + private JsonFieldPaths(Set uncommonFieldPaths) { + this.uncommonFieldPaths = uncommonFieldPaths; + } + + Set getUncommon() { + return this.uncommonFieldPaths; + } + + static JsonFieldPaths from(Collection items) { + Set> itemsFieldPaths = new HashSet<>(); + Set allFieldPaths = new HashSet<>(); + for (Object item : items) { + Set paths = new LinkedHashSet<>(); + from(paths, "", item); + itemsFieldPaths.add(paths); + allFieldPaths.addAll(paths); + } + Set uncommonFieldPaths = new HashSet<>(); + for (Set itemFieldPaths : itemsFieldPaths) { + Set uncommonForItem = new HashSet<>(allFieldPaths); + uncommonForItem.removeAll(itemFieldPaths); + uncommonFieldPaths.addAll(uncommonForItem); + } + return new JsonFieldPaths(uncommonFieldPaths); + } + + private static void from(Set paths, String parent, Object object) { + if (object instanceof List) { + String path = append(parent, "[]"); + paths.add(path); + from(paths, path, (List) object); + } + else if (object instanceof Map) { + from(paths, parent, (Map) object); + } + } + + private static void from(Set paths, String parent, List items) { + for (Object item : items) { + from(paths, parent, item); + } + } + + private static void from(Set paths, String parent, Map map) { + for (Entry entry : map.entrySet()) { + String path = append(parent, entry.getKey()); + paths.add(path); + from(paths, path, entry.getValue()); + } + } + + private static String append(String path, Object suffix) { + return (path.length() == 0) ? ("" + suffix) : (path + "." + suffix); + } + +} diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/FieldPathPayloadSubsectionExtractorTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/FieldPathPayloadSubsectionExtractorTests.java index 42c7ae072..7ef2306f0 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/FieldPathPayloadSubsectionExtractorTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/FieldPathPayloadSubsectionExtractorTests.java @@ -17,7 +17,6 @@ package org.springframework.restdocs.payload; import java.io.IOException; -import java.util.List; import java.util.Map; import com.fasterxml.jackson.core.JsonParseException; @@ -30,7 +29,6 @@ import org.springframework.http.MediaType; import static org.assertj.core.api.Assertions.assertThat; -import static org.hamcrest.CoreMatchers.equalTo; /** * Tests for {@link FieldPathPayloadSubsectionExtractor}. @@ -57,29 +55,28 @@ public void extractMapSubsectionOfJsonMap() @Test @SuppressWarnings("unchecked") - public void extractMultiElementArraySubsectionOfJsonMap() + public void extractSingleElementArraySubsectionOfJsonMap() throws JsonParseException, JsonMappingException, IOException { - byte[] extractedPayload = new FieldPathPayloadSubsectionExtractor("a") - .extractSubsection("{\"a\":[{\"b\":5},{\"b\":4}]}".getBytes(), + byte[] extractedPayload = new FieldPathPayloadSubsectionExtractor("a.[]") + .extractSubsection("{\"a\":[{\"b\":5}]}".getBytes(), MediaType.APPLICATION_JSON); - List> extracted = new ObjectMapper() - .readValue(extractedPayload, List.class); - assertThat(extracted.size()).isEqualTo(2); - assertThat(extracted.get(0).get("b")).isEqualTo(5); - assertThat(extracted.get(1).get("b")).isEqualTo(4); + Map extracted = new ObjectMapper().readValue(extractedPayload, + Map.class); + assertThat(extracted.size()).isEqualTo(1); + assertThat(extracted).containsOnlyKeys("b"); } @Test @SuppressWarnings("unchecked") - public void extractSingleElementArraySubsectionOfJsonMap() + public void extractMultiElementArraySubsectionOfJsonMap() throws JsonParseException, JsonMappingException, IOException { - byte[] extractedPayload = new FieldPathPayloadSubsectionExtractor("a.[]") - .extractSubsection("{\"a\":[{\"b\":5}]}".getBytes(), + byte[] extractedPayload = new FieldPathPayloadSubsectionExtractor("a") + .extractSubsection("{\"a\":[{\"b\":5},{\"b\":4}]}".getBytes(), MediaType.APPLICATION_JSON); - List> extracted = new ObjectMapper() - .readValue(extractedPayload, List.class); + Map extracted = new ObjectMapper().readValue(extractedPayload, + Map.class); assertThat(extracted.size()).isEqualTo(1); - assertThat(extracted.get(0).get("b")).isEqualTo(5); + assertThat(extracted).containsOnlyKeys("b"); } @Test @@ -96,13 +93,26 @@ public void extractMapSubsectionFromSingleElementArrayInAJsonMap() } @Test - public void extractMapSubsectionFromMultiElementArrayInAJsonMap() + @SuppressWarnings("unchecked") + public void extractMapSubsectionWithCommonStructureFromMultiElementArrayInAJsonMap() + throws JsonParseException, JsonMappingException, IOException { + byte[] extractedPayload = new FieldPathPayloadSubsectionExtractor("a.[].b") + .extractSubsection( + "{\"a\":[{\"b\":{\"c\":5}},{\"b\":{\"c\":6}}]}".getBytes(), + MediaType.APPLICATION_JSON); + Map extracted = new ObjectMapper().readValue(extractedPayload, + Map.class); + assertThat(extracted.size()).isEqualTo(1); + assertThat(extracted).containsOnlyKeys("c"); + } + + @Test + public void extractMapSubsectionWithVaryingStructureFromMultiElementArrayInAJsonMap() throws JsonParseException, JsonMappingException, IOException { this.thrown.expect(PayloadHandlingException.class); - this.thrown.expectMessage( - equalTo("a.[].b does not uniquely identify a subsection of the payload")); + this.thrown.expectMessage("The following uncommon paths were found: [a.[].b.d]"); new FieldPathPayloadSubsectionExtractor("a.[].b").extractSubsection( - "{\"a\":[{\"b\":{\"c\":5}},{\"b\":{\"c\":6}}]}".getBytes(), + "{\"a\":[{\"b\":{\"c\":5}},{\"b\":{\"c\":6, \"d\": 7}}]}".getBytes(), MediaType.APPLICATION_JSON); } diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/JsonFieldPathsTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/JsonFieldPathsTests.java new file mode 100644 index 000000000..51dfd9e91 --- /dev/null +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/JsonFieldPathsTests.java @@ -0,0 +1,107 @@ +/* + * Copyright 2014-2018 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.payload; + +import java.io.IOException; +import java.util.Arrays; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link JsonFieldPaths}. + * + * @author Andy Wilkinson + */ +public class JsonFieldPathsTests { + + @Test + public void noUncommonPathsForSingleItem() { + assertThat(JsonFieldPaths + .from(Arrays + .asList(json("{\"a\": 1, \"b\": [ { \"c\": 2}, {\"c\": 3} ]}"))) + .getUncommon()).isEmpty(); + } + + @Test + public void noUncommonPathsForMultipleIdenticalItems() { + Object item = json("{\"a\": 1, \"b\": [ { \"c\": 2}, {\"c\": 3} ]}"); + assertThat(JsonFieldPaths.from(Arrays.asList(item, item)).getUncommon()) + .isEmpty(); + } + + @Test + public void noUncommonPathsForMultipleMatchingItemsWithDifferentScalarValues() { + assertThat(JsonFieldPaths + .from(Arrays.asList( + json("{\"a\": 1, \"b\": [ { \"c\": 2}, {\"c\": 3} ]}"), + json("{\"a\": 4, \"b\": [ { \"c\": 5}, {\"c\": 6} ]}"))) + .getUncommon()).isEmpty(); + } + + @Test + public void missingEntryInMapIsIdentifiedAsUncommon() { + assertThat(JsonFieldPaths.from(Arrays.asList(json("{\"a\": 1}"), + json("{\"a\": 1}"), json("{\"a\": 1, \"b\": 2}"))).getUncommon()) + .containsExactly("b"); + } + + @Test + public void missingEntryInNestedMapIsIdentifiedAsUncommon() { + assertThat( + JsonFieldPaths + .from(Arrays.asList(json("{\"a\": 1, \"b\": {\"c\": 1}}"), + json("{\"a\": 1, \"b\": {\"c\": 1}}"), + json("{\"a\": 1, \"b\": {\"c\": 1, \"d\": 2}}"))) + .getUncommon()).containsExactly("b.d"); + } + + @Test + public void missingEntriesInNestedMapAreIdentifiedAsUncommon() { + assertThat( + JsonFieldPaths.from(Arrays.asList(json("{\"a\": 1, \"b\": {\"c\": 1}}"), + json("{\"a\": 1, \"b\": {\"c\": 1}}"), + json("{\"a\": 1, \"b\": {\"d\": 2}}"))).getUncommon()) + .containsExactly("b.c", "b.d"); + } + + @Test + public void missingEntryBeneathArrayIsIdentifiedAsUncommon() { + assertThat(JsonFieldPaths.from(Arrays.asList(json("[{\"b\": 1}]"), + json("[{\"b\": 1}]"), json("[{\"b\": 1, \"c\": 2}]"))).getUncommon()) + .containsExactly("[].c"); + } + + @Test + public void missingEntryBeneathNestedArrayIsIdentifiedAsUncommon() { + assertThat(JsonFieldPaths.from(Arrays.asList(json("{\"a\": [{\"b\": 1}]}"), + json("{\"a\": [{\"b\": 1}]}"), json("{\"a\": [{\"b\": 1, \"c\": 2}]}"))) + .getUncommon()).containsExactly("a.[].c"); + } + + private Object json(String json) { + try { + return new ObjectMapper().readValue(json, Object.class); + } + catch (IOException ex) { + throw new RuntimeException(ex); + } + } + +} diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/ResponseFieldsSnippetTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/ResponseFieldsSnippetTests.java index d31448d8b..e2f4c4a84 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/ResponseFieldsSnippetTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/ResponseFieldsSnippetTests.java @@ -94,6 +94,19 @@ public void subsectionOfMapResponse() throws IOException { .row("`b`", "`Number`", "one").row("`c`", "`String`", "two")); } + @Test + public void subsectionOfMapResponseBeneathAnArray() throws IOException { + responseFields(beneathPath("a.b.[]"), fieldWithPath("c").description("one"), + fieldWithPath("d.[].e").description("two")) + .document(this.operationBuilder.response().content( + "{\"a\": {\"b\": [{\"c\": 1, \"d\": [{\"e\": 5}]}, {\"c\": 3, \"d\": [{\"e\": 4}]}]}}") + .build()); + assertThat(this.generatedSnippets.snippet("response-fields-beneath-a.b.[]")) + .is(tableWithHeader("Path", "Type", "Description") + .row("`c`", "`Number`", "one") + .row("`d.[].e`", "`Number`", "two")); + } + @Test public void subsectionOfMapResponseWithCommonsPrefix() throws IOException { responseFields(beneathPath("a")) From 71198a402a8f96795c76a90e7008e5e71cc01880 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Thu, 22 Nov 2018 11:33:34 +0000 Subject: [PATCH 010/502] Maintain formatting during subsection extraction Closes gh-466 --- .../FieldPathPayloadSubsectionExtractor.java | 22 ++++++++++++- ...ldPathPayloadSubsectionExtractorTests.java | 32 +++++++++++++++++++ 2 files changed, 53 insertions(+), 1 deletion(-) diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/FieldPathPayloadSubsectionExtractor.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/FieldPathPayloadSubsectionExtractor.java index 9b0b0fbb1..94292aa9f 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/FieldPathPayloadSubsectionExtractor.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/FieldPathPayloadSubsectionExtractor.java @@ -22,6 +22,7 @@ import java.util.Set; import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; import org.springframework.http.MediaType; import org.springframework.restdocs.payload.JsonFieldProcessor.ExtractedField; @@ -39,6 +40,9 @@ public class FieldPathPayloadSubsectionExtractor private static final ObjectMapper objectMapper = new ObjectMapper(); + private static final ObjectMapper prettyPrintingOjectMapper = new ObjectMapper() + .enable(SerializationFeature.INDENT_OUTPUT); + private final String fieldPath; private final String subsectionId; @@ -90,7 +94,7 @@ public byte[] extractSubsection(byte[] payload, MediaType contentType) { throw new PayloadHandlingException(message); } } - return objectMapper.writeValueAsBytes(value); + return getObjectMapper(payload).writeValueAsBytes(value); } catch (IOException ex) { throw new PayloadHandlingException(ex); @@ -115,4 +119,20 @@ public FieldPathPayloadSubsectionExtractor withSubsectionId(String subsectionId) return new FieldPathPayloadSubsectionExtractor(this.fieldPath, subsectionId); } + private ObjectMapper getObjectMapper(byte[] payload) { + if (isPrettyPrinted(payload)) { + return prettyPrintingOjectMapper; + } + return objectMapper; + } + + private boolean isPrettyPrinted(byte[] payload) { + for (byte b : payload) { + if (b == '\n') { + return true; + } + } + return false; + } + } diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/FieldPathPayloadSubsectionExtractorTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/FieldPathPayloadSubsectionExtractorTests.java index 7ef2306f0..9ffcd7d7b 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/FieldPathPayloadSubsectionExtractorTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/FieldPathPayloadSubsectionExtractorTests.java @@ -20,8 +20,10 @@ import java.util.Map; import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; @@ -116,4 +118,34 @@ public void extractMapSubsectionWithVaryingStructureFromMultiElementArrayInAJson MediaType.APPLICATION_JSON); } + @Test + public void extractedSubsectionIsPrettyPrintedWhenInputIsPrettyPrinted() + throws JsonParseException, JsonMappingException, JsonProcessingException, + IOException { + ObjectMapper objectMapper = new ObjectMapper() + .enable(SerializationFeature.INDENT_OUTPUT); + byte[] prettyPrintedPayload = objectMapper.writeValueAsBytes( + objectMapper.readValue("{\"a\": { \"b\": { \"c\": 1 }}}", Object.class)); + byte[] extractedSubsection = new FieldPathPayloadSubsectionExtractor("a.b") + .extractSubsection(prettyPrintedPayload, MediaType.APPLICATION_JSON); + byte[] prettyPrintedSubsection = objectMapper + .writeValueAsBytes(objectMapper.readValue("{\"c\": 1 }", Object.class)); + assertThat(new String(extractedSubsection)) + .isEqualTo(new String(prettyPrintedSubsection)); + } + + @Test + public void extractedSubsectionIsNotPrettyPrintedWhenInputIsNotPrettyPrinted() + throws JsonParseException, JsonMappingException, JsonProcessingException, + IOException { + ObjectMapper objectMapper = new ObjectMapper(); + byte[] payload = objectMapper.writeValueAsBytes( + objectMapper.readValue("{\"a\": { \"b\": { \"c\": 1 }}}", Object.class)); + byte[] extractedSubsection = new FieldPathPayloadSubsectionExtractor("a.b") + .extractSubsection(payload, MediaType.APPLICATION_JSON); + byte[] subsection = objectMapper + .writeValueAsBytes(objectMapper.readValue("{\"c\": 1 }", Object.class)); + assertThat(new String(extractedSubsection)).isEqualTo(new String(subsection)); + } + } From 1c941aaa559cdec9bd9570628f1ec8ed1db2f209 Mon Sep 17 00:00:00 2001 From: Johnny Lim Date: Tue, 27 Nov 2018 09:00:47 +0900 Subject: [PATCH 011/502] Update README link references so numbers are contiguous Closes gh-565 --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 9228c8e37..64a5e8bc8 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,7 @@ There are several that you can contribute to Spring REST Docs: | [restdocs-wiremock][17] | Auto-generate [WireMock][18] stubs as part of documenting your RESTful API | | [restdocsext-jersey][19] | Enables Spring REST Docs to be used with [Jersey's test framework][20] | | [spring-auto-restdocs][21] | Uses introspection and Javadoc to automatically document request and response parameters | -| [restdocs-api-spec][23] | A Spring REST Docs extension that adds API specification support. It currently supports [OpenAPI 2][24] and [OpenAPI 3][25] | +| [restdocs-api-spec][22] | A Spring REST Docs extension that adds API specification support. It currently supports [OpenAPI 2][23] and [OpenAPI 3][24] | ## Licence @@ -67,6 +67,6 @@ Spring REST Docs is open source software released under the [Apache 2.0 license] [19]: https://github.com/RESTDocsEXT/restdocsext-jersey [20]: https://jersey.java.net/documentation/latest/test-framework.html [21]: https://github.com/ScaCap/spring-auto-restdocs -[23]: https://github.com/ePages-de/restdocs-api-spec -[24]: https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md -[25]: https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md +[22]: https://github.com/ePages-de/restdocs-api-spec +[23]: https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md +[24]: https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md From c467b02c8ae0c417fcd7853dab2ef13561bd7b12 Mon Sep 17 00:00:00 2001 From: Spring Buildmaster Date: Mon, 10 Dec 2018 12:14:30 +0000 Subject: [PATCH 012/502] Next development version --- gradle.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle.properties b/gradle.properties index 6266034cd..e0497a6b7 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,3 @@ +version=1.2.7.BUILD-SNAPSHOT javaFormatVersion=0.0.7-SNAPSHOT -version=1.2.6.BUILD-SNAPSHOT -org.gradle.daemon=false \ No newline at end of file +org.gradle.daemon=false From c9db399713e74786382ecd3a3a285c3429ec86aa Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Mon, 10 Dec 2018 12:20:38 +0000 Subject: [PATCH 013/502] Update the samples to use 1.2.7 snaphots --- samples/rest-assured/build.gradle | 2 +- samples/rest-notes-grails/build.gradle | 2 +- samples/rest-notes-slate/build.gradle | 2 +- samples/rest-notes-spring-data-rest/pom.xml | 2 +- samples/rest-notes-spring-hateoas/build.gradle | 2 +- samples/testng/build.gradle | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/samples/rest-assured/build.gradle b/samples/rest-assured/build.gradle index bc45b8264..69c664ba1 100644 --- a/samples/rest-assured/build.gradle +++ b/samples/rest-assured/build.gradle @@ -30,7 +30,7 @@ ext { snippetsDir = file('build/generated-snippets') } -ext['spring-restdocs.version'] = '1.2.6.BUILD-SNAPSHOT' +ext['spring-restdocs.version'] = '1.2.7.BUILD-SNAPSHOT' dependencies { compile 'org.springframework.boot:spring-boot-starter-web' diff --git a/samples/rest-notes-grails/build.gradle b/samples/rest-notes-grails/build.gradle index b1164b3ab..b928077d2 100644 --- a/samples/rest-notes-grails/build.gradle +++ b/samples/rest-notes-grails/build.gradle @@ -22,7 +22,7 @@ apply plugin: "idea" apply plugin: "org.grails.grails-web" ext { - restDocsVersion = "1.2.6.BUILD-SNAPSHOT" + restDocsVersion = "1.2.7.BUILD-SNAPSHOT" snippetsDir = file('src/docs/generated-snippets') } diff --git a/samples/rest-notes-slate/build.gradle b/samples/rest-notes-slate/build.gradle index ada8e05c0..a64607862 100644 --- a/samples/rest-notes-slate/build.gradle +++ b/samples/rest-notes-slate/build.gradle @@ -26,7 +26,7 @@ ext { snippetsDir = file('build/generated-snippets') } -ext['spring-restdocs.version'] = '1.2.6.BUILD-SNAPSHOT' +ext['spring-restdocs.version'] = '1.2.7.BUILD-SNAPSHOT' dependencies { compile 'org.springframework.boot:spring-boot-starter-data-jpa' diff --git a/samples/rest-notes-spring-data-rest/pom.xml b/samples/rest-notes-spring-data-rest/pom.xml index 5feeac06f..3ff4e7695 100644 --- a/samples/rest-notes-spring-data-rest/pom.xml +++ b/samples/rest-notes-spring-data-rest/pom.xml @@ -18,7 +18,7 @@ UTF-8 1.7 - 1.2.6.BUILD-SNAPSHOT + 1.2.7.BUILD-SNAPSHOT diff --git a/samples/rest-notes-spring-hateoas/build.gradle b/samples/rest-notes-spring-hateoas/build.gradle index e189d2cda..e6e78f3c7 100644 --- a/samples/rest-notes-spring-hateoas/build.gradle +++ b/samples/rest-notes-spring-hateoas/build.gradle @@ -30,7 +30,7 @@ ext { snippetsDir = file('build/generated-snippets') } -ext['spring-restdocs.version'] = '1.2.6.BUILD-SNAPSHOT' +ext['spring-restdocs.version'] = '1.2.7.BUILD-SNAPSHOT' dependencies { asciidoctor "org.springframework.restdocs:spring-restdocs-asciidoctor:${project.ext['spring-restdocs.version']}" diff --git a/samples/testng/build.gradle b/samples/testng/build.gradle index ab948820d..efaf9aa25 100644 --- a/samples/testng/build.gradle +++ b/samples/testng/build.gradle @@ -30,7 +30,7 @@ ext { snippetsDir = file('build/generated-snippets') } -ext['spring-restdocs.version'] = '1.2.6.BUILD-SNAPSHOT' +ext['spring-restdocs.version'] = '1.2.7.BUILD-SNAPSHOT' dependencies { asciidoctor "org.springframework.restdocs:spring-restdocs-asciidoctor:${project.ext['spring-restdocs.version']}" From 244c6989c907f9926ef625825a6f0904652d387f Mon Sep 17 00:00:00 2001 From: Spring Buildmaster Date: Mon, 10 Dec 2018 13:33:36 +0000 Subject: [PATCH 014/502] Next development version --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 0520af25c..ce03bf970 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,3 @@ +version=2.0.4.BUILD-SNAPSHOT javaFormatVersion=0.0.7-SNAPSHOT -version=2.0.3.BUILD-SNAPSHOT org.gradle.daemon=false From bc02ee0c1c9012a47871686c9c3ab42a6f454e1f Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Mon, 10 Dec 2018 13:41:59 +0000 Subject: [PATCH 015/502] Update the samples to use 2.0.4 snapshots --- samples/junit5/build.gradle | 2 +- samples/rest-assured/build.gradle | 2 +- samples/rest-notes-grails/build.gradle | 2 +- samples/rest-notes-slate/build.gradle | 2 +- samples/rest-notes-spring-data-rest/pom.xml | 2 +- samples/rest-notes-spring-hateoas/build.gradle | 2 +- samples/testng/build.gradle | 2 +- samples/web-test-client/build.gradle | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/samples/junit5/build.gradle b/samples/junit5/build.gradle index ec9666a63..a9bac880a 100644 --- a/samples/junit5/build.gradle +++ b/samples/junit5/build.gradle @@ -34,7 +34,7 @@ ext { junitJupiterVersion = '5.0.0' } -ext['spring-restdocs.version'] = '2.0.3.BUILD-SNAPSHOT' +ext['spring-restdocs.version'] = '2.0.4.BUILD-SNAPSHOT' dependencies { asciidoctor "org.springframework.restdocs:spring-restdocs-asciidoctor:${project.ext['spring-restdocs.version']}" diff --git a/samples/rest-assured/build.gradle b/samples/rest-assured/build.gradle index e544e1071..d70b3c9c2 100644 --- a/samples/rest-assured/build.gradle +++ b/samples/rest-assured/build.gradle @@ -31,7 +31,7 @@ ext { snippetsDir = file('build/generated-snippets') } -ext['spring-restdocs.version'] = '2.0.3.BUILD-SNAPSHOT' +ext['spring-restdocs.version'] = '2.0.4.BUILD-SNAPSHOT' dependencies { compile 'org.springframework.boot:spring-boot-starter-web' diff --git a/samples/rest-notes-grails/build.gradle b/samples/rest-notes-grails/build.gradle index d339e4c9b..8af0afb79 100644 --- a/samples/rest-notes-grails/build.gradle +++ b/samples/rest-notes-grails/build.gradle @@ -22,7 +22,7 @@ apply plugin: "idea" apply plugin: "org.grails.grails-web" ext { - restDocsVersion = "2.0.3.BUILD-SNAPSHOT" + restDocsVersion = "2.0.4.BUILD-SNAPSHOT" snippetsDir = file('src/docs/generated-snippets') } diff --git a/samples/rest-notes-slate/build.gradle b/samples/rest-notes-slate/build.gradle index 3c17bccdc..e4a2bd3e4 100644 --- a/samples/rest-notes-slate/build.gradle +++ b/samples/rest-notes-slate/build.gradle @@ -27,7 +27,7 @@ ext { snippetsDir = file('build/generated-snippets') } -ext['spring-restdocs.version'] = '2.0.3.BUILD-SNAPSHOT' +ext['spring-restdocs.version'] = '2.0.4.BUILD-SNAPSHOT' dependencies { compile 'org.springframework.boot:spring-boot-starter-data-jpa' diff --git a/samples/rest-notes-spring-data-rest/pom.xml b/samples/rest-notes-spring-data-rest/pom.xml index 16b716db7..cf8faaceb 100644 --- a/samples/rest-notes-spring-data-rest/pom.xml +++ b/samples/rest-notes-spring-data-rest/pom.xml @@ -18,7 +18,7 @@ UTF-8 1.8 - 2.0.3.BUILD-SNAPSHOT + 2.0.4.BUILD-SNAPSHOT diff --git a/samples/rest-notes-spring-hateoas/build.gradle b/samples/rest-notes-spring-hateoas/build.gradle index 112fb41e7..131a6c296 100644 --- a/samples/rest-notes-spring-hateoas/build.gradle +++ b/samples/rest-notes-spring-hateoas/build.gradle @@ -31,7 +31,7 @@ ext { snippetsDir = file('build/generated-snippets') } -ext['spring-restdocs.version'] = '2.0.3.BUILD-SNAPSHOT' +ext['spring-restdocs.version'] = '2.0.4.BUILD-SNAPSHOT' dependencies { asciidoctor "org.springframework.restdocs:spring-restdocs-asciidoctor:${project.ext['spring-restdocs.version']}" diff --git a/samples/testng/build.gradle b/samples/testng/build.gradle index 9aef5712b..e8cec0a56 100644 --- a/samples/testng/build.gradle +++ b/samples/testng/build.gradle @@ -31,7 +31,7 @@ ext { snippetsDir = file('build/generated-snippets') } -ext['spring-restdocs.version'] = '2.0.3.BUILD-SNAPSHOT' +ext['spring-restdocs.version'] = '2.0.4.BUILD-SNAPSHOT' dependencies { asciidoctor "org.springframework.restdocs:spring-restdocs-asciidoctor:${project.ext['spring-restdocs.version']}" diff --git a/samples/web-test-client/build.gradle b/samples/web-test-client/build.gradle index 8d40e948b..90f07d3c5 100644 --- a/samples/web-test-client/build.gradle +++ b/samples/web-test-client/build.gradle @@ -20,7 +20,7 @@ ext { snippetsDir = file('build/generated-snippets') } -ext['spring-restdocs.version'] = '2.0.3.BUILD-SNAPSHOT' +ext['spring-restdocs.version'] = '2.0.4.BUILD-SNAPSHOT' dependencies { compile 'io.projectreactor.ipc:reactor-netty:0.7.1.RELEASE' From 6a2d30a32e150033f590163b20fe52ce2c7c7d11 Mon Sep 17 00:00:00 2001 From: Jay Bryant Date: Wed, 6 Feb 2019 13:10:30 -0600 Subject: [PATCH 016/502] Improve style and consistency of the documentation Closes gh-575 --- docs/src/docs/asciidoc/configuration.adoc | 101 ++- docs/src/docs/asciidoc/contributing.adoc | 13 +- .../customizing-requests-and-responses.adoc | 93 ++- .../docs/asciidoc/documenting-your-api.adoc | 736 ++++++++++-------- docs/src/docs/asciidoc/getting-started.adoc | 180 +++-- docs/src/docs/asciidoc/index.adoc | 4 +- docs/src/docs/asciidoc/introduction.adoc | 24 +- .../asciidoc/working-with-asciidoctor.adoc | 130 ++-- .../docs/asciidoc/working-with-markdown.adoc | 12 +- 9 files changed, 722 insertions(+), 571 deletions(-) diff --git a/docs/src/docs/asciidoc/configuration.adoc b/docs/src/docs/asciidoc/configuration.adoc index 9dad1faf3..6c6bd1932 100644 --- a/docs/src/docs/asciidoc/configuration.adoc +++ b/docs/src/docs/asciidoc/configuration.adoc @@ -1,17 +1,18 @@ [[configuration]] == Configuration - +This section covers how to configure Spring REST Docs. [[configuration-uris]] === Documented URIs - +This section covers configuring documented URIs. [[configuration-uris-mockmvc]] -==== MockMvc URI customization +==== MockMvc URI Customization -When using MockMvc, the default configuration for URIs documented by Spring REST Docs is: +When using MockMvc, the default configuration for URIs documented by Spring REST Docs is +as follows: |=== |Setting |Default @@ -26,16 +27,19 @@ When using MockMvc, the default configuration for URIs documented by Spring REST |`8080` |=== -This configuration is applied by `MockMvcRestDocumentationConfigurer`. You can use its API -to change one or more of the defaults to suit your needs: +This configuration is applied by `MockMvcRestDocumentationConfigurer`. You can use its +API to change one or more of the defaults to suit your needs. The following example shows +how to do so: +==== [source,java,indent=0] ---- include::{examples-dir}/com/example/mockmvc/CustomUriConfiguration.java[tags=custom-uri-configuration] ---- +==== NOTE: If the port is set to the default for the configured scheme (port 80 for HTTP or -port 443 for HTTPS), it will be omitted from any URIs in the generated snippets. +port 443 for HTTPS), it is omitted from any URIs in the generated snippets. TIP: To configure a request's context path, use the `contextPath` method on `MockHttpServletRequestBuilder`. @@ -43,37 +47,43 @@ TIP: To configure a request's context path, use the `contextPath` method on [[configuration-uris-rest-assured]] -==== REST Assured URI customization +==== REST Assured URI Customization REST Assured tests a service by making actual HTTP requests. As a result, URIs must be customized once the operation on the service has been performed but before it is -documented. A <> is provided for this purpose. +documented. A +<> is provided for this purpose. [[configuration-uris-webtestclient]] -==== WebTestClient URI customization +==== WebTestClient URI Customization When using WebTestClient, the default base for URIs documented by Spring REST -Docs is `http://localhost:8080`. This base can be customized using the +Docs is `http://localhost:8080`. You can customize this base by using the {spring-framework-api}/org/springframework/test/web/reactive/server/WebTestClient.Builder.html#baseUrl-java.lang.String-[ -`baseUrl(String)` method on `WebTestClient.Builder`]: +`baseUrl(String)` method on `WebTestClient.Builder`]. The following example shows how to +do so: +==== [source,java,indent=0] ---- include::{examples-dir}/com/example/webtestclient/CustomUriConfiguration.java[tags=custom-uri-configuration] ---- <1> Configure the base of documented URIs to be `https://api.example.com`. +==== [[configuration-snippet-encoding]] -=== Snippet encoding +=== Snippet Encoding -The default snippet encoding is `UTF-8`. You can change the default snippet encoding -using the `RestDocumentationConfigurer` API. For example, to use `ISO-8859-1`: +The default snippet encoding is `UTF-8`. You can change the default snippet encoding by +using the `RestDocumentationConfigurer` API. For example, the following examples use +`ISO-8859-1`: +==== [source,java,indent=0,role="primary"] .MockMvc ---- @@ -91,20 +101,23 @@ include::{examples-dir}/com/example/webtestclient/CustomEncoding.java[tags=custo ---- include::{examples-dir}/com/example/restassured/CustomEncoding.java[tags=custom-encoding] ---- +==== -TIP: When Spring REST Docs converts a request or response's content to a String, the -`charset` specified in the `Content-Type` header will be used if it is available. In its -absence, the JVM's default `Charset` will be used. The JVM's default `Charset` can be -configured using the `file.encoding` system property. +TIP: When Spring REST Docs converts the content of a request or a response to a `String`, +the `charset` specified in the `Content-Type` header is used if it is available. In its +absence, the JVM's default `Charset` is used. You can configure the JVM's default +`Charset` byusing the `file.encoding` system property. [[configuration-snippet-template-format]] -=== Snippet template format +=== Snippet Template Format The default snippet template format is Asciidoctor. Markdown is also supported out of the -box. You can change the default format using the `RestDocumentationConfigurer` API: +box. You can change the default format by using the `RestDocumentationConfigurer` API. +The following examples show how to do so: +==== [source,java,indent=0,role="primary"] .MockMvc ---- @@ -122,25 +135,27 @@ include::{examples-dir}/com/example/webtestclient/CustomFormat.java[tags=custom- ---- include::{examples-dir}/com/example/restassured/CustomFormat.java[tags=custom-format] ---- +==== [[configuration-default-snippets]] -=== Default snippets +=== Default Snippets Six snippets are produced by default: -- `curl-request` -- `http-request` -- `http-response` -- `httpie-request` -- `request-body` -- `response-body` +* `curl-request` +* `http-request` +* `http-response` +* `httpie-request` +* `request-body` +* `response-body` -You can change the default snippet configuration during setup using the -`RestDocumentationConfigurer` API. For example, to only produce the `curl-request` +You can change the default snippet configuration during setup by using the +`RestDocumentationConfigurer` API. The following examples produce only the `curl-request` snippet by default: +==== [source,java,indent=0,role="primary"] .MockMvc ---- @@ -158,35 +173,37 @@ include::{examples-dir}/com/example/webtestclient/CustomDefaultSnippets.java[tag ---- include::{examples-dir}/com/example/restassured/CustomDefaultSnippets.java[tags=custom-default-snippets] ---- +==== [[configuration-default-preprocessors]] -=== Default operation preprocessors +=== Default Operation Preprocessors -You can configure default request and response preprocessors during setup using the -`RestDocumentationConfigurer` API. For example, to remove the `Foo` headers from all requests -and pretty print all responses: +You can configure default request and response preprocessors during setup by using the +`RestDocumentationConfigurer` API. The following examples remove the `Foo` headers from +all requests and pretty print all responses: +==== [source,java,indent=0,role="primary"] .MockMvc ---- include::{examples-dir}/com/example/mockmvc/CustomDefaultOperationPreprocessors.java[tags=custom-default-operation-preprocessors] ---- -<1> Apply a request preprocessor that will remove the header named `Foo`. -<2> Apply a response preprocessor that will pretty print its content. +<1> Apply a request preprocessor that removes the header named `Foo`. +<2> Apply a response preprocessor that pretty prints its content. [source,java,indent=0,role="secondary"] .WebTestClient ---- include::{examples-dir}/com/example/webtestclient/CustomDefaultOperationPreprocessors.java[tags=custom-default-operation-preprocessors] ---- -<1> Apply a request preprocessor that will remove the header named `Foo`. -<2> Apply a response preprocessor that will pretty print its content. +<1> Apply a request preprocessor that removes the header named `Foo`. +<2> Apply a response preprocessor that pretty prints its content. [source,java,indent=0,role="secondary"] .REST Assured ---- include::{examples-dir}/com/example/restassured/CustomDefaultOperationPreprocessors.java[tags=custom-default-operation-preprocessors] ---- -<1> Apply a request preprocessor that will remove the header named `Foo`. -<2> Apply a response preprocessor that will pretty print its content. - +<1> Apply a request preprocessor that removes the header named `Foo`. +<2> Apply a response preprocessor that pretty prints its content. +==== diff --git a/docs/src/docs/asciidoc/contributing.adoc b/docs/src/docs/asciidoc/contributing.adoc index c5c36bff6..d4666189a 100644 --- a/docs/src/docs/asciidoc/contributing.adoc +++ b/docs/src/docs/asciidoc/contributing.adoc @@ -1,16 +1,17 @@ [[contributing]] == Contributing -Spring REST Docs is intended to make it easy for you to produce high-quality documentation -for your RESTful services. However, we can't achieve that goal without your contributions. +Spring REST Docs is intended to make it easy for you to produce high-quality +documentation for your RESTful services. However, we cannot achieve that goal without +your contributions. [[contributing-questions]] === Questions -You can ask questions about Spring REST Docs on http://stackoverflow.com[StackOverflow] -using the `spring-restdocs` tag. Similarly, we encourage you to help your fellow +You can ask questions about Spring REST Docs on http://stackoverflow.com[Stack Overflow] +by using the `spring-restdocs` tag. Similarly, we encourage you to help your fellow Spring REST Docs users by answering questions. @@ -28,9 +29,9 @@ ideally, includes a test that reproduces it. [[contributing-enhancements]] === Enhancements -If you'd like an enhancement to be made to Spring REST Docs, pull requests are most +If you would like an enhancement to be made to Spring REST Docs, pull requests are most welcome. The source code is on {github}[GitHub]. You may want to search the {github}/issues?q=is%3Aissue[existing issues] and {github}/pulls?q=is%3Apr[pull requests] -to see if the enhancement is already being worked on. You may also want to +to see if the enhancement has already been proprosed. You may also want to {github}/issues/new[open a new issue] to discuss a possible enhancement before work on it begins. diff --git a/docs/src/docs/asciidoc/customizing-requests-and-responses.adoc b/docs/src/docs/asciidoc/customizing-requests-and-responses.adoc index f47b9fd02..84f1268a4 100644 --- a/docs/src/docs/asciidoc/customizing-requests-and-responses.adoc +++ b/docs/src/docs/asciidoc/customizing-requests-and-responses.adoc @@ -3,68 +3,74 @@ There may be situations where you do not want to document a request exactly as it was sent or a response exactly as it was received. Spring REST Docs provides a number of -preprocessors that can be used to modify a request or response before it's documented. +preprocessors that can be used to modify a request or response before it is documented. -Preprocessing is configured by calling `document` with an `OperationRequestPreprocessor`, -and/or an `OperationResponsePreprocessor`. Instances can be obtained using the -static `preprocessRequest` and `preprocessResponse` methods on `Preprocessors`. For -example: +Preprocessing is configured by calling `document` with an `OperationRequestPreprocessor` +or an `OperationResponsePreprocessor`. You can obtain instances by using the static +`preprocessRequest` and `preprocessResponse` methods on `Preprocessors`. The following +examples show how to do so: +==== [source,java,indent=0,role="primary"] .MockMvc ---- include::{examples-dir}/com/example/mockmvc/PerTestPreprocessing.java[tags=preprocessing] ---- -<1> Apply a request preprocessor that will remove the header named `Foo`. -<2> Apply a response preprocessor that will pretty print its content. +<1> Apply a request preprocessor that removes the header named `Foo`. +<2> Apply a response preprocessor that pretty prints its content. [source,java,indent=0,role="secondary"] .WebTestClient ---- include::{examples-dir}/com/example/webtestclient/PerTestPreprocessing.java[tags=preprocessing] ---- -<1> Apply a request preprocessor that will remove the header named `Foo`. -<2> Apply a response preprocessor that will pretty print its content. +<1> Apply a request preprocessor that removes the header named `Foo`. +<2> Apply a response preprocessor that pretty prints its content. [source,java,indent=0,role="secondary"] .REST Assured ---- include::{examples-dir}/com/example/restassured/PerTestPreprocessing.java[tags=preprocessing] ---- -<1> Apply a request preprocessor that will remove the header named `Foo`. -<2> Apply a response preprocessor that will pretty print its content. +<1> Apply a request preprocessor that removes the header named `Foo`. +<2> Apply a response preprocessor that pretty prints its content. +==== -Alternatively, you may want to apply the same preprocessors to every test. You can do -so by configuring the preprocessors using the `RestDocumentationConfigurer` API in your -`@Before` method. For example to remove the `Foo` header from all requests and pretty print -all responses: +Alternatively, you may want to apply the same preprocessors to every test. You can do so +by using the `RestDocumentationConfigurer` API in your `@Before` method to configure the +preprocessors. For example to remove the `Foo` header from all requests and pretty print +all responses, you could do one of the following (depending on your testing environment): +==== [source,java,indent=0,role="primary"] .MockMvc ---- include::{examples-dir}/com/example/mockmvc/EveryTestPreprocessing.java[tags=setup] ---- -<1> Apply a request preprocessor that will remove the header named `Foo`. -<2> Apply a response preprocessor that will pretty print its content. +<1> Apply a request preprocessor that removes the header named `Foo`. +<2> Apply a response preprocessor that pretty prints its content. [source,java,indent=0,role="secondary"] .WebTestClient ---- include::{examples-dir}/com/example/webtestclient/EveryTestPreprocessing.java[tags=setup] ---- -<1> Apply a request preprocessor that will remove the header named `Foo`. -<2> Apply a response preprocessor that will pretty print its content. +<1> Apply a request preprocessor that removes the header named `Foo`. +<2> Apply a response preprocessor that pretty prints its content. [source,java,indent=0,role="secondary"] .REST Assured ---- include::{examples-dir}/com/example/restassured/EveryTestPreprocessing.java[tags=setup] ---- -<1> Apply a request preprocessor that will remove the header named `Foo`. -<2> Apply a response preprocessor that will pretty print its content. +<1> Apply a request preprocessor that removes the header named `Foo`. +<2> Apply a response preprocessor that pretty prints its content. +==== -Then, in each test, any configuration specific to that test can be performed. For example: +Then, in each test, you can perform any configuration specific to that test. The +following examples show how to do so: +==== [source,java,indent=0,role="primary"] .MockMvc ---- @@ -82,9 +88,10 @@ include::{examples-dir}/com/example/webtestclient/EveryTestPreprocessing.java[ta ---- include::{examples-dir}/com/example/restassured/EveryTestPreprocessing.java[tags=use] ---- +==== -Various built in preprocessors, including those illustrated above, are available via the -static methods on `Preprocessors`. See <> for further details. +Various built-in preprocessors, including those illustrated above, are available through +the static methods on `Preprocessors`. See <> for further details. @@ -94,7 +101,7 @@ static methods on `Preprocessors`. See <> for further deta [[customizing-requests-and-responses-preprocessors-pretty-print]] -==== Pretty printing +==== Pretty Printing `prettyPrint` on `Preprocessors` formats the content of the request or response to make it easier to read. @@ -102,18 +109,18 @@ to make it easier to read. [[customizing-requests-and-responses-preprocessors-mask-links]] -==== Masking links +==== Masking Links -If you're documenting a Hypermedia-based API, you may want to encourage clients to -navigate the API using links rather than through the use of hard coded URIs. One way to do -this is to limit the use of URIs in the documentation. `maskLinks` on -`Preprocessors` replaces the `href` of any links in the response with `...`. A -different replacement can also be specified if you wish. +If you are documenting a hypermedia-based API, you may want to encourage clients to +navigate the API by using links rather than through the use of hard coded URIs. One way to +do so is to limit the use of URIs in the documentation. `maskLinks` on +`Preprocessors` replaces the `href` of any links in the response with `...`. You can also +specify a different replacement if you wish. [[customizing-requests-and-responses-preprocessors-remove-headers]] -==== Removing headers +==== Removing Headers `removeHeaders` on `Preprocessors` removes any headers from the request or response where the name is equal to any of the given header names. @@ -124,18 +131,18 @@ response where the name matches any of the given regular expression patterns. [[customizing-requests-and-responses-preprocessors-replace-patterns]] -==== Replacing patterns +==== Replacing Patterns `replacePattern` on `Preprocessors` provides a general purpose mechanism for -replacing content in a request or response. Any occurrences of a regular expression are -replaced. +replacing content in a request or response. Any occurrences that match a regular +expression are replaced. [[customizing-requests-and-responses-preprocessors-modify-request-parameters]] -==== Modifying request parameters +==== Modifying Request Parameters -`modifyParameters` on `Preprocessors` can be used to add, set, and remove request +You can use `modifyParameters` on `Preprocessors` to add, set, and remove request parameters. @@ -143,23 +150,23 @@ parameters. [[customizing-requests-and-responses-preprocessors-modify-uris]] ==== Modifying URIs -TIP: If you are using MockMvc or a WebTestClient that is not bound to a server, -URIs should be customized by <>. +TIP: If you use MockMvc or a WebTestClient that is not bound to a server, +you should customize URIs by <>. -`modifyUris` on `Preprocessors` can be used to modify any URIs in a request +You can use `modifyUris` on `Preprocessors` to modify any URIs in a request or a response. When using REST Assured or WebTestClient bound to a server, this -allows you to customize the URIs that appear in the documentation while testing a +lets you customize the URIs that appear in the documentation while testing a local instance of the service. [[customizing-requests-and-responses-preprocessors-writing-your-own]] -==== Writing your own preprocessor +==== Writing Your Own Preprocessor If one of the built-in preprocessors does not meet your needs, you can write your own by implementing the `OperationPreprocessor` interface. You can then use your custom preprocessor in exactly the same way as any of the built-in preprocessors. -If you only want to modify the content (body) of a request or response, consider +If you want to modify only the content (body) of a request or response, consider implementing the `ContentModifier` interface and using it with the built-in `ContentModifyingOperationPreprocessor`. diff --git a/docs/src/docs/asciidoc/documenting-your-api.adoc b/docs/src/docs/asciidoc/documenting-your-api.adoc index 770af56df..71c12f5e4 100644 --- a/docs/src/docs/asciidoc/documenting-your-api.adoc +++ b/docs/src/docs/asciidoc/documenting-your-api.adoc @@ -9,8 +9,10 @@ This section provides more details about using Spring REST Docs to document your === Hypermedia Spring REST Docs provides support for documenting the links in a -https://en.wikipedia.org/wiki/HATEOAS[Hypermedia-based] API: +https://en.wikipedia.org/wiki/HATEOAS[hypermedia-based] API. +The following examples show how to use it: +==== [source,java,indent=0,role="primary"] .MockMvc ---- @@ -19,9 +21,9 @@ include::{examples-dir}/com/example/mockmvc/Hypermedia.java[tag=links] <1> Configure Spring REST docs to produce a snippet describing the response's links. Uses the static `links` method on `org.springframework.restdocs.hypermedia.HypermediaDocumentation`. -<2> Expect a link whose rel is `alpha`. Uses the static `linkWithRel` method on +<2> Expect a link whose `rel` is `alpha`. Uses the static `linkWithRel` method on `org.springframework.restdocs.hypermedia.HypermediaDocumentation`. -<3> Expect a link whose rel is `bravo`. +<3> Expect a link whose `rel` is `bravo`. [source,java,indent=0,role="secondary"] .WebTestClient @@ -31,9 +33,9 @@ include::{examples-dir}/com/example/webtestclient/Hypermedia.java[tag=links] <1> Configure Spring REST docs to produce a snippet describing the response's links. Uses the static `links` method on `org.springframework.restdocs.hypermedia.HypermediaDocumentation`. -<2> Expect a link whose rel is `alpha`. Uses the static `linkWithRel` method on +<2> Expect a link whose `rel` is `alpha`. Uses the static `linkWithRel` method on `org.springframework.restdocs.hypermedia.HypermediaDocumentation`. -<3> Expect a link whose rel is `bravo`. +<3> Expect a link whose `rel` is `bravo`. [source,java,indent=0,role="secondary"] .REST Assured @@ -43,25 +45,26 @@ include::{examples-dir}/com/example/restassured/Hypermedia.java[tag=links] <1> Configure Spring REST docs to produce a snippet describing the response's links. Uses the static `links` method on `org.springframework.restdocs.hypermedia.HypermediaDocumentation`. -<2> Expect a link whose rel is `alpha`. Uses the static `linkWithRel` method on +<2> Expect a link whose `rel` is `alpha`. Uses the static `linkWithRel` method on `org.springframework.restdocs.hypermedia.HypermediaDocumentation`. -<3> Expect a link whose rel is `bravo`. +<3> Expect a link whose `rel` is `bravo`. +==== The result is a snippet named `links.adoc` that contains a table describing the resource's links. -TIP: If a link in the response has a `title`, the description can be omitted from its -descriptor and the `title` will be used. If you omit the description and the link does -not have a `title` a failure will occur. +TIP: If a link in the response has a `title`, you can omit the description from its +descriptor and the `title` is used. If you omit the description and the link does +not have a `title`, a failure occurs. -When documenting links, the test will fail if an undocumented link is found in the -response. Similarly, the test will also fail if a documented link is not found in the +When documenting links, the test fails if an undocumented link is found in the +response. Similarly, the test also fails if a documented link is not found in the response and the link has not been marked as optional. -If you do not want to document a link, you can mark it as ignored. This will prevent it +If you do not want to document a link, you can mark it as ignored. Doing so prevents it from appearing in the generated snippet while avoiding the failure described above. -Links can also be documented in a relaxed mode where any undocumented links will not cause +You can also document links in a relaxed mode, where any undocumented links do not cause a test failure. To do so, use the `relaxedLinks` method on `org.springframework.restdocs.hypermedia.HypermediaDocumentation`. This can be useful when documenting a particular scenario where you only want to focus on a subset of the links. @@ -69,18 +72,20 @@ documenting a particular scenario where you only want to focus on a subset of th [[documenting-your-api-hypermedia-link-formats]] -==== Hypermedia link formats +==== Hypermedia Link Formats Two link formats are understood by default: - * Atom – links are expected to be in an array named `links`. Used by default when the - content type of the response is compatible with `application/json`. - * HAL – links are expected to be in a map named `_links`. Used by default when the - content type of the response is compatible with `application/hal+json`. +* Atom: Links are expected to be in an array named `links`. This is used by default when + the content type of the response is compatible with `application/json`. +* HAL: Links are expected to be in a map named `_links`. This is used by default when the + content type of the response is compatible with `application/hal+json`. -If you are using Atom or HAL-format links but with a different content type you can -provide one of the built-in `LinkExtractor` implementations to `links`. For example: +If you use Atom- or HAL-format links but with a different content type, you can provide +one of the built-in `LinkExtractor` implementations to `links`. The following examples +show how to do so: +==== [source,java,indent=0,role="primary"] .MockMvc ---- @@ -104,6 +109,7 @@ include::{examples-dir}/com/example/restassured/Hypermedia.java[tag=explicit-ext ---- <1> Indicate that the links are in HAL format. Uses the static `halLinks` method on `org.springframework.restdocs.hypermedia.HypermediaDocumentation`. +==== If your API represents its links in a format other than Atom or HAL, you can provide your own implementation of the `LinkExtractor` interface to extract the links from the @@ -112,42 +118,46 @@ response. [[documenting-your-api-hypermedia-ignoring-common-links]] -==== Ignoring common links +==== Ignoring Common Links Rather than documenting links that are common to every response, such as `self` and `curies` when using HAL, you may want to document them once in an overview section and then ignore them in the rest of your API's documentation. To do so, you can build on the <> to add link -descriptors to a snippet that's preconfigured to ignore certain links. For example: +descriptors to a snippet that is preconfigured to ignore certain links. The following +example shows how to do so: +==== [source,java,indent=0] ---- include::{examples-dir}/com/example/Hypermedia.java[tags=ignore-links] ---- +==== [[documenting-your-api-request-response-payloads]] -=== Request and response payloads +=== Request and Response Payloads In addition to the hypermedia-specific support <>, support for general documentation of request and response payloads is also +earlier>>, support for general documentation of request and response payloads is also provided. -By default, Spring REST Docs will automatically generate snippets for the body of the -request and the body of the response. These snippets are named `request-body.adoc` and +By default, Spring REST Docs automatically generates snippets for the body of the request +and the body of the response. These snippets are named `request-body.adoc` and `response-body.adoc` respectively. [[documenting-your-api-request-response-payloads-fields]] -==== Request and response fields +==== Request and Response Fields To provide more detailed documentation of a request or response payload, support for documenting the payload's fields is provided. Consider the following payload: +==== [source,json,indent=0] ---- { @@ -157,17 +167,19 @@ Consider the following payload: } } ---- +==== -Its fields can be documented like this: +You can document the previous example's fields as follows: +==== [source,java,indent=0,role="primary"] .MockMvc ---- include::{examples-dir}/com/example/mockmvc/Payload.java[tags=response] ---- <1> Configure Spring REST docs to produce a snippet describing the fields in the response - payload. To document a request `requestFields` can be used. Both are static methods on - `org.springframework.restdocs.payload.PayloadDocumentation`. + payload. To document a request, you can use `requestFields`. Both are static methods + on `org.springframework.restdocs.payload.PayloadDocumentation`. <2> Expect a field with the path `contact.email`. Uses the static `fieldWithPath` method on `org.springframework.restdocs.payload.PayloadDocumentation`. <3> Expect a field with the path `contact.name`. @@ -178,8 +190,8 @@ include::{examples-dir}/com/example/mockmvc/Payload.java[tags=response] include::{examples-dir}/com/example/webtestclient/Payload.java[tags=response] ---- <1> Configure Spring REST docs to produce a snippet describing the fields in the response - payload. To document a request `requestFields` can be used. Both are static methods on - `org.springframework.restdocs.payload.PayloadDocumentation`. + payload. To document a request, you can use `requestFields`. Both are static methods + on `org.springframework.restdocs.payload.PayloadDocumentation`. <2> Expect a field with the path `contact.email`. Uses the static `fieldWithPath` method on `org.springframework.restdocs.payload.PayloadDocumentation`. <3> Expect a field with the path `contact.name`. @@ -190,23 +202,25 @@ include::{examples-dir}/com/example/webtestclient/Payload.java[tags=response] include::{examples-dir}/com/example/restassured/Payload.java[tags=response] ---- <1> Configure Spring REST docs to produce a snippet describing the fields in the response - payload. To document a request `requestFields` can be used. Both are static methods on - `org.springframework.restdocs.payload.PayloadDocumentation`. -<2> Expect a field with the path `contact.email`. Uses the static `fieldWithPath` method on - `org.springframework.restdocs.payload.PayloadDocumentation`. + payload. To document a request, you can use `requestFields`. Both are static methods + on `org.springframework.restdocs.payload.PayloadDocumentation`. +<2> Expect a field with the path `contact.email`. Uses the static `fieldWithPath` method + on `org.springframework.restdocs.payload.PayloadDocumentation`. <3> Expect a field with the path `contact.name`. +==== -The result is a snippet that contains a table describing the fields. For requests this -snippet is named `request-fields.adoc`. For responses this snippet is named +The result is a snippet that contains a table describing the fields. For requests, this +snippet is named `request-fields.adoc`. For responses, this snippet is named `response-fields.adoc`. -When documenting fields, the test will fail if an undocumented field is found in the -payload. Similarly, the test will also fail if a documented field is not found in the -payload and the field has not been marked as optional. +When documenting fields, the test fails if an undocumented field is found in the payload. +Similarly, the test also fails if a documented field is not found in the payload and the +field has not been marked as optional. -If you don't want to provide detailed documentation for all of the fields, an entire -subsection of a payload can be documented. For example: +If you do not want to provide detailed documentation for all of the fields, an entire +subsection of a payload can be documented. The following examples show how to do so: +==== [source,java,indent=0,role="primary"] .MockMvc ---- @@ -233,40 +247,44 @@ include::{examples-dir}/com/example/restassured/Payload.java[tags=subsection] <1> Document the subsection with the path `contact`. `contact.email` and `contact.name` are now seen as having also been documented. Uses the static `subsectionWithPath` method on `org.springframework.restdocs.payload.PayloadDocumentation`. +==== `subsectionWithPath` can be useful for providing a high-level overview of a particular -section of a payload. Separate, more detailed documentation for a subsection can then -<>. +section of a payload. You can then produce separate, more detailed documentation for a +subsection. See <>. If you do not want to document a field or subsection at all, you can mark it as ignored. -This will prevent it from appearing in the generated snippet while avoiding the failure -described above. +This prevents it from appearing in the generated snippet while avoiding the failure +described earlier. -Fields can also be documented in a relaxed mode where any undocumented fields will not +You can also document fields in a relaxed mode, where any undocumented fields do not cause a test failure. To do so, use the `relaxedRequestFields` and `relaxedResponseFields` methods on `org.springframework.restdocs.payload.PayloadDocumentation`. This can be useful when -documenting a particular scenario where you only want to focus on a subset of the payload. +documenting a particular scenario where you want to focus only on a subset of the payload. -TIP: By default, Spring REST Docs will assume that the payload you are documenting is -JSON. If you want to document an XML payload the content type of the request or response -must be compatible with `application/xml`. +TIP: By default, Spring REST Docs assumes that the payload you are documenting is JSON. +If you want to document an XML payload, the content type of the request or response must +be compatible with `application/xml`. [[documenting-your-api-request-response-payloads-fields-json]] -===== Fields in JSON payloads +===== Fields in JSON Payloads + +This section descries how to work with fields in JSON payloads. [[documenting-your-api-request-response-payloads-fields-json-field-paths]] -====== JSON field paths +====== JSON Field Paths JSON field paths use either dot notation or bracket notation. Dot notation uses '.' to -separate each key in the path; `a.b`, for example. Bracket notation wraps each key in -square brackets and single quotes; `['a']['b']`, for example. In either case, `[]` is used -to identify an array. Dot notation is more concise, but using bracket notation enables the -use of `.` within a key name; `['a.b']`, for example. The two different notations can be -used in the same path; `a['b']`, for example. +separate each key in the path (for example, `a.b`). Bracket notation wraps each key in +square brackets and single quotation marks (for example, `['a']['b']`). In either case, +`[]` is used to identify an array. Dot notation is more concise, but using bracket +notation enables the use of `.` within a key name (for example, `['a.b']`). The two +different notations can be used in the same path (for example, `a['b']`). -With this JSON payload: +Consider the following JSON payload: +==== [source,json,indent=0] ---- { @@ -286,8 +304,9 @@ With this JSON payload: } } ---- +==== -The following paths are all present: +In the preceding JSON payload, the following paths are all present: [cols="1,3"] |=== @@ -325,11 +344,12 @@ The following paths are all present: |=== -A payload that uses an array at its root can also be documented. The path `[]` will refer +You can also document a payload that uses an array at its root. The path `[]` refers to the entire array. You can then use bracket or dot notation to identify fields within the array's entries. For example, `[].id` corresponds to the `id` field of every object found in the following array: +==== [source,json,indent=0] ---- [ @@ -341,10 +361,12 @@ found in the following array: } ] ---- +==== You can use `\*` as a wildcard to match fields with different names. For example, `users.*.role` could be used to document the role of every user in the following JSON: +==== [source,json,indent=0] ---- { @@ -358,44 +380,46 @@ You can use `\*` as a wildcard to match fields with different names. For example } } ---- +==== [[documenting-your-api-request-response-payloads-fields-json-field-types]] -====== JSON field types +====== JSON Field Types -When a field is documented, Spring REST Docs will attempt to determine its type by -examining the payload. Seven different types are supported: +When a field is documented, Spring REST Docs tries to determine its type by examining the +payload. Seven different types are supported: [cols="1,3"] |=== | Type | Description -| array -| The value of each occurrence of the field is an array +| `array` +| The value of each occurrence of the field is an array. -| boolean -| The value of each occurrence of the field is a boolean (`true` or `false`) +| `boolean` +| The value of each occurrence of the field is a boolean (`true` or `false`). -| object -| The value of each occurrence of the field is an object +| `object` +| The value of each occurrence of the field is an object. -| number -| The value of each occurrence of the field is a number +| `number` +| The value of each occurrence of the field is a number. -| null -| The value of each occurrence of the field is `null` +| `null` +| The value of each occurrence of the field is `null`. -| string -| The value of each occurrence of the field is a string +| `string` +| The value of each occurrence of the field is a string. -| varies -| The field occurs multiple times in the payload with a variety of different types +| `varies` +| The field occurs multiple times in the payload with a variety of different types. |=== -The type can also be set explicitly using the `type(Object)` method on -`FieldDescriptor`. The result of the supplied ``Object``'s `toString` method will be used -in the documentation. Typically, one of the values enumerated by `JsonFieldType` will be -used: +You can also explicitly set the type by using the `type(Object)` method on +`FieldDescriptor`. The result of the `toString` method of the supplied `Object` is used +in the documentation. Typically, one of the values enumerated by `JsonFieldType` is used. +The following examples show how to do so: +==== [source,java,indent=0,role="primary"] .MockMvc ---- @@ -416,37 +440,41 @@ include::{examples-dir}/com/example/webtestclient/Payload.java[tags=explicit-typ include::{examples-dir}/com/example/restassured/Payload.java[tags=explicit-type] ---- <1> Set the field's type to `String`. +==== [[documenting-your-api-request-response-payloads-fields-xml]] ===== XML payloads +This section describes how to work with XML payloads. + [[documenting-your-api-request-response-payloads-fields-xml-field-paths]] -====== XML field paths +====== XML Field Paths XML field paths are described using XPath. `/` is used to descend into a child node. [[documenting-your-api-request-response-payloads-fields-xml-field-types]] -====== XML field types +====== XML Field Types -When documenting an XML payload, you must provide a type for the field using the +When documenting an XML payload, you must provide a type for the field by using the `type(Object)` method on `FieldDescriptor`. The result of the supplied type's `toString` -method will be used in the documentation. +method is used in the documentation. [[documenting-your-api-request-response-payloads-fields-reusing-field-descriptors]] -===== Reusing field descriptors +===== Reusing Field Descriptors In addition to the general support for <>, the request and response snippets allow additional descriptors to be -configured with a path prefix. This allows the descriptors for a repeated portion of a -request or response payload to be created once and then reused. +snippets>>, the request and response snippets let additional descriptors be configured +with a path prefix. This lets the descriptors for a repeated portion of a request or +response payload be created once and then reused. Consider an endpoint that returns a book: +==== [source,json,indent=0] ---- { @@ -454,11 +482,13 @@ Consider an endpoint that returns a book: "author": "Jane Austen" } ---- +==== -The paths for `title` and `author` are simply `title` and `author` respectively. +The paths for `title` and `author` are `title` and `author`, respectively. Now consider an endpoint that returns an array of books: +==== [source,json,indent=0] ---- [{ @@ -470,79 +500,90 @@ Now consider an endpoint that returns an array of books: "author": "Harper Lee" }] ---- +==== -The paths for `title` and `author` are `[].title` and `[].author` respectively. The only +The paths for `title` and `author` are `[].title` and `[].author`, respectively. The only difference between the single book and the array of books is that the fields' paths now have a `[].` prefix. -The descriptors that document a book can be created: +You can create the descriptors that document a book as follows: +==== [source,java,indent=0] ---- include::{examples-dir}/com/example/Payload.java[tags=book-descriptors] ---- +==== -They can then be used to document a single book: +You can then use them to document a single book, as follows: +==== [source,java,indent=0,role="primary"] .MockMvc ---- include::{examples-dir}/com/example/mockmvc/Payload.java[tags=single-book] ---- -<1> Document `title` and `author` using existing descriptors +<1> Document `title` and `author` by using existing descriptors [source,java,indent=0,role="secondary"] .WebTestClient ---- include::{examples-dir}/com/example/webtestclient/Payload.java[tags=single-book] ---- -<1> Document `title` and `author` using existing descriptors +<1> Document `title` and `author` by using existing descriptors [source,java,indent=0,role="secondary"] .REST Assured ---- include::{examples-dir}/com/example/restassured/Payload.java[tags=single-book] ---- -<1> Document `title` and `author` using existing descriptors +<1> Document `title` and `author` by using existing descriptors +==== -And an array of books: +You can also use the descriptors to document an array of books, as follows: +==== [source,java,indent=0,role="primary"] .MockMvc ---- include::{examples-dir}/com/example/mockmvc/Payload.java[tags=book-array] ---- -<1> Document the array -<2> Document `[].title` and `[].author` using the existing descriptors prefixed with `[].` +<1> Document the array. +<2> Document `[].title` and `[].author` by using the existing descriptors prefixed with + `[].` [source,java,indent=0,role="secondary"] .WebTestClient ---- include::{examples-dir}/com/example/webtestclient/Payload.java[tags=book-array] ---- -<1> Document the array -<2> Document `[].title` and `[].author` using the existing descriptors prefixed with `[].` +<1> Document the array. +<2> Document `[].title` and `[].author` by using the existing descriptors prefixed with + `[].` [source,java,indent=0,role="secondary"] .REST Assured ---- include::{examples-dir}/com/example/restassured/Payload.java[tags=book-array] ---- -<1> Document the array -<2> Document `[].title` and `[].author` using the existing descriptors prefixed with `[].` +<1> Document the array. +<2> Document `[].title` and `[].author` by using the existing descriptors prefixed with + `[].` +==== [[documenting-your-api-request-response-payloads-subsections]] -==== Documenting a subsection of a request or response payload +==== Documenting a Subsection of a Request or Response Payload -If a payload is large or structurally complex, it can be useful to document -individual sections of the payload. REST Docs allows you to do so by extracting a -subsection of the payload and then documenting it. +If a payload is large or structurally complex, it can be useful to document individual +sections of the payload. REST Docs let you do so by extracting a subsection of the +payload and then documenting it. [[documenting-your-api-request-response-payloads-subsections-body]] -===== Documenting a subsection of a request or response body +===== Documenting a Subsection of a Request or Response Body Consider the following JSON response body: +==== [source,json,indent=0] ---- { @@ -558,9 +599,11 @@ Consider the following JSON response body: } } ---- +==== -A snippet that documents the `temperature` object can be produces as follows: +You can produce a snippet that documents the `temperature` object as follows: +==== [source,java,indent=0,role="primary"] .MockMvc ---- @@ -568,8 +611,8 @@ include::{examples-dir}/com/example/mockmvc/Payload.java[tags=body-subsection] ---- <1> Produce a snippet containing a subsection of the response body. Uses the static `responseBody` and `beneathPath` methods on - `org.springframework.restdocs.payload.PayloadDocumentation`. To produce a snippet - for the request body, `requestBody` can be used in place of `responseBody`. + `org.springframework.restdocs.payload.PayloadDocumentation`. To produce a snippet for + the request body, you can use `requestBody` in place of `responseBody`. [source,java,indent=0,role="secondary"] .WebTestClient @@ -578,8 +621,8 @@ include::{examples-dir}/com/example/webtestclient/Payload.java[tags=body-subsect ---- <1> Produce a snippet containing a subsection of the response body. Uses the static `responseBody` and `beneathPath` methods on - `org.springframework.restdocs.payload.PayloadDocumentation`. To produce a snippet - for the request body, `requestBody` can be used in place of `responseBody`. + `org.springframework.restdocs.payload.PayloadDocumentation`. To produce a snippet for + the request body, you can use `requestBody` in place of `responseBody`. [source,java,indent=0,role="secondary"] .REST Assured @@ -588,11 +631,13 @@ include::{examples-dir}/com/example/restassured/Payload.java[tags=body-subsectio ---- <1> Produce a snippet containing a subsection of the response body. Uses the static `responseBody` and `beneathPath` methods on - `org.springframework.restdocs.payload.PayloadDocumentation`. To produce a snippet - for the request body, `requestBody` can be used in place of `responseBody`. + `org.springframework.restdocs.payload.PayloadDocumentation`. To produce a snippet for + the request body, you can use `requestBody` in place of `responseBody`. +==== The result is a snippet with the following contents: +==== [source,json,indent=0] ---- { @@ -602,28 +647,32 @@ The result is a snippet with the following contents: } } ---- +==== To make the snippet's name distinct, an identifier for the subsection is included. By -default, this identifier is `beneath-${path}`. For example, the code above will result in -a snippet named `response-body-beneath-weather.temperature.adoc`. The identifier can -be customized using the `withSubsectionId(String)` method: +default, this identifier is `beneath-${path}`. For example, the preceding code results in +a snippet named `response-body-beneath-weather.temperature.adoc`. You can customized the +identifier by using the `withSubsectionId(String)` method, as follows: +==== [source,java,indent=0] ---- include::{examples-dir}/com/example/Payload.java[tags=custom-subsection-id] ---- +==== -This example will result in a snippet named `request-body-temp.adoc`. +The result is a snippet named `request-body-temp.adoc`. [[documenting-your-api-request-response-payloads-subsections-fields]] -===== Documenting the fields of a subsection of a request or response +===== Documenting the Fields of a Subsection of a Request or Response -As well as documenting a subsection of a request or response body, it's also possible to -document the fields in a particular subsection. A snippet that documents the fields of -the `temperature` object (`high` and `low`) can be produced as follows: +As well as documenting a subsection of a request or response body, you can also document +the fields in a particular subsection. You can produce a snippet that documents the +fields of the `temperature` object (`high` and `low`) as follows: +==== [source,java,indent=0,role="primary"] .MockMvc ---- @@ -653,27 +702,30 @@ include::{examples-dir}/com/example/restassured/Payload.java[tags=fields-subsect beneath the path `weather.temperature`. Uses the static `beneathPath` method on `org.springframework.restdocs.payload.PayloadDocumentation`. <2> Document the `high` and `low` fields. +==== -The result is a snippet that contains a table describing the `high` and `low` fields -of `weather.temperature`. To make the snippet's name distinct, an identifier for the -subsection is included. By default, this identifier is `beneath-${path}`. For -example, the code above will result in a snippet named +The result is a snippet that contains a table describing the `high` and `low` fields of +`weather.temperature`. To make the snippet's name distinct, an identifier for the +subsection is included. By default, this identifier is `beneath-${path}`. For example, +the preceding code results in a snippet named `response-fields-beneath-weather.temperature.adoc`. [[documenting-your-api-request-parameters]] -=== Request parameters +=== Request Parameters -A request's parameters can be documented using `requestParameters`. Request parameters -can be included in a `GET` request's query string. For example: +You can document a request's parameters by using `requestParameters`. You can include +request parameters in a `GET` request's query string. The following examples show how to +do so: +==== [source,java,indent=0,role="primary"] .MockMvc ---- include::{examples-dir}/com/example/mockmvc/RequestParameters.java[tags=request-parameters-query-string] ---- -<1> Perform a `GET` request with two parameters, `page` and `per_page` in the query +<1> Perform a `GET` request with two parameters, `page` and `per_page`, in the query string. <2> Configure Spring REST Docs to produce a snippet describing the request's parameters. Uses the static `requestParameters` method on @@ -687,7 +739,7 @@ include::{examples-dir}/com/example/mockmvc/RequestParameters.java[tags=request- ---- include::{examples-dir}/com/example/webtestclient/RequestParameters.java[tags=request-parameters-query-string] ---- -<1> Perform a `GET` request with two parameters, `page` and `per_page` in the query +<1> Perform a `GET` request with two parameters, `page` and `per_page`, in the query string. <2> Configure Spring REST Docs to produce a snippet describing the request's parameters. Uses the static `requestParameters` method on @@ -707,11 +759,14 @@ include::{examples-dir}/com/example/restassured/RequestParameters.java[tags=requ <2> Document the `page` parameter. Uses the static `parameterWithName` method on `org.springframework.restdocs.request.RequestDocumentation`. <3> Document the `per_page` parameter. -<4> Perform a `GET` request with two parameters, `page` and `per_page` in the query +<4> Perform a `GET` request with two parameters, `page` and `per_page`, in the query string. +==== -Request parameters can also be included as form data in the body of a POST request: +You can also include request parameters as form data in the body of a POST request. The +following examples show how to do so: +==== [source,java,indent=0,role="primary"] .MockMvc ---- @@ -733,21 +788,21 @@ include::{examples-dir}/com/example/restassured/RequestParameters.java[tags=requ ---- <1> Configure the `username` parameter. <2> Perform the `POST` request. +==== -In both cases, the result is a snippet named `request-parameters.adoc` that contains a +In all cases, the result is a snippet named `request-parameters.adoc` that contains a table describing the parameters that are supported by the resource. -When documenting request parameters, the test will fail if an undocumented request -parameter is used in the request. Similarly, the test will also fail if a documented -request parameter is not found in the request and the request parameter has not been -marked as optional. +When documenting request parameters, the test fails if an undocumented request parameter +is used in the request. Similarly, the test also fails if a documented request parameter +is not found in the request and the request parameter has not been marked as optional. -If you do not want to document a request parameter, you can mark it as ignored. This will -prevent it from appearing in the generated snippet while avoiding the failure described +If you do not want to document a request parameter, you can mark it as ignored. This +prevents it from appearing in the generated snippet while avoiding the failure described above. -Request parameters can also be documented in a relaxed mode where any undocumented -parameters will not cause a test failure. To do so, use the `relaxedRequestParameters` +You can also document request parameters in a relaxed mode where any undocumented +parameters do not cause a test failure. To do so, use the `relaxedRequestParameters` method on `org.springframework.restdocs.request.RequestDocumentation`. This can be useful when documenting a particular scenario where you only want to focus on a subset of the request parameters. @@ -755,10 +810,12 @@ request parameters. [[documenting-your-api-path-parameters]] -=== Path parameters +=== Path Parameters -A request's path parameters can be documented using `pathParameters`. For example: +You can document a request's path parameters by using `pathParameters`. The following +examples show how to do so: +==== [source,java,indent=0,role="primary"] .MockMvc ---- @@ -797,35 +854,38 @@ include::{examples-dir}/com/example/restassured/PathParameters.java[tags=path-pa `org.springframework.restdocs.request.RequestDocumentation`. <3> Document the parameter named `longitude`. <4> Perform a `GET` request with two path parameters, `latitude` and `longitude`. +==== The result is a snippet named `path-parameters.adoc` that contains a table describing the path parameters that are supported by the resource. -TIP: If you are using MockMvc then, to make the path parameters available for documentation, -the request must be built using one of the methods on `RestDocumentationRequestBuilders` -rather than `MockMvcRequestBuilders`. +TIP: If you use MockMvc, to make the path parameters available for documentation, +you must build the request by using one of the methods on +`RestDocumentationRequestBuilders` rather than `MockMvcRequestBuilders`. -When documenting path parameters, the test will fail if an undocumented path parameter -is used in the request. Similarly, the test will also fail if a documented path parameter -is not found in the request and the path parameter has not been marked as optional. +When documenting path parameters, the test fails if an undocumented path parameter is +used in the request. Similarly, the test also fails if a documented path parameter is not +found in the request and the path parameter has not been marked as optional. -Path parameters can also be documented in a relaxed mode where any undocumented -parameters will not cause a test failure. To do so, use the `relaxedPathParameters` -method on `org.springframework.restdocs.request.RequestDocumentation`. This can be useful -when documenting a particular scenario where you only want to focus on a subset of the -path parameters. +You can also document path parameters in a relaxed mode, where any undocumented +parameters do not cause a test failure. To do so, use the `relaxedPathParameters` method +on `org.springframework.restdocs.request.RequestDocumentation`. This can be useful when +documenting a particular scenario where you only want to focus on a subset of the path +parameters. -If you do not want to document a path parameter, you can mark it as ignored. This will -prevent it from appearing in the generated snippet while avoiding the failure described -above. +If you do not want to document a path parameter, you can mark it as ignored. Doing so +prevents it from appearing in the generated snippet while avoiding the failure described +earlier. [[documenting-your-api-request-parts]] -=== Request parts +=== Request Parts -The parts of a multipart request can be documenting using `requestParts`. For example: +You can use `requestParts` to document the parts of a multipart request. The following +example shows how to do so: +==== [source,java,indent=0,role="primary"] .MockMvc ---- @@ -862,58 +922,57 @@ include::{examples-dir}/com/example/restassured/RequestParts.java[tags=request-p `org.springframework.restdocs.request.RequestDocumentation`. <3> Configure the request with the part named `file`. <4> Perform the `POST` request to `/upload`. +==== The result is a snippet named `request-parts.adoc` that contains a table describing the request parts that are supported by the resource. -When documenting request parts, the test will fail if an undocumented part is used in the -request. Similarly, the test will also fail if a documented part is not found in the -request and the part has not been marked as optional. +When documenting request parts, the test fails if an undocumented part is used in the +request. Similarly, the test also fails if a documented part is not found in the request +and the part has not been marked as optional. -Request parts can also be documented in a relaxed mode where any undocumented -parts will not cause a test failure. To do so, use the `relaxedRequestParts` method on +You can also document request parts in a relaxed mode where any undocumented parts do not +cause a test failure. To do so, use the `relaxedRequestParts` method on `org.springframework.restdocs.request.RequestDocumentation`. This can be useful when documenting a particular scenario where you only want to focus on a subset of the request parts. -If you do not want to document a request part, you can mark it as ignored. This will -prevent it from appearing in the generated snippet while avoiding the failure described -above. +If you do not want to document a request part, you can mark it as ignored. This prevents +it from appearing in the generated snippet while avoiding the failure described earlier. [[documenting-your-api-request-parts-payloads]] -=== Request part payloads +=== Request Part Payloads -The payload of a request part can be documented in much the same way as the -<> with support +You can document the payload of a request part in much the same way as the +<>, with support for documenting a request part's body and its fields. [[documenting-your-api-request-parts-payloads-body]] -==== Documenting a request part's body +==== Documenting a Request Part's Body -A snippet containing the body of a request part can be generated: +You can generate a snippet containing the body of a request part as follows: +==== [source,java,indent=0,role="primary"] .MockMvc ---- include::{examples-dir}/com/example/mockmvc/RequestPartPayload.java[tags=body] ---- -<1> Configure Spring REST docs to produce a snippet containing the body of the - of the request part named `metadata`. Uses the static `requestPartBody` method on +<1> Configure Spring REST docs to produce a snippet containing the body of the request + part named `metadata`. Uses the static `requestPartBody` method on `PayloadDocumentation`. - payload. [source,java,indent=0,role="secondary"] .WebTestClient ---- include::{examples-dir}/com/example/webtestclient/RequestPartPayload.java[tags=body] ---- -<1> Configure Spring REST docs to produce a snippet containing the body of the - of the request part named `metadata`. Uses the static `requestPartBody` method on +<1> Configure Spring REST docs to produce a snippet containing the body of the request + part named `metadata`. Uses the static `requestPartBody` method on `PayloadDocumentation`. - payload. [source,java,indent=0,role="secondary"] .REST Assured @@ -923,19 +982,21 @@ include::{examples-dir}/com/example/restassured/RequestPartPayload.java[tags=bod <1> Configure Spring REST docs to produce a snippet containing the body of the request part named `metadata`. Uses the static `requestPartBody` method on `PayloadDocumentation`. +==== -The result is a snippet `request-part-${part-name}-body.adoc` that contains the part's -body. For example, documenting a part named `metadata` will produce a snippet named +The result is a snippet named `request-part-${part-name}-body.adoc` that contains the +part's body. For example, documenting a part named `metadata` produces a snippet named `request-part-metadata-body.adoc`. [[documenting-your-api-request-parts-payloads-fields]] -==== Documenting a request part's fields +==== Documenting a Request Part's Fields -A request part's fields can be documented in much the same way as the fields of a request -or response: +You can document a request part's fields in much the same way as the fields of a request +or response, as follows: +==== [source,java,indent=0,role="primary"] .MockMvc ---- @@ -944,7 +1005,6 @@ include::{examples-dir}/com/example/mockmvc/RequestPartPayload.java[tags=fields] <1> Configure Spring REST docs to produce a snippet describing the fields in the payload of the request part named `metadata`. Uses the static `requestPartFields` method on `PayloadDocumentation`. - payload. <2> Expect a field with the path `version`. Uses the static `fieldWithPath` method on `org.springframework.restdocs.payload.PayloadDocumentation`. @@ -956,7 +1016,6 @@ include::{examples-dir}/com/example/webtestclient/RequestPartPayload.java[tags=f <1> Configure Spring REST docs to produce a snippet describing the fields in the payload of the request part named `metadata`. Uses the static `requestPartFields` method on `PayloadDocumentation`. - payload. <2> Expect a field with the path `version`. Uses the static `fieldWithPath` method on `org.springframework.restdocs.payload.PayloadDocumentation`. @@ -970,43 +1029,44 @@ include::{examples-dir}/com/example/restassured/RequestPartPayload.java[tags=fie `PayloadDocumentation`. <2> Expect a field with the path `version`. Uses the static `fieldWithPath` method on `org.springframework.restdocs.payload.PayloadDocumentation`. +==== The result is a snippet that contains a table describing the part's fields. This snippet is named `request-part-${part-name}-fields.adoc`. For example, documenting a part named -`metadata` will produce a snippet named `request-part-metadata-fields.adoc`. +`metadata` produces a snippet named `request-part-metadata-fields.adoc`. -When documenting fields, the test will fail if an undocumented field is found in the -payload of the part. Similarly, the test will also fail if a documented field is not found -in the payload of the part and the field has not been marked as optional. For payloads -with a hierarchical structure, documenting a field is sufficient for all of its -descendants to also be treated as having been documented. +When documenting fields, the test fails if an undocumented field is found in the payload +of the part. Similarly, the test also fails if a documented field is not found in the +payload of the part and the field has not been marked as optional. For payloads with a +hierarchical structure, documenting a field is sufficient for all of its descendants to +also be treated as having been documented. -If you do not want to document a field, you can mark it as ignored. This will prevent it +If you do not want to document a field, you can mark it as ignored. Doing so prevents it from appearing in the generated snippet while avoiding the failure described above. -Fields can also be documented in a relaxed mode where any undocumented fields will not +You can also document fields in a relaxed mode, where any undocumented fields do not cause a test failure. To do so, use the `relaxedRequestPartFields` method on `org.springframework.restdocs.payload.PayloadDocumentation`. This can be useful when documenting a particular scenario where you only want to focus on a subset of the payload of the part. -For further information on describing fields, documenting payloads that use XML, -and more please refer to the -<>. +For further information on describing fields, documenting payloads that use XML, and +more, see the <>. [[documenting-your-api-http-headers]] -=== HTTP headers +=== HTTP Headers -The headers in a request or response can be documented using `requestHeaders` and -`responseHeaders` respectively. For example: +You can document the headers in a request or response by using `requestHeaders` and +`responseHeaders`, respectively. The following examples show how to do so: +==== [source,java,indent=0,role="primary"] .MockMvc ---- include::{examples-dir}/com/example/mockmvc/HttpHeaders.java[tags=headers] ---- -<1> Perform a `GET` request with an `Authorization` header that uses basic authentication +<1> Perform a `GET` request with an `Authorization` header that uses basic authentication. <2> Configure Spring REST Docs to produce a snippet describing the request's headers. Uses the static `requestHeaders` method on `org.springframework.restdocs.headers.HeaderDocumentation`. @@ -1020,7 +1080,7 @@ include::{examples-dir}/com/example/mockmvc/HttpHeaders.java[tags=headers] ---- include::{examples-dir}/com/example/webtestclient/HttpHeaders.java[tags=headers] ---- -<1> Perform a `GET` request with an `Authorization` header that uses basic authentication +<1> Perform a `GET` request with an `Authorization` header that uses basic authentication. <2> Configure Spring REST Docs to produce a snippet describing the request's headers. Uses the static `requestHeaders` method on `org.springframework.restdocs.headers.HeaderDocumentation`. @@ -1041,39 +1101,44 @@ include::{examples-dir}/com/example/restassured/HttpHeaders.java[tags=headers] `org.springframework.restdocs.headers.HeaderDocumentation. <3> Produce a snippet describing the response's headers. Uses the static `responseHeaders` method on `org.springframework.restdocs.headers.HeaderDocumentation`. -<4> Configure the request with an `Authorization` header that uses basic authentication +<4> Configure the request with an `Authorization` header that uses basic authentication. +==== The result is a snippet named `request-headers.adoc` and a snippet named `response-headers.adoc`. Each contains a table describing the headers. -When documenting HTTP Headers, the test will fail if a documented header is not found in +When documenting HTTP Headers, the test fails if a documented header is not found in the request or response. [[documenting-your-api-reusing-snippets]] -=== Reusing snippets +=== Reusing Snippets -It's common for an API that's being documented to have some features that are common -across several of its resources. To avoid repetition when documenting such resources a -`Snippet` configured with the common elements can be reused. +It is common for an API that is being documented to have some features that are common +across several of its resources. To avoid repetition when documenting such resources, you +can reuse a `Snippet` configured with the common elements. -First, create the `Snippet` that describes the common elements. For example: +First, create the `Snippet` that describes the common elements. The following example +shows how to do so: +==== [source,java,indent=0] ---- include::{examples-dir}/com/example/SnippetReuse.java[tags=field] ---- +==== -Second, use this snippet and add further descriptors that are resource-specific. For -example: +Second, use this snippet and add further descriptors that are resource-specific. The +following examples show how to do so: +==== [source,java,indent=0,role="primary"] .MockMvc ---- include::{examples-dir}/com/example/mockmvc/MockMvcSnippetReuse.java[tags=use] ---- -<1> Reuse the `pagingLinks` `Snippet` calling `and` to add descriptors that are specific +<1> Reuse the `pagingLinks` `Snippet`, calling `and` to add descriptors that are specific to the resource that is being documented. [source,java,indent=0,role="secondary"] @@ -1081,7 +1146,7 @@ include::{examples-dir}/com/example/mockmvc/MockMvcSnippetReuse.java[tags=use] ---- include::{examples-dir}/com/example/webtestclient/WebTestClientSnippetReuse.java[tags=use] ---- -<1> Reuse the `pagingLinks` `Snippet` calling `and` to add descriptors that are specific +<1> Reuse the `pagingLinks` `Snippet`, calling `and` to add descriptors that are specific to the resource that is being documented. [source,java,indent=0,role="secondary"] @@ -1089,28 +1154,31 @@ include::{examples-dir}/com/example/webtestclient/WebTestClientSnippetReuse.java ---- include::{examples-dir}/com/example/restassured/RestAssuredSnippetReuse.java[tags=use] ---- -<1> Reuse the `pagingLinks` `Snippet` calling `and` to add descriptors that are specific +<1> Reuse the `pagingLinks` `Snippet`, calling `and` to add descriptors that are specific to the resource that is being documented. +==== -The result of the example is that links with the rels `first`, `last`, `next`, `previous`, -`alpha`, and `bravo` are all documented. +The result of the example is that links with `rel` values of `first`, `last`, `next`, +`previous`, `alpha`, and `bravo` are all documented. [[documenting-your-api-constraints]] -=== Documenting constraints +=== Documenting Constraints Spring REST Docs provides a number of classes that can help you to document constraints. -An instance of `ConstraintDescriptions` can be used to access descriptions of a class's -constraints. For example: +You can use an instance of `ConstraintDescriptions` to access descriptions of a class's +constraints. The following example shows how to do so: +==== [source,java,indent=0] ---- include::{examples-dir}/com/example/Constraints.java[tags=constraints] ---- -<1> Create an instance of `ConstraintDescriptions` for the `UserInput` class -<2> Get the descriptions of the name property's constraints. This list will contain two - descriptions; one for the `NotNull` constraint and one for the `Size` constraint. +<1> Create an instance of `ConstraintDescriptions` for the `UserInput` class. +<2> Get the descriptions of the `name` property's constraints. This list contains two + descriptions: one for the `NotNull` constraint and one for the `Size` constraint. +==== The {samples}/rest-notes-spring-hateoas/src/test/java/com/example/notes/ApiDocumentation.java[`ApiDocumentation`] class in the Spring HATEOAS sample shows this functionality in action. @@ -1118,88 +1186,88 @@ class in the Spring HATEOAS sample shows this functionality in action. [[documenting-your-api-constraints-finding]] -==== Finding constraints +==== Finding Constraints -By default, constraints are found using a Bean Validation `Validator`. Currently, only -property constraints are supported. You can customize the `Validator` that's used by +By default, constraints are found by using a Bean Validation `Validator`. Currently, only +property constraints are supported. You can customize the `Validator` that is used by creating `ConstraintDescriptions` with a custom `ValidatorConstraintResolver` instance. -To take complete control of constraint resolution, your own implementation of -`ConstraintResolver` can be used. +To take complete control of constraint resolution, you can use your own implementation of +`ConstraintResolver`. [[documenting-your-api-constraints-describing]] -==== Describing constraints +==== Describing Constraints Default descriptions are provided for all of Bean Validation 2.0's constraints: -* AssertFalse -* AssertTrue -* DecimalMax -* DecimalMin -* Digits -* Email -* Future -* FutureOrPresent -* Max -* Min -* Negative -* NegativeOrZero -* NotBlank -* NotEmpty -* NotNull -* Null -* Past -* PastOrPresent -* Pattern -* Positive -* PositiveOrZero -* Size +* `AssertFalse` +* `AssertTrue` +* `DecimalMax` +* `DecimalMin` +* `Digits` +* `Email` +* `Future` +* `FutureOrPresent` +* `Max` +* `Min` +* `Negative` +* `NegativeOrZero` +* `NotBlank` +* `NotEmpty` +* `NotNull` +* `Null` +* `Past` +* `PastOrPresent` +* `Pattern` +* `Positive` +* `PositiveOrZero` +* `Size` Default descriptions are also provided for the following constraints from Hibernate Validator: -* CodePointLength -* CreditCardNumber -* Currency -* EAN -* Email -* Length -* LuhnCheck -* Mod10Check -* Mod11Check -* NotBlank -* NotEmpty -* Currency -* Range -* SafeHtml -* URL - -To override the default descriptions, or to provide a new description, create a resource -bundle with the base name +* `CodePointLength` +* `CreditCardNumber` +* `Currency` +* `EAN` +* `Email` +* `Length` +* `LuhnCheck` +* `Mod10Check` +* `Mod11Check` +* `NotBlank` +* `NotEmpty` +* `Currency` +* `Range` +* `SafeHtml` +* `URL` + +To override the default descriptions or to provide a new description, you can create a +resource bundle with a base name of `org.springframework.restdocs.constraints.ConstraintDescriptions`. The Spring HATEOAS-based sample contains {samples}/rest-notes-spring-hateoas/src/test/resources/org/springframework/restdocs/constraints/ConstraintDescriptions.properties[an example of such a resource bundle]. -Each key in the resource bundle is the fully-qualified name of a constraint plus +Each key in the resource bundle is the fully-qualified name of a constraint plus a `.description`. For example, the key for the standard `@NotNull` constraint is `javax.validation.constraints.NotNull.description`. -Property placeholder's referring to a constraint's attributes can be used in its +You can use a property placeholder referring to a constraint's attributes in its description. For example, the default description of the `@Min` constraint, `Must be at least ${value}`, refers to the constraint's `value` attribute. -To take more control of constraint description resolution, create `ConstraintDescriptions` -with a custom `ResourceBundleConstraintDescriptionResolver`. To take complete control, -create `ConstraintDescriptions` with a custom `ConstraintDescriptionResolver` -implementation. +To take more control of constraint description resolution, you can create +`ConstraintDescriptions` with a custom `ResourceBundleConstraintDescriptionResolver`. To +take complete control, you can create `ConstraintDescriptions` with a custom +`ConstraintDescriptionResolver` implementation. -==== Using constraint descriptions in generated snippets +==== Using Constraint Descriptions in Generated Snippets -Once you have a constraint's descriptions, you're free to use them however you like in +Once you have a constraint's descriptions, you are free to use them however you like in the generated snippets. For example, you may want to include the constraint descriptions as part of a field's description. Alternatively, you could include the constraints as <> in @@ -1210,7 +1278,7 @@ class in the Spring HATEOAS-based sample illustrates the latter approach. [[documenting-your-api-default-snippets]] -=== Default snippets +=== Default Snippets A number of snippets are produced automatically when you document a request and response. @@ -1220,37 +1288,37 @@ A number of snippets are produced automatically when you document a request and | `curl-request.adoc` | Contains the http://curl.haxx.se[`curl`] command that is equivalent to the `MockMvc` -call that is being documented +call that is being documented. | `httpie-request.adoc` | Contains the http://httpie.org[`HTTPie`] command that is equivalent to the `MockMvc` -call that is being documented +call that is being documented. | `http-request.adoc` | Contains the HTTP request that is equivalent to the `MockMvc` call that is being -documented +documented. | `http-response.adoc` -| Contains the HTTP response that was returned +| Contains the HTTP response that was returned. | `request-body.adoc` -| Contains the body of the request that was sent +| Contains the body of the request that was sent. | `response-body.adoc` -| Contains the body of the response that was returned +| Contains the body of the response that was returned. |=== -You can configure which snippets are produced by default. Please refer to the +You can configure which snippets are produced by default. See the <> for more information. [[documentating-your-api-parameterized-output-directories]] -=== Using parameterized output directories +=== Using Parameterized Output Directories -When using MockMvc or REST Assured, the output directory used by `document` can be -parameterized. The output directory cannot be parameterized when using WebTestClient. +When using MockMvc or REST Assured, you can parameterize the output directory used by +`document`. You cannot parameterize the output directory when using `WebTestClient`. The following parameters are supported: @@ -1259,35 +1327,36 @@ The following parameters are supported: | Parameter | Description | {methodName} -| The unmodified name of the test method +| The unmodified name of the test method. | {method-name} -| The name of the test method, formatted using kebab-case +| The name of the test method, formatted using kebab-case. | {method_name} -| The name of the test method, formatted using snake_case +| The name of the test method, formatted using snake_case. | {ClassName} -| The unmodified simple name of the test class +| The unmodified simple name of the test class. | {class-name} -| The simple name of the test class, formatted using kebab-case +| The simple name of the test class, formatted using kebab-case. | {class_name} -| The simple name of the test class, formatted using snake_case +| The simple name of the test class, formatted using snake_case. | {step} -| The count of calls made to the service in the current test +| The count of calls made to the service in the current test. |=== For example, `document("{class-name}/{method-name}")` in a test method named -`creatingANote` on the test class `GettingStartedDocumentation`, will write +`creatingANote` on the test class `GettingStartedDocumentation` writes snippets into a directory named `getting-started-documentation/creating-a-note`. -A parameterized output directory is particularly useful in combination with an `@Before` -method. It allows documentation to be configured once in a setup method and then reused -in every test in the class: +A parameterized output directory is particularly useful in combination with a `@Before` +method. It lets documentation be configured once in a setup method and then reused +in every test in the class. The following examples show how to do so: +==== [source,java,indent=0,role="primary"] .MockMvc ---- @@ -1299,8 +1368,9 @@ include::{examples-dir}/com/example/mockmvc/ParameterizedOutput.java[tags=parame ---- include::{examples-dir}/com/example/restassured/ParameterizedOutput.java[tags=parameterized-output] ---- +==== -With this configuration in place, every call to the service you are testing will produce +With this configuration in place, every call to the service you are testing produces the <> without any further configuration. Take a look at the `GettingStartedDocumentation` classes in each of the sample applications to see this functionality in action. @@ -1308,12 +1378,12 @@ sample applications to see this functionality in action. [[documenting-your-api-customizing]] -=== Customizing the output - +=== Customizing the Output +This section describes how to customize the output of Spring REST Docs. [[documenting-your-api-customizing-snippets]] -==== Customizing the generated snippets +==== Customizing the Generated Snippets Spring REST Docs uses https://mustache.github.io[Mustache] templates to produce the generated snippets. {source}/spring-restdocs-core/src/main/resources/org/springframework/restdocs/templates[Default @@ -1322,63 +1392,67 @@ customize a snippet's content, you can provide your own template. Templates are loaded from the classpath from an `org.springframework.restdocs.templates` subpackage. The name of the subpackage is determined by the ID of the template format -that is in use. The default template format, Asciidoctor, has the ID `asciidoctor` so +that is in use. The default template format, Asciidoctor, has an ID of `asciidoctor`, so snippets are loaded from `org.springframework.restdocs.templates.asciidoctor`. Each -template is named after the snippet that it will produce. For example, to -override the template for the `curl-request.adoc` snippet, create a template named +template is named after the snippet that it produces. For example, to override the +template for the `curl-request.adoc` snippet, create a template named `curl-request.snippet` in `src/test/resources/org/springframework/restdocs/templates/asciidoctor`. [[documenting-your-api-customizing-including-extra-information]] -==== Including extra information +==== Including Extra Information There are two ways to provide extra information for inclusion in a generated snippet: -. Use the `attributes` method on a descriptor to add one or more attributes to it. -. Pass in some attributes when calling `curlRequest`, `httpRequest`, `httpResponse`, etc. - Such attributes will be associated with the snippet as a whole. +* Use the `attributes` method on a descriptor to add one or more attributes to it. +* Pass in some attributes when calling `curlRequest`, `httpRequest`, `httpResponse`, and + so on. Such attributes are associated with the snippet as a whole. Any additional attributes are made available during the template rendering process. Coupled with a custom snippet template, this makes it possible to include extra information in a generated snippet. -A concrete example of the above is the addition of a constraints column and a title when -documenting request fields. The first step is to provide a `constraints` attribute for -each field that you are documenting and to provide a `title` attribute: +A concrete example is the addition of a constraints column and a title when documenting +request fields. The first step is to provide a `constraints` attribute for each field +that you document and to provide a `title` attribute. The following examples show how to +do so: +==== [source,java,indent=0,role="primary"] .MockMvc ---- include::{examples-dir}/com/example/mockmvc/Payload.java[tags=constraints] ---- -<1> Configure the `title` attribute for the request fields snippet -<2> Set the `constraints` attribute for the `name` field -<3> Set the `constraints` attribute for the `email` field +<1> Configure the `title` attribute for the request fields snippet. +<2> Set the `constraints` attribute for the `name` field. +<3> Set the `constraints` attribute for the `email` field. [source,java,indent=0,role="secondary"] .WebTestClient ---- include::{examples-dir}/com/example/webtestclient/Payload.java[tags=constraints] ---- -<1> Configure the `title` attribute for the request fields snippet -<2> Set the `constraints` attribute for the `name` field -<3> Set the `constraints` attribute for the `email` field +<1> Configure the `title` attribute for the request fields snippet. +<2> Set the `constraints` attribute for the `name` field. +<3> Set the `constraints` attribute for the `email` field. [source,java,indent=0,role="secondary"] .REST Assured ---- include::{examples-dir}/com/example/restassured/Payload.java[tags=constraints] ---- -<1> Configure the `title` attribute for the request fields snippet -<2> Set the `constraints` attribute for the `name` field -<3> Set the `constraints` attribute for the `email` field +<1> Configure the `title` attribute for the request fields snippet. +<2> Set the `constraints` attribute for the `name` field. +<3> Set the `constraints` attribute for the `email` field. +==== The second step is to provide a custom template named `request-fields.snippet` that includes the information about the fields' constraints in the generated snippet's table -and adds a title: +and adds a title. The following example shows how to do so: +==== [source,indent=0] ---- .{{title}} <1> @@ -1394,7 +1468,7 @@ and adds a title: {{/fields}} |=== ---- -<1> Add a title to the table -<2> Add a new column named "Constraints" -<3> Include the descriptors' `constraints` attribute in each row of the table - +<1> Add a title to the table. +<2> Add a new column named "Constraints". +<3> Include the descriptors' `constraints` attribute in each row of the table. +==== diff --git a/docs/src/docs/asciidoc/getting-started.adoc b/docs/src/docs/asciidoc/getting-started.adoc index 66af165e0..ccb447963 100644 --- a/docs/src/docs/asciidoc/getting-started.adoc +++ b/docs/src/docs/asciidoc/getting-started.adoc @@ -6,11 +6,10 @@ This section describes how to get started with Spring REST Docs. [[getting-started-sample-applications]] -=== Sample applications +=== Sample Applications If you want to jump straight in, a number of sample applications are available: - [cols="3,2,10"] .MockMvc |=== @@ -19,12 +18,12 @@ If you want to jump straight in, a number of sample applications are available: | {samples}/rest-notes-spring-data-rest[Spring Data REST] | Maven | Demonstrates the creation of a getting started guide and an API guide for a service - implemented using http://projects.spring.io/spring-data-rest/[Spring Data REST]. + implemented by using http://projects.spring.io/spring-data-rest/[Spring Data REST]. | {samples}/rest-notes-spring-hateoas[Spring HATEOAS] | Gradle | Demonstrates the creation of a getting started guide and an API guide for a service - implemented using http://projects.spring.io/spring-hateoas/[Spring HATEOAS]. + implemented by using http://projects.spring.io/spring-hateoas/[Spring HATEOAS]. |=== @@ -82,13 +81,10 @@ If you want to jump straight in, a number of sample applications are available: Spring REST Docs has the following minimum requirements: -- Java 8 -- Spring Framework 5 (5.0.2 or later) - -Additionally, the `spring-restdocs-restassured` module has the following minimum -requirements: +* Java 8 +* Spring Framework 5 (5.0.2 or later) -- REST Assured 3.0 +Additionally, the `spring-restdocs-restassured` module requires REST Assured 3.0. [[getting-started-build-configuration]] === Build configuration @@ -96,9 +92,10 @@ requirements: The first step in using Spring REST Docs is to configure your project's build. The {samples}/rest-notes-spring-hateoas[Spring HATEOAS] and {samples}/rest-notes-spring-data-rest[Spring Data REST] samples contain a `build.gradle` -and `pom.xml` respectively that you may wish to use as a reference. The key parts of -the configuration are described below. +and `pom.xml`, respectively, that you may wish to use as a reference. The key parts of +the configuration are described in the following listings: +==== [source,xml,indent=0,subs="verbatim,attributes",role="primary"] .Maven ---- @@ -189,18 +186,21 @@ the configuration are described below. <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. - +==== [[getting-started-build-configuration-packaging-the-documentation]] -==== Packaging the documentation +==== Packaging the Documentation -You may want to package the generated documentation in your project's jar file, for -example to have it {spring-boot-docs}/#boot-features-spring-mvc-static-content[served as +You may want to package the generated documentation in your project's jar file -- for +example, to have it {spring-boot-docs}/#boot-features-spring-mvc-static-content[served as static content] by Spring Boot. To do so, configure your project's build so that: 1. The documentation is generated before the jar is built 2. The generated documentation is included in the jar +The following listings show how to do so in both Maven and Gradle: + +==== [source,xml,indent=0,role="primary"] .Maven ---- @@ -254,14 +254,15 @@ from where it will be included in the jar file. ---- <1> Ensure that the documentation has been generated before the jar is built. <2> Copy the generated documentation into the jar's `static/docs` directory. +==== [[getting-started-documentation-snippets]] -=== Generating documentation snippets +=== Generating Documentation Snippets Spring REST Docs uses Spring MVC's {spring-framework-docs}/testing.html#spring-mvc-test-framework[test framework], -Spring WebFlux's {spring-framework-docs}/testing.html#webtestclient[`WebTestClient`] or +Spring WebFlux's {spring-framework-docs}/testing.html#webtestclient[`WebTestClient`], or http://www.rest-assured.io[REST Assured] to make requests to the service that you are documenting. It then produces documentation snippets for the request and the resulting response. @@ -269,25 +270,26 @@ response. [[getting-started-documentation-snippets-setup]] -==== Setting up your tests +==== Setting up Your Tests -Exactly how you setup your tests depends on the test framework that you're using. -Spring REST Docs provides first-class support for JUnit 4 and JUnit 5. Other frameworks, -such as TestNG, are also supported although slightly more setup is required. +Exactly how you set up your tests depends on the test framework that you use. Spring REST +Docs provides first-class support for JUnit 4 and JUnit 5. Other frameworks, such as +TestNG, are also supported, although slightly more setup is required. [[getting-started-documentation-snippets-setup-junit]] -===== Setting up your JUnit 4 tests +===== Setting up Your JUnit 4 Tests When using JUnit 4, the first step in generating documentation snippets is to declare a -`public` `JUnitRestDocumentation` field that's annotated as a JUnit `@Rule`. - +`public` `JUnitRestDocumentation` field that is annotated as a JUnit `@Rule`. +The following example shows how to do so: +==== [source,java,indent=0] ---- @Rule public JUnitRestDocumentation restDocumentation = new JUnitRestDocumentation(); ---- - +==== By default, the `JUnitRestDocumentation` rule is automatically configured with an output directory based on your project's build tool: @@ -304,24 +306,29 @@ directory based on your project's build tool: |=== -The default can be overridden by providing an output directory when creating the -`JUnitRestDocumentation` instance: +You can override the default by providing an output directory when you create the +`JUnitRestDocumentation` instance. +The following example shows how to do so: +==== [source,java,indent=0] ---- @Rule public JUnitRestDocumentation restDocumentation = new JUnitRestDocumentation("custom"); ---- +==== -Next, provide an `@Before` method to configure MockMvc, WebTestClient or REST Assured: +Next, you must provide an `@Before` method to configure MockMvc, WebTestClient or REST +Assured. The following examples show how to do so: +==== [source,java,indent=0,role="primary"] .MockMvc ---- include::{examples-dir}/com/example/mockmvc/ExampleApplicationTests.java[tags=setup] ---- -<1> The `MockMvc` instance is configured using a `MockMvcRestDocumentationConfigurer`. An -instance of this class can be obtained from the static `documentationConfiguration()` +<1> The `MockMvc` instance is configured by using a `MockMvcRestDocumentationConfigurer`. +You can obtain an instance of this class from the static `documentationConfiguration()` method on `org.springframework.restdocs.mockmvc.MockMvcRestDocumentation`. [source,java,indent=0,role="secondary"] @@ -330,8 +337,8 @@ method on `org.springframework.restdocs.mockmvc.MockMvcRestDocumentation`. include::{examples-dir}/com/example/webtestclient/ExampleApplicationTests.java[tags=setup] ---- <1> The `WebTestClient` instance is configured by adding a -`WebTestclientRestDocumentationConfigurer` as an `ExchangeFilterFunction`. An instance of -this class can be obtained from the static `documentationConfiguration()` method on +`WebTestclientRestDocumentationConfigurer` as an `ExchangeFilterFunction`. You can obtain +an instance of this class from the static `documentationConfiguration()` method on `org.springframework.restdocs.webtestclient.WebTestClientRestDocumentation`. [source,java,indent=0,role="secondary"] @@ -340,34 +347,40 @@ this class can be obtained from the static `documentationConfiguration()` method include::{examples-dir}/com/example/restassured/ExampleApplicationTests.java[tags=setup] ---- <1> REST Assured is configured by adding a `RestAssuredRestDocumentationConfigurer` as a -`Filter`. An instance of this class can be obtained from the static +`Filter`. You can obtain an instance of this class from the static `documentationConfiguration()` method on `RestAssuredRestDocumentation` in the `org.springframework.restdocs.restassured3` package. +==== The configurer applies sensible defaults and also provides an API for customizing the -configuration. Refer to the <> for more information. +configuration. See the <> for more information. [[getting-started-documentation-snippets-setup-junit-5]] -===== Setting up your JUnit 5 tests +===== Setting up Your JUnit 5 Tests When using JUnit 5, the first step in generating documentation snippets is to apply -the `RestDocumentationExtension` to your test class: +the `RestDocumentationExtension` to your test class. +The following example shows how to do so: +==== [source,java,indent=0] ---- @ExtendWith(RestDocumentationExtension.class) public class JUnit5ExampleTests { ---- +==== -For testing a typical Spring application the `SpringExtension` should also be applied: +When testing a typical Spring application, you should also apply the `SpringExtension`: +==== [source,java,indent=0] ---- @ExtendWith({RestDocumentationExtension.class, SpringExtension.class}) public class JUnit5ExampleTests { ---- +==== The `RestDocumentationExtension` is automatically configured with an output directory based on your project's build tool: @@ -386,15 +399,17 @@ based on your project's build tool: -Next, provide a `@BeforeEach` method to configure MockMvc, WebTestClient, or REST Assured: +Next, you must provide a `@BeforeEach` method to configure MockMvc, WebTestClient, or +REST Assured. The following listings show how to do so: +==== [source,java,indent=0,role="primary"] .MockMvc ---- include::{examples-dir}/com/example/mockmvc/ExampleApplicationJUnit5Tests.java[tags=setup] ---- -<1> The `MockMvc` instance is configured using a `MockMvcRestDocumentationConfigurer`. An -instance of this class can be obtained from the static `documentationConfiguration()` +<1> The `MockMvc` instance is configured by using a `MockMvcRestDocumentationConfigurer`. +You can obtain an instance of this class from the static `documentationConfiguration()` method on `org.springframework.restdocs.mockmvc.MockMvcRestDocumentation`. [source,java,indent=0,role="secondary"] @@ -403,8 +418,8 @@ method on `org.springframework.restdocs.mockmvc.MockMvcRestDocumentation`. include::{examples-dir}/com/example/webtestclient/ExampleApplicationJUnit5Tests.java[tags=setup] ---- <1> The `WebTestClient` instance is configured by adding a -`WebTestClientRestDocumentationConfigurer` as an `ExchangeFilterFunction`. An instance of -this class can be obtained from the static `documentationConfiguration()` method on +`WebTestClientRestDocumentationConfigurer` as an `ExchangeFilterFunction`. You can obtain +an instance of this class from the static `documentationConfiguration()` method on `org.springframework.restdocs.webtestclient.WebTestClientRestDocumentation`. [source,java,indent=0,role="secondary"] @@ -413,12 +428,13 @@ this class can be obtained from the static `documentationConfiguration()` method include::{examples-dir}/com/example/restassured/ExampleApplicationJUnit5Tests.java[tags=setup] ---- <1> REST Assured is configured by adding a `RestAssuredRestDocumentationConfigurer` as a -`Filter`. An instance of this class can be obtained from the static +`Filter`. You can obtain an instance of this class from the static `documentationConfiguration()` method on `RestAssuredRestDocumentation` in the `org.springframework.restdocs.restassured3` package. +==== The configurer applies sensible defaults and also provides an API for customizing the -configuration. Refer to the <> for more information. +configuration. See the <> for more information. @@ -429,18 +445,23 @@ The configuration when JUnit is not being used is largely similar to when it is used. This section describes the key differences. The {samples}/testng[TestNG sample] also 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: +The first difference is that you should use `ManualRestDocumentation` in place of +`JUnitRestDocumentation`. Also, you do not need the `@Rule` annotation. +the following example shows hos to use `ManualRestDocumentation`: +==== [source,java,indent=0] ---- private ManualRestDocumentation restDocumentation = new ManualRestDocumentation(); ---- +==== -Secondly, `ManualRestDocumentation.beforeTest(Class, String)` -must be called before each test. This can be done as part of the method that is -configuring MockMvc, WebTestClient, or REST Assured: +Secondly, you must call `ManualRestDocumentation.beforeTest(Class, String)` +before each test. You can do so as part of the method that +configures MockMvc, WebTestClient, or REST Assured. +The following examples show how to do so: +==== [source,java,indent=0,role="primary"] .MockMvc ---- @@ -458,21 +479,25 @@ include::{examples-dir}/com/example/webtestclient/ExampleApplicationTestNgTests. ---- include::{examples-dir}/com/example/restassured/ExampleApplicationTestNgTests.java[tags=setup] ---- +==== -Lastly, `ManualRestDocumentation.afterTest` must be called after each test. For example, -with TestNG: +Finally, you must call `ManualRestDocumentation.afterTest` after each test. +The following example shows how to do so with TestNG: +==== [source,java,indent=0] ---- include::{examples-dir}/com/example/restassured/ExampleApplicationTestNgTests.java[tags=teardown] ---- +==== [[getting-started-documentation-snippets-invoking-the-service]] -==== Invoking the RESTful service +==== Invoking the RESTful Service -Now that the testing framework has been configured, it can be used to invoke the RESTful -service and document the request and response. For example: +Now that you have configured the testing framework, you can use it to invoke the RESTful +service and document the request and response. The following examples show how to do so: +==== [source,java,indent=0,role="primary"] .MockMvc ---- @@ -482,8 +507,8 @@ include::{examples-dir}/com/example/mockmvc/InvokeService.java[tags=invoke-servi is required. <2> Assert that the service produced the expected response. <3> Document the call to the service, writing the snippets into a directory named `index` -that will be located beneath the configured output directory. The snippets are written by -a `RestDocumentationResultHandler`. An instance of this class can be obtained from the +(which is located beneath the configured output directory). The snippets are written by +a `RestDocumentationResultHandler`. You can obtain an instance of this clas from the static `document` method on `org.springframework.restdocs.mockmvc.MockMvcRestDocumentation`. @@ -496,24 +521,26 @@ include::{examples-dir}/com/example/webtestclient/InvokeService.java[tags=invoke is required. <2> Assert that the service produced the expected response. <3> Document the call to the service, writing the snippets into a directory named `index` -that will be located beneath the configured output directory. The snippets are written by -a `Consumer` of the `ExchangeResult`. Such a consumer can be obtained from the static -`document` method on `org.springframework.restdocs.webtestclient.WebTestClientRestDocumentation`. +(which is located beneath the configured output directory). The snippets are written by +a `Consumer` of the `ExchangeResult`. You can obtain such a consumer from the static +`document` method on +`org.springframework.restdocs.webtestclient.WebTestClientRestDocumentation`. [source,java,indent=0,role="secondary"] .REST Assured ---- include::{examples-dir}/com/example/restassured/InvokeService.java[tags=invoke-service] ---- -<1> Apply the specification that was initialised in the `@Before` method. +<1> Apply the specification that was initialized in the `@Before` method. <2> Indicate that an `application/json` response is required. <3> Document the call to the service, writing the snippets into a directory named `index` -that will be located beneath the configured output directory. The snippets are written by -a `RestDocumentationFilter`. An instance of this class can be obtained from the -static `document` method on `RestAssuredRestDocumentation` in the +(which is located beneath the configured output directory). The snippets are written by +a `RestDocumentationFilter`. You can obtain an instance of this class from the static +`document` method on `RestAssuredRestDocumentation` in the `org.springframework.restdocs.restassured3` package. <4> Invoke the root (`/`) of the service. <5> Assert that the service produce the expected response. +==== By default, six snippets are written: @@ -524,18 +551,18 @@ By default, six snippets are written: * `/index/request-body.adoc` * `/index/response-body.adoc` -Refer to <> for more information about these and other snippets +See <> for more information about these and other snippets that can be produced by Spring REST Docs. [[getting-started-using-the-snippets]] -=== Using the snippets +=== Using the Snippets -Before using the generated snippets, a `.adoc` source file must be created. You can name -the file whatever you like as long as it has a `.adoc` suffix. The result HTML file will -have the same name but with a `.html` suffix. The default location of the source files and -the resulting HTML files depends on whether you are using Maven or Gradle: +Before using the generated snippets, you must create an `.adoc` source file. You can name +the file whatever you like as long as it has a `.adoc` suffix. The resulting HTML file +has the same name but with an `.html` suffix. The default location of the source files and +the resulting HTML files depends on whether you use Maven or Gradle: [cols="2,5,8"] |=== @@ -551,14 +578,17 @@ 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 +You can then include the generated snippets in the manually created Asciidoc file +(described earlier in this section) by using the http://asciidoctor.org/docs/asciidoc-syntax-quick-reference/#include-files[include macro]. -The `snippets` attribute that is automatically set by `spring-restdocs-asciidoctor` -configured in the <> can be used to reference the snippets output directory. For example: +You can use the `snippets` attribute that is automatically set by +`spring-restdocs-asciidoctor` configured in the +<> to reference the snippets +output directory. The following example shows how to do so: +==== [source,adoc,indent=0] ---- \include::{snippets}/index/curl-request.adoc[] ---- +==== diff --git a/docs/src/docs/asciidoc/index.adoc b/docs/src/docs/asciidoc/index.adoc index eee9257f8..4d679da51 100644 --- a/docs/src/docs/asciidoc/index.adoc +++ b/docs/src/docs/asciidoc/index.adoc @@ -1,5 +1,5 @@ = Spring REST Docs -Andy Wilkinson +Andy Wilkinson; Jay Bryant :doctype: book :icons: font :source-highlighter: highlightjs @@ -28,4 +28,4 @@ include::customizing-requests-and-responses.adoc[] include::configuration.adoc[] include::working-with-asciidoctor.adoc[] include::working-with-markdown.adoc[] -include::contributing.adoc[] \ No newline at end of file +include::contributing.adoc[] diff --git a/docs/src/docs/asciidoc/introduction.adoc b/docs/src/docs/asciidoc/introduction.adoc index 730439e44..2c0bab737 100644 --- a/docs/src/docs/asciidoc/introduction.adoc +++ b/docs/src/docs/asciidoc/introduction.adoc @@ -1,26 +1,26 @@ [[introduction]] == Introduction -The aim of Spring REST Docs is to help you to produce documentation for your RESTful -services that is accurate and readable. +The aim of Spring REST Docs is to help you produce accurate and readable documentation for +your RESTful services. Writing high-quality documentation is difficult. One way to ease that difficulty is to use tools that are well-suited to the job. To this end, Spring REST Docs uses http://asciidoctor.org[Asciidoctor] by default. Asciidoctor processes plain text and -produces HTML, styled and layed out to suit your needs. If you prefer, Spring REST Docs -can also be configured to use Markdown. +produces HTML, styled and laid out to suit your needs. If you prefer, you can also +configure Spring REST Docs to use Markdown. -Spring REST Docs makes use of snippets produced by tests written with Spring MVC's +Spring REST Docs uses snippets produced by tests written with Spring MVC's {spring-framework-docs}/testing.html#spring-mvc-test-framework[test framework], Spring WebFlux's {spring-framework-docs}/testing.html#webtestclient[`WebTestClient`] or http://www.rest-assured.io[REST Assured 3]. This test-driven approach helps to guarantee -the accuracy of your service's documentation. If a snippet is incorrect the test that -produces it will fail. +the accuracy of your service's documentation. If a snippet is incorrect, the test that +produces it fails. Documenting a RESTful service is largely about describing its resources. Two key parts of each resource's description are the details of the HTTP requests that it consumes -and the HTTP responses that it produces. Spring REST Docs allows you to work with these -resources and the HTTP requests and responses, shielding your documentation -from the inner-details of your service's implementation. This separation helps you to -document your service's API rather than its implementation. It also frees you to evolve -the implementation without having to rework the documentation. +and the HTTP responses that it produces. Spring REST Docs lets you work with these +resources and the HTTP requests and responses, shielding your documentation from the +inner-details of your service's implementation. This separation helps you document your +service's API rather than its implementation. It also frees you to evolve the +implementation without having to rework the documentation. diff --git a/docs/src/docs/asciidoc/working-with-asciidoctor.adoc b/docs/src/docs/asciidoc/working-with-asciidoctor.adoc index de36f81ce..a336f3447 100644 --- a/docs/src/docs/asciidoc/working-with-asciidoctor.adoc +++ b/docs/src/docs/asciidoc/working-with-asciidoctor.adoc @@ -1,9 +1,12 @@ [[working-with-asciidoctor]] == Working with Asciidoctor -This section describes any aspects of working with Asciidoctor that are particularly +This section describes the aspects of working with Asciidoctor that are particularly relevant to Spring REST Docs. +NOTE: Asciidoc is the document format. Asciidoctor is the tool that produces content +(usually as HTML) from Asciidoc files (which end with `.adoc`). + [[working-with-asciidoctor-resources]] @@ -15,43 +18,50 @@ relevant to Spring REST Docs. [[working-with-asciidoctor-including-snippets]] -=== Including snippets +=== Including Snippets + +This section covers how to include Asciidoc snippets. [[working-with-asciidoctor-including-snippets-operation]] -==== Including multiple snippets for an operation +==== Including Multiple Snippets for an Operation -A macro named `operation` can be used to import all or some of the snippets that have +You can use a macro named `operation` to import all or some of the snippets that have been generated for a specific operation. It is made available by including `spring-restdocs-asciidoctor` in your project's <>. -WARNING: If you are using Gradle and its daemon or support for continuous builds, do not +WARNING: If you use Gradle and its daemon or support for continuous builds, do not use version 1.5.6 of the `org.asciidoctor.convert` plugin. It contains a https://github.com/asciidoctor/asciidoctor-gradle-plugin/issues/222[regression] that prevents extensions from working reliably. -The target of the macro is the name of the operation. In its simplest form, the macro -can be used to include all of the snippets for an operation, as shown in the following +The target of the macro is the name of the operation. In its simplest form, you can use +the macro to include all of the snippets for an operation, as shown in the following example: +==== [source,indent=0] ---- operation::index[] ---- +==== -The operation macro also supports a `snippets` attribute. The `snippets` attribute can be -used to select the snippets that should be included. The attribute's value is a -comma-separated list. Each entry in the list should be the name of a snippet file, minus -the `.adoc` suffix, to include. For example, only the curl, HTTP request and HTTP response -snippets can be included as shown in the following example: +You can use the operation macro also supports a `snippets` attribute. The `snippets` +attribute to select the snippets that should be included. The attribute's value is a +comma-separated list. Each entry in the list should be the name of a snippet file (minus +the `.adoc` suffix) to include. For example, only the curl, HTTP request and HTTP response +snippets can be included, as shown in the following example: +==== [source,indent=0] ---- operation::index[snippets='curl-request,http-request,http-response'] ---- +==== -This is the equivalent of the following: +The preceding example is the equivalent of the following: +==== [source,adoc,indent=0] ---- [[example_curl_request]] @@ -70,78 +80,82 @@ This is the equivalent of the following: \include::{snippets}/index/http-response.adoc[] ---- - +==== [[working-with-asciidoctor-including-snippets-operation-titles]] -===== Section titles +===== Section Titles -For each snippet that's including using `operation`, a section with a title will be -created. Default titles are provided for the built-in snippets: +For each snippet that is included by using the `operation` macro, a section with a title +is created. Default titles are provided for the following built-in snippets: |=== | Snippet | Title -| curl-request +| `curl-request` | Curl Request -| http-request +| `http-request` | HTTP request -| http-response +| `http-response` | HTTP response -| httpie-request +| `httpie-request` | HTTPie request -| links +| `links` | Links -| request-body +| `request-body` | Request body -| request-fields +| `request-fields` | Request fields -| response-body +| `response-body` | Response body -| response-fields +| `response-fields` | Response fields |=== -For snippets not listed in the table above, a default title will be generated by replacing -`-` characters with spaces and capitalising the first letter. For example, the title for a -snippet named `custom-snippet` will be "Custom snippet". +For snippets not listed in the preceding table, a default title is generated by replacing +`-` characters with spaces and capitalizing the first letter. For example, the title for a +snippet named `custom-snippet` `will be` "`Custom snippet`". -The default titles can be customized using document attributes. The name of the attribute -should be `operation-{snippet}-title`. For example, to customize the title of the -`curl-request` snippet to be "Example request", use the following attribute: +You can customize the default titles by using document attributes. The name of the +attribute should be `operation-{snippet}-title`. For example, to customize the title of +the `curl-request` snippet to be "Example request", you can use the following attribute: +==== [source,indent=0] ---- :operation-curl-request-title: Example request ---- +==== [[working-with-asciidoctor-including-snippets-individual]] -==== Including individual snippets +==== Including Individual Snippets The http://asciidoctor.org/docs/asciidoc-syntax-quick-reference/#include-files[include -macro] is used to include individual snippets in your documentation. The `snippets` -attribute that is automatically set by `spring-restdocs-asciidoctor` configured in the -<> can be used to reference the -snippets output directory. For example: +macro] is used to include individual snippets in your documentation. You can use the +`snippets` attribute (which is automatically set by `spring-restdocs-asciidoctor` +configured in the <>) to +reference the snippets output directory. The following example shows how to do so: +==== [source,indent=0] ---- \include::{snippets}/index/curl-request.adoc[] ---- +==== [[working-with-asciidoctor-customizing-tables]] -=== Customizing tables +=== Customizing Tables Many of the snippets contain a table in its default configuration. The appearance of the table can be customized, either by providing some additional configuration when the @@ -150,55 +164,63 @@ snippet is included or by using a custom snippet template. [[working-with-asciidoctor-customizing-tables-formatting-columns]] -==== Formatting columns +==== Formatting Columns Asciidoctor has rich support for -http://asciidoctor.org/docs/user-manual/#cols-format[formatting a table's columns]. For -example, the widths of a table's columns can be specified using the `cols` attribute: +http://asciidoctor.org/docs/user-manual/#cols-format[formatting a table's columns]. As the +following example shows, you can specify the widths of a table's columns by using the +`cols` attribute: +==== [source,indent=0] ---- [cols="1,3"] <1> \include::{snippets}/index/links.adoc[] ---- -<1> The table's width will be split across its two columns with the second column being -three times as wide as the first. +<1> The table's width is split across its two columns, with the second column being three + times as wide as the first. +==== [[working-with-asciidoctor-customizing-tables-title]] -==== Configuring the title +==== Configuring the Title -The title of a table can be specified using a line prefixed by a `.`: +You can specify the title of a table by using a line prefixed by a `.`. +The following example shows how to do so: +==== [source,indent=0] ---- .Links <1> \include::{snippets}/index/links.adoc[] ---- <1> The table's title will be `Links`. +==== [[working-with-asciidoctor-customizing-tables-formatting-problems]] -==== Avoiding table formatting problems +==== Avoiding Table Formatting Problems Asciidoctor uses the `|` character to delimit cells in a table. This can cause problems -if you want a `|` to appear in a cell's contents. The problem can be avoided by -escaping the `|` with a backslash, i.e. by using `\|` rather than `|`. +if you want a `|` to appear in a cell's contents. You can avoid the problem by +escaping the `|` with a backslash -- in other words, by using `\|` rather than `|`. -All of the default Asciidoctor snippet templates perform this escaping automatically -use a Mustache lamba named `tableCellContent`. If you write your own custom templates -you may want to use this lamba. For example, to escape `|` characters +All of the default Asciidoctor snippet templates perform this escaping automatically by +using a Mustache lamba named `tableCellContent`. If you write your own custom templates +you may want to use this lamba. The following example shows how to escape `|` characters in a cell that contains the value of a `description` attribute: +==== ---- | {{#tableCellContent}}{{description}}{{/tableCellContent}} ---- +==== -==== Further reading +==== Further Reading -Refer to the http://asciidoctor.org/docs/user-manual/#tables[Tables section of -the Asciidoctor user manual] for more information about customizing tables. +See the http://asciidoctor.org/docs/user-manual/#tables[Tables section of the +Asciidoctor user manual] for more information about customizing tables. diff --git a/docs/src/docs/asciidoc/working-with-markdown.adoc b/docs/src/docs/asciidoc/working-with-markdown.adoc index 4d532a91f..f32fb3d1d 100644 --- a/docs/src/docs/asciidoc/working-with-markdown.adoc +++ b/docs/src/docs/asciidoc/working-with-markdown.adoc @@ -1,7 +1,7 @@ [[working-with-markdown]] == Working with Markdown -This section describes any aspects of working with Markdown that are particularly +This section describes the aspects of working with Markdown that are particularly relevant to Spring REST Docs. @@ -9,9 +9,9 @@ relevant to Spring REST Docs. [[working-with-markdown-limitations]] === Limitations -Markdown was originally designed for people writing for the web and, as such, isn't -as well-suited to writing documentation as Asciidoctor. Typically, these limitations -are overcome by using another tool that builds on top of Markdown. +Markdown was originally designed for people writing for the web and, as such, is not as +well-suited to writing documentation as Asciidoctor. Typically, these limitations are +overcome by using another tool that builds on top of Markdown. Markdown has no official support for tables. Spring REST Docs' default Markdown snippet templates use https://michelf.ca/projects/php-markdown/extra/#table[Markdown Extra's table @@ -20,9 +20,9 @@ format]. [[working-with-markdown-including-snippets]] -=== Including snippets +=== Including Snippets Markdown has no built-in support for including one Markdown file in another. To include the generated snippets of Markdown in your documentation, you should use an additional -tool that supports this functionality. One example that's particularly well-suited to +tool that supports this functionality. One example that is particularly well-suited to documenting APIs is https://github.com/tripit/slate[Slate]. From ba08a787100fffbe504014206dc3a68fab18a175 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=B0=A8=EC=A7=80=ED=9B=88?= Date: Thu, 14 Feb 2019 16:58:55 +0900 Subject: [PATCH 017/502] Fix typo in REST Assured HTTP headers example See gh-579 --- docs/src/test/java/com/example/restassured/HttpHeaders.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/test/java/com/example/restassured/HttpHeaders.java b/docs/src/test/java/com/example/restassured/HttpHeaders.java index 91c56b2d0..661af50d2 100644 --- a/docs/src/test/java/com/example/restassured/HttpHeaders.java +++ b/docs/src/test/java/com/example/restassured/HttpHeaders.java @@ -43,7 +43,7 @@ public void headers() throws Exception { "Remaining requests permitted in current period"), headerWithName("X-RateLimit-Reset").description( "Time at which the rate limit period will reset")))) - .header("Authroization", "Basic dXNlcjpzZWNyZXQ=") // <4> + .header("Authorization", "Basic dXNlcjpzZWNyZXQ=") // <4> .when().get("/people") .then().assertThat().statusCode(is(200)); // end::headers[] From ba48a7270afea8360a9a7f00540ca78d556eaa4f Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Mon, 18 Feb 2019 10:19:17 +0000 Subject: [PATCH 018/502] Inject ApplicationContext not WebApplicationContext with WebTestClient Closes gh-582 --- .../CustomDefaultOperationPreprocessors.java | 6 +++--- .../com/example/webtestclient/CustomDefaultSnippets.java | 6 +++--- .../java/com/example/webtestclient/CustomEncoding.java | 6 +++--- .../test/java/com/example/webtestclient/CustomFormat.java | 6 +++--- .../com/example/webtestclient/CustomUriConfiguration.java | 6 +++--- .../com/example/webtestclient/EveryTestPreprocessing.java | 6 +++--- .../webtestclient/ExampleApplicationJUnit5Tests.java | 8 ++++---- .../webtestclient/ExampleApplicationTestNgTests.java | 6 +++--- .../example/webtestclient/ExampleApplicationTests.java | 6 +++--- 9 files changed, 28 insertions(+), 28 deletions(-) diff --git a/docs/src/test/java/com/example/webtestclient/CustomDefaultOperationPreprocessors.java b/docs/src/test/java/com/example/webtestclient/CustomDefaultOperationPreprocessors.java index 42cce427d..c8cfbc250 100644 --- a/docs/src/test/java/com/example/webtestclient/CustomDefaultOperationPreprocessors.java +++ b/docs/src/test/java/com/example/webtestclient/CustomDefaultOperationPreprocessors.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2017 the original author or authors. + * Copyright 2014-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. @@ -19,9 +19,9 @@ import org.junit.Before; import org.junit.Rule; +import org.springframework.context.ApplicationContext; import org.springframework.restdocs.JUnitRestDocumentation; import org.springframework.test.web.reactive.server.WebTestClient; -import org.springframework.web.context.WebApplicationContext; import static org.springframework.restdocs.operation.preprocess.Preprocessors.prettyPrint; import static org.springframework.restdocs.operation.preprocess.Preprocessors.removeHeaders; @@ -34,7 +34,7 @@ public class CustomDefaultOperationPreprocessors { @Rule public final JUnitRestDocumentation restDocumentation = new JUnitRestDocumentation(); - private WebApplicationContext context; + private ApplicationContext context; @SuppressWarnings("unused") private WebTestClient webTestClient; diff --git a/docs/src/test/java/com/example/webtestclient/CustomDefaultSnippets.java b/docs/src/test/java/com/example/webtestclient/CustomDefaultSnippets.java index 5a8289814..b04f1051f 100644 --- a/docs/src/test/java/com/example/webtestclient/CustomDefaultSnippets.java +++ b/docs/src/test/java/com/example/webtestclient/CustomDefaultSnippets.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2017 the original author or authors. + * Copyright 2014-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. @@ -20,9 +20,9 @@ import org.junit.Rule; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationContext; import org.springframework.restdocs.JUnitRestDocumentation; import org.springframework.test.web.reactive.server.WebTestClient; -import org.springframework.web.context.WebApplicationContext; import static org.springframework.restdocs.cli.CliDocumentation.curlRequest; import static org.springframework.restdocs.webtestclient.WebTestClientRestDocumentation.documentationConfiguration; @@ -35,7 +35,7 @@ public class CustomDefaultSnippets { public final JUnitRestDocumentation restDocumentation = new JUnitRestDocumentation(); @Autowired - private WebApplicationContext context; + private ApplicationContext context; @SuppressWarnings("unused") private WebTestClient webTestClient; diff --git a/docs/src/test/java/com/example/webtestclient/CustomEncoding.java b/docs/src/test/java/com/example/webtestclient/CustomEncoding.java index 63a0e0509..748272a8c 100644 --- a/docs/src/test/java/com/example/webtestclient/CustomEncoding.java +++ b/docs/src/test/java/com/example/webtestclient/CustomEncoding.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2016 the original author or authors. + * Copyright 2014-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. @@ -20,9 +20,9 @@ import org.junit.Rule; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationContext; import org.springframework.restdocs.JUnitRestDocumentation; import org.springframework.test.web.reactive.server.WebTestClient; -import org.springframework.web.context.WebApplicationContext; import static org.springframework.restdocs.webtestclient.WebTestClientRestDocumentation.documentationConfiguration; @@ -34,7 +34,7 @@ public class CustomEncoding { public final JUnitRestDocumentation restDocumentation = new JUnitRestDocumentation(); @Autowired - private WebApplicationContext context; + private ApplicationContext context; @SuppressWarnings("unused") private WebTestClient webTestClient; diff --git a/docs/src/test/java/com/example/webtestclient/CustomFormat.java b/docs/src/test/java/com/example/webtestclient/CustomFormat.java index b112f2aa8..933bd5a43 100644 --- a/docs/src/test/java/com/example/webtestclient/CustomFormat.java +++ b/docs/src/test/java/com/example/webtestclient/CustomFormat.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2016 the original author or authors. + * Copyright 2014-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. @@ -20,10 +20,10 @@ import org.junit.Rule; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationContext; import org.springframework.restdocs.JUnitRestDocumentation; import org.springframework.restdocs.templates.TemplateFormats; import org.springframework.test.web.reactive.server.WebTestClient; -import org.springframework.web.context.WebApplicationContext; import static org.springframework.restdocs.webtestclient.WebTestClientRestDocumentation.documentationConfiguration; @@ -35,7 +35,7 @@ public class CustomFormat { public final JUnitRestDocumentation restDocumentation = new JUnitRestDocumentation(); @Autowired - private WebApplicationContext context; + private ApplicationContext context; @SuppressWarnings("unused") private WebTestClient webTestClient; diff --git a/docs/src/test/java/com/example/webtestclient/CustomUriConfiguration.java b/docs/src/test/java/com/example/webtestclient/CustomUriConfiguration.java index 6f12f4c95..3a5d25c40 100644 --- a/docs/src/test/java/com/example/webtestclient/CustomUriConfiguration.java +++ b/docs/src/test/java/com/example/webtestclient/CustomUriConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2017 the original author or authors. + * Copyright 2014-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. @@ -20,9 +20,9 @@ import org.junit.Rule; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationContext; import org.springframework.restdocs.JUnitRestDocumentation; import org.springframework.test.web.reactive.server.WebTestClient; -import org.springframework.web.context.WebApplicationContext; import static org.springframework.restdocs.webtestclient.WebTestClientRestDocumentation.documentationConfiguration; @@ -35,7 +35,7 @@ public class CustomUriConfiguration { private WebTestClient webTestClient; @Autowired - private WebApplicationContext context; + private ApplicationContext context; // tag::custom-uri-configuration[] @Before diff --git a/docs/src/test/java/com/example/webtestclient/EveryTestPreprocessing.java b/docs/src/test/java/com/example/webtestclient/EveryTestPreprocessing.java index bb6c79a20..11d4ea7b1 100644 --- a/docs/src/test/java/com/example/webtestclient/EveryTestPreprocessing.java +++ b/docs/src/test/java/com/example/webtestclient/EveryTestPreprocessing.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2016 the original author or authors. + * Copyright 2014-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. @@ -19,9 +19,9 @@ import org.junit.Before; import org.junit.Rule; +import org.springframework.context.ApplicationContext; import org.springframework.restdocs.JUnitRestDocumentation; import org.springframework.test.web.reactive.server.WebTestClient; -import org.springframework.web.context.WebApplicationContext; import static org.springframework.restdocs.hypermedia.HypermediaDocumentation.linkWithRel; import static org.springframework.restdocs.hypermedia.HypermediaDocumentation.links; @@ -37,7 +37,7 @@ public class EveryTestPreprocessing { @Rule public final JUnitRestDocumentation restDocumentation = new JUnitRestDocumentation(); - private WebApplicationContext context; + private ApplicationContext context; // tag::setup[] private WebTestClient webTestClient; diff --git a/docs/src/test/java/com/example/webtestclient/ExampleApplicationJUnit5Tests.java b/docs/src/test/java/com/example/webtestclient/ExampleApplicationJUnit5Tests.java index 774887139..645392315 100644 --- a/docs/src/test/java/com/example/webtestclient/ExampleApplicationJUnit5Tests.java +++ b/docs/src/test/java/com/example/webtestclient/ExampleApplicationJUnit5Tests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2017 the original author or authors. + * Copyright 2014-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. @@ -19,10 +19,10 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.context.ApplicationContext; import org.springframework.restdocs.RestDocumentationContextProvider; import org.springframework.restdocs.RestDocumentationExtension; import org.springframework.test.web.reactive.server.WebTestClient; -import org.springframework.web.context.WebApplicationContext; import static org.springframework.restdocs.webtestclient.WebTestClientRestDocumentation.documentationConfiguration; @@ -34,9 +34,9 @@ public class ExampleApplicationJUnit5Tests { private WebTestClient webTestClient; @BeforeEach - public void setUp(WebApplicationContext webApplicationContext, + public void setUp(ApplicationContext applicationContext, RestDocumentationContextProvider restDocumentation) { - this.webTestClient = WebTestClient.bindToApplicationContext(webApplicationContext) + this.webTestClient = WebTestClient.bindToApplicationContext(applicationContext) .configureClient() .filter(documentationConfiguration(restDocumentation)) // <1> .build(); diff --git a/docs/src/test/java/com/example/webtestclient/ExampleApplicationTestNgTests.java b/docs/src/test/java/com/example/webtestclient/ExampleApplicationTestNgTests.java index 162bdb323..c8e776850 100644 --- a/docs/src/test/java/com/example/webtestclient/ExampleApplicationTestNgTests.java +++ b/docs/src/test/java/com/example/webtestclient/ExampleApplicationTestNgTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2017 the original author or authors. + * Copyright 2014-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. @@ -22,9 +22,9 @@ import org.testng.annotations.BeforeMethod; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationContext; import org.springframework.restdocs.ManualRestDocumentation; import org.springframework.test.web.reactive.server.WebTestClient; -import org.springframework.web.context.WebApplicationContext; import static org.springframework.restdocs.webtestclient.WebTestClientRestDocumentation.documentationConfiguration; @@ -37,7 +37,7 @@ public class ExampleApplicationTestNgTests { private WebTestClient webTestClient; @Autowired - private WebApplicationContext context; + private ApplicationContext context; @BeforeMethod public void setUp(Method method) { diff --git a/docs/src/test/java/com/example/webtestclient/ExampleApplicationTests.java b/docs/src/test/java/com/example/webtestclient/ExampleApplicationTests.java index 9fa80253c..c1402b562 100644 --- a/docs/src/test/java/com/example/webtestclient/ExampleApplicationTests.java +++ b/docs/src/test/java/com/example/webtestclient/ExampleApplicationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2017 the original author or authors. + * Copyright 2014-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. @@ -20,9 +20,9 @@ import org.junit.Rule; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationContext; import org.springframework.restdocs.JUnitRestDocumentation; import org.springframework.test.web.reactive.server.WebTestClient; -import org.springframework.web.context.WebApplicationContext; import static org.springframework.restdocs.webtestclient.WebTestClientRestDocumentation.documentationConfiguration; @@ -36,7 +36,7 @@ public class ExampleApplicationTests { private WebTestClient webTestClient; @Autowired - private WebApplicationContext context; + private ApplicationContext context; @Before public void setUp() { From 9ae244879079b46111d5c9effba78813c83f532f Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Thu, 21 Feb 2019 10:10:09 +0000 Subject: [PATCH 019/502] Update Spring Boot-based samples to 2.1.3 Closes gh-586 --- samples/junit5/build.gradle | 9 ++++----- samples/rest-assured/build.gradle | 4 ++-- samples/rest-notes-slate/build.gradle | 2 +- samples/rest-notes-spring-data-rest/pom.xml | 2 +- samples/rest-notes-spring-hateoas/build.gradle | 7 ++----- samples/testng/build.gradle | 6 ++---- 6 files changed, 12 insertions(+), 18 deletions(-) diff --git a/samples/junit5/build.gradle b/samples/junit5/build.gradle index a9bac880a..b94de89a0 100644 --- a/samples/junit5/build.gradle +++ b/samples/junit5/build.gradle @@ -3,7 +3,7 @@ buildscript { mavenCentral() } dependencies { - classpath 'org.springframework.boot:spring-boot-gradle-plugin:2.0.0.RELEASE' + classpath 'org.springframework.boot:spring-boot-gradle-plugin:2.1.3.RELEASE' classpath 'org.junit.platform:junit-platform-gradle-plugin:1.0.1' } } @@ -31,13 +31,12 @@ targetCompatibility = 1.8 ext { snippetsDir = file('build/generated-snippets') - junitJupiterVersion = '5.0.0' } ext['spring-restdocs.version'] = '2.0.4.BUILD-SNAPSHOT' dependencies { - asciidoctor "org.springframework.restdocs:spring-restdocs-asciidoctor:${project.ext['spring-restdocs.version']}" + asciidoctor 'org.springframework.restdocs:spring-restdocs-asciidoctor' compile 'org.springframework.boot:spring-boot-starter-web' @@ -45,8 +44,8 @@ dependencies { exclude group: 'junit', module: 'junit;' } testCompile 'org.springframework.restdocs:spring-restdocs-mockmvc' - testCompile "org.junit.jupiter:junit-jupiter-api:${junitJupiterVersion}" - testRuntime "org.junit.jupiter:junit-jupiter-engine:${junitJupiterVersion}" + testCompile 'org.junit.jupiter:junit-jupiter-api' + testRuntime 'org.junit.jupiter:junit-jupiter-engine' } test { diff --git a/samples/rest-assured/build.gradle b/samples/rest-assured/build.gradle index d70b3c9c2..20cfec7a5 100644 --- a/samples/rest-assured/build.gradle +++ b/samples/rest-assured/build.gradle @@ -3,7 +3,7 @@ buildscript { mavenCentral() } dependencies { - classpath 'org.springframework.boot:spring-boot-gradle-plugin:2.0.0.RELEASE' + classpath 'org.springframework.boot:spring-boot-gradle-plugin:2.1.3.RELEASE' } } @@ -34,11 +34,11 @@ ext { ext['spring-restdocs.version'] = '2.0.4.BUILD-SNAPSHOT' dependencies { + asciidoctor 'org.springframework.restdocs:spring-restdocs-asciidoctor' compile 'org.springframework.boot:spring-boot-starter-web' testCompile 'io.rest-assured:rest-assured:3.0.2' testCompile 'org.springframework.boot:spring-boot-starter-test' testCompile 'org.springframework.restdocs:spring-restdocs-restassured' - asciidoctor "org.springframework.restdocs:spring-restdocs-asciidoctor:${project.ext['spring-restdocs.version']}" } test { diff --git a/samples/rest-notes-slate/build.gradle b/samples/rest-notes-slate/build.gradle index e4a2bd3e4..f23a622ef 100644 --- a/samples/rest-notes-slate/build.gradle +++ b/samples/rest-notes-slate/build.gradle @@ -3,7 +3,7 @@ buildscript { mavenCentral() } dependencies { - classpath 'org.springframework.boot:spring-boot-gradle-plugin:2.0.0.RELEASE' + classpath 'org.springframework.boot:spring-boot-gradle-plugin:2.1.3.RELEASE' } } diff --git a/samples/rest-notes-spring-data-rest/pom.xml b/samples/rest-notes-spring-data-rest/pom.xml index cf8faaceb..0016c4576 100644 --- a/samples/rest-notes-spring-data-rest/pom.xml +++ b/samples/rest-notes-spring-data-rest/pom.xml @@ -11,7 +11,7 @@ org.springframework.boot spring-boot-starter-parent - 2.0.0.RELEASE + 2.1.3.RELEASE diff --git a/samples/rest-notes-spring-hateoas/build.gradle b/samples/rest-notes-spring-hateoas/build.gradle index 131a6c296..d563c6f2f 100644 --- a/samples/rest-notes-spring-hateoas/build.gradle +++ b/samples/rest-notes-spring-hateoas/build.gradle @@ -3,7 +3,7 @@ buildscript { mavenCentral() } dependencies { - classpath 'org.springframework.boot:spring-boot-gradle-plugin:2.0.0.RELEASE' + classpath 'org.springframework.boot:spring-boot-gradle-plugin:2.1.3.RELEASE' } } @@ -34,14 +34,11 @@ ext { ext['spring-restdocs.version'] = '2.0.4.BUILD-SNAPSHOT' dependencies { - asciidoctor "org.springframework.restdocs:spring-restdocs-asciidoctor:${project.ext['spring-restdocs.version']}" - + asciidoctor 'org.springframework.restdocs:spring-restdocs-asciidoctor' compile 'org.springframework.boot:spring-boot-starter-data-jpa' compile 'org.springframework.boot:spring-boot-starter-hateoas' - runtime 'com.h2database:h2' runtime 'org.atteo:evo-inflector:1.2.1' - testCompile 'com.jayway.jsonpath:json-path' testCompile 'org.assertj:assertj-core' testCompile 'org.springframework.boot:spring-boot-starter-test' diff --git a/samples/testng/build.gradle b/samples/testng/build.gradle index e8cec0a56..2550b7c33 100644 --- a/samples/testng/build.gradle +++ b/samples/testng/build.gradle @@ -3,7 +3,7 @@ buildscript { mavenCentral() } dependencies { - classpath 'org.springframework.boot:spring-boot-gradle-plugin:2.0.0.RELEASE' + classpath 'org.springframework.boot:spring-boot-gradle-plugin:2.1.3.RELEASE' } } @@ -34,10 +34,8 @@ ext { ext['spring-restdocs.version'] = '2.0.4.BUILD-SNAPSHOT' dependencies { - asciidoctor "org.springframework.restdocs:spring-restdocs-asciidoctor:${project.ext['spring-restdocs.version']}" - + asciidoctor 'org.springframework.restdocs:spring-restdocs-asciidoctor' compile 'org.springframework.boot:spring-boot-starter-web' - testCompile('org.springframework.boot:spring-boot-starter-test') { exclude group: 'junit', module: 'junit;' } From 5d18c56071a95d5d73fafe8f6a67308684b98dda Mon Sep 17 00:00:00 2001 From: Paul-Christian Volkmer Date: Thu, 7 Feb 2019 12:23:47 +0100 Subject: [PATCH 020/502] Update JUnit 5 sample to use Gradle's native JUnit 5 support See gh-576 --- samples/junit5/build.gradle | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/samples/junit5/build.gradle b/samples/junit5/build.gradle index b94de89a0..c39976982 100644 --- a/samples/junit5/build.gradle +++ b/samples/junit5/build.gradle @@ -4,7 +4,6 @@ buildscript { } dependencies { classpath 'org.springframework.boot:spring-boot-gradle-plugin:2.1.3.RELEASE' - classpath 'org.junit.platform:junit-platform-gradle-plugin:1.0.1' } } @@ -16,7 +15,6 @@ apply plugin: 'java' apply plugin: 'org.springframework.boot' apply plugin: 'eclipse' apply plugin: 'io.spring.dependency-management' -apply plugin: 'org.junit.platform.gradle.plugin' repositories { mavenLocal() @@ -50,6 +48,7 @@ dependencies { test { outputs.dir snippetsDir + useJUnitPlatform() } asciidoctor { From e23cfc6f3e7487186a70d10e2379876ece9b2ab5 Mon Sep 17 00:00:00 2001 From: Spring Operator Date: Tue, 5 Mar 2019 23:58:09 -0600 Subject: [PATCH 021/502] Use SSL for all HTTP URLs See gh-591 --- build.gradle | 4 ++-- gradle/publish-maven.gradle | 4 ++-- samples/rest-notes-spring-data-rest/mvnw | 2 +- samples/rest-notes-spring-data-rest/mvnw.cmd | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/build.gradle b/build.gradle index 580ff1221..d8cb331d8 100644 --- a/build.gradle +++ b/build.gradle @@ -39,8 +39,8 @@ sonarqube { ext { springVersion = '5.0.5.RELEASE' javadocLinks = [ - 'http://docs.oracle.com/javase/8/docs/api/', - "http://docs.spring.io/spring-framework/docs/$springVersion/javadoc-api/", + 'https://docs.oracle.com/javase/8/docs/api/', + "https://docs.spring.io/spring-framework/docs/$springVersion/javadoc-api/", 'https://docs.jboss.org/hibernate/stable/beanvalidation/api/', 'https://docs.jboss.org/hibernate/stable/validator/api/' ] as String[] diff --git a/gradle/publish-maven.gradle b/gradle/publish-maven.gradle index ad2d75058..94b5e564e 100644 --- a/gradle/publish-maven.gradle +++ b/gradle/publish-maven.gradle @@ -15,12 +15,12 @@ def customizePom(pom, gradleProject) { url = "https://github.com/spring-projects/spring-restdocs" organization { name = "Spring IO" - url = "http://projects.spring.io/spring-restdocs" + url = "https://projects.spring.io/spring-restdocs" } licenses { license { name "The Apache Software License, Version 2.0" - url "http://www.apache.org/licenses/LICENSE-2.0.txt" + url "https://www.apache.org/licenses/LICENSE-2.0.txt" distribution "repo" } } diff --git a/samples/rest-notes-spring-data-rest/mvnw b/samples/rest-notes-spring-data-rest/mvnw index fc7efd17d..63fcc8f0f 100755 --- a/samples/rest-notes-spring-data-rest/mvnw +++ b/samples/rest-notes-spring-data-rest/mvnw @@ -8,7 +8,7 @@ # "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 +# https://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 diff --git a/samples/rest-notes-spring-data-rest/mvnw.cmd b/samples/rest-notes-spring-data-rest/mvnw.cmd index 001048081..66e928bd1 100644 --- a/samples/rest-notes-spring-data-rest/mvnw.cmd +++ b/samples/rest-notes-spring-data-rest/mvnw.cmd @@ -7,7 +7,7 @@ @REM "License"); you may not use this file except in compliance @REM with the License. You may obtain a copy of the License at @REM -@REM http://www.apache.org/licenses/LICENSE-2.0 +@REM https://www.apache.org/licenses/LICENSE-2.0 @REM @REM Unless required by applicable law or agreed to in writing, @REM software distributed under the License is distributed on an From 91653a300a300911c4a4c4aea963ef3f8110bda5 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 13 Mar 2019 09:20:42 +0000 Subject: [PATCH 022/502] Set Javadoc and JavaCompile encoding to UTF-8 Closes gh-593 --- build.gradle | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/build.gradle b/build.gradle index 337b1d8e7..16157e9d2 100644 --- a/build.gradle +++ b/build.gradle @@ -103,6 +103,10 @@ subprojects { options.compilerArgs = [ '-Xlint:deprecation', '-Xlint:-options', '-Werror' ] } + tasks.withType(JavaCompile) { + options.encoding = 'UTF-8' + } + } configure(subprojects - project(":docs")) { subproject -> @@ -149,6 +153,7 @@ configure(subprojects - project(":docs")) { subproject -> options.docTitle = "${options.header} API" options.links = javadocLinks options.addStringOption '-quiet' + options.encoding = 'UTF-8' } task sourcesJar(type: Jar) { From 2f12c2de6a36d8d3c7b13fdd71fc406bfc90536e Mon Sep 17 00:00:00 2001 From: clydebarrow <2366188+clydebarrow@users.noreply.github.com> Date: Wed, 13 Mar 2019 07:33:08 +1100 Subject: [PATCH 023/502] Fix links to ignored() in RequestDocumentation's javadoc See gh-595 --- .../request/RequestDocumentation.java | 40 +++++++++---------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/request/RequestDocumentation.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/request/RequestDocumentation.java index e7a669693..a893399dc 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/request/RequestDocumentation.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/request/RequestDocumentation.java @@ -65,8 +65,8 @@ public static RequestPartDescriptor partWithName(String name) { * request path, a failure will also occur. *

* If you do not want to document a path parameter, a parameter descriptor can be - * marked as {@link ParameterDescriptor#ignored}. This will prevent it from appearing - * in the generated snippet while avoiding the failure described above. + * marked as {@link ParameterDescriptor#ignored()}. This will prevent it from + * appearing in the generated snippet while avoiding the failure described above. * @param descriptors the descriptions of the parameters in the request's path * @return the snippet that will document the parameters */ @@ -86,8 +86,8 @@ public static PathParametersSnippet pathParameters( * request path, a failure will also occur. *

* If you do not want to document a path parameter, a parameter descriptor can be - * marked as {@link ParameterDescriptor#ignored}. This will prevent it from appearing - * in the generated snippet while avoiding the failure described above. + * marked as {@link ParameterDescriptor#ignored()}. This will prevent it from + * appearing in the generated snippet while avoiding the failure described above. * @param descriptors the descriptions of the parameters in the request's path * @return the snippet that will document the parameters */ @@ -138,8 +138,8 @@ public static PathParametersSnippet relaxedPathParameters( * request path, a failure will also occur. *

* If you do not want to document a path parameter, a parameter descriptor can be - * marked as {@link ParameterDescriptor#ignored}. This will prevent it from appearing - * in the generated snippet while avoiding the failure described above. + * marked as {@link ParameterDescriptor#ignored()}. This will prevent it from + * appearing in the generated snippet while avoiding the failure described above. * @param attributes the attributes * @param descriptors the descriptions of the parameters in the request's path * @return the snippet that will document the parameters @@ -161,8 +161,8 @@ public static PathParametersSnippet pathParameters(Map attribute * request path, a failure will also occur. *

* If you do not want to document a path parameter, a parameter descriptor can be - * marked as {@link ParameterDescriptor#ignored}. This will prevent it from appearing - * in the generated snippet while avoiding the failure described above. + * marked as {@link ParameterDescriptor#ignored()}. This will prevent it from + * appearing in the generated snippet while avoiding the failure described above. * @param attributes the attributes * @param descriptors the descriptions of the parameters in the request's path * @return the snippet that will document the parameters @@ -217,8 +217,8 @@ public static PathParametersSnippet relaxedPathParameters( * request, a failure will also occur. *

* If you do not want to document a request parameter, a parameter descriptor can be - * marked as {@link ParameterDescriptor#ignored}. This will prevent it from appearing - * in the generated snippet while avoiding the failure described above. + * marked as {@link ParameterDescriptor#ignored()}. This will prevent it from + * appearing in the generated snippet while avoiding the failure described above. * @param descriptors the descriptions of the request's parameters * @return the snippet * @see OperationRequest#getParameters() @@ -239,8 +239,8 @@ public static RequestParametersSnippet requestParameters( * request, a failure will also occur. *

* If you do not want to document a request parameter, a parameter descriptor can be - * marked as {@link ParameterDescriptor#ignored}. This will prevent it from appearing - * in the generated snippet while avoiding the failure described above. + * marked as {@link ParameterDescriptor#ignored()}. This will prevent it from + * appearing in the generated snippet while avoiding the failure described above. * @param descriptors the descriptions of the request's parameters * @return the snippet * @see OperationRequest#getParameters() @@ -294,8 +294,8 @@ public static RequestParametersSnippet relaxedRequestParameters( * request, a failure will also occur. *

* If you do not want to document a request parameter, a parameter descriptor can be - * marked as {@link ParameterDescriptor#ignored}. This will prevent it from appearing - * in the generated snippet while avoiding the failure described above. + * marked as {@link ParameterDescriptor#ignored()}. This will prevent it from + * appearing in the generated snippet while avoiding the failure described above. * @param attributes the attributes * @param descriptors the descriptions of the request's parameters * @return the snippet that will document the parameters @@ -318,8 +318,8 @@ public static RequestParametersSnippet requestParameters( * request, a failure will also occur. *

* If you do not want to document a request parameter, a parameter descriptor can be - * marked as {@link ParameterDescriptor#ignored}. This will prevent it from appearing - * in the generated snippet while avoiding the failure described above. + * marked as {@link ParameterDescriptor#ignored()}. This will prevent it from + * appearing in the generated snippet while avoiding the failure described above. * @param attributes the attributes * @param descriptors the descriptions of the request's parameters * @return the snippet that will document the parameters @@ -376,7 +376,7 @@ public static RequestParametersSnippet relaxedRequestParameters( * failure will also occur. *

* If you do not want to document a part, a part descriptor can be marked as - * {@link RequestPartDescriptor#ignored}. This will prevent it from appearing in the + * {@link RequestPartDescriptor#ignored()}. This will prevent it from appearing in the * generated snippet while avoiding the failure described above. * @param descriptors the descriptions of the request's parts * @return the snippet @@ -396,7 +396,7 @@ public static RequestPartsSnippet requestParts(RequestPartDescriptor... descript * failure will also occur. *

* If you do not want to document a part, a part descriptor can be marked as - * {@link RequestPartDescriptor#ignored}. This will prevent it from appearing in the + * {@link RequestPartDescriptor#ignored()}. This will prevent it from appearing in the * generated snippet while avoiding the failure described above. * @param descriptors the descriptions of the request's parts * @return the snippet @@ -448,7 +448,7 @@ public static RequestPartsSnippet relaxedRequestParts( * failure will also occur. *

* If you do not want to document a part, a part descriptor can be marked as - * {@link RequestPartDescriptor#ignored}. This will prevent it from appearing in the + * {@link RequestPartDescriptor#ignored()}. This will prevent it from appearing in the * generated snippet while avoiding the failure described above. * @param attributes the attributes * @param descriptors the descriptions of the request's parts @@ -471,7 +471,7 @@ public static RequestPartsSnippet requestParts(Map attributes, * failure will also occur. *

* If you do not want to document a part, a part descriptor can be marked as - * {@link RequestPartDescriptor#ignored}. This will prevent it from appearing in the + * {@link RequestPartDescriptor#ignored()}. This will prevent it from appearing in the * generated snippet while avoiding the failure described above. * @param attributes the attributes * @param descriptors the descriptions of the request's parts From 874ebba73d3470bca768eb8bb8177ae36f4ebfd0 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 13 Mar 2019 09:31:35 +0000 Subject: [PATCH 024/502] Polish "Fix links to ignored() in RequestDocumentation's javadoc" See gh-595 --- .../springframework/restdocs/request/RequestDocumentation.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/request/RequestDocumentation.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/request/RequestDocumentation.java index a893399dc..d17855b49 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/request/RequestDocumentation.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/request/RequestDocumentation.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2016 the original author or authors. + * Copyright 2014-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. From 1572be5b299d2eb661e7d6e4f29d8ba6033da1e2 Mon Sep 17 00:00:00 2001 From: Spring Operator Date: Sat, 16 Mar 2019 11:55:06 -0500 Subject: [PATCH 025/502] Update build configuration to prefer HTTPS See gh-596 --- build.gradle | 4 ++-- gradle/publish-maven.gradle | 4 ++-- samples/rest-notes-spring-data-rest/mvnw | 2 +- samples/rest-notes-spring-data-rest/mvnw.cmd | 2 +- samples/rest-notes-spring-data-rest/pom.xml | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/build.gradle b/build.gradle index 8de250007..2fb54d936 100644 --- a/build.gradle +++ b/build.gradle @@ -37,8 +37,8 @@ sonarqube { ext { springVersion = '4.1.8.RELEASE' javadocLinks = [ - 'http://docs.oracle.com/javase/8/docs/api/', - "http://docs.spring.io/spring-framework/docs/$springVersion/javadoc-api/", + 'https://docs.oracle.com/javase/8/docs/api/', + "https://docs.spring.io/spring-framework/docs/$springVersion/javadoc-api/", 'https://docs.jboss.org/hibernate/stable/beanvalidation/api/' ] as String[] } diff --git a/gradle/publish-maven.gradle b/gradle/publish-maven.gradle index ad2d75058..94b5e564e 100644 --- a/gradle/publish-maven.gradle +++ b/gradle/publish-maven.gradle @@ -15,12 +15,12 @@ def customizePom(pom, gradleProject) { url = "https://github.com/spring-projects/spring-restdocs" organization { name = "Spring IO" - url = "http://projects.spring.io/spring-restdocs" + url = "https://projects.spring.io/spring-restdocs" } licenses { license { name "The Apache Software License, Version 2.0" - url "http://www.apache.org/licenses/LICENSE-2.0.txt" + url "https://www.apache.org/licenses/LICENSE-2.0.txt" distribution "repo" } } diff --git a/samples/rest-notes-spring-data-rest/mvnw b/samples/rest-notes-spring-data-rest/mvnw index fc7efd17d..63fcc8f0f 100755 --- a/samples/rest-notes-spring-data-rest/mvnw +++ b/samples/rest-notes-spring-data-rest/mvnw @@ -8,7 +8,7 @@ # "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 +# https://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 diff --git a/samples/rest-notes-spring-data-rest/mvnw.cmd b/samples/rest-notes-spring-data-rest/mvnw.cmd index 001048081..66e928bd1 100644 --- a/samples/rest-notes-spring-data-rest/mvnw.cmd +++ b/samples/rest-notes-spring-data-rest/mvnw.cmd @@ -7,7 +7,7 @@ @REM "License"); you may not use this file except in compliance @REM with the License. You may obtain a copy of the License at @REM -@REM http://www.apache.org/licenses/LICENSE-2.0 +@REM https://www.apache.org/licenses/LICENSE-2.0 @REM @REM Unless required by applicable law or agreed to in writing, @REM software distributed under the License is distributed on an diff --git a/samples/rest-notes-spring-data-rest/pom.xml b/samples/rest-notes-spring-data-rest/pom.xml index 95427ccbb..2e845ce57 100644 --- a/samples/rest-notes-spring-data-rest/pom.xml +++ b/samples/rest-notes-spring-data-rest/pom.xml @@ -1,6 +1,6 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 com.example From 75132b537a9261bcffc65c00173d2d33c4ffddcc Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Tue, 19 Mar 2019 11:21:34 +0000 Subject: [PATCH 026/502] Use HTTPS to link to Apache license --- README.md | 2 +- .../springframework/restdocs/build/SampleBuildConfigurer.groovy | 2 +- .../org/springframework/restdocs/build/SamplesExtension.groovy | 2 +- .../org/springframework/restdocs/build/SamplesPlugin.groovy | 2 +- config/checkstyle/checkstyle-header.txt | 2 +- docs/src/test/java/com/example/AlwaysDo.java | 2 +- docs/src/test/java/com/example/Constraints.java | 2 +- .../java/com/example/CustomDefaultSnippetsConfiguration.java | 2 +- docs/src/test/java/com/example/CustomEncoding.java | 2 +- docs/src/test/java/com/example/CustomUriConfiguration.java | 2 +- docs/src/test/java/com/example/EveryTestPreprocessing.java | 2 +- docs/src/test/java/com/example/ExampleApplicationTests.java | 2 +- docs/src/test/java/com/example/HttpHeaders.java | 2 +- docs/src/test/java/com/example/Hypermedia.java | 2 +- docs/src/test/java/com/example/InvokeService.java | 2 +- docs/src/test/java/com/example/PathParameters.java | 2 +- docs/src/test/java/com/example/Payload.java | 2 +- docs/src/test/java/com/example/PerTestPreprocessing.java | 2 +- docs/src/test/java/com/example/RequestParameters.java | 2 +- .../src/main/java/com/example/notes/Note.java | 2 +- .../src/main/java/com/example/notes/NoteRepository.java | 2 +- .../main/java/com/example/notes/RestNotesSpringDataRest.java | 2 +- .../src/main/java/com/example/notes/Tag.java | 2 +- .../src/main/java/com/example/notes/TagRepository.java | 2 +- .../src/test/java/com/example/notes/ApiDocumentation.java | 2 +- .../java/com/example/notes/GettingStartedDocumentation.java | 2 +- .../com/example/notes/ExceptionSupressingErrorAttributes.java | 2 +- .../src/main/java/com/example/notes/IndexController.java | 2 +- .../src/main/java/com/example/notes/NestedContentResource.java | 2 +- .../src/main/java/com/example/notes/Note.java | 2 +- .../src/main/java/com/example/notes/NoteInput.java | 2 +- .../src/main/java/com/example/notes/NotePatchInput.java | 2 +- .../src/main/java/com/example/notes/NoteRepository.java | 2 +- .../src/main/java/com/example/notes/NoteResourceAssembler.java | 2 +- .../src/main/java/com/example/notes/NotesController.java | 2 +- .../src/main/java/com/example/notes/NullOrNotBlank.java | 2 +- .../java/com/example/notes/ResourceDoesNotExistException.java | 2 +- .../main/java/com/example/notes/RestNotesControllerAdvice.java | 2 +- .../src/main/java/com/example/notes/RestNotesSpringHateoas.java | 2 +- .../src/main/java/com/example/notes/Tag.java | 2 +- .../src/main/java/com/example/notes/TagInput.java | 2 +- .../src/main/java/com/example/notes/TagPatchInput.java | 2 +- .../src/main/java/com/example/notes/TagRepository.java | 2 +- .../src/main/java/com/example/notes/TagResourceAssembler.java | 2 +- .../src/main/java/com/example/notes/TagsController.java | 2 +- .../src/test/java/com/example/notes/ApiDocumentation.java | 2 +- .../java/com/example/notes/GettingStartedDocumentation.java | 2 +- .../src/test/java/com/example/notes/NullOrNotBlankTests.java | 2 +- .../java/org/springframework/restdocs/RestDocumentation.java | 2 +- .../org/springframework/restdocs/RestDocumentationContext.java | 2 +- .../java/org/springframework/restdocs/config/package-info.java | 2 +- .../org/springframework/restdocs/constraints/Constraint.java | 2 +- .../restdocs/constraints/ConstraintDescriptionResolver.java | 2 +- .../restdocs/constraints/ConstraintDescriptions.java | 2 +- .../restdocs/constraints/ConstraintResolver.java | 2 +- .../ResourceBundleConstraintDescriptionResolver.java | 2 +- .../restdocs/constraints/ValidatorConstraintResolver.java | 2 +- .../org/springframework/restdocs/constraints/package-info.java | 2 +- .../org/springframework/restdocs/curl/CurlDocumentation.java | 2 +- .../org/springframework/restdocs/curl/CurlRequestSnippet.java | 2 +- .../org/springframework/restdocs/curl/QueryStringParser.java | 2 +- .../java/org/springframework/restdocs/curl/package-info.java | 2 +- .../restdocs/headers/AbstractHeadersSnippet.java | 2 +- .../org/springframework/restdocs/headers/HeaderDescriptor.java | 2 +- .../springframework/restdocs/headers/HeaderDocumentation.java | 2 +- .../springframework/restdocs/headers/RequestHeadersSnippet.java | 2 +- .../restdocs/headers/ResponseHeadersSnippet.java | 2 +- .../java/org/springframework/restdocs/headers/package-info.java | 2 +- .../org/springframework/restdocs/http/HttpDocumentation.java | 2 +- .../org/springframework/restdocs/http/HttpRequestSnippet.java | 2 +- .../org/springframework/restdocs/http/HttpResponseSnippet.java | 2 +- .../java/org/springframework/restdocs/http/package-info.java | 2 +- .../restdocs/hypermedia/AbstractJsonLinkExtractor.java | 2 +- .../springframework/restdocs/hypermedia/AtomLinkExtractor.java | 2 +- .../restdocs/hypermedia/ContentTypeLinkExtractor.java | 2 +- .../springframework/restdocs/hypermedia/HalLinkExtractor.java | 2 +- .../restdocs/hypermedia/HypermediaDocumentation.java | 2 +- .../main/java/org/springframework/restdocs/hypermedia/Link.java | 2 +- .../org/springframework/restdocs/hypermedia/LinkDescriptor.java | 2 +- .../org/springframework/restdocs/hypermedia/LinkExtractor.java | 2 +- .../org/springframework/restdocs/hypermedia/LinksSnippet.java | 2 +- .../org/springframework/restdocs/hypermedia/package-info.java | 2 +- .../restdocs/operation/AbstractOperationMessage.java | 2 +- .../springframework/restdocs/operation/HttpHeadersHelper.java | 2 +- .../java/org/springframework/restdocs/operation/Operation.java | 2 +- .../springframework/restdocs/operation/OperationRequest.java | 2 +- .../restdocs/operation/OperationRequestFactory.java | 2 +- .../restdocs/operation/OperationRequestPart.java | 2 +- .../restdocs/operation/OperationRequestPartFactory.java | 2 +- .../springframework/restdocs/operation/OperationResponse.java | 2 +- .../restdocs/operation/OperationResponseFactory.java | 2 +- .../java/org/springframework/restdocs/operation/Parameters.java | 2 +- .../springframework/restdocs/operation/StandardOperation.java | 2 +- .../restdocs/operation/StandardOperationRequest.java | 2 +- .../restdocs/operation/StandardOperationRequestPart.java | 2 +- .../restdocs/operation/StandardOperationResponse.java | 2 +- .../org/springframework/restdocs/operation/package-info.java | 2 +- .../restdocs/operation/preprocess/ContentModifier.java | 2 +- .../preprocess/ContentModifyingOperationPreprocessor.java | 2 +- .../preprocess/DelegatingOperationRequestPreprocessor.java | 2 +- .../preprocess/DelegatingOperationResponsePreprocessor.java | 2 +- .../preprocess/HeaderRemovingOperationPreprocessor.java | 2 +- .../operation/preprocess/LinkMaskingContentModifier.java | 2 +- .../restdocs/operation/preprocess/OperationPreprocessor.java | 2 +- .../operation/preprocess/OperationRequestPreprocessor.java | 2 +- .../operation/preprocess/OperationResponsePreprocessor.java | 2 +- .../operation/preprocess/PatternReplacingContentModifier.java | 2 +- .../restdocs/operation/preprocess/Preprocessors.java | 2 +- .../operation/preprocess/PrettyPrintingContentModifier.java | 2 +- .../restdocs/operation/preprocess/package-info.java | 2 +- .../main/java/org/springframework/restdocs/package-info.java | 2 +- .../springframework/restdocs/payload/AbstractFieldsSnippet.java | 2 +- .../org/springframework/restdocs/payload/ContentHandler.java | 2 +- .../org/springframework/restdocs/payload/FieldDescriptor.java | 2 +- .../restdocs/payload/FieldDoesNotExistException.java | 2 +- .../restdocs/payload/FieldTypeRequiredException.java | 2 +- .../springframework/restdocs/payload/JsonContentHandler.java | 2 +- .../org/springframework/restdocs/payload/JsonFieldPath.java | 2 +- .../springframework/restdocs/payload/JsonFieldProcessor.java | 2 +- .../org/springframework/restdocs/payload/JsonFieldType.java | 2 +- .../springframework/restdocs/payload/JsonFieldTypeResolver.java | 2 +- .../springframework/restdocs/payload/PayloadDocumentation.java | 2 +- .../restdocs/payload/PayloadHandlingException.java | 2 +- .../springframework/restdocs/payload/RequestFieldsSnippet.java | 2 +- .../springframework/restdocs/payload/ResponseFieldsSnippet.java | 2 +- .../org/springframework/restdocs/payload/XmlContentHandler.java | 2 +- .../java/org/springframework/restdocs/payload/package-info.java | 2 +- .../restdocs/request/AbstractParametersSnippet.java | 2 +- .../springframework/restdocs/request/ParameterDescriptor.java | 2 +- .../springframework/restdocs/request/PathParametersSnippet.java | 2 +- .../springframework/restdocs/request/RequestDocumentation.java | 2 +- .../restdocs/request/RequestParametersSnippet.java | 2 +- .../java/org/springframework/restdocs/request/package-info.java | 2 +- .../springframework/restdocs/snippet/AbstractDescriptor.java | 2 +- .../java/org/springframework/restdocs/snippet/Attributes.java | 2 +- .../springframework/restdocs/snippet/IgnorableDescriptor.java | 2 +- .../restdocs/snippet/ModelCreationException.java | 2 +- .../snippet/RestDocumentationContextPlaceholderResolver.java | 2 +- .../main/java/org/springframework/restdocs/snippet/Snippet.java | 2 +- .../org/springframework/restdocs/snippet/SnippetException.java | 2 +- .../restdocs/snippet/StandardWriterResolver.java | 2 +- .../org/springframework/restdocs/snippet/TemplatedSnippet.java | 2 +- .../org/springframework/restdocs/snippet/WriterResolver.java | 2 +- .../java/org/springframework/restdocs/snippet/package-info.java | 2 +- .../restdocs/templates/StandardTemplateResourceResolver.java | 2 +- .../java/org/springframework/restdocs/templates/Template.java | 2 +- .../org/springframework/restdocs/templates/TemplateEngine.java | 2 +- .../restdocs/templates/TemplateResourceResolver.java | 2 +- .../restdocs/templates/mustache/MustacheTemplate.java | 2 +- .../restdocs/templates/mustache/MustacheTemplateEngine.java | 2 +- .../restdocs/templates/mustache/package-info.java | 2 +- .../org/springframework/restdocs/templates/package-info.java | 2 +- .../restdocs/constraints/ConstraintDescriptionsTests.java | 2 +- .../ResourceBundleConstraintDescriptionResolverTests.java | 2 +- .../restdocs/constraints/ValidatorConstraintResolverTests.java | 2 +- .../springframework/restdocs/curl/CurlRequestSnippetTests.java | 2 +- .../springframework/restdocs/curl/QueryStringParserTests.java | 2 +- .../restdocs/headers/RequestHeadersSnippetTests.java | 2 +- .../restdocs/headers/ResponseHeadersSnippetTests.java | 2 +- .../springframework/restdocs/http/HttpRequestSnippetTests.java | 2 +- .../springframework/restdocs/http/HttpResponseSnippetTests.java | 2 +- .../restdocs/hypermedia/ContentTypeLinkExtractorTests.java | 2 +- .../restdocs/hypermedia/LinkExtractorsPayloadTests.java | 2 +- .../springframework/restdocs/hypermedia/LinksSnippetTests.java | 2 +- .../preprocess/ContentModifyingOperationPreprocessorTests.java | 2 +- .../preprocess/DelegatingOperationRequestPreprocessorTests.java | 2 +- .../DelegatingOperationResponsePreprocessorTests.java | 2 +- .../preprocess/HeaderRemovingOperationPreprocessorTests.java | 2 +- .../operation/preprocess/LinkMaskingContentModifierTests.java | 2 +- .../preprocess/PatternReplacingContentModifierTests.java | 2 +- .../preprocess/PrettyPrintingContentModifierTests.java | 2 +- .../springframework/restdocs/payload/JsonFieldPathTests.java | 2 +- .../restdocs/payload/JsonFieldProcessorTests.java | 2 +- .../restdocs/payload/JsonFieldTypeResolverTests.java | 2 +- .../restdocs/payload/RequestFieldsSnippetTests.java | 2 +- .../restdocs/payload/ResponseFieldsSnippetTests.java | 2 +- .../restdocs/request/PathParametersSnippetTests.java | 2 +- .../restdocs/request/RequestParametersSnippetTests.java | 2 +- .../RestDocumentationContextPlaceholderResolverTests.java | 2 +- .../restdocs/snippet/StandardWriterResolverTests.java | 2 +- .../springframework/restdocs/snippet/TemplatedSnippetTests.java | 2 +- .../templates/StandardTemplateResourceResolverTests.java | 2 +- .../java/org/springframework/restdocs/test/ExpectedSnippet.java | 2 +- .../org/springframework/restdocs/test/OperationBuilder.java | 2 +- .../java/org/springframework/restdocs/test/OutputCapture.java | 2 +- .../java/org/springframework/restdocs/test/SnippetMatchers.java | 2 +- .../springframework/restdocs/mockmvc/AbstractConfigurer.java | 2 +- .../restdocs/mockmvc/AbstractNestedConfigurer.java | 2 +- .../springframework/restdocs/mockmvc/IterableEnumeration.java | 2 +- .../restdocs/mockmvc/MockMvcOperationRequestFactory.java | 2 +- .../restdocs/mockmvc/MockMvcOperationResponseFactory.java | 2 +- .../restdocs/mockmvc/MockMvcRestDocumentation.java | 2 +- .../org/springframework/restdocs/mockmvc/NestedConfigurer.java | 2 +- .../restdocs/mockmvc/RestDocumentationMockMvcConfigurer.java | 2 +- .../restdocs/mockmvc/RestDocumentationRequestBuilders.java | 2 +- .../restdocs/mockmvc/RestDocumentationResultHandler.java | 2 +- .../org/springframework/restdocs/mockmvc/SnippetConfigurer.java | 2 +- .../org/springframework/restdocs/mockmvc/UriConfigurer.java | 2 +- .../java/org/springframework/restdocs/mockmvc/package-info.java | 2 +- .../restdocs/mockmvc/MockMvcOperationRequestFactoryTests.java | 2 +- .../mockmvc/MockMvcRestDocumentationIntegrationTests.java | 2 +- .../restdocs/mockmvc/RestDocumentationConfigurerTests.java | 2 +- .../restdocs/mockmvc/RestDocumentationRequestBuildersTests.java | 2 +- .../restdocs/mockmvc/RestDocumentationResultHandlerTests.java | 2 +- 204 files changed, 204 insertions(+), 204 deletions(-) diff --git a/README.md b/README.md index aaa0c6dcc..3d715d1d3 100644 --- a/README.md +++ b/README.md @@ -45,5 +45,5 @@ Spring REST Docs is open source software released under the [Apache 2.0 license] [11]: CODE_OF_CONDUCT.md [12]: https://help.github.com/articles/using-pull-requests/ [13]: CONTRIBUTING.md -[14]: http://www.apache.org/licenses/LICENSE-2.0.html +[14]: https://www.apache.org/licenses/LICENSE-2.0.html diff --git a/buildSrc/src/main/groovy/org/springframework/restdocs/build/SampleBuildConfigurer.groovy b/buildSrc/src/main/groovy/org/springframework/restdocs/build/SampleBuildConfigurer.groovy index 5ddd17ab1..437216d8f 100644 --- a/buildSrc/src/main/groovy/org/springframework/restdocs/build/SampleBuildConfigurer.groovy +++ b/buildSrc/src/main/groovy/org/springframework/restdocs/build/SampleBuildConfigurer.groovy @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/buildSrc/src/main/groovy/org/springframework/restdocs/build/SamplesExtension.groovy b/buildSrc/src/main/groovy/org/springframework/restdocs/build/SamplesExtension.groovy index c86a3104a..3a409801f 100644 --- a/buildSrc/src/main/groovy/org/springframework/restdocs/build/SamplesExtension.groovy +++ b/buildSrc/src/main/groovy/org/springframework/restdocs/build/SamplesExtension.groovy @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/buildSrc/src/main/groovy/org/springframework/restdocs/build/SamplesPlugin.groovy b/buildSrc/src/main/groovy/org/springframework/restdocs/build/SamplesPlugin.groovy index 09af86d80..ca3cf49d4 100644 --- a/buildSrc/src/main/groovy/org/springframework/restdocs/build/SamplesPlugin.groovy +++ b/buildSrc/src/main/groovy/org/springframework/restdocs/build/SamplesPlugin.groovy @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/config/checkstyle/checkstyle-header.txt b/config/checkstyle/checkstyle-header.txt index 154aaa1a6..39429ee64 100644 --- a/config/checkstyle/checkstyle-header.txt +++ b/config/checkstyle/checkstyle-header.txt @@ -5,7 +5,7 @@ ^\Q * you may not use this file except in compliance with the License.\E$ ^\Q * You may obtain a copy of the License at\E$ ^\Q *\E$ -^\Q * http://www.apache.org/licenses/LICENSE-2.0\E$ +^\Q * https://www.apache.org/licenses/LICENSE-2.0\E$ ^\Q *\E$ ^\Q * Unless required by applicable law or agreed to in writing, software\E$ ^\Q * distributed under the License is distributed on an "AS IS" BASIS,\E$ diff --git a/docs/src/test/java/com/example/AlwaysDo.java b/docs/src/test/java/com/example/AlwaysDo.java index efc64f6c7..9444caa4b 100644 --- a/docs/src/test/java/com/example/AlwaysDo.java +++ b/docs/src/test/java/com/example/AlwaysDo.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/docs/src/test/java/com/example/Constraints.java b/docs/src/test/java/com/example/Constraints.java index 5bcea8595..70b88037a 100644 --- a/docs/src/test/java/com/example/Constraints.java +++ b/docs/src/test/java/com/example/Constraints.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/docs/src/test/java/com/example/CustomDefaultSnippetsConfiguration.java b/docs/src/test/java/com/example/CustomDefaultSnippetsConfiguration.java index a964c9646..6ec28aa24 100644 --- a/docs/src/test/java/com/example/CustomDefaultSnippetsConfiguration.java +++ b/docs/src/test/java/com/example/CustomDefaultSnippetsConfiguration.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/docs/src/test/java/com/example/CustomEncoding.java b/docs/src/test/java/com/example/CustomEncoding.java index 4490e8a4d..f6af4cc13 100644 --- a/docs/src/test/java/com/example/CustomEncoding.java +++ b/docs/src/test/java/com/example/CustomEncoding.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/docs/src/test/java/com/example/CustomUriConfiguration.java b/docs/src/test/java/com/example/CustomUriConfiguration.java index b70d4e08e..bfc3fe8a3 100644 --- a/docs/src/test/java/com/example/CustomUriConfiguration.java +++ b/docs/src/test/java/com/example/CustomUriConfiguration.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/docs/src/test/java/com/example/EveryTestPreprocessing.java b/docs/src/test/java/com/example/EveryTestPreprocessing.java index b189f8ffd..5b0f93fc8 100644 --- a/docs/src/test/java/com/example/EveryTestPreprocessing.java +++ b/docs/src/test/java/com/example/EveryTestPreprocessing.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/docs/src/test/java/com/example/ExampleApplicationTests.java b/docs/src/test/java/com/example/ExampleApplicationTests.java index 70fb8e188..76bceac77 100644 --- a/docs/src/test/java/com/example/ExampleApplicationTests.java +++ b/docs/src/test/java/com/example/ExampleApplicationTests.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/docs/src/test/java/com/example/HttpHeaders.java b/docs/src/test/java/com/example/HttpHeaders.java index f47e39714..10e18b71d 100644 --- a/docs/src/test/java/com/example/HttpHeaders.java +++ b/docs/src/test/java/com/example/HttpHeaders.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/docs/src/test/java/com/example/Hypermedia.java b/docs/src/test/java/com/example/Hypermedia.java index 3cf6c1bcf..fbd073cd2 100644 --- a/docs/src/test/java/com/example/Hypermedia.java +++ b/docs/src/test/java/com/example/Hypermedia.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/docs/src/test/java/com/example/InvokeService.java b/docs/src/test/java/com/example/InvokeService.java index 097899f2b..66b79478f 100644 --- a/docs/src/test/java/com/example/InvokeService.java +++ b/docs/src/test/java/com/example/InvokeService.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/docs/src/test/java/com/example/PathParameters.java b/docs/src/test/java/com/example/PathParameters.java index c78105986..57861cac6 100644 --- a/docs/src/test/java/com/example/PathParameters.java +++ b/docs/src/test/java/com/example/PathParameters.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/docs/src/test/java/com/example/Payload.java b/docs/src/test/java/com/example/Payload.java index 5ee1a8902..58e06f8ac 100644 --- a/docs/src/test/java/com/example/Payload.java +++ b/docs/src/test/java/com/example/Payload.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/docs/src/test/java/com/example/PerTestPreprocessing.java b/docs/src/test/java/com/example/PerTestPreprocessing.java index 504f96c09..17822a2dc 100644 --- a/docs/src/test/java/com/example/PerTestPreprocessing.java +++ b/docs/src/test/java/com/example/PerTestPreprocessing.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/docs/src/test/java/com/example/RequestParameters.java b/docs/src/test/java/com/example/RequestParameters.java index 5a314958c..72cff69f5 100644 --- a/docs/src/test/java/com/example/RequestParameters.java +++ b/docs/src/test/java/com/example/RequestParameters.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/samples/rest-notes-spring-data-rest/src/main/java/com/example/notes/Note.java b/samples/rest-notes-spring-data-rest/src/main/java/com/example/notes/Note.java index d5211b858..5160682a3 100644 --- a/samples/rest-notes-spring-data-rest/src/main/java/com/example/notes/Note.java +++ b/samples/rest-notes-spring-data-rest/src/main/java/com/example/notes/Note.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/samples/rest-notes-spring-data-rest/src/main/java/com/example/notes/NoteRepository.java b/samples/rest-notes-spring-data-rest/src/main/java/com/example/notes/NoteRepository.java index 71cd9ad07..ba6dd5fb3 100644 --- a/samples/rest-notes-spring-data-rest/src/main/java/com/example/notes/NoteRepository.java +++ b/samples/rest-notes-spring-data-rest/src/main/java/com/example/notes/NoteRepository.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/samples/rest-notes-spring-data-rest/src/main/java/com/example/notes/RestNotesSpringDataRest.java b/samples/rest-notes-spring-data-rest/src/main/java/com/example/notes/RestNotesSpringDataRest.java index 74b98dd0c..f45cefa75 100644 --- a/samples/rest-notes-spring-data-rest/src/main/java/com/example/notes/RestNotesSpringDataRest.java +++ b/samples/rest-notes-spring-data-rest/src/main/java/com/example/notes/RestNotesSpringDataRest.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/samples/rest-notes-spring-data-rest/src/main/java/com/example/notes/Tag.java b/samples/rest-notes-spring-data-rest/src/main/java/com/example/notes/Tag.java index 970b642f4..8bd834f98 100644 --- a/samples/rest-notes-spring-data-rest/src/main/java/com/example/notes/Tag.java +++ b/samples/rest-notes-spring-data-rest/src/main/java/com/example/notes/Tag.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/samples/rest-notes-spring-data-rest/src/main/java/com/example/notes/TagRepository.java b/samples/rest-notes-spring-data-rest/src/main/java/com/example/notes/TagRepository.java index 8790619bb..96ad37917 100644 --- a/samples/rest-notes-spring-data-rest/src/main/java/com/example/notes/TagRepository.java +++ b/samples/rest-notes-spring-data-rest/src/main/java/com/example/notes/TagRepository.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/samples/rest-notes-spring-data-rest/src/test/java/com/example/notes/ApiDocumentation.java b/samples/rest-notes-spring-data-rest/src/test/java/com/example/notes/ApiDocumentation.java index 51581811d..4eda380e7 100644 --- a/samples/rest-notes-spring-data-rest/src/test/java/com/example/notes/ApiDocumentation.java +++ b/samples/rest-notes-spring-data-rest/src/test/java/com/example/notes/ApiDocumentation.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/samples/rest-notes-spring-data-rest/src/test/java/com/example/notes/GettingStartedDocumentation.java b/samples/rest-notes-spring-data-rest/src/test/java/com/example/notes/GettingStartedDocumentation.java index 3770023ba..15e2ab1fb 100644 --- a/samples/rest-notes-spring-data-rest/src/test/java/com/example/notes/GettingStartedDocumentation.java +++ b/samples/rest-notes-spring-data-rest/src/test/java/com/example/notes/GettingStartedDocumentation.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/samples/rest-notes-spring-hateoas/src/main/java/com/example/notes/ExceptionSupressingErrorAttributes.java b/samples/rest-notes-spring-hateoas/src/main/java/com/example/notes/ExceptionSupressingErrorAttributes.java index e8abbe594..158d2319f 100644 --- a/samples/rest-notes-spring-hateoas/src/main/java/com/example/notes/ExceptionSupressingErrorAttributes.java +++ b/samples/rest-notes-spring-hateoas/src/main/java/com/example/notes/ExceptionSupressingErrorAttributes.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/samples/rest-notes-spring-hateoas/src/main/java/com/example/notes/IndexController.java b/samples/rest-notes-spring-hateoas/src/main/java/com/example/notes/IndexController.java index b8e882b5a..bd3e61810 100644 --- a/samples/rest-notes-spring-hateoas/src/main/java/com/example/notes/IndexController.java +++ b/samples/rest-notes-spring-hateoas/src/main/java/com/example/notes/IndexController.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/samples/rest-notes-spring-hateoas/src/main/java/com/example/notes/NestedContentResource.java b/samples/rest-notes-spring-hateoas/src/main/java/com/example/notes/NestedContentResource.java index 00a61ee8a..4294eed1b 100644 --- a/samples/rest-notes-spring-hateoas/src/main/java/com/example/notes/NestedContentResource.java +++ b/samples/rest-notes-spring-hateoas/src/main/java/com/example/notes/NestedContentResource.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/samples/rest-notes-spring-hateoas/src/main/java/com/example/notes/Note.java b/samples/rest-notes-spring-hateoas/src/main/java/com/example/notes/Note.java index 412b34e04..a4f037ada 100644 --- a/samples/rest-notes-spring-hateoas/src/main/java/com/example/notes/Note.java +++ b/samples/rest-notes-spring-hateoas/src/main/java/com/example/notes/Note.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/samples/rest-notes-spring-hateoas/src/main/java/com/example/notes/NoteInput.java b/samples/rest-notes-spring-hateoas/src/main/java/com/example/notes/NoteInput.java index 27b04f7b5..9afe3b39e 100644 --- a/samples/rest-notes-spring-hateoas/src/main/java/com/example/notes/NoteInput.java +++ b/samples/rest-notes-spring-hateoas/src/main/java/com/example/notes/NoteInput.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/samples/rest-notes-spring-hateoas/src/main/java/com/example/notes/NotePatchInput.java b/samples/rest-notes-spring-hateoas/src/main/java/com/example/notes/NotePatchInput.java index 62e07d012..b163e673e 100644 --- a/samples/rest-notes-spring-hateoas/src/main/java/com/example/notes/NotePatchInput.java +++ b/samples/rest-notes-spring-hateoas/src/main/java/com/example/notes/NotePatchInput.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/samples/rest-notes-spring-hateoas/src/main/java/com/example/notes/NoteRepository.java b/samples/rest-notes-spring-hateoas/src/main/java/com/example/notes/NoteRepository.java index 87c0a72f3..ac781323c 100644 --- a/samples/rest-notes-spring-hateoas/src/main/java/com/example/notes/NoteRepository.java +++ b/samples/rest-notes-spring-hateoas/src/main/java/com/example/notes/NoteRepository.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/samples/rest-notes-spring-hateoas/src/main/java/com/example/notes/NoteResourceAssembler.java b/samples/rest-notes-spring-hateoas/src/main/java/com/example/notes/NoteResourceAssembler.java index a78626dfa..4a7f5108e 100644 --- a/samples/rest-notes-spring-hateoas/src/main/java/com/example/notes/NoteResourceAssembler.java +++ b/samples/rest-notes-spring-hateoas/src/main/java/com/example/notes/NoteResourceAssembler.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/samples/rest-notes-spring-hateoas/src/main/java/com/example/notes/NotesController.java b/samples/rest-notes-spring-hateoas/src/main/java/com/example/notes/NotesController.java index 0eccb0e24..e47020a9a 100644 --- a/samples/rest-notes-spring-hateoas/src/main/java/com/example/notes/NotesController.java +++ b/samples/rest-notes-spring-hateoas/src/main/java/com/example/notes/NotesController.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/samples/rest-notes-spring-hateoas/src/main/java/com/example/notes/NullOrNotBlank.java b/samples/rest-notes-spring-hateoas/src/main/java/com/example/notes/NullOrNotBlank.java index 7421a0ea0..c336ff6a0 100644 --- a/samples/rest-notes-spring-hateoas/src/main/java/com/example/notes/NullOrNotBlank.java +++ b/samples/rest-notes-spring-hateoas/src/main/java/com/example/notes/NullOrNotBlank.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/samples/rest-notes-spring-hateoas/src/main/java/com/example/notes/ResourceDoesNotExistException.java b/samples/rest-notes-spring-hateoas/src/main/java/com/example/notes/ResourceDoesNotExistException.java index a3de9e547..03e23e746 100644 --- a/samples/rest-notes-spring-hateoas/src/main/java/com/example/notes/ResourceDoesNotExistException.java +++ b/samples/rest-notes-spring-hateoas/src/main/java/com/example/notes/ResourceDoesNotExistException.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/samples/rest-notes-spring-hateoas/src/main/java/com/example/notes/RestNotesControllerAdvice.java b/samples/rest-notes-spring-hateoas/src/main/java/com/example/notes/RestNotesControllerAdvice.java index a8b1c0f7f..e621709e5 100644 --- a/samples/rest-notes-spring-hateoas/src/main/java/com/example/notes/RestNotesControllerAdvice.java +++ b/samples/rest-notes-spring-hateoas/src/main/java/com/example/notes/RestNotesControllerAdvice.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/samples/rest-notes-spring-hateoas/src/main/java/com/example/notes/RestNotesSpringHateoas.java b/samples/rest-notes-spring-hateoas/src/main/java/com/example/notes/RestNotesSpringHateoas.java index c51ecee0d..473fbfd98 100644 --- a/samples/rest-notes-spring-hateoas/src/main/java/com/example/notes/RestNotesSpringHateoas.java +++ b/samples/rest-notes-spring-hateoas/src/main/java/com/example/notes/RestNotesSpringHateoas.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/samples/rest-notes-spring-hateoas/src/main/java/com/example/notes/Tag.java b/samples/rest-notes-spring-hateoas/src/main/java/com/example/notes/Tag.java index 69807d519..f721fcb50 100644 --- a/samples/rest-notes-spring-hateoas/src/main/java/com/example/notes/Tag.java +++ b/samples/rest-notes-spring-hateoas/src/main/java/com/example/notes/Tag.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/samples/rest-notes-spring-hateoas/src/main/java/com/example/notes/TagInput.java b/samples/rest-notes-spring-hateoas/src/main/java/com/example/notes/TagInput.java index 2df23e5fd..37bb3012a 100644 --- a/samples/rest-notes-spring-hateoas/src/main/java/com/example/notes/TagInput.java +++ b/samples/rest-notes-spring-hateoas/src/main/java/com/example/notes/TagInput.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/samples/rest-notes-spring-hateoas/src/main/java/com/example/notes/TagPatchInput.java b/samples/rest-notes-spring-hateoas/src/main/java/com/example/notes/TagPatchInput.java index ba5b2fad0..b392492a5 100644 --- a/samples/rest-notes-spring-hateoas/src/main/java/com/example/notes/TagPatchInput.java +++ b/samples/rest-notes-spring-hateoas/src/main/java/com/example/notes/TagPatchInput.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/samples/rest-notes-spring-hateoas/src/main/java/com/example/notes/TagRepository.java b/samples/rest-notes-spring-hateoas/src/main/java/com/example/notes/TagRepository.java index c92d9e238..6bc9fc3cb 100644 --- a/samples/rest-notes-spring-hateoas/src/main/java/com/example/notes/TagRepository.java +++ b/samples/rest-notes-spring-hateoas/src/main/java/com/example/notes/TagRepository.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/samples/rest-notes-spring-hateoas/src/main/java/com/example/notes/TagResourceAssembler.java b/samples/rest-notes-spring-hateoas/src/main/java/com/example/notes/TagResourceAssembler.java index c11d79159..45d881799 100644 --- a/samples/rest-notes-spring-hateoas/src/main/java/com/example/notes/TagResourceAssembler.java +++ b/samples/rest-notes-spring-hateoas/src/main/java/com/example/notes/TagResourceAssembler.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/samples/rest-notes-spring-hateoas/src/main/java/com/example/notes/TagsController.java b/samples/rest-notes-spring-hateoas/src/main/java/com/example/notes/TagsController.java index bc22f0661..fcf09f73f 100644 --- a/samples/rest-notes-spring-hateoas/src/main/java/com/example/notes/TagsController.java +++ b/samples/rest-notes-spring-hateoas/src/main/java/com/example/notes/TagsController.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/samples/rest-notes-spring-hateoas/src/test/java/com/example/notes/ApiDocumentation.java b/samples/rest-notes-spring-hateoas/src/test/java/com/example/notes/ApiDocumentation.java index 4da12b336..a0166eda0 100644 --- a/samples/rest-notes-spring-hateoas/src/test/java/com/example/notes/ApiDocumentation.java +++ b/samples/rest-notes-spring-hateoas/src/test/java/com/example/notes/ApiDocumentation.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/samples/rest-notes-spring-hateoas/src/test/java/com/example/notes/GettingStartedDocumentation.java b/samples/rest-notes-spring-hateoas/src/test/java/com/example/notes/GettingStartedDocumentation.java index 60ba09692..d17b80713 100644 --- a/samples/rest-notes-spring-hateoas/src/test/java/com/example/notes/GettingStartedDocumentation.java +++ b/samples/rest-notes-spring-hateoas/src/test/java/com/example/notes/GettingStartedDocumentation.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/samples/rest-notes-spring-hateoas/src/test/java/com/example/notes/NullOrNotBlankTests.java b/samples/rest-notes-spring-hateoas/src/test/java/com/example/notes/NullOrNotBlankTests.java index 24d9e85ad..b4f2f5977 100644 --- a/samples/rest-notes-spring-hateoas/src/test/java/com/example/notes/NullOrNotBlankTests.java +++ b/samples/rest-notes-spring-hateoas/src/test/java/com/example/notes/NullOrNotBlankTests.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/RestDocumentation.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/RestDocumentation.java index 401b67139..703b508a8 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/RestDocumentation.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/RestDocumentation.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/RestDocumentationContext.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/RestDocumentationContext.java index 86dbf6c8e..a40bae9cb 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/RestDocumentationContext.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/RestDocumentationContext.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/config/package-info.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/config/package-info.java index 1b4a13e01..0c92c51e0 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/config/package-info.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/config/package-info.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/constraints/Constraint.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/constraints/Constraint.java index 31a3fd51f..d8cf77471 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/constraints/Constraint.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/constraints/Constraint.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/constraints/ConstraintDescriptionResolver.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/constraints/ConstraintDescriptionResolver.java index 2bd63472f..7fa30ecef 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/constraints/ConstraintDescriptionResolver.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/constraints/ConstraintDescriptionResolver.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/constraints/ConstraintDescriptions.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/constraints/ConstraintDescriptions.java index c55857980..548dd1634 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/constraints/ConstraintDescriptions.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/constraints/ConstraintDescriptions.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/constraints/ConstraintResolver.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/constraints/ConstraintResolver.java index ed5ce37aa..ee6e7292a 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/constraints/ConstraintResolver.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/constraints/ConstraintResolver.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/constraints/ResourceBundleConstraintDescriptionResolver.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/constraints/ResourceBundleConstraintDescriptionResolver.java index 759950a64..bdf898a69 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/constraints/ResourceBundleConstraintDescriptionResolver.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/constraints/ResourceBundleConstraintDescriptionResolver.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/constraints/ValidatorConstraintResolver.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/constraints/ValidatorConstraintResolver.java index 531157b2a..9dc82b9b0 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/constraints/ValidatorConstraintResolver.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/constraints/ValidatorConstraintResolver.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/constraints/package-info.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/constraints/package-info.java index fb1e842ec..66adf0a6f 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/constraints/package-info.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/constraints/package-info.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/curl/CurlDocumentation.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/curl/CurlDocumentation.java index a3549443b..c49fbe4da 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/curl/CurlDocumentation.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/curl/CurlDocumentation.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/curl/CurlRequestSnippet.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/curl/CurlRequestSnippet.java index 50764ecde..bed72f3c3 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/curl/CurlRequestSnippet.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/curl/CurlRequestSnippet.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/curl/QueryStringParser.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/curl/QueryStringParser.java index ea5f31481..43d160032 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/curl/QueryStringParser.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/curl/QueryStringParser.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/curl/package-info.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/curl/package-info.java index 7c07b91e0..87e4f08c5 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/curl/package-info.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/curl/package-info.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/headers/AbstractHeadersSnippet.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/headers/AbstractHeadersSnippet.java index 223913567..95f5ed7ea 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/headers/AbstractHeadersSnippet.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/headers/AbstractHeadersSnippet.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/headers/HeaderDescriptor.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/headers/HeaderDescriptor.java index b0e332abf..0719d3464 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/headers/HeaderDescriptor.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/headers/HeaderDescriptor.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/headers/HeaderDocumentation.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/headers/HeaderDocumentation.java index 85800ecff..3eca8b57b 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/headers/HeaderDocumentation.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/headers/HeaderDocumentation.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/headers/RequestHeadersSnippet.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/headers/RequestHeadersSnippet.java index 83dd6b6d5..29207d294 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/headers/RequestHeadersSnippet.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/headers/RequestHeadersSnippet.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/headers/ResponseHeadersSnippet.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/headers/ResponseHeadersSnippet.java index 979083c42..ce20cbdfe 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/headers/ResponseHeadersSnippet.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/headers/ResponseHeadersSnippet.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/headers/package-info.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/headers/package-info.java index f27ba176c..bbc63a954 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/headers/package-info.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/headers/package-info.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/http/HttpDocumentation.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/http/HttpDocumentation.java index f1bc8b389..1c7c650c9 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/http/HttpDocumentation.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/http/HttpDocumentation.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/http/HttpRequestSnippet.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/http/HttpRequestSnippet.java index cd855f7be..5249711a0 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/http/HttpRequestSnippet.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/http/HttpRequestSnippet.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/http/HttpResponseSnippet.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/http/HttpResponseSnippet.java index c9fd1f718..46807070a 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/http/HttpResponseSnippet.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/http/HttpResponseSnippet.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/http/package-info.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/http/package-info.java index da609abbe..c2f8d4f53 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/http/package-info.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/http/package-info.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/hypermedia/AbstractJsonLinkExtractor.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/hypermedia/AbstractJsonLinkExtractor.java index a345cd2de..a15d69fea 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/hypermedia/AbstractJsonLinkExtractor.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/hypermedia/AbstractJsonLinkExtractor.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/hypermedia/AtomLinkExtractor.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/hypermedia/AtomLinkExtractor.java index ad12497a3..aaf8ff4d1 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/hypermedia/AtomLinkExtractor.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/hypermedia/AtomLinkExtractor.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/hypermedia/ContentTypeLinkExtractor.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/hypermedia/ContentTypeLinkExtractor.java index ec36eb63d..b1f0673fd 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/hypermedia/ContentTypeLinkExtractor.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/hypermedia/ContentTypeLinkExtractor.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/hypermedia/HalLinkExtractor.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/hypermedia/HalLinkExtractor.java index eb55843aa..7a34ee8a2 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/hypermedia/HalLinkExtractor.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/hypermedia/HalLinkExtractor.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/hypermedia/HypermediaDocumentation.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/hypermedia/HypermediaDocumentation.java index d5ddaf0b4..937dbbc8e 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/hypermedia/HypermediaDocumentation.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/hypermedia/HypermediaDocumentation.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/hypermedia/Link.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/hypermedia/Link.java index 5e8a34f3b..46f4111e3 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/hypermedia/Link.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/hypermedia/Link.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/hypermedia/LinkDescriptor.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/hypermedia/LinkDescriptor.java index 8876cf7de..0b2cc7a01 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/hypermedia/LinkDescriptor.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/hypermedia/LinkDescriptor.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/hypermedia/LinkExtractor.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/hypermedia/LinkExtractor.java index 747731d6d..be05e0f24 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/hypermedia/LinkExtractor.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/hypermedia/LinkExtractor.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/hypermedia/LinksSnippet.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/hypermedia/LinksSnippet.java index 771e2e7a8..1abbaaa9b 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/hypermedia/LinksSnippet.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/hypermedia/LinksSnippet.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/hypermedia/package-info.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/hypermedia/package-info.java index 0d3ad26d2..d42d90770 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/hypermedia/package-info.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/hypermedia/package-info.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/AbstractOperationMessage.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/AbstractOperationMessage.java index 41e8fec3e..f69279de6 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/AbstractOperationMessage.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/AbstractOperationMessage.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/HttpHeadersHelper.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/HttpHeadersHelper.java index a9cb7c5a0..240b4f6d8 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/HttpHeadersHelper.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/HttpHeadersHelper.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/Operation.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/Operation.java index a00533639..3c5792bcb 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/Operation.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/Operation.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/OperationRequest.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/OperationRequest.java index 29153eec6..0c3b02cc2 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/OperationRequest.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/OperationRequest.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/OperationRequestFactory.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/OperationRequestFactory.java index c105fd75c..ab22e0c3b 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/OperationRequestFactory.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/OperationRequestFactory.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/OperationRequestPart.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/OperationRequestPart.java index 13cb8ed06..f99057167 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/OperationRequestPart.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/OperationRequestPart.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/OperationRequestPartFactory.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/OperationRequestPartFactory.java index 47aa7e431..f72a721a6 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/OperationRequestPartFactory.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/OperationRequestPartFactory.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/OperationResponse.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/OperationResponse.java index 6a5186791..212225083 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/OperationResponse.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/OperationResponse.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/OperationResponseFactory.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/OperationResponseFactory.java index 1cfd1434a..3a1f8b86c 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/OperationResponseFactory.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/OperationResponseFactory.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/Parameters.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/Parameters.java index 0235ec800..7a44a1647 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/Parameters.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/Parameters.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/StandardOperation.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/StandardOperation.java index 736fc4b5a..f39751ad2 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/StandardOperation.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/StandardOperation.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/StandardOperationRequest.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/StandardOperationRequest.java index a09bd645f..c12c58544 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/StandardOperationRequest.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/StandardOperationRequest.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/StandardOperationRequestPart.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/StandardOperationRequestPart.java index e9fee9d75..825e1c962 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/StandardOperationRequestPart.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/StandardOperationRequestPart.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/StandardOperationResponse.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/StandardOperationResponse.java index 0131a4b5a..2ab6ff88b 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/StandardOperationResponse.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/StandardOperationResponse.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/package-info.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/package-info.java index e9ba93d90..704ca0ecb 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/package-info.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/package-info.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/preprocess/ContentModifier.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/preprocess/ContentModifier.java index 8781a817f..f443fe115 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/preprocess/ContentModifier.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/preprocess/ContentModifier.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/preprocess/ContentModifyingOperationPreprocessor.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/preprocess/ContentModifyingOperationPreprocessor.java index d18948e37..10caf9512 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/preprocess/ContentModifyingOperationPreprocessor.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/preprocess/ContentModifyingOperationPreprocessor.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/preprocess/DelegatingOperationRequestPreprocessor.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/preprocess/DelegatingOperationRequestPreprocessor.java index 76490760a..7302f8e15 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/preprocess/DelegatingOperationRequestPreprocessor.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/preprocess/DelegatingOperationRequestPreprocessor.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/preprocess/DelegatingOperationResponsePreprocessor.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/preprocess/DelegatingOperationResponsePreprocessor.java index f55ce4eb1..48ab020d3 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/preprocess/DelegatingOperationResponsePreprocessor.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/preprocess/DelegatingOperationResponsePreprocessor.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/preprocess/HeaderRemovingOperationPreprocessor.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/preprocess/HeaderRemovingOperationPreprocessor.java index 7766af57c..be7e2e826 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/preprocess/HeaderRemovingOperationPreprocessor.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/preprocess/HeaderRemovingOperationPreprocessor.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/preprocess/LinkMaskingContentModifier.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/preprocess/LinkMaskingContentModifier.java index 928f700f3..9d9b95c88 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/preprocess/LinkMaskingContentModifier.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/preprocess/LinkMaskingContentModifier.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/preprocess/OperationPreprocessor.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/preprocess/OperationPreprocessor.java index bfdfbc25e..68fc6d0db 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/preprocess/OperationPreprocessor.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/preprocess/OperationPreprocessor.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/preprocess/OperationRequestPreprocessor.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/preprocess/OperationRequestPreprocessor.java index 24cf7535c..5620dd839 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/preprocess/OperationRequestPreprocessor.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/preprocess/OperationRequestPreprocessor.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/preprocess/OperationResponsePreprocessor.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/preprocess/OperationResponsePreprocessor.java index 4763b05b3..9db284d47 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/preprocess/OperationResponsePreprocessor.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/preprocess/OperationResponsePreprocessor.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/preprocess/PatternReplacingContentModifier.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/preprocess/PatternReplacingContentModifier.java index 7fe67754c..6d669d6db 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/preprocess/PatternReplacingContentModifier.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/preprocess/PatternReplacingContentModifier.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/preprocess/Preprocessors.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/preprocess/Preprocessors.java index 35b5c1fd6..52e298041 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/preprocess/Preprocessors.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/preprocess/Preprocessors.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/preprocess/PrettyPrintingContentModifier.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/preprocess/PrettyPrintingContentModifier.java index e53ff431e..67f0949d7 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/preprocess/PrettyPrintingContentModifier.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/preprocess/PrettyPrintingContentModifier.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/preprocess/package-info.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/preprocess/package-info.java index a00ceb0e5..8f1bf78ea 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/preprocess/package-info.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/preprocess/package-info.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/package-info.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/package-info.java index 73fee6695..540f8a207 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/package-info.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/package-info.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/AbstractFieldsSnippet.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/AbstractFieldsSnippet.java index dcff13bdd..96f3a8354 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/AbstractFieldsSnippet.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/AbstractFieldsSnippet.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/ContentHandler.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/ContentHandler.java index ce99ff00f..058f939e1 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/ContentHandler.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/ContentHandler.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/FieldDescriptor.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/FieldDescriptor.java index d68bb68d7..4c30e63df 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/FieldDescriptor.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/FieldDescriptor.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/FieldDoesNotExistException.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/FieldDoesNotExistException.java index 37d794932..9fadf5e66 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/FieldDoesNotExistException.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/FieldDoesNotExistException.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/FieldTypeRequiredException.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/FieldTypeRequiredException.java index 6538491c2..b473ef4d1 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/FieldTypeRequiredException.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/FieldTypeRequiredException.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/JsonContentHandler.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/JsonContentHandler.java index 779b75fbc..35d317113 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/JsonContentHandler.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/JsonContentHandler.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/JsonFieldPath.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/JsonFieldPath.java index 10478a839..dc071ebf3 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/JsonFieldPath.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/JsonFieldPath.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/JsonFieldProcessor.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/JsonFieldProcessor.java index fb63a2148..293829e3f 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/JsonFieldProcessor.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/JsonFieldProcessor.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/JsonFieldType.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/JsonFieldType.java index fcaffa6da..2f334c8fb 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/JsonFieldType.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/JsonFieldType.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/JsonFieldTypeResolver.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/JsonFieldTypeResolver.java index f5bc6ec3e..daf10d137 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/JsonFieldTypeResolver.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/JsonFieldTypeResolver.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/PayloadDocumentation.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/PayloadDocumentation.java index 097e1c47c..e61752b48 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/PayloadDocumentation.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/PayloadDocumentation.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/PayloadHandlingException.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/PayloadHandlingException.java index 383ba2221..f2cd61176 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/PayloadHandlingException.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/PayloadHandlingException.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/RequestFieldsSnippet.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/RequestFieldsSnippet.java index 354a0283e..bfdd530cd 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/RequestFieldsSnippet.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/RequestFieldsSnippet.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/ResponseFieldsSnippet.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/ResponseFieldsSnippet.java index 82015ef8f..1a9091a34 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/ResponseFieldsSnippet.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/ResponseFieldsSnippet.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/XmlContentHandler.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/XmlContentHandler.java index 67e2763d5..ccb2cbddc 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/XmlContentHandler.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/XmlContentHandler.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/package-info.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/package-info.java index 2c3281d6c..395fb7030 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/package-info.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/package-info.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/request/AbstractParametersSnippet.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/request/AbstractParametersSnippet.java index 0be930228..5713cfe94 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/request/AbstractParametersSnippet.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/request/AbstractParametersSnippet.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/request/ParameterDescriptor.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/request/ParameterDescriptor.java index 9172a5525..16b3dafc7 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/request/ParameterDescriptor.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/request/ParameterDescriptor.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/request/PathParametersSnippet.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/request/PathParametersSnippet.java index 4186faa08..f0e0f0614 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/request/PathParametersSnippet.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/request/PathParametersSnippet.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/request/RequestDocumentation.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/request/RequestDocumentation.java index e0aa2f4ba..5be28fa08 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/request/RequestDocumentation.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/request/RequestDocumentation.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/request/RequestParametersSnippet.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/request/RequestParametersSnippet.java index 5b1f9ba81..20e0829fa 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/request/RequestParametersSnippet.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/request/RequestParametersSnippet.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/request/package-info.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/request/package-info.java index c2828b7b5..36017ad3f 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/request/package-info.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/request/package-info.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/snippet/AbstractDescriptor.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/snippet/AbstractDescriptor.java index a0b67a3a8..0df7da34b 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/snippet/AbstractDescriptor.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/snippet/AbstractDescriptor.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/snippet/Attributes.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/snippet/Attributes.java index b5f1a9c3c..7506dd13c 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/snippet/Attributes.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/snippet/Attributes.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/snippet/IgnorableDescriptor.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/snippet/IgnorableDescriptor.java index 477431ee5..1031d811c 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/snippet/IgnorableDescriptor.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/snippet/IgnorableDescriptor.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/snippet/ModelCreationException.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/snippet/ModelCreationException.java index 93c60192f..e83b22074 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/snippet/ModelCreationException.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/snippet/ModelCreationException.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/snippet/RestDocumentationContextPlaceholderResolver.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/snippet/RestDocumentationContextPlaceholderResolver.java index 81898c250..0fde0787d 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/snippet/RestDocumentationContextPlaceholderResolver.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/snippet/RestDocumentationContextPlaceholderResolver.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/snippet/Snippet.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/snippet/Snippet.java index a43091562..77fa39004 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/snippet/Snippet.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/snippet/Snippet.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/snippet/SnippetException.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/snippet/SnippetException.java index 9928c3522..e7a937443 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/snippet/SnippetException.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/snippet/SnippetException.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/snippet/StandardWriterResolver.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/snippet/StandardWriterResolver.java index 883e1c115..08da01c33 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/snippet/StandardWriterResolver.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/snippet/StandardWriterResolver.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/snippet/TemplatedSnippet.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/snippet/TemplatedSnippet.java index dedfa98a3..2803cebea 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/snippet/TemplatedSnippet.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/snippet/TemplatedSnippet.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/snippet/WriterResolver.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/snippet/WriterResolver.java index 29c2393e3..d242b2782 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/snippet/WriterResolver.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/snippet/WriterResolver.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/snippet/package-info.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/snippet/package-info.java index 90a6642b1..89135cc70 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/snippet/package-info.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/snippet/package-info.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/templates/StandardTemplateResourceResolver.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/templates/StandardTemplateResourceResolver.java index 847f6ee85..444d0364c 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/templates/StandardTemplateResourceResolver.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/templates/StandardTemplateResourceResolver.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/templates/Template.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/templates/Template.java index 7275c5292..47c7f5b91 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/templates/Template.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/templates/Template.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/templates/TemplateEngine.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/templates/TemplateEngine.java index 17c2dfc7e..d628937bc 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/templates/TemplateEngine.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/templates/TemplateEngine.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/templates/TemplateResourceResolver.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/templates/TemplateResourceResolver.java index 7def94628..cd308638e 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/templates/TemplateResourceResolver.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/templates/TemplateResourceResolver.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/templates/mustache/MustacheTemplate.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/templates/mustache/MustacheTemplate.java index cb98ab2a2..17cd82735 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/templates/mustache/MustacheTemplate.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/templates/mustache/MustacheTemplate.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/templates/mustache/MustacheTemplateEngine.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/templates/mustache/MustacheTemplateEngine.java index 3a5acc721..ab86d270f 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/templates/mustache/MustacheTemplateEngine.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/templates/mustache/MustacheTemplateEngine.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/templates/mustache/package-info.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/templates/mustache/package-info.java index 9f7231ce9..b9f21708f 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/templates/mustache/package-info.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/templates/mustache/package-info.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/templates/package-info.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/templates/package-info.java index a0a11105a..ba58f2b76 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/templates/package-info.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/templates/package-info.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/constraints/ConstraintDescriptionsTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/constraints/ConstraintDescriptionsTests.java index a3dbd9abe..d8cd95eb4 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/constraints/ConstraintDescriptionsTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/constraints/ConstraintDescriptionsTests.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/constraints/ResourceBundleConstraintDescriptionResolverTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/constraints/ResourceBundleConstraintDescriptionResolverTests.java index 06334f51e..db8c9e985 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/constraints/ResourceBundleConstraintDescriptionResolverTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/constraints/ResourceBundleConstraintDescriptionResolverTests.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/constraints/ValidatorConstraintResolverTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/constraints/ValidatorConstraintResolverTests.java index 4ff83c65c..7b6155c3f 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/constraints/ValidatorConstraintResolverTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/constraints/ValidatorConstraintResolverTests.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/curl/CurlRequestSnippetTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/curl/CurlRequestSnippetTests.java index 5e5b44c76..28fa4a680 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/curl/CurlRequestSnippetTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/curl/CurlRequestSnippetTests.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/curl/QueryStringParserTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/curl/QueryStringParserTests.java index 634fede11..5675dc726 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/curl/QueryStringParserTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/curl/QueryStringParserTests.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/headers/RequestHeadersSnippetTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/headers/RequestHeadersSnippetTests.java index 5f493033c..1211beb1c 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/headers/RequestHeadersSnippetTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/headers/RequestHeadersSnippetTests.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/headers/ResponseHeadersSnippetTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/headers/ResponseHeadersSnippetTests.java index 41fe5fcd2..fe0e857ff 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/headers/ResponseHeadersSnippetTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/headers/ResponseHeadersSnippetTests.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/http/HttpRequestSnippetTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/http/HttpRequestSnippetTests.java index ed0302323..7c17a6e9d 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/http/HttpRequestSnippetTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/http/HttpRequestSnippetTests.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/http/HttpResponseSnippetTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/http/HttpResponseSnippetTests.java index df19b6bc5..405448ce0 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/http/HttpResponseSnippetTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/http/HttpResponseSnippetTests.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/hypermedia/ContentTypeLinkExtractorTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/hypermedia/ContentTypeLinkExtractorTests.java index 9c923e440..67d4eba97 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/hypermedia/ContentTypeLinkExtractorTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/hypermedia/ContentTypeLinkExtractorTests.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/hypermedia/LinkExtractorsPayloadTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/hypermedia/LinkExtractorsPayloadTests.java index b26374e81..b6d8f4c3e 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/hypermedia/LinkExtractorsPayloadTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/hypermedia/LinkExtractorsPayloadTests.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/hypermedia/LinksSnippetTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/hypermedia/LinksSnippetTests.java index fd0a4c5df..c52d451a0 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/hypermedia/LinksSnippetTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/hypermedia/LinksSnippetTests.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/operation/preprocess/ContentModifyingOperationPreprocessorTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/operation/preprocess/ContentModifyingOperationPreprocessorTests.java index 4e45a742f..da2110723 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/operation/preprocess/ContentModifyingOperationPreprocessorTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/operation/preprocess/ContentModifyingOperationPreprocessorTests.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/operation/preprocess/DelegatingOperationRequestPreprocessorTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/operation/preprocess/DelegatingOperationRequestPreprocessorTests.java index 62e69a367..8b3bf232d 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/operation/preprocess/DelegatingOperationRequestPreprocessorTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/operation/preprocess/DelegatingOperationRequestPreprocessorTests.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/operation/preprocess/DelegatingOperationResponsePreprocessorTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/operation/preprocess/DelegatingOperationResponsePreprocessorTests.java index 422393d62..03fbc5097 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/operation/preprocess/DelegatingOperationResponsePreprocessorTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/operation/preprocess/DelegatingOperationResponsePreprocessorTests.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/operation/preprocess/HeaderRemovingOperationPreprocessorTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/operation/preprocess/HeaderRemovingOperationPreprocessorTests.java index bd3b07792..fd4f12edc 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/operation/preprocess/HeaderRemovingOperationPreprocessorTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/operation/preprocess/HeaderRemovingOperationPreprocessorTests.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/operation/preprocess/LinkMaskingContentModifierTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/operation/preprocess/LinkMaskingContentModifierTests.java index a8d999fc4..6b676d298 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/operation/preprocess/LinkMaskingContentModifierTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/operation/preprocess/LinkMaskingContentModifierTests.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/operation/preprocess/PatternReplacingContentModifierTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/operation/preprocess/PatternReplacingContentModifierTests.java index f8ea398d3..49cdfa2a2 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/operation/preprocess/PatternReplacingContentModifierTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/operation/preprocess/PatternReplacingContentModifierTests.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/operation/preprocess/PrettyPrintingContentModifierTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/operation/preprocess/PrettyPrintingContentModifierTests.java index 319c37fbe..c47ee02de 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/operation/preprocess/PrettyPrintingContentModifierTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/operation/preprocess/PrettyPrintingContentModifierTests.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/JsonFieldPathTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/JsonFieldPathTests.java index 043977968..53d30cfb1 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/JsonFieldPathTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/JsonFieldPathTests.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/JsonFieldProcessorTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/JsonFieldProcessorTests.java index 01af20974..84202b8aa 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/JsonFieldProcessorTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/JsonFieldProcessorTests.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/JsonFieldTypeResolverTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/JsonFieldTypeResolverTests.java index 502bfd29c..eb806031d 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/JsonFieldTypeResolverTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/JsonFieldTypeResolverTests.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/RequestFieldsSnippetTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/RequestFieldsSnippetTests.java index 216b5ab7b..270e699a7 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/RequestFieldsSnippetTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/RequestFieldsSnippetTests.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/ResponseFieldsSnippetTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/ResponseFieldsSnippetTests.java index 1356d7b3b..00bd4131d 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/ResponseFieldsSnippetTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/ResponseFieldsSnippetTests.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/request/PathParametersSnippetTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/request/PathParametersSnippetTests.java index 51b1aad96..ab43f00bd 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/request/PathParametersSnippetTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/request/PathParametersSnippetTests.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/request/RequestParametersSnippetTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/request/RequestParametersSnippetTests.java index 97b4253bb..0207f18e9 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/request/RequestParametersSnippetTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/request/RequestParametersSnippetTests.java @@ -5,7 +5,7 @@ * 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 + * https://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, 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 def767471..6b5f9b312 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 @@ -5,7 +5,7 @@ * 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 + * https://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, 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 e3152d7b0..49319b3b9 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 @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/snippet/TemplatedSnippetTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/snippet/TemplatedSnippetTests.java index 4213da4e5..d9945e7b7 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/snippet/TemplatedSnippetTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/snippet/TemplatedSnippetTests.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/templates/StandardTemplateResourceResolverTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/templates/StandardTemplateResourceResolverTests.java index 52e0138b6..8f179b019 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/templates/StandardTemplateResourceResolverTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/templates/StandardTemplateResourceResolverTests.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/test/ExpectedSnippet.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/test/ExpectedSnippet.java index 111096b56..8e7ebe5be 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/test/ExpectedSnippet.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/test/ExpectedSnippet.java @@ -5,7 +5,7 @@ * 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 + * https://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, 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 e483d6c51..7e027b1fa 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 @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/test/OutputCapture.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/test/OutputCapture.java index e7b4ef755..54f4f6a52 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/test/OutputCapture.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/test/OutputCapture.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/test/SnippetMatchers.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/test/SnippetMatchers.java index 7f23ad8ea..b28a34ef4 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/test/SnippetMatchers.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/test/SnippetMatchers.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-mockmvc/src/main/java/org/springframework/restdocs/mockmvc/AbstractConfigurer.java b/spring-restdocs-mockmvc/src/main/java/org/springframework/restdocs/mockmvc/AbstractConfigurer.java index f8effd0a9..fb84914e3 100644 --- a/spring-restdocs-mockmvc/src/main/java/org/springframework/restdocs/mockmvc/AbstractConfigurer.java +++ b/spring-restdocs-mockmvc/src/main/java/org/springframework/restdocs/mockmvc/AbstractConfigurer.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-mockmvc/src/main/java/org/springframework/restdocs/mockmvc/AbstractNestedConfigurer.java b/spring-restdocs-mockmvc/src/main/java/org/springframework/restdocs/mockmvc/AbstractNestedConfigurer.java index a4444e7cb..8134ab09a 100644 --- a/spring-restdocs-mockmvc/src/main/java/org/springframework/restdocs/mockmvc/AbstractNestedConfigurer.java +++ b/spring-restdocs-mockmvc/src/main/java/org/springframework/restdocs/mockmvc/AbstractNestedConfigurer.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-mockmvc/src/main/java/org/springframework/restdocs/mockmvc/IterableEnumeration.java b/spring-restdocs-mockmvc/src/main/java/org/springframework/restdocs/mockmvc/IterableEnumeration.java index d4b9653f2..628d1a283 100644 --- a/spring-restdocs-mockmvc/src/main/java/org/springframework/restdocs/mockmvc/IterableEnumeration.java +++ b/spring-restdocs-mockmvc/src/main/java/org/springframework/restdocs/mockmvc/IterableEnumeration.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-mockmvc/src/main/java/org/springframework/restdocs/mockmvc/MockMvcOperationRequestFactory.java b/spring-restdocs-mockmvc/src/main/java/org/springframework/restdocs/mockmvc/MockMvcOperationRequestFactory.java index 3045131d0..f26cecd4a 100644 --- a/spring-restdocs-mockmvc/src/main/java/org/springframework/restdocs/mockmvc/MockMvcOperationRequestFactory.java +++ b/spring-restdocs-mockmvc/src/main/java/org/springframework/restdocs/mockmvc/MockMvcOperationRequestFactory.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-mockmvc/src/main/java/org/springframework/restdocs/mockmvc/MockMvcOperationResponseFactory.java b/spring-restdocs-mockmvc/src/main/java/org/springframework/restdocs/mockmvc/MockMvcOperationResponseFactory.java index 4e4f765f5..2aa1275c9 100644 --- a/spring-restdocs-mockmvc/src/main/java/org/springframework/restdocs/mockmvc/MockMvcOperationResponseFactory.java +++ b/spring-restdocs-mockmvc/src/main/java/org/springframework/restdocs/mockmvc/MockMvcOperationResponseFactory.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-mockmvc/src/main/java/org/springframework/restdocs/mockmvc/MockMvcRestDocumentation.java b/spring-restdocs-mockmvc/src/main/java/org/springframework/restdocs/mockmvc/MockMvcRestDocumentation.java index bedd3753a..e6555c846 100644 --- a/spring-restdocs-mockmvc/src/main/java/org/springframework/restdocs/mockmvc/MockMvcRestDocumentation.java +++ b/spring-restdocs-mockmvc/src/main/java/org/springframework/restdocs/mockmvc/MockMvcRestDocumentation.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-mockmvc/src/main/java/org/springframework/restdocs/mockmvc/NestedConfigurer.java b/spring-restdocs-mockmvc/src/main/java/org/springframework/restdocs/mockmvc/NestedConfigurer.java index 1c6768c8f..eb75ed61a 100644 --- a/spring-restdocs-mockmvc/src/main/java/org/springframework/restdocs/mockmvc/NestedConfigurer.java +++ b/spring-restdocs-mockmvc/src/main/java/org/springframework/restdocs/mockmvc/NestedConfigurer.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-mockmvc/src/main/java/org/springframework/restdocs/mockmvc/RestDocumentationMockMvcConfigurer.java b/spring-restdocs-mockmvc/src/main/java/org/springframework/restdocs/mockmvc/RestDocumentationMockMvcConfigurer.java index 6bca090a3..6706f6306 100644 --- a/spring-restdocs-mockmvc/src/main/java/org/springframework/restdocs/mockmvc/RestDocumentationMockMvcConfigurer.java +++ b/spring-restdocs-mockmvc/src/main/java/org/springframework/restdocs/mockmvc/RestDocumentationMockMvcConfigurer.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-mockmvc/src/main/java/org/springframework/restdocs/mockmvc/RestDocumentationRequestBuilders.java b/spring-restdocs-mockmvc/src/main/java/org/springframework/restdocs/mockmvc/RestDocumentationRequestBuilders.java index 23f8b7936..250fb6d8a 100644 --- a/spring-restdocs-mockmvc/src/main/java/org/springframework/restdocs/mockmvc/RestDocumentationRequestBuilders.java +++ b/spring-restdocs-mockmvc/src/main/java/org/springframework/restdocs/mockmvc/RestDocumentationRequestBuilders.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-mockmvc/src/main/java/org/springframework/restdocs/mockmvc/RestDocumentationResultHandler.java b/spring-restdocs-mockmvc/src/main/java/org/springframework/restdocs/mockmvc/RestDocumentationResultHandler.java index 1969e5e94..4d27c98f8 100644 --- a/spring-restdocs-mockmvc/src/main/java/org/springframework/restdocs/mockmvc/RestDocumentationResultHandler.java +++ b/spring-restdocs-mockmvc/src/main/java/org/springframework/restdocs/mockmvc/RestDocumentationResultHandler.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-mockmvc/src/main/java/org/springframework/restdocs/mockmvc/SnippetConfigurer.java b/spring-restdocs-mockmvc/src/main/java/org/springframework/restdocs/mockmvc/SnippetConfigurer.java index 7ac33bd05..16f0d1634 100644 --- a/spring-restdocs-mockmvc/src/main/java/org/springframework/restdocs/mockmvc/SnippetConfigurer.java +++ b/spring-restdocs-mockmvc/src/main/java/org/springframework/restdocs/mockmvc/SnippetConfigurer.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-mockmvc/src/main/java/org/springframework/restdocs/mockmvc/UriConfigurer.java b/spring-restdocs-mockmvc/src/main/java/org/springframework/restdocs/mockmvc/UriConfigurer.java index bbf44345f..a2abaa7af 100644 --- a/spring-restdocs-mockmvc/src/main/java/org/springframework/restdocs/mockmvc/UriConfigurer.java +++ b/spring-restdocs-mockmvc/src/main/java/org/springframework/restdocs/mockmvc/UriConfigurer.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-mockmvc/src/main/java/org/springframework/restdocs/mockmvc/package-info.java b/spring-restdocs-mockmvc/src/main/java/org/springframework/restdocs/mockmvc/package-info.java index e587e074f..5956dd0e4 100644 --- a/spring-restdocs-mockmvc/src/main/java/org/springframework/restdocs/mockmvc/package-info.java +++ b/spring-restdocs-mockmvc/src/main/java/org/springframework/restdocs/mockmvc/package-info.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-mockmvc/src/test/java/org/springframework/restdocs/mockmvc/MockMvcOperationRequestFactoryTests.java b/spring-restdocs-mockmvc/src/test/java/org/springframework/restdocs/mockmvc/MockMvcOperationRequestFactoryTests.java index 3ca08471e..2d0134ade 100644 --- a/spring-restdocs-mockmvc/src/test/java/org/springframework/restdocs/mockmvc/MockMvcOperationRequestFactoryTests.java +++ b/spring-restdocs-mockmvc/src/test/java/org/springframework/restdocs/mockmvc/MockMvcOperationRequestFactoryTests.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-mockmvc/src/test/java/org/springframework/restdocs/mockmvc/MockMvcRestDocumentationIntegrationTests.java b/spring-restdocs-mockmvc/src/test/java/org/springframework/restdocs/mockmvc/MockMvcRestDocumentationIntegrationTests.java index 86dd0f55c..d712aa7e4 100644 --- a/spring-restdocs-mockmvc/src/test/java/org/springframework/restdocs/mockmvc/MockMvcRestDocumentationIntegrationTests.java +++ b/spring-restdocs-mockmvc/src/test/java/org/springframework/restdocs/mockmvc/MockMvcRestDocumentationIntegrationTests.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-mockmvc/src/test/java/org/springframework/restdocs/mockmvc/RestDocumentationConfigurerTests.java b/spring-restdocs-mockmvc/src/test/java/org/springframework/restdocs/mockmvc/RestDocumentationConfigurerTests.java index eda5107d9..6fea23d09 100644 --- a/spring-restdocs-mockmvc/src/test/java/org/springframework/restdocs/mockmvc/RestDocumentationConfigurerTests.java +++ b/spring-restdocs-mockmvc/src/test/java/org/springframework/restdocs/mockmvc/RestDocumentationConfigurerTests.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-mockmvc/src/test/java/org/springframework/restdocs/mockmvc/RestDocumentationRequestBuildersTests.java b/spring-restdocs-mockmvc/src/test/java/org/springframework/restdocs/mockmvc/RestDocumentationRequestBuildersTests.java index 0ed8fee98..2bde64ab3 100644 --- a/spring-restdocs-mockmvc/src/test/java/org/springframework/restdocs/mockmvc/RestDocumentationRequestBuildersTests.java +++ b/spring-restdocs-mockmvc/src/test/java/org/springframework/restdocs/mockmvc/RestDocumentationRequestBuildersTests.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-restdocs-mockmvc/src/test/java/org/springframework/restdocs/mockmvc/RestDocumentationResultHandlerTests.java b/spring-restdocs-mockmvc/src/test/java/org/springframework/restdocs/mockmvc/RestDocumentationResultHandlerTests.java index 4c8b53ded..0aca54788 100644 --- a/spring-restdocs-mockmvc/src/test/java/org/springframework/restdocs/mockmvc/RestDocumentationResultHandlerTests.java +++ b/spring-restdocs-mockmvc/src/test/java/org/springframework/restdocs/mockmvc/RestDocumentationResultHandlerTests.java @@ -5,7 +5,7 @@ * 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 + * https://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, From 81a07d49511e0eae6b779c4628800310773e68ec Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Tue, 19 Mar 2019 11:44:44 +0000 Subject: [PATCH 027/502] Use HTTPS linked in the README --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 3d715d1d3..9e9823e0b 100644 --- a/README.md +++ b/README.md @@ -34,14 +34,14 @@ Spring REST Docs is open source software released under the [Apache 2.0 license] [1]: https://build.spring.io/plugins/servlet/buildStatusImage/SRD-PUB (Build status) [2]: https://build.spring.io/browse/SRD-PUB -[3]: http://asciidoctor.org -[4]: http://docs.spring.io/spring-framework/docs/4.1.x/spring-framework-reference/htmlsingle/#spring-mvc-test-framework +[3]: https://asciidoctor.org +[4]: https://docs.spring.io/spring-framework/docs/4.1.x/spring-framework-reference/htmlsingle/#spring-mvc-test-framework [5]: https://developer.github.com/v3/ -[6]: http://swagger.io +[6]: https://swagger.io [7]: https://speakerdeck.com/ankinson/documenting-restful-apis-webinar [8]: https://www.youtube.com/watch?v=knH5ihPNiUs&feature=youtu.be -[9]: http://docs.spring.io/spring-restdocs/docs/ -[10]: http://gradle.org +[9]: https://docs.spring.io/spring-restdocs/docs/ +[10]: https://gradle.org [11]: CODE_OF_CONDUCT.md [12]: https://help.github.com/articles/using-pull-requests/ [13]: CONTRIBUTING.md From 62e6c9cd3de7a105c52c3d0e29cdcaeb7991331d Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 20 Mar 2019 14:38:05 +0000 Subject: [PATCH 028/502] Switch to checkstyle.org for Checkstyle DTDs --- config/checkstyle/checkstyle-import-control.xml | 2 +- config/checkstyle/checkstyle-suppressions.xml | 2 +- config/checkstyle/checkstyle.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/config/checkstyle/checkstyle-import-control.xml b/config/checkstyle/checkstyle-import-control.xml index af08f1a2c..7bb744d36 100644 --- a/config/checkstyle/checkstyle-import-control.xml +++ b/config/checkstyle/checkstyle-import-control.xml @@ -1,5 +1,5 @@ - + diff --git a/config/checkstyle/checkstyle-suppressions.xml b/config/checkstyle/checkstyle-suppressions.xml index f74d92343..7c71fd49b 100644 --- a/config/checkstyle/checkstyle-suppressions.xml +++ b/config/checkstyle/checkstyle-suppressions.xml @@ -1,7 +1,7 @@ + "https://checkstyle.org/dtds/suppressions_1_1.dtd"> diff --git a/config/checkstyle/checkstyle.xml b/config/checkstyle/checkstyle.xml index d9cdead77..d2d3e80b5 100644 --- a/config/checkstyle/checkstyle.xml +++ b/config/checkstyle/checkstyle.xml @@ -1,5 +1,5 @@ - + From 4fdb1f5361a61ca5407f0ff0b58fea59014f76f5 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 20 Mar 2019 14:44:46 +0000 Subject: [PATCH 029/502] Drop Travis CI configuration --- .travis.yml | 8 -------- 1 file changed, 8 deletions(-) delete mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 69d0bdad0..000000000 --- a/.travis.yml +++ /dev/null @@ -1,8 +0,0 @@ -sudo: false -language: java -jdk: - - oraclejdk7 -env: - - GRADLE_OPTS=-Dorg.gradle.daemon=false -script: - - "./gradlew build buildSamples --stacktrace" \ No newline at end of file From c3890f9312c376f640ef8f7e82dd2c2f7ff30c57 Mon Sep 17 00:00:00 2001 From: Spring Operator Date: Tue, 26 Mar 2019 00:50:58 -0500 Subject: [PATCH 030/502] Use HTTPS where possible for external links in XML files See gh-607 --- samples/rest-notes-slate/slate/source/fonts/slate.svg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/rest-notes-slate/slate/source/fonts/slate.svg b/samples/rest-notes-slate/slate/source/fonts/slate.svg index 5f3498230..82e48fb50 100755 --- a/samples/rest-notes-slate/slate/source/fonts/slate.svg +++ b/samples/rest-notes-slate/slate/source/fonts/slate.svg @@ -1,5 +1,5 @@ - + Generated by IcoMoon From f2e60ea3473f1560e315ccee8f98b4d51584b006 Mon Sep 17 00:00:00 2001 From: Spring Operator Date: Tue, 26 Mar 2019 04:42:31 -0500 Subject: [PATCH 031/502] Use HTTPS for external links where possible See gh-609 --- CODE_OF_CONDUCT.md | 4 ++-- CONTRIBUTING.md | 2 +- docs/src/docs/asciidoc/contributing.adoc | 2 +- docs/src/docs/asciidoc/documenting-your-api.adoc | 2 +- docs/src/docs/asciidoc/getting-started.adoc | 6 +++--- docs/src/docs/asciidoc/index.adoc | 4 ++-- docs/src/docs/asciidoc/introduction.adoc | 2 +- docs/src/docs/asciidoc/working-with-asciidoctor.adoc | 10 +++++----- .../src/main/asciidoc/getting-started-guide.adoc | 2 +- .../test/java/com/example/notes/ApiDocumentation.java | 8 ++++---- .../src/docs/asciidoc/getting-started-guide.adoc | 2 +- .../test/java/com/example/notes/ApiDocumentation.java | 8 ++++---- .../restdocs/hypermedia/HypermediaDocumentation.java | 4 ++-- .../preprocess/PrettyPrintingContentModifier.java | 2 +- .../hypermedia/LinkExtractorsPayloadTests.java | 10 +++++----- .../multiple-fields-and-embedded-and-links.json | 4 ++-- .../field-payloads/multiple-fields-and-links.json | 4 ++-- .../atom/multiple-links-different-rels.json | 4 ++-- .../link-payloads/atom/multiple-links-same-rels.json | 4 ++-- .../test/resources/link-payloads/atom/single-link.json | 2 +- .../resources/link-payloads/atom/wrong-format.json | 4 ++-- .../hal/multiple-links-different-rels.json | 4 ++-- .../link-payloads/hal/multiple-links-same-rels.json | 4 ++-- .../test/resources/link-payloads/hal/single-link.json | 2 +- .../test/resources/link-payloads/hal/wrong-format.json | 4 ++-- 25 files changed, 52 insertions(+), 52 deletions(-) diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index 4df5b8d41..b8dfcb906 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -42,5 +42,5 @@ with regard to the reporter of an incident. This Code of Conduct is adapted from the [Contributor Covenant][1], version 1.3.0, available at [contributor-covenant.org/version/1/3/0/][2]. -[1]: http://contributor-covenant.org -[2]: http://contributor-covenant.org/version/1/3/0/ \ No newline at end of file +[1]: https://contributor-covenant.org +[2]: https://contributor-covenant.org/version/1/3/0/ \ No newline at end of file diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 5b609d53c..2a8c3c7f3 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -62,4 +62,4 @@ The project can then be imported into Eclipse using `File -> Import…` and then [1]: CODE_OF_CONDUCT.md [2]: https://support.springsource.com/spring_committer_signup -[3]: http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html \ No newline at end of file +[3]: https://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html \ No newline at end of file diff --git a/docs/src/docs/asciidoc/contributing.adoc b/docs/src/docs/asciidoc/contributing.adoc index ce726ed63..c2c594369 100644 --- a/docs/src/docs/asciidoc/contributing.adoc +++ b/docs/src/docs/asciidoc/contributing.adoc @@ -9,7 +9,7 @@ for your RESTful services. However, we can't achieve that goal without your cont [[contributing-questions]] === Questions -You can ask questions about Spring REST Docs on http://stackoverflow.com[StackOverflow] +You can ask questions about Spring REST Docs on https://stackoverflow.com[StackOverflow] using the `spring-restdocs` tag. Similarly, we encourage you to help your fellow Spring REST Docs users by answering questions. diff --git a/docs/src/docs/asciidoc/documenting-your-api.adoc b/docs/src/docs/asciidoc/documenting-your-api.adoc index 25fc52b15..01928fbaa 100644 --- a/docs/src/docs/asciidoc/documenting-your-api.adoc +++ b/docs/src/docs/asciidoc/documenting-your-api.adoc @@ -444,7 +444,7 @@ A number of snippets are produced automatically when you document a call to |Snippet | Description | `curl-request.adoc` -| Contains the http://curl.haxx.se[`curl`] command that is equivalent to the `MockMvc` +| Contains the https://curl.haxx.se[`curl`] command that is equivalent to the `MockMvc` call that is being documented | `http-request.adoc` diff --git a/docs/src/docs/asciidoc/getting-started.adoc b/docs/src/docs/asciidoc/getting-started.adoc index 4a12eef42..69a07874e 100644 --- a/docs/src/docs/asciidoc/getting-started.adoc +++ b/docs/src/docs/asciidoc/getting-started.adoc @@ -10,9 +10,9 @@ This section describes how to get started with Spring REST Docs. If you want to jump straight in, there are two sample applications available. {samples}/rest-notes-spring-hateoas[One sample] uses -http://projects.spring.io/spring-hateoas/[Spring HATEOAS] and +https://projects.spring.io/spring-hateoas/[Spring HATEOAS] and {samples}/rest-notes-spring-data-rest[the other] uses -http://projects.spring.io/spring-data-rest/[Spring Data REST]. Both samples use +https://projects.spring.io/spring-data-rest/[Spring Data REST]. Both samples use Spring REST Docs to produce a detailed API guide and a getting started walkthrough. Each sample contains a file named `api-guide.adoc` that produces an API guide for the @@ -295,7 +295,7 @@ that can be produced by Spring REST Docs. === Using the snippets The generated snippets can be included in your documentation using the -http://asciidoctor.org/docs/asciidoc-syntax-quick-reference/#include-files[include macro]. +https://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: diff --git a/docs/src/docs/asciidoc/index.adoc b/docs/src/docs/asciidoc/index.adoc index 17cde86ea..96f519d7d 100644 --- a/docs/src/docs/asciidoc/index.adoc +++ b/docs/src/docs/asciidoc/index.adoc @@ -12,8 +12,8 @@ Andy Wilkinson :source: {github}/tree/{branch-or-tag} :samples: {source}/samples :templates: {source}spring-restdocs/src/main/resources/org/springframework/restdocs/templates -:spring-boot-docs: http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle -:spring-framework-docs: http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle +:spring-boot-docs: https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle +:spring-framework-docs: https://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle [[abstract]] diff --git a/docs/src/docs/asciidoc/introduction.adoc b/docs/src/docs/asciidoc/introduction.adoc index 9590ac358..2eef3b6d2 100644 --- a/docs/src/docs/asciidoc/introduction.adoc +++ b/docs/src/docs/asciidoc/introduction.adoc @@ -6,7 +6,7 @@ services that is accurate and readable. Writing high-quality documentation is difficult. One way to ease that difficulty is to use tools that are well-suited to the job. To this end, Spring REST Docs uses -http://asciidoctor.org[Asciidoctor]. Asciidoctor processes plain text and produces +https://asciidoctor.org[Asciidoctor]. Asciidoctor processes plain text and produces HTML, styled and layed out to suit your needs. Spring REST Docs makes use of snippets produced by tests written with diff --git a/docs/src/docs/asciidoc/working-with-asciidoctor.adoc b/docs/src/docs/asciidoc/working-with-asciidoctor.adoc index ce166410b..75a3ba7f8 100644 --- a/docs/src/docs/asciidoc/working-with-asciidoctor.adoc +++ b/docs/src/docs/asciidoc/working-with-asciidoctor.adoc @@ -9,15 +9,15 @@ relevant to Spring REST Docs. [[working-with-asciidoctor-resources]] === Resources - * http://asciidoctor.org/docs/asciidoc-syntax-quick-reference[Syntax quick reference] - * http://asciidoctor.org/docs/user-manual[User manual] + * https://asciidoctor.org/docs/asciidoc-syntax-quick-reference[Syntax quick reference] + * https://asciidoctor.org/docs/user-manual[User manual] [[working-with-asciidoctor-including-snippets]] === Including snippets -The http://asciidoctor.org/docs/asciidoc-syntax-quick-reference/#include-files[include +The https://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: @@ -42,7 +42,7 @@ snippet is included or by using a custom snippet template. ==== Formatting columns Asciidoctor has rich support for -http://asciidoctor.org/docs/user-manual/#cols-format[formatting a table's columns]. For +https://asciidoctor.org/docs/user-manual/#cols-format[formatting a table's columns]. For example, the widths of a table's columns can be specified using the `cols` attribute: [source,adoc,indent=0] @@ -71,5 +71,5 @@ The title of a table can be specified using a line prefixed by a `.`: ==== Further reading -Refer to the http://asciidoctor.org/docs/user-manual/#tables[Tables section of +Refer to the https://asciidoctor.org/docs/user-manual/#tables[Tables section of the Asciidoctor user manual] for more information about customizing tables. \ No newline at end of file diff --git a/samples/rest-notes-spring-data-rest/src/main/asciidoc/getting-started-guide.adoc b/samples/rest-notes-spring-data-rest/src/main/asciidoc/getting-started-guide.adoc index df16161ad..0068e8fc7 100644 --- a/samples/rest-notes-spring-data-rest/src/main/asciidoc/getting-started-guide.adoc +++ b/samples/rest-notes-spring-data-rest/src/main/asciidoc/getting-started-guide.adoc @@ -20,7 +20,7 @@ to describe the relationships between resources and to allow navigation between [getting-started-running-the-service] == Running the service -RESTful Notes is written using http://projects.spring.io/spring-boot[Spring Boot] which +RESTful Notes is written using https://projects.spring.io/spring-boot[Spring Boot] which makes it easy to get it up and running so that you can start exploring the REST API. The first step is to clone the Git repository: diff --git a/samples/rest-notes-spring-data-rest/src/test/java/com/example/notes/ApiDocumentation.java b/samples/rest-notes-spring-data-rest/src/test/java/com/example/notes/ApiDocumentation.java index 4eda380e7..498eee26d 100644 --- a/samples/rest-notes-spring-data-rest/src/test/java/com/example/notes/ApiDocumentation.java +++ b/samples/rest-notes-spring-data-rest/src/test/java/com/example/notes/ApiDocumentation.java @@ -125,7 +125,7 @@ public void notesListExample() throws Exception { this.noteRepository.deleteAll(); createNote("REST maturity model", - "http://martinfowler.com/articles/richardsonMaturityModel.html"); + "https://martinfowler.com/articles/richardsonMaturityModel.html"); createNote("Hypertext Application Language (HAL)", "http://stateless.co/hal_specification.html"); createNote("Application-Level Profile Semantics (ALPS)", "http://alps.io/spec/"); @@ -151,7 +151,7 @@ public void notesCreateExample() throws Exception { Map note = new HashMap(); note.put("title", "REST maturity model"); - note.put("body", "http://martinfowler.com/articles/richardsonMaturityModel.html"); + note.put("body", "https://martinfowler.com/articles/richardsonMaturityModel.html"); note.put("tags", Arrays.asList(tagLocation)); this.mockMvc.perform( @@ -179,7 +179,7 @@ public void noteGetExample() throws Exception { Map note = new HashMap(); note.put("title", "REST maturity model"); - note.put("body", "http://martinfowler.com/articles/richardsonMaturityModel.html"); + note.put("body", "https://martinfowler.com/articles/richardsonMaturityModel.html"); note.put("tags", Arrays.asList(tagLocation)); String noteLocation = this.mockMvc @@ -239,7 +239,7 @@ public void tagsCreateExample() throws Exception { public void noteUpdateExample() throws Exception { Map note = new HashMap(); note.put("title", "REST maturity model"); - note.put("body", "http://martinfowler.com/articles/richardsonMaturityModel.html"); + note.put("body", "https://martinfowler.com/articles/richardsonMaturityModel.html"); String noteLocation = this.mockMvc .perform( diff --git a/samples/rest-notes-spring-hateoas/src/docs/asciidoc/getting-started-guide.adoc b/samples/rest-notes-spring-hateoas/src/docs/asciidoc/getting-started-guide.adoc index 096e00abe..c951418c2 100644 --- a/samples/rest-notes-spring-hateoas/src/docs/asciidoc/getting-started-guide.adoc +++ b/samples/rest-notes-spring-hateoas/src/docs/asciidoc/getting-started-guide.adoc @@ -20,7 +20,7 @@ to describe the relationships between resources and to allow navigation between [getting-started-running-the-service] == Running the service -RESTful Notes is written using http://projects.spring.io/spring-boot[Spring Boot] which +RESTful Notes is written using https://projects.spring.io/spring-boot[Spring Boot] which makes it easy to get it up and running so that you can start exploring the REST API. The first step is to clone the Git repository: diff --git a/samples/rest-notes-spring-hateoas/src/test/java/com/example/notes/ApiDocumentation.java b/samples/rest-notes-spring-hateoas/src/test/java/com/example/notes/ApiDocumentation.java index a0166eda0..4c72fe816 100644 --- a/samples/rest-notes-spring-hateoas/src/test/java/com/example/notes/ApiDocumentation.java +++ b/samples/rest-notes-spring-hateoas/src/test/java/com/example/notes/ApiDocumentation.java @@ -151,7 +151,7 @@ public void notesListExample() throws Exception { this.noteRepository.deleteAll(); createNote("REST maturity model", - "http://martinfowler.com/articles/richardsonMaturityModel.html"); + "https://martinfowler.com/articles/richardsonMaturityModel.html"); createNote("Hypertext Application Language (HAL)", "http://stateless.co/hal_specification.html"); createNote("Application-Level Profile Semantics (ALPS)", "http://alps.io/spec/"); @@ -178,7 +178,7 @@ public void notesCreateExample() throws Exception { Map note = new HashMap(); note.put("title", "REST maturity model"); - note.put("body", "http://martinfowler.com/articles/richardsonMaturityModel.html"); + note.put("body", "https://martinfowler.com/articles/richardsonMaturityModel.html"); note.put("tags", Arrays.asList(tagLocation)); ConstrainedFields fields = new ConstrainedFields(NoteInput.class); @@ -209,7 +209,7 @@ public void noteGetExample() throws Exception { Map note = new HashMap(); note.put("title", "REST maturity model"); - note.put("body", "http://martinfowler.com/articles/richardsonMaturityModel.html"); + note.put("body", "https://martinfowler.com/articles/richardsonMaturityModel.html"); note.put("tags", Arrays.asList(tagLocation)); String noteLocation = this.mockMvc @@ -275,7 +275,7 @@ public void tagsCreateExample() throws Exception { public void noteUpdateExample() throws Exception { Map note = new HashMap(); note.put("title", "REST maturity model"); - note.put("body", "http://martinfowler.com/articles/richardsonMaturityModel.html"); + note.put("body", "https://martinfowler.com/articles/richardsonMaturityModel.html"); String noteLocation = this.mockMvc .perform( diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/hypermedia/HypermediaDocumentation.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/hypermedia/HypermediaDocumentation.java index 937dbbc8e..f259d3b2f 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/hypermedia/HypermediaDocumentation.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/hypermedia/HypermediaDocumentation.java @@ -146,7 +146,7 @@ public static Snippet links(LinkExtractor linkExtractor, * { * "_links": { * "self": { - * "href": "http://example.com/foo" + * "href": "https://example.com/foo" * } * } * } @@ -167,7 +167,7 @@ public static LinkExtractor halLinks() { * "links": [ * { * "rel": "self", - * "href": "http://example.com/foo" + * "href": "https://example.com/foo" * } * ] * } diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/preprocess/PrettyPrintingContentModifier.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/preprocess/PrettyPrintingContentModifier.java index 67f0949d7..8dbfaec78 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/preprocess/PrettyPrintingContentModifier.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/preprocess/PrettyPrintingContentModifier.java @@ -82,7 +82,7 @@ private static final class XmlPrettyPrinter implements PrettyPrinter { public byte[] prettyPrint(byte[] original) throws Exception { Transformer transformer = TransformerFactory.newInstance().newTransformer(); transformer.setOutputProperty(OutputKeys.INDENT, "yes"); - transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", + transformer.setOutputProperty("{https://xml.apache.org/xslt}indent-amount", "4"); transformer.setOutputProperty(OutputKeys.DOCTYPE_PUBLIC, "yes"); ByteArrayOutputStream transformed = new ByteArrayOutputStream(); diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/hypermedia/LinkExtractorsPayloadTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/hypermedia/LinkExtractorsPayloadTests.java index b6d8f4c3e..8889d3653 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/hypermedia/LinkExtractorsPayloadTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/hypermedia/LinkExtractorsPayloadTests.java @@ -68,23 +68,23 @@ public LinkExtractorsPayloadTests(LinkExtractor linkExtractor, String linkType) public void singleLink() throws IOException { Map> links = this.linkExtractor .extractLinks(createResponse("single-link")); - assertLinks(Arrays.asList(new Link("alpha", "http://alpha.example.com")), links); + assertLinks(Arrays.asList(new Link("alpha", "https://alpha.example.com")), links); } @Test public void multipleLinksWithDifferentRels() throws IOException { Map> links = this.linkExtractor .extractLinks(createResponse("multiple-links-different-rels")); - assertLinks(Arrays.asList(new Link("alpha", "http://alpha.example.com"), - new Link("bravo", "http://bravo.example.com")), links); + assertLinks(Arrays.asList(new Link("alpha", "https://alpha.example.com"), + new Link("bravo", "https://bravo.example.com")), links); } @Test public void multipleLinksWithSameRels() throws IOException { Map> links = this.linkExtractor .extractLinks(createResponse("multiple-links-same-rels")); - assertLinks(Arrays.asList(new Link("alpha", "http://alpha.example.com/one"), - new Link("alpha", "http://alpha.example.com/two")), links); + assertLinks(Arrays.asList(new Link("alpha", "https://alpha.example.com/one"), + new Link("alpha", "https://alpha.example.com/two")), links); } @Test diff --git a/spring-restdocs-core/src/test/resources/field-payloads/multiple-fields-and-embedded-and-links.json b/spring-restdocs-core/src/test/resources/field-payloads/multiple-fields-and-embedded-and-links.json index fdaf197d7..e4ceed00d 100644 --- a/spring-restdocs-core/src/test/resources/field-payloads/multiple-fields-and-embedded-and-links.json +++ b/spring-restdocs-core/src/test/resources/field-payloads/multiple-fields-and-embedded-and-links.json @@ -1,7 +1,7 @@ { "_links": { - "alpha": "http://alpha.example.com", - "bravo": "http://bravo.example.com" + "alpha": "https://alpha.example.com", + "bravo": "https://bravo.example.com" }, "_embedded": "embedded-test", "beta": "beta-value", diff --git a/spring-restdocs-core/src/test/resources/field-payloads/multiple-fields-and-links.json b/spring-restdocs-core/src/test/resources/field-payloads/multiple-fields-and-links.json index 794ece500..b4ca7edc3 100644 --- a/spring-restdocs-core/src/test/resources/field-payloads/multiple-fields-and-links.json +++ b/spring-restdocs-core/src/test/resources/field-payloads/multiple-fields-and-links.json @@ -1,7 +1,7 @@ { "_links": { - "alpha": "http://alpha.example.com", - "bravo": "http://bravo.example.com" + "alpha": "https://alpha.example.com", + "bravo": "https://bravo.example.com" }, "beta": "beta-value", "charlie": "charlie-value" diff --git a/spring-restdocs-core/src/test/resources/link-payloads/atom/multiple-links-different-rels.json b/spring-restdocs-core/src/test/resources/link-payloads/atom/multiple-links-different-rels.json index 35e63537d..f20e706c7 100644 --- a/spring-restdocs-core/src/test/resources/link-payloads/atom/multiple-links-different-rels.json +++ b/spring-restdocs-core/src/test/resources/link-payloads/atom/multiple-links-different-rels.json @@ -1,9 +1,9 @@ { "links": [ { "rel": "alpha", - "href": "http://alpha.example.com" + "href": "https://alpha.example.com" }, { "rel": "bravo", - "href": "http://bravo.example.com" + "href": "https://bravo.example.com" } ] } \ No newline at end of file diff --git a/spring-restdocs-core/src/test/resources/link-payloads/atom/multiple-links-same-rels.json b/spring-restdocs-core/src/test/resources/link-payloads/atom/multiple-links-same-rels.json index ff0d3f4ae..8257cb9ff 100644 --- a/spring-restdocs-core/src/test/resources/link-payloads/atom/multiple-links-same-rels.json +++ b/spring-restdocs-core/src/test/resources/link-payloads/atom/multiple-links-same-rels.json @@ -1,9 +1,9 @@ { "links": [ { "rel": "alpha", - "href": "http://alpha.example.com/one" + "href": "https://alpha.example.com/one" }, { "rel": "alpha", - "href": "http://alpha.example.com/two" + "href": "https://alpha.example.com/two" } ] } \ No newline at end of file diff --git a/spring-restdocs-core/src/test/resources/link-payloads/atom/single-link.json b/spring-restdocs-core/src/test/resources/link-payloads/atom/single-link.json index 57532675b..e50f46c13 100644 --- a/spring-restdocs-core/src/test/resources/link-payloads/atom/single-link.json +++ b/spring-restdocs-core/src/test/resources/link-payloads/atom/single-link.json @@ -1,6 +1,6 @@ { "links": [ { "rel": "alpha", - "href": "http://alpha.example.com" + "href": "https://alpha.example.com" } ] } \ No newline at end of file diff --git a/spring-restdocs-core/src/test/resources/link-payloads/atom/wrong-format.json b/spring-restdocs-core/src/test/resources/link-payloads/atom/wrong-format.json index a5e2e40fd..00c90d2f5 100644 --- a/spring-restdocs-core/src/test/resources/link-payloads/atom/wrong-format.json +++ b/spring-restdocs-core/src/test/resources/link-payloads/atom/wrong-format.json @@ -1,9 +1,9 @@ { "links": { "alpha": [{ - "href": "http://alpha.example.com/one" + "href": "https://alpha.example.com/one" }, { - "href": "http://alpha.example.com/two" + "href": "https://alpha.example.com/two" }] } } \ No newline at end of file diff --git a/spring-restdocs-core/src/test/resources/link-payloads/hal/multiple-links-different-rels.json b/spring-restdocs-core/src/test/resources/link-payloads/hal/multiple-links-different-rels.json index 08d0f3eaf..c329418c4 100644 --- a/spring-restdocs-core/src/test/resources/link-payloads/hal/multiple-links-different-rels.json +++ b/spring-restdocs-core/src/test/resources/link-payloads/hal/multiple-links-different-rels.json @@ -1,10 +1,10 @@ { "_links": { "alpha": { - "href": "http://alpha.example.com" + "href": "https://alpha.example.com" }, "bravo": { - "href": "http://bravo.example.com" + "href": "https://bravo.example.com" } } } \ No newline at end of file diff --git a/spring-restdocs-core/src/test/resources/link-payloads/hal/multiple-links-same-rels.json b/spring-restdocs-core/src/test/resources/link-payloads/hal/multiple-links-same-rels.json index 45ebca3ca..aa62edc51 100644 --- a/spring-restdocs-core/src/test/resources/link-payloads/hal/multiple-links-same-rels.json +++ b/spring-restdocs-core/src/test/resources/link-payloads/hal/multiple-links-same-rels.json @@ -1,9 +1,9 @@ { "_links": { "alpha": [{ - "href": "http://alpha.example.com/one" + "href": "https://alpha.example.com/one" }, { - "href": "http://alpha.example.com/two" + "href": "https://alpha.example.com/two" }] } } \ No newline at end of file diff --git a/spring-restdocs-core/src/test/resources/link-payloads/hal/single-link.json b/spring-restdocs-core/src/test/resources/link-payloads/hal/single-link.json index d19ca125c..64ece04cc 100644 --- a/spring-restdocs-core/src/test/resources/link-payloads/hal/single-link.json +++ b/spring-restdocs-core/src/test/resources/link-payloads/hal/single-link.json @@ -1,7 +1,7 @@ { "_links": { "alpha": { - "href": "http://alpha.example.com" + "href": "https://alpha.example.com" } } } \ No newline at end of file diff --git a/spring-restdocs-core/src/test/resources/link-payloads/hal/wrong-format.json b/spring-restdocs-core/src/test/resources/link-payloads/hal/wrong-format.json index 7c99aa4ef..a4d79046c 100644 --- a/spring-restdocs-core/src/test/resources/link-payloads/hal/wrong-format.json +++ b/spring-restdocs-core/src/test/resources/link-payloads/hal/wrong-format.json @@ -1,9 +1,9 @@ { "_links": [ { "rel": "alpha", - "href": "http://alpha.example.com/one" + "href": "https://alpha.example.com/one" }, { "rel": "alpha", - "href": "http://alpha.example.com/two" + "href": "https://alpha.example.com/two" } ] } \ No newline at end of file From 447cc4940e5916b6cef2cfe33b24e823f49a094f Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Tue, 26 Mar 2019 10:29:14 +0000 Subject: [PATCH 032/502] Polish "Use HTTPS for external links where possible" See gh-609 --- .../src/test/java/com/example/notes/ApiDocumentation.java | 6 +++--- .../src/test/java/com/example/notes/ApiDocumentation.java | 6 +++--- .../operation/preprocess/PrettyPrintingContentModifier.java | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/samples/rest-notes-spring-data-rest/src/test/java/com/example/notes/ApiDocumentation.java b/samples/rest-notes-spring-data-rest/src/test/java/com/example/notes/ApiDocumentation.java index 498eee26d..cabce1076 100644 --- a/samples/rest-notes-spring-data-rest/src/test/java/com/example/notes/ApiDocumentation.java +++ b/samples/rest-notes-spring-data-rest/src/test/java/com/example/notes/ApiDocumentation.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2015 the original author or authors. + * Copyright 2014-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. @@ -127,8 +127,8 @@ public void notesListExample() throws Exception { createNote("REST maturity model", "https://martinfowler.com/articles/richardsonMaturityModel.html"); createNote("Hypertext Application Language (HAL)", - "http://stateless.co/hal_specification.html"); - createNote("Application-Level Profile Semantics (ALPS)", "http://alps.io/spec/"); + "https://github.com/mikekelly/hal_specification"); + createNote("Application-Level Profile Semantics (ALPS)", "https://github.com/alps-io/spec"); this.mockMvc.perform(get("/notes")) .andExpect(status().isOk()) diff --git a/samples/rest-notes-spring-hateoas/src/test/java/com/example/notes/ApiDocumentation.java b/samples/rest-notes-spring-hateoas/src/test/java/com/example/notes/ApiDocumentation.java index 4c72fe816..3b9983fde 100644 --- a/samples/rest-notes-spring-hateoas/src/test/java/com/example/notes/ApiDocumentation.java +++ b/samples/rest-notes-spring-hateoas/src/test/java/com/example/notes/ApiDocumentation.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2015 the original author or authors. + * Copyright 2014-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. @@ -153,9 +153,9 @@ public void notesListExample() throws Exception { createNote("REST maturity model", "https://martinfowler.com/articles/richardsonMaturityModel.html"); createNote("Hypertext Application Language (HAL)", - "http://stateless.co/hal_specification.html"); - createNote("Application-Level Profile Semantics (ALPS)", "http://alps.io/spec/"); + "https://github.com/mikekelly/hal_specification"); + createNote("Application-Level Profile Semantics (ALPS)", "https://github.com/alps-io/spec"); this.document.snippets( responseFields( fieldWithPath("_embedded.notes").description("An array of <>"))); diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/preprocess/PrettyPrintingContentModifier.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/preprocess/PrettyPrintingContentModifier.java index 8dbfaec78..67f0949d7 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/preprocess/PrettyPrintingContentModifier.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/preprocess/PrettyPrintingContentModifier.java @@ -82,7 +82,7 @@ private static final class XmlPrettyPrinter implements PrettyPrinter { public byte[] prettyPrint(byte[] original) throws Exception { Transformer transformer = TransformerFactory.newInstance().newTransformer(); transformer.setOutputProperty(OutputKeys.INDENT, "yes"); - transformer.setOutputProperty("{https://xml.apache.org/xslt}indent-amount", + transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4"); transformer.setOutputProperty(OutputKeys.DOCTYPE_PUBLIC, "yes"); ByteArrayOutputStream transformed = new ByteArrayOutputStream(); From 1fa4c293c6d0931ae99ab64a45678e1e9b2f5028 Mon Sep 17 00:00:00 2001 From: Spring Operator Date: Tue, 26 Mar 2019 04:42:52 -0500 Subject: [PATCH 033/502] Use HTTPS for external links where possible See gh-610 --- .../docs/asciidoc/documenting-your-api.adoc | 2 +- docs/src/docs/asciidoc/getting-started.adoc | 8 +-- docs/src/docs/asciidoc/introduction.adoc | 2 +- samples/rest-notes-grails/README.md | 2 +- .../grails-app/conf/logback.groovy | 2 +- samples/rest-notes-slate/README.md | 2 +- samples/rest-notes-slate/slate/README.md | 50 +++++++++---------- .../slate/source/javascripts/app/_lang.js | 2 +- .../slate/source/javascripts/lib/_energize.js | 2 +- .../javascripts/lib/_jquery.highlight.js | 2 +- .../source/javascripts/lib/_jquery.tocify.js | 6 +-- .../source/javascripts/lib/_jquery_ui.js | 12 ++--- .../slate/source/javascripts/lib/_lunr.js | 8 +-- .../com/example/notes/ApiDocumentation.java | 8 +-- .../com/example/notes/ApiDocumentation.java | 2 +- .../PrettyPrintingContentModifier.java | 2 +- ...riModifyingOperationPreprocessorTests.java | 36 ++++++------- 17 files changed, 74 insertions(+), 74 deletions(-) diff --git a/docs/src/docs/asciidoc/documenting-your-api.adoc b/docs/src/docs/asciidoc/documenting-your-api.adoc index af9696198..d4918e4b6 100644 --- a/docs/src/docs/asciidoc/documenting-your-api.adoc +++ b/docs/src/docs/asciidoc/documenting-your-api.adoc @@ -769,7 +769,7 @@ A number of snippets are produced automatically when you document a request and call that is being documented | `httpie-request.adoc` -| Contains the http://httpie.org[`HTTPie`] command that is equivalent to the `MockMvc` +| Contains the https://httpie.org[`HTTPie`] command that is equivalent to the `MockMvc` call that is being documented | `http-request.adoc` diff --git a/docs/src/docs/asciidoc/getting-started.adoc b/docs/src/docs/asciidoc/getting-started.adoc index 69794b134..daa7739b5 100644 --- a/docs/src/docs/asciidoc/getting-started.adoc +++ b/docs/src/docs/asciidoc/getting-started.adoc @@ -19,12 +19,12 @@ If you want to jump straight in, a number of sample applications are available: | {samples}/rest-notes-spring-data-rest[Spring Data REST] | Maven | Demonstrates the creation of a getting started guide and an API guide for a service - implemented using http://projects.spring.io/spring-data-rest/[Spring Data REST]. + implemented using https://projects.spring.io/spring-data-rest/[Spring Data REST]. | {samples}/rest-notes-spring-hateoas[Spring HATEOAS] | Gradle | Demonstrates the creation of a getting started guide and an API guide for a service - implemented using http://projects.spring.io/spring-hateoas/[Spring HATEOAS]. + implemented using https://projects.spring.io/spring-hateoas/[Spring HATEOAS]. |=== @@ -54,7 +54,7 @@ If you want to jump straight in, a number of sample applications are available: | {samples}/rest-notes-slate[Slate] | Gradle | Demonstrates the use of Spring REST Docs with Markdown and - http://github.com/tripit/slate[Slate]. + https://github.com/tripit/slate[Slate]. | {samples}/testng[TestNG] | Gradle @@ -244,7 +244,7 @@ from where it will be included in the jar file. === Generating documentation snippets Spring REST Docs uses {spring-framework-docs}/#spring-mvc-test-framework[Spring's MVC Test framework] or -http://www.rest-assured.io[REST Assured] to make requests to the service that you are +http://rest-assured.io/[REST Assured] to make requests to the service that you are documenting. It then produces documentation snippets for the request and the resulting response. diff --git a/docs/src/docs/asciidoc/introduction.adoc b/docs/src/docs/asciidoc/introduction.adoc index d0943da84..a44c23398 100644 --- a/docs/src/docs/asciidoc/introduction.adoc +++ b/docs/src/docs/asciidoc/introduction.adoc @@ -12,7 +12,7 @@ can also be configured to use Markdown. Spring REST Docs makes use of snippets produced by tests written with {spring-framework-docs}/#spring-mvc-test-framework[Spring MVC Test] or -http://www.rest-assured.io[REST Assured]. This test-driven approach helps to guarantee the +http://rest-assured.io/[REST Assured]. This test-driven approach helps to guarantee the accuracy of your service's documentation. If a snippet is incorrect the test that produces it will fail. diff --git a/samples/rest-notes-grails/README.md b/samples/rest-notes-grails/README.md index d6c1be30c..0e62fb32b 100644 --- a/samples/rest-notes-grails/README.md +++ b/samples/rest-notes-grails/README.md @@ -3,7 +3,7 @@ ## Overview This is a sample project using Grails 3, Spock, and Spring REST docs. For more -information about the Grails framework please see [grails.org](http://grails.org). +information about the Grails framework please see [grails.org](https://grails.org). Grails is built on top of Spring Boot and Gradle so there are a few different ways to run this project including: diff --git a/samples/rest-notes-grails/grails-app/conf/logback.groovy b/samples/rest-notes-grails/grails-app/conf/logback.groovy index 72cda2de1..41467f2a0 100644 --- a/samples/rest-notes-grails/grails-app/conf/logback.groovy +++ b/samples/rest-notes-grails/grails-app/conf/logback.groovy @@ -17,7 +17,7 @@ import grails.util.BuildSettings import grails.util.Environment -// See http://logback.qos.ch/manual/groovy.html for details on configuration +// See https://logback.qos.ch/manual/groovy.html for details on configuration appender('STDOUT', ConsoleAppender) { encoder(PatternLayoutEncoder) { pattern = "%level %logger - %msg%n" diff --git a/samples/rest-notes-slate/README.md b/samples/rest-notes-slate/README.md index bb4de692c..37f6935ed 100644 --- a/samples/rest-notes-slate/README.md +++ b/samples/rest-notes-slate/README.md @@ -21,4 +21,4 @@ documentation by [ERB][4]. The combined Markdown document is then turned into HT [1]: https://github.com/tripit/slate [2]: slate/api-guide.md.erb [3]: src/test/java/com/example/notes/ApiDocumentation.java -[4]: http://ruby-doc.org/stdlib-2.2.3/libdoc/erb/rdoc/ERB.html \ No newline at end of file +[4]: https://ruby-doc.org/stdlib-2.2.3/libdoc/erb/rdoc/ERB.html \ No newline at end of file diff --git a/samples/rest-notes-slate/slate/README.md b/samples/rest-notes-slate/slate/README.md index 2f042e7f2..68c041283 100644 --- a/samples/rest-notes-slate/slate/README.md +++ b/samples/rest-notes-slate/slate/README.md @@ -7,7 +7,7 @@ Slate helps you create beautiful API documentation. Think of it as an intelligen Screenshot of Example Documentation created with Slate -*The example above was created with Slate. Check it out at [tripit.github.io/slate](http://tripit.github.io/slate).* +*The example above was created with Slate. Check it out at [tripit.github.io/slate](https://tripit.github.io/slate).* Features ------------ @@ -20,15 +20,15 @@ Features * **Write code samples in multiple languages** — if your API has bindings in multiple programming languages, you easily put in tabs to switch between them. In your document, you'll distinguish different languages by specifying the language name at the top of each code block, just like with Github Flavored Markdown! -* **Out-of-the-box syntax highlighting** for [almost 60 languages](http://rouge.jayferd.us/demo), no configuration required. +* **Out-of-the-box syntax highlighting** for [almost 60 languages](https://rouge.jayferd.us/demo), no configuration required. * **Automatic, smoothly scrolling table of contents** on the far left of the page. As you scroll, it displays your current position in the document. It's fast, too. We're using Slate at TripIt to build documentation for our new API, where our table of contents has over 180 entries. We've made sure that the performance remains excellent, even for larger documents. * **Let your users update your documentation for you** — by default, your Slate-generated documentation is hosted in a public Github repository. Not only does this mean you get free hosting for your docs with Github Pages, but it also makes it's simple for other developers to make pull requests to your docs if they find typos or other problems. Of course, if you don't want to, you're welcome to not use Github and host your docs elsewhere! -Getting starting with Slate is super easy! Simply fork this repository, and then follow the instructions below. Or, if you'd like to check out what Slate is capable of, take a look at the [sample docs](http://tripit.github.io/slate). +Getting starting with Slate is super easy! Simply fork this repository, and then follow the instructions below. Or, if you'd like to check out what Slate is capable of, take a look at the [sample docs](https://tripit.github.io/slate). - + Getting Started with Slate ------------------------------ @@ -66,34 +66,34 @@ Now that Slate is all set up your machine, you'll probably want to learn more ab Examples of Slate in the Wild --------------------------------- -* [Travis-CI's API docs](http://docs.travis-ci.com/api/) -* [Mozilla's localForage docs](http://mozilla.github.io/localForage/) -* [Mozilla Recroom](http://mozilla.github.io/recroom/) -* [ChaiOne Gameplan API docs](http://chaione.github.io/gameplanb2b/#introduction) -* [Drcaban's Build a Quine tutorial](http://drcabana.github.io/build-a-quine/#introduction) +* [Travis-CI's API docs](https://docs.travis-ci.com/api/) +* [Mozilla's localForage docs](https://mozilla.github.io/localForage/) +* [Mozilla Recroom](https://mozilla.github.io/recroom/) +* [ChaiOne Gameplan API docs](https://chaione.github.io/gameplanb2b/#introduction) +* [Drcaban's Build a Quine tutorial](https://drcabana.github.io/build-a-quine/#introduction) * [PricePlow API docs](https://www.priceplow.com/api/documentation) -* [Emerging Threats API docs](http://apidocs.emergingthreats.net/) -* [Appium docs](http://appium.io/slate/en/master) -* [Golazon Developer](http://developer.golazon.com) +* [Emerging Threats API docs](https://apidocs.emergingthreats.net/) +* [Appium docs](https://appium.io/slate/en/master) +* [Golazon Developer](https://developer.golazon.com) * [Dwolla API docs](https://docs.dwolla.com/) -* [RozpisyZapasu API docs](http://www.rozpisyzapasu.cz/dev/api/) -* [Codestar Framework Docs](http://codestarframework.com/documentation/) +* [RozpisyZapasu API docs](https://www.rozpisyzapasu.cz/dev/api/) +* [Codestar Framework Docs](https://codestarframework.com/documentation/) * [Buddycloud API](http://buddycloud.com/api) * [Crafty Clicks API](https://craftyclicks.co.uk/api/) * [Paracel API Reference](http://paracel.io/docs/api_reference.html) -* [Switch Payments Documentation](http://switchpayments.com/docs/) & [API](http://switchpayments.com/developers/) +* [Switch Payments Documentation](https://switchpayments.com/docs/) & [API](https://switchpayments.com/developers/) * [Coinbase API Reference](https://developers.coinbase.com/api) * [Whispir.io API](https://whispir.github.io/api) * [NASA API](https://data.nasa.gov/developer/external/planetary/) * [CardPay API](https://developers.cardpay.com/) * [IBM Cloudant](https://docs-testb.cloudant.com/content-review/_design/couchapp/index.html) -* [Bitrix basis components](http://bbc.bitrix.expert/) -* [viagogo API Documentation](http://developer.viagogo.net/) -* [Fidor Bank API Documentation](http://docs.fidor.de/) -* [Market Prophit API Documentation](http://developer.marketprophit.com/) -* [OAuth.io API Documentation](http://docs.oauth.io/) -* [Aircall for Developers](http://developer.aircall.io/) -* [SupportKit API Docs](http://docs.supportkit.io/) +* [Bitrix basis components](https://bbc.bitrix.expert/) +* [viagogo API Documentation](https://developer.viagogo.net/) +* [Fidor Bank API Documentation](https://docs.fidor.de/) +* [Market Prophit API Documentation](https://developer.marketprophit.com/) +* [OAuth.io API Documentation](https://docs.oauth.io/) +* [Aircall for Developers](https://developer.aircall.io/) +* [SupportKit API Docs](https://docs.smooch.io/) * [SocialRadar's LocationKit Docs](https://docs.locationkit.io/) * [SafetyCulture API Documentation](https://developer.safetyculture.io/) * [hosting.de API Documentation](https://www.hosting.de/docs/api/) @@ -109,7 +109,7 @@ Just [submit a issue](https://github.com/tripit/slate/issues) to the Slate Githu Contributors -------------------- -Slate was built by [Robert Lord](https://lord.io) while at [TripIt](http://tripit.com). +Slate was built by [Robert Lord](https://lord.io) while at [TripIt](https://tripit.com). Thanks to the following people who have submitted major pull requests: @@ -117,7 +117,7 @@ Thanks to the following people who have submitted major pull requests: - [@bootstraponline](https://github.com/bootstraponline) - [@realityking](https://github.com/realityking) -Also, thanks to [Sauce Labs](http://saucelabs.com) for helping sponsor the project. +Also, thanks to [Sauce Labs](https://saucelabs.com) for helping sponsor the project. Special Thanks -------------------- @@ -125,4 +125,4 @@ Special Thanks - [jquery.tocify.js](https://github.com/gfranko/jquery.tocify.js) - [middleman-syntax](https://github.com/middleman/middleman-syntax) - [middleman-gh-pages](https://github.com/neo/middleman-gh-pages) -- [Font Awesome](http://fortawesome.github.io/Font-Awesome/) +- [Font Awesome](https://fortawesome.github.io/Font-Awesome/) diff --git a/samples/rest-notes-slate/slate/source/javascripts/app/_lang.js b/samples/rest-notes-slate/slate/source/javascripts/app/_lang.js index 9d45388ef..9ba1aebc1 100644 --- a/samples/rest-notes-slate/slate/source/javascripts/app/_lang.js +++ b/samples/rest-notes-slate/slate/source/javascripts/app/_lang.js @@ -61,7 +61,7 @@ under the License. key = decodeURIComponent(key); // missing `=` should be `null`: - // http://w3.org/TR/2012/WD-url-20120524/#collect-url-parameters + // https://w3.org/TR/2012/WD-url-20120524/#collect-url-parameters val = val === undefined ? null : decodeURIComponent(val); if (!ret.hasOwnProperty(key)) { diff --git a/samples/rest-notes-slate/slate/source/javascripts/lib/_energize.js b/samples/rest-notes-slate/slate/source/javascripts/lib/_energize.js index 6798f3c03..582407842 100644 --- a/samples/rest-notes-slate/slate/source/javascripts/lib/_energize.js +++ b/samples/rest-notes-slate/slate/source/javascripts/lib/_energize.js @@ -115,7 +115,7 @@ /** * Special logic for standalone web apps - * See http://stackoverflow.com/questions/2898740/iphone-safari-web-app-opens-links-in-new-window + * See https://stackoverflow.com/questions/2898740/iphone-safari-web-app-opens-links-in-new-window */ if(standAlone) { window.location = target.getAttribute("href"); diff --git a/samples/rest-notes-slate/slate/source/javascripts/lib/_jquery.highlight.js b/samples/rest-notes-slate/slate/source/javascripts/lib/_jquery.highlight.js index 9dcf3c7af..6c2408608 100644 --- a/samples/rest-notes-slate/slate/source/javascripts/lib/_jquery.highlight.js +++ b/samples/rest-notes-slate/slate/source/javascripts/lib/_jquery.highlight.js @@ -2,7 +2,7 @@ * jQuery Highlight plugin * * Based on highlight v3 by Johann Burkard - * http://johannburkard.de/blog/programming/javascript/highlight-javascript-text-higlighting-jquery-plugin.html + * https://johannburkard.de/blog/programming/javascript/highlight-javascript-text-higlighting-jquery-plugin.html * * Code a little bit refactored and cleaned (in my humble opinion). * Most important changes: diff --git a/samples/rest-notes-slate/slate/source/javascripts/lib/_jquery.tocify.js b/samples/rest-notes-slate/slate/source/javascripts/lib/_jquery.tocify.js index 91cf63791..b60bc686e 100644 --- a/samples/rest-notes-slate/slate/source/javascripts/lib/_jquery.tocify.js +++ b/samples/rest-notes-slate/slate/source/javascripts/lib/_jquery.tocify.js @@ -1,5 +1,5 @@ /* jquery Tocify - v1.8.0 - 2013-09-16 -* http://www.gregfranko.com/jquery.tocify.js/ +* http://gregfranko.com/jquery.tocify.js/ * Copyright (c) 2013 Greg Franko; Licensed MIT * Modified lightly by Robert Lord to fix a bug I found, * and also so it adds ids to headers @@ -10,7 +10,7 @@ // Immediately-Invoked Function Expression (IIFE) [Ben Alman Blog Post](http://benalman.com/news/2010/11/immediately-invoked-function-expression/) that calls another IIFE that contains all of the plugin logic. I used this pattern so that anyone viewing this code would not have to scroll to the bottom of the page to view the local parameters that were passed to the main IIFE. (function(tocify) { - // ECMAScript 5 Strict Mode: [John Resig Blog Post](http://ejohn.org/blog/ecmascript-5-strict-mode-json-and-more/) + // ECMAScript 5 Strict Mode: [John Resig Blog Post](https://johnresig.com/blog/ecmascript-5-strict-mode-json-and-more/) "use strict"; // Calls the second IIFE and locally passes in the global jQuery, window, and document objects @@ -21,7 +21,7 @@ // Locally passes in `jQuery`, the `window` object, the `document` object, and an `undefined` variable. The `jQuery`, `window` and `document` objects are passed in locally, to improve performance, since javascript first searches for a variable match within the local variables set before searching the global variables set. All of the global variables are also passed in locally to be minifier friendly. `undefined` can be passed in locally, because it is not a reserved word in JavaScript. (function($, window, document, undefined) { - // ECMAScript 5 Strict Mode: [John Resig Blog Post](http://ejohn.org/blog/ecmascript-5-strict-mode-json-and-more/) + // ECMAScript 5 Strict Mode: [John Resig Blog Post](https://johnresig.com/blog/ecmascript-5-strict-mode-json-and-more/) "use strict"; var tocClassName = "tocify", diff --git a/samples/rest-notes-slate/slate/source/javascripts/lib/_jquery_ui.js b/samples/rest-notes-slate/slate/source/javascripts/lib/_jquery_ui.js index 637e9c142..2417b46e6 100644 --- a/samples/rest-notes-slate/slate/source/javascripts/lib/_jquery_ui.js +++ b/samples/rest-notes-slate/slate/source/javascripts/lib/_jquery_ui.js @@ -1,5 +1,5 @@ /*! jQuery UI - v1.11.3 - 2015-02-12 - * http://jqueryui.com + * https://jqueryui.com * Includes: widget.js * Copyright 2015 jQuery Foundation and other contributors; Licensed MIT */ @@ -16,13 +16,13 @@ }(function( $ ) { /*! * jQuery UI Widget 1.11.3 - * http://jqueryui.com + * https://jqueryui.com * * Copyright jQuery Foundation and other contributors * Released under the MIT license. - * http://jquery.org/license + * https://jquery.org/license * - * http://api.jqueryui.com/jQuery.widget/ + * https://api.jqueryui.com/jQuery.widget/ */ @@ -41,7 +41,7 @@ $( elem ).triggerHandler( "remove" ); } - // http://bugs.jquery.com/ticket/8235 + // https://bugs.jquery.com/ticket/8235 } catch ( e ) {} } orig( elems ); @@ -305,7 +305,7 @@ .unbind( this.eventNamespace ) .removeData( this.widgetFullName ) // support: jquery <1.6.3 - // http://bugs.jquery.com/ticket/9413 + // https://bugs.jquery.com/ticket/9413 .removeData( $.camelCase( this.widgetFullName ) ); this.widget() .unbind( this.eventNamespace ) diff --git a/samples/rest-notes-slate/slate/source/javascripts/lib/_lunr.js b/samples/rest-notes-slate/slate/source/javascripts/lib/_lunr.js index 54457dab7..31aa92464 100644 --- a/samples/rest-notes-slate/slate/source/javascripts/lib/_lunr.js +++ b/samples/rest-notes-slate/slate/source/javascripts/lib/_lunr.js @@ -1,5 +1,5 @@ /** - * lunr - http://lunrjs.com - A bit like Solr, but much smaller and not as bright - 0.5.7 + * lunr - https://lunrjs.com - A bit like Solr, but much smaller and not as bright - 0.5.7 * Copyright (C) 2014 Oliver Nightingale * MIT Licensed * @license @@ -1298,12 +1298,12 @@ /*! * lunr.stemmer * Copyright (C) 2014 Oliver Nightingale - * Includes code from - http://tartarus.org/~martin/PorterStemmer/js.txt + * Includes code from - https://tartarus.org/~martin/PorterStemmer/js.txt */ /** * lunr.stemmer is an english language stemmer, this is a JavaScript - * implementation of the PorterStemmer taken from http://tartaurs.org/~martin + * implementation of the PorterStemmer taken from https://tartaurs.org/~martin * * @module * @param {String} str The string to stem @@ -1689,7 +1689,7 @@ /*! * lunr.stemmer * Copyright (C) 2014 Oliver Nightingale - * Includes code from - http://tartarus.org/~martin/PorterStemmer/js.txt + * Includes code from - https://tartarus.org/~martin/PorterStemmer/js.txt */ /** diff --git a/samples/rest-notes-slate/src/test/java/com/example/notes/ApiDocumentation.java b/samples/rest-notes-slate/src/test/java/com/example/notes/ApiDocumentation.java index 56a5b645e..417d970ac 100644 --- a/samples/rest-notes-slate/src/test/java/com/example/notes/ApiDocumentation.java +++ b/samples/rest-notes-slate/src/test/java/com/example/notes/ApiDocumentation.java @@ -126,7 +126,7 @@ public void notesListExample() throws Exception { this.noteRepository.deleteAll(); createNote("REST maturity model", - "http://martinfowler.com/articles/richardsonMaturityModel.html"); + "https://martinfowler.com/articles/richardsonMaturityModel.html"); createNote("Hypertext Application Language (HAL)", "http://stateless.co/hal_specification.html"); createNote("Application-Level Profile Semantics (ALPS)", "http://alps.io/spec/"); @@ -152,7 +152,7 @@ public void notesCreateExample() throws Exception { Map note = new HashMap(); note.put("title", "REST maturity model"); - note.put("body", "http://martinfowler.com/articles/richardsonMaturityModel.html"); + note.put("body", "https://martinfowler.com/articles/richardsonMaturityModel.html"); note.put("tags", Arrays.asList(tagLocation)); this.mockMvc.perform( @@ -180,7 +180,7 @@ public void noteGetExample() throws Exception { Map note = new HashMap(); note.put("title", "REST maturity model"); - note.put("body", "http://martinfowler.com/articles/richardsonMaturityModel.html"); + note.put("body", "https://martinfowler.com/articles/richardsonMaturityModel.html"); note.put("tags", Arrays.asList(tagLocation)); String noteLocation = this.mockMvc @@ -240,7 +240,7 @@ public void tagsCreateExample() throws Exception { public void noteUpdateExample() throws Exception { Map note = new HashMap(); note.put("title", "REST maturity model"); - note.put("body", "http://martinfowler.com/articles/richardsonMaturityModel.html"); + note.put("body", "https://martinfowler.com/articles/richardsonMaturityModel.html"); String noteLocation = this.mockMvc .perform( diff --git a/samples/rest-notes-spring-hateoas/src/test/java/com/example/notes/ApiDocumentation.java b/samples/rest-notes-spring-hateoas/src/test/java/com/example/notes/ApiDocumentation.java index 23d51fcf4..1fdc0f993 100644 --- a/samples/rest-notes-spring-hateoas/src/test/java/com/example/notes/ApiDocumentation.java +++ b/samples/rest-notes-spring-hateoas/src/test/java/com/example/notes/ApiDocumentation.java @@ -147,7 +147,7 @@ public void indexExample() throws Exception { public void notesListExample() throws Exception { this.noteRepository.deleteAll(); - createNote("REST maturity model", "https://martinfowler.com/articles/richardsonMaturityModel.html"); + createNote("REST maturity model", "https://martinfowler.com/articles/richardsonMaturityModel.html");<<<<<<< HEAD createNote("Hypertext Application Language (HAL)", "https://github.com/mikekelly/hal_specification"); createNote("Application-Level Profile Semantics (ALPS)", "https://github.com/alps-io/spec"); diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/preprocess/PrettyPrintingContentModifier.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/preprocess/PrettyPrintingContentModifier.java index 67f0949d7..8dbfaec78 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/preprocess/PrettyPrintingContentModifier.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/preprocess/PrettyPrintingContentModifier.java @@ -82,7 +82,7 @@ private static final class XmlPrettyPrinter implements PrettyPrinter { public byte[] prettyPrint(byte[] original) throws Exception { Transformer transformer = TransformerFactory.newInstance().newTransformer(); transformer.setOutputProperty(OutputKeys.INDENT, "yes"); - transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", + transformer.setOutputProperty("{https://xml.apache.org/xslt}indent-amount", "4"); transformer.setOutputProperty(OutputKeys.DOCTYPE_PUBLIC, "yes"); ByteArrayOutputStream transformed = new ByteArrayOutputStream(); diff --git a/spring-restdocs-restassured/src/test/java/org/springframework/restdocs/restassured/operation/preprocess/UriModifyingOperationPreprocessorTests.java b/spring-restdocs-restassured/src/test/java/org/springframework/restdocs/restassured/operation/preprocess/UriModifyingOperationPreprocessorTests.java index 1782a4d79..a356d1d22 100644 --- a/spring-restdocs-restassured/src/test/java/org/springframework/restdocs/restassured/operation/preprocess/UriModifyingOperationPreprocessorTests.java +++ b/spring-restdocs-restassured/src/test/java/org/springframework/restdocs/restassured/operation/preprocess/UriModifyingOperationPreprocessorTests.java @@ -63,9 +63,9 @@ public void requestUriSchemeCanBeModified() { public void requestUriHostCanBeModified() { this.preprocessor.host("api.example.com"); OperationRequest processed = this.preprocessor - .preprocess(createRequestWithUri("http://api.foo.com:12345")); + .preprocess(createRequestWithUri("https://api.foo.com:12345")); assertThat(processed.getUri(), - is(equalTo(URI.create("http://api.example.com:12345")))); + is(equalTo(URI.create("https://api.example.com:12345")))); assertThat(processed.getHeaders().getFirst(HttpHeaders.HOST), is(equalTo("api.example.com:12345"))); } @@ -74,9 +74,9 @@ public void requestUriHostCanBeModified() { public void requestUriPortCanBeModified() { this.preprocessor.port(23456); OperationRequest processed = this.preprocessor - .preprocess(createRequestWithUri("http://api.example.com:12345")); + .preprocess(createRequestWithUri("https://api.example.com:12345")); assertThat(processed.getUri(), - is(equalTo(URI.create("http://api.example.com:23456")))); + is(equalTo(URI.create("https://api.example.com:23456")))); assertThat(processed.getHeaders().getFirst(HttpHeaders.HOST), is(equalTo("api.example.com:23456"))); } @@ -85,8 +85,8 @@ public void requestUriPortCanBeModified() { public void requestUriPortCanBeRemoved() { this.preprocessor.removePort(); OperationRequest processed = this.preprocessor - .preprocess(createRequestWithUri("http://api.example.com:12345")); - assertThat(processed.getUri(), is(equalTo(URI.create("http://api.example.com")))); + .preprocess(createRequestWithUri("https://api.example.com:12345")); + assertThat(processed.getUri(), is(equalTo(URI.create("https://api.example.com")))); assertThat(processed.getHeaders().getFirst(HttpHeaders.HOST), is(equalTo("api.example.com"))); } @@ -95,27 +95,27 @@ public void requestUriPortCanBeRemoved() { public void requestUriPathIsPreserved() { this.preprocessor.removePort(); OperationRequest processed = this.preprocessor - .preprocess(createRequestWithUri("http://api.example.com:12345/foo/bar")); + .preprocess(createRequestWithUri("https://api.example.com:12345/foo/bar")); assertThat(processed.getUri(), - is(equalTo(URI.create("http://api.example.com/foo/bar")))); + is(equalTo(URI.create("https://api.example.com/foo/bar")))); } @Test public void requestUriQueryIsPreserved() { this.preprocessor.removePort(); OperationRequest processed = this.preprocessor - .preprocess(createRequestWithUri("http://api.example.com:12345?foo=bar")); + .preprocess(createRequestWithUri("https://api.example.com:12345?foo=bar")); assertThat(processed.getUri(), - is(equalTo(URI.create("http://api.example.com?foo=bar")))); + is(equalTo(URI.create("https://api.example.com?foo=bar")))); } @Test public void requestUriAnchorIsPreserved() { this.preprocessor.removePort(); OperationRequest processed = this.preprocessor - .preprocess(createRequestWithUri("http://api.example.com:12345#foo")); + .preprocess(createRequestWithUri("https://api.example.com:12345#foo")); assertThat(processed.getUri(), - is(equalTo(URI.create("http://api.example.com#foo")))); + is(equalTo(URI.create("https://api.example.com#foo")))); } @Test @@ -135,7 +135,7 @@ public void requestContentUriHostCanBeModified() { .preprocess(createRequestWithContent( "The uri 'http://localhost:12345' should be used")); assertThat(new String(processed.getContent()), - is(equalTo("The uri 'http://api.example.com:12345' should be used"))); + is(equalTo("The uri 'https://api.example.com:12345' should be used"))); } @Test @@ -215,7 +215,7 @@ public void responseContentUriHostCanBeModified() { .preprocess(createResponseWithContent( "The uri 'http://localhost:12345' should be used")); assertThat(new String(processed.getContent()), - is(equalTo("The uri 'http://api.example.com:12345' should be used"))); + is(equalTo("The uri 'https://api.example.com:12345' should be used"))); } @Test @@ -283,7 +283,7 @@ public void urisInRequestHeadersCanBeModified() { OperationRequest processed = this.preprocessor.host("api.example.com") .preprocess(createRequestWithHeader("Foo", "http://locahost:12345")); assertThat(processed.getHeaders().getFirst("Foo"), - is(equalTo("http://api.example.com:12345"))); + is(equalTo("https://api.example.com:12345"))); assertThat(processed.getHeaders().getFirst("Host"), is(equalTo("api.example.com"))); } @@ -293,7 +293,7 @@ public void urisInResponseHeadersCanBeModified() { OperationResponse processed = this.preprocessor.host("api.example.com") .preprocess(createResponseWithHeader("Foo", "http://locahost:12345")); assertThat(processed.getHeaders().getFirst("Foo"), - is(equalTo("http://api.example.com:12345"))); + is(equalTo("https://api.example.com:12345"))); } @Test @@ -301,7 +301,7 @@ public void urisInRequestPartHeadersCanBeModified() { OperationRequest processed = this.preprocessor.host("api.example.com").preprocess( createRequestWithPartWithHeader("Foo", "http://locahost:12345")); assertThat(processed.getParts().iterator().next().getHeaders().getFirst("Foo"), - is(equalTo("http://api.example.com:12345"))); + is(equalTo("https://api.example.com:12345"))); } @Test @@ -310,7 +310,7 @@ public void urisInRequestPartContentCanBeModified() { .preprocess(createRequestWithPartWithContent( "The uri 'http://localhost:12345' should be used")); assertThat(new String(processed.getParts().iterator().next().getContent()), - is(equalTo("The uri 'http://api.example.com:12345' should be used"))); + is(equalTo("The uri 'https://api.example.com:12345' should be used"))); } @Test From 9444083b81eac7f09b6f058f99a1115da0039ffc Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Tue, 26 Mar 2019 11:07:18 +0000 Subject: [PATCH 034/502] Polish "Use HTTPS for external links where possible" See gh-610 --- .../rest-notes-slate/slate/source/api-guide.md.erb | 6 +++--- .../java/com/example/notes/ApiDocumentation.java | 4 ++-- .../src/main/asciidoc/api-guide.adoc | 8 ++++---- .../src/main/asciidoc/getting-started-guide.adoc | 3 ++- .../src/docs/asciidoc/api-guide.adoc | 8 ++++---- .../java/com/example/notes/ApiDocumentation.java | 2 +- .../preprocess/PrettyPrintingContentModifier.java | 2 +- .../UriModifyingOperationPreprocessorTests.java | 14 +++++++------- 8 files changed, 24 insertions(+), 23 deletions(-) diff --git a/samples/rest-notes-slate/slate/source/api-guide.md.erb b/samples/rest-notes-slate/slate/source/api-guide.md.erb index 11248a3ea..77dab5229 100644 --- a/samples/rest-notes-slate/slate/source/api-guide.md.erb +++ b/samples/rest-notes-slate/slate/source/api-guide.md.erb @@ -49,9 +49,9 @@ that describes the problem. The error object has the following structure: ## Hypermedia RESTful Notes uses hypermedia and resources include links to other resources in their -responses. Responses are in [Hypertext Application Language (HAL)](http://stateless.co/hal_specification.html format). -Links can be found beneath the `_links` key. Users of the API should not create URIs -themselves, instead they should use the above-described links to navigate +responses. Responses are in [Hypertext Application Language (HAL)](https://github.com/mikekelly/hal_specification) +format. Links can be found beneath the `_links` key. Users of the API should not create +URIs themselves, instead they should use the above-described links to navigate diff --git a/samples/rest-notes-slate/src/test/java/com/example/notes/ApiDocumentation.java b/samples/rest-notes-slate/src/test/java/com/example/notes/ApiDocumentation.java index 417d970ac..ef702fa15 100644 --- a/samples/rest-notes-slate/src/test/java/com/example/notes/ApiDocumentation.java +++ b/samples/rest-notes-slate/src/test/java/com/example/notes/ApiDocumentation.java @@ -128,8 +128,8 @@ public void notesListExample() throws Exception { createNote("REST maturity model", "https://martinfowler.com/articles/richardsonMaturityModel.html"); createNote("Hypertext Application Language (HAL)", - "http://stateless.co/hal_specification.html"); - createNote("Application-Level Profile Semantics (ALPS)", "http://alps.io/spec/"); + "https://github.com/mikekelly/hal_specification"); + createNote("Application-Level Profile Semantics (ALPS)", "https://github.com/alps-io/spec"); this.mockMvc.perform(get("/notes")) .andExpect(status().isOk()) diff --git a/samples/rest-notes-spring-data-rest/src/main/asciidoc/api-guide.adoc b/samples/rest-notes-spring-data-rest/src/main/asciidoc/api-guide.adoc index 4f7697d70..45a80cb38 100644 --- a/samples/rest-notes-spring-data-rest/src/main/asciidoc/api-guide.adoc +++ b/samples/rest-notes-spring-data-rest/src/main/asciidoc/api-guide.adoc @@ -75,10 +75,10 @@ include::{snippets}/error-example/http-response.adoc[] == Hypermedia RESTful Notes uses hypermedia and resources include links to other resources in their -responses. Responses are in http://stateless.co/hal_specification.html[Hypertext Application -from resource to resource. -Language (HAL)] format. Links can be found beneath the `_links` key. Users of the API should -not create URIs themselves, instead they should use the above-described links to navigate +responses. Responses are in https://github.com/mikekelly/hal_specification[Hypertext +Application Language (HAL)] format. Links can be found beneath the `_links` key. Users of +the API should not create URIs themselves, instead they should use the above-described +links to navigate from resource to resource. [[resources]] = Resources diff --git a/samples/rest-notes-spring-data-rest/src/main/asciidoc/getting-started-guide.adoc b/samples/rest-notes-spring-data-rest/src/main/asciidoc/getting-started-guide.adoc index 0068e8fc7..78a442369 100644 --- a/samples/rest-notes-spring-data-rest/src/main/asciidoc/getting-started-guide.adoc +++ b/samples/rest-notes-spring-data-rest/src/main/asciidoc/getting-started-guide.adoc @@ -45,7 +45,8 @@ cURL: include::{snippets}/index/1/curl-request.adoc[] This request should yield the following response in the -http://stateless.co/hal_specification.html[Hypertext Application Language (HAL)] format: +https://github.com/mikekelly/hal_specification[Hypertext Application Language (HAL)] +format: include::{snippets}/index/1/http-response.adoc[] diff --git a/samples/rest-notes-spring-hateoas/src/docs/asciidoc/api-guide.adoc b/samples/rest-notes-spring-hateoas/src/docs/asciidoc/api-guide.adoc index c0a42afde..30d3d1591 100644 --- a/samples/rest-notes-spring-hateoas/src/docs/asciidoc/api-guide.adoc +++ b/samples/rest-notes-spring-hateoas/src/docs/asciidoc/api-guide.adoc @@ -82,10 +82,10 @@ include::{snippets}/error-example/http-response.adoc[] == Hypermedia RESTful Notes uses hypermedia and resources include links to other resources in their -responses. Responses are in http://stateless.co/hal_specification.html[Hypertext Application -from resource to resource. -Language (HAL)] format. Links can be found beneath the `_links` key. Users of the API should -not create URIs themselves, instead they should use the above-described links to navigate +responses. Responses are in https://github.com/mikekelly/hal_specification[Hypertext +Application Language (HAL)] format. Links can be found beneath the `_links` key. Users of +the API should not create URIs themselves, instead they should use the above-described +links to navigate from resource to resource. [[resources]] = Resources diff --git a/samples/rest-notes-spring-hateoas/src/test/java/com/example/notes/ApiDocumentation.java b/samples/rest-notes-spring-hateoas/src/test/java/com/example/notes/ApiDocumentation.java index 1fdc0f993..23d51fcf4 100644 --- a/samples/rest-notes-spring-hateoas/src/test/java/com/example/notes/ApiDocumentation.java +++ b/samples/rest-notes-spring-hateoas/src/test/java/com/example/notes/ApiDocumentation.java @@ -147,7 +147,7 @@ public void indexExample() throws Exception { public void notesListExample() throws Exception { this.noteRepository.deleteAll(); - createNote("REST maturity model", "https://martinfowler.com/articles/richardsonMaturityModel.html");<<<<<<< HEAD + createNote("REST maturity model", "https://martinfowler.com/articles/richardsonMaturityModel.html"); createNote("Hypertext Application Language (HAL)", "https://github.com/mikekelly/hal_specification"); createNote("Application-Level Profile Semantics (ALPS)", "https://github.com/alps-io/spec"); diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/preprocess/PrettyPrintingContentModifier.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/preprocess/PrettyPrintingContentModifier.java index 8dbfaec78..67f0949d7 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/preprocess/PrettyPrintingContentModifier.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/preprocess/PrettyPrintingContentModifier.java @@ -82,7 +82,7 @@ private static final class XmlPrettyPrinter implements PrettyPrinter { public byte[] prettyPrint(byte[] original) throws Exception { Transformer transformer = TransformerFactory.newInstance().newTransformer(); transformer.setOutputProperty(OutputKeys.INDENT, "yes"); - transformer.setOutputProperty("{https://xml.apache.org/xslt}indent-amount", + transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4"); transformer.setOutputProperty(OutputKeys.DOCTYPE_PUBLIC, "yes"); ByteArrayOutputStream transformed = new ByteArrayOutputStream(); diff --git a/spring-restdocs-restassured/src/test/java/org/springframework/restdocs/restassured/operation/preprocess/UriModifyingOperationPreprocessorTests.java b/spring-restdocs-restassured/src/test/java/org/springframework/restdocs/restassured/operation/preprocess/UriModifyingOperationPreprocessorTests.java index a356d1d22..746e2915d 100644 --- a/spring-restdocs-restassured/src/test/java/org/springframework/restdocs/restassured/operation/preprocess/UriModifyingOperationPreprocessorTests.java +++ b/spring-restdocs-restassured/src/test/java/org/springframework/restdocs/restassured/operation/preprocess/UriModifyingOperationPreprocessorTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2016 the original author or authors. + * Copyright 2014-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. @@ -133,7 +133,7 @@ public void requestContentUriHostCanBeModified() { this.preprocessor.host("api.example.com"); OperationRequest processed = this.preprocessor .preprocess(createRequestWithContent( - "The uri 'http://localhost:12345' should be used")); + "The uri 'https://localhost:12345' should be used")); assertThat(new String(processed.getContent()), is(equalTo("The uri 'https://api.example.com:12345' should be used"))); } @@ -213,7 +213,7 @@ public void responseContentUriHostCanBeModified() { this.preprocessor.host("api.example.com"); OperationResponse processed = this.preprocessor .preprocess(createResponseWithContent( - "The uri 'http://localhost:12345' should be used")); + "The uri 'https://localhost:12345' should be used")); assertThat(new String(processed.getContent()), is(equalTo("The uri 'https://api.example.com:12345' should be used"))); } @@ -281,7 +281,7 @@ public void responseContentUriAnchorIsPreserved() { @Test public void urisInRequestHeadersCanBeModified() { OperationRequest processed = this.preprocessor.host("api.example.com") - .preprocess(createRequestWithHeader("Foo", "http://locahost:12345")); + .preprocess(createRequestWithHeader("Foo", "https://locahost:12345")); assertThat(processed.getHeaders().getFirst("Foo"), is(equalTo("https://api.example.com:12345"))); assertThat(processed.getHeaders().getFirst("Host"), @@ -291,7 +291,7 @@ public void urisInRequestHeadersCanBeModified() { @Test public void urisInResponseHeadersCanBeModified() { OperationResponse processed = this.preprocessor.host("api.example.com") - .preprocess(createResponseWithHeader("Foo", "http://locahost:12345")); + .preprocess(createResponseWithHeader("Foo", "https://locahost:12345")); assertThat(processed.getHeaders().getFirst("Foo"), is(equalTo("https://api.example.com:12345"))); } @@ -299,7 +299,7 @@ public void urisInResponseHeadersCanBeModified() { @Test public void urisInRequestPartHeadersCanBeModified() { OperationRequest processed = this.preprocessor.host("api.example.com").preprocess( - createRequestWithPartWithHeader("Foo", "http://locahost:12345")); + createRequestWithPartWithHeader("Foo", "https://locahost:12345")); assertThat(processed.getParts().iterator().next().getHeaders().getFirst("Foo"), is(equalTo("https://api.example.com:12345"))); } @@ -308,7 +308,7 @@ public void urisInRequestPartHeadersCanBeModified() { public void urisInRequestPartContentCanBeModified() { OperationRequest processed = this.preprocessor.host("api.example.com") .preprocess(createRequestWithPartWithContent( - "The uri 'http://localhost:12345' should be used")); + "The uri 'https://localhost:12345' should be used")); assertThat(new String(processed.getParts().iterator().next().getContent()), is(equalTo("The uri 'https://api.example.com:12345' should be used"))); } From cb5d7c2220b402f5f591879e6f845d67811cfb48 Mon Sep 17 00:00:00 2001 From: Spring Operator Date: Tue, 26 Mar 2019 04:43:01 -0500 Subject: [PATCH 035/502] Use HTTPS for externals links where possible See gh-611 --- .../slate/source/index.html.md | 10 ++-- .../slate/source/javascripts/lib/_jquery.js | 50 +++++++++---------- .../PrettyPrintingContentModifier.java | 2 +- ...riModifyingOperationPreprocessorTests.java | 36 ++++++------- 4 files changed, 49 insertions(+), 49 deletions(-) diff --git a/samples/rest-notes-slate/slate/source/index.html.md b/samples/rest-notes-slate/slate/source/index.html.md index fc26b1964..1e776f51e 100644 --- a/samples/rest-notes-slate/slate/source/index.html.md +++ b/samples/rest-notes-slate/slate/source/index.html.md @@ -55,7 +55,7 @@ let api = kittn.authorize('meowmeowmeow'); > Make sure to replace `meowmeowmeow` with your API key. -Kittn uses API keys to allow access to the API. You can register a new Kittn API key at our [developer portal](http://example.com/developers). +Kittn uses API keys to allow access to the API. You can register a new Kittn API key at our [developer portal](https://example.com/developers). Kittn expects for the API key to be included in all API requests to the server in a header that looks like the following: @@ -84,7 +84,7 @@ api.kittens.get() ``` ```shell -curl "http://example.com/api/kittens" +curl "https://example.com/api/kittens" -H "Authorization: meowmeowmeow" ``` @@ -120,7 +120,7 @@ This endpoint retrieves all kittens. ### HTTP Request -`GET http://example.com/api/kittens` +`GET https://example.com/api/kittens` ### Query Parameters @@ -150,7 +150,7 @@ api.kittens.get(2) ``` ```shell -curl "http://example.com/api/kittens/2" +curl "https://example.com/api/kittens/2" -H "Authorization: meowmeowmeow" ``` @@ -179,7 +179,7 @@ This endpoint retrieves a specific kitten. ### HTTP Request -`GET http://example.com/kittens/` +`GET https://example.com/kittens/` ### URL Parameters diff --git a/samples/rest-notes-slate/slate/source/javascripts/lib/_jquery.js b/samples/rest-notes-slate/slate/source/javascripts/lib/_jquery.js index b78120e6a..d08ed3193 100644 --- a/samples/rest-notes-slate/slate/source/javascripts/lib/_jquery.js +++ b/samples/rest-notes-slate/slate/source/javascripts/lib/_jquery.js @@ -1,13 +1,13 @@ /*! * jQuery JavaScript Library v2.2.0 - * http://jquery.com/ + * https://jquery.com/ * * Includes Sizzle.js - * http://sizzlejs.com/ + * https://sizzlejs.com/ * * Copyright jQuery Foundation and other contributors * Released under the MIT license - * http://jquery.org/license + * https://jquery.org/license * * Date: 2016-01-08T20:02Z */ @@ -540,11 +540,11 @@ function isArrayLike( obj ) { var Sizzle = /*! * Sizzle CSS Selector Engine v2.2.1 - * http://sizzlejs.com/ + * https://sizzlejs.com/ * * Copyright jQuery Foundation and other contributors * Released under the MIT license - * http://jquery.org/license + * https://jquery.org/license * * Date: 2015-10-17 */ @@ -598,7 +598,7 @@ var i, push = arr.push, slice = arr.slice, // Use a stripped-down indexOf as it's faster than native - // http://jsperf.com/thor-indexof-vs-for/5 + // https://jsperf.com/thor-indexof-vs-for/5 indexOf = function( list, elem ) { var i = 0, len = list.length; @@ -614,13 +614,13 @@ var i, // Regular expressions - // http://www.w3.org/TR/css3-selectors/#whitespace + // https://www.w3.org/TR/css3-selectors/#whitespace whitespace = "[\\x20\\t\\r\\n\\f]", - // http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier + // https://www.w3.org/TR/CSS21/syndata.html#value-def-identifier identifier = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+", - // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors + // Attribute selectors: https://www.w3.org/TR/selectors/#attribute-selectors attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace + // Operator (capture 2) "*([*^$|!~]?=)" + whitespace + @@ -677,7 +677,7 @@ var i, rsibling = /[+~]/, rescape = /'|\\/g, - // CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters + // CSS escapes https://www.w3.org/TR/CSS21/syndata.html#escaped-characters runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ), funescape = function( _, escaped, escapedWhitespace ) { var high = "0x" + escaped - 0x10000; @@ -1169,7 +1169,7 @@ setDocument = Sizzle.setDocument = function( node ) { // We allow this because of a bug in IE8/9 that throws an error // whenever `document.activeElement` is accessed on an iframe // So, we allow :focus to pass through QSA all the time to avoid the IE error - // See http://bugs.jquery.com/ticket/13378 + // See https://bugs.jquery.com/ticket/13378 rbuggyQSA = []; if ( (support.qsa = rnative.test( document.querySelectorAll )) ) { @@ -1180,7 +1180,7 @@ setDocument = Sizzle.setDocument = function( node ) { // This is to test IE's treatment of not explicitly // setting a boolean content attribute, // since its presence should be enough - // http://bugs.jquery.com/ticket/12359 + // https://bugs.jquery.com/ticket/12359 docElem.appendChild( div ).innerHTML = "" + ""; @@ -1188,7 +1188,7 @@ setDocument = Sizzle.setDocument = function( node ) { // Support: IE8, Opera 11-12.16 // Nothing should be selected when empty strings follow ^= or $= or *= // The test attribute must be unknown in Opera but "safe" for WinRT - // http://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section + // https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section if ( div.querySelectorAll("[msallowcapture^='']").length ) { rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" ); } @@ -1205,7 +1205,7 @@ setDocument = Sizzle.setDocument = function( node ) { } // Webkit/Opera - :checked should return selected option elements - // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + // https://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked // IE8 throws error here and will not see later tests if ( !div.querySelectorAll(":checked").length ) { rbuggyQSA.push(":checked"); @@ -1802,7 +1802,7 @@ Expr = Sizzle.selectors = { "PSEUDO": function( pseudo, argument ) { // pseudo-class names are case-insensitive - // http://www.w3.org/TR/selectors/#pseudo-classes + // https://www.w3.org/TR/selectors/#pseudo-classes // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters // Remember that setFilters inherits from pseudos var args, @@ -1889,7 +1889,7 @@ Expr = Sizzle.selectors = { // or beginning with the identifier C immediately followed by "-". // The matching of C against the element's language value is performed case-insensitively. // The identifier C does not have to be a valid language name." - // http://www.w3.org/TR/selectors/#lang-pseudo + // https://www.w3.org/TR/selectors/#lang-pseudo "lang": markFunction( function( lang ) { // lang value must be a valid identifier if ( !ridentifier.test(lang || "") ) { @@ -1936,7 +1936,7 @@ Expr = Sizzle.selectors = { "checked": function( elem ) { // In CSS3, :checked should return both checked and selected elements - // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + // https://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked var nodeName = elem.nodeName.toLowerCase(); return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected); }, @@ -1953,7 +1953,7 @@ Expr = Sizzle.selectors = { // Contents "empty": function( elem ) { - // http://www.w3.org/TR/selectors/#empty-pseudo + // https://www.w3.org/TR/selectors/#empty-pseudo // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5), // but not by others (comment: 8; processing instruction: 7; etc.) // nodeType < 6 works because attributes (2) do not appear as children @@ -2627,7 +2627,7 @@ support.sortDetached = assert(function( div1 ) { // Support: IE<8 // Prevent attribute/property "interpolation" -// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx +// https://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx if ( !assert(function( div ) { div.innerHTML = ""; return div.firstChild.getAttribute("href") === "#" ; @@ -4995,7 +4995,7 @@ jQuery.Event = function( src, props ) { }; // jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding -// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html +// https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html jQuery.Event.prototype = { constructor: jQuery.Event, isDefaultPrevented: returnFalse, @@ -5328,7 +5328,7 @@ jQuery.extend( { if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) && !jQuery.isXMLDoc( elem ) ) { - // We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2 + // We eschew Sizzle here for performance reasons: https://jsperf.com/getall-vs-sizzle/2 destElements = getAll( clone ); srcElements = getAll( elem ); @@ -5805,7 +5805,7 @@ function curCSS( elem, name, computed ) { // Android Browser returns percentage for some values, // but width seems to be reliably pixels. // This is against the CSSOM draft spec: - // http://dev.w3.org/csswg/cssom/#resolved-values + // https://dev.w3.org/csswg/cssom/#resolved-values if ( !support.pixelMarginRight() && rnumnonpx.test( ret ) && rmargin.test( name ) ) { // Remember the original values @@ -7069,7 +7069,7 @@ jQuery.fx.speeds = { // Based off of the plugin by Clint Helfers, with permission. -// http://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/ +// https://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/ jQuery.fn.delay = function( time, type ) { time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time; type = type || "fx"; @@ -7302,7 +7302,7 @@ jQuery.extend( { // elem.tabIndex doesn't always return the // correct value when it hasn't been explicitly set - // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ + // https://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ // Use proper attribute retrieval(#12072) var tabindex = jQuery.find.attr( elem, "tabindex" ); @@ -7912,7 +7912,7 @@ support.focusin = "onfocusin" in window; // // Support: Chrome, Safari // focus(in | out) events fire after focus & blur events, -// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order +// which is spec violation - https://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order // Related ticket - https://code.google.com/p/chromium/issues/detail?id=449857 if ( !support.focusin ) { jQuery.each( { focus: "focusin", blur: "focusout" }, function( orig, fix ) { diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/preprocess/PrettyPrintingContentModifier.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/preprocess/PrettyPrintingContentModifier.java index c38c5ff50..879aa40d3 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/preprocess/PrettyPrintingContentModifier.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/preprocess/PrettyPrintingContentModifier.java @@ -82,7 +82,7 @@ private static final class XmlPrettyPrinter implements PrettyPrinter { public byte[] prettyPrint(byte[] original) throws Exception { Transformer transformer = TransformerFactory.newInstance().newTransformer(); transformer.setOutputProperty(OutputKeys.INDENT, "yes"); - transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", + transformer.setOutputProperty("{https://xml.apache.org/xslt}indent-amount", "4"); transformer.setOutputProperty(OutputKeys.DOCTYPE_PUBLIC, "yes"); ByteArrayOutputStream transformed = new ByteArrayOutputStream(); diff --git a/spring-restdocs-restassured/src/test/java/org/springframework/restdocs/restassured3/operation/preprocess/UriModifyingOperationPreprocessorTests.java b/spring-restdocs-restassured/src/test/java/org/springframework/restdocs/restassured3/operation/preprocess/UriModifyingOperationPreprocessorTests.java index bdd998ecf..349d5bc2e 100644 --- a/spring-restdocs-restassured/src/test/java/org/springframework/restdocs/restassured3/operation/preprocess/UriModifyingOperationPreprocessorTests.java +++ b/spring-restdocs-restassured/src/test/java/org/springframework/restdocs/restassured3/operation/preprocess/UriModifyingOperationPreprocessorTests.java @@ -62,9 +62,9 @@ public void requestUriSchemeCanBeModified() { public void requestUriHostCanBeModified() { this.preprocessor.host("api.example.com"); OperationRequest processed = this.preprocessor - .preprocess(createRequestWithUri("http://api.foo.com:12345")); + .preprocess(createRequestWithUri("https://api.foo.com:12345")); assertThat(processed.getUri()) - .isEqualTo(URI.create("http://api.example.com:12345")); + .isEqualTo(URI.create("https://api.example.com:12345")); assertThat(processed.getHeaders().getFirst(HttpHeaders.HOST)) .isEqualTo("api.example.com:12345"); } @@ -73,9 +73,9 @@ public void requestUriHostCanBeModified() { public void requestUriPortCanBeModified() { this.preprocessor.port(23456); OperationRequest processed = this.preprocessor - .preprocess(createRequestWithUri("http://api.example.com:12345")); + .preprocess(createRequestWithUri("https://api.example.com:12345")); assertThat(processed.getUri()) - .isEqualTo(URI.create("http://api.example.com:23456")); + .isEqualTo(URI.create("https://api.example.com:23456")); assertThat(processed.getHeaders().getFirst(HttpHeaders.HOST)) .isEqualTo("api.example.com:23456"); } @@ -84,8 +84,8 @@ public void requestUriPortCanBeModified() { public void requestUriPortCanBeRemoved() { this.preprocessor.removePort(); OperationRequest processed = this.preprocessor - .preprocess(createRequestWithUri("http://api.example.com:12345")); - assertThat(processed.getUri()).isEqualTo(URI.create("http://api.example.com")); + .preprocess(createRequestWithUri("https://api.example.com:12345")); + assertThat(processed.getUri()).isEqualTo(URI.create("https://api.example.com")); assertThat(processed.getHeaders().getFirst(HttpHeaders.HOST)) .isEqualTo("api.example.com"); } @@ -94,27 +94,27 @@ public void requestUriPortCanBeRemoved() { public void requestUriPathIsPreserved() { this.preprocessor.removePort(); OperationRequest processed = this.preprocessor - .preprocess(createRequestWithUri("http://api.example.com:12345/foo/bar")); + .preprocess(createRequestWithUri("https://api.example.com:12345/foo/bar")); assertThat(processed.getUri()) - .isEqualTo(URI.create("http://api.example.com/foo/bar")); + .isEqualTo(URI.create("https://api.example.com/foo/bar")); } @Test public void requestUriQueryIsPreserved() { this.preprocessor.removePort(); OperationRequest processed = this.preprocessor - .preprocess(createRequestWithUri("http://api.example.com:12345?foo=bar")); + .preprocess(createRequestWithUri("https://api.example.com:12345?foo=bar")); assertThat(processed.getUri()) - .isEqualTo(URI.create("http://api.example.com?foo=bar")); + .isEqualTo(URI.create("https://api.example.com?foo=bar")); } @Test public void requestUriAnchorIsPreserved() { this.preprocessor.removePort(); OperationRequest processed = this.preprocessor - .preprocess(createRequestWithUri("http://api.example.com:12345#foo")); + .preprocess(createRequestWithUri("https://api.example.com:12345#foo")); assertThat(processed.getUri()) - .isEqualTo(URI.create("http://api.example.com#foo")); + .isEqualTo(URI.create("https://api.example.com#foo")); } @Test @@ -134,7 +134,7 @@ public void requestContentUriHostCanBeModified() { .preprocess(createRequestWithContent( "The uri 'http://localhost:12345' should be used")); assertThat(new String(processed.getContent())) - .isEqualTo("The uri 'http://api.example.com:12345' should be used"); + .isEqualTo("The uri 'https://api.example.com:12345' should be used"); } @Test @@ -214,7 +214,7 @@ public void responseContentUriHostCanBeModified() { .preprocess(createResponseWithContent( "The uri 'http://localhost:12345' should be used")); assertThat(new String(processed.getContent())) - .isEqualTo("The uri 'http://api.example.com:12345' should be used"); + .isEqualTo("The uri 'https://api.example.com:12345' should be used"); } @Test @@ -282,7 +282,7 @@ public void urisInRequestHeadersCanBeModified() { OperationRequest processed = this.preprocessor.host("api.example.com") .preprocess(createRequestWithHeader("Foo", "http://locahost:12345")); assertThat(processed.getHeaders().getFirst("Foo")) - .isEqualTo("http://api.example.com:12345"); + .isEqualTo("https://api.example.com:12345"); assertThat(processed.getHeaders().getFirst("Host")).isEqualTo("api.example.com"); } @@ -291,7 +291,7 @@ public void urisInResponseHeadersCanBeModified() { OperationResponse processed = this.preprocessor.host("api.example.com") .preprocess(createResponseWithHeader("Foo", "http://locahost:12345")); assertThat(processed.getHeaders().getFirst("Foo")) - .isEqualTo("http://api.example.com:12345"); + .isEqualTo("https://api.example.com:12345"); } @Test @@ -299,7 +299,7 @@ public void urisInRequestPartHeadersCanBeModified() { OperationRequest processed = this.preprocessor.host("api.example.com").preprocess( createRequestWithPartWithHeader("Foo", "http://locahost:12345")); assertThat(processed.getParts().iterator().next().getHeaders().getFirst("Foo")) - .isEqualTo("http://api.example.com:12345"); + .isEqualTo("https://api.example.com:12345"); } @Test @@ -308,7 +308,7 @@ public void urisInRequestPartContentCanBeModified() { .preprocess(createRequestWithPartWithContent( "The uri 'http://localhost:12345' should be used")); assertThat(new String(processed.getParts().iterator().next().getContent())) - .isEqualTo("The uri 'http://api.example.com:12345' should be used"); + .isEqualTo("The uri 'https://api.example.com:12345' should be used"); } @Test From 2dda908c7ef307c40737ece4ebeffb09ad4a31b6 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Tue, 26 Mar 2019 12:00:27 +0000 Subject: [PATCH 036/502] Polish "Use HTTPS for externals links where possible" See gh-611 --- .../PrettyPrintingContentModifier.java | 2 +- .../LinkExtractorsPayloadTests.java | 3 ++- ...riModifyingOperationPreprocessorTests.java | 8 +++---- ...riModifyingOperationPreprocessorTests.java | 22 +++++++++---------- 4 files changed, 18 insertions(+), 17 deletions(-) diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/preprocess/PrettyPrintingContentModifier.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/preprocess/PrettyPrintingContentModifier.java index 879aa40d3..c38c5ff50 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/preprocess/PrettyPrintingContentModifier.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/preprocess/PrettyPrintingContentModifier.java @@ -82,7 +82,7 @@ private static final class XmlPrettyPrinter implements PrettyPrinter { public byte[] prettyPrint(byte[] original) throws Exception { Transformer transformer = TransformerFactory.newInstance().newTransformer(); transformer.setOutputProperty(OutputKeys.INDENT, "yes"); - transformer.setOutputProperty("{https://xml.apache.org/xslt}indent-amount", + transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4"); transformer.setOutputProperty(OutputKeys.DOCTYPE_PUBLIC, "yes"); ByteArrayOutputStream transformed = new ByteArrayOutputStream(); diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/hypermedia/LinkExtractorsPayloadTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/hypermedia/LinkExtractorsPayloadTests.java index d868297a4..ea0d4a02e 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/hypermedia/LinkExtractorsPayloadTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/hypermedia/LinkExtractorsPayloadTests.java @@ -68,7 +68,8 @@ public LinkExtractorsPayloadTests(LinkExtractor linkExtractor, String linkType) public void singleLink() throws IOException { Map> links = this.linkExtractor .extractLinks(createResponse("single-link")); - assertLinks(Arrays.asList(new Link("alpha", "https://alpha.example.com", "Alpha")), + assertLinks( + Arrays.asList(new Link("alpha", "https://alpha.example.com", "Alpha")), links); } diff --git a/spring-restdocs-restassured/src/test/java/org/springframework/restdocs/restassured/operation/preprocess/UriModifyingOperationPreprocessorTests.java b/spring-restdocs-restassured/src/test/java/org/springframework/restdocs/restassured/operation/preprocess/UriModifyingOperationPreprocessorTests.java index 9a7ab00e2..ce2b99e1f 100644 --- a/spring-restdocs-restassured/src/test/java/org/springframework/restdocs/restassured/operation/preprocess/UriModifyingOperationPreprocessorTests.java +++ b/spring-restdocs-restassured/src/test/java/org/springframework/restdocs/restassured/operation/preprocess/UriModifyingOperationPreprocessorTests.java @@ -94,8 +94,8 @@ public void requestUriPortCanBeRemoved() { @Test public void requestUriPathIsPreserved() { this.preprocessor.removePort(); - OperationRequest processed = this.preprocessor - .preprocess(createRequestWithUri("https://api.example.com:12345/foo/bar")); + OperationRequest processed = this.preprocessor.preprocess( + createRequestWithUri("https://api.example.com:12345/foo/bar")); assertThat(processed.getUri()) .isEqualTo(URI.create("https://api.example.com/foo/bar")); } @@ -103,8 +103,8 @@ public void requestUriPathIsPreserved() { @Test public void requestUriQueryIsPreserved() { this.preprocessor.removePort(); - OperationRequest processed = this.preprocessor - .preprocess(createRequestWithUri("https://api.example.com:12345?foo=bar")); + OperationRequest processed = this.preprocessor.preprocess( + createRequestWithUri("https://api.example.com:12345?foo=bar")); assertThat(processed.getUri()) .isEqualTo(URI.create("https://api.example.com?foo=bar")); } diff --git a/spring-restdocs-restassured/src/test/java/org/springframework/restdocs/restassured3/operation/preprocess/UriModifyingOperationPreprocessorTests.java b/spring-restdocs-restassured/src/test/java/org/springframework/restdocs/restassured3/operation/preprocess/UriModifyingOperationPreprocessorTests.java index 349d5bc2e..efcefd5a3 100644 --- a/spring-restdocs-restassured/src/test/java/org/springframework/restdocs/restassured3/operation/preprocess/UriModifyingOperationPreprocessorTests.java +++ b/spring-restdocs-restassured/src/test/java/org/springframework/restdocs/restassured3/operation/preprocess/UriModifyingOperationPreprocessorTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2016 the original author or authors. + * Copyright 2014-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. @@ -93,8 +93,8 @@ public void requestUriPortCanBeRemoved() { @Test public void requestUriPathIsPreserved() { this.preprocessor.removePort(); - OperationRequest processed = this.preprocessor - .preprocess(createRequestWithUri("https://api.example.com:12345/foo/bar")); + OperationRequest processed = this.preprocessor.preprocess( + createRequestWithUri("https://api.example.com:12345/foo/bar")); assertThat(processed.getUri()) .isEqualTo(URI.create("https://api.example.com/foo/bar")); } @@ -102,8 +102,8 @@ public void requestUriPathIsPreserved() { @Test public void requestUriQueryIsPreserved() { this.preprocessor.removePort(); - OperationRequest processed = this.preprocessor - .preprocess(createRequestWithUri("https://api.example.com:12345?foo=bar")); + OperationRequest processed = this.preprocessor.preprocess( + createRequestWithUri("https://api.example.com:12345?foo=bar")); assertThat(processed.getUri()) .isEqualTo(URI.create("https://api.example.com?foo=bar")); } @@ -132,7 +132,7 @@ public void requestContentUriHostCanBeModified() { this.preprocessor.host("api.example.com"); OperationRequest processed = this.preprocessor .preprocess(createRequestWithContent( - "The uri 'http://localhost:12345' should be used")); + "The uri 'https://localhost:12345' should be used")); assertThat(new String(processed.getContent())) .isEqualTo("The uri 'https://api.example.com:12345' should be used"); } @@ -212,7 +212,7 @@ public void responseContentUriHostCanBeModified() { this.preprocessor.host("api.example.com"); OperationResponse processed = this.preprocessor .preprocess(createResponseWithContent( - "The uri 'http://localhost:12345' should be used")); + "The uri 'https://localhost:12345' should be used")); assertThat(new String(processed.getContent())) .isEqualTo("The uri 'https://api.example.com:12345' should be used"); } @@ -280,7 +280,7 @@ public void responseContentUriAnchorIsPreserved() { @Test public void urisInRequestHeadersCanBeModified() { OperationRequest processed = this.preprocessor.host("api.example.com") - .preprocess(createRequestWithHeader("Foo", "http://locahost:12345")); + .preprocess(createRequestWithHeader("Foo", "https://locahost:12345")); assertThat(processed.getHeaders().getFirst("Foo")) .isEqualTo("https://api.example.com:12345"); assertThat(processed.getHeaders().getFirst("Host")).isEqualTo("api.example.com"); @@ -289,7 +289,7 @@ public void urisInRequestHeadersCanBeModified() { @Test public void urisInResponseHeadersCanBeModified() { OperationResponse processed = this.preprocessor.host("api.example.com") - .preprocess(createResponseWithHeader("Foo", "http://locahost:12345")); + .preprocess(createResponseWithHeader("Foo", "https://locahost:12345")); assertThat(processed.getHeaders().getFirst("Foo")) .isEqualTo("https://api.example.com:12345"); } @@ -297,7 +297,7 @@ public void urisInResponseHeadersCanBeModified() { @Test public void urisInRequestPartHeadersCanBeModified() { OperationRequest processed = this.preprocessor.host("api.example.com").preprocess( - createRequestWithPartWithHeader("Foo", "http://locahost:12345")); + createRequestWithPartWithHeader("Foo", "https://locahost:12345")); assertThat(processed.getParts().iterator().next().getHeaders().getFirst("Foo")) .isEqualTo("https://api.example.com:12345"); } @@ -306,7 +306,7 @@ public void urisInRequestPartHeadersCanBeModified() { public void urisInRequestPartContentCanBeModified() { OperationRequest processed = this.preprocessor.host("api.example.com") .preprocess(createRequestWithPartWithContent( - "The uri 'http://localhost:12345' should be used")); + "The uri 'https://localhost:12345' should be used")); assertThat(new String(processed.getParts().iterator().next().getContent())) .isEqualTo("The uri 'https://api.example.com:12345' should be used"); } From 1d0ffa7ac46afc1ddf6e81988e2a88b9a937dab2 Mon Sep 17 00:00:00 2001 From: Spring Operator Date: Wed, 20 Mar 2019 22:17:03 -0500 Subject: [PATCH 037/502] Use HTTPS for external links where possible See gh-602 --- docs/src/docs/asciidoc/getting-started.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/docs/asciidoc/getting-started.adoc b/docs/src/docs/asciidoc/getting-started.adoc index 798f89591..e58b42dc7 100644 --- a/docs/src/docs/asciidoc/getting-started.adoc +++ b/docs/src/docs/asciidoc/getting-started.adoc @@ -72,7 +72,7 @@ If you want to jump straight in, a number of sample applications are available: | {samples}/junit5[JUnit 5] | Gradle -| Demonstrates the use of Spring REST Docs with http://junit.org/junit5/[JUnit 5]. +| Demonstrates the use of Spring REST Docs with https://junit.org/junit5/[JUnit 5]. |=== From 2f5bc50b841c1d7ff5d38c5ecbe7f1d52ff73835 Mon Sep 17 00:00:00 2001 From: kevinjom Date: Wed, 10 Apr 2019 18:16:50 +0800 Subject: [PATCH 038/502] Fix minor mistake made from last merge for `README.md` See commit 6069d2864f881a5a03d18ef2637156bdc2c4c92c See gh-614 --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 2a3828979..8ed4f451b 100644 --- a/README.md +++ b/README.md @@ -37,7 +37,6 @@ There are several that you can contribute to Spring REST Docs: | Name | Description | | ---- | ----------- | -<<<<<<< HEAD | [restdocs-wiremock][17] | Auto-generate WireMock stubs as part of documenting your RESTful API | | [restdocsext-jersey][18] | Enables Spring REST Docs to be used with [Jersey's test framework][19] | | [spring-auto-restdocs][20] | Uses introspection and Javadoc to automatically document request and response parameters | From f1eaf0c91aeca5b8a29682c090b93cda626a04c7 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Mon, 10 Jun 2019 10:38:22 +0100 Subject: [PATCH 039/502] Add NoHTTP to the build --- build.gradle | 10 + config/eclipse/org.eclipse.jdt.core.prefs | 411 ------------------ config/eclipse/org.eclipse.jdt.ui.prefs | 125 ------ config/nohttp/whitelist.lines | 1 + .../.settings/org.eclipse.jdt.core.prefs | 296 ------------- .../.settings/org.eclipse.jdt.ui.prefs | 62 --- .../.settings/org.eclipse.jdt.core.prefs | 295 ------------- .../.settings/org.eclipse.jdt.ui.prefs | 62 --- 8 files changed, 11 insertions(+), 1251 deletions(-) delete mode 100644 config/eclipse/org.eclipse.jdt.core.prefs delete mode 100644 config/eclipse/org.eclipse.jdt.ui.prefs create mode 100644 config/nohttp/whitelist.lines delete mode 100644 samples/rest-notes-spring-data-rest/.settings/org.eclipse.jdt.core.prefs delete mode 100644 samples/rest-notes-spring-data-rest/.settings/org.eclipse.jdt.ui.prefs delete mode 100644 samples/rest-notes-spring-hateoas/.settings/org.eclipse.jdt.core.prefs delete mode 100644 samples/rest-notes-spring-hateoas/.settings/org.eclipse.jdt.ui.prefs diff --git a/build.gradle b/build.gradle index 03e258c7d..b1f0f0d24 100644 --- a/build.gradle +++ b/build.gradle @@ -10,6 +10,7 @@ buildscript { classpath 'io.spring.gradle:spring-io-plugin:0.0.8.RELEASE' classpath 'org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:2.6.2' classpath "io.spring.javaformat:spring-javaformat-gradle-plugin:$javaFormatVersion" + classpath 'io.spring.nohttp:nohttp-gradle:0.0.2.RELEASE' } } @@ -23,6 +24,7 @@ allprojects { apply plugin: 'samples' apply plugin: 'org.sonarqube' +apply plugin: 'io.spring.nohttp' sonarqube { properties { @@ -35,6 +37,14 @@ sonarqube { } } +nohttp { + source.exclude 'samples/rest-notes-slate/slate/source/javascripts/lib/_jquery*.js' + source.exclude 'buildSrc/.gradle/**' + source.exclude '**/build/**' + source.exclude '**/target/**' + whitelistFile = project.file('config/nohttp/whitelist.lines') +} + ext { springVersion = '4.3.15.RELEASE' javadocLinks = [ diff --git a/config/eclipse/org.eclipse.jdt.core.prefs b/config/eclipse/org.eclipse.jdt.core.prefs deleted file mode 100644 index 9f047259a..000000000 --- a/config/eclipse/org.eclipse.jdt.core.prefs +++ /dev/null @@ -1,411 +0,0 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.codeComplete.argumentPrefixes= -org.eclipse.jdt.core.codeComplete.argumentSuffixes= -org.eclipse.jdt.core.codeComplete.fieldPrefixes= -org.eclipse.jdt.core.codeComplete.fieldSuffixes= -org.eclipse.jdt.core.codeComplete.localPrefixes= -org.eclipse.jdt.core.codeComplete.localSuffixes= -org.eclipse.jdt.core.codeComplete.staticFieldPrefixes= -org.eclipse.jdt.core.codeComplete.staticFieldSuffixes= -org.eclipse.jdt.core.codeComplete.staticFinalFieldPrefixes= -org.eclipse.jdt.core.codeComplete.staticFinalFieldSuffixes= -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7 -org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve -org.eclipse.jdt.core.compiler.compliance=1.7 -org.eclipse.jdt.core.compiler.debug.lineNumber=generate -org.eclipse.jdt.core.compiler.debug.localVariable=generate -org.eclipse.jdt.core.compiler.debug.sourceFile=generate -org.eclipse.jdt.core.compiler.doc.comment.support=enabled -org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.autoboxing=ignore -org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning -org.eclipse.jdt.core.compiler.problem.deadCode=warning -org.eclipse.jdt.core.compiler.problem.deprecation=warning -org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled -org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled -org.eclipse.jdt.core.compiler.problem.discouragedReference=warning -org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore -org.eclipse.jdt.core.compiler.problem.fatalOptionalError=disabled -org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore -org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning -org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning -org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning -org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning -org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=disabled -org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning -org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore -org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore -org.eclipse.jdt.core.compiler.problem.invalidJavadoc=warning -org.eclipse.jdt.core.compiler.problem.invalidJavadocTags=enabled -org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsDeprecatedRef=disabled -org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsNotVisibleRef=enabled -org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsVisibility=default -org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore -org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning -org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore -org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore -org.eclipse.jdt.core.compiler.problem.missingJavadocComments=ignore -org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsOverriding=disabled -org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsVisibility=public -org.eclipse.jdt.core.compiler.problem.missingJavadocTagDescription=all_standard_tags -org.eclipse.jdt.core.compiler.problem.missingJavadocTags=warning -org.eclipse.jdt.core.compiler.problem.missingJavadocTagsMethodTypeParameters=disabled -org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=disabled -org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility=default -org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore -org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled -org.eclipse.jdt.core.compiler.problem.missingSerialVersion=ignore -org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore -org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning -org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning -org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore -org.eclipse.jdt.core.compiler.problem.nullReference=ignore -org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning -org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore -org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore -org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore -org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning -org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore -org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=warning -org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore -org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore -org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore -org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled -org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning -org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled -org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled -org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore -org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning -org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=enabled -org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning -org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore -org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning -org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore -org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning -org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled -org.eclipse.jdt.core.compiler.problem.unusedImport=warning -org.eclipse.jdt.core.compiler.problem.unusedLabel=warning -org.eclipse.jdt.core.compiler.problem.unusedLocal=warning -org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=ignore -org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore -org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled -org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled -org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled -org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning -org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning -org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning -org.eclipse.jdt.core.compiler.processAnnotations=disabled -org.eclipse.jdt.core.compiler.source=1.7 -org.eclipse.jdt.core.formatter.align_fields_grouping_blank_lines=2147483647 -org.eclipse.jdt.core.formatter.align_type_members_on_columns=false -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16 -org.eclipse.jdt.core.formatter.alignment_for_assignment=0 -org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16 -org.eclipse.jdt.core.formatter.alignment_for_compact_if=16 -org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=16 -org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0 -org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16 -org.eclipse.jdt.core.formatter.alignment_for_expressions_in_for_loop_header=0 -org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0 -org.eclipse.jdt.core.formatter.alignment_for_module_statements=16 -org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16 -org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0 -org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=80 -org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16 -org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_type_arguments=0 -org.eclipse.jdt.core.formatter.alignment_for_type_parameters=0 -org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch=16 -org.eclipse.jdt.core.formatter.blank_lines_after_imports=1 -org.eclipse.jdt.core.formatter.blank_lines_after_package=1 -org.eclipse.jdt.core.formatter.blank_lines_before_field=0 -org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0 -org.eclipse.jdt.core.formatter.blank_lines_before_imports=1 -org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1 -org.eclipse.jdt.core.formatter.blank_lines_before_method=1 -org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1 -org.eclipse.jdt.core.formatter.blank_lines_before_package=0 -org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1 -org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1 -org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_lambda_body=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line -org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false -org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false -org.eclipse.jdt.core.formatter.comment.count_line_length_from_starting_position=false -org.eclipse.jdt.core.formatter.comment.format_block_comments=true -org.eclipse.jdt.core.formatter.comment.format_header=false -org.eclipse.jdt.core.formatter.comment.format_html=true -org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true -org.eclipse.jdt.core.formatter.comment.format_line_comments=true -org.eclipse.jdt.core.formatter.comment.format_source_code=false -org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true -org.eclipse.jdt.core.formatter.comment.indent_root_tags=false -org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=do not insert -org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=do not insert -org.eclipse.jdt.core.formatter.comment.line_length=90 -org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true -org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true -org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=false -org.eclipse.jdt.core.formatter.compact_else_if=true -org.eclipse.jdt.core.formatter.continuation_indentation=2 -org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2 -org.eclipse.jdt.core.formatter.disabling_tag=@formatter\:off -org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on -org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false -org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true -org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true -org.eclipse.jdt.core.formatter.indent_empty_lines=false -org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true -org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true -org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true -org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false -org.eclipse.jdt.core.formatter.indentation.size=4 -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_enum_constant=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_after_type_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=insert -org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=insert -org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=insert -org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert -org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert -org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert -org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow=insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources=insert -org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert -org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert -org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert -org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert -org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert -org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.join_lines_in_comments=true -org.eclipse.jdt.core.formatter.join_wrapped_lines=true -org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false -org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false -org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false -org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false -org.eclipse.jdt.core.formatter.lineSplit=90 -org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false -org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false -org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0 -org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1 -org.eclipse.jdt.core.formatter.parentheses_positions_in_annotation=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_catch_clause=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_enum_constant_declaration=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_for_statment=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_if_while_statement=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_lambda_declaration=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_method_delcaration=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_method_invocation=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_switch_statement=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_try_clause=common_lines -org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true -org.eclipse.jdt.core.formatter.tabulation.char=tab -org.eclipse.jdt.core.formatter.tabulation.size=4 -org.eclipse.jdt.core.formatter.use_on_off_tags=true -org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false -org.eclipse.jdt.core.formatter.wrap_before_assignment_operator=false -org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true -org.eclipse.jdt.core.formatter.wrap_before_conditional_operator=true -org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true -org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true -org.eclipse.jdt.core.javaFormatter=org.eclipse.jdt.core.defaultJavaFormatter diff --git a/config/eclipse/org.eclipse.jdt.ui.prefs b/config/eclipse/org.eclipse.jdt.ui.prefs deleted file mode 100644 index f794f2aba..000000000 --- a/config/eclipse/org.eclipse.jdt.ui.prefs +++ /dev/null @@ -1,125 +0,0 @@ -cleanup.add_default_serial_version_id=true -cleanup.add_generated_serial_version_id=false -cleanup.add_missing_annotations=true -cleanup.add_missing_deprecated_annotations=true -cleanup.add_missing_methods=false -cleanup.add_missing_nls_tags=false -cleanup.add_missing_override_annotations=true -cleanup.add_missing_override_annotations_interface_methods=true -cleanup.add_serial_version_id=false -cleanup.always_use_blocks=true -cleanup.always_use_parentheses_in_expressions=false -cleanup.always_use_this_for_non_static_field_access=true -cleanup.always_use_this_for_non_static_method_access=false -cleanup.convert_functional_interfaces=false -cleanup.convert_to_enhanced_for_loop=false -cleanup.correct_indentation=false -cleanup.format_source_code=true -cleanup.format_source_code_changes_only=false -cleanup.insert_inferred_type_arguments=false -cleanup.make_local_variable_final=false -cleanup.make_parameters_final=false -cleanup.make_private_fields_final=false -cleanup.make_type_abstract_if_missing_method=false -cleanup.make_variable_declarations_final=false -cleanup.never_use_blocks=false -cleanup.never_use_parentheses_in_expressions=true -cleanup.organize_imports=true -cleanup.qualify_static_field_accesses_with_declaring_class=false -cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true -cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true -cleanup.qualify_static_member_accesses_with_declaring_class=true -cleanup.qualify_static_method_accesses_with_declaring_class=false -cleanup.remove_private_constructors=true -cleanup.remove_redundant_type_arguments=true -cleanup.remove_trailing_whitespaces=true -cleanup.remove_trailing_whitespaces_all=true -cleanup.remove_trailing_whitespaces_ignore_empty=false -cleanup.remove_unnecessary_casts=true -cleanup.remove_unnecessary_nls_tags=false -cleanup.remove_unused_imports=true -cleanup.remove_unused_local_variables=false -cleanup.remove_unused_private_fields=true -cleanup.remove_unused_private_members=false -cleanup.remove_unused_private_methods=true -cleanup.remove_unused_private_types=true -cleanup.sort_members=false -cleanup.sort_members_all=false -cleanup.use_anonymous_class_creation=false -cleanup.use_blocks=true -cleanup.use_blocks_only_for_return_and_throw=false -cleanup.use_lambda=true -cleanup.use_parentheses_in_expressions=false -cleanup.use_this_for_non_static_field_access=false -cleanup.use_this_for_non_static_field_access_only_if_necessary=false -cleanup.use_this_for_non_static_method_access=false -cleanup.use_this_for_non_static_method_access_only_if_necessary=true -cleanup.use_type_arguments=false -cleanup_profile=_Spring REST Docs Cleanup Conventions -cleanup_settings_version=2 -eclipse.preferences.version=1 -editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true -formatter_profile=_Spring REST Docs Java Conventions -formatter_settings_version=13 -org.eclipse.jdt.ui.exception.name=e -org.eclipse.jdt.ui.gettersetter.use.is=true -org.eclipse.jdt.ui.ignorelowercasenames=true -org.eclipse.jdt.ui.importorder=java;javax;;org.springframework;\#; -org.eclipse.jdt.ui.javadoc=true -org.eclipse.jdt.ui.keywordthis=false -org.eclipse.jdt.ui.ondemandthreshold=9999 -org.eclipse.jdt.ui.overrideannotation=true -org.eclipse.jdt.ui.staticondemandthreshold=9999 -org.eclipse.jdt.ui.text.custom_code_templates= -sp_cleanup.add_default_serial_version_id=true -sp_cleanup.add_generated_serial_version_id=false -sp_cleanup.add_missing_annotations=true -sp_cleanup.add_missing_deprecated_annotations=true -sp_cleanup.add_missing_methods=false -sp_cleanup.add_missing_nls_tags=false -sp_cleanup.add_missing_override_annotations=true -sp_cleanup.add_missing_override_annotations_interface_methods=true -sp_cleanup.add_serial_version_id=false -sp_cleanup.always_use_blocks=true -sp_cleanup.always_use_parentheses_in_expressions=true -sp_cleanup.always_use_this_for_non_static_field_access=true -sp_cleanup.always_use_this_for_non_static_method_access=false -sp_cleanup.convert_to_enhanced_for_loop=false -sp_cleanup.correct_indentation=false -sp_cleanup.format_source_code=true -sp_cleanup.format_source_code_changes_only=false -sp_cleanup.make_local_variable_final=false -sp_cleanup.make_parameters_final=false -sp_cleanup.make_private_fields_final=false -sp_cleanup.make_type_abstract_if_missing_method=false -sp_cleanup.make_variable_declarations_final=false -sp_cleanup.never_use_blocks=false -sp_cleanup.never_use_parentheses_in_expressions=false -sp_cleanup.on_save_use_additional_actions=true -sp_cleanup.organize_imports=true -sp_cleanup.qualify_static_field_accesses_with_declaring_class=false -sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true -sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true -sp_cleanup.qualify_static_member_accesses_with_declaring_class=true -sp_cleanup.qualify_static_method_accesses_with_declaring_class=false -sp_cleanup.remove_private_constructors=true -sp_cleanup.remove_trailing_whitespaces=true -sp_cleanup.remove_trailing_whitespaces_all=true -sp_cleanup.remove_trailing_whitespaces_ignore_empty=false -sp_cleanup.remove_unnecessary_casts=true -sp_cleanup.remove_unnecessary_nls_tags=false -sp_cleanup.remove_unused_imports=true -sp_cleanup.remove_unused_local_variables=false -sp_cleanup.remove_unused_private_fields=true -sp_cleanup.remove_unused_private_members=false -sp_cleanup.remove_unused_private_methods=true -sp_cleanup.remove_unused_private_types=true -sp_cleanup.sort_members=false -sp_cleanup.sort_members_all=false -sp_cleanup.use_blocks=true -sp_cleanup.use_blocks_only_for_return_and_throw=false -sp_cleanup.use_parentheses_in_expressions=false -sp_cleanup.use_this_for_non_static_field_access=true -sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=false -sp_cleanup.use_this_for_non_static_method_access=false -sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true diff --git a/config/nohttp/whitelist.lines b/config/nohttp/whitelist.lines new file mode 100644 index 000000000..cc5c521d3 --- /dev/null +++ b/config/nohttp/whitelist.lines @@ -0,0 +1 @@ +^http://rest-assured.io.* \ No newline at end of file diff --git a/samples/rest-notes-spring-data-rest/.settings/org.eclipse.jdt.core.prefs b/samples/rest-notes-spring-data-rest/.settings/org.eclipse.jdt.core.prefs deleted file mode 100644 index 30f00a942..000000000 --- a/samples/rest-notes-spring-data-rest/.settings/org.eclipse.jdt.core.prefs +++ /dev/null @@ -1,296 +0,0 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7 -org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve -org.eclipse.jdt.core.compiler.compliance=1.7 -org.eclipse.jdt.core.compiler.debug.lineNumber=generate -org.eclipse.jdt.core.compiler.debug.localVariable=generate -org.eclipse.jdt.core.compiler.debug.sourceFile=generate -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning -org.eclipse.jdt.core.compiler.source=1.7 -org.eclipse.jdt.core.formatter.align_type_members_on_columns=false -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16 -org.eclipse.jdt.core.formatter.alignment_for_assignment=0 -org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16 -org.eclipse.jdt.core.formatter.alignment_for_compact_if=16 -org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80 -org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0 -org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16 -org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0 -org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16 -org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=80 -org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16 -org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch=16 -org.eclipse.jdt.core.formatter.blank_lines_after_imports=1 -org.eclipse.jdt.core.formatter.blank_lines_after_package=1 -org.eclipse.jdt.core.formatter.blank_lines_before_field=1 -org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=1 -org.eclipse.jdt.core.formatter.blank_lines_before_imports=1 -org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1 -org.eclipse.jdt.core.formatter.blank_lines_before_method=1 -org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1 -org.eclipse.jdt.core.formatter.blank_lines_before_package=0 -org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1 -org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1 -org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_lambda_body=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line -org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false -org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false -org.eclipse.jdt.core.formatter.comment.format_block_comments=true -org.eclipse.jdt.core.formatter.comment.format_header=false -org.eclipse.jdt.core.formatter.comment.format_html=true -org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true -org.eclipse.jdt.core.formatter.comment.format_line_comments=true -org.eclipse.jdt.core.formatter.comment.format_source_code=false -org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true -org.eclipse.jdt.core.formatter.comment.indent_root_tags=false -org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=do not insert -org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=do not insert -org.eclipse.jdt.core.formatter.comment.line_length=90 -org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true -org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true -org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=false -org.eclipse.jdt.core.formatter.compact_else_if=true -org.eclipse.jdt.core.formatter.continuation_indentation=2 -org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2 -org.eclipse.jdt.core.formatter.disabling_tag=@formatter\:off -org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on -org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false -org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true -org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true -org.eclipse.jdt.core.formatter.indent_empty_lines=false -org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true -org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true -org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true -org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false -org.eclipse.jdt.core.formatter.indentation.size=8 -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_after_type_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=insert -org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=insert -org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=insert -org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert -org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert -org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert -org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow=insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources=insert -org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert -org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert -org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert -org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert -org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert -org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.join_lines_in_comments=true -org.eclipse.jdt.core.formatter.join_wrapped_lines=true -org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false -org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false -org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false -org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false -org.eclipse.jdt.core.formatter.lineSplit=90 -org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false -org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false -org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0 -org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1 -org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true -org.eclipse.jdt.core.formatter.tabulation.char=tab -org.eclipse.jdt.core.formatter.tabulation.size=4 -org.eclipse.jdt.core.formatter.use_on_off_tags=false -org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false -org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true -org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true -org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true diff --git a/samples/rest-notes-spring-data-rest/.settings/org.eclipse.jdt.ui.prefs b/samples/rest-notes-spring-data-rest/.settings/org.eclipse.jdt.ui.prefs deleted file mode 100644 index 1f4325cd5..000000000 --- a/samples/rest-notes-spring-data-rest/.settings/org.eclipse.jdt.ui.prefs +++ /dev/null @@ -1,62 +0,0 @@ -cleanup.add_default_serial_version_id=true -cleanup.add_generated_serial_version_id=false -cleanup.add_missing_annotations=true -cleanup.add_missing_deprecated_annotations=true -cleanup.add_missing_methods=false -cleanup.add_missing_nls_tags=false -cleanup.add_missing_override_annotations=true -cleanup.add_missing_override_annotations_interface_methods=true -cleanup.add_serial_version_id=false -cleanup.always_use_blocks=true -cleanup.always_use_parentheses_in_expressions=false -cleanup.always_use_this_for_non_static_field_access=true -cleanup.always_use_this_for_non_static_method_access=false -cleanup.convert_functional_interfaces=false -cleanup.convert_to_enhanced_for_loop=false -cleanup.correct_indentation=true -cleanup.format_source_code=true -cleanup.format_source_code_changes_only=false -cleanup.insert_inferred_type_arguments=false -cleanup.make_local_variable_final=false -cleanup.make_parameters_final=false -cleanup.make_private_fields_final=false -cleanup.make_type_abstract_if_missing_method=false -cleanup.make_variable_declarations_final=false -cleanup.never_use_blocks=false -cleanup.never_use_parentheses_in_expressions=true -cleanup.organize_imports=true -cleanup.qualify_static_field_accesses_with_declaring_class=false -cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true -cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true -cleanup.qualify_static_member_accesses_with_declaring_class=true -cleanup.qualify_static_method_accesses_with_declaring_class=false -cleanup.remove_private_constructors=true -cleanup.remove_redundant_type_arguments=true -cleanup.remove_trailing_whitespaces=true -cleanup.remove_trailing_whitespaces_all=true -cleanup.remove_trailing_whitespaces_ignore_empty=false -cleanup.remove_unnecessary_casts=true -cleanup.remove_unnecessary_nls_tags=false -cleanup.remove_unused_imports=true -cleanup.remove_unused_local_variables=false -cleanup.remove_unused_private_fields=true -cleanup.remove_unused_private_members=false -cleanup.remove_unused_private_methods=true -cleanup.remove_unused_private_types=true -cleanup.sort_members=false -cleanup.sort_members_all=false -cleanup.use_anonymous_class_creation=false -cleanup.use_blocks=true -cleanup.use_blocks_only_for_return_and_throw=false -cleanup.use_lambda=true -cleanup.use_parentheses_in_expressions=false -cleanup.use_this_for_non_static_field_access=true -cleanup.use_this_for_non_static_field_access_only_if_necessary=false -cleanup.use_this_for_non_static_method_access=false -cleanup.use_this_for_non_static_method_access_only_if_necessary=true -cleanup.use_type_arguments=false -cleanup_profile=_Spring Rest Docs Cleanup Conventions -cleanup_settings_version=2 -eclipse.preferences.version=1 -formatter_profile=_Spring Rest Docs Java Conventions -formatter_settings_version=12 diff --git a/samples/rest-notes-spring-hateoas/.settings/org.eclipse.jdt.core.prefs b/samples/rest-notes-spring-hateoas/.settings/org.eclipse.jdt.core.prefs deleted file mode 100644 index 83412a90a..000000000 --- a/samples/rest-notes-spring-hateoas/.settings/org.eclipse.jdt.core.prefs +++ /dev/null @@ -1,295 +0,0 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7 -org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve -org.eclipse.jdt.core.compiler.compliance=1.7 -org.eclipse.jdt.core.compiler.debug.lineNumber=generate -org.eclipse.jdt.core.compiler.debug.localVariable=generate -org.eclipse.jdt.core.compiler.debug.sourceFile=generate -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.source=1.7 -org.eclipse.jdt.core.formatter.align_type_members_on_columns=false -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16 -org.eclipse.jdt.core.formatter.alignment_for_assignment=0 -org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16 -org.eclipse.jdt.core.formatter.alignment_for_compact_if=16 -org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80 -org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0 -org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16 -org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0 -org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16 -org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=80 -org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16 -org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch=16 -org.eclipse.jdt.core.formatter.blank_lines_after_imports=1 -org.eclipse.jdt.core.formatter.blank_lines_after_package=1 -org.eclipse.jdt.core.formatter.blank_lines_before_field=1 -org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=1 -org.eclipse.jdt.core.formatter.blank_lines_before_imports=1 -org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1 -org.eclipse.jdt.core.formatter.blank_lines_before_method=1 -org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1 -org.eclipse.jdt.core.formatter.blank_lines_before_package=0 -org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1 -org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1 -org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_lambda_body=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line -org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false -org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false -org.eclipse.jdt.core.formatter.comment.format_block_comments=true -org.eclipse.jdt.core.formatter.comment.format_header=false -org.eclipse.jdt.core.formatter.comment.format_html=true -org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true -org.eclipse.jdt.core.formatter.comment.format_line_comments=true -org.eclipse.jdt.core.formatter.comment.format_source_code=false -org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true -org.eclipse.jdt.core.formatter.comment.indent_root_tags=false -org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=do not insert -org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=do not insert -org.eclipse.jdt.core.formatter.comment.line_length=90 -org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true -org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true -org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=false -org.eclipse.jdt.core.formatter.compact_else_if=true -org.eclipse.jdt.core.formatter.continuation_indentation=2 -org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2 -org.eclipse.jdt.core.formatter.disabling_tag=@formatter\:off -org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on -org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false -org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true -org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true -org.eclipse.jdt.core.formatter.indent_empty_lines=false -org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true -org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true -org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true -org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false -org.eclipse.jdt.core.formatter.indentation.size=8 -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_after_type_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=insert -org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=insert -org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=insert -org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert -org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert -org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert -org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow=insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources=insert -org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert -org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert -org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert -org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert -org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert -org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.join_lines_in_comments=true -org.eclipse.jdt.core.formatter.join_wrapped_lines=true -org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false -org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false -org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false -org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false -org.eclipse.jdt.core.formatter.lineSplit=90 -org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false -org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false -org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0 -org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1 -org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true -org.eclipse.jdt.core.formatter.tabulation.char=tab -org.eclipse.jdt.core.formatter.tabulation.size=4 -org.eclipse.jdt.core.formatter.use_on_off_tags=false -org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false -org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true -org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true -org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true diff --git a/samples/rest-notes-spring-hateoas/.settings/org.eclipse.jdt.ui.prefs b/samples/rest-notes-spring-hateoas/.settings/org.eclipse.jdt.ui.prefs deleted file mode 100644 index 1f4325cd5..000000000 --- a/samples/rest-notes-spring-hateoas/.settings/org.eclipse.jdt.ui.prefs +++ /dev/null @@ -1,62 +0,0 @@ -cleanup.add_default_serial_version_id=true -cleanup.add_generated_serial_version_id=false -cleanup.add_missing_annotations=true -cleanup.add_missing_deprecated_annotations=true -cleanup.add_missing_methods=false -cleanup.add_missing_nls_tags=false -cleanup.add_missing_override_annotations=true -cleanup.add_missing_override_annotations_interface_methods=true -cleanup.add_serial_version_id=false -cleanup.always_use_blocks=true -cleanup.always_use_parentheses_in_expressions=false -cleanup.always_use_this_for_non_static_field_access=true -cleanup.always_use_this_for_non_static_method_access=false -cleanup.convert_functional_interfaces=false -cleanup.convert_to_enhanced_for_loop=false -cleanup.correct_indentation=true -cleanup.format_source_code=true -cleanup.format_source_code_changes_only=false -cleanup.insert_inferred_type_arguments=false -cleanup.make_local_variable_final=false -cleanup.make_parameters_final=false -cleanup.make_private_fields_final=false -cleanup.make_type_abstract_if_missing_method=false -cleanup.make_variable_declarations_final=false -cleanup.never_use_blocks=false -cleanup.never_use_parentheses_in_expressions=true -cleanup.organize_imports=true -cleanup.qualify_static_field_accesses_with_declaring_class=false -cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true -cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true -cleanup.qualify_static_member_accesses_with_declaring_class=true -cleanup.qualify_static_method_accesses_with_declaring_class=false -cleanup.remove_private_constructors=true -cleanup.remove_redundant_type_arguments=true -cleanup.remove_trailing_whitespaces=true -cleanup.remove_trailing_whitespaces_all=true -cleanup.remove_trailing_whitespaces_ignore_empty=false -cleanup.remove_unnecessary_casts=true -cleanup.remove_unnecessary_nls_tags=false -cleanup.remove_unused_imports=true -cleanup.remove_unused_local_variables=false -cleanup.remove_unused_private_fields=true -cleanup.remove_unused_private_members=false -cleanup.remove_unused_private_methods=true -cleanup.remove_unused_private_types=true -cleanup.sort_members=false -cleanup.sort_members_all=false -cleanup.use_anonymous_class_creation=false -cleanup.use_blocks=true -cleanup.use_blocks_only_for_return_and_throw=false -cleanup.use_lambda=true -cleanup.use_parentheses_in_expressions=false -cleanup.use_this_for_non_static_field_access=true -cleanup.use_this_for_non_static_field_access_only_if_necessary=false -cleanup.use_this_for_non_static_method_access=false -cleanup.use_this_for_non_static_method_access_only_if_necessary=true -cleanup.use_type_arguments=false -cleanup_profile=_Spring Rest Docs Cleanup Conventions -cleanup_settings_version=2 -eclipse.preferences.version=1 -formatter_profile=_Spring Rest Docs Java Conventions -formatter_settings_version=12 From c9837c645f4297884921775f4d791dda65a5ccd8 Mon Sep 17 00:00:00 2001 From: Kirill Gavrilov Date: Mon, 10 Jun 2019 11:35:47 +0300 Subject: [PATCH 040/502] Fix lack of syntax highlighting when using Maven See gh-620 --- docs/src/docs/asciidoc/getting-started.adoc | 2 +- samples/rest-notes-spring-data-rest/pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/src/docs/asciidoc/getting-started.adoc b/docs/src/docs/asciidoc/getting-started.adoc index 966f6946a..a17a8ae94 100644 --- a/docs/src/docs/asciidoc/getting-started.adoc +++ b/docs/src/docs/asciidoc/getting-started.adoc @@ -100,7 +100,7 @@ the configuration are described below. <2> org.asciidoctor asciidoctor-maven-plugin - 1.5.3 + 1.5.8 generate-docs diff --git a/samples/rest-notes-spring-data-rest/pom.xml b/samples/rest-notes-spring-data-rest/pom.xml index c71e91695..ca7fb37a9 100644 --- a/samples/rest-notes-spring-data-rest/pom.xml +++ b/samples/rest-notes-spring-data-rest/pom.xml @@ -72,7 +72,7 @@ org.asciidoctor asciidoctor-maven-plugin - 1.5.3 + 1.5.8 generate-docs From aee49b8511516ba0afad0182bb2d4e72496b7331 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Tue, 18 Jun 2019 12:05:05 +0100 Subject: [PATCH 041/502] Allow Matrix tests to select single artifact in a group --- .../restdocs/build/matrix/MatrixTestExtension.groovy | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/buildSrc/src/main/groovy/org/springframework/restdocs/build/matrix/MatrixTestExtension.groovy b/buildSrc/src/main/groovy/org/springframework/restdocs/build/matrix/MatrixTestExtension.groovy index 9f97a9321..6d4e6f4fa 100644 --- a/buildSrc/src/main/groovy/org/springframework/restdocs/build/matrix/MatrixTestExtension.groovy +++ b/buildSrc/src/main/groovy/org/springframework/restdocs/build/matrix/MatrixTestExtension.groovy @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-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. @@ -43,7 +43,7 @@ public class MatrixTestExtension { void configureTestTasks(Project project) { if (!entries.empty) { cartesianProduct(entries.collect { entry -> - entry.versions.collect { ['group': entry.group, 'version': it] } + entry.versions.collect { ['group': entry.group, 'artifact': entry.artifact, 'version': it] } }).forEach { configureTestTask(project, it) } } } @@ -64,6 +64,7 @@ public class MatrixTestExtension { resolutionStrategy.eachDependency { dependency -> versionSelectors .findAll{ it.group == dependency.requested.group } + .findAll { !it.artifact || it.artifact == dependency.requested.name } .each { dependency.useVersion it.version } } } @@ -98,6 +99,8 @@ public class MatrixTestExtension { String group + String artifact + List versions } From 82f3b250e81933e0071bad9101f0a13e8dd7ffa1 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Tue, 18 Jun 2019 12:06:20 +0100 Subject: [PATCH 042/502] Fix matrix testing with single selector that has multiple versions --- .../restdocs/build/matrix/MatrixTestExtension.groovy | 3 --- 1 file changed, 3 deletions(-) diff --git a/buildSrc/src/main/groovy/org/springframework/restdocs/build/matrix/MatrixTestExtension.groovy b/buildSrc/src/main/groovy/org/springframework/restdocs/build/matrix/MatrixTestExtension.groovy index 6d4e6f4fa..b3b4dab72 100644 --- a/buildSrc/src/main/groovy/org/springframework/restdocs/build/matrix/MatrixTestExtension.groovy +++ b/buildSrc/src/main/groovy/org/springframework/restdocs/build/matrix/MatrixTestExtension.groovy @@ -74,9 +74,6 @@ public class MatrixTestExtension { } List>> cartesianProduct(List>> lists) { - if (lists.size() == 1) { - return lists - } return cartesianProduct(lists, 0) } From 76a89cf65841ac294084d7829ca4d18e2358b2a6 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Tue, 18 Jun 2019 12:14:15 +0100 Subject: [PATCH 043/502] Upgrade to AsciidoctorJ 1.5.8.1 Closes gh-621 --- build.gradle | 2 +- .../src/test/resources/operations/all-snippets.html | 2 +- .../src/test/resources/operations/snippet-table.html | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/build.gradle b/build.gradle index b1f0f0d24..37b25620e 100644 --- a/build.gradle +++ b/build.gradle @@ -82,7 +82,7 @@ subprojects { dependency 'io.rest-assured:rest-assured:3.0.7' dependency 'org.apache.pdfbox:pdfbox:2.0.7' dependency 'org.assertj:assertj-core:2.9.1' - dependency 'org.asciidoctor:asciidoctorj:1.5.6' + dependency 'org.asciidoctor:asciidoctorj:1.5.8.1' dependency 'org.asciidoctor:asciidoctorj-pdf:1.5.0-alpha.16' dependency 'org.hamcrest:hamcrest-core:1.3' dependency 'org.hamcrest:hamcrest-library:1.3' diff --git a/spring-restdocs-asciidoctor/src/test/resources/operations/all-snippets.html b/spring-restdocs-asciidoctor/src/test/resources/operations/all-snippets.html index 524e1ee7e..491f9dedf 100644 --- a/spring-restdocs-asciidoctor/src/test/resources/operations/all-snippets.html +++ b/spring-restdocs-asciidoctor/src/test/resources/operations/all-snippets.html @@ -32,7 +32,7 @@

HTTP request

Response fields

- +
diff --git a/spring-restdocs-asciidoctor/src/test/resources/operations/snippet-table.html b/spring-restdocs-asciidoctor/src/test/resources/operations/snippet-table.html index a8241a03e..b01bc522a 100644 --- a/spring-restdocs-asciidoctor/src/test/resources/operations/snippet-table.html +++ b/spring-restdocs-asciidoctor/src/test/resources/operations/snippet-table.html @@ -1,7 +1,7 @@

Response fields

-
+
From ff18f8034df6084b2a1d2bdfc79ff6e5d5011c1b Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Tue, 18 Jun 2019 12:03:42 +0100 Subject: [PATCH 044/502] Add AsciidoctorJ 1.6 and 2.0 compatibility AsciidoctorJ 1.6 is not backwards compatible with AsciidoctorJ 1.5 and AsciidoctorJ 2.0 is not backwards compatible with AsciidoctorJ 1.6 or 1.5. The backwards incompatibilities are such that they cannot be worked around using reflection so code needs to be compiled against each of the three versions. To this end, this commit splits spring-restdocs-asciidoctor into several separate modules: 1. spring-restdocs-asciidoctor-support 2. spring-restdocs-asciidoctor-1.5 3. spring-restdocs-asciidoctor-1.6 4. spring-restdocs-asciidoctor-2.0 spring-restdocs-asciidoctor-support contains support code that is not tied to a specific version of AsciidoctorJ and can be used with 1.5, 1.6 and 2.0. The other three modules contain code that is specific to a particular version of AsciidoctorJ. Each version-specific module uses class names that are unique across all three modules and is written in such a way that they will back off when used in an environment with a different version of AsciidoctorJ. The existing spring-restdocs-asciidoctor module has been modified to merge the version specific jars and the support jar together into a single jar that supports AsciidoctorJ 1.5, 1.6, and 2.0. The above-described changes should allow users to depend upon spring-restdocs-asciidoctor as before and to now be able to use AsciidoctorJ 1.5, 1.6, or 2.0. Closes gh-581 --- build.gradle | 26 ++----- gradle.properties | 3 + settings.gradle | 4 ++ spring-restdocs-asciidoctor-1.5/build.gradle | 10 +++ ...tAttributesAsciidoctorJ15Preprocessor.java | 4 +- ...stDocsAsciidoctorJ15ExtensionRegistry.java | 52 ++++++++++++++ ...ibutesAsciidoctorJ15PreprocessorTests.java | 35 ++++++---- spring-restdocs-asciidoctor-1.6/build.gradle | 10 +++ ...tAttributesAsciidoctorJ16Preprocessor.java | 39 +++++++++++ ...stDocsAsciidoctorJ16ExtensionRegistry.java | 52 ++++++++++++++ ...ibutesAsciidoctorJ16PreprocessorTests.java | 70 +++++++++++++++++++ spring-restdocs-asciidoctor-2.0/build.gradle | 10 +++ ...tAttributesAsciidoctorJ20Preprocessor.java | 39 +++++++++++ ...stDocsAsciidoctorJ20ExtensionRegistry.java | 13 ++-- ...ibutesAsciidoctorJ20PreprocessorTests.java | 70 +++++++++++++++++++ .../build.gradle | 6 ++ .../SnippetsDirectoryResolver.java | 2 +- .../extensions/operation_block_macro.rb | 0 .../SnippetsDirectoryResolverTests.java | 2 +- spring-restdocs-asciidoctor/build.gradle | 25 +++++-- .../restdocs/asciidoctor/package-info.java | 20 ------ ...sciidoctor.extension.spi.ExtensionRegistry | 3 +- ...ctor.jruby.extension.spi.ExtensionRegistry | 1 + 23 files changed, 427 insertions(+), 69 deletions(-) create mode 100644 spring-restdocs-asciidoctor-1.5/build.gradle rename spring-restdocs-asciidoctor/src/main/java/org/springframework/restdocs/asciidoctor/DefaultAttributesPreprocessor.java => spring-restdocs-asciidoctor-1.5/src/main/java/org/springframework/restdocs/asciidoctor/DefaultAttributesAsciidoctorJ15Preprocessor.java (90%) create mode 100644 spring-restdocs-asciidoctor-1.5/src/main/java/org/springframework/restdocs/asciidoctor/RestDocsAsciidoctorJ15ExtensionRegistry.java rename spring-restdocs-asciidoctor/src/test/java/org/springframework/restdocs/asciidoctor/DefaultAttributesPreprocessorTests.java => spring-restdocs-asciidoctor-1.5/src/test/java/org/springframework/restdocs/asciidoctor/DefaultAttributesAsciidoctorJ15PreprocessorTests.java (58%) create mode 100644 spring-restdocs-asciidoctor-1.6/build.gradle create mode 100644 spring-restdocs-asciidoctor-1.6/src/main/java/org/springframework/restdocs/asciidoctor/DefaultAttributesAsciidoctorJ16Preprocessor.java create mode 100644 spring-restdocs-asciidoctor-1.6/src/main/java/org/springframework/restdocs/asciidoctor/RestDocsAsciidoctorJ16ExtensionRegistry.java create mode 100644 spring-restdocs-asciidoctor-1.6/src/test/java/org/springframework/restdocs/asciidoctor/DefaultAttributesAsciidoctorJ16PreprocessorTests.java create mode 100644 spring-restdocs-asciidoctor-2.0/build.gradle create mode 100644 spring-restdocs-asciidoctor-2.0/src/main/java/org/springframework/restdocs/asciidoctor/DefaultAttributesAsciidoctorJ20Preprocessor.java rename spring-restdocs-asciidoctor/src/main/java/org/springframework/restdocs/asciidoctor/RestDocsExtensionRegistry.java => spring-restdocs-asciidoctor-2.0/src/main/java/org/springframework/restdocs/asciidoctor/RestDocsAsciidoctorJ20ExtensionRegistry.java (70%) create mode 100644 spring-restdocs-asciidoctor-2.0/src/test/java/org/springframework/restdocs/asciidoctor/DefaultAttributesAsciidoctorJ20PreprocessorTests.java create mode 100644 spring-restdocs-asciidoctor-support/build.gradle rename {spring-restdocs-asciidoctor => spring-restdocs-asciidoctor-support}/src/main/java/org/springframework/restdocs/asciidoctor/SnippetsDirectoryResolver.java (97%) rename {spring-restdocs-asciidoctor => spring-restdocs-asciidoctor-support}/src/main/resources/extensions/operation_block_macro.rb (100%) rename {spring-restdocs-asciidoctor => spring-restdocs-asciidoctor-support}/src/test/java/org/springframework/restdocs/asciidoctor/SnippetsDirectoryResolverTests.java (98%) delete mode 100644 spring-restdocs-asciidoctor/src/main/java/org/springframework/restdocs/asciidoctor/package-info.java create mode 100644 spring-restdocs-asciidoctor/src/main/resources/META-INF/services/org.asciidoctor.jruby.extension.spi.ExtensionRegistry diff --git a/build.gradle b/build.gradle index 6d69b6984..d794fd801 100644 --- a/build.gradle +++ b/build.gradle @@ -83,7 +83,6 @@ subprojects { dependency 'io.rest-assured:rest-assured:3.0.7' dependency 'org.apache.pdfbox:pdfbox:2.0.7' dependency 'org.assertj:assertj-core:2.9.1' - dependency 'org.asciidoctor:asciidoctorj:1.5.8.1' dependency 'org.asciidoctor:asciidoctorj-pdf:1.5.0-alpha.16' dependency 'org.hamcrest:hamcrest-core:1.3' dependency 'org.hamcrest:hamcrest-library:1.3' @@ -123,27 +122,12 @@ subprojects { } -configure(subprojects - project(":docs")) { subproject -> +def codeProjects = subprojects - project(":docs") +configure(codeProjects) { apply plugin: 'io.spring.javaformat' apply plugin: 'checkstyle' apply from: "${rootProject.projectDir}/gradle/publish-maven.gradle" - if (project.hasProperty('platformVersion') && subproject.path != ':spring-restdocs-asciidoctor') { - apply plugin: 'spring-io' - - repositories { - maven { url "https://repo.spring.io/libs-snapshot" } - } - - dependencyManagement { - springIoTestRuntime { - imports { - mavenBom "io.spring.platform:platform-bom:${platformVersion}" - } - } - } - } - checkstyle { configFile = rootProject.file('config/checkstyle/checkstyle.xml') configProperties = [ 'checkstyle.config.dir' : rootProject.file('config/checkstyle') ] @@ -158,7 +142,10 @@ configure(subprojects - project(":docs")) { subproject -> checkstyle "io.spring.javaformat:spring-javaformat-checkstyle:$javaFormatVersion" jacoco 'org.jacoco:org.jacoco.agent::runtime' } +} +def publishedCodeProjects = codeProjects.findAll { codeProject -> !codeProject.name.contains('spring-restdocs-asciidoctor')} +configure(publishedCodeProjects) { subproject -> javadoc { description = "Generates project-level javadoc for use in -javadoc jar" options.memberLevel = org.gradle.external.javadoc.JavadocMemberLevel.PROTECTED @@ -243,8 +230,7 @@ task api (type: Javadoc) { options.links = javadocLinks options.addStringOption '-quiet' - source subprojects.findAll { project -> project.path != ":spring-restdocs-asciidoctor" } - .collect { project -> project.sourceSets.main.allJava } + source publishedCodeProjects.collect { project -> project.sourceSets.main.allJava } destinationDir = new File(buildDir, "api") diff --git a/gradle.properties b/gradle.properties index ce03bf970..165156e6a 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,6 @@ version=2.0.4.BUILD-SNAPSHOT javaFormatVersion=0.0.7-SNAPSHOT org.gradle.daemon=false +asciidoctorj15Version=1.5.8.1 +asciidoctorj16Version=1.6.2 +asciidoctorj20Version=2.0.0-RC.3 diff --git a/settings.gradle b/settings.gradle index 1af633bfa..eabf9a196 100644 --- a/settings.gradle +++ b/settings.gradle @@ -2,6 +2,10 @@ rootProject.name = 'spring-restdocs' include 'docs' include 'spring-restdocs-asciidoctor' +include 'spring-restdocs-asciidoctor-1.5' +include 'spring-restdocs-asciidoctor-1.6' +include 'spring-restdocs-asciidoctor-2.0' +include 'spring-restdocs-asciidoctor-support' include 'spring-restdocs-core' include 'spring-restdocs-mockmvc' include 'spring-restdocs-restassured' diff --git a/spring-restdocs-asciidoctor-1.5/build.gradle b/spring-restdocs-asciidoctor-1.5/build.gradle new file mode 100644 index 000000000..653cb1071 --- /dev/null +++ b/spring-restdocs-asciidoctor-1.5/build.gradle @@ -0,0 +1,10 @@ +description = 'AsciidoctorJ 1.5 extensions for Spring REST Docs' + +dependencies { + compileOnly "org.asciidoctor:asciidoctorj:$asciidoctorj15Version" + implementation project(':spring-restdocs-asciidoctor-support') + testCompile 'junit:junit' + testCompile "org.asciidoctor:asciidoctorj:$asciidoctorj15Version" + testCompile 'org.assertj:assertj-core' + testRuntime project(':spring-restdocs-asciidoctor-support') +} \ No newline at end of file diff --git a/spring-restdocs-asciidoctor/src/main/java/org/springframework/restdocs/asciidoctor/DefaultAttributesPreprocessor.java b/spring-restdocs-asciidoctor-1.5/src/main/java/org/springframework/restdocs/asciidoctor/DefaultAttributesAsciidoctorJ15Preprocessor.java similarity index 90% rename from spring-restdocs-asciidoctor/src/main/java/org/springframework/restdocs/asciidoctor/DefaultAttributesPreprocessor.java rename to spring-restdocs-asciidoctor-1.5/src/main/java/org/springframework/restdocs/asciidoctor/DefaultAttributesAsciidoctorJ15Preprocessor.java index 5483cfcdf..36d86fb08 100644 --- a/spring-restdocs-asciidoctor/src/main/java/org/springframework/restdocs/asciidoctor/DefaultAttributesPreprocessor.java +++ b/spring-restdocs-asciidoctor-1.5/src/main/java/org/springframework/restdocs/asciidoctor/DefaultAttributesAsciidoctorJ15Preprocessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2016 the original author or authors. + * Copyright 2014-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. @@ -26,7 +26,7 @@ * * @author Andy Wilkinson */ -final class DefaultAttributesPreprocessor extends Preprocessor { +final class DefaultAttributesAsciidoctorJ15Preprocessor extends Preprocessor { private final SnippetsDirectoryResolver snippetsDirectoryResolver = new SnippetsDirectoryResolver(); diff --git a/spring-restdocs-asciidoctor-1.5/src/main/java/org/springframework/restdocs/asciidoctor/RestDocsAsciidoctorJ15ExtensionRegistry.java b/spring-restdocs-asciidoctor-1.5/src/main/java/org/springframework/restdocs/asciidoctor/RestDocsAsciidoctorJ15ExtensionRegistry.java new file mode 100644 index 000000000..529a141a6 --- /dev/null +++ b/spring-restdocs-asciidoctor-1.5/src/main/java/org/springframework/restdocs/asciidoctor/RestDocsAsciidoctorJ15ExtensionRegistry.java @@ -0,0 +1,52 @@ +/* + * Copyright 2014-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 + * + * https://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.extension.spi.ExtensionRegistry; + +/** + * AsciidoctorJ 1.5 {@link ExtensionRegistry} for Spring REST Docs. + * + * @author Andy Wilkinson + */ +public final class RestDocsAsciidoctorJ15ExtensionRegistry implements ExtensionRegistry { + + @Override + public void register(Asciidoctor asciidoctor) { + if (!asciidoctorJ15()) { + return; + } + asciidoctor.javaExtensionRegistry() + .preprocessor(new DefaultAttributesAsciidoctorJ15Preprocessor()); + asciidoctor.rubyExtensionRegistry() + .loadClass(RestDocsAsciidoctorJ15ExtensionRegistry.class + .getResourceAsStream("/extensions/operation_block_macro.rb")) + .blockMacro("operation", "OperationBlockMacro"); + } + + private boolean asciidoctorJ15() { + try { + return !Class.forName("org.asciidoctor.extension.JavaExtensionRegistry") + .isInterface(); + } + catch (Throwable ex) { + return false; + } + } + +} diff --git a/spring-restdocs-asciidoctor/src/test/java/org/springframework/restdocs/asciidoctor/DefaultAttributesPreprocessorTests.java b/spring-restdocs-asciidoctor-1.5/src/test/java/org/springframework/restdocs/asciidoctor/DefaultAttributesAsciidoctorJ15PreprocessorTests.java similarity index 58% rename from spring-restdocs-asciidoctor/src/test/java/org/springframework/restdocs/asciidoctor/DefaultAttributesPreprocessorTests.java rename to spring-restdocs-asciidoctor-1.5/src/test/java/org/springframework/restdocs/asciidoctor/DefaultAttributesAsciidoctorJ15PreprocessorTests.java index 12bf34fe1..761294832 100644 --- a/spring-restdocs-asciidoctor/src/test/java/org/springframework/restdocs/asciidoctor/DefaultAttributesPreprocessorTests.java +++ b/spring-restdocs-asciidoctor-1.5/src/test/java/org/springframework/restdocs/asciidoctor/DefaultAttributesAsciidoctorJ15PreprocessorTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2016 the original author or authors. + * Copyright 2014-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. @@ -26,36 +26,45 @@ import static org.assertj.core.api.Assertions.assertThat; /** - * Tests for {@link DefaultAttributesPreprocessor}. + * Tests for {@link DefaultAttributesAsciidoctorJ15Preprocessor}. * * @author Andy Wilkinson */ -public class DefaultAttributesPreprocessorTests { +public class DefaultAttributesAsciidoctorJ15PreprocessorTests { @Test public void snippetsAttributeIsSet() { - Options options = new Options(); - options.setAttributes(new Attributes("projectdir=../../..")); - String converted = Asciidoctor.Factory.create().convert("{snippets}", options); + String converted = createAsciidoctor().convert("{snippets}", + createOptions("projectdir=../../..")); assertThat(converted) .contains("build" + File.separatorChar + "generated-snippets"); } @Test public void snippetsAttributeFromConvertArgumentIsNotOverridden() { - Options options = new Options(); - options.setAttributes(new Attributes("snippets=custom projectdir=../../..")); - String converted = Asciidoctor.Factory.create().convert("{snippets}", options); + String converted = createAsciidoctor().convert("{snippets}", + createOptions("snippets=custom projectdir=../../..")); assertThat(converted).contains("custom"); } @Test public void snippetsAttributeFromDocumentPreambleIsNotOverridden() { - Options options = new Options(); - options.setAttributes(new Attributes("projectdir=../../..")); - String converted = Asciidoctor.Factory.create() - .convert(":snippets: custom\n{snippets}", options); + String converted = createAsciidoctor().convert(":snippets: custom\n{snippets}", + createOptions("projectdir=../../..")); assertThat(converted).contains("custom"); } + private Options createOptions(String attributes) { + Options options = new Options(); + options.setAttributes(new Attributes(attributes)); + return options; + } + + private Asciidoctor createAsciidoctor() { + Asciidoctor asciidoctor = Asciidoctor.Factory.create(); + asciidoctor.javaExtensionRegistry() + .preprocessor(new DefaultAttributesAsciidoctorJ15Preprocessor()); + return asciidoctor; + } + } diff --git a/spring-restdocs-asciidoctor-1.6/build.gradle b/spring-restdocs-asciidoctor-1.6/build.gradle new file mode 100644 index 000000000..a09724e66 --- /dev/null +++ b/spring-restdocs-asciidoctor-1.6/build.gradle @@ -0,0 +1,10 @@ +description = 'AsciidoctorJ 1.6 extensions for Spring REST Docs' + +dependencies { + compileOnly "org.asciidoctor:asciidoctorj:$asciidoctorj16Version" + implementation project(':spring-restdocs-asciidoctor-support') + testCompile 'junit:junit' + testCompile "org.asciidoctor:asciidoctorj:$asciidoctorj16Version" + testCompile 'org.assertj:assertj-core' + testRuntime project(':spring-restdocs-asciidoctor-support') +} \ No newline at end of file diff --git a/spring-restdocs-asciidoctor-1.6/src/main/java/org/springframework/restdocs/asciidoctor/DefaultAttributesAsciidoctorJ16Preprocessor.java b/spring-restdocs-asciidoctor-1.6/src/main/java/org/springframework/restdocs/asciidoctor/DefaultAttributesAsciidoctorJ16Preprocessor.java new file mode 100644 index 000000000..017126aa0 --- /dev/null +++ b/spring-restdocs-asciidoctor-1.6/src/main/java/org/springframework/restdocs/asciidoctor/DefaultAttributesAsciidoctorJ16Preprocessor.java @@ -0,0 +1,39 @@ +/* + * Copyright 2014-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 + * + * https://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.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 DefaultAttributesAsciidoctorJ16Preprocessor extends Preprocessor { + + private final SnippetsDirectoryResolver snippetsDirectoryResolver = new SnippetsDirectoryResolver(); + + @Override + public void process(Document document, PreprocessorReader reader) { + document.setAttribute("snippets", this.snippetsDirectoryResolver + .getSnippetsDirectory(document.getAttributes()), false); + } + +} diff --git a/spring-restdocs-asciidoctor-1.6/src/main/java/org/springframework/restdocs/asciidoctor/RestDocsAsciidoctorJ16ExtensionRegistry.java b/spring-restdocs-asciidoctor-1.6/src/main/java/org/springframework/restdocs/asciidoctor/RestDocsAsciidoctorJ16ExtensionRegistry.java new file mode 100644 index 000000000..91c07aa66 --- /dev/null +++ b/spring-restdocs-asciidoctor-1.6/src/main/java/org/springframework/restdocs/asciidoctor/RestDocsAsciidoctorJ16ExtensionRegistry.java @@ -0,0 +1,52 @@ +/* + * Copyright 2014-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 + * + * https://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.extension.spi.ExtensionRegistry; + +/** + * AsciidoctorJ 1.6 {@link ExtensionRegistry} for Spring REST Docs. + * + * @author Andy Wilkinson + */ +public final class RestDocsAsciidoctorJ16ExtensionRegistry implements ExtensionRegistry { + + @Override + public void register(Asciidoctor asciidoctor) { + if (!asciidoctorJ16()) { + return; + } + asciidoctor.javaExtensionRegistry() + .preprocessor(new DefaultAttributesAsciidoctorJ16Preprocessor()); + asciidoctor.rubyExtensionRegistry() + .loadClass(RestDocsAsciidoctorJ16ExtensionRegistry.class + .getResourceAsStream("/extensions/operation_block_macro.rb")) + .blockMacro("operation", "OperationBlockMacro"); + } + + private boolean asciidoctorJ16() { + try { + return Class.forName("org.asciidoctor.extension.JavaExtensionRegistry") + .isInterface(); + } + catch (Throwable ex) { + return false; + } + } + +} diff --git a/spring-restdocs-asciidoctor-1.6/src/test/java/org/springframework/restdocs/asciidoctor/DefaultAttributesAsciidoctorJ16PreprocessorTests.java b/spring-restdocs-asciidoctor-1.6/src/test/java/org/springframework/restdocs/asciidoctor/DefaultAttributesAsciidoctorJ16PreprocessorTests.java new file mode 100644 index 000000000..6055607e5 --- /dev/null +++ b/spring-restdocs-asciidoctor-1.6/src/test/java/org/springframework/restdocs/asciidoctor/DefaultAttributesAsciidoctorJ16PreprocessorTests.java @@ -0,0 +1,70 @@ +/* + * Copyright 2014-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 + * + * https://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.Asciidoctor; +import org.asciidoctor.Attributes; +import org.asciidoctor.Options; +import org.junit.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link DefaultAttributesAsciidoctorJ16Preprocessor}. + * + * @author Andy Wilkinson + */ +public class DefaultAttributesAsciidoctorJ16PreprocessorTests { + + @Test + public void snippetsAttributeIsSet() { + String converted = createAsciidoctor().convert("{snippets}", + createOptions("projectdir=../../..")); + assertThat(converted) + .contains("build" + File.separatorChar + "generated-snippets"); + } + + @Test + public void snippetsAttributeFromConvertArgumentIsNotOverridden() { + String converted = createAsciidoctor().convert("{snippets}", + createOptions("snippets=custom projectdir=../../..")); + assertThat(converted).contains("custom"); + } + + @Test + public void snippetsAttributeFromDocumentPreambleIsNotOverridden() { + String converted = createAsciidoctor().convert(":snippets: custom\n{snippets}", + createOptions("projectdir=../../..")); + assertThat(converted).contains("custom"); + } + + private Options createOptions(String attributes) { + Options options = new Options(); + options.setAttributes(new Attributes(attributes)); + return options; + } + + private Asciidoctor createAsciidoctor() { + Asciidoctor asciidoctor = Asciidoctor.Factory.create(); + asciidoctor.javaExtensionRegistry() + .preprocessor(new DefaultAttributesAsciidoctorJ16Preprocessor()); + return asciidoctor; + } + +} diff --git a/spring-restdocs-asciidoctor-2.0/build.gradle b/spring-restdocs-asciidoctor-2.0/build.gradle new file mode 100644 index 000000000..48e8d5cfe --- /dev/null +++ b/spring-restdocs-asciidoctor-2.0/build.gradle @@ -0,0 +1,10 @@ +description = 'AsciidoctorJ 2.0 extensions for Spring REST Docs' + +dependencies { + compileOnly "org.asciidoctor:asciidoctorj:$asciidoctorj20Version" + implementation project(':spring-restdocs-asciidoctor-support') + testCompile 'junit:junit' + testCompile "org.asciidoctor:asciidoctorj:$asciidoctorj15Version" + testCompile 'org.assertj:assertj-core' + testRuntime project(':spring-restdocs-asciidoctor-support') +} \ No newline at end of file diff --git a/spring-restdocs-asciidoctor-2.0/src/main/java/org/springframework/restdocs/asciidoctor/DefaultAttributesAsciidoctorJ20Preprocessor.java b/spring-restdocs-asciidoctor-2.0/src/main/java/org/springframework/restdocs/asciidoctor/DefaultAttributesAsciidoctorJ20Preprocessor.java new file mode 100644 index 000000000..054fd9d85 --- /dev/null +++ b/spring-restdocs-asciidoctor-2.0/src/main/java/org/springframework/restdocs/asciidoctor/DefaultAttributesAsciidoctorJ20Preprocessor.java @@ -0,0 +1,39 @@ +/* + * Copyright 2014-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 + * + * https://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.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 DefaultAttributesAsciidoctorJ20Preprocessor extends Preprocessor { + + private final SnippetsDirectoryResolver snippetsDirectoryResolver = new SnippetsDirectoryResolver(); + + @Override + public void process(Document document, PreprocessorReader reader) { + document.setAttribute("snippets", this.snippetsDirectoryResolver + .getSnippetsDirectory(document.getAttributes()), false); + } + +} diff --git a/spring-restdocs-asciidoctor/src/main/java/org/springframework/restdocs/asciidoctor/RestDocsExtensionRegistry.java b/spring-restdocs-asciidoctor-2.0/src/main/java/org/springframework/restdocs/asciidoctor/RestDocsAsciidoctorJ20ExtensionRegistry.java similarity index 70% rename from spring-restdocs-asciidoctor/src/main/java/org/springframework/restdocs/asciidoctor/RestDocsExtensionRegistry.java rename to spring-restdocs-asciidoctor-2.0/src/main/java/org/springframework/restdocs/asciidoctor/RestDocsAsciidoctorJ20ExtensionRegistry.java index 4872c27ba..5fd651f31 100644 --- a/spring-restdocs-asciidoctor/src/main/java/org/springframework/restdocs/asciidoctor/RestDocsExtensionRegistry.java +++ b/spring-restdocs-asciidoctor-2.0/src/main/java/org/springframework/restdocs/asciidoctor/RestDocsAsciidoctorJ20ExtensionRegistry.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2016 the original author or authors. + * Copyright 2014-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. @@ -17,24 +17,23 @@ package org.springframework.restdocs.asciidoctor; import org.asciidoctor.Asciidoctor; -import org.asciidoctor.extension.spi.ExtensionRegistry; +import org.asciidoctor.jruby.extension.spi.ExtensionRegistry; /** - * Asciidoctor {@link ExtensionRegistry} for Spring REST Docs. + * AsciidoctorJ 2.0 {@link ExtensionRegistry} for Spring REST Docs. * * @author Andy Wilkinson */ -public final class RestDocsExtensionRegistry implements ExtensionRegistry { +public final class RestDocsAsciidoctorJ20ExtensionRegistry implements ExtensionRegistry { @Override public void register(Asciidoctor asciidoctor) { asciidoctor.javaExtensionRegistry() - .preprocessor(new DefaultAttributesPreprocessor()); + .preprocessor(new DefaultAttributesAsciidoctorJ20Preprocessor()); asciidoctor.rubyExtensionRegistry() - .loadClass(RestDocsExtensionRegistry.class + .loadClass(RestDocsAsciidoctorJ20ExtensionRegistry.class .getResourceAsStream("/extensions/operation_block_macro.rb")) .blockMacro("operation", "OperationBlockMacro"); - } } diff --git a/spring-restdocs-asciidoctor-2.0/src/test/java/org/springframework/restdocs/asciidoctor/DefaultAttributesAsciidoctorJ20PreprocessorTests.java b/spring-restdocs-asciidoctor-2.0/src/test/java/org/springframework/restdocs/asciidoctor/DefaultAttributesAsciidoctorJ20PreprocessorTests.java new file mode 100644 index 000000000..7c4cbfd78 --- /dev/null +++ b/spring-restdocs-asciidoctor-2.0/src/test/java/org/springframework/restdocs/asciidoctor/DefaultAttributesAsciidoctorJ20PreprocessorTests.java @@ -0,0 +1,70 @@ +/* + * Copyright 2014-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 + * + * https://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.Asciidoctor; +import org.asciidoctor.Attributes; +import org.asciidoctor.Options; +import org.junit.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link DefaultAttributesAsciidoctorJ20Preprocessor}. + * + * @author Andy Wilkinson + */ +public class DefaultAttributesAsciidoctorJ20PreprocessorTests { + + @Test + public void snippetsAttributeIsSet() { + String converted = createAsciidoctor().convert("{snippets}", + createOptions("projectdir=../../..")); + assertThat(converted) + .contains("build" + File.separatorChar + "generated-snippets"); + } + + @Test + public void snippetsAttributeFromConvertArgumentIsNotOverridden() { + String converted = createAsciidoctor().convert("{snippets}", + createOptions("snippets=custom projectdir=../../..")); + assertThat(converted).contains("custom"); + } + + @Test + public void snippetsAttributeFromDocumentPreambleIsNotOverridden() { + String converted = createAsciidoctor().convert(":snippets: custom\n{snippets}", + createOptions("projectdir=../../..")); + assertThat(converted).contains("custom"); + } + + private Options createOptions(String attributes) { + Options options = new Options(); + options.setAttributes(new Attributes(attributes)); + return options; + } + + private Asciidoctor createAsciidoctor() { + Asciidoctor asciidoctor = Asciidoctor.Factory.create(); + asciidoctor.javaExtensionRegistry() + .preprocessor(new DefaultAttributesAsciidoctorJ20Preprocessor()); + return asciidoctor; + } + +} diff --git a/spring-restdocs-asciidoctor-support/build.gradle b/spring-restdocs-asciidoctor-support/build.gradle new file mode 100644 index 000000000..5274e8750 --- /dev/null +++ b/spring-restdocs-asciidoctor-support/build.gradle @@ -0,0 +1,6 @@ +description = 'Support code for AsciidoctorJ extensions for Spring REST Docs' + +dependencies { + testCompile 'junit:junit' + testCompile 'org.assertj:assertj-core' +} \ No newline at end of file diff --git a/spring-restdocs-asciidoctor/src/main/java/org/springframework/restdocs/asciidoctor/SnippetsDirectoryResolver.java b/spring-restdocs-asciidoctor-support/src/main/java/org/springframework/restdocs/asciidoctor/SnippetsDirectoryResolver.java similarity index 97% rename from spring-restdocs-asciidoctor/src/main/java/org/springframework/restdocs/asciidoctor/SnippetsDirectoryResolver.java rename to spring-restdocs-asciidoctor-support/src/main/java/org/springframework/restdocs/asciidoctor/SnippetsDirectoryResolver.java index 4889c51b5..622853d13 100644 --- a/spring-restdocs-asciidoctor/src/main/java/org/springframework/restdocs/asciidoctor/SnippetsDirectoryResolver.java +++ b/spring-restdocs-asciidoctor-support/src/main/java/org/springframework/restdocs/asciidoctor/SnippetsDirectoryResolver.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2016 the original author or authors. + * Copyright 2014-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. diff --git a/spring-restdocs-asciidoctor/src/main/resources/extensions/operation_block_macro.rb b/spring-restdocs-asciidoctor-support/src/main/resources/extensions/operation_block_macro.rb similarity index 100% rename from spring-restdocs-asciidoctor/src/main/resources/extensions/operation_block_macro.rb rename to spring-restdocs-asciidoctor-support/src/main/resources/extensions/operation_block_macro.rb diff --git a/spring-restdocs-asciidoctor/src/test/java/org/springframework/restdocs/asciidoctor/SnippetsDirectoryResolverTests.java b/spring-restdocs-asciidoctor-support/src/test/java/org/springframework/restdocs/asciidoctor/SnippetsDirectoryResolverTests.java similarity index 98% rename from spring-restdocs-asciidoctor/src/test/java/org/springframework/restdocs/asciidoctor/SnippetsDirectoryResolverTests.java rename to spring-restdocs-asciidoctor-support/src/test/java/org/springframework/restdocs/asciidoctor/SnippetsDirectoryResolverTests.java index c17f6e8e3..04d0aaab4 100644 --- a/spring-restdocs-asciidoctor/src/test/java/org/springframework/restdocs/asciidoctor/SnippetsDirectoryResolverTests.java +++ b/spring-restdocs-asciidoctor-support/src/test/java/org/springframework/restdocs/asciidoctor/SnippetsDirectoryResolverTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-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. diff --git a/spring-restdocs-asciidoctor/build.gradle b/spring-restdocs-asciidoctor/build.gradle index dcb58c2fe..ac464080b 100644 --- a/spring-restdocs-asciidoctor/build.gradle +++ b/spring-restdocs-asciidoctor/build.gradle @@ -1,11 +1,28 @@ -description = 'Asciidoctor extensions for Spring REST Docs' +configurations { + merge + testRuntime { extendsFrom merge } +} dependencies { - provided 'org.asciidoctor:asciidoctorj' - testCompile 'junit:junit' + merge project(':spring-restdocs-asciidoctor-1.5') + merge project(':spring-restdocs-asciidoctor-1.6') + merge project(':spring-restdocs-asciidoctor-2.0') testCompile 'org.apache.pdfbox:pdfbox' - testCompile 'org.asciidoctor:asciidoctorj' + testCompile 'org.asciidoctor:asciidoctorj:1.5.8.1' testCompile 'org.assertj:assertj-core' + testCompile 'junit:junit' testCompile 'org.springframework:spring-core' testRuntime 'org.asciidoctor:asciidoctorj-pdf' +} + +jar { + from configurations.merge.collect { file -> zipTree(file) } +} + +matrixTest { + asciidoctorj { + group = 'org.asciidoctor' + artifact = 'asciidoctorj' + versions = [ asciidoctorj16Version, asciidoctorj20Version ] + } } \ No newline at end of file diff --git a/spring-restdocs-asciidoctor/src/main/java/org/springframework/restdocs/asciidoctor/package-info.java b/spring-restdocs-asciidoctor/src/main/java/org/springframework/restdocs/asciidoctor/package-info.java deleted file mode 100644 index 8b586e736..000000000 --- a/spring-restdocs-asciidoctor/src/main/java/org/springframework/restdocs/asciidoctor/package-info.java +++ /dev/null @@ -1,20 +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 - * - * https://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. - */ - -/** - * Spring REST Docs Asciidoctor extensions. - */ -package org.springframework.restdocs.asciidoctor; 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 index 7c790a308..ccdd8d45c 100644 --- 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 @@ -1 +1,2 @@ -org.springframework.restdocs.asciidoctor.RestDocsExtensionRegistry \ No newline at end of file +org.springframework.restdocs.asciidoctor.RestDocsAsciidoctorJ15ExtensionRegistry +org.springframework.restdocs.asciidoctor.RestDocsAsciidoctorJ16ExtensionRegistry diff --git a/spring-restdocs-asciidoctor/src/main/resources/META-INF/services/org.asciidoctor.jruby.extension.spi.ExtensionRegistry b/spring-restdocs-asciidoctor/src/main/resources/META-INF/services/org.asciidoctor.jruby.extension.spi.ExtensionRegistry new file mode 100644 index 000000000..7ae7da385 --- /dev/null +++ b/spring-restdocs-asciidoctor/src/main/resources/META-INF/services/org.asciidoctor.jruby.extension.spi.ExtensionRegistry @@ -0,0 +1 @@ +org.springframework.restdocs.asciidoctor.RestDocsAsciidoctorJ20ExtensionRegistry From 136df15fadffe1137c510f0dde15ae618b562b5e Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Tue, 18 Jun 2019 12:51:34 +0100 Subject: [PATCH 045/502] Ensure that jars to be merged are built before merging them See gh-581 --- spring-restdocs-asciidoctor/build.gradle | 3 +++ 1 file changed, 3 insertions(+) diff --git a/spring-restdocs-asciidoctor/build.gradle b/spring-restdocs-asciidoctor/build.gradle index ac464080b..c7fab6756 100644 --- a/spring-restdocs-asciidoctor/build.gradle +++ b/spring-restdocs-asciidoctor/build.gradle @@ -16,6 +16,9 @@ dependencies { } jar { + dependsOn ':spring-restdocs-asciidoctor-1.5:jar' + dependsOn ':spring-restdocs-asciidoctor-1.6:jar' + dependsOn ':spring-restdocs-asciidoctor-2.0:jar' from configurations.merge.collect { file -> zipTree(file) } } From 9c221bfb3ccf8fd09275a70817b532a22496dfc2 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Tue, 18 Jun 2019 12:55:21 +0100 Subject: [PATCH 046/502] Polish --- spring-restdocs-asciidoctor-2.0/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-restdocs-asciidoctor-2.0/build.gradle b/spring-restdocs-asciidoctor-2.0/build.gradle index 48e8d5cfe..9ac719ef9 100644 --- a/spring-restdocs-asciidoctor-2.0/build.gradle +++ b/spring-restdocs-asciidoctor-2.0/build.gradle @@ -4,7 +4,7 @@ dependencies { compileOnly "org.asciidoctor:asciidoctorj:$asciidoctorj20Version" implementation project(':spring-restdocs-asciidoctor-support') testCompile 'junit:junit' - testCompile "org.asciidoctor:asciidoctorj:$asciidoctorj15Version" + testCompile "org.asciidoctor:asciidoctorj:$asciidoctorj20Version" testCompile 'org.assertj:assertj-core' testRuntime project(':spring-restdocs-asciidoctor-support') } \ No newline at end of file From 3fa64a1b2c2ed01ba8da8b1c5da77566765e8712 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Tue, 18 Jun 2019 12:57:40 +0100 Subject: [PATCH 047/502] Upgrade to AsciidoctorJ PDF 1.5.0-alpha.18 Closes gh-622 --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 37b25620e..63cb78099 100644 --- a/build.gradle +++ b/build.gradle @@ -83,7 +83,7 @@ subprojects { dependency 'org.apache.pdfbox:pdfbox:2.0.7' dependency 'org.assertj:assertj-core:2.9.1' dependency 'org.asciidoctor:asciidoctorj:1.5.8.1' - dependency 'org.asciidoctor:asciidoctorj-pdf:1.5.0-alpha.16' + dependency 'org.asciidoctor:asciidoctorj-pdf:1.5.0-alpha.18' dependency 'org.hamcrest:hamcrest-core:1.3' dependency 'org.hamcrest:hamcrest-library:1.3' dependency 'org.hibernate:hibernate-validator:5.2.5.Final' From f7bd5faecfcb5840c8dfe16efe12a07e58681c37 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Tue, 18 Jun 2019 13:37:00 +0100 Subject: [PATCH 048/502] Remove Spring IO plugin from the build Closes gh-623 --- build.gradle | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/build.gradle b/build.gradle index 63cb78099..46857e0f0 100644 --- a/build.gradle +++ b/build.gradle @@ -7,8 +7,8 @@ buildscript { } dependencies { classpath 'org.springframework.build.gradle:propdeps-plugin:0.0.7' - classpath 'io.spring.gradle:spring-io-plugin:0.0.8.RELEASE' classpath 'org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:2.6.2' + classpath 'io.spring.gradle:dependency-management-plugin:1.0.8.RELEASE' classpath "io.spring.javaformat:spring-javaformat-gradle-plugin:$javaFormatVersion" classpath 'io.spring.nohttp:nohttp-gradle:0.0.2.RELEASE' } @@ -124,22 +124,6 @@ configure(subprojects - project(":docs")) { subproject -> apply plugin: 'checkstyle' apply from: "${rootProject.projectDir}/gradle/publish-maven.gradle" - if (project.hasProperty('platformVersion') && subproject.path != ':spring-restdocs-asciidoctor') { - apply plugin: 'spring-io' - - repositories { - maven { url "https://repo.spring.io/libs-snapshot" } - } - - dependencyManagement { - springIoTestRuntime { - imports { - mavenBom "io.spring.platform:platform-bom:${platformVersion}" - } - } - } - } - checkstyle { configFile = rootProject.file('config/checkstyle/checkstyle.xml') configProperties = [ 'checkstyle.config.dir' : rootProject.file('config/checkstyle') ] From 3dabf8e53f2d6ae753bea758a93cc1ebf91ea822 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Tue, 18 Jun 2019 14:09:05 +0100 Subject: [PATCH 049/502] Reinstate javadoc and sources jars for spring-restdocs-asciidoctor See gh-581 --- build.gradle | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index 74daeeba4..e795c475d 100644 --- a/build.gradle +++ b/build.gradle @@ -144,7 +144,7 @@ configure(codeProjects) { } } -def publishedCodeProjects = codeProjects.findAll { codeProject -> !codeProject.name.contains('spring-restdocs-asciidoctor')} +def publishedCodeProjects = codeProjects.findAll { codeProject -> !codeProject.name.contains('spring-restdocs-asciidoctor-')} configure(publishedCodeProjects) { subproject -> javadoc { description = "Generates project-level javadoc for use in -javadoc jar" @@ -230,7 +230,8 @@ task api (type: Javadoc) { options.links = javadocLinks options.addStringOption '-quiet' - source publishedCodeProjects.collect { project -> project.sourceSets.main.allJava } + source publishedCodeProjects.findAll { !it.name == 'spring-restdocs-asciidoctor' } + .collect { it.sourceSets.main.allJava } destinationDir = new File(buildDir, "api") From 619847582a1c69b7db92b3791d43268f981fb805 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Thu, 20 Jun 2019 10:15:03 +0100 Subject: [PATCH 050/502] Reuse document's attributes when loading snippet content Previously, when adding blocks for the snippets' content, the operation macro would call Asciidoctor to load the content with attributes that only included the projectdir. This resulted in a failure in environments that did not set the projectdir and instead relied on another attribute, such as gradle-projectdir as used by the latest versions of the Asciidoctor Gradle plugin. This commit updates the macro to reuse all of the main document's attributes when loading the snippets' content, thereby ensuring that any attributes available in the main document are also available during snipppet processing. Closes gh-624 --- .../extensions/operation_block_macro.rb | 3 +- ... => AbstractOperationBlockMacroTests.java} | 45 +++++++----- .../GradleOperationBlockMacroTests.java | 69 ++++++++++++++++++ .../MavenOperationBlockMacroTests.java | 73 +++++++++++++++++++ 4 files changed, 170 insertions(+), 20 deletions(-) rename spring-restdocs-asciidoctor/src/test/java/org/springframework/restdocs/asciidoctor/{OperationBlockMacroTests.java => AbstractOperationBlockMacroTests.java} (89%) create mode 100644 spring-restdocs-asciidoctor/src/test/java/org/springframework/restdocs/asciidoctor/GradleOperationBlockMacroTests.java create mode 100644 spring-restdocs-asciidoctor/src/test/java/org/springframework/restdocs/asciidoctor/MavenOperationBlockMacroTests.java diff --git a/spring-restdocs-asciidoctor-support/src/main/resources/extensions/operation_block_macro.rb b/spring-restdocs-asciidoctor-support/src/main/resources/extensions/operation_block_macro.rb index 4d94c40ea..b3f3a0ddd 100644 --- a/spring-restdocs-asciidoctor-support/src/main/resources/extensions/operation_block_macro.rb +++ b/spring-restdocs-asciidoctor-support/src/main/resources/extensions/operation_block_macro.rb @@ -47,8 +47,7 @@ def do_read_snippets(snippets, parent, operation, snippet_titles) end def add_blocks(content, doc, parent) - options = { safe: doc.options[:safe], - attributes: { 'projectdir' => doc.attr(:projectdir) } } + options = { safe: doc.options[:safe], attributes: doc.attributes } fragment = Asciidoctor.load content, options fragment.blocks.each do |b| b.parent = parent diff --git a/spring-restdocs-asciidoctor/src/test/java/org/springframework/restdocs/asciidoctor/OperationBlockMacroTests.java b/spring-restdocs-asciidoctor/src/test/java/org/springframework/restdocs/asciidoctor/AbstractOperationBlockMacroTests.java similarity index 89% rename from spring-restdocs-asciidoctor/src/test/java/org/springframework/restdocs/asciidoctor/OperationBlockMacroTests.java rename to spring-restdocs-asciidoctor/src/test/java/org/springframework/restdocs/asciidoctor/AbstractOperationBlockMacroTests.java index 2d72b9242..96be6cffd 100644 --- a/spring-restdocs-asciidoctor/src/test/java/org/springframework/restdocs/asciidoctor/OperationBlockMacroTests.java +++ b/spring-restdocs-asciidoctor/src/test/java/org/springframework/restdocs/asciidoctor/AbstractOperationBlockMacroTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-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. @@ -33,39 +33,48 @@ import org.asciidoctor.Asciidoctor; import org.asciidoctor.Attributes; import org.asciidoctor.Options; +import org.asciidoctor.OptionsBuilder; +import org.asciidoctor.SafeMode; import org.junit.Before; -import org.junit.BeforeClass; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.TemporaryFolder; import org.springframework.util.FileSystemUtils; import static org.assertj.core.api.Assertions.assertThat; /** - * Tests for Ruby operation block macro. + * Base class for tests for the Ruby operation block macro. * * @author Gerrit Meier * @author Andy Wilkinson */ -public class OperationBlockMacroTests { +public abstract class AbstractOperationBlockMacroTests { - private final Options options = new Options(); + @Rule + public TemporaryFolder temp = new TemporaryFolder(); + + private Options options; private final Asciidoctor asciidoctor = Asciidoctor.Factory.create(); - @BeforeClass - public static void prepareOperationSnippets() throws IOException { - File destination = new File("build/generated-snippets/some-operation"); + @Before + public void setUp() throws IOException { + prepareOperationSnippets(getBuildOutputLocation()); + this.options = OptionsBuilder.options().safe(SafeMode.UNSAFE) + .baseDir(getSourceLocation()).get(); + this.options.setAttributes(getAttributes()); + } + + public void prepareOperationSnippets(File buildOutputLocation) throws IOException { + File destination = new File(buildOutputLocation, + "generated-snippets/some-operation"); destination.mkdirs(); FileSystemUtils.copyRecursively(new File("src/test/resources/some-operation"), destination); } - @Before - public void setUp() { - this.options.setAttributes(getAttributes()); - } - @Test public void codeBlockSnippetInclude() throws Exception { String result = this.asciidoctor.convert( @@ -208,11 +217,11 @@ private boolean isWindows() { return File.separatorChar == '\\'; } - private Attributes getAttributes() { - Attributes attributes = new Attributes(); - attributes.setAttribute("projectdir", new File(".").getAbsolutePath()); - return attributes; - } + protected abstract Attributes getAttributes(); + + protected abstract File getBuildOutputLocation(); + + protected abstract File getSourceLocation(); private File configurePdfOutput() { this.options.setBackend("pdf"); diff --git a/spring-restdocs-asciidoctor/src/test/java/org/springframework/restdocs/asciidoctor/GradleOperationBlockMacroTests.java b/spring-restdocs-asciidoctor/src/test/java/org/springframework/restdocs/asciidoctor/GradleOperationBlockMacroTests.java new file mode 100644 index 000000000..3287b44c0 --- /dev/null +++ b/spring-restdocs-asciidoctor/src/test/java/org/springframework/restdocs/asciidoctor/GradleOperationBlockMacroTests.java @@ -0,0 +1,69 @@ +/* + * Copyright 2014-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 + * + * https://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.Attributes; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameters; + +/** + * Tests for Ruby operation block macro when used in a Gradle build. + * + * @author Andy Wilkinson + */ +@RunWith(Parameterized.class) +public class GradleOperationBlockMacroTests extends AbstractOperationBlockMacroTests { + + private final String attributeName; + + public GradleOperationBlockMacroTests(String attributeName) { + this.attributeName = attributeName; + } + + @Parameters(name = "{0}") + public static Object[] parameters() { + return new Object[] { "projectdir", "gradle-projectdir" }; + } + + protected Attributes getAttributes() { + Attributes attributes = new Attributes(); + attributes.setAttribute(this.attributeName, + new File(temp.getRoot(), "gradle-project").getAbsolutePath()); + return attributes; + } + + @Override + protected File getBuildOutputLocation() { + File outputLocation = new File(temp.getRoot(), "gradle-project/build"); + outputLocation.mkdirs(); + return outputLocation; + } + + @Override + protected File getSourceLocation() { + File sourceLocation = new File(temp.getRoot(), + "gradle-project/src/docs/asciidoc"); + if (!sourceLocation.exists()) { + sourceLocation.mkdirs(); + } + return sourceLocation; + } + +} diff --git a/spring-restdocs-asciidoctor/src/test/java/org/springframework/restdocs/asciidoctor/MavenOperationBlockMacroTests.java b/spring-restdocs-asciidoctor/src/test/java/org/springframework/restdocs/asciidoctor/MavenOperationBlockMacroTests.java new file mode 100644 index 000000000..ad711d7d5 --- /dev/null +++ b/spring-restdocs-asciidoctor/src/test/java/org/springframework/restdocs/asciidoctor/MavenOperationBlockMacroTests.java @@ -0,0 +1,73 @@ +/* + * Copyright 2014-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 + * + * https://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 org.asciidoctor.Attributes; +import org.junit.After; +import org.junit.Before; + +/** + * Tests for Ruby operation block macro when used in a Maven build. + * + * @author Andy Wilkinson + */ +public class MavenOperationBlockMacroTests extends AbstractOperationBlockMacroTests { + + @Before + public void setMavenHome() { + System.setProperty("maven.home", "maven-home"); + } + + @After + public void clearMavenHome() { + System.clearProperty("maven.home"); + } + + protected Attributes getAttributes() { + try { + File sourceLocation = getSourceLocation(); + new File(sourceLocation.getParentFile().getParentFile().getParentFile(), + "pom.xml").createNewFile(); + Attributes attributes = new Attributes(); + attributes.setAttribute("docdir", sourceLocation.getAbsolutePath()); + return attributes; + } + catch (IOException ex) { + throw new RuntimeException(ex); + } + } + + @Override + protected File getBuildOutputLocation() { + File outputLocation = new File(temp.getRoot(), "maven-project/target"); + outputLocation.mkdirs(); + return outputLocation; + } + + @Override + protected File getSourceLocation() { + File sourceLocation = new File(temp.getRoot(), "maven-project/src/main/asciidoc"); + if (!sourceLocation.exists()) { + sourceLocation.mkdirs(); + } + return sourceLocation; + } + +} From 4a084b52d06f149c62317985e302eeaed7487c35 Mon Sep 17 00:00:00 2001 From: Alexander Schwartz Date: Fri, 2 Aug 2019 21:03:40 +0200 Subject: [PATCH 051/502] Fix IDs of sections in examples See gh-629 --- .../src/main/asciidoc/getting-started-guide.adoc | 16 ++++++++-------- .../src/docs/asciidoc/getting-started-guide.adoc | 16 ++++++++-------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/samples/rest-notes-spring-data-rest/src/main/asciidoc/getting-started-guide.adoc b/samples/rest-notes-spring-data-rest/src/main/asciidoc/getting-started-guide.adoc index 78a442369..fbd4793b7 100644 --- a/samples/rest-notes-spring-data-rest/src/main/asciidoc/getting-started-guide.adoc +++ b/samples/rest-notes-spring-data-rest/src/main/asciidoc/getting-started-guide.adoc @@ -7,18 +7,18 @@ Andy Wilkinson; :toclevels: 4 :sectlinks: -[introduction] +[[introduction]] = Introduction RESTful Notes is a RESTful web service for creating and storing notes. It uses hypermedia to describe the relationships between resources and to allow navigation between them. -[getting-started] +[[getting-started]] = Getting started -[getting-started-running-the-service] +[[getting-started-running-the-service]] == Running the service RESTful Notes is written using https://projects.spring.io/spring-boot[Spring Boot] which makes it easy to get it up and running so that you can start exploring the REST API. @@ -54,7 +54,7 @@ Note the `_links` in the JSON response. They are key to navigating the API. -[getting-started-creating-a-note] +[[getting-started-creating-a-note]] == Creating a note Now that you've started the service and verified that it works, the next step is to use it to create a new note. As you saw above, the URI for working with notes is included as @@ -85,7 +85,7 @@ Note the `tags` link which we'll make use of later. -[getting-started-creating-a-tag] +[[getting-started-creating-a-tag]] == Creating a tag To make a note easier to find, it can be associated with any number of tags. To be able to tag a note, you must first create the tag. @@ -116,7 +116,7 @@ include::{snippets}/creating-a-note/4/http-response.adoc[] -[getting-started-tagging-a-note] +[[getting-started-tagging-a-note]] == Tagging a note A tag isn't particularly useful until it's been associated with one or more notes. There are two ways to tag a note: when the note is first created or by updating an existing @@ -124,7 +124,7 @@ note. We'll look at both of these in turn. -[getting-started-tagging-a-note-creating] +[[getting-started-tagging-a-note-creating]] === Creating a tagged note The process is largely the same as we saw before, but this time, in addition to providing a title and body for the note, we'll also provide the tag that we want to be associated @@ -155,7 +155,7 @@ include::{snippets}/creating-a-note/7/http-response.adoc[] -[getting-started-tagging-a-note-existing] +[[getting-started-tagging-a-note-existing]] === Tagging an existing note An existing note can be tagged by executing a `PATCH` request against the note's URI with a body that contains the array of tags to be associated with the note. We'll used the diff --git a/samples/rest-notes-spring-hateoas/src/docs/asciidoc/getting-started-guide.adoc b/samples/rest-notes-spring-hateoas/src/docs/asciidoc/getting-started-guide.adoc index c951418c2..b07a9ffd9 100644 --- a/samples/rest-notes-spring-hateoas/src/docs/asciidoc/getting-started-guide.adoc +++ b/samples/rest-notes-spring-hateoas/src/docs/asciidoc/getting-started-guide.adoc @@ -7,18 +7,18 @@ Andy Wilkinson; :toclevels: 4 :sectlinks: -[introduction] +[[introduction]] = Introduction RESTful Notes is a RESTful web service for creating and storing notes. It uses hypermedia to describe the relationships between resources and to allow navigation between them. -[getting-started] +[[getting-started]] = Getting started -[getting-started-running-the-service] +[[getting-started-running-the-service]] == Running the service RESTful Notes is written using https://projects.spring.io/spring-boot[Spring Boot] which makes it easy to get it up and running so that you can start exploring the REST API. @@ -52,7 +52,7 @@ Note the `_links` in the JSON response. They are key to navigating the API. -[getting-started-creating-a-note] +[[getting-started-creating-a-note]] == Creating a note Now that you've started the service and verified that it works, the next step is to use it to create a new note. As you saw above, the URI for working with notes is included as @@ -83,7 +83,7 @@ Note the `note-tags` link which we'll make use of later. -[getting-started-creating-a-tag] +[[getting-started-creating-a-tag]] == Creating a tag To make a note easier to find, it can be associated with any number of tags. To be able to tag a note, you must first create the tag. @@ -114,7 +114,7 @@ include::{snippets}/creating-a-note/4/http-response.adoc[] -[getting-started-tagging-a-note] +[[getting-started-tagging-a-note]] == Tagging a note A tag isn't particularly useful until it's been associated with one or more notes. There are two ways to tag a note: when the note is first created or by updating an existing @@ -122,7 +122,7 @@ note. We'll look at both of these in turn. -[getting-started-tagging-a-note-creating] +[[getting-started-tagging-a-note-creating]] === Creating a tagged note The process is largely the same as we saw before, but this time, in addition to providing a title and body for the note, we'll also provide the tag that we want to be associated @@ -153,7 +153,7 @@ include::{snippets}/creating-a-note/7/http-response.adoc[] -[getting-started-tagging-a-note-existing] +[[getting-started-tagging-a-note-existing]] === Tagging an existing note An existing note can be tagged by executing a `PATCH` request against the note's URI with a body that contains the array of tags to be associated with the note. We'll use the From 508b3d65932ec40231d3ea211f441ac5549ccc90 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Fri, 30 Aug 2019 11:07:04 +0100 Subject: [PATCH 052/502] Upgrade to Spring Java Format 0.0.15 --- build.gradle | 4 +- gradle.properties | 2 +- .../DefaultAttributesPreprocessor.java | 6 +- .../RestDocsExtensionRegistry.java | 8 +- .../SnippetsDirectoryResolver.java | 8 +- .../DefaultAttributesPreprocessorTests.java | 8 +- .../asciidoctor/OperationBlockMacroTests.java | 91 ++-- .../SnippetsDirectoryResolverTests.java | 33 +- .../restdocs/JUnitRestDocumentation.java | 5 +- .../restdocs/ManualRestDocumentation.java | 8 +- .../restdocs/RestDocumentationContext.java | 5 +- .../restdocs/cli/CliDocumentation.java | 8 +- .../restdocs/cli/CliOperationRequest.java | 26 +- .../restdocs/cli/CurlRequestSnippet.java | 26 +- .../restdocs/cli/HttpieRequestSnippet.java | 38 +- .../restdocs/cli/QueryStringParser.java | 5 +- .../restdocs/config/AbstractConfigurer.java | 5 +- .../config/AbstractNestedConfigurer.java | 5 +- .../config/RestDocumentationConfigurer.java | 30 +- .../restdocs/config/SnippetConfigurer.java | 19 +- .../constraints/ConstraintDescriptions.java | 14 +- ...ceBundleConstraintDescriptionResolver.java | 14 +- .../ValidatorConstraintResolver.java | 11 +- .../restdocs/curl/CurlRequestSnippet.java | 5 +- .../generate/RestDocumentationGenerator.java | 53 +-- .../headers/AbstractHeadersSnippet.java | 18 +- .../restdocs/headers/HeaderDocumentation.java | 11 +- .../headers/RequestHeadersSnippet.java | 8 +- .../headers/ResponseHeadersSnippet.java | 11 +- .../restdocs/http/HttpRequestSnippet.java | 31 +- .../hypermedia/AbstractJsonLinkExtractor.java | 8 +- .../hypermedia/AtomLinkExtractor.java | 5 +- .../hypermedia/ContentTypeLinkExtractor.java | 8 +- .../hypermedia/HypermediaDocumentation.java | 45 +- .../restdocs/hypermedia/Link.java | 6 +- .../restdocs/hypermedia/LinksSnippet.java | 31 +- .../operation/AbstractOperationMessage.java | 10 +- .../restdocs/operation/OperationMessage.java | 34 ++ .../operation/OperationRequestFactory.java | 53 +-- .../OperationRequestPartFactory.java | 8 +- .../operation/OperationResponseFactory.java | 27 +- .../restdocs/operation/Parameters.java | 9 +- .../restdocs/operation/QueryStringParser.java | 8 +- .../restdocs/operation/StandardOperation.java | 6 +- .../operation/StandardOperationRequest.java | 8 +- .../StandardOperationRequestPart.java | 8 +- .../operation/StandardOperationResponse.java | 5 +- .../HeaderRemovingOperationPreprocessor.java | 8 +- .../LinkMaskingContentModifier.java | 5 +- ...ametersModifyingOperationPreprocessor.java | 5 +- .../operation/preprocess/Preprocessors.java | 32 +- .../PrettyPrintingContentModifier.java | 33 +- .../restdocs/payload/AbstractBodySnippet.java | 18 +- .../payload/AbstractFieldsSnippet.java | 71 ++-- .../FieldPathPayloadSubsectionExtractor.java | 9 +- .../FieldTypesDoNotMatchException.java | 6 +- .../restdocs/payload/JsonContentHandler.java | 36 +- .../restdocs/payload/JsonFieldPath.java | 14 +- .../restdocs/payload/JsonFieldProcessor.java | 96 ++--- .../payload/JsonFieldTypeResolver.java | 5 +- .../payload/PayloadDocumentation.java | 203 ++++----- .../restdocs/payload/RequestBodySnippet.java | 5 +- .../payload/RequestFieldsSnippet.java | 52 +-- .../payload/RequestPartBodySnippet.java | 14 +- .../payload/RequestPartFieldsSnippet.java | 49 +-- .../restdocs/payload/ResponseBodySnippet.java | 5 +- .../payload/ResponseFieldsSnippet.java | 42 +- .../restdocs/payload/XmlContentHandler.java | 27 +- .../request/AbstractParametersSnippet.java | 32 +- .../request/PathParametersSnippet.java | 28 +- .../request/RequestDocumentation.java | 57 ++- .../request/RequestParametersSnippet.java | 24 +- .../restdocs/request/RequestPartsSnippet.java | 46 +-- .../restdocs/snippet/IgnorableDescriptor.java | 5 +- ...cumentationContextPlaceholderResolver.java | 5 +- ...tionContextPlaceholderResolverFactory.java | 5 +- .../snippet/StandardWriterResolver.java | 37 +- .../restdocs/snippet/TemplatedSnippet.java | 18 +- .../restdocs/snippet/WriterResolver.java | 6 +- .../StandardTemplateResourceResolver.java | 16 +- .../templates/mustache/MustacheTemplate.java | 5 +- .../mustache/MustacheTemplateEngine.java | 16 +- .../restdocs/AbstractSnippetTests.java | 12 +- .../RestDocumentationGeneratorTests.java | 83 ++-- .../ConcatenatingCommandFormatterTests.java | 8 +- .../restdocs/cli/CurlRequestSnippetTests.java | 324 +++++++-------- .../cli/HttpieRequestSnippetTests.java | 313 ++++++-------- .../RestDocumentationConfigurerTests.java | 112 ++--- .../ConstraintDescriptionsTests.java | 25 +- ...dleConstraintDescriptionResolverTests.java | 74 ++-- .../ValidatorConstraintResolverTests.java | 25 +- .../RequestHeadersSnippetFailureTests.java | 26 +- .../headers/RequestHeadersSnippetTests.java | 126 ++---- .../ResponseHeadersSnippetFailureTests.java | 26 +- .../headers/ResponseHeadersSnippetTests.java | 110 ++--- .../http/HttpRequestSnippetTests.java | 322 ++++++--------- .../http/HttpResponseSnippetTests.java | 42 +- .../ContentTypeLinkExtractorTests.java | 12 +- .../LinkExtractorsPayloadTests.java | 25 +- .../hypermedia/LinksSnippetFailureTests.java | 34 +- .../hypermedia/LinksSnippetTests.java | 107 ++--- .../hypermedia/StubLinkExtractor.java | 5 +- .../operation/QueryStringParserTests.java | 20 +- ...ntModifyingOperationPreprocessorTests.java | 17 +- ...tingOperationRequestPreprocessorTests.java | 11 +- ...ingOperationResponsePreprocessorTests.java | 14 +- ...derRemovingOperationPreprocessorTests.java | 17 +- .../LinkMaskingContentModifierTests.java | 45 +- ...rsModifyingOperationPreprocessorTests.java | 51 +-- .../PatternReplacingContentModifierTests.java | 26 +- .../PrettyPrintingContentModifierTests.java | 29 +- .../AsciidoctorRequestFieldsSnippetTests.java | 35 +- ...ldPathPayloadSubsectionExtractorTests.java | 68 ++- .../payload/JsonContentHandlerTests.java | 96 ++--- .../restdocs/payload/JsonFieldPathTests.java | 35 +- .../restdocs/payload/JsonFieldPathsTests.java | 44 +- .../payload/JsonFieldProcessorTests.java | 89 ++-- .../payload/JsonFieldTypeResolverTests.java | 112 ++--- .../payload/PayloadDocumentationTests.java | 11 +- .../payload/RequestBodyPartSnippetTests.java | 24 +- .../payload/RequestBodySnippetTests.java | 22 +- .../RequestFieldsSnippetFailureTests.java | 151 +++---- .../payload/RequestFieldsSnippetTests.java | 334 ++++++--------- .../RequestPartFieldsSnippetFailureTests.java | 32 +- .../RequestPartFieldsSnippetTests.java | 81 ++-- .../payload/ResponseBodySnippetTests.java | 18 +- .../ResponseFieldsSnippetFailureTests.java | 136 +++--- .../payload/ResponseFieldsSnippetTests.java | 387 +++++++----------- .../payload/XmlContentHandlerTests.java | 24 +- .../PathParametersSnippetFailureTests.java | 34 +- .../request/PathParametersSnippetTests.java | 152 +++---- .../RequestParametersSnippetFailureTests.java | 35 +- .../RequestParametersSnippetTests.java | 126 +++--- .../RequestPartsSnippetFailureTests.java | 24 +- .../request/RequestPartsSnippetTests.java | 125 +++--- ...tationContextPlaceholderResolverTests.java | 15 +- .../snippet/StandardWriterResolverTests.java | 39 +- .../snippet/TemplatedSnippetTests.java | 20 +- ...StandardTemplateResourceResolverTests.java | 80 ++-- .../restdocs/test/GeneratedSnippets.java | 6 +- .../restdocs/test/OperationBuilder.java | 37 +- .../restdocs/test/OperationTestRule.java | 8 +- .../restdocs/test/OutputCapture.java | 6 +- .../restdocs/test/SnippetConditions.java | 76 ++-- .../mockmvc/MockMvcRequestConverter.java | 57 +-- .../mockmvc/MockMvcResponseConverter.java | 8 +- .../mockmvc/MockMvcRestDocumentation.java | 31 +- .../MockMvcRestDocumentationConfigurer.java | 29 +- .../mockmvc/MockMvcSnippetConfigurer.java | 9 +- .../RestDocumentationRequestBuilders.java | 67 ++- .../RestDocumentationResultHandler.java | 11 +- .../restdocs/mockmvc/UriConfigurer.java | 12 +- .../mockmvc/MockMvcRequestConverterTests.java | 75 ++-- ...ckMvcRestDocumentationConfigurerTests.java | 29 +- ...kMvcRestDocumentationIntegrationTests.java | 378 +++++++---------- ...RestDocumentationRequestBuildersTests.java | 10 +- .../RestAssuredRequestConverter.java | 40 +- .../RestAssuredResponseConverter.java | 7 +- .../RestAssuredRestDocumentation.java | 29 +- ...estAssuredRestDocumentationConfigurer.java | 19 +- .../RestAssuredSnippetConfigurer.java | 9 +- .../restassured/RestDocumentationFilter.java | 24 +- .../UriModifyingOperationPreprocessor.java | 30 +- .../RestAssuredRequestConverter.java | 40 +- .../RestAssuredResponseConverter.java | 7 +- .../RestAssuredRestDocumentation.java | 29 +- ...estAssuredRestDocumentationConfigurer.java | 19 +- .../RestAssuredSnippetConfigurer.java | 9 +- .../restassured3/RestDocumentationFilter.java | 24 +- .../UriModifyingOperationPreprocessor.java | 30 +- .../RestAssuredRequestConverterTests.java | 179 +++----- ...suredRestDocumentationConfigurerTests.java | 22 +- ...uredRestDocumentationIntegrationTests.java | 285 +++++-------- .../restdocs/restassured/TomcatServer.java | 8 +- ...riModifyingOperationPreprocessorTests.java | 189 ++++----- .../RestAssuredRequestConverterTests.java | 179 +++----- ...suredRestDocumentationConfigurerTests.java | 22 +- ...uredRestDocumentationIntegrationTests.java | 278 +++++-------- .../restdocs/restassured3/TomcatServer.java | 8 +- ...riModifyingOperationPreprocessorTests.java | 189 ++++----- 180 files changed, 3337 insertions(+), 5407 deletions(-) create mode 100644 spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/OperationMessage.java diff --git a/build.gradle b/build.gradle index 46857e0f0..7829bf5da 100644 --- a/build.gradle +++ b/build.gradle @@ -127,7 +127,7 @@ configure(subprojects - project(":docs")) { subproject -> checkstyle { configFile = rootProject.file('config/checkstyle/checkstyle.xml') configProperties = [ 'checkstyle.config.dir' : rootProject.file('config/checkstyle') ] - toolVersion = '6.10.1' + toolVersion = '8.22' } configurations { @@ -254,4 +254,4 @@ configurations { artifacts { archives docsZip -} \ No newline at end of file +} diff --git a/gradle.properties b/gradle.properties index e0497a6b7..613e6ef9f 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,3 @@ version=1.2.7.BUILD-SNAPSHOT -javaFormatVersion=0.0.7-SNAPSHOT +javaFormatVersion=0.0.15 org.gradle.daemon=false 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 index 5483cfcdf..1abf90725 100644 --- 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 @@ -1,5 +1,5 @@ /* - * Copyright 2014-2016 the original author or authors. + * Copyright 2014-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. @@ -32,8 +32,8 @@ final class DefaultAttributesPreprocessor extends Preprocessor { @Override public PreprocessorReader process(Document document, PreprocessorReader reader) { - document.setAttr("snippets", this.snippetsDirectoryResolver - .getSnippetsDirectory(document.getAttributes()), false); + document.setAttr("snippets", this.snippetsDirectoryResolver.getSnippetsDirectory(document.getAttributes()), + false); return reader; } diff --git a/spring-restdocs-asciidoctor/src/main/java/org/springframework/restdocs/asciidoctor/RestDocsExtensionRegistry.java b/spring-restdocs-asciidoctor/src/main/java/org/springframework/restdocs/asciidoctor/RestDocsExtensionRegistry.java index 4872c27ba..4a894e185 100644 --- a/spring-restdocs-asciidoctor/src/main/java/org/springframework/restdocs/asciidoctor/RestDocsExtensionRegistry.java +++ b/spring-restdocs-asciidoctor/src/main/java/org/springframework/restdocs/asciidoctor/RestDocsExtensionRegistry.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2016 the original author or authors. + * Copyright 2014-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. @@ -28,11 +28,9 @@ public final class RestDocsExtensionRegistry implements ExtensionRegistry { @Override public void register(Asciidoctor asciidoctor) { - asciidoctor.javaExtensionRegistry() - .preprocessor(new DefaultAttributesPreprocessor()); + asciidoctor.javaExtensionRegistry().preprocessor(new DefaultAttributesPreprocessor()); asciidoctor.rubyExtensionRegistry() - .loadClass(RestDocsExtensionRegistry.class - .getResourceAsStream("/extensions/operation_block_macro.rb")) + .loadClass(RestDocsExtensionRegistry.class.getResourceAsStream("/extensions/operation_block_macro.rb")) .blockMacro("operation", "OperationBlockMacro"); } 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 index ac62896c2..318267ea7 100644 --- 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 @@ -1,5 +1,5 @@ /* - * Copyright 2014-2016 the original author or authors. + * Copyright 2014-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. @@ -40,8 +40,7 @@ File getSnippetsDirectory(Map attributes) { private File getMavenSnippetsDirectory(Map attributes) { Path docdir = Paths.get(getRequiredAttribute(attributes, "docdir")); - return new File(docdir.relativize(findPom(docdir).getParent()).toFile(), - "target/generated-snippets"); + return new File(docdir.relativize(findPom(docdir).getParent()).toFile(), "target/generated-snippets"); } private Path findPom(Path docdir) { @@ -57,8 +56,7 @@ private Path findPom(Path docdir) { } private File getGradleSnippetsDirectory(Map attributes) { - return new File(getRequiredAttribute(attributes, "projectdir"), - "build/generated-snippets"); + return new File(getRequiredAttribute(attributes, "projectdir"), "build/generated-snippets"); } private String getRequiredAttribute(Map attributes, String name) { 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 index 12bf34fe1..343296c5c 100644 --- 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 @@ -1,5 +1,5 @@ /* - * Copyright 2014-2016 the original author or authors. + * Copyright 2014-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. @@ -37,8 +37,7 @@ public void snippetsAttributeIsSet() { Options options = new Options(); options.setAttributes(new Attributes("projectdir=../../..")); String converted = Asciidoctor.Factory.create().convert("{snippets}", options); - assertThat(converted) - .contains("build" + File.separatorChar + "generated-snippets"); + assertThat(converted).contains("build" + File.separatorChar + "generated-snippets"); } @Test @@ -53,8 +52,7 @@ public void snippetsAttributeFromConvertArgumentIsNotOverridden() { public void snippetsAttributeFromDocumentPreambleIsNotOverridden() { Options options = new Options(); options.setAttributes(new Attributes("projectdir=../../..")); - String converted = Asciidoctor.Factory.create() - .convert(":snippets: custom\n{snippets}", options); + String converted = Asciidoctor.Factory.create().convert(":snippets: custom\n{snippets}", options); assertThat(converted).contains("custom"); } diff --git a/spring-restdocs-asciidoctor/src/test/java/org/springframework/restdocs/asciidoctor/OperationBlockMacroTests.java b/spring-restdocs-asciidoctor/src/test/java/org/springframework/restdocs/asciidoctor/OperationBlockMacroTests.java index 2d72b9242..70d2f08e6 100644 --- a/spring-restdocs-asciidoctor/src/test/java/org/springframework/restdocs/asciidoctor/OperationBlockMacroTests.java +++ b/spring-restdocs-asciidoctor/src/test/java/org/springframework/restdocs/asciidoctor/OperationBlockMacroTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-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. @@ -57,8 +57,7 @@ public class OperationBlockMacroTests { public static void prepareOperationSnippets() throws IOException { File destination = new File("build/generated-snippets/some-operation"); destination.mkdirs(); - FileSystemUtils.copyRecursively(new File("src/test/resources/some-operation"), - destination); + FileSystemUtils.copyRecursively(new File("src/test/resources/some-operation"), destination); } @Before @@ -68,8 +67,7 @@ public void setUp() { @Test public void codeBlockSnippetInclude() throws Exception { - String result = this.asciidoctor.convert( - "operation::some-operation[snippets='curl-request']", this.options); + String result = this.asciidoctor.convert("operation::some-operation[snippets='curl-request']", this.options); assertThat(result).isEqualTo(getExpectedContentFromFile("snippet-simple")); } @@ -78,41 +76,34 @@ public void operationWithParameterizedName() throws Exception { Attributes attributes = getAttributes(); attributes.setAttribute("name", "some"); this.options.setAttributes(attributes); - String result = this.asciidoctor.convert( - "operation::{name}-operation[snippets='curl-request']", this.options); + String result = this.asciidoctor.convert("operation::{name}-operation[snippets='curl-request']", this.options); assertThat(result).isEqualTo(getExpectedContentFromFile("snippet-simple")); } @Test public void codeBlockSnippetIncludeWithPdfBackend() throws Exception { File output = configurePdfOutput(); - this.asciidoctor.convert("operation::some-operation[snippets='curl-request']", - this.options); - assertThat(extractStrings(output)).containsExactly("Curl request", - "$ curl 'http://localhost:8080/' -i", "1"); + this.asciidoctor.convert("operation::some-operation[snippets='curl-request']", this.options); + assertThat(extractStrings(output)).containsExactly("Curl request", "$ curl 'http://localhost:8080/' -i", "1"); } @Test public void tableSnippetInclude() throws Exception { - String result = this.asciidoctor.convert( - "operation::some-operation[snippets='response-fields']", this.options); + String result = this.asciidoctor.convert("operation::some-operation[snippets='response-fields']", this.options); assertThat(result).isEqualTo(getExpectedContentFromFile("snippet-table")); } @Test public void tableSnippetIncludeWithPdfBackend() throws Exception { File output = configurePdfOutput(); - this.asciidoctor.convert("operation::some-operation[snippets='response-fields']", - this.options); - assertThat(extractStrings(output)).containsExactly("Response fields", "Path", - "Type", "Description", "a", "Object", "one", "a.b", "Number", "two", - "a.c", "String", "three", "1"); + this.asciidoctor.convert("operation::some-operation[snippets='response-fields']", this.options); + assertThat(extractStrings(output)).containsExactly("Response fields", "Path", "Type", "Description", "a", + "Object", "one", "a.b", "Number", "two", "a.c", "String", "three", "1"); } @Test public void includeSnippetInSection() throws Exception { - String result = this.asciidoctor.convert( - "== Section\n" + "operation::some-operation[snippets='curl-request']", + String result = this.asciidoctor.convert("== Section\n" + "operation::some-operation[snippets='curl-request']", this.options); assertThat(result).isEqualTo(getExpectedContentFromFile("snippet-in-section")); } @@ -120,83 +111,64 @@ public void includeSnippetInSection() throws Exception { @Test public void includeSnippetInSectionWithPdfBackend() throws Exception { File output = configurePdfOutput(); - this.asciidoctor.convert( - "== Section\n" + "operation::some-operation[snippets='curl-request']", - this.options); + this.asciidoctor.convert("== Section\n" + "operation::some-operation[snippets='curl-request']", this.options); assertThat(extractStrings(output)).containsExactly("Section", "Curl request", "$ curl 'http://localhost:8080/' -i", "1"); } @Test public void includeMultipleSnippets() throws Exception { - String result = this.asciidoctor.convert( - "operation::some-operation[snippets='curl-request,http-request']", + String result = this.asciidoctor.convert("operation::some-operation[snippets='curl-request,http-request']", this.options); assertThat(result).isEqualTo(getExpectedContentFromFile("multiple-snippets")); } @Test public void useMacroWithoutSnippetAttributeAddsAllSnippets() throws Exception { - String result = this.asciidoctor.convert("operation::some-operation[]", - this.options); + String result = this.asciidoctor.convert("operation::some-operation[]", this.options); assertThat(result).isEqualTo(getExpectedContentFromFile("all-snippets")); } @Test public void useMacroWithEmptySnippetAttributeAddsAllSnippets() throws Exception { - String result = this.asciidoctor.convert("operation::some-operation[snippets=]", - this.options); + String result = this.asciidoctor.convert("operation::some-operation[snippets=]", this.options); assertThat(result).isEqualTo(getExpectedContentFromFile("all-snippets")); } @Test public void includingMissingSnippetAddsWarning() throws Exception { - String result = this.asciidoctor.convert( - "operation::some-operation[snippets='missing-snippet']", this.options); + String result = this.asciidoctor.convert("operation::some-operation[snippets='missing-snippet']", this.options); assertThat(result).startsWith(getExpectedContentFromFile("missing-snippet")); } @Test public void defaultTitleIsProvidedForCustomSnippet() throws Exception { - String result = this.asciidoctor.convert( - "operation::some-operation[snippets='custom-snippet']", this.options); - assertThat(result) - .isEqualTo(getExpectedContentFromFile("custom-snippet-default-title")); + String result = this.asciidoctor.convert("operation::some-operation[snippets='custom-snippet']", this.options); + assertThat(result).isEqualTo(getExpectedContentFromFile("custom-snippet-default-title")); } @Test public void missingOperationIsHandledGracefully() throws Exception { - String result = this.asciidoctor.convert("operation::missing-operation[]", - this.options); + String result = this.asciidoctor.convert("operation::missing-operation[]", this.options); assertThat(result).startsWith(getExpectedContentFromFile("missing-operation")); } @Test - public void titleOfBuiltInSnippetCanBeCustomizedUsingDocumentAttribute() - throws URISyntaxException, IOException { - String result = this.asciidoctor.convert( - ":operation-curl-request-title: Example request\n" - + "operation::some-operation[snippets='curl-request']", - this.options); - assertThat(result) - .isEqualTo(getExpectedContentFromFile("built-in-snippet-custom-title")); + public void titleOfBuiltInSnippetCanBeCustomizedUsingDocumentAttribute() throws URISyntaxException, IOException { + String result = this.asciidoctor.convert(":operation-curl-request-title: Example request\n" + + "operation::some-operation[snippets='curl-request']", this.options); + assertThat(result).isEqualTo(getExpectedContentFromFile("built-in-snippet-custom-title")); } @Test - public void titleOfCustomSnippetCanBeCustomizedUsingDocumentAttribute() - throws Exception { - String result = this.asciidoctor.convert( - ":operation-custom-snippet-title: Customized title\n" - + "operation::some-operation[snippets='custom-snippet']", - this.options); - assertThat(result) - .isEqualTo(getExpectedContentFromFile("custom-snippet-custom-title")); + public void titleOfCustomSnippetCanBeCustomizedUsingDocumentAttribute() throws Exception { + String result = this.asciidoctor.convert(":operation-custom-snippet-title: Customized title\n" + + "operation::some-operation[snippets='custom-snippet']", this.options); + assertThat(result).isEqualTo(getExpectedContentFromFile("custom-snippet-custom-title")); } - private String getExpectedContentFromFile(String fileName) - throws URISyntaxException, IOException { - Path filePath = Paths.get( - this.getClass().getResource("/operations/" + fileName + ".html").toURI()); + private String getExpectedContentFromFile(String fileName) throws URISyntaxException, IOException { + Path filePath = Paths.get(this.getClass().getResource("/operations/" + fileName + ".html").toURI()); String content = new String(Files.readAllBytes(filePath)); if (isWindows()) { return content.replace("\r\n", "\n"); @@ -234,8 +206,7 @@ private static final class StringExtractor extends PDFStreamEngine { private final List strings = new ArrayList<>(); @Override - protected void processOperator(Operator operator, List operands) - throws IOException { + protected void processOperator(Operator operator, List operands) throws IOException { if ("Tj".equals(operator.getName())) { for (COSBase operand : operands) { if (operand instanceof COSString) { @@ -245,7 +216,7 @@ protected void processOperator(Operator operator, List operands) } } - public List getStrings() { + private List getStrings() { return this.strings; } 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 index 4081aaff5..f2591b0e3 100644 --- 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 @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-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. @@ -43,34 +43,27 @@ public class SnippetsDirectoryResolverTests { public ExpectedException thrown = ExpectedException.none(); @Test - public void mavenProjectsUseTargetGeneratedSnippetsRelativeToDocdir() - throws IOException { + 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()); + attributes.put("docdir", new File(this.temporaryFolder.getRoot(), "src/main/asciidoc").getAbsolutePath()); File snippetsDirectory = getMavenSnippetsDirectory(attributes); assertThat(snippetsDirectory).isRelative(); - assertThat(snippetsDirectory) - .isEqualTo(new File("../../../target/generated-snippets")); + assertThat(snippetsDirectory).isEqualTo(new File("../../../target/generated-snippets")); } @Test public void illegalStateExceptionWhenMavenPomCannotBeFound() throws IOException { Map attributes = new HashMap<>(); - String docdir = new File(this.temporaryFolder.getRoot(), "src/main/asciidoc") - .getAbsolutePath(); + String docdir = new File(this.temporaryFolder.getRoot(), "src/main/asciidoc").getAbsolutePath(); attributes.put("docdir", docdir); this.thrown.expect(IllegalStateException.class); - this.thrown - .expectMessage(equalTo("pom.xml not found in '" + docdir + "' or above")); + this.thrown.expectMessage(equalTo("pom.xml not found in '" + docdir + "' or above")); getMavenSnippetsDirectory(attributes); } @Test - public void illegalStateWhenDocdirAttributeIsNotSetInMavenProject() - throws IOException { + public void illegalStateWhenDocdirAttributeIsNotSetInMavenProject() throws IOException { Map attributes = new HashMap<>(); this.thrown.expect(IllegalStateException.class); this.thrown.expectMessage(equalTo("docdir attribute not found")); @@ -78,19 +71,15 @@ public void illegalStateWhenDocdirAttributeIsNotSetInMavenProject() } @Test - public void gradleProjectsUseBuildGeneratedSnippetsBeneathProjectDir() - throws IOException { + public void gradleProjectsUseBuildGeneratedSnippetsBeneathProjectDir() throws IOException { Map attributes = new HashMap<>(); attributes.put("projectdir", "project/dir"); - File snippetsDirectory = new SnippetsDirectoryResolver() - .getSnippetsDirectory(attributes); - assertThat(snippetsDirectory) - .isEqualTo(new File("project/dir/build/generated-snippets")); + File snippetsDirectory = new SnippetsDirectoryResolver().getSnippetsDirectory(attributes); + assertThat(snippetsDirectory).isEqualTo(new File("project/dir/build/generated-snippets")); } @Test - public void illegalStateWhenProjectdirAttributeIsNotSetInGradleProject() - throws IOException { + public void illegalStateWhenProjectdirAttributeIsNotSetInGradleProject() throws IOException { Map attributes = new HashMap<>(); this.thrown.expect(IllegalStateException.class); this.thrown.expectMessage(equalTo("projectdir attribute not found")); diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/JUnitRestDocumentation.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/JUnitRestDocumentation.java index 3022a8c6c..bbf99d94d 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/JUnitRestDocumentation.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/JUnitRestDocumentation.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2016 the original author or authors. + * Copyright 2014-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. @@ -27,8 +27,7 @@ * @author Andy Wilkinson * @since 1.1.0 */ -public class JUnitRestDocumentation - implements RestDocumentationContextProvider, TestRule { +public class JUnitRestDocumentation implements RestDocumentationContextProvider, TestRule { private final ManualRestDocumentation delegate; 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 7d30be987..2ae733879 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 @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-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. @@ -68,11 +68,9 @@ private ManualRestDocumentation(File outputDirectory) { @SuppressWarnings("deprecation") public void beforeTest(Class testClass, String testMethodName) { if (this.context != null) { - throw new IllegalStateException( - "Context already exists. Did you forget to call afterTest()?"); + throw new IllegalStateException("Context already exists. Did you forget to call afterTest()?"); } - this.context = new RestDocumentationContext(testClass, testMethodName, - this.outputDirectory); + this.context = new RestDocumentationContext(testClass, testMethodName, this.outputDirectory); } /** diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/RestDocumentationContext.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/RestDocumentationContext.java index 1529f28fc..4f799d7d6 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/RestDocumentationContext.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/RestDocumentationContext.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2015 the original author or authors. + * Copyright 2014-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. @@ -45,8 +45,7 @@ public final class RestDocumentationContext { * @deprecated Since 1.1 in favor of {@link ManualRestDocumentation}. */ @Deprecated - public RestDocumentationContext(Class testClass, String testMethodName, - File outputDirectory) { + public RestDocumentationContext(Class testClass, String testMethodName, File outputDirectory) { this.testClass = testClass; this.testMethodName = testMethodName; this.outputDirectory = outputDirectory; diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/cli/CliDocumentation.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/cli/CliDocumentation.java index 508cf28b9..94531be12 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/cli/CliDocumentation.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/cli/CliDocumentation.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2016 the original author or authors. + * Copyright 2014-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. @@ -80,8 +80,7 @@ public static Snippet curlRequest(CommandFormatter commandFormatter) { * @return the snippet that will document the curl request * @since 1.2.0 */ - public static Snippet curlRequest(Map attributes, - CommandFormatter commandFormatter) { + public static Snippet curlRequest(Map attributes, CommandFormatter commandFormatter) { return new CurlRequestSnippet(attributes, commandFormatter); } @@ -127,8 +126,7 @@ public static Snippet httpieRequest(CommandFormatter commandFormatter) { * @return the snippet that will document the HTTPie request * @since 1.2.0 */ - public static Snippet httpieRequest(Map attributes, - CommandFormatter commandFormatter) { + public static Snippet httpieRequest(Map attributes, CommandFormatter commandFormatter) { return new HttpieRequestSnippet(attributes, commandFormatter); } diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/cli/CliOperationRequest.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/cli/CliOperationRequest.java index 3f202a683..254bf623f 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/cli/CliOperationRequest.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/cli/CliOperationRequest.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-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. @@ -48,19 +48,16 @@ final class CliOperationRequest implements OperationRequest { CliOperationRequest(OperationRequest delegate) { this.delegate = delegate; - this.headerFilters = new HashSet<>(Arrays.asList( - new NamedHeaderFilter(HttpHeaders.CONTENT_LENGTH), + this.headerFilters = new HashSet<>(Arrays.asList(new NamedHeaderFilter(HttpHeaders.CONTENT_LENGTH), new BasicAuthHeaderFilter(), new HostHeaderFilter(delegate.getUri()))); } boolean isPutOrPost() { - return HttpMethod.PUT.equals(this.delegate.getMethod()) - || HttpMethod.POST.equals(this.delegate.getMethod()); + return HttpMethod.PUT.equals(this.delegate.getMethod()) || HttpMethod.POST.equals(this.delegate.getMethod()); } String getBasicAuthCredentials() { - List headerValue = this.delegate.getHeaders() - .get(HttpHeaders.AUTHORIZATION); + List headerValue = this.delegate.getHeaders().get(HttpHeaders.AUTHORIZATION); if (BasicAuthHeaderFilter.isBasicAuthHeader(headerValue)) { return BasicAuthHeaderFilter.decodeBasicAuthHeader(headerValue); } @@ -94,11 +91,9 @@ private boolean allowedHeader(Map.Entry> header) { return false; } } - if (HttpHeaders.HOST.equalsIgnoreCase(header.getKey()) - && (!header.getValue().isEmpty())) { + if (HttpHeaders.HOST.equalsIgnoreCase(header.getKey()) && (!header.getValue().isEmpty())) { String value = header.getValue().get(0); - if (value.equals(this.delegate.getUri().getHost() + ":" - + this.delegate.getUri().getPort())) { + if (value.equals(this.delegate.getUri().getHost() + ":" + this.delegate.getUri().getPort())) { return false; } } @@ -144,8 +139,7 @@ public boolean allow(String name, List value) { } static boolean isBasicAuthHeader(List value) { - return value != null && (!value.isEmpty()) - && value.get(0).startsWith("Basic "); + return value != null && (!value.isEmpty()) && value.get(0).startsWith("Basic "); } static String decodeBasicAuthHeader(List value) { @@ -179,13 +173,11 @@ private HostHeaderFilter(URI uri) { @Override public boolean allow(String name, List value) { - return !(value.isEmpty() - || this.getImplicitHostHeader().equals(value.get(0))); + return !(value.isEmpty() || this.getImplicitHostHeader().equals(value.get(0))); } private String getImplicitHostHeader() { - return this.uri.getHost() - + ((this.uri.getPort() == -1) ? "" : ":" + this.uri.getPort()); + return this.uri.getHost() + ((this.uri.getPort() == -1) ? "" : ":" + this.uri.getPort()); } } diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/cli/CurlRequestSnippet.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/cli/CurlRequestSnippet.java index 26fde8b83..0d9b32901 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/cli/CurlRequestSnippet.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/cli/CurlRequestSnippet.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-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. @@ -87,8 +87,7 @@ protected CurlRequestSnippet(Map attributes) { * @param attributes the additional attributes * @param commandFormatter the formatter for generating the snippet */ - protected CurlRequestSnippet(Map attributes, - CommandFormatter commandFormatter) { + protected CurlRequestSnippet(Map attributes, CommandFormatter commandFormatter) { super("curl-request", attributes); Assert.notNull(commandFormatter, "Command formatter must not be null"); this.commandFormatter = commandFormatter; @@ -104,20 +103,17 @@ protected Map createModel(Operation operation) { private String getUrl(Operation operation) { OperationRequest request = operation.getRequest(); - Parameters uniqueParameters = request.getParameters() - .getUniqueParameters(operation.getRequest().getUri()); + Parameters uniqueParameters = request.getParameters().getUniqueParameters(operation.getRequest().getUri()); if (!uniqueParameters.isEmpty() && includeParametersInUri(request)) { return String.format("'%s%s%s'", request.getUri(), - StringUtils.hasText(request.getUri().getRawQuery()) ? "&" : "?", - uniqueParameters.toQueryString()); + StringUtils.hasText(request.getUri().getRawQuery()) ? "&" : "?", uniqueParameters.toQueryString()); } return String.format("'%s'", request.getUri()); } private boolean includeParametersInUri(OperationRequest request) { return request.getMethod() == HttpMethod.GET || (request.getContent().length > 0 - && !MediaType.APPLICATION_FORM_URLENCODED - .isCompatibleWith(request.getHeaders().getContentType())); + && !MediaType.APPLICATION_FORM_URLENCODED.isCompatibleWith(request.getHeaders().getContentType())); } private String getOptions(Operation operation) { @@ -146,8 +142,7 @@ private void writeCookies(CliOperationRequest request, List lines) { if (cookiesBuilder.length() > 0) { cookiesBuilder.append(";"); } - cookiesBuilder.append( - String.format("%s=%s", cookie.getName(), cookie.getValue())); + cookiesBuilder.append(String.format("%s=%s", cookie.getName(), cookie.getValue())); } lines.add(String.format("--cookie '%s'", cookiesBuilder.toString())); } @@ -157,8 +152,7 @@ private void writeIncludeHeadersInOutputOption(StringBuilder builder) { builder.append("-i"); } - private void writeUserOptionIfNecessary(CliOperationRequest request, - StringBuilder builder) { + private void writeUserOptionIfNecessary(CliOperationRequest request, StringBuilder builder) { String credentials = request.getBasicAuthCredentials(); if (credentials != null) { builder.append(String.format(" -u '%s'", credentials)); @@ -213,10 +207,8 @@ else if (request.isPutOrPost()) { } } - private void writeContentUsingParameters(OperationRequest request, - List lines) { - Parameters uniqueParameters = request.getParameters() - .getUniqueParameters(request.getUri()); + private void writeContentUsingParameters(OperationRequest request, List lines) { + Parameters uniqueParameters = request.getParameters().getUniqueParameters(request.getUri()); String queryString = uniqueParameters.toQueryString(); if (StringUtils.hasText(queryString)) { lines.add(String.format("-d '%s'", queryString)); diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/cli/HttpieRequestSnippet.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/cli/HttpieRequestSnippet.java index 43ed2d888..aa679817c 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/cli/HttpieRequestSnippet.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/cli/HttpieRequestSnippet.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-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. @@ -88,8 +88,7 @@ protected HttpieRequestSnippet(Map attributes) { * @param attributes the additional attributes * @param commandFormatter the formatter for generating the snippet */ - protected HttpieRequestSnippet(Map attributes, - CommandFormatter commandFormatter) { + protected HttpieRequestSnippet(Map attributes, CommandFormatter commandFormatter) { super("httpie-request", attributes); Assert.notNull(commandFormatter, "Command formatter must not be null"); this.commandFormatter = commandFormatter; @@ -124,12 +123,10 @@ private String getOptions(CliOperationRequest request) { } private String getUrl(OperationRequest request) { - Parameters uniqueParameters = request.getParameters() - .getUniqueParameters(request.getUri()); + Parameters uniqueParameters = request.getParameters().getUniqueParameters(request.getUri()); if (!uniqueParameters.isEmpty() && includeParametersInUri(request)) { return String.format("'%s%s%s'", request.getUri(), - StringUtils.hasText(request.getUri().getRawQuery()) ? "&" : "?", - uniqueParameters.toQueryString()); + StringUtils.hasText(request.getUri().getRawQuery()) ? "&" : "?", uniqueParameters.toQueryString()); } return String.format("'%s'", request.getUri()); } @@ -146,28 +143,23 @@ private String getRequestItems(CliOperationRequest request) { } private void writeOptions(OperationRequest request, PrintWriter writer) { - if (!request.getParts().isEmpty() - || (!request.getParameters().getUniqueParameters(request.getUri()) - .isEmpty() && !includeParametersInUri(request) - && includeParametersAsFormOptions(request))) { + if (!request.getParts().isEmpty() || (!request.getParameters().getUniqueParameters(request.getUri()).isEmpty() + && !includeParametersInUri(request) && includeParametersAsFormOptions(request))) { writer.print("--form "); } } private boolean includeParametersInUri(OperationRequest request) { return request.getMethod() == HttpMethod.GET || (request.getContent().length > 0 - && !MediaType.APPLICATION_FORM_URLENCODED - .isCompatibleWith(request.getHeaders().getContentType())); + && !MediaType.APPLICATION_FORM_URLENCODED.isCompatibleWith(request.getHeaders().getContentType())); } private boolean includeParametersAsFormOptions(OperationRequest request) { return request.getMethod() != HttpMethod.GET && (request.getContent().length == 0 - || !MediaType.APPLICATION_FORM_URLENCODED - .isCompatibleWith(request.getHeaders().getContentType())); + || !MediaType.APPLICATION_FORM_URLENCODED.isCompatibleWith(request.getHeaders().getContentType())); } - private void writeUserOptionIfNecessary(CliOperationRequest request, - PrintWriter writer) { + private void writeUserOptionIfNecessary(CliOperationRequest request, PrintWriter writer) { String credentials = request.getBasicAuthCredentials(); if (credentials != null) { writer.print(String.format("--auth '%s' ", credentials)); @@ -199,8 +191,7 @@ private void writeHeaders(OperationRequest request, List lines) { for (Entry> entry : headers.entrySet()) { for (String header : entry.getValue()) { // HTTPie adds Content-Type automatically with --form - if (!request.getParts().isEmpty() - && entry.getKey().equals(HttpHeaders.CONTENT_TYPE) + if (!request.getParts().isEmpty() && entry.getKey().equals(HttpHeaders.CONTENT_TYPE) && header.startsWith(MediaType.MULTIPART_FORM_DATA_VALUE)) { continue; } @@ -211,13 +202,11 @@ private void writeHeaders(OperationRequest request, List lines) { private void writeCookies(OperationRequest request, List lines) { for (RequestCookie cookie : request.getCookies()) { - lines.add( - String.format("'Cookie:%s=%s'", cookie.getName(), cookie.getValue())); + lines.add(String.format("'Cookie:%s=%s'", cookie.getName(), cookie.getValue())); } } - private void writeParametersIfNecessary(CliOperationRequest request, - List lines) { + private void writeParametersIfNecessary(CliOperationRequest request, List lines) { if (StringUtils.hasText(request.getContentAsString())) { return; } @@ -225,8 +214,7 @@ private void writeParametersIfNecessary(CliOperationRequest request, writeContentUsingParameters(request.getParameters(), lines); } else if (request.isPutOrPost()) { - writeContentUsingParameters( - request.getParameters().getUniqueParameters(request.getUri()), lines); + writeContentUsingParameters(request.getParameters().getUniqueParameters(request.getUri()), lines); } } diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/cli/QueryStringParser.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/cli/QueryStringParser.java index 366f8174f..9c4d956ee 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/cli/QueryStringParser.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/cli/QueryStringParser.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2016 the original author or authors. + * Copyright 2014-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. @@ -24,7 +24,6 @@ * {@link org.springframework.restdocs.operation.QueryStringParser} */ @Deprecated -public class QueryStringParser - extends org.springframework.restdocs.operation.QueryStringParser { +public class QueryStringParser extends org.springframework.restdocs.operation.QueryStringParser { } diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/config/AbstractConfigurer.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/config/AbstractConfigurer.java index 469d1ba72..39bfd6d3f 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/config/AbstractConfigurer.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/config/AbstractConfigurer.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2016 the original author or authors. + * Copyright 2014-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. @@ -34,7 +34,6 @@ public abstract class AbstractConfigurer { * @param configuration the configuration to be configured * @param context the current documentation context */ - public abstract void apply(Map configuration, - RestDocumentationContext context); + public abstract void apply(Map configuration, RestDocumentationContext context); } diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/config/AbstractNestedConfigurer.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/config/AbstractNestedConfigurer.java index c2496aa54..c5327c864 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/config/AbstractNestedConfigurer.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/config/AbstractNestedConfigurer.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-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. @@ -23,8 +23,7 @@ * @author Andy Wilkinson * @since 1.1.0 */ -public abstract class AbstractNestedConfigurer extends AbstractConfigurer - implements NestedConfigurer { +public abstract class AbstractNestedConfigurer extends AbstractConfigurer implements NestedConfigurer { private final PARENT parent; diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/config/RestDocumentationConfigurer.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/config/RestDocumentationConfigurer.java index b4cca3501..ab4ab1e72 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/config/RestDocumentationConfigurer.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/config/RestDocumentationConfigurer.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-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. @@ -83,10 +83,9 @@ public final T writerResolver(WriterResolver writerResolver) { * @param configuration the configuration * @param context the current context */ - protected final void apply(Map configuration, - RestDocumentationContext context) { - List configurers = Arrays.asList(snippets(), - this.templateEngineConfigurer, this.writerResolverConfigurer); + protected final void apply(Map configuration, RestDocumentationContext context) { + List configurers = Arrays.asList(snippets(), this.templateEngineConfigurer, + this.writerResolverConfigurer); for (AbstractConfigurer configurer : configurers) { configurer.apply(configuration, context); } @@ -97,21 +96,17 @@ private static final class TemplateEngineConfigurer extends AbstractConfigurer { private TemplateEngine templateEngine; @Override - public void apply(Map configuration, - RestDocumentationContext context) { + public void apply(Map configuration, RestDocumentationContext context) { TemplateEngine engineToUse = this.templateEngine; if (engineToUse == null) { SnippetConfiguration snippetConfiguration = (SnippetConfiguration) configuration .get(SnippetConfiguration.class.getName()); Map templateContext = new HashMap<>(); - if (snippetConfiguration.getTemplateFormat().getId() - .equals(TemplateFormats.asciidoctor().getId())) { - templateContext.put("tableCellContent", - new AsciidoctorTableCellContentLambda()); + if (snippetConfiguration.getTemplateFormat().getId().equals(TemplateFormats.asciidoctor().getId())) { + templateContext.put("tableCellContent", new AsciidoctorTableCellContentLambda()); } engineToUse = new MustacheTemplateEngine( - new StandardTemplateResourceResolver( - snippetConfiguration.getTemplateFormat()), + new StandardTemplateResourceResolver(snippetConfiguration.getTemplateFormat()), Mustache.compiler().escapeHTML(false), templateContext); } configuration.put(TemplateEngine.class.getName(), engineToUse); @@ -128,16 +123,13 @@ private static final class WriterResolverConfigurer extends AbstractConfigurer { private WriterResolver writerResolver; @Override - public void apply(Map configuration, - RestDocumentationContext context) { + public void apply(Map configuration, RestDocumentationContext context) { WriterResolver resolverToUse = this.writerResolver; if (resolverToUse == null) { SnippetConfiguration snippetConfiguration = (SnippetConfiguration) configuration .get(SnippetConfiguration.class.getName()); - resolverToUse = new StandardWriterResolver( - new RestDocumentationContextPlaceholderResolverFactory(), - snippetConfiguration.getEncoding(), - snippetConfiguration.getTemplateFormat()); + resolverToUse = new StandardWriterResolver(new RestDocumentationContextPlaceholderResolverFactory(), + snippetConfiguration.getEncoding(), snippetConfiguration.getTemplateFormat()); } configuration.put(WriterResolver.class.getName(), resolverToUse); } diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/config/SnippetConfigurer.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/config/SnippetConfigurer.java index 58e2bde7d..a21b63146 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/config/SnippetConfigurer.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/config/SnippetConfigurer.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-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. @@ -38,12 +38,10 @@ * @author Andy Wilkinson * @since 1.1.0 */ -public abstract class SnippetConfigurer - extends AbstractNestedConfigurer { +public abstract class SnippetConfigurer extends AbstractNestedConfigurer { - private List defaultSnippets = new ArrayList<>(Arrays.asList( - CliDocumentation.curlRequest(), CliDocumentation.httpieRequest(), - HttpDocumentation.httpRequest(), HttpDocumentation.httpResponse(), + private List defaultSnippets = new ArrayList<>(Arrays.asList(CliDocumentation.curlRequest(), + CliDocumentation.httpieRequest(), HttpDocumentation.httpRequest(), HttpDocumentation.httpResponse(), PayloadDocumentation.requestBody(), PayloadDocumentation.responseBody())); /** @@ -58,8 +56,7 @@ public abstract class SnippetConfigurer * * @see #withTemplateFormat(TemplateFormat) */ - public static final TemplateFormat DEFAULT_TEMPLATE_FORMAT = TemplateFormats - .asciidoctor(); + public static final TemplateFormat DEFAULT_TEMPLATE_FORMAT = TemplateFormats.asciidoctor(); private String snippetEncoding = DEFAULT_SNIPPET_ENCODING; @@ -74,12 +71,10 @@ protected SnippetConfigurer(PARENT parent) { } @Override - public void apply(Map configuration, - RestDocumentationContext context) { + public void apply(Map configuration, RestDocumentationContext context) { configuration.put(SnippetConfiguration.class.getName(), new SnippetConfiguration(this.snippetEncoding, this.templateFormat)); - configuration.put(RestDocumentationGenerator.ATTRIBUTE_NAME_DEFAULT_SNIPPETS, - this.defaultSnippets); + configuration.put(RestDocumentationGenerator.ATTRIBUTE_NAME_DEFAULT_SNIPPETS, this.defaultSnippets); } /** diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/constraints/ConstraintDescriptions.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/constraints/ConstraintDescriptions.java index bf169003d..7df2bb0c9 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/constraints/ConstraintDescriptions.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/constraints/ConstraintDescriptions.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2015 the original author or authors. + * Copyright 2014-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. @@ -41,8 +41,7 @@ public class ConstraintDescriptions { * @param clazz the class */ public ConstraintDescriptions(Class clazz) { - this(clazz, new ValidatorConstraintResolver(), - new ResourceBundleConstraintDescriptionResolver()); + this(clazz, new ValidatorConstraintResolver(), new ResourceBundleConstraintDescriptionResolver()); } /** @@ -54,8 +53,7 @@ public ConstraintDescriptions(Class clazz) { * @param constraintResolver the constraint resolver */ public ConstraintDescriptions(Class clazz, ConstraintResolver constraintResolver) { - this(clazz, constraintResolver, - new ResourceBundleConstraintDescriptionResolver()); + this(clazz, constraintResolver, new ResourceBundleConstraintDescriptionResolver()); } /** @@ -65,8 +63,7 @@ public ConstraintDescriptions(Class clazz, ConstraintResolver constraintResol * @param clazz the class * @param descriptionResolver the description resolver */ - public ConstraintDescriptions(Class clazz, - ConstraintDescriptionResolver descriptionResolver) { + public ConstraintDescriptions(Class clazz, ConstraintDescriptionResolver descriptionResolver) { this(clazz, new ValidatorConstraintResolver(), descriptionResolver); } @@ -91,8 +88,7 @@ public ConstraintDescriptions(Class clazz, ConstraintResolver constraintResol * @return the list of constraint descriptions */ public List descriptionsForProperty(String property) { - List constraints = this.constraintResolver - .resolveForProperty(property, this.clazz); + List constraints = this.constraintResolver.resolveForProperty(property, this.clazz); List descriptions = new ArrayList<>(); for (Constraint constraint : constraints) { descriptions.add(this.descriptionResolver.resolveDescription(constraint)); diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/constraints/ResourceBundleConstraintDescriptionResolver.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/constraints/ResourceBundleConstraintDescriptionResolver.java index a822d420b..5ed899b35 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/constraints/ResourceBundleConstraintDescriptionResolver.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/constraints/ResourceBundleConstraintDescriptionResolver.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-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. @@ -95,11 +95,9 @@ * * @author Andy Wilkinson */ -public class ResourceBundleConstraintDescriptionResolver - implements ConstraintDescriptionResolver { +public class ResourceBundleConstraintDescriptionResolver implements ConstraintDescriptionResolver { - private final PropertyPlaceholderHelper propertyPlaceholderHelper = new PropertyPlaceholderHelper( - "${", "}"); + private final PropertyPlaceholderHelper propertyPlaceholderHelper = new PropertyPlaceholderHelper("${", "}"); private final ResourceBundle defaultDescriptions; @@ -128,8 +126,7 @@ public ResourceBundleConstraintDescriptionResolver(ResourceBundle resourceBundle private static ResourceBundle getBundle(String name) { try { return ResourceBundle.getBundle( - ResourceBundleConstraintDescriptionResolver.class.getPackage() - .getName() + "." + name, + ResourceBundleConstraintDescriptionResolver.class.getPackage().getName() + "." + name, Locale.getDefault(), Thread.currentThread().getContextClassLoader()); } catch (MissingResourceException ex) { @@ -156,8 +153,7 @@ private String getDescription(String key) { return this.defaultDescriptions.getString(key); } - private static final class ConstraintPlaceholderResolver - implements PlaceholderResolver { + private static final class ConstraintPlaceholderResolver implements PlaceholderResolver { private final Constraint constraint; diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/constraints/ValidatorConstraintResolver.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/constraints/ValidatorConstraintResolver.java index e893b0373..e8e9fecbc 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/constraints/ValidatorConstraintResolver.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/constraints/ValidatorConstraintResolver.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-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. @@ -64,13 +64,10 @@ public ValidatorConstraintResolver(Validator validator) { public List resolveForProperty(String property, Class clazz) { List constraints = new ArrayList<>(); BeanDescriptor beanDescriptor = this.validator.getConstraintsForClass(clazz); - PropertyDescriptor propertyDescriptor = beanDescriptor - .getConstraintsForProperty(property); + PropertyDescriptor propertyDescriptor = beanDescriptor.getConstraintsForProperty(property); if (propertyDescriptor != null) { - for (ConstraintDescriptor constraintDescriptor : propertyDescriptor - .getConstraintDescriptors()) { - constraints.add(new Constraint( - constraintDescriptor.getAnnotation().annotationType().getName(), + for (ConstraintDescriptor constraintDescriptor : propertyDescriptor.getConstraintDescriptors()) { + constraints.add(new Constraint(constraintDescriptor.getAnnotation().annotationType().getName(), constraintDescriptor.getAttributes())); } } diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/curl/CurlRequestSnippet.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/curl/CurlRequestSnippet.java index 7e5b80879..93c3fd5c4 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/curl/CurlRequestSnippet.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/curl/CurlRequestSnippet.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2016 the original author or authors. + * Copyright 2014-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. @@ -30,8 +30,7 @@ * {@link org.springframework.restdocs.cli.CurlRequestSnippet}. */ @Deprecated -public class CurlRequestSnippet - extends org.springframework.restdocs.cli.CurlRequestSnippet { +public class CurlRequestSnippet extends org.springframework.restdocs.cli.CurlRequestSnippet { /** * Creates a new {@code CurlRequestSnippet} with no additional attributes. diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/generate/RestDocumentationGenerator.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/generate/RestDocumentationGenerator.java index 67614f99f..78f6d0f87 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/generate/RestDocumentationGenerator.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/generate/RestDocumentationGenerator.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-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. @@ -80,11 +80,9 @@ public final class RestDocumentationGenerator { * @param responseConverter the response converter * @param snippets the snippets */ - public RestDocumentationGenerator(String identifier, - RequestConverter requestConverter, + public RestDocumentationGenerator(String identifier, RequestConverter requestConverter, ResponseConverter responseConverter, Snippet... snippets) { - this(identifier, requestConverter, responseConverter, - new IdentityOperationRequestPreprocessor(), + this(identifier, requestConverter, responseConverter, new IdentityOperationRequestPreprocessor(), new IdentityOperationResponsePreprocessor(), snippets); } @@ -102,10 +100,9 @@ public RestDocumentationGenerator(String identifier, * @param requestPreprocessor the request preprocessor * @param snippets the snippets */ - public RestDocumentationGenerator(String identifier, - RequestConverter requestConverter, - ResponseConverter responseConverter, - OperationRequestPreprocessor requestPreprocessor, Snippet... snippets) { + public RestDocumentationGenerator(String identifier, RequestConverter requestConverter, + ResponseConverter responseConverter, OperationRequestPreprocessor requestPreprocessor, + Snippet... snippets) { this(identifier, requestConverter, responseConverter, requestPreprocessor, new IdentityOperationResponsePreprocessor(), snippets); } @@ -124,13 +121,11 @@ public RestDocumentationGenerator(String identifier, * @param responsePreprocessor the response preprocessor * @param snippets the snippets */ - public RestDocumentationGenerator(String identifier, - RequestConverter requestConverter, - ResponseConverter responseConverter, - OperationResponsePreprocessor responsePreprocessor, Snippet... snippets) { - this(identifier, requestConverter, responseConverter, - new IdentityOperationRequestPreprocessor(), responsePreprocessor, - snippets); + public RestDocumentationGenerator(String identifier, RequestConverter requestConverter, + ResponseConverter responseConverter, OperationResponsePreprocessor responsePreprocessor, + Snippet... snippets) { + this(identifier, requestConverter, responseConverter, new IdentityOperationRequestPreprocessor(), + responsePreprocessor, snippets); } /** @@ -148,10 +143,8 @@ public RestDocumentationGenerator(String identifier, * @param responsePreprocessor the response preprocessor * @param snippets the snippets */ - public RestDocumentationGenerator(String identifier, - RequestConverter requestConverter, - ResponseConverter responseConverter, - OperationRequestPreprocessor requestPreprocessor, + public RestDocumentationGenerator(String identifier, RequestConverter requestConverter, + ResponseConverter responseConverter, OperationRequestPreprocessor requestPreprocessor, OperationResponsePreprocessor responsePreprocessor, Snippet... snippets) { Assert.notNull(identifier, "identifier must be non-null"); Assert.notNull(requestConverter, "requestConverter must be non-null"); @@ -178,14 +171,12 @@ public RestDocumentationGenerator(String identifier, * @throws RestDocumentationGenerationException if a failure occurs during handling */ public void handle(REQ request, RESP response, Map configuration) { - OperationRequest operationRequest = this.requestPreprocessor - .preprocess(this.requestConverter.convert(request)); + OperationRequest operationRequest = this.requestPreprocessor.preprocess(this.requestConverter.convert(request)); OperationResponse operationResponse = this.responsePreprocessor .preprocess(this.responseConverter.convert(response)); Map attributes = new HashMap<>(configuration); - Operation operation = new StandardOperation(this.identifier, operationRequest, - operationResponse, attributes); + Operation operation = new StandardOperation(this.identifier, operationRequest, operationResponse, attributes); try { for (Snippet snippet : getSnippets(attributes)) { snippet.document(operation); @@ -215,16 +206,14 @@ public void addSnippets(Snippet... snippets) { * @return the new generator */ public RestDocumentationGenerator withSnippets(Snippet... snippets) { - return new RestDocumentationGenerator<>(this.identifier, this.requestConverter, - this.responseConverter, this.requestPreprocessor, - this.responsePreprocessor, snippets); + return new RestDocumentationGenerator<>(this.identifier, this.requestConverter, this.responseConverter, + this.requestPreprocessor, this.responsePreprocessor, snippets); } @SuppressWarnings("unchecked") private List getSnippets(Map configuration) { List combinedSnippets = new ArrayList<>(); - List defaultSnippets = (List) configuration - .get(ATTRIBUTE_NAME_DEFAULT_SNIPPETS); + List defaultSnippets = (List) configuration.get(ATTRIBUTE_NAME_DEFAULT_SNIPPETS); if (defaultSnippets != null) { combinedSnippets.addAll(defaultSnippets); } @@ -234,8 +223,7 @@ private List getSnippets(Map configuration) { return combinedSnippets; } - private static final class IdentityOperationRequestPreprocessor - implements OperationRequestPreprocessor { + private static final class IdentityOperationRequestPreprocessor implements OperationRequestPreprocessor { @Override public OperationRequest preprocess(OperationRequest request) { @@ -244,8 +232,7 @@ public OperationRequest preprocess(OperationRequest request) { } - private static final class IdentityOperationResponsePreprocessor - implements OperationResponsePreprocessor { + private static final class IdentityOperationResponsePreprocessor implements OperationResponsePreprocessor { @Override public OperationResponse preprocess(OperationResponse response) { diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/headers/AbstractHeadersSnippet.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/headers/AbstractHeadersSnippet.java index dcc5942de..6e049b7a7 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/headers/AbstractHeadersSnippet.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/headers/AbstractHeadersSnippet.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2016 the original author or authors. + * Copyright 2014-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. @@ -48,14 +48,11 @@ public abstract class AbstractHeadersSnippet extends TemplatedSnippet { * @param descriptors the header descriptors * @param attributes the additional attributes */ - protected AbstractHeadersSnippet(String type, List descriptors, - Map attributes) { + protected AbstractHeadersSnippet(String type, List descriptors, Map attributes) { super(type + "-headers", attributes); for (HeaderDescriptor descriptor : descriptors) { - Assert.notNull(descriptor.getName(), - "The name of the header must not be null"); - Assert.notNull(descriptor.getDescription(), - "The description of the header must not be null"); + Assert.notNull(descriptor.getName(), "The name of the header must not be null"); + Assert.notNull(descriptor.getDescription(), "The description of the header must not be null"); } this.headerDescriptors = descriptors; this.type = type; @@ -81,8 +78,8 @@ private void validateHeaderDocumentation(Operation operation) { for (HeaderDescriptor headerDescriptor : missingHeaders) { names.add(headerDescriptor.getName()); } - throw new SnippetException("Headers with the following names were not found" - + " in the " + this.type + ": " + names); + throw new SnippetException( + "Headers with the following names were not found" + " in the " + this.type + ": " + names); } } @@ -97,8 +94,7 @@ protected List findMissingHeaders(Operation operation) { List missingHeaders = new ArrayList<>(); Set actualHeaders = extractActualHeaders(operation); for (HeaderDescriptor headerDescriptor : this.headerDescriptors) { - if (!headerDescriptor.isOptional() - && !actualHeaders.contains(headerDescriptor.getName())) { + if (!headerDescriptor.isOptional() && !actualHeaders.contains(headerDescriptor.getName())) { missingHeaders.add(headerDescriptor); } } diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/headers/HeaderDocumentation.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/headers/HeaderDocumentation.java index 36dd51079..e3a090f0c 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/headers/HeaderDocumentation.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/headers/HeaderDocumentation.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2016 the original author or authors. + * Copyright 2014-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. @@ -69,8 +69,7 @@ public static RequestHeadersSnippet requestHeaders(HeaderDescriptor... descripto * @return the snippet that will document the request headers * @see #headerWithName(String) */ - public static RequestHeadersSnippet requestHeaders( - List descriptors) { + public static RequestHeadersSnippet requestHeaders(List descriptors) { return new RequestHeadersSnippet(descriptors); } @@ -118,8 +117,7 @@ public static RequestHeadersSnippet requestHeaders(Map attribute * @return the snippet that will document the response headers * @see #headerWithName(String) */ - public static ResponseHeadersSnippet responseHeaders( - HeaderDescriptor... descriptors) { + public static ResponseHeadersSnippet responseHeaders(HeaderDescriptor... descriptors) { return responseHeaders(Arrays.asList(descriptors)); } @@ -133,8 +131,7 @@ public static ResponseHeadersSnippet responseHeaders( * @return the snippet that will document the response headers * @see #headerWithName(String) */ - public static ResponseHeadersSnippet responseHeaders( - List descriptors) { + public static ResponseHeadersSnippet responseHeaders(List descriptors) { return new ResponseHeadersSnippet(descriptors); } diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/headers/RequestHeadersSnippet.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/headers/RequestHeadersSnippet.java index 297f64e14..e64e7c08b 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/headers/RequestHeadersSnippet.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/headers/RequestHeadersSnippet.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2016 the original author or authors. + * Copyright 2014-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. @@ -51,8 +51,7 @@ protected RequestHeadersSnippet(List descriptors) { * @param descriptors the descriptors * @param attributes the additional attributes */ - protected RequestHeadersSnippet(List descriptors, - Map attributes) { + protected RequestHeadersSnippet(List descriptors, Map attributes) { super("request", descriptors, attributes); } @@ -80,8 +79,7 @@ public final RequestHeadersSnippet and(HeaderDescriptor... additionalDescriptors * @return the new snippet */ public final RequestHeadersSnippet and(List additionalDescriptors) { - List combinedDescriptors = new ArrayList<>( - this.getHeaderDescriptors()); + List combinedDescriptors = new ArrayList<>(this.getHeaderDescriptors()); combinedDescriptors.addAll(additionalDescriptors); return new RequestHeadersSnippet(combinedDescriptors, getAttributes()); } diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/headers/ResponseHeadersSnippet.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/headers/ResponseHeadersSnippet.java index 4caa75c26..e1acb6812 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/headers/ResponseHeadersSnippet.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/headers/ResponseHeadersSnippet.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2016 the original author or authors. + * Copyright 2014-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. @@ -51,8 +51,7 @@ protected ResponseHeadersSnippet(List descriptors) { * @param descriptors the descriptors * @param attributes the additional attributes */ - protected ResponseHeadersSnippet(List descriptors, - Map attributes) { + protected ResponseHeadersSnippet(List descriptors, Map attributes) { super("response", descriptors, attributes); } @@ -79,10 +78,8 @@ public final ResponseHeadersSnippet and(HeaderDescriptor... additionalDescriptor * @param additionalDescriptors the additional descriptors * @return the new snippet */ - public final ResponseHeadersSnippet and( - List additionalDescriptors) { - List combinedDescriptors = new ArrayList<>( - this.getHeaderDescriptors()); + public final ResponseHeadersSnippet and(List additionalDescriptors) { + List combinedDescriptors = new ArrayList<>(this.getHeaderDescriptors()); combinedDescriptors.addAll(additionalDescriptors); return new ResponseHeadersSnippet(combinedDescriptors, getAttributes()); } diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/http/HttpRequestSnippet.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/http/HttpRequestSnippet.java index 7253d6944..7193bd8a2 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/http/HttpRequestSnippet.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/http/HttpRequestSnippet.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-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. @@ -76,8 +76,7 @@ protected Map createModel(Operation operation) { private String getPath(OperationRequest request) { String path = request.getUri().getRawPath(); String queryString = request.getUri().getRawQuery(); - Parameters uniqueParameters = request.getParameters() - .getUniqueParameters(request.getUri()); + Parameters uniqueParameters = request.getParameters().getUniqueParameters(request.getUri()); if (!uniqueParameters.isEmpty() && includeParametersInUri(request)) { if (StringUtils.hasText(queryString)) { queryString = queryString + "&" + uniqueParameters.toQueryString(); @@ -94,8 +93,7 @@ private String getPath(OperationRequest request) { private boolean includeParametersInUri(OperationRequest request) { return request.getMethod() == HttpMethod.GET || (request.getContent().length > 0 - && !MediaType.APPLICATION_FORM_URLENCODED - .isCompatibleWith(request.getHeaders().getContentType())); + && !MediaType.APPLICATION_FORM_URLENCODED.isCompatibleWith(request.getHeaders().getContentType())); } private List> getHeaders(OperationRequest request) { @@ -103,10 +101,8 @@ private List> getHeaders(OperationRequest request) { for (Entry> header : request.getHeaders().entrySet()) { for (String value : header.getValue()) { - if (HttpHeaders.CONTENT_TYPE.equals(header.getKey()) - && !request.getParts().isEmpty()) { - headers.add(header(header.getKey(), - String.format("%s; boundary=%s", value, MULTIPART_BOUNDARY))); + if (HttpHeaders.CONTENT_TYPE.equals(header.getKey()) && !request.getParts().isEmpty()) { + headers.add(header(header.getKey(), String.format("%s; boundary=%s", value, MULTIPART_BOUNDARY))); } else { headers.add(header(header.getKey(), value)); @@ -116,13 +112,11 @@ private List> getHeaders(OperationRequest request) { } for (RequestCookie cookie : request.getCookies()) { - headers.add(header(HttpHeaders.COOKIE, - String.format("%s=%s", cookie.getName(), cookie.getValue()))); + headers.add(header(HttpHeaders.COOKIE, String.format("%s=%s", cookie.getName(), cookie.getValue()))); } if (requiresFormEncodingContentTypeHeader(request)) { - headers.add(header(HttpHeaders.CONTENT_TYPE, - MediaType.APPLICATION_FORM_URLENCODED_VALUE)); + headers.add(header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_FORM_URLENCODED_VALUE)); } return headers; } @@ -150,8 +144,7 @@ else if (isPutOrPost(request)) { } private boolean isPutOrPost(OperationRequest request) { - return HttpMethod.PUT.equals(request.getMethod()) - || HttpMethod.POST.equals(request.getMethod()); + return HttpMethod.PUT.equals(request.getMethod()) || HttpMethod.POST.equals(request.getMethod()); } private void writeParts(OperationRequest request, PrintWriter writer) { @@ -186,8 +179,7 @@ private void writePart(OperationRequestPart part, PrintWriter writer) { part.getHeaders().getContentType(), writer); } - private void writePart(String name, String value, String filename, - MediaType contentType, PrintWriter writer) { + private void writePart(String name, String value, String filename, MediaType contentType, PrintWriter writer) { writer.printf("Content-Disposition: form-data; name=%s", name); if (StringUtils.hasText(filename)) { writer.printf("; filename=%s", filename); @@ -205,9 +197,8 @@ private void writeMultipartEnd(PrintWriter writer) { } private boolean requiresFormEncodingContentTypeHeader(OperationRequest request) { - return request.getHeaders().get(HttpHeaders.CONTENT_TYPE) == null - && isPutOrPost(request) && (!request.getParameters().isEmpty() - && !includeParametersInUri(request)); + return request.getHeaders().get(HttpHeaders.CONTENT_TYPE) == null && isPutOrPost(request) + && (!request.getParameters().isEmpty() && !includeParametersInUri(request)); } private Map header(String name, String value) { diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/hypermedia/AbstractJsonLinkExtractor.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/hypermedia/AbstractJsonLinkExtractor.java index a15d69fea..a019ef7e7 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/hypermedia/AbstractJsonLinkExtractor.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/hypermedia/AbstractJsonLinkExtractor.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2015 the original author or authors. + * Copyright 2014-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. @@ -35,10 +35,8 @@ abstract class AbstractJsonLinkExtractor implements LinkExtractor { @Override @SuppressWarnings("unchecked") - public Map> extractLinks(OperationResponse response) - throws IOException { - Map jsonContent = this.objectMapper - .readValue(response.getContent(), Map.class); + public Map> extractLinks(OperationResponse response) throws IOException { + Map jsonContent = this.objectMapper.readValue(response.getContent(), Map.class); return extractLinks(jsonContent); } diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/hypermedia/AtomLinkExtractor.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/hypermedia/AtomLinkExtractor.java index 99d989ede..f2a68f897 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/hypermedia/AtomLinkExtractor.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/hypermedia/AtomLinkExtractor.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-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. @@ -58,8 +58,7 @@ private static Link maybeCreateLink(Map linkMap) { return null; } - private static void maybeStoreLink(Link link, - MultiValueMap extractedLinks) { + private static void maybeStoreLink(Link link, MultiValueMap extractedLinks) { if (link != null) { extractedLinks.add(link.getRel(), link); } diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/hypermedia/ContentTypeLinkExtractor.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/hypermedia/ContentTypeLinkExtractor.java index fa8e5c6a7..ef2a9e8ec 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/hypermedia/ContentTypeLinkExtractor.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/hypermedia/ContentTypeLinkExtractor.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2015 the original author or authors. + * Copyright 2014-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. @@ -45,16 +45,14 @@ class ContentTypeLinkExtractor implements LinkExtractor { } @Override - public Map> extractLinks(OperationResponse response) - throws IOException { + public Map> extractLinks(OperationResponse response) throws IOException { MediaType contentType = response.getHeaders().getContentType(); LinkExtractor extractorForContentType = getExtractorForContentType(contentType); if (extractorForContentType != null) { return extractorForContentType.extractLinks(response); } throw new IllegalStateException( - "No LinkExtractor has been provided and one is not available for the " - + "content type " + contentType); + "No LinkExtractor has been provided and one is not available for the " + "content type " + contentType); } private LinkExtractor getExtractorForContentType(MediaType contentType) { diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/hypermedia/HypermediaDocumentation.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/hypermedia/HypermediaDocumentation.java index 7b8dd4ad3..74bacc616 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/hypermedia/HypermediaDocumentation.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/hypermedia/HypermediaDocumentation.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-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. @@ -147,8 +147,7 @@ public static LinksSnippet relaxedLinks(List descriptors) { * @param descriptors the descriptions of the response's links * @return the snippet that will document the links */ - public static LinksSnippet links(Map attributes, - LinkDescriptor... descriptors) { + public static LinksSnippet links(Map attributes, LinkDescriptor... descriptors) { return links(attributes, Arrays.asList(descriptors)); } @@ -174,8 +173,7 @@ public static LinksSnippet links(Map attributes, * @param descriptors the descriptions of the response's links * @return the snippet that will document the links */ - public static LinksSnippet links(Map attributes, - List descriptors) { + public static LinksSnippet links(Map attributes, List descriptors) { return new LinksSnippet(new ContentTypeLinkExtractor(), descriptors, attributes); } @@ -195,8 +193,7 @@ public static LinksSnippet links(Map attributes, * @param descriptors the descriptions of the response's links * @return the snippet that will document the links */ - public static LinksSnippet relaxedLinks(Map attributes, - LinkDescriptor... descriptors) { + public static LinksSnippet relaxedLinks(Map attributes, LinkDescriptor... descriptors) { return relaxedLinks(attributes, Arrays.asList(descriptors)); } @@ -216,10 +213,8 @@ public static LinksSnippet relaxedLinks(Map attributes, * @param descriptors the descriptions of the response's links * @return the snippet that will document the links */ - public static LinksSnippet relaxedLinks(Map attributes, - List descriptors) { - return new LinksSnippet(new ContentTypeLinkExtractor(), descriptors, attributes, - true); + public static LinksSnippet relaxedLinks(Map attributes, List descriptors) { + return new LinksSnippet(new ContentTypeLinkExtractor(), descriptors, attributes, true); } /** @@ -243,8 +238,7 @@ public static LinksSnippet relaxedLinks(Map attributes, * @param descriptors the descriptions of the response's links * @return the snippet that will document the links */ - public static LinksSnippet links(LinkExtractor linkExtractor, - LinkDescriptor... descriptors) { + public static LinksSnippet links(LinkExtractor linkExtractor, LinkDescriptor... descriptors) { return links(linkExtractor, Arrays.asList(descriptors)); } @@ -269,8 +263,7 @@ public static LinksSnippet links(LinkExtractor linkExtractor, * @param descriptors the descriptions of the response's links * @return the snippet that will document the links */ - public static LinksSnippet links(LinkExtractor linkExtractor, - List descriptors) { + public static LinksSnippet links(LinkExtractor linkExtractor, List descriptors) { return new LinksSnippet(linkExtractor, descriptors); } @@ -289,8 +282,7 @@ public static LinksSnippet links(LinkExtractor linkExtractor, * @param descriptors the descriptions of the response's links * @return the snippet that will document the links */ - public static LinksSnippet relaxedLinks(LinkExtractor linkExtractor, - LinkDescriptor... descriptors) { + public static LinksSnippet relaxedLinks(LinkExtractor linkExtractor, LinkDescriptor... descriptors) { return relaxedLinks(linkExtractor, Arrays.asList(descriptors)); } @@ -309,8 +301,7 @@ public static LinksSnippet relaxedLinks(LinkExtractor linkExtractor, * @param descriptors the descriptions of the response's links * @return the snippet that will document the links */ - public static LinksSnippet relaxedLinks(LinkExtractor linkExtractor, - List descriptors) { + public static LinksSnippet relaxedLinks(LinkExtractor linkExtractor, List descriptors) { return new LinksSnippet(linkExtractor, descriptors, true); } @@ -337,8 +328,8 @@ public static LinksSnippet relaxedLinks(LinkExtractor linkExtractor, * @param descriptors the descriptions of the response's links * @return the snippet that will document the links */ - public static LinksSnippet links(LinkExtractor linkExtractor, - Map attributes, LinkDescriptor... descriptors) { + public static LinksSnippet links(LinkExtractor linkExtractor, Map attributes, + LinkDescriptor... descriptors) { return links(linkExtractor, attributes, Arrays.asList(descriptors)); } @@ -365,8 +356,8 @@ public static LinksSnippet links(LinkExtractor linkExtractor, * @param descriptors the descriptions of the response's links * @return the snippet that will document the links */ - public static LinksSnippet links(LinkExtractor linkExtractor, - Map attributes, List descriptors) { + public static LinksSnippet links(LinkExtractor linkExtractor, Map attributes, + List descriptors) { return new LinksSnippet(linkExtractor, descriptors, attributes); } @@ -387,8 +378,8 @@ public static LinksSnippet links(LinkExtractor linkExtractor, * @param descriptors the descriptions of the response's links * @return the snippet that will document the links */ - public static LinksSnippet relaxedLinks(LinkExtractor linkExtractor, - Map attributes, LinkDescriptor... descriptors) { + public static LinksSnippet relaxedLinks(LinkExtractor linkExtractor, Map attributes, + LinkDescriptor... descriptors) { return relaxedLinks(linkExtractor, attributes, Arrays.asList(descriptors)); } @@ -409,8 +400,8 @@ public static LinksSnippet relaxedLinks(LinkExtractor linkExtractor, * @param descriptors the descriptions of the response's links * @return the snippet that will document the links */ - public static LinksSnippet relaxedLinks(LinkExtractor linkExtractor, - Map attributes, List descriptors) { + public static LinksSnippet relaxedLinks(LinkExtractor linkExtractor, Map attributes, + List descriptors) { return new LinksSnippet(linkExtractor, descriptors, attributes, true); } diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/hypermedia/Link.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/hypermedia/Link.java index 263de7941..004c04fac 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/hypermedia/Link.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/hypermedia/Link.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2015 the original author or authors. + * Copyright 2014-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. @@ -118,8 +118,8 @@ public int hashCode() { @Override public String toString() { - return new ToStringCreator(this).append("rel", this.rel).append("href", this.href) - .append("title", this.title).toString(); + return new ToStringCreator(this).append("rel", this.rel).append("href", this.href).append("title", this.title) + .toString(); } } diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/hypermedia/LinksSnippet.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/hypermedia/LinksSnippet.java index 139bdb7b7..e5ee2ce8c 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/hypermedia/LinksSnippet.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/hypermedia/LinksSnippet.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2016 the original author or authors. + * Copyright 2014-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. @@ -60,8 +60,7 @@ public class LinksSnippet extends TemplatedSnippet { * @param linkExtractor the link extractor * @param descriptors the link descriptors */ - protected LinksSnippet(LinkExtractor linkExtractor, - List descriptors) { + protected LinksSnippet(LinkExtractor linkExtractor, List descriptors) { this(linkExtractor, descriptors, null, false); } @@ -144,8 +143,7 @@ private void validate(Map> links) { } Set requiredRels = new HashSet<>(); - for (Entry relAndDescriptor : this.descriptorsByRel - .entrySet()) { + for (Entry relAndDescriptor : this.descriptorsByRel.entrySet()) { if (!relAndDescriptor.getValue().isOptional()) { requiredRels.add(relAndDescriptor.getKey()); } @@ -157,15 +155,13 @@ private void validate(Map> links) { if (!undocumentedRels.isEmpty() || !missingRels.isEmpty()) { String message = ""; if (!undocumentedRels.isEmpty()) { - message += "Links with the following relations were not documented: " - + undocumentedRels; + message += "Links with the following relations were not documented: " + undocumentedRels; } if (!missingRels.isEmpty()) { if (message.length() > 0) { message += ". "; } - message += "Links with the following relations were not found in the " - + "response: " + missingRels; + message += "Links with the following relations were not found in the " + "response: " + missingRels; } throw new SnippetException(message); } @@ -177,9 +173,7 @@ private List> createLinksModel(Map> links LinkDescriptor descriptor = entry.getValue(); if (!descriptor.isIgnored()) { if (descriptor.getDescription() == null) { - descriptor = createDescriptor( - getDescriptionFromLinkTitle(links, descriptor.getRel()), - descriptor); + descriptor = createDescriptor(getDescriptionFromLinkTitle(links, descriptor.getRel()), descriptor); } model.add(createModelForDescriptor(descriptor)); } @@ -187,8 +181,7 @@ private List> createLinksModel(Map> links return model; } - private String getDescriptionFromLinkTitle(Map> links, - String rel) { + private String getDescriptionFromLinkTitle(Map> links, String rel) { List linksForRel = links.get(rel); if (linksForRel != null) { for (Link link : linksForRel) { @@ -197,13 +190,12 @@ private String getDescriptionFromLinkTitle(Map> links, } } } - throw new SnippetException("No description was provided for the link with rel '" - + rel + "' and no title was available from the link in the payload"); + throw new SnippetException("No description was provided for the link with rel '" + rel + + "' and no title was available from the link in the payload"); } private LinkDescriptor createDescriptor(String description, LinkDescriptor source) { - LinkDescriptor newDescriptor = new LinkDescriptor(source.getRel()) - .description(description); + LinkDescriptor newDescriptor = new LinkDescriptor(source.getRel()).description(description); if (source.isOptional()) { newDescriptor.optional(); } @@ -255,8 +247,7 @@ public final LinksSnippet and(LinkDescriptor... additionalDescriptors) { * @return the new snippet */ public final LinksSnippet and(List additionalDescriptors) { - List combinedDescriptors = new ArrayList<>( - this.descriptorsByRel.values()); + List combinedDescriptors = new ArrayList<>(this.descriptorsByRel.values()); combinedDescriptors.addAll(additionalDescriptors); return new LinksSnippet(this.linkExtractor, combinedDescriptors, getAttributes()); } diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/AbstractOperationMessage.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/AbstractOperationMessage.java index 0146e419b..7019cd750 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/AbstractOperationMessage.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/AbstractOperationMessage.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-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. @@ -27,7 +27,7 @@ * * @author Andy Wilkinson */ -abstract class AbstractOperationMessage { +abstract class AbstractOperationMessage implements OperationMessage { private final byte[] content; @@ -38,19 +38,21 @@ abstract class AbstractOperationMessage { this.headers = headers; } + @Override public byte[] getContent() { return Arrays.copyOf(this.content, this.content.length); } + @Override public HttpHeaders getHeaders() { return HttpHeaders.readOnlyHttpHeaders(this.headers); } + @Override public String getContentAsString() { if (this.content.length > 0) { Charset charset = extractCharsetFromContentTypeHeader(); - return (charset != null) ? new String(this.content, charset) - : new String(this.content); + return (charset != null) ? new String(this.content, charset) : new String(this.content); } return ""; } diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/OperationMessage.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/OperationMessage.java new file mode 100644 index 000000000..7570c5ed1 --- /dev/null +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/OperationMessage.java @@ -0,0 +1,34 @@ +/* + * Copyright 2014-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 + * + * https://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.operation; + +import org.springframework.http.HttpHeaders; + +/** + * Base contract for operation requests, request parts, and responses. + * + * @author Andy Wilkinson + */ +interface OperationMessage { + + byte[] getContent(); + + String getContentAsString(); + + HttpHeaders getHeaders(); + +} diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/OperationRequestFactory.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/OperationRequestFactory.java index 0f62509ed..c8ce358e4 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/OperationRequestFactory.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/OperationRequestFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-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. @@ -43,11 +43,10 @@ public class OperationRequestFactory { * @param cookies the request's cookies * @return the {@code OperationRequest} */ - public OperationRequest create(URI uri, HttpMethod method, byte[] content, - HttpHeaders headers, Parameters parameters, - Collection parts, Collection cookies) { - return new StandardOperationRequest(uri, method, content, - augmentHeaders(headers, uri, content), parameters, parts, cookies); + public OperationRequest create(URI uri, HttpMethod method, byte[] content, HttpHeaders headers, + Parameters parameters, Collection parts, Collection cookies) { + return new StandardOperationRequest(uri, method, content, augmentHeaders(headers, uri, content), parameters, + parts, cookies); } /** @@ -62,11 +61,9 @@ public OperationRequest create(URI uri, HttpMethod method, byte[] content, * @param parts the request's parts * @return the {@code OperationRequest} */ - public OperationRequest create(URI uri, HttpMethod method, byte[] content, - HttpHeaders headers, Parameters parameters, - Collection parts) { - return create(uri, method, content, headers, parameters, parts, - Collections.emptyList()); + public OperationRequest create(URI uri, HttpMethod method, byte[] content, HttpHeaders headers, + Parameters parameters, Collection parts) { + return create(uri, method, content, headers, parameters, parts, Collections.emptyList()); } /** @@ -78,9 +75,9 @@ public OperationRequest create(URI uri, HttpMethod method, byte[] content, * @return the new request with the new content */ public OperationRequest createFrom(OperationRequest original, byte[] newContent) { - return new StandardOperationRequest(original.getUri(), original.getMethod(), - newContent, getUpdatedHeaders(original.getHeaders(), newContent), - original.getParameters(), original.getParts(), original.getCookies()); + return new StandardOperationRequest(original.getUri(), original.getMethod(), newContent, + getUpdatedHeaders(original.getHeaders(), newContent), original.getParameters(), original.getParts(), + original.getCookies()); } /** @@ -90,11 +87,9 @@ public OperationRequest createFrom(OperationRequest original, byte[] newContent) * @param newHeaders the new headers * @return the new request with the new headers */ - public OperationRequest createFrom(OperationRequest original, - HttpHeaders newHeaders) { - return new StandardOperationRequest(original.getUri(), original.getMethod(), - original.getContent(), newHeaders, original.getParameters(), - original.getParts(), original.getCookies()); + public OperationRequest createFrom(OperationRequest original, HttpHeaders newHeaders) { + return new StandardOperationRequest(original.getUri(), original.getMethod(), original.getContent(), newHeaders, + original.getParameters(), original.getParts(), original.getCookies()); } /** @@ -104,17 +99,13 @@ public OperationRequest createFrom(OperationRequest original, * @param newParameters the new parameters * @return the new request with the new parameters */ - public OperationRequest createFrom(OperationRequest original, - Parameters newParameters) { - return new StandardOperationRequest(original.getUri(), original.getMethod(), - original.getContent(), original.getHeaders(), newParameters, - original.getParts(), original.getCookies()); + public OperationRequest createFrom(OperationRequest original, Parameters newParameters) { + return new StandardOperationRequest(original.getUri(), original.getMethod(), original.getContent(), + original.getHeaders(), newParameters, original.getParts(), original.getCookies()); } - private HttpHeaders augmentHeaders(HttpHeaders originalHeaders, URI uri, - byte[] content) { - return new HttpHeadersHelper(originalHeaders) - .addIfAbsent(HttpHeaders.HOST, createHostHeader(uri)) + private HttpHeaders augmentHeaders(HttpHeaders originalHeaders, URI uri, byte[] content) { + return new HttpHeadersHelper(originalHeaders).addIfAbsent(HttpHeaders.HOST, createHostHeader(uri)) .setContentLengthHeader(content).getHeaders(); } @@ -125,10 +116,8 @@ private String createHostHeader(URI uri) { return uri.getHost() + ":" + uri.getPort(); } - private HttpHeaders getUpdatedHeaders(HttpHeaders originalHeaders, - byte[] updatedContent) { - return new HttpHeadersHelper(originalHeaders) - .updateContentLengthHeaderIfPresent(updatedContent).getHeaders(); + private HttpHeaders getUpdatedHeaders(HttpHeaders originalHeaders, byte[] updatedContent) { + return new HttpHeadersHelper(originalHeaders).updateContentLengthHeaderIfPresent(updatedContent).getHeaders(); } } diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/OperationRequestPartFactory.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/OperationRequestPartFactory.java index ea3881da2..d9fe354c6 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/OperationRequestPartFactory.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/OperationRequestPartFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2015 the original author or authors. + * Copyright 2014-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. @@ -35,10 +35,8 @@ public class OperationRequestPartFactory { * @param headers the headers of the part * @return the {@code OperationRequestPart} */ - public OperationRequestPart create(String name, String submittedFileName, - byte[] content, HttpHeaders headers) { - return new StandardOperationRequestPart(name, submittedFileName, content, - augmentHeaders(headers, content)); + public OperationRequestPart create(String name, String submittedFileName, byte[] content, HttpHeaders headers) { + return new StandardOperationRequestPart(name, submittedFileName, content, augmentHeaders(headers, content)); } private HttpHeaders augmentHeaders(HttpHeaders input, byte[] content) { diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/OperationResponseFactory.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/OperationResponseFactory.java index dd5fa117d..e865987eb 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/OperationResponseFactory.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/OperationResponseFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-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. @@ -35,10 +35,8 @@ public class OperationResponseFactory { * @param content the content of the request * @return the {@code OperationResponse} */ - public OperationResponse create(HttpStatus status, HttpHeaders headers, - byte[] content) { - return new StandardOperationResponse(status, augmentHeaders(headers, content), - content); + public OperationResponse create(HttpStatus status, HttpHeaders headers, byte[] content) { + return new StandardOperationResponse(status, augmentHeaders(headers, content), content); } /** @@ -51,8 +49,8 @@ public OperationResponse create(HttpStatus status, HttpHeaders headers, * @return the new response with the new content */ public OperationResponse createFrom(OperationResponse original, byte[] newContent) { - return new StandardOperationResponse(original.getStatus(), - getUpdatedHeaders(original.getHeaders(), newContent), newContent); + return new StandardOperationResponse(original.getStatus(), getUpdatedHeaders(original.getHeaders(), newContent), + newContent); } /** @@ -62,21 +60,16 @@ public OperationResponse createFrom(OperationResponse original, byte[] newConten * @param newHeaders the new headers * @return the new response with the new headers */ - public OperationResponse createFrom(OperationResponse original, - HttpHeaders newHeaders) { - return new StandardOperationResponse(original.getStatus(), newHeaders, - original.getContent()); + public OperationResponse createFrom(OperationResponse original, HttpHeaders newHeaders) { + return new StandardOperationResponse(original.getStatus(), newHeaders, original.getContent()); } private HttpHeaders augmentHeaders(HttpHeaders originalHeaders, byte[] content) { - return new HttpHeadersHelper(originalHeaders).setContentLengthHeader(content) - .getHeaders(); + return new HttpHeadersHelper(originalHeaders).setContentLengthHeader(content).getHeaders(); } - private HttpHeaders getUpdatedHeaders(HttpHeaders originalHeaders, - byte[] updatedContent) { - return new HttpHeadersHelper(originalHeaders) - .updateContentLengthHeaderIfPresent(updatedContent).getHeaders(); + private HttpHeaders getUpdatedHeaders(HttpHeaders originalHeaders, byte[] updatedContent) { + return new HttpHeadersHelper(originalHeaders).updateContentLengthHeaderIfPresent(updatedContent).getHeaders(); } } diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/Parameters.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/Parameters.java index a0b856b2f..0e3558e5f 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/Parameters.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/Parameters.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2016 the original author or authors. + * Copyright 2014-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. @@ -69,8 +69,8 @@ public Parameters getUniqueParameters(URI uri) { return uniqueParameters; } - private void addIfUnique(Map.Entry> parameter, - Parameters queryStringParameters, Parameters uniqueParameters) { + private void addIfUnique(Map.Entry> parameter, Parameters queryStringParameters, + Parameters uniqueParameters) { if (!queryStringParameters.containsKey(parameter.getKey())) { uniqueParameters.put(parameter.getKey(), parameter.getValue()); } @@ -108,8 +108,7 @@ private static String urlEncodeUTF8(String s) { return URLEncoder.encode(s, "UTF-8"); } catch (UnsupportedEncodingException ex) { - throw new IllegalStateException("Unable to URL encode " + s + " using UTF-8", - ex); + throw new IllegalStateException("Unable to URL encode " + s + " using UTF-8", ex); } } diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/QueryStringParser.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/QueryStringParser.java index 850f19e14..f02563768 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/QueryStringParser.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/QueryStringParser.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2016 the original author or authors. + * Copyright 2014-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. @@ -71,8 +71,7 @@ private void processParameter(String parameter, Parameters parameters) { } } else { - throw new IllegalArgumentException( - "The parameter '" + parameter + "' is malformed"); + throw new IllegalArgumentException("The parameter '" + parameter + "' is malformed"); } } @@ -81,8 +80,7 @@ private String decode(String encoded) { return URLDecoder.decode(encoded, "UTF-8"); } catch (UnsupportedEncodingException ex) { - throw new IllegalStateException( - "Unable to URL encode " + encoded + " using UTF-8", ex); + throw new IllegalStateException("Unable to URL encode " + encoded + " using UTF-8", ex); } } diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/StandardOperation.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/StandardOperation.java index f11478cdd..14a62de2e 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/StandardOperation.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/StandardOperation.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2015 the original author or authors. + * Copyright 2014-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. @@ -40,8 +40,8 @@ public class StandardOperation implements Operation { * @param response the response that was received * @param attributes attributes to associate with the operation */ - public StandardOperation(String name, OperationRequest request, - OperationResponse response, Map attributes) { + public StandardOperation(String name, OperationRequest request, OperationResponse response, + Map attributes) { this.name = name; this.request = request; this.response = response; diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/StandardOperationRequest.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/StandardOperationRequest.java index 73199f1bf..204ab28f2 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/StandardOperationRequest.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/StandardOperationRequest.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-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. @@ -28,8 +28,7 @@ * * @author Andy Wilkinson */ -class StandardOperationRequest extends AbstractOperationMessage - implements OperationRequest { +class StandardOperationRequest extends AbstractOperationMessage implements OperationRequest { private HttpMethod method; @@ -53,8 +52,7 @@ class StandardOperationRequest extends AbstractOperationMessage * @param parts the parts * @param cookies the cookies */ - StandardOperationRequest(URI uri, HttpMethod method, byte[] content, - HttpHeaders headers, Parameters parameters, + StandardOperationRequest(URI uri, HttpMethod method, byte[] content, HttpHeaders headers, Parameters parameters, Collection parts, Collection cookies) { super(content, headers); this.uri = uri; diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/StandardOperationRequestPart.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/StandardOperationRequestPart.java index 0af3a838d..2a9e9b50e 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/StandardOperationRequestPart.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/StandardOperationRequestPart.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2015 the original author or authors. + * Copyright 2014-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. @@ -23,8 +23,7 @@ * * @author Andy Wilkinson */ -class StandardOperationRequestPart extends AbstractOperationMessage - implements OperationRequestPart { +class StandardOperationRequestPart extends AbstractOperationMessage implements OperationRequestPart { private final String name; @@ -37,8 +36,7 @@ class StandardOperationRequestPart extends AbstractOperationMessage * @param content the contents of the part * @param headers the headers of the part */ - StandardOperationRequestPart(String name, String submittedFileName, byte[] content, - HttpHeaders headers) { + StandardOperationRequestPart(String name, String submittedFileName, byte[] content, HttpHeaders headers) { super(content, headers); this.name = name; this.submittedFileName = submittedFileName; diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/StandardOperationResponse.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/StandardOperationResponse.java index 98f7829ec..6896245cd 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/StandardOperationResponse.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/StandardOperationResponse.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2015 the original author or authors. + * Copyright 2014-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. @@ -24,8 +24,7 @@ * * @author Andy Wilkinson */ -class StandardOperationResponse extends AbstractOperationMessage - implements OperationResponse { +class StandardOperationResponse extends AbstractOperationMessage implements OperationResponse { private final HttpStatus status; diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/preprocess/HeaderRemovingOperationPreprocessor.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/preprocess/HeaderRemovingOperationPreprocessor.java index d7602d1e7..4f0091ef9 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/preprocess/HeaderRemovingOperationPreprocessor.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/preprocess/HeaderRemovingOperationPreprocessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2017 the original author or authors. + * Copyright 2014-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. @@ -45,14 +45,12 @@ class HeaderRemovingOperationPreprocessor implements OperationPreprocessor { @Override public OperationResponse preprocess(OperationResponse response) { - return this.responseFactory.createFrom(response, - removeHeaders(response.getHeaders())); + return this.responseFactory.createFrom(response, removeHeaders(response.getHeaders())); } @Override public OperationRequest preprocess(OperationRequest request) { - return this.requestFactory.createFrom(request, - removeHeaders(request.getHeaders())); + return this.requestFactory.createFrom(request, removeHeaders(request.getHeaders())); } private HttpHeaders removeHeaders(HttpHeaders originalHeaders) { diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/preprocess/LinkMaskingContentModifier.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/preprocess/LinkMaskingContentModifier.java index 9d9b95c88..7eea97aac 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/preprocess/LinkMaskingContentModifier.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/preprocess/LinkMaskingContentModifier.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2015 the original author or authors. + * Copyright 2014-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. @@ -29,8 +29,7 @@ class LinkMaskingContentModifier implements ContentModifier { private static final String DEFAULT_MASK = "..."; - private static final Pattern LINK_HREF = Pattern.compile("\"href\"\\s*:\\s*\"(.*?)\"", - Pattern.DOTALL); + private static final Pattern LINK_HREF = Pattern.compile("\"href\"\\s*:\\s*\"(.*?)\"", Pattern.DOTALL); private final ContentModifier contentModifier; diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/preprocess/ParametersModifyingOperationPreprocessor.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/preprocess/ParametersModifyingOperationPreprocessor.java index 4bf86db55..943213434 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/preprocess/ParametersModifyingOperationPreprocessor.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/preprocess/ParametersModifyingOperationPreprocessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2016 the original author or authors. + * Copyright 2014-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. @@ -32,8 +32,7 @@ * @author Andy Wilkinson * @since 1.1.0 */ -public final class ParametersModifyingOperationPreprocessor - extends OperationPreprocessorAdapter { +public final class ParametersModifyingOperationPreprocessor extends OperationPreprocessorAdapter { private final OperationRequestFactory requestFactory = new OperationRequestFactory(); diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/preprocess/Preprocessors.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/preprocess/Preprocessors.java index 5c1d61d0a..1bb43eff8 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/preprocess/Preprocessors.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/preprocess/Preprocessors.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2015 the original author or authors. + * Copyright 2014-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. @@ -44,8 +44,7 @@ private Preprocessors() { * @param preprocessors the preprocessors * @return the request preprocessor */ - public static OperationRequestPreprocessor preprocessRequest( - OperationPreprocessor... preprocessors) { + public static OperationRequestPreprocessor preprocessRequest(OperationPreprocessor... preprocessors) { return new DelegatingOperationRequestPreprocessor(Arrays.asList(preprocessors)); } @@ -55,8 +54,7 @@ public static OperationRequestPreprocessor preprocessRequest( * @param preprocessors the preprocessors * @return the response preprocessor */ - public static OperationResponsePreprocessor preprocessResponse( - OperationPreprocessor... preprocessors) { + public static OperationResponsePreprocessor preprocessResponse(OperationPreprocessor... preprocessors) { return new DelegatingOperationResponsePreprocessor(Arrays.asList(preprocessors)); } @@ -66,8 +64,7 @@ public static OperationResponsePreprocessor preprocessResponse( * @return the preprocessor */ public static OperationPreprocessor prettyPrint() { - return new ContentModifyingOperationPreprocessor( - new PrettyPrintingContentModifier()); + return new ContentModifyingOperationPreprocessor(new PrettyPrintingContentModifier()); } /** @@ -79,8 +76,7 @@ public static OperationPreprocessor prettyPrint() { * @see String#equals(Object) */ public static OperationPreprocessor removeHeaders(String... headerNames) { - return new HeaderRemovingOperationPreprocessor( - new ExactMatchHeaderFilter(headerNames)); + return new HeaderRemovingOperationPreprocessor(new ExactMatchHeaderFilter(headerNames)); } /** @@ -91,10 +87,8 @@ public static OperationPreprocessor removeHeaders(String... headerNames) { * @return the preprocessor * @see java.util.regex.Matcher#matches() */ - public static OperationPreprocessor removeMatchingHeaders( - String... headerNamePatterns) { - return new HeaderRemovingOperationPreprocessor( - new PatternMatchHeaderFilter(headerNamePatterns)); + public static OperationPreprocessor removeMatchingHeaders(String... headerNamePatterns) { + return new HeaderRemovingOperationPreprocessor(new PatternMatchHeaderFilter(headerNamePatterns)); } /** @@ -103,8 +97,7 @@ public static OperationPreprocessor removeMatchingHeaders( * @return the preprocessor */ public static OperationPreprocessor maskLinks() { - return new ContentModifyingOperationPreprocessor( - new LinkMaskingContentModifier()); + return new ContentModifyingOperationPreprocessor(new LinkMaskingContentModifier()); } /** @@ -114,8 +107,7 @@ public static OperationPreprocessor maskLinks() { * @return the preprocessor */ public static OperationPreprocessor maskLinks(String mask) { - return new ContentModifyingOperationPreprocessor( - new LinkMaskingContentModifier(mask)); + return new ContentModifyingOperationPreprocessor(new LinkMaskingContentModifier(mask)); } /** @@ -126,10 +118,8 @@ public static OperationPreprocessor maskLinks(String mask) { * @param replacement the replacement * @return the preprocessor */ - public static OperationPreprocessor replacePattern(Pattern pattern, - String replacement) { - return new ContentModifyingOperationPreprocessor( - new PatternReplacingContentModifier(pattern, replacement)); + public static OperationPreprocessor replacePattern(Pattern pattern, String replacement) { + return new ContentModifyingOperationPreprocessor(new PatternReplacingContentModifier(pattern, replacement)); } /** diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/preprocess/PrettyPrintingContentModifier.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/preprocess/PrettyPrintingContentModifier.java index c38c5ff50..dff8f1d38 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/preprocess/PrettyPrintingContentModifier.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/preprocess/PrettyPrintingContentModifier.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2017 the original author or authors. + * Copyright 2014-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. @@ -52,8 +52,7 @@ public class PrettyPrintingContentModifier implements ContentModifier { private static final List PRETTY_PRINTERS = Collections - .unmodifiableList( - Arrays.asList(new JsonPrettyPrinter(), new XmlPrettyPrinter())); + .unmodifiableList(Arrays.asList(new JsonPrettyPrinter(), new XmlPrettyPrinter())); @Override public byte[] modifyContent(byte[] originalContent, MediaType contentType) { @@ -82,44 +81,37 @@ private static final class XmlPrettyPrinter implements PrettyPrinter { public byte[] prettyPrint(byte[] original) throws Exception { Transformer transformer = TransformerFactory.newInstance().newTransformer(); transformer.setOutputProperty(OutputKeys.INDENT, "yes"); - transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", - "4"); + transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4"); transformer.setOutputProperty(OutputKeys.DOCTYPE_PUBLIC, "yes"); ByteArrayOutputStream transformed = new ByteArrayOutputStream(); transformer.setErrorListener(new SilentErrorListener()); - transformer.transform(createSaxSource(original), - new StreamResult(transformed)); + transformer.transform(createSaxSource(original), new StreamResult(transformed)); return transformed.toByteArray(); } - private SAXSource createSaxSource(byte[] original) - throws ParserConfigurationException, SAXException { + private SAXSource createSaxSource(byte[] original) throws ParserConfigurationException, SAXException { SAXParserFactory parserFactory = SAXParserFactory.newInstance(); SAXParser parser = parserFactory.newSAXParser(); XMLReader xmlReader = parser.getXMLReader(); xmlReader.setErrorHandler(new SilentErrorHandler()); - return new SAXSource(xmlReader, - new InputSource(new ByteArrayInputStream(original))); + return new SAXSource(xmlReader, new InputSource(new ByteArrayInputStream(original))); } private static final class SilentErrorListener implements ErrorListener { @Override - public void warning(TransformerException exception) - throws TransformerException { + public void warning(TransformerException exception) throws TransformerException { // Suppress } @Override - public void error(TransformerException exception) - throws TransformerException { + public void error(TransformerException exception) throws TransformerException { // Suppress } @Override - public void fatalError(TransformerException exception) - throws TransformerException { + public void fatalError(TransformerException exception) throws TransformerException { // Suppress } @@ -148,13 +140,12 @@ public void fatalError(SAXParseException exception) throws SAXException { private static final class JsonPrettyPrinter implements PrettyPrinter { - private final ObjectMapper objectMapper = new ObjectMapper() - .configure(SerializationFeature.INDENT_OUTPUT, true); + private final ObjectMapper objectMapper = new ObjectMapper().configure(SerializationFeature.INDENT_OUTPUT, + true); @Override public byte[] prettyPrint(byte[] original) throws IOException { - return this.objectMapper - .writeValueAsBytes(this.objectMapper.readTree(original)); + return this.objectMapper.writeValueAsBytes(this.objectMapper.readTree(original)); } } diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/AbstractBodySnippet.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/AbstractBodySnippet.java index 431103acd..f9895e897 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/AbstractBodySnippet.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/AbstractBodySnippet.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-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. @@ -46,8 +46,7 @@ public abstract class AbstractBodySnippet extends TemplatedSnippet { * @param subsectionExtractor the subsection extractor * @param attributes the attributes */ - protected AbstractBodySnippet(String type, - PayloadSubsectionExtractor subsectionExtractor, + protected AbstractBodySnippet(String type, PayloadSubsectionExtractor subsectionExtractor, Map attributes) { this(type, type, subsectionExtractor, attributes); } @@ -63,12 +62,9 @@ protected AbstractBodySnippet(String type, * @param subsectionExtractor the subsection extractor * @param attributes the attributes */ - protected AbstractBodySnippet(String name, String type, - PayloadSubsectionExtractor subsectionExtractor, + protected AbstractBodySnippet(String name, String type, PayloadSubsectionExtractor subsectionExtractor, Map attributes) { - super(name + "-body" - + ((subsectionExtractor != null) - ? "-" + subsectionExtractor.getSubsectionId() : ""), + super(name + "-body" + ((subsectionExtractor != null) ? "-" + subsectionExtractor.getSubsectionId() : ""), type + "-body", attributes); this.subsectionExtractor = subsectionExtractor; } @@ -79,12 +75,10 @@ protected Map createModel(Operation operation) { MediaType contentType = getContentType(operation); byte[] content = getContent(operation); if (this.subsectionExtractor != null) { - content = this.subsectionExtractor.extractSubsection(content, - contentType); + content = this.subsectionExtractor.extractSubsection(content, contentType); } Charset charset = extractCharset(contentType); - String body = (charset != null) ? new String(content, charset) - : new String(content); + String body = (charset != null) ? new String(content, charset) : new String(content); Map model = new HashMap<>(); model.put("body", body); return model; diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/AbstractFieldsSnippet.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/AbstractFieldsSnippet.java index 57b8518c7..fbe08ca8c 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/AbstractFieldsSnippet.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/AbstractFieldsSnippet.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-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. @@ -61,8 +61,7 @@ public abstract class AbstractFieldsSnippet extends TemplatedSnippet { * {@link #AbstractFieldsSnippet(String, List, Map, boolean)} */ @Deprecated - protected AbstractFieldsSnippet(String type, List descriptors, - Map attributes) { + protected AbstractFieldsSnippet(String type, List descriptors, Map attributes) { this(type, descriptors, attributes, false); } @@ -78,8 +77,8 @@ protected AbstractFieldsSnippet(String type, List descriptors, * @param attributes the additional attributes * @param ignoreUndocumentedFields whether undocumented fields should be ignored */ - protected AbstractFieldsSnippet(String type, List descriptors, - Map attributes, boolean ignoreUndocumentedFields) { + protected AbstractFieldsSnippet(String type, List descriptors, Map attributes, + boolean ignoreUndocumentedFields) { this(type, type, descriptors, attributes, ignoreUndocumentedFields); } @@ -98,11 +97,9 @@ protected AbstractFieldsSnippet(String type, List descriptors, * @param subsectionExtractor the subsection extractor * @since 1.2.0 */ - protected AbstractFieldsSnippet(String type, List descriptors, - Map attributes, boolean ignoreUndocumentedFields, - PayloadSubsectionExtractor subsectionExtractor) { - this(type, type, descriptors, attributes, ignoreUndocumentedFields, - subsectionExtractor); + protected AbstractFieldsSnippet(String type, List descriptors, Map attributes, + boolean ignoreUndocumentedFields, PayloadSubsectionExtractor subsectionExtractor) { + this(type, type, descriptors, attributes, ignoreUndocumentedFields, subsectionExtractor); } /** @@ -118,9 +115,8 @@ protected AbstractFieldsSnippet(String type, List descriptors, * @param attributes the additional attributes * @param ignoreUndocumentedFields whether undocumented fields should be ignored */ - protected AbstractFieldsSnippet(String name, String type, - List descriptors, Map attributes, - boolean ignoreUndocumentedFields) { + protected AbstractFieldsSnippet(String name, String type, List descriptors, + Map attributes, boolean ignoreUndocumentedFields) { this(name, type, descriptors, attributes, ignoreUndocumentedFields, null); } @@ -141,20 +137,16 @@ protected AbstractFieldsSnippet(String name, String type, * empty string can be used to indicate that the entire payload should be documented. * @since 1.2.0 */ - protected AbstractFieldsSnippet(String name, String type, - List descriptors, Map attributes, - boolean ignoreUndocumentedFields, + protected AbstractFieldsSnippet(String name, String type, List descriptors, + Map attributes, boolean ignoreUndocumentedFields, PayloadSubsectionExtractor subsectionExtractor) { - super(name + "-fields" - + ((subsectionExtractor != null) - ? "-" + subsectionExtractor.getSubsectionId() : ""), + super(name + "-fields" + ((subsectionExtractor != null) ? "-" + subsectionExtractor.getSubsectionId() : ""), type + "-fields", attributes); for (FieldDescriptor descriptor : descriptors) { Assert.notNull(descriptor.getPath(), "Field descriptors must have a path"); if (!descriptor.isIgnored()) { - Assert.notNull(descriptor.getDescription() != null, - "The descriptor for '" + descriptor.getPath() + "' must have a" - + " description or it must be marked as ignored"); + Assert.notNull(descriptor.getDescription() != null, "The descriptor for '" + descriptor.getPath() + + "' must have a" + " description or it must be marked as ignored"); } } this.fieldDescriptors = descriptors; @@ -174,8 +166,7 @@ protected Map createModel(Operation operation) { } MediaType contentType = getContentType(operation); if (this.subsectionExtractor != null) { - content = verifyContent( - this.subsectionExtractor.extractSubsection(content, contentType)); + content = verifyContent(this.subsectionExtractor.extractSubsection(content, contentType)); } ContentHandler contentHandler = getContentHandler(content, contentType); @@ -189,9 +180,8 @@ protected Map createModel(Operation operation) { descriptorsToDocument.add(copyWithType(descriptor, type)); } catch (FieldDoesNotExistException ex) { - String message = "Cannot determine the type of the field '" - + descriptor.getPath() + "' as it is not present in the " - + "payload. Please provide a type using " + String message = "Cannot determine the type of the field '" + descriptor.getPath() + + "' as it is not present in the " + "payload. Please provide a type using " + "FieldDescriptor.type(Object type)."; throw new FieldTypeRequiredException(message); } @@ -211,8 +201,8 @@ protected Map createModel(Operation operation) { private byte[] verifyContent(byte[] content) { if (content.length == 0) { - throw new SnippetException("Cannot document " + this.type + " fields as the " - + this.type + " body is empty"); + throw new SnippetException( + "Cannot document " + this.type + " fields as the " + this.type + " body is empty"); } return content; } @@ -222,8 +212,8 @@ private ContentHandler getContentHandler(byte[] content, MediaType contentType) if (contentHandler == null) { contentHandler = createXmlContentHandler(content); if (contentHandler == null) { - throw new PayloadHandlingException("Cannot handle " + contentType - + " content as it could not be parsed as JSON or XML"); + throw new PayloadHandlingException( + "Cannot handle " + contentType + " content as it could not be parsed as JSON or XML"); } } return contentHandler; @@ -248,8 +238,7 @@ private ContentHandler createXmlContentHandler(byte[] content) { } private void validateFieldDocumentation(ContentHandler payloadHandler) { - List missingFields = payloadHandler - .findMissingFields(this.fieldDescriptors); + List missingFields = payloadHandler.findMissingFields(this.fieldDescriptors); String undocumentedPayload = this.ignoreUndocumentedFields ? null : payloadHandler.getUndocumentedContent(this.fieldDescriptors); @@ -257,8 +246,8 @@ private void validateFieldDocumentation(ContentHandler payloadHandler) { if (!missingFields.isEmpty() || StringUtils.hasText(undocumentedPayload)) { String message = ""; if (StringUtils.hasText(undocumentedPayload)) { - message += String.format("The following parts of the payload were" - + " not documented:%n%s", undocumentedPayload); + message += String.format("The following parts of the payload were" + " not documented:%n%s", + undocumentedPayload); } if (!missingFields.isEmpty()) { if (message.length() > 0) { @@ -268,8 +257,7 @@ private void validateFieldDocumentation(ContentHandler payloadHandler) { for (FieldDescriptor fieldDescriptor : missingFields) { paths.add(fieldDescriptor.getPath()); } - message += "Fields with the following paths were not found in the" - + " payload: " + paths; + message += "Fields with the following paths were not found in the" + " payload: " + paths; } throw new SnippetException(message); } @@ -334,11 +322,9 @@ protected Map createModelForDescriptor(FieldDescriptor descripto } private FieldDescriptor copyWithType(FieldDescriptor source, Object type) { - FieldDescriptor result = (source instanceof SubsectionDescriptor) - ? new SubsectionDescriptor(source.getPath()) + FieldDescriptor result = (source instanceof SubsectionDescriptor) ? new SubsectionDescriptor(source.getPath()) : new FieldDescriptor(source.getPath()); - result.description(source.getDescription()).type(type) - .attributes(asArray(source.getAttributes())); + result.description(source.getDescription()).type(type).attributes(asArray(source.getAttributes())); if (source.isIgnored()) { result.ignored(); } @@ -351,8 +337,7 @@ private FieldDescriptor copyWithType(FieldDescriptor source, Object type) { private static Attribute[] asArray(Map attributeMap) { List attributes = new ArrayList<>(); for (Map.Entry attribute : attributeMap.entrySet()) { - attributes - .add(Attributes.key(attribute.getKey()).value(attribute.getValue())); + attributes.add(Attributes.key(attribute.getKey()).value(attribute.getValue())); } return attributes.toArray(new Attribute[attributes.size()]); } diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/FieldPathPayloadSubsectionExtractor.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/FieldPathPayloadSubsectionExtractor.java index 251e4ad39..a4afda246 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/FieldPathPayloadSubsectionExtractor.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/FieldPathPayloadSubsectionExtractor.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-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. @@ -72,13 +72,12 @@ protected FieldPathPayloadSubsectionExtractor(String fieldPath, String subsectio @Override public byte[] extractSubsection(byte[] payload, MediaType contentType) { try { - ExtractedField extractedField = new JsonFieldProcessor().extract( - this.fieldPath, objectMapper.readValue(payload, Object.class)); + ExtractedField extractedField = new JsonFieldProcessor().extract(this.fieldPath, + objectMapper.readValue(payload, Object.class)); Object value = extractedField.getValue(); if (value instanceof List) { List extractedList = (List) value; - Set uncommonPaths = JsonFieldPaths.from(extractedList) - .getUncommon(); + Set uncommonPaths = JsonFieldPaths.from(extractedList).getUncommon(); if (uncommonPaths.isEmpty()) { value = extractedList.get(0); } diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/FieldTypesDoNotMatchException.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/FieldTypesDoNotMatchException.java index 1713ef287..477a1900b 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/FieldTypesDoNotMatchException.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/FieldTypesDoNotMatchException.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2016 the original author or authors. + * Copyright 2014-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. @@ -31,8 +31,8 @@ class FieldTypesDoNotMatchException extends RuntimeException { * @param actualType the actual type of the field */ FieldTypesDoNotMatchException(FieldDescriptor fieldDescriptor, Object actualType) { - super("The documented type of the field '" + fieldDescriptor.getPath() + "' is " - + fieldDescriptor.getType() + " but the actual type is " + actualType); + super("The documented type of the field '" + fieldDescriptor.getPath() + "' is " + fieldDescriptor.getType() + + " but the actual type is " + actualType); } } diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/JsonContentHandler.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/JsonContentHandler.java index d4637123c..4f14ce881 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/JsonContentHandler.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/JsonContentHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-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. @@ -39,8 +39,7 @@ class JsonContentHandler implements ContentHandler { private final JsonFieldTypeResolver fieldTypeResolver = new JsonFieldTypeResolver(); - private final ObjectMapper objectMapper = new ObjectMapper() - .enable(SerializationFeature.INDENT_OUTPUT); + private final ObjectMapper objectMapper = new ObjectMapper().enable(SerializationFeature.INDENT_OUTPUT); private final byte[] rawContent; @@ -50,15 +49,12 @@ class JsonContentHandler implements ContentHandler { } @Override - public List findMissingFields( - List fieldDescriptors) { + public List findMissingFields(List fieldDescriptors) { List missingFields = new ArrayList<>(); Object payload = readContent(); for (FieldDescriptor fieldDescriptor : fieldDescriptors) { - if (!fieldDescriptor.isOptional() - && !this.fieldProcessor.hasField(fieldDescriptor.getPath(), payload) - && !isNestedBeneathMissingOptionalField(fieldDescriptor, - fieldDescriptors, payload)) { + if (!fieldDescriptor.isOptional() && !this.fieldProcessor.hasField(fieldDescriptor.getPath(), payload) + && !isNestedBeneathMissingOptionalField(fieldDescriptor, fieldDescriptors, payload)) { missingFields.add(fieldDescriptor); } } @@ -66,13 +62,12 @@ public List findMissingFields( return missingFields; } - private boolean isNestedBeneathMissingOptionalField(FieldDescriptor missing, - List fieldDescriptors, Object payload) { + private boolean isNestedBeneathMissingOptionalField(FieldDescriptor missing, List fieldDescriptors, + Object payload) { List candidates = new ArrayList<>(fieldDescriptors); candidates.remove(missing); for (FieldDescriptor candidate : candidates) { - if (candidate.isOptional() - && missing.getPath().startsWith(candidate.getPath()) + if (candidate.isOptional() && missing.getPath().startsWith(candidate.getPath()) && isMissing(candidate, payload)) { return true; } @@ -84,8 +79,7 @@ private boolean isMissing(FieldDescriptor candidate, Object payload) { if (!this.fieldProcessor.hasField(candidate.getPath(), payload)) { return true; } - ExtractedField extracted = this.fieldProcessor.extract(candidate.getPath(), - payload); + ExtractedField extracted = this.fieldProcessor.extract(candidate.getPath(), payload); return extracted.getValue() == null || isEmptyCollection(extracted.getValue()); } @@ -147,20 +141,16 @@ private boolean isEmpty(Object object) { @Override public Object determineFieldType(FieldDescriptor fieldDescriptor) { if (fieldDescriptor.getType() == null) { - return this.fieldTypeResolver.resolveFieldType(fieldDescriptor, - readContent()); + return this.fieldTypeResolver.resolveFieldType(fieldDescriptor, readContent()); } if (!(fieldDescriptor.getType() instanceof JsonFieldType)) { return fieldDescriptor.getType(); } JsonFieldType descriptorFieldType = (JsonFieldType) fieldDescriptor.getType(); try { - JsonFieldType actualFieldType = this.fieldTypeResolver - .resolveFieldType(fieldDescriptor, readContent()); - if (descriptorFieldType == JsonFieldType.VARIES - || descriptorFieldType == actualFieldType - || (fieldDescriptor.isOptional() - && actualFieldType == JsonFieldType.NULL)) { + JsonFieldType actualFieldType = this.fieldTypeResolver.resolveFieldType(fieldDescriptor, readContent()); + if (descriptorFieldType == JsonFieldType.VARIES || descriptorFieldType == actualFieldType + || (fieldDescriptor.isOptional() && actualFieldType == JsonFieldType.NULL)) { return descriptorFieldType; } throw new FieldTypesDoNotMatchException(fieldDescriptor, actualFieldType); diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/JsonFieldPath.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/JsonFieldPath.java index 3da92e422..43c066848 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/JsonFieldPath.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/JsonFieldPath.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-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. @@ -33,8 +33,7 @@ final class JsonFieldPath { private static final Pattern BRACKETS_AND_ARRAY_PATTERN = Pattern .compile("\\[\'(.+?)\'\\]|\\[([0-9]+|\\*){0,1}\\]"); - private static final Pattern ARRAY_INDEX_PATTERN = Pattern - .compile("\\[([0-9]+|\\*){0,1}\\]"); + private static final Pattern ARRAY_INDEX_PATTERN = Pattern.compile("\\[([0-9]+|\\*){0,1}\\]"); private final String rawPath; @@ -63,8 +62,7 @@ public String toString() { static JsonFieldPath compile(String path) { List segments = extractSegments(path); - return new JsonFieldPath(path, segments, - matchesSingleValue(segments) ? PathType.SINGLE : PathType.MULTI); + return new JsonFieldPath(path, segments, matchesSingleValue(segments) ? PathType.SINGLE : PathType.MULTI); } static boolean isArraySegment(String segment) { @@ -75,8 +73,7 @@ static boolean matchesSingleValue(List segments) { Iterator iterator = segments.iterator(); while (iterator.hasNext()) { String segment = iterator.next(); - if ((isArraySegment(segment) && iterator.hasNext()) - || isWildcardSegment(segment)) { + if ((isArraySegment(segment) && iterator.hasNext()) || isWildcardSegment(segment)) { return false; } } @@ -95,8 +92,7 @@ private static List extractSegments(String path) { List segments = new ArrayList<>(); while (matcher.find()) { if (previous != matcher.start()) { - segments.addAll(extractDotSeparatedSegments( - path.substring(previous, matcher.start()))); + segments.addAll(extractDotSeparatedSegments(path.substring(previous, matcher.start()))); } if (matcher.group(1) != null) { segments.add(matcher.group(1)); diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/JsonFieldProcessor.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/JsonFieldProcessor.java index 417f62b59..61caf185e 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/JsonFieldProcessor.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/JsonFieldProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-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. @@ -58,43 +58,40 @@ public void absent() { if (matches.isEmpty()) { throw new FieldDoesNotExistException(path); } - return new ExtractedField( - (compiledPath.getType() != PathType.SINGLE) ? matches : matches.get(0), + return new ExtractedField((compiledPath.getType() != PathType.SINGLE) ? matches : matches.get(0), compiledPath.getType()); } void remove(String path, Object payload) { - traverse(new ProcessingContext(payload, JsonFieldPath.compile(path)), - new MatchCallback() { + traverse(new ProcessingContext(payload, JsonFieldPath.compile(path)), new MatchCallback() { - @Override - public void foundMatch(Match match) { - match.remove(); - } + @Override + public void foundMatch(Match match) { + match.remove(); + } - @Override - public void absent() { + @Override + public void absent() { - } + } - }); + }); } void removeSubsection(String path, Object payload) { - traverse(new ProcessingContext(payload, JsonFieldPath.compile(path)), - new MatchCallback() { + traverse(new ProcessingContext(payload, JsonFieldPath.compile(path)), new MatchCallback() { - @Override - public void foundMatch(Match match) { - match.removeSubsection(); - } + @Override + public void foundMatch(Match match) { + match.removeSubsection(); + } - @Override - public void absent() { + @Override + public void absent() { - } + } - }); + }); } private void traverse(ProcessingContext context, MatchCallback matchCallback) { @@ -109,54 +106,48 @@ else if (context.getPayload() instanceof Map) { } } - private void handleCollectionPayload(ProcessingContext context, - MatchCallback matchCallback) { - handleCollectionPayload((Collection) context.getPayload(), matchCallback, - context); + private void handleCollectionPayload(ProcessingContext context, MatchCallback matchCallback) { + handleCollectionPayload((Collection) context.getPayload(), matchCallback, context); } - private void handleCollectionPayload(Collection collection, - MatchCallback matchCallback, ProcessingContext context) { + private void handleCollectionPayload(Collection collection, MatchCallback matchCallback, + ProcessingContext context) { if (context.isLeaf()) { - matchCallback.foundMatch( - new LeafCollectionMatch(collection, context.getParentMatch())); + matchCallback.foundMatch(new LeafCollectionMatch(collection, context.getParentMatch())); } else { Iterator items = collection.iterator(); while (items.hasNext()) { Object item = items.next(); - traverse(context.descend(item, new CollectionMatch(items, collection, - item, context.getParentMatch())), matchCallback); + traverse(context.descend(item, new CollectionMatch(items, collection, item, context.getParentMatch())), + matchCallback); } } } - private void handleWildcardPayload(Collection collection, - MatchCallback matchCallback, ProcessingContext context) { + private void handleWildcardPayload(Collection collection, MatchCallback matchCallback, + ProcessingContext context) { Iterator items = collection.iterator(); if (context.isLeaf()) { while (items.hasNext()) { Object item = items.next(); - matchCallback.foundMatch(new CollectionMatch(items, collection, item, - context.getParentMatch())); + matchCallback.foundMatch(new CollectionMatch(items, collection, item, context.getParentMatch())); } } else { while (items.hasNext()) { Object item = items.next(); - traverse(context.descend(item, new CollectionMatch(items, collection, - item, context.getParentMatch())), matchCallback); + traverse(context.descend(item, new CollectionMatch(items, collection, item, context.getParentMatch())), + matchCallback); } } } - private void handleMapPayload(ProcessingContext context, - MatchCallback matchCallback) { + private void handleMapPayload(ProcessingContext context, MatchCallback matchCallback) { Map map = context.getPayload(); if (map.containsKey(context.getSegment())) { Object item = map.get(context.getSegment()); - MapMatch mapMatch = new MapMatch(item, map, context.getSegment(), - context.getParentMatch()); + MapMatch mapMatch = new MapMatch(item, map, context.getSegment(), context.getParentMatch()); if (context.isLeaf()) { matchCallback.foundMatch(mapMatch); } @@ -181,8 +172,8 @@ private static final class HasFieldMatchCallback implements MatchCallback { @Override public void foundMatch(Match match) { - this.matchType = this.matchType.combinedWith( - (match.getValue() != null) ? MatchType.NON_NULL : MatchType.NULL); + this.matchType = this.matchType + .combinedWith((match.getValue() != null) ? MatchType.NON_NULL : MatchType.NULL); } @Override @@ -191,8 +182,7 @@ public void absent() { } boolean fieldFound() { - return this.matchType == MatchType.NON_NULL - || this.matchType == MatchType.NULL; + return this.matchType == MatchType.NON_NULL || this.matchType == MatchType.NULL; } private enum MatchType { @@ -235,8 +225,7 @@ public Object getValue() { @Override public void remove() { Object removalCandidate = this.map.get(this.segment); - if (isMapWithEntries(removalCandidate) - || isCollectionWithNonScalarEntries(removalCandidate)) { + if (isMapWithEntries(removalCandidate) || isCollectionWithNonScalarEntries(removalCandidate)) { return; } this.map.remove(this.segment); @@ -281,8 +270,7 @@ private static final class CollectionMatch implements Match { private final Match parent; - private CollectionMatch(Iterator items, Collection collection, Object item, - Match parent) { + private CollectionMatch(Iterator items, Collection collection, Object item, Match parent) { this.items = items; this.collection = collection; this.item = item; @@ -404,8 +392,7 @@ private ProcessingContext(Object payload, JsonFieldPath path) { this(payload, path, null, null); } - private ProcessingContext(Object payload, JsonFieldPath path, - List segments, Match parent) { + private ProcessingContext(Object payload, JsonFieldPath path, List segments, Match parent) { this.payload = payload; this.path = path; this.segments = (segments != null) ? segments : path.getSegments(); @@ -430,8 +417,7 @@ private Match getParentMatch() { } private ProcessingContext descend(Object payload, Match match) { - return new ProcessingContext(payload, this.path, - this.segments.subList(1, this.segments.size()), match); + return new ProcessingContext(payload, this.path, this.segments.subList(1, this.segments.size()), match); } } diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/JsonFieldTypeResolver.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/JsonFieldTypeResolver.java index ccde3bad4..510dcbb9d 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/JsonFieldTypeResolver.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/JsonFieldTypeResolver.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2017 the original author or authors. + * Copyright 2014-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. @@ -32,8 +32,7 @@ class JsonFieldTypeResolver { private final JsonFieldProcessor fieldProcessor = new JsonFieldProcessor(); JsonFieldType resolveFieldType(FieldDescriptor fieldDescriptor, Object payload) { - ExtractedField extractedField = this.fieldProcessor - .extract(fieldDescriptor.getPath(), payload); + ExtractedField extractedField = this.fieldProcessor.extract(fieldDescriptor.getPath(), payload); Object value = extractedField.getValue(); if (value instanceof Collection && extractedField.getType() == PathType.MULTI) { JsonFieldType commonType = null; diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/PayloadDocumentation.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/PayloadDocumentation.java index 7c3e917b4..205f2584f 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/PayloadDocumentation.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/PayloadDocumentation.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-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. @@ -228,8 +228,7 @@ public static RequestFieldsSnippet requestFields(List descripto * @see #fieldWithPath(String) * @see #subsectionWithPath(String) */ - public static RequestFieldsSnippet relaxedRequestFields( - FieldDescriptor... descriptors) { + public static RequestFieldsSnippet relaxedRequestFields(FieldDescriptor... descriptors) { return relaxedRequestFields(Arrays.asList(descriptors)); } @@ -244,8 +243,7 @@ public static RequestFieldsSnippet relaxedRequestFields( * @see #fieldWithPath(String) * @see #subsectionWithPath(String) */ - public static RequestFieldsSnippet relaxedRequestFields( - List descriptors) { + public static RequestFieldsSnippet relaxedRequestFields(List descriptors) { return new RequestFieldsSnippet(descriptors, true); } @@ -271,8 +269,7 @@ public static RequestFieldsSnippet relaxedRequestFields( * @see #fieldWithPath(String) * @see #subsectionWithPath(String) */ - public static RequestFieldsSnippet requestFields(Map attributes, - FieldDescriptor... descriptors) { + public static RequestFieldsSnippet requestFields(Map attributes, FieldDescriptor... descriptors) { return requestFields(attributes, Arrays.asList(descriptors)); } @@ -316,8 +313,8 @@ public static RequestFieldsSnippet requestFields(Map attributes, * @see #fieldWithPath(String) * @see #subsectionWithPath(String) */ - public static RequestFieldsSnippet relaxedRequestFields( - Map attributes, FieldDescriptor... descriptors) { + public static RequestFieldsSnippet relaxedRequestFields(Map attributes, + FieldDescriptor... descriptors) { return relaxedRequestFields(attributes, Arrays.asList(descriptors)); } @@ -334,8 +331,8 @@ public static RequestFieldsSnippet relaxedRequestFields( * @see #fieldWithPath(String) * @see #subsectionWithPath(String) */ - public static RequestFieldsSnippet relaxedRequestFields( - Map attributes, List descriptors) { + public static RequestFieldsSnippet relaxedRequestFields(Map attributes, + List descriptors) { return new RequestFieldsSnippet(descriptors, attributes, true); } @@ -364,8 +361,7 @@ public static RequestFieldsSnippet relaxedRequestFields( * @see #subsectionWithPath(String) * @see #beneathPath(String) */ - public static RequestFieldsSnippet requestFields( - PayloadSubsectionExtractor subsectionExtractor, + public static RequestFieldsSnippet requestFields(PayloadSubsectionExtractor subsectionExtractor, FieldDescriptor... descriptors) { return requestFields(subsectionExtractor, Arrays.asList(descriptors)); } @@ -395,8 +391,7 @@ public static RequestFieldsSnippet requestFields( * @see #subsectionWithPath(String) * @see #beneathPath(String) */ - public static RequestFieldsSnippet requestFields( - PayloadSubsectionExtractor subsectionExtractor, + public static RequestFieldsSnippet requestFields(PayloadSubsectionExtractor subsectionExtractor, List descriptors) { return new RequestFieldsSnippet(subsectionExtractor, descriptors); } @@ -416,8 +411,7 @@ public static RequestFieldsSnippet requestFields( * @see #subsectionWithPath(String) * @see #beneathPath(String) */ - public static RequestFieldsSnippet relaxedRequestFields( - PayloadSubsectionExtractor subsectionExtractor, + public static RequestFieldsSnippet relaxedRequestFields(PayloadSubsectionExtractor subsectionExtractor, FieldDescriptor... descriptors) { return relaxedRequestFields(subsectionExtractor, Arrays.asList(descriptors)); } @@ -437,8 +431,7 @@ public static RequestFieldsSnippet relaxedRequestFields( * @see #subsectionWithPath(String) * @see #beneathPath(String) */ - public static RequestFieldsSnippet relaxedRequestFields( - PayloadSubsectionExtractor subsectionExtractor, + public static RequestFieldsSnippet relaxedRequestFields(PayloadSubsectionExtractor subsectionExtractor, List descriptors) { return new RequestFieldsSnippet(subsectionExtractor, descriptors, true); } @@ -470,8 +463,7 @@ public static RequestFieldsSnippet relaxedRequestFields( * @see #subsectionWithPath(String) * @see #beneathPath(String) */ - public static RequestFieldsSnippet requestFields( - PayloadSubsectionExtractor subsectionExtractor, + public static RequestFieldsSnippet requestFields(PayloadSubsectionExtractor subsectionExtractor, Map attributes, FieldDescriptor... descriptors) { return requestFields(subsectionExtractor, attributes, Arrays.asList(descriptors)); } @@ -503,8 +495,7 @@ public static RequestFieldsSnippet requestFields( * @see #subsectionWithPath(String) * @see #beneathPath(String) */ - public static RequestFieldsSnippet requestFields( - PayloadSubsectionExtractor subsectionExtractor, + public static RequestFieldsSnippet requestFields(PayloadSubsectionExtractor subsectionExtractor, Map attributes, List descriptors) { return new RequestFieldsSnippet(subsectionExtractor, descriptors, attributes); } @@ -526,11 +517,9 @@ public static RequestFieldsSnippet requestFields( * @see #subsectionWithPath(String) * @see #beneathPath(String) */ - public static RequestFieldsSnippet relaxedRequestFields( - PayloadSubsectionExtractor subsectionExtractor, + public static RequestFieldsSnippet relaxedRequestFields(PayloadSubsectionExtractor subsectionExtractor, Map attributes, FieldDescriptor... descriptors) { - return relaxedRequestFields(subsectionExtractor, attributes, - Arrays.asList(descriptors)); + return relaxedRequestFields(subsectionExtractor, attributes, Arrays.asList(descriptors)); } /** @@ -550,11 +539,9 @@ public static RequestFieldsSnippet relaxedRequestFields( * @see #subsectionWithPath(String) * @see #beneathPath(String) */ - public static RequestFieldsSnippet relaxedRequestFields( - PayloadSubsectionExtractor subsectionExtractor, + public static RequestFieldsSnippet relaxedRequestFields(PayloadSubsectionExtractor subsectionExtractor, Map attributes, List descriptors) { - return new RequestFieldsSnippet(subsectionExtractor, descriptors, attributes, - true); + return new RequestFieldsSnippet(subsectionExtractor, descriptors, attributes, true); } /** @@ -581,8 +568,7 @@ public static RequestFieldsSnippet relaxedRequestFields( * @see #fieldWithPath(String) * @see #subsectionWithPath(String) */ - public static RequestPartFieldsSnippet requestPartFields(String part, - FieldDescriptor... descriptors) { + public static RequestPartFieldsSnippet requestPartFields(String part, FieldDescriptor... descriptors) { return requestPartFields(part, Arrays.asList(descriptors)); } @@ -609,8 +595,7 @@ public static RequestPartFieldsSnippet requestPartFields(String part, * @see #fieldWithPath(String) * @see #subsectionWithPath(String) */ - public static RequestPartFieldsSnippet requestPartFields(String part, - List descriptors) { + public static RequestPartFieldsSnippet requestPartFields(String part, List descriptors) { return new RequestPartFieldsSnippet(part, descriptors); } @@ -627,8 +612,7 @@ public static RequestPartFieldsSnippet requestPartFields(String part, * @see #fieldWithPath(String) * @see #subsectionWithPath(String) */ - public static RequestPartFieldsSnippet relaxedRequestPartFields(String part, - FieldDescriptor... descriptors) { + public static RequestPartFieldsSnippet relaxedRequestPartFields(String part, FieldDescriptor... descriptors) { return relaxedRequestPartFields(part, Arrays.asList(descriptors)); } @@ -645,8 +629,7 @@ public static RequestPartFieldsSnippet relaxedRequestPartFields(String part, * @see #fieldWithPath(String) * @see #subsectionWithPath(String) */ - public static RequestPartFieldsSnippet relaxedRequestPartFields(String part, - List descriptors) { + public static RequestPartFieldsSnippet relaxedRequestPartFields(String part, List descriptors) { return new RequestPartFieldsSnippet(part, descriptors, true); } @@ -675,8 +658,8 @@ public static RequestPartFieldsSnippet relaxedRequestPartFields(String part, * @see #fieldWithPath(String) * @see #subsectionWithPath(String) */ - public static RequestPartFieldsSnippet requestPartFields(String part, - Map attributes, FieldDescriptor... descriptors) { + public static RequestPartFieldsSnippet requestPartFields(String part, Map attributes, + FieldDescriptor... descriptors) { return requestPartFields(part, attributes, Arrays.asList(descriptors)); } @@ -705,8 +688,8 @@ public static RequestPartFieldsSnippet requestPartFields(String part, * @see #fieldWithPath(String) * @see #subsectionWithPath(String) */ - public static RequestPartFieldsSnippet requestPartFields(String part, - Map attributes, List descriptors) { + public static RequestPartFieldsSnippet requestPartFields(String part, Map attributes, + List descriptors) { return new RequestPartFieldsSnippet(part, descriptors, attributes); } @@ -725,8 +708,8 @@ public static RequestPartFieldsSnippet requestPartFields(String part, * @see #fieldWithPath(String) * @see #subsectionWithPath(String) */ - public static RequestPartFieldsSnippet relaxedRequestPartFields(String part, - Map attributes, FieldDescriptor... descriptors) { + public static RequestPartFieldsSnippet relaxedRequestPartFields(String part, Map attributes, + FieldDescriptor... descriptors) { return relaxedRequestPartFields(part, attributes, Arrays.asList(descriptors)); } @@ -745,8 +728,8 @@ public static RequestPartFieldsSnippet relaxedRequestPartFields(String part, * @see #fieldWithPath(String) * @see #subsectionWithPath(String) */ - public static RequestPartFieldsSnippet relaxedRequestPartFields(String part, - Map attributes, List descriptors) { + public static RequestPartFieldsSnippet relaxedRequestPartFields(String part, Map attributes, + List descriptors) { return new RequestPartFieldsSnippet(part, descriptors, attributes, true); } @@ -778,8 +761,7 @@ public static RequestPartFieldsSnippet relaxedRequestPartFields(String part, * @see #beneathPath(String) */ public static RequestPartFieldsSnippet requestPartFields(String part, - PayloadSubsectionExtractor subsectionExtractor, - FieldDescriptor... descriptors) { + PayloadSubsectionExtractor subsectionExtractor, FieldDescriptor... descriptors) { return requestPartFields(part, subsectionExtractor, Arrays.asList(descriptors)); } @@ -811,8 +793,7 @@ public static RequestPartFieldsSnippet requestPartFields(String part, * @see #beneathPath(String) */ public static RequestPartFieldsSnippet requestPartFields(String part, - PayloadSubsectionExtractor subsectionExtractor, - List descriptors) { + PayloadSubsectionExtractor subsectionExtractor, List descriptors) { return new RequestPartFieldsSnippet(part, subsectionExtractor, descriptors); } @@ -834,10 +815,8 @@ public static RequestPartFieldsSnippet requestPartFields(String part, * @see #beneathPath(String) */ public static RequestPartFieldsSnippet relaxedRequestPartFields(String part, - PayloadSubsectionExtractor subsectionExtractor, - FieldDescriptor... descriptors) { - return relaxedRequestPartFields(part, subsectionExtractor, - Arrays.asList(descriptors)); + PayloadSubsectionExtractor subsectionExtractor, FieldDescriptor... descriptors) { + return relaxedRequestPartFields(part, subsectionExtractor, Arrays.asList(descriptors)); } /** @@ -858,8 +837,7 @@ public static RequestPartFieldsSnippet relaxedRequestPartFields(String part, * @see #beneathPath(String) */ public static RequestPartFieldsSnippet relaxedRequestPartFields(String part, - PayloadSubsectionExtractor subsectionExtractor, - List descriptors) { + PayloadSubsectionExtractor subsectionExtractor, List descriptors) { return new RequestPartFieldsSnippet(part, subsectionExtractor, descriptors, true); } @@ -893,10 +871,9 @@ public static RequestPartFieldsSnippet relaxedRequestPartFields(String part, * @see #beneathPath(String) */ public static RequestPartFieldsSnippet requestPartFields(String part, - PayloadSubsectionExtractor subsectionExtractor, - Map attributes, FieldDescriptor... descriptors) { - return requestPartFields(part, subsectionExtractor, attributes, - Arrays.asList(descriptors)); + PayloadSubsectionExtractor subsectionExtractor, Map attributes, + FieldDescriptor... descriptors) { + return requestPartFields(part, subsectionExtractor, attributes, Arrays.asList(descriptors)); } /** @@ -929,10 +906,9 @@ public static RequestPartFieldsSnippet requestPartFields(String part, * @see #beneathPath(String) */ public static RequestPartFieldsSnippet requestPartFields(String part, - PayloadSubsectionExtractor subsectionExtractor, - Map attributes, List descriptors) { - return new RequestPartFieldsSnippet(part, subsectionExtractor, descriptors, - attributes); + PayloadSubsectionExtractor subsectionExtractor, Map attributes, + List descriptors) { + return new RequestPartFieldsSnippet(part, subsectionExtractor, descriptors, attributes); } /** @@ -955,10 +931,9 @@ public static RequestPartFieldsSnippet requestPartFields(String part, * @see #beneathPath(String) */ public static RequestPartFieldsSnippet relaxedRequestPartFields(String part, - PayloadSubsectionExtractor subsectionExtractor, - Map attributes, FieldDescriptor... descriptors) { - return relaxedRequestPartFields(part, subsectionExtractor, attributes, - Arrays.asList(descriptors)); + PayloadSubsectionExtractor subsectionExtractor, Map attributes, + FieldDescriptor... descriptors) { + return relaxedRequestPartFields(part, subsectionExtractor, attributes, Arrays.asList(descriptors)); } /** @@ -981,10 +956,9 @@ public static RequestPartFieldsSnippet relaxedRequestPartFields(String part, * @see #beneathPath(String) */ public static RequestPartFieldsSnippet relaxedRequestPartFields(String part, - PayloadSubsectionExtractor subsectionExtractor, - Map attributes, List descriptors) { - return new RequestPartFieldsSnippet(part, subsectionExtractor, descriptors, - attributes, true); + PayloadSubsectionExtractor subsectionExtractor, Map attributes, + List descriptors) { + return new RequestPartFieldsSnippet(part, subsectionExtractor, descriptors, attributes, true); } /** @@ -1035,8 +1009,7 @@ public static ResponseFieldsSnippet responseFields(FieldDescriptor... descriptor * @see #subsectionWithPath(String) * @see #beneathPath(String) */ - public static ResponseFieldsSnippet responseFields( - List descriptors) { + public static ResponseFieldsSnippet responseFields(List descriptors) { return new ResponseFieldsSnippet(descriptors); } @@ -1054,8 +1027,7 @@ public static ResponseFieldsSnippet responseFields( * @see #subsectionWithPath(String) * @see #beneathPath(String) */ - public static ResponseFieldsSnippet relaxedResponseFields( - FieldDescriptor... descriptors) { + public static ResponseFieldsSnippet relaxedResponseFields(FieldDescriptor... descriptors) { return relaxedResponseFields(Arrays.asList(descriptors)); } @@ -1071,8 +1043,7 @@ public static ResponseFieldsSnippet relaxedResponseFields( * @see #fieldWithPath(String) * @see #subsectionWithPath(String) */ - public static ResponseFieldsSnippet relaxedResponseFields( - List descriptors) { + public static ResponseFieldsSnippet relaxedResponseFields(List descriptors) { return new ResponseFieldsSnippet(descriptors, true); } @@ -1098,8 +1069,7 @@ public static ResponseFieldsSnippet relaxedResponseFields( * @see #fieldWithPath(String) * @see #subsectionWithPath(String) */ - public static ResponseFieldsSnippet responseFields(Map attributes, - FieldDescriptor... descriptors) { + public static ResponseFieldsSnippet responseFields(Map attributes, FieldDescriptor... descriptors) { return responseFields(attributes, Arrays.asList(descriptors)); } @@ -1143,8 +1113,8 @@ public static ResponseFieldsSnippet responseFields(Map attribute * @see #fieldWithPath(String) * @see #subsectionWithPath(String) */ - public static ResponseFieldsSnippet relaxedResponseFields( - Map attributes, FieldDescriptor... descriptors) { + public static ResponseFieldsSnippet relaxedResponseFields(Map attributes, + FieldDescriptor... descriptors) { return relaxedResponseFields(attributes, Arrays.asList(descriptors)); } @@ -1161,8 +1131,8 @@ public static ResponseFieldsSnippet relaxedResponseFields( * @see #fieldWithPath(String) * @see #subsectionWithPath(String) */ - public static ResponseFieldsSnippet relaxedResponseFields( - Map attributes, List descriptors) { + public static ResponseFieldsSnippet relaxedResponseFields(Map attributes, + List descriptors) { return new ResponseFieldsSnippet(descriptors, attributes, true); } @@ -1192,8 +1162,7 @@ public static ResponseFieldsSnippet relaxedResponseFields( * @see #subsectionWithPath(String) * @see #beneathPath(String) */ - public static ResponseFieldsSnippet responseFields( - PayloadSubsectionExtractor subsectionExtractor, + public static ResponseFieldsSnippet responseFields(PayloadSubsectionExtractor subsectionExtractor, FieldDescriptor... descriptors) { return responseFields(subsectionExtractor, Arrays.asList(descriptors)); } @@ -1224,8 +1193,7 @@ public static ResponseFieldsSnippet responseFields( * @see #subsectionWithPath(String) * @see #beneathPath(String) */ - public static ResponseFieldsSnippet responseFields( - PayloadSubsectionExtractor subsectionExtractor, + public static ResponseFieldsSnippet responseFields(PayloadSubsectionExtractor subsectionExtractor, List descriptors) { return new ResponseFieldsSnippet(subsectionExtractor, descriptors); } @@ -1246,8 +1214,7 @@ public static ResponseFieldsSnippet responseFields( * @see #subsectionWithPath(String) * @see #beneathPath(String) */ - public static ResponseFieldsSnippet relaxedResponseFields( - PayloadSubsectionExtractor subsectionExtractor, + public static ResponseFieldsSnippet relaxedResponseFields(PayloadSubsectionExtractor subsectionExtractor, FieldDescriptor... descriptors) { return relaxedResponseFields(subsectionExtractor, Arrays.asList(descriptors)); } @@ -1268,8 +1235,7 @@ public static ResponseFieldsSnippet relaxedResponseFields( * @see #subsectionWithPath(String) * @see #beneathPath(String) */ - public static ResponseFieldsSnippet relaxedResponseFields( - PayloadSubsectionExtractor subsectionExtractor, + public static ResponseFieldsSnippet relaxedResponseFields(PayloadSubsectionExtractor subsectionExtractor, List descriptors) { return new ResponseFieldsSnippet(subsectionExtractor, descriptors, true); } @@ -1302,11 +1268,9 @@ public static ResponseFieldsSnippet relaxedResponseFields( * @see #subsectionWithPath(String) * @see #beneathPath(String) */ - public static ResponseFieldsSnippet responseFields( - PayloadSubsectionExtractor subsectionExtractor, + public static ResponseFieldsSnippet responseFields(PayloadSubsectionExtractor subsectionExtractor, Map attributes, FieldDescriptor... descriptors) { - return responseFields(subsectionExtractor, attributes, - Arrays.asList(descriptors)); + return responseFields(subsectionExtractor, attributes, Arrays.asList(descriptors)); } /** @@ -1337,8 +1301,7 @@ public static ResponseFieldsSnippet responseFields( * @see #subsectionWithPath(String) * @see #beneathPath(String) */ - public static ResponseFieldsSnippet responseFields( - PayloadSubsectionExtractor subsectionExtractor, + public static ResponseFieldsSnippet responseFields(PayloadSubsectionExtractor subsectionExtractor, Map attributes, List descriptors) { return new ResponseFieldsSnippet(subsectionExtractor, descriptors, attributes); } @@ -1361,11 +1324,9 @@ public static ResponseFieldsSnippet responseFields( * @see #subsectionWithPath(String) * @see #beneathPath(String) */ - public static ResponseFieldsSnippet relaxedResponseFields( - PayloadSubsectionExtractor subsectionExtractor, + public static ResponseFieldsSnippet relaxedResponseFields(PayloadSubsectionExtractor subsectionExtractor, Map attributes, FieldDescriptor... descriptors) { - return relaxedResponseFields(subsectionExtractor, attributes, - Arrays.asList(descriptors)); + return relaxedResponseFields(subsectionExtractor, attributes, Arrays.asList(descriptors)); } /** @@ -1386,11 +1347,9 @@ public static ResponseFieldsSnippet relaxedResponseFields( * @see #subsectionWithPath(String) * @see #beneathPath(String) */ - public static ResponseFieldsSnippet relaxedResponseFields( - PayloadSubsectionExtractor subsectionExtractor, + public static ResponseFieldsSnippet relaxedResponseFields(PayloadSubsectionExtractor subsectionExtractor, Map attributes, List descriptors) { - return new ResponseFieldsSnippet(subsectionExtractor, descriptors, attributes, - true); + return new ResponseFieldsSnippet(subsectionExtractor, descriptors, attributes, true); } /** @@ -1420,8 +1379,7 @@ public static RequestBodySnippet requestBody(Map attributes) { * @param subsectionExtractor the subsection extractor * @return the snippet that will document the request body subsection */ - public static RequestBodySnippet requestBody( - PayloadSubsectionExtractor subsectionExtractor) { + public static RequestBodySnippet requestBody(PayloadSubsectionExtractor subsectionExtractor) { return new RequestBodySnippet(subsectionExtractor); } @@ -1434,8 +1392,7 @@ public static RequestBodySnippet requestBody( * @param attributes the attributes * @return the snippet that will document the request body subsection */ - public static RequestBodySnippet requestBody( - PayloadSubsectionExtractor subsectionExtractor, + public static RequestBodySnippet requestBody(PayloadSubsectionExtractor subsectionExtractor, Map attributes) { return new RequestBodySnippet(subsectionExtractor, attributes); } @@ -1467,8 +1424,7 @@ public static ResponseBodySnippet responseBody(Map attributes) { * @param subsectionExtractor the subsection extractor * @return the snippet that will document the response body subsection */ - public static ResponseBodySnippet responseBody( - PayloadSubsectionExtractor subsectionExtractor) { + public static ResponseBodySnippet responseBody(PayloadSubsectionExtractor subsectionExtractor) { return new ResponseBodySnippet(subsectionExtractor); } @@ -1481,8 +1437,7 @@ public static ResponseBodySnippet responseBody( * @param attributes the attributes * @return the snippet that will document the response body subsection */ - public static ResponseBodySnippet responseBody( - PayloadSubsectionExtractor subsectionExtractor, + public static ResponseBodySnippet responseBody(PayloadSubsectionExtractor subsectionExtractor, Map attributes) { return new ResponseBodySnippet(subsectionExtractor, attributes); } @@ -1505,8 +1460,7 @@ public static RequestPartBodySnippet requestPartBody(String partName) { * @param attributes the attributes * @return the snippet that will document the response body */ - public static RequestPartBodySnippet requestPartBody(String partName, - Map attributes) { + public static RequestPartBodySnippet requestPartBody(String partName, Map attributes) { return new RequestPartBodySnippet(partName, attributes); } @@ -1534,8 +1488,7 @@ public static RequestPartBodySnippet requestPartBody(String partName, * @return the snippet that will document the response body */ public static RequestPartBodySnippet requestPartBody(String partName, - PayloadSubsectionExtractor subsectionExtractor, - Map attributes) { + PayloadSubsectionExtractor subsectionExtractor, Map attributes) { return new RequestPartBodySnippet(partName, subsectionExtractor, attributes); } @@ -1546,16 +1499,13 @@ public static RequestPartBodySnippet requestPartBody(String partName, * @param descriptors the descriptors to copy * @return the copied descriptors with the prefix applied */ - public static List applyPathPrefix(String pathPrefix, - List descriptors) { + public static List applyPathPrefix(String pathPrefix, List descriptors) { List prefixedDescriptors = new ArrayList<>(); for (FieldDescriptor descriptor : descriptors) { String prefixedPath = pathPrefix + descriptor.getPath(); FieldDescriptor prefixedDescriptor = (descriptor instanceof SubsectionDescriptor) - ? new SubsectionDescriptor(prefixedPath) - : new FieldDescriptor(prefixedPath); - prefixedDescriptor.description(descriptor.getDescription()) - .type(descriptor.getType()) + ? new SubsectionDescriptor(prefixedPath) : new FieldDescriptor(prefixedPath); + prefixedDescriptor.description(descriptor.getDescription()).type(descriptor.getType()) .attributes(asArray(descriptor.getAttributes())); if (descriptor.isIgnored()) { prefixedDescriptor.ignored(); @@ -1582,8 +1532,7 @@ public static PayloadSubsectionExtractor beneathPath(String path) { private static Attribute[] asArray(Map attributeMap) { List attributes = new ArrayList<>(); for (Map.Entry attribute : attributeMap.entrySet()) { - attributes - .add(Attributes.key(attribute.getKey()).value(attribute.getValue())); + attributes.add(Attributes.key(attribute.getKey()).value(attribute.getValue())); } return attributes.toArray(new Attribute[attributes.size()]); } diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/RequestBodySnippet.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/RequestBodySnippet.java index 0bdd30a1a..bdbb4b401 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/RequestBodySnippet.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/RequestBodySnippet.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-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. @@ -63,8 +63,7 @@ public RequestBodySnippet(Map attributes) { * @param subsectionExtractor the subsection extractor * @param attributes the additional attributes */ - public RequestBodySnippet(PayloadSubsectionExtractor subsectionExtractor, - Map attributes) { + public RequestBodySnippet(PayloadSubsectionExtractor subsectionExtractor, Map attributes) { super("request", subsectionExtractor, attributes); } diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/RequestFieldsSnippet.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/RequestFieldsSnippet.java index f4dd20a98..92fe48e43 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/RequestFieldsSnippet.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/RequestFieldsSnippet.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-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. @@ -52,8 +52,7 @@ protected RequestFieldsSnippet(List descriptors) { * @param descriptors the descriptors * @param ignoreUndocumentedFields whether undocumented fields should be ignored */ - protected RequestFieldsSnippet(List descriptors, - boolean ignoreUndocumentedFields) { + protected RequestFieldsSnippet(List descriptors, boolean ignoreUndocumentedFields) { this(descriptors, null, ignoreUndocumentedFields); } @@ -65,8 +64,7 @@ protected RequestFieldsSnippet(List descriptors, * @param descriptors the descriptors * @param attributes the additional attributes */ - protected RequestFieldsSnippet(List descriptors, - Map attributes) { + protected RequestFieldsSnippet(List descriptors, Map attributes) { this(descriptors, attributes, false); } @@ -80,8 +78,8 @@ protected RequestFieldsSnippet(List descriptors, * @param attributes the additional attributes * @param ignoreUndocumentedFields whether undocumented fields should be ignored */ - protected RequestFieldsSnippet(List descriptors, - Map attributes, boolean ignoreUndocumentedFields) { + protected RequestFieldsSnippet(List descriptors, Map attributes, + boolean ignoreUndocumentedFields) { this(null, descriptors, attributes, ignoreUndocumentedFields); } @@ -108,8 +106,8 @@ protected RequestFieldsSnippet(PayloadSubsectionExtractor subsectionExtractor * @param ignoreUndocumentedFields whether undocumented fields should be ignored * @since 1.2.0 */ - protected RequestFieldsSnippet(PayloadSubsectionExtractor subsectionExtractor, - List descriptors, boolean ignoreUndocumentedFields) { + protected RequestFieldsSnippet(PayloadSubsectionExtractor subsectionExtractor, List descriptors, + boolean ignoreUndocumentedFields) { this(subsectionExtractor, descriptors, null, ignoreUndocumentedFields); } @@ -123,8 +121,8 @@ protected RequestFieldsSnippet(PayloadSubsectionExtractor subsectionExtractor * @param attributes the additional attributes * @since 1.2.0 */ - protected RequestFieldsSnippet(PayloadSubsectionExtractor subsectionExtractor, - List descriptors, Map attributes) { + protected RequestFieldsSnippet(PayloadSubsectionExtractor subsectionExtractor, List descriptors, + Map attributes) { this(subsectionExtractor, descriptors, attributes, false); } @@ -141,11 +139,9 @@ protected RequestFieldsSnippet(PayloadSubsectionExtractor subsectionExtractor * @param ignoreUndocumentedFields whether undocumented fields should be ignored * @since 1.2.0 */ - protected RequestFieldsSnippet(PayloadSubsectionExtractor subsectionExtractor, - List descriptors, Map attributes, - boolean ignoreUndocumentedFields) { - super("request", descriptors, attributes, ignoreUndocumentedFields, - subsectionExtractor); + protected RequestFieldsSnippet(PayloadSubsectionExtractor subsectionExtractor, List descriptors, + Map attributes, boolean ignoreUndocumentedFields) { + super("request", descriptors, attributes, ignoreUndocumentedFields, subsectionExtractor); } @Override @@ -189,14 +185,13 @@ public final RequestFieldsSnippet and(List additionalDescriptor * @param additionalDescriptors the additional descriptors * @return the new snippet */ - public final RequestFieldsSnippet andWithPrefix(String pathPrefix, - FieldDescriptor... additionalDescriptors) { + public final RequestFieldsSnippet andWithPrefix(String pathPrefix, FieldDescriptor... additionalDescriptors) { List combinedDescriptors = new ArrayList<>(); combinedDescriptors.addAll(getFieldDescriptors()); - combinedDescriptors.addAll(PayloadDocumentation.applyPathPrefix(pathPrefix, - Arrays.asList(additionalDescriptors))); - return new RequestFieldsSnippet(getSubsectionExtractor(), combinedDescriptors, - getAttributes(), isIgnoredUndocumentedFields()); + combinedDescriptors + .addAll(PayloadDocumentation.applyPathPrefix(pathPrefix, Arrays.asList(additionalDescriptors))); + return new RequestFieldsSnippet(getSubsectionExtractor(), combinedDescriptors, getAttributes(), + isIgnoredUndocumentedFields()); } /** @@ -208,14 +203,11 @@ public final RequestFieldsSnippet andWithPrefix(String pathPrefix, * @param additionalDescriptors the additional descriptors * @return the new snippet */ - public final RequestFieldsSnippet andWithPrefix(String pathPrefix, - List additionalDescriptors) { - List combinedDescriptors = new ArrayList<>( - getFieldDescriptors()); - combinedDescriptors.addAll( - PayloadDocumentation.applyPathPrefix(pathPrefix, additionalDescriptors)); - return new RequestFieldsSnippet(getSubsectionExtractor(), combinedDescriptors, - getAttributes(), isIgnoredUndocumentedFields()); + public final RequestFieldsSnippet andWithPrefix(String pathPrefix, List additionalDescriptors) { + List combinedDescriptors = new ArrayList<>(getFieldDescriptors()); + combinedDescriptors.addAll(PayloadDocumentation.applyPathPrefix(pathPrefix, additionalDescriptors)); + return new RequestFieldsSnippet(getSubsectionExtractor(), combinedDescriptors, getAttributes(), + isIgnoredUndocumentedFields()); } } diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/RequestPartBodySnippet.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/RequestPartBodySnippet.java index d12a91eab..3ab046015 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/RequestPartBodySnippet.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/RequestPartBodySnippet.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-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. @@ -50,8 +50,7 @@ public RequestPartBodySnippet(String partName) { * @param partName the name of the request part * @param subsectionExtractor the subsection extractor */ - public RequestPartBodySnippet(String partName, - PayloadSubsectionExtractor subsectionExtractor) { + public RequestPartBodySnippet(String partName, PayloadSubsectionExtractor subsectionExtractor) { this(partName, subsectionExtractor, null); } @@ -76,11 +75,9 @@ public RequestPartBodySnippet(String partName, Map attributes) { * @param subsectionExtractor the subsection extractor * @param attributes the additional attributes */ - public RequestPartBodySnippet(String partName, - PayloadSubsectionExtractor subsectionExtractor, + public RequestPartBodySnippet(String partName, PayloadSubsectionExtractor subsectionExtractor, Map attributes) { - super("request-part-" + partName, "request-part", subsectionExtractor, - attributes); + super("request-part-" + partName, "request-part", subsectionExtractor, attributes); this.partName = partName; } @@ -100,8 +97,7 @@ private OperationRequestPart findPart(Operation operation) { return candidate; } } - throw new SnippetException("A request part named '" + this.partName - + "' was not found in the request"); + throw new SnippetException("A request part named '" + this.partName + "' was not found in the request"); } } diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/RequestPartFieldsSnippet.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/RequestPartFieldsSnippet.java index 1488f7978..f5a9e1b84 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/RequestPartFieldsSnippet.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/RequestPartFieldsSnippet.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2016 the original author or authors. + * Copyright 2014-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. @@ -48,8 +48,7 @@ public class RequestPartFieldsSnippet extends AbstractFieldsSnippet { * @param partName the part name * @param descriptors the descriptors */ - protected RequestPartFieldsSnippet(String partName, - List descriptors) { + protected RequestPartFieldsSnippet(String partName, List descriptors) { this(partName, descriptors, null, false); } @@ -106,8 +105,7 @@ protected RequestPartFieldsSnippet(String partName, List descri * @param subsectionExtractor the subsection extractor * @param descriptors the descriptors */ - protected RequestPartFieldsSnippet(String partName, - PayloadSubsectionExtractor subsectionExtractor, + protected RequestPartFieldsSnippet(String partName, PayloadSubsectionExtractor subsectionExtractor, List descriptors) { this(partName, subsectionExtractor, descriptors, null, false); } @@ -123,8 +121,7 @@ protected RequestPartFieldsSnippet(String partName, * @param descriptors the descriptors * @param ignoreUndocumentedFields whether undocumented fields should be ignored */ - protected RequestPartFieldsSnippet(String partName, - PayloadSubsectionExtractor subsectionExtractor, + protected RequestPartFieldsSnippet(String partName, PayloadSubsectionExtractor subsectionExtractor, List descriptors, boolean ignoreUndocumentedFields) { this(partName, subsectionExtractor, descriptors, null, ignoreUndocumentedFields); } @@ -140,8 +137,7 @@ protected RequestPartFieldsSnippet(String partName, * @param descriptors the descriptors * @param attributes the additional attributes */ - protected RequestPartFieldsSnippet(String partName, - PayloadSubsectionExtractor subsectionExtractor, + protected RequestPartFieldsSnippet(String partName, PayloadSubsectionExtractor subsectionExtractor, List descriptors, Map attributes) { this(partName, subsectionExtractor, descriptors, attributes, false); } @@ -159,12 +155,10 @@ protected RequestPartFieldsSnippet(String partName, * @param attributes the additional attributes * @param ignoreUndocumentedFields whether undocumented fields should be ignored */ - protected RequestPartFieldsSnippet(String partName, - PayloadSubsectionExtractor subsectionExtractor, - List descriptors, Map attributes, - boolean ignoreUndocumentedFields) { - super("request-part-" + partName, "request-part", descriptors, attributes, - ignoreUndocumentedFields, subsectionExtractor); + protected RequestPartFieldsSnippet(String partName, PayloadSubsectionExtractor subsectionExtractor, + List descriptors, Map attributes, boolean ignoreUndocumentedFields) { + super("request-part-" + partName, "request-part", descriptors, attributes, ignoreUndocumentedFields, + subsectionExtractor); this.partName = partName; } @@ -184,8 +178,7 @@ private OperationRequestPart findPart(Operation operation) { return candidate; } } - throw new SnippetException("A request part named '" + this.partName - + "' was not found in the request"); + throw new SnippetException("A request part named '" + this.partName + "' was not found in the request"); } /** @@ -206,8 +199,7 @@ public final RequestPartFieldsSnippet and(FieldDescriptor... additionalDescripto * @param additionalDescriptors the additional descriptors * @return the new snippet */ - public final RequestPartFieldsSnippet and( - List additionalDescriptors) { + public final RequestPartFieldsSnippet and(List additionalDescriptors) { return andWithPrefix("", additionalDescriptors); } @@ -220,14 +212,12 @@ public final RequestPartFieldsSnippet and( * @param additionalDescriptors the additional descriptors * @return the new snippet */ - public final RequestPartFieldsSnippet andWithPrefix(String pathPrefix, - FieldDescriptor... additionalDescriptors) { + public final RequestPartFieldsSnippet andWithPrefix(String pathPrefix, FieldDescriptor... additionalDescriptors) { List combinedDescriptors = new ArrayList<>(); combinedDescriptors.addAll(getFieldDescriptors()); - combinedDescriptors.addAll(PayloadDocumentation.applyPathPrefix(pathPrefix, - Arrays.asList(additionalDescriptors))); - return new RequestPartFieldsSnippet(this.partName, combinedDescriptors, - this.getAttributes()); + combinedDescriptors + .addAll(PayloadDocumentation.applyPathPrefix(pathPrefix, Arrays.asList(additionalDescriptors))); + return new RequestPartFieldsSnippet(this.partName, combinedDescriptors, this.getAttributes()); } /** @@ -241,12 +231,9 @@ public final RequestPartFieldsSnippet andWithPrefix(String pathPrefix, */ public final RequestPartFieldsSnippet andWithPrefix(String pathPrefix, List additionalDescriptors) { - List combinedDescriptors = new ArrayList<>( - getFieldDescriptors()); - combinedDescriptors.addAll( - PayloadDocumentation.applyPathPrefix(pathPrefix, additionalDescriptors)); - return new RequestPartFieldsSnippet(this.partName, combinedDescriptors, - this.getAttributes()); + List combinedDescriptors = new ArrayList<>(getFieldDescriptors()); + combinedDescriptors.addAll(PayloadDocumentation.applyPathPrefix(pathPrefix, additionalDescriptors)); + return new RequestPartFieldsSnippet(this.partName, combinedDescriptors, this.getAttributes()); } } diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/ResponseBodySnippet.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/ResponseBodySnippet.java index d771c019b..c316b54fa 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/ResponseBodySnippet.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/ResponseBodySnippet.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-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. @@ -63,8 +63,7 @@ public ResponseBodySnippet(Map attributes) { * @param subsectionExtractor the subsection extractor * @param attributes the additional attributes */ - public ResponseBodySnippet(PayloadSubsectionExtractor subsectionExtractor, - Map attributes) { + public ResponseBodySnippet(PayloadSubsectionExtractor subsectionExtractor, Map attributes) { super("response", subsectionExtractor, attributes); } diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/ResponseFieldsSnippet.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/ResponseFieldsSnippet.java index d7ae5416c..f4dc1053a 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/ResponseFieldsSnippet.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/ResponseFieldsSnippet.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-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. @@ -53,8 +53,7 @@ protected ResponseFieldsSnippet(List descriptors) { * @param descriptors the descriptors * @param ignoreUndocumentedFields whether undocumented fields should be ignored */ - protected ResponseFieldsSnippet(List descriptors, - boolean ignoreUndocumentedFields) { + protected ResponseFieldsSnippet(List descriptors, boolean ignoreUndocumentedFields) { this(descriptors, null, ignoreUndocumentedFields); } @@ -66,8 +65,7 @@ protected ResponseFieldsSnippet(List descriptors, * @param descriptors the descriptors * @param attributes the additional attributes */ - protected ResponseFieldsSnippet(List descriptors, - Map attributes) { + protected ResponseFieldsSnippet(List descriptors, Map attributes) { this(descriptors, attributes, false); } @@ -81,8 +79,8 @@ protected ResponseFieldsSnippet(List descriptors, * @param attributes the additional attributes * @param ignoreUndocumentedFields whether undocumented fields should be ignored */ - protected ResponseFieldsSnippet(List descriptors, - Map attributes, boolean ignoreUndocumentedFields) { + protected ResponseFieldsSnippet(List descriptors, Map attributes, + boolean ignoreUndocumentedFields) { this(null, descriptors, attributes, ignoreUndocumentedFields); } @@ -146,10 +144,8 @@ protected ResponseFieldsSnippet(PayloadSubsectionExtractor subsectionExtracto * @since 1.2.0 */ protected ResponseFieldsSnippet(PayloadSubsectionExtractor subsectionExtractor, - List descriptors, Map attributes, - boolean ignoreUndocumentedFields) { - super("response", descriptors, attributes, ignoreUndocumentedFields, - subsectionExtractor); + List descriptors, Map attributes, boolean ignoreUndocumentedFields) { + super("response", descriptors, attributes, ignoreUndocumentedFields, subsectionExtractor); } @Override @@ -193,14 +189,13 @@ public final ResponseFieldsSnippet and(List additionalDescripto * @param additionalDescriptors the additional descriptors * @return the new snippet */ - public final ResponseFieldsSnippet andWithPrefix(String pathPrefix, - FieldDescriptor... additionalDescriptors) { + public final ResponseFieldsSnippet andWithPrefix(String pathPrefix, FieldDescriptor... additionalDescriptors) { List combinedDescriptors = new ArrayList<>(); combinedDescriptors.addAll(getFieldDescriptors()); - combinedDescriptors.addAll(PayloadDocumentation.applyPathPrefix(pathPrefix, - Arrays.asList(additionalDescriptors))); - return new ResponseFieldsSnippet(getSubsectionExtractor(), combinedDescriptors, - this.getAttributes(), isIgnoredUndocumentedFields()); + combinedDescriptors + .addAll(PayloadDocumentation.applyPathPrefix(pathPrefix, Arrays.asList(additionalDescriptors))); + return new ResponseFieldsSnippet(getSubsectionExtractor(), combinedDescriptors, this.getAttributes(), + isIgnoredUndocumentedFields()); } /** @@ -212,14 +207,11 @@ public final ResponseFieldsSnippet andWithPrefix(String pathPrefix, * @param additionalDescriptors the additional descriptors * @return the new snippet */ - public final ResponseFieldsSnippet andWithPrefix(String pathPrefix, - List additionalDescriptors) { - List combinedDescriptors = new ArrayList<>( - getFieldDescriptors()); - combinedDescriptors.addAll( - PayloadDocumentation.applyPathPrefix(pathPrefix, additionalDescriptors)); - return new ResponseFieldsSnippet(getSubsectionExtractor(), combinedDescriptors, - this.getAttributes(), isIgnoredUndocumentedFields()); + public final ResponseFieldsSnippet andWithPrefix(String pathPrefix, List additionalDescriptors) { + List combinedDescriptors = new ArrayList<>(getFieldDescriptors()); + combinedDescriptors.addAll(PayloadDocumentation.applyPathPrefix(pathPrefix, additionalDescriptors)); + return new ResponseFieldsSnippet(getSubsectionExtractor(), combinedDescriptors, this.getAttributes(), + isIgnoredUndocumentedFields()); } } diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/XmlContentHandler.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/XmlContentHandler.java index aef7cfcd9..8e3e49706 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/XmlContentHandler.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/XmlContentHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2017 the original author or authors. + * Copyright 2014-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. @@ -55,8 +55,7 @@ class XmlContentHandler implements ContentHandler { XmlContentHandler(byte[] rawContent) { try { - this.documentBuilder = DocumentBuilderFactory.newInstance() - .newDocumentBuilder(); + this.documentBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); } catch (ParserConfigurationException ex) { throw new IllegalStateException("Failed to create document builder", ex); @@ -66,8 +65,7 @@ class XmlContentHandler implements ContentHandler { } @Override - public List findMissingFields( - List fieldDescriptors) { + public List findMissingFields(List fieldDescriptors) { List missingFields = new ArrayList<>(); Document payload = readPayload(); for (FieldDescriptor fieldDescriptor : fieldDescriptors) { @@ -82,11 +80,9 @@ public List findMissingFields( return missingFields; } - private NodeList findMatchingNodes(FieldDescriptor fieldDescriptor, - Document payload) { + private NodeList findMatchingNodes(FieldDescriptor fieldDescriptor, Document payload) { try { - return (NodeList) createXPath(fieldDescriptor.getPath()).evaluate(payload, - XPathConstants.NODESET); + return (NodeList) createXPath(fieldDescriptor.getPath()).evaluate(payload, XPathConstants.NODESET); } catch (XPathExpressionException ex) { throw new PayloadHandlingException(ex); @@ -95,16 +91,14 @@ private NodeList findMatchingNodes(FieldDescriptor fieldDescriptor, private Document readPayload() { try { - return this.documentBuilder - .parse(new InputSource(new ByteArrayInputStream(this.rawContent))); + return this.documentBuilder.parse(new InputSource(new ByteArrayInputStream(this.rawContent))); } catch (Exception ex) { throw new PayloadHandlingException(ex); } } - private XPathExpression createXPath(String fieldPath) - throws XPathExpressionException { + private XPathExpression createXPath(String fieldPath) throws XPathExpressionException { return XPathFactory.newInstance().newXPath().compile(fieldPath); } @@ -115,8 +109,8 @@ public String getUndocumentedContent(List fieldDescriptors) { for (FieldDescriptor fieldDescriptor : fieldDescriptors) { NodeList matchingNodes; try { - matchingNodes = (NodeList) createXPath(fieldDescriptor.getPath()) - .evaluate(payload, XPathConstants.NODESET); + matchingNodes = (NodeList) createXPath(fieldDescriptor.getPath()).evaluate(payload, + XPathConstants.NODESET); } catch (XPathExpressionException ex) { throw new PayloadHandlingException(ex); @@ -128,8 +122,7 @@ public String getUndocumentedContent(List fieldDescriptors) { attr.getOwnerElement().removeAttributeNode(attr); } else { - if (fieldDescriptor instanceof SubsectionDescriptor - || isLeafNode(node)) { + if (fieldDescriptor instanceof SubsectionDescriptor || isLeafNode(node)) { node.getParentNode().removeChild(node); } else { diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/request/AbstractParametersSnippet.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/request/AbstractParametersSnippet.java index 8175ddddb..376ce2cf3 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/request/AbstractParametersSnippet.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/request/AbstractParametersSnippet.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2016 the original author or authors. + * Copyright 2014-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. @@ -55,8 +55,8 @@ public abstract class AbstractParametersSnippet extends TemplatedSnippet { * {@link #AbstractParametersSnippet(String, List, Map, boolean)} */ @Deprecated - protected AbstractParametersSnippet(String snippetName, - List descriptors, Map attributes) { + protected AbstractParametersSnippet(String snippetName, List descriptors, + Map attributes) { this(snippetName, descriptors, attributes, false); } @@ -72,18 +72,14 @@ protected AbstractParametersSnippet(String snippetName, * @param ignoreUndocumentedParameters whether undocumented parameters should be * ignored */ - protected AbstractParametersSnippet(String snippetName, - List descriptors, Map attributes, - boolean ignoreUndocumentedParameters) { + protected AbstractParametersSnippet(String snippetName, List descriptors, + Map attributes, boolean ignoreUndocumentedParameters) { super(snippetName, attributes); for (ParameterDescriptor descriptor : descriptors) { - Assert.notNull(descriptor.getName(), - "Parameter descriptors must have a name"); + Assert.notNull(descriptor.getName(), "Parameter descriptors must have a name"); if (!descriptor.isIgnored()) { - Assert.notNull(descriptor.getDescription(), - "The descriptor for parameter '" + descriptor.getName() - + "' must either have a description or be marked as " - + "ignored"); + Assert.notNull(descriptor.getDescription(), "The descriptor for parameter '" + descriptor.getName() + + "' must either have a description or be marked as " + "ignored"); } this.descriptorsByName.put(descriptor.getName(), descriptor); } @@ -96,8 +92,7 @@ protected Map createModel(Operation operation) { Map model = new HashMap<>(); List> parameters = new ArrayList<>(); - for (Entry entry : this.descriptorsByName - .entrySet()) { + for (Entry entry : this.descriptorsByName.entrySet()) { ParameterDescriptor descriptor = entry.getValue(); if (!descriptor.isIgnored()) { parameters.add(createModelForDescriptor(descriptor)); @@ -110,8 +105,7 @@ protected Map createModel(Operation operation) { private void verifyParameterDescriptors(Operation operation) { Set actualParameters = extractActualParameters(operation); Set expectedParameters = new HashSet<>(); - for (Entry entry : this.descriptorsByName - .entrySet()) { + for (Entry entry : this.descriptorsByName.entrySet()) { if (!entry.getValue().isOptional()) { expectedParameters.add(entry.getKey()); } @@ -147,8 +141,7 @@ private void verifyParameterDescriptors(Operation operation) { * @param missingParameters the parameters that were documented but were not found in * the operation */ - protected abstract void verificationFailed(Set undocumentedParameters, - Set missingParameters); + protected abstract void verificationFailed(Set undocumentedParameters, Set missingParameters); /** * Returns a {@code Map} of {@link ParameterDescriptor ParameterDescriptors} that will @@ -177,8 +170,7 @@ protected final Map getParameterDescriptors() { * @param descriptor the descriptor * @return the model */ - protected Map createModelForDescriptor( - ParameterDescriptor descriptor) { + protected Map createModelForDescriptor(ParameterDescriptor descriptor) { Map model = new HashMap<>(); model.put("name", descriptor.getName()); model.put("description", descriptor.getDescription()); diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/request/PathParametersSnippet.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/request/PathParametersSnippet.java index 87696d4f5..91acf47bb 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/request/PathParametersSnippet.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/request/PathParametersSnippet.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-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. @@ -61,8 +61,7 @@ protected PathParametersSnippet(List descriptors) { * @param ignoreUndocumentedParameters whether undocumented parameters should be * ignored */ - protected PathParametersSnippet(List descriptors, - boolean ignoreUndocumentedParameters) { + protected PathParametersSnippet(List descriptors, boolean ignoreUndocumentedParameters) { this(descriptors, null, ignoreUndocumentedParameters); } @@ -74,8 +73,7 @@ protected PathParametersSnippet(List descriptors, * @param descriptors the parameter descriptors * @param attributes the additional attributes */ - protected PathParametersSnippet(List descriptors, - Map attributes) { + protected PathParametersSnippet(List descriptors, Map attributes) { this(descriptors, attributes, false); } @@ -90,8 +88,8 @@ protected PathParametersSnippet(List descriptors, * @param ignoreUndocumentedParameters whether undocumented parameters should be * ignored */ - protected PathParametersSnippet(List descriptors, - Map attributes, boolean ignoreUndocumentedParameters) { + protected PathParametersSnippet(List descriptors, Map attributes, + boolean ignoreUndocumentedParameters) { super("path-parameters", descriptors, attributes, ignoreUndocumentedParameters); } @@ -136,19 +134,17 @@ private static String getParameterName(String match) { } @Override - protected void verificationFailed(Set undocumentedParameters, - Set missingParameters) { + protected void verificationFailed(Set undocumentedParameters, Set missingParameters) { String message = ""; if (!undocumentedParameters.isEmpty()) { - message += "Path parameters with the following names were not documented: " - + undocumentedParameters; + message += "Path parameters with the following names were not documented: " + undocumentedParameters; } if (!missingParameters.isEmpty()) { if (message.length() > 0) { message += ". "; } - message += "Path parameters with the following names were not found in " - + "the request: " + missingParameters; + message += "Path parameters with the following names were not found in " + "the request: " + + missingParameters; } throw new SnippetException(message); } @@ -171,10 +167,8 @@ public final PathParametersSnippet and(ParameterDescriptor... additionalDescript * @param additionalDescriptors the additional descriptors * @return the new snippet */ - public final PathParametersSnippet and( - List additionalDescriptors) { - List combinedDescriptors = new ArrayList<>( - getParameterDescriptors().values()); + public final PathParametersSnippet and(List additionalDescriptors) { + List combinedDescriptors = new ArrayList<>(getParameterDescriptors().values()); combinedDescriptors.addAll(additionalDescriptors); return new PathParametersSnippet(combinedDescriptors, this.getAttributes()); } diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/request/RequestDocumentation.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/request/RequestDocumentation.java index 8c488784e..3c051fbca 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/request/RequestDocumentation.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/request/RequestDocumentation.java @@ -70,8 +70,7 @@ public static RequestPartDescriptor partWithName(String name) { * @param descriptors the descriptions of the parameters in the request's path * @return the snippet that will document the parameters */ - public static PathParametersSnippet pathParameters( - ParameterDescriptor... descriptors) { + public static PathParametersSnippet pathParameters(ParameterDescriptor... descriptors) { return pathParameters(Arrays.asList(descriptors)); } @@ -91,8 +90,7 @@ public static PathParametersSnippet pathParameters( * @param descriptors the descriptions of the parameters in the request's path * @return the snippet that will document the parameters */ - public static PathParametersSnippet pathParameters( - List descriptors) { + public static PathParametersSnippet pathParameters(List descriptors) { return new PathParametersSnippet(descriptors); } @@ -106,8 +104,7 @@ public static PathParametersSnippet pathParameters( * @param descriptors the descriptions of the parameters in the request's path * @return the snippet that will document the parameters */ - public static PathParametersSnippet relaxedPathParameters( - ParameterDescriptor... descriptors) { + public static PathParametersSnippet relaxedPathParameters(ParameterDescriptor... descriptors) { return relaxedPathParameters(Arrays.asList(descriptors)); } @@ -121,8 +118,7 @@ public static PathParametersSnippet relaxedPathParameters( * @param descriptors the descriptions of the parameters in the request's path * @return the snippet that will document the parameters */ - public static PathParametersSnippet relaxedPathParameters( - List descriptors) { + public static PathParametersSnippet relaxedPathParameters(List descriptors) { return new PathParametersSnippet(descriptors, true); } @@ -184,8 +180,8 @@ public static PathParametersSnippet pathParameters(Map attribute * @param descriptors the descriptions of the parameters in the request's path * @return the snippet that will document the parameters */ - public static PathParametersSnippet relaxedPathParameters( - Map attributes, ParameterDescriptor... descriptors) { + public static PathParametersSnippet relaxedPathParameters(Map attributes, + ParameterDescriptor... descriptors) { return relaxedPathParameters(attributes, Arrays.asList(descriptors)); } @@ -201,8 +197,8 @@ public static PathParametersSnippet relaxedPathParameters( * @param descriptors the descriptions of the parameters in the request's path * @return the snippet that will document the parameters */ - public static PathParametersSnippet relaxedPathParameters( - Map attributes, List descriptors) { + public static PathParametersSnippet relaxedPathParameters(Map attributes, + List descriptors) { return new PathParametersSnippet(descriptors, attributes, true); } @@ -223,8 +219,7 @@ public static PathParametersSnippet relaxedPathParameters( * @return the snippet * @see OperationRequest#getParameters() */ - public static RequestParametersSnippet requestParameters( - ParameterDescriptor... descriptors) { + public static RequestParametersSnippet requestParameters(ParameterDescriptor... descriptors) { return requestParameters(Arrays.asList(descriptors)); } @@ -245,8 +240,7 @@ public static RequestParametersSnippet requestParameters( * @return the snippet * @see OperationRequest#getParameters() */ - public static RequestParametersSnippet requestParameters( - List descriptors) { + public static RequestParametersSnippet requestParameters(List descriptors) { return new RequestParametersSnippet(descriptors); } @@ -261,8 +255,7 @@ public static RequestParametersSnippet requestParameters( * @return the snippet * @see OperationRequest#getParameters() */ - public static RequestParametersSnippet relaxedRequestParameters( - ParameterDescriptor... descriptors) { + public static RequestParametersSnippet relaxedRequestParameters(ParameterDescriptor... descriptors) { return relaxedRequestParameters(Arrays.asList(descriptors)); } @@ -277,8 +270,7 @@ public static RequestParametersSnippet relaxedRequestParameters( * @return the snippet * @see OperationRequest#getParameters() */ - public static RequestParametersSnippet relaxedRequestParameters( - List descriptors) { + public static RequestParametersSnippet relaxedRequestParameters(List descriptors) { return new RequestParametersSnippet(descriptors, true); } @@ -301,8 +293,8 @@ public static RequestParametersSnippet relaxedRequestParameters( * @return the snippet that will document the parameters * @see OperationRequest#getParameters() */ - public static RequestParametersSnippet requestParameters( - Map attributes, ParameterDescriptor... descriptors) { + public static RequestParametersSnippet requestParameters(Map attributes, + ParameterDescriptor... descriptors) { return requestParameters(attributes, Arrays.asList(descriptors)); } @@ -325,8 +317,8 @@ public static RequestParametersSnippet requestParameters( * @return the snippet that will document the parameters * @see OperationRequest#getParameters() */ - public static RequestParametersSnippet requestParameters( - Map attributes, List descriptors) { + public static RequestParametersSnippet requestParameters(Map attributes, + List descriptors) { return new RequestParametersSnippet(descriptors, attributes); } @@ -343,8 +335,8 @@ public static RequestParametersSnippet requestParameters( * @return the snippet that will document the parameters * @see OperationRequest#getParameters() */ - public static RequestParametersSnippet relaxedRequestParameters( - Map attributes, ParameterDescriptor... descriptors) { + public static RequestParametersSnippet relaxedRequestParameters(Map attributes, + ParameterDescriptor... descriptors) { return relaxedRequestParameters(attributes, Arrays.asList(descriptors)); } @@ -361,8 +353,8 @@ public static RequestParametersSnippet relaxedRequestParameters( * @return the snippet that will document the parameters * @see OperationRequest#getParameters() */ - public static RequestParametersSnippet relaxedRequestParameters( - Map attributes, List descriptors) { + public static RequestParametersSnippet relaxedRequestParameters(Map attributes, + List descriptors) { return new RequestParametersSnippet(descriptors, attributes, true); } @@ -402,8 +394,7 @@ public static RequestPartsSnippet requestParts(RequestPartDescriptor... descript * @return the snippet * @see OperationRequest#getParts() */ - public static RequestPartsSnippet requestParts( - List descriptors) { + public static RequestPartsSnippet requestParts(List descriptors) { return new RequestPartsSnippet(descriptors); } @@ -417,8 +408,7 @@ public static RequestPartsSnippet requestParts( * @return the snippet * @see OperationRequest#getParts() */ - public static RequestPartsSnippet relaxedRequestParts( - RequestPartDescriptor... descriptors) { + public static RequestPartsSnippet relaxedRequestParts(RequestPartDescriptor... descriptors) { return relaxedRequestParts(Arrays.asList(descriptors)); } @@ -432,8 +422,7 @@ public static RequestPartsSnippet relaxedRequestParts( * @return the snippet * @see OperationRequest#getParts() */ - public static RequestPartsSnippet relaxedRequestParts( - List descriptors) { + public static RequestPartsSnippet relaxedRequestParts(List descriptors) { return new RequestPartsSnippet(descriptors, true); } diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/request/RequestParametersSnippet.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/request/RequestParametersSnippet.java index 23103e2c4..790a71092 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/request/RequestParametersSnippet.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/request/RequestParametersSnippet.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2016 the original author or authors. + * Copyright 2014-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. @@ -59,8 +59,7 @@ protected RequestParametersSnippet(List descriptors) { * @param ignoreUndocumentedParameters whether undocumented parameters should be * ignored */ - protected RequestParametersSnippet(List descriptors, - boolean ignoreUndocumentedParameters) { + protected RequestParametersSnippet(List descriptors, boolean ignoreUndocumentedParameters) { this(descriptors, null, ignoreUndocumentedParameters); } @@ -72,8 +71,7 @@ protected RequestParametersSnippet(List descriptors, * @param descriptors the parameter descriptors * @param attributes the additional attributes */ - protected RequestParametersSnippet(List descriptors, - Map attributes) { + protected RequestParametersSnippet(List descriptors, Map attributes) { this(descriptors, attributes, false); } @@ -88,19 +86,16 @@ protected RequestParametersSnippet(List descriptors, * @param ignoreUndocumentedParameters whether undocumented parameters should be * ignored */ - protected RequestParametersSnippet(List descriptors, - Map attributes, boolean ignoreUndocumentedParameters) { - super("request-parameters", descriptors, attributes, - ignoreUndocumentedParameters); + protected RequestParametersSnippet(List descriptors, Map attributes, + boolean ignoreUndocumentedParameters) { + super("request-parameters", descriptors, attributes, ignoreUndocumentedParameters); } @Override - protected void verificationFailed(Set undocumentedParameters, - Set missingParameters) { + protected void verificationFailed(Set undocumentedParameters, Set missingParameters) { String message = ""; if (!undocumentedParameters.isEmpty()) { - message += "Request parameters with the following names were not documented: " - + undocumentedParameters; + message += "Request parameters with the following names were not documented: " + undocumentedParameters; } if (!missingParameters.isEmpty()) { if (message.length() > 0) { @@ -136,8 +131,7 @@ public RequestParametersSnippet and(ParameterDescriptor... additionalDescriptors * @return the new snippet */ public RequestParametersSnippet and(List additionalDescriptors) { - List combinedDescriptors = new ArrayList<>( - getParameterDescriptors().values()); + List combinedDescriptors = new ArrayList<>(getParameterDescriptors().values()); combinedDescriptors.addAll(additionalDescriptors); return new RequestParametersSnippet(combinedDescriptors, this.getAttributes()); } diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/request/RequestPartsSnippet.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/request/RequestPartsSnippet.java index 7bce7bb7b..28302de7b 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/request/RequestPartsSnippet.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/request/RequestPartsSnippet.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2016 the original author or authors. + * Copyright 2014-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. @@ -66,8 +66,7 @@ protected RequestPartsSnippet(List descriptors) { * @param descriptors the parameter descriptors * @param ignoreUndocumentedParts whether undocumented parts should be ignored */ - protected RequestPartsSnippet(List descriptors, - boolean ignoreUndocumentedParts) { + protected RequestPartsSnippet(List descriptors, boolean ignoreUndocumentedParts) { this(descriptors, null, ignoreUndocumentedParts); } @@ -78,8 +77,7 @@ protected RequestPartsSnippet(List descriptors, * @param descriptors the parameter descriptors * @param attributes the additional attributes */ - protected RequestPartsSnippet(List descriptors, - Map attributes) { + protected RequestPartsSnippet(List descriptors, Map attributes) { this(descriptors, attributes, false); } @@ -92,17 +90,14 @@ protected RequestPartsSnippet(List descriptors, * @param attributes the additional attributes * @param ignoreUndocumentedParts whether undocumented parts should be ignored */ - protected RequestPartsSnippet(List descriptors, - Map attributes, boolean ignoreUndocumentedParts) { + protected RequestPartsSnippet(List descriptors, Map attributes, + boolean ignoreUndocumentedParts) { super("request-parts", attributes); for (RequestPartDescriptor descriptor : descriptors) { - Assert.notNull(descriptor.getName(), - "Request part descriptors must have a name"); + Assert.notNull(descriptor.getName(), "Request part descriptors must have a name"); if (!descriptor.isIgnored()) { - Assert.notNull(descriptor.getDescription(), - "The descriptor for request part '" + descriptor.getName() - + "' must either have a description or be marked as " - + "ignored"); + Assert.notNull(descriptor.getDescription(), "The descriptor for request part '" + descriptor.getName() + + "' must either have a description or be marked as " + "ignored"); } this.descriptorsByName.put(descriptor.getName(), descriptor); } @@ -125,10 +120,8 @@ public final RequestPartsSnippet and(RequestPartDescriptor... additionalDescript * @param additionalDescriptors the additional descriptors * @return the new snippet */ - public final RequestPartsSnippet and( - List additionalDescriptors) { - List combinedDescriptors = new ArrayList<>( - this.descriptorsByName.values()); + public final RequestPartsSnippet and(List additionalDescriptors) { + List combinedDescriptors = new ArrayList<>(this.descriptorsByName.values()); combinedDescriptors.addAll(additionalDescriptors); return new RequestPartsSnippet(combinedDescriptors, this.getAttributes()); } @@ -138,8 +131,7 @@ protected Map createModel(Operation operation) { verifyRequestPartDescriptors(operation); Map model = new HashMap<>(); List> requestParts = new ArrayList<>(); - for (Entry entry : this.descriptorsByName - .entrySet()) { + for (Entry entry : this.descriptorsByName.entrySet()) { RequestPartDescriptor descriptor = entry.getValue(); if (!descriptor.isIgnored()) { requestParts.add(createModelForDescriptor(descriptor)); @@ -152,8 +144,7 @@ protected Map createModel(Operation operation) { private void verifyRequestPartDescriptors(Operation operation) { Set actualRequestParts = extractActualRequestParts(operation); Set expectedRequestParts = new HashSet<>(); - for (Entry entry : this.descriptorsByName - .entrySet()) { + for (Entry entry : this.descriptorsByName.entrySet()) { if (!entry.getValue().isOptional()) { expectedRequestParts.add(entry.getKey()); } @@ -183,25 +174,22 @@ private Set extractActualRequestParts(Operation operation) { return actualRequestParts; } - private void verificationFailed(Set undocumentedRequestParts, - Set missingRequestParts) { + private void verificationFailed(Set undocumentedRequestParts, Set missingRequestParts) { String message = ""; if (!undocumentedRequestParts.isEmpty()) { - message += "Request parts with the following names were not documented: " - + undocumentedRequestParts; + message += "Request parts with the following names were not documented: " + undocumentedRequestParts; } if (!missingRequestParts.isEmpty()) { if (message.length() > 0) { message += ". "; } - message += "Request parts with the following names were not found in " - + "the request: " + missingRequestParts; + message += "Request parts with the following names were not found in " + "the request: " + + missingRequestParts; } throw new SnippetException(message); } - private Map createModelForDescriptor( - RequestPartDescriptor descriptor) { + private Map createModelForDescriptor(RequestPartDescriptor descriptor) { Map model = new HashMap<>(); model.put("name", descriptor.getName()); model.put("description", descriptor.getDescription()); diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/snippet/IgnorableDescriptor.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/snippet/IgnorableDescriptor.java index fc258fd93..d3ba77250 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/snippet/IgnorableDescriptor.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/snippet/IgnorableDescriptor.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2015 the original author or authors. + * Copyright 2014-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. @@ -22,8 +22,7 @@ * @param the type of the descriptor * @author Andy Wilkinson */ -public abstract class IgnorableDescriptor> - extends AbstractDescriptor { +public abstract class IgnorableDescriptor> extends AbstractDescriptor { private boolean ignored = false; diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/snippet/RestDocumentationContextPlaceholderResolver.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/snippet/RestDocumentationContextPlaceholderResolver.java index af61a99d0..11bf86778 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/snippet/RestDocumentationContextPlaceholderResolver.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/snippet/RestDocumentationContextPlaceholderResolver.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2016 the original author or authors. + * Copyright 2014-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. @@ -133,8 +133,7 @@ private String camelCaseToSeparator(String string, String separator) { Matcher matcher = CAMEL_CASE_PATTERN.matcher(string); StringBuffer result = new StringBuffer(); while (matcher.find()) { - String replacement = (matcher.start() > 0) - ? separator + matcher.group(1).toLowerCase() + String replacement = (matcher.start() > 0) ? separator + matcher.group(1).toLowerCase() : matcher.group(1).toLowerCase(); matcher.appendReplacement(result, replacement); } diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/snippet/RestDocumentationContextPlaceholderResolverFactory.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/snippet/RestDocumentationContextPlaceholderResolverFactory.java index df8e075cb..852b9b8d0 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/snippet/RestDocumentationContextPlaceholderResolverFactory.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/snippet/RestDocumentationContextPlaceholderResolverFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2016 the original author or authors. + * Copyright 2014-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. @@ -26,8 +26,7 @@ * @author Andy Wilkinson * @since 1.1.0 */ -public final class RestDocumentationContextPlaceholderResolverFactory - implements PlaceholderResolverFactory { +public final class RestDocumentationContextPlaceholderResolverFactory implements PlaceholderResolverFactory { @Override public PlaceholderResolver create(RestDocumentationContext context) { diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/snippet/StandardWriterResolver.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/snippet/StandardWriterResolver.java index d8c0d85ac..7a8c3e01d 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/snippet/StandardWriterResolver.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/snippet/StandardWriterResolver.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2016 the original author or authors. + * Copyright 2014-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. @@ -37,8 +37,7 @@ public final class StandardWriterResolver implements WriterResolver { private final PlaceholderResolverFactory placeholderResolverFactory; - private final PropertyPlaceholderHelper propertyPlaceholderHelper = new PropertyPlaceholderHelper( - "{", "}"); + private final PropertyPlaceholderHelper propertyPlaceholderHelper = new PropertyPlaceholderHelper("{", "}"); private String encoding = "UTF-8"; @@ -55,8 +54,7 @@ public final class StandardWriterResolver implements WriterResolver { */ @Deprecated public StandardWriterResolver(PlaceholderResolver placeholderResolver) { - this(new SingleInstancePlaceholderResolverFactory(placeholderResolver), "UTF-8", - TemplateFormats.asciidoctor()); + this(new SingleInstancePlaceholderResolverFactory(placeholderResolver), "UTF-8", TemplateFormats.asciidoctor()); } /** @@ -70,26 +68,24 @@ public StandardWriterResolver(PlaceholderResolver placeholderResolver) { * @param encoding the encoding * @param templateFormat the snippet format */ - public StandardWriterResolver(PlaceholderResolverFactory placeholderResolverFactory, - String encoding, TemplateFormat templateFormat) { + public StandardWriterResolver(PlaceholderResolverFactory placeholderResolverFactory, String encoding, + TemplateFormat templateFormat) { this.placeholderResolverFactory = placeholderResolverFactory; this.encoding = encoding; this.templateFormat = templateFormat; } @Override - public Writer resolve(String operationName, String snippetName, - RestDocumentationContext context) throws IOException { - PlaceholderResolver placeholderResolver = this.placeholderResolverFactory - .create(context); + public Writer resolve(String operationName, String snippetName, RestDocumentationContext context) + throws IOException { + PlaceholderResolver placeholderResolver = this.placeholderResolverFactory.create(context); String outputDirectory = replacePlaceholders(placeholderResolver, operationName); String fileName = replacePlaceholders(placeholderResolver, snippetName) + "." + this.templateFormat.getFileExtension(); File outputFile = resolveFile(outputDirectory, fileName, context); if (outputFile != null) { createDirectoriesIfNecessary(outputFile); - return new OutputStreamWriter(new FileOutputStream(outputFile), - this.encoding); + return new OutputStreamWriter(new FileOutputStream(outputFile), this.encoding); } else { return new OutputStreamWriter(System.out, this.encoding); @@ -106,8 +102,7 @@ private String replacePlaceholders(PlaceholderResolver resolver, String input) { return this.propertyPlaceholderHelper.replacePlaceholders(input, resolver); } - File resolveFile(String outputDirectory, String fileName, - RestDocumentationContext context) { + File resolveFile(String outputDirectory, String fileName, RestDocumentationContext context) { File outputFile = new File(outputDirectory, fileName); if (!outputFile.isAbsolute()) { outputFile = makeRelativeToConfiguredOutputDir(outputFile, context); @@ -115,8 +110,7 @@ File resolveFile(String outputDirectory, String fileName, return outputFile; } - private File makeRelativeToConfiguredOutputDir(File outputFile, - RestDocumentationContext context) { + private File makeRelativeToConfiguredOutputDir(File outputFile, RestDocumentationContext context) { File configuredOutputDir = context.getOutputDirectory(); if (configuredOutputDir != null) { return new File(configuredOutputDir, outputFile.getPath()); @@ -127,18 +121,15 @@ private File makeRelativeToConfiguredOutputDir(File outputFile, private void createDirectoriesIfNecessary(File outputFile) { File parent = outputFile.getParentFile(); if (!parent.isDirectory() && !parent.mkdirs()) { - throw new IllegalStateException( - "Failed to create directory '" + parent + "'"); + throw new IllegalStateException("Failed to create directory '" + parent + "'"); } } - private static final class SingleInstancePlaceholderResolverFactory - implements PlaceholderResolverFactory { + private static final class SingleInstancePlaceholderResolverFactory implements PlaceholderResolverFactory { private final PlaceholderResolver placeholderResolver; - private SingleInstancePlaceholderResolverFactory( - PlaceholderResolver placeholderResolver) { + private SingleInstancePlaceholderResolverFactory(PlaceholderResolver placeholderResolver) { this.placeholderResolver = placeholderResolver; } diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/snippet/TemplatedSnippet.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/snippet/TemplatedSnippet.java index f3786831d..b38735937 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/snippet/TemplatedSnippet.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/snippet/TemplatedSnippet.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-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. @@ -61,8 +61,7 @@ protected TemplatedSnippet(String snippetName, Map attributes) { * @param templateName the name of the template * @param attributes the additional attributes */ - protected TemplatedSnippet(String snippetName, String templateName, - Map attributes) { + protected TemplatedSnippet(String snippetName, String templateName, Map attributes) { this.templateName = templateName; this.snippetName = snippetName; if (attributes != null) { @@ -72,18 +71,15 @@ protected TemplatedSnippet(String snippetName, String templateName, @Override public void document(Operation operation) throws IOException { - RestDocumentationContext context = (RestDocumentationContext) operation - .getAttributes().get(RestDocumentationContext.class.getName()); - WriterResolver writerResolver = (WriterResolver) operation.getAttributes() - .get(WriterResolver.class.getName()); - try (Writer writer = writerResolver.resolve(operation.getName(), this.snippetName, - context)) { + RestDocumentationContext context = (RestDocumentationContext) operation.getAttributes() + .get(RestDocumentationContext.class.getName()); + WriterResolver writerResolver = (WriterResolver) operation.getAttributes().get(WriterResolver.class.getName()); + try (Writer writer = writerResolver.resolve(operation.getName(), this.snippetName, context)) { Map model = createModel(operation); model.putAll(this.attributes); TemplateEngine templateEngine = (TemplateEngine) operation.getAttributes() .get(TemplateEngine.class.getName()); - writer.append( - templateEngine.compileTemplate(this.templateName).render(model)); + writer.append(templateEngine.compileTemplate(this.templateName).render(model)); } } diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/snippet/WriterResolver.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/snippet/WriterResolver.java index 3c9164ba4..846af9cba 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/snippet/WriterResolver.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/snippet/WriterResolver.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2016 the original author or authors. + * Copyright 2014-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. @@ -38,8 +38,8 @@ public interface WriterResolver { * @return the writer * @throws IOException if a writer cannot be resolved */ - Writer resolve(String operationName, String snippetName, - RestDocumentationContext restDocumentationContext) throws IOException; + Writer resolve(String operationName, String snippetName, RestDocumentationContext restDocumentationContext) + throws IOException; /** * Configures the encoding that should be used by any writers produced by this diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/templates/StandardTemplateResourceResolver.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/templates/StandardTemplateResourceResolver.java index c6c177b7a..557c2b68d 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/templates/StandardTemplateResourceResolver.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/templates/StandardTemplateResourceResolver.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2016 the original author or authors. + * Copyright 2014-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. @@ -75,24 +75,20 @@ public Resource resolveTemplateResource(String name) { if (defaultTemplate.exists()) { return defaultTemplate; } - throw new IllegalStateException( - "Template named '" + name + "' could not be resolved"); + throw new IllegalStateException("Template named '" + name + "' could not be resolved"); } private Resource getFormatSpecificCustomTemplate(String name) { - return new ClassPathResource( - String.format("org/springframework/restdocs/templates/%s/%s.snippet", - this.templateFormat.getId(), name)); + return new ClassPathResource(String.format("org/springframework/restdocs/templates/%s/%s.snippet", + this.templateFormat.getId(), name)); } private Resource getCustomTemplate(String name) { - return new ClassPathResource( - String.format("org/springframework/restdocs/templates/%s.snippet", name)); + return new ClassPathResource(String.format("org/springframework/restdocs/templates/%s.snippet", name)); } private Resource getDefaultTemplate(String name) { - return new ClassPathResource(String.format( - "org/springframework/restdocs/templates/%s/default-%s.snippet", + return new ClassPathResource(String.format("org/springframework/restdocs/templates/%s/default-%s.snippet", this.templateFormat.getId(), name)); } diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/templates/mustache/MustacheTemplate.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/templates/mustache/MustacheTemplate.java index 83b3e836d..3fc9e3a41 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/templates/mustache/MustacheTemplate.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/templates/mustache/MustacheTemplate.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-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. @@ -50,8 +50,7 @@ public MustacheTemplate(org.springframework.restdocs.mustache.Template delegate) * @param delegate the delegate to adapt * @param context the context */ - public MustacheTemplate(org.springframework.restdocs.mustache.Template delegate, - Map context) { + public MustacheTemplate(org.springframework.restdocs.mustache.Template delegate, Map context) { this.delegate = delegate; this.context = context; } diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/templates/mustache/MustacheTemplateEngine.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/templates/mustache/MustacheTemplateEngine.java index b16939e87..2820731e8 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/templates/mustache/MustacheTemplateEngine.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/templates/mustache/MustacheTemplateEngine.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2016 the original author or authors. + * Copyright 2014-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. @@ -60,8 +60,7 @@ public MustacheTemplateEngine(TemplateResourceResolver templateResourceResolver) * @param templateResourceResolver the resolver to use * @param compiler the compiler to use */ - public MustacheTemplateEngine(TemplateResourceResolver templateResourceResolver, - Compiler compiler) { + public MustacheTemplateEngine(TemplateResourceResolver templateResourceResolver, Compiler compiler) { this(templateResourceResolver, compiler, Collections.emptyMap()); } @@ -76,8 +75,8 @@ public MustacheTemplateEngine(TemplateResourceResolver templateResourceResolver, * @see MustacheTemplate#MustacheTemplate(org.springframework.restdocs.mustache.Template, * Map) */ - public MustacheTemplateEngine(TemplateResourceResolver templateResourceResolver, - Compiler compiler, Map context) { + public MustacheTemplateEngine(TemplateResourceResolver templateResourceResolver, Compiler compiler, + Map context) { this.templateResourceResolver = templateResourceResolver; this.compiler = compiler; this.context = context; @@ -85,11 +84,8 @@ public MustacheTemplateEngine(TemplateResourceResolver templateResourceResolver, @Override public Template compileTemplate(String name) throws IOException { - Resource templateResource = this.templateResourceResolver - .resolveTemplateResource(name); - return new MustacheTemplate( - this.compiler.compile( - new InputStreamReader(templateResource.getInputStream())), + Resource templateResource = this.templateResourceResolver.resolveTemplateResource(name); + return new MustacheTemplate(this.compiler.compile(new InputStreamReader(templateResource.getInputStream())), this.context); } diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/AbstractSnippetTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/AbstractSnippetTests.java index f5148e781..f04afe0be 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/AbstractSnippetTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/AbstractSnippetTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-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. @@ -55,8 +55,7 @@ public abstract class AbstractSnippetTests { @Parameters(name = "{0}") public static List parameters() { - return Arrays.asList( - new Object[] { "Asciidoctor", TemplateFormats.asciidoctor() }, + return Arrays.asList(new Object[] { "Asciidoctor", TemplateFormats.asciidoctor() }, new Object[] { "Markdown", TemplateFormats.markdown() }); } @@ -79,8 +78,7 @@ public TableCondition tableWithHeader(String... headers) { } public TableCondition tableWithTitleAndHeader(String title, String... headers) { - return SnippetConditions.tableWithTitleAndHeader(this.templateFormat, title, - headers); + return SnippetConditions.tableWithTitleAndHeader(this.templateFormat, title, headers); } public HttpRequestCondition httpRequest(RequestMethod method, String uri) { @@ -92,8 +90,8 @@ public HttpResponseCondition httpResponse(HttpStatus responseStatus) { } protected FileSystemResource snippetResource(String name) { - return new FileSystemResource("src/test/resources/custom-snippet-templates/" - + this.templateFormat.getId() + "/" + name + ".snippet"); + return new FileSystemResource( + "src/test/resources/custom-snippet-templates/" + this.templateFormat.getId() + "/" + name + ".snippet"); } } diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/RestDocumentationGeneratorTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/RestDocumentationGeneratorTests.java index f6adbe8fd..82e10b318 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/RestDocumentationGeneratorTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/RestDocumentationGeneratorTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-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. @@ -54,53 +54,43 @@ public class RestDocumentationGeneratorTests { @SuppressWarnings("unchecked") - private final RequestConverter requestConverter = mock( - RequestConverter.class); + private final RequestConverter requestConverter = mock(RequestConverter.class); @SuppressWarnings("unchecked") - private final ResponseConverter responseConverter = mock( - ResponseConverter.class); + private final ResponseConverter responseConverter = mock(ResponseConverter.class); private final Object request = new Object(); private final Object response = new Object(); private final OperationRequest operationRequest = new OperationRequestFactory() - .create(URI.create("http://localhost:8080"), null, null, new HttpHeaders(), - null, null); + .create(URI.create("http://localhost:8080"), null, null, new HttpHeaders(), null, null); - private final OperationResponse operationResponse = new OperationResponseFactory() - .create(null, null, null); + private final OperationResponse operationResponse = new OperationResponseFactory().create(null, null, null); private final Snippet snippet = mock(Snippet.class); @Test public void basicHandling() throws IOException { - given(this.requestConverter.convert(this.request)) - .willReturn(this.operationRequest); - given(this.responseConverter.convert(this.response)) - .willReturn(this.operationResponse); + given(this.requestConverter.convert(this.request)).willReturn(this.operationRequest); + given(this.responseConverter.convert(this.response)).willReturn(this.operationResponse); HashMap configuration = new HashMap<>(); - new RestDocumentationGenerator<>("id", this.requestConverter, - this.responseConverter, this.snippet).handle(this.request, this.response, - configuration); + new RestDocumentationGenerator<>("id", this.requestConverter, this.responseConverter, this.snippet) + .handle(this.request, this.response, configuration); verifySnippetInvocation(this.snippet, configuration); } @Test public void defaultSnippetsAreCalled() throws IOException { - given(this.requestConverter.convert(this.request)) - .willReturn(this.operationRequest); - given(this.responseConverter.convert(this.response)) - .willReturn(this.operationResponse); + given(this.requestConverter.convert(this.request)).willReturn(this.operationRequest); + given(this.responseConverter.convert(this.response)).willReturn(this.operationResponse); HashMap configuration = new HashMap<>(); Snippet defaultSnippet1 = mock(Snippet.class); Snippet defaultSnippet2 = mock(Snippet.class); configuration.put(RestDocumentationGenerator.ATTRIBUTE_NAME_DEFAULT_SNIPPETS, Arrays.asList(defaultSnippet1, defaultSnippet2)); - new RestDocumentationGenerator<>("id", this.requestConverter, - this.responseConverter, this.snippet).handle(this.request, this.response, - configuration); + new RestDocumentationGenerator<>("id", this.requestConverter, this.responseConverter, this.snippet) + .handle(this.request, this.response, configuration); InOrder inOrder = Mockito.inOrder(defaultSnippet1, defaultSnippet2, this.snippet); verifySnippetInvocation(inOrder, defaultSnippet1, configuration); verifySnippetInvocation(inOrder, defaultSnippet2, configuration); @@ -110,20 +100,17 @@ public void defaultSnippetsAreCalled() throws IOException { @Test @Deprecated public void additionalSnippetsAreCalled() throws IOException { - given(this.requestConverter.convert(this.request)) - .willReturn(this.operationRequest); - given(this.responseConverter.convert(this.response)) - .willReturn(this.operationResponse); + given(this.requestConverter.convert(this.request)).willReturn(this.operationRequest); + given(this.responseConverter.convert(this.response)).willReturn(this.operationResponse); Snippet additionalSnippet1 = mock(Snippet.class); Snippet additionalSnippet2 = mock(Snippet.class); - RestDocumentationGenerator generator = new RestDocumentationGenerator<>( - "id", this.requestConverter, this.responseConverter, this.snippet); + RestDocumentationGenerator generator = new RestDocumentationGenerator<>("id", + this.requestConverter, this.responseConverter, this.snippet); generator.addSnippets(additionalSnippet1, additionalSnippet2); HashMap configuration = new HashMap<>(); generator.handle(this.request, this.response, configuration); generator.handle(this.request, this.response, configuration); - InOrder inOrder = Mockito.inOrder(this.snippet, additionalSnippet1, - additionalSnippet2); + InOrder inOrder = Mockito.inOrder(this.snippet, additionalSnippet1, additionalSnippet2); verifySnippetInvocation(inOrder, this.snippet, configuration); verifySnippetInvocation(inOrder, additionalSnippet1, configuration); verifySnippetInvocation(inOrder, additionalSnippet2, configuration); @@ -133,33 +120,25 @@ public void additionalSnippetsAreCalled() throws IOException { @Test public void newGeneratorOnlyCallsItsSnippets() throws IOException { - OperationRequestPreprocessor requestPreprocessor = mock( - OperationRequestPreprocessor.class); - OperationResponsePreprocessor responsePreprocessor = mock( - OperationResponsePreprocessor.class); - given(this.requestConverter.convert(this.request)) - .willReturn(this.operationRequest); - given(this.responseConverter.convert(this.response)) - .willReturn(this.operationResponse); - given(requestPreprocessor.preprocess(this.operationRequest)) - .willReturn(this.operationRequest); - given(responsePreprocessor.preprocess(this.operationResponse)) - .willReturn(this.operationResponse); + OperationRequestPreprocessor requestPreprocessor = mock(OperationRequestPreprocessor.class); + OperationResponsePreprocessor responsePreprocessor = mock(OperationResponsePreprocessor.class); + given(this.requestConverter.convert(this.request)).willReturn(this.operationRequest); + given(this.responseConverter.convert(this.response)).willReturn(this.operationResponse); + given(requestPreprocessor.preprocess(this.operationRequest)).willReturn(this.operationRequest); + given(responsePreprocessor.preprocess(this.operationResponse)).willReturn(this.operationResponse); Snippet additionalSnippet1 = mock(Snippet.class); Snippet additionalSnippet2 = mock(Snippet.class); - RestDocumentationGenerator generator = new RestDocumentationGenerator<>( - "id", this.requestConverter, this.responseConverter, requestPreprocessor, - responsePreprocessor, this.snippet); + RestDocumentationGenerator generator = new RestDocumentationGenerator<>("id", + this.requestConverter, this.responseConverter, requestPreprocessor, responsePreprocessor, this.snippet); HashMap configuration = new HashMap<>(); - generator.withSnippets(additionalSnippet1, additionalSnippet2) - .handle(this.request, this.response, configuration); + generator.withSnippets(additionalSnippet1, additionalSnippet2).handle(this.request, this.response, + configuration); verifyNoMoreInteractions(this.snippet); verifySnippetInvocation(additionalSnippet1, configuration); verifySnippetInvocation(additionalSnippet2, configuration); } - private void verifySnippetInvocation(Snippet snippet, Map attributes) - throws IOException { + private void verifySnippetInvocation(Snippet snippet, Map attributes) throws IOException { ArgumentCaptor operation = ArgumentCaptor.forClass(Operation.class); verify(snippet).document(operation.capture()); assertThat(this.operationRequest).isEqualTo(operation.getValue().getRequest()); @@ -167,8 +146,8 @@ private void verifySnippetInvocation(Snippet snippet, Map attrib assertThat(attributes).isEqualTo(operation.getValue().getAttributes()); } - private void verifySnippetInvocation(InOrder inOrder, Snippet snippet, - Map attributes) throws IOException { + private void verifySnippetInvocation(InOrder inOrder, Snippet snippet, Map attributes) + throws IOException { ArgumentCaptor operation = ArgumentCaptor.forClass(Operation.class); inOrder.verify(snippet).document(operation.capture()); assertThat(this.operationRequest).isEqualTo(operation.getValue().getRequest()); diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/cli/ConcatenatingCommandFormatterTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/cli/ConcatenatingCommandFormatterTests.java index be6eb7b57..88eb84def 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/cli/ConcatenatingCommandFormatterTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/cli/ConcatenatingCommandFormatterTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-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. @@ -35,8 +35,7 @@ public class ConcatenatingCommandFormatterTests { @Test public void formattingAnEmptyListProducesAnEmptyString() { - assertThat(this.singleLineFormat.format(Collections.emptyList())) - .isEqualTo(""); + assertThat(this.singleLineFormat.format(Collections.emptyList())).isEqualTo(""); } @Test @@ -46,8 +45,7 @@ public void formattingNullProducesAnEmptyString() { @Test public void formattingASingleElement() { - assertThat(this.singleLineFormat.format(Collections.singletonList("alpha"))) - .isEqualTo(" alpha"); + assertThat(this.singleLineFormat.format(Collections.singletonList("alpha"))).isEqualTo(" alpha"); } @Test diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/cli/CurlRequestSnippetTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/cli/CurlRequestSnippetTests.java index dfdc45e9b..fd7d29771 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/cli/CurlRequestSnippetTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/cli/CurlRequestSnippetTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-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. @@ -53,323 +53,277 @@ public CurlRequestSnippetTests(String name, TemplateFormat templateFormat) { public void getRequest() throws IOException { new CurlRequestSnippet(this.commandFormatter) .document(this.operationBuilder.request("http://localhost/foo").build()); - assertThat(this.generatedSnippets.curlRequest()).is( - codeBlock("bash").withContent("$ curl 'http://localhost/foo' -i -X GET")); + assertThat(this.generatedSnippets.curlRequest()) + .is(codeBlock("bash").withContent("$ curl 'http://localhost/foo' -i -X GET")); } @Test public void getRequestWithParameter() throws IOException { - new CurlRequestSnippet(this.commandFormatter).document(this.operationBuilder - .request("http://localhost/foo").param("a", "alpha").build()); - assertThat(this.generatedSnippets.curlRequest()).is(codeBlock("bash") - .withContent("$ curl 'http://localhost/foo?a=alpha' -i -X GET")); + new CurlRequestSnippet(this.commandFormatter) + .document(this.operationBuilder.request("http://localhost/foo").param("a", "alpha").build()); + assertThat(this.generatedSnippets.curlRequest()) + .is(codeBlock("bash").withContent("$ curl 'http://localhost/foo?a=alpha' -i -X GET")); } @Test public void nonGetRequest() throws IOException { - new CurlRequestSnippet(this.commandFormatter).document(this.operationBuilder - .request("http://localhost/foo").method("POST").build()); - assertThat(this.generatedSnippets.curlRequest()).is(codeBlock("bash") - .withContent("$ curl 'http://localhost/foo' -i -X POST")); + new CurlRequestSnippet(this.commandFormatter) + .document(this.operationBuilder.request("http://localhost/foo").method("POST").build()); + assertThat(this.generatedSnippets.curlRequest()) + .is(codeBlock("bash").withContent("$ curl 'http://localhost/foo' -i -X POST")); } @Test public void requestWithContent() throws IOException { - new CurlRequestSnippet(this.commandFormatter).document(this.operationBuilder - .request("http://localhost/foo").content("content").build()); - assertThat(this.generatedSnippets.curlRequest()).is(codeBlock("bash") - .withContent("$ curl 'http://localhost/foo' -i -X GET -d 'content'")); + new CurlRequestSnippet(this.commandFormatter) + .document(this.operationBuilder.request("http://localhost/foo").content("content").build()); + assertThat(this.generatedSnippets.curlRequest()) + .is(codeBlock("bash").withContent("$ curl 'http://localhost/foo' -i -X GET -d 'content'")); } @Test public void getRequestWithQueryString() throws IOException { - new CurlRequestSnippet(this.commandFormatter).document(this.operationBuilder - .request("http://localhost/foo?param=value").build()); - assertThat(this.generatedSnippets.curlRequest()).is(codeBlock("bash") - .withContent("$ curl 'http://localhost/foo?param=value' -i -X GET")); + new CurlRequestSnippet(this.commandFormatter) + .document(this.operationBuilder.request("http://localhost/foo?param=value").build()); + assertThat(this.generatedSnippets.curlRequest()) + .is(codeBlock("bash").withContent("$ curl 'http://localhost/foo?param=value' -i -X GET")); } @Test - public void getRequestWithTotallyOverlappingQueryStringAndParameters() - throws IOException { + public void getRequestWithTotallyOverlappingQueryStringAndParameters() throws IOException { new CurlRequestSnippet(this.commandFormatter).document( - this.operationBuilder.request("http://localhost/foo?param=value") - .param("param", "value").build()); - assertThat(this.generatedSnippets.curlRequest()).is(codeBlock("bash") - .withContent("$ curl 'http://localhost/foo?param=value' -i -X GET")); + this.operationBuilder.request("http://localhost/foo?param=value").param("param", "value").build()); + assertThat(this.generatedSnippets.curlRequest()) + .is(codeBlock("bash").withContent("$ curl 'http://localhost/foo?param=value' -i -X GET")); } @Test - public void getRequestWithPartiallyOverlappingQueryStringAndParameters() - throws IOException { - new CurlRequestSnippet(this.commandFormatter) - .document(this.operationBuilder.request("http://localhost/foo?a=alpha") - .param("a", "alpha").param("b", "bravo").build()); - assertThat(this.generatedSnippets.curlRequest()).is(codeBlock("bash") - .withContent("$ curl 'http://localhost/foo?a=alpha&b=bravo' -i -X GET")); + public void getRequestWithPartiallyOverlappingQueryStringAndParameters() throws IOException { + new CurlRequestSnippet(this.commandFormatter).document(this.operationBuilder + .request("http://localhost/foo?a=alpha").param("a", "alpha").param("b", "bravo").build()); + assertThat(this.generatedSnippets.curlRequest()) + .is(codeBlock("bash").withContent("$ curl 'http://localhost/foo?a=alpha&b=bravo' -i -X GET")); } @Test public void getRequestWithDisjointQueryStringAndParameters() throws IOException { - new CurlRequestSnippet(this.commandFormatter).document(this.operationBuilder - .request("http://localhost/foo?a=alpha").param("b", "bravo").build()); - assertThat(this.generatedSnippets.curlRequest()).is(codeBlock("bash") - .withContent("$ curl 'http://localhost/foo?a=alpha&b=bravo' -i -X GET")); + new CurlRequestSnippet(this.commandFormatter) + .document(this.operationBuilder.request("http://localhost/foo?a=alpha").param("b", "bravo").build()); + assertThat(this.generatedSnippets.curlRequest()) + .is(codeBlock("bash").withContent("$ curl 'http://localhost/foo?a=alpha&b=bravo' -i -X GET")); } @Test public void getRequestWithQueryStringWithNoValue() throws IOException { - new CurlRequestSnippet(this.commandFormatter).document( - this.operationBuilder.request("http://localhost/foo?param").build()); - assertThat(this.generatedSnippets.curlRequest()).is(codeBlock("bash") - .withContent("$ curl 'http://localhost/foo?param' -i -X GET")); + new CurlRequestSnippet(this.commandFormatter) + .document(this.operationBuilder.request("http://localhost/foo?param").build()); + assertThat(this.generatedSnippets.curlRequest()) + .is(codeBlock("bash").withContent("$ curl 'http://localhost/foo?param' -i -X GET")); } @Test public void postRequestWithQueryString() throws IOException { - new CurlRequestSnippet(this.commandFormatter).document(this.operationBuilder - .request("http://localhost/foo?param=value").method("POST").build()); - assertThat(this.generatedSnippets.curlRequest()).is(codeBlock("bash") - .withContent("$ curl 'http://localhost/foo?param=value' -i -X POST")); + new CurlRequestSnippet(this.commandFormatter) + .document(this.operationBuilder.request("http://localhost/foo?param=value").method("POST").build()); + assertThat(this.generatedSnippets.curlRequest()) + .is(codeBlock("bash").withContent("$ curl 'http://localhost/foo?param=value' -i -X POST")); } @Test public void postRequestWithQueryStringWithNoValue() throws IOException { - new CurlRequestSnippet(this.commandFormatter).document(this.operationBuilder - .request("http://localhost/foo?param").method("POST").build()); - assertThat(this.generatedSnippets.curlRequest()).is(codeBlock("bash") - .withContent("$ curl 'http://localhost/foo?param' -i -X POST")); + new CurlRequestSnippet(this.commandFormatter) + .document(this.operationBuilder.request("http://localhost/foo?param").method("POST").build()); + assertThat(this.generatedSnippets.curlRequest()) + .is(codeBlock("bash").withContent("$ curl 'http://localhost/foo?param' -i -X POST")); } @Test public void postRequestWithOneParameter() throws IOException { - new CurlRequestSnippet(this.commandFormatter) - .document(this.operationBuilder.request("http://localhost/foo") - .method("POST").param("k1", "v1").build()); - assertThat(this.generatedSnippets.curlRequest()).is(codeBlock("bash") - .withContent("$ curl 'http://localhost/foo' -i -X POST -d 'k1=v1'")); + new CurlRequestSnippet(this.commandFormatter).document( + this.operationBuilder.request("http://localhost/foo").method("POST").param("k1", "v1").build()); + assertThat(this.generatedSnippets.curlRequest()) + .is(codeBlock("bash").withContent("$ curl 'http://localhost/foo' -i -X POST -d 'k1=v1'")); } @Test public void postRequestWithOneParameterWithNoValue() throws IOException { - new CurlRequestSnippet(this.commandFormatter).document(this.operationBuilder - .request("http://localhost/foo").method("POST").param("k1").build()); - assertThat(this.generatedSnippets.curlRequest()).is(codeBlock("bash") - .withContent("$ curl 'http://localhost/foo' -i -X POST -d 'k1='")); + new CurlRequestSnippet(this.commandFormatter) + .document(this.operationBuilder.request("http://localhost/foo").method("POST").param("k1").build()); + assertThat(this.generatedSnippets.curlRequest()) + .is(codeBlock("bash").withContent("$ curl 'http://localhost/foo' -i -X POST -d 'k1='")); } @Test public void postRequestWithMultipleParameters() throws IOException { - new CurlRequestSnippet(this.commandFormatter).document( - this.operationBuilder.request("http://localhost/foo").method("POST") - .param("k1", "v1", "v1-bis").param("k2", "v2").build()); - assertThat(this.generatedSnippets.curlRequest()).is( - codeBlock("bash").withContent("$ curl 'http://localhost/foo' -i -X POST" - + " -d 'k1=v1&k1=v1-bis&k2=v2'")); + new CurlRequestSnippet(this.commandFormatter).document(this.operationBuilder.request("http://localhost/foo") + .method("POST").param("k1", "v1", "v1-bis").param("k2", "v2").build()); + assertThat(this.generatedSnippets.curlRequest()).is(codeBlock("bash") + .withContent("$ curl 'http://localhost/foo' -i -X POST" + " -d 'k1=v1&k1=v1-bis&k2=v2'")); } @Test public void postRequestWithUrlEncodedParameter() throws IOException { - new CurlRequestSnippet(this.commandFormatter) - .document(this.operationBuilder.request("http://localhost/foo") - .method("POST").param("k1", "a&b").build()); - assertThat(this.generatedSnippets.curlRequest()).is(codeBlock("bash") - .withContent("$ curl 'http://localhost/foo' -i -X POST -d 'k1=a%26b'")); + new CurlRequestSnippet(this.commandFormatter).document( + this.operationBuilder.request("http://localhost/foo").method("POST").param("k1", "a&b").build()); + assertThat(this.generatedSnippets.curlRequest()) + .is(codeBlock("bash").withContent("$ curl 'http://localhost/foo' -i -X POST -d 'k1=a%26b'")); } @Test public void postRequestWithDisjointQueryStringAndParameter() throws IOException { - new CurlRequestSnippet(this.commandFormatter) - .document(this.operationBuilder.request("http://localhost/foo?a=alpha") - .method("POST").param("b", "bravo").build()); - assertThat(this.generatedSnippets.curlRequest()).is(codeBlock("bash").withContent( - "$ curl 'http://localhost/foo?a=alpha' -i -X POST -d 'b=bravo'")); + new CurlRequestSnippet(this.commandFormatter).document(this.operationBuilder + .request("http://localhost/foo?a=alpha").method("POST").param("b", "bravo").build()); + assertThat(this.generatedSnippets.curlRequest()) + .is(codeBlock("bash").withContent("$ curl 'http://localhost/foo?a=alpha' -i -X POST -d 'b=bravo'")); } @Test - public void postRequestWithTotallyOverlappingQueryStringAndParameters() - throws IOException { - new CurlRequestSnippet(this.commandFormatter).document( - this.operationBuilder.request("http://localhost/foo?a=alpha&b=bravo") - .method("POST").param("a", "alpha").param("b", "bravo").build()); - assertThat(this.generatedSnippets.curlRequest()).is(codeBlock("bash") - .withContent("$ curl 'http://localhost/foo?a=alpha&b=bravo' -i -X POST")); + public void postRequestWithTotallyOverlappingQueryStringAndParameters() throws IOException { + new CurlRequestSnippet(this.commandFormatter) + .document(this.operationBuilder.request("http://localhost/foo?a=alpha&b=bravo").method("POST") + .param("a", "alpha").param("b", "bravo").build()); + assertThat(this.generatedSnippets.curlRequest()) + .is(codeBlock("bash").withContent("$ curl 'http://localhost/foo?a=alpha&b=bravo' -i -X POST")); } @Test - public void postRequestWithPartiallyOverlappingQueryStringAndParameters() - throws IOException { + public void postRequestWithPartiallyOverlappingQueryStringAndParameters() throws IOException { new CurlRequestSnippet(this.commandFormatter) - .document(this.operationBuilder.request("http://localhost/foo?a=alpha") - .method("POST").param("a", "alpha").param("b", "bravo").build()); - assertThat(this.generatedSnippets.curlRequest()).is(codeBlock("bash").withContent( - "$ curl 'http://localhost/foo?a=alpha' -i -X POST -d 'b=bravo'")); + .document(this.operationBuilder.request("http://localhost/foo?a=alpha").method("POST") + .param("a", "alpha").param("b", "bravo").build()); + assertThat(this.generatedSnippets.curlRequest()) + .is(codeBlock("bash").withContent("$ curl 'http://localhost/foo?a=alpha' -i -X POST -d 'b=bravo'")); } @Test - public void postRequestWithOverlappingParametersAndFormUrlEncodedBody() - throws IOException { - new CurlRequestSnippet(this.commandFormatter).document(this.operationBuilder - .request("http://localhost/foo").method("POST").content("a=alpha&b=bravo") - .header(HttpHeaders.CONTENT_TYPE, - MediaType.APPLICATION_FORM_URLENCODED_VALUE) - .param("a", "alpha").param("b", "bravo").build()); - assertThat(this.generatedSnippets.curlRequest()).is( - codeBlock("bash").withContent("$ curl 'http://localhost/foo' -i -X POST " - + "-H 'Content-Type: application/x-www-form-urlencoded' " - + "-d 'a=alpha&b=bravo'")); + public void postRequestWithOverlappingParametersAndFormUrlEncodedBody() throws IOException { + new CurlRequestSnippet(this.commandFormatter).document( + this.operationBuilder.request("http://localhost/foo").method("POST").content("a=alpha&b=bravo") + .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_FORM_URLENCODED_VALUE) + .param("a", "alpha").param("b", "bravo").build()); + assertThat(this.generatedSnippets.curlRequest()) + .is(codeBlock("bash").withContent("$ curl 'http://localhost/foo' -i -X POST " + + "-H 'Content-Type: application/x-www-form-urlencoded' " + "-d 'a=alpha&b=bravo'")); } @Test public void putRequestWithOneParameter() throws IOException { - new CurlRequestSnippet(this.commandFormatter).document(this.operationBuilder - .request("http://localhost/foo").method("PUT").param("k1", "v1").build()); - assertThat(this.generatedSnippets.curlRequest()).is(codeBlock("bash") - .withContent("$ curl 'http://localhost/foo' -i -X PUT -d 'k1=v1'")); + new CurlRequestSnippet(this.commandFormatter).document( + this.operationBuilder.request("http://localhost/foo").method("PUT").param("k1", "v1").build()); + assertThat(this.generatedSnippets.curlRequest()) + .is(codeBlock("bash").withContent("$ curl 'http://localhost/foo' -i -X PUT -d 'k1=v1'")); } @Test public void putRequestWithMultipleParameters() throws IOException { - new CurlRequestSnippet(this.commandFormatter).document(this.operationBuilder - .request("http://localhost/foo").method("PUT").param("k1", "v1") - .param("k1", "v1-bis").param("k2", "v2").build()); - assertThat(this.generatedSnippets.curlRequest()).is( - codeBlock("bash").withContent("$ curl 'http://localhost/foo' -i -X PUT" - + " -d 'k1=v1&k1=v1-bis&k2=v2'")); + new CurlRequestSnippet(this.commandFormatter).document(this.operationBuilder.request("http://localhost/foo") + .method("PUT").param("k1", "v1").param("k1", "v1-bis").param("k2", "v2").build()); + assertThat(this.generatedSnippets.curlRequest()).is(codeBlock("bash") + .withContent("$ curl 'http://localhost/foo' -i -X PUT" + " -d 'k1=v1&k1=v1-bis&k2=v2'")); } @Test public void putRequestWithUrlEncodedParameter() throws IOException { - new CurlRequestSnippet(this.commandFormatter) - .document(this.operationBuilder.request("http://localhost/foo") - .method("PUT").param("k1", "a&b").build()); - assertThat(this.generatedSnippets.curlRequest()).is(codeBlock("bash") - .withContent("$ curl 'http://localhost/foo' -i -X PUT -d 'k1=a%26b'")); + new CurlRequestSnippet(this.commandFormatter).document( + this.operationBuilder.request("http://localhost/foo").method("PUT").param("k1", "a&b").build()); + assertThat(this.generatedSnippets.curlRequest()) + .is(codeBlock("bash").withContent("$ curl 'http://localhost/foo' -i -X PUT -d 'k1=a%26b'")); } @Test public void requestWithHeaders() throws IOException { - new CurlRequestSnippet(this.commandFormatter).document(this.operationBuilder - .request("http://localhost/foo") - .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) - .header("a", "alpha").build()); - assertThat(this.generatedSnippets.curlRequest()).is( - codeBlock("bash").withContent("$ curl 'http://localhost/foo' -i -X GET" - + " -H 'Content-Type: application/json' -H 'a: alpha'")); + new CurlRequestSnippet(this.commandFormatter).document(this.operationBuilder.request("http://localhost/foo") + .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE).header("a", "alpha").build()); + assertThat(this.generatedSnippets.curlRequest()).is(codeBlock("bash").withContent( + "$ curl 'http://localhost/foo' -i -X GET" + " -H 'Content-Type: application/json' -H 'a: alpha'")); } @Test public void requestWithHeadersMultiline() throws IOException { - new CurlRequestSnippet(CliDocumentation.multiLineFormat()) - .document(this.operationBuilder.request("http://localhost/foo") - .header(HttpHeaders.CONTENT_TYPE, - MediaType.APPLICATION_JSON_VALUE) - .header("a", "alpha").build()); - assertThat(this.generatedSnippets.curlRequest()).is(codeBlock("bash") - .withContent(String.format("$ curl 'http://localhost/foo' -i -X GET \\%n" - + " -H 'Content-Type: application/json' \\%n" - + " -H 'a: alpha'"))); + new CurlRequestSnippet(CliDocumentation.multiLineFormat()).document(this.operationBuilder + .request("http://localhost/foo").header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) + .header("a", "alpha").build()); + assertThat(this.generatedSnippets.curlRequest()) + .is(codeBlock("bash").withContent(String.format("$ curl 'http://localhost/foo' -i -X GET \\%n" + + " -H 'Content-Type: application/json' \\%n" + " -H 'a: alpha'"))); } @Test public void requestWithCookies() throws IOException { - new CurlRequestSnippet(this.commandFormatter) - .document(this.operationBuilder.request("http://localhost/foo") - .cookie("name1", "value1").cookie("name2", "value2").build()); - assertThat(this.generatedSnippets.curlRequest()).is( - codeBlock("bash").withContent("$ curl 'http://localhost/foo' -i -X GET" - + " --cookie 'name1=value1;name2=value2'")); + new CurlRequestSnippet(this.commandFormatter).document(this.operationBuilder.request("http://localhost/foo") + .cookie("name1", "value1").cookie("name2", "value2").build()); + assertThat(this.generatedSnippets.curlRequest()).is(codeBlock("bash") + .withContent("$ curl 'http://localhost/foo' -i -X GET" + " --cookie 'name1=value1;name2=value2'")); } @Test public void multipartPostWithNoSubmittedFileName() throws IOException { - new CurlRequestSnippet(this.commandFormatter).document(this.operationBuilder - .request("http://localhost/upload").method("POST") - .header(HttpHeaders.CONTENT_TYPE, MediaType.MULTIPART_FORM_DATA_VALUE) + new CurlRequestSnippet(this.commandFormatter).document(this.operationBuilder.request("http://localhost/upload") + .method("POST").header(HttpHeaders.CONTENT_TYPE, MediaType.MULTIPART_FORM_DATA_VALUE) .part("metadata", "{\"description\": \"foo\"}".getBytes()).build()); String expectedContent = "$ curl 'http://localhost/upload' -i -X POST -H " - + "'Content-Type: multipart/form-data' -F " - + "'metadata={\"description\": \"foo\"}'"; - assertThat(this.generatedSnippets.curlRequest()) - .is(codeBlock("bash").withContent(expectedContent)); + + "'Content-Type: multipart/form-data' -F " + "'metadata={\"description\": \"foo\"}'"; + assertThat(this.generatedSnippets.curlRequest()).is(codeBlock("bash").withContent(expectedContent)); } @Test public void multipartPostWithContentType() throws IOException { - new CurlRequestSnippet(this.commandFormatter).document(this.operationBuilder - .request("http://localhost/upload").method("POST") - .header(HttpHeaders.CONTENT_TYPE, MediaType.MULTIPART_FORM_DATA_VALUE) - .part("image", new byte[0]) - .header(HttpHeaders.CONTENT_TYPE, MediaType.IMAGE_PNG_VALUE) + new CurlRequestSnippet(this.commandFormatter).document(this.operationBuilder.request("http://localhost/upload") + .method("POST").header(HttpHeaders.CONTENT_TYPE, MediaType.MULTIPART_FORM_DATA_VALUE) + .part("image", new byte[0]).header(HttpHeaders.CONTENT_TYPE, MediaType.IMAGE_PNG_VALUE) .submittedFileName("documents/images/example.png").build()); String expectedContent = "$ curl 'http://localhost/upload' -i -X POST -H " - + "'Content-Type: multipart/form-data' -F " - + "'image=@documents/images/example.png;type=image/png'"; - assertThat(this.generatedSnippets.curlRequest()) - .is(codeBlock("bash").withContent(expectedContent)); + + "'Content-Type: multipart/form-data' -F " + "'image=@documents/images/example.png;type=image/png'"; + assertThat(this.generatedSnippets.curlRequest()).is(codeBlock("bash").withContent(expectedContent)); } @Test public void multipartPost() throws IOException { - new CurlRequestSnippet(this.commandFormatter).document(this.operationBuilder - .request("http://localhost/upload").method("POST") - .header(HttpHeaders.CONTENT_TYPE, MediaType.MULTIPART_FORM_DATA_VALUE) - .part("image", new byte[0]) - .submittedFileName("documents/images/example.png").build()); + new CurlRequestSnippet(this.commandFormatter).document(this.operationBuilder.request("http://localhost/upload") + .method("POST").header(HttpHeaders.CONTENT_TYPE, MediaType.MULTIPART_FORM_DATA_VALUE) + .part("image", new byte[0]).submittedFileName("documents/images/example.png").build()); String expectedContent = "$ curl 'http://localhost/upload' -i -X POST -H " - + "'Content-Type: multipart/form-data' -F " - + "'image=@documents/images/example.png'"; - assertThat(this.generatedSnippets.curlRequest()) - .is(codeBlock("bash").withContent(expectedContent)); + + "'Content-Type: multipart/form-data' -F " + "'image=@documents/images/example.png'"; + assertThat(this.generatedSnippets.curlRequest()).is(codeBlock("bash").withContent(expectedContent)); } @Test public void multipartPostWithParameters() throws IOException { - new CurlRequestSnippet(this.commandFormatter).document(this.operationBuilder - .request("http://localhost/upload").method("POST") - .header(HttpHeaders.CONTENT_TYPE, MediaType.MULTIPART_FORM_DATA_VALUE) - .part("image", new byte[0]) - .submittedFileName("documents/images/example.png").and() + new CurlRequestSnippet(this.commandFormatter).document(this.operationBuilder.request("http://localhost/upload") + .method("POST").header(HttpHeaders.CONTENT_TYPE, MediaType.MULTIPART_FORM_DATA_VALUE) + .part("image", new byte[0]).submittedFileName("documents/images/example.png").and() .param("a", "apple", "avocado").param("b", "banana").build()); String expectedContent = "$ curl 'http://localhost/upload' -i -X POST -H " + "'Content-Type: multipart/form-data' -F " - + "'image=@documents/images/example.png' -F 'a=apple' -F 'a=avocado' " - + "-F 'b=banana'"; - assertThat(this.generatedSnippets.curlRequest()) - .is(codeBlock("bash").withContent(expectedContent)); + + "'image=@documents/images/example.png' -F 'a=apple' -F 'a=avocado' " + "-F 'b=banana'"; + assertThat(this.generatedSnippets.curlRequest()).is(codeBlock("bash").withContent(expectedContent)); } @Test public void basicAuthCredentialsAreSuppliedUsingUserOption() throws IOException { - new CurlRequestSnippet(this.commandFormatter).document(this.operationBuilder - .request("http://localhost/foo") - .header(HttpHeaders.AUTHORIZATION, - "Basic " + Base64Utils.encodeToString("user:secret".getBytes())) + new CurlRequestSnippet(this.commandFormatter).document(this.operationBuilder.request("http://localhost/foo") + .header(HttpHeaders.AUTHORIZATION, "Basic " + Base64Utils.encodeToString("user:secret".getBytes())) .build()); - assertThat(this.generatedSnippets.curlRequest()).is(codeBlock("bash") - .withContent("$ curl 'http://localhost/foo' -i -u 'user:secret' -X GET")); + assertThat(this.generatedSnippets.curlRequest()) + .is(codeBlock("bash").withContent("$ curl 'http://localhost/foo' -i -u 'user:secret' -X GET")); } @Test public void customAttributes() throws IOException { - new CurlRequestSnippet(this.commandFormatter).document(this.operationBuilder - .request("http://localhost/foo") + new CurlRequestSnippet(this.commandFormatter).document(this.operationBuilder.request("http://localhost/foo") .header(HttpHeaders.HOST, "api.example.com") - .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) - .header("a", "alpha").build()); - assertThat(this.generatedSnippets.curlRequest()).is(codeBlock("bash").withContent( - "$ curl 'http://localhost/foo' -i -X GET -H 'Host: api.example.com'" + .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE).header("a", "alpha").build()); + assertThat(this.generatedSnippets.curlRequest()) + .is(codeBlock("bash").withContent("$ curl 'http://localhost/foo' -i -X GET -H 'Host: api.example.com'" + " -H 'Content-Type: application/json' -H 'a: alpha'")); } @Test public void postWithContentAndParameters() throws IOException { - new CurlRequestSnippet(this.commandFormatter).document(this.operationBuilder - .request("http://localhost/foo").param("a", "alpha").method("POST") - .param("b", "bravo").content("Some content").build()); + new CurlRequestSnippet(this.commandFormatter).document(this.operationBuilder.request("http://localhost/foo") + .param("a", "alpha").method("POST").param("b", "bravo").content("Some content").build()); assertThat(this.generatedSnippets.curlRequest()).is(codeBlock("bash") - .withContent("$ curl 'http://localhost/foo?a=alpha&b=bravo' -i " - + "-X POST -d 'Some content'")); + .withContent("$ curl 'http://localhost/foo?a=alpha&b=bravo' -i " + "-X POST -d 'Some content'")); } } diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/cli/HttpieRequestSnippetTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/cli/HttpieRequestSnippetTests.java index 5176fb833..145796578 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/cli/HttpieRequestSnippetTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/cli/HttpieRequestSnippetTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-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. @@ -60,315 +60,274 @@ public void getRequest() throws IOException { @Test public void getRequestWithParameter() throws IOException { - new HttpieRequestSnippet(this.commandFormatter).document(this.operationBuilder - .request("http://localhost/foo").param("a", "alpha").build()); - assertThat(this.generatedSnippets.httpieRequest()).is(codeBlock("bash") - .withContent("$ http GET 'http://localhost/foo?a=alpha'")); + new HttpieRequestSnippet(this.commandFormatter) + .document(this.operationBuilder.request("http://localhost/foo").param("a", "alpha").build()); + assertThat(this.generatedSnippets.httpieRequest()) + .is(codeBlock("bash").withContent("$ http GET 'http://localhost/foo?a=alpha'")); } @Test public void nonGetRequest() throws IOException { - new HttpieRequestSnippet(this.commandFormatter).document(this.operationBuilder - .request("http://localhost/foo").method("POST").build()); + new HttpieRequestSnippet(this.commandFormatter) + .document(this.operationBuilder.request("http://localhost/foo").method("POST").build()); assertThat(this.generatedSnippets.httpieRequest()) .is(codeBlock("bash").withContent("$ http POST 'http://localhost/foo'")); } @Test public void requestWithContent() throws IOException { - new HttpieRequestSnippet(this.commandFormatter).document(this.operationBuilder - .request("http://localhost/foo").content("content").build()); - assertThat(this.generatedSnippets.httpieRequest()).is(codeBlock("bash") - .withContent("$ echo 'content' | http GET 'http://localhost/foo'")); + new HttpieRequestSnippet(this.commandFormatter) + .document(this.operationBuilder.request("http://localhost/foo").content("content").build()); + assertThat(this.generatedSnippets.httpieRequest()) + .is(codeBlock("bash").withContent("$ echo 'content' | http GET 'http://localhost/foo'")); } @Test public void getRequestWithQueryString() throws IOException { - new HttpieRequestSnippet(this.commandFormatter).document(this.operationBuilder - .request("http://localhost/foo?param=value").build()); - assertThat(this.generatedSnippets.httpieRequest()).is(codeBlock("bash") - .withContent("$ http GET 'http://localhost/foo?param=value'")); + new HttpieRequestSnippet(this.commandFormatter) + .document(this.operationBuilder.request("http://localhost/foo?param=value").build()); + assertThat(this.generatedSnippets.httpieRequest()) + .is(codeBlock("bash").withContent("$ http GET 'http://localhost/foo?param=value'")); } @Test - public void getRequestWithTotallyOverlappingQueryStringAndParameters() - throws IOException { + public void getRequestWithTotallyOverlappingQueryStringAndParameters() throws IOException { new HttpieRequestSnippet(this.commandFormatter).document( - this.operationBuilder.request("http://localhost/foo?param=value") - .param("param", "value").build()); - assertThat(this.generatedSnippets.httpieRequest()).is(codeBlock("bash") - .withContent("$ http GET 'http://localhost/foo?param=value'")); + this.operationBuilder.request("http://localhost/foo?param=value").param("param", "value").build()); + assertThat(this.generatedSnippets.httpieRequest()) + .is(codeBlock("bash").withContent("$ http GET 'http://localhost/foo?param=value'")); } @Test - public void getRequestWithPartiallyOverlappingQueryStringAndParameters() - throws IOException { - new HttpieRequestSnippet(this.commandFormatter) - .document(this.operationBuilder.request("http://localhost/foo?a=alpha") - .param("a", "alpha").param("b", "bravo").build()); - assertThat(this.generatedSnippets.httpieRequest()).is(codeBlock("bash") - .withContent("$ http GET 'http://localhost/foo?a=alpha&b=bravo'")); + public void getRequestWithPartiallyOverlappingQueryStringAndParameters() throws IOException { + new HttpieRequestSnippet(this.commandFormatter).document(this.operationBuilder + .request("http://localhost/foo?a=alpha").param("a", "alpha").param("b", "bravo").build()); + assertThat(this.generatedSnippets.httpieRequest()) + .is(codeBlock("bash").withContent("$ http GET 'http://localhost/foo?a=alpha&b=bravo'")); } @Test public void getRequestWithDisjointQueryStringAndParameters() throws IOException { - new HttpieRequestSnippet(this.commandFormatter).document(this.operationBuilder - .request("http://localhost/foo?a=alpha").param("b", "bravo").build()); - assertThat(this.generatedSnippets.httpieRequest()).is(codeBlock("bash") - .withContent("$ http GET 'http://localhost/foo?a=alpha&b=bravo'")); + new HttpieRequestSnippet(this.commandFormatter) + .document(this.operationBuilder.request("http://localhost/foo?a=alpha").param("b", "bravo").build()); + assertThat(this.generatedSnippets.httpieRequest()) + .is(codeBlock("bash").withContent("$ http GET 'http://localhost/foo?a=alpha&b=bravo'")); } @Test public void getRequestWithQueryStringWithNoValue() throws IOException { - new HttpieRequestSnippet(this.commandFormatter).document( - this.operationBuilder.request("http://localhost/foo?param").build()); - assertThat(this.generatedSnippets.httpieRequest()).is( - codeBlock("bash").withContent("$ http GET 'http://localhost/foo?param'")); + new HttpieRequestSnippet(this.commandFormatter) + .document(this.operationBuilder.request("http://localhost/foo?param").build()); + assertThat(this.generatedSnippets.httpieRequest()) + .is(codeBlock("bash").withContent("$ http GET 'http://localhost/foo?param'")); } @Test public void postRequestWithQueryString() throws IOException { - new HttpieRequestSnippet(this.commandFormatter).document(this.operationBuilder - .request("http://localhost/foo?param=value").method("POST").build()); - assertThat(this.generatedSnippets.httpieRequest()).is(codeBlock("bash") - .withContent("$ http POST 'http://localhost/foo?param=value'")); + new HttpieRequestSnippet(this.commandFormatter) + .document(this.operationBuilder.request("http://localhost/foo?param=value").method("POST").build()); + assertThat(this.generatedSnippets.httpieRequest()) + .is(codeBlock("bash").withContent("$ http POST 'http://localhost/foo?param=value'")); } @Test public void postRequestWithQueryStringWithNoValue() throws IOException { - new HttpieRequestSnippet(this.commandFormatter).document(this.operationBuilder - .request("http://localhost/foo?param").method("POST").build()); - assertThat(this.generatedSnippets.httpieRequest()).is(codeBlock("bash") - .withContent("$ http POST 'http://localhost/foo?param'")); + new HttpieRequestSnippet(this.commandFormatter) + .document(this.operationBuilder.request("http://localhost/foo?param").method("POST").build()); + assertThat(this.generatedSnippets.httpieRequest()) + .is(codeBlock("bash").withContent("$ http POST 'http://localhost/foo?param'")); } @Test public void postRequestWithOneParameter() throws IOException { - new HttpieRequestSnippet(this.commandFormatter) - .document(this.operationBuilder.request("http://localhost/foo") - .method("POST").param("k1", "v1").build()); - assertThat(this.generatedSnippets.httpieRequest()).is(codeBlock("bash") - .withContent("$ http --form POST 'http://localhost/foo' 'k1=v1'")); + new HttpieRequestSnippet(this.commandFormatter).document( + this.operationBuilder.request("http://localhost/foo").method("POST").param("k1", "v1").build()); + assertThat(this.generatedSnippets.httpieRequest()) + .is(codeBlock("bash").withContent("$ http --form POST 'http://localhost/foo' 'k1=v1'")); } @Test public void postRequestWithOneParameterWithNoValue() throws IOException { - new HttpieRequestSnippet(this.commandFormatter).document(this.operationBuilder - .request("http://localhost/foo").method("POST").param("k1").build()); - assertThat(this.generatedSnippets.httpieRequest()).is(codeBlock("bash") - .withContent("$ http --form POST 'http://localhost/foo' 'k1='")); + new HttpieRequestSnippet(this.commandFormatter) + .document(this.operationBuilder.request("http://localhost/foo").method("POST").param("k1").build()); + assertThat(this.generatedSnippets.httpieRequest()) + .is(codeBlock("bash").withContent("$ http --form POST 'http://localhost/foo' 'k1='")); } @Test public void postRequestWithMultipleParameters() throws IOException { - new HttpieRequestSnippet(this.commandFormatter).document( - this.operationBuilder.request("http://localhost/foo").method("POST") - .param("k1", "v1", "v1-bis").param("k2", "v2").build()); - assertThat(this.generatedSnippets.httpieRequest()).is( - codeBlock("bash").withContent("$ http --form POST 'http://localhost/foo'" - + " 'k1=v1' 'k1=v1-bis' 'k2=v2'")); + new HttpieRequestSnippet(this.commandFormatter).document(this.operationBuilder.request("http://localhost/foo") + .method("POST").param("k1", "v1", "v1-bis").param("k2", "v2").build()); + assertThat(this.generatedSnippets.httpieRequest()).is(codeBlock("bash") + .withContent("$ http --form POST 'http://localhost/foo'" + " 'k1=v1' 'k1=v1-bis' 'k2=v2'")); } @Test public void postRequestWithUrlEncodedParameter() throws IOException { - new HttpieRequestSnippet(this.commandFormatter) - .document(this.operationBuilder.request("http://localhost/foo") - .method("POST").param("k1", "a&b").build()); - assertThat(this.generatedSnippets.httpieRequest()).is(codeBlock("bash") - .withContent("$ http --form POST 'http://localhost/foo' 'k1=a&b'")); + new HttpieRequestSnippet(this.commandFormatter).document( + this.operationBuilder.request("http://localhost/foo").method("POST").param("k1", "a&b").build()); + assertThat(this.generatedSnippets.httpieRequest()) + .is(codeBlock("bash").withContent("$ http --form POST 'http://localhost/foo' 'k1=a&b'")); } @Test public void postRequestWithDisjointQueryStringAndParameter() throws IOException { - new HttpieRequestSnippet(this.commandFormatter) - .document(this.operationBuilder.request("http://localhost/foo?a=alpha") - .method("POST").param("b", "bravo").build()); + new HttpieRequestSnippet(this.commandFormatter).document(this.operationBuilder + .request("http://localhost/foo?a=alpha").method("POST").param("b", "bravo").build()); assertThat(this.generatedSnippets.httpieRequest()) - .is(codeBlock("bash").withContent( - "$ http --form POST 'http://localhost/foo?a=alpha' 'b=bravo'")); + .is(codeBlock("bash").withContent("$ http --form POST 'http://localhost/foo?a=alpha' 'b=bravo'")); } @Test - public void postRequestWithTotallyOverlappingQueryStringAndParameters() - throws IOException { - new HttpieRequestSnippet(this.commandFormatter).document( - this.operationBuilder.request("http://localhost/foo?a=alpha&b=bravo") - .method("POST").param("a", "alpha").param("b", "bravo").build()); - assertThat(this.generatedSnippets.httpieRequest()).is(codeBlock("bash") - .withContent("$ http POST 'http://localhost/foo?a=alpha&b=bravo'")); + public void postRequestWithTotallyOverlappingQueryStringAndParameters() throws IOException { + new HttpieRequestSnippet(this.commandFormatter) + .document(this.operationBuilder.request("http://localhost/foo?a=alpha&b=bravo").method("POST") + .param("a", "alpha").param("b", "bravo").build()); + assertThat(this.generatedSnippets.httpieRequest()) + .is(codeBlock("bash").withContent("$ http POST 'http://localhost/foo?a=alpha&b=bravo'")); } @Test - public void postRequestWithPartiallyOverlappingQueryStringAndParameters() - throws IOException { + public void postRequestWithPartiallyOverlappingQueryStringAndParameters() throws IOException { new HttpieRequestSnippet(this.commandFormatter) - .document(this.operationBuilder.request("http://localhost/foo?a=alpha") - .method("POST").param("a", "alpha").param("b", "bravo").build()); + .document(this.operationBuilder.request("http://localhost/foo?a=alpha").method("POST") + .param("a", "alpha").param("b", "bravo").build()); assertThat(this.generatedSnippets.httpieRequest()) - .is(codeBlock("bash").withContent( - "$ http --form POST 'http://localhost/foo?a=alpha' 'b=bravo'")); + .is(codeBlock("bash").withContent("$ http --form POST 'http://localhost/foo?a=alpha' 'b=bravo'")); } @Test - public void postRequestWithOverlappingParametersAndFormUrlEncodedBody() - throws IOException { - new HttpieRequestSnippet(this.commandFormatter).document(this.operationBuilder - .request("http://localhost/foo").method("POST").content("a=alpha&b=bravo") - .header(HttpHeaders.CONTENT_TYPE, - MediaType.APPLICATION_FORM_URLENCODED_VALUE) - .param("a", "alpha").param("b", "bravo").build()); + public void postRequestWithOverlappingParametersAndFormUrlEncodedBody() throws IOException { + new HttpieRequestSnippet(this.commandFormatter).document( + this.operationBuilder.request("http://localhost/foo").method("POST").content("a=alpha&b=bravo") + .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_FORM_URLENCODED_VALUE) + .param("a", "alpha").param("b", "bravo").build()); assertThat(this.generatedSnippets.httpieRequest()) - .is(codeBlock("bash").withContent( - "$ echo 'a=alpha&b=bravo' | http POST 'http://localhost/foo' " - + "'Content-Type:application/x-www-form-urlencoded'")); + .is(codeBlock("bash").withContent("$ echo 'a=alpha&b=bravo' | http POST 'http://localhost/foo' " + + "'Content-Type:application/x-www-form-urlencoded'")); } @Test public void putRequestWithOneParameter() throws IOException { - new HttpieRequestSnippet(this.commandFormatter).document(this.operationBuilder - .request("http://localhost/foo").method("PUT").param("k1", "v1").build()); - assertThat(this.generatedSnippets.httpieRequest()).is(codeBlock("bash") - .withContent("$ http --form PUT 'http://localhost/foo' 'k1=v1'")); + new HttpieRequestSnippet(this.commandFormatter).document( + this.operationBuilder.request("http://localhost/foo").method("PUT").param("k1", "v1").build()); + assertThat(this.generatedSnippets.httpieRequest()) + .is(codeBlock("bash").withContent("$ http --form PUT 'http://localhost/foo' 'k1=v1'")); } @Test public void putRequestWithMultipleParameters() throws IOException { - new HttpieRequestSnippet(this.commandFormatter).document(this.operationBuilder - .request("http://localhost/foo").method("PUT").param("k1", "v1") - .param("k1", "v1-bis").param("k2", "v2").build()); - assertThat(this.generatedSnippets.httpieRequest()).is( - codeBlock("bash").withContent("$ http --form PUT 'http://localhost/foo'" - + " 'k1=v1' 'k1=v1-bis' 'k2=v2'")); + new HttpieRequestSnippet(this.commandFormatter).document(this.operationBuilder.request("http://localhost/foo") + .method("PUT").param("k1", "v1").param("k1", "v1-bis").param("k2", "v2").build()); + assertThat(this.generatedSnippets.httpieRequest()).is(codeBlock("bash") + .withContent("$ http --form PUT 'http://localhost/foo'" + " 'k1=v1' 'k1=v1-bis' 'k2=v2'")); } @Test public void putRequestWithUrlEncodedParameter() throws IOException { - new HttpieRequestSnippet(this.commandFormatter) - .document(this.operationBuilder.request("http://localhost/foo") - .method("PUT").param("k1", "a&b").build()); - assertThat(this.generatedSnippets.httpieRequest()).is(codeBlock("bash") - .withContent("$ http --form PUT 'http://localhost/foo' 'k1=a&b'")); + new HttpieRequestSnippet(this.commandFormatter).document( + this.operationBuilder.request("http://localhost/foo").method("PUT").param("k1", "a&b").build()); + assertThat(this.generatedSnippets.httpieRequest()) + .is(codeBlock("bash").withContent("$ http --form PUT 'http://localhost/foo' 'k1=a&b'")); } @Test public void requestWithHeaders() throws IOException { - new HttpieRequestSnippet(this.commandFormatter).document(this.operationBuilder - .request("http://localhost/foo") - .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) - .header("a", "alpha").build()); - assertThat(this.generatedSnippets.httpieRequest()) - .is(codeBlock("bash").withContent("$ http GET 'http://localhost/foo'" - + " 'Content-Type:application/json' 'a:alpha'")); + new HttpieRequestSnippet(this.commandFormatter).document(this.operationBuilder.request("http://localhost/foo") + .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE).header("a", "alpha").build()); + assertThat(this.generatedSnippets.httpieRequest()).is(codeBlock("bash") + .withContent("$ http GET 'http://localhost/foo'" + " 'Content-Type:application/json' 'a:alpha'")); } @Test public void requestWithHeadersMultiline() throws IOException { - new HttpieRequestSnippet(CliDocumentation.multiLineFormat()) - .document(this.operationBuilder.request("http://localhost/foo") - .header(HttpHeaders.CONTENT_TYPE, - MediaType.APPLICATION_JSON_VALUE) - .header("a", "alpha").build()); - assertThat(this.generatedSnippets.httpieRequest()).is(codeBlock("bash") - .withContent(String.format("$ http GET 'http://localhost/foo' \\%n" - + " 'Content-Type:application/json' \\%n 'a:alpha'"))); + new HttpieRequestSnippet(CliDocumentation.multiLineFormat()).document(this.operationBuilder + .request("http://localhost/foo").header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) + .header("a", "alpha").build()); + assertThat(this.generatedSnippets.httpieRequest()).is(codeBlock("bash").withContent(String.format( + "$ http GET 'http://localhost/foo' \\%n" + " 'Content-Type:application/json' \\%n 'a:alpha'"))); } @Test public void requestWithCookies() throws IOException { - new HttpieRequestSnippet(this.commandFormatter) - .document(this.operationBuilder.request("http://localhost/foo") - .cookie("name1", "value1").cookie("name2", "value2").build()); - assertThat(this.generatedSnippets.httpieRequest()) - .is(codeBlock("bash").withContent("$ http GET 'http://localhost/foo'" - + " 'Cookie:name1=value1' 'Cookie:name2=value2'")); + new HttpieRequestSnippet(this.commandFormatter).document(this.operationBuilder.request("http://localhost/foo") + .cookie("name1", "value1").cookie("name2", "value2").build()); + assertThat(this.generatedSnippets.httpieRequest()).is(codeBlock("bash") + .withContent("$ http GET 'http://localhost/foo'" + " 'Cookie:name1=value1' 'Cookie:name2=value2'")); } @Test public void multipartPostWithNoSubmittedFileName() throws IOException { - new HttpieRequestSnippet(this.commandFormatter).document(this.operationBuilder - .request("http://localhost/upload").method("POST") - .header(HttpHeaders.CONTENT_TYPE, MediaType.MULTIPART_FORM_DATA_VALUE) - .part("metadata", "{\"description\": \"foo\"}".getBytes()).build()); + new HttpieRequestSnippet(this.commandFormatter) + .document(this.operationBuilder.request("http://localhost/upload").method("POST") + .header(HttpHeaders.CONTENT_TYPE, MediaType.MULTIPART_FORM_DATA_VALUE) + .part("metadata", "{\"description\": \"foo\"}".getBytes()).build()); String expectedContent = "$ http --form POST 'http://localhost/upload'" + " 'metadata'@<(echo '{\"description\": \"foo\"}')"; - assertThat(this.generatedSnippets.httpieRequest()) - .is(codeBlock("bash").withContent(expectedContent)); + assertThat(this.generatedSnippets.httpieRequest()).is(codeBlock("bash").withContent(expectedContent)); } @Test public void multipartPostWithContentType() throws IOException { - new HttpieRequestSnippet(this.commandFormatter).document(this.operationBuilder - .request("http://localhost/upload").method("POST") - .header(HttpHeaders.CONTENT_TYPE, MediaType.MULTIPART_FORM_DATA_VALUE) - .part("image", new byte[0]) - .header(HttpHeaders.CONTENT_TYPE, MediaType.IMAGE_PNG_VALUE) - .submittedFileName("documents/images/example.png").build()); + new HttpieRequestSnippet(this.commandFormatter) + .document(this.operationBuilder.request("http://localhost/upload").method("POST") + .header(HttpHeaders.CONTENT_TYPE, MediaType.MULTIPART_FORM_DATA_VALUE) + .part("image", new byte[0]).header(HttpHeaders.CONTENT_TYPE, MediaType.IMAGE_PNG_VALUE) + .submittedFileName("documents/images/example.png").build()); // httpie does not yet support manually set content type by part String expectedContent = "$ http --form POST 'http://localhost/upload'" + " 'image'@'documents/images/example.png'"; - assertThat(this.generatedSnippets.httpieRequest()) - .is(codeBlock("bash").withContent(expectedContent)); + assertThat(this.generatedSnippets.httpieRequest()).is(codeBlock("bash").withContent(expectedContent)); } @Test public void multipartPost() throws IOException { - new HttpieRequestSnippet(this.commandFormatter).document(this.operationBuilder - .request("http://localhost/upload").method("POST") - .header(HttpHeaders.CONTENT_TYPE, MediaType.MULTIPART_FORM_DATA_VALUE) - .part("image", new byte[0]) - .submittedFileName("documents/images/example.png").build()); + new HttpieRequestSnippet(this.commandFormatter) + .document(this.operationBuilder.request("http://localhost/upload").method("POST") + .header(HttpHeaders.CONTENT_TYPE, MediaType.MULTIPART_FORM_DATA_VALUE) + .part("image", new byte[0]).submittedFileName("documents/images/example.png").build()); String expectedContent = "$ http --form POST 'http://localhost/upload'" + " 'image'@'documents/images/example.png'"; - assertThat(this.generatedSnippets.httpieRequest()) - .is(codeBlock("bash").withContent(expectedContent)); + assertThat(this.generatedSnippets.httpieRequest()).is(codeBlock("bash").withContent(expectedContent)); } @Test public void multipartPostWithParameters() throws IOException { - new HttpieRequestSnippet(this.commandFormatter).document(this.operationBuilder - .request("http://localhost/upload").method("POST") - .header(HttpHeaders.CONTENT_TYPE, MediaType.MULTIPART_FORM_DATA_VALUE) - .part("image", new byte[0]) - .submittedFileName("documents/images/example.png").and() - .param("a", "apple", "avocado").param("b", "banana").build()); + new HttpieRequestSnippet(this.commandFormatter) + .document(this.operationBuilder.request("http://localhost/upload").method("POST") + .header(HttpHeaders.CONTENT_TYPE, MediaType.MULTIPART_FORM_DATA_VALUE) + .part("image", new byte[0]).submittedFileName("documents/images/example.png").and() + .param("a", "apple", "avocado").param("b", "banana").build()); String expectedContent = "$ http --form POST 'http://localhost/upload'" - + " 'image'@'documents/images/example.png' 'a=apple' 'a=avocado'" - + " 'b=banana'"; - assertThat(this.generatedSnippets.httpieRequest()) - .is(codeBlock("bash").withContent(expectedContent)); + + " 'image'@'documents/images/example.png' 'a=apple' 'a=avocado'" + " 'b=banana'"; + assertThat(this.generatedSnippets.httpieRequest()).is(codeBlock("bash").withContent(expectedContent)); } @Test public void basicAuthCredentialsAreSuppliedUsingAuthOption() throws IOException { - new HttpieRequestSnippet(this.commandFormatter).document(this.operationBuilder - .request("http://localhost/foo") - .header(HttpHeaders.AUTHORIZATION, - "Basic " + Base64Utils.encodeToString("user:secret".getBytes())) + new HttpieRequestSnippet(this.commandFormatter).document(this.operationBuilder.request("http://localhost/foo") + .header(HttpHeaders.AUTHORIZATION, "Basic " + Base64Utils.encodeToString("user:secret".getBytes())) .build()); - assertThat(this.generatedSnippets.httpieRequest()).is(codeBlock("bash") - .withContent("$ http --auth 'user:secret' GET 'http://localhost/foo'")); + assertThat(this.generatedSnippets.httpieRequest()) + .is(codeBlock("bash").withContent("$ http --auth 'user:secret' GET 'http://localhost/foo'")); } @Test public void customAttributes() throws IOException { - new HttpieRequestSnippet(this.commandFormatter).document(this.operationBuilder - .request("http://localhost/foo") + new HttpieRequestSnippet(this.commandFormatter).document(this.operationBuilder.request("http://localhost/foo") .header(HttpHeaders.HOST, "api.example.com") - .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) - .header("a", "alpha").build()); - assertThat(this.generatedSnippets.httpieRequest()).is(codeBlock("bash") - .withContent("$ http GET 'http://localhost/foo' 'Host:api.example.com'" + .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE).header("a", "alpha").build()); + assertThat(this.generatedSnippets.httpieRequest()) + .is(codeBlock("bash").withContent("$ http GET 'http://localhost/foo' 'Host:api.example.com'" + " 'Content-Type:application/json' 'a:alpha'")); } @Test public void postWithContentAndParameters() throws IOException { - new HttpieRequestSnippet(this.commandFormatter).document(this.operationBuilder - .request("http://localhost/foo").method("POST").param("a", "alpha") - .param("b", "bravo").content("Some content").build()); - assertThat(this.generatedSnippets.httpieRequest()) - .is(codeBlock("bash").withContent("$ echo 'Some content' | http POST " - + "'http://localhost/foo?a=alpha&b=bravo'")); + new HttpieRequestSnippet(this.commandFormatter).document(this.operationBuilder.request("http://localhost/foo") + .method("POST").param("a", "alpha").param("b", "bravo").content("Some content").build()); + assertThat(this.generatedSnippets.httpieRequest()).is(codeBlock("bash") + .withContent("$ echo 'Some content' | http POST " + "'http://localhost/foo?a=alpha&b=bravo'")); } } 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 723522fbd..3bb631e10 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 @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-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. @@ -59,62 +59,48 @@ public void defaultConfiguration() { Map configuration = new HashMap<>(); this.configurer.apply(configuration, createContext()); assertThat(configuration).containsKey(TemplateEngine.class.getName()); - assertThat(configuration.get(TemplateEngine.class.getName())) - .isInstanceOf(MustacheTemplateEngine.class); + assertThat(configuration.get(TemplateEngine.class.getName())).isInstanceOf(MustacheTemplateEngine.class); assertThat(configuration).containsKey(WriterResolver.class.getName()); - assertThat(configuration.get(WriterResolver.class.getName())) - .isInstanceOf(StandardWriterResolver.class); - assertThat(configuration) - .containsKey(RestDocumentationGenerator.ATTRIBUTE_NAME_DEFAULT_SNIPPETS); - assertThat(configuration - .get(RestDocumentationGenerator.ATTRIBUTE_NAME_DEFAULT_SNIPPETS)) - .isInstanceOf(List.class); + assertThat(configuration.get(WriterResolver.class.getName())).isInstanceOf(StandardWriterResolver.class); + assertThat(configuration).containsKey(RestDocumentationGenerator.ATTRIBUTE_NAME_DEFAULT_SNIPPETS); + assertThat(configuration.get(RestDocumentationGenerator.ATTRIBUTE_NAME_DEFAULT_SNIPPETS)) + .isInstanceOf(List.class); List defaultSnippets = (List) configuration .get(RestDocumentationGenerator.ATTRIBUTE_NAME_DEFAULT_SNIPPETS); - assertThat(defaultSnippets).extracting("class").containsExactlyInAnyOrder( - CurlRequestSnippet.class, HttpieRequestSnippet.class, - HttpRequestSnippet.class, HttpResponseSnippet.class, + assertThat(defaultSnippets).extracting("class").containsExactlyInAnyOrder(CurlRequestSnippet.class, + HttpieRequestSnippet.class, HttpRequestSnippet.class, HttpResponseSnippet.class, RequestBodySnippet.class, ResponseBodySnippet.class); assertThat(configuration).containsKey(SnippetConfiguration.class.getName()); - assertThat(configuration.get(SnippetConfiguration.class.getName())) - .isInstanceOf(SnippetConfiguration.class); + assertThat(configuration.get(SnippetConfiguration.class.getName())).isInstanceOf(SnippetConfiguration.class); SnippetConfiguration snippetConfiguration = (SnippetConfiguration) configuration .get(SnippetConfiguration.class.getName()); assertThat(snippetConfiguration.getEncoding()).isEqualTo("UTF-8"); - assertThat(snippetConfiguration.getTemplateFormat().getId()) - .isEqualTo(TemplateFormats.asciidoctor().getId()); + assertThat(snippetConfiguration.getTemplateFormat().getId()).isEqualTo(TemplateFormats.asciidoctor().getId()); } @Test public void customTemplateEngine() { Map configuration = new HashMap<>(); TemplateEngine templateEngine = mock(TemplateEngine.class); - this.configurer.templateEngine(templateEngine).apply(configuration, - createContext()); - assertThat(configuration).containsEntry(TemplateEngine.class.getName(), - templateEngine); + this.configurer.templateEngine(templateEngine).apply(configuration, createContext()); + assertThat(configuration).containsEntry(TemplateEngine.class.getName(), templateEngine); } @Test public void customWriterResolver() { Map configuration = new HashMap<>(); WriterResolver writerResolver = mock(WriterResolver.class); - this.configurer.writerResolver(writerResolver).apply(configuration, - createContext()); - assertThat(configuration).containsEntry(WriterResolver.class.getName(), - writerResolver); + this.configurer.writerResolver(writerResolver).apply(configuration, createContext()); + assertThat(configuration).containsEntry(WriterResolver.class.getName(), writerResolver); } @Test public void customDefaultSnippets() { Map configuration = new HashMap<>(); - this.configurer.snippets().withDefaults(CliDocumentation.curlRequest()) - .apply(configuration, createContext()); - assertThat(configuration) - .containsKey(RestDocumentationGenerator.ATTRIBUTE_NAME_DEFAULT_SNIPPETS); - assertThat(configuration - .get(RestDocumentationGenerator.ATTRIBUTE_NAME_DEFAULT_SNIPPETS)) - .isInstanceOf(List.class); + this.configurer.snippets().withDefaults(CliDocumentation.curlRequest()).apply(configuration, createContext()); + assertThat(configuration).containsKey(RestDocumentationGenerator.ATTRIBUTE_NAME_DEFAULT_SNIPPETS); + assertThat(configuration.get(RestDocumentationGenerator.ATTRIBUTE_NAME_DEFAULT_SNIPPETS)) + .isInstanceOf(List.class); @SuppressWarnings("unchecked") List defaultSnippets = (List) configuration .get(RestDocumentationGenerator.ATTRIBUTE_NAME_DEFAULT_SNIPPETS); @@ -127,29 +113,23 @@ public void customDefaultSnippets() { public void additionalDefaultSnippets() { Map configuration = new HashMap<>(); Snippet snippet = mock(Snippet.class); - this.configurer.snippets().withAdditionalDefaults(snippet).apply(configuration, - createContext()); - assertThat(configuration) - .containsKey(RestDocumentationGenerator.ATTRIBUTE_NAME_DEFAULT_SNIPPETS); - assertThat(configuration - .get(RestDocumentationGenerator.ATTRIBUTE_NAME_DEFAULT_SNIPPETS)) - .isInstanceOf(List.class); + this.configurer.snippets().withAdditionalDefaults(snippet).apply(configuration, createContext()); + assertThat(configuration).containsKey(RestDocumentationGenerator.ATTRIBUTE_NAME_DEFAULT_SNIPPETS); + assertThat(configuration.get(RestDocumentationGenerator.ATTRIBUTE_NAME_DEFAULT_SNIPPETS)) + .isInstanceOf(List.class); List defaultSnippets = (List) configuration .get(RestDocumentationGenerator.ATTRIBUTE_NAME_DEFAULT_SNIPPETS); - assertThat(defaultSnippets).extracting("class").containsExactlyInAnyOrder( - CurlRequestSnippet.class, HttpieRequestSnippet.class, - HttpRequestSnippet.class, HttpResponseSnippet.class, + assertThat(defaultSnippets).extracting("class").containsExactlyInAnyOrder(CurlRequestSnippet.class, + HttpieRequestSnippet.class, HttpRequestSnippet.class, HttpResponseSnippet.class, RequestBodySnippet.class, ResponseBodySnippet.class, snippet.getClass()); } @Test public void customSnippetEncoding() { Map configuration = new HashMap<>(); - this.configurer.snippets().withEncoding("ISO 8859-1").apply(configuration, - createContext()); + this.configurer.snippets().withEncoding("ISO 8859-1").apply(configuration, createContext()); assertThat(configuration).containsKey(SnippetConfiguration.class.getName()); - assertThat(configuration.get(SnippetConfiguration.class.getName())) - .isInstanceOf(SnippetConfiguration.class); + assertThat(configuration.get(SnippetConfiguration.class.getName())).isInstanceOf(SnippetConfiguration.class); SnippetConfiguration snippetConfiguration = (SnippetConfiguration) configuration .get(SnippetConfiguration.class.getName()); assertThat(snippetConfiguration.getEncoding()).isEqualTo("ISO 8859-1"); @@ -158,15 +138,12 @@ public void customSnippetEncoding() { @Test public void customTemplateFormat() { Map configuration = new HashMap<>(); - this.configurer.snippets().withTemplateFormat(TemplateFormats.markdown()) - .apply(configuration, createContext()); + this.configurer.snippets().withTemplateFormat(TemplateFormats.markdown()).apply(configuration, createContext()); assertThat(configuration).containsKey(SnippetConfiguration.class.getName()); - assertThat(configuration.get(SnippetConfiguration.class.getName())) - .isInstanceOf(SnippetConfiguration.class); + assertThat(configuration.get(SnippetConfiguration.class.getName())).isInstanceOf(SnippetConfiguration.class); SnippetConfiguration snippetConfiguration = (SnippetConfiguration) configuration .get(SnippetConfiguration.class.getName()); - assertThat(snippetConfiguration.getTemplateFormat().getId()) - .isEqualTo(TemplateFormats.markdown().getId()); + assertThat(snippetConfiguration.getTemplateFormat().getId()).isEqualTo(TemplateFormats.markdown().getId()); } @SuppressWarnings("unchecked") @@ -174,14 +151,12 @@ public void customTemplateFormat() { public void asciidoctorTableCellContentLambaIsInstalledWhenUsingAsciidoctorTemplateFormat() { Map configuration = new HashMap<>(); this.configurer.apply(configuration, createContext()); - TemplateEngine templateEngine = (TemplateEngine) configuration - .get(TemplateEngine.class.getName()); + TemplateEngine templateEngine = (TemplateEngine) configuration.get(TemplateEngine.class.getName()); MustacheTemplateEngine mustacheTemplateEngine = (MustacheTemplateEngine) templateEngine; - Map templateContext = (Map) ReflectionTestUtils - .getField(mustacheTemplateEngine, "context"); + Map templateContext = (Map) ReflectionTestUtils.getField(mustacheTemplateEngine, + "context"); assertThat(templateContext).containsKey("tableCellContent"); - assertThat(templateContext.get("tableCellContent")) - .isInstanceOf(AsciidoctorTableCellContentLambda.class); + assertThat(templateContext.get("tableCellContent")).isInstanceOf(AsciidoctorTableCellContentLambda.class); } @SuppressWarnings("unchecked") @@ -190,27 +165,24 @@ public void asciidoctorTableCellContentLambaIsNotInstalledWhenUsingNonAsciidocto Map configuration = new HashMap<>(); this.configurer.snippetConfigurer.withTemplateFormat(TemplateFormats.markdown()); this.configurer.apply(configuration, createContext()); - TemplateEngine templateEngine = (TemplateEngine) configuration - .get(TemplateEngine.class.getName()); + TemplateEngine templateEngine = (TemplateEngine) configuration.get(TemplateEngine.class.getName()); MustacheTemplateEngine mustacheTemplateEngine = (MustacheTemplateEngine) templateEngine; - Map templateContext = (Map) ReflectionTestUtils - .getField(mustacheTemplateEngine, "context"); + Map templateContext = (Map) ReflectionTestUtils.getField(mustacheTemplateEngine, + "context"); assertThat(templateContext.size()).isEqualTo(0); } private RestDocumentationContext createContext() { - ManualRestDocumentation manualRestDocumentation = new ManualRestDocumentation( - "build"); + ManualRestDocumentation manualRestDocumentation = new ManualRestDocumentation("build"); manualRestDocumentation.beforeTest(null, null); RestDocumentationContext context = manualRestDocumentation.beforeOperation(); return context; } - private static final class TestRestDocumentationConfigurer extends - RestDocumentationConfigurer { + private static final class TestRestDocumentationConfigurer + extends RestDocumentationConfigurer { - private final TestSnippetConfigurer snippetConfigurer = new TestSnippetConfigurer( - this); + private final TestSnippetConfigurer snippetConfigurer = new TestSnippetConfigurer(this); @Override public TestSnippetConfigurer snippets() { @@ -219,8 +191,8 @@ public TestSnippetConfigurer snippets() { } - private static final class TestSnippetConfigurer extends - SnippetConfigurer { + private static final class TestSnippetConfigurer + extends SnippetConfigurer { private TestSnippetConfigurer(TestRestDocumentationConfigurer parent) { super(parent); diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/constraints/ConstraintDescriptionsTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/constraints/ConstraintDescriptionsTests.java index 47b7f6737..94d8d63ae 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/constraints/ConstraintDescriptionsTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/constraints/ConstraintDescriptionsTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2015 the original author or authors. + * Copyright 2014-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. @@ -37,32 +37,25 @@ public class ConstraintDescriptionsTests { private final ConstraintDescriptionResolver constraintDescriptionResolver = mock( ConstraintDescriptionResolver.class); - private final ConstraintDescriptions constraintDescriptions = new ConstraintDescriptions( - Constrained.class, this.constraintResolver, - this.constraintDescriptionResolver); + private final ConstraintDescriptions constraintDescriptions = new ConstraintDescriptions(Constrained.class, + this.constraintResolver, this.constraintDescriptionResolver); @Test public void descriptionsForConstraints() { - Constraint constraint1 = new Constraint("constraint1", - Collections.emptyMap()); - Constraint constraint2 = new Constraint("constraint2", - Collections.emptyMap()); + Constraint constraint1 = new Constraint("constraint1", Collections.emptyMap()); + Constraint constraint2 = new Constraint("constraint2", Collections.emptyMap()); given(this.constraintResolver.resolveForProperty("foo", Constrained.class)) .willReturn(Arrays.asList(constraint1, constraint2)); - given(this.constraintDescriptionResolver.resolveDescription(constraint1)) - .willReturn("Bravo"); - given(this.constraintDescriptionResolver.resolveDescription(constraint2)) - .willReturn("Alpha"); - assertThat(this.constraintDescriptions.descriptionsForProperty("foo")) - .containsExactly("Alpha", "Bravo"); + given(this.constraintDescriptionResolver.resolveDescription(constraint1)).willReturn("Bravo"); + given(this.constraintDescriptionResolver.resolveDescription(constraint2)).willReturn("Alpha"); + assertThat(this.constraintDescriptions.descriptionsForProperty("foo")).containsExactly("Alpha", "Bravo"); } @Test public void emptyListOfDescriptionsWhenThereAreNoConstraints() { given(this.constraintResolver.resolveForProperty("foo", Constrained.class)) .willReturn(Collections.emptyList()); - assertThat(this.constraintDescriptions.descriptionsForProperty("foo").size()) - .isEqualTo(0); + assertThat(this.constraintDescriptions.descriptionsForProperty("foo").size()).isEqualTo(0); } private static class Constrained { diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/constraints/ResourceBundleConstraintDescriptionResolverTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/constraints/ResourceBundleConstraintDescriptionResolverTests.java index fead05a51..a30d95bfa 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/constraints/ResourceBundleConstraintDescriptionResolverTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/constraints/ResourceBundleConstraintDescriptionResolverTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-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. @@ -69,8 +69,7 @@ public class ResourceBundleConstraintDescriptionResolverTests { @Test public void defaultMessageAssertFalse() { - assertThat(constraintDescriptionForField("assertFalse")) - .isEqualTo("Must be false"); + assertThat(constraintDescriptionForField("assertFalse")).isEqualTo("Must be false"); } @Test @@ -80,14 +79,12 @@ public void defaultMessageAssertTrue() { @Test public void defaultMessageDecimalMax() { - assertThat(constraintDescriptionForField("decimalMax")) - .isEqualTo("Must be at most 9.875"); + assertThat(constraintDescriptionForField("decimalMax")).isEqualTo("Must be at most 9.875"); } @Test public void defaultMessageDecimalMin() { - assertThat(constraintDescriptionForField("decimalMin")) - .isEqualTo("Must be at least 1.5"); + assertThat(constraintDescriptionForField("decimalMin")).isEqualTo("Must be at least 1.5"); } @Test @@ -98,8 +95,7 @@ public void defaultMessageDigits() { @Test public void defaultMessageFuture() { - assertThat(constraintDescriptionForField("future")) - .isEqualTo("Must be in the future"); + assertThat(constraintDescriptionForField("future")).isEqualTo("Must be in the future"); } @Test @@ -114,8 +110,7 @@ public void defaultMessageMin() { @Test public void defaultMessageNotNull() { - assertThat(constraintDescriptionForField("notNull")) - .isEqualTo("Must not be null"); + assertThat(constraintDescriptionForField("notNull")).isEqualTo("Must not be null"); } @Test @@ -125,8 +120,7 @@ public void defaultMessageNull() { @Test public void defaultMessagePast() { - assertThat(constraintDescriptionForField("past")) - .isEqualTo("Must be in the past"); + assertThat(constraintDescriptionForField("past")).isEqualTo("Must be in the past"); } @Test @@ -137,8 +131,7 @@ public void defaultMessagePattern() { @Test public void defaultMessageSize() { - assertThat(constraintDescriptionForField("size")) - .isEqualTo("Size must be between 2 and 10 inclusive"); + assertThat(constraintDescriptionForField("size")).isEqualTo("Size must be between 2 and 10 inclusive"); } @Test @@ -149,20 +142,17 @@ public void defaultMessageCreditCardNumber() { @Test public void defaultMessageEan() { - assertThat(constraintDescriptionForField("ean")) - .isEqualTo("Must be a well-formed EAN13 number"); + assertThat(constraintDescriptionForField("ean")).isEqualTo("Must be a well-formed EAN13 number"); } @Test public void defaultMessageEmail() { - assertThat(constraintDescriptionForField("email")) - .isEqualTo("Must be a well-formed email address"); + assertThat(constraintDescriptionForField("email")).isEqualTo("Must be a well-formed email address"); } @Test public void defaultMessageLength() { - assertThat(constraintDescriptionForField("length")) - .isEqualTo("Length must be between 2 and 10 inclusive"); + assertThat(constraintDescriptionForField("length")).isEqualTo("Length must be between 2 and 10 inclusive"); } @Test @@ -173,44 +163,37 @@ public void defaultMessageLuhnCheck() { @Test public void defaultMessageMod10Check() { - assertThat(constraintDescriptionForField("mod10Check")) - .isEqualTo("Must pass the Mod10 checksum algorithm"); + assertThat(constraintDescriptionForField("mod10Check")).isEqualTo("Must pass the Mod10 checksum algorithm"); } @Test public void defaultMessageMod11Check() { - assertThat(constraintDescriptionForField("mod11Check")) - .isEqualTo("Must pass the Mod11 checksum algorithm"); + assertThat(constraintDescriptionForField("mod11Check")).isEqualTo("Must pass the Mod11 checksum algorithm"); } @Test public void defaultMessageNotBlank() { - assertThat(constraintDescriptionForField("notBlank")) - .isEqualTo("Must not be blank"); + assertThat(constraintDescriptionForField("notBlank")).isEqualTo("Must not be blank"); } @Test public void defaultMessageNotEmpty() { - assertThat(constraintDescriptionForField("notEmpty")) - .isEqualTo("Must not be empty"); + assertThat(constraintDescriptionForField("notEmpty")).isEqualTo("Must not be empty"); } @Test public void defaultMessageRange() { - assertThat(constraintDescriptionForField("range")) - .isEqualTo("Must be at least 10 and at most 100"); + assertThat(constraintDescriptionForField("range")).isEqualTo("Must be at least 10 and at most 100"); } @Test public void defaultMessageSafeHtml() { - assertThat(constraintDescriptionForField("safeHtml")) - .isEqualTo("Must be safe HTML"); + assertThat(constraintDescriptionForField("safeHtml")).isEqualTo("Must be safe HTML"); } @Test public void defaultMessageUrl() { - assertThat(constraintDescriptionForField("url")) - .isEqualTo("Must be a well-formed URL"); + assertThat(constraintDescriptionForField("url")).isEqualTo("Must be a well-formed URL"); } @Test @@ -219,8 +202,7 @@ public void customMessage() { @Override public URL getResource(String name) { - if (name.startsWith( - "org/springframework/restdocs/constraints/ConstraintDescriptions")) { + if (name.startsWith("org/springframework/restdocs/constraints/ConstraintDescriptions")) { return super.getResource( "org/springframework/restdocs/constraints/TestConstraintDescriptions.properties"); } @@ -230,9 +212,8 @@ public URL getResource(String name) { }); try { - String description = new ResourceBundleConstraintDescriptionResolver() - .resolveDescription(new Constraint(NotNull.class.getName(), - Collections.emptyMap())); + String description = new ResourceBundleConstraintDescriptionResolver().resolveDescription( + new Constraint(NotNull.class.getName(), Collections.emptyMap())); assertThat(description).isEqualTo("Should not be null"); } @@ -247,14 +228,12 @@ public void customResourceBundle() { @Override protected Object[][] getContents() { - return new String[][] { - { NotNull.class.getName() + ".description", "Not null" } }; + return new String[][] { { NotNull.class.getName() + ".description", "Not null" } }; } }; String description = new ResourceBundleConstraintDescriptionResolver(bundle) - .resolveDescription(new Constraint(NotNull.class.getName(), - Collections.emptyMap())); + .resolveDescription(new Constraint(NotNull.class.getName(), Collections.emptyMap())); assertThat(description).isEqualTo("Not null"); } @@ -263,10 +242,9 @@ private String constraintDescriptionForField(String name) { } private Constraint getConstraintFromField(String name) { - Annotation[] annotations = ReflectionUtils.findField(Constrained.class, name) - .getAnnotations(); - Assert.isTrue(annotations.length == 1, "The field '" + name + "' must have " - + "exactly one @Constrained annotation"); + Annotation[] annotations = ReflectionUtils.findField(Constrained.class, name).getAnnotations(); + Assert.isTrue(annotations.length == 1, + "The field '" + name + "' must have " + "exactly one @Constrained annotation"); return new Constraint(annotations[0].annotationType().getName(), AnnotationUtils.getAnnotationAttributes(annotations[0])); } diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/constraints/ValidatorConstraintResolverTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/constraints/ValidatorConstraintResolverTests.java index b9e436e5a..bd3298edb 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/constraints/ValidatorConstraintResolverTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/constraints/ValidatorConstraintResolverTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-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. @@ -51,33 +51,28 @@ public class ValidatorConstraintResolverTests { @Test public void singleFieldConstraint() { - List constraints = this.resolver.resolveForProperty("single", - ConstrainedFields.class); + List constraints = this.resolver.resolveForProperty("single", ConstrainedFields.class); assertThat(constraints).hasSize(1); assertThat(constraints.get(0).getName()).isEqualTo(NotNull.class.getName()); } @Test public void multipleFieldConstraints() { - List constraints = this.resolver.resolveForProperty("multiple", - ConstrainedFields.class); + List constraints = this.resolver.resolveForProperty("multiple", ConstrainedFields.class); assertThat(constraints).hasSize(2); assertThat(constraints.get(0)).is(constraint(NotNull.class)); - assertThat(constraints.get(1)) - .is(constraint(Size.class).config("min", 8).config("max", 16)); + assertThat(constraints.get(1)).is(constraint(Size.class).config("min", 8).config("max", 16)); } @Test public void noFieldConstraints() { - List constraints = this.resolver.resolveForProperty("none", - ConstrainedFields.class); + List constraints = this.resolver.resolveForProperty("none", ConstrainedFields.class); assertThat(constraints).hasSize(0); } @Test public void compositeConstraint() { - List constraints = this.resolver.resolveForProperty("composite", - ConstrainedFields.class); + List constraints = this.resolver.resolveForProperty("composite", ConstrainedFields.class); assertThat(constraints).hasSize(1); } @@ -126,11 +121,10 @@ private static final class ConstraintCondition extends Condition { private ConstraintCondition(Class annotation) { this.annotation = annotation; - as(new TextDescription("Constraint named %s with configuration %s", - this.annotation, this.configuration)); + as(new TextDescription("Constraint named %s with configuration %s", this.annotation, this.configuration)); } - public ConstraintCondition config(String key, Object value) { + private ConstraintCondition config(String key, Object value) { this.configuration.put(key, value); return this; } @@ -141,8 +135,7 @@ public boolean matches(Constraint constraint) { return false; } for (Entry entry : this.configuration.entrySet()) { - if (!constraint.getConfiguration().get(entry.getKey()) - .equals(entry.getValue())) { + if (!constraint.getConfiguration().get(entry.getKey()).equals(entry.getValue())) { return false; } } diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/headers/RequestHeadersSnippetFailureTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/headers/RequestHeadersSnippetFailureTests.java index 23f954957..8390afbd3 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/headers/RequestHeadersSnippetFailureTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/headers/RequestHeadersSnippetFailureTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-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. @@ -40,8 +40,7 @@ public class RequestHeadersSnippetFailureTests { @Rule - public OperationBuilder operationBuilder = new OperationBuilder( - TemplateFormats.asciidoctor()); + public OperationBuilder operationBuilder = new OperationBuilder(TemplateFormats.asciidoctor()); @Rule public ExpectedException thrown = ExpectedException.none(); @@ -49,24 +48,19 @@ public class RequestHeadersSnippetFailureTests { @Test public void missingRequestHeader() throws IOException { this.thrown.expect(SnippetException.class); - this.thrown - .expectMessage(equalTo("Headers with the following names were not found" - + " in the request: [Accept]")); - new RequestHeadersSnippet( - Arrays.asList(headerWithName("Accept").description("one"))).document( - this.operationBuilder.request("http://localhost").build()); + this.thrown.expectMessage( + equalTo("Headers with the following names were not found" + " in the request: [Accept]")); + new RequestHeadersSnippet(Arrays.asList(headerWithName("Accept").description("one"))) + .document(this.operationBuilder.request("http://localhost").build()); } @Test public void undocumentedRequestHeaderAndMissingRequestHeader() throws IOException { this.thrown.expect(SnippetException.class); - this.thrown - .expectMessage(endsWith("Headers with the following names were not found" - + " in the request: [Accept]")); - new RequestHeadersSnippet( - Arrays.asList(headerWithName("Accept").description("one"))) - .document(this.operationBuilder.request("http://localhost") - .header("X-Test", "test").build()); + this.thrown.expectMessage( + endsWith("Headers with the following names were not found" + " in the request: [Accept]")); + new RequestHeadersSnippet(Arrays.asList(headerWithName("Accept").description("one"))) + .document(this.operationBuilder.request("http://localhost").header("X-Test", "test").build()); } } diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/headers/RequestHeadersSnippetTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/headers/RequestHeadersSnippetTests.java index 8c7cdf75a..5904f3171 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/headers/RequestHeadersSnippetTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/headers/RequestHeadersSnippetTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-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. @@ -49,43 +49,32 @@ public RequestHeadersSnippetTests(String name, TemplateFormat templateFormat) { @Test public void requestWithHeaders() throws IOException { - new RequestHeadersSnippet( - Arrays.asList(headerWithName("X-Test").description("one"), - headerWithName("Accept").description("two"), - headerWithName("Accept-Encoding").description("three"), - headerWithName("Accept-Language").description("four"), - headerWithName("Cache-Control").description("five"), - headerWithName("Connection").description("six"))).document( - this.operationBuilder.request("http://localhost") - .header("X-Test", "test").header("Accept", "*/*") - .header("Accept-Encoding", "gzip, deflate") - .header("Accept-Language", "en-US,en;q=0.5") - .header("Cache-Control", "max-age=0") - .header("Connection", "keep-alive").build()); - assertThat(this.generatedSnippets.requestHeaders()) - .is(tableWithHeader("Name", "Description").row("`X-Test`", "one") - .row("`Accept`", "two").row("`Accept-Encoding`", "three") - .row("`Accept-Language`", "four").row("`Cache-Control`", "five") - .row("`Connection`", "six")); + new RequestHeadersSnippet(Arrays.asList(headerWithName("X-Test").description("one"), + headerWithName("Accept").description("two"), headerWithName("Accept-Encoding").description("three"), + headerWithName("Accept-Language").description("four"), + headerWithName("Cache-Control").description("five"), headerWithName("Connection").description("six"))) + .document(this.operationBuilder.request("http://localhost").header("X-Test", "test") + .header("Accept", "*/*").header("Accept-Encoding", "gzip, deflate") + .header("Accept-Language", "en-US,en;q=0.5").header("Cache-Control", "max-age=0") + .header("Connection", "keep-alive").build()); + assertThat(this.generatedSnippets.requestHeaders()).is(tableWithHeader("Name", "Description") + .row("`X-Test`", "one").row("`Accept`", "two").row("`Accept-Encoding`", "three") + .row("`Accept-Language`", "four").row("`Cache-Control`", "five").row("`Connection`", "six")); } @Test public void caseInsensitiveRequestHeaders() throws IOException { - new RequestHeadersSnippet( - Arrays.asList(headerWithName("X-Test").description("one"))) - .document(this.operationBuilder.request("/") - .header("X-test", "test").build()); + new RequestHeadersSnippet(Arrays.asList(headerWithName("X-Test").description("one"))) + .document(this.operationBuilder.request("/").header("X-test", "test").build()); assertThat(this.generatedSnippets.requestHeaders()) .is(tableWithHeader("Name", "Description").row("`X-Test`", "one")); } @Test public void undocumentedRequestHeader() throws IOException { - new RequestHeadersSnippet( - Arrays.asList(headerWithName("X-Test").description("one"))) - .document(this.operationBuilder.request("http://localhost") - .header("X-Test", "test").header("Accept", "*/*") - .build()); + new RequestHeadersSnippet(Arrays.asList(headerWithName("X-Test").description("one"))) + .document(this.operationBuilder.request("http://localhost").header("X-Test", "test") + .header("Accept", "*/*").build()); assertThat(this.generatedSnippets.requestHeaders()) .is(tableWithHeader("Name", "Description").row("`X-Test`", "one")); } @@ -95,16 +84,11 @@ public void requestHeadersWithCustomAttributes() throws IOException { TemplateResourceResolver resolver = mock(TemplateResourceResolver.class); given(resolver.resolveTemplateResource("request-headers")) .willReturn(snippetResource("request-headers-with-title")); - new RequestHeadersSnippet( - Arrays.asList(headerWithName("X-Test").description("one")), attributes( - key("title").value("Custom title"))) - .document( - this.operationBuilder - .attribute(TemplateEngine.class.getName(), - new MustacheTemplateEngine( - resolver)) - .request("http://localhost") - .header("X-Test", "test").build()); + new RequestHeadersSnippet(Arrays.asList(headerWithName("X-Test").description("one")), + attributes(key("title").value("Custom title"))) + .document(this.operationBuilder + .attribute(TemplateEngine.class.getName(), new MustacheTemplateEngine(resolver)) + .request("http://localhost").header("X-Test", "test").build()); assertThat(this.generatedSnippets.requestHeaders()).contains("Custom title"); } @@ -113,61 +97,41 @@ public void requestHeadersWithCustomDescriptorAttributes() throws IOException { TemplateResourceResolver resolver = mock(TemplateResourceResolver.class); given(resolver.resolveTemplateResource("request-headers")) .willReturn(snippetResource("request-headers-with-extra-column")); - new RequestHeadersSnippet(Arrays.asList( - headerWithName("X-Test").description("one") - .attributes(key("foo").value("alpha")), - headerWithName("Accept-Encoding").description("two") - .attributes(key("foo").value("bravo")), - headerWithName("Accept").description("three") - .attributes(key("foo").value("charlie")))) - .document( - this.operationBuilder - .attribute(TemplateEngine.class.getName(), - new MustacheTemplateEngine( - resolver)) - .request("http://localhost") - .header("X-Test", "test") - .header("Accept-Encoding", - "gzip, deflate") - .header("Accept", "*/*").build()); + new RequestHeadersSnippet( + Arrays.asList(headerWithName("X-Test").description("one").attributes(key("foo").value("alpha")), + headerWithName("Accept-Encoding").description("two").attributes(key("foo").value("bravo")), + headerWithName("Accept").description("three").attributes(key("foo").value("charlie")))) + .document(this.operationBuilder + .attribute(TemplateEngine.class.getName(), new MustacheTemplateEngine(resolver)) + .request("http://localhost").header("X-Test", "test") + .header("Accept-Encoding", "gzip, deflate").header("Accept", "*/*").build()); assertThat(this.generatedSnippets.requestHeaders()).is(// - tableWithHeader("Name", "Description", "Foo") - .row("X-Test", "one", "alpha") - .row("Accept-Encoding", "two", "bravo") - .row("Accept", "three", "charlie")); + tableWithHeader("Name", "Description", "Foo").row("X-Test", "one", "alpha") + .row("Accept-Encoding", "two", "bravo").row("Accept", "three", "charlie")); } @Test public void additionalDescriptors() throws IOException { - HeaderDocumentation - .requestHeaders(headerWithName("X-Test").description("one"), - headerWithName("Accept").description("two"), - headerWithName("Accept-Encoding").description("three"), - headerWithName("Accept-Language").description("four")) + HeaderDocumentation.requestHeaders(headerWithName("X-Test").description("one"), + headerWithName("Accept").description("two"), headerWithName("Accept-Encoding").description("three"), + headerWithName("Accept-Language").description("four")) .and(headerWithName("Cache-Control").description("five"), headerWithName("Connection").description("six")) - .document(this.operationBuilder.request("http://localhost") - .header("X-Test", "test").header("Accept", "*/*") - .header("Accept-Encoding", "gzip, deflate") - .header("Accept-Language", "en-US,en;q=0.5") - .header("Cache-Control", "max-age=0") + .document(this.operationBuilder.request("http://localhost").header("X-Test", "test") + .header("Accept", "*/*").header("Accept-Encoding", "gzip, deflate") + .header("Accept-Language", "en-US,en;q=0.5").header("Cache-Control", "max-age=0") .header("Connection", "keep-alive").build()); - assertThat(this.generatedSnippets.requestHeaders()) - .is(tableWithHeader("Name", "Description").row("`X-Test`", "one") - .row("`Accept`", "two").row("`Accept-Encoding`", "three") - .row("`Accept-Language`", "four").row("`Cache-Control`", "five") - .row("`Connection`", "six")); + assertThat(this.generatedSnippets.requestHeaders()).is(tableWithHeader("Name", "Description") + .row("`X-Test`", "one").row("`Accept`", "two").row("`Accept-Encoding`", "three") + .row("`Accept-Language`", "four").row("`Cache-Control`", "five").row("`Connection`", "six")); } @Test public void tableCellContentIsEscapedWhenNecessary() throws IOException { - new RequestHeadersSnippet( - Arrays.asList(headerWithName("Foo|Bar").description("one|two"))) - .document(this.operationBuilder.request("http://localhost") - .header("Foo|Bar", "baz").build()); - assertThat(this.generatedSnippets.requestHeaders()).is( - tableWithHeader("Name", "Description").row(escapeIfNecessary("`Foo|Bar`"), - escapeIfNecessary("one|two"))); + new RequestHeadersSnippet(Arrays.asList(headerWithName("Foo|Bar").description("one|two"))) + .document(this.operationBuilder.request("http://localhost").header("Foo|Bar", "baz").build()); + assertThat(this.generatedSnippets.requestHeaders()).is(tableWithHeader("Name", "Description") + .row(escapeIfNecessary("`Foo|Bar`"), escapeIfNecessary("one|two"))); } private String escapeIfNecessary(String input) { diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/headers/ResponseHeadersSnippetFailureTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/headers/ResponseHeadersSnippetFailureTests.java index ebcfe5371..c436bdb0e 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/headers/ResponseHeadersSnippetFailureTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/headers/ResponseHeadersSnippetFailureTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-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. @@ -40,8 +40,7 @@ public class ResponseHeadersSnippetFailureTests { @Rule - public OperationBuilder operationBuilder = new OperationBuilder( - TemplateFormats.asciidoctor()); + public OperationBuilder operationBuilder = new OperationBuilder(TemplateFormats.asciidoctor()); @Rule public ExpectedException thrown = ExpectedException.none(); @@ -49,24 +48,19 @@ public class ResponseHeadersSnippetFailureTests { @Test public void missingResponseHeader() throws IOException { this.thrown.expect(SnippetException.class); - this.thrown - .expectMessage(equalTo("Headers with the following names were not found" - + " in the response: [Content-Type]")); - new ResponseHeadersSnippet( - Arrays.asList(headerWithName("Content-Type").description("one"))) - .document(this.operationBuilder.response().build()); + this.thrown.expectMessage( + equalTo("Headers with the following names were not found" + " in the response: [Content-Type]")); + new ResponseHeadersSnippet(Arrays.asList(headerWithName("Content-Type").description("one"))) + .document(this.operationBuilder.response().build()); } @Test public void undocumentedResponseHeaderAndMissingResponseHeader() throws IOException { this.thrown.expect(SnippetException.class); - this.thrown - .expectMessage(endsWith("Headers with the following names were not found" - + " in the response: [Content-Type]")); - new ResponseHeadersSnippet( - Arrays.asList(headerWithName("Content-Type").description("one"))) - .document(this.operationBuilder.response() - .header("X-Test", "test").build()); + this.thrown.expectMessage( + endsWith("Headers with the following names were not found" + " in the response: [Content-Type]")); + new ResponseHeadersSnippet(Arrays.asList(headerWithName("Content-Type").description("one"))) + .document(this.operationBuilder.response().header("X-Test", "test").build()); } } diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/headers/ResponseHeadersSnippetTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/headers/ResponseHeadersSnippetTests.java index 5c9385dfd..dc87a7a08 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/headers/ResponseHeadersSnippetTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/headers/ResponseHeadersSnippetTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-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. @@ -49,39 +49,29 @@ public ResponseHeadersSnippetTests(String name, TemplateFormat templateFormat) { @Test public void responseWithHeaders() throws IOException { - new ResponseHeadersSnippet( - Arrays.asList(headerWithName("X-Test").description("one"), - headerWithName("Content-Type").description("two"), - headerWithName("Etag").description("three"), - headerWithName("Cache-Control").description("five"), - headerWithName("Vary").description("six"))).document( - this.operationBuilder.response().header("X-Test", "test") - .header("Content-Type", "application/json") - .header("Etag", "lskjadldj3ii32l2ij23") - .header("Cache-Control", "max-age=0") - .header("Vary", "User-Agent").build()); + new ResponseHeadersSnippet(Arrays.asList(headerWithName("X-Test").description("one"), + headerWithName("Content-Type").description("two"), headerWithName("Etag").description("three"), + headerWithName("Cache-Control").description("five"), headerWithName("Vary").description("six"))) + .document(this.operationBuilder.response().header("X-Test", "test") + .header("Content-Type", "application/json").header("Etag", "lskjadldj3ii32l2ij23") + .header("Cache-Control", "max-age=0").header("Vary", "User-Agent").build()); assertThat(this.generatedSnippets.responseHeaders()) - .is(tableWithHeader("Name", "Description").row("`X-Test`", "one") - .row("`Content-Type`", "two").row("`Etag`", "three") - .row("`Cache-Control`", "five").row("`Vary`", "six")); + .is(tableWithHeader("Name", "Description").row("`X-Test`", "one").row("`Content-Type`", "two") + .row("`Etag`", "three").row("`Cache-Control`", "five").row("`Vary`", "six")); } @Test public void caseInsensitiveResponseHeaders() throws IOException { - new ResponseHeadersSnippet( - Arrays.asList(headerWithName("X-Test").description("one"))) - .document(this.operationBuilder.response() - .header("X-test", "test").build()); + new ResponseHeadersSnippet(Arrays.asList(headerWithName("X-Test").description("one"))) + .document(this.operationBuilder.response().header("X-test", "test").build()); assertThat(this.generatedSnippets.responseHeaders()) .is(tableWithHeader("Name", "Description").row("`X-Test`", "one")); } @Test public void undocumentedResponseHeader() throws IOException { - new ResponseHeadersSnippet( - Arrays.asList(headerWithName("X-Test").description("one"))).document( - this.operationBuilder.response().header("X-Test", "test") - .header("Content-Type", "*/*").build()); + new ResponseHeadersSnippet(Arrays.asList(headerWithName("X-Test").description("one"))).document( + this.operationBuilder.response().header("X-Test", "test").header("Content-Type", "*/*").build()); assertThat(this.generatedSnippets.responseHeaders()) .is(tableWithHeader("Name", "Description").row("`X-Test`", "one")); } @@ -91,16 +81,11 @@ public void responseHeadersWithCustomAttributes() throws IOException { TemplateResourceResolver resolver = mock(TemplateResourceResolver.class); given(resolver.resolveTemplateResource("response-headers")) .willReturn(snippetResource("response-headers-with-title")); - new ResponseHeadersSnippet( - Arrays.asList(headerWithName("X-Test").description("one")), attributes( - key("title").value("Custom title"))) - .document( - this.operationBuilder - .attribute(TemplateEngine.class.getName(), - new MustacheTemplateEngine( - resolver)) - .response().header("X-Test", "test") - .build()); + new ResponseHeadersSnippet(Arrays.asList(headerWithName("X-Test").description("one")), + attributes(key("title").value("Custom title"))) + .document(this.operationBuilder + .attribute(TemplateEngine.class.getName(), new MustacheTemplateEngine(resolver)) + .response().header("X-Test", "test").build()); assertThat(this.generatedSnippets.responseHeaders()).contains("Custom title"); } @@ -109,57 +94,38 @@ public void responseHeadersWithCustomDescriptorAttributes() throws IOException { TemplateResourceResolver resolver = mock(TemplateResourceResolver.class); given(resolver.resolveTemplateResource("response-headers")) .willReturn(snippetResource("response-headers-with-extra-column")); - new ResponseHeadersSnippet(Arrays.asList( - headerWithName("X-Test").description("one") - .attributes(key("foo").value("alpha")), - headerWithName("Content-Type").description("two") - .attributes(key("foo").value("bravo")), - headerWithName("Etag").description("three") - .attributes(key("foo").value("charlie")))) - .document( - this.operationBuilder - .attribute(TemplateEngine.class.getName(), - new MustacheTemplateEngine( - resolver)) - .response().header("X-Test", "test") - .header("Content-Type", - "application/json") - .header("Etag", "lskjadldj3ii32l2ij23") - .build()); - assertThat(this.generatedSnippets.responseHeaders()) - .is(tableWithHeader("Name", "Description", "Foo") - .row("X-Test", "one", "alpha").row("Content-Type", "two", "bravo") - .row("Etag", "three", "charlie")); + new ResponseHeadersSnippet( + Arrays.asList(headerWithName("X-Test").description("one").attributes(key("foo").value("alpha")), + headerWithName("Content-Type").description("two").attributes(key("foo").value("bravo")), + headerWithName("Etag").description("three").attributes(key("foo").value("charlie")))) + .document(this.operationBuilder + .attribute(TemplateEngine.class.getName(), new MustacheTemplateEngine(resolver)) + .response().header("X-Test", "test").header("Content-Type", "application/json") + .header("Etag", "lskjadldj3ii32l2ij23").build()); + assertThat(this.generatedSnippets.responseHeaders()).is(tableWithHeader("Name", "Description", "Foo") + .row("X-Test", "one", "alpha").row("Content-Type", "two", "bravo").row("Etag", "three", "charlie")); } @Test public void additionalDescriptors() throws IOException { HeaderDocumentation .responseHeaders(headerWithName("X-Test").description("one"), - headerWithName("Content-Type").description("two"), - headerWithName("Etag").description("three")) - .and(headerWithName("Cache-Control").description("five"), - headerWithName("Vary").description("six")) + headerWithName("Content-Type").description("two"), headerWithName("Etag").description("three")) + .and(headerWithName("Cache-Control").description("five"), headerWithName("Vary").description("six")) .document(this.operationBuilder.response().header("X-Test", "test") - .header("Content-Type", "application/json") - .header("Etag", "lskjadldj3ii32l2ij23") - .header("Cache-Control", "max-age=0").header("Vary", "User-Agent") - .build()); + .header("Content-Type", "application/json").header("Etag", "lskjadldj3ii32l2ij23") + .header("Cache-Control", "max-age=0").header("Vary", "User-Agent").build()); assertThat(this.generatedSnippets.responseHeaders()) - .is(tableWithHeader("Name", "Description").row("`X-Test`", "one") - .row("`Content-Type`", "two").row("`Etag`", "three") - .row("`Cache-Control`", "five").row("`Vary`", "six")); + .is(tableWithHeader("Name", "Description").row("`X-Test`", "one").row("`Content-Type`", "two") + .row("`Etag`", "three").row("`Cache-Control`", "five").row("`Vary`", "six")); } @Test public void tableCellContentIsEscapedWhenNecessary() throws IOException { - new ResponseHeadersSnippet( - Arrays.asList(headerWithName("Foo|Bar").description("one|two"))) - .document(this.operationBuilder.response() - .header("Foo|Bar", "baz").build()); - assertThat(this.generatedSnippets.responseHeaders()).is( - tableWithHeader("Name", "Description").row(escapeIfNecessary("`Foo|Bar`"), - escapeIfNecessary("one|two"))); + new ResponseHeadersSnippet(Arrays.asList(headerWithName("Foo|Bar").description("one|two"))) + .document(this.operationBuilder.response().header("Foo|Bar", "baz").build()); + assertThat(this.generatedSnippets.responseHeaders()).is(tableWithHeader("Name", "Description") + .row(escapeIfNecessary("`Foo|Bar`"), escapeIfNecessary("one|two"))); } private String escapeIfNecessary(String input) { diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/http/HttpRequestSnippetTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/http/HttpRequestSnippetTests.java index da4f144dd..5ac9889d7 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/http/HttpRequestSnippetTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/http/HttpRequestSnippetTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-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. @@ -51,338 +51,260 @@ public HttpRequestSnippetTests(String name, TemplateFormat templateFormat) { @Test public void getRequest() throws IOException { - new HttpRequestSnippet().document(this.operationBuilder - .request("http://localhost/foo").header("Alpha", "a").build()); + new HttpRequestSnippet() + .document(this.operationBuilder.request("http://localhost/foo").header("Alpha", "a").build()); assertThat(this.generatedSnippets.httpRequest()) - .is(httpRequest(RequestMethod.GET, "/foo").header("Alpha", "a") - .header(HttpHeaders.HOST, "localhost")); + .is(httpRequest(RequestMethod.GET, "/foo").header("Alpha", "a").header(HttpHeaders.HOST, "localhost")); } @Test public void getRequestWithParameters() throws IOException { - new HttpRequestSnippet() - .document(this.operationBuilder.request("http://localhost/foo") - .header("Alpha", "a").param("b", "bravo").build()); - assertThat(this.generatedSnippets.httpRequest()) - .is(httpRequest(RequestMethod.GET, "/foo?b=bravo").header("Alpha", "a") - .header(HttpHeaders.HOST, "localhost")); + new HttpRequestSnippet().document( + this.operationBuilder.request("http://localhost/foo").header("Alpha", "a").param("b", "bravo").build()); + assertThat(this.generatedSnippets.httpRequest()).is(httpRequest(RequestMethod.GET, "/foo?b=bravo") + .header("Alpha", "a").header(HttpHeaders.HOST, "localhost")); } @Test public void getRequestWithPort() throws IOException { - new HttpRequestSnippet().document(this.operationBuilder - .request("http://localhost:8080/foo").header("Alpha", "a").build()); - assertThat(this.generatedSnippets.httpRequest()) - .is(httpRequest(RequestMethod.GET, "/foo").header("Alpha", "a") - .header(HttpHeaders.HOST, "localhost:8080")); + new HttpRequestSnippet() + .document(this.operationBuilder.request("http://localhost:8080/foo").header("Alpha", "a").build()); + assertThat(this.generatedSnippets.httpRequest()).is( + httpRequest(RequestMethod.GET, "/foo").header("Alpha", "a").header(HttpHeaders.HOST, "localhost:8080")); } @Test public void getRequestWithCookies() throws IOException { - new HttpRequestSnippet() - .document(this.operationBuilder.request("http://localhost/foo") - .cookie("name1", "value1").cookie("name2", "value2").build()); + new HttpRequestSnippet().document(this.operationBuilder.request("http://localhost/foo") + .cookie("name1", "value1").cookie("name2", "value2").build()); assertThat(this.generatedSnippets.httpRequest()) - .is(httpRequest(RequestMethod.GET, "/foo") - .header(HttpHeaders.HOST, "localhost") - .header(HttpHeaders.COOKIE, "name1=value1") - .header(HttpHeaders.COOKIE, "name2=value2")); + .is(httpRequest(RequestMethod.GET, "/foo").header(HttpHeaders.HOST, "localhost") + .header(HttpHeaders.COOKIE, "name1=value1").header(HttpHeaders.COOKIE, "name2=value2")); } @Test public void getRequestWithQueryString() throws IOException { - new HttpRequestSnippet().document( - this.operationBuilder.request("http://localhost/foo?bar=baz").build()); + new HttpRequestSnippet().document(this.operationBuilder.request("http://localhost/foo?bar=baz").build()); assertThat(this.generatedSnippets.httpRequest()) - .is(httpRequest(RequestMethod.GET, "/foo?bar=baz") - .header(HttpHeaders.HOST, "localhost")); + .is(httpRequest(RequestMethod.GET, "/foo?bar=baz").header(HttpHeaders.HOST, "localhost")); } @Test public void getRequestWithQueryStringWithNoValue() throws IOException { - new HttpRequestSnippet().document( - this.operationBuilder.request("http://localhost/foo?bar").build()); + new HttpRequestSnippet().document(this.operationBuilder.request("http://localhost/foo?bar").build()); assertThat(this.generatedSnippets.httpRequest()) - .is(httpRequest(RequestMethod.GET, "/foo?bar").header(HttpHeaders.HOST, - "localhost")); + .is(httpRequest(RequestMethod.GET, "/foo?bar").header(HttpHeaders.HOST, "localhost")); } @Test public void getWithPartiallyOverlappingQueryStringAndParameters() throws IOException { - new HttpRequestSnippet() - .document(this.operationBuilder.request("http://localhost/foo?a=alpha") - .param("a", "alpha").param("b", "bravo").build()); + new HttpRequestSnippet().document(this.operationBuilder.request("http://localhost/foo?a=alpha") + .param("a", "alpha").param("b", "bravo").build()); assertThat(this.generatedSnippets.httpRequest()) - .is(httpRequest(RequestMethod.GET, "/foo?a=alpha&b=bravo") - .header(HttpHeaders.HOST, "localhost")); + .is(httpRequest(RequestMethod.GET, "/foo?a=alpha&b=bravo").header(HttpHeaders.HOST, "localhost")); } @Test public void getWithTotallyOverlappingQueryStringAndParameters() throws IOException { - new HttpRequestSnippet().document( - this.operationBuilder.request("http://localhost/foo?a=alpha&b=bravo") - .param("a", "alpha").param("b", "bravo").build()); + new HttpRequestSnippet().document(this.operationBuilder.request("http://localhost/foo?a=alpha&b=bravo") + .param("a", "alpha").param("b", "bravo").build()); assertThat(this.generatedSnippets.httpRequest()) - .is(httpRequest(RequestMethod.GET, "/foo?a=alpha&b=bravo") - .header(HttpHeaders.HOST, "localhost")); + .is(httpRequest(RequestMethod.GET, "/foo?a=alpha&b=bravo").header(HttpHeaders.HOST, "localhost")); } @Test public void postRequestWithContent() throws IOException { String content = "Hello, world"; - new HttpRequestSnippet().document(this.operationBuilder - .request("http://localhost/foo").method("POST").content(content).build()); + new HttpRequestSnippet().document( + this.operationBuilder.request("http://localhost/foo").method("POST").content(content).build()); assertThat(this.generatedSnippets.httpRequest()) - .is(httpRequest(RequestMethod.POST, "/foo") - .header(HttpHeaders.HOST, "localhost").content(content) + .is(httpRequest(RequestMethod.POST, "/foo").header(HttpHeaders.HOST, "localhost").content(content) .header(HttpHeaders.CONTENT_LENGTH, content.getBytes().length)); } @Test public void postRequestWithContentAndParameters() throws IOException { String content = "Hello, world"; - new HttpRequestSnippet() - .document(this.operationBuilder.request("http://localhost/foo") - .method("POST").param("a", "alpha").content(content).build()); + new HttpRequestSnippet().document(this.operationBuilder.request("http://localhost/foo").method("POST") + .param("a", "alpha").content(content).build()); assertThat(this.generatedSnippets.httpRequest()) - .is(httpRequest(RequestMethod.POST, "/foo?a=alpha") - .header(HttpHeaders.HOST, "localhost").content(content) - .header(HttpHeaders.CONTENT_LENGTH, content.getBytes().length)); + .is(httpRequest(RequestMethod.POST, "/foo?a=alpha").header(HttpHeaders.HOST, "localhost") + .content(content).header(HttpHeaders.CONTENT_LENGTH, content.getBytes().length)); } @Test - public void postRequestWithContentAndDisjointQueryStringAndParameters() - throws IOException { + public void postRequestWithContentAndDisjointQueryStringAndParameters() throws IOException { String content = "Hello, world"; - new HttpRequestSnippet() - .document(this.operationBuilder.request("http://localhost/foo?b=bravo") - .method("POST").param("a", "alpha").content(content).build()); + new HttpRequestSnippet().document(this.operationBuilder.request("http://localhost/foo?b=bravo").method("POST") + .param("a", "alpha").content(content).build()); assertThat(this.generatedSnippets.httpRequest()) - .is(httpRequest(RequestMethod.POST, "/foo?b=bravo&a=alpha") - .header(HttpHeaders.HOST, "localhost").content(content) - .header(HttpHeaders.CONTENT_LENGTH, content.getBytes().length)); + .is(httpRequest(RequestMethod.POST, "/foo?b=bravo&a=alpha").header(HttpHeaders.HOST, "localhost") + .content(content).header(HttpHeaders.CONTENT_LENGTH, content.getBytes().length)); } @Test - public void postRequestWithContentAndPartiallyOverlappingQueryStringAndParameters() - throws IOException { + public void postRequestWithContentAndPartiallyOverlappingQueryStringAndParameters() throws IOException { String content = "Hello, world"; - new HttpRequestSnippet().document(this.operationBuilder - .request("http://localhost/foo?b=bravo").method("POST") + new HttpRequestSnippet().document(this.operationBuilder.request("http://localhost/foo?b=bravo").method("POST") .param("a", "alpha").param("b", "bravo").content(content).build()); assertThat(this.generatedSnippets.httpRequest()) - .is(httpRequest(RequestMethod.POST, "/foo?b=bravo&a=alpha") - .header(HttpHeaders.HOST, "localhost").content(content) - .header(HttpHeaders.CONTENT_LENGTH, content.getBytes().length)); + .is(httpRequest(RequestMethod.POST, "/foo?b=bravo&a=alpha").header(HttpHeaders.HOST, "localhost") + .content(content).header(HttpHeaders.CONTENT_LENGTH, content.getBytes().length)); } @Test - public void postRequestWithContentAndTotallyOverlappingQueryStringAndParameters() - throws IOException { + public void postRequestWithContentAndTotallyOverlappingQueryStringAndParameters() throws IOException { String content = "Hello, world"; - new HttpRequestSnippet().document(this.operationBuilder - .request("http://localhost/foo?b=bravo&a=alpha").method("POST") - .param("a", "alpha").param("b", "bravo").content(content).build()); + new HttpRequestSnippet().document(this.operationBuilder.request("http://localhost/foo?b=bravo&a=alpha") + .method("POST").param("a", "alpha").param("b", "bravo").content(content).build()); assertThat(this.generatedSnippets.httpRequest()) - .is(httpRequest(RequestMethod.POST, "/foo?b=bravo&a=alpha") - .header(HttpHeaders.HOST, "localhost").content(content) - .header(HttpHeaders.CONTENT_LENGTH, content.getBytes().length)); + .is(httpRequest(RequestMethod.POST, "/foo?b=bravo&a=alpha").header(HttpHeaders.HOST, "localhost") + .content(content).header(HttpHeaders.CONTENT_LENGTH, content.getBytes().length)); } @Test - public void postRequestWithOverlappingParametersAndFormUrlEncodedBody() - throws IOException { + public void postRequestWithOverlappingParametersAndFormUrlEncodedBody() throws IOException { String content = "a=alpha&b=bravo"; - new HttpRequestSnippet().document(this.operationBuilder - .request("http://localhost/foo").method("POST").content("a=alpha&b=bravo") - .header(HttpHeaders.CONTENT_TYPE, - MediaType.APPLICATION_FORM_URLENCODED_VALUE) - .param("a", "alpha").param("b", "bravo").build()); - assertThat(this.generatedSnippets.httpRequest()) - .is(httpRequest(RequestMethod.POST, "/foo") - .header(HttpHeaders.CONTENT_TYPE, - MediaType.APPLICATION_FORM_URLENCODED_VALUE) - .header(HttpHeaders.HOST, "localhost").content(content) - .header(HttpHeaders.CONTENT_LENGTH, content.getBytes().length)); + new HttpRequestSnippet().document( + this.operationBuilder.request("http://localhost/foo").method("POST").content("a=alpha&b=bravo") + .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_FORM_URLENCODED_VALUE) + .param("a", "alpha").param("b", "bravo").build()); + assertThat(this.generatedSnippets.httpRequest()).is(httpRequest(RequestMethod.POST, "/foo") + .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_FORM_URLENCODED_VALUE) + .header(HttpHeaders.HOST, "localhost").content(content) + .header(HttpHeaders.CONTENT_LENGTH, content.getBytes().length)); } @Test public void postRequestWithCharset() throws IOException { String japaneseContent = "\u30b3\u30f3\u30c6\u30f3\u30c4"; byte[] contentBytes = japaneseContent.getBytes("UTF-8"); - new HttpRequestSnippet() - .document(this.operationBuilder.request("http://localhost/foo") - .method("POST").header("Content-Type", "text/plain;charset=UTF-8") - .content(contentBytes).build()); - assertThat(this.generatedSnippets.httpRequest()) - .is(httpRequest(RequestMethod.POST, "/foo") - .header("Content-Type", "text/plain;charset=UTF-8") - .header(HttpHeaders.HOST, "localhost") - .header(HttpHeaders.CONTENT_LENGTH, contentBytes.length) - .content(japaneseContent)); + new HttpRequestSnippet().document(this.operationBuilder.request("http://localhost/foo").method("POST") + .header("Content-Type", "text/plain;charset=UTF-8").content(contentBytes).build()); + assertThat(this.generatedSnippets.httpRequest()).is(httpRequest(RequestMethod.POST, "/foo") + .header("Content-Type", "text/plain;charset=UTF-8").header(HttpHeaders.HOST, "localhost") + .header(HttpHeaders.CONTENT_LENGTH, contentBytes.length).content(japaneseContent)); } @Test public void postRequestWithParameter() throws IOException { - new HttpRequestSnippet() - .document(this.operationBuilder.request("http://localhost/foo") - .method("POST").param("b&r", "baz").param("a", "alpha").build()); + new HttpRequestSnippet().document(this.operationBuilder.request("http://localhost/foo").method("POST") + .param("b&r", "baz").param("a", "alpha").build()); assertThat(this.generatedSnippets.httpRequest()) - .is(httpRequest(RequestMethod.POST, "/foo") - .header(HttpHeaders.HOST, "localhost") - .header("Content-Type", "application/x-www-form-urlencoded") - .content("b%26r=baz&a=alpha")); + .is(httpRequest(RequestMethod.POST, "/foo").header(HttpHeaders.HOST, "localhost") + .header("Content-Type", "application/x-www-form-urlencoded").content("b%26r=baz&a=alpha")); } @Test public void postRequestWithParameterWithNoValue() throws IOException { - new HttpRequestSnippet().document(this.operationBuilder - .request("http://localhost/foo").method("POST").param("bar").build()); + new HttpRequestSnippet() + .document(this.operationBuilder.request("http://localhost/foo").method("POST").param("bar").build()); assertThat(this.generatedSnippets.httpRequest()) - .is(httpRequest(RequestMethod.POST, "/foo") - .header(HttpHeaders.HOST, "localhost") - .header("Content-Type", "application/x-www-form-urlencoded") - .content("bar=")); + .is(httpRequest(RequestMethod.POST, "/foo").header(HttpHeaders.HOST, "localhost") + .header("Content-Type", "application/x-www-form-urlencoded").content("bar=")); } @Test public void putRequestWithContent() throws IOException { String content = "Hello, world"; - new HttpRequestSnippet().document(this.operationBuilder - .request("http://localhost/foo").method("PUT").content(content).build()); + new HttpRequestSnippet() + .document(this.operationBuilder.request("http://localhost/foo").method("PUT").content(content).build()); assertThat(this.generatedSnippets.httpRequest()) - .is(httpRequest(RequestMethod.PUT, "/foo") - .header(HttpHeaders.HOST, "localhost").content(content) + .is(httpRequest(RequestMethod.PUT, "/foo").header(HttpHeaders.HOST, "localhost").content(content) .header(HttpHeaders.CONTENT_LENGTH, content.getBytes().length)); } @Test public void putRequestWithParameter() throws IOException { - new HttpRequestSnippet() - .document(this.operationBuilder.request("http://localhost/foo") - .method("PUT").param("b&r", "baz").param("a", "alpha").build()); + new HttpRequestSnippet().document(this.operationBuilder.request("http://localhost/foo").method("PUT") + .param("b&r", "baz").param("a", "alpha").build()); assertThat(this.generatedSnippets.httpRequest()) - .is(httpRequest(RequestMethod.PUT, "/foo") - .header(HttpHeaders.HOST, "localhost") - .header("Content-Type", "application/x-www-form-urlencoded") - .content("b%26r=baz&a=alpha")); + .is(httpRequest(RequestMethod.PUT, "/foo").header(HttpHeaders.HOST, "localhost") + .header("Content-Type", "application/x-www-form-urlencoded").content("b%26r=baz&a=alpha")); } @Test public void multipartPost() throws IOException { - new HttpRequestSnippet().document(this.operationBuilder - .request("http://localhost/upload").method("POST") + new HttpRequestSnippet().document(this.operationBuilder.request("http://localhost/upload").method("POST") .header(HttpHeaders.CONTENT_TYPE, MediaType.MULTIPART_FORM_DATA_VALUE) .part("image", "<< data >>".getBytes()).build()); - String expectedContent = createPart(String.format( - "Content-Disposition: " + "form-data; " + "name=image%n%n<< data >>")); - assertThat(this.generatedSnippets.httpRequest()) - .is(httpRequest(RequestMethod.POST, "/upload") - .header("Content-Type", - "multipart/form-data; boundary=" + BOUNDARY) - .header(HttpHeaders.HOST, "localhost").content(expectedContent)); + String expectedContent = createPart( + String.format("Content-Disposition: " + "form-data; " + "name=image%n%n<< data >>")); + assertThat(this.generatedSnippets.httpRequest()).is(httpRequest(RequestMethod.POST, "/upload") + .header("Content-Type", "multipart/form-data; boundary=" + BOUNDARY) + .header(HttpHeaders.HOST, "localhost").content(expectedContent)); } @Test public void multipartPostWithFilename() throws IOException { - new HttpRequestSnippet().document(this.operationBuilder - .request("http://localhost/upload").method("POST") + new HttpRequestSnippet().document(this.operationBuilder.request("http://localhost/upload").method("POST") .header(HttpHeaders.CONTENT_TYPE, MediaType.MULTIPART_FORM_DATA_VALUE) - .part("image", "<< data >>".getBytes()).submittedFileName("image.png") - .build()); - String expectedContent = createPart(String.format("Content-Disposition: " - + "form-data; " + "name=image; filename=image.png%n%n<< data >>")); - assertThat(this.generatedSnippets.httpRequest()) - .is(httpRequest(RequestMethod.POST, "/upload") - .header("Content-Type", - "multipart/form-data; boundary=" + BOUNDARY) - .header(HttpHeaders.HOST, "localhost").content(expectedContent)); + .part("image", "<< data >>".getBytes()).submittedFileName("image.png").build()); + String expectedContent = createPart(String + .format("Content-Disposition: " + "form-data; " + "name=image; filename=image.png%n%n<< data >>")); + assertThat(this.generatedSnippets.httpRequest()).is(httpRequest(RequestMethod.POST, "/upload") + .header("Content-Type", "multipart/form-data; boundary=" + BOUNDARY) + .header(HttpHeaders.HOST, "localhost").content(expectedContent)); } @Test public void multipartPostWithParameters() throws IOException { - new HttpRequestSnippet().document(this.operationBuilder - .request("http://localhost/upload").method("POST") - .header(HttpHeaders.CONTENT_TYPE, MediaType.MULTIPART_FORM_DATA_VALUE) - .param("a", "apple", "avocado").param("b", "banana") - .part("image", "<< data >>".getBytes()).build()); - String param1Part = createPart( - String.format("Content-Disposition: form-data; " + "name=a%n%napple"), - false); - String param2Part = createPart( - String.format("Content-Disposition: form-data; " + "name=a%n%navocado"), - false); - String param3Part = createPart( - String.format("Content-Disposition: form-data; " + "name=b%n%nbanana"), - false); - String filePart = createPart(String - .format("Content-Disposition: form-data; " + "name=image%n%n<< data >>")); + new HttpRequestSnippet().document(this.operationBuilder.request("http://localhost/upload").method("POST") + .header(HttpHeaders.CONTENT_TYPE, MediaType.MULTIPART_FORM_DATA_VALUE).param("a", "apple", "avocado") + .param("b", "banana").part("image", "<< data >>".getBytes()).build()); + String param1Part = createPart(String.format("Content-Disposition: form-data; " + "name=a%n%napple"), false); + String param2Part = createPart(String.format("Content-Disposition: form-data; " + "name=a%n%navocado"), false); + String param3Part = createPart(String.format("Content-Disposition: form-data; " + "name=b%n%nbanana"), false); + String filePart = createPart(String.format("Content-Disposition: form-data; " + "name=image%n%n<< data >>")); String expectedContent = param1Part + param2Part + param3Part + filePart; - assertThat(this.generatedSnippets.httpRequest()) - .is(httpRequest(RequestMethod.POST, "/upload") - .header("Content-Type", - "multipart/form-data; boundary=" + BOUNDARY) - .header(HttpHeaders.HOST, "localhost").content(expectedContent)); + assertThat(this.generatedSnippets.httpRequest()).is(httpRequest(RequestMethod.POST, "/upload") + .header("Content-Type", "multipart/form-data; boundary=" + BOUNDARY) + .header(HttpHeaders.HOST, "localhost").content(expectedContent)); } @Test public void multipartPostWithParameterWithNoValue() throws IOException { - new HttpRequestSnippet().document(this.operationBuilder - .request("http://localhost/upload").method("POST") - .header(HttpHeaders.CONTENT_TYPE, MediaType.MULTIPART_FORM_DATA_VALUE) - .param("a").part("image", "<< data >>".getBytes()).build()); - String paramPart = createPart( - String.format("Content-Disposition: form-data; " + "name=a%n"), false); - String filePart = createPart(String - .format("Content-Disposition: form-data; " + "name=image%n%n<< data >>")); + new HttpRequestSnippet().document(this.operationBuilder.request("http://localhost/upload").method("POST") + .header(HttpHeaders.CONTENT_TYPE, MediaType.MULTIPART_FORM_DATA_VALUE).param("a") + .part("image", "<< data >>".getBytes()).build()); + String paramPart = createPart(String.format("Content-Disposition: form-data; " + "name=a%n"), false); + String filePart = createPart(String.format("Content-Disposition: form-data; " + "name=image%n%n<< data >>")); String expectedContent = paramPart + filePart; - assertThat(this.generatedSnippets.httpRequest()) - .is(httpRequest(RequestMethod.POST, "/upload") - .header("Content-Type", - "multipart/form-data; boundary=" + BOUNDARY) - .header(HttpHeaders.HOST, "localhost").content(expectedContent)); + assertThat(this.generatedSnippets.httpRequest()).is(httpRequest(RequestMethod.POST, "/upload") + .header("Content-Type", "multipart/form-data; boundary=" + BOUNDARY) + .header(HttpHeaders.HOST, "localhost").content(expectedContent)); } @Test public void multipartPostWithContentType() throws IOException { - new HttpRequestSnippet().document(this.operationBuilder - .request("http://localhost/upload").method("POST") + new HttpRequestSnippet().document(this.operationBuilder.request("http://localhost/upload").method("POST") .header(HttpHeaders.CONTENT_TYPE, MediaType.MULTIPART_FORM_DATA_VALUE) - .part("image", "<< data >>".getBytes()) - .header(HttpHeaders.CONTENT_TYPE, MediaType.IMAGE_PNG_VALUE).build()); - String expectedContent = createPart( - String.format("Content-Disposition: form-data; name=image%nContent-Type: " - + "image/png%n%n<< data >>")); - assertThat(this.generatedSnippets.httpRequest()) - .is(httpRequest(RequestMethod.POST, "/upload") - .header("Content-Type", - "multipart/form-data; boundary=" + BOUNDARY) - .header(HttpHeaders.HOST, "localhost").content(expectedContent)); + .part("image", "<< data >>".getBytes()).header(HttpHeaders.CONTENT_TYPE, MediaType.IMAGE_PNG_VALUE) + .build()); + String expectedContent = createPart(String + .format("Content-Disposition: form-data; name=image%nContent-Type: " + "image/png%n%n<< data >>")); + assertThat(this.generatedSnippets.httpRequest()).is(httpRequest(RequestMethod.POST, "/upload") + .header("Content-Type", "multipart/form-data; boundary=" + BOUNDARY) + .header(HttpHeaders.HOST, "localhost").content(expectedContent)); } @Test public void getRequestWithCustomHost() throws IOException { - new HttpRequestSnippet() - .document(this.operationBuilder.request("http://localhost/foo") - .header(HttpHeaders.HOST, "api.example.com").build()); + new HttpRequestSnippet().document(this.operationBuilder.request("http://localhost/foo") + .header(HttpHeaders.HOST, "api.example.com").build()); assertThat(this.generatedSnippets.httpRequest()) - .is(httpRequest(RequestMethod.GET, "/foo").header(HttpHeaders.HOST, - "api.example.com")); + .is(httpRequest(RequestMethod.GET, "/foo").header(HttpHeaders.HOST, "api.example.com")); } @Test public void requestWithCustomSnippetAttributes() throws IOException { TemplateResourceResolver resolver = mock(TemplateResourceResolver.class); - given(resolver.resolveTemplateResource("http-request")) - .willReturn(snippetResource("http-request-with-title")); - new HttpRequestSnippet(attributes(key("title").value("Title for the request"))) - .document(this.operationBuilder - .attribute(TemplateEngine.class.getName(), - new MustacheTemplateEngine(resolver)) + given(resolver.resolveTemplateResource("http-request")).willReturn(snippetResource("http-request-with-title")); + new HttpRequestSnippet(attributes(key("title").value("Title for the request"))).document( + this.operationBuilder.attribute(TemplateEngine.class.getName(), new MustacheTemplateEngine(resolver)) .request("http://localhost/foo").build()); - assertThat(this.generatedSnippets.httpRequest()) - .contains("Title for the request"); + assertThat(this.generatedSnippets.httpRequest()).contains("Title for the request"); } private String createPart(String content) { diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/http/HttpResponseSnippetTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/http/HttpResponseSnippetTests.java index d84d4d243..bf701b432 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/http/HttpResponseSnippetTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/http/HttpResponseSnippetTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-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. @@ -55,29 +55,25 @@ public void basicResponse() throws IOException { @Test public void nonOkResponse() throws IOException { - new HttpResponseSnippet().document(this.operationBuilder.response() - .status(HttpStatus.BAD_REQUEST.value()).build()); - assertThat(this.generatedSnippets.httpResponse()) - .is(httpResponse(HttpStatus.BAD_REQUEST)); + new HttpResponseSnippet() + .document(this.operationBuilder.response().status(HttpStatus.BAD_REQUEST.value()).build()); + assertThat(this.generatedSnippets.httpResponse()).is(httpResponse(HttpStatus.BAD_REQUEST)); } @Test public void responseWithHeaders() throws IOException { new HttpResponseSnippet().document(this.operationBuilder.response() - .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) - .header("a", "alpha").build()); - assertThat(this.generatedSnippets.httpResponse()).is(httpResponse(HttpStatus.OK) - .header("Content-Type", "application/json").header("a", "alpha")); + .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE).header("a", "alpha").build()); + assertThat(this.generatedSnippets.httpResponse()) + .is(httpResponse(HttpStatus.OK).header("Content-Type", "application/json").header("a", "alpha")); } @Test public void responseWithContent() throws IOException { String content = "content"; - new HttpResponseSnippet() - .document(this.operationBuilder.response().content(content).build()); - assertThat(this.generatedSnippets.httpResponse()) - .is(httpResponse(HttpStatus.OK).content(content) - .header(HttpHeaders.CONTENT_LENGTH, content.getBytes().length)); + new HttpResponseSnippet().document(this.operationBuilder.response().content(content).build()); + assertThat(this.generatedSnippets.httpResponse()).is(httpResponse(HttpStatus.OK).content(content) + .header(HttpHeaders.CONTENT_LENGTH, content.getBytes().length)); } @Test @@ -85,12 +81,10 @@ public void responseWithCharset() throws IOException { String japaneseContent = "\u30b3\u30f3\u30c6\u30f3\u30c4"; byte[] contentBytes = japaneseContent.getBytes("UTF-8"); new HttpResponseSnippet().document(this.operationBuilder.response() - .header("Content-Type", "text/plain;charset=UTF-8").content(contentBytes) - .build()); - assertThat(this.generatedSnippets.httpResponse()).is(httpResponse(HttpStatus.OK) - .header("Content-Type", "text/plain;charset=UTF-8") - .content(japaneseContent) - .header(HttpHeaders.CONTENT_LENGTH, contentBytes.length)); + .header("Content-Type", "text/plain;charset=UTF-8").content(contentBytes).build()); + assertThat(this.generatedSnippets.httpResponse()) + .is(httpResponse(HttpStatus.OK).header("Content-Type", "text/plain;charset=UTF-8") + .content(japaneseContent).header(HttpHeaders.CONTENT_LENGTH, contentBytes.length)); } @Test @@ -98,11 +92,9 @@ public void responseWithCustomSnippetAttributes() throws IOException { TemplateResourceResolver resolver = mock(TemplateResourceResolver.class); given(resolver.resolveTemplateResource("http-response")) .willReturn(snippetResource("http-response-with-title")); - new HttpResponseSnippet(attributes(key("title").value("Title for the response"))) - .document(this.operationBuilder.attribute(TemplateEngine.class.getName(), - new MustacheTemplateEngine(resolver)).build()); - assertThat(this.generatedSnippets.httpResponse()) - .contains("Title for the response"); + new HttpResponseSnippet(attributes(key("title").value("Title for the response"))).document(this.operationBuilder + .attribute(TemplateEngine.class.getName(), new MustacheTemplateEngine(resolver)).build()); + assertThat(this.generatedSnippets.httpResponse()).contains("Title for the response"); } } diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/hypermedia/ContentTypeLinkExtractorTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/hypermedia/ContentTypeLinkExtractorTests.java index d22c54a84..cb88d4d2c 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/hypermedia/ContentTypeLinkExtractorTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/hypermedia/ContentTypeLinkExtractorTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2017 the original author or authors. + * Copyright 2014-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. @@ -48,8 +48,8 @@ public class ContentTypeLinkExtractorTests { @Test public void extractionFailsWithNullContentType() throws IOException { this.thrown.expect(IllegalStateException.class); - new ContentTypeLinkExtractor().extractLinks( - this.responseFactory.create(HttpStatus.OK, new HttpHeaders(), null)); + new ContentTypeLinkExtractor() + .extractLinks(this.responseFactory.create(HttpStatus.OK, new HttpHeaders(), null)); } @Test @@ -59,8 +59,7 @@ public void extractorCalledWithMatchingContextType() throws IOException { extractors.put(MediaType.APPLICATION_JSON, extractor); HttpHeaders httpHeaders = new HttpHeaders(); httpHeaders.setContentType(MediaType.APPLICATION_JSON); - OperationResponse response = this.responseFactory.create(HttpStatus.OK, - httpHeaders, null); + OperationResponse response = this.responseFactory.create(HttpStatus.OK, httpHeaders, null); new ContentTypeLinkExtractor(extractors).extractLinks(response); verify(extractor).extractLinks(response); } @@ -72,8 +71,7 @@ public void extractorCalledWithCompatibleContextType() throws IOException { extractors.put(MediaType.APPLICATION_JSON, extractor); HttpHeaders httpHeaders = new HttpHeaders(); httpHeaders.setContentType(MediaType.parseMediaType("application/json;foo=bar")); - OperationResponse response = this.responseFactory.create(HttpStatus.OK, - httpHeaders, null); + OperationResponse response = this.responseFactory.create(HttpStatus.OK, httpHeaders, null); new ContentTypeLinkExtractor(extractors).extractLinks(response); verify(extractor).extractLinks(response); } diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/hypermedia/LinkExtractorsPayloadTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/hypermedia/LinkExtractorsPayloadTests.java index ea0d4a02e..55e4ccacc 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/hypermedia/LinkExtractorsPayloadTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/hypermedia/LinkExtractorsPayloadTests.java @@ -66,11 +66,8 @@ public LinkExtractorsPayloadTests(LinkExtractor linkExtractor, String linkType) @Test public void singleLink() throws IOException { - Map> links = this.linkExtractor - .extractLinks(createResponse("single-link")); - assertLinks( - Arrays.asList(new Link("alpha", "https://alpha.example.com", "Alpha")), - links); + Map> links = this.linkExtractor.extractLinks(createResponse("single-link")); + assertLinks(Arrays.asList(new Link("alpha", "https://alpha.example.com", "Alpha")), links); } @Test @@ -83,29 +80,24 @@ public void multipleLinksWithDifferentRels() throws IOException { @Test public void multipleLinksWithSameRels() throws IOException { - Map> links = this.linkExtractor - .extractLinks(createResponse("multiple-links-same-rels")); - assertLinks(Arrays.asList( - new Link("alpha", "https://alpha.example.com/one", "Alpha one"), + Map> links = this.linkExtractor.extractLinks(createResponse("multiple-links-same-rels")); + assertLinks(Arrays.asList(new Link("alpha", "https://alpha.example.com/one", "Alpha one"), new Link("alpha", "https://alpha.example.com/two")), links); } @Test public void noLinks() throws IOException { - Map> links = this.linkExtractor - .extractLinks(createResponse("no-links")); + Map> links = this.linkExtractor.extractLinks(createResponse("no-links")); assertLinks(Collections.emptyList(), links); } @Test public void linksInTheWrongFormat() throws IOException { - Map> links = this.linkExtractor - .extractLinks(createResponse("wrong-format")); + Map> links = this.linkExtractor.extractLinks(createResponse("wrong-format")); assertLinks(Collections.emptyList(), links); } - private void assertLinks(List expectedLinks, - Map> actualLinks) { + private void assertLinks(List expectedLinks, Map> actualLinks) { MultiValueMap expectedLinksByRel = new LinkedMultiValueMap<>(); for (Link expectedLink : expectedLinks) { expectedLinksByRel.add(expectedLink.getRel(), expectedLink); @@ -119,8 +111,7 @@ private OperationResponse createResponse(String contentName) throws IOException } private File getPayloadFile(String name) { - return new File("src/test/resources/link-payloads/" + this.linkType + "/" + name - + ".json"); + return new File("src/test/resources/link-payloads/" + this.linkType + "/" + name + ".json"); } } diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/hypermedia/LinksSnippetFailureTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/hypermedia/LinksSnippetFailureTests.java index a8a7f7f5e..cff432be8 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/hypermedia/LinksSnippetFailureTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/hypermedia/LinksSnippetFailureTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-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. @@ -39,8 +39,7 @@ public class LinksSnippetFailureTests { @Rule - public OperationBuilder operationBuilder = new OperationBuilder( - TemplateFormats.asciidoctor()); + public OperationBuilder operationBuilder = new OperationBuilder(TemplateFormats.asciidoctor()); @Rule public ExpectedException thrown = ExpectedException.none(); @@ -48,43 +47,36 @@ public class LinksSnippetFailureTests { @Test public void undocumentedLink() throws IOException { this.thrown.expect(SnippetException.class); - this.thrown.expectMessage(equalTo( - "Links with the following relations were not" + " documented: [foo]")); + this.thrown.expectMessage(equalTo("Links with the following relations were not" + " documented: [foo]")); new LinksSnippet(new StubLinkExtractor().withLinks(new Link("foo", "bar")), - Collections.emptyList()) - .document(this.operationBuilder.build()); + Collections.emptyList()).document(this.operationBuilder.build()); } @Test public void missingLink() throws IOException { this.thrown.expect(SnippetException.class); - this.thrown.expectMessage(equalTo("Links with the following relations were not" - + " found in the response: [foo]")); - new LinksSnippet(new StubLinkExtractor(), - Arrays.asList(new LinkDescriptor("foo").description("bar"))) - .document(this.operationBuilder.build()); + this.thrown.expectMessage( + equalTo("Links with the following relations were not" + " found in the response: [foo]")); + new LinksSnippet(new StubLinkExtractor(), Arrays.asList(new LinkDescriptor("foo").description("bar"))) + .document(this.operationBuilder.build()); } @Test public void undocumentedLinkAndMissingLink() throws IOException { this.thrown.expect(SnippetException.class); this.thrown.expectMessage(equalTo("Links with the following relations were not" - + " documented: [a]. Links with the following relations were not" - + " found in the response: [foo]")); + + " documented: [a]. Links with the following relations were not" + " found in the response: [foo]")); new LinksSnippet(new StubLinkExtractor().withLinks(new Link("a", "alpha")), - Arrays.asList(new LinkDescriptor("foo").description("bar"))) - .document(this.operationBuilder.build()); + Arrays.asList(new LinkDescriptor("foo").description("bar"))).document(this.operationBuilder.build()); } @Test public void linkWithNoDescription() throws IOException { this.thrown.expect(SnippetException.class); - this.thrown.expectMessage( - equalTo("No description was provided for the link with rel 'foo' and no" - + " title was available from the link in the payload")); + this.thrown.expectMessage(equalTo("No description was provided for the link with rel 'foo' and no" + + " title was available from the link in the payload")); new LinksSnippet(new StubLinkExtractor().withLinks(new Link("foo", "bar")), - Arrays.asList(new LinkDescriptor("foo"))) - .document(this.operationBuilder.build()); + Arrays.asList(new LinkDescriptor("foo"))).document(this.operationBuilder.build()); } } diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/hypermedia/LinksSnippetTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/hypermedia/LinksSnippetTests.java index 783588a43..05b88c16f 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/hypermedia/LinksSnippetTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/hypermedia/LinksSnippetTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-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. @@ -47,25 +47,18 @@ public LinksSnippetTests(String name, TemplateFormat templateFormat) { @Test public void ignoredLink() throws IOException { - new LinksSnippet( - new StubLinkExtractor().withLinks(new Link("a", "alpha"), - new Link("b", "bravo")), - Arrays.asList(new LinkDescriptor("a").ignored(), - new LinkDescriptor("b").description("Link b"))) - .document(this.operationBuilder.build()); - assertThat(this.generatedSnippets.links()) - .is(tableWithHeader("Relation", "Description").row("`b`", "Link b")); + new LinksSnippet(new StubLinkExtractor().withLinks(new Link("a", "alpha"), new Link("b", "bravo")), + Arrays.asList(new LinkDescriptor("a").ignored(), new LinkDescriptor("b").description("Link b"))) + .document(this.operationBuilder.build()); + assertThat(this.generatedSnippets.links()).is(tableWithHeader("Relation", "Description").row("`b`", "Link b")); } @Test public void allUndocumentedLinksCanBeIgnored() throws IOException { - new LinksSnippet( - new StubLinkExtractor().withLinks(new Link("a", "alpha"), - new Link("b", "bravo")), + new LinksSnippet(new StubLinkExtractor().withLinks(new Link("a", "alpha"), new Link("b", "bravo")), Arrays.asList(new LinkDescriptor("b").description("Link b")), true) .document(this.operationBuilder.build()); - assertThat(this.generatedSnippets.links()) - .is(tableWithHeader("Relation", "Description").row("`b`", "Link b")); + assertThat(this.generatedSnippets.links()).is(tableWithHeader("Relation", "Description").row("`b`", "Link b")); } @Test @@ -73,8 +66,7 @@ public void presentOptionalLink() throws IOException { new LinksSnippet(new StubLinkExtractor().withLinks(new Link("foo", "blah")), Arrays.asList(new LinkDescriptor("foo").description("bar").optional())) .document(this.operationBuilder.build()); - assertThat(this.generatedSnippets.links()) - .is(tableWithHeader("Relation", "Description").row("`foo`", "bar")); + assertThat(this.generatedSnippets.links()).is(tableWithHeader("Relation", "Description").row("`foo`", "bar")); } @Test @@ -82,87 +74,63 @@ public void missingOptionalLink() throws IOException { new LinksSnippet(new StubLinkExtractor(), Arrays.asList(new LinkDescriptor("foo").description("bar").optional())) .document(this.operationBuilder.build()); - assertThat(this.generatedSnippets.links()) - .is(tableWithHeader("Relation", "Description").row("`foo`", "bar")); + assertThat(this.generatedSnippets.links()).is(tableWithHeader("Relation", "Description").row("`foo`", "bar")); } @Test public void documentedLinks() throws IOException { - new LinksSnippet( - new StubLinkExtractor().withLinks(new Link("a", "alpha"), - new Link("b", "bravo")), - Arrays.asList(new LinkDescriptor("a").description("one"), - new LinkDescriptor("b").description("two"))) - .document(this.operationBuilder.build()); + new LinksSnippet(new StubLinkExtractor().withLinks(new Link("a", "alpha"), new Link("b", "bravo")), + Arrays.asList(new LinkDescriptor("a").description("one"), new LinkDescriptor("b").description("two"))) + .document(this.operationBuilder.build()); assertThat(this.generatedSnippets.links()) - .is(tableWithHeader("Relation", "Description").row("`a`", "one") - .row("`b`", "two")); + .is(tableWithHeader("Relation", "Description").row("`a`", "one").row("`b`", "two")); } @Test public void linkDescriptionFromTitleInPayload() throws IOException { new LinksSnippet( - new StubLinkExtractor().withLinks(new Link("a", "alpha", "Link a"), - new Link("b", "bravo", "Link b")), - Arrays.asList(new LinkDescriptor("a").description("one"), - new LinkDescriptor("b"))).document(this.operationBuilder.build()); + new StubLinkExtractor().withLinks(new Link("a", "alpha", "Link a"), new Link("b", "bravo", "Link b")), + Arrays.asList(new LinkDescriptor("a").description("one"), new LinkDescriptor("b"))) + .document(this.operationBuilder.build()); assertThat(this.generatedSnippets.links()) - .is(tableWithHeader("Relation", "Description").row("`a`", "one") - .row("`b`", "Link b")); + .is(tableWithHeader("Relation", "Description").row("`a`", "one").row("`b`", "Link b")); } @Test public void linksWithCustomAttributes() throws IOException { TemplateResourceResolver resolver = mock(TemplateResourceResolver.class); - given(resolver.resolveTemplateResource("links")) - .willReturn(snippetResource("links-with-title")); - new LinksSnippet( - new StubLinkExtractor().withLinks(new Link("a", "alpha"), - new Link("b", "bravo")), - Arrays.asList(new LinkDescriptor("a").description("one"), - new LinkDescriptor("b").description("two")), + given(resolver.resolveTemplateResource("links")).willReturn(snippetResource("links-with-title")); + new LinksSnippet(new StubLinkExtractor().withLinks(new Link("a", "alpha"), new Link("b", "bravo")), + Arrays.asList(new LinkDescriptor("a").description("one"), new LinkDescriptor("b").description("two")), attributes(key("title").value("Title for the links"))) - .document( - this.operationBuilder - .attribute(TemplateEngine.class.getName(), - new MustacheTemplateEngine(resolver)) - .build()); + .document(this.operationBuilder + .attribute(TemplateEngine.class.getName(), new MustacheTemplateEngine(resolver)) + .build()); assertThat(this.generatedSnippets.links()).contains("Title for the links"); } @Test public void linksWithCustomDescriptorAttributes() throws IOException { TemplateResourceResolver resolver = mock(TemplateResourceResolver.class); - given(resolver.resolveTemplateResource("links")) - .willReturn(snippetResource("links-with-extra-column")); - new LinksSnippet( - new StubLinkExtractor().withLinks(new Link("a", "alpha"), - new Link("b", "bravo")), - Arrays.asList( - new LinkDescriptor("a").description("one") - .attributes(key("foo").value("alpha")), - new LinkDescriptor("b").description("two") - .attributes(key("foo").value("bravo")))) - .document(this.operationBuilder.attribute( - TemplateEngine.class.getName(), - new MustacheTemplateEngine(resolver)) - .build()); - assertThat(this.generatedSnippets.links()) - .is(tableWithHeader("Relation", "Description", "Foo") - .row("a", "one", "alpha").row("b", "two", "bravo")); + given(resolver.resolveTemplateResource("links")).willReturn(snippetResource("links-with-extra-column")); + new LinksSnippet(new StubLinkExtractor().withLinks(new Link("a", "alpha"), new Link("b", "bravo")), + Arrays.asList(new LinkDescriptor("a").description("one").attributes(key("foo").value("alpha")), + new LinkDescriptor("b").description("two").attributes(key("foo").value("bravo")))) + .document(this.operationBuilder + .attribute(TemplateEngine.class.getName(), new MustacheTemplateEngine(resolver)) + .build()); + assertThat(this.generatedSnippets.links()).is( + tableWithHeader("Relation", "Description", "Foo").row("a", "one", "alpha").row("b", "two", "bravo")); } @Test public void additionalDescriptors() throws IOException { HypermediaDocumentation - .links(new StubLinkExtractor().withLinks(new Link("a", "alpha"), - new Link("b", "bravo")), + .links(new StubLinkExtractor().withLinks(new Link("a", "alpha"), new Link("b", "bravo")), new LinkDescriptor("a").description("one")) - .and(new LinkDescriptor("b").description("two")) - .document(this.operationBuilder.build()); + .and(new LinkDescriptor("b").description("two")).document(this.operationBuilder.build()); assertThat(this.generatedSnippets.links()) - .is(tableWithHeader("Relation", "Description").row("`a`", "one") - .row("`b`", "two")); + .is(tableWithHeader("Relation", "Description").row("`a`", "one").row("`b`", "two")); } @Test @@ -170,9 +138,8 @@ public void tableCellContentIsEscapedWhenNecessary() throws IOException { new LinksSnippet(new StubLinkExtractor().withLinks(new Link("Foo|Bar", "foo")), Arrays.asList(new LinkDescriptor("Foo|Bar").description("one|two"))) .document(this.operationBuilder.build()); - assertThat(this.generatedSnippets.links()) - .is(tableWithHeader("Relation", "Description").row( - escapeIfNecessary("`Foo|Bar`"), escapeIfNecessary("one|two"))); + assertThat(this.generatedSnippets.links()).is(tableWithHeader("Relation", "Description") + .row(escapeIfNecessary("`Foo|Bar`"), escapeIfNecessary("one|two"))); } private String escapeIfNecessary(String input) { diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/hypermedia/StubLinkExtractor.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/hypermedia/StubLinkExtractor.java index 71d7a4ee8..ca5e3d6b8 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/hypermedia/StubLinkExtractor.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/hypermedia/StubLinkExtractor.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2016 the original author or authors. + * Copyright 2014-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. @@ -32,8 +32,7 @@ class StubLinkExtractor implements LinkExtractor { private MultiValueMap linksByRel = new LinkedMultiValueMap<>(); @Override - public MultiValueMap extractLinks(OperationResponse response) - throws IOException { + public MultiValueMap extractLinks(OperationResponse response) throws IOException { return this.linksByRel; } diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/operation/QueryStringParserTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/operation/QueryStringParserTests.java index f365dff08..75450b3be 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/operation/QueryStringParserTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/operation/QueryStringParserTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-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. @@ -40,23 +40,20 @@ public class QueryStringParserTests { @Test public void noParameters() { - Parameters parameters = this.queryStringParser - .parse(URI.create("http://localhost")); + Parameters parameters = this.queryStringParser.parse(URI.create("http://localhost")); assertThat(parameters.size()).isEqualTo(0); } @Test public void singleParameter() { - Parameters parameters = this.queryStringParser - .parse(URI.create("http://localhost?a=alpha")); + Parameters parameters = this.queryStringParser.parse(URI.create("http://localhost?a=alpha")); assertThat(parameters.size()).isEqualTo(1); assertThat(parameters).containsEntry("a", Arrays.asList("alpha")); } @Test public void multipleParameters() { - Parameters parameters = this.queryStringParser - .parse(URI.create("http://localhost?a=alpha&b=bravo&c=charlie")); + Parameters parameters = this.queryStringParser.parse(URI.create("http://localhost?a=alpha&b=bravo&c=charlie")); assertThat(parameters.size()).isEqualTo(3); assertThat(parameters).containsEntry("a", Arrays.asList("alpha")); assertThat(parameters).containsEntry("b", Arrays.asList("bravo")); @@ -65,16 +62,14 @@ public void multipleParameters() { @Test public void multipleParametersWithSameKey() { - Parameters parameters = this.queryStringParser - .parse(URI.create("http://localhost?a=apple&a=avocado")); + Parameters parameters = this.queryStringParser.parse(URI.create("http://localhost?a=apple&a=avocado")); assertThat(parameters.size()).isEqualTo(1); assertThat(parameters).containsEntry("a", Arrays.asList("apple", "avocado")); } @Test public void encoded() { - Parameters parameters = this.queryStringParser - .parse(URI.create("http://localhost?a=al%26%3Dpha")); + Parameters parameters = this.queryStringParser.parse(URI.create("http://localhost?a=al%26%3Dpha")); assertThat(parameters.size()).isEqualTo(1); assertThat(parameters).containsEntry("a", Arrays.asList("al&=pha")); } @@ -82,8 +77,7 @@ public void encoded() { @Test public void malformedParameter() { this.thrown.expect(IllegalArgumentException.class); - this.thrown - .expectMessage(equalTo("The parameter 'a=apple=avocado' is malformed")); + this.thrown.expectMessage(equalTo("The parameter 'a=apple=avocado' is malformed")); this.queryStringParser.parse(URI.create("http://localhost?a=apple=avocado")); } diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/operation/preprocess/ContentModifyingOperationPreprocessorTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/operation/preprocess/ContentModifyingOperationPreprocessorTests.java index 52c89a189..1835b856a 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/operation/preprocess/ContentModifyingOperationPreprocessorTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/operation/preprocess/ContentModifyingOperationPreprocessorTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-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. @@ -58,9 +58,8 @@ public byte[] modifyContent(byte[] originalContent, MediaType mediaType) { @Test public void modifyRequestContent() { - OperationRequest request = this.requestFactory.create( - URI.create("http://localhost"), HttpMethod.GET, "content".getBytes(), - new HttpHeaders(), new Parameters(), + OperationRequest request = this.requestFactory.create(URI.create("http://localhost"), HttpMethod.GET, + "content".getBytes(), new HttpHeaders(), new Parameters(), Collections.emptyList()); OperationRequest preprocessed = this.preprocessor.preprocess(request); assertThat(preprocessed.getContent()).isEqualTo("modified".getBytes()); @@ -68,8 +67,8 @@ public void modifyRequestContent() { @Test public void modifyResponseContent() { - OperationResponse response = this.responseFactory.create(HttpStatus.OK, - new HttpHeaders(), "content".getBytes()); + OperationResponse response = this.responseFactory.create(HttpStatus.OK, new HttpHeaders(), + "content".getBytes()); OperationResponse preprocessed = this.preprocessor.preprocess(response); assertThat(preprocessed.getContent()).isEqualTo("modified".getBytes()); } @@ -78,10 +77,8 @@ public void modifyResponseContent() { public void contentLengthIsUpdated() { HttpHeaders httpHeaders = new HttpHeaders(); httpHeaders.setContentLength(7); - OperationRequest request = this.requestFactory.create( - URI.create("http://localhost"), HttpMethod.GET, "content".getBytes(), - httpHeaders, new Parameters(), - Collections.emptyList()); + OperationRequest request = this.requestFactory.create(URI.create("http://localhost"), HttpMethod.GET, + "content".getBytes(), httpHeaders, new Parameters(), Collections.emptyList()); OperationRequest preprocessed = this.preprocessor.preprocess(request); assertThat(preprocessed.getHeaders().getContentLength()).isEqualTo(8L); } diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/operation/preprocess/DelegatingOperationRequestPreprocessorTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/operation/preprocess/DelegatingOperationRequestPreprocessorTests.java index 203f3d7f8..63335f725 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/operation/preprocess/DelegatingOperationRequestPreprocessorTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/operation/preprocess/DelegatingOperationRequestPreprocessorTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-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. @@ -44,14 +44,11 @@ public void delegationOccurs() { OperationRequest preprocessedRequest3 = mock(OperationRequest.class); given(preprocessor1.preprocess(originalRequest)).willReturn(preprocessedRequest1); - given(preprocessor2.preprocess(preprocessedRequest1)) - .willReturn(preprocessedRequest2); - given(preprocessor3.preprocess(preprocessedRequest2)) - .willReturn(preprocessedRequest3); + given(preprocessor2.preprocess(preprocessedRequest1)).willReturn(preprocessedRequest2); + given(preprocessor3.preprocess(preprocessedRequest2)).willReturn(preprocessedRequest3); OperationRequest result = new DelegatingOperationRequestPreprocessor( - Arrays.asList(preprocessor1, preprocessor2, preprocessor3)) - .preprocess(originalRequest); + Arrays.asList(preprocessor1, preprocessor2, preprocessor3)).preprocess(originalRequest); assertThat(result).isSameAs(preprocessedRequest3); } diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/operation/preprocess/DelegatingOperationResponsePreprocessorTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/operation/preprocess/DelegatingOperationResponsePreprocessorTests.java index 1e350ce69..80f60a7b8 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/operation/preprocess/DelegatingOperationResponsePreprocessorTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/operation/preprocess/DelegatingOperationResponsePreprocessorTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-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. @@ -43,16 +43,12 @@ public void delegationOccurs() { OperationPreprocessor preprocessor3 = mock(OperationPreprocessor.class); OperationResponse preprocessedResponse3 = mock(OperationResponse.class); - given(preprocessor1.preprocess(originalResponse)) - .willReturn(preprocessedResponse1); - given(preprocessor2.preprocess(preprocessedResponse1)) - .willReturn(preprocessedResponse2); - given(preprocessor3.preprocess(preprocessedResponse2)) - .willReturn(preprocessedResponse3); + given(preprocessor1.preprocess(originalResponse)).willReturn(preprocessedResponse1); + given(preprocessor2.preprocess(preprocessedResponse1)).willReturn(preprocessedResponse2); + given(preprocessor3.preprocess(preprocessedResponse2)).willReturn(preprocessedResponse3); OperationResponse result = new DelegatingOperationResponsePreprocessor( - Arrays.asList(preprocessor1, preprocessor2, preprocessor3)) - .preprocess(originalResponse); + Arrays.asList(preprocessor1, preprocessor2, preprocessor3)).preprocess(originalResponse); assertThat(result).isSameAs(preprocessedResponse3); } diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/operation/preprocess/HeaderRemovingOperationPreprocessorTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/operation/preprocess/HeaderRemovingOperationPreprocessorTests.java index 873fe5418..79330122f 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/operation/preprocess/HeaderRemovingOperationPreprocessorTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/operation/preprocess/HeaderRemovingOperationPreprocessorTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2016 the original author or authors. + * Copyright 2014-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. @@ -51,15 +51,12 @@ public class HeaderRemovingOperationPreprocessorTests { @Test public void modifyRequestHeaders() { - OperationRequest request = this.requestFactory.create( - URI.create("http://localhost"), HttpMethod.GET, new byte[0], - getHttpHeaders(), new Parameters(), - Collections.emptyList()); + OperationRequest request = this.requestFactory.create(URI.create("http://localhost"), HttpMethod.GET, + new byte[0], getHttpHeaders(), new Parameters(), Collections.emptyList()); OperationRequest preprocessed = this.preprocessor.preprocess(request); assertThat(preprocessed.getHeaders().size()).isEqualTo(2); assertThat(preprocessed.getHeaders()).containsEntry("a", Arrays.asList("alpha")); - assertThat(preprocessed.getHeaders()).containsEntry("Host", - Arrays.asList("localhost")); + assertThat(preprocessed.getHeaders()).containsEntry("Host", Arrays.asList("localhost")); } @Test @@ -78,8 +75,7 @@ public void modifyWithPattern() { OperationResponse preprocessed = processor.preprocess(response); assertThat(preprocessed.getHeaders().size()).isEqualTo(2); assertThat(preprocessed.getHeaders()).containsEntry("a", Arrays.asList("alpha")); - assertThat(preprocessed.getHeaders()).containsEntry("b", - Arrays.asList("bravo", "banana")); + assertThat(preprocessed.getHeaders()).containsEntry("b", Arrays.asList("bravo", "banana")); } @Test @@ -91,8 +87,7 @@ public void removeAllHeaders() { } private OperationResponse createResponse(String... extraHeaders) { - return this.responseFactory.create(HttpStatus.OK, getHttpHeaders(extraHeaders), - new byte[0]); + return this.responseFactory.create(HttpStatus.OK, getHttpHeaders(extraHeaders), new byte[0]); } private HttpHeaders getHttpHeaders(String... extraHeaders) { diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/operation/preprocess/LinkMaskingContentModifierTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/operation/preprocess/LinkMaskingContentModifierTests.java index 7c68b2773..952909643 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/operation/preprocess/LinkMaskingContentModifierTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/operation/preprocess/LinkMaskingContentModifierTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2017 the original author or authors. + * Copyright 2014-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. @@ -42,53 +42,46 @@ public class LinkMaskingContentModifierTests { private final ContentModifier contentModifier = new LinkMaskingContentModifier(); - private final Link[] links = new Link[] { new Link("a", "alpha"), - new Link("b", "bravo") }; + private final Link[] links = new Link[] { new Link("a", "alpha"), new Link("b", "bravo") }; - private final Link[] maskedLinks = new Link[] { new Link("a", "..."), - new Link("b", "...") }; + private final Link[] maskedLinks = new Link[] { new Link("a", "..."), new Link("b", "...") }; @Test public void halLinksAreMasked() throws Exception { - assertThat( - this.contentModifier.modifyContent(halPayloadWithLinks(this.links), null)) - .isEqualTo(halPayloadWithLinks(this.maskedLinks)); + assertThat(this.contentModifier.modifyContent(halPayloadWithLinks(this.links), null)) + .isEqualTo(halPayloadWithLinks(this.maskedLinks)); } @Test public void formattedHalLinksAreMasked() throws Exception { - assertThat(this.contentModifier - .modifyContent(formattedHalPayloadWithLinks(this.links), null)) - .isEqualTo(formattedHalPayloadWithLinks(this.maskedLinks)); + assertThat(this.contentModifier.modifyContent(formattedHalPayloadWithLinks(this.links), null)) + .isEqualTo(formattedHalPayloadWithLinks(this.maskedLinks)); } @Test public void atomLinksAreMasked() throws Exception { - assertThat(this.contentModifier.modifyContent(atomPayloadWithLinks(this.links), - null)).isEqualTo(atomPayloadWithLinks(this.maskedLinks)); + assertThat(this.contentModifier.modifyContent(atomPayloadWithLinks(this.links), null)) + .isEqualTo(atomPayloadWithLinks(this.maskedLinks)); } @Test public void formattedAtomLinksAreMasked() throws Exception { - assertThat(this.contentModifier - .modifyContent(formattedAtomPayloadWithLinks(this.links), null)) - .isEqualTo(formattedAtomPayloadWithLinks(this.maskedLinks)); + assertThat(this.contentModifier.modifyContent(formattedAtomPayloadWithLinks(this.links), null)) + .isEqualTo(formattedAtomPayloadWithLinks(this.maskedLinks)); } @Test public void maskCanBeCustomized() throws Exception { - assertThat(new LinkMaskingContentModifier("custom") - .modifyContent(formattedAtomPayloadWithLinks(this.links), null)) - .isEqualTo(formattedAtomPayloadWithLinks(new Link("a", "custom"), - new Link("b", "custom"))); + assertThat( + new LinkMaskingContentModifier("custom").modifyContent(formattedAtomPayloadWithLinks(this.links), null)) + .isEqualTo(formattedAtomPayloadWithLinks(new Link("a", "custom"), new Link("b", "custom"))); } private byte[] atomPayloadWithLinks(Link... links) throws JsonProcessingException { return new ObjectMapper().writeValueAsBytes(createAtomPayload(links)); } - private byte[] formattedAtomPayloadWithLinks(Link... links) - throws JsonProcessingException { + private byte[] formattedAtomPayloadWithLinks(Link... links) throws JsonProcessingException { return new ObjectMapper().configure(SerializationFeature.INDENT_OUTPUT, true) .writeValueAsBytes(createAtomPayload(links)); } @@ -103,8 +96,7 @@ private byte[] halPayloadWithLinks(Link... links) throws JsonProcessingException return new ObjectMapper().writeValueAsBytes(createHalPayload(links)); } - private byte[] formattedHalPayloadWithLinks(Link... links) - throws JsonProcessingException { + private byte[] formattedHalPayloadWithLinks(Link... links) throws JsonProcessingException { return new ObjectMapper().configure(SerializationFeature.INDENT_OUTPUT, true) .writeValueAsBytes(createHalPayload(links)); } @@ -121,11 +113,10 @@ private HalPayload createHalPayload(Link... links) { return payload; } - private static final class AtomPayload { + public static final class AtomPayload { private List links; - @SuppressWarnings("unused") public List getLinks() { return this.links; } @@ -136,7 +127,7 @@ public void setLinks(List links) { } - private static final class HalPayload { + public static final class HalPayload { private Map links; diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/operation/preprocess/ParametersModifyingOperationPreprocessorTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/operation/preprocess/ParametersModifyingOperationPreprocessorTests.java index 1b7fccb73..5f6dc268f 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/operation/preprocess/ParametersModifyingOperationPreprocessorTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/operation/preprocess/ParametersModifyingOperationPreprocessorTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-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. @@ -43,59 +43,53 @@ public class ParametersModifyingOperationPreprocessorTests { @Test public void addNewParameter() { Parameters parameters = new Parameters(); - assertThat(this.preprocessor.add("a", "alpha") - .preprocess(createRequest(parameters)).getParameters()).containsEntry("a", - Arrays.asList("alpha")); + assertThat(this.preprocessor.add("a", "alpha").preprocess(createRequest(parameters)).getParameters()) + .containsEntry("a", Arrays.asList("alpha")); } @Test public void addValueToExistingParameter() { Parameters parameters = new Parameters(); parameters.add("a", "apple"); - assertThat(this.preprocessor.add("a", "alpha") - .preprocess(createRequest(parameters)).getParameters()).containsEntry("a", - Arrays.asList("apple", "alpha")); + assertThat(this.preprocessor.add("a", "alpha").preprocess(createRequest(parameters)).getParameters()) + .containsEntry("a", Arrays.asList("apple", "alpha")); } @Test public void setNewParameter() { Parameters parameters = new Parameters(); - assertThat(this.preprocessor.set("a", "alpha", "avocado") - .preprocess(createRequest(parameters)).getParameters()).containsEntry("a", - Arrays.asList("alpha", "avocado")); + assertThat(this.preprocessor.set("a", "alpha", "avocado").preprocess(createRequest(parameters)).getParameters()) + .containsEntry("a", Arrays.asList("alpha", "avocado")); } @Test public void setExistingParameter() { Parameters parameters = new Parameters(); parameters.add("a", "apple"); - assertThat(this.preprocessor.set("a", "alpha", "avocado") - .preprocess(createRequest(parameters)).getParameters()).containsEntry("a", - Arrays.asList("alpha", "avocado")); + assertThat(this.preprocessor.set("a", "alpha", "avocado").preprocess(createRequest(parameters)).getParameters()) + .containsEntry("a", Arrays.asList("alpha", "avocado")); } @Test public void removeNonExistentParameter() { Parameters parameters = new Parameters(); - assertThat(this.preprocessor.remove("a").preprocess(createRequest(parameters)) - .getParameters().size()).isEqualTo(0); + assertThat(this.preprocessor.remove("a").preprocess(createRequest(parameters)).getParameters().size()) + .isEqualTo(0); } @Test public void removeParameter() { Parameters parameters = new Parameters(); parameters.add("a", "apple"); - assertThat(this.preprocessor.set("a", "alpha", "avocado") - .preprocess(createRequest(parameters)).getParameters()).containsEntry("a", - Arrays.asList("alpha", "avocado")); + assertThat(this.preprocessor.set("a", "alpha", "avocado").preprocess(createRequest(parameters)).getParameters()) + .containsEntry("a", Arrays.asList("alpha", "avocado")); } @Test public void removeParameterValueForNonExistentParameter() { Parameters parameters = new Parameters(); - assertThat(this.preprocessor.remove("a", "apple") - .preprocess(createRequest(parameters)).getParameters().size()) - .isEqualTo(0); + assertThat(this.preprocessor.remove("a", "apple").preprocess(createRequest(parameters)).getParameters().size()) + .isEqualTo(0); } @Test @@ -103,24 +97,21 @@ public void removeParameterValueWithMultipleValues() { Parameters parameters = new Parameters(); parameters.add("a", "apple"); parameters.add("a", "alpha"); - assertThat(this.preprocessor.remove("a", "apple") - .preprocess(createRequest(parameters)).getParameters()).containsEntry("a", - Arrays.asList("alpha")); + assertThat(this.preprocessor.remove("a", "apple").preprocess(createRequest(parameters)).getParameters()) + .containsEntry("a", Arrays.asList("alpha")); } @Test public void removeParameterValueWithSingleValueRemovesEntryEntirely() { Parameters parameters = new Parameters(); parameters.add("a", "apple"); - assertThat(this.preprocessor.remove("a", "apple") - .preprocess(createRequest(parameters)).getParameters().size()) - .isEqualTo(0); + assertThat(this.preprocessor.remove("a", "apple").preprocess(createRequest(parameters)).getParameters().size()) + .isEqualTo(0); } private OperationRequest createRequest(Parameters parameters) { - return new OperationRequestFactory().create(URI.create("http://localhost:8080"), - HttpMethod.GET, new byte[0], new HttpHeaders(), parameters, - Collections.emptyList()); + return new OperationRequestFactory().create(URI.create("http://localhost:8080"), HttpMethod.GET, new byte[0], + new HttpHeaders(), parameters, Collections.emptyList()); } } diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/operation/preprocess/PatternReplacingContentModifierTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/operation/preprocess/PatternReplacingContentModifierTests.java index 9a6a762ac..54d9909e3 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/operation/preprocess/PatternReplacingContentModifierTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/operation/preprocess/PatternReplacingContentModifierTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-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. @@ -34,34 +34,28 @@ public class PatternReplacingContentModifierTests { @Test public void patternsAreReplaced() throws Exception { - Pattern pattern = Pattern.compile( - "[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}", + Pattern pattern = Pattern.compile("[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}", Pattern.CASE_INSENSITIVE); - PatternReplacingContentModifier contentModifier = new PatternReplacingContentModifier( - pattern, "<>"); - assertThat(contentModifier.modifyContent( - "{\"id\" : \"CA761232-ED42-11CE-BACD-00AA0057B223\"}".getBytes(), null)) + PatternReplacingContentModifier contentModifier = new PatternReplacingContentModifier(pattern, "<>"); + assertThat( + contentModifier.modifyContent("{\"id\" : \"CA761232-ED42-11CE-BACD-00AA0057B223\"}".getBytes(), null)) .isEqualTo("{\"id\" : \"<>\"}".getBytes()); } @Test public void contentThatDoesNotMatchIsUnchanged() throws Exception { - Pattern pattern = Pattern.compile( - "[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}", + Pattern pattern = Pattern.compile("[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}", Pattern.CASE_INSENSITIVE); - PatternReplacingContentModifier contentModifier = new PatternReplacingContentModifier( - pattern, "<>"); - assertThat(contentModifier - .modifyContent("{\"id\" : \"CA76-ED42-11CE-BACD\"}".getBytes(), null)) - .isEqualTo("{\"id\" : \"CA76-ED42-11CE-BACD\"}".getBytes()); + PatternReplacingContentModifier contentModifier = new PatternReplacingContentModifier(pattern, "<>"); + assertThat(contentModifier.modifyContent("{\"id\" : \"CA76-ED42-11CE-BACD\"}".getBytes(), null)) + .isEqualTo("{\"id\" : \"CA76-ED42-11CE-BACD\"}".getBytes()); } @Test public void encodingIsPreserved() { String japaneseContent = "\u30b3\u30f3\u30c6\u30f3\u30c4"; Pattern pattern = Pattern.compile("[0-9]+"); - PatternReplacingContentModifier contentModifier = new PatternReplacingContentModifier( - pattern, "<>"); + PatternReplacingContentModifier contentModifier = new PatternReplacingContentModifier(pattern, "<>"); assertThat(contentModifier.modifyContent((japaneseContent + " 123").getBytes(), new MediaType("text", "plain", Charset.forName("UTF-8")))) .isEqualTo((japaneseContent + " <>").getBytes()); diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/operation/preprocess/PrettyPrintingContentModifierTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/operation/preprocess/PrettyPrintingContentModifierTests.java index 15416f22e..d5a7d4847 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/operation/preprocess/PrettyPrintingContentModifierTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/operation/preprocess/PrettyPrintingContentModifierTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-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. @@ -41,32 +41,29 @@ public class PrettyPrintingContentModifierTests { @Test public void prettyPrintJson() throws Exception { - assertThat(new PrettyPrintingContentModifier() - .modifyContent("{\"a\":5}".getBytes(), null)) - .isEqualTo(String.format("{%n \"a\" : 5%n}").getBytes()); + assertThat(new PrettyPrintingContentModifier().modifyContent("{\"a\":5}".getBytes(), null)) + .isEqualTo(String.format("{%n \"a\" : 5%n}").getBytes()); } @Test public void prettyPrintXml() throws Exception { - assertThat(new PrettyPrintingContentModifier().modifyContent( - "".getBytes(), null)).isEqualTo( - String.format("%n" - + "%n %n%n") - .getBytes()); + assertThat(new PrettyPrintingContentModifier() + .modifyContent("".getBytes(), null)) + .isEqualTo(String.format("%n" + + "%n %n%n").getBytes()); } @Test public void empytContentIsHandledGracefully() throws Exception { - assertThat(new PrettyPrintingContentModifier().modifyContent("".getBytes(), null)) - .isEqualTo("".getBytes()); + assertThat(new PrettyPrintingContentModifier().modifyContent("".getBytes(), null)).isEqualTo("".getBytes()); } @Test public void nonJsonAndNonXmlContentIsHandledGracefully() throws Exception { String content = "abcdefg"; this.outputCapture.expect(isEmptyString()); - assertThat(new PrettyPrintingContentModifier().modifyContent(content.getBytes(), - null)).isEqualTo(content.getBytes()); + assertThat(new PrettyPrintingContentModifier().modifyContent(content.getBytes(), null)) + .isEqualTo(content.getBytes()); } @@ -76,9 +73,9 @@ public void encodingIsPreserved() throws Exception { input.put("japanese", "\u30b3\u30f3\u30c6\u30f3\u30c4"); ObjectMapper objectMapper = new ObjectMapper(); @SuppressWarnings("unchecked") - Map output = objectMapper - .readValue(new PrettyPrintingContentModifier().modifyContent( - objectMapper.writeValueAsBytes(input), null), Map.class); + Map output = objectMapper.readValue( + new PrettyPrintingContentModifier().modifyContent(objectMapper.writeValueAsBytes(input), null), + Map.class); assertThat(output).isEqualTo(input); } diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/AsciidoctorRequestFieldsSnippetTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/AsciidoctorRequestFieldsSnippetTests.java index e8ba448c6..08db8b3b0 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/AsciidoctorRequestFieldsSnippetTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/AsciidoctorRequestFieldsSnippetTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-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. @@ -44,40 +44,27 @@ public class AsciidoctorRequestFieldsSnippetTests { @Rule - public OperationBuilder operationBuilder = new OperationBuilder( - TemplateFormats.asciidoctor()); + public OperationBuilder operationBuilder = new OperationBuilder(TemplateFormats.asciidoctor()); @Rule - public GeneratedSnippets generatedSnippets = new GeneratedSnippets( - TemplateFormats.asciidoctor()); + public GeneratedSnippets generatedSnippets = new GeneratedSnippets(TemplateFormats.asciidoctor()); @Test public void requestFieldsWithListDescription() throws IOException { TemplateResourceResolver resolver = mock(TemplateResourceResolver.class); given(resolver.resolveTemplateResource("request-fields")) .willReturn(snippetResource("request-fields-with-list-description")); - new RequestFieldsSnippet( - Arrays.asList( - fieldWithPath("a").description(Arrays.asList("one", "two")))) - .document( - this.operationBuilder - .attribute(TemplateEngine.class.getName(), - new MustacheTemplateEngine( - resolver)) - .request("http://localhost") - .content("{\"a\": \"foo\"}").build()); - assertThat(this.generatedSnippets.requestFields()).is(SnippetConditions - .tableWithHeader(TemplateFormats.asciidoctor(), "Path", "Type", - "Description") - // - .row("a", "String", String.format(" - one%n - two")) - .configuration("[cols=\"1,1,1a\"]")); + new RequestFieldsSnippet(Arrays.asList(fieldWithPath("a").description(Arrays.asList("one", "two")))).document( + this.operationBuilder.attribute(TemplateEngine.class.getName(), new MustacheTemplateEngine(resolver)) + .request("http://localhost").content("{\"a\": \"foo\"}").build()); + assertThat(this.generatedSnippets.requestFields()) + .is(SnippetConditions.tableWithHeader(TemplateFormats.asciidoctor(), "Path", "Type", "Description") + // + .row("a", "String", String.format(" - one%n - two")).configuration("[cols=\"1,1,1a\"]")); } private FileSystemResource snippetResource(String name) { - return new FileSystemResource( - "src/test/resources/custom-snippet-templates/asciidoctor/" + name - + ".snippet"); + return new FileSystemResource("src/test/resources/custom-snippet-templates/asciidoctor/" + name + ".snippet"); } } diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/FieldPathPayloadSubsectionExtractorTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/FieldPathPayloadSubsectionExtractorTests.java index e579e3b86..9db464a3b 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/FieldPathPayloadSubsectionExtractorTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/FieldPathPayloadSubsectionExtractorTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-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. @@ -44,13 +44,10 @@ public class FieldPathPayloadSubsectionExtractorTests { @Test @SuppressWarnings("unchecked") - public void extractMapSubsectionOfJsonMap() - throws JsonParseException, JsonMappingException, IOException { + public void extractMapSubsectionOfJsonMap() throws JsonParseException, JsonMappingException, IOException { byte[] extractedPayload = new FieldPathPayloadSubsectionExtractor("a.b") - .extractSubsection("{\"a\":{\"b\":{\"c\":5}}}".getBytes(), - MediaType.APPLICATION_JSON); - Map extracted = new ObjectMapper().readValue(extractedPayload, - Map.class); + .extractSubsection("{\"a\":{\"b\":{\"c\":5}}}".getBytes(), MediaType.APPLICATION_JSON); + Map extracted = new ObjectMapper().readValue(extractedPayload, Map.class); assertThat(extracted.size()).isEqualTo(1); assertThat(extracted.get("c")).isEqualTo(5); } @@ -60,10 +57,8 @@ public void extractMapSubsectionOfJsonMap() public void extractSingleElementArraySubsectionOfJsonMap() throws JsonParseException, JsonMappingException, IOException { byte[] extractedPayload = new FieldPathPayloadSubsectionExtractor("a.[]") - .extractSubsection("{\"a\":[{\"b\":5}]}".getBytes(), - MediaType.APPLICATION_JSON); - Map extracted = new ObjectMapper().readValue(extractedPayload, - Map.class); + .extractSubsection("{\"a\":[{\"b\":5}]}".getBytes(), MediaType.APPLICATION_JSON); + Map extracted = new ObjectMapper().readValue(extractedPayload, Map.class); assertThat(extracted.size()).isEqualTo(1); assertThat(extracted).containsOnlyKeys("b"); } @@ -73,10 +68,8 @@ public void extractSingleElementArraySubsectionOfJsonMap() public void extractMultiElementArraySubsectionOfJsonMap() throws JsonParseException, JsonMappingException, IOException { byte[] extractedPayload = new FieldPathPayloadSubsectionExtractor("a") - .extractSubsection("{\"a\":[{\"b\":5},{\"b\":4}]}".getBytes(), - MediaType.APPLICATION_JSON); - Map extracted = new ObjectMapper().readValue(extractedPayload, - Map.class); + .extractSubsection("{\"a\":[{\"b\":5},{\"b\":4}]}".getBytes(), MediaType.APPLICATION_JSON); + Map extracted = new ObjectMapper().readValue(extractedPayload, Map.class); assertThat(extracted.size()).isEqualTo(1); assertThat(extracted).containsOnlyKeys("b"); } @@ -86,10 +79,8 @@ public void extractMultiElementArraySubsectionOfJsonMap() public void extractMapSubsectionFromSingleElementArrayInAJsonMap() throws JsonParseException, JsonMappingException, IOException { byte[] extractedPayload = new FieldPathPayloadSubsectionExtractor("a.[].b") - .extractSubsection("{\"a\":[{\"b\":{\"c\":5}}]}".getBytes(), - MediaType.APPLICATION_JSON); - Map extracted = new ObjectMapper().readValue(extractedPayload, - Map.class); + .extractSubsection("{\"a\":[{\"b\":{\"c\":5}}]}".getBytes(), MediaType.APPLICATION_JSON); + Map extracted = new ObjectMapper().readValue(extractedPayload, Map.class); assertThat(extracted.size()).isEqualTo(1); assertThat(extracted.get("c")).isEqualTo(5); } @@ -98,12 +89,9 @@ public void extractMapSubsectionFromSingleElementArrayInAJsonMap() @SuppressWarnings("unchecked") public void extractMapSubsectionWithCommonStructureFromMultiElementArrayInAJsonMap() throws JsonParseException, JsonMappingException, IOException { - byte[] extractedPayload = new FieldPathPayloadSubsectionExtractor("a.[].b") - .extractSubsection( - "{\"a\":[{\"b\":{\"c\":5}},{\"b\":{\"c\":6}}]}".getBytes(), - MediaType.APPLICATION_JSON); - Map extracted = new ObjectMapper().readValue(extractedPayload, - Map.class); + byte[] extractedPayload = new FieldPathPayloadSubsectionExtractor("a.[].b").extractSubsection( + "{\"a\":[{\"b\":{\"c\":5}},{\"b\":{\"c\":6}}]}".getBytes(), MediaType.APPLICATION_JSON); + Map extracted = new ObjectMapper().readValue(extractedPayload, Map.class); assertThat(extracted.size()).isEqualTo(1); assertThat(extracted).containsOnlyKeys("c"); } @@ -114,37 +102,31 @@ public void extractMapSubsectionWithVaryingStructureFromMultiElementArrayInAJson this.thrown.expect(PayloadHandlingException.class); this.thrown.expectMessage("The following uncommon paths were found: [a.[].b.d]"); new FieldPathPayloadSubsectionExtractor("a.[].b").extractSubsection( - "{\"a\":[{\"b\":{\"c\":5}},{\"b\":{\"c\":6, \"d\": 7}}]}".getBytes(), - MediaType.APPLICATION_JSON); + "{\"a\":[{\"b\":{\"c\":5}},{\"b\":{\"c\":6, \"d\": 7}}]}".getBytes(), MediaType.APPLICATION_JSON); } @Test public void extractedSubsectionIsPrettyPrintedWhenInputIsPrettyPrinted() - throws JsonParseException, JsonMappingException, JsonProcessingException, - IOException { - ObjectMapper objectMapper = new ObjectMapper() - .enable(SerializationFeature.INDENT_OUTPUT); - byte[] prettyPrintedPayload = objectMapper.writeValueAsBytes( - objectMapper.readValue("{\"a\": { \"b\": { \"c\": 1 }}}", Object.class)); + throws JsonParseException, JsonMappingException, JsonProcessingException, IOException { + ObjectMapper objectMapper = new ObjectMapper().enable(SerializationFeature.INDENT_OUTPUT); + byte[] prettyPrintedPayload = objectMapper + .writeValueAsBytes(objectMapper.readValue("{\"a\": { \"b\": { \"c\": 1 }}}", Object.class)); byte[] extractedSubsection = new FieldPathPayloadSubsectionExtractor("a.b") .extractSubsection(prettyPrintedPayload, MediaType.APPLICATION_JSON); byte[] prettyPrintedSubsection = objectMapper .writeValueAsBytes(objectMapper.readValue("{\"c\": 1 }", Object.class)); - assertThat(new String(extractedSubsection)) - .isEqualTo(new String(prettyPrintedSubsection)); + assertThat(new String(extractedSubsection)).isEqualTo(new String(prettyPrintedSubsection)); } @Test public void extractedSubsectionIsNotPrettyPrintedWhenInputIsNotPrettyPrinted() - throws JsonParseException, JsonMappingException, JsonProcessingException, - IOException { + throws JsonParseException, JsonMappingException, JsonProcessingException, IOException { ObjectMapper objectMapper = new ObjectMapper(); - byte[] payload = objectMapper.writeValueAsBytes( - objectMapper.readValue("{\"a\": { \"b\": { \"c\": 1 }}}", Object.class)); - byte[] extractedSubsection = new FieldPathPayloadSubsectionExtractor("a.b") - .extractSubsection(payload, MediaType.APPLICATION_JSON); - byte[] subsection = objectMapper - .writeValueAsBytes(objectMapper.readValue("{\"c\": 1 }", Object.class)); + byte[] payload = objectMapper + .writeValueAsBytes(objectMapper.readValue("{\"a\": { \"b\": { \"c\": 1 }}}", Object.class)); + byte[] extractedSubsection = new FieldPathPayloadSubsectionExtractor("a.b").extractSubsection(payload, + MediaType.APPLICATION_JSON); + byte[] subsection = objectMapper.writeValueAsBytes(objectMapper.readValue("{\"c\": 1 }", Object.class)); assertThat(new String(extractedSubsection)).isEqualTo(new String(subsection)); } diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/JsonContentHandlerTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/JsonContentHandlerTests.java index 6924bfd49..10af29d39 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/JsonContentHandlerTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/JsonContentHandlerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-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. @@ -46,55 +46,48 @@ public void typeForFieldWithNullValueMustMatch() { public void typeForFieldWithNotNullAndThenNullValueMustMatch() { this.thrown.expect(FieldTypesDoNotMatchException.class); new JsonContentHandler("{\"a\":[{\"id\":1},{\"id\":null}]}".getBytes()) - .determineFieldType( - new FieldDescriptor("a[].id").type(JsonFieldType.STRING)); + .determineFieldType(new FieldDescriptor("a[].id").type(JsonFieldType.STRING)); } @Test public void typeForFieldWithNullAndThenNotNullValueMustMatch() { this.thrown.expect(FieldTypesDoNotMatchException.class); new JsonContentHandler("{\"a\":[{\"id\":null},{\"id\":1}]}".getBytes()) - .determineFieldType( - new FieldDescriptor("a.[].id").type(JsonFieldType.STRING)); + .determineFieldType(new FieldDescriptor("a.[].id").type(JsonFieldType.STRING)); } @Test public void typeForOptionalFieldWithNumberAndThenNullValueIsNumber() { - Object fieldType = new JsonContentHandler( - "{\"a\":[{\"id\":1},{\"id\":null}]}\"".getBytes()) - .determineFieldType(new FieldDescriptor("a[].id").optional()); + Object fieldType = new JsonContentHandler("{\"a\":[{\"id\":1},{\"id\":null}]}\"".getBytes()) + .determineFieldType(new FieldDescriptor("a[].id").optional()); assertThat((JsonFieldType) fieldType).isEqualTo(JsonFieldType.NUMBER); } @Test public void typeForOptionalFieldWithNullAndThenNumberIsNumber() { - Object fieldType = new JsonContentHandler( - "{\"a\":[{\"id\":null},{\"id\":1}]}".getBytes()) - .determineFieldType(new FieldDescriptor("a[].id").optional()); + Object fieldType = new JsonContentHandler("{\"a\":[{\"id\":null},{\"id\":1}]}".getBytes()) + .determineFieldType(new FieldDescriptor("a[].id").optional()); assertThat((JsonFieldType) fieldType).isEqualTo(JsonFieldType.NUMBER); } @Test public void typeForFieldWithNumberAndThenNullValueIsVaries() { - Object fieldType = new JsonContentHandler( - "{\"a\":[{\"id\":1},{\"id\":null}]}\"".getBytes()) - .determineFieldType(new FieldDescriptor("a[].id")); + Object fieldType = new JsonContentHandler("{\"a\":[{\"id\":1},{\"id\":null}]}\"".getBytes()) + .determineFieldType(new FieldDescriptor("a[].id")); assertThat((JsonFieldType) fieldType).isEqualTo(JsonFieldType.VARIES); } @Test public void typeForFieldWithNullAndThenNumberIsVaries() { - Object fieldType = new JsonContentHandler( - "{\"a\":[{\"id\":null},{\"id\":1}]}".getBytes()) - .determineFieldType(new FieldDescriptor("a[].id")); + Object fieldType = new JsonContentHandler("{\"a\":[{\"id\":null},{\"id\":1}]}".getBytes()) + .determineFieldType(new FieldDescriptor("a[].id")); assertThat((JsonFieldType) fieldType).isEqualTo(JsonFieldType.VARIES); } @Test public void typeForOptionalFieldWithNullValueCanBeProvidedExplicitly() { Object fieldType = new JsonContentHandler("{\"a\": null}".getBytes()) - .determineFieldType( - new FieldDescriptor("a").type(JsonFieldType.STRING).optional()); + .determineFieldType(new FieldDescriptor("a").type(JsonFieldType.STRING).optional()); assertThat((JsonFieldType) fieldType).isEqualTo(JsonFieldType.STRING); } @@ -106,89 +99,76 @@ public void failsFastWithNonJsonContent() { @Test public void describedFieldThatIsNotPresentIsConsideredMissing() { - List missingFields = new JsonContentHandler( - "{\"a\": \"alpha\", \"b\":\"bravo\"}".getBytes()) - .findMissingFields(Arrays.asList(new FieldDescriptor("a"), - new FieldDescriptor("b"), new FieldDescriptor("c"))); + List missingFields = new JsonContentHandler("{\"a\": \"alpha\", \"b\":\"bravo\"}".getBytes()) + .findMissingFields( + Arrays.asList(new FieldDescriptor("a"), new FieldDescriptor("b"), new FieldDescriptor("c"))); assertThat(missingFields.size()).isEqualTo(1); assertThat(missingFields.get(0).getPath()).isEqualTo("c"); } @Test public void describedOptionalFieldThatIsNotPresentIsNotConsideredMissing() { - List missingFields = new JsonContentHandler( - "{\"a\": \"alpha\", \"b\":\"bravo\"}".getBytes()).findMissingFields( - Arrays.asList(new FieldDescriptor("a"), new FieldDescriptor("b"), - new FieldDescriptor("c").optional())); + List missingFields = new JsonContentHandler("{\"a\": \"alpha\", \"b\":\"bravo\"}".getBytes()) + .findMissingFields(Arrays.asList(new FieldDescriptor("a"), new FieldDescriptor("b"), + new FieldDescriptor("c").optional())); assertThat(missingFields.size()).isEqualTo(0); } @Test public void describedFieldThatIsNotPresentNestedBeneathOptionalFieldThatIsPresentIsConsideredMissing() { - List missingFields = new JsonContentHandler( - "{\"a\":\"alpha\",\"b\":\"bravo\"}".getBytes()).findMissingFields( - Arrays.asList(new FieldDescriptor("a").optional(), - new FieldDescriptor("b"), new FieldDescriptor("a.c"))); + List missingFields = new JsonContentHandler("{\"a\":\"alpha\",\"b\":\"bravo\"}".getBytes()) + .findMissingFields(Arrays.asList(new FieldDescriptor("a").optional(), new FieldDescriptor("b"), + new FieldDescriptor("a.c"))); assertThat(missingFields.size()).isEqualTo(1); assertThat(missingFields.get(0).getPath()).isEqualTo("a.c"); } @Test public void describedFieldThatIsNotPresentNestedBeneathOptionalFieldThatIsNotPresentIsNotConsideredMissing() { - List missingFields = new JsonContentHandler( - "{\"b\":\"bravo\"}".getBytes()).findMissingFields( - Arrays.asList(new FieldDescriptor("a").optional(), - new FieldDescriptor("b"), new FieldDescriptor("a.c"))); + List missingFields = new JsonContentHandler("{\"b\":\"bravo\"}".getBytes()) + .findMissingFields(Arrays.asList(new FieldDescriptor("a").optional(), new FieldDescriptor("b"), + new FieldDescriptor("a.c"))); assertThat(missingFields.size()).isEqualTo(0); } @Test public void describedFieldThatIsNotPresentNestedBeneathOptionalArrayThatIsEmptyIsNotConsideredMissing() { - List missingFields = new JsonContentHandler( - "{\"outer\":[]}".getBytes()) - .findMissingFields(Arrays.asList(new FieldDescriptor("outer"), - new FieldDescriptor("outer[]").optional(), - new FieldDescriptor("outer[].inner"))); + List missingFields = new JsonContentHandler("{\"outer\":[]}".getBytes()) + .findMissingFields(Arrays.asList(new FieldDescriptor("outer"), + new FieldDescriptor("outer[]").optional(), new FieldDescriptor("outer[].inner"))); assertThat(missingFields.size()).isEqualTo(0); } @Test public void describedSometimesPresentFieldThatIsChildOfSometimesPresentOptionalArrayIsNotConsideredMissing() { List missingFields = new JsonContentHandler( - "{\"a\":[ {\"b\": \"bravo\"}, {\"b\": \"bravo\", \"c\": { \"d\": \"delta\"}}]}" - .getBytes()).findMissingFields( - Arrays.asList(new FieldDescriptor("a.[].c").optional(), - new FieldDescriptor("a.[].c.d"))); + "{\"a\":[ {\"b\": \"bravo\"}, {\"b\": \"bravo\", \"c\": { \"d\": \"delta\"}}]}".getBytes()) + .findMissingFields(Arrays.asList(new FieldDescriptor("a.[].c").optional(), + new FieldDescriptor("a.[].c.d"))); assertThat(missingFields.size()).isEqualTo(0); } @Test public void describedMissingFieldThatIsChildOfNestedOptionalArrayThatIsEmptyIsNotConsideredMissing() { - List missingFields = new JsonContentHandler( - "{\"a\":[{\"b\":[]}]}".getBytes()).findMissingFields( - Arrays.asList(new FieldDescriptor("a.[].b").optional(), - new FieldDescriptor("a.[].b.[]").optional(), - new FieldDescriptor("a.[].b.[].c"))); + List missingFields = new JsonContentHandler("{\"a\":[{\"b\":[]}]}".getBytes()) + .findMissingFields(Arrays.asList(new FieldDescriptor("a.[].b").optional(), + new FieldDescriptor("a.[].b.[]").optional(), new FieldDescriptor("a.[].b.[].c"))); assertThat(missingFields.size()).isEqualTo(0); } @Test public void describedMissingFieldThatIsChildOfNestedOptionalArrayThatContainsAnObjectIsConsideredMissing() { - List missingFields = new JsonContentHandler( - "{\"a\":[{\"b\":[{}]}]}".getBytes()).findMissingFields( - Arrays.asList(new FieldDescriptor("a.[].b").optional(), - new FieldDescriptor("a.[].b.[]").optional(), - new FieldDescriptor("a.[].b.[].c"))); + List missingFields = new JsonContentHandler("{\"a\":[{\"b\":[{}]}]}".getBytes()) + .findMissingFields(Arrays.asList(new FieldDescriptor("a.[].b").optional(), + new FieldDescriptor("a.[].b.[]").optional(), new FieldDescriptor("a.[].b.[].c"))); assertThat(missingFields.size()).isEqualTo(1); assertThat(missingFields.get(0).getPath()).isEqualTo("a.[].b.[].c"); } @Test public void describedMissingFieldThatIsChildOfOptionalObjectThatIsNullIsNotConsideredMissing() { - List missingFields = new JsonContentHandler( - "{\"a\":null}".getBytes()).findMissingFields( - Arrays.asList(new FieldDescriptor("a").optional(), - new FieldDescriptor("a.b"))); + List missingFields = new JsonContentHandler("{\"a\":null}".getBytes()) + .findMissingFields(Arrays.asList(new FieldDescriptor("a").optional(), new FieldDescriptor("a.b"))); assertThat(missingFields.size()).isEqualTo(0); } diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/JsonFieldPathTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/JsonFieldPathTests.java index c8c70a76e..b350235dd 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/JsonFieldPathTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/JsonFieldPathTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-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. @@ -103,68 +103,57 @@ public void compilationOfSingleElementPath() { @Test public void compilationOfMultipleElementPath() { - assertThat(JsonFieldPath.compile("a.b.c").getSegments()).containsExactly("a", "b", - "c"); + assertThat(JsonFieldPath.compile("a.b.c").getSegments()).containsExactly("a", "b", "c"); } @Test public void compilationOfPathWithArraysWithNoDotSeparators() { - assertThat(JsonFieldPath.compile("a[]b[]c").getSegments()).containsExactly("a", - "[]", "b", "[]", "c"); + assertThat(JsonFieldPath.compile("a[]b[]c").getSegments()).containsExactly("a", "[]", "b", "[]", "c"); } @Test public void compilationOfPathWithArraysWithPreAndPostDotSeparators() { - assertThat(JsonFieldPath.compile("a.[].b.[].c").getSegments()) - .containsExactly("a", "[]", "b", "[]", "c"); + assertThat(JsonFieldPath.compile("a.[].b.[].c").getSegments()).containsExactly("a", "[]", "b", "[]", "c"); } @Test public void compilationOfPathWithArraysWithPreDotSeparators() { - assertThat(JsonFieldPath.compile("a.[]b.[]c").getSegments()).containsExactly("a", - "[]", "b", "[]", "c"); + assertThat(JsonFieldPath.compile("a.[]b.[]c").getSegments()).containsExactly("a", "[]", "b", "[]", "c"); } @Test public void compilationOfPathWithArraysWithPostDotSeparators() { - assertThat(JsonFieldPath.compile("a[].b[].c").getSegments()).containsExactly("a", - "[]", "b", "[]", "c"); + assertThat(JsonFieldPath.compile("a[].b[].c").getSegments()).containsExactly("a", "[]", "b", "[]", "c"); } @Test public void compilationOfPathStartingWithAnArray() { - assertThat(JsonFieldPath.compile("[]a.b.c").getSegments()).containsExactly("[]", - "a", "b", "c"); + assertThat(JsonFieldPath.compile("[]a.b.c").getSegments()).containsExactly("[]", "a", "b", "c"); } @Test public void compilationOfMultipleElementPathWithBrackets() { - assertThat(JsonFieldPath.compile("['a']['b']['c']").getSegments()) - .containsExactly("a", "b", "c"); + assertThat(JsonFieldPath.compile("['a']['b']['c']").getSegments()).containsExactly("a", "b", "c"); } @Test public void compilationOfMultipleElementPathWithAndWithoutBrackets() { - assertThat(JsonFieldPath.compile("['a'][].b['c']").getSegments()) - .containsExactly("a", "[]", "b", "c"); + assertThat(JsonFieldPath.compile("['a'][].b['c']").getSegments()).containsExactly("a", "[]", "b", "c"); } @Test public void compilationOfMultipleElementPathWithAndWithoutBracketsAndEmbeddedDots() { - assertThat(JsonFieldPath.compile("['a.key'][].b['c']").getSegments()) - .containsExactly("a.key", "[]", "b", "c"); + assertThat(JsonFieldPath.compile("['a.key'][].b['c']").getSegments()).containsExactly("a.key", "[]", "b", "c"); } @Test public void compilationOfPathWithAWildcard() { - assertThat(JsonFieldPath.compile("a.b.*.c").getSegments()).containsExactly("a", - "b", "*", "c"); + assertThat(JsonFieldPath.compile("a.b.*.c").getSegments()).containsExactly("a", "b", "*", "c"); } @Test public void compilationOfPathWithAWildcardInBrackets() { - assertThat(JsonFieldPath.compile("a.b.['*'].c").getSegments()) - .containsExactly("a", "b", "*", "c"); + assertThat(JsonFieldPath.compile("a.b.['*'].c").getSegments()).containsExactly("a", "b", "*", "c"); } } diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/JsonFieldPathsTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/JsonFieldPathsTests.java index 7fefc8205..3558a61c2 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/JsonFieldPathsTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/JsonFieldPathsTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-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. @@ -33,33 +33,27 @@ public class JsonFieldPathsTests { @Test public void noUncommonPathsForSingleItem() { - assertThat(JsonFieldPaths - .from(Arrays - .asList(json("{\"a\": 1, \"b\": [ { \"c\": 2}, {\"c\": 3} ]}"))) + assertThat(JsonFieldPaths.from(Arrays.asList(json("{\"a\": 1, \"b\": [ { \"c\": 2}, {\"c\": 3} ]}"))) .getUncommon()).isEmpty(); } @Test public void noUncommonPathsForMultipleIdenticalItems() { Object item = json("{\"a\": 1, \"b\": [ { \"c\": 2}, {\"c\": 3} ]}"); - assertThat(JsonFieldPaths.from(Arrays.asList(item, item)).getUncommon()) - .isEmpty(); + assertThat(JsonFieldPaths.from(Arrays.asList(item, item)).getUncommon()).isEmpty(); } @Test public void noUncommonPathsForMultipleMatchingItemsWithDifferentScalarValues() { - assertThat(JsonFieldPaths - .from(Arrays.asList( - json("{\"a\": 1, \"b\": [ { \"c\": 2}, {\"c\": 3} ]}"), - json("{\"a\": 4, \"b\": [ { \"c\": 5}, {\"c\": 6} ]}"))) - .getUncommon()).isEmpty(); + assertThat(JsonFieldPaths.from(Arrays.asList(json("{\"a\": 1, \"b\": [ { \"c\": 2}, {\"c\": 3} ]}"), + json("{\"a\": 4, \"b\": [ { \"c\": 5}, {\"c\": 6} ]}"))).getUncommon()).isEmpty(); } @Test public void missingEntryInMapIsIdentifiedAsUncommon() { - assertThat(JsonFieldPaths.from(Arrays.asList(json("{\"a\": 1}"), - json("{\"a\": 1}"), json("{\"a\": 1, \"b\": 2}"))).getUncommon()) - .containsExactly("b"); + assertThat( + JsonFieldPaths.from(Arrays.asList(json("{\"a\": 1}"), json("{\"a\": 1}"), json("{\"a\": 1, \"b\": 2}"))) + .getUncommon()).containsExactly("b"); } @Test @@ -67,32 +61,30 @@ public void missingEntryInNestedMapIsIdentifiedAsUncommon() { assertThat( JsonFieldPaths .from(Arrays.asList(json("{\"a\": 1, \"b\": {\"c\": 1}}"), - json("{\"a\": 1, \"b\": {\"c\": 1}}"), - json("{\"a\": 1, \"b\": {\"c\": 1, \"d\": 2}}"))) + json("{\"a\": 1, \"b\": {\"c\": 1}}"), json("{\"a\": 1, \"b\": {\"c\": 1, \"d\": 2}}"))) .getUncommon()).containsExactly("b.d"); } @Test public void missingEntriesInNestedMapAreIdentifiedAsUncommon() { assertThat( - JsonFieldPaths.from(Arrays.asList(json("{\"a\": 1, \"b\": {\"c\": 1}}"), - json("{\"a\": 1, \"b\": {\"c\": 1}}"), - json("{\"a\": 1, \"b\": {\"d\": 2}}"))).getUncommon()) - .containsExactly("b.c", "b.d"); + JsonFieldPaths + .from(Arrays.asList(json("{\"a\": 1, \"b\": {\"c\": 1}}"), + json("{\"a\": 1, \"b\": {\"c\": 1}}"), json("{\"a\": 1, \"b\": {\"d\": 2}}"))) + .getUncommon()).containsExactly("b.c", "b.d"); } @Test public void missingEntryBeneathArrayIsIdentifiedAsUncommon() { - assertThat(JsonFieldPaths.from(Arrays.asList(json("[{\"b\": 1}]"), - json("[{\"b\": 1}]"), json("[{\"b\": 1, \"c\": 2}]"))).getUncommon()) - .containsExactly("[].c"); + assertThat(JsonFieldPaths + .from(Arrays.asList(json("[{\"b\": 1}]"), json("[{\"b\": 1}]"), json("[{\"b\": 1, \"c\": 2}]"))) + .getUncommon()).containsExactly("[].c"); } @Test public void missingEntryBeneathNestedArrayIsIdentifiedAsUncommon() { - assertThat(JsonFieldPaths.from(Arrays.asList(json("{\"a\": [{\"b\": 1}]}"), - json("{\"a\": [{\"b\": 1}]}"), json("{\"a\": [{\"b\": 1, \"c\": 2}]}"))) - .getUncommon()).containsExactly("a.[].c"); + assertThat(JsonFieldPaths.from(Arrays.asList(json("{\"a\": [{\"b\": 1}]}"), json("{\"a\": [{\"b\": 1}]}"), + json("{\"a\": [{\"b\": 1, \"c\": 2}]}"))).getUncommon()).containsExactly("a.[].c"); } private Object json(String json) { diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/JsonFieldProcessorTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/JsonFieldProcessorTests.java index 48d146615..d5ba9ad38 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/JsonFieldProcessorTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/JsonFieldProcessorTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-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. @@ -43,8 +43,7 @@ public class JsonFieldProcessorTests { public void extractTopLevelMapEntry() { Map payload = new HashMap<>(); payload.put("a", "alpha"); - assertThat(this.fieldProcessor.extract("a", payload).getValue()) - .isEqualTo("alpha"); + assertThat(this.fieldProcessor.extract("a", payload).getValue()).isEqualTo("alpha"); } @Test @@ -53,8 +52,7 @@ public void extractNestedMapEntry() { Map alpha = new HashMap<>(); payload.put("a", alpha); alpha.put("b", "bravo"); - assertThat(this.fieldProcessor.extract("a.b", payload).getValue()) - .isEqualTo("bravo"); + assertThat(this.fieldProcessor.extract("a.b", payload).getValue()).isEqualTo("bravo"); } @Test @@ -64,8 +62,7 @@ public void extractTopLevelArray() { bravo.put("b", "bravo"); payload.add(bravo); payload.add(bravo); - assertThat(this.fieldProcessor.extract("[]", payload).getValue()) - .isEqualTo(payload); + assertThat(this.fieldProcessor.extract("[]", payload).getValue()).isEqualTo(payload); } @Test @@ -85,8 +82,7 @@ public void extractArrayContents() { bravo.put("b", "bravo"); List> alpha = Arrays.asList(bravo, bravo); payload.put("a", alpha); - assertThat(this.fieldProcessor.extract("a[]", payload).getValue()) - .isEqualTo(alpha); + assertThat(this.fieldProcessor.extract("a[]", payload).getValue()).isEqualTo(alpha); } @Test @@ -96,8 +92,7 @@ public void extractFromItemsInArray() { entry.put("b", "bravo"); List> alpha = Arrays.asList(entry, entry); payload.put("a", alpha); - assertThat(this.fieldProcessor.extract("a[].b", payload).getValue()) - .isEqualTo(Arrays.asList("bravo", "bravo")); + assertThat(this.fieldProcessor.extract("a[].b", payload).getValue()).isEqualTo(Arrays.asList("bravo", "bravo")); } @Test @@ -105,11 +100,9 @@ public void extractOccasionallyAbsentFieldFromItemsInArray() { Map payload = new HashMap<>(); Map entry = new HashMap<>(); entry.put("b", "bravo"); - List> alpha = Arrays.asList(entry, - new HashMap()); + List> alpha = Arrays.asList(entry, new HashMap()); payload.put("a", alpha); - assertThat(this.fieldProcessor.extract("a[].b", payload).getValue()) - .isEqualTo(Arrays.asList("bravo")); + assertThat(this.fieldProcessor.extract("a[].b", payload).getValue()).isEqualTo(Arrays.asList("bravo")); } @Test @@ -121,8 +114,7 @@ public void extractOccasionallyNullFieldFromItemsInArray() { nullField.put("b", null); List> alpha = Arrays.asList(nonNullField, nullField); payload.put("a", alpha); - assertThat(this.fieldProcessor.extract("a[].b", payload).getValue()) - .isEqualTo(Arrays.asList("bravo", null)); + assertThat(this.fieldProcessor.extract("a[].b", payload).getValue()).isEqualTo(Arrays.asList("bravo", null)); } @Test @@ -131,11 +123,10 @@ public void extractNestedArray() { Map entry1 = createEntry("id:1"); Map entry2 = createEntry("id:2"); Map entry3 = createEntry("id:3"); - List>> alpha = Arrays - .asList(Arrays.asList(entry1, entry2), Arrays.asList(entry3)); + List>> alpha = Arrays.asList(Arrays.asList(entry1, entry2), Arrays.asList(entry3)); payload.put("a", alpha); - assertThat(this.fieldProcessor.extract("a[][]", payload).getValue()).isEqualTo( - Arrays.asList(Arrays.asList(entry1, entry2), Arrays.asList(entry3))); + assertThat(this.fieldProcessor.extract("a[][]", payload).getValue()) + .isEqualTo(Arrays.asList(Arrays.asList(entry1, entry2), Arrays.asList(entry3))); } @Test @@ -144,11 +135,9 @@ public void extractFromItemsInNestedArray() { Map entry1 = createEntry("id:1"); Map entry2 = createEntry("id:2"); Map entry3 = createEntry("id:3"); - List>> alpha = Arrays - .asList(Arrays.asList(entry1, entry2), Arrays.asList(entry3)); + List>> alpha = Arrays.asList(Arrays.asList(entry1, entry2), Arrays.asList(entry3)); payload.put("a", alpha); - assertThat(this.fieldProcessor.extract("a[][].id", payload).getValue()) - .isEqualTo(Arrays.asList("1", "2", "3")); + assertThat(this.fieldProcessor.extract("a[][].id", payload).getValue()).isEqualTo(Arrays.asList("1", "2", "3")); } @Test @@ -157,12 +146,10 @@ public void extractArraysFromItemsInNestedArray() { Map entry1 = createEntry("ids", Arrays.asList(1, 2)); Map entry2 = createEntry("ids", Arrays.asList(3)); Map entry3 = createEntry("ids", Arrays.asList(4)); - List>> alpha = Arrays - .asList(Arrays.asList(entry1, entry2), Arrays.asList(entry3)); + List>> alpha = Arrays.asList(Arrays.asList(entry1, entry2), Arrays.asList(entry3)); payload.put("a", alpha); assertThat(this.fieldProcessor.extract("a[][].ids", payload).getValue()) - .isEqualTo(Arrays.asList(Arrays.asList(1, 2), Arrays.asList(3), - Arrays.asList(4))); + .isEqualTo(Arrays.asList(Arrays.asList(1, 2), Arrays.asList(3), Arrays.asList(4))); } @Test(expected = FieldDoesNotExistException.class) @@ -256,8 +243,8 @@ public void removeNestedMapEntry() { @SuppressWarnings("unchecked") @Test public void removeItemsInArray() throws IOException { - Map payload = new ObjectMapper() - .readValue("{\"a\": [{\"b\":\"bravo\"},{\"b\":\"bravo\"}]}", Map.class); + Map payload = new ObjectMapper().readValue("{\"a\": [{\"b\":\"bravo\"},{\"b\":\"bravo\"}]}", + Map.class); this.fieldProcessor.remove("a[].b", payload); assertThat(payload.size()).isEqualTo(0); } @@ -265,8 +252,8 @@ public void removeItemsInArray() throws IOException { @SuppressWarnings("unchecked") @Test public void removeItemsInNestedArray() throws IOException { - Map payload = new ObjectMapper() - .readValue("{\"a\": [[{\"id\":1},{\"id\":2}], [{\"id\":3}]]}", Map.class); + Map payload = new ObjectMapper().readValue("{\"a\": [[{\"id\":1},{\"id\":2}], [{\"id\":3}]]}", + Map.class); this.fieldProcessor.remove("a[][].id", payload); assertThat(payload.size()).isEqualTo(0); } @@ -274,8 +261,8 @@ public void removeItemsInNestedArray() throws IOException { @SuppressWarnings("unchecked") @Test public void removeDoesNotRemoveArrayWithMapEntries() throws IOException { - Map payload = new ObjectMapper() - .readValue("{\"a\": [{\"b\":\"bravo\"},{\"b\":\"bravo\"}]}", Map.class); + Map payload = new ObjectMapper().readValue("{\"a\": [{\"b\":\"bravo\"},{\"b\":\"bravo\"}]}", + Map.class); this.fieldProcessor.remove("a[]", payload); assertThat(payload.size()).isEqualTo(1); } @@ -283,8 +270,7 @@ public void removeDoesNotRemoveArrayWithMapEntries() throws IOException { @SuppressWarnings("unchecked") @Test public void removeDoesNotRemoveArrayWithListEntries() throws IOException { - Map payload = new ObjectMapper().readValue("{\"a\": [[2],[3]]}", - Map.class); + Map payload = new ObjectMapper().readValue("{\"a\": [[2],[3]]}", Map.class); this.fieldProcessor.remove("a[]", payload); assertThat(payload.size()).isEqualTo(1); } @@ -292,8 +278,7 @@ public void removeDoesNotRemoveArrayWithListEntries() throws IOException { @SuppressWarnings("unchecked") @Test public void removeRemovesArrayWithOnlyScalarEntries() throws IOException { - Map payload = new ObjectMapper() - .readValue("{\"a\": [\"bravo\", \"charlie\"]}", Map.class); + Map payload = new ObjectMapper().readValue("{\"a\": [\"bravo\", \"charlie\"]}", Map.class); this.fieldProcessor.remove("a", payload); assertThat(payload.size()).isEqualTo(0); } @@ -301,8 +286,8 @@ public void removeRemovesArrayWithOnlyScalarEntries() throws IOException { @SuppressWarnings("unchecked") @Test public void removeSubsectionRemovesArrayWithMapEntries() throws IOException { - Map payload = new ObjectMapper() - .readValue("{\"a\": [{\"b\":\"bravo\"},{\"b\":\"bravo\"}]}", Map.class); + Map payload = new ObjectMapper().readValue("{\"a\": [{\"b\":\"bravo\"},{\"b\":\"bravo\"}]}", + Map.class); this.fieldProcessor.removeSubsection("a[]", payload); assertThat(payload.size()).isEqualTo(0); } @@ -310,8 +295,7 @@ public void removeSubsectionRemovesArrayWithMapEntries() throws IOException { @SuppressWarnings("unchecked") @Test public void removeSubsectionRemovesArrayWithListEntries() throws IOException { - Map payload = new ObjectMapper().readValue("{\"a\": [[2],[3]]}", - Map.class); + Map payload = new ObjectMapper().readValue("{\"a\": [[2],[3]]}", Map.class); this.fieldProcessor.removeSubsection("a[]", payload); assertThat(payload.size()).isEqualTo(0); } @@ -322,8 +306,7 @@ public void extractNestedEntryWithDotInKeys() throws IOException { Map alpha = new HashMap<>(); payload.put("a.key", alpha); alpha.put("b.key", "bravo"); - assertThat(this.fieldProcessor.extract("['a.key']['b.key']", payload).getValue()) - .isEqualTo("bravo"); + assertThat(this.fieldProcessor.extract("['a.key']['b.key']", payload).getValue()).isEqualTo("bravo"); } @SuppressWarnings("unchecked") @@ -336,8 +319,8 @@ public void extractNestedEntriesUsingTopLevelWildcard() throws IOException { Map charlie = new LinkedHashMap<>(); charlie.put("b", "bravo2"); payload.put("c", charlie); - assertThat((List) this.fieldProcessor.extract("*.b", payload).getValue()) - .containsExactly("bravo1", "bravo2"); + assertThat((List) this.fieldProcessor.extract("*.b", payload).getValue()).containsExactly("bravo1", + "bravo2"); } @SuppressWarnings("unchecked") @@ -350,9 +333,8 @@ public void extractNestedEntriesUsingMidLevelWildcard() throws IOException { bravo.put("b", "bravo"); alpha.put("one", bravo); alpha.put("two", bravo); - assertThat( - (List) this.fieldProcessor.extract("a.*.b", payload).getValue()) - .containsExactly("bravo", "bravo"); + assertThat((List) this.fieldProcessor.extract("a.*.b", payload).getValue()).containsExactly("bravo", + "bravo"); } @SuppressWarnings("unchecked") @@ -365,8 +347,7 @@ public void extractUsingLeafWildcardMatchingSingleItem() throws IOException { Map charlie = new HashMap<>(); charlie.put("b", "bravo2"); payload.put("c", charlie); - assertThat((List) this.fieldProcessor.extract("a.*", payload).getValue()) - .containsExactly("bravo1"); + assertThat((List) this.fieldProcessor.extract("a.*", payload).getValue()).containsExactly("bravo1"); } @SuppressWarnings("unchecked") @@ -377,8 +358,8 @@ public void extractUsingLeafWildcardMatchingMultipleItems() throws IOException { payload.put("a", alpha); alpha.put("b", "bravo1"); alpha.put("c", "charlie"); - assertThat((List) this.fieldProcessor.extract("a.*", payload).getValue()) - .containsExactly("bravo1", "charlie"); + assertThat((List) this.fieldProcessor.extract("a.*", payload).getValue()).containsExactly("bravo1", + "charlie"); } @Test diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/JsonFieldTypeResolverTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/JsonFieldTypeResolverTests.java index de4024b59..01b87c959 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/JsonFieldTypeResolverTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/JsonFieldTypeResolverTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-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. @@ -47,30 +47,25 @@ public void arrayField() throws IOException { @Test public void topLevelArray() throws IOException { assertThat(this.fieldTypeResolver.resolveFieldType(new FieldDescriptor("[]"), - new ObjectMapper().readValue("[{\"a\":\"alpha\"}]", List.class))) - .isEqualTo(JsonFieldType.ARRAY); + new ObjectMapper().readValue("[{\"a\":\"alpha\"}]", List.class))).isEqualTo(JsonFieldType.ARRAY); } @Test public void nestedArray() throws IOException { assertThat(this.fieldTypeResolver.resolveFieldType(new FieldDescriptor("a[]"), - createPayload("{\"a\": [{\"b\":\"bravo\"}]}"))) - .isEqualTo(JsonFieldType.ARRAY); + createPayload("{\"a\": [{\"b\":\"bravo\"}]}"))).isEqualTo(JsonFieldType.ARRAY); } @Test public void arrayNestedBeneathAnArray() throws IOException { assertThat(this.fieldTypeResolver.resolveFieldType(new FieldDescriptor("a[].b[]"), - createPayload("{\"a\": [{\"b\": [ 1, 2 ]}]}"))) - .isEqualTo(JsonFieldType.ARRAY); + createPayload("{\"a\": [{\"b\": [ 1, 2 ]}]}"))).isEqualTo(JsonFieldType.ARRAY); } @Test public void specificFieldOfObjectInArrayNestedBeneathAnArray() throws IOException { - assertThat( - this.fieldTypeResolver.resolveFieldType(new FieldDescriptor("a[].b[].c"), - createPayload("{\"a\": [{\"b\": [ {\"c\": 5}, {\"c\": 5}]}]}"))) - .isEqualTo(JsonFieldType.NUMBER); + assertThat(this.fieldTypeResolver.resolveFieldType(new FieldDescriptor("a[].b[].c"), + createPayload("{\"a\": [{\"b\": [ {\"c\": 5}, {\"c\": 5}]}]}"))).isEqualTo(JsonFieldType.NUMBER); } @Test @@ -101,118 +96,92 @@ public void stringField() throws IOException { @Test public void nestedField() throws IOException { assertThat(this.fieldTypeResolver.resolveFieldType(new FieldDescriptor("a.b.c"), - createPayload("{\"a\":{\"b\":{\"c\":{}}}}"))) - .isEqualTo(JsonFieldType.OBJECT); + createPayload("{\"a\":{\"b\":{\"c\":{}}}}"))).isEqualTo(JsonFieldType.OBJECT); } @Test public void multipleFieldsWithSameType() throws IOException { assertThat(this.fieldTypeResolver.resolveFieldType(new FieldDescriptor("a[].id"), - createPayload("{\"a\":[{\"id\":1},{\"id\":2}]}"))) - .isEqualTo(JsonFieldType.NUMBER); + createPayload("{\"a\":[{\"id\":1},{\"id\":2}]}"))).isEqualTo(JsonFieldType.NUMBER); } @Test public void multipleFieldsWithDifferentTypes() throws IOException { assertThat(this.fieldTypeResolver.resolveFieldType(new FieldDescriptor("a[].id"), - createPayload("{\"a\":[{\"id\":1},{\"id\":true}]}"))) - .isEqualTo(JsonFieldType.VARIES); + createPayload("{\"a\":[{\"id\":1},{\"id\":true}]}"))).isEqualTo(JsonFieldType.VARIES); } @Test public void multipleFieldsWithDifferentTypesAndSometimesAbsent() throws IOException { assertThat(this.fieldTypeResolver.resolveFieldType(new FieldDescriptor("a[].id"), - createPayload("{\"a\":[{\"id\":1},{\"id\":true}, { }]}"))) - .isEqualTo(JsonFieldType.VARIES); + createPayload("{\"a\":[{\"id\":1},{\"id\":true}, { }]}"))).isEqualTo(JsonFieldType.VARIES); } @Test - public void multipleFieldsWithDifferentTypesAndSometimesAbsentWhenOptionalResolvesToVaries() - throws IOException { - assertThat(this.fieldTypeResolver.resolveFieldType( - new FieldDescriptor("a[].id").optional(), - createPayload("{\"a\":[{\"id\":1},{\"id\":true}, { }]}"))) - .isEqualTo(JsonFieldType.VARIES); + public void multipleFieldsWithDifferentTypesAndSometimesAbsentWhenOptionalResolvesToVaries() throws IOException { + assertThat(this.fieldTypeResolver.resolveFieldType(new FieldDescriptor("a[].id").optional(), + createPayload("{\"a\":[{\"id\":1},{\"id\":true}, { }]}"))).isEqualTo(JsonFieldType.VARIES); } @Test public void multipleFieldsWhenSometimesAbsent() throws IOException { assertThat(this.fieldTypeResolver.resolveFieldType(new FieldDescriptor("a[].id"), - createPayload("{\"a\":[{\"id\":1},{ }]}"))) - .isEqualTo(JsonFieldType.NUMBER); + createPayload("{\"a\":[{\"id\":1},{ }]}"))).isEqualTo(JsonFieldType.NUMBER); } @Test public void multipleFieldsWithDifferentTypesAndSometimesNull() throws IOException { assertThat(this.fieldTypeResolver.resolveFieldType(new FieldDescriptor("a[].id"), - createPayload("{\"a\":[{\"id\":1},{\"id\":true}, {\"id\":null}]}"))) - .isEqualTo(JsonFieldType.VARIES); + createPayload("{\"a\":[{\"id\":1},{\"id\":true}, {\"id\":null}]}"))).isEqualTo(JsonFieldType.VARIES); } @Test - public void multipleFieldsWhenNotNullThenNullWhenRequiredHasVariesType() - throws IOException { + public void multipleFieldsWhenNotNullThenNullWhenRequiredHasVariesType() throws IOException { assertThat(this.fieldTypeResolver.resolveFieldType(new FieldDescriptor("a[].id"), - createPayload("{\"a\":[{\"id\":1},{\"id\":null}]}"))) - .isEqualTo(JsonFieldType.VARIES); + createPayload("{\"a\":[{\"id\":1},{\"id\":null}]}"))).isEqualTo(JsonFieldType.VARIES); } @Test - public void multipleFieldsWhenNotNullThenNullWhenOptionalHasSpecificType() - throws IOException { - assertThat(this.fieldTypeResolver.resolveFieldType( - new FieldDescriptor("a[].id").optional(), - createPayload("{\"a\":[{\"id\":1},{\"id\":null}]}"))) - .isEqualTo(JsonFieldType.NUMBER); + public void multipleFieldsWhenNotNullThenNullWhenOptionalHasSpecificType() throws IOException { + assertThat(this.fieldTypeResolver.resolveFieldType(new FieldDescriptor("a[].id").optional(), + createPayload("{\"a\":[{\"id\":1},{\"id\":null}]}"))).isEqualTo(JsonFieldType.NUMBER); } @Test - public void multipleFieldsWhenNullThenNotNullWhenRequiredHasVariesType() - throws IOException { + public void multipleFieldsWhenNullThenNotNullWhenRequiredHasVariesType() throws IOException { assertThat(this.fieldTypeResolver.resolveFieldType(new FieldDescriptor("a[].id"), - createPayload("{\"a\":[{\"id\":null},{\"id\":1}]}"))) - .isEqualTo(JsonFieldType.VARIES); + createPayload("{\"a\":[{\"id\":null},{\"id\":1}]}"))).isEqualTo(JsonFieldType.VARIES); } @Test - public void multipleFieldsWhenNullThenNotNullWhenOptionalHasSpecificType() - throws IOException { - assertThat(this.fieldTypeResolver.resolveFieldType( - new FieldDescriptor("a[].id").optional(), - createPayload("{\"a\":[{\"id\":null},{\"id\":1}]}"))) - .isEqualTo(JsonFieldType.NUMBER); + public void multipleFieldsWhenNullThenNotNullWhenOptionalHasSpecificType() throws IOException { + assertThat(this.fieldTypeResolver.resolveFieldType(new FieldDescriptor("a[].id").optional(), + createPayload("{\"a\":[{\"id\":null},{\"id\":1}]}"))).isEqualTo(JsonFieldType.NUMBER); } @Test public void multipleFieldsWhenEitherNullOrAbsent() throws IOException { assertThat(this.fieldTypeResolver.resolveFieldType(new FieldDescriptor("a[].id"), - createPayload("{\"a\":[{},{\"id\":null}]}"))) - .isEqualTo(JsonFieldType.NULL); + createPayload("{\"a\":[{},{\"id\":null}]}"))).isEqualTo(JsonFieldType.NULL); } @Test public void multipleFieldsThatAreAllNull() throws IOException { assertThat(this.fieldTypeResolver.resolveFieldType(new FieldDescriptor("a[].id"), - createPayload("{\"a\":[{\"id\":null},{\"id\":null}]}"))) - .isEqualTo(JsonFieldType.NULL); + createPayload("{\"a\":[{\"id\":null},{\"id\":null}]}"))).isEqualTo(JsonFieldType.NULL); } @Test - public void nonExistentSingleFieldProducesFieldDoesNotExistException() - throws IOException { + public void nonExistentSingleFieldProducesFieldDoesNotExistException() throws IOException { this.thrownException.expect(FieldDoesNotExistException.class); - this.thrownException.expectMessage( - "The payload does not contain a field with the path 'a.b'"); - this.fieldTypeResolver.resolveFieldType(new FieldDescriptor("a.b"), - createPayload("{\"a\":{}}")); + this.thrownException.expectMessage("The payload does not contain a field with the path 'a.b'"); + this.fieldTypeResolver.resolveFieldType(new FieldDescriptor("a.b"), createPayload("{\"a\":{}}")); } @Test - public void nonExistentMultipleFieldsProducesFieldDoesNotExistException() - throws IOException { + public void nonExistentMultipleFieldsProducesFieldDoesNotExistException() throws IOException { this.thrownException.expect(FieldDoesNotExistException.class); - this.thrownException.expectMessage( - "The payload does not contain a field with the path 'a[].b'"); + this.thrownException.expectMessage("The payload does not contain a field with the path 'a[].b'"); this.fieldTypeResolver.resolveFieldType(new FieldDescriptor("a[].b"), createPayload("{\"a\":[{\"c\":1},{\"c\":2}]}")); } @@ -220,22 +189,19 @@ public void nonExistentMultipleFieldsProducesFieldDoesNotExistException() @Test public void leafWildcardWithCommonType() throws IOException { assertThat(this.fieldTypeResolver.resolveFieldType(new FieldDescriptor("a.*"), - createPayload("{\"a\": {\"b\": 5, \"c\": 6}}"))) - .isEqualTo(JsonFieldType.NUMBER); + createPayload("{\"a\": {\"b\": 5, \"c\": 6}}"))).isEqualTo(JsonFieldType.NUMBER); } @Test public void leafWildcardWithVaryingType() throws IOException { assertThat(this.fieldTypeResolver.resolveFieldType(new FieldDescriptor("a.*"), - createPayload("{\"a\": {\"b\": 5, \"c\": \"six\"}}"))) - .isEqualTo(JsonFieldType.VARIES); + createPayload("{\"a\": {\"b\": 5, \"c\": \"six\"}}"))).isEqualTo(JsonFieldType.VARIES); } @Test public void intermediateWildcardWithCommonType() throws IOException { assertThat(this.fieldTypeResolver.resolveFieldType(new FieldDescriptor("a.*.d"), - createPayload("{\"a\": {\"b\": {\"d\": 4}, \"c\": {\"d\": 5}}}}"))) - .isEqualTo(JsonFieldType.NUMBER); + createPayload("{\"a\": {\"b\": {\"d\": 4}, \"c\": {\"d\": 5}}}}"))).isEqualTo(JsonFieldType.NUMBER); } @Test @@ -245,10 +211,10 @@ public void intermediateWildcardWithVaryingType() throws IOException { .isEqualTo(JsonFieldType.VARIES); } - private void assertFieldType(JsonFieldType expectedType, String jsonValue) - throws IOException { - assertThat(this.fieldTypeResolver.resolveFieldType(new FieldDescriptor("field"), - createSimplePayload(jsonValue))).isEqualTo(expectedType); + private void assertFieldType(JsonFieldType expectedType, String jsonValue) throws IOException { + assertThat( + this.fieldTypeResolver.resolveFieldType(new FieldDescriptor("field"), createSimplePayload(jsonValue))) + .isEqualTo(expectedType); } private Map createSimplePayload(String value) throws IOException { diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/PayloadDocumentationTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/PayloadDocumentationTests.java index 60413f916..7c57c3c19 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/PayloadDocumentationTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/PayloadDocumentationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-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. @@ -43,16 +43,14 @@ public void applyPathPrefixAppliesPrefixToDescriptorPaths() { @Test public void applyPathPrefixCopiesIgnored() { - List descriptors = applyPathPrefix("alpha.", - Arrays.asList(fieldWithPath("bravo").ignored())); + List descriptors = applyPathPrefix("alpha.", Arrays.asList(fieldWithPath("bravo").ignored())); assertThat(descriptors.size()).isEqualTo(1); assertThat(descriptors.get(0).isIgnored()).isTrue(); } @Test public void applyPathPrefixCopiesOptional() { - List descriptors = applyPathPrefix("alpha.", - Arrays.asList(fieldWithPath("bravo").optional())); + List descriptors = applyPathPrefix("alpha.", Arrays.asList(fieldWithPath("bravo").optional())); assertThat(descriptors.size()).isEqualTo(1); assertThat(descriptors.get(0).isOptional()).isTrue(); } @@ -76,8 +74,7 @@ public void applyPathPrefixCopiesType() { @Test public void applyPathPrefixCopiesAttributes() { List descriptors = applyPathPrefix("alpha.", - Arrays.asList(fieldWithPath("bravo").attributes(key("a").value("alpha"), - key("b").value("bravo")))); + Arrays.asList(fieldWithPath("bravo").attributes(key("a").value("alpha"), key("b").value("bravo")))); assertThat(descriptors.size()).isEqualTo(1); assertThat(descriptors.get(0).getAttributes().size()).isEqualTo(2); assertThat(descriptors.get(0).getAttributes().get("a")).isEqualTo("alpha"); diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/RequestBodyPartSnippetTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/RequestBodyPartSnippetTests.java index 50b7fe2e1..85a686d98 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/RequestBodyPartSnippetTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/RequestBodyPartSnippetTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-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. @@ -47,25 +47,24 @@ public RequestBodyPartSnippetTests(String name, TemplateFormat templateFormat) { @Test public void requestPartWithBody() throws IOException { - requestPartBody("one").document(this.operationBuilder.request("http://localhost") - .part("one", "some content".getBytes()).build()); + requestPartBody("one").document( + this.operationBuilder.request("http://localhost").part("one", "some content".getBytes()).build()); assertThat(this.generatedSnippets.snippet("request-part-one-body")) .is(codeBlock(null, "nowrap").withContent("some content")); } @Test public void requestPartWithNoBody() throws IOException { - requestPartBody("one").document(this.operationBuilder.request("http://localhost") - .part("one", new byte[0]).build()); + requestPartBody("one") + .document(this.operationBuilder.request("http://localhost").part("one", new byte[0]).build()); assertThat(this.generatedSnippets.snippet("request-part-one-body")) .is(codeBlock(null, "nowrap").withContent("")); } @Test public void subsectionOfRequestPartBody() throws IOException { - requestPartBody("one", beneathPath("a.b")) - .document(this.operationBuilder.request("http://localhost") - .part("one", "{\"a\":{\"b\":{\"c\":5}}}".getBytes()).build()); + requestPartBody("one", beneathPath("a.b")).document(this.operationBuilder.request("http://localhost") + .part("one", "{\"a\":{\"b\":{\"c\":5}}}".getBytes()).build()); assertThat(this.generatedSnippets.snippet("request-part-one-body-beneath-a.b")) .is(codeBlock(null, "nowrap").withContent("{\"c\":5}")); } @@ -75,12 +74,9 @@ public void customSnippetAttributes() throws IOException { TemplateResourceResolver resolver = mock(TemplateResourceResolver.class); given(resolver.resolveTemplateResource("request-part-body")) .willReturn(snippetResource("request-part-body-with-language")); - requestPartBody("one", attributes(key("language").value("json"))) - .document(this.operationBuilder - .attribute(TemplateEngine.class.getName(), - new MustacheTemplateEngine(resolver)) - .request("http://localhost") - .part("one", "{\"a\":\"alpha\"}".getBytes()).build()); + requestPartBody("one", attributes(key("language").value("json"))).document( + this.operationBuilder.attribute(TemplateEngine.class.getName(), new MustacheTemplateEngine(resolver)) + .request("http://localhost").part("one", "{\"a\":\"alpha\"}".getBytes()).build()); assertThat(this.generatedSnippets.snippet("request-part-one-body")) .is(codeBlock("json", "nowrap").withContent("{\"a\":\"alpha\"}")); } diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/RequestBodySnippetTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/RequestBodySnippetTests.java index 6410a318c..87e35e552 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/RequestBodySnippetTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/RequestBodySnippetTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-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. @@ -47,8 +47,7 @@ public RequestBodySnippetTests(String name, TemplateFormat templateFormat) { @Test public void requestWithBody() throws IOException { - requestBody().document(this.operationBuilder.request("http://localhost") - .content("some content").build()); + requestBody().document(this.operationBuilder.request("http://localhost").content("some content").build()); assertThat(this.generatedSnippets.snippet("request-body")) .is(codeBlock(null, "nowrap").withContent("some content")); } @@ -56,15 +55,13 @@ public void requestWithBody() throws IOException { @Test public void requestWithNoBody() throws IOException { requestBody().document(this.operationBuilder.request("http://localhost").build()); - assertThat(this.generatedSnippets.snippet("request-body")) - .is(codeBlock(null, "nowrap").withContent("")); + assertThat(this.generatedSnippets.snippet("request-body")).is(codeBlock(null, "nowrap").withContent("")); } @Test public void subsectionOfRequestBody() throws IOException { - requestBody(beneathPath("a.b")) - .document(this.operationBuilder.request("http://localhost") - .content("{\"a\":{\"b\":{\"c\":5}}}").build()); + requestBody(beneathPath("a.b")).document( + this.operationBuilder.request("http://localhost").content("{\"a\":{\"b\":{\"c\":5}}}").build()); assertThat(this.generatedSnippets.snippet("request-body-beneath-a.b")) .is(codeBlock(null, "nowrap").withContent("{\"c\":5}")); } @@ -74,12 +71,9 @@ public void customSnippetAttributes() throws IOException { TemplateResourceResolver resolver = mock(TemplateResourceResolver.class); given(resolver.resolveTemplateResource("request-body")) .willReturn(snippetResource("request-body-with-language")); - requestBody(attributes(key("language").value("json"))) - .document(this.operationBuilder - .attribute(TemplateEngine.class.getName(), - new MustacheTemplateEngine(resolver)) - .request("http://localhost").content("{\"a\":\"alpha\"}") - .build()); + requestBody(attributes(key("language").value("json"))).document( + this.operationBuilder.attribute(TemplateEngine.class.getName(), new MustacheTemplateEngine(resolver)) + .request("http://localhost").content("{\"a\":\"alpha\"}").build()); assertThat(this.generatedSnippets.snippet("request-body")) .is(codeBlock("json", "nowrap").withContent("{\"a\":\"alpha\"}")); } diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/RequestFieldsSnippetFailureTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/RequestFieldsSnippetFailureTests.java index e1f449916..827a69428 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/RequestFieldsSnippetFailureTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/RequestFieldsSnippetFailureTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-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. @@ -44,8 +44,7 @@ public class RequestFieldsSnippetFailureTests { @Rule - public OperationBuilder operationBuilder = new OperationBuilder( - TemplateFormats.asciidoctor()); + public OperationBuilder operationBuilder = new OperationBuilder(TemplateFormats.asciidoctor()); @Rule public ExpectedException thrown = ExpectedException.none(); @@ -53,50 +52,40 @@ public class RequestFieldsSnippetFailureTests { @Test public void undocumentedRequestField() throws IOException { this.thrown.expect(SnippetException.class); - this.thrown.expectMessage(startsWith( - "The following parts of the payload were not" + " documented:")); + this.thrown.expectMessage(startsWith("The following parts of the payload were not" + " documented:")); new RequestFieldsSnippet(Collections.emptyList()) - .document(this.operationBuilder.request("http://localhost") - .content("{\"a\": 5}").build()); + .document(this.operationBuilder.request("http://localhost").content("{\"a\": 5}").build()); } @Test public void missingRequestField() throws IOException { this.thrown.expect(SnippetException.class); - this.thrown.expectMessage(equalTo("Fields with the following paths were not found" - + " in the payload: [a.b]")); + this.thrown.expectMessage(equalTo("Fields with the following paths were not found" + " in the payload: [a.b]")); new RequestFieldsSnippet(Arrays.asList(fieldWithPath("a.b").description("one"))) - .document(this.operationBuilder.request("http://localhost").content("{}") - .build()); + .document(this.operationBuilder.request("http://localhost").content("{}").build()); } @Test public void missingOptionalRequestFieldWithNoTypeProvided() throws IOException { this.thrown.expect(FieldTypeRequiredException.class); - new RequestFieldsSnippet( - Arrays.asList(fieldWithPath("a.b").description("one").optional())) - .document(this.operationBuilder.request("http://localhost") - .content("{ }").build()); + new RequestFieldsSnippet(Arrays.asList(fieldWithPath("a.b").description("one").optional())) + .document(this.operationBuilder.request("http://localhost").content("{ }").build()); } @Test public void undocumentedRequestFieldAndMissingRequestField() throws IOException { this.thrown.expect(SnippetException.class); - this.thrown.expectMessage(startsWith( - "The following parts of the payload were not" + " documented:")); + this.thrown.expectMessage(startsWith("The following parts of the payload were not" + " documented:")); this.thrown - .expectMessage(endsWith("Fields with the following paths were not found" - + " in the payload: [a.b]")); + .expectMessage(endsWith("Fields with the following paths were not found" + " in the payload: [a.b]")); new RequestFieldsSnippet(Arrays.asList(fieldWithPath("a.b").description("one"))) - .document(this.operationBuilder.request("http://localhost") - .content("{ \"a\": { \"c\": 5 }}").build()); + .document(this.operationBuilder.request("http://localhost").content("{ \"a\": { \"c\": 5 }}").build()); } @Test public void attemptToDocumentFieldsWithNoRequestBody() throws IOException { this.thrown.expect(SnippetException.class); - this.thrown.expectMessage( - equalTo("Cannot document request fields as the request body is empty")); + this.thrown.expectMessage(equalTo("Cannot document request fields as the request body is empty")); new RequestFieldsSnippet(Arrays.asList(fieldWithPath("a").description("one"))) .document(this.operationBuilder.request("http://localhost").build()); } @@ -104,131 +93,101 @@ public void attemptToDocumentFieldsWithNoRequestBody() throws IOException { @Test public void fieldWithExplicitTypeThatDoesNotMatchThePayload() throws IOException { this.thrown.expect(FieldTypesDoNotMatchException.class); - this.thrown.expectMessage(equalTo("The documented type of the field 'a' is" - + " Object but the actual type is Number")); - new RequestFieldsSnippet(Arrays - .asList(fieldWithPath("a").description("one").type(JsonFieldType.OBJECT))) - .document(this.operationBuilder.request("http://localhost") - .content("{ \"a\": 5 }").build()); + this.thrown.expectMessage( + equalTo("The documented type of the field 'a' is" + " Object but the actual type is Number")); + new RequestFieldsSnippet(Arrays.asList(fieldWithPath("a").description("one").type(JsonFieldType.OBJECT))) + .document(this.operationBuilder.request("http://localhost").content("{ \"a\": 5 }").build()); } @Test public void fieldWithExplicitSpecificTypeThatActuallyVaries() throws IOException { this.thrown.expect(FieldTypesDoNotMatchException.class); - this.thrown.expectMessage(equalTo("The documented type of the field '[].a' is" - + " Object but the actual type is Varies")); - new RequestFieldsSnippet(Arrays.asList( - fieldWithPath("[].a").description("one").type(JsonFieldType.OBJECT))) - .document(this.operationBuilder.request("http://localhost") - .content("[{ \"a\": 5 },{ \"a\": \"b\" }]").build()); + this.thrown.expectMessage( + equalTo("The documented type of the field '[].a' is" + " Object but the actual type is Varies")); + new RequestFieldsSnippet(Arrays.asList(fieldWithPath("[].a").description("one").type(JsonFieldType.OBJECT))) + .document(this.operationBuilder.request("http://localhost").content("[{ \"a\": 5 },{ \"a\": \"b\" }]") + .build()); } @Test public void undocumentedXmlRequestField() throws IOException { this.thrown.expect(SnippetException.class); - this.thrown.expectMessage( - startsWith("The following parts of the payload were not documented:")); + this.thrown.expectMessage(startsWith("The following parts of the payload were not documented:")); new RequestFieldsSnippet(Collections.emptyList()) - .document(this.operationBuilder.request("http://localhost") - .content("5") - .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_XML_VALUE) - .build()); + .document(this.operationBuilder.request("http://localhost").content("5") + .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_XML_VALUE).build()); } @Test public void xmlDescendentsAreNotDocumentedByFieldDescriptor() throws IOException { this.thrown.expect(SnippetException.class); - this.thrown.expectMessage( - startsWith("The following parts of the payload were not documented:")); - new RequestFieldsSnippet( - Arrays.asList(fieldWithPath("a").type("a").description("one"))) - .document(this.operationBuilder.request("http://localhost") - .content("5") - .header(HttpHeaders.CONTENT_TYPE, - MediaType.APPLICATION_XML_VALUE) - .build()); + this.thrown.expectMessage(startsWith("The following parts of the payload were not documented:")); + new RequestFieldsSnippet(Arrays.asList(fieldWithPath("a").type("a").description("one"))) + .document(this.operationBuilder.request("http://localhost").content("5") + .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_XML_VALUE).build()); } @Test public void xmlRequestFieldWithNoType() throws IOException { this.thrown.expect(FieldTypeRequiredException.class); new RequestFieldsSnippet(Arrays.asList(fieldWithPath("a").description("one"))) - .document(this.operationBuilder.request("http://localhost") - .content("5") - .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_XML_VALUE) - .build()); + .document(this.operationBuilder.request("http://localhost").content("5") + .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_XML_VALUE).build()); } @Test public void missingXmlRequestField() throws IOException { this.thrown.expect(SnippetException.class); - this.thrown.expectMessage(equalTo("Fields with the following paths were not found" - + " in the payload: [a/b]")); - new RequestFieldsSnippet(Arrays.asList(fieldWithPath("a/b").description("one"), - fieldWithPath("a").description("one"))).document(this.operationBuilder - .request("http://localhost").content("") - .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_XML_VALUE) - .build()); + this.thrown.expectMessage(equalTo("Fields with the following paths were not found" + " in the payload: [a/b]")); + new RequestFieldsSnippet( + Arrays.asList(fieldWithPath("a/b").description("one"), fieldWithPath("a").description("one"))) + .document(this.operationBuilder.request("http://localhost").content("") + .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_XML_VALUE).build()); } @Test - public void undocumentedXmlRequestFieldAndMissingXmlRequestField() - throws IOException { + public void undocumentedXmlRequestFieldAndMissingXmlRequestField() throws IOException { this.thrown.expect(SnippetException.class); - this.thrown.expectMessage( - startsWith("The following parts of the payload were not documented:")); + this.thrown.expectMessage(startsWith("The following parts of the payload were not documented:")); this.thrown - .expectMessage(endsWith("Fields with the following paths were not found" - + " in the payload: [a/b]")); + .expectMessage(endsWith("Fields with the following paths were not found" + " in the payload: [a/b]")); new RequestFieldsSnippet(Arrays.asList(fieldWithPath("a/b").description("one"))) - .document(this.operationBuilder.request("http://localhost") - .content("5") - .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_XML_VALUE) - .build()); + .document(this.operationBuilder.request("http://localhost").content("5") + .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_XML_VALUE).build()); } @Test public void unsupportedContent() throws IOException { this.thrown.expect(PayloadHandlingException.class); - this.thrown.expectMessage(equalTo("Cannot handle text/plain content as it could" - + " not be parsed as JSON or XML")); + this.thrown.expectMessage( + equalTo("Cannot handle text/plain content as it could" + " not be parsed as JSON or XML")); new RequestFieldsSnippet(Collections.emptyList()) - .document(this.operationBuilder.request("http://localhost") - .content("Some plain text") - .header(HttpHeaders.CONTENT_TYPE, MediaType.TEXT_PLAIN_VALUE) - .build()); + .document(this.operationBuilder.request("http://localhost").content("Some plain text") + .header(HttpHeaders.CONTENT_TYPE, MediaType.TEXT_PLAIN_VALUE).build()); } @Test public void nonOptionalFieldBeneathArrayThatIsSometimesNull() throws IOException { this.thrown.expect(SnippetException.class); - this.thrown.expectMessage(startsWith( - "Fields with the following paths were not found in the payload: " - + "[a[].b]")); - new RequestFieldsSnippet(Arrays.asList( - fieldWithPath("a[].b").description("one").type(JsonFieldType.NUMBER), + this.thrown.expectMessage( + startsWith("Fields with the following paths were not found in the payload: " + "[a[].b]")); + new RequestFieldsSnippet(Arrays.asList(fieldWithPath("a[].b").description("one").type(JsonFieldType.NUMBER), fieldWithPath("a[].c").description("two").type(JsonFieldType.NUMBER))) - .document(this.operationBuilder.request("http://localhost") - .content("{\"a\":[{\"b\": 1,\"c\": 2}, " - + "{\"b\": null, \"c\": 2}," - + " {\"b\": 1,\"c\": 2}]}") + .document(this.operationBuilder.request("http://localhost").content( + "{\"a\":[{\"b\": 1,\"c\": 2}, " + "{\"b\": null, \"c\": 2}," + " {\"b\": 1,\"c\": 2}]}") .build()); } @Test public void nonOptionalFieldBeneathArrayThatIsSometimesAbsent() throws IOException { this.thrown.expect(SnippetException.class); - this.thrown.expectMessage(startsWith( - "Fields with the following paths were not found in the payload: " - + "[a[].b]")); - new RequestFieldsSnippet(Arrays.asList( - fieldWithPath("a[].b").description("one").type(JsonFieldType.NUMBER), + this.thrown.expectMessage( + startsWith("Fields with the following paths were not found in the payload: " + "[a[].b]")); + new RequestFieldsSnippet(Arrays.asList(fieldWithPath("a[].b").description("one").type(JsonFieldType.NUMBER), fieldWithPath("a[].c").description("two").type(JsonFieldType.NUMBER))) - .document( - this.operationBuilder.request("http://localhost") - .content("{\"a\":[{\"b\": 1,\"c\": 2}, " - + "{\"c\": 2}, {\"b\": 1,\"c\": 2}]}") - .build()); + .document(this.operationBuilder.request("http://localhost") + .content("{\"a\":[{\"b\": 1,\"c\": 2}, " + "{\"c\": 2}, {\"b\": 1,\"c\": 2}]}") + .build()); } } diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/RequestFieldsSnippetTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/RequestFieldsSnippetTests.java index 65ffc3e9b..490f1a801 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/RequestFieldsSnippetTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/RequestFieldsSnippetTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-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. @@ -54,179 +54,139 @@ public RequestFieldsSnippetTests(String name, TemplateFormat templateFormat) { @Test public void mapRequestWithFields() throws IOException { new RequestFieldsSnippet(Arrays.asList(fieldWithPath("a.b").description("one"), - fieldWithPath("a.c").description("two"), - fieldWithPath("a").description("three"))) + fieldWithPath("a.c").description("two"), fieldWithPath("a").description("three"))) .document(this.operationBuilder.request("http://localhost") - .content("{\"a\": {\"b\": 5, \"c\": \"charlie\"}}") - .build()); - assertThat(this.generatedSnippets.requestFields()) - .is(tableWithHeader("Path", "Type", "Description") - .row("`a.b`", "`Number`", "one").row("`a.c`", "`String`", "two") - .row("`a`", "`Object`", "three")); + .content("{\"a\": {\"b\": 5, \"c\": \"charlie\"}}").build()); + assertThat(this.generatedSnippets.requestFields()).is(tableWithHeader("Path", "Type", "Description") + .row("`a.b`", "`Number`", "one").row("`a.c`", "`String`", "two").row("`a`", "`Object`", "three")); } @Test public void mapRequestWithNullField() throws IOException { new RequestFieldsSnippet(Arrays.asList(fieldWithPath("a.b").description("one"))) - .document(this.operationBuilder.request("http://localhost") - .content("{\"a\": {\"b\": null}}").build()); + .document(this.operationBuilder.request("http://localhost").content("{\"a\": {\"b\": null}}").build()); assertThat(this.generatedSnippets.requestFields()) - .is(tableWithHeader("Path", "Type", "Description").row("`a.b`", "`Null`", - "one")); + .is(tableWithHeader("Path", "Type", "Description").row("`a.b`", "`Null`", "one")); } @Test public void entireSubsectionsCanBeDocumented() throws IOException { - new RequestFieldsSnippet( - Arrays.asList(subsectionWithPath("a").description("one"))) - .document(this.operationBuilder.request("http://localhost") - .content("{\"a\": {\"b\": 5, \"c\": \"charlie\"}}") - .build()); + new RequestFieldsSnippet(Arrays.asList(subsectionWithPath("a").description("one"))) + .document(this.operationBuilder.request("http://localhost") + .content("{\"a\": {\"b\": 5, \"c\": \"charlie\"}}").build()); assertThat(this.generatedSnippets.requestFields()) - .is(tableWithHeader("Path", "Type", "Description").row("`a`", "`Object`", - "one")); + .is(tableWithHeader("Path", "Type", "Description").row("`a`", "`Object`", "one")); } @Test public void subsectionOfMapRequest() throws IOException { - requestFields(beneathPath("a"), fieldWithPath("b").description("one"), - fieldWithPath("c").description("two")) - .document(this.operationBuilder.request("http://localhost") - .content("{\"a\": {\"b\": 5, \"c\": \"charlie\"}}") - .build()); + requestFields(beneathPath("a"), fieldWithPath("b").description("one"), fieldWithPath("c").description("two")) + .document(this.operationBuilder.request("http://localhost") + .content("{\"a\": {\"b\": 5, \"c\": \"charlie\"}}").build()); assertThat(this.generatedSnippets.snippet("request-fields-beneath-a")) - .is(tableWithHeader("Path", "Type", "Description") - .row("`b`", "`Number`", "one").row("`c`", "`String`", "two")); + .is(tableWithHeader("Path", "Type", "Description").row("`b`", "`Number`", "one").row("`c`", "`String`", + "two")); } @Test public void subsectionOfMapRequestWithCommonPrefix() throws IOException { - requestFields(beneathPath("a")) - .andWithPrefix("b.", fieldWithPath("c").description("two")) + requestFields(beneathPath("a")).andWithPrefix("b.", fieldWithPath("c").description("two")) .document(this.operationBuilder.request("http://localhost") .content("{\"a\": {\"b\": {\"c\": \"charlie\"}}}").build()); assertThat(this.generatedSnippets.snippet("request-fields-beneath-a")) - .is(tableWithHeader("Path", "Type", "Description").row("`b.c`", - "`String`", "two")); + .is(tableWithHeader("Path", "Type", "Description").row("`b.c`", "`String`", "two")); } @Test public void arrayRequestWithFields() throws IOException { new RequestFieldsSnippet(Arrays.asList(fieldWithPath("[]").description("one"), - fieldWithPath("[]a.b").description("two"), - fieldWithPath("[]a.c").description("three"), - fieldWithPath("[]a").description("four"))) - .document(this.operationBuilder.request("http://localhost") - .content("[{\"a\": {\"b\": 5, \"c\":\"charlie\"}}," - + "{\"a\": {\"b\": 4, \"c\":\"chalk\"}}]") - .build()); - assertThat(this.generatedSnippets.requestFields()) - .is(tableWithHeader("Path", "Type", "Description") - .row("`[]`", "`Array`", "one").row("`[]a.b`", "`Number`", "two") - .row("`[]a.c`", "`String`", "three") - .row("`[]a`", "`Object`", "four")); + fieldWithPath("[]a.b").description("two"), fieldWithPath("[]a.c").description("three"), + fieldWithPath("[]a").description("four"))).document(this.operationBuilder.request("http://localhost") + .content("[{\"a\": {\"b\": 5, \"c\":\"charlie\"}}," + "{\"a\": {\"b\": 4, \"c\":\"chalk\"}}]") + .build()); + assertThat(this.generatedSnippets.requestFields()).is(tableWithHeader("Path", "Type", "Description") + .row("`[]`", "`Array`", "one").row("`[]a.b`", "`Number`", "two").row("`[]a.c`", "`String`", "three") + .row("`[]a`", "`Object`", "four")); } @Test public void arrayRequestWithAlwaysNullField() throws IOException { new RequestFieldsSnippet(Arrays.asList(fieldWithPath("[]a.b").description("one"))) .document(this.operationBuilder.request("http://localhost") - .content("[{\"a\": {\"b\": null}}," + "{\"a\": {\"b\": null}}]") - .build()); + .content("[{\"a\": {\"b\": null}}," + "{\"a\": {\"b\": null}}]").build()); assertThat(this.generatedSnippets.requestFields()) - .is(tableWithHeader("Path", "Type", "Description").row("`[]a.b`", - "`Null`", "one")); + .is(tableWithHeader("Path", "Type", "Description").row("`[]a.b`", "`Null`", "one")); } @Test public void subsectionOfArrayRequest() throws IOException { - requestFields(beneathPath("[].a"), fieldWithPath("b").description("one"), - fieldWithPath("c").description("two")) - .document(this.operationBuilder.request("http://localhost") - .content("[{\"a\": {\"b\": 5, \"c\": \"charlie\"}}]") - .build()); + requestFields(beneathPath("[].a"), fieldWithPath("b").description("one"), fieldWithPath("c").description("two")) + .document(this.operationBuilder.request("http://localhost") + .content("[{\"a\": {\"b\": 5, \"c\": \"charlie\"}}]").build()); assertThat(this.generatedSnippets.snippet("request-fields-beneath-[].a")) - .is(tableWithHeader("Path", "Type", "Description") - .row("`b`", "`Number`", "one").row("`c`", "`String`", "two")); + .is(tableWithHeader("Path", "Type", "Description").row("`b`", "`Number`", "one").row("`c`", "`String`", + "two")); } @Test public void ignoredRequestField() throws IOException { - new RequestFieldsSnippet(Arrays.asList(fieldWithPath("a").ignored(), - fieldWithPath("b").description("Field b"))) - .document(this.operationBuilder.request("http://localhost") - .content("{\"a\": 5, \"b\": 4}").build()); + new RequestFieldsSnippet(Arrays.asList(fieldWithPath("a").ignored(), fieldWithPath("b").description("Field b"))) + .document(this.operationBuilder.request("http://localhost").content("{\"a\": 5, \"b\": 4}").build()); assertThat(this.generatedSnippets.requestFields()) - .is(tableWithHeader("Path", "Type", "Description").row("`b`", "`Number`", - "Field b")); + .is(tableWithHeader("Path", "Type", "Description").row("`b`", "`Number`", "Field b")); } @Test public void entireSubsectionCanBeIgnored() throws IOException { - new RequestFieldsSnippet(Arrays.asList(subsectionWithPath("a").ignored(), - fieldWithPath("c").description("Field c"))) + new RequestFieldsSnippet( + Arrays.asList(subsectionWithPath("a").ignored(), fieldWithPath("c").description("Field c"))) .document(this.operationBuilder.request("http://localhost") .content("{\"a\": {\"b\": 5}, \"c\": 4}").build()); assertThat(this.generatedSnippets.requestFields()) - .is(tableWithHeader("Path", "Type", "Description").row("`c`", "`Number`", - "Field c")); + .is(tableWithHeader("Path", "Type", "Description").row("`c`", "`Number`", "Field c")); } @Test public void allUndocumentedRequestFieldsCanBeIgnored() throws IOException { - new RequestFieldsSnippet(Arrays.asList(fieldWithPath("b").description("Field b")), - true).document( - this.operationBuilder.request("http://localhost") - .content("{\"a\": 5, \"b\": 4}").build()); + new RequestFieldsSnippet(Arrays.asList(fieldWithPath("b").description("Field b")), true) + .document(this.operationBuilder.request("http://localhost").content("{\"a\": 5, \"b\": 4}").build()); assertThat(this.generatedSnippets.requestFields()) - .is(tableWithHeader("Path", "Type", "Description").row("`b`", "`Number`", - "Field b")); + .is(tableWithHeader("Path", "Type", "Description").row("`b`", "`Number`", "Field b")); } @Test - public void allUndocumentedFieldsContinueToBeIgnoredAfterAddingDescriptors() - throws IOException { - new RequestFieldsSnippet(Arrays.asList(fieldWithPath("b").description("Field b")), - true).andWithPrefix("c.", fieldWithPath("d").description("Field d")) - .document(this.operationBuilder.request("http://localhost") - .content("{\"a\":5,\"b\":4,\"c\":{\"d\": 3}}").build()); - assertThat(this.generatedSnippets.requestFields()) - .is(tableWithHeader("Path", "Type", "Description") - .row("`b`", "`Number`", "Field b") - .row("`c.d`", "`Number`", "Field d")); + public void allUndocumentedFieldsContinueToBeIgnoredAfterAddingDescriptors() throws IOException { + new RequestFieldsSnippet(Arrays.asList(fieldWithPath("b").description("Field b")), true) + .andWithPrefix("c.", fieldWithPath("d").description("Field d")).document(this.operationBuilder + .request("http://localhost").content("{\"a\":5,\"b\":4,\"c\":{\"d\": 3}}").build()); + assertThat(this.generatedSnippets.requestFields()).is(tableWithHeader("Path", "Type", "Description") + .row("`b`", "`Number`", "Field b").row("`c.d`", "`Number`", "Field d")); } @Test public void missingOptionalRequestField() throws IOException { - new RequestFieldsSnippet(Arrays.asList(fieldWithPath("a.b").description("one") - .type(JsonFieldType.STRING).optional())) - .document(this.operationBuilder.request("http://localhost") - .content("{}").build()); + new RequestFieldsSnippet( + Arrays.asList(fieldWithPath("a.b").description("one").type(JsonFieldType.STRING).optional())) + .document(this.operationBuilder.request("http://localhost").content("{}").build()); assertThat(this.generatedSnippets.requestFields()) - .is(tableWithHeader("Path", "Type", "Description").row("`a.b`", - "`String`", "one")); + .is(tableWithHeader("Path", "Type", "Description").row("`a.b`", "`String`", "one")); } @Test - public void missingIgnoredOptionalRequestFieldDoesNotRequireAType() - throws IOException { - new RequestFieldsSnippet(Arrays - .asList(fieldWithPath("a.b").description("one").ignored().optional())) - .document(this.operationBuilder.request("http://localhost") - .content("{}").build()); - assertThat(this.generatedSnippets.requestFields()) - .is(tableWithHeader("Path", "Type", "Description")); + public void missingIgnoredOptionalRequestFieldDoesNotRequireAType() throws IOException { + new RequestFieldsSnippet(Arrays.asList(fieldWithPath("a.b").description("one").ignored().optional())) + .document(this.operationBuilder.request("http://localhost").content("{}").build()); + assertThat(this.generatedSnippets.requestFields()).is(tableWithHeader("Path", "Type", "Description")); } @Test public void presentOptionalRequestField() throws IOException { - new RequestFieldsSnippet(Arrays.asList(fieldWithPath("a.b").description("one") - .type(JsonFieldType.STRING).optional())) + new RequestFieldsSnippet( + Arrays.asList(fieldWithPath("a.b").description("one").type(JsonFieldType.STRING).optional())) .document(this.operationBuilder.request("http://localhost") .content("{\"a\": { \"b\": \"bravo\"}}").build()); assertThat(this.generatedSnippets.requestFields()) - .is(tableWithHeader("Path", "Type", "Description").row("`a.b`", - "`String`", "one")); + .is(tableWithHeader("Path", "Type", "Description").row("`a.b`", "`String`", "one")); } @Test @@ -234,16 +194,11 @@ public void requestFieldsWithCustomAttributes() throws IOException { TemplateResourceResolver resolver = mock(TemplateResourceResolver.class); given(resolver.resolveTemplateResource("request-fields")) .willReturn(snippetResource("request-fields-with-title")); - new RequestFieldsSnippet( - Arrays.asList(fieldWithPath("a").description("one")), attributes( - key("title").value("Custom title"))) - .document( - this.operationBuilder - .attribute(TemplateEngine.class.getName(), - new MustacheTemplateEngine( - resolver)) - .request("http://localhost") - .content("{\"a\": \"foo\"}").build()); + new RequestFieldsSnippet(Arrays.asList(fieldWithPath("a").description("one")), + attributes(key("title").value("Custom title"))) + .document(this.operationBuilder + .attribute(TemplateEngine.class.getName(), new MustacheTemplateEngine(resolver)) + .request("http://localhost").content("{\"a\": \"foo\"}").build()); assertThat(this.generatedSnippets.requestFields()).contains("Custom title"); } @@ -252,47 +207,33 @@ public void requestFieldsWithCustomDescriptorAttributes() throws IOException { TemplateResourceResolver resolver = mock(TemplateResourceResolver.class); given(resolver.resolveTemplateResource("request-fields")) .willReturn(snippetResource("request-fields-with-extra-column")); - new RequestFieldsSnippet(Arrays.asList( - fieldWithPath("a.b").description("one") - .attributes(key("foo").value("alpha")), - fieldWithPath("a.c").description("two") - .attributes(key("foo").value("bravo")), - fieldWithPath("a").description("three") - .attributes(key("foo").value("charlie")))) + new RequestFieldsSnippet( + Arrays.asList(fieldWithPath("a.b").description("one").attributes(key("foo").value("alpha")), + fieldWithPath("a.c").description("two").attributes(key("foo").value("bravo")), + fieldWithPath("a").description("three").attributes(key("foo").value("charlie")))) .document(this.operationBuilder - .attribute(TemplateEngine.class.getName(), - new MustacheTemplateEngine(resolver)) - .request("http://localhost") - .content( - "{\"a\": {\"b\": 5, \"c\": \"charlie\"}}") + .attribute(TemplateEngine.class.getName(), new MustacheTemplateEngine(resolver)) + .request("http://localhost").content("{\"a\": {\"b\": 5, \"c\": \"charlie\"}}") .build()); assertThat(this.generatedSnippets.requestFields()) - .is(tableWithHeader("Path", "Type", "Description", "Foo") - .row("a.b", "Number", "one", "alpha") - .row("a.c", "String", "two", "bravo") - .row("a", "Object", "three", "charlie")); + .is(tableWithHeader("Path", "Type", "Description", "Foo").row("a.b", "Number", "one", "alpha") + .row("a.c", "String", "two", "bravo").row("a", "Object", "three", "charlie")); } @Test public void fieldWithExplictExactlyMatchingType() throws IOException { - new RequestFieldsSnippet(Arrays - .asList(fieldWithPath("a").description("one").type(JsonFieldType.NUMBER))) - .document(this.operationBuilder.request("http://localhost") - .content("{\"a\": 5 }").build()); + new RequestFieldsSnippet(Arrays.asList(fieldWithPath("a").description("one").type(JsonFieldType.NUMBER))) + .document(this.operationBuilder.request("http://localhost").content("{\"a\": 5 }").build()); assertThat(this.generatedSnippets.requestFields()) - .is(tableWithHeader("Path", "Type", "Description").row("`a`", "`Number`", - "one")); + .is(tableWithHeader("Path", "Type", "Description").row("`a`", "`Number`", "one")); } @Test public void fieldWithExplictVariesType() throws IOException { - new RequestFieldsSnippet(Arrays - .asList(fieldWithPath("a").description("one").type(JsonFieldType.VARIES))) - .document(this.operationBuilder.request("http://localhost") - .content("{\"a\": 5 }").build()); + new RequestFieldsSnippet(Arrays.asList(fieldWithPath("a").description("one").type(JsonFieldType.VARIES))) + .document(this.operationBuilder.request("http://localhost").content("{\"a\": 5 }").build()); assertThat(this.generatedSnippets.requestFields()) - .is(tableWithHeader("Path", "Type", "Description").row("`a`", "`Varies`", - "one")); + .is(tableWithHeader("Path", "Type", "Description").row("`a`", "`Varies`", "one")); } @Test @@ -311,128 +252,95 @@ public void customXmlRequestFields() throws IOException { } private void xmlRequestFields(MediaType contentType) throws IOException { - new RequestFieldsSnippet(Arrays.asList( - fieldWithPath("a/b").description("one").type("b"), - fieldWithPath("a/c").description("two").type("c"), - fieldWithPath("a").description("three").type("a"))) + new RequestFieldsSnippet(Arrays.asList(fieldWithPath("a/b").description("one").type("b"), + fieldWithPath("a/c").description("two").type("c"), fieldWithPath("a").description("three").type("a"))) .document(this.operationBuilder.request("http://localhost") .content("5charlie") - .header(HttpHeaders.CONTENT_TYPE, contentType.toString()) - .build()); - assertThat(this.generatedSnippets.requestFields()).is( - tableWithHeader("Path", "Type", "Description").row("`a/b`", "`b`", "one") - .row("`a/c`", "`c`", "two").row("`a`", "`a`", "three")); + .header(HttpHeaders.CONTENT_TYPE, contentType.toString()).build()); + assertThat(this.generatedSnippets.requestFields()).is(tableWithHeader("Path", "Type", "Description") + .row("`a/b`", "`b`", "one").row("`a/c`", "`c`", "two").row("`a`", "`a`", "three")); } @Test public void entireSubsectionOfXmlPayloadCanBeDocumented() throws IOException { - new RequestFieldsSnippet( - Arrays.asList(subsectionWithPath("a").description("one").type("a"))) - .document(this.operationBuilder.request("http://localhost") - .content("5charlie") - .header(HttpHeaders.CONTENT_TYPE, - MediaType.APPLICATION_XML_VALUE) - .build()); - assertThat(this.generatedSnippets.requestFields()).is( - tableWithHeader("Path", "Type", "Description").row("`a`", "`a`", "one")); + new RequestFieldsSnippet(Arrays.asList(subsectionWithPath("a").description("one").type("a"))) + .document(this.operationBuilder.request("http://localhost").content("5charlie") + .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_XML_VALUE).build()); + assertThat(this.generatedSnippets.requestFields()) + .is(tableWithHeader("Path", "Type", "Description").row("`a`", "`a`", "one")); } @Test public void additionalDescriptors() throws IOException { PayloadDocumentation - .requestFields(fieldWithPath("a.b").description("one"), - fieldWithPath("a.c").description("two")) - .and(fieldWithPath("a").description("three")) - .document(this.operationBuilder.request("http://localhost") + .requestFields(fieldWithPath("a.b").description("one"), fieldWithPath("a.c").description("two")) + .and(fieldWithPath("a").description("three")).document(this.operationBuilder.request("http://localhost") .content("{\"a\": {\"b\": 5, \"c\": \"charlie\"}}").build()); - assertThat(this.generatedSnippets.requestFields()) - .is(tableWithHeader("Path", "Type", "Description") - .row("`a.b`", "`Number`", "one").row("`a.c`", "`String`", "two") - .row("`a`", "`Object`", "three")); + assertThat(this.generatedSnippets.requestFields()).is(tableWithHeader("Path", "Type", "Description") + .row("`a.b`", "`Number`", "one").row("`a.c`", "`String`", "two").row("`a`", "`Object`", "three")); } @Test public void prefixedAdditionalDescriptors() throws IOException { PayloadDocumentation.requestFields(fieldWithPath("a").description("one")) - .andWithPrefix("a.", fieldWithPath("b").description("two"), - fieldWithPath("c").description("three")) + .andWithPrefix("a.", fieldWithPath("b").description("two"), fieldWithPath("c").description("three")) .document(this.operationBuilder.request("http://localhost") .content("{\"a\": {\"b\": 5, \"c\": \"charlie\"}}").build()); - assertThat(this.generatedSnippets.requestFields()) - .is(tableWithHeader("Path", "Type", "Description") - .row("`a`", "`Object`", "one").row("`a.b`", "`Number`", "two") - .row("`a.c`", "`String`", "three")); + assertThat(this.generatedSnippets.requestFields()).is(tableWithHeader("Path", "Type", "Description") + .row("`a`", "`Object`", "one").row("`a.b`", "`Number`", "two").row("`a.c`", "`String`", "three")); } @Test public void requestWithFieldsWithEscapedContent() throws IOException { - new RequestFieldsSnippet(Arrays.asList( - fieldWithPath("Foo|Bar").type("one|two").description("three|four"))) - .document(this.operationBuilder.request("http://localhost") - .content("{\"Foo|Bar\": 5}").build()); - assertThat(this.generatedSnippets.requestFields()) - .is(tableWithHeader("Path", "Type", "Description").row( - escapeIfNecessary("`Foo|Bar`"), escapeIfNecessary("`one|two`"), - escapeIfNecessary("three|four"))); + new RequestFieldsSnippet(Arrays.asList(fieldWithPath("Foo|Bar").type("one|two").description("three|four"))) + .document(this.operationBuilder.request("http://localhost").content("{\"Foo|Bar\": 5}").build()); + assertThat(this.generatedSnippets.requestFields()).is(tableWithHeader("Path", "Type", "Description") + .row(escapeIfNecessary("`Foo|Bar`"), escapeIfNecessary("`one|two`"), escapeIfNecessary("three|four"))); } @Test public void mapRequestWithVaryingKeysMatchedUsingWildcard() throws IOException { - new RequestFieldsSnippet( - Arrays.asList(fieldWithPath("things.*.size").description("one"), - fieldWithPath("things.*.type").description("two"))).document( - this.operationBuilder.request("http://localhost") - .content("{\"things\": {\"12abf\": {\"type\":" - + "\"Whale\", \"size\": \"HUGE\"}," - + "\"gzM33\" : {\"type\": \"Screw\"," - + "\"size\": \"SMALL\"}}}") - .build()); - assertThat(this.generatedSnippets.requestFields()) - .is(tableWithHeader("Path", "Type", "Description") - .row("`things.*.size`", "`String`", "one") - .row("`things.*.type`", "`String`", "two")); + new RequestFieldsSnippet(Arrays.asList(fieldWithPath("things.*.size").description("one"), + fieldWithPath("things.*.type").description("two"))) + .document(this.operationBuilder.request("http://localhost") + .content("{\"things\": {\"12abf\": {\"type\":" + "\"Whale\", \"size\": \"HUGE\"}," + + "\"gzM33\" : {\"type\": \"Screw\"," + "\"size\": \"SMALL\"}}}") + .build()); + assertThat(this.generatedSnippets.requestFields()).is(tableWithHeader("Path", "Type", "Description") + .row("`things.*.size`", "`String`", "one").row("`things.*.type`", "`String`", "two")); } @Test public void requestWithArrayContainingFieldThatIsSometimesNull() throws IOException { - new RequestFieldsSnippet(Arrays.asList(fieldWithPath("assets[].name") - .description("one").type(JsonFieldType.STRING).optional())) - .document(this.operationBuilder.request("http://localhost") - .content("{\"assets\": [" + "{\"name\": \"sample1\"}, " - + "{\"name\": null}, " - + "{\"name\": \"sample2\"}]}") + new RequestFieldsSnippet( + Arrays.asList(fieldWithPath("assets[].name").description("one").type(JsonFieldType.STRING).optional())) + .document(this.operationBuilder.request("http://localhost").content("{\"assets\": [" + + "{\"name\": \"sample1\"}, " + "{\"name\": null}, " + "{\"name\": \"sample2\"}]}") .build()); assertThat(this.generatedSnippets.requestFields()) - .is(tableWithHeader("Path", "Type", "Description").row("`assets[].name`", - "`String`", "one")); + .is(tableWithHeader("Path", "Type", "Description").row("`assets[].name`", "`String`", "one")); } @Test public void optionalFieldBeneathArrayThatIsSometimesAbsent() throws IOException { - new RequestFieldsSnippet(Arrays.asList( - fieldWithPath("a[].b").description("one").type(JsonFieldType.NUMBER) - .optional(), - fieldWithPath("a[].c").description("two").type(JsonFieldType.NUMBER))) - .document( - this.operationBuilder.request("http://localhost") - .content("{\"a\":[{\"b\": 1,\"c\": 2}, " - + "{\"c\": 2}, {\"b\": 1,\"c\": 2}]}") + new RequestFieldsSnippet( + Arrays.asList(fieldWithPath("a[].b").description("one").type(JsonFieldType.NUMBER).optional(), + fieldWithPath("a[].c").description("two").type(JsonFieldType.NUMBER))) + .document(this.operationBuilder.request("http://localhost") + .content("{\"a\":[{\"b\": 1,\"c\": 2}, " + "{\"c\": 2}, {\"b\": 1,\"c\": 2}]}") .build()); - assertThat(this.generatedSnippets.requestFields()) - .is(tableWithHeader("Path", "Type", "Description") - .row("`a[].b`", "`Number`", "one") - .row("`a[].c`", "`Number`", "two")); + assertThat(this.generatedSnippets.requestFields()).is(tableWithHeader("Path", "Type", "Description") + .row("`a[].b`", "`Number`", "one").row("`a[].c`", "`Number`", "two")); } @Test public void typeDeterminationDoesNotSetTypeOnDescriptor() throws IOException { FieldDescriptor descriptor = fieldWithPath("a.b").description("one"); - new RequestFieldsSnippet(Arrays.asList(descriptor)).document(this.operationBuilder - .request("http://localhost").content("{\"a\": {\"b\": 5}}").build()); + new RequestFieldsSnippet(Arrays.asList(descriptor)) + .document(this.operationBuilder.request("http://localhost").content("{\"a\": {\"b\": 5}}").build()); assertThat(descriptor.getType()).isNull(); assertThat(this.generatedSnippets.requestFields()) - .is(tableWithHeader("Path", "Type", "Description").row("`a.b`", - "`Number`", "one")); + .is(tableWithHeader("Path", "Type", "Description").row("`a.b`", "`Number`", "one")); } private String escapeIfNecessary(String input) { diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/RequestPartFieldsSnippetFailureTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/RequestPartFieldsSnippetFailureTests.java index 360f32276..13427f25d 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/RequestPartFieldsSnippetFailureTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/RequestPartFieldsSnippetFailureTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2016 the original author or authors. + * Copyright 2014-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. @@ -42,8 +42,7 @@ public class RequestPartFieldsSnippetFailureTests { @Rule - public OperationBuilder operationBuilder = new OperationBuilder( - TemplateFormats.asciidoctor()); + public OperationBuilder operationBuilder = new OperationBuilder(TemplateFormats.asciidoctor()); @Rule public ExpectedException thrown = ExpectedException.none(); @@ -51,33 +50,26 @@ public class RequestPartFieldsSnippetFailureTests { @Test public void undocumentedRequestPartField() throws IOException { this.thrown.expect(SnippetException.class); - this.thrown.expectMessage( - startsWith("The following parts of the payload were not documented:")); - new RequestPartFieldsSnippet("part", Collections.emptyList()) - .document(this.operationBuilder.request("http://localhost") - .part("part", "{\"a\": 5}".getBytes()).build()); + this.thrown.expectMessage(startsWith("The following parts of the payload were not documented:")); + new RequestPartFieldsSnippet("part", Collections.emptyList()).document( + this.operationBuilder.request("http://localhost").part("part", "{\"a\": 5}".getBytes()).build()); } @Test public void missingRequestPartField() throws IOException { this.thrown.expect(SnippetException.class); - this.thrown.expectMessage( - startsWith("The following parts of the payload were not documented:")); - new RequestPartFieldsSnippet("part", - Arrays.asList(fieldWithPath("b").description("one"))) - .document(this.operationBuilder.request("http://localhost") - .part("part", "{\"a\": 5}".getBytes()).build()); + this.thrown.expectMessage(startsWith("The following parts of the payload were not documented:")); + new RequestPartFieldsSnippet("part", Arrays.asList(fieldWithPath("b").description("one"))).document( + this.operationBuilder.request("http://localhost").part("part", "{\"a\": 5}".getBytes()).build()); } @Test public void missingRequestPart() throws IOException { this.thrown.expect(SnippetException.class); - this.thrown.expectMessage( - equalTo("A request part named 'another' was not found in the request")); - new RequestPartFieldsSnippet("another", - Arrays.asList(fieldWithPath("a.b").description("one"))) - .document(this.operationBuilder.request("http://localhost") - .part("part", "{\"a\": {\"b\": 5}}".getBytes()).build()); + this.thrown.expectMessage(equalTo("A request part named 'another' was not found in the request")); + new RequestPartFieldsSnippet("another", Arrays.asList(fieldWithPath("a.b").description("one"))) + .document(this.operationBuilder.request("http://localhost") + .part("part", "{\"a\": {\"b\": 5}}".getBytes()).build()); } } diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/RequestPartFieldsSnippetTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/RequestPartFieldsSnippetTests.java index fef2f08fa..666db4770 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/RequestPartFieldsSnippetTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/RequestPartFieldsSnippetTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-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. @@ -44,53 +44,43 @@ public RequestPartFieldsSnippetTests(String name, TemplateFormat templateFormat) @Test public void mapRequestPartFields() throws IOException { - new RequestPartFieldsSnippet("one", Arrays.asList( - fieldWithPath("a.b").description("one"), - fieldWithPath("a.c").description("two"), - fieldWithPath("a").description("three"))).document(this.operationBuilder - .request("http://localhost") - .part("one", "{\"a\": {\"b\": 5, \"c\": \"charlie\"}}".getBytes()) - .build()); - assertThat(this.generatedSnippets.requestPartFields("one")) - .is(tableWithHeader("Path", "Type", "Description") - .row("`a.b`", "`Number`", "one").row("`a.c`", "`String`", "two") - .row("`a`", "`Object`", "three")); + new RequestPartFieldsSnippet("one", + Arrays.asList(fieldWithPath("a.b").description("one"), fieldWithPath("a.c").description("two"), + fieldWithPath("a").description("three"))) + .document(this.operationBuilder.request("http://localhost") + .part("one", "{\"a\": {\"b\": 5, \"c\": \"charlie\"}}".getBytes()).build()); + assertThat(this.generatedSnippets.requestPartFields("one")).is(tableWithHeader("Path", "Type", "Description") + .row("`a.b`", "`Number`", "one").row("`a.c`", "`String`", "two").row("`a`", "`Object`", "three")); } @Test public void mapRequestPartSubsectionFields() throws IOException { - new RequestPartFieldsSnippet("one", beneathPath("a"), Arrays.asList( - fieldWithPath("b").description("one"), - fieldWithPath("c").description("two"))).document(this.operationBuilder - .request("http://localhost") - .part("one", "{\"a\": {\"b\": 5, \"c\": \"charlie\"}}".getBytes()) - .build()); + new RequestPartFieldsSnippet("one", beneathPath("a"), + Arrays.asList(fieldWithPath("b").description("one"), fieldWithPath("c").description("two"))) + .document(this.operationBuilder.request("http://localhost") + .part("one", "{\"a\": {\"b\": 5, \"c\": \"charlie\"}}".getBytes()).build()); assertThat(this.generatedSnippets.snippet("request-part-one-fields-beneath-a")) - .is(tableWithHeader("Path", "Type", "Description") - .row("`b`", "`Number`", "one").row("`c`", "`String`", "two")); + .is(tableWithHeader("Path", "Type", "Description").row("`b`", "`Number`", "one").row("`c`", "`String`", + "two")); } @Test public void multipleRequestParts() throws IOException { - Operation operation = this.operationBuilder.request("http://localhost") - .part("one", "{}".getBytes()).and().part("two", "{}".getBytes()).build(); - new RequestPartFieldsSnippet("one", Collections.emptyList()) - .document(operation); - new RequestPartFieldsSnippet("two", Collections.emptyList()) - .document(operation); + Operation operation = this.operationBuilder.request("http://localhost").part("one", "{}".getBytes()).and() + .part("two", "{}".getBytes()).build(); + new RequestPartFieldsSnippet("one", Collections.emptyList()).document(operation); + new RequestPartFieldsSnippet("two", Collections.emptyList()).document(operation); assertThat(this.generatedSnippets.requestPartFields("one")).isNotNull(); assertThat(this.generatedSnippets.requestPartFields("two")).isNotNull(); } @Test public void allUndocumentedRequestPartFieldsCanBeIgnored() throws IOException { - new RequestPartFieldsSnippet("one", - Arrays.asList(fieldWithPath("b").description("Field b")), true) - .document(this.operationBuilder.request("http://localhost") - .part("one", "{\"a\": 5, \"b\": 4}".getBytes()).build()); + new RequestPartFieldsSnippet("one", Arrays.asList(fieldWithPath("b").description("Field b")), true) + .document(this.operationBuilder.request("http://localhost") + .part("one", "{\"a\": 5, \"b\": 4}".getBytes()).build()); assertThat(this.generatedSnippets.requestPartFields("one")) - .is(tableWithHeader("Path", "Type", "Description").row("`b`", "`Number`", - "Field b")); + .is(tableWithHeader("Path", "Type", "Description").row("`b`", "`Number`", "Field b")); } @Test @@ -98,29 +88,20 @@ public void additionalDescriptors() throws IOException { PayloadDocumentation .requestPartFields("one", fieldWithPath("a.b").description("one"), fieldWithPath("a.c").description("two")) - .and(fieldWithPath("a").description("three")) - .document(this.operationBuilder.request("http://localhost") - .part("one", "{\"a\": {\"b\": 5, \"c\": \"charlie\"}}".getBytes()) - .build()); - assertThat(this.generatedSnippets.requestPartFields("one")) - .is(tableWithHeader("Path", "Type", "Description") - .row("`a.b`", "`Number`", "one").row("`a.c`", "`String`", "two") - .row("`a`", "`Object`", "three")); + .and(fieldWithPath("a").description("three")).document(this.operationBuilder.request("http://localhost") + .part("one", "{\"a\": {\"b\": 5, \"c\": \"charlie\"}}".getBytes()).build()); + assertThat(this.generatedSnippets.requestPartFields("one")).is(tableWithHeader("Path", "Type", "Description") + .row("`a.b`", "`Number`", "one").row("`a.c`", "`String`", "two").row("`a`", "`Object`", "three")); } @Test public void prefixedAdditionalDescriptors() throws IOException { - PayloadDocumentation - .requestPartFields("one", fieldWithPath("a").description("one")) - .andWithPrefix("a.", fieldWithPath("b").description("two"), - fieldWithPath("c").description("three")) + PayloadDocumentation.requestPartFields("one", fieldWithPath("a").description("one")) + .andWithPrefix("a.", fieldWithPath("b").description("two"), fieldWithPath("c").description("three")) .document(this.operationBuilder.request("http://localhost") - .part("one", "{\"a\": {\"b\": 5, \"c\": \"charlie\"}}".getBytes()) - .build()); - assertThat(this.generatedSnippets.requestPartFields("one")) - .is(tableWithHeader("Path", "Type", "Description") - .row("`a`", "`Object`", "one").row("`a.b`", "`Number`", "two") - .row("`a.c`", "`String`", "three")); + .part("one", "{\"a\": {\"b\": 5, \"c\": \"charlie\"}}".getBytes()).build()); + assertThat(this.generatedSnippets.requestPartFields("one")).is(tableWithHeader("Path", "Type", "Description") + .row("`a`", "`Object`", "one").row("`a.b`", "`Number`", "two").row("`a.c`", "`String`", "three")); } } diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/ResponseBodySnippetTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/ResponseBodySnippetTests.java index 57dfb3f73..078fe097c 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/ResponseBodySnippetTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/ResponseBodySnippetTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-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. @@ -47,8 +47,7 @@ public ResponseBodySnippetTests(String name, TemplateFormat templateFormat) { @Test public void responseWithBody() throws IOException { - new ResponseBodySnippet().document( - this.operationBuilder.response().content("some content").build()); + new ResponseBodySnippet().document(this.operationBuilder.response().content("some content").build()); assertThat(this.generatedSnippets.snippet("response-body")) .is(codeBlock(null, "nowrap").withContent("some content")); } @@ -56,14 +55,13 @@ public void responseWithBody() throws IOException { @Test public void responseWithNoBody() throws IOException { new ResponseBodySnippet().document(this.operationBuilder.response().build()); - assertThat(this.generatedSnippets.snippet("response-body")) - .is(codeBlock(null, "nowrap").withContent("")); + assertThat(this.generatedSnippets.snippet("response-body")).is(codeBlock(null, "nowrap").withContent("")); } @Test public void subsectionOfResponseBody() throws IOException { - responseBody(beneathPath("a.b")).document(this.operationBuilder.response() - .content("{\"a\":{\"b\":{\"c\":5}}}").build()); + responseBody(beneathPath("a.b")) + .document(this.operationBuilder.response().content("{\"a\":{\"b\":{\"c\":5}}}").build()); assertThat(this.generatedSnippets.snippet("response-body-beneath-a.b")) .is(codeBlock(null, "nowrap").withContent("{\"c\":5}")); } @@ -73,10 +71,8 @@ public void customSnippetAttributes() throws IOException { TemplateResourceResolver resolver = mock(TemplateResourceResolver.class); given(resolver.resolveTemplateResource("response-body")) .willReturn(snippetResource("response-body-with-language")); - new ResponseBodySnippet(attributes(key("language").value("json"))) - .document(this.operationBuilder - .attribute(TemplateEngine.class.getName(), - new MustacheTemplateEngine(resolver)) + new ResponseBodySnippet(attributes(key("language").value("json"))).document( + this.operationBuilder.attribute(TemplateEngine.class.getName(), new MustacheTemplateEngine(resolver)) .response().content("{\"a\":\"alpha\"}").build()); assertThat(this.generatedSnippets.snippet("response-body")) .is(codeBlock("json", "nowrap").withContent("{\"a\":\"alpha\"}")); diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/ResponseFieldsSnippetFailureTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/ResponseFieldsSnippetFailureTests.java index 4b93e6cb6..3b934f331 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/ResponseFieldsSnippetFailureTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/ResponseFieldsSnippetFailureTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-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. @@ -44,8 +44,7 @@ public class ResponseFieldsSnippetFailureTests { @Rule - public OperationBuilder operationBuilder = new OperationBuilder( - TemplateFormats.asciidoctor()); + public OperationBuilder operationBuilder = new OperationBuilder(TemplateFormats.asciidoctor()); @Rule public ExpectedException thrown = ExpectedException.none(); @@ -53,8 +52,7 @@ public class ResponseFieldsSnippetFailureTests { @Test public void attemptToDocumentFieldsWithNoResponseBody() throws IOException { this.thrown.expect(SnippetException.class); - this.thrown.expectMessage( - equalTo("Cannot document response fields as the response body is empty")); + this.thrown.expectMessage(equalTo("Cannot document response fields as the response body is empty")); new ResponseFieldsSnippet(Arrays.asList(fieldWithPath("a").description("one"))) .document(this.operationBuilder.build()); } @@ -62,65 +60,48 @@ public void attemptToDocumentFieldsWithNoResponseBody() throws IOException { @Test public void fieldWithExplicitTypeThatDoesNotMatchThePayload() throws IOException { this.thrown.expect(FieldTypesDoNotMatchException.class); - this.thrown.expectMessage(equalTo("The documented type of the field 'a' is" - + " Object but the actual type is Number")); - new ResponseFieldsSnippet(Arrays - .asList(fieldWithPath("a").description("one").type(JsonFieldType.OBJECT))) - .document(this.operationBuilder.response() - .content("{ \"a\": 5 }}").build()); + this.thrown.expectMessage( + equalTo("The documented type of the field 'a' is" + " Object but the actual type is Number")); + new ResponseFieldsSnippet(Arrays.asList(fieldWithPath("a").description("one").type(JsonFieldType.OBJECT))) + .document(this.operationBuilder.response().content("{ \"a\": 5 }}").build()); } @Test public void fieldWithExplicitSpecificTypeThatActuallyVaries() throws IOException { this.thrown.expect(FieldTypesDoNotMatchException.class); - this.thrown.expectMessage(equalTo("The documented type of the field '[].a' is" - + " Object but the actual type is Varies")); - new ResponseFieldsSnippet(Arrays.asList( - fieldWithPath("[].a").description("one").type(JsonFieldType.OBJECT))) - .document(this.operationBuilder.response() - .content("[{ \"a\": 5 },{ \"a\": \"b\" }]").build()); + this.thrown.expectMessage( + equalTo("The documented type of the field '[].a' is" + " Object but the actual type is Varies")); + new ResponseFieldsSnippet(Arrays.asList(fieldWithPath("[].a").description("one").type(JsonFieldType.OBJECT))) + .document(this.operationBuilder.response().content("[{ \"a\": 5 },{ \"a\": \"b\" }]").build()); } @Test public void undocumentedXmlResponseField() throws IOException { this.thrown.expect(SnippetException.class); - this.thrown.expectMessage(startsWith( - "The following parts of the payload were not" + " documented:")); - new ResponseFieldsSnippet(Collections.emptyList()) - .document(this.operationBuilder.response().content("5") - .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_XML_VALUE) - .build()); + this.thrown.expectMessage(startsWith("The following parts of the payload were not" + " documented:")); + new ResponseFieldsSnippet(Collections.emptyList()).document(this.operationBuilder.response() + .content("5").header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_XML_VALUE).build()); } @Test public void missingXmlAttribute() throws IOException { this.thrown.expect(SnippetException.class); - this.thrown.expectMessage(equalTo("Fields with the following paths were not found" - + " in the payload: [a/@id]")); - new ResponseFieldsSnippet( - Arrays.asList(fieldWithPath("a").description("one").type("b"), - fieldWithPath("a/@id").description("two").type("c"))) - .document( - this.operationBuilder.response() - .content("foo") - .header(HttpHeaders.CONTENT_TYPE, - MediaType.APPLICATION_XML_VALUE) - .build()); + this.thrown + .expectMessage(equalTo("Fields with the following paths were not found" + " in the payload: [a/@id]")); + new ResponseFieldsSnippet(Arrays.asList(fieldWithPath("a").description("one").type("b"), + fieldWithPath("a/@id").description("two").type("c"))) + .document(this.operationBuilder.response().content("foo") + .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_XML_VALUE).build()); } @Test public void documentedXmlAttributesAreRemoved() throws IOException { this.thrown.expect(SnippetException.class); - this.thrown.expectMessage(equalTo( - String.format("The following parts of the payload were not documented:" - + "%nbar%n"))); - new ResponseFieldsSnippet( - Arrays.asList(fieldWithPath("a/@id").description("one").type("a"))) - .document(this.operationBuilder.response() - .content("bar") - .header(HttpHeaders.CONTENT_TYPE, - MediaType.APPLICATION_XML_VALUE) - .build()); + this.thrown.expectMessage( + equalTo(String.format("The following parts of the payload were not documented:" + "%nbar%n"))); + new ResponseFieldsSnippet(Arrays.asList(fieldWithPath("a/@id").description("one").type("a"))) + .document(this.operationBuilder.response().content("bar") + .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_XML_VALUE).build()); } @Test @@ -128,78 +109,61 @@ public void xmlResponseFieldWithNoType() throws IOException { this.thrown.expect(FieldTypeRequiredException.class); new ResponseFieldsSnippet(Arrays.asList(fieldWithPath("a").description("one"))) .document(this.operationBuilder.response().content("5") - .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_XML_VALUE) - .build()); + .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_XML_VALUE).build()); } @Test public void missingXmlResponseField() throws IOException { this.thrown.expect(SnippetException.class); - this.thrown.expectMessage(equalTo("Fields with the following paths were not found" - + " in the payload: [a/b]")); - new ResponseFieldsSnippet(Arrays.asList(fieldWithPath("a/b").description("one"), - fieldWithPath("a").description("one"))).document(this.operationBuilder - .response().content("") - .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_XML_VALUE) - .build()); + this.thrown.expectMessage(equalTo("Fields with the following paths were not found" + " in the payload: [a/b]")); + new ResponseFieldsSnippet( + Arrays.asList(fieldWithPath("a/b").description("one"), fieldWithPath("a").description("one"))) + .document(this.operationBuilder.response().content("") + .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_XML_VALUE).build()); } @Test - public void undocumentedXmlResponseFieldAndMissingXmlResponseField() - throws IOException { + public void undocumentedXmlResponseFieldAndMissingXmlResponseField() throws IOException { this.thrown.expect(SnippetException.class); - this.thrown.expectMessage(startsWith( - "The following parts of the payload were not" + " documented:")); + this.thrown.expectMessage(startsWith("The following parts of the payload were not" + " documented:")); this.thrown - .expectMessage(endsWith("Fields with the following paths were not found" - + " in the payload: [a/b]")); + .expectMessage(endsWith("Fields with the following paths were not found" + " in the payload: [a/b]")); new ResponseFieldsSnippet(Arrays.asList(fieldWithPath("a/b").description("one"))) .document(this.operationBuilder.response().content("5") - .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_XML_VALUE) - .build()); + .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_XML_VALUE).build()); } @Test public void unsupportedContent() throws IOException { this.thrown.expect(PayloadHandlingException.class); - this.thrown.expectMessage(equalTo("Cannot handle text/plain content as it could" - + " not be parsed as JSON or XML")); - new ResponseFieldsSnippet(Collections.emptyList()) - .document(this.operationBuilder.response().content("Some plain text") - .header(HttpHeaders.CONTENT_TYPE, MediaType.TEXT_PLAIN_VALUE) - .build()); + this.thrown.expectMessage( + equalTo("Cannot handle text/plain content as it could" + " not be parsed as JSON or XML")); + new ResponseFieldsSnippet(Collections.emptyList()).document(this.operationBuilder.response() + .content("Some plain text").header(HttpHeaders.CONTENT_TYPE, MediaType.TEXT_PLAIN_VALUE).build()); } @Test public void nonOptionalFieldBeneathArrayThatIsSometimesNull() throws IOException { this.thrown.expect(SnippetException.class); - this.thrown.expectMessage(startsWith( - "Fields with the following paths were not found in the payload: " - + "[a[].b]")); - new ResponseFieldsSnippet(Arrays.asList( - fieldWithPath("a[].b").description("one").type(JsonFieldType.NUMBER), + this.thrown.expectMessage( + startsWith("Fields with the following paths were not found in the payload: " + "[a[].b]")); + new ResponseFieldsSnippet(Arrays.asList(fieldWithPath("a[].b").description("one").type(JsonFieldType.NUMBER), fieldWithPath("a[].c").description("two").type(JsonFieldType.NUMBER))) - .document(this.operationBuilder.response() - .content("{\"a\":[{\"b\": 1,\"c\": 2}, " - + "{\"b\": null, \"c\": 2}," - + " {\"b\": 1,\"c\": 2}]}") + .document(this.operationBuilder.response().content( + "{\"a\":[{\"b\": 1,\"c\": 2}, " + "{\"b\": null, \"c\": 2}," + " {\"b\": 1,\"c\": 2}]}") .build()); } @Test public void nonOptionalFieldBeneathArrayThatIsSometimesAbsent() throws IOException { this.thrown.expect(SnippetException.class); - this.thrown.expectMessage(startsWith( - "Fields with the following paths were not found in the payload: " - + "[a[].b]")); - new ResponseFieldsSnippet(Arrays.asList( - fieldWithPath("a[].b").description("one").type(JsonFieldType.NUMBER), + this.thrown.expectMessage( + startsWith("Fields with the following paths were not found in the payload: " + "[a[].b]")); + new ResponseFieldsSnippet(Arrays.asList(fieldWithPath("a[].b").description("one").type(JsonFieldType.NUMBER), fieldWithPath("a[].c").description("two").type(JsonFieldType.NUMBER))) - .document( - this.operationBuilder.response() - .content("{\"a\":[{\"b\": 1,\"c\": 2}, " - + "{\"c\": 2}, {\"b\": 1,\"c\": 2}]}") - .build()); + .document(this.operationBuilder.response() + .content("{\"a\":[{\"b\": 1,\"c\": 2}, " + "{\"c\": 2}, {\"b\": 1,\"c\": 2}]}") + .build()); } } diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/ResponseFieldsSnippetTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/ResponseFieldsSnippetTests.java index 7872c09a9..5747dca9a 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/ResponseFieldsSnippetTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/ResponseFieldsSnippetTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-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. @@ -53,45 +53,32 @@ public ResponseFieldsSnippetTests(String name, TemplateFormat templateFormat) { @Test public void mapResponseWithFields() throws IOException { new ResponseFieldsSnippet(Arrays.asList(fieldWithPath("id").description("one"), - fieldWithPath("date").description("two"), - fieldWithPath("assets").description("three"), - fieldWithPath("assets[]").description("four"), - fieldWithPath("assets[].id").description("five"), - fieldWithPath("assets[].name").description("six"))) - .document(this.operationBuilder.response() - .content( - "{\"id\": 67,\"date\": \"2015-01-20\",\"assets\":" - + " [{\"id\":356,\"name\": \"sample\"}]}") - .build()); - assertThat(this.generatedSnippets.responseFields()) - .is(tableWithHeader("Path", "Type", "Description") - .row("`id`", "`Number`", "one").row("`date`", "`String`", "two") - .row("`assets`", "`Array`", "three") - .row("`assets[]`", "`Array`", "four") - .row("`assets[].id`", "`Number`", "five") - .row("`assets[].name`", "`String`", "six")); + fieldWithPath("date").description("two"), fieldWithPath("assets").description("three"), + fieldWithPath("assets[]").description("four"), fieldWithPath("assets[].id").description("five"), + fieldWithPath("assets[].name").description("six"))).document( + this.operationBuilder.response().content("{\"id\": 67,\"date\": \"2015-01-20\",\"assets\":" + + " [{\"id\":356,\"name\": \"sample\"}]}").build()); + assertThat(this.generatedSnippets.responseFields()).is(tableWithHeader("Path", "Type", "Description") + .row("`id`", "`Number`", "one").row("`date`", "`String`", "two").row("`assets`", "`Array`", "three") + .row("`assets[]`", "`Array`", "four").row("`assets[].id`", "`Number`", "five") + .row("`assets[].name`", "`String`", "six")); } @Test public void mapResponseWithNullField() throws IOException { new ResponseFieldsSnippet(Arrays.asList(fieldWithPath("a.b").description("one"))) - .document(this.operationBuilder.response() - .content("{\"a\": {\"b\": null}}").build()); + .document(this.operationBuilder.response().content("{\"a\": {\"b\": null}}").build()); assertThat(this.generatedSnippets.responseFields()) - .is(tableWithHeader("Path", "Type", "Description").row("`a.b`", "`Null`", - "one")); + .is(tableWithHeader("Path", "Type", "Description").row("`a.b`", "`Null`", "one")); } @Test public void subsectionOfMapResponse() throws IOException { - responseFields(beneathPath("a"), fieldWithPath("b").description("one"), - fieldWithPath("c").description("two")) - .document(this.operationBuilder.response() - .content("{\"a\": {\"b\": 5, \"c\": \"charlie\"}}") - .build()); + responseFields(beneathPath("a"), fieldWithPath("b").description("one"), fieldWithPath("c").description("two")) + .document(this.operationBuilder.response().content("{\"a\": {\"b\": 5, \"c\": \"charlie\"}}").build()); assertThat(this.generatedSnippets.snippet("response-fields-beneath-a")) - .is(tableWithHeader("Path", "Type", "Description") - .row("`b`", "`Number`", "one").row("`c`", "`String`", "two")); + .is(tableWithHeader("Path", "Type", "Description").row("`b`", "`Number`", "one").row("`c`", "`String`", + "two")); } @Test @@ -102,94 +89,70 @@ public void subsectionOfMapResponseBeneathAnArray() throws IOException { "{\"a\": {\"b\": [{\"c\": 1, \"d\": [{\"e\": 5}]}, {\"c\": 3, \"d\": [{\"e\": 4}]}]}}") .build()); assertThat(this.generatedSnippets.snippet("response-fields-beneath-a.b.[]")) - .is(tableWithHeader("Path", "Type", "Description") - .row("`c`", "`Number`", "one") - .row("`d.[].e`", "`Number`", "two")); + .is(tableWithHeader("Path", "Type", "Description").row("`c`", "`Number`", "one").row("`d.[].e`", + "`Number`", "two")); } @Test public void subsectionOfMapResponseWithCommonsPrefix() throws IOException { - responseFields(beneathPath("a")) - .andWithPrefix("b.", fieldWithPath("c").description("two")) - .document(this.operationBuilder.response() - .content("{\"a\": {\"b\": {\"c\": \"charlie\"}}}").build()); + responseFields(beneathPath("a")).andWithPrefix("b.", fieldWithPath("c").description("two")) + .document(this.operationBuilder.response().content("{\"a\": {\"b\": {\"c\": \"charlie\"}}}").build()); assertThat(this.generatedSnippets.snippet("response-fields-beneath-a")) - .is(tableWithHeader("Path", "Type", "Description").row("`b.c`", - "`String`", "two")); + .is(tableWithHeader("Path", "Type", "Description").row("`b.c`", "`String`", "two")); } @Test public void arrayResponseWithFields() throws IOException { new ResponseFieldsSnippet(Arrays.asList(fieldWithPath("[]a.b").description("one"), - fieldWithPath("[]a.c").description("two"), - fieldWithPath("[]a").description("three"))) - .document(this.operationBuilder.response() - .content("[{\"a\": {\"b\": 5, \"c\":\"charlie\"}}," - + "{\"a\": {\"b\": 4, \"c\":\"chalk\"}}]") + fieldWithPath("[]a.c").description("two"), fieldWithPath("[]a").description("three"))) + .document(this.operationBuilder.response().content( + "[{\"a\": {\"b\": 5, \"c\":\"charlie\"}}," + "{\"a\": {\"b\": 4, \"c\":\"chalk\"}}]") .build()); - assertThat(this.generatedSnippets.responseFields()) - .is(tableWithHeader("Path", "Type", "Description") - .row("`[]a.b`", "`Number`", "one") - .row("`[]a.c`", "`String`", "two") - .row("`[]a`", "`Object`", "three")); + assertThat(this.generatedSnippets.responseFields()).is(tableWithHeader("Path", "Type", "Description") + .row("`[]a.b`", "`Number`", "one").row("`[]a.c`", "`String`", "two").row("`[]a`", "`Object`", "three")); } @Test public void arrayResponseWithAlwaysNullField() throws IOException { - new ResponseFieldsSnippet( - Arrays.asList(fieldWithPath("[]a.b").description("one"))) - .document(this.operationBuilder.response().content( - "[{\"a\": {\"b\": null}}," + "{\"a\": {\"b\": null}}]") - .build()); + new ResponseFieldsSnippet(Arrays.asList(fieldWithPath("[]a.b").description("one"))) + .document(this.operationBuilder.response() + .content("[{\"a\": {\"b\": null}}," + "{\"a\": {\"b\": null}}]").build()); assertThat(this.generatedSnippets.responseFields()) - .is(tableWithHeader("Path", "Type", "Description").row("`[]a.b`", - "`Null`", "one")); + .is(tableWithHeader("Path", "Type", "Description").row("`[]a.b`", "`Null`", "one")); } @Test public void arrayResponse() throws IOException { new ResponseFieldsSnippet(Arrays.asList(fieldWithPath("[]").description("one"))) - .document(this.operationBuilder.response() - .content("[\"a\", \"b\", \"c\"]").build()); + .document(this.operationBuilder.response().content("[\"a\", \"b\", \"c\"]").build()); assertThat(this.generatedSnippets.responseFields()) - .is(tableWithHeader("Path", "Type", "Description").row("`[]`", "`Array`", - "one")); + .is(tableWithHeader("Path", "Type", "Description").row("`[]`", "`Array`", "one")); } @Test public void ignoredResponseField() throws IOException { - new ResponseFieldsSnippet(Arrays.asList(fieldWithPath("a").ignored(), - fieldWithPath("b").description("Field b"))) - .document(this.operationBuilder.response() - .content("{\"a\": 5, \"b\": 4}").build()); + new ResponseFieldsSnippet( + Arrays.asList(fieldWithPath("a").ignored(), fieldWithPath("b").description("Field b"))) + .document(this.operationBuilder.response().content("{\"a\": 5, \"b\": 4}").build()); assertThat(this.generatedSnippets.responseFields()) - .is(tableWithHeader("Path", "Type", "Description").row("`b`", "`Number`", - "Field b")); + .is(tableWithHeader("Path", "Type", "Description").row("`b`", "`Number`", "Field b")); } @Test public void allUndocumentedFieldsCanBeIgnored() throws IOException { - new ResponseFieldsSnippet( - Arrays.asList(fieldWithPath("b").description("Field b")), true) - .document(this.operationBuilder.response() - .content("{\"a\": 5, \"b\": 4}").build()); + new ResponseFieldsSnippet(Arrays.asList(fieldWithPath("b").description("Field b")), true) + .document(this.operationBuilder.response().content("{\"a\": 5, \"b\": 4}").build()); assertThat(this.generatedSnippets.responseFields()) - .is(tableWithHeader("Path", "Type", "Description").row("`b`", "`Number`", - "Field b")); + .is(tableWithHeader("Path", "Type", "Description").row("`b`", "`Number`", "Field b")); } @Test - public void allUndocumentedFieldsContinueToBeIgnoredAfterAddingDescriptors() - throws IOException { - new ResponseFieldsSnippet( - Arrays.asList(fieldWithPath("b").description("Field b")), true) - .andWithPrefix("c.", fieldWithPath("d").description("Field d")) - .document(this.operationBuilder.response() - .content("{\"a\":5,\"b\":4,\"c\":{\"d\": 3}}").build()); - assertThat(this.generatedSnippets.responseFields()) - .is(tableWithHeader("Path", "Type", "Description") - .row("`b`", "`Number`", "Field b") - .row("`c.d`", "`Number`", "Field d")); + public void allUndocumentedFieldsContinueToBeIgnoredAfterAddingDescriptors() throws IOException { + new ResponseFieldsSnippet(Arrays.asList(fieldWithPath("b").description("Field b")), true) + .andWithPrefix("c.", fieldWithPath("d").description("Field d")) + .document(this.operationBuilder.response().content("{\"a\":5,\"b\":4,\"c\":{\"d\": 3}}").build()); + assertThat(this.generatedSnippets.responseFields()).is(tableWithHeader("Path", "Type", "Description") + .row("`b`", "`Number`", "Field b").row("`c.d`", "`Number`", "Field d")); } @Test @@ -197,48 +160,37 @@ public void responseFieldsWithCustomAttributes() throws IOException { TemplateResourceResolver resolver = mock(TemplateResourceResolver.class); given(resolver.resolveTemplateResource("response-fields")) .willReturn(snippetResource("response-fields-with-title")); - new ResponseFieldsSnippet( - Arrays.asList(fieldWithPath("a").description("one")), attributes( - key("title").value("Custom title"))) - .document( - this.operationBuilder - .attribute(TemplateEngine.class.getName(), - new MustacheTemplateEngine( - resolver)) - .response().content("{\"a\": \"foo\"}") - .build()); + new ResponseFieldsSnippet(Arrays.asList(fieldWithPath("a").description("one")), + attributes(key("title").value("Custom title"))) + .document(this.operationBuilder + .attribute(TemplateEngine.class.getName(), new MustacheTemplateEngine(resolver)) + .response().content("{\"a\": \"foo\"}").build()); assertThat(this.generatedSnippets.responseFields()).contains("Custom title"); } @Test public void missingOptionalResponseField() throws IOException { - new ResponseFieldsSnippet(Arrays.asList(fieldWithPath("a.b").description("one") - .type(JsonFieldType.STRING).optional())) + new ResponseFieldsSnippet( + Arrays.asList(fieldWithPath("a.b").description("one").type(JsonFieldType.STRING).optional())) .document(this.operationBuilder.response().content("{}").build()); assertThat(this.generatedSnippets.responseFields()) - .is(tableWithHeader("Path", "Type", "Description").row("`a.b`", - "`String`", "one")); + .is(tableWithHeader("Path", "Type", "Description").row("`a.b`", "`String`", "one")); } @Test - public void missingIgnoredOptionalResponseFieldDoesNotRequireAType() - throws IOException { - new ResponseFieldsSnippet(Arrays - .asList(fieldWithPath("a.b").description("one").ignored().optional())) - .document(this.operationBuilder.response().content("{}").build()); - assertThat(this.generatedSnippets.responseFields()) - .is(tableWithHeader("Path", "Type", "Description")); + public void missingIgnoredOptionalResponseFieldDoesNotRequireAType() throws IOException { + new ResponseFieldsSnippet(Arrays.asList(fieldWithPath("a.b").description("one").ignored().optional())) + .document(this.operationBuilder.response().content("{}").build()); + assertThat(this.generatedSnippets.responseFields()).is(tableWithHeader("Path", "Type", "Description")); } @Test public void presentOptionalResponseField() throws IOException { - new ResponseFieldsSnippet(Arrays.asList(fieldWithPath("a.b").description("one") - .type(JsonFieldType.STRING).optional())) - .document(this.operationBuilder.response() - .content("{\"a\": { \"b\": \"bravo\"}}").build()); + new ResponseFieldsSnippet( + Arrays.asList(fieldWithPath("a.b").description("one").type(JsonFieldType.STRING).optional())) + .document(this.operationBuilder.response().content("{\"a\": { \"b\": \"bravo\"}}").build()); assertThat(this.generatedSnippets.responseFields()) - .is(tableWithHeader("Path", "Type", "Description").row("`a.b`", - "`String`", "one")); + .is(tableWithHeader("Path", "Type", "Description").row("`a.b`", "`String`", "one")); } @Test @@ -246,47 +198,32 @@ public void responseFieldsWithCustomDescriptorAttributes() throws IOException { TemplateResourceResolver resolver = mock(TemplateResourceResolver.class); given(resolver.resolveTemplateResource("response-fields")) .willReturn(snippetResource("response-fields-with-extra-column")); - new ResponseFieldsSnippet(Arrays.asList( - fieldWithPath("a.b").description("one") - .attributes(key("foo").value("alpha")), - fieldWithPath("a.c").description("two") - .attributes(key("foo").value("bravo")), - fieldWithPath("a").description("three") - .attributes(key("foo").value("charlie")))) + new ResponseFieldsSnippet( + Arrays.asList(fieldWithPath("a.b").description("one").attributes(key("foo").value("alpha")), + fieldWithPath("a.c").description("two").attributes(key("foo").value("bravo")), + fieldWithPath("a").description("three").attributes(key("foo").value("charlie")))) .document(this.operationBuilder - .attribute(TemplateEngine.class.getName(), - new MustacheTemplateEngine(resolver)) - .response() - .content( - "{\"a\": {\"b\": 5, \"c\": \"charlie\"}}") - .build()); + .attribute(TemplateEngine.class.getName(), new MustacheTemplateEngine(resolver)) + .response().content("{\"a\": {\"b\": 5, \"c\": \"charlie\"}}").build()); assertThat(this.generatedSnippets.responseFields()) - .is(tableWithHeader("Path", "Type", "Description", "Foo") - .row("a.b", "Number", "one", "alpha") - .row("a.c", "String", "two", "bravo") - .row("a", "Object", "three", "charlie")); + .is(tableWithHeader("Path", "Type", "Description", "Foo").row("a.b", "Number", "one", "alpha") + .row("a.c", "String", "two", "bravo").row("a", "Object", "three", "charlie")); } @Test public void fieldWithExplictExactlyMatchingType() throws IOException { - new ResponseFieldsSnippet(Arrays - .asList(fieldWithPath("a").description("one").type(JsonFieldType.NUMBER))) - .document(this.operationBuilder.response().content("{\"a\": 5 }") - .build()); + new ResponseFieldsSnippet(Arrays.asList(fieldWithPath("a").description("one").type(JsonFieldType.NUMBER))) + .document(this.operationBuilder.response().content("{\"a\": 5 }").build()); assertThat(this.generatedSnippets.responseFields()) - .is(tableWithHeader("Path", "Type", "Description").row("`a`", "`Number`", - "one")); + .is(tableWithHeader("Path", "Type", "Description").row("`a`", "`Number`", "one")); } @Test public void fieldWithExplictVariesType() throws IOException { - new ResponseFieldsSnippet(Arrays - .asList(fieldWithPath("a").description("one").type(JsonFieldType.VARIES))) - .document(this.operationBuilder.response().content("{\"a\": 5 }") - .build()); + new ResponseFieldsSnippet(Arrays.asList(fieldWithPath("a").description("one").type(JsonFieldType.VARIES))) + .document(this.operationBuilder.response().content("{\"a\": 5 }").build()); assertThat(this.generatedSnippets.responseFields()) - .is(tableWithHeader("Path", "Type", "Description").row("`a`", "`Varies`", - "one")); + .is(tableWithHeader("Path", "Type", "Description").row("`a`", "`Varies`", "one")); } @Test @@ -305,167 +242,119 @@ public void customXmlResponseFields() throws IOException { } private void xmlResponseFields(MediaType contentType) throws IOException { - new ResponseFieldsSnippet(Arrays.asList( - fieldWithPath("a/b").description("one").type("b"), - fieldWithPath("a/c").description("two").type("c"), - fieldWithPath("a").description("three").type("a"))) - .document(this.operationBuilder.response() - .content("5charlie") - .header(HttpHeaders.CONTENT_TYPE, contentType.toString()) - .build()); - assertThat(this.generatedSnippets.responseFields()).is( - tableWithHeader("Path", "Type", "Description").row("`a/b`", "`b`", "one") - .row("`a/c`", "`c`", "two").row("`a`", "`a`", "three")); + new ResponseFieldsSnippet(Arrays.asList(fieldWithPath("a/b").description("one").type("b"), + fieldWithPath("a/c").description("two").type("c"), fieldWithPath("a").description("three").type("a"))) + .document(this.operationBuilder.response().content("5charlie") + .header(HttpHeaders.CONTENT_TYPE, contentType.toString()).build()); + assertThat(this.generatedSnippets.responseFields()).is(tableWithHeader("Path", "Type", "Description") + .row("`a/b`", "`b`", "one").row("`a/c`", "`c`", "two").row("`a`", "`a`", "three")); } @Test public void xmlAttribute() throws IOException { - new ResponseFieldsSnippet( - Arrays.asList(fieldWithPath("a").description("one").type("b"), - fieldWithPath("a/@id").description("two").type("c"))) - .document( - this.operationBuilder.response() - .content("foo") - .header(HttpHeaders.CONTENT_TYPE, - MediaType.APPLICATION_XML_VALUE) - .build()); - assertThat(this.generatedSnippets.responseFields()) - .is(tableWithHeader("Path", "Type", "Description") - .row("`a`", "`b`", "one").row("`a/@id`", "`c`", "two")); + new ResponseFieldsSnippet(Arrays.asList(fieldWithPath("a").description("one").type("b"), + fieldWithPath("a/@id").description("two").type("c"))) + .document(this.operationBuilder.response().content("foo") + .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_XML_VALUE).build()); + assertThat(this.generatedSnippets.responseFields()).is( + tableWithHeader("Path", "Type", "Description").row("`a`", "`b`", "one").row("`a/@id`", "`c`", "two")); } @Test public void missingOptionalXmlAttribute() throws IOException { - new ResponseFieldsSnippet( - Arrays.asList(fieldWithPath("a").description("one").type("b"), - fieldWithPath("a/@id").description("two").type("c").optional())) - .document( - this.operationBuilder.response() - .content("foo") - .header(HttpHeaders.CONTENT_TYPE, - MediaType.APPLICATION_XML_VALUE) - .build()); - assertThat(this.generatedSnippets.responseFields()) - .is(tableWithHeader("Path", "Type", "Description") - .row("`a`", "`b`", "one").row("`a/@id`", "`c`", "two")); + new ResponseFieldsSnippet(Arrays.asList(fieldWithPath("a").description("one").type("b"), + fieldWithPath("a/@id").description("two").type("c").optional())) + .document(this.operationBuilder.response().content("foo") + .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_XML_VALUE).build()); + assertThat(this.generatedSnippets.responseFields()).is( + tableWithHeader("Path", "Type", "Description").row("`a`", "`b`", "one").row("`a/@id`", "`c`", "two")); } @Test public void undocumentedAttributeDoesNotCauseFailure() throws IOException { - new ResponseFieldsSnippet( - Arrays.asList(fieldWithPath("a").description("one").type("a"))).document( - this.operationBuilder.response().content("bar") - .header(HttpHeaders.CONTENT_TYPE, - MediaType.APPLICATION_XML_VALUE) - .build()); - assertThat(this.generatedSnippets.responseFields()).is( - tableWithHeader("Path", "Type", "Description").row("`a`", "`a`", "one")); + new ResponseFieldsSnippet(Arrays.asList(fieldWithPath("a").description("one").type("a"))) + .document(this.operationBuilder.response().content("bar") + .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_XML_VALUE).build()); + assertThat(this.generatedSnippets.responseFields()) + .is(tableWithHeader("Path", "Type", "Description").row("`a`", "`a`", "one")); } @Test public void additionalDescriptors() throws IOException { PayloadDocumentation - .responseFields(fieldWithPath("id").description("one"), - fieldWithPath("date").description("two"), + .responseFields(fieldWithPath("id").description("one"), fieldWithPath("date").description("two"), fieldWithPath("assets").description("three")) - .and(fieldWithPath("assets[]").description("four"), - fieldWithPath("assets[].id").description("five"), + .and(fieldWithPath("assets[]").description("four"), fieldWithPath("assets[].id").description("five"), fieldWithPath("assets[].name").description("six")) - .document(this.operationBuilder.response() - .content("{\"id\": 67,\"date\": \"2015-01-20\",\"assets\":" - + " [{\"id\":356,\"name\": \"sample\"}]}") + .document(this.operationBuilder.response().content( + "{\"id\": 67,\"date\": \"2015-01-20\",\"assets\":" + " [{\"id\":356,\"name\": \"sample\"}]}") .build()); - assertThat(this.generatedSnippets.responseFields()) - .is(tableWithHeader("Path", "Type", "Description") - .row("`id`", "`Number`", "one").row("`date`", "`String`", "two") - .row("`assets`", "`Array`", "three") - .row("`assets[]`", "`Array`", "four") - .row("`assets[].id`", "`Number`", "five") - .row("`assets[].name`", "`String`", "six")); + assertThat(this.generatedSnippets.responseFields()).is(tableWithHeader("Path", "Type", "Description") + .row("`id`", "`Number`", "one").row("`date`", "`String`", "two").row("`assets`", "`Array`", "three") + .row("`assets[]`", "`Array`", "four").row("`assets[].id`", "`Number`", "five") + .row("`assets[].name`", "`String`", "six")); } @Test public void prefixedAdditionalDescriptors() throws IOException { PayloadDocumentation.responseFields(fieldWithPath("a").description("one")) - .andWithPrefix("a.", fieldWithPath("b").description("two"), - fieldWithPath("c").description("three")) - .document(this.operationBuilder.response() - .content("{\"a\": {\"b\": 5, \"c\": \"charlie\"}}").build()); - assertThat(this.generatedSnippets.responseFields()) - .is(tableWithHeader("Path", "Type", "Description") - .row("`a`", "`Object`", "one").row("`a.b`", "`Number`", "two") - .row("`a.c`", "`String`", "three")); + .andWithPrefix("a.", fieldWithPath("b").description("two"), fieldWithPath("c").description("three")) + .document(this.operationBuilder.response().content("{\"a\": {\"b\": 5, \"c\": \"charlie\"}}").build()); + assertThat(this.generatedSnippets.responseFields()).is(tableWithHeader("Path", "Type", "Description") + .row("`a`", "`Object`", "one").row("`a.b`", "`Number`", "two").row("`a.c`", "`String`", "three")); } @Test public void responseWithFieldsWithEscapedContent() throws IOException { - new ResponseFieldsSnippet(Arrays.asList( - fieldWithPath("Foo|Bar").type("one|two").description("three|four"))) - .document(this.operationBuilder.response() - .content("{\"Foo|Bar\": 5}").build()); - assertThat(this.generatedSnippets.responseFields()) - .is(tableWithHeader("Path", "Type", "Description").row( - escapeIfNecessary("`Foo|Bar`"), escapeIfNecessary("`one|two`"), - escapeIfNecessary("three|four"))); + new ResponseFieldsSnippet(Arrays.asList(fieldWithPath("Foo|Bar").type("one|two").description("three|four"))) + .document(this.operationBuilder.response().content("{\"Foo|Bar\": 5}").build()); + assertThat(this.generatedSnippets.responseFields()).is(tableWithHeader("Path", "Type", "Description") + .row(escapeIfNecessary("`Foo|Bar`"), escapeIfNecessary("`one|two`"), escapeIfNecessary("three|four"))); } @Test public void mapResponseWithVaryingKeysMatchedUsingWildcard() throws IOException { - new ResponseFieldsSnippet( - Arrays.asList(fieldWithPath("things.*.size").description("one"), - fieldWithPath("things.*.type").description("two"))) - .document(this.operationBuilder.response() - .content("{\"things\": {\"12abf\": {\"type\":" - + "\"Whale\", \"size\": \"HUGE\"}," - + "\"gzM33\" : {\"type\": \"Screw\"," - + "\"size\": \"SMALL\"}}}") - .build()); - assertThat(this.generatedSnippets.responseFields()) - .is(tableWithHeader("Path", "Type", "Description") - .row("`things.*.size`", "`String`", "one") - .row("`things.*.type`", "`String`", "two")); + new ResponseFieldsSnippet(Arrays.asList(fieldWithPath("things.*.size").description("one"), + fieldWithPath("things.*.type").description("two"))) + .document(this.operationBuilder.response() + .content("{\"things\": {\"12abf\": {\"type\":" + "\"Whale\", \"size\": \"HUGE\"}," + + "\"gzM33\" : {\"type\": \"Screw\"," + "\"size\": \"SMALL\"}}}") + .build()); + assertThat(this.generatedSnippets.responseFields()).is(tableWithHeader("Path", "Type", "Description") + .row("`things.*.size`", "`String`", "one").row("`things.*.type`", "`String`", "two")); } @Test public void responseWithArrayContainingFieldThatIsSometimesNull() throws IOException { - new ResponseFieldsSnippet(Arrays.asList(fieldWithPath("assets[].name") - .description("one").type(JsonFieldType.STRING).optional())) - .document(this.operationBuilder.response() - .content("{\"assets\": [" + "{\"name\": \"sample1\"}, " - + "{\"name\": null}, " - + "{\"name\": \"sample2\"}]}") - .build()); + new ResponseFieldsSnippet( + Arrays.asList(fieldWithPath("assets[].name").description("one").type(JsonFieldType.STRING).optional())) + .document( + this.operationBuilder.response().content("{\"assets\": [" + "{\"name\": \"sample1\"}, " + + "{\"name\": null}, " + "{\"name\": \"sample2\"}]}").build()); assertThat(this.generatedSnippets.responseFields()) - .is(tableWithHeader("Path", "Type", "Description").row("`assets[].name`", - "`String`", "one")); + .is(tableWithHeader("Path", "Type", "Description").row("`assets[].name`", "`String`", "one")); } @Test public void optionalFieldBeneathArrayThatIsSometimesAbsent() throws IOException { - new ResponseFieldsSnippet(Arrays.asList( - fieldWithPath("a[].b").description("one").type(JsonFieldType.NUMBER) - .optional(), - fieldWithPath("a[].c").description("two").type(JsonFieldType.NUMBER))) - .document( - this.operationBuilder.response() - .content("{\"a\":[{\"b\": 1,\"c\": 2}, " - + "{\"c\": 2}, {\"b\": 1,\"c\": 2}]}") + new ResponseFieldsSnippet( + Arrays.asList(fieldWithPath("a[].b").description("one").type(JsonFieldType.NUMBER).optional(), + fieldWithPath("a[].c").description("two").type(JsonFieldType.NUMBER))) + .document(this.operationBuilder.response() + .content("{\"a\":[{\"b\": 1,\"c\": 2}, " + "{\"c\": 2}, {\"b\": 1,\"c\": 2}]}") .build()); - assertThat(this.generatedSnippets.responseFields()) - .is(tableWithHeader("Path", "Type", "Description") - .row("`a[].b`", "`Number`", "one") - .row("`a[].c`", "`Number`", "two")); + assertThat(this.generatedSnippets.responseFields()).is(tableWithHeader("Path", "Type", "Description") + .row("`a[].b`", "`Number`", "one").row("`a[].c`", "`Number`", "two")); } @Test public void typeDeterminationDoesNotSetTypeOnDescriptor() throws IOException { FieldDescriptor descriptor = fieldWithPath("id").description("one"); - new ResponseFieldsSnippet(Arrays.asList(descriptor)).document( - this.operationBuilder.response().content("{\"id\": 67}").build()); + new ResponseFieldsSnippet(Arrays.asList(descriptor)) + .document(this.operationBuilder.response().content("{\"id\": 67}").build()); assertThat(descriptor.getType()).isNull(); assertThat(this.generatedSnippets.responseFields()) - .is(tableWithHeader("Path", "Type", "Description").row("`id`", "`Number`", - "one")); + .is(tableWithHeader("Path", "Type", "Description").row("`id`", "`Number`", "one")); } private String escapeIfNecessary(String input) { diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/XmlContentHandlerTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/XmlContentHandlerTests.java index 170a84bfd..240107f6a 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/XmlContentHandlerTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/XmlContentHandlerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-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. @@ -38,41 +38,36 @@ public class XmlContentHandlerTests { @Test public void topLevelElementCanBeDocumented() { - String undocumentedContent = createHandler("5").getUndocumentedContent( - Arrays.asList(fieldWithPath("a").type("a").description("description"))); + String undocumentedContent = createHandler("5") + .getUndocumentedContent(Arrays.asList(fieldWithPath("a").type("a").description("description"))); assertThat(undocumentedContent).isNull(); } @Test public void nestedElementCanBeDocumentedLeavingAncestors() { String undocumentedContent = createHandler("5") - .getUndocumentedContent(Arrays.asList( - fieldWithPath("a/b").type("b").description("description"))); + .getUndocumentedContent(Arrays.asList(fieldWithPath("a/b").type("b").description("description"))); assertThat(undocumentedContent).isEqualTo(String.format("%n")); } @Test public void fieldDescriptorDoesNotDocumentEntireSubsection() { String undocumentedContent = createHandler("5") - .getUndocumentedContent(Arrays - .asList(fieldWithPath("a").type("a").description("description"))); - assertThat(undocumentedContent) - .isEqualTo(String.format("%n 5%n%n")); + .getUndocumentedContent(Arrays.asList(fieldWithPath("a").type("a").description("description"))); + assertThat(undocumentedContent).isEqualTo(String.format("%n 5%n%n")); } @Test public void subsectionDescriptorDocumentsEntireSubsection() { String undocumentedContent = createHandler("5") - .getUndocumentedContent(Arrays.asList( - subsectionWithPath("a").type("a").description("description"))); + .getUndocumentedContent(Arrays.asList(subsectionWithPath("a").type("a").description("description"))); assertThat(undocumentedContent).isNull(); } @Test public void multipleElementsCanBeInDescendingOrderDocumented() { String undocumentedContent = createHandler("5") - .getUndocumentedContent(Arrays.asList( - fieldWithPath("a").type("a").description("description"), + .getUndocumentedContent(Arrays.asList(fieldWithPath("a").type("a").description("description"), fieldWithPath("a/b").type("b").description("description"))); assertThat(undocumentedContent).isNull(); } @@ -80,8 +75,7 @@ public void multipleElementsCanBeInDescendingOrderDocumented() { @Test public void multipleElementsCanBeInAscendingOrderDocumented() { String undocumentedContent = createHandler("5") - .getUndocumentedContent(Arrays.asList( - fieldWithPath("a/b").type("b").description("description"), + .getUndocumentedContent(Arrays.asList(fieldWithPath("a/b").type("b").description("description"), fieldWithPath("a").type("a").description("description"))); assertThat(undocumentedContent).isNull(); } diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/request/PathParametersSnippetFailureTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/request/PathParametersSnippetFailureTests.java index 45566ff71..b7a29b10f 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/request/PathParametersSnippetFailureTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/request/PathParametersSnippetFailureTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2016 the original author or authors. + * Copyright 2014-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. @@ -41,8 +41,7 @@ public class PathParametersSnippetFailureTests { @Rule - public OperationBuilder operationBuilder = new OperationBuilder( - TemplateFormats.asciidoctor()); + public OperationBuilder operationBuilder = new OperationBuilder(TemplateFormats.asciidoctor()); @Rule public ExpectedException thrown = ExpectedException.none(); @@ -50,25 +49,18 @@ public class PathParametersSnippetFailureTests { @Test public void undocumentedPathParameter() throws IOException { this.thrown.expect(SnippetException.class); - this.thrown.expectMessage(equalTo("Path parameters with the following names were" - + " not documented: [a]")); - new PathParametersSnippet(Collections.emptyList()) - .document(this.operationBuilder - .attribute(RestDocumentationGenerator.ATTRIBUTE_NAME_URL_TEMPLATE, - "/{a}/") - .build()); + this.thrown.expectMessage(equalTo("Path parameters with the following names were" + " not documented: [a]")); + new PathParametersSnippet(Collections.emptyList()).document(this.operationBuilder + .attribute(RestDocumentationGenerator.ATTRIBUTE_NAME_URL_TEMPLATE, "/{a}/").build()); } @Test public void missingPathParameter() throws IOException { this.thrown.expect(SnippetException.class); - this.thrown.expectMessage(equalTo("Path parameters with the following names were" - + " not found in the request: [a]")); - new PathParametersSnippet( - Arrays.asList(parameterWithName("a").description("one"))) - .document(this.operationBuilder.attribute( - RestDocumentationGenerator.ATTRIBUTE_NAME_URL_TEMPLATE, - "/").build()); + this.thrown.expectMessage( + equalTo("Path parameters with the following names were" + " not found in the request: [a]")); + new PathParametersSnippet(Arrays.asList(parameterWithName("a").description("one"))).document( + this.operationBuilder.attribute(RestDocumentationGenerator.ATTRIBUTE_NAME_URL_TEMPLATE, "/").build()); } @Test @@ -77,11 +69,9 @@ public void undocumentedAndMissingPathParameters() throws IOException { this.thrown.expectMessage(equalTo("Path parameters with the following names were" + " not documented: [b]. Path parameters with the following" + " names were not found in the request: [a]")); - new PathParametersSnippet( - Arrays.asList(parameterWithName("a").description("one"))) - .document(this.operationBuilder.attribute( - RestDocumentationGenerator.ATTRIBUTE_NAME_URL_TEMPLATE, - "/{b}").build()); + new PathParametersSnippet(Arrays.asList(parameterWithName("a").description("one"))) + .document(this.operationBuilder + .attribute(RestDocumentationGenerator.ATTRIBUTE_NAME_URL_TEMPLATE, "/{b}").build()); } } diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/request/PathParametersSnippetTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/request/PathParametersSnippetTests.java index 0c604dade..2f4b5bdc5 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/request/PathParametersSnippetTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/request/PathParametersSnippetTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-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. @@ -49,86 +49,73 @@ public PathParametersSnippetTests(String name, TemplateFormat templateFormat) { @Test public void pathParameters() throws IOException { - new PathParametersSnippet(Arrays.asList(parameterWithName("a").description("one"), - parameterWithName("b").description("two"))).document(this.operationBuilder - .attribute(RestDocumentationGenerator.ATTRIBUTE_NAME_URL_TEMPLATE, - "/{a}/{b}") - .build()); - assertThat(this.generatedSnippets.pathParameters()) - .is(tableWithTitleAndHeader(getTitle(), "Parameter", "Description") - .row("`a`", "one").row("`b`", "two")); + new PathParametersSnippet( + Arrays.asList(parameterWithName("a").description("one"), parameterWithName("b").description("two"))) + .document(this.operationBuilder + .attribute(RestDocumentationGenerator.ATTRIBUTE_NAME_URL_TEMPLATE, "/{a}/{b}").build()); + assertThat(this.generatedSnippets.pathParameters()).is( + tableWithTitleAndHeader(getTitle(), "Parameter", "Description").row("`a`", "one").row("`b`", "two")); } @Test public void ignoredPathParameter() throws IOException { - new PathParametersSnippet(Arrays.asList(parameterWithName("a").ignored(), - parameterWithName("b").description("two"))).document(this.operationBuilder - .attribute(RestDocumentationGenerator.ATTRIBUTE_NAME_URL_TEMPLATE, - "/{a}/{b}") - .build()); + new PathParametersSnippet( + Arrays.asList(parameterWithName("a").ignored(), parameterWithName("b").description("two"))) + .document(this.operationBuilder + .attribute(RestDocumentationGenerator.ATTRIBUTE_NAME_URL_TEMPLATE, "/{a}/{b}").build()); assertThat(this.generatedSnippets.pathParameters()) - .is(tableWithTitleAndHeader(getTitle(), "Parameter", "Description") - .row("`b`", "two")); + .is(tableWithTitleAndHeader(getTitle(), "Parameter", "Description").row("`b`", "two")); } @Test public void allUndocumentedPathParametersCanBeIgnored() throws IOException { - new PathParametersSnippet( - Arrays.asList(parameterWithName("b").description("two")), true) - .document(this.operationBuilder.attribute( - RestDocumentationGenerator.ATTRIBUTE_NAME_URL_TEMPLATE, - "/{a}/{b}").build()); + new PathParametersSnippet(Arrays.asList(parameterWithName("b").description("two")), true) + .document(this.operationBuilder + .attribute(RestDocumentationGenerator.ATTRIBUTE_NAME_URL_TEMPLATE, "/{a}/{b}").build()); assertThat(this.generatedSnippets.pathParameters()) - .is(tableWithTitleAndHeader(getTitle(), "Parameter", "Description") - .row("`b`", "two")); + .is(tableWithTitleAndHeader(getTitle(), "Parameter", "Description").row("`b`", "two")); } @Test public void missingOptionalPathParameter() throws IOException { new PathParametersSnippet(Arrays.asList(parameterWithName("a").description("one"), parameterWithName("b").description("two").optional())) - .document(this.operationBuilder.attribute( - RestDocumentationGenerator.ATTRIBUTE_NAME_URL_TEMPLATE, - "/{a}").build()); + .document(this.operationBuilder + .attribute(RestDocumentationGenerator.ATTRIBUTE_NAME_URL_TEMPLATE, "/{a}").build()); assertThat(this.generatedSnippets.pathParameters()) - .is(tableWithTitleAndHeader(getTitle("/{a}"), "Parameter", "Description") - .row("`a`", "one").row("`b`", "two")); + .is(tableWithTitleAndHeader(getTitle("/{a}"), "Parameter", "Description").row("`a`", "one").row("`b`", + "two")); } @Test public void presentOptionalPathParameter() throws IOException { - new PathParametersSnippet( - Arrays.asList(parameterWithName("a").description("one").optional())) - .document(this.operationBuilder.attribute( - RestDocumentationGenerator.ATTRIBUTE_NAME_URL_TEMPLATE, - "/{a}").build()); + new PathParametersSnippet(Arrays.asList(parameterWithName("a").description("one").optional())) + .document(this.operationBuilder + .attribute(RestDocumentationGenerator.ATTRIBUTE_NAME_URL_TEMPLATE, "/{a}").build()); assertThat(this.generatedSnippets.pathParameters()) - .is(tableWithTitleAndHeader(getTitle("/{a}"), "Parameter", "Description") - .row("`a`", "one")); + .is(tableWithTitleAndHeader(getTitle("/{a}"), "Parameter", "Description").row("`a`", "one")); } @Test public void pathParametersWithQueryString() throws IOException { - new PathParametersSnippet(Arrays.asList(parameterWithName("a").description("one"), - parameterWithName("b").description("two"))).document(this.operationBuilder - .attribute(RestDocumentationGenerator.ATTRIBUTE_NAME_URL_TEMPLATE, - "/{a}/{b}?foo=bar") - .build()); - assertThat(this.generatedSnippets.pathParameters()) - .is(tableWithTitleAndHeader(getTitle(), "Parameter", "Description") - .row("`a`", "one").row("`b`", "two")); + new PathParametersSnippet( + Arrays.asList(parameterWithName("a").description("one"), parameterWithName("b").description("two"))) + .document(this.operationBuilder + .attribute(RestDocumentationGenerator.ATTRIBUTE_NAME_URL_TEMPLATE, "/{a}/{b}?foo=bar") + .build()); + assertThat(this.generatedSnippets.pathParameters()).is( + tableWithTitleAndHeader(getTitle(), "Parameter", "Description").row("`a`", "one").row("`b`", "two")); } @Test public void pathParametersWithQueryStringWithParameters() throws IOException { - new PathParametersSnippet(Arrays.asList(parameterWithName("a").description("one"), - parameterWithName("b").description("two"))).document(this.operationBuilder - .attribute(RestDocumentationGenerator.ATTRIBUTE_NAME_URL_TEMPLATE, - "/{a}/{b}?foo={c}") - .build()); - assertThat(this.generatedSnippets.pathParameters()) - .is(tableWithTitleAndHeader(getTitle(), "Parameter", "Description") - .row("`a`", "one").row("`b`", "two")); + new PathParametersSnippet( + Arrays.asList(parameterWithName("a").description("one"), parameterWithName("b").description("two"))) + .document(this.operationBuilder + .attribute(RestDocumentationGenerator.ATTRIBUTE_NAME_URL_TEMPLATE, "/{a}/{b}?foo={c}") + .build()); + assertThat(this.generatedSnippets.pathParameters()).is( + tableWithTitleAndHeader(getTitle(), "Parameter", "Description").row("`a`", "one").row("`b`", "two")); } @Test @@ -137,17 +124,12 @@ public void pathParametersWithCustomAttributes() throws IOException { given(resolver.resolveTemplateResource("path-parameters")) .willReturn(snippetResource("path-parameters-with-title")); new PathParametersSnippet( - Arrays.asList( - parameterWithName("a").description("one") - .attributes(key("foo").value("alpha")), - parameterWithName("b").description("two") - .attributes(key("foo").value("bravo"))), + Arrays.asList(parameterWithName("a").description("one").attributes(key("foo").value("alpha")), + parameterWithName("b").description("two").attributes(key("foo").value("bravo"))), attributes(key("title").value("The title"))) - .document(this.operationBuilder.attribute( - RestDocumentationGenerator.ATTRIBUTE_NAME_URL_TEMPLATE, - "/{a}/{b}") - .attribute(TemplateEngine.class.getName(), - new MustacheTemplateEngine(resolver)) + .document(this.operationBuilder + .attribute(RestDocumentationGenerator.ATTRIBUTE_NAME_URL_TEMPLATE, "/{a}/{b}") + .attribute(TemplateEngine.class.getName(), new MustacheTemplateEngine(resolver)) .build()); assertThat(this.generatedSnippets.pathParameters()).contains("The title"); } @@ -157,46 +139,34 @@ public void pathParametersWithCustomDescriptorAttributes() throws IOException { TemplateResourceResolver resolver = mock(TemplateResourceResolver.class); given(resolver.resolveTemplateResource("path-parameters")) .willReturn(snippetResource("path-parameters-with-extra-column")); - new PathParametersSnippet(Arrays.asList( - parameterWithName("a").description("one") - .attributes(key("foo").value("alpha")), - parameterWithName("b").description("two").attributes(key("foo") - .value("bravo")))).document(this.operationBuilder.attribute( - RestDocumentationGenerator.ATTRIBUTE_NAME_URL_TEMPLATE, - "/{a}/{b}") - .attribute(TemplateEngine.class.getName(), - new MustacheTemplateEngine(resolver)) - .build()); - assertThat(this.generatedSnippets.pathParameters()) - .is(tableWithHeader("Parameter", "Description", "Foo") - .row("a", "one", "alpha").row("b", "two", "bravo")); + new PathParametersSnippet( + Arrays.asList(parameterWithName("a").description("one").attributes(key("foo").value("alpha")), + parameterWithName("b").description("two").attributes(key("foo").value("bravo")))) + .document(this.operationBuilder + .attribute(RestDocumentationGenerator.ATTRIBUTE_NAME_URL_TEMPLATE, "/{a}/{b}") + .attribute(TemplateEngine.class.getName(), new MustacheTemplateEngine(resolver)) + .build()); + assertThat(this.generatedSnippets.pathParameters()).is( + tableWithHeader("Parameter", "Description", "Foo").row("a", "one", "alpha").row("b", "two", "bravo")); } @Test public void additionalDescriptors() throws IOException { RequestDocumentation.pathParameters(parameterWithName("a").description("one")) - .and(parameterWithName("b").description("two")) - .document(this.operationBuilder - .attribute(RestDocumentationGenerator.ATTRIBUTE_NAME_URL_TEMPLATE, - "/{a}/{b}") - .build()); - assertThat(this.generatedSnippets.pathParameters()) - .is(tableWithTitleAndHeader(getTitle(), "Parameter", "Description") - .row("`a`", "one").row("`b`", "two")); + .and(parameterWithName("b").description("two")).document(this.operationBuilder + .attribute(RestDocumentationGenerator.ATTRIBUTE_NAME_URL_TEMPLATE, "/{a}/{b}").build()); + assertThat(this.generatedSnippets.pathParameters()).is( + tableWithTitleAndHeader(getTitle(), "Parameter", "Description").row("`a`", "one").row("`b`", "two")); } @Test public void pathParametersWithEscapedContent() throws IOException { - RequestDocumentation - .pathParameters(parameterWithName("Foo|Bar").description("one|two")) + RequestDocumentation.pathParameters(parameterWithName("Foo|Bar").description("one|two")) .document(this.operationBuilder - .attribute(RestDocumentationGenerator.ATTRIBUTE_NAME_URL_TEMPLATE, - "{Foo|Bar}") - .build()); - assertThat(this.generatedSnippets.pathParameters()).is( - tableWithTitleAndHeader(getTitle("{Foo|Bar}"), "Parameter", "Description") - .row(escapeIfNecessary("`Foo|Bar`"), - escapeIfNecessary("one|two"))); + .attribute(RestDocumentationGenerator.ATTRIBUTE_NAME_URL_TEMPLATE, "{Foo|Bar}").build()); + assertThat(this.generatedSnippets.pathParameters()) + .is(tableWithTitleAndHeader(getTitle("{Foo|Bar}"), "Parameter", "Description") + .row(escapeIfNecessary("`Foo|Bar`"), escapeIfNecessary("one|two"))); } private String escapeIfNecessary(String input) { diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/request/RequestParametersSnippetFailureTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/request/RequestParametersSnippetFailureTests.java index ff9824302..2410ca69b 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/request/RequestParametersSnippetFailureTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/request/RequestParametersSnippetFailureTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-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. @@ -40,8 +40,7 @@ public class RequestParametersSnippetFailureTests { @Rule - public OperationBuilder operationBuilder = new OperationBuilder( - TemplateFormats.asciidoctor()); + public OperationBuilder operationBuilder = new OperationBuilder(TemplateFormats.asciidoctor()); @Rule public ExpectedException thrown = ExpectedException.none(); @@ -49,36 +48,28 @@ public class RequestParametersSnippetFailureTests { @Test public void undocumentedParameter() throws IOException { this.thrown.expect(SnippetException.class); - this.thrown - .expectMessage(equalTo("Request parameters with the following names were" - + " not documented: [a]")); + this.thrown.expectMessage(equalTo("Request parameters with the following names were" + " not documented: [a]")); new RequestParametersSnippet(Collections.emptyList()) - .document(this.operationBuilder.request("http://localhost") - .param("a", "alpha").build()); + .document(this.operationBuilder.request("http://localhost").param("a", "alpha").build()); } @Test public void missingParameter() throws IOException { this.thrown.expect(SnippetException.class); - this.thrown - .expectMessage(equalTo("Request parameters with the following names were" - + " not found in the request: [a]")); - new RequestParametersSnippet( - Arrays.asList(parameterWithName("a").description("one"))).document( - this.operationBuilder.request("http://localhost").build()); + this.thrown.expectMessage( + equalTo("Request parameters with the following names were" + " not found in the request: [a]")); + new RequestParametersSnippet(Arrays.asList(parameterWithName("a").description("one"))) + .document(this.operationBuilder.request("http://localhost").build()); } @Test public void undocumentedAndMissingParameters() throws IOException { this.thrown.expect(SnippetException.class); - this.thrown - .expectMessage(equalTo("Request parameters with the following names were" - + " not documented: [b]. Request parameters with the following" - + " names were not found in the request: [a]")); - new RequestParametersSnippet( - Arrays.asList(parameterWithName("a").description("one"))) - .document(this.operationBuilder.request("http://localhost") - .param("b", "bravo").build()); + this.thrown.expectMessage(equalTo("Request parameters with the following names were" + + " not documented: [b]. Request parameters with the following" + + " names were not found in the request: [a]")); + new RequestParametersSnippet(Arrays.asList(parameterWithName("a").description("one"))) + .document(this.operationBuilder.request("http://localhost").param("b", "bravo").build()); } } diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/request/RequestParametersSnippetTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/request/RequestParametersSnippetTests.java index af948ac78..85fb1c235 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/request/RequestParametersSnippetTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/request/RequestParametersSnippetTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-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. @@ -49,63 +49,52 @@ public RequestParametersSnippetTests(String name, TemplateFormat templateFormat) @Test public void requestParameters() throws IOException { new RequestParametersSnippet( - Arrays.asList(parameterWithName("a").description("one"), - parameterWithName("b").description("two"))).document( - this.operationBuilder.request("http://localhost") - .param("a", "bravo").param("b", "bravo").build()); + Arrays.asList(parameterWithName("a").description("one"), parameterWithName("b").description("two"))) + .document(this.operationBuilder.request("http://localhost").param("a", "bravo") + .param("b", "bravo").build()); assertThat(this.generatedSnippets.requestParameters()) - .is(tableWithHeader("Parameter", "Description").row("`a`", "one") - .row("`b`", "two")); + .is(tableWithHeader("Parameter", "Description").row("`a`", "one").row("`b`", "two")); } @Test public void requestParameterWithNoValue() throws IOException { - new RequestParametersSnippet( - Arrays.asList(parameterWithName("a").description("one"))) - .document(this.operationBuilder.request("http://localhost") - .param("a").build()); + new RequestParametersSnippet(Arrays.asList(parameterWithName("a").description("one"))) + .document(this.operationBuilder.request("http://localhost").param("a").build()); assertThat(this.generatedSnippets.requestParameters()) .is(tableWithHeader("Parameter", "Description").row("`a`", "one")); } @Test public void ignoredRequestParameter() throws IOException { - new RequestParametersSnippet(Arrays.asList(parameterWithName("a").ignored(), - parameterWithName("b").description("two"))) - .document(this.operationBuilder.request("http://localhost") - .param("a", "bravo").param("b", "bravo").build()); + new RequestParametersSnippet( + Arrays.asList(parameterWithName("a").ignored(), parameterWithName("b").description("two"))) + .document(this.operationBuilder.request("http://localhost").param("a", "bravo") + .param("b", "bravo").build()); assertThat(this.generatedSnippets.requestParameters()) .is(tableWithHeader("Parameter", "Description").row("`b`", "two")); } @Test public void allUndocumentedRequestParametersCanBeIgnored() throws IOException { - new RequestParametersSnippet( - Arrays.asList(parameterWithName("b").description("two")), true) - .document(this.operationBuilder.request("http://localhost") - .param("a", "bravo").param("b", "bravo").build()); + new RequestParametersSnippet(Arrays.asList(parameterWithName("b").description("two")), true).document( + this.operationBuilder.request("http://localhost").param("a", "bravo").param("b", "bravo").build()); assertThat(this.generatedSnippets.requestParameters()) .is(tableWithHeader("Parameter", "Description").row("`b`", "two")); } @Test public void missingOptionalRequestParameter() throws IOException { - new RequestParametersSnippet( - Arrays.asList(parameterWithName("a").description("one").optional(), - parameterWithName("b").description("two"))).document( - this.operationBuilder.request("http://localhost") - .param("b", "bravo").build()); + new RequestParametersSnippet(Arrays.asList(parameterWithName("a").description("one").optional(), + parameterWithName("b").description("two"))) + .document(this.operationBuilder.request("http://localhost").param("b", "bravo").build()); assertThat(this.generatedSnippets.requestParameters()) - .is(tableWithHeader("Parameter", "Description").row("`a`", "one") - .row("`b`", "two")); + .is(tableWithHeader("Parameter", "Description").row("`a`", "one").row("`b`", "two")); } @Test public void presentOptionalRequestParameter() throws IOException { - new RequestParametersSnippet( - Arrays.asList(parameterWithName("a").description("one").optional())) - .document(this.operationBuilder.request("http://localhost") - .param("a", "one").build()); + new RequestParametersSnippet(Arrays.asList(parameterWithName("a").description("one").optional())) + .document(this.operationBuilder.request("http://localhost").param("a", "one").build()); assertThat(this.generatedSnippets.requestParameters()) .is(tableWithHeader("Parameter", "Description").row("`a`", "one")); } @@ -115,17 +104,13 @@ public void requestParametersWithCustomAttributes() throws IOException { TemplateResourceResolver resolver = mock(TemplateResourceResolver.class); given(resolver.resolveTemplateResource("request-parameters")) .willReturn(snippetResource("request-parameters-with-title")); - new RequestParametersSnippet(Arrays.asList( - parameterWithName("a").description("one") - .attributes(key("foo").value("alpha")), - parameterWithName("b").description("two") - .attributes(key("foo").value("bravo"))), + new RequestParametersSnippet( + Arrays.asList(parameterWithName("a").description("one").attributes(key("foo").value("alpha")), + parameterWithName("b").description("two").attributes(key("foo").value("bravo"))), attributes(key("title").value("The title"))) .document(this.operationBuilder - .attribute(TemplateEngine.class.getName(), - new MustacheTemplateEngine(resolver)) - .request("http://localhost").param("a", "alpha") - .param("b", "bravo").build()); + .attribute(TemplateEngine.class.getName(), new MustacheTemplateEngine(resolver)) + .request("http://localhost").param("a", "alpha").param("b", "bravo").build()); assertThat(this.generatedSnippets.requestParameters()).contains("The title"); } @@ -134,22 +119,14 @@ public void requestParametersWithCustomDescriptorAttributes() throws IOException TemplateResourceResolver resolver = mock(TemplateResourceResolver.class); given(resolver.resolveTemplateResource("request-parameters")) .willReturn(snippetResource("request-parameters-with-extra-column")); - new RequestParametersSnippet(Arrays.asList( - parameterWithName("a").description("one") - .attributes(key("foo").value("alpha")), - parameterWithName("b").description("two") - .attributes(key("foo").value("bravo")))) - .document( - this.operationBuilder - .attribute(TemplateEngine.class.getName(), - new MustacheTemplateEngine( - resolver)) - .request("http://localhost") - .param("a", "alpha").param("b", "bravo") - .build()); - assertThat(this.generatedSnippets.requestParameters()) - .is(tableWithHeader("Parameter", "Description", "Foo") - .row("a", "one", "alpha").row("b", "two", "bravo")); + new RequestParametersSnippet( + Arrays.asList(parameterWithName("a").description("one").attributes(key("foo").value("alpha")), + parameterWithName("b").description("two").attributes(key("foo").value("bravo")))) + .document(this.operationBuilder + .attribute(TemplateEngine.class.getName(), new MustacheTemplateEngine(resolver)) + .request("http://localhost").param("a", "alpha").param("b", "bravo").build()); + assertThat(this.generatedSnippets.requestParameters()).is( + tableWithHeader("Parameter", "Description", "Foo").row("a", "one", "alpha").row("b", "two", "bravo")); } @Test @@ -157,42 +134,31 @@ public void requestParametersWithOptionalColumn() throws IOException { TemplateResourceResolver resolver = mock(TemplateResourceResolver.class); given(resolver.resolveTemplateResource("request-parameters")) .willReturn(snippetResource("request-parameters-with-optional-column")); - new RequestParametersSnippet( - Arrays.asList(parameterWithName("a").description("one").optional(), - parameterWithName("b").description("two"))) - .document( - this.operationBuilder - .attribute(TemplateEngine.class.getName(), - new MustacheTemplateEngine( - resolver)) - .request("http://localhost") - .param("a", "alpha").param("b", "bravo") - .build()); + new RequestParametersSnippet(Arrays.asList(parameterWithName("a").description("one").optional(), + parameterWithName("b").description("two"))) + .document(this.operationBuilder + .attribute(TemplateEngine.class.getName(), new MustacheTemplateEngine(resolver)) + .request("http://localhost").param("a", "alpha").param("b", "bravo").build()); assertThat(this.generatedSnippets.requestParameters()) - .is(tableWithHeader("Parameter", "Optional", "Description") - .row("a", "true", "one").row("b", "false", "two")); + .is(tableWithHeader("Parameter", "Optional", "Description").row("a", "true", "one").row("b", "false", + "two")); } @Test public void additionalDescriptors() throws IOException { RequestDocumentation.requestParameters(parameterWithName("a").description("one")) - .and(parameterWithName("b").description("two")) - .document(this.operationBuilder.request("http://localhost") - .param("a", "bravo").param("b", "bravo").build()); + .and(parameterWithName("b").description("two")).document(this.operationBuilder + .request("http://localhost").param("a", "bravo").param("b", "bravo").build()); assertThat(this.generatedSnippets.requestParameters()) - .is(tableWithHeader("Parameter", "Description").row("`a`", "one") - .row("`b`", "two")); + .is(tableWithHeader("Parameter", "Description").row("`a`", "one").row("`b`", "two")); } @Test public void requestParametersWithEscapedContent() throws IOException { - RequestDocumentation - .requestParameters(parameterWithName("Foo|Bar").description("one|two")) - .document(this.operationBuilder.request("http://localhost") - .param("Foo|Bar", "baz").build()); - assertThat(this.generatedSnippets.requestParameters()) - .is(tableWithHeader("Parameter", "Description").row( - escapeIfNecessary("`Foo|Bar`"), escapeIfNecessary("one|two"))); + RequestDocumentation.requestParameters(parameterWithName("Foo|Bar").description("one|two")) + .document(this.operationBuilder.request("http://localhost").param("Foo|Bar", "baz").build()); + assertThat(this.generatedSnippets.requestParameters()).is(tableWithHeader("Parameter", "Description") + .row(escapeIfNecessary("`Foo|Bar`"), escapeIfNecessary("one|two"))); } private String escapeIfNecessary(String input) { diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/request/RequestPartsSnippetFailureTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/request/RequestPartsSnippetFailureTests.java index 0c0517f2b..11c1442a7 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/request/RequestPartsSnippetFailureTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/request/RequestPartsSnippetFailureTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-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. @@ -40,8 +40,7 @@ public class RequestPartsSnippetFailureTests { @Rule - public OperationBuilder operationBuilder = new OperationBuilder( - TemplateFormats.asciidoctor()); + public OperationBuilder operationBuilder = new OperationBuilder(TemplateFormats.asciidoctor()); @Rule public ExpectedException thrown = ExpectedException.none(); @@ -49,18 +48,16 @@ public class RequestPartsSnippetFailureTests { @Test public void undocumentedPart() throws IOException { this.thrown.expect(SnippetException.class); - this.thrown.expectMessage(equalTo( - "Request parts with the following names were" + " not documented: [a]")); + this.thrown.expectMessage(equalTo("Request parts with the following names were" + " not documented: [a]")); new RequestPartsSnippet(Collections.emptyList()) - .document(this.operationBuilder.request("http://localhost") - .part("a", "alpha".getBytes()).build()); + .document(this.operationBuilder.request("http://localhost").part("a", "alpha".getBytes()).build()); } @Test public void missingPart() throws IOException { this.thrown.expect(SnippetException.class); - this.thrown.expectMessage(equalTo("Request parts with the following names were" - + " not found in the request: [a]")); + this.thrown.expectMessage( + equalTo("Request parts with the following names were" + " not found in the request: [a]")); new RequestPartsSnippet(Arrays.asList(partWithName("a").description("one"))) .document(this.operationBuilder.request("http://localhost").build()); } @@ -68,12 +65,11 @@ public void missingPart() throws IOException { @Test public void undocumentedAndMissingParts() throws IOException { this.thrown.expect(SnippetException.class); - this.thrown.expectMessage(equalTo("Request parts with the following names were" - + " not documented: [b]. Request parts with the following" - + " names were not found in the request: [a]")); + this.thrown.expectMessage(equalTo( + "Request parts with the following names were" + " not documented: [b]. Request parts with the following" + + " names were not found in the request: [a]")); new RequestPartsSnippet(Arrays.asList(partWithName("a").description("one"))) - .document(this.operationBuilder.request("http://localhost") - .part("b", "bravo".getBytes()).build()); + .document(this.operationBuilder.request("http://localhost").part("b", "bravo".getBytes()).build()); } } diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/request/RequestPartsSnippetTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/request/RequestPartsSnippetTests.java index 0318dc8ba..34f82d1ca 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/request/RequestPartsSnippetTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/request/RequestPartsSnippetTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-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. @@ -48,57 +48,45 @@ public RequestPartsSnippetTests(String name, TemplateFormat templateFormat) { @Test public void requestParts() throws IOException { - new RequestPartsSnippet(Arrays.asList(partWithName("a").description("one"), - partWithName("b").description("two"))) - .document(this.operationBuilder.request("http://localhost") - .part("a", "bravo".getBytes()).and() + new RequestPartsSnippet( + Arrays.asList(partWithName("a").description("one"), partWithName("b").description("two"))) + .document(this.operationBuilder.request("http://localhost").part("a", "bravo".getBytes()).and() .part("b", "bravo".getBytes()).build()); assertThat(this.generatedSnippets.requestParts()) - .is(tableWithHeader("Part", "Description").row("`a`", "one").row("`b`", - "two")); + .is(tableWithHeader("Part", "Description").row("`a`", "one").row("`b`", "two")); } @Test public void ignoredRequestPart() throws IOException { - new RequestPartsSnippet(Arrays.asList(partWithName("a").ignored(), - partWithName("b").description("two"))) - .document(this.operationBuilder.request("http://localhost") - .part("a", "bravo".getBytes()).and() - .part("b", "bravo".getBytes()).build()); - assertThat(this.generatedSnippets.requestParts()) - .is(tableWithHeader("Part", "Description").row("`b`", "two")); + new RequestPartsSnippet(Arrays.asList(partWithName("a").ignored(), partWithName("b").description("two"))) + .document(this.operationBuilder.request("http://localhost").part("a", "bravo".getBytes()).and() + .part("b", "bravo".getBytes()).build()); + assertThat(this.generatedSnippets.requestParts()).is(tableWithHeader("Part", "Description").row("`b`", "two")); } @Test public void allUndocumentedRequestPartsCanBeIgnored() throws IOException { new RequestPartsSnippet(Arrays.asList(partWithName("b").description("two")), true) - .document(this.operationBuilder.request("http://localhost") - .part("a", "bravo".getBytes()).and().part("b", "bravo".getBytes()) - .build()); - assertThat(this.generatedSnippets.requestParts()) - .is(tableWithHeader("Part", "Description").row("`b`", "two")); + .document(this.operationBuilder.request("http://localhost").part("a", "bravo".getBytes()).and() + .part("b", "bravo".getBytes()).build()); + assertThat(this.generatedSnippets.requestParts()).is(tableWithHeader("Part", "Description").row("`b`", "two")); } @Test public void missingOptionalRequestPart() throws IOException { new RequestPartsSnippet( - Arrays.asList(partWithName("a").description("one").optional(), - partWithName("b").description("two"))).document( - this.operationBuilder.request("http://localhost") - .part("b", "bravo".getBytes()).build()); + Arrays.asList(partWithName("a").description("one").optional(), partWithName("b").description("two"))) + .document(this.operationBuilder.request("http://localhost").part("b", "bravo".getBytes()) + .build()); assertThat(this.generatedSnippets.requestParts()) - .is(tableWithHeader("Part", "Description").row("`a`", "one").row("`b`", - "two")); + .is(tableWithHeader("Part", "Description").row("`a`", "one").row("`b`", "two")); } @Test public void presentOptionalRequestPart() throws IOException { - new RequestPartsSnippet( - Arrays.asList(partWithName("a").description("one").optional())) - .document(this.operationBuilder.request("http://localhost") - .part("a", "one".getBytes()).build()); - assertThat(this.generatedSnippets.requestParts()) - .is(tableWithHeader("Part", "Description").row("`a`", "one")); + new RequestPartsSnippet(Arrays.asList(partWithName("a").description("one").optional())) + .document(this.operationBuilder.request("http://localhost").part("a", "one".getBytes()).build()); + assertThat(this.generatedSnippets.requestParts()).is(tableWithHeader("Part", "Description").row("`a`", "one")); } @Test @@ -106,17 +94,14 @@ public void requestPartsWithCustomAttributes() throws IOException { TemplateResourceResolver resolver = mock(TemplateResourceResolver.class); given(resolver.resolveTemplateResource("request-parts")) .willReturn(snippetResource("request-parts-with-title")); - new RequestPartsSnippet(Arrays.asList( - partWithName("a").description("one") - .attributes(key("foo").value("alpha")), - partWithName("b").description("two") - .attributes(key("foo").value("bravo"))), + new RequestPartsSnippet( + Arrays.asList(partWithName("a").description("one").attributes(key("foo").value("alpha")), + partWithName("b").description("two").attributes(key("foo").value("bravo"))), attributes(key("title").value("The title"))) .document(this.operationBuilder - .attribute(TemplateEngine.class.getName(), - new MustacheTemplateEngine(resolver)) - .request("http://localhost").part("a", "alpha".getBytes()) - .and().part("b", "bravo".getBytes()).build()); + .attribute(TemplateEngine.class.getName(), new MustacheTemplateEngine(resolver)) + .request("http://localhost").part("a", "alpha".getBytes()).and() + .part("b", "bravo".getBytes()).build()); assertThat(this.generatedSnippets.requestParts()).contains("The title"); } @@ -125,22 +110,15 @@ public void requestPartsWithCustomDescriptorAttributes() throws IOException { TemplateResourceResolver resolver = mock(TemplateResourceResolver.class); given(resolver.resolveTemplateResource("request-parts")) .willReturn(snippetResource("request-parts-with-extra-column")); - new RequestPartsSnippet(Arrays.asList( - partWithName("a").description("one") - .attributes(key("foo").value("alpha")), - partWithName("b").description("two") - .attributes(key("foo").value("bravo")))) - .document( - this.operationBuilder - .attribute(TemplateEngine.class.getName(), - new MustacheTemplateEngine( - resolver)) - .request("http://localhost") - .part("a", "alpha".getBytes()).and() - .part("b", "bravo".getBytes()).build()); + new RequestPartsSnippet( + Arrays.asList(partWithName("a").description("one").attributes(key("foo").value("alpha")), + partWithName("b").description("two").attributes(key("foo").value("bravo")))) + .document(this.operationBuilder + .attribute(TemplateEngine.class.getName(), new MustacheTemplateEngine(resolver)) + .request("http://localhost").part("a", "alpha".getBytes()).and() + .part("b", "bravo".getBytes()).build()); assertThat(this.generatedSnippets.requestParts()) - .is(tableWithHeader("Part", "Description", "Foo").row("a", "one", "alpha") - .row("b", "two", "bravo")); + .is(tableWithHeader("Part", "Description", "Foo").row("a", "one", "alpha").row("b", "two", "bravo")); } @Test @@ -149,41 +127,30 @@ public void requestPartsWithOptionalColumn() throws IOException { given(resolver.resolveTemplateResource("request-parts")) .willReturn(snippetResource("request-parts-with-optional-column")); new RequestPartsSnippet( - Arrays.asList(partWithName("a").description("one").optional(), - partWithName("b").description("two"))) - .document( - this.operationBuilder - .attribute(TemplateEngine.class.getName(), - new MustacheTemplateEngine( - resolver)) - .request("http://localhost") - .part("a", "alpha".getBytes()).and() - .part("b", "bravo".getBytes()).build()); - assertThat(this.generatedSnippets.requestParts()) - .is(tableWithHeader("Part", "Optional", "Description") - .row("a", "true", "one").row("b", "false", "two")); + Arrays.asList(partWithName("a").description("one").optional(), partWithName("b").description("two"))) + .document(this.operationBuilder + .attribute(TemplateEngine.class.getName(), new MustacheTemplateEngine(resolver)) + .request("http://localhost").part("a", "alpha".getBytes()).and() + .part("b", "bravo".getBytes()).build()); + assertThat(this.generatedSnippets.requestParts()).is( + tableWithHeader("Part", "Optional", "Description").row("a", "true", "one").row("b", "false", "two")); } @Test public void additionalDescriptors() throws IOException { RequestDocumentation.requestParts(partWithName("a").description("one")) - .and(partWithName("b").description("two")) - .document(this.operationBuilder.request("http://localhost") - .part("a", "bravo".getBytes()).and().part("b", "bravo".getBytes()) - .build()); + .and(partWithName("b").description("two")).document(this.operationBuilder.request("http://localhost") + .part("a", "bravo".getBytes()).and().part("b", "bravo".getBytes()).build()); assertThat(this.generatedSnippets.requestParts()) - .is(tableWithHeader("Part", "Description").row("`a`", "one").row("`b`", - "two")); + .is(tableWithHeader("Part", "Description").row("`a`", "one").row("`b`", "two")); } @Test public void requestPartsWithEscapedContent() throws IOException { RequestDocumentation.requestParts(partWithName("Foo|Bar").description("one|two")) - .document(this.operationBuilder.request("http://localhost") - .part("Foo|Bar", "baz".getBytes()).build()); - assertThat(this.generatedSnippets.requestParts()).is( - tableWithHeader("Part", "Description").row(escapeIfNecessary("`Foo|Bar`"), - escapeIfNecessary("one|two"))); + .document(this.operationBuilder.request("http://localhost").part("Foo|Bar", "baz".getBytes()).build()); + assertThat(this.generatedSnippets.requestParts()).is(tableWithHeader("Part", "Description") + .row(escapeIfNecessary("`Foo|Bar`"), escapeIfNecessary("one|two"))); } private String escapeIfNecessary(String input) { 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 3e0006501..23c2bd94d 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 @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-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. @@ -34,16 +34,14 @@ public class RestDocumentationContextPlaceholderResolverTests { @Test public void kebabCaseMethodName() throws Exception { - assertThat(createResolver("dashSeparatedMethodName") - .resolvePlaceholder("method-name")) - .isEqualTo("dash-separated-method-name"); + assertThat(createResolver("dashSeparatedMethodName").resolvePlaceholder("method-name")) + .isEqualTo("dash-separated-method-name"); } @Test public void snakeCaseMethodName() throws Exception { - assertThat(createResolver("underscoreSeparatedMethodName") - .resolvePlaceholder("method_name")) - .isEqualTo("underscore_separated_method_name"); + assertThat(createResolver("underscoreSeparatedMethodName").resolvePlaceholder("method_name")) + .isEqualTo("underscore_separated_method_name"); } @Test @@ -84,8 +82,7 @@ private PlaceholderResolver createResolver(String methodName) { } 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 ec767517a..418650654 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 @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-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. @@ -45,42 +45,37 @@ public class StandardWriterResolverTests { @Rule public final TemporaryFolder temp = new TemporaryFolder(); - private final PlaceholderResolverFactory placeholderResolverFactory = mock( - PlaceholderResolverFactory.class); + private final PlaceholderResolverFactory placeholderResolverFactory = mock(PlaceholderResolverFactory.class); - private final StandardWriterResolver resolver = new StandardWriterResolver( - this.placeholderResolverFactory, "UTF-8", TemplateFormats.asciidoctor()); + private final StandardWriterResolver resolver = new StandardWriterResolver(this.placeholderResolverFactory, "UTF-8", + TemplateFormats.asciidoctor()); @Test public void absoluteInput() { String absolutePath = new File("foo").getAbsolutePath(); - assertThat(this.resolver.resolveFile(absolutePath, "bar.txt", - createContext(absolutePath))) - .isEqualTo(new File(absolutePath, "bar.txt")); + assertThat(this.resolver.resolveFile(absolutePath, "bar.txt", createContext(absolutePath))) + .isEqualTo(new File(absolutePath, "bar.txt")); } @Test public void configuredOutputAndRelativeInput() { File outputDir = new File("foo").getAbsoluteFile(); - assertThat(this.resolver.resolveFile("bar", "baz.txt", - createContext(outputDir.getAbsolutePath()))) - .isEqualTo(new File(outputDir, "bar/baz.txt")); + assertThat(this.resolver.resolveFile("bar", "baz.txt", createContext(outputDir.getAbsolutePath()))) + .isEqualTo(new File(outputDir, "bar/baz.txt")); } @Test public void configuredOutputAndAbsoluteInput() { File outputDir = new File("foo").getAbsoluteFile(); String absolutePath = new File("bar").getAbsolutePath(); - assertThat(this.resolver.resolveFile(absolutePath, "baz.txt", - createContext(outputDir.getAbsolutePath()))) - .isEqualTo(new File(absolutePath, "baz.txt")); + assertThat(this.resolver.resolveFile(absolutePath, "baz.txt", createContext(outputDir.getAbsolutePath()))) + .isEqualTo(new File(absolutePath, "baz.txt")); } @Test public void placeholdersAreResolvedInOperationName() throws IOException { File outputDirectory = this.temp.newFolder(); - RestDocumentationContext context = createContext( - outputDirectory.getAbsolutePath()); + RestDocumentationContext context = createContext(outputDirectory.getAbsolutePath()); PlaceholderResolver resolver = mock(PlaceholderResolver.class); given(resolver.resolvePlaceholder("a")).willReturn("alpha"); given(this.placeholderResolverFactory.create(context)).willReturn(resolver); @@ -91,8 +86,7 @@ public void placeholdersAreResolvedInOperationName() throws IOException { @Test public void placeholdersAreResolvedInSnippetName() throws IOException { File outputDirectory = this.temp.newFolder(); - RestDocumentationContext context = createContext( - outputDirectory.getAbsolutePath()); + RestDocumentationContext context = createContext(outputDirectory.getAbsolutePath()); PlaceholderResolver resolver = mock(PlaceholderResolver.class); given(resolver.resolvePlaceholder("b")).willReturn("bravo"); given(this.placeholderResolverFactory.create(context)).willReturn(resolver); @@ -101,20 +95,17 @@ public void placeholdersAreResolvedInSnippetName() throws IOException { } 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; } - private void assertSnippetLocation(Writer writer, File expectedLocation) - throws IOException { + private void assertSnippetLocation(Writer writer, File expectedLocation) throws IOException { writer.write("test"); writer.flush(); assertThat(expectedLocation).exists(); - assertThat(FileCopyUtils.copyToString(new FileReader(expectedLocation))) - .isEqualTo("test"); + assertThat(FileCopyUtils.copyToString(new FileReader(expectedLocation))).isEqualTo("test"); } } diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/snippet/TemplatedSnippetTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/snippet/TemplatedSnippetTests.java index 46d53fed4..f44e85a76 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/snippet/TemplatedSnippetTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/snippet/TemplatedSnippetTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-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. @@ -39,12 +39,10 @@ public class TemplatedSnippetTests { @Rule - public OperationBuilder operationBuilder = new OperationBuilder( - TemplateFormats.asciidoctor()); + public OperationBuilder operationBuilder = new OperationBuilder(TemplateFormats.asciidoctor()); @Rule - public GeneratedSnippets snippets = new GeneratedSnippets( - TemplateFormats.asciidoctor()); + public GeneratedSnippets snippets = new GeneratedSnippets(TemplateFormats.asciidoctor()); @Test public void attributesAreCopied() { @@ -64,16 +62,13 @@ public void nullAttributesAreTolerated() { @Test public void snippetName() { - assertThat(new TestTemplatedSnippet(Collections.emptyMap()) - .getSnippetName()).isEqualTo("test"); + assertThat(new TestTemplatedSnippet(Collections.emptyMap()).getSnippetName()).isEqualTo("test"); } @Test public void multipleSnippetsCanBeProducedFromTheSameTemplate() throws IOException { - new TestTemplatedSnippet("one", "multiple-snippets") - .document(this.operationBuilder.build()); - new TestTemplatedSnippet("two", "multiple-snippets") - .document(this.operationBuilder.build()); + new TestTemplatedSnippet("one", "multiple-snippets").document(this.operationBuilder.build()); + new TestTemplatedSnippet("two", "multiple-snippets").document(this.operationBuilder.build()); assertThat(this.snippets.snippet("multiple-snippets-one")).isNotNull(); assertThat(this.snippets.snippet("multiple-snippets-two")).isNotNull(); } @@ -81,8 +76,7 @@ public void multipleSnippetsCanBeProducedFromTheSameTemplate() throws IOExceptio private static class TestTemplatedSnippet extends TemplatedSnippet { protected TestTemplatedSnippet(String snippetName, String templateName) { - super(templateName + "-" + snippetName, templateName, - Collections.emptyMap()); + super(templateName + "-" + snippetName, templateName, Collections.emptyMap()); } protected TestTemplatedSnippet(Map attributes) { diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/templates/StandardTemplateResourceResolverTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/templates/StandardTemplateResourceResolverTests.java index dd4c03e85..3b3c5e9d3 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/templates/StandardTemplateResourceResolverTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/templates/StandardTemplateResourceResolverTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-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. @@ -47,72 +47,56 @@ public class StandardTemplateResourceResolverTests { @Test public void formatSpecificCustomSnippetHasHighestPrecedence() throws Exception { - this.classLoader.addResource( - "org/springframework/restdocs/templates/asciidoctor/test.snippet", + this.classLoader.addResource("org/springframework/restdocs/templates/asciidoctor/test.snippet", getClass().getResource("test-format-specific-custom.snippet")); - this.classLoader.addResource( - "org/springframework/restdocs/templates/test.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", + this.classLoader.addResource("org/springframework/restdocs/templates/asciidoctor/default-test.snippet", getClass().getResource("test-default.snippet")); - Resource snippet = doWithThreadContextClassLoader(this.classLoader, - new Callable() { + Resource snippet = doWithThreadContextClassLoader(this.classLoader, new Callable() { - @Override - public Resource call() { - return StandardTemplateResourceResolverTests.this.resolver - .resolveTemplateResource("test"); - } + @Override + public Resource call() { + return StandardTemplateResourceResolverTests.this.resolver.resolveTemplateResource("test"); + } - }); + }); - assertThat(snippet.getURL()) - .isEqualTo(getClass().getResource("test-format-specific-custom.snippet")); + assertThat(snippet.getURL()).isEqualTo(getClass().getResource("test-format-specific-custom.snippet")); } @Test - public void generalCustomSnippetIsUsedInAbsenceOfFormatSpecificCustomSnippet() - throws Exception { - this.classLoader.addResource( - "org/springframework/restdocs/templates/test.snippet", + 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", + this.classLoader.addResource("org/springframework/restdocs/templates/asciidoctor/default-test.snippet", getClass().getResource("test-default.snippet")); - Resource snippet = doWithThreadContextClassLoader(this.classLoader, - new Callable() { + Resource snippet = doWithThreadContextClassLoader(this.classLoader, new Callable() { - @Override - public Resource call() { - return StandardTemplateResourceResolverTests.this.resolver - .resolveTemplateResource("test"); - } + @Override + public Resource call() { + return StandardTemplateResourceResolverTests.this.resolver.resolveTemplateResource("test"); + } - }); + }); - assertThat(snippet.getURL()) - .isEqualTo(getClass().getResource("test-custom.snippet")); + assertThat(snippet.getURL()).isEqualTo(getClass().getResource("test-custom.snippet")); } @Test public void defaultSnippetIsUsedInAbsenceOfCustomSnippets() throws Exception { - this.classLoader.addResource( - "org/springframework/restdocs/templates/asciidoctor/default-test.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 snippet = doWithThreadContextClassLoader(this.classLoader, new Callable() { - @Override - public Resource call() { - return StandardTemplateResourceResolverTests.this.resolver - .resolveTemplateResource("test"); - } + @Override + public Resource call() { + return StandardTemplateResourceResolverTests.this.resolver.resolveTemplateResource("test"); + } - }); + }); - assertThat(snippet.getURL()) - .isEqualTo(getClass().getResource("test-default.snippet")); + assertThat(snippet.getURL()).isEqualTo(getClass().getResource("test-default.snippet")); } @Test @@ -123,15 +107,13 @@ public void failsIfCustomAndDefaultSnippetsDoNotExist() throws Exception { @Override public Resource call() { - return StandardTemplateResourceResolverTests.this.resolver - .resolveTemplateResource("test"); + return StandardTemplateResourceResolverTests.this.resolver.resolveTemplateResource("test"); } }); } - private T doWithThreadContextClassLoader(ClassLoader classLoader, - Callable action) throws Exception { + private T doWithThreadContextClassLoader(ClassLoader classLoader, Callable action) throws Exception { ClassLoader previous = Thread.currentThread().getContextClassLoader(); Thread.currentThread().setContextClassLoader(classLoader); try { diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/test/GeneratedSnippets.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/test/GeneratedSnippets.java index 80fe1f2fb..6c03b4b1c 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/test/GeneratedSnippets.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/test/GeneratedSnippets.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-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. @@ -109,8 +109,8 @@ public String requestParameters() { public String snippet(String name) { File snippetFile = getSnippetFile(name); try { - return FileCopyUtils.copyToString(new InputStreamReader( - new FileInputStream(snippetFile), StandardCharsets.UTF_8)); + return FileCopyUtils + .copyToString(new InputStreamReader(new FileInputStream(snippetFile), StandardCharsets.UTF_8)); } catch (Exception ex) { fail("Failed to read '" + snippetFile + "'", ex); 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 ea4f18b48..d4ec2520b 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 @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-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. @@ -101,25 +101,19 @@ private void prepare(String operationName, File outputDirectory) { public Operation build() { if (this.attributes.get(TemplateEngine.class.getName()) == null) { Map templateContext = new HashMap<>(); - templateContext.put("tableCellContent", - new AsciidoctorTableCellContentLambda()); + templateContext.put("tableCellContent", new AsciidoctorTableCellContentLambda()); this.attributes.put(TemplateEngine.class.getName(), - new MustacheTemplateEngine( - new StandardTemplateResourceResolver(this.templateFormat), + new MustacheTemplateEngine(new StandardTemplateResourceResolver(this.templateFormat), Mustache.compiler().escapeHTML(false), templateContext)); } RestDocumentationContext context = createContext(); this.attributes.put(RestDocumentationContext.class.getName(), context); - this.attributes.put(WriterResolver.class.getName(), - new StandardWriterResolver( - new RestDocumentationContextPlaceholderResolverFactory(), "UTF-8", - this.templateFormat)); + this.attributes.put(WriterResolver.class.getName(), new StandardWriterResolver( + new RestDocumentationContextPlaceholderResolverFactory(), "UTF-8", this.templateFormat)); return new StandardOperation(this.name, - ((this.requestBuilder == null) - ? new OperationRequestBuilder("http://localhost/").buildRequest() + ((this.requestBuilder == null) ? new OperationRequestBuilder("http://localhost/").buildRequest() : this.requestBuilder.buildRequest()), - (this.responseBuilder == null) - ? new OperationResponseBuilder().buildResponse() + (this.responseBuilder == null) ? new OperationResponseBuilder().buildResponse() : this.responseBuilder.buildResponse(), this.attributes); } @@ -166,8 +160,8 @@ private OperationRequest buildRequest() { for (OperationRequestPartBuilder builder : this.partBuilders) { parts.add(builder.buildPart()); } - return new OperationRequestFactory().create(this.requestUri, this.method, - this.content, this.headers, this.parameters, parts, this.cookies); + return new OperationRequestFactory().create(this.requestUri, this.method, this.content, this.headers, + this.parameters, parts, this.cookies); } public Operation build() { @@ -207,8 +201,7 @@ public OperationRequestBuilder header(String name, String value) { } public OperationRequestPartBuilder part(String name, byte[] content) { - OperationRequestPartBuilder partBuilder = new OperationRequestPartBuilder( - name, content); + OperationRequestPartBuilder partBuilder = new OperationRequestPartBuilder(name, content); this.partBuilders.add(partBuilder); return partBuilder; } @@ -236,8 +229,7 @@ private OperationRequestPartBuilder(String name, byte[] content) { this.content = content; } - public OperationRequestPartBuilder submittedFileName( - String submittedFileName) { + public OperationRequestPartBuilder submittedFileName(String submittedFileName) { this.submittedFileName = submittedFileName; return this; } @@ -251,8 +243,8 @@ public Operation build() { } private OperationRequestPart buildPart() { - return new OperationRequestPartFactory().create(this.name, - this.submittedFileName, this.content, this.headers); + return new OperationRequestPartFactory().create(this.name, this.submittedFileName, this.content, + this.headers); } public OperationRequestPartBuilder header(String name, String value) { @@ -276,8 +268,7 @@ public final class OperationResponseBuilder { private byte[] content = new byte[0]; private OperationResponse buildResponse() { - return new OperationResponseFactory().create(this.status, this.headers, - this.content); + return new OperationResponseFactory().create(this.status, this.headers, this.content); } public OperationResponseBuilder status(int status) { diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/test/OperationTestRule.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/test/OperationTestRule.java index 821de702d..bc8d532e5 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/test/OperationTestRule.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/test/OperationTestRule.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2016 the original author or authors. + * Copyright 2014-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. @@ -31,8 +31,7 @@ abstract class OperationTestRule implements TestRule { @Override public final Statement apply(Statement base, Description description) { - return apply(base, determineOutputDirectory(description), - determineOperationName(description)); + return apply(base, determineOutputDirectory(description), determineOperationName(description)); } private File determineOutputDirectory(Description description) { @@ -48,7 +47,6 @@ private String determineOperationName(Description description) { return operationName; } - protected abstract Statement apply(Statement base, File outputDirectory, - String operationName); + protected abstract Statement apply(Statement base, File outputDirectory, String operationName); } diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/test/OutputCapture.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/test/OutputCapture.java index 0e4618967..951008358 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/test/OutputCapture.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/test/OutputCapture.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 the original author or authors. + * 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. @@ -60,8 +60,8 @@ public void evaluate() throws Throwable { finally { try { if (!OutputCapture.this.matchers.isEmpty()) { - assertThat(getOutputAsString()).is(new HamcrestCondition<>( - allOf(OutputCapture.this.matchers))); + assertThat(getOutputAsString()) + .is(new HamcrestCondition<>(allOf(OutputCapture.this.matchers))); } } finally { diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/test/SnippetConditions.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/test/SnippetConditions.java index 80fffe2f5..657b3e572 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/test/SnippetConditions.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/test/SnippetConditions.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-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. @@ -42,45 +42,37 @@ private SnippetConditions() { } - public static TableCondition tableWithHeader(TemplateFormat format, - String... headers) { + public static TableCondition tableWithHeader(TemplateFormat format, String... headers) { if ("adoc".equals(format.getFileExtension())) { return new AsciidoctorTableCondition(null, headers); } return new MarkdownTableCondition(null, headers); } - public static TableCondition tableWithTitleAndHeader(TemplateFormat format, - String title, String... headers) { + public static TableCondition tableWithTitleAndHeader(TemplateFormat format, String title, String... headers) { if ("adoc".equals(format.getFileExtension())) { return new AsciidoctorTableCondition(title, headers); } return new MarkdownTableCondition(title, headers); } - public static HttpRequestCondition httpRequest(TemplateFormat format, - RequestMethod requestMethod, String uri) { + public static HttpRequestCondition httpRequest(TemplateFormat format, RequestMethod requestMethod, String uri) { if ("adoc".equals(format.getFileExtension())) { - return new HttpRequestCondition(requestMethod, uri, - new AsciidoctorCodeBlockCondition<>("http", "nowrap"), 3); + return new HttpRequestCondition(requestMethod, uri, new AsciidoctorCodeBlockCondition<>("http", "nowrap"), + 3); } - return new HttpRequestCondition(requestMethod, uri, - new MarkdownCodeBlockCondition<>("http"), 2); + return new HttpRequestCondition(requestMethod, uri, new MarkdownCodeBlockCondition<>("http"), 2); } - public static HttpResponseCondition httpResponse(TemplateFormat format, - HttpStatus status) { + public static HttpResponseCondition httpResponse(TemplateFormat format, HttpStatus status) { if ("adoc".equals(format.getFileExtension())) { - return new HttpResponseCondition(status, - new AsciidoctorCodeBlockCondition<>("http", "nowrap"), 3); + return new HttpResponseCondition(status, new AsciidoctorCodeBlockCondition<>("http", "nowrap"), 3); } - return new HttpResponseCondition(status, new MarkdownCodeBlockCondition<>("http"), - 2); + return new HttpResponseCondition(status, new MarkdownCodeBlockCondition<>("http"), 2); } @SuppressWarnings({ "rawtypes" }) - public static CodeBlockCondition codeBlock(TemplateFormat format, - String language) { + public static CodeBlockCondition codeBlock(TemplateFormat format, String language) { if ("adoc".equals(format.getFileExtension())) { return new AsciidoctorCodeBlockCondition(language, null); } @@ -88,16 +80,14 @@ public static CodeBlockCondition codeBlock(TemplateFormat format, } @SuppressWarnings({ "rawtypes" }) - public static CodeBlockCondition codeBlock(TemplateFormat format, String language, - String options) { + public static CodeBlockCondition codeBlock(TemplateFormat format, String language, String options) { if ("adoc".equals(format.getFileExtension())) { return new AsciidoctorCodeBlockCondition(language, options); } return new MarkdownCodeBlockCondition(language); } - private abstract static class AbstractSnippetContentCondition - extends Condition { + private abstract static class AbstractSnippetContentCondition extends Condition { private List lines = new ArrayList<>(); @@ -151,8 +141,7 @@ private String getLinesAsString() { * * @param The type of the Condition */ - public static class CodeBlockCondition> - extends AbstractSnippetContentCondition { + public static class CodeBlockCondition> extends AbstractSnippetContentCondition { @SuppressWarnings("unchecked") public T withContent(String content) { @@ -199,8 +188,7 @@ protected MarkdownCodeBlockCondition(String language) { * * @param The type of the Condition */ - public abstract static class HttpCondition> - extends Condition { + public abstract static class HttpCondition> extends Condition { private final CodeBlockCondition delegate; @@ -239,11 +227,9 @@ public boolean matches(String item) { /** * A {@link Condition} for an HTTP response. */ - public static final class HttpResponseCondition - extends HttpCondition { + public static final class HttpResponseCondition extends HttpCondition { - private HttpResponseCondition(HttpStatus status, CodeBlockCondition delegate, - int headerOffset) { + private HttpResponseCondition(HttpStatus status, CodeBlockCondition delegate, int headerOffset) { super(delegate, headerOffset); this.content("HTTP/1.1 " + status.value() + " " + status.getReasonPhrase()); this.content(""); @@ -254,11 +240,10 @@ private HttpResponseCondition(HttpStatus status, CodeBlockCondition delegate, /** * A {@link Condition} for an HTTP request. */ - public static final class HttpRequestCondition - extends HttpCondition { + public static final class HttpRequestCondition extends HttpCondition { - private HttpRequestCondition(RequestMethod requestMethod, String uri, - CodeBlockCondition delegate, int headerOffset) { + private HttpRequestCondition(RequestMethod requestMethod, String uri, CodeBlockCondition delegate, + int headerOffset) { super(delegate, headerOffset); this.content(requestMethod.name() + " " + uri + " HTTP/1.1"); this.content(""); @@ -271,8 +256,7 @@ private HttpRequestCondition(RequestMethod requestMethod, String uri, * * @param The concrete type of the Condition */ - public abstract static class TableCondition> - extends AbstractSnippetContentCondition { + public abstract static class TableCondition> extends AbstractSnippetContentCondition { public abstract T row(String... entries); @@ -283,16 +267,14 @@ public abstract static class TableCondition> /** * A {@link Condition} for an Asciidoctor table. */ - public static final class AsciidoctorTableCondition - extends TableCondition { + public static final class AsciidoctorTableCondition extends TableCondition { private AsciidoctorTableCondition(String title, String... columns) { if (StringUtils.hasText(title)) { this.addLine("." + title); } this.addLine("|==="); - String header = "|" + StringUtils - .collectionToDelimitedString(Arrays.asList(columns), "|"); + String header = "|" + StringUtils.collectionToDelimitedString(Arrays.asList(columns), "|"); this.addLine(header); this.addLine(""); this.addLine("|==="); @@ -325,16 +307,14 @@ public AsciidoctorTableCondition configuration(String configuration) { /** * A {@link Condition} for a Markdown table. */ - public static final class MarkdownTableCondition - extends TableCondition { + public static final class MarkdownTableCondition extends TableCondition { private MarkdownTableCondition(String title, String... columns) { if (StringUtils.hasText(title)) { this.addLine(title); this.addLine(""); } - String header = StringUtils - .collectionToDelimitedString(Arrays.asList(columns), " | "); + String header = StringUtils.collectionToDelimitedString(Arrays.asList(columns), " | "); this.addLine(header); List components = new ArrayList<>(); for (String column : columns) { @@ -350,15 +330,13 @@ private MarkdownTableCondition(String title, String... columns) { @Override public MarkdownTableCondition row(String... entries) { - this.addLine(-1, StringUtils - .collectionToDelimitedString(Arrays.asList(entries), " | ")); + this.addLine(-1, StringUtils.collectionToDelimitedString(Arrays.asList(entries), " | ")); return this; } @Override public MarkdownTableCondition configuration(String configuration) { - throw new UnsupportedOperationException( - "Markdown does not support table configuration"); + throw new UnsupportedOperationException("Markdown does not support table configuration"); } } diff --git a/spring-restdocs-mockmvc/src/main/java/org/springframework/restdocs/mockmvc/MockMvcRequestConverter.java b/spring-restdocs-mockmvc/src/main/java/org/springframework/restdocs/mockmvc/MockMvcRequestConverter.java index d8a975258..710e580df 100644 --- a/spring-restdocs-mockmvc/src/main/java/org/springframework/restdocs/mockmvc/MockMvcRequestConverter.java +++ b/spring-restdocs-mockmvc/src/main/java/org/springframework/restdocs/mockmvc/MockMvcRequestConverter.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-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. @@ -70,32 +70,27 @@ public OperationRequest convert(MockHttpServletRequest mockRequest) { List parts = extractParts(mockRequest); Collection cookies = extractCookies(mockRequest, headers); String queryString = mockRequest.getQueryString(); - if (!StringUtils.hasText(queryString) - && "GET".equals(mockRequest.getMethod())) { + if (!StringUtils.hasText(queryString) && "GET".equals(mockRequest.getMethod())) { queryString = parameters.toQueryString(); } return new OperationRequestFactory().create( URI.create( - getRequestUri(mockRequest) + (StringUtils.hasText(queryString) - ? "?" + queryString : "")), + getRequestUri(mockRequest) + (StringUtils.hasText(queryString) ? "?" + queryString : "")), HttpMethod.valueOf(mockRequest.getMethod()), - FileCopyUtils.copyToByteArray(mockRequest.getInputStream()), headers, - parameters, parts, cookies); + FileCopyUtils.copyToByteArray(mockRequest.getInputStream()), headers, parameters, parts, cookies); } catch (Exception ex) { throw new ConversionException(ex); } } - private Collection extractCookies(MockHttpServletRequest mockRequest, - HttpHeaders headers) { + private Collection extractCookies(MockHttpServletRequest mockRequest, HttpHeaders headers) { if (mockRequest.getCookies() == null || mockRequest.getCookies().length == 0) { return Collections.emptyList(); } List cookies = new ArrayList<>(); for (javax.servlet.http.Cookie servletCookie : mockRequest.getCookies()) { - cookies.add( - new RequestCookie(servletCookie.getName(), servletCookie.getValue())); + cookies.add(new RequestCookie(servletCookie.getName(), servletCookie.getValue())); } headers.remove(HttpHeaders.COOKIE); return cookies; @@ -106,14 +101,13 @@ private List extractParts(MockHttpServletRequest servletRe List parts = new ArrayList<>(); parts.addAll(extractServletRequestParts(servletRequest)); if (servletRequest instanceof MockMultipartHttpServletRequest) { - parts.addAll(extractMultipartRequestParts( - (MockMultipartHttpServletRequest) servletRequest)); + parts.addAll(extractMultipartRequestParts((MockMultipartHttpServletRequest) servletRequest)); } return parts; } - private List extractServletRequestParts( - MockHttpServletRequest servletRequest) throws IOException, ServletException { + private List extractServletRequestParts(MockHttpServletRequest servletRequest) + throws IOException, ServletException { List parts = new ArrayList<>(); for (Part part : servletRequest.getParts()) { parts.add(createOperationRequestPart(part)); @@ -121,24 +115,21 @@ private List extractServletRequestParts( return parts; } - private OperationRequestPart createOperationRequestPart(Part part) - throws IOException { + private OperationRequestPart createOperationRequestPart(Part part) throws IOException { HttpHeaders partHeaders = extractHeaders(part); List contentTypeHeader = partHeaders.get(HttpHeaders.CONTENT_TYPE); if (part.getContentType() != null && contentTypeHeader == null) { partHeaders.setContentType(MediaType.parseMediaType(part.getContentType())); } return new OperationRequestPartFactory().create(part.getName(), - StringUtils.hasText(part.getSubmittedFileName()) - ? part.getSubmittedFileName() : null, + StringUtils.hasText(part.getSubmittedFileName()) ? part.getSubmittedFileName() : null, FileCopyUtils.copyToByteArray(part.getInputStream()), partHeaders); } - private List extractMultipartRequestParts( - MockMultipartHttpServletRequest multipartRequest) throws IOException { + private List extractMultipartRequestParts(MockMultipartHttpServletRequest multipartRequest) + throws IOException { List parts = new ArrayList<>(); - for (Entry> entry : multipartRequest.getMultiFileMap() - .entrySet()) { + for (Entry> entry : multipartRequest.getMultiFileMap().entrySet()) { for (MultipartFile file : entry.getValue()) { parts.add(createOperationRequestPart(file)); } @@ -146,16 +137,14 @@ private List extractMultipartRequestParts( return parts; } - private OperationRequestPart createOperationRequestPart(MultipartFile file) - throws IOException { + private OperationRequestPart createOperationRequestPart(MultipartFile file) throws IOException { HttpHeaders partHeaders = new HttpHeaders(); if (StringUtils.hasText(file.getContentType())) { partHeaders.setContentType(MediaType.parseMediaType(file.getContentType())); } return new OperationRequestPartFactory().create(file.getName(), - StringUtils.hasText(file.getOriginalFilename()) - ? file.getOriginalFilename() : null, - file.getBytes(), partHeaders); + StringUtils.hasText(file.getOriginalFilename()) ? file.getOriginalFilename() : null, file.getBytes(), + partHeaders); } private HttpHeaders extractHeaders(Part part) { @@ -180,10 +169,8 @@ private Parameters extractParameters(MockHttpServletRequest servletRequest) { private HttpHeaders extractHeaders(MockHttpServletRequest servletRequest) { HttpHeaders headers = new HttpHeaders(); - for (String headerName : IterableEnumeration - .of(servletRequest.getHeaderNames())) { - for (String value : IterableEnumeration - .of(servletRequest.getHeaders(headerName))) { + for (String headerName : IterableEnumeration.of(servletRequest.getHeaderNames())) { + for (String value : IterableEnumeration.of(servletRequest.getHeaders(headerName))) { headers.add(headerName, value); } } @@ -191,10 +178,8 @@ private HttpHeaders extractHeaders(MockHttpServletRequest servletRequest) { } private boolean isNonStandardPort(MockHttpServletRequest request) { - return (SCHEME_HTTP.equals(request.getScheme()) - && request.getServerPort() != STANDARD_PORT_HTTP) - || (SCHEME_HTTPS.equals(request.getScheme()) - && request.getServerPort() != STANDARD_PORT_HTTPS); + return (SCHEME_HTTP.equals(request.getScheme()) && request.getServerPort() != STANDARD_PORT_HTTP) + || (SCHEME_HTTPS.equals(request.getScheme()) && request.getServerPort() != STANDARD_PORT_HTTPS); } private String getRequestUri(MockHttpServletRequest request) { diff --git a/spring-restdocs-mockmvc/src/main/java/org/springframework/restdocs/mockmvc/MockMvcResponseConverter.java b/spring-restdocs-mockmvc/src/main/java/org/springframework/restdocs/mockmvc/MockMvcResponseConverter.java index 8a55f5e10..8e1e49aaa 100644 --- a/spring-restdocs-mockmvc/src/main/java/org/springframework/restdocs/mockmvc/MockMvcResponseConverter.java +++ b/spring-restdocs-mockmvc/src/main/java/org/springframework/restdocs/mockmvc/MockMvcResponseConverter.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2017 the original author or authors. + * Copyright 2014-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. @@ -36,8 +36,7 @@ class MockMvcResponseConverter implements ResponseConverter( - identifier, REQUEST_CONVERTER, RESPONSE_CONVERTER, snippets)); + public static RestDocumentationResultHandler document(String identifier, Snippet... snippets) { + return new RestDocumentationResultHandler( + new RestDocumentationGenerator<>(identifier, REQUEST_CONVERTER, RESPONSE_CONVERTER, snippets)); } /** @@ -97,9 +95,8 @@ public static RestDocumentationResultHandler document(String identifier, */ public static RestDocumentationResultHandler document(String identifier, OperationRequestPreprocessor requestPreprocessor, Snippet... snippets) { - return new RestDocumentationResultHandler( - new RestDocumentationGenerator<>(identifier, REQUEST_CONVERTER, - RESPONSE_CONVERTER, requestPreprocessor, snippets)); + return new RestDocumentationResultHandler(new RestDocumentationGenerator<>(identifier, REQUEST_CONVERTER, + RESPONSE_CONVERTER, requestPreprocessor, snippets)); } /** @@ -115,9 +112,8 @@ public static RestDocumentationResultHandler document(String identifier, */ public static RestDocumentationResultHandler document(String identifier, OperationResponsePreprocessor responsePreprocessor, Snippet... snippets) { - return new RestDocumentationResultHandler( - new RestDocumentationGenerator<>(identifier, REQUEST_CONVERTER, - RESPONSE_CONVERTER, responsePreprocessor, snippets)); + return new RestDocumentationResultHandler(new RestDocumentationGenerator<>(identifier, REQUEST_CONVERTER, + RESPONSE_CONVERTER, responsePreprocessor, snippets)); } /** @@ -134,11 +130,10 @@ public static RestDocumentationResultHandler document(String identifier, * @see ResultActions#andDo(org.springframework.test.web.servlet.ResultHandler) */ public static RestDocumentationResultHandler document(String identifier, - OperationRequestPreprocessor requestPreprocessor, - OperationResponsePreprocessor responsePreprocessor, Snippet... snippets) { - return new RestDocumentationResultHandler(new RestDocumentationGenerator<>( - identifier, REQUEST_CONVERTER, RESPONSE_CONVERTER, requestPreprocessor, - responsePreprocessor, snippets)); + OperationRequestPreprocessor requestPreprocessor, OperationResponsePreprocessor responsePreprocessor, + Snippet... snippets) { + return new RestDocumentationResultHandler(new RestDocumentationGenerator<>(identifier, REQUEST_CONVERTER, + RESPONSE_CONVERTER, requestPreprocessor, responsePreprocessor, snippets)); } } diff --git a/spring-restdocs-mockmvc/src/main/java/org/springframework/restdocs/mockmvc/MockMvcRestDocumentationConfigurer.java b/spring-restdocs-mockmvc/src/main/java/org/springframework/restdocs/mockmvc/MockMvcRestDocumentationConfigurer.java index dddbfbc27..2dcc19305 100644 --- a/spring-restdocs-mockmvc/src/main/java/org/springframework/restdocs/mockmvc/MockMvcRestDocumentationConfigurer.java +++ b/spring-restdocs-mockmvc/src/main/java/org/springframework/restdocs/mockmvc/MockMvcRestDocumentationConfigurer.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-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. @@ -35,12 +35,11 @@ * @author Andy Wilkinson * @since 1.1.0 */ -public final class MockMvcRestDocumentationConfigurer extends - RestDocumentationConfigurer +public final class MockMvcRestDocumentationConfigurer + extends RestDocumentationConfigurer implements MockMvcConfigurer { - private final MockMvcSnippetConfigurer snippetConfigurer = new MockMvcSnippetConfigurer( - this); + private final MockMvcSnippetConfigurer snippetConfigurer = new MockMvcSnippetConfigurer(this); private final UriConfigurer uriConfigurer = new UriConfigurer(this); @@ -60,8 +59,8 @@ public UriConfigurer uris() { } @Override - public RequestPostProcessor beforeMockMvcCreated( - ConfigurableMockMvcBuilder builder, WebApplicationContext context) { + public RequestPostProcessor beforeMockMvcCreated(ConfigurableMockMvcBuilder builder, + WebApplicationContext context) { return new ConfigurerApplyingRequestPostProcessor(this.contextManager); } @@ -75,13 +74,11 @@ public MockMvcSnippetConfigurer snippets() { return this.snippetConfigurer; } - private final class ConfigurerApplyingRequestPostProcessor - implements RequestPostProcessor { + private final class ConfigurerApplyingRequestPostProcessor implements RequestPostProcessor { private final RestDocumentationContextProvider contextManager; - private ConfigurerApplyingRequestPostProcessor( - RestDocumentationContextProvider contextManager) { + private ConfigurerApplyingRequestPostProcessor(RestDocumentationContextProvider contextManager) { this.contextManager = contextManager; } @@ -91,15 +88,11 @@ public MockHttpServletRequest postProcessRequest(MockHttpServletRequest request) Map configuration = new HashMap<>(); configuration.put(MockHttpServletRequest.class.getName(), request); configuration.put(RestDocumentationGenerator.ATTRIBUTE_NAME_URL_TEMPLATE, - request.getAttribute( - RestDocumentationGenerator.ATTRIBUTE_NAME_URL_TEMPLATE)); + request.getAttribute(RestDocumentationGenerator.ATTRIBUTE_NAME_URL_TEMPLATE)); configuration.put(RestDocumentationContext.class.getName(), context); - request.setAttribute( - RestDocumentationResultHandler.ATTRIBUTE_NAME_CONFIGURATION, - configuration); + request.setAttribute(RestDocumentationResultHandler.ATTRIBUTE_NAME_CONFIGURATION, configuration); MockMvcRestDocumentationConfigurer.this.apply(configuration, context); - MockMvcRestDocumentationConfigurer.this.uriConfigurer.apply(configuration, - context); + MockMvcRestDocumentationConfigurer.this.uriConfigurer.apply(configuration, context); return request; } diff --git a/spring-restdocs-mockmvc/src/main/java/org/springframework/restdocs/mockmvc/MockMvcSnippetConfigurer.java b/spring-restdocs-mockmvc/src/main/java/org/springframework/restdocs/mockmvc/MockMvcSnippetConfigurer.java index 2087780e9..ef6bb5908 100644 --- a/spring-restdocs-mockmvc/src/main/java/org/springframework/restdocs/mockmvc/MockMvcSnippetConfigurer.java +++ b/spring-restdocs-mockmvc/src/main/java/org/springframework/restdocs/mockmvc/MockMvcSnippetConfigurer.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2017 the original author or authors. + * Copyright 2014-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. @@ -29,8 +29,7 @@ * @since 1.1.0 */ public final class MockMvcSnippetConfigurer extends - SnippetConfigurer - implements MockMvcConfigurer { + SnippetConfigurer implements MockMvcConfigurer { MockMvcSnippetConfigurer(MockMvcRestDocumentationConfigurer parent) { super(parent); @@ -42,8 +41,8 @@ public void afterConfigurerAdded(ConfigurableMockMvcBuilder builder) { } @Override - public RequestPostProcessor beforeMockMvcCreated( - ConfigurableMockMvcBuilder builder, WebApplicationContext context) { + public RequestPostProcessor beforeMockMvcCreated(ConfigurableMockMvcBuilder builder, + WebApplicationContext context) { return and().beforeMockMvcCreated(builder, context); } diff --git a/spring-restdocs-mockmvc/src/main/java/org/springframework/restdocs/mockmvc/RestDocumentationRequestBuilders.java b/spring-restdocs-mockmvc/src/main/java/org/springframework/restdocs/mockmvc/RestDocumentationRequestBuilders.java index fbb8926d2..0db526baf 100644 --- a/spring-restdocs-mockmvc/src/main/java/org/springframework/restdocs/mockmvc/RestDocumentationRequestBuilders.java +++ b/spring-restdocs-mockmvc/src/main/java/org/springframework/restdocs/mockmvc/RestDocumentationRequestBuilders.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2015 the original author or authors. + * Copyright 2014-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. @@ -50,10 +50,9 @@ private RestDocumentationRequestBuilders() { * @param urlVariables zero or more URL variables * @return the builder for the GET request */ - public static MockHttpServletRequestBuilder get(String urlTemplate, - Object... urlVariables) { - return MockMvcRequestBuilders.get(urlTemplate, urlVariables).requestAttr( - RestDocumentationGenerator.ATTRIBUTE_NAME_URL_TEMPLATE, urlTemplate); + public static MockHttpServletRequestBuilder get(String urlTemplate, Object... urlVariables) { + return MockMvcRequestBuilders.get(urlTemplate, urlVariables) + .requestAttr(RestDocumentationGenerator.ATTRIBUTE_NAME_URL_TEMPLATE, urlTemplate); } /** @@ -72,10 +71,9 @@ public static MockHttpServletRequestBuilder get(URI uri) { * @param urlVariables zero or more URL variables * @return the builder for the POST request */ - public static MockHttpServletRequestBuilder post(String urlTemplate, - Object... urlVariables) { - return MockMvcRequestBuilders.post(urlTemplate, urlVariables).requestAttr( - RestDocumentationGenerator.ATTRIBUTE_NAME_URL_TEMPLATE, urlTemplate); + public static MockHttpServletRequestBuilder post(String urlTemplate, Object... urlVariables) { + return MockMvcRequestBuilders.post(urlTemplate, urlVariables) + .requestAttr(RestDocumentationGenerator.ATTRIBUTE_NAME_URL_TEMPLATE, urlTemplate); } /** @@ -94,10 +92,9 @@ public static MockHttpServletRequestBuilder post(URI uri) { * @param urlVariables zero or more URL variables * @return the builder for the PUT request */ - public static MockHttpServletRequestBuilder put(String urlTemplate, - Object... urlVariables) { - return MockMvcRequestBuilders.put(urlTemplate, urlVariables).requestAttr( - RestDocumentationGenerator.ATTRIBUTE_NAME_URL_TEMPLATE, urlTemplate); + public static MockHttpServletRequestBuilder put(String urlTemplate, Object... urlVariables) { + return MockMvcRequestBuilders.put(urlTemplate, urlVariables) + .requestAttr(RestDocumentationGenerator.ATTRIBUTE_NAME_URL_TEMPLATE, urlTemplate); } /** @@ -116,10 +113,9 @@ public static MockHttpServletRequestBuilder put(URI uri) { * @param urlVariables zero or more URL variables * @return the builder for the PATCH request */ - public static MockHttpServletRequestBuilder patch(String urlTemplate, - Object... urlVariables) { - return MockMvcRequestBuilders.patch(urlTemplate, urlVariables).requestAttr( - RestDocumentationGenerator.ATTRIBUTE_NAME_URL_TEMPLATE, urlTemplate); + public static MockHttpServletRequestBuilder patch(String urlTemplate, Object... urlVariables) { + return MockMvcRequestBuilders.patch(urlTemplate, urlVariables) + .requestAttr(RestDocumentationGenerator.ATTRIBUTE_NAME_URL_TEMPLATE, urlTemplate); } /** @@ -138,10 +134,9 @@ public static MockHttpServletRequestBuilder patch(URI uri) { * @param urlVariables zero or more URL variables * @return the builder for the DELETE request */ - public static MockHttpServletRequestBuilder delete(String urlTemplate, - Object... urlVariables) { - return MockMvcRequestBuilders.delete(urlTemplate, urlVariables).requestAttr( - RestDocumentationGenerator.ATTRIBUTE_NAME_URL_TEMPLATE, urlTemplate); + public static MockHttpServletRequestBuilder delete(String urlTemplate, Object... urlVariables) { + return MockMvcRequestBuilders.delete(urlTemplate, urlVariables) + .requestAttr(RestDocumentationGenerator.ATTRIBUTE_NAME_URL_TEMPLATE, urlTemplate); } /** @@ -160,10 +155,9 @@ public static MockHttpServletRequestBuilder delete(URI uri) { * @param urlVariables zero or more URL variables * @return the builder for the OPTIONS request */ - public static MockHttpServletRequestBuilder options(String urlTemplate, - Object... urlVariables) { - return MockMvcRequestBuilders.options(urlTemplate, urlVariables).requestAttr( - RestDocumentationGenerator.ATTRIBUTE_NAME_URL_TEMPLATE, urlTemplate); + public static MockHttpServletRequestBuilder options(String urlTemplate, Object... urlVariables) { + return MockMvcRequestBuilders.options(urlTemplate, urlVariables) + .requestAttr(RestDocumentationGenerator.ATTRIBUTE_NAME_URL_TEMPLATE, urlTemplate); } /** @@ -182,10 +176,9 @@ public static MockHttpServletRequestBuilder options(URI uri) { * @param urlVariables zero or more URL variables * @return the builder for the HEAD request */ - public static MockHttpServletRequestBuilder head(String urlTemplate, - Object... urlVariables) { - return MockMvcRequestBuilders.head(urlTemplate, urlVariables).requestAttr( - RestDocumentationGenerator.ATTRIBUTE_NAME_URL_TEMPLATE, urlTemplate); + public static MockHttpServletRequestBuilder head(String urlTemplate, Object... urlVariables) { + return MockMvcRequestBuilders.head(urlTemplate, urlVariables) + .requestAttr(RestDocumentationGenerator.ATTRIBUTE_NAME_URL_TEMPLATE, urlTemplate); } /** @@ -205,11 +198,10 @@ public static MockHttpServletRequestBuilder head(URI uri) { * @param urlVariables zero or more URL variables * @return the builder for the request */ - public static MockHttpServletRequestBuilder request(HttpMethod httpMethod, - String urlTemplate, Object... urlVariables) { + public static MockHttpServletRequestBuilder request(HttpMethod httpMethod, String urlTemplate, + Object... urlVariables) { return MockMvcRequestBuilders.request(httpMethod, urlTemplate, urlVariables) - .requestAttr(RestDocumentationGenerator.ATTRIBUTE_NAME_URL_TEMPLATE, - urlTemplate); + .requestAttr(RestDocumentationGenerator.ATTRIBUTE_NAME_URL_TEMPLATE, urlTemplate); } /** @@ -230,12 +222,9 @@ public static MockHttpServletRequestBuilder request(HttpMethod httpMethod, URI u * @param urlVariables zero or more URL variables * @return the builder for the file upload request */ - public static MockMultipartHttpServletRequestBuilder fileUpload(String urlTemplate, - Object... urlVariables) { - return (MockMultipartHttpServletRequestBuilder) MockMvcRequestBuilders - .fileUpload(urlTemplate, urlVariables) - .requestAttr(RestDocumentationGenerator.ATTRIBUTE_NAME_URL_TEMPLATE, - urlTemplate); + public static MockMultipartHttpServletRequestBuilder fileUpload(String urlTemplate, Object... urlVariables) { + return (MockMultipartHttpServletRequestBuilder) MockMvcRequestBuilders.fileUpload(urlTemplate, urlVariables) + .requestAttr(RestDocumentationGenerator.ATTRIBUTE_NAME_URL_TEMPLATE, urlTemplate); } /** diff --git a/spring-restdocs-mockmvc/src/main/java/org/springframework/restdocs/mockmvc/RestDocumentationResultHandler.java b/spring-restdocs-mockmvc/src/main/java/org/springframework/restdocs/mockmvc/RestDocumentationResultHandler.java index 4787e4987..76f9c441e 100644 --- a/spring-restdocs-mockmvc/src/main/java/org/springframework/restdocs/mockmvc/RestDocumentationResultHandler.java +++ b/spring-restdocs-mockmvc/src/main/java/org/springframework/restdocs/mockmvc/RestDocumentationResultHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-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. @@ -91,12 +91,9 @@ public RestDocumentationResultHandler document(Snippet... snippets) { public void handle(MvcResult result) throws Exception { @SuppressWarnings("unchecked") Map configuration = new HashMap<>( - (Map) result.getRequest() - .getAttribute(ATTRIBUTE_NAME_CONFIGURATION)); - configuration.remove( - RestDocumentationGenerator.ATTRIBUTE_NAME_DEFAULT_SNIPPETS); - getDelegate().handle(result.getRequest(), result.getResponse(), - configuration); + (Map) result.getRequest().getAttribute(ATTRIBUTE_NAME_CONFIGURATION)); + configuration.remove(RestDocumentationGenerator.ATTRIBUTE_NAME_DEFAULT_SNIPPETS); + getDelegate().handle(result.getRequest(), result.getResponse(), configuration); } }; diff --git a/spring-restdocs-mockmvc/src/main/java/org/springframework/restdocs/mockmvc/UriConfigurer.java b/spring-restdocs-mockmvc/src/main/java/org/springframework/restdocs/mockmvc/UriConfigurer.java index 34b816a1e..4e1be3290 100644 --- a/spring-restdocs-mockmvc/src/main/java/org/springframework/restdocs/mockmvc/UriConfigurer.java +++ b/spring-restdocs-mockmvc/src/main/java/org/springframework/restdocs/mockmvc/UriConfigurer.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-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. @@ -31,8 +31,7 @@ * * @author Andy Wilkinson */ -public class UriConfigurer - extends AbstractNestedConfigurer +public class UriConfigurer extends AbstractNestedConfigurer implements MockMvcConfigurer { /** @@ -100,8 +99,7 @@ public UriConfigurer withPort(int port) { } @Override - public void apply(Map configuration, - RestDocumentationContext context) { + public void apply(Map configuration, RestDocumentationContext context) { MockHttpServletRequest request = (MockHttpServletRequest) configuration .get(MockHttpServletRequest.class.getName()); request.setScheme(this.scheme); @@ -115,8 +113,8 @@ public void afterConfigurerAdded(ConfigurableMockMvcBuilder builder) { } @Override - public RequestPostProcessor beforeMockMvcCreated( - ConfigurableMockMvcBuilder builder, WebApplicationContext context) { + public RequestPostProcessor beforeMockMvcCreated(ConfigurableMockMvcBuilder builder, + WebApplicationContext context) { return and().beforeMockMvcCreated(builder, context); } diff --git a/spring-restdocs-mockmvc/src/test/java/org/springframework/restdocs/mockmvc/MockMvcRequestConverterTests.java b/spring-restdocs-mockmvc/src/test/java/org/springframework/restdocs/mockmvc/MockMvcRequestConverterTests.java index fca910351..d4588f119 100644 --- a/spring-restdocs-mockmvc/src/test/java/org/springframework/restdocs/mockmvc/MockMvcRequestConverterTests.java +++ b/spring-restdocs-mockmvc/src/test/java/org/springframework/restdocs/mockmvc/MockMvcRequestConverterTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-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. @@ -51,16 +51,14 @@ public class MockMvcRequestConverterTests { @Test public void httpRequest() throws Exception { - OperationRequest request = createOperationRequest( - MockMvcRequestBuilders.get("/foo")); + OperationRequest request = createOperationRequest(MockMvcRequestBuilders.get("/foo")); assertThat(request.getUri()).isEqualTo(URI.create("http://localhost/foo")); assertThat(request.getMethod()).isEqualTo(HttpMethod.GET); } @Test public void httpRequestWithCustomPort() throws Exception { - MockHttpServletRequest mockRequest = MockMvcRequestBuilders.get("/foo") - .buildRequest(new MockServletContext()); + MockHttpServletRequest mockRequest = MockMvcRequestBuilders.get("/foo").buildRequest(new MockServletContext()); mockRequest.setServerPort(8080); OperationRequest request = this.factory.convert(mockRequest); assertThat(request.getUri()).isEqualTo(URI.create("http://localhost:8080/foo")); @@ -69,28 +67,25 @@ public void httpRequestWithCustomPort() throws Exception { @Test public void requestWithContextPath() throws Exception { - OperationRequest request = createOperationRequest( - MockMvcRequestBuilders.get("/foo/bar").contextPath("/foo")); + OperationRequest request = createOperationRequest(MockMvcRequestBuilders.get("/foo/bar").contextPath("/foo")); assertThat(request.getUri()).isEqualTo(URI.create("http://localhost/foo/bar")); assertThat(request.getMethod()).isEqualTo(HttpMethod.GET); } @Test public void requestWithHeaders() throws Exception { - OperationRequest request = createOperationRequest(MockMvcRequestBuilders - .get("/foo").header("a", "alpha", "apple").header("b", "bravo")); + OperationRequest request = createOperationRequest( + MockMvcRequestBuilders.get("/foo").header("a", "alpha", "apple").header("b", "bravo")); assertThat(request.getUri()).isEqualTo(URI.create("http://localhost/foo")); assertThat(request.getMethod()).isEqualTo(HttpMethod.GET); - assertThat(request.getHeaders()).containsEntry("a", - Arrays.asList("alpha", "apple")); + assertThat(request.getHeaders()).containsEntry("a", Arrays.asList("alpha", "apple")); assertThat(request.getHeaders()).containsEntry("b", Arrays.asList("bravo")); } @Test public void requestWithCookies() throws Exception { OperationRequest request = createOperationRequest( - MockMvcRequestBuilders.get("/foo").cookie( - new javax.servlet.http.Cookie("cookieName1", "cookieVal1"), + MockMvcRequestBuilders.get("/foo").cookie(new javax.servlet.http.Cookie("cookieName1", "cookieVal1"), new javax.servlet.http.Cookie("cookieName2", "cookieVal2"))); assertThat(request.getUri()).isEqualTo(URI.create("http://localhost/foo")); assertThat(request.getMethod()).isEqualTo(HttpMethod.GET); @@ -109,8 +104,7 @@ public void requestWithCookies() throws Exception { @Test public void httpsRequest() throws Exception { - MockHttpServletRequest mockRequest = MockMvcRequestBuilders.get("/foo") - .buildRequest(new MockServletContext()); + MockHttpServletRequest mockRequest = MockMvcRequestBuilders.get("/foo").buildRequest(new MockServletContext()); mockRequest.setScheme("https"); mockRequest.setServerPort(443); OperationRequest request = this.factory.convert(mockRequest); @@ -120,8 +114,7 @@ public void httpsRequest() throws Exception { @Test public void httpsRequestWithCustomPort() throws Exception { - MockHttpServletRequest mockRequest = MockMvcRequestBuilders.get("/foo") - .buildRequest(new MockServletContext()); + MockHttpServletRequest mockRequest = MockMvcRequestBuilders.get("/foo").buildRequest(new MockServletContext()); mockRequest.setScheme("https"); mockRequest.setServerPort(8443); OperationRequest request = this.factory.convert(mockRequest); @@ -131,23 +124,19 @@ public void httpsRequestWithCustomPort() throws Exception { @Test public void getRequestWithParametersProducesUriWithQueryString() throws Exception { - OperationRequest request = createOperationRequest(MockMvcRequestBuilders - .get("/foo").param("a", "alpha", "apple").param("b", "br&vo")); - assertThat(request.getUri()) - .isEqualTo(URI.create("http://localhost/foo?a=alpha&a=apple&b=br%26vo")); + OperationRequest request = createOperationRequest( + MockMvcRequestBuilders.get("/foo").param("a", "alpha", "apple").param("b", "br&vo")); + assertThat(request.getUri()).isEqualTo(URI.create("http://localhost/foo?a=alpha&a=apple&b=br%26vo")); assertThat(request.getParameters().size()).isEqualTo(2); - assertThat(request.getParameters()).containsEntry("a", - Arrays.asList("alpha", "apple")); + assertThat(request.getParameters()).containsEntry("a", Arrays.asList("alpha", "apple")); assertThat(request.getParameters()).containsEntry("b", Arrays.asList("br&vo")); assertThat(request.getMethod()).isEqualTo(HttpMethod.GET); } @Test public void getRequestWithQueryStringPopulatesParameters() throws Exception { - OperationRequest request = createOperationRequest( - MockMvcRequestBuilders.get("/foo?a=alpha&b=bravo")); - assertThat(request.getUri()) - .isEqualTo(URI.create("http://localhost/foo?a=alpha&b=bravo")); + OperationRequest request = createOperationRequest(MockMvcRequestBuilders.get("/foo?a=alpha&b=bravo")); + assertThat(request.getUri()).isEqualTo(URI.create("http://localhost/foo?a=alpha&b=bravo")); assertThat(request.getParameters().size()).isEqualTo(2); assertThat(request.getParameters()).containsEntry("a", Arrays.asList("alpha")); assertThat(request.getParameters()).containsEntry("b", Arrays.asList("bravo")); @@ -156,21 +145,19 @@ public void getRequestWithQueryStringPopulatesParameters() throws Exception { @Test public void postRequestWithParameters() throws Exception { - OperationRequest request = createOperationRequest(MockMvcRequestBuilders - .post("/foo").param("a", "alpha", "apple").param("b", "br&vo")); + OperationRequest request = createOperationRequest( + MockMvcRequestBuilders.post("/foo").param("a", "alpha", "apple").param("b", "br&vo")); assertThat(request.getUri()).isEqualTo(URI.create("http://localhost/foo")); assertThat(request.getMethod()).isEqualTo(HttpMethod.POST); assertThat(request.getParameters().size()).isEqualTo(2); - assertThat(request.getParameters()).containsEntry("a", - Arrays.asList("alpha", "apple")); + assertThat(request.getParameters()).containsEntry("a", Arrays.asList("alpha", "apple")); assertThat(request.getParameters()).containsEntry("b", Arrays.asList("br&vo")); } @Test public void mockMultipartFileUpload() throws Exception { - OperationRequest request = createOperationRequest( - MockMvcRequestBuilders.fileUpload("/foo") - .file(new MockMultipartFile("file", new byte[] { 1, 2, 3, 4 }))); + OperationRequest request = createOperationRequest(MockMvcRequestBuilders.fileUpload("/foo") + .file(new MockMultipartFile("file", new byte[] { 1, 2, 3, 4 }))); assertThat(request.getUri()).isEqualTo(URI.create("http://localhost/foo")); assertThat(request.getMethod()).isEqualTo(HttpMethod.POST); assertThat(request.getParts().size()).isEqualTo(1); @@ -184,9 +171,8 @@ public void mockMultipartFileUpload() throws Exception { @Test public void mockMultipartFileUploadWithContentType() throws Exception { - OperationRequest request = createOperationRequest( - MockMvcRequestBuilders.fileUpload("/foo").file(new MockMultipartFile( - "file", "original", "image/png", new byte[] { 1, 2, 3, 4 }))); + OperationRequest request = createOperationRequest(MockMvcRequestBuilders.fileUpload("/foo") + .file(new MockMultipartFile("file", "original", "image/png", new byte[] { 1, 2, 3, 4 }))); assertThat(request.getUri()).isEqualTo(URI.create("http://localhost/foo")); assertThat(request.getMethod()).isEqualTo(HttpMethod.POST); assertThat(request.getParts().size()).isEqualTo(1); @@ -199,14 +185,12 @@ public void mockMultipartFileUploadWithContentType() throws Exception { @Test public void requestWithPart() throws Exception { - MockHttpServletRequest mockRequest = MockMvcRequestBuilders.get("/foo") - .buildRequest(new MockServletContext()); + MockHttpServletRequest mockRequest = MockMvcRequestBuilders.get("/foo").buildRequest(new MockServletContext()); Part mockPart = mock(Part.class); given(mockPart.getHeaderNames()).willReturn(Arrays.asList("a", "b")); given(mockPart.getHeaders("a")).willReturn(Arrays.asList("alpha")); given(mockPart.getHeaders("b")).willReturn(Arrays.asList("bravo", "banana")); - given(mockPart.getInputStream()) - .willReturn(new ByteArrayInputStream(new byte[] { 1, 2, 3, 4 })); + given(mockPart.getInputStream()).willReturn(new ByteArrayInputStream(new byte[] { 1, 2, 3, 4 })); given(mockPart.getName()).willReturn("part-name"); given(mockPart.getSubmittedFileName()).willReturn("submitted.txt"); mockRequest.addPart(mockPart); @@ -223,14 +207,12 @@ public void requestWithPart() throws Exception { @Test public void requestWithPartWithContentType() throws Exception { - MockHttpServletRequest mockRequest = MockMvcRequestBuilders.get("/foo") - .buildRequest(new MockServletContext()); + MockHttpServletRequest mockRequest = MockMvcRequestBuilders.get("/foo").buildRequest(new MockServletContext()); Part mockPart = mock(Part.class); given(mockPart.getHeaderNames()).willReturn(Arrays.asList("a", "b")); given(mockPart.getHeaders("a")).willReturn(Arrays.asList("alpha")); given(mockPart.getHeaders("b")).willReturn(Arrays.asList("bravo", "banana")); - given(mockPart.getInputStream()) - .willReturn(new ByteArrayInputStream(new byte[] { 1, 2, 3, 4 })); + given(mockPart.getInputStream()).willReturn(new ByteArrayInputStream(new byte[] { 1, 2, 3, 4 })); given(mockPart.getName()).willReturn("part-name"); given(mockPart.getSubmittedFileName()).willReturn("submitted.png"); given(mockPart.getContentType()).willReturn("image/png"); @@ -246,8 +228,7 @@ public void requestWithPartWithContentType() throws Exception { assertThat(part.getContent()).isEqualTo(new byte[] { 1, 2, 3, 4 }); } - private OperationRequest createOperationRequest(MockHttpServletRequestBuilder builder) - throws Exception { + private OperationRequest createOperationRequest(MockHttpServletRequestBuilder builder) throws Exception { return this.factory.convert(builder.buildRequest(new MockServletContext())); } diff --git a/spring-restdocs-mockmvc/src/test/java/org/springframework/restdocs/mockmvc/MockMvcRestDocumentationConfigurerTests.java b/spring-restdocs-mockmvc/src/test/java/org/springframework/restdocs/mockmvc/MockMvcRestDocumentationConfigurerTests.java index 3e27a64a4..966ecdf3a 100644 --- a/spring-restdocs-mockmvc/src/test/java/org/springframework/restdocs/mockmvc/MockMvcRestDocumentationConfigurerTests.java +++ b/spring-restdocs-mockmvc/src/test/java/org/springframework/restdocs/mockmvc/MockMvcRestDocumentationConfigurerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-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. @@ -45,44 +45,40 @@ public class MockMvcRestDocumentationConfigurerTests { @Test public void defaultConfiguration() { - RequestPostProcessor postProcessor = new MockMvcRestDocumentationConfigurer( - this.restDocumentation).beforeMockMvcCreated(null, null); + RequestPostProcessor postProcessor = new MockMvcRestDocumentationConfigurer(this.restDocumentation) + .beforeMockMvcCreated(null, null); postProcessor.postProcessRequest(this.request); assertUriConfiguration("http", "localhost", 8080); } @Test public void customScheme() { - RequestPostProcessor postProcessor = new MockMvcRestDocumentationConfigurer( - this.restDocumentation).uris().withScheme("https") - .beforeMockMvcCreated(null, null); + RequestPostProcessor postProcessor = new MockMvcRestDocumentationConfigurer(this.restDocumentation).uris() + .withScheme("https").beforeMockMvcCreated(null, null); postProcessor.postProcessRequest(this.request); assertUriConfiguration("https", "localhost", 8080); } @Test public void customHost() { - RequestPostProcessor postProcessor = new MockMvcRestDocumentationConfigurer( - this.restDocumentation).uris().withHost("api.example.com") - .beforeMockMvcCreated(null, null); + RequestPostProcessor postProcessor = new MockMvcRestDocumentationConfigurer(this.restDocumentation).uris() + .withHost("api.example.com").beforeMockMvcCreated(null, null); postProcessor.postProcessRequest(this.request); assertUriConfiguration("http", "api.example.com", 8080); } @Test public void customPort() { - RequestPostProcessor postProcessor = new MockMvcRestDocumentationConfigurer( - this.restDocumentation).uris().withPort(8081).beforeMockMvcCreated(null, - null); + RequestPostProcessor postProcessor = new MockMvcRestDocumentationConfigurer(this.restDocumentation).uris() + .withPort(8081).beforeMockMvcCreated(null, null); postProcessor.postProcessRequest(this.request); assertUriConfiguration("http", "localhost", 8081); } @Test public void noContentLengthHeaderWhenRequestHasNotContent() { - RequestPostProcessor postProcessor = new MockMvcRestDocumentationConfigurer( - this.restDocumentation).uris().withPort(8081).beforeMockMvcCreated(null, - null); + RequestPostProcessor postProcessor = new MockMvcRestDocumentationConfigurer(this.restDocumentation).uris() + .withPort(8081).beforeMockMvcCreated(null, null); postProcessor.postProcessRequest(this.request); assertThat(this.request.getHeader("Content-Length")).isNull(); } @@ -91,8 +87,7 @@ private void assertUriConfiguration(String scheme, String host, int port) { assertThat(scheme).isEqualTo(this.request.getScheme()); assertThat(host).isEqualTo(this.request.getServerName()); assertThat(port).isEqualTo(this.request.getServerPort()); - RequestContextHolder - .setRequestAttributes(new ServletRequestAttributes(this.request)); + RequestContextHolder.setRequestAttributes(new ServletRequestAttributes(this.request)); try { URI uri = BasicLinkBuilder.linkToCurrentMapping().toUri(); assertThat(scheme).isEqualTo(uri.getScheme()); diff --git a/spring-restdocs-mockmvc/src/test/java/org/springframework/restdocs/mockmvc/MockMvcRestDocumentationIntegrationTests.java b/spring-restdocs-mockmvc/src/test/java/org/springframework/restdocs/mockmvc/MockMvcRestDocumentationIntegrationTests.java index 190d5e4e5..29d9236ca 100644 --- a/spring-restdocs-mockmvc/src/test/java/org/springframework/restdocs/mockmvc/MockMvcRestDocumentationIntegrationTests.java +++ b/spring-restdocs-mockmvc/src/test/java/org/springframework/restdocs/mockmvc/MockMvcRestDocumentationIntegrationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-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. @@ -127,26 +127,23 @@ public void clearOutputDirSystemProperty() { @Test public void basicSnippetGeneration() throws Exception { MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(this.context) - .apply(new MockMvcRestDocumentationConfigurer(this.restDocumentation) - .snippets().withEncoding("UTF-8")) + .apply(new MockMvcRestDocumentationConfigurer(this.restDocumentation).snippets().withEncoding("UTF-8")) .build(); - mockMvc.perform(get("/").accept(MediaType.APPLICATION_JSON)) - .andExpect(status().isOk()).andDo(document("basic")); - assertExpectedSnippetFilesExist(new File("build/generated-snippets/basic"), - "http-request.adoc", "http-response.adoc", "curl-request.adoc"); + mockMvc.perform(get("/").accept(MediaType.APPLICATION_JSON)).andExpect(status().isOk()) + .andDo(document("basic")); + assertExpectedSnippetFilesExist(new File("build/generated-snippets/basic"), "http-request.adoc", + "http-response.adoc", "curl-request.adoc"); } @Test public void markdownSnippetGeneration() throws Exception { MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(this.context) - .apply(new MockMvcRestDocumentationConfigurer(this.restDocumentation) - .snippets().withEncoding("UTF-8") + .apply(new MockMvcRestDocumentationConfigurer(this.restDocumentation).snippets().withEncoding("UTF-8") .withTemplateFormat(TemplateFormats.markdown())) .build(); - mockMvc.perform(get("/").accept(MediaType.APPLICATION_JSON)) - .andExpect(status().isOk()).andDo(document("basic-markdown")); - assertExpectedSnippetFilesExist( - new File("build/generated-snippets/basic-markdown"), "http-request.md", + mockMvc.perform(get("/").accept(MediaType.APPLICATION_JSON)).andExpect(status().isOk()) + .andDo(document("basic-markdown")); + assertExpectedSnippetFilesExist(new File("build/generated-snippets/basic-markdown"), "http-request.md", "http-response.md", "curl-request.md"); } @@ -154,186 +151,147 @@ public void markdownSnippetGeneration() throws Exception { public void curlSnippetWithContent() throws Exception { MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(this.context) .apply(documentationConfiguration(this.restDocumentation)).build(); - mockMvc.perform(post("/").accept(MediaType.APPLICATION_JSON).content("content")) - .andExpect(status().isOk()).andDo(document("curl-snippet-with-content")); - assertThat(new File( - "build/generated-snippets/curl-snippet-with-content/curl-request.adoc")) - .has(content(codeBlock(TemplateFormats.asciidoctor(), "bash") - .withContent(String.format( - "$ curl 'http://localhost:8080/' -i -X POST \\%n" - + " -H 'Accept: application/json' \\%n" - + " -d 'content'")))); + mockMvc.perform(post("/").accept(MediaType.APPLICATION_JSON).content("content")).andExpect(status().isOk()) + .andDo(document("curl-snippet-with-content")); + assertThat(new File("build/generated-snippets/curl-snippet-with-content/curl-request.adoc")) + .has(content(codeBlock(TemplateFormats.asciidoctor(), "bash") + .withContent(String.format("$ curl 'http://localhost:8080/' -i -X POST \\%n" + + " -H 'Accept: application/json' \\%n" + " -d 'content'")))); } @Test public void curlSnippetWithCookies() throws Exception { MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(this.context) .apply(documentationConfiguration(this.restDocumentation)).build(); - mockMvc.perform(get("/").accept(MediaType.APPLICATION_JSON) - .cookie(new Cookie("cookieName", "cookieVal"))).andExpect(status().isOk()) - .andDo(document("curl-snippet-with-cookies")); - assertThat(new File( - "build/generated-snippets/curl-snippet-with-cookies/curl-request.adoc")) - .has(content(codeBlock(TemplateFormats.asciidoctor(), "bash") - .withContent(String.format( - "$ curl 'http://localhost:8080/' -i -X GET \\%n" - + " -H 'Accept: application/json' \\%n" - + " --cookie 'cookieName=cookieVal'")))); + mockMvc.perform(get("/").accept(MediaType.APPLICATION_JSON).cookie(new Cookie("cookieName", "cookieVal"))) + .andExpect(status().isOk()).andDo(document("curl-snippet-with-cookies")); + assertThat(new File("build/generated-snippets/curl-snippet-with-cookies/curl-request.adoc")) + .has(content(codeBlock(TemplateFormats.asciidoctor(), "bash") + .withContent(String.format("$ curl 'http://localhost:8080/' -i -X GET \\%n" + + " -H 'Accept: application/json' \\%n" + " --cookie 'cookieName=cookieVal'")))); } @Test public void curlSnippetWithQueryStringOnPost() throws Exception { MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(this.context) .apply(documentationConfiguration(this.restDocumentation)).build(); - mockMvc.perform(post("/?foo=bar").param("foo", "bar").param("a", "alpha") - .accept(MediaType.APPLICATION_JSON)).andExpect(status().isOk()) - .andDo(document("curl-snippet-with-query-string")); - assertThat(new File( - "build/generated-snippets/curl-snippet-with-query-string/curl-request.adoc")) - .has(content(codeBlock(TemplateFormats.asciidoctor(), "bash") - .withContent(String.format("$ curl " - + "'http://localhost:8080/?foo=bar' -i -X POST \\%n" - + " -H 'Accept: application/json' \\%n" - + " -d 'a=alpha'")))); + mockMvc.perform(post("/?foo=bar").param("foo", "bar").param("a", "alpha").accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()).andDo(document("curl-snippet-with-query-string")); + assertThat(new File("build/generated-snippets/curl-snippet-with-query-string/curl-request.adoc")) + .has(content(codeBlock(TemplateFormats.asciidoctor(), "bash") + .withContent(String.format("$ curl " + "'http://localhost:8080/?foo=bar' -i -X POST \\%n" + + " -H 'Accept: application/json' \\%n" + " -d 'a=alpha'")))); } @Test public void curlSnippetWithContentAndParametersOnPost() throws Exception { MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(this.context) .apply(documentationConfiguration(this.restDocumentation)).build(); - mockMvc.perform(post("/").param("a", "alpha").accept(MediaType.APPLICATION_JSON) - .content("some content")).andExpect(status().isOk()) - .andDo(document("curl-snippet-with-content-and-parameters")); - assertThat(new File( - "build/generated-snippets/curl-snippet-with-content-and-parameters/curl-request.adoc")) - .has(content(codeBlock(TemplateFormats.asciidoctor(), "bash") - .withContent(String.format( - "$ curl 'http://localhost:8080/?a=alpha' -i -X POST \\%n" - + " -H 'Accept: application/json' \\%n" - + " -d 'some content'")))); + mockMvc.perform(post("/").param("a", "alpha").accept(MediaType.APPLICATION_JSON).content("some content")) + .andExpect(status().isOk()).andDo(document("curl-snippet-with-content-and-parameters")); + assertThat(new File("build/generated-snippets/curl-snippet-with-content-and-parameters/curl-request.adoc")) + .has(content(codeBlock(TemplateFormats.asciidoctor(), "bash") + .withContent(String.format("$ curl 'http://localhost:8080/?a=alpha' -i -X POST \\%n" + + " -H 'Accept: application/json' \\%n" + " -d 'some content'")))); } @Test public void httpieSnippetWithContent() throws Exception { MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(this.context) .apply(documentationConfiguration(this.restDocumentation)).build(); - mockMvc.perform(post("/").accept(MediaType.APPLICATION_JSON).content("content")) - .andExpect(status().isOk()) + mockMvc.perform(post("/").accept(MediaType.APPLICATION_JSON).content("content")).andExpect(status().isOk()) .andDo(document("httpie-snippet-with-content")); - assertThat(new File( - "build/generated-snippets/httpie-snippet-with-content/httpie-request.adoc")) - .has(content(codeBlock(TemplateFormats.asciidoctor(), "bash") - .withContent(String.format("$ echo 'content' | " - + "http POST 'http://localhost:8080/' \\%n" - + " 'Accept:application/json'")))); + assertThat(new File("build/generated-snippets/httpie-snippet-with-content/httpie-request.adoc")).has( + content(codeBlock(TemplateFormats.asciidoctor(), "bash").withContent(String.format("$ echo 'content' | " + + "http POST 'http://localhost:8080/' \\%n" + " 'Accept:application/json'")))); } @Test public void httpieSnippetWithCookies() throws Exception { MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(this.context) .apply(documentationConfiguration(this.restDocumentation)).build(); - mockMvc.perform(get("/").accept(MediaType.APPLICATION_JSON) - .cookie(new Cookie("cookieName", "cookieVal"))).andExpect(status().isOk()) - .andDo(document("httpie-snippet-with-cookies")); - assertThat(new File( - "build/generated-snippets/httpie-snippet-with-cookies/httpie-request.adoc")) - .has(content(codeBlock(TemplateFormats.asciidoctor(), "bash") - .withContent(String - .format("$ http GET 'http://localhost:8080/' \\%n" - + " 'Accept:application/json' \\%n" - + " 'Cookie:cookieName=cookieVal'")))); + mockMvc.perform(get("/").accept(MediaType.APPLICATION_JSON).cookie(new Cookie("cookieName", "cookieVal"))) + .andExpect(status().isOk()).andDo(document("httpie-snippet-with-cookies")); + assertThat(new File("build/generated-snippets/httpie-snippet-with-cookies/httpie-request.adoc")) + .has(content(codeBlock(TemplateFormats.asciidoctor(), "bash") + .withContent(String.format("$ http GET 'http://localhost:8080/' \\%n" + + " 'Accept:application/json' \\%n" + " 'Cookie:cookieName=cookieVal'")))); } @Test public void httpieSnippetWithQueryStringOnPost() throws Exception { MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(this.context) .apply(documentationConfiguration(this.restDocumentation)).build(); - mockMvc.perform(post("/?foo=bar").param("foo", "bar").param("a", "alpha") - .accept(MediaType.APPLICATION_JSON)).andExpect(status().isOk()) - .andDo(document("httpie-snippet-with-query-string")); - assertThat(new File( - "build/generated-snippets/httpie-snippet-with-query-string/httpie-request.adoc")) - .has(content(codeBlock(TemplateFormats.asciidoctor(), "bash") - .withContent(String.format("$ http " - + "--form POST 'http://localhost:8080/?foo=bar' \\%n" - + " 'Accept:application/json' \\%n 'a=alpha'")))); + mockMvc.perform(post("/?foo=bar").param("foo", "bar").param("a", "alpha").accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()).andDo(document("httpie-snippet-with-query-string")); + assertThat(new File("build/generated-snippets/httpie-snippet-with-query-string/httpie-request.adoc")) + .has(content(codeBlock(TemplateFormats.asciidoctor(), "bash") + .withContent(String.format("$ http " + "--form POST 'http://localhost:8080/?foo=bar' \\%n" + + " 'Accept:application/json' \\%n 'a=alpha'")))); } @Test public void httpieSnippetWithContentAndParametersOnPost() throws Exception { MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(this.context) .apply(documentationConfiguration(this.restDocumentation)).build(); - mockMvc.perform(post("/").param("a", "alpha").content("some content") - .accept(MediaType.APPLICATION_JSON)).andExpect(status().isOk()) - .andDo(document("httpie-snippet-post-with-content-and-parameters")); + mockMvc.perform(post("/").param("a", "alpha").content("some content").accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()).andDo(document("httpie-snippet-post-with-content-and-parameters")); assertThat(new File( "build/generated-snippets/httpie-snippet-post-with-content-and-parameters/httpie-request.adoc")) .has(content(codeBlock(TemplateFormats.asciidoctor(), "bash") - .withContent(String - .format("$ echo " + "'some content' | http POST " - + "'http://localhost:8080/?a=alpha' \\%n" - + " 'Accept:application/json'")))); + .withContent(String.format("$ echo " + "'some content' | http POST " + + "'http://localhost:8080/?a=alpha' \\%n" + " 'Accept:application/json'")))); } @Test public void linksSnippet() throws Exception { MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(this.context) .apply(documentationConfiguration(this.restDocumentation)).build(); - mockMvc.perform(get("/").accept(MediaType.APPLICATION_JSON)) - .andExpect(status().isOk()).andDo(document("links", - links(linkWithRel("rel").description("The description")))); + mockMvc.perform(get("/").accept(MediaType.APPLICATION_JSON)).andExpect(status().isOk()) + .andDo(document("links", links(linkWithRel("rel").description("The description")))); - assertExpectedSnippetFilesExist(new File("build/generated-snippets/links"), - "http-request.adoc", "http-response.adoc", "curl-request.adoc", - "links.adoc"); + assertExpectedSnippetFilesExist(new File("build/generated-snippets/links"), "http-request.adoc", + "http-response.adoc", "curl-request.adoc", "links.adoc"); } @Test public void pathParametersSnippet() throws Exception { MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(this.context) .apply(documentationConfiguration(this.restDocumentation)).build(); - mockMvc.perform(get("{foo}", "/").accept(MediaType.APPLICATION_JSON)) - .andExpect(status().isOk()).andDo(document("links", pathParameters( - parameterWithName("foo").description("The description")))); - assertExpectedSnippetFilesExist(new File("build/generated-snippets/links"), - "http-request.adoc", "http-response.adoc", "curl-request.adoc", - "path-parameters.adoc"); + mockMvc.perform(get("{foo}", "/").accept(MediaType.APPLICATION_JSON)).andExpect(status().isOk()) + .andDo(document("links", pathParameters(parameterWithName("foo").description("The description")))); + assertExpectedSnippetFilesExist(new File("build/generated-snippets/links"), "http-request.adoc", + "http-response.adoc", "curl-request.adoc", "path-parameters.adoc"); } @Test public void requestParametersSnippet() throws Exception { MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(this.context) .apply(documentationConfiguration(this.restDocumentation)).build(); - mockMvc.perform(get("/").param("foo", "bar").accept(MediaType.APPLICATION_JSON)) - .andExpect(status().isOk()).andDo(document("links", requestParameters( - parameterWithName("foo").description("The description")))); - assertExpectedSnippetFilesExist(new File("build/generated-snippets/links"), - "http-request.adoc", "http-response.adoc", "curl-request.adoc", - "request-parameters.adoc"); + mockMvc.perform(get("/").param("foo", "bar").accept(MediaType.APPLICATION_JSON)).andExpect(status().isOk()) + .andDo(document("links", requestParameters(parameterWithName("foo").description("The description")))); + assertExpectedSnippetFilesExist(new File("build/generated-snippets/links"), "http-request.adoc", + "http-response.adoc", "curl-request.adoc", "request-parameters.adoc"); } @Test public void requestFieldsSnippet() throws Exception { MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(this.context) .apply(documentationConfiguration(this.restDocumentation)).build(); - mockMvc.perform(get("/").param("foo", "bar").content("{\"a\":\"alpha\"}") - .accept(MediaType.APPLICATION_JSON)).andExpect(status().isOk()) - .andDo(document("links", requestFields( - fieldWithPath("a").description("The description")))); - assertExpectedSnippetFilesExist(new File("build/generated-snippets/links"), - "http-request.adoc", "http-response.adoc", "curl-request.adoc", - "request-fields.adoc"); + mockMvc.perform(get("/").param("foo", "bar").content("{\"a\":\"alpha\"}").accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andDo(document("links", requestFields(fieldWithPath("a").description("The description")))); + assertExpectedSnippetFilesExist(new File("build/generated-snippets/links"), "http-request.adoc", + "http-response.adoc", "curl-request.adoc", "request-fields.adoc"); } @Test public void requestPartsSnippet() throws Exception { MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(this.context) .apply(documentationConfiguration(this.restDocumentation)).build(); - mockMvc.perform(fileUpload("/upload").file("foo", "bar".getBytes())) - .andExpect(status().isOk()).andDo(document("request-parts", requestParts( - partWithName("foo").description("The description")))); - assertExpectedSnippetFilesExist( - new File("build/generated-snippets/request-parts"), "http-request.adoc", + mockMvc.perform(fileUpload("/upload").file("foo", "bar".getBytes())).andExpect(status().isOk()) + .andDo(document("request-parts", requestParts(partWithName("foo").description("The description")))); + assertExpectedSnippetFilesExist(new File("build/generated-snippets/request-parts"), "http-request.adoc", "http-response.adoc", "curl-request.adoc", "request-parts.adoc"); } @@ -341,62 +299,48 @@ public void requestPartsSnippet() throws Exception { public void responseFieldsSnippet() throws Exception { MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(this.context) .apply(documentationConfiguration(this.restDocumentation)).build(); - mockMvc.perform(get("/").param("foo", "bar").accept(MediaType.APPLICATION_JSON)) - .andExpect(status().isOk()) - .andDo(document("links", - responseFields(fieldWithPath("a").description("The description"), - subsectionWithPath("links") - .description("Links to other resources")))); - assertExpectedSnippetFilesExist(new File("build/generated-snippets/links"), - "http-request.adoc", "http-response.adoc", "curl-request.adoc", - "response-fields.adoc"); + mockMvc.perform(get("/").param("foo", "bar").accept(MediaType.APPLICATION_JSON)).andExpect(status().isOk()) + .andDo(document("links", responseFields(fieldWithPath("a").description("The description"), + subsectionWithPath("links").description("Links to other resources")))); + assertExpectedSnippetFilesExist(new File("build/generated-snippets/links"), "http-request.adoc", + "http-response.adoc", "curl-request.adoc", "response-fields.adoc"); } @Test public void responseWithSetCookie() throws Exception { MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(this.context) .apply(documentationConfiguration(this.restDocumentation)).build(); - mockMvc.perform(get("/set-cookie")).andExpect(status().isOk()) - .andDo(document("set-cookie", - responseHeaders(headerWithName(HttpHeaders.SET_COOKIE) - .description("set-cookie")))); + mockMvc.perform(get("/set-cookie")).andExpect(status().isOk()).andDo(document("set-cookie", + responseHeaders(headerWithName(HttpHeaders.SET_COOKIE).description("set-cookie")))); assertThat(new File("build/generated-snippets/set-cookie/http-response.adoc")) - .has(content(httpResponse(TemplateFormats.asciidoctor(), HttpStatus.OK) - .header(HttpHeaders.SET_COOKIE, - "name=value; Domain=localhost; HttpOnly"))); + .has(content(httpResponse(TemplateFormats.asciidoctor(), HttpStatus.OK).header(HttpHeaders.SET_COOKIE, + "name=value; Domain=localhost; HttpOnly"))); } @Test public void parameterizedOutputDirectory() throws Exception { MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(this.context) .apply(documentationConfiguration(this.restDocumentation)).build(); - mockMvc.perform(get("/").accept(MediaType.APPLICATION_JSON)) - .andExpect(status().isOk()).andDo(document("{method-name}")); - assertExpectedSnippetFilesExist( - new File("build/generated-snippets/parameterized-output-directory"), + mockMvc.perform(get("/").accept(MediaType.APPLICATION_JSON)).andExpect(status().isOk()) + .andDo(document("{method-name}")); + assertExpectedSnippetFilesExist(new File("build/generated-snippets/parameterized-output-directory"), "http-request.adoc", "http-response.adoc", "curl-request.adoc"); } @Test public void multiStep() throws Exception { MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(this.context) - .apply(documentationConfiguration(this.restDocumentation)) - .alwaysDo(document("{method-name}-{step}")).build(); - mockMvc.perform(get("/").accept(MediaType.APPLICATION_JSON)) - .andExpect(status().isOk()); - assertExpectedSnippetFilesExist( - new File("build/generated-snippets/multi-step-1/"), "http-request.adoc", + .apply(documentationConfiguration(this.restDocumentation)).alwaysDo(document("{method-name}-{step}")) + .build(); + mockMvc.perform(get("/").accept(MediaType.APPLICATION_JSON)).andExpect(status().isOk()); + assertExpectedSnippetFilesExist(new File("build/generated-snippets/multi-step-1/"), "http-request.adoc", "http-response.adoc", "curl-request.adoc"); - mockMvc.perform(get("/").accept(MediaType.APPLICATION_JSON)) - .andExpect(status().isOk()); - assertExpectedSnippetFilesExist( - new File("build/generated-snippets/multi-step-2/"), "http-request.adoc", + mockMvc.perform(get("/").accept(MediaType.APPLICATION_JSON)).andExpect(status().isOk()); + assertExpectedSnippetFilesExist(new File("build/generated-snippets/multi-step-2/"), "http-request.adoc", "http-response.adoc", "curl-request.adoc"); - mockMvc.perform(get("/").accept(MediaType.APPLICATION_JSON)) - .andExpect(status().isOk()); - assertExpectedSnippetFilesExist( - new File("build/generated-snippets/multi-step-3/"), "http-request.adoc", + mockMvc.perform(get("/").accept(MediaType.APPLICATION_JSON)).andExpect(status().isOk()); + assertExpectedSnippetFilesExist(new File("build/generated-snippets/multi-step-3/"), "http-request.adoc", "http-response.adoc", "curl-request.adoc"); } @@ -404,16 +348,11 @@ public void multiStep() throws Exception { public void alwaysDoWithAdditionalSnippets() throws Exception { RestDocumentationResultHandler documentation = document("{method-name}-{step}"); MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(this.context) - .apply(documentationConfiguration(this.restDocumentation)) - .alwaysDo(documentation).build(); - mockMvc.perform(get("/").accept(MediaType.APPLICATION_JSON)) - .andExpect(status().isOk()).andDo(documentation.document( - responseHeaders(headerWithName("a").description("one")))); - assertExpectedSnippetFilesExist( - new File( - "build/generated-snippets/always-do-with-additional-snippets-1/"), - "http-request.adoc", "http-response.adoc", "curl-request.adoc", - "response-headers.adoc"); + .apply(documentationConfiguration(this.restDocumentation)).alwaysDo(documentation).build(); + mockMvc.perform(get("/").accept(MediaType.APPLICATION_JSON)).andExpect(status().isOk()) + .andDo(documentation.document(responseHeaders(headerWithName("a").description("one")))); + assertExpectedSnippetFilesExist(new File("build/generated-snippets/always-do-with-additional-snippets-1/"), + "http-request.adoc", "http-response.adoc", "curl-request.adoc", "response-headers.adoc"); } @Test @@ -422,42 +361,30 @@ public void preprocessedRequest() throws Exception { .apply(documentationConfiguration(this.restDocumentation)).build(); Pattern pattern = Pattern.compile("(\"alpha\")"); MvcResult result = mockMvc - .perform(get("/").header("a", "alpha").header("b", "bravo") - .contentType(MediaType.APPLICATION_JSON) + .perform(get("/").header("a", "alpha").header("b", "bravo").contentType(MediaType.APPLICATION_JSON) .accept(MediaType.APPLICATION_JSON).content("{\"a\":\"alpha\"}")) .andExpect(status().isOk()).andDo(document("original-request")) .andDo(document("preprocessed-request", preprocessRequest(prettyPrint(), - removeHeaders("a", HttpHeaders.HOST, - HttpHeaders.CONTENT_LENGTH), + removeHeaders("a", HttpHeaders.HOST, HttpHeaders.CONTENT_LENGTH), replacePattern(pattern, "\"<>\"")))) .andReturn(); - HttpRequestCondition originalRequest = httpRequest(TemplateFormats.asciidoctor(), - RequestMethod.GET, "/"); - for (String headerName : IterableEnumeration - .of(result.getRequest().getHeaderNames())) { + HttpRequestCondition originalRequest = httpRequest(TemplateFormats.asciidoctor(), RequestMethod.GET, "/"); + for (String headerName : IterableEnumeration.of(result.getRequest().getHeaderNames())) { originalRequest.header(headerName, result.getRequest().getHeader(headerName)); } - assertThat( - new File("build/generated-snippets/original-request/http-request.adoc")) - .has(content(originalRequest.header("Host", "localhost:8080") - .header("Content-Length", "13") - .content("{\"a\":\"alpha\"}"))); - HttpRequestCondition preprocessedRequest = httpRequest( - TemplateFormats.asciidoctor(), RequestMethod.GET, "/"); - List removedHeaders = Arrays.asList("a", HttpHeaders.HOST, - HttpHeaders.CONTENT_LENGTH); - for (String headerName : IterableEnumeration - .of(result.getRequest().getHeaderNames())) { + assertThat(new File("build/generated-snippets/original-request/http-request.adoc")).has(content(originalRequest + .header("Host", "localhost:8080").header("Content-Length", "13").content("{\"a\":\"alpha\"}"))); + HttpRequestCondition preprocessedRequest = httpRequest(TemplateFormats.asciidoctor(), RequestMethod.GET, "/"); + List removedHeaders = Arrays.asList("a", HttpHeaders.HOST, HttpHeaders.CONTENT_LENGTH); + for (String headerName : IterableEnumeration.of(result.getRequest().getHeaderNames())) { if (!removedHeaders.contains(headerName)) { - preprocessedRequest.header(headerName, - result.getRequest().getHeader(headerName)); + preprocessedRequest.header(headerName, result.getRequest().getHeader(headerName)); } } String prettyPrinted = String.format("{%n \"a\" : \"<>\"%n}"); - assertThat(new File( - "build/generated-snippets/preprocessed-request/http-request.adoc")) - .has(content(preprocessedRequest.content(prettyPrinted))); + assertThat(new File("build/generated-snippets/preprocessed-request/http-request.adoc")) + .has(content(preprocessedRequest.content(prettyPrinted))); } @Test @@ -467,53 +394,42 @@ public void preprocessedResponse() throws Exception { Pattern pattern = Pattern.compile("(\"alpha\")"); - mockMvc.perform(get("/").accept(MediaType.APPLICATION_JSON)) - .andExpect(status().isOk()).andDo(document("original-response")) - .andDo(document("preprocessed-response", - preprocessResponse(prettyPrint(), maskLinks(), removeHeaders("a"), - replacePattern(pattern, "\"<>\"")))); + mockMvc.perform(get("/").accept(MediaType.APPLICATION_JSON)).andExpect(status().isOk()) + .andDo(document("original-response")) + .andDo(document("preprocessed-response", preprocessResponse(prettyPrint(), maskLinks(), + removeHeaders("a"), replacePattern(pattern, "\"<>\"")))); - String original = "{\"a\":\"alpha\",\"links\":[{\"rel\":\"rel\"," - + "\"href\":\"href\"}]}"; - assertThat(new File( - "build/generated-snippets/original-response/http-response.adoc")).has( - content(httpResponse(TemplateFormats.asciidoctor(), HttpStatus.OK) - .header("a", "alpha") - .header("Content-Type", "application/json;charset=UTF-8") - .header(HttpHeaders.CONTENT_LENGTH, - original.getBytes().length) - .content(original))); + String original = "{\"a\":\"alpha\",\"links\":[{\"rel\":\"rel\"," + "\"href\":\"href\"}]}"; + assertThat(new File("build/generated-snippets/original-response/http-response.adoc")) + .has(content(httpResponse(TemplateFormats.asciidoctor(), HttpStatus.OK).header("a", "alpha") + .header("Content-Type", "application/json;charset=UTF-8") + .header(HttpHeaders.CONTENT_LENGTH, original.getBytes().length).content(original))); String prettyPrinted = String.format("{%n \"a\" : \"<>\",%n \"links\" : " + "[ {%n \"rel\" : \"rel\",%n \"href\" : \"...\"%n } ]%n}"); - assertThat(new File( - "build/generated-snippets/preprocessed-response/http-response.adoc")).has( - content(httpResponse(TemplateFormats.asciidoctor(), HttpStatus.OK) - .header("Content-Type", "application/json;charset=UTF-8") - .header(HttpHeaders.CONTENT_LENGTH, - prettyPrinted.getBytes().length) - .content(prettyPrinted))); + assertThat(new File("build/generated-snippets/preprocessed-response/http-response.adoc")) + .has(content(httpResponse(TemplateFormats.asciidoctor(), HttpStatus.OK) + .header("Content-Type", "application/json;charset=UTF-8") + .header(HttpHeaders.CONTENT_LENGTH, prettyPrinted.getBytes().length).content(prettyPrinted))); } @Test public void customSnippetTemplate() throws Exception { MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(this.context) .apply(documentationConfiguration(this.restDocumentation)).build(); - ClassLoader classLoader = new URLClassLoader(new URL[] { - new File("src/test/resources/custom-snippet-templates").toURI().toURL() }, + ClassLoader classLoader = new URLClassLoader( + new URL[] { new File("src/test/resources/custom-snippet-templates").toURI().toURL() }, getClass().getClassLoader()); ClassLoader previous = Thread.currentThread().getContextClassLoader(); Thread.currentThread().setContextClassLoader(classLoader); try { - mockMvc.perform(get("/").accept(MediaType.APPLICATION_JSON)) - .andExpect(status().isOk()) + mockMvc.perform(get("/").accept(MediaType.APPLICATION_JSON)).andExpect(status().isOk()) .andDo(document("custom-snippet-template")); } finally { Thread.currentThread().setContextClassLoader(previous); } - assertThat(new File( - "build/generated-snippets/custom-snippet-template/curl-request.adoc")) - .hasContent("Custom curl request"); + assertThat(new File("build/generated-snippets/custom-snippet-template/curl-request.adoc")) + .hasContent("Custom curl request"); } @Test @@ -521,24 +437,20 @@ public void customContextPath() throws Exception { MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(this.context) .apply(documentationConfiguration(this.restDocumentation)).build(); - mockMvc.perform( - get("/custom/").contextPath("/custom").accept(MediaType.APPLICATION_JSON)) + mockMvc.perform(get("/custom/").contextPath("/custom").accept(MediaType.APPLICATION_JSON)) .andExpect(status().isOk()).andDo(document("custom-context-path")); - assertThat(new File( - "build/generated-snippets/custom-context-path/curl-request.adoc")) - .has(content(codeBlock(TemplateFormats.asciidoctor(), "bash") - .withContent(String.format( - "$ curl 'http://localhost:8080/custom/' -i -X GET \\%n" - + " -H 'Accept: application/json'")))); + assertThat(new File("build/generated-snippets/custom-context-path/curl-request.adoc")) + .has(content(codeBlock(TemplateFormats.asciidoctor(), "bash") + .withContent(String.format("$ curl 'http://localhost:8080/custom/' -i -X GET \\%n" + + " -H 'Accept: application/json'")))); } @Test public void multiPart() throws Exception { MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(this.context) .apply(documentationConfiguration(this.restDocumentation)).build(); - mockMvc.perform(fileUpload("/upload").file("test", "content".getBytes())) - .andExpect(status().isOk()).andDo(document("upload", - requestParts(partWithName("test").description("Foo")))); + mockMvc.perform(fileUpload("/upload").file("test", "content".getBytes())).andExpect(status().isOk()) + .andDo(document("upload", requestParts(partWithName("test").description("Foo")))); } private void assertExpectedSnippetFilesExist(File directory, String... snippets) { @@ -553,9 +465,8 @@ private Condition content(final Condition delegate) { @Override public boolean matches(File value) { try { - return delegate - .matches(FileCopyUtils.copyToString(new InputStreamReader( - new FileInputStream(value), StandardCharsets.UTF_8))); + return delegate.matches(FileCopyUtils + .copyToString(new InputStreamReader(new FileInputStream(value), StandardCharsets.UTF_8))); } catch (IOException ex) { fail("Failed to read '" + value + "'", ex); @@ -570,8 +481,7 @@ private CodeBlockCondition codeBlock(TemplateFormat format, String language) return SnippetConditions.codeBlock(format, language); } - private HttpRequestCondition httpRequest(TemplateFormat format, - RequestMethod requestMethod, String uri) { + private HttpRequestCondition httpRequest(TemplateFormat format, RequestMethod requestMethod, String uri) { return SnippetConditions.httpRequest(format, requestMethod, uri); } @@ -587,7 +497,7 @@ private HttpResponseCondition httpResponse(TemplateFormat format, HttpStatus sta static class TestConfiguration { @Bean - public TestController testController() { + TestController testController() { return new TestController(); } @@ -597,7 +507,7 @@ public TestController testController() { private static class TestController { @RequestMapping(value = "/", produces = "application/json;charset=UTF-8") - public ResponseEntity> foo() { + ResponseEntity> foo() { Map response = new HashMap<>(); response.put("a", "alpha"); Map link = new HashMap<>(); @@ -610,17 +520,17 @@ public ResponseEntity> foo() { } @RequestMapping(value = "/company/5", produces = MediaType.APPLICATION_JSON_VALUE) - public String bar() { + String bar() { return "{\"companyName\": \"FooBar\",\"employee\": [{\"name\": \"Lorem\",\"age\": \"42\"},{\"name\": \"Ipsum\",\"age\": \"24\"}]}"; } @RequestMapping(value = "/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) - public void upload() { + void upload() { } @RequestMapping("/set-cookie") - public void setCookie(HttpServletResponse response) { + void setCookie(HttpServletResponse response) { Cookie cookie = new Cookie("name", "value"); cookie.setDomain("localhost"); cookie.setHttpOnly(true); diff --git a/spring-restdocs-mockmvc/src/test/java/org/springframework/restdocs/mockmvc/RestDocumentationRequestBuildersTests.java b/spring-restdocs-mockmvc/src/test/java/org/springframework/restdocs/mockmvc/RestDocumentationRequestBuildersTests.java index 6529b9fbd..66ee51463 100644 --- a/spring-restdocs-mockmvc/src/test/java/org/springframework/restdocs/mockmvc/RestDocumentationRequestBuildersTests.java +++ b/spring-restdocs-mockmvc/src/test/java/org/springframework/restdocs/mockmvc/RestDocumentationRequestBuildersTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-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. @@ -139,12 +139,10 @@ public void fileUploadUri() { assertUri(fileUpload(URI.create("/uri")), HttpMethod.POST); } - private void assertTemplate(MockHttpServletRequestBuilder builder, - HttpMethod httpMethod) { + private void assertTemplate(MockHttpServletRequestBuilder builder, HttpMethod httpMethod) { MockHttpServletRequest request = builder.buildRequest(this.servletContext); - assertThat((String) request - .getAttribute(RestDocumentationGenerator.ATTRIBUTE_NAME_URL_TEMPLATE)) - .isEqualTo("{template}"); + assertThat((String) request.getAttribute(RestDocumentationGenerator.ATTRIBUTE_NAME_URL_TEMPLATE)) + .isEqualTo("{template}"); assertThat(request.getRequestURI()).isEqualTo("t"); assertThat(request.getMethod()).isEqualTo(httpMethod.name()); } diff --git a/spring-restdocs-restassured/src/main/java/org/springframework/restdocs/restassured/RestAssuredRequestConverter.java b/spring-restdocs-restassured/src/main/java/org/springframework/restdocs/restassured/RestAssuredRequestConverter.java index d1ff8771c..acc20da5d 100644 --- a/spring-restdocs-restassured/src/main/java/org/springframework/restdocs/restassured/RestAssuredRequestConverter.java +++ b/spring-restdocs-restassured/src/main/java/org/springframework/restdocs/restassured/RestAssuredRequestConverter.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-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. @@ -49,20 +49,17 @@ * * @author Andy Wilkinson */ -class RestAssuredRequestConverter - implements RequestConverter { +class RestAssuredRequestConverter implements RequestConverter { @Override public OperationRequest convert(FilterableRequestSpecification requestSpec) { return new OperationRequestFactory().create(URI.create(requestSpec.getURI()), - HttpMethod.valueOf(requestSpec.getMethod().name()), - extractContent(requestSpec), extractHeaders(requestSpec), - extractParameters(requestSpec), extractParts(requestSpec), + HttpMethod.valueOf(requestSpec.getMethod().name()), extractContent(requestSpec), + extractHeaders(requestSpec), extractParameters(requestSpec), extractParts(requestSpec), extractCookies(requestSpec)); } - private Collection extractCookies( - FilterableRequestSpecification requestSpec) { + private Collection extractCookies(FilterableRequestSpecification requestSpec) { Collection cookies = new ArrayList<>(); for (Cookie cookie : requestSpec.getCookies()) { cookies.add(new RequestCookie(cookie.getName(), cookie.getValue())); @@ -91,8 +88,7 @@ else if (content == null) { return new byte[0]; } else { - throw new IllegalStateException( - "Unsupported request content: " + content.getClass().getName()); + throw new IllegalStateException("Unsupported request content: " + content.getClass().getName()); } } @@ -101,8 +97,7 @@ private byte[] copyToByteArray(File file) { return FileCopyUtils.copyToByteArray(file); } catch (IOException ex) { - throw new IllegalStateException("Failed to read content from file " + file, - ex); + throw new IllegalStateException("Failed to read content from file " + file, ex); } } @@ -111,15 +106,14 @@ private byte[] copyToByteArray(InputStream inputStream) { inputStream.reset(); } catch (IOException ex) { - throw new IllegalStateException("Cannot read content from input stream " - + inputStream + " due to reset() failure"); + throw new IllegalStateException( + "Cannot read content from input stream " + inputStream + " due to reset() failure"); } try { return StreamUtils.copyToByteArray(inputStream); } catch (IOException ex) { - throw new IllegalStateException( - "Failed to read content from input stream " + inputStream, ex); + throw new IllegalStateException("Failed to read content from input stream " + inputStream, ex); } } @@ -134,8 +128,7 @@ private HttpHeaders extractHeaders(FilterableRequestSpecification requestSpec) { } private boolean isAllMediaTypesAcceptHeader(Header header) { - return HttpHeaders.ACCEPT.equals(header.getName()) - && "*/*".equals(header.getValue()); + return HttpHeaders.ACCEPT.equals(header.getName()) && "*/*".equals(header.getValue()); } private Parameters extractParameters(FilterableRequestSpecification requestSpec) { @@ -160,17 +153,14 @@ private Parameters extractParameters(FilterableRequestSpecification requestSpec) return parameters; } - private Collection extractParts( - FilterableRequestSpecification requestSpec) { + private Collection extractParts(FilterableRequestSpecification requestSpec) { List parts = new ArrayList<>(); for (MultiPartSpecification multiPartSpec : requestSpec.getMultiPartParams()) { HttpHeaders headers = new HttpHeaders(); headers.setContentType((multiPartSpec.getMimeType() != null) - ? MediaType.parseMediaType(multiPartSpec.getMimeType()) - : MediaType.TEXT_PLAIN); - parts.add(new OperationRequestPartFactory().create( - multiPartSpec.getControlName(), multiPartSpec.getFileName(), - convertContent(multiPartSpec.getContent()), headers)); + ? MediaType.parseMediaType(multiPartSpec.getMimeType()) : MediaType.TEXT_PLAIN); + parts.add(new OperationRequestPartFactory().create(multiPartSpec.getControlName(), + multiPartSpec.getFileName(), convertContent(multiPartSpec.getContent()), headers)); } return parts; } diff --git a/spring-restdocs-restassured/src/main/java/org/springframework/restdocs/restassured/RestAssuredResponseConverter.java b/spring-restdocs-restassured/src/main/java/org/springframework/restdocs/restassured/RestAssuredResponseConverter.java index 06e170992..1867e5032 100644 --- a/spring-restdocs-restassured/src/main/java/org/springframework/restdocs/restassured/RestAssuredResponseConverter.java +++ b/spring-restdocs-restassured/src/main/java/org/springframework/restdocs/restassured/RestAssuredResponseConverter.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2016 the original author or authors. + * Copyright 2014-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. @@ -35,9 +35,8 @@ class RestAssuredResponseConverter implements ResponseConverter { @Override public OperationResponse convert(Response response) { - return new OperationResponseFactory().create( - HttpStatus.valueOf(response.getStatusCode()), extractHeaders(response), - extractContent(response)); + return new OperationResponseFactory().create(HttpStatus.valueOf(response.getStatusCode()), + extractHeaders(response), extractContent(response)); } private HttpHeaders extractHeaders(Response response) { diff --git a/spring-restdocs-restassured/src/main/java/org/springframework/restdocs/restassured/RestAssuredRestDocumentation.java b/spring-restdocs-restassured/src/main/java/org/springframework/restdocs/restassured/RestAssuredRestDocumentation.java index d130d17a1..0a78879a3 100644 --- a/spring-restdocs-restassured/src/main/java/org/springframework/restdocs/restassured/RestAssuredRestDocumentation.java +++ b/spring-restdocs-restassured/src/main/java/org/springframework/restdocs/restassured/RestAssuredRestDocumentation.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-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. @@ -48,10 +48,9 @@ private RestAssuredRestDocumentation() { * @param snippets the snippets that will document the API call * @return a {@link RestDocumentationFilter} that will produce the documentation */ - public static RestDocumentationFilter document(String identifier, - Snippet... snippets) { - return new RestDocumentationFilter(new RestDocumentationGenerator<>(identifier, - REQUEST_CONVERTER, RESPONSE_CONVERTER, snippets)); + public static RestDocumentationFilter document(String identifier, Snippet... snippets) { + return new RestDocumentationFilter( + new RestDocumentationGenerator<>(identifier, REQUEST_CONVERTER, RESPONSE_CONVERTER, snippets)); } /** @@ -63,10 +62,10 @@ public static RestDocumentationFilter document(String identifier, * @param snippets the snippets * @return a {@link RestDocumentationFilter} that will produce the documentation */ - public static RestDocumentationFilter document(String identifier, - OperationRequestPreprocessor requestPreprocessor, Snippet... snippets) { - return new RestDocumentationFilter(new RestDocumentationGenerator<>(identifier, - REQUEST_CONVERTER, RESPONSE_CONVERTER, requestPreprocessor, snippets)); + public static RestDocumentationFilter document(String identifier, OperationRequestPreprocessor requestPreprocessor, + Snippet... snippets) { + return new RestDocumentationFilter(new RestDocumentationGenerator<>(identifier, REQUEST_CONVERTER, + RESPONSE_CONVERTER, requestPreprocessor, snippets)); } /** @@ -80,8 +79,8 @@ public static RestDocumentationFilter document(String identifier, */ public static RestDocumentationFilter document(String identifier, OperationResponsePreprocessor responsePreprocessor, Snippet... snippets) { - return new RestDocumentationFilter(new RestDocumentationGenerator<>(identifier, - REQUEST_CONVERTER, RESPONSE_CONVERTER, responsePreprocessor, snippets)); + return new RestDocumentationFilter(new RestDocumentationGenerator<>(identifier, REQUEST_CONVERTER, + RESPONSE_CONVERTER, responsePreprocessor, snippets)); } /** @@ -95,12 +94,10 @@ public static RestDocumentationFilter document(String identifier, * @param snippets the snippets * @return a {@link RestDocumentationFilter} that will produce the documentation */ - public static RestDocumentationFilter document(String identifier, - OperationRequestPreprocessor requestPreprocessor, + public static RestDocumentationFilter document(String identifier, OperationRequestPreprocessor requestPreprocessor, OperationResponsePreprocessor responsePreprocessor, Snippet... snippets) { - return new RestDocumentationFilter(new RestDocumentationGenerator<>(identifier, - REQUEST_CONVERTER, RESPONSE_CONVERTER, requestPreprocessor, - responsePreprocessor, snippets)); + return new RestDocumentationFilter(new RestDocumentationGenerator<>(identifier, REQUEST_CONVERTER, + RESPONSE_CONVERTER, requestPreprocessor, responsePreprocessor, snippets)); } /** diff --git a/spring-restdocs-restassured/src/main/java/org/springframework/restdocs/restassured/RestAssuredRestDocumentationConfigurer.java b/spring-restdocs-restassured/src/main/java/org/springframework/restdocs/restassured/RestAssuredRestDocumentationConfigurer.java index 7e0220e54..930f9d56e 100644 --- a/spring-restdocs-restassured/src/main/java/org/springframework/restdocs/restassured/RestAssuredRestDocumentationConfigurer.java +++ b/spring-restdocs-restassured/src/main/java/org/springframework/restdocs/restassured/RestAssuredRestDocumentationConfigurer.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2017 the original author or authors. + * Copyright 2014-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. @@ -38,17 +38,15 @@ * {@link org.springframework.restdocs.restassured3.RestAssuredRestDocumentationConfigurer} */ @Deprecated -public final class RestAssuredRestDocumentationConfigurer extends - RestDocumentationConfigurer +public final class RestAssuredRestDocumentationConfigurer + extends RestDocumentationConfigurer implements Filter { - private final RestAssuredSnippetConfigurer snippetConfigurer = new RestAssuredSnippetConfigurer( - this); + private final RestAssuredSnippetConfigurer snippetConfigurer = new RestAssuredSnippetConfigurer(this); private final RestDocumentationContextProvider contextProvider; - RestAssuredRestDocumentationConfigurer( - RestDocumentationContextProvider contextProvider) { + RestAssuredRestDocumentationConfigurer(RestDocumentationContextProvider contextProvider) { this.contextProvider = contextProvider; } @@ -58,13 +56,12 @@ public RestAssuredSnippetConfigurer snippets() { } @Override - public Response filter(FilterableRequestSpecification requestSpec, - FilterableResponseSpecification responseSpec, FilterContext filterContext) { + public Response filter(FilterableRequestSpecification requestSpec, FilterableResponseSpecification responseSpec, + FilterContext filterContext) { RestDocumentationContext context = this.contextProvider.beforeOperation(); filterContext.setValue(RestDocumentationContext.class.getName(), context); Map configuration = new HashMap<>(); - filterContext.setValue(RestDocumentationFilter.CONTEXT_KEY_CONFIGURATION, - configuration); + filterContext.setValue(RestDocumentationFilter.CONTEXT_KEY_CONFIGURATION, configuration); apply(configuration, context); return filterContext.next(requestSpec, responseSpec); } diff --git a/spring-restdocs-restassured/src/main/java/org/springframework/restdocs/restassured/RestAssuredSnippetConfigurer.java b/spring-restdocs-restassured/src/main/java/org/springframework/restdocs/restassured/RestAssuredSnippetConfigurer.java index 359c5d628..c93802efa 100644 --- a/spring-restdocs-restassured/src/main/java/org/springframework/restdocs/restassured/RestAssuredSnippetConfigurer.java +++ b/spring-restdocs-restassured/src/main/java/org/springframework/restdocs/restassured/RestAssuredSnippetConfigurer.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2017 the original author or authors. + * Copyright 2014-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. @@ -35,16 +35,15 @@ */ @Deprecated public final class RestAssuredSnippetConfigurer extends - SnippetConfigurer - implements Filter { + SnippetConfigurer implements Filter { RestAssuredSnippetConfigurer(RestAssuredRestDocumentationConfigurer parent) { super(parent); } @Override - public Response filter(FilterableRequestSpecification requestSpec, - FilterableResponseSpecification responseSpec, FilterContext context) { + public Response filter(FilterableRequestSpecification requestSpec, FilterableResponseSpecification responseSpec, + FilterContext context) { return and().filter(requestSpec, responseSpec, context); } diff --git a/spring-restdocs-restassured/src/main/java/org/springframework/restdocs/restassured/RestDocumentationFilter.java b/spring-restdocs-restassured/src/main/java/org/springframework/restdocs/restassured/RestDocumentationFilter.java index 742b30753..13dd953cd 100644 --- a/spring-restdocs-restassured/src/main/java/org/springframework/restdocs/restassured/RestDocumentationFilter.java +++ b/spring-restdocs-restassured/src/main/java/org/springframework/restdocs/restassured/RestDocumentationFilter.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-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. @@ -45,8 +45,7 @@ public class RestDocumentationFilter implements Filter { private final RestDocumentationGenerator delegate; - RestDocumentationFilter( - RestDocumentationGenerator delegate) { + RestDocumentationFilter(RestDocumentationGenerator delegate) { Assert.notNull(delegate, "delegate must be non-null"); this.delegate = delegate; } @@ -70,15 +69,12 @@ public final Response filter(FilterableRequestSpecification requestSpec, * @param context the filter context * @return the configuration */ - protected Map getConfiguration( - FilterableRequestSpecification requestSpec, FilterContext context) { + protected Map getConfiguration(FilterableRequestSpecification requestSpec, FilterContext context) { Map configuration = new HashMap<>( context.>getValue(CONTEXT_KEY_CONFIGURATION)); configuration.put(RestDocumentationContext.class.getName(), - context.getValue( - RestDocumentationContext.class.getName())); - configuration.put(RestDocumentationGenerator.ATTRIBUTE_NAME_URL_TEMPLATE, - requestSpec.getUserDefinedPath()); + context.getValue(RestDocumentationContext.class.getName())); + configuration.put(RestDocumentationGenerator.ATTRIBUTE_NAME_URL_TEMPLATE, requestSpec.getUserDefinedPath()); return configuration; } @@ -105,12 +101,10 @@ public final RestDocumentationFilter document(Snippet... snippets) { return new RestDocumentationFilter(this.delegate.withSnippets(snippets)) { @Override - protected Map getConfiguration( - FilterableRequestSpecification requestSpec, FilterContext context) { - Map configuration = super.getConfiguration(requestSpec, - context); - configuration.remove( - RestDocumentationGenerator.ATTRIBUTE_NAME_DEFAULT_SNIPPETS); + protected Map getConfiguration(FilterableRequestSpecification requestSpec, + FilterContext context) { + Map configuration = super.getConfiguration(requestSpec, context); + configuration.remove(RestDocumentationGenerator.ATTRIBUTE_NAME_DEFAULT_SNIPPETS); return configuration; } diff --git a/spring-restdocs-restassured/src/main/java/org/springframework/restdocs/restassured/operation/preprocess/UriModifyingOperationPreprocessor.java b/spring-restdocs-restassured/src/main/java/org/springframework/restdocs/restassured/operation/preprocess/UriModifyingOperationPreprocessor.java index 628c0fdcf..b6c5edf9f 100644 --- a/spring-restdocs-restassured/src/main/java/org/springframework/restdocs/restassured/operation/preprocess/UriModifyingOperationPreprocessor.java +++ b/spring-restdocs-restassured/src/main/java/org/springframework/restdocs/restassured/operation/preprocess/UriModifyingOperationPreprocessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-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. @@ -138,19 +138,17 @@ public OperationRequest preprocess(OperationRequest request) { } URI modifiedUri = uriBuilder.build(true).toUri(); HttpHeaders modifiedHeaders = modify(request.getHeaders()); - modifiedHeaders.set(HttpHeaders.HOST, modifiedUri.getHost() - + ((modifiedUri.getPort() != -1) ? ":" + modifiedUri.getPort() : "")); - return this.contentModifyingDelegate.preprocess(new OperationRequestFactory() - .create(uriBuilder.build(true).toUri(), request.getMethod(), - request.getContent(), modifiedHeaders, request.getParameters(), - modify(request.getParts()), request.getCookies())); + modifiedHeaders.set(HttpHeaders.HOST, + modifiedUri.getHost() + ((modifiedUri.getPort() != -1) ? ":" + modifiedUri.getPort() : "")); + return this.contentModifyingDelegate.preprocess(new OperationRequestFactory().create( + uriBuilder.build(true).toUri(), request.getMethod(), request.getContent(), modifiedHeaders, + request.getParameters(), modify(request.getParts()), request.getCookies())); } @Override public OperationResponse preprocess(OperationResponse response) { - return this.contentModifyingDelegate - .preprocess(new OperationResponseFactory().create(response.getStatus(), - modify(response.getHeaders()), response.getContent())); + return this.contentModifyingDelegate.preprocess(new OperationResponseFactory().create(response.getStatus(), + modify(response.getHeaders()), response.getContent())); } private HttpHeaders modify(HttpHeaders headers) { @@ -163,14 +161,12 @@ private HttpHeaders modify(HttpHeaders headers) { return modified; } - private Collection modify( - Collection parts) { + private Collection modify(Collection parts) { List modifiedParts = new ArrayList<>(); OperationRequestPartFactory factory = new OperationRequestPartFactory(); for (OperationRequestPart part : parts) { modifiedParts.add(factory.create(part.getName(), part.getSubmittedFileName(), - this.contentModifier.modifyContent(part.getContent(), - part.getHeaders().getContentType()), + this.contentModifier.modifyContent(part.getContent(), part.getHeaders().getContentType()), modify(part.getHeaders()))); } return modifiedParts; @@ -178,8 +174,7 @@ private Collection modify( private static final class UriModifyingContentModifier implements ContentModifier { - private static final Pattern SCHEME_HOST_PORT_PATTERN = Pattern - .compile("(http[s]?)://([^/:#?]+)(:[0-9]+)?"); + private static final Pattern SCHEME_HOST_PORT_PATTERN = Pattern.compile("(http[s]?)://([^/:#?]+)(:[0-9]+)?"); private String scheme; @@ -228,8 +223,7 @@ private String modify(String input) { if (matcher.start(i) >= 0) { previous = matcher.end(i); } - builder.append( - getReplacement(matcher.group(i), replacements.get(i - 1))); + builder.append(getReplacement(matcher.group(i), replacements.get(i - 1))); } } diff --git a/spring-restdocs-restassured/src/main/java/org/springframework/restdocs/restassured3/RestAssuredRequestConverter.java b/spring-restdocs-restassured/src/main/java/org/springframework/restdocs/restassured3/RestAssuredRequestConverter.java index 917a934b0..6356e437e 100644 --- a/spring-restdocs-restassured/src/main/java/org/springframework/restdocs/restassured3/RestAssuredRequestConverter.java +++ b/spring-restdocs-restassured/src/main/java/org/springframework/restdocs/restassured3/RestAssuredRequestConverter.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-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. @@ -49,19 +49,16 @@ * * @author Andy Wilkinson */ -class RestAssuredRequestConverter - implements RequestConverter { +class RestAssuredRequestConverter implements RequestConverter { @Override public OperationRequest convert(FilterableRequestSpecification requestSpec) { return new OperationRequestFactory().create(URI.create(requestSpec.getURI()), - HttpMethod.valueOf(requestSpec.getMethod()), extractContent(requestSpec), - extractHeaders(requestSpec), extractParameters(requestSpec), - extractParts(requestSpec), extractCookies(requestSpec)); + HttpMethod.valueOf(requestSpec.getMethod()), extractContent(requestSpec), extractHeaders(requestSpec), + extractParameters(requestSpec), extractParts(requestSpec), extractCookies(requestSpec)); } - private Collection extractCookies( - FilterableRequestSpecification requestSpec) { + private Collection extractCookies(FilterableRequestSpecification requestSpec) { Collection cookies = new ArrayList<>(); for (Cookie cookie : requestSpec.getCookies()) { cookies.add(new RequestCookie(cookie.getName(), cookie.getValue())); @@ -90,8 +87,7 @@ else if (content == null) { return new byte[0]; } else { - throw new IllegalStateException( - "Unsupported request content: " + content.getClass().getName()); + throw new IllegalStateException("Unsupported request content: " + content.getClass().getName()); } } @@ -100,8 +96,7 @@ private byte[] copyToByteArray(File file) { return FileCopyUtils.copyToByteArray(file); } catch (IOException ex) { - throw new IllegalStateException("Failed to read content from file " + file, - ex); + throw new IllegalStateException("Failed to read content from file " + file, ex); } } @@ -110,15 +105,14 @@ private byte[] copyToByteArray(InputStream inputStream) { inputStream.reset(); } catch (IOException ex) { - throw new IllegalStateException("Cannot read content from input stream " - + inputStream + " due to reset() failure"); + throw new IllegalStateException( + "Cannot read content from input stream " + inputStream + " due to reset() failure"); } try { return StreamUtils.copyToByteArray(inputStream); } catch (IOException ex) { - throw new IllegalStateException( - "Failed to read content from input stream " + inputStream, ex); + throw new IllegalStateException("Failed to read content from input stream " + inputStream, ex); } } @@ -133,8 +127,7 @@ private HttpHeaders extractHeaders(FilterableRequestSpecification requestSpec) { } private boolean isAllMediaTypesAcceptHeader(Header header) { - return HttpHeaders.ACCEPT.equals(header.getName()) - && "*/*".equals(header.getValue()); + return HttpHeaders.ACCEPT.equals(header.getName()) && "*/*".equals(header.getValue()); } private Parameters extractParameters(FilterableRequestSpecification requestSpec) { @@ -159,17 +152,14 @@ private Parameters extractParameters(FilterableRequestSpecification requestSpec) return parameters; } - private Collection extractParts( - FilterableRequestSpecification requestSpec) { + private Collection extractParts(FilterableRequestSpecification requestSpec) { List parts = new ArrayList<>(); for (MultiPartSpecification multiPartSpec : requestSpec.getMultiPartParams()) { HttpHeaders headers = new HttpHeaders(); headers.setContentType((multiPartSpec.getMimeType() != null) - ? MediaType.parseMediaType(multiPartSpec.getMimeType()) - : MediaType.TEXT_PLAIN); - parts.add(new OperationRequestPartFactory().create( - multiPartSpec.getControlName(), multiPartSpec.getFileName(), - convertContent(multiPartSpec.getContent()), headers)); + ? MediaType.parseMediaType(multiPartSpec.getMimeType()) : MediaType.TEXT_PLAIN); + parts.add(new OperationRequestPartFactory().create(multiPartSpec.getControlName(), + multiPartSpec.getFileName(), convertContent(multiPartSpec.getContent()), headers)); } return parts; } diff --git a/spring-restdocs-restassured/src/main/java/org/springframework/restdocs/restassured3/RestAssuredResponseConverter.java b/spring-restdocs-restassured/src/main/java/org/springframework/restdocs/restassured3/RestAssuredResponseConverter.java index 8308ba907..3835fe888 100644 --- a/spring-restdocs-restassured/src/main/java/org/springframework/restdocs/restassured3/RestAssuredResponseConverter.java +++ b/spring-restdocs-restassured/src/main/java/org/springframework/restdocs/restassured3/RestAssuredResponseConverter.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2017 the original author or authors. + * Copyright 2014-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. @@ -35,9 +35,8 @@ class RestAssuredResponseConverter implements ResponseConverter { @Override public OperationResponse convert(Response response) { - return new OperationResponseFactory().create( - HttpStatus.valueOf(response.getStatusCode()), extractHeaders(response), - extractContent(response)); + return new OperationResponseFactory().create(HttpStatus.valueOf(response.getStatusCode()), + extractHeaders(response), extractContent(response)); } private HttpHeaders extractHeaders(Response response) { diff --git a/spring-restdocs-restassured/src/main/java/org/springframework/restdocs/restassured3/RestAssuredRestDocumentation.java b/spring-restdocs-restassured/src/main/java/org/springframework/restdocs/restassured3/RestAssuredRestDocumentation.java index 6b739e97c..b2e899b46 100644 --- a/spring-restdocs-restassured/src/main/java/org/springframework/restdocs/restassured3/RestAssuredRestDocumentation.java +++ b/spring-restdocs-restassured/src/main/java/org/springframework/restdocs/restassured3/RestAssuredRestDocumentation.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-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. @@ -45,10 +45,9 @@ private RestAssuredRestDocumentation() { * @param snippets the snippets that will document the API call * @return a {@link RestDocumentationFilter} that will produce the documentation */ - public static RestDocumentationFilter document(String identifier, - Snippet... snippets) { - return new RestDocumentationFilter(new RestDocumentationGenerator<>(identifier, - REQUEST_CONVERTER, RESPONSE_CONVERTER, snippets)); + public static RestDocumentationFilter document(String identifier, Snippet... snippets) { + return new RestDocumentationFilter( + new RestDocumentationGenerator<>(identifier, REQUEST_CONVERTER, RESPONSE_CONVERTER, snippets)); } /** @@ -60,10 +59,10 @@ public static RestDocumentationFilter document(String identifier, * @param snippets the snippets * @return a {@link RestDocumentationFilter} that will produce the documentation */ - public static RestDocumentationFilter document(String identifier, - OperationRequestPreprocessor requestPreprocessor, Snippet... snippets) { - return new RestDocumentationFilter(new RestDocumentationGenerator<>(identifier, - REQUEST_CONVERTER, RESPONSE_CONVERTER, requestPreprocessor, snippets)); + public static RestDocumentationFilter document(String identifier, OperationRequestPreprocessor requestPreprocessor, + Snippet... snippets) { + return new RestDocumentationFilter(new RestDocumentationGenerator<>(identifier, REQUEST_CONVERTER, + RESPONSE_CONVERTER, requestPreprocessor, snippets)); } /** @@ -77,8 +76,8 @@ public static RestDocumentationFilter document(String identifier, */ public static RestDocumentationFilter document(String identifier, OperationResponsePreprocessor responsePreprocessor, Snippet... snippets) { - return new RestDocumentationFilter(new RestDocumentationGenerator<>(identifier, - REQUEST_CONVERTER, RESPONSE_CONVERTER, responsePreprocessor, snippets)); + return new RestDocumentationFilter(new RestDocumentationGenerator<>(identifier, REQUEST_CONVERTER, + RESPONSE_CONVERTER, responsePreprocessor, snippets)); } /** @@ -92,12 +91,10 @@ public static RestDocumentationFilter document(String identifier, * @param snippets the snippets * @return a {@link RestDocumentationFilter} that will produce the documentation */ - public static RestDocumentationFilter document(String identifier, - OperationRequestPreprocessor requestPreprocessor, + public static RestDocumentationFilter document(String identifier, OperationRequestPreprocessor requestPreprocessor, OperationResponsePreprocessor responsePreprocessor, Snippet... snippets) { - return new RestDocumentationFilter(new RestDocumentationGenerator<>(identifier, - REQUEST_CONVERTER, RESPONSE_CONVERTER, requestPreprocessor, - responsePreprocessor, snippets)); + return new RestDocumentationFilter(new RestDocumentationGenerator<>(identifier, REQUEST_CONVERTER, + RESPONSE_CONVERTER, requestPreprocessor, responsePreprocessor, snippets)); } /** diff --git a/spring-restdocs-restassured/src/main/java/org/springframework/restdocs/restassured3/RestAssuredRestDocumentationConfigurer.java b/spring-restdocs-restassured/src/main/java/org/springframework/restdocs/restassured3/RestAssuredRestDocumentationConfigurer.java index cb7b76f8c..2ccdbfb24 100644 --- a/spring-restdocs-restassured/src/main/java/org/springframework/restdocs/restassured3/RestAssuredRestDocumentationConfigurer.java +++ b/spring-restdocs-restassured/src/main/java/org/springframework/restdocs/restassured3/RestAssuredRestDocumentationConfigurer.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2017 the original author or authors. + * Copyright 2014-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. @@ -35,17 +35,15 @@ * @author Andy Wilkinson * @since 1.2.0 */ -public final class RestAssuredRestDocumentationConfigurer extends - RestDocumentationConfigurer +public final class RestAssuredRestDocumentationConfigurer + extends RestDocumentationConfigurer implements Filter { - private final RestAssuredSnippetConfigurer snippetConfigurer = new RestAssuredSnippetConfigurer( - this); + private final RestAssuredSnippetConfigurer snippetConfigurer = new RestAssuredSnippetConfigurer(this); private final RestDocumentationContextProvider contextProvider; - RestAssuredRestDocumentationConfigurer( - RestDocumentationContextProvider contextProvider) { + RestAssuredRestDocumentationConfigurer(RestDocumentationContextProvider contextProvider) { this.contextProvider = contextProvider; } @@ -55,13 +53,12 @@ public RestAssuredSnippetConfigurer snippets() { } @Override - public Response filter(FilterableRequestSpecification requestSpec, - FilterableResponseSpecification responseSpec, FilterContext filterContext) { + public Response filter(FilterableRequestSpecification requestSpec, FilterableResponseSpecification responseSpec, + FilterContext filterContext) { RestDocumentationContext context = this.contextProvider.beforeOperation(); filterContext.setValue(RestDocumentationContext.class.getName(), context); Map configuration = new HashMap<>(); - filterContext.setValue(RestDocumentationFilter.CONTEXT_KEY_CONFIGURATION, - configuration); + filterContext.setValue(RestDocumentationFilter.CONTEXT_KEY_CONFIGURATION, configuration); apply(configuration, context); return filterContext.next(requestSpec, responseSpec); } diff --git a/spring-restdocs-restassured/src/main/java/org/springframework/restdocs/restassured3/RestAssuredSnippetConfigurer.java b/spring-restdocs-restassured/src/main/java/org/springframework/restdocs/restassured3/RestAssuredSnippetConfigurer.java index 756d53fe4..0dbebbdb5 100644 --- a/spring-restdocs-restassured/src/main/java/org/springframework/restdocs/restassured3/RestAssuredSnippetConfigurer.java +++ b/spring-restdocs-restassured/src/main/java/org/springframework/restdocs/restassured3/RestAssuredSnippetConfigurer.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2017 the original author or authors. + * Copyright 2014-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. @@ -32,16 +32,15 @@ * @since 1.2.0 */ public final class RestAssuredSnippetConfigurer extends - SnippetConfigurer - implements Filter { + SnippetConfigurer implements Filter { RestAssuredSnippetConfigurer(RestAssuredRestDocumentationConfigurer parent) { super(parent); } @Override - public Response filter(FilterableRequestSpecification requestSpec, - FilterableResponseSpecification responseSpec, FilterContext context) { + public Response filter(FilterableRequestSpecification requestSpec, FilterableResponseSpecification responseSpec, + FilterContext context) { return and().filter(requestSpec, responseSpec, context); } diff --git a/spring-restdocs-restassured/src/main/java/org/springframework/restdocs/restassured3/RestDocumentationFilter.java b/spring-restdocs-restassured/src/main/java/org/springframework/restdocs/restassured3/RestDocumentationFilter.java index ae10fc988..5e964d76f 100644 --- a/spring-restdocs-restassured/src/main/java/org/springframework/restdocs/restassured3/RestDocumentationFilter.java +++ b/spring-restdocs-restassured/src/main/java/org/springframework/restdocs/restassured3/RestDocumentationFilter.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-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. @@ -42,8 +42,7 @@ public class RestDocumentationFilter implements Filter { private final RestDocumentationGenerator delegate; - RestDocumentationFilter( - RestDocumentationGenerator delegate) { + RestDocumentationFilter(RestDocumentationGenerator delegate) { Assert.notNull(delegate, "delegate must be non-null"); this.delegate = delegate; } @@ -67,15 +66,12 @@ public final Response filter(FilterableRequestSpecification requestSpec, * @param context the filter context * @return the configuration */ - protected Map getConfiguration( - FilterableRequestSpecification requestSpec, FilterContext context) { + protected Map getConfiguration(FilterableRequestSpecification requestSpec, FilterContext context) { Map configuration = new HashMap<>( context.>getValue(CONTEXT_KEY_CONFIGURATION)); configuration.put(RestDocumentationContext.class.getName(), - context.getValue( - RestDocumentationContext.class.getName())); - configuration.put(RestDocumentationGenerator.ATTRIBUTE_NAME_URL_TEMPLATE, - requestSpec.getUserDefinedPath()); + context.getValue(RestDocumentationContext.class.getName())); + configuration.put(RestDocumentationGenerator.ATTRIBUTE_NAME_URL_TEMPLATE, requestSpec.getUserDefinedPath()); return configuration; } @@ -102,12 +98,10 @@ public final RestDocumentationFilter document(Snippet... snippets) { return new RestDocumentationFilter(this.delegate.withSnippets(snippets)) { @Override - protected Map getConfiguration( - FilterableRequestSpecification requestSpec, FilterContext context) { - Map configuration = super.getConfiguration(requestSpec, - context); - configuration.remove( - RestDocumentationGenerator.ATTRIBUTE_NAME_DEFAULT_SNIPPETS); + protected Map getConfiguration(FilterableRequestSpecification requestSpec, + FilterContext context) { + Map configuration = super.getConfiguration(requestSpec, context); + configuration.remove(RestDocumentationGenerator.ATTRIBUTE_NAME_DEFAULT_SNIPPETS); return configuration; } diff --git a/spring-restdocs-restassured/src/main/java/org/springframework/restdocs/restassured3/operation/preprocess/UriModifyingOperationPreprocessor.java b/spring-restdocs-restassured/src/main/java/org/springframework/restdocs/restassured3/operation/preprocess/UriModifyingOperationPreprocessor.java index 82366a4da..bd6238dbe 100644 --- a/spring-restdocs-restassured/src/main/java/org/springframework/restdocs/restassured3/operation/preprocess/UriModifyingOperationPreprocessor.java +++ b/spring-restdocs-restassured/src/main/java/org/springframework/restdocs/restassured3/operation/preprocess/UriModifyingOperationPreprocessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-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. @@ -135,19 +135,17 @@ public OperationRequest preprocess(OperationRequest request) { } URI modifiedUri = uriBuilder.build(true).toUri(); HttpHeaders modifiedHeaders = modify(request.getHeaders()); - modifiedHeaders.set(HttpHeaders.HOST, modifiedUri.getHost() - + ((modifiedUri.getPort() != -1) ? ":" + modifiedUri.getPort() : "")); - return this.contentModifyingDelegate.preprocess(new OperationRequestFactory() - .create(uriBuilder.build(true).toUri(), request.getMethod(), - request.getContent(), modifiedHeaders, request.getParameters(), - modify(request.getParts()), request.getCookies())); + modifiedHeaders.set(HttpHeaders.HOST, + modifiedUri.getHost() + ((modifiedUri.getPort() != -1) ? ":" + modifiedUri.getPort() : "")); + return this.contentModifyingDelegate.preprocess(new OperationRequestFactory().create( + uriBuilder.build(true).toUri(), request.getMethod(), request.getContent(), modifiedHeaders, + request.getParameters(), modify(request.getParts()), request.getCookies())); } @Override public OperationResponse preprocess(OperationResponse response) { - return this.contentModifyingDelegate - .preprocess(new OperationResponseFactory().create(response.getStatus(), - modify(response.getHeaders()), response.getContent())); + return this.contentModifyingDelegate.preprocess(new OperationResponseFactory().create(response.getStatus(), + modify(response.getHeaders()), response.getContent())); } private HttpHeaders modify(HttpHeaders headers) { @@ -160,14 +158,12 @@ private HttpHeaders modify(HttpHeaders headers) { return modified; } - private Collection modify( - Collection parts) { + private Collection modify(Collection parts) { List modifiedParts = new ArrayList<>(); OperationRequestPartFactory factory = new OperationRequestPartFactory(); for (OperationRequestPart part : parts) { modifiedParts.add(factory.create(part.getName(), part.getSubmittedFileName(), - this.contentModifier.modifyContent(part.getContent(), - part.getHeaders().getContentType()), + this.contentModifier.modifyContent(part.getContent(), part.getHeaders().getContentType()), modify(part.getHeaders()))); } return modifiedParts; @@ -175,8 +171,7 @@ private Collection modify( private static final class UriModifyingContentModifier implements ContentModifier { - private static final Pattern SCHEME_HOST_PORT_PATTERN = Pattern - .compile("(http[s]?)://([^/:#?]+)(:[0-9]+)?"); + private static final Pattern SCHEME_HOST_PORT_PATTERN = Pattern.compile("(http[s]?)://([^/:#?]+)(:[0-9]+)?"); private String scheme; @@ -225,8 +220,7 @@ private String modify(String input) { if (matcher.start(i) >= 0) { previous = matcher.end(i); } - builder.append( - getReplacement(matcher.group(i), replacements.get(i - 1))); + builder.append(getReplacement(matcher.group(i), replacements.get(i - 1))); } } diff --git a/spring-restdocs-restassured/src/test/java/org/springframework/restdocs/restassured/RestAssuredRequestConverterTests.java b/spring-restdocs-restassured/src/test/java/org/springframework/restdocs/restassured/RestAssuredRequestConverterTests.java index d667ded11..41581b51c 100644 --- a/spring-restdocs-restassured/src/test/java/org/springframework/restdocs/restassured/RestAssuredRequestConverterTests.java +++ b/spring-restdocs-restassured/src/test/java/org/springframework/restdocs/restassured/RestAssuredRequestConverterTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-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. @@ -62,105 +62,84 @@ public class RestAssuredRequestConverterTests { public void requestUri() { RequestSpecification requestSpec = RestAssured.given().port(tomcat.getPort()); requestSpec.get("/foo/bar"); - OperationRequest request = this.factory - .convert((FilterableRequestSpecification) requestSpec); - assertThat(request.getUri()).isEqualTo( - URI.create("http://localhost:" + tomcat.getPort() + "/foo/bar")); + OperationRequest request = this.factory.convert((FilterableRequestSpecification) requestSpec); + assertThat(request.getUri()).isEqualTo(URI.create("http://localhost:" + tomcat.getPort() + "/foo/bar")); } @Test public void requestMethod() { RequestSpecification requestSpec = RestAssured.given().port(tomcat.getPort()); requestSpec.head("/foo/bar"); - OperationRequest request = this.factory - .convert((FilterableRequestSpecification) requestSpec); + OperationRequest request = this.factory.convert((FilterableRequestSpecification) requestSpec); assertThat(request.getMethod()).isEqualTo(HttpMethod.HEAD); } @Test public void queryStringParameters() { - RequestSpecification requestSpec = RestAssured.given().port(tomcat.getPort()) - .queryParam("foo", "bar"); + RequestSpecification requestSpec = RestAssured.given().port(tomcat.getPort()).queryParam("foo", "bar"); requestSpec.get("/"); - OperationRequest request = this.factory - .convert((FilterableRequestSpecification) requestSpec); + OperationRequest request = this.factory.convert((FilterableRequestSpecification) requestSpec); assertThat(request.getParameters()).hasSize(1); - assertThat(request.getParameters()).containsEntry("foo", - Collections.singletonList("bar")); + assertThat(request.getParameters()).containsEntry("foo", Collections.singletonList("bar")); } @Test public void queryStringFromUrlParameters() { RequestSpecification requestSpec = RestAssured.given().port(tomcat.getPort()); requestSpec.get("/?foo=bar&foo=qix"); - OperationRequest request = this.factory - .convert((FilterableRequestSpecification) requestSpec); + OperationRequest request = this.factory.convert((FilterableRequestSpecification) requestSpec); assertThat(request.getParameters()).hasSize(1); - assertThat(request.getParameters()).containsEntry("foo", - Arrays.asList("bar", "qix")); + assertThat(request.getParameters()).containsEntry("foo", Arrays.asList("bar", "qix")); } @Test public void formParameters() { - RequestSpecification requestSpec = RestAssured.given().port(tomcat.getPort()) - .formParameter("foo", "bar"); + RequestSpecification requestSpec = RestAssured.given().port(tomcat.getPort()).formParameter("foo", "bar"); requestSpec.get("/"); - OperationRequest request = this.factory - .convert((FilterableRequestSpecification) requestSpec); + OperationRequest request = this.factory.convert((FilterableRequestSpecification) requestSpec); assertThat(request.getParameters()).hasSize(1); - assertThat(request.getParameters()).containsEntry("foo", - Collections.singletonList("bar")); + assertThat(request.getParameters()).containsEntry("foo", Collections.singletonList("bar")); } @Test public void requestParameters() { - RequestSpecification requestSpec = RestAssured.given().port(tomcat.getPort()) - .parameter("foo", "bar"); + RequestSpecification requestSpec = RestAssured.given().port(tomcat.getPort()).parameter("foo", "bar"); requestSpec.get("/"); - OperationRequest request = this.factory - .convert((FilterableRequestSpecification) requestSpec); + OperationRequest request = this.factory.convert((FilterableRequestSpecification) requestSpec); assertThat(request.getParameters()).hasSize(1); - assertThat(request.getParameters()).containsEntry("foo", - Collections.singletonList("bar")); + assertThat(request.getParameters()).containsEntry("foo", Collections.singletonList("bar")); } @Test public void headers() { - RequestSpecification requestSpec = RestAssured.given().port(tomcat.getPort()) - .header("Foo", "bar"); + RequestSpecification requestSpec = RestAssured.given().port(tomcat.getPort()).header("Foo", "bar"); requestSpec.get("/"); - OperationRequest request = this.factory - .convert((FilterableRequestSpecification) requestSpec); + OperationRequest request = this.factory.convert((FilterableRequestSpecification) requestSpec); assertThat(request.getHeaders()).hasSize(2); - assertThat(request.getHeaders()).containsEntry("Foo", - Collections.singletonList("bar")); + assertThat(request.getHeaders()).containsEntry("Foo", Collections.singletonList("bar")); assertThat(request.getHeaders()).containsEntry("Host", Collections.singletonList("localhost:" + tomcat.getPort())); } @Test public void headersWithCustomAccept() { - RequestSpecification requestSpec = RestAssured.given().port(tomcat.getPort()) - .header("Foo", "bar").accept("application/json"); + RequestSpecification requestSpec = RestAssured.given().port(tomcat.getPort()).header("Foo", "bar") + .accept("application/json"); requestSpec.get("/"); - OperationRequest request = this.factory - .convert((FilterableRequestSpecification) requestSpec); + OperationRequest request = this.factory.convert((FilterableRequestSpecification) requestSpec); assertThat(request.getHeaders()).hasSize(3); - assertThat(request.getHeaders()).containsEntry("Foo", - Collections.singletonList("bar")); - assertThat(request.getHeaders()).containsEntry("Accept", - Collections.singletonList("application/json")); + assertThat(request.getHeaders()).containsEntry("Foo", Collections.singletonList("bar")); + assertThat(request.getHeaders()).containsEntry("Accept", Collections.singletonList("application/json")); assertThat(request.getHeaders()).containsEntry("Host", Collections.singletonList("localhost:" + tomcat.getPort())); } @Test public void cookies() { - RequestSpecification requestSpec = RestAssured.given().port(tomcat.getPort()) - .cookie("cookie1", "cookieVal1").cookie("cookie2", "cookieVal2"); + RequestSpecification requestSpec = RestAssured.given().port(tomcat.getPort()).cookie("cookie1", "cookieVal1") + .cookie("cookie2", "cookieVal2"); requestSpec.get("/"); - OperationRequest request = this.factory - .convert((FilterableRequestSpecification) requestSpec); + OperationRequest request = this.factory.convert((FilterableRequestSpecification) requestSpec); assertThat(request.getCookies().size()).isEqualTo(2); Iterator cookieIterator = request.getCookies().iterator(); @@ -177,115 +156,94 @@ public void cookies() { @Test public void multipart() { RequestSpecification requestSpec = RestAssured.given().port(tomcat.getPort()) - .multiPart("a", "a.txt", "alpha", null) - .multiPart("b", new ObjectBody("bar"), "application/json"); + .multiPart("a", "a.txt", "alpha", null).multiPart("b", new ObjectBody("bar"), "application/json"); requestSpec.post(); - OperationRequest request = this.factory - .convert((FilterableRequestSpecification) requestSpec); + OperationRequest request = this.factory.convert((FilterableRequestSpecification) requestSpec); Collection parts = request.getParts(); assertThat(parts).hasSize(2); assertThat(parts).extracting("name").containsExactly("a", "b"); - assertThat(parts).extracting("submittedFileName").containsExactly("a.txt", - "file"); - assertThat(parts).extracting("contentAsString").containsExactly("alpha", - "{\"foo\":\"bar\"}"); - assertThat(parts).extracting("headers").extracting(HttpHeaders.CONTENT_TYPE) - .containsExactly(Collections.singletonList(MediaType.TEXT_PLAIN_VALUE), - Collections.singletonList(MediaType.APPLICATION_JSON_VALUE)); + assertThat(parts).extracting("submittedFileName").containsExactly("a.txt", "file"); + assertThat(parts).extracting("contentAsString").containsExactly("alpha", "{\"foo\":\"bar\"}"); + assertThat(parts).extracting("headers").extracting(HttpHeaders.CONTENT_TYPE).containsExactly( + Collections.singletonList(MediaType.TEXT_PLAIN_VALUE), + Collections.singletonList(MediaType.APPLICATION_JSON_VALUE)); } @Test public void byteArrayBody() { - RequestSpecification requestSpec = RestAssured.given().body("body".getBytes()) - .port(tomcat.getPort()); + RequestSpecification requestSpec = RestAssured.given().body("body".getBytes()).port(tomcat.getPort()); requestSpec.post(); this.factory.convert((FilterableRequestSpecification) requestSpec); } @Test public void stringBody() { - RequestSpecification requestSpec = RestAssured.given().body("body") - .port(tomcat.getPort()); + RequestSpecification requestSpec = RestAssured.given().body("body").port(tomcat.getPort()); requestSpec.post(); - OperationRequest request = this.factory - .convert((FilterableRequestSpecification) requestSpec); + OperationRequest request = this.factory.convert((FilterableRequestSpecification) requestSpec); assertThat(request.getContentAsString()).isEqualTo("body"); } @Test public void objectBody() { - RequestSpecification requestSpec = RestAssured.given().body(new ObjectBody("bar")) - .port(tomcat.getPort()); + RequestSpecification requestSpec = RestAssured.given().body(new ObjectBody("bar")).port(tomcat.getPort()); requestSpec.post(); - OperationRequest request = this.factory - .convert((FilterableRequestSpecification) requestSpec); + OperationRequest request = this.factory.convert((FilterableRequestSpecification) requestSpec); assertThat(request.getContentAsString()).isEqualTo("{\"foo\":\"bar\"}"); } @Test public void byteArrayInputStreamBody() { - RequestSpecification requestSpec = RestAssured.given() - .body(new ByteArrayInputStream(new byte[] { 1, 2, 3, 4 })) + RequestSpecification requestSpec = RestAssured.given().body(new ByteArrayInputStream(new byte[] { 1, 2, 3, 4 })) .port(tomcat.getPort()); requestSpec.post(); - OperationRequest request = this.factory - .convert((FilterableRequestSpecification) requestSpec); + OperationRequest request = this.factory.convert((FilterableRequestSpecification) requestSpec); assertThat(request.getContent()).isEqualTo(new byte[] { 1, 2, 3, 4 }); } @Test public void fileBody() { - RequestSpecification requestSpec = RestAssured.given() - .body(new File("src/test/resources/body.txt")).port(tomcat.getPort()); + RequestSpecification requestSpec = RestAssured.given().body(new File("src/test/resources/body.txt")) + .port(tomcat.getPort()); requestSpec.post(); - OperationRequest request = this.factory - .convert((FilterableRequestSpecification) requestSpec); + OperationRequest request = this.factory.convert((FilterableRequestSpecification) requestSpec); assertThat(request.getContentAsString()).isEqualTo("file"); } @Test public void fileInputStreamBody() throws FileNotFoundException { FileInputStream inputStream = new FileInputStream("src/test/resources/body.txt"); - RequestSpecification requestSpec = RestAssured.given().body(inputStream) - .port(tomcat.getPort()); + RequestSpecification requestSpec = RestAssured.given().body(inputStream).port(tomcat.getPort()); requestSpec.post(); this.thrown.expect(IllegalStateException.class); - this.thrown.expectMessage("Cannot read content from input stream " + inputStream - + " due to reset() failure"); + this.thrown.expectMessage("Cannot read content from input stream " + inputStream + " due to reset() failure"); this.factory.convert((FilterableRequestSpecification) requestSpec); } @Test public void multipartWithByteArrayInputStreamBody() { - RequestSpecification requestSpec = RestAssured.given().port(tomcat.getPort()) - .multiPart("foo", "foo.txt", new ByteArrayInputStream("foo".getBytes())); + RequestSpecification requestSpec = RestAssured.given().port(tomcat.getPort()).multiPart("foo", "foo.txt", + new ByteArrayInputStream("foo".getBytes())); requestSpec.post(); - OperationRequest request = this.factory - .convert((FilterableRequestSpecification) requestSpec); - assertThat(request.getParts().iterator().next().getContentAsString()) - .isEqualTo("foo"); + OperationRequest request = this.factory.convert((FilterableRequestSpecification) requestSpec); + assertThat(request.getParts().iterator().next().getContentAsString()).isEqualTo("foo"); } @Test public void multipartWithStringBody() { - RequestSpecification requestSpec = RestAssured.given().port(tomcat.getPort()) - .multiPart("control", "foo"); + RequestSpecification requestSpec = RestAssured.given().port(tomcat.getPort()).multiPart("control", "foo"); requestSpec.post(); - OperationRequest request = this.factory - .convert((FilterableRequestSpecification) requestSpec); - assertThat(request.getParts().iterator().next().getContentAsString()) - .isEqualTo("foo"); + OperationRequest request = this.factory.convert((FilterableRequestSpecification) requestSpec); + assertThat(request.getParts().iterator().next().getContentAsString()).isEqualTo("foo"); } @Test public void multipartWithByteArrayBody() { - RequestSpecification requestSpec = RestAssured.given().port(tomcat.getPort()) - .multiPart("control", "file", "foo".getBytes()); + RequestSpecification requestSpec = RestAssured.given().port(tomcat.getPort()).multiPart("control", "file", + "foo".getBytes()); requestSpec.post(); - OperationRequest request = this.factory - .convert((FilterableRequestSpecification) requestSpec); - assertThat(request.getParts().iterator().next().getContentAsString()) - .isEqualTo("foo"); + OperationRequest request = this.factory.convert((FilterableRequestSpecification) requestSpec); + assertThat(request.getParts().iterator().next().getContentAsString()).isEqualTo("foo"); } @Test @@ -293,39 +251,34 @@ public void multipartWithFileBody() { RequestSpecification requestSpec = RestAssured.given().port(tomcat.getPort()) .multiPart(new File("src/test/resources/body.txt")); requestSpec.post(); - OperationRequest request = this.factory - .convert((FilterableRequestSpecification) requestSpec); - assertThat(request.getParts().iterator().next().getContentAsString()) - .isEqualTo("file"); + OperationRequest request = this.factory.convert((FilterableRequestSpecification) requestSpec); + assertThat(request.getParts().iterator().next().getContentAsString()).isEqualTo("file"); } @Test public void multipartWithFileInputStreamBody() throws FileNotFoundException { FileInputStream inputStream = new FileInputStream("src/test/resources/body.txt"); - RequestSpecification requestSpec = RestAssured.given().port(tomcat.getPort()) - .multiPart("foo", "foo.txt", inputStream); + RequestSpecification requestSpec = RestAssured.given().port(tomcat.getPort()).multiPart("foo", "foo.txt", + inputStream); requestSpec.post(); this.thrown.expect(IllegalStateException.class); - this.thrown.expectMessage("Cannot read content from input stream " + inputStream - + " due to reset() failure"); + this.thrown.expectMessage("Cannot read content from input stream " + inputStream + " due to reset() failure"); this.factory.convert((FilterableRequestSpecification) requestSpec); } @Test public void multipartWithObjectBody() { - RequestSpecification requestSpec = RestAssured.given().port(tomcat.getPort()) - .multiPart("control", new ObjectBody("bar")); + RequestSpecification requestSpec = RestAssured.given().port(tomcat.getPort()).multiPart("control", + new ObjectBody("bar")); requestSpec.post(); - OperationRequest request = this.factory - .convert((FilterableRequestSpecification) requestSpec); - assertThat(request.getParts().iterator().next().getContentAsString()) - .isEqualTo("{\"foo\":\"bar\"}"); + OperationRequest request = this.factory.convert((FilterableRequestSpecification) requestSpec); + assertThat(request.getParts().iterator().next().getContentAsString()).isEqualTo("{\"foo\":\"bar\"}"); } /** * Sample object body to verify JSON serialization. */ - static class ObjectBody { + public static class ObjectBody { private final String foo; diff --git a/spring-restdocs-restassured/src/test/java/org/springframework/restdocs/restassured/RestAssuredRestDocumentationConfigurerTests.java b/spring-restdocs-restassured/src/test/java/org/springframework/restdocs/restassured/RestAssuredRestDocumentationConfigurerTests.java index 560db54dd..0152cdcb9 100644 --- a/spring-restdocs-restassured/src/test/java/org/springframework/restdocs/restassured/RestAssuredRestDocumentationConfigurerTests.java +++ b/spring-restdocs-restassured/src/test/java/org/springframework/restdocs/restassured/RestAssuredRestDocumentationConfigurerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-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. @@ -47,11 +47,9 @@ public class RestAssuredRestDocumentationConfigurerTests { @Rule public final JUnitRestDocumentation restDocumentation = new JUnitRestDocumentation(); - private final FilterableRequestSpecification requestSpec = mock( - FilterableRequestSpecification.class); + private final FilterableRequestSpecification requestSpec = mock(FilterableRequestSpecification.class); - private final FilterableResponseSpecification responseSpec = mock( - FilterableResponseSpecification.class); + private final FilterableResponseSpecification responseSpec = mock(FilterableResponseSpecification.class); private final FilterContext filterContext = mock(FilterContext.class); @@ -69,18 +67,14 @@ public void configurationIsAddedToTheContext() { this.configurer.filter(this.requestSpec, this.responseSpec, this.filterContext); @SuppressWarnings("rawtypes") ArgumentCaptor configurationCaptor = ArgumentCaptor.forClass(Map.class); - verify(this.filterContext).setValue( - eq(RestDocumentationFilter.CONTEXT_KEY_CONFIGURATION), + verify(this.filterContext).setValue(eq(RestDocumentationFilter.CONTEXT_KEY_CONFIGURATION), configurationCaptor.capture()); @SuppressWarnings("unchecked") Map configuration = configurationCaptor.getValue(); - assertThat(configuration.get(TemplateEngine.class.getName())) - .isInstanceOf(TemplateEngine.class); - assertThat(configuration.get(WriterResolver.class.getName())) - .isInstanceOf(WriterResolver.class); - assertThat(configuration - .get(RestDocumentationGenerator.ATTRIBUTE_NAME_DEFAULT_SNIPPETS)) - .isInstanceOf(List.class); + assertThat(configuration.get(TemplateEngine.class.getName())).isInstanceOf(TemplateEngine.class); + assertThat(configuration.get(WriterResolver.class.getName())).isInstanceOf(WriterResolver.class); + assertThat(configuration.get(RestDocumentationGenerator.ATTRIBUTE_NAME_DEFAULT_SNIPPETS)) + .isInstanceOf(List.class); } } diff --git a/spring-restdocs-restassured/src/test/java/org/springframework/restdocs/restassured/RestAssuredRestDocumentationIntegrationTests.java b/spring-restdocs-restassured/src/test/java/org/springframework/restdocs/restassured/RestAssuredRestDocumentationIntegrationTests.java index 2c6b429bd..bf17f0969 100644 --- a/spring-restdocs-restassured/src/test/java/org/springframework/restdocs/restassured/RestAssuredRestDocumentationIntegrationTests.java +++ b/spring-restdocs-restassured/src/test/java/org/springframework/restdocs/restassured/RestAssuredRestDocumentationIntegrationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-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. @@ -87,319 +87,238 @@ public class RestAssuredRestDocumentationIntegrationTests { @Test public void defaultSnippetGeneration() { RestAssured.given().port(tomcat.getPort()) - .filter(RestAssuredRestDocumentation - .documentationConfiguration(this.restDocumentation)) - .filter(RestAssuredRestDocumentation.document("default")).get("/").then() - .statusCode(200); - assertExpectedSnippetFilesExist(new File("build/generated-snippets/default"), - "http-request.adoc", "http-response.adoc", "curl-request.adoc"); + .filter(RestAssuredRestDocumentation.documentationConfiguration(this.restDocumentation)) + .filter(RestAssuredRestDocumentation.document("default")).get("/").then().statusCode(200); + assertExpectedSnippetFilesExist(new File("build/generated-snippets/default"), "http-request.adoc", + "http-response.adoc", "curl-request.adoc"); } @Test public void curlSnippetWithContent() throws Exception { String contentType = "text/plain; charset=UTF-8"; RestAssured.given().port(tomcat.getPort()) - .filter(RestAssuredRestDocumentation - .documentationConfiguration(this.restDocumentation)) - .filter(RestAssuredRestDocumentation - .document("curl-snippet-with-content")) - .accept("application/json").content("content").contentType(contentType) - .post("/").then().statusCode(200); - - assertThat(new File( - "build/generated-snippets/curl-snippet-with-content/curl-request.adoc")) - .has(content(codeBlock(TemplateFormats.asciidoctor(), "bash") - .withContent(String.format("$ curl 'http://localhost:" - + tomcat.getPort() + "/' -i -X POST \\%n" - + " -H 'Accept: application/json' \\%n" - + " -H 'Content-Type: " + contentType - + "' \\%n" + " -d 'content'")))); + .filter(RestAssuredRestDocumentation.documentationConfiguration(this.restDocumentation)) + .filter(RestAssuredRestDocumentation.document("curl-snippet-with-content")).accept("application/json") + .content("content").contentType(contentType).post("/").then().statusCode(200); + + assertThat(new File("build/generated-snippets/curl-snippet-with-content/curl-request.adoc")).has(content( + codeBlock(TemplateFormats.asciidoctor(), "bash").withContent(String.format("$ curl 'http://localhost:" + + tomcat.getPort() + "/' -i -X POST \\%n" + " -H 'Accept: application/json' \\%n" + + " -H 'Content-Type: " + contentType + "' \\%n" + " -d 'content'")))); } @Test public void curlSnippetWithCookies() throws Exception { String contentType = "text/plain; charset=UTF-8"; RestAssured.given().port(tomcat.getPort()) - .filter(RestAssuredRestDocumentation - .documentationConfiguration(this.restDocumentation)) - .filter(RestAssuredRestDocumentation - .document("curl-snippet-with-cookies")) - .accept("application/json").contentType(contentType) - .cookie("cookieName", "cookieVal").get("/").then().statusCode(200); - assertThat(new File( - "build/generated-snippets/curl-snippet-with-cookies/curl-request.adoc")) - .has(content(codeBlock(TemplateFormats.asciidoctor(), "bash") - .withContent(String.format("$ curl 'http://localhost:" - + tomcat.getPort() + "/' -i -X GET \\%n" - + " -H 'Accept: application/json' \\%n" - + " -H 'Content-Type: " + contentType - + "' \\%n" - + " --cookie 'cookieName=cookieVal'")))); + .filter(RestAssuredRestDocumentation.documentationConfiguration(this.restDocumentation)) + .filter(RestAssuredRestDocumentation.document("curl-snippet-with-cookies")).accept("application/json") + .contentType(contentType).cookie("cookieName", "cookieVal").get("/").then().statusCode(200); + assertThat(new File("build/generated-snippets/curl-snippet-with-cookies/curl-request.adoc")).has(content( + codeBlock(TemplateFormats.asciidoctor(), "bash").withContent(String.format("$ curl 'http://localhost:" + + tomcat.getPort() + "/' -i -X GET \\%n" + " -H 'Accept: application/json' \\%n" + + " -H 'Content-Type: " + contentType + "' \\%n" + " --cookie 'cookieName=cookieVal'")))); } @Test public void curlSnippetWithQueryStringOnPost() throws Exception { RestAssured.given().port(tomcat.getPort()) - .filter(RestAssuredRestDocumentation - .documentationConfiguration(this.restDocumentation)) - .filter(RestAssuredRestDocumentation - .document("curl-snippet-with-query-string")) - .accept("application/json").param("foo", "bar").param("a", "alpha") - .post("/?foo=bar").then().statusCode(200); + .filter(RestAssuredRestDocumentation.documentationConfiguration(this.restDocumentation)) + .filter(RestAssuredRestDocumentation.document("curl-snippet-with-query-string")) + .accept("application/json").param("foo", "bar").param("a", "alpha").post("/?foo=bar").then() + .statusCode(200); String contentType = "application/x-www-form-urlencoded; charset=ISO-8859-1"; - assertThat(new File( - "build/generated-snippets/curl-snippet-with-query-string/curl-request.adoc")) - .has(content(codeBlock(TemplateFormats.asciidoctor(), "bash") - .withContent(String.format("$ curl " - + "'http://localhost:" + tomcat.getPort() - + "/?foo=bar' -i -X POST \\%n" - + " -H 'Accept: application/json' \\%n" - + " -H 'Content-Type: " + contentType - + "' \\%n" + " -d 'a=alpha'")))); + assertThat(new File("build/generated-snippets/curl-snippet-with-query-string/curl-request.adoc")) + .has(content(codeBlock(TemplateFormats.asciidoctor(), "bash") + .withContent(String.format("$ curl " + "'http://localhost:" + tomcat.getPort() + + "/?foo=bar' -i -X POST \\%n" + " -H 'Accept: application/json' \\%n" + + " -H 'Content-Type: " + contentType + "' \\%n" + " -d 'a=alpha'")))); } @Test public void linksSnippet() throws Exception { RestAssured.given().port(tomcat.getPort()) - .filter(RestAssuredRestDocumentation - .documentationConfiguration(this.restDocumentation)) + .filter(RestAssuredRestDocumentation.documentationConfiguration(this.restDocumentation)) .filter(RestAssuredRestDocumentation.document("links", links(linkWithRel("rel").description("The description")))) .accept("application/json").get("/").then().statusCode(200); - assertExpectedSnippetFilesExist(new File("build/generated-snippets/links"), - "http-request.adoc", "http-response.adoc", "curl-request.adoc", - "links.adoc"); + assertExpectedSnippetFilesExist(new File("build/generated-snippets/links"), "http-request.adoc", + "http-response.adoc", "curl-request.adoc", "links.adoc"); } @Test public void pathParametersSnippet() throws Exception { RestAssured.given().port(tomcat.getPort()) - .filter(RestAssuredRestDocumentation - .documentationConfiguration(this.restDocumentation)) + .filter(RestAssuredRestDocumentation.documentationConfiguration(this.restDocumentation)) .filter(RestAssuredRestDocumentation.document("path-parameters", - pathParameters( - parameterWithName("foo").description("The description")))) + pathParameters(parameterWithName("foo").description("The description")))) .accept("application/json").get("/{foo}", "").then().statusCode(200); - assertExpectedSnippetFilesExist( - new File("build/generated-snippets/path-parameters"), "http-request.adoc", + assertExpectedSnippetFilesExist(new File("build/generated-snippets/path-parameters"), "http-request.adoc", "http-response.adoc", "curl-request.adoc", "path-parameters.adoc"); } @Test public void requestParametersSnippet() throws Exception { RestAssured.given().port(tomcat.getPort()) - .filter(RestAssuredRestDocumentation - .documentationConfiguration(this.restDocumentation)) + .filter(RestAssuredRestDocumentation.documentationConfiguration(this.restDocumentation)) .filter(RestAssuredRestDocumentation.document("request-parameters", - requestParameters( - parameterWithName("foo").description("The description")))) - .accept("application/json").param("foo", "bar").get("/").then() - .statusCode(200); - assertExpectedSnippetFilesExist( - new File("build/generated-snippets/request-parameters"), - "http-request.adoc", "http-response.adoc", "curl-request.adoc", - "request-parameters.adoc"); + requestParameters(parameterWithName("foo").description("The description")))) + .accept("application/json").param("foo", "bar").get("/").then().statusCode(200); + assertExpectedSnippetFilesExist(new File("build/generated-snippets/request-parameters"), "http-request.adoc", + "http-response.adoc", "curl-request.adoc", "request-parameters.adoc"); } @Test public void requestFieldsSnippet() throws Exception { RestAssured.given().port(tomcat.getPort()) - .filter(RestAssuredRestDocumentation - .documentationConfiguration(this.restDocumentation)) + .filter(RestAssuredRestDocumentation.documentationConfiguration(this.restDocumentation)) .filter(RestAssuredRestDocumentation.document("request-fields", requestFields(fieldWithPath("a").description("The description")))) - .accept("application/json").content("{\"a\":\"alpha\"}").post("/").then() - .statusCode(200); - assertExpectedSnippetFilesExist( - new File("build/generated-snippets/request-fields"), "http-request.adoc", + .accept("application/json").content("{\"a\":\"alpha\"}").post("/").then().statusCode(200); + assertExpectedSnippetFilesExist(new File("build/generated-snippets/request-fields"), "http-request.adoc", "http-response.adoc", "curl-request.adoc", "request-fields.adoc"); } @Test public void requestPartsSnippet() throws Exception { RestAssured.given().port(tomcat.getPort()) - .filter(RestAssuredRestDocumentation - .documentationConfiguration(this.restDocumentation)) + .filter(RestAssuredRestDocumentation.documentationConfiguration(this.restDocumentation)) .filter(RestAssuredRestDocumentation.document("request-parts", requestParts(partWithName("a").description("The description")))) .multiPart("a", "foo").post("/upload").then().statusCode(200); - assertExpectedSnippetFilesExist( - new File("build/generated-snippets/request-parts"), "http-request.adoc", + assertExpectedSnippetFilesExist(new File("build/generated-snippets/request-parts"), "http-request.adoc", "http-response.adoc", "curl-request.adoc", "request-parts.adoc"); } @Test public void responseFieldsSnippet() throws Exception { RestAssured.given().port(tomcat.getPort()) - .filter(RestAssuredRestDocumentation - .documentationConfiguration(this.restDocumentation)) + .filter(RestAssuredRestDocumentation.documentationConfiguration(this.restDocumentation)) .filter(RestAssuredRestDocumentation.document("response-fields", responseFields(fieldWithPath("a").description("The description"), - subsectionWithPath("links") - .description("Links to other resources")))) + subsectionWithPath("links").description("Links to other resources")))) .accept("application/json").get("/").then().statusCode(200); - assertExpectedSnippetFilesExist( - new File("build/generated-snippets/response-fields"), "http-request.adoc", + assertExpectedSnippetFilesExist(new File("build/generated-snippets/response-fields"), "http-request.adoc", "http-response.adoc", "curl-request.adoc", "response-fields.adoc"); } @Test public void parameterizedOutputDirectory() throws Exception { RestAssured.given().port(tomcat.getPort()) - .filter(RestAssuredRestDocumentation - .documentationConfiguration(this.restDocumentation)) - .filter(RestAssuredRestDocumentation.document("{method-name}")).get("/") - .then().statusCode(200); - assertExpectedSnippetFilesExist( - new File("build/generated-snippets/parameterized-output-directory"), + .filter(RestAssuredRestDocumentation.documentationConfiguration(this.restDocumentation)) + .filter(RestAssuredRestDocumentation.document("{method-name}")).get("/").then().statusCode(200); + assertExpectedSnippetFilesExist(new File("build/generated-snippets/parameterized-output-directory"), "http-request.adoc", "http-response.adoc", "curl-request.adoc"); } @Test public void multiStep() throws Exception { RequestSpecification spec = new RequestSpecBuilder().setPort(tomcat.getPort()) - .addFilter(RestAssuredRestDocumentation - .documentationConfiguration(this.restDocumentation)) - .addFilter(RestAssuredRestDocumentation.document("{method-name}-{step}")) - .build(); + .addFilter(RestAssuredRestDocumentation.documentationConfiguration(this.restDocumentation)) + .addFilter(RestAssuredRestDocumentation.document("{method-name}-{step}")).build(); RestAssured.given(spec).get("/").then().statusCode(200); - assertExpectedSnippetFilesExist( - new File("build/generated-snippets/multi-step-1/"), "http-request.adoc", + assertExpectedSnippetFilesExist(new File("build/generated-snippets/multi-step-1/"), "http-request.adoc", "http-response.adoc", "curl-request.adoc"); RestAssured.given(spec).get("/").then().statusCode(200); - assertExpectedSnippetFilesExist( - new File("build/generated-snippets/multi-step-2/"), "http-request.adoc", + assertExpectedSnippetFilesExist(new File("build/generated-snippets/multi-step-2/"), "http-request.adoc", "http-response.adoc", "curl-request.adoc"); RestAssured.given(spec).get("/").then().statusCode(200); - assertExpectedSnippetFilesExist( - new File("build/generated-snippets/multi-step-3/"), "http-request.adoc", + assertExpectedSnippetFilesExist(new File("build/generated-snippets/multi-step-3/"), "http-request.adoc", "http-response.adoc", "curl-request.adoc"); } @Test public void additionalSnippets() throws Exception { - RestDocumentationFilter documentation = RestAssuredRestDocumentation - .document("{method-name}-{step}"); + RestDocumentationFilter documentation = RestAssuredRestDocumentation.document("{method-name}-{step}"); RequestSpecification spec = new RequestSpecBuilder().setPort(tomcat.getPort()) - .addFilter(RestAssuredRestDocumentation - .documentationConfiguration(this.restDocumentation)) + .addFilter(RestAssuredRestDocumentation.documentationConfiguration(this.restDocumentation)) .addFilter(documentation).build(); - RestAssured.given(spec) - .filter(documentation - .document(responseHeaders(headerWithName("a").description("one"), - headerWithName("Foo").description("two")))) + RestAssured.given(spec).filter(documentation.document( + responseHeaders(headerWithName("a").description("one"), headerWithName("Foo").description("two")))) .get("/").then().statusCode(200); - assertExpectedSnippetFilesExist( - new File("build/generated-snippets/additional-snippets-1/"), - "http-request.adoc", "http-response.adoc", "curl-request.adoc", - "response-headers.adoc"); + assertExpectedSnippetFilesExist(new File("build/generated-snippets/additional-snippets-1/"), + "http-request.adoc", "http-response.adoc", "curl-request.adoc", "response-headers.adoc"); } @Test public void responseWithCookie() { RestAssured.given().port(tomcat.getPort()) - .filter(RestAssuredRestDocumentation - .documentationConfiguration(this.restDocumentation)) + .filter(RestAssuredRestDocumentation.documentationConfiguration(this.restDocumentation)) .filter(RestAssuredRestDocumentation.document("set-cookie", - preprocessResponse(removeHeaders(HttpHeaders.DATE, - HttpHeaders.CONTENT_TYPE)))) + preprocessResponse(removeHeaders(HttpHeaders.DATE, HttpHeaders.CONTENT_TYPE)))) .get("/set-cookie").then().statusCode(200); - assertExpectedSnippetFilesExist(new File("build/generated-snippets/set-cookie"), - "http-request.adoc", "http-response.adoc", "curl-request.adoc"); + assertExpectedSnippetFilesExist(new File("build/generated-snippets/set-cookie"), "http-request.adoc", + "http-response.adoc", "curl-request.adoc"); assertThat(new File("build/generated-snippets/set-cookie/http-response.adoc")) - .has(content(httpResponse(TemplateFormats.asciidoctor(), HttpStatus.OK) - .header(HttpHeaders.SET_COOKIE, - "name=value; Domain=localhost; HttpOnly"))); + .has(content(httpResponse(TemplateFormats.asciidoctor(), HttpStatus.OK).header(HttpHeaders.SET_COOKIE, + "name=value; Domain=localhost; HttpOnly"))); } @Test public void preprocessedRequest() throws Exception { Pattern pattern = Pattern.compile("(\"alpha\")"); RestAssured.given().port(tomcat.getPort()) - .filter(RestAssuredRestDocumentation - .documentationConfiguration(this.restDocumentation)) - .header("a", "alpha").header("b", "bravo").contentType("application/json") - .accept("application/json").content("{\"a\":\"alpha\"}") - .filter(RestAssuredRestDocumentation.document("original-request")) + .filter(RestAssuredRestDocumentation.documentationConfiguration(this.restDocumentation)) + .header("a", "alpha").header("b", "bravo").contentType("application/json").accept("application/json") + .content("{\"a\":\"alpha\"}").filter(RestAssuredRestDocumentation.document("original-request")) .filter(RestAssuredRestDocumentation.document("preprocessed-request", - preprocessRequest(prettyPrint(), - replacePattern(pattern, "\"<>\""), + preprocessRequest(prettyPrint(), replacePattern(pattern, "\"<>\""), RestAssuredPreprocessors.modifyUris().removePort(), removeHeaders("a", HttpHeaders.CONTENT_LENGTH)))) .get("/").then().statusCode(200); - assertThat( - new File("build/generated-snippets/original-request/http-request.adoc")) - .has(content(httpRequest(TemplateFormats.asciidoctor(), - RequestMethod.GET, "/").header("a", "alpha") - .header("b", "bravo") - .header("Accept", - MediaType.APPLICATION_JSON_VALUE) - .header("Content-Type", - "application/json; charset=UTF-8") - .header("Host", "localhost:" + tomcat.getPort()) - .header("Content-Length", "13") - .content("{\"a\":\"alpha\"}"))); + assertThat(new File("build/generated-snippets/original-request/http-request.adoc")) + .has(content(httpRequest(TemplateFormats.asciidoctor(), RequestMethod.GET, "/").header("a", "alpha") + .header("b", "bravo").header("Accept", MediaType.APPLICATION_JSON_VALUE) + .header("Content-Type", "application/json; charset=UTF-8") + .header("Host", "localhost:" + tomcat.getPort()).header("Content-Length", "13") + .content("{\"a\":\"alpha\"}"))); String prettyPrinted = String.format("{%n \"a\" : \"<>\"%n}"); - assertThat(new File( - "build/generated-snippets/preprocessed-request/http-request.adoc")) - .has(content(httpRequest(TemplateFormats.asciidoctor(), - RequestMethod.GET, "/") - .header("b", "bravo") - .header("Accept", - MediaType.APPLICATION_JSON_VALUE) - .header("Content-Type", - "application/json; charset=UTF-8") - .header("Host", "localhost") - .content(prettyPrinted))); + assertThat(new File("build/generated-snippets/preprocessed-request/http-request.adoc")) + .has(content(httpRequest(TemplateFormats.asciidoctor(), RequestMethod.GET, "/").header("b", "bravo") + .header("Accept", MediaType.APPLICATION_JSON_VALUE) + .header("Content-Type", "application/json; charset=UTF-8").header("Host", "localhost") + .content(prettyPrinted))); } @Test public void preprocessedResponse() throws Exception { Pattern pattern = Pattern.compile("(\"alpha\")"); RestAssured.given().port(tomcat.getPort()) - .filter(RestAssuredRestDocumentation - .documentationConfiguration(this.restDocumentation)) + .filter(RestAssuredRestDocumentation.documentationConfiguration(this.restDocumentation)) .filter(RestAssuredRestDocumentation.document("original-response")) .filter(RestAssuredRestDocumentation.document("preprocessed-response", preprocessResponse(prettyPrint(), maskLinks(), removeHeaders("a", "Transfer-Encoding", "Date", "Server"), - replacePattern(pattern, "\"<>\""), - RestAssuredPreprocessors.modifyUris().scheme("https") - .host("api.example.com").removePort()))) + replacePattern(pattern, "\"<>\""), RestAssuredPreprocessors.modifyUris() + .scheme("https").host("api.example.com").removePort()))) .get("/").then().statusCode(200); String prettyPrinted = String.format("{%n \"a\" : \"<>\",%n \"links\" : " + "[ {%n \"rel\" : \"rel\",%n \"href\" : \"...\"%n } ]%n}"); - assertThat(new File( - "build/generated-snippets/preprocessed-response/http-response.adoc")).has( - content(httpResponse(TemplateFormats.asciidoctor(), HttpStatus.OK) - .header("Foo", "https://api.example.com/foo/bar") - .header("Content-Type", "application/json;charset=UTF-8") - .header(HttpHeaders.CONTENT_LENGTH, - prettyPrinted.getBytes().length) - .content(prettyPrinted))); + assertThat(new File("build/generated-snippets/preprocessed-response/http-response.adoc")) + .has(content(httpResponse(TemplateFormats.asciidoctor(), HttpStatus.OK) + .header("Foo", "https://api.example.com/foo/bar") + .header("Content-Type", "application/json;charset=UTF-8") + .header(HttpHeaders.CONTENT_LENGTH, prettyPrinted.getBytes().length).content(prettyPrinted))); } @Test public void customSnippetTemplate() throws Exception { - ClassLoader classLoader = new URLClassLoader(new URL[] { - new File("src/test/resources/custom-snippet-templates").toURI().toURL() }, + ClassLoader classLoader = new URLClassLoader( + new URL[] { new File("src/test/resources/custom-snippet-templates").toURI().toURL() }, getClass().getClassLoader()); ClassLoader previous = Thread.currentThread().getContextClassLoader(); Thread.currentThread().setContextClassLoader(classLoader); try { RestAssured.given().port(tomcat.getPort()).accept("application/json") - .filter(RestAssuredRestDocumentation - .documentationConfiguration(this.restDocumentation)) - .filter(RestAssuredRestDocumentation - .document("custom-snippet-template")) - .get("/").then().statusCode(200); + .filter(RestAssuredRestDocumentation.documentationConfiguration(this.restDocumentation)) + .filter(RestAssuredRestDocumentation.document("custom-snippet-template")).get("/").then() + .statusCode(200); } finally { Thread.currentThread().setContextClassLoader(previous); } - assertThat(new File( - "build/generated-snippets/custom-snippet-template/curl-request.adoc")) - .hasContent("Custom curl request"); + assertThat(new File("build/generated-snippets/custom-snippet-template/curl-request.adoc")) + .hasContent("Custom curl request"); } private void assertExpectedSnippetFilesExist(File directory, String... snippets) { @@ -412,8 +331,7 @@ private CodeBlockCondition codeBlock(TemplateFormat format, String language) return SnippetConditions.codeBlock(format, language); } - private HttpRequestCondition httpRequest(TemplateFormat format, - RequestMethod requestMethod, String uri) { + private HttpRequestCondition httpRequest(TemplateFormat format, RequestMethod requestMethod, String uri) { return SnippetConditions.httpRequest(format, requestMethod, uri); } @@ -427,9 +345,8 @@ private Condition content(final Condition delegate) { @Override public boolean matches(File value) { try { - return delegate - .matches(FileCopyUtils.copyToString(new InputStreamReader( - new FileInputStream(value), StandardCharsets.UTF_8))); + return delegate.matches(FileCopyUtils + .copyToString(new InputStreamReader(new FileInputStream(value), StandardCharsets.UTF_8))); } catch (IOException ex) { fail("Failed to read '" + value + "'", ex); diff --git a/spring-restdocs-restassured/src/test/java/org/springframework/restdocs/restassured/TomcatServer.java b/spring-restdocs-restassured/src/test/java/org/springframework/restdocs/restassured/TomcatServer.java index 5916bc809..8b38b9622 100644 --- a/spring-restdocs-restassured/src/test/java/org/springframework/restdocs/restassured/TomcatServer.java +++ b/spring-restdocs-restassured/src/test/java/org/springframework/restdocs/restassured/TomcatServer.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2017 the original author or authors. + * Copyright 2014-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. @@ -89,8 +89,7 @@ protected void doPost(HttpServletRequest request, HttpServletResponse response) respondWithJson(response); } - private void respondWithJson(HttpServletResponse response) - throws IOException, JsonProcessingException { + private void respondWithJson(HttpServletResponse response) throws IOException, JsonProcessingException { response.setCharacterEncoding("UTF-8"); response.setContentType("application/json"); Map content = new HashMap<>(); @@ -113,8 +112,7 @@ private void respondWithJson(HttpServletResponse response) private static final class CookiesServlet extends HttpServlet { @Override - protected void doGet(HttpServletRequest req, HttpServletResponse resp) - throws ServletException, IOException { + protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { Cookie cookie = new Cookie("name", "value"); cookie.setDomain("localhost"); cookie.setHttpOnly(true); diff --git a/spring-restdocs-restassured/src/test/java/org/springframework/restdocs/restassured/operation/preprocess/UriModifyingOperationPreprocessorTests.java b/spring-restdocs-restassured/src/test/java/org/springframework/restdocs/restassured/operation/preprocess/UriModifyingOperationPreprocessorTests.java index ce2b99e1f..db249aa54 100644 --- a/spring-restdocs-restassured/src/test/java/org/springframework/restdocs/restassured/operation/preprocess/UriModifyingOperationPreprocessorTests.java +++ b/spring-restdocs-restassured/src/test/java/org/springframework/restdocs/restassured/operation/preprocess/UriModifyingOperationPreprocessorTests.java @@ -54,20 +54,16 @@ public class UriModifyingOperationPreprocessorTests { @Test public void requestUriSchemeCanBeModified() { this.preprocessor.scheme("https"); - OperationRequest processed = this.preprocessor - .preprocess(createRequestWithUri("http://localhost:12345")); + OperationRequest processed = this.preprocessor.preprocess(createRequestWithUri("http://localhost:12345")); assertThat(processed.getUri()).isEqualTo(URI.create("https://localhost:12345")); } @Test public void requestUriHostCanBeModified() { this.preprocessor.host("api.example.com"); - OperationRequest processed = this.preprocessor - .preprocess(createRequestWithUri("https://api.foo.com:12345")); - assertThat(processed.getUri()) - .isEqualTo(URI.create("https://api.example.com:12345")); - assertThat(processed.getHeaders().getFirst(HttpHeaders.HOST)) - .isEqualTo("api.example.com:12345"); + OperationRequest processed = this.preprocessor.preprocess(createRequestWithUri("https://api.foo.com:12345")); + assertThat(processed.getUri()).isEqualTo(URI.create("https://api.example.com:12345")); + assertThat(processed.getHeaders().getFirst(HttpHeaders.HOST)).isEqualTo("api.example.com:12345"); } @Test @@ -75,10 +71,8 @@ public void requestUriPortCanBeModified() { this.preprocessor.port(23456); OperationRequest processed = this.preprocessor .preprocess(createRequestWithUri("https://api.example.com:12345")); - assertThat(processed.getUri()) - .isEqualTo(URI.create("https://api.example.com:23456")); - assertThat(processed.getHeaders().getFirst(HttpHeaders.HOST)) - .isEqualTo("api.example.com:23456"); + assertThat(processed.getUri()).isEqualTo(URI.create("https://api.example.com:23456")); + assertThat(processed.getHeaders().getFirst(HttpHeaders.HOST)).isEqualTo("api.example.com:23456"); } @Test @@ -87,26 +81,23 @@ public void requestUriPortCanBeRemoved() { OperationRequest processed = this.preprocessor .preprocess(createRequestWithUri("https://api.example.com:12345")); assertThat(processed.getUri()).isEqualTo(URI.create("https://api.example.com")); - assertThat(processed.getHeaders().getFirst(HttpHeaders.HOST)) - .isEqualTo("api.example.com"); + assertThat(processed.getHeaders().getFirst(HttpHeaders.HOST)).isEqualTo("api.example.com"); } @Test public void requestUriPathIsPreserved() { this.preprocessor.removePort(); - OperationRequest processed = this.preprocessor.preprocess( - createRequestWithUri("https://api.example.com:12345/foo/bar")); - assertThat(processed.getUri()) - .isEqualTo(URI.create("https://api.example.com/foo/bar")); + OperationRequest processed = this.preprocessor + .preprocess(createRequestWithUri("https://api.example.com:12345/foo/bar")); + assertThat(processed.getUri()).isEqualTo(URI.create("https://api.example.com/foo/bar")); } @Test public void requestUriQueryIsPreserved() { this.preprocessor.removePort(); - OperationRequest processed = this.preprocessor.preprocess( - createRequestWithUri("https://api.example.com:12345?foo=bar")); - assertThat(processed.getUri()) - .isEqualTo(URI.create("https://api.example.com?foo=bar")); + OperationRequest processed = this.preprocessor + .preprocess(createRequestWithUri("https://api.example.com:12345?foo=bar")); + assertThat(processed.getUri()).isEqualTo(URI.create("https://api.example.com?foo=bar")); } @Test @@ -114,26 +105,22 @@ public void requestUriAnchorIsPreserved() { this.preprocessor.removePort(); OperationRequest processed = this.preprocessor .preprocess(createRequestWithUri("https://api.example.com:12345#foo")); - assertThat(processed.getUri()) - .isEqualTo(URI.create("https://api.example.com#foo")); + assertThat(processed.getUri()).isEqualTo(URI.create("https://api.example.com#foo")); } @Test public void requestContentUriSchemeCanBeModified() { this.preprocessor.scheme("https"); OperationRequest processed = this.preprocessor - .preprocess(createRequestWithContent( - "The uri 'http://localhost:12345' should be used")); - assertThat(new String(processed.getContent())) - .isEqualTo("The uri 'https://localhost:12345' should be used"); + .preprocess(createRequestWithContent("The uri 'http://localhost:12345' should be used")); + assertThat(new String(processed.getContent())).isEqualTo("The uri 'https://localhost:12345' should be used"); } @Test public void requestContentUriHostCanBeModified() { this.preprocessor.host("api.example.com"); OperationRequest processed = this.preprocessor - .preprocess(createRequestWithContent( - "The uri 'https://localhost:12345' should be used")); + .preprocess(createRequestWithContent("The uri 'https://localhost:12345' should be used")); assertThat(new String(processed.getContent())) .isEqualTo("The uri 'https://api.example.com:12345' should be used"); } @@ -142,78 +129,64 @@ public void requestContentUriHostCanBeModified() { public void requestContentUriPortCanBeModified() { this.preprocessor.port(23456); OperationRequest processed = this.preprocessor - .preprocess(createRequestWithContent( - "The uri 'http://localhost:12345' should be used")); - assertThat(new String(processed.getContent())) - .isEqualTo("The uri 'http://localhost:23456' should be used"); + .preprocess(createRequestWithContent("The uri 'http://localhost:12345' should be used")); + assertThat(new String(processed.getContent())).isEqualTo("The uri 'http://localhost:23456' should be used"); } @Test public void requestContentUriPortCanBeRemoved() { this.preprocessor.removePort(); OperationRequest processed = this.preprocessor - .preprocess(createRequestWithContent( - "The uri 'http://localhost:12345' should be used")); - assertThat(new String(processed.getContent())) - .isEqualTo("The uri 'http://localhost' should be used"); + .preprocess(createRequestWithContent("The uri 'http://localhost:12345' should be used")); + assertThat(new String(processed.getContent())).isEqualTo("The uri 'http://localhost' should be used"); } @Test public void multipleRequestContentUrisCanBeModified() { this.preprocessor.removePort(); - OperationRequest processed = this.preprocessor - .preprocess(createRequestWithContent( - "Use 'http://localhost:12345' or 'https://localhost:23456' to access the service")); - assertThat(new String(processed.getContent())).isEqualTo( - "Use 'http://localhost' or 'https://localhost' to access the service"); + OperationRequest processed = this.preprocessor.preprocess(createRequestWithContent( + "Use 'http://localhost:12345' or 'https://localhost:23456' to access the service")); + assertThat(new String(processed.getContent())) + .isEqualTo("Use 'http://localhost' or 'https://localhost' to access the service"); } @Test public void requestContentUriPathIsPreserved() { this.preprocessor.removePort(); OperationRequest processed = this.preprocessor - .preprocess(createRequestWithContent( - "The uri 'http://localhost:12345/foo/bar' should be used")); - assertThat(new String(processed.getContent())) - .isEqualTo("The uri 'http://localhost/foo/bar' should be used"); + .preprocess(createRequestWithContent("The uri 'http://localhost:12345/foo/bar' should be used")); + assertThat(new String(processed.getContent())).isEqualTo("The uri 'http://localhost/foo/bar' should be used"); } @Test public void requestContentUriQueryIsPreserved() { this.preprocessor.removePort(); OperationRequest processed = this.preprocessor - .preprocess(createRequestWithContent( - "The uri 'http://localhost:12345?foo=bar' should be used")); - assertThat(new String(processed.getContent())) - .isEqualTo("The uri 'http://localhost?foo=bar' should be used"); + .preprocess(createRequestWithContent("The uri 'http://localhost:12345?foo=bar' should be used")); + assertThat(new String(processed.getContent())).isEqualTo("The uri 'http://localhost?foo=bar' should be used"); } @Test public void requestContentUriAnchorIsPreserved() { this.preprocessor.removePort(); OperationRequest processed = this.preprocessor - .preprocess(createRequestWithContent( - "The uri 'http://localhost:12345#foo' should be used")); - assertThat(new String(processed.getContent())) - .isEqualTo("The uri 'http://localhost#foo' should be used"); + .preprocess(createRequestWithContent("The uri 'http://localhost:12345#foo' should be used")); + assertThat(new String(processed.getContent())).isEqualTo("The uri 'http://localhost#foo' should be used"); } @Test public void responseContentUriSchemeCanBeModified() { this.preprocessor.scheme("https"); OperationResponse processed = this.preprocessor - .preprocess(createResponseWithContent( - "The uri 'http://localhost:12345' should be used")); - assertThat(new String(processed.getContent())) - .isEqualTo("The uri 'https://localhost:12345' should be used"); + .preprocess(createResponseWithContent("The uri 'http://localhost:12345' should be used")); + assertThat(new String(processed.getContent())).isEqualTo("The uri 'https://localhost:12345' should be used"); } @Test public void responseContentUriHostCanBeModified() { this.preprocessor.host("api.example.com"); OperationResponse processed = this.preprocessor - .preprocess(createResponseWithContent( - "The uri 'https://localhost:12345' should be used")); + .preprocess(createResponseWithContent("The uri 'https://localhost:12345' should be used")); assertThat(new String(processed.getContent())) .isEqualTo("The uri 'https://api.example.com:12345' should be used"); } @@ -222,68 +195,56 @@ public void responseContentUriHostCanBeModified() { public void responseContentUriPortCanBeModified() { this.preprocessor.port(23456); OperationResponse processed = this.preprocessor - .preprocess(createResponseWithContent( - "The uri 'http://localhost:12345' should be used")); - assertThat(new String(processed.getContent())) - .isEqualTo("The uri 'http://localhost:23456' should be used"); + .preprocess(createResponseWithContent("The uri 'http://localhost:12345' should be used")); + assertThat(new String(processed.getContent())).isEqualTo("The uri 'http://localhost:23456' should be used"); } @Test public void responseContentUriPortCanBeRemoved() { this.preprocessor.removePort(); OperationResponse processed = this.preprocessor - .preprocess(createResponseWithContent( - "The uri 'http://localhost:12345' should be used")); - assertThat(new String(processed.getContent())) - .isEqualTo("The uri 'http://localhost' should be used"); + .preprocess(createResponseWithContent("The uri 'http://localhost:12345' should be used")); + assertThat(new String(processed.getContent())).isEqualTo("The uri 'http://localhost' should be used"); } @Test public void multipleResponseContentUrisCanBeModified() { this.preprocessor.removePort(); - OperationResponse processed = this.preprocessor - .preprocess(createResponseWithContent( - "Use 'http://localhost:12345' or 'https://localhost:23456' to access the service")); - assertThat(new String(processed.getContent())).isEqualTo( - "Use 'http://localhost' or 'https://localhost' to access the service"); + OperationResponse processed = this.preprocessor.preprocess(createResponseWithContent( + "Use 'http://localhost:12345' or 'https://localhost:23456' to access the service")); + assertThat(new String(processed.getContent())) + .isEqualTo("Use 'http://localhost' or 'https://localhost' to access the service"); } @Test public void responseContentUriPathIsPreserved() { this.preprocessor.removePort(); OperationResponse processed = this.preprocessor - .preprocess(createResponseWithContent( - "The uri 'http://localhost:12345/foo/bar' should be used")); - assertThat(new String(processed.getContent())) - .isEqualTo("The uri 'http://localhost/foo/bar' should be used"); + .preprocess(createResponseWithContent("The uri 'http://localhost:12345/foo/bar' should be used")); + assertThat(new String(processed.getContent())).isEqualTo("The uri 'http://localhost/foo/bar' should be used"); } @Test public void responseContentUriQueryIsPreserved() { this.preprocessor.removePort(); OperationResponse processed = this.preprocessor - .preprocess(createResponseWithContent( - "The uri 'http://localhost:12345?foo=bar' should be used")); - assertThat(new String(processed.getContent())) - .isEqualTo("The uri 'http://localhost?foo=bar' should be used"); + .preprocess(createResponseWithContent("The uri 'http://localhost:12345?foo=bar' should be used")); + assertThat(new String(processed.getContent())).isEqualTo("The uri 'http://localhost?foo=bar' should be used"); } @Test public void responseContentUriAnchorIsPreserved() { this.preprocessor.removePort(); OperationResponse processed = this.preprocessor - .preprocess(createResponseWithContent( - "The uri 'http://localhost:12345#foo' should be used")); - assertThat(new String(processed.getContent())) - .isEqualTo("The uri 'http://localhost#foo' should be used"); + .preprocess(createResponseWithContent("The uri 'http://localhost:12345#foo' should be used")); + assertThat(new String(processed.getContent())).isEqualTo("The uri 'http://localhost#foo' should be used"); } @Test public void urisInRequestHeadersCanBeModified() { OperationRequest processed = this.preprocessor.host("api.example.com") .preprocess(createRequestWithHeader("Foo", "https://locahost:12345")); - assertThat(processed.getHeaders().getFirst("Foo")) - .isEqualTo("https://api.example.com:12345"); + assertThat(processed.getHeaders().getFirst("Foo")).isEqualTo("https://api.example.com:12345"); assertThat(processed.getHeaders().getFirst("Host")).isEqualTo("api.example.com"); } @@ -291,14 +252,13 @@ public void urisInRequestHeadersCanBeModified() { public void urisInResponseHeadersCanBeModified() { OperationResponse processed = this.preprocessor.host("api.example.com") .preprocess(createResponseWithHeader("Foo", "https://locahost:12345")); - assertThat(processed.getHeaders().getFirst("Foo")) - .isEqualTo("https://api.example.com:12345"); + assertThat(processed.getHeaders().getFirst("Foo")).isEqualTo("https://api.example.com:12345"); } @Test public void urisInRequestPartHeadersCanBeModified() { - OperationRequest processed = this.preprocessor.host("api.example.com").preprocess( - createRequestWithPartWithHeader("Foo", "https://locahost:12345")); + OperationRequest processed = this.preprocessor.host("api.example.com") + .preprocess(createRequestWithPartWithHeader("Foo", "https://locahost:12345")); assertThat(processed.getParts().iterator().next().getHeaders().getFirst("Foo")) .isEqualTo("https://api.example.com:12345"); } @@ -306,8 +266,7 @@ public void urisInRequestPartHeadersCanBeModified() { @Test public void urisInRequestPartContentCanBeModified() { OperationRequest processed = this.preprocessor.host("api.example.com") - .preprocess(createRequestWithPartWithContent( - "The uri 'https://localhost:12345' should be used")); + .preprocess(createRequestWithPartWithContent("The uri 'https://localhost:12345' should be used")); assertThat(new String(processed.getParts().iterator().next().getContent())) .isEqualTo("The uri 'https://api.example.com:12345' should be used"); } @@ -317,61 +276,53 @@ public void modifiedUriDoesNotGetDoubleEncoded() { this.preprocessor.scheme("https"); OperationRequest processed = this.preprocessor .preprocess(createRequestWithUri("http://localhost:12345?foo=%7B%7D")); - assertThat(processed.getUri()) - .isEqualTo(URI.create("https://localhost:12345?foo=%7B%7D")); + assertThat(processed.getUri()).isEqualTo(URI.create("https://localhost:12345?foo=%7B%7D")); } @Test public void resultingRequestHasCookiesFromOriginalRequst() { List cookies = Arrays.asList(new RequestCookie("a", "alpha")); - OperationRequest request = this.requestFactory.create( - URI.create("http://localhost:12345"), HttpMethod.GET, new byte[0], - new HttpHeaders(), new Parameters(), - Collections.emptyList(), cookies); + OperationRequest request = this.requestFactory.create(URI.create("http://localhost:12345"), HttpMethod.GET, + new byte[0], new HttpHeaders(), new Parameters(), Collections.emptyList(), + cookies); OperationRequest processed = this.preprocessor.preprocess(request); assertThat(processed.getCookies().size()).isEqualTo(1); } private OperationRequest createRequestWithUri(String uri) { - return this.requestFactory.create(URI.create(uri), HttpMethod.GET, new byte[0], - new HttpHeaders(), new Parameters(), - Collections.emptyList()); + return this.requestFactory.create(URI.create(uri), HttpMethod.GET, new byte[0], new HttpHeaders(), + new Parameters(), Collections.emptyList()); } private OperationRequest createRequestWithContent(String content) { - return this.requestFactory.create(URI.create("http://localhost"), HttpMethod.GET, - content.getBytes(), new HttpHeaders(), new Parameters(), - Collections.emptyList()); + return this.requestFactory.create(URI.create("http://localhost"), HttpMethod.GET, content.getBytes(), + new HttpHeaders(), new Parameters(), Collections.emptyList()); } private OperationRequest createRequestWithHeader(String name, String value) { HttpHeaders headers = new HttpHeaders(); headers.add(name, value); - return this.requestFactory.create(URI.create("http://localhost"), HttpMethod.GET, - new byte[0], headers, new Parameters(), - Collections.emptyList()); + return this.requestFactory.create(URI.create("http://localhost"), HttpMethod.GET, new byte[0], headers, + new Parameters(), Collections.emptyList()); } private OperationRequest createRequestWithPartWithHeader(String name, String value) { HttpHeaders headers = new HttpHeaders(); headers.add(name, value); - return this.requestFactory.create(URI.create("http://localhost"), HttpMethod.GET, - new byte[0], new HttpHeaders(), new Parameters(), - Arrays.asList(new OperationRequestPartFactory().create("part", "fileName", - new byte[0], headers))); + return this.requestFactory.create(URI.create("http://localhost"), HttpMethod.GET, new byte[0], + new HttpHeaders(), new Parameters(), + Arrays.asList(new OperationRequestPartFactory().create("part", "fileName", new byte[0], headers))); } private OperationRequest createRequestWithPartWithContent(String content) { - return this.requestFactory.create(URI.create("http://localhost"), HttpMethod.GET, - new byte[0], new HttpHeaders(), new Parameters(), - Arrays.asList(new OperationRequestPartFactory().create("part", "fileName", - content.getBytes(), new HttpHeaders()))); + return this.requestFactory.create(URI.create("http://localhost"), HttpMethod.GET, new byte[0], + new HttpHeaders(), new Parameters(), Arrays.asList(new OperationRequestPartFactory().create("part", + "fileName", content.getBytes(), new HttpHeaders()))); } private OperationResponse createResponseWithContent(String content) { - return this.responseFactory.create(HttpStatus.OK, new HttpHeaders(), - content.getBytes()); + return this.responseFactory.create(HttpStatus.OK, new HttpHeaders(), content.getBytes()); } private OperationResponse createResponseWithHeader(String name, String value) { diff --git a/spring-restdocs-restassured/src/test/java/org/springframework/restdocs/restassured3/RestAssuredRequestConverterTests.java b/spring-restdocs-restassured/src/test/java/org/springframework/restdocs/restassured3/RestAssuredRequestConverterTests.java index ecb5cfc65..72f9a94d4 100644 --- a/spring-restdocs-restassured/src/test/java/org/springframework/restdocs/restassured3/RestAssuredRequestConverterTests.java +++ b/spring-restdocs-restassured/src/test/java/org/springframework/restdocs/restassured3/RestAssuredRequestConverterTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-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. @@ -62,105 +62,84 @@ public class RestAssuredRequestConverterTests { public void requestUri() { RequestSpecification requestSpec = RestAssured.given().port(tomcat.getPort()); requestSpec.get("/foo/bar"); - OperationRequest request = this.factory - .convert((FilterableRequestSpecification) requestSpec); - assertThat(request.getUri()).isEqualTo( - URI.create("http://localhost:" + tomcat.getPort() + "/foo/bar")); + OperationRequest request = this.factory.convert((FilterableRequestSpecification) requestSpec); + assertThat(request.getUri()).isEqualTo(URI.create("http://localhost:" + tomcat.getPort() + "/foo/bar")); } @Test public void requestMethod() { RequestSpecification requestSpec = RestAssured.given().port(tomcat.getPort()); requestSpec.head("/foo/bar"); - OperationRequest request = this.factory - .convert((FilterableRequestSpecification) requestSpec); + OperationRequest request = this.factory.convert((FilterableRequestSpecification) requestSpec); assertThat(request.getMethod()).isEqualTo(HttpMethod.HEAD); } @Test public void queryStringParameters() { - RequestSpecification requestSpec = RestAssured.given().port(tomcat.getPort()) - .queryParam("foo", "bar"); + RequestSpecification requestSpec = RestAssured.given().port(tomcat.getPort()).queryParam("foo", "bar"); requestSpec.get("/"); - OperationRequest request = this.factory - .convert((FilterableRequestSpecification) requestSpec); + OperationRequest request = this.factory.convert((FilterableRequestSpecification) requestSpec); assertThat(request.getParameters()).hasSize(1); - assertThat(request.getParameters()).containsEntry("foo", - Collections.singletonList("bar")); + assertThat(request.getParameters()).containsEntry("foo", Collections.singletonList("bar")); } @Test public void queryStringFromUrlParameters() { RequestSpecification requestSpec = RestAssured.given().port(tomcat.getPort()); requestSpec.get("/?foo=bar&foo=qix"); - OperationRequest request = this.factory - .convert((FilterableRequestSpecification) requestSpec); + OperationRequest request = this.factory.convert((FilterableRequestSpecification) requestSpec); assertThat(request.getParameters()).hasSize(1); - assertThat(request.getParameters()).containsEntry("foo", - Arrays.asList("bar", "qix")); + assertThat(request.getParameters()).containsEntry("foo", Arrays.asList("bar", "qix")); } @Test public void formParameters() { - RequestSpecification requestSpec = RestAssured.given().port(tomcat.getPort()) - .formParam("foo", "bar"); + RequestSpecification requestSpec = RestAssured.given().port(tomcat.getPort()).formParam("foo", "bar"); requestSpec.get("/"); - OperationRequest request = this.factory - .convert((FilterableRequestSpecification) requestSpec); + OperationRequest request = this.factory.convert((FilterableRequestSpecification) requestSpec); assertThat(request.getParameters()).hasSize(1); - assertThat(request.getParameters()).containsEntry("foo", - Collections.singletonList("bar")); + assertThat(request.getParameters()).containsEntry("foo", Collections.singletonList("bar")); } @Test public void requestParameters() { - RequestSpecification requestSpec = RestAssured.given().port(tomcat.getPort()) - .param("foo", "bar"); + RequestSpecification requestSpec = RestAssured.given().port(tomcat.getPort()).param("foo", "bar"); requestSpec.get("/"); - OperationRequest request = this.factory - .convert((FilterableRequestSpecification) requestSpec); + OperationRequest request = this.factory.convert((FilterableRequestSpecification) requestSpec); assertThat(request.getParameters()).hasSize(1); - assertThat(request.getParameters()).containsEntry("foo", - Collections.singletonList("bar")); + assertThat(request.getParameters()).containsEntry("foo", Collections.singletonList("bar")); } @Test public void headers() { - RequestSpecification requestSpec = RestAssured.given().port(tomcat.getPort()) - .header("Foo", "bar"); + RequestSpecification requestSpec = RestAssured.given().port(tomcat.getPort()).header("Foo", "bar"); requestSpec.get("/"); - OperationRequest request = this.factory - .convert((FilterableRequestSpecification) requestSpec); + OperationRequest request = this.factory.convert((FilterableRequestSpecification) requestSpec); assertThat(request.getHeaders()).hasSize(2); - assertThat(request.getHeaders()).containsEntry("Foo", - Collections.singletonList("bar")); + assertThat(request.getHeaders()).containsEntry("Foo", Collections.singletonList("bar")); assertThat(request.getHeaders()).containsEntry("Host", Collections.singletonList("localhost:" + tomcat.getPort())); } @Test public void headersWithCustomAccept() { - RequestSpecification requestSpec = RestAssured.given().port(tomcat.getPort()) - .header("Foo", "bar").accept("application/json"); + RequestSpecification requestSpec = RestAssured.given().port(tomcat.getPort()).header("Foo", "bar") + .accept("application/json"); requestSpec.get("/"); - OperationRequest request = this.factory - .convert((FilterableRequestSpecification) requestSpec); + OperationRequest request = this.factory.convert((FilterableRequestSpecification) requestSpec); assertThat(request.getHeaders()).hasSize(3); - assertThat(request.getHeaders()).containsEntry("Foo", - Collections.singletonList("bar")); - assertThat(request.getHeaders()).containsEntry("Accept", - Collections.singletonList("application/json")); + assertThat(request.getHeaders()).containsEntry("Foo", Collections.singletonList("bar")); + assertThat(request.getHeaders()).containsEntry("Accept", Collections.singletonList("application/json")); assertThat(request.getHeaders()).containsEntry("Host", Collections.singletonList("localhost:" + tomcat.getPort())); } @Test public void cookies() { - RequestSpecification requestSpec = RestAssured.given().port(tomcat.getPort()) - .cookie("cookie1", "cookieVal1").cookie("cookie2", "cookieVal2"); + RequestSpecification requestSpec = RestAssured.given().port(tomcat.getPort()).cookie("cookie1", "cookieVal1") + .cookie("cookie2", "cookieVal2"); requestSpec.get("/"); - OperationRequest request = this.factory - .convert((FilterableRequestSpecification) requestSpec); + OperationRequest request = this.factory.convert((FilterableRequestSpecification) requestSpec); assertThat(request.getCookies().size()).isEqualTo(2); Iterator cookieIterator = request.getCookies().iterator(); @@ -177,115 +156,94 @@ public void cookies() { @Test public void multipart() { RequestSpecification requestSpec = RestAssured.given().port(tomcat.getPort()) - .multiPart("a", "a.txt", "alpha", null) - .multiPart("b", new ObjectBody("bar"), "application/json"); + .multiPart("a", "a.txt", "alpha", null).multiPart("b", new ObjectBody("bar"), "application/json"); requestSpec.post(); - OperationRequest request = this.factory - .convert((FilterableRequestSpecification) requestSpec); + OperationRequest request = this.factory.convert((FilterableRequestSpecification) requestSpec); Collection parts = request.getParts(); assertThat(parts).hasSize(2); assertThat(parts).extracting("name").containsExactly("a", "b"); - assertThat(parts).extracting("submittedFileName").containsExactly("a.txt", - "file"); - assertThat(parts).extracting("contentAsString").containsExactly("alpha", - "{\"foo\":\"bar\"}"); - assertThat(parts).extracting("headers").extracting(HttpHeaders.CONTENT_TYPE) - .containsExactly(Collections.singletonList(MediaType.TEXT_PLAIN_VALUE), - Collections.singletonList(MediaType.APPLICATION_JSON_VALUE)); + assertThat(parts).extracting("submittedFileName").containsExactly("a.txt", "file"); + assertThat(parts).extracting("contentAsString").containsExactly("alpha", "{\"foo\":\"bar\"}"); + assertThat(parts).extracting("headers").extracting(HttpHeaders.CONTENT_TYPE).containsExactly( + Collections.singletonList(MediaType.TEXT_PLAIN_VALUE), + Collections.singletonList(MediaType.APPLICATION_JSON_VALUE)); } @Test public void byteArrayBody() { - RequestSpecification requestSpec = RestAssured.given().body("body".getBytes()) - .port(tomcat.getPort()); + RequestSpecification requestSpec = RestAssured.given().body("body".getBytes()).port(tomcat.getPort()); requestSpec.post(); this.factory.convert((FilterableRequestSpecification) requestSpec); } @Test public void stringBody() { - RequestSpecification requestSpec = RestAssured.given().body("body") - .port(tomcat.getPort()); + RequestSpecification requestSpec = RestAssured.given().body("body").port(tomcat.getPort()); requestSpec.post(); - OperationRequest request = this.factory - .convert((FilterableRequestSpecification) requestSpec); + OperationRequest request = this.factory.convert((FilterableRequestSpecification) requestSpec); assertThat(request.getContentAsString()).isEqualTo("body"); } @Test public void objectBody() { - RequestSpecification requestSpec = RestAssured.given().body(new ObjectBody("bar")) - .port(tomcat.getPort()); + RequestSpecification requestSpec = RestAssured.given().body(new ObjectBody("bar")).port(tomcat.getPort()); requestSpec.post(); - OperationRequest request = this.factory - .convert((FilterableRequestSpecification) requestSpec); + OperationRequest request = this.factory.convert((FilterableRequestSpecification) requestSpec); assertThat(request.getContentAsString()).isEqualTo("{\"foo\":\"bar\"}"); } @Test public void byteArrayInputStreamBody() { - RequestSpecification requestSpec = RestAssured.given() - .body(new ByteArrayInputStream(new byte[] { 1, 2, 3, 4 })) + RequestSpecification requestSpec = RestAssured.given().body(new ByteArrayInputStream(new byte[] { 1, 2, 3, 4 })) .port(tomcat.getPort()); requestSpec.post(); - OperationRequest request = this.factory - .convert((FilterableRequestSpecification) requestSpec); + OperationRequest request = this.factory.convert((FilterableRequestSpecification) requestSpec); assertThat(request.getContent()).isEqualTo(new byte[] { 1, 2, 3, 4 }); } @Test public void fileBody() { - RequestSpecification requestSpec = RestAssured.given() - .body(new File("src/test/resources/body.txt")).port(tomcat.getPort()); + RequestSpecification requestSpec = RestAssured.given().body(new File("src/test/resources/body.txt")) + .port(tomcat.getPort()); requestSpec.post(); - OperationRequest request = this.factory - .convert((FilterableRequestSpecification) requestSpec); + OperationRequest request = this.factory.convert((FilterableRequestSpecification) requestSpec); assertThat(request.getContentAsString()).isEqualTo("file"); } @Test public void fileInputStreamBody() throws FileNotFoundException { FileInputStream inputStream = new FileInputStream("src/test/resources/body.txt"); - RequestSpecification requestSpec = RestAssured.given().body(inputStream) - .port(tomcat.getPort()); + RequestSpecification requestSpec = RestAssured.given().body(inputStream).port(tomcat.getPort()); requestSpec.post(); this.thrown.expect(IllegalStateException.class); - this.thrown.expectMessage("Cannot read content from input stream " + inputStream - + " due to reset() failure"); + this.thrown.expectMessage("Cannot read content from input stream " + inputStream + " due to reset() failure"); this.factory.convert((FilterableRequestSpecification) requestSpec); } @Test public void multipartWithByteArrayInputStreamBody() { - RequestSpecification requestSpec = RestAssured.given().port(tomcat.getPort()) - .multiPart("foo", "foo.txt", new ByteArrayInputStream("foo".getBytes())); + RequestSpecification requestSpec = RestAssured.given().port(tomcat.getPort()).multiPart("foo", "foo.txt", + new ByteArrayInputStream("foo".getBytes())); requestSpec.post(); - OperationRequest request = this.factory - .convert((FilterableRequestSpecification) requestSpec); - assertThat(request.getParts().iterator().next().getContentAsString()) - .isEqualTo("foo"); + OperationRequest request = this.factory.convert((FilterableRequestSpecification) requestSpec); + assertThat(request.getParts().iterator().next().getContentAsString()).isEqualTo("foo"); } @Test public void multipartWithStringBody() { - RequestSpecification requestSpec = RestAssured.given().port(tomcat.getPort()) - .multiPart("control", "foo"); + RequestSpecification requestSpec = RestAssured.given().port(tomcat.getPort()).multiPart("control", "foo"); requestSpec.post(); - OperationRequest request = this.factory - .convert((FilterableRequestSpecification) requestSpec); - assertThat(request.getParts().iterator().next().getContentAsString()) - .isEqualTo("foo"); + OperationRequest request = this.factory.convert((FilterableRequestSpecification) requestSpec); + assertThat(request.getParts().iterator().next().getContentAsString()).isEqualTo("foo"); } @Test public void multipartWithByteArrayBody() { - RequestSpecification requestSpec = RestAssured.given().port(tomcat.getPort()) - .multiPart("control", "file", "foo".getBytes()); + RequestSpecification requestSpec = RestAssured.given().port(tomcat.getPort()).multiPart("control", "file", + "foo".getBytes()); requestSpec.post(); - OperationRequest request = this.factory - .convert((FilterableRequestSpecification) requestSpec); - assertThat(request.getParts().iterator().next().getContentAsString()) - .isEqualTo("foo"); + OperationRequest request = this.factory.convert((FilterableRequestSpecification) requestSpec); + assertThat(request.getParts().iterator().next().getContentAsString()).isEqualTo("foo"); } @Test @@ -293,39 +251,34 @@ public void multipartWithFileBody() { RequestSpecification requestSpec = RestAssured.given().port(tomcat.getPort()) .multiPart(new File("src/test/resources/body.txt")); requestSpec.post(); - OperationRequest request = this.factory - .convert((FilterableRequestSpecification) requestSpec); - assertThat(request.getParts().iterator().next().getContentAsString()) - .isEqualTo("file"); + OperationRequest request = this.factory.convert((FilterableRequestSpecification) requestSpec); + assertThat(request.getParts().iterator().next().getContentAsString()).isEqualTo("file"); } @Test public void multipartWithFileInputStreamBody() throws FileNotFoundException { FileInputStream inputStream = new FileInputStream("src/test/resources/body.txt"); - RequestSpecification requestSpec = RestAssured.given().port(tomcat.getPort()) - .multiPart("foo", "foo.txt", inputStream); + RequestSpecification requestSpec = RestAssured.given().port(tomcat.getPort()).multiPart("foo", "foo.txt", + inputStream); requestSpec.post(); this.thrown.expect(IllegalStateException.class); - this.thrown.expectMessage("Cannot read content from input stream " + inputStream - + " due to reset() failure"); + this.thrown.expectMessage("Cannot read content from input stream " + inputStream + " due to reset() failure"); this.factory.convert((FilterableRequestSpecification) requestSpec); } @Test public void multipartWithObjectBody() { - RequestSpecification requestSpec = RestAssured.given().port(tomcat.getPort()) - .multiPart("control", new ObjectBody("bar")); + RequestSpecification requestSpec = RestAssured.given().port(tomcat.getPort()).multiPart("control", + new ObjectBody("bar")); requestSpec.post(); - OperationRequest request = this.factory - .convert((FilterableRequestSpecification) requestSpec); - assertThat(request.getParts().iterator().next().getContentAsString()) - .isEqualTo("{\"foo\":\"bar\"}"); + OperationRequest request = this.factory.convert((FilterableRequestSpecification) requestSpec); + assertThat(request.getParts().iterator().next().getContentAsString()).isEqualTo("{\"foo\":\"bar\"}"); } /** * Sample object body to verify JSON serialization. */ - static class ObjectBody { + public static class ObjectBody { private final String foo; diff --git a/spring-restdocs-restassured/src/test/java/org/springframework/restdocs/restassured3/RestAssuredRestDocumentationConfigurerTests.java b/spring-restdocs-restassured/src/test/java/org/springframework/restdocs/restassured3/RestAssuredRestDocumentationConfigurerTests.java index f2edae550..bb42366bd 100644 --- a/spring-restdocs-restassured/src/test/java/org/springframework/restdocs/restassured3/RestAssuredRestDocumentationConfigurerTests.java +++ b/spring-restdocs-restassured/src/test/java/org/springframework/restdocs/restassured3/RestAssuredRestDocumentationConfigurerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-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. @@ -46,11 +46,9 @@ public class RestAssuredRestDocumentationConfigurerTests { @Rule public final JUnitRestDocumentation restDocumentation = new JUnitRestDocumentation(); - private final FilterableRequestSpecification requestSpec = mock( - FilterableRequestSpecification.class); + private final FilterableRequestSpecification requestSpec = mock(FilterableRequestSpecification.class); - private final FilterableResponseSpecification responseSpec = mock( - FilterableResponseSpecification.class); + private final FilterableResponseSpecification responseSpec = mock(FilterableResponseSpecification.class); private final FilterContext filterContext = mock(FilterContext.class); @@ -68,18 +66,14 @@ public void configurationIsAddedToTheContext() { this.configurer.filter(this.requestSpec, this.responseSpec, this.filterContext); @SuppressWarnings("rawtypes") ArgumentCaptor configurationCaptor = ArgumentCaptor.forClass(Map.class); - verify(this.filterContext).setValue( - eq(RestDocumentationFilter.CONTEXT_KEY_CONFIGURATION), + verify(this.filterContext).setValue(eq(RestDocumentationFilter.CONTEXT_KEY_CONFIGURATION), configurationCaptor.capture()); @SuppressWarnings("unchecked") Map configuration = configurationCaptor.getValue(); - assertThat(configuration.get(TemplateEngine.class.getName())) - .isInstanceOf(TemplateEngine.class); - assertThat(configuration.get(WriterResolver.class.getName())) - .isInstanceOf(WriterResolver.class); - assertThat(configuration - .get(RestDocumentationGenerator.ATTRIBUTE_NAME_DEFAULT_SNIPPETS)) - .isInstanceOf(List.class); + assertThat(configuration.get(TemplateEngine.class.getName())).isInstanceOf(TemplateEngine.class); + assertThat(configuration.get(WriterResolver.class.getName())).isInstanceOf(WriterResolver.class); + assertThat(configuration.get(RestDocumentationGenerator.ATTRIBUTE_NAME_DEFAULT_SNIPPETS)) + .isInstanceOf(List.class); } } diff --git a/spring-restdocs-restassured/src/test/java/org/springframework/restdocs/restassured3/RestAssuredRestDocumentationIntegrationTests.java b/spring-restdocs-restassured/src/test/java/org/springframework/restdocs/restassured3/RestAssuredRestDocumentationIntegrationTests.java index cd1f124fe..fc91a2e7a 100644 --- a/spring-restdocs-restassured/src/test/java/org/springframework/restdocs/restassured3/RestAssuredRestDocumentationIntegrationTests.java +++ b/spring-restdocs-restassured/src/test/java/org/springframework/restdocs/restassured3/RestAssuredRestDocumentationIntegrationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-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. @@ -87,156 +87,113 @@ public class RestAssuredRestDocumentationIntegrationTests { @Test public void defaultSnippetGeneration() { - given().port(tomcat.getPort()) - .filter(documentationConfiguration(this.restDocumentation)) + given().port(tomcat.getPort()).filter(documentationConfiguration(this.restDocumentation)) .filter(document("default")).get("/").then().statusCode(200); - assertExpectedSnippetFilesExist(new File("build/generated-snippets/default"), - "http-request.adoc", "http-response.adoc", "curl-request.adoc"); + assertExpectedSnippetFilesExist(new File("build/generated-snippets/default"), "http-request.adoc", + "http-response.adoc", "curl-request.adoc"); } @Test public void curlSnippetWithContent() throws Exception { String contentType = "text/plain; charset=UTF-8"; - given().port(tomcat.getPort()) - .filter(documentationConfiguration(this.restDocumentation)) - .filter(document("curl-snippet-with-content")).accept("application/json") - .body("content").contentType(contentType).post("/").then() - .statusCode(200); - - assertThat(new File( - "build/generated-snippets/curl-snippet-with-content/curl-request.adoc")) - .has(content(codeBlock(TemplateFormats.asciidoctor(), "bash") - .withContent(String.format("$ curl 'http://localhost:" - + tomcat.getPort() + "/' -i -X POST \\%n" - + " -H 'Accept: application/json' \\%n" - + " -H 'Content-Type: " + contentType - + "' \\%n" + " -d 'content'")))); + given().port(tomcat.getPort()).filter(documentationConfiguration(this.restDocumentation)) + .filter(document("curl-snippet-with-content")).accept("application/json").body("content") + .contentType(contentType).post("/").then().statusCode(200); + + assertThat(new File("build/generated-snippets/curl-snippet-with-content/curl-request.adoc")).has(content( + codeBlock(TemplateFormats.asciidoctor(), "bash").withContent(String.format("$ curl 'http://localhost:" + + tomcat.getPort() + "/' -i -X POST \\%n" + " -H 'Accept: application/json' \\%n" + + " -H 'Content-Type: " + contentType + "' \\%n" + " -d 'content'")))); } @Test public void curlSnippetWithCookies() throws Exception { String contentType = "text/plain; charset=UTF-8"; - given().port(tomcat.getPort()) - .filter(documentationConfiguration(this.restDocumentation)) - .filter(document("curl-snippet-with-cookies")).accept("application/json") - .contentType(contentType).cookie("cookieName", "cookieVal").get("/") - .then().statusCode(200); - assertThat(new File( - "build/generated-snippets/curl-snippet-with-cookies/curl-request.adoc")) - .has(content(codeBlock(TemplateFormats.asciidoctor(), "bash") - .withContent(String.format("$ curl 'http://localhost:" - + tomcat.getPort() + "/' -i -X GET \\%n" - + " -H 'Accept: application/json' \\%n" - + " -H 'Content-Type: " + contentType - + "' \\%n" - + " --cookie 'cookieName=cookieVal'")))); + given().port(tomcat.getPort()).filter(documentationConfiguration(this.restDocumentation)) + .filter(document("curl-snippet-with-cookies")).accept("application/json").contentType(contentType) + .cookie("cookieName", "cookieVal").get("/").then().statusCode(200); + assertThat(new File("build/generated-snippets/curl-snippet-with-cookies/curl-request.adoc")).has(content( + codeBlock(TemplateFormats.asciidoctor(), "bash").withContent(String.format("$ curl 'http://localhost:" + + tomcat.getPort() + "/' -i -X GET \\%n" + " -H 'Accept: application/json' \\%n" + + " -H 'Content-Type: " + contentType + "' \\%n" + " --cookie 'cookieName=cookieVal'")))); } @Test public void curlSnippetWithQueryStringOnPost() throws Exception { - given().port(tomcat.getPort()) - .filter(documentationConfiguration(this.restDocumentation)) - .filter(document("curl-snippet-with-query-string")) - .accept("application/json").param("foo", "bar").param("a", "alpha") - .post("/?foo=bar").then().statusCode(200); + given().port(tomcat.getPort()).filter(documentationConfiguration(this.restDocumentation)) + .filter(document("curl-snippet-with-query-string")).accept("application/json").param("foo", "bar") + .param("a", "alpha").post("/?foo=bar").then().statusCode(200); String contentType = "application/x-www-form-urlencoded; charset=ISO-8859-1"; - assertThat(new File( - "build/generated-snippets/curl-snippet-with-query-string/curl-request.adoc")) - .has(content(codeBlock(TemplateFormats.asciidoctor(), "bash") - .withContent(String.format("$ curl " - + "'http://localhost:" + tomcat.getPort() - + "/?foo=bar' -i -X POST \\%n" - + " -H 'Accept: application/json' \\%n" - + " -H 'Content-Type: " + contentType - + "' \\%n" + " -d 'a=alpha'")))); + assertThat(new File("build/generated-snippets/curl-snippet-with-query-string/curl-request.adoc")) + .has(content(codeBlock(TemplateFormats.asciidoctor(), "bash") + .withContent(String.format("$ curl " + "'http://localhost:" + tomcat.getPort() + + "/?foo=bar' -i -X POST \\%n" + " -H 'Accept: application/json' \\%n" + + " -H 'Content-Type: " + contentType + "' \\%n" + " -d 'a=alpha'")))); } @Test public void linksSnippet() throws Exception { - given().port(tomcat.getPort()) - .filter(documentationConfiguration(this.restDocumentation)) - .filter(document("links", - links(linkWithRel("rel").description("The description")))) + given().port(tomcat.getPort()).filter(documentationConfiguration(this.restDocumentation)) + .filter(document("links", links(linkWithRel("rel").description("The description")))) .accept("application/json").get("/").then().statusCode(200); - assertExpectedSnippetFilesExist(new File("build/generated-snippets/links"), - "http-request.adoc", "http-response.adoc", "curl-request.adoc", - "links.adoc"); + assertExpectedSnippetFilesExist(new File("build/generated-snippets/links"), "http-request.adoc", + "http-response.adoc", "curl-request.adoc", "links.adoc"); } @Test public void pathParametersSnippet() throws Exception { - given().port(tomcat.getPort()) - .filter(documentationConfiguration(this.restDocumentation)) + given().port(tomcat.getPort()).filter(documentationConfiguration(this.restDocumentation)) .filter(document("path-parameters", - pathParameters( - parameterWithName("foo").description("The description")))) + pathParameters(parameterWithName("foo").description("The description")))) .accept("application/json").get("/{foo}", "").then().statusCode(200); - assertExpectedSnippetFilesExist( - new File("build/generated-snippets/path-parameters"), "http-request.adoc", + assertExpectedSnippetFilesExist(new File("build/generated-snippets/path-parameters"), "http-request.adoc", "http-response.adoc", "curl-request.adoc", "path-parameters.adoc"); } @Test public void requestParametersSnippet() throws Exception { - given().port(tomcat.getPort()) - .filter(documentationConfiguration(this.restDocumentation)) + given().port(tomcat.getPort()).filter(documentationConfiguration(this.restDocumentation)) .filter(document("request-parameters", - requestParameters( - parameterWithName("foo").description("The description")))) - .accept("application/json").param("foo", "bar").get("/").then() - .statusCode(200); - assertExpectedSnippetFilesExist( - new File("build/generated-snippets/request-parameters"), - "http-request.adoc", "http-response.adoc", "curl-request.adoc", - "request-parameters.adoc"); + requestParameters(parameterWithName("foo").description("The description")))) + .accept("application/json").param("foo", "bar").get("/").then().statusCode(200); + assertExpectedSnippetFilesExist(new File("build/generated-snippets/request-parameters"), "http-request.adoc", + "http-response.adoc", "curl-request.adoc", "request-parameters.adoc"); } @Test public void requestFieldsSnippet() throws Exception { - given().port(tomcat.getPort()) - .filter(documentationConfiguration(this.restDocumentation)) - .filter(document("request-fields", - requestFields(fieldWithPath("a").description("The description")))) - .accept("application/json").body("{\"a\":\"alpha\"}").post("/").then() - .statusCode(200); - assertExpectedSnippetFilesExist( - new File("build/generated-snippets/request-fields"), "http-request.adoc", + given().port(tomcat.getPort()).filter(documentationConfiguration(this.restDocumentation)) + .filter(document("request-fields", requestFields(fieldWithPath("a").description("The description")))) + .accept("application/json").body("{\"a\":\"alpha\"}").post("/").then().statusCode(200); + assertExpectedSnippetFilesExist(new File("build/generated-snippets/request-fields"), "http-request.adoc", "http-response.adoc", "curl-request.adoc", "request-fields.adoc"); } @Test public void requestPartsSnippet() throws Exception { - given().port(tomcat.getPort()) - .filter(documentationConfiguration(this.restDocumentation)) - .filter(document("request-parts", - requestParts(partWithName("a").description("The description")))) + given().port(tomcat.getPort()).filter(documentationConfiguration(this.restDocumentation)) + .filter(document("request-parts", requestParts(partWithName("a").description("The description")))) .multiPart("a", "foo").post("/upload").then().statusCode(200); - assertExpectedSnippetFilesExist( - new File("build/generated-snippets/request-parts"), "http-request.adoc", + assertExpectedSnippetFilesExist(new File("build/generated-snippets/request-parts"), "http-request.adoc", "http-response.adoc", "curl-request.adoc", "request-parts.adoc"); } @Test public void responseFieldsSnippet() throws Exception { - given().port(tomcat.getPort()) - .filter(documentationConfiguration(this.restDocumentation)) + given().port(tomcat.getPort()).filter(documentationConfiguration(this.restDocumentation)) .filter(document("response-fields", responseFields(fieldWithPath("a").description("The description"), - subsectionWithPath("links") - .description("Links to other resources")))) + subsectionWithPath("links").description("Links to other resources")))) .accept("application/json").get("/").then().statusCode(200); - assertExpectedSnippetFilesExist( - new File("build/generated-snippets/response-fields"), "http-request.adoc", + assertExpectedSnippetFilesExist(new File("build/generated-snippets/response-fields"), "http-request.adoc", "http-response.adoc", "curl-request.adoc", "response-fields.adoc"); } @Test public void parameterizedOutputDirectory() throws Exception { - given().port(tomcat.getPort()) - .filter(documentationConfiguration(this.restDocumentation)) + given().port(tomcat.getPort()).filter(documentationConfiguration(this.restDocumentation)) .filter(document("{method-name}")).get("/").then().statusCode(200); - assertExpectedSnippetFilesExist( - new File("build/generated-snippets/parameterized-output-directory"), + assertExpectedSnippetFilesExist(new File("build/generated-snippets/parameterized-output-directory"), "http-request.adoc", "http-response.adoc", "curl-request.adoc"); } @@ -246,16 +203,13 @@ public void multiStep() throws Exception { .addFilter(documentationConfiguration(this.restDocumentation)) .addFilter(document("{method-name}-{step}")).build(); given(spec).get("/").then().statusCode(200); - assertExpectedSnippetFilesExist( - new File("build/generated-snippets/multi-step-1/"), "http-request.adoc", + assertExpectedSnippetFilesExist(new File("build/generated-snippets/multi-step-1/"), "http-request.adoc", "http-response.adoc", "curl-request.adoc"); given(spec).get("/").then().statusCode(200); - assertExpectedSnippetFilesExist( - new File("build/generated-snippets/multi-step-2/"), "http-request.adoc", + assertExpectedSnippetFilesExist(new File("build/generated-snippets/multi-step-2/"), "http-request.adoc", "http-response.adoc", "curl-request.adoc"); given(spec).get("/").then().statusCode(200); - assertExpectedSnippetFilesExist( - new File("build/generated-snippets/multi-step-3/"), "http-request.adoc", + assertExpectedSnippetFilesExist(new File("build/generated-snippets/multi-step-3/"), "http-request.adoc", "http-response.adoc", "curl-request.adoc"); } @@ -263,118 +217,88 @@ public void multiStep() throws Exception { public void additionalSnippets() throws Exception { RestDocumentationFilter documentation = document("{method-name}-{step}"); RequestSpecification spec = new RequestSpecBuilder().setPort(tomcat.getPort()) - .addFilter(documentationConfiguration(this.restDocumentation)) - .addFilter(documentation).build(); - given(spec) - .filter(documentation - .document(responseHeaders(headerWithName("a").description("one"), - headerWithName("Foo").description("two")))) + .addFilter(documentationConfiguration(this.restDocumentation)).addFilter(documentation).build(); + given(spec).filter(documentation.document( + responseHeaders(headerWithName("a").description("one"), headerWithName("Foo").description("two")))) .get("/").then().statusCode(200); - assertExpectedSnippetFilesExist( - new File("build/generated-snippets/additional-snippets-1/"), - "http-request.adoc", "http-response.adoc", "curl-request.adoc", - "response-headers.adoc"); + assertExpectedSnippetFilesExist(new File("build/generated-snippets/additional-snippets-1/"), + "http-request.adoc", "http-response.adoc", "curl-request.adoc", "response-headers.adoc"); } @Test public void responseWithCookie() { - given().port(tomcat.getPort()) - .filter(documentationConfiguration(this.restDocumentation)) + given().port(tomcat.getPort()).filter(documentationConfiguration(this.restDocumentation)) .filter(document("set-cookie", - preprocessResponse(removeHeaders(HttpHeaders.DATE, - HttpHeaders.CONTENT_TYPE)))) + preprocessResponse(removeHeaders(HttpHeaders.DATE, HttpHeaders.CONTENT_TYPE)))) .get("/set-cookie").then().statusCode(200); - assertExpectedSnippetFilesExist(new File("build/generated-snippets/set-cookie"), - "http-request.adoc", "http-response.adoc", "curl-request.adoc"); + assertExpectedSnippetFilesExist(new File("build/generated-snippets/set-cookie"), "http-request.adoc", + "http-response.adoc", "curl-request.adoc"); assertThat(new File("build/generated-snippets/set-cookie/http-response.adoc")) - .has(content(httpResponse(TemplateFormats.asciidoctor(), HttpStatus.OK) - .header(HttpHeaders.SET_COOKIE, - "name=value; Domain=localhost; HttpOnly"))); + .has(content(httpResponse(TemplateFormats.asciidoctor(), HttpStatus.OK).header(HttpHeaders.SET_COOKIE, + "name=value; Domain=localhost; HttpOnly"))); } @Test public void preprocessedRequest() throws Exception { Pattern pattern = Pattern.compile("(\"alpha\")"); - given().port(tomcat.getPort()) - .filter(documentationConfiguration(this.restDocumentation)) - .header("a", "alpha").header("b", "bravo").contentType("application/json") - .accept("application/json").body("{\"a\":\"alpha\"}") - .filter(document("original-request")) + given().port(tomcat.getPort()).filter(documentationConfiguration(this.restDocumentation)).header("a", "alpha") + .header("b", "bravo").contentType("application/json").accept("application/json") + .body("{\"a\":\"alpha\"}").filter(document("original-request")) .filter(document("preprocessed-request", - preprocessRequest(prettyPrint(), - replacePattern(pattern, "\"<>\""), - modifyUris().removePort(), - removeHeaders("a", HttpHeaders.CONTENT_LENGTH)))) + preprocessRequest(prettyPrint(), replacePattern(pattern, "\"<>\""), + modifyUris().removePort(), removeHeaders("a", HttpHeaders.CONTENT_LENGTH)))) .get("/").then().statusCode(200); - assertThat( - new File("build/generated-snippets/original-request/http-request.adoc")) - .has(content(httpRequest(TemplateFormats.asciidoctor(), - RequestMethod.GET, "/").header("a", "alpha") - .header("b", "bravo") - .header("Accept", - MediaType.APPLICATION_JSON_VALUE) - .header("Content-Type", - "application/json; charset=UTF-8") - .header("Host", "localhost:" + tomcat.getPort()) - .header("Content-Length", "13") - .content("{\"a\":\"alpha\"}"))); + assertThat(new File("build/generated-snippets/original-request/http-request.adoc")) + .has(content(httpRequest(TemplateFormats.asciidoctor(), RequestMethod.GET, "/").header("a", "alpha") + .header("b", "bravo").header("Accept", MediaType.APPLICATION_JSON_VALUE) + .header("Content-Type", "application/json; charset=UTF-8") + .header("Host", "localhost:" + tomcat.getPort()).header("Content-Length", "13") + .content("{\"a\":\"alpha\"}"))); String prettyPrinted = String.format("{%n \"a\" : \"<>\"%n}"); - assertThat(new File( - "build/generated-snippets/preprocessed-request/http-request.adoc")) - .has(content(httpRequest(TemplateFormats.asciidoctor(), - RequestMethod.GET, "/") - .header("b", "bravo") - .header("Accept", - MediaType.APPLICATION_JSON_VALUE) - .header("Content-Type", - "application/json; charset=UTF-8") - .header("Host", "localhost") - .content(prettyPrinted))); + assertThat(new File("build/generated-snippets/preprocessed-request/http-request.adoc")) + .has(content(httpRequest(TemplateFormats.asciidoctor(), RequestMethod.GET, "/").header("b", "bravo") + .header("Accept", MediaType.APPLICATION_JSON_VALUE) + .header("Content-Type", "application/json; charset=UTF-8").header("Host", "localhost") + .content(prettyPrinted))); } @Test public void preprocessedResponse() throws Exception { Pattern pattern = Pattern.compile("(\"alpha\")"); - given().port(tomcat.getPort()) - .filter(documentationConfiguration(this.restDocumentation)) + given().port(tomcat.getPort()).filter(documentationConfiguration(this.restDocumentation)) .filter(document("original-response")) - .filter(document("preprocessed-response", preprocessResponse( - prettyPrint(), maskLinks(), - removeHeaders("a", "Transfer-Encoding", "Date", "Server"), - replacePattern(pattern, "\"<>\""), modifyUris() - .scheme("https").host("api.example.com").removePort()))) + .filter(document("preprocessed-response", + preprocessResponse(prettyPrint(), maskLinks(), + removeHeaders("a", "Transfer-Encoding", "Date", "Server"), + replacePattern(pattern, "\"<>\""), + modifyUris().scheme("https").host("api.example.com").removePort()))) .get("/").then().statusCode(200); String prettyPrinted = String.format("{%n \"a\" : \"<>\",%n \"links\" : " + "[ {%n \"rel\" : \"rel\",%n \"href\" : \"...\"%n } ]%n}"); - assertThat(new File( - "build/generated-snippets/preprocessed-response/http-response.adoc")).has( - content(httpResponse(TemplateFormats.asciidoctor(), HttpStatus.OK) - .header("Foo", "https://api.example.com/foo/bar") - .header("Content-Type", "application/json;charset=UTF-8") - .header(HttpHeaders.CONTENT_LENGTH, - prettyPrinted.getBytes().length) - .content(prettyPrinted))); + assertThat(new File("build/generated-snippets/preprocessed-response/http-response.adoc")) + .has(content(httpResponse(TemplateFormats.asciidoctor(), HttpStatus.OK) + .header("Foo", "https://api.example.com/foo/bar") + .header("Content-Type", "application/json;charset=UTF-8") + .header(HttpHeaders.CONTENT_LENGTH, prettyPrinted.getBytes().length).content(prettyPrinted))); } @Test public void customSnippetTemplate() throws Exception { - ClassLoader classLoader = new URLClassLoader(new URL[] { - new File("src/test/resources/custom-snippet-templates").toURI().toURL() }, + ClassLoader classLoader = new URLClassLoader( + new URL[] { new File("src/test/resources/custom-snippet-templates").toURI().toURL() }, getClass().getClassLoader()); ClassLoader previous = Thread.currentThread().getContextClassLoader(); Thread.currentThread().setContextClassLoader(classLoader); try { given().port(tomcat.getPort()).accept("application/json") .filter(documentationConfiguration(this.restDocumentation)) - .filter(document("custom-snippet-template")).get("/").then() - .statusCode(200); + .filter(document("custom-snippet-template")).get("/").then().statusCode(200); } finally { Thread.currentThread().setContextClassLoader(previous); } - assertThat(new File( - "build/generated-snippets/custom-snippet-template/curl-request.adoc")) - .hasContent("Custom curl request"); + assertThat(new File("build/generated-snippets/custom-snippet-template/curl-request.adoc")) + .hasContent("Custom curl request"); } private void assertExpectedSnippetFilesExist(File directory, String... snippets) { @@ -389,9 +313,8 @@ private Condition content(final Condition delegate) { @Override public boolean matches(File value) { try { - return delegate - .matches(FileCopyUtils.copyToString(new InputStreamReader( - new FileInputStream(value), StandardCharsets.UTF_8))); + return delegate.matches(FileCopyUtils + .copyToString(new InputStreamReader(new FileInputStream(value), StandardCharsets.UTF_8))); } catch (IOException ex) { fail("Failed to read '" + value + "'", ex); @@ -406,8 +329,7 @@ private CodeBlockCondition codeBlock(TemplateFormat format, String language) return SnippetConditions.codeBlock(format, language); } - private HttpRequestCondition httpRequest(TemplateFormat format, - RequestMethod requestMethod, String uri) { + private HttpRequestCondition httpRequest(TemplateFormat format, RequestMethod requestMethod, String uri) { return SnippetConditions.httpRequest(format, requestMethod, uri); } diff --git a/spring-restdocs-restassured/src/test/java/org/springframework/restdocs/restassured3/TomcatServer.java b/spring-restdocs-restassured/src/test/java/org/springframework/restdocs/restassured3/TomcatServer.java index b4d3925b0..3f252bd35 100644 --- a/spring-restdocs-restassured/src/test/java/org/springframework/restdocs/restassured3/TomcatServer.java +++ b/spring-restdocs-restassured/src/test/java/org/springframework/restdocs/restassured3/TomcatServer.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2017 the original author or authors. + * Copyright 2014-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. @@ -89,8 +89,7 @@ protected void doPost(HttpServletRequest request, HttpServletResponse response) respondWithJson(response); } - private void respondWithJson(HttpServletResponse response) - throws IOException, JsonProcessingException { + private void respondWithJson(HttpServletResponse response) throws IOException, JsonProcessingException { response.setCharacterEncoding("UTF-8"); response.setContentType("application/json"); Map content = new HashMap<>(); @@ -113,8 +112,7 @@ private void respondWithJson(HttpServletResponse response) private static final class CookiesServlet extends HttpServlet { @Override - protected void doGet(HttpServletRequest req, HttpServletResponse resp) - throws ServletException, IOException { + protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { Cookie cookie = new Cookie("name", "value"); cookie.setDomain("localhost"); cookie.setHttpOnly(true); diff --git a/spring-restdocs-restassured/src/test/java/org/springframework/restdocs/restassured3/operation/preprocess/UriModifyingOperationPreprocessorTests.java b/spring-restdocs-restassured/src/test/java/org/springframework/restdocs/restassured3/operation/preprocess/UriModifyingOperationPreprocessorTests.java index efcefd5a3..a7fb542f0 100644 --- a/spring-restdocs-restassured/src/test/java/org/springframework/restdocs/restassured3/operation/preprocess/UriModifyingOperationPreprocessorTests.java +++ b/spring-restdocs-restassured/src/test/java/org/springframework/restdocs/restassured3/operation/preprocess/UriModifyingOperationPreprocessorTests.java @@ -53,20 +53,16 @@ public class UriModifyingOperationPreprocessorTests { @Test public void requestUriSchemeCanBeModified() { this.preprocessor.scheme("https"); - OperationRequest processed = this.preprocessor - .preprocess(createRequestWithUri("http://localhost:12345")); + OperationRequest processed = this.preprocessor.preprocess(createRequestWithUri("http://localhost:12345")); assertThat(processed.getUri()).isEqualTo(URI.create("https://localhost:12345")); } @Test public void requestUriHostCanBeModified() { this.preprocessor.host("api.example.com"); - OperationRequest processed = this.preprocessor - .preprocess(createRequestWithUri("https://api.foo.com:12345")); - assertThat(processed.getUri()) - .isEqualTo(URI.create("https://api.example.com:12345")); - assertThat(processed.getHeaders().getFirst(HttpHeaders.HOST)) - .isEqualTo("api.example.com:12345"); + OperationRequest processed = this.preprocessor.preprocess(createRequestWithUri("https://api.foo.com:12345")); + assertThat(processed.getUri()).isEqualTo(URI.create("https://api.example.com:12345")); + assertThat(processed.getHeaders().getFirst(HttpHeaders.HOST)).isEqualTo("api.example.com:12345"); } @Test @@ -74,10 +70,8 @@ public void requestUriPortCanBeModified() { this.preprocessor.port(23456); OperationRequest processed = this.preprocessor .preprocess(createRequestWithUri("https://api.example.com:12345")); - assertThat(processed.getUri()) - .isEqualTo(URI.create("https://api.example.com:23456")); - assertThat(processed.getHeaders().getFirst(HttpHeaders.HOST)) - .isEqualTo("api.example.com:23456"); + assertThat(processed.getUri()).isEqualTo(URI.create("https://api.example.com:23456")); + assertThat(processed.getHeaders().getFirst(HttpHeaders.HOST)).isEqualTo("api.example.com:23456"); } @Test @@ -86,26 +80,23 @@ public void requestUriPortCanBeRemoved() { OperationRequest processed = this.preprocessor .preprocess(createRequestWithUri("https://api.example.com:12345")); assertThat(processed.getUri()).isEqualTo(URI.create("https://api.example.com")); - assertThat(processed.getHeaders().getFirst(HttpHeaders.HOST)) - .isEqualTo("api.example.com"); + assertThat(processed.getHeaders().getFirst(HttpHeaders.HOST)).isEqualTo("api.example.com"); } @Test public void requestUriPathIsPreserved() { this.preprocessor.removePort(); - OperationRequest processed = this.preprocessor.preprocess( - createRequestWithUri("https://api.example.com:12345/foo/bar")); - assertThat(processed.getUri()) - .isEqualTo(URI.create("https://api.example.com/foo/bar")); + OperationRequest processed = this.preprocessor + .preprocess(createRequestWithUri("https://api.example.com:12345/foo/bar")); + assertThat(processed.getUri()).isEqualTo(URI.create("https://api.example.com/foo/bar")); } @Test public void requestUriQueryIsPreserved() { this.preprocessor.removePort(); - OperationRequest processed = this.preprocessor.preprocess( - createRequestWithUri("https://api.example.com:12345?foo=bar")); - assertThat(processed.getUri()) - .isEqualTo(URI.create("https://api.example.com?foo=bar")); + OperationRequest processed = this.preprocessor + .preprocess(createRequestWithUri("https://api.example.com:12345?foo=bar")); + assertThat(processed.getUri()).isEqualTo(URI.create("https://api.example.com?foo=bar")); } @Test @@ -113,26 +104,22 @@ public void requestUriAnchorIsPreserved() { this.preprocessor.removePort(); OperationRequest processed = this.preprocessor .preprocess(createRequestWithUri("https://api.example.com:12345#foo")); - assertThat(processed.getUri()) - .isEqualTo(URI.create("https://api.example.com#foo")); + assertThat(processed.getUri()).isEqualTo(URI.create("https://api.example.com#foo")); } @Test public void requestContentUriSchemeCanBeModified() { this.preprocessor.scheme("https"); OperationRequest processed = this.preprocessor - .preprocess(createRequestWithContent( - "The uri 'http://localhost:12345' should be used")); - assertThat(new String(processed.getContent())) - .isEqualTo("The uri 'https://localhost:12345' should be used"); + .preprocess(createRequestWithContent("The uri 'http://localhost:12345' should be used")); + assertThat(new String(processed.getContent())).isEqualTo("The uri 'https://localhost:12345' should be used"); } @Test public void requestContentUriHostCanBeModified() { this.preprocessor.host("api.example.com"); OperationRequest processed = this.preprocessor - .preprocess(createRequestWithContent( - "The uri 'https://localhost:12345' should be used")); + .preprocess(createRequestWithContent("The uri 'https://localhost:12345' should be used")); assertThat(new String(processed.getContent())) .isEqualTo("The uri 'https://api.example.com:12345' should be used"); } @@ -141,78 +128,64 @@ public void requestContentUriHostCanBeModified() { public void requestContentUriPortCanBeModified() { this.preprocessor.port(23456); OperationRequest processed = this.preprocessor - .preprocess(createRequestWithContent( - "The uri 'http://localhost:12345' should be used")); - assertThat(new String(processed.getContent())) - .isEqualTo("The uri 'http://localhost:23456' should be used"); + .preprocess(createRequestWithContent("The uri 'http://localhost:12345' should be used")); + assertThat(new String(processed.getContent())).isEqualTo("The uri 'http://localhost:23456' should be used"); } @Test public void requestContentUriPortCanBeRemoved() { this.preprocessor.removePort(); OperationRequest processed = this.preprocessor - .preprocess(createRequestWithContent( - "The uri 'http://localhost:12345' should be used")); - assertThat(new String(processed.getContent())) - .isEqualTo("The uri 'http://localhost' should be used"); + .preprocess(createRequestWithContent("The uri 'http://localhost:12345' should be used")); + assertThat(new String(processed.getContent())).isEqualTo("The uri 'http://localhost' should be used"); } @Test public void multipleRequestContentUrisCanBeModified() { this.preprocessor.removePort(); - OperationRequest processed = this.preprocessor - .preprocess(createRequestWithContent( - "Use 'http://localhost:12345' or 'https://localhost:23456' to access the service")); - assertThat(new String(processed.getContent())).isEqualTo( - "Use 'http://localhost' or 'https://localhost' to access the service"); + OperationRequest processed = this.preprocessor.preprocess(createRequestWithContent( + "Use 'http://localhost:12345' or 'https://localhost:23456' to access the service")); + assertThat(new String(processed.getContent())) + .isEqualTo("Use 'http://localhost' or 'https://localhost' to access the service"); } @Test public void requestContentUriPathIsPreserved() { this.preprocessor.removePort(); OperationRequest processed = this.preprocessor - .preprocess(createRequestWithContent( - "The uri 'http://localhost:12345/foo/bar' should be used")); - assertThat(new String(processed.getContent())) - .isEqualTo("The uri 'http://localhost/foo/bar' should be used"); + .preprocess(createRequestWithContent("The uri 'http://localhost:12345/foo/bar' should be used")); + assertThat(new String(processed.getContent())).isEqualTo("The uri 'http://localhost/foo/bar' should be used"); } @Test public void requestContentUriQueryIsPreserved() { this.preprocessor.removePort(); OperationRequest processed = this.preprocessor - .preprocess(createRequestWithContent( - "The uri 'http://localhost:12345?foo=bar' should be used")); - assertThat(new String(processed.getContent())) - .isEqualTo("The uri 'http://localhost?foo=bar' should be used"); + .preprocess(createRequestWithContent("The uri 'http://localhost:12345?foo=bar' should be used")); + assertThat(new String(processed.getContent())).isEqualTo("The uri 'http://localhost?foo=bar' should be used"); } @Test public void requestContentUriAnchorIsPreserved() { this.preprocessor.removePort(); OperationRequest processed = this.preprocessor - .preprocess(createRequestWithContent( - "The uri 'http://localhost:12345#foo' should be used")); - assertThat(new String(processed.getContent())) - .isEqualTo("The uri 'http://localhost#foo' should be used"); + .preprocess(createRequestWithContent("The uri 'http://localhost:12345#foo' should be used")); + assertThat(new String(processed.getContent())).isEqualTo("The uri 'http://localhost#foo' should be used"); } @Test public void responseContentUriSchemeCanBeModified() { this.preprocessor.scheme("https"); OperationResponse processed = this.preprocessor - .preprocess(createResponseWithContent( - "The uri 'http://localhost:12345' should be used")); - assertThat(new String(processed.getContent())) - .isEqualTo("The uri 'https://localhost:12345' should be used"); + .preprocess(createResponseWithContent("The uri 'http://localhost:12345' should be used")); + assertThat(new String(processed.getContent())).isEqualTo("The uri 'https://localhost:12345' should be used"); } @Test public void responseContentUriHostCanBeModified() { this.preprocessor.host("api.example.com"); OperationResponse processed = this.preprocessor - .preprocess(createResponseWithContent( - "The uri 'https://localhost:12345' should be used")); + .preprocess(createResponseWithContent("The uri 'https://localhost:12345' should be used")); assertThat(new String(processed.getContent())) .isEqualTo("The uri 'https://api.example.com:12345' should be used"); } @@ -221,68 +194,56 @@ public void responseContentUriHostCanBeModified() { public void responseContentUriPortCanBeModified() { this.preprocessor.port(23456); OperationResponse processed = this.preprocessor - .preprocess(createResponseWithContent( - "The uri 'http://localhost:12345' should be used")); - assertThat(new String(processed.getContent())) - .isEqualTo("The uri 'http://localhost:23456' should be used"); + .preprocess(createResponseWithContent("The uri 'http://localhost:12345' should be used")); + assertThat(new String(processed.getContent())).isEqualTo("The uri 'http://localhost:23456' should be used"); } @Test public void responseContentUriPortCanBeRemoved() { this.preprocessor.removePort(); OperationResponse processed = this.preprocessor - .preprocess(createResponseWithContent( - "The uri 'http://localhost:12345' should be used")); - assertThat(new String(processed.getContent())) - .isEqualTo("The uri 'http://localhost' should be used"); + .preprocess(createResponseWithContent("The uri 'http://localhost:12345' should be used")); + assertThat(new String(processed.getContent())).isEqualTo("The uri 'http://localhost' should be used"); } @Test public void multipleResponseContentUrisCanBeModified() { this.preprocessor.removePort(); - OperationResponse processed = this.preprocessor - .preprocess(createResponseWithContent( - "Use 'http://localhost:12345' or 'https://localhost:23456' to access the service")); - assertThat(new String(processed.getContent())).isEqualTo( - "Use 'http://localhost' or 'https://localhost' to access the service"); + OperationResponse processed = this.preprocessor.preprocess(createResponseWithContent( + "Use 'http://localhost:12345' or 'https://localhost:23456' to access the service")); + assertThat(new String(processed.getContent())) + .isEqualTo("Use 'http://localhost' or 'https://localhost' to access the service"); } @Test public void responseContentUriPathIsPreserved() { this.preprocessor.removePort(); OperationResponse processed = this.preprocessor - .preprocess(createResponseWithContent( - "The uri 'http://localhost:12345/foo/bar' should be used")); - assertThat(new String(processed.getContent())) - .isEqualTo("The uri 'http://localhost/foo/bar' should be used"); + .preprocess(createResponseWithContent("The uri 'http://localhost:12345/foo/bar' should be used")); + assertThat(new String(processed.getContent())).isEqualTo("The uri 'http://localhost/foo/bar' should be used"); } @Test public void responseContentUriQueryIsPreserved() { this.preprocessor.removePort(); OperationResponse processed = this.preprocessor - .preprocess(createResponseWithContent( - "The uri 'http://localhost:12345?foo=bar' should be used")); - assertThat(new String(processed.getContent())) - .isEqualTo("The uri 'http://localhost?foo=bar' should be used"); + .preprocess(createResponseWithContent("The uri 'http://localhost:12345?foo=bar' should be used")); + assertThat(new String(processed.getContent())).isEqualTo("The uri 'http://localhost?foo=bar' should be used"); } @Test public void responseContentUriAnchorIsPreserved() { this.preprocessor.removePort(); OperationResponse processed = this.preprocessor - .preprocess(createResponseWithContent( - "The uri 'http://localhost:12345#foo' should be used")); - assertThat(new String(processed.getContent())) - .isEqualTo("The uri 'http://localhost#foo' should be used"); + .preprocess(createResponseWithContent("The uri 'http://localhost:12345#foo' should be used")); + assertThat(new String(processed.getContent())).isEqualTo("The uri 'http://localhost#foo' should be used"); } @Test public void urisInRequestHeadersCanBeModified() { OperationRequest processed = this.preprocessor.host("api.example.com") .preprocess(createRequestWithHeader("Foo", "https://locahost:12345")); - assertThat(processed.getHeaders().getFirst("Foo")) - .isEqualTo("https://api.example.com:12345"); + assertThat(processed.getHeaders().getFirst("Foo")).isEqualTo("https://api.example.com:12345"); assertThat(processed.getHeaders().getFirst("Host")).isEqualTo("api.example.com"); } @@ -290,14 +251,13 @@ public void urisInRequestHeadersCanBeModified() { public void urisInResponseHeadersCanBeModified() { OperationResponse processed = this.preprocessor.host("api.example.com") .preprocess(createResponseWithHeader("Foo", "https://locahost:12345")); - assertThat(processed.getHeaders().getFirst("Foo")) - .isEqualTo("https://api.example.com:12345"); + assertThat(processed.getHeaders().getFirst("Foo")).isEqualTo("https://api.example.com:12345"); } @Test public void urisInRequestPartHeadersCanBeModified() { - OperationRequest processed = this.preprocessor.host("api.example.com").preprocess( - createRequestWithPartWithHeader("Foo", "https://locahost:12345")); + OperationRequest processed = this.preprocessor.host("api.example.com") + .preprocess(createRequestWithPartWithHeader("Foo", "https://locahost:12345")); assertThat(processed.getParts().iterator().next().getHeaders().getFirst("Foo")) .isEqualTo("https://api.example.com:12345"); } @@ -305,8 +265,7 @@ public void urisInRequestPartHeadersCanBeModified() { @Test public void urisInRequestPartContentCanBeModified() { OperationRequest processed = this.preprocessor.host("api.example.com") - .preprocess(createRequestWithPartWithContent( - "The uri 'https://localhost:12345' should be used")); + .preprocess(createRequestWithPartWithContent("The uri 'https://localhost:12345' should be used")); assertThat(new String(processed.getParts().iterator().next().getContent())) .isEqualTo("The uri 'https://api.example.com:12345' should be used"); } @@ -316,61 +275,53 @@ public void modifiedUriDoesNotGetDoubleEncoded() { this.preprocessor.scheme("https"); OperationRequest processed = this.preprocessor .preprocess(createRequestWithUri("http://localhost:12345?foo=%7B%7D")); - assertThat(processed.getUri()) - .isEqualTo(URI.create("https://localhost:12345?foo=%7B%7D")); + assertThat(processed.getUri()).isEqualTo(URI.create("https://localhost:12345?foo=%7B%7D")); } @Test public void resultingRequestHasCookiesFromOriginalRequst() { List cookies = Arrays.asList(new RequestCookie("a", "alpha")); - OperationRequest request = this.requestFactory.create( - URI.create("http://localhost:12345"), HttpMethod.GET, new byte[0], - new HttpHeaders(), new Parameters(), - Collections.emptyList(), cookies); + OperationRequest request = this.requestFactory.create(URI.create("http://localhost:12345"), HttpMethod.GET, + new byte[0], new HttpHeaders(), new Parameters(), Collections.emptyList(), + cookies); OperationRequest processed = this.preprocessor.preprocess(request); assertThat(processed.getCookies().size()).isEqualTo(1); } private OperationRequest createRequestWithUri(String uri) { - return this.requestFactory.create(URI.create(uri), HttpMethod.GET, new byte[0], - new HttpHeaders(), new Parameters(), - Collections.emptyList()); + return this.requestFactory.create(URI.create(uri), HttpMethod.GET, new byte[0], new HttpHeaders(), + new Parameters(), Collections.emptyList()); } private OperationRequest createRequestWithContent(String content) { - return this.requestFactory.create(URI.create("http://localhost"), HttpMethod.GET, - content.getBytes(), new HttpHeaders(), new Parameters(), - Collections.emptyList()); + return this.requestFactory.create(URI.create("http://localhost"), HttpMethod.GET, content.getBytes(), + new HttpHeaders(), new Parameters(), Collections.emptyList()); } private OperationRequest createRequestWithHeader(String name, String value) { HttpHeaders headers = new HttpHeaders(); headers.add(name, value); - return this.requestFactory.create(URI.create("http://localhost"), HttpMethod.GET, - new byte[0], headers, new Parameters(), - Collections.emptyList()); + return this.requestFactory.create(URI.create("http://localhost"), HttpMethod.GET, new byte[0], headers, + new Parameters(), Collections.emptyList()); } private OperationRequest createRequestWithPartWithHeader(String name, String value) { HttpHeaders headers = new HttpHeaders(); headers.add(name, value); - return this.requestFactory.create(URI.create("http://localhost"), HttpMethod.GET, - new byte[0], new HttpHeaders(), new Parameters(), - Arrays.asList(new OperationRequestPartFactory().create("part", "fileName", - new byte[0], headers))); + return this.requestFactory.create(URI.create("http://localhost"), HttpMethod.GET, new byte[0], + new HttpHeaders(), new Parameters(), + Arrays.asList(new OperationRequestPartFactory().create("part", "fileName", new byte[0], headers))); } private OperationRequest createRequestWithPartWithContent(String content) { - return this.requestFactory.create(URI.create("http://localhost"), HttpMethod.GET, - new byte[0], new HttpHeaders(), new Parameters(), - Arrays.asList(new OperationRequestPartFactory().create("part", "fileName", - content.getBytes(), new HttpHeaders()))); + return this.requestFactory.create(URI.create("http://localhost"), HttpMethod.GET, new byte[0], + new HttpHeaders(), new Parameters(), Arrays.asList(new OperationRequestPartFactory().create("part", + "fileName", content.getBytes(), new HttpHeaders()))); } private OperationResponse createResponseWithContent(String content) { - return this.responseFactory.create(HttpStatus.OK, new HttpHeaders(), - content.getBytes()); + return this.responseFactory.create(HttpStatus.OK, new HttpHeaders(), content.getBytes()); } private OperationResponse createResponseWithHeader(String name, String value) { From 43ec46fcc15b704d297bcdf3cf32760ea84213c8 Mon Sep 17 00:00:00 2001 From: Jochen Just Date: Fri, 9 Aug 2019 12:38:12 +0200 Subject: [PATCH 053/502] Allow custom snippets directory via JUnit 5 See gh-633 --- docs/src/docs/asciidoc/getting-started.adoc | 12 ++++++++++++ .../restdocs/RestDocumentationExtension.java | 19 ++++++++++++++++++- 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/docs/src/docs/asciidoc/getting-started.adoc b/docs/src/docs/asciidoc/getting-started.adoc index 91e25f073..9c5348711 100644 --- a/docs/src/docs/asciidoc/getting-started.adoc +++ b/docs/src/docs/asciidoc/getting-started.adoc @@ -397,6 +397,18 @@ based on your project's build tool: |=== +If you are using JUnit 5.1 or later the default can be overridden by providing +an output directory when registering the `RestDocumentationExtension` instance: + +[source,java,indent=0] +---- +public class JUnit5ExampleTests { + @RegisterExtension + static final RestDocumentationExtension restDocumentation = + new RestDocumentationExtension ("custom"); +} +---- + Next, you must provide a `@BeforeEach` method to configure MockMvc, WebTestClient, or diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/RestDocumentationExtension.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/RestDocumentationExtension.java index 7c9292dbf..7b9cf57a6 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/RestDocumentationExtension.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/RestDocumentationExtension.java @@ -32,6 +32,16 @@ */ public class RestDocumentationExtension implements BeforeEachCallback, AfterEachCallback, ParameterResolver { + private final String outputDirectory; + + public RestDocumentationExtension () { + this(null); + } + + public RestDocumentationExtension (String outputDirectory) { + this.outputDirectory = outputDirectory; + } + @Override public void beforeEach(ExtensionContext context) throws Exception { this.getDelegate(context).beforeTest(context.getRequiredTestClass(), context.getRequiredTestMethod().getName()); @@ -62,7 +72,14 @@ private boolean isTestMethodContext(ExtensionContext context) { private ManualRestDocumentation getDelegate(ExtensionContext context) { Namespace namespace = Namespace.create(getClass(), context.getUniqueId()); return context.getStore(namespace).getOrComputeIfAbsent(ManualRestDocumentation.class, - (key) -> new ManualRestDocumentation(), ManualRestDocumentation.class); + this::createManualRestDocumentation, ManualRestDocumentation.class); } + private ManualRestDocumentation createManualRestDocumentation (Class key) { + if (outputDirectory != null) { + return new ManualRestDocumentation(outputDirectory); + } else { + return new ManualRestDocumentation(); + } + } } From bc66fe56430ed9ee84f0ca23f754810e01502a5e Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Fri, 30 Aug 2019 11:37:22 +0100 Subject: [PATCH 054/502] Polish "Allow custom snippets directory via JUnit 5" See gh-633 --- docs/src/docs/asciidoc/getting-started.adoc | 14 +++++------ .../restdocs/RestDocumentationExtension.java | 24 ++++++++++++++----- 2 files changed, 25 insertions(+), 13 deletions(-) diff --git a/docs/src/docs/asciidoc/getting-started.adoc b/docs/src/docs/asciidoc/getting-started.adoc index 9c5348711..8ce277be9 100644 --- a/docs/src/docs/asciidoc/getting-started.adoc +++ b/docs/src/docs/asciidoc/getting-started.adoc @@ -397,19 +397,19 @@ based on your project's build tool: |=== -If you are using JUnit 5.1 or later the default can be overridden by providing -an output directory when registering the `RestDocumentationExtension` instance: +If you are using JUnit 5.1, you can override the default by registering the extension +as a field in your test class and providing an output directory when creating it. The +following example shows how to do so: [source,java,indent=0] ---- public class JUnit5ExampleTests { - @RegisterExtension - static final RestDocumentationExtension restDocumentation = - new RestDocumentationExtension ("custom"); -} ----- + @RegisterExtension + final RestDocumentationExtension restDocumentation = new RestDocumentationExtension ("custom"); +} +---- Next, you must provide a `@BeforeEach` method to configure MockMvc, WebTestClient, or REST Assured. The following listings show how to do so: diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/RestDocumentationExtension.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/RestDocumentationExtension.java index 7b9cf57a6..743ad319d 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/RestDocumentationExtension.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/RestDocumentationExtension.java @@ -34,11 +34,21 @@ public class RestDocumentationExtension implements BeforeEachCallback, AfterEach private final String outputDirectory; - public RestDocumentationExtension () { + /** + * Creates a new {@code RestDocumentationExtension} that will use the default output + * directory. + */ + public RestDocumentationExtension() { this(null); } - public RestDocumentationExtension (String outputDirectory) { + /** + * Creates a new {@code RestDocumentationExtension} that will use the given + * {@code outputDirectory}. + * @param outputDirectory snippet output directory + * @since 2.0.4 + */ + public RestDocumentationExtension(String outputDirectory) { this.outputDirectory = outputDirectory; } @@ -75,11 +85,13 @@ private ManualRestDocumentation getDelegate(ExtensionContext context) { this::createManualRestDocumentation, ManualRestDocumentation.class); } - private ManualRestDocumentation createManualRestDocumentation (Class key) { - if (outputDirectory != null) { - return new ManualRestDocumentation(outputDirectory); - } else { + private ManualRestDocumentation createManualRestDocumentation(Class key) { + if (this.outputDirectory != null) { + return new ManualRestDocumentation(this.outputDirectory); + } + else { return new ManualRestDocumentation(); } } + } From b66c8b459412a3d37cc5bad8fa7b76bbe8371d6b Mon Sep 17 00:00:00 2001 From: Alexander Schwartz Date: Fri, 2 Aug 2019 20:38:06 +0200 Subject: [PATCH 055/502] Avoid warnings when parsing AsciiDoc sub-content in Asciidoctor.load Renderings with standard section depth first to avoid warnings that document starts with level 3 headings. Adjust block level when adding the content to the parent. See gh-628 --- .../extensions/operation_block_macro.rb | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/spring-restdocs-asciidoctor-support/src/main/resources/extensions/operation_block_macro.rb b/spring-restdocs-asciidoctor-support/src/main/resources/extensions/operation_block_macro.rb index b3f3a0ddd..a15ee8055 100644 --- a/spring-restdocs-asciidoctor-support/src/main/resources/extensions/operation_block_macro.rb +++ b/spring-restdocs-asciidoctor-support/src/main/resources/extensions/operation_block_macro.rb @@ -37,10 +37,9 @@ def read_snippets(snippets_dir, snippet_names, parent, operation, def do_read_snippets(snippets, parent, operation, snippet_titles) content = StringIO.new - section_level = parent.level + 1 section_id = parent.id snippets.each do |snippet| - append_snippet_block(content, snippet, section_level, section_id, + append_snippet_block(content, snippet, section_id, operation, snippet_titles) end content.string @@ -51,11 +50,12 @@ def add_blocks(content, doc, parent) fragment = Asciidoctor.load content, options fragment.blocks.each do |b| b.parent = parent + b.level += parent.level parent << b end parent.find_by.each do |b| - b.parent = b.parent unless b.is_a? Asciidoctor::Document - end + b.parent = b.parent unless b.is_a? Asciidoctor::Document + end end def snippets_to_include(snippet_names, snippets_dir, operation) @@ -78,9 +78,9 @@ def all_snippets(snippets_dir, operation) .map { |file| Snippet.new(File.join(operation_dir, file), file[0..-6]) } end - def append_snippet_block(content, snippet, section_level, section_id, + def append_snippet_block(content, snippet, section_id, operation, snippet_titles) - write_title content, snippet, section_level, section_id, snippet_titles + write_title content, snippet, section_id, snippet_titles write_content content, snippet, operation end @@ -96,8 +96,8 @@ def write_content(content, snippet, operation) end end - def write_title(content, snippet, level, id, snippet_titles) - section_level = '=' * (level + 1) + def write_title(content, snippet, id, snippet_titles) + section_level = '==' title = snippet_titles.title_for_snippet snippet content.puts "[[#{id}_#{snippet.name.sub '-', '_'}]]" content.puts "#{section_level} #{title}" @@ -141,4 +141,4 @@ def title_for_snippet(snippet) end end end -end +end \ No newline at end of file From 9de06a36d225ec8aedf68641384021f278cbbb29 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Fri, 30 Aug 2019 12:29:55 +0100 Subject: [PATCH 056/502] Polish "Avoid warnings when parsing AsciiDoc sub-content in Asciidoctor.load" See gh-628 --- .../AbstractOperationBlockMacroTests.java | 10 ++++- .../asciidoctor/CapturingLogHandler.java | 42 +++++++++++++++++++ .../services/org.asciidoctor.log.LogHandler | 1 + .../operations/snippet-in-section.html | 14 ++++++- 4 files changed, 64 insertions(+), 3 deletions(-) create mode 100644 spring-restdocs-asciidoctor/src/test/java/org/springframework/restdocs/asciidoctor/CapturingLogHandler.java create mode 100644 spring-restdocs-asciidoctor/src/test/resources/META-INF/services/org.asciidoctor.log.LogHandler diff --git a/spring-restdocs-asciidoctor/src/test/java/org/springframework/restdocs/asciidoctor/AbstractOperationBlockMacroTests.java b/spring-restdocs-asciidoctor/src/test/java/org/springframework/restdocs/asciidoctor/AbstractOperationBlockMacroTests.java index 46fde7b00..31bbda40c 100644 --- a/spring-restdocs-asciidoctor/src/test/java/org/springframework/restdocs/asciidoctor/AbstractOperationBlockMacroTests.java +++ b/spring-restdocs-asciidoctor/src/test/java/org/springframework/restdocs/asciidoctor/AbstractOperationBlockMacroTests.java @@ -35,6 +35,7 @@ import org.asciidoctor.Options; import org.asciidoctor.OptionsBuilder; import org.asciidoctor.SafeMode; +import org.junit.After; import org.junit.Before; import org.junit.Rule; import org.junit.Test; @@ -64,6 +65,12 @@ public void setUp() throws IOException { prepareOperationSnippets(getBuildOutputLocation()); this.options = OptionsBuilder.options().safe(SafeMode.UNSAFE).baseDir(getSourceLocation()).get(); this.options.setAttributes(getAttributes()); + CapturingLogHandler.clear(); + } + + @After + public void verifyLogging() { + assertThat(CapturingLogHandler.getLogRecords()).isEmpty(); } public void prepareOperationSnippets(File buildOutputLocation) throws IOException { @@ -110,7 +117,8 @@ public void tableSnippetIncludeWithPdfBackend() throws Exception { @Test public void includeSnippetInSection() throws Exception { - String result = this.asciidoctor.convert("== Section\n" + "operation::some-operation[snippets='curl-request']", + String result = this.asciidoctor.convert( + "= A\n\nAlpha\n\n== B\n\nBravo\n\n" + "operation::some-operation[snippets='curl-request']", this.options); assertThat(result).isEqualTo(getExpectedContentFromFile("snippet-in-section")); } diff --git a/spring-restdocs-asciidoctor/src/test/java/org/springframework/restdocs/asciidoctor/CapturingLogHandler.java b/spring-restdocs-asciidoctor/src/test/java/org/springframework/restdocs/asciidoctor/CapturingLogHandler.java new file mode 100644 index 000000000..f60ce09c4 --- /dev/null +++ b/spring-restdocs-asciidoctor/src/test/java/org/springframework/restdocs/asciidoctor/CapturingLogHandler.java @@ -0,0 +1,42 @@ +/* + * Copyright 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 + * + * https://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.util.ArrayList; +import java.util.List; + +import org.asciidoctor.log.LogHandler; +import org.asciidoctor.log.LogRecord; + +public class CapturingLogHandler implements LogHandler { + + private static final List logRecords = new ArrayList(); + + @Override + public void log(LogRecord logRecord) { + logRecords.add(logRecord); + } + + static List getLogRecords() { + return logRecords; + } + + static void clear() { + logRecords.clear(); + } + +} diff --git a/spring-restdocs-asciidoctor/src/test/resources/META-INF/services/org.asciidoctor.log.LogHandler b/spring-restdocs-asciidoctor/src/test/resources/META-INF/services/org.asciidoctor.log.LogHandler new file mode 100644 index 000000000..28aea3ae1 --- /dev/null +++ b/spring-restdocs-asciidoctor/src/test/resources/META-INF/services/org.asciidoctor.log.LogHandler @@ -0,0 +1 @@ +org.springframework.restdocs.asciidoctor.CapturingLogHandler \ No newline at end of file diff --git a/spring-restdocs-asciidoctor/src/test/resources/operations/snippet-in-section.html b/spring-restdocs-asciidoctor/src/test/resources/operations/snippet-in-section.html index 5c7938ae0..0bc6f2728 100644 --- a/spring-restdocs-asciidoctor/src/test/resources/operations/snippet-in-section.html +++ b/spring-restdocs-asciidoctor/src/test/resources/operations/snippet-in-section.html @@ -1,8 +1,18 @@ +
+
+
+

Alpha

+
+
+
-

Section

+

B

+
+

Bravo

+
-

Curl request

+

Curl request

$ curl 'http://localhost:8080/' -i
From 1b87af13be1bed345a69941a7bf16800f0a67b66 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Fri, 30 Aug 2019 14:05:50 +0100 Subject: [PATCH 057/502] Improve diagnostics when extracting a non-existent subsection Closes gh-568 --- .../payload/FieldPathPayloadSubsectionExtractor.java | 3 +++ .../FieldPathPayloadSubsectionExtractorTests.java | 9 +++++++++ 2 files changed, 12 insertions(+) diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/FieldPathPayloadSubsectionExtractor.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/FieldPathPayloadSubsectionExtractor.java index a4afda246..b0da8d42d 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/FieldPathPayloadSubsectionExtractor.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/FieldPathPayloadSubsectionExtractor.java @@ -75,6 +75,9 @@ public byte[] extractSubsection(byte[] payload, MediaType contentType) { ExtractedField extractedField = new JsonFieldProcessor().extract(this.fieldPath, objectMapper.readValue(payload, Object.class)); Object value = extractedField.getValue(); + if (value == ExtractedField.ABSENT) { + throw new PayloadHandlingException(this.fieldPath + " does not identify a section of the payload"); + } if (value instanceof List) { List extractedList = (List) value; Set uncommonPaths = JsonFieldPaths.from(extractedList).getUncommon(); diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/FieldPathPayloadSubsectionExtractorTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/FieldPathPayloadSubsectionExtractorTests.java index 9db464a3b..facf11db6 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/FieldPathPayloadSubsectionExtractorTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/FieldPathPayloadSubsectionExtractorTests.java @@ -31,6 +31,7 @@ import org.springframework.http.MediaType; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; /** * Tests for {@link FieldPathPayloadSubsectionExtractor}. @@ -130,4 +131,12 @@ public void extractedSubsectionIsNotPrettyPrintedWhenInputIsNotPrettyPrinted() assertThat(new String(extractedSubsection)).isEqualTo(new String(subsection)); } + @Test + public void extractNonExistentSubsection() throws JsonParseException, JsonMappingException, IOException { + assertThatThrownBy(() -> new FieldPathPayloadSubsectionExtractor("a.c") + .extractSubsection("{\"a\":{\"b\":{\"c\":5}}}".getBytes(), MediaType.APPLICATION_JSON)) + .isInstanceOf(PayloadHandlingException.class) + .hasMessage("a.c does not identify a section of the payload"); + } + } From 412c03def28fea1120acb418a8bb84c0f0e967c9 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Fri, 30 Aug 2019 14:17:17 +0100 Subject: [PATCH 058/502] Upgrade to Spring Framework 5.0.9.RELEASE Closes gh-636 --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 3d02e27d3..3b946028b 100644 --- a/build.gradle +++ b/build.gradle @@ -47,7 +47,7 @@ nohttp { } ext { - springVersion = '5.0.5.RELEASE' + springVersion = '5.0.9.RELEASE' javadocLinks = [ 'https://docs.oracle.com/javase/8/docs/api/', "https://docs.spring.io/spring-framework/docs/$springVersion/javadoc-api/", From c4d664c3a27561287f9d78c263e7445da5eac912 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Fri, 30 Aug 2019 17:08:30 +0100 Subject: [PATCH 059/502] Upgrade to AssertJ 3.11.1 --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 3b946028b..d3ecc5e97 100644 --- a/build.gradle +++ b/build.gradle @@ -82,7 +82,7 @@ subprojects { dependency 'junit:junit:4.12' dependency 'io.rest-assured:rest-assured:3.0.7' dependency 'org.apache.pdfbox:pdfbox:2.0.7' - dependency 'org.assertj:assertj-core:2.9.1' + dependency 'org.assertj:assertj-core:3.11.1' dependency 'org.asciidoctor:asciidoctorj-pdf:1.5.0-alpha.18' dependency 'org.hamcrest:hamcrest-core:1.3' dependency 'org.hamcrest:hamcrest-library:1.3' From b5f2454c005f08497cc55be345afb17ac016a851 Mon Sep 17 00:00:00 2001 From: Dmytro Nosan Date: Mon, 18 Feb 2019 16:08:53 +0200 Subject: [PATCH 060/502] Improve diagnostics for null configuration See gh-583 --- .../RestDocumentationResultHandler.java | 21 ++++++++++------ ...kMvcRestDocumentationIntegrationTests.java | 24 +++++++++++++++++++ .../restassured3/RestDocumentationFilter.java | 13 ++++++++-- ...uredRestDocumentationIntegrationTests.java | 22 +++++++++++++++++ .../WebTestClientRestDocumentation.java | 20 ++++++++++------ ...ientRestDocumentationIntegrationTests.java | 16 +++++++++++++ 6 files changed, 100 insertions(+), 16 deletions(-) diff --git a/spring-restdocs-mockmvc/src/main/java/org/springframework/restdocs/mockmvc/RestDocumentationResultHandler.java b/spring-restdocs-mockmvc/src/main/java/org/springframework/restdocs/mockmvc/RestDocumentationResultHandler.java index a5c12334f..944940b33 100644 --- a/spring-restdocs-mockmvc/src/main/java/org/springframework/restdocs/mockmvc/RestDocumentationResultHandler.java +++ b/spring-restdocs-mockmvc/src/main/java/org/springframework/restdocs/mockmvc/RestDocumentationResultHandler.java @@ -49,10 +49,7 @@ public class RestDocumentationResultHandler implements ResultHandler { @Override public void handle(MvcResult result) throws Exception { - @SuppressWarnings("unchecked") - Map configuration = (Map) result.getRequest() - .getAttribute(ATTRIBUTE_NAME_CONFIGURATION); - this.delegate.handle(result.getRequest(), result.getResponse(), configuration); + this.delegate.handle(result.getRequest(), result.getResponse(), getRequiredConfiguration(result)); } /** @@ -75,9 +72,7 @@ public RestDocumentationResultHandler document(Snippet... snippets) { @Override public void handle(MvcResult result) throws Exception { - @SuppressWarnings("unchecked") - Map configuration = new HashMap<>( - (Map) result.getRequest().getAttribute(ATTRIBUTE_NAME_CONFIGURATION)); + Map configuration = new HashMap<>(getRequiredConfiguration(result)); configuration.remove(RestDocumentationGenerator.ATTRIBUTE_NAME_DEFAULT_SNIPPETS); getDelegate().handle(result.getRequest(), result.getResponse(), configuration); } @@ -93,4 +88,16 @@ protected final RestDocumentationGenerator getRequiredConfiguration(MvcResult result) { + @SuppressWarnings("unchecked") + Map configuration = (Map) result.getRequest() + .getAttribute(ATTRIBUTE_NAME_CONFIGURATION); + Assert.state(configuration != null, + () -> String.format( + "There is no REST Docs configuration. Looks like " + + "'%s' was not invoked. Please check your configuration.", + MockMvcRestDocumentationConfigurer.class.getName())); + return configuration; + } + } diff --git a/spring-restdocs-mockmvc/src/test/java/org/springframework/restdocs/mockmvc/MockMvcRestDocumentationIntegrationTests.java b/spring-restdocs-mockmvc/src/test/java/org/springframework/restdocs/mockmvc/MockMvcRestDocumentationIntegrationTests.java index ed8872e88..38ebdfa4c 100644 --- a/spring-restdocs-mockmvc/src/test/java/org/springframework/restdocs/mockmvc/MockMvcRestDocumentationIntegrationTests.java +++ b/spring-restdocs-mockmvc/src/test/java/org/springframework/restdocs/mockmvc/MockMvcRestDocumentationIntegrationTests.java @@ -69,6 +69,7 @@ import org.springframework.web.servlet.config.annotation.EnableWebMvc; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.assertj.core.api.Assertions.fail; import static org.springframework.restdocs.headers.HeaderDocumentation.headerWithName; import static org.springframework.restdocs.headers.HeaderDocumentation.responseHeaders; @@ -491,6 +492,29 @@ public void customContextPath() throws Exception { + " -H 'Accept: application/json'")))); } + @Test + public void exceptionShouldBeThrownWhenCallDocumentMockMvcNotConfigured() { + MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(this.context).build(); + assertThatThrownBy(() -> mockMvc.perform(get("/").accept(MediaType.APPLICATION_JSON)).andDo(document("basic"))) + .isInstanceOf(IllegalStateException.class).hasMessageContaining(missingConfigurationMessage()); + + } + + @Test + public void exceptionShouldBeThrownWhenCallDocumentSnippetsMockMvcNotConfigured() { + RestDocumentationResultHandler documentation = document("{method-name}-{step}"); + MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(this.context).build(); + assertThatThrownBy(() -> mockMvc.perform(get("/").accept(MediaType.APPLICATION_JSON)) + .andDo(documentation.document(responseHeaders(headerWithName("a").description("one"))))) + .isInstanceOf(IllegalStateException.class).hasMessageContaining(missingConfigurationMessage()); + } + + private String missingConfigurationMessage() { + return "There is no REST Docs configuration. Looks like " + + "'org.springframework.restdocs.mockmvc.MockMvcRestDocumentationConfigurer' " + + "was not invoked. Please check your configuration."; + } + @Test public void multiPart() throws Exception { MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(this.context) diff --git a/spring-restdocs-restassured/src/main/java/org/springframework/restdocs/restassured3/RestDocumentationFilter.java b/spring-restdocs-restassured/src/main/java/org/springframework/restdocs/restassured3/RestDocumentationFilter.java index b3e730e26..eb6299179 100644 --- a/spring-restdocs-restassured/src/main/java/org/springframework/restdocs/restassured3/RestDocumentationFilter.java +++ b/spring-restdocs-restassured/src/main/java/org/springframework/restdocs/restassured3/RestDocumentationFilter.java @@ -67,8 +67,7 @@ public final Response filter(FilterableRequestSpecification requestSpec, * @return the configuration */ protected Map getConfiguration(FilterableRequestSpecification requestSpec, FilterContext context) { - Map configuration = new HashMap<>( - context.>getValue(CONTEXT_KEY_CONFIGURATION)); + Map configuration = new HashMap<>(getRequiredConfiguration(context)); configuration.put(RestDocumentationContext.class.getName(), context.getValue(RestDocumentationContext.class.getName())); configuration.put(RestDocumentationGenerator.ATTRIBUTE_NAME_URL_TEMPLATE, requestSpec.getUserDefinedPath()); @@ -97,4 +96,14 @@ protected Map getConfiguration(FilterableRequestSpecification re }; } + private static Map getRequiredConfiguration(FilterContext context) { + Map configuration = context.getValue(CONTEXT_KEY_CONFIGURATION); + Assert.state(configuration != null, + () -> String.format( + "There is no REST Docs configuration. Looks like " + + "'%s' was not invoked. Please check your configuration.", + RestDocumentationFilter.class.getName())); + return configuration; + } + } diff --git a/spring-restdocs-restassured/src/test/java/org/springframework/restdocs/restassured3/RestAssuredRestDocumentationIntegrationTests.java b/spring-restdocs-restassured/src/test/java/org/springframework/restdocs/restassured3/RestAssuredRestDocumentationIntegrationTests.java index a52061051..c3b91f6be 100644 --- a/spring-restdocs-restassured/src/test/java/org/springframework/restdocs/restassured3/RestAssuredRestDocumentationIntegrationTests.java +++ b/spring-restdocs-restassured/src/test/java/org/springframework/restdocs/restassured3/RestAssuredRestDocumentationIntegrationTests.java @@ -47,6 +47,7 @@ import static io.restassured.RestAssured.given; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.assertj.core.api.Assertions.fail; import static org.springframework.restdocs.headers.HeaderDocumentation.headerWithName; import static org.springframework.restdocs.headers.HeaderDocumentation.responseHeaders; @@ -339,6 +340,27 @@ public void customSnippetTemplate() throws Exception { .hasContent("Custom curl request"); } + @Test + public void exceptionShouldBeThrownWhenCallDocumentRequestSpecificationNotConfigured() { + assertThatThrownBy(() -> given().port(tomcat.getPort()).filter(document("default")).get("/")) + .isInstanceOf(IllegalStateException.class).hasMessageContaining(messingConfigurationMessage()); + } + + @Test + public void exceptionShouldBeThrownWhenCallDocumentSnippetsRequestSpecificationNotConfigured() { + RestDocumentationFilter documentation = document("{method-name}-{step}"); + assertThatThrownBy(() -> given().port(tomcat.getPort()) + .filter(documentation.document(responseHeaders(headerWithName("a").description("one")))).get("/")) + .isInstanceOf(IllegalStateException.class).hasMessageContaining(messingConfigurationMessage()); + } + + private String messingConfigurationMessage() { + return "There is no REST Docs configuration. Looks like 'org.springframework." + + "restdocs.restassured3.RestDocumentationFilter' was not invoked." + + " Please check your configuration."; + + } + private void assertExpectedSnippetFilesExist(File directory, String... snippets) { for (String snippet : snippets) { assertThat(new File(directory, snippet)).isFile(); diff --git a/spring-restdocs-webtestclient/src/main/java/org/springframework/restdocs/webtestclient/WebTestClientRestDocumentation.java b/spring-restdocs-webtestclient/src/main/java/org/springframework/restdocs/webtestclient/WebTestClientRestDocumentation.java index 1dd60c172..8ed49c24a 100644 --- a/spring-restdocs-webtestclient/src/main/java/org/springframework/restdocs/webtestclient/WebTestClientRestDocumentation.java +++ b/spring-restdocs-webtestclient/src/main/java/org/springframework/restdocs/webtestclient/WebTestClientRestDocumentation.java @@ -30,6 +30,7 @@ import org.springframework.test.web.reactive.server.WebTestClient.BodyContentSpec; import org.springframework.test.web.reactive.server.WebTestClient.BodySpec; import org.springframework.test.web.reactive.server.WebTestClient.Builder; +import org.springframework.util.Assert; import org.springframework.web.reactive.function.client.ExchangeFilterFunction; /** @@ -75,7 +76,7 @@ public static WebTestClientRestDocumentationConfigurer documentationConfiguratio */ public static Consumer document(String identifier, Snippet... snippets) { return (result) -> new RestDocumentationGenerator<>(identifier, REQUEST_CONVERTER, RESPONSE_CONVERTER, snippets) - .handle(result, result, retrieveConfiguration(result)); + .handle(result, result, getRequiredConfiguration(result)); } /** @@ -92,7 +93,7 @@ public static Consumer document(String identifier, public static Consumer document(String identifier, OperationRequestPreprocessor requestPreprocessor, Snippet... snippets) { return (result) -> new RestDocumentationGenerator<>(identifier, REQUEST_CONVERTER, RESPONSE_CONVERTER, - requestPreprocessor, snippets).handle(result, result, retrieveConfiguration(result)); + requestPreprocessor, snippets).handle(result, result, getRequiredConfiguration(result)); } /** @@ -109,7 +110,7 @@ public static Consumer document(String identifier, public static Consumer document(String identifier, OperationResponsePreprocessor responsePreprocessor, Snippet... snippets) { return (result) -> new RestDocumentationGenerator<>(identifier, REQUEST_CONVERTER, RESPONSE_CONVERTER, - responsePreprocessor, snippets).handle(result, result, retrieveConfiguration(result)); + responsePreprocessor, snippets).handle(result, result, getRequiredConfiguration(result)); } /** @@ -130,12 +131,17 @@ public static Consumer document(String identifier, Snippet... snippets) { return (result) -> new RestDocumentationGenerator<>(identifier, REQUEST_CONVERTER, RESPONSE_CONVERTER, requestPreprocessor, responsePreprocessor, snippets).handle(result, result, - retrieveConfiguration(result)); + getRequiredConfiguration(result)); } - private static Map retrieveConfiguration(ExchangeResult result) { - Map configuration = new HashMap<>( - WebTestClientRestDocumentationConfigurer.retrieveConfiguration(result.getRequestHeaders())); + private static Map getRequiredConfiguration(ExchangeResult result) { + Map config = WebTestClientRestDocumentationConfigurer + .retrieveConfiguration(result.getRequestHeaders()); + Assert.state(config != null, + () -> String.format("There is no REST Docs configuration. Looks like '%s' " + + "was not invoked or configuration has already been removed. Please check your configuration.", + WebTestClientRestDocumentationConfigurer.class.getName())); + Map configuration = new HashMap<>(config); configuration.put(RestDocumentationGenerator.ATTRIBUTE_NAME_URL_TEMPLATE, result.getUriTemplate()); return configuration; } diff --git a/spring-restdocs-webtestclient/src/test/java/org/springframework/restdocs/webtestclient/WebTestClientRestDocumentationIntegrationTests.java b/spring-restdocs-webtestclient/src/test/java/org/springframework/restdocs/webtestclient/WebTestClientRestDocumentationIntegrationTests.java index ae3766c80..e09633fe9 100644 --- a/spring-restdocs-webtestclient/src/test/java/org/springframework/restdocs/webtestclient/WebTestClientRestDocumentationIntegrationTests.java +++ b/spring-restdocs-webtestclient/src/test/java/org/springframework/restdocs/webtestclient/WebTestClientRestDocumentationIntegrationTests.java @@ -23,6 +23,7 @@ import java.nio.charset.StandardCharsets; import java.util.Arrays; import java.util.HashSet; +import java.util.List; import java.util.Set; import java.util.function.Consumer; import java.util.stream.Collectors; @@ -58,6 +59,7 @@ import org.springframework.web.reactive.function.server.ServerResponse; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.assertj.core.api.Assertions.fail; import static org.springframework.restdocs.request.RequestDocumentation.parameterWithName; import static org.springframework.restdocs.request.RequestDocumentation.partWithName; @@ -173,6 +175,20 @@ public void httpieSnippetWithCookies() throws Exception { + " 'Accept:application/json' \\%n" + " 'Cookie:cookieName=cookieVal'")))); } + @Test + public void illegalStateExceptionShouldBeThrownWhenCallDocumentWebClientNotConfigured() { + assertThatThrownBy(() -> this.webTestClient + .mutateWith((builder, httpHandlerBuilder, connector) -> builder.filters(List::clear).build()).get() + .uri("/").exchange().expectBody().consumeWith(document("default-snippets"))) + .isInstanceOf(IllegalStateException.class).hasMessageContaining(missingConfiguration()); + } + + private String missingConfiguration() { + return "There is no REST Docs configuration. Looks like " + + "'org.springframework.restdocs.webtestclient.WebTestClientRestDocumentationConfigurer' " + + "was not invoked or configuration has already been removed. Please check your configuration."; + } + private void assertExpectedSnippetFilesExist(File directory, String... snippets) { Set actual = new HashSet<>(Arrays.asList(directory.listFiles())); Set expected = Stream.of(snippets).map((snippet) -> new File(directory, snippet)) From fce255695ebf5641e0c12ded00649298b1a08411 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Fri, 30 Aug 2019 16:57:21 +0100 Subject: [PATCH 061/502] Polish "Improve diagnostics for null configuration" See gh-583 --- .../RestDocumentationResultHandler.java | 13 +++++-------- ...kMvcRestDocumentationIntegrationTests.java | 13 +++++-------- .../restassured3/RestDocumentationFilter.java | 11 +++++------ ...uredRestDocumentationIntegrationTests.java | 16 +++++++--------- .../WebTestClientRestDocumentation.java | 19 ++++++------------- ...TestClientRestDocumentationConfigurer.java | 6 +++++- ...lientRestDocumentationConfigurerTests.java | 4 +++- ...ientRestDocumentationIntegrationTests.java | 10 +++------- 8 files changed, 39 insertions(+), 53 deletions(-) diff --git a/spring-restdocs-mockmvc/src/main/java/org/springframework/restdocs/mockmvc/RestDocumentationResultHandler.java b/spring-restdocs-mockmvc/src/main/java/org/springframework/restdocs/mockmvc/RestDocumentationResultHandler.java index 944940b33..3111b7b6f 100644 --- a/spring-restdocs-mockmvc/src/main/java/org/springframework/restdocs/mockmvc/RestDocumentationResultHandler.java +++ b/spring-restdocs-mockmvc/src/main/java/org/springframework/restdocs/mockmvc/RestDocumentationResultHandler.java @@ -49,7 +49,7 @@ public class RestDocumentationResultHandler implements ResultHandler { @Override public void handle(MvcResult result) throws Exception { - this.delegate.handle(result.getRequest(), result.getResponse(), getRequiredConfiguration(result)); + this.delegate.handle(result.getRequest(), result.getResponse(), retrieveConfiguration(result)); } /** @@ -72,7 +72,7 @@ public RestDocumentationResultHandler document(Snippet... snippets) { @Override public void handle(MvcResult result) throws Exception { - Map configuration = new HashMap<>(getRequiredConfiguration(result)); + Map configuration = new HashMap<>(retrieveConfiguration(result)); configuration.remove(RestDocumentationGenerator.ATTRIBUTE_NAME_DEFAULT_SNIPPETS); getDelegate().handle(result.getRequest(), result.getResponse(), configuration); } @@ -88,15 +88,12 @@ protected final RestDocumentationGenerator getRequiredConfiguration(MvcResult result) { + private Map retrieveConfiguration(MvcResult result) { @SuppressWarnings("unchecked") Map configuration = (Map) result.getRequest() .getAttribute(ATTRIBUTE_NAME_CONFIGURATION); - Assert.state(configuration != null, - () -> String.format( - "There is no REST Docs configuration. Looks like " - + "'%s' was not invoked. Please check your configuration.", - MockMvcRestDocumentationConfigurer.class.getName())); + Assert.state(configuration != null, () -> "REST Docs configuration not found. Did you forget to apply a " + + MockMvcRestDocumentationConfigurer.class.getSimpleName() + " when building the MockMvc instance?"); return configuration; } diff --git a/spring-restdocs-mockmvc/src/test/java/org/springframework/restdocs/mockmvc/MockMvcRestDocumentationIntegrationTests.java b/spring-restdocs-mockmvc/src/test/java/org/springframework/restdocs/mockmvc/MockMvcRestDocumentationIntegrationTests.java index 38ebdfa4c..129952b7e 100644 --- a/spring-restdocs-mockmvc/src/test/java/org/springframework/restdocs/mockmvc/MockMvcRestDocumentationIntegrationTests.java +++ b/spring-restdocs-mockmvc/src/test/java/org/springframework/restdocs/mockmvc/MockMvcRestDocumentationIntegrationTests.java @@ -496,7 +496,8 @@ public void customContextPath() throws Exception { public void exceptionShouldBeThrownWhenCallDocumentMockMvcNotConfigured() { MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(this.context).build(); assertThatThrownBy(() -> mockMvc.perform(get("/").accept(MediaType.APPLICATION_JSON)).andDo(document("basic"))) - .isInstanceOf(IllegalStateException.class).hasMessageContaining(missingConfigurationMessage()); + .isInstanceOf(IllegalStateException.class).hasMessage("REST Docs configuration not found. Did you " + + "forget to apply a MockMvcRestDocumentationConfigurer when building the MockMvc instance?"); } @@ -506,13 +507,9 @@ public void exceptionShouldBeThrownWhenCallDocumentSnippetsMockMvcNotConfigured( MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(this.context).build(); assertThatThrownBy(() -> mockMvc.perform(get("/").accept(MediaType.APPLICATION_JSON)) .andDo(documentation.document(responseHeaders(headerWithName("a").description("one"))))) - .isInstanceOf(IllegalStateException.class).hasMessageContaining(missingConfigurationMessage()); - } - - private String missingConfigurationMessage() { - return "There is no REST Docs configuration. Looks like " - + "'org.springframework.restdocs.mockmvc.MockMvcRestDocumentationConfigurer' " - + "was not invoked. Please check your configuration."; + .isInstanceOf(IllegalStateException.class) + .hasMessage("REST Docs configuration not found. Did you forget to apply a " + + "MockMvcRestDocumentationConfigurer when building the MockMvc instance?"); } @Test diff --git a/spring-restdocs-restassured/src/main/java/org/springframework/restdocs/restassured3/RestDocumentationFilter.java b/spring-restdocs-restassured/src/main/java/org/springframework/restdocs/restassured3/RestDocumentationFilter.java index eb6299179..342d69eb1 100644 --- a/spring-restdocs-restassured/src/main/java/org/springframework/restdocs/restassured3/RestDocumentationFilter.java +++ b/spring-restdocs-restassured/src/main/java/org/springframework/restdocs/restassured3/RestDocumentationFilter.java @@ -67,7 +67,7 @@ public final Response filter(FilterableRequestSpecification requestSpec, * @return the configuration */ protected Map getConfiguration(FilterableRequestSpecification requestSpec, FilterContext context) { - Map configuration = new HashMap<>(getRequiredConfiguration(context)); + Map configuration = new HashMap<>(retrieveConfiguration(context)); configuration.put(RestDocumentationContext.class.getName(), context.getValue(RestDocumentationContext.class.getName())); configuration.put(RestDocumentationGenerator.ATTRIBUTE_NAME_URL_TEMPLATE, requestSpec.getUserDefinedPath()); @@ -96,13 +96,12 @@ protected Map getConfiguration(FilterableRequestSpecification re }; } - private static Map getRequiredConfiguration(FilterContext context) { + private static Map retrieveConfiguration(FilterContext context) { Map configuration = context.getValue(CONTEXT_KEY_CONFIGURATION); Assert.state(configuration != null, - () -> String.format( - "There is no REST Docs configuration. Looks like " - + "'%s' was not invoked. Please check your configuration.", - RestDocumentationFilter.class.getName())); + () -> "REST Docs configuration not found. Did you forget to add a " + + RestAssuredRestDocumentationConfigurer.class.getSimpleName() + + " as a filter when building the RequestSpecification?"); return configuration; } diff --git a/spring-restdocs-restassured/src/test/java/org/springframework/restdocs/restassured3/RestAssuredRestDocumentationIntegrationTests.java b/spring-restdocs-restassured/src/test/java/org/springframework/restdocs/restassured3/RestAssuredRestDocumentationIntegrationTests.java index c3b91f6be..492e71b21 100644 --- a/spring-restdocs-restassured/src/test/java/org/springframework/restdocs/restassured3/RestAssuredRestDocumentationIntegrationTests.java +++ b/spring-restdocs-restassured/src/test/java/org/springframework/restdocs/restassured3/RestAssuredRestDocumentationIntegrationTests.java @@ -343,7 +343,9 @@ public void customSnippetTemplate() throws Exception { @Test public void exceptionShouldBeThrownWhenCallDocumentRequestSpecificationNotConfigured() { assertThatThrownBy(() -> given().port(tomcat.getPort()).filter(document("default")).get("/")) - .isInstanceOf(IllegalStateException.class).hasMessageContaining(messingConfigurationMessage()); + .isInstanceOf(IllegalStateException.class) + .hasMessage("REST Docs configuration not found. Did you forget to add a " + + "RestAssuredRestDocumentationConfigurer as a filter when building the RequestSpecification?"); } @Test @@ -351,14 +353,10 @@ public void exceptionShouldBeThrownWhenCallDocumentSnippetsRequestSpecificationN RestDocumentationFilter documentation = document("{method-name}-{step}"); assertThatThrownBy(() -> given().port(tomcat.getPort()) .filter(documentation.document(responseHeaders(headerWithName("a").description("one")))).get("/")) - .isInstanceOf(IllegalStateException.class).hasMessageContaining(messingConfigurationMessage()); - } - - private String messingConfigurationMessage() { - return "There is no REST Docs configuration. Looks like 'org.springframework." - + "restdocs.restassured3.RestDocumentationFilter' was not invoked." - + " Please check your configuration."; - + .isInstanceOf(IllegalStateException.class) + .hasMessage("REST Docs configuration not found. Did you forget to add a " + + "RestAssuredRestDocumentationConfigurer as a filter when building the " + + "RequestSpecification?"); } private void assertExpectedSnippetFilesExist(File directory, String... snippets) { diff --git a/spring-restdocs-webtestclient/src/main/java/org/springframework/restdocs/webtestclient/WebTestClientRestDocumentation.java b/spring-restdocs-webtestclient/src/main/java/org/springframework/restdocs/webtestclient/WebTestClientRestDocumentation.java index 8ed49c24a..ce66df5f8 100644 --- a/spring-restdocs-webtestclient/src/main/java/org/springframework/restdocs/webtestclient/WebTestClientRestDocumentation.java +++ b/spring-restdocs-webtestclient/src/main/java/org/springframework/restdocs/webtestclient/WebTestClientRestDocumentation.java @@ -16,7 +16,6 @@ package org.springframework.restdocs.webtestclient; -import java.util.HashMap; import java.util.Map; import java.util.function.Consumer; @@ -30,7 +29,6 @@ import org.springframework.test.web.reactive.server.WebTestClient.BodyContentSpec; import org.springframework.test.web.reactive.server.WebTestClient.BodySpec; import org.springframework.test.web.reactive.server.WebTestClient.Builder; -import org.springframework.util.Assert; import org.springframework.web.reactive.function.client.ExchangeFilterFunction; /** @@ -76,7 +74,7 @@ public static WebTestClientRestDocumentationConfigurer documentationConfiguratio */ public static Consumer document(String identifier, Snippet... snippets) { return (result) -> new RestDocumentationGenerator<>(identifier, REQUEST_CONVERTER, RESPONSE_CONVERTER, snippets) - .handle(result, result, getRequiredConfiguration(result)); + .handle(result, result, retrieveConfiguration(result)); } /** @@ -93,7 +91,7 @@ public static Consumer document(String identifier, public static Consumer document(String identifier, OperationRequestPreprocessor requestPreprocessor, Snippet... snippets) { return (result) -> new RestDocumentationGenerator<>(identifier, REQUEST_CONVERTER, RESPONSE_CONVERTER, - requestPreprocessor, snippets).handle(result, result, getRequiredConfiguration(result)); + requestPreprocessor, snippets).handle(result, result, retrieveConfiguration(result)); } /** @@ -110,7 +108,7 @@ public static Consumer document(String identifier, public static Consumer document(String identifier, OperationResponsePreprocessor responsePreprocessor, Snippet... snippets) { return (result) -> new RestDocumentationGenerator<>(identifier, REQUEST_CONVERTER, RESPONSE_CONVERTER, - responsePreprocessor, snippets).handle(result, result, getRequiredConfiguration(result)); + responsePreprocessor, snippets).handle(result, result, retrieveConfiguration(result)); } /** @@ -131,17 +129,12 @@ public static Consumer document(String identifier, Snippet... snippets) { return (result) -> new RestDocumentationGenerator<>(identifier, REQUEST_CONVERTER, RESPONSE_CONVERTER, requestPreprocessor, responsePreprocessor, snippets).handle(result, result, - getRequiredConfiguration(result)); + retrieveConfiguration(result)); } - private static Map getRequiredConfiguration(ExchangeResult result) { - Map config = WebTestClientRestDocumentationConfigurer + private static Map retrieveConfiguration(ExchangeResult result) { + Map configuration = WebTestClientRestDocumentationConfigurer .retrieveConfiguration(result.getRequestHeaders()); - Assert.state(config != null, - () -> String.format("There is no REST Docs configuration. Looks like '%s' " - + "was not invoked or configuration has already been removed. Please check your configuration.", - WebTestClientRestDocumentationConfigurer.class.getName())); - Map configuration = new HashMap<>(config); configuration.put(RestDocumentationGenerator.ATTRIBUTE_NAME_URL_TEMPLATE, result.getUriTemplate()); return configuration; } diff --git a/spring-restdocs-webtestclient/src/main/java/org/springframework/restdocs/webtestclient/WebTestClientRestDocumentationConfigurer.java b/spring-restdocs-webtestclient/src/main/java/org/springframework/restdocs/webtestclient/WebTestClientRestDocumentationConfigurer.java index f210d3ed6..e6d5299dc 100644 --- a/spring-restdocs-webtestclient/src/main/java/org/springframework/restdocs/webtestclient/WebTestClientRestDocumentationConfigurer.java +++ b/spring-restdocs-webtestclient/src/main/java/org/springframework/restdocs/webtestclient/WebTestClientRestDocumentationConfigurer.java @@ -29,6 +29,7 @@ import org.springframework.restdocs.RestDocumentationContextProvider; import org.springframework.restdocs.config.RestDocumentationConfigurer; import org.springframework.test.web.reactive.server.WebTestClient; +import org.springframework.util.Assert; import org.springframework.util.StringUtils; import org.springframework.web.reactive.function.client.ClientRequest; import org.springframework.web.reactive.function.client.ClientResponse; @@ -78,7 +79,10 @@ private Map createConfiguration() { static Map retrieveConfiguration(HttpHeaders headers) { String requestId = headers.getFirst(WebTestClient.WEBTESTCLIENT_REQUEST_ID); - return configurations.remove(requestId); + Map configuration = configurations.remove(requestId); + Assert.state(configuration != null, () -> "REST Docs configuration not found. Did you forget to register a " + + WebTestClientRestDocumentationConfigurer.class.getSimpleName() + " as a filter?"); + return configuration; } @Override diff --git a/spring-restdocs-webtestclient/src/test/java/org/springframework/restdocs/webtestclient/WebTestClientRestDocumentationConfigurerTests.java b/spring-restdocs-webtestclient/src/test/java/org/springframework/restdocs/webtestclient/WebTestClientRestDocumentationConfigurerTests.java index 920b85825..74a3a4aaf 100644 --- a/spring-restdocs-webtestclient/src/test/java/org/springframework/restdocs/webtestclient/WebTestClientRestDocumentationConfigurerTests.java +++ b/spring-restdocs-webtestclient/src/test/java/org/springframework/restdocs/webtestclient/WebTestClientRestDocumentationConfigurerTests.java @@ -29,6 +29,7 @@ import org.springframework.web.reactive.function.client.ExchangeFunction; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatIllegalStateException; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; @@ -51,7 +52,8 @@ public void configurationCanBeRetrievedButOnlyOnce() { .header(WebTestClient.WEBTESTCLIENT_REQUEST_ID, "1").build(); this.configurer.filter(request, mock(ExchangeFunction.class)); assertThat(WebTestClientRestDocumentationConfigurer.retrieveConfiguration(request.headers())).isNotNull(); - assertThat(WebTestClientRestDocumentationConfigurer.retrieveConfiguration(request.headers())).isNull(); + assertThatIllegalStateException() + .isThrownBy(() -> WebTestClientRestDocumentationConfigurer.retrieveConfiguration(request.headers())); } @Test diff --git a/spring-restdocs-webtestclient/src/test/java/org/springframework/restdocs/webtestclient/WebTestClientRestDocumentationIntegrationTests.java b/spring-restdocs-webtestclient/src/test/java/org/springframework/restdocs/webtestclient/WebTestClientRestDocumentationIntegrationTests.java index e09633fe9..06199f8c8 100644 --- a/spring-restdocs-webtestclient/src/test/java/org/springframework/restdocs/webtestclient/WebTestClientRestDocumentationIntegrationTests.java +++ b/spring-restdocs-webtestclient/src/test/java/org/springframework/restdocs/webtestclient/WebTestClientRestDocumentationIntegrationTests.java @@ -180,13 +180,9 @@ public void illegalStateExceptionShouldBeThrownWhenCallDocumentWebClientNotConfi assertThatThrownBy(() -> this.webTestClient .mutateWith((builder, httpHandlerBuilder, connector) -> builder.filters(List::clear).build()).get() .uri("/").exchange().expectBody().consumeWith(document("default-snippets"))) - .isInstanceOf(IllegalStateException.class).hasMessageContaining(missingConfiguration()); - } - - private String missingConfiguration() { - return "There is no REST Docs configuration. Looks like " - + "'org.springframework.restdocs.webtestclient.WebTestClientRestDocumentationConfigurer' " - + "was not invoked or configuration has already been removed. Please check your configuration."; + .isInstanceOf(IllegalStateException.class) + .hasMessage("REST Docs configuration not found. Did you forget to register a " + + "WebTestClientRestDocumentationConfigurer as a filter?"); } private void assertExpectedSnippetFilesExist(File directory, String... snippets) { From 015468685ed9009510b1f20dbb176b63b350d5ff Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Fri, 30 Aug 2019 17:59:28 +0100 Subject: [PATCH 062/502] Upgrade the Grails sample to Grails 3.3.9 --- samples/rest-notes-grails/gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/rest-notes-grails/gradle.properties b/samples/rest-notes-grails/gradle.properties index 7593b7f9b..edafcff0a 100644 --- a/samples/rest-notes-grails/gradle.properties +++ b/samples/rest-notes-grails/gradle.properties @@ -1 +1 @@ -grailsVersion=3.3.2 +grailsVersion=3.3.9 From d586d9f15bdb032b67b026ecac1eaa82cd693ef2 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Sat, 31 Aug 2019 07:59:43 +0100 Subject: [PATCH 063/502] Drop the Grails 3 sample as it is incompatible with Framework 5 Closes gh-637 --- build.gradle | 4 - docs/src/docs/asciidoc/getting-started.adoc | 5 - samples/rest-notes-grails/.gitignore | 10 - samples/rest-notes-grails/README.md | 93 ---------- samples/rest-notes-grails/build.gradle | 101 ---------- samples/rest-notes-grails/gradle.properties | 1 - .../gradle/wrapper/gradle-wrapper.jar | Bin 54329 -> 0 bytes .../gradle/wrapper/gradle-wrapper.properties | 5 - samples/rest-notes-grails/gradlew | 172 ------------------ samples/rest-notes-grails/gradlew.bat | 84 --------- .../grails-app/conf/application.yml | 100 ---------- .../grails-app/conf/logback.groovy | 39 ---- .../grails-app/conf/spring/resources.groovy | 2 - .../com/example/UrlMappings.groovy | 28 --- .../grails-app/domain/com/example/Note.groovy | 37 ---- .../grails-app/domain/com/example/Tag.groovy | 36 ---- .../grails-app/i18n/messages.properties | 56 ------ .../init/com/example/Application.groovy | 28 --- .../init/com/example/BootStrap.groovy | 31 ---- .../grails-app/views/error.gson | 6 - .../grails-app/views/notFound.gson | 6 - samples/rest-notes-grails/settings.gradle | 0 .../src/docs/asciidoc/index.adoc | 98 ---------- .../com/example/ApiDocumentationSpec.groovy | 138 -------------- 24 files changed, 1080 deletions(-) delete mode 100644 samples/rest-notes-grails/.gitignore delete mode 100644 samples/rest-notes-grails/README.md delete mode 100644 samples/rest-notes-grails/build.gradle delete mode 100644 samples/rest-notes-grails/gradle.properties delete mode 100644 samples/rest-notes-grails/gradle/wrapper/gradle-wrapper.jar delete mode 100644 samples/rest-notes-grails/gradle/wrapper/gradle-wrapper.properties delete mode 100755 samples/rest-notes-grails/gradlew delete mode 100644 samples/rest-notes-grails/gradlew.bat delete mode 100644 samples/rest-notes-grails/grails-app/conf/application.yml delete mode 100644 samples/rest-notes-grails/grails-app/conf/logback.groovy delete mode 100644 samples/rest-notes-grails/grails-app/conf/spring/resources.groovy delete mode 100644 samples/rest-notes-grails/grails-app/controllers/com/example/UrlMappings.groovy delete mode 100644 samples/rest-notes-grails/grails-app/domain/com/example/Note.groovy delete mode 100644 samples/rest-notes-grails/grails-app/domain/com/example/Tag.groovy delete mode 100644 samples/rest-notes-grails/grails-app/i18n/messages.properties delete mode 100644 samples/rest-notes-grails/grails-app/init/com/example/Application.groovy delete mode 100644 samples/rest-notes-grails/grails-app/init/com/example/BootStrap.groovy delete mode 100644 samples/rest-notes-grails/grails-app/views/error.gson delete mode 100644 samples/rest-notes-grails/grails-app/views/notFound.gson delete mode 100644 samples/rest-notes-grails/settings.gradle delete mode 100644 samples/rest-notes-grails/src/docs/asciidoc/index.adoc delete mode 100644 samples/rest-notes-grails/src/integration-test/groovy/com/example/ApiDocumentationSpec.groovy diff --git a/build.gradle b/build.gradle index d3ecc5e97..ec598de2e 100644 --- a/build.gradle +++ b/build.gradle @@ -180,10 +180,6 @@ samples { dependOn 'spring-restdocs-webtestclient:install' dependOn 'spring-restdocs-asciidoctor:install' - restNotesGrails { - workingDir "$projectDir/samples/rest-notes-grails" - } - restNotesSpringHateoas { workingDir "$projectDir/samples/rest-notes-spring-hateoas" } diff --git a/docs/src/docs/asciidoc/getting-started.adoc b/docs/src/docs/asciidoc/getting-started.adoc index 8ce277be9..b9a9ef4b1 100644 --- a/docs/src/docs/asciidoc/getting-started.adoc +++ b/docs/src/docs/asciidoc/getting-started.adoc @@ -44,11 +44,6 @@ If you want to jump straight in, a number of sample applications are available: |=== | Sample | Build system | Description -| {samples}/rest-notes-grails[Grails] -| Gradle -| Demonstrates the use of Spring REST docs with https://grails.org[Grails] and - https://github.com/spockframework/spock[Spock]. - | {samples}/rest-assured[REST Assured] | Gradle | Demonstrates the use of Spring REST Docs with http://rest-assured.io[REST Assured]. diff --git a/samples/rest-notes-grails/.gitignore b/samples/rest-notes-grails/.gitignore deleted file mode 100644 index 801345f8a..000000000 --- a/samples/rest-notes-grails/.gitignore +++ /dev/null @@ -1,10 +0,0 @@ -.gradle -build/ -classes/ -.idea -*.iml -*.ipr -*.iws -.project -.settings -.classpath \ No newline at end of file diff --git a/samples/rest-notes-grails/README.md b/samples/rest-notes-grails/README.md deleted file mode 100644 index 0e62fb32b..000000000 --- a/samples/rest-notes-grails/README.md +++ /dev/null @@ -1,93 +0,0 @@ -# rest-notes-grails - -## Overview - -This is a sample project using Grails 3, Spock, and Spring REST docs. For more -information about the Grails framework please see [grails.org](https://grails.org). - -Grails is built on top of Spring Boot and Gradle so there are a few different ways to -run this project including: - -### Gradle Wrapper (recommended) - -The gradle wrapper allows a project to build without having Gradle installed locally. The -executable file will acquire the version of Gradle and other dependencies recommended for -this project. This is especially important since some versions of Gradle may cause -conflicts with this project. - -On Unix-like platforms, such as Linux and Mac OS X: - -``` -$ ./gradlew run -``` - -On Windows: - -``` -$ gradlew run -``` - -*Please note*, if you are including integration tests in Grails, they will not run as -part of the `gradle test` task. Run them via the build task or individually as -`gradle integrationTest` - -### Gradle Command Line - -Clean the project: - -``` -$ gradle clean -``` - -Build the project: - -``` -$ gradle build -``` - -Run the project: - -``` -$ gradle run -``` - -### Grails Command Line - -Grails applications also have a command line feature useful for code generation and -running projects locally. The command line is accessible by typing `grails` in the -terminal at the root of the project. Please ensure you are running the correct version -of Grails as specified in [gradle.properties](gradle.properties) - -Similar to `gradle clean`, this task destroys the `build` directory and cached assets. - -``` -grails> clean -``` - -The 'test-app' task runs all of the tests for the project. - -``` -grails> test-app -``` - -The `run-app` task is used to run the application locally. By default, the project is -run in development mode including automatic reloading and not caching static assets. It -is not suggested to use this in production. - -``` -grails> run-app -``` - -### Building and Viewing the Docs - -This is an example of the Grails API profile. Therefore, there is no view layer to -return the docs as static assets. The result of running `asciidoctor` or `build` is that -the docs are sent to `/build/asciidoc/`. You can then publish them to a destination of -your choosing using the [gradle github-pages](https://github.com/ajoberstar/gradle-git) -plugin or similar. - -To just generate documentation and not run the application use: - -``` -$ ./gradlew asciidoctor -``` diff --git a/samples/rest-notes-grails/build.gradle b/samples/rest-notes-grails/build.gradle deleted file mode 100644 index 8af0afb79..000000000 --- a/samples/rest-notes-grails/build.gradle +++ /dev/null @@ -1,101 +0,0 @@ -buildscript { - repositories { - mavenCentral() - maven { url "https://repo.grails.org/grails/core" } - } - dependencies { - classpath "org.grails:grails-gradle-plugin:$grailsVersion" - classpath "org.grails.plugins:hibernate5:6.0.7" - } -} - -plugins { - id 'org.asciidoctor.convert' version '1.5.3' -} - -version "0.1" -group "com.example" - -apply plugin: "war" -apply plugin: "eclipse" -apply plugin: "idea" -apply plugin: "org.grails.grails-web" - -ext { - restDocsVersion = "2.0.4.BUILD-SNAPSHOT" - snippetsDir = file('src/docs/generated-snippets') -} - -repositories { - mavenLocal() - maven { url 'https://repo.spring.io/libs-snapshot' } - maven { url "https://repo.grails.org/grails/core" } -} - -dependencyManagement { - dependencies { - dependency "org.springframework.restdocs:spring-restdocs-core:$restDocsVersion" - dependency "org.springframework.restdocs:spring-restdocs-restassured:$restDocsVersion" - dependency "org.springframework.restdocs:spring-restdocs-asciidoctor:$restDocsVersion" - } - imports { - mavenBom "org.grails:grails-bom:$grailsVersion" - } - applyMavenExclusions false -} - -dependencies { - asciidoctor "org.springframework.restdocs:spring-restdocs-asciidoctor" - - compile "org.springframework.boot:spring-boot-starter-logging" - compile "org.springframework.boot:spring-boot-autoconfigure" - compile "org.springframework.boot:spring-boot-starter-actuator" - compile "org.springframework.boot:spring-boot-starter-tomcat" - compile "org.grails:grails-core" - compile "org.grails:grails-plugin-url-mappings" - compile "org.grails:grails-plugin-rest" - compile "org.grails:grails-plugin-codecs" - compile "org.grails:grails-plugin-interceptors" - compile "org.grails:grails-plugin-services" - compile "org.grails:grails-plugin-datasource" - compile "org.grails:grails-plugin-databinding" - compile "org.grails.plugins:async" - compile "org.grails:grails-web-boot" - compile "org.grails:grails-logging" - compile "org.grails.plugins:cache" - compile "org.grails.plugins:hibernate5" - compile "org.hibernate:hibernate-core:5.1.2.Final" - compile "org.hibernate:hibernate-ehcache:5.1.2.Final" - compile "org.grails.plugins:views-json" - compile "org.grails.plugins:views-json-templates" - console "org.grails:grails-console" - - profile "org.grails.profiles:rest-api" - - runtime "com.h2database:h2" - runtime 'org.apache.tomcat:tomcat-jdbc' - - testCompile "io.rest-assured:rest-assured:3.0.2" - testCompile "org.grails:grails-test-mixins:3.3.0" - testCompile "org.grails.plugins:geb" - testCompile "org.grails:grails-datastore-rest-client" - testCompile "org.springframework.restdocs:spring-restdocs-restassured" - - testRuntime "org.seleniumhq.selenium:selenium-htmlunit-driver:2.47.1" - testRuntime "net.sourceforge.htmlunit:htmlunit:2.18" -} - -ext { - snippetsDir = file('build/generated-snippets') -} - -test { - outputs.dir snippetsDir -} - -asciidoctor { - dependsOn integrationTest - inputs.dir snippetsDir -} - -build.dependsOn asciidoctor diff --git a/samples/rest-notes-grails/gradle.properties b/samples/rest-notes-grails/gradle.properties deleted file mode 100644 index edafcff0a..000000000 --- a/samples/rest-notes-grails/gradle.properties +++ /dev/null @@ -1 +0,0 @@ -grailsVersion=3.3.9 diff --git a/samples/rest-notes-grails/gradle/wrapper/gradle-wrapper.jar b/samples/rest-notes-grails/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index 01b8bf6b1f99cad9213fc495b33ad5bbab8efd20..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 54329 zcmagFV|ZrKvM!pAZQHhO+qP}9lTNj?q^^Y^VFp)SH8qbSJ)2BQ2giqeFT zAwqu@)c?v~^Z#E_K}1nTQbJ9gQ9<%vVRAxVj)8FwL5_iTdUB>&m3fhE=kRWl;g`&m z!W5kh{WsV%fO*%je&j+Lv4xxK~zsEYQls$Q-p&dwID|A)!7uWtJF-=Tm1{V@#x*+kUI$=%KUuf2ka zjiZ{oiL1MXE2EjciJM!jrjFNwCh`~hL>iemrqwqnX?T*MX;U>>8yRcZb{Oy+VKZos zLiFKYPw=LcaaQt8tj=eoo3-@bG_342HQ%?jpgAE?KCLEHC+DmjxAfJ%Og^$dpC8Xw zAcp-)tfJm}BPNq_+6m4gBgBm3+CvmL>4|$2N$^Bz7W(}fz1?U-u;nE`+9`KCLuqg} zwNstNM!J4Uw|78&Y9~9>MLf56to!@qGkJw5Thx%zkzj%Ek9Nn1QA@8NBXbwyWC>9H z#EPwjMNYPigE>*Ofz)HfTF&%PFj$U6mCe-AFw$U%-L?~-+nSXHHKkdgC5KJRTF}`G zE_HNdrE}S0zf4j{r_f-V2imSqW?}3w-4=f@o@-q+cZgaAbZ((hn))@|eWWhcT2pLpTpL!;_5*vM=sRL8 zqU##{U#lJKuyqW^X$ETU5ETeEVzhU|1m1750#f}38_5N9)B_2|v@1hUu=Kt7-@dhA zq_`OMgW01n`%1dB*}C)qxC8q;?zPeF_r;>}%JYmlER_1CUbKa07+=TV45~symC*g8 zW-8(gag#cAOuM0B1xG8eTp5HGVLE}+gYTmK=`XVVV*U!>H`~j4+ROIQ+NkN$LY>h4 zqpwdeE_@AX@PL};e5vTn`Ro(EjHVf$;^oiA%@IBQq>R7_D>m2D4OwwEepkg}R_k*M zM-o;+P27087eb+%*+6vWFCo9UEGw>t&WI17Pe7QVuoAoGHdJ(TEQNlJOqnjZ8adCb zI`}op16D@v7UOEo%8E-~m?c8FL1utPYlg@m$q@q7%mQ4?OK1h%ODjTjFvqd!C z-PI?8qX8{a@6d&Lb_X+hKxCImb*3GFemm?W_du5_&EqRq!+H?5#xiX#w$eLti-?E$;Dhu`{R(o>LzM4CjO>ICf z&DMfES#FW7npnbcuqREgjPQM#gs6h>`av_oEWwOJZ2i2|D|0~pYd#WazE2Bbsa}X@ zu;(9fi~%!VcjK6)?_wMAW-YXJAR{QHxrD5g(ou9mR6LPSA4BRG1QSZT6A?kelP_g- zH(JQjLc!`H4N=oLw=f3{+WmPA*s8QEeEUf6Vg}@!xwnsnR0bl~^2GSa5vb!Yl&4!> zWb|KQUsC$lT=3A|7vM9+d;mq=@L%uWKwXiO9}a~gP4s_4Yohc!fKEgV7WbVo>2ITbE*i`a|V!^p@~^<={#?Gz57 zyPWeM2@p>D*FW#W5Q`1`#5NW62XduP1XNO(bhg&cX`-LYZa|m-**bu|>}S;3)eP8_ zpNTnTfm8 ze+7wDH3KJ95p)5tlwk`S7mbD`SqHnYD*6`;gpp8VdHDz%RR_~I_Ar>5)vE-Pgu7^Y z|9Px+>pi3!DV%E%4N;ii0U3VBd2ZJNUY1YC^-e+{DYq+l@cGtmu(H#Oh%ibUBOd?C z{y5jW3v=0eV0r@qMLgv1JjZC|cZ9l9Q)k1lLgm))UR@#FrJd>w^`+iy$c9F@ic-|q zVHe@S2UAnc5VY_U4253QJxm&Ip!XKP8WNcnx9^cQ;KH6PlW8%pSihSH2(@{2m_o+m zr((MvBja2ctg0d0&U5XTD;5?d?h%JcRJp{_1BQW1xu&BrA3(a4Fh9hon-ly$pyeHq zG&;6q?m%NJ36K1Sq_=fdP(4f{Hop;_G_(i?sPzvB zDM}>*(uOsY0I1j^{$yn3#U(;B*g4cy$-1DTOkh3P!LQ;lJlP%jY8}Nya=h8$XD~%Y zbV&HJ%eCD9nui-0cw!+n`V~p6VCRqh5fRX z8`GbdZ@73r7~myQLBW%db;+BI?c-a>Y)m-FW~M=1^|<21_Sh9RT3iGbO{o-hpN%d6 z7%++#WekoBOP^d0$$|5npPe>u3PLvX_gjH2x(?{&z{jJ2tAOWTznPxv-pAv<*V7r$ z6&glt>7CAClWz6FEi3bToz-soY^{ScrjwVPV51=>n->c(NJngMj6TyHty`bfkF1hc zkJS%A@cL~QV0-aK4>Id!9dh7>0IV;1J9(myDO+gv76L3NLMUm9XyPauvNu$S<)-|F zZS}(kK_WnB)Cl`U?jsdYfAV4nrgzIF@+%1U8$poW&h^c6>kCx3;||fS1_7JvQT~CV zQ8Js+!p)3oW>Df(-}uqC`Tcd%E7GdJ0p}kYj5j8NKMp(KUs9u7?jQ94C)}0rba($~ zqyBx$(1ae^HEDG`Zc@-rXk1cqc7v0wibOR4qpgRDt#>-*8N3P;uKV0CgJE2SP>#8h z=+;i_CGlv+B^+$5a}SicVaSeaNn29K`C&=}`=#Nj&WJP9Xhz4mVa<+yP6hkrq1vo= z1rX4qg8dc4pmEvq%NAkpMK>mf2g?tg_1k2%v}<3`$6~Wlq@ItJ*PhHPoEh1Yi>v57 z4k0JMO)*=S`tKvR5gb-(VTEo>5Y>DZJZzgR+j6{Y`kd|jCVrg!>2hVjz({kZR z`dLlKhoqT!aI8=S+fVp(5*Dn6RrbpyO~0+?fy;bm$0jmTN|t5i6rxqr4=O}dY+ROd zo9Et|x}!u*xi~>-y>!M^+f&jc;IAsGiM_^}+4|pHRn{LThFFpD{bZ|TA*wcGm}XV^ zr*C6~@^5X-*R%FrHIgo-hJTBcyQ|3QEj+cSqp#>&t`ZzB?cXM6S(lRQw$I2?m5=wd z78ki`R?%;o%VUhXH?Z#(uwAn9$m`npJ=cA+lHGk@T7qq_M6Zoy1Lm9E0UUysN)I_x zW__OAqvku^>`J&CB=ie@yNWsaFmem}#L3T(x?a`oZ+$;3O-icj2(5z72Hnj=9Z0w% z<2#q-R=>hig*(t0^v)eGq2DHC%GymE-_j1WwBVGoU=GORGjtaqr0BNigOCqyt;O(S zKG+DoBsZU~okF<7ahjS}bzwXxbAxFfQAk&O@>LsZMsZ`?N?|CDWM(vOm%B3CBPC3o z%2t@%H$fwur}SSnckUm0-k)mOtht`?nwsDz=2#v=RBPGg39i#%odKq{K^;bTD!6A9 zskz$}t)sU^=a#jLZP@I=bPo?f-L}wpMs{Tc!m7-bi!Ldqj3EA~V;4(dltJmTXqH0r z%HAWKGutEc9vOo3P6Q;JdC^YTnby->VZ6&X8f{obffZ??1(cm&L2h7q)*w**+sE6dG*;(H|_Q!WxU{g)CeoT z(KY&bv!Usc|m+Fqfmk;h&RNF|LWuNZ!+DdX*L=s-=_iH=@i` z?Z+Okq^cFO4}_n|G*!)Wl_i%qiMBaH8(WuXtgI7EO=M>=i_+;MDjf3aY~6S9w0K zUuDO7O5Ta6+k40~xh~)D{=L&?Y0?c$s9cw*Ufe18)zzk%#ZY>Tr^|e%8KPb0ht`b( zuP@8#Ox@nQIqz9}AbW0RzE`Cf>39bOWz5N3qzS}ocxI=o$W|(nD~@EhW13Rj5nAp; zu2obEJa=kGC*#3=MkdkWy_%RKcN=?g$7!AZ8vBYKr$ePY(8aIQ&yRPlQ=mudv#q$q z4%WzAx=B{i)UdLFx4os?rZp6poShD7Vc&mSD@RdBJ=_m^&OlkEE1DFU@csgKcBifJ zz4N7+XEJhYzzO=86 z#%eBQZ$Nsf2+X0XPHUNmg#(sNt^NW1Y0|M(${e<0kW6f2q5M!2YE|hSEQ*X-%qo(V zHaFwyGZ0on=I{=fhe<=zo{=Og-_(to3?cvL4m6PymtNsdDINsBh8m>a%!5o3s(en) z=1I z6O+YNertC|OFNqd6P=$gMyvmfa`w~p9*gKDESFqNBy(~Zw3TFDYh}$iudn)9HxPBi zdokK@o~nu?%imcURr5Y~?6oo_JBe}t|pU5qjai|#JDyG=i^V~7+a{dEnO<(y>ahND#_X_fcEBNiZ)uc&%1HVtx8Ts z*H_Btvx^IhkfOB#{szN*n6;y05A>3eARDXslaE>tnLa>+`V&cgho?ED+&vv5KJszf zG4@G;7i;4_bVvZ>!mli3j7~tPgybF5|J6=Lt`u$D%X0l}#iY9nOXH@(%FFJLtzb%p zzHfABnSs;v-9(&nzbZytLiqqDIWzn>JQDk#JULcE5CyPq_m#4QV!}3421haQ+LcfO*>r;rg6K|r#5Sh|y@h1ao%Cl)t*u`4 zMTP!deC?aL7uTxm5^nUv#q2vS-5QbBKP|drbDXS%erB>fYM84Kpk^au99-BQBZR z7CDynflrIAi&ahza+kUryju5LR_}-Z27g)jqOc(!Lx9y)e z{cYc&_r947s9pteaa4}dc|!$$N9+M38sUr7h(%@Ehq`4HJtTpA>B8CLNO__@%(F5d z`SmX5jbux6i#qc}xOhumzbAELh*Mfr2SW99=WNOZRZgoCU4A2|4i|ZVFQt6qEhH#B zK_9G;&h*LO6tB`5dXRSBF0hq0tk{2q__aCKXYkP#9n^)@cq}`&Lo)1KM{W+>5mSed zKp~=}$p7>~nK@va`vN{mYzWN1(tE=u2BZhga5(VtPKk(*TvE&zmn5vSbjo zZLVobTl%;t@6;4SsZ>5+U-XEGUZGG;+~|V(pE&qqrp_f~{_1h@5ZrNETqe{bt9ioZ z#Qn~gWCH!t#Ha^n&fT2?{`}D@s4?9kXj;E;lWV9Zw8_4yM0Qg-6YSsKgvQ*fF{#Pq z{=(nyV>#*`RloBVCs;Lp*R1PBIQOY=EK4CQa*BD0MsYcg=opP?8;xYQDSAJBeJpw5 zPBc_Ft9?;<0?pBhCmOtWU*pN*;CkjJ_}qVic`}V@$TwFi15!mF1*m2wVX+>5p%(+R zQ~JUW*zWkalde{90@2v+oVlkxOZFihE&ZJ){c?hX3L2@R7jk*xjYtHi=}qb+4B(XJ z$gYcNudR~4Kz_WRq8eS((>ALWCO)&R-MXE+YxDn9V#X{_H@j616<|P(8h(7z?q*r+ zmpqR#7+g$cT@e&(%_|ipI&A%9+47%30TLY(yuf&*knx1wNx|%*H^;YB%ftt%5>QM= z^i;*6_KTSRzQm%qz*>cK&EISvF^ovbS4|R%)zKhTH_2K>jP3mBGn5{95&G9^a#4|K zv+!>fIsR8z{^x4)FIr*cYT@Q4Z{y}};rLHL+atCgHbfX*;+k&37DIgENn&=k(*lKD zG;uL-KAdLn*JQ?@r6Q!0V$xXP=J2i~;_+i3|F;_En;oAMG|I-RX#FwnmU&G}w`7R{ z788CrR-g1DW4h_`&$Z`ctN~{A)Hv_-Bl!%+pfif8wN32rMD zJDs$eVWBYQx1&2sCdB0!vU5~uf)=vy*{}t{2VBpcz<+~h0wb7F3?V^44*&83Z2#F` z32!rd4>uc63rQP$3lTH3zb-47IGR}f)8kZ4JvX#toIpXH`L%NnPDE~$QI1)0)|HS4 zVcITo$$oWWwCN@E-5h>N?Hua!N9CYb6f8vTFd>h3q5Jg-lCI6y%vu{Z_Uf z$MU{{^o~;nD_@m2|E{J)q;|BK7rx%`m``+OqZAqAVj-Dy+pD4-S3xK?($>wn5bi90CFAQ+ACd;&m6DQB8_o zjAq^=eUYc1o{#+p+ zn;K<)Pn*4u742P!;H^E3^Qu%2dM{2slouc$AN_3V^M7H_KY3H)#n7qd5_p~Za7zAj|s9{l)RdbV9e||_67`#Tu*c<8!I=zb@ z(MSvQ9;Wrkq6d)!9afh+G`!f$Ip!F<4ADdc*OY-y7BZMsau%y?EN6*hW4mOF%Q~bw z2==Z3^~?q<1GTeS>xGN-?CHZ7a#M4kDL zQxQr~1ZMzCSKFK5+32C%+C1kE#(2L=15AR!er7GKbp?Xd1qkkGipx5Q~FI-6zt< z*PTpeVI)Ngnnyaz5noIIgNZtb4bQdKG{Bs~&tf)?nM$a;7>r36djllw%hQxeCXeW^ z(i6@TEIuxD<2ulwLTt|&gZP%Ei+l!(%p5Yij6U(H#HMkqM8U$@OKB|5@vUiuY^d6X zW}fP3;Kps6051OEO(|JzmVU6SX(8q>*yf*x5QoxDK={PH^F?!VCzES_Qs>()_y|jg6LJlJWp;L zKM*g5DK7>W_*uv}{0WUB0>MHZ#oJZmO!b3MjEc}VhsLD~;E-qNNd?x7Q6~v zR=0$u>Zc2Xr}>x_5$-s#l!oz6I>W?lw;m9Ae{Tf9eMX;TI-Wf_mZ6sVrMnY#F}cDd z%CV*}fDsXUF7Vbw>PuDaGhu631+3|{xp<@Kl|%WxU+vuLlcrklMC!Aq+7n~I3cmQ! z`e3cA!XUEGdEPSu``&lZEKD1IKO(-VGvcnSc153m(i!8ohi`)N2n>U_BemYJ`uY>8B*Epj!oXRLV}XK}>D*^DHQ7?NY*&LJ9VSo`Ogi9J zGa;clWI8vIQqkngv2>xKd91K>?0`Sw;E&TMg&6dcd20|FcTsnUT7Yn{oI5V4@Ow~m zz#k~8TM!A9L7T!|colrC0P2WKZW7PNj_X4MfESbt<-soq*0LzShZ}fyUx!(xIIDwx zRHt^_GAWe0-Vm~bDZ(}XG%E+`XhKpPlMBo*5q_z$BGxYef8O!ToS8aT8pmjbPq)nV z%x*PF5ZuSHRJqJ!`5<4xC*xb2vC?7u1iljB_*iUGl6+yPyjn?F?GOF2_KW&gOkJ?w z3e^qc-te;zez`H$rsUCE0<@7PKGW?7sT1SPYWId|FJ8H`uEdNu4YJjre`8F*D}6Wh z|FQ`xf7yiphHIAkU&OYCn}w^ilY@o4larl?^M7&8YI;hzBIsX|i3UrLsx{QDKwCX< zy;a>yjfJ6!sz`NcVi+a!Fqk^VE^{6G53L?@Tif|j!3QZ0fk9QeUq8CWI;OmO-Hs+F zuZ4sHLA3{}LR2Qlyo+{d@?;`tpp6YB^BMoJt?&MHFY!JQwoa0nTSD+#Ku^4b{5SZVFwU9<~APYbaLO zu~Z)nS#dxI-5lmS-Bnw!(u15by(80LlC@|ynj{TzW)XcspC*}z0~8VRZq>#Z49G`I zgl|C#H&=}n-ajxfo{=pxPV(L*7g}gHET9b*s=cGV7VFa<;Htgjk>KyW@S!|z`lR1( zGSYkEl&@-bZ*d2WQ~hw3NpP=YNHF^XC{TMG$Gn+{b6pZn+5=<()>C!N^jncl0w6BJ zdHdnmSEGK5BlMeZD!v4t5m7ct7{k~$1Ie3GLFoHjAH*b?++s<|=yTF+^I&jT#zuMx z)MLhU+;LFk8bse|_{j+d*a=&cm2}M?*arjBPnfPgLwv)86D$6L zLJ0wPul7IenMvVAK$z^q5<^!)7aI|<&GGEbOr=E;UmGOIa}yO~EIr5xWU_(ol$&fa zR5E(2vB?S3EvJglTXdU#@qfDbCYs#82Yo^aZN6`{Ex#M)easBTe_J8utXu(fY1j|R z9o(sQbj$bKU{IjyhosYahY{63>}$9_+hWxB3j}VQkJ@2$D@vpeRSldU?&7I;qd2MF zSYmJ>zA(@N_iK}m*AMPIJG#Y&1KR)6`LJ83qg~`Do3v^B0>fU&wUx(qefuTgzFED{sJ65!iw{F2}1fQ3= ziFIP{kezQxmlx-!yo+sC4PEtG#K=5VM9YIN0z9~c4XTX?*4e@m;hFM!zVo>A`#566 z>f&3g94lJ{r)QJ5m7Xe3SLau_lOpL;A($wsjHR`;xTXgIiZ#o&vt~ zGR6KdU$FFbLfZCC3AEu$b`tj!9XgOGLSV=QPIYW zjI!hSP#?8pn0@ezuenOzoka8!8~jXTbiJ6+ZuItsWW03uzASFyn*zV2kIgPFR$Yzm zE<$cZlF>R8?Nr2_i?KiripBc+TGgJvG@vRTY2o?(_Di}D30!k&CT`>+7ry2!!iC*X z<@=U0_C#16=PN7bB39w+zPwDOHX}h20Ap);dx}kjXX0-QkRk=cr};GYsjSvyLZa-t zzHONWddi*)RDUH@RTAsGB_#&O+QJaaL+H<<9LLSE+nB@eGF1fALwjVOl8X_sdOYme z0lk!X=S(@25=TZHR7LlPp}fY~yNeThMIjD}pd9+q=j<_inh0$>mIzWVY+Z9p<{D^#0Xk+b_@eNSiR8;KzSZ#7lUsk~NGMcB8C2c=m2l5paHPq`q{S(kdA7Z1a zyfk2Y;w?^t`?@yC5Pz9&pzo}Hc#}mLgDmhKV|PJ3lKOY(Km@Fi2AV~CuET*YfUi}u zfInZnqDX(<#vaS<^fszuR=l)AbqG{}9{rnyx?PbZz3Pyu!eSJK`uwkJU!ORQXy4x83r!PNgOyD33}}L=>xX_93l6njNTuqL8J{l%*3FVn3MG4&Fv*`lBXZ z?=;kn6HTT^#SrPX-N)4EZiIZI!0ByXTWy;;J-Tht{jq1mjh`DSy7yGjHxIaY%*sTx zuy9#9CqE#qi>1misx=KRWm=qx4rk|}vd+LMY3M`ow8)}m$3Ggv&)Ri*ON+}<^P%T5 z_7JPVPfdM=Pv-oH<tecoE}(0O7|YZc*d8`Uv_M*3Rzv7$yZnJE6N_W=AQ3_BgU_TjA_T?a)U1csCmJ&YqMp-lJe`y6>N zt++Bi;ZMOD%%1c&-Q;bKsYg!SmS^#J@8UFY|G3!rtyaTFb!5@e(@l?1t(87ln8rG? z--$1)YC~vWnXiW3GXm`FNSyzu!m$qT=Eldf$sMl#PEfGmzQs^oUd=GIQfj(X=}dw+ zT*oa0*oS%@cLgvB&PKIQ=Ok?>x#c#dC#sQifgMwtAG^l3D9nIg(Zqi;D%807TtUUCL3_;kjyte#cAg?S%e4S2W>9^A(uy8Ss0Tc++ZTjJw1 z&Em2g!3lo@LlDyri(P^I8BPpn$RE7n*q9Q-c^>rfOMM6Pd5671I=ZBjAvpj8oIi$! zl0exNl(>NIiQpX~FRS9UgK|0l#s@#)p4?^?XAz}Gjb1?4Qe4?j&cL$C8u}n)?A@YC zfmbSM`Hl5pQFwv$CQBF=_$Sq zxsV?BHI5bGZTk?B6B&KLdIN-40S426X3j_|ceLla*M3}3gx3(_7MVY1++4mzhH#7# zD>2gTHy*%i$~}mqc#gK83288SKp@y3wz1L_e8fF$Rb}ex+`(h)j}%~Ld^3DUZkgez zOUNy^%>>HHE|-y$V@B}-M|_{h!vXpk01xaD%{l{oQ|~+^>rR*rv9iQen5t?{BHg|% zR`;S|KtUb!X<22RTBA4AAUM6#M?=w5VY-hEV)b`!y1^mPNEoy2K)a>OyA?Q~Q*&(O zRzQI~y_W=IPi?-OJX*&&8dvY0zWM2%yXdFI!D-n@6FsG)pEYdJbuA`g4yy;qrgR?G z8Mj7gv1oiWq)+_$GqqQ$(ZM@#|0j7})=#$S&hZwdoijFI4aCFLVI3tMH5fLreZ;KD zqA`)0l~D2tuIBYOy+LGw&hJ5OyE+@cnZ0L5+;yo2pIMdt@4$r^5Y!x7nHs{@>|W(MzJjATyWGNwZ^4j+EPU0RpAl-oTM@u{lx*i0^yyWPfHt6QwPvYpk9xFMWfBFt!+Gu6TlAmr zeQ#PX71vzN*_-xh&__N`IXv6`>CgV#eA_%e@7wjgkj8jlKzO~Ic6g$cT`^W{R{606 zCDP~+NVZ6DMO$jhL~#+!g*$T!XW63#(ngDn#Qwy71yj^gazS{e;3jGRM0HedGD@pt z?(ln3pCUA(ekqAvvnKy0G@?-|-dh=eS%4Civ&c}s%wF@0K5Bltaq^2Os1n6Z3%?-Q zAlC4goQ&vK6TpgtzkHVt*1!tBYt-`|5HLV1V7*#45Vb+GACuU+QB&hZ=N_flPy0TY zR^HIrdskB#<$aU;HY(K{a3(OQa$0<9qH(oa)lg@Uf>M5g2W0U5 zk!JSlhrw8quBx9A>RJ6}=;W&wt@2E$7J=9SVHsdC?K(L(KACb#z)@C$xXD8^!7|uv zZh$6fkq)aoD}^79VqdJ!Nz-8$IrU(_-&^cHBI;4 z^$B+1aPe|LG)C55LjP;jab{dTf$0~xbXS9!!QdcmDYLbL^jvxu2y*qnx2%jbL%rB z{aP85qBJe#(&O~Prk%IJARcdEypZ)vah%ZZ%;Zk{eW(U)Bx7VlzgOi8)x z`rh4l`@l_Ada7z&yUK>ZF;i6YLGwI*Sg#Fk#Qr0Jg&VLax(nNN$u-XJ5=MsP3|(lEdIOJ7|(x3iY;ea)5#BW*mDV%^=8qOeYO&gIdJVuLLN3cFaN=xZtFB=b zH{l)PZl_j^u+qx@89}gAQW7ofb+k)QwX=aegihossZq*+@PlCpb$rpp>Cbk9UJO<~ zDjlXQ_Ig#W0zdD3&*ei(FwlN#3b%FSR%&M^ywF@Fr>d~do@-kIS$e%wkIVfJ|Ohh=zc zF&Rnic^|>@R%v?@jO}a9;nY3Qrg_!xC=ZWUcYiA5R+|2nsM*$+c$TOs6pm!}Z}dfM zGeBhMGWw3$6KZXav^>YNA=r6Es>p<6HRYcZY)z{>yasbC81A*G-le8~QoV;rtKnkx z;+os8BvEe?0A6W*a#dOudsv3aWs?d% z0oNngyVMjavLjtjiG`!007#?62ClTqqU$@kIY`=x^$2e>iqIy1>o|@Tw@)P)B8_1$r#6>DB_5 zmaOaoE~^9TolgDgooKFuEFB#klSF%9-~d2~_|kQ0Y{Ek=HH5yq9s zDq#1S551c`kSiWPZbweN^A4kWiP#Qg6er1}HcKv{fxb1*BULboD0fwfaNM_<55>qM zETZ8TJDO4V)=aPp_eQjX%||Ud<>wkIzvDlpNjqW>I}W!-j7M^TNe5JIFh#-}zAV!$ICOju8Kx)N z0vLtzDdy*rQN!7r>Xz7rLw8J-(GzQlYYVH$WK#F`i_i^qVlzTNAh>gBWKV@XC$T-` z3|kj#iCquDhiO7NKum07i|<-NuVsX}Q}mIP$jBJDMfUiaWR3c|F_kWBMw0_Sr|6h4 zk`_r5=0&rCR^*tOy$A8K;@|NqwncjZ>Y-75vlpxq%Cl3EgH`}^^~=u zoll6xxY@a>0f%Ddpi;=cY}fyG!K2N-dEyXXmUP5u){4VnyS^T4?pjN@Ot4zjL(Puw z_U#wMH2Z#8Pts{olG5Dy0tZj;N@;fHheu>YKYQU=4Bk|wcD9MbA`3O4bj$hNRHwzb zSLcG0SLV%zywdbuwl(^E_!@&)TdXge4O{MRWk2RKOt@!8E{$BU-AH(@4{gxs=YAz9LIob|Hzto0}9cWoz6Tp2x0&xi#$ zHh$dwO&UCR1Ob2w00-2eG7d4=cN(Y>0R#$q8?||q@iTi+7-w-xR%uMr&StFIthC<# zvK(aPduwuNB}oJUV8+Zl)%cnfsHI%4`;x6XW^UF^e4s3Z@S<&EV8?56Wya;HNs0E> z`$0dgRdiUz9RO9Au3RmYq>K#G=X%*_dUbSJHP`lSfBaN8t-~@F>)BL1RT*9I851A3 z<-+Gb#_QRX>~av#Ni<#zLswtu-c6{jGHR>wflhKLzC4P@b%8&~u)fosoNjk4r#GvC zlU#UU9&0Hv;d%g72Wq?Ym<&&vtA3AB##L}=ZjiTR4hh7J)e>ei} zt*u+>h%MwN`%3}b4wYpV=QwbY!jwfIj#{me)TDOG`?tI!%l=AwL2G@9I~}?_dA5g6 zCKgK(;6Q0&P&K21Tx~k=o6jwV{dI_G+Ba*Zts|Tl6q1zeC?iYJTb{hel*x>^wb|2RkHkU$!+S4OU4ZOKPZjV>9OVsqNnv5jK8TRAE$A&^yRwK zj-MJ3Pl?)KA~fq#*K~W0l4$0=8GRx^9+?w z!QT8*-)w|S^B0)ZeY5gZPI2G(QtQf?DjuK(s^$rMA!C%P22vynZY4SuOE=wX2f8$R z)A}mzJi4WJnZ`!bHG1=$lwaxm!GOnRbR15F$nRC-M*H<*VfF|pQw(;tbSfp({>9^5 zw_M1-SJ9eGF~m(0dvp*P8uaA0Yw+EkP-SWqu zqal$hK8SmM7#Mrs0@OD+%_J%H*bMyZiWAZdsIBj#lkZ!l2c&IpLu(5^T0Ge5PHzR} zn;TXs$+IQ_&;O~u=Jz+XE0wbOy`=6>m9JVG} zJ~Kp1e5m?K3x@@>!D)piw^eMIHjD4RebtR`|IlckplP1;r21wTi8v((KqNqn%2CB< zifaQc&T}*M&0i|LW^LgdjIaX|o~I$`owHolRqeH_CFrqCUCleN130&vH}dK|^kC>) z-r2P~mApHotL4dRX$25lIcRh_*kJaxi^%ZN5-GAAMOxfB!6flLPY-p&QzL9TE%ho( zRwftE3sy5<*^)qYzKkL|rE>n@hyr;xPqncY6QJ8125!MWr`UCWuC~A#G1AqF1@V$kv>@NBvN&2ygy*{QvxolkRRb%Ui zsmKROR%{*g*WjUUod@@cS^4eF^}yQ1>;WlGwOli z+Y$(8I`0(^d|w>{eaf!_BBM;NpCoeem2>J}82*!em=}}ymoXk>QEfJ>G(3LNA2-46 z5PGvjr)Xh9>aSe>vEzM*>xp{tJyZox1ZRl}QjcvX2TEgNc^(_-hir@Es>NySoa1g^ zFow_twnHdx(j?Q_3q51t3XI7YlJ4_q&(0#)&a+RUy{IcBq?)eaWo*=H2UUVIqtp&lW9JTJiP&u zw8+4vo~_IJXZIJb_U^&=GI1nSD%e;P!c{kZALNCm5c%%oF+I3DrA63_@4)(v4(t~JiddILp7jmoy+>cD~ivwoctFfEL zP*#2Rx?_&bCpX26MBgp^4G>@h`Hxc(lnqyj!*t>9sOBcXN(hTwEDpn^X{x!!gPX?1 z*uM$}cYRwHXuf+gYTB}gDTcw{TXSOUU$S?8BeP&sc!Lc{{pEv}x#ELX>6*ipI1#>8 zKes$bHjiJ1OygZge_ak^Hz#k;=od1wZ=o71ba7oClBMq>Uk6hVq|ePPt)@FM5bW$I z;d2Or@wBjbTyZj|;+iHp%Bo!Vy(X3YM-}lasMItEV_QrP-Kk_J4C>)L&I3Xxj=E?| zsAF(IfVQ4w+dRRnJ>)}o^3_012YYgFWE)5TT=l2657*L8_u1KC>Y-R{7w^S&A^X^U}h20jpS zQsdeaA#WIE*<8KG*oXc~$izYilTc#z{5xhpXmdT-YUnGh9v4c#lrHG6X82F2-t35} zB`jo$HjKe~E*W$=g|j&P>70_cI`GnOQ;Jp*JK#CT zuEGCn{8A@bC)~0%wsEv?O^hSZF*iqjO~_h|>xv>PO+?525Nw2472(yqS>(#R)D7O( zg)Zrj9n9$}=~b00=Wjf?E418qP-@8%MQ%PBiCTX=$B)e5cHFDu$LnOeJ~NC;xmOk# z>z&TbsK>Qzk)!88lNI8fOE2$Uxso^j*1fz>6Ot49y@=po)j4hbTIcVR`ePHpuJSfp zxaD^Dn3X}Na3@<_Pc>a;-|^Pon(>|ytG_+U^8j_JxP=_d>L$Hj?|0lz>_qQ#a|$+( z(x=Lipuc8p4^}1EQhI|TubffZvB~lu$zz9ao%T?%ZLyV5S9}cLeT?c} z>yCN9<04NRi~1oR)CiBakoNhY9BPnv)kw%*iv8vdr&&VgLGIs(-FbJ?d_gfbL2={- zBk4lkdPk~7+jIxd4{M(-W1AC_WcN&Oza@jZoj zaE*9Y;g83#m(OhA!w~LNfUJNUuRz*H-=$s*z+q+;snKPRm9EptejugC-@7-a-}Tz0 z@KHra#Y@OXK+KsaSN9WiGf?&jlZ!V7L||%KHP;SLksMFfjkeIMf<1e~t?!G3{n)H8 zQAlFY#QwfKuj;l@<$YDATAk;%PtD%B(0<|8>rXU< zJ66rkAVW_~Dj!7JGdGGi4NFuE?7ZafdMxIh65Sz7yQoA7fBZCE@WwysB=+`kT^LFX zz8#FlSA5)6FG9(qL3~A24mpzL@@2D#>0J7mMS1T*9UJ zvOq!!a(%IYY69+h45CE?(&v9H4FCr>gK0>mK~F}5RdOuH2{4|}k@5XpsX7+LZo^Qa4sH5`eUj>iffoBVm+ zz4Mtf`h?NW$*q1yr|}E&eNl)J``SZvTf6Qr*&S%tVv_OBpbjnA0&Vz#(;QmGiq-k! zgS0br4I&+^2mgA15*~Cd00cXLYOLA#Ep}_)eED>m+K@JTPr_|lSN}(OzFXQSBc6fM z@f-%2;1@BzhZa*LFV z-LrLmkmB%<<&jEURBEW>soaZ*rSIJNwaV%-RSaCZi4X)qYy^PxZ=oL?6N-5OGOMD2 z;q_JK?zkwQ@b3~ln&sDtT5SpW9a0q+5Gm|fpVY2|zqlNYBR}E5+ahgdj!CvK$Tlk0 z9g$5N;aar=CqMsudQV>yb4l@hN(9Jcc=1(|OHsqH6|g=K-WBd8GxZ`AkT?OO z-z_Ued-??Z*R4~L7jwJ%-`s~FK|qNAJ;EmIVDVpk{Lr7T4l{}vL)|GuUuswe9c5F| zv*5%u01hlv08?00Vpwyk*Q&&fY8k6MjOfpZfKa@F-^6d=Zv|0@&4_544RP5(s|4VPVP-f>%u(J@23BHqo2=zJ#v9g=F!cP((h zpt0|(s++ej?|$;2PE%+kc6JMmJjDW)3BXvBK!h!E`8Y&*7hS{c_Z?4SFP&Y<3evqf z9-ke+bSj$%Pk{CJlJbWwlBg^mEC^@%Ou?o>*|O)rl&`KIbHrjcpqsc$Zqt0^^F-gU2O=BusO+(Op}!jNzLMc zT;0YT%$@ClS%V+6lMTfhuzzxomoat=1H?1$5Ei7&M|gxo`~{UiV5w64Np6xV zVK^nL$)#^tjhCpTQMspXI({TW^U5h&Wi1Jl8g?P1YCV4=%ZYyjSo#5$SX&`r&1PyC zzc;uzCd)VTIih|8eNqFNeBMe#j_FS6rq81b>5?aXg+E#&$m++Gz9<+2)h=K(xtn}F ziV{rmu+Y>A)qvF}ms}4X^Isy!M&1%$E!rTO~5(p+8{U6#hWu>(Ll1}eD64Xa>~73A*538wry?v$vW z>^O#FRdbj(k0Nr&)U`Tl(4PI*%IV~;ZcI2z&rmq=(k^}zGOYZF3b2~Klpzd2eZJl> zB=MOLwI1{$RxQ7Y4e30&yOx?BvAvDkTBvWPpl4V8B7o>4SJn*+h1Ms&fHso%XLN5j z-zEwT%dTefp~)J_C8;Q6i$t!dnlh-!%haR1X_NuYUuP-)`IGWjwzAvp!9@h`kPZhf zwLwFk{m3arCdx8rD~K2`42mIN4}m%OQ|f)4kf%pL?Af5Ul<3M2fv>;nlhEPR8b)u} zIV*2-wyyD%%) zl$G@KrC#cUwoL?YdQyf9WH)@gWB{jd5w4evI& zOFF)p_D8>;3-N1z6mES!OPe>B^<;9xsh)){Cw$Vs-ez5nXS95NOr3s$IU;>VZSzKn zBvub8_J~I%(DozZW@{)Vp37-zevxMRZ8$8iRfwHmYvyjOxIOAF2FUngKj289!(uxY zaClWm!%x&teKmr^ABrvZ(ikx{{I-lEzw5&4t3P0eX%M~>$wG0ZjA4Mb&op+0$#SO_ z--R`>X!aqFu^F|a!{Up-iF(K+alKB{MNMs>e(i@Tpy+7Z-dK%IEjQFO(G+2mOb@BO zP>WHlS#fSQm0et)bG8^ZDScGnh-qRKIFz zfUdnk=m){ej0i(VBd@RLtRq3Ep=>&2zZ2%&vvf?Iex01hx1X!8U+?>ER;yJlR-2q4 z;Y@hzhEC=d+Le%=esE>OQ!Q|E%6yG3V_2*uh&_nguPcZ{q?DNq8h_2ahaP6=pP-+x zK!(ve(yfoYC+n(_+chiJ6N(ZaN+XSZ{|H{TR1J_s8x4jpis-Z-rlRvRK#U%SMJ(`C z?T2 zF(NNfO_&W%2roEC2j#v*(nRgl1X)V-USp-H|CwFNs?n@&vpRcj@W@xCJwR6@T!jt377?XjZ06=`d*MFyTdyvW!`mQm~t3luzYzvh^F zM|V}rO>IlBjZc}9Z zd$&!tthvr>5)m;5;96LWiAV0?t)7suqdh0cZis`^Pyg@?t>Ms~7{nCU;z`Xl+raSr zXpp=W1oHB*98s!Tpw=R5C)O{{Inl>9l7M*kq%#w9a$6N~v?BY2GKOVRkXYCgg*d

<5G2M1WZP5 zzqSuO91lJod(SBDDw<*sX(+F6Uq~YAeYV#2A;XQu_p=N5X+#cmu19Qk>QAnV=k!?wbk5I;tDWgFc}0NkvC*G=V+Yh1cyeJVq~9czZiDXe+S=VfL2g`LWo8om z$Y~FQc6MFjV-t1Y`^D9XMwY*U_re2R?&(O~68T&D4S{X`6JYU-pz=}ew-)V0AOUT1 zVOkHAB-8uBcRjLvz<9HS#a@X*Kc@|W)nyiSgi|u5$Md|P()%2(?olGg@ypoJwp6>m z*dnfjjWC>?_1p;%1brqZyDRR;8EntVA92EJ3ByOxj6a+bhPl z;a?m4rQAV1@QU^#M1HX)0+}A<7TCO`ZR_RzF}X9-M>cRLyN4C+lCk2)kT^3gN^`IT zNP~fAm(wyIoR+l^lQDA(e1Yv}&$I!n?&*p6?lZcQ+vGLLd~fM)qt}wsbf3r=tmVYe zl)ntf#E!P7wlakP9MXS7m0nsAmqxZ*)#j;M&0De`oNmFgi$ov#!`6^4)iQyxg5Iuj zjLAhzQ)r`^hf7`*1`Rh`X;LVBtDSz@0T?kkT1o!ijeyTGt5vc^Cd*tmNgiNo^EaWvaC8$e+nb_{W01j3%=1Y&92YacjCi>eNbwk%-gPQ@H-+4xskQ}f_c=jg^S-# zYFBDf)2?@5cy@^@FHK5$YdAK9cI;!?Jgd}25lOW%xbCJ>By3=HiK@1EM+I46A)Lsd zeT|ZH;KlCml=@;5+hfYf>QNOr^XNH%J-lvev)$Omy8MZ`!{`j>(J5cG&ZXXgv)TaF zg;cz99i$4CX_@3MIb?GL0s*8J=3`#P(jXF(_(6DXZjc@(@h&=M&JG)9&Te1?(^XMW zjjC_70|b=9hB6pKQi`S^Ls7JyJw^@P>Ko^&q8F&?>6i;#CbxUiLz1ZH4lNyd@QACd zu>{!sqjB!2Dg}pbAXD>d!3jW}=5aN0b;rw*W>*PAxm7D)aw(c*RX2@bTGEI|RRp}vw7;NR2wa;rXN{L{Q#=Fa z$x@ms6pqb>!8AuV(prv>|aU8oWV={C&$c zMa=p=CDNOC2tISZcd8~18GN5oTbKY+Vrq;3_obJlfSKRMk;Hdp1`y`&LNSOqeauR_ z^j*Ojl3Ohzb5-a49A8s|UnM*NM8tg}BJXdci5%h&;$afbmRpN0&~9rCnBA`#lG!p zc{(9Y?A0Y9yo?wSYn>iigf~KP$0*@bGZ>*YM4&D;@{<%Gg5^uUJGRrV4 z(aZOGB&{_0f*O=Oi0k{@8vN^BU>s3jJRS&CJOl3o|BE{FAA&a#2YYiX3pZz@|Go-F z|Fly;7eX2OTs>R}<`4RwpHFs9nwh)B28*o5qK1Ge=_^w0m`uJOv!=&!tzt#Save(C zgKU=Bsgql|`ui(e1KVxR`?>Dx>(rD1$iWp&m`v)3A!j5(6vBm*z|aKm*T*)mo(W;R zNGo2`KM!^SS7+*9YxTm6YMm_oSrLceqN*nDOAtagULuZl5Q<7mOnB@Hq&P|#9y{5B z!2x+2s<%Cv2Aa0+u{bjZXS);#IFPk(Ph-K7K?3i|4ro> zRbqJoiOEYo(Im^((r}U4b8nvo_>4<`)ut`24?ILnglT;Pd&U}$lV3U$F9#PD(O=yV zgNNA=GW|(E=&m_1;uaNmipQe?pon4{T=zK!N!2_CJL0E*R^XXIKf*wi!>@l}3_P9Z zF~JyMbW!+n-+>!u=A1ESxzkJy$DRuG+$oioG7(@Et|xVbJ#BCt;J43Nvj@MKvTxzy zMmjNuc#LXBxFAwIGZJk~^!q$*`FME}yKE8d1f5Mp}KHNq(@=Z8YxV}0@;YS~|SpGg$_jG7>_8WWYcVx#4SxpzlV9N4aO>K{c z$P?a_fyDzGX$Of3@ykvedGd<@-R;M^Shlj*SswJLD+j@hi_&_>6WZ}#AYLR0iWMK|A zH_NBeu(tMyG=6VO-=Pb>-Q#$F*or}KmEGg*-n?vWQREURdB#+6AvOj*I%!R-4E_2$ zU5n9m>RWs|Wr;h2DaO&mFBdDb-Z{APGQx$(L`if?C|njd*fC=rTS%{o69U|meRvu?N;Z|Y zbT|ojL>j;q*?xXmnHH#3R4O-59NV1j=uapkK7}6@Wo*^Nd#(;$iuGsb;H315xh3pl zHaJ>h-_$hdNl{+|Zb%DZH%ES;*P*v0#}g|vrKm9;j-9e1M4qX@zkl&5OiwnCz=tb6 zz<6HXD+rGIVpGtkb{Q^LIgExOm zz?I|oO9)!BOLW#krLmWvX5(k!h{i>ots*EhpvAE;06K|u_c~y{#b|UxQ*O@Ks=bca z^_F0a@61j3I(Ziv{xLb8AXQj3;R{f_l6a#H5ukg5rxwF9A$?Qp-Mo54`N-SKc}fWp z0T)-L@V$$&my;l#Ha{O@!fK4-FSA)L&3<${Hcwa7ue`=f&YsXY(NgeDU#sRlT3+9J z6;(^(sjSK@3?oMo$%L-nqy*E;3pb0nZLx6 z;h5)T$y8GXK1DS-F@bGun8|J(v-9o=42&nLJy#}M5D0T^5VWBNn$RpC zZzG6Bt66VY4_?W=PX$DMpKAI!d`INr) zkMB{XPQ<52rvWVQqgI0OL_NWxoe`xxw&X8yVftdODPj5|t}S6*VMqN$-h9)1MBe0N zYq?g0+e8fJCoAksr0af1)FYtz?Me!Cxn`gUx&|T;)695GG6HF7!Kg1zzRf_{VWv^bo81v4$?F6u2g|wxHc6eJQAg&V z#%0DnWm2Rmu71rPJ8#xFUNFC*V{+N_qqFH@gYRLZ6C?GAcVRi>^n3zQxORPG)$-B~ z%_oB?-%Zf7d*Fe;cf%tQwcGv2S?rD$Z&>QC2X^vwYjnr5pa5u#38cHCt4G3|efuci z@3z=#A13`+ztmp;%zjXwPY_aq-;isu*hecWWX_=Z8paSqq7;XYnUjK*T>c4~PR4W7 z#C*%_H&tfGx`Y$w7`dXvVhmovDnT>btmy~SLf>>~84jkoQ%cv=MMb+a{JV&t0+1`I z32g_Y@yDhKe|K^PevP~MiiVl{Ou7^Mt9{lOnXEQ`xY^6L8D$705GON{!1?1&YJEl#fTf5Z)da=yiEQ zGgtC-soFGOEBEB~ZF_{7b(76En>d}mI~XIwNw{e>=Fv)sgcw@qOsykWr?+qAOZSVrQfg}TNI ztKNG)1SRrAt6#Q?(me%)>&A_^DM`pL>J{2xu>xa$3d@90xR61TQDl@fu%_85DuUUA za9tn64?At;{`BAW6oykwntxHeDpXsV#{tmt5RqdN7LtcF4vR~_kZNT|wqyR#z^Xcd zFdymVRZvyLfTpBT>w9<)Ozv@;Yk@dOSVWbbtm^y@@C>?flP^EgQPAwsy75bveo=}T zFxl(f)s)j(0#N_>Or(xEuV(n$M+`#;Pc$1@OjXEJZumkaekVqgP_i}p`oTx;terTx zZpT+0dpUya2hqlf`SpXN{}>PfhajNk_J0`H|2<5E;U5Vh4F8er z;RxLSFgpGhkU>W?IwdW~NZTyOBrQ84H7_?gviIf71l`EETodG9a1!8e{jW?DpwjL? zGEM&eCzwoZt^P*8KHZ$B<%{I}>46IT%jJ3AnnB5P%D2E2Z_ z1M!vr#8r}1|KTqWA4%67ZdbMW2YJ81b(KF&SQ2L1Qn(y-=J${p?xLMx3W7*MK;LFQ z6Z`aU;;mTL4XrrE;HY*Rkh6N%?qviUGNAKiCB~!P}Z->IpO6E(gGd7I#eDuT7j|?nZ zK}I(EJ>$Kb&@338M~O+em9(L!+=0zBR;JAQesx|3?Ok90)D1aS9P?yTh6Poh8Cr4X zk3zc=f2rE7jj+aP7nUsr@~?^EGP>Q>h#NHS?F{Cn`g-gD<8F&dqOh-0sa%pfL`b+1 zUsF*4a~)KGb4te&K0}bE>z3yb8% zibb5Q%Sfiv7feb1r0tfmiMv z@^4XYwg@KZI=;`wC)`1jUA9Kv{HKe2t$WmRcR4y8)VAFjRi zaz&O7Y2tDmc5+SX(bj6yGHYk$dBkWc96u3u&F)2yEE~*i0F%t9Kg^L6MJSb&?wrXi zGSc;_rln$!^ybwYBeacEFRsVGq-&4uC{F)*Y;<0y7~USXswMo>j4?~5%Zm!m@i@-> zXzi82sa-vpU{6MFRktJy+E0j#w`f`>Lbog{zP|9~hg(r{RCa!uGe>Yl536cn$;ouH za#@8XMvS-kddc1`!1LVq;h57~zV`7IYR}pp3u!JtE6Q67 zq3H9ZUcWPm2V4IukS}MCHSdF0qg2@~ufNx9+VMjQP&exiG_u9TZAeAEj*jw($G)zL zq9%#v{wVyOAC4A~AF=dPX|M}MZV)s(qI9@aIK?Pe+~ch|>QYb+78lDF*Nxz2-vpRbtQ*F4$0fDbvNM#CCatgQ@z1+EZWrt z2dZfywXkiW=no5jus-92>gXn5rFQ-COvKyegmL=4+NPzw6o@a?wGE-1Bt;pCHe;34K%Z z-FnOb%!nH;)gX+!a3nCk?5(f1HaWZBMmmC@lc({dUah+E;NOros{?ui1zPC-Q0);w zEbJmdE$oU$AVGQPdm{?xxI_0CKNG$LbY*i?YRQ$(&;NiA#h@DCxC(U@AJ$Yt}}^xt-EC_ z4!;QlLkjvSOhdx!bR~W|Ezmuf6A#@T`2tsjkr>TvW*lFCMY>Na_v8+{Y|=MCu1P8y z89vPiH5+CKcG-5lzk0oY>~aJC_0+4rS@c@ZVKLAp`G-sJB$$)^4*A!B zmcf}lIw|VxV9NSoJ8Ag3CwN&d7`|@>&B|l9G8tXT^BDHOUPrtC70NgwN4${$k~d_4 zJ@eo6%YQnOgq$th?0{h`KnqYa$Nz@vlHw<%!C5du6<*j1nwquk=uY}B8r7f|lY+v7 zm|JU$US08ugor8E$h3wH$c&i~;guC|3-tqJy#T;v(g( zBZtPMSyv%jzf->435yM(-UfyHq_D=6;ouL4!ZoD+xI5uCM5ay2m)RPmm$I}h>()hS zO!0gzMxc`BPkUZ)WXaXam%1;)gedA7SM8~8yIy@6TPg!hR0=T>4$Zxd)j&P-pXeSF z9W`lg6@~YDhd19B9ETv(%er^Xp8Yj@AuFVR_8t*KS;6VHkEDKI#!@l!l3v6`W1`1~ zP{C@keuV4Q`Rjc08lx?zmT$e$!3esc9&$XZf4nRL(Z*@keUbk!GZi(2Bmyq*saOD? z3Q$V<*P-X1p2}aQmuMw9nSMbOzuASsxten7DKd6A@ftZ=NhJ(0IM|Jr<91uAul4JR zADqY^AOVT3a(NIxg|U;fyc#ZnSzw2cr}#a5lZ38>nP{05D)7~ad7JPhw!LqOwATXtRhK!w0X4HgS1i<%AxbFmGJx9?sEURV+S{k~g zGYF$IWSlQonq6}e;B(X(sIH|;52+(LYW}v_gBcp|x%rEAVB`5LXg_d5{Q5tMDu0_2 z|LOm$@K2?lrLNF=mr%YP|U-t)~9bqd+wHb4KuPmNK<}PK6e@aosGZK57=Zt+kcszVOSbe;`E^dN! ze7`ha3WUUU7(nS0{?@!}{0+-VO4A{7+nL~UOPW9_P(6^GL0h${SLtqG!} zKl~Ng5#@Sy?65wk9z*3SA`Dpd4b4T^@C8Fhd8O)k_4%0RZL5?#b~jmgU+0|DB%0Z) zql-cPC>A9HPjdOTpPC` zQwvF}uB5kG$Xr4XnaH#ruSjM*xG?_hT7y3G+8Ox`flzU^QIgb_>2&-f+XB6MDr-na zSi#S+c!ToK84<&m6sCiGTd^8pNdXo+$3^l3FL_E`0 z>8it5YIDxtTp2Tm(?}FX^w{fbfgh7>^8mtvN>9fWgFN_*a1P`Gz*dyOZF{OV7BC#j zQV=FQM5m>47xXgapI$WbPM5V`V<7J9tD)oz@d~MDoM`R^Y6-Na(lO~uvZlpu?;zw6 zVO1faor3dg#JEb5Q*gz4<W8tgC3nE2BG2jeIQs1)<{In&7hJ39x=;ih;CJDy)>0S1at*7n?Wr0ahYCpFjZ|@u91Zl7( zv;CSBRC65-6f+*JPf4p1UZ)k=XivKTX6_bWT~7V#rq0Xjas6hMO!HJN8GdpBKg_$B zwDHJF6;z?h<;GXFZan8W{XFNPpOj!(&I1`&kWO86p?Xz`a$`7qV7Xqev|7nn_lQuX ziGpU1MMYt&5dE2A62iX3;*0WzNB9*nSTzI%62A+N?f?;S>N@8M=|ef3gtQTIA*=yq zQAAjOqa!CkHOQo4?TsqrrsJLclXcP?dlAVv?v`}YUjo1Htt;6djP@NPFH+&p1I+f_ z)Y279{7OWomY8baT(4TAOlz1OyD{4P?(DGv3XyJTA2IXe=kqD)^h(@*E3{I~w;ws8 z)ZWv7E)pbEM zd3MOXRH3mQhks9 zv6{s;k0y5vrcjXaVfw8^>YyPo=oIqd5IGI{)+TZq5Z5O&hXAw%ZlL}^6FugH;-%vP zAaKFtt3i^ag226=f0YjzdPn6|4(C2sC5wHFX{7QF!tG1E-JFA`>eZ`}$ymcRJK?0c zN363o{&ir)QySOFY0vcu6)kX#;l??|7o{HBDVJN+17rt|w3;(C_1b>d;g9Gp=8YVl zYTtA52@!7AUEkTm@P&h#eg+F*lR zQ7iotZTcMR1frJ0*V@Hw__~CL>_~2H2cCtuzYIUD24=Cv!1j6s{QS!v=PzwQ(a0HS zBKx04KA}-Ue+%9d`?PG*hIij@54RDSQpA7|>qYVIrK_G6%6;#ZkR}NjUgmGju)2F`>|WJoljo)DJgZr4eo1k1i1+o z1D{>^RlpIY8OUaOEf5EBu%a&~c5aWnqM zxBpJq98f=%M^{4mm~5`CWl%)nFR64U{(chmST&2jp+-r z3675V<;Qi-kJud%oWnCLdaU-)xTnMM%rx%Jw6v@=J|Ir=4n-1Z23r-EVf91CGMGNz zb~wyv4V{H-hkr3j3WbGnComiqmS0vn?n?5v2`Vi>{Ip3OZUEPN7N8XeUtF)Ry6>y> zvn0BTLCiqGroFu|m2zG-;Xb6;W`UyLw)@v}H&(M}XCEVXZQoWF=Ykr5lX3XWwyNyF z#jHv)A*L~2BZ4lX?AlN3X#axMwOC)PoVy^6lCGse9bkGjb=qz%kDa6}MOmSwK`cVO zt(e*MW-x}XtU?GY5}9{MKhRhYOlLhJE5=ca+-RmO04^ z66z{40J=s=ey9OCdc(RCzy zd7Zr1%!y3}MG(D=wM_ebhXnJ@MLi7cImDkhm0y{d-Vm81j`0mbi4lF=eirlr)oW~a zCd?26&j^m4AeXEsIUXiTal)+SPM4)HX%%YWF1?(FV47BaA`h9m67S9x>hWMVHx~Hg z1meUYoLL(p@b3?x|9DgWeI|AJ`Ia84*P{Mb%H$ZRROouR4wZhOPX15=KiBMHl!^JnCt$Az`KiH^_d>cev&f zaG2>cWf$=A@&GP~DubsgYb|L~o)cn5h%2`i^!2)bzOTw2UR!>q5^r&2Vy}JaWFUQE04v>2;Z@ZPwXr?y&G(B^@&y zsd6kC=hHdKV>!NDLIj+3rgZJ|dF`%N$DNd;B)9BbiT9Ju^Wt%%u}SvfM^=|q-nxDG zuWCQG9e#~Q5cyf8@y76#kkR^}{c<_KnZ0QsZcAT|YLRo~&tU|N@BjxOuy`#>`X~Q< z?R?-Gsk$$!oo(BveQLlUrcL#eirhgBLh`qHEMg`+sR1`A=1QX7)ZLMRT+GBy?&mM8 zQG^z-!Oa&J-k7I(3_2#Q6Bg=NX<|@X&+YMIOzfEO2$6Mnh}YV!m!e^__{W@-CTprr zbdh3f=BeCD$gHwCrmwgM3LAv3!Mh$wM)~KWzp^w)Cu6roO7uUG5z*}i0_0j47}pK; ztN530`ScGatLOL06~zO)Qmuv`h!gq5l#wx(EliKe&rz-5qH(hb1*fB#B+q`9=jLp@ zOa2)>JTl7ovxMbrif`Xe9;+fqB1K#l=Dv!iT;xF zdkCvS>C5q|O;}ns3AgoE({Ua-zNT-9_5|P0iANmC6O76Sq_(AN?UeEQJ>#b54fi3k zFmh+P%b1x3^)0M;QxXLP!BZ^h|AhOde*{9A=f3|Xq*JAs^Y{eViF|=EBfS6L%k4ip zk+7M$gEKI3?bQg?H3zaE@;cyv9kv;cqK$VxQbFEsy^iM{XXW0@2|DOu$!-k zSFl}Y=jt-VaT>Cx*KQnHTyXt}f9XswFB9ibYh+k2J!ofO+nD?1iw@mwtrqI4_i?nE zhLkPp41ED62me}J<`3RN80#vjW;wt`pP?%oQ!oqy7`miL>d-35a=qotK$p{IzeSk# ze_$CFYp_zIkrPFVaW^s#U4xT1lI^A0IBe~Y<4uS%zSV=wcuLr%gQT=&5$&K*bwqx| zWzCMiz>7t^Et@9CRUm9E+@hy~sBpm9fri$sE1zgLU((1?Yg{N1Sars=DiW&~Zw=3I zi7y)&oTC?UWD2w97xQ&5vx zRXEBGeJ(I?Y}eR0_O{$~)bMJRTsNUPIfR!xU9PE7A>AMNr_wbrFK>&vVw=Y;RH zO$mlpmMsQ}-FQ2cSj7s7GpC+~^Q~dC?y>M}%!-3kq(F3hGWo9B-Gn02AwUgJ>Z-pKOaj zysJBQx{1>Va=*e@sLb2z&RmQ7ira;aBijM-xQ&cpR>X3wP^foXM~u1>sv9xOjzZpX z0K;EGouSYD~oQ&lAafj3~EaXfFShC+>VsRlEMa9cg9i zFxhCKO}K0ax6g4@DEA?dg{mo>s+~RPI^ybb^u--^nTF>**0l5R9pocwB?_K)BG_)S zyLb&k%XZhBVr7U$wlhMqwL)_r&&n%*N$}~qijbkfM|dIWP{MyLx}X&}ES?}7i;9bW zmTVK@zR)7kE2+L42Q`n4m0VVg5l5(W`SC9HsfrLZ=v%lpef=Gj)W59VTLe+Z$8T8i z4V%5+T0t8LnM&H>Rsm5C%qpWBFqgTwL{=_4mE{S3EnBXknM&u8n}A^IIM4$s3m(Rd z>zq=CP-!9p9es2C*)_hoL@tDYABn+o#*l;6@7;knWIyDrt5EuakO99S$}n((Fj4y} zD!VvuRzghcE{!s;jC*<_H$y6!6QpePo2A3ZbX*ZzRnQq*b%KK^NF^z96CHaWmzU@f z#j;y?X=UP&+YS3kZx7;{ zDA{9(wfz7GF`1A6iB6fnXu0?&d|^p|6)%3$aG0Uor~8o? z*e}u#qz7Ri?8Uxp4m_u{a@%bztvz-BzewR6bh*1Xp+G=tQGpcy|4V_&*aOqu|32CM zz3r*E8o8SNea2hYJpLQ-_}R&M9^%@AMx&`1H8aDx4j%-gE+baf2+9zI*+Pmt+v{39 zDZ3Ix_vPYSc;Y;yn68kW4CG>PE5RoaV0n@#eVmk?p$u&Fy&KDTy!f^Hy6&^-H*)#u zdrSCTJPJw?(hLf56%2;_3n|ujUSJOU8VPOTlDULwt0jS@j^t1WS z!n7dZIoT+|O9hFUUMbID4Ec$!cc($DuQWkocVRcYSikFeM&RZ=?BW)mG4?fh#)KVG zcJ!<=-8{&MdE)+}?C8s{k@l49I|Zwswy^ZN3;E!FKyglY~Aq?4m74P-0)sMTGXqd5(S<-(DjjM z&7dL-Mr8jhUCAG$5^mI<|%`;JI5FVUnNj!VO2?Jiqa|c2;4^n!R z`5KK0hyB*F4w%cJ@Un6GC{mY&r%g`OX|1w2$B7wxu97%<@~9>NlXYd9RMF2UM>(z0 zouu4*+u+1*k;+nFPk%ly!nuMBgH4sL5Z`@Rok&?Ef=JrTmvBAS1h?C0)ty5+yEFRz zY$G=coQtNmT@1O5uk#_MQM1&bPPnspy5#>=_7%WcEL*n$;t3FUcXxMpcXxMpA@1(( z32}FUxI1xoH;5;M_i@j?f6mF_p3Cd1DTb=dTK#qJneN`*d+pvYD*L?M(1O%DEmB>$ zs6n;@Lcm9c7=l6J&J(yBnm#+MxMvd-VKqae7;H7p-th(nwc}?ov%$8ckwY%n{RAF3 zTl^SF7qIWdSa7%WJ@B^V-wD|Z)9IQkl$xF>ebi>0AwBv5oh5$D*C*Pyj?j_*pT*IMgu3 z$p#f0_da0~Wq(H~yP##oQ}x66iYFc0O@JFgyB>ul@qz{&<14#Jy@myMM^N%oy0r|b zDPBoU!Y$vUxi%_kPeb4Hrc>;Zd^sftawKla0o|3mk@B)339@&p6inAo(Su3qlK2a) zf?EU`oSg^?f`?y=@Vaq4Dps8HLHW zIe~fHkXwT>@)r+5W7#pW$gzbbaJ$9e;W-u#VF?D=gsFfFlBJ5wR>SB;+f)sFJsYJ| z29l2Ykg+#1|INd=uj3&d)m@usb;VbGnoI1RHvva@?i&>sP&;Lt!ZY=e!=d-yZ;QV% zP@(f)+{|<*XDq%mvYKwIazn8HS`~mW%9+B|`&x*n?Y$@l{uy@ z^XxQnuny+p0JG0h)#^7}C|Btyp7=P#A2ed1vP0KGw9+~-^y4~S$bRm3gCT{+7Z<(A zJ&tg=7X|uKPKd6%z@IcZ@FgQe=rS&&1|O!s#>B_z!M_^B`O(SqE>|x- zh{~)$RW_~jXj)}mO>_PZvGdD|vtN44=Tp!oCP0>)gYeJ;n*&^BZG{$>y%Yb|L zeBUI#470!F`GM-U$?+~k+g9lj5C-P_i1%c3Zbo!@EjMJDoxQ7%jHHKeMVw&_(aoL? z%*h*aIt9-De$J>ZRLa7aWcLn<=%D+u0}RV9ys#TBGLAE%Vh`LWjWUi`Q3kpW;bd)YD~f(#$jfNdx}lOAq=#J*aV zz;K>I?)4feI+HrrrhDVkjePq;L7r87;&vm|7qaN z_>XhM8GU6I5tSr3O2W4W%m6wDH#=l32!%LRho(~*d3GfA6v-ND^0trp-qZs(B(ewD z3y3@ZV!2`DZ6b6c(Ftqg-s715;=lZqGF>H+z+c&7NeDz!We+7WNk>X*b7OZmlcTnf z{C1CB67e@xbWprDhN+t!B%4od#|>yQA$5mBM>XdhP?1U^%aD&^=PYWQEY*8Mr%h~R zOVzrd9}6RSl}Lt42r166_*s|U<1}`{l(H}m8H=D+oG>*=+=W^%IMB&CHZ-?)78G2b z)9kj_ldMecB_65eV&R+(yQ$2`ol&&7$&ns_{%A6cC2C*C6dY7qyWrHSYyOBl$0=$> z-YgkNlH{1MR-FXx7rD=4;l%6Ub3OMx9)A|Y7KLnvb`5OB?hLb#o@Wu(k|;_b!fbq( zX|rh*D3ICnZF{5ipmz8`5UV3Otwcso0I#;Q(@w+Pyj&Qa(}Uq2O(AcLU(T`+x_&~?CFLly*`fdP6NU5A|ygPXM>}(+) zkTRUw*cD<% zzFnMeB(A4A9{|Zx2*#!sRCFTk2|AMy5+@z8ws0L-{mt(9;H#}EGePUWxLabB_fFcp zLiT)TDLUXPbV2$Cde<9gv4=;u5aQ$kc9|GE2?AQZsS~D%AR`}qP?-kS_bd>C2r(I; zOc&r~HB7tUOQgZOpH&7C&q%N612f?t(MAe(B z@A!iZi)0qo^Nyb`#9DkzKjoI4rR1ghi1wJU5Tejt!ISGE93m@qDNYd|gg9(s|8-&G zcMnsX0=@2qQQ__ujux#EJ=veg&?3U<`tIWk~F=vm+WTviUvueFk&J@TcoGO{~C%6NiiNJ*0FJBQ!3Ab zm59ILI24e8!=;-k%yEf~YqN_UJ8k z0GVIS0n^8Yc)UK1eQne}<0XqzHkkTl*8VrWr zo}y?WN5@TL*1p>@MrUtxq0Vki($sn_!&;gR2e$?F4^pe@J_BQS&K3{4n+f7tZX4wQn z*Z#0eBs&H8_t`w^?ZYx=BGgyUI;H$i*t%(~8BRZ4gH+nJT0R-3lzdn4JY=xfs!YpF zQdi3kV|NTMB}uxx^KP!`=S(}{s*kfb?6w^OZpU?Wa~7f@Q^pV}+L@9kfDE`c@h5T* zY@@@?HJI)j;Y#l8z|k8y#lNTh2r?s=X_!+jny>OsA7NM~(rh3Tj7?e&pD!Jm28*UL zmRgopf0sV~MzaHDTW!bPMNcymg=!OS2bD@6Z+)R#227ET3s+2m-(W$xXBE#L$Whsi zjz6P+4cGBQkJY*vc1voifsTD}?H$&NoN^<=zK~75d|WSU4Jaw`!GoPr$b>4AjbMy+ z%4;Kt7#wwi)gyzL$R97(N?-cKygLClUk{bBPjSMLdm|MG-;oz70mGNDus zdGOi}L59=uz=VR2nIux^(D85f)1|tK&c!z1KS6tgYd^jgg6lT^5h42tZCn#Q-9k>H zVby-zby2o_GjI!zKn8ZuQ`asmp6R@=FR9kJ_Vja#I#=wtQWTes>INZynAoj$5 zN^9Ws&hvDhu*lY=De$Zby12$N&1#U2W1OHzuh;fSZH4igQodAG1K*;%>P9emF7PPD z>XZ&_hiFcX9rBXQ8-#bgSQ!5coh=(>^8gL%iOnnR>{_O#bF>l+6yZQ4R42{Sd#c7G zHy!)|g^tmtT4$YEk9PUIM8h)r?0_f=aam-`koGL&0Zp*c3H2SvrSr60s|0VtFPF^) z-$}3C94MKB)r#398;v@)bMN#qH}-%XAyJ_V&k@k+GHJ^+YA<*xmxN8qT6xd+3@i$( z0`?f(la@NGP*H0PT#Od3C6>0hxarvSr3G;0P=rG^v=nB5sfJ}9&klYZ>G1BM2({El zg0i|%d~|f2e(yWsh%r)XsV~Fm`F*Gsm;yTQV)dW!c8^WHRfk~@iC$w^h=ICTD!DD;~TIlIoVUh*r@aS|%Ae3Io zU~>^l$P8{6Ro~g26!@NToOZ(^5f8p`*6ovpcQdIDf%)?{NPPwHB>l*f_prp9XDCM8 zG`(I8xl|w{x(c`}T_;LJ!%h6L=N=zglX2Ea+2%Q8^GA>jow-M>0w{XIE-yz|?~M+; zeZO2F3QK@>(rqR|i7J^!1YGH^9MK~IQPD}R<6^~VZWErnek^xHV>ZdiPc4wesiYVL z2~8l7^g)X$kd}HC74!Y=Uq^xre22Osz!|W@zsoB9dT;2Dx8iSuK!Tj+Pgy0-TGd)7 zNy)m@P3Le@AyO*@Z2~+K9t2;=7>-*e(ZG`dBPAnZLhl^zBIy9G+c)=lq0UUNV4+N% zu*Nc4_cDh$ou3}Re}`U&(e^N?I_T~#42li13_LDYm`bNLC~>z0ZG^o6=IDdbIf+XFTfe>SeLw4UzaK#4CM4HNOs- zz>VBRkL@*A7+XY8%De)|BYE<%pe~JzZN-EU4-s_P9eINA^Qvy3z?DOTlkS!kfBG_7 zg{L6N2(=3y=iY)kang=0jClzAWZqf+fDMy-MH&Px&6X36P^!0gj%Z0JLvg~oB$9Z| zgl=6_$4LSD#(2t{Eg=2|v_{w7op+)>ehcvio@*>XM!kz+xfJees9(ObmZ~rVGH>K zWaiBlWGEV{JU=KQ>{!0+EDe-+Z#pO zv{^R<7A^gloN;Tx$g`N*Z5OG!5gN^Xj=2<4D;k1QuN5N{4O`Pfjo3Ht_RRYSzsnhTK?YUf)z4WjNY z>R04WTIh4N(RbY*hPsjKGhKu;&WI)D53RhTUOT}#QBDfUh%lJSy88oqBFX)1pt>;M z>{NTkPPk8#}DUO;#AV8I7ZQsC?Wzxn|3ubiQYI|Fn_g4r)%eNZ~ zSvTYKS*9Bcw{!=C$=1` zGQ~1D97;N!8rzKPX5WoqDHosZIKjc!MS+Q9ItJK?6Wd%STS2H!*A#a4t5 zJ-Rz_`n>>Up%|81tJR2KND<6Uoe82l={J~r*D5c_bThxVxJ<}?b0Sy}L1u|Yk=e&t z0b5c2X(#x^^fI)l<2=3b=|1OH_)-2beVEH9IzpS*Es0!4Or+xE$%zdgY+VTK2}#fpxSPtD^1a6Z)S%5eqVDzs`rL1U;Zep@^Y zWf#dJzp_iWP{z=UEepfZ4ltYMb^%H7_m4Pu81CP@Ra)ds+|Oi~a>Xi(RBCy2dTu-R z$dw(E?$QJUA3tTIf;uZq!^?_edu~bltHs!5WPM-U=R74UsBwN&nus2c?`XAzNUYY|fasp?z$nFwXQYnT`iSR<=N`1~h3#L#lF-Fc1D#UZhC2IXZ{#IDYl_r8 z?+BRvo_fPGAXi+bPVzp=nKTvN_v*xCrb^n=3cQ~No{JzfPo@YWh=7K(M_$Jk*+9u* zEY4Ww3A|JQ`+$z(hec&3&3wxV{q>D{fj!Euy2>tla^LP_2T8`St2em~qQp zm{Tk<>V3ecaP1ghn}kzS7VtKksV*27X+;Y6#I$urr=25xuC=AIP7#Jp+)L67G6>EZ zA~n}qEWm6A8GOK!3q9Yw*Z07R(qr{YBOo5&4#pD_O(O^y0a{UlC6w@ZalAN0Rq_E0 zVA!pI-6^`?nb7`y(3W5OsoVJ^MT!7r57Jm{FS{(GWAWwAh$dBpffjcOZUpPv$tTc} zv~jnA{+|18GmMDq7VK6Sb=-2nzz^7TDiixA{mf%8eQC|x>*=)((3}twJCoh~V4m3) zM5fwDbrTpnYR`lIO7Il7Eq@)St{h>Nllv+5Hk2FAE8fdD*YT|zJix?!cZ-=Uqqieb z-~swMc+yvTu(h?fT4K_UuVDqTup3%((3Q!0*Tfwyl`3e27*p{$ zaJMMF-Pb=3imlQ*%M6q5dh3tT+^%wG_r)q5?yHvrYAmc-zUo*HtP&qP#@bfcX~jwn!$k~XyC#Ox9i7dO7b4}b^f zrVEPkeD%)l0-c_gazzFf=__#Q6Pwv_V=B^h=)CYCUszS6g!}T!r&pL)E*+2C z5KCcctx6Otpf@x~7wZz*>qB_JwO!uI@9wL0_F>QAtg3fvwj*#_AKvsaD?!gcj+zp) zl2mC)yiuumO+?R2`iiVpf_E|9&}83;^&95y96F6T#E1}DY!|^IW|pf-3G0l zE&_r{24TQAa`1xj3JMev)B_J-K2MTo{nyRKWjV#+O}2ah2DZ>qnYF_O{a6Gy{aLJi#hWo3YT3U7yVxoNrUyw31163sHsCUQG|rriZFeoTcP` zFV<&;-;5x0n`rqMjx2^_7y)dHPV@tJC*jHQo!~1h`#z)Gu7m@0@z*e?o|S#5#Ht~%GC|r zd?EY_E0XKUQ2o7*e3D9{Lt7s#x~`hjzwQ{TYw;Fq8la&)%4Vj_N@ivmaSNw9X3M$MAG97a&m1SODLZ-#$~7&@ zrB~0E+38b6sfezlmhDej*KRVbzptE0Xg%$xpjqoeL;-LwmKIR#%+EZ7U|&;9rS6lo8u9iOD;-3HF{Gm=EL@W zG8L9&8=FxGHICO+MX@lC?DpY4GAE9!S+7hKsTmr8%hFI9QGI4sCj&?Of-yA98KvLsP z|k5cP?Z zay4&3t8e5RgA_@c7z{RX6d`;{B~l03#AD@RJD1{;4x93d7mD15wnFLi^LI%`Z~6@ zq9}|AG1Lq-1~Fb{1b?}bFLaSnWm!7L)P8#%g{{}}u@Q`4N{s3LiD4kSqTnM8UNN4XQi57LZRzkkL9+rJ{_?juO;cZL=MIT2H1q-=Tt1G666hVaPojp^(AM>6 zDQQf0_>1u=rvT+6(5 zAQR5%mlLdhkl4MpIyY0GN9VrGYkq?1sF8F(VeB0u3{p`h6IgEBC}Jr!^-)@5@<8s( zXyiL`ENayjlbGx}3q2T;y&|@~&$+T=hN0iS4BAARQ_JBclEeBW7}$3lx|!Ee&vs&o z=A4b##+t=rylLD-dc(X)^d?KbmU^9uZ)zXbIPC%pD{s(>p9*fu8&(?$LE67%%b-e) z!IU|lpUpK`<&YPqJnj5wb8(;a)JoC~+Kb`Fq-HL<>X@DYPqu4t9tLfS9C>Kn*Ho zl3Zz2y8;bCi@KYchQ;1JTPXL`ZMCb4R7fLlP_qKJ`aTs3H2Q6`g3GdtURX%yk`~xS z#|RDc0Y|%b+$^QYCSEG~ZF;*rT;@T=Ko6uwRJ&RasW^4$W<^nS^v|}UmIHe`P{(x| zI&y@A&b6=G2#r*st8^|19`Yw20=}MF9@@6zIuB%!vd7J%E|@zK(MRvFif-szGX^db zIvb}^{t9g(lZhLP&h6;2p>69mWE3ss6di_-KeYjPVskOMEu?5m_A>;o`6 z5ot9G8pI8Jwi@yJExKVZVw-3FD7TW3Ya{_*rS5+LicF^BX(Mq)H&l_B5o9^ zpcL6s^X}J-_9RAs(wk7s1J$cjO~jo*4l3!1V)$J+_j7t8g4A=ab`L(-{#G?z>z@KneXt&ZOv>m);*lTA}gRhYxtJt;0QZ<#l+OWu6(%(tdZ`LkXb}TQjhal;1vd{D+b@g7G z25i;qgu#ieYC?Fa?iwzeLiJa|vAU1AggN5q{?O?J9YU|xHi}PZb<6>I7->aWA4Y7-|a+7)RQagGQn@cj+ED7h6!b>XIIVI=iT(

    xR8>x!-hF($8?9?2$_G0!Ov-PHdEZo(@$?ZcCM)7YB>$ZH zMWhPJRjqPm%P_V5#UMfZ_L}+C(&-@fiUm`Gvj-V2YSM@AwZ4+@>lf-7*yxYxYzJG9 z8Z>T-V-h|PI-K8#1LBs++!+=;G&ed}>Qgs%CA|)bQd$SYzJ8U?H+Pb2&Bf=hSo*HL zELt9Z&2dz8&QQ^NY<~PP+wu57Eu>N@zkBFwO!w+BO}S0Xa(XN?BY)~WGZ<~bbZC&C zlJR|EK1_BLx*FK@OvkyG#ANGZbW~h5*xsx24d9toyTm-JUKo$r%(W42t>}}xax;qL zaw}VpEIzc=)VsC}Yx9kb@Fhh4bEWXlb4-DIH+tzLMlaT-I#A!e zKkZtQ^c@m*;P`&@?i@8tZ&Nel~z27L^F*m1}Rg^-xTzqy}3Mmq4jjJ zJC;ZK#U6QdBoE~b+-^xIyHSxNAYFGGB2WifSL_@3*CnzN18{kDvLM;dN50Jan0*YL zysmN}*Wyag#N?qeBO*E})kZMhzVKMFI zDJmEG_Wsed#Z_9T6Bi+-#s5oCG_$W<;8y%ubb!E>m!Z=HcX$Bn<&6a4a2Chp>^pAB zp^7;RF-lQa$1Ct5l88Ak4)(sYu$IRd5RwLPKa|y3wT%gBAk>pg*z=8s4UmZK(jK)g9^;e+#jYwF69JTFlz)U-(XXg zVD)U0B}ikjXJzsrW~I@l1yli*n|ww}_xpCY3<26Dc~n-dpoOqM{Yl-J@$IpVw7>YtzDZx zm}rqKSP(PM@M<^E+@ndf@wwxe$H(}rbzF`SGkwj1!{}Q6TTpZBhPDXdbCOaApGUN{ zp2q!e{c-`;@|>B9}2F<0G^h<$k%JitT<6nO`x0+K5ENk(~hYea8D*w-By=7s}!4= zEoMdOGi9B3%80sqaGRk?gj6fRr0Fa>BuM;1>R*i3bMU5rwG3r+@a~dnKMBZ_F6p*D zSRYfrDus5nFWJ%X>N6PgH~k zoB<3qHH^YyRy53{hNY>5xN6Eca!2jh-~3)NhoknTATWJ!&07-OYK-DUfkw!51UCML zP%@F<)A4~r{TkOKV9%x#edO(7H_Ke!J~A!tmmodA8dcLhhp0O@++ z35`8{H{So#b*sdgj8}LRCS%J zMNaioFbuoChaX&t7Y?OKWH~o|eKoy3#xH1@U=XTh@!Q~vn|%by)=@}Z~4PJ z#rEgEqtziT(C6b(ZY(f6TML12y;4W&hc|Wk^qF-Z1s^|{r;$!-$%|%?L5*qkt|0_#E8Vm^z>=DH zA)i=K;T0iy&HZUpgwtjWd=X{jWOQ{Vfx1iEWh^jM_jtfULMGKh;?UFn9d2W&&uVkI znCG!maf1t{Up0-*%Tdhm0F4C37_#;%@ma4c@(iAP_aZ){`hdlr=SCOwrW zCS`?8iWZGp-Jd2JaP~we_KLo04??+L+utj7_Ns~95mHW&?m6N)fbK6{TH82eKPdw* zyvp48VDX+auZ&A=LBr9ZzGzH+JHsC3p)|Bj{LquB=03Jv#0I!^36fe2=|kle_y}%Y zZMUr8YRuvpM(Yn?ik*}SUI%Qksmt(!<}vZl9k#%ZmL*phd>@;KK(izsGu1Pw3@gi% z8p#5HtQ8`>v<~M9-&pH{t`g;c>K?mcz8tk)kZB8|dc;byKSO&A!E(z=xHg{sp{>G+ zouA_g>SkebBfF}|RJUj274Y^1>;6s-eX)HzLvOD>Y1B#-Z854a=er5qqP4DvqU1IL z@VWKv&GuY%VqR$Y*Q&i3TF>jL@Uz_aKXQO$@3>X%wo>f-m<~=ye(bo_NNgIUKCT^* z3um;yNvFYd2dz%BImY}j_l*DvAuvj3Ev^cyap}Y4*`r*cE2i-e{jAGR`}Mk3WH}a5 zZ?mR>|=Izi2&RGE4_MJ(~Dz6D>7h=alt^eb2+Vd5Zh# zp`ZKBEzPQQHhds7y$?({(za}(Eve7P)~cR7yl$!N-j!maYX4zTjm{bu4*V@u)GYCA zM4{J97aDL`0J*tw;)~ZEF#Tb49m(s})Pxg}Nd_LQK2|8U9)fM!kz0rtUWz7dL{eUi zA(b07DqfmE9{hbrwrw#y?>ka@(p<#%J;XUWD6y;uZzKIrj231k^Xv>aV8O>(sDfCg@6$-_BI1rTWK3XbZ0xiZX`!QGFhWH$?;sOH?B<_4`KXd2TyX zViEvhZ!60PDc_QlVMh@e4$G?8P#0=6f2ve4d0S>Azth>50p#~Cx_~lOT&)vK%v9Mz z9J4WWMsU+Uul}8}SS9#=J9-0CXJo`-pjDLU{>Ut8dKIHMr}mW4{g_CwL^6n^%lNrb zN!T9a5yXWgpW9HnvbeE=II_8QZSPJxkw0IYBm}N!rT;bC8HRp?=|!5H)2+jsgyiqRIXnfwga8gMYN&vNAS~9r)D$peKR(j{E{TdRFU#B z<;Vl20JSOBn1$@~*W?Zk!!15f4HO>})HqKDn9MIH(`G?tN}H#xiehlE(3um>iCb$N zLD+Q@#TMJT8(G@h4UmfJ2+Ox`jD@Re{595tBwu5LH=ttNH@_8_$z5^-t4Cyf*bi)u ztx%NyZm=*{*DMOO^o6gJmm@E+WRd8yRwGaR^akm04&0lK=jL?hhqr%e6Mwx?Ws&JD zaQ5_EPnl}{ZoPhs$$2Ev?e{KIke~}D2u(QPJLV%&5@#~7@6T1jfD9g!cQaM9JgX&|LGoQE{Lh@=M65w z9alK+Q1=Ih4>Sg+ZLzH&q|WF$&FbK5JpOv|ddHyKj)r~3TH&<^x)VSPx8`PQ35i7NJ=jp(aN%iIR}7#z`P(|}jD1o% zZF9~T^QZ0Fdqv{mM8A#sSiZ(v9LGKCOtm-kiVCd#@<6s%wu#1Q1#=~%w> zrl?pthDR))hp&>qly?jMHL=53fPJ`lM?glcJuEH}CM{V{6U>hf73S~4!KXMEw^&Y7 z4{w&iLu_}AAbxDH1M=J~?GrWLND238JO$zVat1B%^L*33e$7|XA zls1r#cuaQ>#;0;+D!~HTl_8AL&$j%g1Kx7v24#aF{Q+p+h31$*S9%rXT9jjF=TNc( z23%Sr1IG1osJ(uAL_m04g~L~_ZYydDSj5l zGP6t#d5z@uBUZa|u?}9>N3u}1gNGOygP5L5Cxf4go3x?Kq#b7GTk=gZnnUuN++0zn z27%%V!d$FubU`2K2%!}ctgD)j;4nflhF2PE(VywWALKM&Bd+m+2=?>R0Il#dv;m)5 zts4r(Yp$l4crwsdomvk;s7a)g6-~uvQR3Y?Ik8WR*yTg??;)sRiuEjn-If_YydA%m z@wRljzltj_#crXi3e*T*B9(2_xD4t6{=Vn7Z$-=5jeAG2;u_ib`CIw}_3i1&CW+@f zX(6!tCnX8~j$!`DJUo6vF#C%afu3<0ZHR4vJx?6K84-%V@7nxrT>s+`+#jQRguME{ zj)XKcQl8)yXdv*CAm>mHg(A1flmgS@n)c*_`dRa{s|H#)r>#)JdP9yAb=+o$h(!x{ zUIRALkEsd}L_Jb6SRXRZJl0t0KmG9d@k$4loYX)@MpgpXm+$>OO;+wsU}%~sMSk>$ z%sxsAB3pH@vyV;WpKi8m@;5s|!64z>M=WfWc?)ZXuaj55`WGwvA5oI;7ejXIX$@~c z8nt*O`PL3n@K?G;R)z1-6%dGZ!D*@TGHA~$z^KL_W-Su$|ysw+^L+E~k@$rgI{Q!?8-0E!8 zxM1)H2Ia=)v|0=5#_nsENYw|{A9NH0eDY*iW-h?79B5slt`(DXoRbW$9~>amy7XH( zR-_o?F9f>fNlmVQ^tlEa>bob+eGEz(iwrysCSL_qHaOvz>oZ6-<@`Yk78*~=-Hf$7iBwJ~-ifEs1-!r|d|(zgR~z=> zIInVoYz>zLUx*dIZu&Jxh2EDv?C$#LQdB!Yf)-q_53BkF4K;_jvD{(WFzkHqQ9ZE( z<%u`;VW(gpeXol(ZIc;%&59NBvTpl}`LN(IXOb3Y`bn`aN{<|3e{9BH#Zzp66|u)| z>Do<1WAqZyBC5Fv!I~<^5quNgk63qfCf|)FV#V)}!AAc&xWZuMf$Ct)-zP^xj()iw z>-*+o^?QRy{iMFTcM%H>ovhdiFL(aKco{7`0B1p=0B1qje(@IAS(_Q^JN%B4Y(}iO zbQcdoz&Hr703cSVJNNiAFdDq$7QSpac`gCU4L^G#tz{7O8;Bob%0yI;ubxP@5K3t0 z1-2+o57JrJE}aUk&!{VbuB+8~kkDN%cB>PFNrO%>oWK|0VIe(*M3l{){UzjE(yNx? za6e&zYF1dO&M}XviL;G-(iao>Hb1hTi2@U;Cg<8vlze2rbP=$k^wo!bQ6!6;@-~~) z??Zr9ow zA=l~)->N9Co}($XV}|D~o6=y>dJmYt?dtS?7h%KVm*EViR=vieKx2H$jfN_7sarUf zmSPznK6b+CmpQ@@2_jz$Z;uI8h*b0{FAUxTVwhGVYU5Jv&=!=^lYd%!U+i^irr>bM zzS-;46hU%`k9W?*#aA!loZ^7kQ-1d8BjD@C`u9G4nf&WdYnK}MH0^Y2s{gf9993(*A|G`f;iqo97N*~28;L6JPpJBBH4?^SgR5% zu%Yg3cJXp&_F-)NWGW0&J!R=tA3n=wK`qsRV6vO2y`u-y#hGk}Ulzti1=T!l`GPJS z=G4qAj~5F6ni1Vl57OFmut_+3a`qw0K}a<${V#*R`Rh!Ar%Rgw)+{Uc~8t-%Ihbq z-j+|>cbi;~yfyxkl4}LS^4QNXjSeB$4N@c%^hvmKtx z0pRve5B^)M{%_1@ZfZ$qfJ)8)TIgpItLK6NcyoUNz-Mjk@Ka&lMpD<*3J{3+tSkSr zZYI74MtK0d8Nh}Aj0?C^0))Z*0$Ko|4`5-fYw#Ztx|e`M)@=6g0nNk%s4v4`0NDV3 zk$(aNj2kYlyp9eg0Cite{bxChmkiMtuw(CkDy9OY{&D}pkOpXIL^z{~#&0%1E{ zK>kKWfRLbwwWXniwY9mU&99s0sLU*`5Fi`R0H`V1bHxF7)Oh~@{qLkxKW*>VxO>Mc z_9Xz6CBOv$`cuIK{DNOpS@b_v_iMb2Qk2^-fHr0VWM=p)9vIcH@vQ6}bS*6Yn+<0` zHS-Vv-qdTr#{}n3wF3e|XZ$C;U)Qd{m8L}r&_O_ewZqTP@pJJM`6Zf!wef%L?Uz~3 zpTS_ne+l+mInQ6()XNOo&n#$?|C{C4&G0hQ=rg7e;4A)%PJcP|_)Ff=moW%6^ug z8A_gu6#(#0?fWxw=jFpM^OZb5obmUE|C2J}zt06c~G6javMT=uh?kFRJn{;a>`(Kf~)={S*9)sq#zMmpb6ju-(@G1p8+%!%NJUqO#AJ zLyrH1`9}=EfBQ1Nly7}TZE*Sx)c-E#`m*{jB`KeY#NB?E=#S?4w?O4ff|v4t&jdW4 zzd`U1Vt_B1UW$Z0Gx_`c2GegzhP~u`sr&TIN$CF@od2W(^^)qPP{uQrcGz!F{ex`A zOQx5i1kX&Gk-x$8hdJ>6Qlj7`)yr7$XDZp4-=+e5Uu^!Y>-Li5WoYd)iE;dIll<|% z{z+`)CCkeg&Sw^b#NTH5b42G$f|v1g&jg|=|DOc^tHoYMG(A({rT+%i|7@$5p)Jq& zu9?4q|IdLgFWc>9B)~ISBVax9V!-~>SoO!R`1K^~<^J \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi -done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >/dev/null -APP_HOME="`pwd -P`" -cd "$SAVED" >/dev/null - -APP_NAME="Gradle" -APP_BASE_NAME=`basename "$0"` - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS="" - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD="maximum" - -warn () { - echo "$*" -} - -die () { - echo - echo "$*" - echo - exit 1 -} - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -nonstop=false -case "`uname`" in - CYGWIN* ) - cygwin=true - ;; - Darwin* ) - darwin=true - ;; - MINGW* ) - msys=true - ;; - NONSTOP* ) - nonstop=true - ;; -esac - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" - else - JAVACMD="$JAVA_HOME/bin/java" - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD="java" - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." -fi - -# Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then - MAX_FD_LIMIT=`ulimit -H -n` - if [ $? -eq 0 ] ; then - if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then - MAX_FD="$MAX_FD_LIMIT" - fi - ulimit -n $MAX_FD - if [ $? -ne 0 ] ; then - warn "Could not set maximum file descriptor limit: $MAX_FD" - fi - else - warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" - fi -fi - -# For Darwin, add options to specify how the application appears in the dock -if $darwin; then - GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" -fi - -# For Cygwin, switch paths to Windows format before running java -if $cygwin ; then - APP_HOME=`cygpath --path --mixed "$APP_HOME"` - CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - JAVACMD=`cygpath --unix "$JAVACMD"` - - # We build the pattern for arguments to be converted via cygpath - ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` - SEP="" - for dir in $ROOTDIRSRAW ; do - ROOTDIRS="$ROOTDIRS$SEP$dir" - SEP="|" - done - OURCYGPATTERN="(^($ROOTDIRS))" - # Add a user-defined pattern to the cygpath arguments - if [ "$GRADLE_CYGPATTERN" != "" ] ; then - OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" - fi - # Now convert the arguments - kludge to limit ourselves to /bin/sh - i=0 - for arg in "$@" ; do - CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` - CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option - - if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition - eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` - else - eval `echo args$i`="\"$arg\"" - fi - i=$((i+1)) - done - case $i in - (0) set -- ;; - (1) set -- "$args0" ;; - (2) set -- "$args0" "$args1" ;; - (3) set -- "$args0" "$args1" "$args2" ;; - (4) set -- "$args0" "$args1" "$args2" "$args3" ;; - (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; - esac -fi - -# Escape application args -save () { - for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done - echo " " -} -APP_ARGS=$(save "$@") - -# Collect all arguments for the java command, following the shell quoting and substitution rules -eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" - -# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong -if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then - cd "$(dirname "$0")" -fi - -exec "$JAVACMD" "$@" diff --git a/samples/rest-notes-grails/gradlew.bat b/samples/rest-notes-grails/gradlew.bat deleted file mode 100644 index e95643d6a..000000000 --- a/samples/rest-notes-grails/gradlew.bat +++ /dev/null @@ -1,84 +0,0 @@ -@if "%DEBUG%" == "" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS= - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto init - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto init - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:init -@rem Get command-line arguments, handling Windows variants - -if not "%OS%" == "Windows_NT" goto win9xME_args - -:win9xME_args -@rem Slurp the command line arguments. -set CMD_LINE_ARGS= -set _SKIP=2 - -:win9xME_args_slurp -if "x%~1" == "x" goto execute - -set CMD_LINE_ARGS=%* - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% - -:end -@rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega diff --git a/samples/rest-notes-grails/grails-app/conf/application.yml b/samples/rest-notes-grails/grails-app/conf/application.yml deleted file mode 100644 index 915c149a9..000000000 --- a/samples/rest-notes-grails/grails-app/conf/application.yml +++ /dev/null @@ -1,100 +0,0 @@ ---- -grails: - profile: rest-api - codegen: - defaultPackage: com.example -info: - app: - name: '@info.app.name@' - version: '@info.app.version@' - grailsVersion: '@info.app.grailsVersion@' -spring: - groovy: - template: - check-template-location: false - ---- -grails: - mime: - disable: - accept: - header: - userAgents: - - Gecko - - WebKit - - Presto - - Trident - types: - all: '*/*' - atom: application/atom+xml - css: text/css - csv: text/csv - form: application/x-www-form-urlencoded - html: - - text/html - - application/xhtml+xml - js: text/javascript - json: - - application/json - - text/json - multipartForm: multipart/form-data - rss: application/rss+xml - text: text/plain - hal: - - application/hal+json - - application/hal+xml - xml: - - text/xml - - application/xml - urlmapping: - cache: - maxsize: 1000 - controllers: - defaultScope: singleton - converters: - encoding: UTF-8 - hibernate: - cache: - queries: false - ---- -dataSource: - pooled: true - jmxExport: true - driverClassName: org.h2.Driver - username: sa - password: - -environments: - development: - dataSource: - dbCreate: create-drop - url: jdbc:h2:mem:devDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE - test: - dataSource: - dbCreate: update - url: jdbc:h2:mem:testDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE - server: - port: 0 - production: - dataSource: - dbCreate: update - url: jdbc:h2:./prodDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE - properties: - jmxEnabled: true - initialSize: 5 - maxActive: 50 - minIdle: 5 - maxIdle: 25 - maxWait: 10000 - maxAge: 600000 - timeBetweenEvictionRunsMillis: 5000 - minEvictableIdleTimeMillis: 60000 - validationQuery: SELECT 1 - validationQueryTimeout: 3 - validationInterval: 15000 - testOnBorrow: true - testWhileIdle: true - testOnReturn: false - jdbcInterceptors: ConnectionState - defaultTransactionIsolation: 2 # TRANSACTION_READ_COMMITTED diff --git a/samples/rest-notes-grails/grails-app/conf/logback.groovy b/samples/rest-notes-grails/grails-app/conf/logback.groovy deleted file mode 100644 index 41467f2a0..000000000 --- a/samples/rest-notes-grails/grails-app/conf/logback.groovy +++ /dev/null @@ -1,39 +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 - * - * https://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. - */ - -import grails.util.BuildSettings -import grails.util.Environment - -// See https://logback.qos.ch/manual/groovy.html for details on configuration -appender('STDOUT', ConsoleAppender) { - encoder(PatternLayoutEncoder) { - pattern = "%level %logger - %msg%n" - } -} - -root(ERROR, ['STDOUT']) - -def targetDir = BuildSettings.TARGET_DIR -if (Environment.isDevelopmentMode() && targetDir) { - appender("FULL_STACKTRACE", FileAppender) { - file = "${targetDir}/stacktrace.log" - append = true - encoder(PatternLayoutEncoder) { - pattern = "%level %logger - %msg%n" - } - } - logger("StackTrace", ERROR, ['FULL_STACKTRACE'], false) -} diff --git a/samples/rest-notes-grails/grails-app/conf/spring/resources.groovy b/samples/rest-notes-grails/grails-app/conf/spring/resources.groovy deleted file mode 100644 index 4907ee437..000000000 --- a/samples/rest-notes-grails/grails-app/conf/spring/resources.groovy +++ /dev/null @@ -1,2 +0,0 @@ -// Place your Spring DSL code here -beans = {} diff --git a/samples/rest-notes-grails/grails-app/controllers/com/example/UrlMappings.groovy b/samples/rest-notes-grails/grails-app/controllers/com/example/UrlMappings.groovy deleted file mode 100644 index e90d3ba08..000000000 --- a/samples/rest-notes-grails/grails-app/controllers/com/example/UrlMappings.groovy +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright 2014-2017 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 - * - * https://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 com.example - -class UrlMappings { - - static mappings = { - '/notes'(resources: 'note') - - "500"(view: '/error') - "404"(view: '/notFound') - } - -} diff --git a/samples/rest-notes-grails/grails-app/domain/com/example/Note.groovy b/samples/rest-notes-grails/grails-app/domain/com/example/Note.groovy deleted file mode 100644 index bbff273d2..000000000 --- a/samples/rest-notes-grails/grails-app/domain/com/example/Note.groovy +++ /dev/null @@ -1,37 +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 - * - * https://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 com.example - -import grails.rest.Resource - -@Resource(uri='/notes') -class Note { - - Long id - - String title - - String body - - static hasMany = [tags: Tag] - - static mapping = { - tags joinTable: [name: "mm_notes_tags", key: 'mm_note_id' ] - } - -} - diff --git a/samples/rest-notes-grails/grails-app/domain/com/example/Tag.groovy b/samples/rest-notes-grails/grails-app/domain/com/example/Tag.groovy deleted file mode 100644 index 72d2d2723..000000000 --- a/samples/rest-notes-grails/grails-app/domain/com/example/Tag.groovy +++ /dev/null @@ -1,36 +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 - * - * https://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 com.example - -import grails.rest.Resource - -@Resource(uri='/tags') -class Tag { - - Long id - - String name - - static hasMany = [notes: Note] - - static belongsTo = Note - - static mapping = { - notes joinTable: [name: "mm_notes_tags", key: 'mm_tag_id'] - } - -} diff --git a/samples/rest-notes-grails/grails-app/i18n/messages.properties b/samples/rest-notes-grails/grails-app/i18n/messages.properties deleted file mode 100644 index b04513621..000000000 --- a/samples/rest-notes-grails/grails-app/i18n/messages.properties +++ /dev/null @@ -1,56 +0,0 @@ -default.doesnt.match.message=Property [{0}] of class [{1}] with value [{2}] does not match the required pattern [{3}] -default.invalid.url.message=Property [{0}] of class [{1}] with value [{2}] is not a valid URL -default.invalid.creditCard.message=Property [{0}] of class [{1}] with value [{2}] is not a valid credit card number -default.invalid.email.message=Property [{0}] of class [{1}] with value [{2}] is not a valid e-mail address -default.invalid.range.message=Property [{0}] of class [{1}] with value [{2}] does not fall within the valid range from [{3}] to [{4}] -default.invalid.size.message=Property [{0}] of class [{1}] with value [{2}] does not fall within the valid size range from [{3}] to [{4}] -default.invalid.max.message=Property [{0}] of class [{1}] with value [{2}] exceeds maximum value [{3}] -default.invalid.min.message=Property [{0}] of class [{1}] with value [{2}] is less than minimum value [{3}] -default.invalid.max.size.message=Property [{0}] of class [{1}] with value [{2}] exceeds the maximum size of [{3}] -default.invalid.min.size.message=Property [{0}] of class [{1}] with value [{2}] is less than the minimum size of [{3}] -default.invalid.validator.message=Property [{0}] of class [{1}] with value [{2}] does not pass custom validation -default.not.inlist.message=Property [{0}] of class [{1}] with value [{2}] is not contained within the list [{3}] -default.blank.message=Property [{0}] of class [{1}] cannot be blank -default.not.equal.message=Property [{0}] of class [{1}] with value [{2}] cannot equal [{3}] -default.null.message=Property [{0}] of class [{1}] cannot be null -default.not.unique.message=Property [{0}] of class [{1}] with value [{2}] must be unique - -default.paginate.prev=Previous -default.paginate.next=Next -default.boolean.true=True -default.boolean.false=False -default.date.format=yyyy-MM-dd HH:mm:ss z -default.number.format=0 - -default.created.message={0} {1} created -default.updated.message={0} {1} updated -default.deleted.message={0} {1} deleted -default.not.deleted.message={0} {1} could not be deleted -default.not.found.message={0} not found with id {1} -default.optimistic.locking.failure=Another user has updated this {0} while you were editing - -default.home.label=Home -default.list.label={0} List -default.add.label=Add {0} -default.new.label=New {0} -default.create.label=Create {0} -default.show.label=Show {0} -default.edit.label=Edit {0} - -default.button.create.label=Create -default.button.edit.label=Edit -default.button.update.label=Update -default.button.delete.label=Delete -default.button.delete.confirm.message=Are you sure? - -# Data binding errors. Use "typeMismatch.$className.$propertyName to customize (eg typeMismatch.Book.author) -typeMismatch.java.net.URL=Property {0} must be a valid URL -typeMismatch.java.net.URI=Property {0} must be a valid URI -typeMismatch.java.util.Date=Property {0} must be a valid Date -typeMismatch.java.lang.Double=Property {0} must be a valid number -typeMismatch.java.lang.Integer=Property {0} must be a valid number -typeMismatch.java.lang.Long=Property {0} must be a valid number -typeMismatch.java.lang.Short=Property {0} must be a valid number -typeMismatch.java.math.BigDecimal=Property {0} must be a valid number -typeMismatch.java.math.BigInteger=Property {0} must be a valid number -typeMismatch=Property {0} is type-mismatched diff --git a/samples/rest-notes-grails/grails-app/init/com/example/Application.groovy b/samples/rest-notes-grails/grails-app/init/com/example/Application.groovy deleted file mode 100644 index 86736fa40..000000000 --- a/samples/rest-notes-grails/grails-app/init/com/example/Application.groovy +++ /dev/null @@ -1,28 +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 - * - * https://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 com.example - -import grails.boot.GrailsApp -import grails.boot.config.GrailsAutoConfiguration - -class Application extends GrailsAutoConfiguration { - - static void main(String[] args) { - GrailsApp.run(Application, args) - } - -} diff --git a/samples/rest-notes-grails/grails-app/init/com/example/BootStrap.groovy b/samples/rest-notes-grails/grails-app/init/com/example/BootStrap.groovy deleted file mode 100644 index fd751b00f..000000000 --- a/samples/rest-notes-grails/grails-app/init/com/example/BootStrap.groovy +++ /dev/null @@ -1,31 +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 - * - * https://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 com.example - -class BootStrap { - - def init = { servletContext -> - environments { - test { - new Note(title: 'Hello, World!', body: 'Hello from the Integration Test').save() - } - } - } - - def destroy = {} - -} diff --git a/samples/rest-notes-grails/grails-app/views/error.gson b/samples/rest-notes-grails/grails-app/views/error.gson deleted file mode 100644 index 314e80db7..000000000 --- a/samples/rest-notes-grails/grails-app/views/error.gson +++ /dev/null @@ -1,6 +0,0 @@ -response.status 500 - -json { - message "Internal server error" - error 500 -} \ No newline at end of file diff --git a/samples/rest-notes-grails/grails-app/views/notFound.gson b/samples/rest-notes-grails/grails-app/views/notFound.gson deleted file mode 100644 index 1a710b267..000000000 --- a/samples/rest-notes-grails/grails-app/views/notFound.gson +++ /dev/null @@ -1,6 +0,0 @@ -response.status 404 - -json { - message "Not Found" - error 404 -} \ No newline at end of file diff --git a/samples/rest-notes-grails/settings.gradle b/samples/rest-notes-grails/settings.gradle deleted file mode 100644 index e69de29bb..000000000 diff --git a/samples/rest-notes-grails/src/docs/asciidoc/index.adoc b/samples/rest-notes-grails/src/docs/asciidoc/index.adoc deleted file mode 100644 index 72d379b4a..000000000 --- a/samples/rest-notes-grails/src/docs/asciidoc/index.adoc +++ /dev/null @@ -1,98 +0,0 @@ -= Grails RESTful Notes API Guide -Andy Wilkinson; Jenn Strater -:doctype: book -:icons: font -:source-highlighter: highlightjs -:toc: left -:toclevels: 4 -:sectlinks: -:operation-curl-request-title: Example request -:operation-http-response-title: Example response - -[[overview]] -= Overview - -[[overview-http-verbs]] -== HTTP verbs - -Grails RESTful notes tries to adhere as closely as possible to standard HTTP and REST conventions in its -use of HTTP verbs. - -|=== -| Verb | Usage - -| `GET` -| Used to retrieve a resource - -| `POST` -| Used to create a new resource - -| `PATCH` -| Used to update an existing resource, including partial updates - -| `DELETE` -| Used to delete an existing resource -|=== - -[[overview-http-status-codes]] -== HTTP status codes - -Grails RESTful notes tries to adhere as closely as possible to standard HTTP and REST conventions in its -use of HTTP status codes. - -|=== -| Status code | Usage - -| `200 OK` -| The request completed successfully - -| `201 Created` -| A new resource has been created successfully. The resource's URI is available from the response's -`Location` header - -| `204 No Content` -| An update to an existing resource has been applied successfully - -| `400 Bad Request` -| The request was malformed. The response body will include an error providing further information - -| `404 Not Found` -| The requested resource did not exist -|=== - -[[resources]] -= Resources - - - -[[resources-notes]] -== Notes - -The Notes resources is used to create and list notes - - - -[[resources-notes-list]] -=== Listing notes - -A `GET` request will list all of the service's notes. - -operation::notes-list-example[snippets='response-fields,curl-request,http-response'] - - - -[[resources-notes-create]] -=== Creating a note - -A `POST` request is used to create a note - -operation::notes-create-example[snippets='request-fields,curl-request,http-response'] - - - -[[resources-note-retrieve]] -=== Retrieve a note - -A `GET` request will retrieve the details of a note - -operation::note-get-example[snippets='response-fields,curl-request,http-response'] 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 deleted file mode 100644 index 0514f84bf..000000000 --- a/samples/rest-notes-grails/src/integration-test/groovy/com/example/ApiDocumentationSpec.groovy +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Copyright 2014-2017 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 - * - * https://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 com.example - -import org.springframework.restdocs.payload.JsonFieldType - -import static io.restassured.RestAssured.given -import static org.hamcrest.CoreMatchers.is -import static org.springframework.restdocs.operation.preprocess.Preprocessors.preprocessRequest -import static org.springframework.restdocs.operation.preprocess.Preprocessors.preprocessResponse -import static org.springframework.restdocs.operation.preprocess.Preprocessors.prettyPrint -import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath -import static org.springframework.restdocs.payload.PayloadDocumentation.requestFields -import static org.springframework.restdocs.payload.PayloadDocumentation.responseFields -import static org.springframework.restdocs.payload.PayloadDocumentation.subsectionWithPath -import static org.springframework.restdocs.restassured3.operation.preprocess.RestAssuredPreprocessors.modifyUris -import static org.springframework.restdocs.restassured3.RestAssuredRestDocumentation.document -import static org.springframework.restdocs.restassured3.RestAssuredRestDocumentation.documentationConfiguration - -import io.restassured.builder.RequestSpecBuilder -import io.restassured.specification.RequestSpecification -import grails.test.mixin.integration.Integration -import grails.transaction.Rollback -import org.junit.Rule -import org.springframework.beans.factory.annotation.Value -import org.springframework.http.MediaType -import org.springframework.restdocs.JUnitRestDocumentation -import spock.lang.Specification - -@Integration -@Rollback -class ApiDocumentationSpec extends Specification { - - @Rule - JUnitRestDocumentation restDocumentation = new JUnitRestDocumentation() - - @Value('${local.server.port}') - Integer serverPort - - protected RequestSpecification documentationSpec - - void setup() { - this.documentationSpec = new RequestSpecBuilder() - .addFilter(documentationConfiguration(restDocumentation)) - .build() - } - - void 'test and document notes list request'() { - expect: - given(this.documentationSpec) - .accept(MediaType.APPLICATION_JSON.toString()) - .filter(document('notes-list-example', - preprocessRequest(modifyUris() - .host('api.example.com') - .removePort()), - preprocessResponse(prettyPrint()), - responseFields( - fieldWithPath('[].id').description('the id of the note'), - fieldWithPath('[].title').description('the title of the note'), - fieldWithPath('[].body').description('the body of the note'), - fieldWithPath('[].tags').type(JsonFieldType.ARRAY).description('the list of tags associated with the note'), - ))) - .when() - .port(this.serverPort) - .get('/notes') - .then() - .assertThat() - .statusCode(is(200)) - } - - void 'test and document create new note'() { - expect: - given(this.documentationSpec) - .accept(MediaType.APPLICATION_JSON.toString()) - .contentType(MediaType.APPLICATION_JSON.toString()) - .filter(document('notes-create-example', - preprocessRequest(modifyUris() - .host('api.example.com') - .removePort()), - preprocessResponse(prettyPrint()), - requestFields( - fieldWithPath('title').description('the title of the note'), - fieldWithPath('body').description('the body of the note'), - subsectionWithPath('tags').type(JsonFieldType.ARRAY).description('a list of tags associated to the note') - ), - responseFields( - fieldWithPath('id').description('the id of the note'), - fieldWithPath('title').description('the title of the note'), - fieldWithPath('body').description('the body of the note'), - subsectionWithPath('tags').type(JsonFieldType.ARRAY).description('the list of tags associated with the note') - ))) - .body('{ "body": "My test example", "title": "Eureka!", "tags": [{"name": "testing123"}] }') - .when() - .port(this.serverPort) - .post('/notes') - .then() - .assertThat() - .statusCode(is(201)) - } - - void 'test and document getting specific note'() { - expect: - given(this.documentationSpec) - .accept(MediaType.APPLICATION_JSON.toString()) - .filter(document('note-get-example', - preprocessRequest(modifyUris() - .host('api.example.com') - .removePort()), - preprocessResponse(prettyPrint()), - responseFields( - fieldWithPath('id').description('the id of the note'), - fieldWithPath('title').description('the title of the note'), - fieldWithPath('body').description('the body of the note'), - fieldWithPath('tags').type(JsonFieldType.ARRAY).description('the list of tags associated with the note'), - ))) - .when() - .port(this.serverPort) - .get('/notes/1') - .then() - .assertThat() - .statusCode(is(200)) - } - -} From 3597ebc35a099f4c9a825759ded9680b00a3ca1c Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Thu, 12 Sep 2019 17:03:21 +0100 Subject: [PATCH 064/502] Allow responses with non-standard status codes to be documented Fixes gh-639 --- .../restdocs/operation/OperationResponse.java | 12 ++++- .../operation/OperationResponseFactory.java | 12 +++-- .../operation/StandardOperationResponse.java | 9 +++- .../UriModifyingOperationPreprocessor.java | 2 +- .../RestDocumentationGeneratorTests.java | 4 +- .../RestDocumentationConfigurerTests.java | 2 +- .../ContentTypeLinkExtractorTests.java | 6 +-- .../LinkExtractorsPayloadTests.java | 2 +- ...ntModifyingOperationPreprocessorTests.java | 2 +- ...derRemovingOperationPreprocessorTests.java | 2 +- ...riModifyingOperationPreprocessorTests.java | 4 +- .../restdocs/test/OperationBuilder.java | 4 +- .../mockmvc/MockMvcResponseConverter.java | 5 +- .../MockMvcResponseConverterTests.java | 11 +++- .../RestAssuredResponseConverter.java | 5 +- .../RestAssuredResponseConverterTests.java | 52 +++++++++++++++++++ .../WebTestClientResponseConverter.java | 2 +- 17 files changed, 107 insertions(+), 29 deletions(-) create mode 100644 spring-restdocs-restassured/src/test/java/org/springframework/restdocs/restassured3/RestAssuredResponseConverterTests.java diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/OperationResponse.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/OperationResponse.java index 6e5e20bb2..378160d42 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/OperationResponse.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/OperationResponse.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2015 the original author or authors. + * Copyright 2014-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. @@ -30,10 +30,18 @@ public interface OperationResponse { /** * Returns the status of the response. - * @return the status + * @return the status or {@code null} if the status is unknown to {@link HttpStatus} */ HttpStatus getStatus(); + /** + * Returns the status code of the response. + * @return the status code + */ + default int getStatusCode() { + throw new UnsupportedOperationException(); + } + /** * Returns the headers in the response. * @return the headers diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/OperationResponseFactory.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/OperationResponseFactory.java index e865987eb..2768451b1 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/OperationResponseFactory.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/OperationResponseFactory.java @@ -34,8 +34,14 @@ public class OperationResponseFactory { * @param headers the request's headers * @param content the content of the request * @return the {@code OperationResponse} + * @deprecated since 2.0.4 in favor of {@link #create(int, HttpHeaders, byte[])} */ + @Deprecated public OperationResponse create(HttpStatus status, HttpHeaders headers, byte[] content) { + return this.create(status.value(), headers, content); + } + + public OperationResponse create(int status, HttpHeaders headers, byte[] content) { return new StandardOperationResponse(status, augmentHeaders(headers, content), content); } @@ -49,8 +55,8 @@ public OperationResponse create(HttpStatus status, HttpHeaders headers, byte[] c * @return the new response with the new content */ public OperationResponse createFrom(OperationResponse original, byte[] newContent) { - return new StandardOperationResponse(original.getStatus(), getUpdatedHeaders(original.getHeaders(), newContent), - newContent); + return new StandardOperationResponse(original.getStatusCode(), + getUpdatedHeaders(original.getHeaders(), newContent), newContent); } /** @@ -61,7 +67,7 @@ public OperationResponse createFrom(OperationResponse original, byte[] newConten * @return the new response with the new headers */ public OperationResponse createFrom(OperationResponse original, HttpHeaders newHeaders) { - return new StandardOperationResponse(original.getStatus(), newHeaders, original.getContent()); + return new StandardOperationResponse(original.getStatusCode(), newHeaders, original.getContent()); } private HttpHeaders augmentHeaders(HttpHeaders originalHeaders, byte[] content) { diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/StandardOperationResponse.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/StandardOperationResponse.java index 6896245cd..3a169365b 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/StandardOperationResponse.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/StandardOperationResponse.java @@ -26,7 +26,7 @@ */ class StandardOperationResponse extends AbstractOperationMessage implements OperationResponse { - private final HttpStatus status; + private final int status; /** * Creates a new response with the given {@code status}, {@code headers}, and @@ -35,13 +35,18 @@ class StandardOperationResponse extends AbstractOperationMessage implements Oper * @param headers the headers of the response * @param content the content of the response */ - StandardOperationResponse(HttpStatus status, HttpHeaders headers, byte[] content) { + StandardOperationResponse(int status, HttpHeaders headers, byte[] content) { super(content, headers); this.status = status; } @Override public HttpStatus getStatus() { + return HttpStatus.resolve(this.status); + } + + @Override + public int getStatusCode() { return this.status; } diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/preprocess/UriModifyingOperationPreprocessor.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/preprocess/UriModifyingOperationPreprocessor.java index f1856dbd6..42e0df1c2 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/preprocess/UriModifyingOperationPreprocessor.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/preprocess/UriModifyingOperationPreprocessor.java @@ -141,7 +141,7 @@ public OperationRequest preprocess(OperationRequest request) { @Override public OperationResponse preprocess(OperationResponse response) { - return this.contentModifyingDelegate.preprocess(new OperationResponseFactory().create(response.getStatus(), + return this.contentModifyingDelegate.preprocess(new OperationResponseFactory().create(response.getStatusCode(), modify(response.getHeaders()), response.getContent())); } diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/RestDocumentationGeneratorTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/RestDocumentationGeneratorTests.java index c16c27279..c84ec96e8 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/RestDocumentationGeneratorTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/RestDocumentationGeneratorTests.java @@ -69,7 +69,7 @@ public class RestDocumentationGeneratorTests { private final OperationRequest operationRequest = new OperationRequestFactory() .create(URI.create("http://localhost:8080"), null, null, new HttpHeaders(), null, null); - private final OperationResponse operationResponse = new OperationResponseFactory().create(null, null, null); + private final OperationResponse operationResponse = new OperationResponseFactory().create(0, null, null); private final Snippet snippet = mock(Snippet.class); @@ -197,7 +197,7 @@ private static OperationRequest createRequest() { } private static OperationResponse createResponse() { - return new OperationResponseFactory().create(null, null, null); + return new OperationResponseFactory().create(0, null, null); } } 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 990a3e603..c8ade9271 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 @@ -217,7 +217,7 @@ public void customDefaultOperationResponsePreprocessor() { .get(RestDocumentationGenerator.ATTRIBUTE_NAME_DEFAULT_OPERATION_RESPONSE_PREPROCESSOR); HttpHeaders headers = new HttpHeaders(); headers.add("Foo", "value"); - OperationResponse response = new OperationResponseFactory().create(HttpStatus.OK, headers, null); + OperationResponse response = new OperationResponseFactory().create(HttpStatus.OK.value(), headers, null); assertThat(preprocessor.preprocess(response).getHeaders()).doesNotContainKey("Foo"); } diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/hypermedia/ContentTypeLinkExtractorTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/hypermedia/ContentTypeLinkExtractorTests.java index cb88d4d2c..e987a5af2 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/hypermedia/ContentTypeLinkExtractorTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/hypermedia/ContentTypeLinkExtractorTests.java @@ -49,7 +49,7 @@ public class ContentTypeLinkExtractorTests { public void extractionFailsWithNullContentType() throws IOException { this.thrown.expect(IllegalStateException.class); new ContentTypeLinkExtractor() - .extractLinks(this.responseFactory.create(HttpStatus.OK, new HttpHeaders(), null)); + .extractLinks(this.responseFactory.create(HttpStatus.OK.value(), new HttpHeaders(), null)); } @Test @@ -59,7 +59,7 @@ public void extractorCalledWithMatchingContextType() throws IOException { extractors.put(MediaType.APPLICATION_JSON, extractor); HttpHeaders httpHeaders = new HttpHeaders(); httpHeaders.setContentType(MediaType.APPLICATION_JSON); - OperationResponse response = this.responseFactory.create(HttpStatus.OK, httpHeaders, null); + OperationResponse response = this.responseFactory.create(HttpStatus.OK.value(), httpHeaders, null); new ContentTypeLinkExtractor(extractors).extractLinks(response); verify(extractor).extractLinks(response); } @@ -71,7 +71,7 @@ public void extractorCalledWithCompatibleContextType() throws IOException { extractors.put(MediaType.APPLICATION_JSON, extractor); HttpHeaders httpHeaders = new HttpHeaders(); httpHeaders.setContentType(MediaType.parseMediaType("application/json;foo=bar")); - OperationResponse response = this.responseFactory.create(HttpStatus.OK, httpHeaders, null); + OperationResponse response = this.responseFactory.create(HttpStatus.OK.value(), httpHeaders, null); new ContentTypeLinkExtractor(extractors).extractLinks(response); verify(extractor).extractLinks(response); } diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/hypermedia/LinkExtractorsPayloadTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/hypermedia/LinkExtractorsPayloadTests.java index 55e4ccacc..1eb99f194 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/hypermedia/LinkExtractorsPayloadTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/hypermedia/LinkExtractorsPayloadTests.java @@ -106,7 +106,7 @@ private void assertLinks(List expectedLinks, Map> actua } private OperationResponse createResponse(String contentName) throws IOException { - return this.responseFactory.create(HttpStatus.OK, null, + return this.responseFactory.create(HttpStatus.OK.value(), null, FileCopyUtils.copyToByteArray(getPayloadFile(contentName))); } diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/operation/preprocess/ContentModifyingOperationPreprocessorTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/operation/preprocess/ContentModifyingOperationPreprocessorTests.java index 1835b856a..57b54c98a 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/operation/preprocess/ContentModifyingOperationPreprocessorTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/operation/preprocess/ContentModifyingOperationPreprocessorTests.java @@ -67,7 +67,7 @@ public void modifyRequestContent() { @Test public void modifyResponseContent() { - OperationResponse response = this.responseFactory.create(HttpStatus.OK, new HttpHeaders(), + OperationResponse response = this.responseFactory.create(HttpStatus.OK.value(), new HttpHeaders(), "content".getBytes()); OperationResponse preprocessed = this.preprocessor.preprocess(response); assertThat(preprocessed.getContent()).isEqualTo("modified".getBytes()); diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/operation/preprocess/HeaderRemovingOperationPreprocessorTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/operation/preprocess/HeaderRemovingOperationPreprocessorTests.java index 79330122f..87f5e8c0c 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/operation/preprocess/HeaderRemovingOperationPreprocessorTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/operation/preprocess/HeaderRemovingOperationPreprocessorTests.java @@ -87,7 +87,7 @@ public void removeAllHeaders() { } private OperationResponse createResponse(String... extraHeaders) { - return this.responseFactory.create(HttpStatus.OK, getHttpHeaders(extraHeaders), new byte[0]); + return this.responseFactory.create(HttpStatus.OK.value(), getHttpHeaders(extraHeaders), new byte[0]); } private HttpHeaders getHttpHeaders(String... extraHeaders) { diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/operation/preprocess/UriModifyingOperationPreprocessorTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/operation/preprocess/UriModifyingOperationPreprocessorTests.java index 2880c4b0a..2b9562bd3 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/operation/preprocess/UriModifyingOperationPreprocessorTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/operation/preprocess/UriModifyingOperationPreprocessorTests.java @@ -321,13 +321,13 @@ private OperationRequest createRequestWithPartWithContent(String content) { } private OperationResponse createResponseWithContent(String content) { - return this.responseFactory.create(HttpStatus.OK, new HttpHeaders(), content.getBytes()); + return this.responseFactory.create(HttpStatus.OK.value(), new HttpHeaders(), content.getBytes()); } private OperationResponse createResponseWithHeader(String name, String value) { HttpHeaders headers = new HttpHeaders(); headers.add(name, value); - return this.responseFactory.create(HttpStatus.OK, headers, new byte[0]); + return this.responseFactory.create(HttpStatus.OK.value(), headers, new byte[0]); } } 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 d4ec2520b..fbe16a085 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 @@ -261,7 +261,7 @@ public OperationRequestPartBuilder header(String name, String value) { */ public final class OperationResponseBuilder { - private HttpStatus status = HttpStatus.OK; + private int status = HttpStatus.OK.value(); private HttpHeaders headers = new HttpHeaders(); @@ -272,7 +272,7 @@ private OperationResponse buildResponse() { } public OperationResponseBuilder status(int status) { - this.status = HttpStatus.valueOf(status); + this.status = status; return this; } diff --git a/spring-restdocs-mockmvc/src/main/java/org/springframework/restdocs/mockmvc/MockMvcResponseConverter.java b/spring-restdocs-mockmvc/src/main/java/org/springframework/restdocs/mockmvc/MockMvcResponseConverter.java index 8e1e49aaa..93e6b1f47 100644 --- a/spring-restdocs-mockmvc/src/main/java/org/springframework/restdocs/mockmvc/MockMvcResponseConverter.java +++ b/spring-restdocs-mockmvc/src/main/java/org/springframework/restdocs/mockmvc/MockMvcResponseConverter.java @@ -19,7 +19,6 @@ import javax.servlet.http.Cookie; import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpStatus; import org.springframework.mock.web.MockHttpServletResponse; import org.springframework.restdocs.operation.OperationResponse; import org.springframework.restdocs.operation.OperationResponseFactory; @@ -36,8 +35,8 @@ class MockMvcResponseConverter implements ResponseConverter { @Override public OperationResponse convert(Response response) { - return new OperationResponseFactory().create(HttpStatus.valueOf(response.getStatusCode()), - extractHeaders(response), extractContent(response)); + return new OperationResponseFactory().create(response.getStatusCode(), extractHeaders(response), + extractContent(response)); } private HttpHeaders extractHeaders(Response response) { diff --git a/spring-restdocs-restassured/src/test/java/org/springframework/restdocs/restassured3/RestAssuredResponseConverterTests.java b/spring-restdocs-restassured/src/test/java/org/springframework/restdocs/restassured3/RestAssuredResponseConverterTests.java new file mode 100644 index 000000000..927cf67be --- /dev/null +++ b/spring-restdocs-restassured/src/test/java/org/springframework/restdocs/restassured3/RestAssuredResponseConverterTests.java @@ -0,0 +1,52 @@ +/* + * Copyright 2014-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 + * + * https://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.restassured3; + +import io.restassured.http.Headers; +import io.restassured.response.Response; +import io.restassured.response.ResponseBody; +import org.junit.Test; + +import org.springframework.restdocs.operation.OperationResponse; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.mock; + +/** + * Tests for {@link RestAssuredResponseConverter}. + * + * @author Andy Wilkinson + */ +public class RestAssuredResponseConverterTests { + + private final RestAssuredResponseConverter converter = new RestAssuredResponseConverter(); + + @Test + public void responseWithCustomStatus() { + Response response = mock(Response.class); + given(response.getStatusCode()).willReturn(600); + given(response.getHeaders()).willReturn(new Headers()); + ResponseBody body = mock(ResponseBody.class); + given(response.getBody()).willReturn(body); + given(body.asByteArray()).willReturn(new byte[0]); + OperationResponse operationResponse = this.converter.convert(response); + assertThat(operationResponse.getStatus()).isNull(); + assertThat(operationResponse.getStatusCode()).isEqualTo(600); + } + +} diff --git a/spring-restdocs-webtestclient/src/main/java/org/springframework/restdocs/webtestclient/WebTestClientResponseConverter.java b/spring-restdocs-webtestclient/src/main/java/org/springframework/restdocs/webtestclient/WebTestClientResponseConverter.java index 293203dfa..df0a60843 100644 --- a/spring-restdocs-webtestclient/src/main/java/org/springframework/restdocs/webtestclient/WebTestClientResponseConverter.java +++ b/spring-restdocs-webtestclient/src/main/java/org/springframework/restdocs/webtestclient/WebTestClientResponseConverter.java @@ -36,7 +36,7 @@ class WebTestClientResponseConverter implements ResponseConverter Date: Fri, 13 Sep 2019 12:58:11 +0100 Subject: [PATCH 065/502] Broaden compatibility testing for Asciidoctor 2.x Closes gh-630 --- gradle.properties | 3 ++- settings.gradle | 2 +- .../build.gradle | 2 +- .../DefaultAttributesAsciidoctorJ2xPreprocessor.java | 2 +- .../RestDocsAsciidoctorJ2xExtensionRegistry.java | 8 ++++---- .../DefaultAttributesAsciidoctorJ2xPreprocessorTests.java | 6 +++--- spring-restdocs-asciidoctor/build.gradle | 6 +++--- .../org.asciidoctor.jruby.extension.spi.ExtensionRegistry | 2 +- 8 files changed, 16 insertions(+), 15 deletions(-) rename {spring-restdocs-asciidoctor-2.0 => spring-restdocs-asciidoctor-2.x}/build.gradle (84%) rename spring-restdocs-asciidoctor-2.0/src/main/java/org/springframework/restdocs/asciidoctor/DefaultAttributesAsciidoctorJ20Preprocessor.java => spring-restdocs-asciidoctor-2.x/src/main/java/org/springframework/restdocs/asciidoctor/DefaultAttributesAsciidoctorJ2xPreprocessor.java (95%) rename spring-restdocs-asciidoctor-2.0/src/main/java/org/springframework/restdocs/asciidoctor/RestDocsAsciidoctorJ20ExtensionRegistry.java => spring-restdocs-asciidoctor-2.x/src/main/java/org/springframework/restdocs/asciidoctor/RestDocsAsciidoctorJ2xExtensionRegistry.java (83%) rename spring-restdocs-asciidoctor-2.0/src/test/java/org/springframework/restdocs/asciidoctor/DefaultAttributesAsciidoctorJ20PreprocessorTests.java => spring-restdocs-asciidoctor-2.x/src/test/java/org/springframework/restdocs/asciidoctor/DefaultAttributesAsciidoctorJ2xPreprocessorTests.java (92%) diff --git a/gradle.properties b/gradle.properties index 98e26aa31..d7c7c7a43 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,4 +3,5 @@ javaFormatVersion=0.0.15 org.gradle.daemon=false asciidoctorj15Version=1.5.8.1 asciidoctorj16Version=1.6.2 -asciidoctorj20Version=2.0.0-RC.3 +asciidoctorj20Version=2.0.0 +asciidoctorj21Version=2.1.0 diff --git a/settings.gradle b/settings.gradle index eabf9a196..458a5e3c5 100644 --- a/settings.gradle +++ b/settings.gradle @@ -4,7 +4,7 @@ include 'docs' include 'spring-restdocs-asciidoctor' include 'spring-restdocs-asciidoctor-1.5' include 'spring-restdocs-asciidoctor-1.6' -include 'spring-restdocs-asciidoctor-2.0' +include 'spring-restdocs-asciidoctor-2.x' include 'spring-restdocs-asciidoctor-support' include 'spring-restdocs-core' include 'spring-restdocs-mockmvc' diff --git a/spring-restdocs-asciidoctor-2.0/build.gradle b/spring-restdocs-asciidoctor-2.x/build.gradle similarity index 84% rename from spring-restdocs-asciidoctor-2.0/build.gradle rename to spring-restdocs-asciidoctor-2.x/build.gradle index 9ac719ef9..f2ed1334e 100644 --- a/spring-restdocs-asciidoctor-2.0/build.gradle +++ b/spring-restdocs-asciidoctor-2.x/build.gradle @@ -1,4 +1,4 @@ -description = 'AsciidoctorJ 2.0 extensions for Spring REST Docs' +description = 'AsciidoctorJ 2.x extensions for Spring REST Docs' dependencies { compileOnly "org.asciidoctor:asciidoctorj:$asciidoctorj20Version" diff --git a/spring-restdocs-asciidoctor-2.0/src/main/java/org/springframework/restdocs/asciidoctor/DefaultAttributesAsciidoctorJ20Preprocessor.java b/spring-restdocs-asciidoctor-2.x/src/main/java/org/springframework/restdocs/asciidoctor/DefaultAttributesAsciidoctorJ2xPreprocessor.java similarity index 95% rename from spring-restdocs-asciidoctor-2.0/src/main/java/org/springframework/restdocs/asciidoctor/DefaultAttributesAsciidoctorJ20Preprocessor.java rename to spring-restdocs-asciidoctor-2.x/src/main/java/org/springframework/restdocs/asciidoctor/DefaultAttributesAsciidoctorJ2xPreprocessor.java index 5ccd4919c..3ed0a62ca 100644 --- a/spring-restdocs-asciidoctor-2.0/src/main/java/org/springframework/restdocs/asciidoctor/DefaultAttributesAsciidoctorJ20Preprocessor.java +++ b/spring-restdocs-asciidoctor-2.x/src/main/java/org/springframework/restdocs/asciidoctor/DefaultAttributesAsciidoctorJ2xPreprocessor.java @@ -26,7 +26,7 @@ * * @author Andy Wilkinson */ -final class DefaultAttributesAsciidoctorJ20Preprocessor extends Preprocessor { +final class DefaultAttributesAsciidoctorJ2xPreprocessor extends Preprocessor { private final SnippetsDirectoryResolver snippetsDirectoryResolver = new SnippetsDirectoryResolver(); diff --git a/spring-restdocs-asciidoctor-2.0/src/main/java/org/springframework/restdocs/asciidoctor/RestDocsAsciidoctorJ20ExtensionRegistry.java b/spring-restdocs-asciidoctor-2.x/src/main/java/org/springframework/restdocs/asciidoctor/RestDocsAsciidoctorJ2xExtensionRegistry.java similarity index 83% rename from spring-restdocs-asciidoctor-2.0/src/main/java/org/springframework/restdocs/asciidoctor/RestDocsAsciidoctorJ20ExtensionRegistry.java rename to spring-restdocs-asciidoctor-2.x/src/main/java/org/springframework/restdocs/asciidoctor/RestDocsAsciidoctorJ2xExtensionRegistry.java index c0158d01c..973b1b8c7 100644 --- a/spring-restdocs-asciidoctor-2.0/src/main/java/org/springframework/restdocs/asciidoctor/RestDocsAsciidoctorJ20ExtensionRegistry.java +++ b/spring-restdocs-asciidoctor-2.x/src/main/java/org/springframework/restdocs/asciidoctor/RestDocsAsciidoctorJ2xExtensionRegistry.java @@ -20,17 +20,17 @@ import org.asciidoctor.jruby.extension.spi.ExtensionRegistry; /** - * AsciidoctorJ 2.0 {@link ExtensionRegistry} for Spring REST Docs. + * AsciidoctorJ 2.x {@link ExtensionRegistry} for Spring REST Docs. * * @author Andy Wilkinson */ -public final class RestDocsAsciidoctorJ20ExtensionRegistry implements ExtensionRegistry { +public final class RestDocsAsciidoctorJ2xExtensionRegistry implements ExtensionRegistry { @Override public void register(Asciidoctor asciidoctor) { - asciidoctor.javaExtensionRegistry().preprocessor(new DefaultAttributesAsciidoctorJ20Preprocessor()); + asciidoctor.javaExtensionRegistry().preprocessor(new DefaultAttributesAsciidoctorJ2xPreprocessor()); asciidoctor.rubyExtensionRegistry() - .loadClass(RestDocsAsciidoctorJ20ExtensionRegistry.class + .loadClass(RestDocsAsciidoctorJ2xExtensionRegistry.class .getResourceAsStream("/extensions/operation_block_macro.rb")) .blockMacro("operation", "OperationBlockMacro"); } diff --git a/spring-restdocs-asciidoctor-2.0/src/test/java/org/springframework/restdocs/asciidoctor/DefaultAttributesAsciidoctorJ20PreprocessorTests.java b/spring-restdocs-asciidoctor-2.x/src/test/java/org/springframework/restdocs/asciidoctor/DefaultAttributesAsciidoctorJ2xPreprocessorTests.java similarity index 92% rename from spring-restdocs-asciidoctor-2.0/src/test/java/org/springframework/restdocs/asciidoctor/DefaultAttributesAsciidoctorJ20PreprocessorTests.java rename to spring-restdocs-asciidoctor-2.x/src/test/java/org/springframework/restdocs/asciidoctor/DefaultAttributesAsciidoctorJ2xPreprocessorTests.java index e5f5ace4e..4bb84aab4 100644 --- a/spring-restdocs-asciidoctor-2.0/src/test/java/org/springframework/restdocs/asciidoctor/DefaultAttributesAsciidoctorJ20PreprocessorTests.java +++ b/spring-restdocs-asciidoctor-2.x/src/test/java/org/springframework/restdocs/asciidoctor/DefaultAttributesAsciidoctorJ2xPreprocessorTests.java @@ -26,11 +26,11 @@ import static org.assertj.core.api.Assertions.assertThat; /** - * Tests for {@link DefaultAttributesAsciidoctorJ20Preprocessor}. + * Tests for {@link DefaultAttributesAsciidoctorJ2xPreprocessor}. * * @author Andy Wilkinson */ -public class DefaultAttributesAsciidoctorJ20PreprocessorTests { +public class DefaultAttributesAsciidoctorJ2xPreprocessorTests { @Test public void snippetsAttributeIsSet() { @@ -60,7 +60,7 @@ private Options createOptions(String attributes) { private Asciidoctor createAsciidoctor() { Asciidoctor asciidoctor = Asciidoctor.Factory.create(); - asciidoctor.javaExtensionRegistry().preprocessor(new DefaultAttributesAsciidoctorJ20Preprocessor()); + asciidoctor.javaExtensionRegistry().preprocessor(new DefaultAttributesAsciidoctorJ2xPreprocessor()); return asciidoctor; } diff --git a/spring-restdocs-asciidoctor/build.gradle b/spring-restdocs-asciidoctor/build.gradle index c7fab6756..dbcbf06f9 100644 --- a/spring-restdocs-asciidoctor/build.gradle +++ b/spring-restdocs-asciidoctor/build.gradle @@ -6,7 +6,7 @@ configurations { dependencies { merge project(':spring-restdocs-asciidoctor-1.5') merge project(':spring-restdocs-asciidoctor-1.6') - merge project(':spring-restdocs-asciidoctor-2.0') + merge project(':spring-restdocs-asciidoctor-2.x') testCompile 'org.apache.pdfbox:pdfbox' testCompile 'org.asciidoctor:asciidoctorj:1.5.8.1' testCompile 'org.assertj:assertj-core' @@ -18,7 +18,7 @@ dependencies { jar { dependsOn ':spring-restdocs-asciidoctor-1.5:jar' dependsOn ':spring-restdocs-asciidoctor-1.6:jar' - dependsOn ':spring-restdocs-asciidoctor-2.0:jar' + dependsOn ':spring-restdocs-asciidoctor-2.x:jar' from configurations.merge.collect { file -> zipTree(file) } } @@ -26,6 +26,6 @@ matrixTest { asciidoctorj { group = 'org.asciidoctor' artifact = 'asciidoctorj' - versions = [ asciidoctorj16Version, asciidoctorj20Version ] + versions = [ asciidoctorj16Version, asciidoctorj20Version, asciidoctorj21Version ] } } \ No newline at end of file diff --git a/spring-restdocs-asciidoctor/src/main/resources/META-INF/services/org.asciidoctor.jruby.extension.spi.ExtensionRegistry b/spring-restdocs-asciidoctor/src/main/resources/META-INF/services/org.asciidoctor.jruby.extension.spi.ExtensionRegistry index 7ae7da385..249b935ab 100644 --- a/spring-restdocs-asciidoctor/src/main/resources/META-INF/services/org.asciidoctor.jruby.extension.spi.ExtensionRegistry +++ b/spring-restdocs-asciidoctor/src/main/resources/META-INF/services/org.asciidoctor.jruby.extension.spi.ExtensionRegistry @@ -1 +1 @@ -org.springframework.restdocs.asciidoctor.RestDocsAsciidoctorJ20ExtensionRegistry +org.springframework.restdocs.asciidoctor.RestDocsAsciidoctorJ2xExtensionRegistry From 4bbc5b37b52d37adc8716e2a9846044d1b3241b8 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Fri, 13 Sep 2019 13:02:51 +0100 Subject: [PATCH 066/502] Perform compatibility testing against REST Assured 4.0 and 4.1 Closes gh-640 --- spring-restdocs-restassured/build.gradle | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/spring-restdocs-restassured/build.gradle b/spring-restdocs-restassured/build.gradle index 53433def8..0f372e7db 100644 --- a/spring-restdocs-restassured/build.gradle +++ b/spring-restdocs-restassured/build.gradle @@ -13,4 +13,11 @@ dependencies { test { jvmArgs "-javaagent:${configurations.jacoco.asPath}=destfile=${buildDir}/jacoco.exec,includes=org.springframework.restdocs.*" +} + +matrixTest { + restAssured { + group = 'io.rest-assured' + versions = ['4.0.0', '4.1.1'] + } } \ No newline at end of file From ef0973c5482e785bc1355d61669ddfd95d93c669 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Sat, 14 Sep 2019 17:38:29 +0100 Subject: [PATCH 067/502] Test against latest Framework 5.1 snapshot This updates REST Docs to test against Framework's latest 5.1 snapshot. Due to a bug in the behaviour of HttpHeaders' key set [1], HeaderRemovingOperationPreprocessor has been updated to no longer use it when removing headers from a request or response prior to it being documented. [1] https://github.com/spring-projects/spring-framework/issues/22821 --- spring-restdocs-core/build.gradle | 2 +- .../HeaderRemovingOperationPreprocessor.java | 11 +++++------ spring-restdocs-mockmvc/build.gradle | 2 +- spring-restdocs-webtestclient/build.gradle | 2 +- 4 files changed, 8 insertions(+), 9 deletions(-) diff --git a/spring-restdocs-core/build.gradle b/spring-restdocs-core/build.gradle index 186b3405a..8aac3d7a7 100644 --- a/spring-restdocs-core/build.gradle +++ b/spring-restdocs-core/build.gradle @@ -67,6 +67,6 @@ test { matrixTest { springFramework { group = 'org.springframework' - versions = ['5.1.0.BUILD-SNAPSHOT'] + versions = ['5.1.10.BUILD-SNAPSHOT'] } } \ No newline at end of file diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/preprocess/HeaderRemovingOperationPreprocessor.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/preprocess/HeaderRemovingOperationPreprocessor.java index 4f0091ef9..01710e992 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/preprocess/HeaderRemovingOperationPreprocessor.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/preprocess/HeaderRemovingOperationPreprocessor.java @@ -16,7 +16,8 @@ package org.springframework.restdocs.operation.preprocess; -import java.util.Iterator; +import java.util.List; +import java.util.Map.Entry; import org.springframework.http.HttpHeaders; import org.springframework.restdocs.operation.OperationRequest; @@ -55,11 +56,9 @@ public OperationRequest preprocess(OperationRequest request) { private HttpHeaders removeHeaders(HttpHeaders originalHeaders) { HttpHeaders processedHeaders = new HttpHeaders(); - processedHeaders.putAll(originalHeaders); - Iterator headers = processedHeaders.keySet().iterator(); - while (headers.hasNext()) { - if (this.headerFilter.excludeHeader(headers.next())) { - headers.remove(); + for (Entry> header : originalHeaders.entrySet()) { + if (!this.headerFilter.excludeHeader(header.getKey())) { + processedHeaders.put(header.getKey(), header.getValue()); } } return processedHeaders; diff --git a/spring-restdocs-mockmvc/build.gradle b/spring-restdocs-mockmvc/build.gradle index 49c0f19c1..85d5fb231 100644 --- a/spring-restdocs-mockmvc/build.gradle +++ b/spring-restdocs-mockmvc/build.gradle @@ -21,6 +21,6 @@ test { matrixTest { springFramework { group = 'org.springframework' - versions = ['5.1.0.BUILD-SNAPSHOT'] + versions = ['5.1.10.BUILD-SNAPSHOT'] } } \ No newline at end of file diff --git a/spring-restdocs-webtestclient/build.gradle b/spring-restdocs-webtestclient/build.gradle index ce63d379c..c4eb9633e 100644 --- a/spring-restdocs-webtestclient/build.gradle +++ b/spring-restdocs-webtestclient/build.gradle @@ -19,6 +19,6 @@ test { matrixTest { springFramework { group = 'org.springframework' - versions = ['5.1.0.BUILD-SNAPSHOT'] + versions = ['5.1.10.BUILD-SNAPSHOT'] } } \ No newline at end of file From 3a5cc58fab58f095834380f02447c7a7bd701888 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Sun, 15 Sep 2019 15:03:50 +0100 Subject: [PATCH 068/502] Test against Spring Framework 5.2 --- spring-restdocs-core/build.gradle | 2 +- spring-restdocs-mockmvc/build.gradle | 2 +- spring-restdocs-webtestclient/build.gradle | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/spring-restdocs-core/build.gradle b/spring-restdocs-core/build.gradle index 8aac3d7a7..656dc5d88 100644 --- a/spring-restdocs-core/build.gradle +++ b/spring-restdocs-core/build.gradle @@ -67,6 +67,6 @@ test { matrixTest { springFramework { group = 'org.springframework' - versions = ['5.1.10.BUILD-SNAPSHOT'] + versions = ['5.1.+', '5.2.+'] } } \ No newline at end of file diff --git a/spring-restdocs-mockmvc/build.gradle b/spring-restdocs-mockmvc/build.gradle index 85d5fb231..a74ce5080 100644 --- a/spring-restdocs-mockmvc/build.gradle +++ b/spring-restdocs-mockmvc/build.gradle @@ -21,6 +21,6 @@ test { matrixTest { springFramework { group = 'org.springframework' - versions = ['5.1.10.BUILD-SNAPSHOT'] + versions = ['5.1.+', '5.2.+'] } } \ No newline at end of file diff --git a/spring-restdocs-webtestclient/build.gradle b/spring-restdocs-webtestclient/build.gradle index c4eb9633e..ec019f782 100644 --- a/spring-restdocs-webtestclient/build.gradle +++ b/spring-restdocs-webtestclient/build.gradle @@ -19,6 +19,6 @@ test { matrixTest { springFramework { group = 'org.springframework' - versions = ['5.1.10.BUILD-SNAPSHOT'] + versions = ['5.1.+', '5.2.+'] } } \ No newline at end of file From 3f66b066f7c74137bbdf63ad7afe163ada573b99 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 18 Sep 2019 11:53:42 +0100 Subject: [PATCH 069/502] Improve field type resolution for fields with optional ancestors Fixes gh-567 --- .../payload/AbstractFieldsSnippet.java | 8 +- .../restdocs/payload/ContentHandler.java | 25 ++-- .../restdocs/payload/FieldTypeResolver.java | 23 +++- .../restdocs/payload/JsonContentHandler.java | 24 ++-- .../restdocs/payload/XmlContentHandler.java | 13 +- .../payload/FieldTypeResolverTests.java | 30 ++++- .../payload/JsonContentHandlerTests.java | 114 +++++++++++------- .../payload/XmlContentHandlerTests.java | 36 +++--- 8 files changed, 176 insertions(+), 97 deletions(-) diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/AbstractFieldsSnippet.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/AbstractFieldsSnippet.java index a27f258d4..a721ee654 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/AbstractFieldsSnippet.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/AbstractFieldsSnippet.java @@ -153,7 +153,8 @@ protected Map createModel(Operation operation) { if (this.subsectionExtractor != null) { content = verifyContent(this.subsectionExtractor.extractSubsection(content, contentType)); } - ContentHandler contentHandler = ContentHandler.forContent(content, contentType); + ContentHandler contentHandler = ContentHandler.forContentWithDescriptors(content, contentType, + this.fieldDescriptors); validateFieldDocumentation(contentHandler); @@ -193,10 +194,9 @@ private byte[] verifyContent(byte[] content) { } private void validateFieldDocumentation(ContentHandler payloadHandler) { - List missingFields = payloadHandler.findMissingFields(this.fieldDescriptors); + List missingFields = payloadHandler.findMissingFields(); - String undocumentedPayload = this.ignoreUndocumentedFields ? null - : payloadHandler.getUndocumentedContent(this.fieldDescriptors); + String undocumentedPayload = this.ignoreUndocumentedFields ? null : payloadHandler.getUndocumentedContent(); if (!missingFields.isEmpty() || StringUtils.hasText(undocumentedPayload)) { String message = ""; diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/ContentHandler.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/ContentHandler.java index 417ed9652..0111548c3 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/ContentHandler.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/ContentHandler.java @@ -30,41 +30,40 @@ interface ContentHandler extends FieldTypeResolver { /** * Finds the fields that are missing from the handler's payload. A field is missing if - * it is described by one of the {@code fieldDescriptors} but is not present in the - * payload. - * @param fieldDescriptors the descriptors + * it is described but is not present in the payload. * @return descriptors for the fields that are missing from the payload * @throws PayloadHandlingException if a failure occurs */ - List findMissingFields(List fieldDescriptors); + List findMissingFields(); /** * Returns modified content, formatted as a String, that only contains the fields that * are undocumented. A field is undocumented if it is present in the handler's content - * but is not described by the given {@code fieldDescriptors}. If the content is - * completely documented, {@code null} is returned - * @param fieldDescriptors the descriptors + * but is not described. If the content is completely documented, {@code null} is + * returned * @return the undocumented content, or {@code null} if all of the content is * documented * @throws PayloadHandlingException if a failure occurs */ - String getUndocumentedContent(List fieldDescriptors); + String getUndocumentedContent(); /** - * Create a {@link ContentHandler} for the given content type and payload. + * Create a {@link ContentHandler} for the given content type and payload, described + * by the given descriptors. * @param content the payload * @param contentType the content type + * @param descriptors descriptors of the content * @return the ContentHandler * @throws PayloadHandlingException if no known ContentHandler can handle the content */ - static ContentHandler forContent(byte[] content, MediaType contentType) { - + static ContentHandler forContentWithDescriptors(byte[] content, MediaType contentType, + List descriptors) { try { - return new JsonContentHandler(content); + return new JsonContentHandler(content, descriptors); } catch (Exception je) { try { - return new XmlContentHandler(content); + return new XmlContentHandler(content, descriptors); } catch (Exception xe) { throw new PayloadHandlingException( diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/FieldTypeResolver.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/FieldTypeResolver.java index 530a2a07b..6c8397c39 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/FieldTypeResolver.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/FieldTypeResolver.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-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. @@ -16,6 +16,9 @@ package org.springframework.restdocs.payload; +import java.util.Collections; +import java.util.List; + import org.springframework.http.MediaType; /** @@ -33,9 +36,25 @@ public interface FieldTypeResolver { * @param content the payload that the {@code FieldTypeResolver} should handle * @param contentType the content type of the payload * @return the {@code FieldTypeResolver} + * @deprecated since 2.0.4 in favor of + * {@link #forContentWithDescriptors(byte[], MediaType, List)} */ + @Deprecated static FieldTypeResolver forContent(byte[] content, MediaType contentType) { - return ContentHandler.forContent(content, contentType); + return forContentWithDescriptors(content, contentType, Collections.emptyList()); + } + + /** + * Create a {@code FieldTypeResolver} for the given {@code content} and + * {@code contentType}, described by the given {@code descriptors}. + * @param content the payload that the {@code FieldTypeResolver} should handle + * @param contentType the content type of the payload + * @param descriptors the descriptors of the content + * @return the {@code FieldTypeResolver} + */ + static FieldTypeResolver forContentWithDescriptors(byte[] content, MediaType contentType, + List descriptors) { + return ContentHandler.forContentWithDescriptors(content, contentType, descriptors); } /** diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/JsonContentHandler.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/JsonContentHandler.java index a5829276f..976a27718 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/JsonContentHandler.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/JsonContentHandler.java @@ -44,18 +44,21 @@ class JsonContentHandler implements ContentHandler { private final byte[] rawContent; - JsonContentHandler(byte[] content) { + private final List fieldDescriptors; + + JsonContentHandler(byte[] content, List fieldDescriptors) { this.rawContent = content; + this.fieldDescriptors = fieldDescriptors; readContent(); } @Override - public List findMissingFields(List fieldDescriptors) { + public List findMissingFields() { List missingFields = new ArrayList<>(); Object payload = readContent(); - for (FieldDescriptor fieldDescriptor : fieldDescriptors) { + for (FieldDescriptor fieldDescriptor : this.fieldDescriptors) { if (!fieldDescriptor.isOptional() && !this.fieldProcessor.hasField(fieldDescriptor.getPath(), payload) - && !isNestedBeneathMissingOptionalField(fieldDescriptor, fieldDescriptors, payload)) { + && !isNestedBeneathMissingOptionalField(fieldDescriptor, payload)) { missingFields.add(fieldDescriptor); } } @@ -63,9 +66,8 @@ public List findMissingFields(List fieldDescri return missingFields; } - private boolean isNestedBeneathMissingOptionalField(FieldDescriptor missing, List fieldDescriptors, - Object payload) { - List candidates = new ArrayList<>(fieldDescriptors); + private boolean isNestedBeneathMissingOptionalField(FieldDescriptor missing, Object payload) { + List candidates = new ArrayList<>(this.fieldDescriptors); candidates.remove(missing); for (FieldDescriptor candidate : candidates) { if (candidate.isOptional() && missing.getPath().startsWith(candidate.getPath()) @@ -98,9 +100,9 @@ private boolean isEmptyCollection(Object value) { } @Override - public String getUndocumentedContent(List fieldDescriptors) { + public String getUndocumentedContent() { Object content = readContent(); - for (FieldDescriptor fieldDescriptor : fieldDescriptors) { + for (FieldDescriptor fieldDescriptor : this.fieldDescriptors) { if (describesSubsection(fieldDescriptor)) { this.fieldProcessor.removeSubsection(fieldDescriptor.getPath(), content); } @@ -154,7 +156,9 @@ public Object resolveFieldType(FieldDescriptor fieldDescriptor) { .discoverFieldTypes(fieldDescriptor.getPath(), readContent()) .coalesce(fieldDescriptor.isOptional()); if (descriptorFieldType == JsonFieldType.VARIES || descriptorFieldType == actualFieldType - || (fieldDescriptor.isOptional() && actualFieldType == JsonFieldType.NULL)) { + || (fieldDescriptor.isOptional() && actualFieldType == JsonFieldType.NULL) + || (isNestedBeneathMissingOptionalField(fieldDescriptor, readContent()) + && actualFieldType == JsonFieldType.VARIES)) { return descriptorFieldType; } throw new FieldTypesDoNotMatchException(fieldDescriptor, actualFieldType); diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/XmlContentHandler.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/XmlContentHandler.java index 6f58ac1e7..8ca819900 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/XmlContentHandler.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/XmlContentHandler.java @@ -53,7 +53,9 @@ class XmlContentHandler implements ContentHandler { private final byte[] rawContent; - XmlContentHandler(byte[] rawContent) { + private final List fieldDescriptors; + + XmlContentHandler(byte[] rawContent, List fieldDescriptors) { try { this.documentBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); } @@ -61,14 +63,15 @@ class XmlContentHandler implements ContentHandler { throw new IllegalStateException("Failed to create document builder", ex); } this.rawContent = rawContent; + this.fieldDescriptors = fieldDescriptors; readPayload(); } @Override - public List findMissingFields(List fieldDescriptors) { + public List findMissingFields() { List missingFields = new ArrayList<>(); Document payload = readPayload(); - for (FieldDescriptor fieldDescriptor : fieldDescriptors) { + for (FieldDescriptor fieldDescriptor : this.fieldDescriptors) { if (!fieldDescriptor.isOptional()) { NodeList matchingNodes = findMatchingNodes(fieldDescriptor, payload); if (matchingNodes.getLength() == 0) { @@ -103,10 +106,10 @@ private XPathExpression createXPath(String fieldPath) throws XPathExpressionExce } @Override - public String getUndocumentedContent(List fieldDescriptors) { + public String getUndocumentedContent() { Document payload = readPayload(); List matchedButNotRemoved = new ArrayList<>(); - for (FieldDescriptor fieldDescriptor : fieldDescriptors) { + for (FieldDescriptor fieldDescriptor : this.fieldDescriptors) { NodeList matchingNodes; try { matchingNodes = (NodeList) createXPath(fieldDescriptor.getPath()).evaluate(payload, diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/FieldTypeResolverTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/FieldTypeResolverTests.java index fa96e92e3..17d3edf5b 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/FieldTypeResolverTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/FieldTypeResolverTests.java @@ -16,6 +16,8 @@ package org.springframework.restdocs.payload; +import java.util.Collections; + import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; @@ -35,21 +37,43 @@ public class FieldTypeResolverTests { public ExpectedException thrownException = ExpectedException.none(); @Test - public void returnJsonFieldTypeResolver() { + @Deprecated + public void whenForContentCalledWithJsonContentThenReturnsJsonFieldTypeResolver() { assertThat(FieldTypeResolver.forContent("{\"field\": \"value\"}".getBytes(), MediaType.APPLICATION_JSON)) .isInstanceOf(JsonContentHandler.class); } @Test - public void returnXmlContentHandler() { + @Deprecated + public void whenForContentCalledWithXmlContentThenReturnsXmlContentHandler() { assertThat(FieldTypeResolver.forContent("5".getBytes(), MediaType.APPLICATION_XML)) .isInstanceOf(XmlContentHandler.class); } @Test - public void throwOnInvalidContent() { + @Deprecated + public void whenForContentIsCalledWithInvalidContentThenExceptionIsThrown() { this.thrownException.expect(PayloadHandlingException.class); FieldTypeResolver.forContent("some".getBytes(), MediaType.APPLICATION_XML); } + @Test + public void whenForContentWithDescriptorsCalledWithJsonContentThenReturnsJsonFieldTypeResolver() { + assertThat(FieldTypeResolver.forContentWithDescriptors("{\"field\": \"value\"}".getBytes(), + MediaType.APPLICATION_JSON, Collections.emptyList())).isInstanceOf(JsonContentHandler.class); + } + + @Test + public void whenForContentWithDescriptorsCalledWithXmlContentThenReturnsXmlContentHandler() { + assertThat(FieldTypeResolver.forContentWithDescriptors("5".getBytes(), MediaType.APPLICATION_XML, + Collections.emptyList())).isInstanceOf(XmlContentHandler.class); + } + + @Test + public void whenForContentWithDescriptorsIsCalledWithInvalidContentThenExceptionIsThrown() { + this.thrownException.expect(PayloadHandlingException.class); + FieldTypeResolver.forContentWithDescriptors("some".getBytes(), MediaType.APPLICATION_XML, + Collections.emptyList()); + } + } diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/JsonContentHandlerTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/JsonContentHandlerTests.java index 1055a7200..6785bcac6 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/JsonContentHandlerTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/JsonContentHandlerTests.java @@ -16,7 +16,9 @@ package org.springframework.restdocs.payload; +import java.io.IOException; import java.util.Arrays; +import java.util.Collections; import java.util.List; import org.junit.Rule; @@ -39,137 +41,163 @@ public class JsonContentHandlerTests { @Test public void typeForFieldWithNullValueMustMatch() { this.thrown.expect(FieldTypesDoNotMatchException.class); - new JsonContentHandler("{\"a\": null}".getBytes()) - .resolveFieldType(new FieldDescriptor("a").type(JsonFieldType.STRING)); + FieldDescriptor descriptor = new FieldDescriptor("a").type(JsonFieldType.STRING); + new JsonContentHandler("{\"a\": null}".getBytes(), Arrays.asList(descriptor)).resolveFieldType(descriptor); } @Test public void typeForFieldWithNotNullAndThenNullValueMustMatch() { this.thrown.expect(FieldTypesDoNotMatchException.class); - new JsonContentHandler("{\"a\":[{\"id\":1},{\"id\":null}]}".getBytes()) - .resolveFieldType(new FieldDescriptor("a[].id").type(JsonFieldType.STRING)); + FieldDescriptor descriptor = new FieldDescriptor("a[].id").type(JsonFieldType.STRING); + new JsonContentHandler("{\"a\":[{\"id\":1},{\"id\":null}]}".getBytes(), Arrays.asList(descriptor)) + .resolveFieldType(descriptor); } @Test public void typeForFieldWithNullAndThenNotNullValueMustMatch() { this.thrown.expect(FieldTypesDoNotMatchException.class); - new JsonContentHandler("{\"a\":[{\"id\":null},{\"id\":1}]}".getBytes()) - .resolveFieldType(new FieldDescriptor("a.[].id").type(JsonFieldType.STRING)); + FieldDescriptor descriptor = new FieldDescriptor("a.[].id").type(JsonFieldType.STRING); + new JsonContentHandler("{\"a\":[{\"id\":null},{\"id\":1}]}".getBytes(), Arrays.asList(descriptor)) + .resolveFieldType(descriptor); } @Test public void typeForOptionalFieldWithNumberAndThenNullValueIsNumber() { - Object fieldType = new JsonContentHandler("{\"a\":[{\"id\":1},{\"id\":null}]}\"".getBytes()) - .resolveFieldType(new FieldDescriptor("a[].id").optional()); + FieldDescriptor descriptor = new FieldDescriptor("a[].id").optional(); + Object fieldType = new JsonContentHandler("{\"a\":[{\"id\":1},{\"id\":null}]}\"".getBytes(), + Arrays.asList(descriptor)).resolveFieldType(descriptor); assertThat((JsonFieldType) fieldType).isEqualTo(JsonFieldType.NUMBER); } @Test public void typeForOptionalFieldWithNullAndThenNumberIsNumber() { - Object fieldType = new JsonContentHandler("{\"a\":[{\"id\":null},{\"id\":1}]}".getBytes()) - .resolveFieldType(new FieldDescriptor("a[].id").optional()); + FieldDescriptor descriptor = new FieldDescriptor("a[].id").optional(); + Object fieldType = new JsonContentHandler("{\"a\":[{\"id\":null},{\"id\":1}]}".getBytes(), + Arrays.asList(descriptor)).resolveFieldType(descriptor); assertThat((JsonFieldType) fieldType).isEqualTo(JsonFieldType.NUMBER); } @Test public void typeForFieldWithNumberAndThenNullValueIsVaries() { - Object fieldType = new JsonContentHandler("{\"a\":[{\"id\":1},{\"id\":null}]}\"".getBytes()) - .resolveFieldType(new FieldDescriptor("a[].id")); + FieldDescriptor descriptor = new FieldDescriptor("a[].id"); + Object fieldType = new JsonContentHandler("{\"a\":[{\"id\":1},{\"id\":null}]}\"".getBytes(), + Arrays.asList(descriptor)).resolveFieldType(descriptor); assertThat((JsonFieldType) fieldType).isEqualTo(JsonFieldType.VARIES); } @Test public void typeForFieldWithNullAndThenNumberIsVaries() { - Object fieldType = new JsonContentHandler("{\"a\":[{\"id\":null},{\"id\":1}]}".getBytes()) - .resolveFieldType(new FieldDescriptor("a[].id")); + FieldDescriptor descriptor = new FieldDescriptor("a[].id"); + Object fieldType = new JsonContentHandler("{\"a\":[{\"id\":null},{\"id\":1}]}".getBytes(), + Arrays.asList(descriptor)).resolveFieldType(descriptor); assertThat((JsonFieldType) fieldType).isEqualTo(JsonFieldType.VARIES); } @Test public void typeForOptionalFieldWithNullValueCanBeProvidedExplicitly() { - Object fieldType = new JsonContentHandler("{\"a\": null}".getBytes()) - .resolveFieldType(new FieldDescriptor("a").type(JsonFieldType.STRING).optional()); + FieldDescriptor descriptor = new FieldDescriptor("a").type(JsonFieldType.STRING).optional(); + Object fieldType = new JsonContentHandler("{\"a\": null}".getBytes(), Arrays.asList(descriptor)) + .resolveFieldType(descriptor); assertThat((JsonFieldType) fieldType).isEqualTo(JsonFieldType.STRING); } + @Test + public void typeForFieldWithSometimesPresentOptionalAncestorCanBeProvidedExplicitly() throws IOException { + FieldDescriptor descriptor = new FieldDescriptor("a.[].b.c").type(JsonFieldType.NUMBER); + FieldDescriptor ancestor = new FieldDescriptor("a.[].b").optional(); + Object fieldType = new JsonContentHandler("{\"a\":[ { \"d\": 4}, {\"b\":{\"c\":5}, \"d\": 4}]}".getBytes(), + Arrays.asList(descriptor, ancestor)).resolveFieldType(descriptor); + assertThat((JsonFieldType) fieldType).isEqualTo(JsonFieldType.NUMBER); + } + @Test public void failsFastWithNonJsonContent() { this.thrown.expect(PayloadHandlingException.class); - new JsonContentHandler("Non-JSON content".getBytes()); + new JsonContentHandler("Non-JSON content".getBytes(), Collections.emptyList()); } @Test public void describedFieldThatIsNotPresentIsConsideredMissing() { - List missingFields = new JsonContentHandler("{\"a\": \"alpha\", \"b\":\"bravo\"}".getBytes()) - .findMissingFields( - Arrays.asList(new FieldDescriptor("a"), new FieldDescriptor("b"), new FieldDescriptor("c"))); + List descriptors = Arrays.asList(new FieldDescriptor("a"), new FieldDescriptor("b"), + new FieldDescriptor("c")); + List missingFields = new JsonContentHandler("{\"a\": \"alpha\", \"b\":\"bravo\"}".getBytes(), + descriptors).findMissingFields(); assertThat(missingFields.size()).isEqualTo(1); assertThat(missingFields.get(0).getPath()).isEqualTo("c"); } @Test public void describedOptionalFieldThatIsNotPresentIsNotConsideredMissing() { - List missingFields = new JsonContentHandler("{\"a\": \"alpha\", \"b\":\"bravo\"}".getBytes()) - .findMissingFields(Arrays.asList(new FieldDescriptor("a"), new FieldDescriptor("b"), - new FieldDescriptor("c").optional())); + List descriptors = Arrays.asList(new FieldDescriptor("a"), new FieldDescriptor("b"), + new FieldDescriptor("c").optional()); + List missingFields = new JsonContentHandler("{\"a\": \"alpha\", \"b\":\"bravo\"}".getBytes(), + descriptors).findMissingFields(); assertThat(missingFields.size()).isEqualTo(0); } @Test public void describedFieldThatIsNotPresentNestedBeneathOptionalFieldThatIsPresentIsConsideredMissing() { - List missingFields = new JsonContentHandler("{\"a\":\"alpha\",\"b\":\"bravo\"}".getBytes()) - .findMissingFields(Arrays.asList(new FieldDescriptor("a").optional(), new FieldDescriptor("b"), - new FieldDescriptor("a.c"))); + List descriptors = Arrays.asList(new FieldDescriptor("a").optional(), new FieldDescriptor("b"), + new FieldDescriptor("a.c")); + List missingFields = new JsonContentHandler("{\"a\":\"alpha\",\"b\":\"bravo\"}".getBytes(), + descriptors).findMissingFields(); assertThat(missingFields.size()).isEqualTo(1); assertThat(missingFields.get(0).getPath()).isEqualTo("a.c"); } @Test public void describedFieldThatIsNotPresentNestedBeneathOptionalFieldThatIsNotPresentIsNotConsideredMissing() { - List missingFields = new JsonContentHandler("{\"b\":\"bravo\"}".getBytes()) - .findMissingFields(Arrays.asList(new FieldDescriptor("a").optional(), new FieldDescriptor("b"), - new FieldDescriptor("a.c"))); + List descriptors = Arrays.asList(new FieldDescriptor("a").optional(), new FieldDescriptor("b"), + new FieldDescriptor("a.c")); + List missingFields = new JsonContentHandler("{\"b\":\"bravo\"}".getBytes(), descriptors) + .findMissingFields(); assertThat(missingFields.size()).isEqualTo(0); } @Test public void describedFieldThatIsNotPresentNestedBeneathOptionalArrayThatIsEmptyIsNotConsideredMissing() { - List missingFields = new JsonContentHandler("{\"outer\":[]}".getBytes()) - .findMissingFields(Arrays.asList(new FieldDescriptor("outer"), - new FieldDescriptor("outer[]").optional(), new FieldDescriptor("outer[].inner"))); + List descriptors = Arrays.asList(new FieldDescriptor("outer"), + new FieldDescriptor("outer[]").optional(), new FieldDescriptor("outer[].inner")); + List missingFields = new JsonContentHandler("{\"outer\":[]}".getBytes(), descriptors) + .findMissingFields(); assertThat(missingFields.size()).isEqualTo(0); } @Test public void describedSometimesPresentFieldThatIsChildOfSometimesPresentOptionalArrayIsNotConsideredMissing() { + List descriptors = Arrays.asList(new FieldDescriptor("a.[].c").optional(), + new FieldDescriptor("a.[].c.d")); List missingFields = new JsonContentHandler( - "{\"a\":[ {\"b\": \"bravo\"}, {\"b\": \"bravo\", \"c\": { \"d\": \"delta\"}}]}".getBytes()) - .findMissingFields(Arrays.asList(new FieldDescriptor("a.[].c").optional(), - new FieldDescriptor("a.[].c.d"))); + "{\"a\":[ {\"b\": \"bravo\"}, {\"b\": \"bravo\", \"c\": { \"d\": \"delta\"}}]}".getBytes(), descriptors) + .findMissingFields(); assertThat(missingFields.size()).isEqualTo(0); } @Test public void describedMissingFieldThatIsChildOfNestedOptionalArrayThatIsEmptyIsNotConsideredMissing() { - List missingFields = new JsonContentHandler("{\"a\":[{\"b\":[]}]}".getBytes()) - .findMissingFields(Arrays.asList(new FieldDescriptor("a.[].b").optional(), - new FieldDescriptor("a.[].b.[]").optional(), new FieldDescriptor("a.[].b.[].c"))); + List descriptors = Arrays.asList(new FieldDescriptor("a.[].b").optional(), + new FieldDescriptor("a.[].b.[]").optional(), new FieldDescriptor("a.[].b.[].c")); + List missingFields = new JsonContentHandler("{\"a\":[{\"b\":[]}]}".getBytes(), descriptors) + .findMissingFields(); assertThat(missingFields.size()).isEqualTo(0); } @Test public void describedMissingFieldThatIsChildOfNestedOptionalArrayThatContainsAnObjectIsConsideredMissing() { - List missingFields = new JsonContentHandler("{\"a\":[{\"b\":[{}]}]}".getBytes()) - .findMissingFields(Arrays.asList(new FieldDescriptor("a.[].b").optional(), - new FieldDescriptor("a.[].b.[]").optional(), new FieldDescriptor("a.[].b.[].c"))); + List descriptors = Arrays.asList(new FieldDescriptor("a.[].b").optional(), + new FieldDescriptor("a.[].b.[]").optional(), new FieldDescriptor("a.[].b.[].c")); + List missingFields = new JsonContentHandler("{\"a\":[{\"b\":[{}]}]}".getBytes(), descriptors) + .findMissingFields(); assertThat(missingFields.size()).isEqualTo(1); assertThat(missingFields.get(0).getPath()).isEqualTo("a.[].b.[].c"); } @Test public void describedMissingFieldThatIsChildOfOptionalObjectThatIsNullIsNotConsideredMissing() { - List missingFields = new JsonContentHandler("{\"a\":null}".getBytes()) - .findMissingFields(Arrays.asList(new FieldDescriptor("a").optional(), new FieldDescriptor("a.b"))); + List descriptors = Arrays.asList(new FieldDescriptor("a").optional(), + new FieldDescriptor("a.b")); + List missingFields = new JsonContentHandler("{\"a\":null}".getBytes(), descriptors) + .findMissingFields(); assertThat(missingFields.size()).isEqualTo(0); } diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/XmlContentHandlerTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/XmlContentHandlerTests.java index 240107f6a..24b1f8b21 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/XmlContentHandlerTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/XmlContentHandlerTests.java @@ -17,6 +17,8 @@ package org.springframework.restdocs.payload; import java.util.Arrays; +import java.util.Collections; +import java.util.List; import org.junit.Rule; import org.junit.Test; @@ -38,56 +40,56 @@ public class XmlContentHandlerTests { @Test public void topLevelElementCanBeDocumented() { - String undocumentedContent = createHandler("5") - .getUndocumentedContent(Arrays.asList(fieldWithPath("a").type("a").description("description"))); + List descriptors = Arrays.asList(fieldWithPath("a").type("a").description("description")); + String undocumentedContent = createHandler("5", descriptors).getUndocumentedContent(); assertThat(undocumentedContent).isNull(); } @Test public void nestedElementCanBeDocumentedLeavingAncestors() { - String undocumentedContent = createHandler("5") - .getUndocumentedContent(Arrays.asList(fieldWithPath("a/b").type("b").description("description"))); + List descriptors = Arrays.asList(fieldWithPath("a/b").type("b").description("description")); + String undocumentedContent = createHandler("5", descriptors).getUndocumentedContent(); assertThat(undocumentedContent).isEqualTo(String.format("%n")); } @Test public void fieldDescriptorDoesNotDocumentEntireSubsection() { - String undocumentedContent = createHandler("5") - .getUndocumentedContent(Arrays.asList(fieldWithPath("a").type("a").description("description"))); + List descriptors = Arrays.asList(fieldWithPath("a").type("a").description("description")); + String undocumentedContent = createHandler("5", descriptors).getUndocumentedContent(); assertThat(undocumentedContent).isEqualTo(String.format("%n 5%n%n")); } @Test public void subsectionDescriptorDocumentsEntireSubsection() { - String undocumentedContent = createHandler("5") - .getUndocumentedContent(Arrays.asList(subsectionWithPath("a").type("a").description("description"))); + List descriptors = Arrays.asList(subsectionWithPath("a").type("a").description("description")); + String undocumentedContent = createHandler("5", descriptors).getUndocumentedContent(); assertThat(undocumentedContent).isNull(); } @Test public void multipleElementsCanBeInDescendingOrderDocumented() { - String undocumentedContent = createHandler("5") - .getUndocumentedContent(Arrays.asList(fieldWithPath("a").type("a").description("description"), - fieldWithPath("a/b").type("b").description("description"))); + List descriptors = Arrays.asList(fieldWithPath("a").type("a").description("description"), + fieldWithPath("a/b").type("b").description("description")); + String undocumentedContent = createHandler("5", descriptors).getUndocumentedContent(); assertThat(undocumentedContent).isNull(); } @Test public void multipleElementsCanBeInAscendingOrderDocumented() { - String undocumentedContent = createHandler("5") - .getUndocumentedContent(Arrays.asList(fieldWithPath("a/b").type("b").description("description"), - fieldWithPath("a").type("a").description("description"))); + List descriptors = Arrays.asList(fieldWithPath("a/b").type("b").description("description"), + fieldWithPath("a").type("a").description("description")); + String undocumentedContent = createHandler("5", descriptors).getUndocumentedContent(); assertThat(undocumentedContent).isNull(); } @Test public void failsFastWithNonXmlContent() { this.thrown.expect(PayloadHandlingException.class); - createHandler("non-XML content"); + createHandler("non-XML content", Collections.emptyList()); } - private XmlContentHandler createHandler(String xml) { - return new XmlContentHandler(xml.getBytes()); + private XmlContentHandler createHandler(String xml, List descriptors) { + return new XmlContentHandler(xml.getBytes(), descriptors); } } From 93a43dfd0a427dd6f1c749c49bc4f396db46b64f Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 18 Sep 2019 14:26:40 +0100 Subject: [PATCH 070/502] Consider optionality when finding uncommon fields in subsection extraction Fixes gh-573 --- .../payload/AbstractFieldsSnippet.java | 3 +- .../FieldPathPayloadSubsectionExtractor.java | 37 +++++++++++++++---- .../restdocs/payload/JsonContentHandler.java | 20 ++++++---- .../restdocs/payload/JsonFieldPath.java | 20 ++++++++++ .../payload/PayloadSubsectionExtractor.java | 15 ++++++++ ...ldPathPayloadSubsectionExtractorTests.java | 27 +++++++++++++- 6 files changed, 104 insertions(+), 18 deletions(-) diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/AbstractFieldsSnippet.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/AbstractFieldsSnippet.java index a721ee654..fe077017e 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/AbstractFieldsSnippet.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/AbstractFieldsSnippet.java @@ -151,7 +151,8 @@ protected Map createModel(Operation operation) { } MediaType contentType = getContentType(operation); if (this.subsectionExtractor != null) { - content = verifyContent(this.subsectionExtractor.extractSubsection(content, contentType)); + content = verifyContent( + this.subsectionExtractor.extractSubsection(content, contentType, this.fieldDescriptors)); } ContentHandler contentHandler = ContentHandler.forContentWithDescriptors(content, contentType, this.fieldDescriptors); diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/FieldPathPayloadSubsectionExtractor.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/FieldPathPayloadSubsectionExtractor.java index b0da8d42d..7a0b5070b 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/FieldPathPayloadSubsectionExtractor.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/FieldPathPayloadSubsectionExtractor.java @@ -17,9 +17,11 @@ package org.springframework.restdocs.payload; import java.io.IOException; -import java.util.ArrayList; +import java.util.Collections; import java.util.List; +import java.util.Map; import java.util.Set; +import java.util.stream.Collectors; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; @@ -71,6 +73,11 @@ protected FieldPathPayloadSubsectionExtractor(String fieldPath, String subsectio @Override public byte[] extractSubsection(byte[] payload, MediaType contentType) { + return extractSubsection(payload, contentType, Collections.emptyList()); + } + + @Override + public byte[] extractSubsection(byte[] payload, MediaType contentType, List descriptors) { try { ExtractedField extractedField = new JsonFieldProcessor().extract(this.fieldPath, objectMapper.readValue(payload, Object.class)); @@ -78,21 +85,27 @@ public byte[] extractSubsection(byte[] payload, MediaType contentType) { if (value == ExtractedField.ABSENT) { throw new PayloadHandlingException(this.fieldPath + " does not identify a section of the payload"); } + Map descriptorsByPath = descriptors.stream() + .collect(Collectors.toMap( + (descriptor) -> JsonFieldPath.compile(this.fieldPath + "." + descriptor.getPath()), + this::prependFieldPath)); if (value instanceof List) { List extractedList = (List) value; - Set uncommonPaths = JsonFieldPaths.from(extractedList).getUncommon(); + JsonContentHandler contentHandler = new JsonContentHandler(payload, descriptorsByPath.values()); + Set uncommonPaths = JsonFieldPaths.from(extractedList).getUncommon().stream() + .map((path) -> JsonFieldPath.compile(this.fieldPath + "." + path)).filter((path) -> { + FieldDescriptor descriptorForPath = descriptorsByPath.getOrDefault(path, + new FieldDescriptor(path.toString())); + return contentHandler.isMissing(descriptorForPath); + }).collect(Collectors.toSet()); if (uncommonPaths.isEmpty()) { value = extractedList.get(0); } else { String message = this.fieldPath + " identifies multiple sections of " + "the payload and they do not have a common structure. The " - + "following uncommon paths were found: "; - List prefixedPaths = new ArrayList<>(); - for (String uncommonPath : uncommonPaths) { - prefixedPaths.add(this.fieldPath + "." + uncommonPath); - } - message += prefixedPaths; + + "following non-optional uncommon paths were found: "; + message += uncommonPaths; throw new PayloadHandlingException(message); } } @@ -103,6 +116,14 @@ public byte[] extractSubsection(byte[] payload, MediaType contentType) { } } + private FieldDescriptor prependFieldPath(FieldDescriptor original) { + FieldDescriptor prefixed = new FieldDescriptor(this.fieldPath + "." + original.getPath()); + if (original.isOptional()) { + prefixed.optional(); + } + return prefixed; + } + @Override public String getSubsectionId() { return this.subsectionId; diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/JsonContentHandler.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/JsonContentHandler.java index 976a27718..7457d4d0d 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/JsonContentHandler.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/JsonContentHandler.java @@ -44,9 +44,9 @@ class JsonContentHandler implements ContentHandler { private final byte[] rawContent; - private final List fieldDescriptors; + private final Collection fieldDescriptors; - JsonContentHandler(byte[] content, List fieldDescriptors) { + JsonContentHandler(byte[] content, Collection fieldDescriptors) { this.rawContent = content; this.fieldDescriptors = fieldDescriptors; readContent(); @@ -55,10 +55,8 @@ class JsonContentHandler implements ContentHandler { @Override public List findMissingFields() { List missingFields = new ArrayList<>(); - Object payload = readContent(); for (FieldDescriptor fieldDescriptor : this.fieldDescriptors) { - if (!fieldDescriptor.isOptional() && !this.fieldProcessor.hasField(fieldDescriptor.getPath(), payload) - && !isNestedBeneathMissingOptionalField(fieldDescriptor, payload)) { + if (isMissing(fieldDescriptor)) { missingFields.add(fieldDescriptor); } } @@ -66,11 +64,17 @@ public List findMissingFields() { return missingFields; } - private boolean isNestedBeneathMissingOptionalField(FieldDescriptor missing, Object payload) { + boolean isMissing(FieldDescriptor descriptor) { + Object payload = readContent(); + return !descriptor.isOptional() && !this.fieldProcessor.hasField(descriptor.getPath(), payload) + && !isNestedBeneathMissingOptionalField(descriptor, payload); + } + + private boolean isNestedBeneathMissingOptionalField(FieldDescriptor descriptor, Object payload) { List candidates = new ArrayList<>(this.fieldDescriptors); - candidates.remove(missing); + candidates.remove(descriptor); for (FieldDescriptor candidate : candidates) { - if (candidate.isOptional() && missing.getPath().startsWith(candidate.getPath()) + if (candidate.isOptional() && descriptor.getPath().startsWith(candidate.getPath()) && isMissing(candidate, payload)) { return true; } diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/JsonFieldPath.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/JsonFieldPath.java index 43c066848..b730b059d 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/JsonFieldPath.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/JsonFieldPath.java @@ -55,6 +55,26 @@ List getSegments() { return this.segments; } + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + JsonFieldPath other = (JsonFieldPath) obj; + return this.segments.equals(other.segments); + } + + @Override + public int hashCode() { + return this.segments.hashCode(); + } + @Override public String toString() { return this.rawPath; diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/PayloadSubsectionExtractor.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/PayloadSubsectionExtractor.java index eec484fc6..097a8125f 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/PayloadSubsectionExtractor.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/PayloadSubsectionExtractor.java @@ -16,6 +16,8 @@ package org.springframework.restdocs.payload; +import java.util.List; + import org.springframework.http.MediaType; /** @@ -36,6 +38,19 @@ public interface PayloadSubsectionExtractor descriptors) { + return extractSubsection(payload, contentType); + } + /** * Returns an identifier for the subsection that this extractor will extract. * @return the identifier diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/FieldPathPayloadSubsectionExtractorTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/FieldPathPayloadSubsectionExtractorTests.java index facf11db6..b50efb974 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/FieldPathPayloadSubsectionExtractorTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/FieldPathPayloadSubsectionExtractorTests.java @@ -17,6 +17,7 @@ package org.springframework.restdocs.payload; import java.io.IOException; +import java.util.Arrays; import java.util.Map; import com.fasterxml.jackson.core.JsonParseException; @@ -101,11 +102,35 @@ public void extractMapSubsectionWithCommonStructureFromMultiElementArrayInAJsonM public void extractMapSubsectionWithVaryingStructureFromMultiElementArrayInAJsonMap() throws JsonParseException, JsonMappingException, IOException { this.thrown.expect(PayloadHandlingException.class); - this.thrown.expectMessage("The following uncommon paths were found: [a.[].b.d]"); + this.thrown.expectMessage("The following non-optional uncommon paths were found: [a.[].b.d]"); new FieldPathPayloadSubsectionExtractor("a.[].b").extractSubsection( "{\"a\":[{\"b\":{\"c\":5}},{\"b\":{\"c\":6, \"d\": 7}}]}".getBytes(), MediaType.APPLICATION_JSON); } + @Test + @SuppressWarnings("unchecked") + public void extractMapSubsectionWithVaryingStructureDueToOptionalFieldsFromMultiElementArrayInAJsonMap() + throws JsonParseException, JsonMappingException, IOException { + byte[] extractedPayload = new FieldPathPayloadSubsectionExtractor("a.[].b").extractSubsection( + "{\"a\":[{\"b\":{\"c\":5}},{\"b\":{\"c\":6, \"d\": 7}}]}".getBytes(), MediaType.APPLICATION_JSON, + Arrays.asList(new FieldDescriptor("d").optional())); + Map extracted = new ObjectMapper().readValue(extractedPayload, Map.class); + assertThat(extracted.size()).isEqualTo(1); + assertThat(extracted).containsOnlyKeys("c"); + } + + @Test + @SuppressWarnings("unchecked") + public void extractMapSubsectionWithVaryingStructureDueToOptionalParentFieldsFromMultiElementArrayInAJsonMap() + throws JsonParseException, JsonMappingException, IOException { + byte[] extractedPayload = new FieldPathPayloadSubsectionExtractor("a.[].b").extractSubsection( + "{\"a\":[{\"b\":{\"c\":5}},{\"b\":{\"c\":6, \"d\": { \"e\": 7}}}]}".getBytes(), + MediaType.APPLICATION_JSON, Arrays.asList(new FieldDescriptor("d").optional())); + Map extracted = new ObjectMapper().readValue(extractedPayload, Map.class); + assertThat(extracted.size()).isEqualTo(1); + assertThat(extracted).containsOnlyKeys("c"); + } + @Test public void extractedSubsectionIsPrettyPrintedWhenInputIsPrettyPrinted() throws JsonParseException, JsonMappingException, JsonProcessingException, IOException { From ae59baf38ca7d025b3f44063bbde86b119552e48 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Thu, 19 Sep 2019 10:37:51 +0100 Subject: [PATCH 071/502] Remove invalid and empty part from samples' getting started guides Fixes gh-641 --- samples/rest-notes-spring-data-rest/pom.xml | 6 ++++++ .../src/main/asciidoc/getting-started-guide.adoc | 3 --- .../src/docs/asciidoc/getting-started-guide.adoc | 3 --- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/samples/rest-notes-spring-data-rest/pom.xml b/samples/rest-notes-spring-data-rest/pom.xml index 4cd376e00..2fc62c038 100644 --- a/samples/rest-notes-spring-data-rest/pom.xml +++ b/samples/rest-notes-spring-data-rest/pom.xml @@ -83,6 +83,12 @@ html book + + true + + DEBUG (2) + + diff --git a/samples/rest-notes-spring-data-rest/src/main/asciidoc/getting-started-guide.adoc b/samples/rest-notes-spring-data-rest/src/main/asciidoc/getting-started-guide.adoc index fbd4793b7..f794201f7 100644 --- a/samples/rest-notes-spring-data-rest/src/main/asciidoc/getting-started-guide.adoc +++ b/samples/rest-notes-spring-data-rest/src/main/asciidoc/getting-started-guide.adoc @@ -13,9 +13,6 @@ Andy Wilkinson; RESTful Notes is a RESTful web service for creating and storing notes. It uses hypermedia to describe the relationships between resources and to allow navigation between them. -[[getting-started]] -= Getting started - [[getting-started-running-the-service]] diff --git a/samples/rest-notes-spring-hateoas/src/docs/asciidoc/getting-started-guide.adoc b/samples/rest-notes-spring-hateoas/src/docs/asciidoc/getting-started-guide.adoc index b07a9ffd9..788508f31 100644 --- a/samples/rest-notes-spring-hateoas/src/docs/asciidoc/getting-started-guide.adoc +++ b/samples/rest-notes-spring-hateoas/src/docs/asciidoc/getting-started-guide.adoc @@ -13,9 +13,6 @@ Andy Wilkinson; RESTful Notes is a RESTful web service for creating and storing notes. It uses hypermedia to describe the relationships between resources and to allow navigation between them. -[[getting-started]] -= Getting started - [[getting-started-running-the-service]] From 1d911367d6077110bfaed8f7b34d2bb42b21dee0 Mon Sep 17 00:00:00 2001 From: Alexander Schwartz Date: Mon, 9 Sep 2019 21:32:50 +0200 Subject: [PATCH 072/502] Prevent unwanted incrementing of section number in operation macro See gh-638 --- .../main/resources/extensions/operation_block_macro.rb | 8 +++++++- .../asciidoctor/AbstractOperationBlockMacroTests.java | 2 +- .../test/resources/operations/snippet-in-section.html | 10 ++++++++-- 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/spring-restdocs-asciidoctor-support/src/main/resources/extensions/operation_block_macro.rb b/spring-restdocs-asciidoctor-support/src/main/resources/extensions/operation_block_macro.rb index a15ee8055..8b37bc63c 100644 --- a/spring-restdocs-asciidoctor-support/src/main/resources/extensions/operation_block_macro.rb +++ b/spring-restdocs-asciidoctor-support/src/main/resources/extensions/operation_block_macro.rb @@ -48,9 +48,15 @@ def do_read_snippets(snippets, parent, operation, snippet_titles) def add_blocks(content, doc, parent) options = { safe: doc.options[:safe], attributes: doc.attributes } fragment = Asciidoctor.load content, options + # use a template to get the correct sectname and level for blocks to append + template = create_section(parent, '', {}) fragment.blocks.each do |b| b.parent = parent - b.level += parent.level + # might be a standard block and no section in case of 'No snippets were found for operation' + if b.respond_to?(:sectname) + b.sectname = template.sectname + end + b.level = template.level parent << b end parent.find_by.each do |b| diff --git a/spring-restdocs-asciidoctor/src/test/java/org/springframework/restdocs/asciidoctor/AbstractOperationBlockMacroTests.java b/spring-restdocs-asciidoctor/src/test/java/org/springframework/restdocs/asciidoctor/AbstractOperationBlockMacroTests.java index 31bbda40c..bd0cab519 100644 --- a/spring-restdocs-asciidoctor/src/test/java/org/springframework/restdocs/asciidoctor/AbstractOperationBlockMacroTests.java +++ b/spring-restdocs-asciidoctor/src/test/java/org/springframework/restdocs/asciidoctor/AbstractOperationBlockMacroTests.java @@ -118,7 +118,7 @@ public void tableSnippetIncludeWithPdfBackend() throws Exception { @Test public void includeSnippetInSection() throws Exception { String result = this.asciidoctor.convert( - "= A\n\nAlpha\n\n== B\n\nBravo\n\n" + "operation::some-operation[snippets='curl-request']", + "= A\n:doctype: book\n:sectnums:\n\nAlpha\n\n== B\n\nBravo\n\n" + "operation::some-operation[snippets='curl-request']\n\n== C\n", this.options); assertThat(result).isEqualTo(getExpectedContentFromFile("snippet-in-section")); } diff --git a/spring-restdocs-asciidoctor/src/test/resources/operations/snippet-in-section.html b/spring-restdocs-asciidoctor/src/test/resources/operations/snippet-in-section.html index 0bc6f2728..a8ec3f471 100644 --- a/spring-restdocs-asciidoctor/src/test/resources/operations/snippet-in-section.html +++ b/spring-restdocs-asciidoctor/src/test/resources/operations/snippet-in-section.html @@ -6,18 +6,24 @@
-

B

+

1. B

Bravo

-

Curl request

+

1.1. Curl request

$ curl 'http://localhost:8080/' -i
+
+
+
+

2. C

+
+
\ No newline at end of file From 8624a33ff578b7de6492d9203ba5cedaf2418b51 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Thu, 19 Sep 2019 11:10:57 +0100 Subject: [PATCH 073/502] Polish "Prevent unwanted incrementing of section number in operation macro" See gh-638 --- .../asciidoctor/AbstractOperationBlockMacroTests.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/spring-restdocs-asciidoctor/src/test/java/org/springframework/restdocs/asciidoctor/AbstractOperationBlockMacroTests.java b/spring-restdocs-asciidoctor/src/test/java/org/springframework/restdocs/asciidoctor/AbstractOperationBlockMacroTests.java index bd0cab519..369c82660 100644 --- a/spring-restdocs-asciidoctor/src/test/java/org/springframework/restdocs/asciidoctor/AbstractOperationBlockMacroTests.java +++ b/spring-restdocs-asciidoctor/src/test/java/org/springframework/restdocs/asciidoctor/AbstractOperationBlockMacroTests.java @@ -117,9 +117,8 @@ public void tableSnippetIncludeWithPdfBackend() throws Exception { @Test public void includeSnippetInSection() throws Exception { - String result = this.asciidoctor.convert( - "= A\n:doctype: book\n:sectnums:\n\nAlpha\n\n== B\n\nBravo\n\n" + "operation::some-operation[snippets='curl-request']\n\n== C\n", - this.options); + String result = this.asciidoctor.convert("= A\n:doctype: book\n:sectnums:\n\nAlpha\n\n== B\n\nBravo\n\n" + + "operation::some-operation[snippets='curl-request']\n\n== C\n", this.options); assertThat(result).isEqualTo(getExpectedContentFromFile("snippet-in-section")); } From 5f6f7680cdf71a9674046cfcadd1f8aa7b6f84fb Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Thu, 19 Sep 2019 12:08:12 +0100 Subject: [PATCH 074/502] Upgrade to org.asciidoctor.convert 1.5.9.2 Closes gh-642 --- docs/build.gradle | 2 +- docs/src/docs/asciidoc/getting-started.adoc | 2 +- docs/src/docs/asciidoc/working-with-asciidoctor.adoc | 5 ----- samples/junit5/build.gradle | 2 +- samples/rest-assured/build.gradle | 2 +- samples/rest-notes-spring-hateoas/build.gradle | 2 +- 6 files changed, 5 insertions(+), 10 deletions(-) diff --git a/docs/build.gradle b/docs/build.gradle index 9accb8cb5..528f2f8bd 100644 --- a/docs/build.gradle +++ b/docs/build.gradle @@ -1,5 +1,5 @@ plugins { - id 'org.asciidoctor.convert' version '1.5.3' + id 'org.asciidoctor.convert' version '1.5.9.2' } repositories { diff --git a/docs/src/docs/asciidoc/getting-started.adoc b/docs/src/docs/asciidoc/getting-started.adoc index b9a9ef4b1..a5086ee75 100644 --- a/docs/src/docs/asciidoc/getting-started.adoc +++ b/docs/src/docs/asciidoc/getting-started.adoc @@ -146,7 +146,7 @@ the configuration are described in the following listings: .Gradle ---- plugins { <1> - id "org.asciidoctor.convert" version "1.5.3" + id "org.asciidoctor.convert" version "1.5.9.2" } dependencies { diff --git a/docs/src/docs/asciidoc/working-with-asciidoctor.adoc b/docs/src/docs/asciidoc/working-with-asciidoctor.adoc index b1d5869c0..05ba07bb4 100644 --- a/docs/src/docs/asciidoc/working-with-asciidoctor.adoc +++ b/docs/src/docs/asciidoc/working-with-asciidoctor.adoc @@ -30,11 +30,6 @@ been generated for a specific operation. It is made available by including `spring-restdocs-asciidoctor` in your project's <>. -WARNING: If you use Gradle and its daemon or support for continuous builds, do not -use version 1.5.6 of the `org.asciidoctor.convert` plugin. It contains a -https://github.com/asciidoctor/asciidoctor-gradle-plugin/issues/222[regression] that -prevents extensions from working reliably. - The target of the macro is the name of the operation. In its simplest form, you can use the macro to include all of the snippets for an operation, as shown in the following example: diff --git a/samples/junit5/build.gradle b/samples/junit5/build.gradle index c39976982..a7e86dd67 100644 --- a/samples/junit5/build.gradle +++ b/samples/junit5/build.gradle @@ -8,7 +8,7 @@ buildscript { } plugins { - id "org.asciidoctor.convert" version "1.5.3" + id "org.asciidoctor.convert" version "1.5.9.2" } apply plugin: 'java' diff --git a/samples/rest-assured/build.gradle b/samples/rest-assured/build.gradle index 20cfec7a5..ae01a5724 100644 --- a/samples/rest-assured/build.gradle +++ b/samples/rest-assured/build.gradle @@ -8,7 +8,7 @@ buildscript { } plugins { - id "org.asciidoctor.convert" version "1.5.3" + id "org.asciidoctor.convert" version "1.5.9.2" } apply plugin: 'java' diff --git a/samples/rest-notes-spring-hateoas/build.gradle b/samples/rest-notes-spring-hateoas/build.gradle index d563c6f2f..fec27b1a0 100644 --- a/samples/rest-notes-spring-hateoas/build.gradle +++ b/samples/rest-notes-spring-hateoas/build.gradle @@ -8,7 +8,7 @@ buildscript { } plugins { - id "org.asciidoctor.convert" version "1.5.3" + id "org.asciidoctor.convert" version "1.5.9.2" } apply plugin: 'java' From 733039d12f8707b42237eda494ebf7d9002b234f Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Sun, 29 Sep 2019 18:10:19 +0100 Subject: [PATCH 075/502] Upgrade to Spring Framework 5.0.15.RELEASE Closes gh-636 --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index ec598de2e..92f2c2df7 100644 --- a/build.gradle +++ b/build.gradle @@ -47,7 +47,7 @@ nohttp { } ext { - springVersion = '5.0.9.RELEASE' + springVersion = '5.0.15.RELEASE' javadocLinks = [ 'https://docs.oracle.com/javase/8/docs/api/', "https://docs.spring.io/spring-framework/docs/$springVersion/javadoc-api/", From ce9d0c985f2183c81f3190255e080bcd75fa3b64 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Sun, 29 Sep 2019 18:24:01 +0100 Subject: [PATCH 076/502] Upgrade the Spring Boot-based samples to 2.1.8.RELEASE Closes gh-645 --- samples/junit5/build.gradle | 2 +- samples/rest-assured/build.gradle | 2 +- samples/rest-notes-slate/build.gradle | 2 +- samples/rest-notes-spring-data-rest/pom.xml | 2 +- samples/rest-notes-spring-hateoas/build.gradle | 2 +- samples/testng/build.gradle | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/samples/junit5/build.gradle b/samples/junit5/build.gradle index a7e86dd67..26ecb01e8 100644 --- a/samples/junit5/build.gradle +++ b/samples/junit5/build.gradle @@ -3,7 +3,7 @@ buildscript { mavenCentral() } dependencies { - classpath 'org.springframework.boot:spring-boot-gradle-plugin:2.1.3.RELEASE' + classpath 'org.springframework.boot:spring-boot-gradle-plugin:2.1.8.RELEASE' } } diff --git a/samples/rest-assured/build.gradle b/samples/rest-assured/build.gradle index ae01a5724..5ba9a6a3f 100644 --- a/samples/rest-assured/build.gradle +++ b/samples/rest-assured/build.gradle @@ -3,7 +3,7 @@ buildscript { mavenCentral() } dependencies { - classpath 'org.springframework.boot:spring-boot-gradle-plugin:2.1.3.RELEASE' + classpath 'org.springframework.boot:spring-boot-gradle-plugin:2.1.8.RELEASE' } } diff --git a/samples/rest-notes-slate/build.gradle b/samples/rest-notes-slate/build.gradle index f23a622ef..1c36d264f 100644 --- a/samples/rest-notes-slate/build.gradle +++ b/samples/rest-notes-slate/build.gradle @@ -3,7 +3,7 @@ buildscript { mavenCentral() } dependencies { - classpath 'org.springframework.boot:spring-boot-gradle-plugin:2.1.3.RELEASE' + classpath 'org.springframework.boot:spring-boot-gradle-plugin:2.1.9.RELEASE' } } diff --git a/samples/rest-notes-spring-data-rest/pom.xml b/samples/rest-notes-spring-data-rest/pom.xml index 2fc62c038..c043a831d 100644 --- a/samples/rest-notes-spring-data-rest/pom.xml +++ b/samples/rest-notes-spring-data-rest/pom.xml @@ -11,7 +11,7 @@ org.springframework.boot spring-boot-starter-parent - 2.1.3.RELEASE + 2.1.8.RELEASE diff --git a/samples/rest-notes-spring-hateoas/build.gradle b/samples/rest-notes-spring-hateoas/build.gradle index fec27b1a0..38ac2949c 100644 --- a/samples/rest-notes-spring-hateoas/build.gradle +++ b/samples/rest-notes-spring-hateoas/build.gradle @@ -3,7 +3,7 @@ buildscript { mavenCentral() } dependencies { - classpath 'org.springframework.boot:spring-boot-gradle-plugin:2.1.3.RELEASE' + classpath 'org.springframework.boot:spring-boot-gradle-plugin:2.1.8.RELEASE' } } diff --git a/samples/testng/build.gradle b/samples/testng/build.gradle index 2550b7c33..b85ec5d44 100644 --- a/samples/testng/build.gradle +++ b/samples/testng/build.gradle @@ -3,7 +3,7 @@ buildscript { mavenCentral() } dependencies { - classpath 'org.springframework.boot:spring-boot-gradle-plugin:2.1.3.RELEASE' + classpath 'org.springframework.boot:spring-boot-gradle-plugin:2.1.8.RELEASE' } } From c12d8c00246b5a42a538c3e433f1bac8e8998765 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Sun, 29 Sep 2019 18:24:41 +0100 Subject: [PATCH 077/502] Complete upgrade to org.asciidoctor.convert 1.5.9.2 See gh-642 --- samples/testng/build.gradle | 2 +- samples/web-test-client/build.gradle | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/samples/testng/build.gradle b/samples/testng/build.gradle index b85ec5d44..8381266a8 100644 --- a/samples/testng/build.gradle +++ b/samples/testng/build.gradle @@ -8,7 +8,7 @@ buildscript { } plugins { - id "org.asciidoctor.convert" version "1.5.3" + id "org.asciidoctor.convert" version "1.5.9.2" } apply plugin: 'java' diff --git a/samples/web-test-client/build.gradle b/samples/web-test-client/build.gradle index 90f07d3c5..8a89a0747 100644 --- a/samples/web-test-client/build.gradle +++ b/samples/web-test-client/build.gradle @@ -1,5 +1,5 @@ plugins { - id "org.asciidoctor.convert" version "1.5.3" + id "org.asciidoctor.convert" version "1.5.9.2" } apply plugin: 'java' From e66c1f4c08f03ecb08316e6c402b312830b246f4 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Sun, 29 Sep 2019 19:48:11 +0100 Subject: [PATCH 078/502] Fix generation of javadoc for the documentation zip --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 92f2c2df7..9bc4ef060 100644 --- a/build.gradle +++ b/build.gradle @@ -226,7 +226,7 @@ task api (type: Javadoc) { options.links = javadocLinks options.addStringOption '-quiet' - source publishedCodeProjects.findAll { !it.name == 'spring-restdocs-asciidoctor' } + source publishedCodeProjects.findAll { it.name != 'spring-restdocs-asciidoctor' } .collect { it.sourceSets.main.allJava } destinationDir = new File(buildDir, "api") From 816987824c03d4b15deb1e90bcb6de9b4ac57c47 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Mon, 30 Sep 2019 09:04:09 +0100 Subject: [PATCH 079/502] Ensure that spring-restdocs-asciidoctor pom contains name and description --- spring-restdocs-asciidoctor/build.gradle | 2 ++ 1 file changed, 2 insertions(+) diff --git a/spring-restdocs-asciidoctor/build.gradle b/spring-restdocs-asciidoctor/build.gradle index dbcbf06f9..0fedbcd33 100644 --- a/spring-restdocs-asciidoctor/build.gradle +++ b/spring-restdocs-asciidoctor/build.gradle @@ -1,3 +1,5 @@ +description = 'Spring REST Docs Asciidoctor Extension' + configurations { merge testRuntime { extendsFrom merge } From 79fce0c0d72e478b3a9bda45555aff0c95c53d5c Mon Sep 17 00:00:00 2001 From: Spring Buildmaster Date: Mon, 30 Sep 2019 08:24:32 +0000 Subject: [PATCH 080/502] Next development version --- gradle.properties | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/gradle.properties b/gradle.properties index d7c7c7a43..bc9f2aa8a 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,7 +1,7 @@ -version=2.0.4.BUILD-SNAPSHOT -javaFormatVersion=0.0.15 -org.gradle.daemon=false +version=2.0.5.BUILD-SNAPSHOT asciidoctorj15Version=1.5.8.1 asciidoctorj16Version=1.6.2 +javaFormatVersion=0.0.15 asciidoctorj20Version=2.0.0 asciidoctorj21Version=2.1.0 +org.gradle.daemon=false From 92926d65bc348d8bd1ae44d5f2507b05b6eb667a Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Fri, 4 Oct 2019 18:34:42 +0100 Subject: [PATCH 081/502] Update the samples to use 2.0.5 snapshots --- samples/junit5/build.gradle | 2 +- samples/rest-assured/build.gradle | 2 +- samples/rest-notes-slate/build.gradle | 2 +- samples/rest-notes-spring-data-rest/pom.xml | 2 +- samples/rest-notes-spring-hateoas/build.gradle | 2 +- samples/testng/build.gradle | 2 +- samples/web-test-client/build.gradle | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/samples/junit5/build.gradle b/samples/junit5/build.gradle index 26ecb01e8..872ae25c6 100644 --- a/samples/junit5/build.gradle +++ b/samples/junit5/build.gradle @@ -31,7 +31,7 @@ ext { snippetsDir = file('build/generated-snippets') } -ext['spring-restdocs.version'] = '2.0.4.BUILD-SNAPSHOT' +ext['spring-restdocs.version'] = '2.0.5.BUILD-SNAPSHOT' dependencies { asciidoctor 'org.springframework.restdocs:spring-restdocs-asciidoctor' diff --git a/samples/rest-assured/build.gradle b/samples/rest-assured/build.gradle index 5ba9a6a3f..f3da3e124 100644 --- a/samples/rest-assured/build.gradle +++ b/samples/rest-assured/build.gradle @@ -31,7 +31,7 @@ ext { snippetsDir = file('build/generated-snippets') } -ext['spring-restdocs.version'] = '2.0.4.BUILD-SNAPSHOT' +ext['spring-restdocs.version'] = '2.0.5.BUILD-SNAPSHOT' dependencies { asciidoctor 'org.springframework.restdocs:spring-restdocs-asciidoctor' diff --git a/samples/rest-notes-slate/build.gradle b/samples/rest-notes-slate/build.gradle index 1c36d264f..edbf17ade 100644 --- a/samples/rest-notes-slate/build.gradle +++ b/samples/rest-notes-slate/build.gradle @@ -27,7 +27,7 @@ ext { snippetsDir = file('build/generated-snippets') } -ext['spring-restdocs.version'] = '2.0.4.BUILD-SNAPSHOT' +ext['spring-restdocs.version'] = '2.0.5.BUILD-SNAPSHOT' dependencies { compile 'org.springframework.boot:spring-boot-starter-data-jpa' diff --git a/samples/rest-notes-spring-data-rest/pom.xml b/samples/rest-notes-spring-data-rest/pom.xml index c043a831d..e0f1bd06a 100644 --- a/samples/rest-notes-spring-data-rest/pom.xml +++ b/samples/rest-notes-spring-data-rest/pom.xml @@ -18,7 +18,7 @@ UTF-8 1.8 - 2.0.4.BUILD-SNAPSHOT + 2.0.5.BUILD-SNAPSHOT diff --git a/samples/rest-notes-spring-hateoas/build.gradle b/samples/rest-notes-spring-hateoas/build.gradle index 38ac2949c..b9df631dc 100644 --- a/samples/rest-notes-spring-hateoas/build.gradle +++ b/samples/rest-notes-spring-hateoas/build.gradle @@ -31,7 +31,7 @@ ext { snippetsDir = file('build/generated-snippets') } -ext['spring-restdocs.version'] = '2.0.4.BUILD-SNAPSHOT' +ext['spring-restdocs.version'] = '2.0.5.BUILD-SNAPSHOT' dependencies { asciidoctor 'org.springframework.restdocs:spring-restdocs-asciidoctor' diff --git a/samples/testng/build.gradle b/samples/testng/build.gradle index 8381266a8..dad542e2b 100644 --- a/samples/testng/build.gradle +++ b/samples/testng/build.gradle @@ -31,7 +31,7 @@ ext { snippetsDir = file('build/generated-snippets') } -ext['spring-restdocs.version'] = '2.0.4.BUILD-SNAPSHOT' +ext['spring-restdocs.version'] = '2.0.5.BUILD-SNAPSHOT' dependencies { asciidoctor 'org.springframework.restdocs:spring-restdocs-asciidoctor' diff --git a/samples/web-test-client/build.gradle b/samples/web-test-client/build.gradle index 8a89a0747..fc1c6ba27 100644 --- a/samples/web-test-client/build.gradle +++ b/samples/web-test-client/build.gradle @@ -20,7 +20,7 @@ ext { snippetsDir = file('build/generated-snippets') } -ext['spring-restdocs.version'] = '2.0.4.BUILD-SNAPSHOT' +ext['spring-restdocs.version'] = '2.0.5.BUILD-SNAPSHOT' dependencies { compile 'io.projectreactor.ipc:reactor-netty:0.7.1.RELEASE' From 97ddf3dcec524d0742f2b4a144d4da19b7816212 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Fri, 4 Oct 2019 18:17:53 +0100 Subject: [PATCH 082/502] Fix handling of empty querty string parameters Previously empty parameters in a query string were handled inconsistently such that they sometimes had a value of "" in a list and sometimes were represented as an empty list. This inconsistency lead to the parameter appearing twice in the cURL request snippet. This commit removes the inconsistency by always using an empty string to represent an empty query parameter value. Fixes gh-647 --- .../restdocs/operation/QueryStringParser.java | 6 ++---- .../restdocs/operation/QueryStringParserTests.java | 14 ++++++++++++++ .../MockMvcRestDocumentationIntegrationTests.java | 13 +++++++++++++ ...stAssuredRestDocumentationIntegrationTests.java | 12 ++++++++++++ ...estClientRestDocumentationIntegrationTests.java | 11 +++++++++++ 5 files changed, 52 insertions(+), 4 deletions(-) diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/QueryStringParser.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/QueryStringParser.java index f02563768..49d637dd3 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/QueryStringParser.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/QueryStringParser.java @@ -64,10 +64,8 @@ private void processParameter(String parameter, Parameters parameters) { parameters.add(decode(name), decode(value)); } else { - List values = parameters.get(components[0]); - if (values == null) { - parameters.put(components[0], new LinkedList()); - } + List values = parameters.computeIfAbsent(components[0], (p) -> new LinkedList()); + values.add(""); } } else { diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/operation/QueryStringParserTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/operation/QueryStringParserTests.java index 75450b3be..b287d4415 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/operation/QueryStringParserTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/operation/QueryStringParserTests.java @@ -81,4 +81,18 @@ public void malformedParameter() { this.queryStringParser.parse(URI.create("http://localhost?a=apple=avocado")); } + @Test + public void emptyParameter() { + Parameters parameters = this.queryStringParser.parse(URI.create("http://localhost?a=")); + assertThat(parameters.size()).isEqualTo(1); + assertThat(parameters).containsEntry("a", Arrays.asList("")); + } + + @Test + public void emptyAndNotEmptyParameter() { + Parameters parameters = this.queryStringParser.parse(URI.create("http://localhost?a=&a=alpha")); + assertThat(parameters.size()).isEqualTo(1); + assertThat(parameters).containsEntry("a", Arrays.asList("", "alpha")); + } + } diff --git a/spring-restdocs-mockmvc/src/test/java/org/springframework/restdocs/mockmvc/MockMvcRestDocumentationIntegrationTests.java b/spring-restdocs-mockmvc/src/test/java/org/springframework/restdocs/mockmvc/MockMvcRestDocumentationIntegrationTests.java index 129952b7e..b2da36ad1 100644 --- a/spring-restdocs-mockmvc/src/test/java/org/springframework/restdocs/mockmvc/MockMvcRestDocumentationIntegrationTests.java +++ b/spring-restdocs-mockmvc/src/test/java/org/springframework/restdocs/mockmvc/MockMvcRestDocumentationIntegrationTests.java @@ -185,6 +185,19 @@ public void curlSnippetWithQueryStringOnPost() throws Exception { + " -H 'Accept: application/json' \\%n" + " -d 'a=alpha'")))); } + @Test + public void curlSnippetWithEmptyParameterQueryString() throws Exception { + MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(this.context) + .apply(documentationConfiguration(this.restDocumentation)).build(); + mockMvc.perform(get("/").param("a", "").accept(MediaType.APPLICATION_JSON)).andExpect(status().isOk()) + .andDo(document("curl-snippet-with-empty-parameter-query-string")); + assertThat( + new File("build/generated-snippets/curl-snippet-with-empty-parameter-query-string/curl-request.adoc")) + .has(content(codeBlock(TemplateFormats.asciidoctor(), "bash") + .withContent(String.format("$ curl 'http://localhost:8080/?a=' -i -X GET \\%n" + + " -H 'Accept: application/json'")))); + } + @Test public void curlSnippetWithContentAndParametersOnPost() throws Exception { MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(this.context) diff --git a/spring-restdocs-restassured/src/test/java/org/springframework/restdocs/restassured3/RestAssuredRestDocumentationIntegrationTests.java b/spring-restdocs-restassured/src/test/java/org/springframework/restdocs/restassured3/RestAssuredRestDocumentationIntegrationTests.java index 492e71b21..aa86fc1f8 100644 --- a/spring-restdocs-restassured/src/test/java/org/springframework/restdocs/restassured3/RestAssuredRestDocumentationIntegrationTests.java +++ b/spring-restdocs-restassured/src/test/java/org/springframework/restdocs/restassured3/RestAssuredRestDocumentationIntegrationTests.java @@ -120,6 +120,18 @@ public void curlSnippetWithCookies() throws Exception { + " -H 'Content-Type: " + contentType + "' \\%n" + " --cookie 'cookieName=cookieVal'")))); } + @Test + public void curlSnippetWithEmptyParameterQueryString() throws Exception { + given().port(tomcat.getPort()).filter(documentationConfiguration(this.restDocumentation)) + .filter(document("curl-snippet-with-empty-parameter-query-string")).accept("application/json") + .param("a", "").get("/").then().statusCode(200); + assertThat( + new File("build/generated-snippets/curl-snippet-with-empty-parameter-query-string/curl-request.adoc")) + .has(content(codeBlock(TemplateFormats.asciidoctor(), "bash") + .withContent(String.format("$ curl 'http://localhost:" + tomcat.getPort() + + "/?a=' -i -X GET \\%n -H 'Accept: application/json'")))); + } + @Test public void curlSnippetWithQueryStringOnPost() throws Exception { given().port(tomcat.getPort()).filter(documentationConfiguration(this.restDocumentation)) diff --git a/spring-restdocs-webtestclient/src/test/java/org/springframework/restdocs/webtestclient/WebTestClientRestDocumentationIntegrationTests.java b/spring-restdocs-webtestclient/src/test/java/org/springframework/restdocs/webtestclient/WebTestClientRestDocumentationIntegrationTests.java index 06199f8c8..3c59dc606 100644 --- a/spring-restdocs-webtestclient/src/test/java/org/springframework/restdocs/webtestclient/WebTestClientRestDocumentationIntegrationTests.java +++ b/spring-restdocs-webtestclient/src/test/java/org/springframework/restdocs/webtestclient/WebTestClientRestDocumentationIntegrationTests.java @@ -165,6 +165,17 @@ public void curlSnippetWithCookies() throws Exception { + " -H 'Accept: application/json' \\%n" + " --cookie 'cookieName=cookieVal'")))); } + @Test + public void curlSnippetWithEmptyParameterQueryString() throws Exception { + this.webTestClient.get().uri("/?a=").accept(MediaType.APPLICATION_JSON).exchange().expectStatus().isOk() + .expectBody().consumeWith(document("curl-snippet-with-empty-parameter-query-string")); + assertThat( + new File("build/generated-snippets/curl-snippet-with-empty-parameter-query-string/curl-request.adoc")) + .has(content(codeBlock(TemplateFormats.asciidoctor(), "bash") + .withContent(String.format("$ curl 'https://api.example.com/?a=' -i -X GET \\%n" + + " -H 'Accept: application/json'")))); + } + @Test public void httpieSnippetWithCookies() throws Exception { this.webTestClient.get().uri("/").cookie("cookieName", "cookieVal").accept(MediaType.APPLICATION_JSON) From 4fb27dbc9f01d285ca9d6efe08532f107b418e3f Mon Sep 17 00:00:00 2001 From: Johnny Lim Date: Thu, 17 Oct 2019 08:48:19 +0900 Subject: [PATCH 083/502] Remove accidental characters in sample's pom.xml See gh-651 --- samples/rest-notes-spring-data-rest/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/rest-notes-spring-data-rest/pom.xml b/samples/rest-notes-spring-data-rest/pom.xml index e0f1bd06a..1fe266b2a 100644 --- a/samples/rest-notes-spring-data-rest/pom.xml +++ b/samples/rest-notes-spring-data-rest/pom.xml @@ -86,7 +86,7 @@ true - DEBUG (2) + DEBUG From bb7aecbfe554941c57c1221d55cdd3f60e5c6934 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Thu, 17 Oct 2019 15:40:52 +0100 Subject: [PATCH 084/502] Fix problem with operation block macro when using leveloffset Previously, when a document had a leveloffset attribute this was included in the attributes used when loading a snippet in the operation block macro. This could lead to warnings about section titles being out of sequence as the level used for the title did not take the leveloffset into consideration. This commit clones the documents attributes and removes any leveloffset attribute before loading a snippet. This removes the need for the leveloffset to be considered when loading a snippet fragment. As before, the level of each block in the fragment loaded from snippet is then set prior to adding the block to the main document. This takes the leveloffset into consideration. Closes gh-649 --- .../extensions/operation_block_macro.rb | 3 ++- .../AbstractOperationBlockMacroTests.java | 16 ++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/spring-restdocs-asciidoctor-support/src/main/resources/extensions/operation_block_macro.rb b/spring-restdocs-asciidoctor-support/src/main/resources/extensions/operation_block_macro.rb index 8b37bc63c..94f118018 100644 --- a/spring-restdocs-asciidoctor-support/src/main/resources/extensions/operation_block_macro.rb +++ b/spring-restdocs-asciidoctor-support/src/main/resources/extensions/operation_block_macro.rb @@ -46,7 +46,8 @@ def do_read_snippets(snippets, parent, operation, snippet_titles) end def add_blocks(content, doc, parent) - options = { safe: doc.options[:safe], attributes: doc.attributes } + options = { safe: doc.options[:safe], attributes: doc.attributes.clone } + options[:attributes].delete 'leveloffset' fragment = Asciidoctor.load content, options # use a template to get the correct sectname and level for blocks to append template = create_section(parent, '', {}) diff --git a/spring-restdocs-asciidoctor/src/test/java/org/springframework/restdocs/asciidoctor/AbstractOperationBlockMacroTests.java b/spring-restdocs-asciidoctor/src/test/java/org/springframework/restdocs/asciidoctor/AbstractOperationBlockMacroTests.java index 369c82660..c40f9344a 100644 --- a/spring-restdocs-asciidoctor/src/test/java/org/springframework/restdocs/asciidoctor/AbstractOperationBlockMacroTests.java +++ b/spring-restdocs-asciidoctor/src/test/java/org/springframework/restdocs/asciidoctor/AbstractOperationBlockMacroTests.java @@ -122,6 +122,22 @@ public void includeSnippetInSection() throws Exception { assertThat(result).isEqualTo(getExpectedContentFromFile("snippet-in-section")); } + @Test + public void includeSnippetInSectionWithAbsoluteLevelOffset() throws Exception { + String result = this.asciidoctor + .convert("= A\n:doctype: book\n:sectnums:\n:leveloffset: 1\n\nAlpha\n\n= B\n\nBravo\n\n" + + "operation::some-operation[snippets='curl-request']\n\n= C\n", this.options); + assertThat(result).isEqualTo(getExpectedContentFromFile("snippet-in-section")); + } + + @Test + public void includeSnippetInSectionWithRelativeLevelOffset() throws Exception { + String result = this.asciidoctor + .convert("= A\n:doctype: book\n:sectnums:\n:leveloffset: +1\n\nAlpha\n\n= B\n\nBravo\n\n" + + "operation::some-operation[snippets='curl-request']\n\n= C\n", this.options); + assertThat(result).isEqualTo(getExpectedContentFromFile("snippet-in-section")); + } + @Test public void includeSnippetInSectionWithPdfBackend() throws Exception { File output = configurePdfOutput(); From aee641b642c250738329e411b6cbb57820af7586 Mon Sep 17 00:00:00 2001 From: Florian Ferreira Date: Thu, 17 Oct 2019 16:03:21 +0200 Subject: [PATCH 085/502] Fix NPE in HttpResponseSnippet when response has custom status See gh-653 --- .../restdocs/http/HttpResponseSnippet.java | 10 ++++++++-- .../restdocs/AbstractSnippetTests.java | 4 ++++ .../restdocs/http/HttpResponseSnippetTests.java | 5 +++++ .../restdocs/test/SnippetConditions.java | 13 +++++++++++++ 4 files changed, 30 insertions(+), 2 deletions(-) diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/http/HttpResponseSnippet.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/http/HttpResponseSnippet.java index 8ad1654e7..b24f92ad2 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/http/HttpResponseSnippet.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/http/HttpResponseSnippet.java @@ -59,9 +59,15 @@ protected Map createModel(Operation operation) { HttpStatus status = response.getStatus(); Map model = new HashMap<>(); model.put("responseBody", responseBody(response)); - model.put("statusCode", status.value()); - model.put("statusReason", status.getReasonPhrase()); model.put("headers", headers(response)); + if (status != null) { + model.put("statusCode", status.value()); + model.put("statusReason", status.getReasonPhrase()); + } + else { + model.put("statusCode", response.getStatusCode()); + model.put("statusReason", "Http custom status."); + } return model; } diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/AbstractSnippetTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/AbstractSnippetTests.java index f04afe0be..b27b31421 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/AbstractSnippetTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/AbstractSnippetTests.java @@ -89,6 +89,10 @@ public HttpResponseCondition httpResponse(HttpStatus responseStatus) { return SnippetConditions.httpResponse(this.templateFormat, responseStatus); } + public HttpResponseCondition httpResponse(Integer responseStatusCode, String responseStatusReason) { + return SnippetConditions.httpResponse(this.templateFormat, responseStatusCode, responseStatusReason); + } + protected FileSystemResource snippetResource(String name) { return new FileSystemResource( "src/test/resources/custom-snippet-templates/" + this.templateFormat.getId() + "/" + name + ".snippet"); diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/http/HttpResponseSnippetTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/http/HttpResponseSnippetTests.java index bf701b432..41d4f1e04 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/http/HttpResponseSnippetTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/http/HttpResponseSnippetTests.java @@ -97,4 +97,9 @@ public void responseWithCustomSnippetAttributes() throws IOException { assertThat(this.generatedSnippets.httpResponse()).contains("Title for the response"); } + @Test + public void responseWithCustomStatus() throws IOException { + new HttpResponseSnippet().document(this.operationBuilder.response().status(215).build()); + assertThat(this.generatedSnippets.httpResponse()).is(httpResponse(215,"Http custom status.")); + } } diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/test/SnippetConditions.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/test/SnippetConditions.java index 657b3e572..2c3905811 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/test/SnippetConditions.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/test/SnippetConditions.java @@ -71,6 +71,13 @@ public static HttpResponseCondition httpResponse(TemplateFormat format, HttpStat return new HttpResponseCondition(status, new MarkdownCodeBlockCondition<>("http"), 2); } + public static HttpResponseCondition httpResponse(TemplateFormat format, Integer responseStatusCode, String responseStatusReason) { + if ("adoc".equals(format.getFileExtension())) { + return new HttpResponseCondition(responseStatusCode, responseStatusReason, new AsciidoctorCodeBlockCondition<>("http", "nowrap"), 3); + } + return new HttpResponseCondition(responseStatusCode, responseStatusReason, new MarkdownCodeBlockCondition<>("http"), 2); + } + @SuppressWarnings({ "rawtypes" }) public static CodeBlockCondition codeBlock(TemplateFormat format, String language) { if ("adoc".equals(format.getFileExtension())) { @@ -235,6 +242,12 @@ private HttpResponseCondition(HttpStatus status, CodeBlockCondition delegate, this.content(""); } + private HttpResponseCondition(Integer responseStatusCode, String responseStatusReason, CodeBlockCondition delegate, int headerOffset) { + super(delegate, headerOffset); + this.content("HTTP/1.1 " + responseStatusCode + " " + responseStatusReason); + this.content(""); + } + } /** From d925a9f2195615d7dc9ddcff3cac940c845e51fb Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Tue, 22 Oct 2019 10:06:51 +0100 Subject: [PATCH 086/502] Polish "Fix NPE in HttpResponseSnippet when response has custom status" See gh-653 --- .../restdocs/http/HttpResponseSnippet.java | 6 +++--- .../restdocs/AbstractSnippetTests.java | 4 ++-- .../restdocs/http/HttpResponseSnippetTests.java | 3 ++- .../restdocs/test/SnippetConditions.java | 12 ++++++++---- 4 files changed, 15 insertions(+), 10 deletions(-) diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/http/HttpResponseSnippet.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/http/HttpResponseSnippet.java index b24f92ad2..7e4a9c113 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/http/HttpResponseSnippet.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/http/HttpResponseSnippet.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-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. @@ -56,17 +56,17 @@ protected HttpResponseSnippet(Map attributes) { @Override protected Map createModel(Operation operation) { OperationResponse response = operation.getResponse(); - HttpStatus status = response.getStatus(); Map model = new HashMap<>(); model.put("responseBody", responseBody(response)); model.put("headers", headers(response)); + HttpStatus status = response.getStatus(); if (status != null) { model.put("statusCode", status.value()); model.put("statusReason", status.getReasonPhrase()); } else { model.put("statusCode", response.getStatusCode()); - model.put("statusReason", "Http custom status."); + model.put("statusReason", ""); } return model; } diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/AbstractSnippetTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/AbstractSnippetTests.java index b27b31421..0dabb13f7 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/AbstractSnippetTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/AbstractSnippetTests.java @@ -89,8 +89,8 @@ public HttpResponseCondition httpResponse(HttpStatus responseStatus) { return SnippetConditions.httpResponse(this.templateFormat, responseStatus); } - public HttpResponseCondition httpResponse(Integer responseStatusCode, String responseStatusReason) { - return SnippetConditions.httpResponse(this.templateFormat, responseStatusCode, responseStatusReason); + public HttpResponseCondition httpResponse(int responseStatusCode) { + return SnippetConditions.httpResponse(this.templateFormat, responseStatusCode, ""); } protected FileSystemResource snippetResource(String name) { diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/http/HttpResponseSnippetTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/http/HttpResponseSnippetTests.java index 41d4f1e04..302871834 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/http/HttpResponseSnippetTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/http/HttpResponseSnippetTests.java @@ -100,6 +100,7 @@ public void responseWithCustomSnippetAttributes() throws IOException { @Test public void responseWithCustomStatus() throws IOException { new HttpResponseSnippet().document(this.operationBuilder.response().status(215).build()); - assertThat(this.generatedSnippets.httpResponse()).is(httpResponse(215,"Http custom status.")); + assertThat(this.generatedSnippets.httpResponse()).is(httpResponse(215)); } + } diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/test/SnippetConditions.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/test/SnippetConditions.java index 2c3905811..de574f194 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/test/SnippetConditions.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/test/SnippetConditions.java @@ -71,11 +71,14 @@ public static HttpResponseCondition httpResponse(TemplateFormat format, HttpStat return new HttpResponseCondition(status, new MarkdownCodeBlockCondition<>("http"), 2); } - public static HttpResponseCondition httpResponse(TemplateFormat format, Integer responseStatusCode, String responseStatusReason) { + public static HttpResponseCondition httpResponse(TemplateFormat format, Integer responseStatusCode, + String responseStatusReason) { if ("adoc".equals(format.getFileExtension())) { - return new HttpResponseCondition(responseStatusCode, responseStatusReason, new AsciidoctorCodeBlockCondition<>("http", "nowrap"), 3); + return new HttpResponseCondition(responseStatusCode, responseStatusReason, + new AsciidoctorCodeBlockCondition<>("http", "nowrap"), 3); } - return new HttpResponseCondition(responseStatusCode, responseStatusReason, new MarkdownCodeBlockCondition<>("http"), 2); + return new HttpResponseCondition(responseStatusCode, responseStatusReason, + new MarkdownCodeBlockCondition<>("http"), 2); } @SuppressWarnings({ "rawtypes" }) @@ -242,7 +245,8 @@ private HttpResponseCondition(HttpStatus status, CodeBlockCondition delegate, this.content(""); } - private HttpResponseCondition(Integer responseStatusCode, String responseStatusReason, CodeBlockCondition delegate, int headerOffset) { + private HttpResponseCondition(int responseStatusCode, String responseStatusReason, + CodeBlockCondition delegate, int headerOffset) { super(delegate, headerOffset); this.content("HTTP/1.1 " + responseStatusCode + " " + responseStatusReason); this.content(""); From c8727a21881813fe5015ef7bf6d03a7e65dd114b Mon Sep 17 00:00:00 2001 From: ChangYong Date: Thu, 24 Oct 2019 17:07:36 +0900 Subject: [PATCH 087/502] Mention WebTestClient in Gradle getting started example See gh-654 --- docs/src/docs/asciidoc/getting-started.adoc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/src/docs/asciidoc/getting-started.adoc b/docs/src/docs/asciidoc/getting-started.adoc index a5086ee75..f5b806c9e 100644 --- a/docs/src/docs/asciidoc/getting-started.adoc +++ b/docs/src/docs/asciidoc/getting-started.adoc @@ -172,9 +172,9 @@ the configuration are described in the following listings: This will automatically configure the `snippets` attribute for use in your `.adoc` files to point to `build/generated-snippets`. It will also allow you to use the `operation` block macro. -<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> Add a dependency on `spring-restdocs-mockmvc` in the `testCompile` configuration. If you want to use + `WebTestClient` or REST Assured rather than MockMvc, add a dependency on + `spring-restdocs-webtestclient` or `spring-restdocs-restassured` respectively instead. <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 From 14149cb85f3d6eb8d7182ca853d748ccfae0889a Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Thu, 24 Oct 2019 10:15:27 +0100 Subject: [PATCH 088/502] Polish "Mention WebTestClient in Gradle getting started example" See gh-654 --- docs/src/docs/asciidoc/getting-started.adoc | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/docs/src/docs/asciidoc/getting-started.adoc b/docs/src/docs/asciidoc/getting-started.adoc index f5b806c9e..8e8b5c257 100644 --- a/docs/src/docs/asciidoc/getting-started.adoc +++ b/docs/src/docs/asciidoc/getting-started.adoc @@ -172,9 +172,10 @@ the configuration are described in the following listings: This will automatically configure the `snippets` attribute for use in your `.adoc` files to point to `build/generated-snippets`. It will also allow you to use the `operation` block macro. -<3> Add a dependency on `spring-restdocs-mockmvc` in the `testCompile` configuration. If you want to use - `WebTestClient` or REST Assured rather than MockMvc, add a dependency on - `spring-restdocs-webtestclient` or `spring-restdocs-restassured` respectively instead. +<3> Add a dependency on `spring-restdocs-mockmvc` in the `testCompile` configuration. If + you want to use `WebTestClient` or REST Assured rather than MockMvc, add a dependency + on `spring-restdocs-webtestclient` or `spring-restdocs-restassured` respectively + instead. <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 From c34cdc65b1a3309d369ee65c3ba6bde5cee13f7f Mon Sep 17 00:00:00 2001 From: Johnny Lim Date: Fri, 25 Oct 2019 19:16:49 +0900 Subject: [PATCH 089/502] Upgrade the Spring Boot-based samples to 2.1.9.RELEASE See gh-656 --- samples/junit5/build.gradle | 2 +- samples/rest-assured/build.gradle | 2 +- samples/rest-notes-spring-data-rest/pom.xml | 2 +- samples/rest-notes-spring-hateoas/build.gradle | 2 +- samples/testng/build.gradle | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/samples/junit5/build.gradle b/samples/junit5/build.gradle index 872ae25c6..7a9ec2655 100644 --- a/samples/junit5/build.gradle +++ b/samples/junit5/build.gradle @@ -3,7 +3,7 @@ buildscript { mavenCentral() } dependencies { - classpath 'org.springframework.boot:spring-boot-gradle-plugin:2.1.8.RELEASE' + classpath 'org.springframework.boot:spring-boot-gradle-plugin:2.1.9.RELEASE' } } diff --git a/samples/rest-assured/build.gradle b/samples/rest-assured/build.gradle index f3da3e124..1c16a474a 100644 --- a/samples/rest-assured/build.gradle +++ b/samples/rest-assured/build.gradle @@ -3,7 +3,7 @@ buildscript { mavenCentral() } dependencies { - classpath 'org.springframework.boot:spring-boot-gradle-plugin:2.1.8.RELEASE' + classpath 'org.springframework.boot:spring-boot-gradle-plugin:2.1.9.RELEASE' } } diff --git a/samples/rest-notes-spring-data-rest/pom.xml b/samples/rest-notes-spring-data-rest/pom.xml index 1fe266b2a..6e60976a7 100644 --- a/samples/rest-notes-spring-data-rest/pom.xml +++ b/samples/rest-notes-spring-data-rest/pom.xml @@ -11,7 +11,7 @@ org.springframework.boot spring-boot-starter-parent - 2.1.8.RELEASE + 2.1.9.RELEASE diff --git a/samples/rest-notes-spring-hateoas/build.gradle b/samples/rest-notes-spring-hateoas/build.gradle index b9df631dc..def0731cd 100644 --- a/samples/rest-notes-spring-hateoas/build.gradle +++ b/samples/rest-notes-spring-hateoas/build.gradle @@ -3,7 +3,7 @@ buildscript { mavenCentral() } dependencies { - classpath 'org.springframework.boot:spring-boot-gradle-plugin:2.1.8.RELEASE' + classpath 'org.springframework.boot:spring-boot-gradle-plugin:2.1.9.RELEASE' } } diff --git a/samples/testng/build.gradle b/samples/testng/build.gradle index dad542e2b..ab514e417 100644 --- a/samples/testng/build.gradle +++ b/samples/testng/build.gradle @@ -3,7 +3,7 @@ buildscript { mavenCentral() } dependencies { - classpath 'org.springframework.boot:spring-boot-gradle-plugin:2.1.8.RELEASE' + classpath 'org.springframework.boot:spring-boot-gradle-plugin:2.1.9.RELEASE' } } From 189d235c84a663cc70563b054be75052939c9e9e Mon Sep 17 00:00:00 2001 From: Daniel Shuy Date: Wed, 18 Dec 2019 15:51:15 +0800 Subject: [PATCH 090/502] Use @BeforeEach instead of @Before in JUnit 5 examples See gh-663 --- .../example/restassured/ExampleApplicationJUnit5Tests.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/src/test/java/com/example/restassured/ExampleApplicationJUnit5Tests.java b/docs/src/test/java/com/example/restassured/ExampleApplicationJUnit5Tests.java index 1a3e54fac..1002a9a3f 100644 --- a/docs/src/test/java/com/example/restassured/ExampleApplicationJUnit5Tests.java +++ b/docs/src/test/java/com/example/restassured/ExampleApplicationJUnit5Tests.java @@ -18,7 +18,7 @@ import io.restassured.builder.RequestSpecBuilder; import io.restassured.specification.RequestSpecification; -import org.junit.Before; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.restdocs.RestDocumentationContextProvider; @@ -33,7 +33,7 @@ public class ExampleApplicationJUnit5Tests { // tag::setup[] private RequestSpecification spec; - @Before + @BeforeEach public void setUp(RestDocumentationContextProvider restDocumentation) { this.spec = new RequestSpecBuilder() .addFilter(documentationConfiguration(restDocumentation)) // <1> From 1ee96bbb7642614c59a67fccb0a7b8093a56d522 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 18 Dec 2019 17:43:35 +0000 Subject: [PATCH 091/502] Make tests tolerate varying presence of Content-Length header In Framework 5.2, the Content-Length is now provided by MockMvc. In earlier versions it is not. This commit updates the tests to tolerate this difference in behaviour so that the compatibility tests pass again. --- .../MockMvcRestDocumentationIntegrationTests.java | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/spring-restdocs-mockmvc/src/test/java/org/springframework/restdocs/mockmvc/MockMvcRestDocumentationIntegrationTests.java b/spring-restdocs-mockmvc/src/test/java/org/springframework/restdocs/mockmvc/MockMvcRestDocumentationIntegrationTests.java index b2da36ad1..b22f26b9e 100644 --- a/spring-restdocs-mockmvc/src/test/java/org/springframework/restdocs/mockmvc/MockMvcRestDocumentationIntegrationTests.java +++ b/spring-restdocs-mockmvc/src/test/java/org/springframework/restdocs/mockmvc/MockMvcRestDocumentationIntegrationTests.java @@ -25,8 +25,10 @@ import java.nio.charset.StandardCharsets; import java.util.Arrays; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.regex.Pattern; import javax.servlet.http.Cookie; @@ -385,11 +387,17 @@ public void preprocessedRequest() throws Exception { replacePattern(pattern, "\"<>\"")))) .andReturn(); HttpRequestCondition originalRequest = httpRequest(TemplateFormats.asciidoctor(), RequestMethod.GET, "/"); + Set mvcResultHeaderNames = new HashSet<>(); for (String headerName : IterableEnumeration.of(result.getRequest().getHeaderNames())) { originalRequest.header(headerName, result.getRequest().getHeader(headerName)); + mvcResultHeaderNames.add(headerName); } - assertThat(new File("build/generated-snippets/original-request/http-request.adoc")).has(content(originalRequest - .header("Host", "localhost:8080").header("Content-Length", "13").content("{\"a\":\"alpha\"}"))); + originalRequest.header("Host", "localhost:8080"); + if (!mvcResultHeaderNames.contains("Content-Length")) { + originalRequest.header("Content-Length", "13"); + } + assertThat(new File("build/generated-snippets/original-request/http-request.adoc")) + .has(content(originalRequest.content("{\"a\":\"alpha\"}"))); HttpRequestCondition preprocessedRequest = httpRequest(TemplateFormats.asciidoctor(), RequestMethod.GET, "/"); List removedHeaders = Arrays.asList("a", HttpHeaders.HOST, HttpHeaders.CONTENT_LENGTH); for (String headerName : IterableEnumeration.of(result.getRequest().getHeaderNames())) { From e2e61dff53387d813c2fecb5fa583bc63d0d525c Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Fri, 27 Mar 2020 15:44:59 +0000 Subject: [PATCH 092/502] Use snake_case consistently for anchors and cross-references Closes gh-674 --- .../src/main/asciidoc/api-guide.adoc | 40 +++++++++--------- .../main/asciidoc/getting-started-guide.adoc | 12 +++--- .../com/example/notes/ApiDocumentation.java | 30 ++++++------- .../src/docs/asciidoc/api-guide.adoc | 42 +++++++++---------- .../docs/asciidoc/getting-started-guide.adoc | 12 +++--- .../com/example/notes/ApiDocumentation.java | 24 +++++------ 6 files changed, 80 insertions(+), 80 deletions(-) diff --git a/samples/rest-notes-spring-data-rest/src/main/asciidoc/api-guide.adoc b/samples/rest-notes-spring-data-rest/src/main/asciidoc/api-guide.adoc index beed99d19..8cb817847 100644 --- a/samples/rest-notes-spring-data-rest/src/main/asciidoc/api-guide.adoc +++ b/samples/rest-notes-spring-data-rest/src/main/asciidoc/api-guide.adoc @@ -12,7 +12,7 @@ Andy Wilkinson; [[overview]] = Overview -[[overview-http-verbs]] +[[overview_http_verbs]] == HTTP verbs RESTful notes tries to adhere as closely as possible to standard HTTP and REST conventions in its @@ -34,7 +34,7 @@ use of HTTP verbs. | Used to delete an existing resource |=== -[[overview-http-status-codes]] +[[overview_http_status_codes]] == HTTP status codes RESTful notes tries to adhere as closely as possible to standard HTTP and REST conventions in its @@ -60,7 +60,7 @@ use of HTTP status codes. | The requested resource did not exist |=== -[[overview-errors]] +[[overview_errors]] == Errors Whenever an error response (status code >= 400) is returned, the body will contain a JSON object @@ -73,7 +73,7 @@ For example, a request that attempts to apply a non-existent tag to a note will include::{snippets}/error-example/http-response.adoc[] -[[overview-hypermedia]] +[[overview_hypermedia]] == Hypermedia RESTful Notes uses hypermedia and resources include links to other resources in their @@ -87,14 +87,14 @@ links to navigate from resource to resource. -[[resources-index]] +[[resources_index]] == Index The index provides the entry point into the service. -[[resources-index-access]] +[[resources_index_access]] === Accessing the index A `GET` request is used to access the index @@ -103,14 +103,14 @@ operation::index-example[snippets='response-fields,http-response,links'] -[[resources-notes]] +[[resources_notes]] == Notes The Notes resources is used to create and list notes -[[resources-notes-list]] +[[resources_notes_list]] === Listing notes A `GET` request will list all of the service's notes. @@ -119,7 +119,7 @@ operation::notes-list-example[snippets='response-fields,curl-request,http-respon -[[resources-notes-create]] +[[resources_notes_create]] === Creating a note A `POST` request is used to create a note. @@ -128,14 +128,14 @@ operation::notes-create-example[snippets='request-fields,curl-request,http-respo -[[resources-tags]] +[[resources_tags]] == Tags The Tags resource is used to create and list tags. -[[resources-tags-list]] +[[resources_tags_list]] === Listing tags A `GET` request will list all of the service's tags. @@ -144,7 +144,7 @@ operation::tags-list-example[snippets='response-fields,curl-request,http-respons -[[resources-tags-create]] +[[resources_tags_create]] === Creating a tag A `POST` request is used to create a note @@ -153,21 +153,21 @@ operation::tags-create-example[snippets='request-fields,curl-request,http-respon -[[resources-note]] +[[resources_note]] == Note The Note resource is used to retrieve, update, and delete individual notes -[[resources-note-links]] +[[resources_note_links]] === Links include::{snippets}/note-get-example/links.adoc[] -[[resources-note-retrieve]] +[[resources_note_retrieve]] === Retrieve a note A `GET` request will retrieve the details of a note @@ -176,7 +176,7 @@ operation::note-get-example[snippets='response-fields,curl-request,http-response -[[resources-note-update]] +[[resources_note_update]] === Update a note A `PATCH` request is used to update a note @@ -197,21 +197,21 @@ include::{snippets}/note-update-example/http-response.adoc[] -[[resources-tag]] +[[resources_tag]] == Tag The Tag resource is used to retrieve, update, and delete individual tags -[[resources-tag-links]] +[[resources_tag_links]] === Links include::{snippets}/tag-get-example/links.adoc[] -[[resources-tag-retrieve]] +[[resources_tag_retrieve]] === Retrieve a tag A `GET` request will retrieve the details of a tag @@ -220,7 +220,7 @@ operation::tag-get-example[snippets='response-fields,curl-request,http-response' -[[resources-tag-update]] +[[resources_tag_update]] === Update a tag A `PATCH` request is used to update a tag diff --git a/samples/rest-notes-spring-data-rest/src/main/asciidoc/getting-started-guide.adoc b/samples/rest-notes-spring-data-rest/src/main/asciidoc/getting-started-guide.adoc index f794201f7..b9ab9136c 100644 --- a/samples/rest-notes-spring-data-rest/src/main/asciidoc/getting-started-guide.adoc +++ b/samples/rest-notes-spring-data-rest/src/main/asciidoc/getting-started-guide.adoc @@ -15,7 +15,7 @@ to describe the relationships between resources and to allow navigation between -[[getting-started-running-the-service]] +[[getting_started_running_the_service]] == Running the service RESTful Notes is written using https://projects.spring.io/spring-boot[Spring Boot] which makes it easy to get it up and running so that you can start exploring the REST API. @@ -51,7 +51,7 @@ Note the `_links` in the JSON response. They are key to navigating the API. -[[getting-started-creating-a-note]] +[[getting_started_creating_a_note]] == Creating a note Now that you've started the service and verified that it works, the next step is to use it to create a new note. As you saw above, the URI for working with notes is included as @@ -82,7 +82,7 @@ Note the `tags` link which we'll make use of later. -[[getting-started-creating-a-tag]] +[[getting_started_creating_a_tag]] == Creating a tag To make a note easier to find, it can be associated with any number of tags. To be able to tag a note, you must first create the tag. @@ -113,7 +113,7 @@ include::{snippets}/creating-a-note/4/http-response.adoc[] -[[getting-started-tagging-a-note]] +[[getting_started_tagging_a_note]] == Tagging a note A tag isn't particularly useful until it's been associated with one or more notes. There are two ways to tag a note: when the note is first created or by updating an existing @@ -121,7 +121,7 @@ note. We'll look at both of these in turn. -[[getting-started-tagging-a-note-creating]] +[[getting_started_tagging_a_note_creating]] === Creating a tagged note The process is largely the same as we saw before, but this time, in addition to providing a title and body for the note, we'll also provide the tag that we want to be associated @@ -152,7 +152,7 @@ include::{snippets}/creating-a-note/7/http-response.adoc[] -[[getting-started-tagging-a-note-existing]] +[[getting_started_tagging_a_note_existing]] === Tagging an existing note An existing note can be tagged by executing a `PATCH` request against the note's URI with a body that contains the array of tags to be associated with the note. We'll used the diff --git a/samples/rest-notes-spring-data-rest/src/test/java/com/example/notes/ApiDocumentation.java b/samples/rest-notes-spring-data-rest/src/test/java/com/example/notes/ApiDocumentation.java index 4c65f7b08..bbcc9a3fb 100644 --- a/samples/rest-notes-spring-data-rest/src/test/java/com/example/notes/ApiDocumentation.java +++ b/samples/rest-notes-spring-data-rest/src/test/java/com/example/notes/ApiDocumentation.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2019 the original author or authors. + * Copyright 2014-2020 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. @@ -111,11 +111,11 @@ public void indexExample() throws Exception { .andExpect(status().isOk()) .andDo(document("index-example", links( - linkWithRel("notes").description("The <>"), - linkWithRel("tags").description("The <>"), + linkWithRel("notes").description("The <>"), + linkWithRel("tags").description("The <>"), linkWithRel("profile").description("The ALPS profile for the service")), responseFields( - subsectionWithPath("_links").description("<> to other resources")))); + subsectionWithPath("_links").description("<> to other resources")))); } @@ -136,8 +136,8 @@ public void notesListExample() throws Exception { linkWithRel("self").description("Canonical link for this resource"), linkWithRel("profile").description("The ALPS profile for this resource")), responseFields( - subsectionWithPath("_embedded.notes").description("An array of <>"), - subsectionWithPath("_links").description("<> to other resources")))); + subsectionWithPath("_embedded.notes").description("An array of <>"), + subsectionWithPath("_links").description("<> to other resources")))); } @Test @@ -201,13 +201,13 @@ public void noteGetExample() throws Exception { .andDo(print()) .andDo(document("note-get-example", links( - linkWithRel("self").description("Canonical link for this <>"), - linkWithRel("note").description("This <>"), + linkWithRel("self").description("Canonical link for this <>"), + linkWithRel("note").description("This <>"), linkWithRel("tags").description("This note's tags")), responseFields( fieldWithPath("title").description("The title of the note"), fieldWithPath("body").description("The body of the note"), - subsectionWithPath("_links").description("<> to other resources")))); + subsectionWithPath("_links").description("<> to other resources")))); } @Test @@ -226,8 +226,8 @@ public void tagsListExample() throws Exception { linkWithRel("self").description("Canonical link for this resource"), linkWithRel("profile").description("The ALPS profile for this resource")), responseFields( - subsectionWithPath("_embedded.tags").description("An array of <>"), - subsectionWithPath("_links").description("<> to other resources")))); + subsectionWithPath("_embedded.tags").description("An array of <>"), + subsectionWithPath("_links").description("<> to other resources")))); } @Test @@ -304,12 +304,12 @@ public void tagGetExample() throws Exception { .andExpect(jsonPath("name", is(tag.get("name")))) .andDo(document("tag-get-example", links( - linkWithRel("self").description("Canonical link for this <>"), - linkWithRel("tag").description("This <>"), - linkWithRel("notes").description("The <> that have this tag")), + linkWithRel("self").description("Canonical link for this <>"), + linkWithRel("tag").description("This <>"), + linkWithRel("notes").description("The notes that have this tag")), responseFields( fieldWithPath("name").description("The name of the tag"), - subsectionWithPath("_links").description("<> to other resources")))); + subsectionWithPath("_links").description("<> to other resources")))); } @Test diff --git a/samples/rest-notes-spring-hateoas/src/docs/asciidoc/api-guide.adoc b/samples/rest-notes-spring-hateoas/src/docs/asciidoc/api-guide.adoc index 27b6db583..90745896e 100644 --- a/samples/rest-notes-spring-hateoas/src/docs/asciidoc/api-guide.adoc +++ b/samples/rest-notes-spring-hateoas/src/docs/asciidoc/api-guide.adoc @@ -12,7 +12,7 @@ Andy Wilkinson; [[overview]] = Overview -[[overview-http-verbs]] +[[overview_http_verbs]] == HTTP verbs RESTful notes tries to adhere as closely as possible to standard HTTP and REST conventions in its @@ -34,7 +34,7 @@ use of HTTP verbs. | Used to delete an existing resource |=== -[[overview-http-status-codes]] +[[overview_http_status_codes]] == HTTP status codes RESTful notes tries to adhere as closely as possible to standard HTTP and REST conventions in its @@ -60,14 +60,14 @@ use of HTTP status codes. | The requested resource did not exist |=== -[[overview-headers]] +[[overview_headers]] == Headers Every response has the following header(s): include::{snippets}/headers-example/response-headers.adoc[] -[[overview-errors]] +[[overview_errors]] == Errors Whenever an error response (status code >= 400) is returned, the body will contain a JSON object @@ -80,7 +80,7 @@ For example, a request that attempts to apply a non-existent tag to a note will include::{snippets}/error-example/http-response.adoc[] -[[overview-hypermedia]] +[[overview_hypermedia]] == Hypermedia RESTful Notes uses hypermedia and resources include links to other resources in their @@ -94,14 +94,14 @@ links to navigate from resource to resource. -[[resources-index]] +[[resources_index]] == Index The index provides the entry point into the service. -[[resources-index-access]] +[[resources_index_access]] === Accessing the index A `GET` request is used to access the index @@ -110,14 +110,14 @@ operation::index-example[snippets='response-fields,http-response,links'] -[[resources-notes]] +[[resources_notes]] == Notes The Notes resources is used to create and list notes -[[resources-notes-list]] +[[resources_notes_list]] === Listing notes A `GET` request will list all of the service's notes. @@ -126,7 +126,7 @@ operation::notes-list-example[snippets='response-fields,curl-request,http-respon -[[resources-notes-create]] +[[resources_notes_create]] === Creating a note A `POST` request is used to create a note. @@ -135,14 +135,14 @@ operation::notes-create-example[snippets='request-fields,curl-request,http-respo -[[resources-tags]] +[[resources_tags]] == Tags The Tags resource is used to create and list tags. -[[resources-tags-list]] +[[resources_tags_list]] === Listing tags A `GET` request will list all of the service's tags. @@ -151,7 +151,7 @@ operation::tags-list-example[snippets='response-fields,curl-request,http-respons -[[resources-tags-create]] +[[resources_tags_create]] === Creating a tag A `POST` request is used to create a note @@ -160,21 +160,21 @@ operation::tags-create-example[snippets='request-fields,curl-request,http-respon -[[resources-note]] +[[resources_note]] == Note The Note resource is used to retrieve, update, and delete individual notes -[[resources-note-links]] +[[resources_note_links]] === Links include::{snippets}/note-get-example/links.adoc[] -[[resources-note-retrieve]] +[[resources_note_retrieve]] === Retrieve a note A `GET` request will retrieve the details of a note @@ -183,7 +183,7 @@ operation::note-get-example[snippets='response-fields,curl-request,http-response -[[resources-note-update]] +[[resources_note_update]] === Update a note A `PATCH` request is used to update a note @@ -198,21 +198,21 @@ operation::note-update-example[snippets='curl-request,http-response'] -[[resources-tag]] +[[resources_tag]] == Tag The Tag resource is used to retrieve, update, and delete individual tags -[[resources-tag-links]] +[[resources_tag_links]] === Links include::{snippets}/tag-get-example/links.adoc[] -[[resources-tag-retrieve]] +[[resources_tag_retrieve]] === Retrieve a tag A `GET` request will retrieve the details of a tag @@ -221,7 +221,7 @@ operation::tag-get-example[snippets='response-fields,curl-request,http-response' -[[resources-tag-update]] +[[resources_tag_update]] === Update a tag A `PATCH` request is used to update a tag diff --git a/samples/rest-notes-spring-hateoas/src/docs/asciidoc/getting-started-guide.adoc b/samples/rest-notes-spring-hateoas/src/docs/asciidoc/getting-started-guide.adoc index 788508f31..7e8346ac7 100644 --- a/samples/rest-notes-spring-hateoas/src/docs/asciidoc/getting-started-guide.adoc +++ b/samples/rest-notes-spring-hateoas/src/docs/asciidoc/getting-started-guide.adoc @@ -15,7 +15,7 @@ to describe the relationships between resources and to allow navigation between -[[getting-started-running-the-service]] +[[getting_started_running_the_service]] == Running the service RESTful Notes is written using https://projects.spring.io/spring-boot[Spring Boot] which makes it easy to get it up and running so that you can start exploring the REST API. @@ -49,7 +49,7 @@ Note the `_links` in the JSON response. They are key to navigating the API. -[[getting-started-creating-a-note]] +[[getting_started_creating_a_note]] == Creating a note Now that you've started the service and verified that it works, the next step is to use it to create a new note. As you saw above, the URI for working with notes is included as @@ -80,7 +80,7 @@ Note the `note-tags` link which we'll make use of later. -[[getting-started-creating-a-tag]] +[[getting_started_creating_a_tag]] == Creating a tag To make a note easier to find, it can be associated with any number of tags. To be able to tag a note, you must first create the tag. @@ -111,7 +111,7 @@ include::{snippets}/creating-a-note/4/http-response.adoc[] -[[getting-started-tagging-a-note]] +[[getting_started_tagging_a_note]] == Tagging a note A tag isn't particularly useful until it's been associated with one or more notes. There are two ways to tag a note: when the note is first created or by updating an existing @@ -119,7 +119,7 @@ note. We'll look at both of these in turn. -[[getting-started-tagging-a-note-creating]] +[[getting_started_tagging_a_note_creating]] === Creating a tagged note The process is largely the same as we saw before, but this time, in addition to providing a title and body for the note, we'll also provide the tag that we want to be associated @@ -150,7 +150,7 @@ include::{snippets}/creating-a-note/7/http-response.adoc[] -[[getting-started-tagging-a-note-existing]] +[[getting_started_tagging_a_note_existing]] === Tagging an existing note An existing note can be tagged by executing a `PATCH` request against the note's URI with a body that contains the array of tags to be associated with the note. We'll use the diff --git a/samples/rest-notes-spring-hateoas/src/test/java/com/example/notes/ApiDocumentation.java b/samples/rest-notes-spring-hateoas/src/test/java/com/example/notes/ApiDocumentation.java index 78ed5974b..17cebdb18 100644 --- a/samples/rest-notes-spring-hateoas/src/test/java/com/example/notes/ApiDocumentation.java +++ b/samples/rest-notes-spring-hateoas/src/test/java/com/example/notes/ApiDocumentation.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2019 the original author or authors. + * Copyright 2014-2020 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. @@ -136,10 +136,10 @@ public void indexExample() throws Exception { .andExpect(status().isOk()) .andDo(this.documentationHandler.document( links( - linkWithRel("notes").description("The <>"), - linkWithRel("tags").description("The <>")), + linkWithRel("notes").description("The <>"), + linkWithRel("tags").description("The <>")), responseFields( - subsectionWithPath("_links").description("<> to other resources")))); + subsectionWithPath("_links").description("<> to other resources")))); } @Test @@ -155,7 +155,7 @@ public void notesListExample() throws Exception { .andExpect(status().isOk()) .andDo(this.documentationHandler.document( responseFields( - subsectionWithPath("_embedded.notes").description("An array of <>")))); + subsectionWithPath("_embedded.notes").description("An array of <>")))); } @Test @@ -223,12 +223,12 @@ public void noteGetExample() throws Exception { .andExpect(jsonPath("_links.note-tags", is(notNullValue()))) .andDo(this.documentationHandler.document( links( - linkWithRel("self").description("This <>"), - linkWithRel("note-tags").description("This note's <>")), + linkWithRel("self").description("This <>"), + linkWithRel("note-tags").description("This note's <>")), responseFields( fieldWithPath("title").description("The title of the note"), fieldWithPath("body").description("The body of the note"), - subsectionWithPath("_links").description("<> to other resources")))); + subsectionWithPath("_links").description("<> to other resources")))); } @@ -246,7 +246,7 @@ public void tagsListExample() throws Exception { .andExpect(status().isOk()) .andDo(this.documentationHandler.document( responseFields( - subsectionWithPath("_embedded.tags").description("An array of <>")))); + subsectionWithPath("_embedded.tags").description("An array of <>")))); } @Test @@ -339,11 +339,11 @@ public void tagGetExample() throws Exception { .andExpect(jsonPath("name", is(tag.get("name")))) .andDo(this.documentationHandler.document( links( - linkWithRel("self").description("This <>"), - linkWithRel("tagged-notes").description("The <> that have this tag")), + linkWithRel("self").description("This <>"), + linkWithRel("tagged-notes").description("The <> that have this tag")), responseFields( fieldWithPath("name").description("The name of the tag"), - subsectionWithPath("_links").description("<> to other resources")))); + subsectionWithPath("_links").description("<> to other resources")))); } @Test From 075f02d64cbd7fa8ba69e23d3be6ef277ec70b2c Mon Sep 17 00:00:00 2001 From: luvarqpp Date: Fri, 27 Mar 2020 16:15:37 +0100 Subject: [PATCH 093/502] Add snapshot plugin repository to Data REST sample See gh-673 --- samples/rest-notes-spring-data-rest/pom.xml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/samples/rest-notes-spring-data-rest/pom.xml b/samples/rest-notes-spring-data-rest/pom.xml index 6e60976a7..ee1a1fe4c 100644 --- a/samples/rest-notes-spring-data-rest/pom.xml +++ b/samples/rest-notes-spring-data-rest/pom.xml @@ -133,5 +133,15 @@ + + + spring-snapshot + Spring Snapshot Repository + https://repo.spring.io/snapshot + + true + + + From eb0aaf389bd092e4843c45e12812824a0cded624 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Fri, 27 Mar 2020 15:48:59 +0000 Subject: [PATCH 094/502] Polish "Add snapshot plugin repository to Data REST sample" See gh-673 --- samples/rest-notes-spring-data-rest/pom.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/samples/rest-notes-spring-data-rest/pom.xml b/samples/rest-notes-spring-data-rest/pom.xml index ee1a1fe4c..02d133c6a 100644 --- a/samples/rest-notes-spring-data-rest/pom.xml +++ b/samples/rest-notes-spring-data-rest/pom.xml @@ -135,9 +135,9 @@ - spring-snapshot - Spring Snapshot Repository - https://repo.spring.io/snapshot + spring-snapshots + Spring snapshots + https://repo.spring.io/libs-snapshot true From 513a0e917243f1bce998383e29297da454c36dcf Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Fri, 27 Mar 2020 16:19:06 +0000 Subject: [PATCH 095/502] Tolerate breaking change in MockHttpServletRequestBuilder Closes gh-675 --- ...kMvcRestDocumentationIntegrationTests.java | 2 +- ...RestDocumentationRequestBuildersTests.java | 22 +++++++++---------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/spring-restdocs-mockmvc/src/test/java/org/springframework/restdocs/mockmvc/MockMvcRestDocumentationIntegrationTests.java b/spring-restdocs-mockmvc/src/test/java/org/springframework/restdocs/mockmvc/MockMvcRestDocumentationIntegrationTests.java index b22f26b9e..fdb6d4b0b 100644 --- a/spring-restdocs-mockmvc/src/test/java/org/springframework/restdocs/mockmvc/MockMvcRestDocumentationIntegrationTests.java +++ b/spring-restdocs-mockmvc/src/test/java/org/springframework/restdocs/mockmvc/MockMvcRestDocumentationIntegrationTests.java @@ -275,7 +275,7 @@ public void linksSnippet() throws Exception { public void pathParametersSnippet() throws Exception { MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(this.context) .apply(documentationConfiguration(this.restDocumentation)).build(); - mockMvc.perform(get("{foo}", "/").accept(MediaType.APPLICATION_JSON)).andExpect(status().isOk()) + mockMvc.perform(get("/{foo}", "").accept(MediaType.APPLICATION_JSON)).andExpect(status().isOk()) .andDo(document("links", pathParameters(parameterWithName("foo").description("The description")))); assertExpectedSnippetFilesExist(new File("build/generated-snippets/links"), "http-request.adoc", "http-response.adoc", "curl-request.adoc", "path-parameters.adoc"); diff --git a/spring-restdocs-mockmvc/src/test/java/org/springframework/restdocs/mockmvc/RestDocumentationRequestBuildersTests.java b/spring-restdocs-mockmvc/src/test/java/org/springframework/restdocs/mockmvc/RestDocumentationRequestBuildersTests.java index 66ee51463..53a12c115 100644 --- a/spring-restdocs-mockmvc/src/test/java/org/springframework/restdocs/mockmvc/RestDocumentationRequestBuildersTests.java +++ b/spring-restdocs-mockmvc/src/test/java/org/springframework/restdocs/mockmvc/RestDocumentationRequestBuildersTests.java @@ -51,7 +51,7 @@ public class RestDocumentationRequestBuildersTests { @Test public void getTemplate() { - assertTemplate(get("{template}", "t"), HttpMethod.GET); + assertTemplate(get("/{template}", "t"), HttpMethod.GET); } @Test @@ -61,7 +61,7 @@ public void getUri() { @Test public void postTemplate() { - assertTemplate(post("{template}", "t"), HttpMethod.POST); + assertTemplate(post("/{template}", "t"), HttpMethod.POST); } @Test @@ -71,7 +71,7 @@ public void postUri() { @Test public void putTemplate() { - assertTemplate(put("{template}", "t"), HttpMethod.PUT); + assertTemplate(put("/{template}", "t"), HttpMethod.PUT); } @Test @@ -81,7 +81,7 @@ public void putUri() { @Test public void patchTemplate() { - assertTemplate(patch("{template}", "t"), HttpMethod.PATCH); + assertTemplate(patch("/{template}", "t"), HttpMethod.PATCH); } @Test @@ -91,7 +91,7 @@ public void patchUri() { @Test public void deleteTemplate() { - assertTemplate(delete("{template}", "t"), HttpMethod.DELETE); + assertTemplate(delete("/{template}", "t"), HttpMethod.DELETE); } @Test @@ -101,7 +101,7 @@ public void deleteUri() { @Test public void optionsTemplate() { - assertTemplate(options("{template}", "t"), HttpMethod.OPTIONS); + assertTemplate(options("/{template}", "t"), HttpMethod.OPTIONS); } @Test @@ -111,7 +111,7 @@ public void optionsUri() { @Test public void headTemplate() { - assertTemplate(head("{template}", "t"), HttpMethod.HEAD); + assertTemplate(head("/{template}", "t"), HttpMethod.HEAD); } @Test @@ -121,7 +121,7 @@ public void headUri() { @Test public void requestTemplate() { - assertTemplate(request(HttpMethod.GET, "{template}", "t"), HttpMethod.GET); + assertTemplate(request(HttpMethod.GET, "/{template}", "t"), HttpMethod.GET); } @Test @@ -131,7 +131,7 @@ public void requestUri() { @Test public void fileUploadTemplate() { - assertTemplate(fileUpload("{template}", "t"), HttpMethod.POST); + assertTemplate(fileUpload("/{template}", "t"), HttpMethod.POST); } @Test @@ -142,8 +142,8 @@ public void fileUploadUri() { private void assertTemplate(MockHttpServletRequestBuilder builder, HttpMethod httpMethod) { MockHttpServletRequest request = builder.buildRequest(this.servletContext); assertThat((String) request.getAttribute(RestDocumentationGenerator.ATTRIBUTE_NAME_URL_TEMPLATE)) - .isEqualTo("{template}"); - assertThat(request.getRequestURI()).isEqualTo("t"); + .isEqualTo("/{template}"); + assertThat(request.getRequestURI()).isEqualTo("/t"); assertThat(request.getMethod()).isEqualTo(httpMethod.name()); } From 3fc8780dfc74a3da4e85e884ce29c089353696eb Mon Sep 17 00:00:00 2001 From: "jinseong.hwang" Date: Thu, 9 Apr 2020 02:39:39 +0900 Subject: [PATCH 096/502] Fix a typo in getting started reference documentation See gh-679 --- docs/src/docs/asciidoc/getting-started.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/docs/asciidoc/getting-started.adoc b/docs/src/docs/asciidoc/getting-started.adoc index 8e8b5c257..4adcf0a8e 100644 --- a/docs/src/docs/asciidoc/getting-started.adoc +++ b/docs/src/docs/asciidoc/getting-started.adoc @@ -516,7 +516,7 @@ is required. <2> Assert that the service produced the expected response. <3> Document the call to the service, writing the snippets into a directory named `index` (which is located beneath the configured output directory). The snippets are written by -a `RestDocumentationResultHandler`. You can obtain an instance of this clas from the +a `RestDocumentationResultHandler`. You can obtain an instance of this class from the static `document` method on `org.springframework.restdocs.mockmvc.MockMvcRestDocumentation`. From 0146f1a8ca9298608ea2280da373cb51267d858f Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 6 May 2020 13:35:19 +0100 Subject: [PATCH 097/502] Fix handling of parameters when documenting non-GET requests Fixes gh-683 --- .../restdocs/cli/CurlRequestSnippet.java | 8 +++++--- .../restdocs/cli/HttpieRequestSnippet.java | 8 +++++--- .../restdocs/http/HttpRequestSnippet.java | 8 +++++--- .../restdocs/cli/CurlRequestSnippetTests.java | 18 +++++++++++++++++- .../cli/HttpieRequestSnippetTests.java | 18 +++++++++++++++++- .../restdocs/http/HttpRequestSnippetTests.java | 18 +++++++++++++++++- 6 files changed, 66 insertions(+), 12 deletions(-) diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/cli/CurlRequestSnippet.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/cli/CurlRequestSnippet.java index d0f80f520..c0a7db3ce 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/cli/CurlRequestSnippet.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/cli/CurlRequestSnippet.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2019 the original author or authors. + * Copyright 2014-2020 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. @@ -91,8 +91,10 @@ private String getUrl(Operation operation) { } private boolean includeParametersInUri(OperationRequest request) { - return request.getMethod() == HttpMethod.GET || (request.getContent().length > 0 - && !MediaType.APPLICATION_FORM_URLENCODED.isCompatibleWith(request.getHeaders().getContentType())); + HttpMethod method = request.getMethod(); + return (method != HttpMethod.PUT && method != HttpMethod.POST && method != HttpMethod.PATCH) + || (request.getContent().length > 0 && !MediaType.APPLICATION_FORM_URLENCODED + .isCompatibleWith(request.getHeaders().getContentType())); } private String getOptions(Operation operation) { diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/cli/HttpieRequestSnippet.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/cli/HttpieRequestSnippet.java index 933930823..2617c80c6 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/cli/HttpieRequestSnippet.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/cli/HttpieRequestSnippet.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2019 the original author or authors. + * Copyright 2014-2020 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. @@ -129,8 +129,10 @@ private void writeOptions(OperationRequest request, PrintWriter writer) { } private boolean includeParametersInUri(OperationRequest request) { - return request.getMethod() == HttpMethod.GET || (request.getContent().length > 0 - && !MediaType.APPLICATION_FORM_URLENCODED.isCompatibleWith(request.getHeaders().getContentType())); + HttpMethod method = request.getMethod(); + return (method != HttpMethod.PUT && method != HttpMethod.POST && method != HttpMethod.PATCH) + || (request.getContent().length > 0 && !MediaType.APPLICATION_FORM_URLENCODED + .isCompatibleWith(request.getHeaders().getContentType())); } private boolean includeParametersAsFormOptions(OperationRequest request) { diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/http/HttpRequestSnippet.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/http/HttpRequestSnippet.java index 7193bd8a2..1fb835828 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/http/HttpRequestSnippet.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/http/HttpRequestSnippet.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2019 the original author or authors. + * Copyright 2014-2020 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. @@ -92,8 +92,10 @@ private String getPath(OperationRequest request) { } private boolean includeParametersInUri(OperationRequest request) { - return request.getMethod() == HttpMethod.GET || (request.getContent().length > 0 - && !MediaType.APPLICATION_FORM_URLENCODED.isCompatibleWith(request.getHeaders().getContentType())); + HttpMethod method = request.getMethod(); + return (method != HttpMethod.PUT && method != HttpMethod.POST && method != HttpMethod.PATCH) + || (request.getContent().length > 0 && !MediaType.APPLICATION_FORM_URLENCODED + .isCompatibleWith(request.getHeaders().getContentType())); } private List> getHeaders(OperationRequest request) { diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/cli/CurlRequestSnippetTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/cli/CurlRequestSnippetTests.java index fd7d29771..779c00772 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/cli/CurlRequestSnippetTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/cli/CurlRequestSnippetTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2019 the original author or authors. + * Copyright 2014-2020 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. @@ -326,4 +326,20 @@ public void postWithContentAndParameters() throws IOException { .withContent("$ curl 'http://localhost/foo?a=alpha&b=bravo' -i " + "-X POST -d 'Some content'")); } + @Test + public void deleteWithParameters() throws IOException { + new CurlRequestSnippet(this.commandFormatter).document(this.operationBuilder.request("http://localhost/foo") + .method("DELETE").param("a", "alpha").param("b", "bravo").build()); + assertThat(this.generatedSnippets.curlRequest()) + .is(codeBlock("bash").withContent("$ curl 'http://localhost/foo?a=alpha&b=bravo' -i " + "-X DELETE")); + } + + @Test + public void deleteWithQueryString() throws IOException { + new CurlRequestSnippet(this.commandFormatter).document( + this.operationBuilder.request("http://localhost/foo?a=alpha&b=bravo").method("DELETE").build()); + assertThat(this.generatedSnippets.curlRequest()) + .is(codeBlock("bash").withContent("$ curl 'http://localhost/foo?a=alpha&b=bravo' -i " + "-X DELETE")); + } + } diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/cli/HttpieRequestSnippetTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/cli/HttpieRequestSnippetTests.java index 145796578..4ef85cb7d 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/cli/HttpieRequestSnippetTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/cli/HttpieRequestSnippetTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2019 the original author or authors. + * Copyright 2014-2020 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. @@ -330,4 +330,20 @@ public void postWithContentAndParameters() throws IOException { .withContent("$ echo 'Some content' | http POST " + "'http://localhost/foo?a=alpha&b=bravo'")); } + @Test + public void deleteWithParameters() throws IOException { + new HttpieRequestSnippet(this.commandFormatter).document(this.operationBuilder.request("http://localhost/foo") + .method("DELETE").param("a", "alpha").param("b", "bravo").build()); + assertThat(this.generatedSnippets.httpieRequest()) + .is(codeBlock("bash").withContent("$ http DELETE 'http://localhost/foo?a=alpha&b=bravo'")); + } + + @Test + public void deleteWithQueryString() throws IOException { + new HttpieRequestSnippet(this.commandFormatter).document( + this.operationBuilder.request("http://localhost/foo?a=alpha&b=bravo").method("DELETE").build()); + assertThat(this.generatedSnippets.httpieRequest()) + .is(codeBlock("bash").withContent("$ http DELETE 'http://localhost/foo?a=alpha&b=bravo'")); + } + } diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/http/HttpRequestSnippetTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/http/HttpRequestSnippetTests.java index 5ac9889d7..ae9ef1a4b 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/http/HttpRequestSnippetTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/http/HttpRequestSnippetTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2019 the original author or authors. + * Copyright 2014-2020 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. @@ -307,6 +307,22 @@ public void requestWithCustomSnippetAttributes() throws IOException { assertThat(this.generatedSnippets.httpRequest()).contains("Title for the request"); } + @Test + public void deleteWithParameters() throws IOException { + new HttpRequestSnippet().document(this.operationBuilder.request("http://localhost/foo").method("DELETE") + .param("a", "alpha").param("b", "bravo").build()); + assertThat(this.generatedSnippets.httpRequest()) + .is(httpRequest(RequestMethod.DELETE, "/foo?a=alpha&b=bravo").header("Host", "localhost")); + } + + @Test + public void deleteWithQueryString() throws IOException { + new HttpRequestSnippet().document( + this.operationBuilder.request("http://localhost/foo?a=alpha&b=bravo").method("DELETE").build()); + assertThat(this.generatedSnippets.httpRequest()) + .is(httpRequest(RequestMethod.DELETE, "/foo?a=alpha&b=bravo").header("Host", "localhost")); + } + private String createPart(String content) { return this.createPart(content, true); } From a9c4732a83f9faf24a9910ccca58f5c48d36a1b7 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Mon, 8 Jun 2020 16:40:48 +0100 Subject: [PATCH 098/502] Update javadoc to be Java 11 compatible Closes gh-687 --- build.gradle | 1 + .../restdocs/payload/PayloadDocumentation.java | 6 ++++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index 9bc4ef060..99acdaa1f 100644 --- a/build.gradle +++ b/build.gradle @@ -155,6 +155,7 @@ configure(publishedCodeProjects) { subproject -> options.links = javadocLinks options.addStringOption '-quiet' options.encoding = 'UTF-8' + options.source = '1.8' } task sourcesJar(type: Jar) { diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/PayloadDocumentation.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/PayloadDocumentation.java index 205f2584f..80e53736a 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/PayloadDocumentation.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/PayloadDocumentation.java @@ -68,7 +68,8 @@ private PayloadDocumentation() { * * The following paths are all present: * - *
+ *
+ * * * * @@ -132,7 +133,8 @@ public static FieldDescriptor fieldWithPath(String path) { * * The following paths are all present: * - *
Paths that are present and their values
PathValue
+ *
+ * * * * From 7a1a9897655be107a47248e54536aae0513ad911 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Mon, 13 Jul 2020 10:53:28 +0100 Subject: [PATCH 099/502] Expand and update REST Assured compatibility testing Closes gh-688 --- spring-restdocs-restassured/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-restdocs-restassured/build.gradle b/spring-restdocs-restassured/build.gradle index 0f372e7db..27008ecbc 100644 --- a/spring-restdocs-restassured/build.gradle +++ b/spring-restdocs-restassured/build.gradle @@ -18,6 +18,6 @@ test { matrixTest { restAssured { group = 'io.rest-assured' - versions = ['4.0.0', '4.1.1'] + versions = ['4.0.0', '4.1.2', '4.2.0', '4.3.1'] } } \ No newline at end of file From 323cec45271873f70d65dbf1d63039084ec8aab0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=20Schr=C3=B6er?= <16744580+m-schroeer@users.noreply.github.com> Date: Tue, 18 Aug 2020 14:10:00 +0200 Subject: [PATCH 100/502] Fix descries -> describes typo in the reference docs See gh-690 --- docs/src/docs/asciidoc/documenting-your-api.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/docs/asciidoc/documenting-your-api.adoc b/docs/src/docs/asciidoc/documenting-your-api.adoc index cc5dfa92f..665dd35d1 100644 --- a/docs/src/docs/asciidoc/documenting-your-api.adoc +++ b/docs/src/docs/asciidoc/documenting-your-api.adoc @@ -270,7 +270,7 @@ be compatible with `application/xml`. [[documenting-your-api-request-response-payloads-fields-json]] ===== Fields in JSON Payloads -This section descries how to work with fields in JSON payloads. +This section describes how to work with fields in JSON payloads. [[documenting-your-api-request-response-payloads-fields-json-field-paths]] ====== JSON Field Paths From 9162888f1bf9481b5a354b0e61fe79742c69fba7 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Tue, 1 Sep 2020 13:22:54 +0100 Subject: [PATCH 101/502] Read snippet templates as UTF-8 by default Fixes gh-585 --- .../config/RestDocumentationConfigurer.java | 6 +- .../mustache/MustacheTemplateEngine.java | 65 +++++++++++++++++-- .../RestDocumentationConfigurerTests.java | 12 +++- 3 files changed, 72 insertions(+), 11 deletions(-) diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/config/RestDocumentationConfigurer.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/config/RestDocumentationConfigurer.java index b2ab8316f..67147fc93 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/config/RestDocumentationConfigurer.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/config/RestDocumentationConfigurer.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2019 the original author or authors. + * Copyright 2014-2020 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. @@ -16,6 +16,7 @@ package org.springframework.restdocs.config; +import java.nio.charset.Charset; import java.util.Arrays; import java.util.HashMap; import java.util.List; @@ -116,7 +117,8 @@ public void apply(Map configuration, RestDocumentationContext co } engineToUse = new MustacheTemplateEngine( new StandardTemplateResourceResolver(snippetConfiguration.getTemplateFormat()), - Mustache.compiler().escapeHTML(false), templateContext); + Charset.forName(snippetConfiguration.getEncoding()), Mustache.compiler().escapeHTML(false), + templateContext); } configuration.put(TemplateEngine.class.getName(), engineToUse); } diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/templates/mustache/MustacheTemplateEngine.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/templates/mustache/MustacheTemplateEngine.java index 2820731e8..584c871a5 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/templates/mustache/MustacheTemplateEngine.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/templates/mustache/MustacheTemplateEngine.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2019 the original author or authors. + * Copyright 2014-2020 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. @@ -18,6 +18,8 @@ import java.io.IOException; import java.io.InputStreamReader; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; import java.util.Collections; import java.util.Map; @@ -40,23 +42,38 @@ public class MustacheTemplateEngine implements TemplateEngine { private final TemplateResourceResolver templateResourceResolver; + private final Charset templateEncoding; + private final Compiler compiler; private final Map context; /** * Creates a new {@code MustacheTemplateEngine} that will use the given - * {@code templateResourceResolver} to resolve template paths. + * {@code templateResourceResolver} to resolve template paths. Templates will be read + * as UTF-8. * @param templateResourceResolver the resolver to use */ public MustacheTemplateEngine(TemplateResourceResolver templateResourceResolver) { this(templateResourceResolver, Mustache.compiler().escapeHTML(false)); } + /** + * Creates a new {@code MustacheTemplateEngine} that will use the given + * {@code templateResourceResolver} to resolve template paths, reading them using the + * given {@code templateEncoding}. + * @param templateResourceResolver the resolver to use + * @param templateEncoding the charset to use when reading the templates + * @since 2.0.5 + */ + public MustacheTemplateEngine(TemplateResourceResolver templateResourceResolver, Charset templateEncoding) { + this(templateResourceResolver, templateEncoding, Mustache.compiler().escapeHTML(false)); + } + /** * Creates a new {@code MustacheTemplateEngine} that will use the given * {@code templateResourceResolver} to resolve templates and the given - * {@code compiler} to compile them. + * {@code compiler} to compile them. Templates will be read as UTF-8. * @param templateResourceResolver the resolver to use * @param compiler the compiler to use */ @@ -67,8 +84,23 @@ public MustacheTemplateEngine(TemplateResourceResolver templateResourceResolver, /** * Creates a new {@code MustacheTemplateEngine} that will use the given * {@code templateResourceResolver} to resolve templates and the given - * {@code compiler} to compile them. Compiled templates will be created with the given - * {@code context}. + * {@code compiler} to compile them. Templates will be read using the given + * {@code templateEncoding}. + * @param templateResourceResolver the resolver to use + * @param templateEncoding the charset to use when reading the templates + * @param compiler the compiler to use + * @since 2.0.5 + */ + public MustacheTemplateEngine(TemplateResourceResolver templateResourceResolver, Charset templateEncoding, + Compiler compiler) { + this(templateResourceResolver, templateEncoding, compiler, Collections.emptyMap()); + } + + /** + * Creates a new {@code MustacheTemplateEngine} that will use the given + * {@code templateResourceResolver} to resolve templates. Templates will be read as + * UTF-8. Once read, the given {@code compiler} will be used to compile them. Compiled + * templates will be created with the given {@code context}. * @param templateResourceResolver the resolver to use * @param compiler the compiler to use * @param context the context to pass to compiled templates @@ -77,7 +109,27 @@ public MustacheTemplateEngine(TemplateResourceResolver templateResourceResolver, */ public MustacheTemplateEngine(TemplateResourceResolver templateResourceResolver, Compiler compiler, Map context) { + this(templateResourceResolver, StandardCharsets.UTF_8, compiler, context); + } + + /** + * Creates a new {@code MustacheTemplateEngine} that will use the given + * {@code templateResourceResolver} to resolve templates. Template will be read using + * the given {@code templateEncoding}. Once read, the given {@code compiler} will be + * used to compile them. Compiled templates will be created with the given + * {@code context}. + * @param templateResourceResolver the resolver to use + * @param templateEncoding the charset to use when reading the templates + * @param compiler the compiler to use + * @param context the context to pass to compiled templates + * @since 2.0.5 + * @see MustacheTemplate#MustacheTemplate(org.springframework.restdocs.mustache.Template, + * Map) + */ + public MustacheTemplateEngine(TemplateResourceResolver templateResourceResolver, Charset templateEncoding, + Compiler compiler, Map context) { this.templateResourceResolver = templateResourceResolver; + this.templateEncoding = templateEncoding; this.compiler = compiler; this.context = context; } @@ -85,7 +137,8 @@ public MustacheTemplateEngine(TemplateResourceResolver templateResourceResolver, @Override public Template compileTemplate(String name) throws IOException { Resource templateResource = this.templateResourceResolver.resolveTemplateResource(name); - return new MustacheTemplate(this.compiler.compile(new InputStreamReader(templateResource.getInputStream())), + return new MustacheTemplate( + this.compiler.compile(new InputStreamReader(templateResource.getInputStream(), this.templateEncoding)), this.context); } 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 c8ade9271..f5f0e7087 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 @@ -1,5 +1,5 @@ /* - * Copyright 2014-2019 the original author or authors. + * Copyright 2014-2020 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. @@ -17,6 +17,7 @@ package org.springframework.restdocs.config; import java.net.URI; +import java.nio.charset.StandardCharsets; import java.util.Collections; import java.util.HashMap; import java.util.List; @@ -73,6 +74,8 @@ public void defaultConfiguration() { this.configurer.apply(configuration, createContext()); assertThat(configuration).containsKey(TemplateEngine.class.getName()); assertThat(configuration.get(TemplateEngine.class.getName())).isInstanceOf(MustacheTemplateEngine.class); + assertThat(configuration.get(TemplateEngine.class.getName())).hasFieldOrPropertyWithValue("templateEncoding", + StandardCharsets.UTF_8); assertThat(configuration).containsKey(WriterResolver.class.getName()); assertThat(configuration.get(WriterResolver.class.getName())).isInstanceOf(StandardWriterResolver.class); assertThat(configuration).containsKey(RestDocumentationGenerator.ATTRIBUTE_NAME_DEFAULT_SNIPPETS); @@ -147,12 +150,15 @@ public void additionalDefaultSnippets() { @Test public void customSnippetEncoding() { Map configuration = new HashMap<>(); - this.configurer.snippets().withEncoding("ISO 8859-1").apply(configuration, createContext()); + this.configurer.snippets().withEncoding("ISO-8859-1"); + this.configurer.apply(configuration, createContext()); assertThat(configuration).containsKey(SnippetConfiguration.class.getName()); assertThat(configuration.get(SnippetConfiguration.class.getName())).isInstanceOf(SnippetConfiguration.class); SnippetConfiguration snippetConfiguration = (SnippetConfiguration) configuration .get(SnippetConfiguration.class.getName()); - assertThat(snippetConfiguration.getEncoding()).isEqualTo("ISO 8859-1"); + assertThat(snippetConfiguration.getEncoding()).isEqualTo(StandardCharsets.ISO_8859_1.displayName()); + assertThat(configuration.get(TemplateEngine.class.getName())).hasFieldOrPropertyWithValue("templateEncoding", + StandardCharsets.ISO_8859_1); } @Test From b02fcbee6a0af1eea022f6c4ecd804faba10a658 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Tue, 1 Sep 2020 13:37:13 +0100 Subject: [PATCH 102/502] Default to UTF-8 when reading operation content as a string Fixes gh-689 --- .../restdocs/operation/AbstractOperationMessage.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/AbstractOperationMessage.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/AbstractOperationMessage.java index 7019cd750..038831d20 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/AbstractOperationMessage.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/AbstractOperationMessage.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2019 the original author or authors. + * Copyright 2014-2020 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. @@ -17,6 +17,7 @@ package org.springframework.restdocs.operation; import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; import java.util.Arrays; import org.springframework.http.HttpHeaders; @@ -52,7 +53,10 @@ public HttpHeaders getHeaders() { public String getContentAsString() { if (this.content.length > 0) { Charset charset = extractCharsetFromContentTypeHeader(); - return (charset != null) ? new String(this.content, charset) : new String(this.content); + if (charset == null) { + charset = StandardCharsets.UTF_8; + } + return new String(this.content, charset); } return ""; } From eac7d67c4e6d78a09bd1b4b24ff370eb1b560001 Mon Sep 17 00:00:00 2001 From: Brice Dutheil Date: Mon, 30 Mar 2020 18:24:18 +0200 Subject: [PATCH 103/502] Propagate ignoreUndocumentedParamteres with .and() See gh-676 --- .../restdocs/request/AbstractParametersSnippet.java | 4 ++++ .../restdocs/request/RequestParametersSnippet.java | 2 +- .../restdocs/request/RequestParametersSnippetTests.java | 9 +++++++++ 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/request/AbstractParametersSnippet.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/request/AbstractParametersSnippet.java index 3be05028d..dd590be22 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/request/AbstractParametersSnippet.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/request/AbstractParametersSnippet.java @@ -148,6 +148,10 @@ protected final Map getParameterDescriptors() { return this.descriptorsByName; } + protected final boolean isIgnoreUndocumentedParameters() { + return ignoreUndocumentedParameters; + } + /** * Returns a model for the given {@code descriptor}. * @param descriptor the descriptor diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/request/RequestParametersSnippet.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/request/RequestParametersSnippet.java index 790a71092..5af9abee1 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/request/RequestParametersSnippet.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/request/RequestParametersSnippet.java @@ -133,7 +133,7 @@ public RequestParametersSnippet and(ParameterDescriptor... additionalDescriptors public RequestParametersSnippet and(List additionalDescriptors) { List combinedDescriptors = new ArrayList<>(getParameterDescriptors().values()); combinedDescriptors.addAll(additionalDescriptors); - return new RequestParametersSnippet(combinedDescriptors, this.getAttributes()); + return new RequestParametersSnippet(combinedDescriptors, this.getAttributes(), this.isIgnoreUndocumentedParameters()); } } diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/request/RequestParametersSnippetTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/request/RequestParametersSnippetTests.java index 85fb1c235..19a47c654 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/request/RequestParametersSnippetTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/request/RequestParametersSnippetTests.java @@ -153,6 +153,15 @@ public void additionalDescriptors() throws IOException { .is(tableWithHeader("Parameter", "Description").row("`a`", "one").row("`b`", "two")); } + @Test + public void additionalDescriptorsWithRelaxedRequestParameters() throws IOException { + RequestDocumentation.relaxedRequestParameters(parameterWithName("a").description("one")) + .and(parameterWithName("b").description("two")).document(this.operationBuilder + .request("http://localhost").param("a", "bravo").param("b", "bravo").param("c", "undocumented").build()); + assertThat(this.generatedSnippets.requestParameters()) + .is(tableWithHeader("Parameter", "Description").row("`a`", "one").row("`b`", "two")); + } + @Test public void requestParametersWithEscapedContent() throws IOException { RequestDocumentation.requestParameters(parameterWithName("Foo|Bar").description("one|two")) From ffe4c93c3862df712dde666c04be64faaf041bc8 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Tue, 1 Sep 2020 13:54:39 +0100 Subject: [PATCH 104/502] Polish "Propagate ignoreUndocumentedParamteres with .and()" See gh-676 --- .../restdocs/request/AbstractParametersSnippet.java | 10 ++++++++-- .../restdocs/request/PathParametersSnippet.java | 4 ++-- .../restdocs/request/RequestParametersSnippet.java | 5 +++-- .../restdocs/request/PathParametersSnippetTests.java | 12 +++++++++++- .../request/RequestParametersSnippetTests.java | 7 ++++--- 5 files changed, 28 insertions(+), 10 deletions(-) diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/request/AbstractParametersSnippet.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/request/AbstractParametersSnippet.java index dd590be22..523d65c81 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/request/AbstractParametersSnippet.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/request/AbstractParametersSnippet.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2019 the original author or authors. + * Copyright 2014-2020 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. @@ -148,8 +148,14 @@ protected final Map getParameterDescriptors() { return this.descriptorsByName; } + /** + * Returns whether to ignore undocumented parameters. + * @return {@code true} if undocumented parameters should be ignored, otherwise + * {@code false} + * @since 2.0.5 + */ protected final boolean isIgnoreUndocumentedParameters() { - return ignoreUndocumentedParameters; + return this.ignoreUndocumentedParameters; } /** diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/request/PathParametersSnippet.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/request/PathParametersSnippet.java index 91acf47bb..6b4f4f329 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/request/PathParametersSnippet.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/request/PathParametersSnippet.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2019 the original author or authors. + * Copyright 2014-2020 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. @@ -170,7 +170,7 @@ public final PathParametersSnippet and(ParameterDescriptor... additionalDescript public final PathParametersSnippet and(List additionalDescriptors) { List combinedDescriptors = new ArrayList<>(getParameterDescriptors().values()); combinedDescriptors.addAll(additionalDescriptors); - return new PathParametersSnippet(combinedDescriptors, this.getAttributes()); + return new PathParametersSnippet(combinedDescriptors, this.getAttributes(), isIgnoreUndocumentedParameters()); } } diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/request/RequestParametersSnippet.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/request/RequestParametersSnippet.java index 5af9abee1..b1a1afc14 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/request/RequestParametersSnippet.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/request/RequestParametersSnippet.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2019 the original author or authors. + * Copyright 2014-2020 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. @@ -133,7 +133,8 @@ public RequestParametersSnippet and(ParameterDescriptor... additionalDescriptors public RequestParametersSnippet and(List additionalDescriptors) { List combinedDescriptors = new ArrayList<>(getParameterDescriptors().values()); combinedDescriptors.addAll(additionalDescriptors); - return new RequestParametersSnippet(combinedDescriptors, this.getAttributes(), this.isIgnoreUndocumentedParameters()); + return new RequestParametersSnippet(combinedDescriptors, this.getAttributes(), + this.isIgnoreUndocumentedParameters()); } } diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/request/PathParametersSnippetTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/request/PathParametersSnippetTests.java index 2f4b5bdc5..bb455ae93 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/request/PathParametersSnippetTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/request/PathParametersSnippetTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2019 the original author or authors. + * Copyright 2014-2020 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. @@ -159,6 +159,16 @@ public void additionalDescriptors() throws IOException { tableWithTitleAndHeader(getTitle(), "Parameter", "Description").row("`a`", "one").row("`b`", "two")); } + @Test + public void additionalDescriptorsWithRelaxedRequestParameters() throws IOException { + RequestDocumentation.relaxedPathParameters(parameterWithName("a").description("one")) + .and(parameterWithName("b").description("two")).document(this.operationBuilder + .attribute(RestDocumentationGenerator.ATTRIBUTE_NAME_URL_TEMPLATE, "/{a}/{b}/{c}").build()); + assertThat(this.generatedSnippets.pathParameters()) + .is(tableWithTitleAndHeader(getTitle("/{a}/{b}/{c}"), "Parameter", "Description").row("`a`", "one") + .row("`b`", "two")); + } + @Test public void pathParametersWithEscapedContent() throws IOException { RequestDocumentation.pathParameters(parameterWithName("Foo|Bar").description("one|two")) diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/request/RequestParametersSnippetTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/request/RequestParametersSnippetTests.java index 19a47c654..92857a27b 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/request/RequestParametersSnippetTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/request/RequestParametersSnippetTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2019 the original author or authors. + * Copyright 2014-2020 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. @@ -156,8 +156,9 @@ public void additionalDescriptors() throws IOException { @Test public void additionalDescriptorsWithRelaxedRequestParameters() throws IOException { RequestDocumentation.relaxedRequestParameters(parameterWithName("a").description("one")) - .and(parameterWithName("b").description("two")).document(this.operationBuilder - .request("http://localhost").param("a", "bravo").param("b", "bravo").param("c", "undocumented").build()); + .and(parameterWithName("b").description("two")) + .document(this.operationBuilder.request("http://localhost").param("a", "bravo").param("b", "bravo") + .param("c", "undocumented").build()); assertThat(this.generatedSnippets.requestParameters()) .is(tableWithHeader("Parameter", "Description").row("`a`", "one").row("`b`", "two")); } From baaf4f2e0504890f798d0b23c9eec6d90dbe49ee Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Tue, 1 Sep 2020 15:30:11 +0100 Subject: [PATCH 105/502] Update query string when modifying GET request's parameters Fixes gh-682 --- .../operation/OperationRequestFactory.java | 25 +++++-- ...rsModifyingOperationPreprocessorTests.java | 72 +++++++++++++------ 2 files changed, 71 insertions(+), 26 deletions(-) diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/OperationRequestFactory.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/OperationRequestFactory.java index c8ce358e4..69eb7c2af 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/OperationRequestFactory.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/OperationRequestFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2019 the original author or authors. + * Copyright 2014-2020 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. @@ -17,6 +17,7 @@ package org.springframework.restdocs.operation; import java.net.URI; +import java.net.URISyntaxException; import java.util.Collection; import java.util.Collections; @@ -94,14 +95,28 @@ public OperationRequest createFrom(OperationRequest original, HttpHeaders newHea /** * Creates a new {@code OperationRequest} based on the given {@code original} but with - * the given {@code newParameters}. + * the given {@code newParameters} applied. The query string of a {@code GET} request + * will be updated to reflect the new parameters. * @param original the original request * @param newParameters the new parameters - * @return the new request with the new parameters + * @return the new request with the parameters applied */ public OperationRequest createFrom(OperationRequest original, Parameters newParameters) { - return new StandardOperationRequest(original.getUri(), original.getMethod(), original.getContent(), - original.getHeaders(), newParameters, original.getParts(), original.getCookies()); + URI uri = (original.getMethod() == HttpMethod.GET) ? updateQueryString(original.getUri(), newParameters) + : original.getUri(); + return new StandardOperationRequest(uri, original.getMethod(), original.getContent(), original.getHeaders(), + newParameters, original.getParts(), original.getCookies()); + } + + private URI updateQueryString(URI originalUri, Parameters parameters) { + try { + return new URI(originalUri.getScheme(), originalUri.getUserInfo(), originalUri.getHost(), + originalUri.getPort(), originalUri.getPath(), + parameters.isEmpty() ? null : parameters.toQueryString(), originalUri.getFragment()); + } + catch (URISyntaxException ex) { + throw new RuntimeException(ex); + } } private HttpHeaders augmentHeaders(HttpHeaders originalHeaders, URI uri, byte[] content) { diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/operation/preprocess/ParametersModifyingOperationPreprocessorTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/operation/preprocess/ParametersModifyingOperationPreprocessorTests.java index 5f6dc268f..3331102cf 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/operation/preprocess/ParametersModifyingOperationPreprocessorTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/operation/preprocess/ParametersModifyingOperationPreprocessorTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2019 the original author or authors. + * Copyright 2014-2020 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. @@ -43,53 +43,62 @@ public class ParametersModifyingOperationPreprocessorTests { @Test public void addNewParameter() { Parameters parameters = new Parameters(); - assertThat(this.preprocessor.add("a", "alpha").preprocess(createRequest(parameters)).getParameters()) - .containsEntry("a", Arrays.asList("alpha")); + OperationRequest request = this.preprocessor.add("a", "alpha").preprocess(createGetRequest(parameters)); + assertThat(request.getParameters()).containsEntry("a", Arrays.asList("alpha")); + assertThat(request.getUri()).isEqualTo(URI.create("http://localhost:8080?a=alpha")); } @Test public void addValueToExistingParameter() { Parameters parameters = new Parameters(); parameters.add("a", "apple"); - assertThat(this.preprocessor.add("a", "alpha").preprocess(createRequest(parameters)).getParameters()) - .containsEntry("a", Arrays.asList("apple", "alpha")); + OperationRequest request = this.preprocessor.add("a", "alpha").preprocess(createGetRequest(parameters)); + assertThat(request.getParameters()).containsEntry("a", Arrays.asList("apple", "alpha")); + assertThat(request.getUri()).isEqualTo(URI.create("http://localhost:8080?a=apple&a=alpha")); } @Test public void setNewParameter() { Parameters parameters = new Parameters(); - assertThat(this.preprocessor.set("a", "alpha", "avocado").preprocess(createRequest(parameters)).getParameters()) - .containsEntry("a", Arrays.asList("alpha", "avocado")); + OperationRequest request = this.preprocessor.set("a", "alpha", "avocado") + .preprocess(createGetRequest(parameters)); + assertThat(request.getParameters()).containsEntry("a", Arrays.asList("alpha", "avocado")); + assertThat(request.getUri()).isEqualTo(URI.create("http://localhost:8080?a=alpha&a=avocado")); } @Test public void setExistingParameter() { Parameters parameters = new Parameters(); parameters.add("a", "apple"); - assertThat(this.preprocessor.set("a", "alpha", "avocado").preprocess(createRequest(parameters)).getParameters()) - .containsEntry("a", Arrays.asList("alpha", "avocado")); + OperationRequest request = this.preprocessor.set("a", "alpha", "avocado") + .preprocess(createGetRequest(parameters)); + assertThat(request.getParameters()).containsEntry("a", Arrays.asList("alpha", "avocado")); + assertThat(request.getUri()).isEqualTo(URI.create("http://localhost:8080?a=alpha&a=avocado")); } @Test public void removeNonExistentParameter() { Parameters parameters = new Parameters(); - assertThat(this.preprocessor.remove("a").preprocess(createRequest(parameters)).getParameters().size()) - .isEqualTo(0); + OperationRequest request = this.preprocessor.remove("a").preprocess(createGetRequest(parameters)); + assertThat(request.getParameters().size()).isEqualTo(0); + assertThat(request.getUri()).isEqualTo(URI.create("http://localhost:8080")); } @Test public void removeParameter() { Parameters parameters = new Parameters(); parameters.add("a", "apple"); - assertThat(this.preprocessor.set("a", "alpha", "avocado").preprocess(createRequest(parameters)).getParameters()) - .containsEntry("a", Arrays.asList("alpha", "avocado")); + OperationRequest request = this.preprocessor.remove("a").preprocess(createGetRequest(parameters)); + assertThat(request.getParameters()).isEmpty(); + assertThat(request.getUri()).isEqualTo(URI.create("http://localhost:8080")); } @Test public void removeParameterValueForNonExistentParameter() { Parameters parameters = new Parameters(); - assertThat(this.preprocessor.remove("a", "apple").preprocess(createRequest(parameters)).getParameters().size()) - .isEqualTo(0); + OperationRequest request = this.preprocessor.remove("a", "apple").preprocess(createGetRequest(parameters)); + assertThat(request.getParameters()).isEmpty(); + assertThat(request.getUri()).isEqualTo(URI.create("http://localhost:8080")); } @Test @@ -97,20 +106,41 @@ public void removeParameterValueWithMultipleValues() { Parameters parameters = new Parameters(); parameters.add("a", "apple"); parameters.add("a", "alpha"); - assertThat(this.preprocessor.remove("a", "apple").preprocess(createRequest(parameters)).getParameters()) - .containsEntry("a", Arrays.asList("alpha")); + parameters.add("b", "bravo"); + OperationRequest request = this.preprocessor.remove("a", "apple").preprocess(createGetRequest(parameters)); + assertThat(request.getParameters()).containsEntry("a", Arrays.asList("alpha")); + assertThat(request.getUri()).isEqualTo(URI.create("http://localhost:8080?a=alpha&b=bravo")); } @Test public void removeParameterValueWithSingleValueRemovesEntryEntirely() { Parameters parameters = new Parameters(); parameters.add("a", "apple"); - assertThat(this.preprocessor.remove("a", "apple").preprocess(createRequest(parameters)).getParameters().size()) - .isEqualTo(0); + parameters.add("b", "bravo"); + OperationRequest request = this.preprocessor.remove("a", "apple").preprocess(createGetRequest(parameters)); + assertThat(request.getParameters()).doesNotContainKey("a"); + assertThat(request.getUri()).isEqualTo(URI.create("http://localhost:8080?b=bravo")); } - private OperationRequest createRequest(Parameters parameters) { - return new OperationRequestFactory().create(URI.create("http://localhost:8080"), HttpMethod.GET, new byte[0], + @Test + public void whenParametersOfANonGetRequestAreModifiedThenTheQueryStringIsUnaffected() { + Parameters parameters = new Parameters(); + parameters.add("a", "apple"); + parameters.add("b", "bravo"); + OperationRequest request = this.preprocessor.remove("a", "apple").preprocess(createPostRequest(parameters)); + assertThat(request.getParameters()).doesNotContainKey("a"); + assertThat(request.getUri()).isEqualTo(URI.create("http://localhost:8080")); + } + + private OperationRequest createGetRequest(Parameters parameters) { + return new OperationRequestFactory().create( + URI.create("http://localhost:8080" + (parameters.isEmpty() ? "" : "?" + parameters.toQueryString())), + HttpMethod.GET, new byte[0], new HttpHeaders(), parameters, + Collections.emptyList()); + } + + private OperationRequest createPostRequest(Parameters parameters) { + return new OperationRequestFactory().create(URI.create("http://localhost:8080"), HttpMethod.POST, new byte[0], new HttpHeaders(), parameters, Collections.emptyList()); } From 536e87acc9f684fac405a7b19f19cf9a4d630741 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Tue, 1 Sep 2020 16:28:03 +0100 Subject: [PATCH 106/502] Fix kebab and snake case formatting of all upper case words Closes gh-658 --- ...cumentationContextPlaceholderResolver.java | 23 ++++++----- ...tationContextPlaceholderResolverTests.java | 38 ++++++++++++++++++- 2 files changed, 48 insertions(+), 13 deletions(-) diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/snippet/RestDocumentationContextPlaceholderResolver.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/snippet/RestDocumentationContextPlaceholderResolver.java index 11bf86778..df8a743b1 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/snippet/RestDocumentationContextPlaceholderResolver.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/snippet/RestDocumentationContextPlaceholderResolver.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2019 the original author or authors. + * Copyright 2014-2020 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. @@ -16,9 +16,6 @@ package org.springframework.restdocs.snippet; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - import org.springframework.restdocs.RestDocumentationContext; import org.springframework.util.PropertyPlaceholderHelper.PlaceholderResolver; @@ -51,8 +48,6 @@ */ public class RestDocumentationContextPlaceholderResolver implements PlaceholderResolver { - private static final Pattern CAMEL_CASE_PATTERN = Pattern.compile("([A-Z])"); - private final RestDocumentationContext context; /** @@ -130,14 +125,18 @@ protected final RestDocumentationContext getContext() { } private String camelCaseToSeparator(String string, String separator) { - Matcher matcher = CAMEL_CASE_PATTERN.matcher(string); StringBuffer result = new StringBuffer(); - while (matcher.find()) { - String replacement = (matcher.start() > 0) ? separator + matcher.group(1).toLowerCase() - : matcher.group(1).toLowerCase(); - matcher.appendReplacement(result, replacement); + char[] chars = string.toCharArray(); + for (int i = 0; i < chars.length; i++) { + char current = chars[i]; + if (Character.isUpperCase(current) && i > 0) { + if (Character.isLowerCase(chars[i - 1]) + || (i < chars.length - 1 && Character.isLowerCase(chars[i + 1]))) { + result.append(separator); + } + } + result.append(Character.toLowerCase(chars[i])); } - matcher.appendTail(result); return result.toString(); } 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 23c2bd94d..d9f8ac266 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 @@ -1,5 +1,5 @@ /* - * Copyright 2014-2019 the original author or authors. + * Copyright 2014-2020 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. @@ -38,12 +38,48 @@ public void kebabCaseMethodName() throws Exception { .isEqualTo("dash-separated-method-name"); } + @Test + public void kebabCaseMethodNameWithUpperCaseOpeningSection() throws Exception { + assertThat(createResolver("URIDashSeparatedMethodName").resolvePlaceholder("method-name")) + .isEqualTo("uri-dash-separated-method-name"); + } + + @Test + public void kebabCaseMethodNameWithUpperCaseMidSection() throws Exception { + assertThat(createResolver("dashSeparatedMethodNameWithURIInIt").resolvePlaceholder("method-name")) + .isEqualTo("dash-separated-method-name-with-uri-in-it"); + } + + @Test + public void kebabCaseMethodNameWithUpperCaseEndSection() throws Exception { + assertThat(createResolver("dashSeparatedMethodNameWithURI").resolvePlaceholder("method-name")) + .isEqualTo("dash-separated-method-name-with-uri"); + } + @Test public void snakeCaseMethodName() throws Exception { assertThat(createResolver("underscoreSeparatedMethodName").resolvePlaceholder("method_name")) .isEqualTo("underscore_separated_method_name"); } + @Test + public void snakeCaseMethodNameWithUpperCaseOpeningSection() throws Exception { + assertThat(createResolver("URIUnderscoreSeparatedMethodName").resolvePlaceholder("method_name")) + .isEqualTo("uri_underscore_separated_method_name"); + } + + @Test + public void snakeCaseMethodNameWithUpperCaseMidSection() throws Exception { + assertThat(createResolver("underscoreSeparatedMethodNameWithURIInIt").resolvePlaceholder("method_name")) + .isEqualTo("underscore_separated_method_name_with_uri_in_it"); + } + + @Test + public void snakeCaseMethodNameWithUpperCaseEndSection() throws Exception { + assertThat(createResolver("underscoreSeparatedMethodNameWithURI").resolvePlaceholder("method_name")) + .isEqualTo("underscore_separated_method_name_with_uri"); + } + @Test public void camelCaseMethodName() throws Exception { assertThat(createResolver("camelCaseMethodName").resolvePlaceholder("methodName")) From 9fa94022d26d192f87271745765eac345d32c898 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 2 Sep 2020 10:56:05 +0100 Subject: [PATCH 107/502] Upgrade Slate sample to Slate 2.7.1 Closes gh-693 --- samples/rest-notes-slate/slate/.gitignore | 3 + samples/rest-notes-slate/slate/CHANGELOG.md | 149 +- samples/rest-notes-slate/slate/Dockerfile | 20 + samples/rest-notes-slate/slate/Gemfile | 15 +- samples/rest-notes-slate/slate/Gemfile.lock | 119 +- samples/rest-notes-slate/slate/LICENSE | 208 +- samples/rest-notes-slate/slate/README.md | 111 - samples/rest-notes-slate/slate/Vagrantfile | 15 +- samples/rest-notes-slate/slate/config.rb | 23 +- samples/rest-notes-slate/slate/deploy.sh | 37 +- .../slate/lib/monokai_sublime_slate.rb | 95 + .../rest-notes-slate/slate/lib/multilang.rb | 12 +- .../slate/lib/nesting_unique_head.rb | 22 + .../rest-notes-slate/slate/lib/toc_data.rb | 31 + .../rest-notes-slate/slate/lib/unique_head.rb | 24 + .../slate/source/fonts/slate.eot | Bin .../slate/source/fonts/slate.svg | 2 +- .../slate/source/fonts/slate.ttf | Bin .../slate/source/fonts/slate.woff | Bin .../slate/source/fonts/slate.woff2 | Bin .../slate/source/includes/_errors.md | 20 +- .../slate/source/index.html.md | 70 +- .../slate/source/javascripts/all.js | 4 +- .../slate/source/javascripts/all_nosearch.js | 26 +- .../slate/source/javascripts/app/_copy.js | 15 + .../slate/source/javascripts/app/_lang.js | 20 +- .../slate/source/javascripts/app/_search.js | 71 +- .../slate/source/javascripts/app/_toc.js | 149 +- .../slate/source/javascripts/lib/_energize.js | 2 +- .../javascripts/lib/_imagesloaded.min.js | 4 +- .../javascripts/lib/_jquery.highlight.js | 2 +- .../slate/source/javascripts/lib/_jquery.js | 18595 ++++++++-------- .../source/javascripts/lib/_jquery.tocify.js | 1042 - .../source/javascripts/lib/_jquery_ui.js | 566 - .../slate/source/javascripts/lib/_lunr.js | 4835 ++-- .../slate/source/layouts/layout.erb | 54 +- .../slate/source/stylesheets/_rtl.scss | 140 + .../slate/source/stylesheets/_variables.scss | 30 +- .../slate/source/stylesheets/print.css.scss | 10 +- .../slate/source/stylesheets/screen.css.scss | 140 +- 40 files changed, 14260 insertions(+), 12421 deletions(-) create mode 100644 samples/rest-notes-slate/slate/Dockerfile delete mode 100644 samples/rest-notes-slate/slate/README.md create mode 100644 samples/rest-notes-slate/slate/lib/monokai_sublime_slate.rb create mode 100644 samples/rest-notes-slate/slate/lib/nesting_unique_head.rb create mode 100644 samples/rest-notes-slate/slate/lib/toc_data.rb create mode 100644 samples/rest-notes-slate/slate/lib/unique_head.rb mode change 100755 => 100644 samples/rest-notes-slate/slate/source/fonts/slate.eot mode change 100755 => 100644 samples/rest-notes-slate/slate/source/fonts/slate.svg mode change 100755 => 100644 samples/rest-notes-slate/slate/source/fonts/slate.ttf mode change 100755 => 100644 samples/rest-notes-slate/slate/source/fonts/slate.woff mode change 100755 => 100644 samples/rest-notes-slate/slate/source/fonts/slate.woff2 create mode 100644 samples/rest-notes-slate/slate/source/javascripts/app/_copy.js delete mode 100644 samples/rest-notes-slate/slate/source/javascripts/lib/_jquery.tocify.js delete mode 100644 samples/rest-notes-slate/slate/source/javascripts/lib/_jquery_ui.js create mode 100644 samples/rest-notes-slate/slate/source/stylesheets/_rtl.scss diff --git a/samples/rest-notes-slate/slate/.gitignore b/samples/rest-notes-slate/slate/.gitignore index 105015835..1d5d08dd2 100644 --- a/samples/rest-notes-slate/slate/.gitignore +++ b/samples/rest-notes-slate/slate/.gitignore @@ -22,3 +22,6 @@ build/ _yardoc doc/ .idea/ + +# Vagrant artifacts +ubuntu-*-console.log diff --git a/samples/rest-notes-slate/slate/CHANGELOG.md b/samples/rest-notes-slate/slate/CHANGELOG.md index be29842dc..30b9e1f17 100644 --- a/samples/rest-notes-slate/slate/CHANGELOG.md +++ b/samples/rest-notes-slate/slate/CHANGELOG.md @@ -1,6 +1,151 @@ # Changelog -## Version 1.5.0 +## Version 2.7.1 + +*August 13, 2020* + +* __[security]__ Bumped middleman from 4.3.7 to 4.3.8 + +_Note_: Slate uses redcarpet, not kramdown, for rendering markdown to HTML, and so was unaffected by the security vulnerability in middleman. +If you have changed slate to use kramdown, and with GFM, you may need to install the `kramdown-parser-gfm` gem. + +## Version 2.7.0 + +*June 21, 2020* + +* __[security]__ Bumped rack in Gemfile.lock from 2.2.2 to 2.2.3 +* Bumped bundled jQuery from 3.2.1 to 3.5.1 +* Bumped bundled lunr from 0.5.7 to 2.3.8 +* Bumped imagesloaded from 3.1.8 to 4.1.4 +* Bumped rouge from 3.17.0 to 3.20.0 +* Bumped redcarpet from 3.4.0 to 3.5.0 +* Fix color of highlighted code being unreadable when printing page +* Add clipboard icon for "Copy to Clipboard" functionality to code boxes (see note below) +* Fix handling of ToC selectors that contain punctutation (thanks @gruis) +* Fix language bar truncating languages that overflow screen width +* Strip HTML tags from ToC title before displaying it in title bar in JS (backup to stripping done in Ruby code) (thanks @atic) + +To enable the new clipboard icon, you need to add `code_clipboard: true` to the frontmatter of source/index.html.md. +See [this line](https://github.com/slatedocs/slate/blame/main/source/index.html.md#L19) for an example of usage. + +## Version 2.6.1 + +*May 30, 2020* + +* __[security]__ update child dependency activesupport in Gemfile.lock to 5.4.2.3 +* Update Middleman in Gemfile.lock to 4.3.7 +* Replace Travis-CI with GitHub actions for continuous integration +* Replace Spectrum with GitHub discussions + +## Version 2.6.0 + +*May 18, 2020* + +__Note__: 2.5.0 was "pulled" due to a breaking bug discovered after release. It is recommended to skip it, and move straight to 2.6.0. + +* Fix large whitespace gap in middle column for sections with codeblocks +* Fix highlighted code elements having a different background than rest of code block +* Change JSON keys to have a different font color than their values +* Disable asset hashing for woff and woff2 elements due to middleman bug breaking woff2 asset hashing in general +* Move Dockerfile to Debian from Alpine +* Converted repo to a [GitHub template](https://help.github.com/en/github/creating-cloning-and-archiving-repositories/creating-a-template-repository) +* Update sassc to 2.3.0 in Gemfile.lock + +## Version 2.5.0 + +*May 8, 2020* + +* __[security]__ update nokogiri to ~> 1.10.8 +* Update links in example docs to https://github.com/slatedocs/slate from https://github.com/lord/slate +* Update LICENSE to include full Apache 2.0 text +* Test slate against Ruby 2.5 and 2.6 on Travis-CI +* Update Vagrantfile to use Ubuntu 18.04 (thanks @bradthurber) +* Parse arguments and flags for deploy.sh on script start, instead of potentially after building source files +* Install nodejs inside Vagrantfile (thanks @fernandoaguilar) +* Add Dockerfile for running slate (thanks @redhatxl) +* update middleman-syntax and rouge to ~>3.2 +* update middleman to 4.3.6 + +## Version 2.4.0 + +*October 19, 2019* + +- Move repository from lord/slate to slatedocs/slate +- Fix documentation to point at new repo link, thanks to [Arun](https://github.com/slash-arun), [Gustavo Gawryszewski](https://github.com/gawry), and [Daniel Korbit](https://github.com/danielkorbit) +- Update `nokogiri` to 1.10.4 +- Update `ffi` in `Gemfile.lock` to fix security warnings, thanks to [Grey Baker](https://github.com/greysteil) and [jakemack](https://github.com/jakemack) +- Update `rack` to 2.0.7 in `Gemfile.lock` to fix security warnings, thanks to [Grey Baker](https://github.com/greysteil) and [jakemack](https://github.com/jakemack) +- Update middleman to `4.3` and relax constraints on middleman related gems, thanks to [jakemack](https://github.com/jakemack) +- Add sass gem, thanks to [jakemack](https://github.com/jakemack) +- Activate `asset_cache` in middleman to improve cacheability of static files, thanks to [Sam Gilman](https://github.com/thenengah) +- Update to using bundler 2 for `Gemfile.lock`, thanks to [jakemack](https://github.com/jakemack) + +## Version 2.3.1 + +*July 5, 2018* + +- Update `sprockets` in `Gemfile.lock` to fix security warnings + +## Version 2.3 + +*July 5, 2018* + +- Allows strikethrough in markdown by default. +- Upgrades jQuery to 3.2.1, thanks to [Tomi Takussaari](https://github.com/TomiTakussaari) +- Fixes invalid HTML in `layout.erb`, thanks to [Eric Scouten](https://github.com/scouten) for pointing out +- Hopefully fixes Vagrant memory issues, thanks to [Petter Blomberg](https://github.com/p-blomberg) for the suggestion +- Cleans HTML in headers before setting `document.title`, thanks to [Dan Levy](https://github.com/justsml) +- Allows trailing whitespace in markdown files, thanks to [Samuel Cousin](https://github.com/kuzyn) +- Fixes pushState/replaceState problems with scrolling not changing the document hash, thanks to [Andrey Fedorov](https://github.com/anfedorov) +- Removes some outdated examples, thanks [@al-tr](https://github.com/al-tr), [Jerome Dahdah](https://github.com/jdahdah), and [Ricardo Castro](https://github.com/mccricardo) +- Fixes `nav-padding` bug, thanks [Jerome Dahdah](https://github.com/jdahdah) +- Code style fixes thanks to [Sebastian Zaremba](https://github.com/vassyz) +- Nokogiri version bump thanks to [Grey Baker](https://github.com/greysteil) +- Fix to default `index.md` text thanks to [Nick Busey](https://github.com/NickBusey) + +Thanks to everyone who contributed to this release! + +## Version 2.2 + +*January 19, 2018* + +- Fixes bugs with some non-roman languages not generating unique headers +- Adds editorconfig, thanks to [Jay Thomas](https://github.com/jaythomas) +- Adds optional `NestingUniqueHeadCounter`, thanks to [Vladimir Morozov](https://github.com/greenhost87) +- Small fixes to typos and language, thx [Emir Ribić](https://github.com/ribice), [Gregor Martynus](https://github.com/gr2m), and [Martius](https://github.com/martiuslim)! +- Adds links to Spectrum chat for questions in README and ISSUE_TEMPLATE + +## Version 2.1 + +*October 30, 2017* + +- Right-to-left text stylesheet option, thanks to [Mohammad Hossein Rabiee](https://github.com/mhrabiee) +- Fix for HTML5 history state bug, thanks to [Zach Toolson](https://github.com/ztoolson) +- Small styling changes, typo fixes, small bug fixes from [Marian Friedmann](https://github.com/rnarian), [Ben Wilhelm](https://github.com/benwilhelm), [Fouad Matin](https://github.com/fouad), [Nicolas Bonduel](https://github.com/NicolasBonduel), [Christian Oliff](https://github.com/coliff) + +Thanks to everyone who submitted PRs for this version! + +## Version 2.0 + +*July 17, 2017* + +- All-new statically generated table of contents + - Should be much faster loading and scrolling for large pages + - Smaller Javascript file sizes + - Avoids the problem with the last link in the ToC not ever highlighting if the section was shorter than the page + - Fixes control-click not opening in a new page + - Automatically updates the HTML title as you scroll +- Updated design + - New default colors! + - New spacings and sizes! + - System-default typefaces, just like GitHub +- Added search input delay on large corpuses to reduce lag +- We even bumped the major version cause hey, why not? +- Various small bug fixes + +Thanks to everyone who helped debug or wrote code for this version! It was a serious community effort, and I couldn't have done it alone. + +## Version 1.5 *February 23, 2017* @@ -9,7 +154,7 @@ - Switch default code highlighting color scheme to better highlight JSON - Various small typo and bug fixes -## Version 1.4.0 +## Version 1.4 *November 24, 2016* diff --git a/samples/rest-notes-slate/slate/Dockerfile b/samples/rest-notes-slate/slate/Dockerfile new file mode 100644 index 000000000..33b80ca42 --- /dev/null +++ b/samples/rest-notes-slate/slate/Dockerfile @@ -0,0 +1,20 @@ +FROM ruby:2.6-slim + +WORKDIR /srv/slate + +VOLUME /srv/slate/source +EXPOSE 4567 + +COPY . /srv/slate + +RUN apt-get update \ + && apt-get install -y --no-install-recommends \ + build-essential \ + nodejs \ + && gem install bundler \ + && bundle install \ + && apt-get remove -y build-essential \ + && apt-get autoremove -y \ + && rm -rf /var/lib/apt/lists/* + +CMD ["bundle", "exec", "middleman", "server", "--watcher-force-polling"] diff --git a/samples/rest-notes-slate/slate/Gemfile b/samples/rest-notes-slate/slate/Gemfile index 1bff87424..315a86d09 100644 --- a/samples/rest-notes-slate/slate/Gemfile +++ b/samples/rest-notes-slate/slate/Gemfile @@ -1,9 +1,12 @@ +ruby '>=2.3.1' source 'https://rubygems.org' # Middleman -gem 'middleman', '~>4.2.1' -gem 'middleman-syntax', '~> 3.0.0' -gem 'middleman-autoprefixer', '~> 2.7.0' -gem "middleman-sprockets", "~> 4.1.0" -gem 'rouge', '~> 2.0.5' -gem 'redcarpet', '~> 3.4.0' +gem 'middleman', '~>4.3' +gem 'middleman-syntax', '~> 3.2' +gem 'middleman-autoprefixer', '~> 2.7' +gem 'middleman-sprockets', '~> 4.1' +gem 'rouge', '~> 3.20' +gem 'redcarpet', '~> 3.5.0' +gem 'nokogiri', '~> 1.10.8' +gem 'sass' diff --git a/samples/rest-notes-slate/slate/Gemfile.lock b/samples/rest-notes-slate/slate/Gemfile.lock index 0cdee1461..dc76f571e 100644 --- a/samples/rest-notes-slate/slate/Gemfile.lock +++ b/samples/rest-notes-slate/slate/Gemfile.lock @@ -1,60 +1,58 @@ GEM remote: https://rubygems.org/ specs: - activesupport (5.0.7) + activesupport (5.2.4.3) concurrent-ruby (~> 1.0, >= 1.0.2) i18n (>= 0.7, < 2) minitest (~> 5.1) tzinfo (~> 1.1) - addressable (2.5.2) - public_suffix (>= 2.0.2, < 4.0) - autoprefixer-rails (6.7.7.2) + addressable (2.7.0) + public_suffix (>= 2.0.2, < 5.0) + autoprefixer-rails (9.5.1.1) execjs - backports (3.11.4) + backports (3.18.1) coffee-script (2.4.1) coffee-script-source execjs coffee-script-source (1.12.2) - compass-import-once (1.0.5) - sass (>= 3.2, < 3.5) - concurrent-ruby (1.1.3) + concurrent-ruby (1.1.7) contracts (0.13.0) - dotenv (2.5.0) + dotenv (2.7.6) erubis (2.7.0) execjs (2.7.0) fast_blank (1.0.0) - fastimage (2.1.4) - ffi (1.9.25) - haml (5.0.4) + fastimage (2.2.0) + ffi (1.13.1) + haml (5.1.2) temple (>= 0.8.0) tilt hamster (3.0.0) concurrent-ruby (~> 1.0) hashie (3.6.0) - i18n (0.7.0) - kramdown (1.17.0) + i18n (0.9.5) + concurrent-ruby (~> 1.0) + kramdown (2.3.0) + rexml listen (3.0.8) rb-fsevent (~> 0.9, >= 0.9.4) rb-inotify (~> 0.9, >= 0.9.7) - memoist (0.16.0) - middleman (4.2.1) + memoist (0.16.2) + middleman (4.3.8) coffee-script (~> 2.2) - compass-import-once (= 1.0.5) haml (>= 4.0.5) - kramdown (~> 1.2) - middleman-cli (= 4.2.1) - middleman-core (= 4.2.1) - sass (>= 3.4.0, < 4.0) - middleman-autoprefixer (2.7.1) - autoprefixer-rails (>= 6.5.2, < 7.0.0) + kramdown (>= 2.3.0) + middleman-cli (= 4.3.8) + middleman-core (= 4.3.8) + middleman-autoprefixer (2.10.1) + autoprefixer-rails (~> 9.1) middleman-core (>= 3.3.3) - middleman-cli (4.2.1) + middleman-cli (4.3.8) thor (>= 0.17.0, < 2.0) - middleman-core (4.2.1) - activesupport (>= 4.2, < 5.1) + middleman-core (4.3.8) + activesupport (>= 4.2, < 6.0) addressable (~> 2.3) backports (~> 3.6) - bundler (~> 1.1) + bundler contracts (~> 0.13.0) dotenv erubis @@ -63,47 +61,57 @@ GEM fastimage (~> 2.0) hamster (~> 3.0) hashie (~> 3.4) - i18n (~> 0.7.0) + i18n (~> 0.9.0) listen (~> 3.0.0) memoist (~> 0.14) padrino-helpers (~> 0.13.0) parallel rack (>= 1.4.5, < 3) - sass (>= 3.4) + sassc (~> 2.0) servolux - tilt (~> 2.0) + tilt (~> 2.0.9) uglifier (~> 3.0) middleman-sprockets (4.1.1) middleman-core (~> 4.0) sprockets (>= 3.0) - middleman-syntax (3.0.0) + middleman-syntax (3.2.0) middleman-core (>= 3.2) - rouge (~> 2.0) - minitest (5.11.3) + rouge (~> 3.2) + mini_portile2 (2.4.0) + minitest (5.14.1) + nokogiri (1.10.9) + mini_portile2 (~> 2.4.0) padrino-helpers (0.13.3.4) i18n (~> 0.6, >= 0.6.7) padrino-support (= 0.13.3.4) tilt (>= 1.4.1, < 3) padrino-support (0.13.3.4) activesupport (>= 3.1) - parallel (1.12.1) - public_suffix (3.0.3) - rack (2.0.6) - rb-fsevent (0.10.3) - rb-inotify (0.9.10) - ffi (>= 0.5.0, < 2) - redcarpet (3.4.0) - rouge (2.0.7) - sass (3.4.25) + parallel (1.19.2) + public_suffix (4.0.5) + rack (2.2.3) + rb-fsevent (0.10.4) + rb-inotify (0.10.1) + ffi (~> 1.0) + redcarpet (3.5.0) + rexml (3.2.4) + rouge (3.20.0) + sass (3.7.4) + sass-listen (~> 4.0.0) + sass-listen (4.0.0) + rb-fsevent (~> 0.9, >= 0.9.4) + rb-inotify (~> 0.9, >= 0.9.7) + sassc (2.4.0) + ffi (~> 1.9) servolux (0.13.0) sprockets (3.7.2) concurrent-ruby (~> 1.0) rack (> 1, < 3) - temple (0.8.0) - thor (0.20.3) + temple (0.8.2) + thor (1.0.1) thread_safe (0.3.6) - tilt (2.0.8) - tzinfo (1.2.5) + tilt (2.0.10) + tzinfo (1.2.7) thread_safe (~> 0.1) uglifier (3.2.0) execjs (>= 0.3.0, < 3) @@ -112,12 +120,17 @@ PLATFORMS ruby DEPENDENCIES - middleman (~> 4.2.1) - middleman-autoprefixer (~> 2.7.0) - middleman-sprockets (~> 4.1.0) - middleman-syntax (~> 3.0.0) - redcarpet (~> 3.4.0) - rouge (~> 2.0.5) + middleman (~> 4.3) + middleman-autoprefixer (~> 2.7) + middleman-sprockets (~> 4.1) + middleman-syntax (~> 3.2) + nokogiri (~> 1.10.8) + redcarpet (~> 3.5.0) + rouge (~> 3.20) + sass + +RUBY VERSION + ruby 2.3.3p222 BUNDLED WITH - 1.17.1 + 2.1.4 diff --git a/samples/rest-notes-slate/slate/LICENSE b/samples/rest-notes-slate/slate/LICENSE index 8edb3189a..261eeb9e9 100644 --- a/samples/rest-notes-slate/slate/LICENSE +++ b/samples/rest-notes-slate/slate/LICENSE @@ -1,13 +1,201 @@ -Copyright 2008-2013 Concur Technologies, Inc. + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ -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 + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - https://www.apache.org/licenses/LICENSE-2.0 + 1. Definitions. -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. \ No newline at end of file + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. diff --git a/samples/rest-notes-slate/slate/README.md b/samples/rest-notes-slate/slate/README.md deleted file mode 100644 index 5a4497a63..000000000 --- a/samples/rest-notes-slate/slate/README.md +++ /dev/null @@ -1,111 +0,0 @@ -

- Slate: API Documentation Generator -
- Build Status -

- -

Slate helps you create beautiful, intelligent, responsive API documentation.

- -

Screenshot of Example Documentation created with Slate

- -

The example above was created with Slate. Check it out at lord.github.io/slate.

- -Features ------------- - -* **Clean, intuitive design** — With Slate, the description of your API is on the left side of your documentation, and all the code examples are on the right side. Inspired by [Stripe's](https://stripe.com/docs/api) and [Paypal's](https://developer.paypal.com/webapps/developer/docs/api/) API docs. Slate is responsive, so it looks great on tablets, phones, and even in print. - -* **Everything on a single page** — Gone are the days when your users had to search through a million pages to find what they wanted. Slate puts the entire documentation on a single page. We haven't sacrificed linkability, though. As you scroll, your browser's hash will update to the nearest header, so linking to a particular point in the documentation is still natural and easy. - -* **Slate is just Markdown** — When you write docs with Slate, you're just writing Markdown, which makes it simple to edit and understand. Everything is written in Markdown — even the code samples are just Markdown code blocks. - -* **Write code samples in multiple languages** — If your API has bindings in multiple programming languages, you can easily put in tabs to switch between them. In your document, you'll distinguish different languages by specifying the language name at the top of each code block, just like with Github Flavored Markdown. - -* **Out-of-the-box syntax highlighting** for [over 100 languages](https://github.com/jneen/rouge/wiki/List-of-supported-languages-and-lexers), no configuration required. - -* **Automatic, smoothly scrolling table of contents** on the far left of the page. As you scroll, it displays your current position in the document. It's fast, too. We're using Slate at TripIt to build documentation for our new API, where our table of contents has over 180 entries. We've made sure that the performance remains excellent, even for larger documents. - -* **Let your users update your documentation for you** — By default, your Slate-generated documentation is hosted in a public Github repository. Not only does this mean you get free hosting for your docs with Github Pages, but it also makes it simple for other developers to make pull requests to your docs if they find typos or other problems. Of course, if you don't want to use GitHub, you're also welcome to host your docs elsewhere. - -Getting started with Slate is super easy! Simply fork this repository and follow the instructions below. Or, if you'd like to check out what Slate is capable of, take a look at the [sample docs](https://lord.github.io/slate). - -Getting Started with Slate ------------------------------- - -### Prerequisites - -You're going to need: - - - **Linux or OS X** — Windows may work, but is unsupported. - - **Ruby, version 2.2.5 or newer** - - **Bundler** — If Ruby is already installed, but the `bundle` command doesn't work, just run `gem install bundler` in a terminal. - -### Getting Set Up - -1. Fork this repository on Github. -2. Clone *your forked repository* (not our original one) to your hard drive with `git clone https://github.com/YOURUSERNAME/slate.git` -3. `cd slate` -4. Initialize and start Slate. You can either do this locally, or with Vagrant: - -```shell -# either run this to run locally -bundle install -bundle exec middleman server - -# OR run this to run with vagrant -vagrant up -``` - -You can now see the docs at http://localhost:4567. Whoa! That was fast! - -Now that Slate is all set up on your machine, you'll probably want to learn more about [editing Slate markdown](https://github.com/lord/slate/wiki/Markdown-Syntax), or [how to publish your docs](https://github.com/lord/slate/wiki/Deploying-Slate). - -If you'd prefer to use Docker, instructions are available [in the wiki](https://github.com/lord/slate/wiki/Docker). - -Companies Using Slate ---------------------------------- - -* [NASA](https://api.nasa.gov) -* [IBM](https://docs.cloudant.com/api.html) -* [Sony](https://developers.cimediacloud.com) -* [Mozilla](https://localforage.github.io/localForage/) -* [Best Buy](https://bestbuyapis.github.io/api-documentation/) -* [Travis-CI](https://docs.travis-ci.com/api/) -* [Greenhouse](https://developers.greenhouse.io/harvest.html) -* [Woocommerce](https://woocommerce.github.io/woocommerce-rest-api-docs/) -* [Appium](https://appium.io/slate/en/master) -* [Dwolla](https://docs.dwolla.com/) -* [Clearbit](https://clearbit.com/docs) -* [Coinbase](https://developers.coinbase.com/api) -* [Parrot Drones](https://developer.parrot.com/docs/bebop/) -* [Fidor Bank](https://api-docs.fidor.de) -* [Scale](https://docs.scaleapi.com/) - -You can view more in [the list on the wiki](https://github.com/lord/slate/wiki/Slate-in-the-Wild). - -Need Help? Found a bug? --------------------- - -[Submit an issue](https://github.com/lord/slate/issues) to the Slate Github if you need any help. And, of course, feel free to submit pull requests with bug fixes or changes. - -Contributors --------------------- - -Slate was built by [Robert Lord](https://lord.io) while interning at [TripIt](https://www.tripit.com/). - -Thanks to the following people who have submitted major pull requests: - -- [@chrissrogers](https://github.com/chrissrogers) -- [@bootstraponline](https://github.com/bootstraponline) -- [@realityking](https://github.com/realityking) -- [@cvkef](https://github.com/cvkef) - -Also, thanks to [Sauce Labs](https://saucelabs.com) for helping sponsor the project. - -Special Thanks --------------------- -- [Middleman](https://github.com/middleman/middleman) -- [jquery.tocify.js](https://github.com/gfranko/jquery.tocify.js) -- [middleman-syntax](https://github.com/middleman/middleman-syntax) -- [middleman-gh-pages](https://github.com/edgecase/middleman-gh-pages) -- [Font Awesome](https://fortawesome.github.io/Font-Awesome/) diff --git a/samples/rest-notes-slate/slate/Vagrantfile b/samples/rest-notes-slate/slate/Vagrantfile index 43b1f9954..4166fb6ba 100644 --- a/samples/rest-notes-slate/slate/Vagrantfile +++ b/samples/rest-notes-slate/slate/Vagrantfile @@ -1,14 +1,21 @@ Vagrant.configure(2) do |config| - config.vm.box = "ubuntu/trusty64" + config.vm.box = "ubuntu/bionic64" config.vm.network :forwarded_port, guest: 4567, host: 4567 + config.vm.provider "virtualbox" do |vb| + vb.memory = "2048" + end config.vm.provision "bootstrap", type: "shell", inline: <<-SHELL + # add nodejs v12 repository + curl -sL https://deb.nodesource.com/setup_12.x | sudo -E bash - + sudo apt-get update - sudo apt-get install -yq ruby2.0 ruby2.0-dev pkg-config build-essential nodejs git libxml2-dev libxslt-dev + sudo apt-get install -yq ruby ruby-dev + sudo apt-get install -yq pkg-config build-essential nodejs git libxml2-dev libxslt-dev sudo apt-get autoremove -yq - gem2.0 install --no-ri --no-rdoc bundler + gem install --no-ri --no-rdoc bundler SHELL # add the local user git config to the vm @@ -34,6 +41,6 @@ Vagrant.configure(2) do |config| echo "Starting up middleman at http://localhost:4567" echo "If it does not come up, check the ~/middleman.log file for any error messages" cd /vagrant - bundle exec middleman server --force-polling --latency=1 &> ~/middleman.log & + bundle exec middleman server --watcher-force-polling --watcher-latency=1 &> ~/middleman.log & SHELL end diff --git a/samples/rest-notes-slate/slate/config.rb b/samples/rest-notes-slate/slate/config.rb index 0cb5fea49..6f8b677f6 100644 --- a/samples/rest-notes-slate/slate/config.rb +++ b/samples/rest-notes-slate/slate/config.rb @@ -1,3 +1,6 @@ +# Unique header generation +require './lib/unique_head.rb' + # Markdown set :markdown_engine, :redcarpet set :markdown, @@ -5,9 +8,11 @@ smartypants: true, disable_indented_code_blocks: true, prettify: true, + strikethrough: true, tables: true, with_toc_data: true, - no_intra_emphasis: true + no_intra_emphasis: true, + renderer: UniqueHeadCounter # Assets set :css_dir, 'stylesheets' @@ -18,6 +23,7 @@ # Activate the syntax highlighter activate :syntax ready do + require './lib/monokai_sublime_slate.rb' require './lib/multilang.rb' end @@ -34,19 +40,24 @@ set :relative_links, true # Build Configuration - -set :build_dir, '../build/docs' - configure :build do + # We do want to hash woff and woff2 as there's a bug where woff2 will use + # woff asset hash which breaks things. Trying to use a combination of ignore and + # rewrite_ignore does not work as it conflicts weirdly with relative_assets. Disabling + # the .woff2 extension only does not work as .woff will still activate it so have to + # have both. See https://github.com/slatedocs/slate/issues/1171 for more details. + activate :asset_hash, :exts => app.config[:asset_extensions] - %w[.woff .woff2] # If you're having trouble with Middleman hanging, commenting # out the following two lines has been known to help activate :minify_css activate :minify_javascript - # activate :relative_assets - # activate :asset_hash # activate :gzip end # Deploy Configuration # If you want Middleman to listen on a different port, you can set that below set :port, 4567 + +helpers do + require './lib/toc_data.rb' +end diff --git a/samples/rest-notes-slate/slate/deploy.sh b/samples/rest-notes-slate/slate/deploy.sh index 909a9d908..9dbd7db9c 100755 --- a/samples/rest-notes-slate/slate/deploy.sh +++ b/samples/rest-notes-slate/slate/deploy.sh @@ -15,9 +15,14 @@ Options: deploy branch. -n, --no-hash Don't append the source commit's hash to the deploy commit's message. + --source-only Only build but not push + --push-only Only push but not build " -bundle exec middleman build --clean + +run_build() { + bundle exec middleman build --clean +} parse_args() { # Set args from a local environment file. @@ -31,7 +36,7 @@ parse_args() { while : ; do if [[ $1 = "-h" || $1 = "--help" ]]; then echo "$help_message" - return 0 + exit 0 elif [[ $1 = "-v" || $1 = "--verbose" ]]; then verbose=true shift @@ -44,11 +49,22 @@ parse_args() { elif [[ $1 = "-n" || $1 = "--no-hash" ]]; then GIT_DEPLOY_APPEND_HASH=false shift + elif [[ $1 = "--source-only" ]]; then + source_only=true + shift + elif [[ $1 = "--push-only" ]]; then + push_only=true + shift else break fi done + if [ ${source_only} ] && [ ${push_only} ]; then + >&2 echo "You can only specify one of --source-only or --push-only" + exit 1 + fi + # Set internal option vars from the environment and arg flags. All internal # vars should be declared here, with sane defaults if applicable. @@ -68,8 +84,6 @@ parse_args() { } main() { - parse_args "$@" - enable_expanded_output if ! git diff --exit-code --quiet --cached; then @@ -97,7 +111,7 @@ main() { return 1 fi - # must use short form of flag in ls for compatibility with OS X and BSD + # must use short form of flag in ls for compatibility with macOS and BSD if [[ -z `ls -A "$deploy_directory" 2> /dev/null` && -z $allow_empty ]]; then echo "Deploy directory '$deploy_directory' is empty. Aborting. If you're sure you want to deploy an empty tree, use the --allow-empty / -e flag." >&2 return 1 @@ -140,7 +154,7 @@ incremental_deploy() { 0) echo No changes to files in $deploy_directory. Skipping commit.;; 1) commit+push;; *) - echo git diff exited with code $diff. Aborting. Staying on branch $deploy_branch so you can debug. To switch back to master, use: git symbolic-ref HEAD refs/heads/master && git reset --mixed >&2 + echo git diff exited with code $diff. Aborting. Staying on branch $deploy_branch so you can debug. To switch back to main, use: git symbolic-ref HEAD refs/heads/main && git reset --mixed >&2 return $diff ;; esac @@ -200,4 +214,13 @@ sanitize() { "$@" 2> >(filter 1>&2) | filter } -[[ $1 = --source-only ]] || main "$@" +parse_args "$@" + +if [[ ${source_only} ]]; then + run_build +elif [[ ${push_only} ]]; then + main "$@" +else + run_build + main "$@" +fi diff --git a/samples/rest-notes-slate/slate/lib/monokai_sublime_slate.rb b/samples/rest-notes-slate/slate/lib/monokai_sublime_slate.rb new file mode 100644 index 000000000..cd2de3317 --- /dev/null +++ b/samples/rest-notes-slate/slate/lib/monokai_sublime_slate.rb @@ -0,0 +1,95 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +# this is based on https://github.com/rouge-ruby/rouge/blob/master/lib/rouge/themes/monokai_sublime.rb +# but without the added background, and changed styling for JSON keys to be soft_yellow instead of white + +module Rouge + module Themes + class MonokaiSublimeSlate < CSSTheme + name 'monokai.sublime.slate' + + palette :black => '#000000' + palette :bright_green => '#a6e22e' + palette :bright_pink => '#f92672' + palette :carmine => '#960050' + palette :dark => '#49483e' + palette :dark_grey => '#888888' + palette :dark_red => '#aa0000' + palette :dimgrey => '#75715e' + palette :emperor => '#555555' + palette :grey => '#999999' + palette :light_grey => '#aaaaaa' + palette :light_violet => '#ae81ff' + palette :soft_cyan => '#66d9ef' + palette :soft_yellow => '#e6db74' + palette :very_dark => '#1e0010' + palette :whitish => '#f8f8f2' + palette :orange => '#f6aa11' + palette :white => '#ffffff' + + style Generic::Heading, :fg => :grey + style Literal::String::Regex, :fg => :orange + style Generic::Output, :fg => :dark_grey + style Generic::Prompt, :fg => :emperor + style Generic::Strong, :bold => false + style Generic::Subheading, :fg => :light_grey + style Name::Builtin, :fg => :orange + style Comment::Multiline, + Comment::Preproc, + Comment::Single, + Comment::Special, + Comment, :fg => :dimgrey + style Error, + Generic::Error, + Generic::Traceback, :fg => :carmine + style Generic::Deleted, + Generic::Inserted, + Generic::Emph, :fg => :dark + style Keyword::Constant, + Keyword::Declaration, + Keyword::Reserved, + Name::Constant, + Keyword::Type, :fg => :soft_cyan + style Literal::Number::Float, + Literal::Number::Hex, + Literal::Number::Integer::Long, + Literal::Number::Integer, + Literal::Number::Oct, + Literal::Number, + Literal::String::Char, + Literal::String::Escape, + Literal::String::Symbol, :fg => :light_violet + style Literal::String::Doc, + Literal::String::Double, + Literal::String::Backtick, + Literal::String::Heredoc, + Literal::String::Interpol, + Literal::String::Other, + Literal::String::Single, + Literal::String, :fg => :soft_yellow + style Name::Attribute, + Name::Class, + Name::Decorator, + Name::Exception, + Name::Function, :fg => :bright_green + style Name::Variable::Class, + Name::Namespace, + Name::Entity, + Name::Builtin::Pseudo, + Name::Variable::Global, + Name::Variable::Instance, + Name::Variable, + Text::Whitespace, + Text, + Name, :fg => :white + style Name::Label, :fg => :bright_pink + style Operator::Word, + Name::Tag, + Keyword, + Keyword::Namespace, + Keyword::Pseudo, + Operator, :fg => :bright_pink + end + end + end diff --git a/samples/rest-notes-slate/slate/lib/multilang.rb b/samples/rest-notes-slate/slate/lib/multilang.rb index 624c6e495..36fbe5b1f 100644 --- a/samples/rest-notes-slate/slate/lib/multilang.rb +++ b/samples/rest-notes-slate/slate/lib/multilang.rb @@ -1,9 +1,13 @@ module Multilang def block_code(code, full_lang_name) - parts = full_lang_name.split('--') - rouge_lang_name = parts[0] || "" - super(code, rouge_lang_name).sub("highlight #{rouge_lang_name}") do |match| - match + " tab-" + full_lang_name + if full_lang_name + parts = full_lang_name.split('--') + rouge_lang_name = (parts) ? parts[0] : "" # just parts[0] here causes null ref exception when no language specified + super(code, rouge_lang_name).sub("highlight #{rouge_lang_name}") do |match| + match + " tab-" + full_lang_name + end + else + super(code, full_lang_name) end end end diff --git a/samples/rest-notes-slate/slate/lib/nesting_unique_head.rb b/samples/rest-notes-slate/slate/lib/nesting_unique_head.rb new file mode 100644 index 000000000..01278371c --- /dev/null +++ b/samples/rest-notes-slate/slate/lib/nesting_unique_head.rb @@ -0,0 +1,22 @@ +# Nested unique header generation +require 'middleman-core/renderers/redcarpet' + +class NestingUniqueHeadCounter < Middleman::Renderers::MiddlemanRedcarpetHTML + def initialize + super + @@headers_history = {} if !defined?(@@headers_history) + end + + def header(text, header_level) + friendly_text = text.gsub(/<[^>]*>/,"").parameterize + @@headers_history[header_level] = text.parameterize + + if header_level > 1 + for i in (header_level - 1).downto(1) + friendly_text.prepend("#{@@headers_history[i]}-") if @@headers_history.key?(i) + end + end + + return "#{text}" + end +end diff --git a/samples/rest-notes-slate/slate/lib/toc_data.rb b/samples/rest-notes-slate/slate/lib/toc_data.rb new file mode 100644 index 000000000..4a04efee2 --- /dev/null +++ b/samples/rest-notes-slate/slate/lib/toc_data.rb @@ -0,0 +1,31 @@ +require 'nokogiri' + +def toc_data(page_content) + html_doc = Nokogiri::HTML::DocumentFragment.parse(page_content) + + # get a flat list of headers + headers = [] + html_doc.css('h1, h2, h3').each do |header| + headers.push({ + id: header.attribute('id').to_s, + content: header.children, + title: header.children.to_s.gsub(/<[^>]*>/, ''), + level: header.name[1].to_i, + children: [] + }) + end + + [3,2].each do |header_level| + header_to_nest = nil + headers = headers.reject do |header| + if header[:level] == header_level + header_to_nest[:children].push header if header_to_nest + true + else + header_to_nest = header if header[:level] < header_level + false + end + end + end + headers +end diff --git a/samples/rest-notes-slate/slate/lib/unique_head.rb b/samples/rest-notes-slate/slate/lib/unique_head.rb new file mode 100644 index 000000000..d42bab2aa --- /dev/null +++ b/samples/rest-notes-slate/slate/lib/unique_head.rb @@ -0,0 +1,24 @@ +# Unique header generation +require 'middleman-core/renderers/redcarpet' +require 'digest' +class UniqueHeadCounter < Middleman::Renderers::MiddlemanRedcarpetHTML + def initialize + super + @head_count = {} + end + def header(text, header_level) + friendly_text = text.gsub(/<[^>]*>/,"").parameterize + if friendly_text.strip.length == 0 + # Looks like parameterize removed the whole thing! It removes many unicode + # characters like Chinese and Russian. To get a unique URL, let's just + # URI escape the whole header + friendly_text = Digest::SHA1.hexdigest(text)[0,10] + end + @head_count[friendly_text] ||= 0 + @head_count[friendly_text] += 1 + if @head_count[friendly_text] > 1 + friendly_text += "-#{@head_count[friendly_text]}" + end + return "#{text}" + end +end diff --git a/samples/rest-notes-slate/slate/source/fonts/slate.eot b/samples/rest-notes-slate/slate/source/fonts/slate.eot old mode 100755 new mode 100644 diff --git a/samples/rest-notes-slate/slate/source/fonts/slate.svg b/samples/rest-notes-slate/slate/source/fonts/slate.svg old mode 100755 new mode 100644 index 82e48fb50..5f3498230 --- a/samples/rest-notes-slate/slate/source/fonts/slate.svg +++ b/samples/rest-notes-slate/slate/source/fonts/slate.svg @@ -1,5 +1,5 @@ - + Generated by IcoMoon diff --git a/samples/rest-notes-slate/slate/source/fonts/slate.ttf b/samples/rest-notes-slate/slate/source/fonts/slate.ttf old mode 100755 new mode 100644 diff --git a/samples/rest-notes-slate/slate/source/fonts/slate.woff b/samples/rest-notes-slate/slate/source/fonts/slate.woff old mode 100755 new mode 100644 diff --git a/samples/rest-notes-slate/slate/source/fonts/slate.woff2 b/samples/rest-notes-slate/slate/source/fonts/slate.woff2 old mode 100755 new mode 100644 diff --git a/samples/rest-notes-slate/slate/source/includes/_errors.md b/samples/rest-notes-slate/slate/source/includes/_errors.md index 267e352f3..7b35e92b5 100644 --- a/samples/rest-notes-slate/slate/source/includes/_errors.md +++ b/samples/rest-notes-slate/slate/source/includes/_errors.md @@ -1,20 +1,22 @@ # Errors - +includes/_errors.md. Slate allows you to optionally separate out your docs into many files...just save them to the includes folder and add them to the top of your index.md's frontmatter. Files are included in the order listed. + The Kittn API uses the following error codes: Error Code | Meaning ---------- | ------- -400 | Bad Request -- Your request sucks -401 | Unauthorized -- Your API key is wrong -403 | Forbidden -- The kitten requested is hidden for administrators only -404 | Not Found -- The specified kitten could not be found -405 | Method Not Allowed -- You tried to access a kitten with an invalid method -406 | Not Acceptable -- You requested a format that isn't json -410 | Gone -- The kitten requested has been removed from our servers -418 | I'm a teapot +400 | Bad Request -- Your request is invalid. +401 | Unauthorized -- Your API key is wrong. +403 | Forbidden -- The kitten requested is hidden for administrators only. +404 | Not Found -- The specified kitten could not be found. +405 | Method Not Allowed -- You tried to access a kitten with an invalid method. +406 | Not Acceptable -- You requested a format that isn't json. +410 | Gone -- The kitten requested has been removed from our servers. +418 | I'm a teapot. 429 | Too Many Requests -- You're requesting too many kittens! Slow down! 500 | Internal Server Error -- We had a problem with our server. Try again later. 503 | Service Unavailable -- We're temporarily offline for maintenance. Please try again later. diff --git a/samples/rest-notes-slate/slate/source/index.html.md b/samples/rest-notes-slate/slate/source/index.html.md index 1e776f51e..1bf6780af 100644 --- a/samples/rest-notes-slate/slate/source/index.html.md +++ b/samples/rest-notes-slate/slate/source/index.html.md @@ -1,7 +1,7 @@ --- title: API Reference -language_tabs: +language_tabs: # must be one of https://git.io/vQNgJ - shell - ruby - python @@ -9,21 +9,23 @@ language_tabs: toc_footers: - Sign Up for a Developer Key - - Documentation Powered by Slate + - Documentation Powered by Slate includes: - errors search: true + +code_clipboard: true --- # Introduction Welcome to the Kittn API! You can use our API to access Kittn API endpoints, which can get information on various cats, kittens, and breeds in our database. -We have language bindings in Shell, Ruby, and Python! You can view code examples in the dark area to the right, and you can switch the programming language of the examples with the tabs in the top right. +We have language bindings in Shell, Ruby, Python, and JavaScript! You can view code examples in the dark area to the right, and you can switch the programming language of the examples with the tabs in the top right. -This example API documentation page was created with [Slate](https://github.com/tripit/slate). Feel free to edit it and use it as a base for your own API's documentation. +This example API documentation page was created with [Slate](https://github.com/slatedocs/slate). Feel free to edit it and use it as a base for your own API's documentation. # Authentication @@ -55,7 +57,7 @@ let api = kittn.authorize('meowmeowmeow'); > Make sure to replace `meowmeowmeow` with your API key. -Kittn uses API keys to allow access to the API. You can register a new Kittn API key at our [developer portal](https://example.com/developers). +Kittn uses API keys to allow access to the API. You can register a new Kittn API key at our [developer portal](http://example.com/developers). Kittn expects for the API key to be included in all API requests to the server in a header that looks like the following: @@ -84,7 +86,7 @@ api.kittens.get() ``` ```shell -curl "https://example.com/api/kittens" +curl "http://example.com/api/kittens" -H "Authorization: meowmeowmeow" ``` @@ -120,7 +122,7 @@ This endpoint retrieves all kittens. ### HTTP Request -`GET https://example.com/api/kittens` +`GET http://example.com/api/kittens` ### Query Parameters @@ -150,7 +152,7 @@ api.kittens.get(2) ``` ```shell -curl "https://example.com/api/kittens/2" +curl "http://example.com/api/kittens/2" -H "Authorization: meowmeowmeow" ``` @@ -179,7 +181,7 @@ This endpoint retrieves a specific kitten. ### HTTP Request -`GET https://example.com/kittens/` +`GET http://example.com/kittens/` ### URL Parameters @@ -187,3 +189,53 @@ Parameter | Description --------- | ----------- ID | The ID of the kitten to retrieve +## Delete a Specific Kitten + +```ruby +require 'kittn' + +api = Kittn::APIClient.authorize!('meowmeowmeow') +api.kittens.delete(2) +``` + +```python +import kittn + +api = kittn.authorize('meowmeowmeow') +api.kittens.delete(2) +``` + +```shell +curl "http://example.com/api/kittens/2" + -X DELETE + -H "Authorization: meowmeowmeow" +``` + +```javascript +const kittn = require('kittn'); + +let api = kittn.authorize('meowmeowmeow'); +let max = api.kittens.delete(2); +``` + +> The above command returns JSON structured like this: + +```json +{ + "id": 2, + "deleted" : ":(" +} +``` + +This endpoint deletes a specific kitten. + +### HTTP Request + +`DELETE http://example.com/kittens/` + +### URL Parameters + +Parameter | Description +--------- | ----------- +ID | The ID of the kitten to delete + diff --git a/samples/rest-notes-slate/slate/source/javascripts/all.js b/samples/rest-notes-slate/slate/source/javascripts/all.js index ffaa9b013..5f5d4067b 100644 --- a/samples/rest-notes-slate/slate/source/javascripts/all.js +++ b/samples/rest-notes-slate/slate/source/javascripts/all.js @@ -1,4 +1,2 @@ -//= require ./lib/_energize -//= require ./app/_lang +//= require ./all_nosearch //= require ./app/_search -//= require ./app/_toc diff --git a/samples/rest-notes-slate/slate/source/javascripts/all_nosearch.js b/samples/rest-notes-slate/slate/source/javascripts/all_nosearch.js index 818bc4e50..026e5a200 100644 --- a/samples/rest-notes-slate/slate/source/javascripts/all_nosearch.js +++ b/samples/rest-notes-slate/slate/source/javascripts/all_nosearch.js @@ -1,3 +1,27 @@ //= require ./lib/_energize -//= require ./app/_lang +//= require ./app/_copy //= require ./app/_toc +//= require ./app/_lang + +function adjustLanguageSelectorWidth() { + const elem = $('.dark-box > .lang-selector'); + elem.width(elem.parent().width()); +} + +$(function() { + loadToc($('#toc'), '.toc-link', '.toc-list-h2', 10); + setupLanguages($('body').data('languages')); + $('.content').imagesLoaded( function() { + window.recacheHeights(); + window.refreshToc(); + }); + + $(window).resize(function() { + adjustLanguageSelectorWidth(); + }); + adjustLanguageSelectorWidth(); +}); + +window.onpopstate = function() { + activateLanguage(getLanguageFromQueryString()); +}; diff --git a/samples/rest-notes-slate/slate/source/javascripts/app/_copy.js b/samples/rest-notes-slate/slate/source/javascripts/app/_copy.js new file mode 100644 index 000000000..f1e3a4325 --- /dev/null +++ b/samples/rest-notes-slate/slate/source/javascripts/app/_copy.js @@ -0,0 +1,15 @@ +function copyToClipboard(container) { + const el = document.createElement('textarea'); + el.value = container.textContent; + document.body.appendChild(el); + el.select(); + document.execCommand('copy'); + document.body.removeChild(el); +} + +function setupCodeCopy() { + $('pre.highlight').prepend('
Copy to Clipboard
'); + $('.copy-clipboard').on('click', function() { + copyToClipboard(this.parentNode.children[1]); + }); +} diff --git a/samples/rest-notes-slate/slate/source/javascripts/app/_lang.js b/samples/rest-notes-slate/slate/source/javascripts/app/_lang.js index 67e96b23d..0fbaaef70 100644 --- a/samples/rest-notes-slate/slate/source/javascripts/app/_lang.js +++ b/samples/rest-notes-slate/slate/source/javascripts/app/_lang.js @@ -7,7 +7,7 @@ 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 - https://www.apache.org/licenses/LICENSE-2.0 + 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 @@ -15,13 +15,14 @@ WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -(function (global) { +;(function () { 'use strict'; var languages = []; - global.setupLanguages = setupLanguages; - global.activateLanguage = activateLanguage; + window.setupLanguages = setupLanguages; + window.activateLanguage = activateLanguage; + window.getLanguageFromQueryString = getLanguageFromQueryString; function activateLanguage(language) { if (!language) return; @@ -36,7 +37,7 @@ under the License. $(".highlight.tab-" + language).show(); $(".lang-specific." + language).show(); - global.toc.calculateHeights(); + window.recacheHeights(); // scroll to the new location of the position if ($(window.location.hash).get(0)) { @@ -65,7 +66,7 @@ under the License. key = decodeURIComponent(key); // missing `=` should be `null`: - // https://w3.org/TR/2012/WD-url-20120524/#collect-url-parameters + // http://w3.org/TR/2012/WD-url-20120524/#collect-url-parameters val = val === undefined ? null : decodeURIComponent(val); if (!ret.hasOwnProperty(key)) { @@ -97,7 +98,7 @@ under the License. // gets the language set in the query string function getLanguageFromQueryString() { if (location.search.length >= 1) { - var language = parseURL(location.search).language + var language = parseURL(location.search).language; if (language) { return language; } else if (jQuery.inArray(location.search.substr(1), languages) != -1) { @@ -159,8 +160,5 @@ under the License. activateLanguage(language); return false; }); - window.onpopstate = function() { - activateLanguage(getLanguageFromQueryString()); - }; }); -})(window); +})(); diff --git a/samples/rest-notes-slate/slate/source/javascripts/app/_search.js b/samples/rest-notes-slate/slate/source/javascripts/app/_search.js index 5ace538d8..0b0ccd97f 100644 --- a/samples/rest-notes-slate/slate/source/javascripts/app/_search.js +++ b/samples/rest-notes-slate/slate/source/javascripts/app/_search.js @@ -1,50 +1,76 @@ //= require ../lib/_lunr //= require ../lib/_jquery //= require ../lib/_jquery.highlight -(function () { +;(function () { 'use strict'; var content, searchResults; var highlightOpts = { element: 'span', className: 'search-highlight' }; + var searchDelay = 0; + var timeoutHandle = 0; + var index; - var index = new lunr.Index(); + function populate() { + index = lunr(function(){ + + this.ref('id'); + this.field('title', { boost: 10 }); + this.field('body'); + this.pipeline.add(lunr.trimmer, lunr.stopWordFilter); + var lunrConfig = this; + + $('h1, h2').each(function() { + var title = $(this); + var body = title.nextUntil('h1, h2'); + lunrConfig.add({ + id: title.prop('id'), + title: title.text(), + body: body.text() + }); + }); - index.ref('id'); - index.field('title', { boost: 10 }); - index.field('body'); - index.pipeline.add(lunr.trimmer, lunr.stopWordFilter); + }); + determineSearchDelay(); + } $(populate); $(bind); - function populate() { - $('h1, h2').each(function() { - var title = $(this); - var body = title.nextUntil('h1, h2'); - index.add({ - id: title.prop('id'), - title: title.text(), - body: body.text() - }); - }); + function determineSearchDelay() { + if (index.tokenSet.toArray().length>5000) { + searchDelay = 300; + } } function bind() { content = $('.content'); searchResults = $('.search-results'); - $('#input-search').on('keyup', search); + $('#input-search').on('keyup',function(e) { + var wait = function() { + return function(executingFunction, waitTime){ + clearTimeout(timeoutHandle); + timeoutHandle = setTimeout(executingFunction, waitTime); + }; + }(); + wait(function(){ + search(e); + }, searchDelay); + }); } function search(event) { + + var searchInput = $('#input-search')[0]; + unhighlight(); searchResults.addClass('visible'); // ESC clears the field - if (event.keyCode === 27) this.value = ''; + if (event.keyCode === 27) searchInput.value = ''; - if (this.value) { - var results = index.search(this.value).filter(function(r) { + if (searchInput.value) { + var results = index.search(searchInput.value).filter(function(r) { return r.score > 0.0001; }); @@ -54,10 +80,10 @@ var elem = document.getElementById(result.ref); searchResults.append("
  • " + $(elem).text() + "
  • "); }); - highlight.call(this); + highlight.call(searchInput); } else { searchResults.html('
  • '); - $('.search-results li').text('No Results Found for "' + this.value + '"'); + $('.search-results li').text('No Results Found for "' + searchInput.value + '"'); } } else { unhighlight(); @@ -73,3 +99,4 @@ content.unhighlight(highlightOpts); } })(); + diff --git a/samples/rest-notes-slate/slate/source/javascripts/app/_toc.js b/samples/rest-notes-slate/slate/source/javascripts/app/_toc.js index 21d080006..f70bdc0ff 100644 --- a/samples/rest-notes-slate/slate/source/javascripts/app/_toc.js +++ b/samples/rest-notes-slate/slate/source/javascripts/app/_toc.js @@ -1,57 +1,122 @@ //= require ../lib/_jquery -//= require ../lib/_jquery_ui -//= require ../lib/_jquery.tocify //= require ../lib/_imagesloaded.min -(function (global) { +;(function () { 'use strict'; + var htmlPattern = /<[^>]*>/g; + var loaded = false; + + var debounce = function(func, waitTime) { + var timeout = false; + return function() { + if (timeout === false) { + setTimeout(function() { + func(); + timeout = false; + }, waitTime); + timeout = true; + } + }; + }; + var closeToc = function() { - $(".tocify-wrapper").removeClass('open'); + $(".toc-wrapper").removeClass('open'); $("#nav-button").removeClass('open'); }; - var makeToc = function() { - global.toc = $("#toc").tocify({ - selectors: 'h1, h2', - extendPage: false, - theme: 'none', - smoothScroll: false, - showEffectSpeed: 0, - hideEffectSpeed: 180, - ignoreSelector: '.toc-ignore', - highlightOffset: 60, - scrollTo: -1, - scrollHistory: true, - hashGenerator: function (text, element) { - return element.prop('id'); + function loadToc($toc, tocLinkSelector, tocListSelector, scrollOffset) { + var headerHeights = {}; + var pageHeight = 0; + var windowHeight = 0; + var originalTitle = document.title; + + var recacheHeights = function() { + headerHeights = {}; + pageHeight = $(document).height(); + windowHeight = $(window).height(); + + $toc.find(tocLinkSelector).each(function() { + var targetId = $(this).attr('href'); + if (targetId[0] === "#") { + headerHeights[targetId] = $("#" + $.escapeSelector(targetId.substring(1))).offset().top; + } + }); + }; + + var refreshToc = function() { + var currentTop = $(document).scrollTop() + scrollOffset; + + if (currentTop + windowHeight >= pageHeight) { + // at bottom of page, so just select last header by making currentTop very large + // this fixes the problem where the last header won't ever show as active if its content + // is shorter than the window height + currentTop = pageHeight + 1000; } - }).data('toc-tocify'); - $("#nav-button").click(function() { - $(".tocify-wrapper").toggleClass('open'); - $("#nav-button").toggleClass('open'); - return false; - }); + var best = null; + for (var name in headerHeights) { + if ((headerHeights[name] < currentTop && headerHeights[name] > headerHeights[best]) || best === null) { + best = name; + } + } - $(".page-wrapper").click(closeToc); - $(".tocify-item").click(closeToc); - }; + // Catch the initial load case + if (currentTop == scrollOffset && !loaded) { + best = window.location.hash; + loaded = true; + } - // Hack to make already open sections to start opened, - // instead of displaying an ugly animation - function animate() { - setTimeout(function() { - toc.setOption('showEffectSpeed', 180); - }, 50); - } + var $best = $toc.find("[href='" + best + "']").first(); + if (!$best.hasClass("active")) { + // .active is applied to the ToC link we're currently on, and its parent
      s selected by tocListSelector + // .active-expanded is applied to the ToC links that are parents of this one + $toc.find(".active").removeClass("active"); + $toc.find(".active-parent").removeClass("active-parent"); + $best.addClass("active"); + $best.parents(tocListSelector).addClass("active").siblings(tocLinkSelector).addClass('active-parent'); + $best.siblings(tocListSelector).addClass("active"); + $toc.find(tocListSelector).filter(":not(.active)").slideUp(150); + $toc.find(tocListSelector).filter(".active").slideDown(150); + if (window.history.replaceState) { + window.history.replaceState(null, "", best); + } + var thisTitle = $best.data("title"); + if (thisTitle !== undefined && thisTitle.length > 0) { + document.title = thisTitle.replace(htmlPattern, "") + " – " + originalTitle; + } else { + document.title = originalTitle; + } + } + }; + + var makeToc = function() { + recacheHeights(); + refreshToc(); + + $("#nav-button").click(function() { + $(".toc-wrapper").toggleClass('open'); + $("#nav-button").toggleClass('open'); + return false; + }); + $(".page-wrapper").click(closeToc); + $(".toc-link").click(closeToc); + + // reload immediately after scrolling on toc click + $toc.find(tocLinkSelector).click(function() { + setTimeout(function() { + refreshToc(); + }, 0); + }); + + $(window).scroll(debounce(refreshToc, 200)); + $(window).resize(debounce(recacheHeights, 200)); + }; - $(function() { makeToc(); - animate(); - setupLanguages($('body').data('languages')); - $('.content').imagesLoaded( function() { - global.toc.calculateHeights(); - }); - }); -})(window); + window.recacheHeights = recacheHeights; + window.refreshToc = refreshToc; + } + + window.loadToc = loadToc; +})(); diff --git a/samples/rest-notes-slate/slate/source/javascripts/lib/_energize.js b/samples/rest-notes-slate/slate/source/javascripts/lib/_energize.js index 582407842..6798f3c03 100644 --- a/samples/rest-notes-slate/slate/source/javascripts/lib/_energize.js +++ b/samples/rest-notes-slate/slate/source/javascripts/lib/_energize.js @@ -115,7 +115,7 @@ /** * Special logic for standalone web apps - * See https://stackoverflow.com/questions/2898740/iphone-safari-web-app-opens-links-in-new-window + * See http://stackoverflow.com/questions/2898740/iphone-safari-web-app-opens-links-in-new-window */ if(standAlone) { window.location = target.getAttribute("href"); diff --git a/samples/rest-notes-slate/slate/source/javascripts/lib/_imagesloaded.min.js b/samples/rest-notes-slate/slate/source/javascripts/lib/_imagesloaded.min.js index d66f65893..e443a77d6 100644 --- a/samples/rest-notes-slate/slate/source/javascripts/lib/_imagesloaded.min.js +++ b/samples/rest-notes-slate/slate/source/javascripts/lib/_imagesloaded.min.js @@ -1,7 +1,7 @@ /*! - * imagesLoaded PACKAGED v3.1.8 + * imagesLoaded PACKAGED v4.1.4 * JavaScript is all like "You images are done yet or what?" * MIT License */ -(function(){function e(){}function t(e,t){for(var n=e.length;n--;)if(e[n].listener===t)return n;return-1}function n(e){return function(){return this[e].apply(this,arguments)}}var i=e.prototype,r=this,o=r.EventEmitter;i.getListeners=function(e){var t,n,i=this._getEvents();if("object"==typeof e){t={};for(n in i)i.hasOwnProperty(n)&&e.test(n)&&(t[n]=i[n])}else t=i[e]||(i[e]=[]);return t},i.flattenListeners=function(e){var t,n=[];for(t=0;e.length>t;t+=1)n.push(e[t].listener);return n},i.getListenersAsObject=function(e){var t,n=this.getListeners(e);return n instanceof Array&&(t={},t[e]=n),t||n},i.addListener=function(e,n){var i,r=this.getListenersAsObject(e),o="object"==typeof n;for(i in r)r.hasOwnProperty(i)&&-1===t(r[i],n)&&r[i].push(o?n:{listener:n,once:!1});return this},i.on=n("addListener"),i.addOnceListener=function(e,t){return this.addListener(e,{listener:t,once:!0})},i.once=n("addOnceListener"),i.defineEvent=function(e){return this.getListeners(e),this},i.defineEvents=function(e){for(var t=0;e.length>t;t+=1)this.defineEvent(e[t]);return this},i.removeListener=function(e,n){var i,r,o=this.getListenersAsObject(e);for(r in o)o.hasOwnProperty(r)&&(i=t(o[r],n),-1!==i&&o[r].splice(i,1));return this},i.off=n("removeListener"),i.addListeners=function(e,t){return this.manipulateListeners(!1,e,t)},i.removeListeners=function(e,t){return this.manipulateListeners(!0,e,t)},i.manipulateListeners=function(e,t,n){var i,r,o=e?this.removeListener:this.addListener,s=e?this.removeListeners:this.addListeners;if("object"!=typeof t||t instanceof RegExp)for(i=n.length;i--;)o.call(this,t,n[i]);else for(i in t)t.hasOwnProperty(i)&&(r=t[i])&&("function"==typeof r?o.call(this,i,r):s.call(this,i,r));return this},i.removeEvent=function(e){var t,n=typeof e,i=this._getEvents();if("string"===n)delete i[e];else if("object"===n)for(t in i)i.hasOwnProperty(t)&&e.test(t)&&delete i[t];else delete this._events;return this},i.removeAllListeners=n("removeEvent"),i.emitEvent=function(e,t){var n,i,r,o,s=this.getListenersAsObject(e);for(r in s)if(s.hasOwnProperty(r))for(i=s[r].length;i--;)n=s[r][i],n.once===!0&&this.removeListener(e,n.listener),o=n.listener.apply(this,t||[]),o===this._getOnceReturnValue()&&this.removeListener(e,n.listener);return this},i.trigger=n("emitEvent"),i.emit=function(e){var t=Array.prototype.slice.call(arguments,1);return this.emitEvent(e,t)},i.setOnceReturnValue=function(e){return this._onceReturnValue=e,this},i._getOnceReturnValue=function(){return this.hasOwnProperty("_onceReturnValue")?this._onceReturnValue:!0},i._getEvents=function(){return this._events||(this._events={})},e.noConflict=function(){return r.EventEmitter=o,e},"function"==typeof define&&define.amd?define("eventEmitter/EventEmitter",[],function(){return e}):"object"==typeof module&&module.exports?module.exports=e:this.EventEmitter=e}).call(this),function(e){function t(t){var n=e.event;return n.target=n.target||n.srcElement||t,n}var n=document.documentElement,i=function(){};n.addEventListener?i=function(e,t,n){e.addEventListener(t,n,!1)}:n.attachEvent&&(i=function(e,n,i){e[n+i]=i.handleEvent?function(){var n=t(e);i.handleEvent.call(i,n)}:function(){var n=t(e);i.call(e,n)},e.attachEvent("on"+n,e[n+i])});var r=function(){};n.removeEventListener?r=function(e,t,n){e.removeEventListener(t,n,!1)}:n.detachEvent&&(r=function(e,t,n){e.detachEvent("on"+t,e[t+n]);try{delete e[t+n]}catch(i){e[t+n]=void 0}});var o={bind:i,unbind:r};"function"==typeof define&&define.amd?define("eventie/eventie",o):e.eventie=o}(this),function(e,t){"function"==typeof define&&define.amd?define(["eventEmitter/EventEmitter","eventie/eventie"],function(n,i){return t(e,n,i)}):"object"==typeof exports?module.exports=t(e,require("wolfy87-eventemitter"),require("eventie")):e.imagesLoaded=t(e,e.EventEmitter,e.eventie)}(window,function(e,t,n){function i(e,t){for(var n in t)e[n]=t[n];return e}function r(e){return"[object Array]"===d.call(e)}function o(e){var t=[];if(r(e))t=e;else if("number"==typeof e.length)for(var n=0,i=e.length;i>n;n++)t.push(e[n]);else t.push(e);return t}function s(e,t,n){if(!(this instanceof s))return new s(e,t);"string"==typeof e&&(e=document.querySelectorAll(e)),this.elements=o(e),this.options=i({},this.options),"function"==typeof t?n=t:i(this.options,t),n&&this.on("always",n),this.getImages(),a&&(this.jqDeferred=new a.Deferred);var r=this;setTimeout(function(){r.check()})}function f(e){this.img=e}function c(e){this.src=e,v[e]=this}var a=e.jQuery,u=e.console,h=u!==void 0,d=Object.prototype.toString;s.prototype=new t,s.prototype.options={},s.prototype.getImages=function(){this.images=[];for(var e=0,t=this.elements.length;t>e;e++){var n=this.elements[e];"IMG"===n.nodeName&&this.addImage(n);var i=n.nodeType;if(i&&(1===i||9===i||11===i))for(var r=n.querySelectorAll("img"),o=0,s=r.length;s>o;o++){var f=r[o];this.addImage(f)}}},s.prototype.addImage=function(e){var t=new f(e);this.images.push(t)},s.prototype.check=function(){function e(e,r){return t.options.debug&&h&&u.log("confirm",e,r),t.progress(e),n++,n===i&&t.complete(),!0}var t=this,n=0,i=this.images.length;if(this.hasAnyBroken=!1,!i)return this.complete(),void 0;for(var r=0;i>r;r++){var o=this.images[r];o.on("confirm",e),o.check()}},s.prototype.progress=function(e){this.hasAnyBroken=this.hasAnyBroken||!e.isLoaded;var t=this;setTimeout(function(){t.emit("progress",t,e),t.jqDeferred&&t.jqDeferred.notify&&t.jqDeferred.notify(t,e)})},s.prototype.complete=function(){var e=this.hasAnyBroken?"fail":"done";this.isComplete=!0;var t=this;setTimeout(function(){if(t.emit(e,t),t.emit("always",t),t.jqDeferred){var n=t.hasAnyBroken?"reject":"resolve";t.jqDeferred[n](t)}})},a&&(a.fn.imagesLoaded=function(e,t){var n=new s(this,e,t);return n.jqDeferred.promise(a(this))}),f.prototype=new t,f.prototype.check=function(){var e=v[this.img.src]||new c(this.img.src);if(e.isConfirmed)return this.confirm(e.isLoaded,"cached was confirmed"),void 0;if(this.img.complete&&void 0!==this.img.naturalWidth)return this.confirm(0!==this.img.naturalWidth,"naturalWidth"),void 0;var t=this;e.on("confirm",function(e,n){return t.confirm(e.isLoaded,n),!0}),e.check()},f.prototype.confirm=function(e,t){this.isLoaded=e,this.emit("confirm",this,t)};var v={};return c.prototype=new t,c.prototype.check=function(){if(!this.isChecked){var e=new Image;n.bind(e,"load",this),n.bind(e,"error",this),e.src=this.src,this.isChecked=!0}},c.prototype.handleEvent=function(e){var t="on"+e.type;this[t]&&this[t](e)},c.prototype.onload=function(e){this.confirm(!0,"onload"),this.unbindProxyEvents(e)},c.prototype.onerror=function(e){this.confirm(!1,"onerror"),this.unbindProxyEvents(e)},c.prototype.confirm=function(e,t){this.isConfirmed=!0,this.isLoaded=e,this.emit("confirm",this,t)},c.prototype.unbindProxyEvents=function(e){n.unbind(e.target,"load",this),n.unbind(e.target,"error",this)},s}); \ No newline at end of file +!function(e,t){"function"==typeof define&&define.amd?define("ev-emitter/ev-emitter",t):"object"==typeof module&&module.exports?module.exports=t():e.EvEmitter=t()}("undefined"!=typeof window?window:this,function(){function e(){}var t=e.prototype;return t.on=function(e,t){if(e&&t){var i=this._events=this._events||{},n=i[e]=i[e]||[];return n.indexOf(t)==-1&&n.push(t),this}},t.once=function(e,t){if(e&&t){this.on(e,t);var i=this._onceEvents=this._onceEvents||{},n=i[e]=i[e]||{};return n[t]=!0,this}},t.off=function(e,t){var i=this._events&&this._events[e];if(i&&i.length){var n=i.indexOf(t);return n!=-1&&i.splice(n,1),this}},t.emitEvent=function(e,t){var i=this._events&&this._events[e];if(i&&i.length){i=i.slice(0),t=t||[];for(var n=this._onceEvents&&this._onceEvents[e],o=0;o elements + // (i.e., `typeof document.createElement( "object" ) === "function"`). + // We don't want to classify *any* DOM node as a function. + return typeof obj === "function" && typeof obj.nodeType !== "number"; }; -jQuery.fn = jQuery.prototype = { - - // The current version of jQuery being used - jquery: version, - - constructor: jQuery, - - // Start with an empty selector - selector: "", - - // The default length of a jQuery object is 0 - length: 0, - - toArray: function() { - return slice.call( this ); - }, - // Get the Nth element in the matched element set OR - // Get the whole matched element set as a clean array - get: function( num ) { - return num != null ? +var isWindow = function isWindow( obj ) { + return obj != null && obj === obj.window; + }; - // Return just the one element from the set - ( num < 0 ? this[ num + this.length ] : this[ num ] ) : - // Return all the elements in a clean array - slice.call( this ); - }, - - // Take an array of elements and push it onto the stack - // (returning the new matched element set) - pushStack: function( elems ) { - - // Build a new jQuery matched element set - var ret = jQuery.merge( this.constructor(), elems ); +var document = window.document; - // Add the old object onto the stack (as a reference) - ret.prevObject = this; - ret.context = this.context; - // Return the newly-formed element set - return ret; - }, - // Execute a callback for every element in the matched set. - each: function( callback ) { - return jQuery.each( this, callback ); - }, + var preservedScriptAttributes = { + type: true, + src: true, + nonce: true, + noModule: true + }; + + function DOMEval( code, node, doc ) { + doc = doc || document; + + var i, val, + script = doc.createElement( "script" ); + + script.text = code; + if ( node ) { + for ( i in preservedScriptAttributes ) { + + // Support: Firefox 64+, Edge 18+ + // Some browsers don't support the "nonce" property on scripts. + // On the other hand, just using `getAttribute` is not enough as + // the `nonce` attribute is reset to an empty string whenever it + // becomes browsing-context connected. + // See https://github.com/whatwg/html/issues/2369 + // See https://html.spec.whatwg.org/#nonce-attributes + // The `node.getAttribute` check was added for the sake of + // `jQuery.globalEval` so that it can fake a nonce-containing node + // via an object. + val = node[ i ] || node.getAttribute && node.getAttribute( i ); + if ( val ) { + script.setAttribute( i, val ); + } + } + } + doc.head.appendChild( script ).parentNode.removeChild( script ); + } + + +function toType( obj ) { + if ( obj == null ) { + return obj + ""; + } + + // Support: Android <=2.3 only (functionish RegExp) + return typeof obj === "object" || typeof obj === "function" ? + class2type[ toString.call( obj ) ] || "object" : + typeof obj; +} +/* global Symbol */ +// Defining this global in .eslintrc.json would create a danger of using the global +// unguarded in another place, it seems safer to define global only for this module - map: function( callback ) { - return this.pushStack( jQuery.map( this, function( elem, i ) { - return callback.call( elem, i, elem ); - } ) ); - }, - slice: function() { - return this.pushStack( slice.apply( this, arguments ) ); - }, - first: function() { - return this.eq( 0 ); - }, +var + version = "3.5.1", - last: function() { - return this.eq( -1 ); - }, + // Define a local copy of jQuery + jQuery = function( selector, context ) { - eq: function( i ) { - var len = this.length, - j = +i + ( i < 0 ? len : 0 ); - return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] ); - }, + // The jQuery object is actually just the init constructor 'enhanced' + // Need init if jQuery is called (just allow error to be thrown if not included) + return new jQuery.fn.init( selector, context ); + }; - end: function() { - return this.prevObject || this.constructor(); - }, +jQuery.fn = jQuery.prototype = { - // For internal use only. - // Behaves like an Array's method, not like a jQuery method. - push: push, - sort: arr.sort, - splice: arr.splice + // The current version of jQuery being used + jquery: version, + + constructor: jQuery, + + // The default length of a jQuery object is 0 + length: 0, + + toArray: function() { + return slice.call( this ); + }, + + // Get the Nth element in the matched element set OR + // Get the whole matched element set as a clean array + get: function( num ) { + + // Return all the elements in a clean array + if ( num == null ) { + return slice.call( this ); + } + + // Return just the one element from the set + return num < 0 ? this[ num + this.length ] : this[ num ]; + }, + + // Take an array of elements and push it onto the stack + // (returning the new matched element set) + pushStack: function( elems ) { + + // Build a new jQuery matched element set + var ret = jQuery.merge( this.constructor(), elems ); + + // Add the old object onto the stack (as a reference) + ret.prevObject = this; + + // Return the newly-formed element set + return ret; + }, + + // Execute a callback for every element in the matched set. + each: function( callback ) { + return jQuery.each( this, callback ); + }, + + map: function( callback ) { + return this.pushStack( jQuery.map( this, function( elem, i ) { + return callback.call( elem, i, elem ); + } ) ); + }, + + slice: function() { + return this.pushStack( slice.apply( this, arguments ) ); + }, + + first: function() { + return this.eq( 0 ); + }, + + last: function() { + return this.eq( -1 ); + }, + + even: function() { + return this.pushStack( jQuery.grep( this, function( _elem, i ) { + return ( i + 1 ) % 2; + } ) ); + }, + + odd: function() { + return this.pushStack( jQuery.grep( this, function( _elem, i ) { + return i % 2; + } ) ); + }, + + eq: function( i ) { + var len = this.length, + j = +i + ( i < 0 ? len : 0 ); + return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] ); + }, + + end: function() { + return this.prevObject || this.constructor(); + }, + + // For internal use only. + // Behaves like an Array's method, not like a jQuery method. + push: push, + sort: arr.sort, + splice: arr.splice }; jQuery.extend = jQuery.fn.extend = function() { - var options, name, src, copy, copyIsArray, clone, - target = arguments[ 0 ] || {}, - i = 1, - length = arguments.length, - deep = false; - - // Handle a deep copy situation - if ( typeof target === "boolean" ) { - deep = target; - - // Skip the boolean and the target - target = arguments[ i ] || {}; - i++; - } - - // Handle case when target is a string or something (possible in deep copy) - if ( typeof target !== "object" && !jQuery.isFunction( target ) ) { - target = {}; - } - - // Extend jQuery itself if only one argument is passed - if ( i === length ) { - target = this; - i--; - } - - for ( ; i < length; i++ ) { - - // Only deal with non-null/undefined values - if ( ( options = arguments[ i ] ) != null ) { - - // Extend the base object - for ( name in options ) { - src = target[ name ]; - copy = options[ name ]; - - // Prevent never-ending loop - if ( target === copy ) { - continue; - } - - // Recurse if we're merging plain objects or arrays - if ( deep && copy && ( jQuery.isPlainObject( copy ) || - ( copyIsArray = jQuery.isArray( copy ) ) ) ) { - - if ( copyIsArray ) { - copyIsArray = false; - clone = src && jQuery.isArray( src ) ? src : []; - - } else { - clone = src && jQuery.isPlainObject( src ) ? src : {}; - } - - // Never move original objects, clone them - target[ name ] = jQuery.extend( deep, clone, copy ); - - // Don't bring in undefined values - } else if ( copy !== undefined ) { - target[ name ] = copy; - } - } - } - } - - // Return the modified object - return target; + var options, name, src, copy, copyIsArray, clone, + target = arguments[ 0 ] || {}, + i = 1, + length = arguments.length, + deep = false; + + // Handle a deep copy situation + if ( typeof target === "boolean" ) { + deep = target; + + // Skip the boolean and the target + target = arguments[ i ] || {}; + i++; + } + + // Handle case when target is a string or something (possible in deep copy) + if ( typeof target !== "object" && !isFunction( target ) ) { + target = {}; + } + + // Extend jQuery itself if only one argument is passed + if ( i === length ) { + target = this; + i--; + } + + for ( ; i < length; i++ ) { + + // Only deal with non-null/undefined values + if ( ( options = arguments[ i ] ) != null ) { + + // Extend the base object + for ( name in options ) { + copy = options[ name ]; + + // Prevent Object.prototype pollution + // Prevent never-ending loop + if ( name === "__proto__" || target === copy ) { + continue; + } + + // Recurse if we're merging plain objects or arrays + if ( deep && copy && ( jQuery.isPlainObject( copy ) || + ( copyIsArray = Array.isArray( copy ) ) ) ) { + src = target[ name ]; + + // Ensure proper type for the source value + if ( copyIsArray && !Array.isArray( src ) ) { + clone = []; + } else if ( !copyIsArray && !jQuery.isPlainObject( src ) ) { + clone = {}; + } else { + clone = src; + } + copyIsArray = false; + + // Never move original objects, clone them + target[ name ] = jQuery.extend( deep, clone, copy ); + + // Don't bring in undefined values + } else if ( copy !== undefined ) { + target[ name ] = copy; + } + } + } + } + + // Return the modified object + return target; }; jQuery.extend( { - // Unique for each copy of jQuery on the page - expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ), - - // Assume jQuery is ready without the ready module - isReady: true, - - error: function( msg ) { - throw new Error( msg ); - }, - - noop: function() {}, - - isFunction: function( obj ) { - return jQuery.type( obj ) === "function"; - }, - - isArray: Array.isArray, - - isWindow: function( obj ) { - return obj != null && obj === obj.window; - }, - - isNumeric: function( obj ) { - - // parseFloat NaNs numeric-cast false positives (null|true|false|"") - // ...but misinterprets leading-number strings, particularly hex literals ("0x...") - // subtraction forces infinities to NaN - // adding 1 corrects loss of precision from parseFloat (#15100) - var realStringObj = obj && obj.toString(); - return !jQuery.isArray( obj ) && ( realStringObj - parseFloat( realStringObj ) + 1 ) >= 0; - }, - - isPlainObject: function( obj ) { - - // Not plain objects: - // - Any object or value whose internal [[Class]] property is not "[object Object]" - // - DOM nodes - // - window - if ( jQuery.type( obj ) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) { - return false; - } - - if ( obj.constructor && - !hasOwn.call( obj.constructor.prototype, "isPrototypeOf" ) ) { - return false; - } - - // If the function hasn't returned already, we're confident that - // |obj| is a plain object, created by {} or constructed with new Object - return true; - }, - - isEmptyObject: function( obj ) { - var name; - for ( name in obj ) { - return false; - } - return true; - }, - - type: function( obj ) { - if ( obj == null ) { - return obj + ""; - } - - // Support: Android<4.0, iOS<6 (functionish RegExp) - return typeof obj === "object" || typeof obj === "function" ? - class2type[ toString.call( obj ) ] || "object" : - typeof obj; - }, - - // Evaluates a script in a global context - globalEval: function( code ) { - var script, - indirect = eval; - - code = jQuery.trim( code ); - - if ( code ) { - - // If the code includes a valid, prologue position - // strict mode pragma, execute code by injecting a - // script tag into the document. - if ( code.indexOf( "use strict" ) === 1 ) { - script = document.createElement( "script" ); - script.text = code; - document.head.appendChild( script ).parentNode.removeChild( script ); - } else { - - // Otherwise, avoid the DOM node creation, insertion - // and removal by using an indirect global eval - - indirect( code ); - } - } - }, - - // Convert dashed to camelCase; used by the css and data modules - // Support: IE9-11+ - // Microsoft forgot to hump their vendor prefix (#9572) - camelCase: function( string ) { - return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); - }, - - nodeName: function( elem, name ) { - return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); - }, - - each: function( obj, callback ) { - var length, i = 0; - - if ( isArrayLike( obj ) ) { - length = obj.length; - for ( ; i < length; i++ ) { - if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { - break; - } - } - } else { - for ( i in obj ) { - if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { - break; - } - } - } - - return obj; - }, - - // Support: Android<4.1 - trim: function( text ) { - return text == null ? - "" : - ( text + "" ).replace( rtrim, "" ); - }, - - // results is for internal usage only - makeArray: function( arr, results ) { - var ret = results || []; - - if ( arr != null ) { - if ( isArrayLike( Object( arr ) ) ) { - jQuery.merge( ret, - typeof arr === "string" ? - [ arr ] : arr - ); - } else { - push.call( ret, arr ); - } - } - - return ret; - }, - - inArray: function( elem, arr, i ) { - return arr == null ? -1 : indexOf.call( arr, elem, i ); - }, - - merge: function( first, second ) { - var len = +second.length, - j = 0, - i = first.length; - - for ( ; j < len; j++ ) { - first[ i++ ] = second[ j ]; - } - - first.length = i; - - return first; - }, - - grep: function( elems, callback, invert ) { - var callbackInverse, - matches = [], - i = 0, - length = elems.length, - callbackExpect = !invert; - - // Go through the array, only saving the items - // that pass the validator function - for ( ; i < length; i++ ) { - callbackInverse = !callback( elems[ i ], i ); - if ( callbackInverse !== callbackExpect ) { - matches.push( elems[ i ] ); - } - } - - return matches; - }, - - // arg is for internal usage only - map: function( elems, callback, arg ) { - var length, value, - i = 0, - ret = []; - - // Go through the array, translating each of the items to their new values - if ( isArrayLike( elems ) ) { - length = elems.length; - for ( ; i < length; i++ ) { - value = callback( elems[ i ], i, arg ); - - if ( value != null ) { - ret.push( value ); - } - } - - // Go through every key on the object, - } else { - for ( i in elems ) { - value = callback( elems[ i ], i, arg ); - - if ( value != null ) { - ret.push( value ); - } - } - } - - // Flatten any nested arrays - return concat.apply( [], ret ); - }, - - // A global GUID counter for objects - guid: 1, - - // Bind a function to a context, optionally partially applying any - // arguments. - proxy: function( fn, context ) { - var tmp, args, proxy; - - if ( typeof context === "string" ) { - tmp = fn[ context ]; - context = fn; - fn = tmp; - } - - // Quick check to determine if target is callable, in the spec - // this throws a TypeError, but we will just return undefined. - if ( !jQuery.isFunction( fn ) ) { - return undefined; - } - - // Simulated bind - args = slice.call( arguments, 2 ); - proxy = function() { - return fn.apply( context || this, args.concat( slice.call( arguments ) ) ); - }; - - // Set the guid of unique handler to the same of original handler, so it can be removed - proxy.guid = fn.guid = fn.guid || jQuery.guid++; - - return proxy; - }, - - now: Date.now, - - // jQuery.support is not used in Core but other projects attach their - // properties to it so it needs to exist. - support: support + // Unique for each copy of jQuery on the page + expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ), + + // Assume jQuery is ready without the ready module + isReady: true, + + error: function( msg ) { + throw new Error( msg ); + }, + + noop: function() {}, + + isPlainObject: function( obj ) { + var proto, Ctor; + + // Detect obvious negatives + // Use toString instead of jQuery.type to catch host objects + if ( !obj || toString.call( obj ) !== "[object Object]" ) { + return false; + } + + proto = getProto( obj ); + + // Objects with no prototype (e.g., `Object.create( null )`) are plain + if ( !proto ) { + return true; + } + + // Objects with prototype are plain iff they were constructed by a global Object function + Ctor = hasOwn.call( proto, "constructor" ) && proto.constructor; + return typeof Ctor === "function" && fnToString.call( Ctor ) === ObjectFunctionString; + }, + + isEmptyObject: function( obj ) { + var name; + + for ( name in obj ) { + return false; + } + return true; + }, + + // Evaluates a script in a provided context; falls back to the global one + // if not specified. + globalEval: function( code, options, doc ) { + DOMEval( code, { nonce: options && options.nonce }, doc ); + }, + + each: function( obj, callback ) { + var length, i = 0; + + if ( isArrayLike( obj ) ) { + length = obj.length; + for ( ; i < length; i++ ) { + if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { + break; + } + } + } else { + for ( i in obj ) { + if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { + break; + } + } + } + + return obj; + }, + + // results is for internal usage only + makeArray: function( arr, results ) { + var ret = results || []; + + if ( arr != null ) { + if ( isArrayLike( Object( arr ) ) ) { + jQuery.merge( ret, + typeof arr === "string" ? + [ arr ] : arr + ); + } else { + push.call( ret, arr ); + } + } + + return ret; + }, + + inArray: function( elem, arr, i ) { + return arr == null ? -1 : indexOf.call( arr, elem, i ); + }, + + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + merge: function( first, second ) { + var len = +second.length, + j = 0, + i = first.length; + + for ( ; j < len; j++ ) { + first[ i++ ] = second[ j ]; + } + + first.length = i; + + return first; + }, + + grep: function( elems, callback, invert ) { + var callbackInverse, + matches = [], + i = 0, + length = elems.length, + callbackExpect = !invert; + + // Go through the array, only saving the items + // that pass the validator function + for ( ; i < length; i++ ) { + callbackInverse = !callback( elems[ i ], i ); + if ( callbackInverse !== callbackExpect ) { + matches.push( elems[ i ] ); + } + } + + return matches; + }, + + // arg is for internal usage only + map: function( elems, callback, arg ) { + var length, value, + i = 0, + ret = []; + + // Go through the array, translating each of the items to their new values + if ( isArrayLike( elems ) ) { + length = elems.length; + for ( ; i < length; i++ ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret.push( value ); + } + } + + // Go through every key on the object, + } else { + for ( i in elems ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret.push( value ); + } + } + } + + // Flatten any nested arrays + return flat( ret ); + }, + + // A global GUID counter for objects + guid: 1, + + // jQuery.support is not used in Core but other projects attach their + // properties to it so it needs to exist. + support: support } ); -// JSHint would error on this code due to the Symbol not being defined in ES5. -// Defining this global in .jshintrc would create a danger of using the global -// unguarded in another place, it seems safer to just disable JSHint for these -// three lines. -/* jshint ignore: start */ if ( typeof Symbol === "function" ) { - jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ]; + jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ]; } -/* jshint ignore: end */ // Populate the class2type map jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ), -function( i, name ) { - class2type[ "[object " + name + "]" ] = name.toLowerCase(); +function( _i, name ) { + class2type[ "[object " + name + "]" ] = name.toLowerCase(); } ); function isArrayLike( obj ) { - // Support: iOS 8.2 (not reproducible in simulator) - // `in` check used to prevent JIT error (gh-2145) - // hasOwn isn't used here due to false negatives - // regarding Nodelist length in IE - var length = !!obj && "length" in obj && obj.length, - type = jQuery.type( obj ); + // Support: real iOS 8.2 only (not reproducible in simulator) + // `in` check used to prevent JIT error (gh-2145) + // hasOwn isn't used here due to false negatives + // regarding Nodelist length in IE + var length = !!obj && "length" in obj && obj.length, + type = toType( obj ); - if ( type === "function" || jQuery.isWindow( obj ) ) { - return false; - } + if ( isFunction( obj ) || isWindow( obj ) ) { + return false; + } - return type === "array" || length === 0 || - typeof length === "number" && length > 0 && ( length - 1 ) in obj; + return type === "array" || length === 0 || + typeof length === "number" && length > 0 && ( length - 1 ) in obj; } var Sizzle = /*! - * Sizzle CSS Selector Engine v2.2.1 + * Sizzle CSS Selector Engine v2.3.5 * https://sizzlejs.com/ * - * Copyright jQuery Foundation and other contributors + * Copyright JS Foundation and other contributors * Released under the MIT license - * https://jquery.org/license + * https://js.foundation/ * - * Date: 2015-10-17 + * Date: 2020-03-14 */ -(function( window ) { - +( function( window ) { var i, - support, - Expr, - getText, - isXML, - tokenize, - compile, - select, - outermostContext, - sortInput, - hasDuplicate, - - // Local document vars - setDocument, - document, - docElem, - documentIsHTML, - rbuggyQSA, - rbuggyMatches, - matches, - contains, - - // Instance-specific data - expando = "sizzle" + 1 * new Date(), - preferredDoc = window.document, - dirruns = 0, - done = 0, - classCache = createCache(), - tokenCache = createCache(), - compilerCache = createCache(), - sortOrder = function( a, b ) { - if ( a === b ) { - hasDuplicate = true; - } - return 0; - }, - - // General-purpose constants - MAX_NEGATIVE = 1 << 31, - - // Instance methods - hasOwn = ({}).hasOwnProperty, - arr = [], - pop = arr.pop, - push_native = arr.push, - push = arr.push, - slice = arr.slice, - // Use a stripped-down indexOf as it's faster than native - // https://jsperf.com/thor-indexof-vs-for/5 - indexOf = function( list, elem ) { - var i = 0, - len = list.length; - for ( ; i < len; i++ ) { - if ( list[i] === elem ) { - return i; - } - } - return -1; - }, - - booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped", - - // Regular expressions - - // https://www.w3.org/TR/css3-selectors/#whitespace - whitespace = "[\\x20\\t\\r\\n\\f]", - - // https://www.w3.org/TR/CSS21/syndata.html#value-def-identifier - identifier = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+", - - // Attribute selectors: https://www.w3.org/TR/selectors/#attribute-selectors - attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace + - // Operator (capture 2) - "*([*^$|!~]?=)" + whitespace + - // "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]" - "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace + - "*\\]", - - pseudos = ":(" + identifier + ")(?:\\((" + - // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments: - // 1. quoted (capture 3; capture 4 or capture 5) - "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" + - // 2. simple (capture 6) - "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" + - // 3. anything else (capture 2) - ".*" + - ")\\)|)", - - // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter - rwhitespace = new RegExp( whitespace + "+", "g" ), - rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ), - - rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), - rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ), - - rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ), - - rpseudo = new RegExp( pseudos ), - ridentifier = new RegExp( "^" + identifier + "$" ), - - matchExpr = { - "ID": new RegExp( "^#(" + identifier + ")" ), - "CLASS": new RegExp( "^\\.(" + identifier + ")" ), - "TAG": new RegExp( "^(" + identifier + "|[*])" ), - "ATTR": new RegExp( "^" + attributes ), - "PSEUDO": new RegExp( "^" + pseudos ), - "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace + - "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace + - "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), - "bool": new RegExp( "^(?:" + booleans + ")$", "i" ), - // For use in libraries implementing .is() - // We use this for POS matching in `select` - "needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + - whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" ) - }, - - rinputs = /^(?:input|select|textarea|button)$/i, - rheader = /^h\d$/i, - - rnative = /^[^{]+\{\s*\[native \w/, - - // Easily-parseable/retrievable ID or TAG or CLASS selectors - rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, - - rsibling = /[+~]/, - rescape = /'|\\/g, - - // CSS escapes https://www.w3.org/TR/CSS21/syndata.html#escaped-characters - runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ), - funescape = function( _, escaped, escapedWhitespace ) { - var high = "0x" + escaped - 0x10000; - // NaN means non-codepoint - // Support: Firefox<24 - // Workaround erroneous numeric interpretation of +"0x" - return high !== high || escapedWhitespace ? - escaped : - high < 0 ? - // BMP codepoint - String.fromCharCode( high + 0x10000 ) : - // Supplemental Plane codepoint (surrogate pair) - String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); - }, - - // Used for iframes - // See setDocument() - // Removing the function wrapper causes a "Permission Denied" - // error in IE - unloadHandler = function() { - setDocument(); - }; + support, + Expr, + getText, + isXML, + tokenize, + compile, + select, + outermostContext, + sortInput, + hasDuplicate, + + // Local document vars + setDocument, + document, + docElem, + documentIsHTML, + rbuggyQSA, + rbuggyMatches, + matches, + contains, + + // Instance-specific data + expando = "sizzle" + 1 * new Date(), + preferredDoc = window.document, + dirruns = 0, + done = 0, + classCache = createCache(), + tokenCache = createCache(), + compilerCache = createCache(), + nonnativeSelectorCache = createCache(), + sortOrder = function( a, b ) { + if ( a === b ) { + hasDuplicate = true; + } + return 0; + }, + + // Instance methods + hasOwn = ( {} ).hasOwnProperty, + arr = [], + pop = arr.pop, + pushNative = arr.push, + push = arr.push, + slice = arr.slice, + + // Use a stripped-down indexOf as it's faster than native + // https://jsperf.com/thor-indexof-vs-for/5 + indexOf = function( list, elem ) { + var i = 0, + len = list.length; + for ( ; i < len; i++ ) { + if ( list[ i ] === elem ) { + return i; + } + } + return -1; + }, + + booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|" + + "ismap|loop|multiple|open|readonly|required|scoped", + + // Regular expressions + + // http://www.w3.org/TR/css3-selectors/#whitespace + whitespace = "[\\x20\\t\\r\\n\\f]", + + // https://www.w3.org/TR/css-syntax-3/#ident-token-diagram + identifier = "(?:\\\\[\\da-fA-F]{1,6}" + whitespace + + "?|\\\\[^\\r\\n\\f]|[\\w-]|[^\0-\\x7f])+", + + // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors + attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace + + + // Operator (capture 2) + "*([*^$|!~]?=)" + whitespace + + + // "Attribute values must be CSS identifiers [capture 5] + // or strings [capture 3 or capture 4]" + "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + + whitespace + "*\\]", + + pseudos = ":(" + identifier + ")(?:\\((" + + + // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments: + // 1. quoted (capture 3; capture 4 or capture 5) + "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" + + + // 2. simple (capture 6) + "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" + + + // 3. anything else (capture 2) + ".*" + + ")\\)|)", + + // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter + rwhitespace = new RegExp( whitespace + "+", "g" ), + rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + + whitespace + "+$", "g" ), + + rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), + rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + + "*" ), + rdescend = new RegExp( whitespace + "|>" ), + + rpseudo = new RegExp( pseudos ), + ridentifier = new RegExp( "^" + identifier + "$" ), + + matchExpr = { + "ID": new RegExp( "^#(" + identifier + ")" ), + "CLASS": new RegExp( "^\\.(" + identifier + ")" ), + "TAG": new RegExp( "^(" + identifier + "|[*])" ), + "ATTR": new RegExp( "^" + attributes ), + "PSEUDO": new RegExp( "^" + pseudos ), + "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + + whitespace + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + + whitespace + "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), + "bool": new RegExp( "^(?:" + booleans + ")$", "i" ), + + // For use in libraries implementing .is() + // We use this for POS matching in `select` + "needsContext": new RegExp( "^" + whitespace + + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + whitespace + + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" ) + }, + + rhtml = /HTML$/i, + rinputs = /^(?:input|select|textarea|button)$/i, + rheader = /^h\d$/i, + + rnative = /^[^{]+\{\s*\[native \w/, + + // Easily-parseable/retrievable ID or TAG or CLASS selectors + rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, + + rsibling = /[+~]/, + + // CSS escapes + // http://www.w3.org/TR/CSS21/syndata.html#escaped-characters + runescape = new RegExp( "\\\\[\\da-fA-F]{1,6}" + whitespace + "?|\\\\([^\\r\\n\\f])", "g" ), + funescape = function( escape, nonHex ) { + var high = "0x" + escape.slice( 1 ) - 0x10000; + + return nonHex ? + + // Strip the backslash prefix from a non-hex escape sequence + nonHex : + + // Replace a hexadecimal escape sequence with the encoded Unicode code point + // Support: IE <=11+ + // For values outside the Basic Multilingual Plane (BMP), manually construct a + // surrogate pair + high < 0 ? + String.fromCharCode( high + 0x10000 ) : + String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); + }, + + // CSS string/identifier serialization + // https://drafts.csswg.org/cssom/#common-serializing-idioms + rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g, + fcssescape = function( ch, asCodePoint ) { + if ( asCodePoint ) { + + // U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER + if ( ch === "\0" ) { + return "\uFFFD"; + } + + // Control characters and (dependent upon position) numbers get escaped as code points + return ch.slice( 0, -1 ) + "\\" + + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " "; + } + + // Other potentially-special ASCII characters get backslash-escaped + return "\\" + ch; + }, + + // Used for iframes + // See setDocument() + // Removing the function wrapper causes a "Permission Denied" + // error in IE + unloadHandler = function() { + setDocument(); + }, + + inDisabledFieldset = addCombinator( + function( elem ) { + return elem.disabled === true && elem.nodeName.toLowerCase() === "fieldset"; + }, + { dir: "parentNode", next: "legend" } + ); // Optimize for push.apply( _, NodeList ) try { - push.apply( - (arr = slice.call( preferredDoc.childNodes )), - preferredDoc.childNodes - ); - // Support: Android<4.0 - // Detect silently failing push.apply - arr[ preferredDoc.childNodes.length ].nodeType; + push.apply( + ( arr = slice.call( preferredDoc.childNodes ) ), + preferredDoc.childNodes + ); + + // Support: Android<4.0 + // Detect silently failing push.apply + // eslint-disable-next-line no-unused-expressions + arr[ preferredDoc.childNodes.length ].nodeType; } catch ( e ) { - push = { apply: arr.length ? - - // Leverage slice if possible - function( target, els ) { - push_native.apply( target, slice.call(els) ); - } : - - // Support: IE<9 - // Otherwise append directly - function( target, els ) { - var j = target.length, - i = 0; - // Can't trust NodeList.length - while ( (target[j++] = els[i++]) ) {} - target.length = j - 1; - } - }; + push = { apply: arr.length ? + + // Leverage slice if possible + function( target, els ) { + pushNative.apply( target, slice.call( els ) ); + } : + + // Support: IE<9 + // Otherwise append directly + function( target, els ) { + var j = target.length, + i = 0; + + // Can't trust NodeList.length + while ( ( target[ j++ ] = els[ i++ ] ) ) {} + target.length = j - 1; + } + }; } function Sizzle( selector, context, results, seed ) { - var m, i, elem, nid, nidselect, match, groups, newSelector, - newContext = context && context.ownerDocument, - - // nodeType defaults to 9, since context defaults to document - nodeType = context ? context.nodeType : 9; - - results = results || []; - - // Return early from calls with invalid selector or context - if ( typeof selector !== "string" || !selector || - nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) { - - return results; - } - - // Try to shortcut find operations (as opposed to filters) in HTML documents - if ( !seed ) { - - if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) { - setDocument( context ); - } - context = context || document; - - if ( documentIsHTML ) { - - // If the selector is sufficiently simple, try using a "get*By*" DOM method - // (excepting DocumentFragment context, where the methods don't exist) - if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) { - - // ID selector - if ( (m = match[1]) ) { - - // Document context - if ( nodeType === 9 ) { - if ( (elem = context.getElementById( m )) ) { - - // Support: IE, Opera, Webkit - // TODO: identify versions - // getElementById can match elements by name instead of ID - if ( elem.id === m ) { - results.push( elem ); - return results; - } - } else { - return results; - } - - // Element context - } else { - - // Support: IE, Opera, Webkit - // TODO: identify versions - // getElementById can match elements by name instead of ID - if ( newContext && (elem = newContext.getElementById( m )) && - contains( context, elem ) && - elem.id === m ) { - - results.push( elem ); - return results; - } - } - - // Type selector - } else if ( match[2] ) { - push.apply( results, context.getElementsByTagName( selector ) ); - return results; - - // Class selector - } else if ( (m = match[3]) && support.getElementsByClassName && - context.getElementsByClassName ) { - - push.apply( results, context.getElementsByClassName( m ) ); - return results; - } - } - - // Take advantage of querySelectorAll - if ( support.qsa && - !compilerCache[ selector + " " ] && - (!rbuggyQSA || !rbuggyQSA.test( selector )) ) { - - if ( nodeType !== 1 ) { - newContext = context; - newSelector = selector; - - // qSA looks outside Element context, which is not what we want - // Thanks to Andrew Dupont for this workaround technique - // Support: IE <=8 - // Exclude object elements - } else if ( context.nodeName.toLowerCase() !== "object" ) { - - // Capture the context ID, setting it first if necessary - if ( (nid = context.getAttribute( "id" )) ) { - nid = nid.replace( rescape, "\\$&" ); - } else { - context.setAttribute( "id", (nid = expando) ); - } - - // Prefix every selector in the list - groups = tokenize( selector ); - i = groups.length; - nidselect = ridentifier.test( nid ) ? "#" + nid : "[id='" + nid + "']"; - while ( i-- ) { - groups[i] = nidselect + " " + toSelector( groups[i] ); - } - newSelector = groups.join( "," ); - - // Expand context for sibling selectors - newContext = rsibling.test( selector ) && testContext( context.parentNode ) || - context; - } - - if ( newSelector ) { - try { - push.apply( results, - newContext.querySelectorAll( newSelector ) - ); - return results; - } catch ( qsaError ) { - } finally { - if ( nid === expando ) { - context.removeAttribute( "id" ); - } - } - } - } - } - } - - // All others - return select( selector.replace( rtrim, "$1" ), context, results, seed ); + var m, i, elem, nid, match, groups, newSelector, + newContext = context && context.ownerDocument, + + // nodeType defaults to 9, since context defaults to document + nodeType = context ? context.nodeType : 9; + + results = results || []; + + // Return early from calls with invalid selector or context + if ( typeof selector !== "string" || !selector || + nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) { + + return results; + } + + // Try to shortcut find operations (as opposed to filters) in HTML documents + if ( !seed ) { + setDocument( context ); + context = context || document; + + if ( documentIsHTML ) { + + // If the selector is sufficiently simple, try using a "get*By*" DOM method + // (excepting DocumentFragment context, where the methods don't exist) + if ( nodeType !== 11 && ( match = rquickExpr.exec( selector ) ) ) { + + // ID selector + if ( ( m = match[ 1 ] ) ) { + + // Document context + if ( nodeType === 9 ) { + if ( ( elem = context.getElementById( m ) ) ) { + + // Support: IE, Opera, Webkit + // TODO: identify versions + // getElementById can match elements by name instead of ID + if ( elem.id === m ) { + results.push( elem ); + return results; + } + } else { + return results; + } + + // Element context + } else { + + // Support: IE, Opera, Webkit + // TODO: identify versions + // getElementById can match elements by name instead of ID + if ( newContext && ( elem = newContext.getElementById( m ) ) && + contains( context, elem ) && + elem.id === m ) { + + results.push( elem ); + return results; + } + } + + // Type selector + } else if ( match[ 2 ] ) { + push.apply( results, context.getElementsByTagName( selector ) ); + return results; + + // Class selector + } else if ( ( m = match[ 3 ] ) && support.getElementsByClassName && + context.getElementsByClassName ) { + + push.apply( results, context.getElementsByClassName( m ) ); + return results; + } + } + + // Take advantage of querySelectorAll + if ( support.qsa && + !nonnativeSelectorCache[ selector + " " ] && + ( !rbuggyQSA || !rbuggyQSA.test( selector ) ) && + + // Support: IE 8 only + // Exclude object elements + ( nodeType !== 1 || context.nodeName.toLowerCase() !== "object" ) ) { + + newSelector = selector; + newContext = context; + + // qSA considers elements outside a scoping root when evaluating child or + // descendant combinators, which is not what we want. + // In such cases, we work around the behavior by prefixing every selector in the + // list with an ID selector referencing the scope context. + // The technique has to be used as well when a leading combinator is used + // as such selectors are not recognized by querySelectorAll. + // Thanks to Andrew Dupont for this technique. + if ( nodeType === 1 && + ( rdescend.test( selector ) || rcombinators.test( selector ) ) ) { + + // Expand context for sibling selectors + newContext = rsibling.test( selector ) && testContext( context.parentNode ) || + context; + + // We can use :scope instead of the ID hack if the browser + // supports it & if we're not changing the context. + if ( newContext !== context || !support.scope ) { + + // Capture the context ID, setting it first if necessary + if ( ( nid = context.getAttribute( "id" ) ) ) { + nid = nid.replace( rcssescape, fcssescape ); + } else { + context.setAttribute( "id", ( nid = expando ) ); + } + } + + // Prefix every selector in the list + groups = tokenize( selector ); + i = groups.length; + while ( i-- ) { + groups[ i ] = ( nid ? "#" + nid : ":scope" ) + " " + + toSelector( groups[ i ] ); + } + newSelector = groups.join( "," ); + } + + try { + push.apply( results, + newContext.querySelectorAll( newSelector ) + ); + return results; + } catch ( qsaError ) { + nonnativeSelectorCache( selector, true ); + } finally { + if ( nid === expando ) { + context.removeAttribute( "id" ); + } + } + } + } + } + + // All others + return select( selector.replace( rtrim, "$1" ), context, results, seed ); } /** * Create key-value caches of limited size * @returns {function(string, object)} Returns the Object data after storing it on itself with - * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) - * deleting the oldest entry + * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) + * deleting the oldest entry */ function createCache() { - var keys = []; - - function cache( key, value ) { - // Use (key + " ") to avoid collision with native prototype properties (see Issue #157) - if ( keys.push( key + " " ) > Expr.cacheLength ) { - // Only keep the most recent entries - delete cache[ keys.shift() ]; - } - return (cache[ key + " " ] = value); - } - return cache; + var keys = []; + + function cache( key, value ) { + + // Use (key + " ") to avoid collision with native prototype properties (see Issue #157) + if ( keys.push( key + " " ) > Expr.cacheLength ) { + + // Only keep the most recent entries + delete cache[ keys.shift() ]; + } + return ( cache[ key + " " ] = value ); + } + return cache; } /** @@ -889,29 +921,31 @@ function createCache() { * @param {Function} fn The function to mark */ function markFunction( fn ) { - fn[ expando ] = true; - return fn; + fn[ expando ] = true; + return fn; } /** * Support testing using an element - * @param {Function} fn Passed the created div and expects a boolean result + * @param {Function} fn Passed the created element and returns a boolean result */ function assert( fn ) { - var div = document.createElement("div"); - - try { - return !!fn( div ); - } catch (e) { - return false; - } finally { - // Remove from its parent by default - if ( div.parentNode ) { - div.parentNode.removeChild( div ); - } - // release memory in IE - div = null; - } + var el = document.createElement( "fieldset" ); + + try { + return !!fn( el ); + } catch ( e ) { + return false; + } finally { + + // Remove from its parent by default + if ( el.parentNode ) { + el.parentNode.removeChild( el ); + } + + // release memory in IE + el = null; + } } /** @@ -920,12 +954,12 @@ function assert( fn ) { * @param {Function} handler The method that will be applied */ function addHandle( attrs, handler ) { - var arr = attrs.split("|"), - i = arr.length; + var arr = attrs.split( "|" ), + i = arr.length; - while ( i-- ) { - Expr.attrHandle[ arr[i] ] = handler; - } + while ( i-- ) { + Expr.attrHandle[ arr[ i ] ] = handler; + } } /** @@ -935,26 +969,25 @@ function addHandle( attrs, handler ) { * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b */ function siblingCheck( a, b ) { - var cur = b && a, - diff = cur && a.nodeType === 1 && b.nodeType === 1 && - ( ~b.sourceIndex || MAX_NEGATIVE ) - - ( ~a.sourceIndex || MAX_NEGATIVE ); - - // Use IE sourceIndex if available on both nodes - if ( diff ) { - return diff; - } - - // Check if b follows a - if ( cur ) { - while ( (cur = cur.nextSibling) ) { - if ( cur === b ) { - return -1; - } - } - } - - return a ? 1 : -1; + var cur = b && a, + diff = cur && a.nodeType === 1 && b.nodeType === 1 && + a.sourceIndex - b.sourceIndex; + + // Use IE sourceIndex if available on both nodes + if ( diff ) { + return diff; + } + + // Check if b follows a + if ( cur ) { + while ( ( cur = cur.nextSibling ) ) { + if ( cur === b ) { + return -1; + } + } + } + + return a ? 1 : -1; } /** @@ -962,10 +995,10 @@ function siblingCheck( a, b ) { * @param {String} type */ function createInputPseudo( type ) { - return function( elem ) { - var name = elem.nodeName.toLowerCase(); - return name === "input" && elem.type === type; - }; + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === type; + }; } /** @@ -973,10 +1006,66 @@ function createInputPseudo( type ) { * @param {String} type */ function createButtonPseudo( type ) { - return function( elem ) { - var name = elem.nodeName.toLowerCase(); - return (name === "input" || name === "button") && elem.type === type; - }; + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return ( name === "input" || name === "button" ) && elem.type === type; + }; +} + +/** + * Returns a function to use in pseudos for :enabled/:disabled + * @param {Boolean} disabled true for :disabled; false for :enabled + */ +function createDisabledPseudo( disabled ) { + + // Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable + return function( elem ) { + + // Only certain elements can match :enabled or :disabled + // https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled + // https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled + if ( "form" in elem ) { + + // Check for inherited disabledness on relevant non-disabled elements: + // * listed form-associated elements in a disabled fieldset + // https://html.spec.whatwg.org/multipage/forms.html#category-listed + // https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled + // * option elements in a disabled optgroup + // https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled + // All such elements have a "form" property. + if ( elem.parentNode && elem.disabled === false ) { + + // Option elements defer to a parent optgroup if present + if ( "label" in elem ) { + if ( "label" in elem.parentNode ) { + return elem.parentNode.disabled === disabled; + } else { + return elem.disabled === disabled; + } + } + + // Support: IE 6 - 11 + // Use the isDisabled shortcut property to check for disabled fieldset ancestors + return elem.isDisabled === disabled || + + // Where there is no isDisabled, check manually + /* jshint -W018 */ + elem.isDisabled !== !disabled && + inDisabledFieldset( elem ) === disabled; + } + + return elem.disabled === disabled; + + // Try to winnow out elements that can't be disabled before trusting the disabled property. + // Some victims get caught in our net (label, legend, menu, track), but it shouldn't + // even exist on them, let alone have a boolean value. + } else if ( "label" in elem ) { + return elem.disabled === disabled; + } + + // Remaining elements are neither :enabled nor :disabled + return false; + }; } /** @@ -984,21 +1073,21 @@ function createButtonPseudo( type ) { * @param {Function} fn */ function createPositionalPseudo( fn ) { - return markFunction(function( argument ) { - argument = +argument; - return markFunction(function( seed, matches ) { - var j, - matchIndexes = fn( [], seed.length, argument ), - i = matchIndexes.length; - - // Match elements found at the specified indexes - while ( i-- ) { - if ( seed[ (j = matchIndexes[i]) ] ) { - seed[j] = !(matches[j] = seed[j]); - } - } - }); - }); + return markFunction( function( argument ) { + argument = +argument; + return markFunction( function( seed, matches ) { + var j, + matchIndexes = fn( [], seed.length, argument ), + i = matchIndexes.length; + + // Match elements found at the specified indexes + while ( i-- ) { + if ( seed[ ( j = matchIndexes[ i ] ) ] ) { + seed[ j ] = !( matches[ j ] = seed[ j ] ); + } + } + } ); + } ); } /** @@ -1007,7 +1096,7 @@ function createPositionalPseudo( fn ) { * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value */ function testContext( context ) { - return context && typeof context.getElementsByTagName !== "undefined" && context; + return context && typeof context.getElementsByTagName !== "undefined" && context; } // Expose support vars for convenience @@ -1019,10 +1108,13 @@ support = Sizzle.support = {}; * @returns {Boolean} True iff elem is a non-HTML XML node */ isXML = Sizzle.isXML = function( elem ) { - // documentElement is verified for cases where it doesn't yet exist - // (such as loading iframes in IE - #4833) - var documentElement = elem && (elem.ownerDocument || elem).documentElement; - return documentElement ? documentElement.nodeName !== "HTML" : false; + var namespace = elem.namespaceURI, + docElem = ( elem.ownerDocument || elem ).documentElement; + + // Support: IE <=8 + // Assume HTML when documentElement doesn't yet exist, such as inside loading iframes + // https://bugs.jquery.com/ticket/4833 + return !rhtml.test( namespace || docElem && docElem.nodeName || "HTML" ); }; /** @@ -1031,436 +1123,558 @@ isXML = Sizzle.isXML = function( elem ) { * @returns {Object} Returns the current document */ setDocument = Sizzle.setDocument = function( node ) { - var hasCompare, parent, - doc = node ? node.ownerDocument || node : preferredDoc; - - // Return early if doc is invalid or already selected - if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) { - return document; - } - - // Update global variables - document = doc; - docElem = document.documentElement; - documentIsHTML = !isXML( document ); - - // Support: IE 9-11, Edge - // Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936) - if ( (parent = document.defaultView) && parent.top !== parent ) { - // Support: IE 11 - if ( parent.addEventListener ) { - parent.addEventListener( "unload", unloadHandler, false ); - - // Support: IE 9 - 10 only - } else if ( parent.attachEvent ) { - parent.attachEvent( "onunload", unloadHandler ); - } - } - - /* Attributes - ---------------------------------------------------------------------- */ - - // Support: IE<8 - // Verify that getAttribute really returns attributes and not properties - // (excepting IE8 booleans) - support.attributes = assert(function( div ) { - div.className = "i"; - return !div.getAttribute("className"); - }); - - /* getElement(s)By* - ---------------------------------------------------------------------- */ - - // Check if getElementsByTagName("*") returns only elements - support.getElementsByTagName = assert(function( div ) { - div.appendChild( document.createComment("") ); - return !div.getElementsByTagName("*").length; - }); - - // Support: IE<9 - support.getElementsByClassName = rnative.test( document.getElementsByClassName ); - - // Support: IE<10 - // Check if getElementById returns elements by name - // The broken getElementById methods don't pick up programatically-set names, - // so use a roundabout getElementsByName test - support.getById = assert(function( div ) { - docElem.appendChild( div ).id = expando; - return !document.getElementsByName || !document.getElementsByName( expando ).length; - }); - - // ID find and filter - if ( support.getById ) { - Expr.find["ID"] = function( id, context ) { - if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { - var m = context.getElementById( id ); - return m ? [ m ] : []; - } - }; - Expr.filter["ID"] = function( id ) { - var attrId = id.replace( runescape, funescape ); - return function( elem ) { - return elem.getAttribute("id") === attrId; - }; - }; - } else { - // Support: IE6/7 - // getElementById is not reliable as a find shortcut - delete Expr.find["ID"]; - - Expr.filter["ID"] = function( id ) { - var attrId = id.replace( runescape, funescape ); - return function( elem ) { - var node = typeof elem.getAttributeNode !== "undefined" && - elem.getAttributeNode("id"); - return node && node.value === attrId; - }; - }; - } - - // Tag - Expr.find["TAG"] = support.getElementsByTagName ? - function( tag, context ) { - if ( typeof context.getElementsByTagName !== "undefined" ) { - return context.getElementsByTagName( tag ); - - // DocumentFragment nodes don't have gEBTN - } else if ( support.qsa ) { - return context.querySelectorAll( tag ); - } - } : - - function( tag, context ) { - var elem, - tmp = [], - i = 0, - // By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too - results = context.getElementsByTagName( tag ); - - // Filter out possible comments - if ( tag === "*" ) { - while ( (elem = results[i++]) ) { - if ( elem.nodeType === 1 ) { - tmp.push( elem ); - } - } - - return tmp; - } - return results; - }; - - // Class - Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) { - if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) { - return context.getElementsByClassName( className ); - } - }; - - /* QSA/matchesSelector - ---------------------------------------------------------------------- */ - - // QSA and matchesSelector support - - // matchesSelector(:active) reports false when true (IE9/Opera 11.5) - rbuggyMatches = []; - - // qSa(:focus) reports false when true (Chrome 21) - // We allow this because of a bug in IE8/9 that throws an error - // whenever `document.activeElement` is accessed on an iframe - // So, we allow :focus to pass through QSA all the time to avoid the IE error - // See https://bugs.jquery.com/ticket/13378 - rbuggyQSA = []; - - if ( (support.qsa = rnative.test( document.querySelectorAll )) ) { - // Build QSA regex - // Regex strategy adopted from Diego Perini - assert(function( div ) { - // Select is set to empty string on purpose - // This is to test IE's treatment of not explicitly - // setting a boolean content attribute, - // since its presence should be enough - // https://bugs.jquery.com/ticket/12359 - docElem.appendChild( div ).innerHTML = "" + - ""; - - // Support: IE8, Opera 11-12.16 - // Nothing should be selected when empty strings follow ^= or $= or *= - // The test attribute must be unknown in Opera but "safe" for WinRT - // https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section - if ( div.querySelectorAll("[msallowcapture^='']").length ) { - rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" ); - } - - // Support: IE8 - // Boolean attributes and "value" are not treated correctly - if ( !div.querySelectorAll("[selected]").length ) { - rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" ); - } - - // Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+ - if ( !div.querySelectorAll( "[id~=" + expando + "-]" ).length ) { - rbuggyQSA.push("~="); - } - - // Webkit/Opera - :checked should return selected option elements - // https://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked - // IE8 throws error here and will not see later tests - if ( !div.querySelectorAll(":checked").length ) { - rbuggyQSA.push(":checked"); - } - - // Support: Safari 8+, iOS 8+ - // https://bugs.webkit.org/show_bug.cgi?id=136851 - // In-page `selector#id sibing-combinator selector` fails - if ( !div.querySelectorAll( "a#" + expando + "+*" ).length ) { - rbuggyQSA.push(".#.+[+~]"); - } - }); - - assert(function( div ) { - // Support: Windows 8 Native Apps - // The type and name attributes are restricted during .innerHTML assignment - var input = document.createElement("input"); - input.setAttribute( "type", "hidden" ); - div.appendChild( input ).setAttribute( "name", "D" ); - - // Support: IE8 - // Enforce case-sensitivity of name attribute - if ( div.querySelectorAll("[name=d]").length ) { - rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" ); - } - - // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) - // IE8 throws error here and will not see later tests - if ( !div.querySelectorAll(":enabled").length ) { - rbuggyQSA.push( ":enabled", ":disabled" ); - } - - // Opera 10-11 does not throw on post-comma invalid pseudos - div.querySelectorAll("*,:x"); - rbuggyQSA.push(",.*:"); - }); - } - - if ( (support.matchesSelector = rnative.test( (matches = docElem.matches || - docElem.webkitMatchesSelector || - docElem.mozMatchesSelector || - docElem.oMatchesSelector || - docElem.msMatchesSelector) )) ) { - - assert(function( div ) { - // Check to see if it's possible to do matchesSelector - // on a disconnected node (IE 9) - support.disconnectedMatch = matches.call( div, "div" ); - - // This should fail with an exception - // Gecko does not error, returns false instead - matches.call( div, "[s!='']:x" ); - rbuggyMatches.push( "!=", pseudos ); - }); - } - - rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") ); - rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") ); - - /* Contains - ---------------------------------------------------------------------- */ - hasCompare = rnative.test( docElem.compareDocumentPosition ); - - // Element contains another - // Purposefully self-exclusive - // As in, an element does not contain itself - contains = hasCompare || rnative.test( docElem.contains ) ? - function( a, b ) { - var adown = a.nodeType === 9 ? a.documentElement : a, - bup = b && b.parentNode; - return a === bup || !!( bup && bup.nodeType === 1 && ( - adown.contains ? - adown.contains( bup ) : - a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16 - )); - } : - function( a, b ) { - if ( b ) { - while ( (b = b.parentNode) ) { - if ( b === a ) { - return true; - } - } - } - return false; - }; - - /* Sorting - ---------------------------------------------------------------------- */ - - // Document order sorting - sortOrder = hasCompare ? - function( a, b ) { - - // Flag for duplicate removal - if ( a === b ) { - hasDuplicate = true; - return 0; - } - - // Sort on method existence if only one input has compareDocumentPosition - var compare = !a.compareDocumentPosition - !b.compareDocumentPosition; - if ( compare ) { - return compare; - } - - // Calculate position if both inputs belong to the same document - compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ? - a.compareDocumentPosition( b ) : - - // Otherwise we know they are disconnected - 1; - - // Disconnected nodes - if ( compare & 1 || - (!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) { - - // Choose the first element that is related to our preferred document - if ( a === document || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) { - return -1; - } - if ( b === document || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) { - return 1; - } - - // Maintain original order - return sortInput ? - ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : - 0; - } - - return compare & 4 ? -1 : 1; - } : - function( a, b ) { - // Exit early if the nodes are identical - if ( a === b ) { - hasDuplicate = true; - return 0; - } - - var cur, - i = 0, - aup = a.parentNode, - bup = b.parentNode, - ap = [ a ], - bp = [ b ]; - - // Parentless nodes are either documents or disconnected - if ( !aup || !bup ) { - return a === document ? -1 : - b === document ? 1 : - aup ? -1 : - bup ? 1 : - sortInput ? - ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : - 0; - - // If the nodes are siblings, we can do a quick check - } else if ( aup === bup ) { - return siblingCheck( a, b ); - } - - // Otherwise we need full lists of their ancestors for comparison - cur = a; - while ( (cur = cur.parentNode) ) { - ap.unshift( cur ); - } - cur = b; - while ( (cur = cur.parentNode) ) { - bp.unshift( cur ); - } - - // Walk down the tree looking for a discrepancy - while ( ap[i] === bp[i] ) { - i++; - } - - return i ? - // Do a sibling check if the nodes have a common ancestor - siblingCheck( ap[i], bp[i] ) : - - // Otherwise nodes in our document sort first - ap[i] === preferredDoc ? -1 : - bp[i] === preferredDoc ? 1 : - 0; - }; - - return document; + var hasCompare, subWindow, + doc = node ? node.ownerDocument || node : preferredDoc; + + // Return early if doc is invalid or already selected + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( doc == document || doc.nodeType !== 9 || !doc.documentElement ) { + return document; + } + + // Update global variables + document = doc; + docElem = document.documentElement; + documentIsHTML = !isXML( document ); + + // Support: IE 9 - 11+, Edge 12 - 18+ + // Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936) + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( preferredDoc != document && + ( subWindow = document.defaultView ) && subWindow.top !== subWindow ) { + + // Support: IE 11, Edge + if ( subWindow.addEventListener ) { + subWindow.addEventListener( "unload", unloadHandler, false ); + + // Support: IE 9 - 10 only + } else if ( subWindow.attachEvent ) { + subWindow.attachEvent( "onunload", unloadHandler ); + } + } + + // Support: IE 8 - 11+, Edge 12 - 18+, Chrome <=16 - 25 only, Firefox <=3.6 - 31 only, + // Safari 4 - 5 only, Opera <=11.6 - 12.x only + // IE/Edge & older browsers don't support the :scope pseudo-class. + // Support: Safari 6.0 only + // Safari 6.0 supports :scope but it's an alias of :root there. + support.scope = assert( function( el ) { + docElem.appendChild( el ).appendChild( document.createElement( "div" ) ); + return typeof el.querySelectorAll !== "undefined" && + !el.querySelectorAll( ":scope fieldset div" ).length; + } ); + + /* Attributes + ---------------------------------------------------------------------- */ + + // Support: IE<8 + // Verify that getAttribute really returns attributes and not properties + // (excepting IE8 booleans) + support.attributes = assert( function( el ) { + el.className = "i"; + return !el.getAttribute( "className" ); + } ); + + /* getElement(s)By* + ---------------------------------------------------------------------- */ + + // Check if getElementsByTagName("*") returns only elements + support.getElementsByTagName = assert( function( el ) { + el.appendChild( document.createComment( "" ) ); + return !el.getElementsByTagName( "*" ).length; + } ); + + // Support: IE<9 + support.getElementsByClassName = rnative.test( document.getElementsByClassName ); + + // Support: IE<10 + // Check if getElementById returns elements by name + // The broken getElementById methods don't pick up programmatically-set names, + // so use a roundabout getElementsByName test + support.getById = assert( function( el ) { + docElem.appendChild( el ).id = expando; + return !document.getElementsByName || !document.getElementsByName( expando ).length; + } ); + + // ID filter and find + if ( support.getById ) { + Expr.filter[ "ID" ] = function( id ) { + var attrId = id.replace( runescape, funescape ); + return function( elem ) { + return elem.getAttribute( "id" ) === attrId; + }; + }; + Expr.find[ "ID" ] = function( id, context ) { + if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { + var elem = context.getElementById( id ); + return elem ? [ elem ] : []; + } + }; + } else { + Expr.filter[ "ID" ] = function( id ) { + var attrId = id.replace( runescape, funescape ); + return function( elem ) { + var node = typeof elem.getAttributeNode !== "undefined" && + elem.getAttributeNode( "id" ); + return node && node.value === attrId; + }; + }; + + // Support: IE 6 - 7 only + // getElementById is not reliable as a find shortcut + Expr.find[ "ID" ] = function( id, context ) { + if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { + var node, i, elems, + elem = context.getElementById( id ); + + if ( elem ) { + + // Verify the id attribute + node = elem.getAttributeNode( "id" ); + if ( node && node.value === id ) { + return [ elem ]; + } + + // Fall back on getElementsByName + elems = context.getElementsByName( id ); + i = 0; + while ( ( elem = elems[ i++ ] ) ) { + node = elem.getAttributeNode( "id" ); + if ( node && node.value === id ) { + return [ elem ]; + } + } + } + + return []; + } + }; + } + + // Tag + Expr.find[ "TAG" ] = support.getElementsByTagName ? + function( tag, context ) { + if ( typeof context.getElementsByTagName !== "undefined" ) { + return context.getElementsByTagName( tag ); + + // DocumentFragment nodes don't have gEBTN + } else if ( support.qsa ) { + return context.querySelectorAll( tag ); + } + } : + + function( tag, context ) { + var elem, + tmp = [], + i = 0, + + // By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too + results = context.getElementsByTagName( tag ); + + // Filter out possible comments + if ( tag === "*" ) { + while ( ( elem = results[ i++ ] ) ) { + if ( elem.nodeType === 1 ) { + tmp.push( elem ); + } + } + + return tmp; + } + return results; + }; + + // Class + Expr.find[ "CLASS" ] = support.getElementsByClassName && function( className, context ) { + if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) { + return context.getElementsByClassName( className ); + } + }; + + /* QSA/matchesSelector + ---------------------------------------------------------------------- */ + + // QSA and matchesSelector support + + // matchesSelector(:active) reports false when true (IE9/Opera 11.5) + rbuggyMatches = []; + + // qSa(:focus) reports false when true (Chrome 21) + // We allow this because of a bug in IE8/9 that throws an error + // whenever `document.activeElement` is accessed on an iframe + // So, we allow :focus to pass through QSA all the time to avoid the IE error + // See https://bugs.jquery.com/ticket/13378 + rbuggyQSA = []; + + if ( ( support.qsa = rnative.test( document.querySelectorAll ) ) ) { + + // Build QSA regex + // Regex strategy adopted from Diego Perini + assert( function( el ) { + + var input; + + // Select is set to empty string on purpose + // This is to test IE's treatment of not explicitly + // setting a boolean content attribute, + // since its presence should be enough + // https://bugs.jquery.com/ticket/12359 + docElem.appendChild( el ).innerHTML = "" + + ""; + + // Support: IE8, Opera 11-12.16 + // Nothing should be selected when empty strings follow ^= or $= or *= + // The test attribute must be unknown in Opera but "safe" for WinRT + // https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section + if ( el.querySelectorAll( "[msallowcapture^='']" ).length ) { + rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" ); + } + + // Support: IE8 + // Boolean attributes and "value" are not treated correctly + if ( !el.querySelectorAll( "[selected]" ).length ) { + rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" ); + } + + // Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+ + if ( !el.querySelectorAll( "[id~=" + expando + "-]" ).length ) { + rbuggyQSA.push( "~=" ); + } + + // Support: IE 11+, Edge 15 - 18+ + // IE 11/Edge don't find elements on a `[name='']` query in some cases. + // Adding a temporary attribute to the document before the selection works + // around the issue. + // Interestingly, IE 10 & older don't seem to have the issue. + input = document.createElement( "input" ); + input.setAttribute( "name", "" ); + el.appendChild( input ); + if ( !el.querySelectorAll( "[name='']" ).length ) { + rbuggyQSA.push( "\\[" + whitespace + "*name" + whitespace + "*=" + + whitespace + "*(?:''|\"\")" ); + } + + // Webkit/Opera - :checked should return selected option elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + // IE8 throws error here and will not see later tests + if ( !el.querySelectorAll( ":checked" ).length ) { + rbuggyQSA.push( ":checked" ); + } + + // Support: Safari 8+, iOS 8+ + // https://bugs.webkit.org/show_bug.cgi?id=136851 + // In-page `selector#id sibling-combinator selector` fails + if ( !el.querySelectorAll( "a#" + expando + "+*" ).length ) { + rbuggyQSA.push( ".#.+[+~]" ); + } + + // Support: Firefox <=3.6 - 5 only + // Old Firefox doesn't throw on a badly-escaped identifier. + el.querySelectorAll( "\\\f" ); + rbuggyQSA.push( "[\\r\\n\\f]" ); + } ); + + assert( function( el ) { + el.innerHTML = "" + + ""; + + // Support: Windows 8 Native Apps + // The type and name attributes are restricted during .innerHTML assignment + var input = document.createElement( "input" ); + input.setAttribute( "type", "hidden" ); + el.appendChild( input ).setAttribute( "name", "D" ); + + // Support: IE8 + // Enforce case-sensitivity of name attribute + if ( el.querySelectorAll( "[name=d]" ).length ) { + rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" ); + } + + // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) + // IE8 throws error here and will not see later tests + if ( el.querySelectorAll( ":enabled" ).length !== 2 ) { + rbuggyQSA.push( ":enabled", ":disabled" ); + } + + // Support: IE9-11+ + // IE's :disabled selector does not pick up the children of disabled fieldsets + docElem.appendChild( el ).disabled = true; + if ( el.querySelectorAll( ":disabled" ).length !== 2 ) { + rbuggyQSA.push( ":enabled", ":disabled" ); + } + + // Support: Opera 10 - 11 only + // Opera 10-11 does not throw on post-comma invalid pseudos + el.querySelectorAll( "*,:x" ); + rbuggyQSA.push( ",.*:" ); + } ); + } + + if ( ( support.matchesSelector = rnative.test( ( matches = docElem.matches || + docElem.webkitMatchesSelector || + docElem.mozMatchesSelector || + docElem.oMatchesSelector || + docElem.msMatchesSelector ) ) ) ) { + + assert( function( el ) { + + // Check to see if it's possible to do matchesSelector + // on a disconnected node (IE 9) + support.disconnectedMatch = matches.call( el, "*" ); + + // This should fail with an exception + // Gecko does not error, returns false instead + matches.call( el, "[s!='']:x" ); + rbuggyMatches.push( "!=", pseudos ); + } ); + } + + rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join( "|" ) ); + rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join( "|" ) ); + + /* Contains + ---------------------------------------------------------------------- */ + hasCompare = rnative.test( docElem.compareDocumentPosition ); + + // Element contains another + // Purposefully self-exclusive + // As in, an element does not contain itself + contains = hasCompare || rnative.test( docElem.contains ) ? + function( a, b ) { + var adown = a.nodeType === 9 ? a.documentElement : a, + bup = b && b.parentNode; + return a === bup || !!( bup && bup.nodeType === 1 && ( + adown.contains ? + adown.contains( bup ) : + a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16 + ) ); + } : + function( a, b ) { + if ( b ) { + while ( ( b = b.parentNode ) ) { + if ( b === a ) { + return true; + } + } + } + return false; + }; + + /* Sorting + ---------------------------------------------------------------------- */ + + // Document order sorting + sortOrder = hasCompare ? + function( a, b ) { + + // Flag for duplicate removal + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + // Sort on method existence if only one input has compareDocumentPosition + var compare = !a.compareDocumentPosition - !b.compareDocumentPosition; + if ( compare ) { + return compare; + } + + // Calculate position if both inputs belong to the same document + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + compare = ( a.ownerDocument || a ) == ( b.ownerDocument || b ) ? + a.compareDocumentPosition( b ) : + + // Otherwise we know they are disconnected + 1; + + // Disconnected nodes + if ( compare & 1 || + ( !support.sortDetached && b.compareDocumentPosition( a ) === compare ) ) { + + // Choose the first element that is related to our preferred document + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( a == document || a.ownerDocument == preferredDoc && + contains( preferredDoc, a ) ) { + return -1; + } + + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( b == document || b.ownerDocument == preferredDoc && + contains( preferredDoc, b ) ) { + return 1; + } + + // Maintain original order + return sortInput ? + ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : + 0; + } + + return compare & 4 ? -1 : 1; + } : + function( a, b ) { + + // Exit early if the nodes are identical + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + var cur, + i = 0, + aup = a.parentNode, + bup = b.parentNode, + ap = [ a ], + bp = [ b ]; + + // Parentless nodes are either documents or disconnected + if ( !aup || !bup ) { + + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + /* eslint-disable eqeqeq */ + return a == document ? -1 : + b == document ? 1 : + /* eslint-enable eqeqeq */ + aup ? -1 : + bup ? 1 : + sortInput ? + ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : + 0; + + // If the nodes are siblings, we can do a quick check + } else if ( aup === bup ) { + return siblingCheck( a, b ); + } + + // Otherwise we need full lists of their ancestors for comparison + cur = a; + while ( ( cur = cur.parentNode ) ) { + ap.unshift( cur ); + } + cur = b; + while ( ( cur = cur.parentNode ) ) { + bp.unshift( cur ); + } + + // Walk down the tree looking for a discrepancy + while ( ap[ i ] === bp[ i ] ) { + i++; + } + + return i ? + + // Do a sibling check if the nodes have a common ancestor + siblingCheck( ap[ i ], bp[ i ] ) : + + // Otherwise nodes in our document sort first + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + /* eslint-disable eqeqeq */ + ap[ i ] == preferredDoc ? -1 : + bp[ i ] == preferredDoc ? 1 : + /* eslint-enable eqeqeq */ + 0; + }; + + return document; }; Sizzle.matches = function( expr, elements ) { - return Sizzle( expr, null, null, elements ); + return Sizzle( expr, null, null, elements ); }; Sizzle.matchesSelector = function( elem, expr ) { - // Set document vars if needed - if ( ( elem.ownerDocument || elem ) !== document ) { - setDocument( elem ); - } - - // Make sure that attribute selectors are quoted - expr = expr.replace( rattributeQuotes, "='$1']" ); - - if ( support.matchesSelector && documentIsHTML && - !compilerCache[ expr + " " ] && - ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) && - ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) { - - try { - var ret = matches.call( elem, expr ); - - // IE 9's matchesSelector returns false on disconnected nodes - if ( ret || support.disconnectedMatch || - // As well, disconnected nodes are said to be in a document - // fragment in IE 9 - elem.document && elem.document.nodeType !== 11 ) { - return ret; - } - } catch (e) {} - } - - return Sizzle( expr, document, null, [ elem ] ).length > 0; + setDocument( elem ); + + if ( support.matchesSelector && documentIsHTML && + !nonnativeSelectorCache[ expr + " " ] && + ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) && + ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) { + + try { + var ret = matches.call( elem, expr ); + + // IE 9's matchesSelector returns false on disconnected nodes + if ( ret || support.disconnectedMatch || + + // As well, disconnected nodes are said to be in a document + // fragment in IE 9 + elem.document && elem.document.nodeType !== 11 ) { + return ret; + } + } catch ( e ) { + nonnativeSelectorCache( expr, true ); + } + } + + return Sizzle( expr, document, null, [ elem ] ).length > 0; }; Sizzle.contains = function( context, elem ) { - // Set document vars if needed - if ( ( context.ownerDocument || context ) !== document ) { - setDocument( context ); - } - return contains( context, elem ); + + // Set document vars if needed + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( ( context.ownerDocument || context ) != document ) { + setDocument( context ); + } + return contains( context, elem ); }; Sizzle.attr = function( elem, name ) { - // Set document vars if needed - if ( ( elem.ownerDocument || elem ) !== document ) { - setDocument( elem ); - } - - var fn = Expr.attrHandle[ name.toLowerCase() ], - // Don't get fooled by Object.prototype properties (jQuery #13807) - val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ? - fn( elem, name, !documentIsHTML ) : - undefined; - - return val !== undefined ? - val : - support.attributes || !documentIsHTML ? - elem.getAttribute( name ) : - (val = elem.getAttributeNode(name)) && val.specified ? - val.value : - null; + + // Set document vars if needed + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( ( elem.ownerDocument || elem ) != document ) { + setDocument( elem ); + } + + var fn = Expr.attrHandle[ name.toLowerCase() ], + + // Don't get fooled by Object.prototype properties (jQuery #13807) + val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ? + fn( elem, name, !documentIsHTML ) : + undefined; + + return val !== undefined ? + val : + support.attributes || !documentIsHTML ? + elem.getAttribute( name ) : + ( val = elem.getAttributeNode( name ) ) && val.specified ? + val.value : + null; +}; + +Sizzle.escape = function( sel ) { + return ( sel + "" ).replace( rcssescape, fcssescape ); }; Sizzle.error = function( msg ) { - throw new Error( "Syntax error, unrecognized expression: " + msg ); + throw new Error( "Syntax error, unrecognized expression: " + msg ); }; /** @@ -1468,32 +1682,32 @@ Sizzle.error = function( msg ) { * @param {ArrayLike} results */ Sizzle.uniqueSort = function( results ) { - var elem, - duplicates = [], - j = 0, - i = 0; - - // Unless we *know* we can detect duplicates, assume their presence - hasDuplicate = !support.detectDuplicates; - sortInput = !support.sortStable && results.slice( 0 ); - results.sort( sortOrder ); - - if ( hasDuplicate ) { - while ( (elem = results[i++]) ) { - if ( elem === results[ i ] ) { - j = duplicates.push( i ); - } - } - while ( j-- ) { - results.splice( duplicates[ j ], 1 ); - } - } - - // Clear input after sorting to release objects - // See https://github.com/jquery/sizzle/pull/225 - sortInput = null; - - return results; + var elem, + duplicates = [], + j = 0, + i = 0; + + // Unless we *know* we can detect duplicates, assume their presence + hasDuplicate = !support.detectDuplicates; + sortInput = !support.sortStable && results.slice( 0 ); + results.sort( sortOrder ); + + if ( hasDuplicate ) { + while ( ( elem = results[ i++ ] ) ) { + if ( elem === results[ i ] ) { + j = duplicates.push( i ); + } + } + while ( j-- ) { + results.splice( duplicates[ j ], 1 ); + } + } + + // Clear input after sorting to release objects + // See https://github.com/jquery/sizzle/pull/225 + sortInput = null; + + return results; }; /** @@ -1501,553 +1715,594 @@ Sizzle.uniqueSort = function( results ) { * @param {Array|Element} elem */ getText = Sizzle.getText = function( elem ) { - var node, - ret = "", - i = 0, - nodeType = elem.nodeType; - - if ( !nodeType ) { - // If no nodeType, this is expected to be an array - while ( (node = elem[i++]) ) { - // Do not traverse comment nodes - ret += getText( node ); - } - } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { - // Use textContent for elements - // innerText usage removed for consistency of new lines (jQuery #11153) - if ( typeof elem.textContent === "string" ) { - return elem.textContent; - } else { - // Traverse its children - for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { - ret += getText( elem ); - } - } - } else if ( nodeType === 3 || nodeType === 4 ) { - return elem.nodeValue; - } - // Do not include comment or processing instruction nodes - - return ret; + var node, + ret = "", + i = 0, + nodeType = elem.nodeType; + + if ( !nodeType ) { + + // If no nodeType, this is expected to be an array + while ( ( node = elem[ i++ ] ) ) { + + // Do not traverse comment nodes + ret += getText( node ); + } + } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { + + // Use textContent for elements + // innerText usage removed for consistency of new lines (jQuery #11153) + if ( typeof elem.textContent === "string" ) { + return elem.textContent; + } else { + + // Traverse its children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + ret += getText( elem ); + } + } + } else if ( nodeType === 3 || nodeType === 4 ) { + return elem.nodeValue; + } + + // Do not include comment or processing instruction nodes + + return ret; }; Expr = Sizzle.selectors = { - // Can be adjusted by the user - cacheLength: 50, - - createPseudo: markFunction, - - match: matchExpr, - - attrHandle: {}, - - find: {}, - - relative: { - ">": { dir: "parentNode", first: true }, - " ": { dir: "parentNode" }, - "+": { dir: "previousSibling", first: true }, - "~": { dir: "previousSibling" } - }, - - preFilter: { - "ATTR": function( match ) { - match[1] = match[1].replace( runescape, funescape ); - - // Move the given value to match[3] whether quoted or unquoted - match[3] = ( match[3] || match[4] || match[5] || "" ).replace( runescape, funescape ); - - if ( match[2] === "~=" ) { - match[3] = " " + match[3] + " "; - } - - return match.slice( 0, 4 ); - }, - - "CHILD": function( match ) { - /* matches from matchExpr["CHILD"] - 1 type (only|nth|...) - 2 what (child|of-type) - 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...) - 4 xn-component of xn+y argument ([+-]?\d*n|) - 5 sign of xn-component - 6 x of xn-component - 7 sign of y-component - 8 y of y-component - */ - match[1] = match[1].toLowerCase(); - - if ( match[1].slice( 0, 3 ) === "nth" ) { - // nth-* requires argument - if ( !match[3] ) { - Sizzle.error( match[0] ); - } - - // numeric x and y parameters for Expr.filter.CHILD - // remember that false/true cast respectively to 0/1 - match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) ); - match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" ); - - // other types prohibit arguments - } else if ( match[3] ) { - Sizzle.error( match[0] ); - } - - return match; - }, - - "PSEUDO": function( match ) { - var excess, - unquoted = !match[6] && match[2]; - - if ( matchExpr["CHILD"].test( match[0] ) ) { - return null; - } - - // Accept quoted arguments as-is - if ( match[3] ) { - match[2] = match[4] || match[5] || ""; - - // Strip excess characters from unquoted arguments - } else if ( unquoted && rpseudo.test( unquoted ) && - // Get excess from tokenize (recursively) - (excess = tokenize( unquoted, true )) && - // advance to the next closing parenthesis - (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) { - - // excess is a negative index - match[0] = match[0].slice( 0, excess ); - match[2] = unquoted.slice( 0, excess ); - } - - // Return only captures needed by the pseudo filter method (type and argument) - return match.slice( 0, 3 ); - } - }, - - filter: { - - "TAG": function( nodeNameSelector ) { - var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase(); - return nodeNameSelector === "*" ? - function() { return true; } : - function( elem ) { - return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; - }; - }, - - "CLASS": function( className ) { - var pattern = classCache[ className + " " ]; - - return pattern || - (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) && - classCache( className, function( elem ) { - return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute("class") || "" ); - }); - }, - - "ATTR": function( name, operator, check ) { - return function( elem ) { - var result = Sizzle.attr( elem, name ); - - if ( result == null ) { - return operator === "!="; - } - if ( !operator ) { - return true; - } - - result += ""; - - return operator === "=" ? result === check : - operator === "!=" ? result !== check : - operator === "^=" ? check && result.indexOf( check ) === 0 : - operator === "*=" ? check && result.indexOf( check ) > -1 : - operator === "$=" ? check && result.slice( -check.length ) === check : - operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 : - operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" : - false; - }; - }, - - "CHILD": function( type, what, argument, first, last ) { - var simple = type.slice( 0, 3 ) !== "nth", - forward = type.slice( -4 ) !== "last", - ofType = what === "of-type"; - - return first === 1 && last === 0 ? - - // Shortcut for :nth-*(n) - function( elem ) { - return !!elem.parentNode; - } : - - function( elem, context, xml ) { - var cache, uniqueCache, outerCache, node, nodeIndex, start, - dir = simple !== forward ? "nextSibling" : "previousSibling", - parent = elem.parentNode, - name = ofType && elem.nodeName.toLowerCase(), - useCache = !xml && !ofType, - diff = false; - - if ( parent ) { - - // :(first|last|only)-(child|of-type) - if ( simple ) { - while ( dir ) { - node = elem; - while ( (node = node[ dir ]) ) { - if ( ofType ? - node.nodeName.toLowerCase() === name : - node.nodeType === 1 ) { - - return false; - } - } - // Reverse direction for :only-* (if we haven't yet done so) - start = dir = type === "only" && !start && "nextSibling"; - } - return true; - } - - start = [ forward ? parent.firstChild : parent.lastChild ]; - - // non-xml :nth-child(...) stores cache data on `parent` - if ( forward && useCache ) { - - // Seek `elem` from a previously-cached index - - // ...in a gzip-friendly way - node = parent; - outerCache = node[ expando ] || (node[ expando ] = {}); - - // Support: IE <9 only - // Defend against cloned attroperties (jQuery gh-1709) - uniqueCache = outerCache[ node.uniqueID ] || - (outerCache[ node.uniqueID ] = {}); - - cache = uniqueCache[ type ] || []; - nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; - diff = nodeIndex && cache[ 2 ]; - node = nodeIndex && parent.childNodes[ nodeIndex ]; - - while ( (node = ++nodeIndex && node && node[ dir ] || - - // Fallback to seeking `elem` from the start - (diff = nodeIndex = 0) || start.pop()) ) { - - // When found, cache indexes on `parent` and break - if ( node.nodeType === 1 && ++diff && node === elem ) { - uniqueCache[ type ] = [ dirruns, nodeIndex, diff ]; - break; - } - } - - } else { - // Use previously-cached element index if available - if ( useCache ) { - // ...in a gzip-friendly way - node = elem; - outerCache = node[ expando ] || (node[ expando ] = {}); - - // Support: IE <9 only - // Defend against cloned attroperties (jQuery gh-1709) - uniqueCache = outerCache[ node.uniqueID ] || - (outerCache[ node.uniqueID ] = {}); - - cache = uniqueCache[ type ] || []; - nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; - diff = nodeIndex; - } - - // xml :nth-child(...) - // or :nth-last-child(...) or :nth(-last)?-of-type(...) - if ( diff === false ) { - // Use the same loop as above to seek `elem` from the start - while ( (node = ++nodeIndex && node && node[ dir ] || - (diff = nodeIndex = 0) || start.pop()) ) { - - if ( ( ofType ? - node.nodeName.toLowerCase() === name : - node.nodeType === 1 ) && - ++diff ) { - - // Cache the index of each encountered element - if ( useCache ) { - outerCache = node[ expando ] || (node[ expando ] = {}); - - // Support: IE <9 only - // Defend against cloned attroperties (jQuery gh-1709) - uniqueCache = outerCache[ node.uniqueID ] || - (outerCache[ node.uniqueID ] = {}); - - uniqueCache[ type ] = [ dirruns, diff ]; - } - - if ( node === elem ) { - break; - } - } - } - } - } - - // Incorporate the offset, then check against cycle size - diff -= last; - return diff === first || ( diff % first === 0 && diff / first >= 0 ); - } - }; - }, - - "PSEUDO": function( pseudo, argument ) { - // pseudo-class names are case-insensitive - // https://www.w3.org/TR/selectors/#pseudo-classes - // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters - // Remember that setFilters inherits from pseudos - var args, - fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] || - Sizzle.error( "unsupported pseudo: " + pseudo ); - - // The user may use createPseudo to indicate that - // arguments are needed to create the filter function - // just as Sizzle does - if ( fn[ expando ] ) { - return fn( argument ); - } - - // But maintain support for old signatures - if ( fn.length > 1 ) { - args = [ pseudo, pseudo, "", argument ]; - return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ? - markFunction(function( seed, matches ) { - var idx, - matched = fn( seed, argument ), - i = matched.length; - while ( i-- ) { - idx = indexOf( seed, matched[i] ); - seed[ idx ] = !( matches[ idx ] = matched[i] ); - } - }) : - function( elem ) { - return fn( elem, 0, args ); - }; - } - - return fn; - } - }, - - pseudos: { - // Potentially complex pseudos - "not": markFunction(function( selector ) { - // Trim the selector passed to compile - // to avoid treating leading and trailing - // spaces as combinators - var input = [], - results = [], - matcher = compile( selector.replace( rtrim, "$1" ) ); - - return matcher[ expando ] ? - markFunction(function( seed, matches, context, xml ) { - var elem, - unmatched = matcher( seed, null, xml, [] ), - i = seed.length; - - // Match elements unmatched by `matcher` - while ( i-- ) { - if ( (elem = unmatched[i]) ) { - seed[i] = !(matches[i] = elem); - } - } - }) : - function( elem, context, xml ) { - input[0] = elem; - matcher( input, null, xml, results ); - // Don't keep the element (issue #299) - input[0] = null; - return !results.pop(); - }; - }), - - "has": markFunction(function( selector ) { - return function( elem ) { - return Sizzle( selector, elem ).length > 0; - }; - }), - - "contains": markFunction(function( text ) { - text = text.replace( runescape, funescape ); - return function( elem ) { - return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1; - }; - }), - - // "Whether an element is represented by a :lang() selector - // is based solely on the element's language value - // being equal to the identifier C, - // or beginning with the identifier C immediately followed by "-". - // The matching of C against the element's language value is performed case-insensitively. - // The identifier C does not have to be a valid language name." - // https://www.w3.org/TR/selectors/#lang-pseudo - "lang": markFunction( function( lang ) { - // lang value must be a valid identifier - if ( !ridentifier.test(lang || "") ) { - Sizzle.error( "unsupported lang: " + lang ); - } - lang = lang.replace( runescape, funescape ).toLowerCase(); - return function( elem ) { - var elemLang; - do { - if ( (elemLang = documentIsHTML ? - elem.lang : - elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) { - - elemLang = elemLang.toLowerCase(); - return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0; - } - } while ( (elem = elem.parentNode) && elem.nodeType === 1 ); - return false; - }; - }), - - // Miscellaneous - "target": function( elem ) { - var hash = window.location && window.location.hash; - return hash && hash.slice( 1 ) === elem.id; - }, - - "root": function( elem ) { - return elem === docElem; - }, - - "focus": function( elem ) { - return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex); - }, - - // Boolean properties - "enabled": function( elem ) { - return elem.disabled === false; - }, - - "disabled": function( elem ) { - return elem.disabled === true; - }, - - "checked": function( elem ) { - // In CSS3, :checked should return both checked and selected elements - // https://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked - var nodeName = elem.nodeName.toLowerCase(); - return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected); - }, - - "selected": function( elem ) { - // Accessing this property makes selected-by-default - // options in Safari work properly - if ( elem.parentNode ) { - elem.parentNode.selectedIndex; - } - - return elem.selected === true; - }, - - // Contents - "empty": function( elem ) { - // https://www.w3.org/TR/selectors/#empty-pseudo - // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5), - // but not by others (comment: 8; processing instruction: 7; etc.) - // nodeType < 6 works because attributes (2) do not appear as children - for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { - if ( elem.nodeType < 6 ) { - return false; - } - } - return true; - }, - - "parent": function( elem ) { - return !Expr.pseudos["empty"]( elem ); - }, - - // Element/input types - "header": function( elem ) { - return rheader.test( elem.nodeName ); - }, - - "input": function( elem ) { - return rinputs.test( elem.nodeName ); - }, - - "button": function( elem ) { - var name = elem.nodeName.toLowerCase(); - return name === "input" && elem.type === "button" || name === "button"; - }, - - "text": function( elem ) { - var attr; - return elem.nodeName.toLowerCase() === "input" && - elem.type === "text" && - - // Support: IE<8 - // New HTML5 attribute values (e.g., "search") appear with elem.type === "text" - ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" ); - }, - - // Position-in-collection - "first": createPositionalPseudo(function() { - return [ 0 ]; - }), - - "last": createPositionalPseudo(function( matchIndexes, length ) { - return [ length - 1 ]; - }), - - "eq": createPositionalPseudo(function( matchIndexes, length, argument ) { - return [ argument < 0 ? argument + length : argument ]; - }), - - "even": createPositionalPseudo(function( matchIndexes, length ) { - var i = 0; - for ( ; i < length; i += 2 ) { - matchIndexes.push( i ); - } - return matchIndexes; - }), - - "odd": createPositionalPseudo(function( matchIndexes, length ) { - var i = 1; - for ( ; i < length; i += 2 ) { - matchIndexes.push( i ); - } - return matchIndexes; - }), - - "lt": createPositionalPseudo(function( matchIndexes, length, argument ) { - var i = argument < 0 ? argument + length : argument; - for ( ; --i >= 0; ) { - matchIndexes.push( i ); - } - return matchIndexes; - }), - - "gt": createPositionalPseudo(function( matchIndexes, length, argument ) { - var i = argument < 0 ? argument + length : argument; - for ( ; ++i < length; ) { - matchIndexes.push( i ); - } - return matchIndexes; - }) - } + // Can be adjusted by the user + cacheLength: 50, + + createPseudo: markFunction, + + match: matchExpr, + + attrHandle: {}, + + find: {}, + + relative: { + ">": { dir: "parentNode", first: true }, + " ": { dir: "parentNode" }, + "+": { dir: "previousSibling", first: true }, + "~": { dir: "previousSibling" } + }, + + preFilter: { + "ATTR": function( match ) { + match[ 1 ] = match[ 1 ].replace( runescape, funescape ); + + // Move the given value to match[3] whether quoted or unquoted + match[ 3 ] = ( match[ 3 ] || match[ 4 ] || + match[ 5 ] || "" ).replace( runescape, funescape ); + + if ( match[ 2 ] === "~=" ) { + match[ 3 ] = " " + match[ 3 ] + " "; + } + + return match.slice( 0, 4 ); + }, + + "CHILD": function( match ) { + + /* matches from matchExpr["CHILD"] + 1 type (only|nth|...) + 2 what (child|of-type) + 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...) + 4 xn-component of xn+y argument ([+-]?\d*n|) + 5 sign of xn-component + 6 x of xn-component + 7 sign of y-component + 8 y of y-component + */ + match[ 1 ] = match[ 1 ].toLowerCase(); + + if ( match[ 1 ].slice( 0, 3 ) === "nth" ) { + + // nth-* requires argument + if ( !match[ 3 ] ) { + Sizzle.error( match[ 0 ] ); + } + + // numeric x and y parameters for Expr.filter.CHILD + // remember that false/true cast respectively to 0/1 + match[ 4 ] = +( match[ 4 ] ? + match[ 5 ] + ( match[ 6 ] || 1 ) : + 2 * ( match[ 3 ] === "even" || match[ 3 ] === "odd" ) ); + match[ 5 ] = +( ( match[ 7 ] + match[ 8 ] ) || match[ 3 ] === "odd" ); + + // other types prohibit arguments + } else if ( match[ 3 ] ) { + Sizzle.error( match[ 0 ] ); + } + + return match; + }, + + "PSEUDO": function( match ) { + var excess, + unquoted = !match[ 6 ] && match[ 2 ]; + + if ( matchExpr[ "CHILD" ].test( match[ 0 ] ) ) { + return null; + } + + // Accept quoted arguments as-is + if ( match[ 3 ] ) { + match[ 2 ] = match[ 4 ] || match[ 5 ] || ""; + + // Strip excess characters from unquoted arguments + } else if ( unquoted && rpseudo.test( unquoted ) && + + // Get excess from tokenize (recursively) + ( excess = tokenize( unquoted, true ) ) && + + // advance to the next closing parenthesis + ( excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length ) ) { + + // excess is a negative index + match[ 0 ] = match[ 0 ].slice( 0, excess ); + match[ 2 ] = unquoted.slice( 0, excess ); + } + + // Return only captures needed by the pseudo filter method (type and argument) + return match.slice( 0, 3 ); + } + }, + + filter: { + + "TAG": function( nodeNameSelector ) { + var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase(); + return nodeNameSelector === "*" ? + function() { + return true; + } : + function( elem ) { + return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; + }; + }, + + "CLASS": function( className ) { + var pattern = classCache[ className + " " ]; + + return pattern || + ( pattern = new RegExp( "(^|" + whitespace + + ")" + className + "(" + whitespace + "|$)" ) ) && classCache( + className, function( elem ) { + return pattern.test( + typeof elem.className === "string" && elem.className || + typeof elem.getAttribute !== "undefined" && + elem.getAttribute( "class" ) || + "" + ); + } ); + }, + + "ATTR": function( name, operator, check ) { + return function( elem ) { + var result = Sizzle.attr( elem, name ); + + if ( result == null ) { + return operator === "!="; + } + if ( !operator ) { + return true; + } + + result += ""; + + /* eslint-disable max-len */ + + return operator === "=" ? result === check : + operator === "!=" ? result !== check : + operator === "^=" ? check && result.indexOf( check ) === 0 : + operator === "*=" ? check && result.indexOf( check ) > -1 : + operator === "$=" ? check && result.slice( -check.length ) === check : + operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 : + operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" : + false; + /* eslint-enable max-len */ + + }; + }, + + "CHILD": function( type, what, _argument, first, last ) { + var simple = type.slice( 0, 3 ) !== "nth", + forward = type.slice( -4 ) !== "last", + ofType = what === "of-type"; + + return first === 1 && last === 0 ? + + // Shortcut for :nth-*(n) + function( elem ) { + return !!elem.parentNode; + } : + + function( elem, _context, xml ) { + var cache, uniqueCache, outerCache, node, nodeIndex, start, + dir = simple !== forward ? "nextSibling" : "previousSibling", + parent = elem.parentNode, + name = ofType && elem.nodeName.toLowerCase(), + useCache = !xml && !ofType, + diff = false; + + if ( parent ) { + + // :(first|last|only)-(child|of-type) + if ( simple ) { + while ( dir ) { + node = elem; + while ( ( node = node[ dir ] ) ) { + if ( ofType ? + node.nodeName.toLowerCase() === name : + node.nodeType === 1 ) { + + return false; + } + } + + // Reverse direction for :only-* (if we haven't yet done so) + start = dir = type === "only" && !start && "nextSibling"; + } + return true; + } + + start = [ forward ? parent.firstChild : parent.lastChild ]; + + // non-xml :nth-child(...) stores cache data on `parent` + if ( forward && useCache ) { + + // Seek `elem` from a previously-cached index + + // ...in a gzip-friendly way + node = parent; + outerCache = node[ expando ] || ( node[ expando ] = {} ); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ node.uniqueID ] || + ( outerCache[ node.uniqueID ] = {} ); + + cache = uniqueCache[ type ] || []; + nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; + diff = nodeIndex && cache[ 2 ]; + node = nodeIndex && parent.childNodes[ nodeIndex ]; + + while ( ( node = ++nodeIndex && node && node[ dir ] || + + // Fallback to seeking `elem` from the start + ( diff = nodeIndex = 0 ) || start.pop() ) ) { + + // When found, cache indexes on `parent` and break + if ( node.nodeType === 1 && ++diff && node === elem ) { + uniqueCache[ type ] = [ dirruns, nodeIndex, diff ]; + break; + } + } + + } else { + + // Use previously-cached element index if available + if ( useCache ) { + + // ...in a gzip-friendly way + node = elem; + outerCache = node[ expando ] || ( node[ expando ] = {} ); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ node.uniqueID ] || + ( outerCache[ node.uniqueID ] = {} ); + + cache = uniqueCache[ type ] || []; + nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; + diff = nodeIndex; + } + + // xml :nth-child(...) + // or :nth-last-child(...) or :nth(-last)?-of-type(...) + if ( diff === false ) { + + // Use the same loop as above to seek `elem` from the start + while ( ( node = ++nodeIndex && node && node[ dir ] || + ( diff = nodeIndex = 0 ) || start.pop() ) ) { + + if ( ( ofType ? + node.nodeName.toLowerCase() === name : + node.nodeType === 1 ) && + ++diff ) { + + // Cache the index of each encountered element + if ( useCache ) { + outerCache = node[ expando ] || + ( node[ expando ] = {} ); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ node.uniqueID ] || + ( outerCache[ node.uniqueID ] = {} ); + + uniqueCache[ type ] = [ dirruns, diff ]; + } + + if ( node === elem ) { + break; + } + } + } + } + } + + // Incorporate the offset, then check against cycle size + diff -= last; + return diff === first || ( diff % first === 0 && diff / first >= 0 ); + } + }; + }, + + "PSEUDO": function( pseudo, argument ) { + + // pseudo-class names are case-insensitive + // http://www.w3.org/TR/selectors/#pseudo-classes + // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters + // Remember that setFilters inherits from pseudos + var args, + fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] || + Sizzle.error( "unsupported pseudo: " + pseudo ); + + // The user may use createPseudo to indicate that + // arguments are needed to create the filter function + // just as Sizzle does + if ( fn[ expando ] ) { + return fn( argument ); + } + + // But maintain support for old signatures + if ( fn.length > 1 ) { + args = [ pseudo, pseudo, "", argument ]; + return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ? + markFunction( function( seed, matches ) { + var idx, + matched = fn( seed, argument ), + i = matched.length; + while ( i-- ) { + idx = indexOf( seed, matched[ i ] ); + seed[ idx ] = !( matches[ idx ] = matched[ i ] ); + } + } ) : + function( elem ) { + return fn( elem, 0, args ); + }; + } + + return fn; + } + }, + + pseudos: { + + // Potentially complex pseudos + "not": markFunction( function( selector ) { + + // Trim the selector passed to compile + // to avoid treating leading and trailing + // spaces as combinators + var input = [], + results = [], + matcher = compile( selector.replace( rtrim, "$1" ) ); + + return matcher[ expando ] ? + markFunction( function( seed, matches, _context, xml ) { + var elem, + unmatched = matcher( seed, null, xml, [] ), + i = seed.length; + + // Match elements unmatched by `matcher` + while ( i-- ) { + if ( ( elem = unmatched[ i ] ) ) { + seed[ i ] = !( matches[ i ] = elem ); + } + } + } ) : + function( elem, _context, xml ) { + input[ 0 ] = elem; + matcher( input, null, xml, results ); + + // Don't keep the element (issue #299) + input[ 0 ] = null; + return !results.pop(); + }; + } ), + + "has": markFunction( function( selector ) { + return function( elem ) { + return Sizzle( selector, elem ).length > 0; + }; + } ), + + "contains": markFunction( function( text ) { + text = text.replace( runescape, funescape ); + return function( elem ) { + return ( elem.textContent || getText( elem ) ).indexOf( text ) > -1; + }; + } ), + + // "Whether an element is represented by a :lang() selector + // is based solely on the element's language value + // being equal to the identifier C, + // or beginning with the identifier C immediately followed by "-". + // The matching of C against the element's language value is performed case-insensitively. + // The identifier C does not have to be a valid language name." + // http://www.w3.org/TR/selectors/#lang-pseudo + "lang": markFunction( function( lang ) { + + // lang value must be a valid identifier + if ( !ridentifier.test( lang || "" ) ) { + Sizzle.error( "unsupported lang: " + lang ); + } + lang = lang.replace( runescape, funescape ).toLowerCase(); + return function( elem ) { + var elemLang; + do { + if ( ( elemLang = documentIsHTML ? + elem.lang : + elem.getAttribute( "xml:lang" ) || elem.getAttribute( "lang" ) ) ) { + + elemLang = elemLang.toLowerCase(); + return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0; + } + } while ( ( elem = elem.parentNode ) && elem.nodeType === 1 ); + return false; + }; + } ), + + // Miscellaneous + "target": function( elem ) { + var hash = window.location && window.location.hash; + return hash && hash.slice( 1 ) === elem.id; + }, + + "root": function( elem ) { + return elem === docElem; + }, + + "focus": function( elem ) { + return elem === document.activeElement && + ( !document.hasFocus || document.hasFocus() ) && + !!( elem.type || elem.href || ~elem.tabIndex ); + }, + + // Boolean properties + "enabled": createDisabledPseudo( false ), + "disabled": createDisabledPseudo( true ), + + "checked": function( elem ) { + + // In CSS3, :checked should return both checked and selected elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + var nodeName = elem.nodeName.toLowerCase(); + return ( nodeName === "input" && !!elem.checked ) || + ( nodeName === "option" && !!elem.selected ); + }, + + "selected": function( elem ) { + + // Accessing this property makes selected-by-default + // options in Safari work properly + if ( elem.parentNode ) { + // eslint-disable-next-line no-unused-expressions + elem.parentNode.selectedIndex; + } + + return elem.selected === true; + }, + + // Contents + "empty": function( elem ) { + + // http://www.w3.org/TR/selectors/#empty-pseudo + // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5), + // but not by others (comment: 8; processing instruction: 7; etc.) + // nodeType < 6 works because attributes (2) do not appear as children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + if ( elem.nodeType < 6 ) { + return false; + } + } + return true; + }, + + "parent": function( elem ) { + return !Expr.pseudos[ "empty" ]( elem ); + }, + + // Element/input types + "header": function( elem ) { + return rheader.test( elem.nodeName ); + }, + + "input": function( elem ) { + return rinputs.test( elem.nodeName ); + }, + + "button": function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === "button" || name === "button"; + }, + + "text": function( elem ) { + var attr; + return elem.nodeName.toLowerCase() === "input" && + elem.type === "text" && + + // Support: IE<8 + // New HTML5 attribute values (e.g., "search") appear with elem.type === "text" + ( ( attr = elem.getAttribute( "type" ) ) == null || + attr.toLowerCase() === "text" ); + }, + + // Position-in-collection + "first": createPositionalPseudo( function() { + return [ 0 ]; + } ), + + "last": createPositionalPseudo( function( _matchIndexes, length ) { + return [ length - 1 ]; + } ), + + "eq": createPositionalPseudo( function( _matchIndexes, length, argument ) { + return [ argument < 0 ? argument + length : argument ]; + } ), + + "even": createPositionalPseudo( function( matchIndexes, length ) { + var i = 0; + for ( ; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + } ), + + "odd": createPositionalPseudo( function( matchIndexes, length ) { + var i = 1; + for ( ; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + } ), + + "lt": createPositionalPseudo( function( matchIndexes, length, argument ) { + var i = argument < 0 ? + argument + length : + argument > length ? + length : + argument; + for ( ; --i >= 0; ) { + matchIndexes.push( i ); + } + return matchIndexes; + } ), + + "gt": createPositionalPseudo( function( matchIndexes, length, argument ) { + var i = argument < 0 ? argument + length : argument; + for ( ; ++i < length; ) { + matchIndexes.push( i ); + } + return matchIndexes; + } ) + } }; -Expr.pseudos["nth"] = Expr.pseudos["eq"]; +Expr.pseudos[ "nth" ] = Expr.pseudos[ "eq" ]; // Add button/input type pseudos for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) { - Expr.pseudos[ i ] = createInputPseudo( i ); + Expr.pseudos[ i ] = createInputPseudo( i ); } for ( i in { submit: true, reset: true } ) { - Expr.pseudos[ i ] = createButtonPseudo( i ); + Expr.pseudos[ i ] = createButtonPseudo( i ); } // Easy API for creating new setFilters @@ -2056,474 +2311,516 @@ setFilters.prototype = Expr.filters = Expr.pseudos; Expr.setFilters = new setFilters(); tokenize = Sizzle.tokenize = function( selector, parseOnly ) { - var matched, match, tokens, type, - soFar, groups, preFilters, - cached = tokenCache[ selector + " " ]; - - if ( cached ) { - return parseOnly ? 0 : cached.slice( 0 ); - } - - soFar = selector; - groups = []; - preFilters = Expr.preFilter; - - while ( soFar ) { - - // Comma and first run - if ( !matched || (match = rcomma.exec( soFar )) ) { - if ( match ) { - // Don't consume trailing commas as valid - soFar = soFar.slice( match[0].length ) || soFar; - } - groups.push( (tokens = []) ); - } - - matched = false; - - // Combinators - if ( (match = rcombinators.exec( soFar )) ) { - matched = match.shift(); - tokens.push({ - value: matched, - // Cast descendant combinators to space - type: match[0].replace( rtrim, " " ) - }); - soFar = soFar.slice( matched.length ); - } - - // Filters - for ( type in Expr.filter ) { - if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] || - (match = preFilters[ type ]( match ))) ) { - matched = match.shift(); - tokens.push({ - value: matched, - type: type, - matches: match - }); - soFar = soFar.slice( matched.length ); - } - } - - if ( !matched ) { - break; - } - } - - // Return the length of the invalid excess - // if we're just parsing - // Otherwise, throw an error or return tokens - return parseOnly ? - soFar.length : - soFar ? - Sizzle.error( selector ) : - // Cache the tokens - tokenCache( selector, groups ).slice( 0 ); + var matched, match, tokens, type, + soFar, groups, preFilters, + cached = tokenCache[ selector + " " ]; + + if ( cached ) { + return parseOnly ? 0 : cached.slice( 0 ); + } + + soFar = selector; + groups = []; + preFilters = Expr.preFilter; + + while ( soFar ) { + + // Comma and first run + if ( !matched || ( match = rcomma.exec( soFar ) ) ) { + if ( match ) { + + // Don't consume trailing commas as valid + soFar = soFar.slice( match[ 0 ].length ) || soFar; + } + groups.push( ( tokens = [] ) ); + } + + matched = false; + + // Combinators + if ( ( match = rcombinators.exec( soFar ) ) ) { + matched = match.shift(); + tokens.push( { + value: matched, + + // Cast descendant combinators to space + type: match[ 0 ].replace( rtrim, " " ) + } ); + soFar = soFar.slice( matched.length ); + } + + // Filters + for ( type in Expr.filter ) { + if ( ( match = matchExpr[ type ].exec( soFar ) ) && ( !preFilters[ type ] || + ( match = preFilters[ type ]( match ) ) ) ) { + matched = match.shift(); + tokens.push( { + value: matched, + type: type, + matches: match + } ); + soFar = soFar.slice( matched.length ); + } + } + + if ( !matched ) { + break; + } + } + + // Return the length of the invalid excess + // if we're just parsing + // Otherwise, throw an error or return tokens + return parseOnly ? + soFar.length : + soFar ? + Sizzle.error( selector ) : + + // Cache the tokens + tokenCache( selector, groups ).slice( 0 ); }; function toSelector( tokens ) { - var i = 0, - len = tokens.length, - selector = ""; - for ( ; i < len; i++ ) { - selector += tokens[i].value; - } - return selector; + var i = 0, + len = tokens.length, + selector = ""; + for ( ; i < len; i++ ) { + selector += tokens[ i ].value; + } + return selector; } function addCombinator( matcher, combinator, base ) { - var dir = combinator.dir, - checkNonElements = base && dir === "parentNode", - doneName = done++; - - return combinator.first ? - // Check against closest ancestor/preceding element - function( elem, context, xml ) { - while ( (elem = elem[ dir ]) ) { - if ( elem.nodeType === 1 || checkNonElements ) { - return matcher( elem, context, xml ); - } - } - } : - - // Check against all ancestor/preceding elements - function( elem, context, xml ) { - var oldCache, uniqueCache, outerCache, - newCache = [ dirruns, doneName ]; - - // We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching - if ( xml ) { - while ( (elem = elem[ dir ]) ) { - if ( elem.nodeType === 1 || checkNonElements ) { - if ( matcher( elem, context, xml ) ) { - return true; - } - } - } - } else { - while ( (elem = elem[ dir ]) ) { - if ( elem.nodeType === 1 || checkNonElements ) { - outerCache = elem[ expando ] || (elem[ expando ] = {}); - - // Support: IE <9 only - // Defend against cloned attroperties (jQuery gh-1709) - uniqueCache = outerCache[ elem.uniqueID ] || (outerCache[ elem.uniqueID ] = {}); - - if ( (oldCache = uniqueCache[ dir ]) && - oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) { - - // Assign to newCache so results back-propagate to previous elements - return (newCache[ 2 ] = oldCache[ 2 ]); - } else { - // Reuse newcache so results back-propagate to previous elements - uniqueCache[ dir ] = newCache; - - // A match means we're done; a fail means we have to keep checking - if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) { - return true; - } - } - } - } - } - }; + var dir = combinator.dir, + skip = combinator.next, + key = skip || dir, + checkNonElements = base && key === "parentNode", + doneName = done++; + + return combinator.first ? + + // Check against closest ancestor/preceding element + function( elem, context, xml ) { + while ( ( elem = elem[ dir ] ) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + return matcher( elem, context, xml ); + } + } + return false; + } : + + // Check against all ancestor/preceding elements + function( elem, context, xml ) { + var oldCache, uniqueCache, outerCache, + newCache = [ dirruns, doneName ]; + + // We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching + if ( xml ) { + while ( ( elem = elem[ dir ] ) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + if ( matcher( elem, context, xml ) ) { + return true; + } + } + } + } else { + while ( ( elem = elem[ dir ] ) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + outerCache = elem[ expando ] || ( elem[ expando ] = {} ); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ elem.uniqueID ] || + ( outerCache[ elem.uniqueID ] = {} ); + + if ( skip && skip === elem.nodeName.toLowerCase() ) { + elem = elem[ dir ] || elem; + } else if ( ( oldCache = uniqueCache[ key ] ) && + oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) { + + // Assign to newCache so results back-propagate to previous elements + return ( newCache[ 2 ] = oldCache[ 2 ] ); + } else { + + // Reuse newcache so results back-propagate to previous elements + uniqueCache[ key ] = newCache; + + // A match means we're done; a fail means we have to keep checking + if ( ( newCache[ 2 ] = matcher( elem, context, xml ) ) ) { + return true; + } + } + } + } + } + return false; + }; } function elementMatcher( matchers ) { - return matchers.length > 1 ? - function( elem, context, xml ) { - var i = matchers.length; - while ( i-- ) { - if ( !matchers[i]( elem, context, xml ) ) { - return false; - } - } - return true; - } : - matchers[0]; + return matchers.length > 1 ? + function( elem, context, xml ) { + var i = matchers.length; + while ( i-- ) { + if ( !matchers[ i ]( elem, context, xml ) ) { + return false; + } + } + return true; + } : + matchers[ 0 ]; } function multipleContexts( selector, contexts, results ) { - var i = 0, - len = contexts.length; - for ( ; i < len; i++ ) { - Sizzle( selector, contexts[i], results ); - } - return results; + var i = 0, + len = contexts.length; + for ( ; i < len; i++ ) { + Sizzle( selector, contexts[ i ], results ); + } + return results; } function condense( unmatched, map, filter, context, xml ) { - var elem, - newUnmatched = [], - i = 0, - len = unmatched.length, - mapped = map != null; - - for ( ; i < len; i++ ) { - if ( (elem = unmatched[i]) ) { - if ( !filter || filter( elem, context, xml ) ) { - newUnmatched.push( elem ); - if ( mapped ) { - map.push( i ); - } - } - } - } - - return newUnmatched; + var elem, + newUnmatched = [], + i = 0, + len = unmatched.length, + mapped = map != null; + + for ( ; i < len; i++ ) { + if ( ( elem = unmatched[ i ] ) ) { + if ( !filter || filter( elem, context, xml ) ) { + newUnmatched.push( elem ); + if ( mapped ) { + map.push( i ); + } + } + } + } + + return newUnmatched; } function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) { - if ( postFilter && !postFilter[ expando ] ) { - postFilter = setMatcher( postFilter ); - } - if ( postFinder && !postFinder[ expando ] ) { - postFinder = setMatcher( postFinder, postSelector ); - } - return markFunction(function( seed, results, context, xml ) { - var temp, i, elem, - preMap = [], - postMap = [], - preexisting = results.length, - - // Get initial elements from seed or context - elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ), - - // Prefilter to get matcher input, preserving a map for seed-results synchronization - matcherIn = preFilter && ( seed || !selector ) ? - condense( elems, preMap, preFilter, context, xml ) : - elems, - - matcherOut = matcher ? - // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results, - postFinder || ( seed ? preFilter : preexisting || postFilter ) ? - - // ...intermediate processing is necessary - [] : - - // ...otherwise use results directly - results : - matcherIn; - - // Find primary matches - if ( matcher ) { - matcher( matcherIn, matcherOut, context, xml ); - } - - // Apply postFilter - if ( postFilter ) { - temp = condense( matcherOut, postMap ); - postFilter( temp, [], context, xml ); - - // Un-match failing elements by moving them back to matcherIn - i = temp.length; - while ( i-- ) { - if ( (elem = temp[i]) ) { - matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem); - } - } - } - - if ( seed ) { - if ( postFinder || preFilter ) { - if ( postFinder ) { - // Get the final matcherOut by condensing this intermediate into postFinder contexts - temp = []; - i = matcherOut.length; - while ( i-- ) { - if ( (elem = matcherOut[i]) ) { - // Restore matcherIn since elem is not yet a final match - temp.push( (matcherIn[i] = elem) ); - } - } - postFinder( null, (matcherOut = []), temp, xml ); - } - - // Move matched elements from seed to results to keep them synchronized - i = matcherOut.length; - while ( i-- ) { - if ( (elem = matcherOut[i]) && - (temp = postFinder ? indexOf( seed, elem ) : preMap[i]) > -1 ) { - - seed[temp] = !(results[temp] = elem); - } - } - } - - // Add elements to results, through postFinder if defined - } else { - matcherOut = condense( - matcherOut === results ? - matcherOut.splice( preexisting, matcherOut.length ) : - matcherOut - ); - if ( postFinder ) { - postFinder( null, results, matcherOut, xml ); - } else { - push.apply( results, matcherOut ); - } - } - }); + if ( postFilter && !postFilter[ expando ] ) { + postFilter = setMatcher( postFilter ); + } + if ( postFinder && !postFinder[ expando ] ) { + postFinder = setMatcher( postFinder, postSelector ); + } + return markFunction( function( seed, results, context, xml ) { + var temp, i, elem, + preMap = [], + postMap = [], + preexisting = results.length, + + // Get initial elements from seed or context + elems = seed || multipleContexts( + selector || "*", + context.nodeType ? [ context ] : context, + [] + ), + + // Prefilter to get matcher input, preserving a map for seed-results synchronization + matcherIn = preFilter && ( seed || !selector ) ? + condense( elems, preMap, preFilter, context, xml ) : + elems, + + matcherOut = matcher ? + + // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results, + postFinder || ( seed ? preFilter : preexisting || postFilter ) ? + + // ...intermediate processing is necessary + [] : + + // ...otherwise use results directly + results : + matcherIn; + + // Find primary matches + if ( matcher ) { + matcher( matcherIn, matcherOut, context, xml ); + } + + // Apply postFilter + if ( postFilter ) { + temp = condense( matcherOut, postMap ); + postFilter( temp, [], context, xml ); + + // Un-match failing elements by moving them back to matcherIn + i = temp.length; + while ( i-- ) { + if ( ( elem = temp[ i ] ) ) { + matcherOut[ postMap[ i ] ] = !( matcherIn[ postMap[ i ] ] = elem ); + } + } + } + + if ( seed ) { + if ( postFinder || preFilter ) { + if ( postFinder ) { + + // Get the final matcherOut by condensing this intermediate into postFinder contexts + temp = []; + i = matcherOut.length; + while ( i-- ) { + if ( ( elem = matcherOut[ i ] ) ) { + + // Restore matcherIn since elem is not yet a final match + temp.push( ( matcherIn[ i ] = elem ) ); + } + } + postFinder( null, ( matcherOut = [] ), temp, xml ); + } + + // Move matched elements from seed to results to keep them synchronized + i = matcherOut.length; + while ( i-- ) { + if ( ( elem = matcherOut[ i ] ) && + ( temp = postFinder ? indexOf( seed, elem ) : preMap[ i ] ) > -1 ) { + + seed[ temp ] = !( results[ temp ] = elem ); + } + } + } + + // Add elements to results, through postFinder if defined + } else { + matcherOut = condense( + matcherOut === results ? + matcherOut.splice( preexisting, matcherOut.length ) : + matcherOut + ); + if ( postFinder ) { + postFinder( null, results, matcherOut, xml ); + } else { + push.apply( results, matcherOut ); + } + } + } ); } function matcherFromTokens( tokens ) { - var checkContext, matcher, j, - len = tokens.length, - leadingRelative = Expr.relative[ tokens[0].type ], - implicitRelative = leadingRelative || Expr.relative[" "], - i = leadingRelative ? 1 : 0, - - // The foundational matcher ensures that elements are reachable from top-level context(s) - matchContext = addCombinator( function( elem ) { - return elem === checkContext; - }, implicitRelative, true ), - matchAnyContext = addCombinator( function( elem ) { - return indexOf( checkContext, elem ) > -1; - }, implicitRelative, true ), - matchers = [ function( elem, context, xml ) { - var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || ( - (checkContext = context).nodeType ? - matchContext( elem, context, xml ) : - matchAnyContext( elem, context, xml ) ); - // Avoid hanging onto element (issue #299) - checkContext = null; - return ret; - } ]; - - for ( ; i < len; i++ ) { - if ( (matcher = Expr.relative[ tokens[i].type ]) ) { - matchers = [ addCombinator(elementMatcher( matchers ), matcher) ]; - } else { - matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches ); - - // Return special upon seeing a positional matcher - if ( matcher[ expando ] ) { - // Find the next relative operator (if any) for proper handling - j = ++i; - for ( ; j < len; j++ ) { - if ( Expr.relative[ tokens[j].type ] ) { - break; - } - } - return setMatcher( - i > 1 && elementMatcher( matchers ), - i > 1 && toSelector( - // If the preceding token was a descendant combinator, insert an implicit any-element `*` - tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" }) - ).replace( rtrim, "$1" ), - matcher, - i < j && matcherFromTokens( tokens.slice( i, j ) ), - j < len && matcherFromTokens( (tokens = tokens.slice( j )) ), - j < len && toSelector( tokens ) - ); - } - matchers.push( matcher ); - } - } - - return elementMatcher( matchers ); + var checkContext, matcher, j, + len = tokens.length, + leadingRelative = Expr.relative[ tokens[ 0 ].type ], + implicitRelative = leadingRelative || Expr.relative[ " " ], + i = leadingRelative ? 1 : 0, + + // The foundational matcher ensures that elements are reachable from top-level context(s) + matchContext = addCombinator( function( elem ) { + return elem === checkContext; + }, implicitRelative, true ), + matchAnyContext = addCombinator( function( elem ) { + return indexOf( checkContext, elem ) > -1; + }, implicitRelative, true ), + matchers = [ function( elem, context, xml ) { + var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || ( + ( checkContext = context ).nodeType ? + matchContext( elem, context, xml ) : + matchAnyContext( elem, context, xml ) ); + + // Avoid hanging onto element (issue #299) + checkContext = null; + return ret; + } ]; + + for ( ; i < len; i++ ) { + if ( ( matcher = Expr.relative[ tokens[ i ].type ] ) ) { + matchers = [ addCombinator( elementMatcher( matchers ), matcher ) ]; + } else { + matcher = Expr.filter[ tokens[ i ].type ].apply( null, tokens[ i ].matches ); + + // Return special upon seeing a positional matcher + if ( matcher[ expando ] ) { + + // Find the next relative operator (if any) for proper handling + j = ++i; + for ( ; j < len; j++ ) { + if ( Expr.relative[ tokens[ j ].type ] ) { + break; + } + } + return setMatcher( + i > 1 && elementMatcher( matchers ), + i > 1 && toSelector( + + // If the preceding token was a descendant combinator, insert an implicit any-element `*` + tokens + .slice( 0, i - 1 ) + .concat( { value: tokens[ i - 2 ].type === " " ? "*" : "" } ) + ).replace( rtrim, "$1" ), + matcher, + i < j && matcherFromTokens( tokens.slice( i, j ) ), + j < len && matcherFromTokens( ( tokens = tokens.slice( j ) ) ), + j < len && toSelector( tokens ) + ); + } + matchers.push( matcher ); + } + } + + return elementMatcher( matchers ); } function matcherFromGroupMatchers( elementMatchers, setMatchers ) { - var bySet = setMatchers.length > 0, - byElement = elementMatchers.length > 0, - superMatcher = function( seed, context, xml, results, outermost ) { - var elem, j, matcher, - matchedCount = 0, - i = "0", - unmatched = seed && [], - setMatched = [], - contextBackup = outermostContext, - // We must always have either seed elements or outermost context - elems = seed || byElement && Expr.find["TAG"]( "*", outermost ), - // Use integer dirruns iff this is the outermost matcher - dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1), - len = elems.length; - - if ( outermost ) { - outermostContext = context === document || context || outermost; - } - - // Add elements passing elementMatchers directly to results - // Support: IE<9, Safari - // Tolerate NodeList properties (IE: "length"; Safari: ) matching elements by id - for ( ; i !== len && (elem = elems[i]) != null; i++ ) { - if ( byElement && elem ) { - j = 0; - if ( !context && elem.ownerDocument !== document ) { - setDocument( elem ); - xml = !documentIsHTML; - } - while ( (matcher = elementMatchers[j++]) ) { - if ( matcher( elem, context || document, xml) ) { - results.push( elem ); - break; - } - } - if ( outermost ) { - dirruns = dirrunsUnique; - } - } - - // Track unmatched elements for set filters - if ( bySet ) { - // They will have gone through all possible matchers - if ( (elem = !matcher && elem) ) { - matchedCount--; - } - - // Lengthen the array for every element, matched or not - if ( seed ) { - unmatched.push( elem ); - } - } - } - - // `i` is now the count of elements visited above, and adding it to `matchedCount` - // makes the latter nonnegative. - matchedCount += i; - - // Apply set filters to unmatched elements - // NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount` - // equals `i`), unless we didn't visit _any_ elements in the above loop because we have - // no element matchers and no seed. - // Incrementing an initially-string "0" `i` allows `i` to remain a string only in that - // case, which will result in a "00" `matchedCount` that differs from `i` but is also - // numerically zero. - if ( bySet && i !== matchedCount ) { - j = 0; - while ( (matcher = setMatchers[j++]) ) { - matcher( unmatched, setMatched, context, xml ); - } - - if ( seed ) { - // Reintegrate element matches to eliminate the need for sorting - if ( matchedCount > 0 ) { - while ( i-- ) { - if ( !(unmatched[i] || setMatched[i]) ) { - setMatched[i] = pop.call( results ); - } - } - } - - // Discard index placeholder values to get only actual matches - setMatched = condense( setMatched ); - } - - // Add matches to results - push.apply( results, setMatched ); - - // Seedless set matches succeeding multiple successful matchers stipulate sorting - if ( outermost && !seed && setMatched.length > 0 && - ( matchedCount + setMatchers.length ) > 1 ) { - - Sizzle.uniqueSort( results ); - } - } - - // Override manipulation of globals by nested matchers - if ( outermost ) { - dirruns = dirrunsUnique; - outermostContext = contextBackup; - } - - return unmatched; - }; - - return bySet ? - markFunction( superMatcher ) : - superMatcher; + var bySet = setMatchers.length > 0, + byElement = elementMatchers.length > 0, + superMatcher = function( seed, context, xml, results, outermost ) { + var elem, j, matcher, + matchedCount = 0, + i = "0", + unmatched = seed && [], + setMatched = [], + contextBackup = outermostContext, + + // We must always have either seed elements or outermost context + elems = seed || byElement && Expr.find[ "TAG" ]( "*", outermost ), + + // Use integer dirruns iff this is the outermost matcher + dirrunsUnique = ( dirruns += contextBackup == null ? 1 : Math.random() || 0.1 ), + len = elems.length; + + if ( outermost ) { + + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + outermostContext = context == document || context || outermost; + } + + // Add elements passing elementMatchers directly to results + // Support: IE<9, Safari + // Tolerate NodeList properties (IE: "length"; Safari: ) matching elements by id + for ( ; i !== len && ( elem = elems[ i ] ) != null; i++ ) { + if ( byElement && elem ) { + j = 0; + + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( !context && elem.ownerDocument != document ) { + setDocument( elem ); + xml = !documentIsHTML; + } + while ( ( matcher = elementMatchers[ j++ ] ) ) { + if ( matcher( elem, context || document, xml ) ) { + results.push( elem ); + break; + } + } + if ( outermost ) { + dirruns = dirrunsUnique; + } + } + + // Track unmatched elements for set filters + if ( bySet ) { + + // They will have gone through all possible matchers + if ( ( elem = !matcher && elem ) ) { + matchedCount--; + } + + // Lengthen the array for every element, matched or not + if ( seed ) { + unmatched.push( elem ); + } + } + } + + // `i` is now the count of elements visited above, and adding it to `matchedCount` + // makes the latter nonnegative. + matchedCount += i; + + // Apply set filters to unmatched elements + // NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount` + // equals `i`), unless we didn't visit _any_ elements in the above loop because we have + // no element matchers and no seed. + // Incrementing an initially-string "0" `i` allows `i` to remain a string only in that + // case, which will result in a "00" `matchedCount` that differs from `i` but is also + // numerically zero. + if ( bySet && i !== matchedCount ) { + j = 0; + while ( ( matcher = setMatchers[ j++ ] ) ) { + matcher( unmatched, setMatched, context, xml ); + } + + if ( seed ) { + + // Reintegrate element matches to eliminate the need for sorting + if ( matchedCount > 0 ) { + while ( i-- ) { + if ( !( unmatched[ i ] || setMatched[ i ] ) ) { + setMatched[ i ] = pop.call( results ); + } + } + } + + // Discard index placeholder values to get only actual matches + setMatched = condense( setMatched ); + } + + // Add matches to results + push.apply( results, setMatched ); + + // Seedless set matches succeeding multiple successful matchers stipulate sorting + if ( outermost && !seed && setMatched.length > 0 && + ( matchedCount + setMatchers.length ) > 1 ) { + + Sizzle.uniqueSort( results ); + } + } + + // Override manipulation of globals by nested matchers + if ( outermost ) { + dirruns = dirrunsUnique; + outermostContext = contextBackup; + } + + return unmatched; + }; + + return bySet ? + markFunction( superMatcher ) : + superMatcher; } compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) { - var i, - setMatchers = [], - elementMatchers = [], - cached = compilerCache[ selector + " " ]; - - if ( !cached ) { - // Generate a function of recursive functions that can be used to check each element - if ( !match ) { - match = tokenize( selector ); - } - i = match.length; - while ( i-- ) { - cached = matcherFromTokens( match[i] ); - if ( cached[ expando ] ) { - setMatchers.push( cached ); - } else { - elementMatchers.push( cached ); - } - } - - // Cache the compiled function - cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) ); - - // Save selector and tokenization - cached.selector = selector; - } - return cached; + var i, + setMatchers = [], + elementMatchers = [], + cached = compilerCache[ selector + " " ]; + + if ( !cached ) { + + // Generate a function of recursive functions that can be used to check each element + if ( !match ) { + match = tokenize( selector ); + } + i = match.length; + while ( i-- ) { + cached = matcherFromTokens( match[ i ] ); + if ( cached[ expando ] ) { + setMatchers.push( cached ); + } else { + elementMatchers.push( cached ); + } + } + + // Cache the compiled function + cached = compilerCache( + selector, + matcherFromGroupMatchers( elementMatchers, setMatchers ) + ); + + // Save selector and tokenization + cached.selector = selector; + } + return cached; }; /** @@ -2536,80 +2833,82 @@ compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) { * @param {Array} [seed] A set of elements to match against */ select = Sizzle.select = function( selector, context, results, seed ) { - var i, tokens, token, type, find, - compiled = typeof selector === "function" && selector, - match = !seed && tokenize( (selector = compiled.selector || selector) ); - - results = results || []; - - // Try to minimize operations if there is only one selector in the list and no seed - // (the latter of which guarantees us context) - if ( match.length === 1 ) { - - // Reduce context if the leading compound selector is an ID - tokens = match[0] = match[0].slice( 0 ); - if ( tokens.length > 2 && (token = tokens[0]).type === "ID" && - support.getById && context.nodeType === 9 && documentIsHTML && - Expr.relative[ tokens[1].type ] ) { - - context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0]; - if ( !context ) { - return results; - - // Precompiled matchers will still verify ancestry, so step up a level - } else if ( compiled ) { - context = context.parentNode; - } - - selector = selector.slice( tokens.shift().value.length ); - } - - // Fetch a seed set for right-to-left matching - i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length; - while ( i-- ) { - token = tokens[i]; - - // Abort if we hit a combinator - if ( Expr.relative[ (type = token.type) ] ) { - break; - } - if ( (find = Expr.find[ type ]) ) { - // Search, expanding context for leading sibling combinators - if ( (seed = find( - token.matches[0].replace( runescape, funescape ), - rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context - )) ) { - - // If seed is empty or no tokens remain, we can return early - tokens.splice( i, 1 ); - selector = seed.length && toSelector( tokens ); - if ( !selector ) { - push.apply( results, seed ); - return results; - } - - break; - } - } - } - } - - // Compile and execute a filtering function if one is not provided - // Provide `match` to avoid retokenization if we modified the selector above - ( compiled || compile( selector, match ) )( - seed, - context, - !documentIsHTML, - results, - !context || rsibling.test( selector ) && testContext( context.parentNode ) || context - ); - return results; + var i, tokens, token, type, find, + compiled = typeof selector === "function" && selector, + match = !seed && tokenize( ( selector = compiled.selector || selector ) ); + + results = results || []; + + // Try to minimize operations if there is only one selector in the list and no seed + // (the latter of which guarantees us context) + if ( match.length === 1 ) { + + // Reduce context if the leading compound selector is an ID + tokens = match[ 0 ] = match[ 0 ].slice( 0 ); + if ( tokens.length > 2 && ( token = tokens[ 0 ] ).type === "ID" && + context.nodeType === 9 && documentIsHTML && Expr.relative[ tokens[ 1 ].type ] ) { + + context = ( Expr.find[ "ID" ]( token.matches[ 0 ] + .replace( runescape, funescape ), context ) || [] )[ 0 ]; + if ( !context ) { + return results; + + // Precompiled matchers will still verify ancestry, so step up a level + } else if ( compiled ) { + context = context.parentNode; + } + + selector = selector.slice( tokens.shift().value.length ); + } + + // Fetch a seed set for right-to-left matching + i = matchExpr[ "needsContext" ].test( selector ) ? 0 : tokens.length; + while ( i-- ) { + token = tokens[ i ]; + + // Abort if we hit a combinator + if ( Expr.relative[ ( type = token.type ) ] ) { + break; + } + if ( ( find = Expr.find[ type ] ) ) { + + // Search, expanding context for leading sibling combinators + if ( ( seed = find( + token.matches[ 0 ].replace( runescape, funescape ), + rsibling.test( tokens[ 0 ].type ) && testContext( context.parentNode ) || + context + ) ) ) { + + // If seed is empty or no tokens remain, we can return early + tokens.splice( i, 1 ); + selector = seed.length && toSelector( tokens ); + if ( !selector ) { + push.apply( results, seed ); + return results; + } + + break; + } + } + } + } + + // Compile and execute a filtering function if one is not provided + // Provide `match` to avoid retokenization if we modified the selector above + ( compiled || compile( selector, match ) )( + seed, + context, + !documentIsHTML, + results, + !context || rsibling.test( selector ) && testContext( context.parentNode ) || context + ); + return results; }; // One-time assignments // Sort stability -support.sortStable = expando.split("").sort( sortOrder ).join("") === expando; +support.sortStable = expando.split( "" ).sort( sortOrder ).join( "" ) === expando; // Support: Chrome 14-35+ // Always assume duplicates if they aren't passed to the comparison function @@ -2620,196 +2919,202 @@ setDocument(); // Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27) // Detached nodes confoundingly follow *each other* -support.sortDetached = assert(function( div1 ) { - // Should return 1, but returns 4 (following) - return div1.compareDocumentPosition( document.createElement("div") ) & 1; -}); +support.sortDetached = assert( function( el ) { + + // Should return 1, but returns 4 (following) + return el.compareDocumentPosition( document.createElement( "fieldset" ) ) & 1; +} ); // Support: IE<8 // Prevent attribute/property "interpolation" // https://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx -if ( !assert(function( div ) { - div.innerHTML = ""; - return div.firstChild.getAttribute("href") === "#" ; -}) ) { - addHandle( "type|href|height|width", function( elem, name, isXML ) { - if ( !isXML ) { - return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 ); - } - }); +if ( !assert( function( el ) { + el.innerHTML = ""; + return el.firstChild.getAttribute( "href" ) === "#"; +} ) ) { + addHandle( "type|href|height|width", function( elem, name, isXML ) { + if ( !isXML ) { + return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 ); + } + } ); } // Support: IE<9 // Use defaultValue in place of getAttribute("value") -if ( !support.attributes || !assert(function( div ) { - div.innerHTML = ""; - div.firstChild.setAttribute( "value", "" ); - return div.firstChild.getAttribute( "value" ) === ""; -}) ) { - addHandle( "value", function( elem, name, isXML ) { - if ( !isXML && elem.nodeName.toLowerCase() === "input" ) { - return elem.defaultValue; - } - }); +if ( !support.attributes || !assert( function( el ) { + el.innerHTML = ""; + el.firstChild.setAttribute( "value", "" ); + return el.firstChild.getAttribute( "value" ) === ""; +} ) ) { + addHandle( "value", function( elem, _name, isXML ) { + if ( !isXML && elem.nodeName.toLowerCase() === "input" ) { + return elem.defaultValue; + } + } ); } // Support: IE<9 // Use getAttributeNode to fetch booleans when getAttribute lies -if ( !assert(function( div ) { - return div.getAttribute("disabled") == null; -}) ) { - addHandle( booleans, function( elem, name, isXML ) { - var val; - if ( !isXML ) { - return elem[ name ] === true ? name.toLowerCase() : - (val = elem.getAttributeNode( name )) && val.specified ? - val.value : - null; - } - }); +if ( !assert( function( el ) { + return el.getAttribute( "disabled" ) == null; +} ) ) { + addHandle( booleans, function( elem, name, isXML ) { + var val; + if ( !isXML ) { + return elem[ name ] === true ? name.toLowerCase() : + ( val = elem.getAttributeNode( name ) ) && val.specified ? + val.value : + null; + } + } ); } return Sizzle; -})( window ); +} )( window ); jQuery.find = Sizzle; jQuery.expr = Sizzle.selectors; + +// Deprecated jQuery.expr[ ":" ] = jQuery.expr.pseudos; jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort; jQuery.text = Sizzle.getText; jQuery.isXMLDoc = Sizzle.isXML; jQuery.contains = Sizzle.contains; +jQuery.escapeSelector = Sizzle.escape; + var dir = function( elem, dir, until ) { - var matched = [], - truncate = until !== undefined; - - while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) { - if ( elem.nodeType === 1 ) { - if ( truncate && jQuery( elem ).is( until ) ) { - break; - } - matched.push( elem ); - } - } - return matched; + var matched = [], + truncate = until !== undefined; + + while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) { + if ( elem.nodeType === 1 ) { + if ( truncate && jQuery( elem ).is( until ) ) { + break; + } + matched.push( elem ); + } + } + return matched; }; var siblings = function( n, elem ) { - var matched = []; + var matched = []; - for ( ; n; n = n.nextSibling ) { - if ( n.nodeType === 1 && n !== elem ) { - matched.push( n ); - } - } + for ( ; n; n = n.nextSibling ) { + if ( n.nodeType === 1 && n !== elem ) { + matched.push( n ); + } + } - return matched; + return matched; }; var rneedsContext = jQuery.expr.match.needsContext; -var rsingleTag = ( /^<([\w-]+)\s*\/?>(?:<\/\1>|)$/ ); - -var risSimple = /^.[^:#\[\.,]*$/; - -// Implement the identical functionality for filter and not -function winnow( elements, qualifier, not ) { - if ( jQuery.isFunction( qualifier ) ) { - return jQuery.grep( elements, function( elem, i ) { - /* jshint -W018 */ - return !!qualifier.call( elem, i, elem ) !== not; - } ); - - } +function nodeName( elem, name ) { - if ( qualifier.nodeType ) { - return jQuery.grep( elements, function( elem ) { - return ( elem === qualifier ) !== not; - } ); + return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); - } +}; +var rsingleTag = ( /^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i ); - if ( typeof qualifier === "string" ) { - if ( risSimple.test( qualifier ) ) { - return jQuery.filter( qualifier, elements, not ); - } - qualifier = jQuery.filter( qualifier, elements ); - } - return jQuery.grep( elements, function( elem ) { - return ( indexOf.call( qualifier, elem ) > -1 ) !== not; - } ); +// Implement the identical functionality for filter and not +function winnow( elements, qualifier, not ) { + if ( isFunction( qualifier ) ) { + return jQuery.grep( elements, function( elem, i ) { + return !!qualifier.call( elem, i, elem ) !== not; + } ); + } + + // Single element + if ( qualifier.nodeType ) { + return jQuery.grep( elements, function( elem ) { + return ( elem === qualifier ) !== not; + } ); + } + + // Arraylike of elements (jQuery, arguments, Array) + if ( typeof qualifier !== "string" ) { + return jQuery.grep( elements, function( elem ) { + return ( indexOf.call( qualifier, elem ) > -1 ) !== not; + } ); + } + + // Filtered directly for both simple and complex selectors + return jQuery.filter( qualifier, elements, not ); } jQuery.filter = function( expr, elems, not ) { - var elem = elems[ 0 ]; + var elem = elems[ 0 ]; + + if ( not ) { + expr = ":not(" + expr + ")"; + } - if ( not ) { - expr = ":not(" + expr + ")"; - } + if ( elems.length === 1 && elem.nodeType === 1 ) { + return jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : []; + } - return elems.length === 1 && elem.nodeType === 1 ? - jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] : - jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) { - return elem.nodeType === 1; - } ) ); + return jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) { + return elem.nodeType === 1; + } ) ); }; jQuery.fn.extend( { - find: function( selector ) { - var i, - len = this.length, - ret = [], - self = this; - - if ( typeof selector !== "string" ) { - return this.pushStack( jQuery( selector ).filter( function() { - for ( i = 0; i < len; i++ ) { - if ( jQuery.contains( self[ i ], this ) ) { - return true; - } - } - } ) ); - } - - for ( i = 0; i < len; i++ ) { - jQuery.find( selector, self[ i ], ret ); - } - - // Needed because $( selector, context ) becomes $( context ).find( selector ) - ret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret ); - ret.selector = this.selector ? this.selector + " " + selector : selector; - return ret; - }, - filter: function( selector ) { - return this.pushStack( winnow( this, selector || [], false ) ); - }, - not: function( selector ) { - return this.pushStack( winnow( this, selector || [], true ) ); - }, - is: function( selector ) { - return !!winnow( - this, - - // If this is a positional/relative selector, check membership in the returned set - // so $("p:first").is("p:last") won't return true for a doc with two "p". - typeof selector === "string" && rneedsContext.test( selector ) ? - jQuery( selector ) : - selector || [], - false - ).length; - } + find: function( selector ) { + var i, ret, + len = this.length, + self = this; + + if ( typeof selector !== "string" ) { + return this.pushStack( jQuery( selector ).filter( function() { + for ( i = 0; i < len; i++ ) { + if ( jQuery.contains( self[ i ], this ) ) { + return true; + } + } + } ) ); + } + + ret = this.pushStack( [] ); + + for ( i = 0; i < len; i++ ) { + jQuery.find( selector, self[ i ], ret ); + } + + return len > 1 ? jQuery.uniqueSort( ret ) : ret; + }, + filter: function( selector ) { + return this.pushStack( winnow( this, selector || [], false ) ); + }, + not: function( selector ) { + return this.pushStack( winnow( this, selector || [], true ) ); + }, + is: function( selector ) { + return !!winnow( + this, + + // If this is a positional/relative selector, check membership in the returned set + // so $("p:first").is("p:last") won't return true for a doc with two "p". + typeof selector === "string" && rneedsContext.test( selector ) ? + jQuery( selector ) : + selector || [], + false + ).length; + } } ); @@ -2819,119 +3124,110 @@ jQuery.fn.extend( { // A central reference to the root jQuery(document) var rootjQuery, - // A simple way to check for HTML strings - // Prioritize #id over to avoid XSS via location.hash (#9521) - // Strict HTML recognition (#11290: must start with <) - rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/, - - init = jQuery.fn.init = function( selector, context, root ) { - var match, elem; - - // HANDLE: $(""), $(null), $(undefined), $(false) - if ( !selector ) { - return this; - } - - // Method init() accepts an alternate rootjQuery - // so migrate can support jQuery.sub (gh-2101) - root = root || rootjQuery; - - // Handle HTML strings - if ( typeof selector === "string" ) { - if ( selector[ 0 ] === "<" && - selector[ selector.length - 1 ] === ">" && - selector.length >= 3 ) { - - // Assume that strings that start and end with <> are HTML and skip the regex check - match = [ null, selector, null ]; - - } else { - match = rquickExpr.exec( selector ); - } - - // Match html or make sure no context is specified for #id - if ( match && ( match[ 1 ] || !context ) ) { - - // HANDLE: $(html) -> $(array) - if ( match[ 1 ] ) { - context = context instanceof jQuery ? context[ 0 ] : context; - - // Option to run scripts is true for back-compat - // Intentionally let the error be thrown if parseHTML is not present - jQuery.merge( this, jQuery.parseHTML( - match[ 1 ], - context && context.nodeType ? context.ownerDocument || context : document, - true - ) ); - - // HANDLE: $(html, props) - if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) { - for ( match in context ) { - - // Properties of context are called as methods if possible - if ( jQuery.isFunction( this[ match ] ) ) { - this[ match ]( context[ match ] ); - - // ...and otherwise set as attributes - } else { - this.attr( match, context[ match ] ); - } - } - } - - return this; - - // HANDLE: $(#id) - } else { - elem = document.getElementById( match[ 2 ] ); - - // Support: Blackberry 4.6 - // gEBID returns nodes no longer in the document (#6963) - if ( elem && elem.parentNode ) { - - // Inject the element directly into the jQuery object - this.length = 1; - this[ 0 ] = elem; - } - - this.context = document; - this.selector = selector; - return this; - } - - // HANDLE: $(expr, $(...)) - } else if ( !context || context.jquery ) { - return ( context || root ).find( selector ); - - // HANDLE: $(expr, context) - // (which is just equivalent to: $(context).find(expr) - } else { - return this.constructor( context ).find( selector ); - } - - // HANDLE: $(DOMElement) - } else if ( selector.nodeType ) { - this.context = this[ 0 ] = selector; - this.length = 1; - return this; - - // HANDLE: $(function) - // Shortcut for document ready - } else if ( jQuery.isFunction( selector ) ) { - return root.ready !== undefined ? - root.ready( selector ) : - - // Execute immediately if ready is not present - selector( jQuery ); - } - - if ( selector.selector !== undefined ) { - this.selector = selector.selector; - this.context = selector.context; - } - - return jQuery.makeArray( selector, this ); - }; + // A simple way to check for HTML strings + // Prioritize #id over to avoid XSS via location.hash (#9521) + // Strict HTML recognition (#11290: must start with <) + // Shortcut simple #id case for speed + rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/, + + init = jQuery.fn.init = function( selector, context, root ) { + var match, elem; + + // HANDLE: $(""), $(null), $(undefined), $(false) + if ( !selector ) { + return this; + } + + // Method init() accepts an alternate rootjQuery + // so migrate can support jQuery.sub (gh-2101) + root = root || rootjQuery; + + // Handle HTML strings + if ( typeof selector === "string" ) { + if ( selector[ 0 ] === "<" && + selector[ selector.length - 1 ] === ">" && + selector.length >= 3 ) { + + // Assume that strings that start and end with <> are HTML and skip the regex check + match = [ null, selector, null ]; + + } else { + match = rquickExpr.exec( selector ); + } + + // Match html or make sure no context is specified for #id + if ( match && ( match[ 1 ] || !context ) ) { + + // HANDLE: $(html) -> $(array) + if ( match[ 1 ] ) { + context = context instanceof jQuery ? context[ 0 ] : context; + + // Option to run scripts is true for back-compat + // Intentionally let the error be thrown if parseHTML is not present + jQuery.merge( this, jQuery.parseHTML( + match[ 1 ], + context && context.nodeType ? context.ownerDocument || context : document, + true + ) ); + + // HANDLE: $(html, props) + if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) { + for ( match in context ) { + + // Properties of context are called as methods if possible + if ( isFunction( this[ match ] ) ) { + this[ match ]( context[ match ] ); + + // ...and otherwise set as attributes + } else { + this.attr( match, context[ match ] ); + } + } + } + + return this; + + // HANDLE: $(#id) + } else { + elem = document.getElementById( match[ 2 ] ); + + if ( elem ) { + + // Inject the element directly into the jQuery object + this[ 0 ] = elem; + this.length = 1; + } + return this; + } + + // HANDLE: $(expr, $(...)) + } else if ( !context || context.jquery ) { + return ( context || root ).find( selector ); + + // HANDLE: $(expr, context) + // (which is just equivalent to: $(context).find(expr) + } else { + return this.constructor( context ).find( selector ); + } + + // HANDLE: $(DOMElement) + } else if ( selector.nodeType ) { + this[ 0 ] = selector; + this.length = 1; + return this; + + // HANDLE: $(function) + // Shortcut for document ready + } else if ( isFunction( selector ) ) { + return root.ready !== undefined ? + root.ready( selector ) : + + // Execute immediately if ready is not present + selector( jQuery ); + } + + return jQuery.makeArray( selector, this ); + }; // Give the init function the jQuery prototype for later instantiation init.prototype = jQuery.fn; @@ -2942,640 +3238,902 @@ rootjQuery = jQuery( document ); var rparentsprev = /^(?:parents|prev(?:Until|All))/, - // Methods guaranteed to produce a unique set when starting from a unique set - guaranteedUnique = { - children: true, - contents: true, - next: true, - prev: true - }; + // Methods guaranteed to produce a unique set when starting from a unique set + guaranteedUnique = { + children: true, + contents: true, + next: true, + prev: true + }; jQuery.fn.extend( { - has: function( target ) { - var targets = jQuery( target, this ), - l = targets.length; - - return this.filter( function() { - var i = 0; - for ( ; i < l; i++ ) { - if ( jQuery.contains( this, targets[ i ] ) ) { - return true; - } - } - } ); - }, - - closest: function( selectors, context ) { - var cur, - i = 0, - l = this.length, - matched = [], - pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ? - jQuery( selectors, context || this.context ) : - 0; - - for ( ; i < l; i++ ) { - for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) { - - // Always skip document fragments - if ( cur.nodeType < 11 && ( pos ? - pos.index( cur ) > -1 : - - // Don't pass non-elements to Sizzle - cur.nodeType === 1 && - jQuery.find.matchesSelector( cur, selectors ) ) ) { - - matched.push( cur ); - break; - } - } - } - - return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched ); - }, - - // Determine the position of an element within the set - index: function( elem ) { - - // No argument, return index in parent - if ( !elem ) { - return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1; - } - - // Index in selector - if ( typeof elem === "string" ) { - return indexOf.call( jQuery( elem ), this[ 0 ] ); - } - - // Locate the position of the desired element - return indexOf.call( this, - - // If it receives a jQuery object, the first element is used - elem.jquery ? elem[ 0 ] : elem - ); - }, - - add: function( selector, context ) { - return this.pushStack( - jQuery.uniqueSort( - jQuery.merge( this.get(), jQuery( selector, context ) ) - ) - ); - }, - - addBack: function( selector ) { - return this.add( selector == null ? - this.prevObject : this.prevObject.filter( selector ) - ); - } + has: function( target ) { + var targets = jQuery( target, this ), + l = targets.length; + + return this.filter( function() { + var i = 0; + for ( ; i < l; i++ ) { + if ( jQuery.contains( this, targets[ i ] ) ) { + return true; + } + } + } ); + }, + + closest: function( selectors, context ) { + var cur, + i = 0, + l = this.length, + matched = [], + targets = typeof selectors !== "string" && jQuery( selectors ); + + // Positional selectors never match, since there's no _selection_ context + if ( !rneedsContext.test( selectors ) ) { + for ( ; i < l; i++ ) { + for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) { + + // Always skip document fragments + if ( cur.nodeType < 11 && ( targets ? + targets.index( cur ) > -1 : + + // Don't pass non-elements to Sizzle + cur.nodeType === 1 && + jQuery.find.matchesSelector( cur, selectors ) ) ) { + + matched.push( cur ); + break; + } + } + } + } + + return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched ); + }, + + // Determine the position of an element within the set + index: function( elem ) { + + // No argument, return index in parent + if ( !elem ) { + return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1; + } + + // Index in selector + if ( typeof elem === "string" ) { + return indexOf.call( jQuery( elem ), this[ 0 ] ); + } + + // Locate the position of the desired element + return indexOf.call( this, + + // If it receives a jQuery object, the first element is used + elem.jquery ? elem[ 0 ] : elem + ); + }, + + add: function( selector, context ) { + return this.pushStack( + jQuery.uniqueSort( + jQuery.merge( this.get(), jQuery( selector, context ) ) + ) + ); + }, + + addBack: function( selector ) { + return this.add( selector == null ? + this.prevObject : this.prevObject.filter( selector ) + ); + } } ); function sibling( cur, dir ) { - while ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {} - return cur; + while ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {} + return cur; } jQuery.each( { - parent: function( elem ) { - var parent = elem.parentNode; - return parent && parent.nodeType !== 11 ? parent : null; - }, - parents: function( elem ) { - return dir( elem, "parentNode" ); - }, - parentsUntil: function( elem, i, until ) { - return dir( elem, "parentNode", until ); - }, - next: function( elem ) { - return sibling( elem, "nextSibling" ); - }, - prev: function( elem ) { - return sibling( elem, "previousSibling" ); - }, - nextAll: function( elem ) { - return dir( elem, "nextSibling" ); - }, - prevAll: function( elem ) { - return dir( elem, "previousSibling" ); - }, - nextUntil: function( elem, i, until ) { - return dir( elem, "nextSibling", until ); - }, - prevUntil: function( elem, i, until ) { - return dir( elem, "previousSibling", until ); - }, - siblings: function( elem ) { - return siblings( ( elem.parentNode || {} ).firstChild, elem ); - }, - children: function( elem ) { - return siblings( elem.firstChild ); - }, - contents: function( elem ) { - return elem.contentDocument || jQuery.merge( [], elem.childNodes ); - } + parent: function( elem ) { + var parent = elem.parentNode; + return parent && parent.nodeType !== 11 ? parent : null; + }, + parents: function( elem ) { + return dir( elem, "parentNode" ); + }, + parentsUntil: function( elem, _i, until ) { + return dir( elem, "parentNode", until ); + }, + next: function( elem ) { + return sibling( elem, "nextSibling" ); + }, + prev: function( elem ) { + return sibling( elem, "previousSibling" ); + }, + nextAll: function( elem ) { + return dir( elem, "nextSibling" ); + }, + prevAll: function( elem ) { + return dir( elem, "previousSibling" ); + }, + nextUntil: function( elem, _i, until ) { + return dir( elem, "nextSibling", until ); + }, + prevUntil: function( elem, _i, until ) { + return dir( elem, "previousSibling", until ); + }, + siblings: function( elem ) { + return siblings( ( elem.parentNode || {} ).firstChild, elem ); + }, + children: function( elem ) { + return siblings( elem.firstChild ); + }, + contents: function( elem ) { + if ( elem.contentDocument != null && + + // Support: IE 11+ + // elements with no `data` attribute has an object + // `contentDocument` with a `null` prototype. + getProto( elem.contentDocument ) ) { + + return elem.contentDocument; + } + + // Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only + // Treat the template element as a regular one in browsers that + // don't support it. + if ( nodeName( elem, "template" ) ) { + elem = elem.content || elem; + } + + return jQuery.merge( [], elem.childNodes ); + } }, function( name, fn ) { - jQuery.fn[ name ] = function( until, selector ) { - var matched = jQuery.map( this, fn, until ); + jQuery.fn[ name ] = function( until, selector ) { + var matched = jQuery.map( this, fn, until ); - if ( name.slice( -5 ) !== "Until" ) { - selector = until; - } + if ( name.slice( -5 ) !== "Until" ) { + selector = until; + } - if ( selector && typeof selector === "string" ) { - matched = jQuery.filter( selector, matched ); - } + if ( selector && typeof selector === "string" ) { + matched = jQuery.filter( selector, matched ); + } - if ( this.length > 1 ) { + if ( this.length > 1 ) { - // Remove duplicates - if ( !guaranteedUnique[ name ] ) { - jQuery.uniqueSort( matched ); - } + // Remove duplicates + if ( !guaranteedUnique[ name ] ) { + jQuery.uniqueSort( matched ); + } - // Reverse order for parents* and prev-derivatives - if ( rparentsprev.test( name ) ) { - matched.reverse(); - } - } + // Reverse order for parents* and prev-derivatives + if ( rparentsprev.test( name ) ) { + matched.reverse(); + } + } - return this.pushStack( matched ); - }; + return this.pushStack( matched ); + }; } ); -var rnotwhite = ( /\S+/g ); +var rnothtmlwhite = ( /[^\x20\t\r\n\f]+/g ); // Convert String-formatted options into Object-formatted ones function createOptions( options ) { - var object = {}; - jQuery.each( options.match( rnotwhite ) || [], function( _, flag ) { - object[ flag ] = true; - } ); - return object; + var object = {}; + jQuery.each( options.match( rnothtmlwhite ) || [], function( _, flag ) { + object[ flag ] = true; + } ); + return object; } /* * Create a callback list using the following parameters: * - * options: an optional list of space-separated options that will change how - * the callback list behaves or a more traditional option object + * options: an optional list of space-separated options that will change how + * the callback list behaves or a more traditional option object * * By default a callback list will act like an event callback list and can be * "fired" multiple times. * * Possible options: * - * once: will ensure the callback list can only be fired once (like a Deferred) + * once: will ensure the callback list can only be fired once (like a Deferred) * - * memory: will keep track of previous values and will call any callback added - * after the list has been fired right away with the latest "memorized" - * values (like a Deferred) + * memory: will keep track of previous values and will call any callback added + * after the list has been fired right away with the latest "memorized" + * values (like a Deferred) * - * unique: will ensure a callback can only be added once (no duplicate in the list) + * unique: will ensure a callback can only be added once (no duplicate in the list) * - * stopOnFalse: interrupt callings when a callback returns false + * stopOnFalse: interrupt callings when a callback returns false * */ jQuery.Callbacks = function( options ) { - // Convert options from String-formatted to Object-formatted if needed - // (we check in cache first) - options = typeof options === "string" ? - createOptions( options ) : - jQuery.extend( {}, options ); - - var // Flag to know if list is currently firing - firing, - - // Last fire value for non-forgettable lists - memory, - - // Flag to know if list was already fired - fired, - - // Flag to prevent firing - locked, - - // Actual callback list - list = [], - - // Queue of execution data for repeatable lists - queue = [], - - // Index of currently firing callback (modified by add/remove as needed) - firingIndex = -1, - - // Fire callbacks - fire = function() { - - // Enforce single-firing - locked = options.once; - - // Execute callbacks for all pending executions, - // respecting firingIndex overrides and runtime changes - fired = firing = true; - for ( ; queue.length; firingIndex = -1 ) { - memory = queue.shift(); - while ( ++firingIndex < list.length ) { - - // Run callback and check for early termination - if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false && - options.stopOnFalse ) { - - // Jump to end and forget the data so .add doesn't re-fire - firingIndex = list.length; - memory = false; - } - } - } - - // Forget the data if we're done with it - if ( !options.memory ) { - memory = false; - } - - firing = false; - - // Clean up if we're done firing for good - if ( locked ) { - - // Keep an empty list if we have data for future add calls - if ( memory ) { - list = []; - - // Otherwise, this object is spent - } else { - list = ""; - } - } - }, - - // Actual Callbacks object - self = { - - // Add a callback or a collection of callbacks to the list - add: function() { - if ( list ) { - - // If we have memory from a past run, we should fire after adding - if ( memory && !firing ) { - firingIndex = list.length - 1; - queue.push( memory ); - } - - ( function add( args ) { - jQuery.each( args, function( _, arg ) { - if ( jQuery.isFunction( arg ) ) { - if ( !options.unique || !self.has( arg ) ) { - list.push( arg ); - } - } else if ( arg && arg.length && jQuery.type( arg ) !== "string" ) { - - // Inspect recursively - add( arg ); - } - } ); - } )( arguments ); - - if ( memory && !firing ) { - fire(); - } - } - return this; - }, - - // Remove a callback from the list - remove: function() { - jQuery.each( arguments, function( _, arg ) { - var index; - while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { - list.splice( index, 1 ); - - // Handle firing indexes - if ( index <= firingIndex ) { - firingIndex--; - } - } - } ); - return this; - }, - - // Check if a given callback is in the list. - // If no argument is given, return whether or not list has callbacks attached. - has: function( fn ) { - return fn ? - jQuery.inArray( fn, list ) > -1 : - list.length > 0; - }, - - // Remove all callbacks from the list - empty: function() { - if ( list ) { - list = []; - } - return this; - }, - - // Disable .fire and .add - // Abort any current/pending executions - // Clear all callbacks and values - disable: function() { - locked = queue = []; - list = memory = ""; - return this; - }, - disabled: function() { - return !list; - }, - - // Disable .fire - // Also disable .add unless we have memory (since it would have no effect) - // Abort any pending executions - lock: function() { - locked = queue = []; - if ( !memory ) { - list = memory = ""; - } - return this; - }, - locked: function() { - return !!locked; - }, - - // Call all callbacks with the given context and arguments - fireWith: function( context, args ) { - if ( !locked ) { - args = args || []; - args = [ context, args.slice ? args.slice() : args ]; - queue.push( args ); - if ( !firing ) { - fire(); - } - } - return this; - }, - - // Call all the callbacks with the given arguments - fire: function() { - self.fireWith( this, arguments ); - return this; - }, - - // To know if the callbacks have already been called at least once - fired: function() { - return !!fired; - } - }; - - return self; + // Convert options from String-formatted to Object-formatted if needed + // (we check in cache first) + options = typeof options === "string" ? + createOptions( options ) : + jQuery.extend( {}, options ); + + var // Flag to know if list is currently firing + firing, + + // Last fire value for non-forgettable lists + memory, + + // Flag to know if list was already fired + fired, + + // Flag to prevent firing + locked, + + // Actual callback list + list = [], + + // Queue of execution data for repeatable lists + queue = [], + + // Index of currently firing callback (modified by add/remove as needed) + firingIndex = -1, + + // Fire callbacks + fire = function() { + + // Enforce single-firing + locked = locked || options.once; + + // Execute callbacks for all pending executions, + // respecting firingIndex overrides and runtime changes + fired = firing = true; + for ( ; queue.length; firingIndex = -1 ) { + memory = queue.shift(); + while ( ++firingIndex < list.length ) { + + // Run callback and check for early termination + if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false && + options.stopOnFalse ) { + + // Jump to end and forget the data so .add doesn't re-fire + firingIndex = list.length; + memory = false; + } + } + } + + // Forget the data if we're done with it + if ( !options.memory ) { + memory = false; + } + + firing = false; + + // Clean up if we're done firing for good + if ( locked ) { + + // Keep an empty list if we have data for future add calls + if ( memory ) { + list = []; + + // Otherwise, this object is spent + } else { + list = ""; + } + } + }, + + // Actual Callbacks object + self = { + + // Add a callback or a collection of callbacks to the list + add: function() { + if ( list ) { + + // If we have memory from a past run, we should fire after adding + if ( memory && !firing ) { + firingIndex = list.length - 1; + queue.push( memory ); + } + + ( function add( args ) { + jQuery.each( args, function( _, arg ) { + if ( isFunction( arg ) ) { + if ( !options.unique || !self.has( arg ) ) { + list.push( arg ); + } + } else if ( arg && arg.length && toType( arg ) !== "string" ) { + + // Inspect recursively + add( arg ); + } + } ); + } )( arguments ); + + if ( memory && !firing ) { + fire(); + } + } + return this; + }, + + // Remove a callback from the list + remove: function() { + jQuery.each( arguments, function( _, arg ) { + var index; + while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { + list.splice( index, 1 ); + + // Handle firing indexes + if ( index <= firingIndex ) { + firingIndex--; + } + } + } ); + return this; + }, + + // Check if a given callback is in the list. + // If no argument is given, return whether or not list has callbacks attached. + has: function( fn ) { + return fn ? + jQuery.inArray( fn, list ) > -1 : + list.length > 0; + }, + + // Remove all callbacks from the list + empty: function() { + if ( list ) { + list = []; + } + return this; + }, + + // Disable .fire and .add + // Abort any current/pending executions + // Clear all callbacks and values + disable: function() { + locked = queue = []; + list = memory = ""; + return this; + }, + disabled: function() { + return !list; + }, + + // Disable .fire + // Also disable .add unless we have memory (since it would have no effect) + // Abort any pending executions + lock: function() { + locked = queue = []; + if ( !memory && !firing ) { + list = memory = ""; + } + return this; + }, + locked: function() { + return !!locked; + }, + + // Call all callbacks with the given context and arguments + fireWith: function( context, args ) { + if ( !locked ) { + args = args || []; + args = [ context, args.slice ? args.slice() : args ]; + queue.push( args ); + if ( !firing ) { + fire(); + } + } + return this; + }, + + // Call all the callbacks with the given arguments + fire: function() { + self.fireWith( this, arguments ); + return this; + }, + + // To know if the callbacks have already been called at least once + fired: function() { + return !!fired; + } + }; + + return self; }; +function Identity( v ) { + return v; +} +function Thrower( ex ) { + throw ex; +} + +function adoptValue( value, resolve, reject, noValue ) { + var method; + + try { + + // Check for promise aspect first to privilege synchronous behavior + if ( value && isFunction( ( method = value.promise ) ) ) { + method.call( value ).done( resolve ).fail( reject ); + + // Other thenables + } else if ( value && isFunction( ( method = value.then ) ) ) { + method.call( value, resolve, reject ); + + // Other non-thenables + } else { + + // Control `resolve` arguments by letting Array#slice cast boolean `noValue` to integer: + // * false: [ value ].slice( 0 ) => resolve( value ) + // * true: [ value ].slice( 1 ) => resolve() + resolve.apply( undefined, [ value ].slice( noValue ) ); + } + + // For Promises/A+, convert exceptions into rejections + // Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in + // Deferred#then to conditionally suppress rejection. + } catch ( value ) { + + // Support: Android 4.0 only + // Strict mode functions invoked without .call/.apply get global-object context + reject.apply( undefined, [ value ] ); + } +} + jQuery.extend( { - Deferred: function( func ) { - var tuples = [ - - // action, add listener, listener list, final state - [ "resolve", "done", jQuery.Callbacks( "once memory" ), "resolved" ], - [ "reject", "fail", jQuery.Callbacks( "once memory" ), "rejected" ], - [ "notify", "progress", jQuery.Callbacks( "memory" ) ] - ], - state = "pending", - promise = { - state: function() { - return state; - }, - always: function() { - deferred.done( arguments ).fail( arguments ); - return this; - }, - then: function( /* fnDone, fnFail, fnProgress */ ) { - var fns = arguments; - return jQuery.Deferred( function( newDefer ) { - jQuery.each( tuples, function( i, tuple ) { - var fn = jQuery.isFunction( fns[ i ] ) && fns[ i ]; - - // deferred[ done | fail | progress ] for forwarding actions to newDefer - deferred[ tuple[ 1 ] ]( function() { - var returned = fn && fn.apply( this, arguments ); - if ( returned && jQuery.isFunction( returned.promise ) ) { - returned.promise() - .progress( newDefer.notify ) - .done( newDefer.resolve ) - .fail( newDefer.reject ); - } else { - newDefer[ tuple[ 0 ] + "With" ]( - this === promise ? newDefer.promise() : this, - fn ? [ returned ] : arguments - ); - } - } ); - } ); - fns = null; - } ).promise(); - }, - - // Get a promise for this deferred - // If obj is provided, the promise aspect is added to the object - promise: function( obj ) { - return obj != null ? jQuery.extend( obj, promise ) : promise; - } - }, - deferred = {}; - - // Keep pipe for back-compat - promise.pipe = promise.then; - - // Add list-specific methods - jQuery.each( tuples, function( i, tuple ) { - var list = tuple[ 2 ], - stateString = tuple[ 3 ]; - - // promise[ done | fail | progress ] = list.add - promise[ tuple[ 1 ] ] = list.add; - - // Handle state - if ( stateString ) { - list.add( function() { - - // state = [ resolved | rejected ] - state = stateString; - - // [ reject_list | resolve_list ].disable; progress_list.lock - }, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock ); - } - - // deferred[ resolve | reject | notify ] - deferred[ tuple[ 0 ] ] = function() { - deferred[ tuple[ 0 ] + "With" ]( this === deferred ? promise : this, arguments ); - return this; - }; - deferred[ tuple[ 0 ] + "With" ] = list.fireWith; - } ); - - // Make the deferred a promise - promise.promise( deferred ); - - // Call given func if any - if ( func ) { - func.call( deferred, deferred ); - } - - // All done! - return deferred; - }, - - // Deferred helper - when: function( subordinate /* , ..., subordinateN */ ) { - var i = 0, - resolveValues = slice.call( arguments ), - length = resolveValues.length, - - // the count of uncompleted subordinates - remaining = length !== 1 || - ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0, - - // the master Deferred. - // If resolveValues consist of only a single Deferred, just use that. - deferred = remaining === 1 ? subordinate : jQuery.Deferred(), - - // Update function for both resolve and progress values - updateFunc = function( i, contexts, values ) { - return function( value ) { - contexts[ i ] = this; - values[ i ] = arguments.length > 1 ? slice.call( arguments ) : value; - if ( values === progressValues ) { - deferred.notifyWith( contexts, values ); - } else if ( !( --remaining ) ) { - deferred.resolveWith( contexts, values ); - } - }; - }, - - progressValues, progressContexts, resolveContexts; - - // Add listeners to Deferred subordinates; treat others as resolved - if ( length > 1 ) { - progressValues = new Array( length ); - progressContexts = new Array( length ); - resolveContexts = new Array( length ); - for ( ; i < length; i++ ) { - if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) { - resolveValues[ i ].promise() - .progress( updateFunc( i, progressContexts, progressValues ) ) - .done( updateFunc( i, resolveContexts, resolveValues ) ) - .fail( deferred.reject ); - } else { - --remaining; - } - } - } - - // If we're not waiting on anything, resolve the master - if ( !remaining ) { - deferred.resolveWith( resolveContexts, resolveValues ); - } - - return deferred.promise(); - } + Deferred: function( func ) { + var tuples = [ + + // action, add listener, callbacks, + // ... .then handlers, argument index, [final state] + [ "notify", "progress", jQuery.Callbacks( "memory" ), + jQuery.Callbacks( "memory" ), 2 ], + [ "resolve", "done", jQuery.Callbacks( "once memory" ), + jQuery.Callbacks( "once memory" ), 0, "resolved" ], + [ "reject", "fail", jQuery.Callbacks( "once memory" ), + jQuery.Callbacks( "once memory" ), 1, "rejected" ] + ], + state = "pending", + promise = { + state: function() { + return state; + }, + always: function() { + deferred.done( arguments ).fail( arguments ); + return this; + }, + "catch": function( fn ) { + return promise.then( null, fn ); + }, + + // Keep pipe for back-compat + pipe: function( /* fnDone, fnFail, fnProgress */ ) { + var fns = arguments; + + return jQuery.Deferred( function( newDefer ) { + jQuery.each( tuples, function( _i, tuple ) { + + // Map tuples (progress, done, fail) to arguments (done, fail, progress) + var fn = isFunction( fns[ tuple[ 4 ] ] ) && fns[ tuple[ 4 ] ]; + + // deferred.progress(function() { bind to newDefer or newDefer.notify }) + // deferred.done(function() { bind to newDefer or newDefer.resolve }) + // deferred.fail(function() { bind to newDefer or newDefer.reject }) + deferred[ tuple[ 1 ] ]( function() { + var returned = fn && fn.apply( this, arguments ); + if ( returned && isFunction( returned.promise ) ) { + returned.promise() + .progress( newDefer.notify ) + .done( newDefer.resolve ) + .fail( newDefer.reject ); + } else { + newDefer[ tuple[ 0 ] + "With" ]( + this, + fn ? [ returned ] : arguments + ); + } + } ); + } ); + fns = null; + } ).promise(); + }, + then: function( onFulfilled, onRejected, onProgress ) { + var maxDepth = 0; + function resolve( depth, deferred, handler, special ) { + return function() { + var that = this, + args = arguments, + mightThrow = function() { + var returned, then; + + // Support: Promises/A+ section 2.3.3.3.3 + // https://promisesaplus.com/#point-59 + // Ignore double-resolution attempts + if ( depth < maxDepth ) { + return; + } + + returned = handler.apply( that, args ); + + // Support: Promises/A+ section 2.3.1 + // https://promisesaplus.com/#point-48 + if ( returned === deferred.promise() ) { + throw new TypeError( "Thenable self-resolution" ); + } + + // Support: Promises/A+ sections 2.3.3.1, 3.5 + // https://promisesaplus.com/#point-54 + // https://promisesaplus.com/#point-75 + // Retrieve `then` only once + then = returned && + + // Support: Promises/A+ section 2.3.4 + // https://promisesaplus.com/#point-64 + // Only check objects and functions for thenability + ( typeof returned === "object" || + typeof returned === "function" ) && + returned.then; + + // Handle a returned thenable + if ( isFunction( then ) ) { + + // Special processors (notify) just wait for resolution + if ( special ) { + then.call( + returned, + resolve( maxDepth, deferred, Identity, special ), + resolve( maxDepth, deferred, Thrower, special ) + ); + + // Normal processors (resolve) also hook into progress + } else { + + // ...and disregard older resolution values + maxDepth++; + + then.call( + returned, + resolve( maxDepth, deferred, Identity, special ), + resolve( maxDepth, deferred, Thrower, special ), + resolve( maxDepth, deferred, Identity, + deferred.notifyWith ) + ); + } + + // Handle all other returned values + } else { + + // Only substitute handlers pass on context + // and multiple values (non-spec behavior) + if ( handler !== Identity ) { + that = undefined; + args = [ returned ]; + } + + // Process the value(s) + // Default process is resolve + ( special || deferred.resolveWith )( that, args ); + } + }, + + // Only normal processors (resolve) catch and reject exceptions + process = special ? + mightThrow : + function() { + try { + mightThrow(); + } catch ( e ) { + + if ( jQuery.Deferred.exceptionHook ) { + jQuery.Deferred.exceptionHook( e, + process.stackTrace ); + } + + // Support: Promises/A+ section 2.3.3.3.4.1 + // https://promisesaplus.com/#point-61 + // Ignore post-resolution exceptions + if ( depth + 1 >= maxDepth ) { + + // Only substitute handlers pass on context + // and multiple values (non-spec behavior) + if ( handler !== Thrower ) { + that = undefined; + args = [ e ]; + } + + deferred.rejectWith( that, args ); + } + } + }; + + // Support: Promises/A+ section 2.3.3.3.1 + // https://promisesaplus.com/#point-57 + // Re-resolve promises immediately to dodge false rejection from + // subsequent errors + if ( depth ) { + process(); + } else { + + // Call an optional hook to record the stack, in case of exception + // since it's otherwise lost when execution goes async + if ( jQuery.Deferred.getStackHook ) { + process.stackTrace = jQuery.Deferred.getStackHook(); + } + window.setTimeout( process ); + } + }; + } + + return jQuery.Deferred( function( newDefer ) { + + // progress_handlers.add( ... ) + tuples[ 0 ][ 3 ].add( + resolve( + 0, + newDefer, + isFunction( onProgress ) ? + onProgress : + Identity, + newDefer.notifyWith + ) + ); + + // fulfilled_handlers.add( ... ) + tuples[ 1 ][ 3 ].add( + resolve( + 0, + newDefer, + isFunction( onFulfilled ) ? + onFulfilled : + Identity + ) + ); + + // rejected_handlers.add( ... ) + tuples[ 2 ][ 3 ].add( + resolve( + 0, + newDefer, + isFunction( onRejected ) ? + onRejected : + Thrower + ) + ); + } ).promise(); + }, + + // Get a promise for this deferred + // If obj is provided, the promise aspect is added to the object + promise: function( obj ) { + return obj != null ? jQuery.extend( obj, promise ) : promise; + } + }, + deferred = {}; + + // Add list-specific methods + jQuery.each( tuples, function( i, tuple ) { + var list = tuple[ 2 ], + stateString = tuple[ 5 ]; + + // promise.progress = list.add + // promise.done = list.add + // promise.fail = list.add + promise[ tuple[ 1 ] ] = list.add; + + // Handle state + if ( stateString ) { + list.add( + function() { + + // state = "resolved" (i.e., fulfilled) + // state = "rejected" + state = stateString; + }, + + // rejected_callbacks.disable + // fulfilled_callbacks.disable + tuples[ 3 - i ][ 2 ].disable, + + // rejected_handlers.disable + // fulfilled_handlers.disable + tuples[ 3 - i ][ 3 ].disable, + + // progress_callbacks.lock + tuples[ 0 ][ 2 ].lock, + + // progress_handlers.lock + tuples[ 0 ][ 3 ].lock + ); + } + + // progress_handlers.fire + // fulfilled_handlers.fire + // rejected_handlers.fire + list.add( tuple[ 3 ].fire ); + + // deferred.notify = function() { deferred.notifyWith(...) } + // deferred.resolve = function() { deferred.resolveWith(...) } + // deferred.reject = function() { deferred.rejectWith(...) } + deferred[ tuple[ 0 ] ] = function() { + deferred[ tuple[ 0 ] + "With" ]( this === deferred ? undefined : this, arguments ); + return this; + }; + + // deferred.notifyWith = list.fireWith + // deferred.resolveWith = list.fireWith + // deferred.rejectWith = list.fireWith + deferred[ tuple[ 0 ] + "With" ] = list.fireWith; + } ); + + // Make the deferred a promise + promise.promise( deferred ); + + // Call given func if any + if ( func ) { + func.call( deferred, deferred ); + } + + // All done! + return deferred; + }, + + // Deferred helper + when: function( singleValue ) { + var + + // count of uncompleted subordinates + remaining = arguments.length, + + // count of unprocessed arguments + i = remaining, + + // subordinate fulfillment data + resolveContexts = Array( i ), + resolveValues = slice.call( arguments ), + + // the master Deferred + master = jQuery.Deferred(), + + // subordinate callback factory + updateFunc = function( i ) { + return function( value ) { + resolveContexts[ i ] = this; + resolveValues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value; + if ( !( --remaining ) ) { + master.resolveWith( resolveContexts, resolveValues ); + } + }; + }; + + // Single- and empty arguments are adopted like Promise.resolve + if ( remaining <= 1 ) { + adoptValue( singleValue, master.done( updateFunc( i ) ).resolve, master.reject, + !remaining ); + + // Use .then() to unwrap secondary thenables (cf. gh-3000) + if ( master.state() === "pending" || + isFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) { + + return master.then(); + } + } + + // Multiple arguments are aggregated like Promise.all array elements + while ( i-- ) { + adoptValue( resolveValues[ i ], updateFunc( i ), master.reject ); + } + + return master.promise(); + } } ); +// These usually indicate a programmer mistake during development, +// warn about them ASAP rather than swallowing them by default. +var rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/; + +jQuery.Deferred.exceptionHook = function( error, stack ) { + + // Support: IE 8 - 9 only + // Console exists when dev tools are open, which can happen at any time + if ( window.console && window.console.warn && error && rerrorNames.test( error.name ) ) { + window.console.warn( "jQuery.Deferred exception: " + error.message, error.stack, stack ); + } +}; + + + + +jQuery.readyException = function( error ) { + window.setTimeout( function() { + throw error; + } ); +}; + + + + // The deferred used on DOM ready -var readyList; +var readyList = jQuery.Deferred(); jQuery.fn.ready = function( fn ) { - // Add the callback - jQuery.ready.promise().done( fn ); + readyList + .then( fn ) + + // Wrap jQuery.readyException in a function so that the lookup + // happens at the time of error handling instead of callback + // registration. + .catch( function( error ) { + jQuery.readyException( error ); + } ); - return this; + return this; }; jQuery.extend( { - // Is the DOM ready to be used? Set to true once it occurs. - isReady: false, - - // A counter to track how many items to wait for before - // the ready event fires. See #6781 - readyWait: 1, - - // Hold (or release) the ready event - holdReady: function( hold ) { - if ( hold ) { - jQuery.readyWait++; - } else { - jQuery.ready( true ); - } - }, - - // Handle when the DOM is ready - ready: function( wait ) { - - // Abort if there are pending holds or we're already ready - if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { - return; - } - - // Remember that the DOM is ready - jQuery.isReady = true; - - // If a normal DOM Ready event fired, decrement, and wait if need be - if ( wait !== true && --jQuery.readyWait > 0 ) { - return; - } - - // If there are functions bound, to execute - readyList.resolveWith( document, [ jQuery ] ); - - // Trigger any bound ready events - if ( jQuery.fn.triggerHandler ) { - jQuery( document ).triggerHandler( "ready" ); - jQuery( document ).off( "ready" ); - } - } -} ); + // Is the DOM ready to be used? Set to true once it occurs. + isReady: false, -/** - * The ready event handler and self cleanup method - */ -function completed() { - document.removeEventListener( "DOMContentLoaded", completed ); - window.removeEventListener( "load", completed ); - jQuery.ready(); -} + // A counter to track how many items to wait for before + // the ready event fires. See #6781 + readyWait: 1, -jQuery.ready.promise = function( obj ) { - if ( !readyList ) { + // Handle when the DOM is ready + ready: function( wait ) { - readyList = jQuery.Deferred(); + // Abort if there are pending holds or we're already ready + if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { + return; + } - // Catch cases where $(document).ready() is called - // after the browser event has already occurred. - // Support: IE9-10 only - // Older IE sometimes signals "interactive" too soon - if ( document.readyState === "complete" || - ( document.readyState !== "loading" && !document.documentElement.doScroll ) ) { + // Remember that the DOM is ready + jQuery.isReady = true; - // Handle it asynchronously to allow scripts the opportunity to delay ready - window.setTimeout( jQuery.ready ); + // If a normal DOM Ready event fired, decrement, and wait if need be + if ( wait !== true && --jQuery.readyWait > 0 ) { + return; + } - } else { + // If there are functions bound, to execute + readyList.resolveWith( document, [ jQuery ] ); + } +} ); - // Use the handy event callback - document.addEventListener( "DOMContentLoaded", completed ); +jQuery.ready.then = readyList.then; - // A fallback to window.onload, that will always work - window.addEventListener( "load", completed ); - } - } - return readyList.promise( obj ); -}; +// The ready event handler and self cleanup method +function completed() { + document.removeEventListener( "DOMContentLoaded", completed ); + window.removeEventListener( "load", completed ); + jQuery.ready(); +} + +// Catch cases where $(document).ready() is called +// after the browser event has already occurred. +// Support: IE <=9 - 10 only +// Older IE sometimes signals "interactive" too soon +if ( document.readyState === "complete" || + ( document.readyState !== "loading" && !document.documentElement.doScroll ) ) { + + // Handle it asynchronously to allow scripts the opportunity to delay ready + window.setTimeout( jQuery.ready ); -// Kick off the DOM ready check even if the user does not -jQuery.ready.promise(); +} else { + + // Use the handy event callback + document.addEventListener( "DOMContentLoaded", completed ); + + // A fallback to window.onload, that will always work + window.addEventListener( "load", completed ); +} @@ -3583,265 +4141,243 @@ jQuery.ready.promise(); // Multifunctional method to get and set values of a collection // The value/s can optionally be executed if it's a function var access = function( elems, fn, key, value, chainable, emptyGet, raw ) { - var i = 0, - len = elems.length, - bulk = key == null; - - // Sets many values - if ( jQuery.type( key ) === "object" ) { - chainable = true; - for ( i in key ) { - access( elems, fn, i, key[ i ], true, emptyGet, raw ); - } - - // Sets one value - } else if ( value !== undefined ) { - chainable = true; - - if ( !jQuery.isFunction( value ) ) { - raw = true; - } - - if ( bulk ) { - - // Bulk operations run against the entire set - if ( raw ) { - fn.call( elems, value ); - fn = null; - - // ...except when executing function values - } else { - bulk = fn; - fn = function( elem, key, value ) { - return bulk.call( jQuery( elem ), value ); - }; - } - } - - if ( fn ) { - for ( ; i < len; i++ ) { - fn( - elems[ i ], key, raw ? - value : - value.call( elems[ i ], i, fn( elems[ i ], key ) ) - ); - } - } - } - - return chainable ? - elems : - - // Gets - bulk ? - fn.call( elems ) : - len ? fn( elems[ 0 ], key ) : emptyGet; + var i = 0, + len = elems.length, + bulk = key == null; + + // Sets many values + if ( toType( key ) === "object" ) { + chainable = true; + for ( i in key ) { + access( elems, fn, i, key[ i ], true, emptyGet, raw ); + } + + // Sets one value + } else if ( value !== undefined ) { + chainable = true; + + if ( !isFunction( value ) ) { + raw = true; + } + + if ( bulk ) { + + // Bulk operations run against the entire set + if ( raw ) { + fn.call( elems, value ); + fn = null; + + // ...except when executing function values + } else { + bulk = fn; + fn = function( elem, _key, value ) { + return bulk.call( jQuery( elem ), value ); + }; + } + } + + if ( fn ) { + for ( ; i < len; i++ ) { + fn( + elems[ i ], key, raw ? + value : + value.call( elems[ i ], i, fn( elems[ i ], key ) ) + ); + } + } + } + + if ( chainable ) { + return elems; + } + + // Gets + if ( bulk ) { + return fn.call( elems ); + } + + return len ? fn( elems[ 0 ], key ) : emptyGet; }; + + +// Matches dashed string for camelizing +var rmsPrefix = /^-ms-/, + rdashAlpha = /-([a-z])/g; + +// Used by camelCase as callback to replace() +function fcamelCase( _all, letter ) { + return letter.toUpperCase(); +} + +// Convert dashed to camelCase; used by the css and data modules +// Support: IE <=9 - 11, Edge 12 - 15 +// Microsoft forgot to hump their vendor prefix (#9572) +function camelCase( string ) { + return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); +} var acceptData = function( owner ) { - // Accepts only: - // - Node - // - Node.ELEMENT_NODE - // - Node.DOCUMENT_NODE - // - Object - // - Any - /* jshint -W018 */ - return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType ); + // Accepts only: + // - Node + // - Node.ELEMENT_NODE + // - Node.DOCUMENT_NODE + // - Object + // - Any + return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType ); }; function Data() { - this.expando = jQuery.expando + Data.uid++; + this.expando = jQuery.expando + Data.uid++; } Data.uid = 1; Data.prototype = { - register: function( owner, initial ) { - var value = initial || {}; - - // If it is a node unlikely to be stringify-ed or looped over - // use plain assignment - if ( owner.nodeType ) { - owner[ this.expando ] = value; - - // Otherwise secure it in a non-enumerable, non-writable property - // configurability must be true to allow the property to be - // deleted with the delete operator - } else { - Object.defineProperty( owner, this.expando, { - value: value, - writable: true, - configurable: true - } ); - } - return owner[ this.expando ]; - }, - cache: function( owner ) { - - // We can accept data for non-element nodes in modern browsers, - // but we should not, see #8335. - // Always return an empty object. - if ( !acceptData( owner ) ) { - return {}; - } - - // Check if the owner object already has a cache - var value = owner[ this.expando ]; - - // If not, create one - if ( !value ) { - value = {}; - - // We can accept data for non-element nodes in modern browsers, - // but we should not, see #8335. - // Always return an empty object. - if ( acceptData( owner ) ) { - - // If it is a node unlikely to be stringify-ed or looped over - // use plain assignment - if ( owner.nodeType ) { - owner[ this.expando ] = value; - - // Otherwise secure it in a non-enumerable property - // configurable must be true to allow the property to be - // deleted when data is removed - } else { - Object.defineProperty( owner, this.expando, { - value: value, - configurable: true - } ); - } - } - } - - return value; - }, - set: function( owner, data, value ) { - var prop, - cache = this.cache( owner ); - - // Handle: [ owner, key, value ] args - if ( typeof data === "string" ) { - cache[ data ] = value; - - // Handle: [ owner, { properties } ] args - } else { - - // Copy the properties one-by-one to the cache object - for ( prop in data ) { - cache[ prop ] = data[ prop ]; - } - } - return cache; - }, - get: function( owner, key ) { - return key === undefined ? - this.cache( owner ) : - owner[ this.expando ] && owner[ this.expando ][ key ]; - }, - access: function( owner, key, value ) { - var stored; - - // In cases where either: - // - // 1. No key was specified - // 2. A string key was specified, but no value provided - // - // Take the "read" path and allow the get method to determine - // which value to return, respectively either: - // - // 1. The entire cache object - // 2. The data stored at the key - // - if ( key === undefined || - ( ( key && typeof key === "string" ) && value === undefined ) ) { - - stored = this.get( owner, key ); - - return stored !== undefined ? - stored : this.get( owner, jQuery.camelCase( key ) ); - } - - // When the key is not a string, or both a key and value - // are specified, set or extend (existing objects) with either: - // - // 1. An object of properties - // 2. A key and value - // - this.set( owner, key, value ); - - // Since the "set" path can have two possible entry points - // return the expected data based on which path was taken[*] - return value !== undefined ? value : key; - }, - remove: function( owner, key ) { - var i, name, camel, - cache = owner[ this.expando ]; - - if ( cache === undefined ) { - return; - } - - if ( key === undefined ) { - this.register( owner ); - - } else { - - // Support array or space separated string of keys - if ( jQuery.isArray( key ) ) { - - // If "name" is an array of keys... - // When data is initially created, via ("key", "val") signature, - // keys will be converted to camelCase. - // Since there is no way to tell _how_ a key was added, remove - // both plain key and camelCase key. #12786 - // This will only penalize the array argument path. - name = key.concat( key.map( jQuery.camelCase ) ); - } else { - camel = jQuery.camelCase( key ); - - // Try the string as a key before any manipulation - if ( key in cache ) { - name = [ key, camel ]; - } else { - - // If a key with the spaces exists, use it. - // Otherwise, create an array by matching non-whitespace - name = camel; - name = name in cache ? - [ name ] : ( name.match( rnotwhite ) || [] ); - } - } - - i = name.length; - - while ( i-- ) { - delete cache[ name[ i ] ]; - } - } - - // Remove the expando if there's no more data - if ( key === undefined || jQuery.isEmptyObject( cache ) ) { - - // Support: Chrome <= 35-45+ - // Webkit & Blink performance suffers when deleting properties - // from DOM nodes, so set to undefined instead - // https://code.google.com/p/chromium/issues/detail?id=378607 - if ( owner.nodeType ) { - owner[ this.expando ] = undefined; - } else { - delete owner[ this.expando ]; - } - } - }, - hasData: function( owner ) { - var cache = owner[ this.expando ]; - return cache !== undefined && !jQuery.isEmptyObject( cache ); - } + cache: function( owner ) { + + // Check if the owner object already has a cache + var value = owner[ this.expando ]; + + // If not, create one + if ( !value ) { + value = {}; + + // We can accept data for non-element nodes in modern browsers, + // but we should not, see #8335. + // Always return an empty object. + if ( acceptData( owner ) ) { + + // If it is a node unlikely to be stringify-ed or looped over + // use plain assignment + if ( owner.nodeType ) { + owner[ this.expando ] = value; + + // Otherwise secure it in a non-enumerable property + // configurable must be true to allow the property to be + // deleted when data is removed + } else { + Object.defineProperty( owner, this.expando, { + value: value, + configurable: true + } ); + } + } + } + + return value; + }, + set: function( owner, data, value ) { + var prop, + cache = this.cache( owner ); + + // Handle: [ owner, key, value ] args + // Always use camelCase key (gh-2257) + if ( typeof data === "string" ) { + cache[ camelCase( data ) ] = value; + + // Handle: [ owner, { properties } ] args + } else { + + // Copy the properties one-by-one to the cache object + for ( prop in data ) { + cache[ camelCase( prop ) ] = data[ prop ]; + } + } + return cache; + }, + get: function( owner, key ) { + return key === undefined ? + this.cache( owner ) : + + // Always use camelCase key (gh-2257) + owner[ this.expando ] && owner[ this.expando ][ camelCase( key ) ]; + }, + access: function( owner, key, value ) { + + // In cases where either: + // + // 1. No key was specified + // 2. A string key was specified, but no value provided + // + // Take the "read" path and allow the get method to determine + // which value to return, respectively either: + // + // 1. The entire cache object + // 2. The data stored at the key + // + if ( key === undefined || + ( ( key && typeof key === "string" ) && value === undefined ) ) { + + return this.get( owner, key ); + } + + // When the key is not a string, or both a key and value + // are specified, set or extend (existing objects) with either: + // + // 1. An object of properties + // 2. A key and value + // + this.set( owner, key, value ); + + // Since the "set" path can have two possible entry points + // return the expected data based on which path was taken[*] + return value !== undefined ? value : key; + }, + remove: function( owner, key ) { + var i, + cache = owner[ this.expando ]; + + if ( cache === undefined ) { + return; + } + + if ( key !== undefined ) { + + // Support array or space separated string of keys + if ( Array.isArray( key ) ) { + + // If key is an array of keys... + // We always set camelCase keys, so remove that. + key = key.map( camelCase ); + } else { + key = camelCase( key ); + + // If a key with the spaces exists, use it. + // Otherwise, create an array by matching non-whitespace + key = key in cache ? + [ key ] : + ( key.match( rnothtmlwhite ) || [] ); + } + + i = key.length; + + while ( i-- ) { + delete cache[ key[ i ] ]; + } + } + + // Remove the expando if there's no more data + if ( key === undefined || jQuery.isEmptyObject( cache ) ) { + + // Support: Chrome <=35 - 45 + // Webkit & Blink performance suffers when deleting properties + // from DOM nodes, so set to undefined instead + // https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted) + if ( owner.nodeType ) { + owner[ this.expando ] = undefined; + } else { + delete owner[ this.expando ]; + } + } + }, + hasData: function( owner ) { + var cache = owner[ this.expando ]; + return cache !== undefined && !jQuery.isEmptyObject( cache ); + } }; var dataPriv = new Data(); @@ -3849,317 +4385,307 @@ var dataUser = new Data(); -// Implementation Summary +// Implementation Summary // -// 1. Enforce API surface and semantic compatibility with 1.9.x branch -// 2. Improve the module's maintainability by reducing the storage -// paths to a single mechanism. -// 3. Use the same single mechanism to support "private" and "user" data. -// 4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData) -// 5. Avoid exposing implementation details on user objects (eg. expando properties) -// 6. Provide a clear path for implementation upgrade to WeakMap in 2014 +// 1. Enforce API surface and semantic compatibility with 1.9.x branch +// 2. Improve the module's maintainability by reducing the storage +// paths to a single mechanism. +// 3. Use the same single mechanism to support "private" and "user" data. +// 4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData) +// 5. Avoid exposing implementation details on user objects (eg. expando properties) +// 6. Provide a clear path for implementation upgrade to WeakMap in 2014 var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/, - rmultiDash = /[A-Z]/g; + rmultiDash = /[A-Z]/g; + +function getData( data ) { + if ( data === "true" ) { + return true; + } + + if ( data === "false" ) { + return false; + } + + if ( data === "null" ) { + return null; + } + + // Only convert to a number if it doesn't change the string + if ( data === +data + "" ) { + return +data; + } + + if ( rbrace.test( data ) ) { + return JSON.parse( data ); + } + + return data; +} function dataAttr( elem, key, data ) { - var name; - - // If nothing was found internally, try to fetch any - // data from the HTML5 data-* attribute - if ( data === undefined && elem.nodeType === 1 ) { - name = "data-" + key.replace( rmultiDash, "-$&" ).toLowerCase(); - data = elem.getAttribute( name ); - - if ( typeof data === "string" ) { - try { - data = data === "true" ? true : - data === "false" ? false : - data === "null" ? null : - - // Only convert to a number if it doesn't change the string - +data + "" === data ? +data : - rbrace.test( data ) ? jQuery.parseJSON( data ) : - data; - } catch ( e ) {} - - // Make sure we set the data so it isn't changed later - dataUser.set( elem, key, data ); - } else { - data = undefined; - } - } - return data; + var name; + + // If nothing was found internally, try to fetch any + // data from the HTML5 data-* attribute + if ( data === undefined && elem.nodeType === 1 ) { + name = "data-" + key.replace( rmultiDash, "-$&" ).toLowerCase(); + data = elem.getAttribute( name ); + + if ( typeof data === "string" ) { + try { + data = getData( data ); + } catch ( e ) {} + + // Make sure we set the data so it isn't changed later + dataUser.set( elem, key, data ); + } else { + data = undefined; + } + } + return data; } jQuery.extend( { - hasData: function( elem ) { - return dataUser.hasData( elem ) || dataPriv.hasData( elem ); - }, - - data: function( elem, name, data ) { - return dataUser.access( elem, name, data ); - }, - - removeData: function( elem, name ) { - dataUser.remove( elem, name ); - }, - - // TODO: Now that all calls to _data and _removeData have been replaced - // with direct calls to dataPriv methods, these can be deprecated. - _data: function( elem, name, data ) { - return dataPriv.access( elem, name, data ); - }, - - _removeData: function( elem, name ) { - dataPriv.remove( elem, name ); - } + hasData: function( elem ) { + return dataUser.hasData( elem ) || dataPriv.hasData( elem ); + }, + + data: function( elem, name, data ) { + return dataUser.access( elem, name, data ); + }, + + removeData: function( elem, name ) { + dataUser.remove( elem, name ); + }, + + // TODO: Now that all calls to _data and _removeData have been replaced + // with direct calls to dataPriv methods, these can be deprecated. + _data: function( elem, name, data ) { + return dataPriv.access( elem, name, data ); + }, + + _removeData: function( elem, name ) { + dataPriv.remove( elem, name ); + } } ); jQuery.fn.extend( { - data: function( key, value ) { - var i, name, data, - elem = this[ 0 ], - attrs = elem && elem.attributes; - - // Gets all values - if ( key === undefined ) { - if ( this.length ) { - data = dataUser.get( elem ); - - if ( elem.nodeType === 1 && !dataPriv.get( elem, "hasDataAttrs" ) ) { - i = attrs.length; - while ( i-- ) { - - // Support: IE11+ - // The attrs elements can be null (#14894) - if ( attrs[ i ] ) { - name = attrs[ i ].name; - if ( name.indexOf( "data-" ) === 0 ) { - name = jQuery.camelCase( name.slice( 5 ) ); - dataAttr( elem, name, data[ name ] ); - } - } - } - dataPriv.set( elem, "hasDataAttrs", true ); - } - } - - return data; - } - - // Sets multiple values - if ( typeof key === "object" ) { - return this.each( function() { - dataUser.set( this, key ); - } ); - } - - return access( this, function( value ) { - var data, camelKey; - - // The calling jQuery object (element matches) is not empty - // (and therefore has an element appears at this[ 0 ]) and the - // `value` parameter was not undefined. An empty jQuery object - // will result in `undefined` for elem = this[ 0 ] which will - // throw an exception if an attempt to read a data cache is made. - if ( elem && value === undefined ) { - - // Attempt to get data from the cache - // with the key as-is - data = dataUser.get( elem, key ) || - - // Try to find dashed key if it exists (gh-2779) - // This is for 2.2.x only - dataUser.get( elem, key.replace( rmultiDash, "-$&" ).toLowerCase() ); - - if ( data !== undefined ) { - return data; - } - - camelKey = jQuery.camelCase( key ); - - // Attempt to get data from the cache - // with the key camelized - data = dataUser.get( elem, camelKey ); - if ( data !== undefined ) { - return data; - } - - // Attempt to "discover" the data in - // HTML5 custom data-* attrs - data = dataAttr( elem, camelKey, undefined ); - if ( data !== undefined ) { - return data; - } - - // We tried really hard, but the data doesn't exist. - return; - } - - // Set the data... - camelKey = jQuery.camelCase( key ); - this.each( function() { - - // First, attempt to store a copy or reference of any - // data that might've been store with a camelCased key. - var data = dataUser.get( this, camelKey ); - - // For HTML5 data-* attribute interop, we have to - // store property names with dashes in a camelCase form. - // This might not apply to all properties...* - dataUser.set( this, camelKey, value ); - - // *... In the case of properties that might _actually_ - // have dashes, we need to also store a copy of that - // unchanged property. - if ( key.indexOf( "-" ) > -1 && data !== undefined ) { - dataUser.set( this, key, value ); - } - } ); - }, null, value, arguments.length > 1, null, true ); - }, - - removeData: function( key ) { - return this.each( function() { - dataUser.remove( this, key ); - } ); - } + data: function( key, value ) { + var i, name, data, + elem = this[ 0 ], + attrs = elem && elem.attributes; + + // Gets all values + if ( key === undefined ) { + if ( this.length ) { + data = dataUser.get( elem ); + + if ( elem.nodeType === 1 && !dataPriv.get( elem, "hasDataAttrs" ) ) { + i = attrs.length; + while ( i-- ) { + + // Support: IE 11 only + // The attrs elements can be null (#14894) + if ( attrs[ i ] ) { + name = attrs[ i ].name; + if ( name.indexOf( "data-" ) === 0 ) { + name = camelCase( name.slice( 5 ) ); + dataAttr( elem, name, data[ name ] ); + } + } + } + dataPriv.set( elem, "hasDataAttrs", true ); + } + } + + return data; + } + + // Sets multiple values + if ( typeof key === "object" ) { + return this.each( function() { + dataUser.set( this, key ); + } ); + } + + return access( this, function( value ) { + var data; + + // The calling jQuery object (element matches) is not empty + // (and therefore has an element appears at this[ 0 ]) and the + // `value` parameter was not undefined. An empty jQuery object + // will result in `undefined` for elem = this[ 0 ] which will + // throw an exception if an attempt to read a data cache is made. + if ( elem && value === undefined ) { + + // Attempt to get data from the cache + // The key will always be camelCased in Data + data = dataUser.get( elem, key ); + if ( data !== undefined ) { + return data; + } + + // Attempt to "discover" the data in + // HTML5 custom data-* attrs + data = dataAttr( elem, key ); + if ( data !== undefined ) { + return data; + } + + // We tried really hard, but the data doesn't exist. + return; + } + + // Set the data... + this.each( function() { + + // We always store the camelCased key + dataUser.set( this, key, value ); + } ); + }, null, value, arguments.length > 1, null, true ); + }, + + removeData: function( key ) { + return this.each( function() { + dataUser.remove( this, key ); + } ); + } } ); jQuery.extend( { - queue: function( elem, type, data ) { - var queue; - - if ( elem ) { - type = ( type || "fx" ) + "queue"; - queue = dataPriv.get( elem, type ); - - // Speed up dequeue by getting out quickly if this is just a lookup - if ( data ) { - if ( !queue || jQuery.isArray( data ) ) { - queue = dataPriv.access( elem, type, jQuery.makeArray( data ) ); - } else { - queue.push( data ); - } - } - return queue || []; - } - }, - - dequeue: function( elem, type ) { - type = type || "fx"; - - var queue = jQuery.queue( elem, type ), - startLength = queue.length, - fn = queue.shift(), - hooks = jQuery._queueHooks( elem, type ), - next = function() { - jQuery.dequeue( elem, type ); - }; - - // If the fx queue is dequeued, always remove the progress sentinel - if ( fn === "inprogress" ) { - fn = queue.shift(); - startLength--; - } - - if ( fn ) { - - // Add a progress sentinel to prevent the fx queue from being - // automatically dequeued - if ( type === "fx" ) { - queue.unshift( "inprogress" ); - } - - // Clear up the last queue stop function - delete hooks.stop; - fn.call( elem, next, hooks ); - } - - if ( !startLength && hooks ) { - hooks.empty.fire(); - } - }, - - // Not public - generate a queueHooks object, or return the current one - _queueHooks: function( elem, type ) { - var key = type + "queueHooks"; - return dataPriv.get( elem, key ) || dataPriv.access( elem, key, { - empty: jQuery.Callbacks( "once memory" ).add( function() { - dataPriv.remove( elem, [ type + "queue", key ] ); - } ) - } ); - } + queue: function( elem, type, data ) { + var queue; + + if ( elem ) { + type = ( type || "fx" ) + "queue"; + queue = dataPriv.get( elem, type ); + + // Speed up dequeue by getting out quickly if this is just a lookup + if ( data ) { + if ( !queue || Array.isArray( data ) ) { + queue = dataPriv.access( elem, type, jQuery.makeArray( data ) ); + } else { + queue.push( data ); + } + } + return queue || []; + } + }, + + dequeue: function( elem, type ) { + type = type || "fx"; + + var queue = jQuery.queue( elem, type ), + startLength = queue.length, + fn = queue.shift(), + hooks = jQuery._queueHooks( elem, type ), + next = function() { + jQuery.dequeue( elem, type ); + }; + + // If the fx queue is dequeued, always remove the progress sentinel + if ( fn === "inprogress" ) { + fn = queue.shift(); + startLength--; + } + + if ( fn ) { + + // Add a progress sentinel to prevent the fx queue from being + // automatically dequeued + if ( type === "fx" ) { + queue.unshift( "inprogress" ); + } + + // Clear up the last queue stop function + delete hooks.stop; + fn.call( elem, next, hooks ); + } + + if ( !startLength && hooks ) { + hooks.empty.fire(); + } + }, + + // Not public - generate a queueHooks object, or return the current one + _queueHooks: function( elem, type ) { + var key = type + "queueHooks"; + return dataPriv.get( elem, key ) || dataPriv.access( elem, key, { + empty: jQuery.Callbacks( "once memory" ).add( function() { + dataPriv.remove( elem, [ type + "queue", key ] ); + } ) + } ); + } } ); jQuery.fn.extend( { - queue: function( type, data ) { - var setter = 2; - - if ( typeof type !== "string" ) { - data = type; - type = "fx"; - setter--; - } - - if ( arguments.length < setter ) { - return jQuery.queue( this[ 0 ], type ); - } - - return data === undefined ? - this : - this.each( function() { - var queue = jQuery.queue( this, type, data ); - - // Ensure a hooks for this queue - jQuery._queueHooks( this, type ); - - if ( type === "fx" && queue[ 0 ] !== "inprogress" ) { - jQuery.dequeue( this, type ); - } - } ); - }, - dequeue: function( type ) { - return this.each( function() { - jQuery.dequeue( this, type ); - } ); - }, - clearQueue: function( type ) { - return this.queue( type || "fx", [] ); - }, - - // Get a promise resolved when queues of a certain type - // are emptied (fx is the type by default) - promise: function( type, obj ) { - var tmp, - count = 1, - defer = jQuery.Deferred(), - elements = this, - i = this.length, - resolve = function() { - if ( !( --count ) ) { - defer.resolveWith( elements, [ elements ] ); - } - }; - - if ( typeof type !== "string" ) { - obj = type; - type = undefined; - } - type = type || "fx"; - - while ( i-- ) { - tmp = dataPriv.get( elements[ i ], type + "queueHooks" ); - if ( tmp && tmp.empty ) { - count++; - tmp.empty.add( resolve ); - } - } - resolve(); - return defer.promise( obj ); - } + queue: function( type, data ) { + var setter = 2; + + if ( typeof type !== "string" ) { + data = type; + type = "fx"; + setter--; + } + + if ( arguments.length < setter ) { + return jQuery.queue( this[ 0 ], type ); + } + + return data === undefined ? + this : + this.each( function() { + var queue = jQuery.queue( this, type, data ); + + // Ensure a hooks for this queue + jQuery._queueHooks( this, type ); + + if ( type === "fx" && queue[ 0 ] !== "inprogress" ) { + jQuery.dequeue( this, type ); + } + } ); + }, + dequeue: function( type ) { + return this.each( function() { + jQuery.dequeue( this, type ); + } ); + }, + clearQueue: function( type ) { + return this.queue( type || "fx", [] ); + }, + + // Get a promise resolved when queues of a certain type + // are emptied (fx is the type by default) + promise: function( type, obj ) { + var tmp, + count = 1, + defer = jQuery.Deferred(), + elements = this, + i = this.length, + resolve = function() { + if ( !( --count ) ) { + defer.resolveWith( elements, [ elements ] ); + } + }; + + if ( typeof type !== "string" ) { + obj = type; + type = undefined; + } + type = type || "fx"; + + while ( i-- ) { + tmp = dataPriv.get( elements[ i ], type + "queueHooks" ); + if ( tmp && tmp.empty ) { + count++; + tmp.empty.add( resolve ); + } + } + resolve(); + return defer.promise( obj ); + } } ); var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source; @@ -4168,335 +4694,492 @@ var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" ); var cssExpand = [ "Top", "Right", "Bottom", "Left" ]; -var isHidden = function( elem, el ) { +var documentElement = document.documentElement; - // isHidden might be called from jQuery#filter function; - // in that case, element will be second argument - elem = el || elem; - return jQuery.css( elem, "display" ) === "none" || - !jQuery.contains( elem.ownerDocument, elem ); - }; + + + var isAttached = function( elem ) { + return jQuery.contains( elem.ownerDocument, elem ); + }, + composed = { composed: true }; + + // Support: IE 9 - 11+, Edge 12 - 18+, iOS 10.0 - 10.2 only + // Check attachment across shadow DOM boundaries when possible (gh-3504) + // Support: iOS 10.0-10.2 only + // Early iOS 10 versions support `attachShadow` but not `getRootNode`, + // leading to errors. We need to check for `getRootNode`. + if ( documentElement.getRootNode ) { + isAttached = function( elem ) { + return jQuery.contains( elem.ownerDocument, elem ) || + elem.getRootNode( composed ) === elem.ownerDocument; + }; + } +var isHiddenWithinTree = function( elem, el ) { + + // isHiddenWithinTree might be called from jQuery#filter function; + // in that case, element will be second argument + elem = el || elem; + + // Inline style trumps all + return elem.style.display === "none" || + elem.style.display === "" && + + // Otherwise, check computed style + // Support: Firefox <=43 - 45 + // Disconnected elements can have computed display: none, so first confirm that elem is + // in the document. + isAttached( elem ) && + + jQuery.css( elem, "display" ) === "none"; + }; function adjustCSS( elem, prop, valueParts, tween ) { - var adjusted, - scale = 1, - maxIterations = 20, - currentValue = tween ? - function() { return tween.cur(); } : - function() { return jQuery.css( elem, prop, "" ); }, - initial = currentValue(), - unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ), - - // Starting value computation is required for potential unit mismatches - initialInUnit = ( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) && - rcssNum.exec( jQuery.css( elem, prop ) ); - - if ( initialInUnit && initialInUnit[ 3 ] !== unit ) { - - // Trust units reported by jQuery.css - unit = unit || initialInUnit[ 3 ]; - - // Make sure we update the tween properties later on - valueParts = valueParts || []; - - // Iteratively approximate from a nonzero starting point - initialInUnit = +initial || 1; - - do { - - // If previous iteration zeroed out, double until we get *something*. - // Use string for doubling so we don't accidentally see scale as unchanged below - scale = scale || ".5"; - - // Adjust and apply - initialInUnit = initialInUnit / scale; - jQuery.style( elem, prop, initialInUnit + unit ); - - // Update scale, tolerating zero or NaN from tween.cur() - // Break the loop if scale is unchanged or perfect, or if we've just had enough. - } while ( - scale !== ( scale = currentValue() / initial ) && scale !== 1 && --maxIterations - ); - } - - if ( valueParts ) { - initialInUnit = +initialInUnit || +initial || 0; - - // Apply relative offset (+=/-=) if specified - adjusted = valueParts[ 1 ] ? - initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] : - +valueParts[ 2 ]; - if ( tween ) { - tween.unit = unit; - tween.start = initialInUnit; - tween.end = adjusted; - } - } - return adjusted; + var adjusted, scale, + maxIterations = 20, + currentValue = tween ? + function() { + return tween.cur(); + } : + function() { + return jQuery.css( elem, prop, "" ); + }, + initial = currentValue(), + unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ), + + // Starting value computation is required for potential unit mismatches + initialInUnit = elem.nodeType && + ( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) && + rcssNum.exec( jQuery.css( elem, prop ) ); + + if ( initialInUnit && initialInUnit[ 3 ] !== unit ) { + + // Support: Firefox <=54 + // Halve the iteration target value to prevent interference from CSS upper bounds (gh-2144) + initial = initial / 2; + + // Trust units reported by jQuery.css + unit = unit || initialInUnit[ 3 ]; + + // Iteratively approximate from a nonzero starting point + initialInUnit = +initial || 1; + + while ( maxIterations-- ) { + + // Evaluate and update our best guess (doubling guesses that zero out). + // Finish if the scale equals or crosses 1 (making the old*new product non-positive). + jQuery.style( elem, prop, initialInUnit + unit ); + if ( ( 1 - scale ) * ( 1 - ( scale = currentValue() / initial || 0.5 ) ) <= 0 ) { + maxIterations = 0; + } + initialInUnit = initialInUnit / scale; + + } + + initialInUnit = initialInUnit * 2; + jQuery.style( elem, prop, initialInUnit + unit ); + + // Make sure we update the tween properties later on + valueParts = valueParts || []; + } + + if ( valueParts ) { + initialInUnit = +initialInUnit || +initial || 0; + + // Apply relative offset (+=/-=) if specified + adjusted = valueParts[ 1 ] ? + initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] : + +valueParts[ 2 ]; + if ( tween ) { + tween.unit = unit; + tween.start = initialInUnit; + tween.end = adjusted; + } + } + return adjusted; } + + +var defaultDisplayMap = {}; + +function getDefaultDisplay( elem ) { + var temp, + doc = elem.ownerDocument, + nodeName = elem.nodeName, + display = defaultDisplayMap[ nodeName ]; + + if ( display ) { + return display; + } + + temp = doc.body.appendChild( doc.createElement( nodeName ) ); + display = jQuery.css( temp, "display" ); + + temp.parentNode.removeChild( temp ); + + if ( display === "none" ) { + display = "block"; + } + defaultDisplayMap[ nodeName ] = display; + + return display; +} + +function showHide( elements, show ) { + var display, elem, + values = [], + index = 0, + length = elements.length; + + // Determine new display value for elements that need to change + for ( ; index < length; index++ ) { + elem = elements[ index ]; + if ( !elem.style ) { + continue; + } + + display = elem.style.display; + if ( show ) { + + // Since we force visibility upon cascade-hidden elements, an immediate (and slow) + // check is required in this first loop unless we have a nonempty display value (either + // inline or about-to-be-restored) + if ( display === "none" ) { + values[ index ] = dataPriv.get( elem, "display" ) || null; + if ( !values[ index ] ) { + elem.style.display = ""; + } + } + if ( elem.style.display === "" && isHiddenWithinTree( elem ) ) { + values[ index ] = getDefaultDisplay( elem ); + } + } else { + if ( display !== "none" ) { + values[ index ] = "none"; + + // Remember what we're overwriting + dataPriv.set( elem, "display", display ); + } + } + } + + // Set the display of the elements in a second loop to avoid constant reflow + for ( index = 0; index < length; index++ ) { + if ( values[ index ] != null ) { + elements[ index ].style.display = values[ index ]; + } + } + + return elements; +} + +jQuery.fn.extend( { + show: function() { + return showHide( this, true ); + }, + hide: function() { + return showHide( this ); + }, + toggle: function( state ) { + if ( typeof state === "boolean" ) { + return state ? this.show() : this.hide(); + } + + return this.each( function() { + if ( isHiddenWithinTree( this ) ) { + jQuery( this ).show(); + } else { + jQuery( this ).hide(); + } + } ); + } +} ); var rcheckableType = ( /^(?:checkbox|radio)$/i ); -var rtagName = ( /<([\w:-]+)/ ); +var rtagName = ( /<([a-z][^\/\0>\x20\t\r\n\f]*)/i ); + +var rscriptType = ( /^$|^module$|\/(?:java|ecma)script/i ); -var rscriptType = ( /^$|\/(?:java|ecma)script/i ); +( function() { + var fragment = document.createDocumentFragment(), + div = fragment.appendChild( document.createElement( "div" ) ), + input = document.createElement( "input" ); + + // Support: Android 4.0 - 4.3 only + // Check state lost if the name is set (#11217) + // Support: Windows Web Apps (WWA) + // `name` and `type` must use .setAttribute for WWA (#14901) + input.setAttribute( "type", "radio" ); + input.setAttribute( "checked", "checked" ); + input.setAttribute( "name", "t" ); + + div.appendChild( input ); + + // Support: Android <=4.1 only + // Older WebKit doesn't clone checked state correctly in fragments + support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked; + + // Support: IE <=11 only + // Make sure textarea (and checkbox) defaultValue is properly cloned + div.innerHTML = ""; + support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue; + + // Support: IE <=9 only + // IE <=9 replaces "; + support.option = !!div.lastChild; +} )(); + // We have to close these tags to support XHTML (#13200) var wrapMap = { - // Support: IE9 - option: [ 1, "" ], + // XHTML parsers do not magically insert elements in the + // same way that tag soup parsers do. So we cannot shorten + // this by omitting
    or other required elements. + thead: [ 1, "
    Paths that are present and their values
    PathValue
    ", "
    " ], + col: [ 2, "", "
    " ], + tr: [ 2, "", "
    " ], + td: [ 3, "", "
    " ], - // XHTML parsers do not magically insert elements in the - // same way that tag soup parsers do. So we cannot shorten - // this by omitting or other required elements. - thead: [ 1, "", "
    " ], - col: [ 2, "", "
    " ], - tr: [ 2, "", "
    " ], - td: [ 3, "", "
    " ], - - _default: [ 0, "", "" ] + _default: [ 0, "", "" ] }; -// Support: IE9 -wrapMap.optgroup = wrapMap.option; - wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; wrapMap.th = wrapMap.td; +// Support: IE <=9 only +if ( !support.option ) { + wrapMap.optgroup = wrapMap.option = [ 1, "" ]; +} + function getAll( context, tag ) { - // Support: IE9-11+ - // Use typeof to avoid zero-argument method invocation on host objects (#15151) - var ret = typeof context.getElementsByTagName !== "undefined" ? - context.getElementsByTagName( tag || "*" ) : - typeof context.querySelectorAll !== "undefined" ? - context.querySelectorAll( tag || "*" ) : - []; - - return tag === undefined || tag && jQuery.nodeName( context, tag ) ? - jQuery.merge( [ context ], ret ) : - ret; + // Support: IE <=9 - 11 only + // Use typeof to avoid zero-argument method invocation on host objects (#15151) + var ret; + + if ( typeof context.getElementsByTagName !== "undefined" ) { + ret = context.getElementsByTagName( tag || "*" ); + + } else if ( typeof context.querySelectorAll !== "undefined" ) { + ret = context.querySelectorAll( tag || "*" ); + + } else { + ret = []; + } + + if ( tag === undefined || tag && nodeName( context, tag ) ) { + return jQuery.merge( [ context ], ret ); + } + + return ret; } // Mark scripts as having already been evaluated function setGlobalEval( elems, refElements ) { - var i = 0, - l = elems.length; - - for ( ; i < l; i++ ) { - dataPriv.set( - elems[ i ], - "globalEval", - !refElements || dataPriv.get( refElements[ i ], "globalEval" ) - ); - } + var i = 0, + l = elems.length; + + for ( ; i < l; i++ ) { + dataPriv.set( + elems[ i ], + "globalEval", + !refElements || dataPriv.get( refElements[ i ], "globalEval" ) + ); + } } var rhtml = /<|&#?\w+;/; function buildFragment( elems, context, scripts, selection, ignored ) { - var elem, tmp, tag, wrap, contains, j, - fragment = context.createDocumentFragment(), - nodes = [], - i = 0, - l = elems.length; - - for ( ; i < l; i++ ) { - elem = elems[ i ]; - - if ( elem || elem === 0 ) { - - // Add nodes directly - if ( jQuery.type( elem ) === "object" ) { - - // Support: Android<4.1, PhantomJS<2 - // push.apply(_, arraylike) throws on ancient WebKit - jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem ); - - // Convert non-html into a text node - } else if ( !rhtml.test( elem ) ) { - nodes.push( context.createTextNode( elem ) ); - - // Convert html into DOM nodes - } else { - tmp = tmp || fragment.appendChild( context.createElement( "div" ) ); - - // Deserialize a standard representation - tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase(); - wrap = wrapMap[ tag ] || wrapMap._default; - tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ]; - - // Descend through wrappers to the right content - j = wrap[ 0 ]; - while ( j-- ) { - tmp = tmp.lastChild; - } - - // Support: Android<4.1, PhantomJS<2 - // push.apply(_, arraylike) throws on ancient WebKit - jQuery.merge( nodes, tmp.childNodes ); - - // Remember the top-level container - tmp = fragment.firstChild; - - // Ensure the created nodes are orphaned (#12392) - tmp.textContent = ""; - } - } - } - - // Remove wrapper from fragment - fragment.textContent = ""; - - i = 0; - while ( ( elem = nodes[ i++ ] ) ) { - - // Skip elements already in the context collection (trac-4087) - if ( selection && jQuery.inArray( elem, selection ) > -1 ) { - if ( ignored ) { - ignored.push( elem ); - } - continue; - } - - contains = jQuery.contains( elem.ownerDocument, elem ); - - // Append to fragment - tmp = getAll( fragment.appendChild( elem ), "script" ); - - // Preserve script evaluation history - if ( contains ) { - setGlobalEval( tmp ); - } - - // Capture executables - if ( scripts ) { - j = 0; - while ( ( elem = tmp[ j++ ] ) ) { - if ( rscriptType.test( elem.type || "" ) ) { - scripts.push( elem ); - } - } - } - } - - return fragment; + var elem, tmp, tag, wrap, attached, j, + fragment = context.createDocumentFragment(), + nodes = [], + i = 0, + l = elems.length; + + for ( ; i < l; i++ ) { + elem = elems[ i ]; + + if ( elem || elem === 0 ) { + + // Add nodes directly + if ( toType( elem ) === "object" ) { + + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem ); + + // Convert non-html into a text node + } else if ( !rhtml.test( elem ) ) { + nodes.push( context.createTextNode( elem ) ); + + // Convert html into DOM nodes + } else { + tmp = tmp || fragment.appendChild( context.createElement( "div" ) ); + + // Deserialize a standard representation + tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase(); + wrap = wrapMap[ tag ] || wrapMap._default; + tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ]; + + // Descend through wrappers to the right content + j = wrap[ 0 ]; + while ( j-- ) { + tmp = tmp.lastChild; + } + + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + jQuery.merge( nodes, tmp.childNodes ); + + // Remember the top-level container + tmp = fragment.firstChild; + + // Ensure the created nodes are orphaned (#12392) + tmp.textContent = ""; + } + } + } + + // Remove wrapper from fragment + fragment.textContent = ""; + + i = 0; + while ( ( elem = nodes[ i++ ] ) ) { + + // Skip elements already in the context collection (trac-4087) + if ( selection && jQuery.inArray( elem, selection ) > -1 ) { + if ( ignored ) { + ignored.push( elem ); + } + continue; + } + + attached = isAttached( elem ); + + // Append to fragment + tmp = getAll( fragment.appendChild( elem ), "script" ); + + // Preserve script evaluation history + if ( attached ) { + setGlobalEval( tmp ); + } + + // Capture executables + if ( scripts ) { + j = 0; + while ( ( elem = tmp[ j++ ] ) ) { + if ( rscriptType.test( elem.type || "" ) ) { + scripts.push( elem ); + } + } + } + } + + return fragment; } -( function() { - var fragment = document.createDocumentFragment(), - div = fragment.appendChild( document.createElement( "div" ) ), - input = document.createElement( "input" ); - - // Support: Android 4.0-4.3, Safari<=5.1 - // Check state lost if the name is set (#11217) - // Support: Windows Web Apps (WWA) - // `name` and `type` must use .setAttribute for WWA (#14901) - input.setAttribute( "type", "radio" ); - input.setAttribute( "checked", "checked" ); - input.setAttribute( "name", "t" ); - - div.appendChild( input ); - - // Support: Safari<=5.1, Android<4.2 - // Older WebKit doesn't clone checked state correctly in fragments - support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked; - - // Support: IE<=11+ - // Make sure textarea (and checkbox) defaultValue is properly cloned - div.innerHTML = ""; - support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue; -} )(); - - var - rkeyEvent = /^key/, - rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/, - rtypenamespace = /^([^.]*)(?:\.(.+)|)/; + rkeyEvent = /^key/, + rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/, + rtypenamespace = /^([^.]*)(?:\.(.+)|)/; function returnTrue() { - return true; + return true; } function returnFalse() { - return false; + return false; +} + +// Support: IE <=9 - 11+ +// focus() and blur() are asynchronous, except when they are no-op. +// So expect focus to be synchronous when the element is already active, +// and blur to be synchronous when the element is not already active. +// (focus and blur are always synchronous in other supported browsers, +// this just defines when we can count on it). +function expectSync( elem, type ) { + return ( elem === safeActiveElement() ) === ( type === "focus" ); } -// Support: IE9 -// See #13393 for more info +// Support: IE <=9 only +// Accessing document.activeElement can throw unexpectedly +// https://bugs.jquery.com/ticket/13393 function safeActiveElement() { - try { - return document.activeElement; - } catch ( err ) { } + try { + return document.activeElement; + } catch ( err ) { } } function on( elem, types, selector, data, fn, one ) { - var origFn, type; - - // Types can be a map of types/handlers - if ( typeof types === "object" ) { - - // ( types-Object, selector, data ) - if ( typeof selector !== "string" ) { - - // ( types-Object, data ) - data = data || selector; - selector = undefined; - } - for ( type in types ) { - on( elem, type, selector, data, types[ type ], one ); - } - return elem; - } - - if ( data == null && fn == null ) { - - // ( types, fn ) - fn = selector; - data = selector = undefined; - } else if ( fn == null ) { - if ( typeof selector === "string" ) { - - // ( types, selector, fn ) - fn = data; - data = undefined; - } else { - - // ( types, data, fn ) - fn = data; - data = selector; - selector = undefined; - } - } - if ( fn === false ) { - fn = returnFalse; - } else if ( !fn ) { - return this; - } - - if ( one === 1 ) { - origFn = fn; - fn = function( event ) { - - // Can use an empty set, since event contains the info - jQuery().off( event ); - return origFn.apply( this, arguments ); - }; - - // Use same guid so caller can remove using origFn - fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); - } - return elem.each( function() { - jQuery.event.add( this, types, fn, data, selector ); - } ); + var origFn, type; + + // Types can be a map of types/handlers + if ( typeof types === "object" ) { + + // ( types-Object, selector, data ) + if ( typeof selector !== "string" ) { + + // ( types-Object, data ) + data = data || selector; + selector = undefined; + } + for ( type in types ) { + on( elem, type, selector, data, types[ type ], one ); + } + return elem; + } + + if ( data == null && fn == null ) { + + // ( types, fn ) + fn = selector; + data = selector = undefined; + } else if ( fn == null ) { + if ( typeof selector === "string" ) { + + // ( types, selector, fn ) + fn = data; + data = undefined; + } else { + + // ( types, data, fn ) + fn = data; + data = selector; + selector = undefined; + } + } + if ( fn === false ) { + fn = returnFalse; + } else if ( !fn ) { + return elem; + } + + if ( one === 1 ) { + origFn = fn; + fn = function( event ) { + + // Can use an empty set, since event contains the info + jQuery().off( event ); + return origFn.apply( this, arguments ); + }; + + // Use same guid so caller can remove using origFn + fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); + } + return elem.each( function() { + jQuery.event.add( this, types, fn, data, selector ); + } ); } /* @@ -4505,3020 +5188,3241 @@ function on( elem, types, selector, data, fn, one ) { */ jQuery.event = { - global: {}, - - add: function( elem, types, handler, data, selector ) { - - var handleObjIn, eventHandle, tmp, - events, t, handleObj, - special, handlers, type, namespaces, origType, - elemData = dataPriv.get( elem ); - - // Don't attach events to noData or text/comment nodes (but allow plain objects) - if ( !elemData ) { - return; - } - - // Caller can pass in an object of custom data in lieu of the handler - if ( handler.handler ) { - handleObjIn = handler; - handler = handleObjIn.handler; - selector = handleObjIn.selector; - } - - // Make sure that the handler has a unique ID, used to find/remove it later - if ( !handler.guid ) { - handler.guid = jQuery.guid++; - } - - // Init the element's event structure and main handler, if this is the first - if ( !( events = elemData.events ) ) { - events = elemData.events = {}; - } - if ( !( eventHandle = elemData.handle ) ) { - eventHandle = elemData.handle = function( e ) { - - // Discard the second event of a jQuery.event.trigger() and - // when an event is called after a page has unloaded - return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ? - jQuery.event.dispatch.apply( elem, arguments ) : undefined; - }; - } - - // Handle multiple events separated by a space - types = ( types || "" ).match( rnotwhite ) || [ "" ]; - t = types.length; - while ( t-- ) { - tmp = rtypenamespace.exec( types[ t ] ) || []; - type = origType = tmp[ 1 ]; - namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); - - // There *must* be a type, no attaching namespace-only handlers - if ( !type ) { - continue; - } - - // If event changes its type, use the special event handlers for the changed type - special = jQuery.event.special[ type ] || {}; - - // If selector defined, determine special event api type, otherwise given type - type = ( selector ? special.delegateType : special.bindType ) || type; - - // Update special based on newly reset type - special = jQuery.event.special[ type ] || {}; - - // handleObj is passed to all event handlers - handleObj = jQuery.extend( { - type: type, - origType: origType, - data: data, - handler: handler, - guid: handler.guid, - selector: selector, - needsContext: selector && jQuery.expr.match.needsContext.test( selector ), - namespace: namespaces.join( "." ) - }, handleObjIn ); - - // Init the event handler queue if we're the first - if ( !( handlers = events[ type ] ) ) { - handlers = events[ type ] = []; - handlers.delegateCount = 0; - - // Only use addEventListener if the special events handler returns false - if ( !special.setup || - special.setup.call( elem, data, namespaces, eventHandle ) === false ) { - - if ( elem.addEventListener ) { - elem.addEventListener( type, eventHandle ); - } - } - } - - if ( special.add ) { - special.add.call( elem, handleObj ); - - if ( !handleObj.handler.guid ) { - handleObj.handler.guid = handler.guid; - } - } - - // Add to the element's handler list, delegates in front - if ( selector ) { - handlers.splice( handlers.delegateCount++, 0, handleObj ); - } else { - handlers.push( handleObj ); - } - - // Keep track of which events have ever been used, for event optimization - jQuery.event.global[ type ] = true; - } - - }, - - // Detach an event or set of events from an element - remove: function( elem, types, handler, selector, mappedTypes ) { - - var j, origCount, tmp, - events, t, handleObj, - special, handlers, type, namespaces, origType, - elemData = dataPriv.hasData( elem ) && dataPriv.get( elem ); - - if ( !elemData || !( events = elemData.events ) ) { - return; - } - - // Once for each type.namespace in types; type may be omitted - types = ( types || "" ).match( rnotwhite ) || [ "" ]; - t = types.length; - while ( t-- ) { - tmp = rtypenamespace.exec( types[ t ] ) || []; - type = origType = tmp[ 1 ]; - namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); - - // Unbind all events (on this namespace, if provided) for the element - if ( !type ) { - for ( type in events ) { - jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); - } - continue; - } - - special = jQuery.event.special[ type ] || {}; - type = ( selector ? special.delegateType : special.bindType ) || type; - handlers = events[ type ] || []; - tmp = tmp[ 2 ] && - new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ); - - // Remove matching events - origCount = j = handlers.length; - while ( j-- ) { - handleObj = handlers[ j ]; - - if ( ( mappedTypes || origType === handleObj.origType ) && - ( !handler || handler.guid === handleObj.guid ) && - ( !tmp || tmp.test( handleObj.namespace ) ) && - ( !selector || selector === handleObj.selector || - selector === "**" && handleObj.selector ) ) { - handlers.splice( j, 1 ); - - if ( handleObj.selector ) { - handlers.delegateCount--; - } - if ( special.remove ) { - special.remove.call( elem, handleObj ); - } - } - } - - // Remove generic event handler if we removed something and no more handlers exist - // (avoids potential for endless recursion during removal of special event handlers) - if ( origCount && !handlers.length ) { - if ( !special.teardown || - special.teardown.call( elem, namespaces, elemData.handle ) === false ) { - - jQuery.removeEvent( elem, type, elemData.handle ); - } - - delete events[ type ]; - } - } - - // Remove data and the expando if it's no longer used - if ( jQuery.isEmptyObject( events ) ) { - dataPriv.remove( elem, "handle events" ); - } - }, - - dispatch: function( event ) { - - // Make a writable jQuery.Event from the native event object - event = jQuery.event.fix( event ); - - var i, j, ret, matched, handleObj, - handlerQueue = [], - args = slice.call( arguments ), - handlers = ( dataPriv.get( this, "events" ) || {} )[ event.type ] || [], - special = jQuery.event.special[ event.type ] || {}; - - // Use the fix-ed jQuery.Event rather than the (read-only) native event - args[ 0 ] = event; - event.delegateTarget = this; - - // Call the preDispatch hook for the mapped type, and let it bail if desired - if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { - return; - } - - // Determine handlers - handlerQueue = jQuery.event.handlers.call( this, event, handlers ); - - // Run delegates first; they may want to stop propagation beneath us - i = 0; - while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) { - event.currentTarget = matched.elem; - - j = 0; - while ( ( handleObj = matched.handlers[ j++ ] ) && - !event.isImmediatePropagationStopped() ) { - - // Triggered event must either 1) have no namespace, or 2) have namespace(s) - // a subset or equal to those in the bound event (both can have no namespace). - if ( !event.rnamespace || event.rnamespace.test( handleObj.namespace ) ) { - - event.handleObj = handleObj; - event.data = handleObj.data; - - ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle || - handleObj.handler ).apply( matched.elem, args ); - - if ( ret !== undefined ) { - if ( ( event.result = ret ) === false ) { - event.preventDefault(); - event.stopPropagation(); - } - } - } - } - } - - // Call the postDispatch hook for the mapped type - if ( special.postDispatch ) { - special.postDispatch.call( this, event ); - } - - return event.result; - }, - - handlers: function( event, handlers ) { - var i, matches, sel, handleObj, - handlerQueue = [], - delegateCount = handlers.delegateCount, - cur = event.target; - - // Support (at least): Chrome, IE9 - // Find delegate handlers - // Black-hole SVG instance trees (#13180) - // - // Support: Firefox<=42+ - // Avoid non-left-click in FF but don't block IE radio events (#3861, gh-2343) - if ( delegateCount && cur.nodeType && - ( event.type !== "click" || isNaN( event.button ) || event.button < 1 ) ) { - - for ( ; cur !== this; cur = cur.parentNode || this ) { - - // Don't check non-elements (#13208) - // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764) - if ( cur.nodeType === 1 && ( cur.disabled !== true || event.type !== "click" ) ) { - matches = []; - for ( i = 0; i < delegateCount; i++ ) { - handleObj = handlers[ i ]; - - // Don't conflict with Object.prototype properties (#13203) - sel = handleObj.selector + " "; - - if ( matches[ sel ] === undefined ) { - matches[ sel ] = handleObj.needsContext ? - jQuery( sel, this ).index( cur ) > -1 : - jQuery.find( sel, this, null, [ cur ] ).length; - } - if ( matches[ sel ] ) { - matches.push( handleObj ); - } - } - if ( matches.length ) { - handlerQueue.push( { elem: cur, handlers: matches } ); - } - } - } - } - - // Add the remaining (directly-bound) handlers - if ( delegateCount < handlers.length ) { - handlerQueue.push( { elem: this, handlers: handlers.slice( delegateCount ) } ); - } - - return handlerQueue; - }, - - // Includes some event props shared by KeyEvent and MouseEvent - props: ( "altKey bubbles cancelable ctrlKey currentTarget detail eventPhase " + - "metaKey relatedTarget shiftKey target timeStamp view which" ).split( " " ), - - fixHooks: {}, - - keyHooks: { - props: "char charCode key keyCode".split( " " ), - filter: function( event, original ) { - - // Add which for key events - if ( event.which == null ) { - event.which = original.charCode != null ? original.charCode : original.keyCode; - } - - return event; - } - }, - - mouseHooks: { - props: ( "button buttons clientX clientY offsetX offsetY pageX pageY " + - "screenX screenY toElement" ).split( " " ), - filter: function( event, original ) { - var eventDoc, doc, body, - button = original.button; - - // Calculate pageX/Y if missing and clientX/Y available - if ( event.pageX == null && original.clientX != null ) { - eventDoc = event.target.ownerDocument || document; - doc = eventDoc.documentElement; - body = eventDoc.body; - - event.pageX = original.clientX + - ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - - ( doc && doc.clientLeft || body && body.clientLeft || 0 ); - event.pageY = original.clientY + - ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - - ( doc && doc.clientTop || body && body.clientTop || 0 ); - } - - // Add which for click: 1 === left; 2 === middle; 3 === right - // Note: button is not normalized, so don't use it - if ( !event.which && button !== undefined ) { - event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) ); - } - - return event; - } - }, - - fix: function( event ) { - if ( event[ jQuery.expando ] ) { - return event; - } - - // Create a writable copy of the event object and normalize some properties - var i, prop, copy, - type = event.type, - originalEvent = event, - fixHook = this.fixHooks[ type ]; - - if ( !fixHook ) { - this.fixHooks[ type ] = fixHook = - rmouseEvent.test( type ) ? this.mouseHooks : - rkeyEvent.test( type ) ? this.keyHooks : - {}; - } - copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props; - - event = new jQuery.Event( originalEvent ); - - i = copy.length; - while ( i-- ) { - prop = copy[ i ]; - event[ prop ] = originalEvent[ prop ]; - } - - // Support: Cordova 2.5 (WebKit) (#13255) - // All events should have a target; Cordova deviceready doesn't - if ( !event.target ) { - event.target = document; - } - - // Support: Safari 6.0+, Chrome<28 - // Target should not be a text node (#504, #13143) - if ( event.target.nodeType === 3 ) { - event.target = event.target.parentNode; - } - - return fixHook.filter ? fixHook.filter( event, originalEvent ) : event; - }, - - special: { - load: { - - // Prevent triggered image.load events from bubbling to window.load - noBubble: true - }, - focus: { - - // Fire native event if possible so blur/focus sequence is correct - trigger: function() { - if ( this !== safeActiveElement() && this.focus ) { - this.focus(); - return false; - } - }, - delegateType: "focusin" - }, - blur: { - trigger: function() { - if ( this === safeActiveElement() && this.blur ) { - this.blur(); - return false; - } - }, - delegateType: "focusout" - }, - click: { - - // For checkbox, fire native event so checked state will be right - trigger: function() { - if ( this.type === "checkbox" && this.click && jQuery.nodeName( this, "input" ) ) { - this.click(); - return false; - } - }, - - // For cross-browser consistency, don't fire native .click() on links - _default: function( event ) { - return jQuery.nodeName( event.target, "a" ); - } - }, - - beforeunload: { - postDispatch: function( event ) { - - // Support: Firefox 20+ - // Firefox doesn't alert if the returnValue field is not set. - if ( event.result !== undefined && event.originalEvent ) { - event.originalEvent.returnValue = event.result; - } - } - } - } + global: {}, + + add: function( elem, types, handler, data, selector ) { + + var handleObjIn, eventHandle, tmp, + events, t, handleObj, + special, handlers, type, namespaces, origType, + elemData = dataPriv.get( elem ); + + // Only attach events to objects that accept data + if ( !acceptData( elem ) ) { + return; + } + + // Caller can pass in an object of custom data in lieu of the handler + if ( handler.handler ) { + handleObjIn = handler; + handler = handleObjIn.handler; + selector = handleObjIn.selector; + } + + // Ensure that invalid selectors throw exceptions at attach time + // Evaluate against documentElement in case elem is a non-element node (e.g., document) + if ( selector ) { + jQuery.find.matchesSelector( documentElement, selector ); + } + + // Make sure that the handler has a unique ID, used to find/remove it later + if ( !handler.guid ) { + handler.guid = jQuery.guid++; + } + + // Init the element's event structure and main handler, if this is the first + if ( !( events = elemData.events ) ) { + events = elemData.events = Object.create( null ); + } + if ( !( eventHandle = elemData.handle ) ) { + eventHandle = elemData.handle = function( e ) { + + // Discard the second event of a jQuery.event.trigger() and + // when an event is called after a page has unloaded + return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ? + jQuery.event.dispatch.apply( elem, arguments ) : undefined; + }; + } + + // Handle multiple events separated by a space + types = ( types || "" ).match( rnothtmlwhite ) || [ "" ]; + t = types.length; + while ( t-- ) { + tmp = rtypenamespace.exec( types[ t ] ) || []; + type = origType = tmp[ 1 ]; + namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); + + // There *must* be a type, no attaching namespace-only handlers + if ( !type ) { + continue; + } + + // If event changes its type, use the special event handlers for the changed type + special = jQuery.event.special[ type ] || {}; + + // If selector defined, determine special event api type, otherwise given type + type = ( selector ? special.delegateType : special.bindType ) || type; + + // Update special based on newly reset type + special = jQuery.event.special[ type ] || {}; + + // handleObj is passed to all event handlers + handleObj = jQuery.extend( { + type: type, + origType: origType, + data: data, + handler: handler, + guid: handler.guid, + selector: selector, + needsContext: selector && jQuery.expr.match.needsContext.test( selector ), + namespace: namespaces.join( "." ) + }, handleObjIn ); + + // Init the event handler queue if we're the first + if ( !( handlers = events[ type ] ) ) { + handlers = events[ type ] = []; + handlers.delegateCount = 0; + + // Only use addEventListener if the special events handler returns false + if ( !special.setup || + special.setup.call( elem, data, namespaces, eventHandle ) === false ) { + + if ( elem.addEventListener ) { + elem.addEventListener( type, eventHandle ); + } + } + } + + if ( special.add ) { + special.add.call( elem, handleObj ); + + if ( !handleObj.handler.guid ) { + handleObj.handler.guid = handler.guid; + } + } + + // Add to the element's handler list, delegates in front + if ( selector ) { + handlers.splice( handlers.delegateCount++, 0, handleObj ); + } else { + handlers.push( handleObj ); + } + + // Keep track of which events have ever been used, for event optimization + jQuery.event.global[ type ] = true; + } + + }, + + // Detach an event or set of events from an element + remove: function( elem, types, handler, selector, mappedTypes ) { + + var j, origCount, tmp, + events, t, handleObj, + special, handlers, type, namespaces, origType, + elemData = dataPriv.hasData( elem ) && dataPriv.get( elem ); + + if ( !elemData || !( events = elemData.events ) ) { + return; + } + + // Once for each type.namespace in types; type may be omitted + types = ( types || "" ).match( rnothtmlwhite ) || [ "" ]; + t = types.length; + while ( t-- ) { + tmp = rtypenamespace.exec( types[ t ] ) || []; + type = origType = tmp[ 1 ]; + namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); + + // Unbind all events (on this namespace, if provided) for the element + if ( !type ) { + for ( type in events ) { + jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); + } + continue; + } + + special = jQuery.event.special[ type ] || {}; + type = ( selector ? special.delegateType : special.bindType ) || type; + handlers = events[ type ] || []; + tmp = tmp[ 2 ] && + new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ); + + // Remove matching events + origCount = j = handlers.length; + while ( j-- ) { + handleObj = handlers[ j ]; + + if ( ( mappedTypes || origType === handleObj.origType ) && + ( !handler || handler.guid === handleObj.guid ) && + ( !tmp || tmp.test( handleObj.namespace ) ) && + ( !selector || selector === handleObj.selector || + selector === "**" && handleObj.selector ) ) { + handlers.splice( j, 1 ); + + if ( handleObj.selector ) { + handlers.delegateCount--; + } + if ( special.remove ) { + special.remove.call( elem, handleObj ); + } + } + } + + // Remove generic event handler if we removed something and no more handlers exist + // (avoids potential for endless recursion during removal of special event handlers) + if ( origCount && !handlers.length ) { + if ( !special.teardown || + special.teardown.call( elem, namespaces, elemData.handle ) === false ) { + + jQuery.removeEvent( elem, type, elemData.handle ); + } + + delete events[ type ]; + } + } + + // Remove data and the expando if it's no longer used + if ( jQuery.isEmptyObject( events ) ) { + dataPriv.remove( elem, "handle events" ); + } + }, + + dispatch: function( nativeEvent ) { + + var i, j, ret, matched, handleObj, handlerQueue, + args = new Array( arguments.length ), + + // Make a writable jQuery.Event from the native event object + event = jQuery.event.fix( nativeEvent ), + + handlers = ( + dataPriv.get( this, "events" ) || Object.create( null ) + )[ event.type ] || [], + special = jQuery.event.special[ event.type ] || {}; + + // Use the fix-ed jQuery.Event rather than the (read-only) native event + args[ 0 ] = event; + + for ( i = 1; i < arguments.length; i++ ) { + args[ i ] = arguments[ i ]; + } + + event.delegateTarget = this; + + // Call the preDispatch hook for the mapped type, and let it bail if desired + if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { + return; + } + + // Determine handlers + handlerQueue = jQuery.event.handlers.call( this, event, handlers ); + + // Run delegates first; they may want to stop propagation beneath us + i = 0; + while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) { + event.currentTarget = matched.elem; + + j = 0; + while ( ( handleObj = matched.handlers[ j++ ] ) && + !event.isImmediatePropagationStopped() ) { + + // If the event is namespaced, then each handler is only invoked if it is + // specially universal or its namespaces are a superset of the event's. + if ( !event.rnamespace || handleObj.namespace === false || + event.rnamespace.test( handleObj.namespace ) ) { + + event.handleObj = handleObj; + event.data = handleObj.data; + + ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle || + handleObj.handler ).apply( matched.elem, args ); + + if ( ret !== undefined ) { + if ( ( event.result = ret ) === false ) { + event.preventDefault(); + event.stopPropagation(); + } + } + } + } + } + + // Call the postDispatch hook for the mapped type + if ( special.postDispatch ) { + special.postDispatch.call( this, event ); + } + + return event.result; + }, + + handlers: function( event, handlers ) { + var i, handleObj, sel, matchedHandlers, matchedSelectors, + handlerQueue = [], + delegateCount = handlers.delegateCount, + cur = event.target; + + // Find delegate handlers + if ( delegateCount && + + // Support: IE <=9 + // Black-hole SVG instance trees (trac-13180) + cur.nodeType && + + // Support: Firefox <=42 + // Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861) + // https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click + // Support: IE 11 only + // ...but not arrow key "clicks" of radio inputs, which can have `button` -1 (gh-2343) + !( event.type === "click" && event.button >= 1 ) ) { + + for ( ; cur !== this; cur = cur.parentNode || this ) { + + // Don't check non-elements (#13208) + // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764) + if ( cur.nodeType === 1 && !( event.type === "click" && cur.disabled === true ) ) { + matchedHandlers = []; + matchedSelectors = {}; + for ( i = 0; i < delegateCount; i++ ) { + handleObj = handlers[ i ]; + + // Don't conflict with Object.prototype properties (#13203) + sel = handleObj.selector + " "; + + if ( matchedSelectors[ sel ] === undefined ) { + matchedSelectors[ sel ] = handleObj.needsContext ? + jQuery( sel, this ).index( cur ) > -1 : + jQuery.find( sel, this, null, [ cur ] ).length; + } + if ( matchedSelectors[ sel ] ) { + matchedHandlers.push( handleObj ); + } + } + if ( matchedHandlers.length ) { + handlerQueue.push( { elem: cur, handlers: matchedHandlers } ); + } + } + } + } + + // Add the remaining (directly-bound) handlers + cur = this; + if ( delegateCount < handlers.length ) { + handlerQueue.push( { elem: cur, handlers: handlers.slice( delegateCount ) } ); + } + + return handlerQueue; + }, + + addProp: function( name, hook ) { + Object.defineProperty( jQuery.Event.prototype, name, { + enumerable: true, + configurable: true, + + get: isFunction( hook ) ? + function() { + if ( this.originalEvent ) { + return hook( this.originalEvent ); + } + } : + function() { + if ( this.originalEvent ) { + return this.originalEvent[ name ]; + } + }, + + set: function( value ) { + Object.defineProperty( this, name, { + enumerable: true, + configurable: true, + writable: true, + value: value + } ); + } + } ); + }, + + fix: function( originalEvent ) { + return originalEvent[ jQuery.expando ] ? + originalEvent : + new jQuery.Event( originalEvent ); + }, + + special: { + load: { + + // Prevent triggered image.load events from bubbling to window.load + noBubble: true + }, + click: { + + // Utilize native event to ensure correct state for checkable inputs + setup: function( data ) { + + // For mutual compressibility with _default, replace `this` access with a local var. + // `|| data` is dead code meant only to preserve the variable through minification. + var el = this || data; + + // Claim the first handler + if ( rcheckableType.test( el.type ) && + el.click && nodeName( el, "input" ) ) { + + // dataPriv.set( el, "click", ... ) + leverageNative( el, "click", returnTrue ); + } + + // Return false to allow normal processing in the caller + return false; + }, + trigger: function( data ) { + + // For mutual compressibility with _default, replace `this` access with a local var. + // `|| data` is dead code meant only to preserve the variable through minification. + var el = this || data; + + // Force setup before triggering a click + if ( rcheckableType.test( el.type ) && + el.click && nodeName( el, "input" ) ) { + + leverageNative( el, "click" ); + } + + // Return non-false to allow normal event-path propagation + return true; + }, + + // For cross-browser consistency, suppress native .click() on links + // Also prevent it if we're currently inside a leveraged native-event stack + _default: function( event ) { + var target = event.target; + return rcheckableType.test( target.type ) && + target.click && nodeName( target, "input" ) && + dataPriv.get( target, "click" ) || + nodeName( target, "a" ); + } + }, + + beforeunload: { + postDispatch: function( event ) { + + // Support: Firefox 20+ + // Firefox doesn't alert if the returnValue field is not set. + if ( event.result !== undefined && event.originalEvent ) { + event.originalEvent.returnValue = event.result; + } + } + } + } }; +// Ensure the presence of an event listener that handles manually-triggered +// synthetic events by interrupting progress until reinvoked in response to +// *native* events that it fires directly, ensuring that state changes have +// already occurred before other listeners are invoked. +function leverageNative( el, type, expectSync ) { + + // Missing expectSync indicates a trigger call, which must force setup through jQuery.event.add + if ( !expectSync ) { + if ( dataPriv.get( el, type ) === undefined ) { + jQuery.event.add( el, type, returnTrue ); + } + return; + } + + // Register the controller as a special universal handler for all event namespaces + dataPriv.set( el, type, false ); + jQuery.event.add( el, type, { + namespace: false, + handler: function( event ) { + var notAsync, result, + saved = dataPriv.get( this, type ); + + if ( ( event.isTrigger & 1 ) && this[ type ] ) { + + // Interrupt processing of the outer synthetic .trigger()ed event + // Saved data should be false in such cases, but might be a leftover capture object + // from an async native handler (gh-4350) + if ( !saved.length ) { + + // Store arguments for use when handling the inner native event + // There will always be at least one argument (an event object), so this array + // will not be confused with a leftover capture object. + saved = slice.call( arguments ); + dataPriv.set( this, type, saved ); + + // Trigger the native event and capture its result + // Support: IE <=9 - 11+ + // focus() and blur() are asynchronous + notAsync = expectSync( this, type ); + this[ type ](); + result = dataPriv.get( this, type ); + if ( saved !== result || notAsync ) { + dataPriv.set( this, type, false ); + } else { + result = {}; + } + if ( saved !== result ) { + + // Cancel the outer synthetic event + event.stopImmediatePropagation(); + event.preventDefault(); + return result.value; + } + + // If this is an inner synthetic event for an event with a bubbling surrogate + // (focus or blur), assume that the surrogate already propagated from triggering the + // native event and prevent that from happening again here. + // This technically gets the ordering wrong w.r.t. to `.trigger()` (in which the + // bubbling surrogate propagates *after* the non-bubbling base), but that seems + // less bad than duplication. + } else if ( ( jQuery.event.special[ type ] || {} ).delegateType ) { + event.stopPropagation(); + } + + // If this is a native event triggered above, everything is now in order + // Fire an inner synthetic event with the original arguments + } else if ( saved.length ) { + + // ...and capture the result + dataPriv.set( this, type, { + value: jQuery.event.trigger( + + // Support: IE <=9 - 11+ + // Extend with the prototype to reset the above stopImmediatePropagation() + jQuery.extend( saved[ 0 ], jQuery.Event.prototype ), + saved.slice( 1 ), + this + ) + } ); + + // Abort handling of the native event + event.stopImmediatePropagation(); + } + } + } ); +} + jQuery.removeEvent = function( elem, type, handle ) { - // This "if" is needed for plain objects - if ( elem.removeEventListener ) { - elem.removeEventListener( type, handle ); - } + // This "if" is needed for plain objects + if ( elem.removeEventListener ) { + elem.removeEventListener( type, handle ); + } }; jQuery.Event = function( src, props ) { - // Allow instantiation without the 'new' keyword - if ( !( this instanceof jQuery.Event ) ) { - return new jQuery.Event( src, props ); - } - - // Event object - if ( src && src.type ) { - this.originalEvent = src; - this.type = src.type; - - // Events bubbling up the document may have been marked as prevented - // by a handler lower down the tree; reflect the correct value. - this.isDefaultPrevented = src.defaultPrevented || - src.defaultPrevented === undefined && - - // Support: Android<4.0 - src.returnValue === false ? - returnTrue : - returnFalse; - - // Event type - } else { - this.type = src; - } - - // Put explicitly provided properties onto the event object - if ( props ) { - jQuery.extend( this, props ); - } - - // Create a timestamp if incoming event doesn't have one - this.timeStamp = src && src.timeStamp || jQuery.now(); - - // Mark it as fixed - this[ jQuery.expando ] = true; + // Allow instantiation without the 'new' keyword + if ( !( this instanceof jQuery.Event ) ) { + return new jQuery.Event( src, props ); + } + + // Event object + if ( src && src.type ) { + this.originalEvent = src; + this.type = src.type; + + // Events bubbling up the document may have been marked as prevented + // by a handler lower down the tree; reflect the correct value. + this.isDefaultPrevented = src.defaultPrevented || + src.defaultPrevented === undefined && + + // Support: Android <=2.3 only + src.returnValue === false ? + returnTrue : + returnFalse; + + // Create target properties + // Support: Safari <=6 - 7 only + // Target should not be a text node (#504, #13143) + this.target = ( src.target && src.target.nodeType === 3 ) ? + src.target.parentNode : + src.target; + + this.currentTarget = src.currentTarget; + this.relatedTarget = src.relatedTarget; + + // Event type + } else { + this.type = src; + } + + // Put explicitly provided properties onto the event object + if ( props ) { + jQuery.extend( this, props ); + } + + // Create a timestamp if incoming event doesn't have one + this.timeStamp = src && src.timeStamp || Date.now(); + + // Mark it as fixed + this[ jQuery.expando ] = true; }; // jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding // https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html jQuery.Event.prototype = { - constructor: jQuery.Event, - isDefaultPrevented: returnFalse, - isPropagationStopped: returnFalse, - isImmediatePropagationStopped: returnFalse, + constructor: jQuery.Event, + isDefaultPrevented: returnFalse, + isPropagationStopped: returnFalse, + isImmediatePropagationStopped: returnFalse, + isSimulated: false, - preventDefault: function() { - var e = this.originalEvent; + preventDefault: function() { + var e = this.originalEvent; - this.isDefaultPrevented = returnTrue; + this.isDefaultPrevented = returnTrue; - if ( e ) { - e.preventDefault(); - } - }, - stopPropagation: function() { - var e = this.originalEvent; + if ( e && !this.isSimulated ) { + e.preventDefault(); + } + }, + stopPropagation: function() { + var e = this.originalEvent; - this.isPropagationStopped = returnTrue; + this.isPropagationStopped = returnTrue; - if ( e ) { - e.stopPropagation(); - } - }, - stopImmediatePropagation: function() { - var e = this.originalEvent; + if ( e && !this.isSimulated ) { + e.stopPropagation(); + } + }, + stopImmediatePropagation: function() { + var e = this.originalEvent; - this.isImmediatePropagationStopped = returnTrue; + this.isImmediatePropagationStopped = returnTrue; - if ( e ) { - e.stopImmediatePropagation(); - } + if ( e && !this.isSimulated ) { + e.stopImmediatePropagation(); + } - this.stopPropagation(); - } + this.stopPropagation(); + } }; +// Includes all common event props including KeyEvent and MouseEvent specific props +jQuery.each( { + altKey: true, + bubbles: true, + cancelable: true, + changedTouches: true, + ctrlKey: true, + detail: true, + eventPhase: true, + metaKey: true, + pageX: true, + pageY: true, + shiftKey: true, + view: true, + "char": true, + code: true, + charCode: true, + key: true, + keyCode: true, + button: true, + buttons: true, + clientX: true, + clientY: true, + offsetX: true, + offsetY: true, + pointerId: true, + pointerType: true, + screenX: true, + screenY: true, + targetTouches: true, + toElement: true, + touches: true, + + which: function( event ) { + var button = event.button; + + // Add which for key events + if ( event.which == null && rkeyEvent.test( event.type ) ) { + return event.charCode != null ? event.charCode : event.keyCode; + } + + // Add which for click: 1 === left; 2 === middle; 3 === right + if ( !event.which && button !== undefined && rmouseEvent.test( event.type ) ) { + if ( button & 1 ) { + return 1; + } + + if ( button & 2 ) { + return 3; + } + + if ( button & 4 ) { + return 2; + } + + return 0; + } + + return event.which; + } +}, jQuery.event.addProp ); + +jQuery.each( { focus: "focusin", blur: "focusout" }, function( type, delegateType ) { + jQuery.event.special[ type ] = { + + // Utilize native event if possible so blur/focus sequence is correct + setup: function() { + + // Claim the first handler + // dataPriv.set( this, "focus", ... ) + // dataPriv.set( this, "blur", ... ) + leverageNative( this, type, expectSync ); + + // Return false to allow normal processing in the caller + return false; + }, + trigger: function() { + + // Force setup before trigger + leverageNative( this, type ); + + // Return non-false to allow normal event-path propagation + return true; + }, + + delegateType: delegateType + }; +} ); + // Create mouseenter/leave events using mouseover/out and event-time checks // so that event delegation works in jQuery. // Do the same for pointerenter/pointerleave and pointerover/pointerout // // Support: Safari 7 only // Safari sends mouseenter too often; see: -// https://code.google.com/p/chromium/issues/detail?id=470258 +// https://bugs.chromium.org/p/chromium/issues/detail?id=470258 // for the description of the bug (it existed in older Chrome versions as well). jQuery.each( { - mouseenter: "mouseover", - mouseleave: "mouseout", - pointerenter: "pointerover", - pointerleave: "pointerout" + mouseenter: "mouseover", + mouseleave: "mouseout", + pointerenter: "pointerover", + pointerleave: "pointerout" }, function( orig, fix ) { - jQuery.event.special[ orig ] = { - delegateType: fix, - bindType: fix, - - handle: function( event ) { - var ret, - target = this, - related = event.relatedTarget, - handleObj = event.handleObj; - - // For mouseenter/leave call the handler if related is outside the target. - // NB: No relatedTarget if the mouse left/entered the browser window - if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) { - event.type = handleObj.origType; - ret = handleObj.handler.apply( this, arguments ); - event.type = fix; - } - return ret; - } - }; + jQuery.event.special[ orig ] = { + delegateType: fix, + bindType: fix, + + handle: function( event ) { + var ret, + target = this, + related = event.relatedTarget, + handleObj = event.handleObj; + + // For mouseenter/leave call the handler if related is outside the target. + // NB: No relatedTarget if the mouse left/entered the browser window + if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) { + event.type = handleObj.origType; + ret = handleObj.handler.apply( this, arguments ); + event.type = fix; + } + return ret; + } + }; } ); jQuery.fn.extend( { - on: function( types, selector, data, fn ) { - return on( this, types, selector, data, fn ); - }, - one: function( types, selector, data, fn ) { - return on( this, types, selector, data, fn, 1 ); - }, - off: function( types, selector, fn ) { - var handleObj, type; - if ( types && types.preventDefault && types.handleObj ) { - - // ( event ) dispatched jQuery.Event - handleObj = types.handleObj; - jQuery( types.delegateTarget ).off( - handleObj.namespace ? - handleObj.origType + "." + handleObj.namespace : - handleObj.origType, - handleObj.selector, - handleObj.handler - ); - return this; - } - if ( typeof types === "object" ) { - - // ( types-object [, selector] ) - for ( type in types ) { - this.off( type, selector, types[ type ] ); - } - return this; - } - if ( selector === false || typeof selector === "function" ) { - - // ( types [, fn] ) - fn = selector; - selector = undefined; - } - if ( fn === false ) { - fn = returnFalse; - } - return this.each( function() { - jQuery.event.remove( this, types, fn, selector ); - } ); - } + + on: function( types, selector, data, fn ) { + return on( this, types, selector, data, fn ); + }, + one: function( types, selector, data, fn ) { + return on( this, types, selector, data, fn, 1 ); + }, + off: function( types, selector, fn ) { + var handleObj, type; + if ( types && types.preventDefault && types.handleObj ) { + + // ( event ) dispatched jQuery.Event + handleObj = types.handleObj; + jQuery( types.delegateTarget ).off( + handleObj.namespace ? + handleObj.origType + "." + handleObj.namespace : + handleObj.origType, + handleObj.selector, + handleObj.handler + ); + return this; + } + if ( typeof types === "object" ) { + + // ( types-object [, selector] ) + for ( type in types ) { + this.off( type, selector, types[ type ] ); + } + return this; + } + if ( selector === false || typeof selector === "function" ) { + + // ( types [, fn] ) + fn = selector; + selector = undefined; + } + if ( fn === false ) { + fn = returnFalse; + } + return this.each( function() { + jQuery.event.remove( this, types, fn, selector ); + } ); + } } ); var - rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:-]+)[^>]*)\/>/gi, - // Support: IE 10-11, Edge 10240+ - // In IE/Edge using regex groups here causes severe slowdowns. - // See https://connect.microsoft.com/IE/feedback/details/1736512/ - rnoInnerhtml = /\s*$/g; + // checked="checked" or checked + rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i, + rcleanScript = /^\s*\s*$/g; +// Prefer a tbody over its parent table for containing new rows function manipulationTarget( elem, content ) { - if ( jQuery.nodeName( elem, "table" ) && - jQuery.nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ) { + if ( nodeName( elem, "table" ) && + nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ) { - return elem.getElementsByTagName( "tbody" )[ 0 ] || elem; - } + return jQuery( elem ).children( "tbody" )[ 0 ] || elem; + } - return elem; + return elem; } // Replace/restore the type attribute of script elements for safe DOM manipulation function disableScript( elem ) { - elem.type = ( elem.getAttribute( "type" ) !== null ) + "/" + elem.type; - return elem; + elem.type = ( elem.getAttribute( "type" ) !== null ) + "/" + elem.type; + return elem; } function restoreScript( elem ) { - var match = rscriptTypeMasked.exec( elem.type ); - - if ( match ) { - elem.type = match[ 1 ]; - } else { - elem.removeAttribute( "type" ); - } + if ( ( elem.type || "" ).slice( 0, 5 ) === "true/" ) { + elem.type = elem.type.slice( 5 ); + } else { + elem.removeAttribute( "type" ); + } - return elem; + return elem; } function cloneCopyEvent( src, dest ) { - var i, l, type, pdataOld, pdataCur, udataOld, udataCur, events; - - if ( dest.nodeType !== 1 ) { - return; - } - - // 1. Copy private data: events, handlers, etc. - if ( dataPriv.hasData( src ) ) { - pdataOld = dataPriv.access( src ); - pdataCur = dataPriv.set( dest, pdataOld ); - events = pdataOld.events; - - if ( events ) { - delete pdataCur.handle; - pdataCur.events = {}; - - for ( type in events ) { - for ( i = 0, l = events[ type ].length; i < l; i++ ) { - jQuery.event.add( dest, type, events[ type ][ i ] ); - } - } - } - } - - // 2. Copy user data - if ( dataUser.hasData( src ) ) { - udataOld = dataUser.access( src ); - udataCur = jQuery.extend( {}, udataOld ); - - dataUser.set( dest, udataCur ); - } + var i, l, type, pdataOld, udataOld, udataCur, events; + + if ( dest.nodeType !== 1 ) { + return; + } + + // 1. Copy private data: events, handlers, etc. + if ( dataPriv.hasData( src ) ) { + pdataOld = dataPriv.get( src ); + events = pdataOld.events; + + if ( events ) { + dataPriv.remove( dest, "handle events" ); + + for ( type in events ) { + for ( i = 0, l = events[ type ].length; i < l; i++ ) { + jQuery.event.add( dest, type, events[ type ][ i ] ); + } + } + } + } + + // 2. Copy user data + if ( dataUser.hasData( src ) ) { + udataOld = dataUser.access( src ); + udataCur = jQuery.extend( {}, udataOld ); + + dataUser.set( dest, udataCur ); + } } // Fix IE bugs, see support tests function fixInput( src, dest ) { - var nodeName = dest.nodeName.toLowerCase(); + var nodeName = dest.nodeName.toLowerCase(); - // Fails to persist the checked state of a cloned checkbox or radio button. - if ( nodeName === "input" && rcheckableType.test( src.type ) ) { - dest.checked = src.checked; + // Fails to persist the checked state of a cloned checkbox or radio button. + if ( nodeName === "input" && rcheckableType.test( src.type ) ) { + dest.checked = src.checked; - // Fails to return the selected option to the default selected state when cloning options - } else if ( nodeName === "input" || nodeName === "textarea" ) { - dest.defaultValue = src.defaultValue; - } + // Fails to return the selected option to the default selected state when cloning options + } else if ( nodeName === "input" || nodeName === "textarea" ) { + dest.defaultValue = src.defaultValue; + } } function domManip( collection, args, callback, ignored ) { - // Flatten any nested arrays - args = concat.apply( [], args ); - - var fragment, first, scripts, hasScripts, node, doc, - i = 0, - l = collection.length, - iNoClone = l - 1, - value = args[ 0 ], - isFunction = jQuery.isFunction( value ); - - // We can't cloneNode fragments that contain checked, in WebKit - if ( isFunction || - ( l > 1 && typeof value === "string" && - !support.checkClone && rchecked.test( value ) ) ) { - return collection.each( function( index ) { - var self = collection.eq( index ); - if ( isFunction ) { - args[ 0 ] = value.call( this, index, self.html() ); - } - domManip( self, args, callback, ignored ); - } ); - } - - if ( l ) { - fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored ); - first = fragment.firstChild; - - if ( fragment.childNodes.length === 1 ) { - fragment = first; - } - - // Require either new content or an interest in ignored elements to invoke the callback - if ( first || ignored ) { - scripts = jQuery.map( getAll( fragment, "script" ), disableScript ); - hasScripts = scripts.length; - - // Use the original fragment for the last item - // instead of the first because it can end up - // being emptied incorrectly in certain situations (#8070). - for ( ; i < l; i++ ) { - node = fragment; - - if ( i !== iNoClone ) { - node = jQuery.clone( node, true, true ); - - // Keep references to cloned scripts for later restoration - if ( hasScripts ) { - - // Support: Android<4.1, PhantomJS<2 - // push.apply(_, arraylike) throws on ancient WebKit - jQuery.merge( scripts, getAll( node, "script" ) ); - } - } - - callback.call( collection[ i ], node, i ); - } - - if ( hasScripts ) { - doc = scripts[ scripts.length - 1 ].ownerDocument; - - // Reenable scripts - jQuery.map( scripts, restoreScript ); - - // Evaluate executable scripts on first document insertion - for ( i = 0; i < hasScripts; i++ ) { - node = scripts[ i ]; - if ( rscriptType.test( node.type || "" ) && - !dataPriv.access( node, "globalEval" ) && - jQuery.contains( doc, node ) ) { - - if ( node.src ) { - - // Optional AJAX dependency, but won't run scripts if not present - if ( jQuery._evalUrl ) { - jQuery._evalUrl( node.src ); - } - } else { - jQuery.globalEval( node.textContent.replace( rcleanScript, "" ) ); - } - } - } - } - } - } - - return collection; + // Flatten any nested arrays + args = flat( args ); + + var fragment, first, scripts, hasScripts, node, doc, + i = 0, + l = collection.length, + iNoClone = l - 1, + value = args[ 0 ], + valueIsFunction = isFunction( value ); + + // We can't cloneNode fragments that contain checked, in WebKit + if ( valueIsFunction || + ( l > 1 && typeof value === "string" && + !support.checkClone && rchecked.test( value ) ) ) { + return collection.each( function( index ) { + var self = collection.eq( index ); + if ( valueIsFunction ) { + args[ 0 ] = value.call( this, index, self.html() ); + } + domManip( self, args, callback, ignored ); + } ); + } + + if ( l ) { + fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored ); + first = fragment.firstChild; + + if ( fragment.childNodes.length === 1 ) { + fragment = first; + } + + // Require either new content or an interest in ignored elements to invoke the callback + if ( first || ignored ) { + scripts = jQuery.map( getAll( fragment, "script" ), disableScript ); + hasScripts = scripts.length; + + // Use the original fragment for the last item + // instead of the first because it can end up + // being emptied incorrectly in certain situations (#8070). + for ( ; i < l; i++ ) { + node = fragment; + + if ( i !== iNoClone ) { + node = jQuery.clone( node, true, true ); + + // Keep references to cloned scripts for later restoration + if ( hasScripts ) { + + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + jQuery.merge( scripts, getAll( node, "script" ) ); + } + } + + callback.call( collection[ i ], node, i ); + } + + if ( hasScripts ) { + doc = scripts[ scripts.length - 1 ].ownerDocument; + + // Reenable scripts + jQuery.map( scripts, restoreScript ); + + // Evaluate executable scripts on first document insertion + for ( i = 0; i < hasScripts; i++ ) { + node = scripts[ i ]; + if ( rscriptType.test( node.type || "" ) && + !dataPriv.access( node, "globalEval" ) && + jQuery.contains( doc, node ) ) { + + if ( node.src && ( node.type || "" ).toLowerCase() !== "module" ) { + + // Optional AJAX dependency, but won't run scripts if not present + if ( jQuery._evalUrl && !node.noModule ) { + jQuery._evalUrl( node.src, { + nonce: node.nonce || node.getAttribute( "nonce" ) + }, doc ); + } + } else { + DOMEval( node.textContent.replace( rcleanScript, "" ), node, doc ); + } + } + } + } + } + } + + return collection; } function remove( elem, selector, keepData ) { - var node, - nodes = selector ? jQuery.filter( selector, elem ) : elem, - i = 0; - - for ( ; ( node = nodes[ i ] ) != null; i++ ) { - if ( !keepData && node.nodeType === 1 ) { - jQuery.cleanData( getAll( node ) ); - } - - if ( node.parentNode ) { - if ( keepData && jQuery.contains( node.ownerDocument, node ) ) { - setGlobalEval( getAll( node, "script" ) ); - } - node.parentNode.removeChild( node ); - } - } - - return elem; + var node, + nodes = selector ? jQuery.filter( selector, elem ) : elem, + i = 0; + + for ( ; ( node = nodes[ i ] ) != null; i++ ) { + if ( !keepData && node.nodeType === 1 ) { + jQuery.cleanData( getAll( node ) ); + } + + if ( node.parentNode ) { + if ( keepData && isAttached( node ) ) { + setGlobalEval( getAll( node, "script" ) ); + } + node.parentNode.removeChild( node ); + } + } + + return elem; } jQuery.extend( { - htmlPrefilter: function( html ) { - return html.replace( rxhtmlTag, "<$1>" ); - }, - - clone: function( elem, dataAndEvents, deepDataAndEvents ) { - var i, l, srcElements, destElements, - clone = elem.cloneNode( true ), - inPage = jQuery.contains( elem.ownerDocument, elem ); - - // Fix IE cloning issues - if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) && - !jQuery.isXMLDoc( elem ) ) { - - // We eschew Sizzle here for performance reasons: https://jsperf.com/getall-vs-sizzle/2 - destElements = getAll( clone ); - srcElements = getAll( elem ); - - for ( i = 0, l = srcElements.length; i < l; i++ ) { - fixInput( srcElements[ i ], destElements[ i ] ); - } - } - - // Copy the events from the original to the clone - if ( dataAndEvents ) { - if ( deepDataAndEvents ) { - srcElements = srcElements || getAll( elem ); - destElements = destElements || getAll( clone ); - - for ( i = 0, l = srcElements.length; i < l; i++ ) { - cloneCopyEvent( srcElements[ i ], destElements[ i ] ); - } - } else { - cloneCopyEvent( elem, clone ); - } - } - - // Preserve script evaluation history - destElements = getAll( clone, "script" ); - if ( destElements.length > 0 ) { - setGlobalEval( destElements, !inPage && getAll( elem, "script" ) ); - } - - // Return the cloned set - return clone; - }, - - cleanData: function( elems ) { - var data, elem, type, - special = jQuery.event.special, - i = 0; - - for ( ; ( elem = elems[ i ] ) !== undefined; i++ ) { - if ( acceptData( elem ) ) { - if ( ( data = elem[ dataPriv.expando ] ) ) { - if ( data.events ) { - for ( type in data.events ) { - if ( special[ type ] ) { - jQuery.event.remove( elem, type ); - - // This is a shortcut to avoid jQuery.event.remove's overhead - } else { - jQuery.removeEvent( elem, type, data.handle ); - } - } - } - - // Support: Chrome <= 35-45+ - // Assign undefined instead of using delete, see Data#remove - elem[ dataPriv.expando ] = undefined; - } - if ( elem[ dataUser.expando ] ) { - - // Support: Chrome <= 35-45+ - // Assign undefined instead of using delete, see Data#remove - elem[ dataUser.expando ] = undefined; - } - } - } - } + htmlPrefilter: function( html ) { + return html; + }, + + clone: function( elem, dataAndEvents, deepDataAndEvents ) { + var i, l, srcElements, destElements, + clone = elem.cloneNode( true ), + inPage = isAttached( elem ); + + // Fix IE cloning issues + if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) && + !jQuery.isXMLDoc( elem ) ) { + + // We eschew Sizzle here for performance reasons: https://jsperf.com/getall-vs-sizzle/2 + destElements = getAll( clone ); + srcElements = getAll( elem ); + + for ( i = 0, l = srcElements.length; i < l; i++ ) { + fixInput( srcElements[ i ], destElements[ i ] ); + } + } + + // Copy the events from the original to the clone + if ( dataAndEvents ) { + if ( deepDataAndEvents ) { + srcElements = srcElements || getAll( elem ); + destElements = destElements || getAll( clone ); + + for ( i = 0, l = srcElements.length; i < l; i++ ) { + cloneCopyEvent( srcElements[ i ], destElements[ i ] ); + } + } else { + cloneCopyEvent( elem, clone ); + } + } + + // Preserve script evaluation history + destElements = getAll( clone, "script" ); + if ( destElements.length > 0 ) { + setGlobalEval( destElements, !inPage && getAll( elem, "script" ) ); + } + + // Return the cloned set + return clone; + }, + + cleanData: function( elems ) { + var data, elem, type, + special = jQuery.event.special, + i = 0; + + for ( ; ( elem = elems[ i ] ) !== undefined; i++ ) { + if ( acceptData( elem ) ) { + if ( ( data = elem[ dataPriv.expando ] ) ) { + if ( data.events ) { + for ( type in data.events ) { + if ( special[ type ] ) { + jQuery.event.remove( elem, type ); + + // This is a shortcut to avoid jQuery.event.remove's overhead + } else { + jQuery.removeEvent( elem, type, data.handle ); + } + } + } + + // Support: Chrome <=35 - 45+ + // Assign undefined instead of using delete, see Data#remove + elem[ dataPriv.expando ] = undefined; + } + if ( elem[ dataUser.expando ] ) { + + // Support: Chrome <=35 - 45+ + // Assign undefined instead of using delete, see Data#remove + elem[ dataUser.expando ] = undefined; + } + } + } + } } ); jQuery.fn.extend( { - - // Keep domManip exposed until 3.0 (gh-2225) - domManip: domManip, - - detach: function( selector ) { - return remove( this, selector, true ); - }, - - remove: function( selector ) { - return remove( this, selector ); - }, - - text: function( value ) { - return access( this, function( value ) { - return value === undefined ? - jQuery.text( this ) : - this.empty().each( function() { - if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { - this.textContent = value; - } - } ); - }, null, value, arguments.length ); - }, - - append: function() { - return domManip( this, arguments, function( elem ) { - if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { - var target = manipulationTarget( this, elem ); - target.appendChild( elem ); - } - } ); - }, - - prepend: function() { - return domManip( this, arguments, function( elem ) { - if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { - var target = manipulationTarget( this, elem ); - target.insertBefore( elem, target.firstChild ); - } - } ); - }, - - before: function() { - return domManip( this, arguments, function( elem ) { - if ( this.parentNode ) { - this.parentNode.insertBefore( elem, this ); - } - } ); - }, - - after: function() { - return domManip( this, arguments, function( elem ) { - if ( this.parentNode ) { - this.parentNode.insertBefore( elem, this.nextSibling ); - } - } ); - }, - - empty: function() { - var elem, - i = 0; - - for ( ; ( elem = this[ i ] ) != null; i++ ) { - if ( elem.nodeType === 1 ) { - - // Prevent memory leaks - jQuery.cleanData( getAll( elem, false ) ); - - // Remove any remaining nodes - elem.textContent = ""; - } - } - - return this; - }, - - clone: function( dataAndEvents, deepDataAndEvents ) { - dataAndEvents = dataAndEvents == null ? false : dataAndEvents; - deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; - - return this.map( function() { - return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); - } ); - }, - - html: function( value ) { - return access( this, function( value ) { - var elem = this[ 0 ] || {}, - i = 0, - l = this.length; - - if ( value === undefined && elem.nodeType === 1 ) { - return elem.innerHTML; - } - - // See if we can take a shortcut and just use innerHTML - if ( typeof value === "string" && !rnoInnerhtml.test( value ) && - !wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) { - - value = jQuery.htmlPrefilter( value ); - - try { - for ( ; i < l; i++ ) { - elem = this[ i ] || {}; - - // Remove element nodes and prevent memory leaks - if ( elem.nodeType === 1 ) { - jQuery.cleanData( getAll( elem, false ) ); - elem.innerHTML = value; - } - } - - elem = 0; - - // If using innerHTML throws an exception, use the fallback method - } catch ( e ) {} - } - - if ( elem ) { - this.empty().append( value ); - } - }, null, value, arguments.length ); - }, - - replaceWith: function() { - var ignored = []; - - // Make the changes, replacing each non-ignored context element with the new content - return domManip( this, arguments, function( elem ) { - var parent = this.parentNode; - - if ( jQuery.inArray( this, ignored ) < 0 ) { - jQuery.cleanData( getAll( this ) ); - if ( parent ) { - parent.replaceChild( elem, this ); - } - } - - // Force callback invocation - }, ignored ); - } + detach: function( selector ) { + return remove( this, selector, true ); + }, + + remove: function( selector ) { + return remove( this, selector ); + }, + + text: function( value ) { + return access( this, function( value ) { + return value === undefined ? + jQuery.text( this ) : + this.empty().each( function() { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + this.textContent = value; + } + } ); + }, null, value, arguments.length ); + }, + + append: function() { + return domManip( this, arguments, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + var target = manipulationTarget( this, elem ); + target.appendChild( elem ); + } + } ); + }, + + prepend: function() { + return domManip( this, arguments, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + var target = manipulationTarget( this, elem ); + target.insertBefore( elem, target.firstChild ); + } + } ); + }, + + before: function() { + return domManip( this, arguments, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this ); + } + } ); + }, + + after: function() { + return domManip( this, arguments, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this.nextSibling ); + } + } ); + }, + + empty: function() { + var elem, + i = 0; + + for ( ; ( elem = this[ i ] ) != null; i++ ) { + if ( elem.nodeType === 1 ) { + + // Prevent memory leaks + jQuery.cleanData( getAll( elem, false ) ); + + // Remove any remaining nodes + elem.textContent = ""; + } + } + + return this; + }, + + clone: function( dataAndEvents, deepDataAndEvents ) { + dataAndEvents = dataAndEvents == null ? false : dataAndEvents; + deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; + + return this.map( function() { + return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); + } ); + }, + + html: function( value ) { + return access( this, function( value ) { + var elem = this[ 0 ] || {}, + i = 0, + l = this.length; + + if ( value === undefined && elem.nodeType === 1 ) { + return elem.innerHTML; + } + + // See if we can take a shortcut and just use innerHTML + if ( typeof value === "string" && !rnoInnerhtml.test( value ) && + !wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) { + + value = jQuery.htmlPrefilter( value ); + + try { + for ( ; i < l; i++ ) { + elem = this[ i ] || {}; + + // Remove element nodes and prevent memory leaks + if ( elem.nodeType === 1 ) { + jQuery.cleanData( getAll( elem, false ) ); + elem.innerHTML = value; + } + } + + elem = 0; + + // If using innerHTML throws an exception, use the fallback method + } catch ( e ) {} + } + + if ( elem ) { + this.empty().append( value ); + } + }, null, value, arguments.length ); + }, + + replaceWith: function() { + var ignored = []; + + // Make the changes, replacing each non-ignored context element with the new content + return domManip( this, arguments, function( elem ) { + var parent = this.parentNode; + + if ( jQuery.inArray( this, ignored ) < 0 ) { + jQuery.cleanData( getAll( this ) ); + if ( parent ) { + parent.replaceChild( elem, this ); + } + } + + // Force callback invocation + }, ignored ); + } } ); jQuery.each( { - appendTo: "append", - prependTo: "prepend", - insertBefore: "before", - insertAfter: "after", - replaceAll: "replaceWith" + appendTo: "append", + prependTo: "prepend", + insertBefore: "before", + insertAfter: "after", + replaceAll: "replaceWith" }, function( name, original ) { - jQuery.fn[ name ] = function( selector ) { - var elems, - ret = [], - insert = jQuery( selector ), - last = insert.length - 1, - i = 0; - - for ( ; i <= last; i++ ) { - elems = i === last ? this : this.clone( true ); - jQuery( insert[ i ] )[ original ]( elems ); - - // Support: QtWebKit - // .get() because push.apply(_, arraylike) throws - push.apply( ret, elems.get() ); - } - - return this.pushStack( ret ); - }; + jQuery.fn[ name ] = function( selector ) { + var elems, + ret = [], + insert = jQuery( selector ), + last = insert.length - 1, + i = 0; + + for ( ; i <= last; i++ ) { + elems = i === last ? this : this.clone( true ); + jQuery( insert[ i ] )[ original ]( elems ); + + // Support: Android <=4.0 only, PhantomJS 1 only + // .get() because push.apply(_, arraylike) throws on ancient WebKit + push.apply( ret, elems.get() ); + } + + return this.pushStack( ret ); + }; } ); - - -var iframe, - elemdisplay = { - - // Support: Firefox - // We have to pre-define these values for FF (#10227) - HTML: "block", - BODY: "block" - }; - -/** - * Retrieve the actual display of a element - * @param {String} name nodeName of the element - * @param {Object} doc Document object - */ - -// Called only from within defaultDisplay -function actualDisplay( name, doc ) { - var elem = jQuery( doc.createElement( name ) ).appendTo( doc.body ), - - display = jQuery.css( elem[ 0 ], "display" ); - - // We don't have any data stored on the element, - // so use "detach" method as fast way to get rid of the element - elem.detach(); - - return display; -} - -/** - * Try to determine the default display value of an element - * @param {String} nodeName - */ -function defaultDisplay( nodeName ) { - var doc = document, - display = elemdisplay[ nodeName ]; - - if ( !display ) { - display = actualDisplay( nodeName, doc ); - - // If the simple way fails, read from inside an iframe - if ( display === "none" || !display ) { - - // Use the already-created iframe if possible - iframe = ( iframe || jQuery( "