kefirjs / jest-kefir

Jest plugin for asserting on Kefir Observables
MIT License
0 stars 2 forks source link

Use toEmit with async code #86

Open DanweDE opened 4 years ago

DanweDE commented 4 years ago

It would be great if toEmit (i.e. createTestHelpers(Kefir).watch) would allow asserting that an observable emits, also asynchronously. For example:

const seq = Kefir.sequentially(100, [1, 2]).toProperty(() => 0)

await expect(seq).toEmit([
  value(0),
  value(1),
  value(2, { current: true }),
  end({ current: true }),
], async () => {
  await Promise((r) => setTimeout(r, 1000));
})
mAAdhaTTah commented 4 years ago

toEmitInTime is used for observables that emit values over time, but we use it with lolex to mock time. So the above example would be as follows:

const seq = Kefir.sequentially(100, [1, 2]).toProperty(() => 0)

expect(seq).toEmitInTime([
  [0, value(0, { current: true })],
  [100, value(1)],
  [200, value(2)],
  [200, end()],
], tick => {
  tick(200);
});
DanweDE commented 4 years ago

Yes, I am aware of that. In theory that is sufficient, in practice it might not work when testing code that also relies on promises so I still think this suggestion would make a lot of sense for real-world testing cases. The second use-case where this would be helpful would be when in your tests you don't care about the exact time but just the order something emitted.

mAAdhaTTah commented 4 years ago

Ok, will reopen to investigate, but not sure when I'll get to it. Open to a PR though if you're interested!

mAAdhaTTah commented 4 years ago

Two things:

  1. I don't think this actually requires any changes in KTU. watch returns the log array and an unwatch function, which in toEmit is called synchronously, but it doesn't need to do that. I'm going to transfer this issue to the jest-kefir repo.
  2. Looking into this now, it appears this would be a breaking change, because expect(obs).toEmit([...]) would now need to be await'd. Instead of modifying toEmit to allow async functions, what do you think about a new matcher called toEmitAsync that expects an async function?