File indexing completed on 2024-05-19 04:39:27
0001 /* 0002 SPDX-FileCopyrightText: 2012-2013 Milian Wolff <mail@milianw.de> 0003 0004 SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0005 */ 0006 0007 #include "test_indexedstring.h" 0008 0009 #include <serialization/indexedstring.h> 0010 #include <serialization/referencecounting.h> 0011 0012 #include <QTest> 0013 0014 #include <cstddef> 0015 #include <utility> 0016 0017 QTEST_GUILESS_MAIN(TestIndexedString) 0018 0019 using namespace KDevelop; 0020 0021 void TestIndexedString::testUrl_data() 0022 { 0023 QTest::addColumn<QUrl>("url"); 0024 QTest::addColumn<QString>("string"); 0025 QTest::newRow("empty") << QUrl() << QString(); 0026 QTest::newRow("/") << QUrl::fromLocalFile(QStringLiteral("/")) << QStringLiteral("/"); 0027 QTest::newRow("/foo/bar") << QUrl::fromLocalFile(QStringLiteral("/foo/bar")) << QStringLiteral("/foo/bar"); 0028 QTest::newRow("http://foo.com/") << QUrl(QStringLiteral("http://foo.com/")) << QStringLiteral("http://foo.com/"); 0029 QTest::newRow("http://foo.com/bar/asdf") << QUrl(QStringLiteral("http://foo.com/bar/asdf")) << QStringLiteral( 0030 "http://foo.com/bar/asdf"); 0031 QTest::newRow("file:///bar/asdf") << QUrl(QStringLiteral("file:///bar/asdf")) << QStringLiteral("/bar/asdf"); 0032 0033 #ifdef Q_OS_WIN 0034 // Make sure we're not running into https://bugreports.qt.io/browse/QTBUG-41729 0035 QTest::newRow("file:///C:/bar/asdf") << QUrl("file:///C:/bar/asdf") << QStringLiteral("C:/bar/asdf"); 0036 #endif 0037 } 0038 0039 void TestIndexedString::testUrl() 0040 { 0041 QFETCH(QUrl, url); 0042 IndexedString indexed(url); 0043 QCOMPARE(indexed.toUrl(), url); 0044 QTEST(indexed.str(), "string"); 0045 } 0046 0047 void TestIndexedString::test() 0048 { 0049 QFETCH(QString, data); 0050 0051 IndexedString indexed(data); 0052 QCOMPARE(indexed.str(), data); 0053 QCOMPARE(indexed.index(), IndexedString::indexForString(data)); 0054 const auto byteArrayData = data.toUtf8(); 0055 QEXPECT_FAIL("char-utf8", "UTF-8 gets decoded and the char data is stored internally", Continue); 0056 QEXPECT_FAIL("string-utf8", "UTF-8 gets decoded and the char data is stored internally", Continue); 0057 QCOMPARE(indexed.length(), data.length()); 0058 // fallback until we rely on internal utf8 encoding 0059 QCOMPARE(indexed.length(), byteArrayData.length()); 0060 0061 QCOMPARE(indexed.byteArray(), byteArrayData); 0062 QVERIFY(!strncmp(indexed.c_str(), byteArrayData.data(), byteArrayData.length())); 0063 QCOMPARE(indexed.index(), IndexedString::indexForString(byteArrayData.data(), byteArrayData.length())); 0064 0065 IndexedString moved = std::move(indexed); 0066 QCOMPARE(moved.str(), data); 0067 } 0068 0069 void TestIndexedString::test_data() 0070 { 0071 QTest::addColumn<QString>("data"); 0072 0073 QTest::newRow("empty") << QString(); 0074 QTest::newRow("char-ascii") << QStringLiteral("a"); 0075 QTest::newRow("char-utf8") << QStringLiteral("ä"); 0076 QTest::newRow("string-ascii") << QStringLiteral("asdf()?="); 0077 QTest::newRow("string-utf8") << QStringLiteral("æſðđäöü"); 0078 } 0079 0080 void TestIndexedString::testMoveAssignment() 0081 { 0082 // Deliberately make no assumptions about the value of the moved-from object. 0083 0084 const QString text = QStringLiteral("random text"); 0085 IndexedString movedFrom(text); 0086 QCOMPARE(movedFrom.str(), text); 0087 0088 IndexedString notRefCounted; 0089 notRefCounted = std::move(movedFrom); 0090 QCOMPARE(notRefCounted.str(), text); 0091 0092 movedFrom = std::move(notRefCounted); 0093 QCOMPARE(movedFrom.str(), text); 0094 0095 const QString toBeDerefed = QStringLiteral("to-be-derefed"); 0096 0097 // Enable reference counting throughout refCounted's lifetime. 0098 std::byte indexedStringData[sizeof(IndexedString)]; 0099 const DUChainReferenceCountingEnabler rcEnabler(indexedStringData, sizeof(IndexedString)); 0100 IndexedString* const refCounted = new (indexedStringData) IndexedString(toBeDerefed); 0101 QCOMPARE(refCounted->str(), toBeDerefed); 0102 0103 *refCounted = std::move(movedFrom); 0104 QCOMPARE(refCounted->str(), text); 0105 refCounted->~IndexedString(); 0106 } 0107 0108 void TestIndexedString::testSwap() 0109 { 0110 QFETCH(bool, lhsRcEnabled); 0111 QFETCH(bool, rhsRcEnabled); 0112 0113 class OptionallyRcString 0114 { 0115 public: 0116 explicit OptionallyRcString(bool rcEnabled, const QString& initText) 0117 : m_rcEnabled{rcEnabled} 0118 , m_initText{initText} 0119 , m_notRefCounted{m_initText} 0120 , m_refCountedData{} 0121 , m_rcEnabler{m_refCountedData, sizeof(IndexedString)} 0122 , m_string{m_rcEnabled ? new (m_refCountedData) IndexedString(m_initText) : &m_notRefCounted} 0123 { 0124 QCOMPARE(m_string->str(), m_initText); 0125 } 0126 0127 ~OptionallyRcString() 0128 { 0129 if (m_rcEnabled) { 0130 m_string->~IndexedString(); 0131 } 0132 } 0133 0134 const QString& initText() const { return m_initText; } 0135 IndexedString& string() { return *m_string; } 0136 0137 private: 0138 const bool m_rcEnabled; 0139 const QString m_initText; 0140 0141 IndexedString m_notRefCounted; 0142 std::byte m_refCountedData[sizeof(IndexedString)]; 0143 const DUChainReferenceCountingEnabler m_rcEnabler; 0144 0145 IndexedString* const m_string = nullptr; 0146 }; 0147 0148 OptionallyRcString lhs(lhsRcEnabled, QStringLiteral("1st text")); 0149 OptionallyRcString rhs(rhsRcEnabled, QStringLiteral("another string")); 0150 0151 using std::swap; 0152 0153 swap(lhs.string(), rhs.string()); 0154 QCOMPARE(lhs.string().str(), rhs.initText()); 0155 QCOMPARE(rhs.string().str(), lhs.initText()); 0156 0157 swap(lhs.string(), rhs.string()); 0158 QCOMPARE(lhs.string().str(), lhs.initText()); 0159 QCOMPARE(rhs.string().str(), rhs.initText()); 0160 } 0161 0162 void TestIndexedString::testSwap_data() 0163 { 0164 QTest::addColumn<bool>("lhsRcEnabled"); 0165 QTest::addColumn<bool>("rhsRcEnabled"); 0166 0167 QTest::newRow("no reference counting") << false << false; 0168 QTest::newRow("lhs reference-counted") << true << false; 0169 QTest::newRow("rhs reference-counted") << false << true; 0170 QTest::newRow("both reference-counted") << true << true; 0171 } 0172 0173 void TestIndexedString::testCString() 0174 { 0175 IndexedString str(nullptr); 0176 QCOMPARE(str.index(), 0u); 0177 QVERIFY(str.isEmpty()); 0178 } 0179 0180 #include "moc_test_indexedstring.cpp"