1// Copyright 2012 The Chromium Authors 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 <vector> 6 7#include "base/apple/scoped_nsobject.h" 8#include "base/compiler_specific.h" 9#include "testing/gtest/include/gtest/gtest.h" 10 11#if HAS_FEATURE(objc_arc) 12#error "This file must not be compiled with ARC." 13#endif 14 15namespace { 16 17TEST(ScopedNSObjectTest, ScopedNSObject) { 18 base::apple::scoped_nsobject<NSObject> p1([[NSObject alloc] init]); 19 ASSERT_TRUE(p1.get()); 20 ASSERT_EQ(1u, [p1.get() retainCount]); 21 base::apple::scoped_nsobject<NSObject> p2(p1); 22 ASSERT_EQ(p1.get(), p2.get()); 23 ASSERT_EQ(2u, [p1.get() retainCount]); 24 p2.reset(); 25 ASSERT_EQ(nil, p2.get()); 26 ASSERT_EQ(1u, [p1.get() retainCount]); 27 { 28 base::apple::scoped_nsobject<NSObject> p3 = p1; 29 ASSERT_EQ(p1.get(), p3.get()); 30 ASSERT_EQ(2u, [p1.get() retainCount]); 31 @autoreleasepool { 32 p3 = p1; 33 } 34 ASSERT_EQ(p1.get(), p3.get()); 35 ASSERT_EQ(2u, [p1.get() retainCount]); 36 } 37 ASSERT_EQ(1u, [p1.get() retainCount]); 38 base::apple::scoped_nsobject<NSObject> p4([p1.get() retain]); 39 ASSERT_EQ(2u, [p1.get() retainCount]); 40 ASSERT_TRUE(p1 == p1); 41 ASSERT_FALSE(p1 != p1); 42 base::apple::scoped_nsobject<NSObject> p5([[NSObject alloc] init]); 43 ASSERT_TRUE(p1 != p5); 44 ASSERT_FALSE(p1 == p5); 45 46 base::apple::scoped_nsobject<NSObject> p6 = p1; 47 ASSERT_EQ(3u, [p6.get() retainCount]); 48 @autoreleasepool { 49 p6.autorelease(); 50 ASSERT_EQ(nil, p6.get()); 51 ASSERT_EQ(3u, [p1.get() retainCount]); 52 } 53 ASSERT_EQ(2u, [p1.get() retainCount]); 54 55 base::apple::scoped_nsobject<NSObject> p7([[NSObject alloc] init]); 56 base::apple::scoped_nsobject<NSObject> p8(std::move(p7)); 57 ASSERT_TRUE(p8); 58 ASSERT_EQ(1u, [p8.get() retainCount]); 59 ASSERT_FALSE(p7.get()); 60} 61 62// Instantiating scoped_nsobject<> with T=NSAutoreleasePool should trip a 63// static_assert. 64#if 0 65TEST(ScopedNSObjectTest, FailToCreateScopedNSObjectAutoreleasePool) { 66 base::apple::scoped_nsobject<NSAutoreleasePool> pool; 67} 68#endif 69 70TEST(ScopedNSObjectTest, ScopedNSObjectInContainer) { 71 base::apple::scoped_nsobject<id> p([[NSObject alloc] init]); 72 ASSERT_TRUE(p.get()); 73 ASSERT_EQ(1u, [p.get() retainCount]); 74 { 75 std::vector<base::apple::scoped_nsobject<id>> objects; 76 objects.push_back(p); 77 ASSERT_EQ(2u, [p.get() retainCount]); 78 ASSERT_EQ(p.get(), objects[0].get()); 79 objects.push_back( 80 base::apple::scoped_nsobject<id>([[NSObject alloc] init])); 81 ASSERT_TRUE(objects[1].get()); 82 ASSERT_EQ(1u, [objects[1].get() retainCount]); 83 } 84 ASSERT_EQ(1u, [p.get() retainCount]); 85} 86 87TEST(ScopedNSObjectTest, ScopedNSObjectFreeFunctions) { 88 base::apple::scoped_nsobject<id> p1([[NSObject alloc] init]); 89 id o1 = p1.get(); 90 ASSERT_TRUE(o1 == p1); 91 ASSERT_FALSE(o1 != p1); 92 base::apple::scoped_nsobject<id> p2([[NSObject alloc] init]); 93 ASSERT_TRUE(o1 != p2); 94 ASSERT_FALSE(o1 == p2); 95 id o2 = p2.get(); 96 swap(p1, p2); 97 ASSERT_EQ(o2, p1.get()); 98 ASSERT_EQ(o1, p2.get()); 99} 100 101TEST(ScopedNSObjectTest, ResetWithAnotherScopedNSObject) { 102 base::apple::scoped_nsobject<id> p1([[NSObject alloc] init]); 103 id o1 = p1.get(); 104 105 id o2 = nil; 106 { 107 base::apple::scoped_nsobject<id> p2([[NSObject alloc] init]); 108 o2 = p2.get(); 109 p1.reset(p2); 110 EXPECT_EQ(2u, [p1.get() retainCount]); 111 } 112 113 EXPECT_NE(o1, p1.get()); 114 EXPECT_EQ(o2, p1.get()); 115 EXPECT_NE(p1.get(), nil); 116 117 EXPECT_EQ(1u, [p1.get() retainCount]); 118} 119 120} // namespace 121