Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ Standard libraries are now cached between tests to speed up editing context crea
This feature can be de-activated by setting the property `org.eclipse.syson.test.cacheStandardLibraries` to `false` in `application.properties`.
The cache holding standard libraries can be invalidated for a specific test method or test class by using the `@InvalidateStandardLibrariesCache` annotation, ensuring the editing contexts are loaded from scratch.
- https://github.com/eclipse-syson/syson/issues/2154[#2154] [diagrams] Improve the _Duplicate Element_ diagram tool to support multi-selection in standard diagrams.
- https://github.com/eclipse-syson/syson/issues/2160[#2160] [diagrams] Improve the _View As_ diagram tool on graphical nodes to support multi-selection in standard diagrams.
- https://github.com/eclipse-syson/syson/issues/2148[#2148] [diagrams] Merge the two perform action creation tools into a single tool, leveraging the updated selection dialog.

=== New features
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,12 +82,8 @@ public class GVDuplicateNodeTest extends AbstractIntegrationTests {

private static final String PART_COPY = "part-copy";

private static final String PART_DEFINITION_COPY = "PartDefinition-copy";

private static final String PART_1_COPY = "part1-copy";

private static final String REQUIREMENT_COPY = "requirement-copy";

private static final String STATE_DEFINITION_COPY = "StateDefinition-copy";

@Autowired
Expand Down Expand Up @@ -343,7 +339,7 @@ public void checkMultiSelectionContainerNodeDuplication() {
SysONRepresentationDescriptionIdentifiers.GENERAL_VIEW_DIAGRAM_DESCRIPTION_ID);
var diagramDescriptionIdProvider = new DiagramDescriptionIdProvider(diagramDescription, this.diagramIdProvider);

var duplicateToolId = diagramDescriptionIdProvider.getGroupNodeToolId("Duplicate Element");
var duplicateToolId = diagramDescriptionIdProvider.getGroupNodeToolId("Duplicate Elements");
Runnable duplicateToolRunnable = () -> this.toolTester.invokeTool(GeneralViewWithTopNodesTestProjectData.EDITING_CONTEXT_ID,
diagram.get().getId(),
List.of(GeneralViewWithTopNodesTestProjectData.GraphicalIds.PART_USAGE_ID, GeneralViewWithTopNodesTestProjectData.GraphicalIds.ACTION_USAGE_ID),
Expand Down Expand Up @@ -411,7 +407,7 @@ public void checkMultiSelectionDifferentContainerNodeDuplication() {
var diagramDescriptionIdProvider = new DiagramDescriptionIdProvider(diagramDescription, this.diagramIdProvider);

var newPartToolId = diagramDescriptionIdProvider.getNodeToolId(this.descriptionNameGenerator.getNodeName(SysmlPackage.eINSTANCE.getPackage()), "New Part");
var duplicateToolId = diagramDescriptionIdProvider.getGroupNodeToolId("Duplicate Element");
var duplicateToolId = diagramDescriptionIdProvider.getGroupNodeToolId("Duplicate Elements");

Runnable createPartToolRunnable = () -> this.toolTester.invokeTool(GeneralViewWithTopNodesTestProjectData.EDITING_CONTEXT_ID,
diagram.get().getId(),
Expand Down Expand Up @@ -471,7 +467,7 @@ public void checkMultiSelectionDifferentContainerNodeDuplication() {
StepVerifier.create(flux)
.consumeNextWith(diag -> {
initialDiagramContentConsumer.accept(diag);
var initialDiagram = (Diagram) ((DiagramRefreshedEventPayload) diag).diagram();
var initialDiagram = diag.diagram();
packageNodeId.set(new DiagramNavigator(initialDiagram).nodeWithTargetObjectId(GeneralViewWithTopNodesTestProjectData.SemanticIds.PACKAGE_ID).getNode().getId());
stateDefinitionNodeId.set(new DiagramNavigator(initialDiagram).nodeWithTargetObjectId(GeneralViewWithTopNodesTestProjectData.SemanticIds.STATE_DEFINITION_ID).getNode().getId());
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,10 @@
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class GVViewAsOnNodeTests extends AbstractIntegrationTests {

private static final String PACKAGE_1_LABEL = "Package1";

private static final String PART = "part";

@Autowired
private IGivenInitialServerState givenInitialServerState;

Expand Down Expand Up @@ -127,18 +131,18 @@ public void testViewAsIVOnPartUsage() {

Consumer<Object> initialDiagramContentConsumer = assertRefreshedDiagramThat(diag -> {
diagramId.set(diag.getId());
assertThat(diag.getNodes()).hasSize(3);
assertThat(diag.getNodes()).hasSize(4);
assertThat(diag.getEdges()).hasSize(2);

var partBNode = new DiagramNavigator(diag).nodeWithLabel(LabelConstants.OPEN_QUOTE + "part" + LabelConstants.CLOSE_QUOTE + LabelConstants.CR + "pB").getNode();
var partBNode = new DiagramNavigator(diag).nodeWithLabel(LabelConstants.OPEN_QUOTE + PART + LabelConstants.CLOSE_QUOTE + LabelConstants.CR + "pB").getNode();
partBNodeId.set(partBNode.getId());
});

Runnable viewAsInterconnectionViewTool = () -> this.toolTester.invokeTool(ViewAsOnNodeTestProjectData.EDITING_CONTEXT_ID, diagramId.get(), partBNodeId.get(), viewAsInterconnectionViewToolId,
List.of());

Consumer<Object> updatedDiagramContentConsumerAfterToolExecution = assertRefreshedDiagramThat(diag -> {
assertThat(diag.getNodes()).hasSize(2);
assertThat(diag.getNodes()).hasSize(3);
assertThat(diag.getEdges()).hasSize(1);

var view2NodeNavigator = new DiagramNavigator(diag)
Expand All @@ -147,12 +151,12 @@ public void testViewAsIVOnPartUsage() {
assertThat(newViewUsageNode).isNotNull();
view2Id.set(newViewUsageNode.getTargetObjectId());

var partBNodeNavigator = view2NodeNavigator.childNodeWithLabel(LabelConstants.OPEN_QUOTE + "part" + LabelConstants.CLOSE_QUOTE + LabelConstants.CR + "pB");
var partBNodeNavigator = view2NodeNavigator.childNodeWithLabel(LabelConstants.OPEN_QUOTE + PART + LabelConstants.CLOSE_QUOTE + LabelConstants.CR + "pB");
var partBNode = partBNodeNavigator.getNode();
assertThat(partBNode).isNotNull();

var partCNodeNavigator = partBNodeNavigator.childNodeWithLabel("interconnection")
.childNodeWithLabel(LabelConstants.OPEN_QUOTE + "part" + LabelConstants.CLOSE_QUOTE + LabelConstants.CR + "pC");
.childNodeWithLabel(LabelConstants.OPEN_QUOTE + PART + LabelConstants.CLOSE_QUOTE + LabelConstants.CR + "pC");
var partCNode = partCNodeNavigator.getNode();
assertThat(partCNode).isNotNull();
});
Expand Down Expand Up @@ -186,14 +190,16 @@ public void testViewAsIVOnPartUsage() {
assertThat(sysmlv2Model.getLabel().toString()).isEqualTo("SysMLv2.sysml");
assertThat(sysmlv2Model.getChildren()).hasSize(1);
TreeItem pkg1 = sysmlv2Model.getChildren().get(0);
assertThat(pkg1.getLabel().toString()).isEqualTo("Package1");
assertThat(pkg1.getLabel().toString()).isEqualTo(PACKAGE_1_LABEL);

assertThat(pkg1.getChildren()).hasSize(3);
assertThat(pkg1.getChildren()).hasSize(4);
TreeItem view1 = pkg1.getChildren().get(0);
assertThat(view1.getLabel().toString()).isEqualTo("view1 [GeneralView]");
TreeItem gv = pkg1.getChildren().get(1);
assertThat(gv.getLabel().toString()).isEqualTo("pA");
TreeItem view2 = pkg1.getChildren().get(2);
TreeItem pA = pkg1.getChildren().get(1);
assertThat(pA.getLabel().toString()).isEqualTo("pA");
TreeItem partDef = pkg1.getChildren().get(2);
assertThat(partDef.getLabel().toString()).isEqualTo("PartDefinition1");
TreeItem view2 = pkg1.getChildren().get(3);
assertThat(view2.getLabel().toString()).isEqualTo("view2 [InterconnectionView]");
assertThat(view2.getChildren()).hasSize(2);
TreeItem diagramView2 = view2.getChildren().get(0);
Expand Down Expand Up @@ -227,17 +233,17 @@ public void testViewAsIVOnPackage() {

Consumer<Object> initialDiagramContentConsumer = assertRefreshedDiagramThat(diag -> {
diagramId.set(diag.getId());
assertThat(diag.getNodes()).hasSize(3);
assertThat(diag.getNodes()).hasSize(4);
assertThat(diag.getEdges()).hasSize(2);
});

Runnable packageTool = () -> this.toolTester.invokeTool(ViewAsOnNodeTestProjectData.EDITING_CONTEXT_ID, diagramId.get(), diagramId.get(), packageToolId, List.of());

Consumer<Object> updatedDiagramContentConsumerAfterPackageToolExecution = assertRefreshedDiagramThat(diag -> {
assertThat(diag.getNodes()).hasSize(4);
assertThat(diag.getNodes()).hasSize(5);
assertThat(diag.getEdges()).hasSize(2);

var packageNode = new DiagramNavigator(diag).nodeWithLabel("Package1").getNode();
var packageNode = new DiagramNavigator(diag).nodeWithLabel(PACKAGE_1_LABEL).getNode();
assertThat(packageNode).isNotNull();
packageNodeId.set(packageNode.getId());
});
Expand All @@ -246,15 +252,15 @@ public void testViewAsIVOnPackage() {
List.of());

Consumer<Object> updatedDiagramContentConsumerAfterViewAsToolExecution = assertRefreshedDiagramThat(diag -> {
assertThat(diag.getNodes()).hasSize(4);
assertThat(diag.getNodes()).hasSize(5);
assertThat(diag.getEdges()).hasSize(2);

var view2NodeNavigator = new DiagramNavigator(diag)
.nodeWithLabel(LabelConstants.OPEN_QUOTE + "view" + LabelConstants.CLOSE_QUOTE + " view2 : StandardViewDefinitions::GeneralView");
var newViewUsageNode = view2NodeNavigator.getNode();
assertThat(newViewUsageNode).isNotNull();

var packageNode = view2NodeNavigator.childNodeWithLabel("Package1").getNode();
var packageNode = view2NodeNavigator.childNodeWithLabel(PACKAGE_1_LABEL).getNode();
assertThat(packageNode).isNotNull();
});

Expand All @@ -267,4 +273,74 @@ public void testViewAsIVOnPackage() {
.thenCancel()
.verify(Duration.ofSeconds(10));
}

@DisplayName("GIVEN a GV diagram, WHEN the group 'View as > Interconnection View' tool is applied on partA and PartDefinition, THEN one new IV ViewUsage is created and visible in the GV with both elements.")
@GivenSysONServer({ ViewAsOnNodeTestProjectData.SCRIPT_PATH })
@Test
public void testViewAsIVOnMultiSelection() {
var flux = this.givenSubscriptionToDiagram();

var diagramDescription = this.givenDiagramDescription.getDiagramDescription(ViewAsOnNodeTestProjectData.EDITING_CONTEXT_ID,
SysONRepresentationDescriptionIdentifiers.GENERAL_VIEW_DIAGRAM_DESCRIPTION_ID);
var diagramDescriptionIdProvider = new DiagramDescriptionIdProvider(diagramDescription, this.diagramIdProvider);

var viewAsInterconnectionViewToolId = diagramDescriptionIdProvider.getGroupNodeToolId("Interconnection View");
assertThat(viewAsInterconnectionViewToolId).isNotNull();

var diagramId = new AtomicReference<String>();
var partANodeId = new AtomicReference<String>();
var partDefinitionNodeId = new AtomicReference<String>();

Consumer<Object> initialDiagramContentConsumer = assertRefreshedDiagramThat(diag -> {
diagramId.set(diag.getId());
assertThat(diag.getNodes()).hasSize(4);
assertThat(diag.getEdges()).hasSize(2);

partANodeId.set(new DiagramNavigator(diag).nodeWithTargetObjectId(ViewAsOnNodeTestProjectData.SemanticIds.PART_A_ID).getNode().getId());
partDefinitionNodeId.set(new DiagramNavigator(diag).nodeWithTargetObjectId(ViewAsOnNodeTestProjectData.SemanticIds.PART_DEFINITION_ID).getNode().getId());
});

Runnable viewAsInterconnectionViewTool = () -> this.toolTester.invokeTool(ViewAsOnNodeTestProjectData.EDITING_CONTEXT_ID, diagramId.get(),
List.of(partANodeId.get(), partDefinitionNodeId.get()), viewAsInterconnectionViewToolId, List.of());

Consumer<Object> updatedDiagramContentConsumerAfterViewAsToolExecution = assertRefreshedDiagramThat(diag -> {
assertThat(diag.getNodes()).hasSize(1);
assertThat(diag.getEdges()).hasSize(0);

var interconnectionViewNodes = diag.getNodes().stream()
.filter(node -> node.getInsideLabel() != null)
.filter(node -> node.getInsideLabel().getText().contains("StandardViewDefinitions::InterconnectionView"))
.toList();
assertThat(interconnectionViewNodes)
.as("Only one Interconnection ViewUsage should be created for the whole selection")
.hasSize(1);

assertThat(diag.getNodes().stream()
.anyMatch(node -> ViewAsOnNodeTestProjectData.SemanticIds.PART_A_ID.equals(node.getTargetObjectId())))
.as("partA should no longer be displayed as a top-level node")
.isFalse();
assertThat(diag.getNodes().stream()
.anyMatch(node -> ViewAsOnNodeTestProjectData.SemanticIds.PART_DEFINITION_ID.equals(node.getTargetObjectId())))
.as("PartDefinition should no longer be displayed as a top-level node")
.isFalse();

var interconnectionViewNode = interconnectionViewNodes.get(0);
assertThat(interconnectionViewNode.getChildNodes())
.as("The new Interconnection ViewUsage should expose the two selected elements")
.hasSize(2);
assertThat(interconnectionViewNode.getChildNodes().stream()
.anyMatch(child -> ViewAsOnNodeTestProjectData.SemanticIds.PART_A_ID.equals(child.getTargetObjectId())))
.isTrue();
assertThat(interconnectionViewNode.getChildNodes().stream()
.anyMatch(child -> ViewAsOnNodeTestProjectData.SemanticIds.PART_DEFINITION_ID.equals(child.getTargetObjectId())))
.isTrue();
});

StepVerifier.create(flux)
.consumeNextWith(initialDiagramContentConsumer)
.then(viewAsInterconnectionViewTool)
.consumeNextWith(updatedDiagramContentConsumerAfterViewAsToolExecution)
.thenCancel()
.verify(Duration.ofSeconds(10));
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2025 Obeo.
* Copyright (c) 2025, 2026 Obeo.
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* which accompanies this distribution, and is available at
Expand Down Expand Up @@ -50,9 +50,16 @@ public static final class SemanticIds {

public static final String PART_A_ELEMENT_ID = "b87ed042-a552-4b0b-aebf-0c47b8d0cfbd";

public static final String PART_A_ID = "45b69ed5-cb3c-42d1-80c5-1ad08342fcb9";

public static final String PART_B_ELEMENT_ID = "82987ce2-47ca-4943-910b-df1d57447b19";

public static final String PART_C_ELEMENT_ID = "3be21122-d555-45bf-96eb-84bb4abc95d5";

public static final String PART_DEFINITION_ELEMENT_ID = "04b2b69b-aa1a-4d7e-aa92-49300f5a9bc2";

public static final String PART_DEFINITION_ID = "884cb950-cef7-4cfa-a7b5-dd757d01ecf2";

}

}
Loading
Loading