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