Giter Club home page Giter Club logo

vis-assert's Introduction

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.

vis-assert's People

Contributors

krzema12 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

vis-assert's Issues

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

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/

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.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.