[Expressions] Add support of partial results to the switch expression function (#108086)

This commit is contained in:
Michael Dokolin 2021-08-11 22:16:53 +02:00 committed by GitHub
parent 6563fad7be
commit 1eae08e2c1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 59 additions and 28 deletions

View file

@ -56,25 +56,6 @@ describe('switch', () => {
});
describe('function', () => {
describe('with no cases', () => {
it('should return the context if no default is provided', () => {
const context = 'foo';
testScheduler.run(({ expectObservable }) =>
expectObservable(fn(context, {})).toBe('(0|)', [context])
);
});
it('should return the default if provided', () => {
const context = 'foo';
const args = { default: () => of('bar') };
testScheduler.run(({ expectObservable }) =>
expectObservable(fn(context, args)).toBe('(0|)', ['bar'])
);
});
});
describe('with no matching cases', () => {
it('should return the context if no default is provided', () => {
const context = 'foo';
@ -108,6 +89,55 @@ describe('switch', () => {
expectObservable(fn(context, args)).toBe('(0|)', [result])
);
});
it('should support partial results', () => {
testScheduler.run(({ cold, expectObservable }) => {
const context = 'foo';
const case1 = cold('--ab-c-', {
a: {
type: 'case',
matches: false,
result: 1,
},
b: {
type: 'case',
matches: true,
result: 2,
},
c: {
type: 'case',
matches: false,
result: 3,
},
});
const case2 = cold('-a--bc-', {
a: {
type: 'case',
matches: true,
result: 4,
},
b: {
type: 'case',
matches: true,
result: 5,
},
c: {
type: 'case',
matches: true,
result: 6,
},
});
const expected = ' --abc(de)-';
const args = { case: [() => case1, () => case2] };
expectObservable(fn(context, args)).toBe(expected, {
a: 4,
b: 2,
c: 2,
d: 5,
e: 6,
});
});
});
});
});
});

View file

@ -5,14 +5,14 @@
* 2.0.
*/
import { Observable, defer, from, of } from 'rxjs';
import { concatMap, filter, merge, pluck, take } from 'rxjs/operators';
import { Observable, combineLatest, defer, of } from 'rxjs';
import { concatMap } from 'rxjs/operators';
import { ExpressionFunctionDefinition } from 'src/plugins/expressions/common';
import { Case } from '../../../types';
import { getFunctionHelp } from '../../../i18n';
interface Arguments {
case?: Array<() => Observable<Case>>;
case: Array<() => Observable<Case>>;
default?(): Observable<any>;
}
@ -43,12 +43,13 @@ export function switchFn(): ExpressionFunctionDefinition<
},
},
fn(input, args) {
return from(args.case ?? []).pipe(
concatMap((item) => item()),
filter(({ matches }) => matches),
pluck('result'),
merge(defer(() => args.default?.() ?? of(input))),
take(1)
return combineLatest(args.case.map((item) => defer(() => item()))).pipe(
concatMap((items) => {
const item = items.find(({ matches }) => matches);
const item$ = item && of(item.result);
return item$ ?? args.default?.() ?? of(input);
})
);
},
};