1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Copyright (C) 2016 Intel Corporation.
5** Contact: https://www.qt.io/licensing/
6**
7** This file is part of the test suite of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:GPL-EXCEPT$
10** Commercial License Usage
11** Licensees holding valid commercial Qt licenses may use this file in
12** accordance with the commercial license agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and The Qt Company. For licensing terms
15** and conditions see https://www.qt.io/terms-conditions. For further
16** information use the contact form at https://www.qt.io/contact-us.
17**
18** GNU General Public License Usage
19** Alternatively, this file may be used under the terms of the GNU
20** General Public License version 3 as published by the Free Software
21** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
22** included in the packaging of this file. Please review the following
23** information to ensure the GNU General Public License requirements will
24** be met: https://www.gnu.org/licenses/gpl-3.0.html.
25**
26** $QT_END_LICENSE$
27**
28****************************************************************************/
29
30#ifdef QT_NO_CAST_FROM_ASCII
31# undef QT_NO_CAST_FROM_ASCII
32#endif
33#ifdef QT_NO_CAST_TO_ASCII
34# undef QT_NO_CAST_TO_ASCII
35#endif
36#ifdef QT_ASCII_CAST_WARNINGS
37# undef QT_ASCII_CAST_WARNINGS
38#endif
39
40#include <private/qglobal_p.h> // for the icu feature test
41#include <QtTest/QtTest>
42#include <qregexp.h>
43#include <qregularexpression.h>
44#include <qtextcodec.h>
45#include <qtextstream.h>
46#include <qstringlist.h>
47#include <qstringmatcher.h>
48#include <qbytearraymatcher.h>
49#include <qvariant.h>
50
51#include <qlocale.h>
52#include <locale.h>
53#include <qhash.h>
54
55#include <string>
56#include <algorithm>
57
58#define CREATE_REF(string) \
59 const QString padded = QLatin1Char(' ') + string + QLatin1Char(' '); \
60 QStringRef ref = padded.midRef(1, padded.size() - 2);
61
62namespace {
63
64// this wraps an argument to a QString function, as well as how to apply
65// the argument to a given QString member function.
66template <typename T>
67class Arg;
68
69template <typename T>
70class Reversed {}; // marker for Arg<QChar> to apply the operation in reverse order (for prepend())
71
72class ArgBase
73{
74protected:
75 QString pinned;
76 explicit ArgBase(const char *str)
77 : pinned(QString::fromLatin1(str)) {}
78};
79
80template <>
81class Arg<QChar> : protected ArgBase
82{
83public:
84 explicit Arg(const char *str) : ArgBase(str) {}
85
86 template <typename MemFun>
87 void apply0(QString &s, MemFun mf) const
88 { for (QChar ch : qAsConst(t: this->pinned)) (s.*mf)(ch); }
89
90 template <typename MemFun, typename A1>
91 void apply1(QString &s, MemFun mf, A1 a1) const
92 { for (QChar ch : qAsConst(t: this->pinned)) (s.*mf)(a1, ch); }
93};
94
95template <>
96class Arg<Reversed<QChar> > : private Arg<QChar>
97{
98public:
99 explicit Arg(const char *str) : Arg<QChar>(str)
100 {
101 std::reverse(first: this->pinned.begin(), last: this->pinned.end());
102 }
103
104 using Arg<QChar>::apply0;
105 using Arg<QChar>::apply1;
106};
107
108template <>
109class Arg<QString> : ArgBase
110{
111public:
112 explicit Arg(const char *str) : ArgBase(str) {}
113
114 template <typename MemFun>
115 void apply0(QString &s, MemFun mf) const
116 { (s.*mf)(this->pinned); }
117
118 template <typename MemFun, typename A1>
119 void apply1(QString &s, MemFun mf, A1 a1) const
120 { (s.*mf)(a1, this->pinned); }
121};
122
123template <>
124class Arg<QStringRef> : ArgBase
125{
126 QStringRef ref() const
127 { return QStringRef(&pinned); }
128public:
129 explicit Arg(const char *str) : ArgBase(str) {}
130
131 template <typename MemFun>
132 void apply0(QString &s, MemFun mf) const
133 { (s.*mf)(ref()); }
134
135 template <typename MemFun, typename A1>
136 void apply1(QString &s, MemFun mf, A1 a1) const
137 { (s.*mf)(a1, ref()); }
138};
139
140template <>
141class Arg<QPair<const QChar *, int> > : ArgBase
142{
143public:
144 explicit Arg(const char *str) : ArgBase(str) {}
145
146 template <typename MemFun>
147 void apply0(QString &s, MemFun mf) const
148 { (s.*mf)(this->pinned.constData(), this->pinned.length()); }
149
150 template <typename MemFun, typename A1>
151 void apply1(QString &s, MemFun mf, A1 a1) const
152 { (s.*mf)(a1, this->pinned.constData(), this->pinned.length()); }
153};
154
155template <>
156class Arg<QLatin1String>
157{
158 QLatin1String l1;
159public:
160 explicit Arg(const char *str) : l1(str) {}
161
162 template <typename MemFun>
163 void apply0(QString &s, MemFun mf) const
164 { (s.*mf)(l1); }
165
166 template <typename MemFun, typename A1>
167 void apply1(QString &s, MemFun mf, A1 a1) const
168 { (s.*mf)(a1, l1); }
169};
170
171template <>
172class Arg<char>
173{
174protected:
175 const char *str;
176public:
177 explicit Arg(const char *str) : str(str) {}
178
179 template <typename MemFun>
180 void apply0(QString &s, MemFun mf) const
181 {
182 if (str) {
183 for (const char *it = str; *it; ++it)
184 (s.*mf)(*it);
185 }
186 }
187
188 template <typename MemFun, typename A1>
189 void apply1(QString &s, MemFun mf, A1 a1) const
190 {
191 if (str) {
192 for (const char *it = str; *it; ++it)
193 (s.*mf)(a1, *it);
194 }
195 }
196};
197
198template <>
199class Arg<Reversed<char> > : private Arg<char>
200{
201 static const char *dupAndReverse(const char *s)
202 {
203 char *s2 = qstrdup(s);
204 std::reverse(first: s2, last: s2 + qstrlen(str: s2));
205 return s2;
206 }
207public:
208 explicit Arg(const char *str) : Arg<char>(dupAndReverse(s: str)) {}
209 ~Arg() { delete[] str; }
210
211 using Arg<char>::apply0;
212 using Arg<char>::apply1;
213};
214
215template <>
216class Arg<const char*>
217{
218 const char *str;
219public:
220 explicit Arg(const char *str) : str(str) {}
221
222 template <typename MemFun>
223 void apply0(QString &s, MemFun mf) const
224 { (s.*mf)(str); }
225
226 template <typename MemFun, typename A1>
227 void apply1(QString &s, MemFun mf, A1 a1) const
228 { (s.*mf)(a1, str); }
229};
230
231template <>
232class Arg<QByteArray>
233{
234 QByteArray ba;
235public:
236 explicit Arg(const char *str) : ba(str) {}
237
238 template <typename MemFun>
239 void apply0(QString &s, MemFun mf) const
240 { (s.*mf)(ba); }
241
242 template <typename MemFun, typename A1>
243 void apply1(QString &s, MemFun mf, A1 a1) const
244 { (s.*mf)(a1, ba); }
245};
246
247// const char* is not allowed as columns in data-driven tests (causes static_assert failure),
248// so wrap it in a container (default ctor is a QMetaType/QVariant requirement):
249class CharStarContainer
250{
251 const char *str;
252public:
253 explicit Q_DECL_CONSTEXPR CharStarContainer(const char *s = nullptr) : str(s) {}
254 Q_DECL_CONSTEXPR operator const char *() const { return str; }
255};
256
257} // unnamed namespace
258QT_BEGIN_NAMESPACE
259Q_DECLARE_TYPEINFO(CharStarContainer, Q_PRIMITIVE_TYPE);
260QT_END_NAMESPACE
261
262Q_DECLARE_METATYPE(CharStarContainer)
263
264// implementation helpers for append_impl/prepend_impl etc
265template <typename ArgType, typename MemFun>
266static void do_apply0(MemFun mf)
267{
268 QFETCH(QString, s);
269 QFETCH(CharStarContainer, arg);
270 QFETCH(QString, expected);
271
272 Arg<ArgType>(arg).apply0(s, mf);
273
274 QCOMPARE(s, expected);
275 QCOMPARE(s.isEmpty(), expected.isEmpty());
276 QCOMPARE(s.isNull(), expected.isNull());
277}
278
279template <typename ArgType, typename A1, typename MemFun>
280static void do_apply1(MemFun mf)
281{
282 QFETCH(QString, s);
283 QFETCH(CharStarContainer, arg);
284 QFETCH(A1, a1);
285 QFETCH(QString, expected);
286
287 Arg<ArgType>(arg).apply1(s, mf, a1);
288
289 QCOMPARE(s, expected);
290 QCOMPARE(s.isEmpty(), expected.isEmpty());
291 QCOMPARE(s.isNull(), expected.isNull());
292}
293
294class tst_QString : public QObject
295{
296 Q_OBJECT
297
298 template<typename List, class RegExp>
299 void split_regexp(const QString &string, const QString &pattern, QStringList result);
300 template<typename List>
301 void split(const QString &string, const QString &separator, QStringList result);
302
303 template <typename ArgType, typename MemFun>
304 void append_impl() const { do_apply0<ArgType>(MemFun(&QString::append)); }
305 template <typename ArgType>
306 void append_impl() const { append_impl<ArgType, QString &(QString::*)(const ArgType&)>(); }
307 void append_data(bool emptyIsNoop = false);
308 template <typename ArgType, typename MemFun>
309 void operator_pluseq_impl() const { do_apply0<ArgType>(MemFun(&QString::operator+=)); }
310 template <typename ArgType>
311 void operator_pluseq_impl() const { operator_pluseq_impl<ArgType, QString &(QString::*)(const ArgType&)>(); }
312 void operator_pluseq_data(bool emptyIsNoop = false);
313 template <typename ArgType, typename MemFun>
314 void prepend_impl() const { do_apply0<ArgType>(MemFun(&QString::prepend)); }
315 template <typename ArgType>
316 void prepend_impl() const { prepend_impl<ArgType, QString &(QString::*)(const ArgType&)>(); }
317 void prepend_data(bool emptyIsNoop = false);
318 template <typename ArgType, typename MemFun>
319 void insert_impl() const { do_apply1<ArgType, int>(MemFun(&QString::insert)); }
320 template <typename ArgType>
321 void insert_impl() const { insert_impl<ArgType, QString &(QString::*)(int, const ArgType&)>(); }
322 void insert_data(bool emptyIsNoop = false);
323
324 class TransientDefaultLocale
325 {
326 const QLocale prior; // Records what *was* the default before we set it.
327 public:
328 TransientDefaultLocale(const QLocale &transient) { revise(transient); }
329 void revise(const QLocale &transient) { QLocale::setDefault(transient); }
330 ~TransientDefaultLocale() { QLocale::setDefault(prior); }
331 };
332
333public:
334 tst_QString();
335private slots:
336 void fromStdString();
337 void toStdString();
338 void check_QTextIOStream();
339 void check_QTextStream();
340 void check_QDataStream();
341 void fromRawData();
342 void setRawData();
343 void endsWith();
344 void startsWith();
345 void setNum();
346 void toDouble_data();
347 void toDouble();
348 void toFloat();
349 void toLong_data();
350 void toLong();
351 void toULong_data();
352 void toULong();
353 void toLongLong();
354 void toULongLong();
355 void toUInt();
356 void toInt();
357 void toShort();
358 void toUShort();
359 void replace_qchar_qchar_data();
360 void replace_qchar_qchar();
361 void replace_qchar_qstring_data();
362 void replace_qchar_qstring();
363 void replace_uint_uint_data();
364 void replace_uint_uint();
365 void replace_extra();
366 void replace_string_data();
367 void replace_string();
368 void replace_regexp_data();
369 void replace_regexp();
370 void remove_uint_uint_data();
371 void remove_uint_uint();
372 void remove_string_data();
373 void remove_string();
374 void remove_regexp_data();
375 void remove_regexp();
376 void remove_extra();
377 void swap();
378
379 void prepend_qstring() { prepend_impl<QString>(); }
380 void prepend_qstring_data() { prepend_data(emptyIsNoop: true); }
381 void prepend_qstringref() { prepend_impl<QStringRef>(); }
382 void prepend_qstringref_data() { prepend_data(emptyIsNoop: true); }
383 void prepend_qlatin1string() { prepend_impl<QLatin1String, QString &(QString::*)(QLatin1String)>(); }
384 void prepend_qlatin1string_data() { prepend_data(emptyIsNoop: true); }
385 void prepend_qcharstar_int() { prepend_impl<QPair<const QChar *, int>, QString &(QString::*)(const QChar *, int)>(); }
386 void prepend_qcharstar_int_data() { prepend_data(emptyIsNoop: true); }
387 void prepend_qchar() { prepend_impl<Reversed<QChar>, QString &(QString::*)(QChar)>(); }
388 void prepend_qchar_data() { prepend_data(emptyIsNoop: true); }
389 void prepend_qbytearray() { prepend_impl<QByteArray>(); }
390 void prepend_qbytearray_data() { prepend_data(emptyIsNoop: true); }
391 void prepend_char() { prepend_impl<Reversed<char>, QString &(QString::*)(QChar)>(); }
392 void prepend_char_data() { prepend_data(emptyIsNoop: true); }
393 void prepend_charstar() { prepend_impl<const char *, QString &(QString::*)(const char *)>(); }
394 void prepend_charstar_data() { prepend_data(emptyIsNoop: true); }
395 void prepend_bytearray_special_cases_data();
396 void prepend_bytearray_special_cases();
397
398 void append_qstring() { append_impl<QString>(); }
399 void append_qstring_data() { append_data(); }
400 void append_qstringref() { append_impl<QStringRef>(); }
401 void append_qstringref_data() { append_data(); }
402 void append_qlatin1string() { append_impl<QLatin1String, QString &(QString::*)(QLatin1String)>(); }
403 void append_qlatin1string_data() { append_data(); }
404 void append_qcharstar_int() { append_impl<QPair<const QChar *, int>, QString&(QString::*)(const QChar *, int)>(); }
405 void append_qcharstar_int_data() { append_data(emptyIsNoop: true); }
406 void append_qchar() { append_impl<QChar, QString &(QString::*)(QChar)>(); }
407 void append_qchar_data() { append_data(emptyIsNoop: true); }
408 void append_qbytearray() { append_impl<QByteArray>(); }
409 void append_qbytearray_data() { append_data(); }
410 void append_char() { append_impl<char, QString &(QString::*)(QChar)>(); }
411 void append_char_data() { append_data(emptyIsNoop: true); }
412 void append_charstar() { append_impl<const char *, QString &(QString::*)(const char *)>(); }
413 void append_charstar_data() { append_data(); }
414 void append_special_cases();
415 void append_bytearray_special_cases_data();
416 void append_bytearray_special_cases();
417
418 void operator_pluseq_qstring() { operator_pluseq_impl<QString>(); }
419 void operator_pluseq_qstring_data() { operator_pluseq_data(); }
420 void operator_pluseq_qstringref() { operator_pluseq_impl<QStringRef>(); }
421 void operator_pluseq_qstringref_data() { operator_pluseq_data(); }
422 void operator_pluseq_qlatin1string() { operator_pluseq_impl<QLatin1String, QString &(QString::*)(QLatin1String)>(); }
423 void operator_pluseq_qlatin1string_data() { operator_pluseq_data(); }
424 void operator_pluseq_qchar() { operator_pluseq_impl<QChar, QString &(QString::*)(QChar)>(); }
425 void operator_pluseq_qchar_data() { operator_pluseq_data(emptyIsNoop: true); }
426 void operator_pluseq_qbytearray() { operator_pluseq_impl<QByteArray>(); }
427 void operator_pluseq_qbytearray_data() { operator_pluseq_data(); }
428 void operator_pluseq_char() { operator_pluseq_impl<char, QString &(QString::*)(char)>(); }
429 void operator_pluseq_char_data() { operator_pluseq_data(emptyIsNoop: true); }
430 void operator_pluseq_charstar() { operator_pluseq_impl<const char *, QString &(QString::*)(const char *)>(); }
431 void operator_pluseq_charstar_data() { operator_pluseq_data(); }
432 void operator_pluseq_bytearray_special_cases_data();
433 void operator_pluseq_bytearray_special_cases();
434
435 void operator_eqeq_bytearray_data();
436 void operator_eqeq_bytearray();
437 void operator_eqeq_nullstring();
438 void operator_smaller();
439
440 void insert_qstring() { insert_impl<QString>(); }
441 void insert_qstring_data() { insert_data(emptyIsNoop: true); }
442 void insert_qstringref() { insert_impl<QStringRef>(); }
443 void insert_qstringref_data() { insert_data(emptyIsNoop: true); }
444 void insert_qlatin1string() { insert_impl<QLatin1String, QString &(QString::*)(int, QLatin1String)>(); }
445 void insert_qlatin1string_data() { insert_data(emptyIsNoop: true); }
446 void insert_qcharstar_int() { insert_impl<QPair<const QChar *, int>, QString &(QString::*)(int, const QChar*, int) >(); }
447 void insert_qcharstar_int_data() { insert_data(emptyIsNoop: true); }
448 void insert_qchar() { insert_impl<Reversed<QChar>, QString &(QString::*)(int, QChar)>(); }
449 void insert_qchar_data() { insert_data(emptyIsNoop: true); }
450 void insert_qbytearray() { insert_impl<QByteArray>(); }
451 void insert_qbytearray_data() { insert_data(emptyIsNoop: true); }
452 void insert_char() { insert_impl<Reversed<char>, QString &(QString::*)(int, QChar)>(); }
453 void insert_char_data() { insert_data(emptyIsNoop: true); }
454 void insert_charstar() { insert_impl<const char *, QString &(QString::*)(int, const char*) >(); }
455 void insert_charstar_data() { insert_data(emptyIsNoop: true); }
456 void insert_special_cases();
457
458 void simplified_data();
459 void simplified();
460 void trimmed();
461 void toUpper();
462 void toLower();
463 void isLower_isUpper_data();
464 void isLower_isUpper();
465 void toCaseFolded();
466 void rightJustified();
467 void leftJustified();
468 void mid();
469 void right();
470 void left();
471 void midRef();
472 void rightRef();
473 void leftRef();
474 void stringRef();
475 void contains();
476 void count();
477 void lastIndexOf_data();
478 void lastIndexOf();
479 void lastIndexOfInvalidRegex();
480 void indexOf_data();
481 void indexOf();
482 void indexOfInvalidRegex();
483 void indexOf2_data();
484 void indexOf2();
485 void indexOf3_data();
486// void indexOf3();
487 void asprintf();
488 void asprintfS();
489 void fill();
490 void truncate();
491 void chop_data();
492 void chop();
493 void constructor();
494 void constructorQByteArray_data();
495 void constructorQByteArray();
496 void STL();
497 void macTypes();
498 void isEmpty();
499 void isNull();
500 void acc_01();
501 void length_data();
502 void length();
503 void utf8_data();
504 void utf8();
505 void fromUtf8_data();
506 void fromUtf8();
507 void nullFromUtf8();
508 void fromLocal8Bit_data();
509 void fromLocal8Bit();
510 void local8Bit_data();
511 void local8Bit();
512 void invalidToLocal8Bit_data();
513 void invalidToLocal8Bit();
514 void nullFromLocal8Bit();
515 void fromLatin1Roundtrip_data();
516 void fromLatin1Roundtrip();
517 void toLatin1Roundtrip_data();
518 void toLatin1Roundtrip();
519 void stringRef_toLatin1Roundtrip_data();
520 void stringRef_toLatin1Roundtrip();
521 void stringRef_utf8_data();
522 void stringRef_utf8();
523 void stringRef_local8Bit_data();
524 void stringRef_local8Bit();
525 void fromLatin1();
526#if QT_DEPRECATED_SINCE(5, 0)
527 void fromAscii();
528#endif
529 void fromUcs4();
530 void toUcs4();
531 void arg();
532 void number();
533 void doubleOut();
534 void arg_fillChar_data();
535 void arg_fillChar();
536 void capacity_data();
537 void capacity();
538 void section_data();
539 void section();
540 void double_conversion_data();
541 void double_conversion();
542 void integer_conversion_data();
543 void integer_conversion();
544 void tortureSprintfDouble();
545 void toNum();
546 void localeAwareCompare_data();
547 void localeAwareCompare();
548 void reverseIterators();
549 void split_data();
550 void split();
551 void split_regexp_data();
552 void split_regexp();
553 void split_regularexpression_data();
554 void split_regularexpression();
555 void splitRef_data();
556 void splitRef();
557 void splitRef_regexp_data();
558 void splitRef_regexp();
559 void splitRef_regularexpression_data();
560 void splitRef_regularexpression();
561 void fromUtf16_data();
562 void fromUtf16();
563 void fromUtf16_char16_data();
564 void fromUtf16_char16();
565 void latin1String();
566 void nanAndInf();
567 void compare_data();
568 void compare();
569 void resize();
570 void resizeAfterFromRawData();
571 void resizeAfterReserve();
572 void resizeWithNegative() const;
573 void truncateWithNegative() const;
574 void QCharRefMutableUnicode() const;
575 void QCharRefDetaching() const;
576 void sprintfZU() const;
577 void repeatedSignature() const;
578 void repeated() const;
579 void repeated_data() const;
580 void compareRef();
581 void arg_locale();
582#if QT_CONFIG(icu)
583 void toUpperLower_icu();
584#endif
585#if !defined(QT_NO_UNICODE_LITERAL)
586 void literals();
587#endif
588 void eightBitLiterals_data();
589 void eightBitLiterals();
590 void reserve();
591 void toHtmlEscaped_data();
592 void toHtmlEscaped();
593 void operatorGreaterWithQLatin1String();
594 void compareQLatin1Strings();
595 void fromQLatin1StringWithLength();
596 void assignQLatin1String();
597 void assignQChar();
598 void isRightToLeft_data();
599 void isRightToLeft();
600 void isValidUtf16_data();
601 void isValidUtf16();
602 void unicodeStrings();
603 void vasprintfWithPrecision();
604};
605
606template <class T> const T &verifyZeroTermination(const T &t) { return t; }
607
608QString verifyZeroTermination(const QString &str)
609{
610 // This test does some evil stuff, it's all supposed to work.
611
612 QString::DataPtr strDataPtr = const_cast<QString &>(str).data_ptr();
613
614 // Skip if isStatic() or fromRawData(), as those offer no guarantees
615 if (strDataPtr->ref.isStatic()
616 || strDataPtr->offset != QString().data_ptr()->offset)
617 return str;
618
619 int strSize = str.size();
620 QChar strTerminator = str.constData()[strSize];
621 if (QChar('\0') != strTerminator)
622 return QString::fromLatin1(
623 str: "*** Result ('%1') not null-terminated: 0x%2 ***").arg(a: str)
624 .arg(a: strTerminator.unicode(), fieldWidth: 4, base: 16, fillChar: QChar('0'));
625
626 // Skip mutating checks on shared strings
627 if (strDataPtr->ref.isShared())
628 return str;
629
630 const QChar *strData = str.constData();
631 const QString strCopy(strData, strSize); // Deep copy
632
633 const_cast<QChar *>(strData)[strSize] = QChar('x');
634 if (QChar('x') != str.constData()[strSize]) {
635 return QString::fromLatin1(str: "*** Failed to replace null-terminator in "
636 "result ('%1') ***").arg(a: str);
637 }
638 if (str != strCopy) {
639 return QString::fromLatin1( str: "*** Result ('%1') differs from its copy "
640 "after null-terminator was replaced ***").arg(a: str);
641 }
642 const_cast<QChar *>(strData)[strSize] = QChar('\0'); // Restore sanity
643
644 return str;
645}
646
647// Overriding QTest's QCOMPARE, to check QString for null termination
648#undef QCOMPARE
649#define QCOMPARE(actual, expected) \
650 do { \
651 if (!QTest::qCompare(verifyZeroTermination(actual), expected, \
652 #actual, #expected, __FILE__, __LINE__)) \
653 return; \
654 } while (0) \
655 /**/
656#undef QTEST
657#define QTEST(actual, testElement) \
658 do { \
659 if (!QTest::qTest(verifyZeroTermination(actual), testElement, \
660 #actual, #testElement, __FILE__, __LINE__)) \
661 return; \
662 } while (0) \
663 /**/
664
665typedef QVector<int> IntList;
666
667tst_QString::tst_QString()
668{
669 QTextCodec::setCodecForLocale(QTextCodec::codecForName(name: "ISO 8859-1"));
670}
671
672void tst_QString::remove_uint_uint_data()
673{
674 replace_uint_uint_data();
675}
676
677void tst_QString::remove_string_data()
678{
679 replace_string_data();
680}
681
682void tst_QString::remove_regexp_data()
683{
684 replace_regexp_data();
685}
686
687void tst_QString::indexOf3_data()
688{
689 indexOf2_data();
690}
691
692void tst_QString::length_data()
693{
694 QTest::addColumn<QString>(name: "s1" );
695 QTest::addColumn<int>(name: "res" );
696
697 QTest::newRow( dataTag: "data0" ) << QString("Test") << 4;
698 QTest::newRow( dataTag: "data1" ) << QString("The quick brown fox jumps over the lazy dog") << 43;
699 QTest::newRow( dataTag: "data2" ) << QString() << 0;
700 QTest::newRow( dataTag: "data3" ) << QString("A") << 1;
701 QTest::newRow( dataTag: "data4" ) << QString("AB") << 2;
702 QTest::newRow( dataTag: "data5" ) << QString("AB\n") << 3;
703 QTest::newRow( dataTag: "data6" ) << QString("AB\nC") << 4;
704 QTest::newRow( dataTag: "data7" ) << QString("\n") << 1;
705 QTest::newRow( dataTag: "data8" ) << QString("\nA") << 2;
706 QTest::newRow( dataTag: "data9" ) << QString("\nAB") << 3;
707 QTest::newRow( dataTag: "data10" ) << QString("\nAB\nCDE") << 7;
708 QTest::newRow( dataTag: "data11" ) << QString("shdnftrheid fhgnt gjvnfmd chfugkh bnfhg thgjf vnghturkf chfnguh bjgnfhvygh hnbhgutjfv dhdnjds dcjs d") << 100;
709}
710
711void tst_QString::replace_qchar_qchar_data()
712{
713 QTest::addColumn<QString>(name: "src" );
714 QTest::addColumn<QChar>(name: "before" );
715 QTest::addColumn<QChar>(name: "after" );
716 QTest::addColumn<int>(name: "cs" );
717 QTest::addColumn<QString>(name: "expected" );
718
719 QTest::newRow( dataTag: "1" ) << QString("foo") << QChar('o') << QChar('a')
720 << int(Qt::CaseSensitive) << QString("faa");
721 QTest::newRow( dataTag: "2" ) << QString("foo") << QChar('o') << QChar('a')
722 << int(Qt::CaseInsensitive) << QString("faa");
723 QTest::newRow( dataTag: "3" ) << QString("foo") << QChar('O') << QChar('a')
724 << int(Qt::CaseSensitive) << QString("foo");
725 QTest::newRow( dataTag: "4" ) << QString("foo") << QChar('O') << QChar('a')
726 << int(Qt::CaseInsensitive) << QString("faa");
727 QTest::newRow( dataTag: "5" ) << QString("ababABAB") << QChar('a') << QChar(' ')
728 << int(Qt::CaseSensitive) << QString(" b bABAB");
729 QTest::newRow( dataTag: "6" ) << QString("ababABAB") << QChar('a') << QChar(' ')
730 << int(Qt::CaseInsensitive) << QString(" b b B B");
731 QTest::newRow( dataTag: "7" ) << QString("ababABAB") << QChar() << QChar(' ')
732 << int(Qt::CaseInsensitive) << QString("ababABAB");
733}
734
735void tst_QString::replace_qchar_qchar()
736{
737 QFETCH(QString, src);
738 QFETCH(QChar, before);
739 QFETCH(QChar, after);
740 QFETCH(int, cs);
741 QFETCH(QString, expected);
742
743 QCOMPARE(src.replace(before, after, Qt::CaseSensitivity(cs)), expected);
744}
745
746void tst_QString::replace_qchar_qstring_data()
747{
748 QTest::addColumn<QString>(name: "src" );
749 QTest::addColumn<QChar>(name: "before" );
750 QTest::addColumn<QString>(name: "after" );
751 QTest::addColumn<int>(name: "cs" );
752 QTest::addColumn<QString>(name: "expected" );
753
754 QTest::newRow( dataTag: "1" ) << QString("foo") << QChar('o') << QString("aA")
755 << int(Qt::CaseSensitive) << QString("faAaA");
756 QTest::newRow( dataTag: "2" ) << QString("foo") << QChar('o') << QString("aA")
757 << int(Qt::CaseInsensitive) << QString("faAaA");
758 QTest::newRow( dataTag: "3" ) << QString("foo") << QChar('O') << QString("aA")
759 << int(Qt::CaseSensitive) << QString("foo");
760 QTest::newRow( dataTag: "4" ) << QString("foo") << QChar('O') << QString("aA")
761 << int(Qt::CaseInsensitive) << QString("faAaA");
762 QTest::newRow( dataTag: "5" ) << QString("ababABAB") << QChar('a') << QString(" ")
763 << int(Qt::CaseSensitive) << QString(" b bABAB");
764 QTest::newRow( dataTag: "6" ) << QString("ababABAB") << QChar('a') << QString(" ")
765 << int(Qt::CaseInsensitive) << QString(" b b B B");
766 QTest::newRow( dataTag: "7" ) << QString("ababABAB") << QChar() << QString(" ")
767 << int(Qt::CaseInsensitive) << QString("ababABAB");
768 QTest::newRow( dataTag: "8" ) << QString("ababABAB") << QChar() << QString()
769 << int(Qt::CaseInsensitive) << QString("ababABAB");
770}
771
772void tst_QString::replace_qchar_qstring()
773{
774 QFETCH(QString, src);
775 QFETCH(QChar, before);
776 QFETCH(QString, after);
777 QFETCH(int, cs);
778 QFETCH(QString, expected);
779
780 QCOMPARE(src.replace(before, after, Qt::CaseSensitivity(cs)), expected);
781}
782
783void tst_QString::replace_uint_uint_data()
784{
785 QTest::addColumn<QString>(name: "string" );
786 QTest::addColumn<int>(name: "index" );
787 QTest::addColumn<int>(name: "len" );
788 QTest::addColumn<QString>(name: "after" );
789 QTest::addColumn<QString>(name: "result" );
790
791 QTest::newRow( dataTag: "rem00" ) << QString("-<>ABCABCABCABC>") << 0 << 3 << QString("") << QString("ABCABCABCABC>");
792 QTest::newRow( dataTag: "rem01" ) << QString("ABCABCABCABC>") << 1 << 4 << QString("") << QString("ACABCABC>");
793 QTest::newRow( dataTag: "rem04" ) << QString("ACABCABC>") << 8 << 4 << QString("") << QString("ACABCABC");
794 QTest::newRow( dataTag: "rem05" ) << QString("ACABCABC") << 7 << 1 << QString("") << QString("ACABCAB");
795 QTest::newRow( dataTag: "rem06" ) << QString("ACABCAB") << 4 << 0 << QString("") << QString("ACABCAB");
796
797 QTest::newRow( dataTag: "rep00" ) << QString("ACABCAB") << 4 << 0 << QString("X") << QString("ACABXCAB");
798 QTest::newRow( dataTag: "rep01" ) << QString("ACABXCAB") << 4 << 1 << QString("Y") << QString("ACABYCAB");
799 QTest::newRow( dataTag: "rep02" ) << QString("ACABYCAB") << 4 << 1 << QString("") << QString("ACABCAB");
800 QTest::newRow( dataTag: "rep03" ) << QString("ACABCAB") << 0 << 9999 << QString("XX") << QString("XX");
801 QTest::newRow( dataTag: "rep04" ) << QString("XX") << 0 << 9999 << QString("") << QString("");
802 QTest::newRow( dataTag: "rep05" ) << QString("ACABCAB") << 0 << 2 << QString("XX") << QString("XXABCAB");
803 QTest::newRow( dataTag: "rep06" ) << QString("ACABCAB") << 1 << 2 << QString("XX") << QString("AXXBCAB");
804 QTest::newRow( dataTag: "rep07" ) << QString("ACABCAB") << 2 << 2 << QString("XX") << QString("ACXXCAB");
805 QTest::newRow( dataTag: "rep08" ) << QString("ACABCAB") << 3 << 2 << QString("XX") << QString("ACAXXAB");
806 QTest::newRow( dataTag: "rep09" ) << QString("ACABCAB") << 4 << 2 << QString("XX") << QString("ACABXXB");
807 QTest::newRow( dataTag: "rep10" ) << QString("ACABCAB") << 5 << 2 << QString("XX") << QString("ACABCXX");
808 QTest::newRow( dataTag: "rep11" ) << QString("ACABCAB") << 6 << 2 << QString("XX") << QString("ACABCAXX");
809 QTest::newRow( dataTag: "rep12" ) << QString() << 0 << 10 << QString("X") << QString("X");
810 QTest::newRow( dataTag: "rep13" ) << QString("short") << 0 << 10 << QString("X") << QString("X");
811 QTest::newRow( dataTag: "rep14" ) << QString() << 0 << 10 << QString("XX") << QString("XX");
812 QTest::newRow( dataTag: "rep15" ) << QString("short") << 0 << 10 << QString("XX") << QString("XX");
813
814 // This is a regression test for an old bug where QString would add index and len parameters,
815 // potentially causing integer overflow.
816 QTest::newRow( dataTag: "no overflow" ) << QString("ACABCAB") << 1 << INT_MAX - 1 << QString("") << QString("A");
817 QTest::newRow( dataTag: "overflow" ) << QString("ACABCAB") << 1 << INT_MAX << QString("") << QString("A");
818}
819
820void tst_QString::replace_string_data()
821{
822 QTest::addColumn<QString>(name: "string" );
823 QTest::addColumn<QString>(name: "before" );
824 QTest::addColumn<QString>(name: "after" );
825 QTest::addColumn<QString>(name: "result" );
826 QTest::addColumn<bool>(name: "bcs" );
827
828 QTest::newRow( dataTag: "rem00" ) << QString("") << QString("") << QString("") << QString("") << true;
829 QTest::newRow( dataTag: "rem01" ) << QString("A") << QString("") << QString("") << QString("A") << true;
830 QTest::newRow( dataTag: "rem02" ) << QString("A") << QString("A") << QString("") << QString("") << true;
831 QTest::newRow( dataTag: "rem03" ) << QString("A") << QString("B") << QString("") << QString("A") << true;
832 QTest::newRow( dataTag: "rem04" ) << QString("AA") << QString("A") << QString("") << QString("") << true;
833 QTest::newRow( dataTag: "rem05" ) << QString("AB") << QString("A") << QString("") << QString("B") << true;
834 QTest::newRow( dataTag: "rem06" ) << QString("AB") << QString("B") << QString("") << QString("A") << true;
835 QTest::newRow( dataTag: "rem07" ) << QString("AB") << QString("C") << QString("") << QString("AB") << true;
836 QTest::newRow( dataTag: "rem08" ) << QString("ABA") << QString("A") << QString("") << QString("B") << true;
837 QTest::newRow( dataTag: "rem09" ) << QString("ABA") << QString("B") << QString("") << QString("AA") << true;
838 QTest::newRow( dataTag: "rem10" ) << QString("ABA") << QString("C") << QString("") << QString("ABA") << true;
839 QTest::newRow( dataTag: "rem11" ) << QString("banana") << QString("an") << QString("") << QString("ba") << true;
840 QTest::newRow( dataTag: "rem12" ) << QString("") << QString("A") << QString("") << QString("") << true;
841 QTest::newRow( dataTag: "rem13" ) << QString("") << QString("A") << QString() << QString("") << true;
842 QTest::newRow( dataTag: "rem14" ) << QString() << QString("A") << QString("") << QString() << true;
843 QTest::newRow( dataTag: "rem15" ) << QString() << QString("A") << QString() << QString() << true;
844 QTest::newRow( dataTag: "rem16" ) << QString() << QString("") << QString("") << QString("") << true;
845 QTest::newRow( dataTag: "rem17" ) << QString("") << QString() << QString("") << QString("") << true;
846 QTest::newRow( dataTag: "rem18" ) << QString("a") << QString("a") << QString("") << QString("") << false;
847 QTest::newRow( dataTag: "rem19" ) << QString("A") << QString("A") << QString("") << QString("") << false;
848 QTest::newRow( dataTag: "rem20" ) << QString("a") << QString("A") << QString("") << QString("") << false;
849 QTest::newRow( dataTag: "rem21" ) << QString("A") << QString("a") << QString("") << QString("") << false;
850 QTest::newRow( dataTag: "rem22" ) << QString("Alpha beta") << QString("a") << QString("") << QString("lph bet") << false;
851
852 QTest::newRow( dataTag: "rep00" ) << QString("ABC") << QString("B") << QString("-") << QString("A-C") << true;
853 QTest::newRow( dataTag: "rep01" ) << QString("$()*+.?[\\]^{|}") << QString("$()*+.?[\\]^{|}") << QString("X") << QString("X") << true;
854 QTest::newRow( dataTag: "rep02" ) << QString("ABCDEF") << QString("") << QString("X") << QString("XAXBXCXDXEXFX") << true;
855 QTest::newRow( dataTag: "rep03" ) << QString("") << QString("") << QString("X") << QString("X") << true;
856 QTest::newRow( dataTag: "rep04" ) << QString("a") << QString("a") << QString("b") << QString("b") << false;
857 QTest::newRow( dataTag: "rep05" ) << QString("A") << QString("A") << QString("b") << QString("b") << false;
858 QTest::newRow( dataTag: "rep06" ) << QString("a") << QString("A") << QString("b") << QString("b") << false;
859 QTest::newRow( dataTag: "rep07" ) << QString("A") << QString("a") << QString("b") << QString("b") << false;
860 QTest::newRow( dataTag: "rep08" ) << QString("a") << QString("a") << QString("a") << QString("a") << false;
861 QTest::newRow( dataTag: "rep09" ) << QString("A") << QString("A") << QString("a") << QString("a") << false;
862 QTest::newRow( dataTag: "rep10" ) << QString("a") << QString("A") << QString("a") << QString("a") << false;
863 QTest::newRow( dataTag: "rep11" ) << QString("A") << QString("a") << QString("a") << QString("a") << false;
864 QTest::newRow( dataTag: "rep12" ) << QString("Alpha beta") << QString("a") << QString("o") << QString("olpho beto") << false;
865 QTest::newRow( dataTag: "rep13" ) << QString() << QString("") << QString("A") << QString("A") << true;
866 QTest::newRow( dataTag: "rep14" ) << QString("") << QString() << QString("A") << QString("A") << true;
867 QTest::newRow( dataTag: "rep15" ) << QString("fooxbarxbazxblub") << QString("x") << QString("yz") << QString("fooyzbaryzbazyzblub") << true;
868 QTest::newRow( dataTag: "rep16" ) << QString("fooxbarxbazxblub") << QString("x") << QString("z") << QString("foozbarzbazzblub") << true;
869 QTest::newRow( dataTag: "rep17" ) << QString("fooxybarxybazxyblub") << QString("xy") << QString("z") << QString("foozbarzbazzblub") << true;
870}
871
872void tst_QString::replace_regexp_data()
873{
874 QTest::addColumn<QString>(name: "string" );
875 QTest::addColumn<QString>(name: "regexp" );
876 QTest::addColumn<QString>(name: "after" );
877 QTest::addColumn<QString>(name: "result" );
878
879 QTest::newRow( dataTag: "rem00" ) << QString("alpha") << QString("a+") << QString("") << QString("lph");
880 QTest::newRow( dataTag: "rem01" ) << QString("banana") << QString("^.a") << QString("") << QString("nana");
881 QTest::newRow( dataTag: "rem02" ) << QString("") << QString("^.a") << QString("") << QString("");
882 QTest::newRow( dataTag: "rem03" ) << QString("") << QString("^.a") << QString() << QString("");
883 QTest::newRow( dataTag: "rem04" ) << QString() << QString("^.a") << QString("") << QString();
884 QTest::newRow( dataTag: "rem05" ) << QString() << QString("^.a") << QString() << QString();
885
886 QTest::newRow( dataTag: "rep00" ) << QString("A <i>bon mot</i>.") << QString("<i>([^<]*)</i>") << QString("\\emph{\\1}") << QString("A \\emph{bon mot}.");
887 QTest::newRow( dataTag: "rep01" ) << QString("banana") << QString("^.a()") << QString("\\1") << QString("nana");
888 QTest::newRow( dataTag: "rep02" ) << QString("banana") << QString("(ba)") << QString("\\1X\\1") << QString("baXbanana");
889 QTest::newRow( dataTag: "rep03" ) << QString("banana") << QString("(ba)(na)na") << QString("\\2X\\1") << QString("naXba");
890
891 QTest::newRow(dataTag: "backref00") << QString("\\1\\2\\3\\4\\5\\6\\7\\8\\9\\A\\10\\11") << QString("\\\\[34]")
892 << QString("X") << QString("\\1\\2XX\\5\\6\\7\\8\\9\\A\\10\\11");
893 QTest::newRow(dataTag: "backref01") << QString("foo") << QString("[fo]") << QString("\\1") << QString("\\1\\1\\1");
894 QTest::newRow(dataTag: "backref02") << QString("foo") << QString("([fo])") << QString("(\\1)") << QString("(f)(o)(o)");
895 QTest::newRow(dataTag: "backref03") << QString("foo") << QString("([fo])") << QString("\\2") << QString("\\2\\2\\2");
896 QTest::newRow(dataTag: "backref04") << QString("foo") << QString("([fo])") << QString("\\10") << QString("f0o0o0");
897 QTest::newRow(dataTag: "backref05") << QString("foo") << QString("([fo])") << QString("\\11") << QString("f1o1o1");
898 QTest::newRow(dataTag: "backref06") << QString("foo") << QString("([fo])") << QString("\\19") << QString("f9o9o9");
899 QTest::newRow(dataTag: "backref07") << QString("foo") << QString("(f)(o+)")
900 << QString("\\2\\1\\10\\20\\11\\22\\19\\29\\3")
901 << QString("ooff0oo0f1oo2f9oo9\\3");
902 QTest::newRow(dataTag: "backref08") << QString("abc") << QString("(((((((((((((([abc]))))))))))))))")
903 << QString("{\\14}") << QString("{a}{b}{c}");
904 QTest::newRow(dataTag: "backref09") << QString("abcdefghijklmn")
905 << QString("(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)(l)(m)(n)")
906 << QString("\\19\\18\\17\\16\\15\\14\\13\\12\\11\\10"
907 "\\9\\90\\8\\80\\7\\70\\6\\60\\5\\50\\4\\40\\3\\30\\2\\20\\1")
908 << QString("a9a8a7a6a5nmlkjii0hh0gg0ff0ee0dd0cc0bb0a");
909 QTest::newRow(dataTag: "backref10") << QString("abc") << QString("((((((((((((((abc))))))))))))))")
910 << QString("\\0\\01\\011") << QString("\\0\\01\\011");
911 QTest::newRow(dataTag: "invalid") << QString("") << QString("invalid regex\\") << QString("") << QString("");
912}
913
914void tst_QString::utf8_data()
915{
916 QString str;
917 QTest::addColumn<QByteArray>(name: "utf8" );
918 QTest::addColumn<QString>(name: "res" );
919
920 QTest::newRow( dataTag: "str0" ) << QByteArray("abcdefgh")
921 << QString("abcdefgh");
922 QTest::newRow( dataTag: "str1" ) << QByteArray("\303\266\303\244\303\274\303\226\303\204\303\234\303\270\303\246\303\245\303\230\303\206\303\205")
923 << QString::fromLatin1(str: "\366\344\374\326\304\334\370\346\345\330\306\305") ;
924 str += QChar( 0x05e9 );
925 str += QChar( 0x05d3 );
926 str += QChar( 0x05d2 );
927 QTest::newRow( dataTag: "str2" ) << QByteArray("\327\251\327\223\327\222")
928 << str;
929
930 str = QChar( 0x20ac );
931 str += " some text";
932 QTest::newRow( dataTag: "str3" ) << QByteArray("\342\202\254 some text")
933 << str;
934
935 str = "Old Italic: ";
936 str += QChar(0xd800);
937 str += QChar(0xdf00);
938 str += QChar(0xd800);
939 str += QChar(0xdf01);
940 str += QChar(0xd800);
941 str += QChar(0xdf02);
942 str += QChar(0xd800);
943 str += QChar(0xdf03);
944 str += QChar(0xd800);
945 str += QChar(0xdf04);
946 QTest::newRow(dataTag: "surrogate") << QByteArray("Old Italic: \360\220\214\200\360\220\214\201\360\220\214\202\360\220\214\203\360\220\214\204") << str;
947}
948
949void tst_QString::length()
950{
951 QFETCH( QString, s1 );
952 QTEST( (int)s1.length(), "res" );
953}
954
955#include <qfile.h>
956
957void tst_QString::acc_01()
958{
959 QString a;
960 QString b; //b(10);
961 QString bb; //bb((int)0);
962 QString c("String C");
963 QChar tmp[10];
964 tmp[0] = 'S';
965 tmp[1] = 't';
966 tmp[2] = 'r';
967 tmp[3] = 'i';
968 tmp[4] = 'n';
969 tmp[5] = 'g';
970 tmp[6] = ' ';
971 tmp[7] = 'D';
972 tmp[8] = 'X';
973 tmp[9] = '\0';
974 QString d(tmp,8);
975 QString ca(a);
976 QString cb(b);
977 QString cc(c);
978 QString n;
979 QString e("String E");
980 QString f;
981 f = e;
982 f[7]='F';
983 QCOMPARE(e, QLatin1String("String E"));
984 char text[]="String f";
985 f = text;
986 text[7]='!';
987 QCOMPARE(f, QLatin1String("String f"));
988 f[7]='F';
989 QCOMPARE(text[7],'!');
990
991 a="";
992 a[0]='A';
993 QCOMPARE(a, QLatin1String("A"));
994 QCOMPARE(a.length(),1);
995 a[1]='B';
996 QCOMPARE(a, QLatin1String("AB"));
997 QCOMPARE(a.length(),2);
998 a[2]='C';
999 QCOMPARE(a, QLatin1String("ABC"));
1000 QCOMPARE(a.length(),3);
1001 a = QString();
1002 QVERIFY(a.isNull());
1003 a[0]='A';
1004 QCOMPARE(a, QLatin1String("A"));
1005 QCOMPARE(a.length(),1);
1006 a[1]='B';
1007 QCOMPARE(a, QLatin1String("AB"));
1008 QCOMPARE(a.length(),2);
1009 a[2]='C';
1010 QCOMPARE(a, QLatin1String("ABC"));
1011 QCOMPARE(a.length(),3);
1012
1013 a="123";
1014 b="456";
1015 a[0]=a[1];
1016 QCOMPARE(a, QLatin1String("223"));
1017 a[1]=b[1];
1018 QCOMPARE(b, QLatin1String("456"));
1019 QCOMPARE(a, QLatin1String("253"));
1020
1021 char t[]="TEXT";
1022 a="A";
1023 a=t;
1024 QCOMPARE(a, QLatin1String("TEXT"));
1025 QCOMPARE(a,(QString)t);
1026 a[0]='X';
1027 QCOMPARE(a, QLatin1String("XEXT"));
1028 QCOMPARE(t[0],'T');
1029 t[0]='Z';
1030 QCOMPARE(a, QLatin1String("XEXT"));
1031
1032 a="ABC";
1033 QCOMPARE(char(a.toLatin1()[1]),'B');
1034 QCOMPARE(strcmp(a.toLatin1(), QByteArrayLiteral("ABC")), 0);
1035 QCOMPARE(a+="DEF", QLatin1String("ABCDEF"));
1036 QCOMPARE(a+='G', QLatin1String("ABCDEFG"));
1037 QCOMPARE(a+=((const char*)(0)), QLatin1String("ABCDEFG"));
1038
1039 // non-member operators
1040
1041 a="ABC";
1042 b="ABC";
1043 c="ACB";
1044 d="ABCD";
1045 QVERIFY(a==b);
1046 QVERIFY(!(a==d));
1047 QVERIFY(!(a!=b));
1048 QVERIFY(a!=d);
1049 QVERIFY(!(a<b));
1050 QVERIFY(a<c);
1051 QVERIFY(a<d);
1052 QVERIFY(!(d<a));
1053 QVERIFY(!(c<a));
1054 QVERIFY(a<=b);
1055 QVERIFY(a<=d);
1056 QVERIFY(a<=c);
1057 QVERIFY(!(c<=a));
1058 QVERIFY(!(d<=a));
1059 QCOMPARE(QString(a+b), QLatin1String("ABCABC"));
1060 QCOMPARE(QString(a+"XXXX"), QLatin1String("ABCXXXX"));
1061 QCOMPARE(QString(a+'X'), QLatin1String("ABCX"));
1062 QCOMPARE(QString("XXXX"+a), QLatin1String("XXXXABC"));
1063 QCOMPARE(QString('X'+a), QLatin1String("XABC"));
1064 a = (const char*)0;
1065 QVERIFY(a.isNull());
1066 QVERIFY(*a.toLatin1().constData() == '\0');
1067 {
1068 QFile f("COMPARE.txt");
1069 f.open(flags: QIODevice::ReadOnly);
1070 QTextStream ts( &f );
1071 ts.setCodec(QTextCodec::codecForName(name: "UTF-16"));
1072 ts << "Abc";
1073 }
1074}
1075
1076QT_WARNING_PUSH
1077QT_WARNING_DISABLE_GCC("-Wformat-security")
1078QT_WARNING_DISABLE_CLANG("-Wformat-security")
1079
1080void tst_QString::isNull()
1081{
1082 QString a;
1083 QVERIFY(a.isNull());
1084
1085 const char *zero = nullptr;
1086 QVERIFY(!QString::asprintf(zero).isNull());
1087}
1088
1089QT_WARNING_POP
1090
1091void tst_QString::isEmpty()
1092{
1093 QString a;
1094 QVERIFY(a.isEmpty());
1095 QString c("Not empty");
1096 QVERIFY(!c.isEmpty());
1097}
1098
1099void tst_QString::constructor()
1100{
1101 QString a;
1102 QString b; //b(10);
1103 QString c("String C");
1104 QChar tmp[10];
1105 tmp[0] = 'S';
1106 tmp[1] = 't';
1107 tmp[2] = 'r';
1108 tmp[3] = 'i';
1109 tmp[4] = 'n';
1110 tmp[5] = 'g';
1111 tmp[6] = ' ';
1112 tmp[7] = 'D';
1113 tmp[8] = 'X';
1114 tmp[9] = '\0';
1115 QString d(tmp,8);
1116 QString ca(a);
1117 QString cb(b);
1118 QString cc(c);
1119
1120 QCOMPARE(a,ca);
1121 QVERIFY(a.isNull());
1122 QVERIFY(a == (QString)"");
1123 QCOMPARE(b,cb);
1124 QCOMPARE(c,cc);
1125 QCOMPARE(d, QLatin1String("String D"));
1126
1127 QString nullStr;
1128 QVERIFY( nullStr.isNull() );
1129 QVERIFY( nullStr.isEmpty() );
1130 QString empty("");
1131 QVERIFY( !empty.isNull() );
1132 QVERIFY( empty.isEmpty() );
1133}
1134
1135void tst_QString::constructorQByteArray_data()
1136{
1137 QTest::addColumn<QByteArray>(name: "src" );
1138 QTest::addColumn<QString>(name: "expected" );
1139
1140 QByteArray ba( 4, 0 );
1141 ba[0] = 'C';
1142 ba[1] = 'O';
1143 ba[2] = 'M';
1144 ba[3] = 'P';
1145
1146 QTest::newRow( dataTag: "1" ) << ba << QString("COMP");
1147
1148 QByteArray ba1( 7, 0 );
1149 ba1[0] = 'a';
1150 ba1[1] = 'b';
1151 ba1[2] = 'c';
1152 ba1[3] = '\0';
1153 ba1[4] = 'd';
1154 ba1[5] = 'e';
1155 ba1[6] = 'f';
1156
1157 QTest::newRow( dataTag: "2" ) << ba1 << QString("abc");
1158
1159 QTest::newRow( dataTag: "3" ) << QByteArray::fromRawData("abcd", size: 3) << QString("abc");
1160 QTest::newRow( dataTag: "4" ) << QByteArray("\xc3\xa9") << QString("\xc3\xa9");
1161 QTest::newRow( dataTag: "4-bis" ) << QByteArray("\xc3\xa9") << QString::fromUtf8(str: "\xc3\xa9");
1162 QTest::newRow( dataTag: "4-tre" ) << QByteArray("\xc3\xa9") << QString::fromLatin1(str: "\xe9");
1163}
1164
1165void tst_QString::constructorQByteArray()
1166{
1167 QFETCH(QByteArray, src);
1168 QFETCH(QString, expected);
1169
1170 QString str1(src);
1171 QCOMPARE(str1.length(), expected.length());
1172 QCOMPARE( str1, expected );
1173
1174 QString strBA(src);
1175 QCOMPARE( strBA, expected );
1176
1177 // test operator= too
1178 if (src.constData()[src.length()] == '\0') {
1179 str1.clear();
1180 str1 = src.constData();
1181 QCOMPARE( str1, expected );
1182 }
1183
1184 strBA.clear();
1185 strBA = src;
1186 QCOMPARE( strBA, expected );
1187}
1188
1189void tst_QString::STL()
1190{
1191 std::string stdstr( "QString" );
1192
1193 QString stlqt = QString::fromStdString(s: stdstr);
1194 QCOMPARE(stlqt, QString::fromLatin1(stdstr.c_str()));
1195 QCOMPARE(stlqt.toStdString(), stdstr);
1196
1197 const wchar_t arr[] = {'h', 'e', 'l', 'l', 'o', 0};
1198 std::wstring stlStr = arr;
1199
1200 QString s = QString::fromStdWString(s: stlStr);
1201
1202 QCOMPARE(s, QString::fromLatin1("hello"));
1203 QCOMPARE(stlStr, s.toStdWString());
1204}
1205
1206void tst_QString::macTypes()
1207{
1208#ifndef Q_OS_MAC
1209 QSKIP("This is a Mac-only test");
1210#else
1211 extern void tst_QString_macTypes(); // in qcore_foundation.mm
1212 tst_QString_macTypes();
1213#endif
1214}
1215
1216void tst_QString::truncate()
1217{
1218 QString e("String E");
1219 e.truncate(pos: 4);
1220 QCOMPARE(e, QLatin1String("Stri"));
1221
1222 e = "String E";
1223 e.truncate(pos: 0);
1224 QCOMPARE(e, QLatin1String(""));
1225 QVERIFY(e.isEmpty());
1226 QVERIFY(!e.isNull());
1227
1228}
1229
1230void tst_QString::chop_data()
1231{
1232 QTest::addColumn<QString>(name: "input");
1233 QTest::addColumn<int>(name: "count" );
1234 QTest::addColumn<QString>(name: "result");
1235
1236 const QString original("abcd");
1237
1238 QTest::newRow(dataTag: "data0") << original << 1 << QString("abc");
1239 QTest::newRow(dataTag: "data1") << original << 0 << original;
1240 QTest::newRow(dataTag: "data2") << original << -1 << original;
1241 QTest::newRow(dataTag: "data3") << original << original.size() << QString();
1242 QTest::newRow(dataTag: "data4") << original << 1000 << QString();
1243}
1244
1245void tst_QString::chop()
1246{
1247 QFETCH(QString, input);
1248 QFETCH(int, count);
1249 QFETCH(QString, result);
1250
1251 input.chop(n: count);
1252 QCOMPARE(input, result);
1253}
1254
1255void tst_QString::fill()
1256{
1257 QString e;
1258 e.fill(c: 'e',size: 1);
1259 QCOMPARE(e, QLatin1String("e"));
1260 QString f;
1261 f.fill(c: 'f',size: 3);
1262 QCOMPARE(f, QLatin1String("fff"));
1263 f.fill(c: 'F');
1264 QCOMPARE(f, QLatin1String("FFF"));
1265}
1266
1267static inline const void *ptrValue(quintptr v)
1268{
1269 return reinterpret_cast<const void *>(v);
1270}
1271
1272void tst_QString::asprintf()
1273{
1274 QString a;
1275 QCOMPARE(QString::asprintf("COMPARE"), QLatin1String("COMPARE"));
1276 QCOMPARE(QString::asprintf("%%%d", 1), QLatin1String("%1"));
1277 QCOMPARE(QString::asprintf("X%dY",2), QLatin1String("X2Y"));
1278 QCOMPARE(QString::asprintf("X%9iY", 50000 ), QLatin1String("X 50000Y"));
1279 QCOMPARE(QString::asprintf("X%-9sY","hello"), QLatin1String("Xhello Y"));
1280 QCOMPARE(QString::asprintf("X%-9iY", 50000 ), QLatin1String("X50000 Y"));
1281 QCOMPARE(QString::asprintf("%lf", 1.23), QLatin1String("1.230000"));
1282 QCOMPARE(QString::asprintf("%lf", 1.23456789), QLatin1String("1.234568"));
1283 QCOMPARE(QString::asprintf("%p", ptrValue(0xbfffd350)), QLatin1String("0xbfffd350"));
1284 QCOMPARE(QString::asprintf("%p", ptrValue(0)), QLatin1String("0x0"));
1285
1286 int i = 6;
1287 long l = -2;
1288 float f = 4.023f;
1289 QCOMPARE(QString::asprintf("%d %ld %f", i, l, f), QLatin1String("6 -2 4.023000"));
1290
1291 double d = -514.25683;
1292 QCOMPARE(QString::asprintf("%f", d), QLatin1String("-514.256830"));
1293}
1294
1295void tst_QString::asprintfS()
1296{
1297 QCOMPARE(QString::asprintf("%.3s", "Hello" ), QLatin1String("Hel"));
1298 QCOMPARE(QString::asprintf("%10.3s", "Hello" ), QLatin1String(" Hel"));
1299 QCOMPARE(QString::asprintf("%.10s", "Hello" ), QLatin1String("Hello"));
1300 QCOMPARE(QString::asprintf("%10.10s", "Hello" ), QLatin1String(" Hello"));
1301 QCOMPARE(QString::asprintf("%-10.10s", "Hello" ), QLatin1String("Hello "));
1302 QCOMPARE(QString::asprintf("%-10.3s", "Hello" ), QLatin1String("Hel "));
1303 QCOMPARE(QString::asprintf("%-5.5s", "Hello" ), QLatin1String("Hello"));
1304 QCOMPARE(QString::asprintf("%*s", 4, "Hello"), QLatin1String("Hello"));
1305 QCOMPARE(QString::asprintf("%*s", 10, "Hello"), QLatin1String(" Hello"));
1306 QCOMPARE(QString::asprintf("%-*s", 10, "Hello"), QLatin1String("Hello "));
1307
1308 // Check utf8 conversion for %s
1309 QCOMPARE(QString::asprintf("%s", "\303\266\303\244\303\274\303\226\303\204\303\234\303\270\303\246\303\245\303\230\303\206\303\205"), QString::fromLatin1("\366\344\374\326\304\334\370\346\345\330\306\305"));
1310
1311 int n1;
1312 QCOMPARE(QString::asprintf("%s%n%s", "hello", &n1, "goodbye"), QString("hellogoodbye"));
1313 QCOMPARE(n1, 5);
1314 qlonglong n2;
1315 QCOMPARE(QString::asprintf("%s%s%lln%s", "foo", "bar", &n2, "whiz"), QString("foobarwhiz"));
1316 QCOMPARE((int)n2, 6);
1317
1318 { // %ls
1319 QCOMPARE(QString::asprintf("%.3ls", qUtf16Printable("Hello")), QLatin1String("Hel"));
1320 QCOMPARE(QString::asprintf("%10.3ls", qUtf16Printable("Hello")), QLatin1String(" Hel"));
1321 QCOMPARE(QString::asprintf("%.10ls", qUtf16Printable("Hello")), QLatin1String("Hello"));
1322 QCOMPARE(QString::asprintf("%10.10ls", qUtf16Printable("Hello")), QLatin1String(" Hello"));
1323 QCOMPARE(QString::asprintf("%-10.10ls", qUtf16Printable("Hello")), QLatin1String("Hello "));
1324 QCOMPARE(QString::asprintf("%-10.3ls", qUtf16Printable("Hello")), QLatin1String("Hel "));
1325 QCOMPARE(QString::asprintf("%-5.5ls", qUtf16Printable("Hello")), QLatin1String("Hello"));
1326 QCOMPARE(QString::asprintf("%*ls", 4, qUtf16Printable("Hello")), QLatin1String("Hello"));
1327 QCOMPARE(QString::asprintf("%*ls", 10, qUtf16Printable("Hello")), QLatin1String(" Hello"));
1328 QCOMPARE(QString::asprintf("%-*ls", 10, qUtf16Printable("Hello")), QLatin1String("Hello "));
1329
1330 // Check utf16 is preserved for %ls
1331 QCOMPARE(QString::asprintf("%ls",
1332 qUtf16Printable("\303\266\303\244\303\274\303\226\303\204\303\234\303\270\303\246\303\245\303\230\303\206\303\205")),
1333 QLatin1String("\366\344\374\326\304\334\370\346\345\330\306\305"));
1334
1335 int n;
1336 QCOMPARE(QString::asprintf("%ls%n%s", qUtf16Printable("hello"), &n, "goodbye"), QLatin1String("hellogoodbye"));
1337 QCOMPARE(n, 5);
1338 }
1339}
1340
1341/*
1342 indexOf() and indexOf02() test QString::indexOf(),
1343 QString::lastIndexOf(), and their QByteArray equivalents.
1344
1345 lastIndexOf() tests QString::lastIndexOf() more in depth, but it
1346 should probably be rewritten to use a data table.
1347*/
1348
1349void tst_QString::indexOf_data()
1350{
1351 QTest::addColumn<QString>(name: "haystack" );
1352 QTest::addColumn<QString>(name: "needle" );
1353 QTest::addColumn<int>(name: "startpos" );
1354 QTest::addColumn<bool>(name: "bcs" );
1355 QTest::addColumn<int>(name: "resultpos" );
1356
1357 QTest::newRow( dataTag: "data0" ) << QString("abc") << QString("a") << 0 << true << 0;
1358 QTest::newRow( dataTag: "data1" ) << QString("abc") << QString("a") << 0 << false << 0;
1359 QTest::newRow( dataTag: "data2" ) << QString("abc") << QString("A") << 0 << true << -1;
1360 QTest::newRow( dataTag: "data3" ) << QString("abc") << QString("A") << 0 << false << 0;
1361 QTest::newRow( dataTag: "data4" ) << QString("abc") << QString("a") << 1 << true << -1;
1362 QTest::newRow( dataTag: "data5" ) << QString("abc") << QString("a") << 1 << false << -1;
1363 QTest::newRow( dataTag: "data6" ) << QString("abc") << QString("A") << 1 << true << -1;
1364 QTest::newRow( dataTag: "data7" ) << QString("abc") << QString("A") << 1 << false << -1;
1365 QTest::newRow( dataTag: "data8" ) << QString("abc") << QString("b") << 0 << true << 1;
1366 QTest::newRow( dataTag: "data9" ) << QString("abc") << QString("b") << 0 << false << 1;
1367 QTest::newRow( dataTag: "data10" ) << QString("abc") << QString("B") << 0 << true << -1;
1368 QTest::newRow( dataTag: "data11" ) << QString("abc") << QString("B") << 0 << false << 1;
1369 QTest::newRow( dataTag: "data12" ) << QString("abc") << QString("b") << 1 << true << 1;
1370 QTest::newRow( dataTag: "data13" ) << QString("abc") << QString("b") << 1 << false << 1;
1371 QTest::newRow( dataTag: "data14" ) << QString("abc") << QString("B") << 1 << true << -1;
1372 QTest::newRow( dataTag: "data15" ) << QString("abc") << QString("B") << 1 << false << 1;
1373 QTest::newRow( dataTag: "data16" ) << QString("abc") << QString("b") << 2 << true << -1;
1374 QTest::newRow( dataTag: "data17" ) << QString("abc") << QString("b") << 2 << false << -1;
1375
1376 QTest::newRow( dataTag: "data20" ) << QString("ABC") << QString("A") << 0 << true << 0;
1377 QTest::newRow( dataTag: "data21" ) << QString("ABC") << QString("A") << 0 << false << 0;
1378 QTest::newRow( dataTag: "data22" ) << QString("ABC") << QString("a") << 0 << true << -1;
1379 QTest::newRow( dataTag: "data23" ) << QString("ABC") << QString("a") << 0 << false << 0;
1380 QTest::newRow( dataTag: "data24" ) << QString("ABC") << QString("A") << 1 << true << -1;
1381 QTest::newRow( dataTag: "data25" ) << QString("ABC") << QString("A") << 1 << false << -1;
1382 QTest::newRow( dataTag: "data26" ) << QString("ABC") << QString("a") << 1 << true << -1;
1383 QTest::newRow( dataTag: "data27" ) << QString("ABC") << QString("a") << 1 << false << -1;
1384 QTest::newRow( dataTag: "data28" ) << QString("ABC") << QString("B") << 0 << true << 1;
1385 QTest::newRow( dataTag: "data29" ) << QString("ABC") << QString("B") << 0 << false << 1;
1386 QTest::newRow( dataTag: "data30" ) << QString("ABC") << QString("b") << 0 << true << -1;
1387 QTest::newRow( dataTag: "data31" ) << QString("ABC") << QString("b") << 0 << false << 1;
1388 QTest::newRow( dataTag: "data32" ) << QString("ABC") << QString("B") << 1 << true << 1;
1389 QTest::newRow( dataTag: "data33" ) << QString("ABC") << QString("B") << 1 << false << 1;
1390 QTest::newRow( dataTag: "data34" ) << QString("ABC") << QString("b") << 1 << true << -1;
1391 QTest::newRow( dataTag: "data35" ) << QString("ABC") << QString("b") << 1 << false << 1;
1392 QTest::newRow( dataTag: "data36" ) << QString("ABC") << QString("B") << 2 << true << -1;
1393 QTest::newRow( dataTag: "data37" ) << QString("ABC") << QString("B") << 2 << false << -1;
1394
1395 QTest::newRow( dataTag: "data40" ) << QString("aBc") << QString("bc") << 0 << true << -1;
1396 QTest::newRow( dataTag: "data41" ) << QString("aBc") << QString("Bc") << 0 << true << 1;
1397 QTest::newRow( dataTag: "data42" ) << QString("aBc") << QString("bC") << 0 << true << -1;
1398 QTest::newRow( dataTag: "data43" ) << QString("aBc") << QString("BC") << 0 << true << -1;
1399 QTest::newRow( dataTag: "data44" ) << QString("aBc") << QString("bc") << 0 << false << 1;
1400 QTest::newRow( dataTag: "data45" ) << QString("aBc") << QString("Bc") << 0 << false << 1;
1401 QTest::newRow( dataTag: "data46" ) << QString("aBc") << QString("bC") << 0 << false << 1;
1402 QTest::newRow( dataTag: "data47" ) << QString("aBc") << QString("BC") << 0 << false << 1;
1403 QTest::newRow( dataTag: "data48" ) << QString("AbC") << QString("bc") << 0 << true << -1;
1404 QTest::newRow( dataTag: "data49" ) << QString("AbC") << QString("Bc") << 0 << true << -1;
1405 QTest::newRow( dataTag: "data50" ) << QString("AbC") << QString("bC") << 0 << true << 1;
1406 QTest::newRow( dataTag: "data51" ) << QString("AbC") << QString("BC") << 0 << true << -1;
1407 QTest::newRow( dataTag: "data52" ) << QString("AbC") << QString("bc") << 0 << false << 1;
1408 QTest::newRow( dataTag: "data53" ) << QString("AbC") << QString("Bc") << 0 << false << 1;
1409
1410 QTest::newRow( dataTag: "data54" ) << QString("AbC") << QString("bC") << 0 << false << 1;
1411 QTest::newRow( dataTag: "data55" ) << QString("AbC") << QString("BC") << 0 << false << 1;
1412 QTest::newRow( dataTag: "data56" ) << QString("AbC") << QString("BC") << 1 << false << 1;
1413 QTest::newRow( dataTag: "data57" ) << QString("AbC") << QString("BC") << 2 << false << -1;
1414#if 0
1415 QTest::newRow( "null-in-null") << QString() << QString() << 0 << false << 0;
1416 QTest::newRow( "empty-in-null") << QString() << QString("") << 0 << false << 0;
1417 QTest::newRow( "null-in-empty") << QString("") << QString() << 0 << false << 0;
1418 QTest::newRow( "empty-in-empty") << QString("") << QString("") << 0 << false << 0;
1419#endif
1420
1421
1422 QString s1 = "abc";
1423 s1 += QChar(0xb5);
1424 QString s2;
1425 s2 += QChar(0x3bc);
1426 QTest::newRow( dataTag: "data58" ) << s1 << s2 << 0 << false << 3;
1427 s2.prepend(c: QLatin1Char('C'));
1428 QTest::newRow( dataTag: "data59" ) << s1 << s2 << 0 << false << 2;
1429
1430 QString veryBigHaystack(500, 'a');
1431 veryBigHaystack += 'B';
1432 QTest::newRow(dataTag: "BoyerMooreStressTest") << veryBigHaystack << veryBigHaystack << 0 << true << 0;
1433 QTest::newRow(dataTag: "BoyerMooreStressTest2") << QString(veryBigHaystack + 'c') << veryBigHaystack << 0 << true << 0;
1434 QTest::newRow(dataTag: "BoyerMooreStressTest3") << QString('c' + veryBigHaystack) << veryBigHaystack << 0 << true << 1;
1435 QTest::newRow(dataTag: "BoyerMooreStressTest4") << veryBigHaystack << QString(veryBigHaystack + 'c') << 0 << true << -1;
1436 QTest::newRow(dataTag: "BoyerMooreStressTest5") << veryBigHaystack << QString('c' + veryBigHaystack) << 0 << true << -1;
1437 QTest::newRow(dataTag: "BoyerMooreStressTest6") << QString('d' + veryBigHaystack) << QString('c' + veryBigHaystack) << 0 << true << -1;
1438 QTest::newRow(dataTag: "BoyerMooreStressTest7") << QString(veryBigHaystack + 'c') << QString('c' + veryBigHaystack) << 0 << true << -1;
1439
1440 QTest::newRow(dataTag: "BoyerMooreInsensitiveStressTest") << veryBigHaystack << veryBigHaystack << 0 << false << 0;
1441
1442}
1443
1444void tst_QString::indexOf()
1445{
1446 QFETCH( QString, haystack );
1447 QFETCH( QString, needle );
1448 QFETCH( int, startpos );
1449 QFETCH( bool, bcs );
1450 QFETCH( int, resultpos );
1451 CREATE_REF(needle);
1452
1453 Qt::CaseSensitivity cs = bcs ? Qt::CaseSensitive : Qt::CaseInsensitive;
1454
1455 bool needleIsLatin = (QString::fromLatin1(str: needle.toLatin1()) == needle);
1456
1457 QCOMPARE( haystack.indexOf(needle, startpos, cs), resultpos );
1458 QCOMPARE( haystack.indexOf(ref, startpos, cs), resultpos );
1459 if (needleIsLatin) {
1460 QCOMPARE( haystack.indexOf(needle.toLatin1(), startpos, cs), resultpos );
1461 QCOMPARE( haystack.indexOf(needle.toLatin1().data(), startpos, cs), resultpos );
1462 }
1463
1464 {
1465 QRegExp rx1 = QRegExp(QRegExp::escape(str: needle), cs);
1466 QRegExp rx2 = QRegExp(needle, cs, QRegExp::FixedString);
1467 QCOMPARE( haystack.indexOf(rx1, startpos), resultpos );
1468 QCOMPARE( haystack.indexOf(rx2, startpos), resultpos );
1469 // these QRegExp must have been modified
1470 QVERIFY( resultpos == -1 || rx1.matchedLength() > 0);
1471 QVERIFY( resultpos == -1 || rx2.matchedLength() > 0);
1472 }
1473
1474 {
1475 const QRegExp rx1 = QRegExp(QRegExp::escape(str: needle), cs);
1476 const QRegExp rx2 = QRegExp(needle, cs, QRegExp::FixedString);
1477 QCOMPARE( haystack.indexOf(rx1, startpos), resultpos );
1478 QCOMPARE( haystack.indexOf(rx2, startpos), resultpos );
1479 // our QRegExp mustn't have been modified
1480 QCOMPARE( rx1.matchedLength(), -1 );
1481 QCOMPARE( rx2.matchedLength(), -1 );
1482 }
1483
1484 {
1485 QRegularExpression::PatternOptions options = QRegularExpression::NoPatternOption;
1486 if (!bcs)
1487 options |= QRegularExpression::CaseInsensitiveOption;
1488
1489 QRegularExpression re(QRegularExpression::escape(str: needle), options);
1490 QCOMPARE( haystack.indexOf(re, startpos), resultpos );
1491 QCOMPARE(haystack.indexOf(re, startpos, nullptr), resultpos);
1492
1493 QRegularExpressionMatch match;
1494 QVERIFY(!match.hasMatch());
1495 QCOMPARE(haystack.indexOf(re, startpos, &match), resultpos);
1496 QCOMPARE(match.hasMatch(), resultpos != -1);
1497 if (resultpos > -1 && needleIsLatin) {
1498 if (bcs)
1499 QVERIFY(match.captured() == needle);
1500 else
1501 QVERIFY(match.captured().toLower() == needle.toLower());
1502 }
1503 }
1504
1505 if (cs == Qt::CaseSensitive) {
1506 QCOMPARE( haystack.indexOf(needle, startpos), resultpos );
1507 QCOMPARE( haystack.indexOf(ref, startpos), resultpos );
1508 if (needleIsLatin) {
1509 QCOMPARE( haystack.indexOf(needle.toLatin1(), startpos), resultpos );
1510 QCOMPARE( haystack.indexOf(needle.toLatin1().data(), startpos), resultpos );
1511 }
1512 if (startpos == 0) {
1513 QCOMPARE( haystack.indexOf(needle), resultpos );
1514 QCOMPARE( haystack.indexOf(ref), resultpos );
1515 if (needleIsLatin) {
1516 QCOMPARE( haystack.indexOf(needle.toLatin1()), resultpos );
1517 QCOMPARE( haystack.indexOf(needle.toLatin1().data()), resultpos );
1518 }
1519 }
1520 }
1521 if (needle.size() == 1) {
1522 QCOMPARE(haystack.indexOf(needle.at(0), startpos, cs), resultpos);
1523 QCOMPARE(haystack.indexOf(ref.at(0), startpos, cs), resultpos);
1524 }
1525
1526}
1527
1528void tst_QString::indexOf2_data()
1529{
1530 QTest::addColumn<QString>(name: "haystack" );
1531 QTest::addColumn<QString>(name: "needle" );
1532 QTest::addColumn<int>(name: "resultpos" );
1533
1534 QTest::newRow( dataTag: "data0" ) << QString() << QString() << 0;
1535 QTest::newRow( dataTag: "data1" ) << QString() << QString("") << 0;
1536 QTest::newRow( dataTag: "data2" ) << QString("") << QString() << 0;
1537 QTest::newRow( dataTag: "data3" ) << QString("") << QString("") << 0;
1538 QTest::newRow( dataTag: "data4" ) << QString() << QString("a") << -1;
1539 QTest::newRow( dataTag: "data5" ) << QString() << QString("abcdefg") << -1;
1540 QTest::newRow( dataTag: "data6" ) << QString("") << QString("a") << -1;
1541 QTest::newRow( dataTag: "data7" ) << QString("") << QString("abcdefg") << -1;
1542
1543 QTest::newRow( dataTag: "data8" ) << QString("a") << QString() << 0;
1544 QTest::newRow( dataTag: "data9" ) << QString("a") << QString("") << 0;
1545 QTest::newRow( dataTag: "data10" ) << QString("a") << QString("a") << 0;
1546 QTest::newRow( dataTag: "data11" ) << QString("a") << QString("b") << -1;
1547 QTest::newRow( dataTag: "data12" ) << QString("a") << QString("abcdefg") << -1;
1548 QTest::newRow( dataTag: "data13" ) << QString("ab") << QString() << 0;
1549 QTest::newRow( dataTag: "data14" ) << QString("ab") << QString("") << 0;
1550 QTest::newRow( dataTag: "data15" ) << QString("ab") << QString("a") << 0;
1551 QTest::newRow( dataTag: "data16" ) << QString("ab") << QString("b") << 1;
1552 QTest::newRow( dataTag: "data17" ) << QString("ab") << QString("ab") << 0;
1553 QTest::newRow( dataTag: "data18" ) << QString("ab") << QString("bc") << -1;
1554 QTest::newRow( dataTag: "data19" ) << QString("ab") << QString("abcdefg") << -1;
1555
1556 QTest::newRow( dataTag: "data30" ) << QString("abc") << QString("a") << 0;
1557 QTest::newRow( dataTag: "data31" ) << QString("abc") << QString("b") << 1;
1558 QTest::newRow( dataTag: "data32" ) << QString("abc") << QString("c") << 2;
1559 QTest::newRow( dataTag: "data33" ) << QString("abc") << QString("d") << -1;
1560 QTest::newRow( dataTag: "data34" ) << QString("abc") << QString("ab") << 0;
1561 QTest::newRow( dataTag: "data35" ) << QString("abc") << QString("bc") << 1;
1562 QTest::newRow( dataTag: "data36" ) << QString("abc") << QString("cd") << -1;
1563 QTest::newRow( dataTag: "data37" ) << QString("abc") << QString("ac") << -1;
1564
1565 // sizeof(whale) > 32
1566 QString whale = "a5zby6cx7dw8evf9ug0th1si2rj3qkp4lomn";
1567 QString minnow = "zby";
1568 QTest::newRow( dataTag: "data40" ) << whale << minnow << 2;
1569 QTest::newRow( dataTag: "data41" ) << QString(whale + whale) << minnow << 2;
1570 QTest::newRow( dataTag: "data42" ) << QString(minnow + whale) << minnow << 0;
1571 QTest::newRow( dataTag: "data43" ) << whale << whale << 0;
1572 QTest::newRow( dataTag: "data44" ) << QString(whale + whale) << whale << 0;
1573 QTest::newRow( dataTag: "data45" ) << whale << QString(whale + whale) << -1;
1574 QTest::newRow( dataTag: "data46" ) << QString(whale + whale) << QString(whale + whale) << 0;
1575 QTest::newRow( dataTag: "data47" ) << QString(whale + whale) << QString(whale + minnow) << -1;
1576 QTest::newRow( dataTag: "data48" ) << QString(minnow + whale) << whale << (int)minnow.length();
1577}
1578
1579void tst_QString::indexOf2()
1580{
1581 QFETCH( QString, haystack );
1582 QFETCH( QString, needle );
1583 QFETCH( int, resultpos );
1584 CREATE_REF(needle);
1585
1586 QByteArray chaystack = haystack.toLatin1();
1587 QByteArray cneedle = needle.toLatin1();
1588 int got;
1589
1590 QCOMPARE( haystack.indexOf(needle, 0, Qt::CaseSensitive), resultpos );
1591 QCOMPARE( haystack.indexOf(ref, 0, Qt::CaseSensitive), resultpos );
1592 QCOMPARE( QStringMatcher(needle, Qt::CaseSensitive).indexIn(haystack, 0), resultpos );
1593 QCOMPARE( haystack.indexOf(needle, 0, Qt::CaseInsensitive), resultpos );
1594 QCOMPARE( haystack.indexOf(ref, 0, Qt::CaseInsensitive), resultpos );
1595 QCOMPARE( QStringMatcher(needle, Qt::CaseInsensitive).indexIn(haystack, 0), resultpos );
1596 if ( needle.length() > 0 ) {
1597 got = haystack.lastIndexOf( s: needle, from: -1, cs: Qt::CaseSensitive );
1598 QVERIFY( got == resultpos || (resultpos >= 0 && got >= resultpos) );
1599 got = haystack.lastIndexOf( s: needle, from: -1, cs: Qt::CaseInsensitive );
1600 QVERIFY( got == resultpos || (resultpos >= 0 && got >= resultpos) );
1601 }
1602
1603 QCOMPARE( chaystack.indexOf(cneedle, 0), resultpos );
1604 QCOMPARE( QByteArrayMatcher(cneedle).indexIn(chaystack, 0), resultpos );
1605 if ( cneedle.length() > 0 ) {
1606 got = chaystack.lastIndexOf(a: cneedle, from: -1);
1607 QVERIFY( got == resultpos || (resultpos >= 0 && got >= resultpos) );
1608 }
1609}
1610
1611void tst_QString::indexOfInvalidRegex()
1612{
1613 QTest::ignoreMessage(type: QtWarningMsg, message: "QString::indexOf: invalid QRegularExpression object");
1614 QCOMPARE(QString("invalid regex\\").indexOf(QRegularExpression("invalid regex\\")), -1);
1615 QTest::ignoreMessage(type: QtWarningMsg, message: "QString::indexOf: invalid QRegularExpression object");
1616 QCOMPARE(QString("invalid regex\\").indexOf(QRegularExpression("invalid regex\\"), -1, nullptr), -1);
1617
1618 QRegularExpressionMatch match;
1619 QVERIFY(!match.hasMatch());
1620 QTest::ignoreMessage(type: QtWarningMsg, message: "QString::indexOf: invalid QRegularExpression object");
1621 QCOMPARE(QString("invalid regex\\").indexOf(QRegularExpression("invalid regex\\"), -1, &match), -1);
1622 QVERIFY(!match.hasMatch());
1623}
1624
1625void tst_QString::lastIndexOf_data()
1626{
1627 QTest::addColumn<QString>(name: "haystack" );
1628 QTest::addColumn<QString>(name: "needle" );
1629 QTest::addColumn<int>(name: "from" );
1630 QTest::addColumn<int>(name: "expected" );
1631 QTest::addColumn<bool>(name: "caseSensitive" );
1632
1633 QString a = "ABCDEFGHIEfGEFG";
1634
1635 QTest::newRow(dataTag: "-1") << a << "G" << a.size() - 1 << 14 << true;
1636 QTest::newRow(dataTag: "1") << a << "G" << - 1 << 14 << true;
1637 QTest::newRow(dataTag: "2") << a << "G" << -3 << 11 << true;
1638 QTest::newRow(dataTag: "3") << a << "G" << -5 << 6 << true;
1639 QTest::newRow(dataTag: "4") << a << "G" << 14 << 14 << true;
1640 QTest::newRow(dataTag: "5") << a << "G" << 13 << 11 << true;
1641 QTest::newRow(dataTag: "6") << a << "B" << a.size() - 1 << 1 << true;
1642 QTest::newRow(dataTag: "7") << a << "B" << - 1 << 1 << true;
1643 QTest::newRow(dataTag: "8") << a << "B" << 1 << 1 << true;
1644 QTest::newRow(dataTag: "9") << a << "B" << 0 << -1 << true;
1645
1646 QTest::newRow(dataTag: "10") << a << "G" << -1 << a.size()-1 << true;
1647 QTest::newRow(dataTag: "11") << a << "G" << a.size()-1 << a.size()-1 << true;
1648 QTest::newRow(dataTag: "12") << a << "G" << a.size() << -1 << true;
1649 QTest::newRow(dataTag: "13") << a << "A" << 0 << 0 << true;
1650 QTest::newRow(dataTag: "14") << a << "A" << -1*a.size() << 0 << true;
1651
1652 QTest::newRow(dataTag: "15") << a << "efg" << 0 << -1 << false;
1653 QTest::newRow(dataTag: "16") << a << "efg" << a.size() << -1 << false;
1654 QTest::newRow(dataTag: "17") << a << "efg" << -1 * a.size() << -1 << false;
1655 QTest::newRow(dataTag: "19") << a << "efg" << a.size() - 1 << 12 << false;
1656 QTest::newRow(dataTag: "20") << a << "efg" << 12 << 12 << false;
1657 QTest::newRow(dataTag: "21") << a << "efg" << -12 << -1 << false;
1658 QTest::newRow(dataTag: "22") << a << "efg" << 11 << 9 << false;
1659
1660 QTest::newRow(dataTag: "24") << "" << "asdf" << -1 << -1 << false;
1661 QTest::newRow(dataTag: "25") << "asd" << "asdf" << -1 << -1 << false;
1662 QTest::newRow(dataTag: "26") << "" << QString() << -1 << -1 << false;
1663
1664 QTest::newRow(dataTag: "27") << a << "" << a.size() << a.size() << false;
1665 QTest::newRow(dataTag: "28") << a << "" << a.size() + 10 << -1 << false;
1666}
1667
1668void tst_QString::lastIndexOf()
1669{
1670 QFETCH(QString, haystack);
1671 QFETCH(QString, needle);
1672 QFETCH(int, from);
1673 QFETCH(int, expected);
1674 QFETCH(bool, caseSensitive);
1675 CREATE_REF(needle);
1676
1677 Qt::CaseSensitivity cs = (caseSensitive ? Qt::CaseSensitive : Qt::CaseInsensitive);
1678
1679 QCOMPARE(haystack.lastIndexOf(needle, from, cs), expected);
1680 QCOMPARE(haystack.lastIndexOf(ref, from, cs), expected);
1681 QCOMPARE(haystack.lastIndexOf(needle.toLatin1(), from, cs), expected);
1682 QCOMPARE(haystack.lastIndexOf(needle.toLatin1().data(), from, cs), expected);
1683
1684 if (from >= -1 && from < haystack.size()) {
1685 // unfortunately, QString and QRegExp don't have the same out of bound semantics
1686 // I think QString is wrong -- See file log for contact information.
1687 {
1688 QRegExp rx1 = QRegExp(QRegExp::escape(str: needle), cs);
1689 QRegExp rx2 = QRegExp(needle, cs, QRegExp::FixedString);
1690 QCOMPARE(haystack.lastIndexOf(rx1, from), expected);
1691 QCOMPARE(haystack.lastIndexOf(rx2, from), expected);
1692 // our QRegExp mustn't have been modified
1693 QVERIFY(expected == -1 || rx1.matchedLength() > 0);
1694 QVERIFY(expected == -1 || rx2.matchedLength() > 0);
1695 }
1696
1697 {
1698 const QRegExp rx1 = QRegExp(QRegExp::escape(str: needle), cs);
1699 const QRegExp rx2 = QRegExp(needle, cs, QRegExp::FixedString);
1700 QCOMPARE(haystack.lastIndexOf(rx1, from), expected);
1701 QCOMPARE(haystack.lastIndexOf(rx2, from), expected);
1702 // our QRegExp mustn't have been modified
1703 QCOMPARE(rx1.matchedLength(), -1);
1704 QCOMPARE(rx2.matchedLength(), -1);
1705 }
1706
1707 {
1708 QRegularExpression::PatternOptions options = QRegularExpression::NoPatternOption;
1709 if (!caseSensitive)
1710 options |= QRegularExpression::CaseInsensitiveOption;
1711
1712 QRegularExpression re(QRegularExpression::escape(str: needle), options);
1713 QCOMPARE(haystack.lastIndexOf(re, from), expected);
1714 QCOMPARE(haystack.lastIndexOf(re, from, nullptr), expected);
1715 QRegularExpressionMatch match;
1716 QVERIFY(!match.hasMatch());
1717 QCOMPARE(haystack.lastIndexOf(re, from, &match), expected);
1718 QCOMPARE(match.hasMatch(), expected > -1);
1719 if (expected > -1) {
1720 if (caseSensitive)
1721 QCOMPARE(match.captured(), needle);
1722 else
1723 QCOMPARE(match.captured().toLower(), needle.toLower());
1724 }
1725 }
1726 }
1727
1728 if (cs == Qt::CaseSensitive) {
1729 QCOMPARE(haystack.lastIndexOf(needle, from), expected);
1730 QCOMPARE(haystack.lastIndexOf(ref, from), expected);
1731 QCOMPARE(haystack.lastIndexOf(needle.toLatin1(), from), expected);
1732 QCOMPARE(haystack.lastIndexOf(needle.toLatin1().data(), from), expected);
1733 if (from == -1) {
1734 QCOMPARE(haystack.lastIndexOf(needle), expected);
1735 QCOMPARE(haystack.lastIndexOf(ref), expected);
1736 QCOMPARE(haystack.lastIndexOf(needle.toLatin1()), expected);
1737 QCOMPARE(haystack.lastIndexOf(needle.toLatin1().data()), expected);
1738 }
1739 }
1740 if (needle.size() == 1) {
1741 QCOMPARE(haystack.lastIndexOf(needle.at(0), from), expected);
1742 QCOMPARE(haystack.lastIndexOf(ref.at(0), from), expected);
1743 }
1744}
1745
1746void tst_QString::lastIndexOfInvalidRegex()
1747{
1748 QTest::ignoreMessage(type: QtWarningMsg, message: "QString::lastIndexOf: invalid QRegularExpression object");
1749 QCOMPARE(QString("invalid regex\\").lastIndexOf(QRegularExpression("invalid regex\\"), 0), -1);
1750 QTest::ignoreMessage(type: QtWarningMsg, message: "QString::lastIndexOf: invalid QRegularExpression object");
1751 QCOMPARE(QString("invalid regex\\").lastIndexOf(QRegularExpression("invalid regex\\"), -1, nullptr), -1);
1752
1753 QRegularExpressionMatch match;
1754 QVERIFY(!match.hasMatch());
1755 QTest::ignoreMessage(type: QtWarningMsg, message: "QString::lastIndexOf: invalid QRegularExpression object");
1756 QCOMPARE(QString("invalid regex\\").lastIndexOf(QRegularExpression("invalid regex\\"), -1, &match), -1);
1757 QVERIFY(!match.hasMatch());
1758}
1759
1760void tst_QString::count()
1761{
1762 QString a;
1763 a="ABCDEFGHIEfGEFG"; // 15 chars
1764 QCOMPARE(a.count('A'),1);
1765 QCOMPARE(a.count('Z'),0);
1766 QCOMPARE(a.count('E'),3);
1767 QCOMPARE(a.count('F'),2);
1768 QCOMPARE(a.count('F',Qt::CaseInsensitive),3);
1769 QCOMPARE(a.count("FG"),2);
1770 QCOMPARE(a.count("FG",Qt::CaseInsensitive),3);
1771 QCOMPARE(a.count( QString(), Qt::CaseInsensitive), 16);
1772 QCOMPARE(a.count( "", Qt::CaseInsensitive), 16);
1773 QCOMPARE(a.count(QRegExp("[FG][HI]")),1);
1774 QCOMPARE(a.count(QRegExp("[G][HE]")),2);
1775 QCOMPARE(a.count(QRegularExpression("")), 16);
1776 QCOMPARE(a.count(QRegularExpression("[FG][HI]")), 1);
1777 QCOMPARE(a.count(QRegularExpression("[G][HE]")), 2);
1778 QTest::ignoreMessage(type: QtWarningMsg, message: "QString::count: invalid QRegularExpression object");
1779 QCOMPARE(a.count(QRegularExpression("invalid regex\\")), 0);
1780
1781 CREATE_REF(QLatin1String("FG"));
1782 QCOMPARE(a.count(ref),2);
1783 QCOMPARE(a.count(ref,Qt::CaseInsensitive),3);
1784 QCOMPARE(a.count( QStringRef(), Qt::CaseInsensitive), 16);
1785 QStringRef emptyRef(&a, 0, 0);
1786 QCOMPARE(a.count( emptyRef, Qt::CaseInsensitive), 16);
1787
1788}
1789
1790void tst_QString::contains()
1791{
1792 QString a;
1793 a="ABCDEFGHIEfGEFG"; // 15 chars
1794 QVERIFY(a.contains('A'));
1795 QVERIFY(!a.contains('Z'));
1796 QVERIFY(a.contains('E'));
1797 QVERIFY(a.contains('F'));
1798 QVERIFY(a.contains('F',Qt::CaseInsensitive));
1799 QVERIFY(a.contains("FG"));
1800 QVERIFY(a.contains("FG",Qt::CaseInsensitive));
1801 QVERIFY(a.contains(QLatin1String("FG")));
1802 QVERIFY(a.contains(QLatin1String("fg"),Qt::CaseInsensitive));
1803 QVERIFY(a.contains( QString(), Qt::CaseInsensitive));
1804 QVERIFY(a.contains( "", Qt::CaseInsensitive));
1805 QVERIFY(a.contains(QRegExp("[FG][HI]")));
1806 QVERIFY(a.contains(QRegExp("[G][HE]")));
1807 QVERIFY(a.contains(QRegularExpression("[FG][HI]")));
1808 QVERIFY(a.contains(QRegularExpression("[G][HE]")));
1809
1810 {
1811 QRegularExpressionMatch match;
1812 QVERIFY(!match.hasMatch());
1813
1814 QVERIFY(a.contains(QRegularExpression("[FG][HI]"), &match));
1815 QVERIFY(match.hasMatch());
1816 QCOMPARE(match.capturedStart(), 6);
1817 QCOMPARE(match.capturedEnd(), 8);
1818 QCOMPARE(match.captured(), QStringLiteral("GH"));
1819
1820 QVERIFY(a.contains(QRegularExpression("[G][HE]"), &match));
1821 QVERIFY(match.hasMatch());
1822 QCOMPARE(match.capturedStart(), 6);
1823 QCOMPARE(match.capturedEnd(), 8);
1824 QCOMPARE(match.captured(), QStringLiteral("GH"));
1825
1826 QVERIFY(a.contains(QRegularExpression("[f](.*)[FG]"), &match));
1827 QVERIFY(match.hasMatch());
1828 QCOMPARE(match.capturedStart(), 10);
1829 QCOMPARE(match.capturedEnd(), 15);
1830 QCOMPARE(match.captured(), QString("fGEFG"));
1831 QCOMPARE(match.capturedStart(1), 11);
1832 QCOMPARE(match.capturedEnd(1), 14);
1833 QCOMPARE(match.captured(1), QStringLiteral("GEF"));
1834
1835 QVERIFY(a.contains(QRegularExpression("[f](.*)[F]"), &match));
1836 QVERIFY(match.hasMatch());
1837 QCOMPARE(match.capturedStart(), 10);
1838 QCOMPARE(match.capturedEnd(), 14);
1839 QCOMPARE(match.captured(), QString("fGEF"));
1840 QCOMPARE(match.capturedStart(1), 11);
1841 QCOMPARE(match.capturedEnd(1), 13);
1842 QCOMPARE(match.captured(1), QStringLiteral("GE"));
1843
1844 QVERIFY(!a.contains(QRegularExpression("ZZZ"), &match));
1845 // doesn't match, but ensure match didn't change
1846 QVERIFY(match.hasMatch());
1847 QCOMPARE(match.capturedStart(), 10);
1848 QCOMPARE(match.capturedEnd(), 14);
1849 QCOMPARE(match.captured(), QStringLiteral("fGEF"));
1850 QCOMPARE(match.capturedStart(1), 11);
1851 QCOMPARE(match.capturedEnd(1), 13);
1852 QCOMPARE(match.captured(1), QStringLiteral("GE"));
1853
1854 // don't crash with a null pointer
1855 QVERIFY(a.contains(QRegularExpression("[FG][HI]"), 0));
1856 QVERIFY(!a.contains(QRegularExpression("ZZZ"), 0));
1857 }
1858
1859 CREATE_REF(QLatin1String("FG"));
1860 QVERIFY(a.contains(ref));
1861 QVERIFY(a.contains(ref, Qt::CaseInsensitive));
1862 QVERIFY(a.contains( QStringRef(), Qt::CaseInsensitive));
1863 QStringRef emptyRef(&a, 0, 0);
1864 QVERIFY(a.contains(emptyRef, Qt::CaseInsensitive));
1865
1866 QTest::ignoreMessage(type: QtWarningMsg, message: "QString::contains: invalid QRegularExpression object");
1867 QVERIFY(!a.contains(QRegularExpression("invalid regex\\")));
1868}
1869
1870
1871void tst_QString::left()
1872{
1873 QString a;
1874 a="ABCDEFGHIEfGEFG"; // 15 chars
1875 QCOMPARE(a.left(3), QLatin1String("ABC"));
1876 QVERIFY(!a.left(0).isNull());
1877 QCOMPARE(a.left(0), QLatin1String(""));
1878
1879 QString n;
1880 QVERIFY(n.left(3).isNull());
1881 QVERIFY(n.left(0).isNull());
1882 QVERIFY(n.left(0).isNull());
1883
1884 QString l = "Left";
1885 QCOMPARE(l.left(-1), l);
1886 QCOMPARE(l.left(100), l);
1887}
1888
1889void tst_QString::leftRef()
1890{
1891 QString a;
1892 a="ABCDEFGHIEfGEFG"; // 15 chars
1893 QCOMPARE(a.leftRef(3).toString(), QLatin1String("ABC"));
1894
1895 QVERIFY(a.leftRef(0).toString().isEmpty());
1896 QCOMPARE(a.leftRef(0).toString(), QLatin1String(""));
1897
1898 QString n;
1899 QVERIFY(n.leftRef(3).toString().isEmpty());
1900 QVERIFY(n.leftRef(0).toString().isEmpty());
1901 QVERIFY(n.leftRef(0).toString().isEmpty());
1902
1903 QString l = "Left";
1904 QCOMPARE(l.leftRef(-1).toString(), l);
1905 QCOMPARE(l.leftRef(100).toString(), l);
1906}
1907
1908void tst_QString::right()
1909{
1910 QString a;
1911 a="ABCDEFGHIEfGEFG"; // 15 chars
1912 QCOMPARE(a.right(3), QLatin1String("EFG"));
1913 QCOMPARE(a.right(0), QLatin1String(""));
1914
1915 QString n;
1916 QVERIFY(n.right(3).isNull());
1917 QVERIFY(n.right(0).isNull());
1918
1919 QString r = "Right";
1920 QCOMPARE(r.right(-1), r);
1921 QCOMPARE(r.right(100), r);
1922}
1923
1924void tst_QString::rightRef()
1925{
1926 QString a;
1927 a="ABCDEFGHIEfGEFG"; // 15 chars
1928 QCOMPARE(a.rightRef(3).toString(), QLatin1String("EFG"));
1929 QCOMPARE(a.rightRef(0).toString(), QLatin1String(""));
1930
1931 QString n;
1932 QVERIFY(n.rightRef(3).toString().isEmpty());
1933 QVERIFY(n.rightRef(0).toString().isEmpty());
1934
1935 QString r = "Right";
1936 QCOMPARE(r.rightRef(-1).toString(), r);
1937 QCOMPARE(r.rightRef(100).toString(), r);
1938}
1939
1940void tst_QString::mid()
1941{
1942 QString a;
1943 a="ABCDEFGHIEfGEFG"; // 15 chars
1944
1945 QCOMPARE(a.mid(3,3), QLatin1String("DEF"));
1946 QCOMPARE(a.mid(0,0), QLatin1String(""));
1947 QVERIFY(!a.mid(15,0).isNull());
1948 QVERIFY(a.mid(15,0).isEmpty());
1949 QVERIFY(!a.mid(15,1).isNull());
1950 QVERIFY(a.mid(15,1).isEmpty());
1951 QVERIFY(a.mid(9999).isNull());
1952 QVERIFY(a.mid(9999,1).isNull());
1953
1954 QCOMPARE(a.mid(-1, 6), a.mid(0, 5));
1955 QVERIFY(a.mid(-100, 6).isEmpty());
1956 QVERIFY(a.mid(INT_MIN, 0).isEmpty());
1957 QCOMPARE(a.mid(INT_MIN, -1), a);
1958 QVERIFY(a.mid(INT_MIN, INT_MAX).isNull());
1959 QVERIFY(a.mid(INT_MIN + 1, INT_MAX).isEmpty());
1960 QCOMPARE(a.mid(INT_MIN + 2, INT_MAX), a.left(1));
1961 QCOMPARE(a.mid(INT_MIN + a.size() + 1, INT_MAX), a);
1962 QVERIFY(a.mid(INT_MAX).isNull());
1963 QVERIFY(a.mid(INT_MAX, INT_MAX).isNull());
1964 QCOMPARE(a.mid(-5, INT_MAX), a);
1965 QCOMPARE(a.mid(-1, INT_MAX), a);
1966 QCOMPARE(a.mid(0, INT_MAX), a);
1967 QCOMPARE(a.mid(1, INT_MAX), QString("BCDEFGHIEfGEFG"));
1968 QCOMPARE(a.mid(5, INT_MAX), QString("FGHIEfGEFG"));
1969 QVERIFY(a.mid(20, INT_MAX).isNull());
1970 QCOMPARE(a.mid(-1, -1), a);
1971
1972 QString n;
1973 QVERIFY(n.mid(3,3).isNull());
1974 QVERIFY(n.mid(0,0).isNull());
1975 QVERIFY(n.mid(9999,0).isNull());
1976 QVERIFY(n.mid(9999,1).isNull());
1977
1978 QVERIFY(n.mid(-1, 6).isNull());
1979 QVERIFY(n.mid(-100, 6).isNull());
1980 QVERIFY(n.mid(INT_MIN, 0).isNull());
1981 QVERIFY(n.mid(INT_MIN, -1).isNull());
1982 QVERIFY(n.mid(INT_MIN, INT_MAX).isNull());
1983 QVERIFY(n.mid(INT_MIN + 1, INT_MAX).isNull());
1984 QVERIFY(n.mid(INT_MIN + 2, INT_MAX).isNull());
1985 QVERIFY(n.mid(INT_MIN + n.size() + 1, INT_MAX).isNull());
1986 QVERIFY(n.mid(INT_MAX).isNull());
1987 QVERIFY(n.mid(INT_MAX, INT_MAX).isNull());
1988 QVERIFY(n.mid(-5, INT_MAX).isNull());
1989 QVERIFY(n.mid(-1, INT_MAX).isNull());
1990 QVERIFY(n.mid(0, INT_MAX).isNull());
1991 QVERIFY(n.mid(1, INT_MAX).isNull());
1992 QVERIFY(n.mid(5, INT_MAX).isNull());
1993 QVERIFY(n.mid(20, INT_MAX).isNull());
1994 QVERIFY(n.mid(-1, -1).isNull());
1995
1996 QString x = "Nine pineapples";
1997 QCOMPARE(x.mid(5, 4), QString("pine"));
1998 QCOMPARE(x.mid(5), QString("pineapples"));
1999
2000 QCOMPARE(x.mid(-1, 6), x.mid(0, 5));
2001 QVERIFY(x.mid(-100, 6).isEmpty());
2002 QVERIFY(x.mid(INT_MIN, 0).isEmpty());
2003 QCOMPARE(x.mid(INT_MIN, -1), x);
2004 QVERIFY(x.mid(INT_MIN, INT_MAX).isNull());
2005 QVERIFY(x.mid(INT_MIN + 1, INT_MAX).isEmpty());
2006 QCOMPARE(x.mid(INT_MIN + 2, INT_MAX), x.left(1));
2007 QCOMPARE(x.mid(INT_MIN + x.size() + 1, INT_MAX), x);
2008 QVERIFY(x.mid(INT_MAX).isNull());
2009 QVERIFY(x.mid(INT_MAX, INT_MAX).isNull());
2010 QCOMPARE(x.mid(-5, INT_MAX), x);
2011 QCOMPARE(x.mid(-1, INT_MAX), x);
2012 QCOMPARE(x.mid(0, INT_MAX), x);
2013 QCOMPARE(x.mid(1, INT_MAX), QString("ine pineapples"));
2014 QCOMPARE(x.mid(5, INT_MAX), QString("pineapples"));
2015 QVERIFY(x.mid(20, INT_MAX).isNull());
2016 QCOMPARE(x.mid(-1, -1), x);
2017}
2018
2019void tst_QString::midRef()
2020{
2021 QString a;
2022 a="ABCDEFGHIEfGEFG"; // 15 chars
2023
2024 QCOMPARE(a.midRef(3,3).toString(), QLatin1String("DEF"));
2025 QCOMPARE(a.midRef(0,0).toString(), QLatin1String(""));
2026 QVERIFY(!a.midRef(15,0).toString().isNull());
2027 QVERIFY(a.midRef(15,0).toString().isEmpty());
2028 QVERIFY(!a.midRef(15,1).toString().isNull());
2029 QVERIFY(a.midRef(15,1).toString().isEmpty());
2030 QVERIFY(a.midRef(9999).toString().isEmpty());
2031 QVERIFY(a.midRef(9999,1).toString().isEmpty());
2032
2033 QCOMPARE(a.midRef(-1, 6), a.midRef(0, 5));
2034 QVERIFY(a.midRef(-100, 6).isEmpty());
2035 QVERIFY(a.midRef(INT_MIN, 0).isEmpty());
2036 QCOMPARE(a.midRef(INT_MIN, -1).toString(), a);
2037 QVERIFY(a.midRef(INT_MIN, INT_MAX).isNull());
2038 QVERIFY(a.midRef(INT_MIN + 1, INT_MAX).isEmpty());
2039 QCOMPARE(a.midRef(INT_MIN + 2, INT_MAX), a.leftRef(1));
2040 QCOMPARE(a.midRef(INT_MIN + a.size() + 1, INT_MAX).toString(), a);
2041 QVERIFY(a.midRef(INT_MAX).isNull());
2042 QVERIFY(a.midRef(INT_MAX, INT_MAX).isNull());
2043 QCOMPARE(a.midRef(-5, INT_MAX).toString(), a);
2044 QCOMPARE(a.midRef(-1, INT_MAX).toString(), a);
2045 QCOMPARE(a.midRef(0, INT_MAX).toString(), a);
2046 QCOMPARE(a.midRef(1, INT_MAX).toString(), QString("BCDEFGHIEfGEFG"));
2047 QCOMPARE(a.midRef(5, INT_MAX).toString(), QString("FGHIEfGEFG"));
2048 QVERIFY(a.midRef(20, INT_MAX).isNull());
2049 QCOMPARE(a.midRef(-1, -1).toString(), a);
2050
2051 QString n;
2052 QVERIFY(n.midRef(3,3).toString().isEmpty());
2053 QVERIFY(n.midRef(0,0).toString().isEmpty());
2054 QVERIFY(n.midRef(9999,0).toString().isEmpty());
2055 QVERIFY(n.midRef(9999,1).toString().isEmpty());
2056
2057 QVERIFY(n.midRef(-1, 6).isNull());
2058 QVERIFY(n.midRef(-100, 6).isNull());
2059 QVERIFY(n.midRef(INT_MIN, 0).isNull());
2060 QVERIFY(n.midRef(INT_MIN, -1).isNull());
2061 QVERIFY(n.midRef(INT_MIN, INT_MAX).isNull());
2062 QVERIFY(n.midRef(INT_MIN + 1, INT_MAX).isNull());
2063 QVERIFY(n.midRef(INT_MIN + 2, INT_MAX).isNull());
2064 QVERIFY(n.midRef(INT_MIN + n.size() + 1, INT_MAX).isNull());
2065 QVERIFY(n.midRef(INT_MAX).isNull());
2066 QVERIFY(n.midRef(INT_MAX, INT_MAX).isNull());
2067 QVERIFY(n.midRef(-5, INT_MAX).isNull());
2068 QVERIFY(n.midRef(-1, INT_MAX).isNull());
2069 QVERIFY(n.midRef(0, INT_MAX).isNull());
2070 QVERIFY(n.midRef(1, INT_MAX).isNull());
2071 QVERIFY(n.midRef(5, INT_MAX).isNull());
2072 QVERIFY(n.midRef(20, INT_MAX).isNull());
2073 QVERIFY(n.midRef(-1, -1).isNull());
2074
2075 QString x = "Nine pineapples";
2076 QCOMPARE(x.midRef(5, 4).toString(), QString("pine"));
2077 QCOMPARE(x.midRef(5).toString(), QString("pineapples"));
2078
2079 QCOMPARE(x.midRef(-1, 6), x.midRef(0, 5));
2080 QVERIFY(x.midRef(-100, 6).isEmpty());
2081 QVERIFY(x.midRef(INT_MIN, 0).isEmpty());
2082 QCOMPARE(x.midRef(INT_MIN, -1).toString(), x);
2083 QVERIFY(x.midRef(INT_MIN, INT_MAX).isNull());
2084 QVERIFY(x.midRef(INT_MIN + 1, INT_MAX).isEmpty());
2085 QCOMPARE(x.midRef(INT_MIN + 2, INT_MAX), x.leftRef(1));
2086 QCOMPARE(x.midRef(INT_MIN + x.size() + 1, INT_MAX).toString(), x);
2087 QVERIFY(x.midRef(INT_MAX).isNull());
2088 QVERIFY(x.midRef(INT_MAX, INT_MAX).isNull());
2089 QCOMPARE(x.midRef(-5, INT_MAX).toString(), x);
2090 QCOMPARE(x.midRef(-1, INT_MAX).toString(), x);
2091 QCOMPARE(x.midRef(0, INT_MAX).toString(), x);
2092 QCOMPARE(x.midRef(1, INT_MAX).toString(), QString("ine pineapples"));
2093 QCOMPARE(x.midRef(5, INT_MAX).toString(), QString("pineapples"));
2094 QVERIFY(x.midRef(20, INT_MAX).isNull());
2095 QCOMPARE(x.midRef(-1, -1).toString(), x);
2096}
2097
2098void tst_QString::stringRef()
2099{
2100 QString a;
2101 a="ABCDEFGHIEfGEFG"; // 15 chars
2102
2103 QVERIFY(QStringRef(&a, 0, 0) == (QString)"");
2104
2105 QVERIFY(QStringRef(&a, 3, 3) == (QString)"DEF");
2106 QVERIFY(QStringRef(&a, 3, 3) == QLatin1String("DEF"));
2107 QVERIFY(QStringRef(&a, 3, 3) == "DEF");
2108 QVERIFY((QString)"DEF" == QStringRef(&a, 3, 3));
2109 QVERIFY(QLatin1String("DEF") == QStringRef(&a, 3, 3));
2110 QVERIFY("DEF" == QStringRef(&a, 3, 3));
2111
2112 QVERIFY(QStringRef(&a, 3, 3) != (QString)"DE");
2113 QVERIFY(QStringRef(&a, 3, 3) != QLatin1String("DE"));
2114 QVERIFY(QStringRef(&a, 3, 3) != "DE");
2115 QVERIFY((QString)"DE" != QStringRef(&a, 3, 3));
2116 QVERIFY(QLatin1String("DE") != QStringRef(&a, 3, 3));
2117 QVERIFY("DE" != QStringRef(&a, 3, 3));
2118
2119 QString s_alpha("alpha");
2120 QString s_beta("beta");
2121 QStringRef alpha(&s_alpha);
2122 QStringRef beta(&s_beta);
2123
2124 QVERIFY(alpha < beta);
2125 QVERIFY(alpha <= beta);
2126 QVERIFY(alpha <= alpha);
2127 QVERIFY(beta > alpha);
2128 QVERIFY(beta >= alpha);
2129 QVERIFY(beta >= beta);
2130
2131 QString s_alpha2("alpha");
2132
2133 QMap<QStringRef, QString> map;
2134 map.insert(akey: alpha, avalue: "alpha");
2135 map.insert(akey: beta, avalue: "beta");
2136 QVERIFY(alpha == map.value(QStringRef(&s_alpha2)));
2137
2138 QHash<QStringRef, QString> hash;
2139 hash.insert(akey: alpha, avalue: "alpha");
2140 hash.insert(akey: beta, avalue: "beta");
2141
2142 QVERIFY(alpha == hash.value(QStringRef(&s_alpha2)));
2143}
2144
2145void tst_QString::leftJustified()
2146{
2147 QString a;
2148 a="ABC";
2149 QCOMPARE(a.leftJustified(5,'-'), QLatin1String("ABC--"));
2150 QCOMPARE(a.leftJustified(4,'-'), QLatin1String("ABC-"));
2151 QCOMPARE(a.leftJustified(4), QLatin1String("ABC "));
2152 QCOMPARE(a.leftJustified(3), QLatin1String("ABC"));
2153 QCOMPARE(a.leftJustified(2), QLatin1String("ABC"));
2154 QCOMPARE(a.leftJustified(1), QLatin1String("ABC"));
2155 QCOMPARE(a.leftJustified(0), QLatin1String("ABC"));
2156
2157 QString n;
2158 QVERIFY(!n.leftJustified(3).isNull());
2159 QCOMPARE(a.leftJustified(4,' ',true), QLatin1String("ABC "));
2160 QCOMPARE(a.leftJustified(3,' ',true), QLatin1String("ABC"));
2161 QCOMPARE(a.leftJustified(2,' ',true), QLatin1String("AB"));
2162 QCOMPARE(a.leftJustified(1,' ',true), QLatin1String("A"));
2163 QCOMPARE(a.leftJustified(0,' ',true), QLatin1String(""));
2164}
2165
2166void tst_QString::rightJustified()
2167{
2168 QString a;
2169 a="ABC";
2170 QCOMPARE(a.rightJustified(5,'-'), QLatin1String("--ABC"));
2171 QCOMPARE(a.rightJustified(4,'-'), QLatin1String("-ABC"));
2172 QCOMPARE(a.rightJustified(4), QLatin1String(" ABC"));
2173 QCOMPARE(a.rightJustified(3), QLatin1String("ABC"));
2174 QCOMPARE(a.rightJustified(2), QLatin1String("ABC"));
2175 QCOMPARE(a.rightJustified(1), QLatin1String("ABC"));
2176 QCOMPARE(a.rightJustified(0), QLatin1String("ABC"));
2177
2178 QString n;
2179 QVERIFY(!n.rightJustified(3).isNull());
2180 QCOMPARE(a.rightJustified(4,'-',true), QLatin1String("-ABC"));
2181 QCOMPARE(a.rightJustified(4,' ',true), QLatin1String(" ABC"));
2182 QCOMPARE(a.rightJustified(3,' ',true), QLatin1String("ABC"));
2183 QCOMPARE(a.rightJustified(2,' ',true), QLatin1String("AB"));
2184 QCOMPARE(a.rightJustified(1,' ',true), QLatin1String("A"));
2185 QCOMPARE(a.rightJustified(0,' ',true), QLatin1String(""));
2186 QCOMPARE(a, QLatin1String("ABC"));
2187}
2188
2189void tst_QString::toUpper()
2190{
2191 QCOMPARE( QString().toUpper(), QString() );
2192 QCOMPARE( QString("").toUpper(), QString("") );
2193 QCOMPARE( QStringLiteral("text").toUpper(), QString("TEXT") );
2194 QCOMPARE( QString("text").toUpper(), QString("TEXT") );
2195 QCOMPARE( QString("Text").toUpper(), QString("TEXT") );
2196 QCOMPARE( QString("tExt").toUpper(), QString("TEXT") );
2197 QCOMPARE( QString("teXt").toUpper(), QString("TEXT") );
2198 QCOMPARE( QString("texT").toUpper(), QString("TEXT") );
2199 QCOMPARE( QString("TExt").toUpper(), QString("TEXT") );
2200 QCOMPARE( QString("teXT").toUpper(), QString("TEXT") );
2201 QCOMPARE( QString("tEXt").toUpper(), QString("TEXT") );
2202 QCOMPARE( QString("tExT").toUpper(), QString("TEXT") );
2203 QCOMPARE( QString("TEXT").toUpper(), QString("TEXT") );
2204 QCOMPARE( QString("@ABYZ[").toUpper(), QString("@ABYZ["));
2205 QCOMPARE( QString("@abyz[").toUpper(), QString("@ABYZ["));
2206 QCOMPARE( QString("`ABYZ{").toUpper(), QString("`ABYZ{"));
2207 QCOMPARE( QString("`abyz{").toUpper(), QString("`ABYZ{"));
2208
2209 QCOMPARE( QString(1, QChar(0xdf)).toUpper(), QString("SS"));
2210 {
2211 QString s = QString::fromUtf8(str: "Gro\xc3\x9fstra\xc3\x9f""e");
2212
2213 // call lvalue-ref version, mustn't change the original
2214 QCOMPARE(s.toUpper(), QString("GROSSSTRASSE"));
2215 QCOMPARE(s, QString::fromUtf8("Gro\xc3\x9fstra\xc3\x9f""e"));
2216
2217 // call rvalue-ref while shared (the original mustn't change)
2218 QString copy = s;
2219 QCOMPARE(std::move(copy).toUpper(), QString("GROSSSTRASSE"));
2220 QCOMPARE(s, QString::fromUtf8("Gro\xc3\x9fstra\xc3\x9f""e"));
2221
2222 // call rvalue-ref version on detached case
2223 copy.clear();
2224 QCOMPARE(std::move(s).toUpper(), QString("GROSSSTRASSE"));
2225 }
2226
2227 QString lower, upper;
2228 lower += QChar(QChar::highSurrogate(ucs4: 0x10428));
2229 lower += QChar(QChar::lowSurrogate(ucs4: 0x10428));
2230 upper += QChar(QChar::highSurrogate(ucs4: 0x10400));
2231 upper += QChar(QChar::lowSurrogate(ucs4: 0x10400));
2232 QCOMPARE( lower.toUpper(), upper);
2233 lower += lower;
2234 upper += upper;
2235 QCOMPARE( lower.toUpper(), upper);
2236
2237 // test for broken surrogate pair handling (low low hi low hi low)
2238 lower.prepend(c: QChar(QChar::lowSurrogate(ucs4: 0x10428)));
2239 lower.prepend(c: QChar(QChar::lowSurrogate(ucs4: 0x10428)));
2240 upper.prepend(c: QChar(QChar::lowSurrogate(ucs4: 0x10428)));
2241 upper.prepend(c: QChar(QChar::lowSurrogate(ucs4: 0x10428)));
2242 QCOMPARE(lower.toUpper(), upper);
2243 // test for broken surrogate pair handling (low low hi low hi low hi hi)
2244 lower += QChar(QChar::highSurrogate(ucs4: 0x10428));
2245 lower += QChar(QChar::highSurrogate(ucs4: 0x10428));
2246 upper += QChar(QChar::highSurrogate(ucs4: 0x10428));
2247 upper += QChar(QChar::highSurrogate(ucs4: 0x10428));
2248 QCOMPARE(lower.toUpper(), upper);
2249
2250#if QT_CONFIG(icu)
2251 // test doesn't work with ICU support, since QChar is unaware of any locale
2252 QEXPECT_FAIL("", "test doesn't work with ICU support, since QChar is unaware of any locale", Continue);
2253 QVERIFY(false);
2254#else
2255 for (int i = 0; i < 65536; ++i) {
2256 QString str(1, QChar(i));
2257 QString upper = str.toUpper();
2258 QVERIFY(upper.length() >= 1);
2259 if (upper.length() == 1)
2260 QVERIFY(upper == QString(1, QChar(i).toUpper()));
2261 }
2262#endif // icu
2263}
2264
2265void tst_QString::toLower()
2266{
2267 QCOMPARE( QString().toLower(), QString() );
2268 QCOMPARE( QString("").toLower(), QString("") );
2269 QCOMPARE( QString("text").toLower(), QString("text") );
2270 QCOMPARE( QStringLiteral("Text").toLower(), QString("text") );
2271 QCOMPARE( QString("Text").toLower(), QString("text") );
2272 QCOMPARE( QString("tExt").toLower(), QString("text") );
2273 QCOMPARE( QString("teXt").toLower(), QString("text") );
2274 QCOMPARE( QString("texT").toLower(), QString("text") );
2275 QCOMPARE( QString("TExt").toLower(), QString("text") );
2276 QCOMPARE( QString("teXT").toLower(), QString("text") );
2277 QCOMPARE( QString("tEXt").toLower(), QString("text") );
2278 QCOMPARE( QString("tExT").toLower(), QString("text") );
2279 QCOMPARE( QString("TEXT").toLower(), QString("text") );
2280 QCOMPARE( QString("@ABYZ[").toLower(), QString("@abyz["));
2281 QCOMPARE( QString("@abyz[").toLower(), QString("@abyz["));
2282 QCOMPARE( QString("`ABYZ{").toLower(), QString("`abyz{"));
2283 QCOMPARE( QString("`abyz{").toLower(), QString("`abyz{"));
2284
2285 QCOMPARE( QString(1, QChar(0x130)).toLower(), QString(QString(1, QChar(0x69)) + QChar(0x307)));
2286
2287 QString lower, upper;
2288 lower += QChar(QChar::highSurrogate(ucs4: 0x10428));
2289 lower += QChar(QChar::lowSurrogate(ucs4: 0x10428));
2290 upper += QChar(QChar::highSurrogate(ucs4: 0x10400));
2291 upper += QChar(QChar::lowSurrogate(ucs4: 0x10400));
2292 QCOMPARE( upper.toLower(), lower);
2293 lower += lower;
2294 upper += upper;
2295 QCOMPARE( upper.toLower(), lower);
2296
2297 // test for broken surrogate pair handling (low low hi low hi low)
2298 lower.prepend(c: QChar(QChar::lowSurrogate(ucs4: 0x10400)));
2299 lower.prepend(c: QChar(QChar::lowSurrogate(ucs4: 0x10400)));
2300 upper.prepend(c: QChar(QChar::lowSurrogate(ucs4: 0x10400)));
2301 upper.prepend(c: QChar(QChar::lowSurrogate(ucs4: 0x10400)));
2302 QCOMPARE( upper.toLower(), lower);
2303 // test for broken surrogate pair handling (low low hi low hi low hi hi)
2304 lower += QChar(QChar::highSurrogate(ucs4: 0x10400));
2305 lower += QChar(QChar::highSurrogate(ucs4: 0x10400));
2306 upper += QChar(QChar::highSurrogate(ucs4: 0x10400));
2307 upper += QChar(QChar::highSurrogate(ucs4: 0x10400));
2308 QCOMPARE( upper.toLower(), lower);
2309
2310#if QT_CONFIG(icu)
2311 // test doesn't work with ICU support, since QChar is unaware of any locale
2312 QEXPECT_FAIL("", "test doesn't work with ICU support, since QChar is unaware of any locale", Continue);
2313 QVERIFY(false);
2314#else
2315 for (int i = 0; i < 65536; ++i) {
2316 QString str(1, QChar(i));
2317 QString lower = str.toLower();
2318 QVERIFY(lower.length() >= 1);
2319 if (lower.length() == 1)
2320 QVERIFY(str.toLower() == QString(1, QChar(i).toLower()));
2321 }
2322#endif // icu
2323}
2324
2325void tst_QString::isLower_isUpper_data()
2326{
2327 QTest::addColumn<QString>(name: "string");
2328 QTest::addColumn<bool>(name: "isLower");
2329 QTest::addColumn<bool>(name: "isUpper");
2330
2331 int row = 0;
2332 QTest::addRow(format: "lower-and-upper-%02d", row++) << QString() << true << true;
2333 QTest::addRow(format: "lower-and-upper-%02d", row++) << QString("") << true << true;
2334 QTest::addRow(format: "lower-and-upper-%02d", row++) << QString(" ") << true << true;
2335 QTest::addRow(format: "lower-and-upper-%02d", row++) << QString("123") << true << true;
2336 QTest::addRow(format: "lower-and-upper-%02d", row++) << QString("@123$#") << true << true;
2337 QTest::addRow(format: "lower-and-upper-%02d", row++) << QString("π„žπ„΄π†β™«") << true << true; // Unicode Block 'Musical Symbols'
2338 // not foldable
2339 QTest::addRow(format: "lower-and-upper-%02d", row++) << QString("πšŠπš‹πšŒπšπšŽ") << true << true; // MATHEMATICAL MONOSPACE SMALL A, ... E
2340 QTest::addRow(format: "lower-and-upper-%02d", row++) << QString("𝙖,𝙗,π™˜,𝙙,π™š") << true << true; // MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL A, ... E
2341 QTest::addRow(format: "lower-and-upper-%02d", row++) << QString("π—”π—•π—–π——π—˜") << true << true; // MATHEMATICAL SANS-SERIF BOLD CAPITAL A, ... E
2342 QTest::addRow(format: "lower-and-upper-%02d", row++) << QString("𝐀,𝐁,𝐂,𝐃,𝐄") << true << true; // MATHEMATICAL BOLD CAPITAL A, ... E
2343
2344 row = 0;
2345 QTest::addRow(format: "only-lower-%02d", row++) << QString("text") << true << false;
2346 QTest::addRow(format: "only-lower-%02d", row++) << QString("Γ aa") << true << false;
2347 QTest::addRow(format: "only-lower-%02d", row++) << QString("øæß") << true << false;
2348 QTest::addRow(format: "only-lower-%02d", row++) << QString("text ") << true << false;
2349 QTest::addRow(format: "only-lower-%02d", row++) << QString(" text") << true << false;
2350 QTest::addRow(format: "only-lower-%02d", row++) << QString("hello, world!") << true << false;
2351 QTest::addRow(format: "only-lower-%02d", row++) << QString("123@abyz[") << true << false;
2352 QTest::addRow(format: "only-lower-%02d", row++) << QString("`abyz{") << true << false;
2353 QTest::addRow(format: "only-lower-%02d", row++) << QString("a𝙖a|b𝙗b|cπ™˜c|d𝙙d|eπ™še") << true << false; // MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL A, ... E
2354 QTest::addRow(format: "only-lower-%02d", row++) << QString("𐐨") << true << false; // DESERET SMALL LETTER LONG I
2355 // uppercase letters, not foldable
2356 QTest::addRow(format: "only-lower-%02d", row++) << QString("text𝗔text") << true << false; // MATHEMATICAL SANS-SERIF BOLD CAPITAL A
2357
2358 row = 0;
2359 QTest::addRow(format: "only-upper-%02d", row++) << QString("TEXT") << false << true;
2360 QTest::addRow(format: "only-upper-%02d", row++) << QString("Γ€AA") << false << true;
2361 QTest::addRow(format: "only-upper-%02d", row++) << QString("Γ˜Γ†αΊž") << false << true;
2362 QTest::addRow(format: "only-upper-%02d", row++) << QString("TEXT ") << false << true;
2363 QTest::addRow(format: "only-upper-%02d", row++) << QString(" TEXT") << false << true;
2364 QTest::addRow(format: "only-upper-%02d", row++) << QString("HELLO, WORLD!") << false << true;
2365 QTest::addRow(format: "only-upper-%02d", row++) << QString("123@ABYZ[") << false << true;
2366 QTest::addRow(format: "only-upper-%02d", row++) << QString("`ABYZ{") << false << true;
2367 QTest::addRow(format: "only-upper-%02d", row++) << QString("A𝐀A|B𝐁B|C𝐂C|D𝐃D|E𝐄E") << false << true; // MATHEMATICAL BOLD CAPITAL A, ... E
2368 QTest::addRow(format: "only-upper-%02d", row++) << QString("𐐀") << false << true; // DESERET CAPITAL LETTER LONG I
2369 // lowercase letters, not foldable
2370 QTest::addRow(format: "only-upper-%02d", row++) << QString("TEXT𝚊TEXT") << false << true; // MATHEMATICAL MONOSPACE SMALL A
2371
2372 row = 0;
2373 QTest::addRow(format: "not-lower-nor-upper-%02d", row++) << QString("Text") << false << false;
2374 QTest::addRow(format: "not-lower-nor-upper-%02d", row++) << QString("tExt") << false << false;
2375 QTest::addRow(format: "not-lower-nor-upper-%02d", row++) << QString("teXt") << false << false;
2376 QTest::addRow(format: "not-lower-nor-upper-%02d", row++) << QString("texT") << false << false;
2377 QTest::addRow(format: "not-lower-nor-upper-%02d", row++) << QString("TExt") << false << false;
2378 QTest::addRow(format: "not-lower-nor-upper-%02d", row++) << QString("teXT") << false << false;
2379 QTest::addRow(format: "not-lower-nor-upper-%02d", row++) << QString("tEXt") << false << false;
2380 QTest::addRow(format: "not-lower-nor-upper-%02d", row++) << QString("tExT") << false << false;
2381 // not foldable
2382 QTest::addRow(format: "not-lower-nor-upper-%02d", row++) << QString("TEXT𝚊text") << false << false; // MATHEMATICAL MONOSPACE SMALL A
2383 QTest::addRow(format: "not-lower-nor-upper-%02d", row++) << QString("text𝗔TEXT") << false << false; // MATHEMATICAL SANS-SERIF BOLD CAPITAL A
2384 // titlecase, foldable
2385 QTest::addRow(format: "not-lower-nor-upper-%02d", row++) << QString("abcLjdef") << false << false; // LATIN CAPITAL LETTER L WITH SMALL LETTER J
2386 QTest::addRow(format: "not-lower-nor-upper-%02d", row++) << QString("ABCLjDEF") << false << false; // LATIN CAPITAL LETTER L WITH SMALL LETTER J
2387}
2388
2389void tst_QString::isLower_isUpper()
2390{
2391 QFETCH(QString, string);
2392 QFETCH(bool, isLower);
2393 QFETCH(bool, isUpper);
2394
2395 QCOMPARE(string.isLower(), isLower);
2396 QCOMPARE(string.toLower() == string, isLower);
2397 QVERIFY(string.toLower().isLower());
2398
2399 QCOMPARE(string.isUpper(), isUpper);
2400 QCOMPARE(string.toUpper() == string, isUpper);
2401 QVERIFY(string.toUpper().isUpper());
2402}
2403
2404void tst_QString::toCaseFolded()
2405{
2406 QCOMPARE( QString().toCaseFolded(), QString() );
2407 QCOMPARE( QString("").toCaseFolded(), QString("") );
2408 QCOMPARE( QString("text").toCaseFolded(), QString("text") );
2409 QCOMPARE( QString("Text").toCaseFolded(), QString("text") );
2410 QCOMPARE( QString("tExt").toCaseFolded(), QString("text") );
2411 QCOMPARE( QString("teXt").toCaseFolded(), QString("text") );
2412 QCOMPARE( QString("texT").toCaseFolded(), QString("text") );
2413 QCOMPARE( QString("TExt").toCaseFolded(), QString("text") );
2414 QCOMPARE( QString("teXT").toCaseFolded(), QString("text") );
2415 QCOMPARE( QString("tEXt").toCaseFolded(), QString("text") );
2416 QCOMPARE( QString("tExT").toCaseFolded(), QString("text") );
2417 QCOMPARE( QString("TEXT").toCaseFolded(), QString("text") );
2418 QCOMPARE( QString("@ABYZ[").toCaseFolded(), QString("@abyz["));
2419 QCOMPARE( QString("@abyz[").toCaseFolded(), QString("@abyz["));
2420 QCOMPARE( QString("`ABYZ{").toCaseFolded(), QString("`abyz{"));
2421 QCOMPARE( QString("`abyz{").toCaseFolded(), QString("`abyz{"));
2422
2423 QCOMPARE( QString(1, QChar(0xa77d)).toCaseFolded(), QString(1, QChar(0x1d79)));
2424 QCOMPARE( QString(1, QChar(0xa78d)).toCaseFolded(), QString(1, QChar(0x0265)));
2425
2426 QString lower, upper;
2427 upper += QChar(QChar::highSurrogate(ucs4: 0x10400));
2428 upper += QChar(QChar::lowSurrogate(ucs4: 0x10400));
2429 lower += QChar(QChar::highSurrogate(ucs4: 0x10428));
2430 lower += QChar(QChar::lowSurrogate(ucs4: 0x10428));
2431 QCOMPARE( upper.toCaseFolded(), lower);
2432 lower += lower;
2433 upper += upper;
2434 QCOMPARE( upper.toCaseFolded(), lower);
2435
2436 // test for broken surrogate pair handling (low low hi low hi low)
2437 lower.prepend(c: QChar(QChar::lowSurrogate(ucs4: 0x10400)));
2438 lower.prepend(c: QChar(QChar::lowSurrogate(ucs4: 0x10400)));
2439 upper.prepend(c: QChar(QChar::lowSurrogate(ucs4: 0x10400)));
2440 upper.prepend(c: QChar(QChar::lowSurrogate(ucs4: 0x10400)));
2441 QCOMPARE(upper.toCaseFolded(), lower);
2442 // test for broken surrogate pair handling (low low hi low hi low hi hi)
2443 lower += QChar(QChar::highSurrogate(ucs4: 0x10400));
2444 lower += QChar(QChar::highSurrogate(ucs4: 0x10400));
2445 upper += QChar(QChar::highSurrogate(ucs4: 0x10400));
2446 upper += QChar(QChar::highSurrogate(ucs4: 0x10400));
2447 QCOMPARE(upper.toCaseFolded(), lower);
2448
2449 //### we currently don't support full case foldings
2450 for (int i = 0; i < 65536; ++i) {
2451 QString str(1, QChar(i));
2452 QString lower = str.toCaseFolded();
2453 QVERIFY(lower.length() >= 1);
2454 if (lower.length() == 1)
2455 QVERIFY(str.toCaseFolded() == QString(1, QChar(i).toCaseFolded()));
2456 }
2457}
2458
2459void tst_QString::trimmed()
2460{
2461 QString a;
2462 a="Text";
2463 QCOMPARE(a, QLatin1String("Text"));
2464 QCOMPARE(a.trimmed(), QLatin1String("Text"));
2465 QCOMPARE(a, QLatin1String("Text"));
2466 a=" ";
2467 QCOMPARE(a.trimmed(), QLatin1String(""));
2468 QCOMPARE(a, QLatin1String(" "));
2469 a=" a ";
2470 QCOMPARE(a.trimmed(), QLatin1String("a"));
2471
2472 a="Text";
2473 QCOMPARE(std::move(a).trimmed(), QLatin1String("Text"));
2474 a=" ";
2475 QCOMPARE(std::move(a).trimmed(), QLatin1String(""));
2476 a=" a ";
2477 QCOMPARE(std::move(a).trimmed(), QLatin1String("a"));
2478}
2479
2480void tst_QString::simplified_data()
2481{
2482 QTest::addColumn<QString>(name: "full" );
2483 QTest::addColumn<QString>(name: "simple" );
2484
2485 QTest::newRow(dataTag: "null") << QString() << QString();
2486 QTest::newRow(dataTag: "empty") << "" << "";
2487 QTest::newRow(dataTag: "one char") << "a" << "a";
2488 QTest::newRow(dataTag: "one word") << "foo" << "foo";
2489 QTest::newRow(dataTag: "chars trivial") << "a b" << "a b";
2490 QTest::newRow(dataTag: "words trivial") << "foo bar" << "foo bar";
2491 QTest::newRow(dataTag: "allspace") << " \t\v " << "";
2492 QTest::newRow(dataTag: "char trailing") << "a " << "a";
2493 QTest::newRow(dataTag: "char trailing tab") << "a\t" << "a";
2494 QTest::newRow(dataTag: "char multitrailing") << "a " << "a";
2495 QTest::newRow(dataTag: "char multitrailing tab") << "a \t" << "a";
2496 QTest::newRow(dataTag: "char leading") << " a" << "a";
2497 QTest::newRow(dataTag: "char leading tab") << "\ta" << "a";
2498 QTest::newRow(dataTag: "char multileading") << " a" << "a";
2499 QTest::newRow(dataTag: "char multileading tab") << "\t a" << "a";
2500 QTest::newRow(dataTag: "chars apart") << "a b" << "a b";
2501 QTest::newRow(dataTag: "words apart") << "foo bar" << "foo bar";
2502 QTest::newRow(dataTag: "enclosed word") << " foo \t " << "foo";
2503 QTest::newRow(dataTag: "enclosed chars apart") << " a b " << "a b";
2504 QTest::newRow(dataTag: "enclosed words apart") << " foo bar " << "foo bar";
2505 QTest::newRow(dataTag: "chars apart posttab") << "a \tb" << "a b";
2506 QTest::newRow(dataTag: "chars apart pretab") << "a\t b" << "a b";
2507 QTest::newRow(dataTag: "many words") << " just some random\ttext here" << "just some random text here";
2508 QTest::newRow(dataTag: "newlines") << "a\nb\nc" << "a b c";
2509 QTest::newRow(dataTag: "newlines-trailing") << "a\nb\nc\n" << "a b c";
2510}
2511
2512void tst_QString::simplified()
2513{
2514 QFETCH(QString, full);
2515 QFETCH(QString, simple);
2516
2517 QString orig_full = full;
2518 orig_full.data(); // forces a detach
2519
2520 QString result = full.simplified();
2521 if (simple.isNull()) {
2522 QVERIFY2(result.isNull(), qPrintable("'" + full + "' did not yield null: " + result));
2523 } else if (simple.isEmpty()) {
2524 QVERIFY2(result.isEmpty() && !result.isNull(), qPrintable("'" + full + "' did not yield empty: " + result));
2525 } else {
2526 QCOMPARE(result, simple);
2527 }
2528 QCOMPARE(full, orig_full);
2529
2530 // without detaching:
2531 QString copy1 = full;
2532 QCOMPARE(std::move(full).simplified(), simple);
2533 QCOMPARE(full, orig_full);
2534
2535 // force a detach
2536 if (!full.isEmpty())
2537 full[0] = full[0];
2538 QCOMPARE(std::move(full).simplified(), simple);
2539}
2540
2541void tst_QString::insert_data(bool emptyIsNoop)
2542{
2543 QTest::addColumn<QString>(name: "s");
2544 QTest::addColumn<CharStarContainer>(name: "arg");
2545 QTest::addColumn<int>(name: "a1");
2546 QTest::addColumn<QString>(name: "expected");
2547
2548 const CharStarContainer nullC;
2549 const CharStarContainer emptyC("");
2550 const CharStarContainer aC("a");
2551 const CharStarContainer bC("b");
2552 //const CharStarContainer abC("ab");
2553 const CharStarContainer baC("ba");
2554
2555 const QString null;
2556 const QString empty("");
2557 const QString a("a");
2558 const QString b("b");
2559 const QString ab("ab");
2560 const QString ba("ba");
2561
2562 QTest::newRow(dataTag: "null.insert(0, null)") << null << nullC << 0 << null;
2563 QTest::newRow(dataTag: "null.insert(0, empty)") << null << emptyC << 0 << (emptyIsNoop ? null : empty);
2564 QTest::newRow(dataTag: "null.insert(0, a)") << null << aC << 0 << a;
2565 QTest::newRow(dataTag: "empty.insert(0, null)") << empty << nullC << 0 << empty;
2566 QTest::newRow(dataTag: "empty.insert(0, empty)") << empty << emptyC << 0 << empty;
2567 QTest::newRow(dataTag: "empty.insert(0, a)") << empty << aC << 0 << a;
2568 QTest::newRow(dataTag: "a.insert(0, null)") << a << nullC << 0 << a;
2569 QTest::newRow(dataTag: "a.insert(0, empty)") << a << emptyC << 0 << a;
2570 QTest::newRow(dataTag: "a.insert(0, b)") << a << bC << 0 << ba;
2571 QTest::newRow(dataTag: "a.insert(0, ba)") << a << baC << 0 << (ba + a);
2572 QTest::newRow(dataTag: "a.insert(1, null)") << a << nullC << 1 << a;
2573 QTest::newRow(dataTag: "a.insert(1, empty)") << a << emptyC << 1 << a;
2574 QTest::newRow(dataTag: "a.insert(1, b)") << a << bC << 1 << ab;
2575 QTest::newRow(dataTag: "a.insert(1, ba)") << a << baC << 1 << (a + ba);
2576 QTest::newRow(dataTag: "ba.insert(1, a)") << ba << aC << 1 << (ba + a);
2577 QTest::newRow(dataTag: "ba.insert(2, b)") << ba << bC << 2 << (ba + b);
2578}
2579
2580void tst_QString::insert_special_cases()
2581{
2582 QString a;
2583
2584 a = "Ys";
2585 QCOMPARE(a.insert(1,'e'), QString("Yes"));
2586 QCOMPARE(a.insert(3,'!'), QString("Yes!"));
2587 QCOMPARE(a.insert(5,'?'), QString("Yes! ?"));
2588
2589 a = "ABC";
2590 QCOMPARE(a.insert(5,"DEF"), QString("ABC DEF"));
2591
2592 a = "ABC";
2593 QCOMPARE(a.insert(2, QString()), QString("ABC"));
2594 QCOMPARE(a.insert(0,"ABC"), QString("ABCABC"));
2595 QCOMPARE(a, QString("ABCABC"));
2596 QCOMPARE(a.insert(0,a), QString("ABCABCABCABC"));
2597
2598 QCOMPARE(a, QString("ABCABCABCABC"));
2599 QCOMPARE(a.insert(0,'<'), QString("<ABCABCABCABC"));
2600 QCOMPARE(a.insert(1,'>'), QString("<>ABCABCABCABC"));
2601
2602 a = "Meal";
2603 const QString montreal = QStringLiteral("Montreal");
2604 QCOMPARE(a.insert(1, QLatin1String("ontr")), montreal);
2605 QCOMPARE(a.insert(4, ""), montreal);
2606 QCOMPARE(a.insert(3, QLatin1String("")), montreal);
2607 QCOMPARE(a.insert(3, QLatin1String(0)), montreal);
2608 QCOMPARE(a.insert(3, static_cast<const char *>(0)), montreal);
2609 QCOMPARE(a.insert(0, QLatin1String("a")), QLatin1String("aMontreal"));
2610}
2611
2612void tst_QString::append_data(bool emptyIsNoop)
2613{
2614 QTest::addColumn<QString>(name: "s");
2615 QTest::addColumn<CharStarContainer>(name: "arg");
2616 QTest::addColumn<QString>(name: "expected");
2617
2618 const CharStarContainer nullC;
2619 const CharStarContainer emptyC("");
2620 const CharStarContainer aC("a");
2621 const CharStarContainer bC("b");
2622 //const CharStarContainer abC("ab");
2623
2624 const QString null;
2625 const QString empty("");
2626 const QString a("a");
2627 //const QString b("b");
2628 const QString ab("ab");
2629
2630 QTest::newRow(dataTag: "null + null") << null << nullC << null;
2631 QTest::newRow(dataTag: "null + empty") << null << emptyC << (emptyIsNoop ? null : empty);
2632 QTest::newRow(dataTag: "null + a") << null << aC << a;
2633 QTest::newRow(dataTag: "empty + null") << empty << nullC << empty;
2634 QTest::newRow(dataTag: "empty + empty") << empty << emptyC << empty;
2635 QTest::newRow(dataTag: "empty + a") << empty << aC << a;
2636 QTest::newRow(dataTag: "a + null") << a << nullC << a;
2637 QTest::newRow(dataTag: "a + empty") << a << emptyC << a;
2638 QTest::newRow(dataTag: "a + b") << a << bC << ab;
2639}
2640
2641void tst_QString::append_special_cases()
2642{
2643 {
2644 QString a;
2645 static const QChar unicode[] = { 'H', 'e', 'l', 'l', 'o', ',', ' ', 'W', 'o', 'r', 'l', 'd', '!' };
2646 a.append(uc: unicode, len: sizeof unicode / sizeof *unicode);
2647 QCOMPARE(a, QLatin1String("Hello, World!"));
2648 static const QChar nl('\n');
2649 a.append(uc: &nl, len: 1);
2650 QCOMPARE(a, QLatin1String("Hello, World!\n"));
2651 a.append(uc: unicode, len: sizeof unicode / sizeof *unicode);
2652 QCOMPARE(a, QLatin1String("Hello, World!\nHello, World!"));
2653 a.append(uc: unicode, len: 0); // no-op
2654 QCOMPARE(a, QLatin1String("Hello, World!\nHello, World!"));
2655 a.append(uc: unicode, len: -1); // no-op
2656 QCOMPARE(a, QLatin1String("Hello, World!\nHello, World!"));
2657 a.append(uc: 0, len: 1); // no-op
2658 QCOMPARE(a, QLatin1String("Hello, World!\nHello, World!"));
2659 }
2660}
2661
2662void tst_QString::append_bytearray_special_cases_data()
2663{
2664 QTest::addColumn<QString>(name: "str" );
2665 QTest::addColumn<QByteArray>(name: "ba" );
2666 QTest::addColumn<QString>(name: "res" );
2667
2668 QByteArray ba( 5, 0 );
2669 ba[0] = 'a';
2670 ba[1] = 'b';
2671 ba[2] = 'c';
2672 ba[3] = 'd';
2673
2674 // no 0 termination
2675 ba.resize( size: 4 );
2676 QTest::newRow( dataTag: "notTerminated_0" ) << QString() << ba << QString("abcd");
2677 QTest::newRow( dataTag: "notTerminated_1" ) << QString("") << ba << QString("abcd");
2678 QTest::newRow( dataTag: "notTerminated_2" ) << QString("foobar ") << ba << QString("foobar abcd");
2679
2680 // byte array with only a 0
2681 ba.resize( size: 1 );
2682 ba[0] = 0;
2683 QByteArray ba2("foobar ");
2684 ba2.append(c: '\0');
2685 QTest::newRow( dataTag: "emptyString" ) << QString("foobar ") << ba << QString(ba2);
2686
2687 // empty byte array
2688 ba.resize( size: 0 );
2689 QTest::newRow( dataTag: "emptyByteArray" ) << QString("foobar ") << ba << QString("foobar ");
2690
2691 // non-ascii byte array
2692 QTest::newRow( dataTag: "nonAsciiByteArray") << QString() << QByteArray("\xc3\xa9") << QString("\xc3\xa9");
2693 QTest::newRow( dataTag: "nonAsciiByteArray2") << QString() << QByteArray("\xc3\xa9") << QString::fromUtf8(str: "\xc3\xa9");
2694}
2695
2696void tst_QString::append_bytearray_special_cases()
2697{
2698 {
2699 QFETCH( QString, str );
2700 QFETCH( QByteArray, ba );
2701
2702 str.append( s: ba );
2703
2704 QTEST( str, "res" );
2705 }
2706 {
2707 QFETCH( QString, str );
2708 QFETCH( QByteArray, ba );
2709
2710 str.append( s: ba );
2711
2712 QTEST( str, "res" );
2713 }
2714
2715 QFETCH( QByteArray, ba );
2716 if (ba.constData()[ba.length()] == '\0') {
2717 QFETCH( QString, str );
2718
2719 str.append(s: ba.constData());
2720 QTEST( str, "res" );
2721 }
2722}
2723
2724void tst_QString::operator_pluseq_data(bool emptyIsNoop)
2725{
2726 append_data(emptyIsNoop);
2727}
2728
2729void tst_QString::operator_pluseq_bytearray_special_cases_data()
2730{
2731 append_bytearray_special_cases_data();
2732}
2733
2734void tst_QString::operator_pluseq_bytearray_special_cases()
2735{
2736 {
2737 QFETCH( QString, str );
2738 QFETCH( QByteArray, ba );
2739
2740 str += ba;
2741
2742 QTEST( str, "res" );
2743 }
2744 {
2745 QFETCH( QString, str );
2746 QFETCH( QByteArray, ba );
2747
2748 str += ba;
2749
2750 QTEST( str, "res" );
2751 }
2752
2753 QFETCH( QByteArray, ba );
2754 if (ba.constData()[ba.length()] == '\0') {
2755 QFETCH( QString, str );
2756
2757 str += ba.constData();
2758 QTEST( str, "res" );
2759 }
2760}
2761
2762void tst_QString::operator_eqeq_bytearray_data()
2763{
2764 constructorQByteArray_data();
2765}
2766
2767void tst_QString::operator_eqeq_bytearray()
2768{
2769 QFETCH(QByteArray, src);
2770 QFETCH(QString, expected);
2771
2772 QVERIFY(expected == src);
2773 QVERIFY(!(expected != src));
2774
2775 if (src.constData()[src.length()] == '\0') {
2776 QVERIFY(expected == src.constData());
2777 QVERIFY(!(expected != src.constData()));
2778 }
2779}
2780
2781void tst_QString::swap()
2782{
2783 QString s1, s2;
2784 s1 = "s1";
2785 s2 = "s2";
2786 s1.swap(other&: s2);
2787 QCOMPARE(s1,QLatin1String("s2"));
2788 QCOMPARE(s2,QLatin1String("s1"));
2789}
2790
2791void tst_QString::prepend_data(bool emptyIsNoop)
2792{
2793 QTest::addColumn<QString>(name: "s");
2794 QTest::addColumn<CharStarContainer>(name: "arg");
2795 QTest::addColumn<QString>(name: "expected");
2796
2797 const CharStarContainer nullC;
2798 const CharStarContainer emptyC("");
2799 const CharStarContainer aC("a");
2800 const CharStarContainer bC("b");
2801 const CharStarContainer baC("ba");
2802
2803 const QString null;
2804 const QString empty("");
2805 const QString a("a");
2806 //const QString b("b");
2807 const QString ba("ba");
2808
2809 QTest::newRow(dataTag: "null.prepend(null)") << null << nullC << null;
2810 QTest::newRow(dataTag: "null.prepend(empty)") << null << emptyC << (emptyIsNoop ? null : empty);
2811 QTest::newRow(dataTag: "null.prepend(a)") << null << aC << a;
2812 QTest::newRow(dataTag: "empty.prepend(null)") << empty << nullC << empty;
2813 QTest::newRow(dataTag: "empty.prepend(empty)") << empty << emptyC << empty;
2814 QTest::newRow(dataTag: "empty.prepend(a)") << empty << aC << a;
2815 QTest::newRow(dataTag: "a.prepend(null)") << a << nullC << a;
2816 QTest::newRow(dataTag: "a.prepend(empty)") << a << emptyC << a;
2817 QTest::newRow(dataTag: "a.prepend(b)") << a << bC << ba;
2818 QTest::newRow(dataTag: "a.prepend(ba)") << a << baC << (ba + a);
2819}
2820
2821void tst_QString::prepend_bytearray_special_cases_data()
2822{
2823 QTest::addColumn<QString>(name: "str" );
2824 QTest::addColumn<QByteArray>(name: "ba" );
2825 QTest::addColumn<QString>(name: "res" );
2826
2827 QByteArray ba( 5, 0 );
2828 ba[0] = 'a';
2829 ba[1] = 'b';
2830 ba[2] = 'c';
2831 ba[3] = 'd';
2832
2833 // byte array with only a 0
2834 ba.resize( size: 1 );
2835 ba[0] = 0;
2836 QTest::newRow( dataTag: "emptyString" ) << QString("foobar ") << ba << QString("foobar ");
2837
2838 // empty byte array
2839 ba.resize( size: 0 );
2840 QTest::newRow( dataTag: "emptyByteArray" ) << QString(" foobar") << ba << QString(" foobar");
2841
2842 // non-ascii byte array
2843 QTest::newRow( dataTag: "nonAsciiByteArray") << QString() << QByteArray("\xc3\xa9") << QString("\xc3\xa9");
2844 QTest::newRow( dataTag: "nonAsciiByteArray2") << QString() << QByteArray("\xc3\xa9") << QString::fromUtf8(str: "\xc3\xa9");
2845}
2846
2847void tst_QString::prepend_bytearray_special_cases()
2848{
2849 {
2850 QFETCH( QString, str );
2851 QFETCH( QByteArray, ba );
2852
2853 str.prepend( s: ba );
2854
2855 QFETCH( QString, res );
2856 QCOMPARE( str, res );
2857 }
2858 {
2859 QFETCH( QString, str );
2860 QFETCH( QByteArray, ba );
2861
2862 str.prepend( s: ba );
2863
2864 QTEST( str, "res" );
2865 }
2866
2867 QFETCH( QByteArray, ba );
2868 if (ba.constData()[ba.length()] == '\0') {
2869 QFETCH( QString, str );
2870
2871 str.prepend(s: ba.constData());
2872 QTEST( str, "res" );
2873 }
2874}
2875
2876void tst_QString::replace_uint_uint()
2877{
2878 QFETCH( QString, string );
2879 QFETCH( int, index );
2880 QFETCH( int, len );
2881 QFETCH( QString, after );
2882
2883 QString s1 = string;
2884 s1.replace( i: (uint) index, len: (int) len, after );
2885 QTEST( s1, "result" );
2886
2887 QString s2 = string;
2888 s2.replace( i: (uint) index, len: (uint) len, s: after.unicode(), slen: after.length() );
2889 QTEST( s2, "result" );
2890
2891 if ( after.length() == 1 ) {
2892 QString s3 = string;
2893 s3.replace( i: (uint) index, len: (uint) len, after: QChar(after[0]) );
2894 QTEST( s3, "result" );
2895
2896 QString s4 = string;
2897 s4.replace( i: (uint) index, len: (uint) len, after: QChar(after[0]).toLatin1() );
2898 QTEST( s4, "result" );
2899 }
2900}
2901
2902void tst_QString::replace_extra()
2903{
2904 /*
2905 This test is designed to be extremely slow if QString::replace() doesn't optimize the case
2906 len == after.size().
2907 */
2908 QString str("dsfkljfdsjklsdjsfjklfsdjkldfjslkjsdfkllkjdsfjklsfdkjsdflkjlsdfjklsdfkjldsflkjsddlkj");
2909 for (int j = 1; j < 12; ++j)
2910 str += str;
2911
2912 QString str2("aaaaaaaaaaaaaaaaaaaa");
2913 for (int i = 0; i < 2000000; ++i) {
2914 str.replace(i: 10, len: 20, after: str2);
2915 }
2916
2917 /*
2918 Make sure that replacing with itself works.
2919 */
2920 QString copy(str);
2921 copy.detach();
2922 str.replace(i: 0, len: str.length(), after: str);
2923 QVERIFY(copy == str);
2924
2925 /*
2926 Make sure that replacing a part of oneself with itself works.
2927 */
2928 QString str3("abcdefghij");
2929 str3.replace(i: 0, len: 1, after: str3);
2930 QCOMPARE(str3, QString("abcdefghijbcdefghij"));
2931
2932 QString str4("abcdefghij");
2933 str4.replace(i: 1, len: 3, after: str4);
2934 QCOMPARE(str4, QString("aabcdefghijefghij"));
2935
2936 QString str5("abcdefghij");
2937 str5.replace(i: 8, len: 10, after: str5);
2938 QCOMPARE(str5, QString("abcdefghabcdefghij"));
2939
2940 // Replacements using only part of the string modified:
2941 QString str6("abcdefghij");
2942 str6.replace(i: 1, len: 8, s: str6.constData() + 3, slen: 3);
2943 QCOMPARE(str6, QString("adefj"));
2944
2945 QString str7("abcdefghibcdefghij");
2946 str7.replace(before: str7.constData() + 1, blen: 6, after: str7.constData() + 2, alen: 3);
2947 QCOMPARE(str7, QString("acdehicdehij"));
2948
2949 const int many = 1024;
2950 /*
2951 QS::replace(const QChar *, int, const QChar *, int, Qt::CaseSensitivity)
2952 does its replacements in batches of many (please keep in sync with any
2953 changes to batch size), which lead to misbehaviour if ether QChar * array
2954 was part of the data being modified.
2955 */
2956 QString str8("abcdefg"), ans8("acdeg");
2957 {
2958 // Make str8 and ans8 repeat themselves many + 1 times:
2959 int i = many;
2960 QString big(str8), small(ans8);
2961 while (i && !(i & 1)) { // Exploit many being a power of 2:
2962 big += big;
2963 small += small;
2964 i >>= 1;
2965 }
2966 while (i-- > 0) {
2967 str8 += big;
2968 ans8 += small;
2969 }
2970 }
2971 str8.replace(before: str8.constData() + 1, blen: 5, after: str8.constData() + 2, alen: 3);
2972 // Pre-test the bit where the diff happens, so it gets displayed:
2973 QCOMPARE(str8.mid((many - 3) * 5), ans8.mid((many - 3) * 5));
2974 // Also check the full values match, of course:
2975 QCOMPARE(str8.size(), ans8.size());
2976 QCOMPARE(str8, ans8);
2977
2978 {
2979 QString s(QLatin1String("BBB"));
2980 QString expected(QLatin1String("BBB"));
2981 for (int i = 0; i < 1028; ++i) {
2982 s.append(s: "X");
2983 expected.append(s: "GXU");
2984 }
2985 s.replace(c: QChar('X'), after: "GXU");
2986 QCOMPARE(s, expected);
2987 }
2988}
2989
2990void tst_QString::replace_string()
2991{
2992 QFETCH( QString, string );
2993 QFETCH( QString, before );
2994 QFETCH( QString, after );
2995 QFETCH( bool, bcs );
2996
2997 Qt::CaseSensitivity cs = bcs ? Qt::CaseSensitive : Qt::CaseInsensitive;
2998
2999 if ( before.length() == 1 ) {
3000 QChar ch = before.at( i: 0 );
3001
3002 QString s1 = string;
3003 s1.replace( c: ch, after, cs );
3004 QTEST( s1, "result" );
3005
3006 if ( QChar(ch.toLatin1()) == ch ) {
3007 QString s2 = string;
3008 s2.replace( c: ch.toLatin1(), after, cs );
3009 QTEST( s2, "result" );
3010 }
3011 }
3012
3013 QString s3 = string;
3014 s3.replace( before, after, cs );
3015 QTEST( s3, "result" );
3016
3017 QString s4 = string;
3018 s4.replace( rx: QRegExp(QRegExp::escape(str: before), cs), after );
3019 QTEST( s4, "result" );
3020
3021 QString s5 = string;
3022 s5.replace(rx: QRegExp(before, cs, QRegExp::FixedString), after);
3023 QTEST( s5, "result" );
3024}
3025
3026void tst_QString::replace_regexp()
3027{
3028 QFETCH( QString, string );
3029 QFETCH( QString, regexp );
3030 QFETCH( QString, after );
3031
3032 QString s2 = string;
3033 s2.replace( rx: QRegExp(regexp), after );
3034 QTEST( s2, "result" );
3035 s2 = string;
3036 QRegularExpression regularExpression(regexp);
3037 if (!regularExpression.isValid())
3038 QTest::ignoreMessage(type: QtWarningMsg, message: "QString::replace: invalid QRegularExpression object");
3039 s2.replace( re: regularExpression, after );
3040 QTEST( s2, "result" );
3041}
3042
3043void tst_QString::remove_uint_uint()
3044{
3045 QFETCH( QString, string );
3046 QFETCH( int, index );
3047 QFETCH( int, len );
3048 QFETCH( QString, after );
3049
3050 if ( after.length() == 0 ) {
3051 QString s1 = string;
3052 s1.remove( i: (uint) index, len: (uint) len );
3053 QTEST( s1, "result" );
3054 } else
3055 QCOMPARE( 0, 0 ); // shut Qt Test
3056}
3057
3058void tst_QString::remove_string()
3059{
3060 QFETCH( QString, string );
3061 QFETCH( QString, before );
3062 QFETCH( QString, after );
3063 QFETCH( bool, bcs );
3064
3065 Qt::CaseSensitivity cs = bcs ? Qt::CaseSensitive : Qt::CaseInsensitive;
3066
3067 if ( after.length() == 0 ) {
3068 if ( before.length() == 1 && cs ) {
3069 QChar ch = before.at( i: 0 );
3070
3071 QString s1 = string;
3072 s1.remove( c: ch );
3073 QTEST( s1, "result" );
3074
3075 if ( QChar(ch.toLatin1()) == ch ) {
3076 QString s2 = string;
3077 s2.remove( c: ch );
3078 QTEST( s2, "result" );
3079 }
3080 }
3081
3082 QString s3 = string;
3083 s3.remove( s: before, cs );
3084 QTEST( s3, "result" );
3085
3086 QString s4 = string;
3087 s4.replace( rx: QRegExp(QRegExp::escape(str: before), cs), after );
3088 QTEST( s4, "result" );
3089
3090 QString s5 = string;
3091 s5.replace( rx: QRegExp(before, cs, QRegExp::FixedString), after );
3092 QTEST( s5, "result" );
3093
3094 if (QtPrivate::isLatin1(s: before)) {
3095 QString s6 = string;
3096 s6.remove( s: QLatin1String(before.toLatin1()), cs );
3097 QTEST( s6, "result" );
3098 }
3099 } else {
3100 QCOMPARE( 0, 0 ); // shut Qt Test
3101 }
3102}
3103
3104void tst_QString::remove_regexp()
3105{
3106 QFETCH( QString, string );
3107 QFETCH( QString, regexp );
3108 QFETCH( QString, after );
3109
3110 if ( after.length() == 0 ) {
3111 QString s2 = string;
3112 s2.remove( rx: QRegExp(regexp) );
3113 QTEST( s2, "result" );
3114
3115 s2 = string;
3116 s2.remove( re: QRegularExpression(regexp) );
3117 QTEST( s2, "result" );
3118 } else {
3119 QCOMPARE( 0, 0 ); // shut Qt Test
3120 }
3121}
3122
3123void tst_QString::remove_extra()
3124{
3125 {
3126 QString s = "The quick brown fox jumps over the lazy dog. "
3127 "The lazy dog jumps over the quick brown fox.";
3128 s.remove(s);
3129 }
3130}
3131
3132void tst_QString::toNum()
3133{
3134#if defined (Q_OS_WIN) && defined (Q_CC_MSVC)
3135#define TEST_TO_INT(num, func) \
3136 a = #num; \
3137 QVERIFY2(a.func(&ok) == num ## i64 && ok, "Failed: num=" #num ", func=" #func);
3138#else
3139#define TEST_TO_INT(num, func) \
3140 a = #num; \
3141 QVERIFY2(a.func(&ok) == num ## LL && ok, "Failed: num=" #num ", func=" #func);
3142#endif
3143
3144 QString a;
3145 bool ok = false;
3146
3147 TEST_TO_INT(0, toInt)
3148 TEST_TO_INT(-1, toInt)
3149 TEST_TO_INT(1, toInt)
3150 TEST_TO_INT(2147483647, toInt)
3151 TEST_TO_INT(-2147483648, toInt)
3152
3153 TEST_TO_INT(0, toShort)
3154 TEST_TO_INT(-1, toShort)
3155 TEST_TO_INT(1, toShort)
3156 TEST_TO_INT(32767, toShort)
3157 TEST_TO_INT(-32768, toShort)
3158
3159 TEST_TO_INT(0, toLong)
3160 TEST_TO_INT(-1, toLong)
3161 TEST_TO_INT(1, toLong)
3162 TEST_TO_INT(2147483647, toLong)
3163 TEST_TO_INT(-2147483648, toLong)
3164 TEST_TO_INT(0, toLongLong)
3165 TEST_TO_INT(-1, toLongLong)
3166 TEST_TO_INT(1, toLongLong)
3167 TEST_TO_INT(9223372036854775807, toLongLong)
3168 TEST_TO_INT(-9223372036854775807, toLongLong)
3169
3170#undef TEST_TO_INT
3171
3172#if defined (Q_OS_WIN) && defined (Q_CC_MSVC)
3173#define TEST_TO_UINT(num, func) \
3174 a = #num; \
3175 QVERIFY2(a.func(&ok) == num ## i64 && ok, "Failed: num=" #num ", func=" #func);
3176#else
3177#define TEST_TO_UINT(num, func) \
3178 a = #num; \
3179 QVERIFY2(a.func(&ok) == num ## ULL && ok, "Failed: num=" #num ", func=" #func);
3180#endif
3181
3182 TEST_TO_UINT(0, toUInt)
3183 TEST_TO_UINT(1, toUInt)
3184 TEST_TO_UINT(4294967295, toUInt)
3185
3186 TEST_TO_UINT(0, toUShort)
3187 TEST_TO_UINT(1, toUShort)
3188 TEST_TO_UINT(65535, toUShort)
3189
3190 TEST_TO_UINT(0, toULong)
3191 TEST_TO_UINT(1, toULong)
3192 TEST_TO_UINT(4294967295, toULong)
3193
3194 TEST_TO_UINT(0, toULongLong)
3195 TEST_TO_UINT(1, toULongLong)
3196 TEST_TO_UINT(18446744073709551615, toULongLong)
3197#undef TEST_TO_UINT
3198
3199
3200#define TEST_BASE(str, base, num) \
3201 a = str; \
3202 QVERIFY2(a.toInt(&ok, base) == num && ok, "Failed: str=" #str " base= "#base " num=" #num ", func=toInt"); \
3203 QVERIFY2(a.toUInt(&ok, base) == num && ok, "Failed: str=" #str " base= "#base " num=" #num ", func=toUInt"); \
3204 QVERIFY2(a.toShort(&ok, base) == num && ok, "Failed: str=" #str " base= "#base " num=" #num ", func=toShort"); \
3205 QVERIFY2(a.toUShort(&ok, base) == num && ok, "Failed: str=" #str " base= "#base " num=" #num ", func=toUShort"); \
3206 QVERIFY2(a.toLong(&ok, base) == num && ok, "Failed: str=" #str " base= "#base " num=" #num ", func=toLong"); \
3207 QVERIFY2(a.toULong(&ok, base) == num && ok, "Failed: str=" #str " base= "#base " num=" #num ", func=toULong"); \
3208 QVERIFY2(a.toLongLong(&ok, base) == num && ok, "Failed: str=" #str " base= "#base " num=" #num ", func=toLongLong"); \
3209 QVERIFY2(a.toULongLong(&ok, base) == num && ok, "Failed: str=" #str " base= "#base " num=" #num ", func=toULongLong");
3210
3211 TEST_BASE("FF", 16, 255)
3212 TEST_BASE("0xFF", 16, 255)
3213 TEST_BASE("77", 8, 63)
3214 TEST_BASE("077", 8, 63)
3215
3216 TEST_BASE("0xFF", 0, 255)
3217 TEST_BASE("077", 0, 63)
3218 TEST_BASE("255", 0, 255)
3219
3220 TEST_BASE(" FF", 16, 255)
3221 TEST_BASE(" 0xFF", 16, 255)
3222 TEST_BASE(" 77", 8, 63)
3223 TEST_BASE(" 077", 8, 63)
3224
3225 TEST_BASE(" 0xFF", 0, 255)
3226 TEST_BASE(" 077", 0, 63)
3227 TEST_BASE(" 255", 0, 255)
3228
3229 TEST_BASE("\tFF\t", 16, 255)
3230 TEST_BASE("\t0xFF ", 16, 255)
3231 TEST_BASE(" 77 ", 8, 63)
3232 TEST_BASE("77 ", 8, 63)
3233
3234#undef TEST_BASE
3235
3236#define TEST_NEG_BASE(str, base, num) \
3237 a = str; \
3238 QVERIFY2(a.toInt(&ok, base) == num && ok, "Failed: str=" #str " base= "#base " num=" #num ", func=toInt"); \
3239 QVERIFY2(a.toShort(&ok, base) == num && ok, "Failed: str=" #str " base= "#base " num=" #num ", func=toShort"); \
3240 QVERIFY2(a.toLong(&ok, base) == num && ok, "Failed: str=" #str " base= "#base " num=" #num ", func=toLong"); \
3241 QVERIFY2(a.toLongLong(&ok, base) == num && ok, "Failed: str=" #str " base= "#base " num=" #num ", func=toLongLong");
3242
3243 TEST_NEG_BASE("-FE", 16, -254)
3244 TEST_NEG_BASE("-0xFE", 16, -254)
3245 TEST_NEG_BASE("-77", 8, -63)
3246 TEST_NEG_BASE("-077", 8, -63)
3247
3248 TEST_NEG_BASE("-0xFE", 0, -254)
3249 TEST_NEG_BASE("-077", 0, -63)
3250 TEST_NEG_BASE("-254", 0, -254)
3251
3252#undef TEST_NEG_BASE
3253
3254#define TEST_DOUBLE(num, str) \
3255 a = str; \
3256 QCOMPARE(a.toDouble(&ok), num); \
3257 QVERIFY(ok);
3258
3259 TEST_DOUBLE(1.2345, "1.2345")
3260 TEST_DOUBLE(12.345, "1.2345e+01")
3261 TEST_DOUBLE(12.345, "1.2345E+01")
3262 TEST_DOUBLE(12345.6, "12345.6")
3263
3264#undef TEST_DOUBLE
3265
3266
3267#define TEST_BAD(str, func) \
3268 a = str; \
3269 a.func(&ok); \
3270 QVERIFY2(!ok, "Failed: str=" #str " func=" #func);
3271
3272 TEST_BAD("32768", toShort)
3273 TEST_BAD("-32769", toShort)
3274 TEST_BAD("65536", toUShort)
3275 TEST_BAD("2147483648", toInt)
3276 TEST_BAD("-2147483649", toInt)
3277 TEST_BAD("4294967296", toUInt)
3278 if (sizeof(long) == 4) {
3279 TEST_BAD("2147483648", toLong)
3280 TEST_BAD("-2147483649", toLong)
3281 TEST_BAD("4294967296", toULong)
3282 }
3283 TEST_BAD("9223372036854775808", toLongLong)
3284 TEST_BAD("-9223372036854775809", toLongLong)
3285 TEST_BAD("18446744073709551616", toULongLong)
3286 TEST_BAD("-1", toUShort)
3287 TEST_BAD("-1", toUInt)
3288 TEST_BAD("-1", toULong)
3289 TEST_BAD("-1", toULongLong)
3290#undef TEST_BAD
3291
3292#define TEST_BAD_ALL(str) \
3293 a = str; \
3294 a.toShort(&ok); \
3295 QVERIFY2(!ok, "Failed: str=" #str); \
3296 a.toUShort(&ok); \
3297 QVERIFY2(!ok, "Failed: str=" #str); \
3298 a.toInt(&ok); \
3299 QVERIFY2(!ok, "Failed: str=" #str); \
3300 a.toUInt(&ok); \
3301 QVERIFY2(!ok, "Failed: str=" #str); \
3302 a.toLong(&ok); \
3303 QVERIFY2(!ok, "Failed: str=" #str); \
3304 a.toULong(&ok); \
3305 QVERIFY2(!ok, "Failed: str=" #str); \
3306 a.toLongLong(&ok); \
3307 QVERIFY2(!ok, "Failed: str=" #str); \
3308 a.toULongLong(&ok); \
3309 QVERIFY2(!ok, "Failed: str=" #str); \
3310 a.toFloat(&ok); \
3311 QVERIFY2(!ok, "Failed: str=" #str); \
3312 a.toDouble(&ok); \
3313 QVERIFY2(!ok, "Failed: str=" #str);
3314
3315 TEST_BAD_ALL((const char*)0);
3316 TEST_BAD_ALL("");
3317 TEST_BAD_ALL(" ");
3318 TEST_BAD_ALL(".");
3319 TEST_BAD_ALL("-");
3320 TEST_BAD_ALL("hello");
3321 TEST_BAD_ALL("1.2.3");
3322 TEST_BAD_ALL("0x0x0x");
3323 TEST_BAD_ALL("123-^~<");
3324 TEST_BAD_ALL("123ThisIsNotANumber");
3325
3326#undef TEST_BAD_ALL
3327
3328 a = "FF";
3329 a.toULongLong(ok: &ok, base: 10);
3330 QVERIFY(!ok);
3331
3332 a = "FF";
3333 a.toULongLong(ok: &ok, base: 0);
3334 QVERIFY(!ok);
3335
3336#ifdef QT_NO_FPU
3337 double d = 3.40282346638528e+38; // slightly off FLT_MAX when using hardfloats
3338#else
3339 double d = 3.4028234663852886e+38; // FLT_MAX
3340#endif
3341 QString::number(d, f: 'e', prec: 17).toFloat(ok: &ok);
3342 QVERIFY(ok);
3343 QString::number(d + 1e32, f: 'e', prec: 17).toFloat(ok: &ok);
3344 QVERIFY(!ok);
3345 QString::number(-d, f: 'e', prec: 17).toFloat(ok: &ok);
3346 QVERIFY(ok);
3347 QString::number(-d - 1e32, f: 'e', prec: 17).toFloat(ok: &ok);
3348 QVERIFY(!ok);
3349 QString::number(d + 1e32, f: 'e', prec: 17).toDouble(ok: &ok);
3350 QVERIFY(ok);
3351 QString::number(-d - 1e32, f: 'e', prec: 17).toDouble(ok: &ok);
3352 QVERIFY(ok);
3353}
3354
3355void tst_QString::toUShort()
3356{
3357 QString a;
3358 bool ok;
3359 QCOMPARE(a.toUShort(),(ushort)0);
3360 QCOMPARE(a.toUShort(&ok),(ushort)0);
3361 QVERIFY(!ok);
3362
3363 a="";
3364 QCOMPARE(a.toUShort(),(ushort)0);
3365 QCOMPARE(a.toUShort(&ok),(ushort)0);
3366 QVERIFY(!ok);
3367
3368 a="COMPARE";
3369 QCOMPARE(a.toUShort(),(ushort)0);
3370 QCOMPARE(a.toUShort(&ok),(ushort)0);
3371 QVERIFY(!ok);
3372
3373 a="123";
3374 QCOMPARE(a.toUShort(),(ushort)123);
3375 QCOMPARE(a.toUShort(&ok),(ushort)123);
3376 QVERIFY(ok);
3377
3378 a="123A";
3379 QCOMPARE(a.toUShort(),(ushort)0);
3380 QCOMPARE(a.toUShort(&ok),(ushort)0);
3381 QVERIFY(!ok);
3382
3383 a="1234567";
3384 QCOMPARE(a.toUShort(),(ushort)0);
3385 QCOMPARE(a.toUShort(&ok),(ushort)0);
3386 QVERIFY(!ok);
3387
3388 a = "aaa123aaa";
3389 QCOMPARE(a.toUShort(),(ushort)0);
3390 QCOMPARE(a.toUShort(&ok),(ushort)0);
3391 QVERIFY(!ok);
3392
3393 a = "aaa123";
3394 QCOMPARE(a.toUShort(),(ushort)0);
3395 QCOMPARE(a.toUShort(&ok),(ushort)0);
3396 QVERIFY(!ok);
3397
3398 a = "123aaa";
3399 QCOMPARE(a.toUShort(),(ushort)0);
3400 QCOMPARE(a.toUShort(&ok),(ushort)0);
3401 QVERIFY(!ok);
3402
3403 a = "32767";
3404 QCOMPARE(a.toUShort(),(ushort)32767);
3405 QCOMPARE(a.toUShort(&ok),(ushort)32767);
3406 QVERIFY(ok);
3407
3408 a = "-32767";
3409 QCOMPARE(a.toUShort(),(ushort)0);
3410 QCOMPARE(a.toUShort(&ok),(ushort)0);
3411 QVERIFY(!ok);
3412
3413 a = "65535";
3414 QCOMPARE(a.toUShort(),(ushort)65535);
3415 QCOMPARE(a.toUShort(&ok),(ushort)65535);
3416 QVERIFY(ok);
3417
3418 if (sizeof(short) == 2) {
3419 a = "65536";
3420 QCOMPARE(a.toUShort(),(ushort)0);
3421 QCOMPARE(a.toUShort(&ok),(ushort)0);
3422 QVERIFY(!ok);
3423
3424 a = "123456";
3425 QCOMPARE(a.toUShort(),(ushort)0);
3426 QCOMPARE(a.toUShort(&ok),(ushort)0);
3427 QVERIFY(!ok);
3428 }
3429}
3430
3431void tst_QString::toShort()
3432{
3433 QString a;
3434 bool ok;
3435 QCOMPARE(a.toShort(),(short)0);
3436 QCOMPARE(a.toShort(&ok),(short)0);
3437 QVERIFY(!ok);
3438
3439 a="";
3440 QCOMPARE(a.toShort(),(short)0);
3441 QCOMPARE(a.toShort(&ok),(short)0);
3442 QVERIFY(!ok);
3443
3444 a="COMPARE";
3445 QCOMPARE(a.toShort(),(short)0);
3446 QCOMPARE(a.toShort(&ok),(short)0);
3447 QVERIFY(!ok);
3448
3449 a="123";
3450 QCOMPARE(a.toShort(),(short)123);
3451 QCOMPARE(a.toShort(&ok),(short)123);
3452 QVERIFY(ok);
3453
3454 a="123A";
3455 QCOMPARE(a.toShort(),(short)0);
3456 QCOMPARE(a.toShort(&ok),(short)0);
3457 QVERIFY(!ok);
3458
3459 a="1234567";
3460 QCOMPARE(a.toShort(),(short)0);
3461 QCOMPARE(a.toShort(&ok),(short)0);
3462 QVERIFY(!ok);
3463
3464 a = "aaa123aaa";
3465 QCOMPARE(a.toShort(),(short)0);
3466 QCOMPARE(a.toShort(&ok),(short)0);
3467 QVERIFY(!ok);
3468
3469 a = "aaa123";
3470 QCOMPARE(a.toShort(),(short)0);
3471 QCOMPARE(a.toShort(&ok),(short)0);
3472 QVERIFY(!ok);
3473
3474 a = "123aaa";
3475 QCOMPARE(a.toShort(),(short)0);
3476 QCOMPARE(a.toShort(&ok),(short)0);
3477 QVERIFY(!ok);
3478
3479 a = "32767";
3480 QCOMPARE(a.toShort(),(short)32767);
3481 QCOMPARE(a.toShort(&ok),(short)32767);
3482 QVERIFY(ok);
3483
3484 a = "-32767";
3485 QCOMPARE(a.toShort(),(short)-32767);
3486 QCOMPARE(a.toShort(&ok),(short)-32767);
3487 QVERIFY(ok);
3488
3489 a = "-32768";
3490 QCOMPARE(a.toShort(),(short)-32768);
3491 QCOMPARE(a.toShort(&ok),(short)-32768);
3492 QVERIFY(ok);
3493
3494 if (sizeof(short) == 2) {
3495 a = "32768";
3496 QCOMPARE(a.toShort(),(short)0);
3497 QCOMPARE(a.toShort(&ok),(short)0);
3498 QVERIFY(!ok);
3499
3500 a = "-32769";
3501 QCOMPARE(a.toShort(),(short)0);
3502 QCOMPARE(a.toShort(&ok),(short)0);
3503 QVERIFY(!ok);
3504 }
3505}
3506
3507void tst_QString::toInt()
3508{
3509 QString a;
3510 bool ok;
3511 QCOMPARE(a.toInt(),0);
3512 QCOMPARE(a.toInt(&ok),0);
3513 QVERIFY(!ok);
3514
3515 a = "";
3516 QCOMPARE(a.toInt(),0);
3517 QCOMPARE(a.toInt(&ok),0);
3518 QVERIFY(!ok);
3519
3520 a="COMPARE";
3521 QCOMPARE(a.toInt(),0);
3522 QCOMPARE(a.toInt(&ok),0);
3523 QVERIFY(!ok);
3524
3525 a="123";
3526 QCOMPARE(a.toInt(),123);
3527 QCOMPARE(a.toInt(&ok),123);
3528 QVERIFY(ok);
3529
3530 a="123A";
3531 QCOMPARE(a.toInt(),0);
3532 QCOMPARE(a.toInt(&ok),0);
3533 QVERIFY(!ok);
3534
3535 a="1234567";
3536 QCOMPARE(a.toInt(),1234567);
3537 QCOMPARE(a.toInt(&ok),1234567);
3538 QVERIFY(ok);
3539
3540 a="12345678901234";
3541 QCOMPARE(a.toInt(),0);
3542 QCOMPARE(a.toInt(&ok),0);
3543 QVERIFY(!ok);
3544
3545 a="3234567890";
3546 QCOMPARE(a.toInt(),0);
3547 QCOMPARE(a.toInt(&ok),0);
3548 QVERIFY(!ok);
3549
3550 a = "aaa12345aaa";
3551 QCOMPARE(a.toInt(),0);
3552 QCOMPARE(a.toInt(&ok),0);
3553 QVERIFY(!ok);
3554
3555 a = "aaa12345";
3556 QCOMPARE(a.toInt(),0);
3557 QCOMPARE(a.toInt(&ok),0);
3558 QVERIFY(!ok);
3559
3560 a = "12345aaa";
3561 QCOMPARE(a.toInt(),0);
3562 QCOMPARE(a.toInt(&ok),0);
3563 QVERIFY(!ok);
3564
3565 a = "2147483647"; // 2**31 - 1
3566 QCOMPARE(a.toInt(),2147483647);
3567 QCOMPARE(a.toInt(&ok),2147483647);
3568 QVERIFY(ok);
3569
3570 if (sizeof(int) == 4) {
3571 a = "-2147483647"; // -(2**31 - 1)
3572 QCOMPARE(a.toInt(),-2147483647);
3573 QCOMPARE(a.toInt(&ok),-2147483647);
3574 QVERIFY(ok);
3575
3576 a = "2147483648"; // 2**31
3577 QCOMPARE(a.toInt(),0);
3578 QCOMPARE(a.toInt(&ok),0);
3579 QVERIFY(!ok);
3580
3581 a = "-2147483648"; // -2**31
3582 QCOMPARE(a.toInt(),-2147483647 - 1);
3583 QCOMPARE(a.toInt(&ok),-2147483647 - 1);
3584 QVERIFY(ok);
3585
3586 a = "2147483649"; // 2**31 + 1
3587 QCOMPARE(a.toInt(),0);
3588 QCOMPARE(a.toInt(&ok),0);
3589 QVERIFY(!ok);
3590 }
3591}
3592
3593void tst_QString::toUInt()
3594{
3595 bool ok;
3596 QString a;
3597 a="3234567890";
3598 QCOMPARE(a.toUInt(&ok),3234567890u);
3599 QVERIFY(ok);
3600
3601 a = "-50";
3602 QCOMPARE(a.toUInt(),0u);
3603 QCOMPARE(a.toUInt(&ok),0u);
3604 QVERIFY(!ok);
3605
3606 a = "4294967295"; // 2**32 - 1
3607 QCOMPARE(a.toUInt(),4294967295u);
3608 QCOMPARE(a.toUInt(&ok),4294967295u);
3609 QVERIFY(ok);
3610
3611 if (sizeof(int) == 4) {
3612 a = "4294967296"; // 2**32
3613 QCOMPARE(a.toUInt(),0u);
3614 QCOMPARE(a.toUInt(&ok),0u);
3615 QVERIFY(!ok);
3616 }
3617}
3618
3619///////////////////////////// to*Long //////////////////////////////////////
3620
3621void tst_QString::toULong_data()
3622{
3623 QTest::addColumn<QString>(name: "str" );
3624 QTest::addColumn<int>(name: "base" );
3625 QTest::addColumn<ulong>(name: "result" );
3626 QTest::addColumn<bool>(name: "ok" );
3627
3628 QTest::newRow( dataTag: "default" ) << QString() << 10 << 0UL << false;
3629 QTest::newRow( dataTag: "empty" ) << QString("") << 10 << 0UL << false;
3630 QTest::newRow( dataTag: "ulong1" ) << QString("3234567890") << 10 << 3234567890UL << true;
3631 QTest::newRow( dataTag: "ulong2" ) << QString("fFFfFfFf") << 16 << 0xFFFFFFFFUL << true;
3632}
3633
3634void tst_QString::toULong()
3635{
3636 QFETCH( QString, str );
3637 QFETCH( int, base );
3638 QFETCH( ulong, result );
3639 QFETCH( bool, ok );
3640
3641 bool b;
3642 QCOMPARE( str.toULong( 0, base ), result );
3643 QCOMPARE( str.toULong( &b, base ), result );
3644 QCOMPARE( b, ok );
3645}
3646
3647void tst_QString::toLong_data()
3648{
3649 QTest::addColumn<QString>(name: "str" );
3650 QTest::addColumn<int>(name: "base" );
3651 QTest::addColumn<long>(name: "result" );
3652 QTest::addColumn<bool>(name: "ok" );
3653
3654 QTest::newRow( dataTag: "default" ) << QString() << 10 << 0L << false;
3655 QTest::newRow( dataTag: "empty" ) << QString("") << 10 << 0L << false;
3656 QTest::newRow( dataTag: "normal" ) << QString("7fFFfFFf") << 16 << 0x7fFFfFFfL << true;
3657 QTest::newRow( dataTag: "long_max" ) << QString("2147483647") << 10 << 2147483647L << true;
3658 if (sizeof(long) == 4) {
3659 QTest::newRow( dataTag: "long_max+1" ) << QString("2147483648") << 10 << 0L << false;
3660 QTest::newRow( dataTag: "long_min-1" ) << QString("-80000001") << 16 << 0L << false;
3661 }
3662 QTest::newRow( dataTag: "negative" ) << QString("-7fffffff") << 16 << -0x7fffffffL << true;
3663// QTest::newRow( "long_min" ) << QString("-80000000") << 16 << 0x80000000uL << true;
3664}
3665
3666void tst_QString::toLong()
3667{
3668 QFETCH( QString, str );
3669 QFETCH( int, base );
3670 QFETCH( long, result );
3671 QFETCH( bool, ok );
3672
3673 bool b;
3674 QCOMPARE( str.toLong( 0, base ), result );
3675 QCOMPARE( str.toLong( &b, base ), result );
3676 QCOMPARE( b, ok );
3677}
3678
3679
3680////////////////////////// to*LongLong //////////////////////////////////////
3681
3682void tst_QString::toULongLong()
3683{
3684 QString str;
3685 bool ok;
3686 str = "18446744073709551615"; // ULLONG_MAX
3687 QCOMPARE( str.toULongLong( 0 ), Q_UINT64_C(18446744073709551615) );
3688 QCOMPARE( str.toULongLong( &ok ), Q_UINT64_C(18446744073709551615) );
3689 QVERIFY( ok );
3690
3691 str = "18446744073709551616"; // ULLONG_MAX + 1
3692 QCOMPARE( str.toULongLong( 0 ), Q_UINT64_C(0) );
3693 QCOMPARE( str.toULongLong( &ok ), Q_UINT64_C(0) );
3694 QVERIFY( !ok );
3695
3696 str = "-150";
3697 QCOMPARE( str.toULongLong( 0 ), Q_UINT64_C(0) );
3698 QCOMPARE( str.toULongLong( &ok ), Q_UINT64_C(0) );
3699 QVERIFY( !ok );
3700}
3701
3702void tst_QString::toLongLong()
3703{
3704 QString str;
3705 bool ok;
3706
3707 str = "9223372036854775807"; // LLONG_MAX
3708 QCOMPARE( str.toLongLong( 0 ), Q_INT64_C(9223372036854775807) );
3709 QCOMPARE( str.toLongLong( &ok ), Q_INT64_C(9223372036854775807) );
3710 QVERIFY( ok );
3711
3712 str = "-9223372036854775808"; // LLONG_MIN
3713 QCOMPARE( str.toLongLong( 0 ),
3714 -Q_INT64_C(9223372036854775807) - Q_INT64_C(1) );
3715 QCOMPARE( str.toLongLong( &ok ),
3716 -Q_INT64_C(9223372036854775807) - Q_INT64_C(1) );
3717 QVERIFY( ok );
3718
3719 str = "aaaa9223372036854775807aaaa";
3720 QCOMPARE( str.toLongLong( 0 ), Q_INT64_C(0) );
3721 QCOMPARE( str.toLongLong( &ok ), Q_INT64_C(0) );
3722 QVERIFY( !ok );
3723
3724 str = "9223372036854775807aaaa";
3725 QCOMPARE( str.toLongLong( 0 ), Q_INT64_C(0) );
3726 QCOMPARE( str.toLongLong( &ok ), Q_INT64_C(0) );
3727 QVERIFY( !ok );
3728
3729 str = "aaaa9223372036854775807";
3730 QCOMPARE( str.toLongLong( 0 ), Q_INT64_C(0) );
3731 QCOMPARE( str.toLongLong( &ok ), Q_INT64_C(0) );
3732 QVERIFY( !ok );
3733
3734 static char digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
3735
3736 for (int i = 0; i < 36; ++i) {
3737 for (int j = 0; j < 36; ++j) {
3738 for (int k = 0; k < 36; ++k) {
3739 QString str;
3740 str += QChar(digits[i]);
3741 str += QChar(digits[j]);
3742 str += QChar(digits[k]);
3743 qlonglong value = (((i * 36) + j) * 36) + k;
3744 QVERIFY(str.toLongLong(0, 36) == value);
3745 }
3746 }
3747 }
3748}
3749
3750////////////////////////////////////////////////////////////////////////////
3751
3752void tst_QString::toFloat()
3753{
3754 QString a;
3755 bool ok;
3756 a="0.000000000931322574615478515625";
3757 QCOMPARE(a.toFloat(&ok),(float)(0.000000000931322574615478515625));
3758 QVERIFY(ok);
3759}
3760
3761void tst_QString::toDouble_data()
3762{
3763 QTest::addColumn<QString>(name: "str" );
3764 QTest::addColumn<double>(name: "result" );
3765 QTest::addColumn<bool>(name: "result_ok" );
3766
3767 QTest::newRow( dataTag: "ok00" ) << QString("0.000000000931322574615478515625") << 0.000000000931322574615478515625 << true;
3768 QTest::newRow( dataTag: "ok01" ) << QString(" 123.45") << 123.45 << true;
3769
3770 QTest::newRow( dataTag: "ok02" ) << QString("0.1e10") << 0.1e10 << true;
3771 QTest::newRow( dataTag: "ok03" ) << QString("0.1e-10") << 0.1e-10 << true;
3772
3773 QTest::newRow( dataTag: "ok04" ) << QString("1e10") << 1.0e10 << true;
3774 QTest::newRow( dataTag: "ok05" ) << QString("1e+10") << 1.0e10 << true;
3775 QTest::newRow( dataTag: "ok06" ) << QString("1e-10") << 1.0e-10 << true;
3776
3777 QTest::newRow( dataTag: "ok07" ) << QString(" 1e10") << 1.0e10 << true;
3778 QTest::newRow( dataTag: "ok08" ) << QString(" 1e+10") << 1.0e10 << true;
3779 QTest::newRow( dataTag: "ok09" ) << QString(" 1e-10") << 1.0e-10 << true;
3780
3781 QTest::newRow( dataTag: "ok10" ) << QString("1.") << 1.0 << true;
3782 QTest::newRow( dataTag: "ok11" ) << QString(".1") << 0.1 << true;
3783
3784 QTest::newRow( dataTag: "wrong00" ) << QString("123.45 ") << 123.45 << true;
3785 QTest::newRow( dataTag: "wrong01" ) << QString(" 123.45 ") << 123.45 << true;
3786
3787 QTest::newRow( dataTag: "wrong02" ) << QString("aa123.45aa") << 0.0 << false;
3788 QTest::newRow( dataTag: "wrong03" ) << QString("123.45aa") << 0.0 << false;
3789 QTest::newRow( dataTag: "wrong04" ) << QString("123erf") << 0.0 << false;
3790
3791 QTest::newRow( dataTag: "wrong05" ) << QString("abc") << 0.0 << false;
3792 QTest::newRow( dataTag: "wrong06" ) << QString() << 0.0 << false;
3793 QTest::newRow( dataTag: "wrong07" ) << QString("") << 0.0 << false;
3794}
3795
3796void tst_QString::toDouble()
3797{
3798 QFETCH( QString, str );
3799 QFETCH( bool, result_ok );
3800 bool ok;
3801 double d = str.toDouble( ok: &ok );
3802 if ( result_ok ) {
3803 QTEST( d, "result" );
3804 QVERIFY( ok );
3805 } else {
3806 QVERIFY( !ok );
3807 }
3808}
3809
3810void tst_QString::setNum()
3811{
3812 QString a;
3813 QCOMPARE(a.setNum(123), QLatin1String("123"));
3814 QCOMPARE(a.setNum(-123), QLatin1String("-123"));
3815 QCOMPARE(a.setNum(0x123,16), QLatin1String("123"));
3816 QCOMPARE(a.setNum((short)123), QLatin1String("123"));
3817 QCOMPARE(a.setNum(123L), QLatin1String("123"));
3818 QCOMPARE(a.setNum(123UL), QLatin1String("123"));
3819 QCOMPARE(a.setNum(2147483647L), QString("2147483647")); // 32 bit LONG_MAX
3820 QCOMPARE(a.setNum(-2147483647L), QString("-2147483647")); // LONG_MIN + 1
3821 QCOMPARE(a.setNum(-2147483647L-1L), QString("-2147483648")); // LONG_MIN
3822 QCOMPARE(a.setNum(1.23), QString("1.23"));
3823 QCOMPARE(a.setNum(1.234567), QString("1.23457"));
3824#if defined(LONG_MAX) && defined(LLONG_MAX) && LONG_MAX == LLONG_MAX
3825 // LONG_MAX and LONG_MIN on 64 bit systems
3826 QCOMPARE(a.setNum(9223372036854775807L), QString("9223372036854775807"));
3827 QCOMPARE(a.setNum(-9223372036854775807L-1L), QString("-9223372036854775808"));
3828 QCOMPARE(a.setNum(18446744073709551615UL), QString("18446744073709551615"));
3829#endif
3830 QCOMPARE(a.setNum(Q_INT64_C(123)), QString("123"));
3831 // 2^40 == 1099511627776
3832 QCOMPARE(a.setNum(Q_INT64_C(-1099511627776)), QString("-1099511627776"));
3833 QCOMPARE(a.setNum(Q_UINT64_C(1099511627776)), QString("1099511627776"));
3834 QCOMPARE(a.setNum(Q_INT64_C(9223372036854775807)), // LLONG_MAX
3835 QString("9223372036854775807"));
3836 QCOMPARE(a.setNum(-Q_INT64_C(9223372036854775807) - Q_INT64_C(1)),
3837 QString("-9223372036854775808"));
3838 QCOMPARE(a.setNum(Q_UINT64_C(18446744073709551615)), // ULLONG_MAX
3839 QString("18446744073709551615"));
3840 QCOMPARE(a.setNum(0.000000000931322574615478515625),QString("9.31323e-10"));
3841
3842// QCOMPARE(a.setNum(0.000000000931322574615478515625,'g',30),(QString)"9.31322574615478515625e-010");
3843// QCOMPARE(a.setNum(0.000000000931322574615478515625,'f',30),(QString)"0.00000000093132257461547852");
3844}
3845
3846void tst_QString::startsWith()
3847{
3848 QString a;
3849 a = "AB";
3850 QVERIFY( a.startsWith("A") );
3851 QVERIFY( a.startsWith("AB") );
3852 QVERIFY( !a.startsWith("C") );
3853 QVERIFY( !a.startsWith("ABCDEF") );
3854 QVERIFY( a.startsWith("") );
3855 QVERIFY( a.startsWith(QString()) );
3856 QVERIFY( a.startsWith('A') );
3857 QVERIFY( a.startsWith(QLatin1Char('A')) );
3858 QVERIFY( a.startsWith(QChar('A')) );
3859 QVERIFY( !a.startsWith('C') );
3860 QVERIFY( !a.startsWith(QChar()) );
3861 QVERIFY( !a.startsWith(QLatin1Char(0)) );
3862
3863 QVERIFY( a.startsWith(QLatin1String("A")) );
3864 QVERIFY( a.startsWith(QLatin1String("AB")) );
3865 QVERIFY( !a.startsWith(QLatin1String("C")) );
3866 QVERIFY( !a.startsWith(QLatin1String("ABCDEF")) );
3867 QVERIFY( a.startsWith(QLatin1String("")) );
3868 QVERIFY( a.startsWith(QLatin1String(0)) );
3869
3870 QVERIFY( a.startsWith("A", Qt::CaseSensitive) );
3871 QVERIFY( a.startsWith("A", Qt::CaseInsensitive) );
3872 QVERIFY( !a.startsWith("a", Qt::CaseSensitive) );
3873 QVERIFY( a.startsWith("a", Qt::CaseInsensitive) );
3874 QVERIFY( !a.startsWith("aB", Qt::CaseSensitive) );
3875 QVERIFY( a.startsWith("aB", Qt::CaseInsensitive) );
3876 QVERIFY( !a.startsWith("C", Qt::CaseSensitive) );
3877 QVERIFY( !a.startsWith("C", Qt::CaseInsensitive) );
3878 QVERIFY( !a.startsWith("c", Qt::CaseSensitive) );
3879 QVERIFY( !a.startsWith("c", Qt::CaseInsensitive) );
3880 QVERIFY( !a.startsWith("abcdef", Qt::CaseInsensitive) );
3881 QVERIFY( a.startsWith("", Qt::CaseInsensitive) );
3882 QVERIFY( a.startsWith(QString(), Qt::CaseInsensitive) );
3883 QVERIFY( a.startsWith('a', Qt::CaseInsensitive) );
3884 QVERIFY( a.startsWith('A', Qt::CaseInsensitive) );
3885 QVERIFY( a.startsWith(QLatin1Char('a'), Qt::CaseInsensitive) );
3886 QVERIFY( a.startsWith(QChar('a'), Qt::CaseInsensitive) );
3887 QVERIFY( !a.startsWith('c', Qt::CaseInsensitive) );
3888 QVERIFY( !a.startsWith(QChar(), Qt::CaseInsensitive) );
3889 QVERIFY( !a.startsWith(QLatin1Char(0), Qt::CaseInsensitive) );
3890
3891 QVERIFY( a.startsWith(QLatin1String("A"), Qt::CaseSensitive) );
3892 QVERIFY( a.startsWith(QLatin1String("A"), Qt::CaseInsensitive) );
3893 QVERIFY( !a.startsWith(QLatin1String("a"), Qt::CaseSensitive) );
3894 QVERIFY( a.startsWith(QLatin1String("a"), Qt::CaseInsensitive) );
3895 QVERIFY( !a.startsWith(QLatin1String("aB"), Qt::CaseSensitive) );
3896 QVERIFY( a.startsWith(QLatin1String("aB"), Qt::CaseInsensitive) );
3897 QVERIFY( !a.startsWith(QLatin1String("C"), Qt::CaseSensitive) );
3898 QVERIFY( !a.startsWith(QLatin1String("C"), Qt::CaseInsensitive) );
3899 QVERIFY( !a.startsWith(QLatin1String("c"), Qt::CaseSensitive) );
3900 QVERIFY( !a.startsWith(QLatin1String("c"), Qt::CaseInsensitive) );
3901 QVERIFY( !a.startsWith(QLatin1String("abcdef"), Qt::CaseInsensitive) );
3902 QVERIFY( a.startsWith(QLatin1String(""), Qt::CaseInsensitive) );
3903 QVERIFY( a.startsWith(QLatin1String(0), Qt::CaseInsensitive) );
3904 QVERIFY( a.startsWith('A', Qt::CaseSensitive) );
3905 QVERIFY( a.startsWith(QLatin1Char('A'), Qt::CaseSensitive) );
3906 QVERIFY( a.startsWith(QChar('A'), Qt::CaseSensitive) );
3907 QVERIFY( !a.startsWith('a', Qt::CaseSensitive) );
3908 QVERIFY( !a.startsWith(QChar(), Qt::CaseSensitive) );
3909 QVERIFY( !a.startsWith(QLatin1Char(0), Qt::CaseSensitive) );
3910
3911#define TEST_REF_STARTS_WITH(string, yes) { CREATE_REF(string); QCOMPARE(a.startsWith(ref), yes); }
3912
3913 TEST_REF_STARTS_WITH("A", true);
3914 TEST_REF_STARTS_WITH("AB", true);
3915 TEST_REF_STARTS_WITH("C", false);
3916 TEST_REF_STARTS_WITH("ABCDEF", false);
3917#undef TEST_REF_STARTS_WITH
3918
3919 a = "";
3920 QVERIFY( a.startsWith("") );
3921 QVERIFY( a.startsWith(QString()) );
3922 QVERIFY( !a.startsWith("ABC") );
3923
3924 QVERIFY( a.startsWith(QLatin1String("")) );
3925 QVERIFY( a.startsWith(QLatin1String(0)) );
3926 QVERIFY( !a.startsWith(QLatin1String("ABC")) );
3927
3928 QVERIFY( !a.startsWith(QLatin1Char(0)) );
3929 QVERIFY( !a.startsWith(QLatin1Char('x')) );
3930 QVERIFY( !a.startsWith(QChar()) );
3931
3932 a = QString();
3933 QVERIFY( !a.startsWith("") );
3934 QVERIFY( a.startsWith(QString()) );
3935 QVERIFY( !a.startsWith("ABC") );
3936
3937 QVERIFY( !a.startsWith(QLatin1String("")) );
3938 QVERIFY( a.startsWith(QLatin1String(0)) );
3939 QVERIFY( !a.startsWith(QLatin1String("ABC")) );
3940
3941 QVERIFY( !a.startsWith(QLatin1Char(0)) );
3942 QVERIFY( !a.startsWith(QLatin1Char('x')) );
3943 QVERIFY( !a.startsWith(QChar()) );
3944
3945 // this test is independent of encoding
3946 a = "\xc3\xa9";
3947 QVERIFY( a.startsWith("\xc3\xa9") );
3948 QVERIFY( !a.startsWith("\xc3\xa1") );
3949
3950 // this one is dependent of encoding
3951 QVERIFY( a.startsWith("\xc3\x89", Qt::CaseInsensitive) );
3952}
3953
3954void tst_QString::endsWith()
3955{
3956 QString a;
3957 a = "AB";
3958 QVERIFY( a.endsWith("B") );
3959 QVERIFY( a.endsWith("AB") );
3960 QVERIFY( !a.endsWith("C") );
3961 QVERIFY( !a.endsWith("ABCDEF") );
3962 QVERIFY( a.endsWith("") );
3963 QVERIFY( a.endsWith(QString()) );
3964 QVERIFY( a.endsWith('B') );
3965 QVERIFY( a.endsWith(QLatin1Char('B')) );
3966 QVERIFY( a.endsWith(QChar('B')) );
3967 QVERIFY( !a.endsWith('C') );
3968 QVERIFY( !a.endsWith(QChar()) );
3969 QVERIFY( !a.endsWith(QLatin1Char(0)) );
3970
3971 QVERIFY( a.endsWith(QLatin1String("B")) );
3972 QVERIFY( a.endsWith(QLatin1String("AB")) );
3973 QVERIFY( !a.endsWith(QLatin1String("C")) );
3974 QVERIFY( !a.endsWith(QLatin1String("ABCDEF")) );
3975 QVERIFY( a.endsWith(QLatin1String("")) );
3976 QVERIFY( a.endsWith(QLatin1String(0)) );
3977
3978 QVERIFY( a.endsWith("B", Qt::CaseSensitive) );
3979 QVERIFY( a.endsWith("B", Qt::CaseInsensitive) );
3980 QVERIFY( !a.endsWith("b", Qt::CaseSensitive) );
3981 QVERIFY( a.endsWith("b", Qt::CaseInsensitive) );
3982 QVERIFY( !a.endsWith("aB", Qt::CaseSensitive) );
3983 QVERIFY( a.endsWith("aB", Qt::CaseInsensitive) );
3984 QVERIFY( !a.endsWith("C", Qt::CaseSensitive) );
3985 QVERIFY( !a.endsWith("C", Qt::CaseInsensitive) );
3986 QVERIFY( !a.endsWith("c", Qt::CaseSensitive) );
3987 QVERIFY( !a.endsWith("c", Qt::CaseInsensitive) );
3988 QVERIFY( !a.endsWith("abcdef", Qt::CaseInsensitive) );
3989 QVERIFY( a.endsWith("", Qt::CaseInsensitive) );
3990 QVERIFY( a.endsWith(QString(), Qt::CaseInsensitive) );
3991 QVERIFY( a.endsWith('b', Qt::CaseInsensitive) );
3992 QVERIFY( a.endsWith('B', Qt::CaseInsensitive) );
3993 QVERIFY( a.endsWith(QLatin1Char('b'), Qt::CaseInsensitive) );
3994 QVERIFY( a.endsWith(QChar('b'), Qt::CaseInsensitive) );
3995 QVERIFY( !a.endsWith('c', Qt::CaseInsensitive) );
3996 QVERIFY( !a.endsWith(QChar(), Qt::CaseInsensitive) );
3997 QVERIFY( !a.endsWith(QLatin1Char(0), Qt::CaseInsensitive) );
3998
3999 QVERIFY( a.endsWith(QLatin1String("B"), Qt::CaseSensitive) );
4000 QVERIFY( a.endsWith(QLatin1String("B"), Qt::CaseInsensitive) );
4001 QVERIFY( !a.endsWith(QLatin1String("b"), Qt::CaseSensitive) );
4002 QVERIFY( a.endsWith(QLatin1String("b"), Qt::CaseInsensitive) );
4003 QVERIFY( !a.endsWith(QLatin1String("aB"), Qt::CaseSensitive) );
4004 QVERIFY( a.endsWith(QLatin1String("aB"), Qt::CaseInsensitive) );
4005 QVERIFY( !a.endsWith(QLatin1String("C"), Qt::CaseSensitive) );
4006 QVERIFY( !a.endsWith(QLatin1String("C"), Qt::CaseInsensitive) );
4007 QVERIFY( !a.endsWith(QLatin1String("c"), Qt::CaseSensitive) );
4008 QVERIFY( !a.endsWith(QLatin1String("c"), Qt::CaseInsensitive) );
4009 QVERIFY( !a.endsWith(QLatin1String("abcdef"), Qt::CaseInsensitive) );
4010 QVERIFY( a.endsWith(QLatin1String(""), Qt::CaseInsensitive) );
4011 QVERIFY( a.endsWith(QLatin1String(0), Qt::CaseInsensitive) );
4012 QVERIFY( a.endsWith('B', Qt::CaseSensitive) );
4013 QVERIFY( a.endsWith(QLatin1Char('B'), Qt::CaseSensitive) );
4014 QVERIFY( a.endsWith(QChar('B'), Qt::CaseSensitive) );
4015 QVERIFY( !a.endsWith('b', Qt::CaseSensitive) );
4016 QVERIFY( !a.endsWith(QChar(), Qt::CaseSensitive) );
4017 QVERIFY( !a.endsWith(QLatin1Char(0), Qt::CaseSensitive) );
4018
4019
4020#define TEST_REF_ENDS_WITH(string, yes) { CREATE_REF(string); QCOMPARE(a.endsWith(ref), yes); }
4021 TEST_REF_ENDS_WITH(QLatin1String("B"), true);
4022 TEST_REF_ENDS_WITH(QLatin1String("AB"), true);
4023 TEST_REF_ENDS_WITH(QLatin1String("C"), false);
4024 TEST_REF_ENDS_WITH(QLatin1String("ABCDEF"), false);
4025 TEST_REF_ENDS_WITH(QLatin1String(""), true);
4026 TEST_REF_ENDS_WITH(QLatin1String(0), true);
4027
4028#undef TEST_REF_STARTS_WITH
4029
4030 a = "";
4031 QVERIFY( a.endsWith("") );
4032 QVERIFY( a.endsWith(QString()) );
4033 QVERIFY( !a.endsWith("ABC") );
4034 QVERIFY( !a.endsWith(QLatin1Char(0)) );
4035 QVERIFY( !a.endsWith(QLatin1Char('x')) );
4036 QVERIFY( !a.endsWith(QChar()) );
4037
4038 QVERIFY( a.endsWith(QLatin1String("")) );
4039 QVERIFY( a.endsWith(QLatin1String(0)) );
4040 QVERIFY( !a.endsWith(QLatin1String("ABC")) );
4041
4042 a = QString();
4043 QVERIFY( !a.endsWith("") );
4044 QVERIFY( a.endsWith(QString()) );
4045 QVERIFY( !a.endsWith("ABC") );
4046
4047 QVERIFY( !a.endsWith(QLatin1String("")) );
4048 QVERIFY( a.endsWith(QLatin1String(0)) );
4049 QVERIFY( !a.endsWith(QLatin1String("ABC")) );
4050
4051 QVERIFY( !a.endsWith(QLatin1Char(0)) );
4052 QVERIFY( !a.endsWith(QLatin1Char('x')) );
4053 QVERIFY( !a.endsWith(QChar()) );
4054
4055 // this test is independent of encoding
4056 a = "\xc3\xa9";
4057 QVERIFY( a.endsWith("\xc3\xa9") );
4058 QVERIFY( !a.endsWith("\xc3\xa1") );
4059
4060 // this one is dependent of encoding
4061 QVERIFY( a.endsWith("\xc3\x89", Qt::CaseInsensitive) );
4062}
4063
4064void tst_QString::check_QDataStream()
4065{
4066 QString a;
4067 QByteArray ar;
4068 {
4069 QDataStream out(&ar,QIODevice::WriteOnly);
4070 out << QString("COMPARE Text");
4071 }
4072 {
4073 QDataStream in(&ar,QIODevice::ReadOnly);
4074 in >> a;
4075 QCOMPARE(a, QLatin1String("COMPARE Text"));
4076 }
4077}
4078
4079void tst_QString::check_QTextStream()
4080{
4081 QString a;
4082 QByteArray ar;
4083 {
4084 QTextStream out(&ar,QIODevice::WriteOnly);
4085 out << QString("This is COMPARE Text");
4086 }
4087 {
4088 QTextStream in(&ar,QIODevice::ReadOnly);
4089 in >> a;
4090 QCOMPARE(a, QLatin1String("This"));
4091 }
4092}
4093
4094void tst_QString::check_QTextIOStream()
4095{
4096 QString a;
4097 {
4098 a="";
4099 QTextStream ts(&a);
4100 ts << "pi \261= " << 3.125;
4101 QCOMPARE(a, QString::fromLatin1("pi \261= 3.125"));
4102 }
4103 {
4104 a="123 456";
4105 int x,y;
4106 QTextStream(&a) >> x >> y;
4107 QCOMPARE(x,123);
4108 QCOMPARE(y,456);
4109 }
4110}
4111
4112void tst_QString::fromRawData()
4113{
4114 const QChar ptr[] = { 0x1234, 0x0000 };
4115 QString cstr = QString::fromRawData(ptr, size: 1);
4116 QVERIFY(cstr.isDetached());
4117 QVERIFY(cstr.constData() == ptr);
4118 QVERIFY(cstr == QString(ptr, 1));
4119 cstr.squeeze();
4120 QVERIFY(cstr.constData() == ptr);
4121 cstr.detach();
4122 QVERIFY(cstr.size() == 1);
4123 QVERIFY(cstr.capacity() == 1);
4124 QVERIFY(cstr.constData() != ptr);
4125 QVERIFY(cstr.constData()[0] == QChar(0x1234));
4126 QVERIFY(cstr.constData()[1] == QChar(0x0000));
4127}
4128
4129void tst_QString::setRawData()
4130{
4131 const QChar ptr[] = { 0x1234, 0x0000 };
4132 const QChar ptr2[] = { 0x4321, 0x0000 };
4133 QString cstr;
4134
4135 // This just tests the fromRawData() fallback
4136 QVERIFY(!cstr.isDetached());
4137 cstr.setRawData(unicode: ptr, size: 1);
4138 QVERIFY(cstr.isDetached());
4139 QVERIFY(cstr.constData() == ptr);
4140 QVERIFY(cstr == QString(ptr, 1));
4141
4142 // This actually tests the recycling of the shared data object
4143 QString::DataPtr csd = cstr.data_ptr();
4144 cstr.setRawData(unicode: ptr2, size: 1);
4145 QVERIFY(cstr.isDetached());
4146 QVERIFY(cstr.constData() == ptr2);
4147 QVERIFY(cstr == QString(ptr2, 1));
4148 QVERIFY(cstr.data_ptr() == csd);
4149
4150 // This tests the discarding of the shared data object
4151 cstr = "foo";
4152 QVERIFY(cstr.isDetached());
4153 QVERIFY(cstr.constData() != ptr2);
4154
4155 // Another test of the fallback
4156 csd = cstr.data_ptr();
4157 cstr.setRawData(unicode: ptr2, size: 1);
4158 QVERIFY(cstr.isDetached());
4159 QVERIFY(cstr.constData() == ptr2);
4160 QVERIFY(cstr == QString(ptr2, 1));
4161 QVERIFY(cstr.data_ptr() != csd);
4162}
4163
4164void tst_QString::fromStdString()
4165{
4166 std::string stroustrup = "foo";
4167 QString eng = QString::fromStdString( s: stroustrup );
4168 QCOMPARE( eng, QString("foo") );
4169 const char cnull[] = "Embedded\0null\0character!";
4170 std::string stdnull( cnull, sizeof(cnull)-1 );
4171 QString qtnull = QString::fromStdString( s: stdnull );
4172 QCOMPARE( qtnull.size(), int(stdnull.size()) );
4173}
4174
4175void tst_QString::toStdString()
4176{
4177 QString nord = "foo";
4178 std::string stroustrup1 = nord.toStdString();
4179 QVERIFY( qstrcmp(stroustrup1.c_str(), "foo") == 0 );
4180 // For now, most QString constructors are also broken with respect
4181 // to embedded null characters, had to find one that works...
4182 const QChar qcnull[] = {
4183 'E', 'm', 'b', 'e', 'd', 'd', 'e', 'd', '\0',
4184 'n', 'u', 'l', 'l', '\0',
4185 'c', 'h', 'a', 'r', 'a', 'c', 't', 'e', 'r', '!'
4186 };
4187 QString qtnull( qcnull, sizeof(qcnull)/sizeof(QChar) );
4188 std::string stdnull = qtnull.toStdString();
4189 QCOMPARE( int(stdnull.size()), qtnull.size() );
4190}
4191
4192void tst_QString::utf8()
4193{
4194 QFETCH( QByteArray, utf8 );
4195 QFETCH( QString, res );
4196
4197 QCOMPARE(res.toUtf8(), utf8);
4198}
4199
4200void tst_QString::stringRef_utf8_data()
4201{
4202 utf8_data();
4203}
4204
4205void tst_QString::stringRef_utf8()
4206{
4207 QFETCH( QByteArray, utf8 );
4208 QFETCH( QString, res );
4209
4210 QStringRef ref(&res, 0, res.length());
4211 QCOMPARE( utf8, QByteArray(ref.toUtf8()) );
4212}
4213
4214// copied to tst_QTextCodec::utf8Codec_data()
4215void tst_QString::fromUtf8_data()
4216{
4217 QTest::addColumn<QByteArray>(name: "utf8");
4218 QTest::addColumn<QString>(name: "res");
4219 QTest::addColumn<int>(name: "len");
4220 QString str;
4221
4222 QTest::newRow(dataTag: "str0") << QByteArray("abcdefgh") << QString("abcdefgh") << -1;
4223 QTest::newRow(dataTag: "str0-len") << QByteArray("abcdefgh") << QString("abc") << 3;
4224 QTest::newRow(dataTag: "str1") << QByteArray("\303\266\303\244\303\274\303\226\303\204\303\234\303\270\303\246\303\245\303\230\303\206\303\205")
4225 << QString::fromLatin1(str: "\366\344\374\326\304\334\370\346\345\330\306\305") << -1;
4226 QTest::newRow(dataTag: "str1-len") << QByteArray("\303\266\303\244\303\274\303\226\303\204\303\234\303\270\303\246\303\245\303\230\303\206\303\205")
4227 << QString::fromLatin1(str: "\366\344\374\326\304") << 10;
4228
4229 str += QChar(0x05e9);
4230 str += QChar(0x05d3);
4231 str += QChar(0x05d2);
4232 QTest::newRow(dataTag: "str2") << QByteArray("\327\251\327\223\327\222") << str << -1;
4233
4234 str = QChar(0x05e9);
4235 QTest::newRow(dataTag: "str2-len") << QByteArray("\327\251\327\223\327\222") << str << 2;
4236
4237 str = QChar(0x20ac);
4238 str += " some text";
4239 QTest::newRow(dataTag: "str3") << QByteArray("\342\202\254 some text") << str << -1;
4240
4241 str = QChar(0x20ac);
4242 str += " some ";
4243 QTest::newRow(dataTag: "str3-len") << QByteArray("\342\202\254 some text") << str << 9;
4244
4245 // test that QString::fromUtf8 suppresses an initial BOM, but not a ZWNBSP
4246 str = "hello";
4247 QByteArray bom("\357\273\277");
4248 QTest::newRow(dataTag: "bom0") << bom << QString() << 3;
4249 QTest::newRow(dataTag: "bom1") << bom + "hello" << str << -1;
4250 QTest::newRow(dataTag: "bom+zwnbsp0") << bom + bom << QString(QChar(0xfeff)) << -1;
4251 QTest::newRow(dataTag: "bom+zwnbsp1") << bom + "hello" + bom << str + QChar(0xfeff) << -1;
4252
4253 str = "hello";
4254 str += QChar::ReplacementCharacter;
4255 str += QChar(0x68);
4256 str += QChar::ReplacementCharacter;
4257 str += QChar::ReplacementCharacter;
4258 str += QChar::ReplacementCharacter;
4259 str += QChar::ReplacementCharacter;
4260 str += QChar(0x61);
4261 str += QChar::ReplacementCharacter;
4262 QTest::newRow(dataTag: "invalid utf8") << QByteArray("hello\344h\344\344\366\344a\304") << str << -1;
4263 QTest::newRow(dataTag: "invalid utf8-len") << QByteArray("hello\344h\344\344\366\344a\304") << QString("hello") << 5;
4264
4265 str = "Prohl";
4266 str += QChar::ReplacementCharacter;
4267 str += QChar::ReplacementCharacter;
4268 str += "e";
4269 str += QChar::ReplacementCharacter;
4270 str += " plugin";
4271 str += QChar::ReplacementCharacter;
4272 str += " Netscape";
4273
4274 QTest::newRow(dataTag: "invalid utf8 2") << QByteArray("Prohl\355\276e\350 plugin\371 Netscape") << str << -1;
4275 QTest::newRow(dataTag: "invalid utf8-len 2") << QByteArray("Prohl\355\276e\350 plugin\371 Netscape") << QString("") << 0;
4276
4277 QTest::newRow(dataTag: "null-1") << QByteArray() << QString() << -1;
4278 QTest::newRow(dataTag: "null0") << QByteArray() << QString() << 0;
4279 QTest::newRow(dataTag: "null5") << QByteArray() << QString() << 5;
4280 QTest::newRow(dataTag: "empty-1") << QByteArray("\0abcd", 5) << QString() << -1;
4281 QTest::newRow(dataTag: "empty0") << QByteArray() << QString() << 0;
4282 QTest::newRow(dataTag: "empty5") << QByteArray("\0abcd", 5) << QString::fromLatin1(str: "\0abcd", size: 5) << 5;
4283 QTest::newRow(dataTag: "other-1") << QByteArray("ab\0cd", 5) << QString::fromLatin1(str: "ab") << -1;
4284 QTest::newRow(dataTag: "other5") << QByteArray("ab\0cd", 5) << QString::fromLatin1(str: "ab\0cd", size: 5) << 5;
4285
4286 str = "Old Italic: ";
4287 str += QChar(0xd800);
4288 str += QChar(0xdf00);
4289 str += QChar(0xd800);
4290 str += QChar(0xdf01);
4291 str += QChar(0xd800);
4292 str += QChar(0xdf02);
4293 str += QChar(0xd800);
4294 str += QChar(0xdf03);
4295 str += QChar(0xd800);
4296 str += QChar(0xdf04);
4297 QTest::newRow(dataTag: "surrogate") << QByteArray("Old Italic: \360\220\214\200\360\220\214\201\360\220\214\202\360\220\214\203\360\220\214\204") << str << -1;
4298
4299 QTest::newRow(dataTag: "surrogate-len") << QByteArray("Old Italic: \360\220\214\200\360\220\214\201\360\220\214\202\360\220\214\203\360\220\214\204") << str.left(n: 16) << 20;
4300
4301}
4302
4303void tst_QString::fromUtf8()
4304{
4305 QFETCH(QByteArray, utf8);
4306 QFETCH(QString, res);
4307 QFETCH(int, len);
4308
4309 QCOMPARE(QString::fromUtf8(utf8.isNull() ? 0 : utf8.data(), len), res);
4310}
4311
4312void tst_QString::nullFromUtf8()
4313{
4314 QString a;
4315 a = QString::fromUtf8(str: 0);
4316 QVERIFY(a.isNull());
4317 QVERIFY(a.isEmpty());
4318 a = QString::fromUtf8(str: "");
4319 QVERIFY(!a.isNull());
4320 QVERIFY(a.isEmpty());
4321 a = QString::fromUtf8(str: QByteArray());
4322 QVERIFY(a.isNull());
4323 QVERIFY(a.isEmpty());
4324 a = QString::fromUtf8(str: QByteArray(""));
4325 QVERIFY(!a.isNull());
4326 QVERIFY(a.isEmpty());
4327}
4328
4329void tst_QString::fromLocal8Bit_data()
4330{
4331 QTest::addColumn<QByteArray>(name: "local8Bit");
4332 QTest::addColumn<int>(name: "len");
4333 QTest::addColumn<QString>(name: "result");
4334
4335 //QTest::newRow("nullString") << QByteArray() << -1 << QString();
4336 //QTest::newRow("emptyString") << QByteArray("") << -1 << QString("");
4337 //QTest::newRow("string") << QByteArray("test") << -1 << QString("test");
4338 //QTest::newRow("stringlen0") << QByteArray("test") << 0 << QString("");
4339 //QTest::newRow("stringlen3") << QByteArray("test") << 3 << QString("tes");
4340 QTest::newRow(dataTag: "stringlen99") << QByteArray("test\0foo", 8) << 8 << QString::fromLatin1(str: "test\0foo", size: 8);
4341
4342 QByteArray longQByteArray;
4343 QString longQString;
4344
4345 for (int l=0;l<111;l++) {
4346 longQByteArray = longQByteArray + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
4347 longQString += "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
4348 }
4349
4350 //QTest::newRow("longString") << longQByteArray << -1 << longQString;
4351 //QTest::newRow("longStringlen0") << longQByteArray << 0 << QString("");
4352 //QTest::newRow("longStringlen3") << longQByteArray << 3 << QString("aaa");
4353 //QTest::newRow("someNonAlphaChars") << QByteArray("d:/this/is/a/test.h") << -1 << QString("d:/this/is/a/test.h");
4354
4355 //QTest::newRow("null-1") << QByteArray() << -1 << QString();
4356 //QTest::newRow("null0") << QByteArray() << 0 << QString();
4357 //QTest::newRow("null5") << QByteArray() << 5 << QString();
4358 //QTest::newRow("empty-1") << QByteArray("\0abcd", 5) << -1 << QString();
4359 //QTest::newRow("empty0") << QByteArray() << 0 << QString();
4360 //QTest::newRow("empty5") << QByteArray("\0abcd", 5) << 5 << QString::fromLatin1("\0abcd", 5);
4361 //QTest::newRow("other-1") << QByteArray("ab\0cd", 5) << -1 << QString::fromLatin1("ab");
4362 //QTest::newRow("other5") << QByteArray("ab\0cd", 5) << 5 << QString::fromLatin1("ab\0cd", 5);
4363}
4364
4365void tst_QString::fromLocal8Bit()
4366{
4367 QFETCH(QByteArray, local8Bit);
4368 QFETCH(int, len);
4369 QFETCH(QString, result);
4370
4371 QCOMPARE(QString::fromLocal8Bit(local8Bit.isNull() ? 0 : local8Bit.data(), len).length(),
4372 result.length());
4373 QCOMPARE(QString::fromLocal8Bit(local8Bit.isNull() ? 0 : local8Bit.data(), len), result);
4374}
4375
4376void tst_QString::local8Bit_data()
4377{
4378 QTest::addColumn<QString>(name: "local8Bit");
4379 QTest::addColumn<QByteArray>(name: "result");
4380
4381 QTest::newRow(dataTag: "nullString") << QString() << QByteArray();
4382 QTest::newRow(dataTag: "emptyString") << QString("") << QByteArray("");
4383 QTest::newRow(dataTag: "string") << QString("test") << QByteArray("test");
4384
4385 QByteArray longQByteArray;
4386 QString longQString;
4387
4388 for (int l=0;l<111;l++) {
4389 longQByteArray = longQByteArray + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
4390 longQString += "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
4391 }
4392
4393 QTest::newRow(dataTag: "longString") << longQString << longQByteArray;
4394 QTest::newRow(dataTag: "someNonAlphaChars") << QString("d:/this/is/a/test.h") << QByteArray("d:/this/is/a/test.h");
4395}
4396
4397void tst_QString::local8Bit()
4398{
4399 QFETCH(QString, local8Bit);
4400 QFETCH(QByteArray, result);
4401
4402 QCOMPARE(local8Bit.toLocal8Bit(), QByteArray(result));
4403}
4404
4405void tst_QString::invalidToLocal8Bit_data()
4406{
4407 QTest::addColumn<QString>(name: "unicode");
4408 QTest::addColumn<QByteArray>(name: "expect"); // Initial validly-converted prefix
4409
4410 {
4411 const QChar malformed[] = { 'A', 0xd800, 'B', 0 };
4412 const char expected[] = "A";
4413 QTest::newRow(dataTag: "LoneHighSurrogate")
4414 << QString(malformed, sizeof(malformed) / sizeof(QChar))
4415 // Don't include the terminating '\0' of expected:
4416 << QByteArray(expected, sizeof(expected) / sizeof(char) - 1);
4417 }
4418 {
4419 const QChar malformed[] = { 'A', 0xdc00, 'B', 0 };
4420 const char expected[] = "A";
4421 QTest::newRow(dataTag: "LoneLowSurrogate")
4422 << QString(malformed, sizeof(malformed) / sizeof(QChar))
4423 << QByteArray(expected, sizeof(expected) / sizeof(char) - 1);
4424 }
4425 {
4426 const QChar malformed[] = { 'A', 0xd800, 0xd801, 'B', 0 };
4427 const char expected[] = "A";
4428 QTest::newRow(dataTag: "DoubleHighSurrogate")
4429 << QString(malformed, sizeof(malformed) / sizeof(QChar))
4430 << QByteArray(expected, sizeof(expected) / sizeof(char) - 1);
4431 }
4432 {
4433 const QChar malformed[] = { 'A', 0xdc00, 0xdc01, 'B', 0 };
4434 const char expected[] = "A";
4435 QTest::newRow(dataTag: "DoubleLowSurrogate")
4436 << QString(malformed, sizeof(malformed) / sizeof(QChar))
4437 << QByteArray(expected, sizeof(expected) / sizeof(char) - 1);
4438 }
4439 {
4440 const QChar malformed[] = { 'A', 0xdc00, 0xd800, 'B', 0 };
4441 const char expected[] = "A";
4442 QTest::newRow(dataTag: "ReversedSurrogates") // low before high
4443 << QString(malformed, sizeof(malformed) / sizeof(QChar))
4444 << QByteArray(expected, sizeof(expected) / sizeof(char) - 1);
4445 }
4446}
4447
4448void tst_QString::invalidToLocal8Bit()
4449{
4450 QFETCH(QString, unicode);
4451 QFETCH(QByteArray, expect);
4452 QByteArray local = unicode.toLocal8Bit();
4453 /*
4454 The main concern of this test is to check that any error-reporting that
4455 toLocal8Bit() prompts on failure isn't dependent on outputting the data
4456 it's converting via toLocal8Bit(), which would be apt to recurse. So the
4457 real purpose of this QVERIFY(), for all that we should indeed check we get
4458 the borked output that matches what we can reliably expect (despite
4459 variation in how codecs respond to errors), is to verify that we got here
4460 - i.e. we didn't crash in such a recursive stack over-flow.
4461 */
4462 QVERIFY(local.startsWith(expect));
4463}
4464
4465void tst_QString::nullFromLocal8Bit()
4466{
4467 QString a;
4468 a = QString::fromLocal8Bit(str: 0);
4469 QVERIFY(a.isNull());
4470 QVERIFY(a.isEmpty());
4471 a = QString::fromLocal8Bit(str: "");
4472 QVERIFY(!a.isNull());
4473 QVERIFY(a.isEmpty());
4474 a = QString::fromLocal8Bit(str: QByteArray());
4475 QVERIFY(a.isNull());
4476 QVERIFY(a.isEmpty());
4477 a = QString::fromLocal8Bit(str: QByteArray(""));
4478 QVERIFY(!a.isNull());
4479 QVERIFY(a.isEmpty());
4480}
4481
4482void tst_QString::stringRef_local8Bit_data()
4483{
4484 local8Bit_data();
4485}
4486
4487void tst_QString::stringRef_local8Bit()
4488{
4489 QFETCH(QString, local8Bit);
4490 QFETCH(QByteArray, result);
4491
4492 QStringRef ref(&local8Bit, 0, local8Bit.length());
4493 QCOMPARE(ref.toLocal8Bit(), QByteArray(result));
4494}
4495
4496void tst_QString::fromLatin1Roundtrip_data()
4497{
4498 QTest::addColumn<QByteArray>(name: "latin1");
4499 QTest::addColumn<QString>(name: "unicode");
4500
4501 QTest::newRow(dataTag: "null") << QByteArray() << QString();
4502 QTest::newRow(dataTag: "empty") << QByteArray("") << "";
4503
4504 static const ushort unicode1[] = { 'H', 'e', 'l', 'l', 'o', 1, '\r', '\n', 0x7f };
4505 QTest::newRow(dataTag: "ascii-only") << QByteArray("Hello") << QString::fromUtf16(unicode1, size: 5);
4506 QTest::newRow(dataTag: "ascii+control") << QByteArray("Hello\1\r\n\x7f") << QString::fromUtf16(unicode1, size: 9);
4507
4508 static const ushort unicode3[] = { 'a', 0, 'z' };
4509 QTest::newRow(dataTag: "ascii+nul") << QByteArray("a\0z", 3) << QString::fromUtf16(unicode3, size: 3);
4510
4511 static const ushort unicode4[] = { 0x80, 0xc0, 0xff };
4512 QTest::newRow(dataTag: "non-ascii") << QByteArray("\x80\xc0\xff") << QString::fromUtf16(unicode4, size: 3);
4513}
4514
4515void tst_QString::fromLatin1Roundtrip()
4516{
4517 QFETCH(QByteArray, latin1);
4518 QFETCH(QString, unicode);
4519
4520 // Qt Test safety check:
4521 QCOMPARE(latin1.isNull(), unicode.isNull());
4522 QCOMPARE(latin1.isEmpty(), unicode.isEmpty());
4523 QCOMPARE(latin1.length(), unicode.length());
4524
4525 if (!latin1.isEmpty())
4526 while (latin1.length() < 128) {
4527 latin1 += latin1;
4528 unicode += unicode;
4529 }
4530
4531 // fromLatin1
4532 QCOMPARE(QString::fromLatin1(latin1, latin1.length()).length(), unicode.length());
4533 QCOMPARE(QString::fromLatin1(latin1, latin1.length()), unicode);
4534
4535 // and back:
4536 QCOMPARE(unicode.toLatin1().length(), latin1.length());
4537 QCOMPARE(unicode.toLatin1(), latin1);
4538}
4539
4540void tst_QString::toLatin1Roundtrip_data()
4541{
4542 QTest::addColumn<QByteArray>(name: "latin1");
4543 QTest::addColumn<QString>(name: "unicodesrc");
4544 QTest::addColumn<QString>(name: "unicodedst");
4545
4546 QTest::newRow(dataTag: "null") << QByteArray() << QString() << QString();
4547 QTest::newRow(dataTag: "empty") << QByteArray("") << "" << "";
4548
4549 static const ushort unicode1[] = { 'H', 'e', 'l', 'l', 'o', 1, '\r', '\n', 0x7f };
4550 QTest::newRow(dataTag: "ascii-only") << QByteArray("Hello") << QString::fromUtf16(unicode1, size: 5) << QString::fromUtf16(unicode1, size: 5);
4551 QTest::newRow(dataTag: "ascii+control") << QByteArray("Hello\1\r\n\x7f") << QString::fromUtf16(unicode1, size: 9) << QString::fromUtf16(unicode1, size: 9);
4552
4553 static const ushort unicode3[] = { 'a', 0, 'z' };
4554 QTest::newRow(dataTag: "ascii+nul") << QByteArray("a\0z", 3) << QString::fromUtf16(unicode3, size: 3) << QString::fromUtf16(unicode3, size: 3);
4555
4556 static const ushort unicode4[] = { 0x80, 0xc0, 0xff };
4557 QTest::newRow(dataTag: "non-ascii") << QByteArray("\x80\xc0\xff") << QString::fromUtf16(unicode4, size: 3) << QString::fromUtf16(unicode4, size: 3);
4558
4559 static const ushort unicodeq[] = { '?', '?', '?', '?', '?' };
4560 const QString questionmarks = QString::fromUtf16(unicodeq, size: 5);
4561
4562 static const ushort unicode5[] = { 0x100, 0x101, 0x17f, 0x7f00, 0x7f7f };
4563 QTest::newRow(dataTag: "non-latin1a") << QByteArray("?????") << QString::fromUtf16(unicode5, size: 5) << questionmarks;
4564
4565 static const ushort unicode6[] = { 0x180, 0x1ff, 0x8001, 0x8080, 0xfffc };
4566 QTest::newRow(dataTag: "non-latin1b") << QByteArray("?????") << QString::fromUtf16(unicode6, size: 5) << questionmarks;
4567}
4568
4569void tst_QString::toLatin1Roundtrip()
4570{
4571 QFETCH(QByteArray, latin1);
4572 QFETCH(QString, unicodesrc);
4573 QFETCH(QString, unicodedst);
4574
4575 // Qt Test safety check:
4576 QCOMPARE(latin1.isNull(), unicodesrc.isNull());
4577 QCOMPARE(latin1.isEmpty(), unicodesrc.isEmpty());
4578 QCOMPARE(latin1.length(), unicodesrc.length());
4579 QCOMPARE(latin1.isNull(), unicodedst.isNull());
4580 QCOMPARE(latin1.isEmpty(), unicodedst.isEmpty());
4581 QCOMPARE(latin1.length(), unicodedst.length());
4582
4583 if (!latin1.isEmpty())
4584 while (latin1.length() < 128) {
4585 latin1 += latin1;
4586 unicodesrc += unicodesrc;
4587 unicodedst += unicodedst;
4588 }
4589
4590 // toLatin1
4591 QCOMPARE(unicodesrc.toLatin1().length(), latin1.length());
4592 QCOMPARE(unicodesrc.toLatin1(), latin1);
4593
4594 // and back:
4595 QCOMPARE(QString::fromLatin1(latin1, latin1.length()).length(), unicodedst.length());
4596 QCOMPARE(QString::fromLatin1(latin1, latin1.length()), unicodedst);
4597
4598 // try the rvalue version of toLatin1()
4599 QString s = unicodesrc;
4600 QCOMPARE(std::move(s).toLatin1(), latin1);
4601
4602 // and verify that the moved-from object can still be used
4603 s = "foo";
4604 s.clear();
4605}
4606
4607void tst_QString::stringRef_toLatin1Roundtrip_data()
4608{
4609 toLatin1Roundtrip_data();
4610}
4611
4612void tst_QString::stringRef_toLatin1Roundtrip()
4613{
4614 QFETCH(QByteArray, latin1);
4615 QFETCH(QString, unicodesrc);
4616 QFETCH(QString, unicodedst);
4617
4618 // Qt Test safety check:
4619 QCOMPARE(latin1.isNull(), unicodesrc.isNull());
4620 QCOMPARE(latin1.isEmpty(), unicodesrc.isEmpty());
4621 QCOMPARE(latin1.length(), unicodesrc.length());
4622 QCOMPARE(latin1.isNull(), unicodedst.isNull());
4623 QCOMPARE(latin1.isEmpty(), unicodedst.isEmpty());
4624 QCOMPARE(latin1.length(), unicodedst.length());
4625
4626 if (!latin1.isEmpty())
4627 while (latin1.length() < 128) {
4628 latin1 += latin1;
4629 unicodesrc += unicodesrc;
4630 unicodedst += unicodedst;
4631 }
4632
4633 // toLatin1
4634 QStringRef src(&unicodesrc, 0, unicodesrc.length());
4635 QCOMPARE(src.toLatin1().length(), latin1.length());
4636 QCOMPARE(src.toLatin1(), latin1);
4637}
4638
4639void tst_QString::fromLatin1()
4640{
4641 QString a;
4642 a = QString::fromLatin1( str: 0 );
4643 QVERIFY( a.isNull() );
4644 QVERIFY( a.isEmpty() );
4645 a = QString::fromLatin1( str: "" );
4646 QVERIFY( !a.isNull() );
4647 QVERIFY( a.isEmpty() );
4648 a = QString::fromLatin1(str: QByteArray());
4649 QVERIFY(a.isNull());
4650 QVERIFY(a.isEmpty());
4651 a = QString::fromLatin1(str: QByteArray(""));
4652 QVERIFY(!a.isNull());
4653 QVERIFY(a.isEmpty());
4654
4655 a = QString::fromLatin1(str: 0, size: 0);
4656 QVERIFY(a.isNull());
4657 a = QString::fromLatin1(str: 0, size: 5);
4658 QVERIFY(a.isNull());
4659 a = QString::fromLatin1(str: "\0abcd", size: 0);
4660 QVERIFY(!a.isNull());
4661 QVERIFY(a.isEmpty());
4662 a = QString::fromLatin1(str: "\0abcd", size: 5);
4663 QVERIFY(a.size() == 5);
4664}
4665
4666#if QT_DEPRECATED_SINCE(5, 0)
4667QT_WARNING_PUSH
4668QT_WARNING_DISABLE_DEPRECATED
4669void tst_QString::fromAscii()
4670{
4671 QString a;
4672 a = QString::fromAscii( str: 0 );
4673 QVERIFY( a.isNull() );
4674 QVERIFY( a.isEmpty() );
4675 a = QString::fromAscii( str: "" );
4676 QVERIFY( !a.isNull() );
4677 QVERIFY( a.isEmpty() );
4678
4679 a = QString::fromAscii(str: 0, size: 0);
4680 QVERIFY(a.isNull());
4681 a = QString::fromAscii(str: 0, size: 5);
4682 QVERIFY(a.isNull());
4683 a = QString::fromAscii(str: "\0abcd", size: 0);
4684 QVERIFY(!a.isNull());
4685 QVERIFY(a.isEmpty());
4686 a = QString::fromAscii(str: "\0abcd", size: 5);
4687 QVERIFY(a.size() == 5);
4688}
4689QT_WARNING_POP
4690#endif
4691
4692void tst_QString::fromUcs4()
4693{
4694 const uint *null = 0;
4695 QString s;
4696 s = QString::fromUcs4( null );
4697 QVERIFY( s.isNull() );
4698 QCOMPARE( s.size(), 0 );
4699 s = QString::fromUcs4( null, size: 0 );
4700 QVERIFY( s.isNull() );
4701 QCOMPARE( s.size(), 0 );
4702 s = QString::fromUcs4( null, size: 5 );
4703 QVERIFY( s.isNull() );
4704 QCOMPARE( s.size(), 0 );
4705
4706 uint nil = '\0';
4707 s = QString::fromUcs4( &nil );
4708 QVERIFY( !s.isNull() );
4709 QCOMPARE( s.size(), 0 );
4710 s = QString::fromUcs4( &nil, size: 0 );
4711 QVERIFY( !s.isNull() );
4712 QCOMPARE( s.size(), 0 );
4713
4714 uint bmp = 'a';
4715 s = QString::fromUcs4( &bmp, size: 1 );
4716 QVERIFY( !s.isNull() );
4717 QCOMPARE( s.size(), 1 );
4718
4719 uint smp = 0x10000;
4720 s = QString::fromUcs4( &smp, size: 1 );
4721 QVERIFY( !s.isNull() );
4722 QCOMPARE( s.size(), 2 );
4723
4724#ifdef Q_COMPILER_UNICODE_STRINGS
4725 static const char32_t str1[] = U"Hello Unicode World";
4726 s = QString::fromUcs4(str: str1, size: sizeof(str1) / sizeof(str1[0]) - 1);
4727 QCOMPARE(s, QString("Hello Unicode World"));
4728
4729 s = QString::fromUcs4(str: str1);
4730 QCOMPARE(s, QString("Hello Unicode World"));
4731
4732 s = QString::fromUcs4(str: str1, size: 5);
4733 QCOMPARE(s, QString("Hello"));
4734
4735 s = QString::fromUcs4(str: U"\u221212\U000020AC\U00010000");
4736 QCOMPARE(s, QString::fromUtf8("\342\210\222" "12" "\342\202\254" "\360\220\200\200"));
4737#endif
4738
4739 // QTBUG-62011: don't mistake ZWNBS for BOM
4740 // Start with one BOM, to ensure we use the right endianness:
4741 const uint text[] = { 0xfeff, 97, 0xfeff, 98, 0xfeff, 99, 0xfeff, 100 };
4742 s = QString::fromUcs4(text, size: 8);
4743 QCOMPARE(s, QStringView(u"a\xfeff" u"b\xfeff" u"c\xfeff" "d"));
4744}
4745
4746void tst_QString::toUcs4()
4747{
4748 QString s;
4749 QVector<uint> ucs4;
4750 QCOMPARE( s.toUcs4().size(), 0 );
4751
4752 static const QChar bmp = QLatin1Char('a');
4753 s = QString(&bmp, 1);
4754 ucs4 = s.toUcs4();
4755 QCOMPARE( ucs4.size(), 1 );
4756 QCOMPARE( ucs4.at(0), 0x0061u );
4757
4758#define QSTRING_FROM_QCHARARRAY(x) (QString((x), sizeof(x)/sizeof((x)[0])))
4759
4760 static const QChar smp[] = { QChar::highSurrogate(ucs4: 0x10000), QChar::lowSurrogate(ucs4: 0x10000) };
4761 s = QSTRING_FROM_QCHARARRAY(smp);
4762 ucs4 = s.toUcs4();
4763 QCOMPARE( ucs4.size(), 1 );
4764 QCOMPARE( ucs4.at(0), 0x10000u );
4765
4766 static const QChar smp2[] = { QChar::highSurrogate(ucs4: 0x10000), QChar::lowSurrogate(ucs4: 0x10000), QChar::highSurrogate(ucs4: 0x10000), QChar::lowSurrogate(ucs4: 0x10000) };
4767 s = QSTRING_FROM_QCHARARRAY(smp2);
4768 ucs4 = s.toUcs4();
4769 QCOMPARE( ucs4.size(), 2 );
4770 QCOMPARE( ucs4.at(0), 0x10000u );
4771 QCOMPARE( ucs4.at(1), 0x10000u );
4772
4773 static const QChar invalid_01[] = { QChar(0xd800) };
4774 s = QSTRING_FROM_QCHARARRAY(invalid_01);
4775 ucs4 = s.toUcs4();
4776 QCOMPARE( ucs4.size(), 1 );
4777 QCOMPARE( ucs4.at(0), 0xFFFDu );
4778
4779 static const QChar invalid_02[] = { QChar(0xdc00) };
4780 s = QSTRING_FROM_QCHARARRAY(invalid_02);
4781 ucs4 = s.toUcs4();
4782 QCOMPARE( ucs4.size(), 1 );
4783 QCOMPARE( ucs4.at(0), 0xFFFDu );
4784
4785 static const QChar invalid_03[] = { QLatin1Char('a'), QChar(0xd800), QLatin1Char('b') };
4786 s = QSTRING_FROM_QCHARARRAY(invalid_03);
4787 ucs4 = s.toUcs4();
4788 QCOMPARE( ucs4.size(), 3 );
4789 QCOMPARE( ucs4.at(0), 0x0061u );
4790 QCOMPARE( ucs4.at(1), 0xFFFDu );
4791 QCOMPARE( ucs4.at(2), 0x0062u );
4792
4793 static const QChar invalid_04[] = { QLatin1Char('a'), QChar(0xdc00), QLatin1Char('b') };
4794 s = QSTRING_FROM_QCHARARRAY(invalid_04);
4795 ucs4 = s.toUcs4();
4796 QCOMPARE( ucs4.size(), 3 );
4797 QCOMPARE( ucs4.at(0), 0x0061u );
4798 QCOMPARE( ucs4.at(1), 0xFFFDu );
4799 QCOMPARE( ucs4.at(2), 0x0062u );
4800
4801 static const QChar invalid_05[] = { QLatin1Char('a'), QChar(0xd800), QChar(0xd800), QLatin1Char('b') };
4802 s = QSTRING_FROM_QCHARARRAY(invalid_05);
4803 ucs4 = s.toUcs4();
4804 QCOMPARE( ucs4.size(), 4 );
4805 QCOMPARE( ucs4.at(0), 0x0061u );
4806 QCOMPARE( ucs4.at(1), 0xFFFDu );
4807 QCOMPARE( ucs4.at(2), 0xFFFDu );
4808 QCOMPARE( ucs4.at(3), 0x0062u );
4809
4810 static const QChar invalid_06[] = { QLatin1Char('a'), QChar(0xdc00), QChar(0xdc00), QLatin1Char('b') };
4811 s = QSTRING_FROM_QCHARARRAY(invalid_06);
4812 ucs4 = s.toUcs4();
4813 QCOMPARE( ucs4.size(), 4 );
4814 QCOMPARE( ucs4.at(0), 0x0061u );
4815 QCOMPARE( ucs4.at(1), 0xFFFDu );
4816 QCOMPARE( ucs4.at(2), 0xFFFDu );
4817 QCOMPARE( ucs4.at(3), 0x0062u );
4818
4819#undef QSTRING_FROM_QCHARARRAY
4820
4821}
4822
4823void tst_QString::arg()
4824{
4825/*
4826 Warning: If any of these test fails, the warning given by Qt Test
4827 is all messed up, because Qt Test itself uses QString::arg().
4828*/
4829
4830 TransientDefaultLocale transient(QString("de_DE"));
4831
4832 QString s4( "[%0]" );
4833 QString s5( "[%1]" );
4834 QString s6( "[%3]" );
4835 QString s7( "[%9]" );
4836 QString s8( "[%0 %1]" );
4837 QString s9( "[%0 %3]" );
4838 QString s10( "[%1 %2 %3]" );
4839 QString s11( "[%9 %3 %0]" );
4840 QString s12( "[%9 %1 %3 %9 %0 %8]" );
4841 QString s13( "%1% %x%c%2 %d%2-%" );
4842 QString s14( "%1%2%3" );
4843
4844 QCOMPARE( s4.arg("foo"), QLatin1String("[foo]") );
4845 QCOMPARE( s5.arg(QLatin1String("foo")), QLatin1String("[foo]") );
4846 QCOMPARE( s6.arg(u"foo"), QLatin1String("[foo]") );
4847 QCOMPARE( s7.arg("foo"), QLatin1String("[foo]") );
4848 QCOMPARE( s8.arg("foo"), QLatin1String("[foo %1]") );
4849 QCOMPARE( s8.arg("foo").arg("bar"), QLatin1String("[foo bar]") );
4850 QCOMPARE( s8.arg("foo", "bar"), QLatin1String("[foo bar]") );
4851 QCOMPARE( s9.arg("foo"), QLatin1String("[foo %3]") );
4852 QCOMPARE( s9.arg("foo").arg("bar"), QLatin1String("[foo bar]") );
4853 QCOMPARE( s9.arg("foo", "bar"), QLatin1String("[foo bar]") );
4854 QCOMPARE( s10.arg("foo"), QLatin1String("[foo %2 %3]") );
4855 QCOMPARE( s10.arg("foo").arg("bar"), QLatin1String("[foo bar %3]") );
4856 QCOMPARE( s10.arg("foo", "bar"), QLatin1String("[foo bar %3]") );
4857 QCOMPARE( s10.arg("foo").arg("bar").arg("baz"), QLatin1String("[foo bar baz]") );
4858 QCOMPARE( s10.arg("foo", "bar", "baz"), QLatin1String("[foo bar baz]") );
4859 QCOMPARE( s11.arg("foo"), QLatin1String("[%9 %3 foo]") );
4860 QCOMPARE( s11.arg("foo").arg("bar"), QLatin1String("[%9 bar foo]") );
4861 QCOMPARE( s11.arg("foo", "bar"), QLatin1String("[%9 bar foo]") );
4862 QCOMPARE( s11.arg("foo").arg("bar").arg("baz"), QLatin1String("[baz bar foo]") );
4863 QCOMPARE( s11.arg("foo", "bar", "baz"), QLatin1String("[baz bar foo]") );
4864 QCOMPARE( s12.arg("a").arg("b").arg("c").arg("d").arg("e"),
4865 QLatin1String("[e b c e a d]") );
4866 QCOMPARE( s12.arg("a", "b", "c", "d").arg("e"), QLatin1String("[e b c e a d]") );
4867 QCOMPARE( s12.arg("a").arg("b", "c", "d", "e"), QLatin1String("[e b c e a d]") );
4868 QCOMPARE( s13.arg("alpha").arg("beta"),
4869 QLatin1String("alpha% %x%cbeta %dbeta-%") );
4870 QCOMPARE( s13.arg("alpha", "beta"), QLatin1String("alpha% %x%cbeta %dbeta-%") );
4871 QCOMPARE( s14.arg("a", "b", "c"), QLatin1String("abc") );
4872 QCOMPARE( s8.arg("%1").arg("foo"), QLatin1String("[foo foo]") );
4873 QCOMPARE( s8.arg("%1", "foo"), QLatin1String("[%1 foo]") );
4874 QCOMPARE( s4.arg("foo", 2), QLatin1String("[foo]") );
4875 QCOMPARE( s4.arg("foo", -2), QLatin1String("[foo]") );
4876 QCOMPARE( s4.arg("foo", 10), QLatin1String("[ foo]") );
4877 QCOMPARE( s4.arg("foo", -10), QLatin1String("[foo ]") );
4878
4879 QString firstName( "James" );
4880 QString lastName( "Bond" );
4881 QString fullName = QString( "My name is %2, %1 %2" )
4882 .arg( a: firstName ).arg( a: lastName );
4883 QCOMPARE( fullName, QLatin1String("My name is Bond, James Bond") );
4884
4885 // number overloads
4886 QCOMPARE( s4.arg(0), QLatin1String("[0]") );
4887 QCOMPARE( s4.arg(-1), QLatin1String("[-1]") );
4888 QCOMPARE( s4.arg(4294967295UL), QLatin1String("[4294967295]") ); // ULONG_MAX 32
4889 QCOMPARE( s4.arg(Q_INT64_C(9223372036854775807)), // LLONG_MAX
4890 QLatin1String("[9223372036854775807]") );
4891
4892 QTest::ignoreMessage(type: QtWarningMsg, message: "QString::arg: Argument missing: \"\" , 0");
4893 QCOMPARE( QString().arg(0), QString() );
4894 QTest::ignoreMessage(type: QtWarningMsg, message: "QString::arg: Argument missing: \"\" , 0");
4895 QCOMPARE( QString("").arg(0), QString("") );
4896 QTest::ignoreMessage(type: QtWarningMsg, message: "QString::arg: Argument missing: \" \" , 0");
4897 QCOMPARE( QString(" ").arg(0), QLatin1String(" ") );
4898 QTest::ignoreMessage(type: QtWarningMsg, message: "QString::arg: Argument missing: \"%\" , 0");
4899 QCOMPARE( QString("%").arg(0), QLatin1String("%") );
4900 QTest::ignoreMessage(type: QtWarningMsg, message: "QString::arg: Argument missing: \"%%\" , 0");
4901 QCOMPARE( QString("%%").arg(0), QLatin1String("%%") );
4902 QTest::ignoreMessage(type: QtWarningMsg, message: "QString::arg: Argument missing: \"%%%\" , 0");
4903 QCOMPARE( QString("%%%").arg(0), QLatin1String("%%%") );
4904 QCOMPARE( QString("%%%1%%%2").arg("foo").arg("bar"), QLatin1String("%%foo%%bar") );
4905
4906 QCOMPARE( QString("%1").arg("hello", -10), QLatin1String("hello ") );
4907 QCOMPARE( QString("%1").arg(QLatin1String("hello"), -5), QLatin1String("hello") );
4908 QCOMPARE( QString("%1").arg(u"hello", -2), QLatin1String("hello") );
4909 QCOMPARE( QString("%1").arg("hello", 0), QLatin1String("hello") );
4910 QCOMPARE( QString("%1").arg(QLatin1String("hello"), 2), QLatin1String("hello") );
4911 QCOMPARE( QString("%1").arg(u"hello", 5), QLatin1String("hello") );
4912 QCOMPARE( QString("%1").arg("hello", 10), QLatin1String(" hello") );
4913 QCOMPARE( QString("%1%1").arg("hello"), QLatin1String("hellohello") );
4914 QCOMPARE( QString("%2%1").arg("hello"), QLatin1String("%2hello") );
4915 QCOMPARE( QString("%1%1").arg(QString()), QLatin1String("") );
4916 QCOMPARE( QString("%2%1").arg(""), QLatin1String("%2") );
4917
4918 QCOMPARE( QString("%2 %L1").arg(12345.6789).arg(12345.6789),
4919 QLatin1String("12345.7 12.345,7") );
4920 QCOMPARE( QString("[%2] [%L1]").arg(12345.6789, 9).arg(12345.6789, 9),
4921 QLatin1String("[ 12345.7] [ 12.345,7]") );
4922 QCOMPARE( QString("[%2] [%L1]").arg(12345.6789, 9, 'g', 7).arg(12345.6789, 9, 'g', 7),
4923 QLatin1String("[ 12345.68] [12.345,68]") );
4924 QCOMPARE( QString("[%2] [%L1]").arg(12345.6789, 10, 'g', 7, QLatin1Char('0')).arg(12345.6789, 10, 'g', 7, QLatin1Char('0')),
4925 QLatin1String("[0012345.68] [012.345,68]") );
4926
4927 QCOMPARE( QString("%2 %L1").arg(123456789).arg(123456789),
4928 QLatin1String("123456789 123.456.789") );
4929 QCOMPARE( QString("[%2] [%L1]").arg(123456789, 12).arg(123456789, 12),
4930 QLatin1String("[ 123456789] [ 123.456.789]") );
4931 QCOMPARE( QString("[%2] [%L1]").arg(123456789, 13, 10, QLatin1Char('0')).arg(123456789, 12, 10, QLatin1Char('0')),
4932 QLatin1String("[000123456789] [00123.456.789]") );
4933 QCOMPARE( QString("[%2] [%L1]").arg(123456789, 13, 16, QLatin1Char('0')).arg(123456789, 12, 16, QLatin1Char('0')),
4934 QLatin1String("[0000075bcd15] [00000075bcd15]") );
4935
4936 QCOMPARE( QString("%L2 %L1 %3").arg(12345.7).arg(123456789).arg('c'),
4937 QLatin1String("123.456.789 12.345,7 c") );
4938
4939 // multi-digit replacement
4940 QString input("%%%L0 %1 %02 %3 %4 %5 %L6 %7 %8 %%% %090 %10 %11 %L12 %14 %L9888 %9999 %%%%%%%L");
4941 input = input.arg(a: "A").arg(a: "B").arg(a: "C")
4942 .arg(a: "D").arg(a: "E").arg(a: "f")
4943 .arg(a: "g").arg(a: "h").arg(a: "i").arg(a: "j")
4944 .arg(a: "k").arg(a: "l").arg(a: "m")
4945 .arg(a: "n").arg(a: "o").arg(a: "p");
4946
4947 QCOMPARE(input, QLatin1String("%%A B C D E f g h i %%% j0 k l m n o88 p99 %%%%%%%L"));
4948
4949 QString str("%1 %2 %3 %4 %5 %6 %7 %8 %9 foo %10 %11 bar");
4950 str = str.arg(args: "one", args: "2", args: "3", args: "4", args: "5", args: "6", args: "7", args: "8", args: "9");
4951 str = str.arg(args: "ahoy", args: "there");
4952 QCOMPARE(str, QLatin1String("one 2 3 4 5 6 7 8 9 foo ahoy there bar"));
4953
4954 QString str2("%123 %234 %345 %456 %567 %999 %1000 %1230");
4955 str2 = str2.arg(args: "A", args: "B", args: "C", args: "D", args: "E", args: "F");
4956 QCOMPARE(str2, QLatin1String("A B C D E F %1000 %1230"));
4957
4958 QCOMPARE(QString("%1").arg(-1, 3, 10, QChar('0')), QLatin1String("-01"));
4959 QCOMPARE(QString("%1").arg(-100, 3, 10, QChar('0')), QLatin1String("-100"));
4960 QCOMPARE(QString("%1").arg(-1, 3, 10, QChar(' ')), QLatin1String(" -1"));
4961 QCOMPARE(QString("%1").arg(-100, 3, 10, QChar(' ')), QLatin1String("-100"));
4962 QCOMPARE(QString("%1").arg(1U, 3, 10, QChar(' ')), QLatin1String(" 1"));
4963 QCOMPARE(QString("%1").arg(1000U, 3, 10, QChar(' ')), QLatin1String("1000"));
4964 QCOMPARE(QString("%1").arg(-1, 3, 10, QChar('x')), QLatin1String("x-1"));
4965 QCOMPARE(QString("%1").arg(-100, 3, 10, QChar('x')), QLatin1String("-100"));
4966 QCOMPARE(QString("%1").arg(1U, 3, 10, QChar('x')), QLatin1String("xx1"));
4967 QCOMPARE(QString("%1").arg(1000U, 3, 10, QChar('x')), QLatin1String("1000"));
4968
4969 QCOMPARE(QString("%1").arg(-1., 3, 'g', -1, QChar('0')), QLatin1String("-01"));
4970 QCOMPARE(QString("%1").arg(-100., 3, 'g', -1, QChar('0')), QLatin1String("-100"));
4971 QCOMPARE(QString("%1").arg(-1., 3, 'g', -1, QChar(' ')), QLatin1String(" -1"));
4972 QCOMPARE(QString("%1").arg(-100., 3, 'g', -1, QChar(' ')), QLatin1String("-100"));
4973 QCOMPARE(QString("%1").arg(1., 3, 'g', -1, QChar('x')), QLatin1String("xx1"));
4974 QCOMPARE(QString("%1").arg(1000., 3, 'g', -1, QChar('x')), QLatin1String("1000"));
4975 QCOMPARE(QString("%1").arg(-1., 3, 'g', -1, QChar('x')), QLatin1String("x-1"));
4976 QCOMPARE(QString("%1").arg(-100., 3, 'g', -1, QChar('x')), QLatin1String("-100"));
4977
4978 transient.revise(transient: QString("ar"));
4979 QCOMPARE( QString("%L1").arg(12345.6789, 10, 'g', 7, QLatin1Char('0')),
4980 QString::fromUtf8("\xd9\xa0\xd9\xa1\xd9\xa2\xd9\xac\xd9\xa3\xd9\xa4\xd9\xa5\xd9\xab\xd9\xa6\xd9\xa8") ); // "Ω Ω‘Ω’Ω¬Ω£Ω€Ω₯Ω«Ω¦Ω¨"
4981 QCOMPARE( QString("%L1").arg(123456789, 13, 10, QLatin1Char('0')),
4982 QString("\xd9\xa0\xd9\xa0\xd9\xa1\xd9\xa2\xd9\xa3\xd9\xac\xd9\xa4\xd9\xa5\xd9\xa6\xd9\xac\xd9\xa7\xd9\xa8\xd9\xa9") ); // Ω Ω Ω‘Ω’Ω£Ω¬Ω€Ω₯Ω¦Ω¬Ω§Ω¨Ω©
4983}
4984
4985void tst_QString::number()
4986{
4987 QCOMPARE( QString::number(int(0)), QLatin1String("0") );
4988 QCOMPARE( QString::number((unsigned int)(11)), QLatin1String("11") );
4989 QCOMPARE( QString::number(-22L), QLatin1String("-22") );
4990 QCOMPARE( QString::number(333UL), QLatin1String("333") );
4991 QCOMPARE( QString::number(4.4), QLatin1String("4.4") );
4992 QCOMPARE( QString::number(Q_INT64_C(-555)), QLatin1String("-555") );
4993 QCOMPARE( QString::number(Q_UINT64_C(6666)), QLatin1String("6666") );
4994
4995#ifndef QT_NO_DOUBLECONVERSION // snprintf_l is too stupid for this
4996 QCOMPARE( QString::number(12.05, 'f', 1), QString("12.1") );
4997 QCOMPARE( QString::number(12.5, 'f', 0), QString("13") );
4998#endif
4999}
5000
5001void tst_QString::doubleOut()
5002{
5003 // Regression test for QTBUG-63620; the first two paths lost the exponent's
5004 // leading 0 at 5.7; C's printf() family guarantee a two-digit exponent (in
5005 // contrast with ECMAScript, which forbids leading zeros).
5006 const QString expect(QStringLiteral("1e-06"));
5007 const double micro = 1e-6;
5008 QCOMPARE(QString::number(micro), expect);
5009 QCOMPARE(QString("%1").arg(micro), expect);
5010 {
5011 QCOMPARE(QString::asprintf("%g", micro), expect);
5012 }
5013 {
5014 QString text;
5015 QTextStream stream(&text);
5016 stream << micro;
5017 QCOMPARE(text, expect);
5018 }
5019}
5020
5021void tst_QString::capacity_data()
5022{
5023 length_data();
5024}
5025
5026void tst_QString::capacity()
5027{
5028 QFETCH( QString, s1 );
5029 QFETCH( int, res );
5030
5031 QString s2( s1 );
5032 s2.reserve( asize: res );
5033 QVERIFY( (int)s2.capacity() >= res );
5034 QCOMPARE( s2, s1 );
5035
5036 s2 = s1; // share again
5037 s2.reserve( asize: res * 2 );
5038 QVERIFY( (int)s2.capacity() >= res * 2 );
5039 QVERIFY(s2.constData() != s1.constData());
5040 QCOMPARE( s2, s1 );
5041
5042 // don't share again -- s2 must be detached for squeeze() to do anything
5043 s2.squeeze();
5044 QVERIFY( (int)s2.capacity() == res );
5045 QCOMPARE( s2, s1 );
5046
5047 s2 = s1; // share again
5048 int oldsize = s1.size();
5049 s2.reserve( asize: res / 2 );
5050 QVERIFY( (int)s2.capacity() >= res / 2 );
5051 QVERIFY( (int)s2.capacity() >= oldsize );
5052 QCOMPARE( s2, s1 );
5053}
5054
5055void tst_QString::section_data()
5056{
5057 QTest::addColumn<QString>(name: "wholeString" );
5058 QTest::addColumn<QString>(name: "sep" );
5059 QTest::addColumn<int>(name: "start" );
5060 QTest::addColumn<int>(name: "end" );
5061 QTest::addColumn<int>(name: "flags" );
5062 QTest::addColumn<QString>(name: "sectionString" );
5063 QTest::addColumn<bool>(name: "regexp" );
5064
5065 QTest::newRow( dataTag: "data0" ) << QString("forename,middlename,surname,phone") << QString(",") << 2 << 2 << int(QString::SectionDefault) << QString("surname") << false;
5066 QTest::newRow( dataTag: "data1" ) << QString("/usr/local/bin/myapp") << QString("/") << 3 << 4 << int(QString::SectionDefault) << QString("bin/myapp") << false;
5067 QTest::newRow( dataTag: "data2" ) << QString("/usr/local/bin/myapp") << QString("/") << 3 << 3 << int(QString::SectionSkipEmpty) << QString("myapp") << false;
5068 QTest::newRow( dataTag: "data3" ) << QString("forename**middlename**surname**phone") << QString("**") << 2 << 2 << int(QString::SectionDefault) << QString("surname") << false;
5069 QTest::newRow( dataTag: "data4" ) << QString("forename**middlename**surname**phone") << QString("**") << -3 << -2 << int(QString::SectionDefault) << QString("middlename**surname") << false;
5070 QTest::newRow( dataTag: "data5" ) << QString("##Datt######wollen######wir######mal######sehen##") << QString("#") << 0 << 0 << int(QString::SectionSkipEmpty) << QString("Datt") << false;
5071 QTest::newRow( dataTag: "data6" ) << QString("##Datt######wollen######wir######mal######sehen##") << QString("#") << 1 << 1 << int(QString::SectionSkipEmpty) << QString("wollen") << false;
5072 QTest::newRow( dataTag: "data7" ) << QString("##Datt######wollen######wir######mal######sehen##") << QString("#") << 2 << 2 << int(QString::SectionSkipEmpty) << QString("wir") << false;
5073 QTest::newRow( dataTag: "data8" ) << QString("##Datt######wollen######wir######mal######sehen##") << QString("#") << 3 << 3 << int(QString::SectionSkipEmpty) << QString("mal") << false;
5074 QTest::newRow( dataTag: "data9" ) << QString("##Datt######wollen######wir######mal######sehen##") << QString("#") << 4 << 4 << int(QString::SectionSkipEmpty) << QString("sehen") << false;
5075 // not fixed for 3.1
5076 QTest::newRow( dataTag: "data10" ) << QString("a/b/c/d") << QString("/") << 1 << -1 << int(QString::SectionIncludeLeadingSep | QString::SectionIncludeTrailingSep) << QString("/b/c/d") << false;
5077 QTest::newRow( dataTag: "data11" ) << QString("aoLoboLocolod") << QString("olo") << -1 << -1 << int(QString::SectionCaseInsensitiveSeps) << QString("d") << false;
5078 QTest::newRow( dataTag: "data12" ) << QString("F0") << QString("F") << 0 << 0 << int(QString::SectionSkipEmpty) << QString("0") << false;
5079 QTest::newRow( dataTag: "foo1" ) << QString("foo;foo;") << QString(";") << 0 << 0
5080 << int(QString::SectionIncludeLeadingSep) << QString("foo") << false;
5081 QTest::newRow( dataTag: "foo2" ) << QString("foo;foo;") << QString(";") << 1 << 1
5082 << int(QString::SectionIncludeLeadingSep) << QString(";foo") << false;
5083 QTest::newRow( dataTag: "foo3" ) << QString("foo;foo;") << QString(";") << 2 << 2
5084 << int(QString::SectionIncludeLeadingSep) << QString(";") << false;
5085 QTest::newRow( dataTag: "foo1rx" ) << QString("foo;foo;") << QString(";") << 0 << 0
5086 << int(QString::SectionIncludeLeadingSep) << QString("foo") << true;
5087 QTest::newRow( dataTag: "foo2rx" ) << QString("foo;foo;") << QString(";") << 1 << 1
5088 << int(QString::SectionIncludeLeadingSep) << QString(";foo") << true;
5089 QTest::newRow( dataTag: "foo3rx" ) << QString("foo;foo;") << QString(";") << 2 << 2
5090 << int(QString::SectionIncludeLeadingSep) << QString(";") << true;
5091
5092 QTest::newRow( dataTag: "qmake_path" ) << QString("/Users/sam/troll/qt4.0/src/corelib/QtCore_debug.xcode/")
5093 << QString("/") << 0 << -2 << int(QString::SectionDefault)
5094 << QString("/Users/sam/troll/qt4.0/src/corelib/QtCore_debug.xcode") << false;
5095 QTest::newRow( dataTag: "qmake_pathrx" ) << QString("/Users/sam/troll/qt4.0/src/corelib/QtCore_debug.xcode/")
5096 << QString("/") << 0 << -2 << int(QString::SectionDefault)
5097 << QString("/Users/sam/troll/qt4.0/src/corelib/QtCore_debug.xcode") << true;
5098 QTest::newRow( dataTag: "data13" ) << QString("||2|3|||")
5099 << QString("|") << 0 << 1 << int(QString::SectionIncludeLeadingSep|QString::SectionIncludeTrailingSep)
5100 << QString("||") << false;
5101 QTest::newRow( dataTag: "data14" ) << QString("||2|3|||")
5102 << QString("\\|") << 0 << 1 << int(QString::SectionIncludeLeadingSep|QString::SectionIncludeTrailingSep)
5103 << QString("||") << true;
5104 QTest::newRow( dataTag: "data15" ) << QString("|1|2|")
5105 << QString("|") << 0 << 1 << int(QString::SectionIncludeLeadingSep|QString::SectionIncludeTrailingSep)
5106 << QString("|1|") << false;
5107 QTest::newRow( dataTag: "data16" ) << QString("|1|2|")
5108 << QString("\\|") << 0 << 1 << int(QString::SectionIncludeLeadingSep|QString::SectionIncludeTrailingSep)
5109 << QString("|1|") << true;
5110 QTest::newRow( dataTag: "normal1" ) << QString("o1o2o")
5111 << QString("o") << 0 << 0
5112 << int(QString::SectionIncludeLeadingSep|QString::SectionIncludeTrailingSep)
5113 << QString("o") << false;
5114 QTest::newRow( dataTag: "normal2" ) << QString("o1o2o")
5115 << QString("o") << 1 << 1
5116 << int(QString::SectionIncludeLeadingSep|QString::SectionIncludeTrailingSep)
5117 << QString("o1o") << false;
5118 QTest::newRow( dataTag: "normal3" ) << QString("o1o2o")
5119 << QString("o") << 2 << 2
5120 << int(QString::SectionIncludeLeadingSep|QString::SectionIncludeTrailingSep)
5121 << QString("o2o") << false;
5122 QTest::newRow( dataTag: "normal4" ) << QString("o1o2o")
5123 << QString("o") << 2 << 3
5124 << int(QString::SectionIncludeLeadingSep|QString::SectionIncludeTrailingSep)
5125 << QString("o2o") << false;
5126 QTest::newRow( dataTag: "normal5" ) << QString("o1o2o")
5127 << QString("o") << 1 << 2
5128 << int(QString::SectionIncludeLeadingSep|QString::SectionIncludeTrailingSep)
5129 << QString("o1o2o") << false;
5130 QTest::newRow( dataTag: "range1" ) << QString("o1o2o")
5131 << QString("o") << -5 << -5
5132 << int(QString::SectionIncludeLeadingSep|QString::SectionIncludeTrailingSep)
5133 << QString() << false;
5134 QTest::newRow( dataTag: "range2" ) << QString("oo1o2o")
5135 << QString("o") << -5 << 1
5136 << int(QString::SectionIncludeLeadingSep|QString::SectionIncludeTrailingSep
5137 |QString::SectionSkipEmpty)
5138 << QString("oo1o2o") << false;
5139 QTest::newRow( dataTag: "range3" ) << QString("o1o2o")
5140 << QString("o") << 2 << 1
5141 << int(QString::SectionIncludeLeadingSep|QString::SectionIncludeTrailingSep)
5142 << QString() << false;
5143 QTest::newRow( dataTag: "range4" ) << QString("o1o2o")
5144 << QString("o") << 4 << 4
5145 << int(QString::SectionIncludeLeadingSep|QString::SectionIncludeTrailingSep)
5146 << QString() << false;
5147 QTest::newRow( dataTag: "range5" ) << QString("o1oo2o")
5148 << QString("o") << -2 << -1
5149 << int(QString::SectionIncludeLeadingSep|QString::SectionIncludeTrailingSep
5150 |QString::SectionSkipEmpty)
5151 << QString("o1oo2o") << false;
5152 QTest::newRow( dataTag: "rx1" ) << QString("o1o2o")
5153 << QString("[a-z]") << 0 << 0
5154 << int(QString::SectionIncludeLeadingSep|QString::SectionIncludeTrailingSep)
5155 << QString("o") << true;
5156 QTest::newRow( dataTag: "rx2" ) << QString("o1o2o")
5157 << QString("[a-z]") << 1 << 1
5158 << int(QString::SectionIncludeLeadingSep|QString::SectionIncludeTrailingSep)
5159 << QString("o1o") << true;
5160 QTest::newRow( dataTag: "rx3" ) << QString("o1o2o")
5161 << QString("[a-z]") << 2 << 2
5162 << int(QString::SectionIncludeLeadingSep|QString::SectionIncludeTrailingSep)
5163 << QString("o2o") << true;
5164 QTest::newRow( dataTag: "rx4" ) << QString("o1o2o")
5165 << QString("[a-z]") << 2 << 3
5166 << int(QString::SectionIncludeLeadingSep|QString::SectionIncludeTrailingSep)
5167 << QString("o2o") << true;
5168 QTest::newRow( dataTag: "rx5" ) << QString("o1o2o")
5169 << QString("[a-z]") << 1 << 2
5170 << int(QString::SectionIncludeLeadingSep|QString::SectionIncludeTrailingSep)
5171 << QString("o1o2o") << true;
5172 QTest::newRow( dataTag: "data17" ) << QString("This is a story, a small story")
5173 << QString("\\b") << 3 << 3
5174 << int(QString::SectionDefault)
5175 << QString("is") << true;
5176 QTest::newRow( dataTag: "data18" ) << QString("99.0 42.3")
5177 << QString("\\s*[AaBb]\\s*") << 1 << 1
5178 << int(QString::SectionIncludeLeadingSep)
5179 << QString() << true;
5180}
5181
5182void tst_QString::section()
5183{
5184 QFETCH( QString, wholeString );
5185 QFETCH( QString, sep );
5186 QFETCH( int, start );
5187 QFETCH( int, end );
5188 QFETCH( int, flags );
5189 QFETCH( QString, sectionString );
5190 QFETCH( bool, regexp );
5191 if (regexp) {
5192 QCOMPARE( wholeString.section( QRegExp(sep), start, end, QString::SectionFlag(flags) ), sectionString );
5193 QCOMPARE( wholeString.section( QRegularExpression(sep), start, end, QString::SectionFlag(flags) ), sectionString );
5194 } else {
5195 if (sep.size() == 1)
5196 QCOMPARE( wholeString.section( sep[0], start, end, QString::SectionFlag(flags) ), sectionString );
5197 QCOMPARE( wholeString.section( sep, start, end, QString::SectionFlag(flags) ), sectionString );
5198 QCOMPARE( wholeString.section( QRegExp(QRegExp::escape(sep)), start, end, QString::SectionFlag(flags) ), sectionString );
5199 QCOMPARE( wholeString.section( QRegularExpression(QRegularExpression::escape(sep)), start, end, QString::SectionFlag(flags) ), sectionString );
5200
5201 }
5202}
5203
5204
5205void tst_QString::operator_eqeq_nullstring()
5206{
5207 /* Some of these might not be all that logical but it's the behaviour we've had since 3.0.0
5208 so we should probably stick with it. */
5209
5210 QVERIFY( QString() == "" );
5211 QVERIFY( "" == QString() );
5212
5213 QVERIFY( QString("") == "" );
5214 QVERIFY( "" == QString("") );
5215
5216 QVERIFY(QString() == nullptr);
5217 QVERIFY(nullptr == QString());
5218
5219 QVERIFY(QString("") == nullptr);
5220 QVERIFY(nullptr == QString(""));
5221
5222 QVERIFY( QString().size() == 0 );
5223
5224 QVERIFY( QString("").size() == 0 );
5225
5226 QVERIFY( QString() == QString("") );
5227 QVERIFY( QString("") == QString() );
5228}
5229
5230void tst_QString::operator_smaller()
5231{
5232 QString null;
5233 QString empty("");
5234 QString foo("foo");
5235 const char *nullC = nullptr;
5236 const char *emptyC = "";
5237
5238 QVERIFY( !(null < QString()) );
5239 QVERIFY( !(null > QString()) );
5240
5241 QVERIFY( !(empty < QString("")) );
5242 QVERIFY( !(empty > QString("")) );
5243
5244 QVERIFY( !(null < empty) );
5245 QVERIFY( !(null > empty) );
5246
5247 QVERIFY( !(nullC < empty) );
5248 QVERIFY( !(nullC > empty) );
5249
5250 QVERIFY( !(null < emptyC) );
5251 QVERIFY( !(null > emptyC) );
5252
5253 QVERIFY( null < foo );
5254 QVERIFY( !(null > foo) );
5255 QVERIFY( foo > null );
5256 QVERIFY( !(foo < null) );
5257
5258 QVERIFY( empty < foo );
5259 QVERIFY( !(empty > foo) );
5260 QVERIFY( foo > empty );
5261 QVERIFY( !(foo < empty) );
5262
5263 QVERIFY( !(null < QLatin1String(0)) );
5264 QVERIFY( !(null > QLatin1String(0)) );
5265 QVERIFY( !(null < QLatin1String("")) );
5266 QVERIFY( !(null > QLatin1String("")) );
5267
5268 QVERIFY( !(null < QLatin1String("")) );
5269 QVERIFY( !(null > QLatin1String("")) );
5270 QVERIFY( !(empty < QLatin1String("")) );
5271 QVERIFY( !(empty > QLatin1String("")) );
5272
5273 QVERIFY( !(QLatin1String(0) < null) );
5274 QVERIFY( !(QLatin1String(0) > null) );
5275 QVERIFY( !(QLatin1String("") < null) );
5276 QVERIFY( !(QLatin1String("") > null) );
5277
5278 QVERIFY( !(QLatin1String(0) < empty) );
5279 QVERIFY( !(QLatin1String(0) > empty) );
5280 QVERIFY( !(QLatin1String("") < empty) );
5281 QVERIFY( !(QLatin1String("") > empty) );
5282
5283 QVERIFY( QLatin1String(0) < foo );
5284 QVERIFY( !(QLatin1String(0) > foo) );
5285 QVERIFY( QLatin1String("") < foo );
5286 QVERIFY( !(QLatin1String("") > foo) );
5287
5288 QVERIFY( foo > QLatin1String(0) );
5289 QVERIFY( !(foo < QLatin1String(0)) );
5290 QVERIFY( foo > QLatin1String("") );
5291 QVERIFY( !(foo < QLatin1String("")) );
5292
5293 QVERIFY( QLatin1String(0) == empty);
5294 QVERIFY( QLatin1String(0) == null);
5295 QVERIFY( QLatin1String("") == empty);
5296 QVERIFY( QLatin1String("") == null);
5297
5298 QVERIFY( !(foo < QLatin1String("foo")));
5299 QVERIFY( !(foo > QLatin1String("foo")));
5300 QVERIFY( !(QLatin1String("foo") < foo));
5301 QVERIFY( !(QLatin1String("foo") > foo));
5302
5303 QVERIFY( !(foo < QLatin1String("a")));
5304 QVERIFY( (foo > QLatin1String("a")));
5305 QVERIFY( (QLatin1String("a") < foo));
5306 QVERIFY( !(QLatin1String("a") > foo));
5307
5308 QVERIFY( (foo < QLatin1String("z")));
5309 QVERIFY( !(foo > QLatin1String("z")));
5310 QVERIFY( !(QLatin1String("z") < foo));
5311 QVERIFY( (QLatin1String("z") > foo));
5312
5313 // operator< is not locale-aware (or shouldn't be)
5314 QVERIFY( foo < QString("\xc3\xa9") );
5315 QVERIFY( foo < "\xc3\xa9" );
5316
5317 QVERIFY(QString("a") < QString("b"));
5318 QVERIFY(QString("a") <= QString("b"));
5319 QVERIFY(QString("a") <= QString("a"));
5320 QVERIFY(QString("a") == QString("a"));
5321 QVERIFY(QString("a") >= QString("a"));
5322 QVERIFY(QString("b") >= QString("a"));
5323 QVERIFY(QString("b") > QString("a"));
5324
5325 QVERIFY("a" < QString("b"));
5326 QVERIFY("a" <= QString("b"));
5327 QVERIFY("a" <= QString("a"));
5328 QVERIFY("a" == QString("a"));
5329 QVERIFY("a" >= QString("a"));
5330 QVERIFY("b" >= QString("a"));
5331 QVERIFY("b" > QString("a"));
5332
5333 QVERIFY(QString("a") < "b");
5334 QVERIFY(QString("a") <= "b");
5335 QVERIFY(QString("a") <= "a");
5336 QVERIFY(QString("a") == "a");
5337 QVERIFY(QString("a") >= "a");
5338 QVERIFY(QString("b") >= "a");
5339 QVERIFY(QString("b") > "a");
5340
5341 QVERIFY(QString("a") < QByteArray("b"));
5342 QVERIFY(QString("a") <= QByteArray("b"));
5343 QVERIFY(QString("a") <= QByteArray("a"));
5344 QVERIFY(QString("a") == QByteArray("a"));
5345 QVERIFY(QString("a") >= QByteArray("a"));
5346 QVERIFY(QString("b") >= QByteArray("a"));
5347 QVERIFY(QString("b") > QByteArray("a"));
5348
5349#if QT_DEPRECATED_SINCE(5, 15)
5350QT_WARNING_PUSH
5351QT_WARNING_DISABLE_DEPRECATED
5352 QVERIFY(QByteArray("a") < QString("b"));
5353 QVERIFY(QByteArray("a") <= QString("b"));
5354 QVERIFY(QByteArray("a") <= QString("a"));
5355 QVERIFY(QByteArray("a") == QString("a"));
5356 QVERIFY(QByteArray("a") >= QString("a"));
5357 QVERIFY(QByteArray("b") >= QString("a"));
5358 QVERIFY(QByteArray("b") > QString("a"));
5359QT_WARNING_POP
5360#endif
5361
5362 QVERIFY(QLatin1String("a") < QString("b"));
5363 QVERIFY(QLatin1String("a") <= QString("b"));
5364 QVERIFY(QLatin1String("a") <= QString("a"));
5365 QVERIFY(QLatin1String("a") == QString("a"));
5366 QVERIFY(QLatin1String("a") >= QString("a"));
5367 QVERIFY(QLatin1String("b") >= QString("a"));
5368 QVERIFY(QLatin1String("b") > QString("a"));
5369
5370 QVERIFY(QString("a") < QLatin1String("b"));
5371 QVERIFY(QString("a") <= QLatin1String("b"));
5372 QVERIFY(QString("a") <= QLatin1String("a"));
5373 QVERIFY(QString("a") == QLatin1String("a"));
5374 QVERIFY(QString("a") >= QLatin1String("a"));
5375 QVERIFY(QString("b") >= QLatin1String("a"));
5376 QVERIFY(QString("b") > QLatin1String("a"));
5377
5378 QVERIFY("a" < QLatin1String("b"));
5379 QVERIFY("a" <= QLatin1String("b"));
5380 QVERIFY("a" <= QLatin1String("a"));
5381 QVERIFY("a" == QLatin1String("a"));
5382 QVERIFY("a" >= QLatin1String("a"));
5383 QVERIFY("b" >= QLatin1String("a"));
5384 QVERIFY("b" > QLatin1String("a"));
5385
5386 QVERIFY(QLatin1String("a") < "b");
5387 QVERIFY(QLatin1String("a") <= "b");
5388 QVERIFY(QLatin1String("a") <= "a");
5389 QVERIFY(QLatin1String("a") == "a");
5390 QVERIFY(QLatin1String("a") >= "a");
5391 QVERIFY(QLatin1String("b") >= "a");
5392 QVERIFY(QLatin1String("b") > "a");
5393}
5394
5395void tst_QString::integer_conversion_data()
5396{
5397 QTest::addColumn<QString>(name: "num_str");
5398 QTest::addColumn<int>(name: "base");
5399 QTest::addColumn<bool>(name: "good");
5400 QTest::addColumn<qlonglong>(name: "num");
5401
5402 QTest::newRow(dataTag: "C empty 0") << QString("") << 0 << false << (qlonglong)0;
5403 QTest::newRow(dataTag: "C empty 8") << QString("") << 8 << false << (qlonglong)0;
5404 QTest::newRow(dataTag: "C empty 10") << QString("") << 10 << false << (qlonglong)0;
5405 QTest::newRow(dataTag: "C empty 16") << QString("") << 16 << false << (qlonglong)0;
5406
5407 QTest::newRow(dataTag: "C null 0") << QString() << 0 << false << (qlonglong)0;
5408 QTest::newRow(dataTag: "C null 8") << QString() << 8 << false << (qlonglong)0;
5409 QTest::newRow(dataTag: "C null 10") << QString() << 10 << false << (qlonglong)0;
5410 QTest::newRow(dataTag: "C null 16") << QString() << 16 << false << (qlonglong)0;
5411
5412 QTest::newRow(dataTag: "C -0xf 0") << QString(" -0xf") << 0 << true << (qlonglong)-15;
5413 QTest::newRow(dataTag: "C -0xf 0") << QString("-0xf ") << 0 << true << (qlonglong)-15;
5414 QTest::newRow(dataTag: "C \t0xf\t 0") << QString("\t0xf\t") << 0 << true << (qlonglong)15;
5415 QTest::newRow(dataTag: "C -010 0") << QString(" -010") << 0 << true << (qlonglong)-8;
5416 QTest::newRow(dataTag: "C 010 0") << QString("010 ") << 0 << true << (qlonglong)8;
5417 QTest::newRow(dataTag: "C \t-010\t 0") << QString("\t-010\t") << 0 << true << (qlonglong)-8;
5418 QTest::newRow(dataTag: "C 123 10") << QString(" 123") << 10 << true << (qlonglong)123;
5419 QTest::newRow(dataTag: "C 123 10") << QString("123 ") << 10 << true << (qlonglong)123;
5420 QTest::newRow(dataTag: "C \t123\t 10") << QString("\t123\t") << 10 << true << (qlonglong)123;
5421 QTest::newRow(dataTag: "C -0xf 16") << QString(" -0xf") << 16 << true << (qlonglong)-15;
5422 QTest::newRow(dataTag: "C -0xf 16") << QString("-0xf ") << 16 << true << (qlonglong)-15;
5423 QTest::newRow(dataTag: "C \t0xf\t 16") << QString("\t0xf\t") << 16 << true << (qlonglong)15;
5424
5425 QTest::newRow(dataTag: "C -0 0") << QString("-0") << 0 << true << (qlonglong)0;
5426 QTest::newRow(dataTag: "C -0 8") << QString("-0") << 8 << true << (qlonglong)0;
5427 QTest::newRow(dataTag: "C -0 10") << QString("-0") << 10 << true << (qlonglong)0;
5428 QTest::newRow(dataTag: "C -0 16") << QString("-0") << 16 << true << (qlonglong)0;
5429
5430 QTest::newRow(dataTag: "C 1.234 10") << QString("1.234") << 10 << false << (qlonglong)0;
5431 QTest::newRow(dataTag: "C 1,234 10") << QString("1,234") << 10 << false << (qlonglong)0;
5432
5433 QTest::newRow(dataTag: "C 0x 0") << QString("0x") << 0 << false << (qlonglong)0;
5434 QTest::newRow(dataTag: "C 0x 16") << QString("0x") << 16 << false << (qlonglong)0;
5435
5436 QTest::newRow(dataTag: "C 10 0") << QString("10") << 0 << true << (qlonglong)10;
5437 QTest::newRow(dataTag: "C 010 0") << QString("010") << 0 << true << (qlonglong)8;
5438 QTest::newRow(dataTag: "C 0x10 0") << QString("0x10") << 0 << true << (qlonglong)16;
5439 QTest::newRow(dataTag: "C 10 8") << QString("10") << 8 << true << (qlonglong)8;
5440 QTest::newRow(dataTag: "C 010 8") << QString("010") << 8 << true << (qlonglong)8;
5441 QTest::newRow(dataTag: "C 0x10 8") << QString("0x10") << 8 << false << (qlonglong)0;
5442 QTest::newRow(dataTag: "C 10 10") << QString("10") << 10 << true << (qlonglong)10;
5443 QTest::newRow(dataTag: "C 010 10") << QString("010") << 10 << true << (qlonglong)10;
5444 QTest::newRow(dataTag: "C 0x10 10") << QString("0x10") << 10 << false << (qlonglong)0;
5445 QTest::newRow(dataTag: "C 10 16") << QString("10") << 16 << true << (qlonglong)16;
5446 QTest::newRow(dataTag: "C 010 16") << QString("010") << 16 << true << (qlonglong)16;
5447 QTest::newRow(dataTag: "C 0x10 16") << QString("0x10") << 16 << true << (qlonglong)16;
5448
5449 QTest::newRow(dataTag: "C -10 0") << QString("-10") << 0 << true << (qlonglong)-10;
5450 QTest::newRow(dataTag: "C -010 0") << QString("-010") << 0 << true << (qlonglong)-8;
5451 QTest::newRow(dataTag: "C -0x10 0") << QString("-0x10") << 0 << true << (qlonglong)-16;
5452 QTest::newRow(dataTag: "C -10 8") << QString("-10") << 8 << true << (qlonglong)-8;
5453 QTest::newRow(dataTag: "C -010 8") << QString("-010") << 8 << true << (qlonglong)-8;
5454 QTest::newRow(dataTag: "C -0x10 8") << QString("-0x10") << 8 << false << (qlonglong)0;
5455 QTest::newRow(dataTag: "C -10 10") << QString("-10") << 10 << true << (qlonglong)-10;
5456 QTest::newRow(dataTag: "C -010 10") << QString("-010") << 10 << true << (qlonglong)-10;
5457 QTest::newRow(dataTag: "C -0x10 10") << QString("-0x10") << 10 << false << (qlonglong)0;
5458 QTest::newRow(dataTag: "C -10 16") << QString("-10") << 16 << true << (qlonglong)-16;
5459 QTest::newRow(dataTag: "C -010 16") << QString("-010") << 16 << true << (qlonglong)-16;
5460 QTest::newRow(dataTag: "C -0x10 16") << QString("-0x10") << 16 << true << (qlonglong)-16;
5461
5462 // Let's try some Arabic
5463 const quint16 arabic_str[] = { 0x0661, 0x0662, 0x0663, 0x0664, 0x0000 }; // "1234"
5464 QTest::newRow(dataTag: "ar_SA 1234 0") << QString::fromUtf16(arabic_str) << 0 << false << (qlonglong)0;
5465}
5466
5467void tst_QString::integer_conversion()
5468{
5469 QFETCH(QString, num_str);
5470 QFETCH(int, base);
5471 QFETCH(bool, good);
5472 QFETCH(qlonglong, num);
5473
5474 bool ok;
5475 qlonglong d = num_str.toLongLong(ok: &ok, base);
5476 QCOMPARE(ok, good);
5477
5478 if (ok) {
5479 QCOMPARE(d, num);
5480 }
5481}
5482
5483void tst_QString::double_conversion_data()
5484{
5485 QTest::addColumn<QString>(name: "num_str");
5486 QTest::addColumn<bool>(name: "good");
5487 QTest::addColumn<double>(name: "num");
5488
5489 // The good...
5490
5491 QTest::newRow(dataTag: "C 1") << QString("1") << true << 1.0;
5492 QTest::newRow(dataTag: "C 1.0") << QString("1.0") << true << 1.0;
5493 QTest::newRow(dataTag: "C 1.234") << QString("1.234") << true << 1.234;
5494 QTest::newRow(dataTag: "C 1.234e-10") << QString("1.234e-10") << true << 1.234e-10;
5495 QTest::newRow(dataTag: "C 1.234E10") << QString("1.234E10") << true << 1.234e10;
5496 QTest::newRow(dataTag: "C 1e10") << QString("1e10") << true << 1.0e10;
5497
5498 // The bad...
5499
5500 QTest::newRow(dataTag: "C empty") << QString("") << false << 0.0;
5501 QTest::newRow(dataTag: "C null") << QString() << false << 0.0;
5502 QTest::newRow(dataTag: "C .") << QString(".") << false << 0.0;
5503 QTest::newRow(dataTag: "C 1e") << QString("1e") << false << 0.0;
5504 QTest::newRow(dataTag: "C 1,") << QString("1,") << false << 0.0;
5505 QTest::newRow(dataTag: "C 1,0") << QString("1,0") << false << 0.0;
5506 QTest::newRow(dataTag: "C 1,000") << QString("1,000") << false << 0.0;
5507 QTest::newRow(dataTag: "C 1e1.0") << QString("1e1.0") << false << 0.0;
5508 QTest::newRow(dataTag: "C 1e+") << QString("1e+") << false << 0.0;
5509 QTest::newRow(dataTag: "C 1e-") << QString("1e-") << false << 0.0;
5510 QTest::newRow(dataTag: "de_DE 1,0") << QString("1,0") << false << 0.0;
5511 QTest::newRow(dataTag: "de_DE 1,234") << QString("1,234") << false << 0.0;
5512 QTest::newRow(dataTag: "de_DE 1,234e-10") << QString("1,234e-10") << false << 0.0;
5513 QTest::newRow(dataTag: "de_DE 1,234E10") << QString("1,234E10") << false << 0.0;
5514
5515 // And the ugly...
5516
5517 QTest::newRow(dataTag: "C .1") << QString(".1") << true << 0.1;
5518 QTest::newRow(dataTag: "C -.1") << QString("-.1") << true << -0.1;
5519 QTest::newRow(dataTag: "C 1.") << QString("1.") << true << 1.0;
5520 QTest::newRow(dataTag: "C 1.E10") << QString("1.E10") << true << 1.0e10;
5521 QTest::newRow(dataTag: "C 1e+10") << QString("1e+10") << true << 1.0e+10;
5522 QTest::newRow(dataTag: "C 1") << QString(" 1") << true << 1.0;
5523 QTest::newRow(dataTag: "C 1 ") << QString("1 ") << true << 1.0;
5524
5525 // Let's try some Arabic
5526 const quint16 arabic_str[] = { 0x0660, 0x066B, 0x0661, 0x0662,
5527 0x0663, 0x0664, 0x0065, 0x0662,
5528 0x0000 }; // "0.1234e2"
5529 QTest::newRow(dataTag: "ar_SA") << QString::fromUtf16(arabic_str) << false << 0.0;
5530}
5531
5532void tst_QString::double_conversion()
5533{
5534#define MY_DOUBLE_EPSILON (2.22045e-16)
5535
5536 QFETCH(QString, num_str);
5537 QFETCH(bool, good);
5538 QFETCH(double, num);
5539
5540 bool ok;
5541 double d = num_str.toDouble(ok: &ok);
5542 QCOMPARE(ok, good);
5543
5544 if (ok) {
5545 double diff = d - num;
5546 if (diff < 0)
5547 diff = -diff;
5548 QVERIFY(diff <= MY_DOUBLE_EPSILON);
5549 }
5550}
5551
5552#ifndef Q_MOC_RUN
5553#include "double_data.h"
5554#endif
5555
5556void tst_QString::tortureSprintfDouble()
5557{
5558 const SprintfDoubleData *data = g_sprintf_double_data;
5559
5560 for (; data->fmt != 0; ++data) {
5561 double d;
5562 char *buff = (char *)&d;
5563# ifndef Q_BYTE_ORDER
5564# error "Q_BYTE_ORDER not defined"
5565# endif
5566
5567# if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
5568 for (uint i = 0; i < 8; ++i)
5569 buff[i] = data->bytes[i];
5570# else
5571 for (uint i = 0; i < 8; ++i)
5572 buff[7 - i] = data->bytes[i];
5573# endif
5574 const QString s = QString::asprintf(format: data->fmt, d);
5575#ifdef QT_NO_FPU // reduced precision when running with hardfloats in qemu
5576 if (d - 0.1 < 1e12)
5577 QSKIP("clib sprintf doesn't fill with 0's on this platform");
5578 QCOMPARE(s.left(16), QString(data->expected).left(16));
5579#else
5580 QCOMPARE(s, QString(data->expected));
5581#endif
5582 }
5583}
5584
5585#include <locale.h>
5586
5587void tst_QString::localeAwareCompare_data()
5588{
5589 QTest::addColumn<QString>(name: "locale");
5590 QTest::addColumn<QString>(name: "s1");
5591 QTest::addColumn<QString>(name: "s2");
5592 QTest::addColumn<int>(name: "result");
5593
5594 // Compare decomposed and composed form
5595 {
5596 // From ES6 test262 test suite (built-ins/String/prototype/localeCompare/15.5.4.9_CE.js). The test cases boil down to code like this:
5597 // console.log("\u1111\u1171\u11B6".localeCompare("\ud4db")
5598
5599 // example from Unicode 5.0, section 3.7, definition D70
5600 QTest::newRow(dataTag: "normalize1") << QString("en_US") << QString::fromUtf8(str: "o\xCC\x88") << QString::fromUtf8(str: "\xC3\xB6") << 0;
5601 // examples from Unicode 5.0, chapter 3.11
5602 QTest::newRow(dataTag: "normalize2") << QString("en_US") << QString::fromUtf8(str: "\xC3\xA4\xCC\xA3") << QString::fromUtf8(str: "a\xCC\xA3\xCC\x88") << 0;
5603 QTest::newRow(dataTag: "normalize3") << QString("en_US") << QString::fromUtf8(str: "a\xCC\x88\xCC\xA3") << QString::fromUtf8(str: "a\xCC\xA3\xCC\x88") << 0;
5604 QTest::newRow(dataTag: "normalize4") << QString("en_US") << QString::fromUtf8(str: "\xE1\xBA\xA1\xCC\x88") << QString::fromUtf8(str: "a\xCC\xA3\xCC\x88") << 0;
5605 QTest::newRow(dataTag: "normalize5") << QString("en_US") << QString::fromUtf8(str: "\xC3\xA4\xCC\x86") << QString::fromUtf8(str: "a\xCC\x88\xCC\x86") << 0;
5606 QTest::newRow(dataTag: "normalize6") << QString("en_US") << QString::fromUtf8(str: "\xC4\x83\xCC\x88") << QString::fromUtf8(str: "a\xCC\x86\xCC\x88") << 0;
5607 // example from Unicode 5.0, chapter 3.12
5608 QTest::newRow(dataTag: "normalize7") << QString("en_US") << QString::fromUtf8(str: "\xE1\x84\x91\xE1\x85\xB1\xE1\x86\xB6") << QString::fromUtf8(str: "\xED\x93\x9B") << 0;
5609 // examples from UTS 10, Unicode Collation Algorithm
5610 QTest::newRow(dataTag: "normalize8") << QString("en_US") << QString::fromUtf8(str: "\xE2\x84\xAB") << QString::fromUtf8(str: "\xC3\x85") << 0;
5611 QTest::newRow(dataTag: "normalize9") << QString("en_US") << QString::fromUtf8(str: "\xE2\x84\xAB") << QString::fromUtf8(str: "A\xCC\x8A") << 0;
5612 QTest::newRow(dataTag: "normalize10") << QString("en_US") << QString::fromUtf8(str: "x\xCC\x9B\xCC\xA3") << QString::fromUtf8(str: "x\xCC\xA3\xCC\x9B") << 0;
5613 QTest::newRow(dataTag: "normalize11") << QString("en_US") << QString::fromUtf8(str: "\xE1\xBB\xB1") << QString::fromUtf8(str: "\xE1\xBB\xA5\xCC\x9B") << 0;
5614 QTest::newRow(dataTag: "normalize12") << QString("en_US") << QString::fromUtf8(str: "\xE1\xBB\xB1") << QString::fromUtf8(str: "u\xCC\x9B\xCC\xA3") << 0;
5615 QTest::newRow(dataTag: "normalize13") << QString("en_US") << QString::fromUtf8(str: "\xE1\xBB\xB1") << QString::fromUtf8(str: "\xC6\xB0\xCC\xA3") << 0;
5616 QTest::newRow(dataTag: "normalize14") << QString("en_US") << QString::fromUtf8(str: "\xE1\xBB\xB1") << QString::fromUtf8(str: "u\xCC\xA3\xCC\x9B") << 0;
5617 // examples from UAX 15, Unicode Normalization Forms
5618 QTest::newRow(dataTag: "normalize15") << QString("en_US") << QString::fromUtf8(str: "\xC3\x87") << QString::fromUtf8(str: "C\xCC\xA7") << 0;
5619 QTest::newRow(dataTag: "normalize16") << QString("en_US") << QString::fromUtf8(str: "q\xCC\x87\xCC\xA3") << QString::fromUtf8(str: "q\xCC\xA3\xCC\x87") << 0;
5620 QTest::newRow(dataTag: "normalize17") << QString("en_US") << QString::fromUtf8(str: "\xEA\xB0\x80") << QString::fromUtf8(str: "\xE1\x84\x80\xE1\x85\xA1") << 0;
5621 QTest::newRow(dataTag: "normalize18") << QString("en_US") << QString::fromUtf8(str: "\xE2\x84\xAB") << QString::fromUtf8(str: "A\xCC\x8A") << 0;
5622 QTest::newRow(dataTag: "normalize19") << QString("en_US") << QString::fromUtf8(str: "\xE2\x84\xA6") << QString::fromUtf8(str: "\xCE\xA9") << 0;
5623 QTest::newRow(dataTag: "normalize20") << QString("en_US") << QString::fromUtf8(str: "\xC3\x85") << QString::fromUtf8(str: "A\xCC\x8A") << 0;
5624 QTest::newRow(dataTag: "normalize21") << QString("en_US") << QString::fromUtf8(str: "\xC3\xB4") << QString::fromUtf8(str: "o\xCC\x82") << 0;
5625 QTest::newRow(dataTag: "normalize22") << QString("en_US") << QString::fromUtf8(str: "\xE1\xB9\xA9") << QString::fromUtf8(str: "s\xCC\xA3\xCC\x87") << 0;
5626 QTest::newRow(dataTag: "normalize23") << QString("en_US") << QString::fromUtf8(str: "\xE1\xB8\x8B\xCC\xA3") << QString::fromUtf8(str: "d\xCC\xA3\xCC\x87") << 0;
5627 QTest::newRow(dataTag: "normalize24") << QString("en_US") << QString::fromUtf8(str: "\xE1\xB8\x8B\xCC\xA3") << QString::fromUtf8(str: "\xE1\xB8\x8D\xCC\x87") << 0;
5628 QTest::newRow(dataTag: "normalize25") << QString("en_US") << QString::fromUtf8(str: "q\xCC\x87\xCC\xA3") << QString::fromUtf8(str: "q\xCC\xA3\xCC\x87") << 0;
5629
5630 }
5631
5632#if !defined(Q_OS_WIN)
5633// On Q_OS_WIN, we cannot set the system or user locale
5634 /*
5635 The C locale performs pure byte comparisons for
5636 Latin-1-specific characters (I think). Compare with Swedish
5637 below.
5638 */
5639 QTest::newRow(dataTag: "c1") << QString("C") << QString::fromLatin1(str: "\xe5") << QString::fromLatin1(str: "\xe4") << 1;
5640 QTest::newRow(dataTag: "c2") << QString("C") << QString::fromLatin1(str: "\xe4") << QString::fromLatin1(str: "\xf6") << -1;
5641 QTest::newRow(dataTag: "c3") << QString("C") << QString::fromLatin1(str: "\xe5") << QString::fromLatin1(str: "\xf6") << -1;
5642
5643 /*
5644 It's hard to test English, because it's treated differently
5645 on different platforms. For example, on Linux, it uses the
5646 iso14651_t1 template file, which happens to provide good
5647 defaults for Swedish. OS X seems to do a pure bytewise
5648 comparison of Latin-1 values, although I'm not sure. So I
5649 just test digits to make sure that it's not totally broken.
5650 */
5651 QTest::newRow(dataTag: "english1") << QString("en_US") << QString("5") << QString("4") << 1;
5652 QTest::newRow(dataTag: "english2") << QString("en_US") << QString("4") << QString("6") << -1;
5653 QTest::newRow(dataTag: "english3") << QString("en_US") << QString("5") << QString("6") << -1;
5654 /*
5655 In Swedish, a with ring above (E5) comes before a with
5656 diaresis (E4), which comes before o diaresis (F6), which
5657 all come after z.
5658 */
5659#ifdef Q_OS_MAC
5660 QTest::newRow("swedish1") << QString("sv_SE.ISO8859-1") << QString::fromLatin1("\xe5") << QString::fromLatin1("\xe4") << -1;
5661 QTest::newRow("swedish2") << QString("sv_SE.ISO8859-1") << QString::fromLatin1("\xe4") << QString::fromLatin1("\xf6") << -1;
5662 QTest::newRow("swedish3") << QString("sv_SE.ISO8859-1") << QString::fromLatin1("\xe5") << QString::fromLatin1("\xf6") << -1;
5663 QTest::newRow("swedish4") << QString("sv_SE.ISO8859-1") << QString::fromLatin1("z") << QString::fromLatin1("\xe5") << -1;
5664#else
5665 QTest::newRow(dataTag: "swedish1") << QString("sv_SE") << QString::fromLatin1(str: "\xe5") << QString::fromLatin1(str: "\xe4") << -1;
5666 QTest::newRow(dataTag: "swedish2") << QString("sv_SE") << QString::fromLatin1(str: "\xe4") << QString::fromLatin1(str: "\xf6") << -1;
5667 QTest::newRow(dataTag: "swedish3") << QString("sv_SE") << QString::fromLatin1(str: "\xe5") << QString::fromLatin1(str: "\xf6") << -1;
5668 QTest::newRow(dataTag: "swedish4") << QString("sv_SE") << QString::fromLatin1(str: "z") << QString::fromLatin1(str: "\xe5") << -1;
5669#endif
5670
5671#if 0
5672 /*
5673 In Norwegian, ae (E6) comes before o with stroke (D8), which
5674 comes before a with ring above (E5).
5675 */
5676 QTest::newRow("norwegian1") << QString("no_NO") << QString::fromLatin1("\xe6") << QString::fromLatin1("\xd8") << -1;
5677 QTest::newRow("norwegian2") << QString("no_NO") << QString::fromLatin1("\xd8") << QString::fromLatin1("\xe5") << -1;
5678 QTest::newRow("norwegian3") << QString("no_NO") << QString::fromLatin1("\xe6") << QString::fromLatin1("\xe5") << -1;
5679#endif
5680
5681 /*
5682 In German, z comes *after* a with diaresis (E4),
5683 which comes before o diaresis (F6).
5684 */
5685#ifdef Q_OS_MAC
5686 QTest::newRow("german1") << QString("de_DE.ISO8859-1") << QString::fromLatin1("z") << QString::fromLatin1("\xe4") << 1;
5687 QTest::newRow("german2") << QString("de_DE.ISO8859-1") << QString::fromLatin1("\xe4") << QString::fromLatin1("\xf6") << -1;
5688 QTest::newRow("german3") << QString("de_DE.ISO8859-1") << QString::fromLatin1("z") << QString::fromLatin1("\xf6") << 1;
5689#else
5690 QTest::newRow(dataTag: "german1") << QString("de_DE") << QString::fromLatin1(str: "z") << QString::fromLatin1(str: "\xe4") << 1;
5691 QTest::newRow(dataTag: "german2") << QString("de_DE") << QString::fromLatin1(str: "\xe4") << QString::fromLatin1(str: "\xf6") << -1;
5692 QTest::newRow(dataTag: "german3") << QString("de_DE") << QString::fromLatin1(str: "z") << QString::fromLatin1(str: "\xf6") << 1;
5693#endif
5694#endif //!defined(Q_OS_WIN)
5695}
5696
5697void tst_QString::localeAwareCompare()
5698{
5699 QFETCH(QString, locale);
5700 QFETCH(QString, s1);
5701 QFETCH(QString, s2);
5702 QFETCH(int, result);
5703
5704 QStringRef r1(&s1, 0, s1.length());
5705 QStringRef r2(&s2, 0, s2.length());
5706
5707 if (!locale.isEmpty()) {
5708#if defined (Q_OS_DARWIN) || QT_CONFIG(icu)
5709 QSKIP("Setting the locale is not supported on OS X or ICU (you can set the C locale, but that won't affect localeAwareCompare)");
5710#else
5711 const char *newLocale = setlocale(LC_ALL, locale.toLatin1());
5712 if (!newLocale) {
5713 setlocale(LC_ALL, "");
5714 QSKIP("Please install the proper locale on this machine to test properly");
5715 }
5716#endif // Darwin || icu
5717 }
5718
5719#if QT_CONFIG(icu)
5720 // ### for c1, ICU disagrees with libc on how to compare
5721 QEXPECT_FAIL("c1", "ICU disagrees with test", Abort);
5722#endif
5723
5724 int testres = QString::localeAwareCompare(s1, s2);
5725 if (result < 0) {
5726 QVERIFY(testres < 0);
5727 } else if (result > 0) {
5728 QVERIFY(testres > 0);
5729 } else {
5730 QVERIFY(testres == 0);
5731 }
5732
5733 testres = QString::localeAwareCompare(s1: s2, s2: s1);
5734 if (result > 0) {
5735 QVERIFY(testres < 0);
5736 } else if (result < 0) {
5737 QVERIFY(testres > 0);
5738 } else {
5739 QVERIFY(testres == 0);
5740 }
5741
5742 testres = QString::localeAwareCompare(s1, s2: r2);
5743 if (result < 0) {
5744 QVERIFY(testres < 0);
5745 } else if (result > 0) {
5746 QVERIFY(testres > 0);
5747 } else {
5748 QVERIFY(testres == 0);
5749 }
5750
5751 testres = QStringRef::localeAwareCompare(s1: r1, s2: r2);
5752 if (result < 0) {
5753 QVERIFY(testres < 0);
5754 } else if (result > 0) {
5755 QVERIFY(testres > 0);
5756 } else {
5757 QVERIFY(testres == 0);
5758 }
5759
5760 testres = QStringRef::localeAwareCompare(s1: r2, s2: r1);
5761 if (result > 0) {
5762 QVERIFY(testres < 0);
5763 } else if (result < 0) {
5764 QVERIFY(testres > 0);
5765 } else {
5766 QVERIFY(testres == 0);
5767 }
5768
5769 if (!locale.isEmpty())
5770 setlocale(LC_ALL, locale: "");
5771}
5772
5773void tst_QString::reverseIterators()
5774{
5775 QString s = "1234";
5776 QString sr = s;
5777 std::reverse(first: sr.begin(), last: sr.end());
5778 const QString &csr = sr;
5779 QVERIFY(std::equal(s.begin(), s.end(), sr.rbegin()));
5780 QVERIFY(std::equal(s.begin(), s.end(), sr.crbegin()));
5781 QVERIFY(std::equal(s.begin(), s.end(), csr.rbegin()));
5782 QVERIFY(std::equal(sr.rbegin(), sr.rend(), s.begin()));
5783 QVERIFY(std::equal(sr.crbegin(), sr.crend(), s.begin()));
5784 QVERIFY(std::equal(csr.rbegin(), csr.rend(), s.begin()));
5785}
5786
5787void tst_QString::split_data()
5788{
5789 QTest::addColumn<QString>(name: "str");
5790 QTest::addColumn<QString>(name: "sep");
5791 QTest::addColumn<QStringList>(name: "result");
5792
5793 QTest::newRow(dataTag: "1") << "a,b,c" << "," << (QStringList() << "a" << "b" << "c");
5794 QTest::newRow(dataTag: "2") << QString("-rw-r--r-- 1 0 0 519240 Jul 9 2002 bigfile")
5795 << " "
5796 << (QStringList() << "-rw-r--r--" << "" << "1" << "0" << "" << "0" << ""
5797 << "519240" << "Jul" << "" << "9" << "" << "2002" << "bigfile");
5798 QTest::newRow(dataTag: "one-empty") << "" << " " << (QStringList() << "");
5799 QTest::newRow(dataTag: "two-empty") << " " << " " << (QStringList() << "" << "");
5800 QTest::newRow(dataTag: "three-empty") << " " << " " << (QStringList() << "" << "" << "");
5801
5802 QTest::newRow(dataTag: "all-empty") << "" << "" << (QStringList() << "" << "");
5803 QTest::newRow(dataTag: "sep-empty") << "abc" << "" << (QStringList() << "" << "a" << "b" << "c" << "");
5804}
5805
5806template<class> struct StringSplitWrapper;
5807template<> struct StringSplitWrapper<QString>
5808{
5809 const QString &string;
5810
5811 QStringList split(const QString &sep, QString::SplitBehavior behavior = QString::KeepEmptyParts, Qt::CaseSensitivity cs = Qt::CaseSensitive) const { return string.split(sep, behavior, cs); }
5812 QStringList split(QChar sep, QString::SplitBehavior behavior = QString::KeepEmptyParts, Qt::CaseSensitivity cs = Qt::CaseSensitive) const { return string.split(sep, behavior, cs); }
5813 QStringList split(const QRegExp &sep, QString::SplitBehavior behavior = QString::KeepEmptyParts) const { return string.split(sep, behavior); }
5814 QStringList split(const QRegularExpression &sep, QString::SplitBehavior behavior = QString::KeepEmptyParts) const { return string.split(sep, behavior); }
5815};
5816
5817template<> struct StringSplitWrapper<QStringRef>
5818{
5819 const QString &string;
5820 QVector<QStringRef> split(const QString &sep, QString::SplitBehavior behavior = QString::KeepEmptyParts, Qt::CaseSensitivity cs = Qt::CaseSensitive) const { return string.splitRef(sep, behavior, cs); }
5821 QVector<QStringRef> split(QChar sep, QString::SplitBehavior behavior = QString::KeepEmptyParts, Qt::CaseSensitivity cs = Qt::CaseSensitive) const { return string.splitRef(sep, behavior, cs); }
5822 QVector<QStringRef> split(const QRegExp &sep, QString::SplitBehavior behavior = QString::KeepEmptyParts) const { return string.splitRef(sep, behavior); }
5823 QVector<QStringRef> split(const QRegularExpression &sep, QString::SplitBehavior behavior = QString::KeepEmptyParts) const { return string.splitRef(sep, behavior); }
5824};
5825
5826static bool operator ==(const QStringList &left, const QVector<QStringRef> &right)
5827{
5828 if (left.size() != right.size())
5829 return false;
5830
5831 QStringList::const_iterator iLeft = left.constBegin();
5832 QVector<QStringRef>::const_iterator iRight = right.constBegin();
5833 for (; iLeft != left.end(); ++iLeft, ++iRight) {
5834 if (*iLeft != *iRight)
5835 return false;
5836 }
5837 return true;
5838}
5839static inline bool operator ==(const QVector<QStringRef> &left, const QStringList &right) { return right == left; }
5840
5841template<class List>
5842void tst_QString::split(const QString &string, const QString &sep, QStringList result)
5843{
5844 QRegExp rx = QRegExp(QRegExp::escape(str: sep));
5845 QRegularExpression re(QRegularExpression::escape(str: sep));
5846
5847 List list;
5848 StringSplitWrapper<typename List::value_type> str = {string};
5849
5850 list = str.split(sep);
5851 QVERIFY(list == result);
5852 list = str.split(rx);
5853 QVERIFY(list == result);
5854 list = str.split(re);
5855 QVERIFY(list == result);
5856 if (sep.size() == 1) {
5857 list = str.split(sep.at(i: 0));
5858 QVERIFY(list == result);
5859 }
5860
5861QT_WARNING_PUSH
5862QT_WARNING_DISABLE_DEPRECATED
5863 list = str.split(sep, QString::KeepEmptyParts);
5864 QVERIFY(list == result);
5865 list = str.split(rx, QString::KeepEmptyParts);
5866 QVERIFY(list == result);
5867 list = str.split(re, QString::KeepEmptyParts);
5868 QVERIFY(list == result);
5869 if (sep.size() == 1) {
5870 list = str.split(sep.at(i: 0), QString::KeepEmptyParts);
5871 QVERIFY(list == result);
5872 }
5873
5874 result.removeAll(t: "");
5875 list = str.split(sep, QString::SkipEmptyParts);
5876 QVERIFY(list == result);
5877 list = str.split(rx, QString::SkipEmptyParts);
5878 QVERIFY(list == result);
5879 list = str.split(re, QString::SkipEmptyParts);
5880 QVERIFY(list == result);
5881 if (sep.size() == 1) {
5882 list = str.split(sep.at(i: 0), QString::SkipEmptyParts);
5883 QVERIFY(list == result);
5884 }
5885QT_WARNING_POP
5886}
5887
5888void tst_QString::split()
5889{
5890 QFETCH(QString, str);
5891 QFETCH(QString, sep);
5892 QFETCH(QStringList, result);
5893 split<QStringList>(string: str, sep, result);
5894}
5895
5896void tst_QString::splitRef_data()
5897{
5898 split_data();
5899}
5900
5901void tst_QString::splitRef()
5902{
5903 QFETCH(QString, str);
5904 QFETCH(QString, sep);
5905 QFETCH(QStringList, result);
5906 split<QVector<QStringRef> >(string: str, sep, result);
5907}
5908
5909void tst_QString::split_regexp_data()
5910{
5911 QTest::addColumn<QString>(name: "string");
5912 QTest::addColumn<QString>(name: "pattern");
5913 QTest::addColumn<QStringList>(name: "result");
5914
5915 QTest::newRow(dataTag: "data01") << "Some text\n\twith strange whitespace."
5916 << "\\s+"
5917 << (QStringList() << "Some" << "text" << "with" << "strange" << "whitespace." );
5918
5919 QTest::newRow(dataTag: "data02") << "This time, a normal English sentence."
5920 << "\\W+"
5921 << (QStringList() << "This" << "time" << "a" << "normal" << "English" << "sentence" << "");
5922
5923 QTest::newRow(dataTag: "data03") << "Now: this sentence fragment."
5924 << "\\b"
5925 << (QStringList() << "" << "Now" << ": " << "this" << " " << "sentence" << " " << "fragment" << ".");
5926}
5927
5928template<class List, class RegExp>
5929void tst_QString::split_regexp(const QString &_string, const QString &pattern, QStringList result)
5930{
5931 List list;
5932 StringSplitWrapper<typename List::value_type> string = {_string};
5933
5934 list = string.split(RegExp(pattern));
5935 QVERIFY(list == result);
5936
5937 result.removeAll(t: QString());
5938
5939 list = string.split(RegExp(pattern), QString::SkipEmptyParts);
5940 QVERIFY(list == result);
5941}
5942
5943void tst_QString::split_regexp()
5944{
5945 QFETCH(QString, string);
5946 QFETCH(QString, pattern);
5947 QFETCH(QStringList, result);
5948 split_regexp<QStringList, QRegExp>(string: string, pattern, result);
5949}
5950
5951void tst_QString::split_regularexpression_data()
5952{
5953 split_regexp_data();
5954}
5955
5956void tst_QString::split_regularexpression()
5957{
5958 QFETCH(QString, string);
5959 QFETCH(QString, pattern);
5960 QFETCH(QStringList, result);
5961 split_regexp<QStringList, QRegularExpression>(string: string, pattern, result);
5962}
5963
5964void tst_QString::splitRef_regularexpression_data()
5965{
5966 split_regexp_data();
5967}
5968
5969void tst_QString::splitRef_regularexpression()
5970{
5971 QFETCH(QString, string);
5972 QFETCH(QString, pattern);
5973 QFETCH(QStringList, result);
5974 split_regexp<QVector<QStringRef>, QRegularExpression>(string: string, pattern, result);
5975}
5976
5977void tst_QString::splitRef_regexp_data()
5978{
5979 split_regexp_data();
5980}
5981
5982void tst_QString::splitRef_regexp()
5983{
5984 QFETCH(QString, string);
5985 QFETCH(QString, pattern);
5986 QFETCH(QStringList, result);
5987 split_regexp<QVector<QStringRef>, QRegExp>(string: string, pattern, result);
5988}
5989
5990void tst_QString::fromUtf16_data()
5991{
5992 QTest::addColumn<QString>(name: "ucs2");
5993 QTest::addColumn<QString>(name: "res");
5994 QTest::addColumn<int>(name: "len");
5995
5996 QTest::newRow(dataTag: "str0") << QString("abcdefgh") << QString("abcdefgh") << -1;
5997 QTest::newRow(dataTag: "str0-len") << QString("abcdefgh") << QString("abc") << 3;
5998}
5999
6000void tst_QString::fromUtf16()
6001{
6002 QFETCH(QString, ucs2);
6003 QFETCH(QString, res);
6004 QFETCH(int, len);
6005
6006 QCOMPARE(QString::fromUtf16(ucs2.utf16(), len), res);
6007}
6008
6009void tst_QString::fromUtf16_char16_data()
6010{
6011#ifdef Q_COMPILER_UNICODE_STRINGS
6012 fromUtf16_data();
6013#else
6014 QSKIP("Compiler does not support C++11 unicode strings");
6015#endif
6016}
6017
6018void tst_QString::fromUtf16_char16()
6019{
6020#ifdef Q_COMPILER_UNICODE_STRINGS
6021 QFETCH(QString, ucs2);
6022 QFETCH(QString, res);
6023 QFETCH(int, len);
6024
6025 QCOMPARE(QString::fromUtf16(reinterpret_cast<const char16_t *>(ucs2.utf16()), len), res);
6026#endif
6027}
6028
6029void tst_QString::unicodeStrings()
6030{
6031#ifdef Q_STDLIB_UNICODE_STRINGS
6032 QString s1, s2;
6033 static const std::u16string u16str1(u"Hello Unicode World");
6034 static const std::u32string u32str1(U"Hello Unicode World");
6035 s1 = QString::fromStdU16String(s: u16str1);
6036 s2 = QString::fromStdU32String(s: u32str1);
6037 QCOMPARE(s1, QString("Hello Unicode World"));
6038 QCOMPARE(s1, s2);
6039
6040 QCOMPARE(s2.toStdU16String(), u16str1);
6041 QCOMPARE(s1.toStdU32String(), u32str1);
6042
6043 s1 = QString::fromStdU32String(s: std::u32string(U"\u221212\U000020AC\U00010000"));
6044 QCOMPARE(s1, QString::fromUtf8("\342\210\222" "12" "\342\202\254" "\360\220\200\200"));
6045#else
6046 QSKIP("Standard Library does not support C++11 unicode strings");
6047#endif
6048}
6049
6050void tst_QString::latin1String()
6051{
6052 QString s("Hello");
6053
6054 QVERIFY(s == QLatin1String("Hello"));
6055 QVERIFY(s != QLatin1String("Hello World"));
6056 QVERIFY(s < QLatin1String("Helloa"));
6057 QVERIFY(!(s > QLatin1String("Helloa")));
6058 QVERIFY(s > QLatin1String("Helln"));
6059 QVERIFY(s > QLatin1String("Hell"));
6060 QVERIFY(!(s < QLatin1String("Helln")));
6061 QVERIFY(!(s < QLatin1String("Hell")));
6062}
6063
6064void tst_QString::nanAndInf()
6065{
6066 bool ok;
6067 double d;
6068
6069#define CHECK_DOUBLE(str, expected_ok, expected_inf) \
6070 d = QString(str).toDouble(&ok); \
6071 QVERIFY(ok == expected_ok); \
6072 QVERIFY(qIsInf(d) == expected_inf);
6073
6074 CHECK_DOUBLE("inf", true, true)
6075 CHECK_DOUBLE("INF", true, true)
6076 CHECK_DOUBLE("inf ", true, true)
6077 CHECK_DOUBLE("+inf", true, true)
6078 CHECK_DOUBLE("\t +INF", true, true)
6079 CHECK_DOUBLE("\t INF", true, true)
6080 CHECK_DOUBLE("inF ", true, true)
6081 CHECK_DOUBLE("+iNf", true, true)
6082 CHECK_DOUBLE("INFe-10", false, false)
6083 CHECK_DOUBLE("0xINF", false, false)
6084 CHECK_DOUBLE("- INF", false, false)
6085 CHECK_DOUBLE("+ INF", false, false)
6086 CHECK_DOUBLE("-- INF", false, false)
6087 CHECK_DOUBLE("inf0", false, false)
6088 CHECK_DOUBLE("--INF", false, false)
6089 CHECK_DOUBLE("++INF", false, false)
6090 CHECK_DOUBLE("INF++", false, false)
6091 CHECK_DOUBLE("INF--", false, false)
6092 CHECK_DOUBLE("INF +", false, false)
6093 CHECK_DOUBLE("INF -", false, false)
6094 CHECK_DOUBLE("0INF", false, false)
6095#undef CHECK_INF
6096
6097#define CHECK_NAN(str, expected_ok, expected_nan) \
6098 d = QString(str).toDouble(&ok); \
6099 QVERIFY(ok == expected_ok); \
6100 QVERIFY(qIsNaN(d) == expected_nan);
6101
6102 CHECK_NAN("nan", true, true)
6103 CHECK_NAN("NAN", true, true)
6104 CHECK_NAN("nan ", true, true)
6105 CHECK_NAN("\t NAN", true, true)
6106 CHECK_NAN("\t NAN ", true, true)
6107 CHECK_NAN("-nan", false, false)
6108 CHECK_NAN("+NAN", false, false)
6109 CHECK_NAN("NaN", true, true)
6110 CHECK_NAN("nAn", true, true)
6111 CHECK_NAN("NANe-10", false, false)
6112 CHECK_NAN("0xNAN", false, false)
6113 CHECK_NAN("0NAN", false, false)
6114#undef CHECK_NAN
6115
6116 d = QString("-INF").toDouble(ok: &ok);
6117 QVERIFY(ok);
6118 QVERIFY(d == -qInf());
6119
6120 QString("INF").toLong(ok: &ok);
6121 QVERIFY(!ok);
6122
6123 QString("INF").toLong(ok: &ok, base: 36);
6124 QVERIFY(ok);
6125
6126 QString("INF0").toLong(ok: &ok, base: 36);
6127 QVERIFY(ok);
6128
6129 QString("0INF0").toLong(ok: &ok, base: 36);
6130 QVERIFY(ok);
6131
6132 // Check that inf (float) => "inf" (QString) => inf (float).
6133 float value = qInf();
6134 QString valueAsString = QString::number(value);
6135 QCOMPARE(valueAsString, QString::fromLatin1("inf"));
6136 float valueFromString = valueAsString.toFloat();
6137 QVERIFY(qIsInf(valueFromString));
6138
6139 // Check that -inf (float) => "-inf" (QString) => -inf (float).
6140 value = -qInf();
6141 valueAsString = QString::number(value);
6142 QCOMPARE(valueAsString, QString::fromLatin1("-inf"));
6143 valueFromString = valueAsString.toFloat();
6144 QVERIFY(value == -qInf());
6145 QVERIFY(qIsInf(valueFromString));
6146}
6147
6148void tst_QString::arg_fillChar_data()
6149{
6150 QTest::addColumn<QString>(name: "pattern");
6151 QTest::addColumn<QList<QVariant> >(name: "replaceValues");
6152 QTest::addColumn<IntList>(name: "widths");
6153 QTest::addColumn<QString>(name: "fillChars");
6154 QTest::addColumn<QString>(name: "expected");
6155
6156 QList<QVariant> replaceValues;
6157 IntList widths;
6158 QString fillChars;
6159
6160 replaceValues << QVariant((int)5) << QVariant(QString("f")) << QVariant((int)0);
6161 widths << 3 << 2 << 5;
6162 QTest::newRow(dataTag: "str0") << QString("%1%2%3") << replaceValues << widths << QString("abc") << QString("aa5bfcccc0");
6163
6164 replaceValues.clear();
6165 widths.clear();
6166 replaceValues << QVariant((int)5.5) << QVariant(QString("foo")) << QVariant((qulonglong)INT_MAX);
6167 widths << 10 << 2 << 5;
6168 QTest::newRow(dataTag: "str1") << QString("%3.%1.%3.%2") << replaceValues << widths << QString("0 c")
6169 << QString("2147483647.0000000005.2147483647.foo");
6170
6171 replaceValues.clear();
6172 widths.clear();
6173 replaceValues << QVariant(QString("fisk"));
6174 widths << 100;
6175 QTest::newRow(dataTag: "str2") << QString("%9 og poteter") << replaceValues << widths << QString("f")
6176 << QString("fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffisk og poteter");
6177}
6178
6179void tst_QString::arg_fillChar()
6180{
6181 static const int base = 10;
6182 static const char fmt = 'g';
6183 static const int prec = -1;
6184
6185 QFETCH(QString, pattern);
6186 QFETCH(QList<QVariant>, replaceValues);
6187 QFETCH(IntList, widths);
6188 QFETCH(QString, fillChars);
6189 QFETCH(QString, expected);
6190 QCOMPARE(replaceValues.count(), fillChars.count());
6191 QCOMPARE(replaceValues.count(), widths.count());
6192
6193 QString actual = pattern;
6194 for (int i=0; i<replaceValues.count(); ++i) {
6195 const QVariant &var = replaceValues.at(i);
6196 const int width = widths.at(i);
6197 const QChar fillChar = fillChars.at(i);
6198 switch (var.type()) {
6199 case QVariant::String: actual = actual.arg(a: var.toString(), fieldWidth: width, fillChar); break;
6200 case QVariant::Int: actual = actual.arg(a: var.toInt(), fieldWidth: width, base, fillChar); break;
6201 case QVariant::UInt: actual = actual.arg(a: var.toUInt(), fieldWidth: width, base, fillChar); break;
6202 case QVariant::Double: actual = actual.arg(a: var.toDouble(), fieldWidth: width, fmt, prec, fillChar); break;
6203 case QVariant::LongLong: actual = actual.arg(a: var.toLongLong(), fieldwidth: width, base, fillChar); break;
6204 case QVariant::ULongLong: actual = actual.arg(a: var.toULongLong(), fieldwidth: width, base, fillChar); break;
6205 default: QVERIFY(0); break;
6206 }
6207 }
6208
6209 QCOMPARE(actual, expected);
6210}
6211
6212static inline int sign(int x)
6213{
6214 return x == 0 ? 0 : (x < 0 ? -1 : 1);
6215}
6216
6217void tst_QString::compare_data()
6218{
6219 QTest::addColumn<QString>(name: "s1");
6220 QTest::addColumn<QString>(name: "s2");
6221 QTest::addColumn<int>(name: "csr"); // case sensitive result
6222 QTest::addColumn<int>(name: "cir"); // case insensitive result
6223
6224 // null strings
6225 QTest::newRow(dataTag: "null-null") << QString() << QString() << 0 << 0;
6226 QTest::newRow(dataTag: "text-null") << QString("a") << QString() << 1 << 1;
6227 QTest::newRow(dataTag: "null-text") << QString() << QString("a") << -1 << -1;
6228 QTest::newRow(dataTag: "null-empty") << QString() << QString("") << 0 << 0;
6229 QTest::newRow(dataTag: "empty-null") << QString("") << QString() << 0 << 0;
6230
6231 // empty strings
6232 QTest::newRow(dataTag: "data0") << QString("") << QString("") << 0 << 0;
6233 QTest::newRow(dataTag: "data1") << QString("a") << QString("") << 1 << 1;
6234 QTest::newRow(dataTag: "data2") << QString("") << QString("a") << -1 << -1;
6235
6236 // equal length
6237 QTest::newRow(dataTag: "data3") << QString("abc") << QString("abc") << 0 << 0;
6238 QTest::newRow(dataTag: "data4") << QString("abC") << QString("abc") << -1 << 0;
6239 QTest::newRow(dataTag: "data5") << QString("abc") << QString("abC") << 1 << 0;
6240
6241 // different length
6242 QTest::newRow(dataTag: "data6") << QString("abcdef") << QString("abc") << 1 << 1;
6243 QTest::newRow(dataTag: "data7") << QString("abCdef") << QString("abc") << -1 << 1;
6244 QTest::newRow(dataTag: "data8") << QString("abc") << QString("abcdef") << -1 << -1;
6245
6246 QString upper;
6247 upper += QChar(QChar::highSurrogate(ucs4: 0x10400));
6248 upper += QChar(QChar::lowSurrogate(ucs4: 0x10400));
6249 QString lower;
6250 lower += QChar(QChar::highSurrogate(ucs4: 0x10428));
6251 lower += QChar(QChar::lowSurrogate(ucs4: 0x10428));
6252 QTest::newRow(dataTag: "data8") << upper << lower << -1 << 0;
6253
6254 // embedded nulls
6255 // These don't work as of now. It's OK that these don't work since \0 is not a valid unicode
6256 /*QTest::newRow("data10") << QString(QByteArray("\0", 1)) << QString(QByteArray("\0", 1)) << 0 << 0;
6257 QTest::newRow("data11") << QString(QByteArray("\0", 1)) << QString("") << 1 << 1;
6258 QTest::newRow("data12") << QString("") << QString(QByteArray("\0", 1)) << -1 << -1;
6259 QTest::newRow("data13") << QString("ab\0c") << QString(QByteArray("ab\0c", 4)) << 0 << 0;
6260 QTest::newRow("data14") << QString(QByteArray("ab\0c", 4)) << QString("abc") << -1 << -1;
6261 QTest::newRow("data15") << QString("abc") << QString(QByteArray("ab\0c", 4)) << 1 << 1;*/
6262
6263 // All tests below (generated by the 3 for-loops) are meant to excercise the vectorized versions
6264 // of ucstrncmp.
6265
6266 QString in1, in2;
6267 for (int i = 0; i < 70; ++i) {
6268 in1 += QString::number(i % 10);
6269 in2 += QString::number((70 - i + 1) % 10);
6270 }
6271 Q_ASSERT(in1.length() == in2.length());
6272 Q_ASSERT(in1 != in2);
6273 Q_ASSERT(in1.at(0) < in2.at(0));
6274 for (int i = 0; i < in1.length(); ++i) {
6275 Q_ASSERT(in1.at(i) != in2.at(i));
6276 }
6277
6278 for (int i = 1; i <= 65; ++i) {
6279 QString inp1 = in1.left(n: i);
6280 QString inp2 = in2.left(n: i);
6281 QTest::addRow(format: "all-different-%d", i) << inp1 << inp2 << -1 << -1;
6282 }
6283
6284 for (int i = 1; i <= 65; ++i) {
6285 QString start(i - 1, 'a');
6286
6287 QString in = start + QLatin1Char('a');
6288 QTest::addRow(format: "all-same-%d", i) << in << in << 0 << 0;
6289
6290 QString in2 = start + QLatin1Char('b');
6291 QTest::addRow(format: "last-different-%d", i) << in << in2 << -1 << -1;
6292 }
6293
6294 for (int i = 0; i < 16; ++i) {
6295 QString in1(16, 'a');
6296 QString in2 = in1;
6297 in2[i] = 'b';
6298 QTest::addRow(format: "all-same-except-char-%d", i) << in1 << in2 << -1 << -1;
6299 }
6300}
6301
6302static bool isLatin(const QString &s)
6303{
6304 for (int i = 0; i < s.length(); ++i)
6305 if (s.at(i).unicode() > 0xff)
6306 return false;
6307 return true;
6308}
6309
6310void tst_QString::compare()
6311{
6312 QFETCH(QString, s1);
6313 QFETCH(QString, s2);
6314 QFETCH(int, csr);
6315 QFETCH(int, cir);
6316
6317 QStringRef r1(&s1, 0, s1.length());
6318 QStringRef r2(&s2, 0, s2.length());
6319
6320 const QStringView v2(s2);
6321
6322 QCOMPARE(sign(QString::compare(s1, s2)), csr);
6323 QCOMPARE(sign(QStringRef::compare(r1, r2)), csr);
6324 QCOMPARE(sign(s1.compare(s2)), csr);
6325 QCOMPARE(sign(s1.compare(r2)), csr);
6326 QCOMPARE(sign(r1.compare(r2)), csr);
6327 QCOMPARE(sign(s1.compare(v2)), csr);
6328
6329 QCOMPARE(sign(s1.compare(s2, Qt::CaseSensitive)), csr);
6330 QCOMPARE(sign(s1.compare(s2, Qt::CaseInsensitive)), cir);
6331 QCOMPARE(sign(s1.compare(r2, Qt::CaseSensitive)), csr);
6332 QCOMPARE(sign(s1.compare(r2, Qt::CaseInsensitive)), cir);
6333 QCOMPARE(sign(r1.compare(r2, Qt::CaseSensitive)), csr);
6334 QCOMPARE(sign(r1.compare(r2, Qt::CaseInsensitive)), cir);
6335 QCOMPARE(sign(s1.compare(v2, Qt::CaseSensitive)), csr);
6336 QCOMPARE(sign(s1.compare(v2, Qt::CaseInsensitive)), cir);
6337
6338 QCOMPARE(sign(QString::compare(s1, s2, Qt::CaseSensitive)), csr);
6339 QCOMPARE(sign(QString::compare(s1, s2, Qt::CaseInsensitive)), cir);
6340 QCOMPARE(sign(QString::compare(s1, r2, Qt::CaseSensitive)), csr);
6341 QCOMPARE(sign(QString::compare(s1, r2, Qt::CaseInsensitive)), cir);
6342 QCOMPARE(sign(QStringRef::compare(r1, r2, Qt::CaseSensitive)), csr);
6343 QCOMPARE(sign(QStringRef::compare(r1, r2, Qt::CaseInsensitive)), cir);
6344
6345 if (csr == 0) {
6346 QVERIFY(qHash(s1) == qHash(s2));
6347 QVERIFY(qHash(s1) == qHash(r2));
6348 QVERIFY(qHash(r1) == qHash(s2));
6349 QVERIFY(qHash(r1) == qHash(r2));
6350 }
6351
6352 if (!cir) {
6353 QCOMPARE(s1.toCaseFolded(), s2.toCaseFolded());
6354 }
6355
6356 if (isLatin(s: s2)) {
6357 QCOMPARE(sign(QString::compare(s1, QLatin1String(s2.toLatin1()))), csr);
6358 QCOMPARE(sign(QString::compare(s1, QLatin1String(s2.toLatin1()), Qt::CaseInsensitive)), cir);
6359 QCOMPARE(sign(QStringRef::compare(r1, QLatin1String(s2.toLatin1()))), csr);
6360 QCOMPARE(sign(QStringRef::compare(r1, QLatin1String(s2.toLatin1()), Qt::CaseInsensitive)), cir);
6361 QByteArray l1 = s2.toLatin1();
6362 l1 += "x";
6363 QLatin1String l1str(l1.constData(), l1.size() - 1);
6364 QCOMPARE(sign(QString::compare(s1, l1str)), csr);
6365 QCOMPARE(sign(QString::compare(s1, l1str, Qt::CaseInsensitive)), cir);
6366 QCOMPARE(sign(QStringRef::compare(r1, l1str)), csr);
6367 QCOMPARE(sign(QStringRef::compare(r1, l1str, Qt::CaseInsensitive)), cir);
6368 }
6369
6370 if (isLatin(s: s1)) {
6371 QCOMPARE(sign(QString::compare(QLatin1String(s1.toLatin1()), s2)), csr);
6372 QCOMPARE(sign(QString::compare(QLatin1String(s1.toLatin1()), s2, Qt::CaseInsensitive)), cir);
6373 }
6374}
6375
6376void tst_QString::resize()
6377{
6378 QString s = QLatin1String("hello world");
6379
6380 s.resize(size: 5);
6381 QCOMPARE(s, QLatin1String("hello"));
6382 s.resize(size: 8);
6383 QCOMPARE(s.size(), 8);
6384 QVERIFY(s.startsWith(QLatin1String("hello")));
6385
6386 s.resize(size: 10, fillChar: QLatin1Char('n'));
6387 QCOMPARE(s.size(), 10);
6388 QVERIFY(s.startsWith(QLatin1String("hello")));
6389 QCOMPARE(s.right(2), QLatin1String("nn"));
6390}
6391
6392void tst_QString::resizeAfterFromRawData()
6393{
6394 QString buffer("hello world");
6395
6396 QString array = QString::fromRawData(buffer.constData(), size: buffer.size());
6397 QVERIFY(array.constData() == buffer.constData());
6398 array.resize(size: 5);
6399 QVERIFY(array.constData() == buffer.constData());
6400}
6401
6402void tst_QString::resizeAfterReserve()
6403{
6404
6405 QString s;
6406 s.reserve(asize: 100);
6407
6408 s += "hello world";
6409
6410 // resize should not affect capacity
6411 s.resize(size: s.size());
6412 QVERIFY(s.capacity() == 100);
6413
6414 // but squeeze does
6415 s.squeeze();
6416 QVERIFY(s.capacity() == s.size());
6417
6418 // clear does too
6419 s.clear();
6420 QVERIFY(s.capacity() == 0);
6421
6422 // test resize(0) border case
6423 s.reserve(asize: 100);
6424 s += "hello world";
6425 s.resize(size: 0);
6426 QVERIFY(s.capacity() == 100);
6427
6428 // reserve() can't be used to truncate data
6429 s.fill(c: 'x', size: 100);
6430 s.reserve(asize: 50);
6431 QVERIFY(s.capacity() == 100);
6432 QVERIFY(s.size() == 100);
6433
6434 // even with increased ref count truncation isn't allowed
6435 QString t = s;
6436 s.reserve(asize: 50);
6437 QVERIFY(s.capacity() == 100);
6438 QVERIFY(s.size() == 100);
6439}
6440
6441void tst_QString::resizeWithNegative() const
6442{
6443 {
6444 QString string(QLatin1String("input"));
6445 string.resize(size: -1);
6446 QCOMPARE(string, QString());
6447 }
6448
6449 {
6450 QString string(QLatin1String("input"));
6451 string.resize(size: -9099);
6452 QCOMPARE(string, QString());
6453 }
6454
6455 {
6456 /* Example code from customer. */
6457 QString s(QLatin1String("hola"));
6458 s.reserve(asize: 1);
6459 s.resize(size: -1);
6460 QCOMPARE(s, QString());
6461 }
6462}
6463
6464void tst_QString::truncateWithNegative() const
6465{
6466 {
6467 QString string(QLatin1String("input"));
6468 string.truncate(pos: -1);
6469 QCOMPARE(string, QString());
6470 }
6471
6472 {
6473 QString string(QLatin1String("input"));
6474 string.truncate(pos: -9099);
6475 QCOMPARE(string, QString());
6476 }
6477
6478 {
6479 /* Example code from customer. */
6480 QString test(QLatin1String("c"));
6481
6482 test.replace(rx: QRegExp(QLatin1String("c")), after: QLatin1String("z"));
6483 test.truncate(pos: -1);
6484 QCOMPARE(test, QString());
6485 }
6486}
6487
6488void tst_QString::QCharRefMutableUnicode() const
6489{
6490 QString str;
6491 str.resize(size: 3);
6492 str[0].unicode() = 115;
6493 str[1].unicode() = 116;
6494 str[2].unicode() = 114;
6495
6496 QCOMPARE(str, QString::fromLatin1("str"));
6497}
6498
6499void tst_QString::QCharRefDetaching() const
6500{
6501 {
6502 QString str = QString::fromLatin1(str: "str");
6503 QString copy;
6504 copy[0] = QLatin1Char('S');
6505
6506 QCOMPARE(str, QString::fromLatin1("str"));
6507 }
6508
6509 {
6510 ushort buf[] = { 's', 't', 'r' };
6511 QString str = QString::fromRawData((const QChar *)buf, size: 3);
6512 str[0] = QLatin1Char('S');
6513
6514 QCOMPARE(buf[0], ushort('s'));
6515 }
6516
6517 {
6518 static const ushort buf[] = { 's', 't', 'r' };
6519 QString str = QString::fromRawData((const QChar *)buf, size: 3);
6520
6521 // this causes a crash in most systems if the detaching doesn't work
6522 str[0] = QLatin1Char('S');
6523
6524 QCOMPARE(buf[0], ushort('s'));
6525 }
6526}
6527
6528void tst_QString::sprintfZU() const
6529{
6530 {
6531 size_t s = 6;
6532 QCOMPARE(QString::asprintf("%zu", s), QString::fromLatin1("6"));
6533 }
6534
6535 {
6536 QCOMPARE(QString::asprintf("%s\n", "foo"), QString::fromLatin1("foo\n"));
6537 }
6538
6539 {
6540 /* This code crashed. I don't know how to reduce it further. In other words,
6541 * both %zu and %s needs to be present. */
6542 size_t s = 6;
6543 QCOMPARE(QString::asprintf("%zu%s", s, "foo"), QString::fromLatin1("6foo"));
6544 }
6545
6546 {
6547 size_t s = 6;
6548 QCOMPARE(QString::asprintf("%zu %s\n", s, "foo"), QString::fromLatin1("6 foo\n"));
6549 }
6550}
6551
6552void tst_QString::repeatedSignature() const
6553{
6554 /* repated() should be a const member. */
6555 const QString string;
6556 (void) string.repeated(times: 3);
6557}
6558
6559void tst_QString::repeated() const
6560{
6561 QFETCH(QString, string);
6562 QFETCH(QString, expected);
6563 QFETCH(int, count);
6564
6565 QCOMPARE(string.repeated(count), expected);
6566}
6567
6568void tst_QString::repeated_data() const
6569{
6570 QTest::addColumn<QString>(name: "string" );
6571 QTest::addColumn<QString>(name: "expected" );
6572 QTest::addColumn<int>(name: "count" );
6573
6574 /* Empty strings. */
6575 QTest::newRow(dataTag: "data1")
6576 << QString()
6577 << QString()
6578 << 0;
6579
6580 QTest::newRow(dataTag: "data2")
6581 << QString()
6582 << QString()
6583 << -1004;
6584
6585 QTest::newRow(dataTag: "data3")
6586 << QString()
6587 << QString()
6588 << 1;
6589
6590 QTest::newRow(dataTag: "data4")
6591 << QString()
6592 << QString()
6593 << 5;
6594
6595 /* On simple string. */
6596 QTest::newRow(dataTag: "data5")
6597 << QString(QLatin1String("abc"))
6598 << QString()
6599 << -1004;
6600
6601 QTest::newRow(dataTag: "data6")
6602 << QString(QLatin1String("abc"))
6603 << QString()
6604 << -1;
6605
6606 QTest::newRow(dataTag: "data7")
6607 << QString(QLatin1String("abc"))
6608 << QString()
6609 << 0;
6610
6611 QTest::newRow(dataTag: "data8")
6612 << QString(QLatin1String("abc"))
6613 << QString(QLatin1String("abc"))
6614 << 1;
6615
6616 QTest::newRow(dataTag: "data9")
6617 << QString(QLatin1String("abc"))
6618 << QString(QLatin1String("abcabc"))
6619 << 2;
6620
6621 QTest::newRow(dataTag: "data10")
6622 << QString(QLatin1String("abc"))
6623 << QString(QLatin1String("abcabcabc"))
6624 << 3;
6625
6626 QTest::newRow(dataTag: "data11")
6627 << QString(QLatin1String("abc"))
6628 << QString(QLatin1String("abcabcabcabc"))
6629 << 4;
6630}
6631
6632void tst_QString::compareRef()
6633{
6634 QString a = "ABCDEFGH";
6635
6636 QCOMPARE(QStringRef(&a, 1, 2).compare(QLatin1String("BC")), 0);
6637 QVERIFY(QStringRef(&a, 1, 2).compare(QLatin1String("BCD")) < 0);
6638 QCOMPARE(QStringRef(&a, 1, 2).compare(QLatin1String("Bc"), Qt::CaseInsensitive), 0);
6639 QVERIFY(QStringRef(&a, 1, 2).compare(QLatin1String("bCD"), Qt::CaseInsensitive) < 0);
6640
6641 QCOMPARE(QStringRef(&a, 1, 2).compare(QString::fromLatin1("BC")), 0);
6642 QVERIFY(QStringRef(&a, 1, 2).compare(QString::fromLatin1("BCD")) < 0);
6643 QCOMPARE(QStringRef(&a, 1, 2).compare(QString::fromLatin1("Bc"), Qt::CaseInsensitive), 0);
6644 QVERIFY(QStringRef(&a, 1, 2).compare(QString::fromLatin1("bCD"), Qt::CaseInsensitive) < 0);
6645
6646 QCOMPARE(QString::fromLatin1("BC").compare(QStringRef(&a, 1, 2)), 0);
6647 QVERIFY(QString::fromLatin1("BCD").compare(QStringRef(&a, 1, 2)) > 0);
6648 QCOMPARE(QString::fromLatin1("Bc").compare(QStringRef(&a, 1, 2), Qt::CaseInsensitive), 0);
6649 QVERIFY(QString::fromLatin1("bCD").compare(QStringRef(&a, 1, 2), Qt::CaseInsensitive) > 0);
6650
6651 QCOMPARE(QStringRef(&a, 1, 2).compare(QStringRef(&a, 1, 2)), 0);
6652 QVERIFY(QStringRef(&a, 1, 2).compare(QStringRef(&a, 1, 3)) < 0);
6653 QCOMPARE(QStringRef(&a, 1, 2).compare(QStringRef(&a, 1, 2), Qt::CaseInsensitive), 0);
6654 QVERIFY(QStringRef(&a, 1, 2).compare(QStringRef(&a, 1, 3), Qt::CaseInsensitive) < 0);
6655
6656 QString a2 = "ABCDEFGh";
6657 QCOMPARE(QStringRef(&a2, 1, 2).compare(QStringRef(&a, 1, 2)), 0);
6658 QVERIFY(QStringRef(&a2, 1, 2).compare(QStringRef(&a, 1, 3)) < 0);
6659 QCOMPARE(QStringRef(&a2, 1, 2).compare(QStringRef(&a, 1, 2), Qt::CaseInsensitive), 0);
6660 QVERIFY(QStringRef(&a2, 1, 2).compare(QStringRef(&a, 1, 3), Qt::CaseInsensitive) < 0);
6661}
6662
6663void tst_QString::arg_locale()
6664{
6665 QLocale l(QLocale::English, QLocale::UnitedKingdom);
6666 QString str("*%L1*%L2*");
6667
6668 TransientDefaultLocale transient(l);
6669 QCOMPARE(str.arg(123456).arg(1234.56), QString::fromLatin1("*123,456*1,234.56*"));
6670
6671 l.setNumberOptions(QLocale::OmitGroupSeparator);
6672 transient.revise(transient: l);
6673 QCOMPARE(str.arg(123456).arg(1234.56), QString::fromLatin1("*123456*1234.56*"));
6674
6675 transient.revise(transient: QLocale::C);
6676 QCOMPARE(str.arg(123456).arg(1234.56), QString::fromLatin1("*123456*1234.56*"));
6677}
6678
6679
6680#if QT_CONFIG(icu)
6681// Qt has to be built with ICU support
6682void tst_QString::toUpperLower_icu()
6683{
6684 QString s = QString::fromLatin1(str: "i");
6685
6686 QCOMPARE(s.toUpper(), QString::fromLatin1("I"));
6687 QCOMPARE(s.toLower(), QString::fromLatin1("i"));
6688
6689 TransientDefaultLocale transient(QLocale(QLocale::Turkish, QLocale::Turkey));
6690
6691 QCOMPARE(s.toUpper(), QString::fromLatin1("I"));
6692 QCOMPARE(s.toLower(), QString::fromLatin1("i"));
6693
6694 // turkish locale has a capital I with a dot (U+0130, utf8 c4b0)
6695 QLocale l;
6696
6697 QCOMPARE(l.toUpper(s), QString::fromUtf8("\xc4\xb0"));
6698 QCOMPARE(l.toLower(QString::fromUtf8("\xc4\xb0")), s);
6699
6700 // nothing should happen here
6701 QCOMPARE(l.toLower(s), s);
6702 QCOMPARE(l.toUpper(QString::fromLatin1("I")), QString::fromLatin1("I"));
6703
6704 // U+0131, utf8 c4b1 is the lower-case i without a dot
6705 QString sup = QString::fromUtf8(str: "\xc4\xb1");
6706
6707 QCOMPARE(l.toUpper(sup), QString::fromLatin1("I"));
6708 QCOMPARE(l.toLower(QString::fromLatin1("I")), sup);
6709
6710 // nothing should happen here
6711 QCOMPARE(l.toLower(sup), sup);
6712 QCOMPARE(l.toLower(QString::fromLatin1("i")), QString::fromLatin1("i"));
6713}
6714#endif // icu
6715
6716#if !defined(QT_NO_UNICODE_LITERAL)
6717// Only tested on c++0x compliant compiler or gcc
6718void tst_QString::literals()
6719{
6720 QString str(QStringLiteral("abcd"));
6721
6722 QVERIFY(str.length() == 4);
6723 QVERIFY(str == QLatin1String("abcd"));
6724 QVERIFY(str.data_ptr()->ref.isStatic());
6725 QVERIFY(str.data_ptr()->offset == sizeof(QStringData));
6726
6727 const QChar *s = str.constData();
6728 QString str2 = str;
6729 QVERIFY(str2.constData() == s);
6730
6731 // detach on non const access
6732 QVERIFY(str.data() != s);
6733
6734 QVERIFY(str2.constData() == s);
6735 QVERIFY(str2.data() != s);
6736}
6737#endif
6738
6739void tst_QString::eightBitLiterals_data()
6740{
6741 QTest::addColumn<QByteArray>(name: "data");
6742 QTest::addColumn<QString>(name: "stringData");
6743
6744 QTest::newRow(dataTag: "null") << QByteArray() << QString();
6745 QTest::newRow(dataTag: "empty") << QByteArray("") << QString("");
6746 QTest::newRow(dataTag: "regular") << QByteArray("foo") << "foo";
6747 QTest::newRow(dataTag: "non-ascii") << QByteArray("\xc3\xa9") << QString::fromLatin1(str: "\xe9");
6748}
6749
6750void tst_QString::eightBitLiterals()
6751{
6752 QFETCH(QByteArray, data);
6753 QFETCH(QString, stringData);
6754
6755 {
6756 QString s(data);
6757 QCOMPARE(s, stringData);
6758 }
6759 {
6760 QString s(data.constData());
6761 QCOMPARE(s, stringData);
6762 }
6763 {
6764 QString s;
6765 s = data;
6766 QCOMPARE(s, stringData);
6767 }
6768 {
6769 QString s;
6770 s = data.constData();
6771 QCOMPARE(s, stringData);
6772 }
6773 {
6774 QString s;
6775 s.append(s: data);
6776 QCOMPARE(s, stringData);
6777 }
6778 {
6779 QString s;
6780 s.append(s: data.constData());
6781 QCOMPARE(s, stringData);
6782 }
6783 {
6784 QString s;
6785 s += data;
6786 QCOMPARE(s, stringData);
6787 }
6788 {
6789 QString s;
6790 s += data.constData();
6791 QCOMPARE(s, stringData);
6792 }
6793 {
6794 QString s;
6795 s.prepend(s: data);
6796 QCOMPARE(s, stringData);
6797 }
6798 {
6799 QString s;
6800 s.prepend(s: data.constData());
6801 QCOMPARE(s, stringData);
6802 }
6803 {
6804 QString s = QString() + data;
6805 QCOMPARE(s, stringData);
6806 }
6807 {
6808 QString s = QString() + data.constData();
6809 QCOMPARE(s, stringData);
6810 }
6811 {
6812 QString s = data + QString();
6813 QCOMPARE(s, stringData);
6814 }
6815 {
6816 QString s = QString() % data;
6817 QCOMPARE(s, stringData);
6818 }
6819 {
6820 QString s = QString() % data.constData();
6821 QCOMPARE(s, stringData);
6822 }
6823 {
6824 QString s = data % QString();
6825 QCOMPARE(s, stringData);
6826 }
6827
6828 {
6829 QVERIFY(stringData == data);
6830 QVERIFY(stringData == data.constData());
6831 QVERIFY(!(stringData != data));
6832 QVERIFY(!(stringData != data.constData()));
6833 QVERIFY(!(stringData < data));
6834 QVERIFY(!(stringData < data.constData()));
6835 QVERIFY(!(stringData > data));
6836 QVERIFY(!(stringData > data.constData()));
6837 QVERIFY(stringData <= data);
6838 QVERIFY(stringData <= data.constData());
6839 QVERIFY(stringData >= data);
6840 QVERIFY(stringData >= data.constData());
6841 }
6842}
6843
6844void tst_QString::reserve()
6845{
6846 QString nil1, nil2;
6847 nil1.reserve(asize: 0);
6848 nil2.squeeze();
6849 nil1.squeeze();
6850 nil2.reserve(asize: 0);
6851}
6852
6853void tst_QString::toHtmlEscaped_data()
6854{
6855 QTest::addColumn<QString>(name: "original");
6856 QTest::addColumn<QString>(name: "expected");
6857
6858 QTest::newRow(dataTag: "1") << "Hello World\n" << "Hello World\n";
6859 QTest::newRow(dataTag: "2") << "#include <QtCore>" << "#include &lt;QtCore&gt;";
6860 QTest::newRow(dataTag: "3") << "<p class=\"cool\"><a href=\"http://example.com/?foo=bar&amp;bar=foo\">plop --&gt; </a></p>"
6861 << "&lt;p class=&quot;cool&quot;&gt;&lt;a href=&quot;http://example.com/?foo=bar&amp;amp;bar=foo&quot;&gt;plop --&amp;gt; &lt;/a&gt;&lt;/p&gt;";
6862 QTest::newRow(dataTag: "4") << QString::fromUtf8(str: "<\320\222\321\201>") << QString::fromUtf8(str: "&lt;\320\222\321\201&gt;");
6863}
6864
6865void tst_QString::toHtmlEscaped()
6866{
6867 QFETCH(QString, original);
6868 QFETCH(QString, expected);
6869
6870 QCOMPARE(original.toHtmlEscaped(), expected);
6871}
6872
6873void tst_QString::operatorGreaterWithQLatin1String()
6874{
6875 QLatin1String latin1foo("fooZZ", 3);
6876 QString stringfoo = QString::fromLatin1(str: "foo");
6877 QVERIFY(stringfoo >= latin1foo);
6878 QVERIFY(!(stringfoo > latin1foo));
6879 QVERIFY(stringfoo <= latin1foo);
6880 QVERIFY(!(stringfoo < latin1foo));
6881}
6882
6883void tst_QString::compareQLatin1Strings()
6884{
6885 QLatin1String abc("abc");
6886 QLatin1String abcd("abcd");
6887 QLatin1String cba("cba");
6888 QLatin1String de("de");
6889
6890 QVERIFY(abc == abc);
6891 QVERIFY(!(abc == cba));
6892 QVERIFY(!(cba == abc));
6893 QVERIFY(!(abc == abcd));
6894 QVERIFY(!(abcd == abc));
6895
6896 QVERIFY(abc != cba);
6897 QVERIFY(!(abc != abc));
6898 QVERIFY(cba != abc);
6899 QVERIFY(abc != abcd);
6900 QVERIFY(abcd != abc);
6901
6902 QVERIFY(abc < abcd);
6903 QVERIFY(abc < cba);
6904 QVERIFY(abc < de);
6905 QVERIFY(abcd < cba);
6906 QVERIFY(!(abc < abc));
6907 QVERIFY(!(abcd < abc));
6908 QVERIFY(!(de < cba));
6909
6910 QVERIFY(abcd > abc);
6911 QVERIFY(cba > abc);
6912 QVERIFY(de > abc);
6913 QVERIFY(!(abc > abc));
6914 QVERIFY(!(abc > abcd));
6915 QVERIFY(!(abcd > cba));
6916
6917 QVERIFY(abc <= abc);
6918 QVERIFY(abc <= abcd);
6919 QVERIFY(abc <= cba);
6920 QVERIFY(abc <= de);
6921 QVERIFY(!(abcd <= abc));
6922 QVERIFY(!(cba <= abc));
6923 QVERIFY(!(cba <= abcd));
6924 QVERIFY(!(de <= abc));
6925
6926 QVERIFY(abc >= abc);
6927 QVERIFY(abcd >= abc);
6928 QVERIFY(!(abc >= abcd));
6929 QVERIFY(cba >= abc);
6930 QVERIFY(!(abc >= cba));
6931 QVERIFY(de >= abc);
6932 QVERIFY(!(abc >= de));
6933
6934 QLatin1String subfoo("fooZZ", 3);
6935 QLatin1String foo("foo");
6936 QVERIFY(subfoo == foo);
6937 QVERIFY(foo == subfoo);
6938 QVERIFY(!(subfoo != foo));
6939 QVERIFY(!(foo != subfoo));
6940 QVERIFY(!(foo < subfoo));
6941 QVERIFY(!(subfoo < foo));
6942 QVERIFY(foo >= subfoo);
6943 QVERIFY(subfoo >= foo);
6944 QVERIFY(!(foo > subfoo));
6945 QVERIFY(!(subfoo > foo));
6946 QVERIFY(foo <= subfoo);
6947 QVERIFY(subfoo <= foo);
6948
6949 QLatin1String subabc("abcZZ", 3);
6950 QLatin1String subab("abcZZ", 2);
6951 QVERIFY(subabc != subab);
6952 QVERIFY(subab != subabc);
6953 QVERIFY(!(subabc == subab));
6954 QVERIFY(!(subab == subabc));
6955 QVERIFY(subab < subabc);
6956 QVERIFY(!(subabc < subab));
6957 QVERIFY(subabc > subab);
6958 QVERIFY(!(subab > subabc));
6959 QVERIFY(subab <= subabc);
6960 QVERIFY(!(subabc <= subab));
6961 QVERIFY(subabc >= subab);
6962 QVERIFY(!(subab >= subabc));
6963}
6964
6965void tst_QString::fromQLatin1StringWithLength()
6966{
6967 QLatin1String latin1foo("foobar", 3);
6968 QString foo(latin1foo);
6969 QCOMPARE(foo.size(), latin1foo.size());
6970 QCOMPARE(foo, QString::fromLatin1("foo"));
6971}
6972
6973void tst_QString::assignQLatin1String()
6974{
6975 QString empty = QLatin1String("");
6976 QVERIFY(empty.isEmpty());
6977 QVERIFY(!empty.isNull());
6978
6979 QString null = QLatin1String(0);
6980 QVERIFY(null.isEmpty());
6981 QVERIFY(null.isNull());
6982
6983 QLatin1String latin1foo("foo");
6984 QString foo = latin1foo;
6985 QCOMPARE(foo.size(), latin1foo.size());
6986 QCOMPARE(foo, QString::fromLatin1("foo"));
6987
6988 QLatin1String latin1subfoo("foobar", 3);
6989 foo = latin1subfoo;
6990 QCOMPARE(foo.size(), latin1subfoo.size());
6991 QCOMPARE(foo, QString::fromLatin1("foo"));
6992
6993 // check capacity re-use:
6994 QString s;
6995 QCOMPARE(s.capacity(), 0);
6996
6997 // assign to null QString:
6998 s = latin1foo;
6999 QCOMPARE(s, QString::fromLatin1("foo"));
7000 QCOMPARE(s.capacity(), 3);
7001
7002 // assign to non-null QString with enough capacity:
7003 s = QString::fromLatin1(str: "foofoo");
7004 const int capacity = s.capacity();
7005 s = latin1foo;
7006 QCOMPARE(s, QString::fromLatin1("foo"));
7007 QCOMPARE(s.capacity(), capacity);
7008
7009 // assign to shared QString (enough capacity, but can't use):
7010 s = QString::fromLatin1(str: "foofoo");
7011 QString s2 = s;
7012 s = latin1foo;
7013 QCOMPARE(s, QString::fromLatin1("foo"));
7014 QCOMPARE(s.capacity(), 3);
7015
7016 // assign to QString with too little capacity:
7017 s = QString::fromLatin1(str: "fo");
7018 QCOMPARE(s.capacity(), 2);
7019 s = latin1foo;
7020 QCOMPARE(s, QString::fromLatin1("foo"));
7021 QCOMPARE(s.capacity(), 3);
7022
7023}
7024
7025void tst_QString::assignQChar()
7026{
7027 const QChar sp = QLatin1Char(' ');
7028 QString s;
7029 QCOMPARE(s.capacity(), 0);
7030
7031 // assign to null QString:
7032 s = sp;
7033 QCOMPARE(s, QString(sp));
7034 QCOMPARE(s.capacity(), 1);
7035
7036 // assign to non-null QString with enough capacity:
7037 s = QLatin1String("foo");
7038 const int capacity = s.capacity();
7039 QCOMPARE(capacity, 3);
7040 s = sp;
7041 QCOMPARE(s, QString(sp));
7042 QCOMPARE(s.capacity(), capacity);
7043
7044 // assign to shared QString (enough capacity, but can't use):
7045 s = QLatin1String("foo");
7046 QString s2 = s;
7047 s = sp;
7048 QCOMPARE(s, QString(sp));
7049 QCOMPARE(s.capacity(), 1);
7050
7051 // assign to empty QString:
7052 s = QString("");
7053 s.detach();
7054 QCOMPARE(s.capacity(), 0);
7055 s = sp;
7056 QCOMPARE(s, QString(sp));
7057 QCOMPARE(s.capacity(), 1);
7058}
7059
7060void tst_QString::isRightToLeft_data()
7061{
7062 QTest::addColumn<QString>(name: "unicode");
7063 QTest::addColumn<bool>(name: "rtl");
7064
7065 QTest::newRow(dataTag: "null") << QString() << false;
7066 QTest::newRow(dataTag: "empty") << QString("") << false;
7067
7068 QTest::newRow(dataTag: "numbers-only") << QString("12345") << false;
7069 QTest::newRow(dataTag: "latin1-only") << QString("hello") << false;
7070 QTest::newRow(dataTag: "numbers-latin1") << (QString("12345") + QString("hello")) << false;
7071
7072 static const ushort unicode1[] = { 0x627, 0x627 };
7073 QTest::newRow(dataTag: "arabic-only") << QString::fromUtf16(unicode1, size: 2) << true;
7074 QTest::newRow(dataTag: "numbers-arabic") << (QString("12345") + QString::fromUtf16(unicode1, size: 2)) << true;
7075 QTest::newRow(dataTag: "numbers-latin1-arabic") << (QString("12345") + QString("hello") + QString::fromUtf16(unicode1, size: 2)) << false;
7076 QTest::newRow(dataTag: "numbers-arabic-latin1") << (QString("12345") + QString::fromUtf16(unicode1, size: 2) + QString("hello")) << true;
7077
7078 static const ushort unicode2[] = { QChar::highSurrogate(ucs4: 0xE01DAu), QChar::lowSurrogate(ucs4: 0xE01DAu), QChar::highSurrogate(ucs4: 0x2F800u), QChar::lowSurrogate(ucs4: 0x2F800u) };
7079 QTest::newRow(dataTag: "surrogates-VS-CJK") << QString::fromUtf16(unicode2, size: 4) << false;
7080
7081 static const ushort unicode3[] = { QChar::highSurrogate(ucs4: 0x10800u), QChar::lowSurrogate(ucs4: 0x10800u), QChar::highSurrogate(ucs4: 0x10805u), QChar::lowSurrogate(ucs4: 0x10805u) };
7082 QTest::newRow(dataTag: "surrogates-cypriot") << QString::fromUtf16(unicode3, size: 4) << true;
7083
7084 QTest::newRow(dataTag: "lre") << (QString("12345") + QChar(0x202a) + QString("9") + QChar(0x202c)) << false;
7085 QTest::newRow(dataTag: "rle") << (QString("12345") + QChar(0x202b) + QString("9") + QChar(0x202c)) << false;
7086 QTest::newRow(dataTag: "r in lre") << (QString("12345") + QChar(0x202a) + QString::fromUtf16(unicode1, size: 2) + QChar(0x202c) + QString("a")) << true;
7087 QTest::newRow(dataTag: "l in lre") << (QString("12345") + QChar(0x202a) + QString("a") + QChar(0x202c) + QString::fromUtf16(unicode1, size: 2)) << false;
7088 QTest::newRow(dataTag: "r in rle") << (QString("12345") + QChar(0x202b) + QString::fromUtf16(unicode1, size: 2) + QChar(0x202c) + QString("a")) << true;
7089 QTest::newRow(dataTag: "l in rle") << (QString("12345") + QChar(0x202b) + QString("a") + QChar(0x202c) + QString::fromUtf16(unicode1, size: 2)) << false;
7090
7091 QTest::newRow(dataTag: "lro") << (QString("12345") + QChar(0x202d) + QString("9") + QChar(0x202c)) << false;
7092 QTest::newRow(dataTag: "rlo") << (QString("12345") + QChar(0x202e) + QString("9") + QChar(0x202c)) << false;
7093 QTest::newRow(dataTag: "r in lro") << (QString("12345") + QChar(0x202d) + QString::fromUtf16(unicode1, size: 2) + QChar(0x202c) + QString("a")) << true;
7094 QTest::newRow(dataTag: "l in lro") << (QString("12345") + QChar(0x202d) + QString("a") + QChar(0x202c) + QString::fromUtf16(unicode1, size: 2)) << false;
7095 QTest::newRow(dataTag: "r in rlo") << (QString("12345") + QChar(0x202e) + QString::fromUtf16(unicode1, size: 2) + QChar(0x202c) + QString("a")) << true;
7096 QTest::newRow(dataTag: "l in rlo") << (QString("12345") + QChar(0x202e) + QString("a") + QChar(0x202c) + QString::fromUtf16(unicode1, size: 2)) << false;
7097
7098 QTest::newRow(dataTag: "lri") << (QString("12345") + QChar(0x2066) + QString("a") + QChar(0x2069) + QString::fromUtf16(unicode1, size: 2)) << true;
7099 QTest::newRow(dataTag: "rli") << (QString("12345") + QChar(0x2067) + QString::fromUtf16(unicode1, size: 2) + QChar(0x2069) + QString("a")) << false;
7100 QTest::newRow(dataTag: "fsi1") << (QString("12345") + QChar(0x2068) + QString("a") + QChar(0x2069) + QString::fromUtf16(unicode1, size: 2)) << true;
7101 QTest::newRow(dataTag: "fsi2") << (QString("12345") + QChar(0x2068) + QString::fromUtf16(unicode1, size: 2) + QChar(0x2069) + QString("a")) << false;
7102}
7103
7104void tst_QString::isRightToLeft()
7105{
7106 QFETCH(QString, unicode);
7107 QFETCH(bool, rtl);
7108
7109 QCOMPARE(unicode.isRightToLeft(), rtl);
7110}
7111
7112void tst_QString::isValidUtf16_data()
7113{
7114 QTest::addColumn<QString>(name: "string");
7115 QTest::addColumn<bool>(name: "valid");
7116
7117 int row = 0;
7118 QTest::addRow(format: "valid-%02d", row++) << QString() << true;
7119 QTest::addRow(format: "valid-%02d", row++) << QString("") << true;
7120 QTest::addRow(format: "valid-%02d", row++) << QString("abc def") << true;
7121 QTest::addRow(format: "valid-%02d", row++) << QString("Γ bΓ§") << true;
7122 QTest::addRow(format: "valid-%02d", row++) << QString("ßẞ") << true;
7123 QTest::addRow(format: "valid-%02d", row++) << QString("𝐀𝐁𝐂abc𝐃𝐄𝐅def") << true;
7124 QTest::addRow(format: "valid-%02d", row++) << QString("abc𝐀𝐁𝐂def𝐃𝐄𝐅") << true;
7125 QTest::addRow(format: "valid-%02d", row++) << (QString("abc") + QChar(0x0000) + QString("def")) << true;
7126 QTest::addRow(format: "valid-%02d", row++) << (QString("abc") + QChar(0xFFFF) + QString("def")) << true;
7127 // check that BOM presence doesn't make any difference
7128 QTest::addRow(format: "valid-%02d", row++) << (QString() + QChar(0xFEFF) + QString("abc𝐀𝐁𝐂def𝐃𝐄𝐅")) << true;
7129 QTest::addRow(format: "valid-%02d", row++) << (QString() + QChar(0xFFFE) + QString("abc𝐀𝐁𝐂def𝐃𝐄𝐅")) << true;
7130
7131 row = 0;
7132 QTest::addRow(format: "stray-high-%02d", row++) << (QString() + QChar(0xD800)) << false;
7133 QTest::addRow(format: "stray-high-%02d", row++) << (QString() + QString("abc") + QChar(0xD800)) << false;
7134 QTest::addRow(format: "stray-high-%02d", row++) << (QString() + QChar(0xD800) + QString("def")) << false;
7135 QTest::addRow(format: "stray-high-%02d", row++) << (QString() + QString("abc") + QChar(0xD800) + QString("def")) << false;
7136 QTest::addRow(format: "stray-high-%02d", row++) << (QString() + QChar(0xD800) + QChar(0xD800)) << false;
7137 QTest::addRow(format: "stray-high-%02d", row++) << (QString() + QString("abc") + QChar(0xD800) + QChar(0xD800)) << false;
7138 QTest::addRow(format: "stray-high-%02d", row++) << (QString() + QChar(0xD800) + QChar(0xD800) + QString("def")) << false;
7139 QTest::addRow(format: "stray-high-%02d", row++) << (QString() + QString("abc") + QChar(0xD800) + QChar(0xD800) + QString("def")) << false;
7140
7141 row = 0;
7142 QTest::addRow(format: "stray-low-%02d", row++) << (QString() + QChar(0xDC00)) << false;
7143 QTest::addRow(format: "stray-low-%02d", row++) << (QString() + QString("abc") + QChar(0xDC00)) << false;
7144 QTest::addRow(format: "stray-low-%02d", row++) << (QString() + QChar(0xDC00) + QString("def")) << false;
7145 QTest::addRow(format: "stray-low-%02d", row++) << (QString() + QString("abc") + QChar(0xDC00) + QString("def")) << false;
7146 QTest::addRow(format: "stray-low-%02d", row++) << (QString() + QChar(0xDC00) + QChar(0xDC00)) << false;
7147 QTest::addRow(format: "stray-low-%02d", row++) << (QString() + QString("abc") + QChar(0xDC00) + QChar(0xDC00)) << false;
7148 QTest::addRow(format: "stray-low-%02d", row++) << (QString() + QChar(0xDC00) + QChar(0xDC00) + QString("def")) << false;
7149 QTest::addRow(format: "stray-low-%02d", row++) << (QString() + QString("abc") + QChar(0xDC00) + QChar(0xDC00) + QString("def")) << false;
7150}
7151
7152void tst_QString::isValidUtf16()
7153{
7154 QFETCH(QString, string);
7155 QTEST(string.isValidUtf16(), "valid");
7156}
7157
7158static QString doVasprintf(const char *msg, ...) {
7159 va_list args;
7160 va_start(args, msg);
7161 const QString result = QString::vasprintf(format: msg, ap: args);
7162 va_end(args);
7163 return result;
7164}
7165
7166void tst_QString::vasprintfWithPrecision()
7167{
7168 {
7169 const char *msg = "Endpoint %.*s with";
7170 static const char arg0[3] = { 'a', 'b', 'c' };
7171 static const char arg1[4] = { 'a', 'b', 'c', '\0' };
7172 QCOMPARE(doVasprintf(msg, 3, arg0), QStringLiteral("Endpoint abc with"));
7173 QCOMPARE(doVasprintf(msg, 9, arg1), QStringLiteral("Endpoint abc with"));
7174 QCOMPARE(doVasprintf(msg, 0, nullptr), QStringLiteral("Endpoint with"));
7175 }
7176
7177 {
7178 const char *msg = "Endpoint %.*ls with";
7179 static const ushort arg0[3] = { 'a', 'b', 'c' };
7180 static const ushort arg1[4] = { 'a', 'b', 'c', '\0' };
7181 QCOMPARE(doVasprintf(msg, 3, arg0), QStringLiteral("Endpoint abc with"));
7182 QCOMPARE(doVasprintf(msg, 9, arg1), QStringLiteral("Endpoint abc with"));
7183 QCOMPARE(doVasprintf(msg, 0, nullptr), QStringLiteral("Endpoint with"));
7184 }
7185}
7186
7187QTEST_APPLESS_MAIN(tst_QString)
7188
7189#include "tst_qstring.moc"
7190

source code of qtbase/tests/auto/corelib/text/qstring/tst_qstring.cpp