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

Kluent 2.0 Roadmap #75

Closed
MarkusAmshove opened this issue Nov 1, 2017 · 33 comments
Closed

Kluent 2.0 Roadmap #75

MarkusAmshove opened this issue Nov 1, 2017 · 33 comments
Projects
Milestone

Comments

@MarkusAmshove
Copy link
Owner

MarkusAmshove commented Nov 1, 2017

I'd like to open a discussion about what we should do and drop with the next major version of Kluent.
@javatarz did a lot of work to make Kluent independent of JUnit (and specific test runners in general), thanks for that!

During those PRs (#71 #72) we started a discussion about what we could do and what we could drop with the next major version.
I would love to have a lot of feedback and opinions here :)
We should atleast give @Egorand , @eburke56 , @javatarz, @guenhter and @goreRatzete a chance to state their opinions here 👍

Dropping support

Mocking

#73 Is already a proposal to drop the mocking features in Kluent. I do agree with @Egorand points and I think it fits into the "no opinion" discussion. If we don't want to force an opinion on a test runner, we also shouldn't do that on mocking. In the beginning of Kluent I started the mocking support with plain java Mockito which didn't work out really well. Later we transitioned to mockito-kotlin and kept our API backwards compatible, but it still doesn't feel great. Kluent doesn't support all kinds of features that a mocking framework is bringing in and it also led to a lot of confusion (#62).

I can see multiple ways of doing this. We could either deprecate mocking in the next 1.x version and drop it completely in 2.x, don't deprecate it (as in keep as it is) in 1.x and drop it in 2.x or also maintain it in 2.x.

Platform independence

Since Kotlin already supports other targets than the JVM (e.g. JavaScript) and more platforms are being worked on (Kotlin native) we could try to take this next major step to also be platform independent.

What that means is that we get rid of all external dependencies (e.g. JUnit) and only use builtin Kotlin functionality.
@javatarz already experimented this within #72 and could give some insights on this.
What we do need if we go into this direction is having tests builtin for each platform, to make sure we don't break anything.

Even if we can get rid of our Java dependencies, we still have dependencies on the Java library, because we do have assertions for java.time.* and java.io.File. I'm not sure if we can be completely platform independent (as in Kotlin platforms) with just maintaining one project.
Having only one core artifact for the Kotlin stdlib and then platform specific assertions (dependent on the core artifact) for Java specific stuff, Android specific stuff and so on, aggregated into one Github organization, might be better in the future.

Android

I also see Android as a kind of another platform, because we are locked in Java 1.6 there. @eburke56 has already contributed logic into our buildsystem so that we can have a specific artifact for Android (e.g. no backtick names). I would definitely want to support Android further.

@javatarz
Copy link
Contributor

javatarz commented Nov 1, 2017

If we want Kluent to be truly platform independent, can we split out the JVM specific dependencies into a new library called kluent-jvm (and possibily kluent-jvm-android)?

What you end up with is

  1. kluent (v2)
  • Contains pure kotlin assertions
  • Useful for Kotlin on JVM, JS and Native
  1. kluent-jvm
  • Contains kluent
  • Adds JVM specific assertions (such as java.time.* and java.io.File)
  • Adds Android specific support (by removing backtick notations and ensuring JVM 1.6 compatibility)

We could go ahead and make the changes that you're outlining in kluent v2 and later start a JVM specific project. It's important to note that until we create kluent-jvm, in most cases existing projects would find it really hard to move to the latest version.

PS: If you're looking for contributors/maintainers for future work, I'd be happy to help :)

@Egorand
Copy link
Collaborator

Egorand commented Nov 2, 2017

A few points I wanted to add:

  • To avoid confining the JVM flavor of the library to Java 6, we can split out kluent-jvm and kluent-android, the latter targeting Java 6, and the former targeting Java 8 (or Java 9)
  • Kotlin 1.2 comes with the support for multiplatform projects, I think that would be a good, future-proof solution for Kluent. Since Kotlin 1.2 is currently in beta, if we decide to go this way, we'd also need to keep Kluent 2 in beta until Kotlin 1.2 is out

@javatarz javatarz mentioned this issue Nov 2, 2017
@javatarz
Copy link
Contributor

javatarz commented Nov 2, 2017

Having put some more thought into this, can we rename kluent-android to kluent-jvm-6 because that's what it is?

I haven't worked on android in a while but if you're on a brand new project targeting newer devices, wouldn't you be able to use JVM 7/8 with newer versions of Kotlin? If that's true, wouldn't you be able to use kluent-jvm instead (because kluent-jvm-6/kluent-android is simply a subset of kluent-jvm).

What do you think @Egorand?

@MarkusAmshove
Copy link
Owner Author

I haven't written an Android app myself, but if there are some specific assertions we can add to make testing Android easier it could make kluent-android valuable.
Think about testing Activities etc.
Maybe some android devs can give us more insight on this :)

@Egorand
Copy link
Collaborator

Egorand commented Nov 3, 2017

@javatarz That's right, current tooling would allow you to use Java 8 features through desugaring, so theoretically a project that uses those features should be able to run kluent-jvm. However, best practice at the moment is to keep supporting Java 6, as I'm sure there's a lot of projects in the wild that drag behind on the tooling integration.

@MarkusAmshove I like the idea. I guess we can go with both kotlin-jvm-6 and kotlin-android: the former still brings value, imagine a pure Kotlin module that is built specifically to support an Android app and doesn't have the Android dependency itself.

@javatarz
Copy link
Contributor

javatarz commented Nov 3, 2017

I guess we can go with both kotlin-jvm-6 and kotlin-android: the former still brings value, imagine a pure Kotlin module that is built specifically to support an Android app and doesn't have the Android dependency itself.
Do you mean kotlin-android will have the Android specific dependencies? Wouldn't a pure kotlin module suffice?

Project Structure

kluent-parent
┌─ kluent
├─ kluent-jvm-6
└─ samples
   ├─ android-project
   ├─ kotlin-jvm-6-project
   └─ kotlin-jvm-8-project

Where

  1. main codebase would be in kluent-parent/kluent
  2. the samples projects can be used for testing on travis and would ensure that we've not added dependencies that cause problems in android builds

@MarkusAmshove
Copy link
Owner Author

I'm at the moment trying to rearrange the structure to match the KotlinConf-App and see how it works out :)
It is using Kotlin 1.2 RC then, which means we would have to wait for a stable release before we can push out Kluent 2.0. But this means also that we have some time to figure it all out ;)

@Egorand
Copy link
Collaborator

Egorand commented Nov 7, 2017

@MarkusAmshove Nice! Kluent 2.0 can also go Beta until Kotlin 1.2 becomes stable

@MarkusAmshove
Copy link
Owner Author

MarkusAmshove commented Nov 9, 2017

Sure, beta is something we should aim for until stable ;-)

I'm not sure how to do the unittests in the "common" project. All our tests are written with Spek (which I found a hint for that they'll support multi platform with 2.0), but the common project shouldn't have a dependency on Java.
I ported one test class to kotlin.test (like in kotlinconf app) but couldn't find a way to run them.

The way it should work (in my opinion) is that the concrete platform projects take the tests from common and run them under their platform, which would make sure that all tests pass on all platforms

@Egorand
Copy link
Collaborator

Egorand commented Nov 9, 2017

@MarkusAmshove have you tried running the tests from cli? IDE support may not be ideal at the moment, I think I had problems running common unit tests from IDE in one of multiplatform projects.

@MarkusAmshove
Copy link
Owner Author

MarkusAmshove commented Nov 9, 2017 via email

@javatarz
Copy link
Contributor

Wonder if bintray has space for beta releases of some sort. It'd be nice to get a few builds out for us to try out on some of our projects where using a beta doesn't hurt :)

@MarkusAmshove
Copy link
Owner Author

MarkusAmshove commented Nov 10, 2017

I've figured out how to get the tests running. It is as @Egorand said, the common project uses kotlin.test and the platform projects run those tests with their runner (e.g. junit on the jvm project).

This means we have to port all the common-lib tests 😨

Spek Milestones state that they "prepare" multiplatform support, maybe thats what we need for the common project

Edit:

I've opened an issue at Spek spekframework/spek#327 to get clarification if we need to port all tests or have to wait for Spek :)

@MarkusAmshove
Copy link
Owner Author

@javatarz it looks like they support it: https://www.jfrog.com/confluence/plugins/servlet/mobile?contentId=46108078#content/view/46108078

Might be interesting in the future to deploy a snapshot after master builds on travis

@MarkusAmshove
Copy link
Owner Author

Since 1.2 was just released I've decided to get the port far enough so that other people can atleast clone it.

Branch kluentv2 (not kluent-2) now contains a gradle project with the multiplatform template of IntelliJ with Kotlin 1.2.

I've disabled the JavaScript project at the moment in the root settings.gradle because JavaScript doesn't support backtick methods (we'll get the same problem with Android, so we'll have to figure it out).

It now contains:

kluent (root common project)

  • kluent-jvm (Java specific)
  • kluent-js (JavaScript specific)

I've ported all Java specific stuff to the jvm project (DateTime and File) and kept everything else in the common project.

I've also ported all Java specific tests to kotlin.test and an example in the common project, to see if every platform executes the common tests under their hood (what they do).

If you checkout the branch and run

gradle build

you can open the test reports from the JVM project in

/kluent-jvm/build/reports/tests/test/index.html

Which also shows the one testclass from the common project which runs assertions:

grafik

Also we have no specific dependency on JUnit anymore (even in the jvm project, only as testCompile for our unittests), as @javatarz wanted :-)

I think it should work really well in the future.
I've asked about how to distribute common libs and the Kotlin docs should be updated soon(TM) for that.

There are a lot of tests to port still, but thankful multiplatform is still experimental as of Jetbrains :-)

@MarkusAmshove
Copy link
Owner Author

test reports will now be in

./Kluent/jvm/build/reports/tests/test/index.html

@MarkusAmshove
Copy link
Owner Author

I've also got a native module running (with gradle) and pushed it into the branch.
It uses the common module and the program itself just does a assertion.
Doing it this way doesn't give any support in CLion at the moment.

I'm also not sure what to do with the backtick methods at the moment.
We could just drop them, but I'm not sure how many people are using them.

The support of backtick names from the Kotlin perspective is the following:

Platform Supports backtick
JVM yes
Android no
JavaScript no
Native yes

Another way than just dropping it would be to have a common-backtick module, which the target platform can depend on.
However, that way the android module can't depend on the JVM module.

@Rosomack
Copy link

Rosomack commented Jan 5, 2018

Hi @MarkusAmshove re: mocking, I understand the decision to drop mocking support, as a user of your library can I suggest deprecating it as soon as possible after reaching a decision? I work in a big team and it would help us keep using mockito-kotlin consistently.

Even better would be to export mocking support to a separate library to avoid the confusion with mockito-kotlin completely until you kill it. If someone wants to upgrade before 2.0, they'd have to pull in an extra dependency.

@MarkusAmshove
Copy link
Owner Author

Hi @Rosomack ,

Mocking will have to be dropped in 2.0, as it wouldn't be consistent between the libraries.
The JVM-library could still include wrappers for mockito-kotlin, but the past has shown that it's hard to maintain and the functionality isn't even on par with mockito-kotlin, so to use all features I would have to use idiomatic mockito-kotlin anyways. Being forced into a specific mockito-kotlin version because Kluent uses it doesn't feel right in that regard.

Deprecating mocking before 2.0 is a good idea, it would make absolutely clear that the codebase won't be compatible with 2.0 and you'd have to go one version down (to get rid of the annoying deprecated warnings) or change your code (which I don't like, but I sadly don't see another option). Using Kluent pre 2.0 is absolutely fine though, since 2.0 is mainly to get all the platforms supported.

What I'm not sure about is the backtick methods. We could also deprecate them and drop them in 2.0, but I think people are dependent on them. The deprecation version could introduce codefixes to convert your code to non-backtick versions.

I'm also making sure that beside that stuff, everything else won't break when bumping up to 2.0, e.g. keeping packages and methods as they are now.

When I'm sure about the backtick stuff, or have heard some more opinions on that topic, I can also get the 2.0 version to a preview, since the JVM stuff wouldn't change.
This means that if you're using Kluent for the JVM, you would have to change the dependency from kluent:1.+ to kluent-jvm:2.+ and everything works as it did before. If you're using it with Android it would be enough to just bump kluent-android to 2.0, because we'll keep that name

@javatarz
Copy link
Contributor

Bump, haven't seen this go anywhere in a while. Are we waiting for a major kotlin release?

@MarkusAmshove
Copy link
Owner Author

At the moment I'm waiting for kotlin native to become a bit more mature.
I also haven't really figured out how to distribute kotlin-js or kotlin-native libraries :-)

@javatarz
Copy link
Contributor

Considering the delay, does it make svense to split the release into 2 parts. Step 1, changes to the capabilities in terms of just the JVM (kluent 2.0). Step 2, support native/js (kluent 2.1/3).

For the API changes we know are coming, we can make the breaking changes right now.. (in which case the step 2 can be kluent 2.1). If we're pushing the breaking changes to step 2, then step 2 will be kluent 3.

Motivation: The thought, initially, behind the major bump was to split the test runner out of the testing framework. Native/JS support seems to be taking time and can be added later.

@MarkusAmshove
Copy link
Owner Author

What would work that way is having a common module and a jvm module for 2.0, but the jvm module would have a new name (kluent-jvm for example). The same thing goes for Android.
Keeping kluent as the jvm artifact using kluent-common would also be possible.

That would mean that we have to migrate all of our current tests from Spek to kotlin.test and keep the incompatibility of backtick names in tests in mind (see here).

#96 and #73 should also be included (maybe in 1.x before), so we can just take the old codebase and split into modules and change the tests.
I'm however a bit busy from April to around 9th of July, which would either be a good phase for a pre release or to postpone it until then.

@javatarz
Copy link
Contributor

Sounds like a potential branch/PR :) I'll see how I can work on some of this if you're around to review PRs in the April-early July time frame.

@MarkusAmshove
Copy link
Owner Author

You can have a look at the v2 branch, I essentially created a new project and copied over the old sources while separating out platform dependent code into the JVM module. I also converted some tests to kotlin.test to run them under native and JS (which works).
I really like Spek and their next milestone has multiplatform in the description, but there is no ETA :)

@MarkusAmshove
Copy link
Owner Author

MarkusAmshove commented May 29, 2018

I've added a PR #106 to track the current status.

My plan for Android is to have a specific Android project.

Is there any reason this project can't depend on the JVM project?
For example, are there APIs (like java.nio) that are available on the JVM but not on Android?

Backticks are still a problem.
I could make a common-backtick module which JVM and Native depend on, but then Android couldn't depend on JVM 😕

@MarkusAmshove
Copy link
Owner Author

I've released the first version that can be considered a huge goal torwards 2.0, which was built and released with the multiplatform setup.

It is still 1.x, because the only change is the multiplatform thingy, but you can try it by including org.amshove.kluent:kluent-jvm:1.39 instead of org.amshove.kluent:kluent:1.38.
It uses another name at the moment to not break users code if they use wildcard versioniong and I somehow broke something, which I think I tested enough.

I would love if you could replace the current import with the new one stated above (with version 1.39) and get back here to tell me if anything is broken.
All packages names etc. remained the same, but a lot of logic went into a common platform module :-)

@hameno
Copy link

hameno commented Sep 28, 2018

I've just tried to upgrade to kluent 1.41 (from 1.38) in my Android project and it failed because kluent is now targeting 1.8. I'm using the kluent-android artifact.
The error I'm getting is this:
Cannot inline bytecode built with JVM target 1.8 into bytecode that is being built with JVM target 1.6. Please specify proper '-jvm-target' option

Is Android not supported anymore? How should I proceed?

@MarkusAmshove
Copy link
Owner Author

Thank you for reporting @hameno

I think I missed something when changing the buildsystem, so that the Android artifact might target the wrong version.
I'll look into it!

@MarkusAmshove
Copy link
Owner Author

this wasn't present before, so thats most likely the issue.

I'll add a conditional and publish an update

@MarkusAmshove
Copy link
Owner Author

You can try v1.42 now, this should solve your issue, if not please let me know!

@hameno
Copy link

hameno commented Sep 29, 2018

Thanks, that fixed it 👍

@MarkusAmshove
Copy link
Owner Author

Thanks for confirming :)

I'll close this issue because the multiplatform stuff is figured out.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
No open projects
Kluent 2.0
  
Done
Development

No branches or pull requests

5 participants