From 9e5c9cb7771c4aef289be5b3ab592aed6423b550 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Tue, 17 Nov 2020 23:48:46 +0100 Subject: [PATCH 1/4] nutclient.cpp: match a copy constructor with a copy assignment operator (Device, Variable, Command classes) --- clients/nutclient.cpp | 33 +++++++++++++++++++++++++++++++++ clients/nutclient.h | 3 +++ 2 files changed, 36 insertions(+) diff --git a/clients/nutclient.cpp b/clients/nutclient.cpp index bb06ebbabb..18bb9be681 100644 --- a/clients/nutclient.cpp +++ b/clients/nutclient.cpp @@ -1084,6 +1084,17 @@ _name(dev._name) { } +Device& Device::operator=(const Device& dev) +{ + // Self assignment? + if (this==&dev) + return *this; + + _client = dev._client; + _name = dev._name; + return *this; +} + Device::~Device() { } @@ -1283,6 +1294,17 @@ _name(var._name) { } +Variable& Variable::operator=(const Variable& var) +{ + // Self assignment? + if (this==&var) + return *this; + + _device = var._device; + _name = var._name; + return *this; +} + Variable::~Variable() { } @@ -1367,6 +1389,17 @@ _name(cmd._name) { } +Command& Command::operator=(const Command& cmd) +{ + // Self assignment? + if (this==&cmd) + return *this; + + _device = cmd._device; + _name = cmd._name; + return *this; +} + Command::~Command() { } diff --git a/clients/nutclient.h b/clients/nutclient.h index 3006aae86a..1d032455e0 100644 --- a/clients/nutclient.h +++ b/clients/nutclient.h @@ -460,6 +460,7 @@ class Device public: ~Device(); Device(const Device& dev); + Device& operator=(const Device& dev); /** * Retrieve the name of the device. @@ -609,6 +610,7 @@ class Variable ~Variable(); Variable(const Variable& var); + Variable& operator=(const Variable& var); /** * Retrieve variable name. @@ -688,6 +690,7 @@ class Command ~Command(); Command(const Command& cmd); + Command& operator=(const Command& cmd); /** * Retrieve command name. From 615cfb35274edd2a953f56925c9a5a8a7e663a5c Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Tue, 24 Nov 2020 23:50:42 +0100 Subject: [PATCH 2/4] clients/nutclient.h: whitespace fixes (indentations) --- clients/nutclient.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/clients/nutclient.h b/clients/nutclient.h index 1d032455e0..081d1aa836 100644 --- a/clients/nutclient.h +++ b/clients/nutclient.h @@ -482,22 +482,22 @@ class Device bool isOk()const; /** * Test if the device is valid (has a name and is attached to a client). - * @see Device::isOk() + * @see Device::isOk() */ operator bool()const; /** * Test if the device is not valid (has no name or is not attached to any client). - * @see Device::isOk() + * @see Device::isOk() */ bool operator!()const; /** * Test if the two devices are sames (same name ad same client attached to). */ bool operator==(const Device& dev)const; - /** - * Comparison operator. - */ - bool operator<(const Device& dev)const; + /** + * Comparison operator. + */ + bool operator<(const Device& dev)const; /** * Retrieve the description of the devce if specified. @@ -507,7 +507,7 @@ class Device /** * Intend to retrieve the value of a variable of the device. * \param name Name of the variable to get. - * \return Value of the variable, if available. + * \return Value of the variable, if available. */ std::vector getVariableValue(const std::string& name); /** @@ -540,7 +540,7 @@ class Device /** * Retrieve a Variable object representing the specified variable. - * \param name Variable name. + * \param name Variable name. * \return Variable object. */ Variable getVariable(const std::string& name); From 7802a620fef8b03ecd2124439ed1599ad5812e14 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Tue, 24 Nov 2020 23:53:27 +0100 Subject: [PATCH 3/4] clients/nutclient.cpp: whitespace fixes (indentations, blank lines) --- clients/nutclient.cpp | 96 +++++++++++++++++++------------------------ 1 file changed, 42 insertions(+), 54 deletions(-) diff --git a/clients/nutclient.cpp b/clients/nutclient.cpp index 18bb9be681..d0170c3919 100644 --- a/clients/nutclient.cpp +++ b/clients/nutclient.cpp @@ -184,7 +184,7 @@ void Socket::connect(const std::string& host, int port) { case EAFNOSUPPORT: case EINVAL: - break; + break; default: throw nut::SystemException(); } @@ -437,7 +437,7 @@ std::set Client::getDevices() std::set devs = getDeviceNames(); for(std::set::iterator it=devs.begin(); it!=devs.end(); ++it) { - res.insert(Device(this, *it)); + res.insert(Device(this, *it)); } return res; @@ -451,16 +451,16 @@ bool Client::hasDeviceVariable(const std::string& dev, const std::string& name) std::map > Client::getDeviceVariableValues(const std::string& dev) { - std::map > res; + std::map > res; - std::set names = getDeviceVariableNames(dev); - for(std::set::iterator it=names.begin(); it!=names.end(); ++it) - { - const std::string& name = *it; - res[name] = getDeviceVariableValue(dev, name); - } + std::set names = getDeviceVariableNames(dev); + for(std::set::iterator it=names.begin(); it!=names.end(); ++it) + { + const std::string& name = *it; + res[name] = getDeviceVariableValue(dev, name); + } - return res; + return res; } std::map > > Client::getDevicesVariableValues(const std::set& devs) @@ -477,8 +477,8 @@ std::map > > Client::g bool Client::hasDeviceCommand(const std::string& dev, const std::string& name) { - std::set names = getDeviceCommandNames(dev); - return names.find(name) != names.end(); + std::set names = getDeviceCommandNames(dev); + return names.find(name) != names.end(); } bool Client::hasFeature(const Feature& feature) @@ -612,7 +612,7 @@ std::set TcpClient::getDeviceNames() std::string TcpClient::getDeviceDescription(const std::string& name) { - return get("UPSDESC", name)[0]; + return get("UPSDESC", name)[0]; } std::set TcpClient::getDeviceVariableNames(const std::string& dev) @@ -1136,7 +1136,7 @@ bool Device::operator==(const Device& dev)const bool Device::operator<(const Device& dev)const { - return getName() Variable Device::getVariable(const std::string& name) { - if (!isOk()) throw NutException("Invalid device"); - if(getClient()->hasDeviceVariable(getName(), name)) - return Variable(this, name); - else - return Variable(NULL, ""); + if (!isOk()) throw NutException("Invalid device"); + if(getClient()->hasDeviceVariable(getName(), name)) + return Variable(this, name); + else + return Variable(NULL, ""); } std::set Device::getVariables() @@ -1197,11 +1197,11 @@ std::set Device::getVariables() std::set set; if (!isOk()) throw NutException("Invalid device"); - std::set names = getClient()->getDeviceVariableNames(getName()); - for(std::set::iterator it=names.begin(); it!=names.end(); ++it) - { + std::set names = getClient()->getDeviceVariableNames(getName()); + for(std::set::iterator it=names.begin(); it!=names.end(); ++it) + { set.insert(Variable(this, *it)); - } + } return set; } @@ -1211,11 +1211,11 @@ std::set Device::getRWVariables() std::set set; if (!isOk()) throw NutException("Invalid device"); - std::set names = getClient()->getDeviceRWVariableNames(getName()); - for(std::set::iterator it=names.begin(); it!=names.end(); ++it) - { + std::set names = getClient()->getDeviceRWVariableNames(getName()); + for(std::set::iterator it=names.begin(); it!=names.end(); ++it) + { set.insert(Variable(this, *it)); - } + } return set; } @@ -1241,29 +1241,29 @@ std::set Device::getCommands() Command Device::getCommand(const std::string& name) { - if (!isOk()) throw NutException("Invalid device"); - if(getClient()->hasDeviceCommand(getName(), name)) - return Command(this, name); - else - return Command(NULL, ""); + if (!isOk()) throw NutException("Invalid device"); + if(getClient()->hasDeviceCommand(getName(), name)) + return Command(this, name); + else + return Command(NULL, ""); } TrackingID Device::executeCommand(const std::string& name, const std::string& param) { - if (!isOk()) throw NutException("Invalid device"); - return getClient()->executeDeviceCommand(getName(), name, param); + if (!isOk()) throw NutException("Invalid device"); + return getClient()->executeDeviceCommand(getName(), name, param); } void Device::login() { - if (!isOk()) throw NutException("Invalid device"); - getClient()->deviceLogin(getName()); + if (!isOk()) throw NutException("Invalid device"); + getClient()->deviceLogin(getName()); } void Device::master() { - if (!isOk()) throw NutException("Invalid device"); - getClient()->deviceMaster(getName()); + if (!isOk()) throw NutException("Invalid device"); + getClient()->deviceMaster(getName()); } void Device::forcedShutdown() @@ -1272,8 +1272,8 @@ void Device::forcedShutdown() int Device::getNumLogins() { - if (!isOk()) throw NutException("Invalid device"); - return getClient()->deviceGetNumLogins(getName()); + if (!isOk()) throw NutException("Invalid device"); + return getClient()->deviceGetNumLogins(getName()); } /* @@ -1352,12 +1352,12 @@ bool Variable::operator<(const Variable& var)const std::vector Variable::getValue() { - return getDevice()->getClient()->getDeviceVariableValue(getDevice()->getName(), getName()); + return getDevice()->getClient()->getDeviceVariableValue(getDevice()->getName(), getName()); } std::string Variable::getDescription() { - return getDevice()->getClient()->getDeviceVariableDescription(getDevice()->getName(), getName()); + return getDevice()->getClient()->getDeviceVariableDescription(getDevice()->getName(), getName()); } void Variable::setValue(const std::string& value) @@ -1422,7 +1422,6 @@ Device* Command::getDevice() bool Command::isOk()const { return _device!=NULL && !_name.empty(); - } Command::operator bool()const @@ -1482,7 +1481,6 @@ void strarr_free(strarr arr) free(arr); } - strarr stringset_to_strarr(const std::set& strset) { strarr arr = strarr_alloc(strset.size()); @@ -1507,7 +1505,6 @@ strarr stringvector_to_strarr(const std::vector& strset) return arr; } - NUTCLIENT_TCP_t nutclient_tcp_create_client(const char* host, unsigned short port) { nut::TcpClient* client = new nut::TcpClient; @@ -1558,7 +1555,6 @@ void nutclient_tcp_disconnect(NUTCLIENT_TCP_t client) } } - int nutclient_tcp_reconnect(NUTCLIENT_TCP_t client) { if(client) @@ -1602,7 +1598,6 @@ long nutclient_tcp_get_timeout(NUTCLIENT_TCP_t client) return -1; } - void nutclient_authenticate(NUTCLIENT_t client, const char* login, const char* passwd) { if(client) @@ -1668,7 +1663,6 @@ int nutclient_get_device_num_logins(NUTCLIENT_t client, const char* dev) return -1; } - void nutclient_device_master(NUTCLIENT_t client, const char* dev) { if(client) @@ -1877,8 +1871,6 @@ void nutclient_set_device_variable_values(NUTCLIENT_t client, const char* dev, c } } - - strarr nutclient_get_device_commands(NUTCLIENT_t client, const char* dev) { if(client) @@ -1896,7 +1888,6 @@ strarr nutclient_get_device_commands(NUTCLIENT_t client, const char* dev) return NULL; } - int nutclient_has_device_command(NUTCLIENT_t client, const char* dev, const char* cmd) { if(client) @@ -1914,7 +1905,6 @@ int nutclient_has_device_command(NUTCLIENT_t client, const char* dev, const char return 0; } - char* nutclient_get_device_command_description(NUTCLIENT_t client, const char* dev, const char* cmd) { if(client) @@ -1949,5 +1939,3 @@ void nutclient_execute_device_command(NUTCLIENT_t client, const char* dev, const } } /* extern "C" */ - - From fd10631bdc4d12d08aaf8a2c15efe4ca475ebe18 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Wed, 25 Nov 2020 00:21:48 +0100 Subject: [PATCH 4/4] tests/nutclienttest.cpp: add tests on Device, Variable and Command copying by assignment and by constructor --- clients/nutclient.h | 9 ++++ tests/nutclienttest.cpp | 99 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 108 insertions(+) diff --git a/clients/nutclient.h b/clients/nutclient.h index 081d1aa836..e978f2c1f2 100644 --- a/clients/nutclient.h +++ b/clients/nutclient.h @@ -457,6 +457,9 @@ class Device { friend class Client; friend class TcpClient; +#ifdef _NUTCLIENTTEST_BUILD + friend class NutClientTest; +#endif public: ~Device(); Device(const Device& dev); @@ -606,6 +609,9 @@ class Variable { friend class Device; friend class TcpClient; +#ifdef _NUTCLIENTTEST_BUILD + friend class NutClientTest; +#endif public: ~Variable(); @@ -686,6 +692,9 @@ class Command { friend class Device; friend class TcpClient; +#ifdef _NUTCLIENTTEST_BUILD + friend class NutClientTest; +#endif public: ~Command(); diff --git a/tests/nutclienttest.cpp b/tests/nutclienttest.cpp index 155ed9f4de..d8cb942f5f 100644 --- a/tests/nutclienttest.cpp +++ b/tests/nutclienttest.cpp @@ -18,11 +18,22 @@ */ #include +namespace nut { + class NutClientTest : public CppUnit::TestFixture { CPPUNIT_TEST_SUITE( NutClientTest ); CPPUNIT_TEST( test_stringset_to_strarr ); CPPUNIT_TEST( test_stringvector_to_strarr ); + + CPPUNIT_TEST( test_copy_constructor_dev ); + CPPUNIT_TEST( test_copy_assignment_dev ); + + CPPUNIT_TEST( test_copy_constructor_cmd ); + CPPUNIT_TEST( test_copy_assignment_cmd ); + + CPPUNIT_TEST( test_copy_constructor_var ); + CPPUNIT_TEST( test_copy_assignment_var ); CPPUNIT_TEST_SUITE_END(); public: @@ -31,12 +42,30 @@ class NutClientTest : public CppUnit::TestFixture void test_stringset_to_strarr(); void test_stringvector_to_strarr(); + + void test_copy_constructor_dev(); + void test_copy_assignment_dev(); + + void test_copy_constructor_cmd(); + void test_copy_assignment_cmd(); + + void test_copy_constructor_var(); + void test_copy_assignment_var(); }; // Registers the fixture into the 'registry' CPPUNIT_TEST_SUITE_REGISTRATION( NutClientTest ); +} // namespace nut {} + +#ifndef _NUTCLIENTTEST_BUILD +# define _NUTCLIENTTEST_BUILD 1 +#endif + #include "../clients/nutclient.h" + +namespace nut { + extern "C" { strarr stringset_to_strarr(const std::set& strset); strarr stringvector_to_strarr(const std::vector& strset); @@ -98,3 +127,73 @@ void NutClientTest::test_stringvector_to_strarr() strarr_free(arr); } + +void NutClientTest::test_copy_constructor_dev() { + nut::TcpClient c; + nut::Device i(&c, "ups1"); + nut::Device j(i); + + CPPUNIT_ASSERT_EQUAL_MESSAGE("Failed to assign value of Device variable j by initializing from i", i, j); +} + +void NutClientTest::test_copy_assignment_dev() { + nut::TcpClient c; + nut::Device i(&c, "ups1"); + nut::Device j(nullptr, "ups2"); + + CPPUNIT_ASSERT_ASSERTION_FAIL_MESSAGE("Device variables i and j were initialized differently but claim to be equal", + CPPUNIT_ASSERT_EQUAL(i, j) ); + + j = i; + CPPUNIT_ASSERT_EQUAL_MESSAGE("Failed to assign value of Device Command j by equating to i", i, j); +} + +void NutClientTest::test_copy_constructor_cmd() { + nut::TcpClient c; + nut::Device d(nullptr, "ups1"); + + nut::Command i(&d, "cmd1"); + nut::Command j(i); + + CPPUNIT_ASSERT_EQUAL_MESSAGE("Failed to assign value of Command variable j by initializing from i", i, j); +} + +void NutClientTest::test_copy_assignment_cmd() { + nut::TcpClient c; + nut::Device d(nullptr, "ups1"); + + nut::Command i(&d, "var1"); + nut::Command j(nullptr, "var2"); + + CPPUNIT_ASSERT_ASSERTION_FAIL_MESSAGE("Command variables i and j were initialized differently but claim to be equal", + CPPUNIT_ASSERT_EQUAL(i, j) ); + + j = i; + CPPUNIT_ASSERT_EQUAL_MESSAGE("Failed to assign value of Command variable j by equating to i", i, j); +} + +void NutClientTest::test_copy_constructor_var() { + nut::TcpClient c; + nut::Device d(nullptr, "ups1"); + + nut::Variable i(&d, "var1"); + nut::Variable j(i); + + CPPUNIT_ASSERT_EQUAL_MESSAGE("Failed to assign value of Variable variable j by initializing from i", i, j); +} + +void NutClientTest::test_copy_assignment_var() { + nut::TcpClient c; + nut::Device d(nullptr, "ups1"); + + nut::Variable i(&d, "var1"); + nut::Variable j(nullptr, "var2"); + + CPPUNIT_ASSERT_ASSERTION_FAIL_MESSAGE("Variable variables i and j were initialized differently but claim to be equal", + CPPUNIT_ASSERT_EQUAL(i, j) ); + + j = i; + CPPUNIT_ASSERT_EQUAL_MESSAGE("Failed to assign value of Variable variable j by equating to i", i, j); +} + +} // namespace nut {}