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/files/file_path.h" 6 #include "base/message_loop/message_loop.h" 7 #include "base/run_loop.h" 8 #include "base/values.h" 9 #include "mojo/common/common_custom_types.mojom.h" 10 #include "mojo/common/test_common_custom_types.mojom.h" 11 #include "mojo/public/cpp/bindings/binding.h" 12 #include "testing/gtest/include/gtest/gtest.h" 13 14 namespace mojo { 15 namespace common { 16 namespace test { 17 namespace { 18 19 template <typename T> 20 struct BounceTestTraits { 21 static void ExpectEquality(const T& a, const T& b) { 22 EXPECT_EQ(a, b); 23 } 24 }; 25 26 template <> 27 struct BounceTestTraits<base::DictionaryValue> { 28 static void ExpectEquality(const base::DictionaryValue& a, 29 const base::DictionaryValue& b) { 30 EXPECT_TRUE(a.Equals(&b)); 31 } 32 }; 33 34 template <> 35 struct BounceTestTraits<base::ListValue> { 36 static void ExpectEquality(const base::ListValue& a, 37 const base::ListValue& b) { 38 EXPECT_TRUE(a.Equals(&b)); 39 } 40 }; 41 42 template <typename T> 43 void DoExpectResponse(T* expected_value, 44 const base::Closure& closure, 45 const T& value) { 46 BounceTestTraits<T>::ExpectEquality(*expected_value, value); 47 closure.Run(); 48 } 49 50 template <typename T> 51 base::Callback<void(const T&)> ExpectResponse(T* expected_value, 52 const base::Closure& closure) { 53 return base::Bind(&DoExpectResponse<T>, expected_value, closure); 54 } 55 56 class TestFilePathImpl : public TestFilePath { 57 public: 58 explicit TestFilePathImpl(TestFilePathRequest request) 59 : binding_(this, std::move(request)) {} 60 61 // TestFilePath implementation: 62 void BounceFilePath(const base::FilePath& in, 63 const BounceFilePathCallback& callback) override { 64 callback.Run(in); 65 } 66 67 private: 68 mojo::Binding<TestFilePath> binding_; 69 }; 70 71 class TestTimeImpl : public TestTime { 72 public: 73 explicit TestTimeImpl(TestTimeRequest request) 74 : binding_(this, std::move(request)) {} 75 76 // TestTime implementation: 77 void BounceTime(const base::Time& in, 78 const BounceTimeCallback& callback) override { 79 callback.Run(in); 80 } 81 82 void BounceTimeDelta(const base::TimeDelta& in, 83 const BounceTimeDeltaCallback& callback) override { 84 callback.Run(in); 85 } 86 87 void BounceTimeTicks(const base::TimeTicks& in, 88 const BounceTimeTicksCallback& callback) override { 89 callback.Run(in); 90 } 91 92 private: 93 mojo::Binding<TestTime> binding_; 94 }; 95 96 class TestValueImpl : public TestValue { 97 public: 98 explicit TestValueImpl(TestValueRequest request) 99 : binding_(this, std::move(request)) {} 100 101 // TestValue implementation: 102 void BounceDictionaryValue( 103 const base::DictionaryValue& in, 104 const BounceDictionaryValueCallback& callback) override { 105 callback.Run(in); 106 } 107 void BounceListValue(const base::ListValue& in, 108 const BounceListValueCallback& callback) override { 109 callback.Run(in); 110 } 111 112 private: 113 mojo::Binding<TestValue> binding_; 114 }; 115 116 class CommonCustomTypesTest : public testing::Test { 117 protected: 118 CommonCustomTypesTest() {} 119 ~CommonCustomTypesTest() override {} 120 121 private: 122 base::MessageLoop message_loop_; 123 124 DISALLOW_COPY_AND_ASSIGN(CommonCustomTypesTest); 125 }; 126 127 } // namespace 128 129 TEST_F(CommonCustomTypesTest, FilePath) { 130 base::RunLoop run_loop; 131 132 TestFilePathPtr ptr; 133 TestFilePathImpl impl(GetProxy(&ptr)); 134 135 base::FilePath dir(FILE_PATH_LITERAL("hello")); 136 base::FilePath file = dir.Append(FILE_PATH_LITERAL("world")); 137 138 ptr->BounceFilePath(file, ExpectResponse(&file, run_loop.QuitClosure())); 139 140 run_loop.Run(); 141 } 142 143 TEST_F(CommonCustomTypesTest, Time) { 144 base::RunLoop run_loop; 145 146 TestTimePtr ptr; 147 TestTimeImpl impl(GetProxy(&ptr)); 148 149 base::Time t = base::Time::Now(); 150 151 ptr->BounceTime(t, ExpectResponse(&t, run_loop.QuitClosure())); 152 153 run_loop.Run(); 154 } 155 156 TEST_F(CommonCustomTypesTest, TimeDelta) { 157 base::RunLoop run_loop; 158 159 TestTimePtr ptr; 160 TestTimeImpl impl(GetProxy(&ptr)); 161 162 base::TimeDelta t = base::TimeDelta::FromDays(123); 163 164 ptr->BounceTimeDelta(t, ExpectResponse(&t, run_loop.QuitClosure())); 165 166 run_loop.Run(); 167 } 168 169 TEST_F(CommonCustomTypesTest, TimeTicks) { 170 base::RunLoop run_loop; 171 172 TestTimePtr ptr; 173 TestTimeImpl impl(GetProxy(&ptr)); 174 175 base::TimeTicks t = base::TimeTicks::Now(); 176 177 ptr->BounceTimeTicks(t, ExpectResponse(&t, run_loop.QuitClosure())); 178 179 run_loop.Run(); 180 } 181 182 TEST_F(CommonCustomTypesTest, Value) { 183 TestValuePtr ptr; 184 TestValueImpl impl(GetProxy(&ptr)); 185 186 base::DictionaryValue dict; 187 dict.SetBoolean("bool", false); 188 dict.SetInteger("int", 2); 189 dict.SetString("string", "some string"); 190 dict.SetBoolean("nested.bool", true); 191 dict.SetInteger("nested.int", 9); 192 dict.Set("some_binary", base::BinaryValue::CreateWithCopiedBuffer("mojo", 4)); 193 { 194 std::unique_ptr<base::ListValue> dict_list(new base::ListValue()); 195 dict_list->AppendString("string"); 196 dict_list->AppendBoolean(true); 197 dict.Set("list", std::move(dict_list)); 198 } 199 { 200 base::RunLoop run_loop; 201 ptr->BounceDictionaryValue( 202 dict, ExpectResponse(&dict, run_loop.QuitClosure())); 203 run_loop.Run(); 204 } 205 206 base::ListValue list; 207 list.AppendString("string"); 208 list.AppendDouble(42.1); 209 list.AppendBoolean(true); 210 list.Append(base::BinaryValue::CreateWithCopiedBuffer("mojo", 4)); 211 { 212 std::unique_ptr<base::DictionaryValue> list_dict( 213 new base::DictionaryValue()); 214 list_dict->SetString("string", "str"); 215 list.Append(std::move(list_dict)); 216 } 217 { 218 base::RunLoop run_loop; 219 ptr->BounceListValue(list, ExpectResponse(&list, run_loop.QuitClosure())); 220 run_loop.Run(); 221 } 222 } 223 224 } // namespace test 225 } // namespace common 226 } // namespace mojo 227