summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMoritz Eysholdt2014-04-10 06:03:26 (EDT)
committerMoritz Eysholdt2014-04-10 06:14:49 (EDT)
commite249ebf1c6126b097b2de95d04536b595509f0f2 (patch)
treef177ed084a26726b5e0301522c8f04a3e37203f0
parent024253a736ce64a008bef70474ecb5fe667b32bc (diff)
downloadorg.eclipse.emf-e249ebf1c6126b097b2de95d04536b595509f0f2.zip
org.eclipse.emf-e249ebf1c6126b097b2de95d04536b595509f0f2.tar.gz
org.eclipse.emf-e249ebf1c6126b097b2de95d04536b595509f0f2.tar.bz2
moved the legacy impl of Xpect to test.ecore.xcore because it has been deleted from Xtextrefs/changes/76/24776/1
For the removal from Xtext, see http://git.eclipse.org/c/tmf/org.eclipse.xtext.git/commit/?id=5d0f6a026c563d4af0cc0958dcc82b59d3ccebcf and https://bugs.eclipse.org/bugs/show_bug.cgi?id=406198 Signed-off-by: Moritz Eysholdt <moritz.eysholdt@itemis.de>
-rw-r--r--tests/org.eclipse.emf.test.ecore.xcore/src/org/eclipse/emf/test/ecore/xcore/ecore/XcoreEcoreTest.java10
-rw-r--r--tests/org.eclipse.emf.test.ecore.xcore/src/org/eclipse/emf/test/ecore/xcore/genmodel/XcoreGenModelTest.java12
-rw-r--r--tests/org.eclipse.emf.test.ecore.xcore/src/org/eclipse/emf/test/ecore/xcore/legacy_xpect_runner/ActualCollection.java47
-rw-r--r--tests/org.eclipse.emf.test.ecore.xcore/src/org/eclipse/emf/test/ecore/xcore/legacy_xpect_runner/ExpectationCollection.java354
-rw-r--r--tests/org.eclipse.emf.test.ecore.xcore/src/org/eclipse/emf/test/ecore/xcore/legacy_xpect_runner/IParameterProvider.java61
-rw-r--r--tests/org.eclipse.emf.test.ecore.xcore/src/org/eclipse/emf/test/ecore/xcore/legacy_xpect_runner/InjectParameter.java21
-rw-r--r--tests/org.eclipse.emf.test.ecore.xcore/src/org/eclipse/emf/test/ecore/xcore/legacy_xpect_runner/Offset.java138
-rw-r--r--tests/org.eclipse.emf.test.ecore.xcore/src/org/eclipse/emf/test/ecore/xcore/legacy_xpect_runner/ParameterSyntax.java21
-rw-r--r--tests/org.eclipse.emf.test.ecore.xcore/src/org/eclipse/emf/test/ecore/xcore/legacy_xpect_runner/ParameterizedXtextRunner.java521
-rw-r--r--tests/org.eclipse.emf.test.ecore.xcore/src/org/eclipse/emf/test/ecore/xcore/legacy_xpect_runner/ResourceURICollector.java71
-rw-r--r--tests/org.eclipse.emf.test.ecore.xcore/src/org/eclipse/emf/test/ecore/xcore/legacy_xpect_runner/ResourceURIs.java26
-rw-r--r--tests/org.eclipse.emf.test.ecore.xcore/src/org/eclipse/emf/test/ecore/xcore/legacy_xpect_runner/StringCollection.java166
-rw-r--r--tests/org.eclipse.emf.test.ecore.xcore/src/org/eclipse/emf/test/ecore/xcore/legacy_xpect_runner/TestExpectationValidator.java52
-rw-r--r--tests/org.eclipse.emf.test.ecore.xcore/src/org/eclipse/emf/test/ecore/xcore/legacy_xpect_runner/Xpect.java20
-rw-r--r--tests/org.eclipse.emf.test.ecore.xcore/src/org/eclipse/emf/test/ecore/xcore/legacy_xpect_runner/XpectCommaSeparatedValues.java158
-rw-r--r--tests/org.eclipse.emf.test.ecore.xcore/src/org/eclipse/emf/test/ecore/xcore/legacy_xpect_runner/XpectLines.java111
-rw-r--r--tests/org.eclipse.emf.test.ecore.xcore/src/org/eclipse/emf/test/ecore/xcore/legacy_xpect_runner/XpectParameterProvider.java541
-rw-r--r--tests/org.eclipse.emf.test.ecore.xcore/src/org/eclipse/emf/test/ecore/xcore/legacy_xpect_runner/XpectString.java73
-rw-r--r--tests/org.eclipse.emf.test.ecore.xcore/src/org/eclipse/emf/test/ecore/xcore/scoping/XcoreScopingTest.java12
-rw-r--r--tests/org.eclipse.emf.test.ecore.xcore/src/org/eclipse/emf/test/ecore/xcore/validation/XcoreParameterizedTestRunner.java3
-rw-r--r--tests/org.eclipse.emf.test.ecore.xcore/src/org/eclipse/emf/test/ecore/xcore/validation/XcoreValidationTest.java6
21 files changed, 2402 insertions, 22 deletions
diff --git a/tests/org.eclipse.emf.test.ecore.xcore/src/org/eclipse/emf/test/ecore/xcore/ecore/XcoreEcoreTest.java b/tests/org.eclipse.emf.test.ecore.xcore/src/org/eclipse/emf/test/ecore/xcore/ecore/XcoreEcoreTest.java
index 6ef526e..1e7523b 100644
--- a/tests/org.eclipse.emf.test.ecore.xcore/src/org/eclipse/emf/test/ecore/xcore/ecore/XcoreEcoreTest.java
+++ b/tests/org.eclipse.emf.test.ecore.xcore/src/org/eclipse/emf/test/ecore/xcore/ecore/XcoreEcoreTest.java
@@ -14,12 +14,12 @@ import org.eclipse.emf.ecore.xcore.XNamedElement;
import org.eclipse.emf.ecore.xcore.XcoreInjectorProvider;
import org.eclipse.emf.ecore.xcore.mappings.XcoreMapper;
import org.eclipse.emf.test.ecore.xcore.GenModelFormatter;
+import org.eclipse.emf.test.ecore.xcore.legacy_xpect_runner.InjectParameter;
+import org.eclipse.emf.test.ecore.xcore.legacy_xpect_runner.Offset;
+import org.eclipse.emf.test.ecore.xcore.legacy_xpect_runner.ParameterizedXtextRunner;
+import org.eclipse.emf.test.ecore.xcore.legacy_xpect_runner.ResourceURIs;
+import org.eclipse.emf.test.ecore.xcore.legacy_xpect_runner.XpectString;
import org.eclipse.xtext.junit4.InjectWith;
-import org.eclipse.xtext.junit4.parameterized.InjectParameter;
-import org.eclipse.xtext.junit4.parameterized.Offset;
-import org.eclipse.xtext.junit4.parameterized.ParameterizedXtextRunner;
-import org.eclipse.xtext.junit4.parameterized.ResourceURIs;
-import org.eclipse.xtext.junit4.parameterized.XpectString;
import org.eclipse.xtext.junit4.validation.ValidationTestHelper;
import org.eclipse.xtext.resource.XtextResource;
import org.junit.Test;
diff --git a/tests/org.eclipse.emf.test.ecore.xcore/src/org/eclipse/emf/test/ecore/xcore/genmodel/XcoreGenModelTest.java b/tests/org.eclipse.emf.test.ecore.xcore/src/org/eclipse/emf/test/ecore/xcore/genmodel/XcoreGenModelTest.java
index 15d384d..25293d2 100644
--- a/tests/org.eclipse.emf.test.ecore.xcore/src/org/eclipse/emf/test/ecore/xcore/genmodel/XcoreGenModelTest.java
+++ b/tests/org.eclipse.emf.test.ecore.xcore/src/org/eclipse/emf/test/ecore/xcore/genmodel/XcoreGenModelTest.java
@@ -14,13 +14,13 @@ import org.eclipse.emf.ecore.xcore.XNamedElement;
import org.eclipse.emf.ecore.xcore.XcoreInjectorProvider;
import org.eclipse.emf.ecore.xcore.mappings.XcoreMapper;
import org.eclipse.emf.test.ecore.xcore.GenModelFormatter;
+import org.eclipse.emf.test.ecore.xcore.legacy_xpect_runner.InjectParameter;
+import org.eclipse.emf.test.ecore.xcore.legacy_xpect_runner.Offset;
+import org.eclipse.emf.test.ecore.xcore.legacy_xpect_runner.ParameterSyntax;
+import org.eclipse.emf.test.ecore.xcore.legacy_xpect_runner.ParameterizedXtextRunner;
+import org.eclipse.emf.test.ecore.xcore.legacy_xpect_runner.ResourceURIs;
+import org.eclipse.emf.test.ecore.xcore.legacy_xpect_runner.XpectString;
import org.eclipse.xtext.junit4.InjectWith;
-import org.eclipse.xtext.junit4.parameterized.InjectParameter;
-import org.eclipse.xtext.junit4.parameterized.Offset;
-import org.eclipse.xtext.junit4.parameterized.ParameterSyntax;
-import org.eclipse.xtext.junit4.parameterized.ParameterizedXtextRunner;
-import org.eclipse.xtext.junit4.parameterized.ResourceURIs;
-import org.eclipse.xtext.junit4.parameterized.XpectString;
import org.eclipse.xtext.junit4.validation.ValidationTestHelper;
import org.eclipse.xtext.resource.XtextResource;
import org.junit.Test;
diff --git a/tests/org.eclipse.emf.test.ecore.xcore/src/org/eclipse/emf/test/ecore/xcore/legacy_xpect_runner/ActualCollection.java b/tests/org.eclipse.emf.test.ecore.xcore/src/org/eclipse/emf/test/ecore/xcore/legacy_xpect_runner/ActualCollection.java
new file mode 100644
index 0000000..1a8dfe4
--- /dev/null
+++ b/tests/org.eclipse.emf.test.ecore.xcore/src/org/eclipse/emf/test/ecore/xcore/legacy_xpect_runner/ActualCollection.java
@@ -0,0 +1,47 @@
+package org.eclipse.emf.test.ecore.xcore.legacy_xpect_runner;
+
+import org.eclipse.emf.test.ecore.xcore.legacy_xpect_runner.ActualCollection.ActualItem;
+import org.eclipse.xtext.util.Exceptions;
+
+import com.google.common.base.Function;
+
+/**
+ * This class will be removed in the next release after 2.4.2
+ *
+ * @author Moritz Eysholdt - Initial contribution and API
+ */
+@Deprecated
+public class ActualCollection extends StringCollection<ActualItem> {
+
+ public static class ToString implements Function<Object, String> {
+ public String apply(Object from) {
+ return from == null ? "null" : from.toString();
+ }
+ }
+
+ public class ActualItem extends StringCollection<ActualItem>.Item {
+ public ActualItem(String pure) {
+ super(pure);
+ }
+ }
+
+ public void init(String... actual) {
+ items = createCollection();
+ for (String obj : actual)
+ items.add(new ActualItem(obj));
+ }
+
+ public void init(Iterable<Object> actual,
+ Class<? extends Function<Object, String>> functionClass) {
+ items = createCollection();
+ try {
+ Function<Object, String> func = functionClass.newInstance();
+ for (Object obj : actual)
+ items.add(new ActualItem(func.apply(obj)));
+ } catch (InstantiationException e) {
+ Exceptions.throwUncheckedException(e);
+ } catch (IllegalAccessException e) {
+ Exceptions.throwUncheckedException(e);
+ }
+ }
+}
diff --git a/tests/org.eclipse.emf.test.ecore.xcore/src/org/eclipse/emf/test/ecore/xcore/legacy_xpect_runner/ExpectationCollection.java b/tests/org.eclipse.emf.test.ecore.xcore/src/org/eclipse/emf/test/ecore/xcore/legacy_xpect_runner/ExpectationCollection.java
new file mode 100644
index 0000000..4e214da
--- /dev/null
+++ b/tests/org.eclipse.emf.test.ecore.xcore/src/org/eclipse/emf/test/ecore/xcore/legacy_xpect_runner/ExpectationCollection.java
@@ -0,0 +1,354 @@
+package org.eclipse.emf.test.ecore.xcore.legacy_xpect_runner;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.emf.test.ecore.xcore.legacy_xpect_runner.ActualCollection.ActualItem;
+import org.eclipse.emf.test.ecore.xcore.legacy_xpect_runner.ExpectationCollection.ExpectationItem;
+import org.eclipse.xtext.util.Pair;
+import org.eclipse.xtext.util.Tuples;
+
+import com.google.common.collect.HashMultiset;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Multiset;
+import com.google.common.collect.Sets;
+
+/**
+ * This class will be removed in the next release after 2.4.2
+ *
+ * @author Moritz Eysholdt - Initial contribution and API
+ */
+@Deprecated
+public class ExpectationCollection extends StringCollection<ExpectationItem> {
+ public class ExpectationItem extends StringCollection<ExpectationItem>.Item {
+ protected boolean negated;
+ protected boolean wildcard;
+
+ public ExpectationItem(String pure, boolean negated, boolean wildcard) {
+ super(pure);
+ this.negated = negated;
+ this.wildcard = wildcard;
+ }
+
+ public boolean isNegated() {
+ return negated;
+ }
+
+ public boolean isWildcard() {
+ return wildcard;
+ }
+
+ public boolean isPure() {
+ return !negated && !wildcard;
+ }
+
+ }
+
+ final protected static String WILDCARD = "...";
+
+ public boolean isPure() {
+ for (ExpectationItem i : this)
+ if (i.isNegated() || i.isWildcard())
+ return false;
+ return true;
+ }
+
+ public boolean matches(ActualCollection actual) {
+ if (!isOrdered() || !actual.isOrdered())
+ return matchesUnordered(actual);
+ else
+ return matchesOrdered(actual);
+ }
+
+ public List<Pair<Collection<ExpectationItem>, ActualItem>> map(
+ ActualCollection actual) {
+ if (!isOrdered() || !actual.isOrdered())
+ return mapUnordered(actual);
+ else
+ return mapOrdered(actual);
+ }
+
+ protected List<Pair<Collection<ExpectationItem>, ActualItem>> mapUnordered(
+ ActualCollection actual) {
+ Map<ExpectationItem, List<ExpectationItem>> remainingExpectations = Maps
+ .newHashMap();
+ Set<ExpectationItem> negatedExpectations = Sets.newLinkedHashSet();
+ List<ExpectationItem> wildcardExpectations = Lists.newArrayList();
+ for (ExpectationItem exp : this)
+ if (exp.isWildcard())
+ wildcardExpectations.add(exp);
+ else if (exp.isNegated())
+ negatedExpectations.add(exp);
+ else {
+ List<ExpectationItem> items = remainingExpectations.get(exp);
+ if (items == null)
+ remainingExpectations
+ .put(exp, items = Lists.newArrayList());
+ items.add(exp);
+ }
+ List<ActualItem> sortedActual = Lists.newArrayList(actual);
+ Collections.sort(sortedActual);
+ List<Pair<Collection<ExpectationItem>, ActualItem>> result = Lists
+ .newArrayList();
+ for (ActualItem act : sortedActual) {
+ List<ExpectationItem> exp = remainingExpectations.get(act);
+ if (exp != null && !exp.isEmpty()) {
+ ExpectationItem ei = exp.get(exp.size() - 1);
+ exp.remove(exp.size() - 1);
+ result.add(Tuples
+ .<Collection<ExpectationItem>, ActualItem> create(
+ Collections.singleton(ei), act));
+ } else if (!negatedExpectations.contains(act)) {
+ if (wildcardExpectations.isEmpty())
+ result.add(Tuples
+ .<Collection<ExpectationItem>, ActualItem> create(
+ negatedExpectations, act));
+ else
+ result.add(Tuples
+ .<Collection<ExpectationItem>, ActualItem> create(
+ wildcardExpectations, act));
+ } else
+ result.add(Tuples
+ .<Collection<ExpectationItem>, ActualItem> create(null,
+ act));
+ }
+ List<ExpectationItem> remainingExpectationsSorted = Lists
+ .newArrayList();
+ for (List<ExpectationItem> x : remainingExpectations.values())
+ remainingExpectationsSorted.addAll(x);
+ Collections.sort(remainingExpectationsSorted);
+ for (ExpectationItem ei : remainingExpectationsSorted)
+ if (ei.isPure())
+ result.add(Tuples
+ .<Collection<ExpectationItem>, ActualItem> create(
+ Collections.singleton(ei), null));
+ return result;
+ }
+
+ protected List<Pair<Collection<ExpectationItem>, ActualItem>> mapOrdered(
+ ActualCollection actual) {
+ List<Pair<Collection<ExpectationItem>, ActualItem>> r = Lists
+ .newArrayList();
+ List<ExpectationItem> exIt = Lists.newArrayList(this.iterator());
+ List<ActualItem> actIt = Lists.newArrayList(actual.iterator());
+ int exp = 0, act = 0;
+ while (exp < exIt.size() && act < actIt.size()) {
+ if (exIt.get(exp).isNegated() || exIt.get(exp).isWildcard()) {
+ Set<ExpectationItem> expectedNegated = Sets.newLinkedHashSet();
+ Set<ExpectationItem> expectedWildcard = Sets.newLinkedHashSet();
+ while (exp < exIt.size() && !exIt.get(exp).isPure()) {
+ if (exIt.get(exp).isNegated())
+ expectedNegated.add(exIt.get(exp));
+ else if (exIt.get(exp).isWildcard())
+ expectedWildcard.add(exIt.get(exp));
+ exp++;
+ }
+ while (act < actIt.size()) {
+ if (exp < exIt.size() && exIt.get(exp).isPure()
+ && exIt.get(exp).equals(actIt.get(act))) {
+ r.add(Tuples
+ .<Collection<ExpectationItem>, ActualItem> create(
+ Collections.singleton(exIt.get(exp)),
+ actIt.get(act)));
+ exp++;
+ act++;
+ break;
+ }
+ if (!expectedNegated.contains(actIt.get(act))) {
+ if (expectedWildcard.isEmpty())
+ r.add(Tuples
+ .<Collection<ExpectationItem>, ActualItem> create(
+ expectedNegated, actIt.get(act)));
+ else
+ r.add(Tuples
+ .<Collection<ExpectationItem>, ActualItem> create(
+ expectedWildcard, actIt.get(act)));
+ } else
+ r.add(Tuples
+ .<Collection<ExpectationItem>, ActualItem> create(
+ null, actIt.get(act)));
+ act++;
+ }
+ } else if (exIt.get(exp).equals(actIt.get(act))) {
+ r.add(Tuples.<Collection<ExpectationItem>, ActualItem> create(
+ Collections.singleton(exIt.get(exp)), actIt.get(act)));
+ exp++;
+ act++;
+ } else {
+ int lact = act + 1;
+ while (lact < actIt.size()
+ && !exIt.get(exp).equals(actIt.get(lact)))
+ lact++;
+ if (lact < actIt.size()) {
+ while (act < lact) {
+ r.add(Tuples
+ .<Collection<ExpectationItem>, ActualItem> create(
+ null, actIt.get(act)));
+ act++;
+ }
+ r.add(Tuples
+ .<Collection<ExpectationItem>, ActualItem> create(
+ Collections.singleton(exIt.get(exp)),
+ actIt.get(lact)));
+ exp++;
+ act++;
+ } else {
+ r.add(Tuples
+ .<Collection<ExpectationItem>, ActualItem> create(
+ Collections.singleton(exIt.get(exp)), null));
+ exp++;
+ }
+ }
+ }
+ while (act < actIt.size()) {
+ r.add(Tuples.<Collection<ExpectationItem>, ActualItem> create(null,
+ actIt.get(act)));
+ act++;
+ }
+ while (exp < exIt.size()) {
+ if (exIt.get(exp).isPure())
+ r.add(Tuples.<Collection<ExpectationItem>, ActualItem> create(
+ Collections.singleton(exIt.get(exp)), null));
+ exp++;
+ }
+ return r;
+ }
+
+ protected boolean matchesOrdered(ActualCollection actual) {
+ if (isPure())
+ return items.equals(actual.items);
+ Iterator<ExpectationItem> exIt = this.iterator();
+ Iterator<ActualItem> actIt = actual.iterator();
+ while (exIt.hasNext() && actIt.hasNext()) {
+ ExpectationItem exp = exIt.next();
+ ActualItem act = actIt.next();
+ if (exp.isNegated() || exp.isWildcard()) {
+ List<ExpectationItem> expectedNegated = Lists.newArrayList();
+ if (exp.isNegated())
+ expectedNegated.add(exp);
+ while (exIt.hasNext()) {
+ exp = exIt.next();
+ if (exp.isNegated())
+ expectedNegated.add(exp);
+ else if (exp.isPure())
+ break;
+ }
+ Set<ActualItem> actualSkipped = Sets.newHashSet();
+ if (exp.isPure()) {
+ if (!exp.equals(act)) {
+ actualSkipped.add(act);
+ while (actIt.hasNext()) {
+ act = actIt.next();
+ if (exp.equals(act))
+ break;
+ else
+ actualSkipped.add(act);
+ }
+ }
+ if (!exp.equals(act))
+ return false;
+ } else {
+ actualSkipped.add(act);
+ while (actIt.hasNext())
+ actualSkipped.add(actIt.next());
+ }
+ for (ExpectationItem e : expectedNegated)
+ if (actualSkipped.contains(e))
+ return false;
+ } else if (!exp.equals(act))
+ return false;
+ }
+ if (actIt.hasNext())
+ return false;
+ while (exIt.hasNext())
+ if (exIt.next().isPure())
+ return false;
+ return true;
+ }
+
+ protected boolean matchesUnordered(ActualCollection actual) {
+ if (isPure())
+ return items.equals(actual.items);
+ Multiset<ActualItem> act = HashMultiset.create(actual);
+ for (ExpectationItem item : this) {
+ if (item.isWildcard())
+ continue;
+ if (item.isNegated()) {
+ if (act.contains(item))
+ return false;
+ } else if (!act.contains(item))
+ return false;
+ }
+ return true;
+ }
+
+ public void init(String expectation) {
+ items = createCollection();
+ boolean esc = false, escaped = true, quote = false, quoted = false, neg = false;
+ StringBuilder item = new StringBuilder();
+ StringBuilder ws = new StringBuilder();
+ for (int i = 0; i < expectation.length(); i++) {
+ char c = expectation.charAt(i);
+ if (!esc) {
+ if (!quote) {
+ if (c == separator) {
+ if (item.length() > 0)
+ items.add(createItem(item.toString(), neg, quoted,
+ escaped));
+ neg = quoted = escaped = false;
+ item = new StringBuilder();
+ ws = new StringBuilder();
+ continue;
+ } else if (Character.isWhitespace(c)) {
+ ws.append(c);
+ continue;
+ } else if (c == '!' && item.length() == 0) {
+ neg = true;
+ continue;
+ }
+ }
+ if (this.quoted && c == this.quote) {
+ if (quote)
+ item.append(ws);
+ ws = new StringBuilder();
+ quote = !quote;
+ quoted = true;
+ continue;
+ } else if (c == '\\') {
+ escaped = esc = true;
+ continue;
+ }
+ } else {
+ esc = false;
+ switch (c) {
+ case 'n':
+ c = '\n';
+ break;
+ case 'r':
+ c = '\r';
+ break;
+ }
+ }
+ if (ws.length() > 0) {
+ if (item.length() > 0)
+ item.append(ws);
+ ws = new StringBuilder();
+ }
+ item.append(c);
+ }
+ if (item.length() > 0)
+ items.add(createItem(item.toString(), neg, quoted, escaped));
+ }
+
+ protected ExpectationItem createItem(String item, boolean negated,
+ boolean quoted, boolean escaped) {
+ if (!escaped && !negated && !quoted && WILDCARD.equals(item))
+ return new ExpectationItem(item.toString(), false, true);
+ return new ExpectationItem(item.toString(), negated, false);
+ }
+}
diff --git a/tests/org.eclipse.emf.test.ecore.xcore/src/org/eclipse/emf/test/ecore/xcore/legacy_xpect_runner/IParameterProvider.java b/tests/org.eclipse.emf.test.ecore.xcore/src/org/eclipse/emf/test/ecore/xcore/legacy_xpect_runner/IParameterProvider.java
new file mode 100644
index 0000000..929b313
--- /dev/null
+++ b/tests/org.eclipse.emf.test.ecore.xcore/src/org/eclipse/emf/test/ecore/xcore/legacy_xpect_runner/IParameterProvider.java
@@ -0,0 +1,61 @@
+package org.eclipse.emf.test.ecore.xcore.legacy_xpect_runner;
+
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.xtext.resource.XtextResource;
+import org.eclipse.xtext.util.Strings;
+
+import com.google.common.collect.Multimap;
+import com.google.inject.ImplementedBy;
+
+/**
+ * use org.xpect.parameter.IParameterProvider from www.xpect-tests.org instead.
+ *
+ * This class will be removed in the next release after 2.4.2
+ *
+ * @author Moritz Eysholdt - Initial contribution and API
+ */
+@Deprecated
+@ImplementedBy(XpectParameterProvider.class)
+public interface IParameterProvider {
+
+ public interface IExpectation {
+ public class Util {
+ public static String replace(XtextResource res, IExpectation exp,
+ String value) {
+ String indented;
+ if (!Strings.isEmpty(exp.getIndentation()))
+ indented = exp.getIndentation()
+ + value.replace("\n", "\n" + exp.getIndentation());
+ else
+ indented = value;
+ String document = res.getParseResult().getRootNode().getText();
+ String before = document.substring(0, exp.getOffset());
+ String after = document.substring(
+ exp.getOffset() + exp.getLength(), document.length());
+ return before + indented + after;
+ }
+ }
+
+ String getExpectation();
+
+ String getIndentation();
+
+ int getLength();
+
+ int getOffset();
+ }
+
+ public interface IParameterAcceptor {
+ void acceptImportURI(URI uri);
+
+ void acceptTest(String title, String method,
+ Multimap<String, Object> params, IExpectation expectation,
+ boolean ignore);
+
+ // void acceptTestClass(Class<?> clazz);
+ }
+
+ void collectParameters(Class<?> testClass, XtextResource resource,
+ IParameterAcceptor acceptor);
+
+}
diff --git a/tests/org.eclipse.emf.test.ecore.xcore/src/org/eclipse/emf/test/ecore/xcore/legacy_xpect_runner/InjectParameter.java b/tests/org.eclipse.emf.test.ecore.xcore/src/org/eclipse/emf/test/ecore/xcore/legacy_xpect_runner/InjectParameter.java
new file mode 100644
index 0000000..52a9203
--- /dev/null
+++ b/tests/org.eclipse.emf.test.ecore.xcore/src/org/eclipse/emf/test/ecore/xcore/legacy_xpect_runner/InjectParameter.java
@@ -0,0 +1,21 @@
+package org.eclipse.emf.test.ecore.xcore.legacy_xpect_runner;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * use www.xpect-tests.org insted. In Xpect, thre is no direct counterpart for
+ * this annotation since each kind of injected parameter has its own annotation.
+ *
+ * This class will be removed in the next release after 2.4.2
+ *
+ * @author Moritz Eysholdt - Initial contribution and API
+ */
+@Deprecated
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.FIELD)
+public @interface InjectParameter {
+ String value() default "";
+}
diff --git a/tests/org.eclipse.emf.test.ecore.xcore/src/org/eclipse/emf/test/ecore/xcore/legacy_xpect_runner/Offset.java b/tests/org.eclipse.emf.test.ecore.xcore/src/org/eclipse/emf/test/ecore/xcore/legacy_xpect_runner/Offset.java
new file mode 100644
index 0000000..abc92d4
--- /dev/null
+++ b/tests/org.eclipse.emf.test.ecore.xcore/src/org/eclipse/emf/test/ecore/xcore/legacy_xpect_runner/Offset.java
@@ -0,0 +1,138 @@
+package org.eclipse.emf.test.ecore.xcore.legacy_xpect_runner;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.xtext.Assignment;
+import org.eclipse.xtext.GrammarUtil;
+import org.eclipse.xtext.nodemodel.ILeafNode;
+import org.eclipse.xtext.nodemodel.INode;
+import org.eclipse.xtext.nodemodel.util.NodeModelUtils;
+import org.eclipse.xtext.parsetree.reconstr.impl.NodeIterator;
+import org.eclipse.xtext.resource.XtextResource;
+import org.eclipse.xtext.util.Pair;
+import org.eclipse.xtext.util.Tuples;
+import org.junit.Assert;
+
+import com.google.common.base.Predicate;
+import com.google.common.base.Predicates;
+
+/**
+ * use org.xpect.xtext.lib.setup.ThisOffset or
+ * org.xpect.parameter.ParameterParser with token rule OFFSET from
+ * www.xpect-tests.org instead. ThisOffset is an annotation that can be used for
+ * method parameters. ParameterParser is a an annotation to define syntax for
+ * test-parameters that can be specified in the DSL file (example: XPECT
+ * myTestMethod myparam1 myparam2). The method parameter type can be any of the
+ * following types int, INode, EObject, ICrossEReferenceAndEObject,
+ * IEAttributeAndEObject, IEReferenceAndEObject, IEStructuralFeatureAndEObject,
+ * etc.
+ *
+ * This class will be removed in the next release after 2.4.2
+ *
+ * @author Moritz Eysholdt - Initial contribution and API
+ */
+@Deprecated
+public class Offset {
+ protected int offset;
+ protected XtextResource resource;
+
+ public Offset(XtextResource resource, int offset) {
+ super();
+ this.resource = resource;
+ this.offset = offset;
+ }
+
+ public EObject getEObject() {
+ EObject object = NodeModelUtils
+ .findActualSemanticObjectFor(getLeafNodeAtOffset());
+ Assert.assertNotNull("No EObject found at offset " + offset, object);
+ return object;
+ }
+
+ public Pair<EObject, EStructuralFeature> getEStructuralFeatureByOffset() {
+ return getEStructuralFeatureByOffset(Predicates
+ .<EStructuralFeature> alwaysTrue());
+ }
+
+ public Pair<EObject, EStructuralFeature> getEStructuralFeatureByOffset(
+ Predicate<EStructuralFeature> matches) {
+ INode leaf = getLeafNodeAtOffset();
+ NodeIterator ni = null;
+ while (ni == null || ni.hasNext()) {
+ INode next = ni == null ? leaf : ni.next();
+ if (ni == null)
+ ni = new NodeIterator(leaf);
+ Assignment ass = GrammarUtil.containingAssignment(next
+ .getGrammarElement());
+ if (ass != null) {
+ EObject object = NodeModelUtils
+ .findActualSemanticObjectFor(next);
+ EStructuralFeature feat = object.eClass()
+ .getEStructuralFeature(ass.getFeature());
+ if (feat != null && matches.apply(feat))
+ return Tuples.create(object, feat);
+ }
+ }
+ Assert.fail("No EStructuralFeature found at offset " + offset);
+ return null;
+ }
+
+ public Pair<EObject, EStructuralFeature> getEStructuralFeatureByParent() {
+ INode leaf = getLeafNodeAtOffset();
+ EObject object = NodeModelUtils.findActualSemanticObjectFor(leaf);
+ Assert.assertNotNull("No EObject found at offset " + offset, object);
+ Assignment ass = GrammarUtil.containingAssignment(leaf
+ .getGrammarElement());
+ while (ass == null && leaf.getParent() != null) {
+ leaf = leaf.getParent();
+ ass = GrammarUtil.containingAssignment(leaf.getGrammarElement());
+ }
+ Assert.assertNotNull("No Assignment found at offset " + offset, ass);
+ EStructuralFeature feature = object.eClass().getEStructuralFeature(
+ ass.getFeature());
+ return Tuples.create(object, feature);
+ }
+
+ public ILeafNode getLeafNodeAtOffset() {
+ ILeafNode node = NodeModelUtils.findLeafNodeAtOffset(resource
+ .getParseResult().getRootNode(), offset);
+ Assert.assertNotNull("No Leaf Node found at offset " + offset, node);
+ return node;
+ }
+
+ @Override
+ public int hashCode() {
+ return offset * (resource != null ? resource.hashCode() : 1);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == null || obj.getClass() != getClass())
+ return false;
+ Offset off = (Offset) obj;
+ return resource == off.resource && offset == off.offset;
+ }
+
+ public int getOffset() {
+ return offset;
+ }
+
+ public XtextResource getResource() {
+ return resource;
+ }
+
+ @Override
+ public String toString() {
+ if (resource == null)
+ return "(resource is null)";
+ if (resource.getParseResult() == null
+ || resource.getParseResult().getRootNode() == null)
+ return "(resource hs no parse result)";
+ String text = resource.getParseResult().getRootNode().getText();
+ if (offset < 0 || offset > text.length())
+ return "(offset out of range)";
+ int from = Math.max(0, offset - 5);
+ int to = Math.min(text.length(), offset + 5);
+ return text.substring(from, offset) + "!" + text.substring(offset, to);
+ }
+}
diff --git a/tests/org.eclipse.emf.test.ecore.xcore/src/org/eclipse/emf/test/ecore/xcore/legacy_xpect_runner/ParameterSyntax.java b/tests/org.eclipse.emf.test.ecore.xcore/src/org/eclipse/emf/test/ecore/xcore/legacy_xpect_runner/ParameterSyntax.java
new file mode 100644
index 0000000..af3523a
--- /dev/null
+++ b/tests/org.eclipse.emf.test.ecore.xcore/src/org/eclipse/emf/test/ecore/xcore/legacy_xpect_runner/ParameterSyntax.java
@@ -0,0 +1,21 @@
+package org.eclipse.emf.test.ecore.xcore.legacy_xpect_runner;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * use org.xpect.parameter.ParameterParser from www.xpect-tests.org instead.
+ *
+ * This class will be removed in the next release after 2.4.2
+ *
+ * @author Moritz Eysholdt - Initial contribution and API
+ */
+@Deprecated
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.METHOD)
+public @interface ParameterSyntax {
+ String value() default "";
+
+}
diff --git a/tests/org.eclipse.emf.test.ecore.xcore/src/org/eclipse/emf/test/ecore/xcore/legacy_xpect_runner/ParameterizedXtextRunner.java b/tests/org.eclipse.emf.test.ecore.xcore/src/org/eclipse/emf/test/ecore/xcore/legacy_xpect_runner/ParameterizedXtextRunner.java
new file mode 100644
index 0000000..68d6827
--- /dev/null
+++ b/tests/org.eclipse.emf.test.ecore.xcore/src/org/eclipse/emf/test/ecore/xcore/legacy_xpect_runner/ParameterizedXtextRunner.java
@@ -0,0 +1,521 @@
+package org.eclipse.emf.test.ecore.xcore.legacy_xpect_runner;
+
+import static org.eclipse.xtext.util.Exceptions.throwUncheckedException;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.resource.ResourceSet;
+import org.eclipse.emf.test.ecore.xcore.legacy_xpect_runner.IParameterProvider.IExpectation;
+import org.eclipse.emf.test.ecore.xcore.legacy_xpect_runner.IParameterProvider.IParameterAcceptor;
+import org.eclipse.emf.test.ecore.xcore.legacy_xpect_runner.ParameterizedXtextRunner.ResourceRunner;
+import org.eclipse.emf.test.ecore.xcore.legacy_xpect_runner.TestExpectationValidator.ITestExpectationValidator;
+import org.eclipse.emf.test.ecore.xcore.legacy_xpect_runner.TestExpectationValidator.TestResult;
+import org.eclipse.xtext.junit4.IInjectorProvider;
+import org.eclipse.xtext.junit4.IRegistryConfigurator;
+import org.eclipse.xtext.junit4.InjectWith;
+import org.eclipse.xtext.resource.XtextResource;
+import org.eclipse.xtext.util.Exceptions;
+import org.eclipse.xtext.util.ReflectionUtil;
+import org.eclipse.xtext.util.Strings;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.Description;
+import org.junit.runner.manipulation.Filter;
+import org.junit.runner.manipulation.NoTestsRemainException;
+import org.junit.runner.notification.Failure;
+import org.junit.runner.notification.RunNotifier;
+import org.junit.runners.ParentRunner;
+import org.junit.runners.model.FrameworkMethod;
+import org.junit.runners.model.InitializationError;
+import org.junit.runners.model.TestClass;
+
+import com.google.common.base.Joiner;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Multimap;
+import com.google.common.collect.Sets;
+
+/**
+ * use org.xpect.runner.XpectRunner from www.xpect-tests.org instead.
+ *
+ * This class will be removed in the next release after 2.4.2
+ *
+ * @author Moritz Eysholdt - Initial contribution and API
+ */
+@Deprecated
+public class ParameterizedXtextRunner extends ParentRunner<ResourceRunner> {
+
+ protected static class MethodWithExpectation {
+ protected Method method;
+
+ protected ITestExpectationValidator<Object> validator;
+
+ public MethodWithExpectation(Method method) throws Throwable {
+ super();
+ this.method = method;
+ this.validator = findValidator();
+ }
+
+ protected ITestExpectationValidator<? extends Object> createValidator(
+ Test annotation) {
+ if (method.getReturnType() != void.class)
+ throw new RuntimeException(
+ "The method is expected to return void. Method: "
+ + method);
+ return new TestExpectationValidator.NullTestResultValidator(
+ annotation);
+ }
+
+ protected ITestExpectationValidator<? extends Object> createValidator(
+ TestExpectationValidator trv, Annotation annotation)
+ throws Throwable {
+ Class<? extends ITestExpectationValidator<?>> validatorClass = trv
+ .validator();
+ Class<?> expectedResultType = getExpectedResultType(validatorClass);
+ boolean voidExpected = expectedResultType == Void.TYPE
+ || expectedResultType == Void.class;
+ boolean returnsExpected = method.getReturnType() == Void.TYPE
+ || method.getReturnType() == Void.class;
+ if (!expectedResultType.isAssignableFrom(method.getReturnType())
+ && (!voidExpected || !returnsExpected))
+ throw new RuntimeException("The return type of " + method
+ + " is expected to be " + expectedResultType.getName());
+ Constructor<? extends ITestExpectationValidator<?>> c = validatorClass
+ .getConstructor(annotation.annotationType());
+ return c.newInstance(annotation);
+ }
+
+ @SuppressWarnings("unchecked")
+ protected ITestExpectationValidator<Object> findValidator()
+ throws Throwable {
+ for (Annotation an : method.getAnnotations())
+ if (an instanceof Test)
+ return (ITestExpectationValidator<Object>) createValidator((Test) an);
+ else {
+ TestExpectationValidator trv = an.annotationType()
+ .getAnnotation(TestExpectationValidator.class);
+ if (trv != null)
+ return (ITestExpectationValidator<Object>) createValidator(
+ trv, an);
+ }
+ Class<?>[] annotations = { Test.class, Xpect.class,
+ XpectString.class, XpectLines.class,
+ XpectCommaSeparatedValues.class };
+ List<String> names = Lists.newArrayList();
+ for (Class<?> o : annotations)
+ names.add("@" + o.getSimpleName());
+ throw new RuntimeException("Annotation missing: "
+ + Joiner.on(", ").join(names) + ", etc. in: " + method);
+ }
+
+ protected Class<?> getExpectedResultType(
+ Class<? extends ITestExpectationValidator<?>> clazz) {
+ for (Method meth : clazz.getMethods()) {
+ Annotation[][] annotations = meth.getParameterAnnotations();
+ for (int i = 0; i < annotations.length; i++)
+ for (Annotation an : annotations[i])
+ if (an instanceof TestResult)
+ return meth.getParameterTypes()[i];
+ }
+ throw new RuntimeException("One of the method parameters of "
+ + clazz.getName() + " must be annotated with @"
+ + TestResult.class.getSimpleName());
+ }
+
+ public Method getMethod() {
+ return method;
+ }
+
+ public ITestExpectationValidator<Object> getValidator() {
+ return validator;
+ }
+ }
+
+ protected static class ParameterSetRunner {
+ protected Description description;
+ protected IExpectation expectation;
+ protected boolean ignore;
+ protected int index = -1;
+ protected String methodName;
+ protected Multimap<String, Object> params;
+ protected ResourceRunner runner;
+ protected String title;
+
+ public Description getDescription() {
+ if (description == null)
+ description = Description.createTestDescription(
+ runner.clazz.getJavaClass(), getFullTitle());
+ return description;
+ }
+
+ public IExpectation getExpectation() {
+ return expectation;
+ }
+
+ public String getFullTitle() {
+ StringBuilder result = new StringBuilder();
+ result.append(methodName);
+ if (!Strings.isEmpty(title)) {
+ result.append(" ");
+ result.append(title);
+ }
+ if (index > -1) {
+ result.append("#");
+ result.append(index);
+ }
+ result.append(" - ");
+ result.append(runner.resource.getURI().lastSegment());
+ return result.toString();
+ }
+
+ public IInjectorProvider getInjectorProvider() {
+ return runner.injectorProvider;
+ }
+
+ public String getMethdoName() {
+ return methodName;
+ }
+
+ public Multimap<String, Object> getParams() {
+ return params;
+ }
+
+ public XtextResource getResource() {
+ return runner.resource;
+ }
+
+ public Class<?> getTestClass() {
+ return runner.clazz.getJavaClass();
+ }
+
+ public void init(ResourceRunner runner, String title, String method,
+ Multimap<String, Object> params, IExpectation expectation,
+ boolean ignore) {
+ this.runner = runner;
+ this.title = title;
+ this.methodName = method;
+ this.params = params;
+ this.expectation = expectation;
+ this.ignore = ignore;
+ }
+
+ public boolean isIgnore() {
+ return ignore;
+ }
+
+ }
+
+ protected static class ResourceRunner implements IParameterAcceptor {
+ protected TestClass clazz;
+ protected Description description;
+ protected IInjectorProvider injectorProvider;
+ protected List<ParameterSetRunner> parameterSets = Lists.newArrayList();
+ protected XtextResource resource;
+ protected ResourceSet resourceSet;
+
+ public void acceptImportURI(URI uri) {
+ resourceSet.getResource(uri, true);
+ }
+
+ public void acceptTest(String title, String method,
+ Multimap<String, Object> params, IExpectation expectation,
+ boolean ignore) {
+ ParameterSetRunner runner = injectorProvider.getInjector()
+ .getInstance(ParameterSetRunner.class);
+ runner.init(this, title, method, params, expectation, ignore);
+ parameterSets.add(runner);
+ }
+
+ protected void collectParameters() {
+ IParameterProvider parameterProvider = injectorProvider
+ .getInjector().getInstance(IParameterProvider.class);
+ parameterProvider.collectParameters(clazz.getJavaClass(), resource,
+ this);
+ }
+
+ public Description getDescription() {
+ if (description == null) {
+ description = Description.createSuiteDescription(resource
+ .getURI().lastSegment());
+ for (ParameterSetRunner child : parameterSets)
+ description.addChild(child.getDescription());
+ }
+ return description;
+ }
+
+ public List<ParameterSetRunner> getParameterSets() {
+ return parameterSets;
+ }
+
+ public void init(TestClass clazz, IInjectorProvider injector, URI uri) {
+ this.clazz = clazz;
+ this.injectorProvider = injector;
+ this.resourceSet = injectorProvider.getInjector().getInstance(
+ ResourceSet.class);
+ this.resource = (XtextResource) resourceSet.getResource(uri, true);
+ collectParameters();
+ setIndex();
+ }
+
+ protected void setIndex() {
+ Set<String> visited = Sets.newHashSet();
+ Set<String> duplicate = Sets.newHashSet();
+ for (ParameterSetRunner r : getParameterSets())
+ if (!visited.add(r.getFullTitle()))
+ duplicate.add(r.getFullTitle());
+ Map<String, Integer> counter = Maps.newHashMap();
+ for (ParameterSetRunner r : getParameterSets())
+ if (duplicate.contains(r.getFullTitle())) {
+ String title = r.getFullTitle();
+ Integer count = counter.get(title);
+ if (count == null)
+ count = 1;
+ else
+ count++;
+ counter.put(title, count);
+ r.index = count;
+ }
+ }
+
+ }
+
+ private static Map<Class<?>, IInjectorProvider> injectorProviderClassCache = Maps
+ .newHashMap();
+
+ protected List<ResourceRunner> children;
+
+ protected Filter filter = null;
+
+ protected Map<String, MethodWithExpectation> methods = Maps.newHashMap();
+
+ public ParameterizedXtextRunner(Class<?> testClass)
+ throws InitializationError {
+ super(testClass);
+ }
+
+ protected IInjectorProvider createInjectorProvider() {
+ IInjectorProvider injectorProvider = null;
+ InjectWith injectWith = getTestClass().getJavaClass().getAnnotation(
+ InjectWith.class);
+ if (injectWith != null) {
+ try {
+ injectorProvider = injectWith.value().newInstance();
+ } catch (Exception e) {
+ throwUncheckedException(e);
+ }
+ }
+ return injectorProvider;
+ }
+
+ @Override
+ protected Description describeChild(ResourceRunner child) {
+ return child.getDescription();
+ }
+
+ @Override
+ public void filter(Filter filter) throws NoTestsRemainException {
+ super.filter(filter);
+ this.filter = filter;
+ }
+
+ protected MethodWithExpectation findTestMethod(String name)
+ throws Throwable {
+ MethodWithExpectation result = methods.get(name);
+ if (result == null) {
+ Method method = getTestClass().getJavaClass().getMethod(name);
+ if (method == null)
+ throw new RuntimeException("Method " + name
+ + "() not found in " + getTestClass().getName());
+ result = new MethodWithExpectation(method);
+ methods.put(name, result);
+ }
+ return result;
+ }
+
+ @Override
+ protected List<ResourceRunner> getChildren() {
+ if (children == null) {
+ children = Lists.newArrayList();
+ IInjectorProvider injectorProvider = getOrCreateInjectorProvider();
+ for (URI uri : getURIs()) {
+ ResourceRunner child = injectorProvider.getInjector()
+ .getInstance(ResourceRunner.class);
+ child.init(getTestClass(), injectorProvider, uri);
+ children.add(child);
+ }
+ }
+ return children;
+ }
+
+ protected IInjectorProvider getInjectorProvider() {
+ return injectorProviderClassCache.get(getTestClass().getJavaClass());
+ }
+
+ protected IInjectorProvider getOrCreateInjectorProvider() {
+ IInjectorProvider injectorProvider = getInjectorProvider();
+ if (injectorProvider == null) {
+ injectorProvider = createInjectorProvider();
+ injectorProviderClassCache.put(getTestClass().getJavaClass(),
+ injectorProvider);
+ }
+ return injectorProvider;
+ }
+
+ protected List<URI> getURIs() {
+ ResourceURIs classAnnotation = getTestClass().getJavaClass()
+ .getAnnotation(ResourceURIs.class);
+ if (classAnnotation != null)
+ return getURIs(classAnnotation);
+ for (FrameworkMethod method : getTestClass().getAnnotatedMethods(
+ ResourceURIs.class)) {
+ int modifiers = method.getMethod().getModifiers();
+ if (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))
+ return getURIs(method);
+ }
+ throw new RuntimeException(
+ "The class "
+ + getTestClass().getJavaClass()
+ + " or one of its static public methods needs to be annotated with @"
+ + ResourceURIs.class.getSimpleName());
+ }
+
+ @SuppressWarnings("unchecked")
+ protected List<URI> getURIs(FrameworkMethod method) {
+ try {
+ return (List<URI>) method.invokeExplosively(null);
+ } catch (Throwable e) {
+ Exceptions.throwUncheckedException(e);
+ return Collections.emptyList();
+ }
+ }
+
+ protected List<URI> getURIs(ResourceURIs uris) {
+ List<URI> result = Lists.newArrayList();
+ ResourceURICollector collector = new ResourceURICollector();
+ if (uris.files().length > 0)
+ result.addAll(collector.collectFiles(uris.files()));
+ if (!Strings.isEmpty(uris.baseDir())
+ || uris.fileExtensions().length > 0) {
+ Assert.assertFalse("@ResourceURIs needs a baseURI",
+ Strings.isEmpty(uris.baseDir()));
+ Assert.assertTrue("@ResourceURIs needs at least one fileExtension",
+ uris.fileExtensions().length > 0);
+ result.addAll(collector.collectFiles(uris.baseDir(),
+ uris.fileExtensions()));
+ }
+ return result;
+ }
+
+ protected Object newTestInstance() throws SecurityException,
+ NoSuchMethodException, IllegalArgumentException,
+ InstantiationException, IllegalAccessException,
+ InvocationTargetException {
+ Constructor<?> constructor = getTestClass().getJavaClass()
+ .getConstructor();
+ return constructor.newInstance();
+ }
+
+ protected void injectParameters(Object test, Multimap<String, Object> params) {
+ List<Field> fields = Lists.newArrayList();
+ Class<?> clazz = test.getClass();
+ while (clazz != null && clazz != Object.class) {
+ fields.addAll(Lists.newArrayList(clazz.getDeclaredFields()));
+ clazz = clazz.getSuperclass();
+ }
+ for (Field field : fields) {
+ InjectParameter annotation = field
+ .getAnnotation(InjectParameter.class);
+ if (annotation != null) {
+ String name = Strings.isEmpty(annotation.value()) ? field
+ .getName() : annotation.value();
+ Class<?> fieldType = ReflectionUtil.getObjectType(field
+ .getType());
+ for (Object value : params.get(name))
+ if (fieldType.isInstance(value)) {
+ field.setAccessible(true);
+ try {
+ field.set(test, value);
+ } catch (IllegalArgumentException e) {
+ } catch (IllegalAccessException e) {
+ }
+ }
+ }
+ }
+
+ }
+
+ // protected Object newTestInstance(Object[][] allParams) throws
+ // IllegalArgumentException, InstantiationException,
+ // IllegalAccessException, InvocationTargetException {
+ // for (Object[] params : allParams)
+ // ROOT: for (Constructor<?> candidate :
+ // getTestClass().getJavaClass().getConstructors())
+ // if (candidate.getParameterTypes().length == params.length) {
+ // for (int i = 0; i < params.length; i++)
+ // if (params[i] != null
+ // && !ReflectionUtil.getObjectType(candidate.getParameterTypes()[i])
+ // .isInstance(params[i]))
+ // continue ROOT;
+ // return candidate.newInstance(params);
+ // }
+ // List<String> alternatives = Lists.newArrayList();
+ // for (Object[] params : allParams) {
+ // List<String> types = Lists.newArrayList();
+ // for (Object p : params)
+ // types.add(p == null ? "?" : p.getClass().getName());
+ // alternatives.add(Joiner.on(", ").join(types));
+ // }
+ // throw new RuntimeException("No valid constructor found in class " +
+ // getTestClass().getJavaClass().getName()
+ // + " for types " + Joiner.on(" or ").join(alternatives));
+ // }
+
+ protected void runChild(ParameterSetRunner ps) throws Throwable {
+ MethodWithExpectation method = findTestMethod(ps.getMethdoName());
+ Object test = newTestInstance();
+ if (ps.getInjectorProvider() instanceof IRegistryConfigurator)
+ ((IRegistryConfigurator) ps.getInjectorProvider()).setupRegistry();
+ try {
+ injectParameters(test, ps.getParams());
+ ps.getInjectorProvider().getInjector().injectMembers(test);
+ Object result = method.getMethod().invoke(test);
+ method.getValidator().validate(ps.getResource(),
+ ps.getExpectation(), result);
+ } catch (InvocationTargetException e) {
+ throw e.getCause();
+ } finally {
+ if (ps.getInjectorProvider() instanceof IRegistryConfigurator)
+ ((IRegistryConfigurator) ps.getInjectorProvider())
+ .restoreRegistry();
+ }
+ }
+
+ @Override
+ protected void runChild(ResourceRunner arg0, RunNotifier notifier) {
+ for (ParameterSetRunner ps : arg0.getParameterSets())
+ if (filter == null || filter.shouldRun(ps.getDescription())) {
+ notifier.fireTestStarted(ps.getDescription());
+ if (ps.isIgnore())
+ notifier.fireTestIgnored(ps.getDescription());
+ else
+ try {
+ runChild(ps);
+ } catch (Throwable e) {
+ notifier.fireTestFailure(new Failure(ps
+ .getDescription(), e));
+ }
+ notifier.fireTestFinished(ps.getDescription());
+ }
+ }
+
+}
diff --git a/tests/org.eclipse.emf.test.ecore.xcore/src/org/eclipse/emf/test/ecore/xcore/legacy_xpect_runner/ResourceURICollector.java b/tests/org.eclipse.emf.test.ecore.xcore/src/org/eclipse/emf/test/ecore/xcore/legacy_xpect_runner/ResourceURICollector.java
new file mode 100644
index 0000000..18af84d
--- /dev/null
+++ b/tests/org.eclipse.emf.test.ecore.xcore/src/org/eclipse/emf/test/ecore/xcore/legacy_xpect_runner/ResourceURICollector.java
@@ -0,0 +1,71 @@
+package org.eclipse.emf.test.ecore.xcore.legacy_xpect_runner;
+
+import java.io.File;
+import java.util.List;
+
+import org.eclipse.emf.common.util.URI;
+
+import com.google.common.base.Predicate;
+import com.google.common.collect.Lists;
+
+/**
+ * This class will be removed in the next release after 2.4.2
+ *
+ * @author Moritz Eysholdt - Initial contribution and API
+ */
+@Deprecated
+public class ResourceURICollector {
+ public static class FilePredicate implements Predicate<File> {
+ private final String[] fileExtensions;
+
+ public FilePredicate(String... fileExts) {
+ this.fileExtensions = fileExts;
+ }
+
+ public boolean apply(File input) {
+ for (String ext : fileExtensions)
+ if (input.getName().endsWith("." + ext))
+ return true;
+ return false;
+ }
+ }
+
+ protected void collectFiles(File dir, List<URI> result,
+ Predicate<File> shouldCollect) {
+ for (File child : dir.listFiles()) {
+ if (shouldCollect.apply(child))
+ result.add(createURI(child));
+ if (child.isDirectory())
+ collectFiles(child, result, shouldCollect);
+ }
+ }
+
+ public List<URI> collectFiles(String directory,
+ Predicate<File> shouldCollect) {
+ File dir = new File(directory);
+ if (!dir.isDirectory())
+ throw new RuntimeException("Directory not found: " + directory);
+ List<URI> result = Lists.newArrayList();
+ collectFiles(new File(directory), result, shouldCollect);
+ return result;
+ }
+
+ public List<URI> collectFiles(String directory, String... fileExtensions) {
+ return collectFiles(directory, new FilePredicate(fileExtensions));
+ }
+
+ public List<URI> collectFiles(String... files) {
+ List<URI> result = Lists.newArrayList();
+ for (String file : files) {
+ File f = new File(file);
+ if (!f.exists())
+ throw new RuntimeException("File not found: " + file);
+ result.add(createURI(f));
+ }
+ return result;
+ }
+
+ protected URI createURI(File file) {
+ return URI.createFileURI(file.getAbsolutePath());
+ }
+}
diff --git a/tests/org.eclipse.emf.test.ecore.xcore/src/org/eclipse/emf/test/ecore/xcore/legacy_xpect_runner/ResourceURIs.java b/tests/org.eclipse.emf.test.ecore.xcore/src/org/eclipse/emf/test/ecore/xcore/legacy_xpect_runner/ResourceURIs.java
new file mode 100644
index 0000000..90b5e13
--- /dev/null
+++ b/tests/org.eclipse.emf.test.ecore.xcore/src/org/eclipse/emf/test/ecore/xcore/legacy_xpect_runner/ResourceURIs.java
@@ -0,0 +1,26 @@
+package org.eclipse.emf.test.ecore.xcore.legacy_xpect_runner;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Use org.xpect.runner.XpectTestFiles from www.xpect-tests.org instead.
+ *
+ * This class will be removed in the next release after 2.4.2
+ *
+ * @author Moritz Eysholdt - Initial contribution and API
+ */
+@Deprecated
+@Inherited
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ ElementType.METHOD, ElementType.TYPE })
+public @interface ResourceURIs {
+ String baseDir() default "";
+
+ String[] fileExtensions() default {};
+
+ String[] files() default {};
+}
diff --git a/tests/org.eclipse.emf.test.ecore.xcore/src/org/eclipse/emf/test/ecore/xcore/legacy_xpect_runner/StringCollection.java b/tests/org.eclipse.emf.test.ecore.xcore/src/org/eclipse/emf/test/ecore/xcore/legacy_xpect_runner/StringCollection.java
new file mode 100644
index 0000000..18aba9c
--- /dev/null
+++ b/tests/org.eclipse.emf.test.ecore.xcore/src/org/eclipse/emf/test/ecore/xcore/legacy_xpect_runner/StringCollection.java
@@ -0,0 +1,166 @@
+package org.eclipse.emf.test.ecore.xcore.legacy_xpect_runner;
+
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.regex.Pattern;
+
+import com.google.common.collect.HashMultiset;
+import com.google.common.collect.Lists;
+
+/**
+ * This class will be removed in the next release after 2.4.2
+ *
+ * @author Moritz Eysholdt - Initial contribution and API
+ */
+@Deprecated
+public class StringCollection<T extends StringCollection<T>.Item> implements
+ Iterable<T> {
+ public class Item implements Comparable<Item> {
+ protected String escaped = null;
+ protected String normalized = null;
+ protected String pure;
+
+ public Item(String pure) {
+ super();
+ this.pure = pure;
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public boolean equals(Object obj) {
+ if (obj == null || !Item.class.isInstance(obj))
+ return false;
+ return getNormalized().equals(((Item) obj).getNormalized());
+ }
+
+ public String getEscaped() {
+ if (escaped == null)
+ escaped = escape(pure);
+ return escaped;
+ }
+
+ public String getNormalized() {
+ if (normalized == null)
+ normalized = normalize(pure);
+ return normalized;
+ }
+
+ public String getPure() {
+ return pure;
+ }
+
+ @Override
+ public int hashCode() {
+ return getNormalized().hashCode();
+ }
+
+ @Override
+ public String toString() {
+ return pure;
+ }
+
+ public int compareTo(Item o) {
+ if (normalized == null)
+ return -1;
+ if (o == null || o.normalized == null)
+ return 1;
+ return normalized.compareTo(o.normalized);
+ }
+
+ }
+
+ protected static final Pattern WS = Pattern.compile("\\s+",
+ Pattern.MULTILINE);
+ protected boolean caseSensitive = true;
+ protected Collection<T> items;
+ protected boolean ordered = true;
+ protected char quote = '\"';
+ protected boolean quoted = true;
+ protected char separator = ',';
+ protected boolean whitespaceSensitive = true;
+
+ protected Collection<T> createCollection() {
+ return ordered ? Lists.<T> newArrayList() : HashMultiset.<T> create();
+ }
+
+ protected String escape(String str) {
+ str = str.replace("\\", "\\\\").replace("\n", "\\n")
+ .replace("\r", "\\r");
+ if (quoted)
+ return quote + str.replace(String.valueOf(quote), "\\" + quote)
+ + quote;
+ if (str.startsWith("!") || str.equals("..."))
+ str = "\\" + str;
+ str = str.replace(String.valueOf(separator), "\\" + separator);
+ if (whitespaceSensitive)
+ return str;
+ return str.trim();
+ }
+
+ protected String escapeUnquoted(String str) {
+ return str.replaceAll("\\s+", " ");
+ }
+
+ public char getQuote() {
+ return quote;
+ }
+
+ public char getSeparator() {
+ return separator;
+ }
+
+ public boolean isCaseSensitive() {
+ return caseSensitive;
+ }
+
+ public boolean isOrdered() {
+ return ordered;
+ }
+
+ public boolean isQuoted() {
+ return quoted;
+ }
+
+ public boolean isWhitespaceSensitive() {
+ return whitespaceSensitive;
+ }
+
+ public Iterator<T> iterator() {
+ return items.iterator();
+ }
+
+ protected String normalize(String item) {
+ if (!quoted)
+ item = item.trim();
+ if (!whitespaceSensitive)
+ item = WS.matcher(item).replaceAll("");
+ if (!caseSensitive)
+ item = item.toLowerCase();
+ return item;
+ }
+
+ public void setCaseSensitive(boolean caseSensitive) {
+ this.caseSensitive = caseSensitive;
+ }
+
+ public void setOrdered(boolean ordered) {
+ this.ordered = ordered;
+ }
+
+ public void setQuote(char quote) {
+ this.quote = quote;
+ }
+
+ public void setQuoted(boolean quoted) {
+ this.quoted = quoted;
+ }
+
+ public void setSeparator(char separator) {
+ this.separator = separator;
+ }
+
+ public void setWhitespaceSensitive(boolean whitespaceSensitive) {
+ this.whitespaceSensitive = whitespaceSensitive;
+ }
+
+} \ No newline at end of file
diff --git a/tests/org.eclipse.emf.test.ecore.xcore/src/org/eclipse/emf/test/ecore/xcore/legacy_xpect_runner/TestExpectationValidator.java b/tests/org.eclipse.emf.test.ecore.xcore/src/org/eclipse/emf/test/ecore/xcore/legacy_xpect_runner/TestExpectationValidator.java
new file mode 100644
index 0000000..5cba6a5
--- /dev/null
+++ b/tests/org.eclipse.emf.test.ecore.xcore/src/org/eclipse/emf/test/ecore/xcore/legacy_xpect_runner/TestExpectationValidator.java
@@ -0,0 +1,52 @@
+package org.eclipse.emf.test.ecore.xcore.legacy_xpect_runner;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import org.eclipse.emf.test.ecore.xcore.legacy_xpect_runner.IParameterProvider.IExpectation;
+import org.eclipse.xtext.resource.XtextResource;
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * This class will be removed in the next release after 2.4.2
+ *
+ * @author Moritz Eysholdt - Initial contribution and API
+ */
+@Deprecated
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.ANNOTATION_TYPE)
+public @interface TestExpectationValidator {
+
+ public interface ITestExpectationValidator<RESULT> {
+
+ void validate(XtextResource resource, IExpectation expectation,
+ RESULT actual);
+ }
+
+ public class NullTestResultValidator implements
+ ITestExpectationValidator<Void> {
+ public NullTestResultValidator(Test config) {
+ }
+
+ public NullTestResultValidator(Xpect config) {
+ }
+
+ public void validate(XtextResource resource, IExpectation expectation,
+ @TestResult Void actual) {
+ if (expectation != null && expectation.getExpectation() != null
+ && expectation.getExpectation().length() > 0)
+ Assert.fail("This test should not have an expectation. Expectation: '"
+ + expectation + "'.");
+ }
+ }
+
+ @Retention(RetentionPolicy.RUNTIME)
+ @Target(ElementType.PARAMETER)
+ public @interface TestResult {
+ }
+
+ Class<? extends ITestExpectationValidator<?>> validator();
+} \ No newline at end of file
diff --git a/tests/org.eclipse.emf.test.ecore.xcore/src/org/eclipse/emf/test/ecore/xcore/legacy_xpect_runner/Xpect.java b/tests/org.eclipse.emf.test.ecore.xcore/src/org/eclipse/emf/test/ecore/xcore/legacy_xpect_runner/Xpect.java
new file mode 100644
index 0000000..bc85f50
--- /dev/null
+++ b/tests/org.eclipse.emf.test.ecore.xcore/src/org/eclipse/emf/test/ecore/xcore/legacy_xpect_runner/Xpect.java
@@ -0,0 +1,20 @@
+package org.eclipse.emf.test.ecore.xcore.legacy_xpect_runner;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * This class will be removed in the next release after 2.4.2
+ *
+ * use org.xpect.runner.Xpect from www.xpect-tests.org instead.
+ *
+ * @author Moritz Eysholdt - Initial contribution and API
+ */
+@Deprecated
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.METHOD)
+@TestExpectationValidator(validator = TestExpectationValidator.NullTestResultValidator.class)
+public @interface Xpect {
+}
diff --git a/tests/org.eclipse.emf.test.ecore.xcore/src/org/eclipse/emf/test/ecore/xcore/legacy_xpect_runner/XpectCommaSeparatedValues.java b/tests/org.eclipse.emf.test.ecore.xcore/src/org/eclipse/emf/test/ecore/xcore/legacy_xpect_runner/XpectCommaSeparatedValues.java
new file mode 100644
index 0000000..106fc40
--- /dev/null
+++ b/tests/org.eclipse.emf.test.ecore.xcore/src/org/eclipse/emf/test/ecore/xcore/legacy_xpect_runner/XpectCommaSeparatedValues.java
@@ -0,0 +1,158 @@
+package org.eclipse.emf.test.ecore.xcore.legacy_xpect_runner;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.util.Collection;
+
+import org.eclipse.emf.test.ecore.xcore.legacy_xpect_runner.ActualCollection.ActualItem;
+import org.eclipse.emf.test.ecore.xcore.legacy_xpect_runner.ActualCollection.ToString;
+import org.eclipse.emf.test.ecore.xcore.legacy_xpect_runner.ExpectationCollection.ExpectationItem;
+import org.eclipse.emf.test.ecore.xcore.legacy_xpect_runner.IParameterProvider.IExpectation;
+import org.eclipse.emf.test.ecore.xcore.legacy_xpect_runner.TestExpectationValidator.ITestExpectationValidator;
+import org.eclipse.emf.test.ecore.xcore.legacy_xpect_runner.TestExpectationValidator.TestResult;
+import org.eclipse.emf.test.ecore.xcore.legacy_xpect_runner.XpectCommaSeparatedValues.CSVResultValidator;
+import org.eclipse.xtext.resource.XtextResource;
+import org.eclipse.xtext.util.Pair;
+import org.junit.Assert;
+import org.junit.ComparisonFailure;
+
+import com.google.common.base.Function;
+
+/**
+ * use org.xpect.runner.Xpect from www.xpect-tests.org instead. In Xpect, test
+ * methods don't have return values anymore. Instead, the test expectation is
+ * passed in as method parameter. To handle a method with a CommaSeparatedValues
+ * expectation you can use a method declaration such as
+ *
+ * <code> @Xpect public void scope(@CommaSeparatedValuesExpectation ICommaSeparatedValuesExpectation expectation) { } </code>
+ *
+ * This class will be removed in the next release after 2.4.2
+ *
+ * @author Moritz Eysholdt - Initial contribution and API
+ */
+@Deprecated
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.METHOD)
+@TestExpectationValidator(validator = CSVResultValidator.class)
+public @interface XpectCommaSeparatedValues {
+
+ public class CSVResultValidator implements
+ ITestExpectationValidator<Iterable<Object>> {
+ protected XpectCommaSeparatedValues cfg;
+
+ public CSVResultValidator(XpectCommaSeparatedValues cfg) {
+ this.cfg = cfg;
+ }
+
+ protected String str(int length) {
+ StringBuilder b = new StringBuilder();
+ for (int i = 0; i < length; i++)
+ b.append(" ");
+ return b.toString();
+ }
+
+ public void validate(XtextResource res, IExpectation expectation,
+ @TestResult Iterable<Object> actual) {
+ Assert.assertNotNull(res);
+ Assert.assertNotNull(expectation);
+ Assert.assertNotNull(expectation.getExpectation());
+ Assert.assertNotNull(actual);
+
+ ExpectationCollection exp = new ExpectationCollection();
+ exp.setCaseSensitive(cfg.caseSensitive());
+ exp.setOrdered(cfg.ordered());
+ exp.setQuoted(cfg.quoted());
+ exp.setSeparator(',');
+ exp.setWhitespaceSensitive(cfg.whitespaceSensitive());
+ exp.init(expectation.getExpectation());
+
+ ActualCollection act = new ActualCollection();
+ act.setCaseSensitive(cfg.caseSensitive());
+ act.setOrdered(cfg.ordered());
+ act.setQuoted(cfg.quoted());
+ act.setSeparator(',');
+ act.setWhitespaceSensitive(cfg.whitespaceSensitive());
+ act.init(actual, cfg.itemFormatter());
+
+ if (!exp.matches(act)) {
+ StringBuilder expString = new StringBuilder();
+ StringBuilder actString = new StringBuilder();
+ boolean expWrap = false;
+ boolean expEmpty = false;
+ boolean actWrap = false;
+ int lineLength = 0, lineCount = 0;
+ for (Pair<Collection<ExpectationItem>, ActualItem> pair : exp
+ .map(act)) {
+ String expItem = null;
+ String actItem = null;
+ if (pair.getFirst() != null && !pair.getFirst().isEmpty()) {
+ if (pair.getSecond() != null)
+ expItem = pair.getSecond().getEscaped();
+ else
+ expItem = pair.getFirst().iterator().next()
+ .getEscaped();
+ } else {
+ if (pair.getSecond() != null)
+ expItem = str(pair.getSecond().getEscaped()
+ .length());
+ }
+ if (pair.getSecond() != null) {
+ actItem = pair.getSecond().getEscaped();
+ lineCount++;
+ lineLength += actItem.length() + 2;
+ boolean count = cfg.maxItemsPerLine() > 0
+ && lineCount > cfg.maxItemsPerLine();
+ boolean width = cfg.maxLineWidth() > 0
+ && lineLength > cfg.maxLineWidth();
+ if (count || width)
+ expWrap = actWrap = true;
+ }
+ if (expItem != null && expString.length() > 0) {
+ if (expWrap) {
+ expString.append(expEmpty ? "\n" : ",\n");
+ expWrap = false;
+ } else
+ expString.append(expEmpty ? " " : ", ");
+ }
+ if (actItem != null && actString.length() > 0) {
+ if (actWrap) {
+ actString.append(",\n");
+ actWrap = false;
+ lineCount = 0;
+ lineLength = 0;
+ } else
+ actString.append(", ");
+ }
+ if (expItem != null) {
+ expString.append(expItem);
+ expEmpty = expItem.trim().length() == 0;
+ }
+ if (actItem != null)
+ actString.append(actItem);
+ }
+ String expDoc = IExpectation.Util.replace(res, expectation,
+ expString.toString());
+ String actDoc = IExpectation.Util.replace(res, expectation,
+ actString.toString());
+ throw new ComparisonFailure("", expDoc, actDoc);
+ }
+ }
+ }
+
+ boolean caseSensitive() default true;
+
+ Class<? extends Function<Object, String>> itemFormatter() default ToString.class;
+
+ int maxItemsPerLine() default -1;
+
+ int maxLineWidth() default 80;
+
+ boolean ordered() default false;
+
+ boolean quoted() default false;
+
+ boolean whitespaceSensitive() default false;
+
+}
diff --git a/tests/org.eclipse.emf.test.ecore.xcore/src/org/eclipse/emf/test/ecore/xcore/legacy_xpect_runner/XpectLines.java b/tests/org.eclipse.emf.test.ecore.xcore/src/org/eclipse/emf/test/ecore/xcore/legacy_xpect_runner/XpectLines.java
new file mode 100644
index 0000000..fada91d
--- /dev/null
+++ b/tests/org.eclipse.emf.test.ecore.xcore/src/org/eclipse/emf/test/ecore/xcore/legacy_xpect_runner/XpectLines.java
@@ -0,0 +1,111 @@
+package org.eclipse.emf.test.ecore.xcore.legacy_xpect_runner;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.util.Collection;
+import java.util.List;
+
+import org.eclipse.emf.test.ecore.xcore.legacy_xpect_runner.ActualCollection.ActualItem;
+import org.eclipse.emf.test.ecore.xcore.legacy_xpect_runner.ActualCollection.ToString;
+import org.eclipse.emf.test.ecore.xcore.legacy_xpect_runner.ExpectationCollection.ExpectationItem;
+import org.eclipse.emf.test.ecore.xcore.legacy_xpect_runner.IParameterProvider.IExpectation;
+import org.eclipse.emf.test.ecore.xcore.legacy_xpect_runner.TestExpectationValidator.ITestExpectationValidator;
+import org.eclipse.emf.test.ecore.xcore.legacy_xpect_runner.TestExpectationValidator.TestResult;
+import org.eclipse.emf.test.ecore.xcore.legacy_xpect_runner.XpectLines.LinesResultValidator;
+import org.eclipse.xtext.resource.XtextResource;
+import org.eclipse.xtext.util.Pair;
+import org.junit.Assert;
+import org.junit.ComparisonFailure;
+
+import com.google.common.base.Function;
+import com.google.common.base.Joiner;
+import com.google.common.collect.Lists;
+
+/**
+ * use org.xpect.runner.Xpect from www.xpect-tests.org instead. In Xpect, test
+ * methods don't have return values anymore. Instead, the test expectation is
+ * passed in as method parameter. To handle a method with a Lines expectation
+ * you can use a method declaration such as
+ *
+ * <code>@Xpect public void exportedObjects(@LinesExpectation ILinesExpectation expectation) { }</code>
+ *
+ * This class will be removed in the next release after 2.4.2
+ *
+ * @author Moritz Eysholdt - Initial contribution and API
+ */
+@Deprecated
+@Target(ElementType.METHOD)
+@Retention(RetentionPolicy.RUNTIME)
+@TestExpectationValidator(validator = LinesResultValidator.class)
+public @interface XpectLines {
+
+ public class LinesResultValidator implements
+ ITestExpectationValidator<Iterable<Object>> {
+
+ protected XpectLines cfg;
+
+ public LinesResultValidator(XpectLines cfg) {
+ this.cfg = cfg;
+ }
+
+ public void validate(XtextResource res, IExpectation expectation,
+ @TestResult Iterable<Object> actual) {
+ Assert.assertNotNull(res);
+ Assert.assertNotNull(expectation);
+ Assert.assertNotNull(expectation.getExpectation());
+ Assert.assertNotNull(actual);
+
+ ExpectationCollection exp = new ExpectationCollection();
+ exp.setCaseSensitive(cfg.caseSensitive());
+ exp.setOrdered(cfg.ordered());
+ exp.setQuoted(cfg.quoted());
+ exp.setSeparator('\n');
+ exp.setWhitespaceSensitive(cfg.whitespaceSensitive());
+ exp.init(expectation.getExpectation());
+
+ ActualCollection act = new ActualCollection();
+ act.setCaseSensitive(cfg.caseSensitive());
+ act.setOrdered(cfg.ordered());
+ act.setQuoted(cfg.quoted());
+ act.setSeparator('\n');
+ act.setWhitespaceSensitive(cfg.whitespaceSensitive());
+ act.init(actual, cfg.itemFormatter());
+
+ if (!exp.matches(act)) {
+ List<String> expString = Lists.newArrayList();
+ List<String> actString = Lists.newArrayList();
+ for (Pair<Collection<ExpectationItem>, ActualItem> pair : exp
+ .map(act)) {
+ if (pair.getFirst() != null && !pair.getFirst().isEmpty()) {
+ if (pair.getSecond() != null)
+ expString.add(pair.getSecond().getEscaped());
+ else
+ expString.add(pair.getFirst().iterator().next()
+ .getEscaped());
+ }
+ if (pair.getSecond() != null)
+ actString.add(pair.getSecond().getEscaped());
+ }
+ String expDoc = IExpectation.Util.replace(res, expectation,
+ Joiner.on('\n').join(expString));
+ String actDoc = IExpectation.Util.replace(res, expectation,
+ Joiner.on('\n').join(actString));
+ throw new ComparisonFailure("", expDoc, actDoc);
+ }
+
+ }
+ }
+
+ boolean caseSensitive() default true;
+
+ boolean whitespaceSensitive() default false;
+
+ boolean quoted() default false;
+
+ Class<? extends Function<Object, String>> itemFormatter() default ToString.class;
+
+ boolean ordered() default false;
+
+}
diff --git a/tests/org.eclipse.emf.test.ecore.xcore/src/org/eclipse/emf/test/ecore/xcore/legacy_xpect_runner/XpectParameterProvider.java b/tests/org.eclipse.emf.test.ecore.xcore/src/org/eclipse/emf/test/ecore/xcore/legacy_xpect_runner/XpectParameterProvider.java
new file mode 100644
index 0000000..5cb385b
--- /dev/null
+++ b/tests/org.eclipse.emf.test.ecore.xcore/src/org/eclipse/emf/test/ecore/xcore/legacy_xpect_runner/XpectParameterProvider.java
@@ -0,0 +1,541 @@
+package org.eclipse.emf.test.ecore.xcore.legacy_xpect_runner;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.math.BigInteger;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Stack;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.xtext.nodemodel.ILeafNode;
+import org.eclipse.xtext.nodemodel.INode;
+import org.eclipse.xtext.parsetree.reconstr.impl.NodeIterator;
+import org.eclipse.xtext.resource.XtextResource;
+import org.eclipse.xtext.util.Exceptions;
+import org.eclipse.xtext.util.Pair;
+import org.eclipse.xtext.util.Strings;
+import org.eclipse.xtext.util.Wrapper;
+import org.eclipse.xtext.util.formallang.FollowerFunctionImpl;
+import org.eclipse.xtext.util.formallang.Nfa;
+import org.eclipse.xtext.util.formallang.NfaUtil;
+import org.eclipse.xtext.util.formallang.NfaUtil.BacktrackHandler;
+import org.eclipse.xtext.util.formallang.StringProduction;
+import org.eclipse.xtext.util.formallang.StringProduction.ElementType;
+import org.eclipse.xtext.util.formallang.StringProduction.ProdElement;
+import org.junit.Test;
+
+import com.google.common.collect.HashMultimap;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Multimap;
+
+/**
+ * This class will be removed in the next release after 2.4.2
+ *
+ * @author Moritz Eysholdt - Initial contribution and API
+ */
+@Deprecated
+@SuppressWarnings("restriction")
+public class XpectParameterProvider implements IParameterProvider {
+
+ protected static class AssignedProduction extends StringProduction {
+
+ public AssignedProduction(String production) {
+ super(production);
+ }
+
+ @Override
+ protected ProdElement parsePrim(Stack<Pair<Token, String>> tokens) {
+ Pair<Token, String> current = tokens.pop();
+ switch (current.getFirst()) {
+ case PL:
+ ProdElement result1 = parseAlt(tokens);
+ if (tokens.peek().getFirst().equals(Token.PR))
+ tokens.pop();
+ else
+ throw new RuntimeException("')' expected, but "
+ + tokens.peek().getFirst() + " found");
+ parseCardinality(tokens, result1);
+ return result1;
+ case STRING:
+ ProdElement result2 = createElement(ElementType.TOKEN);
+ result2.setValue(current.getSecond());
+ parseCardinality(tokens, result2);
+ return result2;
+ case ID:
+ ProdElement result3 = createElement(ElementType.TOKEN);
+ result3.setName(current.getSecond());
+ Pair<Token, String> eq = tokens.pop();
+ if (eq.getFirst() == Token.EQ) {
+ Pair<Token, String> val = tokens.pop();
+ switch (val.getFirst()) {
+ case ID:
+ case STRING:
+ result3.setValue(val.getSecond());
+ break;
+ default:
+ throw new RuntimeException("Unexpected token "
+ + current.getFirst());
+ }
+ } else
+ throw new RuntimeException("Unexpected token "
+ + eq.getFirst() + ", expected '='");
+ parseCardinality(tokens, result3);
+ return result3;
+ default:
+ throw new RuntimeException("Unexpected token "
+ + current.getFirst());
+ }
+ }
+ }
+
+ protected static class BacktrackItem {
+ protected int offset;
+ protected ProdElement token;
+ protected String value;
+
+ public BacktrackItem(int offset) {
+ super();
+ this.offset = offset;
+ }
+
+ public BacktrackItem(int offset, ProdElement token, String value) {
+ super();
+ this.offset = offset;
+ this.token = token;
+ this.value = value;
+ }
+
+ @Override
+ public String toString() {
+ return token + ":" + value;
+ }
+ }
+
+ protected static class Expectation implements IExpectation {
+ protected String expectation;
+ protected String indentation = null;
+ protected int lenght;
+ protected int offset;
+
+ public Expectation(int offset, int lenght, String expectation) {
+ super();
+ this.offset = offset;
+ this.lenght = lenght;
+ this.expectation = expectation;
+ }
+
+ public Expectation(int offset, int lenght, String expectation,
+ String indentation) {
+ super();
+ this.offset = offset;
+ this.lenght = lenght;
+ this.expectation = expectation;
+ this.indentation = indentation;
+ }
+
+ public String getExpectation() {
+ return expectation;
+ }
+
+ public String getIndentation() {
+ return indentation;
+ }
+
+ public int getLength() {
+ return lenght;
+ }
+
+ public int getOffset() {
+ return offset;
+ }
+
+ }
+
+ protected enum Token {
+ ID("[a-zA-Z][a-zA-Z0-9_]*"), //
+ INT("[0-9]+"), //
+ OFFSET("'([^']*)'|[^\\s]+"), //
+ STRING("'([^']*)'"), //
+ TEXT("[^\\s]+");
+
+ public final Pattern pattern;
+
+ private Token(String regex) {
+ this.pattern = Pattern.compile("^" + regex);
+ }
+ }
+
+ public final static String PARAM_OFFSET = "offset";
+ public final static String PARAM_RESOURCE = "resource";
+
+ protected static final Pattern WS = Pattern.compile("^[\\s]+");
+
+ protected static Pattern XPECT_PATTERN = Pattern
+ .compile("(\\S)?XPECT(_CLASS|_IMPORT)?\\s+([a-zA-Z0-9]*)");
+
+ public void collectParameters(Class<?> testClass, XtextResource resource,
+ IParameterAcceptor acceptor) {
+ collectTestMethods(testClass, resource, acceptor);
+ for (ILeafNode leaf : resource.getParseResult().getRootNode()
+ .getLeafNodes())
+ if (leaf.isHidden() && leaf.getText().contains("XPECT"))
+ parseLeaf(testClass, resource, leaf, acceptor);
+
+ }
+
+ protected void collectTestMethods(Class<?> testClass, XtextResource res,
+ IParameterAcceptor acceptor) {
+ for (Method meth : testClass.getMethods()) {
+ if (Modifier.isPublic(meth.getModifiers())
+ && !Modifier.isStatic(meth.getModifiers())) {
+ Test annotation = meth.getAnnotation(Test.class);
+ if (annotation != null)
+ acceptor.acceptTest(null, meth.getName(),
+ getDefaultParams(res, 0), null, false);
+ }
+ }
+ }
+
+ protected Iterable<Object> convertValue(XtextResource res, INode ctx,
+ int offset, Token token, String value) {
+ switch (token) {
+ case OFFSET:
+ int add = value.indexOf('|');
+ if (add >= 0)
+ value = value.substring(0, add) + value.substring(add + 1);
+ else
+ add = 0;
+ String text = ctx.getRootNode().getText();
+ int result = text.indexOf(value, offset);
+ if (result >= 0) {
+ int off = result + add;
+ return Lists.newArrayList(off, new Offset(res, off));
+ } else
+ throw new RuntimeException("OFFSET '" + value + "' not found");
+ case INT:
+ List<Object> r = Lists.newArrayList();
+ try {
+ r.add(Integer.valueOf(value));
+ } catch (NumberFormatException e) {
+ }
+ try {
+ r.add(new BigInteger(value));
+ } catch (NumberFormatException e) {
+ }
+ r.add(value);
+ return r;
+ case ID:
+ case STRING:
+ case TEXT:
+ return Collections.<Object> singleton(value);
+ }
+ return Collections.<Object> singleton(value);
+ }
+
+ protected Multimap<String, Object> getDefaultParams(XtextResource res,
+ int offset) {
+ Multimap<String, Object> result = HashMultimap.create();
+ result.put(PARAM_RESOURCE, res);
+ result.put(PARAM_OFFSET, offset);
+ result.put(PARAM_OFFSET, new Offset(res, offset));
+ return result;
+ }
+
+ protected String getIndentation(INode ctx, int offset) {
+ String text = ctx.getRootNode().getText();
+ int nl = text.lastIndexOf("\n", offset);
+ if (nl < 0)
+ nl = 0;
+ StringBuilder result = new StringBuilder();
+ for (int i = nl + 1; i < text.length()
+ && Character.isWhitespace(text.charAt(i)); i++)
+ result.append(text.charAt(i));
+ return result.toString();
+ }
+
+ protected int getOffsetOfNextSemanticNode(INode node) {
+ Iterator<INode> it = new NodeIterator(node);
+ while (it.hasNext()) {
+ INode n = it.next();
+ if (n instanceof ILeafNode && !((ILeafNode) n).isHidden())
+ return n.getOffset();
+ }
+ return node.getEndOffset();
+ }
+
+ protected Nfa<ProdElement> getParameterNfa(String syntax) {
+ AssignedProduction prod = new AssignedProduction(syntax);
+ FollowerFunctionImpl<ProdElement, String> ff = new FollowerFunctionImpl<ProdElement, String>(
+ prod);
+ ProdElement start = prod.new ProdElement(ElementType.TOKEN);
+ ProdElement stop = prod.new ProdElement(ElementType.TOKEN);
+ Nfa<ProdElement> result = new NfaUtil().create(prod, ff, start, stop);
+ return result;
+ }
+
+ protected String getParameterSyntax(Class<?> testClass, String methodName) {
+ try {
+ Method method = testClass.getMethod(methodName);
+ ParameterSyntax annotation = method
+ .getAnnotation(ParameterSyntax.class);
+ if (annotation != null)
+ return annotation.value();
+ } catch (SecurityException e) {
+ Exceptions.throwUncheckedException(e);
+ } catch (NoSuchMethodException e) {
+ Exceptions.throwUncheckedException(e);
+ }
+ return null;
+ }
+
+ protected void parseLeaf(Class<?> testClass, XtextResource resource,
+ ILeafNode leaf, IParameterAcceptor acceptor) {
+ String text = leaf.getText();
+ Matcher matcher = XPECT_PATTERN.matcher(text);
+ int offset = 0;
+ while (offset < text.length() && matcher.find(offset)) {
+ if (matcher.group(2) == null) {
+ int newOffset;
+ if ((newOffset = parseXpect(testClass, resource, leaf, text,
+ matcher.group(3), matcher.end(), acceptor,
+ matcher.group(1) != null)) >= 0)
+ offset = newOffset;
+ else
+ offset = matcher.end();
+ } else if ("_IMPORT".equals(matcher.group(2))) {
+ offset = parseXpectImport(resource, text, matcher.end(2),
+ acceptor);
+ }
+ // } else {
+ // int newOffset;
+ // if ((newOffset = parseXpectTest(testClass, text, matcher.end(),
+ // acceptor)) >= 0)
+ // offset = newOffset;
+ // else
+ // offset = matcher.end();
+ // }
+ }
+ }
+
+ protected int parseString(String text, int offset, Wrapper<String> value) {
+ if (offset < text.length() && text.charAt(offset) == '"') {
+ int i = offset + 1;
+ while (offset < text.length() && text.charAt(i - 1) == '\\'
+ || text.charAt(i) != '"')
+ i++;
+ if (text.charAt(i) == '"') {
+ value.set(text.substring(offset + 1, i - 1));
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ protected int parseStringOrText(String text, int offset,
+ Wrapper<String> value) {
+ int newOffset = parseString(text, offset, value);
+ if (newOffset < 0)
+ newOffset = parseText(text, offset, value);
+ return newOffset;
+ }
+
+ protected int parseText(String text, int offset, Wrapper<String> value) {
+ int i = offset;
+ while (i < text.length())
+ switch (text.charAt(i)) {
+ case ' ':
+ case '\t':
+ case '\r':
+ case '\n':
+ value.set(text.substring(offset, i));
+ return i;
+ default:
+ i++;
+ }
+ value.set(text.substring(offset, i));
+ return i;
+ }
+
+ protected int parseXpect(Class<?> testClass, XtextResource res, INode ctx,
+ String text, String method, int offset,
+ IParameterAcceptor acceptor, boolean ignore) {
+ int newOffset;
+ Multimap<String, Object> params = HashMultimap.create();
+ Wrapper<Expectation> expectation = new Wrapper<Expectation>(null);
+ offset = skipWhitespace(text, offset);
+ if ((newOffset = parseXpectParams(testClass, res, ctx, method, text,
+ offset, params)) >= 0)
+ offset = newOffset;
+ offset = skipWhitespace(text, offset);
+ if ((newOffset = parseXpectSLExpectation(ctx, text, offset, expectation)) >= 0)
+ offset = newOffset;
+ else if ((newOffset = parseXpectMLExpectation(ctx, text, offset,
+ expectation)) >= 0)
+ offset = newOffset;
+ acceptor.acceptTest(null, method, params, expectation.get(), ignore);
+ return offset;
+ }
+
+ protected int parseXpectImport(XtextResource res, String text, int offset,
+ IParameterAcceptor acceptor) {
+ offset = skipWhitespace(text, offset);
+ int end = text.indexOf("\n", offset);
+ String fileName = text.substring(offset, end).trim();
+ URI uri = URI.createURI(fileName);
+ if (uri.isRelative() && !res.getURI().isRelative())
+ uri = uri.resolve(res.getURI());
+ acceptor.acceptImportURI(uri);
+ return end;
+ }
+
+ protected int parseXpectMLExpectation(INode node, String text, int offset,
+ Wrapper<Expectation> expectation) {
+ if (offset + 3 < text.length()
+ && text.substring(offset, offset + 3).equals("---")) {
+ String indentation = getIndentation(node, node.getOffset() + offset);
+ int start = text.indexOf('\n', offset + 3);
+ int end = text.indexOf("---", offset + 3);
+ if (start >= 0 && end >= 0) {
+ String substring = text.substring(start + 1, end);
+ end = substring.lastIndexOf('\n');
+ if (end >= 0) {
+ String exp = substring.substring(0, end);
+ int len = exp.length();
+ if (exp.startsWith(indentation))
+ exp = exp.substring(indentation.length());
+ exp = exp.replace("\n" + indentation, "\n");
+ expectation.set(new Expectation(node.getOffset() + start
+ + 1, len, exp, indentation));
+ return end + start + 1;
+ }
+ }
+ }
+ return -1;
+ }
+
+ protected int parseXpectParams(Class<?> testClass, XtextResource res,
+ INode node, String methodName, final String text, int offset,
+ Multimap<String, Object> params) {
+ int semanticOffset = getOffsetOfNextSemanticNode(node);
+ params.putAll(getDefaultParams(res, semanticOffset));
+ String paramSyntax = getParameterSyntax(testClass, methodName);
+ if (Strings.isEmpty(paramSyntax))
+ return -1;
+ Nfa<ProdElement> nfa = getParameterNfa(paramSyntax);
+ List<BacktrackItem> trace = new NfaUtil().backtrack(nfa,
+ new BacktrackItem(offset),
+ new BacktrackHandler<ProdElement, BacktrackItem>() {
+ public BacktrackItem handle(ProdElement state,
+ BacktrackItem previous) {
+ if (Strings.isEmpty(state.getValue()))
+ return previous;
+ if (Strings.isEmpty(state.getName())) {
+ if (text.regionMatches(previous.offset, state
+ .getValue(), 0, state.getValue().length())) {
+ int newOffset = previous.offset
+ + state.getValue().length();
+ Matcher ws = WS.matcher(text).region(newOffset,
+ text.length());
+ int childOffset = ws.find() ? ws.end()
+ : newOffset;
+ return new BacktrackItem(childOffset, state,
+ state.getValue());
+ }
+ } else {
+ Token t = Token.valueOf(state.getValue());
+ Matcher matcher = t.pattern.matcher(text).region(
+ previous.offset, text.length());
+ if (matcher.find()) {
+ Matcher ws = WS.matcher(text).region(
+ matcher.end(), text.length());
+ int childOffset = ws.find() ? ws.end()
+ : matcher.end();
+ String value = matcher.groupCount() > 0
+ && matcher.group(1) != null ? matcher
+ .group(1) : matcher.group(0);
+ return new BacktrackItem(childOffset, state,
+ value);
+ }
+ }
+ return null;
+ }
+
+ public boolean isSolution(BacktrackItem result) {
+ return true;
+ }
+
+ public Iterable<ProdElement> sortFollowers(
+ BacktrackItem result,
+ Iterable<ProdElement> followers) {
+ return followers;
+ }
+ });
+ if (trace != null && !trace.isEmpty()) {
+ for (BacktrackItem item : trace)
+ if (item.token != null && item.token.getName() != null) {
+ String key = item.token.getName();
+ params.removeAll(key);
+ params.putAll(
+ key,
+ convertValue(res, node, semanticOffset,
+ Token.valueOf(item.token.getValue()),
+ item.value));
+ }
+ return trace.get(trace.size() - 1).offset;
+ }
+ return -1;
+ }
+
+ protected int parseXpectSLExpectation(INode node, String text, int offset,
+ Wrapper<Expectation> expectation) {
+ if (offset + 3 < text.length()
+ && text.substring(offset, offset + 3).equals("-->")) {
+ int begin = offset + 3;
+ if (text.charAt(begin) == '\r' || text.charAt(begin) == '\n') {
+ expectation
+ .set(new Expectation(node.getOffset() + begin, 0, ""));
+ return begin;
+ } else if (Character.isWhitespace(text.charAt(begin)))
+ begin++;
+ int end = text.indexOf('\n', begin);
+ if (end < 0)
+ end = text.length();
+ String exp = text.substring(begin, end);
+ expectation.set(new Expectation(node.getOffset() + begin, exp
+ .length(), exp));
+ return end;
+ }
+ return -1;
+ }
+
+ // protected int parseXpectTest(Wrapper<Class<?>> test, String text, int
+ // offset, IParameterAcceptor acceptor) {
+ // int index = text.indexOf("\n", offset);
+ // if (index > offset) {
+ // String name = text.substring(offset, index).trim();
+ // try {
+ // Class<?> clazz = Class.forName(name);
+ // acceptor.acceptTestClass(clazz);
+ // } catch (ClassNotFoundException e) {
+ // Exceptions.throwUncheckedException(e);
+ // }
+ // return index;
+ // }
+ // return -1;
+ // }
+
+ protected int skipWhitespace(String text, int offset) {
+ int i = offset;
+ while (i < text.length())
+ if (Character.isWhitespace(text.charAt(i)))
+ i++;
+ else
+ return i;
+ return i;
+ }
+
+}
diff --git a/tests/org.eclipse.emf.test.ecore.xcore/src/org/eclipse/emf/test/ecore/xcore/legacy_xpect_runner/XpectString.java b/tests/org.eclipse.emf.test.ecore.xcore/src/org/eclipse/emf/test/ecore/xcore/legacy_xpect_runner/XpectString.java
new file mode 100644
index 0000000..c3350a7
--- /dev/null
+++ b/tests/org.eclipse.emf.test.ecore.xcore/src/org/eclipse/emf/test/ecore/xcore/legacy_xpect_runner/XpectString.java
@@ -0,0 +1,73 @@
+package org.eclipse.emf.test.ecore.xcore.legacy_xpect_runner;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import org.eclipse.emf.test.ecore.xcore.legacy_xpect_runner.IParameterProvider.IExpectation;
+import org.eclipse.emf.test.ecore.xcore.legacy_xpect_runner.TestExpectationValidator.ITestExpectationValidator;
+import org.eclipse.emf.test.ecore.xcore.legacy_xpect_runner.TestExpectationValidator.TestResult;
+import org.eclipse.emf.test.ecore.xcore.legacy_xpect_runner.XpectString.StringResultValidator;
+import org.eclipse.xtext.resource.XtextResource;
+import org.eclipse.xtext.util.internal.FormattingMigrator;
+import org.junit.Assert;
+import org.junit.ComparisonFailure;
+
+/**
+ * use org.xpect.runner.Xpect from www.xpect-tests.org instead. In Xpect, test
+ * methods don't have return values anymore. Instead, the test expectation is
+ * passed in as method parameter. To handle a method with a String expectation
+ * you can use a method declaration such as
+ *
+ * <code>@Xpect public void linkedName(@StringExpectation IStringExpectation expectation) { }</code>
+ *
+ * This class will be removed in the next release after 2.4.2
+ *
+ * @author Moritz Eysholdt - Initial contribution and API
+ */
+@Deprecated
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.METHOD)
+@SuppressWarnings("restriction")
+@TestExpectationValidator(validator = StringResultValidator.class)
+public @interface XpectString {
+
+ public class StringResultValidator implements
+ ITestExpectationValidator<String> {
+
+ protected XpectString config;
+
+ public StringResultValidator(XpectString config) {
+ this.config = config;
+ }
+
+ public void validate(XtextResource resource, IExpectation expectation,
+ @TestResult String actual) {
+ Assert.assertNotNull(resource);
+ Assert.assertNotNull(expectation);
+ Assert.assertNotNull(expectation.getExpectation());
+ Assert.assertNotNull(actual);
+ String exp;
+ if (!config.whitespaceSensitive()) {
+ FormattingMigrator migrator = new FormattingMigrator();
+ exp = migrator.migrate(actual, expectation.getExpectation());
+ } else
+ exp = expectation.getExpectation();
+
+ if ((config.caseSensitive() && !exp.equals(actual))
+ || (!config.caseSensitive() && !exp
+ .equalsIgnoreCase(actual))) {
+ String expDoc = IExpectation.Util.replace(resource,
+ expectation, exp);
+ String actDoc = IExpectation.Util.replace(resource,
+ expectation, actual);
+ throw new ComparisonFailure("", expDoc, actDoc);
+ }
+ }
+ }
+
+ boolean caseSensitive() default true;
+
+ boolean whitespaceSensitive() default false;
+}
diff --git a/tests/org.eclipse.emf.test.ecore.xcore/src/org/eclipse/emf/test/ecore/xcore/scoping/XcoreScopingTest.java b/tests/org.eclipse.emf.test.ecore.xcore/src/org/eclipse/emf/test/ecore/xcore/scoping/XcoreScopingTest.java
index 8e5c2c7..b2b88e7 100644
--- a/tests/org.eclipse.emf.test.ecore.xcore/src/org/eclipse/emf/test/ecore/xcore/scoping/XcoreScopingTest.java
+++ b/tests/org.eclipse.emf.test.ecore.xcore/src/org/eclipse/emf/test/ecore/xcore/scoping/XcoreScopingTest.java
@@ -14,13 +14,13 @@ import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.xcore.XcoreInjectorProvider;
+import org.eclipse.emf.test.ecore.xcore.legacy_xpect_runner.InjectParameter;
+import org.eclipse.emf.test.ecore.xcore.legacy_xpect_runner.Offset;
+import org.eclipse.emf.test.ecore.xcore.legacy_xpect_runner.ParameterSyntax;
+import org.eclipse.emf.test.ecore.xcore.legacy_xpect_runner.ParameterizedXtextRunner;
+import org.eclipse.emf.test.ecore.xcore.legacy_xpect_runner.ResourceURIs;
+import org.eclipse.emf.test.ecore.xcore.legacy_xpect_runner.XpectCommaSeparatedValues;
import org.eclipse.xtext.junit4.InjectWith;
-import org.eclipse.xtext.junit4.parameterized.InjectParameter;
-import org.eclipse.xtext.junit4.parameterized.Offset;
-import org.eclipse.xtext.junit4.parameterized.ParameterSyntax;
-import org.eclipse.xtext.junit4.parameterized.ParameterizedXtextRunner;
-import org.eclipse.xtext.junit4.parameterized.ResourceURIs;
-import org.eclipse.xtext.junit4.parameterized.XpectCommaSeparatedValues;
import org.eclipse.xtext.junit4.validation.ValidationTestHelper;
import org.eclipse.xtext.resource.IEObjectDescription;
import org.eclipse.xtext.resource.XtextResource;
diff --git a/tests/org.eclipse.emf.test.ecore.xcore/src/org/eclipse/emf/test/ecore/xcore/validation/XcoreParameterizedTestRunner.java b/tests/org.eclipse.emf.test.ecore.xcore/src/org/eclipse/emf/test/ecore/xcore/validation/XcoreParameterizedTestRunner.java
index 0ca0512..707a687 100644
--- a/tests/org.eclipse.emf.test.ecore.xcore/src/org/eclipse/emf/test/ecore/xcore/validation/XcoreParameterizedTestRunner.java
+++ b/tests/org.eclipse.emf.test.ecore.xcore/src/org/eclipse/emf/test/ecore/xcore/validation/XcoreParameterizedTestRunner.java
@@ -12,8 +12,8 @@ import java.util.List;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.resource.ResourceSet;
+import org.eclipse.emf.test.ecore.xcore.legacy_xpect_runner.ParameterizedXtextRunner;
import org.eclipse.xtext.junit4.IInjectorProvider;
-import org.eclipse.xtext.junit4.parameterized.ParameterizedXtextRunner;
import org.eclipse.xtext.resource.XtextResource;
import org.eclipse.xtext.resource.XtextResourceFactory;
import org.junit.runners.model.InitializationError;
@@ -23,7 +23,6 @@ import com.google.common.collect.Lists;
import com.google.inject.Injector;
-@SuppressWarnings("restriction")
public class XcoreParameterizedTestRunner extends ParameterizedXtextRunner
{
diff --git a/tests/org.eclipse.emf.test.ecore.xcore/src/org/eclipse/emf/test/ecore/xcore/validation/XcoreValidationTest.java b/tests/org.eclipse.emf.test.ecore.xcore/src/org/eclipse/emf/test/ecore/xcore/validation/XcoreValidationTest.java
index 88672fd..4ef1c0b 100644
--- a/tests/org.eclipse.emf.test.ecore.xcore/src/org/eclipse/emf/test/ecore/xcore/validation/XcoreValidationTest.java
+++ b/tests/org.eclipse.emf.test.ecore.xcore/src/org/eclipse/emf/test/ecore/xcore/validation/XcoreValidationTest.java
@@ -12,10 +12,10 @@ import java.util.List;
import org.eclipse.emf.ecore.util.EcoreValidator;
import org.eclipse.emf.ecore.xcore.XcoreInjectorProvider;
+import org.eclipse.emf.test.ecore.xcore.legacy_xpect_runner.InjectParameter;
+import org.eclipse.emf.test.ecore.xcore.legacy_xpect_runner.ResourceURIs;
+import org.eclipse.emf.test.ecore.xcore.legacy_xpect_runner.XpectLines;
import org.eclipse.xtext.junit4.InjectWith;
-import org.eclipse.xtext.junit4.parameterized.InjectParameter;
-import org.eclipse.xtext.junit4.parameterized.ResourceURIs;
-import org.eclipse.xtext.junit4.parameterized.XpectLines;
import org.eclipse.xtext.resource.XtextResource;
import org.eclipse.xtext.util.CancelIndicator;
import org.eclipse.xtext.validation.CheckMode;