From 3d52258172d41a1bbe524c5ec78753cce7fc042c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Souchet=20C=C3=A9line?=
<4921914+csouchet@users.noreply.github.com>
Date: Fri, 13 Oct 2023 09:01:14 +0200
Subject: [PATCH] feat: add link event data in `ShapeBpmnSemantic` (#2911)
Add new `linkEventSourceIds` an `linkEventTargetId` properties in
`ShapeBpmnSemantic` to include data related to the link events that are
stored in the internal model.
---------
Co-authored-by: Thomas Bouffard <27200110+tbouffard@users.noreply.github.com>
---
src/component/registry/bpmn-model-registry.ts | 13 ++-
src/component/registry/types.ts | 8 ++
.../bpmn/model-complete-semantic.bpmn | 11 ++-
...pool-2-lanes-link-intermediate-events.bpmn | 81 +++++++++++++++++++
test/integration/dom.bpmn.elements.test.ts | 26 ++++++
test/integration/helpers/model-expect.ts | 23 +++---
.../helpers/semantic-with-svg-utils.ts | 31 ++++++-
test/integration/matchers/toBeShape/index.ts | 15 +++-
test/integration/model.elements.api.test.ts | 24 +++++-
test/shared/model/bpmn-semantic-utils.ts | 14 +++-
.../registry/bpmn-model-registry.test.ts | 64 ++++++++++++++-
test/unit/helpers/bpmn-model-expect.ts | 21 +++--
test/unit/helpers/bpmn-model-utils.ts | 27 +++++++
13 files changed, 328 insertions(+), 30 deletions(-)
create mode 100644 test/fixtures/bpmn/registry/1-pool-2-lanes-link-intermediate-events.bpmn
diff --git a/src/component/registry/bpmn-model-registry.ts b/src/component/registry/bpmn-model-registry.ts
index 401f24d5cb..d55deaed63 100644
--- a/src/component/registry/bpmn-model-registry.ts
+++ b/src/component/registry/bpmn-model-registry.ts
@@ -20,9 +20,15 @@ import type { Edge } from '../../model/bpmn/internal/edge/edge';
import type Shape from '../../model/bpmn/internal/shape/Shape';
import type { ModelFilter } from '../options';
-import { ShapeBpmnMarkerKind, ShapeUtil } from '../../model/bpmn/internal';
+import { ShapeBpmnEventDefinitionKind, ShapeBpmnMarkerKind, ShapeUtil } from '../../model/bpmn/internal';
import { Flow } from '../../model/bpmn/internal/edge/flows';
-import ShapeBpmnElement, { ShapeBpmnCallActivity, ShapeBpmnEvent, ShapeBpmnSubProcess } from '../../model/bpmn/internal/shape/ShapeBpmnElement';
+import ShapeBpmnElement, {
+ ShapeBpmnCallActivity,
+ ShapeBpmnEvent,
+ ShapeBpmnIntermediateCatchEvent,
+ ShapeBpmnIntermediateThrowEvent,
+ ShapeBpmnSubProcess,
+} from '../../model/bpmn/internal/shape/ShapeBpmnElement';
import { ModelFiltering } from './bpmn-model-filters';
@@ -68,6 +74,9 @@ export class BpmnModelRegistry {
callActivityGlobalTaskKind: bpmnElement instanceof ShapeBpmnCallActivity ? bpmnElement.globalTaskKind : undefined,
callActivityKind: bpmnElement instanceof ShapeBpmnCallActivity ? bpmnElement.callActivityKind : undefined,
eventDefinitionKind: bpmnElement instanceof ShapeBpmnEvent ? bpmnElement.eventDefinitionKind : undefined,
+ linkEventSourceIds:
+ bpmnElement instanceof ShapeBpmnIntermediateCatchEvent && bpmnElement.eventDefinitionKind == ShapeBpmnEventDefinitionKind.LINK ? bpmnElement.sourceIds : undefined,
+ linkEventTargetId: bpmnElement instanceof ShapeBpmnIntermediateThrowEvent ? bpmnElement.targetId : undefined,
incomingIds: bpmnElement.incomingIds,
outgoingIds: bpmnElement.outgoingIds,
parentId: bpmnElement.parentId,
diff --git a/src/component/registry/types.ts b/src/component/registry/types.ts
index a33fc2f840..cf103d05b2 100644
--- a/src/component/registry/types.ts
+++ b/src/component/registry/types.ts
@@ -370,13 +370,21 @@ export interface EdgeBpmnSemantic extends BaseBpmnSemantic {
* @category Custom Behavior
*/
export interface ShapeBpmnSemantic extends BaseBpmnSemantic {
+ // IMPORTANT: keep properties in alphabetical order for consistency
+
/** Set when the {@link BaseBpmnSemantic.kind} relates to a BPMN Call Activity calling a global task. */
callActivityGlobalTaskKind?: GlobalTaskKind;
/** Set when the {@link BaseBpmnSemantic.kind} relates to a BPMN Call Activity. */
callActivityKind?: ShapeBpmnCallActivityKind;
/** Set when the {@link BaseBpmnSemantic.kind} relates to a BPMN event. */
eventDefinitionKind?: ShapeBpmnEventDefinitionKind;
+ /** IDs of the incoming flows/edges. */
incomingIds: string[];
+ /** Set when the {@link BaseBpmnSemantic.kind} relates to a BPMN intermediate catch event with {@link ShapeBpmnSemantic.eventDefinitionKind} set to {@link ShapeBpmnEventDefinitionKind.LINK}. */
+ linkEventSourceIds?: string[];
+ /** Set when the {@link BaseBpmnSemantic.kind} relates to a BPMN intermediate throw event with {@link ShapeBpmnSemantic.eventDefinitionKind} set to {@link ShapeBpmnEventDefinitionKind.LINK}. */
+ linkEventTargetId?: string;
+ /** IDs of the outgoing flows/edges. */
outgoingIds: string[];
/**
* This is the ID of the direct parent of the current element, which can be a:
diff --git a/test/fixtures/bpmn/model-complete-semantic.bpmn b/test/fixtures/bpmn/model-complete-semantic.bpmn
index 01d45c7e01..552b96d3a7 100644
--- a/test/fixtures/bpmn/model-complete-semantic.bpmn
+++ b/test/fixtures/bpmn/model-complete-semantic.bpmn
@@ -26,7 +26,12 @@
-
+
+ top_catch_link_definition_id
+
+
+ top_throw_link_definition_id
+
@@ -635,7 +640,7 @@
- top_link_definition_id
+ top_throw_link_definition_id
@@ -673,7 +678,7 @@
- top_link_definition_id
+ top_catch_link_definition_id
diff --git a/test/fixtures/bpmn/registry/1-pool-2-lanes-link-intermediate-events.bpmn b/test/fixtures/bpmn/registry/1-pool-2-lanes-link-intermediate-events.bpmn
new file mode 100644
index 0000000000..469c92299c
--- /dev/null
+++ b/test/fixtures/bpmn/registry/1-pool-2-lanes-link-intermediate-events.bpmn
@@ -0,0 +1,81 @@
+
+
+
+
+
+
+
+
+ Event_1q818hp
+ startEvent_lane_1
+
+
+ Event_1wihmdr
+ Event_0snpz9d
+
+
+
+
+ sequenceFlow_lane_1_elt_1
+
+ LinkEventDefinition_077j2qu
+
+
+
+ sequenceFlow_lane_1_elt_1
+
+
+
+ Flow_18jrbeb
+
+ LinkEventDefinition_11kxj5k
+
+
+
+ Flow_18jrbeb
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/test/integration/dom.bpmn.elements.test.ts b/test/integration/dom.bpmn.elements.test.ts
index 5156c9cca9..ea87791b6d 100644
--- a/test/integration/dom.bpmn.elements.test.ts
+++ b/test/integration/dom.bpmn.elements.test.ts
@@ -24,6 +24,8 @@ import {
} from './helpers/bpmn-visualization-initialization';
import {
expectEndEventBpmnElement,
+ expectIntermediateCatchEventBpmnElement,
+ expectIntermediateThrowEventBpmnElement,
expectParallelGatewayBpmnElement,
expectPoolBpmnElement,
expectSequenceFlowBpmnElement,
@@ -62,6 +64,30 @@ describe('Bpmn Elements registry - retrieve BPMN elements', () => {
expectSequenceFlowBpmnElement(bpmnElements[1], { id: 'Flow_2', source: 'Activity_1', target: 'EndEvent_1' });
});
+ it('Pass existing link intermediate event ids', () => {
+ bpmnVisualization.load(readFileSync('../fixtures/bpmn/registry/1-pool-2-lanes-link-intermediate-events.bpmn'));
+ const bpmnElements = bpmnVisualization.bpmnElementsRegistry.getElementsByIds(['Event_1wihmdr', 'Event_1q818hp']);
+ expect(bpmnElements).toHaveLength(2);
+
+ expectIntermediateCatchEventBpmnElement(bpmnElements[0], {
+ id: 'Event_1wihmdr',
+ name: 'link catch intermediate',
+ parentId: 'lane_02',
+ eventDefinitionKind: ShapeBpmnEventDefinitionKind.LINK,
+ outgoing: ['Flow_18jrbeb'],
+ linkEventSourceIds: ['Event_1q818hp'],
+ });
+
+ expectIntermediateThrowEventBpmnElement(bpmnElements[1], {
+ id: 'Event_1q818hp',
+ name: 'link throw intermediate',
+ parentId: 'lane_01',
+ eventDefinitionKind: ShapeBpmnEventDefinitionKind.LINK,
+ incoming: ['sequenceFlow_lane_1_elt_1'],
+ linkEventTargetId: 'Event_1wihmdr',
+ });
+ });
+
it('Pass a single non existing id', () => {
bpmnVisualization.load(readFileSync('../fixtures/bpmn/simple-start-task-end.bpmn'));
const bpmnElements = bpmnVisualization.bpmnElementsRegistry.getElementsByIds('unknown');
diff --git a/test/integration/helpers/model-expect.ts b/test/integration/helpers/model-expect.ts
index 339932af5b..8872b1eb00 100644
--- a/test/integration/helpers/model-expect.ts
+++ b/test/integration/helpers/model-expect.ts
@@ -83,8 +83,8 @@ declare global {
toBeBusinessRuleTask(modelElement: ExpectedShapeModelElement): R;
toBeStartEvent(modelElement: ExpectedStartEventModelElement): R;
toBeEndEvent(modelElement: ExpectedEventModelElement): R;
- toBeIntermediateThrowEvent(modelElement: ExpectedEventModelElement): R;
- toBeIntermediateCatchEvent(modelElement: ExpectedEventModelElement): R;
+ toBeIntermediateThrowEvent(modelElement: ExpectedIntermediateThrowEventModelElement): R;
+ toBeIntermediateCatchEvent(modelElement: ExpectedIntermediateCatchEventModelElement): R;
toBeBoundaryEvent(modelElement: ExpectedBoundaryEventModelElement): R;
toBeEventBasedGateway(modelElement: ExpectedEventBasedGatewayModelElement): R;
toBeExclusiveGateway(modelElement: ExpectedShapeModelElement): R;
@@ -200,6 +200,18 @@ export type ExpectedShapeModelElement = {
export type ExpectedEventModelElement = {
eventDefinitionKind: ShapeBpmnEventDefinitionKind;
} & ExpectedShapeModelElement;
+export type ExpectedIntermediateCatchEventModelElement = {
+ sourceIds?: string[];
+} & ExpectedEventModelElement;
+export type ExpectedIntermediateThrowEventModelElement = {
+ targetId?: string;
+} & ExpectedEventModelElement;
+export type ExpectedBoundaryEventModelElement = {
+ isInterrupting?: boolean;
+} & ExpectedEventModelElement;
+export type ExpectedStartEventModelElement = {
+ isInterrupting?: boolean;
+} & ExpectedEventModelElement;
export type ExpectedSubProcessModelElement = {
subProcessKind: ShapeBpmnSubProcessKind;
@@ -220,13 +232,6 @@ export type ExpectedSequenceFlowModelElement = {
sequenceFlowKind?: SequenceFlowKind;
} & ExpectedEdgeModelElement;
-export type ExpectedBoundaryEventModelElement = {
- isInterrupting?: boolean;
-} & ExpectedEventModelElement;
-export type ExpectedStartEventModelElement = {
- isInterrupting?: boolean;
-} & ExpectedEventModelElement;
-
export type ExpectedEventBasedGatewayModelElement = {
gatewayKind?: ShapeBpmnEventBasedGatewayKind;
} & ExpectedShapeModelElement;
diff --git a/test/integration/helpers/semantic-with-svg-utils.ts b/test/integration/helpers/semantic-with-svg-utils.ts
index 456f409873..f122d0aaeb 100644
--- a/test/integration/helpers/semantic-with-svg-utils.ts
+++ b/test/integration/helpers/semantic-with-svg-utils.ts
@@ -15,11 +15,28 @@ limitations under the License.
*/
import type { BpmnElement, EdgeBpmnSemantic, ShapeBpmnSemantic } from '@lib/component/registry';
-import type { ExpectedBaseBpmnElement, ExpectedFlowElement, ExpectedFlowNodeElement, ExpectedEventElement } from '@test/shared/model/bpmn-semantic-utils';
+import type {
+ ExpectedBaseBpmnElement,
+ ExpectedFlowElement,
+ ExpectedFlowNodeElement,
+ ExpectedEventElement,
+ ExpectedIntermediateThrowEventElement,
+ ExpectedIntermediateCatchEventElement,
+} from '@test/shared/model/bpmn-semantic-utils';
import { expectSvgEvent, expectSvgGateway, expectSvgPool, expectSvgSequenceFlow, expectSvgTask } from './html-utils';
-import { expectEndEvent, expectParallelGateway, expectPool, expectSequenceFlow, expectServiceTask, expectStartEvent, expectTask } from '@test/shared/model/bpmn-semantic-utils';
+import {
+ expectEndEvent,
+ expectIntermediateCatchEvent,
+ expectIntermediateThrowEvent,
+ expectParallelGateway,
+ expectPool,
+ expectSequenceFlow,
+ expectServiceTask,
+ expectStartEvent,
+ expectTask,
+} from '@test/shared/model/bpmn-semantic-utils';
export function expectStartEventBpmnElement(bpmnElement: BpmnElement, expected: ExpectedEventElement): void {
expectStartEvent(bpmnElement.bpmnSemantic as ShapeBpmnSemantic, expected);
@@ -31,6 +48,16 @@ export function expectEndEventBpmnElement(bpmnElement: BpmnElement, expected: Ex
expectSvgEvent(bpmnElement.htmlElement);
}
+export function expectIntermediateCatchEventBpmnElement(bpmnElement: BpmnElement, expected: ExpectedIntermediateCatchEventElement): void {
+ expectIntermediateCatchEvent(bpmnElement.bpmnSemantic as ShapeBpmnSemantic, expected);
+ expectSvgEvent(bpmnElement.htmlElement);
+}
+
+export function expectIntermediateThrowEventBpmnElement(bpmnElement: BpmnElement, expected: ExpectedIntermediateThrowEventElement): void {
+ expectIntermediateThrowEvent(bpmnElement.bpmnSemantic as ShapeBpmnSemantic, expected);
+ expectSvgEvent(bpmnElement.htmlElement);
+}
+
export function expectSequenceFlowBpmnElement(bpmnElement: BpmnElement, expected: ExpectedFlowElement): void {
expectSequenceFlow(bpmnElement.bpmnSemantic as EdgeBpmnSemantic, expected);
expectSvgSequenceFlow(bpmnElement.htmlElement);
diff --git a/test/integration/matchers/toBeShape/index.ts b/test/integration/matchers/toBeShape/index.ts
index 655ec5bdac..2cf0333180 100644
--- a/test/integration/matchers/toBeShape/index.ts
+++ b/test/integration/matchers/toBeShape/index.ts
@@ -22,6 +22,8 @@ import type {
ExpectedShapeModelElement,
ExpectedStartEventModelElement,
ExpectedSubProcessModelElement,
+ ExpectedIntermediateCatchEventModelElement,
+ ExpectedIntermediateThrowEventModelElement,
} from '../../helpers/model-expect';
import type { BpmnCellStyle, ExpectedCell } from '../matcher-utils';
@@ -97,7 +99,8 @@ function buildExpectedShapeStylePropertyRegexp(
expectedModel:
| ExpectedShapeModelElement
| ExpectedSubProcessModelElement
- | ExpectedEventModelElement
+ | ExpectedIntermediateCatchEventModelElement
+ | ExpectedIntermediateThrowEventModelElement
| ExpectedStartEventModelElement
| ExpectedBoundaryEventModelElement
| ExpectedEventBasedGatewayModelElement
@@ -127,6 +130,12 @@ function buildExpectedShapeStylePropertyRegexp(
if ('gatewayKind' in expectedModel) {
expectedStyle = expectedStyle + `.*bpmn.gatewayKind=${expectedModel.gatewayKind}`;
}
+ if ('sourceIds' in expectedModel) {
+ expectedStyle = expectedStyle + `.*bpmn.linkEventSourceIds=${expectedModel.sourceIds}`;
+ }
+ if ('targetId' in expectedModel) {
+ expectedStyle = expectedStyle + `.*bpmn.linkEventTargetId=${expectedModel.targetId}`;
+ }
return expectedStyle + '.*';
}
@@ -221,11 +230,11 @@ export function toBeEndEvent(this: MatcherContext, received: string, expected: E
return buildEventMatcher('toBeEndEvent', this, received, { ...expected, kind: ShapeBpmnElementKind.EVENT_END });
}
-export function toBeIntermediateThrowEvent(this: MatcherContext, received: string, expected: ExpectedEventModelElement): CustomMatcherResult {
+export function toBeIntermediateThrowEvent(this: MatcherContext, received: string, expected: ExpectedIntermediateThrowEventModelElement): CustomMatcherResult {
return buildEventMatcher('toBeIntermediateThrowEvent', this, received, { ...expected, kind: ShapeBpmnElementKind.EVENT_INTERMEDIATE_THROW });
}
-export function toBeIntermediateCatchEvent(this: MatcherContext, received: string, expected: ExpectedEventModelElement): CustomMatcherResult {
+export function toBeIntermediateCatchEvent(this: MatcherContext, received: string, expected: ExpectedIntermediateCatchEventModelElement): CustomMatcherResult {
return buildEventMatcher('toBeIntermediateCatchEvent', this, received, { ...expected, kind: ShapeBpmnElementKind.EVENT_INTERMEDIATE_CATCH });
}
diff --git a/test/integration/model.elements.api.test.ts b/test/integration/model.elements.api.test.ts
index dd22e799a9..254dbc2c8e 100644
--- a/test/integration/model.elements.api.test.ts
+++ b/test/integration/model.elements.api.test.ts
@@ -26,6 +26,7 @@ import {
expectCallActivity,
expectEndEvent,
expectIntermediateCatchEvent,
+ expectIntermediateThrowEvent,
expectParallelGateway,
expectSequenceFlow,
expectStartEvent,
@@ -107,6 +108,27 @@ describe('Registry API - retrieve Model Bpmn elements', () => {
});
});
+ test('Pass link event (with source & target) ids', () => {
+ const modelElements = bpmnElementsRegistry.getModelElementsByIds(['intermediate_catch_event_link_on_top_id', 'intermediate_throw_event_link_on_top_id']);
+
+ expect(modelElements).toHaveLength(2);
+
+ expectIntermediateCatchEvent(modelElements[0] as ShapeBpmnSemantic, {
+ id: 'intermediate_catch_event_link_on_top_id',
+ name: 'Catch Link Intermediate Event On Top',
+ parentId: 'participant_1_id',
+ eventDefinitionKind: ShapeBpmnEventDefinitionKind.LINK,
+ linkEventSourceIds: ['intermediate_throw_event_link_on_top_id'],
+ });
+ expectIntermediateThrowEvent(modelElements[1] as ShapeBpmnSemantic, {
+ id: 'intermediate_throw_event_link_on_top_id',
+ name: 'Throw Link Intermediate Event On Top',
+ parentId: 'participant_1_id',
+ eventDefinitionKind: ShapeBpmnEventDefinitionKind.LINK,
+ linkEventTargetId: 'intermediate_catch_event_link_on_top_id',
+ });
+ });
+
test('Pass a single non existing id', () => {
expect(bpmnElementsRegistry.getModelElementsByIds('unknown')).toHaveLength(0);
});
@@ -139,11 +161,11 @@ describe('Registry API - retrieve Model Bpmn elements', () => {
target: 'gateway_with_flows_id',
});
expectStartEvent(modelElements[2] as ShapeBpmnSemantic, {
- eventDefinitionKind: ShapeBpmnEventDefinitionKind.NONE,
id: 'start_event_in_adHoc_sub_process_id',
name: 'Start Event In AdHoc Sub-Process',
outgoing: ['sequence_flow_in_adHoc_sub_process_1_id'],
parentId: 'expanded_adHoc_sub_process_id',
+ eventDefinitionKind: ShapeBpmnEventDefinitionKind.NONE,
});
expectBoundaryEvent(modelElements[3] as ShapeBpmnSemantic, {
eventDefinitionKind: ShapeBpmnEventDefinitionKind.TIMER,
diff --git a/test/shared/model/bpmn-semantic-utils.ts b/test/shared/model/bpmn-semantic-utils.ts
index 7a562efb1b..825b64b813 100644
--- a/test/shared/model/bpmn-semantic-utils.ts
+++ b/test/shared/model/bpmn-semantic-utils.ts
@@ -71,6 +71,8 @@ function expectedFlowNode(bpmnSemantic: ShapeBpmnSemantic, expected: ExpectedFlo
}
export type ExpectedEventElement = ExpectedFlowNodeElement & Pick;
+export type ExpectedIntermediateCatchEventElement = ExpectedEventElement & Pick;
+export type ExpectedIntermediateThrowEventElement = ExpectedEventElement & Pick;
function expectEvent(bpmnSemantic: ShapeBpmnSemantic, expected: ExpectedEventElement): void {
expectedFlowNode(bpmnSemantic, expected);
@@ -81,6 +83,7 @@ export function expectStartEvent(bpmnSemantic: ShapeBpmnSemantic, expected: Expe
expect(bpmnSemantic.kind).toEqual(ShapeBpmnElementKind.EVENT_START);
expectEvent(bpmnSemantic, expected);
}
+
export function expectEndEvent(bpmnSemantic: ShapeBpmnSemantic, expected: ExpectedEventElement): void {
expect(bpmnSemantic.kind).toEqual(ShapeBpmnElementKind.EVENT_END);
expectEvent(bpmnSemantic, expected);
@@ -91,9 +94,18 @@ export function expectBoundaryEvent(bpmnSemantic: ShapeBpmnSemantic, expected: E
expectEvent(bpmnSemantic, expected);
}
-export function expectIntermediateCatchEvent(bpmnSemantic: ShapeBpmnSemantic, expected: ExpectedEventElement): void {
+export function expectIntermediateCatchEvent(bpmnSemantic: ShapeBpmnSemantic, expected: ExpectedIntermediateCatchEventElement): void {
expect(bpmnSemantic.kind).toEqual(ShapeBpmnElementKind.EVENT_INTERMEDIATE_CATCH);
expectEvent(bpmnSemantic, expected);
+ expect(bpmnSemantic.linkEventSourceIds).toStrictEqual(expected.linkEventSourceIds);
+ expect(bpmnSemantic.linkEventTargetId).toBeUndefined();
+}
+
+export function expectIntermediateThrowEvent(bpmnSemantic: ShapeBpmnSemantic, expected: ExpectedIntermediateThrowEventElement): void {
+ expect(bpmnSemantic.kind).toEqual(ShapeBpmnElementKind.EVENT_INTERMEDIATE_THROW);
+ expectEvent(bpmnSemantic, expected);
+ expect(bpmnSemantic.linkEventSourceIds).toBeUndefined();
+ expect(bpmnSemantic.linkEventTargetId).toStrictEqual(expected.linkEventTargetId);
}
export function expectParallelGateway(bpmnSemantic: BpmnSemantic, expected: ExpectedFlowNodeElement): void {
diff --git a/test/unit/component/registry/bpmn-model-registry.test.ts b/test/unit/component/registry/bpmn-model-registry.test.ts
index 8aa20b78dc..1b37b5c843 100644
--- a/test/unit/component/registry/bpmn-model-registry.test.ts
+++ b/test/unit/component/registry/bpmn-model-registry.test.ts
@@ -16,11 +16,29 @@ limitations under the License.
import type { EdgeBpmnSemantic, ShapeBpmnSemantic } from '@lib/component/registry';
-import { associationFlowInModel, laneInModel, messageFlowInModel, poolInModel, sequenceFlowInModel, startEventInModel } from '../../helpers/bpmn-model-utils';
+import {
+ associationFlowInModel,
+ intermediateCatchEventInModel,
+ intermediateThrowEventInModel,
+ laneInModel,
+ messageFlowInModel,
+ poolInModel,
+ sequenceFlowInModel,
+ startEventInModel,
+} from '../../helpers/bpmn-model-utils';
import { BpmnModelRegistry } from '@lib/component/registry/bpmn-model-registry';
import { ShapeBpmnEventDefinitionKind } from '@lib/model/bpmn/internal';
-import { expectAssociationFlow, expectLane, expectMessageFlow, expectPool, expectSequenceFlow, expectStartEvent } from '@test/shared/model/bpmn-semantic-utils';
+import {
+ expectAssociationFlow,
+ expectIntermediateCatchEvent,
+ expectIntermediateThrowEvent,
+ expectLane,
+ expectMessageFlow,
+ expectPool,
+ expectSequenceFlow,
+ expectStartEvent,
+} from '@test/shared/model/bpmn-semantic-utils';
const bpmnModelRegistry = new BpmnModelRegistry();
@@ -52,6 +70,7 @@ describe('Bpmn Model registry', () => {
it('search flowNode', () => {
bpmnModelRegistry.load(startEventInModel('start event id', 'start event name', { incomingIds: ['incoming_1'], outgoingIds: ['outgoing_1', 'outgoing_2'] }));
const bpmnSemantic = bpmnModelRegistry.getBpmnSemantic('start event id') as ShapeBpmnSemantic;
+
expectStartEvent(bpmnSemantic, {
id: 'start event id',
name: 'start event name',
@@ -62,6 +81,47 @@ describe('Bpmn Model registry', () => {
});
});
+ it('search intermediate catch event', () => {
+ bpmnModelRegistry.load(
+ intermediateCatchEventInModel('intermediate catch event id', 'intermediate catch event name', { incomingIds: ['incoming_1'], outgoingIds: ['outgoing_1', 'outgoing_2'] }, [
+ 'sourceId',
+ ]),
+ );
+ const bpmnSemantic = bpmnModelRegistry.getBpmnSemantic('intermediate catch event id') as ShapeBpmnSemantic;
+
+ expectIntermediateCatchEvent(bpmnSemantic, {
+ id: 'intermediate catch event id',
+ name: 'intermediate catch event name',
+ incoming: ['incoming_1'],
+ outgoing: ['outgoing_1', 'outgoing_2'],
+ parentId: 'parentId',
+ eventDefinitionKind: ShapeBpmnEventDefinitionKind.LINK,
+ linkEventSourceIds: ['sourceId'],
+ });
+ });
+
+ it('search intermediate throw event', () => {
+ bpmnModelRegistry.load(
+ intermediateThrowEventInModel(
+ 'intermediate throw event id',
+ 'intermediate throw event name',
+ { incomingIds: ['incoming_1'], outgoingIds: ['outgoing_1', 'outgoing_2'] },
+ 'targetId',
+ ),
+ );
+ const bpmnSemantic = bpmnModelRegistry.getBpmnSemantic('intermediate throw event id') as ShapeBpmnSemantic;
+
+ expectIntermediateThrowEvent(bpmnSemantic, {
+ id: 'intermediate throw event id',
+ name: 'intermediate throw event name',
+ incoming: ['incoming_1'],
+ outgoing: ['outgoing_1', 'outgoing_2'],
+ parentId: 'parentId',
+ eventDefinitionKind: ShapeBpmnEventDefinitionKind.LINK,
+ linkEventTargetId: 'targetId',
+ });
+ });
+
it('search lane', () => {
bpmnModelRegistry.load(laneInModel('lane id', 'lane name'));
const bpmnSemantic = bpmnModelRegistry.getBpmnSemantic('lane id');
diff --git a/test/unit/helpers/bpmn-model-expect.ts b/test/unit/helpers/bpmn-model-expect.ts
index 4cc4f842c4..7ffc35ae81 100644
--- a/test/unit/helpers/bpmn-model-expect.ts
+++ b/test/unit/helpers/bpmn-model-expect.ts
@@ -52,15 +52,15 @@ export interface ExpectedEventShape extends ExpectedShape {
eventDefinitionKind: ShapeBpmnEventDefinitionKind;
}
-export interface ExpectedCatchEventShape extends ExpectedEventShape {
+export interface ExpectedIntermediateCatchEventShape extends ExpectedEventShape {
sourceIds?: string[];
}
-export interface ExpectedThrowEventShape extends ExpectedEventShape {
+export interface ExpectedIntermediateThrowEventShape extends ExpectedEventShape {
targetId?: string;
}
-export interface ExpectedBoundaryEventShape extends ExpectedCatchEventShape {
+export interface ExpectedBoundaryEventShape extends ExpectedEventShape {
isInterrupting?: boolean;
}
@@ -103,7 +103,14 @@ export interface ExpectedBounds {
export const verifyShape = (
shape: Shape,
- expectedShape: ExpectedShape | ExpectedActivityShape | ExpectedCallActivityShape | ExpectedCatchEventShape | ExpectedThrowEventShape | ExpectedBoundaryEventShape,
+ expectedShape:
+ | ExpectedShape
+ | ExpectedActivityShape
+ | ExpectedCallActivityShape
+ | ExpectedEventShape
+ | ExpectedIntermediateCatchEventShape
+ | ExpectedIntermediateThrowEventShape
+ | ExpectedBoundaryEventShape,
): void => {
expect(shape.id).toEqual(expectedShape.shapeId);
expect(shape.isHorizontal).toEqual(expectedShape.isHorizontal);
@@ -139,9 +146,9 @@ export const verifyShape = (
if (expectedEvent.eventDefinitionKind === ShapeBpmnEventDefinitionKind.LINK) {
if (ShapeUtil.isIntermediateCatchEvent(expectedShape.bpmnElementKind)) {
- expect((event as ShapeBpmnIntermediateCatchEvent).sourceIds).toEqual((expectedEvent as ExpectedCatchEventShape).sourceIds ?? []);
- } else {
- expect((event as ShapeBpmnIntermediateThrowEvent).targetId).toEqual((expectedEvent as ExpectedThrowEventShape).targetId);
+ expect((event as ShapeBpmnIntermediateCatchEvent).sourceIds).toEqual((expectedEvent as ExpectedIntermediateCatchEventShape).sourceIds ?? []);
+ } else if (ShapeUtil.isIntermediateThrowEvent(expectedShape.bpmnElementKind)) {
+ expect((event as ShapeBpmnIntermediateThrowEvent).targetId).toEqual((expectedEvent as ExpectedIntermediateThrowEventShape).targetId);
}
}
}
diff --git a/test/unit/helpers/bpmn-model-utils.ts b/test/unit/helpers/bpmn-model-utils.ts
index cd9d8c7261..9f4d6be5d1 100644
--- a/test/unit/helpers/bpmn-model-utils.ts
+++ b/test/unit/helpers/bpmn-model-utils.ts
@@ -27,6 +27,8 @@ import ShapeBpmnElement, {
ShapeBpmnCallActivity,
ShapeBpmnStartEvent,
ShapeBpmnSubProcess,
+ ShapeBpmnIntermediateThrowEvent,
+ ShapeBpmnIntermediateCatchEvent,
} from '@lib/model/bpmn/internal/shape/ShapeBpmnElement';
const newBpmnModel = (): BpmnModel => ({
@@ -73,6 +75,18 @@ export const startEventInModel = (id: string, name: string, extras?: ShapeBpmnEl
return bpmnModel;
};
+export const intermediateCatchEventInModel = (id: string, name: string, extras?: ShapeBpmnElementExtraProperties, sourceIds?: string[]): BpmnModel => {
+ const bpmnModel = newBpmnModel();
+ bpmnModel.flowNodes.push(newIntermediateCatchEvent('parentId', id, name, extras, sourceIds));
+ return bpmnModel;
+};
+
+export const intermediateThrowEventInModel = (id: string, name: string, extras?: ShapeBpmnElementExtraProperties, targetId?: string): BpmnModel => {
+ const bpmnModel = newBpmnModel();
+ bpmnModel.flowNodes.push(newIntermediateThrowEvent('parentId', id, name, extras, targetId));
+ return bpmnModel;
+};
+
export const laneInModel = (id: string, name: string): BpmnModel => {
const bpmnModel = newBpmnModel();
bpmnModel.lanes.push(new Shape(buildShapeId(id), new ShapeBpmnElement(id, name, ShapeBpmnElementKind.LANE)));
@@ -99,6 +113,19 @@ export type ShapeBpmnElementExtraProperties = {
const newStartEvent = (parent: string, id: string, name: string, extras?: ShapeBpmnElementExtraProperties): Shape => {
return new Shape(buildShapeId(id), withExtras(new ShapeBpmnStartEvent(id, name, ShapeBpmnEventDefinitionKind.TIMER, parent), extras));
};
+
+const newIntermediateCatchEvent = (parent: string, id: string, name: string, extras?: ShapeBpmnElementExtraProperties, sourceIds: string[] = []): Shape => {
+ const bpmnElement = new ShapeBpmnIntermediateCatchEvent(id, name, ShapeBpmnEventDefinitionKind.LINK, parent);
+ bpmnElement.sourceIds = sourceIds;
+ return new Shape(buildShapeId(id), withExtras(bpmnElement, extras));
+};
+
+const newIntermediateThrowEvent = (parent: string, id: string, name: string, extras?: ShapeBpmnElementExtraProperties, targetId?: string): Shape => {
+ const bpmnElement = new ShapeBpmnIntermediateThrowEvent(id, name, ShapeBpmnEventDefinitionKind.LINK, parent);
+ bpmnElement.targetId = targetId;
+ return new Shape(buildShapeId(id), withExtras(bpmnElement, extras));
+};
+
const newBoundaryEvent = (parent: string, id: string, name: string): Shape =>
new Shape(buildShapeId(id), new ShapeBpmnBoundaryEvent(id, name, ShapeBpmnEventDefinitionKind.CANCEL, parent));