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
2 changes: 2 additions & 0 deletions CHANGELOG.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,10 @@ It has long been unused by Sirius Web itself (since the transition to MUI).
- https://github.com/eclipse-syson/syson/issues/1808[#1808] [diagrams] Remove multiplicity displayed on feature membership edge between Part Definition and Part Usage.
- https://github.com/eclipse-syson/syson/issues/2194[#2194] [diagrams] Properly report feedback messages to user when using _ISysMLMoveElementService_.
- https://github.com/eclipse-syson/syson/issues/2306[#2306] [diagrams] Fixed an error when trying to rename a constraint displayed as a list item through direct edit.
- https://github.com/eclipse-syson/syson/issues/2318[#2318] [diagrams] Direct edit on a constraint label now ignores the expression part (`{ ... }`) if present in the new text.

=== Improvements

- https://github.com/eclipse-syson/syson/issues/2198[#2198] [diagrams] Improve diagram-to-diagram drag and drop to support dropping multiple graphical nodes at once, leveraging Sirius Web's `droppedNodes` and `droppedElements` variables.
- https://github.com/eclipse-syson/syson/issues/2182[#2182] [services] Provide a way for downstream applications to extend _ISysMLMoveElementService_.
- https://github.com/eclipse-syson/syson/issues/2240[#2240] [diagrams] Update the choice of _timeslice_ and _snapshot_ elements that can be created in the selection dialog of tools creating _timeslice_ and _snapshot_ elements.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -651,7 +651,7 @@ public void topLevelConstraintNodeLabelIncludesExpressionInLabel() {
.check(diagram.get(), newDiagram);

String nodeLabel = newDiagram.getNodes().get(0).getInsideLabel().getText();
assertThat(nodeLabel).isEqualTo(constraint»\npressureLimit\n{ pressure <= maxPressure }");
assertThat(nodeLabel).isEqualTo(this.multiLine(this.quoted("constraint"), "pressureLimit", "{ pressure <= maxPressure }"));
});

StepVerifier.create(flux)
Expand All @@ -662,6 +662,70 @@ public void topLevelConstraintNodeLabelIncludesExpressionInLabel() {
.verify(Duration.ofSeconds(10));
}

@DisplayName("GIVEN a SysML model with expressions, WHEN direct editing a constraint node's label with an expression part, THEN the direct edit succeeds but ignores the expression part")
@GivenSysONServer({ ExpressionSamplesProjectData.SCRIPT_PATH })
@Test
public void directEditTopLevelConstraintNodeIgnoresExpressionPart() {
String initialConstraintName = "pressureLimit";
String constraintExpression = "pressure <= maxPressure";
String newConstraintName = "newConstraintName";
String newExpressionIgnored = "false";

var flux = this.givenSubscriptionToNewDiagram();

AtomicReference<Diagram> diagram = new AtomicReference<>();
Consumer<Object> initialDiagramContentConsumer = assertRefreshedDiagramThat(diagram::set);
AtomicReference<String> constraintNodeId = new AtomicReference<>();
AtomicReference<String> constraintNodeLabelId = new AtomicReference<>();

Runnable dropFromExplorerRunnable = () -> {
assertThat(diagram.get().getNodes()).hasSize(0);
this.dropFromExplorerTester.dropFromExplorerOnDiagram(ExpressionSamplesProjectData.EDITING_CONTEXT_ID, diagram, ExpressionSamplesProjectData.SemanticIds.TANK_PRESSURE_LIMIT_CONSTRAINT_ID);
};

Consumer<Object> updatedDiagramConsumer = assertRefreshedDiagramThat(newDiagram -> {
new CheckDiagramElementCount(this.diagramComparator)
.hasNewEdgeCount(0)
.hasNewNodeCount(5)
.check(diagram.get(), newDiagram);

var constraintNode = newDiagram.getNodes().get(0);
String nodeLabel = constraintNode.getInsideLabel().getText();
assertThat(nodeLabel).isEqualTo(this.multiLine(this.quoted("constraint"), initialConstraintName, "{ " + constraintExpression + " }"));
constraintNodeId.set(constraintNode.getId());
constraintNodeLabelId.set(constraintNode.getInsideLabel().getId());
});

var checkDirectEditInitialTextShowsNameOnly = this.directEditInitialLabelTester.checkDirectEditInitialLabel(diagram, constraintNodeLabelId::get,
initialConstraintName);

Runnable editConstraintName = () -> {
String labelId = constraintNodeLabelId.get();
String newLabelWIthExpressionPart = newConstraintName + " {" + newExpressionIgnored + " }";
EditLabelInput input = new EditLabelInput(UUID.randomUUID(), ExpressionSamplesProjectData.EDITING_CONTEXT_ID, diagram.get().getId(), labelId, newLabelWIthExpressionPart);
var result = this.editLabelMutationRunner.run(input);
String typename = JsonPath.read(result.data(), "$.data.editLabel.__typename");
assertThat(typename).isEqualTo(EditLabelSuccessPayload.class.getSimpleName());
};

Consumer<Object> updatedDiagramAfterDirectEditConsumer = assertRefreshedDiagramThat(newDiagram -> {
var constraintNode = new DiagramNavigator(newDiagram).nodeWithTargetObjectId(ExpressionSamplesProjectData.SemanticIds.TANK_PRESSURE_LIMIT_CONSTRAINT_ID)
.getNode();
assertThat(constraintNode).isNotNull();
assertThat(constraintNode.getInsideLabel().getText()).isEqualTo(this.multiLine(this.quoted("constraint"), newConstraintName, "{ " + constraintExpression + " }"));
});

StepVerifier.create(flux)
.consumeNextWith(initialDiagramContentConsumer)
.then(dropFromExplorerRunnable)
.consumeNextWith(updatedDiagramConsumer)
.then(checkDirectEditInitialTextShowsNameOnly)
.then(editConstraintName)
.consumeNextWith(updatedDiagramAfterDirectEditConsumer)
.thenCancel()
.verify(Duration.ofSeconds(10));
}

@DisplayName("GIVEN a SysML model an assumed constraint visible as a list item in a requirement node, WHEN using direct-edit on the constraint, THEN only its name is shown in the initial text and impacted by the edition")
@GivenSysONServer({ ExpressionSamplesProjectData.SCRIPT_PATH })
@Test
Expand Down Expand Up @@ -689,7 +753,7 @@ public void directEditNamedAssumedConstraintListItem() {
.check(diagram.get(), newDiagram);

String nodeLabel = newDiagram.getNodes().get(0).getInsideLabel().getText();
assertThat(nodeLabel).isEqualTo(this.quoted("requirement def") + "\nSensorOperability");
assertThat(nodeLabel).isEqualTo(this.multiLine(this.quoted("requirement def"), "SensorOperability"));

var constraintNode = new DiagramNavigator(newDiagram).nodeWithTargetObjectId(ExpressionSamplesProjectData.SemanticIds.SENSOR_OPERABILITY_ENVIRONMENTAL_PRECONDITION_ASSUMED_CONSTRAINT_ID)
.getNode();
Expand Down Expand Up @@ -717,7 +781,7 @@ public void directEditNamedAssumedConstraintListItem() {
.check(diagram.get(), newDiagram);

String nodeLabel = newDiagram.getNodes().get(0).getInsideLabel().getText();
assertThat(nodeLabel).isEqualTo(this.quoted("requirement def") + "\nSensorOperability");
assertThat(nodeLabel).isEqualTo(this.multiLine(this.quoted("requirement def"), "SensorOperability"));

var constraintNode = new DiagramNavigator(newDiagram).nodeWithTargetObjectId(ExpressionSamplesProjectData.SemanticIds.SENSOR_OPERABILITY_ENVIRONMENTAL_PRECONDITION_ASSUMED_CONSTRAINT_ID)
.getNode();
Expand All @@ -727,13 +791,40 @@ public void directEditNamedAssumedConstraintListItem() {
constraintNodeLabelId.set(constraintNode.getInsideLabel().getId());
});

Runnable editConstraintNameWithExpressionPart = () -> {
String labelId = constraintNodeLabelId.get();
EditLabelInput input = new EditLabelInput(UUID.randomUUID(), ExpressionSamplesProjectData.EDITING_CONTEXT_ID, diagram.get().getId(), labelId, initialConstraintName + "{ false }");
var result = this.editLabelMutationRunner.run(input);
String typename = JsonPath.read(result.data(), "$.data.editLabel.__typename");
assertThat(typename).isEqualTo(EditLabelSuccessPayload.class.getSimpleName());
};

Consumer<Object> updatedDiagramAfterDirectEditWithExpressionPartConsumer = assertRefreshedDiagramThat(newDiagram -> {
new CheckDiagramElementCount(this.diagramComparator)
.hasNewEdgeCount(0)
.hasNewNodeCount(15)
.check(diagram.get(), newDiagram);

String nodeLabel = newDiagram.getNodes().get(0).getInsideLabel().getText();
assertThat(nodeLabel).isEqualTo(this.multiLine(this.quoted("requirement def"), "SensorOperability"));

var constraintNode = new DiagramNavigator(newDiagram).nodeWithTargetObjectId(ExpressionSamplesProjectData.SemanticIds.SENSOR_OPERABILITY_ENVIRONMENTAL_PRECONDITION_ASSUMED_CONSTRAINT_ID)
.getNode();
assertThat(constraintNode).isNotNull();
assertThat(constraintNode.getInsideLabel().getText()).isEqualTo(initialConstraintName + " { " + constraintExpression + " }");
constraintNodeId.set(constraintNode.getId());
constraintNodeLabelId.set(constraintNode.getInsideLabel().getId());
});

StepVerifier.create(flux)
.consumeNextWith(initialDiagramContentConsumer)
.then(dropFromExplorerRunnable)
.consumeNextWith(updatedDiagramConsumer)
.then(checkDirectEditInitialTextShowsNameOnly)
.then(editConstraintName)
.consumeNextWith(updatedDiagramAfterDirectEditConsumer)
.then(editConstraintNameWithExpressionPart)
.consumeNextWith(updatedDiagramAfterDirectEditWithExpressionPartConsumer)
.thenCancel()
.verify(Duration.ofSeconds(10));
}
Expand All @@ -742,6 +833,10 @@ private String quoted(String text) {
return LabelConstants.OPEN_QUOTE + text + LabelConstants.CLOSE_QUOTE;
}

private String multiLine(String... lines) {
return String.join(LabelConstants.CR, lines);
}

/**
* Executes a function in the editing context with the specified id (which is assumed to be loaded). The function
* can perform JUnit assertions to verify the state of the semantic model in the editing context.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import org.eclipse.syson.services.LabelService;
import org.eclipse.syson.services.api.DiagramDirectEditErrorListener;
import org.eclipse.syson.services.api.IDirectEditNamespaceProvider;
import org.eclipse.syson.sysml.ConstraintUsage;
import org.eclipse.syson.sysml.Element;
import org.springframework.stereotype.Service;

Expand Down Expand Up @@ -120,7 +121,11 @@ public Element directEdit(Element element, String newLabel, boolean isCompartmen
* @return the given {@link Element}.
*/
public Element directEditNode(Element element, String newLabel) {
return this.directEdit(element, newLabel, false, (String[]) null);
String cleanNewLabel = newLabel;
if (element instanceof ConstraintUsage) {
cleanNewLabel = newLabel.replaceAll("\\{.*$", "");
}
return this.directEdit(element, cleanNewLabel, false, (String[]) null);
}

/**
Expand All @@ -133,7 +138,11 @@ public Element directEditNode(Element element, String newLabel) {
* @return the given {@link Element}.
*/
public Element directEditListItem(Element element, String newLabel) {
return this.directEdit(element, newLabel, true, LabelService.VALUE_OFF);
String cleanNewLabel = newLabel;
if (element instanceof ConstraintUsage) {
cleanNewLabel = newLabel.replaceAll("\\{.*$", "");
}
return this.directEdit(element, cleanNewLabel, true, LabelService.VALUE_OFF);
}

public Element editMultiplicityRangeCenterLabel(Element element, String newLabel) {
Expand Down
Loading