1 | /**************************************************************************** |
2 | ** |
3 | ** Copyright (C) 2015 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Marc Mutz <marc.mutz@kdab.com> |
4 | ** Contact: https://www.qt.io/licensing/ |
5 | ** |
6 | ** This file is part of the test suite 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 <QtTest/QtTest> |
30 | |
31 | #include <QString> |
32 | |
33 | // Preserve QLatin1String-ness (QVariant(QLatin1String) creates a QVariant::String): |
34 | struct QLatin1StringContainer { |
35 | QLatin1String l1; |
36 | }; |
37 | QT_BEGIN_NAMESPACE |
38 | Q_DECLARE_TYPEINFO(QLatin1StringContainer, Q_MOVABLE_TYPE); |
39 | QT_END_NAMESPACE |
40 | Q_DECLARE_METATYPE(QLatin1StringContainer) |
41 | |
42 | class tst_QLatin1String : public QObject |
43 | { |
44 | Q_OBJECT |
45 | |
46 | private Q_SLOTS: |
47 | void at(); |
48 | void arg() const; |
49 | void midLeftRight(); |
50 | void nullString(); |
51 | void emptyString(); |
52 | void iterators(); |
53 | void relationalOperators_data(); |
54 | void relationalOperators(); |
55 | }; |
56 | |
57 | |
58 | void tst_QLatin1String::at() |
59 | { |
60 | const QLatin1String l1("Hello World" ); |
61 | QCOMPARE(l1.at(0), QLatin1Char('H')); |
62 | QCOMPARE(l1.at(l1.size() - 1), QLatin1Char('d')); |
63 | QCOMPARE(l1[0], QLatin1Char('H')); |
64 | QCOMPARE(l1[l1.size() - 1], QLatin1Char('d')); |
65 | } |
66 | |
67 | void tst_QLatin1String::arg() const |
68 | { |
69 | #define CHECK1(pattern, arg1, expected) \ |
70 | do { \ |
71 | auto p = QLatin1String(pattern); \ |
72 | QCOMPARE(p.arg(QLatin1String(arg1)), expected); \ |
73 | QCOMPARE(p.arg(u"" arg1), expected); \ |
74 | QCOMPARE(p.arg(QStringLiteral(arg1)), expected); \ |
75 | QCOMPARE(p.arg(QString(QLatin1String(arg1))), expected); \ |
76 | } while (false) \ |
77 | /*end*/ |
78 | #define CHECK2(pattern, arg1, arg2, expected) \ |
79 | do { \ |
80 | auto p = QLatin1String(pattern); \ |
81 | QCOMPARE(p.arg(QLatin1String(arg1), QLatin1String(arg2)), expected); \ |
82 | QCOMPARE(p.arg(u"" arg1, QLatin1String(arg2)), expected); \ |
83 | QCOMPARE(p.arg(QLatin1String(arg1), u"" arg2), expected); \ |
84 | QCOMPARE(p.arg(u"" arg1, u"" arg2), expected); \ |
85 | } while (false) \ |
86 | /*end*/ |
87 | |
88 | CHECK1("" , "World" , "" ); |
89 | CHECK1("%1" , "World" , "World" ); |
90 | CHECK1("!%1?" , "World" , "!World?" ); |
91 | CHECK1("%1%1" , "World" , "WorldWorld" ); |
92 | CHECK1("%1%2" , "World" , "World%2" ); |
93 | CHECK1("%2%1" , "World" , "%2World" ); |
94 | |
95 | CHECK2("" , "Hello" , "World" , "" ); |
96 | CHECK2("%1" , "Hello" , "World" , "Hello" ); |
97 | CHECK2("!%1, %2?" , "Hello" , "World" , "!Hello, World?" ); |
98 | CHECK2("%1%1" , "Hello" , "World" , "HelloHello" ); |
99 | CHECK2("%1%2" , "Hello" , "World" , "HelloWorld" ); |
100 | CHECK2("%2%1" , "Hello" , "World" , "WorldHello" ); |
101 | |
102 | #undef CHECK2 |
103 | #undef CHECK1 |
104 | |
105 | QCOMPARE(QLatin1String(" %2 %2 %1 %3 " ).arg(QLatin1Char('c'), QChar::CarriageReturn, u'C'), " \r \r c C " ); |
106 | } |
107 | |
108 | void tst_QLatin1String::midLeftRight() |
109 | { |
110 | const QLatin1String l1("Hello World" ); |
111 | QCOMPARE(l1.mid(0), l1); |
112 | QCOMPARE(l1.mid(0, l1.size()), l1); |
113 | QCOMPARE(l1.left(l1.size()), l1); |
114 | QCOMPARE(l1.right(l1.size()), l1); |
115 | |
116 | QCOMPARE(l1.mid(6), QLatin1String("World" )); |
117 | QCOMPARE(l1.mid(6, 5), QLatin1String("World" )); |
118 | QCOMPARE(l1.right(5), QLatin1String("World" )); |
119 | |
120 | QCOMPARE(l1.mid(6, 1), QLatin1String("W" )); |
121 | QCOMPARE(l1.right(5).left(1), QLatin1String("W" )); |
122 | |
123 | QCOMPARE(l1.left(5), QLatin1String("Hello" )); |
124 | } |
125 | |
126 | void tst_QLatin1String::nullString() |
127 | { |
128 | // default ctor |
129 | { |
130 | QLatin1String l1; |
131 | QCOMPARE(static_cast<const void*>(l1.data()), static_cast<const void*>(nullptr)); |
132 | QCOMPARE(l1.size(), 0); |
133 | |
134 | QString s = l1; |
135 | QVERIFY(s.isNull()); |
136 | } |
137 | |
138 | // from nullptr |
139 | { |
140 | const char *null = nullptr; |
141 | QLatin1String l1(null); |
142 | QCOMPARE(static_cast<const void*>(l1.data()), static_cast<const void*>(nullptr)); |
143 | QCOMPARE(l1.size(), 0); |
144 | |
145 | QString s = l1; |
146 | QVERIFY(s.isNull()); |
147 | } |
148 | |
149 | // from null QByteArray |
150 | { |
151 | const QByteArray null; |
152 | QVERIFY(null.isNull()); |
153 | |
154 | QLatin1String l1(null); |
155 | QEXPECT_FAIL("" , "null QByteArrays become non-null QLatin1Strings..." , Continue); |
156 | QCOMPARE(static_cast<const void*>(l1.data()), static_cast<const void*>(nullptr)); |
157 | QCOMPARE(l1.size(), 0); |
158 | |
159 | QString s = l1; |
160 | QEXPECT_FAIL("" , "null QByteArrays become non-null QLatin1Strings become non-null QStrings..." , Continue); |
161 | QVERIFY(s.isNull()); |
162 | } |
163 | } |
164 | |
165 | void tst_QLatin1String::emptyString() |
166 | { |
167 | { |
168 | const char *empty = "" ; |
169 | QLatin1String l1(empty); |
170 | QCOMPARE(static_cast<const void*>(l1.data()), static_cast<const void*>(empty)); |
171 | QCOMPARE(l1.size(), 0); |
172 | |
173 | QString s = l1; |
174 | QVERIFY(s.isEmpty()); |
175 | QVERIFY(!s.isNull()); |
176 | } |
177 | |
178 | { |
179 | const char *notEmpty = "foo" ; |
180 | QLatin1String l1(notEmpty, 0); |
181 | QCOMPARE(static_cast<const void*>(l1.data()), static_cast<const void*>(notEmpty)); |
182 | QCOMPARE(l1.size(), 0); |
183 | |
184 | QString s = l1; |
185 | QVERIFY(s.isEmpty()); |
186 | QVERIFY(!s.isNull()); |
187 | } |
188 | |
189 | { |
190 | const QByteArray empty = "" ; |
191 | QLatin1String l1(empty); |
192 | QCOMPARE(static_cast<const void*>(l1.data()), static_cast<const void*>(empty.constData())); |
193 | QCOMPARE(l1.size(), 0); |
194 | |
195 | QString s = l1; |
196 | QVERIFY(s.isEmpty()); |
197 | QVERIFY(!s.isNull()); |
198 | } |
199 | } |
200 | |
201 | void tst_QLatin1String::iterators() |
202 | { |
203 | QLatin1String hello("hello" ); |
204 | QLatin1String olleh("olleh" ); |
205 | |
206 | QVERIFY(std::equal(hello.begin(), hello.end(), |
207 | olleh.rbegin())); |
208 | QVERIFY(std::equal(hello.rbegin(), hello.rend(), |
209 | QT_MAKE_CHECKED_ARRAY_ITERATOR(olleh.begin(), olleh.size()))); |
210 | |
211 | QVERIFY(std::equal(hello.cbegin(), hello.cend(), |
212 | olleh.rbegin())); |
213 | QVERIFY(std::equal(hello.crbegin(), hello.crend(), |
214 | QT_MAKE_CHECKED_ARRAY_ITERATOR(olleh.begin(), olleh.size()))); |
215 | } |
216 | |
217 | void tst_QLatin1String::relationalOperators_data() |
218 | { |
219 | QTest::addColumn<QLatin1StringContainer>(name: "lhs" ); |
220 | QTest::addColumn<int>(name: "lhsOrderNumber" ); |
221 | QTest::addColumn<QLatin1StringContainer>(name: "rhs" ); |
222 | QTest::addColumn<int>(name: "rhsOrderNumber" ); |
223 | |
224 | struct Data { |
225 | QLatin1String l1; |
226 | int order; |
227 | } data[] = { |
228 | { .l1: QLatin1String(), .order: 0 }, |
229 | { .l1: QLatin1String("" ), .order: 0 }, |
230 | { .l1: QLatin1String("a" ), .order: 1 }, |
231 | { .l1: QLatin1String("aa" ), .order: 2 }, |
232 | { .l1: QLatin1String("b" ), .order: 3 }, |
233 | }; |
234 | |
235 | for (Data *lhs = data; lhs != data + sizeof data / sizeof *data; ++lhs) { |
236 | for (Data *rhs = data; rhs != data + sizeof data / sizeof *data; ++rhs) { |
237 | QLatin1StringContainer l = { .l1: lhs->l1 }, r = { .l1: rhs->l1 }; |
238 | QTest::addRow(format: "\"%s\" <> \"%s\"" , |
239 | lhs->l1.data() ? lhs->l1.data() : "nullptr" , |
240 | rhs->l1.data() ? rhs->l1.data() : "nullptr" ) |
241 | << l << lhs->order << r << rhs->order; |
242 | } |
243 | } |
244 | } |
245 | |
246 | void tst_QLatin1String::relationalOperators() |
247 | { |
248 | QFETCH(QLatin1StringContainer, lhs); |
249 | QFETCH(int, lhsOrderNumber); |
250 | QFETCH(QLatin1StringContainer, rhs); |
251 | QFETCH(int, rhsOrderNumber); |
252 | |
253 | #define CHECK(op) \ |
254 | QCOMPARE(lhs.l1 op rhs.l1, lhsOrderNumber op rhsOrderNumber) \ |
255 | /*end*/ |
256 | CHECK(==); |
257 | CHECK(!=); |
258 | CHECK(< ); |
259 | CHECK(> ); |
260 | CHECK(<=); |
261 | CHECK(>=); |
262 | #undef CHECK |
263 | } |
264 | |
265 | QTEST_APPLESS_MAIN(tst_QLatin1String) |
266 | |
267 | #include "tst_qlatin1string.moc" |
268 | |