50 TestWidget(
const std::string&
name ) : m_name(
name )
56 const std::string& GetName()
const {
return m_name; }
70 CustomData(
int v,
const std::string& t ) : value( v ),
text( t ) {}
72 bool operator==(
const CustomData& other )
const
74 return value == other.value &&
text == other.text;
81struct PROPERTY_HOLDER_TEST_FIXTURE
83 PROPERTY_HOLDER_TEST_FIXTURE()
86 m_populatedHolder.SetProperty(
"bool_prop",
true );
87 m_populatedHolder.SetProperty(
"int_prop", 42 );
88 m_populatedHolder.SetProperty(
"double_prop", 3.14159 );
89 m_populatedHolder.SetProperty(
"string_prop", std::string(
"hello world" ) );
90 m_populatedHolder.SetProperty(
"cstring_prop",
"c-style string" );
93 m_populatedHolder.SetProperty(
"custom_prop", CustomData( 100,
"custom" ) );
96 std::vector<int> numbers = { 1, 2, 3, 4, 5 };
97 m_populatedHolder.SetProperty(
"vector_prop", numbers );
109BOOST_FIXTURE_TEST_SUITE( TEST_PROPERTY_HOLDER, PROPERTY_HOLDER_TEST_FIXTURE )
122 holder.
SetProperty(
"test_string", std::string(
"test value" ) );
125 auto boolResult = holder.
GetProperty<
bool>(
"test_bool" );
126 BOOST_CHECK( boolResult.has_value() );
129 auto intResult = holder.
GetProperty<
int>(
"test_int" );
130 BOOST_CHECK( intResult.has_value() );
133 auto doubleResult = holder.
GetProperty<
double>(
"test_double" );
134 BOOST_CHECK( doubleResult.has_value() );
135 BOOST_CHECK_CLOSE( *doubleResult, 2.71828, 0.0001 );
137 auto stringResult = holder.
GetProperty<std::string>(
"test_string" );
138 BOOST_CHECK( stringResult.has_value() );
151 auto intResult = holder.
GetProperty<
int>(
"int_value" );
152 BOOST_CHECK( intResult.has_value() );
156 auto stringResult = holder.
GetProperty<std::string>(
"int_value" );
157 BOOST_CHECK( !stringResult.has_value() );
159 auto doubleResult = holder.
GetProperty<
double>(
"int_value" );
160 BOOST_CHECK( !doubleResult.has_value() );
162 auto boolResult = holder.
GetProperty<
bool>(
"int_value" );
163 BOOST_CHECK( !boolResult.has_value() );
175 int existingValue = holder.
GetPropertyOr(
"existing_prop", 999 );
179 int nonExistingValue = holder.
GetPropertyOr(
"missing_prop", 777 );
183 std::string wrongTypeValue = holder.
GetPropertyOr<std::string>(
"existing_prop",
"default" );
187 bool defaultBool = holder.
GetPropertyOr(
"missing_bool",
false );
190 std::string defaultString = holder.
GetPropertyOr<std::string>(
"missing_string",
"fallback" );
203 BOOST_CHECK( m_populatedHolder.HasProperty(
"bool_prop" ) );
204 BOOST_CHECK( m_populatedHolder.HasProperty(
"int_prop" ) );
205 BOOST_CHECK( m_populatedHolder.HasProperty(
"string_prop" ) );
215 BOOST_CHECK( m_populatedHolder.HasPropertyOfType<
bool>(
"bool_prop" ) );
216 BOOST_CHECK( m_populatedHolder.HasPropertyOfType<
int>(
"int_prop" ) );
217 BOOST_CHECK( m_populatedHolder.HasPropertyOfType<
double>(
"double_prop" ) );
218 BOOST_CHECK( m_populatedHolder.HasPropertyOfType<std::string>(
"string_prop" ) );
221 BOOST_CHECK_EQUAL(
false, m_populatedHolder.HasPropertyOfType<
int>(
"bool_prop" ) );
222 BOOST_CHECK_EQUAL(
false, m_populatedHolder.HasPropertyOfType<
bool>(
"int_prop" ) );
223 BOOST_CHECK_EQUAL(
false, m_populatedHolder.HasPropertyOfType<std::string>(
"int_prop" ) );
226 BOOST_CHECK_EQUAL(
false, m_populatedHolder.HasPropertyOfType<
bool>(
"missing_prop" ) );
243 BOOST_CHECK( removed );
268 BOOST_CHECK( holder.
Empty() );
281 BOOST_CHECK( m_emptyHolder.Empty() );
288 m_populatedHolder.SetProperty(
"new_prop", 999 );
292 m_populatedHolder.RemoveProperty(
"new_prop" );
310 std::sort( keys.begin(), keys.end() );
311 std::vector<std::string>
expected = {
"key1",
"key2",
"key3" };
314 BOOST_CHECK_EQUAL_COLLECTIONS( keys.begin(), keys.end(),
expected.begin(),
expected.end() );
317 auto emptyKeys = m_emptyHolder.GetKeys();
328 holder.
SetProperty(
"string_val", std::string(
"hello" ) );
332 BOOST_CHECK( intTypeInfo.has_value() );
333 BOOST_CHECK( intTypeInfo->get() ==
typeid(
int ) );
336 BOOST_CHECK( stringTypeInfo.has_value() );
337 BOOST_CHECK( stringTypeInfo->get() ==
typeid( std::string ) );
341 BOOST_CHECK( !missingTypeInfo.has_value() );
352 CustomData original( 123,
"test data" );
356 auto retrieved = holder.
GetProperty<CustomData>(
"custom" );
357 BOOST_CHECK( retrieved.has_value() );
358 BOOST_CHECK( *retrieved == original );
361 std::vector<std::string> stringVec = {
"one",
"two",
"three" };
364 auto vecRetrieved = holder.
GetProperty<std::vector<std::string>>(
"string_vector" );
365 BOOST_CHECK( vecRetrieved.has_value() );
366 BOOST_CHECK_EQUAL_COLLECTIONS( vecRetrieved->begin(), vecRetrieved->end(),
367 stringVec.begin(), stringVec.end() );
370 auto smartPtr = std::make_shared<int>( 456 );
373 auto ptrRetrieved = holder.
GetProperty<std::shared_ptr<int>>(
"smart_ptr" );
374 BOOST_CHECK( ptrRetrieved.has_value() );
397 holder.
SetProperty(
"changeable", std::string(
"now a string" ) );
402 auto intResult = holder.
GetProperty<
int>(
"changeable" );
403 BOOST_CHECK( !intResult.has_value() );
418 TestWidget widget(
"test_widget" );
421 BOOST_CHECK_EQUAL( widget.GetPropertyOr<std::string>(
"widget_name",
"" ),
"test_widget" );
425 widget.SetProperty(
"runtime_prop", 42 );
429 BOOST_CHECK( widget.HasProperty(
"widget_name" ) );
430 BOOST_CHECK( widget.HasProperty(
"default_enabled" ) );
431 BOOST_CHECK( widget.HasProperty(
"runtime_prop" ) );
440 TestWidget widget1(
"widget1" );
441 TestWidget widget2(
"widget2" );
444 widget1.SetProperty(
"unique_to_1", 100 );
445 widget2.SetProperty(
"unique_to_2", 200 );
454 BOOST_CHECK_EQUAL( widget1.GetPropertyOr<std::string>(
"widget_name",
"" ),
"widget1" );
455 BOOST_CHECK_EQUAL( widget2.GetPropertyOr<std::string>(
"widget_name",
"" ),
"widget2" );
463 TestWidget widget(
"access_test" );
474 BOOST_CHECK( constHolder.
HasProperty(
"widget_name" ) );
475 auto keys = constHolder.
GetKeys();
476 BOOST_CHECK( keys.size() >= 2 );
499 std::string longKey( 1000,
'x' );
512 std::vector<int> bigVector( 1000, 42 );
513 holder.
SetProperty(
"big_vector", std::move( bigVector ) );
516 auto retrieved = holder.
GetProperty<std::vector<int>>(
"big_vector" );
517 BOOST_CHECK( retrieved.has_value() );
530 auto result = holder.
GetProperty<
int>(
"anything" );
531 BOOST_CHECK( !result.has_value() );
535 BOOST_CHECK( !emptyResult.has_value() );
539 BOOST_CHECK( !typeInfo.has_value() );
560 BOOST_CHECK( holder.
IsValid() );
579 void* clientData =
static_cast<void*
>( original );
583 BOOST_CHECK_NE(
nullptr, casted );
584 BOOST_CHECK( casted->
IsValid() );
591 const void* constClientData =
static_cast<const void*
>( original );
593 BOOST_CHECK_NE(
nullptr, constCasted );
594 BOOST_CHECK( constCasted->
IsValid() );
609 int randomInt = 12345;
610 void* randomPtr = &randomInt;
615 uint64_t wrong_magic = 0x1234567890ABCDEFULL;
620 void* fakePtr = &fake;
633 BOOST_CHECK( holder->
IsValid() );
635 void* ptr =
static_cast<void*
>( holder );
651 BOOST_CHECK_NE(
nullptr, holder );
652 BOOST_CHECK( holder->
IsValid() );
655 BOOST_CHECK( holder->
SetProperty(
"client_test", 999 ) );
674 BOOST_CHECK( original.
IsValid() );
678 BOOST_CHECK(
copied.IsValid() );
683 BOOST_CHECK(
moved.IsValid() );
687 BOOST_CHECK( original.
IsValid() );
701 BOOST_CHECK( source.
IsValid() );
702 BOOST_CHECK( target.
IsValid() );
706 BOOST_CHECK( target.
IsValid() );
714 target = std::move( another );
715 BOOST_CHECK( target.
IsValid() );
717 BOOST_CHECK( another.
IsValid() );
726 struct FakePropertyHolder {
727 uint64_t wrong_magic = 0xDEADBEEF;
728 std::unordered_map<std::string, std::any> fake_properties;
731 FakePropertyHolder fake;
741 BOOST_CHECK( fakeHolder->
Empty() );
746 auto result = fakeHolder->
GetProperty<
int>(
"anything" );
747 BOOST_CHECK( !result.has_value() );
754 BOOST_CHECK( !typeInfo.has_value() );
bool operator==(const wxAuiPaneInfo &aLhs, const wxAuiPaneInfo &aRhs)
bool SetProperty(const std::string &aKey, T &&aValue)
Set a property with the given key and value.
static bool SafeDelete(void *aPtr) noexcept
Safely delete a PROPERTY_HOLDER from client data.
std::optional< std::reference_wrapper< const std::type_info > > GetPropertyType(const std::string &aKey) const
Get the type information for a property.
bool Empty() const
Check if there are no properties stored.
std::vector< std::string > GetKeys() const
Get all property keys.
static PROPERTY_HOLDER * SafeCast(void *aPtr) noexcept
Safely cast a void pointer to PROPERTY_HOLDER*.
bool RemoveProperty(const std::string &aKey)
Remove a property.
static constexpr uint64_t MAGIC_VALUE
Magic value for memory validation (ASCII: "PROP" + "HLDR")
std::optional< T > GetProperty(const std::string &aKey) const
Get a property value with type checking.
T GetPropertyOr(const std::string &aKey, T &&aDefaultValue) const
Get a property value with a default fallback.
bool HasPropertyOfType(const std::string &aKey) const
Check if a property exists and has the expected type.
bool HasProperty(const std::string &aKey) const
Check if a property exists.
bool IsValid() const noexcept
Check if this instance has a valid magic value.
bool Clear()
Clear all properties.
size_t Size() const
Get the number of stored properties.
Mixin class to add property support to any class.
void SetProperty(const std::string &aKey, T &&aValue)
BOOST_AUTO_TEST_SUITE(CadstarPartParser)
BOOST_CHECK_EQUAL(ret, c.m_exp_result)
BOOST_AUTO_TEST_SUITE_END()
VECTOR3I expected(15, 30, 45)
BOOST_AUTO_TEST_CASE(BasicSetGet)
Declare the test suite.