Skip to content
This repository has been archived by the owner on Aug 24, 2021. It is now read-only.

Commit

Permalink
feat: Add ExperimentalKwikApi annotation (#224)
Browse files Browse the repository at this point in the history
  • Loading branch information
jcornaz authored Oct 15, 2020
1 parent 4422e1a commit 6a629c3
Show file tree
Hide file tree
Showing 47 changed files with 235 additions and 220 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ jobs:

- name: Check Kwik
if: job.status == 'success' && matrix.java == 8
run: ./gradlew check
run: ./gradlew check -PwarningAsError

- name: Check example
if: job.status == 'success' && matrix.java == 8
Expand Down
9 changes: 4 additions & 5 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,11 @@ Make sure that the environment variable `JAVA_HOME` points to a JDK installation

This project uses [gradle](https://gradle.org/). Here are the most important tasks you may want to run:

* `./gradlew check` Build and test/check everything (Best first task for a fresh clone).
* `./gradlew test` Compile sources and run unit tests
* `./gradlew jvmTest` Compile sources and run unit tests in the JVM (Best first task for a fresh clone)
* `./gradlew check -PwarningAsError` Build and test/check everything
* `./gradlew sphinx` Generate documentation (result will be in `build/site/index.html`)
* `./gradlew detekt` Run a static code analysis and report code smells (may fail if too many code smells are found)


## Coding standard

Follow the [Kotlin conventions](https://kotlinlang.org/docs/reference/coding-conventions.html)
Expand All @@ -49,14 +48,14 @@ Run the static code analysis (`./gradlew detekt`) to get a reports of the code s
* Write automated tests covering the new feature or fix
* if you are not sure how to test your changes, open the pull request as Draft.
I'll gladly help you to write the tests.
* Make sure the build passes (run `./gradlew check`)
* Make sure the build passes (run `./gradlew check -PwarningAsError`)
* Write a description
* explain what problem is solved (with a reference to an existing issue if applicable)
* help to read and understand the code changes
* point parts that requires special attention or consideration
* Update documentation if necessary
* Documentation sources are in folder `docs`
* you can generate it locally with `./gradlew sphinx`
* locally generated documentation will be available in `build/site/index.html`
* the locally generated documentation will be available in `build/site/index.html`

In case you are not sure about something, it is better to open a pull request early (as a draft) and discuss it ;-)
1 change: 0 additions & 1 deletion ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,6 @@ The random generation would still be seeded. But the seed will only be configura

## Major tasks

* [ ] Mark the old API as Obsolete and remove experimental flag for the new API (#185)
* [ ] Introduce TestResult with a minimal api (#85)
* [ ] Provide a fuzzer API that can be used the same way as generator are currently used
* [ ] Provide decent support for input simplification (aka shrinking) (#62, #173, #174, #64)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.github.jcornaz.kwik

/**
* This annotation denotes Kwik's experimental API. It might not be complete,
* and there is a good change that breaking changes will be made in the future.
*/
@RequiresOptIn(
"""
This is highly experimental API. It might not be complete,
and there is a good change that breaking changes will be made in the future.
""",
level = RequiresOptIn.Level.WARNING
)
@Retention(AnnotationRetention.BINARY)
annotation class ExperimentalKwikApi
34 changes: 17 additions & 17 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ import com.jfrog.bintray.gradle.BintrayExtension
import com.jfrog.bintray.gradle.BintrayPlugin
import kr.motd.gradle.sphinx.gradle.SphinxTask
import org.codehaus.plexus.util.Os
import org.jetbrains.kotlin.gradle.dsl.KotlinCompile
import org.jetbrains.kotlin.gradle.dsl.KotlinJvmCompile
import java.util.Date

plugins {
Expand Down Expand Up @@ -55,10 +53,26 @@ subprojects {
apply<JavaPlugin>()

kotlin {
jvm()
jvm {
compilations.all {
kotlinOptions {
jvmTarget = "1.8"
}
}
}
linuxX64("linux")
mingwX64("windows")

@Suppress("SuspiciousCollectionReassignment")
targets.all {
compilations.all {
kotlinOptions {
allWarningsAsErrors = findProperty("warningAsError") != null
freeCompilerArgs += "-Xopt-in=kotlin.RequiresOptIn"
}
}
}

sourceSets {
commonTest {
dependencies {
Expand Down Expand Up @@ -139,20 +153,6 @@ subprojects {
}

tasks {
withType<KotlinCompile<*>> {
kotlinOptions {

@Suppress("SuspiciousCollectionReassignment")
freeCompilerArgs += "-Xopt-in=kotlin.RequiresOptIn"
}
}

withType<KotlinJvmCompile> {
kotlinOptions {
jvmTarget = "1.8"
}
}

val jvmTest by existing {
finalizedBy("jacocoTestReport")
}
Expand Down
1 change: 1 addition & 0 deletions docs/contents.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,5 @@ Welcome to Kwik's documentation!
write-tests
generators
operators
experimental-api
Github <https://github.com/jcornaz/kwik>
13 changes: 13 additions & 0 deletions docs/experimental-api.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
Experimental API
================

After using this library for a while, I started to work on a new iteration of the API.
Although being only a draft, the goal and design intent of the new API has been detailed on this roadmap_.

The whole kwik library should be considered as experimental. But this new API is even more bleeding edge, far from complete and
very likely to receive breaking changes. That is why this new API is marked with the ``@ExperimentalKwikApi`` annotation.

If you want to try it out, you can opt-in with ``@OptIn(ExperimentalApi``.
Alternatively you can or add ``-Xopt-in=com.github.jcornaz.kwik.ExperimentalKwiKApi`` to your compiler flags.

.. _roadmap: https://github.com/jcornaz/kwik/blob/main/ROADMAP.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package com.github.jcornaz.kwik.evaluator

import com.github.jcornaz.kwik.ExperimentalKwikApi
import com.github.jcornaz.kwik.fuzzer.api.Fuzzer
import com.github.jcornaz.kwik.generator.api.randomSequence
import com.github.jcornaz.kwik.fuzzer.api.ExperimentalKwikFuzzer
import com.github.jcornaz.kwik.fuzzer.api.simplifier.findSimplestFalsification
import com.github.jcornaz.kwik.generator.api.randomSequence


/**
Expand All @@ -17,7 +17,7 @@ import com.github.jcornaz.kwik.fuzzer.api.simplifier.findSimplestFalsification
* @param block Function invoked multiple times with random inputs to assess a property of the System under test.
* Must return a throw an exception if the property is falsified.
*/
@ExperimentalKwikFuzzer
@ExperimentalKwikApi
fun <T> forAny(
fuzzer: Fuzzer<T>,
iterations: Int = kwikDefaultIterations,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
package com.github.jcornaz.kwik.evaluator

import com.github.jcornaz.kwik.generator.api.Generator
import kotlin.random.Random
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertFailsWith
import kotlin.test.assertTrue

class CheckForAll1Test : AbstractRunnerTest() {

private val testGenerator = Generator { it: Random -> it.nextInt() }
private val testGenerator = Generator { it.nextInt() }

override fun evaluate(iterations: Int, seed: Long, invocation: PropertyEvaluationContext.() -> Boolean) {
checkForAll(testGenerator, iterations, seed) { assertTrue(invocation()) }
Expand All @@ -19,8 +18,8 @@ class CheckForAll1Test : AbstractRunnerTest() {
fun falsificationDisplayHelpfulMessage() {
val exception = assertFailsWith<FalsifiedPropertyError> {
var i = 0
checkForAll<Int>(
Generator { it: Random -> 42 },
checkForAll(
generator = { 42 },
iterations = 123,
seed = 78
) { assertTrue(++i < 12) }
Expand All @@ -47,7 +46,7 @@ class CheckForAll1Test : AbstractRunnerTest() {

@Test
fun isPredictable() {
val gen = Generator { it: Random -> it.nextInt() }
val gen = Generator { it.nextInt() }

val pass1 = mutableListOf<Int>()
val pass2 = mutableListOf<Int>()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
package com.github.jcornaz.kwik.evaluator

import com.github.jcornaz.kwik.generator.api.Generator
import kotlin.random.Random
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertFailsWith
import kotlin.test.assertTrue

class CheckForAll2Test : AbstractRunnerTest() {

private val testGenerator1 = Generator { it: Random -> it.nextInt() }
private val testGenerator2 = Generator { it: Random -> it.nextDouble() }
private val testGenerator1 = Generator { it.nextInt() }
private val testGenerator2 = Generator { it.nextDouble() }

override fun evaluate(iterations: Int, seed: Long, invocation: PropertyEvaluationContext.() -> Boolean) {
checkForAll(testGenerator1, testGenerator2, iterations, seed) { _, _ -> assertTrue(invocation()) }
Expand All @@ -21,8 +20,8 @@ class CheckForAll2Test : AbstractRunnerTest() {
val exception = assertFailsWith<FalsifiedPropertyError> {
var i = 0
checkForAll(
Generator { it: Random -> 42 },
Generator { it: Random -> -4.1 },
generatorA = { 42 },
generatorB = { -4.1 },
iterations = 123, seed = 78
) { _, _ ->
if (++i >= 12) error("failed")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
package com.github.jcornaz.kwik.evaluator

import com.github.jcornaz.kwik.generator.api.Generator
import kotlin.random.Random
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertFailsWith
import kotlin.test.assertTrue

class CheckForAll3Test : AbstractRunnerTest() {

private val testGenerator1 = Generator { it: Random -> it.nextInt() }
private val testGenerator2 = Generator { it: Random -> it.nextDouble() }
private val testGenerator3 = Generator { it: Random -> it.nextLong() }
private val testGenerator1 = Generator { it.nextInt() }
private val testGenerator2 = Generator { it.nextDouble() }
private val testGenerator3 = Generator { it.nextLong() }

override fun evaluate(iterations: Int, seed: Long, invocation: PropertyEvaluationContext.() -> Boolean) {
checkForAll(
Expand All @@ -28,9 +27,9 @@ class CheckForAll3Test : AbstractRunnerTest() {
val exception = assertFailsWith<FalsifiedPropertyError> {
var i = 0
checkForAll(
Generator { it: Random -> 42 },
Generator { it: Random -> -4.1 },
Generator { it: Random -> 100L },
generatorA = { 42 },
generatorB = { -4.1 },
generatorC = { 100L },
iterations = 123, seed = 78
) { _, _, _ ->
if (++i >= 12 ) error("failed")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,17 @@
package com.github.jcornaz.kwik.evaluator

import com.github.jcornaz.kwik.generator.api.Generator
import kotlin.random.Random
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertFailsWith
import kotlin.test.assertTrue

class CheckForAll4Test : AbstractRunnerTest() {

private val testGenerator1 = Generator { it: Random -> it.nextInt() }
private val testGenerator2 = Generator { it: Random -> it.nextDouble() }
private val testGenerator3 = Generator { it: Random -> it.nextLong() }
private val testGenerator4 = Generator { it: Random -> it.nextFloat() }
private val testGenerator1 = Generator { it.nextInt() }
private val testGenerator2 = Generator { it.nextDouble() }
private val testGenerator3 = Generator { it.nextLong() }
private val testGenerator4 = Generator { it.nextFloat() }

override fun evaluate(iterations: Int, seed: Long, invocation: PropertyEvaluationContext.() -> Boolean) {
checkForAll(
Expand All @@ -32,10 +31,10 @@ class CheckForAll4Test : AbstractRunnerTest() {
val exception = assertFailsWith<FalsifiedPropertyError> {
var i = 0
checkForAll(
Generator { it: Random -> 42 },
Generator { it: Random -> -4.1 },
Generator { it: Random -> 100L },
Generator { it: Random -> "hello world" },
generatorA = { 42 },
generatorB = { -4.1 },
generatorC = { 100L },
generatorD = { "hello world" },
iterations = 123, seed = 78
) { _, _, _, _ ->
if (++i >= 12) error("failed")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
package com.github.jcornaz.kwik.evaluator

import com.github.jcornaz.kwik.generator.api.Generator
import kotlin.random.Random
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertFailsWith
import kotlin.test.assertTrue

class ForAll1Test : AbstractRunnerTest() {

private val testGenerator = Generator { it: Random -> it.nextInt() }
private val testGenerator = Generator { it.nextInt() }

override fun evaluate(iterations: Int, seed: Long, invocation: PropertyEvaluationContext.() -> Boolean) {
forAll(testGenerator, iterations, seed) { invocation() }
Expand All @@ -19,8 +18,8 @@ class ForAll1Test : AbstractRunnerTest() {
fun falsificationDisplayHelpfulMessage() {
val exception = assertFailsWith<FalsifiedPropertyError> {
var i = 0
forAll<Int>(
Generator { it: Random -> 42 },
forAll(
generator = { 42 },
iterations = 123,
seed = 78
) { ++i < 12 }
Expand All @@ -41,7 +40,7 @@ class ForAll1Test : AbstractRunnerTest() {
var iterations = 0

forAll(
Generator { it: Random -> ++iterations },
generator = { ++iterations },
iterations = 10
) { x ->
ensureAtLeastOne { x >= 100 }
Expand All @@ -56,7 +55,7 @@ class ForAll1Test : AbstractRunnerTest() {
var iterations = 0

forAll(
Generator { it: Random -> ++iterations },
generator = { ++iterations },
iterations = 10
) { x ->
ensureAtLeastOne { x >= 100 }
Expand All @@ -72,7 +71,7 @@ class ForAll1Test : AbstractRunnerTest() {
var iterations = 0

forAll(
Generator { it: Random -> ++iterations },
generator = { ++iterations },
iterations = 10
) { x ->
ensureAtLeastOne { x >= 10 }
Expand All @@ -88,7 +87,7 @@ class ForAll1Test : AbstractRunnerTest() {
var iteration = 0

forAll(
Generator { it: Random -> 42 },
generator = { 42 },
iterations = 123
) { x ->
++iteration
Expand All @@ -104,7 +103,7 @@ class ForAll1Test : AbstractRunnerTest() {
var iteration = 0
val exception = assertFailsWith<FalsifiedPropertyError> {
forAll(
Generator { it: Random -> 42 },
generator = { 42 },
iterations = 123,
seed = 78
) { x ->
Expand All @@ -129,8 +128,8 @@ class ForAll1Test : AbstractRunnerTest() {
fun errorDisplayHelpfulMessage() {
val exception = assertFailsWith<FalsifiedPropertyError> {
var i = 0
forAll<Int>(
Generator { it: Random -> 42 },
forAll(
generator = { 42 },
iterations = 123,
seed = 78
) {
Expand Down Expand Up @@ -163,7 +162,7 @@ class ForAll1Test : AbstractRunnerTest() {

@Test
fun isPredictable() {
val gen = Generator { it: Random -> it.nextInt() }
val gen = Generator { it.nextInt() }

val pass1 = mutableListOf<Int>()
val pass2 = mutableListOf<Int>()
Expand Down
Loading

0 comments on commit 6a629c3

Please sign in to comment.