diff --git a/packages/addons/src/bpmn-elements.ts b/packages/addons/src/bpmn-elements.ts index cf9157c..0051706 100644 --- a/packages/addons/src/bpmn-elements.ts +++ b/packages/addons/src/bpmn-elements.ts @@ -23,7 +23,9 @@ const allBpmnElementKinds: BpmnElementKind[] = [...Object.values(ShapeBpmnElemen * Options for deduplicating elements when several names match. */ export type ElementsSearcherFilterDuplicateOptions = { + /** If not set, use all `BpmnElementKind` values. */ kinds?: BpmnElementKind[]; + /** Apply custom function to filter duplicates. */ // TODO find a better name filter?: (bpmnSemantic: BpmnSemantic) => boolean; }; @@ -50,6 +52,8 @@ export class BpmnElementsSearcher { * @param options if not defined, or if the object doesn't define any properties, duplicates are filtered out by selecting the first element corresponding to the name provided. */ // TODO decide if we decide to apply filter if there is a single elements? + // TODO document the filtering order: kinds, then function (TODO add tests for this) + // TODO options JSDoc: put document there, not in the parameter? getElementByName(name: string, options?: ElementsSearcherFilterDuplicateOptions): BpmnSemantic | undefined { // Not optimized, do a full lookup at each call // Split query by kind to avoid returning a big chunk of data diff --git a/packages/addons/test/spec/bpmn-elements.test.ts b/packages/addons/test/spec/bpmn-elements.test.ts index 949290c..51472f9 100644 --- a/packages/addons/test/spec/bpmn-elements.test.ts +++ b/packages/addons/test/spec/bpmn-elements.test.ts @@ -80,8 +80,7 @@ describe('Find elements by providing names', () => { } as ShapeBpmnSemantic); }); - // with options - test('Several existing tasks with the same name - deduplicate with kind', () => { + test('Several existing tasks with the same name - deduplicate with kinds', () => { // TODO duplicate, move this is a specific check (or specific method) // Verify that several elements have the same names expect(getModelElementName('Task_1')).toBe('task 1 with duplicate name'); @@ -96,6 +95,29 @@ describe('Find elements by providing names', () => { outgoingIds: ['Flow_0i4ule4', 'Association_0fwvz81'], } as ShapeBpmnSemantic); }); + + test('Several existing tasks with the same name - deduplicate with the filtering function', () => { + // TODO duplicate, move this is a specific check (or specific method) + // Verify that several elements have the same names + expect(getModelElementName('Task_1')).toBe('task 1 with duplicate name'); + expect(getModelElementName('UserTask_with_same_name_as_Task_1')).toBe('task 1 with duplicate name'); + + expect( + bpmnElementsSearcher.getElementByName('task 1 with duplicate name', { + filter: bpmnSemantic => bpmnSemantic.isShape && (bpmnSemantic as ShapeBpmnSemantic).outgoingIds.includes('Association_0fwvz81'), + }), + ).toEqual({ + id: 'UserTask_with_same_name_as_Task_1', + incomingIds: ['Flow_1a9vtky'], + isShape: true, + kind: ShapeBpmnElementKind.TASK_USER, + name: 'task 1 with duplicate name', + outgoingIds: ['Flow_0i4ule4', 'Association_0fwvz81'], + } as ShapeBpmnSemantic); + }); + + // both kinds and filter function + // filter: isShape = false }); });