• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #include <functional>
16 
17 #include <gtest/gtest.h>
18 
19 #include <meta/api/make_callback.h>
20 #include <meta/api/object.h>
21 #include <meta/base/capture.h>
22 #include <meta/ext/attachment/attachment.h>
23 #include <meta/interface/intf_object_registry.h>
24 
25 #include "TestRunner.h"
26 #include "src/testing_objects.h"
27 #include "src/util.h"
28 
29 using namespace testing::ext;
30 
31 META_BEGIN_NAMESPACE()
32 
33 class CaptureBindTest : public testing::Test {
34 public:
SetUpTestSuite()35     static void SetUpTestSuite()
36     {
37         SetTest();
38     }
TearDownTestSuite()39     static void TearDownTestSuite()
40     {
41         TearDownTest();
42     }
SetUp()43     void SetUp() {}
TearDown()44     void TearDown() {}
45 };
46 
47 HWTEST_F(CaptureBindTest, LambdaAutoLocksCapturedSharedPtr, TestSize.Level1)
48 {
49     {
50         BASE_NS::shared_ptr<int> sp(new int { 6 });
__anon924427be0102(auto p) 51         auto f = CaptureSafe([](auto p) { *p = 1; }, sp);
52 
53         EXPECT_EQ(*sp, 6);
54         EXPECT_NO_THROW(f());
55         EXPECT_EQ(*sp, 1);
56     }
57 
58     {
59         const BASE_NS::shared_ptr<int> sp(new int { 6 });
__anon924427be0202(auto p) 60         auto f = CaptureSafe([](auto p) { *p = 1; }, sp);
61 
62         EXPECT_EQ(*sp, 6);
63         EXPECT_NO_THROW(f());
64         EXPECT_EQ(*sp, 1);
65     }
66 }
67 
68 HWTEST_F(CaptureBindTest, LambdaAutoLocksCapturedWeakPtr, TestSize.Level1)
69 {
70     {
71         BASE_NS::shared_ptr<int> sp(new int { 6 });
72         auto wp = BASE_NS::weak_ptr(sp);
__anon924427be0302(auto p) 73         auto f = CaptureSafe([](auto p) { *p = 1; }, wp);
74 
75         EXPECT_EQ(*sp, 6);
76         EXPECT_NO_THROW(f());
77         EXPECT_EQ(*sp, 1);
78     }
79 
80     {
81         BASE_NS::shared_ptr<int> sp(new int { 6 });
82         const auto wp = BASE_NS::weak_ptr(sp);
__anon924427be0402(auto p) 83         auto f = CaptureSafe([](auto p) { *p = 1; }, wp);
84 
85         EXPECT_EQ(*sp, 6);
86         EXPECT_NO_THROW(f());
87         EXPECT_EQ(*sp, 1);
88     }
89 }
90 
91 HWTEST_F(CaptureBindTest, LambdaNotThrowsWhenCapturedSharedPointerIsReleased, TestSize.Level1)
92 {
93     {
94         BASE_NS::shared_ptr<int> p(new int {});
95 
__anon924427be0502(auto p) 96         auto f = CaptureSafe([](auto p) { *p = 1; }, p);
97         p.reset();
98 
99         EXPECT_NO_THROW(f());
100     }
101 }
102 
103 HWTEST_F(CaptureBindTest, LambdaNotThrowsWhenCapturedWeakPointerPointsToInvalidResource, TestSize.Level1)
104 {
105     {
106         BASE_NS::shared_ptr<int> sp(new int {});
107 
__anon924427be0602(auto p) 108         auto f = CaptureSafe([](auto p) { *p = 1; }, BASE_NS::weak_ptr(sp));
109         sp.reset();
110 
111         EXPECT_NO_THROW(f());
112     }
113 
114     {
115         BASE_NS::shared_ptr<int> sp(new int {});
116         BASE_NS::weak_ptr<int> wp = BASE_NS::weak_ptr(sp);
117 
__anon924427be0702(auto p) 118         auto f = CaptureSafe([](auto p) { *p = 1; }, wp);
119         sp.reset();
120 
121         EXPECT_NO_THROW(f());
122     }
123 }
124 
125 HWTEST_F(CaptureBindTest, SimpleLambda, TestSize.Level1)
126 {
127     BASE_NS::shared_ptr<int> p(new int {});
128 
129     {
__anon924427be0802(auto pp) 130         auto f = Capture([](auto pp) { *pp = 1; }, p);
131         f();
132         EXPECT_EQ(*p, 1);
133     }
134     {
__anon924427be0902(auto p, int v) 135         auto f = Capture([](auto p, int v) { *p = v; }, p);
136         f(2);
137         EXPECT_EQ(*p, 2);
138     }
139     {
__anon924427be0a02() 140         auto f = Capture([]() { return true; });
141         EXPECT_TRUE(f());
142     }
143     {
__anon924427be0b02(int v) 144         auto f = Capture([](int v) { v = 1; });
145         int i = 0;
146         f(i);
147         EXPECT_EQ(i, 0);
148     }
149     {
__anon924427be0c02(int& v) 150         auto f = Capture([](int& v) { v = 1; });
151         int i = 0;
152         f(i);
153         EXPECT_EQ(i, 1);
154     }
155     {
156         BASE_NS::shared_ptr<int> p(new int {});
__anon924427be0d02(auto p) 157         auto f = Capture([](auto p) { return (bool)p; }, p);
158         EXPECT_TRUE(f());
159         p.reset();
160         EXPECT_FALSE(f());
161     }
162     {
163         std::function<bool()> func;
164         {
165             const BASE_NS::shared_ptr<int> p(new int {});
__anon924427be0e02(auto p) 166             func = Capture([](auto p) { return (bool)p; }, p);
167             EXPECT_TRUE(func());
168         }
169         EXPECT_FALSE(func());
170     }
171     {
172         BASE_NS::shared_ptr<int> p(new int {});
173         auto other = p;
__anon924427be0f02(auto p) 174         auto f = Capture([](auto p) { return (bool)p; }, BASE_NS::move(p));
175         EXPECT_TRUE(f());
176         other.reset();
177         EXPECT_FALSE(f());
178     }
179 }
180 
181 HWTEST_F(CaptureBindTest, MakeCallback, TestSize.Level1)
182 {
183     auto& registry = GetObjectRegistry();
184     auto p = META_NS::ConstructProperty<int>(registry, "P1", 0);
185 
186     BASE_NS::shared_ptr<int> count(new int {});
187     p->OnChanged()->AddHandler(MakeCallback<IOnChanged>(
__anon924427be1002(auto i) 188         [](auto i) {
189             if (i) {
190                 ++*i;
191             }
192         },
193         count));
194 
195     p->SetValue(2);
196     EXPECT_EQ(*count, 1);
197 }
198 
199 HWTEST_F(CaptureBindTest, MakeCallable, TestSize.Level1)
200 {
201     auto& registry = GetObjectRegistry();
202     auto c = CreateTestContainer<IContainer>("Test");
203 
204     BASE_NS::shared_ptr<int> count(new int {});
205     c->OnContainerChanged()->AddHandler(MakeCallback<IOnChildChanged>(
__anon924427be1102(auto i, const ChildChangedInfo& info) 206         [](auto i, const ChildChangedInfo& info) {
207             if (i) {
208                 ++*i;
209             }
210         },
211         count));
212 
213     c->Add(Object {});
214     EXPECT_EQ(*count, 1);
215 }
216 
217 namespace {
218 META_REGISTER_CLASS(TestAttachment, "d4e854a2-b169-4b90-ae31-76e78cdf07b0", META_NS::ObjectCategoryBits::APPLICATION)
219 
220 class TestAttachment : public META_NS::AttachmentFwd {
META_OBJECT(TestAttachment,ClassId::TestAttachment,AttachmentFwd)221     META_OBJECT(TestAttachment, ClassId::TestAttachment, AttachmentFwd)
222     bool AttachTo(const META_NS::IAttach::Ptr& target, const IObject::Ptr& dataContext) override
223     {
224         return true;
225     }
DetachFrom(const META_NS::IAttach::Ptr & target)226     bool DetachFrom(const META_NS::IAttach::Ptr& target) override
227     {
228         return true;
229     }
230 };
231 } // namespace
232 
233 HWTEST_F(CaptureBindTest, IObject, TestSize.Level1)
234 {
235     RegisterObjectType<TestAttachment>();
236     IObject::Ptr obj = Object {}.GetIObject();
237     auto func = Capture(
__anon924427be1302(IObject::Ptr p) 238         [](IObject::Ptr p) {
239             if (auto a = interface_cast<IAttach>(p)) {
240                 a->Attach(GetObjectRegistry().Create<IAttachment>(Meta::ClassId::TestAttachment));
241                 return true;
242             }
243             return false;
244         },
245         obj);
246 
247     EXPECT_TRUE(func());
248     EXPECT_EQ(interface_cast<IAttach>(obj)->GetAttachments().size(), 1);
249     obj.reset();
250     EXPECT_FALSE(func());
251     UnregisterObjectType<TestAttachment>();
252 }
253 
254 META_END_NAMESPACE()
255