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