我创建了一个新的 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)