1212 *******************************************************************************/
1313package org .eclipse .syson .application .controllers .diagrams .general .view ;
1414
15+ import static org .assertj .core .api .Assertions .assertThat ;
16+
1517import java .time .Duration ;
18+ import java .util .List ;
1619import java .util .UUID ;
1720import java .util .concurrent .atomic .AtomicReference ;
1821import java .util .stream .Stream ;
1922
23+ import org .apache .commons .lang3 .StringUtils ;
2024import org .eclipse .emf .ecore .EClass ;
2125import org .eclipse .emf .ecore .EReference ;
2226import org .eclipse .sirius .components .collaborative .diagrams .dto .DiagramEventInput ;
2327import org .eclipse .sirius .components .collaborative .diagrams .dto .DiagramRefreshedEventPayload ;
28+ import org .eclipse .sirius .components .collaborative .diagrams .dto .ToolVariable ;
29+ import org .eclipse .sirius .components .collaborative .diagrams .dto .ToolVariableType ;
30+ import org .eclipse .sirius .components .core .api .IIdentityService ;
2431import org .eclipse .sirius .components .core .api .IObjectSearchService ;
2532import org .eclipse .sirius .components .diagrams .Diagram ;
2633import org .eclipse .sirius .components .view .diagram .DiagramDescription ;
4653import org .eclipse .syson .services .diagrams .api .IGivenDiagramDescription ;
4754import org .eclipse .syson .services .diagrams .api .IGivenDiagramReference ;
4855import org .eclipse .syson .services .diagrams .api .IGivenDiagramSubscription ;
56+ import org .eclipse .syson .sysml .ActionUsage ;
57+ import org .eclipse .syson .sysml .PerformActionUsage ;
58+ import org .eclipse .syson .sysml .ReferenceSubsetting ;
59+ import org .eclipse .syson .sysml .StateSubactionKind ;
60+ import org .eclipse .syson .sysml .StateSubactionMembership ;
4961import org .eclipse .syson .sysml .SysmlPackage ;
5062import org .eclipse .syson .util .IDescriptionNameGenerator ;
63+ import org .jetbrains .annotations .NotNull ;
5164import org .junit .jupiter .api .AfterEach ;
5265import org .junit .jupiter .api .BeforeEach ;
5366import org .junit .jupiter .params .ParameterizedTest ;
@@ -104,6 +117,9 @@ public class GVSubNodeStateTransitionCreationTests extends AbstractIntegrationTe
104117 @ Autowired
105118 private DiagramComparator diagramComparator ;
106119
120+ @ Autowired
121+ private IIdentityService identityService ;
122+
107123 private DiagramDescriptionIdProvider diagramDescriptionIdProvider ;
108124
109125 private Step <DiagramRefreshedEventPayload > verifier ;
@@ -120,11 +136,11 @@ public class GVSubNodeStateTransitionCreationTests extends AbstractIntegrationTe
120136
121137 private SemanticCheckerService semanticCheckerService ;
122138
123- private static Stream <Arguments > stateUsageSiblingNodeParameters () {
139+ private static Stream <Arguments > stateSubactionsParameters () {
124140 return Stream .of (
125- Arguments .of (SysmlPackage . eINSTANCE . getActionUsage (), SysmlPackage . eINSTANCE . getStateUsage_EntryAction (), "New Entry Action" , 4 ),
126- Arguments .of (SysmlPackage . eINSTANCE . getActionUsage (), SysmlPackage . eINSTANCE . getStateUsage_DoAction (), "New Do Action" , 4 ),
127- Arguments .of (SysmlPackage . eINSTANCE . getActionUsage (), SysmlPackage . eINSTANCE . getStateUsage_ExitAction (), "New Exit Action" , 4 ))
141+ Arguments .of (StateSubactionKind . ENTRY ),
142+ Arguments .of (StateSubactionKind . DO ),
143+ Arguments .of (StateSubactionKind . EXIT ))
128144 .map (TestNameGenerator ::namedArguments );
129145 }
130146
@@ -138,14 +154,6 @@ private static Stream<Arguments> stateUsageChildNodeParameters() {
138154 .map (TestNameGenerator ::namedArguments );
139155 }
140156
141- private static Stream <Arguments > stateDefinitionSiblingNodeParameters () {
142- return Stream .of (
143- Arguments .of (SysmlPackage .eINSTANCE .getActionUsage (), SysmlPackage .eINSTANCE .getStateDefinition_EntryAction (), "New Entry Action" , 4 ),
144- Arguments .of (SysmlPackage .eINSTANCE .getActionUsage (), SysmlPackage .eINSTANCE .getStateDefinition_DoAction (), "New Do Action" , 4 ),
145- Arguments .of (SysmlPackage .eINSTANCE .getActionUsage (), SysmlPackage .eINSTANCE .getStateDefinition_ExitAction (), "New Exit Action" , 4 ))
146- .map (TestNameGenerator ::namedArguments );
147- }
148-
149157 private static Stream <Arguments > stateDefinitionChildNodeParameters () {
150158 return Stream .of (
151159 Arguments .of (SysmlPackage .eINSTANCE .getDocumentation (), DOC_COMPARTMENT , SysmlPackage .eINSTANCE .getElement_Documentation (), "New Documentation" ),
@@ -185,16 +193,98 @@ public void tearDown() {
185193 @ Sql (scripts = { GeneralViewWithTopNodesTestProjectData .SCRIPT_PATH }, executionPhase = Sql .ExecutionPhase .BEFORE_TEST_METHOD )
186194 @ Sql (scripts = { "/scripts/cleanup.sql" }, executionPhase = Sql .ExecutionPhase .AFTER_TEST_METHOD , config = @ SqlConfig (transactionMode = SqlConfig .TransactionMode .ISOLATED ))
187195 @ ParameterizedTest
188- @ MethodSource ("stateUsageSiblingNodeParameters" )
189- public void createStateUsageSiblingNodes (EClass childEClass , EReference containmentReference , String creationToolName , int compartmentCount ) {
190- EClass parentEClass = SysmlPackage .eINSTANCE .getStateUsage ();
191- String parentLabel = "state" ;
196+ @ MethodSource ("stateSubactionsParameters" )
197+ public void createStateUsageSubactionNode (StateSubactionKind kind ) {
198+ String toolName = "New " + StringUtils .capitalize (kind .getName ()) + " Action" ;
192199
193- this .creationTestsService .createNode (this .verifier , this .diagramDescriptionIdProvider , this .diagram , parentEClass , parentLabel , creationToolName );
194- // the action is created inside a list compartment and outside as a sibling node
195- this .diagramCheckerService .checkDiagram (this .diagramCheckerService .getSiblingNodeGraphicalChecker (this .diagram , this .diagramDescriptionIdProvider , childEClass , compartmentCount , 2 ),
196- this .diagram , this .verifier );
197- this .semanticCheckerService .checkEditingContext (this .semanticCheckerService .getElementInParentSemanticChecker (parentLabel , containmentReference , childEClass ), this .verifier );
200+ this .createStateSubactionNode (kind , SysmlPackage .eINSTANCE .getStateUsage (), "state" , toolName );
201+ }
202+
203+ @ Sql (scripts = { GeneralViewWithTopNodesTestProjectData .SCRIPT_PATH }, executionPhase = Sql .ExecutionPhase .BEFORE_TEST_METHOD )
204+ @ Sql (scripts = { "/scripts/cleanup.sql" }, executionPhase = Sql .ExecutionPhase .AFTER_TEST_METHOD , config = @ SqlConfig (transactionMode = SqlConfig .TransactionMode .ISOLATED ))
205+ @ ParameterizedTest
206+ @ MethodSource ("stateSubactionsParameters" )
207+ public void createStateUsageSubactionWithReferencedActionNode (StateSubactionKind kind ) {
208+ String toolName = "New " + StringUtils .capitalize (kind .getName ()) + " Action with referenced Action" ;
209+ var params = List .of (new ToolVariable ("selectedObject" , GeneralViewWithTopNodesTestProjectData .SemanticIds .ACTION_USAGE_ID , ToolVariableType .OBJECT_ID ));
210+
211+ this .createStateSubactionWithReferencedActionNode (kind , SysmlPackage .eINSTANCE .getStateUsage (), "state" , toolName , params );
212+ }
213+
214+ @ Sql (scripts = { GeneralViewWithTopNodesTestProjectData .SCRIPT_PATH }, executionPhase = Sql .ExecutionPhase .BEFORE_TEST_METHOD )
215+ @ Sql (scripts = { "/scripts/cleanup.sql" }, executionPhase = Sql .ExecutionPhase .AFTER_TEST_METHOD , config = @ SqlConfig (transactionMode = SqlConfig .TransactionMode .ISOLATED ))
216+ @ ParameterizedTest
217+ @ MethodSource ("stateSubactionsParameters" )
218+ public void createStateDefinitionSubactionNode (StateSubactionKind kind ) {
219+ String toolName = "New " + StringUtils .capitalize (kind .getName ()) + " Action" ;
220+
221+ this .createStateSubactionNode (kind , SysmlPackage .eINSTANCE .getStateDefinition (), "StateDefinition" , toolName );
222+ }
223+
224+ @ Sql (scripts = { GeneralViewWithTopNodesTestProjectData .SCRIPT_PATH }, executionPhase = Sql .ExecutionPhase .BEFORE_TEST_METHOD )
225+ @ Sql (scripts = { "/scripts/cleanup.sql" }, executionPhase = Sql .ExecutionPhase .AFTER_TEST_METHOD , config = @ SqlConfig (transactionMode = SqlConfig .TransactionMode .ISOLATED ))
226+ @ ParameterizedTest
227+ @ MethodSource ("stateSubactionsParameters" )
228+ public void createStateDefinitionSubactionWithReferencedActionNode (StateSubactionKind kind ) {
229+ String toolName = "New " + StringUtils .capitalize (kind .getName ()) + " Action with referenced Action" ;
230+ var params = List .of (new ToolVariable ("selectedObject" , GeneralViewWithTopNodesTestProjectData .SemanticIds .ACTION_USAGE_ID , ToolVariableType .OBJECT_ID ));
231+
232+ this .createStateSubactionWithReferencedActionNode (kind , SysmlPackage .eINSTANCE .getStateDefinition (), "StateDefinition" , toolName , params );
233+ }
234+
235+ private void createStateSubactionNode (StateSubactionKind kind , EClass parentEClass , String parentLabel , String toolName ) {
236+ this .creationTestsService .createNode (this .verifier , this .diagramDescriptionIdProvider , this .diagram , parentEClass , parentLabel , toolName );
237+
238+ String [] subActionId = new String [1 ];
239+ IDiagramChecker diagramChecker = (initialDiagram , newDiagram ) -> {
240+ new CheckDiagramElementCount (this .diagramComparator )
241+ // only the new subaction should be created
242+ .hasNewNodeCount (1 )
243+ .hasNewEdgeCount (0 )
244+ .check (initialDiagram , newDiagram );
245+ var node = this .diagramComparator .newNodes (initialDiagram , newDiagram ).get (0 );
246+ subActionId [0 ] = node .getTargetObjectId ();
247+ };
248+ this .diagramCheckerService .checkDiagram (diagramChecker , this .diagram , this .verifier );
249+
250+ this .semanticCheckerService .checkElement (this .verifier , PerformActionUsage .class , () -> subActionId [0 ], subaction -> {
251+ // new subaction should be owned by a StateSubactionMembership with the correct kind
252+ var parentMembership = subaction .eContainer ();
253+ assertThat (parentMembership ).isInstanceOf (StateSubactionMembership .class );
254+ var stateSubactionMembership = (StateSubactionMembership ) parentMembership ;
255+ assertThat (stateSubactionMembership .getKind ()).isEqualTo (kind );
256+ // subaction has no owned membership
257+ assertThat (subaction .getOwnedRelationship ()).hasSize (0 );
258+ });
259+ }
260+
261+ private void createStateSubactionWithReferencedActionNode (StateSubactionKind kind , EClass parentEClass , String parentLabel , String toolName , List <@ NotNull ToolVariable > params ) {
262+ this .creationTestsService .createNode (this .verifier , this .diagramDescriptionIdProvider , this .diagram , parentEClass , parentLabel , toolName , params );
263+
264+ String [] subActionId = new String [1 ];
265+ IDiagramChecker diagramChecker = (initialDiagram , newDiagram ) -> {
266+ new CheckDiagramElementCount (this .diagramComparator )
267+ // only the new subaction should be created
268+ .hasNewNodeCount (1 )
269+ .hasNewEdgeCount (0 )
270+ .check (initialDiagram , newDiagram );
271+ var node = this .diagramComparator .newNodes (initialDiagram , newDiagram ).get (0 );
272+ subActionId [0 ] = node .getTargetObjectId ();
273+ };
274+ this .diagramCheckerService .checkDiagram (diagramChecker , this .diagram , this .verifier );
275+
276+ this .semanticCheckerService .checkElement (this .verifier , PerformActionUsage .class , () -> subActionId [0 ], subaction -> {
277+ var membership = subaction .eContainer ();
278+ assertThat (membership ).isInstanceOf (StateSubactionMembership .class );
279+ var stateSubactionMembership = (StateSubactionMembership ) membership ;
280+ assertThat (stateSubactionMembership .getKind ()).isEqualTo (kind );
281+ // check that the new sub action contains the reference subsetting to the existing action
282+ var memberships = subaction .getOwnedRelationship ();
283+ assertThat (memberships .get (0 )).isInstanceOf (ReferenceSubsetting .class );
284+ var referenceSubsetting = (ReferenceSubsetting ) memberships .get (0 );
285+ assertThat (referenceSubsetting .getReferencedFeature ()).isInstanceOf (ActionUsage .class );
286+ assertThat (this .identityService .getId (referenceSubsetting .getReferencedFeature ())).isEqualTo (GeneralViewWithTopNodesTestProjectData .SemanticIds .ACTION_USAGE_ID );
287+ });
198288 }
199289
200290 @ Sql (scripts = { GeneralViewWithTopNodesTestProjectData .SCRIPT_PATH }, executionPhase = Sql .ExecutionPhase .BEFORE_TEST_METHOD )
@@ -231,21 +321,6 @@ public void createStateUsageChildNodes(EClass childEClass, String compartmentNam
231321 }
232322 }
233323
234- @ Sql (scripts = { GeneralViewWithTopNodesTestProjectData .SCRIPT_PATH }, executionPhase = Sql .ExecutionPhase .BEFORE_TEST_METHOD )
235- @ Sql (scripts = { "/scripts/cleanup.sql" }, executionPhase = Sql .ExecutionPhase .AFTER_TEST_METHOD , config = @ SqlConfig (transactionMode = SqlConfig .TransactionMode .ISOLATED ))
236- @ ParameterizedTest
237- @ MethodSource ("stateDefinitionSiblingNodeParameters" )
238- public void createStateDefinitionSiblingNodes (EClass childEClass , EReference containmentReference , String creationToolName , int compartmentCount ) {
239- EClass parentEClass = SysmlPackage .eINSTANCE .getStateDefinition ();
240- String parentLabel = "StateDefinition" ;
241-
242- this .creationTestsService .createNode (this .verifier , this .diagramDescriptionIdProvider , this .diagram , parentEClass , parentLabel , creationToolName );
243- // the action is created inside a list compartment and outside as a sibling node
244- this .diagramCheckerService .checkDiagram (this .diagramCheckerService .getSiblingNodeGraphicalChecker (this .diagram , this .diagramDescriptionIdProvider , childEClass , compartmentCount , 2 ),
245- this .diagram , this .verifier );
246- this .semanticCheckerService .checkEditingContext (this .semanticCheckerService .getElementInParentSemanticChecker (parentLabel , containmentReference , childEClass ), this .verifier );
247- }
248-
249324 @ Sql (scripts = { GeneralViewWithTopNodesTestProjectData .SCRIPT_PATH }, executionPhase = Sql .ExecutionPhase .BEFORE_TEST_METHOD )
250325 @ Sql (scripts = { "/scripts/cleanup.sql" }, executionPhase = Sql .ExecutionPhase .AFTER_TEST_METHOD , config = @ SqlConfig (transactionMode = SqlConfig .TransactionMode .ISOLATED ))
251326 @ ParameterizedTest
0 commit comments