KHtml

interpreter_tester.cpp
1 /*
2  * interpreter_tester.cpp - Copyright 2005 Frerich Raabe <[email protected]>
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  * notice, this list of conditions and the following disclaimer in the
12  * documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
18  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25 #include "expression.h"
26 #include "parsedstatement.h"
27 
28 #include "XPathExceptionImpl.h"
29 
30 #include "DocumentImpl.h"
31 #include "DOMStringImpl.h"
32 #include "KDOMParser.h"
33 #include "KDOMParserFactory.h"
34 #include "NamedAttrMapImpl.h"
35 
36 #include "kdom.h"
37 
38 #include <QApplication>
39 #include <QBuffer>
40 #include <QtDebug>
41 
42 using namespace KDOM;
43 
44 void check(DocumentImpl *doc, const QString &statement, const QString &expected)
45 {
46  ParsedStatement s(statement);
47  Value result = s.evaluate(doc);
48  if (!result.isString()) {
49  qDebug("ERROR: Query '%s' did not return a string!", statement.latin1());
50  exit(1);
51  }
52 
53  QString string = result.toString();
54  if (string != expected) {
55  qDebug("ERROR: Failed to interprete '%s' correctly!", statement.latin1());
56  qDebug("Expected to get: %s", expected.latin1());
57  qDebug("Got : %s", string.latin1());
58  exit(1);
59  }
60 }
61 
62 void check(DocumentImpl *doc, const QString &statement, double expected)
63 {
64  ParsedStatement s(statement);
65  Value result = s.evaluate(doc);
66  if (!result.isNumber()) {
67  qDebug("ERROR: Query '%s' did not return a number!", statement.latin1());
68  exit(1);
69  }
70 
71  double number = result.toNumber();
72  if (number != expected) {
73  qDebug("ERROR: Failed to interprete '%s' correctly!", statement.latin1());
74  qDebug("Expected to get: %f", expected);
75  qDebug("Got : %f", number);
76  exit(1);
77  }
78 }
79 
80 void check(DocumentImpl *doc, const QString &statement,
81  const QStringList &idsOfExpectedMatches)
82 {
83  ParsedStatement s(statement);
84  Value result = s.evaluate(doc);
85  if (!result.isNodeset()) {
86  qDebug("ERROR: Query '%s' did not return a nodeset!", statement.latin1());
87  exit(1);
88  }
89 
90  QStringList idsOfResultMatches;
91 
92  DomNodeList nodes = result.toNodeset();
93  foreach (NodeImpl *node, nodes) {
94  if (node->nodeType() != ELEMENT_NODE) {
95  continue;
96  }
97  NodeImpl *idNode = 0;
98  NamedAttrMapImpl *attrs = node->attributes(true /*read-only*/);
99  for (unsigned long i = 0; i < attrs->length(); ++i) {
100  idNode = attrs->item(i);
101  if (idNode->nodeName()->string() == "id") {
102  break;
103  }
104  }
105  if (!idNode) {
106  qDebug("ERROR: Found match without id attribute!");
107  exit(1);
108  }
109  idsOfResultMatches.append(idNode->nodeValue()->string());
110  }
111 
112  bool failure = false;
113 
114  foreach (QString id, idsOfExpectedMatches) {
115  if (!idsOfResultMatches.contains(id)) {
116  failure = true;
117  break;
118  }
119  }
120 
121  if (!failure) {
122  foreach (QString id, idsOfResultMatches) {
123  if (!idsOfExpectedMatches.contains(id)) {
124  failure = true;
125  break;
126  }
127  }
128  }
129 
130  if (failure) {
131  qCDebug(KHTML_LOG) << "ERROR: Failed to interprete '" << statement << "' correctly!";
132  qCDebug(KHTML_LOG) << "Expected to match: " << idsOfExpectedMatches.join(",");
133  qCDebug(KHTML_LOG) << "Got matches : " << idsOfResultMatches.join(",");
134  exit(1);
135  }
136 }
137 
138 int main(int argc, char **argv)
139 {
140  QString bookMarkup =
141  "<book id=\"1\">"
142  "<abstract id=\"2\">"
143  "</abstract>"
144  "<chapter id=\"3\" title=\"Introduction\">"
145  "<para id=\"4\">Blah blah blah</para>"
146  "<para id=\"5\">Foo bar yoyodyne</para>"
147  "</chapter>"
148  "<chapter id=\"6\" title=\"TEST\" type=\"x\">"
149  "<para id=\"7\">My sister got bitten by a yak.</para>"
150  "</chapter>"
151  "<chapter id=\"8\" title=\"note\" type=\"y\">"
152  "<para id=\"9\">141,000</para>"
153  "</chapter>"
154  "<chapter id=\"10\" title=\"note\">"
155  "<para id=\"11\">Hell yeah, yaks are nice.</para>"
156  "</chapter>"
157  "</book>";
158 
159  QApplication::setApplicationName("interpreter_tester");
160 
161  QApplication app(argc, argv);
162 
163  // Parser::syncParse called blow deletes the given buffer, so we
164  // cannot use QBuffer objects which live on the stack.
165  QBuffer *buf = new QBuffer;
166  buf->open(QBuffer::ReadWrite);
167  buf->write(bookMarkup.toUtf8());
168 
169  // I can't believe that I have to go through all these hoops to get
170  // a DocumentImpl* out of a string with markup.
171  Parser *parser = ParserFactory::self()->request(KURL(), 0, "qxml");
172  DocumentImpl *doc = parser->syncParse(buf);
173 
174  try {
175  check(doc, "/book", QStringList() << "1");
176  check(doc, "/book/chapter", QStringList() << "3" << "6" << "8");
177  check(doc, "/book/chapter[@title=\"TEST\"]", QStringList() << "6");
178  check(doc, "/book/chapter[last()-1]", QStringList() << "8");
179  check(doc, "/book/chapter[contains(string(@title), \"tro\")]", QStringList() << "3");
180  check(doc, "//para", QStringList() << "4" << "5" << "7" << "9");
181  check(doc, "/book/chapter[position()=2]/following::*", QStringList() << "8" << "9");
182  check(doc, "//chapter[@title and @type]", QStringList() << "6" << "8");
183  check(doc, "/book/chapter[attribute::title = \"note\"][position() = 2]", QStringList() << "10");
184  check(doc, "count(//para)", 5.0);
185  check(doc, "string(/book/chapter/para[text() = \"Foo bar yoyodyne\" ])", QLatin1String("Foo bar yoyodyne"));
186  check(doc, "substring-before(/book/chapter/para[@id=\"9\" ], ',' )", QLatin1String("141"));
187  } catch (XPath::XPathExceptionImpl *e) {
188  qDebug("Caught XPath exception '%s'.", e->codeAsString().latin1());
189  delete e;
190  return 1;
191  }
192 
193  qDebug("All OK!");
194 }
195 
bool contains(const QString &str, Qt::CaseSensitivity cs) const const
QString join(const QString &separator) const const
KIOCORE_EXPORT QString number(KIO::filesize_t size)
void append(const T &value)
virtual bool open(QIODevice::OpenMode flags) override
qint64 write(const char *data, qint64 maxSize)
void setApplicationName(const QString &application)
QByteArray toUtf8() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2021 The KDE developers.
Generated on Mon Oct 25 2021 22:48:16 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.