Flutter Engine
The Flutter Engine
scoped_nsobject_arc_unittests.mm
Go to the documentation of this file.
1// Copyright 2013 The Flutter 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 <vector>
6
7#import <CoreFoundation/CoreFoundation.h>
8
9#include "flutter/fml/platform/darwin/scoped_nsobject.h"
10#include "fml/logging.h"
11#include "gtest/gtest.h"
12
13#if !defined(__has_feature) || !__has_feature(objc_arc)
14#error "This file requires ARC support."
15#endif
16
17namespace {
18
19template <typename NST>
20CFIndex GetRetainCount(const fml::scoped_nsobject<NST>& nst) {
21 @autoreleasepool {
22 return CFGetRetainCount((__bridge CFTypeRef)nst.get()) - 1;
23 }
24}
25
26#if __has_feature(objc_arc_weak)
27TEST(ScopedNSObjectTestARC, DefaultPolicyIsRetain) {
28 __weak id o;
29 @autoreleasepool {
30 fml::scoped_nsprotocol<id> p([[NSObject alloc] init]);
31 o = p.get();
32 EXPECT_EQ(o, p.get());
33 }
34 EXPECT_EQ(o, nil);
35}
36#endif
37
38TEST(ScopedNSObjectTestARC, ScopedNSObject) {
39 fml::scoped_nsobject<NSObject> p1([[NSObject alloc] init]);
40 @autoreleasepool {
41 EXPECT_TRUE(p1.get());
42 EXPECT_TRUE(p1.get());
43 }
44 EXPECT_EQ(1, GetRetainCount(p1));
45 EXPECT_EQ(1, GetRetainCount(p1));
47 @autoreleasepool {
48 EXPECT_EQ(p1.get(), p2.get());
49 }
50 EXPECT_EQ(2, GetRetainCount(p1));
51 p2.reset();
52 EXPECT_EQ(nil, p2.get());
53 EXPECT_EQ(1, GetRetainCount(p1));
54 {
56 @autoreleasepool {
57 EXPECT_EQ(p1.get(), p3.get());
58 }
59 EXPECT_EQ(2, GetRetainCount(p1));
60 p3 = p1;
61 @autoreleasepool {
62 EXPECT_EQ(p1.get(), p3.get());
63 }
64 EXPECT_EQ(2, GetRetainCount(p1));
65 }
66 EXPECT_EQ(1, GetRetainCount(p1));
68 @autoreleasepool {
69 p4 = fml::scoped_nsobject<NSObject>(p1.get());
70 }
71 EXPECT_EQ(2, GetRetainCount(p1));
72 @autoreleasepool {
73 EXPECT_TRUE(p1 == p1.get());
74 EXPECT_TRUE(p1 == p1);
75 EXPECT_FALSE(p1 != p1);
76 EXPECT_FALSE(p1 != p1.get());
77 }
78 fml::scoped_nsobject<NSObject> p5([[NSObject alloc] init]);
79 @autoreleasepool {
80 EXPECT_TRUE(p1 != p5);
81 EXPECT_TRUE(p1 != p5.get());
82 EXPECT_FALSE(p1 == p5);
83 EXPECT_FALSE(p1 == p5.get());
84 }
85
87 EXPECT_EQ(3, GetRetainCount(p6));
88 @autoreleasepool {
89 p6.autorelease();
90 EXPECT_EQ(nil, p6.get());
91 }
92 EXPECT_EQ(2, GetRetainCount(p1));
93}
94
95TEST(ScopedNSObjectTestARC, ScopedNSObjectInContainer) {
96 fml::scoped_nsobject<id> p([[NSObject alloc] init]);
97 @autoreleasepool {
98 EXPECT_TRUE(p.get());
99 }
100 EXPECT_EQ(1, GetRetainCount(p));
101 @autoreleasepool {
102 std::vector<fml::scoped_nsobject<id>> objects;
103 objects.push_back(p);
104 EXPECT_EQ(2, GetRetainCount(p));
105 @autoreleasepool {
106 EXPECT_EQ(p.get(), objects[0].get());
107 }
108 objects.push_back(fml::scoped_nsobject<id>([[NSObject alloc] init]));
109 @autoreleasepool {
110 EXPECT_TRUE(objects[1].get());
111 }
112 EXPECT_EQ(1, GetRetainCount(objects[1]));
113 }
114 EXPECT_EQ(1, GetRetainCount(p));
115}
116
117TEST(ScopedNSObjectTestARC, ScopedNSObjectFreeFunctions) {
118 fml::scoped_nsobject<id> p1([[NSObject alloc] init]);
119 id o1 = p1.get();
120 EXPECT_TRUE(o1 == p1);
121 EXPECT_FALSE(o1 != p1);
122 fml::scoped_nsobject<id> p2([[NSObject alloc] init]);
123 EXPECT_TRUE(o1 != p2);
124 EXPECT_FALSE(o1 == p2);
125 id o2 = p2.get();
126 swap(p1, p2);
127 EXPECT_EQ(o2, p1.get());
128 EXPECT_EQ(o1, p2.get());
129}
130
131} // namespace
#define TEST(S, s, D, expected)
Definition: FitsInTest.cpp:15
void swap(sk_sp< T > &a, sk_sp< T > &b)
Definition: SkRefCnt.h:341
T get() const __attribute((ns_returns_not_retained))
NST autorelease() __attribute((ns_returns_not_retained))
static bool init()
const myers::Point & get(const myers::Segment &)
#define EXPECT_TRUE(handle)
Definition: unit_test.h:678