1

我创建了一个新的 RxJs(6) 运算符 switchIfEmpty(other),它会other在源为空时切换。

我是大理石测试的新手,我创建了一些测试来验证我的操作员,所有测试都通过了,除了一个。我不知道错误是来自操作员还是来自测试!

import { Observable } from 'rxjs';

export const switchIfEmpty = <T, R>(emptySource: Observable<R>) =>
  (source: Observable<T>) => {
    return new Observable<T | R>(subscriber => {
      let empty = true;
      const subscription = source.subscribe(
        e => {
          empty = false;
          subscriber.next(e);
        },
        error => subscriber.error(error),
        () => {
          if (empty) {
            const innerSub = emptySource.subscribe(
              innerE => subscriber.next(innerE),
              error => subscriber.error(error),
              () => subscriber.complete()
            );
            subscription.add(innerSub);
          } else {
            subscriber.complete();
          }
        }
      );
      return subscription;
    });
  };

测试规范:

import { TestScheduler } from 'rxjs/testing';
import { of, throwError } from 'rxjs';
import { switchIfEmpty } from './switch-empty';
import { delay } from 'rxjs/operators';

describe('SWITCH IF EMPTY OPERATOR', () => {

  let scheduler: TestScheduler;

  beforeEach(() => {
    scheduler = new TestScheduler((actual, expected) => {
      expect(actual).toEqual(expected);
    });
  });

  it('switchIfEmpty : source not empty', () => {
    const source = '-x-y-z|';
    const expected = '-x-y-z|';
    scheduler.run(helper => {
      const source$ = scheduler.createColdObservable(source);
      helper.expectObservable(source$.pipe(switchIfEmpty(of(1)))).toBe(expected);
    });
  });

  it('switchIfEmpty : source empty', () => {
    const source = '|';
    const expected = '(1 a|)';
    scheduler.run(helper => {
      const source$ = scheduler.createColdObservable(source);
      helper.expectObservable(source$.pipe(switchIfEmpty(of('1', 'a')))).toBe(expected);
    });
  });

  it('switchIfEmpty : source error', () => {
    const source = '-x#';
    const expected = '-x#';
    scheduler.run(helper => {
      const source$ = scheduler.createColdObservable(source);
      helper.expectObservable(source$.pipe(switchIfEmpty(of(1)))).toBe(expected);
    });
  });

  it('switchIfEmpty : empty source switched to error', () => {
    const source = '|';
    const expected = '#';
    scheduler.run(helper => {
      const source$ = scheduler.createColdObservable(source);
      helper.expectObservable(source$.pipe(switchIfEmpty(throwError('error')))).toBe(expected);
    });
  });

  it('switchIfEmpty : empty source switched to delay', () => {
    const source = '|';
    const expected = '--x|'; // tried '--(x|)' not work
    scheduler.run(helper => {
      const source$ = scheduler.createColdObservable(source);
      const switchedSource = of(1).pipe(delay(20));
      helper.expectObservable(source$.pipe(switchIfEmpty(switchedSource))).toBe(expected, {x: 1});
    });
  });
});

只有最后一个不起作用:

it('switchIfEmpty : empty source switched to delay', () => {
    const source = '|';
    const expected = '--x|'; // tried '--(x|)' not work
    scheduler.run(helper => {
      const source$ = scheduler.createColdObservable(source);
      const switchedSource = of(1).pipe(delay(20));
      helper.expectObservable(source$.pipe(switchIfEmpty(switchedSource))).toBe(expected, {x: 1});
    });
  });

错误信息

SWITCH IF EMPTY OPERATOR switchIfEmpty : empty source switched to delay FAILED
        Expected $.length = 0 to equal 2.
        Expected $[0] = undefined to equal Object({ frame: 2, notification: Notification({ kind: 'N', value: 1, error: undefined, hasValue: true }) }).
        Expected $[1] = undefined to equal Object({ frame: 3, notification: Notification({ kind: 'C', value: undefined, error: undefined, hasValue: false }) }).
            at TestScheduler.assertDeepEqual (http://localhost:9876/src/switch-empty.spec.ts?:12:22)
            at http://localhost:9876/node_modules/rxjs/_esm5/internal/testing/TestScheduler.js?:122:1
            at Array.filter (<anonymous>)
            at TestScheduler.push../node_modules/rxjs/_esm5/internal/testing/TestScheduler.js.TestScheduler.flush (http://localhost:9876/node_modules/rxjs/_esm5/internal/testing/TestScheduler.js?:120:1)
4

0 回答 0