Exclude denormal test cases if system doesn't support it

- current INTEGRITY development pack don't support denormals for float and double.
  All values are rounded to 0.

Task-number: QTBUG-99123
Pick-to: 6.2 6.3
Change-Id: Iaaacdc4210c7ac2ec3ec337c61164a1ade0efb01
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
This commit is contained in:
Tatiana Borisova 2022-02-01 13:26:17 +02:00
parent 7794421bea
commit 23fd249b85
6 changed files with 112 additions and 21 deletions

View File

@ -402,6 +402,11 @@ void tst_QNumeric::distance()
QFETCH(F, from);
QFETCH(F, stop);
QFETCH(Count, expectedDistance);
if constexpr (std::numeric_limits<F>::has_denorm != std::denorm_present) {
if (qstrcmp(QTest::currentDataTag(), "denormal") == 0) {
QSKIP("Skipping 'denorm' as this type lacks denormals on this system");
}
}
QCOMPARE(qFloatDistance(from, stop), expectedDistance);
QCOMPARE(qFloatDistance(stop, from), expectedDistance);
}

View File

@ -106,6 +106,7 @@ private Q_SLOTS:
void toJson();
void toJsonSillyNumericValues();
void toJsonLargeNumericValues();
void toJsonDenormalValues();
void fromJson();
void fromJsonErrors();
void parseNumbers();
@ -399,11 +400,14 @@ void tst_QtJson::testNumbers_2()
// Validate the last actual value is min denorm
QVERIFY2(floatValues_1[1074] == 4.9406564584124654417656879286822e-324, QString("Min denorm value is incorrect: %1").arg(floatValues_1[1074]).toLatin1());
// Validate that every value is half the value before it up to 1
for (int index = 1074; index > 0; index--) {
QVERIFY2(floatValues_1[index] != 0, QString("2**- %1 should not be 0").arg(index).toLatin1());
QVERIFY2(floatValues_1[index - 1] == (floatValues_1[index] * 2), QString("Value should be double adjacent value at index %1").arg(index).toLatin1());
if constexpr (std::numeric_limits<double>::has_denorm == std::denorm_present) {
// Validate that every value is half the value before it up to 1
for (int index = 1074; index > 0; index--) {
QVERIFY2(floatValues_1[index] != 0, QString("2**- %1 should not be 0").arg(index).toLatin1());
QVERIFY2(floatValues_1[index - 1] == (floatValues_1[index] * 2), QString("Value should be double adjacent value at index %1").arg(index).toLatin1());
}
} else {
QSKIP("Skipping 'denorm' as this type lacks denormals on this system");
}
}
@ -1824,16 +1828,13 @@ void tst_QtJson::toJsonLargeNumericValues()
QJsonArray array;
array.append(QJsonValue(1.234567)); // actual precision bug in Qt 5.0.0
array.append(QJsonValue(1.7976931348623157e+308)); // JS Number.MAX_VALUE
array.append(QJsonValue(5e-324)); // JS Number.MIN_VALUE
array.append(QJsonValue(std::numeric_limits<double>::min()));
array.append(QJsonValue(std::numeric_limits<double>::max()));
array.append(QJsonValue(std::numeric_limits<double>::epsilon()));
array.append(QJsonValue(std::numeric_limits<double>::denorm_min()));
array.append(QJsonValue(0.0));
array.append(QJsonValue(-std::numeric_limits<double>::min()));
array.append(QJsonValue(-std::numeric_limits<double>::max()));
array.append(QJsonValue(-std::numeric_limits<double>::epsilon()));
array.append(QJsonValue(-std::numeric_limits<double>::denorm_min()));
array.append(QJsonValue(-0.0));
array.append(QJsonValue(9007199254740992LL)); // JS Number max integer
array.append(QJsonValue(-9007199254740992LL)); // JS Number min integer
@ -1847,27 +1848,21 @@ void tst_QtJson::toJsonLargeNumericValues()
" 1.234567,\n"
" 1.7976931348623157e+308,\n"
#ifdef QT_NO_DOUBLECONVERSION // "shortest" double conversion is not very short then
" 4.9406564584124654e-324,\n"
" 2.2250738585072014e-308,\n"
" 1.7976931348623157e+308,\n"
" 2.2204460492503131e-16,\n"
" 4.9406564584124654e-324,\n"
" 0,\n"
" -2.2250738585072014e-308,\n"
" -1.7976931348623157e+308,\n"
" -2.2204460492503131e-16,\n"
" -4.9406564584124654e-324,\n"
#else
" 5e-324,\n"
" 2.2250738585072014e-308,\n"
" 1.7976931348623157e+308,\n"
" 2.220446049250313e-16,\n"
" 5e-324,\n"
" 0,\n"
" -2.2250738585072014e-308,\n"
" -1.7976931348623157e+308,\n"
" -2.220446049250313e-16,\n"
" -5e-324,\n"
#endif
" 0,\n"
" 9007199254740992,\n"
@ -1883,6 +1878,42 @@ void tst_QtJson::toJsonLargeNumericValues()
QCOMPARE(json, expected);
}
void tst_QtJson::toJsonDenormalValues()
{
if constexpr (std::numeric_limits<double>::has_denorm == std::denorm_present) {
QJsonObject object;
QJsonArray array;
array.append(QJsonValue(5e-324)); // JS Number.MIN_VALUE
array.append(QJsonValue(std::numeric_limits<double>::denorm_min()));
array.append(QJsonValue(-std::numeric_limits<double>::denorm_min()));
object.insert("Array", array);
QByteArray json = QJsonDocument(object).toJson();
QByteArray expected =
"{\n"
" \"Array\": [\n"
#ifdef QT_NO_DOUBLECONVERSION // "shortest" double conversion is not very short then
" 4.9406564584124654e-324,\n"
" 4.9406564584124654e-324,\n"
" -4.9406564584124654e-324\n"
#else
" 5e-324,\n"
" 5e-324,\n"
" -5e-324\n"
#endif
" ]\n"
"}\n";
QCOMPARE(json, expected);
QJsonDocument doc;
doc.setObject(object);
json = doc.toJson();
QCOMPARE(json, expected);
} else {
QSKIP("Skipping 'denorm' as this type lacks denormals on this system");
}
}
void tst_QtJson::fromJson()
{
{
@ -2205,12 +2236,12 @@ void tst_QtJson::parseNumbers()
QCOMPARE(val.toDouble(), (double)numbers[i].n);
}
}
// test number parsing
struct Numbers {
const char *str;
double n;
};
{
// test number parsing
struct Numbers {
const char *str;
double n;
};
Numbers numbers [] = {
{ "0", 0 },
{ "1", 1 },
@ -2226,8 +2257,6 @@ void tst_QtJson::parseNumbers()
{ "1.1e10", 1.1e10 },
{ "1.1e308", 1.1e308 },
{ "-1.1e308", -1.1e308 },
{ "1.1e-308", 1.1e-308 },
{ "-1.1e-308", -1.1e-308 },
{ "1.1e+308", 1.1e+308 },
{ "-1.1e+308", -1.1e+308 },
{ "1.e+308", 1.e+308 },
@ -2249,6 +2278,31 @@ void tst_QtJson::parseNumbers()
QCOMPARE(val.toDouble(), numbers[i].n);
}
}
{
if constexpr (std::numeric_limits<double>::has_denorm == std::denorm_present) {
Numbers numbers [] = {
{ "1.1e-308", 1.1e-308 },
{ "-1.1e-308", -1.1e-308 }
};
int size = sizeof(numbers)/sizeof(Numbers);
for (int i = 0; i < size; ++i) {
QByteArray json = "[ ";
json += numbers[i].str;
json += " ]";
QJsonDocument doc = QJsonDocument::fromJson(json);
QVERIFY(!doc.isEmpty());
QCOMPARE(doc.isArray(), true);
QCOMPARE(doc.isObject(), false);
QJsonArray array = doc.array();
QCOMPARE(array.size(), 1);
QJsonValue val = array.at(0);
QCOMPARE(val.type(), QJsonValue::Double);
QCOMPARE(val.toDouble(), numbers[i].n);
}
} else {
QSKIP("Skipping 'denorm' as this type lacks denormals on this system");
}
}
}
void tst_QtJson::parseStrings()

View File

@ -1309,6 +1309,12 @@ void tst_QByteArray::number_double()
QFETCH(double, value);
QFETCH(char, format);
QFETCH(int, precision);
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");
}

View File

@ -998,10 +998,24 @@ void tst_QLocale::stringToFloat()
QLocale locale(locale_name);
QCOMPARE(locale.name(), locale_name);
if constexpr (std::numeric_limits<float>::has_denorm != std::denorm_present) {
if (qstrcmp(QTest::currentDataTag(), "C float -min") == 0
|| qstrcmp(QTest::currentDataTag(), "C float min") == 0)
QSKIP("Skipping 'denorm' as this type lacks denormals on this system");
}
bool ok;
float f = locale.toFloat(num_str, &ok);
QCOMPARE(ok, good);
if constexpr (std::numeric_limits<double>::has_denorm != std::denorm_present) {
if (qstrcmp(QTest::currentDataTag(), "C double min") == 0
|| qstrcmp(QTest::currentDataTag(), "C double -min") == 0
|| qstrcmp(QTest::currentDataTag(), "C tiny") == 0
|| qstrcmp(QTest::currentDataTag(), "C -tiny") == 0) {
QSKIP("Skipping 'denorm' as this type lacks denormals on this system");
}
}
{
// Make sure result is independent of locale:
TransientLocale ignoreme(LC_ALL, "ar_SA.UTF-8");

View File

@ -5374,6 +5374,11 @@ void tst_QString::number_double()
QFETCH(double, value);
QFETCH(char, format);
QFETCH(int, precision);
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(QString::number(value, format, precision), "expected");
}

View File

@ -269,6 +269,13 @@ void tst_QLine::testLength()
QCOMPARE(l.length(), qreal(length));
l.setLength(lengthToSet);
if constexpr (std::numeric_limits<double>::has_denorm != std::denorm_present) {
if (qstrcmp(QTest::currentDataTag(), "[tiny,tiny]->|2| (-tiny/2,-tiny/2)") == 0
|| qstrcmp(QTest::currentDataTag(), "[4e-323,5e-324]|1892|") == 0) {
QSKIP("Skipping 'denorm' as this type lacks denormals on this system");
}
}
// Scaling tiny values up to big can be imprecise: don't try to test vx, vy
if (length > 0 && qFuzzyIsNull(length)) {
QVERIFY(l.length() > lengthToSet / 2 && l.length() < lengthToSet * 2);