Commit c04fb6a0aed0f1412cc30fb25903a78b108e50ea

Authored by Jojo-1000
Committed by Moritz Wirger
1 parent aa828bf8

Change APICache to allow initial value, remove cached resources from ResourceList.

Change reference to value return types.
include/hueplusplus/APICache.h
... ... @@ -48,7 +48,8 @@ public:
48 48 //! \param path URL appended after username, may be empty.
49 49 //! \param commands HueCommandAPI for making API requests.
50 50 //! \param refresh Interval between cache refreshing. May be 0 to always refresh.
51   - APICache(const std::string& path, const HueCommandAPI& commands, std::chrono::steady_clock::duration refresh);
  51 + //! \param initial Initial value, may be null. If present, assumes the value is up to date.
  52 + APICache(const std::string& path, const HueCommandAPI& commands, std::chrono::steady_clock::duration refresh, const nlohmann::json& initial);
52 53  
53 54 //! \brief Refresh cache now.
54 55 //! \throws std::system_error when system or socket operations fail
... ...
include/hueplusplus/BaseDevice.h
... ... @@ -127,8 +127,9 @@ protected:
127 127 //! \param commands HueCommandAPI for communication with the bridge
128 128 //! \param path Base path for the resource type, ending with a '/'. Example: \c "/lights/"
129 129 //! \param refreshDuration Time between refreshing the cached state.
  130 + //! \param currentState Current state of the device, may be null.
130 131 BaseDevice(int id, const HueCommandAPI& commands, const std::string& path,
131   - std::chrono::steady_clock::duration refreshDuration);
  132 + std::chrono::steady_clock::duration refreshDuration, const nlohmann::json& currentState);
132 133  
133 134 //! \brief Utility function to send a put request to the device.
134 135 //!
... ...
include/hueplusplus/Group.h
... ... @@ -46,7 +46,8 @@ public:
46 46 //! \param id Group id in the bridge
47 47 //! \param commands HueCommandAPI for requests
48 48 //! \param refreshDuration Time between refreshing the cached state.
49   - Group(int id, const HueCommandAPI& commands, std::chrono::steady_clock::duration refreshDuration);
  49 + //! \param currentState The current state, may be null.
  50 + Group(int id, const HueCommandAPI& commands, std::chrono::steady_clock::duration refreshDuration, const nlohmann::json& currentState);
50 51  
51 52 //! \brief Refreshes internal cached state.
52 53 //! \param force \c true forces a refresh, regardless of how long the last refresh was ago.
... ...
include/hueplusplus/Light.h
... ... @@ -554,7 +554,6 @@ public:
554 554 ///@}
555 555  
556 556 protected:
557   -
558 557 //! \brief Protected ctor that is used by \ref Bridge class.
559 558 //!
560 559 //! \param id Integer that specifies the id of this light
... ... @@ -563,7 +562,6 @@ protected:
563 562 //! leaves strategies unset
564 563 Light(int id, const HueCommandAPI& commands);
565 564  
566   -
567 565 Light(int id, const std::shared_ptr<APICache>& baseCache);
568 566  
569 567 //! \brief Protected ctor that is used by \ref Bridge class, also sets
... ... @@ -576,14 +574,15 @@ protected:
576 574 //! \param colorHueStrategy Strategy for color hue/saturation. May be nullptr.
577 575 //! \param refreshDuration Time between refreshing the cached state.
578 576 //! Can be 0 to always refresh, or steady_clock::duration::max() to never refresh.
  577 + //! \param currentState The current light state, may be null.
579 578 //! \throws std::system_error when system or socket operations fail
580 579 //! \throws HueException when response contained no body
581 580 //! \throws HueAPIResponseException when response contains an error
582 581 //! \throws nlohmann::json::parse_error when response could not be parsed
583 582 Light(int id, const HueCommandAPI& commands, std::shared_ptr<const BrightnessStrategy> brightnessStrategy,
584 583 std::shared_ptr<const ColorTemperatureStrategy> colorTempStrategy,
585   - std::shared_ptr<const ColorHueStrategy> colorHueStrategy,
586   - std::chrono::steady_clock::duration refreshDuration = std::chrono::seconds(10));
  584 + std::shared_ptr<const ColorHueStrategy> colorHueStrategy, std::chrono::steady_clock::duration refreshDuration,
  585 + const nlohmann::json& currentState);
587 586  
588 587 //! \brief Protected function that sets the brightness strategy.
589 588 //!
... ...
include/hueplusplus/ResourceList.h
... ... @@ -39,7 +39,7 @@ namespace hueplusplus
39 39 //! \tparam IdT Type of the resource id. int or std::string
40 40 //!
41 41 //! The resources are assumed to be in an object with ids as keys.
42   -//! The Resource class needs a constructor that accepts \c id, HueCommandAPI and \c refreshDuration;
  42 +//! The Resource class needs a constructor that accepts \c id, HueCommandAPI, \c refreshDuration and \c state;
43 43 //! otherwise a factory function needs to be provided that takes \c id and the JSON state.
44 44 template <typename Resource, typename IdT>
45 45 class ResourceList
... ... @@ -78,7 +78,7 @@ public:
78 78 std::chrono::steady_clock::duration refreshDuration,
79 79 const std::function<Resource(IdType, const nlohmann::json&, const std::shared_ptr<APICache>&)>& factory
80 80 = nullptr)
81   - : stateCache(std::make_shared<APICache>(path, commands, refreshDuration)),
  81 + : stateCache(std::make_shared<APICache>(path, commands, refreshDuration, nullptr)),
82 82 factory(factory),
83 83 path(path + '/'),
84 84 sharedState(false)
... ... @@ -98,18 +98,14 @@ public:
98 98 //! \throws HueException when response contains no body
99 99 //! \throws HueAPIResponseException when response contains an error
100 100 //! \throws nlohmann::json::parse_error when response could not be parsed
101   - std::vector<std::reference_wrapper<Resource>> getAll()
  101 + std::vector<Resource> getAll()
102 102 {
103   - nlohmann::json state = stateCache->getValue();
104   - for (auto it = state.begin(); it != state.end(); ++it)
105   - {
106   - get(maybeStoi(it.key()));
107   - }
108   - std::vector<std::reference_wrapper<Resource>> result;
  103 + nlohmann::json& state = stateCache->getValue();
  104 + std::vector<Resource> result;
109 105 result.reserve(state.size());
110   - for (auto& entry : resources)
  106 + for (auto it = state.begin(); it != state.end(); ++it)
111 107 {
112   - result.emplace_back(entry.second);
  108 + result.emplace_back(construct(maybeStoi(it.key()), it.value()));
113 109 }
114 110 return result;
115 111 }
... ... @@ -121,21 +117,15 @@ public:
121 117 //! \throws HueException when id does not exist
122 118 //! \throws HueAPIResponseException when response contains an error
123 119 //! \throws nlohmann::json::parse_error when response could not be parsed
124   - Resource& get(const IdType& id)
  120 + Resource get(const IdType& id)
125 121 {
126   - auto pos = resources.find(id);
127   - if (pos != resources.end())
128   - {
129   - pos->second.refresh(true);
130   - return pos->second;
131   - }
132 122 const nlohmann::json& state = stateCache->getValue();
133 123 std::string key = maybeToString(id);
134 124 if (!state.count(key))
135 125 {
136 126 throw HueException(FileInfo {__FILE__, __LINE__, __func__}, "Resource id is not valid");
137 127 }
138   - return resources.emplace(id, construct(id, state[key])).first->second;
  128 + return construct(id, state[key]);
139 129 }
140 130  
141 131 //! \brief Checks whether resource with id exists
... ... @@ -145,30 +135,14 @@ public:
145 135 //! \throws HueException when response contains no body
146 136 //! \throws HueAPIResponseException when response contains an error
147 137 //! \throws nlohmann::json::parse_error when response could not be parsed
148   - bool exists(const IdType& id)
149   - {
150   - auto pos = resources.find(id);
151   - if (pos != resources.end())
152   - {
153   - return true;
154   - }
155   - return stateCache->getValue().count(maybeToString(id)) != 0;
156   - }
  138 + bool exists(const IdType& id) { return stateCache->getValue().count(maybeToString(id)) != 0; }
157 139  
158 140 //! \brief Checks whether resource with id exists
159 141 //! \param id Identifier of the resource to check
160 142 //! \returns true when the resource with given id exists
161 143 //! \note This will not update the cache
162 144 //! \throws HueException when the cache is empty
163   - bool exists(const IdType& id) const
164   - {
165   - auto pos = resources.find(id);
166   - if (pos != resources.end())
167   - {
168   - return true;
169   - }
170   - return stateCache->getValue().count(maybeToString(id)) != 0;
171   - }
  145 + bool exists(const IdType& id) const { return stateCache->getValue().count(maybeToString(id)) != 0; }
172 146  
173 147 //! \brief Removes the resource
174 148 //! \param id Identifier of the resource to remove
... ... @@ -185,11 +159,6 @@ public:
185 159 nlohmann::json result = stateCache->getCommandAPI().DELETERequest(
186 160 requestPath, nlohmann::json::object(), FileInfo {__FILE__, __LINE__, __func__});
187 161 bool success = utils::safeGetMember(result, 0, "success") == requestPath + " deleted";
188   - auto it = resources.find(id);
189   - if (success && it != resources.end())
190   - {
191   - resources.erase(it);
192   - }
193 162 return success;
194 163 }
195 164  
... ... @@ -205,7 +174,7 @@ protected:
205 174 Resource construct(const IdType& id, const nlohmann::json& state)
206 175 {
207 176 return construct(
208   - id, state, std::is_constructible<Resource, IdType, HueCommandAPI, std::chrono::steady_clock::duration> {});
  177 + id, state, std::is_constructible<Resource, IdType, HueCommandAPI, std::chrono::steady_clock::duration, const nlohmann::json&> {});
209 178 }
210 179  
211 180 //! \brief Protected defaulted move constructor
... ... @@ -214,7 +183,7 @@ protected:
214 183 ResourceList& operator=(ResourceList&&) = default;
215 184  
216 185 private:
217   - // Resource is constructable
  186 + // Resource is constructible
218 187 Resource construct(const IdType& id, const nlohmann::json& state, std::true_type)
219 188 {
220 189 if (factory)
... ... @@ -229,11 +198,11 @@ private:
229 198 }
230 199 else
231 200 {
232   - return Resource(id, stateCache->getCommandAPI(), stateCache->getRefreshDuration());
  201 + return Resource(id, stateCache->getCommandAPI(), stateCache->getRefreshDuration(), state);
233 202 }
234 203 }
235 204 }
236   - // Resource is not constructable
  205 + // Resource is not constructible
237 206 Resource construct(const IdType& id, const nlohmann::json& state, std::false_type)
238 207 {
239 208 if (!factory)
... ... @@ -254,7 +223,6 @@ protected:
254 223 std::shared_ptr<APICache> stateCache;
255 224 std::function<Resource(IdType, const nlohmann::json&, const std::shared_ptr<APICache>&)> factory;
256 225 std::string path;
257   - std::map<IdType, Resource> resources;
258 226 bool sharedState;
259 227 };
260 228  
... ... @@ -361,21 +329,15 @@ public:
361 329 using Base::Base;
362 330 //! \brief Get group, specially handles group 0
363 331 //! \see ResourceList::get
364   - Resource& get(const int& id)
  332 + Resource get(const int& id)
365 333 {
366   - auto pos = this->resources.find(id);
367   - if (pos != this->resources.end())
368   - {
369   - pos->second.refresh();
370   - return pos->second;
371   - }
372 334 const nlohmann::json& state = this->stateCache->getValue();
373 335 std::string key = this->maybeToString(id);
374 336 if (!state.count(key) && id != 0)
375 337 {
376 338 throw HueException(FileInfo {__FILE__, __LINE__, __func__}, "Resource id is not valid");
377 339 }
378   - return this->resources.emplace(id, this->construct(id, state[key])).first->second;
  340 + return this->construct(id, id == 0 ? nlohmann::json{ nullptr } : state[key]);
379 341 }
380 342 //! \brief Get group, specially handles group 0
381 343 //! \see ResourceList::exists
... ...
include/hueplusplus/Rule.h
... ... @@ -46,7 +46,8 @@ public:
46 46 //! \param id Rule id in the bridge
47 47 //! \param commands HueCommandAPI for requests
48 48 //! \param refreshDuration Time between refreshing the cached state.
49   - Rule(int id, const HueCommandAPI& commands, std::chrono::steady_clock::duration refreshDuration);
  49 + //! \param currentState The current state, may be null.
  50 + Rule(int id, const HueCommandAPI& commands, std::chrono::steady_clock::duration refreshDuration, const nlohmann::json& currentState);
50 51  
51 52 //! \brief Refreshes internal cached state.
52 53 //! \param force \c true forces a refresh, regardless of how long the last refresh was ago.
... ...
include/hueplusplus/Scene.h
... ... @@ -127,7 +127,8 @@ public:
127 127 //! \param id Scene id
128 128 //! \param commands HueCommandAPI for requests
129 129 //! \param refreshDuration Time between refreshing the cached state
130   - Scene(const std::string& id, const HueCommandAPI& commands, std::chrono::steady_clock::duration refreshDuration);
  130 + //! \param currentState The current state, may be null.
  131 + Scene(const std::string& id, const HueCommandAPI& commands, std::chrono::steady_clock::duration refreshDuration, const nlohmann::json& currentState);
131 132  
132 133 //! \brief Refreshes internal cached state
133 134 //! \param force \c true forces a refresh, regardless of how long the last refresh was ago.
... ...
include/hueplusplus/Schedule.h
... ... @@ -38,7 +38,8 @@ public:
38 38 //! \param id Schedule ID
39 39 //! \param commands HueCommandAPI for requests
40 40 //! \param refreshDuration Time between refreshing the cached state
41   - Schedule(int id, const HueCommandAPI& commands, std::chrono::steady_clock::duration refreshDuration);
  41 + //! \param currentState The current state, may be null.
  42 + Schedule(int id, const HueCommandAPI& commands, std::chrono::steady_clock::duration refreshDuration, const nlohmann::json& currentState);
42 43  
43 44 //! \brief Refreshes internal cached state
44 45 //! \throws std::system_error when system or socket operations fail
... ...
include/hueplusplus/Sensor.h
... ... @@ -65,7 +65,8 @@ public:
65 65 //! \param id Integer that specifies the id of this sensor
66 66 //! \param commands HueCommandAPI for communication with the bridge
67 67 //! \param refreshDuration Time between refreshing the cached state.
68   - Sensor(int id, const HueCommandAPI& commands, std::chrono::steady_clock::duration refreshDuration);
  68 + //! \param currentState The current state, may be null.
  69 + Sensor(int id, const HueCommandAPI& commands, std::chrono::steady_clock::duration refreshDuration, const nlohmann::json& currentState);
69 70  
70 71 //!\name Config attributes
71 72 ///@{
... ...
src/APICache.cpp
... ... @@ -32,11 +32,16 @@ APICache::APICache(
32 32 commands(baseCache->commands),
33 33 refreshDuration(refresh),
34 34 lastRefresh(baseCache->lastRefresh)
35   -{}
  35 +{ }
36 36  
37   -APICache::APICache(const std::string& path, const HueCommandAPI& commands, std::chrono::steady_clock::duration refresh)
38   - : path(path), commands(commands), refreshDuration(refresh), lastRefresh(std::chrono::steady_clock::duration::zero())
39   -{}
  37 +APICache::APICache(const std::string& path, const HueCommandAPI& commands, std::chrono::steady_clock::duration refresh,
  38 + const nlohmann::json& initial)
  39 + : path(path),
  40 + commands(commands),
  41 + refreshDuration(refresh),
  42 + lastRefresh(initial.is_null() ? std::chrono::steady_clock::time_point() : std::chrono::steady_clock::now()),
  43 + value(initial)
  44 +{ }
40 45  
41 46 void APICache::refresh()
42 47 {
... ...
src/BaseDevice.cpp
... ... @@ -96,10 +96,11 @@ BaseDevice::BaseDevice(int id, const std::shared_ptr&lt;APICache&gt;&amp; baseCache)
96 96 { }
97 97  
98 98 BaseDevice::BaseDevice(
99   - int id, const HueCommandAPI& commands, const std::string& path, std::chrono::steady_clock::duration refreshDuration)
100   - : id(id), path(path), state(path + std::to_string(id), commands, refreshDuration)
  99 + int id, const HueCommandAPI& commands, const std::string& path, std::chrono::steady_clock::duration refreshDuration, const nlohmann::json& currentState)
  100 + : id(id), path(path), state(path + std::to_string(id), commands, refreshDuration, currentState)
101 101 {
102   - state.refresh();
  102 + // Initialize value if not null
  103 + state.getValue();
103 104 }
104 105  
105 106 nlohmann::json BaseDevice::sendPutRequest(const std::string& subPath, const nlohmann::json& request, FileInfo fileInfo)
... ...
src/Bridge.cpp
... ... @@ -145,7 +145,7 @@ Bridge::Bridge(const std::string&amp; ip, const int port, const std::string&amp; usernam
145 145 http_handler(std::move(handler)),
146 146 refreshDuration(refreshDuration),
147 147 stateCache(std::make_shared<APICache>(
148   - "", HueCommandAPI(ip, port, username, http_handler), std::chrono::steady_clock::duration::max())),
  148 + "", HueCommandAPI(ip, port, username, http_handler), std::chrono::steady_clock::duration::max(), nullptr)),
149 149 lightList(stateCache, "lights", refreshDuration, sharedState,
150 150 [factory = LightFactory(stateCache->getCommandAPI(), refreshDuration)](
151 151 int id, const nlohmann::json& state, const std::shared_ptr<APICache>& baseCache) mutable {
... ... @@ -306,7 +306,7 @@ const Bridge::RuleList&amp; Bridge::rules() const
306 306 void Bridge::setHttpHandler(std::shared_ptr<const IHttpHandler> handler)
307 307 {
308 308 http_handler = handler;
309   - stateCache = std::make_shared<APICache>("", HueCommandAPI(ip, port, username, handler), refreshDuration);
  309 + stateCache = std::make_shared<APICache>("", HueCommandAPI(ip, port, username, handler), refreshDuration, nullptr);
310 310 lightList = LightList(stateCache, "lights", refreshDuration,sharedState,
311 311 [factory = LightFactory(stateCache->getCommandAPI(), refreshDuration)](int id, const nlohmann::json& state,
312 312 const std::shared_ptr<APICache>& baseCache) mutable { return factory.createLight(state, id, baseCache); });
... ...
src/Group.cpp
... ... @@ -8,10 +8,11 @@ Group::Group(int id, const std::shared_ptr&lt;APICache&gt;&amp; baseCache)
8 8 : id(id), state(baseCache, std::to_string(id), baseCache->getRefreshDuration())
9 9 { }
10 10  
11   -Group::Group(int id, const HueCommandAPI& commands, std::chrono::steady_clock::duration refreshDuration)
12   - : id(id), state("/groups/" + std::to_string(id), commands, refreshDuration)
  11 +Group::Group(int id, const HueCommandAPI& commands, std::chrono::steady_clock::duration refreshDuration, const nlohmann::json& currentState)
  12 + : id(id), state("/groups/" + std::to_string(id), commands, refreshDuration, currentState)
13 13 {
14   - state.refresh();
  14 + // Initialize value if not null
  15 + state.getValue();
15 16 }
16 17  
17 18 void Group::refresh(bool force)
... ...
src/HueDeviceTypes.cpp
... ... @@ -75,7 +75,7 @@ Light LightFactory::createLight(const nlohmann::json&amp; lightState, int id, const
75 75 // Ignore case
76 76 std::transform(type.begin(), type.end(), type.begin(), [](char c) { return std::tolower(c); });
77 77  
78   - Light light = baseCache ? Light(id, baseCache) : Light(id, commands, nullptr, nullptr, nullptr, refreshDuration);
  78 + Light light = baseCache ? Light(id, baseCache) : Light(id, commands, nullptr, nullptr, nullptr, refreshDuration, lightState);
79 79  
80 80 if (type == "on/off light" || type == "on/off plug-in unit")
81 81 {
... ...
src/Light.cpp
... ... @@ -112,15 +112,18 @@ StateTransaction Light::transaction()
112 112 state.getCommandAPI(), "/lights/" + std::to_string(id) + "/state", &state.getValue().at("state"));
113 113 }
114 114  
115   -Light::Light(int id, const HueCommandAPI& commands) : Light(id, commands, nullptr, nullptr, nullptr) { }
  115 +Light::Light(int id, const HueCommandAPI& commands)
  116 + : Light(id, commands, nullptr, nullptr, nullptr, std::chrono::seconds(10), nullptr)
  117 +{ }
116 118  
117 119 Light::Light(int id, const std::shared_ptr<APICache>& baseCache) : BaseDevice(id, baseCache), colorType(ColorType::NONE)
118 120 { }
119 121  
120 122 Light::Light(int id, const HueCommandAPI& commands, std::shared_ptr<const BrightnessStrategy> brightnessStrategy,
121 123 std::shared_ptr<const ColorTemperatureStrategy> colorTempStrategy,
122   - std::shared_ptr<const ColorHueStrategy> colorHueStrategy, std::chrono::steady_clock::duration refreshDuration)
123   - : BaseDevice(id, commands, "/lights/", refreshDuration),
  124 + std::shared_ptr<const ColorHueStrategy> colorHueStrategy, std::chrono::steady_clock::duration refreshDuration,
  125 + const nlohmann::json& currentState)
  126 + : BaseDevice(id, commands, "/lights/", refreshDuration, currentState),
124 127 colorType(ColorType::NONE),
125 128 brightnessStrategy(std::move(brightnessStrategy)),
126 129 colorTemperatureStrategy(std::move(colorTempStrategy)),
... ...
src/Rule.cpp
... ... @@ -130,10 +130,10 @@ Condition Condition::parse(const nlohmann::json&amp; json)
130 130 return Condition(address, op, value);
131 131 }
132 132  
133   -Rule::Rule(int id, const HueCommandAPI& commands, std::chrono::steady_clock::duration refreshDuration)
134   - : id(id), state("/rules/" + std::to_string(id), commands, refreshDuration)
  133 +Rule::Rule(int id, const HueCommandAPI& commands, std::chrono::steady_clock::duration refreshDuration, const nlohmann::json& currentState)
  134 + : id(id), state("/rules/" + std::to_string(id), commands, refreshDuration, currentState)
135 135 {
136   - state.refresh();
  136 + refresh();
137 137 }
138 138  
139 139 void Rule::refresh(bool force)
... ...
src/Scene.cpp
... ... @@ -150,8 +150,8 @@ LightState LightStateBuilder::create()
150 150 return LightState(state);
151 151 }
152 152  
153   -Scene::Scene(const std::string& id, const HueCommandAPI& commands, std::chrono::steady_clock::duration refreshDuration)
154   - : id(id), state("/scenes/" + id, commands, refreshDuration)
  153 +Scene::Scene(const std::string& id, const HueCommandAPI& commands, std::chrono::steady_clock::duration refreshDuration, const nlohmann::json& currentState)
  154 + : id(id), state("/scenes/" + id, commands, refreshDuration, currentState)
155 155 {
156 156 refresh();
157 157 }
... ...
src/Schedule.cpp
... ... @@ -24,8 +24,8 @@
24 24  
25 25 namespace hueplusplus
26 26 {
27   -Schedule::Schedule(int id, const HueCommandAPI& commands, std::chrono::steady_clock::duration refreshDuration)
28   - : id(id), state("/schedules/" + std::to_string(id), commands, refreshDuration)
  27 +Schedule::Schedule(int id, const HueCommandAPI& commands, std::chrono::steady_clock::duration refreshDuration, const nlohmann::json& currentState)
  28 + : id(id), state("/schedules/" + std::to_string(id), commands, refreshDuration, currentState)
29 29 {
30 30 state.refresh();
31 31 }
... ...
src/Sensor.cpp
... ... @@ -235,8 +235,8 @@ Sensor::Sensor(int id, const std::shared_ptr&lt;APICache&gt;&amp; baseCache)
235 235 { }
236 236  
237 237  
238   -Sensor::Sensor(int id, const HueCommandAPI& commands, std::chrono::steady_clock::duration refreshDuration)
239   - : BaseDevice(id, commands, "/sensors/", refreshDuration)
  238 +Sensor::Sensor(int id, const HueCommandAPI& commands, std::chrono::steady_clock::duration refreshDuration, const nlohmann::json& currentState)
  239 + : BaseDevice(id, commands, "/sensors/", refreshDuration, currentState)
240 240 { }
241 241  
242 242 CreateSensor::CreateSensor(const std::string& name, const std::string& modelid, const std::string& swversion,
... ...
test/mocks/mock_Light.h
... ... @@ -38,7 +38,7 @@ class MockLight : public hueplusplus::Light
38 38 public:
39 39 MockLight(std::shared_ptr<const hueplusplus::IHttpHandler> handler)
40 40 : Light(1, hueplusplus::HueCommandAPI(getBridgeIp(), getBridgePort(), getBridgeUsername(), handler), nullptr,
41   - nullptr, nullptr, std::chrono::steady_clock::duration::max())
  41 + nullptr, nullptr, std::chrono::steady_clock::duration::max(), nullptr)
42 42 {
43 43 // Set refresh duration to max, so random refreshes do not hinder the test setups
44 44 }
... ...
test/test_APICache.cpp
... ... @@ -35,23 +35,23 @@ TEST(APICache, getRefreshDuration)
35 35 HueCommandAPI commands(getBridgeIp(), getBridgePort(), getBridgeUsername(), handler);
36 36 {
37 37 std::chrono::steady_clock::duration refresh = std::chrono::seconds(20);
38   - APICache cache("", commands, refresh);
  38 + APICache cache("", commands, refresh, nullptr);
39 39 EXPECT_EQ(refresh, cache.getRefreshDuration());
40 40 }
41 41 {
42 42 std::chrono::steady_clock::duration refresh = std::chrono::seconds(0);
43   - APICache cache("", commands, refresh);
  43 + APICache cache("", commands, refresh, nullptr);
44 44 EXPECT_EQ(refresh, cache.getRefreshDuration());
45 45 }
46 46 {
47 47 std::chrono::steady_clock::duration refresh = std::chrono::steady_clock::duration::max();
48   - APICache cache("", commands, refresh);
  48 + APICache cache("", commands, refresh, nullptr);
49 49 EXPECT_EQ(refresh, cache.getRefreshDuration());
50 50 }
51 51 // With base cache, still independent duration
52 52 {
53 53 auto duration = std::chrono::seconds(5);
54   - auto baseCache = std::make_shared<APICache>("/test", commands, std::chrono::seconds(0));
  54 + auto baseCache = std::make_shared<APICache>("/test", commands, std::chrono::seconds(0), nullptr);
55 55 APICache c(baseCache, "api", duration);
56 56 EXPECT_EQ(duration, c.getRefreshDuration());
57 57 }
... ... @@ -65,7 +65,7 @@ TEST(APICache, refresh)
65 65  
66 66 {
67 67 std::string path = "/test/abc";
68   - APICache cache(path, commands, std::chrono::seconds(10));
  68 + APICache cache(path, commands, std::chrono::seconds(10), nullptr);
69 69 EXPECT_CALL(*handler,
70 70 GETJson("/api/" + getBridgeUsername() + path, nlohmann::json::object(), getBridgeIp(), getBridgePort()))
71 71 .WillOnce(Return(nlohmann::json::object()));
... ... @@ -74,7 +74,7 @@ TEST(APICache, refresh)
74 74 }
75 75 {
76 76 std::string path = "";
77   - APICache cache(path, commands, std::chrono::seconds(10));
  77 + APICache cache(path, commands, std::chrono::seconds(10), nullptr);
78 78 EXPECT_CALL(*handler,
79 79 GETJson("/api/" + getBridgeUsername() + path, nlohmann::json::object(), getBridgeIp(), getBridgePort()))
80 80 .Times(2)
... ... @@ -94,7 +94,8 @@ TEST(APICache, refreshBase)
94 94 const std::string childPath = "/test/abc";
95 95 // Base cache with max duration
96 96 {
97   - auto baseCache = std::make_shared<APICache>(basePath, commands, std::chrono::steady_clock::duration::max());
  97 + auto baseCache
  98 + = std::make_shared<APICache>(basePath, commands, std::chrono::steady_clock::duration::max(), nullptr);
98 99 APICache cache(baseCache, "abc", std::chrono::seconds(0));
99 100  
100 101 // First call refreshes base, second call only child
... ... @@ -112,7 +113,7 @@ TEST(APICache, refreshBase)
112 113 }
113 114 // Base cache with min duration
114 115 {
115   - auto baseCache = std::make_shared<APICache>(basePath, commands, std::chrono::seconds(0));
  116 + auto baseCache = std::make_shared<APICache>(basePath, commands, std::chrono::seconds(0), nullptr);
116 117 APICache cache(baseCache, "abc", std::chrono::seconds(0));
117 118  
118 119 // Both calls refresh base
... ... @@ -135,7 +136,7 @@ TEST(APICache, getValue)
135 136 // Always refresh
136 137 {
137 138 std::string path = "/test/abc";
138   - APICache cache(path, commands, std::chrono::seconds(0));
  139 + APICache cache(path, commands, std::chrono::seconds(0), nullptr);
139 140 nlohmann::json value = {{"a", "b"}};
140 141 EXPECT_CALL(*handler,
141 142 GETJson("/api/" + getBridgeUsername() + path, nlohmann::json::object(), getBridgeIp(), getBridgePort()))
... ... @@ -148,7 +149,7 @@ TEST(APICache, getValue)
148 149 // Only refresh once
149 150 {
150 151 std::string path = "/test/abc";
151   - APICache cache(path, commands, std::chrono::steady_clock::duration::max());
  152 + APICache cache(path, commands, std::chrono::steady_clock::duration::max(), nullptr);
152 153 nlohmann::json value = {{"a", "b"}};
153 154 EXPECT_CALL(*handler,
154 155 GETJson("/api/" + getBridgeUsername() + path, nlohmann::json::object(), getBridgeIp(), getBridgePort()))
... ... @@ -160,7 +161,7 @@ TEST(APICache, getValue)
160 161 // Only refresh once
161 162 {
162 163 std::string path = "/test/abc";
163   - APICache cache(path, commands, std::chrono::seconds(0));
  164 + APICache cache(path, commands, std::chrono::seconds(0), nullptr);
164 165 nlohmann::json value = {{"a", "b"}};
165 166 EXPECT_CALL(*handler,
166 167 GETJson("/api/" + getBridgeUsername() + path, nlohmann::json::object(), getBridgeIp(), getBridgePort()))
... ... @@ -172,7 +173,7 @@ TEST(APICache, getValue)
172 173 // No refresh with const throws exception
173 174 {
174 175 std::string path = "/test/abc";
175   - const APICache cache(path, commands, std::chrono::steady_clock::duration::max());
  176 + const APICache cache(path, commands, std::chrono::steady_clock::duration::max(), nullptr);
176 177 nlohmann::json value = {{"a", "b"}};
177 178 EXPECT_CALL(*handler,
178 179 GETJson("/api/" + getBridgeUsername() + path, nlohmann::json::object(), getBridgeIp(), getBridgePort()))
... ... @@ -180,6 +181,29 @@ TEST(APICache, getValue)
180 181 EXPECT_THROW(cache.getValue(), HueException);
181 182 Mock::VerifyAndClearExpectations(handler.get());
182 183 }
  184 + // No refresh with initial value
  185 + {
  186 + std::string path = "/test/abc";
  187 + nlohmann::json value = {{"a", "b"}};
  188 + APICache cache(path, commands, std::chrono::steady_clock::duration::max(), value);
  189 + EXPECT_CALL(*handler,
  190 + GETJson("/api/" + getBridgeUsername() + path, nlohmann::json::object(), getBridgeIp(), getBridgePort()))
  191 + .Times(0);
  192 + EXPECT_EQ(value, cache.getValue());
  193 + EXPECT_EQ(value, cache.getValue());
  194 + Mock::VerifyAndClearExpectations(handler.get());
  195 + }
  196 + // No refresh with const but initial value
  197 + {
  198 + std::string path = "/test/abc";
  199 + nlohmann::json value = {{"a", "b"}};
  200 + const APICache cache(path, commands, std::chrono::steady_clock::duration::max(), value);
  201 + EXPECT_CALL(*handler,
  202 + GETJson("/api/" + getBridgeUsername() + path, nlohmann::json::object(), getBridgeIp(), getBridgePort()))
  203 + .Times(0);
  204 + EXPECT_EQ(value, cache.getValue());
  205 + Mock::VerifyAndClearExpectations(handler.get());
  206 + }
183 207 }
184 208  
185 209 TEST(APICache, getValueBase)
... ... @@ -194,7 +218,7 @@ TEST(APICache, getValueBase)
194 218 const nlohmann::json baseValue = {{"abc", childValue}};
195 219 // Always refresh base
196 220 {
197   - auto baseCache = std::make_shared<APICache>(basePath, commands, std::chrono::seconds(0));
  221 + auto baseCache = std::make_shared<APICache>(basePath, commands, std::chrono::seconds(0), nullptr);
198 222 APICache cache(baseCache, "abc", std::chrono::seconds(0));
199 223 EXPECT_CALL(*handler,
200 224 GETJson("/api/" + getBridgeUsername() + basePath, nlohmann::json::object(), getBridgeIp(), getBridgePort()))
... ... @@ -206,7 +230,7 @@ TEST(APICache, getValueBase)
206 230 }
207 231 // Child duration > base duration
208 232 {
209   - auto baseCache = std::make_shared<APICache>(basePath, commands, std::chrono::seconds(0));
  233 + auto baseCache = std::make_shared<APICache>(basePath, commands, std::chrono::seconds(0), nullptr);
210 234 APICache cache(baseCache, "abc", std::chrono::steady_clock::duration::max());
211 235 EXPECT_CALL(*handler,
212 236 GETJson("/api/" + getBridgeUsername() + basePath, nlohmann::json::object(), getBridgeIp(), getBridgePort()))
... ... @@ -218,16 +242,18 @@ TEST(APICache, getValueBase)
218 242 }
219 243 // Child duration < base duration
220 244 {
221   - auto baseCache = std::make_shared<APICache>(basePath, commands, std::chrono::steady_clock::duration::max());
  245 + auto baseCache
  246 + = std::make_shared<APICache>(basePath, commands, std::chrono::steady_clock::duration::max(), nullptr);
222 247 APICache cache(baseCache, "abc", std::chrono::seconds(0));
223   - const nlohmann::json updateChildValue = { {"test", "updated"} };
  248 + const nlohmann::json updateChildValue = {{"test", "updated"}};
224 249 InSequence s;
225 250 EXPECT_CALL(*handler,
226 251 GETJson("/api/" + getBridgeUsername() + basePath, nlohmann::json::object(), getBridgeIp(), getBridgePort()))
227 252 .Times(1)
228 253 .WillRepeatedly(Return(baseValue));
229 254 EXPECT_CALL(*handler,
230   - GETJson("/api/" + getBridgeUsername() + childPath, nlohmann::json::object(), getBridgeIp(), getBridgePort()))
  255 + GETJson(
  256 + "/api/" + getBridgeUsername() + childPath, nlohmann::json::object(), getBridgeIp(), getBridgePort()))
231 257 .Times(1)
232 258 .WillRepeatedly(Return(updateChildValue));
233 259 EXPECT_EQ(childValue, cache.getValue());
... ... @@ -238,7 +264,8 @@ TEST(APICache, getValueBase)
238 264 }
239 265 // Only refresh once
240 266 {
241   - auto baseCache = std::make_shared<APICache>(basePath, commands, std::chrono::steady_clock::duration::max());
  267 + auto baseCache
  268 + = std::make_shared<APICache>(basePath, commands, std::chrono::steady_clock::duration::max(), nullptr);
242 269 APICache cache(baseCache, "abc", std::chrono::steady_clock::duration::max());
243 270 EXPECT_CALL(*handler,
244 271 GETJson("/api/" + getBridgeUsername() + basePath, nlohmann::json::object(), getBridgeIp(), getBridgePort()))
... ... @@ -259,12 +286,12 @@ TEST(APICache, getRequestPath)
259 286 // No base cache
260 287 {
261 288 std::string path = "/test/api";
262   - APICache c(path, commands, std::chrono::seconds(0));
  289 + APICache c(path, commands, std::chrono::seconds(0), nullptr);
263 290 EXPECT_EQ(path, c.getRequestPath());
264 291 }
265 292 // With base cache
266 293 {
267   - auto baseCache = std::make_shared<APICache>("/test", commands, std::chrono::seconds(0));
  294 + auto baseCache = std::make_shared<APICache>("/test", commands, std::chrono::seconds(0), nullptr);
268 295 APICache c(baseCache, "api", std::chrono::seconds(0));
269 296 EXPECT_EQ("/test/api", c.getRequestPath());
270 297 }
... ...
test/test_BaseDevice.cpp
... ... @@ -34,8 +34,8 @@ class TestDevice : public BaseDevice
34 34 {
35 35 public:
36 36 TestDevice(int id, const HueCommandAPI& commands, const std::string& path,
37   - std::chrono::steady_clock::duration refreshDuration)
38   - : BaseDevice(id, commands, path, refreshDuration)
  37 + std::chrono::steady_clock::duration refreshDuration, const nlohmann::json& currentState)
  38 + : BaseDevice(id, commands, path, refreshDuration, currentState)
39 39 { }
40 40 };
41 41  
... ... @@ -61,7 +61,7 @@ protected:
61 61 EXPECT_CALL(*handler,
62 62 GETJson("/api/" + getBridgeUsername() + path + std::to_string(id), _, getBridgeIp(), getBridgePort()))
63 63 .WillOnce(Return(state));
64   - return TestDevice(id, commands, path, std::chrono::steady_clock::duration::max());
  64 + return TestDevice(id, commands, path, std::chrono::steady_clock::duration::max(), nullptr);
65 65 }
66 66 };
67 67  
... ...
test/test_Bridge.cpp
... ... @@ -265,12 +265,7 @@ TEST(Bridge, getLight)
265 265 *handler, GETJson("/api/" + getBridgeUsername(), nlohmann::json::object(), getBridgeIp(), getBridgePort()))
266 266 .Times(1)
267 267 .WillOnce(Return(hue_bridge_state));
268   -
269   - EXPECT_CALL(*handler,
270   - GETJson("/api/" + getBridgeUsername() + "/lights/1", nlohmann::json::object(), getBridgeIp(), getBridgePort()))
271   - .Times(AtLeast(1))
272   - .WillRepeatedly(Return(hue_bridge_state["lights"]["1"]));
273   -
  268 +
274 269 // Refresh cache
275 270 test_bridge = Bridge(getBridgeIp(), getBridgePort(), getBridgeUsername(), handler);
276 271  
... ... @@ -305,11 +300,6 @@ TEST(Bridge, removeLight)
305 300  
306 301 Bridge test_bridge(getBridgeIp(), getBridgePort(), getBridgeUsername(), handler);
307 302  
308   - EXPECT_CALL(*handler,
309   - GETJson("/api/" + getBridgeUsername() + "/lights/1", nlohmann::json::object(), getBridgeIp(), getBridgePort()))
310   - .Times(1)
311   - .WillRepeatedly(Return(hue_bridge_state["lights"]["1"]));
312   -
313 303 nlohmann::json return_answer;
314 304 return_answer = nlohmann::json::array();
315 305 return_answer[0] = nlohmann::json::object();
... ... @@ -347,17 +337,12 @@ TEST(Bridge, getAllLights)
347 337 .Times(AtLeast(1))
348 338 .WillRepeatedly(Return(hue_bridge_state));
349 339  
350   - EXPECT_CALL(*handler,
351   - GETJson("/api/" + getBridgeUsername() + "/lights/1", nlohmann::json::object(), getBridgeIp(), getBridgePort()))
352   - .Times(AtLeast(1))
353   - .WillRepeatedly(Return(hue_bridge_state["lights"]["1"]));
354   -
355 340 Bridge test_bridge(getBridgeIp(), getBridgePort(), getBridgeUsername(), handler);
356 341  
357   - std::vector<std::reference_wrapper<Light>> test_lights = test_bridge.lights().getAll();
  342 + std::vector<Light> test_lights = test_bridge.lights().getAll();
358 343 ASSERT_EQ(1, test_lights.size());
359   - EXPECT_EQ(test_lights[0].get().getName(), "Hue ambiance lamp 1");
360   - EXPECT_EQ(test_lights[0].get().getColorType(), ColorType::TEMPERATURE);
  344 + EXPECT_EQ(test_lights[0].getName(), "Hue ambiance lamp 1");
  345 + EXPECT_EQ(test_lights[0].getColorType(), ColorType::TEMPERATURE);
361 346 }
362 347  
363 348 TEST(Bridge, lightExists)
... ... @@ -411,10 +396,6 @@ TEST(Bridge, getGroup)
411 396 .Times(1)
412 397 .WillOnce(Return(hue_bridge_state));
413 398  
414   - EXPECT_CALL(*handler,
415   - GETJson("/api/" + getBridgeUsername() + "/groups/1", nlohmann::json::object(), getBridgeIp(), getBridgePort()))
416   - .Times(AtLeast(1))
417   - .WillRepeatedly(Return(hue_bridge_state["groups"]["1"]));
418 399  
419 400 // Refresh cache
420 401 test_bridge = Bridge(getBridgeIp(), getBridgePort(), getBridgeUsername(), handler);
... ... @@ -448,11 +429,6 @@ TEST(Bridge, removeGroup)
448 429  
449 430 Bridge test_bridge(getBridgeIp(), getBridgePort(), getBridgeUsername(), handler);
450 431  
451   - EXPECT_CALL(*handler,
452   - GETJson("/api/" + getBridgeUsername() + "/groups/1", nlohmann::json::object(), getBridgeIp(), getBridgePort()))
453   - .Times(1)
454   - .WillRepeatedly(Return(hue_bridge_state["groups"]["1"]));
455   -
456 432 nlohmann::json return_answer;
457 433 return_answer = nlohmann::json::array();
458 434 return_answer[0] = nlohmann::json::object();
... ... @@ -513,17 +489,12 @@ TEST(Bridge, getAllGroups)
513 489 .Times(AtLeast(1))
514 490 .WillRepeatedly(Return(hue_bridge_state));
515 491  
516   - EXPECT_CALL(*handler,
517   - GETJson("/api/" + getBridgeUsername() + "/groups/1", nlohmann::json::object(), getBridgeIp(), getBridgePort()))
518   - .Times(AtLeast(1))
519   - .WillRepeatedly(Return(hue_bridge_state["groups"]["1"]));
520   -
521 492 Bridge test_bridge(getBridgeIp(), getBridgePort(), getBridgeUsername(), handler);
522 493  
523   - std::vector<std::reference_wrapper<Group>> test_groups = test_bridge.groups().getAll();
  494 + std::vector<Group> test_groups = test_bridge.groups().getAll();
524 495 ASSERT_EQ(1, test_groups.size());
525   - EXPECT_EQ(test_groups[0].get().getName(), "Group 1");
526   - EXPECT_EQ(test_groups[0].get().getType(), "LightGroup");
  496 + EXPECT_EQ(test_groups[0].getName(), "Group 1");
  497 + EXPECT_EQ(test_groups[0].getType(), "LightGroup");
527 498 }
528 499  
529 500 TEST(Bridge, createGroup)
... ...
test/test_BridgeConfig.cpp
... ... @@ -34,7 +34,7 @@ TEST(BridgeConfig, refresh)
34 34 {
35 35 auto handler = std::make_shared<MockHttpHandler>();
36 36 HueCommandAPI commands(getBridgeIp(), getBridgePort(), getBridgeUsername(), handler);
37   - auto baseCache = std::make_shared<APICache>("", commands, std::chrono::steady_clock::duration::max());
  37 + auto baseCache = std::make_shared<APICache>("", commands, std::chrono::steady_clock::duration::max(), nullptr);
38 38 EXPECT_CALL(
39 39 *handler, GETJson("/api/" + getBridgeUsername(), nlohmann::json::object(), getBridgeIp(), getBridgePort()))
40 40 .WillOnce(Return(nlohmann::json::object()));
... ... @@ -59,7 +59,7 @@ TEST(BridgeConfig, getWhitelistedUsers)
59 59 {"create date", "2020-02-01T02:03:40"}}}}}}}};
60 60 auto handler = std::make_shared<MockHttpHandler>();
61 61 HueCommandAPI commands(getBridgeIp(), getBridgePort(), getBridgeUsername(), handler);
62   - auto baseCache = std::make_shared<APICache>("", commands, std::chrono::steady_clock::duration::max());
  62 + auto baseCache = std::make_shared<APICache>("", commands, std::chrono::steady_clock::duration::max(), nullptr);
63 63 EXPECT_CALL(
64 64 *handler, GETJson("/api/" + getBridgeUsername(), nlohmann::json::object(), getBridgeIp(), getBridgePort()))
65 65 .WillOnce(Return(state));
... ... @@ -76,7 +76,7 @@ TEST(BridgeConfig, removeUser)
76 76 {
77 77 auto handler = std::make_shared<MockHttpHandler>();
78 78 HueCommandAPI commands(getBridgeIp(), getBridgePort(), getBridgeUsername(), handler);
79   - auto baseCache = std::make_shared<APICache>("", commands, std::chrono::steady_clock::duration::max());
  79 + auto baseCache = std::make_shared<APICache>("", commands, std::chrono::steady_clock::duration::max(), nullptr);
80 80 EXPECT_CALL(
81 81 *handler, GETJson("/api/" + getBridgeUsername(), nlohmann::json::object(), getBridgeIp(), getBridgePort()))
82 82 .WillOnce(Return(nlohmann::json::object()));
... ... @@ -96,7 +96,7 @@ TEST(BridgeConfig, getLinkButton)
96 96 const nlohmann::json state {{"config", {{"linkbutton", true}}}};
97 97 auto handler = std::make_shared<MockHttpHandler>();
98 98 HueCommandAPI commands(getBridgeIp(), getBridgePort(), getBridgeUsername(), handler);
99   - auto baseCache = std::make_shared<APICache>("", commands, std::chrono::steady_clock::duration::max());
  99 + auto baseCache = std::make_shared<APICache>("", commands, std::chrono::steady_clock::duration::max(), nullptr);
100 100 EXPECT_CALL(
101 101 *handler, GETJson("/api/" + getBridgeUsername(), nlohmann::json::object(), getBridgeIp(), getBridgePort()))
102 102 .WillOnce(Return(state));
... ... @@ -115,7 +115,7 @@ TEST(BridgeConfig, pressLinkButton)
115 115 {
116 116 auto handler = std::make_shared<MockHttpHandler>();
117 117 HueCommandAPI commands(getBridgeIp(), getBridgePort(), getBridgeUsername(), handler);
118   - auto baseCache = std::make_shared<APICache>("", commands, std::chrono::steady_clock::duration::max());
  118 + auto baseCache = std::make_shared<APICache>("", commands, std::chrono::steady_clock::duration::max(), nullptr);
119 119 EXPECT_CALL(
120 120 *handler, GETJson("/api/" + getBridgeUsername(), nlohmann::json::object(), getBridgeIp(), getBridgePort()))
121 121 .WillOnce(Return(nlohmann::json::object()));
... ... @@ -133,7 +133,7 @@ TEST(BridgeConfig, touchLink)
133 133 {
134 134 auto handler = std::make_shared<MockHttpHandler>();
135 135 HueCommandAPI commands(getBridgeIp(), getBridgePort(), getBridgeUsername(), handler);
136   - auto baseCache = std::make_shared<APICache>("", commands, std::chrono::steady_clock::duration::max());
  136 + auto baseCache = std::make_shared<APICache>("", commands, std::chrono::steady_clock::duration::max(), nullptr);
137 137 EXPECT_CALL(
138 138 *handler, GETJson("/api/" + getBridgeUsername(), nlohmann::json::object(), getBridgeIp(), getBridgePort()))
139 139 .WillOnce(Return(nlohmann::json::object()));
... ... @@ -152,7 +152,7 @@ TEST(BridgeConfig, getMACAddress)
152 152 const nlohmann::json state {{"config", {{"mac", getBridgeMac()}}}};
153 153 auto handler = std::make_shared<MockHttpHandler>();
154 154 HueCommandAPI commands(getBridgeIp(), getBridgePort(), getBridgeUsername(), handler);
155   - auto baseCache = std::make_shared<APICache>("", commands, std::chrono::steady_clock::duration::max());
  155 + auto baseCache = std::make_shared<APICache>("", commands, std::chrono::steady_clock::duration::max(), nullptr);
156 156 EXPECT_CALL(
157 157 *handler, GETJson("/api/" + getBridgeUsername(), nlohmann::json::object(), getBridgeIp(), getBridgePort()))
158 158 .WillOnce(Return(state));
... ... @@ -168,7 +168,7 @@ TEST(BridgeConfig, getUTCTime)
168 168 const nlohmann::json state {{"config", {{"UTC", utc}}}};
169 169 auto handler = std::make_shared<MockHttpHandler>();
170 170 HueCommandAPI commands(getBridgeIp(), getBridgePort(), getBridgeUsername(), handler);
171   - auto baseCache = std::make_shared<APICache>("", commands, std::chrono::steady_clock::duration::max());
  171 + auto baseCache = std::make_shared<APICache>("", commands, std::chrono::steady_clock::duration::max(), nullptr);
172 172 EXPECT_CALL(
173 173 *handler, GETJson("/api/" + getBridgeUsername(), nlohmann::json::object(), getBridgeIp(), getBridgePort()))
174 174 .WillOnce(Return(state));
... ... @@ -184,7 +184,7 @@ TEST(BridgeConfig, getTimezone)
184 184 const nlohmann::json state {{"config", {{"timezone", timezone}}}};
185 185 auto handler = std::make_shared<MockHttpHandler>();
186 186 HueCommandAPI commands(getBridgeIp(), getBridgePort(), getBridgeUsername(), handler);
187   - auto baseCache = std::make_shared<APICache>("", commands, std::chrono::steady_clock::duration::max());
  187 + auto baseCache = std::make_shared<APICache>("", commands, std::chrono::steady_clock::duration::max(), nullptr);
188 188 EXPECT_CALL(
189 189 *handler, GETJson("/api/" + getBridgeUsername(), nlohmann::json::object(), getBridgeIp(), getBridgePort()))
190 190 .WillOnce(Return(state));
... ...
test/test_Group.cpp
... ... @@ -78,14 +78,14 @@ TEST_F(GroupTest, Construtor)
78 78 {
79 79 const int id = 12;
80 80 expectGetState(id);
81   - Group group(id, commands, std::chrono::seconds(0));
  81 + Group group(id, commands, std::chrono::seconds(0), nullptr);
82 82 EXPECT_EQ(id, group.getId());
83 83 Mock::VerifyAndClearExpectations(handler.get());
84 84 }
85 85 {
86 86 const int id = 0;
87 87 expectGetState(id);
88   - Group group(id, commands, std::chrono::seconds(0));
  88 + Group group(id, commands, std::chrono::seconds(0), nullptr);
89 89 EXPECT_EQ(id, group.getId());
90 90 Mock::VerifyAndClearExpectations(handler.get());
91 91 }
... ... @@ -95,7 +95,7 @@ TEST_F(GroupTest, getName)
95 95 {
96 96 const int id = 1;
97 97 expectGetState(id);
98   - Group group(id, commands, std::chrono::seconds(0));
  98 + Group group(id, commands, std::chrono::seconds(0), nullptr);
99 99 EXPECT_EQ(groupName, Const(group).getName());
100 100 }
101 101  
... ... @@ -103,7 +103,7 @@ TEST_F(GroupTest, getType)
103 103 {
104 104 const int id = 1;
105 105 expectGetState(id);
106   - Group group(id, commands, std::chrono::seconds(0));
  106 + Group group(id, commands, std::chrono::seconds(0), nullptr);
107 107 EXPECT_EQ(type, Const(group).getType());
108 108 }
109 109  
... ... @@ -111,7 +111,7 @@ TEST_F(GroupTest, getLightIds)
111 111 {
112 112 const int id = 1;
113 113 expectGetState(id);
114   - Group group(id, commands, std::chrono::seconds(0));
  114 + Group group(id, commands, std::chrono::seconds(0), nullptr);
115 115 EXPECT_EQ(std::vector<int>({1, 2, 4}), Const(group).getLightIds());
116 116 }
117 117  
... ... @@ -119,7 +119,7 @@ TEST_F(GroupTest, getRoomType)
119 119 {
120 120 const int id = 1;
121 121 expectGetState(id);
122   - Group group(id, commands, std::chrono::seconds(0));
  122 + Group group(id, commands, std::chrono::seconds(0), nullptr);
123 123 EXPECT_EQ(roomType, Const(group).getRoomType());
124 124 }
125 125  
... ... @@ -127,7 +127,7 @@ TEST_F(GroupTest, getAllOn)
127 127 {
128 128 const int id = 1;
129 129 expectGetState(id);
130   - Group group(id, commands, std::chrono::steady_clock::duration::max());
  130 + Group group(id, commands, std::chrono::steady_clock::duration::max(), nullptr);
131 131 EXPECT_EQ(all_on, group.getAllOn());
132 132 EXPECT_EQ(all_on, Const(group).getAllOn());
133 133 }
... ... @@ -136,7 +136,7 @@ TEST_F(GroupTest, getAnyOn)
136 136 {
137 137 const int id = 1;
138 138 expectGetState(id);
139   - Group group(id, commands, std::chrono::steady_clock::duration::max());
  139 + Group group(id, commands, std::chrono::steady_clock::duration::max(), nullptr);
140 140 EXPECT_EQ(any_on, group.getAnyOn());
141 141 EXPECT_EQ(any_on, Const(group).getAnyOn());
142 142 }
... ... @@ -145,7 +145,7 @@ TEST_F(GroupTest, getActionOn)
145 145 {
146 146 const int id = 1;
147 147 expectGetState(id);
148   - Group group(id, commands, std::chrono::steady_clock::duration::max());
  148 + Group group(id, commands, std::chrono::steady_clock::duration::max(), nullptr);
149 149 EXPECT_EQ(on, group.getActionOn());
150 150 EXPECT_EQ(on, Const(group).getActionOn());
151 151 }
... ... @@ -154,7 +154,7 @@ TEST_F(GroupTest, getActionHueSaturation)
154 154 {
155 155 const int id = 1;
156 156 expectGetState(id);
157   - Group group(id, commands, std::chrono::steady_clock::duration::max());
  157 + Group group(id, commands, std::chrono::steady_clock::duration::max(), nullptr);
158 158 std::pair<uint16_t, uint8_t> hueSat {hue, sat};
159 159 EXPECT_EQ(hueSat, group.getActionHueSaturation());
160 160 EXPECT_EQ(hueSat, Const(group).getActionHueSaturation());
... ... @@ -164,7 +164,7 @@ TEST_F(GroupTest, getActionBrightness)
164 164 {
165 165 const int id = 1;
166 166 expectGetState(id);
167   - Group group(id, commands, std::chrono::steady_clock::duration::max());
  167 + Group group(id, commands, std::chrono::steady_clock::duration::max(), nullptr);
168 168 EXPECT_EQ(bri, group.getActionBrightness());
169 169 EXPECT_EQ(bri, Const(group).getActionBrightness());
170 170 }
... ... @@ -173,7 +173,7 @@ TEST_F(GroupTest, getActionColorTemperature)
173 173 {
174 174 const int id = 1;
175 175 expectGetState(id);
176   - Group group(id, commands, std::chrono::steady_clock::duration::max());
  176 + Group group(id, commands, std::chrono::steady_clock::duration::max(), nullptr);
177 177 EXPECT_EQ(ct, group.getActionColorTemperature());
178 178 EXPECT_EQ(ct, Const(group).getActionColorTemperature());
179 179 }
... ... @@ -182,7 +182,7 @@ TEST_F(GroupTest, getActionColorXY)
182 182 {
183 183 const int id = 1;
184 184 expectGetState(id);
185   - Group group(id, commands, std::chrono::steady_clock::duration::max());
  185 + Group group(id, commands, std::chrono::steady_clock::duration::max(), nullptr);
186 186 std::pair<float, float> xy {x, y};
187 187 EXPECT_EQ(xy, group.getActionColorXY());
188 188 EXPECT_EQ(xy, Const(group).getActionColorXY());
... ... @@ -192,7 +192,7 @@ TEST_F(GroupTest, getActionColorMode)
192 192 {
193 193 const int id = 1;
194 194 expectGetState(id);
195   - Group group(id, commands, std::chrono::steady_clock::duration::max());
  195 + Group group(id, commands, std::chrono::steady_clock::duration::max(), nullptr);
196 196 EXPECT_EQ(colormode, group.getActionColorMode());
197 197 EXPECT_EQ(colormode, Const(group).getActionColorMode());
198 198 }
... ... @@ -201,7 +201,7 @@ TEST_F(GroupTest, setName)
201 201 {
202 202 const int id = 1;
203 203 expectGetState(id);
204   - Group group(id, commands, std::chrono::steady_clock::duration::max());
  204 + Group group(id, commands, std::chrono::steady_clock::duration::max(), nullptr);
205 205 const std::string name = "Test group";
206 206 nlohmann::json request = {{"name", name}};
207 207 nlohmann::json response = {{"success", {"/groups/1/name", name}}};
... ... @@ -215,7 +215,7 @@ TEST_F(GroupTest, setLights)
215 215 {
216 216 const int id = 1;
217 217 expectGetState(id);
218   - Group group(id, commands, std::chrono::steady_clock::duration::max());
  218 + Group group(id, commands, std::chrono::steady_clock::duration::max(), nullptr);
219 219 const nlohmann::json lights = {"2", "4", "5"};
220 220 nlohmann::json request = {{"lights", lights}};
221 221 nlohmann::json response = {{"success", {"/groups/1/lights", lights}}};
... ... @@ -229,7 +229,7 @@ TEST_F(GroupTest, setRoomType)
229 229 {
230 230 const int id = 1;
231 231 expectGetState(id);
232   - Group group(id, commands, std::chrono::steady_clock::duration::max());
  232 + Group group(id, commands, std::chrono::steady_clock::duration::max(), nullptr);
233 233 const std::string type = "LivingRoom";
234 234 nlohmann::json request = {{"class", type}};
235 235 nlohmann::json response = {{"success", {"/groups/1/class", type}}};
... ... @@ -243,7 +243,7 @@ TEST_F(GroupTest, setScene)
243 243 {
244 244 const int id = 1;
245 245 expectGetState(id);
246   - Group group(id, commands, std::chrono::steady_clock::duration::max());
  246 + Group group(id, commands, std::chrono::steady_clock::duration::max(), nullptr);
247 247 const std::string scene = "testScene";
248 248 nlohmann::json request = {{"scene", scene}};
249 249 nlohmann::json response = {{"success", {"/groups/1/action/scene", scene}}};
... ... @@ -257,7 +257,7 @@ TEST_F(GroupTest, createSceneAction)
257 257 {
258 258 const int id = 1;
259 259 expectGetState(id);
260   - const Group group(id, commands, std::chrono::steady_clock::duration::max());
  260 + const Group group(id, commands, std::chrono::steady_clock::duration::max(), nullptr);
261 261 const std::string scene = "testScene";
262 262 nlohmann::json request = { {"scene", scene} };
263 263 hueplusplus::Action command = group.createSceneAction(scene);
... ...
test/test_Light.cpp
... ... @@ -75,18 +75,6 @@ protected:
75 75 EXPECT_CALL(*handler, GETJson("/api/" + getBridgeUsername(), nlohmann::json::object(), getBridgeIp(), 80))
76 76 .Times(AtLeast(1))
77 77 .WillRepeatedly(Return(hue_bridge_state));
78   - EXPECT_CALL(
79   - *handler, GETJson("/api/" + getBridgeUsername() + "/lights/1", nlohmann::json::object(), getBridgeIp(), 80))
80   - .Times(AtLeast(1))
81   - .WillRepeatedly(Return(hue_bridge_state["lights"]["1"]));
82   - EXPECT_CALL(
83   - *handler, GETJson("/api/" + getBridgeUsername() + "/lights/2", nlohmann::json::object(), getBridgeIp(), 80))
84   - .Times(AtLeast(1))
85   - .WillRepeatedly(Return(hue_bridge_state["lights"]["2"]));
86   - EXPECT_CALL(
87   - *handler, GETJson("/api/" + getBridgeUsername() + "/lights/3", nlohmann::json::object(), getBridgeIp(), 80))
88   - .Times(AtLeast(1))
89   - .WillRepeatedly(Return(hue_bridge_state["lights"]["3"]));
90 78 }
91 79 ~HueLightTest() {};
92 80 };
... ...
test/test_LightFactory.cpp
... ... @@ -44,31 +44,16 @@ TEST(LightFactory, createLight_noGamut)
44 44 {"name", "Hue ambiance lamp 1"}, {"modelid", "LTW001"}, {"manufacturername", "Philips"},
45 45 {"uniqueid", "00:00:00:00:00:00:00:00-00"}, {"swversion", "5.50.1.19085"}};
46 46  
47   - EXPECT_CALL(*handler,
48   - GETJson("/api/" + getBridgeUsername() + "/lights/1", nlohmann::json::object(), getBridgeIp(), getBridgePort()))
49   - .Times(AtLeast(1))
50   - .WillRepeatedly(Return(lightState));
51   -
52 47 Light test_light_1 = factory.createLight(lightState, 1);
53 48 EXPECT_EQ(test_light_1.getColorType(), ColorType::TEMPERATURE);
54 49  
55 50 lightState["type"] = "Dimmable light";
56 51  
57   - EXPECT_CALL(*handler,
58   - GETJson("/api/" + getBridgeUsername() + "/lights/1", nlohmann::json::object(), getBridgeIp(), getBridgePort()))
59   - .Times(AtLeast(1))
60   - .WillRepeatedly(Return(lightState));
61   -
62 52 test_light_1 = factory.createLight(lightState, 1);
63 53 EXPECT_EQ(test_light_1.getColorType(), ColorType::NONE);
64 54  
65 55 lightState["type"] = "On/Off light";
66 56  
67   - EXPECT_CALL(*handler,
68   - GETJson("/api/" + getBridgeUsername() + "/lights/1", nlohmann::json::object(), getBridgeIp(), getBridgePort()))
69   - .Times(AtLeast(1))
70   - .WillRepeatedly(Return(lightState));
71   -
72 57 test_light_1 = factory.createLight(lightState, 1);
73 58 EXPECT_EQ(test_light_1.getColorType(), ColorType::NONE);
74 59  
... ... @@ -92,69 +77,37 @@ TEST(LightFactory, createLight_gamutCapabilities)
92 77 {"uniqueid", "00:00:00:00:00:00:00:00-00"}, {"swversion", "5.50.1.19085"},
93 78 {"capabilities", {{"control", {{"colorgamuttype", "A"}}}}} };
94 79  
95   - EXPECT_CALL(*handler,
96   - GETJson("/api/" + getBridgeUsername() + "/lights/1", nlohmann::json::object(), getBridgeIp(), getBridgePort()))
97   - .Times(AtLeast(1))
98   - .WillRepeatedly(Return(lightState));
99   -
100 80 Light test_light_1 = factory.createLight(lightState, 1);
101 81 EXPECT_EQ(test_light_1.getColorType(), ColorType::GAMUT_A);
102 82  
103 83 lightState["capabilities"]["control"]["colorgamuttype"] = "B";
104 84  
105   - EXPECT_CALL(*handler,
106   - GETJson("/api/" + getBridgeUsername() + "/lights/1", nlohmann::json::object(), getBridgeIp(), getBridgePort()))
107   - .Times(AtLeast(1))
108   - .WillRepeatedly(Return(lightState));
109   -
110 85 test_light_1 = factory.createLight(lightState, 1);
111 86 EXPECT_EQ(test_light_1.getColorType(), ColorType::GAMUT_B);
112 87  
113 88 lightState["capabilities"]["control"]["colorgamuttype"] = "C";
114 89  
115   - EXPECT_CALL(*handler,
116   - GETJson("/api/" + getBridgeUsername() + "/lights/1", nlohmann::json::object(), getBridgeIp(), getBridgePort()))
117   - .Times(AtLeast(1))
118   - .WillRepeatedly(Return(lightState));
119   -
120 90 test_light_1 = factory.createLight(lightState, 1);
121 91 EXPECT_EQ(test_light_1.getColorType(), ColorType::GAMUT_C);
122 92  
123 93 lightState["capabilities"]["control"]["colorgamuttype"] = "Other";
124 94  
125   - EXPECT_CALL(*handler,
126   - GETJson("/api/" + getBridgeUsername() + "/lights/1", nlohmann::json::object(), getBridgeIp(), getBridgePort()))
127   - .Times(AtLeast(1))
128   - .WillRepeatedly(Return(lightState));
129   -
130 95 test_light_1 = factory.createLight(lightState, 1);
131 96 EXPECT_EQ(test_light_1.getColorType(), ColorType::UNDEFINED);
132 97  
133 98 // With color temperature
134 99 lightState["type"] = "Extended color light";
135 100 lightState["capabilities"]["control"]["colorgamuttype"] = "A";
136   - EXPECT_CALL(*handler,
137   - GETJson("/api/" + getBridgeUsername() + "/lights/1", nlohmann::json::object(), getBridgeIp(), getBridgePort()))
138   - .Times(AtLeast(1))
139   - .WillRepeatedly(Return(lightState));
140 101  
141 102 test_light_1 = factory.createLight(lightState, 1);
142 103 EXPECT_EQ(test_light_1.getColorType(), ColorType::GAMUT_A_TEMPERATURE);
143 104  
144 105 lightState["capabilities"]["control"]["colorgamuttype"] = "B";
145   - EXPECT_CALL(*handler,
146   - GETJson("/api/" + getBridgeUsername() + "/lights/1", nlohmann::json::object(), getBridgeIp(), getBridgePort()))
147   - .Times(AtLeast(1))
148   - .WillRepeatedly(Return(lightState));
149 106  
150 107 test_light_1 = factory.createLight(lightState, 1);
151 108 EXPECT_EQ(test_light_1.getColorType(), ColorType::GAMUT_B_TEMPERATURE);
152 109  
153 110 lightState["capabilities"]["control"]["colorgamuttype"] = "C";
154   - EXPECT_CALL(*handler,
155   - GETJson("/api/" + getBridgeUsername() + "/lights/1", nlohmann::json::object(), getBridgeIp(), getBridgePort()))
156   - .Times(AtLeast(1))
157   - .WillRepeatedly(Return(lightState));
158 111  
159 112 test_light_1 = factory.createLight(lightState, 1);
160 113 EXPECT_EQ(test_light_1.getColorType(), ColorType::GAMUT_C_TEMPERATURE);
... ... @@ -179,30 +132,15 @@ TEST(LightFactory, createLight_gamutModelid)
179 132 {"name", "Hue ambiance lamp 1"}, {"modelid", gamutAModel}, {"manufacturername", "Philips"},
180 133 {"uniqueid", "00:00:00:00:00:00:00:00-00"}, {"swversion", "5.50.1.19085"}};
181 134  
182   - EXPECT_CALL(*handler,
183   - GETJson("/api/" + getBridgeUsername() + "/lights/1", nlohmann::json::object(), getBridgeIp(), getBridgePort()))
184   - .Times(AtLeast(1))
185   - .WillRepeatedly(Return(lightState));
186   -
187 135 Light test_light_1 = factory.createLight(lightState, 1);
188 136 EXPECT_EQ(test_light_1.getColorType(), ColorType::GAMUT_A);
189 137  
190 138 lightState["modelid"] = gamutBModel;
191   - EXPECT_CALL(*handler,
192   - GETJson("/api/" + getBridgeUsername() + "/lights/1", nlohmann::json::object(), getBridgeIp(), getBridgePort()))
193   - .Times(AtLeast(1))
194   - .WillRepeatedly(Return(lightState));
195   -
196 139 test_light_1 = factory.createLight(lightState, 1);
197 140 EXPECT_EQ(test_light_1.getColorType(), ColorType::GAMUT_B);
198 141  
199 142 lightState["modelid"] = gamutCModel;
200 143  
201   - EXPECT_CALL(*handler,
202   - GETJson("/api/" + getBridgeUsername() + "/lights/1", nlohmann::json::object(), getBridgeIp(), getBridgePort()))
203   - .Times(AtLeast(1))
204   - .WillRepeatedly(Return(lightState));
205   -
206 144 test_light_1 = factory.createLight(lightState, 1);
207 145 EXPECT_EQ(test_light_1.getColorType(), ColorType::GAMUT_C);
208 146  
... ... @@ -210,30 +148,16 @@ TEST(LightFactory, createLight_gamutModelid)
210 148 lightState["type"] = "Extended color light";
211 149 lightState["modelid"] = gamutAModel;
212 150  
213   - EXPECT_CALL(*handler,
214   - GETJson("/api/" + getBridgeUsername() + "/lights/1", nlohmann::json::object(), getBridgeIp(), getBridgePort()))
215   - .Times(AtLeast(1))
216   - .WillRepeatedly(Return(lightState));
217   -
218 151 test_light_1 = factory.createLight(lightState, 1);
219 152 EXPECT_EQ(test_light_1.getColorType(), ColorType::GAMUT_A_TEMPERATURE);
220 153  
221 154 lightState["modelid"] = gamutBModel;
222   - EXPECT_CALL(*handler,
223   - GETJson("/api/" + getBridgeUsername() + "/lights/1", nlohmann::json::object(), getBridgeIp(), getBridgePort()))
224   - .Times(AtLeast(1))
225   - .WillRepeatedly(Return(lightState));
226 155  
227 156 test_light_1 = factory.createLight(lightState, 1);
228 157 EXPECT_EQ(test_light_1.getColorType(), ColorType::GAMUT_B_TEMPERATURE);
229 158  
230 159 lightState["modelid"] = gamutCModel;
231 160  
232   - EXPECT_CALL(*handler,
233   - GETJson("/api/" + getBridgeUsername() + "/lights/1", nlohmann::json::object(), getBridgeIp(), getBridgePort()))
234   - .Times(AtLeast(1))
235   - .WillRepeatedly(Return(lightState));
236   -
237 161 test_light_1 = factory.createLight(lightState, 1);
238 162 EXPECT_EQ(test_light_1.getColorType(), ColorType::GAMUT_C_TEMPERATURE);
239 163  
... ...
test/test_ResourceList.cpp
... ... @@ -33,7 +33,7 @@ class TestResource
33 33 {
34 34 public:
35 35 TestResource(int id, std::shared_ptr<APICache> baseCache) {}
36   - TestResource(int id, HueCommandAPI api, std::chrono::steady_clock::duration refreshDuration) : id(id) { }
  36 + TestResource(int id, HueCommandAPI api, std::chrono::steady_clock::duration refreshDuration, const nlohmann::json& currentState) : id(id) { }
37 37  
38 38 void refresh(bool force = false) { }
39 39  
... ... @@ -49,7 +49,7 @@ class TestStringResource
49 49 {
50 50 public:
51 51 TestStringResource(const std::string& id, std::shared_ptr<APICache> baseCache) {}
52   - TestStringResource(const std::string& id, HueCommandAPI api, std::chrono::steady_clock::duration refreshDuration)
  52 + TestStringResource(const std::string& id, HueCommandAPI api, std::chrono::steady_clock::duration refreshDuration, const nlohmann::json& currentState)
53 53 : id(id)
54 54 { }
55 55 void refresh(bool force = false) { }
... ... @@ -81,7 +81,7 @@ TEST(ResourceList, refresh)
81 81 Mock::VerifyAndClearExpectations(handler.get());
82 82 }
83 83 {
84   - auto baseCache = std::make_shared<APICache>("", commands, std::chrono::steady_clock::duration::max());
  84 + auto baseCache = std::make_shared<APICache>("", commands, std::chrono::steady_clock::duration::max(), nullptr);
85 85 ResourceList<TestResource, int> list(baseCache, "resources", std::chrono::steady_clock::duration::max());
86 86 InSequence s;
87 87 EXPECT_CALL(
... ... @@ -113,9 +113,9 @@ TEST(ResourceList, get)
113 113 GETJson("/api/" + getBridgeUsername() + path, nlohmann::json::object(), getBridgeIp(), getBridgePort()))
114 114 .WillOnce(Return(response));
115 115  
116   - TestResource& r = list.get(id);
  116 + TestResource r = list.get(id);
117 117 EXPECT_EQ(id, r.id);
118   - TestResource& r2 = list.get(id);
  118 + TestResource r2 = list.get(id);
119 119 EXPECT_EQ(id, r2.id);
120 120 }
121 121 // With factory
... ... @@ -126,7 +126,7 @@ TEST(ResourceList, get)
126 126  
127 127 MockFunction<TestResource(int, const nlohmann::json&, const std::shared_ptr<APICache>&)> factory;
128 128 EXPECT_CALL(factory, Call(id, state, std::shared_ptr<APICache>()))
129   - .WillOnce(Return(TestResource(id, commands, std::chrono::steady_clock::duration::max())));
  129 + .WillOnce(Return(TestResource(id, commands, std::chrono::steady_clock::duration::max(), nullptr)));
130 130  
131 131 ResourceList<TestResource, int> list(
132 132 commands, path, std::chrono::steady_clock::duration::max(), factory.AsStdFunction());
... ... @@ -134,7 +134,7 @@ TEST(ResourceList, get)
134 134 GETJson("/api/" + getBridgeUsername() + path, nlohmann::json::object(), getBridgeIp(), getBridgePort()))
135 135 .WillOnce(Return(response));
136 136  
137   - TestResource& r = list.get(id);
  137 + TestResource r = list.get(id);
138 138 EXPECT_EQ(id, r.id);
139 139 }
140 140 // String id without factory
... ... @@ -146,9 +146,9 @@ TEST(ResourceList, get)
146 146 GETJson("/api/" + getBridgeUsername() + path, nlohmann::json::object(), getBridgeIp(), getBridgePort()))
147 147 .WillOnce(Return(response));
148 148  
149   - TestStringResource& r = list.get(id);
  149 + TestStringResource r = list.get(id);
150 150 EXPECT_EQ(id, r.id);
151   - TestStringResource& r2 = list.get(id);
  151 + TestStringResource r2 = list.get(id);
152 152 EXPECT_EQ(id, r2.id);
153 153 }
154 154  
... ...
test/test_Rule.cpp
... ... @@ -99,7 +99,7 @@ protected:
99 99 Rule getRule(int id = 1)
100 100 {
101 101 expectGetState(id);
102   - return Rule(id, commands, std::chrono::steady_clock::duration::max());
  102 + return Rule(id, commands, std::chrono::steady_clock::duration::max(), nullptr);
103 103 }
104 104 };
105 105  
... ...
test/test_Scene.cpp
... ... @@ -156,7 +156,7 @@ TEST_F(SceneTest, Constructor)
156 156 {
157 157 const std::string id = "asd89263";
158 158 expectGetState(id);
159   - const Scene scene(id, commands, std::chrono::seconds(0));
  159 + const Scene scene(id, commands, std::chrono::seconds(0), nullptr);
160 160 EXPECT_EQ(id, scene.getId());
161 161 }
162 162  
... ... @@ -166,7 +166,7 @@ TEST_F(SceneTest, getName)
166 166 const std::string name = "Scene name";
167 167 sceneState["name"] = name;
168 168 expectGetState(id);
169   - const Scene scene(id, commands, std::chrono::seconds(0));
  169 + const Scene scene(id, commands, std::chrono::seconds(0), nullptr);
170 170 EXPECT_EQ(name, scene.getName());
171 171 }
172 172  
... ... @@ -176,13 +176,13 @@ TEST_F(SceneTest, getType)
176 176 {
177 177 sceneState["type"] = "GroupScene";
178 178 expectGetState(id);
179   - const Scene scene(id, commands, std::chrono::seconds(0));
  179 + const Scene scene(id, commands, std::chrono::seconds(0), nullptr);
180 180 EXPECT_EQ(Scene::Type::groupScene, scene.getType());
181 181 }
182 182 {
183 183 sceneState["type"] = "LightScene";
184 184 expectGetState(id);
185   - const Scene scene(id, commands, std::chrono::seconds(0));
  185 + const Scene scene(id, commands, std::chrono::seconds(0), nullptr);
186 186 EXPECT_EQ(Scene::Type::lightScene, scene.getType());
187 187 }
188 188 }
... ... @@ -193,14 +193,14 @@ TEST_F(SceneTest, getGroupId)
193 193 {
194 194 sceneState["group"] = "3";
195 195 expectGetState(id);
196   - const Scene scene(id, commands, std::chrono::seconds(0));
  196 + const Scene scene(id, commands, std::chrono::seconds(0), nullptr);
197 197 EXPECT_EQ(3, scene.getGroupId());
198 198 }
199 199 {
200 200 sceneState["type"] = "LightScene";
201 201 sceneState.erase("group");
202 202 expectGetState(id);
203   - const Scene scene(id, commands, std::chrono::seconds(0));
  203 + const Scene scene(id, commands, std::chrono::seconds(0), nullptr);
204 204 EXPECT_EQ(0, scene.getGroupId());
205 205 }
206 206 }
... ... @@ -210,7 +210,7 @@ TEST_F(SceneTest, getLightIds)
210 210 const std::string id = "125asav3";
211 211 sceneState["lights"] = {"3", "4", "5"};
212 212 expectGetState(id);
213   - const Scene scene(id, commands, std::chrono::seconds(0));
  213 + const Scene scene(id, commands, std::chrono::seconds(0), nullptr);
214 214 EXPECT_THAT(scene.getLightIds(), UnorderedElementsAre(3, 4, 5));
215 215 }
216 216  
... ... @@ -220,7 +220,7 @@ TEST_F(SceneTest, getOwner)
220 220 const std::string owner = "testowner";
221 221 sceneState["owner"] = owner;
222 222 expectGetState(id);
223   - const Scene scene(id, commands, std::chrono::seconds(0));
  223 + const Scene scene(id, commands, std::chrono::seconds(0), nullptr);
224 224 EXPECT_EQ(owner, scene.getOwner());
225 225 }
226 226  
... ... @@ -230,7 +230,7 @@ TEST_F(SceneTest, getRecycle)
230 230 const bool recycle = true;
231 231 sceneState["recycle"] = recycle;
232 232 expectGetState(id);
233   - const Scene scene(id, commands, std::chrono::seconds(0));
  233 + const Scene scene(id, commands, std::chrono::seconds(0), nullptr);
234 234 EXPECT_EQ(recycle, scene.getRecycle());
235 235 }
236 236  
... ... @@ -240,7 +240,7 @@ TEST_F(SceneTest, isLocked)
240 240 const bool locked = true;
241 241 sceneState["locked"] = locked;
242 242 expectGetState(id);
243   - const Scene scene(id, commands, std::chrono::seconds(0));
  243 + const Scene scene(id, commands, std::chrono::seconds(0), nullptr);
244 244 EXPECT_EQ(locked, scene.isLocked());
245 245 }
246 246  
... ... @@ -251,7 +251,7 @@ TEST_F(SceneTest, getAppdata)
251 251 const int version = 10;
252 252 sceneState["appdata"] = {{"version", version}, {"data", appdata}};
253 253 expectGetState(id);
254   - const Scene scene(id, commands, std::chrono::seconds(0));
  254 + const Scene scene(id, commands, std::chrono::seconds(0), nullptr);
255 255 EXPECT_EQ(version, scene.getAppdataVersion());
256 256 EXPECT_EQ(appdata, scene.getAppdata());
257 257 }
... ... @@ -262,7 +262,7 @@ TEST_F(SceneTest, getPicture)
262 262 const std::string picture = "abcpicture";
263 263 sceneState["picture"] = picture;
264 264 expectGetState(id);
265   - const Scene scene(id, commands, std::chrono::seconds(0));
  265 + const Scene scene(id, commands, std::chrono::seconds(0), nullptr);
266 266 EXPECT_EQ(picture, scene.getPicture());
267 267 }
268 268  
... ... @@ -270,7 +270,7 @@ TEST_F(SceneTest, getLastUpdated)
270 270 {
271 271 const std::string id = "125asav3";
272 272 expectGetState(id);
273   - const Scene scene(id, commands, std::chrono::seconds(0));
  273 + const Scene scene(id, commands, std::chrono::seconds(0), nullptr);
274 274 const time::AbsoluteTime lastUpdated = scene.getLastUpdated();
275 275 EXPECT_EQ(time::parseUTCTimestamp("2020-04-23T12:00:04"), lastUpdated.getBaseTime());
276 276 }
... ... @@ -281,7 +281,7 @@ TEST_F(SceneTest, getVersion)
281 281 const int version = 2;
282 282 sceneState["version"] = version;
283 283 expectGetState(id);
284   - const Scene scene(id, commands, std::chrono::seconds(0));
  284 + const Scene scene(id, commands, std::chrono::seconds(0), nullptr);
285 285 EXPECT_EQ(version, scene.getVersion());
286 286 }
287 287  
... ... @@ -300,7 +300,7 @@ TEST_F(SceneTest, getLightstates)
300 300 }
301 301 sceneState["lightstates"] = lightstatesJson;
302 302 expectGetState(id);
303   - const Scene scene(id, commands, std::chrono::seconds(0));
  303 + const Scene scene(id, commands, std::chrono::seconds(0), nullptr);
304 304 const std::map<int, LightState> result = scene.getLightStates();
305 305 EXPECT_EQ(lightstates, result);
306 306 }
... ... @@ -308,7 +308,7 @@ TEST_F(SceneTest, getLightstates)
308 308 {
309 309 sceneState.erase("lightstates");
310 310 expectGetState(id);
311   - const Scene scene(id, commands, std::chrono::seconds(0));
  311 + const Scene scene(id, commands, std::chrono::seconds(0), nullptr);
312 312 EXPECT_TRUE(scene.getLightStates().empty());
313 313 }
314 314 }
... ... @@ -317,7 +317,7 @@ TEST_F(SceneTest, refresh)
317 317 {
318 318 const std::string id = "125asav3";
319 319 expectGetState(id);
320   - Scene scene(id, commands, std::chrono::seconds(0));
  320 + Scene scene(id, commands, std::chrono::seconds(0), nullptr);
321 321 expectGetState(id);
322 322 scene.refresh(true);
323 323 }
... ... @@ -326,7 +326,7 @@ TEST_F(SceneTest, setName)
326 326 {
327 327 const std::string id = "125asav3";
328 328 expectGetState(id);
329   - Scene scene(id, commands, std::chrono::seconds(0));
  329 + Scene scene(id, commands, std::chrono::seconds(0), nullptr);
330 330 const std::string name = "Scene name";
331 331 nlohmann::json request = {{"name", name}};
332 332 nlohmann::json response = {{"success", {"/scenes/" + id + "/name", name}}};
... ... @@ -341,7 +341,7 @@ TEST_F(SceneTest, setLightIds)
341 341 {
342 342 const std::string id = "125asav3";
343 343 expectGetState(id);
344   - Scene scene(id, commands, std::chrono::seconds(0));
  344 + Scene scene(id, commands, std::chrono::seconds(0), nullptr);
345 345 const std::vector<int> lightIds = {3, 4, 6, 8};
346 346 nlohmann::json request = {{"lights", {"3", "4", "6", "8"}}};
347 347 nlohmann::json response = {{"success", {"/scenes/" + id + "/lights", {"3", "4", "6", "8"}}}};
... ... @@ -356,7 +356,7 @@ TEST_F(SceneTest, setAppdata)
356 356 {
357 357 const std::string id = "125asav3";
358 358 expectGetState(id);
359   - Scene scene(id, commands, std::chrono::seconds(0));
  359 + Scene scene(id, commands, std::chrono::seconds(0), nullptr);
360 360 const std::string appdata = "New appdata";
361 361 const int version = 3;
362 362 nlohmann::json request = {{"appdata", {{"version", version}, {"data", appdata}}}};
... ... @@ -381,7 +381,7 @@ TEST_F(SceneTest, setLightStates)
381 381 lightstatesJson[std::to_string(entry.first)] = entry.second.toJson();
382 382 }
383 383 expectGetState(id);
384   - Scene scene(id, commands, std::chrono::seconds(0));
  384 + Scene scene(id, commands, std::chrono::seconds(0), nullptr);
385 385 nlohmann::json request = {{"lightstates", lightstatesJson}};
386 386 nlohmann::json response = {{"success", {"/scenes/" + id + "/lights/3/state/on", false}},
387 387 {"success", {"/scenes/" + id + "/lights/3/state/bri", 100}},
... ... @@ -400,7 +400,7 @@ TEST_F(SceneTest, storeCurrentLightState)
400 400 {
401 401 const std::string id = "125asav3";
402 402 expectGetState(id);
403   - Scene scene(id, commands, std::chrono::seconds(0));
  403 + Scene scene(id, commands, std::chrono::seconds(0), nullptr);
404 404 {
405 405 nlohmann::json request = {{"storelightstate", true}};
406 406 nlohmann::json response = {{"success", {"/scenes/" + id + "/storelightstate", true}}};
... ... @@ -431,7 +431,7 @@ TEST_F(SceneTest, recall)
431 431 expectGetState(id);
432 432 nlohmann::json request = {{"scene", id}};
433 433 nlohmann::json response = {{"success", {"/groups/0/action/scene", id}}};
434   - Scene scene(id, commands, std::chrono::seconds(0));
  434 + Scene scene(id, commands, std::chrono::seconds(0), nullptr);
435 435 EXPECT_CALL(*handler,
436 436 PUTJson("/api/" + getBridgeUsername() + "/groups/0/action", request, getBridgeIp(), getBridgePort()))
437 437 .WillOnce(Return(response));
... ... @@ -446,7 +446,7 @@ TEST_F(SceneTest, recall)
446 446 expectGetState(id);
447 447 nlohmann::json request = {{"scene", id}};
448 448 nlohmann::json response = {{"success", {"/groups/" + groupId + "/action/scene", id}}};
449   - Scene scene(id, commands, std::chrono::seconds(0));
  449 + Scene scene(id, commands, std::chrono::seconds(0), nullptr);
450 450 EXPECT_CALL(*handler,
451 451 PUTJson("/api/" + getBridgeUsername() + "/groups/" + groupId + "/action", request, getBridgeIp(),
452 452 getBridgePort()))
... ...
test/test_Schedule.cpp
... ... @@ -59,14 +59,14 @@ TEST_F(ScheduleTest, Constructor)
59 59 {
60 60 const int id = 13;
61 61 expectGetState(id);
62   - const Schedule schedule(id, commands, std::chrono::seconds(0));
  62 + const Schedule schedule(id, commands, std::chrono::seconds(0), nullptr);
63 63 EXPECT_EQ(id, schedule.getId());
64 64 Mock::VerifyAndClearExpectations(handler.get());
65 65 }
66 66 {
67 67 const int id = 0;
68 68 expectGetState(id);
69   - const Schedule schedule(id, commands, std::chrono::seconds(0));
  69 + const Schedule schedule(id, commands, std::chrono::seconds(0), nullptr);
70 70 EXPECT_EQ(id, schedule.getId());
71 71 Mock::VerifyAndClearExpectations(handler.get());
72 72 }
... ... @@ -78,7 +78,7 @@ TEST_F(ScheduleTest, getName)
78 78 const std::string name = "Schedule name";
79 79 scheduleState["name"] = name;
80 80 expectGetState(id);
81   - const Schedule schedule(id, commands, std::chrono::seconds(0));
  81 + const Schedule schedule(id, commands, std::chrono::seconds(0), nullptr);
82 82 EXPECT_EQ(name, schedule.getName());
83 83 }
84 84  
... ... @@ -88,7 +88,7 @@ TEST_F(ScheduleTest, getDescription)
88 88 const std::string description = "Schedule description";
89 89 scheduleState["description"] = description;
90 90 expectGetState(id);
91   - const Schedule schedule(id, commands, std::chrono::seconds(0));
  91 + const Schedule schedule(id, commands, std::chrono::seconds(0), nullptr);
92 92 EXPECT_EQ(description, schedule.getDescription());
93 93 }
94 94  
... ... @@ -99,7 +99,7 @@ TEST_F(ScheduleTest, getCommand)
99 99 const nlohmann::json body = {{"test", "value"}};
100 100 scheduleState["command"] = {{"address", addr}, {"body", body}, {"method", "PUT"}};
101 101 expectGetState(id);
102   - const Schedule schedule(id, commands, std::chrono::seconds(0));
  102 + const Schedule schedule(id, commands, std::chrono::seconds(0), nullptr);
103 103 hueplusplus::Action command = schedule.getCommand();
104 104 EXPECT_EQ(addr, command.getAddress());
105 105 EXPECT_EQ(body, command.getBody());
... ... @@ -112,7 +112,7 @@ TEST_F(ScheduleTest, getTime)
112 112 const std::string time = "T13:00:00/T14:00:00";
113 113 scheduleState["localtime"] = time;
114 114 expectGetState(id);
115   - const Schedule schedule(id, commands, std::chrono::seconds(0));
  115 + const Schedule schedule(id, commands, std::chrono::seconds(0), nullptr);
116 116 time::TimePattern pattern = schedule.getTime();
117 117 EXPECT_EQ(time, pattern.toString());
118 118 }
... ... @@ -123,13 +123,13 @@ TEST_F(ScheduleTest, getStatus)
123 123 {
124 124 scheduleState["status"] = "enabled";
125 125 expectGetState(id);
126   - const Schedule schedule(id, commands, std::chrono::seconds(0));
  126 + const Schedule schedule(id, commands, std::chrono::seconds(0), nullptr);
127 127 EXPECT_EQ(true, schedule.isEnabled());
128 128 }
129 129 {
130 130 scheduleState["status"] = "disabled";
131 131 expectGetState(id);
132   - const Schedule schedule(id, commands, std::chrono::seconds(0));
  132 + const Schedule schedule(id, commands, std::chrono::seconds(0), nullptr);
133 133 EXPECT_EQ(false, schedule.isEnabled());
134 134 }
135 135 }
... ... @@ -140,7 +140,7 @@ TEST_F(ScheduleTest, getAutodelete)
140 140 const bool autodelete = true;
141 141 scheduleState["autodelete"] = autodelete;
142 142 expectGetState(id);
143   - const Schedule schedule(id, commands, std::chrono::seconds(0));
  143 + const Schedule schedule(id, commands, std::chrono::seconds(0), nullptr);
144 144 EXPECT_EQ(autodelete, schedule.getAutodelete());
145 145 }
146 146  
... ... @@ -150,7 +150,7 @@ TEST_F(ScheduleTest, getCreated)
150 150 const std::string created = "2020-03-03T08:20:53";
151 151 scheduleState["created"] = created;
152 152 expectGetState(id);
153   - const Schedule schedule(id, commands, std::chrono::seconds(0));
  153 + const Schedule schedule(id, commands, std::chrono::seconds(0), nullptr);
154 154 EXPECT_EQ(created, schedule.getCreated().toString());
155 155 }
156 156  
... ... @@ -160,7 +160,7 @@ TEST_F(ScheduleTest, getStartTime)
160 160 const std::string starttime = "2020-03-03T08:20:53";
161 161 scheduleState["starttime"] = starttime;
162 162 expectGetState(id);
163   - const Schedule schedule(id, commands, std::chrono::seconds(0));
  163 + const Schedule schedule(id, commands, std::chrono::seconds(0), nullptr);
164 164 EXPECT_EQ(starttime, schedule.getStartTime().toString());
165 165 }
166 166  
... ... @@ -168,7 +168,7 @@ TEST_F(ScheduleTest, setName)
168 168 {
169 169 const int id = 1;
170 170 expectGetState(id);
171   - Schedule schedule(id, commands, std::chrono::steady_clock::duration::max());
  171 + Schedule schedule(id, commands, std::chrono::steady_clock::duration::max(), nullptr);
172 172 const std::string name = "Test schedule";
173 173 nlohmann::json request = {{"name", name}};
174 174 nlohmann::json response = {{"success", {"/schedules/1/name", name}}};
... ... @@ -183,7 +183,7 @@ TEST_F(ScheduleTest, setDescription)
183 183 {
184 184 const int id = 1;
185 185 expectGetState(id);
186   - Schedule schedule(id, commands, std::chrono::steady_clock::duration::max());
  186 + Schedule schedule(id, commands, std::chrono::steady_clock::duration::max(), nullptr);
187 187 const std::string description = "Test schedule description";
188 188 nlohmann::json request = {{"description", description}};
189 189 nlohmann::json response = {{"success", {"/schedules/1/description", description}}};
... ... @@ -198,7 +198,7 @@ TEST_F(ScheduleTest, setCommand)
198 198 {
199 199 const int id = 1;
200 200 expectGetState(id);
201   - Schedule schedule(id, commands, std::chrono::steady_clock::duration::max());
  201 + Schedule schedule(id, commands, std::chrono::steady_clock::duration::max(), nullptr);
202 202 const hueplusplus::Action command({{"address", "abcd"}, {"body", {}}, {"method", "PUT"}});
203 203 nlohmann::json request = {{"command", command.toJson()}};
204 204 nlohmann::json response = {{"success", {"/schedules/1/command", command.toJson()}}};
... ... @@ -213,7 +213,7 @@ TEST_F(ScheduleTest, setTime)
213 213 {
214 214 const int id = 1;
215 215 expectGetState(id);
216   - Schedule schedule(id, commands, std::chrono::steady_clock::duration::max());
  216 + Schedule schedule(id, commands, std::chrono::steady_clock::duration::max(), nullptr);
217 217 time::TimePattern time {time::AbsoluteVariedTime(std::chrono::system_clock::now())};
218 218 nlohmann::json request = {{"localtime", time.toString()}};
219 219 nlohmann::json response = {{"success", {"/schedules/1/localtime", time.toString()}}};
... ... @@ -228,7 +228,7 @@ TEST_F(ScheduleTest, setStatus)
228 228 {
229 229 const int id = 1;
230 230 expectGetState(id);
231   - Schedule schedule(id, commands, std::chrono::steady_clock::duration::max());
  231 + Schedule schedule(id, commands, std::chrono::steady_clock::duration::max(), nullptr);
232 232 {
233 233 nlohmann::json request = {{"status", "enabled"}};
234 234 nlohmann::json response = {{"success", {"/schedules/1/status", "enabled"}}};
... ... @@ -253,7 +253,7 @@ TEST_F(ScheduleTest, setAutodelete)
253 253 {
254 254 const int id = 1;
255 255 expectGetState(id);
256   - Schedule schedule(id, commands, std::chrono::steady_clock::duration::max());
  256 + Schedule schedule(id, commands, std::chrono::steady_clock::duration::max(), nullptr);
257 257 const bool autodelete = false;
258 258 nlohmann::json request = {{"autodelete", autodelete}};
259 259 nlohmann::json response = {{"success", {"/schedules/1/autodelete", autodelete}}};
... ...
test/test_Sensor.cpp
... ... @@ -53,7 +53,7 @@ protected:
53 53 GETJson(
54 54 "/api/" + getBridgeUsername() + "/sensors/" + std::to_string(id), _, getBridgeIp(), getBridgePort()))
55 55 .WillOnce(Return(state));
56   - return Sensor(id, commands, std::chrono::steady_clock::duration::max());
  56 + return Sensor(id, commands, std::chrono::steady_clock::duration::max(), nullptr);
57 57 }
58 58 };
59 59  
... ...
test/test_SensorImpls.cpp
... ... @@ -68,7 +68,7 @@ protected:
68 68 {
69 69 EXPECT_CALL(*handler, GETJson("/api/" + getBridgeUsername() + "/sensors/1", _, getBridgeIp(), getBridgePort()))
70 70 .WillOnce(Return(state));
71   - return T(Sensor(1, commands, std::chrono::steady_clock::duration::max()));
  71 + return T(Sensor(1, commands, std::chrono::steady_clock::duration::max(), nullptr));
72 72 }
73 73 };
74 74  
... ...
test/test_SensorList.cpp
... ... @@ -50,11 +50,6 @@ TEST(SensorList, getAsType)
50 50 EXPECT_CALL(*handler,
51 51 GETJson("/api/" + getBridgeUsername() + "/sensors", nlohmann::json::object(), getBridgeIp(), getBridgePort()))
52 52 .WillOnce(Return(response));
53   - EXPECT_CALL(*handler,
54   - GETJson("/api/" + getBridgeUsername() + "/sensors/" + std::to_string(id), nlohmann::json::object(),
55   - getBridgeIp(), getBridgePort()))
56   - .Times(2)
57   - .WillRepeatedly(Return(nlohmann::json {{"type", "Daylight"}}));
58 53  
59 54 sensors::DaylightSensor daylightSensor = sensors.getAsType<sensors::DaylightSensor>(id);
60 55 EXPECT_THROW(sensors.getAsType<BlaSensor>(2), HueException);
... ... @@ -96,14 +91,6 @@ TEST(SensorList, getAllByType)
96 91 GETJson(
97 92 "/api/" + getBridgeUsername() + "/sensors", nlohmann::json::object(), getBridgeIp(), getBridgePort()))
98 93 .WillOnce(Return(response));
99   - EXPECT_CALL(*handler,
100   - GETJson(
101   - "/api/" + getBridgeUsername() + "/sensors/2", nlohmann::json::object(), getBridgeIp(), getBridgePort()))
102   - .WillOnce(Return(response["2"]));
103   - EXPECT_CALL(*handler,
104   - GETJson(
105   - "/api/" + getBridgeUsername() + "/sensors/4", nlohmann::json::object(), getBridgeIp(), getBridgePort()))
106   - .WillOnce(Return(response["4"]));
107 94 sensors.refresh();
108 95 std::vector<sensors::DaylightSensor> result = sensors.getAllByType<sensors::DaylightSensor>();
109 96 EXPECT_THAT(result,
... ...