1 | /**************************************************************************** |
2 | ** |
3 | ** Copyright (C) 2016 The Qt Company Ltd. |
4 | ** Contact: https://www.qt.io/licensing/ |
5 | ** |
6 | ** This file is part of the autotests of the Qt Toolkit. |
7 | ** |
8 | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$ |
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 https://www.qt.io/terms-conditions. For further |
15 | ** information use the contact form at https://www.qt.io/contact-us. |
16 | ** |
17 | ** GNU General Public License Usage |
18 | ** Alternatively, this file may be used under the terms of the GNU |
19 | ** General Public License version 3 as published by the Free Software |
20 | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT |
21 | ** included in the packaging of this file. Please review the following |
22 | ** information to ensure the GNU General Public License requirements will |
23 | ** be met: https://www.gnu.org/licenses/gpl-3.0.html. |
24 | ** |
25 | ** $QT_END_LICENSE$ |
26 | ** |
27 | ****************************************************************************/ |
28 | |
29 | #include <QColor> |
30 | #include <QFile> |
31 | #include <QFileInfo> |
32 | #include <QVariant> |
33 | #include <QtDebug> |
34 | |
35 | #include "XSDTSTestCase.h" |
36 | |
37 | #include "qxmlschema.h" |
38 | #include "qxmlschemavalidator.h" |
39 | |
40 | using namespace QPatternistSDK; |
41 | using namespace QPatternist; |
42 | |
43 | XSDTSTestCase::XSDTSTestCase(const Scenario scen, TreeItem *p, TestType testType) |
44 | : m_scenario(scen) |
45 | , m_parent(p) |
46 | , m_testType(testType) |
47 | { |
48 | } |
49 | |
50 | XSDTSTestCase::~XSDTSTestCase() |
51 | { |
52 | qDeleteAll(c: m_baseLines); |
53 | } |
54 | |
55 | TestResult::List XSDTSTestCase::execute(const ExecutionStage, TestSuite*) |
56 | { |
57 | ErrorHandler errHandler; |
58 | ErrorHandler::installQtMessageHandler(handler: &errHandler); |
59 | |
60 | TestResult::List retval; |
61 | TestResult::Status resultStatus = TestResult::Unknown; |
62 | QString serialized; |
63 | |
64 | if (m_testType == SchemaTest) { |
65 | executeSchemaTest(resultStatus, serialized, handler: &errHandler); |
66 | } else { |
67 | executeInstanceTest(resultStatus, serialized, handler: &errHandler); |
68 | } |
69 | |
70 | resultStatus = TestBaseLine::scan(serialized, lines: baseLines()); |
71 | Q_ASSERT(resultStatus != TestResult::Unknown); |
72 | |
73 | m_result = new TestResult(name(), resultStatus, 0, errHandler.messages(), |
74 | QPatternist::Item::List(), serialized); |
75 | retval.append(t: m_result); |
76 | ErrorHandler::installQtMessageHandler(handler: 0); |
77 | changed(item: this); |
78 | return retval; |
79 | } |
80 | |
81 | void XSDTSTestCase::executeSchemaTest(TestResult::Status &resultStatus, QString &serialized, QAbstractMessageHandler *handler) |
82 | { |
83 | QFile file(m_schemaUri.path()); |
84 | if (!file.open(flags: QIODevice::ReadOnly)) { |
85 | resultStatus = TestResult::Fail; |
86 | serialized = QString(); |
87 | return; |
88 | } |
89 | |
90 | QXmlSchema schema; |
91 | schema.setMessageHandler(handler); |
92 | schema.load(source: &file, documentUri: m_schemaUri); |
93 | |
94 | if (schema.isValid()) { |
95 | resultStatus = TestResult::Pass; |
96 | serialized = QString::fromLatin1(str: "true" ); |
97 | } else { |
98 | resultStatus = TestResult::Pass; |
99 | serialized = QString::fromLatin1(str: "false" ); |
100 | } |
101 | } |
102 | |
103 | void XSDTSTestCase::executeInstanceTest(TestResult::Status &resultStatus, QString &serialized, QAbstractMessageHandler *handler) |
104 | { |
105 | QFile instanceFile(m_instanceUri.path()); |
106 | if (!instanceFile.open(flags: QIODevice::ReadOnly)) { |
107 | resultStatus = TestResult::Fail; |
108 | serialized = QString(); |
109 | return; |
110 | } |
111 | |
112 | QXmlSchema schema; |
113 | if (m_schemaUri.isValid()) { |
114 | QFile file(m_schemaUri.path()); |
115 | if (!file.open(flags: QIODevice::ReadOnly)) { |
116 | resultStatus = TestResult::Fail; |
117 | serialized = QString(); |
118 | return; |
119 | } |
120 | |
121 | schema.setMessageHandler(handler); |
122 | schema.load(source: &file, documentUri: m_schemaUri); |
123 | |
124 | if (!schema.isValid()) { |
125 | resultStatus = TestResult::Pass; |
126 | serialized = QString::fromLatin1(str: "false" ); |
127 | return; |
128 | } |
129 | } |
130 | |
131 | QXmlSchemaValidator validator(schema); |
132 | validator.setMessageHandler(handler); |
133 | |
134 | qDebug(msg: "check %s" , qPrintable(m_instanceUri.path())); |
135 | if (validator.validate(source: &instanceFile, documentUri: m_instanceUri)) { |
136 | resultStatus = TestResult::Pass; |
137 | serialized = QString::fromLatin1(str: "true" ); |
138 | } else { |
139 | resultStatus = TestResult::Pass; |
140 | serialized = QString::fromLatin1(str: "false" ); |
141 | } |
142 | } |
143 | |
144 | QVariant XSDTSTestCase::data(const Qt::ItemDataRole role, int column) const |
145 | { |
146 | if(role == Qt::DisplayRole) |
147 | { |
148 | if(column == 0) |
149 | return title(); |
150 | |
151 | const TestResult *const tr = testResult(); |
152 | if(!tr) |
153 | { |
154 | if(column == 1) |
155 | return TestResult::displayName(status: TestResult::NotTested); |
156 | else |
157 | return QString(); |
158 | } |
159 | const TestResult::Status status = tr->status(); |
160 | |
161 | switch(column) |
162 | { |
163 | case 1: |
164 | return status == TestResult::Pass ? QString(QChar::fromLatin1(c: '1')) |
165 | : QString(QChar::fromLatin1(c: '0')); |
166 | case 2: |
167 | return status == TestResult::Fail ? QString(QChar::fromLatin1(c: '1')) |
168 | : QString(QChar::fromLatin1(c: '0')); |
169 | default: |
170 | return QString(); |
171 | } |
172 | } |
173 | |
174 | if(role != Qt::BackgroundRole) |
175 | return QVariant(); |
176 | |
177 | const TestResult *const tr = testResult(); |
178 | |
179 | if(!tr) |
180 | { |
181 | if(column == 0) |
182 | return QColor(Qt::yellow); |
183 | else |
184 | return QVariant(); |
185 | } |
186 | |
187 | const TestResult::Status status = tr->status(); |
188 | |
189 | if(status == TestResult::NotTested || status == TestResult::Unknown) |
190 | return QColor(Qt::yellow); |
191 | |
192 | switch(column) |
193 | { |
194 | case 1: |
195 | return status == TestResult::Pass ? QColor(Qt::green) : QVariant(); |
196 | case 2: |
197 | return status == TestResult::Fail ? QColor(Qt::red) : QVariant(); |
198 | default: |
199 | return QVariant(); |
200 | } |
201 | } |
202 | |
203 | QString XSDTSTestCase::sourceCode(bool &ok) const |
204 | { |
205 | QFile file((m_testType == SchemaTest ? m_schemaUri : m_instanceUri).toLocalFile()); |
206 | |
207 | QString err; |
208 | |
209 | if(!file.exists()) |
210 | err = QString::fromLatin1(str: "Error: %1 does not exist." ).arg(a: file.fileName()); |
211 | else if(!QFileInfo(file.fileName()).isFile()) |
212 | err = QString::fromLatin1(str: "Error: %1 is not a file, cannot display it." ).arg(a: file.fileName()); |
213 | else if(!file.open(flags: QIODevice::ReadOnly)) |
214 | err = QString::fromLatin1(str: "Error: Could not open %1. Likely a permission error." ) |
215 | .arg(a: file.fileName()); |
216 | |
217 | if(err.isNull()) /* No errors. */ |
218 | { |
219 | ok = true; |
220 | /* Scary, we assume the query is stored in UTF-8. */ |
221 | return QString::fromUtf8(str: file.readAll()); |
222 | } |
223 | else |
224 | { |
225 | ok = false; |
226 | return err; |
227 | } |
228 | } |
229 | |
230 | int XSDTSTestCase::columnCount() const |
231 | { |
232 | return 2; |
233 | } |
234 | |
235 | void XSDTSTestCase::addBaseLine(TestBaseLine *line) |
236 | { |
237 | m_baseLines.append(t: line); |
238 | } |
239 | |
240 | QString XSDTSTestCase::name() const |
241 | { |
242 | return m_name; |
243 | } |
244 | |
245 | QString XSDTSTestCase::creator() const |
246 | { |
247 | return m_creator; |
248 | } |
249 | |
250 | QString XSDTSTestCase::description() const |
251 | { |
252 | return m_description; |
253 | } |
254 | |
255 | QDate XSDTSTestCase::lastModified() const |
256 | { |
257 | return m_lastModified; |
258 | } |
259 | |
260 | bool XSDTSTestCase::isXPath() const |
261 | { |
262 | return false; |
263 | } |
264 | |
265 | TestCase::Scenario XSDTSTestCase::scenario() const |
266 | { |
267 | return m_scenario; |
268 | } |
269 | |
270 | void XSDTSTestCase::setName(const QString &n) |
271 | { |
272 | m_name = n; |
273 | } |
274 | |
275 | void XSDTSTestCase::setCreator(const QString &ctor) |
276 | { |
277 | m_creator = ctor; |
278 | } |
279 | |
280 | void XSDTSTestCase::setDescription(const QString &descriptionP) |
281 | { |
282 | m_description = descriptionP; |
283 | } |
284 | |
285 | void XSDTSTestCase::setLastModified(const QDate &date) |
286 | { |
287 | m_lastModified = date; |
288 | } |
289 | |
290 | void XSDTSTestCase::setSchemaUri(const QUrl &uri) |
291 | { |
292 | m_schemaUri = uri; |
293 | } |
294 | |
295 | void XSDTSTestCase::setInstanceUri(const QUrl &uri) |
296 | { |
297 | m_instanceUri = uri; |
298 | } |
299 | |
300 | TreeItem *XSDTSTestCase::parent() const |
301 | { |
302 | return m_parent; |
303 | } |
304 | |
305 | QString XSDTSTestCase::title() const |
306 | { |
307 | return m_name; |
308 | } |
309 | |
310 | TestBaseLine::List XSDTSTestCase::baseLines() const |
311 | { |
312 | Q_ASSERT_X(!m_baseLines.isEmpty(), Q_FUNC_INFO, |
313 | qPrintable(QString::fromLatin1("The test %1 has no base lines, it should have at least one." ).arg(name()))); |
314 | return m_baseLines; |
315 | } |
316 | |
317 | QUrl XSDTSTestCase::schemaUri() const |
318 | { |
319 | return m_schemaUri; |
320 | } |
321 | |
322 | QUrl XSDTSTestCase::instanceUri() const |
323 | { |
324 | return m_instanceUri; |
325 | } |
326 | |
327 | void XSDTSTestCase::setContextItemSource(const QUrl &uri) |
328 | { |
329 | m_contextItemSource = uri; |
330 | } |
331 | |
332 | QUrl XSDTSTestCase::contextItemSource() const |
333 | { |
334 | return m_contextItemSource; |
335 | } |
336 | |
337 | void XSDTSTestCase::setParent(TreeItem *const p) |
338 | { |
339 | m_parent = p; |
340 | } |
341 | |
342 | QPatternist::ExternalVariableLoader::Ptr XSDTSTestCase::externalVariableLoader() const |
343 | { |
344 | return QPatternist::ExternalVariableLoader::Ptr(); |
345 | } |
346 | |
347 | TestResult *XSDTSTestCase::testResult() const |
348 | { |
349 | return m_result; |
350 | } |
351 | |
352 | TestItem::ResultSummary XSDTSTestCase::resultSummary() const |
353 | { |
354 | if(m_result) |
355 | return ResultSummary(m_result->status() == TestResult::Pass ? 1 : 0, |
356 | 1); |
357 | |
358 | return ResultSummary(0, 1); |
359 | } |
360 | |
361 | // vim: et:ts=4:sw=4:sts=4 |
362 | |
363 | |