File indexing completed on 2024-05-12 05:55:44
0001 /* 0002 * This file is part of the Okteta Kasten module, made within the KDE community. 0003 * 0004 * SPDX-FileCopyrightText: 2012 Alex Richardson <alex.richardson@gmx.de> 0005 * 0006 * SPDX-License-Identifier: LGPL-2.1-or-later 0007 */ 0008 0009 #include "view/structures/datatypes/primitive/primitivetemplateinfo.hpp" 0010 #include "view/structures/datatypes/primitive/primitivedatainformation.hpp" 0011 #include "view/structures/datatypes/primitive/bitfield/signedbitfielddatainformation.hpp" 0012 #include "view/structures/datatypes/primitive/bitfield/unsignedbitfielddatainformation.hpp" 0013 #include "view/structures/datatypes/primitive/bitfield/boolbitfielddatainformation.hpp" 0014 #include "view/structures/datatypes/primitivefactory.hpp" 0015 #include "structureviewpreferences.hpp" 0016 // Okteta 0017 #include <Okteta/ByteArrayModel> 0018 // KF 0019 #include <KLocalizedString> 0020 // Qt 0021 #include <QTest> 0022 #include <QtGlobal> 0023 #include <QLocale> 0024 // Std 0025 #include <memory> 0026 #include <limits> 0027 0028 inline uint qHash(PrimitiveDataType type) 0029 { 0030 return ::qHash(static_cast<int>(type)); 0031 } 0032 0033 class PrimitiveDataInformationTest : public QObject 0034 { 0035 Q_OBJECT 0036 0037 private: 0038 template <typename s, typename u> 0039 void addRowsGetAndSetSigned(PrimitiveDataType type, const char* name); 0040 template <typename T> 0041 void addRowsGetAndSetUnsigned(PrimitiveDataType type, const char* name); 0042 void checkSignedDisplayBase(int expected); 0043 void checkUnsignedDisplayBase(int expected); 0044 int minimumSignedBits(qint64 value); // get the least number of bits this can be represented in 0045 int minimumUnsignedBits(quint64 value); // get the least number of bits this can be represented in 0046 0047 private Q_SLOTS: 0048 void initTestCase(); 0049 void testValueStringFloat(); 0050 void testValueStringDouble(); 0051 void testValueStringChar(); 0052 void testValueStringInt(); 0053 void testValueStringInt_data(); 0054 void testValueStringUIntAndBool(); 0055 void testValueStringUIntAndBool_data(); 0056 void testToAndFromVariant(); 0057 void testGetAndSetValue(); 0058 void testGetAndSetValue_data(); 0059 void testFromVariant(); 0060 void cleanupTestCase(); 0061 0062 private: 0063 QHash<PrimitiveDataType, PrimitiveDataInformation*> basic; 0064 SignedBitfieldDataInformation* signedBitfield; 0065 UnsignedBitfieldDataInformation* unsignedBitfield; 0066 BoolBitfieldDataInformation* boolBitfield; 0067 // TODO enum 0068 // Okteta::Byte* data; 0069 // std::unique_ptr<Okteta::ByteArrayModel> model; 0070 }; 0071 0072 Q_DECLARE_METATYPE(PrimitiveDataInformation*) 0073 Q_DECLARE_METATYPE(AllPrimitiveTypes) 0074 0075 int PrimitiveDataInformationTest::minimumSignedBits(qint64 value) 0076 { 0077 if (value == 0) { 0078 return 1; 0079 } 0080 if (value >= 0) { 0081 return minimumUnsignedBits(quint64(value)) + 1; 0082 } 0083 if (value == -1) { // has no zero in it -> can't determine size 0084 return 1; 0085 } 0086 // find the first zero 0087 for (int i = 63; i >= 0; --i) { 0088 if ((value & (qint64(1) << i)) == 0) { 0089 return i + 2; // found first zero, we need one bit more 0090 } 0091 } 0092 0093 QTEST_ASSERT(false); 0094 return 65; 0095 } 0096 0097 int PrimitiveDataInformationTest::minimumUnsignedBits(quint64 value) 0098 { 0099 if (value == 0) { 0100 return 1; 0101 } 0102 for (int i = 63; i >= 0; --i) { 0103 if ((value & (quint64(1) << i)) == (quint64(1) << i)) { 0104 return i + 1; 0105 } 0106 } 0107 0108 QTEST_ASSERT(false); 0109 return 65; 0110 } 0111 0112 void PrimitiveDataInformationTest::initTestCase() 0113 { 0114 KLocalizedString::setLanguages(QStringList() << QStringLiteral("C")); 0115 Kasten::StructureViewPreferences::setLocaleAwareDecimalFormatting(false); // this could mess with our expected results 0116 Kasten::StructureViewPreferences::setLocaleAwareFloatFormatting(false); // this could mess with our expected results 0117 QLocale locale(QLocale::C); 0118 locale.setNumberOptions(QLocale::OmitGroupSeparator); 0119 QLocale::setDefault(locale); 0120 0121 LoggerWithContext lwc(nullptr, QString()); 0122 0123 PrimitiveDataType type = PrimitiveDataType::START; 0124 while (type < PrimitiveDataType::Bitfield) { 0125 basic.insert(type, PrimitiveFactory::newInstance(QStringLiteral("prim"), type, lwc)); 0126 type = static_cast<PrimitiveDataType>(static_cast<int>(type) + 1); 0127 } 0128 boolBitfield = new BoolBitfieldDataInformation(QStringLiteral("bitfield"), 24); 0129 unsignedBitfield = new UnsignedBitfieldDataInformation(QStringLiteral("bitfield"), 24); 0130 signedBitfield = new SignedBitfieldDataInformation(QStringLiteral("bitfield"), 24); 0131 } 0132 0133 namespace { 0134 template <PrimitiveDataType Type> 0135 void valueCompareHelper(typename PrimitiveInfo<Type>::valueType value, QString bin, 0136 QString hex, QString dec, QString oct) 0137 { 0138 QCOMPARE(PrimitiveInfo<Type>::Methods::staticValueString(value, 2), bin); 0139 QCOMPARE(PrimitiveInfo<Type>::Methods::staticValueString(value, 16), hex); 0140 QCOMPARE(PrimitiveInfo<Type>::Methods::staticValueString(value, 10), dec); 0141 QCOMPARE(PrimitiveInfo<Type>::Methods::staticValueString(value, 8), oct); 0142 } 0143 0144 template <PrimitiveDataType first, PrimitiveDataType second> 0145 void valueCompareHelperUnsigned(typename PrimitiveInfo<first>::valueType value, const QString& bin, 0146 const QString& hex, const QString& dec, const QString& oct, const QString& boolBase) 0147 { 0148 QCOMPARE(PrimitiveInfo<first>::Methods::staticValueString(value, 2), bin); 0149 QCOMPARE(PrimitiveInfo<first>::Methods::staticValueString(value, 16), hex); 0150 QCOMPARE(PrimitiveInfo<first>::Methods::staticValueString(value, 10), dec); 0151 QCOMPARE(PrimitiveInfo<first>::Methods::staticValueString(value, 8), oct); 0152 0153 QCOMPARE(PrimitiveInfo<second>::Methods::staticValueString(value, 2), 0154 value > 1 ? boolBase.arg(bin) : boolBase); 0155 QCOMPARE(PrimitiveInfo<second>::Methods::staticValueString(value, 16), 0156 value > 1 ? boolBase.arg(hex) : boolBase); 0157 QCOMPARE(PrimitiveInfo<second>::Methods::staticValueString(value, 10), 0158 value > 1 ? boolBase.arg(dec) : boolBase); 0159 QCOMPARE(PrimitiveInfo<second>::Methods::staticValueString(value, 8), 0160 value > 1 ? boolBase.arg(oct) : boolBase); 0161 } 0162 0163 } 0164 0165 void PrimitiveDataInformationTest::testValueStringInt() 0166 { 0167 QFETCH(qint64, value); 0168 QFETCH(QString, binStr); 0169 QFETCH(QString, hexStr); 0170 QFETCH(QString, decStr); 0171 QFETCH(QString, octStr); 0172 0173 int minSize = minimumSignedBits(value); 0174 // qDebug() << "need" << minSize << "bit to represent" << value; 0175 // run once with locale aware, and once without 0176 for (int i = 0; i <= 1; ++i) { 0177 Kasten::StructureViewPreferences::setLocaleAwareDecimalFormatting(bool(i)); 0178 0179 if (minSize <= 8) { 0180 valueCompareHelper<PrimitiveDataType::Int8>(qint8(value), binStr, hexStr, decStr, octStr); 0181 } 0182 if (minSize <= 16) { 0183 valueCompareHelper<PrimitiveDataType::Int16>(qint16(value), binStr, hexStr, decStr, octStr); 0184 } 0185 if (minSize <= 32) { 0186 valueCompareHelper<PrimitiveDataType::Int32>(qint32(value), binStr, hexStr, decStr, octStr); 0187 } 0188 if (minSize <= 64) { 0189 valueCompareHelper<PrimitiveDataType::Int64>(qint64(value), binStr, hexStr, decStr, octStr); 0190 } 0191 0192 // check bitfield now 0193 SignedBitfieldDataInformation bitfield(QStringLiteral("signed"), minSize); 0194 bitfield.setValue(value); 0195 for (uint width = minSize; width <= 64U; ++width) { 0196 bitfield.setWidth(width); 0197 bitfield.mWasAbleToRead = true; 0198 Kasten::StructureViewPreferences::setSignedDisplayBase(2); 0199 QCOMPARE(bitfield.valueString(), binStr); 0200 Kasten::StructureViewPreferences::setSignedDisplayBase(16); 0201 QCOMPARE(bitfield.valueString(), hexStr); 0202 Kasten::StructureViewPreferences::setSignedDisplayBase(10); 0203 QCOMPARE(bitfield.valueString(), decStr); 0204 Kasten::StructureViewPreferences::setSignedDisplayBase(8); 0205 QCOMPARE(bitfield.valueString(), octStr); 0206 } 0207 } 0208 } 0209 0210 void PrimitiveDataInformationTest::testValueStringInt_data() 0211 { 0212 QTest::addColumn<qint64>("value"); 0213 QTest::addColumn<QString>("binStr"); 0214 QTest::addColumn<QString>("hexStr"); 0215 QTest::addColumn<QString>("decStr"); 0216 QTest::addColumn<QString>("octStr"); 0217 0218 QTest::newRow("0") << qint64(0) << "0b0" << "0x0" << "0" << "0o0"; 0219 QTest::newRow("1") << qint64(1) << "0b1" << "0x1" << "1" << "0o1"; 0220 QTest::newRow("2") << qint64(2) << "0b10" << "0x2" << "2" << "0o2"; 0221 QTest::newRow("32") << qint64(32) << "0b100000" << "0x20" << "32" << "0o40"; 0222 QTest::newRow("79") << qint64(79) << "0b1001111" << "0x4f" << "79" << "0o117"; 0223 QTest::newRow("172") << qint64(172) << "0b10101100" // 8 chars -> no space 0224 << "0xac" << "172" << "0o254"; 0225 QTest::newRow("259") << qint64(259) << "0b1 00000011" // 9 chars -> space 0226 << "0x103" << "259" << "0o403"; 0227 QTest::newRow("50448") << qint64(50448) << "0b11000101 00010000" // 16 chars -> no space 0228 << "0xc510" << "50448" << "0o142420"; 0229 QTest::newRow("126832") << qint64(126832) << "0b1 11101111 01110000" // 17 chars -> space 0230 << "0x1ef70" << "126832" << "0o367560"; 0231 // maximum 0232 QTest::newRow("qint8::max()") << qint64(std::numeric_limits<qint8>::max()) 0233 << "0b1111111" << "0x7f" << "127" << "0o177"; 0234 QTest::newRow("qint16::max()") << qint64(std::numeric_limits<qint16>::max()) 0235 << "0b1111111 11111111" << "0x7fff" << "32767" << "0o77777"; 0236 QTest::newRow("qint32::max()") << qint64(std::numeric_limits<qint32>::max()) 0237 << "0b1111111 11111111 11111111 11111111" << "0x7fffffff" << "2147483647" 0238 << "0o177 77777777"; 0239 QTest::newRow("qint64::max()") << qint64(std::numeric_limits<qint64>::max()) 0240 << "0b1111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111" 0241 << "0x7fffffff ffffffff" << "9223372036854775807" << "0o77777 77777777 77777777"; 0242 // negative 0243 QTest::newRow("-1") << qint64(-1) << "-0b1" << "-0x1" << "-1" << "-0o1"; 0244 QTest::newRow("-2") << qint64(-2) << "-0b10" << "-0x2" << "-2" << "-0o2"; 0245 QTest::newRow("-32") << qint64(-32) << "-0b100000" << "-0x20" << "-32" << "-0o40"; 0246 QTest::newRow("-79") << qint64(-79) << "-0b1001111" << "-0x4f" << "-79" << "-0o117"; 0247 QTest::newRow("-172") << qint64(-172) << "-0b10101100" << "-0xac" << "-172" << "-0o254"; 0248 QTest::newRow("-259") << qint64(-259) << "-0b1 00000011" << "-0x103" << "-259" << "-0o403"; 0249 ; 0250 QTest::newRow("-50448") << qint64(-50448) << "-0b11000101 00010000" 0251 << "-0xc510" << "-50448" << "-0o142420"; 0252 QTest::newRow("-126832") << qint64(-126832) << "-0b1 11101111 01110000" 0253 << "-0x1ef70" << "-126832" << "-0o367560"; 0254 // -1 * postive maximum 0255 QTest::newRow("-qint8::max()") << qint64(-std::numeric_limits<qint8>::max()) 0256 << "-0b1111111" << "-0x7f" << "-127" << "-0o177"; 0257 QTest::newRow("-qint16::max()") << qint64(-std::numeric_limits<qint16>::max()) 0258 << "-0b1111111 11111111" << "-0x7fff" << "-32767" << "-0o77777"; 0259 ; 0260 QTest::newRow("-qint32::max()") << qint64(-std::numeric_limits<qint32>::max()) 0261 << "-0b1111111 11111111 11111111 11111111" << "-0x7fffffff" << "-2147483647" 0262 << "-0o177 77777777"; 0263 QTest::newRow("-qint64::max()") << qint64(-std::numeric_limits<qint64>::max()) 0264 << "-0b1111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111" 0265 << "-0x7fffffff ffffffff" << "-9223372036854775807" << "-0o77777 77777777 77777777"; 0266 0267 // negative minimum 0268 QTest::newRow("qint8::min()") << qint64(std::numeric_limits<qint8>::min()) 0269 << "-0b10000000" << "-0x80" << "-128" << "-0o200"; 0270 QTest::newRow("qint16::min()") << qint64(std::numeric_limits<qint16>::min()) 0271 << "-0b10000000 00000000" << "-0x8000" << "-32768" << "-0o100000"; 0272 QTest::newRow("qint32::min()") << qint64(std::numeric_limits<qint32>::min()) 0273 << "-0b10000000 00000000 00000000 00000000" << "-0x80000000" << "-2147483648" 0274 << "-0o200 00000000"; 0275 QTest::newRow("qint64::min()") << qint64(std::numeric_limits<qint64>::min()) 0276 << "-0b10000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000" 0277 << "-0x80000000 00000000" << "-9223372036854775808" << "-0o100000 00000000 00000000"; 0278 } 0279 0280 void PrimitiveDataInformationTest::testFromVariant() 0281 { 0282 bool ok = false; 0283 FloatDataInformationMethods::fromVariant(QVariant(float(42.0F)), &ok); 0284 QCOMPARE(ok, true); // float in range 0285 FloatDataInformationMethods::fromVariant(QVariant(double(42.0)), &ok); 0286 QCOMPARE(ok, true); // double should be fine too 0287 FloatDataInformationMethods::fromVariant(QVariant(double(std::numeric_limits<float>::max())), &ok); 0288 QCOMPARE(ok, true); // float max as a double should work too 0289 FloatDataInformationMethods::fromVariant(QVariant(std::numeric_limits<float>::quiet_NaN()), &ok); 0290 QCOMPARE(ok, true); // nan should be fine too 0291 FloatDataInformationMethods::fromVariant(QVariant(std::numeric_limits<double>::quiet_NaN()), &ok); 0292 QCOMPARE(ok, true); // double nan gets mapped to float nan 0293 FloatDataInformationMethods::fromVariant(QVariant(QStringLiteral("abc")), &ok); 0294 QCOMPARE(ok, false); // bad data type 0295 FloatDataInformationMethods::fromVariant(QVariant(std::numeric_limits<double>::max()), &ok); 0296 QCOMPARE(ok, false); // out of range 0297 0298 DoubleDataInformationMethods::fromVariant(QVariant(float(42.0F)), &ok); 0299 QCOMPARE(ok, true); // float should be fine too QVariant::type() == Float 0300 DoubleDataInformationMethods::fromVariant(QVariant(std::numeric_limits<double>::max()), &ok); 0301 QCOMPARE(ok, true); // double 0302 DoubleDataInformationMethods::fromVariant(QVariant(std::numeric_limits<float>::quiet_NaN()), &ok); 0303 QCOMPARE(ok, true); // nan should be fine too 0304 DoubleDataInformationMethods::fromVariant(QVariant(std::numeric_limits<double>::quiet_NaN()), &ok); 0305 QCOMPARE(ok, true); // double nan gets mapped to float nan 0306 DoubleDataInformationMethods::fromVariant(QVariant(QStringLiteral("abc")), &ok); 0307 QCOMPARE(ok, false); // bad data type 0308 // TODO test other types! 0309 0310 } 0311 0312 void PrimitiveDataInformationTest::testValueStringUIntAndBool() 0313 { 0314 // this test will fail if translations are loaded 0315 QFETCH(quint64, value); 0316 QFETCH(QString, binStr); 0317 QFETCH(QString, hexStr); 0318 QFETCH(QString, decStr); 0319 QFETCH(QString, octStr); 0320 0321 int minSize = minimumUnsignedBits(value); 0322 // qDebug() << "need" << minSize << "bit to represent" << value; 0323 QString boolBase; 0324 if (value == 0) { 0325 boolBase = QStringLiteral("false"); 0326 } else if (value == 1) { 0327 boolBase = QStringLiteral("true"); 0328 } else { 0329 boolBase = QStringLiteral("true (%1)"); 0330 } 0331 // run once with locale aware, and once without 0332 for (int i = 0; i <= 1; ++i) { 0333 Kasten::StructureViewPreferences::setLocaleAwareDecimalFormatting(bool(i)); 0334 0335 if (minSize <= 8) { 0336 valueCompareHelperUnsigned<PrimitiveDataType::UInt8, PrimitiveDataType::Bool8>(quint8(value), binStr, hexStr, 0337 decStr, octStr, boolBase); 0338 } 0339 if (minSize <= 16) { 0340 valueCompareHelperUnsigned<PrimitiveDataType::UInt16, PrimitiveDataType::Bool16>(quint16(value), binStr, hexStr, 0341 decStr, octStr, boolBase); 0342 } 0343 if (minSize <= 32) { 0344 valueCompareHelperUnsigned<PrimitiveDataType::UInt32, PrimitiveDataType::Bool32>(quint32(value), binStr, hexStr, 0345 decStr, octStr, boolBase); 0346 } 0347 if (minSize <= 64) { 0348 valueCompareHelperUnsigned<PrimitiveDataType::UInt64, PrimitiveDataType::Bool64>(quint64(value), binStr, hexStr, 0349 decStr, octStr, boolBase); 0350 } 0351 0352 // check bitfield now 0353 UnsignedBitfieldDataInformation bitfield(QStringLiteral("unsigned"), minSize); 0354 BoolBitfieldDataInformation boolBitfield(QStringLiteral("bool"), minSize); 0355 bitfield.setValue(value); 0356 boolBitfield.setValue(value); 0357 bitfield.mWasAbleToRead = true; 0358 boolBitfield.mWasAbleToRead = true; 0359 for (uint width = minSize; width <= 64U; ++width) { 0360 bitfield.setWidth(width); 0361 bitfield.setWidth(width); 0362 Kasten::StructureViewPreferences::setUnsignedDisplayBase(2); 0363 QCOMPARE(bitfield.valueString(), binStr); 0364 QCOMPARE(boolBitfield.valueString(), value > 1 ? boolBase.arg(binStr) : boolBase); 0365 Kasten::StructureViewPreferences::setUnsignedDisplayBase(16); 0366 QCOMPARE(bitfield.valueString(), hexStr); 0367 QCOMPARE(boolBitfield.valueString(), value > 1 ? boolBase.arg(hexStr) : boolBase); 0368 Kasten::StructureViewPreferences::setUnsignedDisplayBase(10); 0369 QCOMPARE(bitfield.valueString(), decStr); 0370 QCOMPARE(boolBitfield.valueString(), value > 1 ? boolBase.arg(decStr) : boolBase); 0371 Kasten::StructureViewPreferences::setUnsignedDisplayBase(8); 0372 QCOMPARE(bitfield.valueString(), octStr); 0373 QCOMPARE(boolBitfield.valueString(), value > 1 ? boolBase.arg(octStr) : boolBase); 0374 } 0375 } 0376 } 0377 0378 void PrimitiveDataInformationTest::testValueStringUIntAndBool_data() 0379 { 0380 QTest::addColumn<quint64>("value"); 0381 QTest::addColumn<QString>("binStr"); 0382 QTest::addColumn<QString>("hexStr"); 0383 QTest::addColumn<QString>("decStr"); 0384 QTest::addColumn<QString>("octStr"); 0385 0386 QTest::newRow("0") << quint64(0) << "0b0" << "0x0" << "0" << "0o0"; 0387 QTest::newRow("1") << quint64(1) << "0b1" << "0x1" << "1" << "0o1"; 0388 QTest::newRow("2") << quint64(2) << "0b10" << "0x2" << "2" << "0o2"; 0389 QTest::newRow("32") << quint64(32) << "0b100000" << "0x20" << "32" << "0o40"; 0390 QTest::newRow("79") << quint64(79) << "0b1001111" << "0x4f" << "79" << "0o117"; 0391 QTest::newRow("172") << quint64(172) << "0b10101100" // 8 chars -> no space 0392 << "0xac" << "172" << "0o254"; 0393 QTest::newRow("259") << quint64(259) << "0b1 00000011" // 9 chars -> space 0394 << "0x103" << "259" << "0o403"; 0395 QTest::newRow("50448") << quint64(50448) << "0b11000101 00010000" // 16 chars -> no space 0396 << "0xc510" << "50448" << "0o142420"; 0397 QTest::newRow("126832") << quint64(126832) << "0b1 11101111 01110000" // 17 chars -> space 0398 << "0x1ef70" << "126832" << "0o367560"; 0399 // maximum 0400 QTest::newRow("quint8::max()") << quint64(std::numeric_limits<quint8>::max()) 0401 << "0b11111111" << "0xff" << "255" << "0o377"; 0402 QTest::newRow("quint16::max()") << quint64(std::numeric_limits<quint16>::max()) 0403 << "0b11111111 11111111" << "0xffff" << "65535" << "0o177777"; 0404 QTest::newRow("quint32::max()") << quint64(std::numeric_limits<quint32>::max()) 0405 << "0b11111111 11111111 11111111 11111111" << "0xffffffff" << "4294967295" 0406 << "0o377 77777777"; 0407 QTest::newRow("quint64::max()") << quint64(std::numeric_limits<quint64>::max()) 0408 << "0b11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111" 0409 << "0xffffffff ffffffff" << "18446744073709551615" << "0o177777 77777777 77777777"; 0410 } 0411 0412 namespace { 0413 QString charString(quint32 i) 0414 { 0415 QString charString; 0416 if (i == '\n') { 0417 charString = QStringLiteral("\\n"); 0418 } else if (i == '\t') { 0419 charString = QStringLiteral("\\t"); 0420 } else if (i == '\r') { 0421 charString = QStringLiteral("\\r"); 0422 } else if (i == '\f') { 0423 charString = QStringLiteral("\\f"); 0424 } else if (i == '\0') { 0425 charString = QStringLiteral("\\0"); 0426 } else if (i == '\v') { 0427 charString = QStringLiteral("\\v"); 0428 } else if (i == '\b') { 0429 charString = QStringLiteral("\\b"); 0430 } else if (i == '\a') { 0431 charString = QStringLiteral("\\a"); 0432 } else { 0433 QChar unicode = (i > 127) ? QChar::ReplacementCharacter : QChar(i, 0); 0434 if (unicode.isPrint()) { 0435 charString = QString(unicode); 0436 } else { 0437 charString = QString(QChar::ReplacementCharacter); 0438 } 0439 } 0440 // qDebug doesn't output unicode! 0441 // printf("The string for char %#x is: %s\n", i, charString.toUtf8().data()); 0442 return charString; 0443 } 0444 } 0445 0446 void PrimitiveDataInformationTest::testValueStringChar() 0447 { 0448 Kasten::StructureViewPreferences::setShowCharNumericalValue(false); 0449 Kasten::StructureViewPreferences::setLocaleAwareDecimalFormatting(false); 0450 // we don't want the numeric value now 0451 for (int i = 0; i < 256; ++i) { 0452 QString expected = QStringLiteral("'%1'").arg(charString(i)); 0453 QCOMPARE(CharDataInformationMethods::staticValueString(i), expected); 0454 } 0455 0456 Kasten::StructureViewPreferences::setShowCharNumericalValue(true); 0457 Kasten::StructureViewPreferences::setCharDisplayBase(16); 0458 for (int i = 0; i < 256; ++i) { 0459 QString expected = QStringLiteral("'%1' (0x%2)").arg(charString(i), 0460 QString::number(i, 16)); 0461 QCOMPARE(CharDataInformationMethods::staticValueString(i), expected); 0462 } 0463 0464 Kasten::StructureViewPreferences::setCharDisplayBase(10); 0465 for (int i = 0; i < 256; ++i) { 0466 QString expected = QStringLiteral("'%1' (%2)").arg(charString(i), 0467 QString::number(i, 10)); 0468 QCOMPARE(CharDataInformationMethods::staticValueString(i), expected); 0469 } 0470 0471 Kasten::StructureViewPreferences::setCharDisplayBase(2); 0472 for (int i = 0; i < 256; ++i) { 0473 QString expected = QStringLiteral("'%1' (0b%2)").arg(charString(i), 0474 QString::number(i, 2)); 0475 QCOMPARE(CharDataInformationMethods::staticValueString(i), expected); 0476 } 0477 0478 Kasten::StructureViewPreferences::setCharDisplayBase(8); 0479 for (int i = 0; i < 256; ++i) { 0480 QString expected = QStringLiteral("'%1' (0o%2)").arg(charString(i), 0481 QString::number(i, 8)); 0482 QCOMPARE(CharDataInformationMethods::staticValueString(i), expected); 0483 } 0484 0485 // TODO octal 0486 } 0487 0488 void PrimitiveDataInformationTest::testValueStringDouble() 0489 { 0490 // TODO implement 0491 } 0492 0493 void PrimitiveDataInformationTest::testValueStringFloat() 0494 { 0495 // TODO implement 0496 } 0497 0498 void PrimitiveDataInformationTest::testToAndFromVariant() 0499 { 0500 // TODO implement 0501 } 0502 0503 void PrimitiveDataInformationTest::testGetAndSetValue() 0504 { 0505 QFETCH(PrimitiveDataInformation*, data); 0506 QFETCH(AllPrimitiveTypes, newVal); 0507 QFETCH(AllPrimitiveTypes, expected); 0508 0509 std::unique_ptr<PrimitiveDataInformation> clone(data->clone()); 0510 clone->setValue(newVal); 0511 QCOMPARE(clone->value(), expected); 0512 } 0513 0514 template <typename signedType, typename unsignedType> 0515 void PrimitiveDataInformationTest::addRowsGetAndSetSigned(PrimitiveDataType type, const char* name) 0516 { 0517 QString msg = QString::fromUtf8(name); 0518 QTest::newRow(msg.arg(QStringLiteral("-325")).toUtf8().constData()) 0519 << basic[type] << AllPrimitiveTypes(-325) << AllPrimitiveTypes(signedType(-325)); 0520 QTest::newRow(msg.arg(QStringLiteral("0")).toUtf8().constData()) 0521 << basic[type] << AllPrimitiveTypes(0) << AllPrimitiveTypes(signedType(0)); 0522 QTest::newRow(msg.arg(QStringLiteral("-1")).toUtf8().constData()) 0523 << basic[type] << AllPrimitiveTypes(-1) << AllPrimitiveTypes(signedType(-1)); 0524 QTest::newRow(msg.arg(QStringLiteral("357891")).toUtf8().constData()) 0525 << basic[type] << AllPrimitiveTypes(357891) << AllPrimitiveTypes(signedType(357891)); 0526 0527 QTest::newRow(msg.arg(QStringLiteral("max")).toUtf8().constData()) 0528 << basic[type] << AllPrimitiveTypes(std::numeric_limits<signedType>::max()) 0529 << AllPrimitiveTypes(signedType(std::numeric_limits<signedType>::max())); 0530 QTest::newRow(msg.arg(QStringLiteral("min")).toUtf8().constData()) 0531 << basic[type] << AllPrimitiveTypes(std::numeric_limits<signedType>::min()) 0532 << AllPrimitiveTypes(signedType(std::numeric_limits<signedType>::min())); 0533 QTest::newRow(msg.arg(QStringLiteral("u_max")).toUtf8().constData()) 0534 << basic[type] << AllPrimitiveTypes(std::numeric_limits<unsignedType>::max()) 0535 << AllPrimitiveTypes(signedType(std::numeric_limits<unsignedType>::max())); 0536 QTest::newRow(msg.arg(QStringLiteral("u_min")).toUtf8().constData()) 0537 << basic[type] << AllPrimitiveTypes(std::numeric_limits<unsignedType>::min()) 0538 << AllPrimitiveTypes(signedType(std::numeric_limits<unsignedType>::min())); 0539 } 0540 0541 template <typename signedType> 0542 void PrimitiveDataInformationTest::addRowsGetAndSetUnsigned(PrimitiveDataType type, const char* name) 0543 { 0544 QString msg = QString::fromUtf8(name); 0545 QTest::newRow(msg.arg(QStringLiteral("-325")).toUtf8().constData()) 0546 << basic[type] << AllPrimitiveTypes(-325) << AllPrimitiveTypes(signedType(-325)); 0547 QTest::newRow(msg.arg(QStringLiteral("0")).toUtf8().constData()) 0548 << basic[type] << AllPrimitiveTypes(0) << AllPrimitiveTypes(signedType(0)); 0549 QTest::newRow(msg.arg(QStringLiteral("-1")).toUtf8().constData()) 0550 << basic[type] << AllPrimitiveTypes(-1) << AllPrimitiveTypes(signedType(-1)); 0551 QTest::newRow(msg.arg(QStringLiteral("357891")).toUtf8().constData()) 0552 << basic[type] << AllPrimitiveTypes(357891) << AllPrimitiveTypes(signedType(357891)); 0553 0554 QTest::newRow(msg.arg(QStringLiteral("max")).toUtf8().constData()) 0555 << basic[type] << AllPrimitiveTypes(std::numeric_limits<signedType>::max()) 0556 << AllPrimitiveTypes(signedType(std::numeric_limits<signedType>::max())); 0557 QTest::newRow(msg.arg(QStringLiteral("min")).toUtf8().constData()) 0558 << basic[type] << AllPrimitiveTypes(std::numeric_limits<signedType>::min()) 0559 << AllPrimitiveTypes(signedType(std::numeric_limits<signedType>::min())); 0560 } 0561 0562 void PrimitiveDataInformationTest::testGetAndSetValue_data() 0563 { 0564 QTest::addColumn<PrimitiveDataInformation*>("data"); 0565 QTest::addColumn<AllPrimitiveTypes>("newVal"); 0566 QTest::addColumn<AllPrimitiveTypes>("expected"); 0567 0568 addRowsGetAndSetSigned<qint8, quint8>(PrimitiveDataType::Int8, "int8: %1"); 0569 addRowsGetAndSetSigned<qint16, quint16>(PrimitiveDataType::Int16, "int8: %1"); 0570 addRowsGetAndSetSigned<qint32, quint32>(PrimitiveDataType::Int32, "int8: %1"); 0571 addRowsGetAndSetSigned<qint64, quint64>(PrimitiveDataType::Int64, "int8: %1"); 0572 } 0573 0574 void PrimitiveDataInformationTest::cleanupTestCase() 0575 { 0576 qDeleteAll(basic); 0577 delete signedBitfield; 0578 delete unsignedBitfield; 0579 delete boolBitfield; 0580 } 0581 0582 QTEST_GUILESS_MAIN(PrimitiveDataInformationTest) 0583 0584 #include "primitivedatainformationtest.moc"