1 /****************************************************************************
2 **
3 ** Copyright (C) 2015 The Qt Company Ltd.
4 ** Contact: http://www.qt.io/licensing/
5 **
6 ** This file is part of the test suite of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see http://www.qt.io/terms-conditions. For further
15 ** information use the contact form at http://www.qt.io/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 or version 3 as published by the Free
20 ** Software Foundation and appearing in the file LICENSE.LGPLv21 and
21 ** LICENSE.LGPLv3 included in the packaging of this file. Please review the
22 ** following information to ensure the GNU Lesser General Public License
23 ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
24 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25 **
26 ** As a special exception, The Qt Company gives you certain additional
27 ** rights. These rights are described in The Qt Company LGPL Exception
28 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29 **
30 ** GNU General Public License Usage
31 ** Alternatively, this file may be used under the terms of the GNU
32 ** General Public License version 3.0 as published by the Free Software
33 ** Foundation and appearing in the file LICENSE.GPL included in the
34 ** packaging of this file.  Please review the following information to
35 ** ensure the GNU General Public License version 3.0 requirements will be
36 ** met: http://www.gnu.org/copyleft/gpl.html.
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 #include <QFileInfo>
43 #include <QVariant>
44 #include <QXmlInputSource>
45 #include <QXmlSimpleReader>
46 #include <QtDebug>
47 
48 #include "Global.h"
49 #include "TestSuiteHandler.h"
50 #include "TestSuiteResult.h"
51 #include "XMLWriter.h"
52 #include "XSLTTestSuiteHandler.h"
53 #include "XSDTestSuiteHandler.h"
54 #include "qdebug_p.h"
55 
56 #include "TestSuite.h"
57 
58 using namespace QPatternistSDK;
59 using namespace QPatternist;
60 
TestSuite()61 TestSuite::TestSuite()
62 {
63 }
64 
data(const Qt::ItemDataRole role,int column) const65 QVariant TestSuite::data(const Qt::ItemDataRole role, int column) const
66 {
67     if(role != Qt::DisplayRole)
68         return QVariant();
69 
70     switch(column)
71     {
72         case 0:
73             return title();
74         case 1:
75             return QString();
76         default:
77         {
78             Q_ASSERT(false);
79             return QString();
80         }
81     }
82 }
83 
runSuite()84 TestSuiteResult *TestSuite::runSuite()
85 {
86     const QDate date(QDate::currentDate());
87     TestResult::List result(execute(CompileAndRun, this));
88 
89     return new TestSuiteResult(version(), date, result);
90 }
91 
openCatalog(const QUrl & catalogURI,QString & errorMsg,const bool useExclusionList,SuiteType suiteType)92 TestSuite *TestSuite::openCatalog(const QUrl &catalogURI,
93                                   QString &errorMsg,
94                                   const bool useExclusionList,
95                                   SuiteType suiteType)
96 {
97     pDebug() << "Opening catalog:" << catalogURI.toString();
98     QFile ts(catalogURI.toLocalFile());
99     Q_ASSERT(catalogURI.isValid());
100 
101     if(!ts.exists())
102     {
103         errorMsg = QString::fromLatin1("The test suite catalog \"%1\" could not be found.\n")
104                                        .arg(ts.fileName());
105         return 0;
106     }
107 
108     const QFileInfo info(ts);
109 
110     if(!info.isReadable())
111     {
112         errorMsg = QString::fromLatin1("Cannot read the test suite catalog.\n");
113         return 0;
114     }
115     else if(!info.isFile())
116     {
117         errorMsg = QString::fromLatin1("The specified test suite catalog \"%1\" is not a file. "
118                                        "The test suite catalog must be a file, it cannot be "
119                                        "a directory, for example.\n")
120                                        .arg(ts.fileName());
121         return 0;
122     }
123     else if(!ts.open(QIODevice::ReadOnly | QIODevice::Text))
124     {
125         errorMsg = QString::fromLatin1("Failed to open the test suite catalog, \"%1\".\n")
126                                        .arg(ts.fileName());
127         return 0;
128     }
129 
130     return openCatalog(&ts, errorMsg, catalogURI, useExclusionList, suiteType);
131 }
132 
openCatalog(QIODevice * input,QString & errorMsg,const QUrl & fileName,const bool useExclusionList,SuiteType suiteType)133 TestSuite *TestSuite::openCatalog(QIODevice *input,
134                                   QString &errorMsg,
135                                   const QUrl &fileName,
136                                   const bool useExclusionList,
137                                   SuiteType suiteType)
138 {
139     Q_ASSERT(input);
140 
141     QXmlSimpleReader reader;
142     typedef QPatternist::AutoPtr<QXmlDefaultHandler> HandlerPtr;
143 
144     HandlerPtr loader;
145 
146     switch (suiteType) {
147         case XQuerySuite: loader = HandlerPtr(new TestSuiteHandler(fileName, useExclusionList)); break;
148         case XsltSuite: loader = HandlerPtr(new XSLTTestSuiteHandler(fileName)); break;
149         case XsdSuite: loader = HandlerPtr(new XSDTestSuiteHandler(fileName)); break;
150         default: Q_ASSERT(false); break;
151     }
152 
153     reader.setContentHandler(loader.data());
154     reader.setEntityResolver(loader.data());
155 
156     QXmlInputSource source(input);
157 
158     if(!reader.parse(source))
159     {
160         errorMsg = QString::fromLatin1("Couldn't parse %1").arg(fileName.toString());
161         return 0;
162     }
163 
164     TestSuite *suite = 0;
165     switch (suiteType) {
166         case XQuerySuite: suite = static_cast<TestSuiteHandler *>(loader.data())->testSuite(); break;
167         case XsltSuite: suite = static_cast<XSLTTestSuiteHandler *>(loader.data())->testSuite(); break;
168         case XsdSuite: suite = static_cast<XSDTestSuiteHandler *>(loader.data())->testSuite(); break;
169         default: Q_ASSERT(false); break;
170     }
171 
172     if(suite)
173         return suite;
174 
175     errorMsg = QString::fromLatin1("Failed to load \"%1\". "
176                                    "It appears to have no test-suite element.\n").arg(fileName.toString());
177     return 0;
178 }
179 
toXML(XMLWriter & receiver,TestCase * const tc) const180 void TestSuite::toXML(XMLWriter &receiver, TestCase *const tc) const
181 {
182     // TODO startElement() endElement() calls can be simplified.
183 
184     Q_ASSERT(tc);
185 
186     receiver.startDocument();
187     /* <test-suite> */
188     QXmlAttributes test_suiteAtts;
189     test_suiteAtts.append(QLatin1String("CatalogDesignDate"), QString(),
190                           QLatin1String("CatalogDesignDate"), m_designDate.toString(Qt::ISODate));
191     test_suiteAtts.append(QLatin1String("version"), QString(),
192                           QLatin1String("version"), m_version);
193     test_suiteAtts.append(QLatin1String("SourceOffsetPath"), QString(),
194                           QLatin1String("SourceOffsetPath"), QString());
195     test_suiteAtts.append(QLatin1String("ResultOffsetPath"), QString(),
196                           QLatin1String("ResultOffsetPath"), QString());
197     test_suiteAtts.append(QLatin1String("XQueryQueryOffsetPath"), QString(),
198                           QLatin1String("XQueryQueryOffsetPath"), QString());
199     test_suiteAtts.append(QLatin1String("QueryXQueryOffsetPath"), QString(),
200                           QLatin1String("QueryXQueryOffsetPath"), QString());
201     test_suiteAtts.append(QLatin1String("XQueryFileExtension"), QString(),
202                           QLatin1String("XQueryFileExtension"), QString());
203     test_suiteAtts.append(QLatin1String("XQueryXFileExtension"), QString(),
204                           QLatin1String("XQueryXFileExtension"), QString());
205 
206     receiver.startPrefixMapping(QString(), Global::xqtsCatalogNS);
207     receiver.startElement(QLatin1String("test-suite"), test_suiteAtts);
208     receiver.endPrefixMapping(QString());
209 
210     /* <test-group> */
211     QXmlAttributes test_groupAtts;
212     test_groupAtts.append(QLatin1String("GeneratedGroupByPatternistSDKRunSuite"), QString(),
213                           QLatin1String("GeneratedGroupByPatternistSDKRunSuite"), QString());
214     receiver.startElement(QLatin1String("test-group"), test_groupAtts);
215 
216     /* <GroupInfo> */
217     receiver.startElement(QLatin1String("GroupInfo"), test_groupAtts);
218 
219     /* <title> */
220     receiver.startElement(QLatin1String("title"), test_groupAtts);
221     receiver.characters(QLatin1String("Contains the test case generated by PatternistSDKRunSuite."));
222 
223     /* </title> */
224     receiver.endElement(QLatin1String("title"));
225 
226     /* <description> */
227     receiver.startElement(QLatin1String("description"), test_groupAtts);
228     /* </description> */
229     receiver.endElement(QLatin1String("description"));
230 
231     /* </GroupInfo> */
232     receiver.endElement(QLatin1String("GroupInfo"));
233 
234     /* <test-case> */
235     tc->toXML(receiver);
236     /* </test-case> */
237 
238     /* </test-group> */
239     receiver.endElement(QLatin1String("test-group"));
240 
241     /* </test-suite> */
242     receiver.endElement(QLatin1String("test-suite"));
243 }
244 
version() const245 QString TestSuite::version() const
246 {
247     return m_version;
248 }
249 
designDate() const250 QDate TestSuite::designDate() const
251 {
252     return m_designDate;
253 }
254 
setVersion(const QString & ver)255 void TestSuite::setVersion(const QString &ver)
256 {
257     m_version = ver;
258 }
259 
setDesignDate(const QDate & date)260 void TestSuite::setDesignDate(const QDate &date)
261 {
262     m_designDate = date;
263 }
264 
parent() const265 TestContainer *TestSuite::parent() const
266 {
267     return 0;
268 }
269 
270 // vim: et:ts=4:sw=4:sts=4
271