Long live QTest::addRow()!

This new function does the same as newRow(), except that it has a less confusing
name (in line with _add_Column()), and accepts printf-style arguments to avoid
the need to newRow(qPrintable(QString::asprintf())), a common pattern in client
code. It uses qvsnprintf() under the hoods, avoiding the need for the QString
const char* round-trip.

Port all in-tree users of newRow(qPrintable(QString::asnprintf())) to the new
function.

Change-Id: Icd5de9b7ea4f6759d98080ec30f5aecadb8bec39
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
Marc Mutz 2017-01-05 15:43:21 +01:00
parent d135acfa43
commit b2173b54ef
9 changed files with 71 additions and 17 deletions

View File

@ -208,6 +208,17 @@ void myTestFunction_data()
//! [20]
//! [addRow]
void myTestFunction_data()
{
QTest::addColumn<int>("input");
QTest::addColumn<QString>("output");
QTest::addRow("%d", 0) << 0 << QString("0");
QTest::addRow("%d", 1) << 1 << QString("1");
}
//! [addRow]
//! [21]
void myTestFunction_data() {
QTest::addColumn<int>("intval");

View File

@ -2195,6 +2195,48 @@ QTestData &QTest::newRow(const char *dataTag)
return *tbl->newData(dataTag);
}
/*!
\since 5.9
Appends a new row to the current test data. The function's arguments are passed
to qsnprintf() for formatting according to \a format. See the qvsnprintf()
documentation for caveats and limitations.
The formatted string will appear as the name of this test data in the test output.
Returns a QTestData reference that can be used to stream in data.
Example:
\snippet code/src_qtestlib_qtestcase.cpp addRow
\b {Note:} This function can only be used in a test's data function
that is invoked by the test framework.
See \l {Chapter 2: Data Driven Testing}{Data Driven Testing} for
a more extensive example.
\sa addColumn(), QFETCH()
*/
QTestData &QTest::addRow(const char *format, ...)
{
QTEST_ASSERT_X(format, "QTest::addRow()", "Format string cannot be null");
QTestTable *tbl = QTestTable::currentTestTable();
QTEST_ASSERT_X(tbl, "QTest::addRow()", "Cannot add testdata outside of a _data slot.");
QTEST_ASSERT_X(tbl->elementCount(), "QTest::addRow()", "Must add columns before attempting to add rows.");
char buf[1024];
va_list va;
va_start(va, format);
// we don't care about failures, we accept truncation, as well as trailing garbage.
// Names with more than 1K characters are nonsense, anyway.
(void)qvsnprintf(buf, sizeof buf, format, va);
buf[sizeof buf - 1] = '\0';
va_end(va);
return *tbl->newData(buf);
}
/*! \fn void QTest::addColumn(const char *name, T *dummy = 0)
Adds a column with type \c{T} to the current test data.

View File

@ -316,6 +316,7 @@ namespace QTest
addColumnInternal(qMetaTypeId<T>(), name);
}
Q_TESTLIB_EXPORT QTestData &newRow(const char *dataTag);
Q_TESTLIB_EXPORT QTestData &addRow(const char *format, ...) Q_ATTRIBUTE_FORMAT_PRINTF(1, 2);
template <typename T>
inline bool qCompare(T const &t1, T const &t2, const char *actual, const char *expected,

View File

@ -112,13 +112,13 @@ void tst_QGetPutEnv::intValue_data()
ROW(0xffffffff, 0, false);
const int bases[] = {10, 8, 16};
for (size_t i = 0; i < sizeof bases / sizeof *bases; ++i) {
QTest::newRow(qPrintable(QString::asprintf("INT_MAX, base %d", bases[i])))
QTest::addRow("INT_MAX, base %d", bases[i])
<< QByteArray::number(INT_MAX) << INT_MAX << true;
QTest::newRow(qPrintable(QString::asprintf("INT_MAX+1, base %d", bases[i])))
QTest::addRow("INT_MAX+1, base %d", bases[i])
<< QByteArray::number(qlonglong(INT_MAX) + 1) << 0 << false;
QTest::newRow(qPrintable(QString::asprintf("INT_MIN, base %d", bases[i])))
QTest::addRow("INT_MIN, base %d", bases[i])
<< QByteArray::number(INT_MIN) << INT_MIN << true;
QTest::newRow(qPrintable(QString::asprintf("INT_MIN-1, base %d", bases[i])))
QTest::addRow("INT_MIN-1, base %d", bases[i])
<< QByteArray::number(qlonglong(INT_MIN) - 1) << 0 << false;
};
}

View File

@ -143,7 +143,7 @@ void tst_QMutex::convertToMilliseconds_data()
auto add = [](TimeUnit unit, double d, long long i, qint64 expected) {
const QScopedArrayPointer<char> enumName(QTest::toString(unit));
QTest::newRow(qPrintable(QString::asprintf("%s:%f:%lld", enumName.data(), d, i)))
QTest::addRow("%s:%f:%lld", enumName.data(), d, i)
<< unit << d << qint64(i) << expected;
};

View File

@ -1076,22 +1076,22 @@ void tst_QAlgorithms::popCount_data_impl(size_t sizeof_T_Int)
const uint bits = bitsSetInByte(byte);
const quint64 value = static_cast<quint64>(byte);
const quint64 input = value << ((i % sizeof_T_Int) * 8U);
newRow(qPrintable(QString::asprintf("0x%016llx", input))) << input << bits;
QTest::addRow("0x%016llx", input) << input << bits;
}
// and some random ones:
if (sizeof_T_Int >= 8)
for (size_t i = 0; i < 1000; ++i) {
const quint64 input = quint64(qrand()) << 32 | quint32(qrand());
newRow(qPrintable(QString::asprintf("0x%016llx", input))) << input << bitsSetInInt64(input);
QTest::addRow("0x%016llx", input) << input << bitsSetInInt64(input);
}
else if (sizeof_T_Int >= 2)
for (size_t i = 0; i < 1000 ; ++i) {
const quint32 input = qrand();
if (sizeof_T_Int >= 4)
newRow(qPrintable(QString::asprintf("0x%08x", input))) << quint64(input) << bitsSetInInt(input);
QTest::addRow("0x%08x", input) << quint64(input) << bitsSetInInt(input);
else
newRow(qPrintable(QString::asprintf("0x%04x", quint16(input & 0xFFFF)))) << quint64(input & 0xFFFF) << bitsSetInShort(input & 0xFFFF);
QTest::addRow("0x%04x", quint16(input & 0xFFFF)) << quint64(input & 0xFFFF) << bitsSetInShort(input & 0xFFFF);
}
}

View File

@ -108,7 +108,7 @@ void tst_QChar::operators_data()
for (int i = 0; i < 3; ++i) {
for (int j = 0; j < 3; ++j)
QTest::newRow(qPrintable(QString::asprintf("'\\%d' (op) '\\%d'", i, j)))
QTest::addRow("'\\%d' (op) '\\%d'", i, j)
<< QChar(ushort(i)) << QChar(ushort(j));
}
}

View File

@ -176,9 +176,9 @@ void tst_QLatin1String::relationalOperators_data()
for (Data *lhs = data; lhs != data + sizeof data / sizeof *data; ++lhs) {
for (Data *rhs = data; rhs != data + sizeof data / sizeof *data; ++rhs) {
QLatin1StringContainer l = { lhs->l1 }, r = { rhs->l1 };
QTest::newRow(qPrintable(QString::asprintf("\"%s\" <> \"%s\"",
QTest::addRow("\"%s\" <> \"%s\"",
lhs->l1.data() ? lhs->l1.data() : "nullptr",
rhs->l1.data() ? rhs->l1.data() : "nullptr")))
rhs->l1.data() ? rhs->l1.data() : "nullptr")
<< l << lhs->order << r << rhs->order;
}
}

View File

@ -151,10 +151,10 @@ static void makeRow(QSizePolicy sp, QSizePolicy::Policy hp, QSizePolicy::Policy
int hst, int vst, QSizePolicy::ControlType ct, bool hfw, bool wfh,
Qt::Orientations orients)
{
QTest::newRow(qPrintable(QString::asprintf("%s-%s-%d-%d-%s-%s-%s",
QTest::addRow("%s-%s-%d-%d-%s-%s-%s",
PrettyPrint(hp).s(), PrettyPrint(vp).s(), hst, vst,
PrettyPrint(ct).s(),
hfw ? "true" : "false", wfh ? "true" : "false")))
hfw ? "true" : "false", wfh ? "true" : "false")
<< sp << hp << vp << hst << vst << ct << hfw << wfh << orients;
}