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/deferred_callback.h>
19#include <meta/api/property/property_event_handler.h>
20#include <meta/ext/object.h>
21#include <meta/interface/intf_object_registry.h>
22#include <meta/interface/object_macros.h>
23#include <meta/interface/property/intf_property.h>
24
25#include "src/test_runner.h"
26#include "src/util.h"
27
28META_BEGIN_NAMESPACE()
29
30using namespace testing::ext;
31namespace {
32
33struct IOnTestInfo {
34    constexpr static BASE_NS::Uid UID { "3e55eee7-f0e4-4363-b4fc-65d8b3574a4e" };
35    constexpr static char const *name { "OnTest" };
36};
37
38using IOnTest = SimpleEvent<IOnTestInfo, void(int)>;
39
40using Callable = SimpleEvent<IOnTestInfo, void()>::InterfaceType;
41
42};
43
44
45class DeferredCallbackTest : public testing::Test {
46public:
47    static void SetUpTestSuite()
48    {
49        SetTest();
50    }
51    static void TearDownTestSuite()
52    {
53        ResetTest();
54    }
55    void SetUp() override {}
56    void TearDown() override {}
57};
58
59
60/**
61 * @tc.name: DeferredCallbackTest
62 * @tc.desc: test Call With Callable function
63 * @tc.type: FUNC
64 * @tc.require: I7DMS1
65 */
66HWTEST_F(DeferredCallbackTest, CallWithCallable, TestSize.Level1)
67{
68    auto& registry = META_NS::GetObjectRegistry();
69
70    int count = 0;
71    auto q = registry.Create<IPollingTaskQueue>(ClassId::PollingTaskQueue);
72    auto callback = MakeDeferred<Callable>([&] { ++count; }, q);
73    q->ProcessTasks();
74    EXPECT_EQ(count, 0);
75
76    callback->Invoke();
77    callback->Invoke();
78
79    EXPECT_EQ(count, 0);
80
81    q->ProcessTasks();
82    EXPECT_EQ(count, 2);
83}
84
85/**
86 * @tc.name: DeferredCallbackTest
87 * @tc.desc: test CallWithEvent function
88 * @tc.type: FUNC
89 * @tc.require: I7DMS1
90 */
91HWTEST_F(DeferredCallbackTest, CallWithEvent, TestSize.Level1)
92{
93    auto& registry = META_NS::GetObjectRegistry();
94
95    int count = 0;
96    auto q = registry.Create<IPollingTaskQueue>(ClassId::PollingTaskQueue);
97    auto callback = MakeDeferred<IOnTest>([&](int i) { count += i; }, q);
98    q->ProcessTasks();
99    EXPECT_EQ(count, 0);
100
101    callback->Invoke(1);
102    callback->Invoke(2);
103
104    EXPECT_EQ(count, 0);
105
106    q->ProcessTasks();
107    EXPECT_EQ(count, 3);
108}
109
110/**
111 * @tc.name: DeferredCallbackTest
112 * @tc.desc: test PropertyOnChange function
113 * @tc.type: FUNC
114 * @tc.require: I7DMS1
115 */
116HWTEST_F(DeferredCallbackTest, PropertyOnChange, TestSize.Level1)
117{
118    auto& registry = META_NS::GetObjectRegistry();
119
120    auto p = META_NS::ConstructProperty<int>(registry, "P", {});
121    ASSERT_TRUE(p);
122
123    int count = 0;
124    auto q = registry.Create<IPollingTaskQueue>(ClassId::PollingTaskQueue);
125
126    auto t = p->OnChanged()->AddHandler(MakeDeferred<IOnChanged>([&] { ++count; }, q));
127
128    p->SetValue(1);
129    EXPECT_EQ(count, 0);
130
131    q->ProcessTasks();
132    EXPECT_EQ(count, 1);
133
134    p->OnChanged()->RemoveHandler(t);
135
136    p->SetValue(2);
137    q->ProcessTasks();
138    EXPECT_EQ(count, 1);
139}
140
141/**
142 * @tc.name: DeferredCallbackTest
143 * @tc.desc: test PropertyChangedHandler function
144 * @tc.type: FUNC
145 * @tc.require: I7DMS1
146 */
147HWTEST_F(DeferredCallbackTest, PropertyChangedHandler, TestSize.Level1)
148{
149    auto& registry = META_NS::GetObjectRegistry();
150
151    auto p = META_NS::ConstructProperty<int>(registry, "p", {});
152    ASSERT_TRUE(p);
153
154    int count = 0;
155    auto q = registry.Create<IPollingTaskQueue>(ClassId::PollingTaskQueue);
156
157    PropertyChangedEventHandler handler_;
158    handler_.Subscribe(
159        p, [&] { ++count; }, q);
160
161    p->SetValue(1);
162
163    EXPECT_EQ(count, 0);
164    q->ProcessTasks();
165    EXPECT_EQ(count, 1);
166}
167
168/**
169 * @tc.name: DeferredCallbackTest
170 * @tc.desc: test PropertyChangedHandlerId function
171 * @tc.type: FUNC
172 * @tc.require: I7DMS1
173 */
174HWTEST_F(DeferredCallbackTest, PropertyChangedHandlerId, TestSize.Level1)
175{
176    auto& registry = META_NS::GetObjectRegistry();
177
178    auto p = META_NS::ConstructProperty<int>(registry, "P", {});
179    ASSERT_TRUE(p);
180
181    int count = 0;
182    auto q = registry.Create<IPollingTaskQueue>(ClassId::PollingTaskQueue);
183
184    auto queueId = interface_cast<IObjectInstance>(q)->GetInstanceId();
185    META_NS::GetTaskQueueRegistry().RegisterTaskQueue(q, queueId.ToUid());
186    PropertyChangedEventHandler handler_;
187    handler_.Subscribe(
188        p, [&] { ++count; }, queueId.ToUid());
189
190    p->SetValue(1);
191    EXPECT_EQ(count, 0);
192
193    q->ProcessTasks();
194    EXPECT_EQ(count, 1);
195
196    META_NS::GetTaskQueueRegistry().UnregisterTaskQueue(queueId.ToUid());
197}
198META_END_NAMESPACE()