Best Kotest code snippet using io.kotest.matchers.longs.long.Long.shouldBeZero
LaborServiceTest.kt
Source:LaborServiceTest.kt  
1/*2 * Copyright (C) 2016 - present Juergen Zimmermann, Hochschule Karlsruhe3 *4 * This program is free software: you can redistribute it and/or modify5 * it under the terms of the GNU General Public License as published by6 * the Free Software Foundation, either version 3 of the License, or7 * (at your option) any later version.8 *9 * This program is distributed in the hope that it will be useful,10 * but WITHOUT ANY WARRANTY; without even the implied warranty of11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the12 * GNU General Public License for more details.13 *14 * You should have received a copy of the GNU General Public License15 * along with this program.  If not, see <https://www.gnu.org/licenses/>.16 */17@file:Suppress("PackageDirectoryMismatch")18package com.acme.labor.service19import com.acme.labor.config.security.CustomUser20import com.acme.labor.config.security.CustomUserDetailsService21import com.acme.labor.config.security.Rolle22import com.acme.labor.entity.Adresse23import com.acme.labor.entity.Gesundheitsamt24import com.acme.labor.entity.Labor25import com.acme.labor.entity.TestTyp26import com.acme.labor.mail.Mailer27import com.acme.labor.mail.SendResult28import com.mongodb.client.result.DeleteResult29import io.kotest.assertions.asClue30import io.kotest.assertions.assertSoftly31import io.kotest.matchers.longs.shouldBeZero32import io.kotest.matchers.shouldBe33import io.kotest.matchers.shouldNotBe34import io.kotest.matchers.string.shouldBeEqualIgnoringCase35import io.kotest.matchers.types.shouldBeInstanceOf36import io.kotest.matchers.types.shouldBeTypeOf37import io.mockk.clearMocks38import io.mockk.every39import io.mockk.junit5.MockKExtension40import io.mockk.mockk41import kotlinx.coroutines.ExperimentalCoroutinesApi42import kotlinx.coroutines.flow.first43import kotlinx.coroutines.flow.flowOf44import kotlinx.coroutines.flow.map45import kotlinx.coroutines.flow.onEach46import kotlinx.coroutines.reactor.asFlux47import kotlinx.coroutines.runBlocking48import kotlinx.coroutines.test.runBlockingTest49import org.junit.jupiter.api.BeforeEach50import org.junit.jupiter.api.Disabled51import org.junit.jupiter.api.DisplayName52import org.junit.jupiter.api.MethodOrderer53import org.junit.jupiter.api.Nested54import org.junit.jupiter.api.Order55import org.junit.jupiter.api.Tag56import org.junit.jupiter.api.TestMethodOrder57import org.junit.jupiter.api.condition.EnabledForJreRange58import org.junit.jupiter.api.condition.JRE.JAVA_1159import org.junit.jupiter.api.condition.JRE.JAVA_1660import org.junit.jupiter.api.extension.ExtendWith61import org.junit.jupiter.api.parallel.Execution62import org.junit.jupiter.api.parallel.ExecutionMode.CONCURRENT63import org.junit.jupiter.params.ParameterizedTest64import org.junit.jupiter.params.aggregator.ArgumentsAccessor65import org.junit.jupiter.params.aggregator.get66import org.junit.jupiter.params.provider.CsvSource67import org.junit.jupiter.params.provider.ValueSource68import org.springframework.context.support.ReloadableResourceBundleMessageSource69import org.springframework.data.mapping.div70import org.springframework.data.mongodb.core.ReactiveFindOperation.ReactiveFind71import org.springframework.data.mongodb.core.ReactiveFluentMongoOperations72import org.springframework.data.mongodb.core.ReactiveInsertOperation.ReactiveInsert73import org.springframework.data.mongodb.core.ReactiveMongoTemplate74import org.springframework.data.mongodb.core.ReactiveRemoveOperation.ReactiveRemove75import org.springframework.data.mongodb.core.insert76import org.springframework.data.mongodb.core.query77import org.springframework.data.mongodb.core.query.Query.query78import org.springframework.data.mongodb.core.query.isEqualTo79import org.springframework.data.mongodb.core.query.regex80import org.springframework.data.mongodb.core.remove81import org.springframework.security.core.authority.SimpleGrantedAuthority82import org.springframework.security.core.userdetails.UserDetails83import org.springframework.util.LinkedMultiValueMap84import reactor.core.publisher.Mono85import reactor.kotlin.core.publisher.toMono86import java.util.*87import java.util.UUID.randomUUID88import com.acme.labor.config.security.CreateResult as UserCreateResult89// https://junit.org/junit5/docs/current/user-guide90// https://assertj.github.io/doc91@Tag("service")92@DisplayName("Anwendungskern fuer Labor testen")93@Execution(CONCURRENT)94@ExtendWith(MockKExtension::class)95@EnabledForJreRange(min = JAVA_11, max = JAVA_16)96@TestMethodOrder(MethodOrderer.OrderAnnotation::class)97@ExperimentalCoroutinesApi98@Suppress("ReactorUnusedPublisher", "ReactiveStreamsUnusedPublisher")99class LaborServiceTest {100    private var mongo = mockk<ReactiveFluentMongoOperations>()101    // fuer Update102    private val mongoTemplate = mockk<ReactiveMongoTemplate>()103    // ggf. com.ninja-squad:springmockk104    private val messageSource = ReloadableResourceBundleMessageSource().apply {105        setBasename("classpath:messages")106        setDefaultEncoding("UTF-8")107    }108    private var adresseValidator = AdresseValidator(messageSource)109    private var validator = LaborValidator(messageSource, adresseValidator)110    private var userDetailsService = mockk<CustomUserDetailsService>()111    private val mailer = mockk<Mailer>()112    private val gesundheitsamtClient = mockk<GesundheitsamtClient>()113    private val service = LaborService(validator, mongo, userDetailsService, mailer, gesundheitsamtClient)114    private var findOp = mockk<ReactiveFind<Labor>>()115    private var insertOp = mockk<ReactiveInsert<Labor>>()116    private var removeOp = mockk<ReactiveRemove<Labor>>()117    @BeforeEach118    fun beforeEach() {119        clearMocks(120            mongo,121            mongoTemplate,122            userDetailsService,123            mailer,124            findOp,125            insertOp,126            removeOp,127        )128    }129    // -------------------------------------------------------------------------130    // L E S E N131    // -------------------------------------------------------------------------132    @Nested133    inner class Lesen {134        @Suppress("ClassName")135        @Nested136        inner class `Suche anhand der ID` {137            @ParameterizedTest138            @CsvSource("$ID_VORHANDEN, $NAME, $USERNAME")139            @Order(1000)140            // runBlockingTest {}, damit die Testfunktion nicht vor den Coroutinen (= suspend-Funktionen) beendet wird141            // https://github.com/Kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-test/README.md#runblockingtest142            // https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-test/kotlinx.coroutines.test/run-blocking-test.html143            // https://craigrussell.io/2019/11/unit-testing-coroutine-suspend-functions-using-testcoroutinedispatcher144            // https://github.com/Kotlin/kotlinx.coroutines/issues/1222145            // https://github.com/Kotlin/kotlinx.coroutines/issues/1266146            // https://github.com/Kotlin/kotlinx.coroutines/issues/1204147            fun `Suche mit vorhandener ID`(idStr: String, name: String, username: String) = runBlockingTest {148                // given149                every { mongo.query<Labor>() } returns findOp150                val id = UUID.fromString(idStr)151                every { findOp.matching(Labor::id isEqualTo id) } returns findOp152                val laborMock = createLaborMock(id, name)153                // findOp.awaitOneOrNull() ist eine suspend-Funktion154                every { findOp.one() } returns laborMock.toMono()155                // when156                val result = service.findById(id, username)157                // then158                result.asClue {159                    it.shouldBeTypeOf<FindByIdResult.Success>()160                    it.labor.id shouldBe id161                }162            }163            @ParameterizedTest164            @ValueSource(strings = [ID_NICHT_VORHANDEN])165            @Order(1100)166            fun `Suche mit nicht vorhandener ID`(idStr: String) = runBlockingTest {167                // given168                val username = USERNAME_ADMIN169                val password = PASSWORD170                val admin: UserDetails = CustomUser(171                    id = randomUUID(),172                    username = username,173                    password = password,174                    authorities = listOfNotNull(SimpleGrantedAuthority(Rolle.adminStr)),175                )176                @Suppress("UNCHECKED_CAST")177                val adminMono = admin.toMono() as Mono<UserDetails?>178                every { userDetailsService.findByUsername(username) } returns adminMono179                every { mongo.query<Labor>() } returns findOp180                val id = UUID.fromString(idStr)181                every { findOp.matching(Labor::id isEqualTo id) } returns findOp182                every { findOp.one() } returns Mono.empty()183                // when184                val result = service.findById(id, username)185                // then186                result.shouldBeTypeOf<FindByIdResult.NotFound>()187            }188        }189        @ParameterizedTest190        @ValueSource(strings = [NAME])191        @Order(2000)192        fun `Suche alle Laborn`(name: String) = runBlockingTest {193            // given194            every { mongo.query<Labor>() } returns findOp195            val laborMock = createLaborMock(name)196            // .flow()197            every { findOp.all() } returns flowOf(laborMock).asFlux()198            val emptyQueryParams = LinkedMultiValueMap<String, String>()199            // when200            val labore = service.find(emptyQueryParams)201            // then: NoSuchElementException bei leerem Flow202            labore.first()203        }204        @ParameterizedTest205        @ValueSource(strings = [NAME])206        @Order(2100)207        fun `Suche mit vorhandenem Namen`(name: String) = runBlockingTest {208            // given209            every { mongo.query<Labor>() } returns findOp210            every { findOp.matching(Labor::name.regex(name, "i")) } returns findOp211            val laborMock = createLaborMock(name)212            // .flow()213            every { findOp.all() } returns flowOf(laborMock).asFlux()214            val queryParams = LinkedMultiValueMap(mapOf("name" to listOfNotNull(name)))215            // when216            val labore = service.find(queryParams)217            // then218            assertSoftly {219                labore.onEach { labor ->220                    labor.name shouldBe name221                }.first() // NoSuchElementException bei leerem Flow222            }223        }224        @ParameterizedTest225        @CsvSource("$ID_VORHANDEN, $NAME, $PLZ")226        @Order(2400)227        fun `Suche mit vorhandener PLZ`(228            idStr: String,229            name: String,230            plz: String,231        ) = runBlockingTest {232            // given233            every { mongo.query<Labor>() } returns findOp234            every { findOp.matching(Labor::adresse / Adresse::plz regex "^$plz") } returns findOp235            val id = UUID.fromString(idStr)236            val laborMock = createLaborMock(id, name, plz)237            every { findOp.all() } returns flowOf(laborMock).asFlux()238            val queryParams = LinkedMultiValueMap(mapOf("plz" to listOfNotNull(plz)))239            // when240            val labore = service.find(queryParams)241            // then242            assertSoftly {243                labore.map { labor -> labor.adresse.plz }244                    .onEach { p -> p shouldBe plz }245                    .first() // NoSuchElementException bei leerem Flow246            }247        }248        @ParameterizedTest249        @CsvSource("$ID_VORHANDEN, $NAME, $PLZ")250        @Order(2500)251        fun `Suche mit vorhandenem Namen und PLZ`(252            idStr: String,253            name: String,254            plz: String,255        ) = runBlockingTest {256            // given257            every { mongo.query<Labor>() } returns findOp258            val query = query(Labor::name.regex(name, "i"))259            query.addCriteria(Labor::adresse / Adresse::plz regex "^$plz")260            every { findOp.matching(query) } returns findOp261            val id = UUID.fromString(idStr)262            val laborMock = createLaborMock(id, name, plz)263            every { findOp.all() } returns flowOf(laborMock).asFlux()264            val queryParams =265                LinkedMultiValueMap(mapOf("name" to listOfNotNull(name), "plz" to listOfNotNull(plz)))266            // when267            val labore = service.find(queryParams)268            // then269            assertSoftly {270                labore.onEach { labor ->271                    labor.asClue {272                        it.name shouldBeEqualIgnoringCase name273                        it.adresse.plz shouldBe plz274                    }275                }.first() // NoSuchElementException bei leerem Flow276            }277        }278    }279    // -------------------------------------------------------------------------280    // S C H R E I B E N281    // -------------------------------------------------------------------------282    @Nested283    inner class Schreiben {284        @Nested285        inner class Erzeugen {286            @ParameterizedTest287            @CsvSource("$NAME, $PLZ, $USERNAME, $PASSWORD")288            @Order(5000)289            @Disabled("TODO Mocking des Transaktionsrumpfs")290            fun `Neuen Laborn abspeichern`(args: ArgumentsAccessor) = runBlockingTest {291                // given292                val name = args.get<String>(0)293                val plz = args.get<String>(1)294                val username = args.get<String>(2)295                val password = args.get<String>(3)296                every { mongo.query<Labor>() } returns findOp297                every { findOp.exists() } returns false.toMono()298                val userMock = CustomUser(id = null, username = username, password = password)299                val userMockCreated = CustomUser(id = randomUUID(), username = username, password = password)300                val userResult = UserCreateResult.Success(userMockCreated)301                every { runBlocking { userDetailsService.create(userMock) } } returns userResult302                every { mongo.insert<Labor>() } returns insertOp303                val laborMock = createLaborMock(null, name ,plz, username, password)304                val laborResultMock = laborMock.copy(id = randomUUID())305                every { insertOp.one(laborMock) } returns laborResultMock.toMono()306                every { runBlocking { mailer.send(laborMock) } } returns SendResult.Success307                // when308                val result = service.create(laborMock)309                // then310                result.shouldBeInstanceOf<CreateResult.Success>()311                val labor = result.labor312                assertSoftly {313                    labor.asClue {314                        it.id shouldNotBe null315                        it.name shouldBe name316                        it.adresse.plz shouldBe plz317                        it.username shouldBe username318                    }319                }320            }321        }322        @Nested323        inner class Aendern {324            @ParameterizedTest325            @CsvSource("$ID_UPDATE, $NAME")326            @Order(6000)327            @Disabled("Mocking des Cache in Spring Data MongoDB...")328            fun `Vorhandenen Laborn aktualisieren`(329                idStr: String,330                name: String,331            ) = runBlockingTest {332                // given333                every { mongo.query<Labor>() } returns findOp334                val id = UUID.fromString(idStr)335                every { findOp.matching(Labor::id isEqualTo id) } returns findOp336                val laborMock = createLaborMock(id, name)337                every { findOp.one() } returns laborMock.toMono()338                every { mongoTemplate.save(laborMock) } returns laborMock.toMono()339                // when340                val result = service.update(laborMock, id, laborMock.version.toString())341                // then342                result.asClue {343                    it.shouldBeInstanceOf<UpdateResult.Success>()344                    it.labor.id shouldBe id345                }346            }347            @ParameterizedTest348            @CsvSource("$ID_NICHT_VORHANDEN, $NAME, $VERSION")349            @Order(6100)350            fun `Nicht-existierenden Laborn aktualisieren`(args: ArgumentsAccessor) = runBlockingTest {351                // given352                val idStr = args.get<String>(0)353                val id = UUID.fromString(idStr)354                val name = args.get<String>(1)355                val version = args.get<String>(2)356                every { mongo.query<Labor>() } returns findOp357                every { findOp.matching(Labor::id isEqualTo id) } returns findOp358                every { findOp.one() } returns Mono.empty()359                val laborMock = createLaborMock(id, name)360                // when361                val result = service.update(laborMock, id, version)362                // then363                result.shouldBeInstanceOf<UpdateResult.NotFound>()364            }365            @ParameterizedTest366            @CsvSource("$ID_UPDATE, $NAME, $VERSION_INVALID")367            @Order(6200)368            fun `Labor aktualisieren mit falscher Versionsnummer`(args: ArgumentsAccessor) = runBlockingTest {369                // given370                val idStr = args.get<String>(0)371                val id = UUID.fromString(idStr)372                val name = args.get<String>(1)373                val version = args.get<String>(2)374                every { mongo.query<Labor>() } returns findOp375                every { findOp.matching(Labor::id isEqualTo id) } returns findOp376                val laborMock = createLaborMock(id, name)377                every { findOp.one() } returns laborMock.toMono()378                // when379                val result = service.update(laborMock, id, version)380                // then381                result.asClue {382                    it.shouldBeInstanceOf<UpdateResult.VersionInvalid>()383                    it.version shouldBe version384                }385            }386            @ParameterizedTest387            @CsvSource("$ID_UPDATE, $NAME, $VERSION_ALT")388            @Order(6300)389            @Disabled("Mocking des Cache in Spring Data MongoDB...")390            fun `Labor aktualisieren mit alter Versionsnummer`(args: ArgumentsAccessor) = runBlockingTest {391                // given392                val idStr = args.get<String>(0)393                val id = UUID.fromString(idStr)394                val name = args.get<String>(1)395                val version = args.get<String>(2)396                every { mongo.query<Labor>() } returns findOp397                every { findOp.matching(Labor::id isEqualTo id) } returns findOp398                val laborMock = createLaborMock(id, name)399                // when400                val result = service.update(laborMock, id, version)401                // then402                result.asClue {403                    it.shouldBeInstanceOf<UpdateResult.VersionInvalid>()404                    it.version shouldBe version405                }406            }407        }408        @Nested409        inner class Loeschen {410            @ParameterizedTest411            @ValueSource(strings = [ID_LOESCHEN])412            @Order(7000)413            fun `Vorhandenen Laborn loeschen`(idStr: String) = runBlockingTest {414                // given415                every { mongo.remove<Labor>() } returns removeOp416                val id = UUID.fromString(idStr)417                every { removeOp.matching(Labor::id isEqualTo id) } returns removeOp418                // DeleteResult ist eine abstrakte Klasse419                val deleteResultMock = object : DeleteResult() {420                    override fun wasAcknowledged() = true421                    override fun getDeletedCount() = 1L422                }423                every { removeOp.all() } returns deleteResultMock.toMono()424                // when425                val deleteResult = service.deleteById(id)426                // then427                deleteResult.deletedCount shouldBe 1428            }429            @ParameterizedTest430            @ValueSource(strings = [ID_LOESCHEN_NICHT_VORHANDEN])431            @Order(7100)432            fun `Nicht-vorhandenen Laborn loeschen`(idStr: String) = runBlockingTest {433                // given434                every { mongo.remove<Labor>() } returns removeOp435                val id = UUID.fromString(idStr)436                every { removeOp.matching(Labor::id isEqualTo id) } returns removeOp437                // DeleteResult ist eine abstrakte Klasse438                val deleteResultMock = object : DeleteResult() {439                    override fun wasAcknowledged() = true440                    override fun getDeletedCount() = 0L441                }442                every { removeOp.all() } returns deleteResultMock.toMono()443                // when444                val deleteResult = service.deleteById(id)445                // then446                deleteResult.deletedCount.shouldBeZero()447            }448        }449    }450    // -------------------------------------------------------------------------451    // Hilfsmethoden fuer Mocking452    // -------------------------------------------------------------------------453    private fun createLaborMock(name: String): Labor = createLaborMock(randomUUID(), name)454    private fun createLaborMock(id: UUID?, name: String) = createLaborMock(id, name, PLZ)455    private fun createLaborMock(id: UUID?, name: String, plz: String) =456                createLaborMock(id, name, plz, HAUSNUMMER, STRASSE, TELEFONNUMMER, FAX, true, BUNDESLAND, LANDKREIS, USERNAME, PASSWORD)457    private fun createLaborMock(id: UUID?, name: String, plz: String, username: String, password: String) =458    createLaborMock(id, name, plz, HAUSNUMMER, STRASSE, TELEFONNUMMER, FAX, true, BUNDESLAND, LANDKREIS, username, password)459    @Suppress("LongParameterList", "SameParameterValue")460    private fun createLaborMock(461        id: UUID?,462        name: String,463        plz: String,464        hausnummer: Int,465        strasse: String,466        telefonnummer: String,467        fax: String,468        testetAufCorona: Boolean,469        bundesland: String,470        landkreis: String,471        username: String?,472        password: String?,473    ): Labor {474        val adresse = Adresse(plz = plz, ort = ORT, hausnummer = hausnummer, strasse = strasse)475        val gesundheitsamt = Gesundheitsamt(bundesland = bundesland, landkreis = landkreis, adresse = adresse)476        val labor = Labor(477            id = id,478            version = 0,479            name = name,480            adresse = adresse,481            telefonnummer = telefonnummer,482            fax = fax,483            laborTests = listOf(TestTyp.Antikoerper),484            testetAufCorona = testetAufCorona,485            zustaendigesGesundheitsamt = gesundheitsamt,486            username = USERNAME,487        )488        if (username != null && password != null) {489            val customUser = CustomUser(id = null, username = username, password = password)490            labor.user = customUser491        }492        return labor493    }494    private companion object {495        const val ID_VORHANDEN = "00000000-0000-0000-0000-000000000001"496        const val ID_NICHT_VORHANDEN = "99999999-9999-9999-9999-999999999999"497        const val ID_UPDATE = "00000000-0000-0000-0000-000000000002"498        const val ID_LOESCHEN = "00000000-0000-0000-0000-000000000005"499        const val ID_LOESCHEN_NICHT_VORHANDEN = "AAAAAAAA-AAAA-AAAA-AAAA-AAAAAAAAAAAA"500        const val HAUSNUMMER = 1501        const val STRASSE = "Haupstrasse"502        const val PLZ = "12345"503        const val ORT = "Testort"504        const val TELEFONNUMMER = "123456789"505        const val FAX = "12345"506        const val BUNDESLAND = "Bayern"507        const val LANDKREIS = "Test"508        const val NAME = "Test"509        const val USERNAME = "test"510        const val USERNAME_ADMIN = "admin"511        const val PASSWORD = "p"512        const val VERSION = "0"513        const val VERSION_INVALID = "?!"514        const val VERSION_ALT = "-1"515    }516}...CommandTest.kt
Source:CommandTest.kt  
1/*2 * This file is part of bowler-kernel.3 *4 * bowler-kernel is free software: you can redistribute it and/or modify5 * it under the terms of the GNU Lesser General Public License as published by6 * the Free Software Foundation, either version 3 of the License, or7 * (at your option) any later version.8 *9 * bowler-kernel is distributed in the hope that it will be useful,10 * but WITHOUT ANY WARRANTY; without even the implied warranty of11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the12 * GNU Lesser General Public License for more details.13 *14 * You should have received a copy of the GNU Lesser General Public License15 * along with bowler-kernel.  If not, see <https://www.gnu.org/licenses/>.16 */17package com.commonwealthrobotics.bowlerkernel.cli18import io.kotest.matchers.longs.shouldBeZero19import io.kotest.matchers.shouldBe20import io.kotest.matchers.string.shouldContain21import org.junit.jupiter.api.Nested22import org.junit.jupiter.api.Test23import java.util.concurrent.CountDownLatch24internal class CommandTest {25    @Nested26    inner class TerminalCommands {27        @Test28        fun `invoke a terminal command with no options`() {29            val latch = CountDownLatch(1)30            val expectedPrintout = "output"31            val cmd = Command(name = "foo", help = "") { latch.countDown(); expectedPrintout }32            val args = mutableListOf<String>()33            cmd(args).shouldContain(expectedPrintout)34            latch.count.shouldBeZero()35        }36        @Test37        fun `invoke a terminal command with one non-required option`() {38            val latch = CountDownLatch(1)39            val cmd = Command(40                name = "foo",41                help = "bar",42                options = listOf(43                    option<Int>(44                        short = "a",45                        long = "aa",46                        help = "",47                        required = false48                    )49                )50            ) {51                it.option<Int>("aa").shouldBe(1)52                latch.countDown()53                ""54            }55            val args = mutableListOf("-a", "1")56            cmd(args)57            latch.count.shouldBeZero()58        }59        @Test60        fun `invoke a terminal command with one required option`() {61            val latch = CountDownLatch(1)62            val cmd = Command(63                name = "foo",64                help = "bar",65                options = listOf(66                    option<Int>(67                        short = "a",68                        long = "aa",69                        help = "",70                        required = true71                    )72                )73            ) {74                it.option<Int>("aa").shouldBe(1)75                latch.countDown()76                ""77            }78            val args = mutableListOf("-a", "1")79            cmd(args)80            latch.count.shouldBeZero()81        }82        @Test83        fun `invoke a terminal command with one missing required option`() {84            val latch = CountDownLatch(1)85            val cmd = Command(86                name = "foo",87                help = "bar",88                options = listOf(89                    option<Int>(90                        short = "a",91                        long = "aa",92                        help = "",93                        required = true94                    )95                )96            ) {97                latch.countDown()98                ""99            }100            val args = mutableListOf<String>()101            cmd(args).apply {102                shouldContain("Missing option")103                shouldContain("aa")104            }105            latch.count.shouldBe(1)106        }107        @Test108        fun `invoke a terminal command with one missing non-required option`() {109            val latch = CountDownLatch(1)110            val cmd = Command(111                name = "foo",112                help = "bar",113                options = listOf(114                    option<Int>(115                        short = "a",116                        long = "aa",117                        help = "",118                        required = false119                    )120                )121            ) {122                it.option("aa", 2).shouldBe(2)123                latch.countDown()124                ""125            }126            val args = mutableListOf<String>()127            cmd(args)128            latch.count.shouldBe(0)129        }130        @Test131        fun `invoke a terminal command with one option with a missing value`() {132            val latch = CountDownLatch(1)133            val cmd = Command(134                name = "foo",135                help = "bar",136                options = listOf(137                    option<Int>(138                        short = "a",139                        long = "aa",140                        help = "",141                        required = false142                    )143                )144            ) {145                latch.countDown()146                ""147            }148            val args = mutableListOf("-a") // Don't pass a value149            cmd(args)150            latch.count.shouldBe(1)151        }152        @Test153        fun `invoke a terminal command with one option with an invalid value`() {154            val latch = CountDownLatch(1)155            val cmd = Command(156                name = "foo",157                help = "bar",158                options = listOf(159                    option<Int>(160                        short = "a",161                        long = "aa",162                        help = "",163                        required = false,164                        validator = { false }165                    )166                )167            ) {168                latch.countDown()169                ""170            }171            val args = mutableListOf("-a", "1")172            cmd(args).apply {173                shouldContain("Invalid option")174                shouldContain("aa")175            }176            latch.count.shouldBe(1)177        }178        @Test179        fun `invoke a terminal command with one option that fails to parse`() {180            val latch = CountDownLatch(1)181            val cmd = Command(182                name = "foo",183                help = "bar",184                options = listOf(185                    option<Int>(186                        short = "a",187                        long = "aa",188                        help = "",189                        required = false,190                        validator = { false }191                    )192                )193            ) {194                latch.countDown()195                ""196            }197            val args = mutableListOf("-a", "q")198            cmd(args).apply {199                shouldContain("Invalid option")200                shouldContain("aa")201            }202            latch.count.shouldBe(1)203        }204        @Test205        fun `passing an unknown option is an error`() {206            val cmd = Command(name = "foo", help = "") { "" }207            val args = mutableListOf("option1")208            cmd(args).apply {209                shouldContain("Unknown option")210                args.forEach { shouldContain(it) }211            }212        }213    }214    @Nested215    inner class NonTerminalCommands {216        @Test217        fun `run a non-terminal command`() {218            val latch = CountDownLatch(1)219            val expectedPrintout = "output"220            val cmd = Command(221                name = "foo",222                help = "",223                children = listOf(224                    Command(name = "inner1", help = "") { "" },225                    Command(name = "inner2", help = "") { latch.countDown(); expectedPrintout },226                    Command(name = "inner3", help = "") { "" },227                )228            )229            val args = mutableListOf("inner2")230            cmd(args).shouldContain(expectedPrintout)231            latch.count.shouldBeZero()232        }233    }234}...LongMatchersTest.kt
Source:LongMatchersTest.kt  
1package com.sksamuel.kotest.matchers.numerics2import io.kotest.assertions.throwables.shouldThrow3import io.kotest.matchers.comparables.beGreaterThan4import io.kotest.matchers.comparables.beGreaterThanOrEqualTo5import io.kotest.matchers.comparables.beLessThan6import io.kotest.matchers.comparables.beLessThanOrEqualTo7import io.kotest.matchers.longs.between8import io.kotest.matchers.longs.shouldBeNegative9import io.kotest.matchers.longs.shouldBePositive10import io.kotest.matchers.longs.shouldBeZero11import io.kotest.matchers.longs.shouldNotBeZero12import io.kotest.core.spec.style.StringSpec13import io.kotest.matchers.should14import io.kotest.matchers.shouldBe15import io.kotest.data.forAll16import io.kotest.data.forNone17import io.kotest.data.headers18import io.kotest.data.row19import io.kotest.data.table20class LongMatchersTest : StringSpec() {21  init {22    "be positive" {23      1L.shouldBePositive()24      shouldThrow<AssertionError> {25        (-1L).shouldBePositive()26      }.message shouldBe "-1 should be > 0"27      shouldThrow<AssertionError> {28        (0L).shouldBePositive()29      }.message shouldBe "0 should be > 0"30    }31    "be negative" {32      (-1L).shouldBeNegative()33      shouldThrow<AssertionError> {34        1L.shouldBeNegative()35      }.message shouldBe "1 should be < 0"36      shouldThrow<AssertionError> {37        0L.shouldBeNegative()38      }.message shouldBe "0 should be < 0"39    }40    "Ge should be valid" {41      1L should beGreaterThan(0L)42    }43    "beGreaterThan" {44      1L should beGreaterThan(0L)45      shouldThrow<AssertionError> {46        2L should beGreaterThan(3L)47      }48    }49    "beLessThan" {50      1L should beLessThan(2L)51      shouldThrow<AssertionError> {52        2L should beLessThan(1L)53      }54    }55    "beLessThanOrEqualTo" {56      1L should beLessThanOrEqualTo(2L)57      shouldThrow<AssertionError> {58        2L should beLessThanOrEqualTo(1L)59      }60    }61    "greaterThan" {62      1L should beGreaterThanOrEqualTo(0L)63      shouldThrow<AssertionError> {64        2L should beGreaterThanOrEqualTo(3L)65      }66    }67    "between should test for valid interval" {68      val table = table(69          headers("a", "b"),70          row(0L, 2L),71          row(1L, 2L),72          row(0L, 1L),73          row(1L, 1L)74      )75      forAll(table) { a, b ->76        1 shouldBe between(a, b)77      }78    }79    "between should test for invalid interval" {80      val table = table(81          headers("a", "b"),82          row(0L, 2L),83          row(2L, 2L),84          row(4L, 5L),85          row(4L, 6L)86      )87      forNone(table) { a, b ->88        3 shouldBe between(a, b)89      }90    }91    "shouldBeZero" {92      (0L).shouldBeZero()93      (1L).shouldNotBeZero()94      Long.MIN_VALUE.shouldNotBeZero()95      Long.MAX_VALUE.shouldNotBeZero()96    }97  }98}...long.kt
Source:long.kt  
1package io.kotest.matchers.longs2import io.kotest.matchers.Matcher3import io.kotest.matchers.MatcherResult4import io.kotest.matchers.comparables.gt5import io.kotest.matchers.comparables.gte6import io.kotest.matchers.comparables.lt7import io.kotest.matchers.comparables.lte8import io.kotest.matchers.should9import io.kotest.matchers.shouldBe10import io.kotest.matchers.shouldNot11import io.kotest.matchers.shouldNotBe12fun Long.shouldBePositive() = this shouldBe positiveL()13fun positiveL() = object : Matcher<Long> {14  override fun test(value: Long) = MatcherResult(value > 0, "$value should be > 0", "$value should not be > 0")15}16fun Long.shouldBeNegative() = this shouldBe negativeL()17fun negativeL() = object : Matcher<Long> {18  override fun test(value: Long) = MatcherResult(value < 0, "$value should be < 0", "$value should not be < 0")19}20fun Long.shouldBeEven() = this should lbeEven()21fun Long.shouldNotBeEven() = this shouldNot lbeEven()22fun lbeEven() = object : Matcher<Long> {23  override fun test(value: Long): MatcherResult =24      MatcherResult(value % 2 == 0L, "$value should be even", "$value should be odd")25}26fun Long.shouldBeOdd() = this should lbeOdd()27fun Long.shouldNotBeOdd() = this shouldNot lbeOdd()28fun lbeOdd() = object : Matcher<Long> {29  override fun test(value: Long): MatcherResult =30      MatcherResult(value % 2 == 1L, "$value should be odd", "$value should be even")31}32infix fun Long.shouldBeLessThan(x: Long) = this shouldBe lt(x)33infix fun Long.shouldNotBeLessThan(x: Long) = this shouldNotBe lt(x)34infix fun Long.shouldBeLessThanOrEqual(x: Long) = this shouldBe lte(x)35infix fun Long.shouldNotBeLessThanOrEqual(x: Long) = this shouldNotBe lte(x)36infix fun Long.shouldBeGreaterThan(x: Long) = this shouldBe gt(x)37infix fun Long.shouldNotBeGreaterThan(x: Long) = this shouldNotBe gt(x)38infix fun Long.shouldBeGreaterThanOrEqual(x: Long) = this shouldBe gte(x)39infix fun Long.shouldNotBeGreaterThanOrEqual(x: Long) = this shouldNotBe gte(x)40infix fun Long.shouldBeExactly(x: Long) = this shouldBe exactly(x)41infix fun Long.shouldNotBeExactly(x: Long) = this shouldNotBe exactly(x)42fun Long.shouldBeZero() = this shouldBeExactly 0L43fun Long.shouldNotBeZero() = this shouldNotBeExactly 0L...Long.shouldBeZero
Using AI Code Generation
1longValue.shouldBeZero()2longValue.shouldBeOne()3longValue.shouldBePositive()4longValue.shouldBeNegative()5longValue.shouldBeEven()6longValue.shouldBeOdd()7longValue.shouldBeInRange(0L..2L)8longValue.shouldBeLessThan(2L)9longValue.shouldBeLessThanOrEqual(1L)10longValue.shouldBeGreaterThan(1L)11longValue.shouldBeGreaterThanOrEqual(1L)12longValue.shouldBeCloseTo(1L, 1L)13longValue.shouldBeBetween(0L, 2L)Long.shouldBeZero
Using AI Code Generation
1longValue.shouldBeZero()2longValue.shouldBePositive()3longValue.shouldBeNegative()4longValue.shouldBeNonZero()5longValue.shouldBeNonPositive()6longValue.shouldBeNonNegative()7longValue.shouldBeBetween(0L, 2L)8longValue.shouldBeBetweenClosed(0L, 1L)9longValue.shouldBeBetweenExclusive(0L, 2L)10longValue.shouldBeBetweenInclusive(0L, 2L)11longValue.shouldBeBetweenInclusiveStart(1L, 2L)12longValue.shouldBeBetweenInclusiveEnd(0L, 1L)Long.shouldBeZero
Using AI Code Generation
1longs.shouldBeZero(0L)2longs.shouldBeOne(1L)3longs.shouldBeNegative(-1L)4longs.shouldBePositive(1L)5longs.shouldBeNonPositive(0L)6longs.shouldBeNonNegative(1L)7longs.shouldBeEven(2L)8longs.shouldBeOdd(1L)9longs.shouldBeInRange(0L, 1L)10longs.shouldBeLessThan(0L)11longs.shouldBeLessThanOrEqual(1L)12longs.shouldBeGreaterThan(1L)13longs.shouldBeGreaterThanOrEqual(1L)14longs.shouldBeBetween(0L, 1L)15longs.shouldBeBetweenInclusive(0L, 1L)16longs.shouldBeBetweenExclusive(0L, 1L)Long.shouldBeZero
Using AI Code Generation
1@DisplayName ( "test for shouldBeZero" ) fun testForShouldBeZero () { 0 . shouldBeZero () }2@DisplayName ( "test for shouldBeOne" ) fun testForShouldBeOne () { 1 . shouldBeOne () }3@DisplayName ( "test for shouldBeNegative" ) fun testForShouldBeNegative () { - 1 . shouldBeNegative () }4@DisplayName ( "test for shouldBePositive" ) fun testForShouldBePositive () { 1 . shouldBePositive () }5@DisplayName ( "test for shouldBeEven" ) fun testForShouldBeEven () { 2 . shouldBeEven () }6@DisplayName ( "test for shouldBeOdd" ) fun testForShouldBeOdd () { 1 . shouldBeOdd () }7@DisplayName ( "test for shouldBeBetween" ) fun testForShouldBeBetween () { 2 . shouldBeBetween ( 1 . . 3 ) }8@DisplayName ( "test for shouldNotBeBetween" ) fun testForShouldNotBeBetween () { 2 . shouldNotBeBetween ( 3 . . 5 ) }9@DisplayName ( "test for shouldBeExactly" ) fun testForShouldBeExactly () { 2 . shouldBeExactly ( 2 . . 2 ) }10@DisplayName ( "test for shouldNotBeExactly" ) fun testForShouldNotBeExactly () { 2 . shouldNotBeExactly ( 3 . . 5 ) }Long.shouldBeZero
Using AI Code Generation
1@DisplayName("Long shouldBeZero method")2@ValueSource(longs = [0L, 0L, 0L])3fun `Long shouldBeZero method`(longValue: Long) {4longValue.shouldBeZero()5}6}7@DisplayName("Long shouldBeZero method")8@ValueSource(longs = [0L, 0L, 0L])9fun `Long shouldBeZero method`(longValue: Long) {10longValue.shouldBeZero()11}12fun `Long shouldBeZero method`() {130L.shouldBeZero()14}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.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!
