• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1//
2// Copyright 2025 The ANGLE Project Authors. All rights reserved.
3//   of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6// ObjCPtr_test.cpp:
7//   Test for functionality in ObjCPtr.h
8
9#import "common/apple/ObjCPtr.h"
10#import <Metal/Metal.h>
11#import "gtest/gtest.h"
12
13namespace
14{
15using namespace angle;
16
17// This explains why the implementation has ObjCPtr<U> &&other constructor/operator=
18// as opposed to ObjCPtr &&other ones.
19TEST(ObjCPtrTest, ImplementationDetailExplanation)
20{
21    // For Obj-C interfaces we would like the client to use ObjCPtr<T> form, similar
22    // to any C++ smart pointer.
23    MTLStencilDescriptor *rawDesc             = nil;
24    ObjCPtr<MTLStencilDescriptor> stencilDesc = adoptObjCPtr(rawDesc);
25
26    // For Obj-C protocols we would like the client to use ObjCPtr<id<P>> form,
27    // which resembles the normal smart pointer form textually:
28    id<MTLDevice> rawDevice       = nil;
29    ObjCPtr<id<MTLDevice>> device = adoptObjCPtr(rawDevice);
30
31    // adoptObjCPtr for Obj-C interface types works as expected:
32    {
33        auto result = adoptObjCPtr(rawDesc);
34        static_assert(std::is_same_v<ObjCPtr<MTLStencilDescriptor>, decltype(result)>);
35    }
36
37    // adoptObjCPtr for protocols does not:
38    {
39        auto result = adoptObjCPtr(rawDevice);
40        static_assert(!std::is_same_v<ObjCPtr<id<MTLDevice>>, decltype(result)>);
41        static_assert(
42            std::is_same_v<ObjCPtr<std::remove_pointer_t<id<MTLDevice>>>, decltype(result)>);
43    }
44}
45
46TEST(ObjCPtrTest, Comparison)
47{
48    ObjCPtr<MTLStencilDescriptor> a = adoptObjCPtr([[MTLStencilDescriptor alloc] init]);
49    ObjCPtr<MTLStencilDescriptor> b;
50    EXPECT_TRUE(a == a);
51    EXPECT_TRUE(a != b);
52    EXPECT_TRUE(a != nullptr);
53    EXPECT_TRUE(b == nullptr);
54    EXPECT_TRUE(nullptr != a);
55    EXPECT_TRUE(nullptr == b);
56    EXPECT_TRUE(a != nil);
57    EXPECT_TRUE(b == nil);
58    EXPECT_TRUE(nil != a);
59    EXPECT_TRUE(nil == b);
60    EXPECT_TRUE(!!a);
61    EXPECT_TRUE(!b);
62}
63
64TEST(ObjCPtrTest, Copy)
65{
66    ObjCPtr<MTLStencilDescriptor> a = adoptObjCPtr([[MTLStencilDescriptor alloc] init]);
67    ObjCPtr<MTLStencilDescriptor> b = a;
68    EXPECT_EQ(a, b);
69    EXPECT_NE(a, nullptr);
70    a = {};
71    EXPECT_NE(a, b);
72}
73
74TEST(ObjCPtrTest, LeakObject)
75{
76    ObjCPtr<MTLStencilDescriptor> a = adoptObjCPtr([[MTLStencilDescriptor alloc] init]);
77    EXPECT_NE(a, nullptr);
78    auto rawA = a.leakObject();
79    EXPECT_EQ(a, nullptr);
80    EXPECT_EQ(a.leakObject(), nullptr);
81    a = adoptObjCPtr(rawA);
82}
83
84TEST(ObjCPtrTest, SelfAssignment)
85{
86    ObjCPtr a = adoptObjCPtr([[MTLStencilDescriptor alloc] init]);
87    auto rawA = a.get();
88    auto &r   = a;
89    a         = r;
90    EXPECT_EQ(a, rawA);
91    a = std::move(r);
92    EXPECT_EQ(a, rawA);
93}
94
95}  // namespace
96