diff --git a/spring-test/src/main/java/org/springframework/test/web/servlet/result/FlashAttributeResultMatchers.java b/spring-test/src/main/java/org/springframework/test/web/servlet/result/FlashAttributeResultMatchers.java index b403f1d1b1..ce66b04499 100644 --- a/spring-test/src/main/java/org/springframework/test/web/servlet/result/FlashAttributeResultMatchers.java +++ b/spring-test/src/main/java/org/springframework/test/web/servlet/result/FlashAttributeResultMatchers.java @@ -18,6 +18,7 @@ package org.springframework.test.web.servlet.result; import org.hamcrest.Matcher; +import org.springframework.lang.Nullable; import org.springframework.test.web.servlet.ResultMatcher; import static org.hamcrest.MatcherAssert.assertThat; @@ -54,7 +55,7 @@ public class FlashAttributeResultMatchers { /** * Assert a flash attribute's value. */ - public ResultMatcher attribute(String name, Object value) { + public ResultMatcher attribute(String name, @Nullable Object value) { return result -> assertEquals("Flash attribute '" + name + "'", value, result.getFlashMap().get(name)); } diff --git a/spring-test/src/main/java/org/springframework/test/web/servlet/result/JsonPathResultMatchers.java b/spring-test/src/main/java/org/springframework/test/web/servlet/result/JsonPathResultMatchers.java index f2f78967bc..a0d882e2d5 100644 --- a/spring-test/src/main/java/org/springframework/test/web/servlet/result/JsonPathResultMatchers.java +++ b/spring-test/src/main/java/org/springframework/test/web/servlet/result/JsonPathResultMatchers.java @@ -107,7 +107,7 @@ public class JsonPathResultMatchers { * @see #value(Matcher) * @see #value(Matcher, Class) */ - public ResultMatcher value(Object expectedValue) { + public ResultMatcher value(@Nullable Object expectedValue) { return result -> this.jsonPathHelper.assertValue(getContent(result), expectedValue); } diff --git a/spring-test/src/main/java/org/springframework/test/web/servlet/result/ModelResultMatchers.java b/spring-test/src/main/java/org/springframework/test/web/servlet/result/ModelResultMatchers.java index 00bf0626fe..6cb0fce1f8 100644 --- a/spring-test/src/main/java/org/springframework/test/web/servlet/result/ModelResultMatchers.java +++ b/spring-test/src/main/java/org/springframework/test/web/servlet/result/ModelResultMatchers.java @@ -18,6 +18,7 @@ package org.springframework.test.web.servlet.result; import org.hamcrest.Matcher; +import org.springframework.lang.Nullable; import org.springframework.test.web.servlet.MvcResult; import org.springframework.test.web.servlet.ResultMatcher; import org.springframework.ui.ModelMap; @@ -67,7 +68,7 @@ public class ModelResultMatchers { /** * Assert a model attribute value. */ - public ResultMatcher attribute(String name, Object value) { + public ResultMatcher attribute(String name, @Nullable Object value) { return result -> { ModelAndView mav = getModelAndView(result); assertEquals("Model attribute '" + name + "'", value, mav.getModel().get(name)); diff --git a/spring-test/src/main/java/org/springframework/test/web/servlet/result/RequestResultMatchers.java b/spring-test/src/main/java/org/springframework/test/web/servlet/result/RequestResultMatchers.java index eb1c63bf5d..926e3f4349 100644 --- a/spring-test/src/main/java/org/springframework/test/web/servlet/result/RequestResultMatchers.java +++ b/spring-test/src/main/java/org/springframework/test/web/servlet/result/RequestResultMatchers.java @@ -23,6 +23,7 @@ import javax.servlet.http.HttpSession; import org.hamcrest.Matcher; +import org.springframework.lang.Nullable; import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.test.web.servlet.ResultMatcher; import org.springframework.util.Assert; @@ -98,7 +99,7 @@ public class RequestResultMatchers { * or {@link WebAsyncTask}. The value matched is the value returned from the * {@code Callable} or the exception raised. */ - public ResultMatcher asyncResult(Object expectedResult) { + public ResultMatcher asyncResult(@Nullable Object expectedResult) { return result -> { HttpServletRequest request = result.getRequest(); assertAsyncStarted(request); @@ -120,7 +121,7 @@ public class RequestResultMatchers { /** * Assert a request attribute value. */ - public ResultMatcher attribute(String name, Object expectedValue) { + public ResultMatcher attribute(String name, @Nullable Object expectedValue) { return result -> assertEquals("Request attribute '" + name + "'", expectedValue, result.getRequest().getAttribute(name)); } @@ -141,7 +142,7 @@ public class RequestResultMatchers { /** * Assert a session attribute value. */ - public ResultMatcher sessionAttribute(String name, Object value) { + public ResultMatcher sessionAttribute(String name, @Nullable Object value) { return result -> { HttpSession session = result.getRequest().getSession(); Assert.state(session != null, "No HttpSession"); diff --git a/spring-test/src/main/kotlin/org/springframework/test/web/servlet/MockMvcResultMatchersDsl.kt b/spring-test/src/main/kotlin/org/springframework/test/web/servlet/MockMvcResultMatchersDsl.kt index 6a5d909025..8971a80f4b 100644 --- a/spring-test/src/main/kotlin/org/springframework/test/web/servlet/MockMvcResultMatchersDsl.kt +++ b/spring-test/src/main/kotlin/org/springframework/test/web/servlet/MockMvcResultMatchersDsl.kt @@ -30,29 +30,29 @@ class MockMvcResultMatchersDsl internal constructor (private val actions: Result /** * @see MockMvcResultMatchers.request */ - fun request(matcher: RequestResultMatchers.() -> ResultMatcher) { - actions.andExpect(MockMvcResultMatchers.request().matcher()) + fun request(dsl: RequestResultMatchersDsl.() -> Unit) { + RequestResultMatchersDsl(actions).dsl() } /** * @see MockMvcResultMatchers.view */ - fun view(matcher: ViewResultMatchers.() -> ResultMatcher) { - actions.andExpect(MockMvcResultMatchers.view().matcher()) + fun view(dsl: ViewResultMatchersDsl.() -> Unit) { + ViewResultMatchersDsl(actions).dsl() } /** * @see MockMvcResultMatchers.model */ - fun model(matcher: ModelResultMatchers.() -> ResultMatcher) { - actions.andExpect(MockMvcResultMatchers.model().matcher()) + fun model(dsl: ModelResultMatchersDsl.() -> Unit) { + ModelResultMatchersDsl(actions).dsl() } /** * @see MockMvcResultMatchers.flash */ - fun flash(matcher: FlashAttributeResultMatchers.() -> ResultMatcher) { - actions.andExpect(MockMvcResultMatchers.flash().matcher()) + fun flash(dsl: FlashAttributeResultMatchersDsl.() -> Unit) { + FlashAttributeResultMatchersDsl(actions).dsl() } /** @@ -93,22 +93,22 @@ class MockMvcResultMatchersDsl internal constructor (private val actions: Result /** * @see MockMvcResultMatchers.status */ - fun status(matcher: StatusResultMatchers.() -> ResultMatcher) { - actions.andExpect(MockMvcResultMatchers.status().matcher()) + fun status(dsl: StatusResultMatchersDsl.() -> Unit) { + StatusResultMatchersDsl(actions).dsl() } /** * @see MockMvcResultMatchers.header */ - fun header(matcher: HeaderResultMatchers.() -> ResultMatcher) { - actions.andExpect(MockMvcResultMatchers.header().matcher()) + fun header(dsl: HeaderResultMatchersDsl.() -> Unit) { + HeaderResultMatchersDsl(actions).dsl() } /** * @see MockMvcResultMatchers.content */ - fun content(matcher: ContentResultMatchers.() -> ResultMatcher) { - actions.andExpect(MockMvcResultMatchers.content().matcher()) + fun content(dsl: ContentResultMatchersDsl.() -> Unit) { + ContentResultMatchersDsl(actions).dsl() } /** @@ -121,23 +121,22 @@ class MockMvcResultMatchersDsl internal constructor (private val actions: Result /** * @see MockMvcResultMatchers.jsonPath */ - fun jsonPath(expression: String, vararg args: Any, block: JsonPathResultMatchers.() -> ResultMatcher) { - actions.andExpect(MockMvcResultMatchers.jsonPath(expression, *args).block()) + fun jsonPath(expression: String, vararg args: Any?, dsl: JsonPathResultMatchersDsl.() -> Unit) { + JsonPathResultMatchersDsl(actions, expression, *args).dsl() } /** * @see MockMvcResultMatchers.xpath */ - fun xpath(expression: String, vararg args: Any, namespaces: Map? = null, xpathInit: XpathResultMatchers.() -> ResultMatcher) { - actions.andExpect(MockMvcResultMatchers.xpath(expression, namespaces, args).xpathInit()) + fun xpath(expression: String, vararg args: Any?, namespaces: Map? = null, dsl: XpathResultMatchersDsl.() -> Unit) { + XpathResultMatchersDsl(actions, expression, namespaces, *args).dsl() } /** * @see MockMvcResultMatchers.cookie */ - fun cookie(cookieInit: CookieResultMatchers.() -> ResultMatcher) { - val cookie = MockMvcResultMatchers.cookie().cookieInit() - actions.andExpect(cookie) + fun cookie(dsl: CookieResultMatchersDsl.() -> Unit) { + CookieResultMatchersDsl(actions).dsl() } /** diff --git a/spring-test/src/main/kotlin/org/springframework/test/web/servlet/result/ContentResultMatchersDsl.kt b/spring-test/src/main/kotlin/org/springframework/test/web/servlet/result/ContentResultMatchersDsl.kt new file mode 100644 index 0000000000..2ef41fdf1a --- /dev/null +++ b/spring-test/src/main/kotlin/org/springframework/test/web/servlet/result/ContentResultMatchersDsl.kt @@ -0,0 +1,118 @@ +/* + * Copyright 2002-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. + * 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.test.web.servlet.result + +import org.hamcrest.Matcher +import org.springframework.http.MediaType +import org.springframework.test.web.servlet.ResultActions +import org.w3c.dom.Node +import javax.xml.transform.Source + +/** + * Provide a [ContentResultMatchers] Kotlin DSL in order to be able to write idiomatic Kotlin code. + * + * @author Sebastien Deleuze + * @since 5.3 + */ +class ContentResultMatchersDsl internal constructor (private val actions: ResultActions) { + + private val matchers = MockMvcResultMatchers.content() + + /** + * @see ContentResultMatchers.contentType + */ + fun contentType(contentType: String) { + actions.andExpect(matchers.contentType(contentType)) + } + + /** + * @see ContentResultMatchers.contentType + */ + fun contentType(contentType: MediaType) { + actions.andExpect(matchers.contentType(contentType)) + } + + /** + * @see ContentResultMatchers.contentTypeCompatibleWith + */ + fun contentTypeCompatibleWith(contentType: String) { + actions.andExpect(matchers.contentTypeCompatibleWith(contentType)) + } + + /** + * @see ContentResultMatchers.contentTypeCompatibleWith + */ + fun contentTypeCompatibleWith(contentType: MediaType) { + actions.andExpect(matchers.contentTypeCompatibleWith(contentType)) + } + + /** + * @see ContentResultMatchers.encoding + */ + fun encoding(contentType: String) { + actions.andExpect(matchers.encoding(contentType)) + } + + /** + * @see ContentResultMatchers.string + */ + fun string(matcher: Matcher) { + actions.andExpect(matchers.string(matcher)) + } + + /** + * @see ContentResultMatchers.string + */ + fun string(expectedContent: String) { + actions.andExpect(matchers.string(expectedContent)) + } + + /** + * @see ContentResultMatchers.bytes + */ + fun bytes(expectedContent: ByteArray) { + actions.andExpect(matchers.bytes(expectedContent)) + } + + /** + * @see ContentResultMatchers.xml + */ + fun xml(xmlContent: String) { + actions.andExpect(matchers.xml(xmlContent)) + } + + /** + * @see ContentResultMatchers.node + */ + fun node(matcher: Matcher) { + actions.andExpect(matchers.node(matcher)) + } + + /** + * @see ContentResultMatchers.source + */ + fun source(matcher: Matcher) { + actions.andExpect(matchers.source(matcher)) + } + + /** + * @see ContentResultMatchers.json + */ + fun json(jsonContent: String, strict: Boolean = false) { + actions.andExpect(matchers.json(jsonContent, strict)) + } +} diff --git a/spring-test/src/main/kotlin/org/springframework/test/web/servlet/result/CookieResultMatchersDsl.kt b/spring-test/src/main/kotlin/org/springframework/test/web/servlet/result/CookieResultMatchersDsl.kt new file mode 100644 index 0000000000..987f7e19e3 --- /dev/null +++ b/spring-test/src/main/kotlin/org/springframework/test/web/servlet/result/CookieResultMatchersDsl.kt @@ -0,0 +1,143 @@ +/* + * Copyright 2002-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. + * 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.test.web.servlet.result + +import org.hamcrest.Matcher +import org.springframework.test.web.servlet.ResultActions + +/** + * Provide a [CookieResultMatchers] Kotlin DSL in order to be able to write idiomatic Kotlin code. + * + * @author Sebastien Deleuze + * @since 5.3 + */ +class CookieResultMatchersDsl internal constructor (private val actions: ResultActions) { + + private val matchers = MockMvcResultMatchers.cookie() + + /** + * @see CookieResultMatchers.value + */ + fun value(name: String, matcher: Matcher) { + actions.andExpect(matchers.value(name, matcher)) + } + + /** + * @see CookieResultMatchers.value + */ + fun value(name: String, expectedValue: String) { + actions.andExpect(matchers.value(name, expectedValue)) + } + + /** + * @see CookieResultMatchers.exists + */ + fun exists(name: String) { + actions.andExpect(matchers.exists(name)) + } + + /** + * @see CookieResultMatchers.doesNotExist + */ + fun doesNotExist(name: String) { + actions.andExpect(matchers.doesNotExist(name)) + } + + /** + * @see CookieResultMatchers.maxAge + */ + fun maxAge(name: String, matcher: Matcher) { + actions.andExpect(matchers.maxAge(name, matcher)) + } + + /** + * @see CookieResultMatchers.maxAge + */ + fun maxAge(name: String, maxAge: Int) { + actions.andExpect(matchers.maxAge(name, maxAge)) + } + + /** + * @see CookieResultMatchers.path + */ + fun path(name: String, matcher: Matcher) { + actions.andExpect(matchers.path(name, matcher)) + } + + /** + * @see CookieResultMatchers.path + */ + fun path(name: String, path: String) { + actions.andExpect(matchers.path(name, path)) + } + + /** + * @see CookieResultMatchers.domain + */ + fun domain(name: String, matcher: Matcher) { + actions.andExpect(matchers.domain(name, matcher)) + } + + /** + * @see CookieResultMatchers.domain + */ + fun domain(name: String, domain: String) { + actions.andExpect(matchers.domain(name, domain)) + } + + /** + * @see CookieResultMatchers.comment + */ + fun comment(name: String, matcher: Matcher) { + actions.andExpect(matchers.comment(name, matcher)) + } + + /** + * @see CookieResultMatchers.comment + */ + fun comment(name: String, comment: String) { + actions.andExpect(matchers.comment(name, comment)) + } + + /** + * @see CookieResultMatchers.version + */ + fun version(name: String, matcher: Matcher) { + actions.andExpect(matchers.version(name, matcher)) + } + + /** + * @see CookieResultMatchers.version + */ + fun version(name: String, version: Int) { + actions.andExpect(matchers.version(name, version)) + } + + /** + * @see CookieResultMatchers.secure + */ + fun secure(name: String, secure: Boolean) { + actions.andExpect(matchers.secure(name, secure)) + } + + /** + * @see CookieResultMatchers.httpOnly + */ + fun httpOnly(name: String, httpOnly: Boolean) { + actions.andExpect(matchers.httpOnly(name, httpOnly)) + } +} diff --git a/spring-test/src/main/kotlin/org/springframework/test/web/servlet/result/FlashAttributeResultMatchersDsl.kt b/spring-test/src/main/kotlin/org/springframework/test/web/servlet/result/FlashAttributeResultMatchersDsl.kt new file mode 100644 index 0000000000..13175b282f --- /dev/null +++ b/spring-test/src/main/kotlin/org/springframework/test/web/servlet/result/FlashAttributeResultMatchersDsl.kt @@ -0,0 +1,59 @@ +/* + * Copyright 2002-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. + * 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.test.web.servlet.result + +import org.hamcrest.Matcher +import org.springframework.test.web.servlet.ResultActions + +/** + * Provide a [FlashAttributeResultMatchers] Kotlin DSL in order to be able to write idiomatic Kotlin code. + * + * @author Sebastien Deleuze + * @since 5.3 + */ +class FlashAttributeResultMatchersDsl internal constructor (private val actions: ResultActions) { + + private val matchers = MockMvcResultMatchers.flash() + + /** + * @see FlashAttributeResultMatchers.attribute + */ + fun attribute(name: String, matcher: Matcher) { + actions.andExpect(matchers.attribute(name, matcher)) + } + + /** + * @see FlashAttributeResultMatchers.attribute + */ + fun attribute(name: String, value: Any?) { + actions.andExpect(matchers.attribute(name, value)) + } + + /** + * @see FlashAttributeResultMatchers.attributeExists + */ + fun attributeExists(vararg name: String) { + actions.andExpect(matchers.attributeExists(*name)) + } + + /** + * @see FlashAttributeResultMatchers.attributeCount + */ + fun attributeCount(count: Int) { + actions.andExpect(matchers.attributeCount(count)) + } +} diff --git a/spring-test/src/main/kotlin/org/springframework/test/web/servlet/result/HeaderResultMatchersDsl.kt b/spring-test/src/main/kotlin/org/springframework/test/web/servlet/result/HeaderResultMatchersDsl.kt new file mode 100644 index 0000000000..a8afcb4da7 --- /dev/null +++ b/spring-test/src/main/kotlin/org/springframework/test/web/servlet/result/HeaderResultMatchersDsl.kt @@ -0,0 +1,86 @@ +/* + * Copyright 2002-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. + * 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.test.web.servlet.result + +import org.hamcrest.Matcher +import org.springframework.test.web.servlet.ResultActions + +/** + * Provide a [HeaderResultMatchers] Kotlin DSL in order to be able to write idiomatic Kotlin code. + * + * @author Sebastien Deleuze + * @since 5.3 + */ +class HeaderResultMatchersDsl internal constructor (private val actions: ResultActions) { + + private val matchers = MockMvcResultMatchers.header() + + /** + * @see HeaderResultMatchersDsl.string + */ + fun string(name: String, matcher: Matcher) { + actions.andExpect(matchers.string(name, matcher)) + } + + /** + * @see HeaderResultMatchersDsl.stringValues + */ + fun stringValues(name: String, matcher: Matcher>) { + actions.andExpect(matchers.stringValues(name, matcher)) + } + + /** + * @see HeaderResultMatchersDsl.string + */ + fun string(name: String, value: String) { + actions.andExpect(matchers.string(name, value)) + } + + /** + * @see HeaderResultMatchersDsl.stringValues + */ + fun stringValues(name: String, vararg value: String) { + actions.andExpect(matchers.stringValues(name, *value)) + } + + /** + * @see HeaderResultMatchersDsl.exists + */ + fun exists(name: String) { + actions.andExpect(matchers.exists(name)) + } + + /** + * @see HeaderResultMatchersDsl.doesNotExist + */ + fun doesNotExist(name: String) { + actions.andExpect(matchers.doesNotExist(name)) + } + + /** + * @see HeaderResultMatchersDsl.longValue + */ + fun longValue(name: String, value: Long) { + actions.andExpect(matchers.longValue(name, value)) + } + /** + * @see HeaderResultMatchersDsl.dateValue + */ + fun dateValue(name: String, value: Long) { + actions.andExpect(matchers.dateValue(name, value)) + } +} diff --git a/spring-test/src/main/kotlin/org/springframework/test/web/servlet/result/JsonPathResultMatchersDsl.kt b/spring-test/src/main/kotlin/org/springframework/test/web/servlet/result/JsonPathResultMatchersDsl.kt new file mode 100644 index 0000000000..0993903b3b --- /dev/null +++ b/spring-test/src/main/kotlin/org/springframework/test/web/servlet/result/JsonPathResultMatchersDsl.kt @@ -0,0 +1,130 @@ +/* + * Copyright 2002-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. + * 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.test.web.servlet.result + +import org.hamcrest.Matcher +import org.springframework.test.web.servlet.ResultActions + +/** + * Provide a [JsonPathResultMatchers] Kotlin DSL in order to be able to write idiomatic Kotlin code. + * + * @author Sebastien Deleuze + * @since 5.3 + */ +@Suppress("UsePropertyAccessSyntax") +class JsonPathResultMatchersDsl internal constructor(@PublishedApi internal val actions: ResultActions, expression: String, vararg args: Any?) { + + @PublishedApi + internal val matchers = MockMvcResultMatchers.jsonPath(expression, args) + + /** + * @see JsonPathResultMatchers.prefix + */ + fun prefix(prefix: String) { + matchers.prefix(prefix) + } + + /** + * @see JsonPathResultMatchers.value + */ + inline fun value(matcher: Matcher) { + actions.andExpect(matchers.value(matcher, T::class.java)) + } + + /** + * @see JsonPathResultMatchers.value + */ + fun value(expectedValue: Any?) { + actions.andExpect(matchers.value(expectedValue)) + } + + /** + * @see JsonPathResultMatchers.exists + */ + fun exists() { + actions.andExpect(matchers.exists()) + } + + /** + * @see JsonPathResultMatchers.doesNotExist + */ + fun doesNotExist() { + actions.andExpect(matchers.doesNotExist()) + } + + /** + * @see JsonPathResultMatchers.isEmpty + */ + fun isEmpty() { + actions.andExpect(matchers.isEmpty()) + } + + /** + * @see JsonPathResultMatchers.isNotEmpty + */ + fun isNotEmpty() { + actions.andExpect(matchers.isNotEmpty()) + } + + /** + * @see JsonPathResultMatchers.hasJsonPath + */ + fun hasJsonPath() { + actions.andExpect(matchers.hasJsonPath()) + } + + /** + * @see JsonPathResultMatchers.doesNotHaveJsonPath + */ + fun doesNotHaveJsonPath() { + actions.andExpect(matchers.doesNotHaveJsonPath()) + } + + /** + * @see JsonPathResultMatchers.isString + */ + fun isString() { + actions.andExpect(matchers.isString()) + } + + /** + * @see JsonPathResultMatchers.isBoolean + */ + fun isBoolean() { + actions.andExpect(matchers.isBoolean()) + } + + /** + * @see JsonPathResultMatchers.isNumber + */ + fun isNumber() { + actions.andExpect(matchers.isNumber()) + } + + /** + * @see JsonPathResultMatchers.isArray + */ + fun isArray() { + actions.andExpect(matchers.isArray()) + } + + /** + * @see JsonPathResultMatchers.isMap + */ + fun isMap() { + actions.andExpect(matchers.isMap()) + } +} diff --git a/spring-test/src/main/kotlin/org/springframework/test/web/servlet/result/ModelResultMatchersDsl.kt b/spring-test/src/main/kotlin/org/springframework/test/web/servlet/result/ModelResultMatchersDsl.kt new file mode 100644 index 0000000000..68dc88465a --- /dev/null +++ b/spring-test/src/main/kotlin/org/springframework/test/web/servlet/result/ModelResultMatchersDsl.kt @@ -0,0 +1,129 @@ +/* + * Copyright 2002-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. + * 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.test.web.servlet.result + +import org.hamcrest.Matcher +import org.springframework.test.web.servlet.ResultActions + +/** + * Provide a [ModelResultMatchers] Kotlin DSL in order to be able to write idiomatic Kotlin code. + * + * @author Sebastien Deleuze + * @since 5.3 + */ +class ModelResultMatchersDsl internal constructor (private val actions: ResultActions) { + + private val matchers = MockMvcResultMatchers.model() + + /** + * @see ModelResultMatchers.attribute + */ + fun attribute(name: String, matcher: Matcher) { + actions.andExpect(matchers.attribute(name, matcher)) + } + + /** + * @see ModelResultMatchers.attribute + */ + fun attribute(name: String, value: Any?) { + actions.andExpect(matchers.attribute(name, value)) + } + + /** + * @see ModelResultMatchers.attributeExists + */ + fun attributeExists(vararg name: String) { + actions.andExpect(matchers.attributeExists(*name)) + } + + /** + * @see ModelResultMatchers.attributeDoesNotExist + */ + fun attributeDoesNotExist(vararg name: String) { + actions.andExpect(matchers.attributeDoesNotExist(*name)) + } + + /** + * @see ModelResultMatchers.attributeErrorCount + */ + fun attributeErrorCount(name: String, expectedCount: Int) { + actions.andExpect(matchers.attributeErrorCount(name, expectedCount)) + } + + /** + * @see ModelResultMatchers.attributeHasErrors + */ + fun attributeHasErrors(vararg name: String) { + actions.andExpect(matchers.attributeHasErrors(*name)) + } + + /** + * @see ModelResultMatchers.attributeHasNoErrors + */ + fun attributeHasNoErrors(vararg name: String) { + actions.andExpect(matchers.attributeHasNoErrors(*name)) + } + + /** + * @see ModelResultMatchers.attributeHasFieldErrors + */ + fun attributeHasFieldErrors(name: String, vararg fieldNames: String) { + actions.andExpect(matchers.attributeHasFieldErrors(name, *fieldNames)) + } + + /** + * @see ModelResultMatchers.attributeHasFieldErrorCode + */ + fun attributeHasFieldErrorCode(name: String, fieldName: String, code: String) { + actions.andExpect(matchers.attributeHasFieldErrorCode(name, fieldName, code)) + } + + /** + * @see ModelResultMatchers.attributeHasFieldErrorCode + */ + fun attributeHasFieldErrorCode(name: String, fieldName: String, matcher: Matcher) { + actions.andExpect(matchers.attributeHasFieldErrorCode(name, fieldName, matcher)) + } + + /** + * @see ModelResultMatchers.errorCount + */ + fun errorCount(expectedCount: Int) { + actions.andExpect(matchers.errorCount(expectedCount)) + } + + /** + * @see ModelResultMatchers.hasErrors + */ + fun hasErrors() { + actions.andExpect(matchers.hasErrors()) + } + + /** + * @see ModelResultMatchers.hasNoErrors + */ + fun hasNoErrors() { + actions.andExpect(matchers.hasNoErrors()) + } + + /** + * @see ModelResultMatchers.size + */ + fun size(size: Int) { + actions.andExpect(matchers.size(size)) + } +} diff --git a/spring-test/src/main/kotlin/org/springframework/test/web/servlet/result/RequestResultMatchersDsl.kt b/spring-test/src/main/kotlin/org/springframework/test/web/servlet/result/RequestResultMatchersDsl.kt new file mode 100644 index 0000000000..9f82d6fc1a --- /dev/null +++ b/spring-test/src/main/kotlin/org/springframework/test/web/servlet/result/RequestResultMatchersDsl.kt @@ -0,0 +1,94 @@ +/* + * Copyright 2002-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. + * 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.test.web.servlet.result + +import org.hamcrest.Matcher +import org.springframework.test.web.servlet.ResultActions + +/** + * Provide a [RequestResultMatchers] Kotlin DSL in order to be able to write idiomatic Kotlin code. + * + * @author Sebastien Deleuze + * @since 5.3 + */ +class RequestResultMatchersDsl internal constructor (private val actions: ResultActions) { + + private val matchers = MockMvcResultMatchers.request() + + /** + * @see RequestResultMatchers.asyncStarted + */ + fun asyncStarted() { + actions.andExpect(matchers.asyncStarted()) + } + + /** + * @see RequestResultMatchers.asyncStarted + */ + fun asyncNotStarted() { + actions.andExpect(matchers.asyncNotStarted()) + } + + /** + * @see RequestResultMatchers.asyncResult + */ + fun asyncResult(matcher: Matcher) { + actions.andExpect(matchers.asyncResult(matcher)) + } + + /** + * @see RequestResultMatchers.asyncResult + */ + fun asyncResult(expectedResult: Any?) { + actions.andExpect(matchers.asyncResult(expectedResult)) + } + + /** + * @see RequestResultMatchers.attribute + */ + fun attribute(name: String, matcher: Matcher) { + actions.andExpect(matchers.attribute(name, matcher)) + } + + /** + * @see RequestResultMatchers.attribute + */ + fun attribute(name: String, expectedValue: Any?) { + actions.andExpect(matchers.attribute(name, expectedValue)) + } + + /** + * @see RequestResultMatchers.sessionAttribute + */ + fun sessionAttribute(name: String, matcher: Matcher) { + actions.andExpect(matchers.sessionAttribute(name, matcher)) + } + + /** + * @see RequestResultMatchers.sessionAttribute + */ + fun sessionAttribute(name: String, expectedValue: Any?) { + actions.andExpect(matchers.sessionAttribute(name, expectedValue)) + } + + /** + * @see RequestResultMatchers.sessionAttributeDoesNotExist + */ + fun sessionAttributeDoesNotExist(vararg names: String) { + actions.andExpect(matchers.sessionAttributeDoesNotExist(*names)) + } +} diff --git a/spring-test/src/main/kotlin/org/springframework/test/web/servlet/result/StatusResultMatchersDsl.kt b/spring-test/src/main/kotlin/org/springframework/test/web/servlet/result/StatusResultMatchersDsl.kt new file mode 100644 index 0000000000..ef5b774829 --- /dev/null +++ b/spring-test/src/main/kotlin/org/springframework/test/web/servlet/result/StatusResultMatchersDsl.kt @@ -0,0 +1,515 @@ +/* + * Copyright 2002-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. + * 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.test.web.servlet.result + +import org.hamcrest.Matcher +import org.springframework.test.web.servlet.ResultActions + +/** + * Provide a [StatusResultMatchers] Kotlin DSL in order to be able to write idiomatic Kotlin code. + * + * @author Sebastien Deleuze + * @since 5.3 + */ +@Suppress("UsePropertyAccessSyntax") +class StatusResultMatchersDsl internal constructor (private val actions: ResultActions) { + + private val matchers = MockMvcResultMatchers.status() + + /** + * @see StatusResultMatchers.is + */ + fun isEqualTo(matcher: Matcher) { + actions.andExpect(matchers.`is`(matcher)) + } + + /** + * @see StatusResultMatchers.is + */ + fun isEqualTo(status: Int) { + actions.andExpect(matchers.`is`(status)) + } + + /** + * @see StatusResultMatchers.is1xxInformational + */ + fun is1xxInformational() { + actions.andExpect(matchers.is1xxInformational()) + } + + /** + * @see StatusResultMatchers.is2xxSuccessful + */ + fun is2xxSuccessful() { + actions.andExpect(matchers.is2xxSuccessful()) + } + + /** + * @see StatusResultMatchers.is3xxRedirection + */ + fun is3xxRedirection() { + actions.andExpect(matchers.is3xxRedirection()) + } + + /** + * @see StatusResultMatchers.is4xxClientError + */ + fun is4xxClientError() { + actions.andExpect(matchers.is4xxClientError()) + } + + /** + * @see StatusResultMatchers.is5xxServerError + */ + fun is5xxServerError() { + actions.andExpect(matchers.is5xxServerError()) + } + + /** + * @see StatusResultMatchers.reason + */ + fun reason(matcher: Matcher) { + actions.andExpect(matchers.reason(matcher)) + } + + /** + * @see StatusResultMatchers.reason + */ + fun reason(reason: String) { + actions.andExpect(matchers.reason(reason)) + } + + /** + * @see StatusResultMatchers.isContinue + */ + fun isContinue() { + actions.andExpect(matchers.isContinue()) + } + + /** + * @see StatusResultMatchers.isSwitchingProtocols + */ + fun isSwitchingProtocols() { + actions.andExpect(matchers.isSwitchingProtocols()) + } + + /** + * @see StatusResultMatchers.isProcessing + */ + fun isProcessing() { + actions.andExpect(matchers.isProcessing()) + } + + /** + * @see StatusResultMatchers.isCheckpoint + */ + fun isCheckpoint() { + actions.andExpect(matchers.isCheckpoint()) + } + + /** + * @see StatusResultMatchers.isOk + */ + fun isOk() { + actions.andExpect(matchers.isOk()) + } + + /** + * @see StatusResultMatchers.isCreated + */ + fun isCreated() { + actions.andExpect(matchers.isCreated()) + } + + /** + * @see StatusResultMatchers.isAccepted + */ + fun isAccepted() { + actions.andExpect(matchers.isAccepted()) + } + + /** + * @see StatusResultMatchers.isNonAuthoritativeInformation + */ + fun isNonAuthoritativeInformation() { + actions.andExpect(matchers.isNonAuthoritativeInformation()) + } + + /** + * @see StatusResultMatchers.isNoContent + */ + fun isNoContent() { + actions.andExpect(matchers.isNoContent()) + } + + /** + * @see StatusResultMatchers.isResetContent + */ + fun isResetContent() { + actions.andExpect(matchers.isResetContent()) + } + + /** + * @see StatusResultMatchers.isPartialContent + */ + fun isPartialContent() { + actions.andExpect(matchers.isPartialContent()) + } + + /** + * @see StatusResultMatchers.isMultiStatus + */ + fun isMultiStatus() { + actions.andExpect(matchers.isMultiStatus()) + } + + /** + * @see StatusResultMatchers.isAlreadyReported + */ + fun isAlreadyReported() { + actions.andExpect(matchers.isAlreadyReported()) + } + + /** + * @see StatusResultMatchers.isImUsed + */ + fun isImUsed() { + actions.andExpect(matchers.isImUsed()) + } + + /** + * @see StatusResultMatchers.isMultipleChoices + */ + fun isMultipleChoices() { + actions.andExpect(matchers.isMultipleChoices()) + } + + /** + * @see StatusResultMatchers.isFound + */ + fun isFound() { + actions.andExpect(matchers.isFound()) + } + + /** + * @see StatusResultMatchers.isSeeOther + */ + fun isSeeOther() { + actions.andExpect(matchers.isSeeOther()) + } + + /** + * @see StatusResultMatchers.isNotModified + */ + fun isNotModified() { + actions.andExpect(matchers.isNotModified()) + } + + /** + * @see StatusResultMatchers.isTemporaryRedirect + */ + fun isTemporaryRedirect() { + actions.andExpect(matchers.isTemporaryRedirect()) + } + + /** + * @see StatusResultMatchers.isPermanentRedirect + */ + fun isPermanentRedirect() { + actions.andExpect(matchers.isPermanentRedirect()) + } + + /** + * @see StatusResultMatchers.isBadRequest + */ + fun isBadRequest() { + actions.andExpect(matchers.isBadRequest()) + } + + /** + * @see StatusResultMatchers.isUnauthorized + */ + fun isUnauthorized() { + actions.andExpect(matchers.isUnauthorized()) + } + + /** + * @see StatusResultMatchers.isPaymentRequired + */ + fun isPaymentRequired() { + actions.andExpect(matchers.isPaymentRequired()) + } + + /** + * @see StatusResultMatchers.isForbidden + */ + fun isForbidden() { + actions.andExpect(matchers.isForbidden()) + } + + /** + * @see StatusResultMatchers.isNotFound + */ + fun isNotFound() { + actions.andExpect(matchers.isNotFound()) + } + + /** + * @see StatusResultMatchers.isMethodNotAllowed + */ + fun isMethodNotAllowed() { + actions.andExpect(matchers.isMethodNotAllowed()) + } + + /** + * @see StatusResultMatchers.isNotAcceptable + */ + fun isNotAcceptable() { + actions.andExpect(matchers.isNotAcceptable()) + } + + /** + * @see StatusResultMatchers.isProxyAuthenticationRequired + */ + fun isProxyAuthenticationRequired() { + actions.andExpect(matchers.isProxyAuthenticationRequired()) + } + + /** + * @see StatusResultMatchers.isRequestTimeout + */ + fun isRequestTimeout() { + actions.andExpect(matchers.isRequestTimeout()) + } + + /** + * @see StatusResultMatchers.isConflict + */ + fun isConflict() { + actions.andExpect(matchers.isConflict()) + } + + /** + * @see StatusResultMatchers.isGone + */ + fun isGone() { + actions.andExpect(matchers.isGone()) + } + + /** + * @see StatusResultMatchers.isLengthRequired + */ + fun isLengthRequired() { + actions.andExpect(matchers.isLengthRequired()) + } + + /** + * @see StatusResultMatchers.isPreconditionFailed + */ + fun isPreconditionFailed() { + actions.andExpect(matchers.isPreconditionFailed()) + } + + /** + * @see StatusResultMatchers.isPayloadTooLarge + */ + fun isPayloadTooLarge() { + actions.andExpect(matchers.isPayloadTooLarge()) + } + + /** + * @see StatusResultMatchers.isUriTooLong + */ + fun isUriTooLong() { + actions.andExpect(matchers.isUriTooLong()) + } + + /** + * @see StatusResultMatchers.isUnsupportedMediaType + */ + fun isUnsupportedMediaType() { + actions.andExpect(matchers.isUnsupportedMediaType()) + } + + /** + * @see StatusResultMatchers.isRequestedRangeNotSatisfiable + */ + fun isRequestedRangeNotSatisfiable() { + actions.andExpect(matchers.isRequestedRangeNotSatisfiable()) + } + + /** + * @see StatusResultMatchers.isExpectationFailed + */ + fun isExpectationFailed() { + actions.andExpect(matchers.isExpectationFailed()) + } + + /** + * @see StatusResultMatchers.isIAmATeapot + */ + fun isIAmATeapot() { + actions.andExpect(matchers.isIAmATeapot()) + } + + /** + * @see StatusResultMatchers.isUnprocessableEntity + */ + fun isUnprocessableEntity() { + actions.andExpect(matchers.isUnprocessableEntity()) + } + + /** + * @see StatusResultMatchers.isLocked + */ + fun isLocked() { + actions.andExpect(matchers.isLocked()) + } + + /** + * @see StatusResultMatchers.isFailedDependency + */ + fun isFailedDependency() { + actions.andExpect(matchers.isFailedDependency()) + } + + /** + * @see StatusResultMatchers.isTooEarly + */ + fun isTooEarly() { + actions.andExpect(matchers.isTooEarly()) + } + + /** + * @see StatusResultMatchers.isUpgradeRequired + */ + fun isUpgradeRequired() { + actions.andExpect(matchers.isUpgradeRequired()) + } + + /** + * @see StatusResultMatchers.isPreconditionRequired + */ + fun isPreconditionRequired() { + actions.andExpect(matchers.isPreconditionRequired()) + } + + /** + * @see StatusResultMatchers.isTooManyRequests + */ + fun isTooManyRequests() { + actions.andExpect(matchers.isTooManyRequests()) + } + + /** + * @see StatusResultMatchers.isRequestHeaderFieldsTooLarge + */ + fun isRequestHeaderFieldsTooLarge() { + actions.andExpect(matchers.isRequestHeaderFieldsTooLarge()) + } + + /** + * @see StatusResultMatchers.isUnavailableForLegalReasons + */ + fun isUnavailableForLegalReasons() { + actions.andExpect(matchers.isUnavailableForLegalReasons()) + } + + /** + * @see StatusResultMatchers.isInternalServerError + */ + fun isInternalServerError() { + actions.andExpect(matchers.isInternalServerError()) + } + + /** + * @see StatusResultMatchers.isNotImplemented + */ + fun isNotImplemented() { + actions.andExpect(matchers.isNotImplemented()) + } + + /** + * @see StatusResultMatchers.isBadGateway + */ + fun isBadGateway() { + actions.andExpect(matchers.isBadGateway()) + } + + /** + * @see StatusResultMatchers.isServiceUnavailable + */ + fun isServiceUnavailable() { + actions.andExpect(matchers.isServiceUnavailable()) + } + + /** + * @see StatusResultMatchers.isGatewayTimeout + */ + fun isGatewayTimeout() { + actions.andExpect(matchers.isGatewayTimeout()) + } + + /** + * @see StatusResultMatchers.isHttpVersionNotSupported + */ + fun isHttpVersionNotSupported() { + actions.andExpect(matchers.isHttpVersionNotSupported()) + } + + /** + * @see StatusResultMatchers.isVariantAlsoNegotiates + */ + fun isVariantAlsoNegotiates() { + actions.andExpect(matchers.isVariantAlsoNegotiates()) + } + + /** + * @see StatusResultMatchers.isInsufficientStorage + */ + fun isInsufficientStorage() { + actions.andExpect(matchers.isInsufficientStorage()) + } + + /** + * @see StatusResultMatchers.isLoopDetected + */ + fun isLoopDetected() { + actions.andExpect(matchers.isLoopDetected()) + } + + /** + * @see StatusResultMatchers.isBandwidthLimitExceeded + */ + fun isBandwidthLimitExceeded() { + actions.andExpect(matchers.isBandwidthLimitExceeded()) + } + + /** + * @see StatusResultMatchers.isNotExtended + */ + fun isNotExtended() { + actions.andExpect(matchers.isNotExtended()) + } + + /** + * @see StatusResultMatchers.isNetworkAuthenticationRequired + */ + fun isNetworkAuthenticationRequired() { + actions.andExpect(matchers.isNetworkAuthenticationRequired()) + } +} diff --git a/spring-test/src/main/kotlin/org/springframework/test/web/servlet/result/ViewResultMatchersDsl.kt b/spring-test/src/main/kotlin/org/springframework/test/web/servlet/result/ViewResultMatchersDsl.kt new file mode 100644 index 0000000000..92638570b7 --- /dev/null +++ b/spring-test/src/main/kotlin/org/springframework/test/web/servlet/result/ViewResultMatchersDsl.kt @@ -0,0 +1,46 @@ +/* + * Copyright 2002-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. + * 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.test.web.servlet.result + +import org.hamcrest.Matcher +import org.springframework.test.web.servlet.ResultActions + +/** + * Provide a [ViewResultMatchers] Kotlin DSL in order to be able to write idiomatic Kotlin code. + * + * @author Sebastien Deleuze + * @since 5.3 + */ +class ViewResultMatchersDsl internal constructor (private val actions: ResultActions) { + + private val matchers = MockMvcResultMatchers.view() + + /** + * @see ViewResultMatchers.name + */ + fun name(matcher: Matcher) { + actions.andExpect(matchers.name(matcher)) + } + + /** + * @see ViewResultMatchers.name + */ + fun name(expectedViewName: String) { + actions.andExpect(matchers.name(expectedViewName)) + } + +} diff --git a/spring-test/src/main/kotlin/org/springframework/test/web/servlet/result/XpathResultMatchersDsl.kt b/spring-test/src/main/kotlin/org/springframework/test/web/servlet/result/XpathResultMatchersDsl.kt new file mode 100644 index 0000000000..9f38d62998 --- /dev/null +++ b/spring-test/src/main/kotlin/org/springframework/test/web/servlet/result/XpathResultMatchersDsl.kt @@ -0,0 +1,110 @@ +/* + * Copyright 2002-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. + * 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.test.web.servlet.result + +import org.hamcrest.Matcher +import org.springframework.test.web.servlet.ResultActions +import org.w3c.dom.Node +import org.w3c.dom.NodeList + +/** + * Provide a [XpathResultMatchers] Kotlin DSL in order to be able to write idiomatic Kotlin code. + * + * @author Sebastien Deleuze + * @since 5.3 + */ +class XpathResultMatchersDsl internal constructor (private val actions: ResultActions, expression: String, namespaces: Map? = null, vararg args: Any?) { + + private val matchers = if (namespaces == null) MockMvcResultMatchers.xpath(expression, args) else MockMvcResultMatchers.xpath(expression, namespaces, args) + + /** + * @see XpathResultMatchers.node + */ + fun node(matcher: Matcher) { + actions.andExpect(matchers.node(matcher)) + } + + /** + * @see XpathResultMatchers.nodeList + */ + fun nodeList(matcher: Matcher) { + actions.andExpect(matchers.nodeList(matcher)) + } + + /** + * @see XpathResultMatchers.exists + */ + fun exists() { + actions.andExpect(matchers.exists()) + } + + /** + * @see XpathResultMatchers.doesNotExist + */ + fun doesNotExist() { + actions.andExpect(matchers.doesNotExist()) + } + + /** + * @see XpathResultMatchers.nodeCount + */ + fun nodeCount(matcher: Matcher) { + actions.andExpect(matchers.nodeCount(matcher)) + } + + /** + * @see XpathResultMatchers.nodeCount + */ + fun nodeCount(expectedCount: Int) { + actions.andExpect(matchers.nodeCount(expectedCount)) + } + + /** + * @see XpathResultMatchers.string + */ + fun string(matcher: Matcher) { + actions.andExpect(matchers.string(matcher)) + } + + /** + * @see XpathResultMatchers.string + */ + fun string(expectedValue: String) { + actions.andExpect(matchers.string(expectedValue)) + } + + /** + * @see XpathResultMatchers.number + */ + fun number(matcher: Matcher) { + actions.andExpect(matchers.number(matcher)) + } + + /** + * @see XpathResultMatchers.number + */ + fun number(expectedValue: Double) { + actions.andExpect(matchers.number(expectedValue)) + } + + /** + * @see XpathResultMatchers.booleanValue + */ + fun booleanValue(value: Boolean) { + actions.andExpect(matchers.booleanValue(value)) + } +} diff --git a/spring-test/src/test/kotlin/org/springframework/test/web/servlet/MockMvcExtensionsTests.kt b/spring-test/src/test/kotlin/org/springframework/test/web/servlet/MockMvcExtensionsTests.kt index 6324f197e6..72d750e413 100644 --- a/spring-test/src/test/kotlin/org/springframework/test/web/servlet/MockMvcExtensionsTests.kt +++ b/spring-test/src/test/kotlin/org/springframework/test/web/servlet/MockMvcExtensionsTests.kt @@ -18,6 +18,8 @@ package org.springframework.test.web.servlet import org.assertj.core.api.Assertions.* import org.hamcrest.CoreMatchers +import org.hamcrest.Matcher +import org.hamcrest.Matchers import org.junit.jupiter.api.Test import org.springframework.http.HttpMethod import org.springframework.http.HttpStatus @@ -25,6 +27,7 @@ import org.springframework.http.MediaType.* import org.springframework.test.web.Person import org.springframework.test.web.servlet.setup.MockMvcBuilders import org.springframework.web.bind.annotation.* +import org.springframework.web.servlet.ModelAndView import reactor.core.publisher.Mono import java.security.Principal import java.util.* @@ -50,7 +53,7 @@ class MockMvcExtensionsTests { } principal = Principal { "foo" } }.andExpect { - status { isOk } + status { isOk() } content { contentType(APPLICATION_JSON) } jsonPath("$.name") { value("Lee") } content { json("""{"someBoolean": false}""", false) } @@ -62,7 +65,7 @@ class MockMvcExtensionsTests { @Test fun `request without MockHttpServletRequestDsl`() { mockMvc.request(HttpMethod.GET, "/person/{name}", "Lee").andExpect { - status { isOk } + status { isOk() } }.andDo { print() } @@ -75,7 +78,7 @@ class MockMvcExtensionsTests { val matcher = ResultMatcher { matcherInvoked = true } val handler = ResultHandler { handlerInvoked = true } mockMvc.request(HttpMethod.GET, "/person/{name}", "Lee").andExpect { - status { isOk } + status { isOk() } }.andExpect { match(matcher) }.andDo { @@ -98,7 +101,7 @@ class MockMvcExtensionsTests { } principal = Principal { "foo" } }.andExpect { - status { isOk } + status { isOk() } content { contentType(APPLICATION_JSON) } jsonPath("$.name") { value("Lee") } content { json("""{"someBoolean": false}""", false) } @@ -117,7 +120,7 @@ class MockMvcExtensionsTests { } }.andExpect { status { - isCreated + isCreated() } } } @@ -139,7 +142,7 @@ class MockMvcExtensionsTests { assertThatExceptionOfType(AssertionError::class.java).isThrownBy { model { attributeExists("name", "wrong") } } assertThatExceptionOfType(AssertionError::class.java).isThrownBy { redirectedUrl("wrong/Url") } assertThatExceptionOfType(AssertionError::class.java).isThrownBy { redirectedUrlPattern("wrong/Url") } - assertThatExceptionOfType(AssertionError::class.java).isThrownBy { status { isAccepted } } + assertThatExceptionOfType(AssertionError::class.java).isThrownBy { status { isAccepted() } } assertThatExceptionOfType(AssertionError::class.java).isThrownBy { view { name("wrongName") } } assertThatExceptionOfType(AssertionError::class.java).isThrownBy { jsonPath("name") { value("wrong") } } } @@ -150,7 +153,7 @@ class MockMvcExtensionsTests { mockMvc.get("/person/Clint") { accept = APPLICATION_XML }.andExpect { - status { isOk } + status { isOk() } assertThatExceptionOfType(AssertionError::class.java).isThrownBy { xpath("//wrong") { nodeCount(1) } } }.andDo { print() @@ -160,7 +163,17 @@ class MockMvcExtensionsTests { @Test fun asyncDispatch() { mockMvc.get("/async").asyncDispatch().andExpect { - status { isOk } + status { isOk() } + } + } + + @Test + fun modelAndView() { + mockMvc.get("/").andExpect { + model { + assertThatExceptionOfType(AssertionError::class.java).isThrownBy { attribute("foo", "bar") } + attribute("foo", "foo") + } } } @@ -182,5 +195,8 @@ class MockMvcExtensionsTests { fun getAsync(): Mono { return Mono.just(Person("foo")) } + + @GetMapping("/") + fun index() = ModelAndView("index", mapOf("foo" to "foo", "bar" to "bar")) } }