Closed SimY4 closed 1 year ago
I just tried this successfully with the latest version of jqwik (openjdk 17):
interface EqualityContract<T> {
@Property
@Report(Reporting.GENERATED)
default boolean reflexivityEq(@ForAll("anyT") T value) {
return Objects.equals(value, value);
}
Arbitrary<T> anyT();
}
class MyTypeTest implements EqualityContract<MyType> {
@Provide("anyT")
public Arbitrary<MyType> anyT() {
return Arbitraries.strings().alpha().map(MyType::new);
}
}
class MyType {
private final String name;
MyType(String name) {
this.name = name;
}
@Override
public String toString() {
return "My(" + name + ")";
}
}
Maybe an old version is loaded somehow? Or Java version has an influence?
@jlink Sorry, getting more details as I look into this problem more. My simplified example is not representable and in reality was a bit more nuanced:
interface EqualityContract<T> {
@Property
default boolean reflexivityEq(@ForAll("anyT") T value) {
return Objects.equals(value, value);
}
Arbitrary<T> anyT();
}
interface ComparableContract<T extends Comparable<? super T>> extends EqualityContract<T> {}
class MyTypeTest implements ComparableContract<String> {
@Provide("anyT")
Arbitrary<String> anyT() { return Arbitraries.strings(); }
}
Still seems to work with the extended contract. I assume something else is going on.
@jlink It's yet another weird one... If I try to debug it and stall an execution it'll pass for me too. But running a test in a class would make it fail 100% of time on my machine. This makes me wonder where this race could come from. 🤔
In my case, I see that CachingArbitraryResolver
cached the value of an empty set for my type parameter. But if I stall it on compute if absent it'll return 5 arbitraries.
Maybe you can set up a repo that I can use to replicate the problem.
Found minimal example that breaks:
interface A<T> {
@Property
default boolean test1(@ForAll("anyT") T t) {
return true;
}
Arbitrary<T> anyT();
}
interface B<T extends Comparable<? super T>> extends A<T> {
@Property
default boolean test2(@ForAll("anyT") T t) {
return true;
}
}
interface MyType extends Comparable<MyType> { }
interface C<T extends MyType> extends B<T> {
@Property
default boolean test3(@ForAll("anyT") T t) {
return true;
}
}
class MyRecord implements MyType {
@Override
public int compareTo(MyType o) {
return 0;
}
}
public class Test implements C<MyRecord> {
@Provide("anyT")
@Override
public Arbitrary<MyRecord> anyT() {
return Arbitraries.of(new MyRecord());
}
}
@SimY4 Have you seen this work in older versions of jqwik?
@jlink Yeah, it works on 1.7.4 but it could be by chance. IDK...
@SimY4 Sorry for the delay. I can reproduce. Looks like a bug. Will try to dive into it in the week to come.
@jlink no problem. Thank you for looking into this
Fix released in 1.8.1-SNAPSHOT
Awesome work! Thank you.🙏
@SimY4 Do you want to update to 1.8? In that case I could publish 1.8.1 soon.
@jlink i did check the 1.8.1 snapshot on my project. Worked great, no problems detected, all tests are green. 😀
1.8.1 has been released
Testing Problem
fails with: