mirror of
https://github.com/eclipse-paho/paho.mqtt.cpp.git
synced 2025-09-15 12:58:39 +08:00
Converted will_options unit tests from CppUnit to Catch2
This commit is contained in:
parent
8602224a64
commit
51da7fb8f3
@ -47,10 +47,13 @@ class connect_options;
|
|||||||
*/
|
*/
|
||||||
class will_options
|
class will_options
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
/** The default QoS for the LWT, if unspecified */
|
/** The default QoS for the LWT, if unspecified */
|
||||||
static constexpr int DFLT_QOS = 0;
|
static constexpr int DFLT_QOS = 0;
|
||||||
/** The defalut retained flag for LWT, if unspecified */
|
/** The defalut retained flag for LWT, if unspecified */
|
||||||
static constexpr bool DFLT_RETAINED = false;
|
static constexpr bool DFLT_RETAINED = false;
|
||||||
|
|
||||||
|
private:
|
||||||
/** A default C struct to support re-initializing variables */
|
/** A default C struct to support re-initializing variables */
|
||||||
static const MQTTAsync_willOptions DFLT_C_STRUCT;
|
static const MQTTAsync_willOptions DFLT_C_STRUCT;
|
||||||
|
|
||||||
@ -169,6 +172,12 @@ public:
|
|||||||
* @param opt The other options.
|
* @param opt The other options.
|
||||||
*/
|
*/
|
||||||
will_options& operator=(will_options&& opt);
|
will_options& operator=(will_options&& opt);
|
||||||
|
/**
|
||||||
|
* Expose the underlying C struct for the unit tests.
|
||||||
|
*/
|
||||||
|
#if defined(UNIT_TESTS)
|
||||||
|
const MQTTAsync_willOptions& c_struct() const { return opts_; }
|
||||||
|
#endif
|
||||||
/**
|
/**
|
||||||
* Gets the LWT message topic name.
|
* Gets the LWT message topic name.
|
||||||
* @return The LWT message topic name.
|
* @return The LWT message topic name.
|
||||||
|
|||||||
@ -20,7 +20,6 @@
|
|||||||
#include "async_client_test.h"
|
#include "async_client_test.h"
|
||||||
#include "async_client_v3_test.h"
|
#include "async_client_v3_test.h"
|
||||||
#include "client_test.h"
|
#include "client_test.h"
|
||||||
#include "will_options_test.h"
|
|
||||||
#include "ssl_options_test.h"
|
#include "ssl_options_test.h"
|
||||||
#include "connect_options_test.h"
|
#include "connect_options_test.h"
|
||||||
#include "disconnect_options_test.h"
|
#include "disconnect_options_test.h"
|
||||||
@ -36,8 +35,6 @@ using namespace CppUnit;
|
|||||||
|
|
||||||
int main(int argc, char* argv[])
|
int main(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
CPPUNIT_TEST_SUITE_REGISTRATION( mqtt::will_options_test );
|
|
||||||
|
|
||||||
#if defined(OPENSSL)
|
#if defined(OPENSSL)
|
||||||
CPPUNIT_TEST_SUITE_REGISTRATION( mqtt::ssl_options_test );
|
CPPUNIT_TEST_SUITE_REGISTRATION( mqtt::ssl_options_test );
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -1,389 +0,0 @@
|
|||||||
// will_options_test.h
|
|
||||||
// Unit tests for the will_options class in the Paho MQTT C++ library.
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
* Copyright (c) 2016 Frank Pagliughi <fpagliughi@mindspring.com>
|
|
||||||
*
|
|
||||||
* All rights reserved. This program and the accompanying materials
|
|
||||||
* are made available under the terms of the Eclipse Public License v1.0
|
|
||||||
* and Eclipse Distribution License v1.0 which accompany this distribution.
|
|
||||||
*
|
|
||||||
* The Eclipse Public License is available at
|
|
||||||
* http://www.eclipse.org/legal/epl-v10.html
|
|
||||||
* and the Eclipse Distribution License is available at
|
|
||||||
* http://www.eclipse.org/org/documents/edl-v10.php.
|
|
||||||
*
|
|
||||||
* Contributors:
|
|
||||||
* Frank Pagliughi - initial implementation and documentation
|
|
||||||
*******************************************************************************/
|
|
||||||
|
|
||||||
#ifndef __mqtt_will_options_test_h
|
|
||||||
#define __mqtt_will_options_test_h
|
|
||||||
|
|
||||||
#include "mqtt/will_options.h"
|
|
||||||
#include "dummy_async_client.h"
|
|
||||||
#include <cppunit/ui/text/TestRunner.h>
|
|
||||||
#include <cppunit/extensions/HelperMacros.h>
|
|
||||||
#include <cstring>
|
|
||||||
|
|
||||||
namespace mqtt {
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
// Note that at this time, the LWT payload has been converted to binary
|
|
||||||
// from the previous version's use of a text string (NUL-terminated C str).
|
|
||||||
// We now fill in the 'payload' fields of the underlying C struct,
|
|
||||||
// MQTTAsync_willOptions. The 'message' field _must_ stay NULL for the C lib
|
|
||||||
// to use 'payload'.
|
|
||||||
|
|
||||||
class will_options_test : public CppUnit::TestFixture
|
|
||||||
{
|
|
||||||
CPPUNIT_TEST_SUITE( will_options_test );
|
|
||||||
|
|
||||||
CPPUNIT_TEST( test_dflt_constructor );
|
|
||||||
CPPUNIT_TEST( test_string_buf_constructor );
|
|
||||||
CPPUNIT_TEST( test_topic_buf_constructor );
|
|
||||||
CPPUNIT_TEST( test_string_string_constructor );
|
|
||||||
CPPUNIT_TEST( test_string_message_constructor );
|
|
||||||
CPPUNIT_TEST( test_copy_constructor );
|
|
||||||
CPPUNIT_TEST( test_move_constructor );
|
|
||||||
CPPUNIT_TEST( test_copy_assignment );
|
|
||||||
CPPUNIT_TEST( test_move_assignment );
|
|
||||||
CPPUNIT_TEST( test_set_topic_str );
|
|
||||||
CPPUNIT_TEST( test_set_payload );
|
|
||||||
|
|
||||||
CPPUNIT_TEST_SUITE_END();
|
|
||||||
|
|
||||||
const std::string EMPTY_STR;
|
|
||||||
const int DFLT_QOS = will_options::DFLT_QOS;
|
|
||||||
const bool DFLT_RETAINED = will_options::DFLT_RETAINED;
|
|
||||||
|
|
||||||
// C struct signature/eyecatcher
|
|
||||||
const char* CSIG = "MQTW";
|
|
||||||
const size_t CSIG_LEN = std::strlen(CSIG);
|
|
||||||
|
|
||||||
const std::string TOPIC = "hello";
|
|
||||||
const char* BUF = "Hello there";
|
|
||||||
const size_t N = std::strlen(BUF);
|
|
||||||
const std::string PAYLOAD = std::string(BUF);
|
|
||||||
const int QOS = 1;
|
|
||||||
const bool RETAINED = true;
|
|
||||||
|
|
||||||
mqtt::will_options orgOpts;
|
|
||||||
|
|
||||||
public:
|
|
||||||
void setUp() {
|
|
||||||
orgOpts = mqtt::will_options(TOPIC, BUF, N, QOS, RETAINED);
|
|
||||||
}
|
|
||||||
void tearDown() {}
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------
|
|
||||||
// Test the default constructor
|
|
||||||
// ----------------------------------------------------------------------
|
|
||||||
|
|
||||||
void test_dflt_constructor() {
|
|
||||||
mqtt::will_options opts;
|
|
||||||
|
|
||||||
CPPUNIT_ASSERT_EQUAL(EMPTY_STR, opts.get_topic());
|
|
||||||
CPPUNIT_ASSERT_EQUAL(EMPTY_STR, opts.get_payload_str());
|
|
||||||
CPPUNIT_ASSERT_EQUAL(DFLT_QOS, opts.get_qos());
|
|
||||||
CPPUNIT_ASSERT_EQUAL(DFLT_RETAINED, opts.is_retained());
|
|
||||||
|
|
||||||
// Test the C struct
|
|
||||||
const auto& c_struct = opts.opts_;
|
|
||||||
|
|
||||||
CPPUNIT_ASSERT(!memcmp(&c_struct.struct_id, CSIG, CSIG_LEN));
|
|
||||||
CPPUNIT_ASSERT(c_struct.topicName != nullptr);
|
|
||||||
CPPUNIT_ASSERT_EQUAL(size_t(0), strlen(c_struct.topicName));
|
|
||||||
CPPUNIT_ASSERT(c_struct.message == nullptr);
|
|
||||||
CPPUNIT_ASSERT_EQUAL(0, c_struct.payload.len);
|
|
||||||
CPPUNIT_ASSERT(c_struct.payload.data == nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------
|
|
||||||
// Test the raw buffer (void*) constructor
|
|
||||||
// ----------------------------------------------------------------------
|
|
||||||
|
|
||||||
void test_string_buf_constructor() {
|
|
||||||
test::dummy_async_client cli;
|
|
||||||
mqtt::topic topic { cli, TOPIC };
|
|
||||||
|
|
||||||
mqtt::will_options opts(topic, BUF, N, QOS, true);
|
|
||||||
|
|
||||||
CPPUNIT_ASSERT_EQUAL(TOPIC, opts.get_topic());
|
|
||||||
CPPUNIT_ASSERT_EQUAL(PAYLOAD, opts.get_payload_str());
|
|
||||||
CPPUNIT_ASSERT_EQUAL(QOS, opts.get_qos());
|
|
||||||
CPPUNIT_ASSERT_EQUAL(RETAINED, opts.is_retained());
|
|
||||||
|
|
||||||
// Test the C struct
|
|
||||||
// Remember we now fill payload fields, not message
|
|
||||||
const auto& c_struct = opts.opts_;
|
|
||||||
|
|
||||||
CPPUNIT_ASSERT(!memcmp(&c_struct.struct_id, CSIG, CSIG_LEN));
|
|
||||||
CPPUNIT_ASSERT(!strcmp(c_struct.topicName, TOPIC.c_str()));
|
|
||||||
CPPUNIT_ASSERT(c_struct.message == nullptr);
|
|
||||||
CPPUNIT_ASSERT_EQUAL(N, size_t(c_struct.payload.len));
|
|
||||||
CPPUNIT_ASSERT(!memcmp(BUF, c_struct.payload.data, N));
|
|
||||||
}
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------
|
|
||||||
// Test the raw buffer (void*) constructor
|
|
||||||
// ----------------------------------------------------------------------
|
|
||||||
|
|
||||||
void test_topic_buf_constructor() {
|
|
||||||
mqtt::will_options opts(TOPIC, BUF, N, QOS, true);
|
|
||||||
|
|
||||||
CPPUNIT_ASSERT_EQUAL(TOPIC, opts.get_topic());
|
|
||||||
CPPUNIT_ASSERT_EQUAL(PAYLOAD, opts.get_payload_str());
|
|
||||||
CPPUNIT_ASSERT_EQUAL(QOS, opts.get_qos());
|
|
||||||
CPPUNIT_ASSERT_EQUAL(RETAINED, opts.is_retained());
|
|
||||||
|
|
||||||
// Test the C struct
|
|
||||||
const auto& c_struct = opts.opts_;
|
|
||||||
|
|
||||||
CPPUNIT_ASSERT(!memcmp(&c_struct.struct_id, CSIG, CSIG_LEN));
|
|
||||||
CPPUNIT_ASSERT(!strcmp(c_struct.topicName, TOPIC.c_str()));
|
|
||||||
CPPUNIT_ASSERT(c_struct.message == nullptr);
|
|
||||||
CPPUNIT_ASSERT_EQUAL(N, size_t(c_struct.payload.len));
|
|
||||||
CPPUNIT_ASSERT(!memcmp(BUF, c_struct.payload.data, N));
|
|
||||||
}
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------
|
|
||||||
// Test the string payload constructor
|
|
||||||
// ----------------------------------------------------------------------
|
|
||||||
|
|
||||||
void test_string_string_constructor() {
|
|
||||||
mqtt::will_options opts(TOPIC, PAYLOAD, QOS, true);
|
|
||||||
|
|
||||||
CPPUNIT_ASSERT_EQUAL(TOPIC, opts.get_topic());
|
|
||||||
CPPUNIT_ASSERT_EQUAL(PAYLOAD, opts.get_payload_str());
|
|
||||||
CPPUNIT_ASSERT_EQUAL(QOS, opts.get_qos());
|
|
||||||
CPPUNIT_ASSERT_EQUAL(RETAINED, opts.is_retained());
|
|
||||||
|
|
||||||
// Test the C struct
|
|
||||||
const auto& c_struct = opts.opts_;
|
|
||||||
|
|
||||||
CPPUNIT_ASSERT(!memcmp(&c_struct.struct_id, CSIG, CSIG_LEN));
|
|
||||||
CPPUNIT_ASSERT(!strcmp(c_struct.topicName, TOPIC.c_str()));
|
|
||||||
CPPUNIT_ASSERT(c_struct.message == nullptr);
|
|
||||||
CPPUNIT_ASSERT_EQUAL(PAYLOAD.size(), size_t(c_struct.payload.len));
|
|
||||||
CPPUNIT_ASSERT(!memcmp(PAYLOAD.data(), c_struct.payload.data, PAYLOAD.size()));
|
|
||||||
}
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------
|
|
||||||
// Test the message payload constructor
|
|
||||||
// ----------------------------------------------------------------------
|
|
||||||
|
|
||||||
void test_string_message_constructor() {
|
|
||||||
mqtt::message msg(TOPIC, PAYLOAD, QOS, true);
|
|
||||||
mqtt::will_options opts(msg);
|
|
||||||
|
|
||||||
CPPUNIT_ASSERT_EQUAL(TOPIC, opts.get_topic());
|
|
||||||
CPPUNIT_ASSERT_EQUAL(PAYLOAD, opts.get_payload_str());
|
|
||||||
CPPUNIT_ASSERT_EQUAL(QOS, opts.get_qos());
|
|
||||||
CPPUNIT_ASSERT_EQUAL(RETAINED, opts.is_retained());
|
|
||||||
|
|
||||||
// Test the C struct
|
|
||||||
const auto& c_struct = opts.opts_;
|
|
||||||
|
|
||||||
CPPUNIT_ASSERT(!memcmp(&c_struct.struct_id, CSIG, CSIG_LEN));
|
|
||||||
CPPUNIT_ASSERT(!strcmp(c_struct.topicName, TOPIC.c_str()));
|
|
||||||
CPPUNIT_ASSERT(c_struct.message == nullptr);
|
|
||||||
CPPUNIT_ASSERT_EQUAL(PAYLOAD.size(), size_t(c_struct.payload.len));
|
|
||||||
CPPUNIT_ASSERT(!memcmp(PAYLOAD.data(), c_struct.payload.data, PAYLOAD.size()));
|
|
||||||
}
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------
|
|
||||||
// Test the copy constructor
|
|
||||||
// ----------------------------------------------------------------------
|
|
||||||
|
|
||||||
void test_copy_constructor() {
|
|
||||||
mqtt::will_options opts(orgOpts);
|
|
||||||
|
|
||||||
CPPUNIT_ASSERT_EQUAL(TOPIC, opts.get_topic());
|
|
||||||
CPPUNIT_ASSERT_EQUAL(PAYLOAD, opts.get_payload_str());
|
|
||||||
CPPUNIT_ASSERT_EQUAL(QOS, opts.get_qos());
|
|
||||||
CPPUNIT_ASSERT_EQUAL(RETAINED, opts.is_retained());
|
|
||||||
|
|
||||||
// Check the C struct
|
|
||||||
const auto& c_struct = opts.opts_;
|
|
||||||
|
|
||||||
CPPUNIT_ASSERT(!memcmp(&c_struct.struct_id, CSIG, CSIG_LEN));
|
|
||||||
CPPUNIT_ASSERT(!strcmp(c_struct.topicName, TOPIC.c_str()));
|
|
||||||
CPPUNIT_ASSERT(c_struct.message == nullptr);
|
|
||||||
CPPUNIT_ASSERT_EQUAL(N, size_t(c_struct.payload.len));
|
|
||||||
CPPUNIT_ASSERT(!memcmp(BUF, c_struct.payload.data, N));
|
|
||||||
|
|
||||||
// Make sure it's a true copy, not linked to the original
|
|
||||||
orgOpts.set_topic(EMPTY_STR);
|
|
||||||
orgOpts.set_payload(EMPTY_STR);
|
|
||||||
orgOpts.set_qos(DFLT_QOS);
|
|
||||||
orgOpts.set_retained(false);
|
|
||||||
|
|
||||||
CPPUNIT_ASSERT_EQUAL(TOPIC, opts.get_topic());
|
|
||||||
CPPUNIT_ASSERT_EQUAL(PAYLOAD, opts.get_payload_str());
|
|
||||||
CPPUNIT_ASSERT_EQUAL(QOS, opts.get_qos());
|
|
||||||
CPPUNIT_ASSERT_EQUAL(RETAINED, opts.is_retained());
|
|
||||||
}
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------
|
|
||||||
// Test the move constructor
|
|
||||||
// ----------------------------------------------------------------------
|
|
||||||
|
|
||||||
void test_move_constructor() {
|
|
||||||
mqtt::will_options opts(std::move(orgOpts));
|
|
||||||
|
|
||||||
CPPUNIT_ASSERT_EQUAL(TOPIC, opts.get_topic());
|
|
||||||
CPPUNIT_ASSERT_EQUAL(PAYLOAD, opts.get_payload_str());
|
|
||||||
CPPUNIT_ASSERT_EQUAL(QOS, opts.get_qos());
|
|
||||||
CPPUNIT_ASSERT_EQUAL(RETAINED, opts.is_retained());
|
|
||||||
|
|
||||||
// Check the C struct
|
|
||||||
const auto& c_struct = opts.opts_;
|
|
||||||
|
|
||||||
CPPUNIT_ASSERT(!memcmp(&c_struct.struct_id, CSIG, CSIG_LEN));
|
|
||||||
CPPUNIT_ASSERT(!strcmp(c_struct.topicName, TOPIC.c_str()));
|
|
||||||
CPPUNIT_ASSERT(c_struct.message == nullptr);
|
|
||||||
CPPUNIT_ASSERT_EQUAL(N, size_t(c_struct.payload.len));
|
|
||||||
CPPUNIT_ASSERT(!memcmp(BUF, c_struct.payload.data, N));
|
|
||||||
|
|
||||||
// Check that the original was moved
|
|
||||||
CPPUNIT_ASSERT_EQUAL(EMPTY_STR, orgOpts.get_topic());
|
|
||||||
CPPUNIT_ASSERT_EQUAL(EMPTY_STR, orgOpts.get_payload_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------
|
|
||||||
// Test the copy assignment operator=(const&)
|
|
||||||
// ----------------------------------------------------------------------
|
|
||||||
|
|
||||||
void test_copy_assignment() {
|
|
||||||
mqtt::will_options opts;
|
|
||||||
|
|
||||||
opts = orgOpts;
|
|
||||||
|
|
||||||
CPPUNIT_ASSERT_EQUAL(TOPIC, opts.get_topic());
|
|
||||||
CPPUNIT_ASSERT_EQUAL(PAYLOAD, opts.get_payload_str());
|
|
||||||
CPPUNIT_ASSERT_EQUAL(QOS, opts.get_qos());
|
|
||||||
CPPUNIT_ASSERT_EQUAL(RETAINED, opts.is_retained());
|
|
||||||
|
|
||||||
// Check the C struct
|
|
||||||
const auto& c_struct = opts.opts_;
|
|
||||||
|
|
||||||
CPPUNIT_ASSERT(!memcmp(&c_struct.struct_id, CSIG, CSIG_LEN));
|
|
||||||
CPPUNIT_ASSERT(!strcmp(c_struct.topicName, TOPIC.c_str()));
|
|
||||||
CPPUNIT_ASSERT(c_struct.message == nullptr);
|
|
||||||
CPPUNIT_ASSERT_EQUAL(N, size_t(c_struct.payload.len));
|
|
||||||
CPPUNIT_ASSERT(!memcmp(BUF, c_struct.payload.data, N));
|
|
||||||
|
|
||||||
// Make sure it's a true copy, not linked to the original
|
|
||||||
orgOpts.set_topic(EMPTY_STR);
|
|
||||||
orgOpts.set_payload(EMPTY_STR);
|
|
||||||
orgOpts.set_qos(DFLT_QOS);
|
|
||||||
orgOpts.set_retained(false);
|
|
||||||
|
|
||||||
CPPUNIT_ASSERT_EQUAL(TOPIC, opts.get_topic());
|
|
||||||
CPPUNIT_ASSERT_EQUAL(PAYLOAD, opts.get_payload_str());
|
|
||||||
CPPUNIT_ASSERT_EQUAL(QOS, opts.get_qos());
|
|
||||||
CPPUNIT_ASSERT_EQUAL(RETAINED, opts.is_retained());
|
|
||||||
|
|
||||||
// Self assignment should cause no harm
|
|
||||||
opts = opts;
|
|
||||||
|
|
||||||
CPPUNIT_ASSERT_EQUAL(TOPIC, opts.get_topic());
|
|
||||||
CPPUNIT_ASSERT_EQUAL(PAYLOAD, opts.get_payload_str());
|
|
||||||
CPPUNIT_ASSERT_EQUAL(QOS, opts.get_qos());
|
|
||||||
CPPUNIT_ASSERT_EQUAL(RETAINED, opts.is_retained());
|
|
||||||
}
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------
|
|
||||||
// Test the move assignment, operator=(&&)
|
|
||||||
// ----------------------------------------------------------------------
|
|
||||||
|
|
||||||
void test_move_assignment() {
|
|
||||||
mqtt::will_options opts;
|
|
||||||
|
|
||||||
opts = std::move(orgOpts);
|
|
||||||
|
|
||||||
CPPUNIT_ASSERT_EQUAL(TOPIC, opts.get_topic());
|
|
||||||
CPPUNIT_ASSERT_EQUAL(PAYLOAD, opts.get_payload_str());
|
|
||||||
CPPUNIT_ASSERT_EQUAL(QOS, opts.get_qos());
|
|
||||||
CPPUNIT_ASSERT_EQUAL(RETAINED, opts.is_retained());
|
|
||||||
|
|
||||||
// Check the C struct
|
|
||||||
const auto& c_struct = opts.opts_;
|
|
||||||
|
|
||||||
CPPUNIT_ASSERT(!memcmp(&c_struct.struct_id, CSIG, CSIG_LEN));
|
|
||||||
CPPUNIT_ASSERT(!strcmp(c_struct.topicName, TOPIC.c_str()));
|
|
||||||
CPPUNIT_ASSERT(c_struct.message == nullptr);
|
|
||||||
CPPUNIT_ASSERT_EQUAL(N, size_t(c_struct.payload.len));
|
|
||||||
CPPUNIT_ASSERT(!memcmp(BUF, c_struct.payload.data, N));
|
|
||||||
|
|
||||||
// Check that the original was moved
|
|
||||||
CPPUNIT_ASSERT_EQUAL(EMPTY_STR, orgOpts.get_topic());
|
|
||||||
CPPUNIT_ASSERT_EQUAL(EMPTY_STR, orgOpts.get_payload_str());
|
|
||||||
|
|
||||||
// Self assignment should cause no harm
|
|
||||||
// (clang++ is smart enough to warn about this)
|
|
||||||
#if !defined(__clang__)
|
|
||||||
opts = std::move(opts);
|
|
||||||
CPPUNIT_ASSERT_EQUAL(TOPIC, opts.get_topic());
|
|
||||||
CPPUNIT_ASSERT_EQUAL(PAYLOAD, opts.get_payload_str());
|
|
||||||
CPPUNIT_ASSERT_EQUAL(QOS, opts.get_qos());
|
|
||||||
CPPUNIT_ASSERT_EQUAL(RETAINED, opts.is_retained());
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------
|
|
||||||
// Test setting the (text) topic
|
|
||||||
// ----------------------------------------------------------------------
|
|
||||||
|
|
||||||
void test_set_topic_str() {
|
|
||||||
mqtt::will_options opts;
|
|
||||||
|
|
||||||
opts.set_topic(TOPIC);
|
|
||||||
CPPUNIT_ASSERT_EQUAL(TOPIC, opts.get_topic());
|
|
||||||
|
|
||||||
const auto& c_struct = opts.opts_;
|
|
||||||
CPPUNIT_ASSERT(!strcmp(c_struct.topicName, TOPIC.c_str()));
|
|
||||||
|
|
||||||
// Setting empty string should _not_ create nullptr entry, in
|
|
||||||
// C struct, rather a valid zero-length string.
|
|
||||||
opts.set_topic(EMPTY_STR);
|
|
||||||
|
|
||||||
CPPUNIT_ASSERT_EQUAL(EMPTY_STR, opts.get_topic());
|
|
||||||
CPPUNIT_ASSERT(opts.opts_.topicName != nullptr);
|
|
||||||
CPPUNIT_ASSERT_EQUAL(size_t(0), strlen(opts.opts_.topicName));
|
|
||||||
}
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------
|
|
||||||
// Test setting the (binary) payload
|
|
||||||
// ----------------------------------------------------------------------
|
|
||||||
|
|
||||||
void test_set_payload() {
|
|
||||||
mqtt::will_options opts;
|
|
||||||
|
|
||||||
opts.set_payload(PAYLOAD);
|
|
||||||
CPPUNIT_ASSERT_EQUAL(PAYLOAD, opts.get_payload_str());
|
|
||||||
|
|
||||||
const auto& c_struct = opts.opts_;
|
|
||||||
|
|
||||||
CPPUNIT_ASSERT_EQUAL(PAYLOAD.size(), size_t(c_struct.payload.len));
|
|
||||||
CPPUNIT_ASSERT(!memcmp(PAYLOAD.data(), c_struct.payload.data, PAYLOAD.size()));
|
|
||||||
|
|
||||||
// Setting empty string set a valid, but zero-len payload
|
|
||||||
// TODO: We need to check what the C lib now accepts.
|
|
||||||
opts.set_payload(EMPTY_STR);
|
|
||||||
|
|
||||||
CPPUNIT_ASSERT_EQUAL(EMPTY_STR, opts.get_payload_str());
|
|
||||||
CPPUNIT_ASSERT_EQUAL(size_t(0), opts.get_payload().size());
|
|
||||||
|
|
||||||
CPPUNIT_ASSERT_EQUAL(0, opts.opts_.payload.len);
|
|
||||||
CPPUNIT_ASSERT(opts.opts_.payload.data != nullptr);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
// end namespace mqtt
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // __mqtt_will_options_test_h
|
|
||||||
@ -34,6 +34,7 @@ add_executable(unit_tests unit_tests.cpp
|
|||||||
test_properties.cpp
|
test_properties.cpp
|
||||||
test_string_collection.cpp
|
test_string_collection.cpp
|
||||||
test_topic.cpp
|
test_topic.cpp
|
||||||
|
test_will_options.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
# --- Link for executables ---
|
# --- Link for executables ---
|
||||||
|
|||||||
366
test/unit/test_will_options.cpp
Normal file
366
test/unit/test_will_options.cpp
Normal file
@ -0,0 +1,366 @@
|
|||||||
|
// test_will_options.cpp
|
||||||
|
//
|
||||||
|
// Unit tests for the will_options class in the Paho MQTT C++ library.
|
||||||
|
//
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2016-2020 Frank Pagliughi <fpagliughi@mindspring.com>
|
||||||
|
*
|
||||||
|
* All rights reserved. This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
|
* and Eclipse Distribution License v1.0 which accompany this distribution.
|
||||||
|
*
|
||||||
|
* The Eclipse Public License is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
* and the Eclipse Distribution License is available at
|
||||||
|
* http://www.eclipse.org/org/documents/edl-v10.php.
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* Frank Pagliughi - initial implementation and documentation
|
||||||
|
*******************************************************************************/
|
||||||
|
|
||||||
|
#define UNIT_TESTS
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
|
#include "catch2/catch.hpp"
|
||||||
|
#include "mqtt/will_options.h"
|
||||||
|
#include "mock_async_client.h"
|
||||||
|
|
||||||
|
using namespace mqtt;
|
||||||
|
|
||||||
|
static const std::string EMPTY_STR;
|
||||||
|
static const int DFLT_QOS = will_options::DFLT_QOS;
|
||||||
|
static const bool DFLT_RETAINED = will_options::DFLT_RETAINED;
|
||||||
|
|
||||||
|
// C struct signature/eyecatcher
|
||||||
|
static const char* CSIG = "MQTW";
|
||||||
|
static const size_t CSIG_LEN = std::strlen(CSIG);
|
||||||
|
|
||||||
|
static const std::string TOPIC = "hello";
|
||||||
|
static const char* BUF = "Hello there";
|
||||||
|
static const size_t N = std::strlen(BUF);
|
||||||
|
static const std::string PAYLOAD = std::string(BUF);
|
||||||
|
static const int QOS = 1;
|
||||||
|
static const bool RETAINED = true;
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// Test the default constructor
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
TEST_CASE("will_options default ctor", "[options]")
|
||||||
|
{
|
||||||
|
mqtt::will_options opts;
|
||||||
|
|
||||||
|
REQUIRE(EMPTY_STR == opts.get_topic());
|
||||||
|
REQUIRE(EMPTY_STR == opts.get_payload_str());
|
||||||
|
REQUIRE(DFLT_QOS == opts.get_qos());
|
||||||
|
REQUIRE(DFLT_RETAINED == opts.is_retained());
|
||||||
|
|
||||||
|
// Test the C struct
|
||||||
|
const auto& c_struct = opts.c_struct();
|
||||||
|
|
||||||
|
REQUIRE(0 == memcmp(&c_struct.struct_id, CSIG, CSIG_LEN));
|
||||||
|
REQUIRE(c_struct.topicName != nullptr);
|
||||||
|
REQUIRE(size_t(0) == strlen(c_struct.topicName));
|
||||||
|
REQUIRE(c_struct.message == nullptr);
|
||||||
|
REQUIRE(0 == c_struct.payload.len);
|
||||||
|
REQUIRE(c_struct.payload.data == nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// Test the raw buffer (void*) constructor
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
TEST_CASE("will_options string buf ctor", "[options]")
|
||||||
|
{
|
||||||
|
test::mock_async_client cli;
|
||||||
|
mqtt::topic topic { cli, TOPIC };
|
||||||
|
|
||||||
|
mqtt::will_options opts(topic, BUF, N, QOS, true);
|
||||||
|
|
||||||
|
REQUIRE(TOPIC == opts.get_topic());
|
||||||
|
REQUIRE(PAYLOAD == opts.get_payload_str());
|
||||||
|
REQUIRE(QOS == opts.get_qos());
|
||||||
|
REQUIRE(RETAINED == opts.is_retained());
|
||||||
|
|
||||||
|
// Test the C struct
|
||||||
|
// Remember we now fill payload fields, not message
|
||||||
|
const auto& c_struct = opts.c_struct();
|
||||||
|
|
||||||
|
REQUIRE(0 == memcmp(&c_struct.struct_id, CSIG, CSIG_LEN));
|
||||||
|
REQUIRE(0 == strcmp(c_struct.topicName, TOPIC.c_str()));
|
||||||
|
REQUIRE(c_struct.message == nullptr);
|
||||||
|
REQUIRE(N == size_t(c_struct.payload.len));
|
||||||
|
REQUIRE(0 == memcmp(BUF, c_struct.payload.data, N));
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// Test the raw buffer (void*) constructor
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
TEST_CASE("will_options topic buf ctor", "[options]")
|
||||||
|
{
|
||||||
|
mqtt::will_options opts(TOPIC, BUF, N, QOS, true);
|
||||||
|
|
||||||
|
REQUIRE(TOPIC == opts.get_topic());
|
||||||
|
REQUIRE(PAYLOAD == opts.get_payload_str());
|
||||||
|
REQUIRE(QOS == opts.get_qos());
|
||||||
|
REQUIRE(RETAINED == opts.is_retained());
|
||||||
|
|
||||||
|
// Test the C struct
|
||||||
|
const auto& c_struct = opts.c_struct();
|
||||||
|
|
||||||
|
REQUIRE(0 == memcmp(&c_struct.struct_id, CSIG, CSIG_LEN));
|
||||||
|
REQUIRE(0 == strcmp(c_struct.topicName, TOPIC.c_str()));
|
||||||
|
REQUIRE(c_struct.message == nullptr);
|
||||||
|
REQUIRE(N == size_t(c_struct.payload.len));
|
||||||
|
REQUIRE(0 == memcmp(BUF, c_struct.payload.data, N));
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// Test the string payload constructor
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
TEST_CASE("will_options string string ctor", "[options]")
|
||||||
|
{
|
||||||
|
mqtt::will_options opts(TOPIC, PAYLOAD, QOS, true);
|
||||||
|
|
||||||
|
REQUIRE(TOPIC == opts.get_topic());
|
||||||
|
REQUIRE(PAYLOAD == opts.get_payload_str());
|
||||||
|
REQUIRE(QOS == opts.get_qos());
|
||||||
|
REQUIRE(RETAINED == opts.is_retained());
|
||||||
|
|
||||||
|
// Test the C struct
|
||||||
|
const auto& c_struct = opts.c_struct();
|
||||||
|
|
||||||
|
REQUIRE(0 == memcmp(&c_struct.struct_id, CSIG, CSIG_LEN));
|
||||||
|
REQUIRE(0 == strcmp(c_struct.topicName, TOPIC.c_str()));
|
||||||
|
REQUIRE(c_struct.message == nullptr);
|
||||||
|
REQUIRE(PAYLOAD.size() == size_t(c_struct.payload.len));
|
||||||
|
REQUIRE(0 == memcmp(PAYLOAD.data(), c_struct.payload.data, PAYLOAD.size()));
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// Test the message payload constructor
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
TEST_CASE("will_options string message ctor", "[options]")
|
||||||
|
{
|
||||||
|
mqtt::message msg(TOPIC, PAYLOAD, QOS, true);
|
||||||
|
mqtt::will_options opts(msg);
|
||||||
|
|
||||||
|
REQUIRE(TOPIC == opts.get_topic());
|
||||||
|
REQUIRE(PAYLOAD == opts.get_payload_str());
|
||||||
|
REQUIRE(QOS == opts.get_qos());
|
||||||
|
REQUIRE(RETAINED == opts.is_retained());
|
||||||
|
|
||||||
|
// Test the C struct
|
||||||
|
const auto& c_struct = opts.c_struct();
|
||||||
|
|
||||||
|
REQUIRE(0 == memcmp(&c_struct.struct_id, CSIG, CSIG_LEN));
|
||||||
|
REQUIRE(0 == strcmp(c_struct.topicName, TOPIC.c_str()));
|
||||||
|
REQUIRE(c_struct.message == nullptr);
|
||||||
|
REQUIRE(PAYLOAD.size() == size_t(c_struct.payload.len));
|
||||||
|
REQUIRE(0 == memcmp(PAYLOAD.data(), c_struct.payload.data, PAYLOAD.size()));
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// Test the copy constructor
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
TEST_CASE("will_options copy ctor", "[options]")
|
||||||
|
{
|
||||||
|
auto orgOpts = mqtt::will_options(TOPIC, BUF, N, QOS, RETAINED);
|
||||||
|
|
||||||
|
mqtt::will_options opts(orgOpts);
|
||||||
|
|
||||||
|
REQUIRE(TOPIC == opts.get_topic());
|
||||||
|
REQUIRE(PAYLOAD == opts.get_payload_str());
|
||||||
|
REQUIRE(QOS == opts.get_qos());
|
||||||
|
REQUIRE(RETAINED == opts.is_retained());
|
||||||
|
|
||||||
|
// Check the C struct
|
||||||
|
const auto& c_struct = opts.c_struct();
|
||||||
|
|
||||||
|
REQUIRE(0 == memcmp(&c_struct.struct_id, CSIG, CSIG_LEN));
|
||||||
|
REQUIRE(0 == strcmp(c_struct.topicName, TOPIC.c_str()));
|
||||||
|
REQUIRE(c_struct.message == nullptr);
|
||||||
|
REQUIRE(N == size_t(c_struct.payload.len));
|
||||||
|
REQUIRE(0 == memcmp(BUF, c_struct.payload.data, N));
|
||||||
|
|
||||||
|
// Make sure it's a true copy, not linked to the original
|
||||||
|
orgOpts.set_topic(EMPTY_STR);
|
||||||
|
orgOpts.set_payload(EMPTY_STR);
|
||||||
|
orgOpts.set_qos(DFLT_QOS);
|
||||||
|
orgOpts.set_retained(false);
|
||||||
|
|
||||||
|
REQUIRE(TOPIC == opts.get_topic());
|
||||||
|
REQUIRE(PAYLOAD == opts.get_payload_str());
|
||||||
|
REQUIRE(QOS == opts.get_qos());
|
||||||
|
REQUIRE(RETAINED == opts.is_retained());
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// Test the move constructor
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
TEST_CASE("will_options move ctor", "[options]")
|
||||||
|
{
|
||||||
|
auto orgOpts = mqtt::will_options(TOPIC, BUF, N, QOS, RETAINED);
|
||||||
|
|
||||||
|
mqtt::will_options opts(std::move(orgOpts));
|
||||||
|
|
||||||
|
REQUIRE(TOPIC == opts.get_topic());
|
||||||
|
REQUIRE(PAYLOAD == opts.get_payload_str());
|
||||||
|
REQUIRE(QOS == opts.get_qos());
|
||||||
|
REQUIRE(RETAINED == opts.is_retained());
|
||||||
|
|
||||||
|
// Check the C struct
|
||||||
|
const auto& c_struct = opts.c_struct();
|
||||||
|
|
||||||
|
REQUIRE(0 == memcmp(&c_struct.struct_id, CSIG, CSIG_LEN));
|
||||||
|
REQUIRE(0 == strcmp(c_struct.topicName, TOPIC.c_str()));
|
||||||
|
REQUIRE(c_struct.message == nullptr);
|
||||||
|
REQUIRE(N == size_t(c_struct.payload.len));
|
||||||
|
REQUIRE(0 == memcmp(BUF, c_struct.payload.data, N));
|
||||||
|
|
||||||
|
// Check that the original was moved
|
||||||
|
REQUIRE(EMPTY_STR == orgOpts.get_topic());
|
||||||
|
REQUIRE(EMPTY_STR == orgOpts.get_payload_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// Test the copy assignment operator=(const&)
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
TEST_CASE("will_options copy assignment", "[options]")
|
||||||
|
{
|
||||||
|
auto orgOpts = mqtt::will_options(TOPIC, BUF, N, QOS, RETAINED);
|
||||||
|
|
||||||
|
mqtt::will_options opts;
|
||||||
|
opts = orgOpts;
|
||||||
|
|
||||||
|
REQUIRE(TOPIC == opts.get_topic());
|
||||||
|
REQUIRE(PAYLOAD == opts.get_payload_str());
|
||||||
|
REQUIRE(QOS == opts.get_qos());
|
||||||
|
REQUIRE(RETAINED == opts.is_retained());
|
||||||
|
|
||||||
|
// Check the C struct
|
||||||
|
const auto& c_struct = opts.c_struct();
|
||||||
|
|
||||||
|
REQUIRE(0 == memcmp(&c_struct.struct_id, CSIG, CSIG_LEN));
|
||||||
|
REQUIRE(0 == strcmp(c_struct.topicName, TOPIC.c_str()));
|
||||||
|
REQUIRE(c_struct.message == nullptr);
|
||||||
|
REQUIRE(N == size_t(c_struct.payload.len));
|
||||||
|
REQUIRE(0 == memcmp(BUF, c_struct.payload.data, N));
|
||||||
|
|
||||||
|
// Make sure it's a true copy, not linked to the original
|
||||||
|
orgOpts.set_topic(EMPTY_STR);
|
||||||
|
orgOpts.set_payload(EMPTY_STR);
|
||||||
|
orgOpts.set_qos(DFLT_QOS);
|
||||||
|
orgOpts.set_retained(false);
|
||||||
|
|
||||||
|
REQUIRE(TOPIC == opts.get_topic());
|
||||||
|
REQUIRE(PAYLOAD == opts.get_payload_str());
|
||||||
|
REQUIRE(QOS == opts.get_qos());
|
||||||
|
REQUIRE(RETAINED == opts.is_retained());
|
||||||
|
|
||||||
|
// Self assignment should cause no harm
|
||||||
|
opts = opts;
|
||||||
|
|
||||||
|
REQUIRE(TOPIC == opts.get_topic());
|
||||||
|
REQUIRE(PAYLOAD == opts.get_payload_str());
|
||||||
|
REQUIRE(QOS == opts.get_qos());
|
||||||
|
REQUIRE(RETAINED == opts.is_retained());
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// Test the move assignment, operator=(&&)
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
TEST_CASE("will_options move assignment", "[options]")
|
||||||
|
{
|
||||||
|
auto orgOpts = mqtt::will_options(TOPIC, BUF, N, QOS, RETAINED);
|
||||||
|
|
||||||
|
mqtt::will_options opts;
|
||||||
|
opts = std::move(orgOpts);
|
||||||
|
|
||||||
|
REQUIRE(TOPIC == opts.get_topic());
|
||||||
|
REQUIRE(PAYLOAD == opts.get_payload_str());
|
||||||
|
REQUIRE(QOS == opts.get_qos());
|
||||||
|
REQUIRE(RETAINED == opts.is_retained());
|
||||||
|
|
||||||
|
// Check the C struct
|
||||||
|
const auto& c_struct = opts.c_struct();
|
||||||
|
|
||||||
|
REQUIRE(0 == memcmp(&c_struct.struct_id, CSIG, CSIG_LEN));
|
||||||
|
REQUIRE(0 == strcmp(c_struct.topicName, TOPIC.c_str()));
|
||||||
|
REQUIRE(c_struct.message == nullptr);
|
||||||
|
REQUIRE(N == size_t(c_struct.payload.len));
|
||||||
|
REQUIRE(0 == memcmp(BUF, c_struct.payload.data, N));
|
||||||
|
|
||||||
|
// Check that the original was moved
|
||||||
|
REQUIRE(EMPTY_STR == orgOpts.get_topic());
|
||||||
|
REQUIRE(EMPTY_STR == orgOpts.get_payload_str());
|
||||||
|
|
||||||
|
// Self assignment should cause no harm
|
||||||
|
// (clang++ is smart enough to warn about this)
|
||||||
|
#if !defined(__clang__)
|
||||||
|
opts = std::move(opts);
|
||||||
|
REQUIRE(TOPIC == opts.get_topic());
|
||||||
|
REQUIRE(PAYLOAD == opts.get_payload_str());
|
||||||
|
REQUIRE(QOS == opts.get_qos());
|
||||||
|
REQUIRE(RETAINED == opts.is_retained());
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// Test setting the (text) topic
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
TEST_CASE("will_options set_topic_str", "[options]")
|
||||||
|
{
|
||||||
|
mqtt::will_options opts;
|
||||||
|
|
||||||
|
opts.set_topic(TOPIC);
|
||||||
|
REQUIRE(TOPIC == opts.get_topic());
|
||||||
|
|
||||||
|
const auto& c_struct = opts.c_struct();
|
||||||
|
REQUIRE(0 == strcmp(c_struct.topicName, TOPIC.c_str()));
|
||||||
|
|
||||||
|
// Setting empty string should _not_ create nullptr entry, in
|
||||||
|
// C struct, rather a valid zero-length string.
|
||||||
|
opts.set_topic(EMPTY_STR);
|
||||||
|
|
||||||
|
REQUIRE(EMPTY_STR == opts.get_topic());
|
||||||
|
REQUIRE(c_struct.topicName != nullptr);
|
||||||
|
REQUIRE(size_t(0) == strlen(c_struct.topicName));
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// Test setting the (binary) payload
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
TEST_CASE("will_options set_payload", "[options]")
|
||||||
|
{
|
||||||
|
mqtt::will_options opts;
|
||||||
|
|
||||||
|
opts.set_payload(PAYLOAD);
|
||||||
|
REQUIRE(PAYLOAD == opts.get_payload_str());
|
||||||
|
|
||||||
|
const auto& c_struct = opts.c_struct();
|
||||||
|
|
||||||
|
REQUIRE(PAYLOAD.size() == size_t(c_struct.payload.len));
|
||||||
|
REQUIRE(0 == memcmp(PAYLOAD.data(), c_struct.payload.data, PAYLOAD.size()));
|
||||||
|
|
||||||
|
// Setting empty string set a valid, but zero-len payload
|
||||||
|
// TODO: We need to check what the C lib now accepts.
|
||||||
|
opts.set_payload(EMPTY_STR);
|
||||||
|
|
||||||
|
REQUIRE(EMPTY_STR == opts.get_payload_str());
|
||||||
|
REQUIRE(size_t(0) == opts.get_payload().size());
|
||||||
|
|
||||||
|
REQUIRE(0 == c_struct.payload.len);
|
||||||
|
REQUIRE(c_struct.payload.data != nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
Loading…
Reference in New Issue
Block a user