18bf80f4bSopenharmony_ci/*
28bf80f4bSopenharmony_ci * Copyright (C) 2024 Huawei Device Co., Ltd.
38bf80f4bSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
48bf80f4bSopenharmony_ci * you may not use this file except in compliance with the License.
58bf80f4bSopenharmony_ci * You may obtain a copy of the License at
68bf80f4bSopenharmony_ci *
78bf80f4bSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
88bf80f4bSopenharmony_ci *
98bf80f4bSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
108bf80f4bSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
118bf80f4bSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
128bf80f4bSopenharmony_ci * See the License for the specific language governing permissions and
138bf80f4bSopenharmony_ci * limitations under the License.
148bf80f4bSopenharmony_ci */
158bf80f4bSopenharmony_ci
168bf80f4bSopenharmony_ci#include <functional>
178bf80f4bSopenharmony_ci
188bf80f4bSopenharmony_ci#include <gtest/gtest.h>
198bf80f4bSopenharmony_ci
208bf80f4bSopenharmony_ci#include <meta/api/make_callback.h>
218bf80f4bSopenharmony_ci#include <meta/api/object.h>
228bf80f4bSopenharmony_ci#include <meta/base/capture.h>
238bf80f4bSopenharmony_ci#include <meta/ext/attachment/attachment.h>
248bf80f4bSopenharmony_ci#include <meta/interface/intf_object_registry.h>
258bf80f4bSopenharmony_ci
268bf80f4bSopenharmony_ci#include "src/util.h"
278bf80f4bSopenharmony_ci#include "src/test_runner.h"
288bf80f4bSopenharmony_ci#include "src/testing_objects.h"
298bf80f4bSopenharmony_ci
308bf80f4bSopenharmony_ciusing namespace testing::ext;
318bf80f4bSopenharmony_ci
328bf80f4bSopenharmony_ciMETA_BEGIN_NAMESPACE()
338bf80f4bSopenharmony_cinamespace Test {
348bf80f4bSopenharmony_ci
358bf80f4bSopenharmony_ciclass CaptureTest : public testing::Test {
368bf80f4bSopenharmony_cipublic:
378bf80f4bSopenharmony_ci    static void SetUpTestSuite()
388bf80f4bSopenharmony_ci    {
398bf80f4bSopenharmony_ci        SetTest();
408bf80f4bSopenharmony_ci    }
418bf80f4bSopenharmony_ci    static void TearDownTestSuite()
428bf80f4bSopenharmony_ci    {
438bf80f4bSopenharmony_ci        ResetTest();
448bf80f4bSopenharmony_ci    }
458bf80f4bSopenharmony_ci    void SetUp() override {}
468bf80f4bSopenharmony_ci    void TearDown() override {}
478bf80f4bSopenharmony_ci};
488bf80f4bSopenharmony_ci
498bf80f4bSopenharmony_ci/**
508bf80f4bSopenharmony_ci * @tc.name: CaptureTest
518bf80f4bSopenharmony_ci * @tc.desc: test LambdaAutoLocksCapturedSharedPtr function
528bf80f4bSopenharmony_ci * @tc.type: FUNC
538bf80f4bSopenharmony_ci * @tc.require: I7DMS1
548bf80f4bSopenharmony_ci */
558bf80f4bSopenharmony_ciHWTEST_F(CaptureTest, LambdaAutoLocksCapturedSharedPtr, TestSize.Level1)
568bf80f4bSopenharmony_ci{
578bf80f4bSopenharmony_ci    {
588bf80f4bSopenharmony_ci        auto f = CaptureSafe([](auto p) { *p = 1; }, sp);
598bf80f4bSopenharmony_ci
608bf80f4bSopenharmony_ci        EXPECT_EQ(*sp, 6);
618bf80f4bSopenharmony_ci        EXPECT_NO_THROW(f());
628bf80f4bSopenharmony_ci        EXPECT_EQ(*sp, 1);
638bf80f4bSopenharmony_ci    }
648bf80f4bSopenharmony_ci
658bf80f4bSopenharmony_ci    {
668bf80f4bSopenharmony_ci        auto f = CaptureSafe([](auto p) { *p = 1; }, sp);
678bf80f4bSopenharmony_ci
688bf80f4bSopenharmony_ci        EXPECT_EQ(*sp, 6);
698bf80f4bSopenharmony_ci        EXPECT_NO_THROW(f());
708bf80f4bSopenharmony_ci        EXPECT_EQ(*sp, 1);
718bf80f4bSopenharmony_ci    }
728bf80f4bSopenharmony_ci}
738bf80f4bSopenharmony_ci
748bf80f4bSopenharmony_ci/**
758bf80f4bSopenharmony_ci * @tc.name: CaptureTest
768bf80f4bSopenharmony_ci * @tc.desc: test LambdaAutoLocksCapturedWeakPtr function
778bf80f4bSopenharmony_ci * @tc.type: FUNC
788bf80f4bSopenharmony_ci * @tc.require: I7DMS1
798bf80f4bSopenharmony_ci */
808bf80f4bSopenharmony_ciHWTEST_F(CaptureTest, LambdaAutoLocksCapturedWeakPtr, TestSize.Level1)
818bf80f4bSopenharmony_ci{
828bf80f4bSopenharmony_ci    {
838bf80f4bSopenharmony_ci        auto wp = BASE_NS::weak_ptr(sp);
848bf80f4bSopenharmony_ci        auto f = CaptureSafe([](auto p) { *p = 1; }, wp);
858bf80f4bSopenharmony_ci
868bf80f4bSopenharmony_ci        EXPECT_EQ(*sp, 6);
878bf80f4bSopenharmony_ci        EXPECT_NO_THROW(f());
888bf80f4bSopenharmony_ci        EXPECT_EQ(*sp, 1);
898bf80f4bSopenharmony_ci    }
908bf80f4bSopenharmony_ci
918bf80f4bSopenharmony_ci    {
928bf80f4bSopenharmony_ci        const auto wp = BASE_NS::weak_ptr(sp);
938bf80f4bSopenharmony_ci        auto f = CaptureSafe([](auto p) { *p = 1; }, wp);
948bf80f4bSopenharmony_ci
958bf80f4bSopenharmony_ci        EXPECT_EQ(*sp, 6);
968bf80f4bSopenharmony_ci        EXPECT_NO_THROW(f());
978bf80f4bSopenharmony_ci        EXPECT_EQ(*sp, 1);
988bf80f4bSopenharmony_ci    }
998bf80f4bSopenharmony_ci}
1008bf80f4bSopenharmony_ci
1018bf80f4bSopenharmony_ci/**
1028bf80f4bSopenharmony_ci * @tc.name: CaptureTest
1038bf80f4bSopenharmony_ci * @tc.desc: test LambdaNotThrowsWhenCapturedSharedPointerIsReleased function
1048bf80f4bSopenharmony_ci * @tc.type: FUNC
1058bf80f4bSopenharmony_ci * @tc.require: I7DMS1
1068bf80f4bSopenharmony_ci */
1078bf80f4bSopenharmony_ciHWTEST_F(CaptureTest, LambdaNotThrowsWhenCapturedSharedPointerIsReleased, TestSize.Level1)
1088bf80f4bSopenharmony_ci{
1098bf80f4bSopenharmony_ci    {
1108bf80f4bSopenharmony_ci        auto f = CaptureSafe([](auto p) { *p = 1; }, p);
1118bf80f4bSopenharmony_ci        p.reset();
1128bf80f4bSopenharmony_ci
1138bf80f4bSopenharmony_ci        EXPECT_NO_THROW(f());
1148bf80f4bSopenharmony_ci    }
1158bf80f4bSopenharmony_ci}
1168bf80f4bSopenharmony_ci
1178bf80f4bSopenharmony_ci/**
1188bf80f4bSopenharmony_ci * @tc.name: CaptureTest
1198bf80f4bSopenharmony_ci * @tc.desc: test LambdaNotThrowsWhenCapturedWeakPointerPointsToInvalidResource function
1208bf80f4bSopenharmony_ci * @tc.type: FUNC
1218bf80f4bSopenharmony_ci * @tc.require: I7DMS1
1228bf80f4bSopenharmony_ci */
1238bf80f4bSopenharmony_ciHWTEST_F(CaptureTest, LambdaNotThrowsWhenCapturedWeakPointerPointsToInvalidResource, TestSize.Level1)
1248bf80f4bSopenharmony_ci{
1258bf80f4bSopenharmony_ci    {
1268bf80f4bSopenharmony_ci        auto f = CaptureSafe([](auto p) { *p = 1; }, BASE_NS::weak_ptr(sp));
1278bf80f4bSopenharmony_ci        sp.reset();
1288bf80f4bSopenharmony_ci        EXPECT_NO_THROW(f());
1298bf80f4bSopenharmony_ci    }
1308bf80f4bSopenharmony_ci
1318bf80f4bSopenharmony_ci    {
1328bf80f4bSopenharmony_ci        BASE_NS::weak_ptr<int> wp = BASE_NS::weak_ptr(sp);
1338bf80f4bSopenharmony_ci        auto f = CaptureSafe([](auto p) { *p = 1; }, wp);
1348bf80f4bSopenharmony_ci        sp.reset();
1358bf80f4bSopenharmony_ci        EXPECT_NO_THROW(f());
1368bf80f4bSopenharmony_ci    }
1378bf80f4bSopenharmony_ci}
1388bf80f4bSopenharmony_ci
1398bf80f4bSopenharmony_ci/**
1408bf80f4bSopenharmony_ci * @tc.name: CaptureTest
1418bf80f4bSopenharmony_ci * @tc.desc: test SimpleLambda function
1428bf80f4bSopenharmony_ci * @tc.type: FUNC
1438bf80f4bSopenharmony_ci * @tc.require: I7DMS1
1448bf80f4bSopenharmony_ci */
1458bf80f4bSopenharmony_ciHWTEST_F(CaptureTest, SimpleLambda, TestSize.Level1)
1468bf80f4bSopenharmony_ci{
1478bf80f4bSopenharmony_ci    {
1488bf80f4bSopenharmony_ci        auto f = Capture([](auto pp) { *pp = 1; }, p);
1498bf80f4bSopenharmony_ci        f();
1508bf80f4bSopenharmony_ci        EXPECT_EQ(*p, 1);
1518bf80f4bSopenharmony_ci    }
1528bf80f4bSopenharmony_ci    {
1538bf80f4bSopenharmony_ci        auto f = Capture([](auto p, int v) { *p = v; }, p);
1548bf80f4bSopenharmony_ci        f(2);
1558bf80f4bSopenharmony_ci        EXPECT_EQ(*p, 2);
1568bf80f4bSopenharmony_ci    }
1578bf80f4bSopenharmony_ci    {
1588bf80f4bSopenharmony_ci        auto f = Capture([]() { return true; });
1598bf80f4bSopenharmony_ci        EXPECT_TRUE(f());
1608bf80f4bSopenharmony_ci    }
1618bf80f4bSopenharmony_ci    {
1628bf80f4bSopenharmony_ci        auto f = Capture([](int v) { v = 1; });
1638bf80f4bSopenharmony_ci        int i = 0;
1648bf80f4bSopenharmony_ci        f(i);
1658bf80f4bSopenharmony_ci        EXPECT_EQ(i, 0);
1668bf80f4bSopenharmony_ci    }
1678bf80f4bSopenharmony_ci    {
1688bf80f4bSopenharmony_ci        auto f = Capture([](int& v) { v = 1; });
1698bf80f4bSopenharmony_ci        int i = 0;
1708bf80f4bSopenharmony_ci        f(i);
1718bf80f4bSopenharmony_ci        EXPECT_EQ(i, 1);
1728bf80f4bSopenharmony_ci    }
1738bf80f4bSopenharmony_ci    {
1748bf80f4bSopenharmony_ci        auto f = Capture([](auto p) { return (bool)p; }, p);
1758bf80f4bSopenharmony_ci        EXPECT_TRUE(f());
1768bf80f4bSopenharmony_ci        p.reset();
1778bf80f4bSopenharmony_ci        EXPECT_FALSE(f());
1788bf80f4bSopenharmony_ci    }
1798bf80f4bSopenharmony_ci}
1808bf80f4bSopenharmony_ci
1818bf80f4bSopenharmony_ci/**
1828bf80f4bSopenharmony_ci * @tc.name: CaptureTest
1838bf80f4bSopenharmony_ci * @tc.desc: test MakeCallback function
1848bf80f4bSopenharmony_ci * @tc.type: FUNC
1858bf80f4bSopenharmony_ci * @tc.require: I7DMS1
1868bf80f4bSopenharmony_ci */
1878bf80f4bSopenharmony_ciHWTEST_F(CaptureTest, MakeCallback, TestSize.Level1)
1888bf80f4bSopenharmony_ci{
1898bf80f4bSopenharmony_ci    auto& registry = GetObjectRegistry();
1908bf80f4bSopenharmony_ci    auto p = META_NS::ConstructProperty<int>(registry, "P1", 0);
1918bf80f4bSopenharmony_ci
1928bf80f4bSopenharmony_ci    p->OnChanged()->AddHandler(MakeCallback<IOnChanged>(
1938bf80f4bSopenharmony_ci        [](auto i) {
1948bf80f4bSopenharmony_ci            if (i) {
1958bf80f4bSopenharmony_ci                ++*i;
1968bf80f4bSopenharmony_ci            }
1978bf80f4bSopenharmony_ci        },
1988bf80f4bSopenharmony_ci        count));
1998bf80f4bSopenharmony_ci    p->SetValue(2);
2008bf80f4bSopenharmony_ci    EXPECT_EQ(*count, 1);
2018bf80f4bSopenharmony_ci}
2028bf80f4bSopenharmony_ci
2038bf80f4bSopenharmony_ci/**
2048bf80f4bSopenharmony_ci * @tc.name: CaptureTest
2058bf80f4bSopenharmony_ci * @tc.desc: test MakeCallable function
2068bf80f4bSopenharmony_ci * @tc.type: FUNC
2078bf80f4bSopenharmony_ci * @tc.require: I7DMS1
2088bf80f4bSopenharmony_ci */
2098bf80f4bSopenharmony_ciHWTEST_F(CaptureTest, MakeCallable, TestSize.Level1)
2108bf80f4bSopenharmony_ci{
2118bf80f4bSopenharmony_ci    auto& registry = GetObjectRegistry();
2128bf80f4bSopenharmony_ci    auto c = CreateTestContainer<IContainer>("Test");
2138bf80f4bSopenharmony_ci
2148bf80f4bSopenharmony_ci    c->OnAdded()->AddHandler(MakeCallback<IOnChildChanged>(
2158bf80f4bSopenharmony_ci        [](auto i, const ChildChangedInfo& info) {
2168bf80f4bSopenharmony_ci            if (i) {
2178bf80f4bSopenharmony_ci                ++*i;
2188bf80f4bSopenharmony_ci            }
2198bf80f4bSopenharmony_ci        },
2208bf80f4bSopenharmony_ci        count));
2218bf80f4bSopenharmony_ci    c->Add(Object {});
2228bf80f4bSopenharmony_ci    EXPECT_EQ(*count, 1);
2238bf80f4bSopenharmony_ci}
2248bf80f4bSopenharmony_ci
2258bf80f4bSopenharmony_cinamespace {
2268bf80f4bSopenharmony_ciMETA_REGISTER_CLASS(TestAttachment, "d4e854a2-b169-4b90-ae31-76e78cdf07b0", META_NS::ObjectCategoryBits::APPLICATION)
2278bf80f4bSopenharmony_ci
2288bf80f4bSopenharmony_ciclass TestAttachment : public META_NS::AttachmentFwd<TestAttachment, ClassId::TestAttachment> {
2298bf80f4bSopenharmony_ci    bool AttachTo(const META_NS::IAttach::Ptr& target, const IObject::Ptr& dataContext) override
2308bf80f4bSopenharmony_ci    {
2318bf80f4bSopenharmony_ci        return true;
2328bf80f4bSopenharmony_ci    }
2338bf80f4bSopenharmony_ci    bool DetachFrom(const META_NS::IAttach::Ptr& target) override
2348bf80f4bSopenharmony_ci    {
2358bf80f4bSopenharmony_ci        return true;
2368bf80f4bSopenharmony_ci    }
2378bf80f4bSopenharmony_ci};
2388bf80f4bSopenharmony_ci} // namespace
2398bf80f4bSopenharmony_ci
2408bf80f4bSopenharmony_ci/**
2418bf80f4bSopenharmony_ci * @tc.name: CaptureTest
2428bf80f4bSopenharmony_ci * @tc.desc: test IObject function
2438bf80f4bSopenharmony_ci * @tc.type: FUNC
2448bf80f4bSopenharmony_ci * @tc.require: I7DMS1
2458bf80f4bSopenharmony_ci */
2468bf80f4bSopenharmony_ciHWTEST_F(CaptureTest, IObject, TestSize.Level1)
2478bf80f4bSopenharmony_ci{
2488bf80f4bSopenharmony_ci    RegisterObjectType<TestAttachment>();
2498bf80f4bSopenharmony_ci    IObject::Ptr obj = Object {}.GetIObject();
2508bf80f4bSopenharmony_ci    auto func = Capture(
2518bf80f4bSopenharmony_ci        [](IObject::Ptr p) {
2528bf80f4bSopenharmony_ci            if (auto a = interface_cast<IAttach>(p)) {
2538bf80f4bSopenharmony_ci                a->Attach(GetObjectRegistry().Create<IAttachment>(ClassId::TestAttachment));
2548bf80f4bSopenharmony_ci                return true;
2558bf80f4bSopenharmony_ci            }
2568bf80f4bSopenharmony_ci            return false;
2578bf80f4bSopenharmony_ci        },
2588bf80f4bSopenharmony_ci        obj);
2598bf80f4bSopenharmony_ci    EXPECT_TRUE(func());
2608bf80f4bSopenharmony_ci    EXPECT_EQ(interface_cast<IAttach>(obj)->GetAttachments().size(), 1);
2618bf80f4bSopenharmony_ci    obj.reset();
2628bf80f4bSopenharmony_ci    EXPECT_FALSE(func());
2638bf80f4bSopenharmony_ci    UnregisterObjectType<TestAttachment>();
2648bf80f4bSopenharmony_ci}
2658bf80f4bSopenharmony_ci} // namespace Test
2668bf80f4bSopenharmony_ciMETA_END_NAMESPACE()