📄 runxqts.java
字号:
package gnu.xquery.testsuite;import java.io.*;import java.util.*;import gnu.lists.*;import gnu.text.*;import gnu.mapping.*;import gnu.expr.*;import gnu.xml.*;import gnu.kawa.xml.*;import gnu.mapping.Symbol;import gnu.xquery.lang.*;import org.xml.sax.helpers.AttributesImpl;import gnu.xquery.util.NodeUtils;/** Run a suite of XQuery tests, as read from an xml file. */public class RunXQTS extends FilterConsumer{ static XQuery xqueryLanguage = XQuery.getInstance(); /* #ifdef JAVA5 */ // HashMap<String,String> expectedFailures = new HashMap<String,String>(); // HashMap<String,String> modules = new HashMap<String,String>(); // HashMap<String,Object> sources = new HashMap<String,Object>(); // Stack<Symbol> externalVariablesSet = new Stack<Symbol>(); // Stack<String> outputFileAlts = new Stack<String>(); // Stack<String> outputCompareAlts = new Stack<String>(); /* #else */ Hashtable expectedFailures = new Hashtable(); Hashtable modules = new Hashtable(); Hashtable sources = new Hashtable(); Stack externalVariablesSet = new Stack(); Stack outputFileAlts = new Stack(); Stack outputCompareAlts = new Stack(); /* #endif */ ModuleManager manager = ModuleManager.getInstance(); Object failExpected; boolean verbose = true; boolean useComments = true; String directory; String catalog; String XQTSVersion; String ResultOffsetPath; String XQueryQueryOffsetPath; String XQueryXQueryOffsetPath; String XQueryFileExtension; String XQueryXFileExtension; Object contextItem; int passCount; int xpassCount; int failCount; int xfailCount; int cannotTellCount; /** Set of expected error codes. The format is "|Error1|..|ErrorN|". */ StringBuffer expectedErrorsBuf = new StringBuffer("|"); /** Same as expectedErrorBuf.toString() after collecting expected-errors. */ String expectedErrors; String logFileName = "XQTS.log"; XMLPrinter xqlog; String collectionID; Values collectionDocuments; private void summaryReport (int count, String label) { if (count > 0) { System.out.print(label); System.out.println(count); } } private void summaryReport () { summaryReport(passCount, "# of expected passes "); summaryReport(xfailCount, "# of expected failures "); summaryReport(xpassCount, "# of unexpected successes "); summaryReport(failCount, "# of unexpected failures "); summaryReport(cannotTellCount, "# of cannot-tell (Inspect) results "); } public static final String XQTS_RESULT_NAMESPACE = "http://www.w3.org/2005/02/query-test-XQTSResult"; static Object testSuiteResultElementType; static { NamespaceBinding namespaceNodes = new NamespaceBinding(null, XQTS_RESULT_NAMESPACE, new NamespaceBinding("q", XQuery.QEXO_FUNCTION_NAMESPACE, NamespaceBinding.predefinedXML)); Symbol sym = Symbol.make(XQTS_RESULT_NAMESPACE, "test-suite-result", ""); testSuiteResultElementType = new XName(sym, namespaceNodes); } static Object testRunElementType = Symbol.make(XQTS_RESULT_NAMESPACE, "test-run", ""); static Object testSuiteElementType = Symbol.make(XQTS_RESULT_NAMESPACE, "test-suite", ""); static Object testCaseElementType = Symbol.make(XQTS_RESULT_NAMESPACE, "test-case", ""); private void writeStartElement (String name) { xqlog.startElement(Symbol.make(XQTS_RESULT_NAMESPACE, name, "")); } private void writeStartAttribute (String name) { xqlog.startAttribute(name); } private void writeAttribute (String name, String value) { writeStartAttribute(name); xqlog.write(value); xqlog.endAttribute(); } private void writeQexoAttribute (String name, String value) { xqlog.startAttribute(Symbol.make(XQuery.QEXO_FUNCTION_NAMESPACE, name, "q")); xqlog.write(value); xqlog.endAttribute(); } private void writeVerbose (String name, String value) { if (useComments) { // The tricky part is to make sure that the result can be validated. // Specifically, no spaces are allowed in a <test-case>. xqlog.printIndent = -1; xqlog.beginComment(); xqlog.printIndent = 0; xqlog.writeBreakFill(); xqlog.write(name); xqlog.write(": "); xqlog.write(value); xqlog.writeBreakFill(); xqlog.endComment(); } else writeQexoAttribute(name, value); } public static void main (String[] args) { gnu.xquery.lang.XQuery.registerEnvironment(); Language.requirePedantic = true; for (int i = 0; i < args.length; i++) { try { RunXQTS runner = new RunXQTS(new CharArrayOutPort()); runner.directory = args[i]; runner.catalog = runner.directory + "/XQTSCatalog.xml"; System.err.println("catalog: "+runner.catalog); XMLPrinter xqlog = new XMLPrinter(new BufferedOutputStream(new FileOutputStream(runner.logFileName)), FilePath.valueOf(runner.logFileName)); runner.xqlog = xqlog; xqlog.setPrintXMLdecl(true); xqlog.setStyle("xml"); xqlog.useEmptyElementTag = 1; Object saveIndent = XMLPrinter.indentLoc.get(null); XMLPrinter.indentLoc.set("pretty"); xqlog.startDocument(); XMLPrinter.indentLoc.set(saveIndent); Document.parse(runner.catalog, runner); xqlog.endDocument(); runner.summaryReport(); xqlog.close(); } catch (Throwable ex) { ex.printStackTrace(); System.err.println("caught "+ex+" while processing "+args[i]); } } } int nesting = 0; Object currentElementType; Symbol currentElementSymbol; /* #ifdef JAVA5 */ // Stack<Object> elementTypeStack = new Stack<Object>(); /* #else */ Stack elementTypeStack = new Stack(); /* #endif */ boolean inStartTag; int attrValueStart; // Start in cout's buffer of current element, indexed by nesting level. int[] elementStartIndex = new int[20]; AttributesImpl attributes = new AttributesImpl(); String query = null; String expect = null; CharArrayOutPort cout; public RunXQTS(CharArrayOutPort out) { super(out); this.cout = out; expectFailures("K-ReplaceFunc-8", "allow bad regex replacement string"); expectFailures("K2-MatchesFunc-1", "allow bad regex pattern"); expectFailures("static-context-1", "unchecked unknownType in element(*,TypeName)"); expectFailures("fn-abs-more-args-023|fn-abs-more-args-024", "testsuite error (4023): -0 is not valid unsignedLong/unsignedShort literal"); expectFailures("ST-WhereExpr001", "testsuite error (4024) - should not require error"); expectFailures("K2-SeqExprCast-207", "was testsuite error(4252) - now mismatch between '>' and '>'"); /* #ifndef JAVA5 */ expectFailures("surrogates12|surrogates13|surrogates14|surrogates15", "surrogates not handled by java.util.regex"); /* #endif */ expectFailures("K-SeqExprInstanceOf-53", "too lenient about non-stanadrd types: void"); expectFailures("ST-Axes001|ST-Axes002|ST-Axes003|ST-Axes004|ST-Axes005|" +"ST-Axes006|ST-Axes007|ST-Axes008|ST-Axes009|ST-Axes010|" +"ST-Axes011|ST-Axes012|ST-Axes013|ST-Axes014|ST-Axes015", "depends on static typing feature"); expectFailures("fn-id-dtd-5|fn-id-dtd-7|fn-id-dtd-8|fn-id-dtd-9|" +"fn-id-dtd-12|fn-id-dtd-13|fn-id-dtd-15|fn-id-dtd-16|" +"fn-id-dtd-17|fn-id-dtd-18|fn-id-dtd-19|" +"fn-id-dtd-20|fn-id-dtd-21|fn-id-dtd-23|", "fn:id only works with xml:id so far"); expectFailures("fn-idref-dtd-5|fn-idref-dtd-7|fn-idref-dtd-8|" +"fn-idref-dtd-9|fn-idref-dtd-12|fn-idref-dtd-13|" +"fn-idref-dtd-14|fn-idref-dtd-15|fn-idref-dtd-16|" +"fn-idref-dtd-17|fn-idref-dtd-18|fn-idref-dtd-19|" +"fn-idref-dtd-20|fn-idref-dtd-21|fn-idref-dtd-23|", "fn:idref doesn't do much yet"); /* #ifndef use:java.text.Normalizer */ expectFailures("fn-normalize-unicode1args-1|" +"fn-normalize-unicode1args-2|" +"fn-normalize-unicode1args-3|" +"fn-normalize-unicode1args-4|" +"fn-normalize-unicode1args-5|" +"fn-normalize-unicode1args-6|" +"fn-normalize-unicode2args-1|" +"fn-normalize-unicode2args-2|" +"fn-normalize-unicode2args-3|" +"fn-normalize-unicode-1|" +"fn-normalize-unicode-3|fn-normalize-unicode-4|" +"fn-normalize-unicode-5|fn-normalize-unicode-6|" +"fn-normalize-unicode-7|K-NormalizeUnicodeFunc-4|" +"K-NormalizeUnicodeFunc-5|K-NormalizeUnicodeFunc-6|" +"K-NormalizeUnicodeFunc-7|K-NormalizeUnicodeFunc-8|" +"K-NormalizeUnicodeFunc-11|K-NormalizeUnicodeFunc-12", "fn:normalize-unicode not unimplemented yet"); /* #endif */ // RunXQTS failures rather than Qexo errors: // Some work under gcj but not JDK 1.4.x or 1.5.0_05: expectFailures("vardeclerr|K-InternalVariablesWith-17|K-InternalVariablesWith-18", "missing check for circular definitions"); expectFailures("K-TimeAddDTD-1|K-TimeAddDTD-2|K-TimeSubtractDTD-1", "bad interaction between fields and millis"); expectFailures("op-time-greater-than-2", "comparing xs:time doesn't handle differing timezones"); expectFailures("K-SubstringBeforeFunc-5|K-SubstringAfterFunc-5|" +"K-ContainsFunc-5|K-StartsWithFunc-5|K-EndsWithFunc-5", "some string functions don't support collation argument"); expectFailures("caselessmatch04", "regex/unicode special case"); expectFailures("string-queries-results-q4|K2-FunctionProlog-7|K2-FunctionProlog-17|K2-FunctionProlog-18|K2-FunctionProlog-19|K2-FunctionProlog-22", "function conversion incorrect for user-defined functions"); expectFailures("caselessmatch10|caselessmatch11", // Need to translate [xxx-[yyy]] to [xxx&&[^yyy]]. "regex range subtraction not implemented"); } private void expectFailures (String testNames, String reason) { while (testNames != null) { int dot = testNames.indexOf('|'); String testName; if (dot >= 0) { testName = testNames.substring(0, dot); testNames = testNames.substring(dot+1); } else { testName = testNames; testNames = null; } if (testName.length() > 0) expectedFailures.put(testName, reason); } } public void startElement(Object type) { if (inStartTag) handleStartTag(); attributes.clear(); inStartTag = true; elementTypeStack.push(currentElementType); currentElementType = type; currentElementSymbol = type instanceof Symbol ? (Symbol) type : null; /* System.err.println("startElement "+typeName); if ("test-suite".equals(typeName) && nesting == 0) inTestSuite = true; else if ("test-element".equals(typeName)) { } else if ("test".equals(typeName) && (nesting == 0 || (inTestSuite && nesting == 1))) inTest = true; else if (inTestSuite ? nesting == 2 : nesting == 1) { cout.setLength(0); currentTag = typeName; } else if (currentTag == null) throw new RuntimeException("saw <"+typeName+"> not in <test>"); else base.startElement(type); */ nesting++; } boolean tagMatches (String localName) { if (localName.equals(currentElementSymbol.getLocalName())) // also check uri FIXME return true; return false; } public void handleStartTag () { elementStartIndex[nesting] = cout.length(); if (tagMatches("test-suite")) { XQueryQueryOffsetPath = attributes.getValue("XQueryQueryOffsetPath"); XQueryXQueryOffsetPath = attributes.getValue("XQueryXQueryOffsetPath"); XQueryFileExtension = attributes.getValue("XQueryFileExtension"); XQueryXFileExtension = attributes.getValue("XQueryXFileExtension"); ResultOffsetPath = attributes.getValue("ResultOffsetPath"); XQTSVersion = attributes.getValue("version"); xqlog.startElement(testSuiteResultElementType); writeStartElement("implementation"); writeAttribute("name", "Qexo"); writeAttribute("version", kawa.Version.getVersion()); writeStartElement("organization"); writeAttribute("name", "GNU / Per Bothner"); xqlog.endElement(); writeStartElement("submittor"); String user = System.getProperty("user.name"); if ("bothner".equals(user)) { writeAttribute("name", "Per Bothner"); writeAttribute("email", "per@bothner.com"); } else writeAttribute("name", user); xqlog.endElement(); xqlog.endElement(); writeStartElement("syntax"); xqlog.write("XQuery"); xqlog.endElement(); xqlog.startElement(testRunElementType); StringBuffer sbuf = new StringBuffer(); gnu.kawa.xml.XTimeType.dateTimeType.now().toStringDate(sbuf); writeAttribute("dateRun", sbuf.toString()); xqlog.startElement(testSuiteElementType); writeAttribute("version", XQTSVersion); xqlog.endElement(); xqlog.endElement(); } else if (tagMatches("test-element")) { xqlog.writeComment("test-element "+attributes.getValue("name")); } else if (tagMatches("test-case")) { testName = attributes.getValue("name"); scenario = attributes.getValue("scenario"); testFilePath = attributes.getValue("FilePath"); testQueryName = null; outputFileAlts.clear(); outputCompareAlts.clear(); expectedErrorsBuf.setLength(1); manager.clear();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -