diff --git a/fuzzer/api/src/commonMain/kotlin/com/github/jcornaz/kwik/fuzzer/api/FuzzerFactory.kt b/fuzzer/api/src/commonMain/kotlin/com/github/jcornaz/kwik/fuzzer/api/FuzzerFactory.kt
index 028c55b2..4f9e4190 100644
--- a/fuzzer/api/src/commonMain/kotlin/com/github/jcornaz/kwik/fuzzer/api/FuzzerFactory.kt
+++ b/fuzzer/api/src/commonMain/kotlin/com/github/jcornaz/kwik/fuzzer/api/FuzzerFactory.kt
@@ -4,7 +4,6 @@ import com.github.jcornaz.kwik.ExperimentalKwikApi
import com.github.jcornaz.kwik.fuzzer.api.simplifier.Simplifier
import com.github.jcornaz.kwik.fuzzer.api.simplifier.pair
import com.github.jcornaz.kwik.fuzzer.api.simplifier.triple
-import com.github.jcornaz.kwik.generator.api.Generator
import com.github.jcornaz.kwik.generator.api.combineWith
import kotlin.random.Random
@@ -21,6 +20,13 @@ public fun Arbitrary.pair(first: Fuzzer, second: Fuzzer): Fuzzer Arbitrary.pair(fuzzer: Fuzzer): Fuzzer> =
+ pair(fuzzer, fuzzer)
+
/**
* Returns a [Fuzzer] for triple of [A], [B] and [C].
*
@@ -31,7 +37,7 @@ public fun Arbitrary.pair(first: Fuzzer, second: Fuzzer): Fuzzer Arbitrary.triple(first: Fuzzer, second: Fuzzer, third: Fuzzer): Fuzzer> =
Fuzzer(
- generator = Generator { random: Random ->
+ generator = { random: Random ->
Triple(
first.generator.generate(random),
second.generator.generate(random),
@@ -40,3 +46,10 @@ public fun Arbitrary.triple(first: Fuzzer, second: Fuzzer, third
},
simplifier = Simplifier.triple(first.simplifier, second.simplifier, third.simplifier)
)
+
+/**
+ * Returns a [Fuzzer] for triple, using [fuzzer] for all elements.
+ */
+@ExperimentalKwikApi
+public fun Arbitrary.triple(fuzzer: Fuzzer): Fuzzer> =
+ triple(fuzzer, fuzzer, fuzzer)
diff --git a/fuzzer/api/src/commonMain/kotlin/com/github/jcornaz/kwik/fuzzer/api/simplifier/SimplifierFactory.kt b/fuzzer/api/src/commonMain/kotlin/com/github/jcornaz/kwik/fuzzer/api/simplifier/SimplifierFactory.kt
index 04cd6ad9..8a46654c 100644
--- a/fuzzer/api/src/commonMain/kotlin/com/github/jcornaz/kwik/fuzzer/api/simplifier/SimplifierFactory.kt
+++ b/fuzzer/api/src/commonMain/kotlin/com/github/jcornaz/kwik/fuzzer/api/simplifier/SimplifierFactory.kt
@@ -25,6 +25,15 @@ public fun Simplifier.Companion.pair(
}
}
+/**
+ * Create a [Simplifier] that can simplify pairs using [simplifier] for both elements of the pair.
+ *
+ * This is essentially an alias for `Simplifier.pair(simplifier, simplifier)`
+ */
+@ExperimentalKwikApi
+public fun Simplifier.Companion.pair(simplifier: Simplifier): Simplifier> =
+ pair(simplifier, simplifier)
+
/**
* Create a [Simplifier] that can simplify triples.
*
@@ -51,3 +60,12 @@ public fun Simplifier.Companion.triple(
}
}
}
+
+/**
+ * Create a [Simplifier] that can simplify triples using [simplifier] for all elements of the triple.
+ *
+ * This is essentially an alias for `Simplifier.triple(simplifier, simplifier, simplifier)`
+ */
+@ExperimentalKwikApi
+public fun Simplifier.Companion.triple(simplifier: Simplifier): Simplifier> =
+ triple(simplifier, simplifier, simplifier)
diff --git a/fuzzer/api/src/commonTest/kotlin/com/github/jcornaz/kwik/fuzzer/api/FuzzerPairTest.kt b/fuzzer/api/src/commonTest/kotlin/com/github/jcornaz/kwik/fuzzer/api/FuzzerPairTest.kt
index 67b46484..f35b160f 100644
--- a/fuzzer/api/src/commonTest/kotlin/com/github/jcornaz/kwik/fuzzer/api/FuzzerPairTest.kt
+++ b/fuzzer/api/src/commonTest/kotlin/com/github/jcornaz/kwik/fuzzer/api/FuzzerPairTest.kt
@@ -40,4 +40,17 @@ class FuzzerPairTest {
assertEquals(listOf(3 to 50, 10 to 42), pair.simplifier.simplify(10 to 50).toList())
}
-}
\ No newline at end of file
+
+ @Test
+ fun canCreatePairWithSingleItemFuzzer() {
+ val itemFuzz = Generator.of(1).toFuzzer { sequenceOf(it - 1) }
+ assertEquals(
+ Arbitrary.pair(itemFuzz).generator.generate(Random(0)),
+ Arbitrary.pair(itemFuzz, itemFuzz).generator.generate(Random(0))
+ )
+ assertEquals(
+ Arbitrary.pair(itemFuzz).simplifier.simplify(2 to 3).toList(),
+ Arbitrary.pair(itemFuzz, itemFuzz).simplifier.simplify(2 to 3).toList()
+ )
+ }
+}
diff --git a/fuzzer/api/src/commonTest/kotlin/com/github/jcornaz/kwik/fuzzer/api/FuzzerTripleTest.kt b/fuzzer/api/src/commonTest/kotlin/com/github/jcornaz/kwik/fuzzer/api/FuzzerTripleTest.kt
index 0068146b..fc53af31 100644
--- a/fuzzer/api/src/commonTest/kotlin/com/github/jcornaz/kwik/fuzzer/api/FuzzerTripleTest.kt
+++ b/fuzzer/api/src/commonTest/kotlin/com/github/jcornaz/kwik/fuzzer/api/FuzzerTripleTest.kt
@@ -53,4 +53,19 @@ class FuzzerTripleTest {
pair.simplifier.simplify(Triple(10, 20, 30)).toList()
)
}
+
+ @Test
+ fun canCreatePairWithSingleItemFuzzer() {
+ val itemFuzz = Generator.of(1).toFuzzer { sequenceOf(it - 1) }
+ assertEquals(
+ Arbitrary.triple(itemFuzz).generator.generate(Random(0)),
+ Arbitrary.triple(itemFuzz, itemFuzz, itemFuzz).generator.generate(Random(0))
+ )
+ assertEquals(
+ Arbitrary.triple(itemFuzz).simplifier
+ .simplify(Triple(1, 2, 3)).toList(),
+ Arbitrary.triple(itemFuzz, itemFuzz, itemFuzz).simplifier
+ .simplify(Triple(1, 2, 3)).toList()
+ )
+ }
}
diff --git a/fuzzer/api/src/commonTest/kotlin/com/github/jcornaz/kwik/fuzzer/api/simplifier/PairTest.kt b/fuzzer/api/src/commonTest/kotlin/com/github/jcornaz/kwik/fuzzer/api/simplifier/PairTest.kt
index ea0fcfaa..4f9900f8 100644
--- a/fuzzer/api/src/commonTest/kotlin/com/github/jcornaz/kwik/fuzzer/api/simplifier/PairTest.kt
+++ b/fuzzer/api/src/commonTest/kotlin/com/github/jcornaz/kwik/fuzzer/api/simplifier/PairTest.kt
@@ -1,6 +1,8 @@
package com.github.jcornaz.kwik.fuzzer.api.simplifier
import com.github.jcornaz.kwik.ExperimentalKwikApi
+import kotlin.random.Random
+import kotlin.random.nextUInt
import kotlin.test.Test
import kotlin.test.assertEquals
@@ -33,6 +35,19 @@ class PairTest {
)
}
+ @Test
+ fun canUseSameSimplifierForBothElements() {
+ val itemSimplifier = Simplifier { it: Int -> if (it > 0) sequenceOf(it - 1) else emptySequence() }
+
+ repeat(100) {
+ val initialValue = Random.nextInt(0, 5) to Random.nextInt(0, 5)
+ assertEquals(
+ Simplifier.pair(itemSimplifier).simplify(initialValue).toList(),
+ Simplifier.pair(itemSimplifier, itemSimplifier).simplify(initialValue).toList(),
+ )
+ }
+ }
+
@Test
fun returnEmptySequenceIfBothHaveNoSimplerValue() {
val pair = Simplifier.pair(
diff --git a/fuzzer/api/src/commonTest/kotlin/com/github/jcornaz/kwik/fuzzer/api/simplifier/TripleTest.kt b/fuzzer/api/src/commonTest/kotlin/com/github/jcornaz/kwik/fuzzer/api/simplifier/TripleTest.kt
index c5ae9d75..f77d04c2 100644
--- a/fuzzer/api/src/commonTest/kotlin/com/github/jcornaz/kwik/fuzzer/api/simplifier/TripleTest.kt
+++ b/fuzzer/api/src/commonTest/kotlin/com/github/jcornaz/kwik/fuzzer/api/simplifier/TripleTest.kt
@@ -1,6 +1,7 @@
package com.github.jcornaz.kwik.fuzzer.api.simplifier
import com.github.jcornaz.kwik.ExperimentalKwikApi
+import kotlin.random.Random
import kotlin.test.Test
import kotlin.test.assertEquals
@@ -37,6 +38,18 @@ class TripleTest {
)
}
+ @Test
+ fun canUseSameSimplifierForAllElements() {
+ val itemSimplifier = Simplifier { it: Int -> if (it > 0) sequenceOf(it - 1) else emptySequence() }
+
+ repeat(100) {
+ val initialValue = Triple(Random.nextInt(0, 5), Random.nextInt(0, 5), Random.nextInt(0, 5))
+ assertEquals(
+ Simplifier.triple(itemSimplifier).simplify(initialValue).toList(),
+ Simplifier.triple(itemSimplifier, itemSimplifier, itemSimplifier).simplify(initialValue).toList(),
+ )
+ }
+ }
@Test
fun returnEmptySequenceIfNoneHaveSimplerValue() {
diff --git a/generator/api/src/commonMain/kotlin/com/github/jcornaz/kwik/generator/api/GeneratorCombination.kt b/generator/api/src/commonMain/kotlin/com/github/jcornaz/kwik/generator/api/GeneratorCombination.kt
index 6c3131a4..0c8b2c0e 100644
--- a/generator/api/src/commonMain/kotlin/com/github/jcornaz/kwik/generator/api/GeneratorCombination.kt
+++ b/generator/api/src/commonMain/kotlin/com/github/jcornaz/kwik/generator/api/GeneratorCombination.kt
@@ -32,13 +32,29 @@ public fun Generator.Companion.combine(
CombinedGenerators(generator1, generator2, transform)
/**
- * Returns a generator of combining the elements of [generator1] and [generator2]
+ * Returns a generator of pairs using [generator1] (for the left) and [generator2] (for the right)
*/
+@Deprecated("Use pair instead", ReplaceWith("pair(generator1, generator2)"))
public fun Generator.Companion.combine(
generator1: Generator,
generator2: Generator
): Generator> =
- combine(generator1, generator2, ::Pair)
+ pair(generator1, generator2)
+
+/**
+ * Returns a generator of pairs using [leftGen] and [rightGen]
+ */
+public fun Generator.Companion.pair(
+ leftGen: Generator,
+ rightGen: Generator
+): Generator> =
+ combine(leftGen, rightGen, ::Pair)
+
+/**
+ * Returns a generator of pairs using the same [generator] for left and right elements.
+ */
+public fun Generator.Companion.pair(generator: Generator): Generator> =
+ pair(generator, generator)
private class CombinedGenerators(
private val generator1: Generator,
diff --git a/generator/api/src/commonTest/kotlin/com/github/jcornaz/kwik/generator/api/CombineTest.kt b/generator/api/src/commonTest/kotlin/com/github/jcornaz/kwik/generator/api/CombineTest.kt
index 59028d33..0f300d53 100644
--- a/generator/api/src/commonTest/kotlin/com/github/jcornaz/kwik/generator/api/CombineTest.kt
+++ b/generator/api/src/commonTest/kotlin/com/github/jcornaz/kwik/generator/api/CombineTest.kt
@@ -1,15 +1,16 @@
package com.github.jcornaz.kwik.generator.api
import com.github.jcornaz.kwik.generator.test.AbstractGeneratorTest
-import kotlin.random.Random
import kotlin.test.Test
+import kotlin.test.assertEquals
import kotlin.test.assertTrue
+@Suppress("DEPRECATION")
class CombineTest : AbstractGeneratorTest() {
override val generator: Generator<*> = Generator.combine(
- Generator { it: Random -> it.nextInt() },
- Generator { it: Random -> it.nextDouble() }
+ { it.nextInt() },
+ { it.nextDouble() }
)
@Test
@@ -20,20 +21,53 @@ class CombineTest : AbstractGeneratorTest() {
@Test
fun combineDifferentValues() {
val gen = Generator.combine(
- Generator { it: Random -> it.nextInt() },
- Generator { it: Random -> it.nextInt() }
+ { it.nextInt() },
+ { it.nextInt() }
)
assertTrue(gen.randomSequence(123).take(200).count { (a, b) -> a != b } > 150)
}
}
+class PairTest : AbstractGeneratorTest() {
+
+ override val generator: Generator<*> = Generator.pair(
+ { it.nextInt() },
+ { it.nextDouble() }
+ )
+
+ @Test
+ fun combineTheValues() {
+ assertTrue(generator.randomSequence(0).take(200).distinct().count() > 190)
+ }
+
+ @Test
+ fun combineDifferentValues() {
+ val gen = Generator.pair(
+ { it.nextInt() },
+ { it.nextInt() }
+ )
+
+ assertTrue(gen.randomSequence(123).take(200).count { (a, b) -> a != b } > 150)
+ }
+
+ @Test
+ fun canUseSameGeneratorForBothElements() {
+ val itemGen = Generator { it.nextInt() }
+
+ assertEquals(
+ Generator.pair(itemGen).randomSequence(0).take(100).toList(),
+ Generator.pair(itemGen, itemGen).randomSequence(0).take(100).toList()
+ )
+ }
+}
+
class CombineWithTransformTest : AbstractGeneratorTest() {
override val generator: Generator<*> =
Generator.combine(
- Generator { it: Random -> it.nextInt() },
- Generator { it: Random -> it.nextDouble() }
+ { it.nextInt() },
+ { it.nextDouble() }
) { x, y -> CombinedValues(x, y) }
@Test
@@ -44,8 +78,8 @@ class CombineWithTransformTest : AbstractGeneratorTest() {
@Test
fun combineDifferentValues() {
val gen = Generator.combine(
- Generator { it: Random -> it.nextInt() }.withSamples(1, 2),
- Generator { it: Random -> it.nextDouble() }.withSamples(3.0, 4.0)
+ Generator { it.nextInt() }.withSamples(1, 2),
+ Generator { it.nextDouble() }.withSamples(3.0, 4.0)
) { a, b -> CombinedValues(a, b) }
assertTrue(gen.randomSequence(0).take(200).count { (a, b) -> a != b.toInt() } > 150)
@@ -57,7 +91,7 @@ class CombineWithTransformTest : AbstractGeneratorTest() {
class CombineWithTest : AbstractGeneratorTest() {
override val generator: Generator<*> =
- Generator { it: Random -> it.nextInt() }.combineWith(Generator { it: Random -> it.nextDouble() })
+ Generator { it.nextInt() }.combineWith { it.nextDouble() }
@Test
fun combineTheValues() {
@@ -66,7 +100,7 @@ class CombineWithTest : AbstractGeneratorTest() {
@Test
fun combineDifferentValues() {
- val gen = Generator { it: Random -> it.nextInt() }.combineWith(Generator { it: Random -> it.nextInt() })
+ val gen = Generator { it.nextInt() }.combineWith { it.nextInt() }
assertTrue(gen.randomSequence(123).take(200).count { (a, b) -> a != b } > 150)
}
@@ -75,8 +109,8 @@ class CombineWithTest : AbstractGeneratorTest() {
class CombineWithWithTransformTest : AbstractGeneratorTest() {
override val generator: Generator<*> =
- Generator { it: Random -> it.nextInt() }
- .combineWith(Generator { it: Random -> it.nextDouble() }) { x, y ->
+ Generator { it.nextInt() }
+ .combineWith({ it.nextDouble() }) { x, y ->
CombinedValues(
x,
y
@@ -90,8 +124,8 @@ class CombineWithWithTransformTest : AbstractGeneratorTest() {
@Test
fun combineDifferentValues() {
- val gen = Generator { it: Random -> it.nextInt() }
- .combineWith(Generator { it: Random -> it.nextInt() }) { a, b -> a to b }
+ val gen = Generator { it.nextInt() }
+ .combineWith({ it.nextInt() }) { a, b -> a to b }
assertTrue(gen.randomSequence(123).take(200).count { (a, b) -> a != b } > 150)
}