[junit4] improved ParameterizedXtextRunner

This commit is contained in:
Moritz Eysholdt 2011-10-26 05:47:41 +02:00
parent d0f13a42ae
commit c3f2de2167
33 changed files with 2815 additions and 783 deletions

View file

@ -6,7 +6,7 @@ Bundle-Version: 2.1.0.qualifier
Bundle-Vendor: Eclipse Modeling Project
Bundle-RequiredExecutionEnvironment: J2SE-1.5
Export-Package: org.eclipse.xtext.junit4,
org.eclipse.xtext.junit4.parameterized;x-internal:=true,
org.eclipse.xtext.junit4.parameterized;x-friends:="org.eclipse.xtext.junit4.tests",
org.eclipse.xtext.junit4.serializer,
org.eclipse.xtext.junit4.smoketest,
org.eclipse.xtext.junit4.util,

View file

@ -1,186 +0,0 @@
package org.eclipse.xtext.junit4.parameterized;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.regex.Pattern;
import org.eclipse.xtext.junit4.parameterized.TestExpectationValidator.ITestExpectationValidator;
import org.eclipse.xtext.util.Exceptions;
import com.google.common.base.Function;
import com.google.common.collect.HashMultiset;
import com.google.common.collect.LinkedHashMultiset;
import com.google.common.collect.Lists;
import com.google.common.collect.Multiset;
public abstract class AbstractIterableExpectationValidator implements ITestExpectationValidator<Iterable<Object>> {
protected class Item {
protected String escaped;
protected String normalized;
public Item(String normalized, String escaped) {
super();
this.normalized = normalized;
this.escaped = escaped;
}
@Override
public boolean equals(Object obj) {
return normalized.equals(obj);
}
@Override
public int hashCode() {
return normalized.hashCode();
}
@Override
public String toString() {
return normalized;
}
}
public static class ToString implements Function<Object, String> {
public String apply(Object from) {
return from == null ? "null" : from.toString();
}
}
protected static final Pattern WS = Pattern.compile("\\s*", Pattern.MULTILINE);
protected boolean caseSensitive;
protected boolean ordered;
protected boolean whitespaceSensitive;
public AbstractIterableExpectationValidator(boolean caseSensitive, boolean whitespaceSensitive) {
super();
this.caseSensitive = caseSensitive;
this.whitespaceSensitive = whitespaceSensitive;
}
protected Item createItem(String normalized, String escaped) {
return new Item(normalized, escaped);
}
protected List<Item> escape(List<String> items) {
List<Item> result = Lists.newArrayList();
for (String item : items)
result.add(createItem(normalize(item), escape(item)));
return result;
}
protected String escape(String str) {
if (whitespaceSensitive)
return escapeQuoted(str);
return escapeUnquoted(str);
}
protected String escapeQuoted(String str) {
return '"' + str.replaceAll("\\\"", "\\\\\"").replaceAll("\\\\", "\\\\").replaceAll("\\n", "\\\\n")
.replaceAll("\\r", "\\\\r") + '"';
}
protected String escapeUnquoted(String str) {
return str.replaceAll("\\s+", " ");
}
protected Collection<String> normalize(List<String> items) {
Collection<String> result = ordered ? Lists.<String> newArrayList() : HashMultiset.<String> create();
for (String item : items)
result.add(normalize(item));
return result;
}
protected String normalize(String item) {
if (!caseSensitive)
item = item.trim();
if (!whitespaceSensitive)
item = WS.matcher(item).replaceAll("").toLowerCase();
return item;
}
protected List<Item> sort(List<Item> ordered, List<Item> items) {
List<Item> result = Lists.newArrayList();
Multiset<Item> unsorted = LinkedHashMultiset.create(items);
for (Item i : ordered) {
if (unsorted.contains(i)) {
result.add(createItem(i.normalized, i.escaped));
unsorted.remove(i);
}
}
for (Item i : unsorted)
result.add(createItem(i.normalized, i.escaped));
return result;
}
protected List<String> toStringList(Iterable<Object> actual, Class<? extends Function<Object, String>> functionClass) {
List<String> result = Lists.newArrayList();
try {
Function<Object, String> func = functionClass.newInstance();
for (Object obj : actual)
result.add(func.apply(obj));
return result;
} catch (InstantiationException e) {
Exceptions.throwUncheckedException(e);
} catch (IllegalAccessException e) {
Exceptions.throwUncheckedException(e);
}
return Collections.emptyList();
}
protected List<String> toStringList(String items, char separator) {
List<String> result = Lists.newArrayList();
boolean esc = false, quoted = false;
StringBuilder item = new StringBuilder();
StringBuilder ws = new StringBuilder();
for (int i = 0; i < items.length(); i++) {
char c = items.charAt(i);
if (!esc) {
if (!quoted) {
if (c == separator) {
result.add(item.toString());
item = new StringBuilder();
ws = new StringBuilder();
continue;
} else if (Character.isWhitespace(c)) {
ws.append(c);
continue;
}
}
if (whitespaceSensitive && c == '"') {
if (quoted)
item.append(ws);
ws = new StringBuilder();
quoted = !quoted;
continue;
} else if (c == '\\') {
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);
else
ws = new StringBuilder();
}
item.append(c);
}
if (item.length() > 0)
result.add(item.toString());
return result;
}
}

View file

@ -1,175 +0,0 @@
/*******************************************************************************
* Copyright (c) 2011 itemis AG (http://www.itemis.eu) and others.
* 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
*******************************************************************************/
package org.eclipse.xtext.junit4.parameterized;
import static org.junit.Assert.*;
import java.util.List;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.xtext.AbstractElement;
import org.eclipse.xtext.Assignment;
import org.eclipse.xtext.GrammarUtil;
import org.eclipse.xtext.diagnostics.Severity;
import org.eclipse.xtext.junit4.serializer.SerializerTester;
import org.eclipse.xtext.junit4.validation.ValidationTestHelper;
import org.eclipse.xtext.nodemodel.ILeafNode;
import org.eclipse.xtext.nodemodel.INode;
import org.eclipse.xtext.nodemodel.util.NodeModelUtils;
import org.eclipse.xtext.resource.IEObjectDescription;
import org.eclipse.xtext.resource.XtextResource;
import org.eclipse.xtext.scoping.IScope;
import org.eclipse.xtext.scoping.IScopeProvider;
import org.eclipse.xtext.util.CancelIndicator;
import org.eclipse.xtext.util.Pair;
import org.eclipse.xtext.util.Tuples;
import org.eclipse.xtext.validation.CheckMode;
import org.eclipse.xtext.validation.IResourceValidator;
import org.eclipse.xtext.validation.Issue;
import org.junit.Test;
import org.junit.runner.RunWith;
import com.google.common.collect.Lists;
import com.google.inject.Inject;
/**
* @author Moritz Eysholdt - Initial contribution and API
*/
@RunWith(ParameterizedXtextRunner.class)
public class AbstractParameterizedXtextTest {
protected final static int LINE_WIDTH = 80;
protected int offset;
protected XtextResource resource;
@Inject
protected IScopeProvider scopeProvider;
@Inject
protected SerializerTester serializerTester;
@Inject
protected ValidationTestHelper validationHelper;
public AbstractParameterizedXtextTest(XtextResource resource, int offset, String[] params) {
super();
this.resource = resource;
this.offset = offset;
}
protected String formatIssue(Issue issue) {
StringBuilder result = new StringBuilder();
result.append(issue.getSeverity().name().toLowerCase());
if (issue.getOffset() != null && issue.getLength() != null) {
result.append(" at '");
result.append(resource.getParseResult().getRootNode().getText()
.substring(issue.getOffset(), issue.getOffset() + issue.getLength()));
result.append("' ");
} else
result.append(" ");
result.append("message '");
result.append(issue.getMessage());
result.append("'");
return result.toString();
}
protected EObject getEObjectAtOffset() {
EObject object = NodeModelUtils.findActualSemanticObjectFor(getLeafNodeAtOffset());
assertNotNull("No EObject found at offset " + offset, object);
return object;
}
protected Pair<EObject, EStructuralFeature> getEStructuralFeatureAtOffset() {
INode leaf = getLeafNodeAtOffset();
assertTrue(leaf.getGrammarElement() instanceof AbstractElement);
EObject object = NodeModelUtils.findActualSemanticObjectFor(leaf);
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());
}
assertNotNull("No Assignment found at offset " + offset, ass);
@SuppressWarnings("null")
EStructuralFeature feature = object.eClass().getEStructuralFeature(ass.getFeature());
return Tuples.create(object, feature);
}
protected ILeafNode getLeafNodeAtOffset() {
ILeafNode node = NodeModelUtils.findLeafNodeAtOffset(resource.getParseResult().getRootNode(), offset);
assertNotNull("No Leaf Node found at offset " + offset, node);
return node;
}
@Test
public void noValidationErrors() {
validationHelper.assertNoErrors(resource.getContents().get(0));
}
@Test
public void noValidationIssues() {
validationHelper.assertNoErrors(resource.getContents().get(0));
}
@TestAsCommaSeparatedValues()
public List<String> scopeAllElements() {
Pair<EObject, EStructuralFeature> objAndFeature = getEStructuralFeatureAtOffset();
assertTrue(objAndFeature.getSecond() instanceof EReference);
assertFalse(((EReference) objAndFeature.getSecond()).isContainment());
IScope scope = scopeProvider.getScope(objAndFeature.getFirst(), (EReference) objAndFeature.getSecond());
List<String> result = Lists.newArrayList();
for (IEObjectDescription desc : scope.getAllElements())
result.add(desc.getName().toString());
return result;
}
@Test
public void serializeable() throws Exception {
EObject obj = getEObjectAtOffset();
serializerTester.assertSerializeWithNodeModel(obj);
serializerTester.assertSerializeWithoutNodeModel(obj);
}
@Test
public void serializeableWithNodeModel() throws Exception {
serializerTester.assertSerializeWithNodeModel(getEObjectAtOffset());
}
@Test
public void serializeableWithoutNodeModel() throws Exception {
serializerTester.assertSerializeWithoutNodeModel(getEObjectAtOffset());
}
protected List<Issue> validateResource() {
IResourceValidator validator = resource.getResourceServiceProvider().get(IResourceValidator.class);
List<Issue> issues = validator.validate(resource, CheckMode.ALL, CancelIndicator.NullImpl);
return issues;
}
@TestAsLines()
public List<String> validationErrors() {
List<String> result = Lists.newArrayList();
for (Issue issue : validateResource())
if (issue.getSeverity() == Severity.ERROR)
result.add(formatIssue(issue));
return result;
}
@TestAsLines()
public List<String> validationIssues() {
List<String> result = Lists.newArrayList();
for (Issue issue : validateResource())
result.add(formatIssue(issue));
return result;
}
}

View file

@ -0,0 +1,50 @@
/*******************************************************************************
* Copyright (c) 2011 itemis AG (http://www.itemis.eu) and others.
* 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
*******************************************************************************/
package org.eclipse.xtext.junit4.parameterized;
import org.eclipse.xtext.junit4.parameterized.ActualCollection.ActualItem;
import org.eclipse.xtext.util.Exceptions;
import com.google.common.base.Function;
/**
* @author Moritz Eysholdt - Initial contribution and API
*/
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);
}
}
}

View file

@ -0,0 +1,324 @@
/*******************************************************************************
* Copyright (c) 2011 itemis AG (http://www.itemis.eu) and others.
* 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
*******************************************************************************/
package org.eclipse.xtext.junit4.parameterized;
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.xtext.junit4.parameterized.ActualCollection.ActualItem;
import org.eclipse.xtext.junit4.parameterized.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;
/**
* @author Moritz Eysholdt - Initial contribution and API
*/
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);
}
}

View file

@ -9,6 +9,7 @@ package org.eclipse.xtext.junit4.parameterized;
import org.eclipse.emf.common.util.URI;
import org.eclipse.xtext.resource.XtextResource;
import org.eclipse.xtext.util.Strings;
import com.google.inject.ImplementedBy;
@ -18,14 +19,38 @@ import com.google.inject.ImplementedBy;
@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, Object[] params, String expectation, boolean ignore);
void acceptTest(String title, String method, Object[][] params, IExpectation expectation, boolean ignore);
void acceptTestClass(Class<?> clazz);
// void acceptTestClass(Class<?> clazz);
}
void collectParameters(XtextResource resource, IParameterAcceptor acceptor);
void collectParameters(Class<?> testClass, XtextResource resource, IParameterAcceptor acceptor);
}

View file

@ -0,0 +1,23 @@
/*******************************************************************************
* Copyright (c) 2011 itemis AG (http://www.itemis.eu) and others.
* 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
*******************************************************************************/
package org.eclipse.xtext.junit4.parameterized;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @author Moritz Eysholdt - Initial contribution and API
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Parameter {
String syntax() default "";
}

View file

@ -24,6 +24,7 @@ import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.xtext.junit4.IInjectorProvider;
import org.eclipse.xtext.junit4.IRegistryConfigurator;
import org.eclipse.xtext.junit4.InjectWith;
import org.eclipse.xtext.junit4.parameterized.IParameterProvider.IExpectation;
import org.eclipse.xtext.junit4.parameterized.IParameterProvider.IParameterAcceptor;
import org.eclipse.xtext.junit4.parameterized.ParameterizedXtextRunner.ResourceRunner;
import org.eclipse.xtext.junit4.parameterized.TestExpectationValidator.ITestExpectationValidator;
@ -75,7 +76,9 @@ public class ParameterizedXtextRunner extends ParentRunner<ResourceRunner> {
Annotation annotation) throws Throwable {
Class<? extends ITestExpectationValidator<?>> validatorClass = trv.validator();
Class<?> expectedResultType = getExpectedResultType(validatorClass);
if (!expectedResultType.isAssignableFrom(method.getReturnType()))
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
@ -93,7 +96,12 @@ public class ParameterizedXtextRunner extends ParentRunner<ResourceRunner> {
if (trv != null)
return (ITestExpectationValidator<Object>) createValidator(trv, an);
}
throw new RuntimeException("Annotation missing: @Test or @TestString or @TestIterable, etc. in: " + method);
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) {
@ -119,11 +127,11 @@ public class ParameterizedXtextRunner extends ParentRunner<ResourceRunner> {
protected static class ParameterSetRunner {
protected Description description;
protected String expectation;
protected IExpectation expectation;
protected boolean ignore;
protected int index = -1;
protected String methodName;
protected Object[] params;
protected Object[][] params;
protected ResourceRunner runner;
protected String title;
@ -133,7 +141,7 @@ public class ParameterizedXtextRunner extends ParentRunner<ResourceRunner> {
return description;
}
public String getExpectation() {
public IExpectation getExpectation() {
return expectation;
}
@ -161,16 +169,20 @@ public class ParameterizedXtextRunner extends ParentRunner<ResourceRunner> {
return methodName;
}
public Object[] getParams() {
public 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, Object[] params, String expectation,
boolean ignore) {
public void init(ResourceRunner runner, String title, String method, Object[][] params,
IExpectation expectation, boolean ignore) {
this.runner = runner;
this.title = title;
this.methodName = method;
@ -197,7 +209,7 @@ public class ParameterizedXtextRunner extends ParentRunner<ResourceRunner> {
resourceSet.getResource(uri, true);
}
public void acceptTest(String title, String method, Object[] params, String expectation, boolean ignore) {
public void acceptTest(String title, String method, Object[][] params, IExpectation expectation, boolean ignore) {
ParameterSetRunner runner = injectorProvider.getInjector().getInstance(ParameterSetRunner.class);
runner.init(this, title, method, params, expectation, ignore);
parameterSets.add(runner);
@ -209,7 +221,7 @@ public class ParameterizedXtextRunner extends ParentRunner<ResourceRunner> {
protected void collectParameters() {
IParameterProvider parameterProvider = injectorProvider.getInjector().getInstance(IParameterProvider.class);
parameterProvider.collectParameters(resource, this);
parameterProvider.collectParameters(clazz.getJavaClass(), resource, this);
}
public Description getDescription() {
@ -253,6 +265,7 @@ public class ParameterizedXtextRunner extends ParentRunner<ResourceRunner> {
r.index = count;
}
}
}
private static Map<Class<?>, IInjectorProvider> injectorProviderClassCache = Maps.newHashMap();
@ -291,22 +304,6 @@ public class ParameterizedXtextRunner extends ParentRunner<ResourceRunner> {
this.filter = filter;
}
protected Constructor<?> findConstructor(Object[] params) {
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;
}
List<String> types = Lists.newArrayList();
for (Object p : params)
types.add(p == null ? "?" : p.getClass().getName());
throw new RuntimeException("No valid constructor found in class " + getTestClass().getJavaClass().getName()
+ " for types " + Joiner.on(", ").join(types));
}
protected MethodWithExpectation findTestMethod(String name) throws Throwable {
MethodWithExpectation result = methods.get(name);
if (result == null) {
@ -370,24 +367,51 @@ public class ParameterizedXtextRunner extends ParentRunner<ResourceRunner> {
}
}
protected List<URI> getURIs(ResourceURIs resourceURIs) {
Assert.assertFalse("@ResourceURIs needs a baseURI", Strings.isEmpty(resourceURIs.baseDir()));
Assert.assertTrue("@ResourceURIs needs at least one fileExtension", resourceURIs.fileExtensions().length > 0);
protected List<URI> getURIs(ResourceURIs uris) {
List<URI> result = Lists.newArrayList();
ResourceURICollector collector = new ResourceURICollector();
return collector.collectFiles(resourceURIs.baseDir(), resourceURIs.fileExtensions());
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(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());
Constructor<?> constructor = findConstructor(ps.getParams());
Object test = constructor.newInstance(ps.getParams());
Object test = newTestInstance(ps.getParams());
if (ps.getInjectorProvider() instanceof IRegistryConfigurator)
((IRegistryConfigurator) ps.getInjectorProvider()).setupRegistry();
try {
ps.getInjectorProvider().getInjector().injectMembers(test);
Object result = method.getMethod().invoke(test);
method.getValidator().validate(ps.getExpectation(), result);
method.getValidator().validate(ps.getResource(), ps.getExpectation(), result);
} catch (InvocationTargetException e) {
throw e.getCause();
} finally {

View file

@ -56,6 +56,17 @@ public class ResourceURICollector {
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());
}

View file

@ -13,4 +13,6 @@ public @interface ResourceURIs {
String baseDir() default "";
String[] fileExtensions() default {};
String[] files() default {};
}

View file

@ -0,0 +1,159 @@
package org.eclipse.xtext.junit4.parameterized;
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;
/**
* @author Moritz Eysholdt - Initial contribution and API
*/
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;
}
}

View file

@ -1,187 +0,0 @@
/*******************************************************************************
* Copyright (c) 2011 itemis AG (http://www.itemis.eu) and others.
* 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
*******************************************************************************/
package org.eclipse.xtext.junit4.parameterized;
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 java.util.regex.Pattern;
import org.eclipse.xtext.junit4.parameterized.AbstractIterableExpectationValidator.ToString;
import org.eclipse.xtext.junit4.parameterized.TestAsCommaSeparatedValues.CSVResultValidator;
import org.eclipse.xtext.junit4.parameterized.TestExpectationValidator.TestResult;
import org.junit.ComparisonFailure;
import com.google.common.base.Function;
/**
* @author Moritz Eysholdt - Initial contribution and API
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@TestExpectationValidator(validator = CSVResultValidator.class)
public @interface TestAsCommaSeparatedValues {
public class CSVResultValidator extends AbstractIterableExpectationValidator {
protected class ItemWithPred extends Item {
public ItemWithPred(String normalized, String escaped) {
super(normalized, escaped);
}
protected ItemWithPred predecessor;
protected boolean suppressWrapBefore = false;
protected boolean wrapBefore = false;
public int charsInLine() {
if (wrapBefore || predecessor == null)
return escaped.length();
return predecessor.charsInLine() + 2 + escaped.length();
}
@Override
public boolean equals(Object obj) {
if (obj instanceof Item)
return normalized.equals(((Item) obj).normalized);
return false;
}
@Override
public int hashCode() {
return normalized.hashCode();
}
public int itemsInLine() {
if (wrapBefore || predecessor == null)
return 1;
return itemsInLine() + 1;
}
@Override
public String toString() {
StringBuilder result = new StringBuilder();
if (suppressWrapBefore)
result.append("!");
if (wrapBefore)
result.append("\\n");
result.append(normalized);
return result.toString();
}
}
protected static final Pattern WS = Pattern.compile("\\s+", Pattern.MULTILINE);
protected TestAsCommaSeparatedValues cfg;
public CSVResultValidator(TestAsCommaSeparatedValues cfg) {
super(cfg.caseSensitive(), cfg.whitespaceSensitive());
this.cfg = cfg;
}
@Override
protected Item createItem(String normalized, String escaped) {
return new ItemWithPred(normalized, escaped);
}
@Override
protected String escapeUnquoted(String str) {
return super.escapeUnquoted(str).replaceAll(",", "\\,");
}
protected String format(List<Item> items) {
StringBuilder result = new StringBuilder();
for (Item i : items) {
if (result.length() > 0) {
if (((ItemWithPred) i).wrapBefore)
result.append(",\n");
else
result.append(", ");
}
result.append(i.escaped);
}
return result.toString();
}
protected void suppressWrap(List<Item> wrapped, List<Item> items) {
int next = 0;
boolean wrap = false;
for (Item w : wrapped) {
int found = -1;
for (int i = next; i < items.size(); i++)
if (items.get(i).equals(w)) {
found = i;
break;
}
wrap |= ((ItemWithPred) w).wrapBefore;
if (found >= 0) {
if (!wrap)
for (int i = next; i <= found; i++)
((ItemWithPred) items.get(i)).suppressWrapBefore = true;
else
((ItemWithPred) items.get(found)).wrapBefore = true;
wrap = false;
next = found + 1;
}
}
}
public void validate(String expectation, @TestResult Iterable<Object> actual) {
List<String> expectedList = toStringList(expectation, ',');
List<String> actualList = toStringList(actual, cfg.itemFormatter());
Collection<String> expectedNormalized = normalize(expectedList);
Collection<String> actualNormalized = normalize(actualList);
if (!expectedNormalized.equals(actualNormalized)) {
List<Item> actualItems = escape(actualList);
List<Item> expectedItems = escape(expectedList);
if (!cfg.ordered())
expectedItems = sort(actualItems, expectedItems);
wrap(actualItems);
suppressWrap(actualItems, expectedItems);
wrap(expectedItems);
String expectedFormatted = format(expectedItems);
String actualFormatted = format(actualItems);
throw new ComparisonFailure("", expectedFormatted, actualFormatted);
}
}
protected void wrap(List<Item> items) {
boolean restrictWidth = cfg.maxLineWidth() >= 0;
boolean restrictItems = cfg.maxItemsPerLine() >= 0;
ItemWithPred last = null;
for (Item item : items) {
ItemWithPred i = (ItemWithPred) item;
i.predecessor = last;
last = i;
}
for (Item item : items) {
ItemWithPred i = (ItemWithPred) item;
if (!i.suppressWrapBefore && !i.wrapBefore) {
boolean itemsEx = restrictItems && i.itemsInLine() > cfg.maxItemsPerLine();
boolean widthEx = restrictWidth && i.charsInLine() > cfg.maxLineWidth();
i.wrapBefore = itemsEx || widthEx;
}
}
}
}
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 whitespaceSensitive() default false;
}

View file

@ -1,77 +0,0 @@
/*******************************************************************************
* Copyright (c) 2011 itemis AG (http://www.itemis.eu) and others.
* 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
*******************************************************************************/
package org.eclipse.xtext.junit4.parameterized;
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.xtext.junit4.parameterized.AbstractIterableExpectationValidator.ToString;
import org.eclipse.xtext.junit4.parameterized.TestAsLines.LinesResultValidator;
import org.eclipse.xtext.junit4.parameterized.TestExpectationValidator.TestResult;
import org.junit.ComparisonFailure;
import com.google.common.base.Function;
/**
* @author Moritz Eysholdt - Initial contribution and API
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@TestExpectationValidator(validator = LinesResultValidator.class)
public @interface TestAsLines {
public class LinesResultValidator extends AbstractIterableExpectationValidator {
protected TestAsLines cfg;
public LinesResultValidator(TestAsLines cfg) {
super(cfg.caseSensitive(), cfg.whitespaceSensitive());
this.cfg = cfg;
}
protected String format(List<Item> items) {
StringBuilder result = new StringBuilder();
for (Item item : items) {
if (result.length() > 0)
result.append("\n");
result.append(item.escaped);
}
return result.toString();
}
public void validate(String expectation, @TestResult Iterable<Object> actual) {
List<String> expectedList = toStringList(expectation, '\n');
List<String> actualList = toStringList(actual, cfg.itemFormatter());
Collection<String> expectedNormalized = normalize(expectedList);
Collection<String> actualNormalized = normalize(actualList);
if (!expectedNormalized.equals(actualNormalized)) {
List<Item> actualItems = escape(actualList);
List<Item> expectedItems = escape(expectedList);
if (!cfg.ordered())
expectedItems = sort(actualItems, expectedItems);
String expectedFormatted = format(expectedItems);
String actualFormatted = format(actualItems);
throw new ComparisonFailure("", expectedFormatted, actualFormatted);
}
}
}
boolean caseSensitive() default true;
boolean whitespaceSensitive() default false;
Class<? extends Function<Object, String>> itemFormatter() default ToString.class;
boolean ordered() default false;
}

View file

@ -12,6 +12,8 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.eclipse.xtext.junit4.parameterized.IParameterProvider.IExpectation;
import org.eclipse.xtext.resource.XtextResource;
import org.junit.Assert;
import org.junit.Test;
@ -24,15 +26,19 @@ public @interface TestExpectationValidator {
public interface ITestExpectationValidator<RESULT> {
void validate(String expectation, RESULT actual);
void validate(XtextResource resource, IExpectation expectation, RESULT actual);
}
public class NullTestResultValidator implements ITestExpectationValidator<Void> {
public NullTestResultValidator(Test config) {
}
public void validate(String expectation, @TestResult Void actual) {
if (expectation != null && expectation.length() > 0)
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 + "'.");
}
}

View file

@ -0,0 +1,22 @@
/*******************************************************************************
* Copyright (c) 2011 itemis AG (http://www.itemis.eu) and others.
* 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
*******************************************************************************/
package org.eclipse.xtext.junit4.parameterized;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @author Moritz Eysholdt - Initial contribution and API
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@TestExpectationValidator(validator = TestExpectationValidator.NullTestResultValidator.class)
public @interface Xpect {
}

View file

@ -0,0 +1,140 @@
/*******************************************************************************
* Copyright (c) 2011 itemis AG (http://www.itemis.eu) and others.
* 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
*******************************************************************************/
package org.eclipse.xtext.junit4.parameterized;
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.xtext.junit4.parameterized.ActualCollection.ActualItem;
import org.eclipse.xtext.junit4.parameterized.ActualCollection.ToString;
import org.eclipse.xtext.junit4.parameterized.ExpectationCollection.ExpectationItem;
import org.eclipse.xtext.junit4.parameterized.IParameterProvider.IExpectation;
import org.eclipse.xtext.junit4.parameterized.TestExpectationValidator.ITestExpectationValidator;
import org.eclipse.xtext.junit4.parameterized.TestExpectationValidator.TestResult;
import org.eclipse.xtext.junit4.parameterized.XpectCommaSeparatedValues.CSVResultValidator;
import org.eclipse.xtext.resource.XtextResource;
import org.eclipse.xtext.util.Pair;
import org.junit.ComparisonFailure;
import com.google.common.base.Function;
/**
* @author Moritz Eysholdt - Initial contribution and API
*/
@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) {
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().isEmpty();
}
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;
}

View file

@ -0,0 +1,96 @@
/*******************************************************************************
* Copyright (c) 2011 itemis AG (http://www.itemis.eu) and others.
* 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
*******************************************************************************/
package org.eclipse.xtext.junit4.parameterized;
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.xtext.junit4.parameterized.ActualCollection.ActualItem;
import org.eclipse.xtext.junit4.parameterized.ActualCollection.ToString;
import org.eclipse.xtext.junit4.parameterized.ExpectationCollection.ExpectationItem;
import org.eclipse.xtext.junit4.parameterized.IParameterProvider.IExpectation;
import org.eclipse.xtext.junit4.parameterized.TestExpectationValidator.ITestExpectationValidator;
import org.eclipse.xtext.junit4.parameterized.TestExpectationValidator.TestResult;
import org.eclipse.xtext.junit4.parameterized.XpectLines.LinesResultValidator;
import org.eclipse.xtext.resource.XtextResource;
import org.eclipse.xtext.util.Pair;
import org.junit.ComparisonFailure;
import com.google.common.base.Function;
import com.google.common.base.Joiner;
import com.google.common.collect.Lists;
/**
* @author Moritz Eysholdt - Initial contribution and API
*/
@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) {
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;
}

View file

@ -7,74 +7,289 @@
*******************************************************************************/
package org.eclipse.xtext.junit4.parameterized;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
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.Lists;
import com.google.common.collect.Maps;
/**
* @author Moritz Eysholdt - Initial contribution and API
*/
@SuppressWarnings("restriction")
public class XpectParameterProvider implements IParameterProvider {
protected static Pattern XPECT_PATTERN = Pattern.compile("(\\S)?XPECT(_TEST_CLASS)?\\s*([a-zA-Z0-9]+)");
protected static class AssignedProduction extends StringProduction {
// XPECT foo
// XPECT foo("param")
// XPECT foo("param", param2)
// XPECT foo at location
// XPECT foo at loca!tion
// XPECT foo("param") at location
// XPECT foo --> expectation
/* XPECT foo ---
expectation
--- */
/* XPECT foo("param") at location ---
expectation
--- */
public AssignedProduction(String production) {
super(production);
}
public void collectParameters(XtextResource resource, IParameterAcceptor acceptor) {
for (ILeafNode leaf : resource.getParseResult().getRootNode().getLeafNodes())
if (leaf.isHidden() && leaf.getText().contains("XPECT"))
parseLeaf(resource, leaf, acceptor);
@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 void parseLeaf(XtextResource resource, ILeafNode leaf, IParameterAcceptor acceptor) {
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 OFFSET = "offset";
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) {
Object[][] params = createParams(res, Collections.<String, String> emptyMap());
acceptor.acceptTest(null, meth.getName(), params, null, false);
}
}
}
}
protected String convertValue(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)
return String.valueOf(result + add);
else
throw new RuntimeException("OFFSET '" + value + "' not found");
case ID:
case INT:
case STRING:
case TEXT:
return value;
}
return value;
}
protected Object[][] createParams(XtextResource res, Map<String, String> params) {
Object[] params1 = new Object[] { res, params };
Object[] params2 = new Object[] { res };
return new Object[][] { params1, params2 };
}
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.getOffset() + node.getLength();
}
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);
Parameter annotation = method.getAnnotation(Parameter.class);
if (annotation != null)
return annotation.syntax();
} 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(resource, leaf, text, matcher.group(3), matcher.end(), acceptor,
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 {
int newOffset;
if ((newOffset = parseXpectTest(text, matcher.group(3), matcher.end())) >= 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 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 parseString(String text, int offset, Wrapper<String> value) {
if (offset < text.length() && text.charAt(offset) == '"') {
int i = offset + 1;
@ -88,6 +303,13 @@ public class XpectParameterProvider implements IParameterProvider {
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())
@ -105,95 +327,148 @@ public class XpectParameterProvider implements IParameterProvider {
return i;
}
protected int parseXpect(XtextResource res, INode ctx, String text, String method, int offset,
protected int parseXpect(Class<?> testClass, XtextResource res, INode ctx, String text, String method, int offset,
IParameterAcceptor acceptor, boolean ignore) {
int newOffset;
List<String> params = Lists.newArrayList();
Wrapper<String> location = new Wrapper<String>(null);
Wrapper<String> expectation = new Wrapper<String>(null);
Map<String, String> params = Maps.newLinkedHashMap();
Wrapper<Expectation> expectation = new Wrapper<Expectation>(null);
offset = skipWhitespace(text, offset);
if ((newOffset = parseXpectParams(text, offset, params)) >= 0)
if ((newOffset = parseXpectParams(testClass, ctx, method, text, offset, params)) >= 0)
offset = newOffset;
offset = skipWhitespace(text, offset);
if ((newOffset = parseXpectLocation(text, offset, location)) >= 0)
offset = skipWhitespace(text, newOffset);
if ((newOffset = parseXpectSLExpectation(text, offset, expectation)) >= 0)
if ((newOffset = parseXpectSLExpectation(ctx, text, offset, expectation)) >= 0)
offset = newOffset;
else if ((newOffset = parseXpectMLExpectation(text, offset, expectation)) >= 0)
else if ((newOffset = parseXpectMLExpectation(ctx, text, offset, expectation)) >= 0)
offset = newOffset;
int loc;
if (location.get() != null)
loc = res.getParseResult().getRootNode().getText()
.indexOf(location.get(), ctx.getOffset() + ctx.getLength());
else
loc = ctx.getOffset();
Object[] testParms = new Object[] { res, loc, params.toArray(new String[params.size()]) };
acceptor.acceptTest("", method, testParms, expectation.get(), ignore);
acceptor.acceptTest(null, method, createParams(res, params), expectation.get(), ignore);
return offset;
}
protected int parseXpectLocation(String text, int offset, Wrapper<String> location) {
if (offset + 1 < text.length() && text.substring(offset, offset + 2).equals("at")) {
offset = skipWhitespace(text, offset + 2);
return parseStringOrText(text, offset, location);
}
return -1;
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(String text, int offset, Wrapper<String> expectation) {
if (offset + 2 < text.length() && text.substring(offset, offset + 3).equals("---")) {
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) {
expectation.set(substring.substring(0, end));
return end;
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(String text, int offset, List<String> params) {
if (offset < text.length() && text.charAt(offset) == '(') {
int index = text.indexOf(')', offset);
params.add(text.substring(offset, index));
return index;
protected int parseXpectParams(Class<?> testClass, INode node, String methodName, final String text, int offset,
Map<String, String> params) {
String paramSyntax = getParameterSyntax(testClass, methodName);
if (org.eclipse.xtext.util.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;
}
});
int semanticOffset = getOffsetOfNextSemanticNode(node);
params.put(OFFSET, String.valueOf(semanticOffset));
if (trace != null && !trace.isEmpty()) {
for (BacktrackItem item : trace)
if (item.token != null && item.token.getName() != null)
params.put(item.token.getName(),
convertValue(node, semanticOffset, Token.valueOf(item.token.getValue()), item.value));
return trace.get(trace.size() - 1).offset;
}
return -1;
}
protected int parseXpectSLExpectation(String text, int offset, Wrapper<String> expectation) {
if (offset + 2 < text.length() && text.substring(offset, offset + 3).equals("-->")) {
int index = text.indexOf('\n', offset + 3);
if (index < 0)
index = text.length();
expectation.set(text.substring(offset + 3, index));
return index;
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(String text, String name, int offset) {
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())
switch (text.charAt(i)) {
case ' ':
case '\t':
case '\r':
case '\n':
i++;
break;
default:
return i;
}
if (Character.isWhitespace(text.charAt(i)))
i++;
else
return i;
return i;
}

View file

@ -11,11 +11,12 @@ import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.regex.Pattern;
import org.eclipse.xtext.junit4.parameterized.IParameterProvider.IExpectation;
import org.eclipse.xtext.junit4.parameterized.TestExpectationValidator.ITestExpectationValidator;
import org.eclipse.xtext.junit4.parameterized.TestExpectationValidator.TestResult;
import org.eclipse.xtext.junit4.parameterized.TestAsString.StringResultValidator;
import org.eclipse.xtext.junit4.parameterized.XpectString.StringResultValidator;
import org.eclipse.xtext.resource.XtextResource;
import org.eclipse.xtext.util.internal.FormattingMigrator;
import org.junit.ComparisonFailure;
@ -25,30 +26,29 @@ import org.junit.ComparisonFailure;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@TestExpectationValidator(validator = StringResultValidator.class)
public @interface TestAsString {
public @interface XpectString {
public class StringResultValidator implements ITestExpectationValidator<String> {
protected static final Pattern WS = Pattern.compile("\\s+", Pattern.MULTILINE);
protected TestAsString config;
protected XpectString config;
public StringResultValidator(TestAsString config) {
public StringResultValidator(XpectString config) {
this.config = config;
}
public void validate(String expectation, @TestResult String actual) {
public void validate(XtextResource resource, IExpectation expectation, @TestResult String actual) {
String exp;
if (!config.whitespaceSensitive()) {
FormattingMigrator migrator = new FormattingMigrator();
exp = migrator.migrate(actual, expectation, WS);
exp = migrator.migrate(actual, expectation.getExpectation());
} else
exp = expectation;
if (config.caseSensitive()) {
if (!exp.equals(actual))
throw new ComparisonFailure("", exp, actual);
} else {
if (!exp.equalsIgnoreCase(actual))
throw new ComparisonFailure("", exp, actual);
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);
}
}
}

View file

@ -16,56 +16,62 @@ import org.eclipse.emf.common.util.WrappedException;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.xtext.Constants;
import org.eclipse.xtext.resource.IResourceFactory;
import org.eclipse.xtext.resource.XtextResourceSet;
import org.eclipse.xtext.util.StringInputStream;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.name.Named;
/**
* Some convenience methods for parsing (i.e. testing, etc.)
* Some convenience methods for parsing (i.e. testing, etc.)
*
* @author Sven Efftinge - Initial contribution and API
*/
public class ParseHelper<T extends EObject> {
@Inject
private Provider<XtextResourceSet> resourceSetProvider;
@Inject
private IResourceFactory resourceFactory;
@Inject
@Named(Constants.FILE_EXTENSIONS)
public String fileExtension;
@SuppressWarnings("unchecked")
public T parse(InputStream in, URI uriToUse, Map<?,?> options, ResourceSet resourceSet) {
public T parse(InputStream in, URI uriToUse, Map<?, ?> options, ResourceSet resourceSet) {
Resource resource = resourceFactory.createResource(uriToUse);
resourceSet.getResources().add(resource);
try {
resource.load(in, options);
final T root = (T) (resource.getContents().isEmpty()? null : resource.getContents().get(0));
final T root = (T) (resource.getContents().isEmpty() ? null : resource.getContents().get(0));
return root;
} catch (IOException e) {
throw new WrappedException(e);
}
}
public T parse(CharSequence text) throws Exception {
return parse(text, resourceSetProvider.get());
}
public T parse(CharSequence text, ResourceSet resourceSetToUse) throws Exception {
return parse(getAsStream(text), computeUnusedUri(resourceSetToUse), null, resourceSetToUse);
}
public T parse(CharSequence text, URI uriToUse, ResourceSet resourceSetToUse) throws Exception {
return parse(getAsStream(text), uriToUse, null, resourceSetToUse);
}
return parse(getAsStream(text), uriToUse, null, resourceSetToUse);
}
protected URI computeUnusedUri(ResourceSet resourceSet) {
String name = "__synthetic";
for (int i = 0; i < Integer.MAX_VALUE; i++) {
URI syntheticUri = URI.createURI(name+i+".uri");
if (resourceSet.getResource(syntheticUri, false)==null)
URI syntheticUri = URI.createURI(name + i + "." + fileExtension);
if (resourceSet.getResource(syntheticUri, false) == null)
return syntheticUri;
}
throw new IllegalStateException();

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="src" path="src"/>
<classpathentry kind="output" path="bin"/>

View file

@ -20,9 +20,15 @@
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.xtext.ui.shared.xtextBuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>org.eclipse.pde.PluginNature</nature>
<nature>org.eclipse.xtext.ui.shared.xtextNature</nature>
</natures>
</projectDescription>

View file

@ -1,7 +1,12 @@
#Fri Jul 22 15:47:42 CEST 2011
#Wed Oct 26 02:54:21 CEST 2011
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
org.eclipse.jdt.core.compiler.compliance=1.5
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.source=1.5

View file

@ -6,5 +6,7 @@ Bundle-Vendor: Eclipse Modeling Project
Bundle-Version: 2.1.0.qualifier
Require-Bundle: org.junit4,
org.eclipse.xtext.junit4,
com.google.inject;bundle-version="2.0.0"
com.google.inject;bundle-version="2.0.0",
com.google.collect;bundle-version="1.0.0",
org.eclipse.xtext;bundle-version="2.1.0"
Bundle-RequiredExecutionEnvironment: J2SE-1.5

View file

@ -0,0 +1,271 @@
package org.eclipse.xtext.junit4.parameterized;
import java.util.List;
import junit.framework.Assert;
import org.eclipse.xtext.junit4.parameterized.ExpectationCollection;
import org.eclipse.xtext.junit4.parameterized.ExpectationCollection.ExpectationItem;
import org.junit.Test;
import com.google.common.base.Joiner;
import com.google.common.collect.Lists;
public class ExpectationCollectionTest
{
private String format(ExpectationCollection ec)
{
List<String> result = Lists.newArrayList();
for (ExpectationItem i : ec)
{
if (i.isWildcard())
result.add("(wildcard)");
else
result.add((i.isNegated() ? "(negated) " : "") + i.getNormalized().replace("\n", "\\n").replace("\r", "\\r")
+ " -> " + i.getEscaped());
}
return Joiner.on('\n').join(result);
}
@Test(expected = NullPointerException.class)
public void robust1()
{
ExpectationCollection ec = new ExpectationCollection();
ec.init(null);
}
@Test
public void robust2()
{
ExpectationCollection ec = new ExpectationCollection();
ec.init("");
Assert.assertFalse(ec.iterator().hasNext());
Assert.assertEquals("", format(ec));
}
@Test
public void robust3()
{
ExpectationCollection ec = new ExpectationCollection();
ec.init(" ");
Assert.assertFalse(ec.iterator().hasNext());
Assert.assertEquals("", format(ec));
}
@Test
public void robust4()
{
ExpectationCollection ec = new ExpectationCollection();
ec.init("\t");
Assert.assertFalse(ec.iterator().hasNext());
Assert.assertEquals("", format(ec));
}
@Test
public void robust5()
{
ExpectationCollection ec = new ExpectationCollection();
ec.init("\t,\t");
Assert.assertEquals("", format(ec));
Assert.assertFalse(ec.iterator().hasNext());
}
@Test
public void simple()
{
ExpectationCollection ec = new ExpectationCollection();
ec.setQuote('\'');
ec.init("foo, bar");
StringBuilder exp = new StringBuilder();
exp.append("foo -> 'foo'\n");
exp.append("bar -> 'bar'");
Assert.assertEquals(exp.toString(), format(ec));
}
@Test
public void simple_wcq()
{
ExpectationCollection ec = new ExpectationCollection();
ec.setQuote('\'');
ec.setWhitespaceSensitive(false);
ec.setCaseSensitive(false);
ec.setQuoted(false);
ec.init("foo, white space , CasE, !neg, \\!nneg, ..., \\..., es\\,\r\n\\\\caped, 'quoted', qu'ote");
StringBuilder exp = new StringBuilder();
exp.append("foo -> foo\n");
exp.append("whitespace -> white space\n");
exp.append("case -> CasE\n");
exp.append("(negated) neg -> neg\n");
exp.append("!nneg -> \\!nneg\n");
exp.append("(wildcard)\n");
exp.append("... -> \\...\n");
exp.append("es,\\caped -> es\\,\\r\\n\\\\caped\n");
exp.append("'quoted' -> 'quoted'\n");
exp.append("qu'ote -> qu'ote");
Assert.assertEquals(exp.toString(), format(ec));
}
@Test
public void simple_wcQ()
{
ExpectationCollection ec = new ExpectationCollection();
ec.setQuote('\'');
ec.setWhitespaceSensitive(false);
ec.setCaseSensitive(false);
ec.setQuoted(true);
ec.init("'foo', ' white space ', 'CasE', !'neg', '!nneg', ..., '...', 'es,\r\n\\\\caped', 'quoted', 'qu\\'ote'");
StringBuilder exp = new StringBuilder();
exp.append("foo -> 'foo'\n");
exp.append("whitespace -> ' white space '\n");
exp.append("case -> 'CasE'\n");
exp.append("(negated) neg -> 'neg'\n");
exp.append("!nneg -> '!nneg'\n");
exp.append("(wildcard)\n");
exp.append("... -> '...'\n");
exp.append("es,\\caped -> 'es,\\r\\n\\\\caped'\n");
exp.append("quoted -> 'quoted'\n");
exp.append("qu'ote -> 'qu\\'ote'");
Assert.assertEquals(exp.toString(), format(ec));
}
@Test
public void simple_wCq()
{
ExpectationCollection ec = new ExpectationCollection();
ec.setQuote('\'');
ec.setWhitespaceSensitive(false);
ec.setCaseSensitive(true);
ec.setQuoted(false);
ec.init("foo, white space , CasE, !neg, \\!nneg, ..., \\..., es\\,\r\n\\\\caped, 'quoted', qu'ote");
StringBuilder exp = new StringBuilder();
exp.append("foo -> foo\n");
exp.append("whitespace -> white space\n");
exp.append("CasE -> CasE\n");
exp.append("(negated) neg -> neg\n");
exp.append("!nneg -> \\!nneg\n");
exp.append("(wildcard)\n");
exp.append("... -> \\...\n");
exp.append("es,\\caped -> es\\,\\r\\n\\\\caped\n");
exp.append("'quoted' -> 'quoted'\n");
exp.append("qu'ote -> qu'ote");
Assert.assertEquals(exp.toString(), format(ec));
}
@Test
public void simple_wCQ()
{
ExpectationCollection ec = new ExpectationCollection();
ec.setQuote('\'');
ec.setWhitespaceSensitive(false);
ec.setCaseSensitive(true);
ec.setQuoted(true);
ec.init("'foo', ' white space ', 'CasE', !'neg', '!nneg', ..., '...', 'es,\r\n\\\\caped', 'quoted', 'qu\\'ote'");
StringBuilder exp = new StringBuilder();
exp.append("foo -> 'foo'\n");
exp.append("whitespace -> ' white space '\n");
exp.append("CasE -> 'CasE'\n");
exp.append("(negated) neg -> 'neg'\n");
exp.append("!nneg -> '!nneg'\n");
exp.append("(wildcard)\n");
exp.append("... -> '...'\n");
exp.append("es,\\caped -> 'es,\\r\\n\\\\caped'\n");
exp.append("quoted -> 'quoted'\n");
exp.append("qu'ote -> 'qu\\'ote'");
Assert.assertEquals(exp.toString(), format(ec));
}
@Test
public void simple_Wcq()
{
ExpectationCollection ec = new ExpectationCollection();
ec.setQuote('\'');
ec.setWhitespaceSensitive(true);
ec.setCaseSensitive(false);
ec.setQuoted(false);
ec.init("foo, white space , CasE, !neg, \\!nneg, ..., \\..., es\\,\r\n\\\\caped, 'quoted', qu'ote");
StringBuilder exp = new StringBuilder();
exp.append("foo -> foo\n");
exp.append("white space -> white space\n");
exp.append("case -> CasE\n");
exp.append("(negated) neg -> neg\n");
exp.append("!nneg -> \\!nneg\n");
exp.append("(wildcard)\n");
exp.append("... -> \\...\n");
exp.append("es,\\r\\n\\caped -> es\\,\\r\\n\\\\caped\n");
exp.append("'quoted' -> 'quoted'\n");
exp.append("qu'ote -> qu'ote");
Assert.assertEquals(exp.toString(), format(ec));
}
@Test
public void simple_WcQ()
{
ExpectationCollection ec = new ExpectationCollection();
ec.setQuote('\'');
ec.setWhitespaceSensitive(true);
ec.setCaseSensitive(false);
ec.setQuoted(true);
ec.init("'foo', ' white space ', 'CasE', !'neg', '!nneg', ..., '...', 'es,\r\n\\\\caped', 'quoted', 'qu\\'ote'");
StringBuilder exp = new StringBuilder();
exp.append("foo -> 'foo'\n");
exp.append(" white space -> ' white space '\n");
exp.append("case -> 'CasE'\n");
exp.append("(negated) neg -> 'neg'\n");
exp.append("!nneg -> '!nneg'\n");
exp.append("(wildcard)\n");
exp.append("... -> '...'\n");
exp.append("es,\\r\\n\\caped -> 'es,\\r\\n\\\\caped'\n");
exp.append("quoted -> 'quoted'\n");
exp.append("qu'ote -> 'qu\\'ote'");
Assert.assertEquals(exp.toString(), format(ec));
}
@Test
public void simple_WCq()
{
ExpectationCollection ec = new ExpectationCollection();
ec.setQuote('\'');
ec.setWhitespaceSensitive(true);
ec.setCaseSensitive(true);
ec.setQuoted(false);
ec.init("foo, white space , CasE, !neg, \\!nneg, ..., \\..., es\\,\r\n\\\\caped, 'quoted', qu'ote");
StringBuilder exp = new StringBuilder();
exp.append("foo -> foo\n");
exp.append("white space -> white space\n");
exp.append("CasE -> CasE\n");
exp.append("(negated) neg -> neg\n");
exp.append("!nneg -> \\!nneg\n");
exp.append("(wildcard)\n");
exp.append("... -> \\...\n");
exp.append("es,\\r\\n\\caped -> es\\,\\r\\n\\\\caped\n");
exp.append("'quoted' -> 'quoted'\n");
exp.append("qu'ote -> qu'ote");
Assert.assertEquals(exp.toString(), format(ec));
}
@Test
public void simple_WCQ()
{
ExpectationCollection ec = new ExpectationCollection();
ec.setQuote('\'');
ec.setWhitespaceSensitive(true);
ec.setCaseSensitive(true);
ec.setQuoted(true);
ec.init("'foo', ' white space ', 'CasE', !'neg', '!nneg', ..., '...', 'es,\r\n\\\\caped', 'quoted', 'qu\\'ote'");
StringBuilder exp = new StringBuilder();
exp.append("foo -> 'foo'\n");
exp.append(" white space -> ' white space '\n");
exp.append("CasE -> 'CasE'\n");
exp.append("(negated) neg -> 'neg'\n");
exp.append("!nneg -> '!nneg'\n");
exp.append("(wildcard)\n");
exp.append("... -> '...'\n");
exp.append("es,\\r\\n\\caped -> 'es,\\r\\n\\\\caped'\n");
exp.append("quoted -> 'quoted'\n");
exp.append("qu'ote -> 'qu\\'ote'");
Assert.assertEquals(exp.toString(), format(ec));
}
}

View file

@ -0,0 +1,185 @@
package org.eclipse.xtext.junit4.parameterized;
import java.util.Collection;
import java.util.List;
import org.eclipse.xtext.junit4.parameterized.ActualCollection;
import org.eclipse.xtext.junit4.parameterized.ExpectationCollection;
import org.eclipse.xtext.junit4.parameterized.ActualCollection.ActualItem;
import org.eclipse.xtext.junit4.parameterized.ExpectationCollection.ExpectationItem;
import org.eclipse.xtext.util.Pair;
import org.junit.Assert;
import org.junit.Test;
import com.google.common.base.Joiner;
import com.google.common.collect.Lists;
public class OrderedMapTest
{
private String format(Collection<ExpectationItem> items)
{
List<String> result = Lists.newArrayList();
for (ExpectationItem item : items)
{
if (item.isWildcard())
result.add("...");
else if (item.isNegated())
result.add("!" + item.getNormalized());
else
result.add(item.getNormalized());
}
String r = Joiner.on(",").join(result);
return result.size() > 1 ? "(" + r + ")" : r;
}
private String format(List<Pair<Collection<ExpectationItem>, ActualItem>> map)
{
List<String> result = Lists.newArrayList();
for (Pair<Collection<ExpectationItem>, ActualItem> item : map)
{
if ((item.getFirst() == null || item.getFirst().isEmpty()) && item.getSecond() == null)
result.add("null<>null");
else if (item.getFirst() == null || item.getFirst().isEmpty())
result.add("null<>" + item.getSecond().getNormalized());
else if (item.getSecond() == null)
result.add(format(item.getFirst()) + "<>null");
else
result.add(format(item.getFirst()) + "<>" + item.getSecond().getNormalized());
}
return Joiner.on("; ").join(result);
}
@Test
public void simple()
{
ExpectationCollection exp = new ExpectationCollection();
ActualCollection act = new ActualCollection();
exp.setOrdered(true);
act.setOrdered(true);
exp.init("foo, bar");
act.init("foo", "bar");
Assert.assertEquals("foo<>foo; bar<>bar", format(exp.map(act)));
act.init("bar", "foo");
Assert.assertEquals("null<>bar; foo<>foo; bar<>null", format(exp.map(act)));
act.init("bar");
Assert.assertEquals("foo<>null; bar<>bar", format(exp.map(act)));
act.init("foo", "bar", "baz");
Assert.assertEquals("foo<>foo; bar<>bar; null<>baz", format(exp.map(act)));
act.init("bar", "baz");
Assert.assertEquals("foo<>null; bar<>bar; null<>baz", format(exp.map(act)));
}
@Test
public void multi()
{
ExpectationCollection exp = new ExpectationCollection();
ActualCollection act = new ActualCollection();
exp.setOrdered(true);
act.setOrdered(true);
exp.init("foo, foo");
act.init("foo", "foo");
Assert.assertEquals("foo<>foo; foo<>foo", format(exp.map(act)));
act.init("foo");
Assert.assertEquals("foo<>foo; foo<>null", format(exp.map(act)));
act.init("foo", "foo", "foo");
Assert.assertEquals("foo<>foo; foo<>foo; null<>foo", format(exp.map(act)));
}
@Test
public void wildcard1()
{
ExpectationCollection exp = new ExpectationCollection();
ActualCollection act = new ActualCollection();
exp.setOrdered(true);
act.setOrdered(true);
exp.init("foo, ...");
act.init("foo", "foo");
Assert.assertEquals("foo<>foo; ...<>foo", format(exp.map(act)));
act.init("foo", "baz", "zonk");
Assert.assertEquals("foo<>foo; ...<>baz; ...<>zonk", format(exp.map(act)));
act.init("foo");
Assert.assertEquals("foo<>foo", format(exp.map(act)));
act.init("foo", "bar");
Assert.assertEquals("foo<>foo; ...<>bar", format(exp.map(act)));
act.init("bar", "foo");
Assert.assertEquals("null<>bar; foo<>foo", format(exp.map(act)));
act.init("bar");
Assert.assertEquals("foo<>null; ...<>bar", format(exp.map(act)));
}
@Test
public void wildcard2()
{
ExpectationCollection exp = new ExpectationCollection();
ActualCollection act = new ActualCollection();
exp.setOrdered(true);
act.setOrdered(true);
exp.init("foo, ..., bar, ...");
act.init("foo", "bar");
Assert.assertEquals("foo<>foo; bar<>bar", format(exp.map(act)));
act.init("foo", "xxx", "bar", "zzz");
Assert.assertEquals("foo<>foo; ...<>xxx; bar<>bar; ...<>zzz", format(exp.map(act)));
act.init("foo", "aaa", "xxx", "bar", "bbb", "zzz");
Assert.assertEquals("foo<>foo; ...<>aaa; ...<>xxx; bar<>bar; ...<>bbb; ...<>zzz", format(exp.map(act)));
act.init("foo");
Assert.assertEquals("foo<>foo; bar<>null", format(exp.map(act)));
act.init("bar");
Assert.assertEquals("foo<>null; bar<>bar", format(exp.map(act)));
act.init("bar", "foo");
Assert.assertEquals("null<>bar; foo<>foo; bar<>null", format(exp.map(act)));
act.init("bar", "xxx", "foo", "zzz");
Assert.assertEquals("null<>bar; null<>xxx; foo<>foo; ...<>zzz; bar<>null", format(exp.map(act)));
}
@Test
public void negated1()
{
ExpectationCollection exp = new ExpectationCollection();
ActualCollection act = new ActualCollection();
exp.setOrdered(true);
act.setOrdered(true);
exp.init("foo, !bar");
act.init("foo", "foo");
Assert.assertEquals("foo<>foo; !bar<>foo", format(exp.map(act)));
act.init("foo", "baz", "zonk");
Assert.assertEquals("foo<>foo; !bar<>baz; !bar<>zonk", format(exp.map(act)));
act.init("foo");
Assert.assertEquals("foo<>foo", format(exp.map(act)));
act.init("foo", "bar");
Assert.assertEquals("foo<>foo; null<>bar", format(exp.map(act)));
act.init("bar", "foo");
Assert.assertEquals("null<>bar; foo<>foo", format(exp.map(act)));
act.init("bar");
Assert.assertEquals("foo<>null; null<>bar", format(exp.map(act)));
}
@Test
public void negated2()
{
ExpectationCollection exp = new ExpectationCollection();
ActualCollection act = new ActualCollection();
exp.setOrdered(true);
act.setOrdered(true);
exp.init("foo, !xxx, bar, !zzz");
act.init("foo", "bar");
Assert.assertEquals("foo<>foo; bar<>bar", format(exp.map(act)));
act.init("foo", "xxx", "bar", "zzz");
Assert.assertEquals("foo<>foo; null<>xxx; bar<>bar; null<>zzz", format(exp.map(act)));
act.init("foo", "xxz", "bar", "zzx");
Assert.assertEquals("foo<>foo; !xxx<>xxz; bar<>bar; !zzz<>zzx", format(exp.map(act)));
act.init("foo", "aaa", "xxx", "bar", "bbb", "zzz");
Assert.assertEquals("foo<>foo; !xxx<>aaa; null<>xxx; bar<>bar; !zzz<>bbb; null<>zzz", format(exp.map(act)));
act.init("foo", "aaa", "xxz", "bar", "bbb", "zzx");
Assert.assertEquals("foo<>foo; !xxx<>aaa; !xxx<>xxz; bar<>bar; !zzz<>bbb; !zzz<>zzx", format(exp.map(act)));
act.init("foo");
Assert.assertEquals("foo<>foo; bar<>null", format(exp.map(act)));
act.init("bar");
Assert.assertEquals("foo<>null; bar<>bar", format(exp.map(act)));
act.init("bar", "foo");
Assert.assertEquals("null<>bar; foo<>foo; bar<>null", format(exp.map(act)));
act.init("bar", "xxz", "foo", "zzx");
Assert.assertEquals("null<>bar; null<>xxz; foo<>foo; !xxx<>zzx; bar<>null", format(exp.map(act)));
}
}

View file

@ -0,0 +1,143 @@
package org.eclipse.xtext.junit4.parameterized;
import org.eclipse.xtext.junit4.parameterized.ActualCollection;
import org.eclipse.xtext.junit4.parameterized.ExpectationCollection;
import org.junit.Assert;
import org.junit.Test;
public class OrderedMatchTest
{
@Test
public void simple()
{
ExpectationCollection exp = new ExpectationCollection();
ActualCollection act = new ActualCollection();
exp.setOrdered(true);
act.setOrdered(true);
exp.init("foo, bar");
act.init("foo", "bar");
Assert.assertTrue(exp.matches(act));
act.init("bar", "foo");
Assert.assertFalse(exp.matches(act));
act.init("bar");
Assert.assertFalse(exp.matches(act));
act.init("foo", "bar", "baz");
Assert.assertFalse(exp.matches(act));
act.init("bar", "baz");
Assert.assertFalse(exp.matches(act));
}
@Test
public void multi()
{
ExpectationCollection exp = new ExpectationCollection();
ActualCollection act = new ActualCollection();
exp.setOrdered(true);
act.setOrdered(true);
exp.init("foo, foo");
act.init("foo", "foo");
Assert.assertTrue(exp.matches(act));
act.init("foo");
Assert.assertFalse(exp.matches(act));
act.init("foo", "foo", "foo");
Assert.assertFalse(exp.matches(act));
}
@Test
public void wildcard1()
{
ExpectationCollection exp = new ExpectationCollection();
ActualCollection act = new ActualCollection();
exp.setOrdered(true);
act.setOrdered(true);
exp.init("foo, ...");
act.init("foo", "foo");
Assert.assertTrue(exp.matches(act));
act.init("foo", "baz", "zonk");
Assert.assertTrue(exp.matches(act));
act.init("foo");
Assert.assertTrue(exp.matches(act));
act.init("foo", "bar");
Assert.assertTrue(exp.matches(act));
act.init("bar", "foo");
Assert.assertFalse(exp.matches(act));
act.init("bar");
Assert.assertFalse(exp.matches(act));
}
@Test
public void wildcard2()
{
ExpectationCollection exp = new ExpectationCollection();
ActualCollection act = new ActualCollection();
exp.setOrdered(true);
act.setOrdered(true);
exp.init("foo, ..., bar, ...");
act.init("foo", "bar");
Assert.assertTrue(exp.matches(act));
act.init("foo", "xxx", "bar", "zzz");
Assert.assertTrue(exp.matches(act));
act.init("foo", "aaa", "xxx", "bar", "bbb", "zzz");
Assert.assertTrue(exp.matches(act));
act.init("foo");
Assert.assertFalse(exp.matches(act));
act.init("bar");
Assert.assertFalse(exp.matches(act));
act.init("bar", "foo");
Assert.assertFalse(exp.matches(act));
act.init("bar", "xxx", "foo", "zzz");
Assert.assertFalse(exp.matches(act));
}
@Test
public void negated1()
{
ExpectationCollection exp = new ExpectationCollection();
ActualCollection act = new ActualCollection();
exp.setOrdered(true);
act.setOrdered(true);
exp.init("foo, !bar");
act.init("foo", "foo");
Assert.assertTrue(exp.matches(act));
act.init("foo", "baz", "zonk");
Assert.assertTrue(exp.matches(act));
act.init("foo");
Assert.assertTrue(exp.matches(act));
act.init("foo", "bar");
Assert.assertFalse(exp.matches(act));
act.init("bar", "foo");
Assert.assertFalse(exp.matches(act));
act.init("bar");
Assert.assertFalse(exp.matches(act));
}
@Test
public void negated2()
{
ExpectationCollection exp = new ExpectationCollection();
ActualCollection act = new ActualCollection();
exp.setOrdered(true);
act.setOrdered(true);
exp.init("foo, !xxx, bar, !zzz");
act.init("foo", "bar");
Assert.assertTrue(exp.matches(act));
act.init("foo", "xxx", "bar", "zzz");
Assert.assertFalse(exp.matches(act));
act.init("foo", "xxz", "bar", "zzx");
Assert.assertTrue(exp.matches(act));
act.init("foo", "aaa", "xxx", "bar", "bbb", "zzz");
Assert.assertFalse(exp.matches(act));
act.init("foo", "aaa", "xxz", "bar", "bbb", "zzx");
Assert.assertTrue(exp.matches(act));
act.init("foo");
Assert.assertFalse(exp.matches(act));
act.init("bar");
Assert.assertFalse(exp.matches(act));
act.init("bar", "foo");
Assert.assertFalse(exp.matches(act));
act.init("bar", "xxz", "foo", "zzx");
Assert.assertFalse(exp.matches(act));
}
}

View file

@ -0,0 +1,30 @@
grammar org.eclipse.xtext.junit4.parameterized.ParameterizedXtextRunner
generate pkg "http://org.eclipse.xtext.junit4.parameterized.ParameterizedXtextRunner"
import "http://www.eclipse.org/emf/2002/Ecore" as ecore
// XPECT plain
// XPECT plain
// XPECT string --> My long String expectation
/* XPECT string ---
My long String expectation
--- */
/* XPECT csv ---
aaa, bbb, ccc, ddd, eee, fff, ggg, hhh, iii, jjj, kkk, lll,
mmm, nnn, ooo, ppp, qqq, rrr
--- */
/* XPECT lines ---
aaa bbb ccc
foo bar baz
xxx yyy zzz
--- */
// XPECT select from fo!o to b!az --> o='val' bar='val1' b
Root:
foo='val' bar='val1' baz='xxx'
;

View file

@ -0,0 +1,107 @@
package org.eclipse.xtext.junit4.parameterized;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import java.util.Map;
import org.eclipse.xtext.IGrammarAccess;
import org.eclipse.xtext.junit4.InjectWith;
import org.eclipse.xtext.resource.XtextResource;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import com.google.common.collect.Lists;
import com.google.inject.Inject;
@InjectWith(XtextInjectorProvider.class)
@RunWith(ParameterizedXtextRunner.class)
@ResourceURIs(files =
{ "src/org/eclipse/xtext/junit4/parameterized/ParameterizedXtextRunner.xtext" })
public class ParameterizedXtextRunnerTest
{
private XtextResource resource;
private Map<String, String> params;
public ParameterizedXtextRunnerTest(XtextResource res, Map<String, String> params)
{
this.resource = res;
this.params = params;
}
@Inject
IGrammarAccess injected;
private static boolean goodOldTesthasRun = false;
private static int xpectPlain = 0;
private static int xpectString = 0;
private static int xpectCsv = 0;
private static int xpectLines = 0;
private static int xpectSelect = 0;
@Test
public void goodOldTest()
{
goodOldTesthasRun = true;
}
@Before
public void before()
{
assertNotNull(injected);
}
@AfterClass
public static void after()
{
assertTrue(goodOldTesthasRun);
assertEquals(2, xpectPlain);
assertEquals(2, xpectString);
assertEquals(1, xpectCsv);
assertEquals(1, xpectLines);
assertEquals(1, xpectSelect);
}
@Xpect
public void plain()
{
xpectPlain++;
}
@XpectString
public String string()
{
xpectString++;
return "My long String expectation";
}
@XpectCommaSeparatedValues(maxLineWidth = 60)
public Iterable<String> csv()
{
xpectCsv++;
return Lists.newArrayList("aaa", "bbb", "ccc", "ddd", "eee", "fff", "ggg", "hhh", "iii", "jjj", "kkk", "lll",
"mmm", "nnn", "ooo", "ppp", "qqq", "rrr");
}
@XpectLines
public Iterable<String> lines()
{
xpectLines++;
return Lists.newArrayList("foo bar baz", "xxx yyy zzz", "aaa bbb ccc");
}
@XpectString
@Parameter(syntax = "'from' from=OFFSET 'to' to=OFFSET")
public String select()
{
xpectSelect++;
String text = resource.getParseResult().getRootNode().getText();
int from = Integer.parseInt(params.get("from"));
int to = Integer.parseInt(params.get("to"));
return text.substring(from, to);
}
}

View file

@ -0,0 +1,126 @@
package org.eclipse.xtext.junit4.parameterized;
import java.util.Collection;
import java.util.List;
import org.eclipse.xtext.junit4.parameterized.ActualCollection;
import org.eclipse.xtext.junit4.parameterized.ActualCollection.ActualItem;
import org.eclipse.xtext.junit4.parameterized.ExpectationCollection;
import org.eclipse.xtext.junit4.parameterized.ExpectationCollection.ExpectationItem;
import org.eclipse.xtext.util.Pair;
import org.junit.Assert;
import org.junit.Test;
import com.google.common.base.Joiner;
import com.google.common.collect.Lists;
public class UnorderedMapTest
{
private String format(Collection<ExpectationItem> items)
{
List<String> result = Lists.newArrayList();
for (ExpectationItem item : items)
{
if (item.isWildcard())
result.add("...");
else if (item.isNegated())
result.add("!" + item.getNormalized());
else
result.add(item.getNormalized());
}
String r = Joiner.on(",").join(result);
return result.size() > 1 ? "(" + r + ")" : r;
}
private String format(List<Pair<Collection<ExpectationItem>, ActualItem>> map)
{
List<String> result = Lists.newArrayList();
for (Pair<Collection<ExpectationItem>, ActualItem> item : map)
{
if ((item.getFirst() == null || item.getFirst().isEmpty()) && item.getSecond() == null)
result.add("null<>null");
else if (item.getFirst() == null || item.getFirst().isEmpty())
result.add("null<>" + item.getSecond().getNormalized());
else if (item.getSecond() == null)
result.add(format(item.getFirst()) + "<>null");
else
result.add(format(item.getFirst()) + "<>" + item.getSecond().getNormalized());
}
return Joiner.on("; ").join(result);
}
@Test
public void simple()
{
ExpectationCollection exp = new ExpectationCollection();
ActualCollection act = new ActualCollection();
exp.setOrdered(false);
act.setOrdered(false);
exp.init("foo, bar");
act.init("foo", "bar");
Assert.assertEquals("bar<>bar; foo<>foo", format(exp.map(act)));
act.init("bar", "foo");
Assert.assertEquals("bar<>bar; foo<>foo", format(exp.map(act)));
}
@Test
public void multi()
{
ExpectationCollection exp = new ExpectationCollection();
ActualCollection act = new ActualCollection();
exp.setOrdered(false);
act.setOrdered(false);
exp.init("foo, foo");
act.init("foo", "foo");
Assert.assertEquals("foo<>foo; foo<>foo", format(exp.map(act)));
act.init("foo");
Assert.assertEquals("foo<>foo; foo<>null", format(exp.map(act)));
act.init("foo", "foo", "foo");
Assert.assertEquals("foo<>foo; foo<>foo; null<>foo", format(exp.map(act)));
}
@Test
public void wildcard()
{
ExpectationCollection exp = new ExpectationCollection();
ActualCollection act = new ActualCollection();
exp.setOrdered(false);
act.setOrdered(false);
exp.init("foo, ...");
act.init("foo", "foo");
Assert.assertEquals("foo<>foo; ...<>foo", format(exp.map(act)));
act.init("foo", "baz", "zonk");
Assert.assertEquals("...<>baz; foo<>foo; ...<>zonk", format(exp.map(act)));
act.init("foo");
Assert.assertEquals("foo<>foo", format(exp.map(act)));
act.init("foo", "bar");
Assert.assertEquals("...<>bar; foo<>foo", format(exp.map(act)));
act.init("bar", "foo");
Assert.assertEquals("...<>bar; foo<>foo", format(exp.map(act)));
act.init("bar");
Assert.assertEquals("...<>bar; foo<>null", format(exp.map(act)));
}
@Test
public void negated()
{
ExpectationCollection exp = new ExpectationCollection();
ActualCollection act = new ActualCollection();
exp.setOrdered(false);
act.setOrdered(false);
exp.init("foo, !bar");
act.init("foo", "baz");
Assert.assertEquals("!bar<>baz; foo<>foo", format(exp.map(act)));
act.init("foo", "baz", "zonk");
Assert.assertEquals("!bar<>baz; foo<>foo; !bar<>zonk", format(exp.map(act)));
act.init("foo");
Assert.assertEquals("foo<>foo", format(exp.map(act)));
act.init("foo", "bar");
Assert.assertEquals("null<>bar; foo<>foo", format(exp.map(act)));
act.init("bar", "foo");
Assert.assertEquals("null<>bar; foo<>foo", format(exp.map(act)));
act.init("bar");
Assert.assertEquals("null<>bar; foo<>null", format(exp.map(act)));
}
}

View file

@ -0,0 +1,84 @@
package org.eclipse.xtext.junit4.parameterized;
import org.eclipse.xtext.junit4.parameterized.ActualCollection;
import org.eclipse.xtext.junit4.parameterized.ExpectationCollection;
import org.junit.Assert;
import org.junit.Test;
public class UnorderedMatchTest
{
@Test
public void simple()
{
ExpectationCollection exp = new ExpectationCollection();
ActualCollection act = new ActualCollection();
exp.setOrdered(false);
act.setOrdered(false);
exp.init("foo, bar");
act.init("foo", "bar");
Assert.assertTrue(exp.matches(act));
act.init("bar", "foo");
Assert.assertTrue(exp.matches(act));
}
@Test
public void multi()
{
ExpectationCollection exp = new ExpectationCollection();
ActualCollection act = new ActualCollection();
exp.setOrdered(false);
act.setOrdered(false);
exp.init("foo, foo");
act.init("foo", "foo");
Assert.assertTrue(exp.matches(act));
act.init("foo");
Assert.assertFalse(exp.matches(act));
act.init("foo", "foo", "foo");
Assert.assertFalse(exp.matches(act));
}
@Test
public void wildcard()
{
ExpectationCollection exp = new ExpectationCollection();
ActualCollection act = new ActualCollection();
exp.setOrdered(false);
act.setOrdered(false);
exp.init("foo, ...");
act.init("foo", "foo");
Assert.assertTrue(exp.matches(act));
act.init("foo", "baz", "zonk");
Assert.assertTrue(exp.matches(act));
act.init("foo");
Assert.assertTrue(exp.matches(act));
act.init("foo", "bar");
Assert.assertTrue(exp.matches(act));
act.init("bar", "foo");
Assert.assertTrue(exp.matches(act));
act.init("bar");
Assert.assertFalse(exp.matches(act));
}
@Test
public void negated()
{
ExpectationCollection exp = new ExpectationCollection();
ActualCollection act = new ActualCollection();
exp.setOrdered(false);
act.setOrdered(false);
exp.init("foo, !bar");
act.init("foo", "baz");
Assert.assertTrue(exp.matches(act));
act.init("foo", "baz", "zonk");
Assert.assertTrue(exp.matches(act));
act.init("foo");
Assert.assertTrue(exp.matches(act));
act.init("foo", "bar");
Assert.assertFalse(exp.matches(act));
act.init("bar", "foo");
Assert.assertFalse(exp.matches(act));
act.init("bar");
Assert.assertFalse(exp.matches(act));
}
}

View file

@ -0,0 +1,493 @@
package org.eclipse.xtext.junit4.parameterized;
import java.util.List;
import java.util.Map;
import junit.framework.Assert;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.xtext.Grammar;
import org.eclipse.xtext.junit4.InjectWith;
import org.eclipse.xtext.junit4.XtextRunner;
import org.eclipse.xtext.junit4.parameterized.IParameterProvider.IExpectation;
import org.eclipse.xtext.junit4.parameterized.IParameterProvider.IParameterAcceptor;
import org.eclipse.xtext.junit4.util.ParseHelper;
import org.eclipse.xtext.junit4.validation.ValidationTestHelper;
import org.eclipse.xtext.resource.XtextResource;
import org.eclipse.xtext.util.Exceptions;
import org.junit.Test;
import org.junit.runner.RunWith;
import com.google.common.base.Joiner;
import com.google.common.collect.Lists;
import com.google.inject.Inject;
@RunWith(XtextRunner.class)
@InjectWith(value = XtextInjectorProvider.class)
public class XpectParameterProviderTest
{
public static class TestTestCase
{
public void meth()
{
}
@Parameter(syntax = "'at' myOffset=OFFSET")
public void offsetMeth()
{
}
@Parameter(syntax = "('text' myText=TEXT)? ('int' myInt=INT)? ('string' myString=STRING)? ('id' myId=ID)?")
public void optionalMeth()
{
}
}
@Inject
private ParseHelper<Grammar> parseHelper;
@Inject
private ValidationTestHelper validationHelper;
@Inject
private XpectParameterProvider parameterProvider;
private String model = "grammar foo.Bar import 'http://www.eclipse.org/emf/2002/Ecore' as ecore\n generate bar 'http://bar.com/'\n{0}\n foo:val='bar';";
private String parse(String text)
{
String model = this.model.replace("{0}", text);
Grammar grammar;
try
{
grammar = parseHelper.parse(model);
validationHelper.assertNoIssues(grammar);
final List<String> result = Lists.newArrayList();
parameterProvider.collectParameters(TestTestCase.class, (XtextResource) grammar.eResource(),
new IParameterAcceptor()
{
public void acceptImportURI(URI uri)
{
result.add("import " + uri);
}
public void acceptTest(String title, String method, Object[][] params, IExpectation expectation,
boolean ignore)
{
StringBuilder str = new StringBuilder();
if (ignore)
str.append("(ignored) ");
if (title != null)
str.append("'" + title + "' ");
List<String> p1 = Lists.newArrayList();
for (Object[] o : params)
{
List<String> p2 = Lists.newArrayList();
for (Object x : o)
{
if (x == null)
p2.add("null");
else if (x instanceof Resource)
p2.add("Res");
else if (x instanceof Map<?, ?>)
p2.add("Map");
else if (x instanceof Integer)
p2.add("Int");
else
p2.add(x.getClass().getSimpleName());
}
p1.add(Joiner.on(", ").join(p2));
}
str.append(method + "(" + Joiner.on(" | ").join(p1) + ")");
if (expectation != null)
str.append(" --> " + expectation.getExpectation().replace("\n", "\\n"));
result.add(str.toString());
}
});
return Joiner.on("\n").join(result);
} catch (Exception e)
{
Exceptions.throwUncheckedException(e);
return "";
}
}
private String params(String text)
{
String model = this.model.replace("{0}", text);
Grammar grammar;
try
{
grammar = parseHelper.parse(model);
validationHelper.assertNoIssues(grammar);
final List<String> result = Lists.newArrayList();
parameterProvider.collectParameters(TestTestCase.class, (XtextResource) grammar.eResource(),
new IParameterAcceptor()
{
public void acceptImportURI(URI uri)
{
}
public void acceptTest(String title, String method, Object[][] params, IExpectation expectation,
boolean ignore)
{
XtextResource res = (XtextResource) params[0][0];
@SuppressWarnings("unchecked")
Map<String, String> map = (Map<String, String>) params[0][1];
List<String> p2 = Lists.newArrayList();
String text = res.getParseResult().getRootNode().getText();
for (Map.Entry<String, String> e : map.entrySet())
{
if (e.getKey().toLowerCase().contains("offset"))
{
int offs = Integer.parseInt(e.getValue());
String val = "'" + text.substring(offs - 3, offs) + "!" + text.substring(offs, offs + 3) + "'";
p2.add(e.getKey() + " at " + val.replace("\n", "\\n"));
} else
p2.add(e.getKey() + " = " + e.getValue());
}
result.add(method + "(" + Joiner.on(", ").join(p2) + ")");
}
});
return Joiner.on("\n").join(result);
} catch (Exception e)
{
Exceptions.throwUncheckedException(e);
return "";
}
}
private String expectation(String text)
{
String model = this.model.replace("{0}", text);
int before = this.model.indexOf("{0}");
int after = this.model.length() - before - 3;
Grammar grammar;
try
{
grammar = parseHelper.parse(model);
validationHelper.assertNoIssues(grammar);
XtextResource resource = (XtextResource) grammar.eResource();
final StringBuffer result = new StringBuffer(resource.getParseResult().getRootNode().getText());
parameterProvider.collectParameters(TestTestCase.class, resource, new IParameterAcceptor()
{
public void acceptImportURI(URI uri)
{
}
public void acceptTest(String title, String method, Object[][] params, IExpectation expectation, boolean ignore)
{
String replace;
if (expectation.getIndentation() != null)
replace = expectation.getIndentation() + "xxx";
else
replace = "xxx";
result.replace(expectation.getOffset(), expectation.getOffset() + expectation.getLength(), replace);
}
});
return result.substring(before, result.length() - after);
} catch (Exception e)
{
Exceptions.throwUncheckedException(e);
return "";
}
}
@Test
public void xpectSL()
{
String model = "// XPECT meth";
Assert.assertEquals("meth(Res, Map | Res)", parse(model));
}
@Test
public void xpectML()
{
String model = "/* XPECT meth */";
Assert.assertEquals("meth(Res, Map | Res)", parse(model));
}
@Test
public void xpectSLExpectation0()
{
String model = "// XPECT meth -->\n";
String actual = parse(model);
Assert.assertEquals("meth(Res, Map | Res) --> ", actual);
Assert.assertEquals("// XPECT meth -->xxx\n", expectation(model));
}
@Test
public void xpectSLExpectation01()
{
String model = "// XPECT meth --> \n";
String actual = parse(model);
Assert.assertEquals("meth(Res, Map | Res) --> ", actual);
Assert.assertEquals("// XPECT meth --> xxx\n", expectation(model));
}
@Test
public void xpectSLExpectation02()
{
String model = "// XPECT meth --> \n";
String actual = parse(model);
Assert.assertEquals("meth(Res, Map | Res) --> ", actual);
Assert.assertEquals("// XPECT meth --> xxx\n", expectation(model));
}
@Test
public void xpectSLExpectation1()
{
String model = "// XPECT meth -->exp\n";
Assert.assertEquals("meth(Res, Map | Res) --> exp", parse(model));
Assert.assertEquals("// XPECT meth -->xxx\n", expectation(model));
}
@Test
public void xpectSLExpectation2()
{
String model = "// XPECT meth --> exp\n";
Assert.assertEquals("meth(Res, Map | Res) --> exp", parse(model));
Assert.assertEquals("// XPECT meth --> xxx\n", expectation(model));
}
@Test
public void xpectSLExpectation3()
{
String model = "// XPECT meth --> exp \n";
Assert.assertEquals("meth(Res, Map | Res) --> exp ", parse(model));
Assert.assertEquals("// XPECT meth --> xxx\n", expectation(model));
}
@Test
public void xpectMLExpectation0()
{
String model = "/* XPECT meth -->\n*/";
Assert.assertEquals("meth(Res, Map | Res) --> ", parse(model));
Assert.assertEquals("/* XPECT meth -->xxx\n*/", expectation(model));
}
@Test
public void xpectMLExpectation01()
{
String model = "/* XPECT meth --> \n*/";
Assert.assertEquals("meth(Res, Map | Res) --> ", parse(model));
Assert.assertEquals("/* XPECT meth --> xxx\n*/", expectation(model));
}
@Test
public void xpectMLExpectation02()
{
String model = "/* XPECT meth --> \n*/";
Assert.assertEquals("meth(Res, Map | Res) --> ", parse(model));
Assert.assertEquals("/* XPECT meth --> xxx\n*/", expectation(model));
}
@Test
public void xpectMLExpectation1()
{
String model = "/* XPECT meth -->exp\n*/";
Assert.assertEquals("meth(Res, Map | Res) --> exp", parse(model));
Assert.assertEquals("/* XPECT meth -->xxx\n*/", expectation(model));
}
@Test
public void xpectMLExpectation2()
{
String model = "/* XPECT meth --> exp\n*/";
Assert.assertEquals("meth(Res, Map | Res) --> exp", parse(model));
Assert.assertEquals("/* XPECT meth --> xxx\n*/", expectation(model));
}
@Test
public void xpectMLExpectation3()
{
String model = "/* XPECT meth --> exp \n*/";
Assert.assertEquals("meth(Res, Map | Res) --> exp ", parse(model));
Assert.assertEquals("/* XPECT meth --> xxx\n*/", expectation(model));
}
@Test
public void xpectMLExpectation4()
{
String model = "\n/* XPECT meth ---\nexp\n---*/\n";
Assert.assertEquals("meth(Res, Map | Res) --> exp", parse(model));
Assert.assertEquals("\n/* XPECT meth ---\nxxx\n---*/\n", expectation(model));
}
@Test
public void xpectMLIndentation1()
{
StringBuilder model = new StringBuilder();
model.append("/* XPECT meth ---\n");
model.append(" exp\n");
model.append("--- */\n");
StringBuilder parsed = new StringBuilder();
parsed.append("meth(Res, Map | Res) --> exp");
StringBuilder replaced = new StringBuilder();
replaced.append("/* XPECT meth ---\n");
replaced.append("xxx\n");
replaced.append("--- */\n");
Assert.assertEquals(parsed.toString(), parse(model.toString()));
Assert.assertEquals(replaced.toString(), expectation(model.toString()));
}
@Test
public void xpectMLIndentation2()
{
StringBuilder model = new StringBuilder();
model.append(" /* XPECT meth ---\n");
model.append(" exp\n");
model.append(" --- */\n");
StringBuilder parsed = new StringBuilder();
parsed.append("meth(Res, Map | Res) --> exp");
StringBuilder replaced = new StringBuilder();
replaced.append(" /* XPECT meth ---\n");
replaced.append(" xxx\n");
replaced.append(" --- */\n");
Assert.assertEquals(parsed.toString(), parse(model.toString()));
Assert.assertEquals(replaced.toString(), expectation(model.toString()));
}
@Test
public void xpectMLIndentation3()
{
StringBuilder model = new StringBuilder();
model.append("\t/* XPECT meth ---\n");
model.append("\t exp\n");
model.append("\t--- */\n");
StringBuilder parsed = new StringBuilder();
parsed.append("meth(Res, Map | Res) --> exp");
StringBuilder replaced = new StringBuilder();
replaced.append("\t/* XPECT meth ---\n");
replaced.append("\txxx\n");
replaced.append("\t--- */\n");
Assert.assertEquals(parsed.toString(), parse(model.toString()));
Assert.assertEquals(replaced.toString(), expectation(model.toString()));
}
@Test
public void xpectMLIndentation4()
{
StringBuilder model = new StringBuilder();
model.append("\t /* XPECT meth ---\n");
model.append("\t tree {\n");
model.append("\t node\n");
model.append("\t }\n");
model.append("\t --- */\n");
StringBuilder parsed = new StringBuilder();
parsed.append("meth(Res, Map | Res) --> tree {\\n node\\n }");
StringBuilder replaced = new StringBuilder();
replaced.append("\t /* XPECT meth ---\n");
replaced.append("\t xxx\n");
replaced.append("\t --- */\n");
Assert.assertEquals(parsed.toString(), parse(model.toString()));
Assert.assertEquals(replaced.toString(), expectation(model.toString()));
}
@Test
public void xpectMLOffsetParameter1()
{
String model = "/* XPECT offsetMeth at foo --> exp \n*/ Bar: val='foo';";
Assert.assertEquals("offsetMeth(offset at '*/ !Bar', myOffset at 'l='!foo')", params(model));
}
@Test
public void xpectMLOffsetParameter2()
{
String model = "/* XPECT offsetMeth at fo!o --> exp \n*/ Bar: val='foo';";
Assert.assertEquals("offsetMeth(offset at '*/ !Bar', myOffset at ''fo!o';')", params(model));
}
@Test
public void xpectSLParameterText()
{
String model = "// XPECT optionalMeth text foo";
Assert.assertEquals("optionalMeth(offset at 'o\\n !foo', myText = foo)", params(model));
}
@Test
public void xpectSLParameterString()
{
String model = "// XPECT optionalMeth string 'foo'";
Assert.assertEquals("optionalMeth(offset at ''\\n !foo', myString = foo)", params(model));
}
@Test
public void xpectSLParameterInt()
{
String model = "// XPECT optionalMeth int 123";
Assert.assertEquals("optionalMeth(offset at '3\\n !foo', myInt = 123)", params(model));
}
@Test
public void xpectSLParameterId()
{
String model = "// XPECT optionalMeth id foo";
Assert.assertEquals("optionalMeth(offset at 'o\\n !foo', myId = foo)", params(model));
}
@Test
public void xpectSLParameterAll()
{
String model = "// XPECT optionalMeth text abc int 123 string 'str' id foo";
Assert.assertEquals("optionalMeth(offset at 'o\\n !foo', myText = abc, myInt = 123, myString = str, myId = foo)",
params(model));
}
@Test
public void xpectSLParameterWithExp()
{
String model = "// XPECT optionalMeth text abc --> exp\n";
Assert.assertEquals("optionalMeth(Res, Map | Res) --> exp", parse(model));
Assert.assertEquals("optionalMeth(offset at '\\n\\n !foo', myText = abc)", params(model));
}
@Test
public void xpectMLParameterWithExp()
{
String model = "/* XPECT optionalMeth text abc ---\n exp\n--- */";
Assert.assertEquals("optionalMeth(Res, Map | Res) --> exp", parse(model));
Assert.assertEquals("optionalMeth(offset at '/\\n !foo', myText = abc)", params(model));
}
@Test
public void xpectImport()
{
String model = "// XPECT_IMPORT foo/bar_baz-file.ext\n";
Assert.assertEquals("import foo/bar_baz-file.ext", parse(model));
}
@Test
public void xpectMulti()
{
StringBuilder model = new StringBuilder();
model.append("// XPECT_IMPORT foo.ext\n");
model.append("// XPECT meth ---\n");
model.append("// XPECT meth ---\n");
model.append("/* XPECT optionalMeth text abc ---\n exp\n--- */\n");
StringBuilder parsed = new StringBuilder();
parsed.append("import foo.ext\n");
parsed.append("meth(Res, Map | Res)\n");
parsed.append("meth(Res, Map | Res)\n");
parsed.append("optionalMeth(Res, Map | Res) --> exp");
Assert.assertEquals(parsed.toString(), parse(model.toString()));
}
}

View file

@ -0,0 +1,42 @@
package org.eclipse.xtext.junit4.parameterized;
import org.eclipse.xtext.XtextStandaloneSetup;
import org.eclipse.xtext.junit4.GlobalRegistries;
import org.eclipse.xtext.junit4.IInjectorProvider;
import org.eclipse.xtext.junit4.IRegistryConfigurator;
import org.eclipse.xtext.junit4.GlobalRegistries.GlobalStateMemento;
import com.google.inject.Injector;
public class XtextInjectorProvider implements IInjectorProvider, IRegistryConfigurator
{
protected GlobalStateMemento globalStateMemento;
protected Injector injector;
static
{
GlobalRegistries.initializeDefaults();
}
public Injector getInjector()
{
if (injector == null)
{
this.injector = new XtextStandaloneSetup().createInjectorAndDoEMFRegistration();
}
return injector;
}
public void restoreRegistry()
{
globalStateMemento.restoreGlobalState();
}
public void setupRegistry()
{
globalStateMemento = GlobalRegistries.makeCopyOfGlobalState();
if (injector != null)
new XtextStandaloneSetup().register(injector);
}
}