1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "jingle/notifier/base/weak_xmpp_client.h" 6 7 #include "base/basictypes.h" 8 #include "base/memory/scoped_ptr.h" 9 #include "base/memory/weak_ptr.h" 10 #include "base/message_loop/message_loop.h" 11 #include "jingle/glue/task_pump.h" 12 #include "talk/base/sigslot.h" 13 #include "testing/gmock/include/gmock/gmock.h" 14 #include "testing/gtest/include/gtest/gtest.h" 15 16 namespace notifier { 17 18 namespace { 19 20 class MockXmppDelegate : public sigslot::has_slots<> { 21 public: 22 virtual ~MockXmppDelegate() {} 23 24 MOCK_METHOD1(OnStateChange, void(buzz::XmppEngine::State)); 25 MOCK_METHOD2(OnInputLog, void(const char*, int)); 26 MOCK_METHOD2(OnOutputLog, void(const char*, int)); 27 }; 28 29 const buzz::XmppEngine::State kState = buzz::XmppEngine::STATE_OPEN; 30 const char kInputLog[] = "input log"; 31 const char kOutputLog[] = "output log"; 32 33 class WeakXmppClientTest : public testing::Test { 34 protected: 35 WeakXmppClientTest() : task_pump_(new jingle_glue::TaskPump()) {} 36 37 virtual ~WeakXmppClientTest() {} 38 39 void ConnectSignals(buzz::XmppClient* xmpp_client) { 40 xmpp_client->SignalStateChange.connect( 41 &mock_xmpp_delegate_, &MockXmppDelegate::OnStateChange); 42 xmpp_client->SignalLogInput.connect( 43 &mock_xmpp_delegate_, &MockXmppDelegate::OnInputLog); 44 xmpp_client->SignalLogOutput.connect( 45 &mock_xmpp_delegate_, &MockXmppDelegate::OnOutputLog); 46 } 47 48 void ExpectSignalCalls() { 49 EXPECT_CALL(mock_xmpp_delegate_, OnStateChange(kState)); 50 EXPECT_CALL(mock_xmpp_delegate_, 51 OnInputLog(kInputLog, arraysize(kInputLog))); 52 EXPECT_CALL(mock_xmpp_delegate_, 53 OnOutputLog(kOutputLog, arraysize(kOutputLog))); 54 } 55 56 void RaiseSignals(buzz::XmppClient* xmpp_client) { 57 xmpp_client->SignalStateChange(kState); 58 xmpp_client->SignalLogInput(kInputLog, arraysize(kInputLog)); 59 xmpp_client->SignalLogOutput(kOutputLog, arraysize(kOutputLog)); 60 } 61 62 // Needed by TaskPump. 63 base::MessageLoop message_loop_; 64 65 scoped_ptr<jingle_glue::TaskPump> task_pump_; 66 MockXmppDelegate mock_xmpp_delegate_; 67 }; 68 69 TEST_F(WeakXmppClientTest, InvalidationViaInvalidate) { 70 ExpectSignalCalls(); 71 72 WeakXmppClient* weak_xmpp_client = new WeakXmppClient(task_pump_.get()); 73 ConnectSignals(weak_xmpp_client); 74 75 weak_xmpp_client->Start(); 76 base::WeakPtr<WeakXmppClient> weak_ptr = weak_xmpp_client->AsWeakPtr(); 77 EXPECT_TRUE(weak_ptr.get()); 78 RaiseSignals(weak_ptr.get()); 79 80 weak_xmpp_client->Invalidate(); 81 EXPECT_FALSE(weak_ptr.get()); 82 // We know that |weak_xmpp_client| is still valid at this point, 83 // although it should be entirely disconnected. 84 RaiseSignals(weak_xmpp_client); 85 } 86 87 TEST_F(WeakXmppClientTest, InvalidationViaStop) { 88 ExpectSignalCalls(); 89 90 WeakXmppClient* weak_xmpp_client = new WeakXmppClient(task_pump_.get()); 91 ConnectSignals(weak_xmpp_client); 92 93 weak_xmpp_client->Start(); 94 base::WeakPtr<WeakXmppClient> weak_ptr = weak_xmpp_client->AsWeakPtr(); 95 EXPECT_TRUE(weak_ptr.get()); 96 RaiseSignals(weak_ptr.get()); 97 98 weak_xmpp_client->Abort(); 99 EXPECT_FALSE(weak_ptr.get()); 100 // We know that |weak_xmpp_client| is still valid at this point, 101 // although it should be entirely disconnected. 102 RaiseSignals(weak_xmpp_client); 103 } 104 105 TEST_F(WeakXmppClientTest, InvalidationViaDestructor) { 106 ExpectSignalCalls(); 107 108 WeakXmppClient* weak_xmpp_client = new WeakXmppClient(task_pump_.get()); 109 ConnectSignals(weak_xmpp_client); 110 111 weak_xmpp_client->Start(); 112 base::WeakPtr<WeakXmppClient> weak_ptr = weak_xmpp_client->AsWeakPtr(); 113 EXPECT_TRUE(weak_ptr.get()); 114 RaiseSignals(weak_ptr.get()); 115 116 task_pump_.reset(); 117 EXPECT_FALSE(weak_ptr.get()); 118 // |weak_xmpp_client| is truly invalid at this point so we can't 119 // RaiseSignals() with it. 120 } 121 122 } // namespace 123 124 } // namespace notifier 125