Skip to content

Commit

Permalink
[#3007] Content Assistant test infrastructure improvements.
Browse files Browse the repository at this point in the history
- Extend the Content Assistant test infrastructure to test proposals
from several resources: modify the AbstractContentAssistTest
getResourceFor method to ensure that the test file points to a file in
the test project.
- Uplift the testContentAssistant method from the project example
classes into the AbstractContentAssistTest and rename it to
assertContentAssistant.
- Add the events_from_another_file() test case to the
StatemachineContentAssistTest test cases to demonstrate how to test the
content assistant with several resources.
- Also add the ContentAssistWithSeveralResourcesTest test cases that are
continuously executed by the CI build.

Closes #3007

Signed-off-by: miklossy <miklossy@itemis.de>
  • Loading branch information
miklossy committed Apr 30, 2024
1 parent 0afffe3 commit 79797f9
Show file tree
Hide file tree
Showing 8 changed files with 260 additions and 131 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Copyright (c) 2013, 2020 itemis AG (http://www.itemis.eu) and others.
* Copyright (c) 2013, 2024 itemis AG (http://www.itemis.eu) and others.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
Expand All @@ -10,10 +10,12 @@

import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.NullProgressMonitor;
Expand All @@ -26,6 +28,8 @@
import org.eclipse.xtext.resource.FileExtensionProvider;
import org.eclipse.xtext.resource.XtextResource;
import org.eclipse.xtext.resource.XtextResourceSet;
import org.eclipse.xtext.ui.XtextProjectHelper;
import org.eclipse.xtext.ui.testing.util.IResourcesSetupUtil;
import org.eclipse.xtext.ui.testing.util.JavaProjectSetupUtil;
import org.eclipse.xtext.ui.testing.util.ResourceLoadHelper;
import org.junit.AfterClass;
Expand Down Expand Up @@ -53,11 +57,18 @@ public abstract class AbstractContentAssistTest implements ResourceLoadHelper, I
private Injector injector;

private static IJavaProject javaProject;

/**
* cursor position marker
* @since 2.35
*/
protected String c = "<|>";

@BeforeClass
@BeforeAll
public static void setUp() throws CoreException {
javaProject = JavaProjectSetupUtil.createJavaProject("contentAssistTest");
IResourcesSetupUtil.addNature(javaProject.getProject(), XtextProjectHelper.NATURE_ID);
}

@AfterClass
Expand All @@ -72,9 +83,18 @@ public XtextResource getResourceFor(InputStream stream) {
XtextResourceSet resourceSet = resourceSetProvider.get();
initializeTypeProvider(resourceSet);
try {
URI resourceUri = URI.createURI("Test." + fileExtensionProvider.getPrimaryFileExtension());
Resource resource = resourceSet.createResource(resourceUri);
resource.load(stream, null);
String projectFullPath = javaProject.getProject().getFullPath().toString();
URI resourceUri = URI.createPlatformResourceURI(projectFullPath + "/" + "Test." + fileExtensionProvider.getPrimaryFileExtension(), true);

/*
* Avoid the following java.lang.IllegalStateException:
* A different resource with the URI 'platform:/resource/contentAssistTest/Test....' was already registered.
*/
Resource resource = resourceSet.getResource(resourceUri, false);
if (resource == null) {
resource = resourceSet.createResource(resourceUri);
resource.load(stream, null);
}
return (XtextResource) resource;
} catch (IOException e) {
throw new RuntimeException(e);
Expand Down Expand Up @@ -104,4 +124,93 @@ protected void initializeTypeProvider(XtextResourceSet resourceSet) {
resourceSet.setClasspathURIContext(getJavaProject(resourceSet));
}

/**
* Creates a dsl file.
*
* @param fileName
* The name of the file (without the file extension)
*
* @param content
* The content of the file.
*
* @since 2.35
*/
protected IFile createDslFile(String fileName, CharSequence content) {
return createDslFile(fileName, fileExtensionProvider.getPrimaryFileExtension(), content);
}

/**
* Creates a dsl file.
*
* @param fileName
* The name of the file (without the file extension)
*
* @param fileExtension
* The extension of the file.
*
* @param content
* The content of the file.
*
* @since 2.35
*/
protected IFile createDslFile(String fileName, String fileExtension, CharSequence content) {
try {
return IResourcesSetupUtil.createFile(javaProject.getElementName(), fileName, fileExtension, content.toString());
} catch (InvocationTargetException | CoreException | InterruptedException e) {
throw new RuntimeException(e);
}
}

/**
* Verifies whether the content assistant provides the expected proposals on the given cursor position.
*
* @param text
* The editor's input text. The text must contain the {@link #c} special symbol indicating the current cursor position.
*
* @param expectedProposals
* The list of proposals that are expected to be offered whenever the content assistant is triggered on the given cursor position.
*
* @since 2.35
*/
protected void assertContentAssistant(CharSequence text, List<String> expectedProposals) {
assertContentAssistant(text, expectedProposals, null, null);
}

/**
* Verifies whether the content assistant provides the expected proposals on the given cursor position.
* Furthermore, it applies the proposalToApply - if it is given - and verifies the expected content afterwards.
*
* @param text
* The editor's input text. The text must contain the {@link #c} special symbol indicating the current cursor position.
*
* @param expectedProposals
* The list of proposals that are expected to be offered whenever the content assistant is triggered on the given cursor position.
*
* @param proposalToApply
* The proposal to apply from the list of the expected proposals.
*
* @param expectedContent
* The expected editor content after the given proposal has been applied.
*
* @since 2.35
*/
protected void assertContentAssistant(CharSequence text, List<String> expectedProposals, String proposalToApply, String expectedContent) {

int cursorPosition = text.toString().indexOf(c);
if (cursorPosition == -1) {
throw new RuntimeException("Can't locate cursor position symbols '" + c + "' in the input text.");
}

String content = text.toString().replace(c, "");

try {
ContentAssistProcessorTestBuilder builder = newBuilder().append(content).assertTextAtCursorPosition(cursorPosition, expectedProposals.toArray(new String[0]));

if (proposalToApply != null) {
builder.applyProposal(cursorPosition, proposalToApply).expectContent(expectedContent);
}
} catch (Exception exception) {
throw new RuntimeException(exception);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*******************************************************************************
* Copyright (c) 2024 itemis AG (http://www.itemis.eu) and others.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* SPDX-License-Identifier: EPL-2.0
*******************************************************************************/
package org.eclipse.xtext.ui.tests.editor.contentassist;

import java.util.Arrays;

import org.eclipse.xtext.testing.InjectWith;
import org.eclipse.xtext.testing.XtextRunner;
import org.eclipse.xtext.ui.testing.AbstractContentAssistTest;
import org.eclipse.xtext.ui.testing.util.IResourcesSetupUtil;
import org.eclipse.xtext.ui.tests.linking.ui.tests.ImportUriUiTestLanguageUiInjectorProvider;
import org.junit.Test;
import org.junit.runner.RunWith;

/**
* @author miklossy - Initial contribution and API
*/
@RunWith(XtextRunner.class)
@InjectWith(ImportUriUiTestLanguageUiInjectorProvider.class)
public class ContentAssistWithSeveralResourcesTest extends AbstractContentAssistTest {

@Test public void test_with_one_resource() {
assertContentAssistant("type A extends " + c, Arrays.asList("A"));
}

@Test public void test_with_two_resources() {
createDslFile("types", "type A extends A");
IResourcesSetupUtil.waitForBuild();
assertContentAssistant("import \"types.importuriuitestlanguage\" type B extends " + c, Arrays.asList("A", "B"));
}

@Test public void test_with_three_resources() {
createDslFile("types1", "type A extends A");
createDslFile("types2", "type B extends B");
IResourcesSetupUtil.waitForBuild();
assertContentAssistant("import \"types1.importuriuitestlanguage\" import \"types2.importuriuitestlanguage\" type C extends " + c, Arrays.asList("A", "B", "C"));
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2012, 2019 itemis AG (http://www.itemis.eu) and others.
* Copyright (c) 2012, 2024 itemis AG (http://www.itemis.eu) and others.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
Expand All @@ -8,7 +8,6 @@
*******************************************************************************/
package org.eclipse.xtext.example.domainmodel.ui.tests

import java.util.List
import org.eclipse.xtext.testing.InjectWith
import org.eclipse.xtext.testing.XtextRunner
import org.eclipse.xtext.ui.testing.AbstractContentAssistTest
Expand All @@ -22,9 +21,6 @@ import org.junit.runner.RunWith
@InjectWith(DomainmodelUiInjectorProvider)
class ContentAssistTest extends AbstractContentAssistTest {

// cursor position marker
val c = '''<|>'''

@Test def void testImportCompletion() throws Exception {
newBuilder.append('import java.util.Da').assertText('java.util.Date')
}
Expand Down Expand Up @@ -56,7 +52,7 @@ class ContentAssistTest extends AbstractContentAssistTest {
entity E {
«c»
}
'''.testContentAssistant(#[
'''.assertContentAssistant(#[
'Operation - template for an Operation',
'Property - template for a Property',
'op'
Expand All @@ -72,7 +68,7 @@ class ContentAssistTest extends AbstractContentAssistTest {
entity E {
«c»
}
'''.testContentAssistant(#[
'''.assertContentAssistant(#[
'Operation - template for an Operation',
'Property - template for a Property',
'op'
Expand All @@ -84,15 +80,4 @@ class ContentAssistTest extends AbstractContentAssistTest {
}
''')
}

private def void testContentAssistant(CharSequence text, List<String> expectedProposals, String proposalToApply, String expectedContent) throws Exception {

val cursorPosition = text.toString.indexOf(c)
val content = text.toString.replace(c, "")

newBuilder.append(content).
assertTextAtCursorPosition(cursorPosition, expectedProposals).
applyProposal(cursorPosition, proposalToApply).
expectContent(expectedContent)
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Copyright (c) 2012, 2019 itemis AG (http://www.itemis.eu) and others.
* Copyright (c) 2012, 2024 itemis AG (http://www.itemis.eu) and others.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
Expand All @@ -9,15 +9,12 @@
package org.eclipse.xtext.example.domainmodel.ui.tests;

import java.util.Collections;
import java.util.List;
import org.eclipse.xtend2.lib.StringConcatenation;
import org.eclipse.xtext.testing.InjectWith;
import org.eclipse.xtext.testing.XtextRunner;
import org.eclipse.xtext.ui.testing.AbstractContentAssistTest;
import org.eclipse.xtext.ui.testing.ContentAssistProcessorTestBuilder;
import org.eclipse.xtext.xbase.lib.CollectionLiterals;
import org.eclipse.xtext.xbase.lib.Conversions;
import org.eclipse.xtext.xbase.lib.Functions.Function0;
import org.junit.Test;
import org.junit.runner.RunWith;

Expand All @@ -28,15 +25,6 @@
@InjectWith(DomainmodelUiInjectorProvider.class)
@SuppressWarnings("all")
public class ContentAssistTest extends AbstractContentAssistTest {
private final String c = new Function0<String>() {
@Override
public String apply() {
StringConcatenation _builder = new StringConcatenation();
_builder.append("<|>");
return _builder.toString();
}
}.apply();

@Test
public void testImportCompletion() throws Exception {
this.newBuilder().append("import java.util.Da").assertText("java.util.Date");
Expand Down Expand Up @@ -94,7 +82,7 @@ public void testPropertyTemplateProposal() throws Exception {
_builder_1.newLine();
_builder_1.append("}");
_builder_1.newLine();
this.testContentAssistant(_builder,
this.assertContentAssistant(_builder,
Collections.<String>unmodifiableList(CollectionLiterals.<String>newArrayList("Operation - template for an Operation", "Property - template for a Property", "op")), "Property - template for a Property", _builder_1.toString());
}

Expand All @@ -121,13 +109,7 @@ public void testOperationTemplateProposal() throws Exception {
_builder_1.newLine();
_builder_1.append("}");
_builder_1.newLine();
this.testContentAssistant(_builder,
this.assertContentAssistant(_builder,
Collections.<String>unmodifiableList(CollectionLiterals.<String>newArrayList("Operation - template for an Operation", "Property - template for a Property", "op")), "Operation - template for an Operation", _builder_1.toString());
}

private void testContentAssistant(final CharSequence text, final List<String> expectedProposals, final String proposalToApply, final String expectedContent) throws Exception {
final int cursorPosition = text.toString().indexOf(this.c);
final String content = text.toString().replace(this.c, "");
this.newBuilder().append(content).assertTextAtCursorPosition(cursorPosition, ((String[])Conversions.unwrapArray(expectedProposals, String.class))).applyProposal(cursorPosition, proposalToApply).expectContent(expectedContent);
}
}

0 comments on commit 79797f9

Please sign in to comment.