package org.rubypeople.rdt.internal.formatter;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.FactoryConfigurationError;
import javax.xml.parsers.ParserConfigurationException;
import junit.framework.Assert;
import junit.framework.TestCase;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.text.edits.MalformedTreeException;
import org.eclipse.text.edits.TextEdit;
import org.rubypeople.rdt.core.formatter.CodeFormatter;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
public abstract class AbstractCodeFormatterTestCase extends TestCase
{
private static class TestData
{
public TestData(String formattedText, String unformattedText, String assertionMessage)
{
this.formattedText = formattedText;
this.unformattedText = unformattedText;
this.assertionMessage = assertionMessage;
}
public String formattedText;
public String unformattedText;
public String assertionMessage;
}
private static final boolean VERBOSE = false; // set to true if you want output to command line
private Hashtable<String, List<TestData>> testMap;
// FIXME Use setup and teardown!
public AbstractCodeFormatterTestCase(String name) throws SAXException, IOException, ParserConfigurationException,
FactoryConfigurationError
{
super(name);
testMap = new Hashtable<String, List<TestData>>();
this.parseXmlConfiguration();
}
private String stripFirstNewLine(String input)
{
return input.substring(input.indexOf("\n") + 1);
}
private void parseXmlConfiguration() throws SAXException, IOException, ParserConfigurationException,
FactoryConfigurationError
{
Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(getInputDataStream());
NodeList tests = document.getElementsByTagName("test");
for (int i = 0; i < tests.getLength(); i++)
{
Node test = tests.item(i);
String name = test.getAttributes().getNamedItem("ID").getNodeValue();
List<TestData> partList = new ArrayList<TestData>();
NodeList nl = test.getChildNodes();
createTestData(partList, nl);
for (int j = 0; j < nl.getLength(); j++)
{
Node partNode = nl.item(j);
if (partNode.getNodeName().equals("part"))
{
createTestData(partList, partNode.getChildNodes());
}
}
testMap.put(name, partList);
}
}
private void createTestData(List<TestData> partList, NodeList partNodes)
{
String formattedText = null;
String unformattedText = null;
String assertionMessage = null;
for (int k = 0; k < partNodes.getLength(); k++)
{
Node node = partNodes.item(k);
if (node.getNodeName().equals("formatted"))
{
formattedText = this.stripFirstNewLine(node.getFirstChild().getNodeValue());
}
else if (node.getNodeName().equals("unformatted"))
{
unformattedText = this.stripFirstNewLine(node.getFirstChild().getNodeValue());
}
else if (node.getNodeName().equals("assertionMessage"))
{
assertionMessage = node.getFirstChild().getNodeValue().trim();
}
}
if (formattedText != null && unformattedText != null)
{
partList.add(new TestData(formattedText, unformattedText, assertionMessage));
}
}
protected void doTest(String name)
{
ArrayList<TestData> partList = (ArrayList<TestData>) testMap.get(name);
for (int i = 0; i < partList.size(); i++)
{
TestData data = (TestData) partList.get(i);
TextEdit edit = getCodeFormatter().format(-1, data.unformattedText, 0, data.unformattedText.length(), 0,
"\n");
IDocument doc = new org.eclipse.jface.text.Document(data.unformattedText);
try
{
edit.apply(doc);
}
catch (MalformedTreeException e)
{
fail(e.getMessage());
}
catch (BadLocationException e)
{
fail(e.getMessage());
}
String formatted = doc.get();
log("---------- " + data.assertionMessage + " --------");
log(data.unformattedText);
log("------------");
log(formatted);
Assert.assertEquals(data.assertionMessage, data.formattedText, formatted);
}
}
protected abstract CodeFormatter getCodeFormatter();
protected abstract InputStream getInputDataStream();
private void log(String formatted)
{
if (VERBOSE)
System.out.println(formatted);
}
public void testSimple()
{
this.doTest("Keywords");
}
public void testBlockWithBrackets()
{
this.doTest("blockWithBrackets");
}
public void testBlocks()
{
this.doTest("Blocks");
}
public void testParameters()
{
this.doTest("Parameters");
}
public void testLiterals()
{
this.doTest("Literals");
}
public void testLiteralsStartingWithPercentSign()
{
this.doTest("LiteralsStartingWithPercentSign");
}
public void testNegativeIndentation()
{
this.doTest("NegativeIndentation");
}
public void testRescueModifier()
{
doTest("RescueModifier");
}
public void testParen()
{
doTest("LineStartingWithParen");
}
public void testCaseWithWhens()
{
doTest("CaseWithWhens");
}
}