1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "base/scoped_comptr_win.h" 6 7 #include <shlobj.h> 8 9 #include "base/scoped_ptr.h" 10 #include "testing/gtest/include/gtest/gtest.h" 11 12 namespace { 13 14 struct Dummy { 15 Dummy() : adds(0), releases(0) { } 16 void AddRef() { ++adds; } 17 void Release() { ++releases; } 18 19 int adds; 20 int releases; 21 }; 22 23 extern const IID dummy_iid; 24 const IID dummy_iid = { 0x12345678u, 0x1234u, 0x5678u, 01, 23, 45, 67, 89, 25 01, 23, 45 }; 26 27 } // namespace 28 29 TEST(ScopedComPtrTest, ScopedComPtr) { 30 EXPECT_TRUE(memcmp(&ScopedComPtr<IUnknown>::iid(), &IID_IUnknown, 31 sizeof(IID)) == 0); 32 33 EXPECT_TRUE(SUCCEEDED(::CoInitialize(NULL))); 34 35 { 36 ScopedComPtr<IUnknown> unk; 37 EXPECT_TRUE(SUCCEEDED(unk.CreateInstance(CLSID_ShellLink))); 38 ScopedComPtr<IUnknown> unk2; 39 unk2.Attach(unk.Detach()); 40 EXPECT_TRUE(unk == NULL); 41 EXPECT_TRUE(unk2 != NULL); 42 43 ScopedComPtr<IMalloc> mem_alloc; 44 EXPECT_TRUE(SUCCEEDED(CoGetMalloc(1, mem_alloc.Receive()))); 45 46 ScopedComPtr<IUnknown> qi_test; 47 EXPECT_HRESULT_SUCCEEDED(mem_alloc.QueryInterface(IID_IUnknown, 48 reinterpret_cast<void**>(qi_test.Receive()))); 49 EXPECT_TRUE(qi_test.get() != NULL); 50 qi_test.Release(); 51 52 // test ScopedComPtr& constructor 53 ScopedComPtr<IMalloc> copy1(mem_alloc); 54 EXPECT_TRUE(copy1.IsSameObject(mem_alloc)); 55 EXPECT_FALSE(copy1.IsSameObject(unk2)); // unk2 is valid but different 56 EXPECT_FALSE(copy1.IsSameObject(unk)); // unk is NULL 57 58 IMalloc* naked_copy = copy1.Detach(); 59 copy1 = naked_copy; // Test the =(T*) operator. 60 naked_copy->Release(); 61 62 copy1.Release(); 63 EXPECT_FALSE(copy1.IsSameObject(unk2)); // unk2 is valid, copy1 is not 64 65 // test Interface* constructor 66 ScopedComPtr<IMalloc> copy2(static_cast<IMalloc*>(mem_alloc)); 67 EXPECT_TRUE(copy2.IsSameObject(mem_alloc)); 68 69 EXPECT_TRUE(SUCCEEDED(unk.QueryFrom(mem_alloc))); 70 EXPECT_TRUE(unk != NULL); 71 unk.Release(); 72 EXPECT_TRUE(unk == NULL); 73 EXPECT_TRUE(unk.IsSameObject(copy1)); // both are NULL 74 } 75 76 ::CoUninitialize(); 77 } 78 79 TEST(ScopedComPtrTest, ScopedComPtrVector) { 80 // Verify we don't get error C2558. 81 typedef ScopedComPtr<Dummy, &dummy_iid> Ptr; 82 std::vector<Ptr> bleh; 83 84 scoped_ptr<Dummy> p(new Dummy); 85 { 86 Ptr p2(p.get()); 87 EXPECT_EQ(p->adds, 1); 88 EXPECT_EQ(p->releases, 0); 89 Ptr p3 = p2; 90 EXPECT_EQ(p->adds, 2); 91 EXPECT_EQ(p->releases, 0); 92 p3 = p2; 93 EXPECT_EQ(p->adds, 3); 94 EXPECT_EQ(p->releases, 1); 95 // To avoid hitting a reallocation. 96 bleh.reserve(1); 97 bleh.push_back(p2); 98 EXPECT_EQ(p->adds, 4); 99 EXPECT_EQ(p->releases, 1); 100 EXPECT_EQ(bleh[0], p.get()); 101 bleh.pop_back(); 102 EXPECT_EQ(p->adds, 4); 103 EXPECT_EQ(p->releases, 2); 104 } 105 EXPECT_EQ(p->adds, 4); 106 EXPECT_EQ(p->releases, 4); 107 } 108