• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2018 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include <string>
6 #include <utility>
7 
8 #include "base/test/gtest_util.h"
9 #include "base/values.h"
10 #include "mojo/public/cpp/base/values_mojom_traits.h"
11 #include "mojo/public/cpp/test_support/test_utils.h"
12 #include "mojo/public/mojom/base/values.mojom.h"
13 #include "testing/gtest/include/gtest/gtest.h"
14 
15 namespace mojo_base {
16 
TEST(ValuesStructTraitsTest,NullValue)17 TEST(ValuesStructTraitsTest, NullValue) {
18   base::Value in;
19   base::Value out;
20   ASSERT_TRUE(mojo::test::SerializeAndDeserialize<mojom::Value>(&in, &out));
21   EXPECT_EQ(in, out);
22 }
23 
TEST(ValuesStructTraitsTest,BoolValue)24 TEST(ValuesStructTraitsTest, BoolValue) {
25   static constexpr bool kTestCases[] = {true, false};
26   for (auto& test_case : kTestCases) {
27     base::Value in(test_case);
28     base::Value out;
29     ASSERT_TRUE(mojo::test::SerializeAndDeserialize<mojom::Value>(&in, &out));
30     EXPECT_EQ(in, out);
31   }
32 }
33 
TEST(ValuesStructTraitsTest,IntValue)34 TEST(ValuesStructTraitsTest, IntValue) {
35   static constexpr int kTestCases[] = {0, -1, 1,
36                                        std::numeric_limits<int>::min(),
37                                        std::numeric_limits<int>::max()};
38   for (auto& test_case : kTestCases) {
39     base::Value in(test_case);
40     base::Value out;
41     ASSERT_TRUE(mojo::test::SerializeAndDeserialize<mojom::Value>(&in, &out));
42     EXPECT_EQ(in, out);
43   }
44 }
45 
TEST(ValuesStructTraitsTest,DoubleValue)46 TEST(ValuesStructTraitsTest, DoubleValue) {
47   static constexpr double kTestCases[] = {-0.0,
48                                           +0.0,
49                                           -1.0,
50                                           +1.0,
51                                           std::numeric_limits<double>::min(),
52                                           std::numeric_limits<double>::max()};
53   for (auto& test_case : kTestCases) {
54     base::Value in(test_case);
55     base::Value out;
56     ASSERT_TRUE(mojo::test::SerializeAndDeserialize<mojom::Value>(&in, &out));
57     EXPECT_EQ(in, out);
58   }
59 }
60 
TEST(ValuesStructTraitsTest,StringValue)61 TEST(ValuesStructTraitsTest, StringValue) {
62   static constexpr const char* kTestCases[] = {
63       "", "ascii",
64       // ��: Unicode FIREWORKS
65       "\xf0\x9f\x8e\x86",
66   };
67   for (auto* test_case : kTestCases) {
68     base::Value in(test_case);
69     base::Value out;
70     ASSERT_TRUE(mojo::test::SerializeAndDeserialize<mojom::Value>(&in, &out));
71     EXPECT_EQ(in, out);
72   }
73 }
74 
TEST(ValuesStructTraitsTest,BinaryValue)75 TEST(ValuesStructTraitsTest, BinaryValue) {
76   std::vector<char> kBinaryData = {'\x00', '\x80', '\xff', '\x7f', '\x01'};
77   base::Value in(std::move(kBinaryData));
78   base::Value out;
79   ASSERT_TRUE(mojo::test::SerializeAndDeserialize<mojom::Value>(&in, &out));
80   EXPECT_EQ(in, out);
81 }
82 
TEST(ValuesStructTraitsTest,DictionaryValue)83 TEST(ValuesStructTraitsTest, DictionaryValue) {
84   // Note: here and below, it would be nice to use an initializer list, but
85   // move-only types and initializer lists don't mix. Initializer lists can't be
86   // modified: thus it's not possible to move.
87   std::vector<base::Value::DictStorage::value_type> storage;
88   storage.emplace_back("null", std::make_unique<base::Value>());
89   storage.emplace_back("bool", std::make_unique<base::Value>(false));
90   storage.emplace_back("int", std::make_unique<base::Value>(0));
91   storage.emplace_back("double", std::make_unique<base::Value>(0.0));
92   storage.emplace_back("string", std::make_unique<base::Value>("0"));
93   storage.emplace_back(
94       "binary", std::make_unique<base::Value>(base::Value::BlobStorage({0})));
95   storage.emplace_back(
96       "dictionary", std::make_unique<base::Value>(base::Value::DictStorage()));
97   storage.emplace_back(
98       "list", std::make_unique<base::Value>(base::Value::ListStorage()));
99 
100   base::Value in(
101       base::Value::DictStorage(std::move(storage), base::KEEP_LAST_OF_DUPES));
102   base::Value out;
103   ASSERT_TRUE(mojo::test::SerializeAndDeserialize<mojom::Value>(&in, &out));
104   EXPECT_EQ(in, out);
105 
106   ASSERT_TRUE(
107       mojo::test::SerializeAndDeserialize<mojom::DictionaryValue>(&in, &out));
108   EXPECT_EQ(in, out);
109 }
110 
TEST(ValuesStructTraitsTest,SerializeInvalidDictionaryValue)111 TEST(ValuesStructTraitsTest, SerializeInvalidDictionaryValue) {
112   base::Value in;
113   ASSERT_FALSE(in.is_dict());
114 
115   base::Value out;
116   EXPECT_DCHECK_DEATH(
117       mojo::test::SerializeAndDeserialize<mojom::DictionaryValue>(&in, &out));
118 }
119 
TEST(ValuesStructTraitsTest,ListValue)120 TEST(ValuesStructTraitsTest, ListValue) {
121   base::Value::ListStorage storage;
122   storage.emplace_back();
123   storage.emplace_back(false);
124   storage.emplace_back(0);
125   storage.emplace_back(0.0);
126   storage.emplace_back("0");
127   storage.emplace_back(base::Value::BlobStorage({0}));
128   storage.emplace_back(base::Value::DictStorage());
129   storage.emplace_back(base::Value::ListStorage());
130   base::Value in(std::move(storage));
131   base::Value out;
132   ASSERT_TRUE(mojo::test::SerializeAndDeserialize<mojom::Value>(&in, &out));
133   EXPECT_EQ(in, out);
134 
135   ASSERT_TRUE(mojo::test::SerializeAndDeserialize<mojom::ListValue>(&in, &out));
136   EXPECT_EQ(in, out);
137 }
138 
TEST(ValuesStructTraitsTest,SerializeInvalidListValue)139 TEST(ValuesStructTraitsTest, SerializeInvalidListValue) {
140   base::Value in;
141   ASSERT_FALSE(in.is_dict());
142 
143   base::Value out;
144   EXPECT_DCHECK_DEATH(
145       mojo::test::SerializeAndDeserialize<mojom::ListValue>(&in, &out));
146 }
147 
148 // A deeply nested base::Value should trigger a deserialization error.
TEST(ValuesStructTraitsTest,DeeplyNestedValue)149 TEST(ValuesStructTraitsTest, DeeplyNestedValue) {
150   base::Value in;
151   for (int i = 0; i < 100; ++i) {
152     base::Value::ListStorage storage;
153     storage.emplace_back(std::move(in));
154     in = base::Value(std::move(storage));
155   }
156   base::Value out;
157   ASSERT_FALSE(mojo::test::SerializeAndDeserialize<mojom::Value>(&in, &out));
158 }
159 
160 }  // namespace mojo_base
161