Skip to content
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

Kotlin interoperability #52

Closed
tmohme opened this Issue Mar 26, 2019 · 7 comments

Comments

Projects
None yet
2 participants
@tmohme
Copy link
Contributor

tmohme commented Mar 26, 2019

Testing Problem

In Kotlin we want to express something like this:

@Property
fun myTest(@ForAll bigDecimals : List<BigDecimal>) {...}

which is (almost) the equivalent to the following Java code:

@Property
void myTest(@ForAll List<BigDecimal> bigDecimals) {...}

What looks easy and works out of the box with Java produces a net.jqwik.api.CannotFindArbitraryException: Cannot find an Arbitrary for Parameter of type [@net.jqwik.api.ForAll(value=) List<? extends BigDecimal>] with Kotlin.
The difference is obviously the type signature which for Java is List<BigDecimal> while it is List<? extends BigDecimal> for Kotlin.
Due to this little difference, the BigDecimalArbitraryProvider decides that he is unable to provide values for the given targetType.

Suggested Solution

The BigDecimalArbitraryProvider could use the more forgivingtargetType.isAssignableFrom(BigDecimal.class) instead of the stricter targetType.isOfType(BigDecimal.class) to determine if he is able to provide the requested values.
The same applies to some of the other *ArbitraryProviders.
Interestingly, currently not all *ArbitraryProviders are structured the same.
While the providers for BigDecimal and BigInteger use isOfType(...) others (like Boolean, Integer, ...) use isAssignableFrom(...).

Discussion

We tried to get around this by creating our own provider for BigDecimals, but experienced problems in the aftermath when we had trouble to let our provider correctly work with jqwik constraint annotations (like @BigRange). Probably we are missing some knowledge here . . .

@jlink

This comment has been minimized.

Copy link
Owner

jlink commented Mar 26, 2019

There’s indeed some inconsistency about how built-in arbitrary providers match types. I‘ll have a look at it.

@jlink

This comment has been minimized.

Copy link
Owner

jlink commented Mar 26, 2019

Fixed in 22af655

Available in 1.1.2-SNAPSHOT

@jlink

This comment has been minimized.

Copy link
Owner

jlink commented Mar 26, 2019

@tmohme Your approach with registering your own provider should also work. @BigRange should be applicable as long as your own provider will create instances of type BigDecimalArbitrary or BigIntegerArbitrary respectively. If you want I can have a look at that code to see what the problem is.

@jlink jlink closed this Mar 26, 2019

@jlink

This comment has been minimized.

Copy link
Owner

jlink commented Mar 26, 2019

I'm wondering in what situations Kotlin produces the generic subtype, though. Might lead to quite a few type matching problems in various situations...

@tmohme

This comment has been minimized.

Copy link
Contributor Author

tmohme commented Mar 27, 2019

Fixed in 22af655

Thx for the super fast reaction :)

Your approach with registering your own provider should also work.

Thx for the hint and your offer. As I already wrote, we were probably missing some knowledge (and persistence) here.
Next time we stumble upon some problems, we'll delve a bit deeper into the subject.
No need for you to invest your time when we are just too lazy to do our homework ;)

I'm wondering in what situations Kotlin produces the generic subtype, though.

I'll play a bit with IntelliJ's Kolin byte-code viewer tomorrow . . . maybe I find out something useful.

@tmohme

This comment has been minimized.

Copy link
Contributor Author

tmohme commented Apr 2, 2019

I'm wondering in what situations Kotlin produces the generic subtype, though. Might lead to quite a few type matching problems in various situations...

Just found out that you can use @JvmSuppressWildcards(suppress = true) on the test method to avoid this problem.
With this annotation in place the described problem does not exist.

@jlink

This comment has been minimized.

Copy link
Owner

jlink commented Apr 2, 2019

The change is more consistent anyway, And already deployed in 1.1.2. But good to know a workaround exists for future problems.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.