Skip to content

Commit

Permalink
feat(BpmnElementsSearcher): add a new method to get all elements by name
Browse files Browse the repository at this point in the history
It allows the caller to extract several elements and, if required, to choose how to deduplicate
elements with the same name by filtering the results returned.
  • Loading branch information
tbouffard committed Oct 4, 2023
1 parent 59e8593 commit 30003db
Show file tree
Hide file tree
Showing 2 changed files with 104 additions and 2 deletions.
23 changes: 23 additions & 0 deletions packages/addons/src/bpmn-elements.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,29 @@ export class BpmnElementsSearcher {
}
return undefined;
}

/**
* Returns all elements matching the names passed in parameter.
*
* The number of elements returned may differ from the number of names passed in parameter:
* - if there are no elements matching the names
* - if one of the names does not correspond to any elements
* - if a name corresponds to several elements (duplicates)
*
* @param names the names of the elements to retrieve.
*/
getElementsByNames(names: string[]): BpmnSemantic[] {
const elements: BpmnSemantic[] = [];
for (const kind of allBpmnElementKinds) {
elements.push(
...this.elementsRegistry
.getModelElementsByKinds(kind)
.filter(element => names.includes(element.name))
.flat(),
);
}
return elements;
}
}

export class BpmnElementsIdentifier {
Expand Down
83 changes: 81 additions & 2 deletions packages/addons/test/spec/bpmn-elements.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ limitations under the License.
import type { ShapeBpmnSemantic } from 'bpmn-visualization';

import { describe, expect, test } from '@jest/globals';
import { ShapeBpmnElementKind } from 'bpmn-visualization';
import { ShapeBpmnElementKind, ShapeBpmnEventDefinitionKind } from 'bpmn-visualization';

import { BpmnElementsIdentifier, BpmnElementsSearcher, BpmnVisualization } from '../../src';
import { createNewBpmnVisualizationWithoutContainer } from '../shared/bv-utils';
Expand Down Expand Up @@ -65,7 +65,7 @@ describe('Find elements by providing names', () => {
});
});

describe('Retrieve objects', () => {
describe('Retrieve an single object', () => {
test('Several existing tasks with the same name with default options', () => {
expectElementsHavingTheSameName(['Task_1', 'UserTask_with_same_name_as_Task_1'], 'task 1 with duplicate name');

Expand Down Expand Up @@ -132,6 +132,85 @@ describe('Find elements by providing names', () => {
} as ShapeBpmnSemantic);
});
});

describe('Retrieve several objects from several names', () => {
test('Pass several names that are not duplicated across elements', () => {
const elements = bpmnElementsSearcher.getElementsByNames(['gateway 1', 'start event 1']);
expect(elements).toHaveLength(2);
expect(elements[0]).toEqual({
id: 'Gateway_1',
incomingIds: ['Flow_0th6cj1'],
isShape: true,
kind: ShapeBpmnElementKind.GATEWAY_EXCLUSIVE,
name: 'gateway 1',
outgoingIds: ['Flow_18zkq4t', 'Flow_1xozzqt', 'Flow_1a9vtky'],
parentId: 'Participant_1',
} as ShapeBpmnSemantic);
expect(elements[1]).toEqual({
eventDefinitionKind: ShapeBpmnEventDefinitionKind.NONE,
id: 'StartEvent_1',
incomingIds: [],
isShape: true,
kind: ShapeBpmnElementKind.EVENT_START,
name: 'start event 1',
outgoingIds: ['Flow_1yf7yd6'],
parentId: 'Participant_1',
} as ShapeBpmnSemantic);
});

test('Pass several names whose some have no match', () => {
const elements = bpmnElementsSearcher.getElementsByNames(['unknown element 1', 'task 2.1', 'unknown element 2']);
expect(elements).toHaveLength(1);
expect(elements[0]).toEqual({
id: 'Task_2_1',
incomingIds: ['Flow_18zkq4t'],
isShape: true,
kind: ShapeBpmnElementKind.TASK,
name: 'task 2.1',
outgoingIds: ['Flow_045a06d'],
parentId: 'Participant_1',
} as ShapeBpmnSemantic);
});

test('Pass several names without any match', () => {
const elements = bpmnElementsSearcher.getElementsByNames(['unknown element 1', 'another unknown element', 'unknown element 2']);
expect(elements).toHaveLength(0);
});

test('Pass several names whose some relate to several elements (duplicate names)', () => {
expectElementsHavingTheSameName(['Task_1', 'UserTask_with_same_name_as_Task_1'], 'task 1 with duplicate name');

const elements = bpmnElementsSearcher.getElementsByNames(['task 2.2', 'task 1 with duplicate name']);
expect(elements).toHaveLength(3);
expect(elements[0]).toEqual({
id: 'Task_1',
incomingIds: ['Flow_1yf7yd6'],
isShape: true,
kind: ShapeBpmnElementKind.TASK,
name: 'task 1 with duplicate name',
outgoingIds: ['Flow_0th6cj1'],
parentId: 'Participant_1',
} as ShapeBpmnSemantic);
expect(elements[1]).toEqual({
id: 'Activity_08z13ne',
incomingIds: ['Flow_1xozzqt'],
isShape: true,
kind: ShapeBpmnElementKind.TASK,
name: 'task 2.2',
outgoingIds: ['Flow_1cj2f9n'],
parentId: 'Participant_1',
} as ShapeBpmnSemantic);
expect(elements[2]).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'],
parentId: 'Participant_1',
} as ShapeBpmnSemantic);
});
});
});

describe('Identify elements', () => {
Expand Down

0 comments on commit 30003db

Please sign in to comment.