I have a test for mergemap, But it does not return the correct expect result. Can someone help me?
Thanks!
it("should maps to inner observable and flattens", () => {
const values = { a: "hello", b: "world", x: "hello world" };
const obs1 = cold( "-a---a|", values);
const obs2 = cold( "-b-b-b-|", values);
const expected = cold("--x-xxxx-x-|", values);
const result = obs1.pipe(mergeMap(x => obs2.pipe(map(y => x + " " + y))));
expect(result).toBeObservable(expected);
I will try to break down your test so you can understand what's going on and where you're doing things wrong. I'm really sorry, but I won't be using jasmine-marbles library, but a preferred way of writing tests (I'd also recommend you to avoid jasmine-marbles library).
When converted to plain, old marbles (not using jasmine-marbles library), your test looks like this:
And this test is failing. Here is why: you're expecting your test to emit at frames 2, 4, 5, 6, 7, 9 and a complete at frame 11. But, the actual emissions happen at frames 2, 4, 6, 6, 8, 10 and a complete at frame 12. Now, to be able to visually understand why and how this is happening, I will write a test with couple of comments and I will align them a different way so you get a better filling of what happens:
Basically, in
mergeMap, you're returning an instance ofobs2when the source observable emits. In this case, the source isobs1. When it emits the first value (a), at frame 1,mergeMapinternally subscribes toobs2- this is why I aligned the start ofobs2emissions to be belowaat frame 1. Emissions fromobs2are the ones that get to the consumer.Similarly, when
obs1emits the second value, at frame 5, another subscribe toobs2happens and, sinceobs2is acoldobservable, another producer is instantiated, so another stream starts to flow. This is why I added a comment to indicate when the second subscribe toobs2happens. It starts at frame 5, right when the secondais emitted fromobs1. Similarly, emissions from the second subscribe toobs2are the ones that get to the consumer.So, combining this, we get to conclusion where the expected frames should be:
Based on this, the final emissions happen at frames 2, 4, 6, 6, 8 and 10 and the complete happens at frame 12. The problem with this setup is that it is not possible to show an emission which comes early after two or more emissions that come at the same frame.
This is to say, emission at frame 8 is too close to the two emissions at frame 6. The reason being is that emissions that happen at the same frame are grouped with brackets
()in marble diagrams and brackets are somewhat hiding some number of emissions. This is your case:Frames 7, 8 and 9 are hidden and can't be represented so emissions at these frames can't be shown in marble diagrams, no matter what. And, since there is an emission at frame 8 which gets lost, you can't create a proper marble diagram for this expected emissions.
In order for this test to pass, you could emit the second
afrom theobs1one frame further, at frame 6. Now, your test could look like this (and it should pass now):