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
16#include <gtest/gtest.h>
17
18#include <meta/api/function.h>
19#include <meta/interface/intf_metadata.h>
20
21#include "src/test_runner.h"s
22#include "src/testing_objects.h"
23#include "src/util.h"
24
25using namespace testing;
26using namespace testing::ext;
27
28namespace {
29    const int ZERO = 0; // test value for Set/Get function
30    const int ONE = 1; // test value for Set/Get function
31    const int TWO = 2; // test value for Set/Get function
32    const int THREE = 3; // test value for Set/Get function
33}
34
35META_BEGIN_NAMESPACE()
36
37class IntfMetadataTest : public testing::Test {
38public:
39    static void SetUpTestSuite()
40    {
41        SetTest();
42    }
43    static void TearDownTestSuite()
44    {
45        ResetTest();
46    }
47    void SetUp() override {}
48    void TearDown() override {}
49};
50
51/**
52 * @tc.name: IntfMetadataTest
53 * @tc.desc: test Functions function
54 * @tc.type: FUNC
55 * @tc.require: I7DMS1
56 */
57HWTEST_F(IntfMetadataTest, Functions, TestSize.Level1)
58{
59    auto p = CreateTestType();
60    ITestType::ConstPtr cp = p;
61
62    auto m = interface_cast<IMetadata>(p);
63    ASSERT_TRUE(m);
64
65    {
66        auto f = m->GetFunctionByName("MyTestFunc");
67        ASSERT_TRUE(f);
68        EXPECT_FALSE(CallMetaFunction<float>(f, 1));
69        EXPECT_FALSE(CallMetaFunction<int>(f, 0.0));
70        EXPECT_FALSE(CallMetaFunction<int>(f, 1, 1));
71        auto res = CallMetaFunction<int>(f, 1);
72        ASSERT_TRUE(res);
73        EXPECT_EQ(res.value, 1);
74        EXPECT_EQ(f->GetDestination(), interface_pointer_cast<IObject>(p));
75    }
76    {
77        auto f = m->GetFunctionByName("MyConstTestFunc");
78        ASSERT_TRUE(f);
79        auto res = CallMetaFunction<int>(f, 2);
80        ASSERT_TRUE(res);
81        EXPECT_EQ(res.value, 2);
82    }
83    {
84        auto f = m->GetFunctionByName("NormalMember");
85        ASSERT_TRUE(f);
86        auto res = CallMetaFunction<void>(f);
87        ASSERT_TRUE(res);
88    }
89    {
90        auto f = m->GetFunctionByName("OtherNormalMember");
91        ASSERT_TRUE(f);
92
93        auto c = f->CreateCallContext();
94        ASSERT_TRUE(c);
95        ASSERT_TRUE(Get<int>(c, "value"));
96        ASSERT_TRUE(Get<int>(c, "some"));
97
98        auto res = CallMetaFunction<int>(f, 2, 3);
99        ASSERT_TRUE(res);
100        EXPECT_EQ(res.value, 5);
101    }
102}
103
104/**
105 * @tc.name: IntfMetadataTest
106 * @tc.desc: test Events function
107 * @tc.type: FUNC
108 * @tc.require: I7DMS1
109 */
110HWTEST_F(IntfMetadataTest, Events, TestSize.Level1)
111{
112    auto p = CreateTestType();
113    auto m = interface_cast<IMetadata>(p);
114    ASSERT_TRUE(m);
115
116    auto e = m->GetEventByName("OnTest");
117    ASSERT_TRUE(e);
118}
119
120template<typename Set, typename Get>
121void TestGetSetValue(Set sp, Get gp)
122{
123    ASSERT_TRUE(SetValue(sp, "First", ONE));
124    ASSERT_EQ(GetValue(gp, "First", TWO), ONE);
125
126    ASSERT_TRUE(SetValue<int>(sp, "First", TWO));
127    ASSERT_EQ(GetValue<int>(gp, "First"), TWO);
128    ASSERT_EQ(GetValue<int>(gp, "First", ONE), TWO);
129
130    ASSERT_FALSE(SetValue<float>(sp, "First", TWO));
131    ASSERT_EQ(GetValue<float>(gp, "First"), ZERO);
132    ASSERT_EQ(GetValue<float>(gp, "First", ONE), ONE);
133
134    ASSERT_FALSE(SetValue(Set {}, "First", THREE));
135    Get nil {};
136    ASSERT_EQ(GetValue(nil, "First", THREE), THREE);
137    ASSERT_EQ(GetValue<int>(nil, "First", THREE), THREE);
138}
139
140template<typename Type>
141void TestGetSetValue(BASE_NS::shared_ptr<Type> p)
142{
143    BASE_NS::shared_ptr<const Type> c_p = p;
144    BASE_NS::weak_ptr<Type> w_p = p;
145    BASE_NS::weak_ptr<const Type> cw_p = p;
146
147    TestGetSetValue(p, p);
148    TestGetSetValue(p, c_p);
149    TestGetSetValue(p, w_p);
150    TestGetSetValue(p, cw_p);
151    TestGetSetValue(w_p, p);
152}
153
154/**
155 * @tc.name: IntfMetadataTest
156 * @tc.desc: test GetSetValue function
157 * @tc.type: FUNC
158 * @tc.require: I7DMS1
159 */
160HWTEST_F(IntfMetadataTest, GetSetValue, TestSize.Level1)
161{
162    auto p = CreateTestType();
163
164    TestGetSetValue<ITestType>(p);
165    TestGetSetValue<IMetadata>(interface_pointer_cast<IMetadata>(p));
166    TestGetSetValue<CORE_NS::IInterface>(interface_pointer_cast<CORE_NS::IInterface>(p));
167}
168
169template<typename Type>
170static auto* GetMeta(const BASE_NS::vector<Type>& vec, const BASE_NS::string& name)
171{
172    for (size_t i = 0; i != vec.size(); ++i) {
173        if (vec[i].name == name) {
174            return &vec[i];
175        }
176    }
177    return decltype(&vec[0])(nullptr);
178}
179
180/**
181 * @tc.name: IntfMetadataTest
182 * @tc.desc: test StaticMetadata function
183 * @tc.type: FUNC
184 * @tc.require: I7DMS1
185 */
186HWTEST_F(IntfMetadataTest, StaticMetadata, TestSize.Level1)
187{
188    EXPECT_EQ(META_NS::InterfaceId::ITestType.ReadableName(), "This is test type");
189    EXPECT_EQ(META_NS::InterfaceId::ITestContainer.ReadableName(), "ITestContainer");
190
191    auto fac = GetObjectRegistry().GetObjectFactory(ClassId::TestType);
192    ASSERT_TRUE(fac);
193    auto sm = fac->GetClassStaticMetadata();
194
195    auto p = GetMeta(sm.properties, "First");
196    ASSERT_TRUE(p);
197    ASSERT_TRUE(p->interfaceInfo.IsValid());
198    EXPECT_EQ(p->interfaceInfo.ReadableName(), "This is test type");
199
200    auto e = GetMeta(sm.events, "OnTest");
201    ASSERT_TRUE(e);
202    ASSERT_TRUE(e->interfaceInfo.IsValid());
203    EXPECT_EQ(e->interfaceInfo.ReadableName(), "This is test type");
204
205    auto f = GetMeta(sm.functions, "NormalMember");
206    ASSERT_TRUE(f);
207    ASSERT_TRUE(f->interfaceInfo.IsValid());
208    EXPECT_EQ(f->interfaceInfo.ReadableName(), "This is test type");
209}
210META_END_NAMESPACE()