How to use Constraints.and method of io.kotest.property.Constraints class

Best Kotest code snippet using io.kotest.property.Constraints.Constraints.and

ThreadControllerTest.kt

Source:ThreadControllerTest.kt Github

copy

Full Screen

1package com.github.njuro.jard.thread2import com.github.njuro.jard.MockMvcTest3import com.github.njuro.jard.TEST_ATTACHMENT_PNG4import com.github.njuro.jard.WithContainerDatabase5import com.github.njuro.jard.WithMockJardUser6import com.github.njuro.jard.ban.UserBannedException7import com.github.njuro.jard.board8import com.github.njuro.jard.board.BoardFacade9import com.github.njuro.jard.board.dto.BoardDto10import com.github.njuro.jard.common.InputConstraints.MAX_ATTACHMENT_SIZE11import com.github.njuro.jard.common.InputConstraints.MAX_NAME_LENGTH12import com.github.njuro.jard.common.InputConstraints.MAX_POST_LENGTH13import com.github.njuro.jard.common.InputConstraints.MAX_SUBJECT_LENGTH14import com.github.njuro.jard.common.InputConstraints.MAX_TRIPCODE_PASSWORD_LENGTH15import com.github.njuro.jard.common.Mappings16import com.github.njuro.jard.multipartFile17import com.github.njuro.jard.post18import com.github.njuro.jard.post.PostFacade19import com.github.njuro.jard.post.dto.DeleteOwnPostDto20import com.github.njuro.jard.post.dto.PostDto21import com.github.njuro.jard.post.dto.PostForm22import com.github.njuro.jard.randomString23import com.github.njuro.jard.thread24import com.github.njuro.jard.thread.dto.ThreadDto25import com.github.njuro.jard.thread.dto.ThreadForm26import com.github.njuro.jard.toForm27import com.github.njuro.jard.user.UserAuthority28import com.github.njuro.jard.utils.HttpUtils29import com.github.njuro.jard.utils.validation.PropertyValidationException30import com.ninjasquad.springmockk.MockkBean31import io.kotest.matchers.collections.shouldHaveSize32import io.kotest.matchers.collections.shouldNotBeEmpty33import io.kotest.matchers.nulls.shouldNotBeNull34import io.kotest.matchers.should35import io.kotest.matchers.shouldBe36import io.kotest.matchers.string.shouldStartWith37import io.mockk.Runs38import io.mockk.every39import io.mockk.just40import io.mockk.mockkStatic41import io.mockk.slot42import io.mockk.unmockkStatic43import org.junit.jupiter.api.AfterEach44import org.junit.jupiter.api.BeforeEach45import org.junit.jupiter.api.DisplayName46import org.junit.jupiter.api.Nested47import org.junit.jupiter.api.Test48import org.springframework.mock.web.MockMultipartFile49import org.springframework.test.web.servlet.delete50import org.springframework.test.web.servlet.get51import org.springframework.test.web.servlet.multipart52import org.springframework.test.web.servlet.patch53import java.io.IOException54@WithContainerDatabase55internal class ThreadControllerTest : MockMvcTest() {56 @MockkBean57 private lateinit var threadFacade: ThreadFacade58 @MockkBean59 private lateinit var boardFacade: BoardFacade60 @MockkBean61 private lateinit var postFacade: PostFacade62 private val board = board(label = "r")63 private val thread = thread(board)64 private val post = post(thread)65 @BeforeEach66 fun initMocks() {67 mockkStatic(HttpUtils::class)68 every { HttpUtils.getClientIp(any()) } returns "0.0.0.0"69 every { boardFacade.resolveBoard(board.label) } returns board.toDto()70 every { threadFacade.resolveThread(board.label, thread.threadNumber) } returns thread.toDto()71 every { postFacade.resolvePost(board.label, post.postNumber) } returns post.toDto()72 }73 @AfterEach74 fun clearMocks() {75 unmockkStatic(HttpUtils::class)76 }77 @Nested78 @DisplayName("create thread")79 inner class CreateThread {80 private fun createThread(81 threadForm: ThreadForm,82 attachment: MockMultipartFile? = multipartFile("attachment", TEST_ATTACHMENT_PNG)83 ) =84 mockMvc.multipart(Mappings.API_ROOT_THREADS, board.label) {85 part("threadForm", threadForm)86 if (attachment != null) file(attachment)87 }88 @Test89 fun `create valid thread`() {90 val thread = thread(board, subject = "Test thread")91 val threadForm = slot<ThreadForm>()92 every { threadFacade.createThread(capture(threadForm), ofType(BoardDto::class)) } returns thread.toDto()93 val response =94 createThread(thread.toForm()).andExpect { status { isCreated() } }.andReturnConverted<ThreadDto>()95 response.threadNumber shouldBe thread.threadNumber96 threadForm.captured.should {97 it.postForm.ip shouldStartWith "0"98 it.postForm.attachment.originalFilename shouldBe TEST_ATTACHMENT_PNG99 }100 }101 @Test102 fun `create thread with embedded attachment in original post`() {103 val thread = thread(board, subject = "Test thread")104 every {105 threadFacade.createThread(106 ofType(ThreadForm::class),107 ofType(BoardDto::class)108 )109 } answers { thread.toDto() }110 createThread(111 thread.toForm().apply { postForm.embedUrl = "some_url" },112 attachment = null113 ).andExpect { status { isCreated() } }114 .andReturnConverted<ThreadDto>().shouldNotBeNull()115 }116 @Test117 fun `don't create thread when user is banned`() {118 val thread = thread(board, subject = "Test thread")119 every {120 threadFacade.createThread(121 ofType(ThreadForm::class),122 ofType(BoardDto::class)123 )124 } throws UserBannedException()125 createThread(thread.toForm()).andExpect { status { isForbidden() } }126 }127 @Test128 fun `don't create thread with invalid subject`() {129 createThread(130 thread(131 board,132 subject = randomString(MAX_SUBJECT_LENGTH + 1)133 ).toForm()134 ).andExpectValidationError("subject")135 }136 @Test137 fun `don't create thread without subject and body`() {138 createThread(thread(board).toForm()).andExpectValidationError("emptySubjectAndComment")139 }140 @Test141 fun `don't create thread without attachment`() {142 createThread(thread(board).toForm(), attachment = null).andExpectValidationError("uploadedAttachment")143 }144 }145 @Nested146 @DisplayName("reply to thread")147 inner class ReplyToThread {148 private fun replyToThread(149 postForm: PostForm,150 attachment: MockMultipartFile? = multipartFile("attachment", TEST_ATTACHMENT_PNG)151 ) =152 mockMvc.multipart(153 "${Mappings.API_ROOT_THREADS}/${Mappings.PATH_VARIABLE_THREAD}",154 board.label,155 thread.threadNumber156 ) {157 part("postForm", postForm)158 if (attachment != null) file(attachment)159 }160 @Test161 fun `create valid reply`() {162 val post = post(thread)163 val postForm = slot<PostForm>()164 every { threadFacade.replyToThread(capture(postForm), ofType(ThreadDto::class)) } returns post.toDto()165 val response = replyToThread(post.toForm()).andExpect {166 status { isCreated() }167 jsonPath("$.thread") { doesNotExist() }168 }.andReturnConverted<PostDto>()169 response.postNumber shouldBe post.postNumber170 postForm.captured.should {171 it.ip shouldStartWith "0"172 it.attachment.originalFilename shouldBe TEST_ATTACHMENT_PNG173 }174 }175 @Test176 fun `create valid reply without attachment`() {177 val post = post(thread, body = "test")178 every { threadFacade.replyToThread(ofType(PostForm::class), ofType(ThreadDto::class)) } returns post.toDto()179 replyToThread(post.toForm()).andExpect { status { isCreated() } }.andReturnConverted<PostDto>()180 .shouldNotBeNull()181 }182 @Test183 fun `don't create reply with invalid name`() {184 replyToThread(post(thread, name = randomString(MAX_NAME_LENGTH + 1)).toForm())185 .andExpectValidationError("name")186 }187 @Test188 fun `don't create reply when user is banned`() {189 val post = post(thread, body = "test")190 every {191 threadFacade.replyToThread(192 ofType(PostForm::class),193 ofType(ThreadDto::class)194 )195 } throws UserBannedException()196 replyToThread(post.toForm()).andExpect { status { isForbidden() } }197 }198 @Test199 fun `don't create reply with invalid password`() {200 replyToThread(201 post(thread).toForm().apply {202 password = randomString(203 MAX_TRIPCODE_PASSWORD_LENGTH + 1204 )205 }206 ).andExpectValidationError("password")207 }208 @Test209 fun `don't create reply with invalid body`() {210 replyToThread(post(thread, body = randomString(MAX_POST_LENGTH + 1)).toForm())211 .andExpectValidationError("body")212 }213 @Test214 fun `don't create reply with invalid ip`() {215 every { HttpUtils.getClientIp(any()) } returns "a.b.c.d"216 replyToThread(post(thread).toForm()).andExpectValidationError("ip")217 }218 @Test219 fun `don't create reply with attachment too big`() {220 replyToThread(221 post(thread).toForm(),222 attachment = multipartFile("attachment", MAX_ATTACHMENT_SIZE + 1)223 ).andExpectValidationError("attachmentTooBig", message = MAX_ATTACHMENT_SIZE.toString())224 }225 @Test226 fun `don't create reply without attachment and body`() {227 replyToThread(post(thread).toForm(), attachment = null)228 .andExpectValidationError("attachmentOrNonEmptyBody")229 }230 }231 @Nested232 @DisplayName("get thread")233 inner class GetThread {234 private fun getThread() = mockMvc.get(235 "${Mappings.API_ROOT_THREADS}/${Mappings.PATH_VARIABLE_THREAD}",236 board.label,237 thread.threadNumber238 ) { setUp() }239 @Test240 fun `get existing thread`() {241 every { threadFacade.getThread(ofType(ThreadDto::class)) } returns thread.toDto()242 .apply {243 replies = listOf(post(thread, postNumber = 2L).toDto(), post(thread, postNumber = 3L).toDto())244 }245 val response = getThread().andExpect {246 status { isOk() }247 jsonPath("$.originalPost.thread") { doesNotExist() }248 jsonPath("$.originalPost.ip") { doesNotExist() }249 jsonPath("$.replies[*].thread") { doesNotExist() }250 jsonPath("$.replies[*].ip") { doesNotExist() }251 }.andReturnConverted<ThreadDto>()252 response.replies.shouldNotBeEmpty()253 }254 @Test255 fun `don't get non-existing thread`() {256 every { threadFacade.resolveThread(board.label, thread.threadNumber) } throws ThreadNotFoundException()257 getThread().andExpect { status { isNotFound() } }258 }259 }260 @Test261 fun `get new replies for thread`() {262 val lastPostNumber = slot<Long>()263 every {264 threadFacade.getNewReplies(265 ofType(ThreadDto::class),266 capture(lastPostNumber)267 )268 } returns listOf(post(thread).toDto(), post(thread).toDto())269 mockMvc.get(270 "${Mappings.API_ROOT_THREADS}/${Mappings.PATH_VARIABLE_THREAD}/new-replies?lastPost=3",271 board.label,272 thread.threadNumber273 ) { setUp() }.andExpect {274 status { isOk() }275 jsonPath("$[*].thread") { doesNotExist() }276 jsonPath("$[*].ip") { doesNotExist() }277 }.andReturnConverted<List<PostDto>>() shouldHaveSize 2278 lastPostNumber.captured shouldBe 3279 }280 @Test281 @WithMockJardUser(UserAuthority.TOGGLE_STICKY_THREAD)282 fun `toggle sticky on thread`() {283 every { threadFacade.toggleStickyOnThread(ofType(ThreadDto::class)) } just Runs284 mockMvc.patch(285 "${Mappings.API_ROOT_THREADS}/${Mappings.PATH_VARIABLE_THREAD}/sticky",286 board.label,287 thread.threadNumber288 ) { setUp() }.andExpect { status { isOk() } }289 }290 @Test291 @WithMockJardUser(UserAuthority.TOGGLE_LOCK_THREAD)292 fun `toggle lock on thread`() {293 every { threadFacade.toggleLockOnThread(ofType(ThreadDto::class)) } just Runs294 mockMvc.patch(295 "${Mappings.API_ROOT_THREADS}/${Mappings.PATH_VARIABLE_THREAD}/lock",296 board.label,297 thread.threadNumber298 ) { setUp() }.andExpect { status { isOk() } }299 }300 @Nested301 @DisplayName("delete post")302 @WithMockJardUser(UserAuthority.DELETE_POST)303 inner class DeletePost {304 private fun deletePost(postNumber: Long) = mockMvc.delete(305 "${Mappings.API_ROOT_THREADS}/${Mappings.PATH_VARIABLE_THREAD}/${Mappings.PATH_VARIABLE_POST}",306 board.label,307 thread.threadNumber,308 postNumber309 ) { setUp() }310 @Test311 fun `delete post`() {312 every { threadFacade.deletePost(ofType(ThreadDto::class), ofType(PostDto::class)) } just Runs313 deletePost(post.postNumber).andExpect { status { isOk() } }314 }315 @Test316 fun `don't delete post on IO exception`() {317 every { threadFacade.deletePost(ofType(ThreadDto::class), ofType(PostDto::class)) } throws IOException()318 deletePost(post.postNumber).andExpect { status { isBadRequest() } }319 }320 }321 @Nested322 @DisplayName("delete own post")323 inner class DeleteOwnPost {324 private fun deleteOwnPost(postNumber: Long, deletionCode: String = "abcde") = mockMvc.delete(325 "${Mappings.API_ROOT_THREADS}/${Mappings.PATH_VARIABLE_THREAD}/${Mappings.PATH_VARIABLE_POST}/delete-own",326 board.label,327 thread.threadNumber,328 postNumber329 ) { body(DeleteOwnPostDto(deletionCode)) }330 @Test331 fun `delete own post`() {332 val deletionCode = slot<String>()333 every { postFacade.deleteOwnPost(ofType(PostDto::class), capture(deletionCode)) } just Runs334 deleteOwnPost(post.postNumber).andExpect { status { isOk() } }335 deletionCode.captured shouldBe "abcde"336 }337 @Test338 fun `don't delete own post with incorrect deletion code`() {339 every {340 postFacade.deleteOwnPost(341 ofType(PostDto::class),342 ofType(String::class)343 )344 } throws PropertyValidationException("")345 deleteOwnPost(post.postNumber).andExpect { status { isBadRequest() } }346 }347 @Test348 fun `don't delete own post on IO exception`() {349 every { postFacade.deleteOwnPost(ofType(PostDto::class), ofType(String::class)) } throws IOException()350 deleteOwnPost(post.postNumber).andExpect { status { isBadRequest() } }351 }352 }353}...

Full Screen

Full Screen

UserControllerTest.kt

Source:UserControllerTest.kt Github

copy

Full Screen

1package com.github.njuro.jard.user2import com.github.njuro.jard.MockMvcTest3import com.github.njuro.jard.WithContainerDatabase4import com.github.njuro.jard.WithMockJardUser5import com.github.njuro.jard.common.InputConstraints.MAX_USERNAME_LENGTH6import com.github.njuro.jard.common.InputConstraints.MIN_PASSWORD_LENGTH7import com.github.njuro.jard.common.InputConstraints.MIN_USERNAME_LENGTH8import com.github.njuro.jard.common.Mappings9import com.github.njuro.jard.config.security.captcha.CaptchaVerificationException10import com.github.njuro.jard.forgotPasswordRequest11import com.github.njuro.jard.passwordEdit12import com.github.njuro.jard.randomString13import com.github.njuro.jard.resetPasswordRequest14import com.github.njuro.jard.toForm15import com.github.njuro.jard.user16import com.github.njuro.jard.user.dto.CurrentUserEditDto17import com.github.njuro.jard.user.dto.CurrentUserPasswordEditDto18import com.github.njuro.jard.user.dto.ForgotPasswordDto19import com.github.njuro.jard.user.dto.ResetPasswordDto20import com.github.njuro.jard.user.dto.UserDto21import com.github.njuro.jard.user.dto.UserForm22import com.github.njuro.jard.userEdit23import com.github.njuro.jard.utils.validation.PropertyValidationException24import com.ninjasquad.springmockk.MockkBean25import io.kotest.matchers.collections.shouldHaveSize26import io.kotest.matchers.nulls.shouldNotBeNull27import io.kotest.matchers.should28import io.kotest.matchers.shouldBe29import io.mockk.Runs30import io.mockk.every31import io.mockk.just32import io.mockk.slot33import org.junit.jupiter.api.BeforeEach34import org.junit.jupiter.api.DisplayName35import org.junit.jupiter.api.Nested36import org.junit.jupiter.api.Test37import org.springframework.http.HttpHeaders38import org.springframework.test.web.servlet.delete39import org.springframework.test.web.servlet.get40import org.springframework.test.web.servlet.patch41import org.springframework.test.web.servlet.post42import org.springframework.test.web.servlet.put43@WithContainerDatabase44internal class UserControllerTest : MockMvcTest() {45 @MockkBean46 private lateinit var userFacade: UserFacade47 @Nested48 @DisplayName("create user")49 @WithMockJardUser(UserAuthority.MANAGE_USERS)50 inner class CreateUser {51 private fun createUser(userForm: UserForm, ip: String = "1.2.3.4") = mockMvc.post(Mappings.API_ROOT_USERS) {52 body(userForm)53 with { it.apply { remoteAddr = ip } }54 }55 @Test56 fun `create valid user`() {57 val user = user(username = "John", registrationIp = "127.0.0.1")58 val userForm = slot<UserForm>()59 every { userFacade.createUser(capture(userForm)) } returns user.toDto()60 val response = createUser(user.toForm()).andExpect { status { isCreated() } }.andReturnConverted<UserDto>()61 response.username shouldBe user.username62 userForm.captured.registrationIp shouldBe "1.2.3.4"63 }64 @Test65 fun `don't create user with invalid username`() {66 createUser(user(username = randomString(MIN_USERNAME_LENGTH - 1)).toForm()).andExpectValidationError("username")67 createUser(user(username = randomString(MAX_USERNAME_LENGTH + 1)).toForm()).andExpectValidationError("username")68 }69 @Test70 fun `don't create user with invalid password`() {71 createUser(user(password = randomString(MIN_PASSWORD_LENGTH - 1)).toForm()).andExpectValidationError("password")72 }73 @Test74 fun `don't create user with invalid email`() {75 createUser(user(email = "abcdefgh").toForm()).andExpectValidationError("email")76 }77 @Test78 fun `don't create user with invalid registration ip`() {79 createUser(user(registrationIp = "1234").toForm()).andExpectValidationError("registrationIp")80 }81 @Test82 fun `don't create user with invalid role`() {83 createUser(user(role = null).toForm()).andExpectValidationError("role")84 }85 @Test86 fun `don't create user with non-matching password`() {87 createUser(88 user().toForm()89 .apply { password = "firstpass"; passwordRepeated = "secondpass" }90 )91 .andExpectValidationError("passwordMatching")92 }93 }94 @Test95 @WithMockJardUser(UserAuthority.MANAGE_USERS)96 fun `get all users`() {97 every { userFacade.allUsers } returns (1..3).map { user(username = "User $it").toDto() }98 mockMvc.get(Mappings.API_ROOT_USERS) { setUp() }.andExpect {99 status { isOk() }100 jsonPath("$[*].username") { exists() }101 jsonPath("$[*].email") { exists() }102 jsonPath("$[*].role") { exists() }103 jsonPath("$[*].lastLoginIp") { doesNotExist() }104 jsonPath("$[*].registrationIp") { doesNotExist() }105 }.andReturnConverted<List<UserDto>>() shouldHaveSize 3106 }107 @Test108 fun `get current user`() {109 every { userFacade.currentUser } returns user(username = "Anonymous", role = UserRole.ADMIN).toDto()110 val response = mockMvc.get("${Mappings.API_ROOT_USERS}/current") { setUp() }.andExpect {111 status { isOk() }112 jsonPath("$.username") { exists() }113 jsonPath("$.registrationIp") { doesNotExist() }114 }.andReturnConverted<UserDto>()115 response.username shouldBe "Anonymous"116 response.role shouldBe UserRole.ADMIN117 }118 @Nested119 @DisplayName("edit user")120 @WithMockJardUser(UserAuthority.MANAGE_USERS)121 inner class EditUser {122 private fun editUser(username: String, editForm: UserForm) =123 mockMvc.put("${Mappings.API_ROOT_USERS}/$username") { body(editForm) }124 @Test125 fun `edit user`() {126 val user = user(username = "Anonymous")127 every { userFacade.resolveUser(user.username) } returns user.toDto()128 every { userFacade.editUser(ofType(UserDto::class), ofType(UserForm::class)) } returns user.toDto()129 val response = editUser(user.username, user.toForm())130 .andExpect { status { isOk() } }131 .andReturnConverted<UserDto>()132 response.username shouldBe user.username133 }134 @Test135 fun `don't edit non-existing user`() {136 every { userFacade.resolveUser(ofType(String::class)) } throws UserNotFoundException()137 editUser("xxx", user().toForm()).andExpect { status { isNotFound() } }138 }139 }140 @Nested141 @DisplayName("edit current user")142 inner class EditUserCurrentUser {143 private fun editCurrentUser(userEdit: CurrentUserEditDto) =144 mockMvc.patch("${Mappings.API_ROOT_USERS}/current") { body(userEdit) }145 @Test146 fun `edit user email when new email is valid`() {147 every { userFacade.editCurrentUser(ofType(CurrentUserEditDto::class)) } answers { user(email = firstArg<CurrentUserEditDto>().email).toDto() }148 editCurrentUser(userEdit("new@mail.com")).andExpect {149 status { isOk() }150 jsonPath("$.username") { exists() }151 jsonPath("$.registrationIp") { doesNotExist() }152 }.andReturnConverted<UserDto>()153 .shouldNotBeNull()154 }155 @Test156 fun `don't edit user email when new email is not valid`() {157 every { userFacade.editCurrentUser(ofType(CurrentUserEditDto::class)) } answers { user(email = firstArg<CurrentUserEditDto>().email).toDto() }158 editCurrentUser(userEdit("xxx")).andExpect { status { isBadRequest() } }159 }160 }161 @Nested162 @DisplayName("edit current user password")163 inner class EditUserCurrentUserPassword {164 private fun editCurrentUserPassword(passwordEdit: CurrentUserPasswordEditDto) =165 mockMvc.patch("${Mappings.API_ROOT_USERS}/current/password") { body(passwordEdit) }166 @Test167 fun `edit user password when new password is valid`() {168 every { userFacade.editCurrentUserPassword(ofType(CurrentUserPasswordEditDto::class)) } just Runs169 editCurrentUserPassword(passwordEdit("oldPassword", "newPassword")).andExpect { status { isOk() } }170 }171 @Test172 fun `don't edit user password when new password is not valid`() {173 every { userFacade.editCurrentUserPassword(ofType(CurrentUserPasswordEditDto::class)) } just Runs174 editCurrentUserPassword(passwordEdit(null, "a")).andExpectValidationError("currentPassword")175 editCurrentUserPassword(passwordEdit("oldPassword", "a")).andExpectValidationError("newPassword")176 editCurrentUserPassword(177 passwordEdit(178 "oldPassword",179 "newPassword",180 newPasswordRepeated = "otherPassword"181 )182 ).andExpectValidationError("passwordMatching")183 }184 }185 @Nested186 @DisplayName("forgot password")187 inner class ForgotPassword {188 private fun forgotPassword(request: ForgotPasswordDto) =189 mockMvc.post("${Mappings.API_ROOT_USERS}/forgot-password") {190 body(request)191 with { it.apply { remoteAddr = "127.0.0.1" } }192 header(HttpHeaders.USER_AGENT, "test-user-agent")193 }194 @Test195 fun `valid request`() {196 val request = slot<ForgotPasswordDto>()197 every { userFacade.sendPasswordResetLink(capture(request)) } just Runs198 forgotPassword(199 forgotPasswordRequest(200 "user",201 ip = "1.2.3.4",202 userAgent = "fake-ua"203 )204 ).andExpect { status { isOk() } }205 request.captured.should {206 it.username shouldBe "user"207 it.ip shouldBe "127.0.0.1"208 it.userAgent shouldBe "test-user-agent"209 }210 }211 @Test212 fun `invalid request - validation exception`() {213 every { userFacade.sendPasswordResetLink(any()) } throws PropertyValidationException(214 ""215 )216 // we are expecting 200 despite exception (silenced for security reasons)217 forgotPassword(forgotPasswordRequest("user")).andExpect { status { isOk() } }218 }219 @Test220 fun `invalid request - user not found exception`() {221 every { userFacade.sendPasswordResetLink(any()) } throws UserNotFoundException()222 // we are expecting 200 despite exception (silenced for security reasons)223 forgotPassword(forgotPasswordRequest("user")).andExpect { status { isOk() } }224 }225 @Test226 fun `invalid request - captcha exception`() {227 every { userFacade.sendPasswordResetLink(any()) } throws CaptchaVerificationException()228 forgotPassword(forgotPasswordRequest("user")).andExpect { status { isBadRequest() } }229 }230 }231 @Nested232 @DisplayName("reset user password")233 inner class ResetUserPassword {234 private fun resetPassword(request: ResetPasswordDto) =235 mockMvc.post("${Mappings.API_ROOT_USERS}/reset-password") { body(request) }236 @BeforeEach237 fun setUp() {238 every { userFacade.resetPassword(ofType(ResetPasswordDto::class)) } just Runs239 }240 @Test241 fun `valid reset request`() {242 resetPassword(resetPasswordRequest(password = "newPassword"))243 .andExpect { status { isOk() } }244 }245 @Test246 fun `invalid reset request`() {247 resetPassword(resetPasswordRequest(password = "newPassword", passwordRepeated = "xxx"))248 .andExpect { status { isBadRequest() } }249 resetPassword(resetPasswordRequest(password = "xxx"))250 .andExpect { status { isBadRequest() } }251 }252 }253 @Test254 @WithMockJardUser(UserAuthority.MANAGE_USERS)255 fun `delete user`() {256 val user = user(username = "Anonymous")257 every { userFacade.resolveUser(user.username) } returns user.toDto()258 every { userFacade.deleteUser(ofType(UserDto::class)) } just Runs259 mockMvc.delete("${Mappings.API_ROOT_USERS}/${user.username}") { setUp() }.andExpect { status { isOk() } }260 }261}...

Full Screen

Full Screen

BatchMigrationChangeTest.kt

Source:BatchMigrationChangeTest.kt Github

copy

Full Screen

1package liquibase.ext.changes2import io.kotest.core.spec.style.ShouldSpec3import io.kotest.property.checkAll4import io.kotest.property.exhaustive.exhaustive5import io.kotest.property.forAll6import io.mockk.every7import io.mockk.mockk8import io.mockk.spyk9import io.mockk.verify10import liquibase.database.core.OracleDatabase11import liquibase.database.jvm.JdbcConnection12import liquibase.exception.CustomChangeException13import liquibase.ext.generators.ChangeGenerators.otherDatabases14import org.junit.jupiter.api.Assertions.assertThrows15import org.junit.jupiter.api.assertDoesNotThrow16import java.sql.DatabaseMetaData17import java.sql.PreparedStatement18import java.sql.RowIdLifetime19import java.sql.SQLException20import java.sql.Statement21import liquibase.ext.generators.BatchMigrationGenerator as gen22class BatchMigrationChangeTest : ShouldSpec({23 context("Validation") {24 should("result in errors when not all arguments meet the constraints") {25 forAll(gen.invalidMigrationGenerator) { c ->26 val validated = c.validate(OracleDatabase())27 val errors = validated.errorMessages28 errors.forEach { println(it) }29 validated.hasErrors()30 }31 }32 should("pass when all arguments do not meet the constraints but Oracle is not used") {33 forAll(otherDatabases, gen.invalidMigrationGenerator) { db, c ->34 !c.validate(db).hasErrors()35 }36 }37 should("pass when all arguments meet the constraints") {38 forAll(gen.validMigrationWithSleepsGenerator) { c ->39 !c.validate(OracleDatabase()).hasErrors()40 }41 }42 should("pass when all arguments meet the constraints but Oracle is not used") {43 forAll(otherDatabases, gen.validMigrationWithSleepsGenerator) { db, c ->44 !c.validate(db).hasErrors()45 }46 }47 }48 context("Execution") {49 should("do nothing on non-Oracle databases") {50 checkAll(otherDatabases, gen.validMigrationGenerator) { db, c ->51 val conn = mockk<JdbcConnection>()52 val spyDb = spyk(db)53 every { spyDb.connection } returns conn54 c.execute(spyDb)55 verify(exactly = 0) { conn.prepareStatement(any(), any<Int>()) }56 verify(exactly = 0) { conn.prepareStatement(any()) }57 verify(exactly = 0) { conn.commit() }58 }59 }60 should("stop when rowIds are mutable") {61 checkAll(gen.rowIdLifeTimeInvalidGenerator, gen.validMigrationGenerator) { lt, c ->62 val conn = mockk<JdbcConnection>()63 val md = mockk<DatabaseMetaData>()64 val db = mockk<OracleDatabase>()65 every { db.connection } returns conn66 every { conn.isClosed } returns false67 every { md.rowIdLifetime } returns lt68 every { conn.metaData } returns md69 assertThrows(CustomChangeException::class.java) {70 c.execute(db)71 }72 }73 }74 should("continue when rowIds are immutable") {75 checkAll(gen.validMigrationGenerator) { c ->76 val conn = mockk<JdbcConnection>(relaxed = true)77 val md = mockk<DatabaseMetaData>()78 val db = mockk<OracleDatabase>()79 every { db.connection } returns conn80 every { conn.isClosed } returns false81 every { md.rowIdLifetime } returns RowIdLifetime.ROWID_VALID_FOREVER82 every { conn.metaData } returns md83 assertDoesNotThrow {84 c.execute(db)85 }86 }87 }88 should("close statements as many times as commits when execution goes fine") {89 checkAll(gen.validMigrationGenerator) { c ->90 val conn = mockk<JdbcConnection>(relaxed = true)91 val md = mockk<DatabaseMetaData>()92 val db = mockk<OracleDatabase>()93 val stmt = mockk<PreparedStatement>()94 val expectedUpdates = listOf(c.chunkSize!!, c.chunkSize!!, 0L)95 every { db.connection } returns conn96 every { conn.isClosed } returns false97 every { md.rowIdLifetime } returns RowIdLifetime.ROWID_VALID_FOREVER98 every { conn.metaData } returns md99 every { stmt.close() } returns Unit100 every { stmt.executeLargeUpdate() } returnsMany expectedUpdates101 every { conn.prepareStatement(any(), Statement.RETURN_GENERATED_KEYS) } returns stmt102 c.execute(db)103 verify(exactly = expectedUpdates.size) { conn.commit() }104 verify(exactly = expectedUpdates.size) { stmt.close() }105 }106 }107 should("close statements as many times as they are prepared when exceptions may occur") {108 checkAll(gen.validMigrationGenerator) { c ->109 val conn = mockk<JdbcConnection>(relaxed = true)110 val md = mockk<DatabaseMetaData>()111 val db = mockk<OracleDatabase>()112 val stmt = mockk<PreparedStatement>()113 val expectedUpdates = listOf(c.chunkSize!!, c.chunkSize!!, 0L)114 every { db.connection } returns conn115 every { conn.isClosed } returns false116 every { md.rowIdLifetime } returns RowIdLifetime.ROWID_VALID_FOREVER117 every { conn.metaData } returns md118 every { stmt.close() } returns Unit119 every { stmt.executeLargeUpdate() } returnsMany expectedUpdates120 every { conn.commit() } returns Unit andThen Unit andThenThrows SQLException("Anything")121 every { conn.prepareStatement(any(), Statement.RETURN_GENERATED_KEYS) } returns stmt122 try {123 c.execute(db)124 } catch (e: CustomChangeException) {125 }126 verify(exactly = expectedUpdates.size) { conn.commit() }127 verify(exactly = expectedUpdates.size) { stmt.close() }128 }129 }130 should("stop when the connection is not set") {131 val db = mockk<OracleDatabase>()132 every { db.connection } returns null133 assertThrows(CustomChangeException::class.java) {134 BatchMigrationChange().execute(db)135 }136 }137 should("stop when the connection is closed") {138 val db = mockk<OracleDatabase>()139 val conn = mockk<JdbcConnection>()140 every { conn.isClosed } returns true141 every { db.connection } returns null142 assertThrows(CustomChangeException::class.java) {143 BatchMigrationChange().execute(db)144 }145 }146 should("update in the expected chunks") {147 checkAll(148 listOf(0L, 1L, 2L, 50000L, 912345L).exhaustive(),149 gen.validMigrationGenerator150 ) { allRowCount, migration ->151 val conn = mockk<JdbcConnection>()152 val md = mockk<DatabaseMetaData>()153 val db = mockk<OracleDatabase>()154 val stmt = mockk<PreparedStatement>()155 // We split the batch in chunks where we need one extra update to make sure we migrated all156 val requiredUpdates = (allRowCount / migration.chunkSize!! + 1).toInt()157 // Last result should return 0158 var updateResults = listOf(0L)159 repeat(requiredUpdates - 1) {160 updateResults = listOf(migration.chunkSize!!) + updateResults161 }162 every { db.connection } returns conn163 every { conn.isClosed } returns false164 every { md.rowIdLifetime } returns RowIdLifetime.ROWID_VALID_FOREVER165 every { conn.metaData } returns md166 every { stmt.executeLargeUpdate() } returnsMany updateResults167 every { conn.prepareStatement(any(), Statement.RETURN_GENERATED_KEYS) } returns stmt168 every { conn.commit() } returns Unit169 every { stmt.close() } returns Unit170 migration.execute(db)171 verify(exactly = requiredUpdates) { conn.prepareStatement(any(), Statement.RETURN_GENERATED_KEYS) }172 verify(exactly = requiredUpdates) { stmt.executeLargeUpdate() }173 verify(exactly = requiredUpdates) { conn.commit() }174 }175 }176 should("only construct expected update statements") {177 checkAll(gen.validMigrationGenerator) { migration ->178 val conn = mockk<JdbcConnection>()179 val md = mockk<DatabaseMetaData>()180 val db = mockk<OracleDatabase>()181 val stmt = mockk<PreparedStatement>()182 val n = migration.chunkSize!!183 val slot = mutableListOf<String>()184 // Should always be 5 updates185 val tail = kotlin.math.max(n / 2L, 1L)186 every { db.connection } returns conn187 every { conn.isClosed } returns false188 every { md.rowIdLifetime } returns RowIdLifetime.ROWID_VALID_FOREVER189 every { conn.metaData } returns md190 every { stmt.executeLargeUpdate() } returnsMany listOf(n, n, n, tail, 0L)191 every { conn.prepareStatement(capture(slot), Statement.RETURN_GENERATED_KEYS) } returns stmt192 every { conn.commit() } returns Unit193 every { stmt.close() } returns Unit194 migration.execute(db)195 verify(exactly = 5) { conn.prepareStatement(any(), Statement.RETURN_GENERATED_KEYS) }196 }197 }198 }199})...

Full Screen

Full Screen

ExposedRecipeRepositoryTest.kt

Source:ExposedRecipeRepositoryTest.kt Github

copy

Full Screen

1package adapters.database2import adapters.database.DatabaseTestHelper.createRecipeInDatabase3import adapters.database.DatabaseTestHelper.createRecipeTypeInDatabase4import adapters.database.schema.Recipes5import io.kotest.assertions.throwables.shouldThrow6import io.kotest.core.spec.style.DescribeSpec7import io.kotest.data.row8import io.kotest.matchers.ints.shouldNotBeZero9import io.kotest.matchers.nulls.shouldNotBeNull10import io.kotest.matchers.shouldBe11import io.kotest.property.Arb12import io.kotest.property.arbitrary.next13import io.kotest.property.arbitrary.stringPattern14import model.Recipe15import model.RecipeType16import org.jetbrains.exposed.sql.deleteAll17import org.jetbrains.exposed.sql.transactions.transaction18internal class ExposedRecipeRepositoryTest : DescribeSpec({19 val stringSource = Arb.stringPattern("[0-3]([a-c]|[e-g]{1,2})")20 val database = DatabaseTestHelper.database21 var firstRecipeType = RecipeType(name = stringSource.next())22 beforeSpec {23 transaction(database) {24 firstRecipeType = createRecipeTypeInDatabase(firstRecipeType)25 }26 }27 afterTest {28 transaction(database) {29 Recipes.deleteAll()30 }31 }32 describe("Recipe repository") {33 val basicRecipe = Recipe(34 recipeTypeId = firstRecipeType.id,35 recipeTypeName = firstRecipeType.name,36 name = stringSource.next(),37 description = stringSource.next(),38 ingredients = stringSource.next(),39 preparingSteps = stringSource.next()40 )41 it("finds a recipe") {42 val expectedRecipe = createRecipeInDatabase(basicRecipe)43 val repo = ExposedRecipeRepository(database = database)44 val recipe = repo.find(id = expectedRecipe.id)45 recipe.shouldNotBeNull()46 recipe.shouldBe(expectedRecipe)47 }48 describe("Get all") {49 it("gets all the recipe types") {50 val createdRecipes = listOf(51 createRecipeInDatabase(basicRecipe),52 createRecipeInDatabase(basicRecipe.copy(name = stringSource.next()))53 )54 val repo = ExposedRecipeRepository(database = database)55 val recipes = repo.getAll()56 recipes.shouldBe(createdRecipes)57 }58 }59 it("gets the recipe count") {60 val createdRecipes = listOf(61 createRecipeInDatabase(basicRecipe),62 createRecipeInDatabase(basicRecipe),63 createRecipeInDatabase(basicRecipe)64 )65 val repo = ExposedRecipeRepository(database = database)66 val count = repo.count()67 count.shouldBe(createdRecipes.size)68 }69 describe("Search") {70 fun createRecipes(numberOfRecipes: Int = 20) = List(numberOfRecipes) {71 createRecipeInDatabase(basicRecipe)72 }73 it("searches for a specific recipe name") {74 createRecipes(numberOfRecipes = 10)75 val pickedRecipe =76 createRecipeInDatabase(basicRecipe.copy(name = "Duckling"))77 val repo = ExposedRecipeRepository(database = database)78 val result = repo.search(79 name = pickedRecipe.name,80 description = null,81 recipeTypeId = null,82 pageNumber = 1,83 itemsPerPage = 1884 )85 result.count.shouldBe(1)86 result.numberOfPages.shouldBe(1)87 result.results.first().shouldBe(pickedRecipe)88 }89 it("searches for a specific recipe description") {90 createRecipes(numberOfRecipes = 10)91 val pickedRecipe =92 createRecipeInDatabase(93 basicRecipe.copy(94 name = "Stone soup",95 description = stringSource.next()96 )97 )98 val repo = ExposedRecipeRepository(database = database)99 val result = repo.search(100 description = pickedRecipe.description,101 name = null,102 recipeTypeId = null,103 pageNumber = 1,104 itemsPerPage = 18105 )106 result.count.shouldBe(1)107 result.numberOfPages.shouldBe(1)108 result.results.first().shouldBe(pickedRecipe)109 }110 arrayOf(111 row("", null, "when the name is empty"),112 row(null, "", "when the description is empty")113 ).forEach { (name, description, testDescription) ->114 it("returns all the values $testDescription") {115 val createdRecipes = createRecipes(5)116 val repo = ExposedRecipeRepository(database = database)117 val searchResult = repo.search(118 pageNumber = 1,119 itemsPerPage = 10,120 name = name,121 description = description,122 recipeTypeId = null123 )124 searchResult.count.shouldBe(5)125 searchResult.results.shouldBe(createdRecipes)126 }127 }128 arrayOf(129 row(1, 5),130 row(3, 20),131 row(10, 5),132 row(2, 50)133 ).forEach { (pageNumber, itemsPerPage) ->134 it("returns the paginated results for page $pageNumber and $itemsPerPage items per page") {135 val createdRecipes = createRecipes(100)136 val repo = ExposedRecipeRepository(database = database)137 val searchResult = repo.search(138 pageNumber = pageNumber,139 itemsPerPage = itemsPerPage,140 name = null,141 description = null,142 recipeTypeId = null143 )144 with(searchResult) {145 count.shouldBe(100)146 numberOfPages.shouldBe(100 / itemsPerPage)147 val offset = (pageNumber - 1) * itemsPerPage148 createdRecipes.subList(offset, offset + itemsPerPage).shouldBe(results)149 }150 }151 }152 }153 describe("Create") {154 it("creates a new recipe") {155 val repo = ExposedRecipeRepository(database = database)156 val createdRecipeId = repo.create(recipe = basicRecipe)157 createdRecipeId.shouldNotBeZero()158 }159 }160 describe("Update") {161 it("updates a recipe on the database") {162 val createdRecipe = createRecipeInDatabase(basicRecipe)163 val repo = ExposedRecipeRepository(database = database)164 val recipeToBeUpdated = createdRecipe.copy(id = createdRecipe.id, name = "I want to be renamed")165 repo.update(recipeToBeUpdated)166 }167 }168 it("deletes a recipe type") {169 val createdRecipe = createRecipeInDatabase(basicRecipe)170 val repo = ExposedRecipeRepository(database = database)171 val deleted = repo.delete(createdRecipe.id)172 deleted.shouldBe(true)173 }174 describe("Recipe table constraints") {175 arrayOf(176 row(177 basicRecipe.copy(name = "a".repeat(129)),178 "name exceeds the size limit"179 ),180 row(181 basicRecipe.copy(description = "b".repeat(257)),182 "description exceeds the size limit"183 ),184 row(185 basicRecipe.copy(ingredients = "c".repeat(2049)),186 "ingredients exceeds the size limit"187 ),188 row(189 basicRecipe.copy(preparingSteps = "d".repeat(4097)),190 "preparingSteps exceeds the size limit"191 )192 ).forEach { (recipe: Recipe, description: String) ->193 it("throws when $description") {194 val repo = ExposedRecipeRepository(database = database)195 val act = { repo.create(recipe = recipe) }196 shouldThrow<IllegalArgumentException>(act)197 }198 }199 }200 }201})...

Full Screen

Full Screen

EntitySerializerTest.kt

Source:EntitySerializerTest.kt Github

copy

Full Screen

1/*Copyright 2021 Mecharex Kft.2This file is part of the logikaldb library.3The logikaldb library is free software: you can redistribute it and/or modify4it under the terms of the GNU Lesser General Public License as published by5the Free Software Foundation, either version 3 of the License, or6(at your option) any later version.7The logikaldb library is distributed in the hope that it will be useful,8but WITHOUT ANY WARRANTY; without even the implied warranty of9MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the10GNU Lesser General Public License for more details.11You should have received a copy of the GNU Lesser General Public License12along with the logikaldb library. If not, see <http://www.gnu.org/licenses/>.*/13package com.logikaldb.serializer14import com.logikaldb.entity.AndEntity15import com.logikaldb.entity.ConstraintEntity16import com.logikaldb.entity.ConstraintFunEntity17import com.logikaldb.entity.EqualEntity18import com.logikaldb.entity.FieldEntity19import com.logikaldb.entity.OrEntity20import com.logikaldb.entity.ValueEntity21import com.logikaldb.logikal.Logikal.equal22import io.kotest.core.spec.style.StringSpec23import io.kotest.property.Arb24import io.kotest.property.RandomSource25import io.kotest.property.Sample26import io.kotest.property.arbitrary.arb27import io.kotest.property.arbitrary.double28import io.kotest.property.arbitrary.int29import io.kotest.property.arbitrary.list30import io.kotest.property.arbitrary.map31import io.kotest.property.arbitrary.string32import io.kotest.property.forAll33class EntitySerializerTest : StringSpec({34 val underTest = EntitySerializer()35 fun createEqualEntity(randomPair: Pair<Sample<String>, Sample<Any>>): EqualEntity {36 return EqualEntity(FieldEntity(randomPair.first.value, String::class.java), ValueEntity(randomPair.second.value))37 }38 fun anyRandomValues(randomSource: RandomSource): Sequence<Sample<Any>> {39 val randomStrings = Arb.string().values(randomSource)40 val randomIntegers = Arb.int().values(randomSource)41 val randomDoubles = Arb.double().values(randomSource)42 return randomStrings + randomIntegers + randomDoubles43 }44 "A serialized and deserialized EqualEntity must be the same as the original entity" {45 val equalConstraintEntityArb = arb { randomSource ->46 val randomFields = Arb.string().values(randomSource)47 val randomValues = anyRandomValues(randomSource)48 randomFields.zip(randomValues)49 .map(::createEqualEntity)50 .map { ConstraintEntity(it) }51 }52 forAll(equalConstraintEntityArb) { equalConstraintEntity ->53 underTest.deserialize(underTest.serialize(equalConstraintEntity)) == equalConstraintEntity54 }55 }56 "A serialized and deserialized ConstraintEntity is not the same when the constraint fun is defined" {57 val constraintConstraintEntityArb = arb { randomSource ->58 val randomConstraints = Arb.string().values(randomSource)59 val randomParameters = Arb.list(Arb.string())60 .map { parameterNames -> parameterNames.map { FieldEntity(it, String::class.java) } }61 .values(randomSource)62 randomConstraints.zip(randomParameters)63 .map { ConstraintFunEntity(equal(1, 1)) }64 .map { ConstraintEntity(it) }65 }66 forAll(constraintConstraintEntityArb) { constraintConstraintEntity ->67 val convertedConstraintConstraintEntity = underTest.deserialize(underTest.serialize(constraintConstraintEntity))68 convertedConstraintConstraintEntity != constraintConstraintEntity69 }70 }71 "A serialized and deserialized AndEntity must be the same as the original entity" {72 val equalEntityArb = arb { randomSource ->73 val randomFields = Arb.string().values(randomSource)74 val randomValues = anyRandomValues(randomSource)75 randomFields.zip(randomValues)76 .map(::createEqualEntity)77 }78 val andConstraintEntityArb = arb { randomSource ->79 Arb.list(equalEntityArb, IntRange(0, 100)).values(randomSource)80 .map { AndEntity(it.value) }81 .map { ConstraintEntity(it) }82 }83 forAll(andConstraintEntityArb) { andConstraintEntity ->84 underTest.deserialize(underTest.serialize(andConstraintEntity)) == andConstraintEntity85 }86 }87 "A serialized and deserialized OrEntity must be the same as the original entity" {88 val equalEntityArb = arb { randomSource ->89 val randomFields = Arb.string().values(randomSource)90 val randomValues = anyRandomValues(randomSource)91 randomFields.zip(randomValues)92 .map(::createEqualEntity)93 }94 val orConstraintEntityArb = arb { randomSource ->95 Arb.list(equalEntityArb, IntRange(0, 100)).values(randomSource)96 .map { OrEntity(it.value) }97 .map { ConstraintEntity(it) }98 }99 forAll(orConstraintEntityArb) { orConstraintEntity ->100 underTest.deserialize(underTest.serialize(orConstraintEntity)) == orConstraintEntity101 }102 }103})...

Full Screen

Full Screen

ComposedObjectDataTypeSpec.kt

Source:ComposedObjectDataTypeSpec.kt Github

copy

Full Screen

1/*2 * Copyright 2020 https://github.com/openapi-processor/openapi-processor-core3 * PDX-License-Identifier: Apache-2.04 */5package io.openapiprocessor.core.model.datatypes6import io.kotest.core.spec.style.StringSpec7import io.kotest.matchers.collections.shouldContainAll8import io.kotest.matchers.shouldBe9import io.openapiprocessor.core.support.datatypes.ObjectDataType10import io.openapiprocessor.core.support.datatypes.propertyDataType11import io.openapiprocessor.core.support.datatypes.propertyDataTypeString12class ComposedObjectDataTypeSpec : StringSpec({13 "loop properties of allOf objects as if it was a single object" {14 val composed = AllOfObjectDataType(DataTypeName("Foo"), "pkg", listOf(15 ObjectDataType("Foo", "pkg", linkedMapOf(16 Pair("foo", propertyDataTypeString()),17 Pair("foobar", propertyDataTypeString()))18 ),19 ObjectDataType("Bar", "pkg", linkedMapOf(20 Pair("bar", propertyDataTypeString()),21 Pair("barfoo", propertyDataTypeString())22 ))23 ))24 composed.properties.keys shouldBe linkedSetOf("foo", "foobar", "bar", "barfoo")25 }26 "allOf object has id name and type name" {27 val composed = AllOfObjectDataType(DataTypeName("Foo", "FooX"), "pkg", listOf())28 composed.getName() shouldBe "Foo"29 composed.getTypeName() shouldBe "FooX"30 }31 "allOf object has creates import with type name" {32 val composed = AllOfObjectDataType(DataTypeName("Foo", "FooX"), "pkg", listOf())33 composed.getImports() shouldBe setOf("pkg.FooX")34 }35 // https://github.com/openapi-processor/openapi-processor-spring/issues/12836 "allOf creates imports for all items" {37 val composed = AllOfObjectDataType(DataTypeName("Foo"), "pkg", listOf(38 ObjectDataType("Foo", "pkg", linkedMapOf(39 "foo" to propertyDataType(OffsetDateTimeDataType())40 )),41 ObjectDataType("Bar", "pkg", linkedMapOf(42 "bar" to propertyDataType(ObjectDataType("BarBar", "pkg", linkedMapOf(43 "barbar" to propertyDataType(OffsetDateTimeDataType())44 )))45 ))46 ))47 composed.getImports() shouldBe setOf("pkg.Foo")48 composed.referencedImports shouldBe setOf("java.time.OffsetDateTime", "pkg.BarBar")49 }50 "allOf creates does not leak import for type-less item" {51 val composed = AllOfObjectDataType(DataTypeName("Foo"), "pkg", listOf(52 ObjectDataType("Bar", "pkg", linkedMapOf(53 "bar" to propertyDataTypeString()54 )),55 NoDataType(DataTypeName("Leak"), "pkg")56 ))57 composed.getImports() shouldBe setOf("pkg.Foo")58 composed.referencedImports shouldBe setOf("java.lang.String")59 }60 "allOf handles 'required' constraint of all items" {61 val composed = AllOfObjectDataType(DataTypeName("AllOf"), "pkg", listOf(62 ObjectDataType("Foo", "pkg", linkedMapOf(63 "foo" to propertyDataTypeString(),64 "fux" to propertyDataTypeString()65 ), constraints = DataTypeConstraints(required = listOf("foo", "fux"))),66 ObjectDataType(67 "Bar", "pkg", linkedMapOf(68 "bar" to propertyDataTypeString(),69 "bux" to propertyDataTypeString()70 ), constraints = DataTypeConstraints(required = listOf("bar", "bux")))71 ))72 composed.constraints!!.required shouldContainAll listOf("foo", "fux", "bar", "bux")73 }74 "allOf without 'required' has null constraints" {75 val composed = AllOfObjectDataType(DataTypeName("AllOf"), "pkg", listOf(76 ObjectDataType("Foo", "pkg", linkedMapOf(77 "foo" to propertyDataTypeString(),78 "fux" to propertyDataTypeString()79 ), constraints = DataTypeConstraints()),80 ObjectDataType(81 "Bar", "pkg", linkedMapOf(82 "bar" to propertyDataTypeString(),83 "bux" to propertyDataTypeString()84 ), constraints = null)85 ))86 composed.constraints shouldBe null87 }88})...

Full Screen

Full Screen

ReaderTest.kt

Source:ReaderTest.kt Github

copy

Full Screen

1import io.kotest.matchers.booleans.shouldBeFalse2import io.kotest.matchers.booleans.shouldBeTrue3import io.kotest.matchers.shouldBe4import net.jqwik.api.*5import net.jqwik.api.constraints.LowerChars6import net.jqwik.api.constraints.NotEmpty7import net.jqwik.api.constraints.UpperChars8import net.jqwik.kotlin.api.any9import org.junit.jupiter.api.Test10class ReaderTest {11 val inc = { n: Int -> n + 1 }12 val mult2 = { n: Int -> n * 2 }13 val mult2AndThenInc = mult2.map(inc)14 @Property15 fun `f map g is the pipe composition, that is the same as x to g(f(x))`(@ForAll n: Int) {16 mult2AndThenInc(n) shouldBe inc(mult2(n))17 }18 val isValidCommand = { c: Char -> c in "fblr" }19 val isInvalidCommand = isValidCommand.map(Boolean::not)20 val any = { p: (Char) -> Boolean -> { t: String -> t.any(p) } }21 val and = Boolean::and.curried()22 val containsBothValidAndInvalidCommands1 = any(isValidCommand).map(and).ap(any(isInvalidCommand))23 val containsBothValidAndInvalidCommands2 = any(isValidCommand).zip(any(isInvalidCommand), Boolean::and)24 @Property25 fun `f map(g) ap(h) is the same as x to g(f(x))(h(x)) as f ap g is basically x to g(x)(f(x))`(@ForAll("validAndInvalidCommands") xs: String) {26 containsBothValidAndInvalidCommands1(xs) shouldBe (xs.any(isValidCommand) && xs.any(isInvalidCommand))27 }28 @Property29 fun `map ap chain behaves like zip`(@ForAll("validAndInvalidCommands") xs: String) {30 // Statistics.collect(containsBothValidAndInvalidCommands1(xs))31 containsBothValidAndInvalidCommands1(xs) shouldBe containsBothValidAndInvalidCommands2(xs)32 }33 @Suppress("unused")34 @Provide35 fun validAndInvalidCommands(): Arbitrary<String> {36 return String.any().withChars("flbrax_ghjkld")37 }38 val isUnique = List<Any>::distinct.flatMap(List<Any>::equals.curried())39 @Property40 fun `f flatMap(g) is the same as x to g(f(x), x)`(@ForAll @NotEmpty xs: List<Any>) {41 // Statistics.collect(isUnique(xs))42 isUnique(xs) shouldBe (xs.distinct() == xs)43 }44 val isUniqueMapAp = List<Any>::distinct.map(List<Any>::equals.curried()).ap(::identity)45 @Property46 fun `flat mapping f and map f ap identity produce the same results`(@ForAll @NotEmpty xs: List<Any>) {47 isUnique(xs) shouldBe isUniqueMapAp(xs)48 }49 val isUniqueZip = List<Any>::distinct.zip(::identity, List<Any>::equals)50 @Property51 fun `flat mapping f and f zip with identity produce the same results`(@ForAll @NotEmpty xs: List<Any>) {52 isUnique(xs) shouldBe isUniqueZip(xs)53 }54 val eqStr = { xs: String -> { ys: String -> xs == ys } }55 val toLower = { xs: String -> xs.lowercase() }56 val isPalindrome = toLower.map(String::reversed.flatMap(eqStr))57 @Property58 fun `is palindrome works`(@ForAll @NotEmpty @UpperChars @LowerChars xs: String) {59 // Statistics.collect(xs.all { it.isLowerCase() }, xs.all { it.isUpperCase()} )60 val comparison = xs.lowercase().let { it.reversed() == it }61 isPalindrome(xs) shouldBe comparison62 }63 @Test64 fun `is palindrome works for examples`() {65 isPalindrome("Anna").shouldBeTrue()66 isPalindrome("Hello").shouldBeFalse()67 }68}...

Full Screen

Full Screen

Constraints.kt

Source:Constraints.kt Github

copy

Full Screen

1package io.kotest.property2import kotlin.time.Duration3import kotlin.time.TimeSource4/**5 * Controls iterations of a property test.6 */7fun interface Constraints {8 fun evaluate(): Boolean9 companion object {10 /**11 * Returns a [Constraints] that executes the property test for a fixed number of iterations.12 */13 fun iterations(k: Int) = object : Constraints {14 var count = 015 override fun evaluate(): Boolean {16 val result = count < k17 count++18 return result19 }20 }21 /**22 * Returns a [Constraints] that executes the property test for a certain duration.23 */24 fun duration(duration: Duration) = object : Constraints {25 val mark = TimeSource.Monotonic.markNow().plus(duration)26 override fun evaluate(): Boolean {27 return mark.hasNotPassedNow()28 }29 }30 }31}32fun Constraints.and(other: Constraints) = Constraints { this@and.evaluate() && other.evaluate() }33fun Constraints.or(other: Constraints) = Constraints { this@or.evaluate() || other.evaluate() }...

Full Screen

Full Screen

Constraints.and

Using AI Code Generation

copy

Full Screen

1val constraints = Constraints.and(Constraints.max(10), Constraints.min(5))2val constraints = Constraints.or(Constraints.max(10), Constraints.min(5))3val constraints = Constraints.lessThan(10)4val constraints = Constraints.lessThanOrEqual(10)5val constraints = Constraints.greaterThan(10)6val constraints = Constraints.greaterThanOrEqual(10)7val constraints = Constraints.max(10)8val constraints = Constraints.min(10)9val constraints = Constraints.none()10val constraints = Constraints.equal(10)11val constraints = Constraints.between(5, 10)12val constraints = Constraints.betweenInclusive(5, 10)13val constraints = Constraints.betweenExclusive(5, 10)14val constraints = Constraints.betweenInclusiveExclusive(5, 10)15val constraints = Constraints.betweenExclusiveInclusive(5, 10)16val constraints = Constraints.betweenInclusiveInclusive(5, 10)17val constraints = Constraints.betweenExclusiveExclusive(5, 10)

Full Screen

Full Screen

Constraints.and

Using AI Code Generation

copy

Full Screen

1val constraints = Constraints.and(Constraints.lessThan(100), Constraints.greaterThan(50))2constraints.isSatisfiedBy(10) shouldBe false3constraints.isSatisfiedBy(90) shouldBe true4constraints.isSatisfiedBy(150) shouldBe false5constraints.isSatisfiedBy(70) shouldBe true6val constraints = Constraints.or(Constraints.lessThan(100), Constraints.greaterThan(100))7constraints.isSatisfiedBy(10) shouldBe true8constraints.isSatisfiedBy(90) shouldBe true9constraints.isSatisfiedBy(150) shouldBe true10constraints.isSatisfiedBy(70) shouldBe true11constraints.isSatisfiedBy(200) shouldBe false12val constraints = Constraints.not(Constraints.lessThan(100))13constraints.isSatisfiedBy(10) shouldBe false14constraints.isSatisfiedBy(90) shouldBe false15constraints.isSatisfiedBy(150) shouldBe true16constraints.isSatisfiedBy(70) shouldBe false17constraints.isSatisfiedBy(200) shouldBe true18val constraints = Constraints.all(Constraints.lessThan(100), Constraints.greaterThan(50))19constraints.isSatisfiedBy(10) shouldBe false20constraints.isSatisfiedBy(90) shouldBe true21constraints.isSatisfiedBy(150) shouldBe false22constraints.isSatisfiedBy(70) shouldBe true23constraints.isSatisfiedBy(200) shouldBe false24constraints.isSatisfiedBy(40) shouldBe false25constraints.isSatisfiedBy(60) shouldBe true26constraints.isSatisfiedBy(80) shouldBe true27constraints.isSatisfiedBy(100) shouldBe false28constraints.isSatisfiedBy(120) shouldBe false29constraints.isSatisfiedBy(140) shouldBe false30val constraints = Constraints.any(Constraints.lessThan(100), Constraints.greaterThan(100))31constraints.isSatisfiedBy(10) shouldBe true32constraints.isSatisfiedBy(90) shouldBe true33constraints.isSatisfiedBy(150) shouldBe true34constraints.isSatisfiedBy(70) shouldBe true35constraints.isSatisfiedBy(200) shouldBe false36constraints.isSatisfiedBy(40) shouldBe true

Full Screen

Full Screen

Constraints.and

Using AI Code Generation

copy

Full Screen

1val constraint = Constraints.and(Constraints.positive(), Constraints.lessThan(10))2val prop = forAll(constraint) { n: Int ->3}4prop.check()5val constraint = Constraints.or(Constraints.positive(), Constraints.greaterThan(10))6val prop = forAll(constraint) { n: Int ->7}8prop.check()9val constraint = Constraints.not(Constraints.positive())10val prop = forAll(constraint) { n: Int ->11}12prop.check()13val constraint = Constraints.none()14val prop = forAll(constraint) { n: Int ->15}16prop.check()17val constraint = Constraints.all()18val prop = forAll(constraint) { n: Int ->19}20prop.check()21val constraint = Constraints.none()22val prop = forAll(constraint) { n: Int ->23}24prop.check()25val constraint = Constraints.all()26val prop = forAll(constraint) { n: Int ->27}28prop.check()29val constraint = Constraints.all()30val prop = forAll(constraint) { n: Int ->31}32prop.check()33val constraint = Constraints.all()34val prop = forAll(constraint) { n: Int ->35}36prop.check()37val constraint = Constraints.all()38val prop = forAll(constraint) { n: Int ->39}40prop.check()

Full Screen

Full Screen

Constraints.and

Using AI Code Generation

copy

Full Screen

1val constraints = Constraints.and(2Constraints.lessThan(100),3Constraints.greaterThan(50)4val result = Gen.int().constraints(constraints).random()5assert(result in 51..99)6val constraints = Constraints.or(7Constraints.lessThan(10),8Constraints.greaterThan(50)9val result = Gen.int().constraints(constraints).random()10assert(result in 0..9 || result in 51..Int.MAX_VALUE)11val constraints = Constraints.or(12Constraints.lessThan(10),13Constraints.greaterThan(50)14val result = Gen.int().constraints(constraints).random()15assert(result in 0..9 || result in 51..Int.MAX_VALUE)16val constraints = Constraints.and(17Constraints.lessThan(100),18Constraints.greaterThan(50)19val result = Gen.int().constraints(constraints).random()20assert(result in 51..99)21val constraints = Constraints.or(22Constraints.lessThan(10),23Constraints.greaterThan(50)24val result = Gen.int().constraints(constraints).random()25assert(result in 0..9 || result in 51..Int.MAX_VALUE)26val constraints = Constraints.or(27Constraints.lessThan(10),28Constraints.greaterThan(50)29val result = Gen.int().constraints(constraints).random()30assert(result in 0..9 || result in 51..Int.MAX_VALUE)31val constraints = Constraints.and(32Constraints.lessThan(100),33Constraints.greaterThan(50)34val result = Gen.int().constraints(constraints).random()35assert(result in 51..99)36val constraints = Constraints.or(37Constraints.lessThan(10),38Constraints.greaterThan(50)39val result = Gen.int().constraints(constraints).random

Full Screen

Full Screen

Constraints.and

Using AI Code Generation

copy

Full Screen

1val constraints = Constraints.and(2Constraints.min(1),3Constraints.max(10),4Constraints.positive()5checkAll(constraints) { num ->6num.shouldBeGreaterThanOrEqual(1)7num.shouldBeLessThanOrEqual(10)8num.shouldBePositive()9}10}11}

Full Screen

Full Screen

Constraints.and

Using AI Code Generation

copy

Full Screen

1fun `property test with multiple constraints`(x: Int, y: Int) {2Constraints.and(3x should beLessThan(y),4y should beLessThan(x)5}6fun `property test with multiple constraints`(x: Int, y: Int) {7Constraints.or(8x should beLessThan(y),9y should beLessThan(x)10}11fun `property test with multiple constraints`(x: Int, y: Int) {12Constraints.all(13x should beLessThan(y),14y should beLessThan(x)15}16fun `property test with multiple constraints`(x: Int, y: Int) {17Constraints.any(18x should beLessThan(y),19y should beLessThan(x)20}21fun `property test with multiple constraints`(x: Int, y: Int) {22Constraints.none(23x should beLessThan(y),24y should beLessThan(x)25}26fun `property test with multiple constraints`(x: Int, y: Int) {27Constraints.exactly(2,28x should beLessThan(y),29y should beLessThan(x)30}31fun `property test with multiple constraints`(x: Int, y: Int) {32Constraints.atLeast(2,33x should beLessThan(y),34y should beLessThan(x)35}36fun `property test with multiple constraints`(x: Int, y: Int) {37Constraints.atMost(2,38x should beLessThan(y),39y should beLessThan(x)40}

Full Screen

Full Screen

Automation Testing Tutorials

Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.

LambdaTest Learning Hubs:

YouTube

You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.

Run Kotest automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful