/*
* Copyright (C) Chaperon. All rights reserved.
* -------------------------------------------------------------------------
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*/
package net.sourceforge.chaperon.test;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
import net.sourceforge.chaperon.common.ConsoleLog;
import net.sourceforge.chaperon.model.extended.ExtendedGrammar;
import net.sourceforge.chaperon.process.extended.ExtendedDirectParserProcessor;
import org.custommonkey.xmlunit.Diff;
import org.exolab.castor.mapping.Mapping;
import org.exolab.castor.xml.Unmarshaller;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.XMLReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMResult;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.sax.SAXResult;
import javax.xml.transform.sax.SAXTransformerFactory;
import javax.xml.transform.sax.TransformerHandler;
import javax.xml.transform.stream.StreamResult;
public class ExtendedParserProcessorTestCase extends TestCase
{
private String name;
private Element step;
public ExtendedParserProcessorTestCase(String name)
{
super(name);
this.name = name;
}
public ExtendedParserProcessorTestCase(String name, Element step)
{
super(name);
this.name = name;
this.step = step;
}
public void runTest() throws Throwable
{
System.out.println("======================= Test "+name+" =======================");
Document result = null;
try
{
ExtendedGrammar grammar = getExtendedGrammar(step);
System.out.println("Grammar:\n"+grammar);
ExtendedDirectParserProcessor processor = getExtendedParserProcessor(grammar);
long time = System.currentTimeMillis();
result = process(processor, step);
System.out.println("process time = "+(System.currentTimeMillis()-time)+" ms");
}
catch (Exception e)
{
e.printStackTrace();
NodeList list = step.getElementsByTagName("exception");
Element exception = (Element)list.item(0);
if (exception!=null)
assertEquals("Test if exception messages are equal", exception.getAttribute("message"),
e.getMessage());
else
fail("Doesn't expect exception: "+e.getMessage());
}
Document expected = getResult(step);
if (expected!=null)
assertEqual(expected, result);
else if (result!=null)
{
System.out.println("actual:");
print(result);
fail("Result wasn't expected");
}
}
private ExtendedDirectParserProcessor getExtendedParserProcessor(ExtendedGrammar grammar)
{
ExtendedDirectParserProcessor processor = new ExtendedDirectParserProcessor();
processor.setLog(new ConsoleLog(ConsoleLog.INFO));
processor.setExtendedGrammar(grammar);
return processor;
}
private Document process(ExtendedDirectParserProcessor processor, Element step)
throws Exception
{
NodeList list =
step.getElementsByTagNameNS("http://chaperon.sourceforge.net/schema/text/1.0", "text");
Node node = list.item(0);
TransformerFactory streamerfactory = TransformerFactory.newInstance();
Transformer streamer = streamerfactory.newTransformer();
SAXTransformerFactory serializerfactory =
(SAXTransformerFactory)SAXTransformerFactory.newInstance();
TransformerHandler serializer = serializerfactory.newTransformerHandler();
DOMResult result = new DOMResult();
serializer.setResult(result);
processor.setContentHandler(new WhitespaceFilter(serializer, new ConsoleLog(ConsoleLog.INFO)));
streamer.transform(new DOMSource(node), new SAXResult(processor));
return (Document)result.getNode();
}
private ExtendedGrammar getExtendedGrammar(Element step)
throws Exception
{
NodeList list =
step.getElementsByTagNameNS("http://chaperon.sourceforge.net/schema/grammar/2.0", "grammar");
Node node = list.item(0);
Mapping mapping = new Mapping();
mapping.loadMapping(new InputSource(ExtendedGrammar.class.getResource("mapping.xml").openStream()));
Unmarshaller unmarshaller = new Unmarshaller(ExtendedGrammar.class);
unmarshaller.setMapping(mapping);
ExtendedGrammar grammar = (ExtendedGrammar)unmarshaller.unmarshal(node);
return grammar;
}
private Document getResult(Element step) throws Exception
{
NodeList list =
step.getElementsByTagNameNS("http://chaperon.sourceforge.net/schema/syntaxtree/2.0", "output");
Node node = list.item(0);
if (node==null)
return null;
TransformerFactory streamerfactory = TransformerFactory.newInstance();
Transformer streamer = streamerfactory.newTransformer();
DOMResult result = new DOMResult();
streamer.transform(new DOMSource(node), result);
return (Document)result.getNode();
}
private static Document getDocument(String filename, InputStream in)
throws Exception
{
SAXParserFactory parserfactory = SAXParserFactory.newInstance();
parserfactory.setNamespaceAware(true);
XMLReader parser = parserfactory.newSAXParser().getXMLReader();
SAXTransformerFactory serializerfactory =
(SAXTransformerFactory)SAXTransformerFactory.newInstance();
TransformerHandler handler = serializerfactory.newTransformerHandler();
DOMResult result = new DOMResult();
handler.setResult(result);
parser.setContentHandler(new WhitespaceFilter(handler));
InputSource inputsource = new InputSource(in);
inputsource.setSystemId(filename);
parser.parse(inputsource);
return (Document)result.getNode();
}
public final void print(Document document) throws Exception
{
TransformerFactory factory = TransformerFactory.newInstance();
javax.xml.transform.Transformer serializer = factory.newTransformer();
serializer.transform(new DOMSource(document), new StreamResult(System.out));
System.out.println();
}
/**
* Compare two XML documents provided as strings
*
* @param control Control document
* @param test Document to test
*
* @return Diff object describing differences in documents
*/
public final Diff compareXML(Document control, Document test)
{
return new Diff(control, test);
}
/**
* Assert that the result of an XML comparison is similar.
*
* @param msg The assertion message
* @param expected The expected XML document
* @param actual The actual XML Document
*/
public final void assertEqual(String msg, Document expected, Document actual)
{
expected.getDocumentElement().normalize();
actual.getDocumentElement().normalize();
Diff diff = compareXML(expected, actual);
if (!diff.similar())
{
try
{
System.out.println("expected:");
print(expected);
System.out.println("actual:");
print(actual);
}
catch (Exception e)
{
e.printStackTrace();
}
}
assertEquals(msg+", "+diff.toString(), true, diff.similar());
}
/**
* Assert that the result of an XML comparison is similar.
*
* @param msg The assertion message
* @param expected The expected XML document
* @param actual The actual XML Document
*/
public final void assertEqual(Document expected, Document actual)
{
expected.getDocumentElement().normalize();
actual.getDocumentElement().normalize();
Diff diff = compareXML(expected, actual);
if (!diff.similar())
{
try
{
System.out.println("expected:");
print(expected);
System.out.println("actual:");
print(actual);
}
catch (Exception e)
{
e.printStackTrace();
}
}
assertEquals("Test if the assertion document is equal, "+diff.toString(), true, diff.similar());
}
public static Test suite()
{
TestSuite suite = new TestSuite("ExtendedParserProcessorTest");
try
{
File directory =
new File(ExtendedParserProcessorTestCase.class.getResource("extended").getFile());
File[] files = directory.listFiles();
for (int i = 0; i<files.length; i++)
if ((files[i].getName().endsWith(".xml"))/* && (!files[i].getName().startsWith("stress"))*/)
{
Document test = getDocument(files[i].toString(), new FileInputStream(files[i]));
NodeList list = test.getDocumentElement().getElementsByTagName("step");
for (int j = 0; j<list.getLength(); j++)
{
Element step = (Element)list.item(j);
suite.addTest(new ExtendedParserProcessorTestCase("ExtendedParserProcessorTestCase "+
files[i].getName()+":"+
step.getAttribute("name"), step));
}
}
}
catch (Exception e)
{
e.printStackTrace();
}
return suite;
}
}