Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorcbrun2017-01-09 14:12:49 +0000
committercbrun2017-01-10 10:55:54 +0000
commit2e6405cf20bc22d937c46bab1e5d04d129996981 (patch)
tree07153c1ce4e34b1636096e09a8fba4d862078ee7
parent48270ead5dfd583d865c994827d858695a7acaf3 (diff)
downloadorg.eclipse.sirius-2e6405cf20bc22d937c46bab1e5d04d129996981.tar.gz
org.eclipse.sirius-2e6405cf20bc22d937c46bab1e5d04d129996981.tar.xz
org.eclipse.sirius-2e6405cf20bc22d937c46bab1e5d04d129996981.zip
[509930] Add TestCase to check the VSM validation of Properties
Add a JUnit4 Parameterized test case which will check every interpreted expression in a .odesign file based on the following convention: - if the current element is contained (directly or not) in an element which is called "ShouldBeValid" then the expression should trigger no error - if the current element is contained (directly or not) in an element which is called "ShouldBeInvalid" then the expression should trigger at least one error - if the current expression contains the string 'nonExistent' then it is also expected that the validation fails. The VSM model which is used here (/data/vsm/validateVariableTypes.odesign) lead to the verification of 162 cases. Bug: 509930 Change-Id: Ib28bd19aa4c90210649d65758c05f74fdd7ba9ef Signed-off-by: Cedric Brun <cedric.brun@obeo.fr>
-rw-r--r--plugins/org.eclipse.sirius.tests.ui.properties/META-INF/MANIFEST.MF5
-rw-r--r--plugins/org.eclipse.sirius.tests.ui.properties/data/vsm/validateVariableTypes.odesign139
-rw-r--r--plugins/org.eclipse.sirius.tests.ui.properties/src/org/eclipse/sirius/tests/ui/properties/internal/vsm/PropertiesVSMExpressionValidationTest.java266
3 files changed, 409 insertions, 1 deletions
diff --git a/plugins/org.eclipse.sirius.tests.ui.properties/META-INF/MANIFEST.MF b/plugins/org.eclipse.sirius.tests.ui.properties/META-INF/MANIFEST.MF
index 2a4d4eaaf8..6f0d95ddf7 100644
--- a/plugins/org.eclipse.sirius.tests.ui.properties/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.sirius.tests.ui.properties/META-INF/MANIFEST.MF
@@ -14,5 +14,8 @@ Require-Bundle: org.eclipse.sirius.ui.properties;bundle-version="4.1.0",
org.eclipse.eef,
org.eclipse.emf.ecore.xmi,
org.eclipse.sirius.properties,
- org.eclipse.emf.compare
+ org.eclipse.emf.compare,
+ com.google.guava;bundle-version="[11.0.2,16.0)",
+ org.eclipse.sirius.common.acceleo.aql,
+ org.eclipse.sirius.common
Bundle-Localization: plugin
diff --git a/plugins/org.eclipse.sirius.tests.ui.properties/data/vsm/validateVariableTypes.odesign b/plugins/org.eclipse.sirius.tests.ui.properties/data/vsm/validateVariableTypes.odesign
new file mode 100644
index 0000000000..d8cdc67942
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.ui.properties/data/vsm/validateVariableTypes.odesign
@@ -0,0 +1,139 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<description:Group xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:description="http://www.eclipse.org/sirius/description/1.1.0" xmlns:properties="http://www.eclipse.org/sirius/properties/1.0.0" xmlns:properties-ext-widgets-reference="http://www.eclipse.org/sirius/properties/1.0.0/ext/widgets/reference" xmlns:tool="http://www.eclipse.org/sirius/description/tool/1.1.0" name="vsmtypes" version="11.1.1.201610211630">
+ <extensions xsi:type="properties:ViewExtensionDescription" identifier="ShouldBeValid">
+ <metamodels href="http://www.eclipse.org/emf/2002/Ecore#/"/>
+ <metamodels href="http://www.eclipse.org/sirius/sample/interactions#/"/>
+ <pages identifier="Default" labelExpression="aql:self.nsURI" domainClass="ecore.EPackage" semanticCandidateExpression="aql:self" preconditionExpression="aql:self.nsURI &lt;> ''" groups="//@extensions.0/@groups.0"/>
+ <groups identifier="Default" labelExpression="Group" semanticCandidateExpression="aql:OrderedSet{self}->select( e | e.nsURI &lt;> '')" preconditionExpression="aql:self.nsURI &lt;> ''">
+ <controls xsi:type="properties:TextDescription" labelExpression="aql:self.nsURI" helpExpression="aql:self.nsURI" isEnabledExpression="aql:self.nsURI &lt;> ''" valueExpression="aql:self.eClassifiers.name->sep(',')">
+ <initialOperation>
+ <firstModelOperations xsi:type="tool:ChangeContext" browseExpression="var:self">
+ <subModelOperations xsi:type="tool:ChangeContext" browseExpression="aql:input.getOriginalSelection()"/>
+ <subModelOperations xsi:type="tool:For" expression="aql:self.eClassifiers" iteratorName="c">
+ <subModelOperations xsi:type="tool:ChangeContext" browseExpression="aql:c.ePackage"/>
+ </subModelOperations>
+ <subModelOperations xsi:type="tool:If" conditionExpression="aql:self.nsURI &lt;> newValue">
+ <subModelOperations xsi:type="tool:SetValue" featureName="nsURI" valueExpression="aql:newValue"/>
+ </subModelOperations>
+ </firstModelOperations>
+ </initialOperation>
+ <style fontNameExpression="aql:self.nsURI" fontSizeExpression="aql:self.eClassifiers->size()"/>
+ <conditionalStyles preconditionExpression="aql:self.nsURI &lt;> input.emfEditServices(self).getText()">
+ <style fontNameExpression="aql:input.emfEditServices(self).getText()" fontSizeExpression="aql:input.emfEditServices(self).getText().size()"/>
+ </conditionalStyles>
+ </controls>
+ <controls xsi:type="properties:CheckboxDescription" labelExpression="aql:self.nsURI" helpExpression="aql:self.nsURI" isEnabledExpression="aql:self.eClassifiers->size() > 0" valueExpression="aql:self.eClassifiers->size() > 0">
+ <initialOperation>
+ <firstModelOperations xsi:type="tool:ChangeContext" browseExpression="var:self">
+ <subModelOperations xsi:type="tool:If" conditionExpression="aql:newValue = true"/>
+ </firstModelOperations>
+ </initialOperation>
+ </controls>
+ <controls xsi:type="properties:RadioDescription" labelExpression="aql:self.nsURI" helpExpression="aql:self.nsURI" isEnabledExpression="aql:self.nsURI &lt;> 0" valueExpression="aql:self.eClassifiers->first()" candidatesExpression="aql:self.eClassifiers" candidateDisplayExpression="aql:candidate.instanceClassName">
+ <initialOperation>
+ <firstModelOperations xsi:type="tool:ChangeContext" browseExpression="var:self"/>
+ </initialOperation>
+ </controls>
+ <controls xsi:type="properties:SelectDescription" labelExpression="aql:self.nsURI" helpExpression="aql:self.nsURI" isEnabledExpression="aql:self.nsURI.size() > 0" valueExpression="aql: self.eClassifiers->first()" candidatesExpression="aql:self.eClassifiers" candidateDisplayExpression="aql:candidate.instanceClassName">
+ <initialOperation>
+ <firstModelOperations xsi:type="tool:ChangeContext" browseExpression="var:self"/>
+ </initialOperation>
+ </controls>
+ <controls xsi:type="properties:TextAreaDescription" labelExpression="aql:self.nsURI" helpExpression="aql:self.nsURI" isEnabledExpression="aql:self.eClassifiers->size() > 0" valueExpression="aql:self.eClassifiers->first()">
+ <initialOperation>
+ <firstModelOperations xsi:type="tool:ChangeContext" browseExpression="var:self"/>
+ </initialOperation>
+ </controls>
+ <controls xsi:type="properties:LabelDescription" labelExpression="aql:self.nsURI" helpExpression="aql:self.nsURI" isEnabledExpression="aql:self.eClassifiers->size() > 0" valueExpression="aql:self.eClassifiers->first()" displayExpression="aql:self.eClassifiers->first().instanceClassName"/>
+ <controls xsi:type="properties-ext-widgets-reference:ExtReferenceDescription" labelExpression="aql:self.nsURI" helpExpression="aql:self.nsURI" isEnabledExpression="aql:self.nsURI &lt;> null" referenceNameExpression="aql:'eClassifiers'" referenceOwnerExpression="aql:self"/>
+ <controls xsi:type="properties:ListDescription" labelExpression="aql:self.nsURI" helpExpression="aql:self.nsURI" isEnabledExpression="aql:self.nsURI.size() > 0" valueExpression="aql:self.eClassifiers->first()" displayExpression="aql:self.nsURI">
+ <onClickOperation>
+ <firstModelOperations xsi:type="tool:ChangeContext" browseExpression="var:self"/>
+ </onClickOperation>
+ </controls>
+ <controls xsi:type="properties:HyperlinkDescription" labelExpression="aql:self.nsURI" helpExpression="aql:self.nsURI" isEnabledExpression="aql:self.eClassifiers->size() > 0" valueExpression="aql:self.eClassifiers->first()" displayExpression="aql:self.nsURI">
+ <initialOperation>
+ <firstModelOperations xsi:type="tool:ChangeContext" browseExpression="var:self"/>
+ </initialOperation>
+ </controls>
+ <controls xsi:type="properties:ButtonDescription" labelExpression="aql:self.nsURI" helpExpression="aql:self.nsURI" isEnabledExpression="aql:self.nsURI.size() > 0" buttonLabelExpression="aql:self.nsURI">
+ <initialOperation>
+ <firstModelOperations xsi:type="tool:ChangeContext" browseExpression="var:self"/>
+ </initialOperation>
+ </controls>
+ <controls xsi:type="properties:CustomDescription" labelExpression="aql:self.nsURI" helpExpression="aql:self.nsURI" isEnabledExpression="aql:self.nsURI.size() > 0"/>
+ <style fontNameExpression="aql:self.nsURI" fontSizeExpression="aql:self.nsURI.size()"/>
+ <conditionalStyles preconditionExpression="aql:self.nsURI&lt;> ''">
+ <style fontNameExpression="aql:self.nsURI" fontSizeExpression="aql:self.nsURI.size()"/>
+ </conditionalStyles>
+ </groups>
+ </extensions>
+ <extensions xsi:type="properties:ViewExtensionDescription" identifier="ShouldBeInvalid">
+ <metamodels href="http://www.eclipse.org/emf/2002/Ecore#/"/>
+ <metamodels href="http://www.eclipse.org/sirius/sample/interactions#/"/>
+ <pages identifier="Default" labelExpression="aql:self.nonExistent" domainClass="ecore.EPackage" semanticCandidateExpression="aql:self" preconditionExpression="aql:self.nonExistent &lt;> ''" groups="//@extensions.1/@groups.0"/>
+ <groups identifier="Default" labelExpression="Group" semanticCandidateExpression="aql:OrderedSet{self}->select( e | e.nonExistent &lt;> '')" preconditionExpression="aql:self.nonExistent &lt;> ''">
+ <controls xsi:type="properties:TextDescription" labelExpression="aql:self.nonExistent" helpExpression="aql:self.nonExistent" isEnabledExpression="aql:self.nonExistent &lt;> ''" valueExpression="aql:self.eClassifiers.name->sep(',')">
+ <initialOperation>
+ <firstModelOperations xsi:type="tool:ChangeContext" browseExpression="var:self">
+ <subModelOperations xsi:type="tool:ChangeContext" browseExpression="aql:input.getOriginalSelection()"/>
+ <subModelOperations xsi:type="tool:For" expression="aql:self.eClassifiers" iteratorName="c">
+ <subModelOperations xsi:type="tool:ChangeContext" browseExpression="aql:c.ePackage"/>
+ </subModelOperations>
+ <subModelOperations xsi:type="tool:If" conditionExpression="aql:self.nonExistent &lt;> newValue">
+ <subModelOperations xsi:type="tool:SetValue" featureName="nonExistent" valueExpression="aql:newValue"/>
+ </subModelOperations>
+ </firstModelOperations>
+ </initialOperation>
+ <style fontNameExpression="aql:self.nonExistent" fontSizeExpression="aql:self.nonExistent.size()"/>
+ <conditionalStyles preconditionExpression="aql:self.nonExistent &lt;> input.emfEditServices(self).getText()">
+ <style fontNameExpression="aql:input.emfEditServices(self).getText()" fontSizeExpression="aql:input.emfEditServices(self).getText().size()"/>
+ </conditionalStyles>
+ </controls>
+ <controls xsi:type="properties:CheckboxDescription" labelExpression="aql:self.nonExistent" helpExpression="aql:self.nonExistent" isEnabledExpression="aql:self.nonExistent.size() > 0" valueExpression="aql:self.nonExistent.size() > 0">
+ <initialOperation>
+ <firstModelOperations xsi:type="tool:ChangeContext" browseExpression="var:self">
+ <subModelOperations xsi:type="tool:If" conditionExpression="aql:newValue = true"/>
+ </firstModelOperations>
+ </initialOperation>
+ </controls>
+ <controls xsi:type="properties:RadioDescription" labelExpression="aql:self.nonExistent" helpExpression="aql:self.nonExistent" isEnabledExpression="aql:self.nonExistent &lt;> 0" valueExpression="aql:self.nonExistent->first()" candidatesExpression="aql:self.eClassifiers" candidateDisplayExpression="aql:candidate.instanceClassName">
+ <initialOperation>
+ <firstModelOperations xsi:type="tool:ChangeContext" browseExpression="var:self"/>
+ </initialOperation>
+ </controls>
+ <controls xsi:type="properties:SelectDescription" labelExpression="aql:self.nonExistent" helpExpression="aql:self.nonExistent" isEnabledExpression="aql:self.nonExistent.size() > 0" valueExpression="aql: self.nonExistent->first()" candidatesExpression="aql:self.eClassifiers" candidateDisplayExpression="aql:candidate.instanceClassName">
+ <initialOperation>
+ <firstModelOperations xsi:type="tool:ChangeContext" browseExpression="var:self"/>
+ </initialOperation>
+ </controls>
+ <controls xsi:type="properties:TextAreaDescription" labelExpression="aql:self.nonExistent" helpExpression="aql:self.nonExistent" isEnabledExpression="aql:self.nonExistent.size() > 0" valueExpression="aql:self.nonExistent->first()">
+ <initialOperation>
+ <firstModelOperations xsi:type="tool:ChangeContext" browseExpression="var:self"/>
+ </initialOperation>
+ </controls>
+ <controls xsi:type="properties:LabelDescription" labelExpression="aql:self.nonExistent" helpExpression="aql:self.nonExistent" isEnabledExpression="aql:self.nonExistent.size() > 0" valueExpression="aql:self.nonExistent->first()" displayExpression="aql:self.nonExistent->first().instanceClassName"/>
+ <controls xsi:type="properties-ext-widgets-reference:ExtReferenceDescription" labelExpression="aql:self.nonExistent" helpExpression="aql:self.nonExistent" isEnabledExpression="aql:self.nonExistent &lt;> null" referenceNameExpression="aql:'eClassifiers'" referenceOwnerExpression="aql:self"/>
+ <controls xsi:type="properties:ListDescription" labelExpression="aql:self.nonExistent" helpExpression="aql:self.nonExistent" isEnabledExpression="aql:self.nonExistent.size() > 0" valueExpression="aql:self.nonExistent->first()" displayExpression="aql:self.nonExistent">
+ <onClickOperation>
+ <firstModelOperations xsi:type="tool:ChangeContext" browseExpression="var:self"/>
+ </onClickOperation>
+ </controls>
+ <controls xsi:type="properties:HyperlinkDescription" labelExpression="aql:self.nonExistent" helpExpression="aql:self.nonExistent" isEnabledExpression="aql:self.nonExistent.size() > 0" valueExpression="aql:self.nonExistent->first()" displayExpression="aql:self.nonExistent">
+ <initialOperation>
+ <firstModelOperations xsi:type="tool:ChangeContext" browseExpression="var:self"/>
+ </initialOperation>
+ </controls>
+ <controls xsi:type="properties:ButtonDescription" labelExpression="aql:self.nonExistent" helpExpression="aql:self.nonExistent" isEnabledExpression="aql:self.nonExistent.size() > 0" buttonLabelExpression="aql:self.nonExistent">
+ <initialOperation>
+ <firstModelOperations xsi:type="tool:ChangeContext" browseExpression="var:self"/>
+ </initialOperation>
+ </controls>
+ <controls xsi:type="properties:CustomDescription" labelExpression="aql:self.nonExistent" helpExpression="aql:self.nonExistent" isEnabledExpression="aql:self.nonExistent.size() > 0"/>
+ <style fontNameExpression="aql:self.nonExistent" fontSizeExpression="aql:self.nonExistent.size()"/>
+ <conditionalStyles preconditionExpression="aql:self.nonExistent&lt;> ''">
+ <style fontNameExpression="aql:self.nonExistent" fontSizeExpression="aql:self.nonExistent.size()"/>
+ </conditionalStyles>
+ </groups>
+ </extensions>
+</description:Group>
diff --git a/plugins/org.eclipse.sirius.tests.ui.properties/src/org/eclipse/sirius/tests/ui/properties/internal/vsm/PropertiesVSMExpressionValidationTest.java b/plugins/org.eclipse.sirius.tests.ui.properties/src/org/eclipse/sirius/tests/ui/properties/internal/vsm/PropertiesVSMExpressionValidationTest.java
new file mode 100644
index 0000000000..5cda437890
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.ui.properties/src/org/eclipse/sirius/tests/ui/properties/internal/vsm/PropertiesVSMExpressionValidationTest.java
@@ -0,0 +1,266 @@
+/*******************************************************************************
+ * Copyright (c) 2017 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.ui.properties.internal.vsm;
+
+import static org.junit.Assert.fail;
+
+import java.io.IOException;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.EAttribute;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.resource.ResourceSet;
+import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
+import org.eclipse.emf.ecore.util.ECrossReferenceAdapter;
+import org.eclipse.sirius.business.api.dialect.description.MultiLanguagesValidator;
+import org.eclipse.sirius.common.tools.api.interpreter.CompoundInterpreter;
+import org.eclipse.sirius.common.tools.api.interpreter.IInterpreter;
+import org.eclipse.sirius.common.tools.api.interpreter.IInterpreterContext;
+import org.eclipse.sirius.common.tools.api.interpreter.IInterpreterStatus;
+import org.eclipse.sirius.tests.ui.properties.internal.SiriusUiPropertiesTestsEMFPlugin;
+import org.eclipse.sirius.tools.api.interpreter.context.SiriusInterpreterContextFactory;
+import org.eclipse.sirius.viewpoint.description.DescriptionPackage;
+import org.eclipse.sirius.viewpoint.description.Group;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+import com.google.common.base.Function;
+import com.google.common.base.Joiner;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+
+/**
+ * Test checking the variable types are correctly infered when validating a VSM.
+ *
+ * @author <a href="mailto:cedric.brun@obeo.fr">Cedric Brun</a>
+ */
+@RunWith(value = Parameterized.class)
+public class PropertiesVSMExpressionValidationTest {
+ /**
+ * This VSM is conform to some specific conventions to make it easy to test
+ * the type analysis of variables in a VSM.
+ *
+ * Types are checked by having a ChangeContext operation with
+ * feature:someThing where someThing is specific to the expected type.
+ *
+ * feature:nonExistent is used through the VSM for expressions we expect to
+ * fail.
+ *
+ * There are two sections of tools : "ShouldBeValid" is supposed to have no
+ * validation error whatsoever "ShouldBeInvalid" is supposed to have *every
+ * feature:* expression in it failing with a validation error.
+ *
+ */
+ private static final String ODESIGN_TO_CHECK = "/" + SiriusUiPropertiesTestsEMFPlugin.PLUGIN_ID + "/data/vsm/validateVariableTypes.odesign";
+
+ private InterpretedExpression underTest;
+
+ /**
+ * Create the test instance.
+ *
+ * @param expression
+ * the expression to validate.
+ */
+ public PropertiesVSMExpressionValidationTest(InterpretedExpression expression) {
+ this.underTest = expression;
+ }
+
+ /**
+ * Gather all the expressions to test.
+ *
+ * @return the parameters for the test.
+ * @throws IOException
+ * if the file is not found.
+ */
+ @Parameters(name = "org.eclipse.sirius.tests.ui.properties.internal.vsm.PropertiesVSMExpressionValidationTest.{index}: ({0})")
+ public static Collection<Object[]> data() throws IOException {
+ URI uri = URI.createPlatformPluginURI(ODESIGN_TO_CHECK, true);
+
+ List<Object[]> parameters = Lists.newArrayList();
+ Group group = loadVSM(uri);
+ if (group != null) {
+ Iterator<EObject> it = group.eAllContents();
+ while (it.hasNext()) {
+ EObject underTest = it.next();
+ for (EAttribute attr : underTest.eClass().getEAllAttributes()) {
+ if (attr.getEType() == DescriptionPackage.eINSTANCE.getInterpretedExpression()) {
+ Object expr = underTest.eGet(attr);
+ if (expr instanceof String && ((String) expr).length() > 0) {
+ parameters.add(new Object[] { new InterpretedExpression((String) expr, underTest, attr) });
+ }
+
+ }
+ }
+ }
+ }
+ return parameters;
+ }
+
+ private static Group loadVSM(URI uri) {
+ ResourceSet set = new ResourceSetImpl();
+ /*
+ * we need an ECrossReferenceAdapter as some of the VSM implementation
+ * classes are needing it.
+ */
+ ECrossReferenceAdapter crossReferencer = new ECrossReferenceAdapter();
+ set.eAdapters().add(crossReferencer);
+ Resource res = set.getResource(uri, true);
+ for (EObject root : res.getContents()) {
+ if (root instanceof Group) {
+ return (Group) root;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * This test triggers the validation on the current expression and checks
+ * the expectations regarding the reported statuses (there is an error, or
+ * not) are fulfilled. Such expectations are encoded by the use of
+ * 'nonExistent' in the expression when an error should be triggered or the
+ * fact that the englobing tool is in a section named 'ShouldBeInvalid'
+ * Otherwise we expects to have no validation error.
+ *
+ * Any expression which is a direct or indirect children of a tool section
+ * named 'Ignored' is not considered by this test.
+ */
+ @Test
+ public void matchesExpectationsRegardingValidation() {
+ String expression = this.underTest.getExpression();
+ IInterpreter interpreterForExpression = CompoundInterpreter.INSTANCE.getInterpreterForExpression(expression);
+
+ Collection<IInterpreterStatus> errors = Sets.newLinkedHashSet();
+ if (interpreterForExpression.supportsValidation()) {
+ IInterpreterContext context = SiriusInterpreterContextFactory.createInterpreterContext(this.underTest.getDeclaration(), this.underTest.getFeature());
+ errors = MultiLanguagesValidator.getInstance().validateExpression(context, expression).getStatuses();
+ boolean useNonExistantFeature = expression.contains("nonExistent");
+ if (!hasParentNamed(underTest.getDeclaration(), "Ignored")) {
+ if (useNonExistantFeature && errors.size() == 0) {
+ /*
+ * we should have an error
+ */
+ fail("We expected at least an error for : " + this.underTest.toString());
+ } else {
+ /*
+ * we have errors
+ */
+ if (hasParentNamed(underTest.getDeclaration(), "ShouldBeInvalid") && !useNonExistantFeature) {
+ /*
+ * its ok to have an error here.
+ */
+ } else if (!useNonExistantFeature && errors.size() > 0) {
+ String message = underTest.toString() + "triggers unexpected errors \n" + Joiner.on('\n').join(Iterables.transform(errors, new Function<IInterpreterStatus, String>() {
+
+ @Override
+ public String apply(IInterpreterStatus input) {
+ return input.getSeverity() + " : " + input.getMessage();
+ }
+ }));
+
+ fail(message);
+ }
+
+ }
+ }
+ }
+
+ }
+
+ private boolean hasParentNamed(EObject declaration, String name) {
+ EObject cur = declaration;
+ while (cur != null) {
+ if (cur.eClass().getEStructuralFeature("identifier") != null) {
+ Object val = cur.eGet(cur.eClass().getEStructuralFeature("identifier"));
+ if (val instanceof String && name.equals(val)) {
+ return true;
+ }
+ }
+
+ cur = cur.eContainer();
+
+ }
+ return false;
+ }
+
+}
+
+class InterpretedExpression {
+
+ private String expression;
+
+ private EObject declaration;
+
+ private EAttribute feature;
+
+ public InterpretedExpression(String expression, EObject declaration, EAttribute feature) {
+ super();
+ this.expression = expression;
+ this.declaration = declaration;
+ this.feature = feature;
+ }
+
+ public String getExpression() {
+ return expression;
+ }
+
+ public EObject getDeclaration() {
+ return declaration;
+ }
+
+ public EAttribute getFeature() {
+ return feature;
+ }
+
+ @Override
+ public String toString() {
+ return getFeature().getName() + " : " + expression + " in " + qualifiedName(getDeclaration());
+ }
+
+ private String qualifiedName(EObject target) {
+ List<String> segments = Lists.newArrayList();
+
+ EObject cur = target;
+ while (cur != null) {
+
+ Object label = getIfThere(cur, "label");
+ if (label instanceof String) {
+ segments.add((String) label);
+ } else {
+ Object name = getIfThere(cur, "name");
+ if (name instanceof String) {
+ segments.add((String) name);
+ } else {
+ segments.add(cur.eClass().getName());
+ }
+
+ }
+ cur = cur.eContainer();
+ }
+ return Joiner.on(':').join(Lists.reverse(segments));
+ }
+
+ private Object getIfThere(EObject cur, String name) {
+ EStructuralFeature feat = cur.eClass().getEStructuralFeature(name);
+ if (feat != null) {
+ return cur.eGet(feat);
+ }
+ return null;
+ }
+
+}

Back to the top