Fluent assertions for Kotlin

Overview

Kiwi: Fluent assertions for Kotlin projects

License Build Status Awesome Kotlin Badge

Kiwi is multiplatform projects written in pure Kotlin. Except testing it does not use external dependencies

Release

Kiwi is available in SNAPSHOT repository for now

repositories {
    maven {
        url "https://oss.sonatype.org/content/repositories/snapshots"
    }
}

dependencies {
    testImplementation 'org.fromsource:kiwi-core-jvm:0.0.2-SNAPSHOT'
}

Kiwi, Hello World!

Below snippet demonstrates usage of Kiwi assertions for standard type like String

    @Test
    fun `should say hallo to kiwi()` {
        "Kiwi, Hello World!".should startWith "Kiwi" contain "Hello" endWith "!"
    }

Collections

Kiwi supports List, Set and Map

    @Test
    fun `should combine operator in infix chain`() {
        val animals = listOf("kiwi", "hedgehog", "flamingo", "humpback")

        animals.should haveSize 4 contain "humpback" have1st "kiwi"
    }

Numbers

as well as Byte, Short, Int, Long, Float, Double and JVM based numbers like BigDecimal, BigNumber

    @Test
    fun `should check if numer is prime`() {
        val number = 7

        number.should
                .bePositive()
                .beGreaterThan(1)
                .match { number -> (2 until number).all { number % it != 0} }
    }

Dates

LocalDate and LocalDateTime

    @Test
    fun `should check if date meets some conditions`() {
        val date = LocalDate.of(2020, 11, 14)

        date.should
               .beInLeapYear()
               .beInQ4()
               .beBefore(date.plusDays(1))
    }

Custom type

... even custom types are supported

    data class Animal(val name: String, val weight: Int, val mammal: Boolean) {
       fun heavy(): Boolean = weight > 10
    }

    val kiwi     = Animal(name = "kiwi", weight = 1, mammal = true)
    val hedgehog = Animal(name = "hedgehog", weight = 2, mammal = true)
    val flamingo = Animal(name = "flamingo", weight = 5, mammal = false)
    val humpback = Animal(name = "humpback", weight = 5000, mammal = true)


    @Test
    fun `should apply collection operators for list of custom object`() {

        val animals = listOf(kiwi, hedgehog, flamingo, humpback)

        animals.should
                .haveSize(4)
                .contain(flamingo)
                .beSorted { it.weight }
                .filtered { animal -> animal.mammal }
                .matchAny { animal -> animal.heavy() }

    }

JsonPath

If you need json path Kiwi will work too. See Roadmap & Future for more details

    @Test
    fun `should select json paths for json string`() {
        val json = """{
            "kiwi": "kotlin assertion library",
            "github": {
                "developers": ["john", "ben"]
            }
        }"""

        json.should
                .haveJsonPath("$.kiwi")
                .haveJsonPath("$.kiwi", """"kotlin assertion library"""")
                .haveJsonPath("$..developers", """["john", "ben"]""")
                .haveJsonPath("$..developers[0]", """"john"""")
    }

Mix of the operators

Last but not least you can mix all together Different types of operators e.g. Collection, String, Numbers can be used fluently

    @Test
    fun `should mix different types of operators`() {

        val animals = listOf(kiwi, hedgehog, flamingo, humpback)

        animals.should
                .contain(hedgehog)                              // Collection operator
                .last().name                                    // extract
                .should                             
                .match(Regex("[a-z]+"))                         // String operator
    }

Build

Run command below

$ git clone [email protected]/from-source/kiwi.git
$ cd kiwi/
$ ./gradlew clean build

Roadmap & Future

JsonPath evaluation - in progress

Take a look at the JsonPathAcceptanceTest to see which json path selectors are available

    @Test
    fun `should select first book in the store`() {
        val json =  """{ 
            "store": {
                "details": {
                    "name": "Books & Books"
                },
                "books": [
                { 
                    "category": "science",
                    "author": "Douglas Hofstadter",
                    "title": "I Am a Strange Loop",
                    "price": 8.95
                },
                { 
                    "category": "science fiction",
                    "author": "Stanislaw Lem",
                    "title": "Solaris",
                    "isbn": "978-0156027601",
                    "price": 10.99,
                    "details": "Published in 1961"
                }]
            }
        }"""

        json.should
                .haveJsonPath("$.store.details")                                // check if path exists
                .haveJsonPath("$..books[1].category", "science fiction")        // check value of path
                .haveJsonPath("$..books[0]", """{                              
                    "category": "science",
                    "author": "Douglas Hofstadter",
                    "title": "I Am a Strange Loop",
                    "price": 8.95
                }""")
                

    }

Support for more Kotlin types

Sponsored by JetBrains

Comments
  • CharRange support

    CharRange support

    Add support for CharRange

    ('a'..'c').should() startWith('1')
    ('a'..'c').should() endWith('c')
    ('a'..'c').should() contain('b')
    ('a'..'c').should() beNotEmpty()
    ('a'..'c').should() overlap(('b'..'z'))
    
    enhancement good first issue 
    opened by torczuk 2
  • IntRange support

    IntRange support

    Add support for IntRange

    (1..10).should() startWith(1)
    (1..10).should() endWith(10)
    (1..10).should() contain(5)
    (1..10).should() beNotEmpty()
    (1..10).should() overlap((9..10))
    
    enhancement good first issue 
    opened by torczuk 2
  • avoid using () for `something.should()`

    avoid using () for `something.should()`

    It is possible to avoid using () when we call should.

    Why? instead of myString.should() be "Hello we can use myString.should be "Hello I think it is a little bit closer to natural language,

    How to implement it?

    instead of adding external function fun String.should() = StringShould(this)

    we can add

    val String.should: AnyShould
     get() = AnyShould(this)
    

    The question us

    • do you like new staff?
    • if yes, should we remove shuold() staff?
    opened by sergeibukharov 1
  • #5 Add boolean support

    #5 Add boolean support

    Allows to assert a boolean value against another Boolean Allows to assert boolean against isTrue() or isFalse() Allows to assert boolean against another boolean with infix notation

    opened by sergeibukharov 1
  • [Proposal] add `be` function to `BeEqual` interface

    [Proposal] add `be` function to `BeEqual` interface

    In order to maintain fluent DSL, I suggest adding be function to BeEqual interface.

    true.should() be true
    "Hello".should() be "Hello"
    

    interface BeEqual<T, R : BeEqual<T, R>> {

    infix fun be(expected: T): R = beEqual()
    

    }

    As a counterpart we may add notBe

    "Hello".should() notBe "World"
    
    opened by sergeibukharov 1
  • Project does not compile cause ExperimentalStdlibApi has been used

    Project does not compile cause ExperimentalStdlibApi has been used

    In order to compile it, we should use the argument -Xuse-experimental=kotlin.ExperimentalStdlibApi or mark usage or declaration as @ExperimentalStdlibApi

    > Task :kiwi-json:compileKotlinMetadata FAILED
    e: /Users/sgsergey.bukharov/IdeaProjects/kiwi/kiwi-json/src/commonMain/kotlin/io/from/source/kiwi/json/Extension.kt: (19, 53): This declaration is experimental and its usage must be marked with '@kotlin.ExperimentalStdlibApi' or '@UseExperimental(kotlin.ExperimentalStdlibApi::class)'
    e: /Users/sgsergey.bukharov/IdeaProjects/kiwi/kiwi-json/src/commonMain/kotlin/io/from/source/kiwi/json/JsonParser.kt: (5, 27): This declaration is experimental and its usage must be marked with '@kotlin.ExperimentalStdlibApi' or '@UseExperimental(kotlin.ExperimentalStdlibApi::class)'
    
    opened by sergeibukharov 1
  • Triple support

    Triple support

    Add support for Triple similar as for Pair

    Triple(1,2,3).should haveFirstEqualTo(1)
    Triple(1,2,3).should haveSecondEqualTo(2)
    Triple(1,2,3).should haveThirdEqualTo(3)
    
    enhancement good first issue 
    opened by torczuk 0
  • Support for Big[Integer][Decimal]

    Support for Big[Integer][Decimal]

    Add support for java.math.BigInteger, java.math.BigDecimal

    class BigDecimalShould(private val actual: BigDecimal) : NumberShould<BigDecimal> {
    ...
    }
    
    enhancement 
    opened by torczuk 0
  • Support for kotlin.U[Byte][Short][Int][Long]

    Support for kotlin.U[Byte][Short][Int][Long]

    Add support for UByte, UShort, UInt and ULong

    interface UNumberShould<T : Comparable<T>> : BeEqual<T, UNumberShould<T>>, BeComparable<T, UNumberShould<T>> {
    
        fun bePositive(): UNumberShould<T>
        fun beZero(): UNumberShould<T>
    }
    

    Sample implementation for UByteShould might look like

    class UByteShould(private val actual: UByte) : UNumberShould<UByte> {
        ...
    }
    
    enhancement 
    opened by torczuk 0
  • kotlin.Boolean support

    kotlin.Boolean support

    Add support for Boolean type in commonMain

    class BooleanShould(private val actual: Boolean) : BeEqual<Boolean, BooleanShould> {
        fun beTrue(): BooleanShould = .. 
        fun beFalse(): BooleanShould = ..
    }
    
    enhancement good first issue 
    opened by torczuk 0
  • Extension: Support JSON validation

    Extension: Support JSON validation

    Subsequent to validating Maps, it'll be good if we could enhance the library to support validation of JSON strings.

     """{
                "name": "hedgehog",
                "weight": 1,
                "mammal": false,
                "habitats": ["Europe", "Asia", "North America"]
                "eats": {
                    "fish": ["dory", "salmon"]
                }
            }""".should()
                    .beJson()
                    .haveProperty("name", "kiwi")
                    .haveValueOnPath("$.eats.fish[1]", "dory")
    
    enhancement 
    opened by thekneeslim 0
  • Array support - Comparable and Number based type

    Array support - Comparable and Number based type

    As a reference take a loo at the CollectionShould<T> proposed api

       arrayOf(1,2,3,4,5).should
                       .sumTo(13)
                       .beSorted()
    
    enhancement good first issue 
    opened by torczuk 0
  • JsonPath evaluator

    JsonPath evaluator

    Introduce JsonPath evaluation for json object

    sample usage

    json.evaluatePath("$.store.details.name").should be listOf(JsonString("Books & Books"))
    
    json.evaluatePath("$..author").should be listOf(
                    JsonString("Douglas Hofstadter"),
                    JsonString("Christophe Galfard"),
                    JsonString("Nassim Nicholas Taleb"),
                    JsonString("Stanislaw Lem"),
                    JsonString(("J. R. R. Tolkien")))
    

    follow the https://goessner.net/articles/JsonPath/index.html#e2

    opened by torczuk 0
  • LongRange support

    LongRange support

    Add support for LongRange

    (1L..10L).should() startWith(1)
    (1L..10L).should() endWith(10)
    (1L..10L).should() contain(5)
    (1L..10L).should() beNotEmpty()
    (1L..10L).should() overlap((9L..11L))
    
    enhancement good first issue 
    opened by torczuk 0
  • Support for java.nio.file.Path

    Support for java.nio.file.Path

    Add support for java.nio.file.Path as a first iteration use existing methods

    val path = File("/home/arek/.ssh").toPath()
    
    path.should()
           .exist()
           .haveRoot("name of the root")
           .haveParent("parent")
           ...
           .startsWith("somethind")
    
    enhancement 
    opened by torczuk 0
Owner
From Source
From Source
A somewhat copy past of Jetbrain's code from the kotlin plugin repo to make it humanly possible to test Intellij IDEA kotlin plugins that work on kotlin

A somewhat copy past of Jetbrain's code from the kotlin plugin repo to make it humanly possible to test Intellij IDEA kotlin plugins that work on kotlin

common sense OSS 0 Jan 20, 2022
Real life Kotlin Multiplatform project with an iOS application developed in Swift with SwiftUI, an Android application developed in Kotlin with Jetpack Compose and a backed in Kotlin hosted on AppEngine.

Conferences4Hall Real life Kotlin Multiplatform project with an iOS application developed in Swift with SwiftUI, an Android application developed in K

Gérard Paligot 98 Dec 15, 2022
Android + Kotlin + Github Actions + ktlint + Detekt + Gradle Kotlin DSL + buildSrc = ❤️

kotlin-android-template ?? A simple Github template that lets you create an Android/Kotlin project and be up and running in a few seconds. This templa

Nicola Corti 1.5k Jan 3, 2023
LifecycleMvp 1.2 0.0 Kotlin is MVP architecture implementation with Android Architecture Components and Kotlin language features

MinSDK 14+ Download Gradle Add to project level build.gradle allprojects { repositories { ... maven { url 'https://jitpack.io' }

Robert 20 Nov 9, 2021
Opinionated Redux-like implementation backed by Kotlin Coroutines and Kotlin Multiplatform Mobile

CoRed CoRed is Redux-like implementation that maintains the benefits of Redux's core idea without the boilerplate. No more action types, action creato

Kittinun Vantasin 28 Dec 10, 2022
👋 A common toolkit (utils) ⚒️ built to help you further reduce Kotlin boilerplate code and improve development efficiency. Do you think 'kotlin-stdlib' or 'android-ktx' is not sweet enough? You need this! 🍭

Toolkit [ ?? Work in progress ⛏ ?? ??️ ?? ] Snapshot version: repositories { maven("https://s01.oss.sonatype.org/content/repositories/snapshots") }

凛 35 Jul 23, 2022
An app architecture for Kotlin/Native on Android/iOS. Use Kotlin Multiplatform Mobile.

An app architecture for Kotlin/Native on Android/iOS. Use Kotlin Multiplatform Mobile. 项目架构主要分为原生系统层、Android/iOS业务SDK层、KMM SDK层、KMM业务逻辑SDK层、iOS sdkfra

libill 4 Nov 20, 2022
Provides Kotlin libs and some features for building Kotlin plugins

Kotlin Plugin Provides Kotlin libs and some features for building awesome Kotlin plugins. Can be used instead of CreeperFace's KotlinLib (don't use to

null 3 Dec 24, 2021
Notes-App-Kotlin - Notes App Built Using Kotlin

Notes-App-Kotlin Splash Screen Home Page Adding New Notes Filter Feature Search

Priyanka 4 Oct 2, 2022
Kotlin-client-dsl - A kotlin-based dsl project for a (Client) -> (Plugin) styled program

kotlin-client-dsl a kotlin-based dsl project for a (Client) -> (Plugin) styled p

jackson 3 Dec 10, 2022
A Kotlin Native program to show the time since a date, using Kotlin LibUI

TimeSince A Kotlin Native program to show the time since a date, using Kotlin LibUI Report Bug . Request Feature About The Project TimeSince is a Kotl

Russell Banks 2 May 6, 2022
RoomJetpackCompose is an app written in Kotlin and shows a simple solution to perform CRUD operations in the Room database using Kotlin Flow in clean architecture.

RoomJetpackCompose is an app written in Kotlin and shows a simple solution to perform CRUD operations in the Room database using Kotlin Flow in clean architecture.

Alex 27 Jan 1, 2023
Create an application with Kotlin/JVM and Kotlin/JS, and explore features around code sharing, serialization, server- and client

Practical Kotlin Multiplatform on the Web 본 저장소는 코틀린 멀티플랫폼 기반 웹 프로그래밍 워크숍(강좌)을 위해 작성된 템플릿 프로젝트가 있는 곳입니다. 워크숍 과정에서 코틀린 멀티플랫폼을 기반으로 프론트엔드(front-end)는 Ko

SpringRunner 14 Nov 5, 2022
Create an application with Kotlin/JVM and Kotlin/JS, and explore features around code sharing, serialization, server- and client

Building a Full Stack Web App with Kotlin Multiplatform 본 저장소는 INFCON 2022에서 코틀린 멀티플랫폼 기반 웹 프로그래밍 핸즈온랩을 위해 작성된 템플릿 프로젝트가 있는 곳입니다. 핸즈온 과정에서 코틀린 멀티플랫폼을

Arawn Park 19 Sep 8, 2022
Kotlin library for Android

KAndroid Kotlin library for Android providing useful extensions to eliminate boilerplate code in Android SDK and focus on productivity. Download Downl

Paweł Gajda 890 Nov 13, 2022
Type-safe time calculations in Kotlin, powered by generics.

Time This library is made for you if you have ever written something like this: val duration = 10 * 1000 to represent a duration of 10 seconds(in mill

Kizito Nwose 958 Dec 10, 2022
📒 NotyKT is a complete 💎Kotlin-stack (Backend + Android) 📱 application built to demonstrate the use of Modern development tools with best practices implementation🦸.

NotyKT ??️ NotyKT is the complete Kotlin-stack note taking ??️ application ?? built to demonstrate a use of Kotlin programming language in server-side

Shreyas Patil 1.4k Jan 4, 2023
A Kotlin DSL wrapper around the mikepenz/MaterialDrawer library.

MaterialDrawerKt Create navigation drawers in your Activities and Fragments without having to write any XML, in pure Kotlin code, with access to all t

Márton Braun 517 Nov 19, 2022
Kotlin-based modern RecyclerView rendering weapon

Read this in other languages: 中文, English, Changelog Yasha Item introduction: Kotlin-based modern RecyclerView rendering weapon Item Features: No Adap

Season 514 Dec 21, 2022