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