Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMickael LANOE2014-11-20 13:33:56 +0000
committerMickael LANOE2014-11-26 09:48:14 +0000
commit2190d4f204539e959b511a5753f54f1d24b83937 (patch)
tree9bc910d1579b4dd719b392878bcfea19779e8238
parent8a628e52614bf10e649433e3764a1c78f1d337c8 (diff)
downloadorg.eclipse.sirius-2190d4f204539e959b511a5753f54f1d24b83937.tar.gz
org.eclipse.sirius-2190d4f204539e959b511a5753f54f1d24b83937.tar.xz
org.eclipse.sirius-2190d4f204539e959b511a5753f54f1d24b83937.zip
[428770] Improve auto-completion for intepreter prefixes
For expression not provided by an existing interpreter, the auto-completion shows interpreter prefixes that match the expression. So for empty expression all interpreter prefixes are listed. Add tests to check this new feature. Bug: 428770 Change-Id: Ief4033899ae6394f2dec37d571bcd2f22f06d512 Signed-off-by: Mickael LANOE <mickael.lanoe@obeo.fr>
-rw-r--r--plugins/org.eclipse.sirius.common.ui/src/org/eclipse/sirius/common/ui/tools/internal/contentassist/ContentProposalConverter.java13
-rw-r--r--plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/api/interpreter/CompoundInterpreter.java61
-rw-r--r--plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/internal/assist/ContentContextHelper.java74
-rw-r--r--plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/suite/common/AllCommonPluginTests.java8
-rw-r--r--plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/unit/common/interpreter/AbstractCompletionTestCase.java432
-rw-r--r--plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/unit/common/interpreter/CompoundInterpreterTestCase.java156
-rw-r--r--plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/unit/common/interpreter/acceleo/mtl/AcceleoMTLCompletionTests.java238
-rw-r--r--plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/unit/common/interpreter/feature/FeatureCompletionTests.java209
-rw-r--r--plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/unit/common/interpreter/ocl/OCLCompletionTest.java222
-rw-r--r--plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/unit/common/interpreter/service/ServiceCompletionTests.java189
-rw-r--r--plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/unit/common/interpreter/variable/VariableCompletionTests.java224
11 files changed, 1446 insertions, 380 deletions
diff --git a/plugins/org.eclipse.sirius.common.ui/src/org/eclipse/sirius/common/ui/tools/internal/contentassist/ContentProposalConverter.java b/plugins/org.eclipse.sirius.common.ui/src/org/eclipse/sirius/common/ui/tools/internal/contentassist/ContentProposalConverter.java
index fcbbe1bf34..ad308820bf 100644
--- a/plugins/org.eclipse.sirius.common.ui/src/org/eclipse/sirius/common/ui/tools/internal/contentassist/ContentProposalConverter.java
+++ b/plugins/org.eclipse.sirius.common.ui/src/org/eclipse/sirius/common/ui/tools/internal/contentassist/ContentProposalConverter.java
@@ -13,7 +13,6 @@ package org.eclipse.sirius.common.ui.tools.internal.contentassist;
import java.util.List;
import org.eclipse.jface.fieldassist.IContentProposal;
-
import org.eclipse.sirius.common.tools.api.contentassist.ContentProposal;
import org.eclipse.sirius.common.tools.api.util.StringUtil;
@@ -58,18 +57,22 @@ public class ContentProposalConverter {
}
/**
- * Make an IContentProposal for the specified String.
+ * Convert a {@link ContentProposal} to a JFace {@link IContentProposal}.
*
* @param arg
- * @param proposalStart
+ * proposal to convert.
+ * @return converted proposal.
*
*/
- private IContentProposal convertToJFaceContentProposal(final ContentProposal arg) {
+ public IContentProposal convertToJFaceContentProposal(final ContentProposal arg) {
String proposal = arg.getProposal();
int cursorPosition = arg.getCursorPosition();
if (!StringUtil.isEmpty(proposalStart) && proposal.startsWith(proposalStart)) {
proposal = proposal.substring(proposalStart.length());
- cursorPosition = proposal.length();
+
+ // cursorPosition is not always at the end of the proposal, so
+ // just move the position.
+ cursorPosition -= proposalStart.length();
}
return new DefaultContentProposal(proposal, arg.getInformation(), arg.getDisplay(), cursorPosition);
diff --git a/plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/api/interpreter/CompoundInterpreter.java b/plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/api/interpreter/CompoundInterpreter.java
index 511ab5eef2..d1f1b996a6 100644
--- a/plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/api/interpreter/CompoundInterpreter.java
+++ b/plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/api/interpreter/CompoundInterpreter.java
@@ -27,20 +27,21 @@ import org.eclipse.core.runtime.Platform;
import org.eclipse.emf.common.EMFPlugin;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.util.ECrossReferenceAdapter;
-
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Sets;
-
import org.eclipse.sirius.common.tools.DslCommonPlugin;
import org.eclipse.sirius.common.tools.api.contentassist.ContentContext;
import org.eclipse.sirius.common.tools.api.contentassist.ContentInstanceContext;
import org.eclipse.sirius.common.tools.api.contentassist.ContentProposal;
import org.eclipse.sirius.common.tools.api.contentassist.IProposalProvider;
+import org.eclipse.sirius.common.tools.api.util.StringUtil;
+import org.eclipse.sirius.common.tools.internal.assist.ContentContextHelper;
import org.eclipse.sirius.common.tools.internal.assist.ProposalProviderRegistry;
import org.eclipse.sirius.ecore.extender.business.api.accessor.MetamodelDescriptor;
import org.eclipse.sirius.ecore.extender.business.api.accessor.ModelAccessor;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+
/**
* Compound interpreter.
*
@@ -77,7 +78,7 @@ public final class CompoundInterpreter implements IInterpreter, IProposalProvide
* the interpreter, they'll be registered here.
*/
private Collection<MetamodelDescriptor> additionalMetamodels = Sets.newLinkedHashSet();
-
+
/** The dependencies. */
private final List<String> dependencies;
@@ -250,8 +251,9 @@ public final class CompoundInterpreter implements IInterpreter, IProposalProvide
while (interpreterProvider == null && entryIterator.hasNext()) {
final Map.Entry<IInterpreterProvider, IInterpreter> entry = entryIterator.next();
// instance equality do not suffice as long as the interpreter
- // is not a singleton (see CompoundInterpreter.createGenericInterpreter, each session,
- // ...)
+ // is not a singleton (see
+ // CompoundInterpreter.createGenericInterpreter, each session,
+ // ...)
if (entry.getValue() == interpreter) {
interpreterProvider = entry.getKey();
} else if (entry.getValue() != null && entry.getValue().getClass() == interpreter.getClass()) {
@@ -784,6 +786,15 @@ public final class CompoundInterpreter implements IInterpreter, IProposalProvide
for (IProposalProvider provider : proposalProviders) {
proposals.addAll(provider.getProposals(interpreter, context));
}
+
+ if (interpreter == DefaultInterpreterProvider.INSTANCE) {
+ // The default interpreter is used when there is no other
+ // interpreter available for the context. Try to find if the
+ // context matches empty expression from one or several
+ // interpreters prefixes.
+ // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=428770
+ proposals.addAll(getEmptyExpressionProposals(context.getContents()));
+ }
}
return proposals;
}
@@ -833,7 +844,7 @@ public final class CompoundInterpreter implements IInterpreter, IProposalProvide
}
/**
- * Return allways null. use {@link CompoundInterpreter#getVariable(String)}
+ * Return always null. use {@link CompoundInterpreter#getVariable(String)}
* {@inheritDoc}
*
* @see org.eclipse.sirius.common.tools.api.interpreter.IInterpreter#getVariablePrefix()
@@ -910,6 +921,15 @@ public final class CompoundInterpreter implements IInterpreter, IProposalProvide
for (IProposalProvider provider : proposalProviders) {
proposals.addAll(provider.getProposals(interpreterForExpression, context));
}
+
+ if (interpreterForExpression == DefaultInterpreterProvider.INSTANCE) {
+ // The default interpreter is used when there is no other
+ // interpreter available for the context. Try to find if the
+ // context matches empty expression from one or several
+ // interpreters prefixes.
+ // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=428770
+ proposals.addAll(getEmptyExpressionProposals(context.getTextSoFar()));
+ }
}
return proposals;
}
@@ -958,4 +978,27 @@ public final class CompoundInterpreter implements IInterpreter, IProposalProvide
public boolean supportsValidation() {
return true;
}
+
+ /**
+ * Get proposals that match context for available empty expressions.
+ *
+ * @param context
+ * context to match
+ * @return list of proposal for empty expressions
+ */
+ private List<ContentProposal> getEmptyExpressionProposals(String context) {
+ List<ContentProposal> proposals = Lists.newArrayList();
+
+ // Provides all interpreters compatible with the context
+ final List<IProposalProvider> proposalProviders = ProposalProviderRegistry.getAllProviders();
+ for (IProposalProvider provider : proposalProviders) {
+ ContentProposal emptyExpression = provider.getNewEmtpyExpression();
+
+ if (StringUtil.isEmpty(context) || ContentContextHelper.matchEmptyExpression(context, emptyExpression)) {
+ proposals.add(emptyExpression);
+ }
+ }
+
+ return proposals;
+ }
}
diff --git a/plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/internal/assist/ContentContextHelper.java b/plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/internal/assist/ContentContextHelper.java
index dd07dffc32..98690dc353 100644
--- a/plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/internal/assist/ContentContextHelper.java
+++ b/plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/internal/assist/ContentContextHelper.java
@@ -10,6 +10,10 @@
*******************************************************************************/
package org.eclipse.sirius.common.tools.internal.assist;
+import java.util.List;
+
+import org.eclipse.sirius.common.tools.api.contentassist.ContentProposal;
+import org.eclipse.sirius.common.tools.api.interpreter.CompoundInterpreter;
import org.eclipse.sirius.common.tools.api.util.StringUtil;
/**
@@ -50,18 +54,31 @@ public class ContentContextHelper {
*/
public String getProposalStart() {
String proposalStart = "";
- int numberOfalreadyWrittenCharacters = 0;
- if (!StringUtil.isEmpty(contents) && position > 0 && position <= contents.length()) {
- String substring = contents.substring(0, position);
- numberOfalreadyWrittenCharacters = findNumberOfAlreadyWrittenCharacters(substring);
- if (numberOfalreadyWrittenCharacters != 0 && numberOfalreadyWrittenCharacters <= substring.length()) {
- int propStart = substring.length() - numberOfalreadyWrittenCharacters;
- proposalStart = substring.substring(propStart);
-
- // variable ?
- String exprStart = substring.substring(0, propStart);
- if (!StringUtil.isEmpty(prefix) && exprStart.endsWith(prefix)) {
- proposalStart = prefix + proposalStart;
+
+ // There are two cases considered here. In the first case there is no
+ // selected interpreter, so the completion is done on interpreters
+ // empty expressions, we return the entire contents for the proposal
+ // start. In the second case the proposal start is based on some
+ // special characters in the contents.
+ if (!StringUtil.isEmpty(contents)) {
+
+ if (matchEmptyExpressions(contents, CompoundInterpreter.INSTANCE.getAllNewEmtpyExpressions())) {
+ // First case
+ proposalStart = contents;
+ } else if (position > 0 && position <= contents.length()) {
+ // Second case
+ int numberOfalreadyWrittenCharacters = 0;
+ String substring = contents.substring(0, position);
+ numberOfalreadyWrittenCharacters = findNumberOfAlreadyWrittenCharacters(substring);
+ if (numberOfalreadyWrittenCharacters != 0 && numberOfalreadyWrittenCharacters <= substring.length()) {
+ int propStart = substring.length() - numberOfalreadyWrittenCharacters;
+ proposalStart = substring.substring(propStart);
+
+ // variable ?
+ String exprStart = substring.substring(0, propStart);
+ if (!StringUtil.isEmpty(prefix) && exprStart.endsWith(prefix)) {
+ proposalStart = prefix + proposalStart;
+ }
}
}
}
@@ -99,4 +116,37 @@ public class ContentContextHelper {
return numberOfalreadyWrittenCharacters;
}
+ /**
+ * Return true if the contents matches any interpreters empty expressions.
+ *
+ * @param contents
+ * contents to tests
+ * @param emptyExpressions
+ * interpreters empty expressions to match
+ * @return true if the content matches any interpreters empty expressions
+ */
+ public static boolean matchEmptyExpressions(String contents, List<ContentProposal> emptyExpressions) {
+ for (ContentProposal emptyExpression : emptyExpressions) {
+ if (matchEmptyExpression(contents, emptyExpression)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Return true if the contents matches the interpreter empty expression.
+ *
+ * @param contents
+ * contents to tests
+ * @param emptyExpression
+ * one interpreter empty expression to match
+ * @return true if the content matches the interpreter empty expression
+ */
+ public static boolean matchEmptyExpression(String contents, ContentProposal emptyExpression) {
+ String proposal = emptyExpression.getProposal();
+ return proposal.startsWith(contents) && proposal.length() != contents.length();
+ }
+
}
diff --git a/plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/suite/common/AllCommonPluginTests.java b/plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/suite/common/AllCommonPluginTests.java
index 4bceb7161c..22130948ac 100644
--- a/plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/suite/common/AllCommonPluginTests.java
+++ b/plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/suite/common/AllCommonPluginTests.java
@@ -61,17 +61,21 @@ import org.eclipse.sirius.tests.unit.common.RefreshEditorsPrecommitListenerTests
import org.eclipse.sirius.tests.unit.common.RestoreSessionFromEditorInputTests;
import org.eclipse.sirius.tests.unit.common.TransientSessionTests;
import org.eclipse.sirius.tests.unit.common.WorkspaceResourceSyncTestCase;
+import org.eclipse.sirius.tests.unit.common.interpreter.CompoundInterpreterTestCase;
import org.eclipse.sirius.tests.unit.common.interpreter.acceleo.mtl.AcceleoMTInterpreterOnPackageImportTests;
import org.eclipse.sirius.tests.unit.common.interpreter.acceleo.mtl.AcceleoMTLCompletionTests;
import org.eclipse.sirius.tests.unit.common.interpreter.acceleo.mtl.AcceleoMTLInterpreterTests;
import org.eclipse.sirius.tests.unit.common.interpreter.acceleo.mtl.AcceleoPackageRegistryTest;
import org.eclipse.sirius.tests.unit.common.interpreter.acceleo.mtl.IInterpreterValidationExpressionTest;
import org.eclipse.sirius.tests.unit.common.interpreter.acceleo.mtl.InterpretedExpressionTargetSwitchTest;
+import org.eclipse.sirius.tests.unit.common.interpreter.feature.FeatureCompletionTests;
import org.eclipse.sirius.tests.unit.common.interpreter.feature.FeatureInterpreterTests;
import org.eclipse.sirius.tests.unit.common.interpreter.feature.FeatureProposalProviderTests;
import org.eclipse.sirius.tests.unit.common.interpreter.ocl.OCLCompletionTest;
+import org.eclipse.sirius.tests.unit.common.interpreter.service.ServiceCompletionTests;
import org.eclipse.sirius.tests.unit.common.interpreter.service.ServiceInterpreterTests;
import org.eclipse.sirius.tests.unit.common.interpreter.service.ServiceProposalProviderTests;
+import org.eclipse.sirius.tests.unit.common.interpreter.variable.VariableCompletionTests;
import org.eclipse.sirius.tests.unit.common.interpreter.variable.VariableInterpreterTests;
import org.eclipse.sirius.tests.unit.common.interpreter.variable.VariableProposalProviderTests;
import org.eclipse.sirius.tests.unit.common.migration.DiagramMigrationTestCampaign01;
@@ -238,14 +242,18 @@ public class AllCommonPluginTests extends TestCase {
suite.addTestSuite(AcceleoPackageRegistryTest.class);
suite.addTestSuite(IInterpreterValidationExpressionTest.class);
suite.addTestSuite(FeatureInterpreterTests.class);
+ suite.addTestSuite(FeatureCompletionTests.class);
suite.addTestSuite(ServiceInterpreterTests.class);
+ suite.addTestSuite(ServiceCompletionTests.class);
suite.addTestSuite(VariableInterpreterTests.class);
+ suite.addTestSuite(VariableCompletionTests.class);
suite.addTestSuite(FeatureProposalProviderTests.class);
suite.addTestSuite(ServiceProposalProviderTests.class);
suite.addTestSuite(VariableProposalProviderTests.class);
suite.addTestSuite(InterpretedExpressionTargetSwitchTest.class);
suite.addTestSuite(ReloadSessionTest.class);
suite.addTestSuite(EclipseUtilTest.class);
+ suite.addTestSuite(CompoundInterpreterTestCase.class);
suite.addTestSuite(TransientSessionTests.class);
suite.addTestSuite(RestoreSessionFromEditorInputTests.class);
diff --git a/plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/unit/common/interpreter/AbstractCompletionTestCase.java b/plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/unit/common/interpreter/AbstractCompletionTestCase.java
new file mode 100644
index 0000000000..e05eb26330
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/unit/common/interpreter/AbstractCompletionTestCase.java
@@ -0,0 +1,432 @@
+/*******************************************************************************
+ * Copyright (c) 2014 Obeo.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.sirius.tests.unit.common.interpreter;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import junit.framework.TestCase;
+
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EOperation;
+import org.eclipse.emf.ecore.EPackage;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.sirius.common.tools.api.contentassist.ContentContext;
+import org.eclipse.sirius.common.tools.api.contentassist.ContentInstanceContext;
+import org.eclipse.sirius.common.tools.api.contentassist.ContentProposal;
+import org.eclipse.sirius.common.tools.api.contentassist.IProposalProvider;
+import org.eclipse.sirius.common.tools.api.interpreter.CompoundInterpreter;
+import org.eclipse.sirius.common.tools.api.interpreter.DefaultInterpreterContextFactory;
+import org.eclipse.sirius.common.tools.api.interpreter.IInterpreter;
+
+import com.google.common.base.Function;
+import com.google.common.base.Predicate;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+
+/**
+ * Abstract base class for completion test cases.
+ *
+ * @author <a href="mailto:mickael.lanoe@obeo.fr">Mickael LANOE</a>
+ */
+
+public class AbstractCompletionTestCase extends TestCase {
+ /**
+ * Concrete interpreter to test. Must be initialized by calling
+ * {@link AbstractCompletionTestCase#setInterpreterAndProposalProvider()} in
+ * a method that overrides {@link TestCase#setUp()}
+ */
+ protected IInterpreter concreteInterpreter;
+
+ /**
+ * Concrete proposal provider to test. Must be initialized by calling
+ * {@link AbstractCompletionTestCase#setInterpreterAndProposalProvider()} in
+ * a method that overrides {@link TestCase#setUp()}
+ */
+ protected IProposalProvider concreteProposalProvider;
+
+ /**
+ * A proposal function for the current provider that takes a
+ * {@link ContentContext}
+ */
+ protected Function<ContentContext, List<ContentProposal>> proposalFunction = new Function<ContentContext, List<ContentProposal>>() {
+ public List<ContentProposal> apply(ContentContext input) {
+ return getProposals(input);
+ }
+ };
+
+ /**
+ * A proposal function for the current provider that takes a
+ * {@link ContentInstanceContext}
+ */
+ protected Function<ContentInstanceContext, List<ContentProposal>> proposalInstanceFunction = new Function<ContentInstanceContext, List<ContentProposal>>() {
+ public List<ContentProposal> apply(ContentInstanceContext input) {
+ return getProposals(input);
+ }
+ };
+
+ /**
+ * A proposal function for {@link CompoundInterpreter} that takes a
+ * {@link ContentContext}
+ */
+ protected Function<ContentContext, List<ContentProposal>> compoundProposalFunction = new Function<ContentContext, List<ContentProposal>>() {
+ public List<ContentProposal> apply(ContentContext input) {
+ return CompoundInterpreter.INSTANCE.getProposals(CompoundInterpreter.INSTANCE, input);
+ }
+ };
+
+ /**
+ * A proposal function for {@link CompoundInterpreter} that takes a
+ * {@link ContentInstanceContext}
+ */
+ protected Function<ContentInstanceContext, List<ContentProposal>> compoundProposalInstanceFunction = new Function<ContentInstanceContext, List<ContentProposal>>() {
+ public List<ContentProposal> apply(ContentInstanceContext input) {
+ return CompoundInterpreter.INSTANCE.getProposals(CompoundInterpreter.INSTANCE, input);
+ }
+ };
+
+ @Override
+ protected void tearDown() throws Exception {
+ if (concreteInterpreter != null) {
+ concreteInterpreter.dispose();
+ }
+ concreteInterpreter = null;
+ concreteProposalProvider = null;
+ super.tearDown();
+ }
+
+ /**
+ * Set the interpreter and the proposal provider.
+ *
+ * @param interpreter
+ * the interpreter to use in the test
+ * @param proposalProvider
+ * the proposal provider to use in the test
+ */
+ protected void setInterpreterAndProposalProvider(IInterpreter interpreter, IProposalProvider proposalProvider) {
+ this.concreteInterpreter = interpreter;
+ this.concreteProposalProvider = proposalProvider;
+ }
+
+ /**
+ * Evaluates the content proposals for a given expression and returns the
+ * result as a list.
+ *
+ * @param context
+ * the context
+ * @return content proposal list
+ */
+ protected List<ContentProposal> getProposals(ContentContext context) {
+ return concreteProposalProvider.getProposals(concreteInterpreter, context);
+ }
+
+ /**
+ * Evaluates the content proposals for a given expression and returns the
+ * result as a list.
+ *
+ * @param context
+ * the context
+ * @return content proposal list
+ */
+ protected List<ContentProposal> getProposals(ContentInstanceContext context) {
+ return concreteProposalProvider.getProposals(concreteInterpreter, context);
+ }
+
+ /**
+ * Create a {@link ContentContext}.
+ *
+ * @param expression
+ * expression of the context
+ * @param cursorPosition
+ * cursor position in the expression
+ * @param eClass
+ * target domain class
+ * @return a new {@link ContentContext}
+ */
+ protected ContentContext createContentContext(String expression, int cursorPosition, String eClass) {
+ return createContentContext(expression, cursorPosition, eClass, Collections.<String, String> emptyMap());
+ }
+
+ /**
+ * Create a {@link ContentContext}.
+ *
+ * @param expression
+ * expression of the context
+ * @param cursorPosition
+ * cursor position in the expression
+ * @param element
+ * the concerned element
+ * @param eClass
+ * target domain class
+ * @return a new {@link ContentContext}
+ */
+ protected ContentContext createContentContext(String expression, int cursorPosition, EObject element, String eClass) {
+ return createContentContext(expression, cursorPosition, element, eClass, null, Collections.<String, String> emptyMap(), Collections.<String> emptyList());
+ }
+
+ /**
+ * Create a {@link ContentContext}.
+ *
+ * @param expression
+ * expression of the context
+ * @param cursorPosition
+ * cursor position in the expression
+ * @param eClass
+ * target domain class
+ * @param variables
+ * declared variables
+ * @return a new {@link ContentContext}
+ */
+ protected ContentContext createContentContext(String expression, int cursorPosition, String eClass, Map<String, String> variables) {
+ return createContentContext(expression, cursorPosition, eClass, null, variables, Collections.<String> emptyList());
+ }
+
+ /**
+ * Create a {@link ContentContext}.
+ *
+ * @param expression
+ * expression of the context
+ * @param cursorPosition
+ * cursor position in the expression
+ * @param eClass
+ * target domain class
+ * @param ePackage
+ * available EPackage
+ * @return a new {@link ContentContext}
+ */
+ protected ContentContext createContentContext(String expression, int cursorPosition, String eClass, EPackage ePackage) {
+ return createContentContext(expression, cursorPosition, eClass, ePackage, Collections.<String, String> emptyMap(), Collections.<String> emptyList());
+ }
+
+ /**
+ * Create a {@link ContentContext}.
+ *
+ * @param expression
+ * expression of the context
+ * @param cursorPosition
+ * cursor position in the expression
+ * @param element
+ * the concerned element
+ * @param eClass
+ * target domain class
+ * @param ePackage
+ * available EPackage
+ * @return a new {@link ContentContext}
+ */
+ protected ContentContext createContentContext(String expression, int cursorPosition, EObject element, String eClass, EPackage ePackage) {
+ return createContentContext(expression, cursorPosition, element, eClass, ePackage, Collections.<String, String> emptyMap(), Collections.<String> emptyList());
+ }
+
+ /**
+ * Create a {@link ContentContext}.
+ *
+ * @param expression
+ * expression of the context
+ * @param cursorPosition
+ * cursor position in the expression
+ * @param eClass
+ * target domain class
+ * @param ePackage
+ * available EPackage
+ * @param variables
+ * the defined variables
+ * @param dependencies
+ * the list of available dependencies
+ * @return a new {@link ContentContext}
+ */
+ protected ContentContext createContentContext(String expression, int cursorPosition, String eClass, EPackage ePackage, Map<String, String> variables, Collection<String> dependencies) {
+ return createContentContext(expression, cursorPosition, null, eClass, ePackage, variables, dependencies);
+ }
+
+ /**
+ * Create a {@link ContentContext}.
+ *
+ * @param expression
+ * expression of the context
+ * @param cursorPosition
+ * cursor position in the expression
+ * @param element
+ * the concerned element
+ * @param eClass
+ * target domain class
+ * @param ePackage
+ * available EPackage
+ * @param variables
+ * the defined variables
+ * @param dependencies
+ * the list of available dependencies
+ * @return a new {@link ContentContext}
+ */
+ protected ContentContext createContentContext(String expression, int cursorPosition, EObject element, String eClass, EPackage ePackage, Map<String, String> variables,
+ Collection<String> dependencies) {
+ Collection<EPackage> pList = ePackage == null ? Collections.<EPackage> emptyList() : Collections.singletonList(ePackage);
+ return new ContentContext(expression, cursorPosition, DefaultInterpreterContextFactory.createInterpreterContext(element, true, null, Collections.singletonList(eClass), pList, variables,
+ dependencies));
+ }
+
+ /**
+ * Get proposals from content proposals.
+ *
+ * @param proposals
+ * content proposals
+ * @return collection of proposal string
+ */
+ protected Collection<String> extractProposal(List<ContentProposal> proposals) {
+ return Lists.newArrayList(Iterables.transform(proposals, new Function<ContentProposal, String>() {
+ public String apply(ContentProposal from) {
+ return from.getProposal();
+ }
+ }));
+ }
+
+ /**
+ * Ensure that proposal collection contains expected proposals.
+ *
+ * @param expectedProposals
+ * expected proposals
+ * @param proposals
+ * proposals to check
+ * @param concerned
+ * predicate to filter expected proposals
+ * @return error message or empty string
+ */
+ protected StringBuilder lookForExpectedProposals(Iterable<String> expectedProposals, Collection<String> proposals, Predicate<String> concerned) {
+ StringBuilder tmpMsg = new StringBuilder();
+
+ for (String prop : Iterables.filter(expectedProposals, concerned)) {
+ if (proposals.contains(prop)) {
+ proposals.remove(prop);
+ } else {
+ tmpMsg.append("\n * " + prop);
+ }
+ }
+
+ return tmpMsg;
+ }
+
+ /**
+ * Ensures that the given proposal lists contain all the given expected
+ * variables.
+ *
+ * @param variables
+ * the expected variables
+ * @param proposals
+ * the proposals computed by the OCL interpreter
+ * @param concerned
+ * a predicated allowing to select only the elements starting
+ * with the expected prefix
+ * @param errorMsg
+ * the errorMsg to use for listing missing proposals
+ */
+ protected void checkVariables(Set<String> expectedVariables, Collection<String> proposals, Predicate<String> concerned, StringBuilder errorMsg) {
+ // Variables
+ StringBuilder tmpMsg = lookForExpectedProposals(expectedVariables, proposals, concerned);
+
+ if (tmpMsg.length() != 0) {
+ tmpMsg.insert(0, "\nSome expected variables are not present in completion proposals:");
+ errorMsg.append(tmpMsg.toString());
+ }
+ }
+
+ /**
+ * Ensures that the given proposal lists contain all the eStructuralFeatures
+ * of the given {@link EClass} starting with the expected prefix.
+ *
+ * @param eClass
+ * the EClass on which completion is called
+ * @param proposals
+ * the proposals computed by the OCL interpreter
+ * @param concerned
+ * a predicated allowing to select only the elements starting
+ * with the expected prefix
+ * @param errorMsg
+ * the errorMsg to use for listing missing proposals
+ */
+ protected void checkEStruturalFeatures(EClass eClass, Collection<String> proposals, Predicate<String> concerned, StringBuilder errorMsg) {
+ Function<EStructuralFeature, String> getExpectedProposal = new Function<EStructuralFeature, String>() {
+ public String apply(EStructuralFeature from) {
+ return from.getName();
+ }
+ };
+
+ // EStructuralfeatures
+ StringBuilder tmpMsg = lookForExpectedProposals(Iterables.transform(eClass.getEAllStructuralFeatures(), getExpectedProposal), proposals, concerned);
+
+ if (tmpMsg.length() != 0) {
+ tmpMsg.insert(0, "\nSome expected features are not present in completion proposals:");
+ errorMsg.append(tmpMsg.toString());
+ }
+ }
+
+ /**
+ * Ensures that the given proposal lists contain all the eOperations of the
+ * given {@link EClass} starting with the expected prefix.
+ *
+ * @param eClass
+ * the EClass on which completion is called
+ * @param implicitContext
+ * implicit context
+ * @param proposals
+ * the proposals computed by the OCL interpreter
+ * @param concerned
+ * a predicated allowing to select only the elements starting
+ * with the expected prefix
+ * @param signature
+ * function class to get operation signature
+ * @param errorMsg
+ * the errorMsg to use for listing missing proposals
+ */
+ protected void checkEOperations(EClass eClass, boolean implicitContext, Collection<String> proposals, Predicate<String> concerned, Function<EOperation, String> signature, StringBuilder errorMsg) {
+ // EOperations
+ Collection<EOperation> opToCheck = Lists.newArrayList();
+ Collection<String> opNames = Sets.newHashSet();
+ for (EOperation op : eClass.getEAllOperations()) {
+ if (!(implicitContext && opNames.contains(op.getName()))) {
+ opNames.add(op.getName());
+ opToCheck.add(op);
+ }
+ }
+
+ StringBuilder tmpMsg = lookForExpectedProposals(Iterables.transform(opToCheck, signature), proposals, concerned);
+
+ if (tmpMsg.length() != 0) {
+ tmpMsg.insert(0, "\nSome expected operations are not present in completion proposals:");
+ errorMsg.append(tmpMsg.toString());
+ }
+ }
+
+ /**
+ * Ensure that the completion matches the interpreter empty expression
+ *
+ * @param context
+ * context to used
+ * @param getProposalFunction
+ * function class to call to have proposals
+ */
+ protected <T> void assertCompletionMatchesEmptyExpression(T context, Function<T, List<ContentProposal>> getProposalFunction) {
+ List<ContentProposal> proposals = getProposalFunction.apply(context);
+ final ContentProposal emptyExpressionProposal = concreteProposalProvider.getNewEmtpyExpression();
+
+ assertEquals(1, proposals.size());
+ ContentProposal proposal = proposals.get(0);
+
+ // ContentProposal.equals() does not test the display and the cursor
+ // position.
+ assertEquals(emptyExpressionProposal.getProposal(), proposal.getProposal());
+ assertEquals(emptyExpressionProposal.getDisplay(), proposal.getDisplay());
+ assertEquals(emptyExpressionProposal.getCursorPosition(), proposal.getCursorPosition());
+ }
+}
diff --git a/plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/unit/common/interpreter/CompoundInterpreterTestCase.java b/plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/unit/common/interpreter/CompoundInterpreterTestCase.java
new file mode 100644
index 0000000000..8332cb977a
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/unit/common/interpreter/CompoundInterpreterTestCase.java
@@ -0,0 +1,156 @@
+/*******************************************************************************
+ * Copyright (c) 2014 Obeo.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.sirius.tests.unit.common.interpreter;
+
+import java.util.List;
+
+import junit.framework.TestCase;
+
+import org.eclipse.jface.fieldassist.IContentProposal;
+import org.eclipse.sirius.common.tools.api.contentassist.ContentContext;
+import org.eclipse.sirius.common.tools.api.contentassist.ContentProposal;
+import org.eclipse.sirius.common.tools.api.interpreter.CompoundInterpreter;
+import org.eclipse.sirius.common.tools.api.interpreter.IInterpreterContext;
+import org.eclipse.sirius.common.ui.tools.internal.contentassist.ContentProposalConverter;
+import org.eclipse.sirius.diagram.description.DescriptionFactory;
+import org.eclipse.sirius.diagram.description.DescriptionPackage;
+import org.eclipse.sirius.diagram.description.DiagramDescription;
+import org.eclipse.sirius.tools.api.interpreter.context.SiriusInterpreterContextFactory;
+
+import com.google.common.base.Predicate;
+import com.google.common.collect.Iterables;
+
+/**
+ * Tests for {@link CompoundInterpreter}
+ *
+ * @author <a href="mailto:mickael.lanoe@obeo.fr">Mickael LANOE</a>
+ */
+public class CompoundInterpreterTestCase extends TestCase {
+ /**
+ * available interpreters empty expressions
+ */
+ private List<ContentProposal> availableEmptyExpressions;
+
+ /**
+ * Interpreter context
+ */
+ private IInterpreterContext interpreterContext;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ // Get available interpreters empty expressions
+ availableEmptyExpressions = CompoundInterpreter.INSTANCE.getAllNewEmtpyExpressions();
+ assertFalse("At least one interpreter should be declared", availableEmptyExpressions.isEmpty());
+
+ // Get an interpreter context
+ DiagramDescription diagramDescription = DescriptionFactory.eINSTANCE.createDiagramDescription();
+ interpreterContext = SiriusInterpreterContextFactory.createInterpreterContext(diagramDescription, DescriptionPackage.Literals.DIAGRAM_DESCRIPTION__PRECONDITION_EXPRESSION);
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ availableEmptyExpressions = null;
+ interpreterContext = null;
+
+ super.tearDown();
+ }
+
+ /**
+ * Ensures that we get all available interpreters prefixes for an empty or
+ * null expression. see https://bugs.eclipse.org/bugs/show_bug.cgi?id=428770
+ */
+ public void testCompletionForEmptyExpression() {
+ List<ContentProposal> proposalsForNullExpression = getProposals(null);
+ assertTrue("Proposals should contains all interpreters empty expressions for a null context",
+ proposalsForNullExpression.containsAll(availableEmptyExpressions) && proposalsForNullExpression.size() == availableEmptyExpressions.size());
+
+ List<ContentProposal> proposalsForEmptyExpression = getProposals("");
+ assertTrue("Proposals should contains all interpreters empty expressions for an empty context", proposalsForEmptyExpression.containsAll(availableEmptyExpressions)
+ && proposalsForEmptyExpression.size() == availableEmptyExpressions.size());
+ }
+
+ /**
+ * Ensures that we get interpreters empty expressions that match a non empty
+ * context. see https://bugs.eclipse.org/bugs/show_bug.cgi?id=428770
+ */
+ public void testCompletionPerPrefixFirstChar() {
+ for (ContentProposal emptyExpression : availableEmptyExpressions) {
+ String firstChar = emptyExpression.getProposal().substring(0, 1);
+ List<ContentProposal> proposals = getProposals(firstChar);
+ ContentProposalConverter converter = new ContentProposalConverter(firstChar);
+
+ // The following assert is valid for: "[/]" "<%%>" "ocl:" "var:"
+ // "service:" and "feature"
+ assertEquals("Proposals should contains only one proposal", 1, proposals.size());
+
+ // Proposals are interpreter prefixes
+ assertTrue("Proposals should be contained by available empty expressions", availableEmptyExpressions.containsAll(proposals));
+
+ ContentProposal proposal = proposals.get(0);
+ IContentProposal jfaceProposal = converter.convertToJFaceContentProposal(proposal);
+
+ // Check JFace proposal
+ assertEquals("", proposal.getProposal(), firstChar + jfaceProposal.getContent());
+
+ // Check JFace cursor position
+ assertEquals("JFace proposal cursor position is not well computed", proposal.getCursorPosition() - (proposal.getProposal().length() - jfaceProposal.getContent().length()),
+ jfaceProposal.getCursorPosition());
+ }
+ }
+
+ /**
+ * Ensures that for a valid interpreter syntax, we get proposals for the
+ * selected interpreter but not for interpreters empty expressions. See
+ * https://bugs.eclipse.org/bugs/show_bug.cgi?id=428770
+ */
+ public void testCompletionForInterpreterEmptyExpression() {
+ for (ContentProposal emptyExpression : availableEmptyExpressions) {
+ final List<ContentProposal> proposals = getProposals(emptyExpression.getProposal(), emptyExpression.getCursorPosition());
+
+ // Proposals must be part of the selected interpreter, so not in
+ // available empty expressions
+ assertFalse("Proposals must not contains interpreter empty expressions", Iterables.any(availableEmptyExpressions, new Predicate<ContentProposal>() {
+ @Override
+ public boolean apply(ContentProposal arg0) {
+ return proposals.contains(arg0);
+ }
+ }));
+ }
+ }
+
+ /**
+ * Get proposals for a given expression
+ *
+ * @param expression
+ * given expression
+ * @return proposals
+ */
+ private List<ContentProposal> getProposals(String expression) {
+ return getProposals(expression, expression != null ? expression.length() : 0);
+ }
+
+ /**
+ * Get proposals for a given expression
+ *
+ * @param expression
+ * given expression
+ * @param cursorPosition
+ * cursor position
+ * @return proposals
+ */
+ private List<ContentProposal> getProposals(String expression, int cursorPosition) {
+ ContentContext context = new ContentContext(expression, cursorPosition, interpreterContext);
+ return CompoundInterpreter.INSTANCE.getProposals(CompoundInterpreter.INSTANCE, context);
+ }
+
+}
diff --git a/plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/unit/common/interpreter/acceleo/mtl/AcceleoMTLCompletionTests.java b/plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/unit/common/interpreter/acceleo/mtl/AcceleoMTLCompletionTests.java
index 40b0860243..0724f0ab7e 100644
--- a/plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/unit/common/interpreter/acceleo/mtl/AcceleoMTLCompletionTests.java
+++ b/plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/unit/common/interpreter/acceleo/mtl/AcceleoMTLCompletionTests.java
@@ -14,15 +14,10 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
-import java.util.Map;
import java.util.Set;
-import junit.framework.TestCase;
-
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EOperation;
-import org.eclipse.emf.ecore.EPackage;
-import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.EcoreFactory;
import org.eclipse.emf.ecore.EcorePackage;
import org.eclipse.sirius.common.acceleo.mtl.business.internal.interpreter.AcceleoMTLInterpreter;
@@ -31,47 +26,26 @@ import org.eclipse.sirius.common.acceleo.mtl.ide.AcceleoProposalProvider;
import org.eclipse.sirius.common.tools.api.contentassist.ContentContext;
import org.eclipse.sirius.common.tools.api.contentassist.ContentInstanceContext;
import org.eclipse.sirius.common.tools.api.contentassist.ContentProposal;
-import org.eclipse.sirius.common.tools.api.contentassist.IProposalProvider;
-import org.eclipse.sirius.common.tools.api.interpreter.DefaultInterpreterContextFactory;
import org.eclipse.sirius.common.tools.api.interpreter.IInterpreter;
import org.eclipse.sirius.common.tools.api.util.StringUtil;
import org.eclipse.sirius.diagram.DNode;
import org.eclipse.sirius.diagram.DiagramFactory;
import org.eclipse.sirius.diagram.DiagramPackage;
+import org.eclipse.sirius.tests.SiriusTestsPlugin;
+import org.eclipse.sirius.tests.unit.common.interpreter.AbstractCompletionTestCase;
import com.google.common.base.Function;
import com.google.common.base.Predicate;
-import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
-import org.eclipse.sirius.tests.SiriusTestsPlugin;
-
/**
* Tests for the {@link AcceleoMTLInterpreter} utility class.
*
* @author mporhel
*
*/
-public class AcceleoMTLCompletionTests extends TestCase {
-
- private IInterpreter interpreter;
-
- private IProposalProvider proposalProvider;
-
- private Function<ContentContext, List<ContentProposal>> proposalFunction = new Function<ContentContext, List<ContentProposal>>() {
- public List<ContentProposal> apply(ContentContext input) {
- IProposalProvider proposalProvider = new AcceleoProposalProvider();
- return proposalProvider.getProposals(interpreter, input);
- }
- };
-
- private Function<ContentInstanceContext, List<ContentProposal>> proposalInstanceFunction = new Function<ContentInstanceContext, List<ContentProposal>>() {
- public List<ContentProposal> apply(ContentInstanceContext input) {
- IProposalProvider proposalProvider = new AcceleoProposalProvider();
- return proposalProvider.getProposals(interpreter, input);
- }
- };
+public class AcceleoMTLCompletionTests extends AbstractCompletionTestCase {
private static final String IMPORT = "org::eclipse::sirius::tests::unit::common::interpreter::acceleo::mtl::AcceleoMtlInterpreterTestModule";
@@ -83,21 +57,36 @@ public class AcceleoMTLCompletionTests extends TestCase {
}
};
+ @Override
protected void setUp() throws Exception {
super.setUp();
-
- interpreter = new AcceleoMTLInterpreter();
- proposalProvider = new AcceleoProposalProvider();
+ setInterpreterAndProposalProvider(new AcceleoMTLInterpreter(), new AcceleoProposalProvider());
};
- @Override
- protected void tearDown() throws Exception {
- interpreter.dispose();
- interpreter = null;
+ /**
+ * Tests proposal based on acceleo prefix.
+ */
+ public void testAcceleoMTLCompletionInterpreterPrefix() {
- proposalProvider = null;
+ ContentContext cc = createContentContext("[", 1, "EClass");
+ assertCompletionMatchesEmptyExpression(cc, compoundProposalFunction);
- super.tearDown();
+ cc = createContentContext("[/", 2, "EClass");
+ assertCompletionMatchesEmptyExpression(cc, compoundProposalFunction);
+ }
+
+ /**
+ * Tests proposal based on acceleo prefix.
+ */
+ public void testAcceleoMTLInstanceCompletionInterpreterPrefix() {
+ EClass c = EcoreFactory.eINSTANCE.createEClass();
+ c.setName("c1");
+
+ ContentInstanceContext cic = new ContentInstanceContext(c, "[", 1);
+ assertCompletionMatchesEmptyExpression(cic, compoundProposalInstanceFunction);
+
+ cic = new ContentInstanceContext(c, "[/", 2);
+ assertCompletionMatchesEmptyExpression(cic, compoundProposalInstanceFunction);
}
/**
@@ -108,12 +97,10 @@ public class AcceleoMTLCompletionTests extends TestCase {
eClass.setName("c");
ContentContext cc = null;
- assertTrue(proposalProvider.getProposals(interpreter, cc).isEmpty());
+ assertTrue(getProposals(cc).isEmpty());
ContentInstanceContext cic = null;
- assertTrue(proposalProvider.getProposals(interpreter, cic).isEmpty());
-
- interpreter.dispose();
+ assertTrue(getProposals(cic).isEmpty());
}
/**
@@ -121,8 +108,7 @@ public class AcceleoMTLCompletionTests extends TestCase {
*/
public void testAcceleoMTLCompletionEmtpyField() {
ContentContext cc = createContentContext("", 0, "EClass");
-
- doTestAcceleoMTLCompletionEmtpyField(cc, proposalFunction);
+ assertCompletionMatchesEmptyExpression(cc, proposalFunction);
}
/**
@@ -133,22 +119,7 @@ public class AcceleoMTLCompletionTests extends TestCase {
c.setName("c1");
ContentInstanceContext cic = new ContentInstanceContext(c, "", 0);
-
- doTestAcceleoMTLCompletionEmtpyField(cic, proposalInstanceFunction);
- }
-
- private <T> void doTestAcceleoMTLCompletionEmtpyField(T context, Function<T, List<ContentProposal>> getProposalFunction) {
- List<ContentProposal> proposals = getProposalFunction.apply(context);
-
- assertEquals(1, proposals.size());
- assertEquals("[/]", proposals.get(0).getProposal());
- assertEquals("[/]", proposals.get(0).getDisplay());
- assertEquals(1, proposals.get(0).getCursorPosition());
-
- ContentProposal newEmtpyExpression = proposalProvider.getNewEmtpyExpression();
- assertEquals("[/]", newEmtpyExpression.getProposal());
- assertEquals("[/]", newEmtpyExpression.getDisplay());
- assertEquals(1, newEmtpyExpression.getCursorPosition());
+ assertCompletionMatchesEmptyExpression(cic, proposalInstanceFunction);
}
/**
@@ -238,15 +209,15 @@ public class AcceleoMTLCompletionTests extends TestCase {
ContentContext cc = createContentContext("[/]", 0, "EClass");
// No completion before [
- List<ContentProposal> contentProposals = proposalProvider.getProposals(interpreter, cc);
+ List<ContentProposal> contentProposals = getProposals(cc);
// assertTrue(contentProposals.isEmpty());
// implicit context
cc = createContentContext("[/]", 1, "EClass");
- contentProposals = proposalProvider.getProposals(interpreter, cc);
+ contentProposals = getProposals(cc);
Set<String> vars = Sets.newHashSet();
- vars.addAll(interpreter.getVariables().keySet());
+ vars.addAll(concreteInterpreter.getVariables().keySet());
vars.add("thisEObject");
vars.add("self");
@@ -254,15 +225,15 @@ public class AcceleoMTLCompletionTests extends TestCase {
//
cc = createContentContext("[self./]", 6, "EClass");
- contentProposals = proposalProvider.getProposals(interpreter, cc);
+ contentProposals = getProposals(cc);
- checkCompletionProposal(c.eClass(), contentProposals, interpreter.getVariables().keySet(), false);
+ checkCompletionProposal(c.eClass(), contentProposals, concreteInterpreter.getVariables().keySet(), false);
// qualified name
cc = createContentContext("[self./]", 6, "ecore.EClass");
- contentProposals = proposalProvider.getProposals(interpreter, cc);
+ contentProposals = getProposals(cc);
- checkCompletionProposal(c.eClass(), contentProposals, interpreter.getVariables().keySet(), false);
+ checkCompletionProposal(c.eClass(), contentProposals, concreteInterpreter.getVariables().keySet(), false);
}
/**
@@ -276,14 +247,14 @@ public class AcceleoMTLCompletionTests extends TestCase {
ContentInstanceContext cic = new ContentInstanceContext(c, "[/]", 0);
// No completion before [
- List<ContentProposal> contentProposals = proposalProvider.getProposals(interpreter, cic);
+ List<ContentProposal> contentProposals = getProposals(cic);
// assertTrue(contentProposals.isEmpty());
cic = new ContentInstanceContext(c, "[/]", 1);
- contentProposals = proposalProvider.getProposals(interpreter, cic);
+ contentProposals = getProposals(cic);
Set<String> vars = Sets.newHashSet();
- vars.addAll(interpreter.getVariables().keySet());
+ vars.addAll(concreteInterpreter.getVariables().keySet());
vars.add("thisEObject");
vars.add("self");
@@ -291,8 +262,8 @@ public class AcceleoMTLCompletionTests extends TestCase {
//
cic = new ContentInstanceContext(c, "[self./]", 6);
- contentProposals = proposalProvider.getProposals(interpreter, cic);
- checkCompletionProposal(c.eClass(), contentProposals, interpreter.getVariables().keySet(), false);
+ contentProposals = getProposals(cic);
+ checkCompletionProposal(c.eClass(), contentProposals, concreteInterpreter.getVariables().keySet(), false);
}
/**
@@ -307,11 +278,11 @@ public class AcceleoMTLCompletionTests extends TestCase {
ContentContext cc = createContentContext("[/]", 0, "DNode", DiagramPackage.eINSTANCE, Collections.<String, String> emptyMap(), Collections.<String> emptyList());
// No completion before [
- List<ContentProposal> contentProposals = proposalProvider.getProposals(interpreter, cc);
+ List<ContentProposal> contentProposals = getProposals(cc);
// assertTrue(contentProposals.isEmpty());
cc = createContentContext("[/]", 1, "DNode", DiagramPackage.eINSTANCE, Collections.<String, String> emptyMap(), Collections.<String> emptyList());
- contentProposals = proposalProvider.getProposals(interpreter, cc);
+ contentProposals = getProposals(cc);
Set<String> vars = Sets.newHashSet();
vars.add("thisEObject");
@@ -320,14 +291,14 @@ public class AcceleoMTLCompletionTests extends TestCase {
checkCompletionProposal(dNode.eClass(), contentProposals, vars, true);
cc = createContentContext("[self./]", 6, "DNode", DiagramPackage.eINSTANCE, Collections.<String, String> emptyMap(), Collections.<String> emptyList());
- contentProposals = proposalProvider.getProposals(interpreter, cc);
+ contentProposals = getProposals(cc);
- checkCompletionProposal(dNode.eClass(), contentProposals, interpreter.getVariables().keySet(), false);
+ checkCompletionProposal(dNode.eClass(), contentProposals, concreteInterpreter.getVariables().keySet(), false);
cc = createContentContext("[self./]", 6, "diagram.DNode", DiagramPackage.eINSTANCE, Collections.<String, String> emptyMap(), Collections.<String> emptyList());
- contentProposals = proposalProvider.getProposals(interpreter, cc);
+ contentProposals = getProposals(cc);
- checkCompletionProposal(dNode.eClass(), contentProposals, interpreter.getVariables().keySet(), false);
+ checkCompletionProposal(dNode.eClass(), contentProposals, concreteInterpreter.getVariables().keySet(), false);
}
/**
@@ -341,14 +312,14 @@ public class AcceleoMTLCompletionTests extends TestCase {
ContentInstanceContext cic = new ContentInstanceContext(dNode, "[/]", 0);
// No completion before [
- List<ContentProposal> contentProposals = proposalProvider.getProposals(interpreter, cic);
+ List<ContentProposal> contentProposals = getProposals(cic);
// assertTrue(contentProposals.isEmpty());
cic = new ContentInstanceContext(dNode, "[/]", 1);
- contentProposals = proposalProvider.getProposals(interpreter, cic);
+ contentProposals = getProposals(cic);
Set<String> vars = Sets.newHashSet();
- vars.addAll(interpreter.getVariables().keySet());
+ vars.addAll(concreteInterpreter.getVariables().keySet());
vars.add("thisEObject");
vars.add("self");
@@ -356,9 +327,9 @@ public class AcceleoMTLCompletionTests extends TestCase {
//
cic = new ContentInstanceContext(dNode, "[self./]", 6);
- contentProposals = proposalProvider.getProposals(interpreter, cic);
+ contentProposals = getProposals(cic);
- checkCompletionProposal(dNode.eClass(), contentProposals, interpreter.getVariables().keySet(), false);
+ checkCompletionProposal(dNode.eClass(), contentProposals, concreteInterpreter.getVariables().keySet(), false);
}
/**
@@ -400,11 +371,11 @@ public class AcceleoMTLCompletionTests extends TestCase {
* "[self.name.concat()/]", cursor : 18
*/
private <T> void doTestAcceleoMTLCompletionWithVariables(EClass c, String varName, T context1, T context2, Function<T, List<ContentProposal>> getProposalFunction) {
- interpreter.setVariable(varName, c);
- assertEquals("Variables was not declared", 1, interpreter.getVariables().size());
+ concreteInterpreter.setVariable(varName, c);
+ assertEquals("Variables was not declared", 1, concreteInterpreter.getVariables().size());
Set<String> vars = Sets.newHashSet();
- vars.addAll(interpreter.getVariables().keySet());
+ vars.addAll(concreteInterpreter.getVariables().keySet());
vars.add("thisEObject");
vars.add("self");
@@ -461,13 +432,13 @@ public class AcceleoMTLCompletionTests extends TestCase {
private <T> void doTestAcceleoMTLCompletionWithDependencies(EClass c, T context1, T context2, T context3, Function<T, List<ContentProposal>> getProposalFunction, Collection<String> dependencies) {
List<String> mockVsms = new ArrayList<String>();
mockVsms.add(SiriusTestsPlugin.PLUGIN_ID);
- interpreter.setProperty(IInterpreter.FILES, mockVsms);
+ concreteInterpreter.setProperty(IInterpreter.FILES, mockVsms);
for (String dep : dependencies) {
- interpreter.addImport(dep);
+ concreteInterpreter.addImport(dep);
}
Set<String> vars = Sets.newHashSet();
- vars.addAll(interpreter.getVariables().keySet());
+ vars.addAll(concreteInterpreter.getVariables().keySet());
vars.add("thisEObject");
vars.add("self");
@@ -525,11 +496,11 @@ public class AcceleoMTLCompletionTests extends TestCase {
private <T> void doTestAcceleoMTLCompletionWithProposalStart(EClass c, CreateContextWithCursorPosition<T> createContextFunction, Function<T, List<ContentProposal>> getProposalFunction) {
List<String> mockVsms = new ArrayList<String>();
mockVsms.add(SiriusTestsPlugin.PLUGIN_ID);
- interpreter.setProperty(IInterpreter.FILES, mockVsms);
- interpreter.addImport(IMPORT);
+ concreteInterpreter.setProperty(IInterpreter.FILES, mockVsms);
+ concreteInterpreter.addImport(IMPORT);
Set<String> vars = Sets.newHashSet();
- vars.addAll(interpreter.getVariables().keySet());
+ vars.addAll(concreteInterpreter.getVariables().keySet());
vars.add("thisEObject");
vars.add("self");
@@ -551,20 +522,6 @@ public class AcceleoMTLCompletionTests extends TestCase {
checkCompletionProposal(c.eClass(), contentProposals, vars, false, Collections.singleton(IMPORT), "nam");
}
- private ContentContext createContentContext(String expression, int cursorPostion, String eClass) {
- return createContentContext(expression, cursorPostion, eClass, Collections.<String, String> emptyMap());
- }
-
- private ContentContext createContentContext(String expression, int cursorPostion, String eClass, Map<String, String> variables) {
- return createContentContext(expression, cursorPostion, eClass, null, variables, Collections.<String> emptyList());
- }
-
- private ContentContext createContentContext(String expression, int cursorPostion, String eClass, EPackage ePackage, Map<String, String> variables, Collection<String> dependencies) {
- Collection<EPackage> pList = ePackage == null ? Collections.<EPackage> emptyList() : Collections.singletonList(ePackage);
- return new ContentContext(expression, cursorPostion, DefaultInterpreterContextFactory.createInterpreterContext(null, true, null, Collections.singletonList(eClass), pList, variables,
- dependencies));
- }
-
private void checkCompletionProposal(EClass eClass, List<ContentProposal> contentProposals, Set<String> variables, boolean ignoreOperationNotFound) {
checkCompletionProposal(eClass, contentProposals, variables, ignoreOperationNotFound, Collections.<String> emptyList(), "");
}
@@ -590,7 +547,7 @@ public class AcceleoMTLCompletionTests extends TestCase {
checkEStruturalFeatures(eClass, proposals, concerned, errorMsg);
- checkEOperations(eClass, implicitContext, proposals, concerned, errorMsg);
+ checkEOperations(eClass, implicitContext, proposals, concerned, getSignature, errorMsg);
checkDependencies(implicitContext, dependencies, proposals, concerned, errorMsg);
@@ -625,65 +582,6 @@ public class AcceleoMTLCompletionTests extends TestCase {
}
}
- private StringBuilder lookForExpectedProposals(Iterable<String> expectedProposals, Collection<String> proposals, Predicate<String> concerned) {
- StringBuilder tmpMsg = new StringBuilder();
-
- for (String prop : Iterables.filter(expectedProposals, concerned)) {
- if (proposals.contains(prop)) {
- proposals.remove(prop);
- } else {
- tmpMsg.append("\n * " + prop);
- }
- }
-
- return tmpMsg;
- }
-
- private void checkEOperations(EClass eClass, boolean implicitContext, Collection<String> proposals, Predicate<String> concerned, StringBuilder errorMsg) {
- // EOperations
- Collection<EOperation> opToCheck = Lists.newArrayList();
- Collection<String> opNames = Sets.newHashSet();
- for (EOperation op : eClass.getEAllOperations()) {
- if (!(implicitContext && opNames.contains(op.getName()))) {
- opNames.add(op.getName());
- opToCheck.add(op);
- }
- }
-
- StringBuilder tmpMsg = lookForExpectedProposals(Iterables.transform(opToCheck, getSignature), proposals, concerned);
-
- if (tmpMsg.length() != 0) {
- tmpMsg.insert(0, "\nSome expected operations are not present in completion proposals:");
- errorMsg.append(tmpMsg.toString());
- }
- }
-
- private void checkEStruturalFeatures(EClass eClass, Collection<String> proposals, Predicate<String> concerned, StringBuilder errorMsg) {
- Function<EStructuralFeature, String> getExpectedProposal = new Function<EStructuralFeature, String>() {
- public String apply(EStructuralFeature from) {
- return from.getName();
- }
- };
-
- // EStructuralfeatures
- StringBuilder tmpMsg = lookForExpectedProposals(Iterables.transform(eClass.getEAllStructuralFeatures(), getExpectedProposal), proposals, concerned);
-
- if (tmpMsg.length() != 0) {
- tmpMsg.insert(0, "\nSome expected features are not present in completion proposals:");
- errorMsg.append(tmpMsg.toString());
- }
- }
-
- private void checkVariables(Set<String> variables, Collection<String> proposals, Predicate<String> concerned, StringBuilder errorMsg) {
- // Variables
- StringBuilder tmpMsg = lookForExpectedProposals(variables, proposals, concerned);
-
- if (tmpMsg.length() != 0) {
- tmpMsg.insert(0, "\nSome expected variables are not present in completion proposals:");
- errorMsg.append(tmpMsg.toString());
- }
- }
-
private String getProposalSignature(EOperation op) {
String opSig = op.getName() + "(";
if (op.getEParameters().size() > 1) {
@@ -722,14 +620,6 @@ public class AcceleoMTLCompletionTests extends TestCase {
}
- private Collection<String> extractProposal(List<ContentProposal> proposals) {
- return Lists.newArrayList(Iterables.transform(proposals, new Function<ContentProposal, String>() {
- public String apply(ContentProposal from) {
- return from.getProposal();
- }
- }));
- }
-
private abstract class CreateContextWithCursorPosition<T> implements Function<String, T> {
int i = 0;
diff --git a/plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/unit/common/interpreter/feature/FeatureCompletionTests.java b/plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/unit/common/interpreter/feature/FeatureCompletionTests.java
new file mode 100644
index 0000000000..966784d503
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/unit/common/interpreter/feature/FeatureCompletionTests.java
@@ -0,0 +1,209 @@
+/*******************************************************************************
+ * Copyright (c) 2010, 2014 THALES GLOBAL SERVICES.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.sirius.tests.unit.common.interpreter.feature;
+
+import java.util.Collection;
+import java.util.List;
+
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EcoreFactory;
+import org.eclipse.emf.ecore.EcorePackage;
+import org.eclipse.sirius.common.tools.api.contentassist.ContentContext;
+import org.eclipse.sirius.common.tools.api.contentassist.ContentInstanceContext;
+import org.eclipse.sirius.common.tools.api.contentassist.ContentProposal;
+import org.eclipse.sirius.common.tools.internal.interpreter.FeatureInterpreter;
+import org.eclipse.sirius.common.ui.tools.internal.interpreter.FeatureProposalProvider;
+import org.eclipse.sirius.diagram.DNode;
+import org.eclipse.sirius.diagram.DiagramFactory;
+import org.eclipse.sirius.diagram.DiagramPackage;
+import org.eclipse.sirius.tests.unit.common.interpreter.AbstractCompletionTestCase;
+
+import com.google.common.base.Function;
+import com.google.common.base.Predicate;
+
+/**
+ * Tests for the {@link FeatureInterpreter} utility class.
+ *
+ * @author mporhel
+ *
+ */
+public class FeatureCompletionTests extends AbstractCompletionTestCase {
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ setInterpreterAndProposalProvider(new FeatureInterpreter(), new FeatureProposalProvider());
+ };
+
+ /**
+ * Tests proposal based on "feature:" prefix.
+ */
+ public void testCompletionOnInterpreterPrefix() {
+ ContentContext cc = createContentContext("f", 1, "EClass");
+ assertCompletionMatchesEmptyExpression(cc, compoundProposalFunction);
+
+ cc = createContentContext("feature", 7, "EClass");
+ assertCompletionMatchesEmptyExpression(cc, compoundProposalFunction);
+ }
+
+ /**
+ * Tests proposal based on "feature:" prefix.
+ */
+ public void testInstanceCompletionOnInterpreterPrefix() {
+ EClass c = EcoreFactory.eINSTANCE.createEClass();
+ c.setName("c1");
+
+ ContentInstanceContext cic = new ContentInstanceContext(c, "f", 1);
+ assertCompletionMatchesEmptyExpression(cic, compoundProposalInstanceFunction);
+
+ cic = new ContentInstanceContext(c, "feature", 7);
+ assertCompletionMatchesEmptyExpression(cic, compoundProposalInstanceFunction);
+ }
+
+ /**
+ * Tests that completion proposals.
+ */
+ public void testFeatureProposals() {
+ EClass eClass = EcoreFactory.eINSTANCE.createEClass();
+ eClass.setName("c");
+
+ ContentContext cc = null;
+ assertTrue(getProposals(cc).isEmpty());
+
+ ContentInstanceContext cic = null;
+ assertTrue(getProposals(cic).isEmpty());
+ }
+
+ /**
+ * Tests emtpy expression proposal.
+ */
+ public void testCompletionEmtpyField() {
+ ContentContext cc = createContentContext("", 0, "EClass");
+ assertCompletionMatchesEmptyExpression(cc, proposalFunction);
+ }
+
+ /**
+ * Tests emtpy expression proposal.
+ */
+ public void testInstanceCompletionEmtpyField() {
+ ContentInstanceContext cic = new ContentInstanceContext(null, "", 0);
+ assertCompletionMatchesEmptyExpression(cic, proposalInstanceFunction);
+ }
+
+ /**
+ * Tests completion for an EClass.
+ */
+ public void testNoCompletion() {
+ EClass c = EcoreFactory.eINSTANCE.createEClass();
+ c.setName("c1");
+
+ Function<Integer, ContentContext> createEmptyExpressionContextWithCursor = new Function<Integer, ContentContext>() {
+ public ContentContext apply(Integer input) {
+ return createContentContext("feature:", input, "EClass");
+ }
+ };
+ doTestNoCompletion(createEmptyExpressionContextWithCursor, proposalFunction);
+ }
+
+ /**
+ * Tests completion for an EClass.
+ */
+ public void testInstanceNoCompletion() {
+ final EClass c = EcoreFactory.eINSTANCE.createEClass();
+ c.setName("c1");
+
+ Function<Integer, ContentInstanceContext> createEmptyExpressionContextWithCursor = new Function<Integer, ContentInstanceContext>() {
+ public ContentInstanceContext apply(Integer input) {
+ return new ContentInstanceContext(c, "feature:", input);
+ }
+ };
+ doTestNoCompletion(createEmptyExpressionContextWithCursor, proposalInstanceFunction);
+ }
+
+ /**
+ * @param createContextFunction
+ * function to give a context with "feature:" and the wanted
+ * cursor position.
+ */
+ private <T> void doTestNoCompletion(Function<Integer, T> createContextFunction, Function<T, List<ContentProposal>> getProposalFunction) {
+ // No completion in between 'f' and ':' in 'feature:'
+ for (int i = 0; i < 8; i++) {
+ T ctx = createContextFunction.apply(i);
+ List<ContentProposal> contentProposals = getProposalFunction.apply(ctx);
+ assertTrue("No completion should be proposed when cursor is between 'f' and ':' in 'feature:' for i=" + i, contentProposals.isEmpty());
+ }
+ }
+
+ /**
+ * Tests completion for an EClass.
+ */
+ public void testCompletionOnEcore() {
+ EClass c = EcoreFactory.eINSTANCE.createEClass();
+ ContentContext cc = createContentContext("feature:", 8, "EClass", EcorePackage.eINSTANCE);
+
+ // implicit context
+ List<ContentProposal> contentProposals = getProposals(cc);
+
+ checkCompletionProposal(c.eClass(), contentProposals);
+ }
+
+ /**
+ * Tests completion for an EClass.
+ */
+ public void testInstanceCompletionOnEcore() {
+ EClass c = EcoreFactory.eINSTANCE.createEClass();
+ ContentInstanceContext cic = new ContentInstanceContext(c, "feature:", 8);
+
+ // implicit context
+ List<ContentProposal> contentProposals = getProposals(cic);
+
+ checkCompletionProposal(c.eClass(), contentProposals);
+ }
+
+ /**
+ * Tests completion for an EClass.
+ */
+ public void testCompletionOnOtherM2() {
+ DNode dNode = DiagramFactory.eINSTANCE.createDNode();
+ ContentContext cc = createContentContext("feature:", 8, "DNode", DiagramPackage.eINSTANCE);
+ List<ContentProposal> contentProposals = getProposals(cc);
+
+ checkCompletionProposal(dNode.eClass(), contentProposals);
+ }
+
+ /**
+ * Tests completion for an EClass.
+ */
+ public void testInstanceCompletionOnOtherM2() {
+ DNode dNode = DiagramFactory.eINSTANCE.createDNode();
+ ContentInstanceContext cic = new ContentInstanceContext(dNode, "feature:", 8);
+
+ List<ContentProposal> contentProposals = getProposals(cic);
+
+ checkCompletionProposal(dNode.eClass(), contentProposals);
+ }
+
+ private void checkCompletionProposal(EClass eClass, List<ContentProposal> contentProposals) {
+ Collection<String> proposals = extractProposal(contentProposals);
+
+ StringBuilder errorMsg = new StringBuilder();
+
+ Predicate<String> concerned = new Predicate<String>() {
+ public boolean apply(String input) {
+ return true;
+ }
+ };
+
+ checkEStruturalFeatures(eClass, proposals, concerned, errorMsg);
+
+ assertTrue(errorMsg.toString(), 0 == errorMsg.length());
+ }
+}
diff --git a/plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/unit/common/interpreter/ocl/OCLCompletionTest.java b/plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/unit/common/interpreter/ocl/OCLCompletionTest.java
index 7cabf1faa6..90a450a4cc 100644
--- a/plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/unit/common/interpreter/ocl/OCLCompletionTest.java
+++ b/plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/unit/common/interpreter/ocl/OCLCompletionTest.java
@@ -15,23 +15,21 @@ import java.util.Collection;
import java.util.List;
import java.util.Set;
-import junit.framework.TestCase;
-
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EOperation;
-import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.EcoreFactory;
import org.eclipse.emf.ecore.EcorePackage;
import org.eclipse.sirius.common.ocl.business.internal.interpreter.OclInterpreter;
import org.eclipse.sirius.common.tools.api.contentassist.ContentContext;
import org.eclipse.sirius.common.tools.api.contentassist.ContentInstanceContext;
import org.eclipse.sirius.common.tools.api.contentassist.ContentProposal;
-import org.eclipse.sirius.common.tools.api.contentassist.IProposalProvider;
import org.eclipse.sirius.common.tools.api.interpreter.IInterpreter;
import org.eclipse.sirius.common.tools.api.util.StringUtil;
import org.eclipse.sirius.diagram.DNode;
import org.eclipse.sirius.diagram.DiagramFactory;
+import org.eclipse.sirius.tests.SiriusTestsPlugin;
import org.eclipse.sirius.tests.support.api.PluginVersionCompatibility;
+import org.eclipse.sirius.tests.unit.common.interpreter.AbstractCompletionTestCase;
import org.osgi.framework.Version;
import com.google.common.base.Function;
@@ -40,8 +38,6 @@ import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
-import org.eclipse.sirius.tests.SiriusTestsPlugin;
-
/**
* Ensures that the OCL interpreter provides correct completion (e.g. in the
* Interpreter View).
@@ -49,20 +45,18 @@ import org.eclipse.sirius.tests.SiriusTestsPlugin;
* @author <a href="mailto:alex.lagarde@obeo.fr">Alex Lagarde</a>
*
*/
-public class OCLCompletionTest extends TestCase {
-
- private OclInterpreter interpreter;
-
- private IProposalProvider proposalProvider;
+public class OCLCompletionTest extends AbstractCompletionTestCase {
/**
- * A function that, once applied, returns all the proposals according to a
- * given {@link ContentInstanceContext}.
+ *
+ * {@inheritDoc}
+ *
+ * @see junit.framework.TestCase#setUp()
*/
- private Function<ContentInstanceContext, List<ContentProposal>> proposalInstanceFunction = new Function<ContentInstanceContext, List<ContentProposal>>() {
- public List<ContentProposal> apply(ContentInstanceContext input) {
- return proposalProvider.getProposals(interpreter, input);
- }
+ protected void setUp() throws Exception {
+ super.setUp();
+ OclInterpreter oclInterpreter = new OclInterpreter();
+ setInterpreterAndProposalProvider(oclInterpreter, oclInterpreter);
};
/**
@@ -76,33 +70,28 @@ public class OCLCompletionTest extends TestCase {
};
/**
- *
- * {@inheritDoc}
- *
- * @see junit.framework.TestCase#setUp()
+ * Tests proposal based on "ocl:" prefix.
*/
- protected void setUp() throws Exception {
- super.setUp();
+ public void testOCLCompletionOnInterpreterPrefix() {
+ ContentContext cc = createContentContext("o", 1, "EClass");
+ assertCompletionMatchesEmptyExpression(cc, compoundProposalFunction);
- // The OCL Interpreter is its own proposal provider (as it implements
- // IProposalProvider)
- interpreter = new OclInterpreter();
- proposalProvider = interpreter;
- };
+ cc = createContentContext("ocl", 3, "EClass");
+ assertCompletionMatchesEmptyExpression(cc, compoundProposalFunction);
+ }
/**
- *
- * {@inheritDoc}
- *
- * @see junit.framework.TestCase#tearDown()
+ * Tests proposal based on "ocl:" prefix.
*/
- @Override
- protected void tearDown() throws Exception {
- interpreter.dispose();
- interpreter = null;
- proposalProvider = null;
+ public void testOCLInstanceOnCompletionInterpreterPrefix() {
+ EClass c = EcoreFactory.eINSTANCE.createEClass();
+ c.setName("c1");
+
+ ContentInstanceContext cic = new ContentInstanceContext(c, "o", 1);
+ assertCompletionMatchesEmptyExpression(cic, compoundProposalInstanceFunction);
- super.tearDown();
+ cic = new ContentInstanceContext(c, "ocl", 3);
+ assertCompletionMatchesEmptyExpression(cic, compoundProposalInstanceFunction);
}
/**
@@ -111,13 +100,13 @@ public class OCLCompletionTest extends TestCase {
*/
public void testOCLProposalsOnNullContext() {
ContentContext cc = null;
- assertTrue(proposalProvider.getProposals(interpreter, cc).isEmpty());
+ assertTrue(getProposals(cc).isEmpty());
ContentInstanceContext cic = null;
- assertTrue(proposalProvider.getProposals(interpreter, cic).isEmpty());
+ assertTrue(getProposals(cic).isEmpty());
cic = new ContentInstanceContext(null, OclInterpreter.OCL_DISCRIMINANT, OclInterpreter.OCL_DISCRIMINANT.length());
- assertTrue(proposalProvider.getProposals(interpreter, cic).isEmpty());
+ assertTrue(getProposals(cic).isEmpty());
}
/**
@@ -158,21 +147,21 @@ public class OCLCompletionTest extends TestCase {
ContentInstanceContext cic = new ContentInstanceContext(c, OclInterpreter.OCL_DISCRIMINANT, 0);
// No completion before ocl:
- List<ContentProposal> contentProposals = proposalProvider.getProposals(interpreter, cic);
+ List<ContentProposal> contentProposals = getProposals(cic);
assertTrue(contentProposals.isEmpty());
// Check completion on 'ocl:'
cic = new ContentInstanceContext(c, OclInterpreter.OCL_DISCRIMINANT, OclInterpreter.OCL_DISCRIMINANT.length());
- contentProposals = proposalProvider.getProposals(interpreter, cic);
+ contentProposals = getProposals(cic);
Set<String> vars = Sets.newHashSet();
- vars.addAll(interpreter.getVariables().keySet());
+ vars.addAll(concreteInterpreter.getVariables().keySet());
vars.add("self");
checkCompletionProposal(c.eClass(), contentProposals, vars);
// Check completion on 'ocl:self.' (should be the same except for 'self'
cic = new ContentInstanceContext(c, OclInterpreter.OCL_DISCRIMINANT + "self.", 9);
vars.remove("self");
- contentProposals = proposalProvider.getProposals(interpreter, cic);
+ contentProposals = getProposals(cic);
checkCompletionProposal(c.eClass(), contentProposals, vars);
}
@@ -185,21 +174,21 @@ public class OCLCompletionTest extends TestCase {
ContentInstanceContext cic = new ContentInstanceContext(dNode, OclInterpreter.OCL_DISCRIMINANT, 0);
// No completion before ocl:
- List<ContentProposal> contentProposals = proposalProvider.getProposals(interpreter, cic);
+ List<ContentProposal> contentProposals = getProposals(cic);
assertTrue(contentProposals.isEmpty());
// Check completion on 'ocl:'
cic = new ContentInstanceContext(dNode, OclInterpreter.OCL_DISCRIMINANT, OclInterpreter.OCL_DISCRIMINANT.length());
- contentProposals = proposalProvider.getProposals(interpreter, cic);
+ contentProposals = getProposals(cic);
Set<String> vars = Sets.newHashSet();
vars.add("self");
checkCompletionProposal(dNode.eClass(), contentProposals, vars);
// Check completion on 'ocl:self.' (should be the same except for 'self'
cic = new ContentInstanceContext(dNode, OclInterpreter.OCL_DISCRIMINANT + "self./", 9);
- contentProposals = proposalProvider.getProposals(interpreter, cic);
+ contentProposals = getProposals(cic);
- checkCompletionProposal(dNode.eClass(), contentProposals, interpreter.getVariables().keySet());
+ checkCompletionProposal(dNode.eClass(), contentProposals, concreteInterpreter.getVariables().keySet());
}
/**
@@ -217,9 +206,9 @@ public class OCLCompletionTest extends TestCase {
};
List<String> mockVsms = new ArrayList<String>();
mockVsms.add(SiriusTestsPlugin.PLUGIN_ID);
- interpreter.setProperty(IInterpreter.FILES, mockVsms);
+ concreteInterpreter.setProperty(IInterpreter.FILES, mockVsms);
Set<String> vars = Sets.newHashSet();
- vars.addAll(interpreter.getVariables().keySet());
+ vars.addAll(concreteInterpreter.getVariables().keySet());
vars.add("self");
// Step 2: call completion on 'ocl:ab' (should return 'abstract')
@@ -310,7 +299,7 @@ public class OCLCompletionTest extends TestCase {
StringBuilder errorMsg = new StringBuilder();
checkVariables(variables, proposals, concerned, errorMsg);
checkEStruturalFeatures(eClass, proposals, concerned, errorMsg);
- checkEOperations(eClass, proposals, concerned, errorMsg);
+ checkEOperations(eClass, true, proposals, concerned, getSignature, errorMsg);
checkStandardOCLOperations(proposals, concerned, errorMsg);
assertTrue(errorMsg.toString(), 0 == errorMsg.length());
@@ -321,106 +310,6 @@ public class OCLCompletionTest extends TestCase {
}
/**
- * Ensures that the given proposal lists contain all the eOperations of the
- * given {@link EClass} starting with the expected prefix.
- *
- * @param eClass
- * the EClass on which completion is called
- * @param proposals
- * the proposals computed by the OCL interpreter
- * @param concerned
- * a predicated allowing to select only the elements starting
- * with the expected prefix
- * @param errorMsg
- * the errorMsg to use for listing missing proposals
- */
- private void checkEOperations(EClass eClass, Collection<String> proposals, Predicate<String> concerned, StringBuilder errorMsg) {
- // Step 1: get the EOperations contained in the given eClass
- Collection<EOperation> opToCheck = Lists.newArrayList();
- Collection<String> opNames = Sets.newHashSet();
- for (EOperation op : eClass.getEAllOperations()) {
- if (!(opNames.contains(op.getName()))) {
- opNames.add(op.getName());
- opToCheck.add(op);
- }
- }
- Iterable<String> expectedEOperationProposals = Iterables.transform(opToCheck, getSignature);
-
- // Step 2: filtering the EOperations according to proposal start
- expectedEOperationProposals = Iterables.filter(expectedEOperationProposals, concerned);
-
- // Step 3: ensure that proposals contain all the expected elements
- StringBuilder tmpMsg = lookForExpectedProposals(expectedEOperationProposals, proposals);
-
- if (tmpMsg.length() != 0) {
- tmpMsg.insert(0, "\nSome expected operations are not present in completion proposals:");
- errorMsg.append(tmpMsg.toString());
- }
- }
-
- /**
- * Ensures that the given proposal lists contain all the eStructuralFeatures
- * of the given {@link EClass} starting with the expected prefix.
- *
- * @param eClass
- * the EClass on which completion is called
- * @param proposals
- * the proposals computed by the OCL interpreter
- * @param concerned
- * a predicated allowing to select only the elements starting
- * with the expected prefix
- * @param errorMsg
- * the errorMsg to use for listing missing proposals
- */
- private void checkEStruturalFeatures(EClass eClass, Collection<String> proposals, Predicate<String> concerned, StringBuilder errorMsg) {
- // Step 1: get all EClasses structural features
- Function<EStructuralFeature, String> getExpectedProposal = new Function<EStructuralFeature, String>() {
- public String apply(EStructuralFeature from) {
- return from.getName();
- }
- };
- Iterable<String> expectedStructuralFeatures = Iterables.transform(eClass.getEAllStructuralFeatures(), getExpectedProposal);
-
- // Step 2: filtering features according to proposal start
- expectedStructuralFeatures = Sets.newLinkedHashSet(Iterables.filter(expectedStructuralFeatures, concerned));
-
- // Step 3: ensure that proposals contain all the expected elements
- StringBuilder tmpMsg = lookForExpectedProposals(expectedStructuralFeatures, proposals);
-
- if (tmpMsg.length() != 0) {
- tmpMsg.insert(0, "\nSome expected features are not present in completion proposals:");
- errorMsg.append(tmpMsg.toString());
- }
- }
-
- /**
- * Ensures that the given proposal lists contain all the given expected
- * variables.
- *
- * @param variables
- * the expected variables
- * @param proposals
- * the proposals computed by the OCL interpreter
- * @param concerned
- * a predicated allowing to select only the elements starting
- * with the expected prefix
- * @param errorMsg
- * the errorMsg to use for listing missing proposals
- */
- private void checkVariables(Set<String> variables, Collection<String> proposals, Predicate<String> concerned, StringBuilder errorMsg) {
- // Step 1: filtering variable according to proposal start
- Set<String> filteredVariables = Sets.newLinkedHashSet(Iterables.filter(variables, concerned));
-
- // Step 2: ensure that proposals list all the expected variables
- StringBuilder tmpMsg = lookForExpectedProposals(filteredVariables, proposals);
-
- if (tmpMsg.length() != 0) {
- tmpMsg.insert(0, "\nSome expected variables are not present in completion proposals:");
- errorMsg.append(tmpMsg.toString());
- }
- }
-
- /**
* Ensures that the given proposal lists contain all the standard OCL
* operations (oclAsType...) and toString.
*
@@ -442,11 +331,8 @@ public class OCLCompletionTest extends TestCase {
oclOperations.add("toString");
}
- // Step 2: filter expected operations according to proposal start
- oclOperations = Sets.newLinkedHashSet(Iterables.filter(oclOperations, concerned));
-
// Step 3: ensure that proposals list all those operations
- StringBuilder tmpMsg = lookForExpectedProposals(oclOperations, proposals);
+ StringBuilder tmpMsg = lookForExpectedProposals(oclOperations, proposals, concerned);
if (tmpMsg.length() != 0) {
tmpMsg.insert(0, "\nSome expected variables are not present in completion proposals:");
@@ -455,30 +341,6 @@ public class OCLCompletionTest extends TestCase {
}
/**
- * Ensures that the given expected proposals are all contained in the given
- * actual proposals.
- *
- * @param expectedProposals
- * the expected proposals
- * @param proposals
- * the proposals computed by the OCL interpreter
- * @return the error message
- */
- private StringBuilder lookForExpectedProposals(Iterable<String> expectedProposals, Collection<String> proposals) {
- StringBuilder tmpMsg = new StringBuilder();
-
- for (String prop : expectedProposals) {
- if (proposals.contains(prop)) {
- proposals.remove(prop);
- } else {
- tmpMsg.append("\n * " + prop);
- }
- }
-
- return tmpMsg;
- }
-
- /**
* Returns the given collection of {@link ContentProposal} as a list of
* String containing the values of each proposal.
*
diff --git a/plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/unit/common/interpreter/service/ServiceCompletionTests.java b/plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/unit/common/interpreter/service/ServiceCompletionTests.java
new file mode 100644
index 0000000000..12e96fdfc9
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/unit/common/interpreter/service/ServiceCompletionTests.java
@@ -0,0 +1,189 @@
+/*******************************************************************************
+ * Copyright (c) 2010, 2014 THALES GLOBAL SERVICES.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.sirius.tests.unit.common.interpreter.service;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Set;
+
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EcoreFactory;
+import org.eclipse.sirius.common.tools.api.contentassist.ContentContext;
+import org.eclipse.sirius.common.tools.api.contentassist.ContentInstanceContext;
+import org.eclipse.sirius.common.tools.api.contentassist.ContentProposal;
+import org.eclipse.sirius.common.tools.internal.interpreter.ServiceInterpreter;
+import org.eclipse.sirius.common.ui.tools.internal.interpreter.ServiceProposalProvider;
+import org.eclipse.sirius.diagram.DNode;
+import org.eclipse.sirius.diagram.DiagramFactory;
+import org.eclipse.sirius.diagram.DiagramPackage;
+import org.eclipse.sirius.tests.unit.common.interpreter.AbstractCompletionTestCase;
+
+import com.google.common.base.Predicate;
+import com.google.common.collect.Sets;
+
+/**
+ * Tests for the {@link ServiceInterpreter} utility class.
+ *
+ * @author mporhel
+ *
+ */
+public class ServiceCompletionTests extends AbstractCompletionTestCase {
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ setInterpreterAndProposalProvider(new ServiceInterpreter(), new ServiceProposalProvider());
+ };
+
+ /**
+ * Tests proposal based on "service:" prefix.
+ */
+ public void testCompletionOnInterpreterPrefix() {
+ ContentContext cc = createContentContext("s", 1, "EClass");
+ assertCompletionMatchesEmptyExpression(cc, compoundProposalFunction);
+
+ cc = createContentContext("service", 7, "EClass");
+ assertCompletionMatchesEmptyExpression(cc, compoundProposalFunction);
+ }
+
+ /**
+ * Tests proposal based on "service:" prefix.
+ */
+ public void testInstanceCompletionOnInterpreterPrefix() {
+ EClass c = EcoreFactory.eINSTANCE.createEClass();
+ c.setName("c1");
+
+ ContentInstanceContext cic = new ContentInstanceContext(c, "s", 1);
+ assertCompletionMatchesEmptyExpression(cic, compoundProposalInstanceFunction);
+
+ cic = new ContentInstanceContext(c, "service", 7);
+ assertCompletionMatchesEmptyExpression(cic, compoundProposalInstanceFunction);
+ }
+
+ /**
+ * Tests that completion proposals.
+ */
+ public void testProposals() {
+ EClass eClass = EcoreFactory.eINSTANCE.createEClass();
+ eClass.setName("c");
+
+ ContentContext cc = null;
+ assertTrue(getProposals(cc).isEmpty());
+
+ ContentInstanceContext cic = null;
+ assertTrue(getProposals(cic).isEmpty());
+ }
+
+ /**
+ * Tests empty expression proposal.
+ */
+ public void testCompletionEmtpyField() {
+ ContentContext cc = createContentContext("", 0, "EClass");
+ assertCompletionMatchesEmptyExpression(cc, proposalFunction);
+ }
+
+ /**
+ * Tests empty expression proposal.
+ */
+ public void testInstanceCompletionEmtpyField() {
+ ContentInstanceContext cic = new ContentInstanceContext(null, "", 0);
+ assertCompletionMatchesEmptyExpression(cic, proposalInstanceFunction);
+ }
+
+ /**
+ * Tests completion for an EClass.
+ */
+ public void testCompletionOnEcore() {
+ EClass c = EcoreFactory.eINSTANCE.createEClass();
+ ContentContext cc = createContentContext("service:", 8, c, "EClass");
+
+ // implicit context
+ List<ContentProposal> contentProposals = getProposals(cc);
+
+ // ServiceProposalProvider add "." at the end of a variable
+ Set<String> vars = Sets.newHashSet();
+ for (String variable : concreteInterpreter.getVariables().keySet()) {
+ vars.add(variable + ".");
+ }
+ vars.add("self.");
+
+ checkCompletionProposal(c.eClass(), contentProposals, vars);
+ }
+
+ /**
+ * Tests completion for an EClass.
+ */
+ public void testInstanceCompletionOnEcore() {
+ EClass c = EcoreFactory.eINSTANCE.createEClass();
+ ContentInstanceContext cic = new ContentInstanceContext(c, "service:", 8);
+
+ List<ContentProposal> contentProposals = getProposals(cic);
+
+ // ServiceProposalProvider add "." at the end of a variable
+ Set<String> vars = Sets.newHashSet();
+ for (String variable : concreteInterpreter.getVariables().keySet()) {
+ vars.add(variable + ".");
+ }
+ vars.add("self.");
+
+ checkCompletionProposal(c.eClass(), contentProposals, vars);
+ }
+
+ /**
+ * Tests completion for an EClass.
+ */
+ public void testCompletionOnOtherM2() {
+
+ DNode dNode = DiagramFactory.eINSTANCE.createDNode();
+ ContentContext cc = createContentContext("service:", 8, dNode, "DNode", DiagramPackage.eINSTANCE);
+
+ List<ContentProposal> contentProposals = getProposals(cc);
+
+ Set<String> vars = Sets.newHashSet();
+
+ // ServiceProposalProvider add "." at the end of a variable
+ vars.add("self.");
+
+ checkCompletionProposal(dNode.eClass(), contentProposals, vars);
+ }
+
+ /**
+ * Tests completion for an EClass.
+ */
+ public void testInstanceCompletionOnOtherM2() {
+ DNode dNode = DiagramFactory.eINSTANCE.createDNode();
+ ContentInstanceContext cic = new ContentInstanceContext(dNode, "service:", 8);
+ List<ContentProposal> contentProposals = getProposals(cic);
+
+ // ServiceProposalProvider add "." at the end of a variable
+ Set<String> vars = Sets.newHashSet();
+ for (String variable : concreteInterpreter.getVariables().keySet()) {
+ vars.add(variable + ".");
+ }
+ vars.add("self.");
+
+ checkCompletionProposal(dNode.eClass(), contentProposals, vars);
+ }
+
+ private void checkCompletionProposal(EClass eClass, List<ContentProposal> contentProposals, Set<String> variables) {
+ Collection<String> proposals = extractProposal(contentProposals);
+ StringBuilder errorMsg = new StringBuilder();
+
+ Predicate<String> concerned = new Predicate<String>() {
+ public boolean apply(String input) {
+ return true;
+ }
+ };
+
+ checkVariables(variables, proposals, concerned, errorMsg);
+ assertTrue(errorMsg.toString(), 0 == errorMsg.length());
+ }
+}
diff --git a/plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/unit/common/interpreter/variable/VariableCompletionTests.java b/plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/unit/common/interpreter/variable/VariableCompletionTests.java
new file mode 100644
index 0000000000..11311b32a7
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/unit/common/interpreter/variable/VariableCompletionTests.java
@@ -0,0 +1,224 @@
+/*******************************************************************************
+ * Copyright (c) 2010, 2014 THALES GLOBAL SERVICES.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.sirius.tests.unit.common.interpreter.variable;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Set;
+
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EcoreFactory;
+import org.eclipse.sirius.common.tools.api.contentassist.ContentContext;
+import org.eclipse.sirius.common.tools.api.contentassist.ContentInstanceContext;
+import org.eclipse.sirius.common.tools.api.contentassist.ContentProposal;
+import org.eclipse.sirius.common.tools.internal.interpreter.VariableInterpreter;
+import org.eclipse.sirius.common.ui.tools.internal.interpreter.VariableProposalProvider;
+import org.eclipse.sirius.diagram.DNode;
+import org.eclipse.sirius.diagram.DiagramFactory;
+import org.eclipse.sirius.diagram.DiagramPackage;
+import org.eclipse.sirius.tests.unit.common.interpreter.AbstractCompletionTestCase;
+
+import com.google.common.base.Function;
+import com.google.common.base.Predicate;
+import com.google.common.collect.Sets;
+
+/**
+ * Tests for the {@link VariableInterpreter} utility class.
+ *
+ * @author mporhel
+ *
+ */
+public class VariableCompletionTests extends AbstractCompletionTestCase {
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ setInterpreterAndProposalProvider(new VariableInterpreter(), new VariableProposalProvider());
+ };
+
+ /**
+ * Tests proposal based on "var:" prefix.
+ */
+ public void testCompletionOnInterpreterPrefix() {
+
+ ContentContext cc = createContentContext("v", 1, "EClass");
+ assertCompletionMatchesEmptyExpression(cc, compoundProposalFunction);
+
+ cc = createContentContext("var", 3, "EClass");
+ assertCompletionMatchesEmptyExpression(cc, compoundProposalFunction);
+ }
+
+ /**
+ * Tests proposal based on "var:" prefix.
+ */
+ public void testInstanceCompletionOnInterpreterPrefix() {
+ EClass c = EcoreFactory.eINSTANCE.createEClass();
+ c.setName("c1");
+
+ ContentInstanceContext cic = new ContentInstanceContext(c, "v", 1);
+ assertCompletionMatchesEmptyExpression(cic, compoundProposalInstanceFunction);
+
+ cic = new ContentInstanceContext(c, "var", 3);
+ assertCompletionMatchesEmptyExpression(cic, compoundProposalInstanceFunction);
+ }
+
+ /**
+ * Tests that completion proposals.
+ */
+ public void testProposals() {
+ EClass eClass = EcoreFactory.eINSTANCE.createEClass();
+ eClass.setName("c");
+
+ ContentContext cc = null;
+ assertTrue(getProposals(cc).isEmpty());
+
+ ContentInstanceContext cic = null;
+ assertTrue(getProposals(cic).isEmpty());
+ }
+
+ /**
+ * Tests empty expression proposal.
+ */
+ public void testCompletionEmtpyField() {
+ ContentContext cc = createContentContext("", 0, "EClass");
+ assertCompletionMatchesEmptyExpression(cc, proposalFunction);
+ }
+
+ /**
+ * Tests empty expression proposal.
+ */
+ public void testInstanceCompletionEmtpyField() {
+ ContentInstanceContext cic = new ContentInstanceContext(null, "", 0);
+ assertCompletionMatchesEmptyExpression(cic, proposalInstanceFunction);
+ }
+
+ /**
+ * Tests completion for an EClass.
+ */
+ public void testNoCompletion() {
+ EClass c = EcoreFactory.eINSTANCE.createEClass();
+ c.setName("c1");
+
+ Function<Integer, ContentContext> createEmptyExpressionContextWithCursor = new Function<Integer, ContentContext>() {
+ public ContentContext apply(Integer input) {
+ return createContentContext("var:", input, "EClass");
+ }
+ };
+ doTestNoCompletion(createEmptyExpressionContextWithCursor, proposalFunction);
+ }
+
+ /**
+ * Tests completion for an EClass.
+ */
+ public void testInstanceNoCompletion() {
+ final EClass c = EcoreFactory.eINSTANCE.createEClass();
+ c.setName("c1");
+
+ Function<Integer, ContentInstanceContext> createEmptyExpressionContextWithCursor = new Function<Integer, ContentInstanceContext>() {
+ public ContentInstanceContext apply(Integer input) {
+ return new ContentInstanceContext(c, "var:", input);
+ }
+ };
+ doTestNoCompletion(createEmptyExpressionContextWithCursor, proposalInstanceFunction);
+ }
+
+ /**
+ * @param createContextFunction
+ * function to give a context with "var:" and the wanted cursor
+ * position.
+ */
+ private <T> void doTestNoCompletion(Function<Integer, T> createContextFunction, Function<T, List<ContentProposal>> getProposalFunction) {
+ // No completion in between 'v' and ':' in 'var:'
+ for (int i = 0; i < 4; i++) {
+ T ctx = createContextFunction.apply(i);
+ List<ContentProposal> contentProposals = getProposalFunction.apply(ctx);
+ assertTrue("No completion should be proposed when cursor is between 'v' and ':' in 'var:' for i=" + i, contentProposals.isEmpty());
+ }
+ }
+
+ /**
+ * Tests completion for an EClass.
+ */
+ public void testCompletionOnEcore() {
+ EClass c = EcoreFactory.eINSTANCE.createEClass();
+ ContentContext cc = createContentContext("var:", 4, "EClass");
+
+ // implicit context
+ List<ContentProposal> contentProposals = getProposals(cc);
+
+ Set<String> vars = Sets.newHashSet();
+ vars.addAll(concreteInterpreter.getVariables().keySet());
+ vars.add("self");
+
+ checkCompletionProposal(c.eClass(), contentProposals, vars);
+ }
+
+ /**
+ * Tests completion for an EClass.
+ */
+ public void testInstanceCompletionOnEcore() {
+ EClass c = EcoreFactory.eINSTANCE.createEClass();
+ ContentInstanceContext cic = new ContentInstanceContext(c, "var:", 4);
+
+ List<ContentProposal> contentProposals = getProposals(cic);
+
+ Set<String> vars = Sets.newHashSet();
+ vars.addAll(concreteInterpreter.getVariables().keySet());
+ vars.add("self");
+
+ checkCompletionProposal(c.eClass(), contentProposals, vars);
+ }
+
+ /**
+ * Tests completion for an EClass.
+ */
+ public void testCompletionOnOtherM2() {
+
+ DNode dNode = DiagramFactory.eINSTANCE.createDNode();
+ ContentContext cc = createContentContext("var:", 4, "DNode", DiagramPackage.eINSTANCE);
+
+ List<ContentProposal> contentProposals = getProposals(cc);
+
+ Set<String> vars = Sets.newHashSet();
+ vars.add("self");
+
+ checkCompletionProposal(dNode.eClass(), contentProposals, vars);
+ }
+
+ /**
+ * Tests completion for an EClass.
+ */
+ public void testInstanceCompletionOnOtherM2() {
+ DNode dNode = DiagramFactory.eINSTANCE.createDNode();
+ ContentInstanceContext cic = new ContentInstanceContext(dNode, "var:", 4);
+ List<ContentProposal> contentProposals = getProposals(cic);
+
+ Set<String> vars = Sets.newHashSet();
+ vars.addAll(concreteInterpreter.getVariables().keySet());
+ vars.add("self");
+
+ checkCompletionProposal(dNode.eClass(), contentProposals, vars);
+ }
+
+ private void checkCompletionProposal(EClass eClass, List<ContentProposal> contentProposals, Set<String> variables) {
+ Collection<String> proposals = extractProposal(contentProposals);
+ StringBuilder errorMsg = new StringBuilder();
+
+ Predicate<String> concerned = new Predicate<String>() {
+ public boolean apply(String input) {
+ return true;
+ }
+ };
+
+ checkVariables(variables, proposals, concerned, errorMsg);
+ assertTrue(errorMsg.toString(), 0 == errorMsg.length());
+ }
+}

Back to the top