aboutsummaryrefslogtreecommitdiff
path: root/mojo/public/cpp/bindings
diff options
context:
space:
mode:
authorHidehiko Abe <hidehiko@google.com>2018-04-17 16:34:13 +0900
committerHidehiko Abe <hidehiko@google.com>2018-04-17 16:56:42 +0900
commit1e4a1e50aed7593adac78af6f319adb67f03d7bb (patch)
tree1398145f7694eac739142d9bcbfcdf3d8cf4b9a8 /mojo/public/cpp/bindings
parent0325b56b0518f5ca16701e5048fcf81cc96fd725 (diff)
downloadlibmojo-1e4a1e50aed7593adac78af6f319adb67f03d7bb.tar.gz
Reduce diffs from Chrome r456626.
Currently, mojo/ directory is more diverged than it should be. This CL fills the unnecessary gaps. Bug: 73606903 Test: Built locally. Treehugger. Made sure the diff on eyes. Change-Id: I65877b0ff853ecfd6661259f97b0078631a158a7
Diffstat (limited to 'mojo/public/cpp/bindings')
-rw-r--r--mojo/public/cpp/bindings/associated_binding_set.h29
-rw-r--r--mojo/public/cpp/bindings/lib/associated_binding.cc62
-rw-r--r--mojo/public/cpp/bindings/lib/wtf_hash_util.h132
-rw-r--r--mojo/public/cpp/bindings/strong_associated_binding.h125
-rw-r--r--mojo/public/cpp/bindings/strong_binding_set.h26
-rw-r--r--mojo/public/cpp/bindings/tests/BUILD.gn24
-rw-r--r--mojo/public/cpp/bindings/tests/array_common_test.h404
-rw-r--r--mojo/public/cpp/bindings/tests/array_unittest.cc131
-rw-r--r--mojo/public/cpp/bindings/tests/associated_interface_unittest.cc693
-rw-r--r--mojo/public/cpp/bindings/tests/bind_task_runner_unittest.cc10
-rw-r--r--mojo/public/cpp/bindings/tests/binding_callback_unittest.cc26
-rw-r--r--mojo/public/cpp/bindings/tests/binding_set_unittest.cc416
-rw-r--r--mojo/public/cpp/bindings/tests/binding_unittest.cc325
-rw-r--r--mojo/public/cpp/bindings/tests/bindings_perftest.cc155
-rw-r--r--mojo/public/cpp/bindings/tests/connector_unittest.cc26
-rw-r--r--mojo/public/cpp/bindings/tests/constant_unittest.cc28
-rw-r--r--mojo/public/cpp/bindings/tests/data_view_unittest.cc303
-rw-r--r--mojo/public/cpp/bindings/tests/e2e_perftest.cc18
-rw-r--r--mojo/public/cpp/bindings/tests/equals_unittest.cc57
-rw-r--r--mojo/public/cpp/bindings/tests/handle_passing_unittest.cc42
-rw-r--r--mojo/public/cpp/bindings/tests/hash_unittest.cc35
-rw-r--r--mojo/public/cpp/bindings/tests/interface_ptr_unittest.cc309
-rw-r--r--mojo/public/cpp/bindings/tests/map_common_test.h230
-rw-r--r--mojo/public/cpp/bindings/tests/map_unittest.cc225
-rw-r--r--mojo/public/cpp/bindings/tests/message_queue.cc8
-rw-r--r--mojo/public/cpp/bindings/tests/message_queue.h5
-rw-r--r--mojo/public/cpp/bindings/tests/mojo_test_blink_export.h29
-rw-r--r--mojo/public/cpp/bindings/tests/mojo_test_export.h29
-rw-r--r--mojo/public/cpp/bindings/tests/multiplex_router_unittest.cc96
-rw-r--r--mojo/public/cpp/bindings/tests/pickle_unittest.cc75
-rw-r--r--mojo/public/cpp/bindings/tests/pickled_types_blink.h5
-rw-r--r--mojo/public/cpp/bindings/tests/rect_blink.h19
-rw-r--r--mojo/public/cpp/bindings/tests/rect_blink.typemap15
-rw-r--r--mojo/public/cpp/bindings/tests/rect_blink_traits.h5
-rw-r--r--mojo/public/cpp/bindings/tests/rect_chromium.h19
-rw-r--r--mojo/public/cpp/bindings/tests/rect_chromium.typemap15
-rw-r--r--mojo/public/cpp/bindings/tests/rect_chromium_traits.h2
-rw-r--r--mojo/public/cpp/bindings/tests/report_bad_message_unittest.cc194
-rw-r--r--mojo/public/cpp/bindings/tests/request_response_unittest.cc8
-rw-r--r--mojo/public/cpp/bindings/tests/router_test_util.cc13
-rw-r--r--mojo/public/cpp/bindings/tests/router_unittest.cc316
-rw-r--r--mojo/public/cpp/bindings/tests/sample_service_unittest.cc36
-rw-r--r--mojo/public/cpp/bindings/tests/serialization_warning_unittest.cc95
-rw-r--r--mojo/public/cpp/bindings/tests/shared_rect.h43
-rw-r--r--mojo/public/cpp/bindings/tests/shared_rect_traits.h33
-rw-r--r--mojo/public/cpp/bindings/tests/stl_converters_unittest.cc93
-rw-r--r--mojo/public/cpp/bindings/tests/string_unittest.cc131
-rw-r--r--mojo/public/cpp/bindings/tests/struct_traits_unittest.cc211
-rw-r--r--mojo/public/cpp/bindings/tests/struct_unittest.cc274
-rw-r--r--mojo/public/cpp/bindings/tests/struct_with_traits.typemap6
-rw-r--r--mojo/public/cpp/bindings/tests/struct_with_traits_impl.cc15
-rw-r--r--mojo/public/cpp/bindings/tests/struct_with_traits_impl.h68
-rw-r--r--mojo/public/cpp/bindings/tests/struct_with_traits_impl_traits.cc32
-rw-r--r--mojo/public/cpp/bindings/tests/struct_with_traits_impl_traits.h99
-rw-r--r--mojo/public/cpp/bindings/tests/sync_method_unittest.cc33
-rw-r--r--mojo/public/cpp/bindings/tests/test_native_types_blink.typemap2
-rw-r--r--mojo/public/cpp/bindings/tests/test_native_types_chromium.typemap5
-rw-r--r--mojo/public/cpp/bindings/tests/type_conversion_unittest.cc75
-rw-r--r--mojo/public/cpp/bindings/tests/union_unittest.cc374
-rw-r--r--mojo/public/cpp/bindings/tests/validation_context_unittest.cc109
-rw-r--r--mojo/public/cpp/bindings/tests/validation_unittest.cc25
-rw-r--r--mojo/public/cpp/bindings/tests/versioning_apptest.cc6
-rw-r--r--mojo/public/cpp/bindings/tests/versioning_test_service.cc16
-rw-r--r--mojo/public/cpp/bindings/tests/wtf_array_unittest.cc62
-rw-r--r--mojo/public/cpp/bindings/tests/wtf_hash_unittest.cc60
-rw-r--r--mojo/public/cpp/bindings/tests/wtf_map_unittest.cc68
-rw-r--r--mojo/public/cpp/bindings/tests/wtf_types_unittest.cc139
-rw-r--r--mojo/public/cpp/bindings/unique_ptr_impl_ref_traits.h22
68 files changed, 4080 insertions, 2736 deletions
diff --git a/mojo/public/cpp/bindings/associated_binding_set.h b/mojo/public/cpp/bindings/associated_binding_set.h
new file mode 100644
index 0000000..59600c6
--- /dev/null
+++ b/mojo/public/cpp/bindings/associated_binding_set.h
@@ -0,0 +1,29 @@
+// Copyright 2016 The Chromium 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 MOJO_PUBLIC_CPP_BINDINGS_ASSOCIATED_BINDING_SET_H_
+#define MOJO_PUBLIC_CPP_BINDINGS_ASSOCIATED_BINDING_SET_H_
+
+#include "mojo/public/cpp/bindings/associated_binding.h"
+#include "mojo/public/cpp/bindings/associated_interface_ptr.h"
+#include "mojo/public/cpp/bindings/associated_interface_request.h"
+#include "mojo/public/cpp/bindings/binding_set.h"
+
+namespace mojo {
+
+template <typename Interface, typename ImplRefTraits>
+struct BindingSetTraits<AssociatedBinding<Interface, ImplRefTraits>> {
+ using ProxyType = AssociatedInterfacePtr<Interface>;
+ using RequestType = AssociatedInterfaceRequest<Interface>;
+ using BindingType = AssociatedBinding<Interface, ImplRefTraits>;
+ using ImplPointerType = typename BindingType::ImplPointerType;
+};
+
+template <typename Interface, typename ContextType = void>
+using AssociatedBindingSet =
+ BindingSetBase<Interface, AssociatedBinding<Interface>, ContextType>;
+
+} // namespace mojo
+
+#endif // MOJO_PUBLIC_CPP_BINDINGS_ASSOCIATED_BINDING_SET_H_
diff --git a/mojo/public/cpp/bindings/lib/associated_binding.cc b/mojo/public/cpp/bindings/lib/associated_binding.cc
new file mode 100644
index 0000000..6788e68
--- /dev/null
+++ b/mojo/public/cpp/bindings/lib/associated_binding.cc
@@ -0,0 +1,62 @@
+// Copyright 2017 The Chromium 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 "mojo/public/cpp/bindings/associated_binding.h"
+
+namespace mojo {
+
+AssociatedBindingBase::AssociatedBindingBase() {}
+
+AssociatedBindingBase::~AssociatedBindingBase() {}
+
+void AssociatedBindingBase::AddFilter(std::unique_ptr<MessageReceiver> filter) {
+ DCHECK(endpoint_client_);
+ endpoint_client_->AddFilter(std::move(filter));
+}
+
+void AssociatedBindingBase::Close() {
+ endpoint_client_.reset();
+}
+
+void AssociatedBindingBase::CloseWithReason(uint32_t custom_reason,
+ const std::string& description) {
+ if (endpoint_client_)
+ endpoint_client_->CloseWithReason(custom_reason, description);
+ Close();
+}
+
+void AssociatedBindingBase::set_connection_error_handler(
+ const base::Closure& error_handler) {
+ DCHECK(is_bound());
+ endpoint_client_->set_connection_error_handler(error_handler);
+}
+
+void AssociatedBindingBase::set_connection_error_with_reason_handler(
+ const ConnectionErrorWithReasonCallback& error_handler) {
+ DCHECK(is_bound());
+ endpoint_client_->set_connection_error_with_reason_handler(error_handler);
+}
+
+void AssociatedBindingBase::FlushForTesting() {
+ endpoint_client_->FlushForTesting();
+}
+
+void AssociatedBindingBase::BindImpl(
+ ScopedInterfaceEndpointHandle handle,
+ MessageReceiverWithResponderStatus* receiver,
+ std::unique_ptr<MessageReceiver> payload_validator,
+ bool expect_sync_requests,
+ scoped_refptr<base::SingleThreadTaskRunner> runner,
+ uint32_t interface_version) {
+ if (!handle.is_valid()) {
+ endpoint_client_.reset();
+ return;
+ }
+
+ endpoint_client_.reset(new InterfaceEndpointClient(
+ std::move(handle), receiver, std::move(payload_validator),
+ expect_sync_requests, std::move(runner), interface_version));
+}
+
+} // namespace mojo
diff --git a/mojo/public/cpp/bindings/lib/wtf_hash_util.h b/mojo/public/cpp/bindings/lib/wtf_hash_util.h
new file mode 100644
index 0000000..cc590da
--- /dev/null
+++ b/mojo/public/cpp/bindings/lib/wtf_hash_util.h
@@ -0,0 +1,132 @@
+// Copyright 2016 The Chromium 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 MOJO_PUBLIC_CPP_BINDINGS_LIB_WTF_HASH_UTIL_H_
+#define MOJO_PUBLIC_CPP_BINDINGS_LIB_WTF_HASH_UTIL_H_
+
+#include <type_traits>
+
+#include "mojo/public/cpp/bindings/lib/hash_util.h"
+#include "mojo/public/cpp/bindings/struct_ptr.h"
+#include "third_party/WebKit/Source/wtf/HashFunctions.h"
+#include "third_party/WebKit/Source/wtf/text/StringHash.h"
+#include "third_party/WebKit/Source/wtf/text/WTFString.h"
+
+namespace mojo {
+namespace internal {
+
+template <typename T>
+size_t WTFHashCombine(size_t seed, const T& value) {
+ // Based on proposal in:
+ // http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1756.pdf
+ //
+ // TODO(tibell): We'd like to use WTF::DefaultHash instead of std::hash, but
+ // there is no general template specialization of DefaultHash for enums
+ // and there can't be an instance for bool.
+ return seed ^ (std::hash<T>()(value) + (seed << 6) + (seed >> 2));
+}
+
+template <typename T, bool has_hash_method = HasHashMethod<T>::value>
+struct WTFHashTraits;
+
+template <typename T>
+size_t WTFHash(size_t seed, const T& value);
+
+template <typename T>
+struct WTFHashTraits<T, true> {
+ static size_t Hash(size_t seed, const T& value) { return value.Hash(seed); }
+};
+
+template <typename T>
+struct WTFHashTraits<T, false> {
+ static size_t Hash(size_t seed, const T& value) {
+ return WTFHashCombine(seed, value);
+ }
+};
+
+template <>
+struct WTFHashTraits<WTF::String, false> {
+ static size_t Hash(size_t seed, const WTF::String& value) {
+ return HashCombine(seed, WTF::StringHash::hash(value));
+ }
+};
+
+template <typename T>
+size_t WTFHash(size_t seed, const T& value) {
+ return WTFHashTraits<T>::Hash(seed, value);
+}
+
+template <typename T>
+struct StructPtrHashFn {
+ static unsigned hash(const StructPtr<T>& value) {
+ return value.Hash(kHashSeed);
+ }
+ static bool equal(const StructPtr<T>& left, const StructPtr<T>& right) {
+ return left.Equals(right);
+ }
+ static const bool safeToCompareToEmptyOrDeleted = false;
+};
+
+template <typename T>
+struct InlinedStructPtrHashFn {
+ static unsigned hash(const InlinedStructPtr<T>& value) {
+ return value.Hash(kHashSeed);
+ }
+ static bool equal(const InlinedStructPtr<T>& left,
+ const InlinedStructPtr<T>& right) {
+ return left.Equals(right);
+ }
+ static const bool safeToCompareToEmptyOrDeleted = false;
+};
+
+} // namespace internal
+} // namespace mojo
+
+namespace WTF {
+
+template <typename T>
+struct DefaultHash<mojo::StructPtr<T>> {
+ using Hash = mojo::internal::StructPtrHashFn<T>;
+};
+
+template <typename T>
+struct HashTraits<mojo::StructPtr<T>>
+ : public GenericHashTraits<mojo::StructPtr<T>> {
+ static const bool hasIsEmptyValueFunction = true;
+ static bool isEmptyValue(const mojo::StructPtr<T>& value) {
+ return value.is_null();
+ }
+ static void constructDeletedValue(mojo::StructPtr<T>& slot, bool) {
+ mojo::internal::StructPtrWTFHelper<T>::ConstructDeletedValue(slot);
+ }
+ static bool isDeletedValue(const mojo::StructPtr<T>& value) {
+ return mojo::internal::StructPtrWTFHelper<T>::IsHashTableDeletedValue(
+ value);
+ }
+};
+
+template <typename T>
+struct DefaultHash<mojo::InlinedStructPtr<T>> {
+ using Hash = mojo::internal::InlinedStructPtrHashFn<T>;
+};
+
+template <typename T>
+struct HashTraits<mojo::InlinedStructPtr<T>>
+ : public GenericHashTraits<mojo::InlinedStructPtr<T>> {
+ static const bool hasIsEmptyValueFunction = true;
+ static bool isEmptyValue(const mojo::InlinedStructPtr<T>& value) {
+ return value.is_null();
+ }
+ static void constructDeletedValue(mojo::InlinedStructPtr<T>& slot, bool) {
+ mojo::internal::InlinedStructPtrWTFHelper<T>::ConstructDeletedValue(slot);
+ }
+ static bool isDeletedValue(const mojo::InlinedStructPtr<T>& value) {
+ return mojo::internal::InlinedStructPtrWTFHelper<
+ T>::IsHashTableDeletedValue(value);
+ }
+};
+
+} // namespace WTF
+
+#endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_WTF_HASH_UTIL_H_
diff --git a/mojo/public/cpp/bindings/strong_associated_binding.h b/mojo/public/cpp/bindings/strong_associated_binding.h
new file mode 100644
index 0000000..a1e299b
--- /dev/null
+++ b/mojo/public/cpp/bindings/strong_associated_binding.h
@@ -0,0 +1,125 @@
+// Copyright 2016 The Chromium 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 MOJO_PUBLIC_CPP_BINDINGS_STRONG_ASSOCIATED_BINDING_H_
+#define MOJO_PUBLIC_CPP_BINDINGS_STRONG_ASSOCIATED_BINDING_H_
+
+#include <memory>
+#include <string>
+#include <utility>
+
+#include "base/bind.h"
+#include "base/callback.h"
+#include "base/logging.h"
+#include "base/macros.h"
+#include "base/memory/weak_ptr.h"
+#include "mojo/public/cpp/bindings/associated_binding.h"
+#include "mojo/public/cpp/bindings/associated_interface_request.h"
+#include "mojo/public/cpp/bindings/connection_error_callback.h"
+#include "mojo/public/cpp/system/core.h"
+
+namespace mojo {
+
+template <typename Interface>
+class StrongAssociatedBinding;
+
+template <typename Interface>
+using StrongAssociatedBindingPtr =
+ base::WeakPtr<StrongAssociatedBinding<Interface>>;
+
+// This connects an interface implementation strongly to an associated pipe.
+// When a connection error is detected the implementation is deleted. If the
+// task runner that a StrongAssociatedBinding is bound on is stopped, the
+// connection error handler will not be invoked and the implementation will not
+// be deleted.
+//
+// To use, call StrongAssociatedBinding<T>::Create() (see below) or the helper
+// MakeStrongAssociatedBinding function:
+//
+// mojo::MakeStrongAssociatedBinding(base::MakeUnique<FooImpl>(),
+// std::move(foo_request));
+//
+template <typename Interface>
+class StrongAssociatedBinding {
+ public:
+ // Create a new StrongAssociatedBinding instance. The instance owns itself,
+ // cleaning up only in the event of a pipe connection error. Returns a WeakPtr
+ // to the new StrongAssociatedBinding instance.
+ static StrongAssociatedBindingPtr<Interface> Create(
+ std::unique_ptr<Interface> impl,
+ AssociatedInterfaceRequest<Interface> request) {
+ StrongAssociatedBinding* binding =
+ new StrongAssociatedBinding(std::move(impl), std::move(request));
+ return binding->weak_factory_.GetWeakPtr();
+ }
+
+ // Note: The error handler must not delete the interface implementation.
+ //
+ // This method may only be called after this StrongAssociatedBinding has been
+ // bound to a message pipe.
+ void set_connection_error_handler(const base::Closure& error_handler) {
+ DCHECK(binding_.is_bound());
+ connection_error_handler_ = error_handler;
+ connection_error_with_reason_handler_.Reset();
+ }
+
+ void set_connection_error_with_reason_handler(
+ const ConnectionErrorWithReasonCallback& error_handler) {
+ DCHECK(binding_.is_bound());
+ connection_error_with_reason_handler_ = error_handler;
+ connection_error_handler_.Reset();
+ }
+
+ // Forces the binding to close. This destroys the StrongBinding instance.
+ void Close() { delete this; }
+
+ Interface* impl() { return impl_.get(); }
+
+ // Sends a message on the underlying message pipe and runs the current
+ // message loop until its response is received. This can be used in tests to
+ // verify that no message was sent on a message pipe in response to some
+ // stimulus.
+ void FlushForTesting() { binding_.FlushForTesting(); }
+
+ private:
+ StrongAssociatedBinding(std::unique_ptr<Interface> impl,
+ AssociatedInterfaceRequest<Interface> request)
+ : impl_(std::move(impl)),
+ binding_(impl_.get(), std::move(request)),
+ weak_factory_(this) {
+ binding_.set_connection_error_with_reason_handler(base::Bind(
+ &StrongAssociatedBinding::OnConnectionError, base::Unretained(this)));
+ }
+
+ ~StrongAssociatedBinding() {}
+
+ void OnConnectionError(uint32_t custom_reason,
+ const std::string& description) {
+ if (!connection_error_handler_.is_null())
+ connection_error_handler_.Run();
+ else if (!connection_error_with_reason_handler_.is_null())
+ connection_error_with_reason_handler_.Run(custom_reason, description);
+ Close();
+ }
+
+ std::unique_ptr<Interface> impl_;
+ base::Closure connection_error_handler_;
+ ConnectionErrorWithReasonCallback connection_error_with_reason_handler_;
+ AssociatedBinding<Interface> binding_;
+ base::WeakPtrFactory<StrongAssociatedBinding> weak_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(StrongAssociatedBinding);
+};
+
+template <typename Interface, typename Impl>
+StrongAssociatedBindingPtr<Interface> MakeStrongAssociatedBinding(
+ std::unique_ptr<Impl> impl,
+ AssociatedInterfaceRequest<Interface> request) {
+ return StrongAssociatedBinding<Interface>::Create(std::move(impl),
+ std::move(request));
+}
+
+} // namespace mojo
+
+#endif // MOJO_PUBLIC_CPP_BINDINGS_STRONG_ASSOCIATED_BINDING_H_
diff --git a/mojo/public/cpp/bindings/strong_binding_set.h b/mojo/public/cpp/bindings/strong_binding_set.h
new file mode 100644
index 0000000..f6bcd52
--- /dev/null
+++ b/mojo/public/cpp/bindings/strong_binding_set.h
@@ -0,0 +1,26 @@
+// Copyright 2017 The Chromium 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 MOJO_PUBLIC_CPP_BINDINGS_STRONG_BINDING_SET_H_
+#define MOJO_PUBLIC_CPP_BINDINGS_STRONG_BINDING_SET_H_
+
+#include "mojo/public/cpp/bindings/binding_set.h"
+#include "mojo/public/cpp/bindings/unique_ptr_impl_ref_traits.h"
+
+namespace mojo {
+
+// This class manages a set of bindings. When the pipe a binding is bound to is
+// disconnected, the binding is automatically destroyed and removed from the
+// set, and the interface implementation is deleted. When the StrongBindingSet
+// is destructed, all outstanding bindings in the set are destroyed and all the
+// bound interface implementations are automatically deleted.
+template <typename Interface, typename ContextType = void>
+using StrongBindingSet =
+ BindingSetBase<Interface,
+ Binding<Interface, UniquePtrImplRefTraits<Interface>>,
+ ContextType>;
+
+} // namespace mojo
+
+#endif // MOJO_PUBLIC_CPP_BINDINGS_STRONG_BINDING_SET_H_
diff --git a/mojo/public/cpp/bindings/tests/BUILD.gn b/mojo/public/cpp/bindings/tests/BUILD.gn
index 4e38f15..6244226 100644
--- a/mojo/public/cpp/bindings/tests/BUILD.gn
+++ b/mojo/public/cpp/bindings/tests/BUILD.gn
@@ -2,39 +2,35 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
-import("../../../mojo_application.gni")
-
source_set("tests") {
testonly = true
sources = [
- "array_common_test.h",
- "array_unittest.cc",
"associated_interface_unittest.cc",
"bind_task_runner_unittest.cc",
"binding_callback_unittest.cc",
+ "binding_set_unittest.cc",
"binding_unittest.cc",
"buffer_unittest.cc",
"connector_unittest.cc",
"constant_unittest.cc",
"container_test_util.cc",
"container_test_util.h",
+ "data_view_unittest.cc",
"equals_unittest.cc",
"handle_passing_unittest.cc",
+ "hash_unittest.cc",
"interface_ptr_unittest.cc",
- "map_common_test.h",
"map_unittest.cc",
"message_queue.cc",
"message_queue.h",
"multiplex_router_unittest.cc",
+ "report_bad_message_unittest.cc",
"request_response_unittest.cc",
"router_test_util.cc",
"router_test_util.h",
- "router_unittest.cc",
"sample_service_unittest.cc",
"serialization_warning_unittest.cc",
- "stl_converters_unittest.cc",
- "string_unittest.cc",
"struct_unittest.cc",
"sync_method_unittest.cc",
"type_conversion_unittest.cc",
@@ -46,10 +42,14 @@ source_set("tests") {
deps = [
":mojo_public_bindings_test_utils",
+ "//base/test:test_support",
+ "//mojo/edk/system",
"//mojo/public/cpp/bindings",
"//mojo/public/cpp/system",
"//mojo/public/cpp/test_support:test_utils",
"//mojo/public/interfaces/bindings/tests:test_associated_interfaces",
+ "//mojo/public/interfaces/bindings/tests:test_export_component",
+ "//mojo/public/interfaces/bindings/tests:test_exported_import",
"//mojo/public/interfaces/bindings/tests:test_interfaces",
"//mojo/public/interfaces/bindings/tests:test_interfaces_experimental",
"//mojo/public/interfaces/bindings/tests:test_struct_traits_interfaces",
@@ -77,12 +77,10 @@ if (!is_ios) {
testonly = true
sources = [
- "array_common_test.h",
"container_test_util.cc",
"container_test_util.h",
- "map_common_test.h",
"variant_test_util.h",
- "wtf_array_unittest.cc",
+ "wtf_hash_unittest.cc",
"wtf_map_unittest.cc",
"wtf_types_unittest.cc",
]
@@ -90,7 +88,10 @@ if (!is_ios) {
deps = [
"//mojo/public/cpp/bindings",
"//mojo/public/cpp/system",
+ "//mojo/public/interfaces/bindings/tests:test_export_blink_component",
+ "//mojo/public/interfaces/bindings/tests:test_exported_import_blink",
"//mojo/public/interfaces/bindings/tests:test_interfaces",
+ "//mojo/public/interfaces/bindings/tests:test_interfaces_blink",
"//mojo/public/interfaces/bindings/tests:test_wtf_types",
"//mojo/public/interfaces/bindings/tests:test_wtf_types_blink",
"//testing/gtest",
@@ -123,6 +124,7 @@ source_set("perftests") {
deps = [
"//base/test:test_support",
+ "//mojo/edk/system",
"//mojo/edk/test:test_support",
"//mojo/public/cpp/bindings",
"//mojo/public/cpp/system",
diff --git a/mojo/public/cpp/bindings/tests/array_common_test.h b/mojo/public/cpp/bindings/tests/array_common_test.h
deleted file mode 100644
index 6b4bcfb..0000000
--- a/mojo/public/cpp/bindings/tests/array_common_test.h
+++ /dev/null
@@ -1,404 +0,0 @@
-// Copyright 2016 The Chromium 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 <stddef.h>
-#include <stdint.h>
-#include <utility>
-
-#include "mojo/public/cpp/bindings/lib/array_internal.h"
-#include "mojo/public/cpp/bindings/lib/fixed_buffer.h"
-#include "mojo/public/cpp/bindings/lib/serialization.h"
-#include "mojo/public/cpp/bindings/tests/container_test_util.h"
-#include "mojo/public/interfaces/bindings/tests/test_structs.mojom.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace mojo {
-namespace test {
-
-// Common tests for both mojo::Array and mojo::WTFArray.
-template <template <typename...> class ArrayType>
-class ArrayCommonTest {
- public:
- // Tests null and empty arrays.
- static void NullAndEmpty() {
- ArrayType<char> array0;
- EXPECT_TRUE(array0.empty());
- EXPECT_FALSE(array0.is_null());
- array0 = nullptr;
- EXPECT_TRUE(array0.is_null());
- EXPECT_FALSE(array0.empty());
-
- ArrayType<char> array1(nullptr);
- EXPECT_TRUE(array1.is_null());
- EXPECT_FALSE(array1.empty());
- array1.SetToEmpty();
- EXPECT_TRUE(array1.empty());
- EXPECT_FALSE(array1.is_null());
- }
-
- // Tests that basic array operations work.
- static void Basic() {
- ArrayType<char> array(8);
- for (size_t i = 0; i < array.size(); ++i) {
- char val = static_cast<char>(i * 2);
- array[i] = val;
- EXPECT_EQ(val, array.at(i));
- }
- }
-
- // Tests that basic ArrayType<bool> operations work.
- static void Bool() {
- ArrayType<bool> array(64);
- for (size_t i = 0; i < array.size(); ++i) {
- bool val = i % 3 == 0;
- array[i] = val;
- EXPECT_EQ(val, array.at(i));
- }
- }
-
- // Tests that ArrayType<ScopedMessagePipeHandle> supports transferring
- // handles.
- static void Handle() {
- MessagePipe pipe;
- ArrayType<ScopedMessagePipeHandle> handles(2);
- handles[0] = std::move(pipe.handle0);
- handles[1].reset(pipe.handle1.release());
-
- EXPECT_FALSE(pipe.handle0.is_valid());
- EXPECT_FALSE(pipe.handle1.is_valid());
-
- ArrayType<ScopedMessagePipeHandle> handles2 = std::move(handles);
- EXPECT_TRUE(handles2[0].is_valid());
- EXPECT_TRUE(handles2[1].is_valid());
-
- ScopedMessagePipeHandle pipe_handle = std::move(handles2[0]);
- EXPECT_TRUE(pipe_handle.is_valid());
- EXPECT_FALSE(handles2[0].is_valid());
- }
-
- // Tests that ArrayType<ScopedMessagePipeHandle> supports closing handles.
- static void HandlesAreClosed() {
- MessagePipe pipe;
- MojoHandle pipe0_value = pipe.handle0.get().value();
- MojoHandle pipe1_value = pipe.handle0.get().value();
-
- {
- ArrayType<ScopedMessagePipeHandle> handles(2);
- handles[0] = std::move(pipe.handle0);
- handles[1].reset(pipe.handle0.release());
- }
-
- // We expect the pipes to have been closed.
- EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoClose(pipe0_value));
- EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoClose(pipe1_value));
- }
-
- static void Clone() {
- {
- // Test POD.
- ArrayType<int32_t> array(3);
- for (size_t i = 0; i < array.size(); ++i)
- array[i] = static_cast<int32_t>(i);
-
- ArrayType<int32_t> clone_array = array.Clone();
- EXPECT_EQ(array.size(), clone_array.size());
- for (size_t i = 0; i < array.size(); ++i)
- EXPECT_EQ(array[i], clone_array[i]);
- }
-
- {
- // Test copyable object.
- ArrayType<String> array(2);
- array[0] = "hello";
- array[1] = "world";
-
- ArrayType<String> clone_array = array.Clone();
- EXPECT_EQ(array.size(), clone_array.size());
- for (size_t i = 0; i < array.size(); ++i)
- EXPECT_EQ(array[i], clone_array[i]);
- }
-
- {
- // Test struct.
- ArrayType<RectPtr> array(2);
- array[1] = Rect::New();
- array[1]->x = 1;
- array[1]->y = 2;
- array[1]->width = 3;
- array[1]->height = 4;
-
- ArrayType<RectPtr> clone_array = array.Clone();
- EXPECT_EQ(array.size(), clone_array.size());
- EXPECT_TRUE(clone_array[0].is_null());
- EXPECT_EQ(array[1]->x, clone_array[1]->x);
- EXPECT_EQ(array[1]->y, clone_array[1]->y);
- EXPECT_EQ(array[1]->width, clone_array[1]->width);
- EXPECT_EQ(array[1]->height, clone_array[1]->height);
- }
-
- {
- // Test array of array.
- ArrayType<ArrayType<int8_t>> array(2);
- array[0] = nullptr;
- array[1] = ArrayType<int8_t>(2);
- array[1][0] = 0;
- array[1][1] = 1;
-
- ArrayType<ArrayType<int8_t>> clone_array = array.Clone();
- EXPECT_EQ(array.size(), clone_array.size());
- EXPECT_TRUE(clone_array[0].is_null());
- EXPECT_EQ(array[1].size(), clone_array[1].size());
- EXPECT_EQ(array[1][0], clone_array[1][0]);
- EXPECT_EQ(array[1][1], clone_array[1][1]);
- }
-
- {
- // Test that array of handles still works although Clone() is not
- // available.
- ArrayType<ScopedMessagePipeHandle> array(10);
- EXPECT_FALSE(array[0].is_valid());
- }
- }
-
- static void Serialization_ArrayOfPOD() {
- ArrayType<int32_t> array(4);
- for (size_t i = 0; i < array.size(); ++i)
- array[i] = static_cast<int32_t>(i);
-
- size_t size =
- mojo::internal::PrepareToSerialize<Array<int32_t>>(array, nullptr);
- EXPECT_EQ(8U + 4 * 4U, size);
-
- mojo::internal::FixedBufferForTesting buf(size);
- mojo::internal::Array_Data<int32_t>* data;
- mojo::internal::ContainerValidateParams validate_params(0, false, nullptr);
- mojo::internal::Serialize<Array<int32_t>>(array, &buf, &data,
- &validate_params, nullptr);
-
- ArrayType<int32_t> array2;
- mojo::internal::Deserialize<Array<int32_t>>(data, &array2, nullptr);
-
- EXPECT_EQ(4U, array2.size());
- for (size_t i = 0; i < array2.size(); ++i)
- EXPECT_EQ(static_cast<int32_t>(i), array2[i]);
- }
-
- static void Serialization_EmptyArrayOfPOD() {
- ArrayType<int32_t> array;
- size_t size =
- mojo::internal::PrepareToSerialize<Array<int32_t>>(array, nullptr);
- EXPECT_EQ(8U, size);
-
- mojo::internal::FixedBufferForTesting buf(size);
- mojo::internal::Array_Data<int32_t>* data;
- mojo::internal::ContainerValidateParams validate_params(0, false, nullptr);
- mojo::internal::Serialize<Array<int32_t>>(array, &buf, &data,
- &validate_params, nullptr);
-
- ArrayType<int32_t> array2;
- mojo::internal::Deserialize<Array<int32_t>>(data, &array2, nullptr);
- EXPECT_EQ(0U, array2.size());
- }
-
- static void Serialization_ArrayOfArrayOfPOD() {
- ArrayType<ArrayType<int32_t>> array(2);
- for (size_t j = 0; j < array.size(); ++j) {
- ArrayType<int32_t> inner(4);
- for (size_t i = 0; i < inner.size(); ++i)
- inner[i] = static_cast<int32_t>(i + (j * 10));
- array[j] = std::move(inner);
- }
-
- size_t size = mojo::internal::PrepareToSerialize<Array<Array<int32_t>>>(
- array, nullptr);
- EXPECT_EQ(8U + 2 * 8U + 2 * (8U + 4 * 4U), size);
-
- mojo::internal::FixedBufferForTesting buf(size);
- typename mojo::internal::MojomTypeTraits<Array<Array<int32_t>>>::Data* data;
- mojo::internal::ContainerValidateParams validate_params(
- 0, false,
- new mojo::internal::ContainerValidateParams(0, false, nullptr));
- mojo::internal::Serialize<Array<Array<int32_t>>>(array, &buf, &data,
- &validate_params, nullptr);
-
- ArrayType<ArrayType<int32_t>> array2;
- mojo::internal::Deserialize<Array<Array<int32_t>>>(data, &array2, nullptr);
-
- EXPECT_EQ(2U, array2.size());
- for (size_t j = 0; j < array2.size(); ++j) {
- const ArrayType<int32_t>& inner = array2[j];
- EXPECT_EQ(4U, inner.size());
- for (size_t i = 0; i < inner.size(); ++i)
- EXPECT_EQ(static_cast<int32_t>(i + (j * 10)), inner[i]);
- }
- }
-
- static void Serialization_ArrayOfBool() {
- ArrayType<bool> array(10);
- for (size_t i = 0; i < array.size(); ++i)
- array[i] = i % 2 ? true : false;
-
- size_t size =
- mojo::internal::PrepareToSerialize<Array<bool>>(array, nullptr);
- EXPECT_EQ(8U + 8U, size);
-
- mojo::internal::FixedBufferForTesting buf(size);
- mojo::internal::Array_Data<bool>* data;
- mojo::internal::ContainerValidateParams validate_params(0, false, nullptr);
- mojo::internal::Serialize<Array<bool>>(array, &buf, &data, &validate_params,
- nullptr);
-
- ArrayType<bool> array2;
- mojo::internal::Deserialize<Array<bool>>(data, &array2, nullptr);
-
- EXPECT_EQ(10U, array2.size());
- for (size_t i = 0; i < array2.size(); ++i)
- EXPECT_EQ(i % 2 ? true : false, array2[i]);
- }
-
- static void Serialization_ArrayOfString() {
- ArrayType<String> array(10);
- for (size_t i = 0; i < array.size(); ++i) {
- char c = 'A' + static_cast<char>(i);
- array[i] = String(&c, 1);
- }
-
- size_t size =
- mojo::internal::PrepareToSerialize<Array<String>>(array, nullptr);
- EXPECT_EQ(8U + // array header
- 10 * 8U + // array payload (10 pointers)
- 10 * (8U + // string header
- 8U), // string length of 1 padded to 8
- size);
-
- mojo::internal::FixedBufferForTesting buf(size);
- typename mojo::internal::MojomTypeTraits<Array<String>>::Data* data;
- mojo::internal::ContainerValidateParams validate_params(
- 0, false,
- new mojo::internal::ContainerValidateParams(0, false, nullptr));
- mojo::internal::Serialize<Array<String>>(array, &buf, &data,
- &validate_params, nullptr);
-
- ArrayType<String> array2;
- mojo::internal::Deserialize<Array<String>>(data, &array2, nullptr);
-
- EXPECT_EQ(10U, array2.size());
- for (size_t i = 0; i < array2.size(); ++i) {
- char c = 'A' + static_cast<char>(i);
- EXPECT_EQ(String(&c, 1), array2[i]);
- }
- }
-
- static void Resize_Copyable() {
- ASSERT_EQ(0u, CopyableType::num_instances());
- ArrayType<CopyableType> array(3);
- std::vector<CopyableType*> value_ptrs;
- value_ptrs.push_back(array[0].ptr());
- value_ptrs.push_back(array[1].ptr());
-
- for (size_t i = 0; i < array.size(); i++)
- array[i].ResetCopied();
-
- array.resize(2);
- ASSERT_EQ(2u, array.size());
- EXPECT_EQ(array.size(), CopyableType::num_instances());
- for (size_t i = 0; i < array.size(); i++) {
- EXPECT_FALSE(array[i].copied());
- EXPECT_EQ(value_ptrs[i], array[i].ptr());
- }
-
- array.resize(3);
- array[2].ResetCopied();
- ASSERT_EQ(3u, array.size());
- EXPECT_EQ(array.size(), CopyableType::num_instances());
- for (size_t i = 0; i < array.size(); i++)
- EXPECT_FALSE(array[i].copied());
- value_ptrs.push_back(array[2].ptr());
-
- size_t capacity = array.storage().capacity();
- array.resize(capacity);
- ASSERT_EQ(capacity, array.size());
- EXPECT_EQ(array.size(), CopyableType::num_instances());
- for (size_t i = 0; i < 3; i++)
- EXPECT_FALSE(array[i].copied());
- for (size_t i = 3; i < array.size(); i++) {
- array[i].ResetCopied();
- value_ptrs.push_back(array[i].ptr());
- }
-
- array.resize(capacity + 2);
- ASSERT_EQ(capacity + 2, array.size());
- EXPECT_EQ(array.size(), CopyableType::num_instances());
- for (size_t i = 0; i < capacity; i++) {
- EXPECT_TRUE(array[i].copied());
- EXPECT_EQ(value_ptrs[i], array[i].ptr());
- }
- array = nullptr;
- EXPECT_EQ(0u, CopyableType::num_instances());
- EXPECT_FALSE(array);
- array.resize(0);
- EXPECT_EQ(0u, CopyableType::num_instances());
- EXPECT_TRUE(array);
- }
-
- static void Resize_MoveOnly() {
- ASSERT_EQ(0u, MoveOnlyType::num_instances());
- ArrayType<MoveOnlyType> array(3);
- std::vector<MoveOnlyType*> value_ptrs;
- value_ptrs.push_back(array[0].ptr());
- value_ptrs.push_back(array[1].ptr());
-
- for (size_t i = 0; i < array.size(); i++)
- EXPECT_FALSE(array[i].moved());
-
- array.resize(2);
- ASSERT_EQ(2u, array.size());
- EXPECT_EQ(array.size(), MoveOnlyType::num_instances());
- for (size_t i = 0; i < array.size(); i++) {
- EXPECT_FALSE(array[i].moved());
- EXPECT_EQ(value_ptrs[i], array[i].ptr());
- }
-
- array.resize(3);
- ASSERT_EQ(3u, array.size());
- EXPECT_EQ(array.size(), MoveOnlyType::num_instances());
- for (size_t i = 0; i < array.size(); i++)
- EXPECT_FALSE(array[i].moved());
- value_ptrs.push_back(array[2].ptr());
-
- size_t capacity = array.storage().capacity();
- array.resize(capacity);
- ASSERT_EQ(capacity, array.size());
- EXPECT_EQ(array.size(), MoveOnlyType::num_instances());
- for (size_t i = 0; i < array.size(); i++)
- EXPECT_FALSE(array[i].moved());
- for (size_t i = 3; i < array.size(); i++)
- value_ptrs.push_back(array[i].ptr());
-
- array.resize(capacity + 2);
- ASSERT_EQ(capacity + 2, array.size());
- EXPECT_EQ(array.size(), MoveOnlyType::num_instances());
- for (size_t i = 0; i < capacity; i++) {
- EXPECT_TRUE(array[i].moved());
- EXPECT_EQ(value_ptrs[i], array[i].ptr());
- }
- for (size_t i = capacity; i < array.size(); i++)
- EXPECT_FALSE(array[i].moved());
-
- array = nullptr;
- EXPECT_EQ(0u, MoveOnlyType::num_instances());
- EXPECT_FALSE(array);
- array.resize(0);
- EXPECT_EQ(0u, MoveOnlyType::num_instances());
- EXPECT_TRUE(array);
- }
-};
-
-#define ARRAY_COMMON_TEST(ArrayType, test_name) \
- TEST_F(ArrayType##Test, test_name) { \
- ArrayCommonTest<ArrayType>::test_name(); \
- }
-
-} // namespace test
-} // namespace mojo
diff --git a/mojo/public/cpp/bindings/tests/array_unittest.cc b/mojo/public/cpp/bindings/tests/array_unittest.cc
deleted file mode 100644
index 0700bb1..0000000
--- a/mojo/public/cpp/bindings/tests/array_unittest.cc
+++ /dev/null
@@ -1,131 +0,0 @@
-// Copyright 2014 The Chromium 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 "mojo/public/cpp/bindings/array.h"
-
-#include "mojo/public/cpp/bindings/lib/serialization.h"
-#include "mojo/public/cpp/bindings/tests/array_common_test.h"
-#include "mojo/public/cpp/bindings/tests/container_test_util.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace mojo {
-namespace test {
-namespace {
-
-using ArrayTest = testing::Test;
-
-ARRAY_COMMON_TEST(Array, NullAndEmpty)
-ARRAY_COMMON_TEST(Array, Basic)
-ARRAY_COMMON_TEST(Array, Bool)
-ARRAY_COMMON_TEST(Array, Handle)
-ARRAY_COMMON_TEST(Array, HandlesAreClosed)
-ARRAY_COMMON_TEST(Array, Clone)
-ARRAY_COMMON_TEST(Array, Serialization_ArrayOfPOD)
-ARRAY_COMMON_TEST(Array, Serialization_EmptyArrayOfPOD)
-ARRAY_COMMON_TEST(Array, Serialization_ArrayOfArrayOfPOD)
-ARRAY_COMMON_TEST(Array, Serialization_ArrayOfBool)
-ARRAY_COMMON_TEST(Array, Serialization_ArrayOfString)
-ARRAY_COMMON_TEST(Array, Resize_Copyable)
-ARRAY_COMMON_TEST(Array, Resize_MoveOnly)
-
-TEST_F(ArrayTest, PushBack_Copyable) {
- ASSERT_EQ(0u, CopyableType::num_instances());
- Array<CopyableType> array(2);
- array = nullptr;
- std::vector<CopyableType*> value_ptrs;
- size_t capacity = array.storage().capacity();
- for (size_t i = 0; i < capacity; i++) {
- CopyableType value;
- value_ptrs.push_back(value.ptr());
- array.push_back(value);
- ASSERT_EQ(i + 1, array.size());
- ASSERT_EQ(i + 1, value_ptrs.size());
- EXPECT_EQ(array.size() + 1, CopyableType::num_instances());
- EXPECT_TRUE(array[i].copied());
- EXPECT_EQ(value_ptrs[i], array[i].ptr());
- array[i].ResetCopied();
- EXPECT_TRUE(array);
- }
- {
- CopyableType value;
- value_ptrs.push_back(value.ptr());
- array.push_back(value);
- EXPECT_EQ(array.size() + 1, CopyableType::num_instances());
- }
- ASSERT_EQ(capacity + 1, array.size());
- EXPECT_EQ(array.size(), CopyableType::num_instances());
-
- for (size_t i = 0; i < array.size(); i++) {
- EXPECT_TRUE(array[i].copied());
- EXPECT_EQ(value_ptrs[i], array[i].ptr());
- }
- array = nullptr;
- EXPECT_EQ(0u, CopyableType::num_instances());
-}
-
-TEST_F(ArrayTest, PushBack_MoveOnly) {
- ASSERT_EQ(0u, MoveOnlyType::num_instances());
- Array<MoveOnlyType> array(2);
- array = nullptr;
- std::vector<MoveOnlyType*> value_ptrs;
- size_t capacity = array.storage().capacity();
- for (size_t i = 0; i < capacity; i++) {
- MoveOnlyType value;
- value_ptrs.push_back(value.ptr());
- array.push_back(std::move(value));
- ASSERT_EQ(i + 1, array.size());
- ASSERT_EQ(i + 1, value_ptrs.size());
- EXPECT_EQ(array.size() + 1, MoveOnlyType::num_instances());
- EXPECT_TRUE(array[i].moved());
- EXPECT_EQ(value_ptrs[i], array[i].ptr());
- array[i].ResetMoved();
- EXPECT_TRUE(array);
- }
- {
- MoveOnlyType value;
- value_ptrs.push_back(value.ptr());
- array.push_back(std::move(value));
- EXPECT_EQ(array.size() + 1, MoveOnlyType::num_instances());
- }
- ASSERT_EQ(capacity + 1, array.size());
- EXPECT_EQ(array.size(), MoveOnlyType::num_instances());
-
- for (size_t i = 0; i < array.size(); i++) {
- EXPECT_TRUE(array[i].moved());
- EXPECT_EQ(value_ptrs[i], array[i].ptr());
- }
- array = nullptr;
- EXPECT_EQ(0u, MoveOnlyType::num_instances());
-}
-
-TEST_F(ArrayTest, MoveFromAndToSTLVector_Copyable) {
- std::vector<CopyableType> vec1(1);
- Array<CopyableType> arr(std::move(vec1));
- ASSERT_EQ(1u, arr.size());
- ASSERT_FALSE(arr[0].copied());
-
- std::vector<CopyableType> vec2(arr.PassStorage());
- ASSERT_EQ(1u, vec2.size());
- ASSERT_FALSE(vec2[0].copied());
-
- ASSERT_EQ(0u, arr.size());
- ASSERT_TRUE(arr.is_null());
-}
-
-TEST_F(ArrayTest, MoveFromAndToSTLVector_MoveOnly) {
- std::vector<MoveOnlyType> vec1(1);
- Array<MoveOnlyType> arr(std::move(vec1));
-
- ASSERT_EQ(1u, arr.size());
-
- std::vector<MoveOnlyType> vec2(arr.PassStorage());
- ASSERT_EQ(1u, vec2.size());
-
- ASSERT_EQ(0u, arr.size());
- ASSERT_TRUE(arr.is_null());
-}
-
-} // namespace
-} // namespace test
-} // namespace mojo
diff --git a/mojo/public/cpp/bindings/tests/associated_interface_unittest.cc b/mojo/public/cpp/bindings/tests/associated_interface_unittest.cc
index 8f2eb08..625c49c 100644
--- a/mojo/public/cpp/bindings/tests/associated_interface_unittest.cc
+++ b/mojo/public/cpp/bindings/tests/associated_interface_unittest.cc
@@ -9,18 +9,24 @@
#include "base/bind.h"
#include "base/callback.h"
+#include "base/callback_helpers.h"
+#include "base/memory/ptr_util.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
+#include "base/synchronization/waitable_event.h"
+#include "base/threading/sequenced_task_runner_handle.h"
#include "base/threading/thread.h"
#include "base/threading/thread_task_runner_handle.h"
#include "mojo/public/cpp/bindings/associated_binding.h"
-#include "mojo/public/cpp/bindings/associated_group.h"
#include "mojo/public/cpp/bindings/associated_interface_ptr.h"
#include "mojo/public/cpp/bindings/associated_interface_ptr_info.h"
#include "mojo/public/cpp/bindings/associated_interface_request.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "mojo/public/cpp/bindings/lib/multiplex_router.h"
+#include "mojo/public/cpp/bindings/strong_binding.h"
+#include "mojo/public/cpp/bindings/thread_safe_interface_ptr.h"
+#include "mojo/public/interfaces/bindings/tests/ping_service.mojom.h"
#include "mojo/public/interfaces/bindings/tests/test_associated_interfaces.mojom.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -73,10 +79,8 @@ class IntegerSenderConnectionImpl : public IntegerSenderConnection {
}
void AsyncGetSender(const AsyncGetSenderCallback& callback) override {
- AssociatedInterfaceRequest<IntegerSender> request;
IntegerSenderAssociatedPtrInfo ptr_info;
- binding_.associated_group()->CreateAssociatedInterface(
- AssociatedGroup::WILL_PASS_PTR, &ptr_info, &request);
+ auto request = MakeRequest(&ptr_info);
GetSender(std::move(request));
callback.Run(std::move(ptr_info));
}
@@ -99,22 +103,42 @@ class AssociatedInterfaceTest : public testing::Test {
template <typename T>
AssociatedInterfacePtrInfo<T> EmulatePassingAssociatedPtrInfo(
AssociatedInterfacePtrInfo<T> ptr_info,
+ scoped_refptr<MultiplexRouter> source,
scoped_refptr<MultiplexRouter> target) {
ScopedInterfaceEndpointHandle handle = ptr_info.PassHandle();
- CHECK(!handle.is_local());
- return AssociatedInterfacePtrInfo<T>(
- target->CreateLocalEndpointHandle(handle.release()),
- ptr_info.version());
+ CHECK(handle.pending_association());
+ auto id = source->AssociateInterface(std::move(handle));
+ return AssociatedInterfacePtrInfo<T>(target->CreateLocalEndpointHandle(id),
+ ptr_info.version());
}
- template <typename T>
- AssociatedInterfaceRequest<T> EmulatePassingAssociatedRequest(
- AssociatedInterfaceRequest<T> request,
- scoped_refptr<MultiplexRouter> target) {
- ScopedInterfaceEndpointHandle handle = request.PassHandle();
- CHECK(!handle.is_local());
- return MakeAssociatedRequest<T>(
- target->CreateLocalEndpointHandle(handle.release()));
+ void CreateRouterPair(scoped_refptr<MultiplexRouter>* router0,
+ scoped_refptr<MultiplexRouter>* router1) {
+ MessagePipe pipe;
+ *router0 = new MultiplexRouter(std::move(pipe.handle0),
+ MultiplexRouter::MULTI_INTERFACE, true,
+ base::ThreadTaskRunnerHandle::Get());
+ *router1 = new MultiplexRouter(std::move(pipe.handle1),
+ MultiplexRouter::MULTI_INTERFACE, false,
+ base::ThreadTaskRunnerHandle::Get());
+ }
+
+ void CreateIntegerSenderWithExistingRouters(
+ scoped_refptr<MultiplexRouter> router0,
+ IntegerSenderAssociatedPtrInfo* ptr_info0,
+ scoped_refptr<MultiplexRouter> router1,
+ IntegerSenderAssociatedRequest* request1) {
+ *request1 = MakeRequest(ptr_info0);
+ *ptr_info0 = EmulatePassingAssociatedPtrInfo(std::move(*ptr_info0), router1,
+ router0);
+ }
+
+ void CreateIntegerSender(IntegerSenderAssociatedPtrInfo* ptr_info,
+ IntegerSenderAssociatedRequest* request) {
+ scoped_refptr<MultiplexRouter> router0;
+ scoped_refptr<MultiplexRouter> router1;
+ CreateRouterPair(&router0, &router1);
+ CreateIntegerSenderWithExistingRouters(router1, ptr_info, router0, request);
}
// Okay to call from any thread.
@@ -158,30 +182,27 @@ base::Callback<void(int32_t)> ExpectValueSetFlagAndRunClosure(
&DoExpectValueSetFlagAndRunClosure, expected_value, flag, closure);
}
+void Fail() {
+ FAIL() << "Unexpected connection error";
+}
+
TEST_F(AssociatedInterfaceTest, InterfacesAtBothEnds) {
// Bind to the same pipe two associated interfaces, whose implementation lives
// at different ends. Test that the two don't interfere with each other.
- MessagePipe pipe;
- scoped_refptr<MultiplexRouter> router0(new MultiplexRouter(
- true, std::move(pipe.handle0), base::ThreadTaskRunnerHandle::Get()));
- scoped_refptr<MultiplexRouter> router1(new MultiplexRouter(
- false, std::move(pipe.handle1), base::ThreadTaskRunnerHandle::Get()));
+ scoped_refptr<MultiplexRouter> router0;
+ scoped_refptr<MultiplexRouter> router1;
+ CreateRouterPair(&router0, &router1);
AssociatedInterfaceRequest<IntegerSender> request;
IntegerSenderAssociatedPtrInfo ptr_info;
-
- router0->CreateAssociatedGroup()->CreateAssociatedInterface(
- AssociatedGroup::WILL_PASS_PTR, &ptr_info, &request);
- ptr_info = EmulatePassingAssociatedPtrInfo(std::move(ptr_info), router1);
+ CreateIntegerSenderWithExistingRouters(router1, &ptr_info, router0, &request);
IntegerSenderImpl impl0(std::move(request));
AssociatedInterfacePtr<IntegerSender> ptr0;
ptr0.Bind(std::move(ptr_info));
- router0->CreateAssociatedGroup()->CreateAssociatedInterface(
- AssociatedGroup::WILL_PASS_REQUEST, &ptr_info, &request);
- request = EmulatePassingAssociatedRequest(std::move(request), router1);
+ CreateIntegerSenderWithExistingRouters(router0, &ptr_info, router1, &request);
IntegerSenderImpl impl1(std::move(request));
AssociatedInterfacePtr<IntegerSender> ptr1;
@@ -358,19 +379,15 @@ TEST_F(AssociatedInterfaceTest, MultiThreadAccess) {
const int32_t kMaxValue = 1000;
MessagePipe pipe;
- scoped_refptr<MultiplexRouter> router0(new MultiplexRouter(
- true, std::move(pipe.handle0), base::ThreadTaskRunnerHandle::Get()));
- scoped_refptr<MultiplexRouter> router1(new MultiplexRouter(
- false, std::move(pipe.handle1), base::ThreadTaskRunnerHandle::Get()));
+ scoped_refptr<MultiplexRouter> router0;
+ scoped_refptr<MultiplexRouter> router1;
+ CreateRouterPair(&router0, &router1);
AssociatedInterfaceRequest<IntegerSender> requests[4];
IntegerSenderAssociatedPtrInfo ptr_infos[4];
-
for (size_t i = 0; i < 4; ++i) {
- router0->CreateAssociatedGroup()->CreateAssociatedInterface(
- AssociatedGroup::WILL_PASS_PTR, &ptr_infos[i], &requests[i]);
- ptr_infos[i] =
- EmulatePassingAssociatedPtrInfo(std::move(ptr_infos[i]), router1);
+ CreateIntegerSenderWithExistingRouters(router1, &ptr_infos[i], router0,
+ &requests[i]);
}
TestSender senders[4];
@@ -447,19 +464,15 @@ TEST_F(AssociatedInterfaceTest, FIFO) {
const int32_t kMaxValue = 100;
MessagePipe pipe;
- scoped_refptr<MultiplexRouter> router0(new MultiplexRouter(
- true, std::move(pipe.handle0), base::ThreadTaskRunnerHandle::Get()));
- scoped_refptr<MultiplexRouter> router1(new MultiplexRouter(
- false, std::move(pipe.handle1), base::ThreadTaskRunnerHandle::Get()));
+ scoped_refptr<MultiplexRouter> router0;
+ scoped_refptr<MultiplexRouter> router1;
+ CreateRouterPair(&router0, &router1);
AssociatedInterfaceRequest<IntegerSender> requests[4];
IntegerSenderAssociatedPtrInfo ptr_infos[4];
-
for (size_t i = 0; i < 4; ++i) {
- router0->CreateAssociatedGroup()->CreateAssociatedInterface(
- AssociatedGroup::WILL_PASS_PTR, &ptr_infos[i], &requests[i]);
- ptr_infos[i] =
- EmulatePassingAssociatedPtrInfo(std::move(ptr_infos[i]), router1);
+ CreateIntegerSenderWithExistingRouters(router1, &ptr_infos[i], router0,
+ &requests[i]);
}
TestSender senders[4];
@@ -538,11 +551,10 @@ void CaptureSenderPtrInfo(IntegerSenderAssociatedPtr* storage,
TEST_F(AssociatedInterfaceTest, PassAssociatedInterfaces) {
IntegerSenderConnectionPtr connection_ptr;
- IntegerSenderConnectionImpl connection(GetProxy(&connection_ptr));
+ IntegerSenderConnectionImpl connection(MakeRequest(&connection_ptr));
IntegerSenderAssociatedPtr sender0;
- connection_ptr->GetSender(
- GetProxy(&sender0, connection_ptr.associated_group()));
+ connection_ptr->GetSender(MakeRequest(&sender0));
int32_t echoed_value = 0;
base::RunLoop run_loop;
@@ -567,11 +579,10 @@ TEST_F(AssociatedInterfaceTest, PassAssociatedInterfaces) {
TEST_F(AssociatedInterfaceTest, BindingWaitAndPauseWhenNoAssociatedInterfaces) {
IntegerSenderConnectionPtr connection_ptr;
- IntegerSenderConnectionImpl connection(GetProxy(&connection_ptr));
+ IntegerSenderConnectionImpl connection(MakeRequest(&connection_ptr));
IntegerSenderAssociatedPtr sender0;
- connection_ptr->GetSender(
- GetProxy(&sender0, connection_ptr.associated_group()));
+ connection_ptr->GetSender(MakeRequest(&sender0));
EXPECT_FALSE(connection.binding()->HasAssociatedInterfaces());
// There are no associated interfaces running on the pipe yet. It is okay to
@@ -589,6 +600,584 @@ TEST_F(AssociatedInterfaceTest, BindingWaitAndPauseWhenNoAssociatedInterfaces) {
EXPECT_TRUE(connection.binding()->HasAssociatedInterfaces());
}
+class PingServiceImpl : public PingService {
+ public:
+ explicit PingServiceImpl(PingServiceAssociatedRequest request)
+ : binding_(this, std::move(request)) {}
+ ~PingServiceImpl() override {}
+
+ AssociatedBinding<PingService>& binding() { return binding_; }
+
+ void set_ping_handler(const base::Closure& handler) {
+ ping_handler_ = handler;
+ }
+
+ // PingService:
+ void Ping(const PingCallback& callback) override {
+ if (!ping_handler_.is_null())
+ ping_handler_.Run();
+ callback.Run();
+ }
+
+ private:
+ AssociatedBinding<PingService> binding_;
+ base::Closure ping_handler_;
+};
+
+class PingProviderImpl : public AssociatedPingProvider {
+ public:
+ explicit PingProviderImpl(AssociatedPingProviderRequest request)
+ : binding_(this, std::move(request)) {}
+ ~PingProviderImpl() override {}
+
+ // AssociatedPingProvider:
+ void GetPing(PingServiceAssociatedRequest request) override {
+ ping_services_.emplace_back(new PingServiceImpl(std::move(request)));
+
+ if (expected_bindings_count_ > 0 &&
+ ping_services_.size() == expected_bindings_count_ &&
+ !quit_waiting_.is_null()) {
+ expected_bindings_count_ = 0;
+ base::ResetAndReturn(&quit_waiting_).Run();
+ }
+ }
+
+ std::vector<std::unique_ptr<PingServiceImpl>>& ping_services() {
+ return ping_services_;
+ }
+
+ void WaitForBindings(size_t count) {
+ DCHECK(quit_waiting_.is_null());
+
+ expected_bindings_count_ = count;
+ base::RunLoop loop;
+ quit_waiting_ = loop.QuitClosure();
+ loop.Run();
+ }
+
+ private:
+ Binding<AssociatedPingProvider> binding_;
+ std::vector<std::unique_ptr<PingServiceImpl>> ping_services_;
+ size_t expected_bindings_count_ = 0;
+ base::Closure quit_waiting_;
+};
+
+class CallbackFilter : public MessageReceiver {
+ public:
+ explicit CallbackFilter(const base::Closure& callback)
+ : callback_(callback) {}
+ ~CallbackFilter() override {}
+
+ static std::unique_ptr<CallbackFilter> Wrap(const base::Closure& callback) {
+ return base::MakeUnique<CallbackFilter>(callback);
+ }
+
+ // MessageReceiver:
+ bool Accept(Message* message) override {
+ callback_.Run();
+ return true;
+ }
+
+ private:
+ const base::Closure callback_;
+};
+
+// Verifies that filters work as expected on associated bindings, i.e. that
+// they're notified in order, before dispatch; and that each associated
+// binding in a group operates with its own set of filters.
+TEST_F(AssociatedInterfaceTest, BindingWithFilters) {
+ AssociatedPingProviderPtr provider;
+ PingProviderImpl provider_impl(MakeRequest(&provider));
+
+ PingServiceAssociatedPtr ping_a, ping_b;
+ provider->GetPing(MakeRequest(&ping_a));
+ provider->GetPing(MakeRequest(&ping_b));
+ provider_impl.WaitForBindings(2);
+
+ ASSERT_EQ(2u, provider_impl.ping_services().size());
+ PingServiceImpl& ping_a_impl = *provider_impl.ping_services()[0];
+ PingServiceImpl& ping_b_impl = *provider_impl.ping_services()[1];
+
+ int a_status, b_status;
+ auto handler_helper = [] (int* a_status, int* b_status, int expected_a_status,
+ int new_a_status, int expected_b_status,
+ int new_b_status) {
+ EXPECT_EQ(expected_a_status, *a_status);
+ EXPECT_EQ(expected_b_status, *b_status);
+ *a_status = new_a_status;
+ *b_status = new_b_status;
+ };
+ auto create_handler = [&] (int expected_a_status, int new_a_status,
+ int expected_b_status, int new_b_status) {
+ return base::Bind(handler_helper, &a_status, &b_status, expected_a_status,
+ new_a_status, expected_b_status, new_b_status);
+ };
+
+ ping_a_impl.binding().AddFilter(
+ CallbackFilter::Wrap(create_handler(0, 1, 0, 0)));
+ ping_a_impl.binding().AddFilter(
+ CallbackFilter::Wrap(create_handler(1, 2, 0, 0)));
+ ping_a_impl.set_ping_handler(create_handler(2, 3, 0, 0));
+
+ ping_b_impl.binding().AddFilter(
+ CallbackFilter::Wrap(create_handler(3, 3, 0, 1)));
+ ping_b_impl.binding().AddFilter(
+ CallbackFilter::Wrap(create_handler(3, 3, 1, 2)));
+ ping_b_impl.set_ping_handler(create_handler(3, 3, 2, 3));
+
+ for (int i = 0; i < 10; ++i) {
+ a_status = 0;
+ b_status = 0;
+
+ {
+ base::RunLoop loop;
+ ping_a->Ping(loop.QuitClosure());
+ loop.Run();
+ }
+
+ EXPECT_EQ(3, a_status);
+ EXPECT_EQ(0, b_status);
+
+ {
+ base::RunLoop loop;
+ ping_b->Ping(loop.QuitClosure());
+ loop.Run();
+ }
+
+ EXPECT_EQ(3, a_status);
+ EXPECT_EQ(3, b_status);
+ }
+}
+
+TEST_F(AssociatedInterfaceTest, AssociatedPtrFlushForTesting) {
+ AssociatedInterfaceRequest<IntegerSender> request;
+ IntegerSenderAssociatedPtrInfo ptr_info;
+ CreateIntegerSender(&ptr_info, &request);
+
+ IntegerSenderImpl impl0(std::move(request));
+ AssociatedInterfacePtr<IntegerSender> ptr0;
+ ptr0.Bind(std::move(ptr_info));
+ ptr0.set_connection_error_handler(base::Bind(&Fail));
+
+ bool ptr0_callback_run = false;
+ ptr0->Echo(123, ExpectValueSetFlagAndRunClosure(
+ 123, &ptr0_callback_run, base::Bind(&base::DoNothing)));
+ ptr0.FlushForTesting();
+ EXPECT_TRUE(ptr0_callback_run);
+}
+
+void SetBool(bool* value) {
+ *value = true;
+}
+
+template <typename T>
+void SetBoolWithUnusedParameter(bool* value, T unused) {
+ *value = true;
+}
+
+TEST_F(AssociatedInterfaceTest, AssociatedPtrFlushForTestingWithClosedPeer) {
+ AssociatedInterfaceRequest<IntegerSender> request;
+ IntegerSenderAssociatedPtrInfo ptr_info;
+ CreateIntegerSender(&ptr_info, &request);
+
+ AssociatedInterfacePtr<IntegerSender> ptr0;
+ ptr0.Bind(std::move(ptr_info));
+ bool called = false;
+ ptr0.set_connection_error_handler(base::Bind(&SetBool, &called));
+ request = nullptr;
+
+ ptr0.FlushForTesting();
+ EXPECT_TRUE(called);
+ ptr0.FlushForTesting();
+}
+
+TEST_F(AssociatedInterfaceTest, AssociatedBindingFlushForTesting) {
+ AssociatedInterfaceRequest<IntegerSender> request;
+ IntegerSenderAssociatedPtrInfo ptr_info;
+ CreateIntegerSender(&ptr_info, &request);
+
+ IntegerSenderImpl impl0(std::move(request));
+ impl0.set_connection_error_handler(base::Bind(&Fail));
+ AssociatedInterfacePtr<IntegerSender> ptr0;
+ ptr0.Bind(std::move(ptr_info));
+
+ bool ptr0_callback_run = false;
+ ptr0->Echo(123, ExpectValueSetFlagAndRunClosure(
+ 123, &ptr0_callback_run, base::Bind(&base::DoNothing)));
+ // Because the flush is sent from the binding, it only guarantees that the
+ // request has been received, not the response. The second flush waits for the
+ // response to be received.
+ impl0.binding()->FlushForTesting();
+ impl0.binding()->FlushForTesting();
+ EXPECT_TRUE(ptr0_callback_run);
+}
+
+TEST_F(AssociatedInterfaceTest,
+ AssociatedBindingFlushForTestingWithClosedPeer) {
+ scoped_refptr<MultiplexRouter> router0;
+ scoped_refptr<MultiplexRouter> router1;
+ CreateRouterPair(&router0, &router1);
+
+ AssociatedInterfaceRequest<IntegerSender> request;
+ {
+ IntegerSenderAssociatedPtrInfo ptr_info;
+ CreateIntegerSenderWithExistingRouters(router1, &ptr_info, router0,
+ &request);
+ }
+
+ IntegerSenderImpl impl(std::move(request));
+ bool called = false;
+ impl.set_connection_error_handler(base::Bind(&SetBool, &called));
+ impl.binding()->FlushForTesting();
+ EXPECT_TRUE(called);
+ impl.binding()->FlushForTesting();
+}
+
+TEST_F(AssociatedInterfaceTest, BindingFlushForTesting) {
+ IntegerSenderConnectionPtr ptr;
+ IntegerSenderConnectionImpl impl(MakeRequest(&ptr));
+ bool called = false;
+ ptr->AsyncGetSender(base::Bind(
+ &SetBoolWithUnusedParameter<IntegerSenderAssociatedPtrInfo>, &called));
+ EXPECT_FALSE(called);
+ impl.binding()->set_connection_error_handler(base::Bind(&Fail));
+ // Because the flush is sent from the binding, it only guarantees that the
+ // request has been received, not the response. The second flush waits for the
+ // response to be received.
+ impl.binding()->FlushForTesting();
+ impl.binding()->FlushForTesting();
+ EXPECT_TRUE(called);
+}
+
+TEST_F(AssociatedInterfaceTest, BindingFlushForTestingWithClosedPeer) {
+ IntegerSenderConnectionPtr ptr;
+ IntegerSenderConnectionImpl impl(MakeRequest(&ptr));
+ bool called = false;
+ impl.binding()->set_connection_error_handler(base::Bind(&SetBool, &called));
+ ptr.reset();
+ EXPECT_FALSE(called);
+ impl.binding()->FlushForTesting();
+ EXPECT_TRUE(called);
+ impl.binding()->FlushForTesting();
+}
+
+TEST_F(AssociatedInterfaceTest, StrongBindingFlushForTesting) {
+ IntegerSenderConnectionPtr ptr;
+ auto binding =
+ MakeStrongBinding(base::MakeUnique<IntegerSenderConnectionImpl>(
+ IntegerSenderConnectionRequest{}),
+ MakeRequest(&ptr));
+ bool called = false;
+ IntegerSenderAssociatedPtr sender_ptr;
+ ptr->GetSender(MakeRequest(&sender_ptr));
+ sender_ptr->Echo(1, base::Bind(&SetBoolWithUnusedParameter<int>, &called));
+ EXPECT_FALSE(called);
+ // Because the flush is sent from the binding, it only guarantees that the
+ // request has been received, not the response. The second flush waits for the
+ // response to be received.
+ ASSERT_TRUE(binding);
+ binding->FlushForTesting();
+ ASSERT_TRUE(binding);
+ binding->FlushForTesting();
+ EXPECT_TRUE(called);
+}
+
+TEST_F(AssociatedInterfaceTest, StrongBindingFlushForTestingWithClosedPeer) {
+ IntegerSenderConnectionPtr ptr;
+ bool called = false;
+ auto binding =
+ MakeStrongBinding(base::MakeUnique<IntegerSenderConnectionImpl>(
+ IntegerSenderConnectionRequest{}),
+ MakeRequest(&ptr));
+ binding->set_connection_error_handler(base::Bind(&SetBool, &called));
+ ptr.reset();
+ EXPECT_FALSE(called);
+ ASSERT_TRUE(binding);
+ binding->FlushForTesting();
+ EXPECT_TRUE(called);
+ ASSERT_FALSE(binding);
+}
+
+TEST_F(AssociatedInterfaceTest, PtrFlushForTesting) {
+ IntegerSenderConnectionPtr ptr;
+ IntegerSenderConnectionImpl impl(MakeRequest(&ptr));
+ bool called = false;
+ ptr.set_connection_error_handler(base::Bind(&Fail));
+ ptr->AsyncGetSender(base::Bind(
+ &SetBoolWithUnusedParameter<IntegerSenderAssociatedPtrInfo>, &called));
+ EXPECT_FALSE(called);
+ ptr.FlushForTesting();
+ EXPECT_TRUE(called);
+}
+
+TEST_F(AssociatedInterfaceTest, PtrFlushForTestingWithClosedPeer) {
+ IntegerSenderConnectionPtr ptr;
+ MakeRequest(&ptr);
+ bool called = false;
+ ptr.set_connection_error_handler(base::Bind(&SetBool, &called));
+ EXPECT_FALSE(called);
+ ptr.FlushForTesting();
+ EXPECT_TRUE(called);
+ ptr.FlushForTesting();
+}
+
+TEST_F(AssociatedInterfaceTest, AssociatedBindingConnectionErrorWithReason) {
+ AssociatedInterfaceRequest<IntegerSender> request;
+ IntegerSenderAssociatedPtrInfo ptr_info;
+ CreateIntegerSender(&ptr_info, &request);
+
+ IntegerSenderImpl impl(std::move(request));
+ AssociatedInterfacePtr<IntegerSender> ptr;
+ ptr.Bind(std::move(ptr_info));
+
+ base::RunLoop run_loop;
+ impl.binding()->set_connection_error_with_reason_handler(base::Bind(
+ [](const base::Closure& quit_closure, uint32_t custom_reason,
+ const std::string& description) {
+ EXPECT_EQ(123u, custom_reason);
+ EXPECT_EQ("farewell", description);
+ quit_closure.Run();
+ },
+ run_loop.QuitClosure()));
+
+ ptr.ResetWithReason(123u, "farewell");
+
+ run_loop.Run();
+}
+
+TEST_F(AssociatedInterfaceTest,
+ PendingAssociatedBindingConnectionErrorWithReason) {
+ // Test that AssociatedBinding is notified with connection error when the
+ // interface hasn't associated with a message pipe and the peer is closed.
+
+ IntegerSenderAssociatedPtr ptr;
+ IntegerSenderImpl impl(MakeRequest(&ptr));
+
+ base::RunLoop run_loop;
+ impl.binding()->set_connection_error_with_reason_handler(base::Bind(
+ [](const base::Closure& quit_closure, uint32_t custom_reason,
+ const std::string& description) {
+ EXPECT_EQ(123u, custom_reason);
+ EXPECT_EQ("farewell", description);
+ quit_closure.Run();
+ },
+ run_loop.QuitClosure()));
+
+ ptr.ResetWithReason(123u, "farewell");
+
+ run_loop.Run();
+}
+
+TEST_F(AssociatedInterfaceTest, AssociatedPtrConnectionErrorWithReason) {
+ AssociatedInterfaceRequest<IntegerSender> request;
+ IntegerSenderAssociatedPtrInfo ptr_info;
+ CreateIntegerSender(&ptr_info, &request);
+
+ IntegerSenderImpl impl(std::move(request));
+ AssociatedInterfacePtr<IntegerSender> ptr;
+ ptr.Bind(std::move(ptr_info));
+
+ base::RunLoop run_loop;
+ ptr.set_connection_error_with_reason_handler(base::Bind(
+ [](const base::Closure& quit_closure, uint32_t custom_reason,
+ const std::string& description) {
+ EXPECT_EQ(456u, custom_reason);
+ EXPECT_EQ("farewell", description);
+ quit_closure.Run();
+ },
+ run_loop.QuitClosure()));
+
+ impl.binding()->CloseWithReason(456u, "farewell");
+
+ run_loop.Run();
+}
+
+TEST_F(AssociatedInterfaceTest, PendingAssociatedPtrConnectionErrorWithReason) {
+ // Test that AssociatedInterfacePtr is notified with connection error when the
+ // interface hasn't associated with a message pipe and the peer is closed.
+
+ IntegerSenderAssociatedPtr ptr;
+ auto request = MakeRequest(&ptr);
+
+ base::RunLoop run_loop;
+ ptr.set_connection_error_with_reason_handler(base::Bind(
+ [](const base::Closure& quit_closure, uint32_t custom_reason,
+ const std::string& description) {
+ EXPECT_EQ(456u, custom_reason);
+ EXPECT_EQ("farewell", description);
+ quit_closure.Run();
+ },
+ run_loop.QuitClosure()));
+
+ request.ResetWithReason(456u, "farewell");
+
+ run_loop.Run();
+}
+
+TEST_F(AssociatedInterfaceTest, AssociatedRequestResetWithReason) {
+ AssociatedInterfaceRequest<IntegerSender> request;
+ IntegerSenderAssociatedPtrInfo ptr_info;
+ CreateIntegerSender(&ptr_info, &request);
+
+ AssociatedInterfacePtr<IntegerSender> ptr;
+ ptr.Bind(std::move(ptr_info));
+
+ base::RunLoop run_loop;
+ ptr.set_connection_error_with_reason_handler(base::Bind(
+ [](const base::Closure& quit_closure, uint32_t custom_reason,
+ const std::string& description) {
+ EXPECT_EQ(789u, custom_reason);
+ EXPECT_EQ("long time no see", description);
+ quit_closure.Run();
+ },
+ run_loop.QuitClosure()));
+
+ request.ResetWithReason(789u, "long time no see");
+
+ run_loop.Run();
+}
+
+TEST_F(AssociatedInterfaceTest, ThreadSafeAssociatedInterfacePtr) {
+ IntegerSenderConnectionPtr connection_ptr;
+ IntegerSenderConnectionImpl connection(MakeRequest(&connection_ptr));
+
+ IntegerSenderAssociatedPtr sender;
+ connection_ptr->GetSender(MakeRequest(&sender));
+
+ scoped_refptr<ThreadSafeIntegerSenderAssociatedPtr> thread_safe_sender =
+ ThreadSafeIntegerSenderAssociatedPtr::Create(std::move(sender));
+
+ {
+ // Test the thread safe pointer can be used from the interface ptr thread.
+ int32_t echoed_value = 0;
+ base::RunLoop run_loop;
+ (*thread_safe_sender)
+ ->Echo(123, base::Bind(&CaptureInt32, &echoed_value,
+ run_loop.QuitClosure()));
+ run_loop.Run();
+ EXPECT_EQ(123, echoed_value);
+ }
+
+ // Test the thread safe pointer can be used from another thread.
+ base::RunLoop run_loop;
+ base::Thread other_thread("service test thread");
+ other_thread.Start();
+
+ auto run_method = base::Bind(
+ [](const scoped_refptr<base::TaskRunner>& main_task_runner,
+ const base::Closure& quit_closure,
+ const scoped_refptr<ThreadSafeIntegerSenderAssociatedPtr>&
+ thread_safe_sender) {
+ auto done_callback = base::Bind(
+ [](const scoped_refptr<base::TaskRunner>& main_task_runner,
+ const base::Closure& quit_closure,
+ base::PlatformThreadId thread_id, int32_t result) {
+ EXPECT_EQ(123, result);
+ // Validate the callback is invoked on the calling thread.
+ EXPECT_EQ(thread_id, base::PlatformThread::CurrentId());
+ // Notify the run_loop to quit.
+ main_task_runner->PostTask(FROM_HERE, quit_closure);
+ });
+ (*thread_safe_sender)
+ ->Echo(123,
+ base::Bind(done_callback, main_task_runner, quit_closure,
+ base::PlatformThread::CurrentId()));
+ },
+ base::SequencedTaskRunnerHandle::Get(), run_loop.QuitClosure(),
+ thread_safe_sender);
+ other_thread.message_loop()->task_runner()->PostTask(FROM_HERE, run_method);
+
+ // Block until the method callback is called on the background thread.
+ run_loop.Run();
+}
+
+struct ForwarderTestContext {
+ IntegerSenderConnectionPtr connection_ptr;
+ std::unique_ptr<IntegerSenderConnectionImpl> interface_impl;
+ IntegerSenderAssociatedRequest sender_request;
+};
+
+TEST_F(AssociatedInterfaceTest,
+ ThreadSafeAssociatedInterfacePtrWithTaskRunner) {
+ // Start the thread from where we'll bind the interface pointer.
+ base::Thread other_thread("service test thread");
+ other_thread.Start();
+ const scoped_refptr<base::SingleThreadTaskRunner>& other_thread_task_runner =
+ other_thread.message_loop()->task_runner();
+
+ ForwarderTestContext* context = new ForwarderTestContext();
+ IntegerSenderAssociatedPtrInfo sender_info;
+ base::WaitableEvent sender_info_bound_event(
+ base::WaitableEvent::ResetPolicy::MANUAL,
+ base::WaitableEvent::InitialState::NOT_SIGNALED);
+ auto setup = [](base::WaitableEvent* sender_info_bound_event,
+ IntegerSenderAssociatedPtrInfo* sender_info,
+ ForwarderTestContext* context) {
+ context->interface_impl = base::MakeUnique<IntegerSenderConnectionImpl>(
+ MakeRequest(&context->connection_ptr));
+
+ auto sender_request = MakeRequest(sender_info);
+ context->connection_ptr->GetSender(std::move(sender_request));
+
+ // Unblock the main thread as soon as |sender_info| is set.
+ sender_info_bound_event->Signal();
+ };
+ other_thread_task_runner->PostTask(
+ FROM_HERE,
+ base::Bind(setup, &sender_info_bound_event, &sender_info, context));
+ sender_info_bound_event.Wait();
+
+ // Create a ThreadSafeAssociatedPtr that binds on the background thread and is
+ // associated with |connection_ptr| there.
+ scoped_refptr<ThreadSafeIntegerSenderAssociatedPtr> thread_safe_ptr =
+ ThreadSafeIntegerSenderAssociatedPtr::Create(std::move(sender_info),
+ other_thread_task_runner);
+
+ // Issue a call on the thread-safe ptr immediately. Note that this may happen
+ // before the interface is bound on the background thread, and that must be
+ // OK.
+ {
+ auto echo_callback =
+ base::Bind([](const base::Closure& quit_closure, int32_t result) {
+ EXPECT_EQ(123, result);
+ quit_closure.Run();
+ });
+ base::RunLoop run_loop;
+ (*thread_safe_ptr)
+ ->Echo(123, base::Bind(echo_callback, run_loop.QuitClosure()));
+
+ // Block until the method callback is called.
+ run_loop.Run();
+ }
+
+ other_thread_task_runner->DeleteSoon(FROM_HERE, context);
+
+ // Reset the pointer now so the InterfacePtr associated resources can be
+ // deleted before the background thread's message loop is invalidated.
+ thread_safe_ptr = nullptr;
+}
+
+class DiscardingAssociatedPingProviderProvider
+ : public AssociatedPingProviderProvider {
+ public:
+ void GetPingProvider(
+ AssociatedPingProviderAssociatedRequest request) override {}
+};
+
+TEST_F(AssociatedInterfaceTest, CloseWithoutBindingAssociatedRequest) {
+ DiscardingAssociatedPingProviderProvider ping_provider_provider;
+ mojo::Binding<AssociatedPingProviderProvider> binding(
+ &ping_provider_provider);
+ auto provider_provider = binding.CreateInterfacePtrAndBind();
+ AssociatedPingProviderAssociatedPtr provider;
+ provider_provider->GetPingProvider(mojo::MakeRequest(&provider));
+ PingServiceAssociatedPtr ping;
+ provider->GetPing(mojo::MakeRequest(&ping));
+ base::RunLoop run_loop;
+ ping.set_connection_error_handler(run_loop.QuitClosure());
+ run_loop.Run();
+}
+
} // namespace
} // namespace test
} // namespace mojo
diff --git a/mojo/public/cpp/bindings/tests/bind_task_runner_unittest.cc b/mojo/public/cpp/bindings/tests/bind_task_runner_unittest.cc
index dab64f0..0c777ec 100644
--- a/mojo/public/cpp/bindings/tests/bind_task_runner_unittest.cc
+++ b/mojo/public/cpp/bindings/tests/bind_task_runner_unittest.cc
@@ -10,7 +10,6 @@
#include "base/synchronization/waitable_event.h"
#include "base/threading/platform_thread.h"
#include "mojo/public/cpp/bindings/associated_binding.h"
-#include "mojo/public/cpp/bindings/associated_group.h"
#include "mojo/public/cpp/bindings/associated_interface_ptr.h"
#include "mojo/public/cpp/bindings/associated_interface_ptr_info.h"
#include "mojo/public/cpp/bindings/associated_interface_request.h"
@@ -187,7 +186,7 @@ class BindTaskRunnerTest : public testing::Test {
binding_task_runner_ = scoped_refptr<TestTaskRunner>(new TestTaskRunner);
ptr_task_runner_ = scoped_refptr<TestTaskRunner>(new TestTaskRunner);
- auto request = GetProxy(&ptr_, ptr_task_runner_);
+ auto request = MakeRequest(&ptr_, ptr_task_runner_);
impl_.reset(new ImplType(std::move(request), binding_task_runner_));
}
@@ -213,7 +212,7 @@ class AssociatedBindTaskRunnerTest : public testing::Test {
sender_ptr_task_runner_ = scoped_refptr<TestTaskRunner>(new TestTaskRunner);
auto connection_request =
- GetProxy(&connection_ptr_, connection_ptr_task_runner_);
+ MakeRequest(&connection_ptr_, connection_ptr_task_runner_);
connection_impl_.reset(new IntegerSenderConnectionImpl(
std::move(connection_request), connection_binding_task_runner_,
sender_binding_task_runner_));
@@ -222,9 +221,8 @@ class AssociatedBindTaskRunnerTest : public testing::Test {
base::Bind(&AssociatedBindTaskRunnerTest::QuitTaskRunner,
base::Unretained(this)));
- connection_ptr_->GetSender(GetProxy(&sender_ptr_,
- connection_ptr_.associated_group(),
- sender_ptr_task_runner_));
+ connection_ptr_->GetSender(
+ MakeRequest(&sender_ptr_, sender_ptr_task_runner_));
connection_binding_task_runner_->Run();
}
diff --git a/mojo/public/cpp/bindings/tests/binding_callback_unittest.cc b/mojo/public/cpp/bindings/tests/binding_callback_unittest.cc
index 02b082a..43122ce 100644
--- a/mojo/public/cpp/bindings/tests/binding_callback_unittest.cc
+++ b/mojo/public/cpp/bindings/tests/binding_callback_unittest.cc
@@ -9,10 +9,10 @@
#include "base/logging.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
+#include "base/test/gtest_util.h"
#include "build/build_config.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "mojo/public/cpp/bindings/interface_ptr.h"
-#include "mojo/public/cpp/bindings/string.h"
#include "mojo/public/cpp/system/message_pipe.h"
#include "mojo/public/cpp/test_support/test_support.h"
#include "mojo/public/interfaces/bindings/tests/sample_interfaces.mojom.h"
@@ -140,7 +140,7 @@ class BindingCallbackTest : public testing::Test {
TEST_F(BindingCallbackTest, Basic) {
// Create the ServerImpl and the Binding.
InterfaceImpl server_impl;
- Binding<sample::Provider> binding(&server_impl, GetProxy(&interface_ptr_));
+ Binding<sample::Provider> binding(&server_impl, MakeRequest(&interface_ptr_));
// Initialize the test values.
server_impl.resetLastServerValueSeen();
@@ -199,7 +199,8 @@ TEST_F(BindingCallbackTest, DeleteBindingThenRunCallback) {
base::RunLoop run_loop;
{
// Create the binding in an inner scope so it can be deleted first.
- Binding<sample::Provider> binding(&server_impl, GetProxy(&interface_ptr_));
+ Binding<sample::Provider> binding(&server_impl,
+ MakeRequest(&interface_ptr_));
interface_ptr_.set_connection_error_handler(run_loop.QuitClosure());
// Initialize the test values.
@@ -244,7 +245,8 @@ TEST_F(BindingCallbackTest, DeleteBindingThenDeleteCallback) {
InterfaceImpl server_impl;
{
// Create the binding in an inner scope so it can be deleted first.
- Binding<sample::Provider> binding(&server_impl, GetProxy(&interface_ptr_));
+ Binding<sample::Provider> binding(&server_impl,
+ MakeRequest(&interface_ptr_));
// Initialize the test values.
server_impl.resetLastServerValueSeen();
@@ -275,7 +277,7 @@ TEST_F(BindingCallbackTest, DeleteBindingThenDeleteCallback) {
TEST_F(BindingCallbackTest, CloseBindingBeforeDeletingCallback) {
// Create the ServerImpl and the Binding.
InterfaceImpl server_impl;
- Binding<sample::Provider> binding(&server_impl, GetProxy(&interface_ptr_));
+ Binding<sample::Provider> binding(&server_impl, MakeRequest(&interface_ptr_));
// Initialize the test values.
server_impl.resetLastServerValueSeen();
@@ -310,7 +312,7 @@ TEST_F(BindingCallbackTest, CloseBindingBeforeDeletingCallback) {
TEST_F(BindingCallbackTest, DeleteCallbackBeforeBindingDeathTest) {
// Create the ServerImpl and the Binding.
InterfaceImpl server_impl;
- Binding<sample::Provider> binding(&server_impl, GetProxy(&interface_ptr_));
+ Binding<sample::Provider> binding(&server_impl, MakeRequest(&interface_ptr_));
// Initialize the test values.
server_impl.resetLastServerValueSeen();
@@ -328,17 +330,7 @@ TEST_F(BindingCallbackTest, DeleteCallbackBeforeBindingDeathTest) {
EXPECT_EQ(7, server_impl.last_server_value_seen());
EXPECT_EQ(0, last_client_callback_value_seen_);
-#if (!defined(NDEBUG) || defined(DCHECK_ALWAYS_ON)) && !defined(OS_ANDROID)
- // Delete the callback without running it. This should cause a crash in debug
- // builds due to a DCHECK.
- std::string regex("Check failed: !is_valid");
-#if defined(OS_WIN)
- // TODO(msw): Fix MOJO_DCHECK logs and EXPECT_DEATH* on Win: crbug.com/535014
- regex.clear();
-#endif // OS_WIN
- EXPECT_DEATH_IF_SUPPORTED(server_impl.DeleteCallback(), regex.c_str());
-#endif // (!defined(NDEBUG) || defined(DCHECK_ALWAYS_ON)) &&
- // !defined(OS_ANDROID)
+ EXPECT_DCHECK_DEATH(server_impl.DeleteCallback());
}
} // namespace
diff --git a/mojo/public/cpp/bindings/tests/binding_set_unittest.cc b/mojo/public/cpp/bindings/tests/binding_set_unittest.cc
new file mode 100644
index 0000000..07acfbe
--- /dev/null
+++ b/mojo/public/cpp/bindings/tests/binding_set_unittest.cc
@@ -0,0 +1,416 @@
+// Copyright 2016 The Chromium 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 <memory>
+#include <utility>
+
+#include "base/message_loop/message_loop.h"
+#include "base/run_loop.h"
+#include "mojo/public/cpp/bindings/associated_binding_set.h"
+#include "mojo/public/cpp/bindings/binding_set.h"
+#include "mojo/public/cpp/bindings/strong_binding_set.h"
+#include "mojo/public/interfaces/bindings/tests/ping_service.mojom.h"
+#include "mojo/public/interfaces/bindings/tests/test_associated_interfaces.mojom.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace mojo {
+namespace test {
+namespace {
+
+class BindingSetTest : public testing::Test {
+ public:
+ BindingSetTest() {}
+ ~BindingSetTest() override {}
+
+ base::MessageLoop& loop() { return loop_; }
+
+ private:
+ base::MessageLoop loop_;
+
+ DISALLOW_COPY_AND_ASSIGN(BindingSetTest);
+};
+
+template <typename BindingSetType, typename ContextType>
+void ExpectContextHelper(BindingSetType* binding_set,
+ ContextType expected_context) {
+ EXPECT_EQ(expected_context, binding_set->dispatch_context());
+}
+
+template <typename BindingSetType, typename ContextType>
+base::Closure ExpectContext(BindingSetType* binding_set,
+ ContextType expected_context) {
+ return base::Bind(
+ &ExpectContextHelper<BindingSetType, ContextType>, binding_set,
+ expected_context);
+}
+
+base::Closure Sequence(const base::Closure& first,
+ const base::Closure& second) {
+ return base::Bind(
+ [] (const base::Closure& first, const base::Closure& second) {
+ first.Run();
+ second.Run();
+ }, first, second);
+}
+
+class PingImpl : public PingService {
+ public:
+ PingImpl() {}
+ ~PingImpl() override {}
+
+ void set_ping_handler(const base::Closure& handler) {
+ ping_handler_ = handler;
+ }
+
+ private:
+ // PingService:
+ void Ping(const PingCallback& callback) override {
+ if (!ping_handler_.is_null())
+ ping_handler_.Run();
+ callback.Run();
+ }
+
+ base::Closure ping_handler_;
+};
+
+TEST_F(BindingSetTest, BindingSetContext) {
+ PingImpl impl;
+
+ BindingSet<PingService, int> bindings;
+ PingServicePtr ping_a, ping_b;
+ bindings.AddBinding(&impl, MakeRequest(&ping_a), 1);
+ bindings.AddBinding(&impl, MakeRequest(&ping_b), 2);
+
+ {
+ impl.set_ping_handler(ExpectContext(&bindings, 1));
+ base::RunLoop loop;
+ ping_a->Ping(loop.QuitClosure());
+ loop.Run();
+ }
+
+ {
+ impl.set_ping_handler(ExpectContext(&bindings, 2));
+ base::RunLoop loop;
+ ping_b->Ping(loop.QuitClosure());
+ loop.Run();
+ }
+
+ {
+ base::RunLoop loop;
+ bindings.set_connection_error_handler(
+ Sequence(ExpectContext(&bindings, 1), loop.QuitClosure()));
+ ping_a.reset();
+ loop.Run();
+ }
+
+ {
+ base::RunLoop loop;
+ bindings.set_connection_error_handler(
+ Sequence(ExpectContext(&bindings, 2), loop.QuitClosure()));
+ ping_b.reset();
+ loop.Run();
+ }
+
+ EXPECT_TRUE(bindings.empty());
+}
+
+TEST_F(BindingSetTest, BindingSetConnectionErrorWithReason) {
+ PingImpl impl;
+ PingServicePtr ptr;
+ BindingSet<PingService> bindings;
+ bindings.AddBinding(&impl, MakeRequest(&ptr));
+
+ base::RunLoop run_loop;
+ bindings.set_connection_error_with_reason_handler(base::Bind(
+ [](const base::Closure& quit_closure, uint32_t custom_reason,
+ const std::string& description) {
+ EXPECT_EQ(1024u, custom_reason);
+ EXPECT_EQ("bye", description);
+ quit_closure.Run();
+ },
+ run_loop.QuitClosure()));
+
+ ptr.ResetWithReason(1024u, "bye");
+}
+
+class PingProviderImpl : public AssociatedPingProvider, public PingService {
+ public:
+ PingProviderImpl() {}
+ ~PingProviderImpl() override {}
+
+ void set_new_ping_context(int context) { new_ping_context_ = context; }
+
+ void set_new_ping_handler(const base::Closure& handler) {
+ new_ping_handler_ = handler;
+ }
+
+ void set_ping_handler(const base::Closure& handler) {
+ ping_handler_ = handler;
+ }
+
+ AssociatedBindingSet<PingService, int>& ping_bindings() {
+ return ping_bindings_;
+ }
+
+ private:
+ // AssociatedPingProvider:
+ void GetPing(PingServiceAssociatedRequest request) override {
+ ping_bindings_.AddBinding(this, std::move(request), new_ping_context_);
+ if (!new_ping_handler_.is_null())
+ new_ping_handler_.Run();
+ }
+
+ // PingService:
+ void Ping(const PingCallback& callback) override {
+ if (!ping_handler_.is_null())
+ ping_handler_.Run();
+ callback.Run();
+ }
+
+ AssociatedBindingSet<PingService, int> ping_bindings_;
+ int new_ping_context_ = -1;
+ base::Closure ping_handler_;
+ base::Closure new_ping_handler_;
+};
+
+TEST_F(BindingSetTest, AssociatedBindingSetContext) {
+ AssociatedPingProviderPtr provider;
+ PingProviderImpl impl;
+ Binding<AssociatedPingProvider> binding(&impl, MakeRequest(&provider));
+
+ PingServiceAssociatedPtr ping_a;
+ {
+ base::RunLoop loop;
+ impl.set_new_ping_context(1);
+ impl.set_new_ping_handler(loop.QuitClosure());
+ provider->GetPing(MakeRequest(&ping_a));
+ loop.Run();
+ }
+
+ PingServiceAssociatedPtr ping_b;
+ {
+ base::RunLoop loop;
+ impl.set_new_ping_context(2);
+ impl.set_new_ping_handler(loop.QuitClosure());
+ provider->GetPing(MakeRequest(&ping_b));
+ loop.Run();
+ }
+
+ {
+ impl.set_ping_handler(ExpectContext(&impl.ping_bindings(), 1));
+ base::RunLoop loop;
+ ping_a->Ping(loop.QuitClosure());
+ loop.Run();
+ }
+
+ {
+ impl.set_ping_handler(ExpectContext(&impl.ping_bindings(), 2));
+ base::RunLoop loop;
+ ping_b->Ping(loop.QuitClosure());
+ loop.Run();
+ }
+
+ {
+ base::RunLoop loop;
+ impl.ping_bindings().set_connection_error_handler(
+ Sequence(ExpectContext(&impl.ping_bindings(), 1), loop.QuitClosure()));
+ ping_a.reset();
+ loop.Run();
+ }
+
+ {
+ base::RunLoop loop;
+ impl.ping_bindings().set_connection_error_handler(
+ Sequence(ExpectContext(&impl.ping_bindings(), 2), loop.QuitClosure()));
+ ping_b.reset();
+ loop.Run();
+ }
+
+ EXPECT_TRUE(impl.ping_bindings().empty());
+}
+
+TEST_F(BindingSetTest, MasterInterfaceBindingSetContext) {
+ AssociatedPingProviderPtr provider_a, provider_b;
+ PingProviderImpl impl;
+ BindingSet<AssociatedPingProvider, int> bindings;
+
+ bindings.AddBinding(&impl, MakeRequest(&provider_a), 1);
+ bindings.AddBinding(&impl, MakeRequest(&provider_b), 2);
+
+ {
+ PingServiceAssociatedPtr ping;
+ base::RunLoop loop;
+ impl.set_new_ping_handler(
+ Sequence(ExpectContext(&bindings, 1), loop.QuitClosure()));
+ provider_a->GetPing(MakeRequest(&ping));
+ loop.Run();
+ }
+
+ {
+ PingServiceAssociatedPtr ping;
+ base::RunLoop loop;
+ impl.set_new_ping_handler(
+ Sequence(ExpectContext(&bindings, 2), loop.QuitClosure()));
+ provider_b->GetPing(MakeRequest(&ping));
+ loop.Run();
+ }
+
+ {
+ base::RunLoop loop;
+ bindings.set_connection_error_handler(
+ Sequence(ExpectContext(&bindings, 1), loop.QuitClosure()));
+ provider_a.reset();
+ loop.Run();
+ }
+
+ {
+ base::RunLoop loop;
+ bindings.set_connection_error_handler(
+ Sequence(ExpectContext(&bindings, 2), loop.QuitClosure()));
+ provider_b.reset();
+ loop.Run();
+ }
+
+ EXPECT_TRUE(bindings.empty());
+}
+
+TEST_F(BindingSetTest, PreDispatchHandler) {
+ PingImpl impl;
+
+ BindingSet<PingService, int> bindings;
+ PingServicePtr ping_a, ping_b;
+ bindings.AddBinding(&impl, MakeRequest(&ping_a), 1);
+ bindings.AddBinding(&impl, MakeRequest(&ping_b), 2);
+
+ {
+ bindings.set_pre_dispatch_handler(base::Bind([] (const int& context) {
+ EXPECT_EQ(1, context);
+ }));
+ base::RunLoop loop;
+ ping_a->Ping(loop.QuitClosure());
+ loop.Run();
+ }
+
+ {
+ bindings.set_pre_dispatch_handler(base::Bind([] (const int& context) {
+ EXPECT_EQ(2, context);
+ }));
+ base::RunLoop loop;
+ ping_b->Ping(loop.QuitClosure());
+ loop.Run();
+ }
+
+ {
+ base::RunLoop loop;
+ bindings.set_pre_dispatch_handler(
+ base::Bind([](base::RunLoop* loop, const int& context) {
+ EXPECT_EQ(1, context);
+ loop->Quit();
+ }, &loop));
+ ping_a.reset();
+ loop.Run();
+ }
+
+ {
+ base::RunLoop loop;
+ bindings.set_pre_dispatch_handler(
+ base::Bind([](base::RunLoop* loop, const int& context) {
+ EXPECT_EQ(2, context);
+ loop->Quit();
+ }, &loop));
+ ping_b.reset();
+ loop.Run();
+ }
+
+ EXPECT_TRUE(bindings.empty());
+}
+
+TEST_F(BindingSetTest, AssociatedBindingSetConnectionErrorWithReason) {
+ AssociatedPingProviderPtr master_ptr;
+ PingProviderImpl master_impl;
+ Binding<AssociatedPingProvider> master_binding(&master_impl, &master_ptr);
+
+ base::RunLoop run_loop;
+ master_impl.ping_bindings().set_connection_error_with_reason_handler(
+ base::Bind(
+ [](const base::Closure& quit_closure, uint32_t custom_reason,
+ const std::string& description) {
+ EXPECT_EQ(2048u, custom_reason);
+ EXPECT_EQ("bye", description);
+ quit_closure.Run();
+ },
+ run_loop.QuitClosure()));
+
+ PingServiceAssociatedPtr ptr;
+ master_ptr->GetPing(MakeRequest(&ptr));
+
+ ptr.ResetWithReason(2048u, "bye");
+
+ run_loop.Run();
+}
+
+class PingInstanceCounter : public PingService {
+ public:
+ PingInstanceCounter() { ++instance_count; }
+ ~PingInstanceCounter() override { --instance_count; }
+
+ void Ping(const PingCallback& callback) override {}
+
+ static int instance_count;
+};
+int PingInstanceCounter::instance_count = 0;
+
+TEST_F(BindingSetTest, StrongBinding_Destructor) {
+ PingServicePtr ping_a, ping_b;
+ auto bindings = base::MakeUnique<StrongBindingSet<PingService>>();
+
+ bindings->AddBinding(base::MakeUnique<PingInstanceCounter>(),
+ mojo::MakeRequest(&ping_a));
+ EXPECT_EQ(1, PingInstanceCounter::instance_count);
+
+ bindings->AddBinding(base::MakeUnique<PingInstanceCounter>(),
+ mojo::MakeRequest(&ping_b));
+ EXPECT_EQ(2, PingInstanceCounter::instance_count);
+
+ bindings.reset();
+ EXPECT_EQ(0, PingInstanceCounter::instance_count);
+}
+
+TEST_F(BindingSetTest, StrongBinding_ConnectionError) {
+ PingServicePtr ping_a, ping_b;
+ StrongBindingSet<PingService> bindings;
+ bindings.AddBinding(base::MakeUnique<PingInstanceCounter>(),
+ mojo::MakeRequest(&ping_a));
+ bindings.AddBinding(base::MakeUnique<PingInstanceCounter>(),
+ mojo::MakeRequest(&ping_b));
+ EXPECT_EQ(2, PingInstanceCounter::instance_count);
+
+ ping_a.reset();
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(1, PingInstanceCounter::instance_count);
+
+ ping_b.reset();
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(0, PingInstanceCounter::instance_count);
+}
+
+TEST_F(BindingSetTest, StrongBinding_RemoveBinding) {
+ PingServicePtr ping_a, ping_b;
+ StrongBindingSet<PingService> bindings;
+ BindingId binding_id_a = bindings.AddBinding(
+ base::MakeUnique<PingInstanceCounter>(), mojo::MakeRequest(&ping_a));
+ BindingId binding_id_b = bindings.AddBinding(
+ base::MakeUnique<PingInstanceCounter>(), mojo::MakeRequest(&ping_b));
+ EXPECT_EQ(2, PingInstanceCounter::instance_count);
+
+ EXPECT_TRUE(bindings.RemoveBinding(binding_id_a));
+ EXPECT_EQ(1, PingInstanceCounter::instance_count);
+
+ EXPECT_TRUE(bindings.RemoveBinding(binding_id_b));
+ EXPECT_EQ(0, PingInstanceCounter::instance_count);
+}
+
+} // namespace
+} // namespace test
+} // namespace mojo
diff --git a/mojo/public/cpp/bindings/tests/binding_unittest.cc b/mojo/public/cpp/bindings/tests/binding_unittest.cc
index 4838ee8..e76993b 100644
--- a/mojo/public/cpp/bindings/tests/binding_unittest.cc
+++ b/mojo/public/cpp/bindings/tests/binding_unittest.cc
@@ -11,9 +11,12 @@
#include <utility>
#include "base/macros.h"
+#include "base/memory/ptr_util.h"
+#include "base/memory/weak_ptr.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "mojo/public/cpp/bindings/strong_binding.h"
+#include "mojo/public/interfaces/bindings/tests/ping_service.mojom.h"
#include "mojo/public/interfaces/bindings/tests/sample_interfaces.mojom.h"
#include "mojo/public/interfaces/bindings/tests/sample_service.mojom.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -63,7 +66,8 @@ void DoSetFlagAndRunClosure(bool* flag,
const base::Closure& closure,
Args... args) {
*flag = true;
- closure.Run();
+ if (!closure.is_null())
+ closure.Run();
}
template <typename... Args>
@@ -80,7 +84,7 @@ using BindingTest = BindingTestBase;
TEST_F(BindingTest, Close) {
bool called = false;
sample::ServicePtr ptr;
- auto request = GetProxy(&ptr);
+ auto request = MakeRequest(&ptr);
base::RunLoop run_loop;
ptr.set_connection_error_handler(
SetFlagAndRunClosure(&called, run_loop.QuitClosure()));
@@ -98,7 +102,7 @@ TEST_F(BindingTest, DestroyClosesMessagePipe) {
bool encountered_error = false;
ServiceImpl impl;
sample::ServicePtr ptr;
- auto request = GetProxy(&ptr);
+ auto request = MakeRequest(&ptr);
base::RunLoop run_loop;
ptr.set_connection_error_handler(
SetFlagAndRunClosure(&encountered_error, run_loop.QuitClosure()));
@@ -134,7 +138,7 @@ TEST_F(BindingTest, ConnectionError) {
{
ServiceImpl impl;
sample::ServicePtr ptr;
- Binding<sample::Service> binding(&impl, GetProxy(&ptr));
+ Binding<sample::Service> binding(&impl, MakeRequest(&ptr));
base::RunLoop run_loop;
binding.set_connection_error_handler(
SetFlagAndRunClosure(&called, run_loop.QuitClosure()));
@@ -153,7 +157,7 @@ TEST_F(BindingTest, ConnectionError) {
TEST_F(BindingTest, CloseDoesntCallConnectionErrorHandler) {
ServiceImpl impl;
sample::ServicePtr ptr;
- Binding<sample::Service> binding(&impl, GetProxy(&ptr));
+ Binding<sample::Service> binding(&impl, MakeRequest(&ptr));
bool called = false;
binding.set_connection_error_handler(SetFlagAndRunClosure(&called));
binding.Close();
@@ -200,7 +204,7 @@ TEST_F(BindingTest, SelfDeleteOnConnectionError) {
// This should delete itself on connection error.
base::RunLoop run_loop;
new ServiceImplWithBinding(&was_deleted, run_loop.QuitClosure(),
- GetProxy(&ptr));
+ MakeRequest(&ptr));
ptr.reset();
EXPECT_FALSE(was_deleted);
run_loop.Run();
@@ -211,7 +215,7 @@ TEST_F(BindingTest, SelfDeleteOnConnectionError) {
TEST_F(BindingTest, Unbind) {
ServiceImpl impl;
sample::ServicePtr ptr;
- Binding<sample::Service> binding(&impl, GetProxy(&ptr));
+ Binding<sample::Service> binding(&impl, MakeRequest(&ptr));
bool called = false;
base::RunLoop run_loop;
@@ -269,7 +273,7 @@ TEST_F(BindingTest, PauseResume) {
bool called = false;
base::RunLoop run_loop;
sample::ServicePtr ptr;
- auto request = GetProxy(&ptr);
+ auto request = MakeRequest(&ptr);
ServiceImpl impl;
Binding<sample::Service> binding(&impl, std::move(request));
binding.PauseIncomingMethodCallProcessing();
@@ -292,7 +296,7 @@ TEST_F(BindingTest, ErrorHandleNotRunWhilePaused) {
bool called = false;
base::RunLoop run_loop;
sample::ServicePtr ptr;
- auto request = GetProxy(&ptr);
+ auto request = MakeRequest(&ptr);
ServiceImpl impl;
Binding<sample::Service> binding(&impl, std::move(request));
binding.set_connection_error_handler(
@@ -310,6 +314,177 @@ TEST_F(BindingTest, ErrorHandleNotRunWhilePaused) {
EXPECT_TRUE(called);
}
+class PingServiceImpl : public test::PingService {
+ public:
+ PingServiceImpl() {}
+ ~PingServiceImpl() override {}
+
+ // test::PingService:
+ void Ping(const PingCallback& callback) override {
+ if (!ping_handler_.is_null())
+ ping_handler_.Run();
+ callback.Run();
+ }
+
+ void set_ping_handler(const base::Closure& handler) {
+ ping_handler_ = handler;
+ }
+
+ private:
+ base::Closure ping_handler_;
+
+ DISALLOW_COPY_AND_ASSIGN(PingServiceImpl);
+};
+
+class CallbackFilter : public MessageReceiver {
+ public:
+ explicit CallbackFilter(const base::Closure& callback)
+ : callback_(callback) {}
+ ~CallbackFilter() override {}
+
+ static std::unique_ptr<CallbackFilter> Wrap(const base::Closure& callback) {
+ return base::MakeUnique<CallbackFilter>(callback);
+ }
+
+ // MessageReceiver:
+ bool Accept(Message* message) override {
+ callback_.Run();
+ return true;
+ }
+
+ private:
+ const base::Closure callback_;
+};
+
+// Verifies that message filters are notified in the order they were added and
+// are always notified before a message is dispatched.
+TEST_F(BindingTest, MessageFilter) {
+ test::PingServicePtr ptr;
+ PingServiceImpl impl;
+ mojo::Binding<test::PingService> binding(&impl, MakeRequest(&ptr));
+
+ int status = 0;
+ auto handler_helper = [] (int* status, int expected_status, int new_status) {
+ EXPECT_EQ(expected_status, *status);
+ *status = new_status;
+ };
+ auto create_handler = [&] (int expected_status, int new_status) {
+ return base::Bind(handler_helper, &status, expected_status, new_status);
+ };
+
+ binding.AddFilter(CallbackFilter::Wrap(create_handler(0, 1)));
+ binding.AddFilter(CallbackFilter::Wrap(create_handler(1, 2)));
+ impl.set_ping_handler(create_handler(2, 3));
+
+ for (int i = 0; i < 10; ++i) {
+ status = 0;
+ base::RunLoop loop;
+ ptr->Ping(loop.QuitClosure());
+ loop.Run();
+ EXPECT_EQ(3, status);
+ }
+}
+
+void Fail() {
+ FAIL() << "Unexpected connection error";
+}
+
+TEST_F(BindingTest, FlushForTesting) {
+ bool called = false;
+ sample::ServicePtr ptr;
+ auto request = MakeRequest(&ptr);
+ ServiceImpl impl;
+ Binding<sample::Service> binding(&impl, std::move(request));
+ binding.set_connection_error_handler(base::Bind(&Fail));
+
+ ptr->Frobinate(nullptr, sample::Service::BazOptions::REGULAR, nullptr,
+ SetFlagAndRunClosure<int32_t>(&called));
+ EXPECT_FALSE(called);
+ // Because the flush is sent from the binding, it only guarantees that the
+ // request has been received, not the response. The second flush waits for the
+ // response to be received.
+ binding.FlushForTesting();
+ binding.FlushForTesting();
+ EXPECT_TRUE(called);
+}
+
+TEST_F(BindingTest, FlushForTestingWithClosedPeer) {
+ bool called = false;
+ sample::ServicePtr ptr;
+ auto request = MakeRequest(&ptr);
+ ServiceImpl impl;
+ Binding<sample::Service> binding(&impl, std::move(request));
+ binding.set_connection_error_handler(SetFlagAndRunClosure(&called));
+ ptr.reset();
+
+ EXPECT_FALSE(called);
+ binding.FlushForTesting();
+ EXPECT_TRUE(called);
+ binding.FlushForTesting();
+}
+
+TEST_F(BindingTest, ConnectionErrorWithReason) {
+ sample::ServicePtr ptr;
+ auto request = MakeRequest(&ptr);
+ ServiceImpl impl;
+ Binding<sample::Service> binding(&impl, std::move(request));
+
+ base::RunLoop run_loop;
+ binding.set_connection_error_with_reason_handler(base::Bind(
+ [](const base::Closure& quit_closure, uint32_t custom_reason,
+ const std::string& description) {
+ EXPECT_EQ(1234u, custom_reason);
+ EXPECT_EQ("hello", description);
+ quit_closure.Run();
+ },
+ run_loop.QuitClosure()));
+
+ ptr.ResetWithReason(1234u, "hello");
+
+ run_loop.Run();
+}
+
+template <typename T>
+struct WeakPtrImplRefTraits {
+ using PointerType = base::WeakPtr<T>;
+
+ static bool IsNull(const base::WeakPtr<T>& ptr) { return !ptr; }
+ static T* GetRawPointer(base::WeakPtr<T>* ptr) { return ptr->get(); }
+};
+
+template <typename T>
+using WeakBinding = Binding<T, WeakPtrImplRefTraits<T>>;
+
+TEST_F(BindingTest, CustomImplPointerType) {
+ PingServiceImpl impl;
+ base::WeakPtrFactory<test::PingService> weak_factory(&impl);
+
+ test::PingServicePtr proxy;
+ WeakBinding<test::PingService> binding(weak_factory.GetWeakPtr(),
+ MakeRequest(&proxy));
+
+ {
+ // Ensure the binding is functioning.
+ base::RunLoop run_loop;
+ proxy->Ping(run_loop.QuitClosure());
+ run_loop.Run();
+ }
+
+ {
+ // Attempt to dispatch another message after the WeakPtr is invalidated.
+ base::Closure assert_not_reached = base::Bind([] { NOTREACHED(); });
+ impl.set_ping_handler(assert_not_reached);
+ proxy->Ping(assert_not_reached);
+
+ // The binding will close its end of the pipe which will trigger a
+ // connection error on |proxy|.
+ base::RunLoop run_loop;
+ proxy.set_connection_error_handler(run_loop.QuitClosure());
+ weak_factory.InvalidateWeakPtrs();
+ run_loop.Run();
+ }
+}
+
// StrongBindingTest -----------------------------------------------------------
using StrongBindingTest = BindingTestBase;
@@ -320,43 +495,31 @@ TEST_F(StrongBindingTest, DestroyClosesMessagePipe) {
base::RunLoop run_loop;
bool encountered_error = false;
bool was_deleted = false;
- ServiceImpl impl(&was_deleted);
sample::ServicePtr ptr;
- auto request = GetProxy(&ptr);
+ auto request = MakeRequest(&ptr);
ptr.set_connection_error_handler(
SetFlagAndRunClosure(&encountered_error, run_loop.QuitClosure()));
bool called = false;
base::RunLoop run_loop2;
- {
- StrongBinding<sample::Service> binding(&impl, std::move(request));
- ptr->Frobinate(nullptr, sample::Service::BazOptions::REGULAR, nullptr,
- SetFlagAndRunClosure<int32_t>(&called,
- run_loop2.QuitClosure()));
- run_loop2.Run();
- EXPECT_TRUE(called);
- EXPECT_FALSE(encountered_error);
- }
- // Now that the StrongBinding is out of scope we should detect an error on the
- // other end of the pipe.
- run_loop.Run();
- EXPECT_TRUE(encountered_error);
- // But destroying the StrongBinding doesn't destroy the object.
- ASSERT_FALSE(was_deleted);
-}
-
-class ServiceImplWithStrongBinding : public ServiceImpl {
- public:
- ServiceImplWithStrongBinding(bool* was_deleted,
- InterfaceRequest<sample::Service> request)
- : ServiceImpl(was_deleted), binding_(this, std::move(request)) {}
- StrongBinding<sample::Service>& binding() { return binding_; }
+ auto binding = MakeStrongBinding(base::MakeUnique<ServiceImpl>(&was_deleted),
+ std::move(request));
+ ptr->Frobinate(
+ nullptr, sample::Service::BazOptions::REGULAR, nullptr,
+ SetFlagAndRunClosure<int32_t>(&called, run_loop2.QuitClosure()));
+ run_loop2.Run();
+ EXPECT_TRUE(called);
+ EXPECT_FALSE(encountered_error);
+ binding->Close();
- private:
- StrongBinding<sample::Service> binding_;
+ // Now that the StrongBinding is closed we should detect an error on the other
+ // end of the pipe.
+ run_loop.Run();
+ EXPECT_TRUE(encountered_error);
- DISALLOW_COPY_AND_ASSIGN(ServiceImplWithStrongBinding);
-};
+ // Destroying the StrongBinding also destroys the impl.
+ ASSERT_TRUE(was_deleted);
+}
// Tests the typical case, where the implementation object owns the
// StrongBinding (and should be destroyed on connection error).
@@ -366,7 +529,7 @@ TEST_F(StrongBindingTest, ConnectionErrorDestroysImpl) {
// Will delete itself.
base::RunLoop run_loop;
new ServiceImplWithBinding(&was_deleted, run_loop.QuitClosure(),
- GetProxy(&ptr));
+ MakeRequest(&ptr));
base::RunLoop().RunUntilIdle();
EXPECT_FALSE(was_deleted);
@@ -377,37 +540,71 @@ TEST_F(StrongBindingTest, ConnectionErrorDestroysImpl) {
EXPECT_TRUE(was_deleted);
}
-// Tests that even when the implementation object owns the StrongBinding, that
-// the implementation can still be deleted (which should result in the message
-// pipe being closed). Also checks that the connection error handler doesn't get
-// called.
-TEST_F(StrongBindingTest, ExplicitDeleteImpl) {
- bool ptr_error_handler_called = false;
- sample::ServicePtr ptr;
- auto request = GetProxy(&ptr);
- base::RunLoop run_loop;
- ptr.set_connection_error_handler(
- SetFlagAndRunClosure(&ptr_error_handler_called, run_loop.QuitClosure()));
+TEST_F(StrongBindingTest, FlushForTesting) {
+ bool called = false;
bool was_deleted = false;
- ServiceImplWithStrongBinding* impl =
- new ServiceImplWithStrongBinding(&was_deleted, std::move(request));
- bool binding_error_handler_called = false;
- impl->binding().set_connection_error_handler(
- SetFlagAndRunClosure(&binding_error_handler_called));
+ sample::ServicePtr ptr;
+ auto request = MakeRequest(&ptr);
+ auto binding = MakeStrongBinding(base::MakeUnique<ServiceImpl>(&was_deleted),
+ std::move(request));
+ binding->set_connection_error_handler(base::Bind(&Fail));
- base::RunLoop().RunUntilIdle();
- EXPECT_FALSE(ptr_error_handler_called);
+ ptr->Frobinate(nullptr, sample::Service::BazOptions::REGULAR, nullptr,
+ SetFlagAndRunClosure<int32_t>(&called));
+ EXPECT_FALSE(called);
+ // Because the flush is sent from the binding, it only guarantees that the
+ // request has been received, not the response. The second flush waits for the
+ // response to be received.
+ ASSERT_TRUE(binding);
+ binding->FlushForTesting();
+ ASSERT_TRUE(binding);
+ binding->FlushForTesting();
+ EXPECT_TRUE(called);
EXPECT_FALSE(was_deleted);
-
- delete impl;
- EXPECT_FALSE(ptr_error_handler_called);
+ ptr.reset();
+ ASSERT_TRUE(binding);
+ binding->set_connection_error_handler(base::Closure());
+ binding->FlushForTesting();
EXPECT_TRUE(was_deleted);
- was_deleted = false; // It shouldn't be double-deleted!
- run_loop.Run();
- EXPECT_TRUE(ptr_error_handler_called);
+}
+
+TEST_F(StrongBindingTest, FlushForTestingWithClosedPeer) {
+ bool called = false;
+ bool was_deleted = false;
+ sample::ServicePtr ptr;
+ auto request = MakeRequest(&ptr);
+ auto binding = MakeStrongBinding(base::MakeUnique<ServiceImpl>(&was_deleted),
+ std::move(request));
+ binding->set_connection_error_handler(SetFlagAndRunClosure(&called));
+ ptr.reset();
+
+ EXPECT_FALSE(called);
EXPECT_FALSE(was_deleted);
+ ASSERT_TRUE(binding);
+ binding->FlushForTesting();
+ EXPECT_TRUE(called);
+ EXPECT_TRUE(was_deleted);
+ ASSERT_FALSE(binding);
+}
- EXPECT_FALSE(binding_error_handler_called);
+TEST_F(StrongBindingTest, ConnectionErrorWithReason) {
+ sample::ServicePtr ptr;
+ auto request = MakeRequest(&ptr);
+ auto binding =
+ MakeStrongBinding(base::MakeUnique<ServiceImpl>(), std::move(request));
+ base::RunLoop run_loop;
+ binding->set_connection_error_with_reason_handler(base::Bind(
+ [](const base::Closure& quit_closure, uint32_t custom_reason,
+ const std::string& description) {
+ EXPECT_EQ(5678u, custom_reason);
+ EXPECT_EQ("hello", description);
+ quit_closure.Run();
+ },
+ run_loop.QuitClosure()));
+
+ ptr.ResetWithReason(5678u, "hello");
+
+ run_loop.Run();
}
} // namespace
diff --git a/mojo/public/cpp/bindings/tests/bindings_perftest.cc b/mojo/public/cpp/bindings/tests/bindings_perftest.cc
index db0dd05..6a50de4 100644
--- a/mojo/public/cpp/bindings/tests/bindings_perftest.cc
+++ b/mojo/public/cpp/bindings/tests/bindings_perftest.cc
@@ -8,7 +8,13 @@
#include "base/bind.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
+#include "base/threading/thread_task_runner_handle.h"
+#include "base/time/time.h"
#include "mojo/public/cpp/bindings/binding.h"
+#include "mojo/public/cpp/bindings/interface_endpoint_client.h"
+#include "mojo/public/cpp/bindings/lib/message_builder.h"
+#include "mojo/public/cpp/bindings/lib/multiplex_router.h"
+#include "mojo/public/cpp/bindings/message.h"
#include "mojo/public/cpp/test_support/test_support.h"
#include "mojo/public/cpp/test_support/test_utils.h"
#include "mojo/public/interfaces/bindings/tests/ping_service.mojom.h"
@@ -81,9 +87,7 @@ void PingPongTest::OnPingDone() {
}
struct BoundPingService {
- BoundPingService() : binding(&impl) {
- binding.Bind(GetProxy(&service));
- }
+ BoundPingService() : binding(&impl) { binding.Bind(MakeRequest(&service)); }
PingServiceImpl impl;
test::PingServicePtr service;
@@ -101,7 +105,7 @@ class MojoBindingsPerftest : public testing::Test {
TEST_F(MojoBindingsPerftest, InProcessPingPong) {
test::PingServicePtr service;
PingServiceImpl impl;
- Binding<test::PingService> binding(&impl, GetProxy(&service));
+ Binding<test::PingService> binding(&impl, MakeRequest(&service));
PingPongTest test(std::move(service));
{
@@ -133,5 +137,148 @@ TEST_F(MojoBindingsPerftest, InProcessPingPong) {
}
}
+class PingPongPaddle : public MessageReceiverWithResponderStatus {
+ public:
+ PingPongPaddle(MessageReceiver* sender) : sender_(sender) {}
+
+ void set_sender(MessageReceiver* sender) { sender_ = sender; }
+
+ bool Accept(Message* message) override {
+ uint32_t count = message->header()->name;
+ if (!quit_closure_.is_null()) {
+ count++;
+ if (count >= expected_count_) {
+ end_time_ = base::TimeTicks::Now();
+ quit_closure_.Run();
+ return true;
+ }
+ }
+
+ internal::MessageBuilder builder(count, 0, 8, 0);
+ bool result = sender_->Accept(builder.message());
+ DCHECK(result);
+ return true;
+ }
+
+ bool AcceptWithResponder(Message* message,
+ MessageReceiverWithStatus* responder) override {
+ NOTREACHED();
+ return true;
+ }
+
+ base::TimeDelta Serve(uint32_t expected_count) {
+ base::RunLoop run_loop;
+
+ expected_count_ = expected_count;
+ quit_closure_ = run_loop.QuitClosure();
+
+ start_time_ = base::TimeTicks::Now();
+ internal::MessageBuilder builder(0, 0, 8, 0);
+ bool result = sender_->Accept(builder.message());
+ DCHECK(result);
+
+ run_loop.Run();
+
+ return end_time_ - start_time_;
+ }
+
+ private:
+ base::TimeTicks start_time_;
+ base::TimeTicks end_time_;
+ uint32_t expected_count_ = 0;
+ MessageReceiver* sender_;
+ base::Closure quit_closure_;
+};
+
+TEST_F(MojoBindingsPerftest, MultiplexRouterPingPong) {
+ MessagePipe pipe;
+ scoped_refptr<internal::MultiplexRouter> router0(
+ new internal::MultiplexRouter(std::move(pipe.handle0),
+ internal::MultiplexRouter::SINGLE_INTERFACE,
+ true, base::ThreadTaskRunnerHandle::Get()));
+ scoped_refptr<internal::MultiplexRouter> router1(
+ new internal::MultiplexRouter(
+ std::move(pipe.handle1), internal::MultiplexRouter::SINGLE_INTERFACE,
+ false, base::ThreadTaskRunnerHandle::Get()));
+
+ PingPongPaddle paddle0(nullptr);
+ PingPongPaddle paddle1(nullptr);
+
+ InterfaceEndpointClient client0(
+ router0->CreateLocalEndpointHandle(kMasterInterfaceId), &paddle0, nullptr,
+ false, base::ThreadTaskRunnerHandle::Get(), 0u);
+ InterfaceEndpointClient client1(
+ router1->CreateLocalEndpointHandle(kMasterInterfaceId), &paddle1, nullptr,
+ false, base::ThreadTaskRunnerHandle::Get(), 0u);
+
+ paddle0.set_sender(&client0);
+ paddle1.set_sender(&client1);
+
+ static const uint32_t kWarmUpIterations = 1000;
+ static const uint32_t kTestIterations = 1000000;
+
+ paddle0.Serve(kWarmUpIterations);
+
+ base::TimeDelta duration = paddle0.Serve(kTestIterations);
+
+ test::LogPerfResult("MultiplexRouterPingPong", nullptr,
+ kTestIterations / duration.InSecondsF(), "pings/second");
+}
+
+class CounterReceiver : public MessageReceiverWithResponderStatus {
+ public:
+ bool Accept(Message* message) override {
+ counter_++;
+ return true;
+ }
+
+ bool AcceptWithResponder(Message* message,
+ MessageReceiverWithStatus* responder) override {
+ NOTREACHED();
+ return true;
+ }
+
+ uint32_t counter() const { return counter_; }
+
+ void Reset() { counter_ = 0; }
+
+ private:
+ uint32_t counter_ = 0;
+};
+
+TEST_F(MojoBindingsPerftest, MultiplexRouterDispatchCost) {
+ MessagePipe pipe;
+ scoped_refptr<internal::MultiplexRouter> router(new internal::MultiplexRouter(
+ std::move(pipe.handle0), internal::MultiplexRouter::SINGLE_INTERFACE,
+ true, base::ThreadTaskRunnerHandle::Get()));
+ CounterReceiver receiver;
+ InterfaceEndpointClient client(
+ router->CreateLocalEndpointHandle(kMasterInterfaceId), &receiver, nullptr,
+ false, base::ThreadTaskRunnerHandle::Get(), 0u);
+
+ static const uint32_t kIterations[] = {1000, 3000000};
+
+ for (size_t i = 0; i < 2; ++i) {
+ receiver.Reset();
+ base::TimeTicks start_time = base::TimeTicks::Now();
+ for (size_t j = 0; j < kIterations[i]; ++j) {
+ internal::MessageBuilder builder(0, 0, 8, 0);
+ bool result =
+ router->SimulateReceivingMessageForTesting(builder.message());
+ DCHECK(result);
+ }
+
+ base::TimeTicks end_time = base::TimeTicks::Now();
+ base::TimeDelta duration = end_time - start_time;
+ CHECK_EQ(kIterations[i], receiver.counter());
+
+ if (i == 1) {
+ test::LogPerfResult("MultiplexRouterDispatchCost", nullptr,
+ kIterations[i] / duration.InSecondsF(),
+ "times/second");
+ }
+ }
+}
+
} // namespace
} // namespace mojo
diff --git a/mojo/public/cpp/bindings/tests/connector_unittest.cc b/mojo/public/cpp/bindings/tests/connector_unittest.cc
index 89cc51d..74ecb7a 100644
--- a/mojo/public/cpp/bindings/tests/connector_unittest.cc
+++ b/mojo/public/cpp/bindings/tests/connector_unittest.cc
@@ -14,6 +14,7 @@
#include "base/callback_helpers.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
+#include "base/threading/thread.h"
#include "base/threading/thread_task_runner_handle.h"
#include "mojo/public/cpp/bindings/lib/message_builder.h"
#include "mojo/public/cpp/bindings/tests/message_queue.h"
@@ -98,10 +99,10 @@ class ConnectorTest : public testing::Test {
void AllocMessage(const char* text, Message* message) {
size_t payload_size = strlen(text) + 1; // Plus null terminator.
- internal::MessageBuilder builder(1, payload_size);
+ internal::MessageBuilder builder(1, 0, payload_size, 0);
memcpy(builder.buffer()->Allocate(payload_size), text, payload_size);
- builder.message()->MoveTo(message);
+ *message = std::move(*builder.message());
}
protected:
@@ -572,6 +573,27 @@ TEST_F(ConnectorTest, ProcessWhenNested) {
ASSERT_EQ(2u, accumulator.size());
}
+TEST_F(ConnectorTest, DestroyOnDifferentThreadAfterClose) {
+ std::unique_ptr<Connector> connector(
+ new Connector(std::move(handle0_), Connector::SINGLE_THREADED_SEND,
+ base::ThreadTaskRunnerHandle::Get()));
+
+ connector->CloseMessagePipe();
+
+ base::Thread another_thread("ThreadForDestroyingConnector");
+ another_thread.Start();
+
+ base::RunLoop run_loop;
+ another_thread.task_runner()->PostTaskAndReply(
+ FROM_HERE,
+ base::Bind(
+ [](std::unique_ptr<Connector> connector) { connector.reset(); },
+ base::Passed(std::move(connector))),
+ run_loop.QuitClosure());
+
+ run_loop.Run();
+}
+
} // namespace
} // namespace test
} // namespace mojo
diff --git a/mojo/public/cpp/bindings/tests/constant_unittest.cc b/mojo/public/cpp/bindings/tests/constant_unittest.cc
index f6394f3..caa6464 100644
--- a/mojo/public/cpp/bindings/tests/constant_unittest.cc
+++ b/mojo/public/cpp/bindings/tests/constant_unittest.cc
@@ -2,6 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <cmath>
+
+#include "base/strings/string_piece.h"
#include "mojo/public/interfaces/bindings/tests/test_constants.mojom.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -19,23 +22,38 @@ TEST(ConstantTest, GlobalConstants) {
static_assert(kUint32Value == 4294967295U, "");
static_assert(kInt64Value == -9223372036854775807, "");
static_assert(kUint64Value == 9999999999999999999ULL, "");
-
- EXPECT_DOUBLE_EQ(kDoubleValue, 3.14159);
- EXPECT_FLOAT_EQ(kFloatValue, 2.71828f);
+ static_assert(kDoubleValue == 3.14159, "");
+ static_assert(kFloatValue == 2.71828f, "");
+
+ EXPECT_EQ(base::StringPiece(kStringValue), "test string contents");
+ EXPECT_TRUE(std::isnan(kDoubleNaN));
+ EXPECT_TRUE(std::isinf(kDoubleInfinity));
+ EXPECT_TRUE(std::isinf(kDoubleNegativeInfinity));
+ EXPECT_NE(kDoubleInfinity, kDoubleNegativeInfinity);
+ EXPECT_TRUE(std::isnan(kFloatNaN));
+ EXPECT_TRUE(std::isinf(kFloatInfinity));
+ EXPECT_TRUE(std::isinf(kFloatNegativeInfinity));
+ EXPECT_NE(kFloatInfinity, kFloatNegativeInfinity);
}
TEST(ConstantTest, StructConstants) {
// Compile-time constants.
static_assert(StructWithConstants::kInt8Value == 5U, "");
+ static_assert(StructWithConstants::kFloatValue == 765.432f, "");
- EXPECT_FLOAT_EQ(StructWithConstants::kFloatValue, 765.432f);
+ EXPECT_EQ(base::StringPiece(StructWithConstants::kStringValue),
+ "struct test string contents");
}
TEST(ConstantTest, InterfaceConstants) {
// Compile-time constants.
static_assert(InterfaceWithConstants::kUint32Value == 20100722, "");
+ static_assert(InterfaceWithConstants::kDoubleValue == 12.34567, "");
- EXPECT_DOUBLE_EQ(InterfaceWithConstants::kDoubleValue, 12.34567);
+ EXPECT_EQ(base::StringPiece(InterfaceWithConstants::kStringValue),
+ "interface test string contents");
+ EXPECT_EQ(base::StringPiece(InterfaceWithConstants::Name_),
+ "mojo::test::InterfaceWithConstants");
}
} // namespace test
diff --git a/mojo/public/cpp/bindings/tests/data_view_unittest.cc b/mojo/public/cpp/bindings/tests/data_view_unittest.cc
new file mode 100644
index 0000000..0ebfda5
--- /dev/null
+++ b/mojo/public/cpp/bindings/tests/data_view_unittest.cc
@@ -0,0 +1,303 @@
+// Copyright 2016 The Chromium 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 <memory>
+#include <string>
+#include <unordered_map>
+#include <vector>
+
+#include "base/message_loop/message_loop.h"
+#include "mojo/public/cpp/bindings/binding.h"
+#include "mojo/public/cpp/bindings/lib/fixed_buffer.h"
+#include "mojo/public/cpp/bindings/lib/serialization.h"
+#include "mojo/public/interfaces/bindings/tests/test_data_view.mojom.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace mojo {
+namespace test {
+namespace data_view {
+namespace {
+
+class DataViewTest : public testing::Test {
+ private:
+ base::MessageLoop message_loop_;
+};
+
+struct DataViewHolder {
+ std::unique_ptr<TestStructDataView> data_view;
+ std::unique_ptr<mojo::internal::FixedBufferForTesting> buf;
+ mojo::internal::SerializationContext context;
+};
+
+std::unique_ptr<DataViewHolder> SerializeTestStruct(TestStructPtr input) {
+ std::unique_ptr<DataViewHolder> result(new DataViewHolder);
+
+ size_t size = mojo::internal::PrepareToSerialize<TestStructDataView>(
+ input, &result->context);
+
+ result->buf.reset(new mojo::internal::FixedBufferForTesting(size));
+ internal::TestStruct_Data* data = nullptr;
+ mojo::internal::Serialize<TestStructDataView>(input, result->buf.get(), &data,
+ &result->context);
+
+ result->data_view.reset(new TestStructDataView(data, &result->context));
+ return result;
+}
+
+class TestInterfaceImpl : public TestInterface {
+ public:
+ explicit TestInterfaceImpl(TestInterfaceRequest request)
+ : binding_(this, std::move(request)) {}
+ ~TestInterfaceImpl() override {}
+
+ // TestInterface implementation:
+ void Echo(int32_t value, const EchoCallback& callback) override {
+ callback.Run(value);
+ }
+
+ private:
+ Binding<TestInterface> binding_;
+};
+
+} // namespace
+
+TEST_F(DataViewTest, String) {
+ TestStructPtr obj(TestStruct::New());
+ obj->f_string = "hello";
+
+ auto data_view_holder = SerializeTestStruct(std::move(obj));
+ auto& data_view = *data_view_holder->data_view;
+
+ StringDataView string_data_view;
+ data_view.GetFStringDataView(&string_data_view);
+
+ ASSERT_FALSE(string_data_view.is_null());
+ EXPECT_EQ(std::string("hello"),
+ std::string(string_data_view.storage(), string_data_view.size()));
+}
+
+TEST_F(DataViewTest, NestedStruct) {
+ TestStructPtr obj(TestStruct::New());
+ obj->f_struct = NestedStruct::New();
+ obj->f_struct->f_int32 = 42;
+
+ auto data_view_holder = SerializeTestStruct(std::move(obj));
+ auto& data_view = *data_view_holder->data_view;
+
+ NestedStructDataView struct_data_view;
+ data_view.GetFStructDataView(&struct_data_view);
+
+ ASSERT_FALSE(struct_data_view.is_null());
+ EXPECT_EQ(42, struct_data_view.f_int32());
+}
+
+TEST_F(DataViewTest, NativeStruct) {
+ TestStructPtr obj(TestStruct::New());
+ obj->f_native_struct = NativeStruct::New();
+ obj->f_native_struct->data = std::vector<uint8_t>({3, 2, 1});
+
+ auto data_view_holder = SerializeTestStruct(std::move(obj));
+ auto& data_view = *data_view_holder->data_view;
+
+ NativeStructDataView struct_data_view;
+ data_view.GetFNativeStructDataView(&struct_data_view);
+
+ ASSERT_FALSE(struct_data_view.is_null());
+ ASSERT_EQ(3u, struct_data_view.size());
+ EXPECT_EQ(3, struct_data_view[0]);
+ EXPECT_EQ(2, struct_data_view[1]);
+ EXPECT_EQ(1, struct_data_view[2]);
+ EXPECT_EQ(3, *struct_data_view.data());
+}
+
+TEST_F(DataViewTest, BoolArray) {
+ TestStructPtr obj(TestStruct::New());
+ obj->f_bool_array = {true, false};
+
+ auto data_view_holder = SerializeTestStruct(std::move(obj));
+ auto& data_view = *data_view_holder->data_view;
+
+ ArrayDataView<bool> array_data_view;
+ data_view.GetFBoolArrayDataView(&array_data_view);
+
+ ASSERT_FALSE(array_data_view.is_null());
+ ASSERT_EQ(2u, array_data_view.size());
+ EXPECT_TRUE(array_data_view[0]);
+ EXPECT_FALSE(array_data_view[1]);
+}
+
+TEST_F(DataViewTest, IntegerArray) {
+ TestStructPtr obj(TestStruct::New());
+ obj->f_int32_array = {1024, 128};
+
+ auto data_view_holder = SerializeTestStruct(std::move(obj));
+ auto& data_view = *data_view_holder->data_view;
+
+ ArrayDataView<int32_t> array_data_view;
+ data_view.GetFInt32ArrayDataView(&array_data_view);
+
+ ASSERT_FALSE(array_data_view.is_null());
+ ASSERT_EQ(2u, array_data_view.size());
+ EXPECT_EQ(1024, array_data_view[0]);
+ EXPECT_EQ(128, array_data_view[1]);
+ EXPECT_EQ(1024, *array_data_view.data());
+}
+
+TEST_F(DataViewTest, EnumArray) {
+ TestStructPtr obj(TestStruct::New());
+ obj->f_enum_array = {TestEnum::VALUE_1, TestEnum::VALUE_0};
+
+ auto data_view_holder = SerializeTestStruct(std::move(obj));
+ auto& data_view = *data_view_holder->data_view;
+
+ ArrayDataView<TestEnum> array_data_view;
+ data_view.GetFEnumArrayDataView(&array_data_view);
+
+ ASSERT_FALSE(array_data_view.is_null());
+ ASSERT_EQ(2u, array_data_view.size());
+ EXPECT_EQ(TestEnum::VALUE_1, array_data_view[0]);
+ EXPECT_EQ(TestEnum::VALUE_0, array_data_view[1]);
+ EXPECT_EQ(TestEnum::VALUE_0, *(array_data_view.data() + 1));
+
+ TestEnum output;
+ ASSERT_TRUE(array_data_view.Read(0, &output));
+ EXPECT_EQ(TestEnum::VALUE_1, output);
+}
+
+TEST_F(DataViewTest, InterfaceArray) {
+ TestInterfacePtr ptr;
+ TestInterfaceImpl impl(MakeRequest(&ptr));
+
+ TestStructPtr obj(TestStruct::New());
+ obj->f_interface_array.push_back(std::move(ptr));
+
+ auto data_view_holder = SerializeTestStruct(std::move(obj));
+ auto& data_view = *data_view_holder->data_view;
+
+ ArrayDataView<TestInterfacePtrDataView> array_data_view;
+ data_view.GetFInterfaceArrayDataView(&array_data_view);
+
+ ASSERT_FALSE(array_data_view.is_null());
+ ASSERT_EQ(1u, array_data_view.size());
+
+ TestInterfacePtr ptr2 = array_data_view.Take<TestInterfacePtr>(0);
+ ASSERT_TRUE(ptr2);
+ int32_t result = 0;
+ ASSERT_TRUE(ptr2->Echo(42, &result));
+ EXPECT_EQ(42, result);
+}
+
+TEST_F(DataViewTest, NestedArray) {
+ TestStructPtr obj(TestStruct::New());
+ obj->f_nested_array = {{3, 4}, {2}};
+
+ auto data_view_holder = SerializeTestStruct(std::move(obj));
+ auto& data_view = *data_view_holder->data_view;
+
+ ArrayDataView<ArrayDataView<int32_t>> array_data_view;
+ data_view.GetFNestedArrayDataView(&array_data_view);
+
+ ASSERT_FALSE(array_data_view.is_null());
+ ASSERT_EQ(2u, array_data_view.size());
+
+ ArrayDataView<int32_t> nested_array_data_view;
+ array_data_view.GetDataView(0, &nested_array_data_view);
+ ASSERT_FALSE(nested_array_data_view.is_null());
+ ASSERT_EQ(2u, nested_array_data_view.size());
+ EXPECT_EQ(4, nested_array_data_view[1]);
+
+ std::vector<int32_t> vec;
+ ASSERT_TRUE(array_data_view.Read(1, &vec));
+ ASSERT_EQ(1u, vec.size());
+ EXPECT_EQ(2, vec[0]);
+}
+
+TEST_F(DataViewTest, StructArray) {
+ NestedStructPtr nested_struct(NestedStruct::New());
+ nested_struct->f_int32 = 42;
+
+ TestStructPtr obj(TestStruct::New());
+ obj->f_struct_array.push_back(std::move(nested_struct));
+
+ auto data_view_holder = SerializeTestStruct(std::move(obj));
+ auto& data_view = *data_view_holder->data_view;
+
+ ArrayDataView<NestedStructDataView> array_data_view;
+ data_view.GetFStructArrayDataView(&array_data_view);
+
+ ASSERT_FALSE(array_data_view.is_null());
+ ASSERT_EQ(1u, array_data_view.size());
+
+ NestedStructDataView struct_data_view;
+ array_data_view.GetDataView(0, &struct_data_view);
+ ASSERT_FALSE(struct_data_view.is_null());
+ EXPECT_EQ(42, struct_data_view.f_int32());
+
+ NestedStructPtr nested_struct2;
+ ASSERT_TRUE(array_data_view.Read(0, &nested_struct2));
+ ASSERT_TRUE(nested_struct2);
+ EXPECT_EQ(42, nested_struct2->f_int32);
+}
+
+TEST_F(DataViewTest, Map) {
+ TestStructPtr obj(TestStruct::New());
+ obj->f_map["1"] = 1;
+ obj->f_map["2"] = 2;
+
+ auto data_view_holder = SerializeTestStruct(std::move(obj));
+ auto& data_view = *data_view_holder->data_view;
+
+ MapDataView<StringDataView, int32_t> map_data_view;
+ data_view.GetFMapDataView(&map_data_view);
+
+ ASSERT_FALSE(map_data_view.is_null());
+ ASSERT_EQ(2u, map_data_view.size());
+
+ ASSERT_FALSE(map_data_view.keys().is_null());
+ ASSERT_EQ(2u, map_data_view.keys().size());
+
+ ASSERT_FALSE(map_data_view.values().is_null());
+ ASSERT_EQ(2u, map_data_view.values().size());
+
+ std::vector<std::string> keys;
+ ASSERT_TRUE(map_data_view.ReadKeys(&keys));
+ std::vector<int32_t> values;
+ ASSERT_TRUE(map_data_view.ReadValues(&values));
+
+ std::unordered_map<std::string, int32_t> map;
+ for (size_t i = 0; i < 2; ++i)
+ map[keys[i]] = values[i];
+
+ EXPECT_EQ(1, map["1"]);
+ EXPECT_EQ(2, map["2"]);
+}
+
+TEST_F(DataViewTest, UnionArray) {
+ TestUnionPtr union_ptr(TestUnion::New());
+ union_ptr->set_f_int32(1024);
+
+ TestStructPtr obj(TestStruct::New());
+ obj->f_union_array.push_back(std::move(union_ptr));
+
+ auto data_view_holder = SerializeTestStruct(std::move(obj));
+ auto& data_view = *data_view_holder->data_view;
+
+ ArrayDataView<TestUnionDataView> array_data_view;
+ data_view.GetFUnionArrayDataView(&array_data_view);
+ ASSERT_FALSE(array_data_view.is_null());
+ ASSERT_EQ(1u, array_data_view.size());
+
+ TestUnionDataView union_data_view;
+ array_data_view.GetDataView(0, &union_data_view);
+ ASSERT_FALSE(union_data_view.is_null());
+
+ TestUnionPtr union_ptr2;
+ ASSERT_TRUE(array_data_view.Read(0, &union_ptr2));
+ ASSERT_TRUE(union_ptr2->is_f_int32());
+ EXPECT_EQ(1024, union_ptr2->get_f_int32());
+}
+
+} // namespace data_view
+} // namespace test
+} // namespace mojo
diff --git a/mojo/public/cpp/bindings/tests/e2e_perftest.cc b/mojo/public/cpp/bindings/tests/e2e_perftest.cc
index 66ac6dc..bc69e0f 100644
--- a/mojo/public/cpp/bindings/tests/e2e_perftest.cc
+++ b/mojo/public/cpp/bindings/tests/e2e_perftest.cc
@@ -7,13 +7,14 @@
#include "base/bind.h"
#include "base/callback.h"
+#include "base/memory/ptr_util.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/strings/stringprintf.h"
#include "base/test/perf_time_logger.h"
#include "base/threading/thread_task_runner_handle.h"
+#include "mojo/edk/embedder/embedder.h"
#include "mojo/edk/test/mojo_test_base.h"
-#include "mojo/edk/test/scoped_ipc_support.h"
#include "mojo/public/cpp/bindings/strong_binding.h"
#include "mojo/public/interfaces/bindings/tests/ping_service.mojom.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -23,8 +24,7 @@ namespace {
class EchoServiceImpl : public test::EchoService {
public:
- EchoServiceImpl(InterfaceRequest<EchoService> request,
- const base::Closure& quit_closure);
+ explicit EchoServiceImpl(const base::Closure& quit_closure);
~EchoServiceImpl() override;
// |EchoService| methods:
@@ -32,13 +32,11 @@ class EchoServiceImpl : public test::EchoService {
const EchoCallback& callback) override;
private:
- const StrongBinding<EchoService> binding_;
const base::Closure quit_closure_;
};
-EchoServiceImpl::EchoServiceImpl(InterfaceRequest<EchoService> request,
- const base::Closure& quit_closure)
- : binding_(this, std::move(request)), quit_closure_(quit_closure) {}
+EchoServiceImpl::EchoServiceImpl(const base::Closure& quit_closure)
+ : quit_closure_(quit_closure) {}
EchoServiceImpl::~EchoServiceImpl() {
quit_closure_.Run();
@@ -163,7 +161,7 @@ class MojoE2EPerftest : public edk::test::MojoTestBase {
void CreateAndRunService(InterfaceRequest<test::EchoService> request,
const base::Closure& cb) {
- new EchoServiceImpl(std::move(request), cb);
+ MakeStrongBinding(base::MakeUnique<EchoServiceImpl>(cb), std::move(request));
}
DEFINE_TEST_CLIENT_TEST_WITH_PIPE(PingService, MojoE2EPerftest, mp) {
@@ -173,7 +171,7 @@ DEFINE_TEST_CLIENT_TEST_WITH_PIPE(PingService, MojoE2EPerftest, mp) {
InterfaceRequest<test::EchoService> request;
request.Bind(ScopedMessagePipeHandle(MessagePipeHandle(service_mp)));
base::RunLoop run_loop;
- edk::test::GetIoTaskRunner()->PostTask(
+ edk::GetIOTaskRunner()->PostTask(
FROM_HERE,
base::Bind(&CreateAndRunService, base::Passed(&request),
base::Bind(base::IgnoreResult(&base::TaskRunner::PostTask),
@@ -197,7 +195,7 @@ TEST_F(MojoE2EPerftest, MultiProcessEchoIoThread) {
MojoHandle client_mp, service_mp;
CreateMessagePipe(&client_mp, &service_mp);
WriteMessageWithHandles(mp, "hello", &service_mp, 1);
- RunTestOnTaskRunner(edk::test::GetIoTaskRunner(), client_mp,
+ RunTestOnTaskRunner(edk::GetIOTaskRunner().get(), client_mp,
"MultiProcessEchoIoThread");
END_CHILD()
}
diff --git a/mojo/public/cpp/bindings/tests/equals_unittest.cc b/mojo/public/cpp/bindings/tests/equals_unittest.cc
index 376c2bd..6483baf 100644
--- a/mojo/public/cpp/bindings/tests/equals_unittest.cc
+++ b/mojo/public/cpp/bindings/tests/equals_unittest.cc
@@ -14,12 +14,7 @@ namespace test {
namespace {
RectPtr CreateRect() {
- RectPtr r = Rect::New();
- r->x = 1;
- r->y = 2;
- r->width = 3;
- r->height = 4;
- return r;
+ return Rect::New(1, 2, 3, 4);
}
using EqualsTest = testing::Test;
@@ -48,9 +43,7 @@ TEST_F(EqualsTest, Struct) {
}
TEST_F(EqualsTest, StructNested) {
- RectPairPtr p1(RectPair::New());
- p1->first = CreateRect();
- p1->second = CreateRect();
+ RectPairPtr p1(RectPair::New(CreateRect(), CreateRect()));
RectPairPtr p2(p1.Clone());
EXPECT_TRUE(p1.Equals(p2));
p2->second->width = 0;
@@ -60,10 +53,9 @@ TEST_F(EqualsTest, StructNested) {
}
TEST_F(EqualsTest, Array) {
- NamedRegionPtr n1(NamedRegion::New());
- n1->name.emplace("n1");
- n1->rects.emplace();
- n1->rects->push_back(CreateRect());
+ std::vector<RectPtr> rects;
+ rects.push_back(CreateRect());
+ NamedRegionPtr n1(NamedRegion::New(std::string("n1"), std::move(rects)));
NamedRegionPtr n2(n1.Clone());
EXPECT_TRUE(n1.Equals(n2));
@@ -84,37 +76,6 @@ TEST_F(EqualsTest, Array) {
EXPECT_TRUE(n1.Equals(n2));
}
-TEST_F(EqualsTest, Map) {
- auto n1(NamedRegion::New());
- n1->name.emplace("foo");
- n1->rects.emplace();
- n1->rects->push_back(CreateRect());
-
- Map<std::string, NamedRegionPtr> m1;
- m1.insert("foo", std::move(n1));
-
- decltype(m1) m2;
- EXPECT_FALSE(m1.Equals(m2));
-
- m2.insert("bar", m1.at("foo").Clone());
- EXPECT_FALSE(m1.Equals(m2));
-
- m2 = m1.Clone();
- m2.at("foo")->name.emplace("monkey");
- EXPECT_FALSE(m1.Equals(m2));
-
- m2 = m1.Clone();
- m2.at("foo")->rects->push_back(Rect::New());
- EXPECT_FALSE(m1.Equals(m2));
-
- m2.at("foo")->rects->resize(1);
- (*m2.at("foo")->rects)[0]->width = 1;
- EXPECT_FALSE(m1.Equals(m2));
-
- m2 = m1.Clone();
- EXPECT_TRUE(m1.Equals(m2));
-}
-
TEST_F(EqualsTest, InterfacePtr) {
base::MessageLoop message_loop;
@@ -124,13 +85,13 @@ TEST_F(EqualsTest, InterfacePtr) {
EXPECT_TRUE(inf1.Equals(inf1));
EXPECT_TRUE(inf1.Equals(inf2));
- auto inf1_request = GetProxy(&inf1);
+ auto inf1_request = MakeRequest(&inf1);
ALLOW_UNUSED_LOCAL(inf1_request);
EXPECT_TRUE(inf1.Equals(inf1));
EXPECT_FALSE(inf1.Equals(inf2));
- auto inf2_request = GetProxy(&inf2);
+ auto inf2_request = MakeRequest(&inf2);
ALLOW_UNUSED_LOCAL(inf2_request);
EXPECT_FALSE(inf1.Equals(inf2));
@@ -146,13 +107,13 @@ TEST_F(EqualsTest, InterfaceRequest) {
EXPECT_TRUE(req1.Equals(req2));
SomeInterfacePtr inf1;
- req1 = GetProxy(&inf1);
+ req1 = MakeRequest(&inf1);
EXPECT_TRUE(req1.Equals(req1));
EXPECT_FALSE(req1.Equals(req2));
SomeInterfacePtr inf2;
- req2 = GetProxy(&inf2);
+ req2 = MakeRequest(&inf2);
EXPECT_FALSE(req1.Equals(req2));
}
diff --git a/mojo/public/cpp/bindings/tests/handle_passing_unittest.cc b/mojo/public/cpp/bindings/tests/handle_passing_unittest.cc
index 0bd9b28..6797fe4 100644
--- a/mojo/public/cpp/bindings/tests/handle_passing_unittest.cc
+++ b/mojo/public/cpp/bindings/tests/handle_passing_unittest.cc
@@ -5,6 +5,7 @@
#include <stdint.h>
#include <utility>
+#include "base/memory/ptr_util.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "mojo/public/cpp/bindings/binding.h"
@@ -56,8 +57,8 @@ int ImportedInterfaceImpl::do_something_count_ = 0;
class SampleNamedObjectImpl : public sample::NamedObject {
public:
- explicit SampleNamedObjectImpl(InterfaceRequest<sample::NamedObject> request)
- : binding_(this, std::move(request)) {}
+ SampleNamedObjectImpl() {}
+
void SetName(const std::string& name) override { name_ = name; }
void GetName(const GetNameCallback& callback) override {
@@ -66,7 +67,6 @@ class SampleNamedObjectImpl : public sample::NamedObject {
private:
std::string name_;
- StrongBinding<sample::NamedObject> binding_;
};
class SampleFactoryImpl : public sample::Factory {
@@ -95,9 +95,7 @@ class SampleFactoryImpl : public sample::Factory {
EXPECT_TRUE(WriteTextMessage(pipe1_.get(), text2));
}
- sample::ResponsePtr response(sample::Response::New());
- response->x = 2;
- response->pipe = std::move(pipe0);
+ sample::ResponsePtr response(sample::Response::New(2, std::move(pipe0)));
callback.Run(std::move(response), text1);
if (request->obj)
@@ -115,7 +113,7 @@ class SampleFactoryImpl : public sample::Factory {
ASSERT_EQ(MOJO_RESULT_OK,
MojoWait(pipe.get().value(), MOJO_HANDLE_SIGNAL_READABLE,
MOJO_DEADLINE_INDEFINITE, &state));
- ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE, state.satisfied_signals);
+ ASSERT_TRUE(state.satisfied_signals & MOJO_HANDLE_SIGNAL_READABLE);
ASSERT_EQ(MOJO_RESULT_OK,
ReadDataRaw(
pipe.get(), nullptr, &data_size, MOJO_READ_DATA_FLAG_QUERY));
@@ -133,7 +131,8 @@ class SampleFactoryImpl : public sample::Factory {
void CreateNamedObject(
InterfaceRequest<sample::NamedObject> object_request) override {
EXPECT_TRUE(object_request.is_pending());
- new SampleNamedObjectImpl(std::move(object_request));
+ MakeStrongBinding(base::MakeUnique<SampleNamedObjectImpl>(),
+ std::move(object_request));
}
// These aren't called or implemented, but exist here to test that the
@@ -200,7 +199,7 @@ void DoStuff2(bool* got_response,
TEST_F(HandlePassingTest, Basic) {
sample::FactoryPtr factory;
- SampleFactoryImpl factory_impl(GetProxy(&factory));
+ SampleFactoryImpl factory_impl(MakeRequest(&factory));
MessagePipe pipe0;
EXPECT_TRUE(WriteTextMessage(pipe0.handle1.get(), kText1));
@@ -210,13 +209,11 @@ TEST_F(HandlePassingTest, Basic) {
imported::ImportedInterfacePtr imported;
base::RunLoop run_loop;
- ImportedInterfaceImpl imported_impl(GetProxy(&imported),
+ ImportedInterfaceImpl imported_impl(MakeRequest(&imported),
run_loop.QuitClosure());
- sample::RequestPtr request(sample::Request::New());
- request->x = 1;
- request->pipe = std::move(pipe1.handle0);
- request->obj = std::move(imported);
+ sample::RequestPtr request(sample::Request::New(
+ 1, std::move(pipe1.handle0), base::nullopt, std::move(imported)));
bool got_response = false;
std::string got_text_reply;
base::RunLoop run_loop2;
@@ -237,10 +234,11 @@ TEST_F(HandlePassingTest, Basic) {
TEST_F(HandlePassingTest, PassInvalid) {
sample::FactoryPtr factory;
- SampleFactoryImpl factory_impl(GetProxy(&factory));
+ SampleFactoryImpl factory_impl(MakeRequest(&factory));
- sample::RequestPtr request(sample::Request::New());
- request->x = 1;
+ sample::RequestPtr request(
+ sample::Request::New(1, ScopedMessagePipeHandle(), base::nullopt,
+ imported::ImportedInterfacePtr()));
bool got_response = false;
std::string got_text_reply;
base::RunLoop run_loop;
@@ -258,7 +256,7 @@ TEST_F(HandlePassingTest, PassInvalid) {
// Verifies DataPipeConsumer can be passed and read from.
TEST_F(HandlePassingTest, DataPipe) {
sample::FactoryPtr factory;
- SampleFactoryImpl factory_impl(GetProxy(&factory));
+ SampleFactoryImpl factory_impl(MakeRequest(&factory));
// Writes a string to a data pipe and passes the data pipe (consumer) to the
// factory.
@@ -296,7 +294,7 @@ TEST_F(HandlePassingTest, DataPipe) {
TEST_F(HandlePassingTest, PipesAreClosed) {
sample::FactoryPtr factory;
- SampleFactoryImpl factory_impl(GetProxy(&factory));
+ SampleFactoryImpl factory_impl(MakeRequest(&factory));
MessagePipe extra_pipe;
@@ -322,12 +320,12 @@ TEST_F(HandlePassingTest, PipesAreClosed) {
TEST_F(HandlePassingTest, CreateNamedObject) {
sample::FactoryPtr factory;
- SampleFactoryImpl factory_impl(GetProxy(&factory));
+ SampleFactoryImpl factory_impl(MakeRequest(&factory));
sample::NamedObjectPtr object1;
EXPECT_FALSE(object1);
- InterfaceRequest<sample::NamedObject> object1_request = GetProxy(&object1);
+ InterfaceRequest<sample::NamedObject> object1_request(&object1);
EXPECT_TRUE(object1_request.is_pending());
factory->CreateNamedObject(std::move(object1_request));
EXPECT_FALSE(object1_request.is_pending()); // We've passed the request.
@@ -336,7 +334,7 @@ TEST_F(HandlePassingTest, CreateNamedObject) {
object1->SetName("object1");
sample::NamedObjectPtr object2;
- factory->CreateNamedObject(GetProxy(&object2));
+ factory->CreateNamedObject(MakeRequest(&object2));
object2->SetName("object2");
base::RunLoop run_loop, run_loop2;
diff --git a/mojo/public/cpp/bindings/tests/hash_unittest.cc b/mojo/public/cpp/bindings/tests/hash_unittest.cc
new file mode 100644
index 0000000..9ce1f5b
--- /dev/null
+++ b/mojo/public/cpp/bindings/tests/hash_unittest.cc
@@ -0,0 +1,35 @@
+// Copyright 2016 The Chromium 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 "mojo/public/cpp/bindings/lib/hash_util.h"
+
+#include "mojo/public/interfaces/bindings/tests/test_structs.mojom.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace mojo {
+namespace test {
+namespace {
+
+using HashTest = testing::Test;
+
+TEST_F(HashTest, NestedStruct) {
+ // Just check that this template instantiation compiles.
+ ASSERT_EQ(
+ ::mojo::internal::Hash(::mojo::internal::kHashSeed,
+ SimpleNestedStruct::New(ContainsOther::New(1))),
+ ::mojo::internal::Hash(::mojo::internal::kHashSeed,
+ SimpleNestedStruct::New(ContainsOther::New(1))));
+}
+
+TEST_F(HashTest, UnmappedNativeStruct) {
+ // Just check that this template instantiation compiles.
+ ASSERT_EQ(::mojo::internal::Hash(::mojo::internal::kHashSeed,
+ UnmappedNativeStruct::New()),
+ ::mojo::internal::Hash(::mojo::internal::kHashSeed,
+ UnmappedNativeStruct::New()));
+}
+
+} // namespace
+} // namespace test
+} // namespace mojo
diff --git a/mojo/public/cpp/bindings/tests/interface_ptr_unittest.cc b/mojo/public/cpp/bindings/tests/interface_ptr_unittest.cc
index aff6251..431a844 100644
--- a/mojo/public/cpp/bindings/tests/interface_ptr_unittest.cc
+++ b/mojo/public/cpp/bindings/tests/interface_ptr_unittest.cc
@@ -7,10 +7,14 @@
#include "base/bind.h"
#include "base/callback.h"
+#include "base/memory/ptr_util.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
+#include "base/threading/sequenced_task_runner_handle.h"
+#include "base/threading/thread.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "mojo/public/cpp/bindings/strong_binding.h"
+#include "mojo/public/cpp/bindings/thread_safe_interface_ptr.h"
#include "mojo/public/interfaces/bindings/tests/math_calculator.mojom.h"
#include "mojo/public/interfaces/bindings/tests/sample_interfaces.mojom.h"
#include "mojo/public/interfaces/bindings/tests/sample_service.mojom.h"
@@ -29,10 +33,6 @@ class MathCalculatorImpl : public math::Calculator {
: total_(0.0), binding_(this, std::move(request)) {}
~MathCalculatorImpl() override {}
- void CloseMessagePipe() { binding_.Close(); }
-
- void WaitForIncomingMethodCall() { binding_.WaitForIncomingMethodCall(); }
-
void Clear(const CalcCallback& callback) override {
total_ = 0.0;
callback.Run(total_);
@@ -48,6 +48,8 @@ class MathCalculatorImpl : public math::Calculator {
callback.Run(total_);
}
+ Binding<math::Calculator>* binding() { return &binding_; }
+
private:
double total_;
Binding<math::Calculator> binding_;
@@ -78,6 +80,8 @@ class MathCalculatorUI {
double GetOutput() const { return output_; }
+ math::CalculatorPtr& GetInterfacePtr() { return calculator_; }
+
private:
void Output(const base::Closure& closure, double output) {
output_ = output;
@@ -218,13 +222,13 @@ void ExpectValueAndRunClosure(uint32_t expected_value,
TEST_F(InterfacePtrTest, IsBound) {
math::CalculatorPtr calc;
EXPECT_FALSE(calc.is_bound());
- MathCalculatorImpl calc_impl(GetProxy(&calc));
+ MathCalculatorImpl calc_impl(MakeRequest(&calc));
EXPECT_TRUE(calc.is_bound());
}
TEST_F(InterfacePtrTest, EndToEnd) {
math::CalculatorPtr calc;
- MathCalculatorImpl calc_impl(GetProxy(&calc));
+ MathCalculatorImpl calc_impl(MakeRequest(&calc));
// Suppose this is instantiated in a process that has pipe1_.
MathCalculatorUI calculator_ui(std::move(calc));
@@ -240,7 +244,7 @@ TEST_F(InterfacePtrTest, EndToEnd) {
TEST_F(InterfacePtrTest, EndToEnd_Synchronous) {
math::CalculatorPtr calc;
- MathCalculatorImpl calc_impl(GetProxy(&calc));
+ MathCalculatorImpl calc_impl(MakeRequest(&calc));
// Suppose this is instantiated in a process that has pipe1_.
MathCalculatorUI calculator_ui(std::move(calc));
@@ -250,14 +254,14 @@ TEST_F(InterfacePtrTest, EndToEnd_Synchronous) {
base::RunLoop run_loop;
calculator_ui.Add(2.0, run_loop.QuitClosure());
EXPECT_EQ(0.0, calculator_ui.GetOutput());
- calc_impl.WaitForIncomingMethodCall();
+ calc_impl.binding()->WaitForIncomingMethodCall();
run_loop.Run();
EXPECT_EQ(2.0, calculator_ui.GetOutput());
base::RunLoop run_loop2;
calculator_ui.Multiply(5.0, run_loop2.QuitClosure());
EXPECT_EQ(2.0, calculator_ui.GetOutput());
- calc_impl.WaitForIncomingMethodCall();
+ calc_impl.binding()->WaitForIncomingMethodCall();
run_loop2.Run();
EXPECT_EQ(10.0, calculator_ui.GetOutput());
}
@@ -265,7 +269,7 @@ TEST_F(InterfacePtrTest, EndToEnd_Synchronous) {
TEST_F(InterfacePtrTest, Movable) {
math::CalculatorPtr a;
math::CalculatorPtr b;
- MathCalculatorImpl calc_impl(GetProxy(&b));
+ MathCalculatorImpl calc_impl(MakeRequest(&b));
EXPECT_TRUE(!a);
EXPECT_FALSE(!b);
@@ -312,7 +316,7 @@ TEST_F(InterfacePtrTest, BindInvalidHandle) {
TEST_F(InterfacePtrTest, EncounteredError) {
math::CalculatorPtr proxy;
- MathCalculatorImpl calc_impl(GetProxy(&proxy));
+ MathCalculatorImpl calc_impl(MakeRequest(&proxy));
MathCalculatorUI calculator_ui(std::move(proxy));
@@ -326,7 +330,7 @@ TEST_F(InterfacePtrTest, EncounteredError) {
EXPECT_FALSE(calculator_ui.encountered_error());
// Close the server.
- calc_impl.CloseMessagePipe();
+ calc_impl.binding()->Close();
// The state change isn't picked up locally yet.
base::RunLoop run_loop2;
@@ -341,7 +345,7 @@ TEST_F(InterfacePtrTest, EncounteredError) {
TEST_F(InterfacePtrTest, EncounteredErrorCallback) {
math::CalculatorPtr proxy;
- MathCalculatorImpl calc_impl(GetProxy(&proxy));
+ MathCalculatorImpl calc_impl(MakeRequest(&proxy));
bool encountered_error = false;
base::RunLoop run_loop;
@@ -361,7 +365,7 @@ TEST_F(InterfacePtrTest, EncounteredErrorCallback) {
EXPECT_FALSE(calculator_ui.encountered_error());
// Close the server.
- calc_impl.CloseMessagePipe();
+ calc_impl.binding()->Close();
// The state change isn't picked up locally yet.
EXPECT_FALSE(calculator_ui.encountered_error());
@@ -378,7 +382,7 @@ TEST_F(InterfacePtrTest, EncounteredErrorCallback) {
TEST_F(InterfacePtrTest, DestroyInterfacePtrOnMethodResponse) {
math::CalculatorPtr proxy;
- MathCalculatorImpl calc_impl(GetProxy(&proxy));
+ MathCalculatorImpl calc_impl(MakeRequest(&proxy));
EXPECT_EQ(0, SelfDestructingMathCalculatorUI::num_instances());
@@ -393,7 +397,7 @@ TEST_F(InterfacePtrTest, DestroyInterfacePtrOnMethodResponse) {
TEST_F(InterfacePtrTest, NestedDestroyInterfacePtrOnMethodResponse) {
math::CalculatorPtr proxy;
- MathCalculatorImpl calc_impl(GetProxy(&proxy));
+ MathCalculatorImpl calc_impl(MakeRequest(&proxy));
EXPECT_EQ(0, SelfDestructingMathCalculatorUI::num_instances());
@@ -408,7 +412,7 @@ TEST_F(InterfacePtrTest, NestedDestroyInterfacePtrOnMethodResponse) {
TEST_F(InterfacePtrTest, ReentrantWaitForIncomingMethodCall) {
sample::ServicePtr proxy;
- ReentrantServiceImpl impl(GetProxy(&proxy));
+ ReentrantServiceImpl impl(MakeRequest(&proxy));
base::RunLoop run_loop, run_loop2;
proxy->Frobinate(nullptr, sample::Service::BazOptions::REGULAR, nullptr,
@@ -427,7 +431,7 @@ TEST_F(InterfacePtrTest, ReentrantWaitForIncomingMethodCall) {
TEST_F(InterfacePtrTest, QueryVersion) {
IntegerAccessorImpl impl;
sample::IntegerAccessorPtr ptr;
- Binding<sample::IntegerAccessor> binding(&impl, GetProxy(&ptr));
+ Binding<sample::IntegerAccessor> binding(&impl, MakeRequest(&ptr));
EXPECT_EQ(0u, ptr.version());
@@ -442,7 +446,7 @@ TEST_F(InterfacePtrTest, QueryVersion) {
TEST_F(InterfacePtrTest, RequireVersion) {
IntegerAccessorImpl impl;
sample::IntegerAccessorPtr ptr;
- Binding<sample::IntegerAccessor> binding(&impl, GetProxy(&ptr));
+ Binding<sample::IntegerAccessor> binding(&impl, MakeRequest(&ptr));
EXPECT_EQ(0u, ptr.version());
@@ -479,17 +483,7 @@ TEST_F(InterfacePtrTest, RequireVersion) {
class StrongMathCalculatorImpl : public math::Calculator {
public:
- StrongMathCalculatorImpl(ScopedMessagePipeHandle handle,
- bool* error_received,
- bool* destroyed,
- const base::Closure& closure)
- : error_received_(error_received),
- destroyed_(destroyed),
- closure_(closure),
- binding_(this, std::move(handle)) {
- binding_.set_connection_error_handler(
- base::Bind(&SetFlagAndRunClosure, error_received_, closure_));
- }
+ StrongMathCalculatorImpl(bool* destroyed) : destroyed_(destroyed) {}
~StrongMathCalculatorImpl() override { *destroyed_ = true; }
// math::Calculator implementation.
@@ -507,11 +501,7 @@ class StrongMathCalculatorImpl : public math::Calculator {
private:
double total_ = 0.0;
- bool* error_received_;
bool* destroyed_;
- base::Closure closure_;
-
- StrongBinding<math::Calculator> binding_;
};
TEST(StrongConnectorTest, Math) {
@@ -519,13 +509,14 @@ TEST(StrongConnectorTest, Math) {
bool error_received = false;
bool destroyed = false;
- MessagePipe pipe;
+ math::CalculatorPtr calc;
base::RunLoop run_loop;
- new StrongMathCalculatorImpl(std::move(pipe.handle0), &error_received,
- &destroyed, run_loop.QuitClosure());
- math::CalculatorPtr calc;
- calc.Bind(InterfacePtrInfo<math::Calculator>(std::move(pipe.handle1), 0u));
+ auto binding =
+ MakeStrongBinding(base::MakeUnique<StrongMathCalculatorImpl>(&destroyed),
+ MakeRequest(&calc));
+ binding->set_connection_error_handler(base::Bind(
+ &SetFlagAndRunClosure, &error_received, run_loop.QuitClosure()));
{
// Suppose this is instantiated in a process that has the other end of the
@@ -626,10 +617,8 @@ TEST(WeakConnectorTest, Math) {
class CImpl : public C {
public:
- CImpl(bool* d_called, InterfaceRequest<C> request,
- const base::Closure& closure)
- : d_called_(d_called), binding_(this, std::move(request)),
- closure_(closure) {}
+ CImpl(bool* d_called, const base::Closure& closure)
+ : d_called_(d_called), closure_(closure) {}
~CImpl() override {}
private:
@@ -639,25 +628,22 @@ class CImpl : public C {
}
bool* d_called_;
- StrongBinding<C> binding_;
base::Closure closure_;
};
class BImpl : public B {
public:
- BImpl(bool* d_called, InterfaceRequest<B> request,
- const base::Closure& closure)
- : d_called_(d_called), binding_(this, std::move(request)),
- closure_(closure) {}
+ BImpl(bool* d_called, const base::Closure& closure)
+ : d_called_(d_called), closure_(closure) {}
~BImpl() override {}
private:
void GetC(InterfaceRequest<C> c) override {
- new CImpl(d_called_, std::move(c), closure_);
+ MakeStrongBinding(base::MakeUnique<CImpl>(d_called_, closure_),
+ std::move(c));
}
bool* d_called_;
- StrongBinding<B> binding_;
base::Closure closure_;
};
@@ -672,7 +658,8 @@ class AImpl : public A {
private:
void GetB(InterfaceRequest<B> b) override {
- new BImpl(&d_called_, std::move(b), closure_);
+ MakeStrongBinding(base::MakeUnique<BImpl>(&d_called_, closure_),
+ std::move(b));
}
bool d_called_;
@@ -683,15 +670,15 @@ class AImpl : public A {
TEST_F(InterfacePtrTest, Scoping) {
APtr a;
base::RunLoop run_loop;
- AImpl a_impl(GetProxy(&a), run_loop.QuitClosure());
+ AImpl a_impl(MakeRequest(&a), run_loop.QuitClosure());
EXPECT_FALSE(a_impl.d_called());
{
BPtr b;
- a->GetB(GetProxy(&b));
+ a->GetB(MakeRequest(&b));
CPtr c;
- b->GetC(GetProxy(&c));
+ b->GetC(MakeRequest(&c));
c->D();
}
@@ -718,11 +705,11 @@ class PingTestImpl : public sample::PingTest {
// Tests that FuseProxy does what it's supposed to do.
TEST_F(InterfacePtrTest, Fusion) {
sample::PingTestPtr proxy;
- PingTestImpl impl(GetProxy(&proxy));
+ PingTestImpl impl(MakeRequest(&proxy));
// Create another PingTest pipe.
sample::PingTestPtr ptr;
- sample::PingTestRequest request = GetProxy(&ptr);
+ sample::PingTestRequest request(&ptr);
// Fuse the new pipe to the one hanging off |impl|.
EXPECT_TRUE(FuseInterface(std::move(request), proxy.PassInterface()));
@@ -735,6 +722,216 @@ TEST_F(InterfacePtrTest, Fusion) {
EXPECT_TRUE(called);
}
+void Fail() {
+ FAIL() << "Unexpected connection error";
+}
+
+TEST_F(InterfacePtrTest, FlushForTesting) {
+ math::CalculatorPtr calc;
+ MathCalculatorImpl calc_impl(MakeRequest(&calc));
+ calc.set_connection_error_handler(base::Bind(&Fail));
+
+ MathCalculatorUI calculator_ui(std::move(calc));
+
+ calculator_ui.Add(2.0, base::Bind(&base::DoNothing));
+ calculator_ui.GetInterfacePtr().FlushForTesting();
+ EXPECT_EQ(2.0, calculator_ui.GetOutput());
+
+ calculator_ui.Multiply(5.0, base::Bind(&base::DoNothing));
+ calculator_ui.GetInterfacePtr().FlushForTesting();
+
+ EXPECT_EQ(10.0, calculator_ui.GetOutput());
+}
+
+void SetBool(bool* value) {
+ *value = true;
+}
+
+TEST_F(InterfacePtrTest, FlushForTestingWithClosedPeer) {
+ math::CalculatorPtr calc;
+ MakeRequest(&calc);
+ bool called = false;
+ calc.set_connection_error_handler(base::Bind(&SetBool, &called));
+ calc.FlushForTesting();
+ EXPECT_TRUE(called);
+ calc.FlushForTesting();
+}
+
+TEST_F(InterfacePtrTest, ConnectionErrorWithReason) {
+ math::CalculatorPtr calc;
+ MathCalculatorImpl calc_impl(MakeRequest(&calc));
+
+ base::RunLoop run_loop;
+ calc.set_connection_error_with_reason_handler(base::Bind(
+ [](const base::Closure& quit_closure, uint32_t custom_reason,
+ const std::string& description) {
+ EXPECT_EQ(42u, custom_reason);
+ EXPECT_EQ("hey", description);
+ quit_closure.Run();
+ },
+ run_loop.QuitClosure()));
+
+ calc_impl.binding()->CloseWithReason(42u, "hey");
+
+ run_loop.Run();
+}
+
+TEST_F(InterfacePtrTest, InterfaceRequestResetWithReason) {
+ math::CalculatorPtr calc;
+ auto request = MakeRequest(&calc);
+
+ base::RunLoop run_loop;
+ calc.set_connection_error_with_reason_handler(base::Bind(
+ [](const base::Closure& quit_closure, uint32_t custom_reason,
+ const std::string& description) {
+ EXPECT_EQ(88u, custom_reason);
+ EXPECT_EQ("greetings", description);
+ quit_closure.Run();
+ },
+ run_loop.QuitClosure()));
+
+ request.ResetWithReason(88u, "greetings");
+
+ run_loop.Run();
+}
+
+TEST_F(InterfacePtrTest, CallbackIsPassedInterfacePtr) {
+ sample::PingTestPtr ptr;
+ sample::PingTestRequest request(&ptr);
+
+ base::RunLoop run_loop;
+
+ // Make a call with the proxy's lifetime bound to the response callback.
+ sample::PingTest* raw_proxy = ptr.get();
+ ptr.set_connection_error_handler(run_loop.QuitClosure());
+ raw_proxy->Ping(
+ base::Bind([](sample::PingTestPtr ptr) {}, base::Passed(&ptr)));
+
+ // Trigger an error on |ptr|. This will ultimately lead to the proxy's
+ // response callbacks being destroyed, which will in turn lead to the proxy
+ // being destroyed. This should not crash.
+ request.PassMessagePipe();
+ run_loop.Run();
+}
+
+TEST_F(InterfacePtrTest, ConnectionErrorHandlerOwnsInterfacePtr) {
+ sample::PingTestPtr* ptr = new sample::PingTestPtr;
+ sample::PingTestRequest request(ptr);
+
+ base::RunLoop run_loop;
+
+ // Make a call with |ptr|'s lifetime bound to the connection error handler
+ // callback.
+ ptr->set_connection_error_handler(base::Bind(
+ [](const base::Closure& quit, sample::PingTestPtr* ptr) {
+ ptr->reset();
+ quit.Run();
+ },
+ run_loop.QuitClosure(), base::Owned(ptr)));
+
+ // Trigger an error on |ptr|. In the error handler |ptr| is reset. This
+ // shouldn't immediately destroy the callback (and |ptr| that it owns), before
+ // the callback is completed.
+ request.PassMessagePipe();
+ run_loop.Run();
+}
+
+TEST_F(InterfacePtrTest, ThreadSafeInterfacePointer) {
+ math::CalculatorPtr ptr;
+ MathCalculatorImpl calc_impl(MakeRequest(&ptr));
+ scoped_refptr<math::ThreadSafeCalculatorPtr> thread_safe_ptr =
+ math::ThreadSafeCalculatorPtr::Create(std::move(ptr));
+
+ base::RunLoop run_loop;
+
+ // Create and start the thread from where we'll call the interface pointer.
+ base::Thread other_thread("service test thread");
+ other_thread.Start();
+
+ auto run_method = base::Bind(
+ [](const scoped_refptr<base::TaskRunner>& main_task_runner,
+ const base::Closure& quit_closure,
+ const scoped_refptr<math::ThreadSafeCalculatorPtr>& thread_safe_ptr) {
+ auto calc_callback = base::Bind(
+ [](const scoped_refptr<base::TaskRunner>& main_task_runner,
+ const base::Closure& quit_closure,
+ base::PlatformThreadId thread_id,
+ double result) {
+ EXPECT_EQ(123, result);
+ // Validate the callback is invoked on the calling thread.
+ EXPECT_EQ(thread_id, base::PlatformThread::CurrentId());
+ // Notify the run_loop to quit.
+ main_task_runner->PostTask(FROM_HERE, quit_closure);
+ });
+ (*thread_safe_ptr)->Add(
+ 123, base::Bind(calc_callback, main_task_runner, quit_closure,
+ base::PlatformThread::CurrentId()));
+ },
+ base::SequencedTaskRunnerHandle::Get(), run_loop.QuitClosure(),
+ thread_safe_ptr);
+ other_thread.message_loop()->task_runner()->PostTask(FROM_HERE, run_method);
+
+ // Block until the method callback is called on the background thread.
+ run_loop.Run();
+}
+
+TEST_F(InterfacePtrTest, ThreadSafeInterfacePointerWithTaskRunner) {
+ // Create and start the thread from where we'll bind the interface pointer.
+ base::Thread other_thread("service test thread");
+ other_thread.Start();
+ const scoped_refptr<base::SingleThreadTaskRunner>& other_thread_task_runner =
+ other_thread.message_loop()->task_runner();
+
+ math::CalculatorPtr ptr;
+ math::CalculatorRequest request(&ptr);
+
+ // Create a ThreadSafeInterfacePtr that we'll bind from a different thread.
+ scoped_refptr<math::ThreadSafeCalculatorPtr> thread_safe_ptr =
+ math::ThreadSafeCalculatorPtr::Create(ptr.PassInterface(),
+ other_thread_task_runner);
+ ASSERT_TRUE(thread_safe_ptr);
+
+ MathCalculatorImpl* math_calc_impl = nullptr;
+ {
+ base::RunLoop run_loop;
+ auto run_method = base::Bind(
+ [](const scoped_refptr<base::TaskRunner>& main_task_runner,
+ const base::Closure& quit_closure,
+ const scoped_refptr<math::ThreadSafeCalculatorPtr>& thread_safe_ptr,
+ math::CalculatorRequest request,
+ MathCalculatorImpl** math_calc_impl) {
+ math::CalculatorPtr ptr;
+ // In real life, the implementation would have a legitimate owner.
+ *math_calc_impl = new MathCalculatorImpl(std::move(request));
+ main_task_runner->PostTask(FROM_HERE, quit_closure);
+ },
+ base::SequencedTaskRunnerHandle::Get(), run_loop.QuitClosure(),
+ thread_safe_ptr, base::Passed(&request), &math_calc_impl);
+ other_thread.message_loop()->task_runner()->PostTask(FROM_HERE, run_method);
+ run_loop.Run();
+ }
+
+ {
+ // The interface ptr is bound, we can call methods on it.
+ auto calc_callback =
+ base::Bind([](const base::Closure& quit_closure, double result) {
+ EXPECT_EQ(123, result);
+ quit_closure.Run();
+ });
+ base::RunLoop run_loop;
+ (*thread_safe_ptr)
+ ->Add(123, base::Bind(calc_callback, run_loop.QuitClosure()));
+ // Block until the method callback is called.
+ run_loop.Run();
+ }
+
+ other_thread_task_runner->DeleteSoon(FROM_HERE, math_calc_impl);
+
+ // Reset the pointer now so the InterfacePtr associated resources can be
+ // deleted before the background thread's message loop is invalidated.
+ thread_safe_ptr = nullptr;
+}
+
} // namespace
} // namespace test
} // namespace mojo
diff --git a/mojo/public/cpp/bindings/tests/map_common_test.h b/mojo/public/cpp/bindings/tests/map_common_test.h
deleted file mode 100644
index c8654ce..0000000
--- a/mojo/public/cpp/bindings/tests/map_common_test.h
+++ /dev/null
@@ -1,230 +0,0 @@
-// Copyright 2016 The Chromium 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 "mojo/public/cpp/bindings/array.h"
-#include "mojo/public/cpp/bindings/lib/fixed_buffer.h"
-#include "mojo/public/cpp/bindings/lib/serialization.h"
-#include "mojo/public/cpp/bindings/lib/validate_params.h"
-#include "mojo/public/cpp/bindings/map.h"
-#include "mojo/public/cpp/bindings/string.h"
-#include "mojo/public/cpp/bindings/tests/container_test_util.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace WTF {
-class String;
-}
-
-namespace mojo {
-
-template <typename T>
-class WTFArray;
-
-template <typename K, typename V>
-class WTFMap;
-
-namespace test {
-namespace {
-
-struct StringIntData {
- const char* string_data;
- int int_data;
-} kStringIntData[] = {
- {"one", 1},
- {"two", 2},
- {"three", 3},
- {"four", 4},
-};
-
-const size_t kStringIntDataSize = 4;
-
-} // namespace
-
-template <template <typename...> class MapType>
-struct TypeTraits;
-
-template <>
-struct TypeTraits<Map> {
- using StringType = mojo::String;
- template <typename T>
- using ArrayType = Array<T>;
-};
-
-template <>
-struct TypeTraits<WTFMap> {
- using StringType = WTF::String;
- template <typename T>
- using ArrayType = WTFArray<T>;
-};
-
-// Common tests for both mojo::Map and mojo::WTFMap.
-template <template <typename...> class MapType>
-class MapCommonTest {
- public:
- using StringType = typename TypeTraits<MapType>::StringType;
- template <typename T>
- using ArrayType = typename TypeTraits<MapType>::template ArrayType<T>;
-
- // Tests null and empty maps.
- static void NullAndEmpty() {
- MapType<char, char> map0;
- EXPECT_TRUE(map0.empty());
- EXPECT_FALSE(map0.is_null());
- map0 = nullptr;
- EXPECT_TRUE(map0.is_null());
- EXPECT_FALSE(map0.empty());
-
- MapType<char, char> map1(nullptr);
- EXPECT_TRUE(map1.is_null());
- EXPECT_FALSE(map1.empty());
- map1.SetToEmpty();
- EXPECT_TRUE(map1.empty());
- EXPECT_FALSE(map1.is_null());
- }
-
- // Tests that basic Map operations work.
- static void InsertWorks() {
- MapType<StringType, int> map;
- for (size_t i = 0; i < kStringIntDataSize; ++i)
- map.insert(kStringIntData[i].string_data, kStringIntData[i].int_data);
-
- for (size_t i = 0; i < kStringIntDataSize; ++i) {
- EXPECT_EQ(kStringIntData[i].int_data,
- map.at(kStringIntData[i].string_data));
- }
- }
-
- static void TestIndexOperator() {
- MapType<StringType, int> map;
- for (size_t i = 0; i < kStringIntDataSize; ++i)
- map[kStringIntData[i].string_data] = kStringIntData[i].int_data;
-
- for (size_t i = 0; i < kStringIntDataSize; ++i) {
- EXPECT_EQ(kStringIntData[i].int_data,
- map.at(kStringIntData[i].string_data));
- }
- }
-
- static void TestIndexOperatorAsRValue() {
- MapType<StringType, int> map;
- for (size_t i = 0; i < kStringIntDataSize; ++i)
- map.insert(kStringIntData[i].string_data, kStringIntData[i].int_data);
-
- for (size_t i = 0; i < kStringIntDataSize; ++i) {
- EXPECT_EQ(kStringIntData[i].int_data, map[kStringIntData[i].string_data]);
- }
- }
-
- static void TestIndexOperatorMoveOnly() {
- ASSERT_EQ(0u, MoveOnlyType::num_instances());
- MapType<StringType, ArrayType<int32_t>> map;
-
- for (size_t i = 0; i < kStringIntDataSize; ++i) {
- const char* key = kStringIntData[i].string_data;
- ArrayType<int32_t> array(1);
- array[0] = kStringIntData[i].int_data;
- map[key] = std::move(array);
- EXPECT_TRUE(map);
- }
-
- // We now read back that data, to test the behavior of operator[].
- for (size_t i = 0; i < kStringIntDataSize; ++i) {
- auto& value = map[kStringIntData[i].string_data];
- ASSERT_EQ(1u, value.size());
- EXPECT_EQ(kStringIntData[i].int_data, value[0]);
- }
- }
-
- static void MapArrayClone() {
- MapType<StringType, ArrayType<StringType>> m;
- for (size_t i = 0; i < kStringIntDataSize; ++i) {
- ArrayType<StringType> s(1);
- s[0] = StringType(kStringIntData[i].string_data);
- m.insert(kStringIntData[i].string_data, std::move(s));
- }
-
- MapType<StringType, ArrayType<StringType>> m2 = m.Clone();
-
- for (size_t i = 0; i < kStringIntDataSize; ++i) {
- ASSERT_NE(m2.end(), m2.find(kStringIntData[i].string_data));
- ASSERT_EQ(1u, m2[kStringIntData[i].string_data].size());
- EXPECT_EQ(StringType(kStringIntData[i].string_data),
- m2[kStringIntData[i].string_data][0]);
- }
- }
-
- static void ArrayOfMap() {
- {
- using MojomType = Array<Map<int32_t, int8_t>>;
- using UserType = ArrayType<MapType<int32_t, int8_t>>;
-
- UserType array(1);
- array[0].insert(1, 42);
-
- mojo::internal::SerializationContext context;
- size_t size =
- mojo::internal::PrepareToSerialize<MojomType>(array, &context);
- mojo::internal::FixedBufferForTesting buf(size);
- typename mojo::internal::MojomTypeTraits<MojomType>::Data* data;
- mojo::internal::ContainerValidateParams validate_params(
- 0, false,
- new mojo::internal::ContainerValidateParams(
- new mojo::internal::ContainerValidateParams(0, false, nullptr),
- new mojo::internal::ContainerValidateParams(0, false, nullptr)));
-
- mojo::internal::Serialize<MojomType>(array, &buf, &data, &validate_params,
- &context);
-
- UserType deserialized_array;
- mojo::internal::Deserialize<MojomType>(data, &deserialized_array,
- &context);
-
- ASSERT_EQ(1u, deserialized_array.size());
- ASSERT_EQ(1u, deserialized_array[0].size());
- ASSERT_EQ(42, deserialized_array[0].at(1));
- }
-
- {
- using MojomType = Array<Map<String, Array<bool>>>;
- using UserType = ArrayType<MapType<StringType, ArrayType<bool>>>;
-
- UserType array(1);
- ArrayType<bool> map_value(2);
- map_value[0] = false;
- map_value[1] = true;
- array[0].insert("hello world", std::move(map_value));
-
- mojo::internal::SerializationContext context;
- size_t size =
- mojo::internal::PrepareToSerialize<MojomType>(array, &context);
- mojo::internal::FixedBufferForTesting buf(size);
- typename mojo::internal::MojomTypeTraits<MojomType>::Data* data;
- mojo::internal::ContainerValidateParams validate_params(
- 0, false,
- new mojo::internal::ContainerValidateParams(
- new mojo::internal::ContainerValidateParams(
- 0, false, new mojo::internal::ContainerValidateParams(
- 0, false, nullptr)),
- new mojo::internal::ContainerValidateParams(
- 0, false, new mojo::internal::ContainerValidateParams(
- 0, false, nullptr))));
- mojo::internal::Serialize<MojomType>(array, &buf, &data, &validate_params,
- &context);
-
- UserType deserialized_array;
- mojo::internal::Deserialize<MojomType>(data, &deserialized_array,
- &context);
-
- ASSERT_EQ(1u, deserialized_array.size());
- ASSERT_EQ(1u, deserialized_array[0].size());
- ASSERT_FALSE(deserialized_array[0].at("hello world")[0]);
- ASSERT_TRUE(deserialized_array[0].at("hello world")[1]);
- }
- }
-};
-
-#define MAP_COMMON_TEST(MapType, test_name) \
- TEST_F(MapType##Test, test_name) { MapCommonTest<MapType>::test_name(); }
-
-} // namespace test
-} // namespace mojo
diff --git a/mojo/public/cpp/bindings/tests/map_unittest.cc b/mojo/public/cpp/bindings/tests/map_unittest.cc
index c74a15d..8d630a5 100644
--- a/mojo/public/cpp/bindings/tests/map_unittest.cc
+++ b/mojo/public/cpp/bindings/tests/map_unittest.cc
@@ -1,225 +1,44 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
+// Copyright 2017 The Chromium 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 "mojo/public/cpp/bindings/map.h"
-
#include <stddef.h>
#include <stdint.h>
+#include <unordered_map>
#include <utility>
-#include "mojo/public/cpp/bindings/array.h"
-#include "mojo/public/cpp/bindings/string.h"
-#include "mojo/public/cpp/bindings/tests/container_test_util.h"
-#include "mojo/public/cpp/bindings/tests/map_common_test.h"
+#include "mojo/public/cpp/bindings/tests/rect_chromium.h"
+#include "mojo/public/interfaces/bindings/tests/rect.mojom.h"
+#include "mojo/public/interfaces/bindings/tests/test_structs.mojom.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace mojo {
namespace test {
-
namespace {
-using MapTest = testing::Test;
-
-MAP_COMMON_TEST(Map, NullAndEmpty)
-MAP_COMMON_TEST(Map, InsertWorks)
-MAP_COMMON_TEST(Map, TestIndexOperator)
-MAP_COMMON_TEST(Map, TestIndexOperatorAsRValue)
-MAP_COMMON_TEST(Map, TestIndexOperatorMoveOnly)
-MAP_COMMON_TEST(Map, MapArrayClone)
-MAP_COMMON_TEST(Map, ArrayOfMap)
-
-TEST_F(MapTest, ConstructedFromArray) {
- Array<String> keys(kStringIntDataSize);
- Array<int> values(kStringIntDataSize);
- for (size_t i = 0; i < kStringIntDataSize; ++i) {
- keys[i] = kStringIntData[i].string_data;
- values[i] = kStringIntData[i].int_data;
- }
-
- Map<String, int> map(std::move(keys), std::move(values));
-
- for (size_t i = 0; i < kStringIntDataSize; ++i) {
- EXPECT_EQ(kStringIntData[i].int_data,
- map.at(mojo::String(kStringIntData[i].string_data)));
- }
-}
-
-TEST_F(MapTest, DecomposeMapTo) {
- Array<String> keys(kStringIntDataSize);
- Array<int> values(kStringIntDataSize);
- for (size_t i = 0; i < kStringIntDataSize; ++i) {
- keys[i] = kStringIntData[i].string_data;
- values[i] = kStringIntData[i].int_data;
- }
-
- Map<String, int> map(std::move(keys), std::move(values));
- EXPECT_EQ(kStringIntDataSize, map.size());
-
- Array<String> keys2;
- Array<int> values2;
- map.DecomposeMapTo(&keys2, &values2);
- EXPECT_EQ(0u, map.size());
+TEST(MapTest, StructKey) {
+ std::unordered_map<RectPtr, int32_t> map;
+ map.insert(std::make_pair(Rect::New(1, 2, 3, 4), 123));
- EXPECT_EQ(kStringIntDataSize, keys2.size());
- EXPECT_EQ(kStringIntDataSize, values2.size());
+ RectPtr key = Rect::New(1, 2, 3, 4);
+ ASSERT_NE(map.end(), map.find(key));
+ ASSERT_EQ(123, map.find(key)->second);
- for (size_t i = 0; i < kStringIntDataSize; ++i) {
- // We are not guaranteed that the copies have the same sorting as the
- // originals.
- String key = kStringIntData[i].string_data;
- int value = kStringIntData[i].int_data;
-
- bool found = false;
- for (size_t j = 0; j < keys2.size(); ++j) {
- if (keys2[j] == key) {
- EXPECT_EQ(value, values2[j]);
- found = true;
- break;
- }
- }
-
- EXPECT_TRUE(found);
- }
-}
-
-TEST_F(MapTest, Insert_Copyable) {
- ASSERT_EQ(0u, CopyableType::num_instances());
- mojo::Map<mojo::String, CopyableType> map;
- std::vector<CopyableType*> value_ptrs;
-
- for (size_t i = 0; i < kStringIntDataSize; ++i) {
- const char* key = kStringIntData[i].string_data;
- CopyableType value;
- value_ptrs.push_back(value.ptr());
- map.insert(key, value);
- ASSERT_EQ(i + 1, map.size());
- ASSERT_EQ(i + 1, value_ptrs.size());
- EXPECT_EQ(map.size() + 1, CopyableType::num_instances());
- EXPECT_TRUE(map.at(key).copied());
- EXPECT_EQ(value_ptrs[i], map.at(key).ptr());
- map.at(key).ResetCopied();
- EXPECT_TRUE(map);
- }
-
- // std::map doesn't have a capacity() method like std::vector so this test is
- // a lot more boring.
-
- map = nullptr;
- EXPECT_EQ(0u, CopyableType::num_instances());
+ map.erase(key);
+ ASSERT_EQ(0u, map.size());
}
-TEST_F(MapTest, Insert_MoveOnly) {
- ASSERT_EQ(0u, MoveOnlyType::num_instances());
- mojo::Map<mojo::String, MoveOnlyType> map;
- std::vector<MoveOnlyType*> value_ptrs;
-
- for (size_t i = 0; i < kStringIntDataSize; ++i) {
- const char* key = kStringIntData[i].string_data;
- MoveOnlyType value;
- value_ptrs.push_back(value.ptr());
- map.insert(key, std::move(value));
- ASSERT_EQ(i + 1, map.size());
- ASSERT_EQ(i + 1, value_ptrs.size());
- EXPECT_EQ(map.size() + 1, MoveOnlyType::num_instances());
- EXPECT_TRUE(map.at(key).moved());
- EXPECT_EQ(value_ptrs[i], map.at(key).ptr());
- map.at(key).ResetMoved();
- EXPECT_TRUE(map);
- }
-
- // std::map doesn't have a capacity() method like std::vector so this test is
- // a lot more boring.
-
- map = nullptr;
- EXPECT_EQ(0u, MoveOnlyType::num_instances());
-}
-
-TEST_F(MapTest, IndexOperator_MoveOnly) {
- ASSERT_EQ(0u, MoveOnlyType::num_instances());
- mojo::Map<mojo::String, MoveOnlyType> map;
- std::vector<MoveOnlyType*> value_ptrs;
-
- for (size_t i = 0; i < kStringIntDataSize; ++i) {
- const char* key = kStringIntData[i].string_data;
- MoveOnlyType value;
- value_ptrs.push_back(value.ptr());
- map[key] = std::move(value);
- ASSERT_EQ(i + 1, map.size());
- ASSERT_EQ(i + 1, value_ptrs.size());
- EXPECT_EQ(map.size() + 1, MoveOnlyType::num_instances());
- EXPECT_TRUE(map.at(key).moved());
- EXPECT_EQ(value_ptrs[i], map.at(key).ptr());
- map.at(key).ResetMoved();
- EXPECT_TRUE(map);
- }
-
- // std::map doesn't have a capacity() method like std::vector so this test is
- // a lot more boring.
-
- map = nullptr;
- EXPECT_EQ(0u, MoveOnlyType::num_instances());
-}
-
-TEST_F(MapTest, STLToMojo) {
- std::map<std::string, int> stl_data;
- for (size_t i = 0; i < kStringIntDataSize; ++i)
- stl_data[kStringIntData[i].string_data] = kStringIntData[i].int_data;
-
- Map<String, int32_t> mojo_data = Map<String, int32_t>::From(stl_data);
- for (size_t i = 0; i < kStringIntDataSize; ++i) {
- EXPECT_EQ(kStringIntData[i].int_data,
- mojo_data.at(kStringIntData[i].string_data));
- }
-}
-
-TEST_F(MapTest, MojoToSTL) {
- Map<String, int32_t> mojo_map;
- for (size_t i = 0; i < kStringIntDataSize; ++i)
- mojo_map.insert(kStringIntData[i].string_data, kStringIntData[i].int_data);
-
- std::map<std::string, int> stl_map =
- mojo_map.To<std::map<std::string, int>>();
- for (size_t i = 0; i < kStringIntDataSize; ++i) {
- auto it = stl_map.find(kStringIntData[i].string_data);
- ASSERT_TRUE(it != stl_map.end());
- EXPECT_EQ(kStringIntData[i].int_data, it->second);
- }
-}
-
-TEST_F(MapTest, MoveFromAndToSTLMap_Copyable) {
- std::map<int32_t, CopyableType> map1;
- map1.insert(std::make_pair(123, CopyableType()));
- map1[123].ResetCopied();
-
- Map<int32_t, CopyableType> mojo_map(std::move(map1));
- ASSERT_EQ(1u, mojo_map.size());
- ASSERT_NE(mojo_map.end(), mojo_map.find(123));
- ASSERT_FALSE(mojo_map[123].copied());
-
- std::map<int32_t, CopyableType> map2(mojo_map.PassStorage());
- ASSERT_EQ(1u, map2.size());
- ASSERT_NE(map2.end(), map2.find(123));
- ASSERT_FALSE(map2[123].copied());
-
- ASSERT_EQ(0u, mojo_map.size());
- ASSERT_TRUE(mojo_map.is_null());
-}
-
-TEST_F(MapTest, MoveFromAndToSTLMap_MoveOnly) {
- std::map<int32_t, MoveOnlyType> map1;
- map1.insert(std::make_pair(123, MoveOnlyType()));
-
- Map<int32_t, MoveOnlyType> mojo_map(std::move(map1));
- ASSERT_EQ(1u, mojo_map.size());
- ASSERT_NE(mojo_map.end(), mojo_map.find(123));
+TEST(MapTest, TypemappedStructKey) {
+ std::unordered_map<ContainsHashablePtr, int32_t> map;
+ map.insert(
+ std::make_pair(ContainsHashable::New(RectChromium(1, 2, 3, 4)), 123));
- std::map<int32_t, MoveOnlyType> map2(mojo_map.PassStorage());
- ASSERT_EQ(1u, map2.size());
- ASSERT_NE(map2.end(), map2.find(123));
+ ContainsHashablePtr key = ContainsHashable::New(RectChromium(1, 2, 3, 4));
+ ASSERT_NE(map.end(), map.find(key));
+ ASSERT_EQ(123, map.find(key)->second);
- ASSERT_EQ(0u, mojo_map.size());
- ASSERT_TRUE(mojo_map.is_null());
+ map.erase(key);
+ ASSERT_EQ(0u, map.size());
}
} // namespace
diff --git a/mojo/public/cpp/bindings/tests/message_queue.cc b/mojo/public/cpp/bindings/tests/message_queue.cc
index 96a4829..32ed763 100644
--- a/mojo/public/cpp/bindings/tests/message_queue.cc
+++ b/mojo/public/cpp/bindings/tests/message_queue.cc
@@ -14,8 +14,6 @@ MessageQueue::MessageQueue() {
}
MessageQueue::~MessageQueue() {
- while (!queue_.empty())
- Pop();
}
bool MessageQueue::IsEmpty() const {
@@ -23,19 +21,17 @@ bool MessageQueue::IsEmpty() const {
}
void MessageQueue::Push(Message* message) {
- queue_.push(new Message());
- message->MoveTo(queue_.back());
+ queue_.emplace(std::move(*message));
}
void MessageQueue::Pop(Message* message) {
DCHECK(!queue_.empty());
- queue_.front()->MoveTo(message);
+ *message = std::move(queue_.front());
Pop();
}
void MessageQueue::Pop() {
DCHECK(!queue_.empty());
- delete queue_.front();
queue_.pop();
}
diff --git a/mojo/public/cpp/bindings/tests/message_queue.h b/mojo/public/cpp/bindings/tests/message_queue.h
index 8859869..8f13f7a 100644
--- a/mojo/public/cpp/bindings/tests/message_queue.h
+++ b/mojo/public/cpp/bindings/tests/message_queue.h
@@ -8,10 +8,9 @@
#include <queue>
#include "base/macros.h"
+#include "mojo/public/cpp/bindings/message.h"
namespace mojo {
-class Message;
-
namespace test {
// A queue for Message objects.
@@ -34,7 +33,7 @@ class MessageQueue {
private:
void Pop();
- std::queue<Message*> queue_;
+ std::queue<Message> queue_;
DISALLOW_COPY_AND_ASSIGN(MessageQueue);
};
diff --git a/mojo/public/cpp/bindings/tests/mojo_test_blink_export.h b/mojo/public/cpp/bindings/tests/mojo_test_blink_export.h
new file mode 100644
index 0000000..b3bbe27
--- /dev/null
+++ b/mojo/public/cpp/bindings/tests/mojo_test_blink_export.h
@@ -0,0 +1,29 @@
+// Copyright 2016 The Chromium 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 MOJO_PUBLIC_CPP_BINDINGS_TESTS_MOJO_TEST_BLINK_EXPORT_H_
+#define MOJO_PUBLIC_CPP_BINDINGS_TESTS_MOJO_TEST_BLINK_EXPORT_H_
+
+#if defined(COMPONENT_BUILD)
+#if defined(WIN32)
+
+#if defined(MOJO_TEST_BLINK_IMPLEMENTATION)
+#define MOJO_TEST_BLINK_EXPORT __declspec(dllexport)
+#else
+#define MOJO_TEST_BLINK_EXPORT __declspec(dllimport)
+#endif // defined(MOJO_TEST_BLINK_IMPLEMENTATION)
+
+#else // defined(WIN32)
+#if defined(MOJO_TEST_BLINK_IMPLEMENTATION)
+#define MOJO_TEST_BLINK_EXPORT __attribute__((visibility("default")))
+#else
+#define MOJO_TEST_BLINK_EXPORT
+#endif
+#endif
+
+#else // defined(COMPONENT_BUILD)
+#define MOJO_TEST_BLINK_EXPORT
+#endif
+
+#endif // MOJO_PUBLIC_CPP_BINDINGS_TESTS_MOJO_TEST_BLINK_EXPORT_H_
diff --git a/mojo/public/cpp/bindings/tests/mojo_test_export.h b/mojo/public/cpp/bindings/tests/mojo_test_export.h
new file mode 100644
index 0000000..a48a1ba
--- /dev/null
+++ b/mojo/public/cpp/bindings/tests/mojo_test_export.h
@@ -0,0 +1,29 @@
+// Copyright 2016 The Chromium 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 MOJO_PUBLIC_CPP_BINDINGS_TESTS_MOJO_TEST_EXPORT_H_
+#define MOJO_PUBLIC_CPP_BINDINGS_TESTS_MOJO_TEST_EXPORT_H_
+
+#if defined(COMPONENT_BUILD)
+#if defined(WIN32)
+
+#if defined(MOJO_TEST_IMPLEMENTATION)
+#define MOJO_TEST_EXPORT __declspec(dllexport)
+#else
+#define MOJO_TEST_EXPORT __declspec(dllimport)
+#endif // defined(MOJO_TEST_IMPLEMENTATION)
+
+#else // defined(WIN32)
+#if defined(MOJO_TEST_IMPLEMENTATION)
+#define MOJO_TEST_EXPORT __attribute__((visibility("default")))
+#else
+#define MOJO_TEST_EXPORT
+#endif
+#endif
+
+#else // defined(COMPONENT_BUILD)
+#define MOJO_TEST_EXPORT
+#endif
+
+#endif // MOJO_PUBLIC_CPP_BINDINGS_TESTS_MOJO_TEST_EXPORT_H_
diff --git a/mojo/public/cpp/bindings/tests/multiplex_router_unittest.cc b/mojo/public/cpp/bindings/tests/multiplex_router_unittest.cc
index 9bfcf2c..31963e0 100644
--- a/mojo/public/cpp/bindings/tests/multiplex_router_unittest.cc
+++ b/mojo/public/cpp/bindings/tests/multiplex_router_unittest.cc
@@ -14,7 +14,6 @@
#include "base/threading/thread_task_runner_handle.h"
#include "mojo/public/cpp/bindings/interface_endpoint_client.h"
#include "mojo/public/cpp/bindings/message.h"
-#include "mojo/public/cpp/bindings/message_filter.h"
#include "mojo/public/cpp/bindings/scoped_interface_endpoint_handle.h"
#include "mojo/public/cpp/bindings/tests/message_queue.h"
#include "mojo/public/cpp/bindings/tests/router_test_util.h"
@@ -32,27 +31,22 @@ class MultiplexRouterTest : public testing::Test {
void SetUp() override {
MessagePipe pipe;
- router0_ = new MultiplexRouter(true, std::move(pipe.handle0),
+ router0_ = new MultiplexRouter(std::move(pipe.handle0),
+ MultiplexRouter::MULTI_INTERFACE, false,
base::ThreadTaskRunnerHandle::Get());
- router1_ = new MultiplexRouter(true, std::move(pipe.handle1),
+ router1_ = new MultiplexRouter(std::move(pipe.handle1),
+ MultiplexRouter::MULTI_INTERFACE, true,
base::ThreadTaskRunnerHandle::Get());
- router0_->CreateEndpointHandlePair(&endpoint0_, &endpoint1_);
- endpoint1_ =
- EmulatePassingEndpointHandle(std::move(endpoint1_), router1_.get());
+ ScopedInterfaceEndpointHandle::CreatePairPendingAssociation(&endpoint0_,
+ &endpoint1_);
+ auto id = router0_->AssociateInterface(std::move(endpoint1_));
+ endpoint1_ = router1_->CreateLocalEndpointHandle(id);
}
void TearDown() override {}
void PumpMessages() { base::RunLoop().RunUntilIdle(); }
- ScopedInterfaceEndpointHandle EmulatePassingEndpointHandle(
- ScopedInterfaceEndpointHandle handle,
- MultiplexRouter* target) {
- CHECK(!handle.is_local());
-
- return target->CreateLocalEndpointHandle(handle.release());
- }
-
protected:
scoped_refptr<MultiplexRouter> router0_;
scoped_refptr<MultiplexRouter> router1_;
@@ -65,12 +59,12 @@ class MultiplexRouterTest : public testing::Test {
TEST_F(MultiplexRouterTest, BasicRequestResponse) {
InterfaceEndpointClient client0(std::move(endpoint0_), nullptr,
- base::WrapUnique(new PassThroughFilter()),
- false, base::ThreadTaskRunnerHandle::Get());
+ base::MakeUnique<PassThroughFilter>(), false,
+ base::ThreadTaskRunnerHandle::Get(), 0u);
ResponseGenerator generator;
InterfaceEndpointClient client1(std::move(endpoint1_), &generator,
- base::WrapUnique(new PassThroughFilter()),
- false, base::ThreadTaskRunnerHandle::Get());
+ base::MakeUnique<PassThroughFilter>(), false,
+ base::ThreadTaskRunnerHandle::Get(), 0u);
Message request;
AllocRequestMessage(1, "hello", &request);
@@ -112,12 +106,12 @@ TEST_F(MultiplexRouterTest, BasicRequestResponse) {
TEST_F(MultiplexRouterTest, BasicRequestResponse_Synchronous) {
InterfaceEndpointClient client0(std::move(endpoint0_), nullptr,
- base::WrapUnique(new PassThroughFilter()),
- false, base::ThreadTaskRunnerHandle::Get());
+ base::MakeUnique<PassThroughFilter>(), false,
+ base::ThreadTaskRunnerHandle::Get(), 0u);
ResponseGenerator generator;
InterfaceEndpointClient client1(std::move(endpoint1_), &generator,
- base::WrapUnique(new PassThroughFilter()),
- false, base::ThreadTaskRunnerHandle::Get());
+ base::MakeUnique<PassThroughFilter>(), false,
+ base::ThreadTaskRunnerHandle::Get(), 0u);
Message request;
AllocRequestMessage(1, "hello", &request);
@@ -154,46 +148,18 @@ TEST_F(MultiplexRouterTest, BasicRequestResponse_Synchronous) {
std::string(reinterpret_cast<const char*>(response.payload())));
}
-TEST_F(MultiplexRouterTest, RequestWithNoReceiver) {
- InterfaceEndpointClient client0(std::move(endpoint0_), nullptr,
- base::WrapUnique(new PassThroughFilter()),
- false, base::ThreadTaskRunnerHandle::Get());
- InterfaceEndpointClient client1(std::move(endpoint1_), nullptr,
- base::WrapUnique(new PassThroughFilter()),
- false, base::ThreadTaskRunnerHandle::Get());
-
- // Without an incoming receiver set on client1, we expect client0 to observe
- // an error as a result of sending a message.
-
- Message request;
- AllocRequestMessage(1, "hello", &request);
-
- MessageQueue message_queue;
- base::RunLoop run_loop, run_loop2;
- client0.set_connection_error_handler(run_loop.QuitClosure());
- client1.set_connection_error_handler(run_loop2.QuitClosure());
- client0.AcceptWithResponder(
- &request, new MessageAccumulator(&message_queue, run_loop.QuitClosure()));
-
- run_loop.Run();
- run_loop2.Run();
-
- EXPECT_TRUE(client0.encountered_error());
- EXPECT_TRUE(client1.encountered_error());
- EXPECT_TRUE(message_queue.IsEmpty());
-}
-
// Tests MultiplexRouter using the LazyResponseGenerator. The responses will not
// be sent until after the requests have been accepted.
TEST_F(MultiplexRouterTest, LazyResponses) {
- InterfaceEndpointClient client0(std::move(endpoint0_), nullptr,
- base::WrapUnique(new PassThroughFilter()),
- false, base::ThreadTaskRunnerHandle::Get());
+ InterfaceEndpointClient client0(
+ std::move(endpoint0_), nullptr, base::WrapUnique(new PassThroughFilter()),
+ false, base::ThreadTaskRunnerHandle::Get(), 0u);
base::RunLoop run_loop;
LazyResponseGenerator generator(run_loop.QuitClosure());
InterfaceEndpointClient client1(std::move(endpoint1_), &generator,
base::WrapUnique(new PassThroughFilter()),
- false, base::ThreadTaskRunnerHandle::Get());
+ false, base::ThreadTaskRunnerHandle::Get(),
+ 0u);
Message request;
AllocRequestMessage(1, "hello", &request);
@@ -257,9 +223,9 @@ void ForwardErrorHandler(bool* called, const base::Closure& callback) {
// both sides still appear to have a valid message pipe handle bound.
TEST_F(MultiplexRouterTest, MissingResponses) {
base::RunLoop run_loop0, run_loop1;
- InterfaceEndpointClient client0(std::move(endpoint0_), nullptr,
- base::WrapUnique(new PassThroughFilter()),
- false, base::ThreadTaskRunnerHandle::Get());
+ InterfaceEndpointClient client0(
+ std::move(endpoint0_), nullptr, base::WrapUnique(new PassThroughFilter()),
+ false, base::ThreadTaskRunnerHandle::Get(), 0u);
bool error_handler_called0 = false;
client0.set_connection_error_handler(
base::Bind(&ForwardErrorHandler, &error_handler_called0,
@@ -269,7 +235,8 @@ TEST_F(MultiplexRouterTest, MissingResponses) {
LazyResponseGenerator generator(run_loop3.QuitClosure());
InterfaceEndpointClient client1(std::move(endpoint1_), &generator,
base::WrapUnique(new PassThroughFilter()),
- false, base::ThreadTaskRunnerHandle::Get());
+ false, base::ThreadTaskRunnerHandle::Get(),
+ 0u);
bool error_handler_called1 = false;
client1.set_connection_error_handler(
base::Bind(&ForwardErrorHandler, &error_handler_called1,
@@ -314,12 +281,13 @@ TEST_F(MultiplexRouterTest, LateResponse) {
base::RunLoop run_loop;
LazyResponseGenerator generator(run_loop.QuitClosure());
{
- InterfaceEndpointClient client0(std::move(endpoint0_), nullptr,
- base::WrapUnique(new PassThroughFilter()),
- false, base::ThreadTaskRunnerHandle::Get());
+ InterfaceEndpointClient client0(
+ std::move(endpoint0_), nullptr, base::MakeUnique<PassThroughFilter>(),
+ false, base::ThreadTaskRunnerHandle::Get(), 0u);
InterfaceEndpointClient client1(std::move(endpoint1_), &generator,
- base::WrapUnique(new PassThroughFilter()),
- false, base::ThreadTaskRunnerHandle::Get());
+ base::MakeUnique<PassThroughFilter>(),
+ false, base::ThreadTaskRunnerHandle::Get(),
+ 0u);
Message request;
AllocRequestMessage(1, "hello", &request);
diff --git a/mojo/public/cpp/bindings/tests/pickle_unittest.cc b/mojo/public/cpp/bindings/tests/pickle_unittest.cc
index bd716cc..a5947ce 100644
--- a/mojo/public/cpp/bindings/tests/pickle_unittest.cc
+++ b/mojo/public/cpp/bindings/tests/pickle_unittest.cc
@@ -24,28 +24,25 @@ namespace test {
namespace {
template <typename T>
-void DoExpectResult(int foo,
- int bar,
- const base::Closure& callback,
- const T& actual) {
+void DoExpectResult(int foo, int bar, const base::Closure& callback, T actual) {
EXPECT_EQ(foo, actual.foo());
EXPECT_EQ(bar, actual.bar());
callback.Run();
}
template <typename T>
-base::Callback<void(const T&)> ExpectResult(const T& t,
- const base::Closure& callback) {
+base::Callback<void(T)> ExpectResult(const T& t,
+ const base::Closure& callback) {
return base::Bind(&DoExpectResult<T>, t.foo(), t.bar(), callback);
}
template <typename T>
-void DoFail(const std::string& reason, const T&) {
+void DoFail(const std::string& reason, T) {
EXPECT_TRUE(false) << reason;
}
template <typename T>
-base::Callback<void(const T&)> Fail(const std::string& reason) {
+base::Callback<void(T)> Fail(const std::string& reason) {
return base::Bind(&DoFail<T>, reason);
}
@@ -89,9 +86,9 @@ class ChromiumPicklePasserImpl : public PicklePasser {
ChromiumPicklePasserImpl() {}
// mojo::test::PicklePasser:
- void PassPickledStruct(const PickledStructChromium& pickle,
+ void PassPickledStruct(PickledStructChromium pickle,
const PassPickledStructCallback& callback) override {
- callback.Run(pickle);
+ callback.Run(std::move(pickle));
}
void PassPickledEnum(PickledEnumChromium pickle,
@@ -105,15 +102,15 @@ class ChromiumPicklePasserImpl : public PicklePasser {
callback.Run(std::move(container));
}
- void PassPickles(const std::vector<PickledStructChromium>& pickles,
+ void PassPickles(std::vector<PickledStructChromium> pickles,
const PassPicklesCallback& callback) override {
- callback.Run(pickles);
+ callback.Run(std::move(pickles));
}
void PassPickleArrays(
- const std::vector<std::vector<PickledStructChromium>>& pickle_arrays,
+ std::vector<std::vector<PickledStructChromium>> pickle_arrays,
const PassPickleArraysCallback& callback) override {
- callback.Run(pickle_arrays);
+ callback.Run(std::move(pickle_arrays));
}
};
@@ -123,9 +120,9 @@ class BlinkPicklePasserImpl : public blink::PicklePasser {
BlinkPicklePasserImpl() {}
// mojo::test::blink::PicklePasser:
- void PassPickledStruct(const PickledStructBlink& pickle,
+ void PassPickledStruct(PickledStructBlink pickle,
const PassPickledStructCallback& callback) override {
- callback.Run(pickle);
+ callback.Run(std::move(pickle));
}
void PassPickledEnum(PickledEnumBlink pickle,
@@ -139,15 +136,15 @@ class BlinkPicklePasserImpl : public blink::PicklePasser {
callback.Run(std::move(container));
}
- void PassPickles(const WTF::Vector<PickledStructBlink>& pickles,
+ void PassPickles(WTF::Vector<PickledStructBlink> pickles,
const PassPicklesCallback& callback) override {
- callback.Run(pickles);
+ callback.Run(std::move(pickles));
}
void PassPickleArrays(
- const WTF::Vector<WTF::Vector<PickledStructBlink>>& pickle_arrays,
+ WTF::Vector<WTF::Vector<PickledStructBlink>> pickle_arrays,
const PassPickleArraysCallback& callback) override {
- callback.Run(pickle_arrays);
+ callback.Run(std::move(pickle_arrays));
}
};
@@ -160,7 +157,7 @@ class PickleTest : public testing::Test {
template <typename ProxyType = PicklePasser>
InterfacePtr<ProxyType> ConnectToChromiumService() {
InterfacePtr<ProxyType> proxy;
- InterfaceRequest<ProxyType> request = GetProxy(&proxy);
+ InterfaceRequest<ProxyType> request(&proxy);
chromium_bindings_.AddBinding(
&chromium_service_,
ConvertInterfaceRequest<PicklePasser>(std::move(request)));
@@ -170,7 +167,7 @@ class PickleTest : public testing::Test {
template <typename ProxyType = blink::PicklePasser>
InterfacePtr<ProxyType> ConnectToBlinkService() {
InterfacePtr<ProxyType> proxy;
- InterfaceRequest<ProxyType> request = GetProxy(&proxy);
+ InterfaceRequest<ProxyType> request(&proxy);
blink_bindings_.AddBinding(
&blink_service_,
ConvertInterfaceRequest<blink::PicklePasser>(std::move(request)));
@@ -301,7 +298,7 @@ TEST_F(PickleTest, BlinkProxyToChromiumService) {
TEST_F(PickleTest, PickleArray) {
auto proxy = ConnectToChromiumService();
- auto pickles = Array<PickledStructChromium>::New(2);
+ auto pickles = std::vector<PickledStructChromium>(2);
pickles[0].set_foo(1);
pickles[0].set_bar(2);
pickles[0].set_baz(100);
@@ -314,19 +311,18 @@ TEST_F(PickleTest, PickleArray) {
// deserialized intact. This ensures that the ParamTraits are actually used
// rather than doing a byte-for-byte copy of the element data, beacuse the
// |baz| field should never be serialized.
- proxy->PassPickles(
- std::move(pickles),
- BindSimpleLambda<const std::vector<PickledStructChromium>&>(
- [&](const std::vector<PickledStructChromium>& passed) {
- ASSERT_EQ(2u, passed.size());
- EXPECT_EQ(1, passed[0].foo());
- EXPECT_EQ(2, passed[0].bar());
- EXPECT_EQ(0, passed[0].baz());
- EXPECT_EQ(3, passed[1].foo());
- EXPECT_EQ(4, passed[1].bar());
- EXPECT_EQ(0, passed[1].baz());
- run_loop.Quit();
- }));
+ proxy->PassPickles(std::move(pickles),
+ BindSimpleLambda<std::vector<PickledStructChromium>>(
+ [&](std::vector<PickledStructChromium> passed) {
+ ASSERT_EQ(2u, passed.size());
+ EXPECT_EQ(1, passed[0].foo());
+ EXPECT_EQ(2, passed[0].bar());
+ EXPECT_EQ(0, passed[0].baz());
+ EXPECT_EQ(3, passed[1].foo());
+ EXPECT_EQ(4, passed[1].bar());
+ EXPECT_EQ(0, passed[1].baz());
+ run_loop.Quit();
+ }));
run_loop.Run();
}
}
@@ -353,10 +349,9 @@ TEST_F(PickleTest, PickleArrayArray) {
base::RunLoop run_loop;
// Verify that the array-of-arrays serializes and deserializes properly.
proxy->PassPickleArrays(
- pickle_arrays,
- BindSimpleLambda<
- const std::vector<std::vector<PickledStructChromium>>&>(
- [&](const std::vector<std::vector<PickledStructChromium>>& passed) {
+ std::move(pickle_arrays),
+ BindSimpleLambda<std::vector<std::vector<PickledStructChromium>>>(
+ [&](std::vector<std::vector<PickledStructChromium>> passed) {
ASSERT_EQ(2u, passed.size());
ASSERT_EQ(2u, passed[0].size());
ASSERT_EQ(2u, passed[1].size());
diff --git a/mojo/public/cpp/bindings/tests/pickled_types_blink.h b/mojo/public/cpp/bindings/tests/pickled_types_blink.h
index 0b7bd20..37e9e70 100644
--- a/mojo/public/cpp/bindings/tests/pickled_types_blink.h
+++ b/mojo/public/cpp/bindings/tests/pickled_types_blink.h
@@ -51,9 +51,14 @@ class PickledStructBlink {
bar_ = bar;
}
+ // The |baz| field should never be serialized.
+ int baz() const { return baz_; }
+ void set_baz(int baz) { baz_ = baz; }
+
private:
int foo_ = 0;
int bar_ = 0;
+ int baz_ = 0;
DISALLOW_COPY_AND_ASSIGN(PickledStructBlink);
};
diff --git a/mojo/public/cpp/bindings/tests/rect_blink.h b/mojo/public/cpp/bindings/tests/rect_blink.h
index de7a792..7335989 100644
--- a/mojo/public/cpp/bindings/tests/rect_blink.h
+++ b/mojo/public/cpp/bindings/tests/rect_blink.h
@@ -51,6 +51,12 @@ class RectBlink {
int computeArea() const { return width_ * height_; }
+ bool operator==(const RectBlink& other) const {
+ return (x() == other.x() && y() == other.y() && width() == other.width() &&
+ height() == other.height());
+ }
+ bool operator!=(const RectBlink& other) const { return !(*this == other); }
+
private:
int x_ = 0;
int y_ = 0;
@@ -61,4 +67,17 @@ class RectBlink {
} // namespace test
} // namespace mojo
+namespace std {
+
+template <>
+struct hash<mojo::test::RectBlink> {
+ size_t operator()(const mojo::test::RectBlink& value) {
+ // Terrible hash function:
+ return (std::hash<int>()(value.x()) ^ std::hash<int>()(value.y()) ^
+ std::hash<int>()(value.width()) ^ std::hash<int>()(value.height()));
+ }
+};
+
+} // namespace std
+
#endif // MOJO_PUBLIC_CPP_BINDINGS_TESTS_RECT_BLINK_H_
diff --git a/mojo/public/cpp/bindings/tests/rect_blink.typemap b/mojo/public/cpp/bindings/tests/rect_blink.typemap
index 37ee409..657ea1a 100644
--- a/mojo/public/cpp/bindings/tests/rect_blink.typemap
+++ b/mojo/public/cpp/bindings/tests/rect_blink.typemap
@@ -3,7 +3,16 @@
# found in the LICENSE file.
mojom = "//mojo/public/interfaces/bindings/tests/rect.mojom"
-public_headers = [ "//mojo/public/cpp/bindings/tests/rect_blink.h" ]
-traits_headers = [ "//mojo/public/cpp/bindings/tests/rect_blink_traits.h" ]
+public_headers = [
+ "//mojo/public/cpp/bindings/tests/rect_blink.h",
+ "//mojo/public/cpp/bindings/tests/shared_rect.h",
+]
+traits_headers = [
+ "//mojo/public/cpp/bindings/tests/rect_blink_traits.h",
+ "//mojo/public/cpp/bindings/tests/shared_rect_traits.h",
+]
-type_mappings = [ "mojo.test.TypemappedRect=mojo::test::RectBlink" ]
+type_mappings = [
+ "mojo.test.TypemappedRect=mojo::test::RectBlink[hashable]",
+ "mojo.test.SharedTypemappedRect=mojo::test::SharedRect",
+]
diff --git a/mojo/public/cpp/bindings/tests/rect_blink_traits.h b/mojo/public/cpp/bindings/tests/rect_blink_traits.h
index c5f6068..7258739 100644
--- a/mojo/public/cpp/bindings/tests/rect_blink_traits.h
+++ b/mojo/public/cpp/bindings/tests/rect_blink_traits.h
@@ -12,14 +12,13 @@
namespace mojo {
template <>
-struct StructTraits<test::blink::TypemappedRect, test::RectBlink> {
+struct StructTraits<test::TypemappedRectDataView, test::RectBlink> {
static int x(const test::RectBlink& r) { return r.x(); }
static int y(const test::RectBlink& r) { return r.y(); }
static int width(const test::RectBlink& r) { return r.width(); }
static int height(const test::RectBlink& r) { return r.height(); }
- static bool Read(test::blink::TypemappedRectDataView r,
- test::RectBlink* out) {
+ static bool Read(test::TypemappedRectDataView r, test::RectBlink* out) {
if (r.x() < 0 || r.y() < 0 || r.width() < 0 || r.height() < 0) {
return false;
}
diff --git a/mojo/public/cpp/bindings/tests/rect_chromium.h b/mojo/public/cpp/bindings/tests/rect_chromium.h
index 20c4362..d2e0a3e 100644
--- a/mojo/public/cpp/bindings/tests/rect_chromium.h
+++ b/mojo/public/cpp/bindings/tests/rect_chromium.h
@@ -55,6 +55,12 @@ class RectChromium {
int GetArea() const { return width_ * height_; }
+ bool operator==(const RectChromium& other) const {
+ return (x() == other.x() && y() == other.y() && width() == other.width() &&
+ height() == other.height());
+ }
+ bool operator!=(const RectChromium& other) const { return !(*this == other); }
+
private:
int x_ = 0;
int y_ = 0;
@@ -65,4 +71,17 @@ class RectChromium {
} // namespace test
} // namespace mojo
+namespace std {
+
+template <>
+struct hash<mojo::test::RectChromium> {
+ size_t operator()(const mojo::test::RectChromium& value) {
+ // Terrible hash function:
+ return (std::hash<int>()(value.x()) ^ std::hash<int>()(value.y()) ^
+ std::hash<int>()(value.width()) ^ std::hash<int>()(value.height()));
+ }
+};
+
+} // namespace std
+
#endif // MOJO_PUBLIC_CPP_BINDINGS_TESTS_RECT_CHROMIUM_H_
diff --git a/mojo/public/cpp/bindings/tests/rect_chromium.typemap b/mojo/public/cpp/bindings/tests/rect_chromium.typemap
index 0da4021..7e5df84 100644
--- a/mojo/public/cpp/bindings/tests/rect_chromium.typemap
+++ b/mojo/public/cpp/bindings/tests/rect_chromium.typemap
@@ -3,7 +3,16 @@
# found in the LICENSE file.
mojom = "//mojo/public/interfaces/bindings/tests/rect.mojom"
-public_headers = [ "//mojo/public/cpp/bindings/tests/rect_chromium.h" ]
-traits_headers = [ "//mojo/public/cpp/bindings/tests/rect_chromium_traits.h" ]
+public_headers = [
+ "//mojo/public/cpp/bindings/tests/rect_chromium.h",
+ "//mojo/public/cpp/bindings/tests/shared_rect.h",
+]
+traits_headers = [
+ "//mojo/public/cpp/bindings/tests/rect_chromium_traits.h",
+ "//mojo/public/cpp/bindings/tests/shared_rect_traits.h",
+]
-type_mappings = [ "mojo.test.TypemappedRect=mojo::test::RectChromium" ]
+type_mappings = [
+ "mojo.test.TypemappedRect=mojo::test::RectChromium[hashable]",
+ "mojo.test.SharedTypemappedRect=mojo::test::SharedRect",
+]
diff --git a/mojo/public/cpp/bindings/tests/rect_chromium_traits.h b/mojo/public/cpp/bindings/tests/rect_chromium_traits.h
index ab65371..b446d7d 100644
--- a/mojo/public/cpp/bindings/tests/rect_chromium_traits.h
+++ b/mojo/public/cpp/bindings/tests/rect_chromium_traits.h
@@ -12,7 +12,7 @@
namespace mojo {
template <>
-struct StructTraits<test::TypemappedRect, test::RectChromium> {
+struct StructTraits<test::TypemappedRectDataView, test::RectChromium> {
static int x(const test::RectChromium& r) { return r.x(); }
static int y(const test::RectChromium& r) { return r.y(); }
static int width(const test::RectChromium& r) { return r.width(); }
diff --git a/mojo/public/cpp/bindings/tests/report_bad_message_unittest.cc b/mojo/public/cpp/bindings/tests/report_bad_message_unittest.cc
new file mode 100644
index 0000000..1bf3f7a
--- /dev/null
+++ b/mojo/public/cpp/bindings/tests/report_bad_message_unittest.cc
@@ -0,0 +1,194 @@
+// Copyright 2016 The Chromium 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 "base/bind.h"
+#include "base/callback.h"
+#include "base/macros.h"
+#include "base/message_loop/message_loop.h"
+#include "base/run_loop.h"
+#include "mojo/edk/embedder/embedder.h"
+#include "mojo/public/cpp/bindings/binding.h"
+#include "mojo/public/cpp/bindings/message.h"
+#include "mojo/public/interfaces/bindings/tests/test_bad_messages.mojom.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace mojo {
+namespace test {
+namespace {
+
+class TestBadMessagesImpl : public TestBadMessages {
+ public:
+ TestBadMessagesImpl() : binding_(this) {}
+ ~TestBadMessagesImpl() override {}
+
+ void BindImpl(TestBadMessagesRequest request) {
+ binding_.Bind(std::move(request));
+ }
+
+ const ReportBadMessageCallback& bad_message_callback() {
+ return bad_message_callback_;
+ }
+
+ private:
+ // TestBadMessages:
+ void RejectEventually(const RejectEventuallyCallback& callback) override {
+ bad_message_callback_ = GetBadMessageCallback();
+ callback.Run();
+ }
+
+ void RequestResponse(const RequestResponseCallback& callback) override {
+ callback.Run();
+ }
+
+ void RejectSync(const RejectSyncCallback& callback) override {
+ callback.Run();
+ ReportBadMessage("go away");
+ }
+
+ void RequestResponseSync(
+ const RequestResponseSyncCallback& callback) override {
+ callback.Run();
+ }
+
+ ReportBadMessageCallback bad_message_callback_;
+ mojo::Binding<TestBadMessages> binding_;
+
+ DISALLOW_COPY_AND_ASSIGN(TestBadMessagesImpl);
+};
+
+class ReportBadMessageTest : public testing::Test {
+ public:
+ ReportBadMessageTest() {}
+
+ void SetUp() override {
+ mojo::edk::SetDefaultProcessErrorCallback(
+ base::Bind(&ReportBadMessageTest::OnProcessError,
+ base::Unretained(this)));
+
+ impl_.BindImpl(MakeRequest(&proxy_));
+ }
+
+ void TearDown() override {
+ mojo::edk::SetDefaultProcessErrorCallback(
+ mojo::edk::ProcessErrorCallback());
+ }
+
+ TestBadMessages* proxy() { return proxy_.get(); }
+
+ TestBadMessagesImpl* impl() { return &impl_; }
+
+ void SetErrorHandler(const base::Closure& handler) {
+ error_handler_ = handler;
+ }
+
+ private:
+ void OnProcessError(const std::string& error) {
+ if (!error_handler_.is_null())
+ error_handler_.Run();
+ }
+
+ TestBadMessagesPtr proxy_;
+ TestBadMessagesImpl impl_;
+ base::Closure error_handler_;
+ base::MessageLoop message_loop;
+};
+
+TEST_F(ReportBadMessageTest, Request) {
+ // Verify that basic immediate error reporting works.
+ bool error = false;
+ SetErrorHandler(base::Bind([] (bool* flag) { *flag = true; }, &error));
+ EXPECT_TRUE(proxy()->RejectSync());
+ EXPECT_TRUE(error);
+}
+
+TEST_F(ReportBadMessageTest, RequestAsync) {
+ bool error = false;
+ SetErrorHandler(base::Bind([] (bool* flag) { *flag = true; }, &error));
+
+ // This should capture a bad message reporting callback in the impl.
+ base::RunLoop loop;
+ proxy()->RejectEventually(loop.QuitClosure());
+ loop.Run();
+
+ EXPECT_FALSE(error);
+
+ // Now we can run the callback and it should trigger a bad message report.
+ DCHECK(!impl()->bad_message_callback().is_null());
+ impl()->bad_message_callback().Run("bad!");
+ EXPECT_TRUE(error);
+}
+
+TEST_F(ReportBadMessageTest, Response) {
+ bool error = false;
+ SetErrorHandler(base::Bind([] (bool* flag) { *flag = true; }, &error));
+
+ base::RunLoop loop;
+ proxy()->RequestResponse(
+ base::Bind([] (const base::Closure& quit) {
+ // Report a bad message inside the response callback. This should
+ // trigger the error handler.
+ ReportBadMessage("no way!");
+ quit.Run();
+ },
+ loop.QuitClosure()));
+ loop.Run();
+
+ EXPECT_TRUE(error);
+}
+
+TEST_F(ReportBadMessageTest, ResponseAsync) {
+ bool error = false;
+ SetErrorHandler(base::Bind([] (bool* flag) { *flag = true; }, &error));
+
+ ReportBadMessageCallback bad_message_callback;
+ base::RunLoop loop;
+ proxy()->RequestResponse(
+ base::Bind([] (const base::Closure& quit,
+ ReportBadMessageCallback* callback) {
+ // Capture the bad message callback inside the response callback.
+ *callback = GetBadMessageCallback();
+ quit.Run();
+ },
+ loop.QuitClosure(), &bad_message_callback));
+ loop.Run();
+
+ EXPECT_FALSE(error);
+
+ // Invoking this callback should report a bad message and trigger the error
+ // handler immediately.
+ bad_message_callback.Run("this message is bad and should feel bad");
+ EXPECT_TRUE(error);
+}
+
+TEST_F(ReportBadMessageTest, ResponseSync) {
+ bool error = false;
+ SetErrorHandler(base::Bind([] (bool* flag) { *flag = true; }, &error));
+
+ SyncMessageResponseContext context;
+ proxy()->RequestResponseSync();
+
+ EXPECT_FALSE(error);
+ context.ReportBadMessage("i don't like this response");
+ EXPECT_TRUE(error);
+}
+
+TEST_F(ReportBadMessageTest, ResponseSyncDeferred) {
+ bool error = false;
+ SetErrorHandler(base::Bind([] (bool* flag) { *flag = true; }, &error));
+
+ ReportBadMessageCallback bad_message_callback;
+ {
+ SyncMessageResponseContext context;
+ proxy()->RequestResponseSync();
+ bad_message_callback = context.GetBadMessageCallback();
+ }
+
+ EXPECT_FALSE(error);
+ bad_message_callback.Run("nope nope nope");
+ EXPECT_TRUE(error);
+}
+
+} // namespace
+} // namespace test
+} // namespace mojo
diff --git a/mojo/public/cpp/bindings/tests/request_response_unittest.cc b/mojo/public/cpp/bindings/tests/request_response_unittest.cc
index 5e203a2..43b8f0d 100644
--- a/mojo/public/cpp/bindings/tests/request_response_unittest.cc
+++ b/mojo/public/cpp/bindings/tests/request_response_unittest.cc
@@ -95,7 +95,7 @@ class RequestResponseTest : public testing::Test {
TEST_F(RequestResponseTest, EchoString) {
sample::ProviderPtr provider;
- ProviderImpl provider_impl(GetProxy(&provider));
+ ProviderImpl provider_impl(MakeRequest(&provider));
std::string buf;
base::RunLoop run_loop;
@@ -109,7 +109,7 @@ TEST_F(RequestResponseTest, EchoString) {
TEST_F(RequestResponseTest, EchoStrings) {
sample::ProviderPtr provider;
- ProviderImpl provider_impl(GetProxy(&provider));
+ ProviderImpl provider_impl(MakeRequest(&provider));
std::string buf;
base::RunLoop run_loop;
@@ -123,7 +123,7 @@ TEST_F(RequestResponseTest, EchoStrings) {
TEST_F(RequestResponseTest, EchoMessagePipeHandle) {
sample::ProviderPtr provider;
- ProviderImpl provider_impl(GetProxy(&provider));
+ ProviderImpl provider_impl(MakeRequest(&provider));
MessagePipe pipe2;
base::RunLoop run_loop;
@@ -141,7 +141,7 @@ TEST_F(RequestResponseTest, EchoMessagePipeHandle) {
TEST_F(RequestResponseTest, EchoEnum) {
sample::ProviderPtr provider;
- ProviderImpl provider_impl(GetProxy(&provider));
+ ProviderImpl provider_impl(MakeRequest(&provider));
sample::Enum value;
base::RunLoop run_loop;
diff --git a/mojo/public/cpp/bindings/tests/router_test_util.cc b/mojo/public/cpp/bindings/tests/router_test_util.cc
index 3e32ec7..b9b93d8 100644
--- a/mojo/public/cpp/bindings/tests/router_test_util.cc
+++ b/mojo/public/cpp/bindings/tests/router_test_util.cc
@@ -17,10 +17,10 @@ namespace test {
void AllocRequestMessage(uint32_t name, const char* text, Message* message) {
size_t payload_size = strlen(text) + 1; // Plus null terminator.
- internal::RequestMessageBuilder builder(name, payload_size);
+ internal::MessageBuilder builder(name, Message::kFlagExpectsResponse,
+ payload_size, 0);
memcpy(builder.buffer()->Allocate(payload_size), text, payload_size);
-
- builder.message()->MoveTo(message);
+ *message = std::move(*builder.message());
}
void AllocResponseMessage(uint32_t name,
@@ -28,10 +28,11 @@ void AllocResponseMessage(uint32_t name,
uint64_t request_id,
Message* message) {
size_t payload_size = strlen(text) + 1; // Plus null terminator.
- internal::ResponseMessageBuilder builder(name, payload_size, request_id);
+ internal::MessageBuilder builder(name, Message::kFlagIsResponse, payload_size,
+ 0);
+ builder.message()->set_request_id(request_id);
memcpy(builder.buffer()->Allocate(payload_size), text, payload_size);
-
- builder.message()->MoveTo(message);
+ *message = std::move(*builder.message());
}
MessageAccumulator::MessageAccumulator(MessageQueue* queue,
diff --git a/mojo/public/cpp/bindings/tests/router_unittest.cc b/mojo/public/cpp/bindings/tests/router_unittest.cc
deleted file mode 100644
index 39a8363..0000000
--- a/mojo/public/cpp/bindings/tests/router_unittest.cc
+++ /dev/null
@@ -1,316 +0,0 @@
-// Copyright 2014 The Chromium 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 "mojo/public/cpp/bindings/lib/router.h"
-
-#include <utility>
-
-#include "base/bind.h"
-#include "base/message_loop/message_loop.h"
-#include "base/run_loop.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "mojo/public/cpp/bindings/tests/message_queue.h"
-#include "mojo/public/cpp/bindings/tests/router_test_util.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace mojo {
-namespace test {
-namespace {
-
-class RouterTest : public testing::Test {
- public:
- RouterTest() {}
-
- void SetUp() override {
- CreateMessagePipe(nullptr, &handle0_, &handle1_);
- }
-
- void TearDown() override {}
-
- void PumpMessages() { base::RunLoop().RunUntilIdle(); }
-
- protected:
- ScopedMessagePipeHandle handle0_;
- ScopedMessagePipeHandle handle1_;
-
- private:
- base::MessageLoop loop_;
-};
-
-TEST_F(RouterTest, BasicRequestResponse) {
- internal::Router router0(std::move(handle0_), internal::FilterChain(), false,
- base::ThreadTaskRunnerHandle::Get());
- internal::Router router1(std::move(handle1_), internal::FilterChain(), false,
- base::ThreadTaskRunnerHandle::Get());
-
- ResponseGenerator generator;
- router1.set_incoming_receiver(&generator);
-
- Message request;
- AllocRequestMessage(1, "hello", &request);
-
- MessageQueue message_queue;
- base::RunLoop run_loop;
- router0.AcceptWithResponder(
- &request, new MessageAccumulator(&message_queue, run_loop.QuitClosure()));
-
- run_loop.Run();
-
- EXPECT_FALSE(message_queue.IsEmpty());
-
- Message response;
- message_queue.Pop(&response);
-
- EXPECT_EQ(std::string("hello world!"),
- std::string(reinterpret_cast<const char*>(response.payload())));
-
- // Send a second message on the pipe.
- Message request2;
- AllocRequestMessage(1, "hello again", &request2);
-
- base::RunLoop run_loop2;
- router0.AcceptWithResponder(
- &request2,
- new MessageAccumulator(&message_queue, run_loop2.QuitClosure()));
-
- run_loop2.Run();
-
- EXPECT_FALSE(message_queue.IsEmpty());
-
- message_queue.Pop(&response);
-
- EXPECT_EQ(std::string("hello again world!"),
- std::string(reinterpret_cast<const char*>(response.payload())));
-}
-
-TEST_F(RouterTest, BasicRequestResponse_Synchronous) {
- internal::Router router0(std::move(handle0_), internal::FilterChain(), false,
- base::ThreadTaskRunnerHandle::Get());
- internal::Router router1(std::move(handle1_), internal::FilterChain(), false,
- base::ThreadTaskRunnerHandle::Get());
-
- ResponseGenerator generator;
- router1.set_incoming_receiver(&generator);
-
- Message request;
- AllocRequestMessage(1, "hello", &request);
-
- MessageQueue message_queue;
- router0.AcceptWithResponder(&request, new MessageAccumulator(&message_queue));
-
- router1.WaitForIncomingMessage(MOJO_DEADLINE_INDEFINITE);
- router0.WaitForIncomingMessage(MOJO_DEADLINE_INDEFINITE);
-
- EXPECT_FALSE(message_queue.IsEmpty());
-
- Message response;
- message_queue.Pop(&response);
-
- EXPECT_EQ(std::string("hello world!"),
- std::string(reinterpret_cast<const char*>(response.payload())));
-
- // Send a second message on the pipe.
- Message request2;
- AllocRequestMessage(1, "hello again", &request2);
-
- router0.AcceptWithResponder(&request2,
- new MessageAccumulator(&message_queue));
-
- router1.WaitForIncomingMessage(MOJO_DEADLINE_INDEFINITE);
- router0.WaitForIncomingMessage(MOJO_DEADLINE_INDEFINITE);
-
- EXPECT_FALSE(message_queue.IsEmpty());
-
- message_queue.Pop(&response);
-
- EXPECT_EQ(std::string("hello again world!"),
- std::string(reinterpret_cast<const char*>(response.payload())));
-}
-
-TEST_F(RouterTest, RequestWithNoReceiver) {
- internal::Router router0(std::move(handle0_), internal::FilterChain(), false,
- base::ThreadTaskRunnerHandle::Get());
- internal::Router router1(std::move(handle1_), internal::FilterChain(), false,
- base::ThreadTaskRunnerHandle::Get());
-
- // Without an incoming receiver set on router1, we expect router0 to observe
- // an error as a result of sending a message.
-
- Message request;
- AllocRequestMessage(1, "hello", &request);
-
- MessageQueue message_queue;
- base::RunLoop run_loop, run_loop2;
- router0.set_connection_error_handler(run_loop.QuitClosure());
- router1.set_connection_error_handler(run_loop2.QuitClosure());
- router0.AcceptWithResponder(&request, new MessageAccumulator(&message_queue));
-
- run_loop.Run();
- run_loop2.Run();
-
- EXPECT_TRUE(router0.encountered_error());
- EXPECT_TRUE(router1.encountered_error());
- EXPECT_TRUE(message_queue.IsEmpty());
-}
-
-// Tests Router using the LazyResponseGenerator. The responses will not be
-// sent until after the requests have been accepted.
-TEST_F(RouterTest, LazyResponses) {
- internal::Router router0(std::move(handle0_), internal::FilterChain(), false,
- base::ThreadTaskRunnerHandle::Get());
- internal::Router router1(std::move(handle1_), internal::FilterChain(), false,
- base::ThreadTaskRunnerHandle::Get());
-
- base::RunLoop run_loop;
- LazyResponseGenerator generator(run_loop.QuitClosure());
- router1.set_incoming_receiver(&generator);
-
- Message request;
- AllocRequestMessage(1, "hello", &request);
-
- MessageQueue message_queue;
- base::RunLoop run_loop2;
- router0.AcceptWithResponder(
- &request,
- new MessageAccumulator(&message_queue, run_loop2.QuitClosure()));
- run_loop.Run();
-
- // The request has been received but the response has not been sent yet.
- EXPECT_TRUE(message_queue.IsEmpty());
-
- // Send the response.
- EXPECT_TRUE(generator.responder_is_valid());
- generator.CompleteWithResponse();
- run_loop2.Run();
-
- // Check the response.
- EXPECT_FALSE(message_queue.IsEmpty());
- Message response;
- message_queue.Pop(&response);
- EXPECT_EQ(std::string("hello world!"),
- std::string(reinterpret_cast<const char*>(response.payload())));
-
- // Send a second message on the pipe.
- base::RunLoop run_loop3;
- LazyResponseGenerator generator2(run_loop3.QuitClosure());
-
- router1.set_incoming_receiver(&generator2);
- Message request2;
- AllocRequestMessage(1, "hello again", &request2);
-
- base::RunLoop run_loop4;
- router0.AcceptWithResponder(
- &request2,
- new MessageAccumulator(&message_queue, run_loop4.QuitClosure()));
- run_loop3.Run();
-
- // The request has been received but the response has not been sent yet.
- EXPECT_TRUE(message_queue.IsEmpty());
-
- // Send the second response.
- EXPECT_TRUE(generator2.responder_is_valid());
- generator2.CompleteWithResponse();
- run_loop4.Run();
-
- // Check the second response.
- EXPECT_FALSE(message_queue.IsEmpty());
- message_queue.Pop(&response);
- EXPECT_EQ(std::string("hello again world!"),
- std::string(reinterpret_cast<const char*>(response.payload())));
-}
-
-void ForwardErrorHandler(bool* called, const base::Closure& callback) {
- *called = true;
- callback.Run();
-}
-
-// Tests that if the receiving application destroys the responder_ without
-// sending a response, then we trigger connection error at both sides. Moreover,
-// both sides still appear to have a valid message pipe handle bound.
-TEST_F(RouterTest, MissingResponses) {
- base::RunLoop run_loop0, run_loop1;
- internal::Router router0(std::move(handle0_), internal::FilterChain(), false,
- base::ThreadTaskRunnerHandle::Get());
- bool error_handler_called0 = false;
- router0.set_connection_error_handler(
- base::Bind(&ForwardErrorHandler, &error_handler_called0,
- run_loop0.QuitClosure()));
-
- internal::Router router1(std::move(handle1_), internal::FilterChain(), false,
- base::ThreadTaskRunnerHandle::Get());
- bool error_handler_called1 = false;
- router1.set_connection_error_handler(
- base::Bind(&ForwardErrorHandler, &error_handler_called1,
- run_loop1.QuitClosure()));
-
- base::RunLoop run_loop3;
- LazyResponseGenerator generator(run_loop3.QuitClosure());
- router1.set_incoming_receiver(&generator);
- router1.set_incoming_receiver(&generator);
-
- Message request;
- AllocRequestMessage(1, "hello", &request);
-
- MessageQueue message_queue;
- router0.AcceptWithResponder(&request, new MessageAccumulator(&message_queue));
- run_loop3.Run();
-
- // The request has been received but no response has been sent.
- EXPECT_TRUE(message_queue.IsEmpty());
-
- // Destroy the responder MessagerReceiver but don't send any response.
- generator.CompleteWithoutResponse();
- run_loop0.Run();
- run_loop1.Run();
-
- // Check that no response was received.
- EXPECT_TRUE(message_queue.IsEmpty());
-
- // Connection error handler is called at both sides.
- EXPECT_TRUE(error_handler_called0);
- EXPECT_TRUE(error_handler_called1);
-
- // The error flag is set at both sides.
- EXPECT_TRUE(router0.encountered_error());
- EXPECT_TRUE(router1.encountered_error());
-
- // The message pipe handle is valid at both sides.
- EXPECT_TRUE(router0.is_valid());
- EXPECT_TRUE(router1.is_valid());
-}
-
-TEST_F(RouterTest, LateResponse) {
- // Test that things won't blow up if we try to send a message to a
- // MessageReceiver, which was given to us via AcceptWithResponder,
- // after the router has gone away.
-
- base::RunLoop run_loop;
- LazyResponseGenerator generator(run_loop.QuitClosure());
- {
- internal::Router router0(std::move(handle0_), internal::FilterChain(),
- false, base::ThreadTaskRunnerHandle::Get());
- internal::Router router1(std::move(handle1_), internal::FilterChain(),
- false, base::ThreadTaskRunnerHandle::Get());
-
- router1.set_incoming_receiver(&generator);
-
- Message request;
- AllocRequestMessage(1, "hello", &request);
-
- MessageQueue message_queue;
- router0.AcceptWithResponder(&request,
- new MessageAccumulator(&message_queue));
-
- run_loop.Run();
-
- EXPECT_TRUE(generator.has_responder());
- }
-
- EXPECT_FALSE(generator.responder_is_valid());
- generator.CompleteWithResponse(); // This should end up doing nothing.
-}
-
-} // namespace
-} // namespace test
-} // namespace mojo
diff --git a/mojo/public/cpp/bindings/tests/sample_service_unittest.cc b/mojo/public/cpp/bindings/tests/sample_service_unittest.cc
index 00a8dbf..579576f 100644
--- a/mojo/public/cpp/bindings/tests/sample_service_unittest.cc
+++ b/mojo/public/cpp/bindings/tests/sample_service_unittest.cc
@@ -38,22 +38,13 @@ bool g_dump_message_as_text = false;
FooPtr MakeFoo() {
std::string name("foopy");
- BarPtr bar(Bar::New());
- bar->alpha = 20;
- bar->beta = 40;
- bar->gamma = 60;
- bar->type = Bar::Type::VERTICAL;
+ BarPtr bar(Bar::New(20, 40, 60, Bar::Type::VERTICAL));
std::vector<BarPtr> extra_bars(3);
for (size_t i = 0; i < extra_bars.size(); ++i) {
Bar::Type type = i % 2 == 0 ? Bar::Type::VERTICAL : Bar::Type::HORIZONTAL;
- BarPtr bar(Bar::New());
uint8_t base = static_cast<uint8_t>(i * 100);
- bar->alpha = base;
- bar->beta = base + 20;
- bar->gamma = base + 40;
- bar->type = type;
- extra_bars[i] = std::move(bar);
+ extra_bars[i] = Bar::New(base, base + 20, base + 40, type);
}
std::vector<uint8_t> data(10);
@@ -84,22 +75,11 @@ FooPtr MakeFoo() {
}
mojo::MessagePipe pipe;
- FooPtr foo(Foo::New());
- foo->name = name;
- foo->x = 1;
- foo->y = 2;
- foo->a = false;
- foo->b = true;
- foo->c = false;
- foo->bar = std::move(bar);
- foo->extra_bars = std::move(extra_bars);
- foo->data = std::move(data);
- foo->source = std::move(pipe.handle1);
- foo->input_streams = std::move(input_streams);
- foo->output_streams = std::move(output_streams);
- foo->array_of_array_of_bools = std::move(array_of_array_of_bools);
-
- return foo;
+ return Foo::New(name, 1, 2, false, true, false, std::move(bar),
+ std::move(extra_bars), std::move(data),
+ std::move(pipe.handle1), std::move(input_streams),
+ std::move(output_streams), std::move(array_of_array_of_bools),
+ base::nullopt, base::nullopt);
}
// Check that the given |Foo| is identical to the one made by |MakeFoo()|.
@@ -310,7 +290,7 @@ class SimpleMessageReceiver : public mojo::MessageReceiverWithResponder {
// the system. It receives the incoming message.
ServiceImpl impl;
- ServiceStub stub;
+ ServiceStub<> stub;
stub.set_sink(&impl);
return stub.Accept(message);
}
diff --git a/mojo/public/cpp/bindings/tests/serialization_warning_unittest.cc b/mojo/public/cpp/bindings/tests/serialization_warning_unittest.cc
index dcf2967..275f10f 100644
--- a/mojo/public/cpp/bindings/tests/serialization_warning_unittest.cc
+++ b/mojo/public/cpp/bindings/tests/serialization_warning_unittest.cc
@@ -8,12 +8,10 @@
#include <stddef.h>
#include <utility>
-#include "mojo/public/cpp/bindings/array.h"
#include "mojo/public/cpp/bindings/lib/array_internal.h"
#include "mojo/public/cpp/bindings/lib/fixed_buffer.h"
#include "mojo/public/cpp/bindings/lib/serialization.h"
#include "mojo/public/cpp/bindings/lib/validation_errors.h"
-#include "mojo/public/cpp/bindings/string.h"
#include "mojo/public/cpp/system/message_pipe.h"
#include "mojo/public/interfaces/bindings/tests/serialization_test_structs.mojom.h"
#include "mojo/public/interfaces/bindings/tests/test_unions.mojom.h"
@@ -26,15 +24,16 @@ namespace {
using mojo::internal::ContainerValidateParams;
// Creates an array of arrays of handles (2 X 3) for testing.
-Array<Array<ScopedHandle>> CreateTestNestedHandleArray() {
- Array<Array<ScopedHandle>> array(2);
+std::vector<base::Optional<std::vector<ScopedHandle>>>
+CreateTestNestedHandleArray() {
+ std::vector<base::Optional<std::vector<ScopedHandle>>> array(2);
for (size_t i = 0; i < array.size(); ++i) {
- Array<ScopedHandle> nested_array(3);
+ std::vector<ScopedHandle> nested_array(3);
for (size_t j = 0; j < nested_array.size(); ++j) {
MessagePipe pipe;
nested_array[j] = ScopedHandle::From(std::move(pipe.handle1));
}
- array[i] = std::move(nested_array);
+ array[i].emplace(std::move(nested_array));
}
return array;
@@ -47,18 +46,20 @@ class SerializationWarningTest : public testing::Test {
protected:
template <typename T>
void TestWarning(T obj, mojo::internal::ValidationError expected_warning) {
+ using MojomType = typename T::Struct::DataView;
+
warning_observer_.set_last_warning(mojo::internal::VALIDATION_ERROR_NONE);
mojo::internal::SerializationContext context;
mojo::internal::FixedBufferForTesting buf(
- mojo::internal::PrepareToSerialize<T>(obj, &context));
- typename mojo::internal::MojomTypeTraits<T>::Data* data;
- mojo::internal::Serialize<T>(obj, &buf, &data, &context);
+ mojo::internal::PrepareToSerialize<MojomType>(obj, &context));
+ typename mojo::internal::MojomTypeTraits<MojomType>::Data* data;
+ mojo::internal::Serialize<MojomType>(obj, &buf, &data, &context);
EXPECT_EQ(expected_warning, warning_observer_.last_warning());
}
- template <typename T>
+ template <typename MojomType, typename T>
void TestArrayWarning(T obj,
mojo::internal::ValidationError expected_warning,
const ContainerValidateParams* validate_params) {
@@ -66,9 +67,10 @@ class SerializationWarningTest : public testing::Test {
mojo::internal::SerializationContext context;
mojo::internal::FixedBufferForTesting buf(
- mojo::internal::PrepareToSerialize<T>(obj, &context));
- typename mojo::internal::MojomTypeTraits<T>::Data* data;
- mojo::internal::Serialize<T>(obj, &buf, &data, validate_params, &context);
+ mojo::internal::PrepareToSerialize<MojomType>(obj, &context));
+ typename mojo::internal::MojomTypeTraits<MojomType>::Data* data;
+ mojo::internal::Serialize<MojomType>(obj, &buf, &data, validate_params,
+ &context);
EXPECT_EQ(expected_warning, warning_observer_.last_warning());
}
@@ -76,13 +78,15 @@ class SerializationWarningTest : public testing::Test {
template <typename T>
void TestUnionWarning(T obj,
mojo::internal::ValidationError expected_warning) {
+ using MojomType = typename T::Struct::DataView;
+
warning_observer_.set_last_warning(mojo::internal::VALIDATION_ERROR_NONE);
mojo::internal::SerializationContext context;
mojo::internal::FixedBufferForTesting buf(
- mojo::internal::PrepareToSerialize<T>(obj, false, &context));
- typename mojo::internal::MojomTypeTraits<T>::Data* data;
- mojo::internal::Serialize<T>(obj, &buf, &data, false, &context);
+ mojo::internal::PrepareToSerialize<MojomType>(obj, false, &context));
+ typename mojo::internal::MojomTypeTraits<MojomType>::Data* data;
+ mojo::internal::Serialize<MojomType>(obj, &buf, &data, false, &context);
EXPECT_EQ(expected_warning, warning_observer_.last_warning());
}
@@ -153,57 +157,64 @@ TEST_F(SerializationWarningTest, FixedArrayOfStructsInStruct) {
}
TEST_F(SerializationWarningTest, ArrayOfArraysOfHandles) {
- Array<Array<ScopedHandle>> test_array = CreateTestNestedHandleArray();
- test_array[0] = nullptr;
- test_array[1][0] = ScopedHandle();
+ using MojomType = ArrayDataView<ArrayDataView<ScopedHandle>>;
+ auto test_array = CreateTestNestedHandleArray();
+ test_array[0] = base::nullopt;
+ (*test_array[1])[0] = ScopedHandle();
ContainerValidateParams validate_params_0(
0, true, new ContainerValidateParams(0, true, nullptr));
- TestArrayWarning(std::move(test_array), mojo::internal::VALIDATION_ERROR_NONE,
- &validate_params_0);
+ TestArrayWarning<MojomType>(std::move(test_array),
+ mojo::internal::VALIDATION_ERROR_NONE,
+ &validate_params_0);
test_array = CreateTestNestedHandleArray();
- test_array[0] = nullptr;
+ test_array[0] = base::nullopt;
ContainerValidateParams validate_params_1(
0, false, new ContainerValidateParams(0, true, nullptr));
- TestArrayWarning(std::move(test_array),
- mojo::internal::VALIDATION_ERROR_UNEXPECTED_NULL_POINTER,
- &validate_params_1);
+ TestArrayWarning<MojomType>(
+ std::move(test_array),
+ mojo::internal::VALIDATION_ERROR_UNEXPECTED_NULL_POINTER,
+ &validate_params_1);
test_array = CreateTestNestedHandleArray();
- test_array[1][0] = ScopedHandle();
+ (*test_array[1])[0] = ScopedHandle();
ContainerValidateParams validate_params_2(
0, true, new ContainerValidateParams(0, false, nullptr));
- TestArrayWarning(std::move(test_array),
- mojo::internal::VALIDATION_ERROR_UNEXPECTED_INVALID_HANDLE,
- &validate_params_2);
+ TestArrayWarning<MojomType>(
+ std::move(test_array),
+ mojo::internal::VALIDATION_ERROR_UNEXPECTED_INVALID_HANDLE,
+ &validate_params_2);
}
TEST_F(SerializationWarningTest, ArrayOfStrings) {
- Array<String> test_array(3);
+ using MojomType = ArrayDataView<StringDataView>;
+
+ std::vector<std::string> test_array(3);
for (size_t i = 0; i < test_array.size(); ++i)
test_array[i] = "hello";
ContainerValidateParams validate_params_0(
0, true, new ContainerValidateParams(0, false, nullptr));
- TestArrayWarning(std::move(test_array), mojo::internal::VALIDATION_ERROR_NONE,
- &validate_params_0);
+ TestArrayWarning<MojomType>(std::move(test_array),
+ mojo::internal::VALIDATION_ERROR_NONE,
+ &validate_params_0);
- test_array = Array<String>(3);
- for (size_t i = 0; i < test_array.size(); ++i)
- test_array[i] = nullptr;
+ std::vector<base::Optional<std::string>> optional_test_array(3);
ContainerValidateParams validate_params_1(
0, false, new ContainerValidateParams(0, false, nullptr));
- TestArrayWarning(std::move(test_array),
- mojo::internal::VALIDATION_ERROR_UNEXPECTED_NULL_POINTER,
- &validate_params_1);
+ TestArrayWarning<MojomType>(
+ std::move(optional_test_array),
+ mojo::internal::VALIDATION_ERROR_UNEXPECTED_NULL_POINTER,
+ &validate_params_1);
- test_array = Array<String>(2);
+ test_array = std::vector<std::string>(2);
ContainerValidateParams validate_params_2(
3, true, new ContainerValidateParams(0, false, nullptr));
- TestArrayWarning(std::move(test_array),
- mojo::internal::VALIDATION_ERROR_UNEXPECTED_ARRAY_HEADER,
- &validate_params_2);
+ TestArrayWarning<MojomType>(
+ std::move(test_array),
+ mojo::internal::VALIDATION_ERROR_UNEXPECTED_ARRAY_HEADER,
+ &validate_params_2);
}
TEST_F(SerializationWarningTest, StructInUnion) {
diff --git a/mojo/public/cpp/bindings/tests/shared_rect.h b/mojo/public/cpp/bindings/tests/shared_rect.h
new file mode 100644
index 0000000..c0a4771
--- /dev/null
+++ b/mojo/public/cpp/bindings/tests/shared_rect.h
@@ -0,0 +1,43 @@
+// Copyright 2016 The Chromium 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 MOJO_PUBLIC_CPP_BINDINGS_TESTS_SHARED_RECT_H_
+#define MOJO_PUBLIC_CPP_BINDINGS_TESTS_SHARED_RECT_H_
+
+#include "base/logging.h"
+
+namespace mojo {
+namespace test {
+
+// An implementation of a hypothetical Rect type specifically for consumers in
+// both Chromium and Blink.
+class SharedRect {
+ public:
+ SharedRect() {}
+ SharedRect(int x, int y, int width, int height)
+ : x_(x), y_(y), width_(width), height_(height) {}
+
+ int x() const { return x_; }
+ void set_x(int x) { x_ = x; }
+
+ int y() const { return y_; }
+ void set_y(int y) { y_ = y; }
+
+ int width() const { return width_; }
+ void set_width(int width) { width_ = width; }
+
+ int height() const { return height_; }
+ void set_height(int height) { height_ = height; }
+
+ private:
+ int x_ = 0;
+ int y_ = 0;
+ int width_ = 0;
+ int height_ = 0;
+};
+
+} // namespace test
+} // namespace mojo
+
+#endif // MOJO_PUBLIC_CPP_BINDINGS_TESTS_SHARED_RECT_H_
diff --git a/mojo/public/cpp/bindings/tests/shared_rect_traits.h b/mojo/public/cpp/bindings/tests/shared_rect_traits.h
new file mode 100644
index 0000000..bbf04d5
--- /dev/null
+++ b/mojo/public/cpp/bindings/tests/shared_rect_traits.h
@@ -0,0 +1,33 @@
+// Copyright 2016 The Chromium 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 MOJO_PUBLIC_CPP_BINDINGS_TESTS_SHARED_RECT_TRAITS_H_
+#define MOJO_PUBLIC_CPP_BINDINGS_TESTS_SHARED_RECT_TRAITS_H_
+
+#include "mojo/public/cpp/bindings/struct_traits.h"
+#include "mojo/public/cpp/bindings/tests/shared_rect.h"
+#include "mojo/public/interfaces/bindings/tests/rect.mojom-shared.h"
+
+namespace mojo {
+
+template <>
+struct StructTraits<test::SharedTypemappedRectDataView, test::SharedRect> {
+ static int x(const test::SharedRect& r) { return r.x(); }
+ static int y(const test::SharedRect& r) { return r.y(); }
+ static int width(const test::SharedRect& r) { return r.width(); }
+ static int height(const test::SharedRect& r) { return r.height(); }
+
+ static bool Read(test::SharedTypemappedRectDataView r,
+ test::SharedRect* out) {
+ out->set_x(r.x());
+ out->set_y(r.y());
+ out->set_width(r.width());
+ out->set_height(r.height());
+ return true;
+ }
+};
+
+} // namespace mojo
+
+#endif // MOJO_PUBLIC_CPP_BINDINGS_TESTS_SHARED_RECT_TRAITS_H_
diff --git a/mojo/public/cpp/bindings/tests/stl_converters_unittest.cc b/mojo/public/cpp/bindings/tests/stl_converters_unittest.cc
deleted file mode 100644
index 92a31b3..0000000
--- a/mojo/public/cpp/bindings/tests/stl_converters_unittest.cc
+++ /dev/null
@@ -1,93 +0,0 @@
-// Copyright 2016 The Chromium 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 "mojo/public/cpp/bindings/stl_converters.h"
-
-#include <map>
-#include <string>
-#include <vector>
-
-#include "mojo/public/cpp/bindings/array.h"
-#include "mojo/public/cpp/bindings/map.h"
-#include "mojo/public/cpp/bindings/string.h"
-#include "mojo/public/cpp/bindings/tests/container_test_util.h"
-#include "mojo/public/interfaces/bindings/tests/test_structs.mojom.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace mojo {
-namespace test {
-
-using STLConvertersTest = testing::Test;
-
-TEST_F(STLConvertersTest, AvoidUnnecessaryCopies) {
- Array<CopyableType> mojo_array(1);
- std::vector<CopyableType> stl_vector = UnwrapToSTLType(std::move(mojo_array));
- ASSERT_EQ(1u, stl_vector.size());
- ASSERT_FALSE(stl_vector[0].copied());
- Array<CopyableType> mojo_array2 = WrapSTLType(std::move(stl_vector));
- ASSERT_EQ(1u, mojo_array2.size());
- ASSERT_FALSE(mojo_array2[0].copied());
-
- Map<int32_t, CopyableType> mojo_map;
- mojo_map.insert(42, CopyableType());
- mojo_map[42].ResetCopied();
- std::map<int32_t, CopyableType> stl_map =
- UnwrapToSTLType(std::move(mojo_map));
- ASSERT_EQ(1u, stl_map.size());
- ASSERT_FALSE(stl_map[42].copied());
- Map<int32_t, CopyableType> mojo_map2 = WrapSTLType(std::move(stl_map));
- ASSERT_EQ(1u, mojo_map2.size());
- ASSERT_FALSE(mojo_map2[42].copied());
-}
-
-TEST_F(STLConvertersTest, RecursiveConversion) {
- Array<Map<String, Array<int32_t>>> mojo_obj(2);
- mojo_obj[0] = nullptr;
- mojo_obj[1]["hello"].push_back(123);
- mojo_obj[1]["hello"].push_back(456);
-
- std::vector<std::map<std::string, std::vector<int32_t>>> stl_obj =
- UnwrapToSTLType(std::move(mojo_obj));
-
- ASSERT_EQ(2u, stl_obj.size());
- ASSERT_TRUE(stl_obj[0].empty());
- ASSERT_EQ(1u, stl_obj[1].size());
- ASSERT_EQ(2u, stl_obj[1]["hello"].size());
- ASSERT_EQ(123, stl_obj[1]["hello"][0]);
- ASSERT_EQ(456, stl_obj[1]["hello"][1]);
-
- Array<Map<String, Array<int32_t>>> mojo_obj2 =
- WrapSTLType(std::move(stl_obj));
-
- ASSERT_EQ(2u, mojo_obj2.size());
- ASSERT_EQ(0u, mojo_obj2[0].size());
- // The null flag has been lost when converted to std::map.
- ASSERT_FALSE(mojo_obj2[0].is_null());
- ASSERT_EQ(1u, mojo_obj2[1].size());
- ASSERT_EQ(2u, mojo_obj2[1]["hello"].size());
- ASSERT_EQ(123, mojo_obj2[1]["hello"][0]);
- ASSERT_EQ(456, mojo_obj2[1]["hello"][1]);
-}
-
-TEST_F(STLConvertersTest, StopsAtMojoStruct) {
- Array<NamedRegionPtr> mojo_obj(1);
- mojo_obj[0] = NamedRegion::New();
- mojo_obj[0]->name.emplace("hello");
- mojo_obj[0]->rects.emplace(3);
-
- std::vector<NamedRegionPtr> stl_obj = UnwrapToSTLType(std::move(mojo_obj));
-
- ASSERT_EQ(1u, stl_obj.size());
- ASSERT_EQ("hello", stl_obj[0]->name.value());
- ASSERT_EQ(3u, stl_obj[0]->rects->size());
-
- Array<NamedRegionPtr> mojo_obj2 = WrapSTLType(std::move(stl_obj));
-
- ASSERT_EQ(1u, mojo_obj2.size());
- ASSERT_EQ("hello", mojo_obj2[0]->name.value());
- ASSERT_EQ(3u, mojo_obj2[0]->rects->size());
-}
-
-} // namespace test
-} // namespace mojo
diff --git a/mojo/public/cpp/bindings/tests/string_unittest.cc b/mojo/public/cpp/bindings/tests/string_unittest.cc
deleted file mode 100644
index 13486ae..0000000
--- a/mojo/public/cpp/bindings/tests/string_unittest.cc
+++ /dev/null
@@ -1,131 +0,0 @@
-// Copyright 2014 The Chromium 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 "mojo/public/cpp/bindings/string.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace mojo {
-namespace test {
-
-namespace {
-const char* kHelloWorld = "hello world";
-} // namespace
-
-TEST(StringTest, DefaultIsNotNull) {
- String s;
- EXPECT_FALSE(s.is_null());
-}
-
-TEST(StringTest, ConstructedWithNULL) {
- String s(nullptr);
- EXPECT_TRUE(s.is_null());
-}
-
-TEST(StringTest, ConstructedWithNullCharPointer) {
- const char* null = nullptr;
- String s(null);
- EXPECT_TRUE(s.is_null());
-}
-
-TEST(StringTest, AssignedNULL) {
- String s("");
- EXPECT_FALSE(s.is_null());
- s = nullptr;
- EXPECT_TRUE(s.is_null());
-}
-
-TEST(StringTest, Empty) {
- String s("");
- EXPECT_FALSE(s.is_null());
- EXPECT_TRUE(s.get().empty());
-}
-
-TEST(StringTest, Basic) {
- String s(kHelloWorld);
- EXPECT_EQ(std::string(kHelloWorld), s.get());
-}
-
-TEST(StringTest, Assignment) {
- String s(kHelloWorld);
- String t = s; // Makes a copy.
- EXPECT_FALSE(t.is_null());
- EXPECT_EQ(std::string(kHelloWorld), t.get());
- EXPECT_FALSE(s.is_null());
-}
-
-TEST(StringTest, Equality) {
- String s(kHelloWorld);
- String t(kHelloWorld);
- EXPECT_EQ(s, t);
- EXPECT_TRUE(s == s);
- EXPECT_FALSE(s != s);
- EXPECT_TRUE(s == t);
- EXPECT_FALSE(s != t);
- EXPECT_TRUE(kHelloWorld == s);
- EXPECT_TRUE(s == kHelloWorld);
- EXPECT_TRUE("not" != s);
- EXPECT_FALSE("not" == s);
- EXPECT_TRUE(s != "not");
- EXPECT_FALSE(s == "not");
-
- // Test null strings.
- String n1;
- String n2;
- EXPECT_TRUE(n1 == n1);
- EXPECT_FALSE(n1 != n2);
- EXPECT_TRUE(n1 == n2);
- EXPECT_FALSE(n1 != n2);
- EXPECT_TRUE(n1 != s);
- EXPECT_FALSE(n1 == s);
- EXPECT_TRUE(s != n1);
- EXPECT_FALSE(s == n1);
-}
-
-TEST(StringTest, LessThanNullness) {
- String null;
- String null2;
- EXPECT_FALSE(null < null2);
- EXPECT_FALSE(null2 < null);
-
- String real("real");
- EXPECT_TRUE(null < real);
- EXPECT_FALSE(real < null);
-}
-
-TEST(StringTest, MoveConstructors) {
- std::string std_str(kHelloWorld);
-
- String str1(std::move(std_str));
- EXPECT_TRUE(kHelloWorld == str1);
-
- String str2(std::move(str1));
- EXPECT_TRUE(kHelloWorld == str2);
- EXPECT_TRUE(str1.is_null());
-}
-
-TEST(StringTest, MoveAssignments) {
- std::string std_str(kHelloWorld);
-
- String str1;
- str1 = std::move(std_str);
- EXPECT_TRUE(kHelloWorld == str1);
-
- String str2;
- str2 = std::move(str1);
- EXPECT_TRUE(kHelloWorld == str2);
- EXPECT_TRUE(str1.is_null());
-}
-
-TEST(StringTest, Storage) {
- String str(kHelloWorld);
-
- EXPECT_TRUE(kHelloWorld == str.storage());
-
- std::string storage = str.PassStorage();
- EXPECT_TRUE(str.is_null());
- EXPECT_TRUE(kHelloWorld == storage);
-}
-
-} // namespace test
-} // namespace mojo
diff --git a/mojo/public/cpp/bindings/tests/struct_traits_unittest.cc b/mojo/public/cpp/bindings/tests/struct_traits_unittest.cc
index 583dc46..4c06267 100644
--- a/mojo/public/cpp/bindings/tests/struct_traits_unittest.cc
+++ b/mojo/public/cpp/bindings/tests/struct_traits_unittest.cc
@@ -5,6 +5,7 @@
#include "base/bind.h"
#include "base/callback.h"
#include "base/logging.h"
+#include "base/memory/ptr_util.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "mojo/public/cpp/bindings/binding_set.h"
@@ -70,6 +71,11 @@ class ChromiumRectServiceImpl : public RectService {
callback.Run(largest_rect_);
}
+ void PassSharedRect(const SharedRect& r,
+ const PassSharedRectCallback& callback) override {
+ callback.Run(r);
+ }
+
private:
RectChromium largest_rect_;
};
@@ -93,6 +99,11 @@ class BlinkRectServiceImpl : public blink::RectService {
callback.Run(largest_rect_);
}
+ void PassSharedRect(const SharedRect& r,
+ const PassSharedRectCallback& callback) override {
+ callback.Run(r);
+ }
+
private:
RectBlink largest_rect_;
};
@@ -134,9 +145,21 @@ class StructTraitsTest : public testing::Test,
callback.Run(s);
}
- void EchoPassByValueStructWithTraits(
- PassByValueStructWithTraitsImpl s,
- const EchoPassByValueStructWithTraitsCallback& callback) override {
+ void EchoTrivialStructWithTraits(
+ TrivialStructWithTraitsImpl s,
+ const EchoTrivialStructWithTraitsCallback& callback) override {
+ callback.Run(s);
+ }
+
+ void EchoMoveOnlyStructWithTraits(
+ MoveOnlyStructWithTraitsImpl s,
+ const EchoMoveOnlyStructWithTraitsCallback& callback) override {
+ callback.Run(std::move(s));
+ }
+
+ void EchoNullableMoveOnlyStructWithTraits(
+ base::Optional<MoveOnlyStructWithTraitsImpl> s,
+ const EchoNullableMoveOnlyStructWithTraitsCallback& callback) override {
callback.Run(std::move(s));
}
@@ -145,12 +168,25 @@ class StructTraitsTest : public testing::Test,
callback.Run(e);
}
- void EchoStructWithTraitsForUniquePtrTest(
+ void EchoStructWithTraitsForUniquePtr(
std::unique_ptr<int> e,
- const EchoStructWithTraitsForUniquePtrTestCallback& callback) override {
+ const EchoStructWithTraitsForUniquePtrCallback& callback) override {
callback.Run(std::move(e));
}
+ void EchoNullableStructWithTraitsForUniquePtr(
+ std::unique_ptr<int> e,
+ const EchoNullableStructWithTraitsForUniquePtrCallback& callback)
+ override {
+ callback.Run(std::move(e));
+ }
+
+ void EchoUnionWithTraits(
+ std::unique_ptr<test::UnionWithTraitsBase> u,
+ const EchoUnionWithTraitsCallback& callback) override {
+ callback.Run(std::move(u));
+ }
+
base::MessageLoop loop_;
ChromiumRectServiceImpl chromium_service_;
@@ -166,7 +202,7 @@ class StructTraitsTest : public testing::Test,
TEST_F(StructTraitsTest, ChromiumProxyToChromiumService) {
RectServicePtr chromium_proxy;
- BindToChromiumService(GetProxy(&chromium_proxy));
+ BindToChromiumService(MakeRequest(&chromium_proxy));
{
base::RunLoop loop;
chromium_proxy->AddRect(RectChromium(1, 1, 4, 5));
@@ -175,11 +211,18 @@ TEST_F(StructTraitsTest, ChromiumProxyToChromiumService) {
ExpectResult(RectChromium(1, 1, 4, 5), loop.QuitClosure()));
loop.Run();
}
+ {
+ base::RunLoop loop;
+ chromium_proxy->PassSharedRect(
+ {1, 2, 3, 4},
+ ExpectResult(SharedRect({1, 2, 3, 4}), loop.QuitClosure()));
+ loop.Run();
+ }
}
TEST_F(StructTraitsTest, ChromiumToBlinkService) {
RectServicePtr chromium_proxy;
- BindToBlinkService(GetProxy(&chromium_proxy));
+ BindToBlinkService(MakeRequest(&chromium_proxy));
{
base::RunLoop loop;
chromium_proxy->AddRect(RectChromium(1, 1, 4, 5));
@@ -188,6 +231,13 @@ TEST_F(StructTraitsTest, ChromiumToBlinkService) {
ExpectResult(RectChromium(2, 2, 5, 5), loop.QuitClosure()));
loop.Run();
}
+ {
+ base::RunLoop loop;
+ chromium_proxy->PassSharedRect(
+ {1, 2, 3, 4},
+ ExpectResult(SharedRect({1, 2, 3, 4}), loop.QuitClosure()));
+ loop.Run();
+ }
// The Blink service should drop our connection because RectBlink's
// deserializer rejects negative origins.
{
@@ -202,7 +252,7 @@ TEST_F(StructTraitsTest, ChromiumToBlinkService) {
TEST_F(StructTraitsTest, BlinkProxyToBlinkService) {
blink::RectServicePtr blink_proxy;
- BindToBlinkService(GetProxy(&blink_proxy));
+ BindToBlinkService(MakeRequest(&blink_proxy));
{
base::RunLoop loop;
blink_proxy->AddRect(RectBlink(1, 1, 4, 5));
@@ -211,11 +261,18 @@ TEST_F(StructTraitsTest, BlinkProxyToBlinkService) {
ExpectResult(RectBlink(10, 10, 20, 20), loop.QuitClosure()));
loop.Run();
}
+ {
+ base::RunLoop loop;
+ blink_proxy->PassSharedRect(
+ {4, 3, 2, 1},
+ ExpectResult(SharedRect({4, 3, 2, 1}), loop.QuitClosure()));
+ loop.Run();
+ }
}
TEST_F(StructTraitsTest, BlinkProxyToChromiumService) {
blink::RectServicePtr blink_proxy;
- BindToChromiumService(GetProxy(&blink_proxy));
+ BindToChromiumService(MakeRequest(&blink_proxy));
{
base::RunLoop loop;
blink_proxy->AddRect(RectBlink(1, 1, 4, 5));
@@ -224,6 +281,13 @@ TEST_F(StructTraitsTest, BlinkProxyToChromiumService) {
ExpectResult(RectBlink(1, 1, 4, 5), loop.QuitClosure()));
loop.Run();
}
+ {
+ base::RunLoop loop;
+ blink_proxy->PassSharedRect(
+ {4, 3, 2, 1},
+ ExpectResult(SharedRect({4, 3, 2, 1}), loop.QuitClosure()));
+ loop.Run();
+ }
}
void ExpectStructWithTraits(const StructWithTraitsImpl& expected,
@@ -249,6 +313,8 @@ TEST_F(StructTraitsTest, EchoStructWithTraits) {
input.set_uint64(42);
input.set_string("hello world!");
input.get_mutable_string_array().assign({"hello", "world!"});
+ input.get_mutable_string_set().insert("hello");
+ input.get_mutable_string_set().insert("world!");
input.get_mutable_struct().value = 42;
input.get_mutable_struct_array().resize(2);
input.get_mutable_struct_array()[0].value = 1;
@@ -274,24 +340,44 @@ TEST_F(StructTraitsTest, CloneStructWithTraitsContainer) {
EXPECT_EQ(42u, cloned_container->f_struct.get_uint64());
}
+void ExpectTrivialStructWithTraits(TrivialStructWithTraitsImpl expected,
+ const base::Closure& closure,
+ TrivialStructWithTraitsImpl passed) {
+ EXPECT_EQ(expected.value, passed.value);
+ closure.Run();
+}
+
+TEST_F(StructTraitsTest, EchoTrivialStructWithTraits) {
+ TrivialStructWithTraitsImpl input;
+ input.value = 42;
+
+ base::RunLoop loop;
+ TraitsTestServicePtr proxy = GetTraitsTestProxy();
+
+ proxy->EchoTrivialStructWithTraits(
+ input,
+ base::Bind(&ExpectTrivialStructWithTraits, input, loop.QuitClosure()));
+ loop.Run();
+}
+
void CaptureMessagePipe(ScopedMessagePipeHandle* storage,
const base::Closure& closure,
- PassByValueStructWithTraitsImpl passed) {
+ MoveOnlyStructWithTraitsImpl passed) {
storage->reset(MessagePipeHandle(
passed.get_mutable_handle().release().value()));
closure.Run();
}
-TEST_F(StructTraitsTest, EchoPassByValueStructWithTraits) {
+TEST_F(StructTraitsTest, EchoMoveOnlyStructWithTraits) {
MessagePipe mp;
- PassByValueStructWithTraitsImpl input;
+ MoveOnlyStructWithTraitsImpl input;
input.get_mutable_handle().reset(mp.handle0.release());
base::RunLoop loop;
TraitsTestServicePtr proxy = GetTraitsTestProxy();
ScopedMessagePipeHandle received;
- proxy->EchoPassByValueStructWithTraits(
+ proxy->EchoMoveOnlyStructWithTraits(
std::move(input),
base::Bind(&CaptureMessagePipe, &received, loop.QuitClosure()));
loop.Run();
@@ -317,6 +403,27 @@ TEST_F(StructTraitsTest, EchoPassByValueStructWithTraits) {
EXPECT_STREQ(kHello, buffer);
}
+void CaptureNullableMoveOnlyStructWithTraitsImpl(
+ base::Optional<MoveOnlyStructWithTraitsImpl>* storage,
+ const base::Closure& closure,
+ base::Optional<MoveOnlyStructWithTraitsImpl> passed) {
+ *storage = std::move(passed);
+ closure.Run();
+}
+
+TEST_F(StructTraitsTest, EchoNullableMoveOnlyStructWithTraits) {
+ base::RunLoop loop;
+ TraitsTestServicePtr proxy = GetTraitsTestProxy();
+
+ base::Optional<MoveOnlyStructWithTraitsImpl> received;
+ proxy->EchoNullableMoveOnlyStructWithTraits(
+ base::nullopt, base::Bind(&CaptureNullableMoveOnlyStructWithTraitsImpl,
+ &received, loop.QuitClosure()));
+ loop.Run();
+
+ EXPECT_FALSE(received);
+}
+
void ExpectEnumWithTraits(EnumWithTraitsImpl expected_value,
const base::Closure& closure,
EnumWithTraitsImpl value) {
@@ -342,7 +449,9 @@ TEST_F(StructTraitsTest, SerializeStructWithTraits) {
input.set_uint32(7);
input.set_uint64(42);
input.set_string("hello world!");
- input.get_mutable_string_array().assign({"hello", "world!"});
+ input.get_mutable_string_array().assign({ "hello", "world!" });
+ input.get_mutable_string_set().insert("hello");
+ input.get_mutable_string_set().insert("world!");
input.get_mutable_struct().value = 42;
input.get_mutable_struct_array().resize(2);
input.get_mutable_struct_array()[0].value = 1;
@@ -350,7 +459,7 @@ TEST_F(StructTraitsTest, SerializeStructWithTraits) {
input.get_mutable_struct_map()["hello"] = NestedStructWithTraitsImpl(1024);
input.get_mutable_struct_map()["world"] = NestedStructWithTraitsImpl(2048);
- mojo::Array<uint8_t> data = StructWithTraits::Serialize(&input);
+ auto data = StructWithTraits::Serialize(&input);
StructWithTraitsImpl output;
ASSERT_TRUE(StructWithTraits::Deserialize(std::move(data), &output));
@@ -360,26 +469,84 @@ TEST_F(StructTraitsTest, SerializeStructWithTraits) {
EXPECT_EQ(input.get_uint64(), output.get_uint64());
EXPECT_EQ(input.get_string(), output.get_string());
EXPECT_EQ(input.get_string_array(), output.get_string_array());
+ EXPECT_EQ(input.get_string_set(), output.get_string_set());
EXPECT_EQ(input.get_struct(), output.get_struct());
EXPECT_EQ(input.get_struct_array(), output.get_struct_array());
EXPECT_EQ(input.get_struct_map(), output.get_struct_map());
}
-void ExpectUniquePtr(int expected,
+void ExpectUniquePtr(std::unique_ptr<int> expected,
const base::Closure& closure,
std::unique_ptr<int> value) {
- EXPECT_EQ(expected, *value);
+ ASSERT_EQ(!expected, !value);
+ if (expected)
+ EXPECT_EQ(*expected, *value);
closure.Run();
}
TEST_F(StructTraitsTest, TypemapUniquePtr) {
- base::RunLoop loop;
TraitsTestServicePtr proxy = GetTraitsTestProxy();
- proxy->EchoStructWithTraitsForUniquePtrTest(
- base::MakeUnique<int>(12345),
- base::Bind(&ExpectUniquePtr, 12345, loop.QuitClosure()));
- loop.Run();
+ {
+ base::RunLoop loop;
+ proxy->EchoStructWithTraitsForUniquePtr(
+ base::MakeUnique<int>(12345),
+ base::Bind(&ExpectUniquePtr, base::Passed(base::MakeUnique<int>(12345)),
+ loop.QuitClosure()));
+ loop.Run();
+ }
+ {
+ base::RunLoop loop;
+ proxy->EchoNullableStructWithTraitsForUniquePtr(
+ nullptr, base::Bind(&ExpectUniquePtr, nullptr, loop.QuitClosure()));
+ loop.Run();
+ }
+}
+
+TEST_F(StructTraitsTest, EchoUnionWithTraits) {
+ TraitsTestServicePtr proxy = GetTraitsTestProxy();
+
+ {
+ std::unique_ptr<test::UnionWithTraitsBase> input(
+ new test::UnionWithTraitsInt32(1234));
+ base::RunLoop loop;
+ proxy->EchoUnionWithTraits(
+ std::move(input),
+ base::Bind(
+ [](const base::Closure& quit_closure,
+ std::unique_ptr<test::UnionWithTraitsBase> passed) {
+ ASSERT_EQ(test::UnionWithTraitsBase::Type::INT32, passed->type());
+ EXPECT_EQ(1234,
+ static_cast<test::UnionWithTraitsInt32*>(passed.get())
+ ->value());
+ quit_closure.Run();
+
+ },
+ loop.QuitClosure()));
+ loop.Run();
+ }
+
+ {
+ std::unique_ptr<test::UnionWithTraitsBase> input(
+ new test::UnionWithTraitsStruct(4321));
+ base::RunLoop loop;
+ proxy->EchoUnionWithTraits(
+ std::move(input),
+ base::Bind(
+ [](const base::Closure& quit_closure,
+ std::unique_ptr<test::UnionWithTraitsBase> passed) {
+ ASSERT_EQ(test::UnionWithTraitsBase::Type::STRUCT,
+ passed->type());
+ EXPECT_EQ(4321,
+ static_cast<test::UnionWithTraitsStruct*>(passed.get())
+ ->get_struct()
+ .value);
+ quit_closure.Run();
+
+ },
+ loop.QuitClosure()));
+ loop.Run();
+ }
}
} // namespace test
diff --git a/mojo/public/cpp/bindings/tests/struct_unittest.cc b/mojo/public/cpp/bindings/tests/struct_unittest.cc
index 76b4cce..13ba507 100644
--- a/mojo/public/cpp/bindings/tests/struct_unittest.cc
+++ b/mojo/public/cpp/bindings/tests/struct_unittest.cc
@@ -17,12 +17,7 @@ namespace test {
namespace {
RectPtr MakeRect(int32_t factor = 1) {
- RectPtr rect(Rect::New());
- rect->x = 1 * factor;
- rect->y = 2 * factor;
- rect->width = 10 * factor;
- rect->height = 20 * factor;
- return rect;
+ return Rect::New(1 * factor, 2 * factor, 10 * factor, 20 * factor);
}
void CheckRect(const Rect& rect, int32_t factor = 1) {
@@ -33,31 +28,28 @@ void CheckRect(const Rect& rect, int32_t factor = 1) {
}
MultiVersionStructPtr MakeMultiVersionStruct() {
- MultiVersionStructPtr output(MultiVersionStruct::New());
- output->f_int32 = 123;
- output->f_rect = MakeRect(5);
- output->f_string.emplace("hello");
- output->f_array.emplace(3);
- (*output->f_array)[0] = 10;
- (*output->f_array)[1] = 9;
- (*output->f_array)[2] = 8;
MessagePipe pipe;
- output->f_message_pipe = std::move(pipe.handle0);
- output->f_int16 = 42;
-
- return output;
+ return MultiVersionStruct::New(123, MakeRect(5), std::string("hello"),
+ std::vector<int8_t>{10, 9, 8},
+ std::move(pipe.handle0), false, 42);
}
template <typename U, typename T>
U SerializeAndDeserialize(T input) {
- using InputDataType = typename mojo::internal::MojomTypeTraits<T>::Data*;
- using OutputDataType = typename mojo::internal::MojomTypeTraits<U>::Data*;
+ using InputMojomType = typename T::Struct::DataView;
+ using OutputMojomType = typename U::Struct::DataView;
+
+ using InputDataType =
+ typename mojo::internal::MojomTypeTraits<InputMojomType>::Data*;
+ using OutputDataType =
+ typename mojo::internal::MojomTypeTraits<OutputMojomType>::Data*;
mojo::internal::SerializationContext context;
- size_t size = mojo::internal::PrepareToSerialize<T>(input, &context);
+ size_t size =
+ mojo::internal::PrepareToSerialize<InputMojomType>(input, &context);
mojo::internal::FixedBufferForTesting buf(size + 32);
InputDataType data;
- mojo::internal::Serialize<T>(input, &buf, &data, &context);
+ mojo::internal::Serialize<InputMojomType>(input, &buf, &data, &context);
// Set the subsequent area to a special value, so that we can find out if we
// mistakenly access the area.
@@ -67,7 +59,7 @@ U SerializeAndDeserialize(T input) {
OutputDataType output_data = reinterpret_cast<OutputDataType>(data);
U output;
- mojo::internal::Deserialize<U>(output_data, &output, &context);
+ mojo::internal::Deserialize<OutputMojomType>(output_data, &output, &context);
return std::move(output);
}
@@ -131,15 +123,15 @@ TEST_F(StructTest, Clone) {
TEST_F(StructTest, Serialization_Basic) {
RectPtr rect(MakeRect());
- size_t size = mojo::internal::PrepareToSerialize<RectPtr>(rect, nullptr);
+ size_t size = mojo::internal::PrepareToSerialize<RectDataView>(rect, nullptr);
EXPECT_EQ(8U + 16U, size);
mojo::internal::FixedBufferForTesting buf(size);
internal::Rect_Data* data;
- mojo::internal::Serialize<RectPtr>(rect, &buf, &data, nullptr);
+ mojo::internal::Serialize<RectDataView>(rect, &buf, &data, nullptr);
RectPtr rect2;
- mojo::internal::Deserialize<RectPtr>(data, &rect2, nullptr);
+ mojo::internal::Deserialize<RectDataView>(data, &rect2, nullptr);
CheckRect(*rect2);
}
@@ -160,19 +152,18 @@ TEST_F(StructTest, Construction_StructPointers) {
// Serialization test of a struct with struct pointers.
TEST_F(StructTest, Serialization_StructPointers) {
- RectPairPtr pair(RectPair::New());
- pair->first = MakeRect();
- pair->second = MakeRect();
+ RectPairPtr pair(RectPair::New(MakeRect(), MakeRect()));
- size_t size = mojo::internal::PrepareToSerialize<RectPairPtr>(pair, nullptr);
+ size_t size =
+ mojo::internal::PrepareToSerialize<RectPairDataView>(pair, nullptr);
EXPECT_EQ(8U + 16U + 2 * (8U + 16U), size);
mojo::internal::FixedBufferForTesting buf(size);
internal::RectPair_Data* data;
- mojo::internal::Serialize<RectPairPtr>(pair, &buf, &data, nullptr);
+ mojo::internal::Serialize<RectPairDataView>(pair, &buf, &data, nullptr);
RectPairPtr pair2;
- mojo::internal::Deserialize<RectPairPtr>(data, &pair2, nullptr);
+ mojo::internal::Deserialize<RectPairDataView>(data, &pair2, nullptr);
CheckRect(*pair2->first);
CheckRect(*pair2->second);
@@ -180,14 +171,15 @@ TEST_F(StructTest, Serialization_StructPointers) {
// Serialization test of a struct with an array member.
TEST_F(StructTest, Serialization_ArrayPointers) {
- NamedRegionPtr region(NamedRegion::New());
- region->name.emplace("region");
- region->rects.emplace(4);
- for (size_t i = 0; i < region->rects->size(); ++i)
- (*region->rects)[i] = MakeRect(static_cast<int32_t>(i) + 1);
+ std::vector<RectPtr> rects;
+ for (size_t i = 0; i < 4; ++i)
+ rects.push_back(MakeRect(static_cast<int32_t>(i) + 1));
+
+ NamedRegionPtr region(
+ NamedRegion::New(std::string("region"), std::move(rects)));
size_t size =
- mojo::internal::PrepareToSerialize<NamedRegionPtr>(region, nullptr);
+ mojo::internal::PrepareToSerialize<NamedRegionDataView>(region, nullptr);
EXPECT_EQ(8U + // header
8U + // name pointer
8U + // rects pointer
@@ -201,10 +193,10 @@ TEST_F(StructTest, Serialization_ArrayPointers) {
mojo::internal::FixedBufferForTesting buf(size);
internal::NamedRegion_Data* data;
- mojo::internal::Serialize<NamedRegionPtr>(region, &buf, &data, nullptr);
+ mojo::internal::Serialize<NamedRegionDataView>(region, &buf, &data, nullptr);
NamedRegionPtr region2;
- mojo::internal::Deserialize<NamedRegionPtr>(data, &region2, nullptr);
+ mojo::internal::Deserialize<NamedRegionDataView>(data, &region2, nullptr);
EXPECT_EQ("region", *region2->name);
@@ -220,7 +212,7 @@ TEST_F(StructTest, Serialization_NullArrayPointers) {
EXPECT_FALSE(region->rects);
size_t size =
- mojo::internal::PrepareToSerialize<NamedRegionPtr>(region, nullptr);
+ mojo::internal::PrepareToSerialize<NamedRegionDataView>(region, nullptr);
EXPECT_EQ(8U + // header
8U + // name pointer
8U, // rects pointer
@@ -228,10 +220,10 @@ TEST_F(StructTest, Serialization_NullArrayPointers) {
mojo::internal::FixedBufferForTesting buf(size);
internal::NamedRegion_Data* data;
- mojo::internal::Serialize<NamedRegionPtr>(region, &buf, &data, nullptr);
+ mojo::internal::Serialize<NamedRegionDataView>(region, &buf, &data, nullptr);
NamedRegionPtr region2;
- mojo::internal::Deserialize<NamedRegionPtr>(data, &region2, nullptr);
+ mojo::internal::Deserialize<NamedRegionDataView>(data, &region2, nullptr);
EXPECT_FALSE(region2->name);
EXPECT_FALSE(region2->rects);
@@ -240,10 +232,8 @@ TEST_F(StructTest, Serialization_NullArrayPointers) {
// Tests deserializing structs as a newer version.
TEST_F(StructTest, Versioning_OldToNew) {
{
- MultiVersionStructV0Ptr input(MultiVersionStructV0::New());
- input->f_int32 = 123;
- MultiVersionStructPtr expected_output(MultiVersionStruct::New());
- expected_output->f_int32 = 123;
+ MultiVersionStructV0Ptr input(MultiVersionStructV0::New(123));
+ MultiVersionStructPtr expected_output(MultiVersionStruct::New(123));
MultiVersionStructPtr output =
SerializeAndDeserialize<MultiVersionStructPtr>(std::move(input));
@@ -252,12 +242,9 @@ TEST_F(StructTest, Versioning_OldToNew) {
}
{
- MultiVersionStructV1Ptr input(MultiVersionStructV1::New());
- input->f_int32 = 123;
- input->f_rect = MakeRect(5);
- MultiVersionStructPtr expected_output(MultiVersionStruct::New());
- expected_output->f_int32 = 123;
- expected_output->f_rect = MakeRect(5);
+ MultiVersionStructV1Ptr input(MultiVersionStructV1::New(123, MakeRect(5)));
+ MultiVersionStructPtr expected_output(
+ MultiVersionStruct::New(123, MakeRect(5)));
MultiVersionStructPtr output =
SerializeAndDeserialize<MultiVersionStructPtr>(std::move(input));
@@ -266,14 +253,10 @@ TEST_F(StructTest, Versioning_OldToNew) {
}
{
- MultiVersionStructV3Ptr input(MultiVersionStructV3::New());
- input->f_int32 = 123;
- input->f_rect = MakeRect(5);
- input->f_string.emplace("hello");
- MultiVersionStructPtr expected_output(MultiVersionStruct::New());
- expected_output->f_int32 = 123;
- expected_output->f_rect = MakeRect(5);
- expected_output->f_string.emplace("hello");
+ MultiVersionStructV3Ptr input(
+ MultiVersionStructV3::New(123, MakeRect(5), std::string("hello")));
+ MultiVersionStructPtr expected_output(
+ MultiVersionStruct::New(123, MakeRect(5), std::string("hello")));
MultiVersionStructPtr output =
SerializeAndDeserialize<MultiVersionStructPtr>(std::move(input));
@@ -282,22 +265,10 @@ TEST_F(StructTest, Versioning_OldToNew) {
}
{
- MultiVersionStructV5Ptr input(MultiVersionStructV5::New());
- input->f_int32 = 123;
- input->f_rect = MakeRect(5);
- input->f_string.emplace("hello");
- input->f_array.emplace(3);
- (*input->f_array)[0] = 10;
- (*input->f_array)[1] = 9;
- (*input->f_array)[2] = 8;
- MultiVersionStructPtr expected_output(MultiVersionStruct::New());
- expected_output->f_int32 = 123;
- expected_output->f_rect = MakeRect(5);
- expected_output->f_string.emplace("hello");
- expected_output->f_array.emplace(3);
- (*expected_output->f_array)[0] = 10;
- (*expected_output->f_array)[1] = 9;
- (*expected_output->f_array)[2] = 8;
+ MultiVersionStructV5Ptr input(MultiVersionStructV5::New(
+ 123, MakeRect(5), std::string("hello"), std::vector<int8_t>{10, 9, 8}));
+ MultiVersionStructPtr expected_output(MultiVersionStruct::New(
+ 123, MakeRect(5), std::string("hello"), std::vector<int8_t>{10, 9, 8}));
MultiVersionStructPtr output =
SerializeAndDeserialize<MultiVersionStructPtr>(std::move(input));
@@ -306,25 +277,13 @@ TEST_F(StructTest, Versioning_OldToNew) {
}
{
- MultiVersionStructV7Ptr input(MultiVersionStructV7::New());
- input->f_int32 = 123;
- input->f_rect = MakeRect(5);
- input->f_string.emplace("hello");
- input->f_array.emplace(3);
- (*input->f_array)[0] = 10;
- (*input->f_array)[1] = 9;
- (*input->f_array)[2] = 8;
MessagePipe pipe;
- input->f_message_pipe = std::move(pipe.handle0);
-
- MultiVersionStructPtr expected_output(MultiVersionStruct::New());
- expected_output->f_int32 = 123;
- expected_output->f_rect = MakeRect(5);
- expected_output->f_string.emplace("hello");
- expected_output->f_array.emplace(3);
- (*expected_output->f_array)[0] = 10;
- (*expected_output->f_array)[1] = 9;
- (*expected_output->f_array)[2] = 8;
+ MultiVersionStructV7Ptr input(MultiVersionStructV7::New(
+ 123, MakeRect(5), std::string("hello"), std::vector<int8_t>{10, 9, 8},
+ std::move(pipe.handle0), false));
+
+ MultiVersionStructPtr expected_output(MultiVersionStruct::New(
+ 123, MakeRect(5), std::string("hello"), std::vector<int8_t>{10, 9, 8}));
// Save the raw handle value separately so that we can compare later.
MojoHandle expected_handle = input->f_message_pipe.get().value();
@@ -341,14 +300,8 @@ TEST_F(StructTest, Versioning_OldToNew) {
TEST_F(StructTest, Versioning_NewToOld) {
{
MultiVersionStructPtr input = MakeMultiVersionStruct();
- MultiVersionStructV7Ptr expected_output(MultiVersionStructV7::New());
- expected_output->f_int32 = 123;
- expected_output->f_rect = MakeRect(5);
- expected_output->f_string.emplace("hello");
- expected_output->f_array.emplace(3);
- (*expected_output->f_array)[0] = 10;
- (*expected_output->f_array)[1] = 9;
- (*expected_output->f_array)[2] = 8;
+ MultiVersionStructV7Ptr expected_output(MultiVersionStructV7::New(
+ 123, MakeRect(5), std::string("hello"), std::vector<int8_t>{10, 9, 8}));
// Save the raw handle value separately so that we can compare later.
MojoHandle expected_handle = input->f_message_pipe.get().value();
@@ -362,14 +315,8 @@ TEST_F(StructTest, Versioning_NewToOld) {
{
MultiVersionStructPtr input = MakeMultiVersionStruct();
- MultiVersionStructV5Ptr expected_output(MultiVersionStructV5::New());
- expected_output->f_int32 = 123;
- expected_output->f_rect = MakeRect(5);
- expected_output->f_string.emplace("hello");
- expected_output->f_array.emplace(3);
- (*expected_output->f_array)[0] = 10;
- (*expected_output->f_array)[1] = 9;
- (*expected_output->f_array)[2] = 8;
+ MultiVersionStructV5Ptr expected_output(MultiVersionStructV5::New(
+ 123, MakeRect(5), std::string("hello"), std::vector<int8_t>{10, 9, 8}));
MultiVersionStructV5Ptr output =
SerializeAndDeserialize<MultiVersionStructV5Ptr>(std::move(input));
@@ -379,10 +326,8 @@ TEST_F(StructTest, Versioning_NewToOld) {
{
MultiVersionStructPtr input = MakeMultiVersionStruct();
- MultiVersionStructV3Ptr expected_output(MultiVersionStructV3::New());
- expected_output->f_int32 = 123;
- expected_output->f_rect = MakeRect(5);
- expected_output->f_string.emplace("hello");
+ MultiVersionStructV3Ptr expected_output(
+ MultiVersionStructV3::New(123, MakeRect(5), std::string("hello")));
MultiVersionStructV3Ptr output =
SerializeAndDeserialize<MultiVersionStructV3Ptr>(std::move(input));
@@ -392,9 +337,8 @@ TEST_F(StructTest, Versioning_NewToOld) {
{
MultiVersionStructPtr input = MakeMultiVersionStruct();
- MultiVersionStructV1Ptr expected_output(MultiVersionStructV1::New());
- expected_output->f_int32 = 123;
- expected_output->f_rect = MakeRect(5);
+ MultiVersionStructV1Ptr expected_output(
+ MultiVersionStructV1::New(123, MakeRect(5)));
MultiVersionStructV1Ptr output =
SerializeAndDeserialize<MultiVersionStructV1Ptr>(std::move(input));
@@ -404,8 +348,7 @@ TEST_F(StructTest, Versioning_NewToOld) {
{
MultiVersionStructPtr input = MakeMultiVersionStruct();
- MultiVersionStructV0Ptr expected_output(MultiVersionStructV0::New());
- expected_output->f_int32 = 123;
+ MultiVersionStructV0Ptr expected_output(MultiVersionStructV0::New(123));
MultiVersionStructV0Ptr output =
SerializeAndDeserialize<MultiVersionStructV0Ptr>(std::move(input));
@@ -420,65 +363,66 @@ TEST_F(StructTest, Serialization_NativeStruct) {
{
// Serialization of a null native struct.
NativeStructPtr native;
- size_t size =
- mojo::internal::PrepareToSerialize<NativeStructPtr>(native, nullptr);
+ size_t size = mojo::internal::PrepareToSerialize<NativeStructDataView>(
+ native, nullptr);
EXPECT_EQ(0u, size);
mojo::internal::FixedBufferForTesting buf(size);
Data* data = nullptr;
- mojo::internal::Serialize<NativeStructPtr>(std::move(native), &buf, &data,
- nullptr);
+ mojo::internal::Serialize<NativeStructDataView>(std::move(native), &buf,
+ &data, nullptr);
EXPECT_EQ(nullptr, data);
NativeStructPtr output_native;
- mojo::internal::Deserialize<NativeStructPtr>(data, &output_native, nullptr);
+ mojo::internal::Deserialize<NativeStructDataView>(data, &output_native,
+ nullptr);
EXPECT_TRUE(output_native.is_null());
}
{
// Serialization of a native struct with null data.
NativeStructPtr native(NativeStruct::New());
- size_t size =
- mojo::internal::PrepareToSerialize<NativeStructPtr>(native, nullptr);
+ size_t size = mojo::internal::PrepareToSerialize<NativeStructDataView>(
+ native, nullptr);
EXPECT_EQ(0u, size);
mojo::internal::FixedBufferForTesting buf(size);
Data* data = nullptr;
- mojo::internal::Serialize<NativeStructPtr>(std::move(native), &buf, &data,
- nullptr);
+ mojo::internal::Serialize<NativeStructDataView>(std::move(native), &buf,
+ &data, nullptr);
EXPECT_EQ(nullptr, data);
NativeStructPtr output_native;
- mojo::internal::Deserialize<NativeStructPtr>(data, &output_native, nullptr);
+ mojo::internal::Deserialize<NativeStructDataView>(data, &output_native,
+ nullptr);
EXPECT_TRUE(output_native.is_null());
}
{
NativeStructPtr native(NativeStruct::New());
- native->data = Array<uint8_t>(2);
- native->data[0] = 'X';
- native->data[1] = 'Y';
+ native->data = std::vector<uint8_t>{'X', 'Y'};
- size_t size =
- mojo::internal::PrepareToSerialize<NativeStructPtr>(native, nullptr);
+ size_t size = mojo::internal::PrepareToSerialize<NativeStructDataView>(
+ native, nullptr);
EXPECT_EQ(16u, size);
mojo::internal::FixedBufferForTesting buf(size);
Data* data = nullptr;
- mojo::internal::Serialize<NativeStructPtr>(std::move(native), &buf, &data,
- nullptr);
+ mojo::internal::Serialize<NativeStructDataView>(std::move(native), &buf,
+ &data, nullptr);
EXPECT_NE(nullptr, data);
NativeStructPtr output_native;
- mojo::internal::Deserialize<NativeStructPtr>(data, &output_native, nullptr);
- EXPECT_FALSE(output_native.is_null());
- EXPECT_FALSE(output_native->data.is_null());
- EXPECT_EQ(2u, output_native->data.size());
- EXPECT_EQ('X', output_native->data[0]);
- EXPECT_EQ('Y', output_native->data[1]);
+ mojo::internal::Deserialize<NativeStructDataView>(data, &output_native,
+ nullptr);
+ ASSERT_TRUE(output_native);
+ ASSERT_FALSE(output_native->data->empty());
+ EXPECT_EQ(2u, output_native->data->size());
+ EXPECT_EQ('X', (*output_native->data)[0]);
+ EXPECT_EQ('Y', (*output_native->data)[1]);
}
}
@@ -486,7 +430,7 @@ TEST_F(StructTest, Serialization_PublicAPI) {
{
// A null struct pointer.
RectPtr null_struct;
- mojo::Array<uint8_t> data = Rect::Serialize(&null_struct);
+ auto data = Rect::Serialize(&null_struct);
EXPECT_TRUE(data.empty());
// Initialize it to non-null.
@@ -498,7 +442,7 @@ TEST_F(StructTest, Serialization_PublicAPI) {
{
// A struct with no fields.
EmptyStructPtr empty_struct(EmptyStruct::New());
- mojo::Array<uint8_t> data = EmptyStruct::Serialize(&empty_struct);
+ auto data = EmptyStruct::Serialize(&empty_struct);
EXPECT_FALSE(data.empty());
EmptyStructPtr output;
@@ -510,7 +454,7 @@ TEST_F(StructTest, Serialization_PublicAPI) {
// A simple struct.
RectPtr rect = MakeRect();
RectPtr cloned_rect = rect.Clone();
- mojo::Array<uint8_t> data = Rect::Serialize(&rect);
+ auto data = Rect::Serialize(&rect);
RectPtr output;
ASSERT_TRUE(Rect::Deserialize(std::move(data), &output));
@@ -519,17 +463,17 @@ TEST_F(StructTest, Serialization_PublicAPI) {
{
// A struct containing other objects.
- NamedRegionPtr region(NamedRegion::New());
- region->name.emplace("region");
- region->rects.emplace(3);
- for (size_t i = 0; i < region->rects->size(); ++i)
- (*region->rects)[i] = MakeRect(static_cast<int32_t>(i) + 1);
+ std::vector<RectPtr> rects;
+ for (size_t i = 0; i < 3; ++i)
+ rects.push_back(MakeRect(static_cast<int32_t>(i) + 1));
+ NamedRegionPtr region(
+ NamedRegion::New(std::string("region"), std::move(rects)));
NamedRegionPtr cloned_region = region.Clone();
- mojo::Array<uint8_t> data = NamedRegion::Serialize(&region);
+ auto data = NamedRegion::Serialize(&region);
// Make sure that the serialized result gets pointers encoded properly.
- mojo::Array<uint8_t> cloned_data = data.Clone();
+ auto cloned_data = data;
NamedRegionPtr output;
ASSERT_TRUE(NamedRegion::Deserialize(std::move(cloned_data), &output));
EXPECT_TRUE(output.Equals(cloned_region));
@@ -538,12 +482,34 @@ TEST_F(StructTest, Serialization_PublicAPI) {
{
// Deserialization failure.
RectPtr rect = MakeRect();
- mojo::Array<uint8_t> data = Rect::Serialize(&rect);
+ auto data = Rect::Serialize(&rect);
NamedRegionPtr output;
EXPECT_FALSE(NamedRegion::Deserialize(std::move(data), &output));
}
}
+TEST_F(StructTest, VersionedStructConstructor) {
+ auto reordered = ReorderedStruct::New(123, 456, 789);
+ EXPECT_EQ(123, reordered->a);
+ EXPECT_EQ(456, reordered->b);
+ EXPECT_EQ(789, reordered->c);
+
+ reordered = ReorderedStruct::New(123, 456);
+ EXPECT_EQ(123, reordered->a);
+ EXPECT_EQ(6, reordered->b);
+ EXPECT_EQ(456, reordered->c);
+
+ reordered = ReorderedStruct::New(123);
+ EXPECT_EQ(3, reordered->a);
+ EXPECT_EQ(6, reordered->b);
+ EXPECT_EQ(123, reordered->c);
+
+ reordered = ReorderedStruct::New();
+ EXPECT_EQ(3, reordered->a);
+ EXPECT_EQ(6, reordered->b);
+ EXPECT_EQ(1, reordered->c);
+}
+
} // namespace test
} // namespace mojo
diff --git a/mojo/public/cpp/bindings/tests/struct_with_traits.typemap b/mojo/public/cpp/bindings/tests/struct_with_traits.typemap
index da061de..752ce44 100644
--- a/mojo/public/cpp/bindings/tests/struct_with_traits.typemap
+++ b/mojo/public/cpp/bindings/tests/struct_with_traits.typemap
@@ -19,6 +19,8 @@ type_mappings = [
"mojo.test.EnumWithTraits=mojo::test::EnumWithTraitsImpl",
"mojo.test.StructWithTraits=mojo::test::StructWithTraitsImpl",
"mojo.test.NestedStructWithTraits=mojo::test::NestedStructWithTraitsImpl",
- "mojo.test.PassByValueStructWithTraits=mojo::test::PassByValueStructWithTraitsImpl[move_only]",
- "mojo.test.StructWithTraitsForUniquePtrTest=std::unique_ptr<int>[move_only]",
+ "mojo.test.TrivialStructWithTraits=mojo::test::TrivialStructWithTraitsImpl[copyable_pass_by_value]",
+ "mojo.test.MoveOnlyStructWithTraits=mojo::test::MoveOnlyStructWithTraitsImpl[move_only]",
+ "mojo.test.StructWithTraitsForUniquePtr=std::unique_ptr<int>[move_only,nullable_is_same_type]",
+ "mojo.test.UnionWithTraits=std::unique_ptr<mojo::test::UnionWithTraitsBase>[move_only,nullable_is_same_type]",
]
diff --git a/mojo/public/cpp/bindings/tests/struct_with_traits_impl.cc b/mojo/public/cpp/bindings/tests/struct_with_traits_impl.cc
index e99ec2a..cbdd4bf 100644
--- a/mojo/public/cpp/bindings/tests/struct_with_traits_impl.cc
+++ b/mojo/public/cpp/bindings/tests/struct_with_traits_impl.cc
@@ -18,12 +18,19 @@ StructWithTraitsImpl::~StructWithTraitsImpl() {}
StructWithTraitsImpl::StructWithTraitsImpl(const StructWithTraitsImpl& other) =
default;
-PassByValueStructWithTraitsImpl::PassByValueStructWithTraitsImpl() {}
+MoveOnlyStructWithTraitsImpl::MoveOnlyStructWithTraitsImpl() {}
-PassByValueStructWithTraitsImpl::PassByValueStructWithTraitsImpl(
- PassByValueStructWithTraitsImpl&& other) = default;
+MoveOnlyStructWithTraitsImpl::MoveOnlyStructWithTraitsImpl(
+ MoveOnlyStructWithTraitsImpl&& other) = default;
-PassByValueStructWithTraitsImpl::~PassByValueStructWithTraitsImpl() {}
+MoveOnlyStructWithTraitsImpl::~MoveOnlyStructWithTraitsImpl() {}
+
+MoveOnlyStructWithTraitsImpl& MoveOnlyStructWithTraitsImpl::operator=(
+ MoveOnlyStructWithTraitsImpl&& other) = default;
+
+UnionWithTraitsInt32::~UnionWithTraitsInt32() {}
+
+UnionWithTraitsStruct::~UnionWithTraitsStruct() {}
} // namespace test
} // namespace mojo
diff --git a/mojo/public/cpp/bindings/tests/struct_with_traits_impl.h b/mojo/public/cpp/bindings/tests/struct_with_traits_impl.h
index b62ba56..7b007cc 100644
--- a/mojo/public/cpp/bindings/tests/struct_with_traits_impl.h
+++ b/mojo/public/cpp/bindings/tests/struct_with_traits_impl.h
@@ -8,6 +8,7 @@
#include <stdint.h>
#include <map>
+#include <set>
#include <string>
#include <vector>
@@ -61,6 +62,11 @@ class StructWithTraitsImpl {
}
std::vector<std::string>& get_mutable_string_array() { return string_array_; }
+ const std::set<std::string>& get_string_set() const {
+ return string_set_;
+ }
+ std::set<std::string>& get_mutable_string_set() { return string_set_; }
+
const NestedStructWithTraitsImpl& get_struct() const { return struct_; }
NestedStructWithTraitsImpl& get_mutable_struct() { return struct_; }
@@ -86,24 +92,74 @@ class StructWithTraitsImpl {
uint64_t uint64_ = 0;
std::string string_;
std::vector<std::string> string_array_;
+ std::set<std::string> string_set_;
NestedStructWithTraitsImpl struct_;
std::vector<NestedStructWithTraitsImpl> struct_array_;
std::map<std::string, NestedStructWithTraitsImpl> struct_map_;
};
-// A type which knows how to look like a mojo::test::PassByValueStructWithTraits
+// A type which knows how to look like a mojo::test::TrivialStructWithTraits
+// mojom type by way of mojo::StructTraits.
+struct TrivialStructWithTraitsImpl {
+ int32_t value;
+};
+
+// A type which knows how to look like a mojo::test::MoveOnlyStructWithTraits
// mojom type by way of mojo::StructTraits.
-class PassByValueStructWithTraitsImpl {
+class MoveOnlyStructWithTraitsImpl {
public:
- PassByValueStructWithTraitsImpl();
- PassByValueStructWithTraitsImpl(PassByValueStructWithTraitsImpl&& other);
- ~PassByValueStructWithTraitsImpl();
+ MoveOnlyStructWithTraitsImpl();
+ MoveOnlyStructWithTraitsImpl(MoveOnlyStructWithTraitsImpl&& other);
+ ~MoveOnlyStructWithTraitsImpl();
ScopedHandle& get_mutable_handle() { return handle_; }
+ MoveOnlyStructWithTraitsImpl& operator=(MoveOnlyStructWithTraitsImpl&& other);
+
private:
ScopedHandle handle_;
- DISALLOW_COPY_AND_ASSIGN(PassByValueStructWithTraitsImpl);
+ DISALLOW_COPY_AND_ASSIGN(MoveOnlyStructWithTraitsImpl);
+};
+
+class UnionWithTraitsBase {
+ public:
+ enum class Type { INT32, STRUCT };
+
+ virtual ~UnionWithTraitsBase() {}
+
+ Type type() const { return type_; }
+
+ protected:
+ Type type_ = Type::INT32;
+};
+
+class UnionWithTraitsInt32 : public UnionWithTraitsBase {
+ public:
+ UnionWithTraitsInt32() {}
+ explicit UnionWithTraitsInt32(int32_t value) : value_(value) {}
+
+ ~UnionWithTraitsInt32() override;
+
+ int32_t value() const { return value_; }
+ void set_value(int32_t value) { value_ = value; }
+
+ private:
+ int32_t value_ = 0;
+};
+
+class UnionWithTraitsStruct : public UnionWithTraitsBase {
+ public:
+ UnionWithTraitsStruct() { type_ = Type::STRUCT; }
+ explicit UnionWithTraitsStruct(int32_t value) : struct_(value) {
+ type_ = Type::STRUCT;
+ }
+ ~UnionWithTraitsStruct() override;
+
+ NestedStructWithTraitsImpl& get_mutable_struct() { return struct_; }
+ const NestedStructWithTraitsImpl& get_struct() const { return struct_; }
+
+ private:
+ NestedStructWithTraitsImpl struct_;
};
} // namespace test
diff --git a/mojo/public/cpp/bindings/tests/struct_with_traits_impl_traits.cc b/mojo/public/cpp/bindings/tests/struct_with_traits_impl_traits.cc
index c11b37a..6b770b1 100644
--- a/mojo/public/cpp/bindings/tests/struct_with_traits_impl_traits.cc
+++ b/mojo/public/cpp/bindings/tests/struct_with_traits_impl_traits.cc
@@ -14,7 +14,7 @@ struct Context {
} // namespace
// static
-void* StructTraits<test::NestedStructWithTraits,
+void* StructTraits<test::NestedStructWithTraitsDataView,
test::NestedStructWithTraitsImpl>::
SetUpContext(const test::NestedStructWithTraitsImpl& input) {
Context* context = new Context;
@@ -23,7 +23,7 @@ void* StructTraits<test::NestedStructWithTraits,
}
// static
-void StructTraits<test::NestedStructWithTraits,
+void StructTraits<test::NestedStructWithTraitsDataView,
test::NestedStructWithTraitsImpl>::
TearDownContext(const test::NestedStructWithTraitsImpl& input,
void* context) {
@@ -33,7 +33,7 @@ void StructTraits<test::NestedStructWithTraits,
}
// static
-int32_t StructTraits<test::NestedStructWithTraits,
+int32_t StructTraits<test::NestedStructWithTraitsDataView,
test::NestedStructWithTraitsImpl>::
value(const test::NestedStructWithTraitsImpl& input, void* context) {
Context* context_obj = static_cast<Context*>(context);
@@ -42,7 +42,7 @@ int32_t StructTraits<test::NestedStructWithTraits,
}
// static
-bool StructTraits<test::NestedStructWithTraits,
+bool StructTraits<test::NestedStructWithTraitsDataView,
test::NestedStructWithTraitsImpl>::
Read(test::NestedStructWithTraits::DataView data,
test::NestedStructWithTraitsImpl* output) {
@@ -80,9 +80,9 @@ bool EnumTraits<test::EnumWithTraits, test::EnumWithTraitsImpl>::FromMojom(
}
// static
-bool StructTraits<test::StructWithTraits, test::StructWithTraitsImpl>::Read(
- test::StructWithTraits::DataView data,
- test::StructWithTraitsImpl* out) {
+bool StructTraits<test::StructWithTraitsDataView, test::StructWithTraitsImpl>::
+ Read(test::StructWithTraits::DataView data,
+ test::StructWithTraitsImpl* out) {
test::EnumWithTraitsImpl f_enum;
if (!data.ReadFEnum(&f_enum))
return false;
@@ -103,6 +103,16 @@ bool StructTraits<test::StructWithTraits, test::StructWithTraitsImpl>::Read(
if (!data.ReadFStringArray(&out->get_mutable_string_array()))
return false;
+ // We can't deserialize as a std::set, so we have to manually copy from the
+ // data view.
+ ArrayDataView<StringDataView> string_set_data_view;
+ data.GetFStringSetDataView(&string_set_data_view);
+ for (size_t i = 0; i < string_set_data_view.size(); ++i) {
+ std::string value;
+ string_set_data_view.Read(i, &value);
+ out->get_mutable_string_set().insert(value);
+ }
+
if (!data.ReadFStruct(&out->get_mutable_struct()))
return false;
@@ -116,10 +126,10 @@ bool StructTraits<test::StructWithTraits, test::StructWithTraitsImpl>::Read(
}
// static
-bool StructTraits<test::PassByValueStructWithTraits,
- test::PassByValueStructWithTraitsImpl>::
- Read(test::PassByValueStructWithTraits::DataView data,
- test::PassByValueStructWithTraitsImpl* out) {
+bool StructTraits<test::MoveOnlyStructWithTraitsDataView,
+ test::MoveOnlyStructWithTraitsImpl>::
+ Read(test::MoveOnlyStructWithTraits::DataView data,
+ test::MoveOnlyStructWithTraitsImpl* out) {
out->get_mutable_handle() = data.TakeFHandle();
return true;
}
diff --git a/mojo/public/cpp/bindings/tests/struct_with_traits_impl_traits.h b/mojo/public/cpp/bindings/tests/struct_with_traits_impl_traits.h
index 4550526..adcad8a 100644
--- a/mojo/public/cpp/bindings/tests/struct_with_traits_impl_traits.h
+++ b/mojo/public/cpp/bindings/tests/struct_with_traits_impl_traits.h
@@ -18,7 +18,7 @@
namespace mojo {
template <>
-struct StructTraits<test::NestedStructWithTraits,
+struct StructTraits<test::NestedStructWithTraitsDataView,
test::NestedStructWithTraitsImpl> {
static void* SetUpContext(const test::NestedStructWithTraitsImpl& input);
static void TearDownContext(const test::NestedStructWithTraitsImpl& input,
@@ -27,7 +27,7 @@ struct StructTraits<test::NestedStructWithTraits,
static int32_t value(const test::NestedStructWithTraitsImpl& input,
void* context);
- static bool Read(test::NestedStructWithTraits::DataView data,
+ static bool Read(test::NestedStructWithTraitsDataView data,
test::NestedStructWithTraitsImpl* output);
};
@@ -39,9 +39,10 @@ struct EnumTraits<test::EnumWithTraits, test::EnumWithTraitsImpl> {
};
template <>
-struct StructTraits<test::StructWithTraits, test::StructWithTraitsImpl> {
+struct StructTraits<test::StructWithTraitsDataView,
+ test::StructWithTraitsImpl> {
// Deserialization to test::StructTraitsImpl.
- static bool Read(test::StructWithTraits::DataView data,
+ static bool Read(test::StructWithTraitsDataView data,
test::StructWithTraitsImpl* out);
// Fields in test::StructWithTraits.
@@ -76,6 +77,11 @@ struct StructTraits<test::StructWithTraits, test::StructWithTraitsImpl> {
return value.get_string_array();
}
+ static const std::set<std::string>& f_string_set(
+ const test::StructWithTraitsImpl& value) {
+ return value.get_string_set();
+ }
+
static const test::NestedStructWithTraitsImpl& f_struct(
const test::StructWithTraitsImpl& value) {
return value.get_struct();
@@ -93,31 +99,98 @@ struct StructTraits<test::StructWithTraits, test::StructWithTraitsImpl> {
};
template <>
-struct StructTraits<test::PassByValueStructWithTraits,
- test::PassByValueStructWithTraitsImpl> {
- // Deserialization to test::PassByValueStructTraitsImpl.
- static bool Read(test::PassByValueStructWithTraits::DataView data,
- test::PassByValueStructWithTraitsImpl* out);
+struct StructTraits<test::TrivialStructWithTraitsDataView,
+ test::TrivialStructWithTraitsImpl> {
+ // Deserialization to test::TrivialStructTraitsImpl.
+ static bool Read(test::TrivialStructWithTraitsDataView data,
+ test::TrivialStructWithTraitsImpl* out) {
+ out->value = data.value();
+ return true;
+ }
+
+ // Fields in test::TrivialStructWithTraits.
+ // See src/mojo/public/interfaces/bindings/tests/struct_with_traits.mojom.
+ static int32_t value(test::TrivialStructWithTraitsImpl& input) {
+ return input.value;
+ }
+};
+
+template <>
+struct StructTraits<test::MoveOnlyStructWithTraitsDataView,
+ test::MoveOnlyStructWithTraitsImpl> {
+ // Deserialization to test::MoveOnlyStructTraitsImpl.
+ static bool Read(test::MoveOnlyStructWithTraitsDataView data,
+ test::MoveOnlyStructWithTraitsImpl* out);
- // Fields in test::PassByValueStructWithTraits.
+ // Fields in test::MoveOnlyStructWithTraits.
// See src/mojo/public/interfaces/bindings/tests/struct_with_traits.mojom.
- static ScopedHandle f_handle(test::PassByValueStructWithTraitsImpl& value) {
+ static ScopedHandle f_handle(test::MoveOnlyStructWithTraitsImpl& value) {
return std::move(value.get_mutable_handle());
}
};
template <>
-struct StructTraits<test::StructWithTraitsForUniquePtrTest,
+struct StructTraits<test::StructWithTraitsForUniquePtrDataView,
std::unique_ptr<int>> {
+ static bool IsNull(const std::unique_ptr<int>& data) { return !data; }
+ static void SetToNull(std::unique_ptr<int>* data) { data->reset(); }
+
static int f_int32(const std::unique_ptr<int>& data) { return *data; }
- static bool Read(test::StructWithTraitsForUniquePtrTest::DataView data,
+ static bool Read(test::StructWithTraitsForUniquePtrDataView data,
std::unique_ptr<int>* out) {
out->reset(new int(data.f_int32()));
return true;
}
};
+template <>
+struct UnionTraits<test::UnionWithTraitsDataView,
+ std::unique_ptr<test::UnionWithTraitsBase>> {
+ static bool IsNull(const std::unique_ptr<test::UnionWithTraitsBase>& data) {
+ return !data;
+ }
+ static void SetToNull(std::unique_ptr<test::UnionWithTraitsBase>* data) {
+ data->reset();
+ }
+
+ static test::UnionWithTraitsDataView::Tag GetTag(
+ const std::unique_ptr<test::UnionWithTraitsBase>& data) {
+ if (data->type() == test::UnionWithTraitsBase::Type::INT32)
+ return test::UnionWithTraitsDataView::Tag::F_INT32;
+
+ return test::UnionWithTraitsDataView::Tag::F_STRUCT;
+ }
+
+ static int32_t f_int32(
+ const std::unique_ptr<test::UnionWithTraitsBase>& data) {
+ return static_cast<test::UnionWithTraitsInt32*>(data.get())->value();
+ }
+
+ static const test::NestedStructWithTraitsImpl& f_struct(
+ const std::unique_ptr<test::UnionWithTraitsBase>& data) {
+ return static_cast<test::UnionWithTraitsStruct*>(data.get())->get_struct();
+ }
+
+ static bool Read(test::UnionWithTraitsDataView data,
+ std::unique_ptr<test::UnionWithTraitsBase>* out) {
+ switch (data.tag()) {
+ case test::UnionWithTraitsDataView::Tag::F_INT32: {
+ out->reset(new test::UnionWithTraitsInt32(data.f_int32()));
+ return true;
+ }
+ case test::UnionWithTraitsDataView::Tag::F_STRUCT: {
+ auto* struct_object = new test::UnionWithTraitsStruct();
+ out->reset(struct_object);
+ return data.ReadFStruct(&struct_object->get_mutable_struct());
+ }
+ }
+
+ NOTREACHED();
+ return false;
+ }
+};
+
} // namespace mojo
#endif // MOJO_PUBLIC_CPP_BINDINGS_TESTS_STRUCT_WITH_TRAITS_IMPL_TRAITS_H_
diff --git a/mojo/public/cpp/bindings/tests/sync_method_unittest.cc b/mojo/public/cpp/bindings/tests/sync_method_unittest.cc
index 1253930..d0e5f10 100644
--- a/mojo/public/cpp/bindings/tests/sync_method_unittest.cc
+++ b/mojo/public/cpp/bindings/tests/sync_method_unittest.cc
@@ -267,13 +267,10 @@ class SyncMethodAssociatedTest : public SyncMethodTest {
protected:
void SetUp() override {
- master_impl_.reset(new TestSyncMasterImpl(GetProxy(&master_ptr_)));
+ master_impl_.reset(new TestSyncMasterImpl(MakeRequest(&master_ptr_)));
- master_ptr_.associated_group()->CreateAssociatedInterface(
- AssociatedGroup::WILL_PASS_REQUEST, &asso_ptr_info_, &asso_request_);
- master_ptr_.associated_group()->CreateAssociatedInterface(
- AssociatedGroup::WILL_PASS_PTR, &opposite_asso_ptr_info_,
- &opposite_asso_request_);
+ asso_request_ = MakeRequest(&asso_ptr_info_);
+ opposite_asso_request_ = MakeRequest(&opposite_asso_ptr_info_);
master_impl_->set_send_interface_handler(
[this](TestSyncAssociatedPtrInfo ptr) {
@@ -335,14 +332,14 @@ TestSync::AsyncEchoCallback BindAsyncEchoCallback(Func func) {
return base::Bind(&CallAsyncEchoCallback<Func>, func);
}
-// TestSync and TestSyncMaster exercise Router and MultiplexRouter,
-// respectively.
+// TestSync (without associated interfaces) and TestSyncMaster (with associated
+// interfaces) exercise MultiplexRouter with different configurations.
using InterfaceTypes = testing::Types<TestSync, TestSyncMaster>;
TYPED_TEST_CASE(SyncMethodCommonTest, InterfaceTypes);
TYPED_TEST(SyncMethodCommonTest, CallSyncMethodAsynchronously) {
InterfacePtr<TypeParam> ptr;
- typename ImplTraits<TypeParam>::Type impl(GetProxy(&ptr));
+ typename ImplTraits<TypeParam>::Type impl(MakeRequest(&ptr));
base::RunLoop run_loop;
ptr->Echo(123, base::Bind(&ExpectValueAndRunClosure, 123,
@@ -357,7 +354,7 @@ TYPED_TEST(SyncMethodCommonTest, BasicSyncCalls) {
service_thread.thread()->task_runner()->PostTask(
FROM_HERE, base::Bind(&TestSyncServiceThread<TypeParam>::SetUp,
base::Unretained(&service_thread),
- base::Passed(GetProxy(&ptr))));
+ base::Passed(MakeRequest(&ptr))));
ASSERT_TRUE(ptr->Ping());
ASSERT_TRUE(service_thread.ping_called());
@@ -379,7 +376,7 @@ TYPED_TEST(SyncMethodCommonTest, ReenteredBySyncMethodBinding) {
InterfacePtr<TypeParam> ptr;
// The binding lives on the same thread as the interface pointer.
- typename ImplTraits<TypeParam>::Type impl(GetProxy(&ptr));
+ typename ImplTraits<TypeParam>::Type impl(MakeRequest(&ptr));
int32_t output_value = -1;
ASSERT_TRUE(ptr->Echo(42, &output_value));
EXPECT_EQ(42, output_value);
@@ -390,7 +387,7 @@ TYPED_TEST(SyncMethodCommonTest, InterfacePtrDestroyedDuringSyncCall) {
// destroyed while it is waiting for a sync call response.
InterfacePtr<TypeParam> ptr;
- typename ImplTraits<TypeParam>::Type impl(GetProxy(&ptr));
+ typename ImplTraits<TypeParam>::Type impl(MakeRequest(&ptr));
impl.set_ping_handler([&ptr](const TestSync::PingCallback& callback) {
ptr.reset();
callback.Run();
@@ -404,7 +401,7 @@ TYPED_TEST(SyncMethodCommonTest, BindingDestroyedDuringSyncCall) {
// corresponding interface pointer is waiting for a sync call response.
InterfacePtr<TypeParam> ptr;
- typename ImplTraits<TypeParam>::Type impl(GetProxy(&ptr));
+ typename ImplTraits<TypeParam>::Type impl(MakeRequest(&ptr));
impl.set_ping_handler([&impl](const TestSync::PingCallback& callback) {
impl.binding()->Close();
callback.Run();
@@ -417,7 +414,7 @@ TYPED_TEST(SyncMethodCommonTest, NestedSyncCallsWithInOrderResponses) {
// already a sync call ongoing. The responses arrive in order.
InterfacePtr<TypeParam> ptr;
- typename ImplTraits<TypeParam>::Type impl(GetProxy(&ptr));
+ typename ImplTraits<TypeParam>::Type impl(MakeRequest(&ptr));
// The same variable is used to store the output of the two sync calls, in
// order to test that responses are handled in the correct order.
@@ -443,7 +440,7 @@ TYPED_TEST(SyncMethodCommonTest, NestedSyncCallsWithOutOfOrderResponses) {
// already a sync call ongoing. The responses arrive out of order.
InterfacePtr<TypeParam> ptr;
- typename ImplTraits<TypeParam>::Type impl(GetProxy(&ptr));
+ typename ImplTraits<TypeParam>::Type impl(MakeRequest(&ptr));
// The same variable is used to store the output of the two sync calls, in
// order to test that responses are handled in the correct order.
@@ -469,7 +466,7 @@ TYPED_TEST(SyncMethodCommonTest, AsyncResponseQueuedDuringSyncCall) {
// call, async responses are queued until the sync call completes.
InterfacePtr<TypeParam> ptr;
- typename ImplTraits<TypeParam>::Type impl(GetProxy(&ptr));
+ typename ImplTraits<TypeParam>::Type impl(MakeRequest(&ptr));
int32_t async_echo_request_value = -1;
TestSync::AsyncEchoCallback async_echo_request_callback;
@@ -525,7 +522,7 @@ TYPED_TEST(SyncMethodCommonTest, AsyncRequestQueuedDuringSyncCall) {
// until the sync call completes.
InterfacePtr<TypeParam> ptr;
- typename ImplTraits<TypeParam>::Type impl(GetProxy(&ptr));
+ typename ImplTraits<TypeParam>::Type impl(MakeRequest(&ptr));
bool async_echo_request_dispatched = false;
impl.set_async_echo_handler([&async_echo_request_dispatched](
@@ -576,7 +573,7 @@ TYPED_TEST(SyncMethodCommonTest,
// notification is delayed until all the queued messages are processed.
InterfacePtr<TypeParam> ptr;
- typename ImplTraits<TypeParam>::Type impl(GetProxy(&ptr));
+ typename ImplTraits<TypeParam>::Type impl(MakeRequest(&ptr));
int32_t async_echo_request_value = -1;
TestSync::AsyncEchoCallback async_echo_request_callback;
diff --git a/mojo/public/cpp/bindings/tests/test_native_types_blink.typemap b/mojo/public/cpp/bindings/tests/test_native_types_blink.typemap
index 258acd5..1bdfbbc 100644
--- a/mojo/public/cpp/bindings/tests/test_native_types_blink.typemap
+++ b/mojo/public/cpp/bindings/tests/test_native_types_blink.typemap
@@ -13,5 +13,5 @@ deps = [
type_mappings = [
"mojo.test.PickledEnum=mojo::test::PickledEnumBlink",
- "mojo.test.PickledStruct=mojo::test::PickledStructBlink"
+ "mojo.test.PickledStruct=mojo::test::PickledStructBlink[move_only]",
]
diff --git a/mojo/public/cpp/bindings/tests/test_native_types_chromium.typemap b/mojo/public/cpp/bindings/tests/test_native_types_chromium.typemap
index a4c0f5a..50e8076 100644
--- a/mojo/public/cpp/bindings/tests/test_native_types_chromium.typemap
+++ b/mojo/public/cpp/bindings/tests/test_native_types_chromium.typemap
@@ -3,8 +3,7 @@
# found in the LICENSE file.
mojom = "//mojo/public/interfaces/bindings/tests/test_native_types.mojom"
-public_headers =
- [ "//mojo/public/cpp/bindings/tests/pickled_types_chromium.h" ]
+public_headers = [ "//mojo/public/cpp/bindings/tests/pickled_types_chromium.h" ]
sources = [
"//mojo/public/cpp/bindings/tests/pickled_types_chromium.cc",
]
@@ -14,5 +13,5 @@ deps = [
type_mappings = [
"mojo.test.PickledEnum=mojo::test::PickledEnumChromium",
- "mojo.test.PickledStruct=mojo::test::PickledStructChromium"
+ "mojo.test.PickledStruct=mojo::test::PickledStructChromium[move_only]",
]
diff --git a/mojo/public/cpp/bindings/tests/type_conversion_unittest.cc b/mojo/public/cpp/bindings/tests/type_conversion_unittest.cc
index 7eb24ea..b0124aa 100644
--- a/mojo/public/cpp/bindings/tests/type_conversion_unittest.cc
+++ b/mojo/public/cpp/bindings/tests/type_conversion_unittest.cc
@@ -23,8 +23,8 @@ struct RedmondNamedRegion {
std::vector<RedmondRect> rects;
};
-bool AreEqualRectArrays(const Array<test::RectPtr>& rects1,
- const Array<test::RectPtr>& rects2) {
+bool AreEqualRectArrays(const std::vector<test::RectPtr>& rects1,
+ const std::vector<test::RectPtr>& rects2) {
if (rects1.size() != rects2.size())
return false;
@@ -44,12 +44,8 @@ bool AreEqualRectArrays(const Array<test::RectPtr>& rects1,
template <>
struct TypeConverter<test::RectPtr, RedmondRect> {
static test::RectPtr Convert(const RedmondRect& input) {
- test::RectPtr rect(test::Rect::New());
- rect->x = input.left;
- rect->y = input.top;
- rect->width = input.right - input.left;
- rect->height = input.bottom - input.top;
- return rect;
+ return test::Rect::New(input.left, input.top, input.right - input.left,
+ input.bottom - input.top);
}
};
@@ -68,10 +64,8 @@ struct TypeConverter<RedmondRect, test::RectPtr> {
template <>
struct TypeConverter<test::NamedRegionPtr, RedmondNamedRegion> {
static test::NamedRegionPtr Convert(const RedmondNamedRegion& input) {
- test::NamedRegionPtr region(test::NamedRegion::New());
- region->name.emplace(input.name);
- region->rects = Array<test::RectPtr>::From(input.rects).PassStorage();
- return region;
+ return test::NamedRegion::New(
+ input.name, ConvertTo<std::vector<test::RectPtr>>(input.rects));
}
};
@@ -93,53 +87,8 @@ struct TypeConverter<RedmondNamedRegion, test::NamedRegionPtr> {
namespace test {
namespace {
-TEST(TypeConversionTest, String) {
- const char kText[6] = "hello";
-
- String a = std::string(kText);
- String b(kText);
- String c(static_cast<const char*>(kText));
-
- EXPECT_EQ(std::string(kText), a.To<std::string>());
- EXPECT_EQ(std::string(kText), b.To<std::string>());
- EXPECT_EQ(std::string(kText), c.To<std::string>());
-}
-
-TEST(TypeConversionTest, String_Null) {
- String a(nullptr);
- EXPECT_TRUE(a.is_null());
- EXPECT_EQ(std::string(), a.To<std::string>());
-
- String b = String::From(static_cast<const char*>(nullptr));
- EXPECT_TRUE(b.is_null());
-}
-
-TEST(TypeConversionTest, String_Empty) {
- String a = "";
- EXPECT_EQ(std::string(), a.To<std::string>());
-
- String b = std::string();
- EXPECT_FALSE(b.is_null());
- EXPECT_EQ(std::string(), b.To<std::string>());
-}
-
-TEST(TypeConversionTest, StringWithEmbeddedNull) {
- const std::string kText("hel\0lo", 6);
-
- String a(kText);
- EXPECT_EQ(kText, a.To<std::string>());
-
- // Expect truncation:
- String b(kText.c_str());
- EXPECT_EQ(std::string("hel"), b.To<std::string>());
-}
-
TEST(TypeConversionTest, CustomTypeConverter) {
- RectPtr rect(Rect::New());
- rect->x = 10;
- rect->y = 20;
- rect->width = 50;
- rect->height = 45;
+ RectPtr rect(Rect::New(10, 20, 50, 45));
RedmondRect rr = rect.To<RedmondRect>();
EXPECT_EQ(10, rr.left);
@@ -155,9 +104,9 @@ TEST(TypeConversionTest, CustomTypeConverter) {
}
TEST(TypeConversionTest, CustomTypeConverter_Array_Null) {
- Array<RectPtr> rects;
+ std::vector<RectPtr> rects;
- std::vector<RedmondRect> redmond_rects = rects.To<std::vector<RedmondRect>>();
+ auto redmond_rects = ConvertTo<std::vector<RedmondRect>>(rects);
EXPECT_TRUE(redmond_rects.empty());
}
@@ -165,7 +114,7 @@ TEST(TypeConversionTest, CustomTypeConverter_Array_Null) {
TEST(TypeConversionTest, CustomTypeConverter_Array) {
const RedmondRect kBase = {10, 20, 30, 40};
- Array<RectPtr> rects(10);
+ std::vector<RectPtr> rects(10);
for (size_t i = 0; i < rects.size(); ++i) {
RedmondRect rr = kBase;
rr.left += static_cast<int32_t>(i);
@@ -173,9 +122,9 @@ TEST(TypeConversionTest, CustomTypeConverter_Array) {
rects[i] = Rect::From(rr);
}
- std::vector<RedmondRect> redmond_rects = rects.To<std::vector<RedmondRect>>();
+ auto redmond_rects = ConvertTo<std::vector<RedmondRect>>(rects);
- Array<RectPtr> rects2 = Array<RectPtr>::From(redmond_rects);
+ auto rects2 = ConvertTo<std::vector<RectPtr>>(redmond_rects);
EXPECT_TRUE(AreEqualRectArrays(rects, rects2));
}
diff --git a/mojo/public/cpp/bindings/tests/union_unittest.cc b/mojo/public/cpp/bindings/tests/union_unittest.cc
index d65a348..bdf27df 100644
--- a/mojo/public/cpp/bindings/tests/union_unittest.cc
+++ b/mojo/public/cpp/bindings/tests/union_unittest.cc
@@ -9,14 +9,12 @@
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
-#include "mojo/public/cpp/bindings/array.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "mojo/public/cpp/bindings/lib/array_internal.h"
#include "mojo/public/cpp/bindings/lib/fixed_buffer.h"
#include "mojo/public/cpp/bindings/lib/serialization.h"
#include "mojo/public/cpp/bindings/lib/validation_context.h"
#include "mojo/public/cpp/bindings/lib/validation_errors.h"
-#include "mojo/public/cpp/bindings/string.h"
#include "mojo/public/cpp/test_support/test_utils.h"
#include "mojo/public/interfaces/bindings/tests/test_structs.mojom.h"
#include "mojo/public/interfaces/bindings/tests/test_unions.mojom.h"
@@ -123,16 +121,17 @@ TEST(UnionTest, PodSerialization) {
pod1->set_f_int8(10);
mojo::internal::SerializationContext context;
- size_t size =
- mojo::internal::PrepareToSerialize<PodUnionPtr>(pod1, false, &context);
+ size_t size = mojo::internal::PrepareToSerialize<PodUnionDataView>(
+ pod1, false, &context);
EXPECT_EQ(16U, size);
mojo::internal::FixedBufferForTesting buf(size);
internal::PodUnion_Data* data = nullptr;
- mojo::internal::Serialize<PodUnionPtr>(pod1, &buf, &data, false, &context);
+ mojo::internal::Serialize<PodUnionDataView>(pod1, &buf, &data, false,
+ &context);
PodUnionPtr pod2;
- mojo::internal::Deserialize<PodUnionPtr>(data, &pod2, &context);
+ mojo::internal::Deserialize<PodUnionDataView>(data, &pod2, &context);
EXPECT_EQ(10, pod2->get_f_int8());
EXPECT_TRUE(pod2->is_f_int8());
@@ -143,16 +142,17 @@ TEST(UnionTest, EnumSerialization) {
PodUnionPtr pod1(PodUnion::New());
pod1->set_f_enum(AnEnum::SECOND);
- size_t size =
- mojo::internal::PrepareToSerialize<PodUnionPtr>(pod1, false, nullptr);
+ size_t size = mojo::internal::PrepareToSerialize<PodUnionDataView>(
+ pod1, false, nullptr);
EXPECT_EQ(16U, size);
mojo::internal::FixedBufferForTesting buf(size);
internal::PodUnion_Data* data = nullptr;
- mojo::internal::Serialize<PodUnionPtr>(pod1, &buf, &data, false, nullptr);
+ mojo::internal::Serialize<PodUnionDataView>(pod1, &buf, &data, false,
+ nullptr);
PodUnionPtr pod2;
- mojo::internal::Deserialize<PodUnionPtr>(data, &pod2, nullptr);
+ mojo::internal::Deserialize<PodUnionDataView>(data, &pod2, nullptr);
EXPECT_EQ(AnEnum::SECOND, pod2->get_f_enum());
EXPECT_TRUE(pod2->is_f_enum());
@@ -164,16 +164,16 @@ TEST(UnionTest, PodValidation) {
pod->set_f_int8(10);
size_t size =
- mojo::internal::PrepareToSerialize<PodUnionPtr>(pod, false, nullptr);
+ mojo::internal::PrepareToSerialize<PodUnionDataView>(pod, false, nullptr);
EXPECT_EQ(16U, size);
mojo::internal::FixedBufferForTesting buf(size);
internal::PodUnion_Data* data = nullptr;
- mojo::internal::Serialize<PodUnionPtr>(pod, &buf, &data, false, nullptr);
+ mojo::internal::Serialize<PodUnionDataView>(pod, &buf, &data, false, nullptr);
void* raw_buf = buf.Leak();
mojo::internal::ValidationContext validation_context(
- data, static_cast<uint32_t>(size), 0);
+ data, static_cast<uint32_t>(size), 0, 0);
EXPECT_TRUE(
internal::PodUnion_Data::Validate(raw_buf, &validation_context, false));
free(raw_buf);
@@ -183,17 +183,17 @@ TEST(UnionTest, SerializeNotNull) {
PodUnionPtr pod(PodUnion::New());
pod->set_f_int8(0);
size_t size =
- mojo::internal::PrepareToSerialize<PodUnionPtr>(pod, false, nullptr);
+ mojo::internal::PrepareToSerialize<PodUnionDataView>(pod, false, nullptr);
mojo::internal::FixedBufferForTesting buf(size);
internal::PodUnion_Data* data = nullptr;
- mojo::internal::Serialize<PodUnionPtr>(pod, &buf, &data, false, nullptr);
+ mojo::internal::Serialize<PodUnionDataView>(pod, &buf, &data, false, nullptr);
EXPECT_FALSE(data->is_null());
}
TEST(UnionTest, SerializeIsNullInlined) {
PodUnionPtr pod;
size_t size =
- mojo::internal::PrepareToSerialize<PodUnionPtr>(pod, false, nullptr);
+ mojo::internal::PrepareToSerialize<PodUnionDataView>(pod, false, nullptr);
EXPECT_EQ(16U, size);
mojo::internal::FixedBufferForTesting buf(size);
internal::PodUnion_Data* data = internal::PodUnion_Data::New(&buf);
@@ -203,28 +203,28 @@ TEST(UnionTest, SerializeIsNullInlined) {
data->tag = PodUnion::Tag::F_UINT16;
data->data.f_f_int16 = 20;
- mojo::internal::Serialize<PodUnionPtr>(pod, &buf, &data, true, nullptr);
+ mojo::internal::Serialize<PodUnionDataView>(pod, &buf, &data, true, nullptr);
EXPECT_TRUE(data->is_null());
PodUnionPtr pod2;
- mojo::internal::Deserialize<PodUnionPtr>(data, &pod2, nullptr);
+ mojo::internal::Deserialize<PodUnionDataView>(data, &pod2, nullptr);
EXPECT_TRUE(pod2.is_null());
}
TEST(UnionTest, SerializeIsNullNotInlined) {
PodUnionPtr pod;
size_t size =
- mojo::internal::PrepareToSerialize<PodUnionPtr>(pod, false, nullptr);
+ mojo::internal::PrepareToSerialize<PodUnionDataView>(pod, false, nullptr);
EXPECT_EQ(16U, size);
mojo::internal::FixedBufferForTesting buf(size);
internal::PodUnion_Data* data = nullptr;
- mojo::internal::Serialize<PodUnionPtr>(pod, &buf, &data, false, nullptr);
+ mojo::internal::Serialize<PodUnionDataView>(pod, &buf, &data, false, nullptr);
EXPECT_EQ(nullptr, data);
}
TEST(UnionTest, NullValidation) {
void* buf = nullptr;
- mojo::internal::ValidationContext validation_context(buf, 0, 0);
+ mojo::internal::ValidationContext validation_context(buf, 0, 0, 0);
EXPECT_TRUE(internal::PodUnion_Data::Validate(
buf, &validation_context, false));
}
@@ -239,7 +239,7 @@ TEST(UnionTest, OutOfAlignmentValidation) {
internal::PodUnion_Data* data =
reinterpret_cast<internal::PodUnion_Data*>(buf);
mojo::internal::ValidationContext validation_context(
- data, static_cast<uint32_t>(size), 0);
+ data, static_cast<uint32_t>(size), 0, 0);
EXPECT_FALSE(internal::PodUnion_Data::Validate(
buf, &validation_context, false));
free(raw_buf);
@@ -250,7 +250,7 @@ TEST(UnionTest, OOBValidation) {
mojo::internal::FixedBufferForTesting buf(size);
internal::PodUnion_Data* data = internal::PodUnion_Data::New(&buf);
mojo::internal::ValidationContext validation_context(
- data, static_cast<uint32_t>(size), 0);
+ data, static_cast<uint32_t>(size), 0, 0);
void* raw_buf = buf.Leak();
EXPECT_FALSE(
internal::PodUnion_Data::Validate(raw_buf, &validation_context, false));
@@ -263,7 +263,7 @@ TEST(UnionTest, UnknownTagValidation) {
internal::PodUnion_Data* data = internal::PodUnion_Data::New(&buf);
data->tag = static_cast<internal::PodUnion_Data::PodUnion_Tag>(0xFFFFFF);
mojo::internal::ValidationContext validation_context(
- data, static_cast<uint32_t>(size), 0);
+ data, static_cast<uint32_t>(size), 0, 0);
void* raw_buf = buf.Leak();
EXPECT_FALSE(
internal::PodUnion_Data::Validate(raw_buf, &validation_context, false));
@@ -275,16 +275,16 @@ TEST(UnionTest, UnknownEnumValueValidation) {
pod->set_f_enum(static_cast<AnEnum>(0xFFFF));
size_t size =
- mojo::internal::PrepareToSerialize<PodUnionPtr>(pod, false, nullptr);
+ mojo::internal::PrepareToSerialize<PodUnionDataView>(pod, false, nullptr);
EXPECT_EQ(16U, size);
mojo::internal::FixedBufferForTesting buf(size);
internal::PodUnion_Data* data = nullptr;
- mojo::internal::Serialize<PodUnionPtr>(pod, &buf, &data, false, nullptr);
+ mojo::internal::Serialize<PodUnionDataView>(pod, &buf, &data, false, nullptr);
void* raw_buf = buf.Leak();
mojo::internal::ValidationContext validation_context(
- data, static_cast<uint32_t>(size), 0);
+ data, static_cast<uint32_t>(size), 0, 0);
EXPECT_FALSE(
internal::PodUnion_Data::Validate(raw_buf, &validation_context, false));
free(raw_buf);
@@ -295,16 +295,16 @@ TEST(UnionTest, UnknownExtensibleEnumValueValidation) {
pod->set_f_extensible_enum(static_cast<AnExtensibleEnum>(0xFFFF));
size_t size =
- mojo::internal::PrepareToSerialize<PodUnionPtr>(pod, false, nullptr);
+ mojo::internal::PrepareToSerialize<PodUnionDataView>(pod, false, nullptr);
EXPECT_EQ(16U, size);
mojo::internal::FixedBufferForTesting buf(size);
internal::PodUnion_Data* data = nullptr;
- mojo::internal::Serialize<PodUnionPtr>(pod, &buf, &data, false, nullptr);
+ mojo::internal::Serialize<PodUnionDataView>(pod, &buf, &data, false, nullptr);
void* raw_buf = buf.Leak();
mojo::internal::ValidationContext validation_context(
- data, static_cast<uint32_t>(size), 0);
+ data, static_cast<uint32_t>(size), 0, 0);
EXPECT_TRUE(
internal::PodUnion_Data::Validate(raw_buf, &validation_context, false));
free(raw_buf);
@@ -313,7 +313,7 @@ TEST(UnionTest, UnknownExtensibleEnumValueValidation) {
TEST(UnionTest, StringGetterSetter) {
ObjectUnionPtr pod(ObjectUnion::New());
- String hello("hello world");
+ std::string hello("hello world");
pod->set_f_string(hello);
EXPECT_EQ(hello, pod->get_f_string());
EXPECT_TRUE(pod->is_f_string());
@@ -335,7 +335,7 @@ TEST(UnionTest, StringEquals) {
TEST(UnionTest, StringClone) {
ObjectUnionPtr pod(ObjectUnion::New());
- String hello("hello world");
+ std::string hello("hello world");
pod->set_f_string(hello);
ObjectUnionPtr pod_clone = pod.Clone();
EXPECT_EQ(hello, pod_clone->get_f_string());
@@ -346,17 +346,18 @@ TEST(UnionTest, StringClone) {
TEST(UnionTest, StringSerialization) {
ObjectUnionPtr pod1(ObjectUnion::New());
- String hello("hello world");
+ std::string hello("hello world");
pod1->set_f_string(hello);
- size_t size =
- mojo::internal::PrepareToSerialize<ObjectUnionPtr>(pod1, false, nullptr);
+ size_t size = mojo::internal::PrepareToSerialize<ObjectUnionDataView>(
+ pod1, false, nullptr);
mojo::internal::FixedBufferForTesting buf(size);
internal::ObjectUnion_Data* data = nullptr;
- mojo::internal::Serialize<ObjectUnionPtr>(pod1, &buf, &data, false, nullptr);
+ mojo::internal::Serialize<ObjectUnionDataView>(pod1, &buf, &data, false,
+ nullptr);
ObjectUnionPtr pod2;
- mojo::internal::Deserialize<ObjectUnionPtr>(data, &pod2, nullptr);
+ mojo::internal::Deserialize<ObjectUnionDataView>(data, &pod2, nullptr);
EXPECT_EQ(hello, pod2->get_f_string());
EXPECT_TRUE(pod2->is_f_string());
EXPECT_EQ(pod2->which(), ObjectUnion::Tag::F_STRING);
@@ -369,7 +370,7 @@ TEST(UnionTest, NullStringValidation) {
data->tag = internal::ObjectUnion_Data::ObjectUnion_Tag::F_STRING;
data->data.unknown = 0x0;
mojo::internal::ValidationContext validation_context(
- data, static_cast<uint32_t>(size), 0);
+ data, static_cast<uint32_t>(size), 0, 0);
void* raw_buf = buf.Leak();
EXPECT_FALSE(internal::ObjectUnion_Data::Validate(
raw_buf, &validation_context, false));
@@ -383,7 +384,7 @@ TEST(UnionTest, StringPointerOverflowValidation) {
data->tag = internal::ObjectUnion_Data::ObjectUnion_Tag::F_STRING;
data->data.unknown = 0xFFFFFFFFFFFFFFFF;
mojo::internal::ValidationContext validation_context(
- data, static_cast<uint32_t>(size), 0);
+ data, static_cast<uint32_t>(size), 0, 0);
void* raw_buf = buf.Leak();
EXPECT_FALSE(internal::ObjectUnion_Data::Validate(
raw_buf, &validation_context, false));
@@ -402,7 +403,7 @@ TEST(UnionTest, StringValidateOOB) {
reinterpret_cast<mojo::internal::ArrayHeader*>(ptr + *ptr);
array_header->num_bytes = 20; // This should go out of bounds.
array_header->num_elements = 20;
- mojo::internal::ValidationContext validation_context(data, 32, 0);
+ mojo::internal::ValidationContext validation_context(data, 32, 0, 0);
void* raw_buf = buf.Leak();
EXPECT_FALSE(internal::ObjectUnion_Data::Validate(
raw_buf, &validation_context, false));
@@ -425,7 +426,7 @@ TEST(UnionTest, PodUnionInArray) {
}
TEST(UnionTest, PodUnionInArraySerialization) {
- Array<PodUnionPtr> array(2);
+ std::vector<PodUnionPtr> array(2);
array[0] = PodUnion::New();
array[1] = PodUnion::New();
@@ -434,17 +435,19 @@ TEST(UnionTest, PodUnionInArraySerialization) {
EXPECT_EQ(2U, array.size());
size_t size =
- mojo::internal::PrepareToSerialize<Array<PodUnionPtr>>(array, nullptr);
+ mojo::internal::PrepareToSerialize<ArrayDataView<PodUnionDataView>>(
+ array, nullptr);
EXPECT_EQ(40U, size);
mojo::internal::FixedBufferForTesting buf(size);
mojo::internal::Array_Data<internal::PodUnion_Data>* data;
mojo::internal::ContainerValidateParams validate_params(0, false, nullptr);
- mojo::internal::Serialize<Array<PodUnionPtr>>(array, &buf, &data,
- &validate_params, nullptr);
+ mojo::internal::Serialize<ArrayDataView<PodUnionDataView>>(
+ array, &buf, &data, &validate_params, nullptr);
- Array<PodUnionPtr> array2;
- mojo::internal::Deserialize<Array<PodUnionPtr>>(data, &array2, nullptr);
+ std::vector<PodUnionPtr> array2;
+ mojo::internal::Deserialize<ArrayDataView<PodUnionDataView>>(data, &array2,
+ nullptr);
EXPECT_EQ(2U, array2.size());
@@ -453,24 +456,26 @@ TEST(UnionTest, PodUnionInArraySerialization) {
}
TEST(UnionTest, PodUnionInArraySerializationWithNull) {
- Array<PodUnionPtr> array(2);
+ std::vector<PodUnionPtr> array(2);
array[0] = PodUnion::New();
array[0]->set_f_int8(10);
EXPECT_EQ(2U, array.size());
size_t size =
- mojo::internal::PrepareToSerialize<Array<PodUnionPtr>>(array, nullptr);
+ mojo::internal::PrepareToSerialize<ArrayDataView<PodUnionDataView>>(
+ array, nullptr);
EXPECT_EQ(40U, size);
mojo::internal::FixedBufferForTesting buf(size);
mojo::internal::Array_Data<internal::PodUnion_Data>* data;
mojo::internal::ContainerValidateParams validate_params(0, true, nullptr);
- mojo::internal::Serialize<Array<PodUnionPtr>>(array, &buf, &data,
- &validate_params, nullptr);
+ mojo::internal::Serialize<ArrayDataView<PodUnionDataView>>(
+ array, &buf, &data, &validate_params, nullptr);
- Array<PodUnionPtr> array2;
- mojo::internal::Deserialize<Array<PodUnionPtr>>(data, &array2, nullptr);
+ std::vector<PodUnionPtr> array2;
+ mojo::internal::Deserialize<ArrayDataView<PodUnionDataView>>(data, &array2,
+ nullptr);
EXPECT_EQ(2U, array2.size());
@@ -479,7 +484,7 @@ TEST(UnionTest, PodUnionInArraySerializationWithNull) {
}
TEST(UnionTest, ObjectUnionInArraySerialization) {
- Array<ObjectUnionPtr> array(2);
+ std::vector<ObjectUnionPtr> array(2);
array[0] = ObjectUnion::New();
array[1] = ObjectUnion::New();
@@ -488,15 +493,16 @@ TEST(UnionTest, ObjectUnionInArraySerialization) {
EXPECT_EQ(2U, array.size());
size_t size =
- mojo::internal::PrepareToSerialize<Array<ObjectUnionPtr>>(array, nullptr);
+ mojo::internal::PrepareToSerialize<ArrayDataView<ObjectUnionDataView>>(
+ array, nullptr);
EXPECT_EQ(72U, size);
mojo::internal::FixedBufferForTesting buf(size);
mojo::internal::Array_Data<internal::ObjectUnion_Data>* data;
mojo::internal::ContainerValidateParams validate_params(0, false, nullptr);
- mojo::internal::Serialize<Array<ObjectUnionPtr>>(array, &buf, &data,
- &validate_params, nullptr);
+ mojo::internal::Serialize<ArrayDataView<ObjectUnionDataView>>(
+ array, &buf, &data, &validate_params, nullptr);
std::vector<char> new_buf;
new_buf.resize(size);
@@ -509,17 +515,18 @@ TEST(UnionTest, ObjectUnionInArraySerialization) {
reinterpret_cast<mojo::internal::Array_Data<internal::ObjectUnion_Data>*>(
new_buf.data());
mojo::internal::ValidationContext validation_context(
- data, static_cast<uint32_t>(size), 0);
+ data, static_cast<uint32_t>(size), 0, 0);
ASSERT_TRUE(mojo::internal::Array_Data<internal::ObjectUnion_Data>::Validate(
data, &validation_context, &validate_params));
- Array<ObjectUnionPtr> array2;
- mojo::internal::Deserialize<Array<ObjectUnionPtr>>(data, &array2, nullptr);
+ std::vector<ObjectUnionPtr> array2;
+ mojo::internal::Deserialize<ArrayDataView<ObjectUnionDataView>>(data, &array2,
+ nullptr);
EXPECT_EQ(2U, array2.size());
- EXPECT_EQ(String("hello"), array2[0]->get_f_string());
- EXPECT_EQ(String("world"), array2[1]->get_f_string());
+ EXPECT_EQ("hello", array2[0]->get_f_string());
+ EXPECT_EQ("world", array2[1]->get_f_string());
}
// TODO(azani): Move back in struct_unittest.cc when possible.
@@ -540,16 +547,17 @@ TEST(UnionTest, Serialization_UnionOfPods) {
small_struct->pod_union->set_f_int32(10);
mojo::internal::SerializationContext context;
- size_t size = mojo::internal::PrepareToSerialize<SmallStructPtr>(small_struct,
- &context);
+ size_t size = mojo::internal::PrepareToSerialize<SmallStructDataView>(
+ small_struct, &context);
mojo::internal::FixedBufferForTesting buf(size);
internal::SmallStruct_Data* data = nullptr;
- mojo::internal::Serialize<SmallStructPtr>(small_struct, &buf, &data,
- &context);
+ mojo::internal::Serialize<SmallStructDataView>(small_struct, &buf, &data,
+ &context);
SmallStructPtr deserialized;
- mojo::internal::Deserialize<SmallStructPtr>(data, &deserialized, &context);
+ mojo::internal::Deserialize<SmallStructDataView>(data, &deserialized,
+ &context);
EXPECT_EQ(10, deserialized->pod_union->get_f_int32());
}
@@ -558,19 +566,20 @@ TEST(UnionTest, Serialization_UnionOfPods) {
TEST(UnionTest, Serialization_UnionOfObjects) {
SmallObjStructPtr obj_struct(SmallObjStruct::New());
obj_struct->obj_union = ObjectUnion::New();
- String hello("hello world");
+ std::string hello("hello world");
obj_struct->obj_union->set_f_string(hello);
- size_t size = mojo::internal::PrepareToSerialize<SmallObjStructPtr>(
+ size_t size = mojo::internal::PrepareToSerialize<SmallObjStructDataView>(
obj_struct, nullptr);
mojo::internal::FixedBufferForTesting buf(size);
internal::SmallObjStruct_Data* data = nullptr;
- mojo::internal::Serialize<SmallObjStructPtr>(obj_struct, &buf, &data,
- nullptr);
+ mojo::internal::Serialize<SmallObjStructDataView>(obj_struct, &buf, &data,
+ nullptr);
SmallObjStructPtr deserialized;
- mojo::internal::Deserialize<SmallObjStructPtr>(data, &deserialized, nullptr);
+ mojo::internal::Deserialize<SmallObjStructDataView>(data, &deserialized,
+ nullptr);
EXPECT_EQ(hello, deserialized->obj_union->get_f_string());
}
@@ -582,18 +591,17 @@ TEST(UnionTest, Validation_UnionsInStruct) {
small_struct->pod_union->set_f_int32(10);
mojo::internal::SerializationContext context;
- size_t size = mojo::internal::PrepareToSerialize<SmallStructPtr>(small_struct,
- &context);
+ size_t size = mojo::internal::PrepareToSerialize<SmallStructDataView>(
+ small_struct, &context);
mojo::internal::FixedBufferForTesting buf(size);
internal::SmallStruct_Data* data = nullptr;
- mojo::internal::Serialize<SmallStructPtr>(small_struct, &buf, &data,
- &context);
-
+ mojo::internal::Serialize<SmallStructDataView>(small_struct, &buf, &data,
+ &context);
void* raw_buf = buf.Leak();
mojo::internal::ValidationContext validation_context(
- data, static_cast<uint32_t>(size), 0);
+ data, static_cast<uint32_t>(size), 0, 0);
EXPECT_TRUE(internal::SmallStruct_Data::Validate(
raw_buf, &validation_context));
free(raw_buf);
@@ -606,18 +614,18 @@ TEST(UnionTest, Validation_PodUnionInStruct_Failure) {
small_struct->pod_union->set_f_int32(10);
mojo::internal::SerializationContext context;
- size_t size = mojo::internal::PrepareToSerialize<SmallStructPtr>(small_struct,
- &context);
+ size_t size = mojo::internal::PrepareToSerialize<SmallStructDataView>(
+ small_struct, &context);
mojo::internal::FixedBufferForTesting buf(size);
internal::SmallStruct_Data* data = nullptr;
- mojo::internal::Serialize<SmallStructPtr>(small_struct, &buf, &data,
- &context);
+ mojo::internal::Serialize<SmallStructDataView>(small_struct, &buf, &data,
+ &context);
data->pod_union.tag = static_cast<internal::PodUnion_Data::PodUnion_Tag>(100);
void* raw_buf = buf.Leak();
mojo::internal::ValidationContext validation_context(
- data, static_cast<uint32_t>(size), 0);
+ data, static_cast<uint32_t>(size), 0, 0);
EXPECT_FALSE(internal::SmallStruct_Data::Validate(
raw_buf, &validation_context));
free(raw_buf);
@@ -629,7 +637,7 @@ TEST(UnionTest, Validation_NullUnion_Failure) {
SmallStructNonNullableUnion::New());
size_t size =
- mojo::internal::PrepareToSerialize<SmallStructNonNullableUnionPtr>(
+ mojo::internal::PrepareToSerialize<SmallStructNonNullableUnionDataView>(
small_struct, nullptr);
mojo::internal::FixedBufferForTesting buf(size);
@@ -638,7 +646,7 @@ TEST(UnionTest, Validation_NullUnion_Failure) {
void* raw_buf = buf.Leak();
mojo::internal::ValidationContext validation_context(
- data, static_cast<uint32_t>(size), 0);
+ data, static_cast<uint32_t>(size), 0, 0);
EXPECT_FALSE(internal::SmallStructNonNullableUnion_Data::Validate(
raw_buf, &validation_context));
free(raw_buf);
@@ -649,17 +657,17 @@ TEST(UnionTest, Validation_NullableUnion) {
SmallStructPtr small_struct(SmallStruct::New());
mojo::internal::SerializationContext context;
- size_t size = mojo::internal::PrepareToSerialize<SmallStructPtr>(small_struct,
- &context);
+ size_t size = mojo::internal::PrepareToSerialize<SmallStructDataView>(
+ small_struct, &context);
mojo::internal::FixedBufferForTesting buf(size);
internal::SmallStruct_Data* data = nullptr;
- mojo::internal::Serialize<SmallStructPtr>(small_struct, &buf, &data,
- &context);
+ mojo::internal::Serialize<SmallStructDataView>(small_struct, &buf, &data,
+ &context);
void* raw_buf = buf.Leak();
mojo::internal::ValidationContext validation_context(
- data, static_cast<uint32_t>(size), 0);
+ data, static_cast<uint32_t>(size), 0, 0);
EXPECT_TRUE(internal::SmallStruct_Data::Validate(
raw_buf, &validation_context));
free(raw_buf);
@@ -681,57 +689,58 @@ TEST(UnionTest, PodUnionInMap) {
}
TEST(UnionTest, PodUnionInMapSerialization) {
- Map<String, PodUnionPtr> map;
- map.insert("one", PodUnion::New());
- map.insert("two", PodUnion::New());
+ using MojomType = MapDataView<StringDataView, PodUnionDataView>;
+
+ std::unordered_map<std::string, PodUnionPtr> map;
+ map.insert(std::make_pair("one", PodUnion::New()));
+ map.insert(std::make_pair("two", PodUnion::New()));
map["one"]->set_f_int8(8);
map["two"]->set_f_int16(16);
mojo::internal::SerializationContext context;
- size_t size = mojo::internal::PrepareToSerialize<Map<String, PodUnionPtr>>(
- map, &context);
+ size_t size = mojo::internal::PrepareToSerialize<MojomType>(map, &context);
EXPECT_EQ(120U, size);
mojo::internal::FixedBufferForTesting buf(size);
- typename mojo::internal::MojomTypeTraits<Map<String, PodUnionPtr>>::Data*
- data;
+
+ typename mojo::internal::MojomTypeTraits<MojomType>::Data* data;
mojo::internal::ContainerValidateParams validate_params(
new mojo::internal::ContainerValidateParams(0, false, nullptr),
new mojo::internal::ContainerValidateParams(0, false, nullptr));
- mojo::internal::Serialize<Map<String, PodUnionPtr>>(
- map, &buf, &data, &validate_params, &context);
+ mojo::internal::Serialize<MojomType>(map, &buf, &data, &validate_params,
+ &context);
- Map<String, PodUnionPtr> map2;
- mojo::internal::Deserialize<Map<String, PodUnionPtr>>(data, &map2, &context);
+ std::unordered_map<std::string, PodUnionPtr> map2;
+ mojo::internal::Deserialize<MojomType>(data, &map2, &context);
EXPECT_EQ(8, map2["one"]->get_f_int8());
EXPECT_EQ(16, map2["two"]->get_f_int16());
}
TEST(UnionTest, PodUnionInMapSerializationWithNull) {
- Map<String, PodUnionPtr> map;
- map.insert("one", PodUnion::New());
- map.insert("two", nullptr);
+ using MojomType = MapDataView<StringDataView, PodUnionDataView>;
+
+ std::unordered_map<std::string, PodUnionPtr> map;
+ map.insert(std::make_pair("one", PodUnion::New()));
+ map.insert(std::make_pair("two", nullptr));
map["one"]->set_f_int8(8);
mojo::internal::SerializationContext context;
- size_t size = mojo::internal::PrepareToSerialize<Map<String, PodUnionPtr>>(
- map, &context);
+ size_t size = mojo::internal::PrepareToSerialize<MojomType>(map, &context);
EXPECT_EQ(120U, size);
mojo::internal::FixedBufferForTesting buf(size);
- typename mojo::internal::MojomTypeTraits<Map<String, PodUnionPtr>>::Data*
- data;
+ typename mojo::internal::MojomTypeTraits<MojomType>::Data* data;
mojo::internal::ContainerValidateParams validate_params(
new mojo::internal::ContainerValidateParams(0, false, nullptr),
new mojo::internal::ContainerValidateParams(0, true, nullptr));
- mojo::internal::Serialize<Map<String, PodUnionPtr>>(
- map, &buf, &data, &validate_params, &context);
+ mojo::internal::Serialize<MojomType>(map, &buf, &data, &validate_params,
+ &context);
- Map<String, PodUnionPtr> map2;
- mojo::internal::Deserialize<Map<String, PodUnionPtr>>(data, &map2, &context);
+ std::unordered_map<std::string, PodUnionPtr> map2;
+ mojo::internal::Deserialize<MojomType>(data, &map2, &context);
EXPECT_EQ(8, map2["one"]->get_f_int8());
EXPECT_TRUE(map2["two"].is_null());
@@ -754,16 +763,17 @@ TEST(UnionTest, StructInUnionSerialization) {
ObjectUnionPtr obj(ObjectUnion::New());
obj->set_f_dummy(std::move(dummy));
- size_t size =
- mojo::internal::PrepareToSerialize<ObjectUnionPtr>(obj, false, nullptr);
+ size_t size = mojo::internal::PrepareToSerialize<ObjectUnionDataView>(
+ obj, false, nullptr);
EXPECT_EQ(32U, size);
mojo::internal::FixedBufferForTesting buf(size);
internal::ObjectUnion_Data* data = nullptr;
- mojo::internal::Serialize<ObjectUnionPtr>(obj, &buf, &data, false, nullptr);
+ mojo::internal::Serialize<ObjectUnionDataView>(obj, &buf, &data, false,
+ nullptr);
ObjectUnionPtr obj2;
- mojo::internal::Deserialize<ObjectUnionPtr>(data, &obj2, nullptr);
+ mojo::internal::Deserialize<ObjectUnionDataView>(data, &obj2, nullptr);
EXPECT_EQ(8, obj2->get_f_dummy()->f_int8);
}
@@ -774,16 +784,17 @@ TEST(UnionTest, StructInUnionValidation) {
ObjectUnionPtr obj(ObjectUnion::New());
obj->set_f_dummy(std::move(dummy));
- size_t size =
- mojo::internal::PrepareToSerialize<ObjectUnionPtr>(obj, false, nullptr);
+ size_t size = mojo::internal::PrepareToSerialize<ObjectUnionDataView>(
+ obj, false, nullptr);
mojo::internal::FixedBufferForTesting buf(size);
internal::ObjectUnion_Data* data = nullptr;
- mojo::internal::Serialize<ObjectUnionPtr>(obj, &buf, &data, false, nullptr);
+ mojo::internal::Serialize<ObjectUnionDataView>(obj, &buf, &data, false,
+ nullptr);
void* raw_buf = buf.Leak();
mojo::internal::ValidationContext validation_context(
- data, static_cast<uint32_t>(size), 0);
+ data, static_cast<uint32_t>(size), 0, 0);
EXPECT_TRUE(internal::ObjectUnion_Data::Validate(
raw_buf, &validation_context, false));
free(raw_buf);
@@ -797,16 +808,17 @@ TEST(UnionTest, StructInUnionValidationNonNullable) {
ObjectUnionPtr obj(ObjectUnion::New());
obj->set_f_dummy(std::move(dummy));
- size_t size =
- mojo::internal::PrepareToSerialize<ObjectUnionPtr>(obj, false, nullptr);
+ size_t size = mojo::internal::PrepareToSerialize<ObjectUnionDataView>(
+ obj, false, nullptr);
mojo::internal::FixedBufferForTesting buf(size);
internal::ObjectUnion_Data* data = nullptr;
- mojo::internal::Serialize<ObjectUnionPtr>(obj, &buf, &data, false, nullptr);
+ mojo::internal::Serialize<ObjectUnionDataView>(obj, &buf, &data, false,
+ nullptr);
void* raw_buf = buf.Leak();
mojo::internal::ValidationContext validation_context(
- data, static_cast<uint32_t>(size), 0);
+ data, static_cast<uint32_t>(size), 0, 0);
EXPECT_FALSE(internal::ObjectUnion_Data::Validate(
raw_buf, &validation_context, false));
free(raw_buf);
@@ -818,23 +830,24 @@ TEST(UnionTest, StructInUnionValidationNullable) {
ObjectUnionPtr obj(ObjectUnion::New());
obj->set_f_nullable(std::move(dummy));
- size_t size =
- mojo::internal::PrepareToSerialize<ObjectUnionPtr>(obj, false, nullptr);
+ size_t size = mojo::internal::PrepareToSerialize<ObjectUnionDataView>(
+ obj, false, nullptr);
mojo::internal::FixedBufferForTesting buf(size);
internal::ObjectUnion_Data* data = nullptr;
- mojo::internal::Serialize<ObjectUnionPtr>(obj, &buf, &data, false, nullptr);
+ mojo::internal::Serialize<ObjectUnionDataView>(obj, &buf, &data, false,
+ nullptr);
void* raw_buf = buf.Leak();
mojo::internal::ValidationContext validation_context(
- data, static_cast<uint32_t>(size), 0);
+ data, static_cast<uint32_t>(size), 0, 0);
EXPECT_TRUE(internal::ObjectUnion_Data::Validate(
raw_buf, &validation_context, false));
free(raw_buf);
}
TEST(UnionTest, ArrayInUnionGetterSetter) {
- Array<int8_t> array(2);
+ std::vector<int8_t> array(2);
array[0] = 8;
array[1] = 9;
@@ -846,45 +859,47 @@ TEST(UnionTest, ArrayInUnionGetterSetter) {
}
TEST(UnionTest, ArrayInUnionSerialization) {
- Array<int8_t> array(2);
+ std::vector<int8_t> array(2);
array[0] = 8;
array[1] = 9;
ObjectUnionPtr obj(ObjectUnion::New());
obj->set_f_array_int8(std::move(array));
- size_t size =
- mojo::internal::PrepareToSerialize<ObjectUnionPtr>(obj, false, nullptr);
+ size_t size = mojo::internal::PrepareToSerialize<ObjectUnionDataView>(
+ obj, false, nullptr);
EXPECT_EQ(32U, size);
mojo::internal::FixedBufferForTesting buf(size);
internal::ObjectUnion_Data* data = nullptr;
- mojo::internal::Serialize<ObjectUnionPtr>(obj, &buf, &data, false, nullptr);
+ mojo::internal::Serialize<ObjectUnionDataView>(obj, &buf, &data, false,
+ nullptr);
ObjectUnionPtr obj2;
- mojo::internal::Deserialize<ObjectUnionPtr>(data, &obj2, nullptr);
+ mojo::internal::Deserialize<ObjectUnionDataView>(data, &obj2, nullptr);
EXPECT_EQ(8, obj2->get_f_array_int8()[0]);
EXPECT_EQ(9, obj2->get_f_array_int8()[1]);
}
TEST(UnionTest, ArrayInUnionValidation) {
- Array<int8_t> array(2);
+ std::vector<int8_t> array(2);
array[0] = 8;
array[1] = 9;
ObjectUnionPtr obj(ObjectUnion::New());
obj->set_f_array_int8(std::move(array));
- size_t size =
- mojo::internal::PrepareToSerialize<ObjectUnionPtr>(obj, false, nullptr);
+ size_t size = mojo::internal::PrepareToSerialize<ObjectUnionDataView>(
+ obj, false, nullptr);
mojo::internal::FixedBufferForTesting buf(size);
internal::ObjectUnion_Data* data = nullptr;
- mojo::internal::Serialize<ObjectUnionPtr>(obj, &buf, &data, false, nullptr);
+ mojo::internal::Serialize<ObjectUnionDataView>(obj, &buf, &data, false,
+ nullptr);
void* raw_buf = buf.Leak();
mojo::internal::ValidationContext validation_context(
- data, static_cast<uint32_t>(size), 0);
+ data, static_cast<uint32_t>(size), 0, 0);
EXPECT_TRUE(internal::ObjectUnion_Data::Validate(
raw_buf, &validation_context, false));
@@ -912,16 +927,17 @@ TEST(UnionTest, MapInUnionSerialization) {
obj->set_f_map_int8(std::move(map));
mojo::internal::SerializationContext context;
- size_t size =
- mojo::internal::PrepareToSerialize<ObjectUnionPtr>(obj, false, &context);
+ size_t size = mojo::internal::PrepareToSerialize<ObjectUnionDataView>(
+ obj, false, &context);
EXPECT_EQ(112U, size);
mojo::internal::FixedBufferForTesting buf(size);
internal::ObjectUnion_Data* data = nullptr;
- mojo::internal::Serialize<ObjectUnionPtr>(obj, &buf, &data, false, &context);
+ mojo::internal::Serialize<ObjectUnionDataView>(obj, &buf, &data, false,
+ &context);
ObjectUnionPtr obj2;
- mojo::internal::Deserialize<ObjectUnionPtr>(data, &obj2, &context);
+ mojo::internal::Deserialize<ObjectUnionDataView>(data, &obj2, &context);
EXPECT_EQ(1, obj2->get_f_map_int8()["one"]);
EXPECT_EQ(2, obj2->get_f_map_int8()["two"]);
@@ -936,17 +952,18 @@ TEST(UnionTest, MapInUnionValidation) {
obj->set_f_map_int8(std::move(map));
mojo::internal::SerializationContext context;
- size_t size =
- mojo::internal::PrepareToSerialize<ObjectUnionPtr>(obj, false, &context);
+ size_t size = mojo::internal::PrepareToSerialize<ObjectUnionDataView>(
+ obj, false, &context);
EXPECT_EQ(112U, size);
mojo::internal::FixedBufferForTesting buf(size);
internal::ObjectUnion_Data* data = nullptr;
- mojo::internal::Serialize<ObjectUnionPtr>(obj, &buf, &data, false, &context);
+ mojo::internal::Serialize<ObjectUnionDataView>(obj, &buf, &data, false,
+ &context);
void* raw_buf = buf.Leak();
mojo::internal::ValidationContext validation_context(
- data, static_cast<uint32_t>(size), 0);
+ data, static_cast<uint32_t>(size), 0, 0);
EXPECT_TRUE(internal::ObjectUnion_Data::Validate(
raw_buf, &validation_context, false));
@@ -970,16 +987,17 @@ TEST(UnionTest, UnionInUnionSerialization) {
ObjectUnionPtr obj(ObjectUnion::New());
obj->set_f_pod_union(std::move(pod));
- size_t size =
- mojo::internal::PrepareToSerialize<ObjectUnionPtr>(obj, false, nullptr);
+ size_t size = mojo::internal::PrepareToSerialize<ObjectUnionDataView>(
+ obj, false, nullptr);
EXPECT_EQ(32U, size);
mojo::internal::FixedBufferForTesting buf(size);
internal::ObjectUnion_Data* data = nullptr;
- mojo::internal::Serialize<ObjectUnionPtr>(obj, &buf, &data, false, nullptr);
+ mojo::internal::Serialize<ObjectUnionDataView>(obj, &buf, &data, false,
+ nullptr);
ObjectUnionPtr obj2;
- mojo::internal::Deserialize<ObjectUnionPtr>(data, &obj2, nullptr);
+ mojo::internal::Deserialize<ObjectUnionDataView>(data, &obj2, nullptr);
EXPECT_EQ(10, obj2->get_f_pod_union()->get_f_int8());
}
@@ -990,17 +1008,18 @@ TEST(UnionTest, UnionInUnionValidation) {
ObjectUnionPtr obj(ObjectUnion::New());
obj->set_f_pod_union(std::move(pod));
- size_t size =
- mojo::internal::PrepareToSerialize<ObjectUnionPtr>(obj, false, nullptr);
+ size_t size = mojo::internal::PrepareToSerialize<ObjectUnionDataView>(
+ obj, false, nullptr);
EXPECT_EQ(32U, size);
mojo::internal::FixedBufferForTesting buf(size);
internal::ObjectUnion_Data* data = nullptr;
- mojo::internal::Serialize<ObjectUnionPtr>(obj, &buf, &data, false, nullptr);
+ mojo::internal::Serialize<ObjectUnionDataView>(obj, &buf, &data, false,
+ nullptr);
void* raw_buf = buf.Leak();
mojo::internal::ValidationContext validation_context(
- data, static_cast<uint32_t>(size), 0);
+ data, static_cast<uint32_t>(size), 0, 0);
EXPECT_TRUE(internal::ObjectUnion_Data::Validate(
raw_buf, &validation_context, false));
free(raw_buf);
@@ -1014,16 +1033,17 @@ TEST(UnionTest, UnionInUnionValidationNonNullable) {
ObjectUnionPtr obj(ObjectUnion::New());
obj->set_f_pod_union(std::move(pod));
- size_t size =
- mojo::internal::PrepareToSerialize<ObjectUnionPtr>(obj, false, nullptr);
+ size_t size = mojo::internal::PrepareToSerialize<ObjectUnionDataView>(
+ obj, false, nullptr);
mojo::internal::FixedBufferForTesting buf(size);
internal::ObjectUnion_Data* data = nullptr;
- mojo::internal::Serialize<ObjectUnionPtr>(obj, &buf, &data, false, nullptr);
+ mojo::internal::Serialize<ObjectUnionDataView>(obj, &buf, &data, false,
+ nullptr);
void* raw_buf = buf.Leak();
mojo::internal::ValidationContext validation_context(
- data, static_cast<uint32_t>(size), 0);
+ data, static_cast<uint32_t>(size), 0, 0);
EXPECT_FALSE(internal::ObjectUnion_Data::Validate(
raw_buf, &validation_context, false));
free(raw_buf);
@@ -1057,18 +1077,18 @@ TEST(UnionTest, HandleInUnionSerialization) {
handle->set_f_message_pipe(std::move(pipe1));
mojo::internal::SerializationContext context;
- size_t size = mojo::internal::PrepareToSerialize<HandleUnionPtr>(
+ size_t size = mojo::internal::PrepareToSerialize<HandleUnionDataView>(
handle, false, &context);
EXPECT_EQ(16U, size);
mojo::internal::FixedBufferForTesting buf(size);
internal::HandleUnion_Data* data = nullptr;
- mojo::internal::Serialize<HandleUnionPtr>(handle, &buf, &data, false,
- &context);
+ mojo::internal::Serialize<HandleUnionDataView>(handle, &buf, &data, false,
+ &context);
EXPECT_EQ(1U, context.handles.size());
HandleUnionPtr handle2(HandleUnion::New());
- mojo::internal::Deserialize<HandleUnionPtr>(data, &handle2, &context);
+ mojo::internal::Deserialize<HandleUnionDataView>(data, &handle2, &context);
std::string golden("hello world");
WriteTextMessage(pipe0.get(), golden);
@@ -1089,18 +1109,18 @@ TEST(UnionTest, HandleInUnionValidation) {
handle->set_f_message_pipe(std::move(pipe1));
mojo::internal::SerializationContext context;
- size_t size = mojo::internal::PrepareToSerialize<HandleUnionPtr>(
+ size_t size = mojo::internal::PrepareToSerialize<HandleUnionDataView>(
handle, false, &context);
EXPECT_EQ(16U, size);
mojo::internal::FixedBufferForTesting buf(size);
internal::HandleUnion_Data* data = nullptr;
- mojo::internal::Serialize<HandleUnionPtr>(handle, &buf, &data, false,
- &context);
+ mojo::internal::Serialize<HandleUnionDataView>(handle, &buf, &data, false,
+ &context);
void* raw_buf = buf.Leak();
mojo::internal::ValidationContext validation_context(
- data, static_cast<uint32_t>(size), 1);
+ data, static_cast<uint32_t>(size), 1, 0);
EXPECT_TRUE(internal::HandleUnion_Data::Validate(
raw_buf, &validation_context, false));
free(raw_buf);
@@ -1114,18 +1134,18 @@ TEST(UnionTest, HandleInUnionValidationNull) {
handle->set_f_message_pipe(std::move(pipe));
mojo::internal::SerializationContext context;
- size_t size = mojo::internal::PrepareToSerialize<HandleUnionPtr>(
+ size_t size = mojo::internal::PrepareToSerialize<HandleUnionDataView>(
handle, false, &context);
EXPECT_EQ(16U, size);
mojo::internal::FixedBufferForTesting buf(size);
internal::HandleUnion_Data* data = nullptr;
- mojo::internal::Serialize<HandleUnionPtr>(handle, &buf, &data, false,
- &context);
+ mojo::internal::Serialize<HandleUnionDataView>(handle, &buf, &data, false,
+ &context);
void* raw_buf = buf.Leak();
mojo::internal::ValidationContext validation_context(
- data, static_cast<uint32_t>(size), 1);
+ data, static_cast<uint32_t>(size), 1, 0);
EXPECT_FALSE(internal::HandleUnion_Data::Validate(
raw_buf, &validation_context, false));
free(raw_buf);
@@ -1156,7 +1176,7 @@ TEST(UnionTest, InterfaceInUnion) {
base::RunLoop run_loop;
SmallCacheImpl impl(run_loop.QuitClosure());
SmallCachePtr ptr;
- Binding<SmallCache> bindings(&impl, GetProxy(&ptr));
+ Binding<SmallCache> bindings(&impl, MakeRequest(&ptr));
HandleUnionPtr handle(HandleUnion::New());
handle->set_f_small_cache(std::move(ptr));
@@ -1171,23 +1191,23 @@ TEST(UnionTest, InterfaceInUnionSerialization) {
base::RunLoop run_loop;
SmallCacheImpl impl(run_loop.QuitClosure());
SmallCachePtr ptr;
- Binding<SmallCache> bindings(&impl, GetProxy(&ptr));
+ Binding<SmallCache> bindings(&impl, MakeRequest(&ptr));
mojo::internal::SerializationContext context;
HandleUnionPtr handle(HandleUnion::New());
handle->set_f_small_cache(std::move(ptr));
- size_t size = mojo::internal::PrepareToSerialize<HandleUnionPtr>(
+ size_t size = mojo::internal::PrepareToSerialize<HandleUnionDataView>(
handle, false, &context);
EXPECT_EQ(16U, size);
mojo::internal::FixedBufferForTesting buf(size);
internal::HandleUnion_Data* data = nullptr;
- mojo::internal::Serialize<HandleUnionPtr>(handle, &buf, &data, false,
- &context);
+ mojo::internal::Serialize<HandleUnionDataView>(handle, &buf, &data, false,
+ &context);
EXPECT_EQ(1U, context.handles.size());
HandleUnionPtr handle2(HandleUnion::New());
- mojo::internal::Deserialize<HandleUnionPtr>(data, &handle2, &context);
+ mojo::internal::Deserialize<HandleUnionDataView>(data, &handle2, &context);
handle2->get_f_small_cache()->SetIntValue(10);
run_loop.Run();
@@ -1213,7 +1233,7 @@ TEST(UnionTest, UnionInInterface) {
base::MessageLoop message_loop;
UnionInterfaceImpl impl;
UnionInterfacePtr ptr;
- Binding<UnionInterface> bindings(&impl, GetProxy(&ptr));
+ Binding<UnionInterface> bindings(&impl, MakeRequest(&ptr));
PodUnionPtr pod(PodUnion::New());
pod->set_f_int16(16);
diff --git a/mojo/public/cpp/bindings/tests/validation_context_unittest.cc b/mojo/public/cpp/bindings/tests/validation_context_unittest.cc
index aceaf1c..9ce9d60 100644
--- a/mojo/public/cpp/bindings/tests/validation_context_unittest.cc
+++ b/mojo/public/cpp/bindings/tests/validation_context_unittest.cc
@@ -17,6 +17,8 @@ namespace test {
namespace {
using Handle_Data = mojo::internal::Handle_Data;
+using AssociatedEndpointHandle_Data =
+ mojo::internal::AssociatedEndpointHandle_Data;
const void* ToPtr(uintptr_t ptr) {
return reinterpret_cast<const void*>(ptr);
@@ -27,7 +29,7 @@ TEST(ValidationContextTest, ConstructorRangeOverflow) {
{
// Test memory range overflow.
internal::ValidationContext context(
- ToPtr(std::numeric_limits<uintptr_t>::max() - 3000), 5000, 0);
+ ToPtr(std::numeric_limits<uintptr_t>::max() - 3000), 5000, 0, 0);
EXPECT_FALSE(context.IsValidRange(
ToPtr(std::numeric_limits<uintptr_t>::max() - 3000), 1));
@@ -35,11 +37,14 @@ TEST(ValidationContextTest, ConstructorRangeOverflow) {
ToPtr(std::numeric_limits<uintptr_t>::max() - 3000), 1));
}
- if (sizeof(size_t) > sizeof(uint32_t)) {
+ if (sizeof(size_t) <= sizeof(uint32_t))
+ return;
+
+ {
// Test handle index range overflow.
size_t num_handles =
static_cast<size_t>(std::numeric_limits<uint32_t>::max()) + 5;
- internal::ValidationContext context(ToPtr(0), 0, num_handles);
+ internal::ValidationContext context(ToPtr(0), 0, num_handles, 0);
EXPECT_FALSE(context.ClaimHandle(Handle_Data(0)));
EXPECT_FALSE(context.ClaimHandle(
@@ -48,12 +53,28 @@ TEST(ValidationContextTest, ConstructorRangeOverflow) {
EXPECT_TRUE(context.ClaimHandle(
Handle_Data(internal::kEncodedInvalidHandleValue)));
}
+
+ {
+ size_t num_associated_endpoint_handles =
+ static_cast<size_t>(std::numeric_limits<uint32_t>::max()) + 5;
+ internal::ValidationContext context(ToPtr(0), 0, 0,
+ num_associated_endpoint_handles);
+
+ EXPECT_FALSE(context.ClaimAssociatedEndpointHandle(
+ AssociatedEndpointHandle_Data(0)));
+ EXPECT_FALSE(
+ context.ClaimAssociatedEndpointHandle(AssociatedEndpointHandle_Data(
+ std::numeric_limits<uint32_t>::max() - 1)));
+
+ EXPECT_TRUE(context.ClaimAssociatedEndpointHandle(
+ AssociatedEndpointHandle_Data(internal::kEncodedInvalidHandleValue)));
+ }
}
#endif
TEST(ValidationContextTest, IsValidRange) {
{
- internal::ValidationContext context(ToPtr(1234), 100, 0);
+ internal::ValidationContext context(ToPtr(1234), 100, 0, 0);
// Basics.
EXPECT_FALSE(context.IsValidRange(ToPtr(100), 5));
@@ -79,7 +100,7 @@ TEST(ValidationContextTest, IsValidRange) {
}
{
- internal::ValidationContext context(ToPtr(1234), 100, 0);
+ internal::ValidationContext context(ToPtr(1234), 100, 0, 0);
// Should return false for empty ranges.
EXPECT_FALSE(context.IsValidRange(ToPtr(0), 0));
EXPECT_FALSE(context.IsValidRange(ToPtr(1200), 0));
@@ -90,7 +111,7 @@ TEST(ValidationContextTest, IsValidRange) {
{
// The valid memory range is empty.
- internal::ValidationContext context(ToPtr(1234), 0, 0);
+ internal::ValidationContext context(ToPtr(1234), 0, 0, 0);
EXPECT_FALSE(context.IsValidRange(ToPtr(1234), 1));
EXPECT_FALSE(context.IsValidRange(ToPtr(1234), 0));
@@ -98,7 +119,7 @@ TEST(ValidationContextTest, IsValidRange) {
{
internal::ValidationContext context(
- ToPtr(std::numeric_limits<uintptr_t>::max() - 2000), 1000, 0);
+ ToPtr(std::numeric_limits<uintptr_t>::max() - 2000), 1000, 0, 0);
// Test overflow.
EXPECT_FALSE(context.IsValidRange(
@@ -115,7 +136,7 @@ TEST(ValidationContextTest, IsValidRange) {
TEST(ValidationContextTest, ClaimHandle) {
{
- internal::ValidationContext context(ToPtr(0), 0, 10);
+ internal::ValidationContext context(ToPtr(0), 0, 10, 0);
// Basics.
EXPECT_TRUE(context.ClaimHandle(Handle_Data(0)));
@@ -137,7 +158,7 @@ TEST(ValidationContextTest, ClaimHandle) {
{
// No handle to claim.
- internal::ValidationContext context(ToPtr(0), 0, 0);
+ internal::ValidationContext context(ToPtr(0), 0, 0, 0);
EXPECT_FALSE(context.ClaimHandle(Handle_Data(0)));
@@ -152,7 +173,7 @@ TEST(ValidationContextTest, ClaimHandle) {
EXPECT_EQ(internal::kEncodedInvalidHandleValue,
std::numeric_limits<uint32_t>::max());
internal::ValidationContext context(
- ToPtr(0), 0, std::numeric_limits<uint32_t>::max());
+ ToPtr(0), 0, std::numeric_limits<uint32_t>::max(), 0);
EXPECT_TRUE(context.ClaimHandle(
Handle_Data(std::numeric_limits<uint32_t>::max() - 1)));
@@ -166,9 +187,71 @@ TEST(ValidationContextTest, ClaimHandle) {
}
}
+TEST(ValidationContextTest, ClaimAssociatedEndpointHandle) {
+ {
+ internal::ValidationContext context(ToPtr(0), 0, 0, 10);
+
+ // Basics.
+ EXPECT_TRUE(context.ClaimAssociatedEndpointHandle(
+ AssociatedEndpointHandle_Data(0)));
+ EXPECT_FALSE(context.ClaimAssociatedEndpointHandle(
+ AssociatedEndpointHandle_Data(0)));
+
+ EXPECT_TRUE(context.ClaimAssociatedEndpointHandle(
+ AssociatedEndpointHandle_Data(9)));
+ EXPECT_FALSE(context.ClaimAssociatedEndpointHandle(
+ AssociatedEndpointHandle_Data(10)));
+
+ // Should fail because it is smaller than the max index that has been
+ // claimed.
+ EXPECT_FALSE(context.ClaimAssociatedEndpointHandle(
+ AssociatedEndpointHandle_Data(8)));
+
+ // Should return true for invalid handle.
+ EXPECT_TRUE(context.ClaimAssociatedEndpointHandle(
+ AssociatedEndpointHandle_Data(internal::kEncodedInvalidHandleValue)));
+ EXPECT_TRUE(context.ClaimAssociatedEndpointHandle(
+ AssociatedEndpointHandle_Data(internal::kEncodedInvalidHandleValue)));
+ }
+
+ {
+ // No handle to claim.
+ internal::ValidationContext context(ToPtr(0), 0, 0, 0);
+
+ EXPECT_FALSE(context.ClaimAssociatedEndpointHandle(
+ AssociatedEndpointHandle_Data(0)));
+
+ // Should still return true for invalid handle.
+ EXPECT_TRUE(context.ClaimAssociatedEndpointHandle(
+ AssociatedEndpointHandle_Data(internal::kEncodedInvalidHandleValue)));
+ }
+
+ {
+ // Test the case that |num_associated_endpoint_handles| is the same value as
+ // |internal::kEncodedInvalidHandleValue|.
+ EXPECT_EQ(internal::kEncodedInvalidHandleValue,
+ std::numeric_limits<uint32_t>::max());
+ internal::ValidationContext context(ToPtr(0), 0, 0,
+ std::numeric_limits<uint32_t>::max());
+
+ EXPECT_TRUE(
+ context.ClaimAssociatedEndpointHandle(AssociatedEndpointHandle_Data(
+ std::numeric_limits<uint32_t>::max() - 1)));
+ EXPECT_FALSE(
+ context.ClaimAssociatedEndpointHandle(AssociatedEndpointHandle_Data(
+ std::numeric_limits<uint32_t>::max() - 1)));
+ EXPECT_FALSE(context.ClaimAssociatedEndpointHandle(
+ AssociatedEndpointHandle_Data(0)));
+
+ // Should still return true for invalid handle.
+ EXPECT_TRUE(context.ClaimAssociatedEndpointHandle(
+ AssociatedEndpointHandle_Data(internal::kEncodedInvalidHandleValue)));
+ }
+}
+
TEST(ValidationContextTest, ClaimMemory) {
{
- internal::ValidationContext context(ToPtr(1000), 2000, 0);
+ internal::ValidationContext context(ToPtr(1000), 2000, 0, 0);
// Basics.
EXPECT_FALSE(context.ClaimMemory(ToPtr(500), 100));
@@ -186,7 +269,7 @@ TEST(ValidationContextTest, ClaimMemory) {
{
// No memory to claim.
- internal::ValidationContext context(ToPtr(10000), 0, 0);
+ internal::ValidationContext context(ToPtr(10000), 0, 0, 0);
EXPECT_FALSE(context.ClaimMemory(ToPtr(10000), 1));
EXPECT_FALSE(context.ClaimMemory(ToPtr(10000), 0));
@@ -194,7 +277,7 @@ TEST(ValidationContextTest, ClaimMemory) {
{
internal::ValidationContext context(
- ToPtr(std::numeric_limits<uintptr_t>::max() - 1000), 500, 0);
+ ToPtr(std::numeric_limits<uintptr_t>::max() - 1000), 500, 0, 0);
// Test overflow.
EXPECT_FALSE(context.ClaimMemory(
diff --git a/mojo/public/cpp/bindings/tests/validation_unittest.cc b/mojo/public/cpp/bindings/tests/validation_unittest.cc
index d254383..7af7396 100644
--- a/mojo/public/cpp/bindings/tests/validation_unittest.cc
+++ b/mojo/public/cpp/bindings/tests/validation_unittest.cc
@@ -16,9 +16,8 @@
#include "mojo/public/c/system/macros.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "mojo/public/cpp/bindings/connector.h"
+#include "mojo/public/cpp/bindings/filter_chain.h"
#include "mojo/public/cpp/bindings/interface_ptr.h"
-#include "mojo/public/cpp/bindings/lib/filter_chain.h"
-#include "mojo/public/cpp/bindings/lib/router.h"
#include "mojo/public/cpp/bindings/lib/validation_errors.h"
#include "mojo/public/cpp/bindings/message.h"
#include "mojo/public/cpp/bindings/message_header_validator.h"
@@ -266,7 +265,7 @@ class IntegrationTestInterfaceImpl : public IntegrationTestInterface {
void Method0(BasicStructPtr param0,
const Method0Callback& callback) override {
- callback.Run(Array<uint8_t>::New(0u));
+ callback.Run(std::vector<uint8_t>());
}
};
@@ -376,20 +375,20 @@ TEST_F(ValidationTest, InputParser) {
TEST_F(ValidationTest, Conformance) {
DummyMessageReceiver dummy_receiver;
- mojo::internal::FilterChain validators(&dummy_receiver);
+ mojo::FilterChain validators(&dummy_receiver);
validators.Append<mojo::MessageHeaderValidator>();
validators.Append<ConformanceTestInterface::RequestValidator_>();
- RunValidationTests("conformance_", validators.GetHead());
+ RunValidationTests("conformance_", &validators);
}
TEST_F(ValidationTest, AssociatedConformace) {
DummyMessageReceiver dummy_receiver;
- mojo::internal::FilterChain validators(&dummy_receiver);
+ mojo::FilterChain validators(&dummy_receiver);
validators.Append<mojo::MessageHeaderValidator>();
validators.Append<AssociatedConformanceTestInterface::RequestValidator_>();
- RunValidationTests("associated_conformance_", validators.GetHead());
+ RunValidationTests("associated_conformance_", &validators);
}
// This test is similar to Conformance test but its goal is specifically
@@ -397,31 +396,31 @@ TEST_F(ValidationTest, AssociatedConformace) {
// detection of off-by-one errors in method ordinals.
TEST_F(ValidationTest, BoundsCheck) {
DummyMessageReceiver dummy_receiver;
- mojo::internal::FilterChain validators(&dummy_receiver);
+ mojo::FilterChain validators(&dummy_receiver);
validators.Append<mojo::MessageHeaderValidator>();
validators.Append<BoundsCheckTestInterface::RequestValidator_>();
- RunValidationTests("boundscheck_", validators.GetHead());
+ RunValidationTests("boundscheck_", &validators);
}
// This test is similar to the Conformance test but for responses.
TEST_F(ValidationTest, ResponseConformance) {
DummyMessageReceiver dummy_receiver;
- mojo::internal::FilterChain validators(&dummy_receiver);
+ mojo::FilterChain validators(&dummy_receiver);
validators.Append<mojo::MessageHeaderValidator>();
validators.Append<ConformanceTestInterface::ResponseValidator_>();
- RunValidationTests("resp_conformance_", validators.GetHead());
+ RunValidationTests("resp_conformance_", &validators);
}
// This test is similar to the BoundsCheck test but for responses.
TEST_F(ValidationTest, ResponseBoundsCheck) {
DummyMessageReceiver dummy_receiver;
- mojo::internal::FilterChain validators(&dummy_receiver);
+ mojo::FilterChain validators(&dummy_receiver);
validators.Append<mojo::MessageHeaderValidator>();
validators.Append<BoundsCheckTestInterface::ResponseValidator_>();
- RunValidationTests("resp_boundscheck_", validators.GetHead());
+ RunValidationTests("resp_boundscheck_", &validators);
}
// Test that InterfacePtr<X> applies the correct validators and they don't
diff --git a/mojo/public/cpp/bindings/tests/versioning_apptest.cc b/mojo/public/cpp/bindings/tests/versioning_apptest.cc
index 3a08cdd..95a89c0 100644
--- a/mojo/public/cpp/bindings/tests/versioning_apptest.cc
+++ b/mojo/public/cpp/bindings/tests/versioning_apptest.cc
@@ -7,8 +7,8 @@
#include "base/macros.h"
#include "mojo/public/interfaces/bindings/tests/versioning_test_client.mojom.h"
-#include "services/shell/public/cpp/application_test_base.h"
-#include "services/shell/public/cpp/connector.h"
+#include "services/service_manager/public/cpp/application_test_base.h"
+#include "services/service_manager/public/cpp/connector.h"
namespace mojo {
namespace test {
@@ -24,7 +24,7 @@ class VersioningApplicationTest : public ApplicationTestBase {
void SetUp() override {
ApplicationTestBase::SetUp();
- connector()->ConnectToInterface("mojo:versioning_test_service", &database_);
+ connector()->BindInterface("versioning_test_service", &database_);
}
HumanResourceDatabasePtr database_;
diff --git a/mojo/public/cpp/bindings/tests/versioning_test_service.cc b/mojo/public/cpp/bindings/tests/versioning_test_service.cc
index 2f554d9..313a624 100644
--- a/mojo/public/cpp/bindings/tests/versioning_test_service.cc
+++ b/mojo/public/cpp/bindings/tests/versioning_test_service.cc
@@ -8,12 +8,12 @@
#include <utility>
#include "base/macros.h"
-#include "mojo/public/c/system/main.h"
#include "mojo/public/cpp/bindings/strong_binding.h"
#include "mojo/public/interfaces/bindings/tests/versioning_test_service.mojom.h"
-#include "services/shell/public/cpp/application_runner.h"
-#include "services/shell/public/cpp/interface_factory.h"
-#include "services/shell/public/cpp/service.h"
+#include "services/service_manager/public/c/main.h"
+#include "services/service_manager/public/cpp/interface_factory.h"
+#include "services/service_manager/public/cpp/service.h"
+#include "services/service_manager/public/cpp/service_runner.h"
namespace mojo {
namespace test {
@@ -95,12 +95,12 @@ class HumanResourceDatabaseImpl : public HumanResourceDatabase {
};
class HumanResourceSystemServer
- : public shell::Service,
+ : public service_manager::Service,
public InterfaceFactory<HumanResourceDatabase> {
public:
HumanResourceSystemServer() {}
- // shell::Service implementation.
+ // service_manager::Service implementation.
bool OnConnect(Connection* connection) override {
connection->AddInterface<HumanResourceDatabase>(this);
return true;
@@ -119,8 +119,8 @@ class HumanResourceSystemServer
} // namespace test
} // namespace mojo
-MojoResult MojoMain(MojoHandle request) {
- mojo::ApplicationRunner runner(
+MojoResult ServiceMain(MojoHandle request) {
+ mojo::ServiceRunner runner(
new mojo::test::versioning::HumanResourceSystemServer());
return runner.Run(request);
diff --git a/mojo/public/cpp/bindings/tests/wtf_array_unittest.cc b/mojo/public/cpp/bindings/tests/wtf_array_unittest.cc
deleted file mode 100644
index bb54b9c..0000000
--- a/mojo/public/cpp/bindings/tests/wtf_array_unittest.cc
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright 2016 The Chromium 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 "mojo/public/cpp/bindings/wtf_array.h"
-
-#include "mojo/public/cpp/bindings/lib/serialization.h"
-#include "mojo/public/cpp/bindings/lib/wtf_serialization.h"
-#include "mojo/public/cpp/bindings/tests/array_common_test.h"
-#include "mojo/public/cpp/bindings/tests/container_test_util.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace mojo {
-namespace test {
-namespace {
-
-using WTFArrayTest = testing::Test;
-
-ARRAY_COMMON_TEST(WTFArray, NullAndEmpty)
-ARRAY_COMMON_TEST(WTFArray, Basic)
-ARRAY_COMMON_TEST(WTFArray, Bool)
-ARRAY_COMMON_TEST(WTFArray, Handle)
-ARRAY_COMMON_TEST(WTFArray, HandlesAreClosed)
-ARRAY_COMMON_TEST(WTFArray, Clone)
-ARRAY_COMMON_TEST(WTFArray, Serialization_ArrayOfPOD)
-ARRAY_COMMON_TEST(WTFArray, Serialization_EmptyArrayOfPOD)
-ARRAY_COMMON_TEST(WTFArray, Serialization_ArrayOfArrayOfPOD)
-ARRAY_COMMON_TEST(WTFArray, Serialization_ArrayOfBool)
-ARRAY_COMMON_TEST(WTFArray, Serialization_ArrayOfString)
-ARRAY_COMMON_TEST(WTFArray, Resize_Copyable)
-ARRAY_COMMON_TEST(WTFArray, Resize_MoveOnly)
-
-TEST_F(WTFArrayTest, MoveFromAndToWTFVector_Copyable) {
- WTF::Vector<CopyableType> vec1(1);
- WTFArray<CopyableType> arr(std::move(vec1));
- ASSERT_EQ(1u, arr.size());
- ASSERT_FALSE(arr[0].copied());
-
- WTF::Vector<CopyableType> vec2(arr.PassStorage());
- ASSERT_EQ(1u, vec2.size());
- ASSERT_FALSE(vec2[0].copied());
-
- ASSERT_EQ(0u, arr.size());
- ASSERT_TRUE(arr.is_null());
-}
-
-TEST_F(WTFArrayTest, MoveFromAndToWTFVector_MoveOnly) {
- WTF::Vector<MoveOnlyType> vec1(1);
- WTFArray<MoveOnlyType> arr(std::move(vec1));
-
- ASSERT_EQ(1u, arr.size());
-
- WTF::Vector<MoveOnlyType> vec2(arr.PassStorage());
- ASSERT_EQ(1u, vec2.size());
-
- ASSERT_EQ(0u, arr.size());
- ASSERT_TRUE(arr.is_null());
-}
-
-} // namespace
-} // namespace test
-} // namespace mojo
diff --git a/mojo/public/cpp/bindings/tests/wtf_hash_unittest.cc b/mojo/public/cpp/bindings/tests/wtf_hash_unittest.cc
new file mode 100644
index 0000000..959d25b
--- /dev/null
+++ b/mojo/public/cpp/bindings/tests/wtf_hash_unittest.cc
@@ -0,0 +1,60 @@
+// Copyright 2016 The Chromium 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 "mojo/public/cpp/bindings/lib/wtf_hash_util.h"
+
+#include "mojo/public/interfaces/bindings/tests/test_structs.mojom-blink.h"
+#include "mojo/public/interfaces/bindings/tests/test_wtf_types.mojom-blink.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/WebKit/Source/wtf/HashFunctions.h"
+
+namespace mojo {
+namespace test {
+namespace {
+
+using WTFHashTest = testing::Test;
+
+TEST_F(WTFHashTest, NestedStruct) {
+ // Just check that this template instantiation compiles.
+ ASSERT_EQ(::mojo::internal::Hash(
+ ::mojo::internal::kHashSeed,
+ blink::SimpleNestedStruct::New(blink::ContainsOther::New(1))),
+ ::mojo::internal::Hash(
+ ::mojo::internal::kHashSeed,
+ blink::SimpleNestedStruct::New(blink::ContainsOther::New(1))));
+}
+
+TEST_F(WTFHashTest, UnmappedNativeStruct) {
+ // Just check that this template instantiation compiles.
+ ASSERT_EQ(::mojo::internal::Hash(::mojo::internal::kHashSeed,
+ blink::UnmappedNativeStruct::New()),
+ ::mojo::internal::Hash(::mojo::internal::kHashSeed,
+ blink::UnmappedNativeStruct::New()));
+}
+
+TEST_F(WTFHashTest, Enum) {
+ // Just check that this template instantiation compiles.
+
+ // Top-level.
+ ASSERT_EQ(WTF::DefaultHash<blink::TopLevelEnum>::Hash().hash(
+ blink::TopLevelEnum::E0),
+ WTF::DefaultHash<blink::TopLevelEnum>::Hash().hash(
+ blink::TopLevelEnum::E0));
+
+ // Nested in struct.
+ ASSERT_EQ(WTF::DefaultHash<blink::TestWTFStruct::NestedEnum>::Hash().hash(
+ blink::TestWTFStruct::NestedEnum::E0),
+ WTF::DefaultHash<blink::TestWTFStruct::NestedEnum>::Hash().hash(
+ blink::TestWTFStruct::NestedEnum::E0));
+
+ // Nested in interface.
+ ASSERT_EQ(WTF::DefaultHash<blink::TestWTF::NestedEnum>::Hash().hash(
+ blink::TestWTF::NestedEnum::E0),
+ WTF::DefaultHash<blink::TestWTF::NestedEnum>::Hash().hash(
+ blink::TestWTF::NestedEnum::E0));
+}
+
+} // namespace
+} // namespace test
+} // namespace mojo
diff --git a/mojo/public/cpp/bindings/tests/wtf_map_unittest.cc b/mojo/public/cpp/bindings/tests/wtf_map_unittest.cc
index a70c134..5028087 100644
--- a/mojo/public/cpp/bindings/tests/wtf_map_unittest.cc
+++ b/mojo/public/cpp/bindings/tests/wtf_map_unittest.cc
@@ -1,65 +1,39 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
+// Copyright 2017 The Chromium 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 "mojo/public/cpp/bindings/wtf_map.h"
-
-#include "mojo/public/cpp/bindings/lib/wtf_serialization.h"
-#include "mojo/public/cpp/bindings/tests/container_test_util.h"
-#include "mojo/public/cpp/bindings/tests/map_common_test.h"
-#include "mojo/public/cpp/bindings/wtf_array.h"
+#include "mojo/public/cpp/bindings/tests/rect_blink.h"
+#include "mojo/public/interfaces/bindings/tests/rect.mojom-blink.h"
+#include "mojo/public/interfaces/bindings/tests/test_structs.mojom-blink.h"
#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/WebKit/Source/wtf/text/WTFString.h"
namespace mojo {
namespace test {
-
namespace {
-using WTFMapTest = testing::Test;
-
-MAP_COMMON_TEST(WTFMap, NullAndEmpty)
-MAP_COMMON_TEST(WTFMap, InsertWorks)
-MAP_COMMON_TEST(WTFMap, TestIndexOperator)
-MAP_COMMON_TEST(WTFMap, TestIndexOperatorAsRValue)
-MAP_COMMON_TEST(WTFMap, TestIndexOperatorMoveOnly)
-MAP_COMMON_TEST(WTFMap, MapArrayClone)
-MAP_COMMON_TEST(WTFMap, ArrayOfMap)
+TEST(WTFMapTest, StructKey) {
+ WTF::HashMap<blink::RectPtr, int32_t> map;
+ map.insert(blink::Rect::New(1, 2, 3, 4), 123);
-TEST_F(WTFMapTest, MoveFromAndToWTFHashMap_Copyable) {
- WTF::HashMap<int32_t, CopyableType> map1;
- map1.add(123, CopyableType());
- map1.find(123)->value.ResetCopied();
- ASSERT_FALSE(map1.find(123)->value.copied());
+ blink::RectPtr key = blink::Rect::New(1, 2, 3, 4);
+ ASSERT_NE(map.end(), map.find(key));
+ ASSERT_EQ(123, map.find(key)->value);
- WTFMap<int32_t, CopyableType> mojo_map(std::move(map1));
- ASSERT_EQ(1u, mojo_map.size());
- ASSERT_NE(mojo_map.end(), mojo_map.find(123));
- ASSERT_FALSE(mojo_map[123].copied());
-
- WTF::HashMap<int32_t, CopyableType> map2(mojo_map.PassStorage());
- ASSERT_EQ(1u, map2.size());
- ASSERT_NE(map2.end(), map2.find(123));
- ASSERT_FALSE(map2.find(123)->value.copied());
-
- ASSERT_EQ(0u, mojo_map.size());
- ASSERT_TRUE(mojo_map.is_null());
+ map.remove(key);
+ ASSERT_EQ(0u, map.size());
}
-TEST_F(WTFMapTest, MoveFromAndToWTFHashMap_MoveOnly) {
- WTF::HashMap<int32_t, MoveOnlyType> map1;
- map1.add(123, MoveOnlyType());
-
- WTFMap<int32_t, MoveOnlyType> mojo_map(std::move(map1));
- ASSERT_EQ(1u, mojo_map.size());
- ASSERT_NE(mojo_map.end(), mojo_map.find(123));
+TEST(WTFMapTest, TypemappedStructKey) {
+ WTF::HashMap<blink::ContainsHashablePtr, int32_t> map;
+ map.insert(blink::ContainsHashable::New(RectBlink(1, 2, 3, 4)), 123);
- WTF::HashMap<int32_t, MoveOnlyType> map2(mojo_map.PassStorage());
- ASSERT_EQ(1u, map2.size());
- ASSERT_NE(map2.end(), map2.find(123));
+ blink::ContainsHashablePtr key =
+ blink::ContainsHashable::New(RectBlink(1, 2, 3, 4));
+ ASSERT_NE(map.end(), map.find(key));
+ ASSERT_EQ(123, map.find(key)->value);
- ASSERT_EQ(0u, mojo_map.size());
- ASSERT_TRUE(mojo_map.is_null());
+ map.remove(key);
+ ASSERT_EQ(0u, map.size());
}
} // namespace
diff --git a/mojo/public/cpp/bindings/tests/wtf_types_unittest.cc b/mojo/public/cpp/bindings/tests/wtf_types_unittest.cc
index 97392d4..363ef7c 100644
--- a/mojo/public/cpp/bindings/tests/wtf_types_unittest.cc
+++ b/mojo/public/cpp/bindings/tests/wtf_types_unittest.cc
@@ -14,6 +14,7 @@
#include "mojo/public/interfaces/bindings/tests/test_wtf_types.mojom-blink.h"
#include "mojo/public/interfaces/bindings/tests/test_wtf_types.mojom.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/WebKit/Source/wtf/text/StringHash.h"
namespace mojo {
namespace test {
@@ -75,9 +76,9 @@ WTF::Vector<WTF::String> ConstructStringArray() {
WTF::HashMap<WTF::String, WTF::String> ConstructStringMap() {
WTF::HashMap<WTF::String, WTF::String> str_map;
// A null string as value.
- str_map.add("0", WTF::String());
- str_map.add("1", kHelloWorld);
- str_map.add("2", WTF::String::fromUTF8(kUTF8HelloWorld));
+ str_map.insert("0", WTF::String());
+ str_map.insert("1", kHelloWorld);
+ str_map.insert("2", WTF::String::fromUTF8(kUTF8HelloWorld));
return str_map;
}
@@ -106,140 +107,62 @@ void ExpectStringMap(
} // namespace
-TEST_F(WTFTypesTest, Serialization_WTFArrayToWTFArray) {
- WTFArray<WTF::String> strs = ConstructStringArray();
- auto cloned_strs = strs.Clone();
-
- mojo::internal::SerializationContext context;
- size_t size = mojo::internal::PrepareToSerialize<Array<mojo::String>>(
- cloned_strs, &context);
-
- mojo::internal::FixedBufferForTesting buf(size);
- typename mojo::internal::MojomTypeTraits<Array<mojo::String>>::Data* data;
- mojo::internal::ContainerValidateParams validate_params(
- 0, true, new mojo::internal::ContainerValidateParams(0, false, nullptr));
- mojo::internal::Serialize<Array<mojo::String>>(cloned_strs, &buf, &data,
- &validate_params, &context);
-
- WTFArray<WTF::String> strs2;
- mojo::internal::Deserialize<Array<mojo::String>>(data, &strs2, &context);
-
- EXPECT_TRUE(strs.Equals(strs2));
-}
-
TEST_F(WTFTypesTest, Serialization_WTFVectorToWTFVector) {
+ using MojomType = ArrayDataView<StringDataView>;
+
WTF::Vector<WTF::String> strs = ConstructStringArray();
auto cloned_strs = strs;
mojo::internal::SerializationContext context;
- size_t size = mojo::internal::PrepareToSerialize<Array<mojo::String>>(
- cloned_strs, &context);
+ size_t size =
+ mojo::internal::PrepareToSerialize<MojomType>(cloned_strs, &context);
mojo::internal::FixedBufferForTesting buf(size);
- typename mojo::internal::MojomTypeTraits<Array<mojo::String>>::Data* data;
+ typename mojo::internal::MojomTypeTraits<MojomType>::Data* data;
mojo::internal::ContainerValidateParams validate_params(
0, true, new mojo::internal::ContainerValidateParams(0, false, nullptr));
- mojo::internal::Serialize<Array<mojo::String>>(cloned_strs, &buf, &data,
- &validate_params, &context);
+ mojo::internal::Serialize<MojomType>(cloned_strs, &buf, &data,
+ &validate_params, &context);
WTF::Vector<WTF::String> strs2;
- mojo::internal::Deserialize<Array<mojo::String>>(data, &strs2, &context);
+ mojo::internal::Deserialize<MojomType>(data, &strs2, &context);
EXPECT_EQ(strs, strs2);
}
-TEST_F(WTFTypesTest, Serialization_WTFArrayToMojoArray) {
- WTFArray<WTF::String> strs = ConstructStringArray();
-
- mojo::internal::SerializationContext context;
- size_t size =
- mojo::internal::PrepareToSerialize<Array<mojo::String>>(strs, &context);
-
- mojo::internal::FixedBufferForTesting buf(size);
- typename mojo::internal::MojomTypeTraits<Array<mojo::String>>::Data* data;
- mojo::internal::ContainerValidateParams validate_params(
- 0, true, new mojo::internal::ContainerValidateParams(0, false, nullptr));
- mojo::internal::Serialize<Array<mojo::String>>(strs, &buf, &data,
- &validate_params, &context);
-
- Array<mojo::String> strs2;
- mojo::internal::Deserialize<Array<mojo::String>>(data, &strs2, &context);
-
- ASSERT_EQ(4u, strs2.size());
- EXPECT_TRUE(strs2[0].is_null());
- EXPECT_TRUE("" == strs2[1]);
- EXPECT_TRUE(kHelloWorld == strs2[2]);
- EXPECT_TRUE(kUTF8HelloWorld == strs2[3]);
-}
-
-TEST_F(WTFTypesTest, Serialization_WTFMapToWTFMap) {
- using WTFType = WTFMap<WTF::String, WTF::String>;
- using MojomType = Map<mojo::String, mojo::String>;
+TEST_F(WTFTypesTest, Serialization_WTFVectorToStlVector) {
+ using MojomType = ArrayDataView<StringDataView>;
- WTFType str_map = ConstructStringMap();
- WTFType cloned_str_map = str_map.Clone();
+ WTF::Vector<WTF::String> strs = ConstructStringArray();
+ auto cloned_strs = strs;
mojo::internal::SerializationContext context;
size_t size =
- mojo::internal::PrepareToSerialize<MojomType>(cloned_str_map, &context);
+ mojo::internal::PrepareToSerialize<MojomType>(cloned_strs, &context);
mojo::internal::FixedBufferForTesting buf(size);
typename mojo::internal::MojomTypeTraits<MojomType>::Data* data;
mojo::internal::ContainerValidateParams validate_params(
- new mojo::internal::ContainerValidateParams(
- 0, false,
- new mojo::internal::ContainerValidateParams(0, false, nullptr)),
- new mojo::internal::ContainerValidateParams(
- 0, true,
- new mojo::internal::ContainerValidateParams(0, false, nullptr)));
- mojo::internal::Serialize<MojomType>(cloned_str_map, &buf, &data,
+ 0, true, new mojo::internal::ContainerValidateParams(0, false, nullptr));
+ mojo::internal::Serialize<MojomType>(cloned_strs, &buf, &data,
&validate_params, &context);
- WTFType str_map2;
- mojo::internal::Deserialize<MojomType>(data, &str_map2, &context);
-
- EXPECT_TRUE(str_map.Equals(str_map2));
-}
-
-TEST_F(WTFTypesTest, Serialization_WTFMapToMojoMap) {
- using WTFType = WTFMap<WTF::String, WTF::String>;
- using MojomType = Map<mojo::String, mojo::String>;
-
- WTFType str_map = ConstructStringMap();
-
- mojo::internal::SerializationContext context;
- size_t size =
- mojo::internal::PrepareToSerialize<MojomType>(str_map, &context);
+ std::vector<base::Optional<std::string>> strs2;
+ mojo::internal::Deserialize<MojomType>(data, &strs2, &context);
- mojo::internal::FixedBufferForTesting buf(size);
- typename mojo::internal::MojomTypeTraits<MojomType>::Data* data;
- mojo::internal::ContainerValidateParams validate_params(
- new mojo::internal::ContainerValidateParams(
- 0, false,
- new mojo::internal::ContainerValidateParams(0, false, nullptr)),
- new mojo::internal::ContainerValidateParams(
- 0, true,
- new mojo::internal::ContainerValidateParams(0, false, nullptr)));
- mojo::internal::Serialize<MojomType>(str_map, &buf, &data, &validate_params,
- &context);
-
- MojomType str_map2;
- mojo::internal::Deserialize<MojomType>(data, &str_map2, &context);
-
- ASSERT_EQ(3u, str_map2.size());
- EXPECT_TRUE(str_map2["0"].is_null());
- EXPECT_TRUE(kHelloWorld == str_map2["1"]);
- EXPECT_TRUE(kUTF8HelloWorld == str_map2["2"]);
+ ASSERT_EQ(4u, strs2.size());
+ EXPECT_FALSE(strs2[0]);
+ EXPECT_EQ("", *strs2[1]);
+ EXPECT_EQ(kHelloWorld, *strs2[2]);
+ EXPECT_EQ(kUTF8HelloWorld, *strs2[3]);
}
TEST_F(WTFTypesTest, Serialization_PublicAPI) {
- blink::TestWTFStructPtr input(blink::TestWTFStruct::New());
- input->str = kHelloWorld;
- input->integer = 42;
+ blink::TestWTFStructPtr input(blink::TestWTFStruct::New(kHelloWorld, 42));
blink::TestWTFStructPtr cloned_input = input.Clone();
- WTFArray<uint8_t> data = blink::TestWTFStruct::Serialize(&input);
+ auto data = blink::TestWTFStruct::Serialize(&input);
blink::TestWTFStructPtr output;
ASSERT_TRUE(blink::TestWTFStruct::Deserialize(std::move(data), &output));
@@ -248,7 +171,7 @@ TEST_F(WTFTypesTest, Serialization_PublicAPI) {
TEST_F(WTFTypesTest, SendString) {
blink::TestWTFPtr ptr;
- TestWTFImpl impl(ConvertInterfaceRequest<TestWTF>(GetProxy(&ptr)));
+ TestWTFImpl impl(ConvertInterfaceRequest<TestWTF>(MakeRequest(&ptr)));
WTF::Vector<WTF::String> strs = ConstructStringArray();
@@ -267,7 +190,7 @@ TEST_F(WTFTypesTest, SendString) {
TEST_F(WTFTypesTest, SendStringArray) {
blink::TestWTFPtr ptr;
- TestWTFImpl impl(ConvertInterfaceRequest<TestWTF>(GetProxy(&ptr)));
+ TestWTFImpl impl(ConvertInterfaceRequest<TestWTF>(MakeRequest(&ptr)));
WTF::Optional<WTF::Vector<WTF::String>> arrs[3];
// arrs[0] is empty.
@@ -293,7 +216,7 @@ TEST_F(WTFTypesTest, SendStringArray) {
TEST_F(WTFTypesTest, SendStringMap) {
blink::TestWTFPtr ptr;
- TestWTFImpl impl(ConvertInterfaceRequest<TestWTF>(GetProxy(&ptr)));
+ TestWTFImpl impl(ConvertInterfaceRequest<TestWTF>(MakeRequest(&ptr)));
WTF::Optional<WTF::HashMap<WTF::String, WTF::String>> maps[3];
// maps[0] is empty.
diff --git a/mojo/public/cpp/bindings/unique_ptr_impl_ref_traits.h b/mojo/public/cpp/bindings/unique_ptr_impl_ref_traits.h
new file mode 100644
index 0000000..f1ac097
--- /dev/null
+++ b/mojo/public/cpp/bindings/unique_ptr_impl_ref_traits.h
@@ -0,0 +1,22 @@
+// Copyright 2017 The Chromium 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 MOJO_PUBLIC_CPP_BINDINGS_UNIQUE_PTR_IMPL_REF_TRAITS_H_
+#define MOJO_PUBLIC_CPP_BINDINGS_UNIQUE_PTR_IMPL_REF_TRAITS_H_
+
+namespace mojo {
+
+// Traits for a binding's implementation reference type.
+// This corresponds to a unique_ptr reference type.
+template <typename Interface>
+struct UniquePtrImplRefTraits {
+ using PointerType = std::unique_ptr<Interface>;
+
+ static bool IsNull(const PointerType& ptr) { return !ptr; }
+ static Interface* GetRawPointer(PointerType* ptr) { return ptr->get(); }
+};
+
+} // namespace mojo
+
+#endif // MOJO_PUBLIC_CPP_BINDINGS_UNIQUE_PTR_IMPL_REF_TRAITS_H_