Skip to content

Commit

Permalink
Add support of partial results to the switch expression function
Browse files Browse the repository at this point in the history
  • Loading branch information
dokmic committed Aug 10, 2021
1 parent 37a97b4 commit 24ed18e
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,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,
});
});
});
});
});
});
20 changes: 12 additions & 8 deletions x-pack/plugins/canvas/canvas_plugin_src/functions/common/switch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
* 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';
Expand Down Expand Up @@ -43,12 +43,16 @@ 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)
const cases = args.case?.map((item) => defer(() => item())) ?? [];
const cases$ = cases.length ? combineLatest(cases) : of([]);

return cases$.pipe(
concatMap((items) => {
const item = items.find(({ matches }) => matches);
const item$ = item && of(item.result);

return item$ ?? args.default?.() ?? of(input);
})
);
},
};
Expand Down

0 comments on commit 24ed18e

Please sign in to comment.