blob: e125bc440c1dd0671709fd270c04bb9df14ab992 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2005, 2017 IBM Corporation and others.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* SPDX-License-Identifier: EPL-2.0
*
*******************************************************************************/
package org.eclipse.dltk.tcl.parser.tests;
import static org.junit.Assert.assertEquals;
import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Enumeration;
import java.util.List;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.TransformerException;
import org.eclipse.dltk.core.tests.xml.DOMSerializer;
import org.eclipse.dltk.launching.LaunchingMessages;
import org.eclipse.dltk.tcl.core.tests.model.Activator;
import org.eclipse.dltk.tcl.internal.parser.raw.BracesSubstitution;
import org.eclipse.dltk.tcl.internal.parser.raw.CommandSubstitution;
import org.eclipse.dltk.tcl.internal.parser.raw.MagicBackslashSubstitution;
import org.eclipse.dltk.tcl.internal.parser.raw.NormalBackslashSubstitution;
import org.eclipse.dltk.tcl.internal.parser.raw.QuotesSubstitution;
import org.eclipse.dltk.tcl.internal.parser.raw.SimpleTclParser;
import org.eclipse.dltk.tcl.internal.parser.raw.TclCommand;
import org.eclipse.dltk.tcl.internal.parser.raw.TclScript;
import org.eclipse.dltk.tcl.internal.parser.raw.TclWord;
import org.eclipse.dltk.tcl.internal.parser.raw.VariableSubstitution;
import org.junit.Test;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
public class SimpleParserTests {
private String getContents(URL url) throws IOException {
InputStream input = null;
StringBuffer result = new StringBuffer(512);
try {
input = new BufferedInputStream(url.openStream());
// Simple copy
int ch = -1;
while ((ch = input.read()) != -1) {
if (ch != '\r') {
result.append((char) ch);
}
}
} finally {
if (input != null) {
input.close();
}
}
return result.toString();
}
private void print(TclWord s) {
System.out.println(
" - - word from " + s.getStart() + " to " + s.getEnd());
List<?> cmd = s.getContents();
for (Object o : cmd) {
System.out.println(" - - - " + o.toString());
if (o instanceof CommandSubstitution) {
System.out.println("# internal script #");
print(((CommandSubstitution) o).getScript());
System.out.println("# end of internal script #");
}
}
}
private void print(TclCommand s) {
System.out.println(
" - command from " + s.getStart() + " to " + s.getEnd());
List<TclWord> cmd = s.getWords();
for (TclWord word : cmd) {
print(word);
}
}
private void print(TclScript s) {
System.out.println("script from " + s.getStart() + " to " + s.getEnd());
List<TclCommand> cmd = s.getCommands();
for (TclCommand c : cmd) {
if (c == null)
System.out.println(
"comment(AND ERROR TOO, no null ptr should be in result) here!");
else
print(c);
}
}
/**
* Returns a Document that can be used to build a DOM tree
*
* @return the Document
* @throws ParserConfigurationException
* if an exception occurs creating the document builder
*/
public static Document getDocument() throws ParserConfigurationException {
DocumentBuilderFactory dfactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = dfactory.newDocumentBuilder();
Document doc = docBuilder.newDocument();
return doc;
}
/**
* Serializes a XML document into a string - encoded in UTF8 format, with
* platform line separators.
*
* @param doc
* document to serialize
* @return the document as a string
*/
public static String serializeDocument(Document doc)
throws IOException, TransformerException {
return new DOMSerializer().serialize(doc).trim();
}
private String getCodeRange(String code, int start, int end) {
return code.substring(start, end + 1);
}
private Document parseXML(String source) {
Document doc = null;
try {
// Wrapper the stream for efficient parsing
InputStream stream = new ByteArrayInputStream(source.getBytes());
// Do the parsing and obtain the top-level node
try {
DocumentBuilder parser = DocumentBuilderFactory.newInstance()
.newDocumentBuilder();
parser.setErrorHandler(new DefaultHandler());
doc = parser.parse(new InputSource(stream));
} catch (SAXException e) {
throw new IOException(
LaunchingMessages.ScriptRuntime_badFormat);
} catch (ParserConfigurationException e) {
stream.close();
throw new IOException(
LaunchingMessages.ScriptRuntime_badFormat);
} finally {
stream.close();
}
} catch (IOException e) {
}
return doc;
}
private Document createXMLFromSource(String source, TclScript s) {
Document doc;
try {
doc = getDocument();
getXML(source, s, doc);
return doc;
} catch (ParserConfigurationException e) {
e.printStackTrace();
}
return null;
}
private Node getWordAsNode(String source, TclWord word, Document doc) {
Element w = doc.createElement("word");
w.setAttribute("start", Integer.toString(word.getStart()));
w.setAttribute("end", Integer.toString(word.getEnd()));
String wordRawText = getCodeRange(source, word.getStart(),
word.getEnd());
w.setAttribute("text", wordRawText);
List<?> parts = word.getContents();
for (Object o : parts) {
Element p = null;
if (o instanceof String) {
p = doc.createElement("string");
p.setAttribute("text", o.toString());
} else if (o instanceof CommandSubstitution) {
CommandSubstitution cs = (CommandSubstitution) o;
p = doc.createElement("command");
String code = getCodeRange(source, cs.getStart(), cs.getEnd());
if (code == null) {
throw new NullPointerException("failed to get source from "
+ cs.getStart() + " to " + cs.getEnd());
}
p.setAttribute("text", code);
} else if (o instanceof QuotesSubstitution) {
p = doc.createElement("quotes");
// String rawText = ((QuotesSubstitution)o).getRawText();
String rawText = getCodeRange(source,
((QuotesSubstitution) o).getStart(),
((QuotesSubstitution) o).getEnd());
if (rawText == null)
throw new NullPointerException(
o.toString() + " has null raw text");
p.setAttribute("text", rawText);
} else if (o instanceof BracesSubstitution) {
p = doc.createElement("braces");
// String rawText = ((BracesSubstitution)o).getRawText();
String rawText = getCodeRange(source,
((BracesSubstitution) o).getStart(),
((BracesSubstitution) o).getEnd());
if (rawText == null)
throw new NullPointerException(
o.toString() + " has null raw text");
p.setAttribute("text", rawText);
} else if (o instanceof VariableSubstitution) {
p = doc.createElement("variable");
VariableSubstitution vs = (VariableSubstitution) o;
p.setAttribute("start", Integer.toString(vs.getStart()));
p.setAttribute("end", Integer.toString(vs.getEnd()));
p.setAttribute("kind", Integer.toString(vs.getKind()));
if (vs.getName() == null)
throw new NullPointerException(
o.toString() + " has null name");
p.setAttribute("name", vs.getName());
if (vs.getIndex() != null)
p.appendChild(getWordAsNode(source, vs.getIndex(), doc));
} else if (o instanceof NormalBackslashSubstitution) {
p = doc.createElement("normalbs");
// String rawText =
// ((NormalBackslashSubstitution)o).getRawText();
String rawText = getCodeRange(source,
((NormalBackslashSubstitution) o).getStart(),
((NormalBackslashSubstitution) o).getEnd());
if (rawText == null)
throw new NullPointerException(
o.toString() + " has null raw text");
p.setAttribute("text", rawText);
} else if (o instanceof MagicBackslashSubstitution) {
p = doc.createElement("newlinebs");
}
w.appendChild(p);
}
return w;
}
private Node getXML(String source, TclScript s, Document doc) {
Element script = doc.createElement("script");
doc.appendChild(script);
List<TclCommand> cmd = s.getCommands();
for (TclCommand c : cmd) {
Element command = doc.createElement("command");
command.setAttribute("start", Integer.toString(c.getStart()));
command.setAttribute("end", Integer.toString(c.getEnd()));
script.appendChild(command);
List<TclWord> words = c.getWords();
for (TclWord word : words) {
Node w = getWordAsNode(source, word, doc);
command.appendChild(w);
}
}
return script;
}
private void megaprint(String source, TclScript result) {
String xml;
try {
xml = serializeDocument(createXMLFromSource(source, result));
System.out.println(xml);
} catch (IOException | TransformerException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void runTestOn(String name) throws Exception {
System.out.println("Running " + name);
URL in = Activator.getDefault().getBundle().getEntry(name);
URL ans = Activator.getDefault().getBundle().getEntry(name + ".xml");
if (in == null || ans == null)
throw new Exception();
try {
String content = getContents(in);
TclScript s = SimpleTclParser.staticParse(content);
Document docFromSource = createXMLFromSource(content, s);
String resultXML = serializeDocument(docFromSource);
String expectedXML = serializeDocument(parseXML(getContents(ans)));
assertEquals(expectedXML, resultXML);
} catch (IOException e) {
e.printStackTrace();
}
}
public void _testAll() throws Exception {
Enumeration<String> e = Activator.getDefault().getBundle()
.getEntryPaths("rawtests/");
while (e.hasMoreElements()) {
String o = e.nextElement();
System.out.println("found test " + o);
// runTestOn ((new Path(o.toString())).lastSegment());
runTestOn(o);
}
}
@Test
public void test0() throws Exception {
runTestOn("rawtests/0.tcl");
}
@Test
public void test1() throws Exception {
runTestOn("rawtests/1.tcl");
}
@Test
public void test2() throws Exception {
runTestOn("rawtests/2.tcl");
}
@Test
public void test3() throws Exception {
runTestOn("rawtests/3.tcl");
}
@Test
public void test4() throws Exception {
runTestOn("rawtests/4.tcl");
}
@Test
public void test5() throws Exception {
runTestOn("rawtests/5.tcl");
}
@Test
public void test6() throws Exception {
runTestOn("rawtests/6.tcl");
}
@Test
public void test7() throws Exception {
runTestOn("rawtests/simple0.tcl");
}
@Test
public void test8() throws Exception {
runTestOn("rawtests/simple1.tcl");
}
@Test
public void test9() throws Exception {
runTestOn("rawtests/simple3.tcl");
}
@Test
public void test10() throws Exception {
runTestOn("rawtests/all.tcl");
}
@Test
public void test11() throws Exception {
runTestOn("rawtests/a.tcl");
}
@Test
public void test12() throws Exception {
String content = "\r\n puts $a ; puts \"wow!\"\r";
SimpleTclParser.staticParse(content);
}
@Test
public void test13() throws Exception {
runTestOn("rawtests/7.tcl");
}
@Test
public void test14() throws Exception {
runTestOn("rawtests/8.tcl");
}
@Test
public void test15() throws Exception {
runTestOn("rawtests/9.tcl");
}
@Test
public void test16() throws Exception {
runTestOn("rawtests/b.tcl");
}
@Test
public void test17() throws Exception {
runTestOn("rawtests/c.tcl");
}
@Test
public void test18() throws Exception {
runTestOn("rawtests/d.tcl");
}
@Test
public void test19() throws Exception {
runTestOn("rawtests/e.tcl");
}
@Test
public void test20() throws Exception {
runTestOn("rawtests/f.tcl");
}
@Test
public void test21() throws Exception {
runTestOn("rawtests/g.tcl");
}
public void _testUtil() throws Exception { // used to visually in-place
// debug
// String content = "{ \r\n variable asdf\r\n variable {[<>#%\"]} \r\n
// \r\n \r\n proc foo {} {\r\n \n }\n \n}";
String content = "lreplace $list $index $index $newValue";
// URL in =
// TestsPlugin.getDefault().getBundle().getEntry("rawtests/all.tcl");
// String content = getContents(in);
TclScript s = SimpleTclParser.staticParse(content);
print(s);
megaprint(content, s);
}
}