File indexing completed on 2024-05-12 05:55:43
0001 /* 0002 This file is part of the Okteta Kasten Framework, made within the KDE community. 0003 0004 SPDX-FileCopyrightText: 2012 Alex Richardson <alex.richardson@gmx.de> 0005 SPDX-FileCopyrightText: 2016 Aaron Bishop <erroneous@gmail.com> 0006 0007 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 0008 */ 0009 0010 #include "view/structures/parsers/parserutils.hpp" 0011 // Qt 0012 #include <QTest> 0013 #include <QScriptValue> 0014 #include <QScriptEngine> 0015 // Std 0016 #include <memory> 0017 #include <limits> 0018 0019 class CommonParserTest : public QObject 0020 { 0021 Q_OBJECT 0022 0023 private Q_SLOTS: 0024 void testIntFromString(); 0025 void testIntFromString_data(); 0026 void testUIntFromString(); 0027 void testUIntFromString_data(); 0028 0029 void testIntFromScriptValue(); 0030 void testIntFromScriptValue_data(); 0031 void testUIntFromScriptValue(); 0032 void testUIntFromScriptValue_data(); 0033 0034 void testToStringEncoding(); 0035 void testToStringEncoding_data(); 0036 }; 0037 0038 void CommonParserTest::testIntFromString_data() 0039 { 0040 QTest::addColumn<QString>("str"); 0041 QTest::addColumn<bool>("okay"); 0042 QTest::addColumn<int>("value"); 0043 0044 QTest::newRow("-1") << "-1" << true << -1; 0045 QTest::newRow("hex with minus") << "-0xff" << true << -0xff; 0046 QTest::newRow("0xff") << "0xff" << true << 0xff; 0047 0048 int maxInt = 0x7fffffff; 0049 QTEST_ASSERT(maxInt == std::numeric_limits<int>::max()); 0050 QTest::newRow("max decimal") << "2147483647" << true << maxInt; 0051 QTest::newRow("max hex") << "0x7fffffff" << true << maxInt; 0052 QTest::newRow("max hex no leading 0x") << "7fffffff" << false; 0053 0054 QTest::newRow("max+1 decimal") << "2147483648" << false; 0055 QTest::newRow("max+1 hex") << "0x80000000" << false; 0056 QTest::newRow("max-1 decimal") << "2147483646" << true << 0x7ffffffe; 0057 QTest::newRow("max-1 hex") << "7ffffffe" << false << 2147483646; 0058 0059 int minInt = -0x80000000; 0060 QTEST_ASSERT(minInt == std::numeric_limits<int>::min()); 0061 QTest::newRow("min decimal") << "-2147483648" << true << minInt; 0062 QTest::newRow("min hex") << "-0x80000000" << true << minInt; 0063 0064 QTest::newRow("min+1 decimal") << "-2147483647" << true << -0x7fffffff; 0065 QTest::newRow("min+1 hex") << "-0x7fffffff" << true << -2147483647; 0066 QTest::newRow("min-1 decimal") << "-2147483649" << false; 0067 QTest::newRow("min-1 hex") << "-0x80000001" << false; 0068 0069 } 0070 0071 void CommonParserTest::testIntFromString() 0072 { 0073 QFETCH(QString, str); 0074 QFETCH(bool, okay); 0075 0076 ParsedNumber<int> result = ParserUtils::intFromString(str); 0077 QCOMPARE(result.string, str); 0078 QCOMPARE(result.isValid, okay); 0079 if (result.isValid) { 0080 QFETCH(int, value); 0081 QCOMPARE(result.value, value); 0082 } 0083 } 0084 0085 void CommonParserTest::testUIntFromString_data() 0086 { 0087 QTest::addColumn<QString>("str"); 0088 QTest::addColumn<bool>("okay"); 0089 QTest::addColumn<uint>("value"); 0090 0091 QTest::newRow("-1") << "-1" << false; 0092 QTest::newRow("0xff") << "0xff" << true << 0xffU; 0093 QTest::newRow("1234") << "1234" << true << 1234U; 0094 0095 uint maxUint = 0xffffffff; 0096 QTEST_ASSERT(maxUint == std::numeric_limits<uint>::max()); 0097 QTest::newRow("max decimal") << "4294967295" << true << maxUint; 0098 QTest::newRow("max hex") << "0xffffffff" << true << maxUint; 0099 QTest::newRow("max hex no leading 0x") << "ffffffff" << false; 0100 0101 QTest::newRow("max+1 decimal") << "4294967296" << false; 0102 QTest::newRow("max+1 hex") << "0x100000000" << false; 0103 0104 } 0105 0106 void CommonParserTest::testUIntFromString() 0107 { 0108 QFETCH(QString, str); 0109 QFETCH(bool, okay); 0110 0111 ParsedNumber<uint> result = ParserUtils::uintFromString(str); 0112 QCOMPARE(result.string, str); 0113 QCOMPARE(result.isValid, okay); 0114 if (result.isValid) { 0115 QFETCH(uint, value); 0116 QCOMPARE(result.value, value); 0117 } 0118 } 0119 0120 void CommonParserTest::testIntFromScriptValue_data() 0121 { 0122 QTest::addColumn<QScriptValue>("scriptValue"); 0123 QTest::addColumn<bool>("okay"); 0124 QTest::addColumn<int>("value"); 0125 0126 auto* engine = new QScriptEngine(this); 0127 QTest::newRow("invalid script value") << QScriptValue() << false; 0128 QTest::newRow("boolean true") << QScriptValue(true) << false; 0129 QTest::newRow("boolean false") << QScriptValue(false) << false; 0130 QTest::newRow("null script value") << engine->nullValue() << false; 0131 QTest::newRow("undefined script value") << engine->undefinedValue() << false; 0132 QTest::newRow("array") << engine->newArray(5) << false; 0133 QTest::newRow("object") << engine->newObject() << false; 0134 QTest::newRow("float") << QScriptValue(1234.5) << false; 0135 0136 QTest::newRow("-1234 number") << QScriptValue(-1234) << true << -1234; 0137 QTest::newRow("-1234 string") << QScriptValue(QStringLiteral("-1234")) << true << -1234; 0138 QTest::newRow("1234 number") << QScriptValue(1234) << true << 1234; 0139 QTest::newRow("1234 string") << QScriptValue(QStringLiteral("1234")) << true << 1234; 0140 QTest::newRow("0xff number") << QScriptValue(0xff) << true << 0xff; 0141 QTest::newRow("0xff string") << QScriptValue(QStringLiteral("0xff")) << true << 0xff; 0142 QTest::newRow("-0xff number") << QScriptValue(-0xff) << true << -0xff; 0143 QTest::newRow("-0xff string") << QScriptValue(QStringLiteral("-0xff")) << true << -0xff; 0144 0145 int maxInt = 0x7fffffff; 0146 QTEST_ASSERT(maxInt == std::numeric_limits<int>::max()); 0147 QTest::newRow("max int") << QScriptValue(maxInt) << true << maxInt; 0148 QTest::newRow("max double") << QScriptValue(double(maxInt)) << true << maxInt; 0149 QTest::newRow("max string") << QScriptValue(QStringLiteral("2147483647")) << true << maxInt; 0150 QTest::newRow("max hex string") << QScriptValue(QStringLiteral("0x7fffffff")) << true << maxInt; 0151 // to int32 wraps around 0152 QTest::newRow("max+1") << QScriptValue(double(maxInt) + 1) << false; 0153 QTest::newRow("max+1 string") << QScriptValue(QStringLiteral("2147483648")) << false; 0154 QTest::newRow("max+1 hex string") << QScriptValue(QStringLiteral("0x80000000")) << false; 0155 QTest::newRow("max+2") << QScriptValue(double(maxInt) + 2) << false; 0156 0157 int minInt = -0x80000000; 0158 QTEST_ASSERT(minInt == std::numeric_limits<int>::min()); 0159 QTest::newRow("min int") << QScriptValue(minInt) << true << minInt; 0160 QTest::newRow("min double") << QScriptValue(double(minInt)) << true << minInt; 0161 QTest::newRow("min string") << QScriptValue(QStringLiteral("-2147483648")) << true << minInt; 0162 QTest::newRow("min hex string") << QScriptValue(QStringLiteral("-0x80000000")) << true << minInt; 0163 QTest::newRow("min-1") << QScriptValue(double(minInt) - 1) << false; 0164 QTest::newRow("large number") << QScriptValue(double(0x123456789a)) << false; 0165 0166 } 0167 0168 void CommonParserTest::testIntFromScriptValue() 0169 { 0170 QFETCH(QScriptValue, scriptValue); 0171 QFETCH(bool, okay); 0172 0173 ParsedNumber<int> result = ParserUtils::intFromScriptValue(scriptValue); 0174 QCOMPARE(result.string, scriptValue.toString()); 0175 if (result.isValid != okay) { 0176 qDebug() << scriptValue.toString() << ", int =" << scriptValue.toInt32() << ", double = " 0177 << scriptValue.toNumber(); 0178 } 0179 QCOMPARE(result.isValid, okay); 0180 if (result.isValid) { 0181 QFETCH(int, value); 0182 QCOMPARE(result.value, value); 0183 } 0184 } 0185 0186 void CommonParserTest::testUIntFromScriptValue_data() 0187 { 0188 QTest::addColumn<QScriptValue>("scriptValue"); 0189 QTest::addColumn<bool>("okay"); 0190 QTest::addColumn<uint>("value"); 0191 0192 auto* engine = new QScriptEngine(this); 0193 QTest::newRow("invalid script value") << QScriptValue() << false; 0194 QTest::newRow("boolean true") << QScriptValue(true) << false; 0195 QTest::newRow("boolean false") << QScriptValue(false) << false; 0196 QTest::newRow("null script value") << engine->nullValue() << false; 0197 QTest::newRow("undefined script value") << engine->undefinedValue() << false; 0198 QTest::newRow("array") << engine->newArray(5) << false; 0199 QTest::newRow("object") << engine->newObject() << false; 0200 QTest::newRow("float") << QScriptValue(1234.5) << false; 0201 0202 QTest::newRow("1234 number") << QScriptValue(1234) << true << 1234U; 0203 QTest::newRow("1234 string") << QScriptValue(QStringLiteral("1234")) << true << 1234U; 0204 QTest::newRow("0xff number") << QScriptValue(0xff) << true << 0xffU; 0205 QTest::newRow("0xff string") << QScriptValue(QStringLiteral("0xff")) << true << 0xffU; 0206 0207 QTest::newRow("negative string") << QScriptValue(QStringLiteral("-1")) << false; 0208 QTest::newRow("negative number") << QScriptValue(-1) << false; 0209 0210 uint maxInt = 0xffffffff; 0211 QTEST_ASSERT(maxInt == std::numeric_limits<uint>::max()); 0212 QTest::newRow("max") << QScriptValue(double(maxInt)) << true << maxInt; 0213 QTest::newRow("max int") << QScriptValue(maxInt) << true << maxInt; 0214 QTest::newRow("max string") << QScriptValue(QStringLiteral("4294967295")) << true << maxInt; 0215 QTest::newRow("max hex string") << QScriptValue(QStringLiteral("0xffffffff")) << true << maxInt; 0216 QTest::newRow("max+1") << QScriptValue(double(maxInt) + 1) << false; 0217 QTest::newRow("max+1 string") << QScriptValue(QStringLiteral("4294967296")) << false; 0218 QTest::newRow("max+1 hex string") << QScriptValue(QStringLiteral("0x100000000")) << false; 0219 QTest::newRow("large number") << QScriptValue(double(0x123456789a)) << false; 0220 } 0221 0222 void CommonParserTest::testUIntFromScriptValue() 0223 { 0224 QFETCH(QScriptValue, scriptValue); 0225 QFETCH(bool, okay); 0226 0227 ParsedNumber<uint> result = ParserUtils::uintFromScriptValue(scriptValue); 0228 QCOMPARE(result.string, scriptValue.toString()); 0229 if (result.isValid != okay) { 0230 qDebug() << scriptValue.toString() << ", uint =" << scriptValue.toUInt32() << ", double = " 0231 << scriptValue.toNumber(); 0232 } 0233 QCOMPARE(result.isValid, okay); 0234 if (result.isValid) { 0235 QFETCH(uint, value); 0236 QCOMPARE(result.value, value); 0237 } 0238 } 0239 0240 inline void CommonParserTest::testToStringEncoding() 0241 { 0242 QFETCH(QString, str); 0243 QFETCH(int, expected); 0244 std::unique_ptr<ScriptLogger> logger(new ScriptLogger()); 0245 StringDataInformation::StringType type = 0246 ParserUtils::toStringEncoding(str, LoggerWithContext(logger.get(), QString())); 0247 QCOMPARE((int)type, expected); 0248 } 0249 0250 inline void CommonParserTest::testToStringEncoding_data() 0251 { 0252 QTest::addColumn<QString>("str"); 0253 QTest::addColumn<int>("expected"); 0254 0255 QTest::newRow("ascii") << "ascii" << (int)StringDataInformation::StringType::ASCII; 0256 QTest::newRow("ebcdic") << "ebcdic" << (int)StringDataInformation::StringType::EBCDIC; 0257 QTest::newRow("ascii upper") << "ASCII" << (int)StringDataInformation::StringType::ASCII; 0258 QTest::newRow("excess char") << "asciii" << (int)StringDataInformation::StringType::InvalidEncoding; 0259 0260 QTest::newRow("latin1") << "latin1" << (int)StringDataInformation::StringType::Latin1; 0261 QTest::newRow("latin-1") << "latin-1" << (int)StringDataInformation::StringType::Latin1; 0262 QTest::newRow("latin") << "latin" << (int)StringDataInformation::StringType::InvalidEncoding; 0263 0264 QTest::newRow("utf8") << "utf8" << (int)StringDataInformation::StringType::UTF8; 0265 QTest::newRow("utf-8") << "utf-8" << (int)StringDataInformation::StringType::UTF8; 0266 QTest::newRow("utf--8") << "utf--8" << (int)StringDataInformation::StringType::InvalidEncoding; 0267 0268 QTest::newRow("utf16") << "utf16" << (int)StringDataInformation::StringType::UTF16_LE; 0269 QTest::newRow("utf-16") << "utf-16" << (int)StringDataInformation::StringType::UTF16_LE; 0270 QTest::newRow("utf-16le") << "utf-16le" << (int)StringDataInformation::StringType::UTF16_LE; 0271 QTest::newRow("utf-16-le") << "utf-16-le" << (int)StringDataInformation::StringType::UTF16_LE; 0272 QTest::newRow("utf-16--le") << "utf-16--le" << (int)StringDataInformation::StringType::InvalidEncoding; 0273 0274 QTest::newRow("utf-16be") << "utf-16be" << (int)StringDataInformation::StringType::UTF16_BE; 0275 QTest::newRow("utf-16-be") << "utf-16-be" << (int)StringDataInformation::StringType::UTF16_BE; 0276 QTest::newRow("utf-16-abe") << "utf-16-abe" << (int)StringDataInformation::StringType::InvalidEncoding; 0277 0278 QTest::newRow("utf32") << "utf32" << (int)StringDataInformation::StringType::UTF32_LE; 0279 QTest::newRow("utf-32") << "utf-32" << (int)StringDataInformation::StringType::UTF32_LE; 0280 QTest::newRow("utf-32le") << "utf-32le" << (int)StringDataInformation::StringType::UTF32_LE; 0281 QTest::newRow("utf-32-le") << "utf-32-le" << (int)StringDataInformation::StringType::UTF32_LE; 0282 QTest::newRow("utf-32--le") << "utf-32--le" << (int)StringDataInformation::StringType::InvalidEncoding; 0283 0284 QTest::newRow("utf-32be") << "utf-32be" << (int)StringDataInformation::StringType::UTF32_BE; 0285 QTest::newRow("utf-32-be") << "utf-32-be" << (int)StringDataInformation::StringType::UTF32_BE; 0286 QTest::newRow("utf-32-abe") << "utf-32-abe" << (int)StringDataInformation::StringType::InvalidEncoding; 0287 } 0288 0289 QTEST_GUILESS_MAIN(CommonParserTest) 0290 0291 #include "commonparsertest.moc"