https://kotlinlang.org logo
#orbit-mvi
Title
# orbit-mvi
o

Oleksii Malovanyi

09/17/2021, 2:29 PM
Hey guys, what do you think about tweaking the
runOnCreate
function so one could subscribe to container from it -> currently it’s impossible due to compilation restrictions, so in case of ViewModel we have to subscribe from the `init{}`which then could affect tests which don’t wanna run
runOnCreate
on TestContainer
1
e.g.: non-braking change
Copy code
onCreate: Container<STATE, SIDE_EFFECT>.(state: STATE) -> Unit
also, this is doubtable as we could trick the compiler if wrap the subscription call with a method
another thing is (but related) if one collects the state from
onCreate
then
runOnCreate
test would never finish (obviously). Maybe, we could add a param to
runOnCreate
to indicate it should terminate with timeout silently. e.g.
Copy code
runOnCreate(withTimeout:Long = 0L)
and if
withTimeout
> 0 wrap the call with
withTimeoutOrNull
.
a

appmattus

09/21/2021, 1:22 PM
hi @Oleksii Malovanyi, I realise we've not got back to you yet on this, @Mikolaj Leszczynski is currently on holiday so we've not had a chance to discuss this properly. out of curiosity, what is the use case for observing the container from within the viewmodel. i ask as it feels very self-referential and not something we imagined someone doing.
plus1 1
m

Mikolaj Leszczynski

09/22/2021, 8:31 AM
@Oleksii Malovanyi is this not something that can be achieved by simply calling a
ContainerHost
function invoking
intent
where you can subscribe to the container?
Copy code
private inner class SomeMiddleware : ContainerHost<TestState, String> {
        override val container = scope.container<TestState, String>(TestState(42)) {
            test()
        }

        private fun test(): Unit = intent {
            coroutineScope {
                container.stateFlow.collect {
                    println("TEST LOL $it")
                }
            }
        }
    }
👍 1
works for me locally :)
as long as you explicitly specify the return type on
fun test
you’re golden
You can even forgo the function and just launch an intent from within
onCreate
o

Oleksii Malovanyi

09/22/2021, 2:18 PM
Hey guys, thanks for your replies and no worries -> I know I always could get feedback from you and this is something to appreciate 👍
About the thread: the use case is imagine self-validation: every time the input (is stored in the state) changes, the validation (also part of the state) should auto-change. Or another case: travel in time: on error I’d like to apply to the state the properties from it’s previous version.
in the end yes, we could overcome the compilation issues with an extra method, and functionally it’s decent api for me
the more sever issue for me is testing: if you do
runOnCreate
with infinite collection of the state
runBlockingTest
will punch you for that (obviously indefinite collection is not allowed in tests), as it blocks. The solution is to create a coroutine or something similar for the collection –
withTimeoutOrNull
works then, but looks kinda ugly 🤔
unfortunately I haven’t come up with a better solution. I could create a branch with a tests so you could play around with the use case for what I mean
m

Mikolaj Leszczynski

09/22/2021, 2:45 PM
It sounds like we need the test to be in non blocking mode, once you test the on create method in this mode the rest of your tests can block safely with
runOnCreate
set to off. Am I missing something?
o

Oleksii Malovanyi

09/22/2021, 2:47 PM
yeap, and also not really 🤔 or am I missing something – I’ve used to always use
runBlockingTest
, but! There is a case when you have to start
runOnCreate
going (for the collection) and still do
testIntent
for the rollback-state on smth bad happens scenario
m

Mikolaj Leszczynski

09/22/2021, 2:55 PM
Non blocking tests were created with testing flow collection in mind
o

Oleksii Malovanyi

09/22/2021, 2:56 PM
okay, maybe I’ve really missed it 😲 I’ll take a look, thanks
m

Mikolaj Leszczynski

09/22/2021, 3:00 PM
Yeah they should work functionally the same except the blocking happens with a timeout in the assert function
o

Oleksii Malovanyi

09/22/2021, 3:00 PM
aha, so it basically very similar to timeout trick with the coroutines
m

Mikolaj Leszczynski

09/22/2021, 3:01 PM
Yes!
It will await the expected number of states and side effects and time out of it doesn't reach the desired number within 5 seconds
You can tweak the timeout too
I think
@Oleksii Malovanyi let us know how it goes 🙂
@Oleksii Malovanyi anything to report? 🙂
o

Oleksii Malovanyi

09/24/2021, 7:38 AM
sorry, not yet -> would try out this weekend
👍 1
m

Mikolaj Leszczynski

09/24/2021, 7:38 AM
thanks!
4 Views