Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
8 changed files
with
228 additions
and
77 deletions.
There are no files selected for viewing
File renamed without changes.
71 changes: 0 additions & 71 deletions
71
edelta.parent/edelta.tests/xtend-gen/edelta/tests/EdeltaLocationInFileProviderTest.java
This file was deleted.
Oops, something went wrong.
137 changes: 137 additions & 0 deletions
137
edelta.parent/edelta.ui.tests/src/edelta/ui/tests/EdeltaOutlineWithEditorLinkerTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,137 @@ | ||
package edelta.ui.tests; | ||
|
||
import static org.eclipse.xtext.ui.testing.util.IResourcesSetupUtil.createFile; | ||
import static org.eclipse.xtext.ui.testing.util.IResourcesSetupUtil.waitForBuild; | ||
|
||
import org.assertj.core.api.Assertions; | ||
import org.eclipse.jface.viewers.TreeSelection; | ||
import org.eclipse.swt.widgets.Display; | ||
import org.eclipse.xtext.testing.InjectWith; | ||
import org.eclipse.xtext.testing.XtextRunner; | ||
import org.eclipse.xtext.ui.editor.XtextEditor; | ||
import org.eclipse.xtext.ui.editor.outline.impl.EObjectNode; | ||
import org.eclipse.xtext.ui.editor.outline.impl.OutlinePage; | ||
import org.eclipse.xtext.ui.testing.AbstractEditorTest; | ||
import org.junit.Test; | ||
import org.junit.runner.RunWith; | ||
|
||
import com.google.inject.Inject; | ||
|
||
import edelta.ui.internal.EdeltaActivator; | ||
import edelta.ui.tests.utils.EdeltaPluginProjectHelper; | ||
|
||
@RunWith(XtextRunner.class) | ||
@InjectWith(EdeltaUiInjectorProvider.class) | ||
public class EdeltaOutlineWithEditorLinkerTest extends AbstractEditorTest { | ||
|
||
@Inject | ||
private EdeltaPluginProjectHelper edeltaProjectHelper; | ||
|
||
private static final String TEST_PROJECT = "mytestproject"; | ||
|
||
private String program = | ||
"package foo\n" + | ||
"\n" + | ||
"metamodel \"mypackage\"\n" + | ||
"\n" + | ||
"def anOp() {\n" + | ||
"}\n" + | ||
"\n" + | ||
"modifyEcore aTest epackage mypackage {\n" + | ||
" addNewEClass(\"MyNewClass\") [\n" + | ||
" addNewEAttribute(\"MyNewAttribute\", null)\n" + | ||
" ]\n" + | ||
" ecoreref(MyClass)\n" + | ||
" ecoreref(MyDerivedClass) => [\n" + | ||
" addNewEAttribute(\"MyNewDerivedClassAttribute\", null)\n" + | ||
" ]\n" + | ||
"}"; | ||
|
||
private XtextEditor editor; | ||
|
||
private OutlinePage outlinePage; | ||
|
||
@Override | ||
protected String getEditorId() { | ||
return EdeltaActivator.EDELTA_EDELTA; | ||
} | ||
|
||
@Override | ||
public void setUp() throws Exception { | ||
super.setUp(); | ||
edeltaProjectHelper.createEdeltaPluginProject(TEST_PROJECT); | ||
var file = createFile( | ||
TEST_PROJECT + "/src/Test.edelta", | ||
program | ||
); | ||
// we need to wait for build twice when we run all the UI tests | ||
waitForBuild(); | ||
editor = openEditor(file); | ||
outlinePage = editor.getAdapter(OutlinePage.class); | ||
Assertions.assertThat(outlinePage).isNotNull(); | ||
editor.setFocus(); | ||
} | ||
|
||
@Test | ||
public void testSelectOperation() throws Exception { | ||
whenEditorTextIsSelectedThenOutlineNodeIsSelected | ||
("anOp", "anOp() : Object"); | ||
} | ||
|
||
@Test | ||
public void testSelectModifyEcore() throws Exception { | ||
whenEditorTextIsSelectedThenOutlineNodeIsSelected | ||
("modifyEcore", "aTest(EPackage) : void"); | ||
} | ||
|
||
@Test | ||
public void testSelectNonResponsibleExpressionInModifyEcore() throws Exception { | ||
whenEditorTextIsSelectedThenOutlineNodeIsSelected | ||
("ecoreref(MyClass)", "aTest(EPackage) : void"); | ||
} | ||
|
||
@Test | ||
public void testSelectExpressionThatCreatesEClass() throws Exception { | ||
whenEditorTextIsSelectedThenOutlineNodeIsSelected | ||
("addNewEClass", "MyNewClass"); | ||
} | ||
|
||
@Test | ||
public void testSelectExpressionThatCreatesEAttributeInCreatedEClass() throws Exception { | ||
whenEditorTextIsSelectedThenOutlineNodeIsSelected | ||
("addNewEAttribute(\"MyNewAttribute", "MyNewAttribute"); | ||
} | ||
|
||
@Test | ||
public void testSelectExpressionThatCreatesEAttributeInExistingEClass() throws Exception { | ||
whenEditorTextIsSelectedThenOutlineNodeIsSelected | ||
("addNewEAttribute(\"MyNewDerivedClassAttribute", "MyNewDerivedClassAttribute"); | ||
} | ||
|
||
private void whenEditorTextIsSelectedThenOutlineNodeIsSelected(String textToSelect, String expectedNode) throws InterruptedException { | ||
editor.getInternalSourceViewer() | ||
.setSelectedRange(program.indexOf(textToSelect), 0); | ||
var selection = waitForSelection(); | ||
assertEquals(expectedNode, | ||
((EObjectNode) selection.getFirstElement()).getText().toString()); | ||
} | ||
|
||
@SuppressWarnings("all") | ||
private TreeSelection waitForSelection() throws InterruptedException { | ||
int attempts = 30; | ||
for (int i = 0; i < attempts; ++i) { | ||
Thread.sleep(100); | ||
executeAsyncDisplayJobs(); | ||
var selection = (TreeSelection) outlinePage.getTreeViewer().getSelection(); | ||
if (!selection.isEmpty()) | ||
return selection; | ||
} | ||
fail("No node is selected in the outline"); | ||
return null; | ||
} | ||
|
||
private void executeAsyncDisplayJobs() { | ||
while(Display.getCurrent().readAndDispatch()) { | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
65 changes: 65 additions & 0 deletions
65
edelta.parent/edelta.ui/src/edelta/ui/outline/actions/EdeltaOutlineWithEditorLinker.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
/** | ||
* | ||
*/ | ||
package edelta.ui.outline.actions; | ||
|
||
import static edelta.edelta.EdeltaPackage.Literals.EDELTA_MODIFY_ECORE_OPERATION; | ||
import static org.eclipse.emf.ecore.EcorePackage.Literals.EPACKAGE; | ||
|
||
import java.util.Objects; | ||
|
||
import org.eclipse.emf.ecore.ENamedElement; | ||
import org.eclipse.xtext.ui.editor.outline.IOutlineNode; | ||
import org.eclipse.xtext.ui.editor.outline.actions.OutlineWithEditorLinker; | ||
import org.eclipse.xtext.ui.editor.outline.impl.EObjectNode; | ||
import org.eclipse.xtext.util.ITextRegion; | ||
import org.eclipse.xtext.xbase.XExpression; | ||
|
||
/** | ||
* From an {@link XExpression} responsible of the modification of an {@link ENamedElement} | ||
* in the editor, navigate to the corresponding element in the outline. | ||
* | ||
* @author Lorenzo Bettini | ||
* | ||
*/ | ||
public class EdeltaOutlineWithEditorLinker extends OutlineWithEditorLinker { | ||
|
||
@Override | ||
protected IOutlineNode findBestNode(IOutlineNode input, ITextRegion selectedTextRegion) { | ||
final var findBestNode = super.findBestNode(input, selectedTextRegion); | ||
if (findBestNode instanceof EObjectNode) { | ||
EObjectNode eObjectNode = (EObjectNode) findBestNode; | ||
if (eObjectNode.getEClass() == EDELTA_MODIFY_ECORE_OPERATION) { | ||
/* since XExpressions are not shown in the outline, when we select | ||
* such an expression, by default the containing modifyEcore node is | ||
* selected. We try and find a node representing an Ecore element | ||
* that is modified by the selected XExpressionv*/ | ||
return eObjectNode.getParent().getChildren().stream() | ||
.filter(node -> EPACKAGE == ((EObjectNode) node).getEClass()) | ||
.map(node -> findENamedElementNode(node, selectedTextRegion)) | ||
.filter(Objects::nonNull) | ||
.findFirst() | ||
.orElse(findBestNode); | ||
} | ||
} | ||
return findBestNode; | ||
} | ||
|
||
private IOutlineNode findENamedElementNode(IOutlineNode node, ITextRegion selectedTextRegion) { | ||
for (var child : node.getChildren()) { | ||
// at this point we are sure it's an EObjectNode | ||
EObjectNode eObjectNode = (EObjectNode) child; | ||
// our Outline nodes for Ecore elements are already associated with the | ||
// text region of the corresponding responsible XExpression | ||
final var recursiveFind = findENamedElementNode(child, selectedTextRegion); | ||
// first check whether there's a child that matches, since, | ||
// as said before, an outer expression region might match an inner one | ||
if (recursiveFind != null) { | ||
return recursiveFind; | ||
} else if (eObjectNode.getSignificantTextRegion().contains(selectedTextRegion)) { | ||
return eObjectNode; | ||
} | ||
} | ||
return null; | ||
} | ||
} |
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters