Home | History | Annotate | Download | only in tests
      1 // Copyright 2016 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 "base/bind.h"
      6 #include "base/macros.h"
      7 #include "base/message_loop/message_loop.h"
      8 #include "base/run_loop.h"
      9 #include "mojo/public/cpp/bindings/binding.h"
     10 #include "mojo/public/cpp/bindings/lib/fixed_buffer.h"
     11 #include "mojo/public/cpp/bindings/lib/serialization.h"
     12 #include "mojo/public/cpp/bindings/lib/wtf_serialization.h"
     13 #include "mojo/public/cpp/bindings/tests/variant_test_util.h"
     14 #include "mojo/public/interfaces/bindings/tests/test_wtf_types.mojom-blink.h"
     15 #include "mojo/public/interfaces/bindings/tests/test_wtf_types.mojom.h"
     16 #include "testing/gtest/include/gtest/gtest.h"
     17 
     18 namespace mojo {
     19 namespace test {
     20 namespace {
     21 
     22 const char kHelloWorld[] = "hello world";
     23 
     24 // Replace the "o"s in "hello world" with "o"s with acute.
     25 const char kUTF8HelloWorld[] = "hell\xC3\xB3 w\xC3\xB3rld";
     26 
     27 class TestWTFImpl : public TestWTF {
     28  public:
     29   explicit TestWTFImpl(TestWTFRequest request)
     30       : binding_(this, std::move(request)) {}
     31 
     32   // mojo::test::TestWTF implementation:
     33   void EchoString(const base::Optional<std::string>& str,
     34                   const EchoStringCallback& callback) override {
     35     callback.Run(str);
     36   }
     37 
     38   void EchoStringArray(
     39       const base::Optional<std::vector<base::Optional<std::string>>>& arr,
     40       const EchoStringArrayCallback& callback) override {
     41     callback.Run(std::move(arr));
     42   }
     43 
     44   void EchoStringMap(
     45       const base::Optional<
     46           std::unordered_map<std::string, base::Optional<std::string>>>&
     47           str_map,
     48       const EchoStringMapCallback& callback) override {
     49     callback.Run(std::move(str_map));
     50   }
     51 
     52  private:
     53   Binding<TestWTF> binding_;
     54 };
     55 
     56 class WTFTypesTest : public testing::Test {
     57  public:
     58   WTFTypesTest() {}
     59 
     60  private:
     61   base::MessageLoop loop_;
     62 };
     63 
     64 WTF::Vector<WTF::String> ConstructStringArray() {
     65   WTF::Vector<WTF::String> strs(4);
     66   // strs[0] is null.
     67   // strs[1] is empty.
     68   strs[1] = "";
     69   strs[2] = kHelloWorld;
     70   strs[3] = WTF::String::fromUTF8(kUTF8HelloWorld);
     71 
     72   return strs;
     73 }
     74 
     75 WTF::HashMap<WTF::String, WTF::String> ConstructStringMap() {
     76   WTF::HashMap<WTF::String, WTF::String> str_map;
     77   // A null string as value.
     78   str_map.add("0", WTF::String());
     79   str_map.add("1", kHelloWorld);
     80   str_map.add("2", WTF::String::fromUTF8(kUTF8HelloWorld));
     81 
     82   return str_map;
     83 }
     84 
     85 void ExpectString(const WTF::String& expected_string,
     86                   const base::Closure& closure,
     87                   const WTF::String& string) {
     88   EXPECT_EQ(expected_string, string);
     89   closure.Run();
     90 }
     91 
     92 void ExpectStringArray(WTF::Optional<WTF::Vector<WTF::String>>* expected_arr,
     93                        const base::Closure& closure,
     94                        const WTF::Optional<WTF::Vector<WTF::String>>& arr) {
     95   EXPECT_EQ(*expected_arr, arr);
     96   closure.Run();
     97 }
     98 
     99 void ExpectStringMap(
    100     WTF::Optional<WTF::HashMap<WTF::String, WTF::String>>* expected_map,
    101     const base::Closure& closure,
    102     const WTF::Optional<WTF::HashMap<WTF::String, WTF::String>>& map) {
    103   EXPECT_EQ(*expected_map, map);
    104   closure.Run();
    105 }
    106 
    107 }  // namespace
    108 
    109 TEST_F(WTFTypesTest, Serialization_WTFArrayToWTFArray) {
    110   WTFArray<WTF::String> strs = ConstructStringArray();
    111   auto cloned_strs = strs.Clone();
    112 
    113   mojo::internal::SerializationContext context;
    114   size_t size = mojo::internal::PrepareToSerialize<Array<mojo::String>>(
    115       cloned_strs, &context);
    116 
    117   mojo::internal::FixedBufferForTesting buf(size);
    118   typename mojo::internal::MojomTypeTraits<Array<mojo::String>>::Data* data;
    119   mojo::internal::ContainerValidateParams validate_params(
    120       0, true, new mojo::internal::ContainerValidateParams(0, false, nullptr));
    121   mojo::internal::Serialize<Array<mojo::String>>(cloned_strs, &buf, &data,
    122                                                  &validate_params, &context);
    123 
    124   WTFArray<WTF::String> strs2;
    125   mojo::internal::Deserialize<Array<mojo::String>>(data, &strs2, &context);
    126 
    127   EXPECT_TRUE(strs.Equals(strs2));
    128 }
    129 
    130 TEST_F(WTFTypesTest, Serialization_WTFVectorToWTFVector) {
    131   WTF::Vector<WTF::String> strs = ConstructStringArray();
    132   auto cloned_strs = strs;
    133 
    134   mojo::internal::SerializationContext context;
    135   size_t size = mojo::internal::PrepareToSerialize<Array<mojo::String>>(
    136       cloned_strs, &context);
    137 
    138   mojo::internal::FixedBufferForTesting buf(size);
    139   typename mojo::internal::MojomTypeTraits<Array<mojo::String>>::Data* data;
    140   mojo::internal::ContainerValidateParams validate_params(
    141       0, true, new mojo::internal::ContainerValidateParams(0, false, nullptr));
    142   mojo::internal::Serialize<Array<mojo::String>>(cloned_strs, &buf, &data,
    143                                                  &validate_params, &context);
    144 
    145   WTF::Vector<WTF::String> strs2;
    146   mojo::internal::Deserialize<Array<mojo::String>>(data, &strs2, &context);
    147 
    148   EXPECT_EQ(strs, strs2);
    149 }
    150 
    151 TEST_F(WTFTypesTest, Serialization_WTFArrayToMojoArray) {
    152   WTFArray<WTF::String> strs = ConstructStringArray();
    153 
    154   mojo::internal::SerializationContext context;
    155   size_t size =
    156       mojo::internal::PrepareToSerialize<Array<mojo::String>>(strs, &context);
    157 
    158   mojo::internal::FixedBufferForTesting buf(size);
    159   typename mojo::internal::MojomTypeTraits<Array<mojo::String>>::Data* data;
    160   mojo::internal::ContainerValidateParams validate_params(
    161       0, true, new mojo::internal::ContainerValidateParams(0, false, nullptr));
    162   mojo::internal::Serialize<Array<mojo::String>>(strs, &buf, &data,
    163                                                  &validate_params, &context);
    164 
    165   Array<mojo::String> strs2;
    166   mojo::internal::Deserialize<Array<mojo::String>>(data, &strs2, &context);
    167 
    168   ASSERT_EQ(4u, strs2.size());
    169   EXPECT_TRUE(strs2[0].is_null());
    170   EXPECT_TRUE("" == strs2[1]);
    171   EXPECT_TRUE(kHelloWorld == strs2[2]);
    172   EXPECT_TRUE(kUTF8HelloWorld == strs2[3]);
    173 }
    174 
    175 TEST_F(WTFTypesTest, Serialization_WTFMapToWTFMap) {
    176   using WTFType = WTFMap<WTF::String, WTF::String>;
    177   using MojomType = Map<mojo::String, mojo::String>;
    178 
    179   WTFType str_map = ConstructStringMap();
    180   WTFType cloned_str_map = str_map.Clone();
    181 
    182   mojo::internal::SerializationContext context;
    183   size_t size =
    184       mojo::internal::PrepareToSerialize<MojomType>(cloned_str_map, &context);
    185 
    186   mojo::internal::FixedBufferForTesting buf(size);
    187   typename mojo::internal::MojomTypeTraits<MojomType>::Data* data;
    188   mojo::internal::ContainerValidateParams validate_params(
    189       new mojo::internal::ContainerValidateParams(
    190           0, false,
    191           new mojo::internal::ContainerValidateParams(0, false, nullptr)),
    192       new mojo::internal::ContainerValidateParams(
    193           0, true,
    194           new mojo::internal::ContainerValidateParams(0, false, nullptr)));
    195   mojo::internal::Serialize<MojomType>(cloned_str_map, &buf, &data,
    196                                        &validate_params, &context);
    197 
    198   WTFType str_map2;
    199   mojo::internal::Deserialize<MojomType>(data, &str_map2, &context);
    200 
    201   EXPECT_TRUE(str_map.Equals(str_map2));
    202 }
    203 
    204 TEST_F(WTFTypesTest, Serialization_WTFMapToMojoMap) {
    205   using WTFType = WTFMap<WTF::String, WTF::String>;
    206   using MojomType = Map<mojo::String, mojo::String>;
    207 
    208   WTFType str_map = ConstructStringMap();
    209 
    210   mojo::internal::SerializationContext context;
    211   size_t size =
    212       mojo::internal::PrepareToSerialize<MojomType>(str_map, &context);
    213 
    214   mojo::internal::FixedBufferForTesting buf(size);
    215   typename mojo::internal::MojomTypeTraits<MojomType>::Data* data;
    216   mojo::internal::ContainerValidateParams validate_params(
    217       new mojo::internal::ContainerValidateParams(
    218           0, false,
    219           new mojo::internal::ContainerValidateParams(0, false, nullptr)),
    220       new mojo::internal::ContainerValidateParams(
    221           0, true,
    222           new mojo::internal::ContainerValidateParams(0, false, nullptr)));
    223   mojo::internal::Serialize<MojomType>(str_map, &buf, &data, &validate_params,
    224                                        &context);
    225 
    226   MojomType str_map2;
    227   mojo::internal::Deserialize<MojomType>(data, &str_map2, &context);
    228 
    229   ASSERT_EQ(3u, str_map2.size());
    230   EXPECT_TRUE(str_map2["0"].is_null());
    231   EXPECT_TRUE(kHelloWorld == str_map2["1"]);
    232   EXPECT_TRUE(kUTF8HelloWorld == str_map2["2"]);
    233 }
    234 
    235 TEST_F(WTFTypesTest, Serialization_PublicAPI) {
    236   blink::TestWTFStructPtr input(blink::TestWTFStruct::New());
    237   input->str = kHelloWorld;
    238   input->integer = 42;
    239 
    240   blink::TestWTFStructPtr cloned_input = input.Clone();
    241 
    242   WTFArray<uint8_t> data = blink::TestWTFStruct::Serialize(&input);
    243 
    244   blink::TestWTFStructPtr output;
    245   ASSERT_TRUE(blink::TestWTFStruct::Deserialize(std::move(data), &output));
    246   EXPECT_TRUE(cloned_input.Equals(output));
    247 }
    248 
    249 TEST_F(WTFTypesTest, SendString) {
    250   blink::TestWTFPtr ptr;
    251   TestWTFImpl impl(ConvertInterfaceRequest<TestWTF>(GetProxy(&ptr)));
    252 
    253   WTF::Vector<WTF::String> strs = ConstructStringArray();
    254 
    255   for (size_t i = 0; i < strs.size(); ++i) {
    256     base::RunLoop loop;
    257     // Test that a WTF::String is unchanged after the following conversion:
    258     //   - serialized;
    259     //   - deserialized as base::Optional<std::string>;
    260     //   - serialized;
    261     //   - deserialized as WTF::String.
    262     ptr->EchoString(strs[i],
    263                     base::Bind(&ExpectString, strs[i], loop.QuitClosure()));
    264     loop.Run();
    265   }
    266 }
    267 
    268 TEST_F(WTFTypesTest, SendStringArray) {
    269   blink::TestWTFPtr ptr;
    270   TestWTFImpl impl(ConvertInterfaceRequest<TestWTF>(GetProxy(&ptr)));
    271 
    272   WTF::Optional<WTF::Vector<WTF::String>> arrs[3];
    273   // arrs[0] is empty.
    274   arrs[0].emplace();
    275   // arrs[1] is null.
    276   arrs[2] = ConstructStringArray();
    277 
    278   for (size_t i = 0; i < arraysize(arrs); ++i) {
    279     base::RunLoop loop;
    280     // Test that a WTF::Optional<WTF::Vector<WTF::String>> is unchanged after
    281     // the following conversion:
    282     //   - serialized;
    283     //   - deserialized as
    284     //     base::Optional<std::vector<base::Optional<std::string>>>;
    285     //   - serialized;
    286     //   - deserialized as WTF::Optional<WTF::Vector<WTF::String>>.
    287     ptr->EchoStringArray(
    288         arrs[i], base::Bind(&ExpectStringArray, base::Unretained(&arrs[i]),
    289                             loop.QuitClosure()));
    290     loop.Run();
    291   }
    292 }
    293 
    294 TEST_F(WTFTypesTest, SendStringMap) {
    295   blink::TestWTFPtr ptr;
    296   TestWTFImpl impl(ConvertInterfaceRequest<TestWTF>(GetProxy(&ptr)));
    297 
    298   WTF::Optional<WTF::HashMap<WTF::String, WTF::String>> maps[3];
    299   // maps[0] is empty.
    300   maps[0].emplace();
    301   // maps[1] is null.
    302   maps[2] = ConstructStringMap();
    303 
    304   for (size_t i = 0; i < arraysize(maps); ++i) {
    305     base::RunLoop loop;
    306     // Test that a WTF::Optional<WTF::HashMap<WTF::String, WTF::String>> is
    307     // unchanged after the following conversion:
    308     //   - serialized;
    309     //   - deserialized as base::Optional<
    310     //     std::unordered_map<std::string, base::Optional<std::string>>>;
    311     //   - serialized;
    312     //   - deserialized as WTF::Optional<WTF::HashMap<WTF::String,
    313     //     WTF::String>>.
    314     ptr->EchoStringMap(maps[i],
    315                        base::Bind(&ExpectStringMap, base::Unretained(&maps[i]),
    316                                   loop.QuitClosure()));
    317     loop.Run();
    318   }
    319 }
    320 
    321 }  // namespace test
    322 }  // namespace mojo
    323