1313package org .eclipse .syson .application .controllers .diagrams .general .view ;
1414
1515import static org .assertj .core .api .Assertions .assertThat ;
16+ import static org .assertj .core .api .InstanceOfAssertFactories .type ;
1617import static org .eclipse .sirius .components .diagrams .tests .DiagramEventPayloadConsumer .assertRefreshedDiagramThat ;
1718import static org .junit .jupiter .api .Assertions .assertFalse ;
1819
5859import org .eclipse .syson .sysml .Element ;
5960import org .eclipse .syson .sysml .PartUsage ;
6061import org .eclipse .syson .sysml .ReferenceUsage ;
62+ import org .eclipse .syson .sysml .Specialization ;
6163import org .eclipse .syson .sysml .Subsetting ;
6264import org .eclipse .syson .sysml .SysmlPackage ;
6365import org .eclipse .syson .sysml .Type ;
6466import org .eclipse .syson .sysml .helper .EMFUtils ;
6567import org .eclipse .syson .util .IDescriptionNameGenerator ;
6668import org .eclipse .syson .util .SysONRepresentationDescriptionIdentifiers ;
6769import org .junit .jupiter .api .BeforeEach ;
70+ import org .junit .jupiter .api .DisplayName ;
6871import org .junit .jupiter .api .Test ;
6972import org .junit .jupiter .params .ParameterizedTest ;
7073import org .junit .jupiter .params .provider .Arguments ;
8285 * @author arichard
8386 */
8487@ Transactional
88+ @ SuppressWarnings ("checkstyle:MultipleStringLiterals" )
8589@ SpringBootTest (webEnvironment = SpringBootTest .WebEnvironment .RANDOM_PORT )
8690public class GVSubNodeAnalysisCreationTests extends AbstractIntegrationTests {
8791
@@ -477,30 +481,48 @@ public void createUseCaseDefinitionChildNodes(EClass childEClass, String compart
477481 .verify (Duration .ofSeconds (10 ));
478482 }
479483
484+ @ DisplayName ("GIVEN a Case, WHEN creating a new Subject selecting a Part, THEN the Subject subsetted by the Part is created in the Case" )
480485 @ GivenSysONServer ({ GeneralViewWithTopNodesTestProjectData .SCRIPT_PATH })
481486 @ Test
482487 public void createNewUsageSubjectInCaseUsage () {
483488 this .createSubjectWithSubsettingInCaseUsage (SysmlPackage .eINSTANCE .getCaseUsage (), GeneralViewWithTopNodesTestProjectData .SemanticIds .CASE_USAGE_ID , CASE );
484489 }
485490
491+ @ DisplayName ("GIVEN a UseCase, WHEN creating a new Subject selecting a Part, THEN the Subject subsetted by the Part is created in the UseCase" )
486492 @ GivenSysONServer ({ GeneralViewWithTopNodesTestProjectData .SCRIPT_PATH })
487493 @ Test
488494 public void createNewUsageSubjectInUseCaseUsage () {
489495 this .createSubjectWithSubsettingInCaseUsage (SysmlPackage .eINSTANCE .getUseCaseUsage (), GeneralViewWithTopNodesTestProjectData .SemanticIds .USE_CASE_USAGE_ID , USE_CASE );
490496 }
491497
498+ @ DisplayName ("GIVEN a Case, WHEN creating a new Subject selecting a PartDefinition, THEN the Subject typed by the PartDefinition is created in the Case" )
492499 @ GivenSysONServer ({ GeneralViewWithTopNodesTestProjectData .SCRIPT_PATH })
493500 @ Test
494501 public void createNewDefinitionSubjectInCaseUsage () {
495502 this .createSubjectWithFeatureTypingInCaseUsage (SysmlPackage .eINSTANCE .getCaseUsage (), GeneralViewWithTopNodesTestProjectData .SemanticIds .CASE_USAGE_ID , CASE );
496503 }
497504
505+ @ DisplayName ("GIVEN a UseCase, WHEN creating a new Subject selecting a PartDefinition, THEN the Subject typed by the PartDefinition is created in the UseCase" )
498506 @ GivenSysONServer ({ GeneralViewWithTopNodesTestProjectData .SCRIPT_PATH })
499507 @ Test
500508 public void createNewDefinitionSubjectInUseCaseUsage () {
501509 this .createSubjectWithFeatureTypingInCaseUsage (SysmlPackage .eINSTANCE .getUseCaseUsage (), GeneralViewWithTopNodesTestProjectData .SemanticIds .USE_CASE_USAGE_ID , USE_CASE );
502510 }
503511
512+ @ DisplayName ("GIVEN a Case, WHEN creating a new Subject without selection, THEN the Subject without specialization is created in the Case" )
513+ @ GivenSysONServer ({ GeneralViewWithTopNodesTestProjectData .SCRIPT_PATH })
514+ @ Test
515+ public void createNewSubjectWithoutSpecializationInCaseUsage () {
516+ this .createSubjectWithoutSpecializationInCaseUsage (SysmlPackage .eINSTANCE .getCaseUsage (), GeneralViewWithTopNodesTestProjectData .SemanticIds .CASE_USAGE_ID , CASE );
517+ }
518+
519+ @ DisplayName ("GIVEN a UseCase, WHEN creating a new Subject without selection, THEN the Subject without specialization is created in the UseCase" )
520+ @ GivenSysONServer ({ GeneralViewWithTopNodesTestProjectData .SCRIPT_PATH })
521+ @ Test
522+ public void createNewSubjectWithoutSpecializationInUseCaseUsage () {
523+ this .createSubjectWithoutSpecializationInCaseUsage (SysmlPackage .eINSTANCE .getUseCaseUsage (), GeneralViewWithTopNodesTestProjectData .SemanticIds .USE_CASE_USAGE_ID , USE_CASE );
524+ }
525+
504526 @ GivenSysONServer ({ GeneralViewWithTopNodesTestProjectData .SCRIPT_PATH })
505527 @ Test
506528 public void createNewActorWithSubsettingInCaseUsage () {
@@ -538,11 +560,8 @@ private void createSubjectWithSubsettingInCaseUsage(EClass caseUsageSubclass, St
538560 EClass childEClass = SysmlPackage .eINSTANCE .getReferenceUsage ();
539561 String creationToolName = "New Subject" ;
540562 EReference containmentReference = SysmlPackage .eINSTANCE .getCaseUsage_SubjectParameter ();
541- List <ToolVariable > variables = new ArrayList <>();
542- String existingPartId = "2c5fe5a5-18fe-40f4-ab66-a2d91ab7df6a" ;
543- variables .add (new ToolVariable ("selectedObject" , existingPartId , ToolVariableType .OBJECT_ID ));
544563
545- Runnable createNodeRunnable = this .creationTestsService .createNode (diagramDescriptionIdProvider , diagram , caseUsageSubclass , targetObjectId , creationToolName , variables );
564+ Runnable createNodeRunnable = this .creationTestsService .createNodeWithSelectionDialogWithSingleSelection (diagramDescriptionIdProvider , diagram , caseUsageSubclass , targetObjectId , creationToolName , GeneralViewWithTopNodesTestProjectData . SemanticIds . PART_USAGE_ID );
546565
547566 Consumer <Object > diagramCheck = assertRefreshedDiagramThat (newDiagram -> {
548567 var initialDiagram = diagram .get ();
@@ -566,28 +585,24 @@ private void createSubjectWithSubsettingInCaseUsage(EClass caseUsageSubclass, St
566585 .check (initialDiagram , newDiagram );
567586 });
568587
569- ISemanticChecker semanticChecker = (editingContext ) -> {
570- Object semanticRootObject = this .objectSearchService .getObject (editingContext , GeneralViewWithTopNodesTestProjectData .SemanticIds .PACKAGE_1_ID ).orElse (null );
571- assertThat (semanticRootObject ).isInstanceOf (Element .class );
572- Element semanticRootElement = (Element ) semanticRootObject ;
573- Optional <ReferenceUsage > optParentElement = EMFUtils .allContainedObjectOfType (semanticRootElement , ReferenceUsage .class )
574- .filter (element -> Objects .equals (element .getName (), "subject" ))
575- .findFirst ();
576- assertThat (optParentElement ).isPresent ();
577- var referenceUsage = optParentElement .get ();
578- EList <Subsetting > subjectSubsets = referenceUsage .getOwnedSubsetting ();
579- assertFalse (subjectSubsets .isEmpty ());
580- assertThat (subjectSubsets .get (0 ).getSubsettedFeature ().getName ()).isEqualTo ("part" );
588+ Consumer <Object > additionalCheck = referencedObject -> {
589+ assertThat (referencedObject )
590+ .isInstanceOf (ReferenceUsage .class )
591+ .asInstanceOf (type (ReferenceUsage .class ))
592+ .satisfies (referenceUsage -> {
593+ EList <Subsetting > subjectSubsets = referenceUsage .getOwnedSubsetting ();
594+ assertThat (subjectSubsets ).isNotEmpty ();
595+ assertThat (subjectSubsets .get (0 ).getSubsettedFeature ().getName ()).isEqualTo ("part" );
596+ });
581597 };
582- Runnable semanticCheck = this . semanticCheckerService . checkEditingContext ( this . semanticCheckerService . getElementInParentSemanticChecker ( parentLabel , containmentReference , childEClass ));
583- Runnable semanticCheck2 = this .semanticCheckerService .checkEditingContext (semanticChecker );
598+
599+ Runnable semanticCheck = this .semanticCheckerService .checkEditingContext (this . semanticCheckerService . getElementInParentSemanticChecker ( parentLabel , containmentReference , childEClass , additionalCheck ) );
584600
585601 StepVerifier .create (flux )
586602 .consumeNextWith (initialDiagramContentConsumer )
587603 .then (createNodeRunnable )
588604 .consumeNextWith (diagramCheck )
589605 .then (semanticCheck )
590- .then (semanticCheck2 )
591606 .thenCancel ()
592607 .verify (Duration .ofSeconds (10 ));
593608 }
@@ -605,11 +620,8 @@ private void createSubjectWithFeatureTypingInCaseUsage(EClass caseUsageSubclass,
605620 EClass childEClass = SysmlPackage .eINSTANCE .getReferenceUsage ();
606621 String creationToolName = "New Subject" ;
607622 EReference containmentReference = SysmlPackage .eINSTANCE .getCaseUsage_SubjectParameter ();
608- List <ToolVariable > variables = new ArrayList <>();
609- String existingPartDefId = GeneralViewWithTopNodesTestProjectData .SemanticIds .PART_DEFINITION_ID ;
610- variables .add (new ToolVariable ("selectedObject" , existingPartDefId , ToolVariableType .OBJECT_ID ));
611623
612- Runnable createNodeRunnable = this .creationTestsService .createNode (diagramDescriptionIdProvider , diagram , caseUsageSubclass , targetObjectId , creationToolName , variables );
624+ Runnable createNodeRunnable = this .creationTestsService .createNodeWithSelectionDialogWithSingleSelection (diagramDescriptionIdProvider , diagram , caseUsageSubclass , targetObjectId , creationToolName , GeneralViewWithTopNodesTestProjectData . SemanticIds . PART_DEFINITION_ID );
613625
614626 Consumer <Object > diagramCheck = assertRefreshedDiagramThat (newDiagram -> {
615627 var initialDiagram = diagram .get ();
@@ -633,28 +645,83 @@ private void createSubjectWithFeatureTypingInCaseUsage(EClass caseUsageSubclass,
633645 .check (initialDiagram , newDiagram );
634646 });
635647
636- ISemanticChecker semanticChecker = (editingContext ) -> {
637- Object semanticRootObject = this .objectSearchService .getObject (editingContext , GeneralViewWithTopNodesTestProjectData .SemanticIds .PACKAGE_1_ID ).orElse (null );
638- assertThat (semanticRootObject ).isInstanceOf (Element .class );
639- Element semanticRootElement = (Element ) semanticRootObject ;
640- Optional <ReferenceUsage > optParentElement = EMFUtils .allContainedObjectOfType (semanticRootElement , ReferenceUsage .class )
641- .filter (element -> Objects .equals (element .getName (), "subject" ))
642- .findFirst ();
643- assertThat (optParentElement ).isPresent ();
644- var referenceUsage = optParentElement .get ();
645- EList <Type > types = referenceUsage .getType ();
646- assertFalse (types .isEmpty ());
647- assertThat (types .get (0 ).getName ()).isEqualTo ("PartDefinition" );
648+ Consumer <Object > additionalCheck = referencedObject -> {
649+ assertThat (referencedObject )
650+ .isInstanceOf (ReferenceUsage .class )
651+ .asInstanceOf (type (ReferenceUsage .class ))
652+ .satisfies (referenceUsage -> {
653+ EList <Type > types = referenceUsage .getType ();
654+ assertThat (types ).isNotEmpty ();
655+ assertThat (types .get (0 ).getName ()).isEqualTo ("PartDefinition" );
656+ });
648657 };
649- Runnable semanticCheck = this .semanticCheckerService .checkEditingContext (this .semanticCheckerService .getElementInParentSemanticChecker (parentLabel , containmentReference , childEClass ));
650- Runnable semanticCheck2 = this .semanticCheckerService .checkEditingContext (semanticChecker );
658+
659+ Runnable semanticCheck = this .semanticCheckerService .checkEditingContext (this .semanticCheckerService .getElementInParentSemanticChecker (parentLabel , containmentReference , childEClass , additionalCheck ));
660+
661+ StepVerifier .create (flux )
662+ .consumeNextWith (initialDiagramContentConsumer )
663+ .then (createNodeRunnable )
664+ .consumeNextWith (diagramCheck )
665+ .then (semanticCheck )
666+ .thenCancel ()
667+ .verify (Duration .ofSeconds (10 ));
668+ }
669+
670+ private void createSubjectWithoutSpecializationInCaseUsage (EClass caseUsageSubclass , String targetObjectId , String parentLabel ) {
671+ var flux = this .givenSubscriptionToDiagram ();
672+
673+ AtomicReference <Diagram > diagram = new AtomicReference <>();
674+ Consumer <Object > initialDiagramContentConsumer = assertRefreshedDiagramThat (diagram ::set );
675+
676+ var diagramDescription = this .givenDiagramDescription .getDiagramDescription (GeneralViewWithTopNodesTestProjectData .EDITING_CONTEXT_ID ,
677+ SysONRepresentationDescriptionIdentifiers .GENERAL_VIEW_DIAGRAM_DESCRIPTION_ID );
678+ var diagramDescriptionIdProvider = new DiagramDescriptionIdProvider (diagramDescription , this .diagramIdProvider );
679+
680+ EClass childEClass = SysmlPackage .eINSTANCE .getReferenceUsage ();
681+ String creationToolName = "New Subject" ;
682+ EReference containmentReference = SysmlPackage .eINSTANCE .getCaseUsage_SubjectParameter ();
683+
684+ Runnable createNodeRunnable = this .creationTestsService .createNodeWithSelectionDialogWithoutSelectionProvided (diagramDescriptionIdProvider , diagram , caseUsageSubclass , targetObjectId , creationToolName );
685+
686+ Consumer <Object > diagramCheck = assertRefreshedDiagramThat (newDiagram -> {
687+ var initialDiagram = diagram .get ();
688+ int createdNodesExpectedCount = 2 ;
689+ new CheckDiagramElementCount (this .diagramComparator )
690+ .hasNewNodeCount (createdNodesExpectedCount )
691+ .hasNewEdgeCount (1 )
692+ .check (initialDiagram , newDiagram );
693+ // Only the node inside the compartment is visible
694+ // The "sibling" node is hidden
695+ new CheckDiagramElementCount (this .diagramComparator )
696+ .hasNewNodeCount (1 )
697+ .hasNewEdgeCount (0 )
698+ .check (initialDiagram , newDiagram , true );
699+ String listNodeDescription = this .descriptionNameGenerator .getCompartmentItemName (SysmlPackage .eINSTANCE .getCaseUsage (), containmentReference );
700+ new CheckNodeInCompartment (diagramDescriptionIdProvider , this .diagramComparator )
701+ .withTargetObjectId (targetObjectId )
702+ .withCompartmentName ("subject" )
703+ .hasNodeDescriptionName (listNodeDescription )
704+ .hasCompartmentCount (0 )
705+ .check (initialDiagram , newDiagram );
706+ });
707+
708+ Consumer <Object > additionalCheck = referencedObject -> {
709+ assertThat (referencedObject )
710+ .isInstanceOf (ReferenceUsage .class )
711+ .asInstanceOf (type (ReferenceUsage .class ))
712+ .satisfies (referenceUsage -> {
713+ assertThat (referenceUsage .getOwnedSpecialization ()).allMatch (Specialization ::isIsImplied );
714+ assertThat (referenceUsage .getType ()).isEmpty ();
715+ });
716+ };
717+
718+ Runnable semanticCheck = this .semanticCheckerService .checkEditingContext (this .semanticCheckerService .getElementInParentSemanticChecker (parentLabel , containmentReference , childEClass , additionalCheck ));
651719
652720 StepVerifier .create (flux )
653721 .consumeNextWith (initialDiagramContentConsumer )
654722 .then (createNodeRunnable )
655723 .consumeNextWith (diagramCheck )
656724 .then (semanticCheck )
657- .then (semanticCheck2 )
658725 .thenCancel ()
659726 .verify (Duration .ofSeconds (10 ));
660727 }
0 commit comments