Revision control

Copy as Markdown

// Copyright (C) 2017 Witekio.
// Copyright (C) 2018 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QtTest>
#include <QCoreApplication>
#include <QtCoap/qcoapmessage.h>
class tst_QCoapMessage : public QObject
{
Q_OBJECT
private Q_SLOTS:
void copyAndDetach();
void setType_data();
void setType();
void addOption();
void addOption_string_data();
void addOption_string();
void addOption_uint_data();
void addOption_uint();
void removeOption_data();
void removeOption();
void removeOptionByName_data();
void removeOptionByName();
void removeAll();
};
void tst_QCoapMessage::copyAndDetach()
{
QCoapMessage a;
a.setMessageId(3);
a.setPayload("payload");
a.setToken("token");
a.setType(QCoapMessage::Type::Acknowledgment);
a.setVersion(5);
// Test the copy
QCoapMessage b(a);
QVERIFY2(b.messageId() == 3, "Message not copied correctly");
QVERIFY2(b.payload() == "payload", "Message not copied correctly");
QVERIFY2(b.token() == "token", "Message not copied correctly");
QVERIFY2(b.type() == QCoapMessage::Type::Acknowledgment, "Message not copied correctly");
QVERIFY2(b.version() == 5, "Message not copied correctly");
// Detach
b.setMessageId(9);
QCOMPARE(b.messageId(), 9);
QCOMPARE(a.messageId(), 3);
}
void tst_QCoapMessage::setType_data()
{
QTest::addColumn<QCoapMessage::Type>("type");
QTest::newRow("acknowledgment") << QCoapMessage::Type::Acknowledgment;
QTest::newRow("confirmable") << QCoapMessage::Type::Confirmable;
QTest::newRow("non-confirmable") << QCoapMessage::Type::NonConfirmable;
QTest::newRow("reset") << QCoapMessage::Type::Reset;
}
void tst_QCoapMessage::setType()
{
QFETCH(QCoapMessage::Type, type);
QCoapMessage message;
message.setType(type);
QCOMPARE(message.type(), type);
}
void tst_QCoapMessage::addOption()
{
QCoapMessage message;
QList<QCoapOption::OptionName> optionNames = {
QCoapOption::ProxyUri,
QCoapOption::UriHost,
QCoapOption::LocationQuery,
QCoapOption::ProxyUri,
QCoapOption::UriHost,
QCoapOption::UriQuery
};
QVERIFY(!std::is_sorted(optionNames.cbegin(), optionNames.cend()));
const QByteArray value("\xAF\x01\xC2");
for (const auto& name : optionNames)
message.addOption(name, value);
QCOMPARE(message.optionCount(), optionNames.size());
QVERIFY(std::is_sorted(message.options().cbegin(), message.options().cend(),
[](const QCoapOption &a, const QCoapOption &b) -> bool {
return a.name() < b.name();
}));
for (const auto& name : optionNames)
QVERIFY2(message.hasOption(name), qPrintable(QString("Missing option %1").arg(name)));
QVERIFY(std::all_of(message.options().cbegin(), message.options().cend(),
[value](const QCoapOption opt) -> bool {
return opt.opaqueValue() == value;
}));
}
void tst_QCoapMessage::addOption_string_data()
{
QTest::addColumn<QList<QCoapOption>>("options");
QList<QCoapOption> single_string_option = { { QCoapOption::LocationPath, QString("path1") } };
QList<QCoapOption> single_ba_option = {
{ QCoapOption::LocationPath, QByteArray("\xAF\x01\xC2") }
};
QList<QCoapOption> multiple_string_options = {
{ QCoapOption::LocationPath, QString("str_path2") },
{ QCoapOption::LocationPath, QString("str_path3") }
};
QTest::newRow("single_char_option") << single_string_option;
QTest::newRow("single_ba_option") << single_ba_option;
QTest::newRow("multiple_string_options") << multiple_string_options;
}
void tst_QCoapMessage::addOption_string()
{
QFETCH(QList<QCoapOption>, options);
QCoapMessage message;
for (const auto& option : options)
message.addOption(option);
QCOMPARE(message.optionCount(), options.size());
for (const auto& option : options)
{
const auto it = std::find(message.options().cbegin(), message.options().cend(), option);
QVERIFY(it != message.options().cend());
}
}
void tst_QCoapMessage::addOption_uint_data()
{
QTest::addColumn<quint32>("value");
QTest::addColumn<int>("size");
QTest::newRow("4 bytes") << static_cast<quint32>(0xF0aF0010) << 4;
QTest::newRow("3 bytes") << static_cast<quint32>(0x300010) << 3;
QTest::newRow("2 bytes") << static_cast<quint32>(0x5010) << 2;
QTest::newRow("1 byte") << static_cast<quint32>(0x80) << 1;
}
void tst_QCoapMessage::addOption_uint()
{
QFETCH(quint32, value);
QFETCH(int, size);
const auto name = QCoapOption::Block1;
const QCoapOption option(name, value);
QCoapMessage message;
message.addOption(option);
QCOMPARE(message.options(name).size(), 1);
QCOMPARE(message.option(name).uintValue(), value);
QCOMPARE(option.opaqueValue().size(), size);
}
void tst_QCoapMessage::removeOption_data()
{
QTest::addColumn<QList<QCoapOption>>("options");
QList<QCoapOption> single_option = { { QCoapOption::LocationPath, QByteArray("path1") } };
QList<QCoapOption> multiple_options = {
{ QCoapOption::LocationPath, QByteArray("path2") },
{ QCoapOption::LocationPath, QByteArray("path3") }
};
QTest::newRow("single_option") << single_option;
QTest::newRow("multiple_options") << multiple_options;
}
void tst_QCoapMessage::removeOption()
{
QFETCH(QList<QCoapOption>, options);
QCoapMessage message;
for (const auto& option : options)
message.addOption(option);
for (const auto& option : options)
{
// Make sure option is present before removal
auto it = std::find(message.options().cbegin(), message.options().cend(), option);
QVERIFY(it != message.options().end());
message.removeOption(option);
it = std::find(message.options().cbegin(), message.options().cend(), option);
QVERIFY(it == message.options().end());
}
}
void tst_QCoapMessage::removeOptionByName_data()
{
QTest::addColumn<QList<QCoapOption>>("options");
QTest::addColumn<QCoapOption::OptionName>("name");
QList<QCoapOption> single_option = { { QCoapOption::LocationPath, QByteArray("path1") } };
QList<QCoapOption> multiple_options = {
{ QCoapOption::LocationPath, QByteArray("path2") },
{ QCoapOption::LocationPath, QByteArray("path3") }
};
QTest::newRow("remove_single_option") << single_option << single_option.back().name();
QTest::newRow("remove_multiple_options") << multiple_options << multiple_options.back().name();
}
void tst_QCoapMessage::removeOptionByName()
{
QFETCH(QList<QCoapOption>, options);
QFETCH(QCoapOption::OptionName, name);
QCoapMessage message;
for (const auto& option : options)
message.addOption(option);
message.removeOption(name);
QVERIFY(!message.hasOption(name));
}
void tst_QCoapMessage::removeAll()
{
QCoapMessage message;
message.addOption(QCoapOption::LocationPath, "path");
message.addOption(QCoapOption::ProxyUri, "proxy1");
message.addOption(QCoapOption::ProxyUri, "proxy2");
message.clearOptions();
QVERIFY(message.options().isEmpty());
}
QTEST_APPLESS_MAIN(tst_QCoapMessage)
#include "tst_qcoapmessage.moc"