aboutsummaryrefslogtreecommitdiff
path: root/common/data_conversion_unittest.cc
diff options
context:
space:
mode:
Diffstat (limited to 'common/data_conversion_unittest.cc')
-rw-r--r--common/data_conversion_unittest.cc200
1 files changed, 200 insertions, 0 deletions
diff --git a/common/data_conversion_unittest.cc b/common/data_conversion_unittest.cc
new file mode 100644
index 0000000..832fffb
--- /dev/null
+++ b/common/data_conversion_unittest.cc
@@ -0,0 +1,200 @@
+// Copyright 2015 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "common/data_conversion.h"
+
+#include <limits>
+#include <memory>
+#include <string>
+#include <vector>
+
+#include <base/guid.h>
+#include <base/rand_util.h>
+#include <base/values.h>
+#include <brillo/variant_dictionary.h>
+#include <gtest/gtest.h>
+#include <weave/test/unittest_utils.h>
+
+namespace weaved {
+
+namespace {
+
+using brillo::Any;
+using brillo::VariantDictionary;
+using weave::test::CreateDictionaryValue;
+using weave::test::IsEqualValue;
+
+brillo::VariantDictionary ToVariant(const base::DictionaryValue& object) {
+ return details::DictionaryValueToVariantDictionary(object);
+}
+
+std::unique_ptr<base::DictionaryValue> FromVariant(
+ const brillo::VariantDictionary& object) {
+ brillo::ErrorPtr error;
+ auto result = details::VariantDictionaryToDictionaryValue(object, &error);
+ EXPECT_TRUE(result || error);
+ return result;
+}
+
+std::unique_ptr<base::Value> CreateRandomValue(int children);
+std::unique_ptr<base::Value> CreateRandomValue(int children,
+ base::Value::Type type);
+
+const base::Value::Type kRandomTypes[] = {
+ base::Value::TYPE_BOOLEAN, base::Value::TYPE_INTEGER,
+ base::Value::TYPE_DOUBLE, base::Value::TYPE_STRING,
+ base::Value::TYPE_DICTIONARY, base::Value::TYPE_LIST,
+};
+
+const base::Value::Type kRandomTypesWithChildren[] = {
+ base::Value::TYPE_DICTIONARY, base::Value::TYPE_LIST,
+};
+
+base::Value::Type CreateRandomValueType(bool with_children) {
+ if (with_children) {
+ return kRandomTypesWithChildren[base::RandInt(
+ 0, arraysize(kRandomTypesWithChildren) - 1)];
+ }
+ return kRandomTypes[base::RandInt(0, arraysize(kRandomTypes) - 1)];
+}
+
+std::unique_ptr<base::DictionaryValue> CreateRandomDictionary(int children) {
+ std::unique_ptr<base::DictionaryValue> result{new base::DictionaryValue};
+
+ while (children > 0) {
+ int sub_children = base::RandInt(1, children);
+ children -= sub_children;
+ result->Set(base::GenerateGUID(),
+ CreateRandomValue(sub_children).release());
+ }
+
+ return result;
+}
+
+std::unique_ptr<base::ListValue> CreateRandomList(int children) {
+ std::unique_ptr<base::ListValue> result{new base::ListValue};
+
+ base::Value::Type type = CreateRandomValueType(children > 0);
+ while (children > 0) {
+ size_t max_children =
+ (type != base::Value::TYPE_DICTIONARY && type != base::Value::TYPE_LIST)
+ ? 1
+ : children;
+ size_t sub_children = base::RandInt(1, max_children);
+ children -= sub_children;
+ result->Append(CreateRandomValue(sub_children, type).release());
+ }
+
+ return result;
+}
+
+std::unique_ptr<base::Value> CreateRandomValue(int children,
+ base::Value::Type type) {
+ CHECK_GE(children, 1);
+ switch (type) {
+ case base::Value::TYPE_INTEGER:
+ return std::unique_ptr<base::Value>{new base::FundamentalValue{
+ base::RandInt(std::numeric_limits<int>::min(),
+ std::numeric_limits<int>::max())}};
+ case base::Value::TYPE_DOUBLE:
+ return std::unique_ptr<base::Value>{
+ new base::FundamentalValue{base::RandDouble()}};
+ case base::Value::TYPE_STRING:
+ return std::unique_ptr<base::Value>{
+ new base::StringValue{base::GenerateGUID()}};
+ case base::Value::TYPE_DICTIONARY:
+ CHECK_GE(children, 1);
+ return CreateRandomDictionary(children - 1);
+ case base::Value::TYPE_LIST:
+ CHECK_GE(children, 1);
+ return CreateRandomList(children - 1);
+ default:
+ return std::unique_ptr<base::Value>{
+ new base::FundamentalValue{base::RandInt(0, 1) != 0}};
+ }
+}
+
+std::unique_ptr<base::Value> CreateRandomValue(int children) {
+ return CreateRandomValue(children, CreateRandomValueType(children > 0));
+}
+
+} // namespace
+
+TEST(DBusConversionTest, DictionaryToDBusVariantDictionary) {
+ EXPECT_EQ((VariantDictionary{{"bool", true}}),
+ ToVariant(*CreateDictionaryValue("{'bool': true}")));
+ EXPECT_EQ((VariantDictionary{{"int", 5}}),
+ ToVariant(*CreateDictionaryValue("{'int': 5}")));
+ EXPECT_EQ((VariantDictionary{{"double", 6.7}}),
+ ToVariant(*CreateDictionaryValue("{'double': 6.7}")));
+ EXPECT_EQ((VariantDictionary{{"string", std::string{"abc"}}}),
+ ToVariant(*CreateDictionaryValue("{'string': 'abc'}")));
+ EXPECT_EQ((VariantDictionary{{"object", VariantDictionary{{"bool", true}}}}),
+ ToVariant(*CreateDictionaryValue("{'object': {'bool': true}}")));
+ EXPECT_EQ((VariantDictionary{{"emptyList", std::vector<Any>{}}}),
+ ToVariant(*CreateDictionaryValue("{'emptyList': []}")));
+ EXPECT_EQ((VariantDictionary{{"intList", std::vector<int>{5}}}),
+ ToVariant(*CreateDictionaryValue("{'intList': [5]}")));
+ EXPECT_EQ((VariantDictionary{
+ {"intListList", std::vector<Any>{std::vector<int>{5},
+ std::vector<int>{6, 7}}}}),
+ ToVariant(*CreateDictionaryValue(
+ "{'intListList': [[5], [6, 7]]}")));
+ EXPECT_EQ((VariantDictionary{{"objList",
+ std::vector<VariantDictionary>{
+ {{"string", std::string{"abc"}}}}}}),
+ ToVariant(*CreateDictionaryValue(
+ "{'objList': [{'string': 'abc'}]}")));
+}
+
+TEST(DBusConversionTest, VariantDictionaryToDictionaryValue) {
+ EXPECT_JSON_EQ("{'bool': true}", *FromVariant({{"bool", true}}));
+ EXPECT_JSON_EQ("{'int': 5}", *FromVariant({{"int", 5}}));
+ EXPECT_JSON_EQ("{'double': 6.7}", *FromVariant({{"double", 6.7}}));
+ EXPECT_JSON_EQ("{'string': 'abc'}",
+ *FromVariant({{"string", std::string{"abc"}}}));
+ EXPECT_JSON_EQ("{'object': {'bool': true}}",
+ *FromVariant({{"object", VariantDictionary{{"bool", true}}}}));
+ EXPECT_JSON_EQ("{'emptyList': []}",
+ *FromVariant({{"emptyList", std::vector<bool>{}}}));
+ EXPECT_JSON_EQ("{'intList': [5]}",
+ *FromVariant({{"intList", std::vector<int>{5}}}));
+ EXPECT_JSON_EQ(
+ "{'intListList': [[5], [6, 7]]}",
+ *FromVariant({{"intListList",
+ std::vector<Any>{std::vector<int>{5},
+ std::vector<int>{6, 7}}}}));
+ EXPECT_JSON_EQ(
+ "{'objList': [{'string': 'abc'}]}",
+ *FromVariant({{"objList", std::vector<VariantDictionary>{
+ {{"string", std::string{"abc"}}}}}}));
+ EXPECT_JSON_EQ("{'int': 5}", *FromVariant({{"int", Any{Any{5}}}}));
+}
+
+TEST(DBusConversionTest, VariantDictionaryToDictionaryValueErrors) {
+ EXPECT_FALSE(FromVariant({{"cString", "abc"}}));
+ EXPECT_FALSE(FromVariant({{"float", 1.0f}}));
+ EXPECT_FALSE(FromVariant({{"listList", std::vector<std::vector<int>>{}}}));
+ EXPECT_FALSE(FromVariant({{"any", Any{}}}));
+ EXPECT_FALSE(FromVariant({{"null", nullptr}}));
+}
+
+TEST(DBusConversionTest, DBusRandomDictionaryConversion) {
+ auto dict = CreateRandomDictionary(10000);
+ auto varian_dict = ToVariant(*dict);
+ auto dict_restored = FromVariant(varian_dict);
+ EXPECT_PRED2(IsEqualValue, *dict, *dict_restored);
+}
+
+} // namespace buffet