5

Following this post I've decided to write a marble test for this operator.

Here is a basic test:

  it('Test lossy zip', () => {

    const a = hot('a---a--------a-');
    const b = hot('--b----b---b---');

    const observable = zip(
      a.pipe(take(1)),
      b.pipe(take(1))
    ).pipe(
      mergeMapTo(from(['1'])),
      repeat()
    );
    const expected = cold('--1----1-----1-');
    expect(observable).toBeObservable(expected);
  });

This test passes as expected. However, when I decide to fire two emissions, like this, it fails:

const a = hot('a---a--------a-');
const b = hot('--b----b---b---');

const observable = zip(
  a.pipe(take(1)),
  b.pipe(take(1))
).pipe(
  mergeMapTo(from(['1', '2'])), //Here, emitting two items instead of one
  repeat()
);

I would expect the resulting observable to look like this:

const expected = cold('--(12)----(12)-----(12)-');

Or at least like this:

const expected = cold('--12---12----12-');

However both of them fail.

Is it a bug in jasmine-marbles or my expectations are wrong?

JeB
  • 11,653
  • 10
  • 58
  • 87
  • The problem is with your understanding of the marble syntax. Synchronous groups (e.g. `(12)`) have emissions that occur on the first frame (the frame with the `(` character), but the syntax actually spans more than one frame. Related: https://stackoverflow.com/q/46839094/6680611 – cartant Nov 26 '17 at 22:33
  • Oh I see... I guess I should have read the documentation more thoroughly. So the behavior of `TestScheduler` is that not just the inside of the group take appropriate amount of frames but also the parentheses. In this case my test marbles should be something like: `hot('a------a---------a---')` and `hot('--b-------b----b-----')` and the output would be `cold('--(12)----(12)---(12)')`. If you don't mind answering the question with this example I'll accept your answer. Thanks for the help! – JeB Nov 27 '17 at 05:17
  • 1
    No worries. I didn't read the docs carefully either and I documented my experiences [here](https://blog.angularindepth.com/rxjs-marble-testing-rtfm-a9a6cd3db758). – cartant Nov 27 '17 at 05:30
  • 1
    Regarding answering, I'm lazy. How about you [self-answer it](https://stackoverflow.com/help/self-answer)? Then all I have to do is upvote it. – cartant Nov 27 '17 at 05:33

1 Answers1

4

Apparently, according to the official documentation (which I haven't read thoroughly enough) parentheses as well as content of the group take up the relevant amount of frames:

'--(abc)-|': on frame 20, emit a, b, and c, then on frame 80 complete

And this means a working test for group emission would look like this:

  it('Should emit a grouped value', () => {

    const a = hot('a------a---------a---');
    const b = hot('--b-------b----b-----');

    const observable = zip(
      a.pipe(take(1)),
      b.pipe(take(1))
    ).pipe(
      mergeMapTo(from(['1', '2'])),
      repeat()
    );

    const expected = cold('--(12)----(12)---(12)');
    expect(observable).toBeObservable(expected);
  });
Mikkel R. Lund
  • 2,336
  • 1
  • 31
  • 44
JeB
  • 11,653
  • 10
  • 58
  • 87