initial commit

Signed-off-by: Peter Siegmund <mars3142@noreply.mars3142.dev>
This commit is contained in:
2025-10-31 23:37:30 +01:00
commit bf6b52fd94
9654 changed files with 4035664 additions and 0 deletions

View File

@@ -0,0 +1,243 @@
///////////////////////////////////////////////////////////////////////////////
// Name: tests/weakref/evtconnection.cpp
// Purpose: wxWeakRef<T> unit test
// Author: Arne Steinarson
// Created: 2008-01-10
// Copyright: (c) 2007 Arne Steinarson
///////////////////////////////////////////////////////////////////////////////
// ----------------------------------------------------------------------------
// headers
// ----------------------------------------------------------------------------
#include "testprec.h"
#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif // WX_PRECOMP
#include "wx/event.h"
#include "wx/weakref.h"
static int gs_value = 0; // Increased by 1 by first object and 0x10000 by 2nd object
static wxObject *gs_psrc1;
static wxObject *gs_psrc2;
// We need some event types
const wxEventType wxEVT_TEST = wxNewEventType(),
wxEVT_TEST1 = wxNewEventType(),
wxEVT_TEST2 = wxNewEventType();
class wxTestEvent : public wxEvent
{
public:
wxTestEvent(wxEventType type = wxEVT_TEST) : wxEvent(0, type) { }
virtual wxEvent *Clone() const override { return new wxTestEvent(GetEventType()); }
};
class wxTestSink : public wxEvtHandler
{
public:
void OnTestEvent(wxEvent& evt)
{
if ( evt.GetEventObject() == gs_psrc1 )
gs_value += 1;
else if ( evt.GetEventObject() == gs_psrc2 )
gs_value += 0x10000;
}
void OnTestEvent1(wxEvent& )
{
gs_value += 0x00100;
}
void OnTestEvent2(wxEvent&)
{
gs_value += 0x01000000;
}
};
// --------------------------------------------------------------------------
// test class
// --------------------------------------------------------------------------
class EvtConnectionTestCase : public CppUnit::TestCase
{
public:
EvtConnectionTestCase() {}
private:
CPPUNIT_TEST_SUITE( EvtConnectionTestCase );
CPPUNIT_TEST( SinkTest );
CPPUNIT_TEST( SourceDestroyTest );
CPPUNIT_TEST( MultiConnectionTest );
CPPUNIT_TEST_SUITE_END();
void SinkTest();
void SourceDestroyTest();
void MultiConnectionTest();
wxDECLARE_NO_COPY_CLASS(EvtConnectionTestCase);
};
// register in the unnamed registry so that these tests are run by default
CPPUNIT_TEST_SUITE_REGISTRATION( EvtConnectionTestCase );
// also include in its own registry so that these tests can be run alone
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( EvtConnectionTestCase, "EvtConnectionTestCase" );
// Helpers
void DoConnect( wxEvtHandler& eh1, wxEvtHandler& eh2, wxTestSink& ts ){
eh1.Connect(wxEVT_TEST, (wxObjectEventFunction)&wxTestSink::OnTestEvent,
nullptr, &ts);
eh2.Connect(wxEVT_TEST, (wxObjectEventFunction) &wxTestSink::OnTestEvent,
nullptr, &ts);
}
void DoDisconnect( wxEvtHandler& eh1, wxEvtHandler& eh2, wxTestSink& ts ){
eh1.Disconnect(wxEVT_TEST, (wxObjectEventFunction) &wxTestSink::OnTestEvent,
nullptr, &ts);
eh2.Disconnect(wxEVT_TEST, (wxObjectEventFunction) &wxTestSink::OnTestEvent,
nullptr, &ts);
}
void EvtConnectionTestCase::SinkTest()
{
// Let the sink be destroyed before the sources
// An event used below
wxTestEvent evt;
// Connect two event handlers to one sink
wxEvtHandler eh1, eh2;
gs_psrc1 = &eh1;
gs_psrc2 = &eh2;
{
wxTestSink ts;
CPPUNIT_ASSERT( !ts.GetFirst() );
DoConnect(eh1, eh2, ts);
DoDisconnect(eh1, eh2, ts);
DoConnect(eh1, eh2, ts);
// Fire events
evt.SetEventObject(&eh1);
eh1.ProcessEvent(evt);
evt.SetEventObject(&eh2);
eh2.ProcessEvent(evt);
// Make sure they were processed correctly
CPPUNIT_ASSERT_EQUAL( 0x00010001, gs_value );
}
// Fire events again, should be no sink connected now
gs_value = 0;
evt.SetEventObject(&eh1);
eh1.ProcessEvent( evt );
evt.SetEventObject(&eh2);
eh2.ProcessEvent( evt );
// Make sure no processing happened
CPPUNIT_ASSERT_EQUAL( 0, gs_value );
}
void EvtConnectionTestCase::SourceDestroyTest()
{
// Let the sources be destroyed before the sink
wxTestSink ts;
wxTestEvent evt;
{
wxEvtHandler eh1;
{
CPPUNIT_ASSERT( !ts.GetFirst() );
// Connect two event handlers to one sink
wxEvtHandler eh2;
gs_psrc1 = &eh1;
gs_psrc2 = &eh2;
DoConnect( eh1, eh2, ts );
// Fire events
gs_value = 0;
evt.SetEventObject(&eh1);
eh1.ProcessEvent( evt );
evt.SetEventObject(&eh2);
eh2.ProcessEvent( evt );
// Make sure they were processed correctly
CPPUNIT_ASSERT_EQUAL( 0x00010001, gs_value );
}
gs_value = 0;
evt.SetEventObject(&eh1);
eh1.ProcessEvent( evt );
// Make sure still connected
CPPUNIT_ASSERT_EQUAL( 0x00000001, gs_value );
}
CPPUNIT_ASSERT( !ts.GetFirst() );
}
void EvtConnectionTestCase::MultiConnectionTest()
{
// events used below
wxTestEvent evt;
wxTestEvent evt1(wxEVT_TEST1);
wxTestEvent evt2(wxEVT_TEST2);
// One source
wxEvtHandler eh1;
evt.SetEventObject(&eh1);
gs_psrc1 = nullptr;
gs_psrc2 = &eh1;
{
// ...and one sink
wxTestSink ts;
eh1.Connect(wxEVT_TEST, (wxObjectEventFunction)&wxTestSink::OnTestEvent,
nullptr, &ts);
eh1.Connect(wxEVT_TEST1, (wxObjectEventFunction)&wxTestSink::OnTestEvent1,
nullptr, &ts);
eh1.Connect(wxEVT_TEST2, (wxObjectEventFunction)&wxTestSink::OnTestEvent2,
nullptr, &ts);
// Generate events
gs_value = 0;
eh1.ProcessEvent(evt);
eh1.ProcessEvent(evt1);
eh1.ProcessEvent(evt2);
CPPUNIT_ASSERT( gs_value==0x01010100 );
{
// Declare weak references to the objects (using same list)
wxEvtHandlerRef re(&eh1), rs(&ts);
}
// And now destroyed
eh1.Disconnect(wxEVT_TEST, (wxObjectEventFunction)&wxTestSink::OnTestEvent,
nullptr, &ts);
eh1.ProcessEvent(evt);
eh1.ProcessEvent(evt1);
eh1.ProcessEvent(evt2);
CPPUNIT_ASSERT_EQUAL( 0x02010200, gs_value );
}
// No connection should be left now
gs_value = 0;
eh1.ProcessEvent(evt);
eh1.ProcessEvent(evt1);
eh1.ProcessEvent(evt2);
// Nothing should have been done
CPPUNIT_ASSERT_EQUAL( 0, gs_value );
}

View File

@@ -0,0 +1,324 @@
///////////////////////////////////////////////////////////////////////////////
// Name: tests/weakref/weakref.cpp
// Purpose: wxWeakRef<T> unit test
// Author: Arne Steinarson
// Created: 2008-01-10
// Copyright: (c) 2007 Arne Steinarson
///////////////////////////////////////////////////////////////////////////////
// ----------------------------------------------------------------------------
// headers
// ----------------------------------------------------------------------------
#include "testprec.h"
#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif // WX_PRECOMP
#include "wx/event.h"
#include "wx/weakref.h"
// A statically trackable derived wxObject
class wxObjectTrackable : public wxObject, public wxTrackable
{
public:
// Test member access
void TestFunc(){ }
// Make sure this does not clash with wxTrackableBase method
int GetFirst() { return 0; }
};
// --------------------------------------------------------------------------
// test class
// --------------------------------------------------------------------------
class WeakRefTestCase : public CppUnit::TestCase
{
public:
WeakRefTestCase() {}
private:
CPPUNIT_TEST_SUITE( WeakRefTestCase );
CPPUNIT_TEST( DeclareTest );
CPPUNIT_TEST( AssignTest );
CPPUNIT_TEST( AssignWeakRefTest );
CPPUNIT_TEST( MultiAssignTest );
CPPUNIT_TEST( CleanupTest );
CPPUNIT_TEST( DeleteTest );
#ifdef HAVE_DYNAMIC_CAST
CPPUNIT_TEST( DynamicRefTest );
#endif
CPPUNIT_TEST_SUITE_END();
void DeclareTest();
void AssignTest();
void AssignWeakRefTest();
void MultiAssignTest();
void CleanupTest();
void DeleteTest();
#ifdef HAVE_DYNAMIC_CAST
void DynamicRefTest();
#endif
wxDECLARE_NO_COPY_CLASS(WeakRefTestCase);
};
// register in the unnamed registry so that these tests are run by default
CPPUNIT_TEST_SUITE_REGISTRATION( WeakRefTestCase );
// also include in its own registry so that these tests can be run alone
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( WeakRefTestCase, "WeakRefTestCase" );
// Test weak reference to an incomplete type, this should work if the type is
// fully defined before it is used (but currently doesn't, see #11916)
struct ForwardDeclaredClass;
wxWeakRef<ForwardDeclaredClass> g_incompleteWeakRef;
struct ForwardDeclaredClass : wxEvtHandler { };
// A incomplete class that would be defined in other compilation units
struct IncompleteClass;
void WeakRefTestCase::DeclareTest()
{
{
// Not initializing or initializing with nullptr should work too
wxWeakRef<wxEvtHandler> wroDef;
wxWeakRef<wxEvtHandler> wro0(nullptr);
wxObject o; // Should not work
wxEvtHandler eh;
wxObjectTrackable ot;
// Test declare when T is wxObject
// wxWeakRef<wxObject> wro1(&o); // Gives compile time failure
wxWeakRef<wxEvtHandler> wro2(&eh);
wxWeakRef<wxObjectTrackable> wro3(&ot);
CPPUNIT_ASSERT( wro2.get() == &eh );
CPPUNIT_ASSERT( wro3.get() == &ot );
// Test accessing wxObject members
CPPUNIT_ASSERT( !wro2->GetRefData() );
CPPUNIT_ASSERT( !wro3->GetRefData() );
wxWeakRef<wxEvtHandler> wreh(&eh);
wxWeakRef<wxObjectTrackable> wrot(&ot);
CPPUNIT_ASSERT( wreh.get() == &eh );
CPPUNIT_ASSERT( wrot.get() == &ot );
}
// This test requires a working dynamic_cast<>
#ifndef wxNO_RTTI
{
ForwardDeclaredClass fdc;
g_incompleteWeakRef = &fdc;
CPPUNIT_ASSERT( g_incompleteWeakRef );
}
CPPUNIT_ASSERT( !g_incompleteWeakRef );
#endif // RTTI enabled
{
// Construction of a wxWeakRef to an incomplete class should be fine
wxWeakRef<IncompleteClass> p;
// Copying should be also OK
wxCLANG_WARNING_SUPPRESS(self-assign-overloaded)
p = p;
wxCLANG_WARNING_RESTORE(self-assign-overloaded)
// Assigning a raw pointer should cause compile error
#ifdef TEST_INVALID_INCOMPLETE_WEAKREF
p = static_cast<IncompleteClass*>(0);
#endif
// Releasing should be OK
}
}
void WeakRefTestCase::AssignTest()
{
wxWeakRef<wxEvtHandler> wro1;
wxWeakRef<wxObjectTrackable> wro2;
{ // Scope for object destruction
wxEvtHandler eh;
wxObjectTrackable ot;
wro1 = &eh;
wro2 = &ot;
CPPUNIT_ASSERT( wro1.get() == &eh );
CPPUNIT_ASSERT( wro2.get() == &ot );
}
// Should be reset now
CPPUNIT_ASSERT( !wro1 );
CPPUNIT_ASSERT( !wro2 );
// Explicitly resetting should work too
wxEvtHandler eh;
wxObjectTrackable ot;
wro1 = &eh;
wro2 = &ot;
wro1 = nullptr;
wro2 = nullptr;
CPPUNIT_ASSERT( !wro1 );
CPPUNIT_ASSERT( !wro2 );
}
void WeakRefTestCase::AssignWeakRefTest()
{
// Test declare when T is wxObject
wxWeakRef<wxEvtHandler> wro1;
wxWeakRef<wxObjectTrackable> wro2;
{ // Scope for object destruction
wxEvtHandler eh;
wxObjectTrackable ot;
wxWeakRef<wxEvtHandler> wro3;
wxWeakRef<wxObjectTrackable> wro4;
wro1 = &eh;
wro2 = &ot;
wro3 = wro1;
wro4 = wro2;
CPPUNIT_ASSERT( wro1.get() == &eh );
CPPUNIT_ASSERT( wro2.get() == &ot );
CPPUNIT_ASSERT( wro3.get() == &eh );
CPPUNIT_ASSERT( wro4.get() == &ot );
wro4.Release();
CPPUNIT_ASSERT( !wro4.get() );
}
// Should be reset now
CPPUNIT_ASSERT( !wro1 );
CPPUNIT_ASSERT( !wro2 );
}
void WeakRefTestCase::MultiAssignTest()
{
// Object is tracked by several refs
wxEvtHandler *peh = new wxEvtHandler;
// Test declare when T is wxObject
wxWeakRef<wxEvtHandler> wro1(peh);
wxWeakRef<wxEvtHandler> wro2(peh);
wxObjectTrackable *pot = new wxObjectTrackable;
wxWeakRef<wxObjectTrackable> wro3 = pot;
wxWeakRef<wxObjectTrackable> wro4 = pot;
CPPUNIT_ASSERT( wro1.get() == peh );
CPPUNIT_ASSERT( wro2.get() == peh );
CPPUNIT_ASSERT( wro3.get() == pot );
CPPUNIT_ASSERT( wro4.get() == pot );
delete peh;
delete pot;
// Should be reset now
CPPUNIT_ASSERT( !wro1 );
CPPUNIT_ASSERT( !wro2 );
CPPUNIT_ASSERT( !wro3 );
CPPUNIT_ASSERT( !wro4 );
}
void WeakRefTestCase::CleanupTest()
{
// Make sure that trackable objects have no left over tracker nodes after use.
// This time the references goes out of scope before the objects.
wxEvtHandler eh;
wxObjectTrackable ots;
wxObjectTrackable otd;
{ // Scope for object destruction
wxWeakRef<wxEvtHandler> wro1;
wxWeakRef<wxEvtHandler> wro2;
wxWeakRef<wxObjectTrackable> wro3;
wxWeakRef<wxObjectTrackable> wro4;
wro1 = &eh;
wro2 = &eh; // Has two tracker nodes now
wro3 = &ots;
wro4 = &otd;
// Access members of reffed object
wro3->TestFunc();
CPPUNIT_ASSERT( eh.GetFirst()==&wro2 );
CPPUNIT_ASSERT( ots.wxTrackable::GetFirst()==&wro3 );
CPPUNIT_ASSERT( otd.wxTrackable::GetFirst()==&wro4 );
}
// Should be reset now
CPPUNIT_ASSERT( !eh.GetFirst() );
CPPUNIT_ASSERT( !ots.wxTrackable::GetFirst() );
CPPUNIT_ASSERT( !otd.wxTrackable::GetFirst() );
}
void WeakRefTestCase::DeleteTest()
{
// Object is tracked by several refs
wxEvtHandler *peh = new wxEvtHandler;
// Declared derived type of object and test deleting it
wxEvtHandlerRef wre(peh);
wxWeakRef<wxEvtHandler> wro(peh);
CPPUNIT_ASSERT( wre.get() == peh );
CPPUNIT_ASSERT( wro.get() == peh );
delete wre.get();
CPPUNIT_ASSERT( !wre );
CPPUNIT_ASSERT( !wro );
}
#ifdef HAVE_DYNAMIC_CAST
void WeakRefTestCase::DynamicRefTest()
{
wxWeakRefDynamic<wxEvtHandler> wro1;
wxWeakRefDynamic<wxObjectTrackable> wro2;
wxWeakRefDynamic<wxObjectTrackable> wro3;
{ // Scope for object destruction
{
wxEvtHandler eh;
wro1 = &eh;
}
CPPUNIT_ASSERT( !wro1 );
wxObjectTrackable otd1;
wxObjectTrackable otd2;
wro2 = &otd1;
wro3 = &otd2;
CPPUNIT_ASSERT( wro2.get() == &otd1 );
CPPUNIT_ASSERT( wro3.get() == &otd2 );
wro3 = wro2;
CPPUNIT_ASSERT( wro2.get() == &otd1 );
CPPUNIT_ASSERT( wro3.get() == &otd1 );
}
// Should be reset now
CPPUNIT_ASSERT( !wro2 );
CPPUNIT_ASSERT( !wro3 );
}
#endif // HAVE_DYNAMIC_CAST