1// Copyright (C) 2021 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include <QtTest/private/qtestjunitstreamer_p.h>
5#include <QtTest/private/qjunittestlogger_p.h>
6#include <QtTest/private/qtestelement_p.h>
7#include <QtTest/private/qtestelementattribute_p.h>
8#include <QtTest/qtestassert.h>
9#include <QtTest/private/qtestlog_p.h>
10#include <QtTest/private/qtestresult_p.h>
11#include <QtTest/private/qxmltestlogger_p.h>
12
13QT_BEGIN_NAMESPACE
14
15QTestJUnitStreamer::QTestJUnitStreamer(QJUnitTestLogger *logger)
16 : testLogger(logger)
17{
18 QTEST_ASSERT(testLogger);
19}
20
21QTestJUnitStreamer::~QTestJUnitStreamer() = default;
22
23void QTestJUnitStreamer::indentForElement(const QTestElement* element, char* buf, int size)
24{
25 if (size == 0) return;
26
27 buf[0] = 0;
28
29 if (!element) return;
30
31 char* endbuf = buf + size;
32 element = element->parentElement();
33 while (element && buf+2 < endbuf) {
34 *(buf++) = ' ';
35 *(buf++) = ' ';
36 *buf = 0;
37 element = element->parentElement();
38 }
39}
40
41void QTestJUnitStreamer::formatStart(const QTestElement *element, QTestCharBuffer *formatted) const
42{
43 if (!element || !formatted )
44 return;
45
46 char indent[20];
47 indentForElement(element, buf: indent, size: sizeof(indent));
48
49 if (element->elementType() == QTest::LET_Text) {
50 QTest::qt_asprintf(buf: formatted, format: "%s<![CDATA[", indent);
51 return;
52 }
53
54 QTest::qt_asprintf(buf: formatted, format: "%s<%s", indent, element->elementName());
55}
56
57void QTestJUnitStreamer::formatEnd(const QTestElement *element, QTestCharBuffer *formatted) const
58{
59 if (!element || !formatted )
60 return;
61
62 if (element->childElements().empty()) {
63 formatted->data()[0] = '\0';
64 return;
65 }
66
67 char indent[20];
68 indentForElement(element, buf: indent, size: sizeof(indent));
69
70 QTest::qt_asprintf(buf: formatted, format: "%s</%s>\n", indent, element->elementName());
71}
72
73bool QTestJUnitStreamer::formatAttributes(const QTestElement* element,
74 const QTestElementAttribute *attribute,
75 QTestCharBuffer *formatted) const
76{
77 if (!attribute || !formatted )
78 return false;
79
80 QTest::AttributeIndex attrindex = attribute->index();
81
82 if (element && element->elementType() == QTest::LET_Text) {
83 QTEST_ASSERT(attrindex == QTest::AI_Value);
84 return QXmlTestLogger::xmlCdata(dest: formatted, src: attribute->value());
85 }
86
87 QTestCharBuffer quotedValue;
88 if (QXmlTestLogger::xmlQuote(dest: &quotedValue, src: attribute->value())) {
89 return QTest::qt_asprintf(buf: formatted, format: " %s=\"%s\"",
90 attribute->name(), quotedValue.constData()) != 0;
91 }
92 return false;
93}
94
95void QTestJUnitStreamer::formatAfterAttributes(const QTestElement *element, QTestCharBuffer *formatted) const
96{
97 if (!element || !formatted )
98 return;
99
100 if (element->elementType() == QTest::LET_Text) {
101 QTest::qt_asprintf(buf: formatted, format: "]]>\n");
102 return;
103 }
104
105 if (element->childElements().empty())
106 QTest::qt_asprintf(buf: formatted, format: "/>\n");
107 else
108 QTest::qt_asprintf(buf: formatted, format: ">\n");
109}
110
111void QTestJUnitStreamer::output(QTestElement *element) const
112{
113 QTEST_ASSERT(element);
114
115 if (!element->parentElement())
116 outputString(msg: "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n");
117
118 QTestCharBuffer buf;
119
120 formatStart(element, formatted: &buf);
121 outputString(msg: buf.data());
122
123 outputElementAttributes(element, attributes: element->attributes());
124
125 formatAfterAttributes(element, formatted: &buf);
126 outputString(msg: buf.data());
127
128 if (!element->childElements().empty())
129 outputElements(element->childElements());
130
131 formatEnd(element, formatted: &buf);
132 outputString(msg: buf.data());
133}
134
135void QTestJUnitStreamer::outputElements(const std::vector<QTestElement*> &elements) const
136{
137 for (auto *element : elements)
138 output(element);
139}
140
141void QTestJUnitStreamer::outputElementAttributes(const QTestElement* element, const std::vector<QTestElementAttribute*> &attributes) const
142{
143 QTestCharBuffer buf;
144
145 for (auto *attribute : attributes) {
146 if (formatAttributes(element, attribute, formatted: &buf))
147 outputString(msg: buf.data());
148 }
149}
150
151void QTestJUnitStreamer::outputString(const char *msg) const
152{
153 testLogger->outputString(msg);
154}
155
156QT_END_NAMESPACE
157

source code of qtbase/src/testlib/qtestjunitstreamer.cpp