diff options
Diffstat (limited to 'tests/auto/corelib/text/qbytearray/tst_qbytearray.cpp')
-rw-r--r-- | tests/auto/corelib/text/qbytearray/tst_qbytearray.cpp | 1418 |
1 files changed, 744 insertions, 674 deletions
diff --git a/tests/auto/corelib/text/qbytearray/tst_qbytearray.cpp b/tests/auto/corelib/text/qbytearray/tst_qbytearray.cpp index e9d0cf8236..81d79da38b 100644 --- a/tests/auto/corelib/text/qbytearray/tst_qbytearray.cpp +++ b/tests/auto/corelib/text/qbytearray/tst_qbytearray.cpp @@ -1,31 +1,6 @@ -/**************************************************************************** -** -** Copyright (C) 2020 The Qt Company Ltd. -** Copyright (C) 2016 Intel Corporation. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2022 The Qt Company Ltd. +// Copyright (C) 2016 Intel Corporation. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include <QTest> @@ -35,6 +10,13 @@ #include <limits.h> #include <private/qtools_p.h> +#include "../shared/test_number_shared.h" + +#include <QtCore/q20iterator.h> +#include <sstream> + +using namespace Qt::StringLiterals; + class tst_QByteArray : public QObject { Q_OBJECT @@ -42,16 +24,10 @@ class tst_QByteArray : public QObject public: tst_QByteArray(); private slots: + // Note: much of the shared API is tested in ../qbytearrayapisymmetry/ void swap(); void qChecksum_data(); void qChecksum(); - void qCompress_data(); -#ifndef QT_NO_COMPRESS - void qCompress(); - void qUncompressCorruptedData_data(); - void qUncompressCorruptedData(); - void qCompressionZeroTermination(); -#endif void constByteArray(); void leftJustified(); void rightJustified(); @@ -75,40 +51,35 @@ private slots: void prependExtended_data(); void prependExtended(); void append(); + void appendFromRawData(); void appendExtended_data(); void appendExtended(); + void appendEmptyNull(); + void assign(); + void assignShared(); + void assignUsesPrependBuffer(); void insert(); void insertExtended_data(); void insertExtended(); void remove_data(); void remove(); + void remove_extra(); void removeIf(); + void erase(); + void erase_single_arg(); void replace_data(); void replace(); void replaceWithSpecifiedLength(); - void toLong_data(); - void toLong(); - void toULong_data(); - void toULong(); - void toLongLong_data(); - void toLongLong(); - void toULongLong_data(); - void toULongLong(); void number(); - void toShort(); - void toUShort(); - void toInt_data(); - void toInt(); - void toUInt_data(); - void toUInt(); - void toFloat(); - void toDouble_data(); - void toDouble(); + void number_double_data(); + void number_double(); + void number_base_data(); + void number_base(); + void nullness(); void blockSizeCalculations(); void resizeAfterFromRawData(); - void appendAfterFromRawData(); void toFromHex_data(); void toFromHex(); void toFromPercentEncoding(); @@ -116,8 +87,8 @@ private slots: void fromPercentEncoding(); void toPercentEncoding_data(); void toPercentEncoding(); - void toPercentEncoding2_data(); - void toPercentEncoding2(); + void pecentEncodingRoundTrip_data(); + void pecentEncodingRoundTrip(); void qstrcmp_data(); void qstrcmp(); @@ -134,8 +105,9 @@ private slots: void reserve(); void reserveExtended_data(); void reserveExtended(); - void movablity_data(); - void movablity(); + void resize(); + void movability_data(); + void movability(); void literals(); void userDefinedLiterals(); void toUpperLower_data(); @@ -151,8 +123,8 @@ private slots: void fill(); void dataPointers(); void truncate(); - void trimmed(); void trimmed_data(); + void trimmed(); void simplified(); void simplified_data(); void left(); @@ -160,6 +132,7 @@ private slots: void mid(); void length(); void length_data(); + void slice() const; }; static const QByteArray::DataPointer staticStandard = { @@ -173,6 +146,15 @@ static const QByteArray::DataPointer staticNotNullTerminated = { 4 }; +template <typename String> String detached(String s) +{ + if (!s.isNull()) { // detaching loses nullness, but we need to preserve it + auto d = s.data(); + Q_UNUSED(d); + } + return s; +} + template <class T> const T &verifyZeroTermination(const T &t) { return t; } QByteArray verifyZeroTermination(const QByteArray &ba) @@ -185,7 +167,7 @@ QByteArray verifyZeroTermination(const QByteArray &ba) if (!baDataPtr->isMutable()) return ba; - int baSize = ba.size(); + qsizetype baSize = ba.size(); char baTerminator = ba.constData()[baSize]; if ('\0' != baTerminator) return QString::fromUtf8( @@ -259,92 +241,13 @@ void tst_QByteArray::qChecksum() QFETCH(Qt::ChecksumType, standard); QFETCH(uint, checksum); - QCOMPARE(data.length(), int(len)); + QCOMPARE(data.size(), int(len)); if (standard == Qt::ChecksumIso3309) { QCOMPARE(::qChecksum(QByteArrayView(data.constData(), len)), static_cast<quint16>(checksum)); } QCOMPARE(::qChecksum(QByteArrayView(data.constData(), len), standard), static_cast<quint16>(checksum)); } -void tst_QByteArray::qCompress_data() -{ - QTest::addColumn<QByteArray>("ba"); - - const int size1 = 1024*1024; - QByteArray ba1( size1, 0 ); - - QTest::newRow( "00" ) << QByteArray(); - - int i; - for ( i=0; i<size1; i++ ) - ba1[i] = (char)( i / 1024 ); - QTest::newRow( "01" ) << ba1; - - for ( i=0; i<size1; i++ ) - ba1[i] = (char)( i % 256 ); - QTest::newRow( "02" ) << ba1; - - ba1.fill( 'A' ); - QTest::newRow( "03" ) << ba1; - - QFile file( QFINDTESTDATA("rfc3252.txt") ); - QVERIFY( file.open(QIODevice::ReadOnly) ); - QTest::newRow( "04" ) << file.readAll(); -} - -#ifndef QT_NO_COMPRESS -void tst_QByteArray::qCompress() -{ - QFETCH( QByteArray, ba ); - QByteArray compressed = ::qCompress( ba ); - QTEST( ::qUncompress( compressed ), "ba" ); -} - -void tst_QByteArray::qUncompressCorruptedData_data() -{ - QTest::addColumn<QByteArray>("in"); - - QTest::newRow("0x00000000") << QByteArray("\x00\x00\x00\x00", 4); - QTest::newRow("0x000000ff") << QByteArray("\x00\x00\x00\xff", 4); - QTest::newRow("0x3f000000") << QByteArray("\x3f\x00\x00\x00", 4); - QTest::newRow("0x3fffffff") << QByteArray("\x3f\xff\xff\xff", 4); - QTest::newRow("0x7fffff00") << QByteArray("\x7f\xff\xff\x00", 4); - QTest::newRow("0x7fffffff") << QByteArray("\x7f\xff\xff\xff", 4); - QTest::newRow("0x80000000") << QByteArray("\x80\x00\x00\x00", 4); - QTest::newRow("0x800000ff") << QByteArray("\x80\x00\x00\xff", 4); - QTest::newRow("0xcf000000") << QByteArray("\xcf\x00\x00\x00", 4); - QTest::newRow("0xcfffffff") << QByteArray("\xcf\xff\xff\xff", 4); - QTest::newRow("0xffffff00") << QByteArray("\xff\xff\xff\x00", 4); - QTest::newRow("0xffffffff") << QByteArray("\xff\xff\xff\xff", 4); -} - -// Corrupt data causes this test to lock up on HP-UX / PA-RISC with gcc, -// SOLARIS, and Windows. -// This test is expected to produce some warning messages in the test output. -void tst_QByteArray::qUncompressCorruptedData() -{ -#if !(defined(Q_OS_HPUX) && !defined(__ia64) && defined(Q_CC_GNU)) && !defined(Q_OS_SOLARIS) && !defined(Q_OS_WIN) - QFETCH(QByteArray, in); - - QByteArray res; - res = ::qUncompress(in); - QCOMPARE(res, QByteArray()); - - res = ::qUncompress(in + "blah"); - QCOMPARE(res, QByteArray()); -#else - QSKIP("This test freezes on this platform"); -#endif -} - -void tst_QByteArray::qCompressionZeroTermination() -{ - QString s = "Hello, I'm a string."; - QByteArray ba = ::qUncompress(::qCompress(s.toLocal8Bit())); - QVERIFY((int) *(ba.data() + ba.size()) == 0); -} - -#endif void tst_QByteArray::constByteArray() { @@ -425,18 +328,17 @@ void tst_QByteArray::setNum() QCOMPARE(a.setNum(37, 2), QByteArray("100101")); QCOMPARE(a.setNum(37, 36), QByteArray("11")); - // Negative numbers are only properly supported for base 10. - QCOMPARE(a.setNum(short(-1), 16), QByteArray("ffff")); - QCOMPARE(a.setNum(int(-1), 16), QByteArray("ffffffff")); - QCOMPARE(a.setNum(qlonglong(-1), 16), QByteArray("ffffffffffffffff")); + QCOMPARE(a.setNum(short(-1), 16), QByteArray("-1")); + QCOMPARE(a.setNum(int(-1), 16), QByteArray("-1")); + QCOMPARE(a.setNum(qlonglong(-1), 16), QByteArray("-1")); QCOMPARE(a.setNum(short(-1), 10), QByteArray("-1")); QCOMPARE(a.setNum(int(-1), 10), QByteArray("-1")); QCOMPARE(a.setNum(qlonglong(-1), 10), QByteArray("-1")); QCOMPARE(a.setNum(-123), QByteArray("-123")); - QCOMPARE(a.setNum(0x123,16), QByteArray("123")); - QCOMPARE(a.setNum((short)123), QByteArray("123")); + QCOMPARE(a.setNum(0x123, 16), QByteArray("123")); + QCOMPARE(a.setNum(short(123)), QByteArray("123")); QCOMPARE(a.setNum(1.23), QByteArray("1.23")); QCOMPARE(a.setNum(1.234567), QByteArray("1.23457")); @@ -536,7 +438,7 @@ void tst_QByteArray::split() QFETCH(int, size); QList<QByteArray> list = sample.split(' '); - QCOMPARE(list.count(), size); + QCOMPARE(list.size(), size); } void tst_QByteArray::swap() @@ -822,18 +724,18 @@ void tst_QByteArray::qvsnprintf() void tst_QByteArray::qstrlen() { const char *src = "Something about ... \0 a string."; - QCOMPARE(::qstrlen((char*)0), (uint)0); - QCOMPARE(::qstrlen(src), (uint)20); + QCOMPARE(::qstrlen(nullptr), size_t(0)); + QCOMPARE(::qstrlen(src), size_t(20)); } void tst_QByteArray::qstrnlen() { const char *src = "Something about ... \0 a string."; - QCOMPARE(::qstrnlen((char*)0, 1), (uint)0); - QCOMPARE(::qstrnlen(src, 31), (uint)20); - QCOMPARE(::qstrnlen(src, 19), (uint)19); - QCOMPARE(::qstrnlen(src, 21), (uint)20); - QCOMPARE(::qstrnlen(src, 20), (uint)20); + QCOMPARE(::qstrnlen(nullptr, 1), size_t(0)); + QCOMPARE(::qstrnlen(src, 31), size_t(20)); + QCOMPARE(::qstrnlen(src, 19), size_t(19)); + QCOMPARE(::qstrnlen(src, 21), size_t(20)); + QCOMPARE(::qstrnlen(src, 20), size_t(20)); } void tst_QByteArray::qstrcpy() @@ -859,7 +761,10 @@ void tst_QByteArray::qstrncpy() // src == nullptr QCOMPARE(::qstrncpy(dst.data(), 0, 0), (char*)0); + QCOMPARE(*dst.data(), 'b'); // must not have written to dst QCOMPARE(::qstrncpy(dst.data(), 0, 10), (char*)0); + QCOMPARE(*dst.data(), '\0'); // must have written to dst + *dst.data() = 'b'; // restore // valid pointers, but len == 0 QCOMPARE(::qstrncpy(dst.data(), src.data(), 0), dst.data()); @@ -976,6 +881,7 @@ void tst_QByteArray::append() QCOMPARE(QByteArray().append(2, 'a'), QByteArray("aa")); QCOMPARE(QByteArray().append(QByteArray("data")), QByteArray("data")); QCOMPARE(QByteArray().append(data), QByteArray("data")); + QCOMPARE(QByteArray().append(data, -1), QByteArray("data")); QCOMPARE(QByteArray().append(data, 2), QByteArray("da")); QCOMPARE(QByteArray().append(QByteArrayView(data)), QByteArray("data")); @@ -1019,6 +925,20 @@ void tst_QByteArray::append() } } +void tst_QByteArray::appendFromRawData() +{ + char rawData[] = "Hello World!"; + QByteArray ba = QByteArray::fromRawData(rawData, std::size(rawData) - 1); + + QByteArray copy; + copy.append(ba); + QCOMPARE(copy, ba); + // We make an _actual_ copy, because appending a byte array + // created with fromRawData() might be optimized to copy the DataPointer, + // which means we may point to temporary stack data. + QCOMPARE_NE((void *)copy.constData(), (void *)ba.constData()); +} + void tst_QByteArray::appendExtended_data() { prependExtended_data(); @@ -1043,6 +963,207 @@ void tst_QByteArray::appendExtended() QCOMPARE(array.size(), 11); } +void tst_QByteArray::appendEmptyNull() +{ + QByteArray a; + QVERIFY(a.isEmpty()); + QVERIFY(a.isNull()); + + QByteArray b(""); + QVERIFY(b.isEmpty()); + QVERIFY(!b.isNull()); + + // Concatenating a null and an empty-but-not-null byte arrays results in + // an empty but not null byte array + QByteArray r = a + b; + QVERIFY(r.isEmpty()); + QVERIFY(!r.isNull()); +} + +void tst_QByteArray::assign() +{ + // QByteArray &assign(QByteArrayView) + { + QByteArray ba; + QByteArray test("data"); + QCOMPARE(ba.assign(test), test); + QCOMPARE(ba.size(), test.size()); + test = "data\0data"; + QCOMPARE(ba.assign(test), test); + QCOMPARE(ba.size(), test.size()); + test = "data\0data"_ba; + QCOMPARE(ba.assign(test), test); + QCOMPARE(ba.size(), test.size()); + } + // QByteArray &assign(qsizetype, char); + { + QByteArray ba; + QByteArray test("ddd"); + QCOMPARE(ba.assign(3, 'd'), test); + QCOMPARE(ba.size(), test.size()); + test = "xx"; + QCOMPARE(ba.assign(20, 'd').assign(2, 'x'), test); + QCOMPARE(ba.size(), test.size()); + test = "ddddd"; + QCOMPARE(ba.assign(0, 'x').assign(5, 'd'), test); + QCOMPARE(ba.size(), test.size()); + test = "\0\0\0"_ba; + QCOMPARE(ba.assign(0, 'x').assign(3, '\0'), test); + QCOMPARE(ba.size(), test.size()); + } + // QByteArray &assign(InputIterator, InputIterator) + { + QByteArray ba; + QByteArrayView test; + + QList<char> l = {'\0', 'T', 'E', 'S', 'T'}; + ba.assign(l.begin(), l.end()); + test = "\0TEST"_ba; + QCOMPARE(ba, test); + QCOMPARE(ba.size(), test.size()); + + const std::byte bytes[] = {std::byte('T'), std::byte(0), std::byte('S'), std::byte('T')}; + test = QByteArrayView::fromArray(bytes); + QCOMPARE(ba.assign(test.begin(), test.end()), test); + QCOMPARE(ba.size(), test.size()); + + std::stringstream ss; + ss << "T " << '\0' << ' ' << "S " << "T "; + ba.assign(std::istream_iterator<char>{ss}, std::istream_iterator<char>{}); + test = "T\0ST"_ba; + QCOMPARE(ba, test); + QCOMPARE(ba.size(), test.size()); + } + // Test chaining + { + QByteArray ba; + QByteArray test("TTTTT"); + char arr[] = {'T', 'E', 'S', 'T'}; + ba.assign(std::begin(arr), std::end(arr)).assign({"Hello World!"}).assign(5, 'T'); + QCOMPARE(ba, test); + QCOMPARE(ba.size(), test.size()); + test = "DATA"; + QCOMPARE(ba.assign(300, 'T').assign({"DATA"}), test); + QCOMPARE(ba.size(), test.size()); + test = QByteArray(arr, q20::ssize(arr)); + QCOMPARE(ba.assign(10, 'c').assign(std::begin(arr), std::end(arr)), test); + QCOMPARE(ba.size(), test.size()); + test = "TTT"; + QCOMPARE(ba.assign("data").assign(QByteArrayView::fromArray( + {std::byte('T'), std::byte('T'), std::byte('T')})), test); + QCOMPARE(ba.size(), test.size()); + test = "\0data"; + QCOMPARE(ba.assign("data").assign("\0data"), test); + QCOMPARE(ba.size(), test.size()); + } +} + +void tst_QByteArray::assignShared() +{ + { + QByteArray ba; + ba.assign({"DATA"}); + QVERIFY(ba.isDetached()); + QCOMPARE(ba, QByteArray("DATA")); + + auto baCopy = ba; + QVERIFY(!ba.isDetached()); + QVERIFY(!baCopy.isDetached()); + QVERIFY(ba.isSharedWith(baCopy)); + QVERIFY(baCopy.isSharedWith(ba)); + + ba.assign(10, 'D'); + QVERIFY(ba.isDetached()); + QVERIFY(baCopy.isDetached()); + QVERIFY(!ba.isSharedWith(baCopy)); + QVERIFY(!baCopy.isSharedWith(ba)); + QCOMPARE(ba, QByteArray("DDDDDDDDDD")); + QCOMPARE(baCopy, QByteArray("DATA")); + } + { + QByteArray ba("START"); + QByteArrayView bav("DATA"); + QVERIFY(ba.isDetached()); + QCOMPARE(ba, QByteArray("START")); + + auto copyForwardIt = ba; + QVERIFY(!ba.isDetached()); + QVERIFY(!copyForwardIt.isDetached()); + QVERIFY(ba.isSharedWith(copyForwardIt)); + QVERIFY(copyForwardIt.isSharedWith(ba)); + + ba.assign(bav.begin(), bav.end()); + QVERIFY(ba.isDetached()); + QVERIFY(copyForwardIt.isDetached()); + QVERIFY(!ba.isSharedWith(copyForwardIt)); + QVERIFY(!copyForwardIt.isSharedWith(ba)); + QCOMPARE(ba, QByteArray("DATA")); + QCOMPARE(copyForwardIt, QByteArray("START")); + + auto copyInputIt = ba; + QVERIFY(!ba.isDetached()); + QVERIFY(!copyInputIt.isDetached()); + QVERIFY(ba.isSharedWith(copyInputIt)); + QVERIFY(copyInputIt.isSharedWith(ba)); + + std::stringstream ss("1 2 3 4 5 6 "); + ba.assign(std::istream_iterator<char>{ss}, std::istream_iterator<char>{}); + QVERIFY(ba.isDetached()); + QVERIFY(copyInputIt.isDetached()); + QVERIFY(!ba.isSharedWith(copyInputIt)); + QVERIFY(!copyInputIt.isSharedWith(ba)); + QCOMPARE(ba, QByteArray("123456")); + QCOMPARE(copyInputIt, QByteArray("DATA")); + } +} + +void tst_QByteArray::assignUsesPrependBuffer() +{ + const auto capBegin = [](const QByteArray &ba) { + return ba.begin() - ba.d.freeSpaceAtBegin(); + }; + const auto capEnd = [](const QByteArray &ba) { + return ba.end() + ba.d.freeSpaceAtEnd(); + }; + // QByteArray &assign(QByteArrayView) + { + QByteArray withFreeSpaceAtBegin; + for (int i = 0; i < 100 && withFreeSpaceAtBegin.d.freeSpaceAtBegin() < 2; ++i) + withFreeSpaceAtBegin.prepend("data"); + QCOMPARE_GT(withFreeSpaceAtBegin.d.freeSpaceAtBegin(), 1); + + const auto oldCapBegin = capBegin(withFreeSpaceAtBegin); + const auto oldCapEnd = capEnd(withFreeSpaceAtBegin); + + std::string test(withFreeSpaceAtBegin.d.freeSpaceAtBegin(), 'd'); + withFreeSpaceAtBegin.assign(test); + + QCOMPARE_EQ(withFreeSpaceAtBegin.d.freeSpaceAtBegin(), 0); // we used the prepend buffer + QCOMPARE_EQ(capBegin(withFreeSpaceAtBegin), oldCapBegin); + QCOMPARE_EQ(capEnd(withFreeSpaceAtBegin), oldCapEnd); + QCOMPARE(withFreeSpaceAtBegin, test.data()); + } + // QByteArray &assign(InputIterator, InputIterator) + { + QByteArray withFreeSpaceAtBegin; + for (int i = 0; i < 100 && withFreeSpaceAtBegin.d.freeSpaceAtBegin() < 2; ++i) + withFreeSpaceAtBegin.prepend("data"); + QCOMPARE_GT(withFreeSpaceAtBegin.d.freeSpaceAtBegin(), 1); + + const auto oldCapBegin = capBegin(withFreeSpaceAtBegin); + const auto oldCapEnd = capEnd(withFreeSpaceAtBegin); + + std::stringstream ss; + for (qsizetype i = 0; i < withFreeSpaceAtBegin.d.freeSpaceAtBegin(); ++i) + ss << "d "; + + withFreeSpaceAtBegin.assign(std::istream_iterator<char>{ss}, std::istream_iterator<char>{}); + QCOMPARE_EQ(withFreeSpaceAtBegin.d.freeSpaceAtBegin(), 0); // we used the prepend buffer + QCOMPARE_EQ(capBegin(withFreeSpaceAtBegin), oldCapBegin); + QCOMPARE_EQ(capEnd(withFreeSpaceAtBegin), oldCapEnd); + } +} + void tst_QByteArray::insert() { const char data[] = "data"; @@ -1179,7 +1300,30 @@ void tst_QByteArray::remove() QFETCH(int, position); QFETCH(int, length); QFETCH(QByteArray, expected); - QCOMPARE(src.remove(position, length), expected); + // Test when it's shared + QByteArray ba1 = src; + QCOMPARE(ba1.remove(position, length), expected); + + // Test when it's not shared + QByteArray ba2 = src; + ba2.detach(); + QCOMPARE(ba2.remove(position, length), expected); +} + +void tst_QByteArray::remove_extra() +{ + QByteArray ba = "Clock"; + ba.removeFirst(); + QCOMPARE(ba, "lock"); + ba.removeLast(); + QCOMPARE(ba, "loc"); + ba.removeAt(ba.indexOf('o')); + QCOMPARE(ba, "lc"); + ba.clear(); + // No crash on empty byte arrays + ba.removeFirst(); + ba.removeLast(); + ba.removeAt(2); } void tst_QByteArray::removeIf() @@ -1191,7 +1335,58 @@ void tst_QByteArray::removeIf() QVERIFY(!a.isDetached()); a = QByteArray("aBcAbC"); + // Test when it's not shared + QVERIFY(a.isDetached()); QCOMPARE(a.removeIf(removeA), QByteArray("BcbC")); + + a = QByteArray("aBcAbC"); + QByteArray b = a; + // Test when it's shared + QVERIFY(!b.isDetached()); + QCOMPARE(b.removeIf(removeA), QByteArray("BcbC")); +} + +void tst_QByteArray::erase() +{ + { + QByteArray ba = "kittens"; + auto it = ba.erase(ba.cbegin(), ba.cbegin() + 2); + QCOMPARE(ba, "ttens"); + QCOMPARE(it, ba.cbegin()); + } + + { + QByteArray ba = "kittens"; + auto it = ba.erase(ba.cbegin(), ba.cend()); + QCOMPARE(ba, ""); + QCOMPARE(it, ba.cbegin()); + QCOMPARE(ba.cbegin(), ba.cend()); + } + + { + QByteArray ba = "kite"; + auto it = ba.erase(ba.cbegin(), ba.cbegin()); + // erase() should return an iterator (not const_iterator) + *it = 'Z'; + QCOMPARE(ba, "Zite"); + QCOMPARE(it, ba.cbegin()); + } +} + +void tst_QByteArray::erase_single_arg() +{ + QByteArray ba = "abcdefg"; + ba.erase(ba.cend()); + auto it = ba.erase(ba.cbegin()); + QCOMPARE_EQ(ba, "bcdefg"); + QCOMPARE(it, ba.cbegin()); + + it = ba.erase(std::prev(ba.end())); + QCOMPARE_EQ(ba, "bcdef"); + QCOMPARE(it, ba.cend()); + + it = ba.erase(std::find(ba.begin(), ba.end(), QChar('d'))); + QCOMPARE(it, ba.begin() + 2); } void tst_QByteArray::replace_data() @@ -1283,412 +1478,139 @@ void tst_QByteArray::replaceWithSpecifiedLength() void tst_QByteArray::number() { - QCOMPARE(QString(QByteArray::number((quint64) 0)), - QString(QByteArray("0"))); - QCOMPARE(QString(QByteArray::number(Q_UINT64_C(0xFFFFFFFFFFFFFFFF))), - QString(QByteArray("18446744073709551615"))); - QCOMPARE(QString(QByteArray::number(Q_INT64_C(0xFFFFFFFFFFFFFFFF))), - QString(QByteArray("-1"))); - QCOMPARE(QString(QByteArray::number(qint64(0))), - QString(QByteArray("0"))); - QCOMPARE(QString(QByteArray::number(Q_INT64_C(0x7FFFFFFFFFFFFFFF))), - QString(QByteArray("9223372036854775807"))); - QCOMPARE(QString(QByteArray::number(Q_INT64_C(0x8000000000000000))), - QString(QByteArray("-9223372036854775808"))); + QCOMPARE(QByteArray::number(quint64(0)), QByteArray("0")); + QCOMPARE(QByteArray::number(Q_UINT64_C(0xFFFFFFFFFFFFFFFF)), + QByteArray("18446744073709551615")); + QCOMPARE(QByteArray::number(Q_INT64_C(0xFFFFFFFFFFFFFFFF)), QByteArray("-1")); + QCOMPARE(QByteArray::number(qint64(0)), QByteArray("0")); + QCOMPARE(QByteArray::number(Q_INT64_C(0x7FFFFFFFFFFFFFFF)), + QByteArray("9223372036854775807")); + QCOMPARE(QByteArray::number(Q_INT64_C(0x8000000000000000)), + QByteArray("-9223372036854775808")); } -void tst_QByteArray::toShort() +void tst_QByteArray::number_double_data() { - bool ok = true; // opposite to the next expected result - - QCOMPARE(QByteArray().toShort(&ok), 0); - QVERIFY(!ok); - - QCOMPARE(QByteArray("").toShort(&ok), 0); - QVERIFY(!ok); - - QCOMPARE(QByteArray("12345").toShort(&ok), 12345); - QVERIFY(ok); - - QCOMPARE(QByteArray("-12345").toShort(&ok), -12345); - QVERIFY(ok); - - QCOMPARE(QByteArray("32767").toShort(&ok), 32767); - QVERIFY(ok); - - QCOMPARE(QByteArray("-32768").toShort(&ok), -32768); - QVERIFY(ok); - - QCOMPARE(QByteArray("32768").toShort(&ok), 0); - QVERIFY(!ok); + QTest::addColumn<double>("value"); + QTest::addColumn<char>("format"); + QTest::addColumn<int>("precision"); + QTest::addColumn<QByteArray>("expected"); - QCOMPARE(QByteArray("-32769").toShort(&ok), 0); - QVERIFY(!ok); + // This function is implemented in ../shared/test_number_shared.h + add_number_double_shared_data([](NumberDoubleTestData datum) { + QByteArray ba(datum.expected.data(), datum.expected.size()); + const char *title = !datum.optTitle.isEmpty() ? datum.optTitle.data() : ba.data(); + QTest::addRow("%s, format '%c', precision %d", title, datum.f, datum.p) + << datum.d << datum.f << datum.p << ba; + if (datum.f != 'f') { // Also test uppercase format + datum.f = QtMiscUtils::toAsciiUpper(datum.f); + QByteArray upper = ba.toUpper(); + QByteArray upperTitle = QByteArray(title); + if (!datum.optTitle.isEmpty()) + upperTitle += ", uppercase"; + else + upperTitle = upperTitle.toUpper(); + QTest::addRow("%s, format '%c', precision %d", upperTitle.data(), datum.f, datum.p) + << datum.d << datum.f << datum.p << upper; + } + }); } -void tst_QByteArray::toUShort() +void tst_QByteArray::number_double() { - bool ok = true; // opposite to the next expected result - - QCOMPARE(QByteArray().toUShort(&ok), 0); - QVERIFY(!ok); + QFETCH(double, value); + QFETCH(char, format); + QFETCH(int, precision); - QCOMPARE(QByteArray("").toUShort(&ok), 0); - QVERIFY(!ok); - - QCOMPARE(QByteArray("12345").toUShort(&ok), 12345); - QVERIFY(ok); - - QCOMPARE(QByteArray("-12345").toUShort(&ok), 0); - QVERIFY(!ok); - - QCOMPARE(QByteArray("32767").toUShort(&ok), 32767); - QVERIFY(ok); - - QCOMPARE(QByteArray("32768").toUShort(&ok), 32768); - QVERIFY(ok); - - QCOMPARE(QByteArray("65535").toUShort(&ok), 65535); - QVERIFY(ok); - - QCOMPARE(QByteArray("65536").toUShort(&ok), 0); - QVERIFY(!ok); + if constexpr (std::numeric_limits<double>::has_denorm != std::denorm_present) { + if (::qstrcmp(QTest::currentDataTag(), "Very small number, very high precision, format 'f', precision 350") == 0) { + QSKIP("Skipping 'denorm' as this type lacks denormals on this system"); + } + } + QTEST(QByteArray::number(value, format, precision), "expected"); } -// defined later -extern const char globalChar; - -void tst_QByteArray::toInt_data() +void tst_QByteArray::number_base_data() { - QTest::addColumn<QByteArray>("string"); + QTest::addColumn<qlonglong>("n"); QTest::addColumn<int>("base"); - QTest::addColumn<int>("expectednumber"); - QTest::addColumn<bool>("expectedok"); - - QTest::newRow("null") << QByteArray() << 10 << 0 << false; - QTest::newRow("empty") << QByteArray("") << 10 << 0 << false; - - QTest::newRow("base 10") << QByteArray("100") << 10 << int(100) << true; - QTest::newRow("base 16-1") << QByteArray("100") << 16 << int(256) << true; - QTest::newRow("base 16-2") << QByteArray("0400") << 16 << int(1024) << true; - QTest::newRow("base 2") << QByteArray("1111") << 2 << int(15) << true; - QTest::newRow("base 8") << QByteArray("100") << 8 << int(64) << true; - QTest::newRow("base 0-1") << QByteArray("0x10") << 0 << int(16) << true; - QTest::newRow("base 0-2") << QByteArray("10") << 0 << int(10) << true; - QTest::newRow("base 0-3") << QByteArray("010") << 0 << int(8) << true; - QTest::newRow("empty") << QByteArray() << 0 << int(0) << false; - - QTest::newRow("leading space") << QByteArray(" 100") << 10 << int(100) << true; - QTest::newRow("trailing space") << QByteArray("100 ") << 10 << int(100) << true; - QTest::newRow("leading junk") << QByteArray("x100") << 10 << int(0) << false; - QTest::newRow("trailing junk") << QByteArray("100x") << 10 << int(0) << false; + QTest::addColumn<QByteArray>("expected"); - // using fromRawData - QTest::newRow("raw1") << QByteArray::fromRawData("1", 1) << 10 << 1 << true; - QTest::newRow("raw2") << QByteArray::fromRawData("1foo", 1) << 10 << 1 << true; - QTest::newRow("raw3") << QByteArray::fromRawData("12", 1) << 10 << 1 << true; - QTest::newRow("raw4") << QByteArray::fromRawData("123456789", 1) << 10 << 1 << true; - QTest::newRow("raw5") << QByteArray::fromRawData("123456789", 2) << 10 << 12 << true; + QTest::newRow("base 10") << 12346LL << 10 << QByteArray("12346"); + QTest::newRow("base 2") << 12346LL << 2 << QByteArray("11000000111010"); + QTest::newRow("base 8") << 12346LL << 8 << QByteArray("30072"); + QTest::newRow("base 16") << 12346LL << 16 << QByteArray("303a"); + QTest::newRow("base 17") << 12346LL << 17 << QByteArray("28c4"); + QTest::newRow("base 36") << 2181789482LL << 36 << QByteArray("102zbje"); - QTest::newRow("raw-static") << QByteArray::fromRawData(&globalChar, 1) << 10 << 1 << true; + QTest::newRow("largeint, base 10") + << 123456789012LL << 10 << QByteArray("123456789012"); + QTest::newRow("largeint, base 2") + << 123456789012LL << 2 << QByteArray("1110010111110100110010001101000010100"); + QTest::newRow("largeint, base 8") + << 123456789012LL << 8 << QByteArray("1627646215024"); + QTest::newRow("largeint, base 16") + << 123456789012LL << 16 << QByteArray("1cbe991a14"); + QTest::newRow("largeint, base 17") + << 123456789012LL << 17 << QByteArray("10bec2b629"); } -void tst_QByteArray::toInt() +void tst_QByteArray::number_base() { - QFETCH( QByteArray, string ); + QFETCH( qlonglong, n ); QFETCH( int, base ); - QFETCH( int, expectednumber ); - QFETCH( bool, expectedok ); - - bool ok; - int number = string.toInt(&ok, base); - - QCOMPARE( ok, expectedok ); - QCOMPARE( number, expectednumber ); -} - -void tst_QByteArray::toUInt_data() -{ - QTest::addColumn<QByteArray>("string"); - QTest::addColumn<int>("base"); - QTest::addColumn<uint>("expectednumber"); - QTest::addColumn<bool>("expectedok"); - - QTest::newRow("null") << QByteArray() << 10 << 0u << false; - QTest::newRow("empty") << QByteArray("") << 10 << 0u << false; - - QTest::newRow("negative value") << QByteArray("-50") << 10 << 0u << false; - QTest::newRow("more than MAX_INT") << QByteArray("3234567890") << 10 << 3234567890u << true; - QTest::newRow("2^32 - 1") << QByteArray("4294967295") << 10 << 4294967295u << true; - if (sizeof(int) == 4) - QTest::newRow("2^32") << QByteArray("4294967296") << 10 << 0u << false; -} - -void tst_QByteArray::toUInt() -{ - QFETCH(QByteArray, string); - QFETCH(int, base); - QFETCH(uint, expectednumber); - QFETCH(bool, expectedok); - - bool ok; - const uint number = string.toUInt(&ok, base); - - QCOMPARE(ok, expectedok); - QCOMPARE(number, expectednumber); -} - -void tst_QByteArray::toFloat() -{ - bool ok = true; // opposite to the next expected result - - QCOMPARE(QByteArray().toFloat(&ok), 0.0f); - QVERIFY(!ok); - - QCOMPARE(QByteArray("").toFloat(&ok), 0.0f); - QVERIFY(!ok); - - const QByteArray data("0.000000000931322574615478515625"); - const float expectedValue = 9.31322574615478515625e-10f; - QCOMPARE(data.toFloat(&ok), expectedValue); - QVERIFY(ok); -} - -void tst_QByteArray::toDouble_data() -{ - QTest::addColumn<QByteArray>("string"); - QTest::addColumn<double>("expectedNumber"); - QTest::addColumn<bool>("expectedOk"); - - QTest::newRow("null") << QByteArray() << 0.0 << false; - QTest::newRow("empty") << QByteArray("") << 0.0 << false; - - QTest::newRow("decimal") << QByteArray("1.2345") << 1.2345 << true; - QTest::newRow("exponent lowercase") << QByteArray("1.2345e+01") << 12.345 << true; - QTest::newRow("exponent uppercase") << QByteArray("1.2345E+02") << 123.45 << true; - QTest::newRow("leading spaces") << QByteArray(" \n\r\t1.2345") << 1.2345 << true; - QTest::newRow("trailing spaces") << QByteArray("1.2345 \n\r\t") << 1.2345 << true; - QTest::newRow("leading junk") << QByteArray("x1.2345") << 0.0 << false; - QTest::newRow("trailing junk") << QByteArray("1.2345x") << 0.0 << false; - QTest::newRow("high precision") << QByteArray("0.000000000931322574615478515625") - << 0.000000000931322574615478515625 << true; - - QTest::newRow("raw, null plus junk") << QByteArray::fromRawData("1.2\0 junk", 9) << 0.0 << false; - QTest::newRow("raw, null-terminator not included") << QByteArray::fromRawData("2.3", 3) << 2.3 << true; -} - -void tst_QByteArray::toDouble() -{ - QFETCH(QByteArray, string); - QFETCH(double, expectedNumber); - QFETCH(bool, expectedOk); - - bool ok; - const double number = string.toDouble(&ok); - - QCOMPARE(ok, expectedOk); - QCOMPARE(number, expectedNumber); -} - -void tst_QByteArray::toLong_data() -{ - QTest::addColumn<QByteArray>("str"); - QTest::addColumn<int>("base"); - QTest::addColumn<long>("result"); - QTest::addColumn<bool>("ok"); - - QTest::newRow("null") << QByteArray() << 10 << 0L << false; - QTest::newRow("empty") << QByteArray("") << 16 << 0L << false; - QTest::newRow("in range dec") << QByteArray("1608507359") << 10 << 1608507359L << true; - QTest::newRow("in range dec neg") << QByteArray("-1608507359") << 10 << -1608507359L << true; - QTest::newRow("in range hex") << QByteArray("12ABCDEF") << 16 << 0x12ABCDEFL << true; - QTest::newRow("in range hex neg") << QByteArray("-12ABCDEF") << 16 << -0x12ABCDEFL << true; - QTest::newRow("Fibonacci's last int32") << QByteArray("1836311903") << 10 << 1836311903L - << true; - - QTest::newRow("leading spaces") << QByteArray(" \r\n\tABC123") << 16 << 0xABC123L << true; - QTest::newRow("trailing spaces") << QByteArray("1234567\t\r \n") << 10 << 1234567L << true; - QTest::newRow("leading junk") << QByteArray("q12345") << 10 << 0L << false; - QTest::newRow("trailing junk") << QByteArray("abc12345t") << 16 << 0L << false; - - QTest::newRow("dec with base 0") << QByteArray("123") << 0 << 123L << true; - QTest::newRow("neg dec with base 0") << QByteArray("-123") << 0 << -123L << true; - QTest::newRow("hex with base 0") << QByteArray("0x123") << 0 << 0x123L << true; - QTest::newRow("neg hex with base 0") << QByteArray("-0x123") << 0 << -0x123L << true; - QTest::newRow("oct with base 0") << QByteArray("0123") << 0 << 0123L << true; - QTest::newRow("neg oct with base 0") << QByteArray("-0123") << 0 << -0123L << true; - - QTest::newRow("base 3") << QByteArray("12012") << 3 << 140L << true; - QTest::newRow("neg base 3") << QByteArray("-201") << 3 << -19L << true; - - using Bounds = std::numeric_limits<long>; - QTest::newRow("long max") << QByteArray::number(Bounds::max()) << 10 << Bounds::max() << true; - QTest::newRow("long min") << QByteArray::number(Bounds::min()) << 10 << Bounds::min() << true; - - using B32 = std::numeric_limits<qint32>; - QTest::newRow("int32 min bin") << (QByteArray("-1") + QByteArray(31, '0')) << 2 - << long(B32::min()) << true; - QTest::newRow("int32 max bin") << QByteArray(31, '1') << 2 << long(B32::max()) << true; - QTest::newRow("int32 min hex") << QByteArray("-80000000") << 16 << long(B32::min()) << true; - QTest::newRow("int32 max hex") << QByteArray("7fffffff") << 16 << long(B32::max()) << true; - QTest::newRow("int32 min dec") << QByteArray("-2147483648") << 10 << long(B32::min()) << true; - QTest::newRow("int32 max dec") << QByteArray("2147483647") << 10 << long(B32::max()) << true; - - if constexpr (sizeof(long) < sizeof(qlonglong)) { - const qlonglong longMaxPlusOne = static_cast<qlonglong>(Bounds::max()) + 1; - const qlonglong longMinMinusOne = static_cast<qlonglong>(Bounds::min()) - 1; - QTest::newRow("long max + 1") << QByteArray::number(longMaxPlusOne) << 10 << 0L << false; - QTest::newRow("long min - 1") << QByteArray::number(longMinMinusOne) << 10 << 0L << false; + QFETCH( QByteArray, expected ); + QCOMPARE(QByteArray::number(n, base), expected); + QCOMPARE(QByteArray::number(-n, base), '-' + expected); + + // check qlonglong->QByteArray->qlonglong round trip + for (int ibase = 2; ibase <= 36; ++ibase) { + auto stringrep = QByteArray::number(n, ibase); + QCOMPARE(QByteArray::number(-n, ibase), '-' + stringrep); + bool ok(false); + auto result = stringrep.toLongLong(&ok, ibase); + QVERIFY(ok); + QCOMPARE(n, result); } -} - -void tst_QByteArray::toLong() -{ - QFETCH(QByteArray, str); - QFETCH(int, base); - QFETCH(long, result); - QFETCH(bool, ok); - - bool b; - QCOMPARE(str.toLong(nullptr, base), result); - QCOMPARE(str.toLong(&b, base), result); - QCOMPARE(b, ok); - if (base == 10) { - // check that by default base is assumed to be 10 - QCOMPARE(str.toLong(&b), result); - QCOMPARE(b, ok); + if (n <= std::numeric_limits<int>::max()) { + QCOMPARE(QByteArray::number(int(n), base), expected); + QCOMPARE(QByteArray::number(int(-n), base), '-' + expected); + } else if (n <= std::numeric_limits<long>::max()) { + QCOMPARE(QByteArray::number(long(n), base), expected); + QCOMPARE(QByteArray::number(long(-n), base), '-' + expected); } } -void tst_QByteArray::toULong_data() +void tst_QByteArray::nullness() { - QTest::addColumn<QByteArray>("str"); - QTest::addColumn<int>("base"); - QTest::addColumn<ulong>("result"); - QTest::addColumn<bool>("ok"); - - ulong LongMaxPlusOne = (ulong)LONG_MAX + 1; - QTest::newRow("LONG_MAX+1") << QString::number(LongMaxPlusOne).toUtf8() << 10 << LongMaxPlusOne << true; - QTest::newRow("null") << QByteArray() << 10 << 0UL << false; - QTest::newRow("empty") << QByteArray("") << 10 << 0UL << false; - QTest::newRow("ulong1") << QByteArray("3234567890") << 10 << 3234567890UL << true; - QTest::newRow("ulong2") << QByteArray("fFFfFfFf") << 16 << 0xFFFFFFFFUL << true; - - QTest::newRow("leading spaces") << QByteArray(" \n\r\t100") << 10 << 100UL << true; - QTest::newRow("trailing spaces") << QByteArray("100 \n\r\t") << 10 << 100UL << true; - QTest::newRow("leading junk") << QByteArray("x100") << 10 << 0UL << false; - QTest::newRow("trailing junk") << QByteArray("100x") << 10 << 0UL << false; -} - -void tst_QByteArray::toULong() -{ - QFETCH(QByteArray, str); - QFETCH(int, base); - QFETCH(ulong, result); - QFETCH(bool, ok); - - bool b; - QCOMPARE(str.toULong(0, base), result); - QCOMPARE(str.toULong(&b, base), result); - QCOMPARE(b, ok); -} - -void tst_QByteArray::toLongLong_data() -{ - QTest::addColumn<QByteArray>("str"); - QTest::addColumn<int>("base"); - QTest::addColumn<qlonglong>("result"); - QTest::addColumn<bool>("ok"); - - QTest::newRow("null") << QByteArray() << 10 << 0LL << false; - QTest::newRow("empty") << QByteArray("") << 10 << 0LL << false; - QTest::newRow("out of base bound") << QByteArray("c") << 10 << 0LL << false; - - QTest::newRow("in range dec") << QByteArray("7679359922672374856") << 10 - << 7679359922672374856LL << true; - QTest::newRow("in range dec neg") << QByteArray("-7679359922672374856") << 10 - << -7679359922672374856LL << true; - QTest::newRow("in range hex") << QByteArray("6A929129A5421448") << 16 << 0x6A929129A5421448LL - << true; - QTest::newRow("in range hex neg") << QByteArray("-6A929129A5421448") << 16 - << -0x6A929129A5421448LL << true; - QTest::newRow("Fibonacci's last int64") << QByteArray("7540113804746346429") << 10 - << 7540113804746346429LL << true; - - QTest::newRow("leading spaces") << QByteArray(" \r\n\tABCFFFFFFF123") << 16 - << 0xABCFFFFFFF123LL << true; - QTest::newRow("trailing spaces") << QByteArray("9876543210\t\r \n") << 10 - << 9876543210LL << true; - QTest::newRow("leading junk") << QByteArray("q12345") << 10 << 0LL << false; - QTest::newRow("trailing junk") << QByteArray("abc12345t") << 16 << 0LL << false; - - QTest::newRow("dec with base 0") << QByteArray("9876543210") << 0 << 9876543210LL << true; - QTest::newRow("neg dec with base 0") << QByteArray("-9876543210") << 0 << -9876543210LL << true; - QTest::newRow("hex with base 0") << QByteArray("0x9876543210") << 0 << 0x9876543210LL << true; - QTest::newRow("neg hex with base 0") << QByteArray("-0x9876543210") << 0 << -0x9876543210LL - << true; - QTest::newRow("oct with base 0") << QByteArray("07654321234567") << 0 << 07654321234567LL - << true; - QTest::newRow("neg oct with base 0") << QByteArray("-07654321234567") << 0 << -07654321234567LL - << true; - - QTest::newRow("base 3") << QByteArray("12012") << 3 << 140LL << true; - QTest::newRow("neg base 3") << QByteArray("-201") << 3 << -19LL << true; - - QTest::newRow("max dec") << QByteArray("9223372036854775807") << 10 << 9223372036854775807LL - << true; - QTest::newRow("mix hex") << QByteArray("-7FFFFFFFFFFFFFFF") << 16 << -0x7FFFFFFFFFFFFFFFLL - << true; - - QTest::newRow("max + 1 dec") << QByteArray("9223372036854775808") << 10 << 0LL << false; - QTest::newRow("min - 1 hex") << QByteArray("-8000000000000001") << 16 << 0LL << false; -} - -void tst_QByteArray::toLongLong() -{ - QFETCH(QByteArray, str); - QFETCH(int, base); - QFETCH(qlonglong, result); - QFETCH(bool, ok); - - bool b; - QCOMPARE(str.toLongLong(nullptr, base), result); - QCOMPARE(str.toLongLong(&b, base), result); - QCOMPARE(b, ok); - if (base == 10) { - QCOMPARE(str.toLongLong(&b), result); - QCOMPARE(b, ok); + { + QByteArray ba; + QVERIFY(ba.isNull()); + } + { + QByteArray ba = nullptr; + QVERIFY(ba.isNull()); + } + { + const char *ptr = nullptr; + QByteArray ba = ptr; + QVERIFY(ba.isNull()); + } + { + QByteArray ba(nullptr, 0); + QVERIFY(ba.isNull()); + } + { + const char *ptr = nullptr; + QByteArray ba(ptr, 0); + QVERIFY(ba.isNull()); + } + { + QByteArrayView bav; + QVERIFY(bav.isNull()); + QByteArray ba = bav.toByteArray(); + QVERIFY(ba.isNull()); } -} - -void tst_QByteArray::toULongLong_data() -{ - QTest::addColumn<QByteArray>("str"); - QTest::addColumn<int>("base"); - QTest::addColumn<qulonglong>("result"); - QTest::addColumn<bool>("ok"); - - QTest::newRow("null") << QByteArray() << 10 << (qulonglong)0 << false; - QTest::newRow("empty") << QByteArray("") << 10 << (qulonglong)0 << false; - QTest::newRow("out of base bound") << QByteArray("c") << 10 << (qulonglong)0 << false; - - QTest::newRow("leading spaces") << QByteArray(" \n\r\t100") << 10 << qulonglong(100) << true; - QTest::newRow("trailing spaces") << QByteArray("100 \n\r\t") << 10 << qulonglong(100) << true; - QTest::newRow("leading junk") << QByteArray("x100") << 10 << qulonglong(0) << false; - QTest::newRow("trailing junk") << QByteArray("100x") << 10 << qulonglong(0) << false; -} - -void tst_QByteArray::toULongLong() -{ - QFETCH(QByteArray, str); - QFETCH(int, base); - QFETCH(qulonglong, result); - QFETCH(bool, ok); - - bool b; - QCOMPARE(str.toULongLong(0, base), result); - QCOMPARE(str.toULongLong(&b, base), result); - QCOMPARE(b, ok); } static bool checkSize(qsizetype value, qsizetype min) @@ -1716,7 +1638,7 @@ void tst_QByteArray::blockSizeCalculations() QCOMPARE(qCalculateGrowingBlockSize(MaxAllocSize/2, 2, 1).elementCount, qsizetype(MaxAllocSize)/2); // error conditions - QCOMPARE(qCalculateBlockSize(qint64(MaxAllocSize) + 1, 1), qsizetype(-1)); + QCOMPARE(qCalculateBlockSize(quint64(MaxAllocSize) + 1, 1), qsizetype(-1)); QCOMPARE(qCalculateBlockSize(qsizetype(-1), 1), qsizetype(-1)); QCOMPARE(qCalculateBlockSize(MaxAllocSize, 1, 1), qsizetype(-1)); QCOMPARE(qCalculateBlockSize(MaxAllocSize/2 + 1, 2), qsizetype(-1)); @@ -1773,7 +1695,8 @@ void tst_QByteArray::blockSizeCalculations() QVERIFY(checkSize(alloc, qsizetype(MaxAllocSize) / elementSize)); // the next allocation should be invalid - QCOMPARE(qCalculateGrowingBlockSize(alloc + 1, elementSize).size, qsizetype(-1)); + if (alloc < MaxAllocSize) // lest alloc + 1 overflows (= UB) + QCOMPARE(qCalculateGrowingBlockSize(alloc + 1, elementSize).size, qsizetype(-1)); } } @@ -1789,17 +1712,6 @@ void tst_QByteArray::resizeAfterFromRawData() QVERIFY(array.constData()[5] == 0); } -void tst_QByteArray::appendAfterFromRawData() -{ - QByteArray arr; - { - char data[] = "X"; - arr += QByteArray::fromRawData(data, sizeof(data)); - data[0] = 'Y'; - } - QCOMPARE(arr.at(0), 'X'); -} - void tst_QByteArray::toFromHex_data() { QTest::addColumn<QByteArray>("str"); @@ -1879,7 +1791,7 @@ void tst_QByteArray::toFromHex_data() << QByteArray("af") << QByteArray("xaf"); - QTest::newRow("no-leading-zero") + QTest::newRow("no-leading-zero-long") << QByteArray("\xd\xde\xad\xc0\xde") << '\0' << QByteArray("0ddeadc0de") @@ -1940,16 +1852,16 @@ void tst_QByteArray::toFromPercentEncoding() QCOMPARE(QByteArray("").toPercentEncoding(), QByteArray("")); QByteArray data = arr.toPercentEncoding(); - QCOMPARE(QString(data), QString("Qt%20is%20great%21")); - QCOMPARE(QByteArray::fromPercentEncoding(data), arr); + QCOMPARE(data, QByteArray("Qt%20is%20great%21")); + QCOMPARE(data.percentDecoded(), arr); data = arr.toPercentEncoding("! ", "Qt"); - QCOMPARE(QString(data), QString("%51%74 is grea%74!")); - QCOMPARE(QByteArray::fromPercentEncoding(data), arr); + QCOMPARE(data, QByteArray("%51%74 is grea%74!")); + QCOMPARE(data.percentDecoded(), arr); data = arr.toPercentEncoding(QByteArray(), "abcdefghijklmnopqrstuvwxyz", 'Q'); - QCOMPARE(QString(data), QString("Q51Q74Q20Q69Q73Q20Q67Q72Q65Q61Q74Q21")); - QCOMPARE(QByteArray::fromPercentEncoding(data, 'Q'), arr); + QCOMPARE(data, QByteArray("Q51Q74Q20Q69Q73Q20Q67Q72Q65Q61Q74Q21")); + QCOMPARE(data.percentDecoded('Q'), arr); // verify that to/from percent encoding preserves nullity arr = ""; @@ -1965,8 +1877,16 @@ void tst_QByteArray::toFromPercentEncoding() QVERIFY(arr.isNull()); QVERIFY(arr.toPercentEncoding().isEmpty()); QVERIFY(arr.toPercentEncoding().isNull()); - QVERIFY(QByteArray::fromPercentEncoding(QByteArray()).isEmpty()); - QVERIFY(QByteArray::fromPercentEncoding(QByteArray()).isNull()); + QVERIFY(QByteArray().percentDecoded().isEmpty()); + QVERIFY(QByteArray().percentDecoded().isNull()); + + // Verify that literal % in the string to be encoded does round-trip: + arr = "Qt%20is%20great%21"; + data = arr.toPercentEncoding(); + QCOMPARE(data.percentDecoded(), arr); + arr = "87% of all statistics are made up!"; + data = arr.toPercentEncoding(); + QCOMPARE(data.percentDecoded(), arr); } void tst_QByteArray::fromPercentEncoding_data() @@ -1988,7 +1908,7 @@ void tst_QByteArray::fromPercentEncoding() QFETCH(QByteArray, encodedString); QFETCH(QByteArray, decodedString); - QCOMPARE(QByteArray::fromPercentEncoding(encodedString), decodedString); + QCOMPARE(encodedString.percentDecoded(), decodedString); } void tst_QByteArray::toPercentEncoding_data() @@ -2013,36 +1933,34 @@ void tst_QByteArray::toPercentEncoding() QCOMPARE(decodedString.toPercentEncoding("/.").constData(), encodedString.constData()); } -void tst_QByteArray::toPercentEncoding2_data() +void tst_QByteArray::pecentEncodingRoundTrip_data() { QTest::addColumn<QByteArray>("original"); QTest::addColumn<QByteArray>("encoded"); QTest::addColumn<QByteArray>("excludeInEncoding"); QTest::addColumn<QByteArray>("includeInEncoding"); - QTest::newRow("test_01") << QByteArray("abcdevghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345678-._~") - << QByteArray("abcdevghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345678-._~") - << QByteArray("") - << QByteArray(""); - QTest::newRow("test_02") << QByteArray("{\t\n\r^\"abc}") - << QByteArray("%7B%09%0A%0D%5E%22abc%7D") - << QByteArray("") - << QByteArray(""); - QTest::newRow("test_03") << QByteArray("://?#[]@!$&'()*+,;=") - << QByteArray("%3A%2F%2F%3F%23%5B%5D%40%21%24%26%27%28%29%2A%2B%2C%3B%3D") - << QByteArray("") - << QByteArray(""); - QTest::newRow("test_04") << QByteArray("://?#[]@!$&'()*+,;=") - << QByteArray("%3A%2F%2F%3F%23%5B%5D%40!$&'()*+,;=") - << QByteArray("!$&'()*+,;=") - << QByteArray(""); - QTest::newRow("test_05") << QByteArray("abcd") - << QByteArray("a%62%63d") - << QByteArray("") - << QByteArray("bc"); -} - -void tst_QByteArray::toPercentEncoding2() + QTest::newRow("unchanged") + << QByteArray("abcdevghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345678-._~") + << QByteArray("abcdevghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345678-._~") + << QByteArray("") << QByteArray(""); + QTest::newRow("enclosed-space-quote") + << QByteArray("{\t\n\r^\"abc}") + << QByteArray("%7B%09%0A%0D%5E%22abc%7D") + << QByteArray("") << QByteArray(""); + QTest::newRow("punctuate") + << QByteArray("://?#[]@!$&'()*+,;=") + << QByteArray("%3A%2F%2F%3F%23%5B%5D%40%21%24%26%27%28%29%2A%2B%2C%3B%3D") + << QByteArray("") << QByteArray(""); + QTest::newRow("punctuate-exclude") + << QByteArray("://?#[]@!$&'()*+,;=") + << QByteArray("%3A%2F%2F%3F%23%5B%5D%40!$&'()*+,;=") + << QByteArray("!$&'()*+,;=") << QByteArray(""); + QTest::newRow("text-include") + << QByteArray("abcd") << QByteArray("a%62%63d") << QByteArray("") << QByteArray("bc"); +} + +void tst_QByteArray::pecentEncodingRoundTrip() { QFETCH(QByteArray, original); QFETCH(QByteArray, encoded); @@ -2050,8 +1968,8 @@ void tst_QByteArray::toPercentEncoding2() QFETCH(QByteArray, includeInEncoding); QByteArray encodedData = original.toPercentEncoding(excludeInEncoding, includeInEncoding); - QCOMPARE(encodedData.constData(), encoded.constData()); - QCOMPARE(original, QByteArray::fromPercentEncoding(encodedData)); + QCOMPARE(encodedData, encoded); + QCOMPARE(encodedData.percentDecoded(), original); } struct StringComparisonData @@ -2134,52 +2052,49 @@ void tst_QByteArray::compare_singular() void tst_QByteArray::compareCharStar_data() { QTest::addColumn<QByteArray>("str1"); - QTest::addColumn<QString>("string2"); + QTest::addColumn<QByteArray>("string2"); QTest::addColumn<int>("result"); - QTest::newRow("null-null") << QByteArray() << QString() << 0; - QTest::newRow("null-empty") << QByteArray() << "" << 0; - QTest::newRow("null-full") << QByteArray() << "abc" << -1; - QTest::newRow("empty-null") << QByteArray("") << QString() << 0; - QTest::newRow("empty-empty") << QByteArray("") << "" << 0; - QTest::newRow("empty-full") << QByteArray("") << "abc" << -1; - QTest::newRow("raw-null") << QByteArray::fromRawData("abc", 0) << QString() << 0; - QTest::newRow("raw-empty") << QByteArray::fromRawData("abc", 0) << QString("") << 0; - QTest::newRow("raw-full") << QByteArray::fromRawData("abc", 0) << "abc" << -1; + QTest::newRow("null-null") << QByteArray() << QByteArray() << 0; + QTest::newRow("null-empty") << QByteArray() << QByteArray("") << 0; + QTest::newRow("null-full") << QByteArray() << QByteArray("abc") << -1; + QTest::newRow("empty-null") << QByteArray("") << QByteArray() << 0; + QTest::newRow("empty-empty") << QByteArray("") << QByteArray("") << 0; + QTest::newRow("empty-full") << QByteArray("") << QByteArray("abc") << -1; + QTest::newRow("raw-null") << QByteArray::fromRawData("abc", 0) << QByteArray() << 0; + QTest::newRow("raw-empty") << QByteArray::fromRawData("abc", 0) << QByteArray("") << 0; + QTest::newRow("raw-full") << QByteArray::fromRawData("abc", 0) << QByteArray("abc") << -1; - QTest::newRow("full-null") << QByteArray("abc") << QString() << +1; - QTest::newRow("full-empty") << QByteArray("abc") << "" << +1; + QTest::newRow("full-null") << QByteArray("abc") << QByteArray() << +1; + QTest::newRow("full-empty") << QByteArray("abc") << QByteArray("") << +1; - QTest::newRow("equal1") << QByteArray("abc") << "abc" << 0; - QTest::newRow("equal2") << QByteArray("abcd", 3) << "abc" << 0; - QTest::newRow("equal3") << QByteArray::fromRawData("abcd", 3) << "abc" << 0; + QTest::newRow("equal1") << QByteArray("abc") << QByteArray("abc") << 0; + QTest::newRow("equal2") << QByteArray("abcd", 3) << QByteArray("abc") << 0; + QTest::newRow("equal3") << QByteArray::fromRawData("abcd", 3) << QByteArray("abc") << 0; - QTest::newRow("less1") << QByteArray("ab") << "abc" << -1; - QTest::newRow("less2") << QByteArray("abb") << "abc" << -1; - QTest::newRow("less3") << QByteArray::fromRawData("abc", 2) << "abc" << -1; - QTest::newRow("less4") << QByteArray("", 1) << "abc" << -1; - QTest::newRow("less5") << QByteArray::fromRawData("", 1) << "abc" << -1; - QTest::newRow("less6") << QByteArray("a\0bc", 4) << "a.bc" << -1; + QTest::newRow("less1") << QByteArray("ab") << QByteArray("abc") << -1; + QTest::newRow("less2") << QByteArray("abb") << QByteArray("abc") << -1; + QTest::newRow("less3") << QByteArray::fromRawData("abc", 2) << QByteArray("abc") << -1; + QTest::newRow("less4") << QByteArray("", 1) << QByteArray("abc") << -1; + QTest::newRow("less5") << QByteArray::fromRawData("", 1) << QByteArray("abc") << -1; + QTest::newRow("less6") << QByteArray("a\0bc", 4) << QByteArray("a.bc") << -1; - QTest::newRow("greater1") << QByteArray("ac") << "abc" << +1; - QTest::newRow("greater2") << QByteArray("abd") << "abc" << +1; - QTest::newRow("greater3") << QByteArray("abcd") << "abc" << +1; - QTest::newRow("greater4") << QByteArray::fromRawData("abcd", 4) << "abc" << +1; + QTest::newRow("greater1") << QByteArray("ac") << QByteArray("abc") << +1; + QTest::newRow("greater2") << QByteArray("abd") << QByteArray("abc") << +1; + QTest::newRow("greater3") << QByteArray("abcd") << QByteArray("abc") << +1; + QTest::newRow("greater4") << QByteArray::fromRawData("abcd", 4) << QByteArray("abc") << +1; } void tst_QByteArray::compareCharStar() { QFETCH(QByteArray, str1); - QFETCH(QString, string2); + QFETCH(QByteArray, string2); QFETCH(int, result); const bool isEqual = result == 0; const bool isLess = result < 0; const bool isGreater = result > 0; - QByteArray qba = string2.toUtf8(); - const char *str2 = qba.constData(); - if (string2.isNull()) - str2 = 0; + const char *str2 = string2.isNull() ? nullptr : string2.constData(); // basic tests: QCOMPARE(str1 == str2, isEqual); @@ -2377,9 +2292,26 @@ void tst_QByteArray::reserveExtended() QCOMPARE(array.capacity(), array.size()); } -void tst_QByteArray::movablity_data() +void tst_QByteArray::resize() { - QTest::addColumn<QByteArray>("array"); + QByteArray ba; + ba.resize(15); + QCOMPARE(ba.size(), qsizetype(15)); + ba.resize(10); + QCOMPARE(ba.size(), 10); + ba.resize(0); + QCOMPARE(ba.size(), 0); + ba.resize(5, 'a'); + QCOMPARE(ba.size(), 5); + QCOMPARE(ba, "aaaaa"); + ba.resize(10, 'b'); + QCOMPARE(ba.size(), 10); + QCOMPARE(ba, "aaaaabbbbb"); +} + +void tst_QByteArray::movability_data() +{ + prependExtended_data(); QTest::newRow("0x00000000") << QByteArray("\x00\x00\x00\x00", 4); QTest::newRow("0x000000ff") << QByteArray("\x00\x00\x00\xff", 4); @@ -2387,11 +2319,9 @@ void tst_QByteArray::movablity_data() QTest::newRow("empty") << QByteArray(""); QTest::newRow("null") << QByteArray(); QTest::newRow("sss") << QByteArray(3, 's'); - - prependExtended_data(); } -void tst_QByteArray::movablity() +void tst_QByteArray::movability() { QFETCH(QByteArray, array); @@ -2462,7 +2392,7 @@ void tst_QByteArray::literals() { QByteArray str(QByteArrayLiteral("abcd")); - QVERIFY(str.length() == 4); + QVERIFY(str.size() == 4); QCOMPARE(str.capacity(), 0); QVERIFY(str == "abcd"); QVERIFY(!str.data_ptr()->isMutable()); @@ -2474,34 +2404,60 @@ void tst_QByteArray::literals() // detach on non const access QVERIFY(str.data() != s); - QVERIFY(str.capacity() >= str.length()); + QVERIFY(str.capacity() >= str.size()); QVERIFY(str2.constData() == s); QVERIFY(str2.data() != s); - QVERIFY(str2.capacity() >= str2.length()); + QVERIFY(str2.capacity() >= str2.size()); } void tst_QByteArray::userDefinedLiterals() { - QByteArray str = "abcd"_qba; + { + QByteArray str = "abcd"_ba; - QVERIFY(str.length() == 4); - QCOMPARE(str.capacity(), 0); - QVERIFY(str == "abcd"); - QVERIFY(!str.data_ptr()->isMutable()); + QVERIFY(str.size() == 4); + QCOMPARE(str.capacity(), 0); + QVERIFY(str == "abcd"); + QVERIFY(!str.data_ptr()->isMutable()); - const char *s = str.constData(); - QByteArray str2 = str; - QVERIFY(str2.constData() == s); - QCOMPARE(str2.capacity(), 0); + const char *s = str.constData(); + QByteArray str2 = str; + QVERIFY(str2.constData() == s); + QCOMPARE(str2.capacity(), 0); - // detach on non const access - QVERIFY(str.data() != s); - QVERIFY(str.capacity() >= str.length()); + // detach on non const access + QVERIFY(str.data() != s); + QVERIFY(str.capacity() >= str.size()); - QVERIFY(str2.constData() == s); - QVERIFY(str2.data() != s); - QVERIFY(str2.capacity() >= str2.length()); + QVERIFY(str2.constData() == s); + QVERIFY(str2.data() != s); + QVERIFY(str2.capacity() >= str2.size()); + } + +#if QT_DEPRECATED_SINCE(6, 8) + { + QT_IGNORE_DEPRECATIONS(QByteArray str = "abcd"_qba;) + + QVERIFY(str.size() == 4); + QCOMPARE(str.capacity(), 0); + QVERIFY(str == "abcd"); + QVERIFY(!str.data_ptr()->isMutable()); + + const char *s = str.constData(); + QByteArray str2 = str; + QVERIFY(str2.constData() == s); + QCOMPARE(str2.capacity(), 0); + + // detach on non const access + QVERIFY(str.data() != s); + QVERIFY(str.capacity() >= str.size()); + + QVERIFY(str2.constData() == s); + QVERIFY(str2.data() != s); + QVERIFY(str2.capacity() >= str2.size()); + } +#endif // QT_DEPRECATED_SINCE(6, 8) } void tst_QByteArray::toUpperLower_data() @@ -2534,10 +2490,16 @@ void tst_QByteArray::toUpperLower() QFETCH(QByteArray, input); QFETCH(QByteArray, upper); QFETCH(QByteArray, lower); + QVERIFY(upper.isUpper()); + QVERIFY(lower.isLower()); QCOMPARE(lower.toLower(), lower); + QVERIFY(lower.toLower().isLower()); QCOMPARE(upper.toUpper(), upper); + QVERIFY(upper.toUpper().isUpper()); QCOMPARE(input.toUpper(), upper); + QVERIFY(input.toUpper().isUpper()); QCOMPARE(input.toLower(), lower); + QVERIFY(input.toLower().isLower()); QByteArray copy = input; QCOMPARE(std::move(copy).toUpper(), upper); @@ -2566,12 +2528,12 @@ void tst_QByteArray::toUpperLower() void tst_QByteArray::isUpper() { - QVERIFY(!QByteArray().isUpper()); - QVERIFY(!QByteArray("").isUpper()); + QVERIFY(QByteArray().isUpper()); + QVERIFY(QByteArray("").isUpper()); QVERIFY(QByteArray("TEXT").isUpper()); - QVERIFY(!QByteArray("\xD0\xDE").isUpper()); // non-ASCII is neither upper nor lower - QVERIFY(!QByteArray("\xD7").isUpper()); - QVERIFY(!QByteArray("\xDF").isUpper()); + QVERIFY(QByteArray("\xD0\xDE").isUpper()); + QVERIFY(QByteArray("\xD7").isUpper()); + QVERIFY(QByteArray("\xDF").isUpper()); QVERIFY(!QByteArray("text").isUpper()); QVERIFY(!QByteArray("Text").isUpper()); QVERIFY(!QByteArray("tExt").isUpper()); @@ -2581,19 +2543,19 @@ void tst_QByteArray::isUpper() QVERIFY(!QByteArray("teXT").isUpper()); QVERIFY(!QByteArray("tEXt").isUpper()); QVERIFY(!QByteArray("tExT").isUpper()); - QVERIFY(!QByteArray("@ABYZ[").isUpper()); + QVERIFY(QByteArray("@ABYZ[").isUpper()); QVERIFY(!QByteArray("@abyz[").isUpper()); - QVERIFY(!QByteArray("`ABYZ{").isUpper()); + QVERIFY(QByteArray("`ABYZ{").isUpper()); QVERIFY(!QByteArray("`abyz{").isUpper()); } void tst_QByteArray::isLower() { - QVERIFY(!QByteArray().isLower()); - QVERIFY(!QByteArray("").isLower()); + QVERIFY(QByteArray().isLower()); + QVERIFY(QByteArray("").isLower()); QVERIFY(QByteArray("text").isLower()); - QVERIFY(!QByteArray("\xE0\xFF").isLower()); // non-ASCII is neither upper nor lower - QVERIFY(!QByteArray("\xF7").isLower()); + QVERIFY(QByteArray("\xE0\xFF").isLower()); + QVERIFY(QByteArray("\xF7").isLower()); QVERIFY(!QByteArray("Text").isLower()); QVERIFY(!QByteArray("tExt").isLower()); QVERIFY(!QByteArray("teXt").isLower()); @@ -2604,14 +2566,14 @@ void tst_QByteArray::isLower() QVERIFY(!QByteArray("tExT").isLower()); QVERIFY(!QByteArray("TEXT").isLower()); QVERIFY(!QByteArray("@ABYZ[").isLower()); - QVERIFY(!QByteArray("@abyz[").isLower()); + QVERIFY(QByteArray("@abyz[").isLower()); QVERIFY(!QByteArray("`ABYZ{").isLower()); - QVERIFY(!QByteArray("`abyz{").isLower()); + QVERIFY(QByteArray("`abyz{").isLower()); } void tst_QByteArray::macTypes() { -#ifndef Q_OS_MAC +#ifndef Q_OS_DARWIN QSKIP("This is a Apple-only test"); #else extern void tst_QByteArray_macTypes(); // in qbytearray_mac.mm @@ -2624,7 +2586,7 @@ void tst_QByteArray::stdString() std::string stdstr( "QByteArray" ); const QByteArray stlqt = QByteArray::fromStdString(stdstr); - QCOMPARE(stlqt.length(), int(stdstr.length())); + QCOMPARE(stlqt.size(), int(stdstr.length())); QCOMPARE(stlqt.data(), stdstr.c_str()); QCOMPARE(stlqt.toStdString(), stdstr); @@ -2719,30 +2681,37 @@ void tst_QByteArray::truncate() QVERIFY(a.isEmpty()); } -void tst_QByteArray::trimmed() +void tst_QByteArray::trimmed_data() { - QFETCH(QByteArray, source); - QFETCH(QByteArray, expected); + QTest::addColumn<QByteArray>("full" ); + QTest::addColumn<QByteArray>("trimmed" ); - QCOMPARE(source.trimmed(), expected); - QByteArray copy = source; - QCOMPARE(std::move(copy).trimmed(), expected); - - if (source.isEmpty()) - QVERIFY(!source.isDetached()); + QTest::addRow("null") << QByteArray() << QByteArray(); + QTest::addRow("simple") << "Text"_ba << "Text"_ba; + QTest::addRow("single-space") << " "_ba << ""_ba; + QTest::addRow("single-char") << " a "_ba << "a"_ba; + QTest::addRow("mixed") << " a \n\t\v b "_ba << "a \n\t\v b"_ba; } -void tst_QByteArray::trimmed_data() +void tst_QByteArray::trimmed() { - QTest::addColumn<QByteArray>("source"); - QTest::addColumn<QByteArray>("expected"); + QFETCH(QByteArray, full); + QFETCH(QByteArray, trimmed); - QTest::newRow("null") << QByteArray() << QByteArray(); - QTest::newRow("empty") << QByteArray("") << QByteArray(""); - QTest::newRow("no spaces") << QByteArray("a b\nc\td") << QByteArray("a b\nc\td"); - QTest::newRow("with spaces") << QByteArray("\t \v a b\r\nc \td\ve f \r\n\f") - << QByteArray("a b\r\nc \td\ve f"); - QTest::newRow("all spaces") << QByteArray("\t \r \n \v \f") << QByteArray(""); + // Shared + if (!full.isNull()) + QVERIFY(!full.isDetached()); + QCOMPARE(full.trimmed(), trimmed); // lvalue + QCOMPARE(QByteArray(full).trimmed(), trimmed); // rvalue + QCOMPARE(full.isNull(), trimmed.isNull()); + + // Not shared + full = QByteArrayView(full).toByteArray(); + if (!full.isNull()) + QVERIFY(full.isDetached()); + QCOMPARE(full.trimmed(), trimmed); // lvalue + QCOMPARE(QByteArray(full).trimmed(), trimmed); // rvalue + QCOMPARE(full.isNull(), trimmed.isNull()); } void tst_QByteArray::simplified() @@ -2774,45 +2743,99 @@ void tst_QByteArray::simplified_data() void tst_QByteArray::left() { QByteArray a; + QCOMPARE(QByteArray().left(0), QByteArray()); + QCOMPARE(QByteArray().left(10), QByteArray()); QCOMPARE(a.left(0), QByteArray()); QCOMPARE(a.left(10), QByteArray()); QVERIFY(!a.isDetached()); + QCOMPARE(QByteArray(a).left(0), QByteArray()); + QCOMPARE(QByteArray(a).left(10), QByteArray()); + QCOMPARE(detached(a).left(0), QByteArray()); + QCOMPARE(detached(a).left(10), QByteArray()); a = QByteArray("abcdefgh"); const char *ptr = a.constData(); + + // lvalue QCOMPARE(a.left(5), QByteArray("abcde")); QCOMPARE(a.left(20), a); QCOMPARE(a.left(-5), QByteArray()); // calling left() does not modify the source array QCOMPARE(a.constData(), ptr); + + // rvalue, not detached + QCOMPARE(QByteArray(a).left(5), QByteArray("abcde")); + QCOMPARE(QByteArray(a).left(20), a); + QCOMPARE(QByteArray(a).left(-5), QByteArray()); + // calling left() does not modify the source array + QCOMPARE(a.constData(), ptr); + + // rvalue, detached + QCOMPARE(detached(a).left(5), QByteArray("abcde")); + QCOMPARE(detached(a).left(20), a); + QCOMPARE(detached(a).left(-5), QByteArray()); + // calling left() does not modify the source array + QCOMPARE(a.constData(), ptr); } void tst_QByteArray::right() { QByteArray a; + QCOMPARE(QByteArray().right(0), QByteArray()); + QCOMPARE(QByteArray().right(10), QByteArray()); QCOMPARE(a.right(0), QByteArray()); QCOMPARE(a.right(10), QByteArray()); QVERIFY(!a.isDetached()); + QCOMPARE(QByteArray(a).right(0), QByteArray()); + QCOMPARE(QByteArray(a).right(10), QByteArray()); + QCOMPARE(detached(a).right(0), QByteArray()); + QCOMPARE(detached(a).right(10), QByteArray()); a = QByteArray("abcdefgh"); const char *ptr = a.constData(); + + // lvalue QCOMPARE(a.right(5), QByteArray("defgh")); QCOMPARE(a.right(20), a); QCOMPARE(a.right(-5), QByteArray()); // calling right() does not modify the source array QCOMPARE(a.constData(), ptr); + + // rvalue, not detached + QCOMPARE(QByteArray(a).right(5), QByteArray("defgh")); + QCOMPARE(QByteArray(a).right(20), a); + QCOMPARE(QByteArray(a).right(-5), QByteArray()); + // calling right() does not modify the source array + QCOMPARE(a.constData(), ptr); + + // rvalue, detached + QCOMPARE(detached(a).right(5), QByteArray("defgh")); + QCOMPARE(detached(a).right(20), a); + QCOMPARE(detached(a).right(-5), QByteArray()); + // calling right() does not modify the source array + QCOMPARE(a.constData(), ptr); } void tst_QByteArray::mid() { QByteArray a; + QCOMPARE(QByteArray().mid(0), QByteArray()); + QCOMPARE(a.mid(0, 10), QByteArray()); QCOMPARE(a.mid(0), QByteArray()); QCOMPARE(a.mid(0, 10), QByteArray()); QCOMPARE(a.mid(10), QByteArray()); QVERIFY(!a.isDetached()); + QCOMPARE(QByteArray(a).mid(0), QByteArray()); + QCOMPARE(QByteArray(a).mid(0, 10), QByteArray()); + QCOMPARE(QByteArray(a).mid(10), QByteArray()); + QCOMPARE(detached(a).mid(0), QByteArray()); + QCOMPARE(detached(a).mid(0, 10), QByteArray()); + QCOMPARE(detached(a).mid(10), QByteArray()); a = QByteArray("abcdefgh"); const char *ptr = a.constData(); + + // lvalue QCOMPARE(a.mid(2), QByteArray("cdefgh")); QCOMPARE(a.mid(2, 3), QByteArray("cde")); QCOMPARE(a.mid(20), QByteArray()); @@ -2820,6 +2843,24 @@ void tst_QByteArray::mid() QCOMPARE(a.mid(-5, 8), QByteArray("abc")); // calling mid() does not modify the source array QCOMPARE(a.constData(), ptr); + + // rvalue, not detached + QCOMPARE(QByteArray(a).mid(2), QByteArray("cdefgh")); + QCOMPARE(QByteArray(a).mid(2, 3), QByteArray("cde")); + QCOMPARE(QByteArray(a).mid(20), QByteArray()); + QCOMPARE(QByteArray(a).mid(-5), QByteArray("abcdefgh")); + QCOMPARE(QByteArray(a).mid(-5, 8), QByteArray("abc")); + // calling mid() does not modify the source array + QCOMPARE(a.constData(), ptr); + + // rvalue, detached + QCOMPARE(detached(a).mid(2), QByteArray("cdefgh")); + QCOMPARE(detached(a).mid(2, 3), QByteArray("cde")); + QCOMPARE(detached(a).mid(20), QByteArray()); + QCOMPARE(detached(a).mid(-5), QByteArray("abcdefgh")); + QCOMPARE(detached(a).mid(-5, 8), QByteArray("abc")); + // calling mid() does not modify the source array + QCOMPARE(a.constData(), ptr); } void tst_QByteArray::length() @@ -2827,9 +2868,14 @@ void tst_QByteArray::length() QFETCH(QByteArray, src); QFETCH(qsizetype, res); - QCOMPARE(src.length(), res); QCOMPARE(src.size(), res); - QCOMPARE(src.count(), res); + QCOMPARE(src.size(), res); +#if QT_DEPRECATED_SINCE(6, 4) +QT_WARNING_PUSH +QT_WARNING_DISABLE_DEPRECATED + QCOMPARE(src.size(), res); +QT_WARNING_POP +#endif } void tst_QByteArray::length_data() @@ -2845,7 +2891,31 @@ void tst_QByteArray::length_data() QTest::newRow("with '\\0' no size") << QByteArray("abc\0def") << qsizetype(3); } -const char globalChar = '1'; +void tst_QByteArray::slice() const +{ + QByteArray a; + + a.slice(0); + QVERIFY(a.isEmpty()); + QVERIFY(a.isNull()); + a.slice(0, 0); + QVERIFY(a.isEmpty()); + QVERIFY(a.isNull()); + + a = "Five pineapples"; + + a.slice(5); + QCOMPARE_EQ(a, "pineapples"); + + a.slice(4, 3); + QCOMPARE_EQ(a, "app"); + + a.slice(a.size()); + QVERIFY(a.isEmpty()); + + a.slice(0, 0); + QVERIFY(a.isEmpty()); +} QTEST_MAIN(tst_QByteArray) #include "tst_qbytearray.moc" |