question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

`cancelAndIgnoreRemainingEvents()` does not cancel a Molecule StateFlow

See original GitHub issue

This might be Molecule-specific, but I still expect cancelAndIgnoreRemainingEvents() to be able to cancel any StateFlow.

Here’s a simple Molecule presenter:

@Composable fun MoleculePresenter(): Model {
  return Model("Hello!")
}

And a test for it:

class MoleculePresenterTest {
  @Test fun test() = runBlocking {
    makePresenter().test {
      assertEquals(Model("Hello!"), awaitItem())
      cancelAndIgnoreRemainingEvents()
    }
  }

  private fun CoroutineScope.makePresenter(): StateFlow<Model> {
    return launchMolecule(RecompositionClock.Immediate) {
      MoleculePresenter()
    }
  }
}

test() never completes when executed, neither with cancelAndIgnoreRemainingEvents() nor without it.

The repro project is here: https://github.com/Egorand/turbine-cancel-hangs. Simply run ./gradlew app:testDebugUnitTest to reproduce the issue.

(Crappy) workaround:

@Test(expected = CancellationException::class)
fun test() = runBlocking {
  makePresenter().test {
    assertEquals(Model("Hello!"), awaitItem())
    coroutineContext.cancel()
  }
}

Issue Analytics

  • State:closed
  • Created a year ago
  • Comments:6 (5 by maintainers)

github_iconTop GitHub Comments

1reaction
JakeWhartoncommented, Sep 6, 2022

A bit more general in that the background scope can be used for launching things which produce a StateFlow which become the subject of a Turbine test.

Although, in general, testing a StateFlow with Turbine (at least with 0.9.0) is a bit sketchy. We no longer use the Unconfined dispatcher for collections so you are subject to races with which actual states you see reflected as events. Ideally you can just call .value after performing an action, but that relies on no threading to be in play. If there is threading at play, awaitItem() may conflate two updates into a single event which can surprise.

So I’m not actually sure how detailed we want to get here.

1reaction
PaulWoitaschekcommented, Sep 6, 2022
Read more comments on GitHub >

github_iconTop Results From Across the Web

Cancellation requirement not enforced for Hot Flows #90
Ideally these tests would require a call to either cancelAndConsumeRemainingEvents() or cancelAndIgnoreRemainingEvents() towards the end of ...
Read more >
How to cancel collect coroutine StateFlow? - android
Well you have to know something about coroutine. If we just call cancel, it doesn't mean that the coroutine work will just stop....
Read more >
Operations for Stateflow Data - MATLAB & Simulink
Stateflow ® charts in Simulink ® models have an action language property that defines the operations that you can use in state and...
Read more >
Working with Charts (Stateflow)
Specifying Chart Properties. Part of a chart's interface to its Simulink model is set when you specify the properties for a chart. To...
Read more >
Control Logic Made Easy with Stateflow - YouTube
52,740 views • May 21, 2017. See what's new in the latest release of MATLAB and Simulink: https://goo.gl/3MdQK1 Download a trial: ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found