blob: fcbd12c355acbfffedcff4c39302c291d9902649 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2008 xored software, Inc.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* xored software, Inc. - initial API and Implementation (Alex Panchenko)
*******************************************************************************/
package org.eclipse.dltk.formatter.tests;
import java.io.IOException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.eclipse.dltk.compiler.util.Util;
import org.eclipse.dltk.ui.formatter.FormatterException;
import org.eclipse.dltk.ui.formatter.IScriptFormatter;
import org.eclipse.dltk.utils.TextUtils;
import org.osgi.framework.Bundle;
import junit.framework.AssertionFailedError;
import junit.framework.TestCase;
import junit.framework.TestResult;
import junit.framework.TestSuite;
public class ScriptedTest extends AbstractFormatterTest {
public static interface IScriptedTestContext {
Bundle getResourceBundle();
String getCharset();
IScriptFormatter createFormatter(Map<String, Object> preferences);
String validateOptionName(String name);
String validateOptionValue(String name, String value);
}
private boolean ignored;
private String input;
private String expected;
@Override
public void run(TestResult result) {
if (!ignored) {
super.run(result);
}
}
@Override
protected void runTest() throws Throwable {
final String output = format(input);
assertEquals(expected, output);
try {
assertEquals("Reformatting", expected, format(output)); //$NON-NLS-1$
} catch (FormatterException e) {
AssertionFailedError fail = new AssertionFailedError(e.getMessage());
fail.initCause(e);
throw fail;
}
}
private IScriptedTestContext context = null;
private Map<String, Object> preferences = null;
@Override
protected Map<String, Object> getDefaultPreferences() {
return preferences;
}
public void setPreference(String optionName, Object optionValue) {
if (preferences == null) {
preferences = new HashMap<String, Object>();
}
preferences.put(optionName, optionValue);
}
@Override
protected IScriptFormatter createFormatter(Map<String, Object> preferences) {
return context.createFormatter(preferences);
}
protected static char[] readResource(IScriptedTestContext context,
String resourceName) throws IOException {
final URL resource = context.getResourceBundle().getResource(
resourceName);
assertNotNull(resourceName + " is not found", resource); //$NON-NLS-1$
return Util.getInputStreamAsCharArray(resource.openStream(), -1,
context.getCharset());
}
private static final String TEST_MARKER = "===="; //$NON-NLS-1$
private static final String IGNORE_PREFIX = "@IGNORE:"; //$NON-NLS-1$
private static final String RESPONSE_MARKER = "=="; //$NON-NLS-1$
private static final String OPTION_MARKER = "==>"; //$NON-NLS-1$
public TestSuite createScriptedSuite(IScriptedTestContext context,
String resourceName) {
return createScriptedSuite(context, getClass().getName(), resourceName,
0);
}
/**
* @param resourceName
* @return
*/
public TestSuite createScriptedSuite(IScriptedTestContext context,
String suiteName, String resourceName, int beginTestIndex) {
final TestSuite suite = new TestSuite(suiteName);
try {
final String content = new String(readResource(context,
resourceName));
final String[] lines = TextUtils.splitLines(content);
String testName = "START";
int testIndex = 0;
int testBegin = 0;
int responseBegin = -1;
int i = 0;
while (i < lines.length) {
final String line = lines[i++];
if (line.startsWith(TEST_MARKER)
|| line.startsWith(OPTION_MARKER)) {
final int testEnd = i - 1;
if (testEnd > testBegin) {
if (responseBegin < 0) {
throw new IllegalArgumentException(
"No response marker - next test started on line "
+ testEnd);
}
if (testIndex >= beginTestIndex) {
suite.addTest(createTest(context, preferences,
testName, lines, testBegin, responseBegin,
testEnd));
}
++testIndex;
}
testBegin = i;
responseBegin = -1;
if (line.startsWith(TEST_MARKER)) {
testName = line.substring(TEST_MARKER.length()).trim();
} else if (line.startsWith(OPTION_MARKER)) {
final Matcher matcher = OPTION_PATTERN.matcher(line
.substring(OPTION_MARKER.length()));
if (matcher.matches()) {
final String optionName = context
.validateOptionName(matcher.group(1));
if (optionName == null)
throw new IllegalArgumentException(
"Invalid option name: " + line);
final String optionValue = context
.validateOptionValue(optionName, matcher
.group(2));
if (optionValue == null)
throw new IllegalArgumentException(
"Invalid option value: " + line);
setPreference(optionName, optionValue);
} else {
suite.addTest(new TestCase(resourceName + ":"
+ testEnd) {
@Override
protected void runTest() throws Throwable {
throw new IllegalArgumentException(line);
}
});
}
}
} else if (line.startsWith(RESPONSE_MARKER)) {
if (responseBegin >= 0) {
throw new IllegalArgumentException(
"Multiple response markers: line " + (i - 1)
+ ", previous on line " + responseBegin);
}
responseBegin = i;
}
}
if (lines.length > testBegin) {
if (responseBegin < 0) {
throw new IllegalArgumentException(
"No response marker in last test");
}
if (testIndex >= beginTestIndex) {
suite.addTest(createTest(context, preferences, testName,
lines, testBegin, responseBegin, lines.length));
}
}
} catch (final Throwable e) {
suite.addTest(new TestCase(e.getClass().getName()) {
@Override
protected void runTest() throws Throwable {
throw e;
}
});
}
return suite;
}
private static final Pattern OPTION_PATTERN = Pattern
.compile("\\s*([\\w\\.]+)\\s*=\\s*(\\S+)\\s*"); //$NON-NLS-1$
private ScriptedTest createTest(IScriptedTestContext context,
Map<String, Object> preferences, String testName, String[] lines,
int testBegin, int responseBegin, final int testEnd)
throws Exception {
final String input = joinLines(lines, testBegin, responseBegin - 1);
final String expected = joinLines(lines, responseBegin, testEnd);
ScriptedTest test = getClass().newInstance();
if (testName.startsWith(IGNORE_PREFIX)) {
test.ignored = true;
test.setName(testName.substring(IGNORE_PREFIX.length()).trim());
} else {
test.setName(testName);
}
test.input = input;
test.expected = expected;
test.context = context;
test.preferences = preferences != null ? new HashMap<String, Object>(
preferences) : preferences;
return test;
}
}