Warning, file /frameworks/khtml/src/xpath/interpreter_tester.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 /* 0002 * interpreter_tester.cpp - Copyright 2005 Frerich Raabe <raabe@kde.org> 0003 * 0004 * Redistribution and use in source and binary forms, with or without 0005 * modification, are permitted provided that the following conditions 0006 * are met: 0007 * 0008 * 1. Redistributions of source code must retain the above copyright 0009 * notice, this list of conditions and the following disclaimer. 0010 * 2. Redistributions in binary form must reproduce the above copyright 0011 * notice, this list of conditions and the following disclaimer in the 0012 * documentation and/or other materials provided with the distribution. 0013 * 0014 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 0015 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 0016 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 0017 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 0018 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 0019 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 0020 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 0021 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 0022 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 0023 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 0024 */ 0025 #include "expression.h" 0026 #include "parsedstatement.h" 0027 0028 #include "XPathExceptionImpl.h" 0029 0030 #include "DocumentImpl.h" 0031 #include "DOMStringImpl.h" 0032 #include "KDOMParser.h" 0033 #include "KDOMParserFactory.h" 0034 #include "NamedAttrMapImpl.h" 0035 0036 #include "kdom.h" 0037 0038 #include <QApplication> 0039 #include <QBuffer> 0040 #include <QtDebug> 0041 0042 using namespace KDOM; 0043 0044 void check(DocumentImpl *doc, const QString &statement, const QString &expected) 0045 { 0046 ParsedStatement s(statement); 0047 Value result = s.evaluate(doc); 0048 if (!result.isString()) { 0049 qDebug("ERROR: Query '%s' did not return a string!", statement.latin1()); 0050 exit(1); 0051 } 0052 0053 QString string = result.toString(); 0054 if (string != expected) { 0055 qDebug("ERROR: Failed to interprete '%s' correctly!", statement.latin1()); 0056 qDebug("Expected to get: %s", expected.latin1()); 0057 qDebug("Got : %s", string.latin1()); 0058 exit(1); 0059 } 0060 } 0061 0062 void check(DocumentImpl *doc, const QString &statement, double expected) 0063 { 0064 ParsedStatement s(statement); 0065 Value result = s.evaluate(doc); 0066 if (!result.isNumber()) { 0067 qDebug("ERROR: Query '%s' did not return a number!", statement.latin1()); 0068 exit(1); 0069 } 0070 0071 double number = result.toNumber(); 0072 if (number != expected) { 0073 qDebug("ERROR: Failed to interprete '%s' correctly!", statement.latin1()); 0074 qDebug("Expected to get: %f", expected); 0075 qDebug("Got : %f", number); 0076 exit(1); 0077 } 0078 } 0079 0080 void check(DocumentImpl *doc, const QString &statement, 0081 const QStringList &idsOfExpectedMatches) 0082 { 0083 ParsedStatement s(statement); 0084 Value result = s.evaluate(doc); 0085 if (!result.isNodeset()) { 0086 qDebug("ERROR: Query '%s' did not return a nodeset!", statement.latin1()); 0087 exit(1); 0088 } 0089 0090 QStringList idsOfResultMatches; 0091 0092 DomNodeList nodes = result.toNodeset(); 0093 foreach (NodeImpl *node, nodes) { 0094 if (node->nodeType() != ELEMENT_NODE) { 0095 continue; 0096 } 0097 NodeImpl *idNode = 0; 0098 NamedAttrMapImpl *attrs = node->attributes(true /*read-only*/); 0099 for (unsigned long i = 0; i < attrs->length(); ++i) { 0100 idNode = attrs->item(i); 0101 if (idNode->nodeName()->string() == "id") { 0102 break; 0103 } 0104 } 0105 if (!idNode) { 0106 qDebug("ERROR: Found match without id attribute!"); 0107 exit(1); 0108 } 0109 idsOfResultMatches.append(idNode->nodeValue()->string()); 0110 } 0111 0112 bool failure = false; 0113 0114 foreach (QString id, idsOfExpectedMatches) { 0115 if (!idsOfResultMatches.contains(id)) { 0116 failure = true; 0117 break; 0118 } 0119 } 0120 0121 if (!failure) { 0122 foreach (QString id, idsOfResultMatches) { 0123 if (!idsOfExpectedMatches.contains(id)) { 0124 failure = true; 0125 break; 0126 } 0127 } 0128 } 0129 0130 if (failure) { 0131 qCDebug(KHTML_LOG) << "ERROR: Failed to interprete '" << statement << "' correctly!"; 0132 qCDebug(KHTML_LOG) << "Expected to match: " << idsOfExpectedMatches.join(","); 0133 qCDebug(KHTML_LOG) << "Got matches : " << idsOfResultMatches.join(","); 0134 exit(1); 0135 } 0136 } 0137 0138 int main(int argc, char **argv) 0139 { 0140 QString bookMarkup = 0141 "<book id=\"1\">" 0142 "<abstract id=\"2\">" 0143 "</abstract>" 0144 "<chapter id=\"3\" title=\"Introduction\">" 0145 "<para id=\"4\">Blah blah blah</para>" 0146 "<para id=\"5\">Foo bar yoyodyne</para>" 0147 "</chapter>" 0148 "<chapter id=\"6\" title=\"TEST\" type=\"x\">" 0149 "<para id=\"7\">My sister got bitten by a yak.</para>" 0150 "</chapter>" 0151 "<chapter id=\"8\" title=\"note\" type=\"y\">" 0152 "<para id=\"9\">141,000</para>" 0153 "</chapter>" 0154 "<chapter id=\"10\" title=\"note\">" 0155 "<para id=\"11\">Hell yeah, yaks are nice.</para>" 0156 "</chapter>" 0157 "</book>"; 0158 0159 QApplication::setApplicationName("interpreter_tester"); 0160 0161 QApplication app(argc, argv); 0162 0163 // Parser::syncParse called blow deletes the given buffer, so we 0164 // cannot use QBuffer objects which live on the stack. 0165 QBuffer *buf = new QBuffer; 0166 buf->open(QBuffer::ReadWrite); 0167 buf->write(bookMarkup.toUtf8()); 0168 0169 // I can't believe that I have to go through all these hoops to get 0170 // a DocumentImpl* out of a string with markup. 0171 Parser *parser = ParserFactory::self()->request(KURL(), 0, "qxml"); 0172 DocumentImpl *doc = parser->syncParse(buf); 0173 0174 try { 0175 check(doc, "/book", QStringList() << "1"); 0176 check(doc, "/book/chapter", QStringList() << "3" << "6" << "8"); 0177 check(doc, "/book/chapter[@title=\"TEST\"]", QStringList() << "6"); 0178 check(doc, "/book/chapter[last()-1]", QStringList() << "8"); 0179 check(doc, "/book/chapter[contains(string(@title), \"tro\")]", QStringList() << "3"); 0180 check(doc, "//para", QStringList() << "4" << "5" << "7" << "9"); 0181 check(doc, "/book/chapter[position()=2]/following::*", QStringList() << "8" << "9"); 0182 check(doc, "//chapter[@title and @type]", QStringList() << "6" << "8"); 0183 check(doc, "/book/chapter[attribute::title = \"note\"][position() = 2]", QStringList() << "10"); 0184 check(doc, "count(//para)", 5.0); 0185 check(doc, "string(/book/chapter/para[text() = \"Foo bar yoyodyne\" ])", QLatin1String("Foo bar yoyodyne")); 0186 check(doc, "substring-before(/book/chapter/para[@id=\"9\" ], ',' )", QLatin1String("141")); 0187 } catch (XPath::XPathExceptionImpl *e) { 0188 qDebug("Caught XPath exception '%s'.", e->codeAsString().latin1()); 0189 delete e; 0190 return 1; 0191 } 0192 0193 qDebug("All OK!"); 0194 } 0195