-
-
Notifications
You must be signed in to change notification settings - Fork 64
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support "empty" arbitrary #335
Comments
Here's another case. If I split fun `add table`() =
frequencyOf(
1 to `add single table`(),
1 to `add multiple table`()
)
fun `add single table`() =
...
fun `add multiple table`() =
... // I wish this method could return emptyArbitrary that would be just ignored by frequencyOf above However, Of course, I could work around that by something like the below, however propagating @Suppress("UNCHECKED_CAST")
fun<T> emptyArbitrary(): Arbitrary<T> = EMPTY_ARBITRARY as Arbitrary<T>
fun <T> Arbitrary<T>.isEmpty() = this == EMPTY_ARBITRARY
fun <T> Arbitrary<T>.isNotEmpty() = !isEmpty()
fun <T> frequencyOfNonEmpty(vararg frequencies: Pair<Int, Arbitrary<out T>>): Arbitrary<T> =
frequencyOf(
*frequencies
.filter { it.second.isNotEmpty() }
.ifEmpty { return emptyArbitrary() }
.toTypedArray()
)
// plus the similar combineNonEmpty overloads |
I'm thinking of introducing an empty Arbitrary in jqwik2. The question I'm facing is: What guarantees would an arbitrary give to the property runner? A few options:
|
Testing Problem
See #134 (comment)
Similar case:
frequency(empty array)
fails withDiscussion
It might be helpful to explicitly support "empty arbitrary", so:
Pros:
Arbitraries.of(Collection)
acceptsemptyList()
just fineempty
arbitrary might be a reasonable return value for State-Dependent (Ad-Hoc) Action Generator #134 instead ofprecondition
to signal that the given action is not really applicable, and it yields zero possible transformations (==Arbitrary<Transformation<...>>
isempty
)Cons:
Arbitraries.of(emptyList())
is kind of hard to debug since the resulting arbitrary thows at the generation time only (seenet.jqwik.engine.properties.arbitraries.randomized.RandomGenerators#choose(java.util.List<U>)
) that happens at a completely different stacktraceFrankly speaking, I am inclined that explicit support for empty arbitraries would be preferable.
As "non-empty" arbitrary might often be needed, I believe, it might be nice to split "empty-related" methods in two flavours.
First of all, some methods will never return empty arbitraries:
Arbitraries.strings()
would be non-empty.On the other hand,
Arbitraries.of(collection)
,Arbitraries.of(array)
might be empty in case the input collection is empty.So it might be worth providing two methods in the API:
Arbitraries.of(collection)
. Return an arbitrary, or throw in case the collection is empty. That is basically the current method, and it matches the current behaviour.Arbitraries.ofOrEmpty(collection)
. Retrun an arbitrary if collection is non-empty, return "empty arbitrary" in case the collection is empty.This idea was inspired by
orNull
naming pattern in Kotlin: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/first-or-null.html.See https://twitter.com/VladimirSitnikv/status/1521899018112151553 , https://www.youtube.com/watch?v=NJjEFXeiuKY&t=58s&ab_channel=JetBrainsTV
However, if we follow
orEmpty
route, we might to addcombineOrEmpty
,Arbitrary.flatMapOrEmpty
, etc which might sound too invasive.Here's the case when I faced
frequency does not contain...
error.The meaning is as follows:
add table
is a transformer that would add a table to the stateHere's the trick: all the columns must be compatible with each other. All columns should be either "multiple" or "single". However, the gotcha is that
single
column needs at least onesingle
attribute in the state, andmultiple
column requires at least onemultiple
attribute in the model.So in order to generate
add table
transformer I query the list of existing types of attributes (e.g.SINGLE
orMULTIPLE
or both), and then I select which columns to create based on that.It turns out that
frequency(empty)
fails. However, if there are no attributes to support the table, I would prefer to skip add table altogether.The text was updated successfully, but these errors were encountered: