Hey guys, i am a bit new to multiplatform projects...
# javascript
h
Hey guys, i am a bit new to multiplatform projects, i have a project for jvm and js backend targets and i can't get the simplest setup for js to work. Did everything like official docs state but when i add kotlin test-js dependency, compileTestKotlinJs fails saying "Module kotlin is defined in more than one file". I am trying to run tests with mocha as soon as it works and the only dependency i currently have is ktor client. Any ideas anyone?
i
Can you attach a link to your project or gradle file?
h
Sadly No :( do you know of a working minimal example with enabled javascript tests?
I could somewhen later maybe extract a minimal example and share that
i
h
Not sure, i am having a multiplatform project, which seems to be configured quite different from a js only
i
You can check full stack demo. It is multiplatform https://github.com/Kotlin/kotlin-full-stack-application-demo
h
Thx for the hint, sadly the shared subproject, which is such a multiplatform project, doesn't contain any Javascript tests :(
r
@Hanno I've just added a simple test to
template-fullstack-ktor
kvision example (https://github.com/rjaros/kvision-examples/tree/master/template-fullstack-ktor). It works without problems for me.
h
Thx all for your help! @Robert Jaros your example is a bit different than my project but i will take a look at why yours works and mine doesn't. All in all, i am a bit frustrated by the amount of configuration that seems to be necessary to get my simple example to work. I think jvm js multiplat project with working tests and corresponding reports would be super nice as a starter template, linked to from the official docs as a starting point. Going to see if i could deliver that as soon as i can, i will keep you updated.
Btw my use case is an api client that we need for backends and frontends
r
Do you have a link to your project?
Kotlin/JS and Kotlin MMP are still experimental and right now they are undergoing major changes
that's why its so hard to find up to date examples
h
No :( company stuff i cannot share that easily. Yap that's okay for us. Alternatively introducing another language for frontend Client and writing the thing twice is a worse Option :) yea that's true, it's difficult, i would whish there was just a single opinionated official example using mocha and done xD
But hey guys, you are super nice, thanks for your help already
I tried to extract a mininal example project, can be found here https://github.com/hannespernpeintner/kotlin-minimal-jvm-js would be super nice If someone could tell me why i can't call Test compile for js :)
r
With some small changes I can run your test, but with a failure
I think you want to have a test service running
But I'm not sure how do you try to run this service
Ok, I run your test successfully
with some garbage on the screen 😉 but with a checkmark :-)
the problem is you create a service in gradle and want to pass its port to mocha test runner
that forces you to bypass normal kotlin/js testing mechanism and create your own by installing and execution mocha by hand
but it still can work - you just have to fix some directories:
Copy code
val nodeModulesParentFolder = File(buildDir, "js")
// ...
setArgs(listOf(buildDir.resolve("js/packages/kotlin-minimal-jvm-js-test/kotlin").absolutePath, "--${::testServerPort.name}=$testServerPort"))
instead of installMocha task I've added:
Copy code
js() {
        nodejs {
            testTask {
                useMocha {
                }
            }
        }
    }
And last but not least - remove
allWarningsAsErrors = true
option. Node installation task complains about two version of node with two kotlin versions. And that warning, which is absolutely not important, is treated as an error with this option.
with these changes I can run your test - but it is executed twice. By the standard kotlin/js testing - and finishes with a failure because the port is not known. And by additional
runMocha
task, which ends with a success.
h
You are a true hero, i try to parse all your input. The server stuff is stripped out from prod Code. The manual mocha stuff is taken from countless examples i found accepted as a working answer, desperatly trying to get it to work, i never wanted to do it that way :D going to do it with useMocha, why did i overlook that in the future official example, that's exactly what i want... What sense does it make to leave that bit out of the documentation with the hint "do it yourself your way". More harm than good. Can't thank you enough.
Hmmm.. how does one pass values from the build into the test via useMocha?
r
I'm afraid I don't know. I've been trying to look through the sources, but without luck.
I was thinking you could run a service inside the test, using some node API, but it's a totally different thing.
It just seems strange to me, to pass data into the test from the build file. External dependencies should be mocked using some mock tools :-)
I've been playing and I got this: 1. removed all external mocha code from
build.gradle.kts
(only
useMocha { }
is left) 2. added some deps to jstest sourceset:
Copy code
js().compilations["test"].defaultSourceSet {
            dependencies {
                implementation(npm("http"))
                implementation(npm("node-fetch"))
                implementation(npm("abort-controller"))
                implementation(kotlin("test-js"))
            }
        }
3. modified the test code:
Copy code
external fun require(name: String): dynamic
   // ...
    @Test
    fun testClientGet() {
        val randomPort = Random.nextInt(8000, 9000)
        val http = require("http")
        val server = http.createServer { _, res ->
            res.end()
        }.listen(randomPort)

        val config = Config(BaseUrl("<http://localhost>:$randomPort"), defaultApiKey)
        val client = ApiClient(config)
        GlobalScope.launch {
            assertEquals(ConnectionCheckResult.Success, client.checkConnection())
            server.close()
        }
    }
4. jsTest task works perfectly, without a single warning and successful test report is generated without problems
Hope this will be of any use :-)
h
Thx so much for your help! But i am afraid thats Not sufficient. I have to use an external service that is started and stopped in the build with a corresponding gradle plugin. This is the way we test against real apis and it works damn good btw :) we own the service but it's a seperate repository, hence the requirement. The service is also not easy to mock somehow, that's one of the reasons we want to build a client for it. Must be possible to pass a value into the task somehow Oo i will take a look at the sources somewhen
I didn't find a way, i think i will use Code Generation to pass in values from the build into the tests Oo updated my example project, should work now as a template