Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1717)

Unified Diff: remoting/host/mock_callback.h

Issue 719983002: Reporting of policy errors via host-offline-reason: part 3 (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@hor-nohoststatussender
Patch Set: Rebasing... Created 6 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: remoting/host/mock_callback.h
diff --git a/remoting/host/mock_callback.h b/remoting/host/mock_callback.h
index ca3feb6d06a415f1853b363e7b089f8b0a03ad7a..4eb8cb032b1bbf26afb77813aaaa6481b4241c2e 100644
--- a/remoting/host/mock_callback.h
+++ b/remoting/host/mock_callback.h
@@ -10,11 +10,33 @@
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/callback.h"
+#include "base/memory/ref_counted.h"
#include "testing/gmock/include/gmock/gmock.h"
namespace remoting {
+// MockCallback<Sig> can be used to mock Callback<Sig> from base/callback.h
Lambros 2014/12/03 03:20:25 This basically looks fine, though I can't say I fu
+//
+// Basic usage example:
+//
+// MockCallback<void(int)> mock_callback;
+// EXPECT_CALL(mock_callback, Run(123)).Times(2);
+// base::Callback<void(int)> callback = mock_callback.GetCallback();
+//
+// // Use |callback| in the remainder of the test.
+// // GMock will enforce the expectations from above.
+//
+// HasRemainingCallbacks usage example:
+//
+// MockCallback<int()> mock_callback;
+// EXPECT_CALL(mock_callback, Run()).WillOnce(Return(123));
+// HypotheticalFunctionUnderTest(mock_callback.GetCallback());
+// EXPECT_FALSE(mock_callback.HasRemainingCallbacks())
+// << "Verify that FunctionUnderTest didn't store the callback "
Lambros 2014/12/03 03:20:25 This feels like it should be a code comment, not a
Łukasz Anforowicz 2014/12/03 17:54:22 Maybe. I think that having this message in the ou
+// << "and therefore callers of FunctionUnderTest don't have to "
+// << "worry about lifetime of arguments bound to the callback";
+
template <typename Sig>
class MockCallback;
@@ -23,16 +45,106 @@ class MockCallback<R()> {
public:
MOCK_CONST_METHOD0_T(Run, R());
- MockCallback() {
+ MockCallback() : mock_callback_tracker_(new MockCallbackTracker(this)) {
}
// Caller of GetCallback has to guarantee that the returned callback
// will not be run after |this| is destroyed.
base::Callback<R()> GetCallback() {
- return base::Bind(&MockCallback<R()>::Run, base::Unretained(this));
+ return base::Bind(&MockCallbackTracker::Run, mock_callback_tracker_);
+ }
+
+ // Returns |true| if callbacks returned by |GetCallback| have not been
+ // destroyed yet.
+ bool HasRemainingCallbacks() const {
+ bool is_tracker_field_the_only_ref = mock_callback_tracker_->HasOneRef();
+ return !is_tracker_field_the_only_ref;
}
private:
+ // MockCallbackTracker has 2 goals:
+ // - Enable counting of callbacks for |HasRemainingCallbacks| method.
+ // - Allow stack-allocated MockCallbacks to be short-lived, while
+ // callbacks go through a long-lived MockCallbackTracker
+ // (which in the future can enable better handling of callback-
+ // -run-after-mock-callback-already-destroyed).
+ class MockCallbackTracker
+ : public base::RefCountedThreadSafe<MockCallbackTracker> {
+ public:
+ MockCallbackTracker(MockCallback* mock_callback)
+ : mock_callback_(mock_callback) {
+ }
+
+ R Run() {
+ // Forward to (gMock controlled) MockCallback::Run method.
+ return mock_callback_->Run();
+ }
+
+ private:
+ // Ref-counting helpers.
+ friend class base::RefCountedThreadSafe<MockCallbackTracker>;
+ ~MockCallbackTracker() {
+ }
+
+ MockCallback<R()>* mock_callback_;
+ };
+
+ scoped_refptr<MockCallbackTracker> mock_callback_tracker_;
+
+ DISALLOW_COPY_AND_ASSIGN(MockCallback);
+};
+
+template <typename R, typename A1>
+class MockCallback<R(A1)> {
+ public:
+ MOCK_CONST_METHOD1_T(Run, R(A1));
+
+ MockCallback() : mock_callback_tracker_(new MockCallbackTracker(this)) {
+ }
+
+ // Caller of GetCallback has to guarantee that the returned callback
+ // will not be run after |this| is destroyed.
+ base::Callback<R(A1)> GetCallback() {
+ return base::Bind(&MockCallbackTracker::Run, mock_callback_tracker_);
+ }
+
+ // Returns |true| if callbacks returned by |GetCallback| have not been
+ // destroyed yet.
+ bool HasRemainingCallbacks() const {
+ bool is_tracker_field_the_only_ref = mock_callback_tracker_->HasOneRef();
+ return !is_tracker_field_the_only_ref;
+ }
+
+ private:
+ // MockCallbackTracker has 2 goals:
+ // - Enable counting of callbacks for |HasRemainingCallbacks| method.
+ // - Allow stack-allocated MockCallbacks to be short-lived, while
+ // callbacks go through a long-lived MockCallbackTracker
+ // (which in the future can enable better handling of callback-
+ // -run-after-mock-callback-already-destroyed).
+ class MockCallbackTracker
+ : public base::RefCountedThreadSafe<MockCallbackTracker> {
+ public:
+ MockCallbackTracker(MockCallback* mock_callback)
+ : mock_callback_(mock_callback) {
+ }
+
+ R Run(A1 a1) {
+ // Forward to (gMock controlled) MockCallback::Run method.
+ return mock_callback_->Run(a1);
+ }
+
+ private:
+ // Ref-counting helpers.
+ friend class base::RefCountedThreadSafe<MockCallbackTracker>;
+ ~MockCallbackTracker() {
+ }
+
+ MockCallback<R(A1)>* mock_callback_;
+ };
+
+ scoped_refptr<MockCallbackTracker> mock_callback_tracker_;
+
DISALLOW_COPY_AND_ASSIGN(MockCallback);
};

Powered by Google App Engine
This is Rietveld 408576698