• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 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 <gmock/gmock-matchers.h>
16 #include <gtest/gtest.h>
17 
18 #include <meta/api/array_util.h>
19 #include <meta/api/function.h>
20 #include <meta/api/object.h>
21 #include <meta/api/property/array_element_bind.h>
22 #include <meta/api/util.h>
23 #include <meta/ext/implementation_macros.h>
24 #include <meta/ext/minimal_object.h>
25 #include <meta/ext/object_fwd.h>
26 #include <meta/interface/property/array_property.h>
27 #include <meta/interface/property/construct_array_property.h>
28 #include <meta/interface/property/construct_property.h>
29 #include <meta/interface/property/property.h>
30 
31 #include "TestRunner.h"
32 #include "helpers/testing_objects.h"
33 #include "helpers/util.h"
34 
35 using namespace testing;
36 using namespace testing::ext;
37 
38 META_BEGIN_NAMESPACE()
39 
40 class PropertyTest : public testing::Test {
41 public:
SetUpTestSuite()42     static void SetUpTestSuite()
43     {
44         SetTest();
45     }
TearDownTestSuite()46     static void TearDownTestSuite()
47     {
48         TearDownTest();
49     }
SetUp()50     void SetUp() {}
TearDown()51     void TearDown() {}
52 };
53 
54 namespace {
55 struct TestType {
56     int i {};
57 };
58 } // namespace
59 
60 META_TYPE(TestType);
61 
62 /**
63  * @tc.name: Interfaces
64  * @tc.desc: test Interfaces
65  * @tc.type: FUNC
66  */
67 HWTEST_F(PropertyTest, Interfaces, TestSize.Level1)
68 {
69     auto p = ConstructProperty<int>("test");
70     EXPECT_TRUE(interface_cast<IObject>(p.GetProperty()));
71     EXPECT_TRUE(interface_cast<INotifyOnChange>(p.GetProperty()));
72     EXPECT_TRUE(interface_cast<IPropertyInternal>(p.GetProperty()));
73     EXPECT_TRUE(interface_cast<IPropertyInternalAny>(p.GetProperty()));
74     EXPECT_TRUE(interface_cast<IStackProperty>(p.GetProperty()));
75 }
76 
77 /**
78  * @tc.name: Values
79  * @tc.desc: test Values
80  * @tc.type: FUNC
81  */
82 HWTEST_F(PropertyTest, Values, TestSize.Level1)
83 {
84     auto p = ConstructProperty<int>("test");
85 
86     EXPECT_EQ(p->GetValue(), 0);
87     p->SetDefaultValue(2);
88     EXPECT_EQ(p->GetDefaultValue(), 2);
89     EXPECT_EQ(p->GetValue(), 2);
90     p->SetValue(3);
91     EXPECT_EQ(p->GetValue(), 3);
92     p->ResetValue();
93     EXPECT_EQ(p->GetValue(), 2);
94 }
95 
96 /**
97  * @tc.name: Misc
98  * @tc.desc: test Misc
99  * @tc.type: FUNC
100  */
101 HWTEST_F(PropertyTest, Misc, TestSize.Level1)
102 {
103     Object owner(CreateNew);
104     auto p = ConstructProperty<int>("test");
105     if (auto pp = interface_pointer_cast<IPropertyInternal>(p.GetProperty())) {
106         pp->SetOwner(interface_pointer_cast<IOwner>(owner));
107     }
108     EXPECT_EQ(p->GetTypeId(), UidFromType<int>());
109     EXPECT_TRUE(p->IsCompatible(UidFromType<int>()));
110     EXPECT_EQ(p->GetName(), "test");
111     EXPECT_EQ(p->GetOwner().lock(), interface_pointer_cast<IOwner>(owner));
112 }
113 
114 /**
115  * @tc.name: OnChangedEvent
116  * @tc.desc: test OnChangedEvent
117  * @tc.type: FUNC
118  */
119 HWTEST_F(PropertyTest, OnChangedEvent, TestSize.Level1)
120 {
121     auto p = ConstructProperty<int>("test");
122 
123     // does nothing as there are no handlers added
124     p.GetProperty()->NotifyChange();
125 
126     int count = 0;
__anon2a475bbc0202null127     p->OnChanged()->AddHandler(MakeCallback<IOnChanged>([&] { ++count; }));
128 
129     p->SetDefaultValue(2);
130     EXPECT_EQ(count, 1);
131 
132     p->SetValue(2);
133     EXPECT_EQ(count, 2);
134 
135     // settings default does not notify after we have value
136     p->SetDefaultValue(2);
137     EXPECT_EQ(count, 2);
138     {
139         auto acc = p.GetLockedAccess();
140         acc.SetValue(3);
141         EXPECT_EQ(count, 2);
142     }
143     EXPECT_EQ(count, 3);
144     {
145         auto acc = p.GetUnlockedAccess();
146         acc.SetValue(4);
147         EXPECT_EQ(count, 4);
148     }
149     // setting same value does not notify
150     p->SetValue(4);
151     EXPECT_EQ(count, 4);
152 
153     p->ResetValue();
154     EXPECT_EQ(count, 5);
155 
156     p.GetProperty()->NotifyChange();
157     EXPECT_EQ(count, 6);
158 }
159 
160 /**
161  * @tc.name: OnChangedEventWithBind
162  * @tc.desc: test OnChangedEventWithBind
163  * @tc.type: FUNC
164  */
165 HWTEST_F(PropertyTest, OnChangedEventWithBind, TestSize.Level1)
166 {
167     auto p = ConstructProperty<int>("test");
168     auto source = ConstructProperty<int>("source");
169     source->SetValue(2);
170 
171     int count = 0;
__anon2a475bbc0302null172     p->OnChanged()->AddHandler(MakeCallback<IOnChanged>([&] { ++count; }));
173 
174     EXPECT_TRUE(p->SetBind(source));
175     EXPECT_EQ(count, 1);
176     EXPECT_EQ(p->GetValue(), 2);
177 
178     source->SetValue(3);
179     EXPECT_EQ(count, 2);
180     EXPECT_EQ(p->GetValue(), 3);
181 }
182 
183 /**
184  * @tc.name: OnChangedEventWithValues
185  * @tc.desc: test OnChangedEventWithValues
186  * @tc.type: FUNC
187  */
188 HWTEST_F(PropertyTest, OnChangedEventWithValues, TestSize.Level1)
189 {
190     auto p = ConstructProperty<int>("test");
191     auto a = ConstructProperty<int>("a");
192     auto b = ConstructProperty<int>("b");
193 
194     int count = 0;
__anon2a475bbc0402null195     p->OnChanged()->AddHandler(MakeCallback<IOnChanged>([&] { ++count; }));
196 
197     p->PushValue(a.GetProperty());
198     EXPECT_EQ(count, 1);
199     p->PushValue(b.GetProperty());
200     EXPECT_EQ(count, 2);
201     interface_cast<IStackProperty>(p.GetProperty())->RemoveValue(interface_pointer_cast<IValue>(a));
202     EXPECT_EQ(count, 2);
203     p->PopValue();
204     EXPECT_EQ(count, 3);
205 }
206 
207 /**
208  * @tc.name: PropertyBind
209  * @tc.desc: test PropertyBind
210  * @tc.type: FUNC
211  */
212 HWTEST_F(PropertyTest, PropertyBind, TestSize.Level1)
213 {
214     auto p = ConstructProperty<int>("test");
215     auto source = ConstructProperty<int>("source");
216     source->SetValue(2);
217 
218     EXPECT_TRUE(p->SetBind(source));
219     EXPECT_EQ(p->GetValue(), 2);
220 
221     source->SetValue(3);
222     EXPECT_EQ(p->GetValue(), 3);
223 
224     source->ResetValue();
225     EXPECT_EQ(p->GetValue(), 0);
226 }
227 
228 /**
229  * @tc.name: FunctionBind
230  * @tc.desc: test FunctionBind
231  * @tc.type: FUNC
232  */
233 HWTEST_F(PropertyTest, FunctionBind, TestSize.Level1)
234 {
235     auto p = ConstructProperty<int>("test");
236     auto source = CreateTestType("source");
237     auto mdata = interface_cast<IMetadata>(source);
238 
239     auto f = mdata->GetFunction("NormalMember");
240     ASSERT_TRUE(f);
241     EXPECT_TRUE(p->SetBind(f));
242 
243     source->First()->SetValue(3);
244     EXPECT_EQ(p->GetValue(), 3);
245 
246     source->First()->SetValue(4);
247     EXPECT_EQ(p->GetValue(), 4);
248 }
249 
250 /**
251  * @tc.name: LambdaBindMultiDep
252  * @tc.desc: test LambdaBindMultiDep
253  * @tc.type: FUNC
254  */
255 HWTEST_F(PropertyTest, LambdaBindMultiDep, TestSize.Level1)
256 {
257     auto p = ConstructProperty<int>("test");
258     auto s1 = ConstructProperty<int>("s1");
259     auto s2 = ConstructProperty<int>("s2");
260     auto s3 = ConstructProperty<int>("s3");
261 
__anon2a475bbc0502null262     ASSERT_TRUE(s2->SetBind(CreateBindFunction([&] { return s3->GetValue(); })));
__anon2a475bbc0602null263     ASSERT_TRUE(p->SetBind(CreateBindFunction([&] { return s1->GetValue() + s2->GetValue(); })));
264 
265     s3->SetValue(3);
266     EXPECT_EQ(p->GetValue(), 3);
267 
268     s1->SetValue(2);
269     EXPECT_EQ(p->GetValue(), 5);
270 
271     s2->SetValue(5);
272     EXPECT_EQ(p->GetValue(), 7);
273 }
274 
275 /**
276  * @tc.name: LambdaBindInvalid
277  * @tc.desc: test LambdaBindInvalid
278  * @tc.type: FUNC
279  */
280 HWTEST_F(PropertyTest, LambdaBindInvalid, TestSize.Level1)
281 {
282     auto p = ConstructProperty<int>("test");
283     auto s1 = ConstructProperty<int>("s1");
284 
__anon2a475bbc0702null285     ASSERT_TRUE(s1->SetBind(CreateBindFunction([&] { return p->GetValue(); })));
286     p->SetValue(2);
287     EXPECT_EQ(s1->GetValue(), 2);
__anon2a475bbc0802null288     ASSERT_FALSE(p->SetBind(CreateBindFunction([&] { return s1->GetValue(); })));
289 
290     s1->SetValue(3);
291     EXPECT_EQ(p->GetValue(), 2);
292 
293     p->SetValue(4);
294     EXPECT_EQ(p->GetValue(), 4);
295 }
296 
297 /**
298  * @tc.name: LambdaBind
299  * @tc.desc: test LambdaBind
300  * @tc.type: FUNC
301  */
302 HWTEST_F(PropertyTest, LambdaBind, TestSize.Level1)
303 {
304     auto p = ConstructProperty<int>("test");
__anon2a475bbc0902null305     EXPECT_TRUE(p->SetBind(CreateBindFunction([] { return 5; })));
306     EXPECT_EQ(p->GetValue(), 5);
307 
__anon2a475bbc0a02(auto...) 308     EXPECT_TRUE(p->SetBind(CreateBindFunction([](auto...) { return 5; })));
__anon2a475bbc0b02(auto...) 309     EXPECT_TRUE(p->SetBind(CreateBindFunction([](auto...) mutable { return 5; })));
310 }
311 
312 /**
313  * @tc.name: LambdaBindWithDependency
314  * @tc.desc: test LambdaBindWithDependency
315  * @tc.type: FUNC
316  */
317 HWTEST_F(PropertyTest, LambdaBindWithDependency, TestSize.Level1)
318 {
319     auto p = ConstructProperty<int>("test");
320     auto source = ConstructProperty<int>("source");
321     source->SetValue(2);
__anon2a475bbc0c02null322     EXPECT_TRUE(p->SetBind(CreateBindFunction([&] { return source->GetValue(); }),
323         (BASE_NS::vector<INotifyOnChange::ConstPtr> { source.GetProperty() })));
324     EXPECT_EQ(p->GetValue(), 2);
325     source->SetValue(4);
326     EXPECT_EQ(p->GetValue(), 4);
327 }
328 
329 /**
330  * @tc.name: MultipleBinds
331  * @tc.desc: test MultipleBinds
332  * @tc.type: FUNC
333  */
334 HWTEST_F(PropertyTest, MultipleBinds, TestSize.Level1)
335 {
336     auto p = ConstructProperty<int>("test");
337     auto source1 = ConstructProperty<int>("source1", 1);
338     auto source2 = ConstructProperty<int>("source2", 2);
339 
340     EXPECT_EQ(p->GetStackProperty()->GetValues({}, false).size(), 0);
341 
342     EXPECT_TRUE(p->SetBind(source1));
343     EXPECT_EQ(p->GetValue(), 1);
344 
345     EXPECT_EQ(p->GetStackProperty()->GetValues({}, false).size(), 1);
346 
347     EXPECT_TRUE(p->SetBind(source2));
348     EXPECT_EQ(p->GetValue(), 2);
349 
350     EXPECT_EQ(p->GetStackProperty()->GetValues({}, false).size(), 1);
351 }
352 
353 /**
354  * @tc.name: BindingBind
355  * @tc.desc: test BindingBind
356  * @tc.type: FUNC
357  */
358 HWTEST_F(PropertyTest, BindingBind, TestSize.Level1)
359 {
360     auto p1 = ConstructProperty<int>("p1", 0);
361     auto p2 = ConstructProperty<int>("p2", 0);
362     auto p3 = ConstructProperty<int>("p3", 0);
363 
364     p3->SetValue(2);
365 
__anon2a475bbc0d02() 366     EXPECT_TRUE(p1->SetBind(CreateBindFunction([&]() {
367         p2->SetBind(CreateBindFunction([&p3]() { return p3->GetValue(); }));
368         return p2->GetValue();
369     })));
370 
371     EXPECT_EQ(p1->GetValue(), 2);
372 }
373 
374 /**
375  * @tc.name: PropertyInProperty
376  * @tc.desc: test PropertyInProperty
377  * @tc.type: FUNC
378  */
379 HWTEST_F(PropertyTest, PropertyInProperty, TestSize.Level1)
380 {
381     auto p1 = ConstructProperty<int>("p1");
382     auto p2 = ConstructProperty<int>("p2");
383     auto sp1 = interface_cast<IStackProperty>(p1.GetProperty());
384     auto vp2 = interface_pointer_cast<IValue>(p2.GetProperty());
385     ASSERT_TRUE(sp1);
386     ASSERT_TRUE(vp2);
387 
388     EXPECT_TRUE(sp1->PushValue(vp2));
389     EXPECT_EQ(p1->GetValue(), 0);
390     p2->SetValue(2);
391     EXPECT_EQ(p1->GetValue(), 2);
392     p1->SetValue(5);
393     EXPECT_EQ(p1->GetValue(), 5);
394     EXPECT_EQ(p2->GetValue(), 5);
395 }
396 
397 /**
398  * @tc.name: ResetInternalAny
399  * @tc.desc: test ResetInternalAny
400  * @tc.type: FUNC
401  */
402 HWTEST_F(PropertyTest, ResetInternalAny, TestSize.Level1)
403 {
404     auto p = ConstructProperty<int>("test");
405 
406     EXPECT_EQ(p->GetValue(), 0);
407     p->SetDefaultValue(2);
408     EXPECT_EQ(p->GetDefaultValue(), 2);
409     EXPECT_EQ(p->GetValue(), 2);
410     p->SetValue(3);
411     EXPECT_EQ(p->GetValue(), 3);
412 
413     auto i = interface_cast<IPropertyInternalAny>(p.GetProperty());
414     ASSERT_TRUE(i);
415     i->SetInternalAny(IAny::Ptr(new Any<BASE_NS::string>));
416 
417     Property<BASE_NS::string> s(p.GetProperty());
418     ASSERT_TRUE(s);
419 
420     EXPECT_EQ(s->GetValue(), "");
421     s->SetDefaultValue("ab");
422     EXPECT_EQ(s->GetDefaultValue(), "ab");
423     EXPECT_EQ(s->GetValue(), "ab");
424     s->SetValue("xx");
425     EXPECT_EQ(s->GetValue(), "xx");
426 }
427 
428 /**
429  * @tc.name: RecursiveProperty
430  * @tc.desc: test RecursiveProperty
431  * @tc.type: FUNC
432  */
433 HWTEST_F(PropertyTest, RecursiveProperty, TestSize.Level1)
434 {
435     auto p = ConstructProperty<int>("test");
436     auto stack = interface_cast<IStackProperty>(p->GetProperty());
437     EXPECT_EQ(p->PushValue(p.GetProperty()).GetError(), GenericError::RECURSIVE_CALL);
438 
439     auto p2 = ConstructProperty<int>("test2");
440     p2->PushValue(p.GetProperty());
441     EXPECT_EQ(p->PushValue(p2.GetProperty()).GetError(), GenericError::RECURSIVE_CALL);
442 }
443 
444 /**
445  * @tc.name: Reset
446  * @tc.desc: test Reset
447  * @tc.type: FUNC
448  */
449 HWTEST_F(PropertyTest, Reset, TestSize.Level1)
450 {
451     auto p = ConstructProperty<int>("test");
452 
453     EXPECT_EQ(p->GetValue(), 0);
454     p->SetDefaultValue(2);
455     EXPECT_EQ(p->GetDefaultValue(), 2);
456     EXPECT_EQ(p->GetValue(), 2);
457     p->SetValue(3);
458     EXPECT_EQ(p->GetValue(), 3);
459     p->Reset();
460     EXPECT_EQ(p->GetValue(), 2);
461 }
462 
463 /**
464  * @tc.name: ResetWithSharedPointer
465  * @tc.desc: test ResetWithSharedPointer
466  * @tc.type: FUNC
467  */
468 HWTEST_F(PropertyTest, ResetWithSharedPointer, TestSize.Level1)
469 {
470     auto p = ConstructProperty<IObject::Ptr>("test");
471     auto obj = CreateTestType<IObject>();
472     BASE_NS::weak_ptr<IObject> w = obj;
473     p->SetValue(obj);
474     obj.reset();
475     EXPECT_TRUE(w.lock());
476     p->Reset();
477     EXPECT_FALSE(w.lock());
478 }
479 
480 /**
481  * @tc.name: UserType
482  * @tc.desc: test UserType
483  * @tc.type: FUNC
484  */
485 HWTEST_F(PropertyTest, UserType, TestSize.Level1)
486 {
487     auto p = ConstructProperty<TestType>("test");
488     EXPECT_EQ(p->GetValue().i, 0);
489     EXPECT_TRUE(p->SetValue(TestType { 1 }));
490     EXPECT_EQ(p->GetValue().i, 1);
491 }
492 
493 /**
494  * @tc.name: BindingMultiDep
495  * @tc.desc: test BindingMultiDep
496  * @tc.type: FUNC
497  */
498 HWTEST_F(PropertyTest, BindingMultiDep, TestSize.Level1)
499 {
500     auto p1 = ConstructProperty<int>("test1");
501     auto p2 = ConstructProperty<int>("test2");
502     auto p3 = ConstructProperty<int>("test3");
503     auto p4 = ConstructProperty<int>("test4");
504 
505     p3->SetValue(2);
506 
__anon2a475bbc0f02null507     EXPECT_TRUE(p1->SetBind(CreateBindFunction([&p3] { return p3->GetValue(); }),
508         (BASE_NS::vector<INotifyOnChange::ConstPtr> { p3.GetProperty() })));
__anon2a475bbc1002null509     EXPECT_TRUE(p2->SetBind(CreateBindFunction([&p3] { return p3->GetValue(); }),
510         (BASE_NS::vector<INotifyOnChange::ConstPtr> { p3.GetProperty() })));
511 
__anon2a475bbc1102null512     EXPECT_TRUE(p4->SetBind(CreateBindFunction([&p1, &p2] { return p1->GetValue() + p2->GetValue(); }),
513         (BASE_NS::vector<INotifyOnChange::ConstPtr> { p1.GetProperty(), p2.GetProperty() })));
514 
515     EXPECT_EQ(p4->GetValue(), 4);
516     p3->SetValue(3);
517     EXPECT_EQ(p4->GetValue(), 6);
518 }
519 
520 /**
521  * @tc.name: ObjectFlags
522  * @tc.desc: test ObjectFlags
523  * @tc.type: FUNC
524  */
525 HWTEST_F(PropertyTest, ObjectFlags, TestSize.Level1)
526 {
527     auto p = ConstructProperty<int>("test", 0, ObjectFlagBits::INTERNAL);
528     EXPECT_TRUE(IsFlagSet(p.GetProperty(), ObjectFlagBits::INTERNAL));
529     EXPECT_FALSE(IsFlagSet(p.GetProperty(), ObjectFlagBits::SERIALIZE));
530 
531     auto test = CreateTestType();
532     EXPECT_TRUE(IsFlagSet(test->First().GetProperty(), DEFAULT_PROPERTY_FLAGS));
533     EXPECT_TRUE(IsFlagSet(
534         test->Second().GetProperty(), ObjectFlagBitsValue { ObjectFlagBits::INTERNAL } | ObjectFlagBits::NATIVE));
535 }
536 
537 /**
538  * @tc.name: Conversions
539  * @tc.desc: test Conversions
540  * @tc.type: FUNC
541  */
542 HWTEST_F(PropertyTest, Conversions, TestSize.Level1)
543 {
544     Property<int> p = ConstructProperty<int>("test");
545     ASSERT_TRUE(p.IsValid());
546     Property<const int> constp = p;
547     IProperty::Ptr ptrp = p;
548     IProperty::ConstPtr constptrp = p;
549     IProperty::ConstPtr constptrp2 = constp;
550     IProperty::WeakPtr wp = p;
551     IProperty::ConstWeakPtr constwp = p;
552     IProperty::ConstWeakPtr constwp2 = constp;
553     Property<const int> cp1 = ptrp;
554     Property<const int> cp2 = constptrp;
555     EXPECT_TRUE(interface_pointer_cast<IStackProperty>(p));
556     EXPECT_TRUE(interface_cast<IStackProperty>(p));
557 }
558 
559 /**
560  * @tc.name: IncompatibleValue
561  * @tc.desc: test IncompatibleValue
562  * @tc.type: FUNC
563  */
564 HWTEST_F(PropertyTest, IncompatibleValue, TestSize.Level1)
565 {
566     auto p = ConstructProperty<int>("test");
567     auto s = ConstructProperty<BASE_NS::string>("test");
568     EXPECT_EQ(p->PushValue(s.GetProperty()).GetError(), GenericError::INCOMPATIBLE_TYPES);
569 }
570 
571 /**
572  * @tc.name: CompatiblePtrValue
573  * @tc.desc: test CompatiblePtrValue
574  * @tc.type: FUNC
575  */
576 HWTEST_F(PropertyTest, CompatiblePtrValue, TestSize.Level1)
577 {
578     auto p = ConstructProperty<IObject::Ptr>("test");
579     auto obj = CreateTestType();
580 
581     EXPECT_TRUE(p->SetValueAny(Any<SharedPtrIInterface>(interface_pointer_cast<CORE_NS::IInterface>(obj))));
582     EXPECT_EQ(p->GetValue(), interface_pointer_cast<IObject>(obj));
583 }
584 
585 /**
586  * @tc.name: SetValueSafeInit
587  * @tc.desc: test SetValueSafeInit
588  * @tc.type: FUNC
589  */
590 HWTEST_F(PropertyTest, SetValueSafeInit, TestSize.Level1)
591 {
592     Property<int> p(NOCHECK, GetObjectRegistry().GetPropertyRegister().Create(META_NS::ClassId::StackProperty, "Test"));
593 
594     int i = 0;
595     EXPECT_FALSE(p->GetValueAny().GetValue(i));
596 
597     EXPECT_TRUE(p->SetValue(2));
598     EXPECT_EQ(p->GetValue(), 2);
599     EXPECT_TRUE(Property<int>(p));
600 }
601 
602 /**
603  * @tc.name: ValuePtr
604  * @tc.desc: test ValuePtr
605  * @tc.type: FUNC
606  */
607 HWTEST_F(PropertyTest, ValuePtr, TestSize.Level1)
608 {
609     auto obj = GetObjectRegistry().Create<ITestPtrValue>(ClassId::TestPtrValue);
610     ASSERT_TRUE(obj);
611     ASSERT_TRUE(obj->Text()->GetValue());
612     EXPECT_EQ(obj->Text()->GetValue()->GetString(), "Some");
613     EXPECT_TRUE(obj->Text()->SetValueAny(Any<BASE_NS::string>("Hips")));
614     EXPECT_EQ(obj->Text()->GetValue()->GetString(), "Hips");
615 
616     auto str = GetObjectRegistry().Create<ITestString>(ClassId::TestString);
617     ASSERT_TRUE(str);
618     str->SetString("Hoo'o");
619 
620     EXPECT_TRUE(obj->Text()->SetValue(str));
621     EXPECT_EQ(obj->Text()->GetValue()->GetString(), "Hoo'o");
622 }
623 
624 /**
625  * @tc.name: ValuePtrBind
626  * @tc.desc: test ValuePtrBind
627  * @tc.type: FUNC
628  */
629 HWTEST_F(PropertyTest, ValuePtrBind, TestSize.Level1)
630 {
631     auto obj = GetObjectRegistry().Create<ITestString>(ClassId::TestString);
632     ASSERT_TRUE(obj);
633     obj->SetString("hahah");
634 
635     auto p = ConstructProperty<ValuePtr<ITestString, ClassId::TestString>>("Test", BASE_NS::string("empty"));
636     auto strProp = ConstructProperty<BASE_NS::string>("Test", "huuhaa");
637     auto strPtrProp = ConstructProperty<ITestString::Ptr>("Test", obj);
638 
639     EXPECT_EQ(p->GetValue()->GetString(), "empty");
640 
641     ASSERT_TRUE(p->SetBind(strProp));
642     EXPECT_EQ(p->GetValue()->GetString(), "huuhaa");
643 
644     ASSERT_TRUE(p->SetBind(strPtrProp));
645     EXPECT_EQ(p->GetValue()->GetString(), "hahah");
646 
647     auto strP = ConstructProperty<BASE_NS::string>("Test");
648     ASSERT_TRUE(strP->SetBind(p));
649     EXPECT_EQ(strP->GetValue(), "hahah");
650 }
651 
652 /**
653  * @tc.name: ValuePtrDefaultValue
654  * @tc.desc: test ValuePtrDefaultValue
655  * @tc.type: FUNC
656  */
657 HWTEST_F(PropertyTest, ValuePtrDefaultValue, TestSize.Level1)
658 {
659     auto p = ConstructProperty<ValuePtr<ITestString, ClassId::TestString>>("Test", BASE_NS::string("hih"));
660 
661     int count = 0;
__anon2a475bbc1202null662     p->OnChanged()->AddHandler(MakeCallback<IOnChanged>([&] { ++count; }));
663     EXPECT_EQ(p->GetValue()->GetString(), "hih");
664     ITestString::Ptr str;
665     ASSERT_TRUE(p->GetDefaultValueAny().GetValue(str));
666     ASSERT_TRUE(str);
667     str->SetString("hips");
668     EXPECT_EQ(p->GetValue()->GetString(), "hips");
669     EXPECT_EQ(count, 1);
670 }
671 
672 /**
673  * @tc.name: MultiOnChangedWithSameHandle
674  * @tc.desc: test MultiOnChangedWithSameHandle
675  * @tc.type: FUNC
676  */
677 HWTEST_F(PropertyTest, MultiOnChangedWithSameHandle, TestSize.Level1)
678 {
679     auto p = ConstructProperty<int>("test");
680 
681     int count = 0;
__anon2a475bbc1302null682     EXPECT_TRUE(p->OnChanged()->AddHandler(MakeCallback<IOnChanged>([&] { ++count; }), uintptr_t(1)));
__anon2a475bbc1402null683     EXPECT_TRUE(p->OnChanged()->AddHandler(MakeCallback<IOnChanged>([&] { ++count; }), uintptr_t(1)));
684 
685     p->SetValue(1);
686     EXPECT_EQ(count, 1);
687 
688     EXPECT_TRUE(p->OnChanged()->RemoveHandler(uintptr_t(1)));
689 
690     p->SetValue(2);
691     EXPECT_EQ(count, 2);
692 
693     EXPECT_TRUE(p->OnChanged()->RemoveHandler(uintptr_t(1)));
694 
695     p->SetValue(3);
696     EXPECT_EQ(count, 2);
697 }
698 
699 META_REGISTER_CLASS(PropertyOwnerTest, "2ab1b570-f44d-4fe3-9d40-4ed02294cee6", META_NS::ObjectCategoryBits::NO_CATEGORY)
700 class PropertyOwnerTest final : public IntroduceInterfaces<META_NS::ObjectFwd, IEmbeddedTestType, IPropertyOwner> {
META_OBJECT(PropertyOwnerTest,ClassId::PropertyOwnerTest,IntroduceInterfaces)701     META_OBJECT(PropertyOwnerTest, ClassId::PropertyOwnerTest, IntroduceInterfaces)
702 
703     META_BEGIN_STATIC_DATA()
704     META_STATIC_PROPERTY_DATA(IEmbeddedTestType, int, Property)
705     META_END_STATIC_DATA()
706     META_IMPLEMENT_PROPERTY(int, Property)
707 
708     void OnPropertyChanged(const IProperty& p) override
709     {
710         changed_ = p.GetName() == "Property";
711     }
712 
713 public:
714     bool changed_ {};
715 };
716 
717 /**
718  * @tc.name: PropertyOwner
719  * @tc.desc: test PropertyOwner
720  * @tc.type: FUNC
721  */
722 HWTEST_F(PropertyTest, PropertyOwner, TestSize.Level1)
723 {
724     RegisterObjectType<PropertyOwnerTest>();
725     auto object = GetObjectRegistry().Create(ClassId::PropertyOwnerTest);
726     ASSERT_TRUE(object);
727 
728     interface_cast<IEmbeddedTestType>(object)->Property()->SetValue(1);
729     PropertyOwnerTest* p = static_cast<PropertyOwnerTest*>(object.get());
730     EXPECT_TRUE(p->changed_);
731 
732     UnregisterObjectType<PropertyOwnerTest>();
733 }
734 
735 /**
736  * @tc.name: DisableEventHandler
737  * @tc.desc: test DisableEventHandler
738  * @tc.type: FUNC
739  */
740 HWTEST_F(PropertyTest, DisableEventHandler, TestSize.Level1)
741 {
742     auto p = ConstructProperty<int>("test");
743     ASSERT_TRUE(p);
744 
745     int count = 0;
__anon2a475bbc1502null746     auto token = p->OnChanged()->AddHandler(MakeCallback<IOnChanged>([&] { ++count; }));
747 
748     p->SetValue(1);
749     EXPECT_EQ(count, 1);
750 
751     {
752         ScopedDisableEventHandler scoped(p->OnChanged(), token);
753         p->SetValue(2);
754         EXPECT_EQ(count, 1);
755     }
756     p->SetValue(3);
757     EXPECT_EQ(count, 2);
758 }
759 
760 /**
761  * @tc.name: PointerValueLifetime
762  * @tc.desc: test PointerValueLifetime
763  * @tc.type: FUNC
764  */
765 HWTEST_F(PropertyTest, PointerValueLifetime, TestSize.Level1)
766 {
767     auto p = ConstructProperty<IObject::Ptr>("test");
768     auto obj = CreateTestType<IObject>();
769     IObject::WeakPtr w = obj;
770 
771     p->SetValue(obj);
772     obj.reset();
773     EXPECT_TRUE(p->GetValue());
774     p->SetValue(nullptr);
775 
776     EXPECT_FALSE(w.lock());
777 }
778 
779 /**
780  * @tc.name: ValidPropertyLock
781  * @tc.desc: test ValidPropertyLock
782  * @tc.type: FUNC
783  */
784 HWTEST_F(PropertyTest, ValidPropertyLock, TestSize.Level1)
785 {
786     {
787         auto p = ConstructProperty<int>("p").GetProperty();
788         PropertyLock lock { p };
789         EXPECT_TRUE(lock);
790         EXPECT_TRUE(lock.IsValid());
791         EXPECT_TRUE(lock.GetProperty());
792 
793         TypedPropertyLock<int> typedLock { p };
794         EXPECT_TRUE(typedLock);
795         EXPECT_TRUE(typedLock.IsValid());
796         EXPECT_TRUE(typedLock.GetProperty());
797 
798         TypedPropertyLock<float> bad { p };
799         EXPECT_FALSE(bad);
800         EXPECT_FALSE(bad.IsValid());
801         EXPECT_FALSE(bad.GetProperty());
802     }
803     {
804         auto p = ConstructArrayProperty<int>("p").GetProperty();
805         PropertyLock lock { p };
806         EXPECT_TRUE(lock);
807         EXPECT_TRUE(lock.IsValid());
808         EXPECT_TRUE(lock.GetProperty());
809 
810         TypedPropertyLock<int> typedLock { p };
811         EXPECT_FALSE(typedLock);
812         EXPECT_FALSE(typedLock.IsValid());
813         EXPECT_FALSE(typedLock.GetProperty());
814 
815         TypedPropertyLock<float> bad { p };
816         EXPECT_FALSE(bad);
817         EXPECT_FALSE(bad.IsValid());
818         EXPECT_FALSE(bad.GetProperty());
819     }
820 }
821 
822 /**
823  * @tc.name: PropertyHelpers
824  * @tc.desc: test PropertyHelpers
825  * @tc.type: FUNC
826  */
827 HWTEST_F(PropertyTest, PropertyHelpers, TestSize.Level1)
828 {
829     auto obj = CreateTestType<IObject>();
830     auto p = ConstructProperty<IObject::Ptr>("test", obj);
831 
832     EXPECT_FALSE(IsGetPointerArray(p));
833     EXPECT_FALSE(IsSetPointerArray(p));
834 
835     EXPECT_TRUE(IsGetPointer(p));
836     EXPECT_EQ(GetPointer(p), interface_pointer_cast<CORE_NS::IInterface>(obj));
837     EXPECT_EQ(GetPointer<IObject>(p), obj);
838 
839     auto other = CreateTestType<IObject>();
840 
841     EXPECT_TRUE(IsSetPointer(p));
842     EXPECT_TRUE(SetPointer(p, other));
843     EXPECT_EQ(GetPointer(p), interface_pointer_cast<CORE_NS::IInterface>(other));
844 
845     auto cp = ConstructProperty<IObject::ConstPtr>("test", obj);
846     EXPECT_TRUE(IsGetPointer(cp));
847     EXPECT_TRUE(IsSetPointer(cp));
848     EXPECT_TRUE(SetPointer(cp, other));
849     EXPECT_EQ(GetConstPointer(cp), interface_pointer_cast<CORE_NS::IInterface>(other));
850 
851     IObject::ConstPtr some = CreateTestType<IObject>();
852     EXPECT_TRUE(SetPointer(cp, some));
853     EXPECT_EQ(GetConstPointer(cp), interface_pointer_cast<CORE_NS::IInterface>(some));
854 }
855 
856 /**
857  * @tc.name: UnlockedOnChanged
858  * @tc.desc: test UnlockedOnChanged
859  * @tc.type: FUNC
860  */
861 HWTEST_F(PropertyTest, UnlockedOnChanged, TestSize.Level1)
862 {
863     auto prop = ConstructProperty<int>("test");
864     auto p = prop.GetProperty();
865 
866     int count = 0;
__anon2a475bbc1602null867     prop->OnChanged()->AddHandler(MakeCallback<IOnChanged>([&] {
868         ++count;
869         EXPECT_EQ(GetValue<int>(p->GetValue()), count);
870     }));
871 
872     p->SetValue(Any<int>(1));
873 }
874 
875 /**
876  * @tc.name: IsDefault
877  * @tc.desc: test IsDefault
878  * @tc.type: FUNC
879  */
880 HWTEST_F(PropertyTest, IsDefault, TestSize.Level1)
881 {
882     auto prop = ConstructProperty<int>("test", 1);
883     EXPECT_TRUE(prop->IsDefaultValue());
884     EXPECT_EQ(prop->GetValue(), 1);
885     prop->SetValue(2);
886     EXPECT_FALSE(prop->IsDefaultValue());
887     EXPECT_EQ(prop->GetValue(), 2);
888     prop->ResetValue();
889     EXPECT_TRUE(prop->IsDefaultValue());
890     EXPECT_EQ(prop->GetValue(), 1);
891 }
892 
893 META_REGISTER_CLASS(StaticValueTestMod, "3aff3770-0681-45b7-ab56-fe4487883a7a", ObjectCategory::NO_CATEGORY)
894 
895 class StaticValueTestMod : public IntroduceInterfaces<MinimalObject, IModifier> {
896     META_IMPLEMENT_OBJECT_TYPE_INTERFACE(ClassId::StaticValueTestMod)
897 public:
ProcessOnGet(IAny & value)898     EvaluationResult ProcessOnGet(IAny& value) override
899     {
900         value.SetValue<uint32_t>(4);
901         return EVAL_VALUE_CHANGED;
902     }
ProcessOnSet(IAny & value,const IAny & current)903     EvaluationResult ProcessOnSet(IAny& value, const IAny& current) override
904     {
905         return EVAL_CONTINUE;
906     }
IsCompatible(const TypeId & id) const907     bool IsCompatible(const TypeId& id) const override
908     {
909         return id == TypeId(UidFromType<uint32_t>());
910     }
911 };
912 
913 /**
914  * @tc.name: EvaluateAndStore
915  * @tc.desc: test EvaluateAndStore
916  * @tc.type: FUNC
917  */
918 HWTEST_F(PropertyTest, EvaluateAndStore, TestSize.Level1)
919 {
920     auto p = ConstructProperty<uint32_t>("test");
921     auto stack = interface_cast<IStackProperty>(p->GetProperty());
922     ASSERT_TRUE(stack);
923 
924     p->SetValue(2);
925 
926     ASSERT_TRUE(stack->AddModifier(IModifier::Ptr(new StaticValueTestMod)));
927     EXPECT_EQ(p->GetValue(), 4);
928     stack->EvaluateAndStore();
929 
930     auto v = stack->TopValue();
931     ASSERT_TRUE(v);
932     EXPECT_EQ(GetValue<uint32_t>(v->GetValue()), 4);
933 }
934 
935 META_END_NAMESPACE()
936