Test the shape of your functions!

Overview

Build Status Maven Central codecov

🧪 This library is experimental!

Its API is not stabilized yet, and writing tests is still a bit tedious. Use at your own risk. Looking forward to your feedback :)

What is vis-assert?

It's a Kotlin library to write visually appealing ASCII-art-like test assertions for math functions. For example, you can test that your (Float) -> Float function describing a sine wave produces proper values. Or if you have a game where the player jumps, you can describe player's vertical position as a function of time - you could test this function to make sure that the jump movement is fluent and fast enough.

Under the hood, each such ASCII visualisation is translated into a collection of constraints, where each constraint looks at a single X value of the function and performs a certain check on its Y value at this point.

Installation

In your build.gradle or build.gradle.kts:

repositories {
    mavenCentral()
}

dependencies {
    testCompile("it.krzeminski.vis-assert:vis-assert:0.4.1-beta")
}

// or

kotlin {
    sourceSets {
        val ...Test by getting {
            dependencies {
                implementation("it.krzeminski.vis-assert:vis-assert:0.4.1-beta")
            }
        }
    }
}

Examples

@Test
fun sineWaveFor2HzOnePeriod() {
    assertFunctionConformsTo(
            functionUnderTest = sineWave(frequency = 2.0f),
            visualisation = {
                row(1.0f,   "        IIXII                            ")
                row(        "     III     III                         ")
                row(        "    I           I                        ")
                row(        "  II             II                      ")
                row(        " I                 I                     ")
                row(0.0f,   "X                   I                   I")
                row(        "                     I                 I ")
                row(        "                      II             II  ")
                row(        "                        I           I    ")
                row(        "                         III     III     ")
                row(-1.0f,  "                            IIIII        ")
                xAxis {
                    markers("|                   |                   |")
                    values( 0.0f,               0.25f,              0.5f)
                }
            })
}

or for high-frequency function and higher sampling:

@Test
fun assertFunctionConformsToForHighFrequencyFunctionWhenAssertionsAreFulfilledAndSamplingHigherThan1IsUsed() {
    assertFunctionConformsTo(
        functionUnderTest = { x: Float -> (sin(100*x) * sin(x) * x * 0.3).toFloat() },
        samplesPerCharacter = 100,
        visualisation = {
            row( 2.0f,  "                                                                   ")
            row(        "                                                                   ")
            row(        "                                               IIIIIIIIIIIIII      ")
            row( 1.0f,  "                                           IIIIIIIIIIIIIIIIIIIII   ")
            row(        "                   IIIIIIII             IIIIIIIIIIIIIIIIIIIIIIIIIII")
            row(        "         IIIIIIIIIIIIIIIIIIIIIIII   IIIIIIIIIIIIIIIIIIIIIIIIIIIIIII")
            row( 0.0f,  "IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII")
            row(        "         IIIIIIIIIIIIIIIIIIIIIIII    IIIIIIIIIIIIIIIIIIIIIIIIIIIIII")
            row(        "                  IIIIIIII              IIIIIIIIIIIIIIIIIIIIIIIIIII")
            row(-1.0f,  "                                            IIIIIIIIIIIIIIIIIIII   ")
            row(        "                                               IIIIIIIIIIIIII      ")
            row(        "                                                                   ")
            row(-2.0f,  "                                                                   ")
            xAxis {
                markers("|          |          |          |          |          |          |")
                values( 0.0f,      1.0f,      2.0f,      3.0f,      4.0f,      5.0f,      6.0f)
            }
        }
    )
}

Where:

  • I characters mean that for a given X argument, the function's value can be in a certain range around a given Y value. Also, this constraint is "strict", which means that making it wider or narrower vertically would make the assertion fail. In this example, each I character has a tolerance of +/- 0.1. The tolerance is calculated based on the vertical axis description.
  • X characters mean that for a given X argument, the function's value has to exactly match the given Y value.

There's also i constraint, which just checks that all values are in a certain range.

More examples can be found in unit tests for krzema12/fsynth - a project that vis-assert was created for.

Limitations

  • the library performs sampling, as given by the xAxis description and samplesPerCharacter parameter. It means that if two subsequent X values are 0.2 and 0.3, and not enough sampling rate is given, the library may not check what happens for 0.25 or 0.20001. In most cases, such simple sampling is enough.
  • only (Float) -> Float functions are currently supported. Mitigation: it's possible to assert on any other function, as long as it can be presented as a (Float) -> Float function. See this example for adapting an (Int) -> Float function
  • when assertions fail, the current message just says about failed first (x, y) constraint, going from the left. It's thus quite time-consuming to write a test. Ideally, if the assertion fails, vis-assert should show how the ASCII visualisation could look like.
Comments
  • Maven Central publish

    Maven Central publish

    Could you publish the artifact to Central?

    Related issue: https://github.com/korlibs/korge/issues/345

    I have updated the easy plugin already to support central: https://github.com/korlibs/easy-kotlin-mpp-gradle-plugin/releases/tag/v0.14.3

    opened by soywiz 16
  • Fix publishing in JCenter

    Fix publishing in JCenter

    When trying to use PlotAssert from fsynth and jcenter, I'm getting:

    Could not determine the dependencies of task ':core:jsTestPackageJson'.
    > Could not resolve all dependencies for configuration ':core:jsTestNpm'.
       > Could not find it.krzeminski:PlotAssert-js:0.3.0-beta.
         Searched in the following locations:
           - https://repo.maven.apache.org/maven2/it/krzeminski/PlotAssert-js/0.3.0-beta/PlotAssert-js-0.3.0-beta.pom
           - https://jcenter.bintray.com/it/krzeminski/PlotAssert-js/0.3.0-beta/PlotAssert-js-0.3.0-beta.pom
         Required by:
             project :core > it.krzeminski:PlotAssert:0.3.0-beta
    
    Possible solution:
     - Declare repository providing the artifact, see the documentation at https://docs.gradle.org/current/userguide/declaring_repositories.html
    

    Trying to spot the difference between jcenter and non-jcenter way of using the package. In my Bintray repo I see multiple variants (https://dl.bintray.com/krzema1212/it.krzeminski/it/krzeminski/):

    PlotAssert-android/
    PlotAssert-iosarm32/
    PlotAssert-iosarm64/
    PlotAssert-iosx64/
    PlotAssert-js/
    PlotAssert-jvm/
    PlotAssert-linuxx64/
    PlotAssert-macosx64/
    PlotAssert-metadata/
    PlotAssert-mingwx64/
    PlotAssert-tvosarm64/
    PlotAssert-tvosx64/
    PlotAssert-watchosarm32/
    PlotAssert-watchosarm64/
    PlotAssert-watchosx86/
    PlotAssert/
    

    In JCenter (https://jcenter.bintray.com/it/krzeminski/) I see only:

    PlotAssert/
    
    opened by krzema12 7
  • Add strict and loose assertions

    Add strict and loose assertions

    For example, of someone gives a range for a given X value, the strict assertion should also verify that no "stricter" assertion makes the test pass.

    enhancement 
    opened by krzema12 2
  • Review the API before entering public beta

    Review the API before entering public beta

    Ideally the reviewer should be someone:

    • proficient in Kotlin
    • who appreciates the value of unit testing such stuff
    • with experience in business domain that could benefit from PlotAssert
    enhancement 
    opened by krzema12 1
  • For no-one sampling, samples are checked before and after min and max value

    For no-one sampling, samples are checked before and after min and max value

    For example, if a function is defined only between 0 and 1, and such visualization is created, the library should not evaluate the function before 0 and after 1.

    bug 
    opened by krzema12 0
Releases(0.4.0-beta)
Owner
Piotr Krzemiński
Piotr Krzemiński
Gha-central-test - GitHub Actions Maven Central Test

GitHub Actions Maven Central Test Pushing a tag does a release. Local Maven Depl

James Ward 1 Jan 19, 2022
A project that helps us generate the test project to test the Gradle plugin.

Ktlint Gradle Provides the function to generate a Gradle project for us to test your Gradle plugin Latest plugin version: [1.0.0] Table of content How

Jack Chen 5 Jul 20, 2022
Esito ambition is to be your return type for suspending functions.

Esito ambition is to be your return type for suspending functions.

null 58 Oct 21, 2022
Kotlin extensions, BindingAdapters, Composable functions for Android CameraX

Setup dependencies { implementation "com.github.skgmn:cameraxx:0.6.0" } Features CameraXX provides extensions methods for CameraX to use functions

null 12 Aug 9, 2022
Helper functions for making Approvals-Java more Kotlin friendly

Approvals-Kt Helper functions for making Approvals-Java more Kotlin-friendly Usage Verify using Approvals-Kt import com.github.greghynds.approvals.Kot

Greg Hynds 2 Oct 18, 2021
An annotation processor library that automatically creates Hilt's `@Binds` functions and modules.

HiltBinder An annotation processor library that automatically creates Hilt's @Binds functions and modules. If you think this library is useful, please

SangMin Park 5 Sep 19, 2022
A ksp library to automatically generate navigation functions for jetpack compose.

Compose/Navigation/Generator ⚠️ This library is still under development and not considered stable! Content Introduction Usage Example: Single destinat

Steffen Eckardt 4 Sep 13, 2022
🧮 Provides simple and advanced mathematical functions in a beautifully designed UI.

Calculator ?? Android App ?? Download the App ?? What is this App ✍️ This will basically provide simple and advanced mathematical functions in a beaut

Ayush Agnihotri 9 Jan 31, 2023
A funny project to help you test your BNF syntax

Readme The idea of this project is to implement a BNF expression compiler. We could use BNF to design some syntax like Arithmetic expression. <factor>

Jack Chen 4 Dec 21, 2022
Sample demonstrates use of Flow, StateFlow & how we can test Flow

FlowSample This sample demonstrates use of Flow, StateFlow & how we can test Flow. In Kotlin, Coroutine is just the scheduler part of RxJava but now w

null 0 Oct 24, 2021
API for a library using Kotlin, Spring-boot and covered by test

Library API This API is to create Books and be able to borrow from them I'm using: Spring Boot version 2.5.6 Kotlin 1.5.31 Java 11 I'm implementing us

Daniel Queiroz 1 Nov 5, 2021
Test task from AppSelect company

Test task from AppSelect company

Chapaev Anton 0 Nov 22, 2021
Simple App made for a test to Studio Sol Company

Studio Sol Test - Guess the Number Simple App made for a test to Studio Sol Company. #What you'll see in this project: ViewBinding Navigation Animatio

Philippe Muniz 1 Nov 19, 2021
Interview test for Kyosk interview

Kyosk-Android-Test A project done for the submission of my Kyosk interview application. Table Of Content. Project Structure - Domain - Data - Presenta

Kagiri Charles 6 Dec 4, 2021
Modular Android architecture which showcase Kotlin, MVVM, Navigation, Hilt, Coroutines, Jetpack compose, Retrofit, Unit test and Kotlin Gradle DSL.

SampleCompose Modular Android architecture which showcase Kotlin, MVVM, Navigation, Hilt, Coroutines, Jetpack compose, Retrofit, Unit test and Kotlin

Mohammadali Rezaei 7 Nov 28, 2022
A project that takes advantage of docker and makes the load test easier

Performance Test It's a project that takes advantage of docker and makes the load test easier. Also, it collects metrics from each running container.

jorge cabrera 1 Dec 9, 2021
kafka test with embedded kafka

kafka-test Requirements running Kafka on localhost:9092 How to use cat sampleuser.json | http POST localhost:9000/produce or use runConfiguration ./.r

null 0 Dec 9, 2021
🌱 A test implementation of a Minecraft server using RESTful API taking advantage of the interoperability between Kotlin and Java.

?? Norin A test implementation of a Minecraft server using RESTful API taking advantage of the interoperability between Kotlin and Java. This project

Gabriel 1 Jan 4, 2022
TestContainer & Spring Test sample repo

SpringBoot Integration-Test sample ?? Kotlin(1.6.10) + Spring Boot 2.6.2 + Testcontainers(PostgreSQL) + MyBatis + DbUnit + Spring Security + JWT auth

Hikaru Saito 1 Jan 9, 2022