diff --git a/tests/Makefile.in b/tests/Makefile.in
index 6d50737e88..7de6fe5e88 100644
--- a/tests/Makefile.in
+++ b/tests/Makefile.in
@@ -71,6 +71,7 @@ TEST_OBJECTS = \
test_longlongtest.o \
test_convautotest.o \
test_mbconvtest.o \
+ test_ipc.o \
test_regextest.o \
test_wxregextest.o \
test_scopeguardtest.o \
@@ -394,6 +395,9 @@ test_convautotest.o: $(srcdir)/mbconv/convautotest.cpp $(TEST_ODEP)
test_mbconvtest.o: $(srcdir)/mbconv/mbconvtest.cpp $(TEST_ODEP)
$(CXXC) -c -o $@ $(TEST_CXXFLAGS) $(srcdir)/mbconv/mbconvtest.cpp
+test_ipc.o: $(srcdir)/net/ipc.cpp $(TEST_ODEP)
+ $(CXXC) -c -o $@ $(TEST_CXXFLAGS) $(srcdir)/net/ipc.cpp
+
test_regextest.o: $(srcdir)/regex/regextest.cpp $(TEST_ODEP)
$(CXXC) -c -o $@ $(TEST_CXXFLAGS) $(srcdir)/regex/regextest.cpp
diff --git a/tests/makefile.bcc b/tests/makefile.bcc
index 4852c79e4f..f5d622f02e 100644
--- a/tests/makefile.bcc
+++ b/tests/makefile.bcc
@@ -57,6 +57,7 @@ TEST_OBJECTS = \
$(OBJS)\test_longlongtest.obj \
$(OBJS)\test_convautotest.obj \
$(OBJS)\test_mbconvtest.obj \
+ $(OBJS)\test_ipc.obj \
$(OBJS)\test_regextest.obj \
$(OBJS)\test_wxregextest.obj \
$(OBJS)\test_scopeguardtest.obj \
@@ -423,6 +424,9 @@ $(OBJS)\test_convautotest.obj: .\mbconv\convautotest.cpp
$(OBJS)\test_mbconvtest.obj: .\mbconv\mbconvtest.cpp
$(CXX) -q -c -P -o$@ $(TEST_CXXFLAGS) .\mbconv\mbconvtest.cpp
+$(OBJS)\test_ipc.obj: .\net\ipc.cpp
+ $(CXX) -q -c -P -o$@ $(TEST_CXXFLAGS) .\net\ipc.cpp
+
$(OBJS)\test_regextest.obj: .\regex\regextest.cpp
$(CXX) -q -c -P -o$@ $(TEST_CXXFLAGS) .\regex\regextest.cpp
diff --git a/tests/makefile.gcc b/tests/makefile.gcc
index fabe0d9fa1..e53f54bb2e 100644
--- a/tests/makefile.gcc
+++ b/tests/makefile.gcc
@@ -49,6 +49,7 @@ TEST_OBJECTS = \
$(OBJS)\test_longlongtest.o \
$(OBJS)\test_convautotest.o \
$(OBJS)\test_mbconvtest.o \
+ $(OBJS)\test_ipc.o \
$(OBJS)\test_regextest.o \
$(OBJS)\test_wxregextest.o \
$(OBJS)\test_scopeguardtest.o \
@@ -401,6 +402,9 @@ $(OBJS)\test_convautotest.o: ./mbconv/convautotest.cpp
$(OBJS)\test_mbconvtest.o: ./mbconv/mbconvtest.cpp
$(CXX) -c -o $@ $(TEST_CXXFLAGS) $(CPPDEPS) $<
+$(OBJS)\test_ipc.o: ./net/ipc.cpp
+ $(CXX) -c -o $@ $(TEST_CXXFLAGS) $(CPPDEPS) $<
+
$(OBJS)\test_regextest.o: ./regex/regextest.cpp
$(CXX) -c -o $@ $(TEST_CXXFLAGS) $(CPPDEPS) $<
diff --git a/tests/makefile.vc b/tests/makefile.vc
index 6776a9f083..225bda8f92 100644
--- a/tests/makefile.vc
+++ b/tests/makefile.vc
@@ -50,6 +50,7 @@ TEST_OBJECTS = \
$(OBJS)\test_longlongtest.obj \
$(OBJS)\test_convautotest.obj \
$(OBJS)\test_mbconvtest.obj \
+ $(OBJS)\test_ipc.obj \
$(OBJS)\test_regextest.obj \
$(OBJS)\test_wxregextest.obj \
$(OBJS)\test_scopeguardtest.obj \
@@ -508,6 +509,9 @@ $(OBJS)\test_convautotest.obj: .\mbconv\convautotest.cpp
$(OBJS)\test_mbconvtest.obj: .\mbconv\mbconvtest.cpp
$(CXX) /c /nologo /TP /Fo$@ $(TEST_CXXFLAGS) .\mbconv\mbconvtest.cpp
+$(OBJS)\test_ipc.obj: .\net\ipc.cpp
+ $(CXX) /c /nologo /TP /Fo$@ $(TEST_CXXFLAGS) .\net\ipc.cpp
+
$(OBJS)\test_regextest.obj: .\regex\regextest.cpp
$(CXX) /c /nologo /TP /Fo$@ $(TEST_CXXFLAGS) .\regex\regextest.cpp
diff --git a/tests/makefile.wat b/tests/makefile.wat
index 582af283a0..c177331470 100644
--- a/tests/makefile.wat
+++ b/tests/makefile.wat
@@ -262,6 +262,7 @@ TEST_OBJECTS = &
$(OBJS)\test_longlongtest.obj &
$(OBJS)\test_convautotest.obj &
$(OBJS)\test_mbconvtest.obj &
+ $(OBJS)\test_ipc.obj &
$(OBJS)\test_regextest.obj &
$(OBJS)\test_wxregextest.obj &
$(OBJS)\test_scopeguardtest.obj &
@@ -454,6 +455,9 @@ $(OBJS)\test_convautotest.obj : .AUTODEPEND .\mbconv\convautotest.cpp
$(OBJS)\test_mbconvtest.obj : .AUTODEPEND .\mbconv\mbconvtest.cpp
$(CXX) -bt=nt -zq -fo=$^@ $(TEST_CXXFLAGS) $<
+$(OBJS)\test_ipc.obj : .AUTODEPEND .\net\ipc.cpp
+ $(CXX) -bt=nt -zq -fo=$^@ $(TEST_CXXFLAGS) $<
+
$(OBJS)\test_regextest.obj : .AUTODEPEND .\regex\regextest.cpp
$(CXX) -bt=nt -zq -fo=$^@ $(TEST_CXXFLAGS) $<
diff --git a/tests/net/ipc.cpp b/tests/net/ipc.cpp
new file mode 100644
index 0000000000..5ca82bd3e4
--- /dev/null
+++ b/tests/net/ipc.cpp
@@ -0,0 +1,245 @@
+///////////////////////////////////////////////////////////////////////////////
+// Name: tests/net/ipc.cpp
+// Purpose: IPC classes unit tests
+// Author: Vadim Zeitlin
+// RCS-ID: $Id$
+// Copyright: (c) 2008 Vadim Zeitlin
+// Licence: wxWidgets licence
+///////////////////////////////////////////////////////////////////////////////
+
+// For compilers that support precompilation, includes "wx/wx.h".
+// and "wx/cppunit.h"
+#include "testprec.h"
+
+#ifdef __BORLANDC__
+ #pragma hdrstop
+#endif
+
+// for all others, include the necessary headers
+#ifndef WX_PRECOMP
+#endif
+
+// this test needs threads as it runs the test server in a secondary thread
+#if wxUSE_THREADS
+
+#include "wx/ipc.h"
+#include "wx/thread.h"
+
+namespace
+{
+
+const char *IPC_TEST_PORT = "4242";
+const char *IPC_TEST_TOPIC = "IPC TEST";
+
+} // anonymous namespace
+
+// ----------------------------------------------------------------------------
+// test connection class used by IPCTestServer
+// ----------------------------------------------------------------------------
+
+class IPCTestConnection : public wxConnection
+{
+public:
+ IPCTestConnection() { }
+
+ virtual bool OnExec(const wxString& topic, const wxString& data)
+ {
+ if ( topic != IPC_TEST_TOPIC )
+ return false;
+
+ return data == "Date";
+ }
+
+private:
+ DECLARE_NO_COPY_CLASS(IPCTestConnection)
+};
+
+// ----------------------------------------------------------------------------
+// event dispatching thread class
+// ----------------------------------------------------------------------------
+
+class EventThread : public wxThread
+{
+public:
+ EventThread()
+ : wxThread(wxTHREAD_JOINABLE)
+ {
+ Create();
+ Run();
+ }
+
+protected:
+ virtual void *Entry()
+ {
+ wxTheApp->MainLoop();
+
+ return NULL;
+ }
+
+ DECLARE_NO_COPY_CLASS(EventThread)
+};
+
+// ----------------------------------------------------------------------------
+// test server class
+// ----------------------------------------------------------------------------
+
+class IPCTestServer : public wxServer
+{
+public:
+ IPCTestServer()
+ {
+ m_conn = NULL;
+
+ // we must call this from the main thread
+ wxSocketBase::Initialize();
+
+ // we need event dispatching to work for IPC server to work
+ m_thread = new EventThread;
+
+ Create(IPC_TEST_PORT);
+ }
+
+ virtual ~IPCTestServer()
+ {
+ wxTheApp->ExitMainLoop();
+
+ m_thread->Wait();
+ delete m_thread;
+ m_thread = NULL;
+
+ wxSocketBase::Shutdown();
+ }
+
+ virtual wxConnectionBase *OnAcceptConnection(const wxString& topic)
+ {
+ if ( topic != IPC_TEST_TOPIC )
+ return NULL;
+
+ m_conn = new IPCTestConnection;
+ return m_conn;
+ }
+
+private:
+ EventThread *m_thread;
+ IPCTestConnection *m_conn;
+
+ DECLARE_NO_COPY_CLASS(IPCTestServer)
+};
+
+static IPCTestServer *gs_server = NULL;
+
+// ----------------------------------------------------------------------------
+// test client class
+// ----------------------------------------------------------------------------
+
+class IPCTestClient : public wxClient
+{
+public:
+ IPCTestClient()
+ {
+ m_conn = NULL;
+ }
+
+ virtual ~IPCTestClient()
+ {
+ Disconnect();
+ }
+
+ bool
+ Connect(const wxString& host, const wxString& service, const wxString& topic)
+ {
+ m_conn = MakeConnection(host, service, topic);
+
+ return m_conn != NULL;
+ }
+
+ void Disconnect()
+ {
+ if ( m_conn )
+ {
+ delete m_conn;
+ m_conn = NULL;
+ }
+ }
+
+ wxConnectionBase& GetConn() const
+ {
+ CPPUNIT_ASSERT( m_conn );
+
+ return *m_conn;
+ }
+
+private:
+ wxConnectionBase *m_conn;
+
+ DECLARE_NO_COPY_CLASS(IPCTestClient)
+};
+
+static IPCTestClient gs_client;
+
+// ----------------------------------------------------------------------------
+// the test code itself
+// ----------------------------------------------------------------------------
+
+class IPCTestCase : public CppUnit::TestCase
+{
+public:
+ IPCTestCase() { }
+
+private:
+ CPPUNIT_TEST_SUITE( IPCTestCase );
+ CPPUNIT_TEST( Connect );
+ CPPUNIT_TEST( Execute );
+ CPPUNIT_TEST( Disconnect );
+ CPPUNIT_TEST_SUITE_END();
+
+ void Connect();
+ void Execute();
+ void Disconnect();
+
+ DECLARE_NO_COPY_CLASS(IPCTestCase)
+};
+
+// this test is not enabled by default because it requires an IPC server to run
+//CPPUNIT_TEST_SUITE_REGISTRATION( IPCTestCase );
+CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( IPCTestCase, "IPCTestCase" );
+
+void IPCTestCase::Connect()
+{
+ gs_server = new IPCTestServer;
+
+ // connecting to the wrong port should fail
+ CPPUNIT_ASSERT( !gs_client.Connect("localhost", "2424", IPC_TEST_TOPIC) );
+
+ // connecting using an unsupported topic should fail (unless the server
+ // expects a ROT-13'd topic name...)
+ CPPUNIT_ASSERT( !gs_client.Connect("localhost", IPC_TEST_PORT, "VCP GRFG") );
+
+ // connecting to the right port on the right topic should succeed
+ CPPUNIT_ASSERT( gs_client.Connect("localhost", IPC_TEST_PORT, IPC_TEST_TOPIC) );
+}
+
+void IPCTestCase::Execute()
+{
+ wxConnectionBase& conn = gs_client.GetConn();
+
+ const wxString s("Date");
+ CPPUNIT_ASSERT( conn.Execute(s) );
+ CPPUNIT_ASSERT( conn.Execute(s.mb_str(), s.length() + 1) );
+
+ char bytes[] = { 1, 2, 3 };
+ CPPUNIT_ASSERT( conn.Execute(bytes, WXSIZEOF(bytes)) );
+}
+
+void IPCTestCase::Disconnect()
+{
+ gs_client.Disconnect();
+
+ if ( gs_server )
+ {
+ delete gs_server;
+ gs_server = NULL;
+ }
+}
+
+#endif // wxUSE_THREADS
diff --git a/tests/test.bkl b/tests/test.bkl
index 05fb5a75af..34e49912ab 100644
--- a/tests/test.bkl
+++ b/tests/test.bkl
@@ -43,6 +43,7 @@
longlong/longlongtest.cpp
mbconv/convautotest.cpp
mbconv/mbconvtest.cpp
+ net/ipc.cpp
regex/regextest.cpp
regex/wxregextest.cpp
scopeguard/scopeguardtest.cpp
diff --git a/tests/test_test.dsp b/tests/test_test.dsp
index c54d2c6954..f7d86fa686 100644
--- a/tests/test_test.dsp
+++ b/tests/test_test.dsp
@@ -337,6 +337,10 @@ SOURCE=.\streams\iostreams.cpp
# End Source File
# Begin Source File
+SOURCE=.\net\ipc.cpp
+# End Source File
+# Begin Source File
+
SOURCE=.\streams\largefile.cpp
# End Source File
# Begin Source File
diff --git a/tests/test_vc7_test.vcproj b/tests/test_vc7_test.vcproj
index 2e19cd5bf7..63fdfa8701 100644
--- a/tests/test_vc7_test.vcproj
+++ b/tests/test_vc7_test.vcproj
@@ -748,6 +748,8 @@
RelativePath=".\strings\iostream.cpp"/>
+
+