From b3a1fd3f7663b722a0d7e178605a9d14b23fc9eb Mon Sep 17 00:00:00 2001 From: Erich Keane Date: Wed, 7 Jan 2015 13:09:55 -0800 Subject: [PATCH] Implement [] and iteration for OCRepresentation Multiple requests have come in to be able to access the contents of OCRepresentation in an easier to use manner. This fix allows OCRepresentation to be indexed using the [] operator and also be iterated in an STL compliant fashion. Additionally, this adds more than 40 tests for this functionality Change-Id: Ibfc4bc61493324e118c4a6b67efc1d66e8b66b04 Signed-off-by: Erich Keane Reviewed-on: https://gerrit.iotivity.org/gerrit/116 Tested-by: jenkins-iotivity Reviewed-by: Sashi Penta (cherry picked from commit 529bb98b884ca4db27b7659f966075a8680fa3c3) Reviewed-on: https://gerrit.iotivity.org/gerrit/325 Tested-by: Sashi Penta --- resource/examples/garageclient.cpp | 36 +- resource/examples/garageserver.cpp | 35 +- resource/include/AttributeValue.h | 57 +- resource/include/OCRepresentation.h | 167 +++- resource/include/OCUtilities.h | 22 +- resource/src/OCRepresentation.cpp | 334 ++++++- resource/unittests/OCRepresentationTest.cpp | 1311 +++++++++++++++++++++++++++ resource/unittests/makefile | 2 +- 8 files changed, 1925 insertions(+), 39 deletions(-) create mode 100644 resource/unittests/OCRepresentationTest.cpp diff --git a/resource/examples/garageclient.cpp b/resource/examples/garageclient.cpp index 2976aba..a03c742 100644 --- a/resource/examples/garageclient.cpp +++ b/resource/examples/garageclient.cpp @@ -43,6 +43,7 @@ public: std::vector m_lightPowers; OCRepresentation m_lightRep; std::vector m_reps; + std::vector> m_hingeStates; Garage() : m_state(false), m_name("") { @@ -57,7 +58,7 @@ void printRepresentation(const OCRepresentation& rep) // Check if attribute "name" exists, and then getValue if(rep.hasAttribute("name")) { - myGarage.m_name = rep.getValue("name"); + myGarage.m_name = rep["name"]; } std::cout << "\tname: " << myGarage.m_name << std::endl; @@ -92,10 +93,10 @@ void printRepresentation(const OCRepresentation& rep) std::cout << "\tnullAttribute is not null." << std::endl; } - rep.getValue("light", myGarage.m_lightRep); + myGarage.m_lightRep = rep["light"]; - myGarage.m_lightRep.getValue("states", myGarage.m_lightStates); - myGarage.m_lightRep.getValue("powers", myGarage.m_lightPowers); + myGarage.m_lightStates = myGarage.m_lightRep["states"]; + myGarage.m_lightPowers = myGarage.m_lightRep["powers"]; std::cout << "\tlightRep: states: "; @@ -131,13 +132,26 @@ void printRepresentation(const OCRepresentation& rep) std::cout << std::endl; // Get vector of representations - rep.getValue("reps", myGarage.m_reps); - // Client know that server is sending two representations - // and has key1 and key2 repsectively - std::cout << "\treps[0].key1: " << myGarage.m_reps[0].getValue("key1") << std::endl; - std::cout << "\treps[0].key2: " << myGarage.m_reps[1].getValue("key2") << std::endl; + myGarage.m_reps = rep["reps"]; + + int ct = 0; + for(auto& rep : myGarage.m_reps) + { + for(auto& attribute : rep) + { + std::cout<< "\treps["<("json") << std::endl; } // callback handler on PUT request void onPut(const HeaderOptions& headerOptions, const OCRepresentation& rep, const int eCode) @@ -166,7 +180,7 @@ void putLightRepresentation(std::shared_ptr resource) myGarage.m_state = true; - rep.setValue("state", myGarage.m_state); + rep["state"] = myGarage.m_state; // Create QueryParameters Map and add query params (if any) QueryParamsMap queryParamsMap; diff --git a/resource/examples/garageserver.cpp b/resource/examples/garageserver.cpp index e2a57d8..1b2dfde 100644 --- a/resource/examples/garageserver.cpp +++ b/resource/examples/garageserver.cpp @@ -53,25 +53,22 @@ public: // array of lights representation with in GarageResource OCRepresentation m_lightRep; std::vector m_reps; + std::vector> m_hingeStates; public: /// Constructor - GarageResource(): m_name("John's Garage"), m_state(false), m_garageUri("/a/garage") { + GarageResource(): m_name("John's Garage"), m_state(false), m_garageUri("/a/garage"), + m_hingeStates{{1,2,3},{4,5,6}} + { // Initialize representation m_garageRep.setUri(m_garageUri); - m_garageRep.setValue("state", m_state); - m_garageRep.setValue("name", m_name); + m_garageRep["state"] = m_state; + m_garageRep["name"] = m_name; // For demonstration purpose we are setting x to nullptr here. // In reality it may happen else where. - int* x = nullptr; - - // Check for nullptr and set null for that attribute - if(x == nullptr) - { - m_garageRep.setNULL("nullAttribute"); - } + m_garageRep["nullAttribute"] = nullptr; std::vector lightStates; std::vector lightPowers; @@ -82,30 +79,32 @@ public: lightPowers.push_back(i); } - m_lightRep.setValue("states", lightStates); - m_lightRep.setValue("powers", lightPowers); + m_lightRep["states"] = lightStates; + m_lightRep["powers"] = lightPowers; // Storing another representation within a representation - m_garageRep.setValue("light", m_lightRep); + m_garageRep["light"] = m_lightRep; OCRepresentation rep1; int value1 = 5; - rep1.setValue("key1", value1); + rep1["key1"] = value1; OCRepresentation rep2; int value2 = 10; - rep2.setValue("key2", value2); + rep2["key2"] = value2; m_reps.push_back(rep1); m_reps.push_back(rep2); // storing array of representations - m_garageRep.setValue("reps", m_reps); + m_garageRep["reps"] = m_reps; // setting json string std::string json = "{\"num\":10,\"rno\":23.5,\"aoa\":[[1,2],[3]],\"str\":\"john\",\ \"object\":{\"bl1\":false,\"ar\":[2,3]}, \"objects\":[{\"bl2\":true,\"nl\":null},{\"ar1\":[1,2]}]}"; - m_garageRep.setValue("json", json); + m_garageRep["json"] = json; + + m_garageRep["hinges"] = m_hingeStates; } /* Note that this does not need to be a member function: for classes you do not have @@ -164,7 +163,7 @@ public: // sending out. OCRepresentation get() { - m_garageRep.setValue("state", m_state); + m_garageRep["state"] = m_state; return m_garageRep; } diff --git a/resource/include/AttributeValue.h b/resource/include/AttributeValue.h index 5d0d524..be07173 100644 --- a/resource/include/AttributeValue.h +++ b/resource/include/AttributeValue.h @@ -33,20 +33,20 @@ #define BOOST_MPL_LIMIT_LIST_SIZE 30 #define BOOST_MPL_LIMIT_VECTOR_SIZE 30 #include - +#include +#include namespace OC { class OCRepresentation; struct NullType{}; + // Since null needs to be encoded in a special fashion in JSON, the encoder // needs to know the index of the NullType Sentinel Any time the code does a special // case for the NullType, we use the AttributeValueNullIndex. This MUST be kept up to date // with the variant's which() for NullType. static const int AttributeValueNullIndex = 0; typedef boost::variant< - - // Base values: NullType, // Note: this handles the null-type and must match the above static const int, double, @@ -78,5 +78,56 @@ namespace OC std::vector>> > AttributeValue; + enum class AttributeType + { + Null, + Integer, + Double, + Boolean, + String, + OCRepresentation, + Vector + }; + + template + struct AttributeTypeConvert{}; + + template<> + struct AttributeTypeConvert + { + constexpr static AttributeType type = AttributeType::Null; + }; + + template<> + struct AttributeTypeConvert + { + constexpr static AttributeType type = AttributeType::Integer; + }; + + template<> + struct AttributeTypeConvert + { + constexpr static AttributeType type = AttributeType::Double; + }; + + template<> + struct AttributeTypeConvert + { + constexpr static AttributeType type = AttributeType::Boolean; + }; + + template<> + struct AttributeTypeConvert + { + constexpr static AttributeType type = AttributeType::String; + }; + + template<> + struct AttributeTypeConvert + { + constexpr static AttributeType type = AttributeType::OCRepresentation; + }; + + std::ostream& operator << (std::ostream& os, const AttributeType at); } #endif // __ATTRIBUTEVALUE_H diff --git a/resource/include/OCRepresentation.h b/resource/include/OCRepresentation.h index 3a1746b..287d42e 100644 --- a/resource/include/OCRepresentation.h +++ b/resource/include/OCRepresentation.h @@ -121,7 +121,7 @@ namespace OC void setResourceInterfaces(const std::vector& resourceInterfaces); - bool empty() const; + bool emptyData() const; int numberOfAttributes() const; @@ -162,11 +162,172 @@ namespace OC return val; } + std::string getValueToString(const std::string& key) const; bool hasAttribute(const std::string& str) const; void setNULL(const std::string& str); bool isNULL(const std::string& str) const; + + // STL Container stuff + public: + class iterator; + class const_iterator; + // Shim class to allow iterating and indexing of the OCRepresentation + // object. + class AttributeItem + { + friend class OCRepresentation; + friend class iterator; + friend class const_iterator; + public: + const std::string& attrname() const; + AttributeType type() const; + AttributeType base_type() const; + size_t depth() const; + template + T getValue() const + { + return boost::get(m_values[m_attrName]); + } + + std::string getValueToString() const; + + template + AttributeItem& operator=(T&& rhs) + { + m_values[m_attrName] = std::forward(rhs); + return *this; + } + + AttributeItem& operator=(std::nullptr_t rhs) + { + NullType t; + m_values[m_attrName] = t; + return *this; + } + + // Enable-if required to prevent conversions to alternate types. This prevents + // ambigious conversions in the case where conversions can include a number of + // types, such as the string constructor. + template::value || + std::is_same::value || + std::is_same::value || + std::is_same::value || + std::is_same::value || + std::is_same>::value || + std::is_same>>::value || + std::is_same>>>::value || + std::is_same>::value || + std::is_same>>::value || + std::is_same>>>::value || + std::is_same>::value || + std::is_same>>::value || + std::is_same>>>::value || + std::is_same>::value || + std::is_same>>::value || + std::is_same>>>::value || + std::is_same>::value || + std::is_same>>::value || + std::is_same>>>::value + >::type // enable_if + > + operator T() const + { + return this->getValue(); + } + + operator std::nullptr_t() const + { + this->getValue(); + return nullptr; + } + + private: + AttributeItem(const std::string& name, + std::map& vals); + AttributeItem(const AttributeItem&) = default; + std::string m_attrName; + std::map& m_values; + }; + + // Iterator to allow iteration via STL containers/methods + class iterator + { + friend class OCRepresentation; + public: + typedef iterator self_type; + typedef AttributeItem value_type; + typedef value_type& reference; + typedef value_type* pointer; + typedef std::forward_iterator_tag iterator_category; + typedef int difference_type; + + iterator(const iterator&) = default; + ~iterator() = default; + + bool operator ==(const iterator&) const; + bool operator !=(const iterator&) const; + + iterator& operator++(); + iterator operator++(int); + + reference operator*(); + pointer operator->(); + private: + iterator(std::map::iterator&& itr, + std::map& vals) + : m_iterator(std::move(itr)), + m_item(m_iterator != vals.end() ? m_iterator->first:"", vals){} + std::map::iterator m_iterator; + AttributeItem m_item; + }; + + class const_iterator + { + friend class OCRepresentation; + public: + typedef iterator self_type; + typedef const AttributeItem value_type; + typedef value_type& const_reference; + typedef value_type* const_pointer; + typedef std::forward_iterator_tag iterator_category; + typedef int difference_type; + + const_iterator(const iterator& rhs) + :m_iterator(rhs.m_iterator), m_item(rhs.m_item){} + const_iterator(const const_iterator&) = default; + ~const_iterator() = default; + + bool operator ==(const const_iterator&) const; + bool operator !=(const const_iterator&) const; + + const_iterator& operator++(); + const_iterator operator++(int); + + const_reference operator*() const; + const_pointer operator->() const; + private: + const_iterator(std::map::const_iterator&& itr, + std::map& vals) + : m_iterator(std::move(itr)), + m_item(m_iterator != vals.end() ? m_iterator->first: "", vals){} + std::map::const_iterator m_iterator; + AttributeItem m_item; + }; + + iterator begin(); + const_iterator begin() const; + const_iterator cbegin() const; + iterator end(); + const_iterator end() const; + const_iterator cend() const; + size_t size() const; + bool empty() const; + + AttributeItem operator[](const std::string& key); + const AttributeItem operator[](const std::string& key) const; private: friend class OCResourceResponse; friend class cereal::access; @@ -217,12 +378,14 @@ namespace OC private: std::string m_uri; std::vector m_children; - std::map m_values; + mutable std::map m_values; std::vector m_resourceTypes; std::vector m_interfaces; InterfaceType m_interfaceType; }; + + std::ostream& operator <<(std::ostream& os, const OCRepresentation::AttributeItem& ai); } // namespace OC diff --git a/resource/include/OCUtilities.h b/resource/include/OCUtilities.h index aca25e9..cf01b8d 100644 --- a/resource/include/OCUtilities.h +++ b/resource/include/OCUtilities.h @@ -27,7 +27,8 @@ #include #include -#include "OCException.h" +#include +#include namespace OC { namespace Utilities { @@ -96,4 +97,23 @@ namespace OC { } // namespace OC +namespace OC +{ + template + struct is_vector + { + constexpr static bool value = false; + }; + + template + struct is_vector>::value + >::type + > + { + constexpr static bool value = true; + }; +} // namespace OC + #endif diff --git a/resource/src/OCRepresentation.cpp b/resource/src/OCRepresentation.cpp index 71487cd..a91fd72 100644 --- a/resource/src/OCRepresentation.cpp +++ b/resource/src/OCRepresentation.cpp @@ -26,6 +26,7 @@ #include +#include #include #include #include @@ -132,7 +133,7 @@ namespace OC bool firstPrinted = false; for(std::vector::size_type i = 0; i< m_reps.size();++i) { - if(!m_reps[i].empty()) + if(!m_reps[i].emptyData()) { if(firstPrinted) { @@ -165,7 +166,7 @@ namespace OC { } std::string OCRepresentation::getJSONRepresentation() const { - if(empty()) + if(emptyData()) { return "{}"; } @@ -233,7 +234,7 @@ namespace OC return m_values.find(str) != m_values.end(); } - bool OCRepresentation::empty() const + bool OCRepresentation::emptyData() const { // This logic is meant to determine whether based on the JSON serialization rules // if this object will result in empty JSON. URI is only serialized if there is valid @@ -646,3 +647,330 @@ namespace cereal } } } + +namespace OC +{ + std::ostream& operator <<(std::ostream& os, const AttributeType at) + { + switch(at) + { + case AttributeType::Null: + os << "Null"; + break; + case AttributeType::Integer: + os << "Integer"; + break; + case AttributeType::Double: + os << "Double"; + break; + case AttributeType::Boolean: + os << "Boolean"; + break; + case AttributeType::String: + os << "String"; + break; + case AttributeType::OCRepresentation: + os << "OCRepresentation"; + break; + case AttributeType::Vector: + os << "Vector"; + break; + } + return os; + } +} + +// STL Container For OCRepresentation +namespace OC +{ + OCRepresentation::AttributeItem::AttributeItem(const std::string& name, + std::map& vals): + m_attrName(name), m_values(vals){} + + OCRepresentation::AttributeItem OCRepresentation::operator[](const std::string& key) + { + OCRepresentation::AttributeItem attr{key, m_values}; + return std::move(attr); + } + + const OCRepresentation::AttributeItem OCRepresentation::operator[](const std::string& key) const + { + OCRepresentation::AttributeItem attr{key, m_values}; + return std::move(attr); + } + + const std::string& OCRepresentation::AttributeItem::attrname() const + { + return m_attrName; + } + + template + struct type_info + { + // contains the actual type + typedef T type; + // contains the inner most vector-type + typedef T base_type; + // contains the AttributeType for this item + constexpr static AttributeType enum_type = + AttributeTypeConvert::type; + // contains the AttributeType for this base-type + constexpr static AttributeType enum_base_type = + AttributeTypeConvert::type; + // depth of the vector + constexpr static size_t depth = 0; + }; + + template + struct type_info::value>::type> + { + typedef T type; + typedef typename type_info::base_type base_type; + constexpr static AttributeType enum_type = AttributeType::Vector; + constexpr static AttributeType enum_base_type = + type_info::enum_base_type; + constexpr static size_t depth = 1 + + type_info::depth; + }; + + struct type_introspection_visitor : boost::static_visitor<> + { + AttributeType type; + AttributeType base_type; + size_t depth; + + type_introspection_visitor() : boost::static_visitor<>(), + type(AttributeType::Null), base_type(AttributeType::Null), depth(0){} + + template + void operator()(T const& item) + { + type = type_info::enum_type; + base_type = type_info::enum_base_type; + depth = type_info::depth; + } + }; + + AttributeType OCRepresentation::AttributeItem::type() const + { + type_introspection_visitor vis; + boost::apply_visitor(vis, m_values[m_attrName]); + return vis.type; + } + + AttributeType OCRepresentation::AttributeItem::base_type() const + { + type_introspection_visitor vis; + boost::apply_visitor(vis, m_values[m_attrName]); + return vis.base_type; + } + + size_t OCRepresentation::AttributeItem::depth() const + { + type_introspection_visitor vis; + boost::apply_visitor(vis, m_values[m_attrName]); + return vis.depth; + } + + OCRepresentation::iterator OCRepresentation::begin() + { + return OCRepresentation::iterator(m_values.begin(), m_values); + } + + OCRepresentation::const_iterator OCRepresentation::begin() const + { + return OCRepresentation::const_iterator(m_values.begin(), m_values); + } + + OCRepresentation::const_iterator OCRepresentation::cbegin() const + { + return OCRepresentation::const_iterator(m_values.cbegin(), m_values); + } + + OCRepresentation::iterator OCRepresentation::end() + { + return OCRepresentation::iterator(m_values.end(), m_values); + } + + OCRepresentation::const_iterator OCRepresentation::end() const + { + return OCRepresentation::const_iterator(m_values.end(), m_values); + } + + OCRepresentation::const_iterator OCRepresentation::cend() const + { + return OCRepresentation::const_iterator(m_values.cend(), m_values); + } + + size_t OCRepresentation::size() const + { + return m_values.size(); + } + + bool OCRepresentation::empty() const + { + return m_values.empty(); + } + + bool OCRepresentation::iterator::operator==(const OCRepresentation::iterator& rhs) const + { + return m_iterator == rhs.m_iterator; + } + + bool OCRepresentation::iterator::operator!=(const OCRepresentation::iterator& rhs) const + { + return m_iterator != rhs.m_iterator; + } + + bool OCRepresentation::const_iterator::operator==( + const OCRepresentation::const_iterator& rhs) const + { + return m_iterator == rhs.m_iterator; + } + + bool OCRepresentation::const_iterator::operator!=( + const OCRepresentation::const_iterator& rhs) const + { + return m_iterator != rhs.m_iterator; + } + + OCRepresentation::iterator::reference OCRepresentation::iterator::operator*() + { + return m_item; + } + + OCRepresentation::const_iterator::const_reference + OCRepresentation::const_iterator::operator*() const + { + return m_item; + } + + OCRepresentation::iterator::pointer OCRepresentation::iterator::operator->() + { + return &m_item; + } + + OCRepresentation::const_iterator::const_pointer + OCRepresentation::const_iterator::operator->() const + { + return &m_item; + } + + OCRepresentation::iterator& OCRepresentation::iterator::operator++() + { + m_iterator++; + if(m_iterator != m_item.m_values.end()) + { + m_item.m_attrName = m_iterator->first; + } + else + { + m_item.m_attrName = ""; + } + return *this; + } + + OCRepresentation::const_iterator& OCRepresentation::const_iterator::operator++() + { + m_iterator++; + if(m_iterator != m_item.m_values.end()) + { + m_item.m_attrName = m_iterator->first; + } + else + { + m_item.m_attrName = ""; + } + return *this; + } + + OCRepresentation::iterator OCRepresentation::iterator::operator++(int) + { + OCRepresentation::iterator itr(*this); + ++(*this); + return itr; + } + + OCRepresentation::const_iterator OCRepresentation::const_iterator::operator++(int) + { + OCRepresentation::const_iterator itr(*this); + ++(*this); + return itr; + } + + struct to_string_visitor : boost::static_visitor<> + { + std::string str; + template + void operator()(T const& item) + { + str = boost::lexical_cast(item); + } + + template + void operator()(std::vector const& item) + { + to_string_visitor vis; + std::ostringstream stream; + stream << "["; + + for(const auto& i : item) + { + vis(i); + stream << vis.str << " "; + } + stream << "]"; + str = stream.str(); + } + }; + + template<> + void to_string_visitor::operator()(bool const& item) + { + str = item ? "true" : "false"; + } + + template<> + void to_string_visitor::operator()(std::string const& item) + { + str = item; + } + + template<> + void to_string_visitor::operator()(NullType const& item) + { + str = "(null)"; + } + + template<> + void to_string_visitor::operator()(OCRepresentation const& item) + { + str = "OC::OCRepresentation"; + } + + std::string OCRepresentation::getValueToString(const std::string& key) const + { + auto x = m_values.find(key); + if(x != m_values.end()) + { + to_string_visitor vis; + boost::apply_visitor(vis, x->second); + return std::move(vis.str); + } + + return ""; + } + + std::string OCRepresentation::AttributeItem::getValueToString() const + { + to_string_visitor vis; + boost::apply_visitor(vis, m_values[m_attrName]); + return std::move(vis.str); + } + + std::ostream& operator<<(std::ostream& os, const OCRepresentation::AttributeItem& ai) + { + os << ai.getValueToString(); + return os; + } +} diff --git a/resource/unittests/OCRepresentationTest.cpp b/resource/unittests/OCRepresentationTest.cpp new file mode 100644 index 0000000..629b989 --- /dev/null +++ b/resource/unittests/OCRepresentationTest.cpp @@ -0,0 +1,1311 @@ +//****************************************************************** +// +// Copyright 2014 Intel Mobile Communications GmbH All Rights Reserved. +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +#include +#include +#include +#include +#include +namespace OCRepresentationTest +{ + using namespace OC; + using std::string; + using std::vector; + + template + void parsedEqual(T expected, const std::string& actualStr) + { + T actual = boost::lexical_cast(actualStr); + EXPECT_LT(std::abs(expected - actual), std::numeric_limits::epsilon()); + } + + // getValueToString(all types) + TEST(OCRepresentationValueToString, Null) + { + static const std::string AttrName = "NullTest"; + OCRepresentation rep; + rep.setNULL(AttrName); + + EXPECT_TRUE(rep.isNULL(AttrName)); + EXPECT_EQ("(null)", rep.getValueToString(AttrName)); + EXPECT_EQ("(null)", rep[AttrName].getValueToString()); + } + + TEST(OCRepresentationValueToString, Integer) + { + static const std::string AttrName = "IntTest"; + OCRepresentation rep; + + rep.setValue(AttrName, -5); + EXPECT_EQ("-5", rep.getValueToString(AttrName)); + EXPECT_EQ("-5", rep[AttrName].getValueToString()); + + rep.setValue(AttrName, 0); + EXPECT_EQ("0", rep.getValueToString(AttrName)); + EXPECT_EQ("0", rep[AttrName].getValueToString()); + + rep.setValue(AttrName, 5); + EXPECT_EQ("5", rep.getValueToString(AttrName)); + EXPECT_EQ("5", rep[AttrName].getValueToString()); + + rep.setValue(AttrName, 54321); + EXPECT_EQ("54321", rep.getValueToString(AttrName)); + EXPECT_EQ("54321", rep[AttrName].getValueToString()); + } + + TEST(OCRepresentationValueToString, Double) + { + static const std::string AttrName = "DoubleTest"; + OCRepresentation rep; + + rep.setValue(AttrName, -5.0); + parsedEqual(-5.0, rep.getValueToString(AttrName)); + parsedEqual(-5.0, rep[AttrName].getValueToString()); + + rep.setValue(AttrName, 0.0); + parsedEqual(0.0, rep.getValueToString(AttrName)); + parsedEqual(0.0, rep[AttrName].getValueToString()); + + rep.setValue(AttrName, 5.0); + parsedEqual(5.0, rep.getValueToString(AttrName)); + parsedEqual(5.0, rep[AttrName].getValueToString()); + + rep.setValue(AttrName, 54321.0); + parsedEqual(54321.0, rep.getValueToString(AttrName)); + parsedEqual(54321.0, rep[AttrName].getValueToString()); + + rep.setValue(AttrName, 3.55); + parsedEqual(3.55, rep.getValueToString(AttrName)); + parsedEqual(3.55, rep[AttrName].getValueToString()); + + rep.setValue(AttrName, -4.95); + parsedEqual(-4.95, rep.getValueToString(AttrName)); + parsedEqual(-4.95, rep[AttrName].getValueToString()); + + rep.setValue(AttrName, 99999.5555); + parsedEqual(99999.5555, rep.getValueToString(AttrName)); + parsedEqual(99999.5555, rep[AttrName].getValueToString()); + } + + TEST(OCRepresentationValueToString, Boolean) + { + static const std::string AttrName = "BooleanTest"; + OCRepresentation rep; + + rep.setValue(AttrName, false); + EXPECT_EQ("false", rep.getValueToString(AttrName)); + EXPECT_EQ("false", rep[AttrName].getValueToString()); + + rep.setValue(AttrName, true); + EXPECT_EQ("true", rep.getValueToString(AttrName)); + EXPECT_EQ("true", rep[AttrName].getValueToString()); + } + + TEST(OCRepresentationValueToString, String) + { + static const std::string AttrName = "StringTest"; + OCRepresentation rep; + + rep.setValue(AttrName, std::string("test 1")); + EXPECT_EQ("test 1", rep.getValueToString(AttrName)); + EXPECT_EQ("test 1", rep[AttrName].getValueToString()); + + rep.setValue(AttrName, std::string("test 2")); + EXPECT_EQ("test 2", rep.getValueToString(AttrName)); + EXPECT_EQ("test 2", rep[AttrName].getValueToString()); + } + + TEST(OCRepresentationValueToString, SubRepresentation) + { + static const std::string AttrName = "SubRepTest"; + OCRepresentation rep; + OCRepresentation sub1; + OCRepresentation sub2; + + rep.setValue(AttrName, sub1); + EXPECT_EQ("OC::OCRepresentation", rep.getValueToString(AttrName)); + EXPECT_EQ("OC::OCRepresentation", rep[AttrName].getValueToString()); + + rep.setValue(AttrName, sub2); + EXPECT_EQ("OC::OCRepresentation", rep.getValueToString(AttrName)); + EXPECT_EQ("OC::OCRepresentation", rep[AttrName].getValueToString()); + } + + TEST(OCRepresentationValueToString, IntegerVector) + { + static const std::string AttrName = "VectorTest"; + OCRepresentation rep; + + vector vect {1,2,3,4,5,6,7,8,9}; + vector vect2 {-5,-3,-1,0,5,3,2}; + rep.setValue(AttrName, vect); + EXPECT_EQ("[1 2 3 4 5 6 7 8 9 ]", rep.getValueToString(AttrName)); + EXPECT_EQ("[1 2 3 4 5 6 7 8 9 ]", rep[AttrName].getValueToString()); + + rep.setValue(AttrName, vect2); + EXPECT_EQ("[-5 -3 -1 0 5 3 2 ]", rep.getValueToString(AttrName)); + EXPECT_EQ("[-5 -3 -1 0 5 3 2 ]", rep[AttrName].getValueToString()); + } + + TEST(OCRepresentationValueToString, IntegerVectorVector) + { + static const std::string AttrName = "VectorTest"; + OCRepresentation rep; + + vector vect1 {1,2,3,4,5,6,7,8,9}; + vector vect2 {-5,-3,-1,0,5,3,2}; + vector> vect{vect1, vect2}; + + rep.setValue(AttrName, vect); + static const string Expected = "[[1 2 3 4 5 6 7 8 9 ] [-5 -3 -1 0 5 3 2 ] ]"; + EXPECT_EQ(Expected, rep.getValueToString(AttrName)); + EXPECT_EQ(Expected, rep[AttrName].getValueToString()); + } + + TEST(OCRepresentationValueToString, IntegerVectorVectorVector) + { + static const std::string AttrName = "VectorTest"; + OCRepresentation rep; + + vector vect11 {1,2,3,4,5,6,7,8,9}; + vector vect12 {-5,-3,-1,0,5,3,2}; + vector> vect1{vect11, vect12}; + vector vect21 {2,0,1,6,9,3,8}; + vector vect22 {9,7,8,100003}; + vector> vect2{vect21, vect22}; + vector>> vect{vect1, vect2}; + rep.setValue(AttrName, vect); + static const std::string Expected = + "[[[1 2 3 4 5 6 7 8 9 ] [-5 -3 -1 0 5 3 2 ] ] [[2 0 1 6 9 3 8 ] [9 7 8 100003 ] ] ]"; + EXPECT_EQ(Expected, rep.getValueToString(AttrName)); + EXPECT_EQ(Expected, rep[AttrName].getValueToString()); + } + + TEST(OCRepresentationValueToString, DoubleVector) + { + static const std::string AttrName = "VectorTest"; + OCRepresentation rep; + + vector vect {3.12, -5.3, 7.5, 1.110}; + vector vect2 {2.1, -555.5, 0.0001, -0.2}; + rep.setValue(AttrName, vect); + EXPECT_EQ(rep.getValueToString(AttrName), rep[AttrName].getValueToString()); + + rep.setValue(AttrName, vect2); + EXPECT_EQ(rep.getValueToString(AttrName), rep[AttrName].getValueToString()); + } + + TEST(OCRepresentationValueToString, DoubleVectorVector) + { + static const std::string AttrName = "VectorTest"; + OCRepresentation rep; + vector vect1 {30.1,5.88,-22.0,0}; + vector vect2 {2.1,-55.5,0.1100,-.2}; + vector> vect{vect1, vect2}; + + rep.setValue(AttrName, vect); + EXPECT_EQ(rep.getValueToString(AttrName), rep[AttrName].getValueToString()); + } + + TEST(OCRepresentationValueToString, DoubleVectorVectorVector) + { + static const std::string AttrName = "VectorTest"; + OCRepresentation rep; + + vector vect11 {3.01, 5.88, -22.0, 0.0}; + vector vect12 {99.3,8.0,.01236,-.22}; + vector> vect1{vect11, vect12}; + vector vect21 {9.0,-1}; + vector vect22 {-99.2}; + vector> vect2{vect21, vect22}; + vector>> vect{vect1, vect2}; + rep.setValue(AttrName, vect); + EXPECT_EQ(rep.getValueToString(AttrName), rep[AttrName].getValueToString()); + } + + TEST(OCRepresentationValueToString, BooleanVector) + { + static const std::string AttrName = "VectorTest"; + OCRepresentation rep; + + vector vect {true, false, false, true}; + vector vect2 {false, false, false, true}; + rep.setValue(AttrName, vect); + EXPECT_EQ("[true false false true ]", rep.getValueToString(AttrName)); + EXPECT_EQ("[true false false true ]", rep[AttrName].getValueToString()); + + rep.setValue(AttrName, vect2); + EXPECT_EQ("[false false false true ]", rep.getValueToString(AttrName)); + EXPECT_EQ("[false false false true ]", rep[AttrName].getValueToString()); + } + + TEST(OCRepresentationValueToString, BooleanVectorVector) + { + static const std::string AttrName = "VectorTest"; + OCRepresentation rep; + + vector vect1 {true, false, false, true}; + vector vect2 {false, false, false, true}; + vector> vect{vect1, vect2}; + + rep.setValue(AttrName, vect); + static const string Expected="[[true false false true ] [false false false true ] ]"; + + EXPECT_EQ(Expected, rep.getValueToString(AttrName)); + EXPECT_EQ(Expected, rep[AttrName].getValueToString()); + } + + TEST(OCRepresentationValueToString, BooleanVectorVectorVector) + { + static const std::string AttrName = "VectorTest"; + OCRepresentation rep; + + vector vect11 {true, false, false, true}; + vector vect12 {false, false, false, true}; + vector> vect1{vect11, vect12}; + vector vect21 {false, true, true, false}; + vector vect22 {true, true, true, false}; + vector> vect2{vect21, vect22}; + vector>> vect{vect1, vect2}; + rep.setValue(AttrName, vect); + static const std::string Expected = + "[[[true false false true ] [false false false true ] ]" + " [[false true true false ] [true true true false ] ] ]"; + EXPECT_EQ(Expected, rep.getValueToString(AttrName)); + EXPECT_EQ(Expected, rep[AttrName].getValueToString()); + } + + TEST(OCRepresentationValueToString, StringVector) + { + static const std::string AttrName = "VectorTest"; + OCRepresentation rep; + + vector vect {"s1", "s2", "s3"}; + vector vect2 {"s4", "s5", "s6"}; + rep.setValue(AttrName, vect); + EXPECT_EQ("[s1 s2 s3 ]", rep.getValueToString(AttrName)); + EXPECT_EQ("[s1 s2 s3 ]", rep[AttrName].getValueToString()); + + rep.setValue(AttrName, vect2); + EXPECT_EQ("[s4 s5 s6 ]", rep.getValueToString(AttrName)); + EXPECT_EQ("[s4 s5 s6 ]", rep[AttrName].getValueToString()); + } + + TEST(OCRepresentationValueToString, StringVectorVector) + { + static const std::string AttrName = "VectorTest"; + OCRepresentation rep; + + vector vect1 {"s1", "s2", "s3"}; + vector vect2 {"s4", "s5", "s6"}; + vector> vect{vect1, vect2}; + + rep.setValue(AttrName, vect); + static const string Expected="[[s1 s2 s3 ] [s4 s5 s6 ] ]"; + + EXPECT_EQ(Expected, rep.getValueToString(AttrName)); + EXPECT_EQ(Expected, rep[AttrName].getValueToString()); + } + + TEST(OCRepresentationValueToString, StringVectorVectorVector) + { + static const std::string AttrName = "VectorTest"; + OCRepresentation rep; + + vector vect11 {"s1", "s2", "s3"}; + vector vect12 {"s4", "s5", "s6"}; + vector> vect1{vect11, vect12}; + vector vect21 {"s7", "s8"}; + vector vect22 {"s9"}; + vector> vect2{vect21, vect22}; + vector>> vect{vect1, vect2}; + rep.setValue(AttrName, vect); + static const std::string Expected = + "[[[s1 s2 s3 ] [s4 s5 s6 ] ]" + " [[s7 s8 ] [s9 ] ] ]"; + EXPECT_EQ(Expected, rep.getValueToString(AttrName)); + EXPECT_EQ(Expected, rep[AttrName].getValueToString()); + } + + TEST(OCRepresentationValueToString, SubRepresentationVector) + { + static const std::string AttrName = "VectorTest"; + OCRepresentation rep; + + OCRepresentation sub1; + OCRepresentation sub2; + vector vect {sub1, sub2}; + rep.setValue(AttrName, vect); + EXPECT_EQ("[OC::OCRepresentation OC::OCRepresentation ]", rep.getValueToString(AttrName)); + EXPECT_EQ("[OC::OCRepresentation OC::OCRepresentation ]", rep[AttrName].getValueToString()); + } + + TEST(OCRepresentationValueToString, SubRepresentationVectorVector) + { + static const std::string AttrName = "VectorTest"; + OCRepresentation rep; + + OCRepresentation sub1; + OCRepresentation sub2; + OCRepresentation sub3; + OCRepresentation sub4; + vector vect1 {sub1, sub2}; + vector vect2 {sub3, sub4}; + vector> vect{vect1, vect2}; + rep.setValue(AttrName, vect); + static const string Expected = "[[OC::OCRepresentation OC::OCRepresentation ]" + " [OC::OCRepresentation OC::OCRepresentation ] ]"; + EXPECT_EQ(Expected, rep.getValueToString(AttrName)); + EXPECT_EQ(Expected, rep[AttrName].getValueToString()); + } + + TEST(OCRepresentationValueToString, SubRepresentationVectorVectorVector) + { + static const std::string AttrName = "VectorTest"; + OCRepresentation rep; + + OCRepresentation sub1; + OCRepresentation sub2; + OCRepresentation sub3; + OCRepresentation sub4; + OCRepresentation sub5; + OCRepresentation sub6; + + vector vect11 {sub1, sub2}; + vector vect12 {sub3, sub4}; + vector> vect1{vect11, vect12}; + vector vect21 {sub5}; + vector vect22 {sub6}; + vector> vect2{vect21, vect22}; + vector>> vect{vect1, vect2}; + + rep.setValue(AttrName, vect); + static const string Expected = + "[[[OC::OCRepresentation OC::OCRepresentation ] " + "[OC::OCRepresentation OC::OCRepresentation ] ] " + "[[OC::OCRepresentation ] [OC::OCRepresentation ] ] ]"; + EXPECT_EQ(Expected, rep.getValueToString(AttrName)); + EXPECT_EQ(Expected, rep[AttrName].getValueToString()); + } + + // Subscript get/set (all types) + TEST(OCRepresentationSubscript, NullPtr) + { + static const std::string AttrName = "NullTest"; + OCRepresentation rep; + rep[AttrName] = nullptr; + EXPECT_TRUE(rep.isNULL(AttrName)); + + std::nullptr_t repout = rep[AttrName]; + std::nullptr_t repout2; + repout2 = rep[AttrName]; + + EXPECT_EQ(nullptr, repout); + EXPECT_EQ(nullptr, repout2); + + double badout; + EXPECT_THROW(badout = rep[AttrName], boost::bad_get); + string badoutstr; + EXPECT_THROW(badoutstr = rep[AttrName], boost::bad_get); + (void)badout; + (void)badoutstr; + } + + TEST(OCRepresentationSubscript, Integer) + { + static const std::string AttrName = "IntTest"; + OCRepresentation rep; + int repsource = -5; + rep[AttrName] = repsource; + int repout = rep[AttrName]; + int repout2; + repout2 = rep[AttrName]; + + EXPECT_EQ(repsource, repout); + EXPECT_EQ(repsource, repout2); + + double badout; + EXPECT_THROW(badout = rep[AttrName], boost::bad_get); + string badoutstr; + EXPECT_THROW(badoutstr = rep[AttrName], boost::bad_get); + (void)badout; + (void)badoutstr; + } + + TEST(OCRepresentationSubscript, Double) + { + static const std::string AttrName = "DoubleTest"; + OCRepresentation rep; + double repsource = -5.33; + rep[AttrName] = repsource; + double repout = rep[AttrName]; + double repout2; + repout2 = rep[AttrName]; + + EXPECT_EQ(repsource, repout); + EXPECT_EQ(repsource, repout2); + + int badout; + EXPECT_THROW(badout = rep[AttrName], boost::bad_get); + string badoutstr; + EXPECT_THROW(badoutstr = rep[AttrName], boost::bad_get); + (void)badout; + (void)badoutstr; + } + + TEST(OCRepresentationSubscript, Boolean) + { + static const std::string AttrName = "BooleanTest"; + OCRepresentation rep; + bool repsource = true; + rep[AttrName] = repsource; + bool repout = rep[AttrName]; + bool repout2; + repout2 = rep[AttrName]; + + EXPECT_EQ(repsource, repout); + EXPECT_EQ(repsource, repout2); + + repsource = false; + rep[AttrName] = repsource; + repout = rep[AttrName]; + + EXPECT_EQ(repsource, repout); + + int badout; + EXPECT_THROW(badout = rep[AttrName], boost::bad_get); + string badoutstr; + EXPECT_THROW(badoutstr = rep[AttrName], boost::bad_get); + (void)badout; + (void)badoutstr; + } + + TEST(OCRepresentationSubscript, String) + { + static const std::string AttrName = "StringTest"; + OCRepresentation rep; + string repsource = "This is a string!"; + rep[AttrName] = repsource; + string repout = rep[AttrName]; + string repout2; + repout2 = rep[AttrName]; + + EXPECT_EQ(repsource, repout); + EXPECT_EQ(repsource, repout2); + + double badout; + EXPECT_THROW(badout = rep[AttrName], boost::bad_get); + (void)badout; + } + + TEST(OCRepresentationSubscript, SubRepresentation) + { + static const std::string AttrName = "SubRepresentationTest"; + OCRepresentation rep; + OCRepresentation repsource; + repsource.setUri("This is a uri"); + + rep[AttrName] = repsource; + OCRepresentation repout = rep[AttrName]; + OCRepresentation repout2; + repout2 = rep[AttrName]; + + //OCRepresentation doesn't overload equality, so this just compares + //the value we set to ensure we got the same one out; + EXPECT_EQ(repsource.getUri(), repout.getUri()); + EXPECT_EQ(repsource.getUri(), repout2.getUri()); + + double badout; + EXPECT_THROW(badout = rep[AttrName], boost::bad_get); + string badoutstr; + EXPECT_THROW(badoutstr = rep[AttrName], boost::bad_get); + (void)badout; + (void)badoutstr; + } + + TEST(OCRepresentationSubscript, IntegerVector) + { + static const std::string AttrName = "VectorTest"; + OCRepresentation rep; + vector repsource {1,2,3,4}; + rep[AttrName] = repsource; + vector repout = rep[AttrName]; + vector repout2; + repout2 = rep[AttrName]; + + EXPECT_EQ(repsource, repout); + EXPECT_EQ(repsource, repout2); + + double badout; + EXPECT_THROW(badout = rep[AttrName], boost::bad_get); + string badoutstr; + EXPECT_THROW(badoutstr = rep[AttrName], boost::bad_get); + (void)badout; + (void)badoutstr; + } + + TEST(OCRepresentationSubscript, IntegerVectorVector) + { + static const std::string AttrName = "VectorTest"; + OCRepresentation rep; + vector> repsource {{1,2,3,4},{5,6,7,8}}; + rep[AttrName] = repsource; + vector> repout = rep[AttrName]; + vector> repout2; + repout2 = rep[AttrName]; + + EXPECT_EQ(repsource, repout); + EXPECT_EQ(repsource, repout2); + + double badout; + EXPECT_THROW(badout = rep[AttrName], boost::bad_get); + string badoutstr; + EXPECT_THROW(badoutstr = rep[AttrName], boost::bad_get); + (void)badout; + (void)badoutstr; + } + + TEST(OCRepresentationSubscript, IntegerVectorVectorVector) + { + static const std::string AttrName = "VectorTest"; + OCRepresentation rep; + vector>> repsource {{{1,2,3,4},{5,6,7,8}},{{9,10,11},{21,13}}}; + rep[AttrName] = repsource; + vector>> repout = rep[AttrName]; + vector>> repout2; + repout2 = rep[AttrName]; + + EXPECT_EQ(repsource, repout); + EXPECT_EQ(repsource, repout2); + + double badout; + EXPECT_THROW(badout = rep[AttrName], boost::bad_get); + string badoutstr; + EXPECT_THROW(badoutstr = rep[AttrName], boost::bad_get); + (void)badout; + (void)badoutstr; + } + + TEST(OCRepresentationSubscript, DoubleVector) + { + static const std::string AttrName = "VectorTest"; + OCRepresentation rep; + vector repsource {1.1,2.2,3.2,4.2}; + rep[AttrName] = repsource; + vector repout = rep[AttrName]; + vector repout2; + repout2 = rep[AttrName]; + + EXPECT_EQ(repsource, repout); + EXPECT_EQ(repsource, repout2); + + double badout; + EXPECT_THROW(badout = rep[AttrName], boost::bad_get); + string badoutstr; + EXPECT_THROW(badoutstr = rep[AttrName], boost::bad_get); + (void)badout; + (void)badoutstr; + } + + TEST(OCRepresentationSubscript, DoubleVectorVector) + { + static const std::string AttrName = "VectorTest"; + OCRepresentation rep; + vector> repsource {{1.1,2.2,3.2,4.3},{5.5,6.6,7.8,.8}}; + rep[AttrName] = repsource; + vector> repout = rep[AttrName]; + vector> repout2; + repout2 = rep[AttrName]; + + EXPECT_EQ(repsource, repout); + EXPECT_EQ(repsource, repout2); + + double badout; + EXPECT_THROW(badout = rep[AttrName], boost::bad_get); + string badoutstr; + EXPECT_THROW(badoutstr = rep[AttrName], boost::bad_get); + (void)badout; + (void)badoutstr; + } + + TEST(OCRepresentationSubscript, DoubleVectorVectorVector) + { + static const std::string AttrName = "VectorTest"; + OCRepresentation rep; + vector>> repsource {{{1.1,2.5,3.5,4.4},{.5,.6,7.8,8.9}}, + {{9.8,10.8,11.8},{2.1,1.3}}}; + rep[AttrName] = repsource; + vector>> repout = rep[AttrName]; + vector>> repout2; + repout2 = rep[AttrName]; + + EXPECT_EQ(repsource, repout); + EXPECT_EQ(repsource, repout2); + + double badout; + EXPECT_THROW(badout = rep[AttrName], boost::bad_get); + string badoutstr; + EXPECT_THROW(badoutstr = rep[AttrName], boost::bad_get); + (void)badout; + (void)badoutstr; + } + + TEST(OCRepresentationSubscript, BooleanVector) + { + static const std::string AttrName = "VectorTest"; + OCRepresentation rep; + vector repsource {false, false, true}; + rep[AttrName] = repsource; + vector repout = rep[AttrName]; + vector repout2; + repout2 = rep[AttrName]; + + EXPECT_EQ(repsource, repout); + EXPECT_EQ(repsource, repout2); + + double badout; + EXPECT_THROW(badout = rep[AttrName], boost::bad_get); + string badoutstr; + EXPECT_THROW(badoutstr = rep[AttrName], boost::bad_get); + (void)badout; + (void)badoutstr; + } + + TEST(OCRepresentationSubscript, BooleanVectorVector) + { + static const std::string AttrName = "VectorTest"; + OCRepresentation rep; + vector> repsource {{true, true},{false, true}}; + rep[AttrName] = repsource; + vector> repout = rep[AttrName]; + vector> repout2; + repout2 = rep[AttrName]; + + EXPECT_EQ(repsource, repout); + EXPECT_EQ(repsource, repout2); + + double badout; + EXPECT_THROW(badout = rep[AttrName], boost::bad_get); + string badoutstr; + EXPECT_THROW(badoutstr = rep[AttrName], boost::bad_get); + (void)badout; + (void)badoutstr; + } + + TEST(OCRepresentationSubscript, BooleanVectorVectorVector) + { + static const std::string AttrName = "VectorTest"; + OCRepresentation rep; + vector>> repsource {{{true, true, false},{true}}, + {{true, false, false},{false, true, true}}}; + rep[AttrName] = repsource; + vector>> repout = rep[AttrName]; + vector>> repout2; + repout2 = rep[AttrName]; + + EXPECT_EQ(repsource, repout); + EXPECT_EQ(repsource, repout2); + + double badout; + EXPECT_THROW(badout = rep[AttrName], boost::bad_get); + string badoutstr; + EXPECT_THROW(badoutstr = rep[AttrName], boost::bad_get); + (void)badout; + (void)badoutstr; + } + + TEST(OCRepresentationSubscript, StringVector) + { + static const std::string AttrName = "VectorTest"; + OCRepresentation rep; + vector repsource {"str1", "str2"}; + rep[AttrName] = repsource; + vector repout = rep[AttrName]; + vector repout2; + repout2 = rep[AttrName]; + + EXPECT_EQ(repsource, repout); + EXPECT_EQ(repsource, repout2); + + double badout; + EXPECT_THROW(badout = rep[AttrName], boost::bad_get); + string badoutstr; + EXPECT_THROW(badoutstr = rep[AttrName], boost::bad_get); + (void)badout; + (void)badoutstr; + } + + TEST(OCRepresentationSubscript, StringVectorVector) + { + static const std::string AttrName = "VectorTest"; + OCRepresentation rep; + vector> repsource {{"str1", "str2"},{"str3", "str4"}}; + rep[AttrName] = repsource; + vector> repout = rep[AttrName]; + vector> repout2; + repout2 = rep[AttrName]; + + EXPECT_EQ(repsource, repout); + EXPECT_EQ(repsource, repout2); + + double badout; + EXPECT_THROW(badout = rep[AttrName], boost::bad_get); + string badoutstr; + EXPECT_THROW(badoutstr = rep[AttrName], boost::bad_get); + (void)badout; + (void)badoutstr; + } + + TEST(OCRepresentationSubscript, StringVectorVectorVector) + { + static const std::string AttrName = "VectorTest"; + OCRepresentation rep; + vector>> repsource {{{"str1", "str2"},{"str3", "str4"}}, + {{"str5"},{"str6"}}}; + rep[AttrName] = repsource; + vector>> repout = rep[AttrName]; + vector>> repout2; + repout2 = rep[AttrName]; + + EXPECT_EQ(repsource, repout); + EXPECT_EQ(repsource, repout2); + + double badout; + EXPECT_THROW(badout = rep[AttrName], boost::bad_get); + string badoutstr; + EXPECT_THROW(badoutstr = rep[AttrName], boost::bad_get); + (void)badout; + (void)badoutstr; + } + + TEST(OCRepresentationSubscript, SubRepresentationVector) + { + static const std::string AttrName = "VectorTest"; + OCRepresentation rep; + OCRepresentation inner1, inner2; + inner1.setUri("inner1"); + inner2.setUri("inner2"); + vector repsource {inner1, inner2}; + rep[AttrName] = repsource; + vector repout = rep[AttrName]; + vector repout2; + repout2 = rep[AttrName]; + + EXPECT_EQ(2, repout.size()); + EXPECT_EQ(inner1.getUri(), repout[0].getUri()); + EXPECT_EQ(inner2.getUri(), repout[1].getUri()); + EXPECT_EQ(2, repout2.size()); + EXPECT_EQ(inner1.getUri(), repout2[0].getUri()); + EXPECT_EQ(inner2.getUri(), repout2[1].getUri()); + + double badout; + EXPECT_THROW(badout = rep[AttrName], boost::bad_get); + string badoutstr; + EXPECT_THROW(badoutstr = rep[AttrName], boost::bad_get); + (void)badout; + (void)badoutstr; + } + + TEST(OCRepresentationSubscript, SubRepresentationVectorVector) + { + static const std::string AttrName = "VectorTest"; + OCRepresentation rep; + OCRepresentation inner1, inner2, inner3, inner4; + inner1.setUri("inner1"); + inner2.setUri("inner2"); + inner3.setUri("inner3"); + inner4.setUri("inner4"); + + vector> repsource {{inner1, inner2}, {inner3, inner4}}; + rep[AttrName] = repsource; + vector> repout = rep[AttrName]; + vector> repout2; + repout2 = rep[AttrName]; + + EXPECT_EQ(2, repout.size()); + EXPECT_EQ(2, repout[0].size()); + EXPECT_EQ(inner1.getUri(), repout[0][0].getUri()); + EXPECT_EQ(inner2.getUri(), repout[0][1].getUri()); + EXPECT_EQ(2, repout.size()); + EXPECT_EQ(2, repout[1].size()); + EXPECT_EQ(inner3.getUri(), repout[1][0].getUri()); + EXPECT_EQ(inner4.getUri(), repout[1][1].getUri()); + + EXPECT_EQ(2, repout2.size()); + EXPECT_EQ(2, repout2[0].size()); + EXPECT_EQ(inner1.getUri(), repout2[0][0].getUri()); + EXPECT_EQ(inner2.getUri(), repout2[0][1].getUri()); + EXPECT_EQ(2, repout2.size()); + EXPECT_EQ(2, repout2[1].size()); + EXPECT_EQ(inner3.getUri(), repout2[1][0].getUri()); + EXPECT_EQ(inner4.getUri(), repout2[1][1].getUri()); + + double badout; + EXPECT_THROW(badout = rep[AttrName], boost::bad_get); + string badoutstr; + EXPECT_THROW(badoutstr = rep[AttrName], boost::bad_get); + (void)badout; + (void)badoutstr; + } + + TEST(OCRepresentationSubscript, SubRepresentationVectorVectorVector) + { + static const std::string AttrName = "VectorTest"; + OCRepresentation rep; + OCRepresentation inner1, inner2, inner3, inner4, inner5, inner6, inner7, inner8; + inner1.setUri("inner1"); + inner2.setUri("inner2"); + inner3.setUri("inner3"); + inner4.setUri("inner4"); + inner5.setUri("inner5"); + inner6.setUri("inner6"); + inner7.setUri("inner7"); + inner8.setUri("inner8"); + + vector>> repsource + {{{inner1, inner2},{inner3, inner4}},{{inner5, inner6},{inner7,inner8}}}; + + rep[AttrName] = repsource; + vector>> repout = rep[AttrName]; + vector>> repout2; + repout2 = rep[AttrName]; + + EXPECT_EQ(2, repout.size()); + EXPECT_EQ(2, repout[0].size()); + EXPECT_EQ(2, repout[0][0].size()); + EXPECT_EQ(inner1.getUri(), repout[0][0][0].getUri()); + EXPECT_EQ(inner2.getUri(), repout[0][0][1].getUri()); + EXPECT_EQ(2, repout[0][1].size()); + EXPECT_EQ(inner3.getUri(), repout[0][1][0].getUri()); + EXPECT_EQ(inner4.getUri(), repout[0][1][1].getUri()); + EXPECT_EQ(2, repout[1].size()); + EXPECT_EQ(2, repout[1][0].size()); + EXPECT_EQ(inner5.getUri(), repout[1][0][0].getUri()); + EXPECT_EQ(inner6.getUri(), repout[1][0][1].getUri()); + EXPECT_EQ(2, repout[1][1].size()); + EXPECT_EQ(inner7.getUri(), repout[1][1][0].getUri()); + EXPECT_EQ(inner8.getUri(), repout[1][1][1].getUri()); + + EXPECT_EQ(2, repout2.size()); + EXPECT_EQ(2, repout2[0].size()); + EXPECT_EQ(2, repout2[0][0].size()); + EXPECT_EQ(inner1.getUri(), repout2[0][0][0].getUri()); + EXPECT_EQ(inner2.getUri(), repout2[0][0][1].getUri()); + EXPECT_EQ(2, repout[0][1].size()); + EXPECT_EQ(inner3.getUri(), repout2[0][1][0].getUri()); + EXPECT_EQ(inner4.getUri(), repout2[0][1][1].getUri()); + EXPECT_EQ(2, repout[1].size()); + EXPECT_EQ(2, repout[1][0].size()); + EXPECT_EQ(inner5.getUri(), repout2[1][0][0].getUri()); + EXPECT_EQ(inner6.getUri(), repout2[1][0][1].getUri()); + EXPECT_EQ(2, repout[1][1].size()); + EXPECT_EQ(inner7.getUri(), repout2[1][1][0].getUri()); + EXPECT_EQ(inner8.getUri(), repout2[1][1][1].getUri()); + + double badout; + EXPECT_THROW(badout = rep[AttrName], boost::bad_get); + string badoutstr; + EXPECT_THROW(badoutstr = rep[AttrName], boost::bad_get); + (void)badout; + (void)badoutstr; + } + + TEST(OCRepresentationIterator, constiterator) + { + OCRepresentation rep; + + EXPECT_TRUE(rep.empty()); + rep.setValue("int", 8); + EXPECT_FALSE(rep.empty()); + rep.setValue("double", 8.8); + rep.setValue("bool", true); + rep.setValue("string", std::string("this is a string")); + + EXPECT_EQ(4, rep.size()); + EXPECT_FALSE(rep.empty()); + + OCRepresentation::const_iterator itr = rep.cbegin(); + OCRepresentation::const_iterator endItr = rep.cend(); + for(;itr!=endItr;++itr); + + const OCRepresentation& rep2(rep); + OCRepresentation::const_iterator itr2 = rep2.begin(); + OCRepresentation::const_iterator endItr2 = rep2.end(); + for(;itr2!=endItr2;++itr2); + + } + + TEST(OCRepresentationIterator, constautoiterator) + { + OCRepresentation rep; + + EXPECT_TRUE(rep.empty()); + rep.setValue("int", 8); + EXPECT_FALSE(rep.empty()); + rep.setValue("double", 8.8); + rep.setValue("bool", true); + rep.setValue("string", std::string("this is a string")); + + EXPECT_EQ(4, rep.size()); + EXPECT_FALSE(rep.empty()); + + for(const auto& a : rep) + { + (void)a; + } + + const OCRepresentation& rep2(rep); + for(const auto& a : rep2) + { + (void)a; + } + } + TEST(OCRepresentationIterator, autoiterator) + { + OCRepresentation rep; + + EXPECT_TRUE(rep.empty()); + rep.setValue("int", 8); + EXPECT_FALSE(rep.empty()); + rep.setValue("double", 8.8); + rep.setValue("bool", true); + rep.setValue("string", std::string("this is a string")); + + EXPECT_EQ(4, rep.size()); + EXPECT_FALSE(rep.empty()); + + for(auto& cur : rep) + { + if(cur.attrname() == "int") + { + EXPECT_EQ("int", cur.attrname()); + EXPECT_EQ(AttributeType::Integer, cur.type()); + EXPECT_EQ(AttributeType::Integer, cur.base_type()); + EXPECT_EQ(0, cur.depth()); + int curInt = cur.getValue(); + EXPECT_EQ(8, curInt); + } + if(cur.attrname() == "double") + { + EXPECT_EQ("double", cur.attrname()); + EXPECT_EQ(AttributeType::Double, cur.type()); + EXPECT_EQ(AttributeType::Double, cur.base_type()); + EXPECT_EQ(0, cur.depth()); + double curDouble = cur.getValue(); + EXPECT_EQ(8.8, curDouble); + } + if(cur.attrname() == "bool") + { + EXPECT_EQ("bool", cur.attrname()); + EXPECT_EQ(AttributeType::Boolean, cur.type()); + EXPECT_EQ(AttributeType::Boolean, cur.base_type()); + EXPECT_EQ(0, cur.depth()); + bool curBool = cur.getValue(); + EXPECT_EQ(true, curBool); + } + if(cur.attrname() == "string") + { + EXPECT_EQ("string", cur.attrname()); + EXPECT_EQ(AttributeType::String, cur.type()); + EXPECT_EQ(AttributeType::String, cur.base_type()); + EXPECT_EQ(0, cur.depth()); + string curStr = cur.getValue(); + EXPECT_EQ("this is a string", curStr); + } + } + } + // Iterator usage + TEST(OCRepresentationIterator, iterator) + { + OCRepresentation rep; + OCRepresentation sub1; + sub1.setUri("sub rep1 URI"); + OCRepresentation sub2; + sub2.setUri("sub rep2 URI"); + OCRepresentation sub3; + sub3.setUri("sub rep3 URI"); + OCRepresentation sub4; + sub4.setUri("sub rep4 URI"); + OCRepresentation sub5; + sub5.setUri("sub rep5 URI"); + OCRepresentation sub6; + sub6.setUri("sub rep6 URI"); + + + EXPECT_TRUE(rep.empty()); + rep.setValue("int", 8); + EXPECT_FALSE(rep.empty()); + rep.setValue("double", 8.8); + rep.setValue("bool", true); + rep.setValue("string", std::string("this is a string")); + rep.setValue("rep", sub1); + + vector intv {1,2,3,4}; + rep.setValue("intv", intv); + vector doublev {1.1,2.2,3.3,4.4}; + rep.setValue("doublev", doublev); + vector boolv{false, false, true}; + rep.setValue("boolv", boolv); + vector strv{"abc", "def", "ghi"}; + rep.setValue("strv", strv); + vector repv { sub1, sub2 }; + rep.setValue("repv", repv); + + vector> intvv{{1,2,3},{4,5,6}}; + rep.setValue("intvv", intvv); + vector>> intvvv{{{1,2},{3,4}},{{5,6},{8,7}}}; + rep.setValue("intvvv", intvvv); + + vector> doublevv{{1.1,2.1,3},{4.4,5.4,6.4}}; + rep.setValue("doublevv", doublevv); + vector>> doublevvv{{{1.1,2.1},{3.1,4.1}},{{5.1,6.1},{8.1,7.1}}}; + rep.setValue("doublevvv", doublevvv); + + vector> boolvv{{false, true},{true, false}}; + rep.setValue("boolvv", boolvv); + vector>> boolvvv{{{true, false},{true}},{{false},{true}}}; + rep.setValue("boolvvv", boolvvv); + + vector> strvv{{"abc", "def"},{"wer", "qwer"}}; + rep.setValue("strvv", strvv); + vector>> strvvv{{{"wqr", "xcv"},{"234"}},{{"we"},{"wert"}}}; + rep.setValue("strvvv", strvvv); + + vector> repvv{{sub1, sub2},{sub3, sub4}}; + rep.setValue("repvv", repvv); + vector>> repvvv{{{sub5},{sub6}},{{sub3},{sub2}}}; + rep.setValue("repvvv", repvvv); + + EXPECT_EQ(20, rep.size()); + EXPECT_FALSE(rep.empty()); + + OCRepresentation::iterator itr= rep.begin(); + OCRepresentation::iterator endItr = rep.end(); + + for(;itr!=endItr;++itr) + { + if(itr->attrname() == "int") + { + EXPECT_EQ("int", itr->attrname()); + EXPECT_EQ(AttributeType::Integer, itr->type()); + EXPECT_EQ(AttributeType::Integer, itr->base_type()); + EXPECT_EQ(0, itr->depth()); + int curInt = (*itr).getValue(); + EXPECT_EQ(8, curInt); + } + else if (itr->attrname() == "double") + { + EXPECT_EQ("double", itr->attrname()); + EXPECT_EQ(AttributeType::Double, itr->type()); + EXPECT_EQ(AttributeType::Double, itr->base_type()); + EXPECT_EQ(0, itr->depth()); + double curDouble = (*itr).getValue(); + EXPECT_EQ(8.8, curDouble); + } + else if (itr->attrname() == "bool") + { + EXPECT_EQ("bool", itr->attrname()); + EXPECT_EQ(AttributeType::Boolean, itr->type()); + EXPECT_EQ(AttributeType::Boolean, itr->base_type()); + EXPECT_EQ(0, itr->depth()); + bool curBool = (*itr).getValue(); + EXPECT_EQ(true, curBool); + } + else if (itr->attrname() == "string") + { + EXPECT_EQ("string", itr->attrname()); + EXPECT_EQ(AttributeType::String, itr->type()); + EXPECT_EQ(AttributeType::String, itr->base_type()); + EXPECT_EQ(0, itr->depth()); + string curString = (*itr).getValue(); + EXPECT_EQ("this is a string", curString); + } + else if (itr->attrname() == "rep") + { + EXPECT_EQ("rep", itr->attrname()); + EXPECT_EQ(AttributeType::OCRepresentation, itr->type()); + EXPECT_EQ(AttributeType::OCRepresentation, itr->base_type()); + EXPECT_EQ(0, itr->depth()); + OCRepresentation curRep = (*itr).getValue(); + EXPECT_EQ(sub1.getUri(), curRep.getUri()); + } + else if (itr->attrname() == "intv") + { + EXPECT_EQ("intv", itr->attrname()); + EXPECT_EQ(AttributeType::Vector, itr->type()); + EXPECT_EQ(AttributeType::Integer, itr->base_type()); + EXPECT_EQ(1, itr->depth()); + vector curv = (*itr).getValue>(); + EXPECT_EQ(intv, curv); + } + else if (itr->attrname() == "doublev") + { + EXPECT_EQ("doublev", itr->attrname()); + EXPECT_EQ(AttributeType::Vector, itr->type()); + EXPECT_EQ(AttributeType::Double, itr->base_type()); + EXPECT_EQ(1, itr->depth()); + vector curv = (*itr).getValue>(); + EXPECT_EQ(doublev, curv); + } + else if (itr->attrname() == "boolv") + { + EXPECT_EQ("boolv", itr->attrname()); + EXPECT_EQ(AttributeType::Vector, itr->type()); + EXPECT_EQ(AttributeType::Boolean, itr->base_type()); + EXPECT_EQ(1, itr->depth()); + vector curv = (*itr).getValue>(); + EXPECT_EQ(boolv, curv); + } + else if (itr->attrname() == "strv") + { + EXPECT_EQ("strv", itr->attrname()); + EXPECT_EQ(AttributeType::Vector, itr->type()); + EXPECT_EQ(AttributeType::String, itr->base_type()); + EXPECT_EQ(1, itr->depth()); + vector curv = (*itr).getValue>(); + EXPECT_EQ(strv, curv); + } + else if (itr->attrname() == "repv") + { + EXPECT_EQ("repv", itr->attrname()); + EXPECT_EQ(AttributeType::Vector, itr->type()); + EXPECT_EQ(AttributeType::OCRepresentation, itr->base_type()); + EXPECT_EQ(1, itr->depth()); + vector curv = (*itr).getValue>(); + EXPECT_EQ(2, repv.size()); + EXPECT_EQ(sub1.getUri(), repv[0].getUri()); + EXPECT_EQ(sub2.getUri(), repv[1].getUri()); + } + else if (itr->attrname() == "intvv") + { + EXPECT_EQ("intvv", itr->attrname()); + EXPECT_EQ(AttributeType::Vector, itr->type()); + EXPECT_EQ(AttributeType::Integer, itr->base_type()); + EXPECT_EQ(2, itr->depth()); + vector> curv = (*itr).getValue>>(); + EXPECT_EQ(intvv, curv); + } + else if (itr->attrname() == "intvvv") + { + EXPECT_EQ("intvvv", itr->attrname()); + EXPECT_EQ(AttributeType::Vector, itr->type()); + EXPECT_EQ(AttributeType::Integer, itr->base_type()); + EXPECT_EQ(3, itr->depth()); + vector>> curv = (*itr).getValue>>>(); + EXPECT_EQ(intvvv, curv); + } + else if (itr->attrname() == "doublevv") + { + EXPECT_EQ("doublevv", itr->attrname()); + EXPECT_EQ(AttributeType::Vector, itr->type()); + EXPECT_EQ(AttributeType::Double, itr->base_type()); + EXPECT_EQ(2, itr->depth()); + vector> curv = (*itr).getValue>>(); + EXPECT_EQ(doublevv, curv); + } + else if (itr->attrname() == "doublevvv") + { + EXPECT_EQ("doublevvv", itr->attrname()); + EXPECT_EQ(AttributeType::Vector, itr->type()); + EXPECT_EQ(AttributeType::Double, itr->base_type()); + EXPECT_EQ(3, itr->depth()); + vector>> curv = + (*itr).getValue>>>(); + EXPECT_EQ(doublevvv, curv); + } + else if (itr->attrname() == "boolvv") + { + EXPECT_EQ("boolvv", itr->attrname()); + EXPECT_EQ(AttributeType::Vector, itr->type()); + EXPECT_EQ(AttributeType::Boolean, itr->base_type()); + EXPECT_EQ(2, itr->depth()); + vector> curv = (*itr).getValue>>(); + EXPECT_EQ(boolvv, curv); + } + else if (itr->attrname() == "boolvvv") + { + EXPECT_EQ("boolvvv", itr->attrname()); + EXPECT_EQ(AttributeType::Vector, itr->type()); + EXPECT_EQ(AttributeType::Boolean, itr->base_type()); + EXPECT_EQ(3, itr->depth()); + vector>> curv = (*itr).getValue>>>(); + EXPECT_EQ(boolvvv, curv); + } + else if (itr->attrname() == "strvv") + { + EXPECT_EQ("strvv", itr->attrname()); + EXPECT_EQ(AttributeType::Vector, itr->type()); + EXPECT_EQ(AttributeType::String, itr->base_type()); + EXPECT_EQ(2, itr->depth()); + vector> curv = (*itr).getValue>>(); + EXPECT_EQ(strvv, curv); + } + else if (itr->attrname() == "strvvv") + { + EXPECT_EQ("strvvv", itr->attrname()); + EXPECT_EQ(AttributeType::Vector, itr->type()); + EXPECT_EQ(AttributeType::String, itr->base_type()); + EXPECT_EQ(3, itr->depth()); + vector>> curv = + (*itr).getValue>>>(); + EXPECT_EQ(strvvv, curv); + } + else if (itr->attrname() == "repvv") + { + EXPECT_EQ("repvv", itr->attrname()); + EXPECT_EQ(AttributeType::Vector, itr->type()); + EXPECT_EQ(AttributeType::OCRepresentation, itr->base_type()); + EXPECT_EQ(2, itr->depth()); + vector> curv = + (*itr).getValue>>(); + EXPECT_EQ(2, curv.size()); + EXPECT_EQ(2, curv[0].size()); + EXPECT_EQ(sub1.getUri(), curv[0][0].getUri()); + EXPECT_EQ(sub2.getUri(), curv[0][1].getUri()); + EXPECT_EQ(2, curv[1].size()); + EXPECT_EQ(sub3.getUri(), curv[1][0].getUri()); + EXPECT_EQ(sub4.getUri(), curv[1][1].getUri()); + } + else if (itr->attrname() == "repvvv") + { + EXPECT_EQ("repvvv", itr->attrname()); + EXPECT_EQ(AttributeType::Vector, itr->type()); + EXPECT_EQ(AttributeType::OCRepresentation, itr->base_type()); + EXPECT_EQ(3, itr->depth()); + vector>> curv = + (*itr).getValue>>>(); + EXPECT_EQ(2, curv.size()); + EXPECT_EQ(2, curv[0].size()); + EXPECT_EQ(1, curv[0][0].size()); + EXPECT_EQ(sub5.getUri(), curv[0][0][0].getUri()); + EXPECT_EQ(1, curv[0][1].size()); + EXPECT_EQ(sub6.getUri(), curv[0][1][0].getUri()); + EXPECT_EQ(1, curv[1][0].size()); + EXPECT_EQ(sub3.getUri(), curv[1][0][0].getUri()); + EXPECT_EQ(1, curv[1][1].size()); + EXPECT_EQ(sub2.getUri(), curv[1][1][0].getUri()); + } + else + { + EXPECT_TRUE(false) << itr->attrname(); + } + } + } +} diff --git a/resource/unittests/makefile b/resource/unittests/makefile index 7587c04..7b38234 100644 --- a/resource/unittests/makefile +++ b/resource/unittests/makefile @@ -67,7 +67,7 @@ all: prep_dirs $(MOCKS_DIR) unittests prep_dirs: -mkdir -p $(OUT_DIR) -unittests: OCPlatformTest.cpp OCResourceTest.cpp ConstructResourceTest.cpp $(GTEST_LIBS) +unittests: OCPlatformTest.cpp OCResourceTest.cpp ConstructResourceTest.cpp OCRepresentationTest.cpp $(GTEST_LIBS) $(CXX) $^ $(CPPFLAGS) -o $(OUT_DIR)/$@ $(GTEST_DIR): -- 2.7.4