Switch to use ComponentManager for traits/components
Removed the old StateManager, CommandManager and related classes
and switched over to using ComponentManager for all device trait and
component definitions as well as device state.
Change-Id: I99b99a935ba217703d31aa523a3124cca0fa3e90
Reviewed-on: https://weave-review.googlesource.com/1788
Reviewed-by: Alex Vakulenko <avakulenko@google.com>
diff --git a/src/states/error_codes.cc b/src/states/error_codes.cc
deleted file mode 100644
index 4b12a45..0000000
--- a/src/states/error_codes.cc
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright 2015 The Weave Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "src/states/error_codes.h"
-
-namespace weave {
-namespace errors {
-namespace state {
-
-const char kDomain[] = "buffet_state";
-
-const char kPackageNameMissing[] = "package_name_missing";
-const char kPropertyNameMissing[] = "property_name_missing";
-const char kPropertyNotDefined[] = "property_not_defined";
-const char kPropertyRedefinition[] = "property_redefinition";
-
-} // namespace state
-} // namespace errors
-} // namespace weave
diff --git a/src/states/error_codes.h b/src/states/error_codes.h
deleted file mode 100644
index 676a199..0000000
--- a/src/states/error_codes.h
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright 2015 The Weave Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef LIBWEAVE_SRC_STATES_ERROR_CODES_H_
-#define LIBWEAVE_SRC_STATES_ERROR_CODES_H_
-
-namespace weave {
-namespace errors {
-namespace state {
-
-// Error domain for state definitions.
-extern const char kDomain[];
-
-// State-specific error codes.
-extern const char kPackageNameMissing[];
-extern const char kPropertyNameMissing[];
-extern const char kPropertyNotDefined[];
-extern const char kPropertyRedefinition[];
-
-} // namespace state
-} // namespace errors
-} // namespace weave
-
-#endif // LIBWEAVE_SRC_STATES_ERROR_CODES_H_
diff --git a/src/states/mock_state_change_queue_interface.h b/src/states/mock_state_change_queue_interface.h
deleted file mode 100644
index fc119cd..0000000
--- a/src/states/mock_state_change_queue_interface.h
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright 2015 The Weave Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef LIBWEAVE_SRC_STATES_MOCK_STATE_CHANGE_QUEUE_INTERFACE_H_
-#define LIBWEAVE_SRC_STATES_MOCK_STATE_CHANGE_QUEUE_INTERFACE_H_
-
-#include <vector>
-
-#include <gmock/gmock.h>
-
-#include "src/states/state_change_queue_interface.h"
-
-namespace weave {
-
-class MockStateChangeQueueInterface : public StateChangeQueueInterface {
- public:
- MOCK_CONST_METHOD0(IsEmpty, bool());
- MOCK_METHOD2(NotifyPropertiesUpdated,
- bool(base::Time timestamp,
- const base::DictionaryValue& changed_properties));
- MOCK_METHOD0(MockGetAndClearRecordedStateChanges,
- std::vector<StateChange>&());
- MOCK_CONST_METHOD0(GetLastStateChangeId, UpdateID());
- MOCK_METHOD1(MockAddOnStateUpdatedCallback,
- base::CallbackList<void(UpdateID)>::Subscription*(
- const base::Callback<void(UpdateID)>&));
- MOCK_METHOD1(NotifyStateUpdatedOnServer, void(UpdateID));
-
- private:
- std::vector<StateChange> GetAndClearRecordedStateChanges() override {
- return std::move(MockGetAndClearRecordedStateChanges());
- }
-
- Token AddOnStateUpdatedCallback(
- const base::Callback<void(UpdateID)>& callback) override {
- return Token{MockAddOnStateUpdatedCallback(callback)};
- }
-};
-
-} // namespace weave
-
-#endif // LIBWEAVE_SRC_STATES_MOCK_STATE_CHANGE_QUEUE_INTERFACE_H_
diff --git a/src/states/state_change_queue.cc b/src/states/state_change_queue.cc
index b6c67cd..effe7f3 100644
--- a/src/states/state_change_queue.cc
+++ b/src/states/state_change_queue.cc
@@ -5,7 +5,6 @@
#include "src/states/state_change_queue.h"
#include <base/logging.h>
-#include <base/values.h>
namespace weave {
@@ -38,7 +37,6 @@
std::swap(element_old->second, element_new->second);
state_changes_.erase(element_old);
}
- ++last_change_id_;
return true;
}
@@ -52,15 +50,4 @@
return changes;
}
-StateChangeQueueInterface::Token StateChangeQueue::AddOnStateUpdatedCallback(
- const base::Callback<void(UpdateID)>& callback) {
- if (state_changes_.empty())
- callback.Run(last_change_id_);
- return Token{callbacks_.Add(callback).release()};
-}
-
-void StateChangeQueue::NotifyStateUpdatedOnServer(UpdateID update_id) {
- callbacks_.Notify(update_id);
-}
-
} // namespace weave
diff --git a/src/states/state_change_queue.h b/src/states/state_change_queue.h
index 857ec8b..3aef8d5 100644
--- a/src/states/state_change_queue.h
+++ b/src/states/state_change_queue.h
@@ -6,29 +6,36 @@
#define LIBWEAVE_SRC_STATES_STATE_CHANGE_QUEUE_H_
#include <map>
+#include <memory>
#include <vector>
#include <base/macros.h>
-
-#include "src/states/state_change_queue_interface.h"
+#include <base/time/time.h>
+#include <base/values.h>
namespace weave {
+// A simple notification record event to track device state changes.
+// The |timestamp| records the time of the state change.
+// |changed_properties| contains a property set with the new property values
+// which were updated at the time the event was recorded.
+struct StateChange {
+ StateChange(base::Time time,
+ std::unique_ptr<base::DictionaryValue> properties)
+ : timestamp{time}, changed_properties{std::move(properties)} {}
+ base::Time timestamp;
+ std::unique_ptr<base::DictionaryValue> changed_properties;
+};
+
// An object to record and retrieve device state change notification events.
-class StateChangeQueue : public StateChangeQueueInterface {
+class StateChangeQueue {
public:
explicit StateChangeQueue(size_t max_queue_size);
- // Overrides from StateChangeQueueInterface.
- bool IsEmpty() const override { return state_changes_.empty(); }
bool NotifyPropertiesUpdated(
base::Time timestamp,
- const base::DictionaryValue& changed_properties) override;
- std::vector<StateChange> GetAndClearRecordedStateChanges() override;
- UpdateID GetLastStateChangeId() const override { return last_change_id_; }
- Token AddOnStateUpdatedCallback(
- const base::Callback<void(UpdateID)>& callback) override;
- void NotifyStateUpdatedOnServer(UpdateID update_id) override;
+ const base::DictionaryValue& changed_properties);
+ std::vector<StateChange> GetAndClearRecordedStateChanges();
private:
// Maximum queue size. If it is full, the oldest state update records are
@@ -38,13 +45,6 @@
// Accumulated list of device state change notifications.
std::map<base::Time, std::unique_ptr<base::DictionaryValue>> state_changes_;
- // An ID of last state change update. Each NotifyPropertiesUpdated()
- // invocation increments this value by 1.
- UpdateID last_change_id_{0};
-
- // Callback list for state change queue even sinks.
- base::CallbackList<void(UpdateID)> callbacks_;
-
DISALLOW_COPY_AND_ASSIGN(StateChangeQueue);
};
diff --git a/src/states/state_change_queue_interface.h b/src/states/state_change_queue_interface.h
deleted file mode 100644
index 7ddce8c..0000000
--- a/src/states/state_change_queue_interface.h
+++ /dev/null
@@ -1,71 +0,0 @@
-// Copyright 2015 The Weave Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef LIBWEAVE_SRC_STATES_STATE_CHANGE_QUEUE_INTERFACE_H_
-#define LIBWEAVE_SRC_STATES_STATE_CHANGE_QUEUE_INTERFACE_H_
-
-#include <vector>
-
-#include <base/callback_list.h>
-#include <base/time/time.h>
-
-namespace base {
-class DictionaryValue;
-} // namespace base
-
-namespace weave {
-
-// A simple notification record event to track device state changes.
-// The |timestamp| records the time of the state change.
-// |changed_properties| contains a property set with the new property values
-// which were updated at the time the event was recorded.
-struct StateChange {
- StateChange(base::Time time,
- std::unique_ptr<base::DictionaryValue> properties)
- : timestamp{time}, changed_properties{std::move(properties)} {}
- base::Time timestamp;
- std::unique_ptr<base::DictionaryValue> changed_properties;
-};
-
-// An abstract interface to StateChangeQueue to record and retrieve state
-// change notification events.
-class StateChangeQueueInterface {
- public:
- using UpdateID = uint64_t;
- using Token =
- std::unique_ptr<base::CallbackList<void(UpdateID)>::Subscription>;
-
- // Returns true if the state change notification queue is empty.
- virtual bool IsEmpty() const = 0;
-
- // Called by StateManager when device state properties are updated.
- virtual bool NotifyPropertiesUpdated(
- base::Time timestamp,
- const base::DictionaryValue& changed_properties) = 0;
-
- // Returns the recorded state changes since last time this method was called.
- virtual std::vector<StateChange> GetAndClearRecordedStateChanges() = 0;
-
- // Returns an ID of last state change update. Each NotifyPropertiesUpdated()
- // invocation increments this value by 1.
- virtual UpdateID GetLastStateChangeId() const = 0;
-
- // Subscribes for device state update notifications from cloud server.
- // The |callback| will be called every time a state patch with given ID is
- // successfully received and processed by GCD server.
- // Returns a subscription token. As soon as this token is destroyed, the
- // respective callback is removed from the callback list.
- virtual Token AddOnStateUpdatedCallback(
- const base::Callback<void(UpdateID)>& callback) WARN_UNUSED_RESULT = 0;
-
- virtual void NotifyStateUpdatedOnServer(UpdateID update_id) = 0;
-
- protected:
- // No one should attempt do destroy the queue through the interface.
- virtual ~StateChangeQueueInterface() {}
-};
-
-} // namespace weave
-
-#endif // LIBWEAVE_SRC_STATES_STATE_CHANGE_QUEUE_INTERFACE_H_
diff --git a/src/states/state_change_queue_unittest.cc b/src/states/state_change_queue_unittest.cc
index b639d37..57cf490 100644
--- a/src/states/state_change_queue_unittest.cc
+++ b/src/states/state_change_queue_unittest.cc
@@ -23,8 +23,6 @@
};
TEST_F(StateChangeQueueTest, Empty) {
- EXPECT_TRUE(queue_->IsEmpty());
- EXPECT_EQ(0u, queue_->GetLastStateChangeId());
EXPECT_TRUE(queue_->GetAndClearRecordedStateChanges().empty());
}
@@ -32,14 +30,10 @@
auto timestamp = base::Time::Now();
ASSERT_TRUE(queue_->NotifyPropertiesUpdated(
timestamp, *CreateDictionaryValue("{'prop': {'name': 23}}")));
- EXPECT_FALSE(queue_->IsEmpty());
- EXPECT_EQ(1u, queue_->GetLastStateChangeId());
auto changes = queue_->GetAndClearRecordedStateChanges();
- EXPECT_EQ(1u, queue_->GetLastStateChangeId());
ASSERT_EQ(1u, changes.size());
EXPECT_EQ(timestamp, changes.front().timestamp);
EXPECT_JSON_EQ("{'prop':{'name': 23}}", *changes.front().changed_properties);
- EXPECT_TRUE(queue_->IsEmpty());
EXPECT_TRUE(queue_->GetAndClearRecordedStateChanges().empty());
}
@@ -54,15 +48,12 @@
ASSERT_TRUE(queue_->NotifyPropertiesUpdated(
timestamp2, *CreateDictionaryValue(state2)));
- EXPECT_EQ(2u, queue_->GetLastStateChangeId());
- EXPECT_FALSE(queue_->IsEmpty());
auto changes = queue_->GetAndClearRecordedStateChanges();
ASSERT_EQ(2u, changes.size());
EXPECT_EQ(timestamp1, changes[0].timestamp);
EXPECT_JSON_EQ(state1, *changes[0].changed_properties);
EXPECT_EQ(timestamp2, changes[1].timestamp);
EXPECT_JSON_EQ(state2, *changes[1].changed_properties);
- EXPECT_TRUE(queue_->IsEmpty());
EXPECT_TRUE(queue_->GetAndClearRecordedStateChanges().empty());
}
@@ -84,7 +75,6 @@
*CreateDictionaryValue("{'prop': {'name1': 4}}")));
auto changes = queue_->GetAndClearRecordedStateChanges();
- EXPECT_EQ(4u, queue_->GetLastStateChangeId());
ASSERT_EQ(2u, changes.size());
const std::string expected1 = "{'prop': {'name1': 3, 'name2': 2}}";
@@ -113,7 +103,6 @@
start_time + time_delta2,
*CreateDictionaryValue("{'prop': {'name10': 10, 'name11': 11}}")));
- EXPECT_EQ(3u, queue_->GetLastStateChangeId());
auto changes = queue_->GetAndClearRecordedStateChanges();
ASSERT_EQ(2u, changes.size());
@@ -128,26 +117,4 @@
EXPECT_JSON_EQ(expected2, *changes[1].changed_properties);
}
-TEST_F(StateChangeQueueTest, ImmediateStateChangeNotification) {
- // When queue is empty, registering a new callback will trigger it.
- bool called = false;
- auto callback = [&called](StateChangeQueueInterface::UpdateID id) {
- called = true;
- };
- queue_->AddOnStateUpdatedCallback(base::Bind(callback));
- EXPECT_TRUE(called);
-}
-
-TEST_F(StateChangeQueueTest, DelayedStateChangeNotification) {
- // When queue is not empty, registering a new callback will not trigger it.
- ASSERT_TRUE(queue_->NotifyPropertiesUpdated(
- base::Time::Now(),
- *CreateDictionaryValue("{'prop': {'name1': 1, 'name3': 2}}")));
-
- auto callback = [](StateChangeQueueInterface::UpdateID id) {
- FAIL() << "This should not be called";
- };
- queue_->AddOnStateUpdatedCallback(base::Bind(callback));
-}
-
} // namespace weave
diff --git a/src/states/state_manager.cc b/src/states/state_manager.cc
deleted file mode 100644
index 128f7d8..0000000
--- a/src/states/state_manager.cc
+++ /dev/null
@@ -1,232 +0,0 @@
-// Copyright 2015 The Weave Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "src/states/state_manager.h"
-
-#include <base/logging.h>
-#include <base/values.h>
-
-#include "src/json_error_codes.h"
-#include "src/states/error_codes.h"
-#include "src/states/state_change_queue_interface.h"
-#include "src/string_utils.h"
-#include "src/utils.h"
-
-namespace weave {
-
-StateManager::StateManager(StateChangeQueueInterface* state_change_queue)
- : state_change_queue_(state_change_queue) {
- CHECK(state_change_queue_) << "State change queue not specified";
-}
-
-StateManager::~StateManager() {}
-
-void StateManager::AddChangedCallback(const base::Closure& callback) {
- on_changed_.push_back(callback);
- callback.Run(); // Force to read current state.
-}
-
-const base::DictionaryValue& StateManager::GetState() const {
- if (!cached_dict_valid_) {
- cached_dict_.Clear();
- for (const auto& pair : packages_) {
- cached_dict_.SetWithoutPathExpansion(
- pair.first, pair.second->GetValuesAsJson().DeepCopy());
- }
- cached_dict_valid_ = true;
- }
-
- return cached_dict_;
-}
-
-bool StateManager::SetProperty(const std::string& name,
- const base::Value& value,
- ErrorPtr* error) {
- bool result = SetPropertyValue(name, value, base::Time::Now(), error);
- for (const auto& cb : on_changed_)
- cb.Run();
- return result;
-}
-
-const base::Value* StateManager::GetProperty(const std::string& name) const {
- auto parts = SplitAtFirst(name, ".", true);
- const std::string& package_name = parts.first;
- const std::string& property_name = parts.second;
- if (package_name.empty() || property_name.empty())
- return nullptr;
-
- const StatePackage* package = FindPackage(package_name);
- if (!package)
- return nullptr;
-
- return package->GetPropertyValue(property_name, nullptr);
-}
-
-bool StateManager::SetPropertyValue(const std::string& full_property_name,
- const base::Value& value,
- const base::Time& timestamp,
- ErrorPtr* error) {
- auto parts = SplitAtFirst(full_property_name, ".", true);
- const std::string& package_name = parts.first;
- const std::string& property_name = parts.second;
- const bool split = (full_property_name.find(".") != std::string::npos);
-
- if (full_property_name.empty() || (split && property_name.empty())) {
- Error::AddTo(error, FROM_HERE, errors::state::kDomain,
- errors::state::kPropertyNameMissing,
- "Property name is missing");
- return false;
- }
- if (!split || package_name.empty()) {
- Error::AddTo(error, FROM_HERE, errors::state::kDomain,
- errors::state::kPackageNameMissing,
- "Package name is missing in the property name");
- return false;
- }
- StatePackage* package = FindPackage(package_name);
- if (package == nullptr) {
- Error::AddToPrintf(error, FROM_HERE, errors::state::kDomain,
- errors::state::kPropertyNotDefined,
- "Unknown state property package '%s'",
- package_name.c_str());
- return false;
- }
- if (!package->SetPropertyValue(property_name, value, error))
- return false;
-
- cached_dict_valid_ = false;
-
- base::DictionaryValue prop_set;
- prop_set.Set(full_property_name, value.DeepCopy());
- state_change_queue_->NotifyPropertiesUpdated(timestamp, prop_set);
- return true;
-}
-
-std::pair<StateChangeQueueInterface::UpdateID, std::vector<StateChange>>
-StateManager::GetAndClearRecordedStateChanges() {
- return std::make_pair(state_change_queue_->GetLastStateChangeId(),
- state_change_queue_->GetAndClearRecordedStateChanges());
-}
-
-void StateManager::NotifyStateUpdatedOnServer(
- StateChangeQueueInterface::UpdateID id) {
- state_change_queue_->NotifyStateUpdatedOnServer(id);
-}
-
-bool StateManager::LoadStateDefinition(const base::DictionaryValue& dict,
- ErrorPtr* error) {
- for (base::DictionaryValue::Iterator iter(dict); !iter.IsAtEnd();
- iter.Advance()) {
- std::string package_name = iter.key();
- if (package_name.empty()) {
- Error::AddTo(error, FROM_HERE, errors::kErrorDomain,
- errors::kInvalidPackageError, "State package name is empty");
- return false;
- }
- const base::DictionaryValue* package_dict = nullptr;
- if (!iter.value().GetAsDictionary(&package_dict)) {
- Error::AddToPrintf(error, FROM_HERE, errors::json::kDomain,
- errors::json::kObjectExpected,
- "State package '%s' must be an object",
- package_name.c_str());
- return false;
- }
- StatePackage* package = FindOrCreatePackage(package_name);
- CHECK(package) << "Unable to create state package " << package_name;
- if (!package->AddSchemaFromJson(package_dict, error))
- return false;
- }
-
- return true;
-}
-
-bool StateManager::LoadStateDefinitionFromJson(const std::string& json,
- ErrorPtr* error) {
- std::unique_ptr<const base::DictionaryValue> dict = LoadJsonDict(json, error);
- if (!dict)
- return false;
- if (!LoadStateDefinition(*dict, error)) {
- Error::AddToPrintf(error, FROM_HERE, errors::kErrorDomain,
- errors::kSchemaError,
- "Failed to load state definition: '%s'", json.c_str());
- return false;
- }
- return true;
-}
-
-bool StateManager::SetProperties(const base::DictionaryValue& dict,
- ErrorPtr* error) {
- base::Time timestamp = base::Time::Now();
- bool all_success = true;
- for (base::DictionaryValue::Iterator iter(dict); !iter.IsAtEnd();
- iter.Advance()) {
- if (iter.key().empty()) {
- Error::AddTo(error, FROM_HERE, errors::kErrorDomain,
- errors::kInvalidPackageError, "State package name is empty");
- all_success = false;
- continue;
- }
-
- const base::DictionaryValue* package_dict = nullptr;
- if (!iter.value().GetAsDictionary(&package_dict)) {
- Error::AddToPrintf(error, FROM_HERE, errors::json::kDomain,
- errors::json::kObjectExpected,
- "State package '%s' must be an object",
- iter.key().c_str());
- all_success = false;
- continue;
- }
-
- for (base::DictionaryValue::Iterator it_prop(*package_dict);
- !it_prop.IsAtEnd(); it_prop.Advance()) {
- if (!SetPropertyValue(iter.key() + "." + it_prop.key(), it_prop.value(),
- timestamp, error)) {
- all_success = false;
- continue;
- }
- }
- }
- for (const auto& cb : on_changed_)
- cb.Run();
- return all_success;
-}
-
-bool StateManager::SetPropertiesFromJson(const std::string& json,
- ErrorPtr* error) {
- std::unique_ptr<const base::DictionaryValue> dict = LoadJsonDict(json, error);
- if (!dict)
- return false;
- if (!SetProperties(*dict, error)) {
- Error::AddToPrintf(error, FROM_HERE, errors::kErrorDomain,
- errors::kSchemaError, "Failed to load defaults: '%s'",
- json.c_str());
- return false;
- }
- return true;
-}
-
-StatePackage* StateManager::FindPackage(const std::string& package_name) {
- auto it = packages_.find(package_name);
- return (it != packages_.end()) ? it->second.get() : nullptr;
-}
-
-const StatePackage* StateManager::FindPackage(
- const std::string& package_name) const {
- auto it = packages_.find(package_name);
- return (it != packages_.end()) ? it->second.get() : nullptr;
-}
-
-StatePackage* StateManager::FindOrCreatePackage(
- const std::string& package_name) {
- StatePackage* package = FindPackage(package_name);
- if (package == nullptr) {
- std::unique_ptr<StatePackage> new_package{new StatePackage(package_name)};
- package =
- packages_.insert(std::make_pair(package_name, std::move(new_package)))
- .first->second.get();
- }
- return package;
-}
-
-} // namespace weave
diff --git a/src/states/state_manager.h b/src/states/state_manager.h
deleted file mode 100644
index bd1eb92..0000000
--- a/src/states/state_manager.h
+++ /dev/null
@@ -1,95 +0,0 @@
-// Copyright 2015 The Weave Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef LIBWEAVE_SRC_STATES_STATE_MANAGER_H_
-#define LIBWEAVE_SRC_STATES_STATE_MANAGER_H_
-
-#include <map>
-#include <memory>
-#include <set>
-#include <string>
-#include <utility>
-#include <vector>
-
-#include <base/callback.h>
-#include <base/macros.h>
-#include <weave/error.h>
-
-#include "src/states/state_change_queue_interface.h"
-#include "src/states/state_package.h"
-
-namespace base {
-class DictionaryValue;
-class Time;
-} // namespace base
-
-namespace weave {
-
-// StateManager is the class that aggregates the device state fragments
-// provided by device daemons and makes the aggregate device state available
-// to the GCD cloud server and local clients.
-class StateManager final {
- public:
- explicit StateManager(StateChangeQueueInterface* state_change_queue);
- ~StateManager();
-
- void AddChangedCallback(const base::Closure& callback);
- bool LoadStateDefinition(const base::DictionaryValue& dict, ErrorPtr* error);
- bool LoadStateDefinitionFromJson(const std::string& json, ErrorPtr* error);
- bool SetProperties(const base::DictionaryValue& dict, ErrorPtr* error);
- bool SetPropertiesFromJson(const std::string& json, ErrorPtr* error);
- const base::Value* GetProperty(const std::string& name) const;
- bool SetProperty(const std::string& name,
- const base::Value& value,
- ErrorPtr* error);
- const base::DictionaryValue& GetState() const;
-
- // Returns the recorded state changes since last time this method has been
- // called.
- std::pair<StateChangeQueueInterface::UpdateID, std::vector<StateChange>>
- GetAndClearRecordedStateChanges();
-
- // Called to notify that the state patch with |id| has been successfully sent
- // to the server and processed.
- void NotifyStateUpdatedOnServer(StateChangeQueueInterface::UpdateID id);
-
- StateChangeQueueInterface* GetStateChangeQueue() const {
- return state_change_queue_;
- }
-
- const std::map<std::string, std::unique_ptr<StatePackage>>& packages() const {
- return packages_;
- }
-
- private:
- friend class BaseApiHandlerTest;
- friend class StateManagerTest;
-
- // Updates a single property value. |full_property_name| must be the full
- // name of the property to update in format "package.property".
- bool SetPropertyValue(const std::string& full_property_name,
- const base::Value& value,
- const base::Time& timestamp,
- ErrorPtr* error);
-
- // Finds a package by its name. Returns nullptr if not found.
- StatePackage* FindPackage(const std::string& package_name);
- const StatePackage* FindPackage(const std::string& package_name) const;
- // Finds a package by its name. If none exists, one will be created.
- StatePackage* FindOrCreatePackage(const std::string& package_name);
-
- StateChangeQueueInterface* state_change_queue_; // Owned by Manager.
- std::map<std::string, std::unique_ptr<StatePackage>> packages_;
-
- std::vector<base::Closure> on_changed_;
-
- mutable base::DictionaryValue cached_dict_;
- mutable bool cached_dict_valid_ = false;
-
- DISALLOW_COPY_AND_ASSIGN(StateManager);
-};
-
-} // namespace weave
-
-#endif // LIBWEAVE_SRC_STATES_STATE_MANAGER_H_
diff --git a/src/states/state_manager_unittest.cc b/src/states/state_manager_unittest.cc
deleted file mode 100644
index 918fb89..0000000
--- a/src/states/state_manager_unittest.cc
+++ /dev/null
@@ -1,272 +0,0 @@
-// Copyright 2015 The Weave Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "src/states/state_manager.h"
-
-#include <cstdlib> // for abs().
-#include <vector>
-
-#include <base/bind.h>
-#include <base/values.h>
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-#include <weave/provider/test/mock_config_store.h>
-#include <weave/test/unittest_utils.h>
-
-#include "src/commands/schema_constants.h"
-#include "src/states/error_codes.h"
-#include "src/states/mock_state_change_queue_interface.h"
-
-namespace weave {
-
-using testing::_;
-using testing::Return;
-using testing::ReturnRef;
-using test::CreateDictionaryValue;
-
-namespace {
-
-const char kBaseDefinition[] = R"({
- "base": {
- "manufacturer":{"type":"string"},
- "serialNumber":{"type":"string"}
- },
- "device": {
- "state_property":{"type":"string"}
- }
-})";
-
-std::unique_ptr<base::DictionaryValue> GetTestSchema() {
- return CreateDictionaryValue(kBaseDefinition);
-}
-
-const char kBaseDefaults[] = R"({
- "base": {
- "manufacturer":"Test Factory",
- "serialNumber":"Test Model"
- }
-})";
-
-std::unique_ptr<base::DictionaryValue> GetTestValues() {
- return CreateDictionaryValue(kBaseDefaults);
-}
-
-MATCHER_P(IsState, str, "") {
- return arg.Equals(CreateDictionaryValue(str).get());
-}
-
-} // anonymous namespace
-
-class StateManagerTest : public ::testing::Test {
- public:
- void SetUp() override {
- // Initial expectations.
- EXPECT_CALL(mock_state_change_queue_, IsEmpty()).Times(0);
- EXPECT_CALL(mock_state_change_queue_, NotifyPropertiesUpdated(_, _))
- .WillRepeatedly(Return(true));
- EXPECT_CALL(mock_state_change_queue_, MockGetAndClearRecordedStateChanges())
- .Times(0);
- mgr_.reset(new StateManager(&mock_state_change_queue_));
-
- EXPECT_CALL(*this, OnStateChanged()).Times(2);
- mgr_->AddChangedCallback(
- base::Bind(&StateManagerTest::OnStateChanged, base::Unretained(this)));
-
- LoadStateDefinition(GetTestSchema().get(), nullptr);
- ASSERT_TRUE(mgr_->SetProperties(*GetTestValues().get(), nullptr));
- }
- void TearDown() override { mgr_.reset(); }
-
- void LoadStateDefinition(const base::DictionaryValue* json,
- ErrorPtr* error) {
- ASSERT_TRUE(mgr_->LoadStateDefinition(*json, error));
- }
-
- bool SetPropertyValue(const std::string& name,
- const base::Value& value,
- ErrorPtr* error) {
- return mgr_->SetPropertyValue(name, value, timestamp_, error);
- }
-
- MOCK_CONST_METHOD0(OnStateChanged, void());
-
- base::Time timestamp_{base::Time::Now()};
- std::unique_ptr<StateManager> mgr_;
- testing::StrictMock<MockStateChangeQueueInterface> mock_state_change_queue_;
-};
-
-TEST(StateManager, Empty) {
- testing::StrictMock<MockStateChangeQueueInterface> mock_state_change_queue;
- StateManager manager(&mock_state_change_queue);
-}
-
-TEST_F(StateManagerTest, Initialized) {
- auto expected = R"({
- 'base': {
- 'manufacturer': 'Test Factory',
- 'serialNumber': 'Test Model'
- },
- 'device': {}
- })";
- EXPECT_JSON_EQ(expected, mgr_->GetState());
-}
-
-TEST_F(StateManagerTest, LoadStateDefinition) {
- auto dict = CreateDictionaryValue(R"({
- 'power': {
- 'battery_level':'integer'
- }
- })");
- LoadStateDefinition(dict.get(), nullptr);
-
- auto expected = R"({
- 'base': {
- 'manufacturer': 'Test Factory',
- 'serialNumber': 'Test Model'
- },
- 'power': {},
- 'device': {}
- })";
- EXPECT_JSON_EQ(expected, mgr_->GetState());
-}
-
-TEST_F(StateManagerTest, Startup) {
- StateManager manager(&mock_state_change_queue_);
-
- auto state_definition = R"({
- "base": {
- "firmwareVersion": {"type":"string"},
- "localDiscoveryEnabled": {"type":"boolean"},
- "localAnonymousAccessMaxRole": {
- "type": "string",
- "enum": ["none", "viewer", "user"]
- },
- "localPairingEnabled": {"type":"boolean"}
- },
- "power": {"battery_level":{"type":"integer"}}
- })";
- ASSERT_TRUE(manager.LoadStateDefinitionFromJson(state_definition, nullptr));
-
- auto state_values = R"({
- "base": {
- "firmwareVersion": "unknown",
- "localDiscoveryEnabled": false,
- "localAnonymousAccessMaxRole": "none",
- "localPairingEnabled": false
- },
- "power": {"battery_level":44}
- })";
- ASSERT_TRUE(manager.SetPropertiesFromJson(state_values, nullptr));
-
- auto expected = R"({
- 'base': {
- 'firmwareVersion': 'unknown',
- 'localAnonymousAccessMaxRole': 'none',
- 'localDiscoveryEnabled': false,
- 'localPairingEnabled': false
- },
- 'power': {
- 'battery_level': 44
- }
- })";
- EXPECT_JSON_EQ(expected, manager.GetState());
-}
-
-TEST_F(StateManagerTest, SetPropertyValue) {
- const std::string state = "{'device': {'state_property': 'Test Value'}}";
- EXPECT_CALL(mock_state_change_queue_,
- NotifyPropertiesUpdated(timestamp_, IsState(state)))
- .WillOnce(Return(true));
- ASSERT_TRUE(SetPropertyValue("device.state_property",
- base::StringValue{"Test Value"}, nullptr));
- auto expected = R"({
- 'base': {
- 'manufacturer': 'Test Factory',
- 'serialNumber': 'Test Model'
- },
- 'device': {
- 'state_property': 'Test Value'
- }
- })";
- EXPECT_JSON_EQ(expected, mgr_->GetState());
-}
-
-TEST_F(StateManagerTest, SetPropertyValue_Error_NoName) {
- ErrorPtr error;
- ASSERT_FALSE(SetPropertyValue("", base::FundamentalValue{0}, &error));
- EXPECT_EQ(errors::state::kDomain, error->GetDomain());
- EXPECT_EQ(errors::state::kPropertyNameMissing, error->GetCode());
-}
-
-TEST_F(StateManagerTest, SetPropertyValue_Error_NoPackage) {
- ErrorPtr error;
- ASSERT_FALSE(
- SetPropertyValue("state_property", base::FundamentalValue{0}, &error));
- EXPECT_EQ(errors::state::kDomain, error->GetDomain());
- EXPECT_EQ(errors::state::kPackageNameMissing, error->GetCode());
-}
-
-TEST_F(StateManagerTest, SetPropertyValue_Error_UnknownPackage) {
- ErrorPtr error;
- ASSERT_FALSE(
- SetPropertyValue("power.level", base::FundamentalValue{0}, &error));
- EXPECT_EQ(errors::state::kDomain, error->GetDomain());
- EXPECT_EQ(errors::state::kPropertyNotDefined, error->GetCode());
-}
-
-TEST_F(StateManagerTest, SetPropertyValue_Error_UnknownProperty) {
- ASSERT_TRUE(
- SetPropertyValue("base.level", base::FundamentalValue{0}, nullptr));
-}
-
-TEST_F(StateManagerTest, GetAndClearRecordedStateChanges) {
- EXPECT_CALL(mock_state_change_queue_,
- NotifyPropertiesUpdated(timestamp_, _))
- .WillOnce(Return(true));
- ASSERT_TRUE(SetPropertyValue("device.state_property",
- base::StringValue{"Test Value"}, nullptr));
- std::vector<StateChange> expected_state;
- const std::string expected_val =
- "{'device': {'state_property': 'Test Value'}}";
- expected_state.emplace_back(
- timestamp_,
- CreateDictionaryValue(expected_val));
- EXPECT_CALL(mock_state_change_queue_, MockGetAndClearRecordedStateChanges())
- .WillOnce(ReturnRef(expected_state));
- EXPECT_CALL(mock_state_change_queue_, GetLastStateChangeId())
- .WillOnce(Return(0));
- auto changes = mgr_->GetAndClearRecordedStateChanges();
- ASSERT_EQ(1u, changes.second.size());
- EXPECT_EQ(timestamp_, changes.second.back().timestamp);
- EXPECT_JSON_EQ(expected_val, *changes.second.back().changed_properties);
-}
-
-TEST_F(StateManagerTest, SetProperties) {
- const std::string state = "{'base': {'manufacturer': 'No Name'}}";
- EXPECT_CALL(mock_state_change_queue_,
- NotifyPropertiesUpdated(_, IsState(state)))
- .WillOnce(Return(true));
-
- EXPECT_CALL(*this, OnStateChanged()).Times(1);
- ASSERT_TRUE(mgr_->SetProperties(
- *CreateDictionaryValue("{'base':{'manufacturer':'No Name'}}"), nullptr));
-
- auto expected = R"({
- 'base': {
- 'manufacturer': 'No Name',
- 'serialNumber': 'Test Model'
- },
- 'device': {}
- })";
- EXPECT_JSON_EQ(expected, mgr_->GetState());
-}
-
-TEST_F(StateManagerTest, GetProperty) {
- EXPECT_JSON_EQ("'Test Model'", *mgr_->GetProperty("base.serialNumber"));
- EXPECT_EQ(nullptr, mgr_->GetProperty("device.state_property"));
- EXPECT_EQ(nullptr, mgr_->GetProperty("device.unknown"));
- EXPECT_EQ(nullptr, mgr_->GetProperty("unknown.state_property"));
-}
-
-} // namespace weave
diff --git a/src/states/state_package.cc b/src/states/state_package.cc
deleted file mode 100644
index b0ea199..0000000
--- a/src/states/state_package.cc
+++ /dev/null
@@ -1,68 +0,0 @@
-// Copyright 2015 The Weave Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "src/states/state_package.h"
-
-#include <base/logging.h>
-#include <base/values.h>
-
-#include "src/states/error_codes.h"
-
-namespace weave {
-
-StatePackage::StatePackage(const std::string& name) : name_(name) {}
-
-bool StatePackage::AddSchemaFromJson(const base::DictionaryValue* json,
- ErrorPtr* error) {
- // Scan first to make sure we have no property redefinitions.
- for (base::DictionaryValue::Iterator it(*json); !it.IsAtEnd(); it.Advance()) {
- if (types_.HasKey(it.key())) {
- Error::AddToPrintf(error, FROM_HERE, errors::state::kDomain,
- errors::state::kPropertyRedefinition,
- "State property '%s.%s' is already defined",
- name_.c_str(), it.key().c_str());
- return false;
- }
- }
-
- types_.MergeDictionary(json);
- return true;
-}
-
-bool StatePackage::AddValuesFromJson(const base::DictionaryValue* json,
- ErrorPtr* error) {
- for (base::DictionaryValue::Iterator it(*json); !it.IsAtEnd(); it.Advance()) {
- if (!SetPropertyValue(it.key(), it.value(), error))
- return false;
- }
- return true;
-}
-
-const base::DictionaryValue& StatePackage::GetValuesAsJson() const {
- return values_;
-}
-
-const base::Value* StatePackage::GetPropertyValue(
- const std::string& property_name,
- ErrorPtr* error) const {
- const base::Value* value = nullptr;
- if (!values_.Get(property_name, &value)) {
- Error::AddToPrintf(error, FROM_HERE, errors::state::kDomain,
- errors::state::kPropertyNotDefined,
- "State property '%s.%s' is not defined", name_.c_str(),
- property_name.c_str());
- return nullptr;
- }
-
- return value;
-}
-
-bool StatePackage::SetPropertyValue(const std::string& property_name,
- const base::Value& value,
- ErrorPtr* error) {
- values_.Set(property_name, value.DeepCopy());
- return true;
-}
-
-} // namespace weave
diff --git a/src/states/state_package.h b/src/states/state_package.h
deleted file mode 100644
index afc4c52..0000000
--- a/src/states/state_package.h
+++ /dev/null
@@ -1,74 +0,0 @@
-// Copyright 2015 The Weave Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef LIBWEAVE_SRC_STATES_STATE_PACKAGE_H_
-#define LIBWEAVE_SRC_STATES_STATE_PACKAGE_H_
-
-#include <map>
-#include <memory>
-#include <string>
-
-#include <base/macros.h>
-#include <base/values.h>
-#include <weave/error.h>
-
-namespace weave {
-
-// A package is a set of related state properties. GCD specification defines
-// a number of standard state properties in "base" package such as
-// "base.manufacturer", "base.model", "base.firmwareVersion" and so on.
-class StatePackage final {
- public:
- explicit StatePackage(const std::string& name);
-
- // Loads state property definitions from a JSON object and adds them
- // to the current package.
- bool AddSchemaFromJson(const base::DictionaryValue* json, ErrorPtr* error);
- // Loads a set of state property values from a JSON object and assigns them
- // to existing properties. A property must be defined prior to loading its
- // value. We use this when we load default values during buffet startup.
- bool AddValuesFromJson(const base::DictionaryValue* json, ErrorPtr* error);
-
- // Returns a set of state properties and their values as a JSON object.
- // After being aggregated across multiple packages, this becomes the device
- // state object passed to the GCD server or a local client in the format
- // described by GCD specification, e.g.:
- // {
- // "base": {
- // "manufacturer":"...",
- // "model":"..."
- // },
- // "printer": {
- // "message": "Printer low on cyan ink"
- // }
- // }
- const base::DictionaryValue& GetValuesAsJson() const;
-
- // Gets the value for a specific state property. |property_name| must not
- // include the package name as part of the property name.
- const base::Value* GetPropertyValue(const std::string& property_name,
- ErrorPtr* error) const;
- // Sets the value for a specific state property. |property_name| must not
- // include the package name as part of the property name.
- bool SetPropertyValue(const std::string& property_name,
- const base::Value& value,
- ErrorPtr* error);
-
- // Returns the name of the this package.
- const std::string& GetName() const { return name_; }
-
- const base::DictionaryValue& types() const { return types_; }
-
- private:
- std::string name_;
- base::DictionaryValue types_;
- base::DictionaryValue values_;
-
- friend class StatePackageTestHelper;
- DISALLOW_COPY_AND_ASSIGN(StatePackage);
-};
-
-} // namespace weave
-
-#endif // LIBWEAVE_SRC_STATES_STATE_PACKAGE_H_
diff --git a/src/states/state_package_unittest.cc b/src/states/state_package_unittest.cc
deleted file mode 100644
index d09625a..0000000
--- a/src/states/state_package_unittest.cc
+++ /dev/null
@@ -1,289 +0,0 @@
-// Copyright 2015 The Weave Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "src/states/state_package.h"
-
-#include <memory>
-#include <string>
-
-#include <base/values.h>
-#include <gtest/gtest.h>
-#include <weave/test/unittest_utils.h>
-
-#include "src/commands/schema_constants.h"
-#include "src/states/error_codes.h"
-
-namespace weave {
-
-using test::CreateDictionaryValue;
-
-class StatePackageTestHelper {
- public:
- // Returns the state property definitions (types/constraints/etc).
- static const base::DictionaryValue& GetTypes(const StatePackage& package) {
- return package.types_;
- }
- // Returns the all state property values in this package.
- static const base::DictionaryValue& GetValues(const StatePackage& package) {
- return package.values_;
- }
-};
-
-namespace {
-std::unique_ptr<base::DictionaryValue> GetTestSchema() {
- return CreateDictionaryValue(R"({
- 'color': {
- 'type': 'string'
- },
- 'direction': {
- 'additionalProperties': false,
- 'properties': {
- 'altitude': {
- 'maximum': 90.0,
- 'type': 'number'
- },
- 'azimuth': {
- 'type': 'number'
- }
- },
- 'type': 'object',
- 'required': [ 'azimuth' ]
- },
- 'iso': {
- 'enum': [50, 100, 200, 400],
- 'type': 'integer'
- },
- 'light': {
- 'type': 'boolean'
- }
- })");
-}
-
-std::unique_ptr<base::DictionaryValue> GetTestValues() {
- return CreateDictionaryValue(R"({
- 'light': true,
- 'color': 'white',
- 'direction': {'azimuth':57.2957795, 'altitude':89.9},
- 'iso': 200
- })");
-}
-
-inline const base::DictionaryValue& GetTypes(const StatePackage& package) {
- return StatePackageTestHelper::GetTypes(package);
-}
-// Returns the all state property values in this package.
-inline const base::DictionaryValue& GetValues(const StatePackage& package) {
- return StatePackageTestHelper::GetValues(package);
-}
-
-} // anonymous namespace
-
-class StatePackageTest : public ::testing::Test {
- public:
- void SetUp() override {
- package_.reset(new StatePackage("test"));
- ASSERT_TRUE(package_->AddSchemaFromJson(GetTestSchema().get(), nullptr));
- ASSERT_TRUE(package_->AddValuesFromJson(GetTestValues().get(), nullptr));
- }
- void TearDown() override { package_.reset(); }
- std::unique_ptr<StatePackage> package_;
-};
-
-TEST(StatePackage, Empty) {
- StatePackage package("test");
- EXPECT_EQ("test", package.GetName());
- EXPECT_TRUE(GetTypes(package).empty());
- EXPECT_TRUE(GetValues(package).empty());
-}
-
-TEST(StatePackage, AddSchemaFromJson_OnEmpty) {
- StatePackage package("test");
- ASSERT_TRUE(package.AddSchemaFromJson(GetTestSchema().get(), nullptr));
- EXPECT_EQ(4u, GetTypes(package).size());
- EXPECT_EQ(0u, GetValues(package).size());
-
- auto expected = R"({
- 'color': {
- 'type': 'string'
- },
- 'direction': {
- 'additionalProperties': false,
- 'properties': {
- 'altitude': {
- 'maximum': 90.0,
- 'type': 'number'
- },
- 'azimuth': {
- 'type': 'number'
- }
- },
- 'type': 'object',
- 'required': [ 'azimuth' ]
- },
- 'iso': {
- 'enum': [50, 100, 200, 400],
- 'type': 'integer'
- },
- 'light': {
- 'type': 'boolean'
- }
- })";
- EXPECT_JSON_EQ(expected, GetTypes(package));
-
- EXPECT_JSON_EQ("{}", package.GetValuesAsJson());
-}
-
-TEST(StatePackage, AddValuesFromJson_OnEmpty) {
- StatePackage package("test");
- ASSERT_TRUE(package.AddSchemaFromJson(GetTestSchema().get(), nullptr));
- ASSERT_TRUE(package.AddValuesFromJson(GetTestValues().get(), nullptr));
- EXPECT_EQ(4u, GetValues(package).size());
- auto expected = R"({
- 'color': 'white',
- 'direction': {
- 'altitude': 89.9,
- 'azimuth': 57.2957795
- },
- 'iso': 200,
- 'light': true
- })";
- EXPECT_JSON_EQ(expected, package.GetValuesAsJson());
-}
-
-TEST_F(StatePackageTest, AddSchemaFromJson_AddMore) {
- auto dict = CreateDictionaryValue(R"({'brightness':{
- 'enum': ['low', 'medium', 'high'],
- 'type': 'string'
- }})");
- ASSERT_TRUE(package_->AddSchemaFromJson(dict.get(), nullptr));
- EXPECT_EQ(5u, GetTypes(*package_).size());
- EXPECT_EQ(4u, GetValues(*package_).size());
- auto expected = R"({
- 'brightness': {
- 'enum': ['low', 'medium', 'high'],
- 'type': 'string'
- },
- 'color': {
- 'type': 'string'
- },
- 'direction': {
- 'additionalProperties': false,
- 'properties': {
- 'altitude': {
- 'maximum': 90.0,
- 'type': 'number'
- },
- 'azimuth': {
- 'type': 'number'
- }
- },
- 'type': 'object',
- 'required': [ 'azimuth' ]
- },
- 'iso': {
- 'enum': [50, 100, 200, 400],
- 'type': 'integer'
- },
- 'light': {
- 'type': 'boolean'
- }
- })";
- EXPECT_JSON_EQ(expected, GetTypes(*package_));
-
- expected = R"({
- 'color': 'white',
- 'direction': {
- 'altitude': 89.9,
- 'azimuth': 57.2957795
- },
- 'iso': 200,
- 'light': true
- })";
- EXPECT_JSON_EQ(expected, package_->GetValuesAsJson());
-}
-
-TEST_F(StatePackageTest, AddValuesFromJson_AddMore) {
- auto dict = CreateDictionaryValue(R"({'brightness':{
- 'enum': ['low', 'medium', 'high'],
- 'type': 'string'
- }})");
- ASSERT_TRUE(package_->AddSchemaFromJson(dict.get(), nullptr));
- dict = CreateDictionaryValue("{'brightness':'medium'}");
- ASSERT_TRUE(package_->AddValuesFromJson(dict.get(), nullptr));
- EXPECT_EQ(5u, GetValues(*package_).size());
- auto expected = R"({
- 'brightness': 'medium',
- 'color': 'white',
- 'direction': {
- 'altitude': 89.9,
- 'azimuth': 57.2957795
- },
- 'iso': 200,
- 'light': true
- })";
- EXPECT_JSON_EQ(expected, package_->GetValuesAsJson());
-}
-
-TEST_F(StatePackageTest, AddSchemaFromJson_Error_Redefined) {
- auto dict = CreateDictionaryValue(R"({'color':
- {'type':'string', 'enum':['white', 'blue', 'red']}})");
- ErrorPtr error;
- EXPECT_FALSE(package_->AddSchemaFromJson(dict.get(), &error));
- EXPECT_EQ(errors::state::kDomain, error->GetDomain());
- EXPECT_EQ(errors::state::kPropertyRedefinition, error->GetCode());
-}
-
-TEST_F(StatePackageTest, AddValuesFromJson_Error_Undefined) {
- auto dict = CreateDictionaryValue("{'brightness':'medium'}");
- EXPECT_TRUE(package_->AddValuesFromJson(dict.get(), nullptr));
-}
-
-TEST_F(StatePackageTest, GetPropertyValue) {
- EXPECT_JSON_EQ("'white'", *package_->GetPropertyValue("color", nullptr));
- EXPECT_JSON_EQ("true", *package_->GetPropertyValue("light", nullptr));
- EXPECT_JSON_EQ("200", *package_->GetPropertyValue("iso", nullptr));
- EXPECT_JSON_EQ("{'altitude': 89.9, 'azimuth': 57.2957795}",
- *package_->GetPropertyValue("direction", nullptr));
-}
-
-TEST_F(StatePackageTest, GetPropertyValue_Unknown) {
- ErrorPtr error;
- EXPECT_EQ(nullptr, package_->GetPropertyValue("volume", &error));
- EXPECT_EQ(errors::state::kDomain, error->GetDomain());
- EXPECT_EQ(errors::state::kPropertyNotDefined, error->GetCode());
-}
-
-TEST_F(StatePackageTest, SetPropertyValue_Simple) {
- EXPECT_TRUE(
- package_->SetPropertyValue("color", base::StringValue{"blue"}, nullptr));
- EXPECT_JSON_EQ("'blue'", *package_->GetPropertyValue("color", nullptr));
- EXPECT_TRUE(package_->SetPropertyValue("light", base::FundamentalValue{false},
- nullptr));
- bool light = false;
- ASSERT_TRUE(
- package_->GetPropertyValue("light", nullptr)->GetAsBoolean(&light));
- EXPECT_FALSE(light);
- EXPECT_TRUE(
- package_->SetPropertyValue("iso", base::FundamentalValue{400}, nullptr));
- EXPECT_JSON_EQ("400", *package_->GetPropertyValue("iso", nullptr));
-}
-
-TEST_F(StatePackageTest, SetPropertyValue_Object) {
- EXPECT_TRUE(package_->SetPropertyValue(
- "direction",
- *CreateDictionaryValue("{'altitude': 45.0, 'azimuth': 15.0}"), nullptr));
-
- auto expected = R"({
- 'color': 'white',
- 'direction': {
- 'altitude': 45.0,
- 'azimuth': 15.0
- },
- 'iso': 200,
- 'light': true
- })";
- EXPECT_JSON_EQ(expected, package_->GetValuesAsJson());
-}
-
-} // namespace weave