| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010 | 
							- ///////////////////////////////////////////////////////////////////////////////
 
- // Name:        tests/fswatcher/fswatchertest.cpp
 
- // Purpose:     wxFileSystemWatcher unit test
 
- // Author:      Bartosz Bekier
 
- // Created:     2009-06-11
 
- // Copyright:   (c) 2009 Bartosz Bekier
 
- ///////////////////////////////////////////////////////////////////////////////
 
- // ----------------------------------------------------------------------------
 
- // headers
 
- // ----------------------------------------------------------------------------
 
- #include "testprec.h"
 
- #ifdef __BORLANDC__
 
-     #pragma hdrstop
 
- #endif
 
- #ifndef WX_PRECOMP
 
-     #include "wx/timer.h"
 
- #endif
 
- #include "wx/evtloop.h"
 
- #include "wx/filename.h"
 
- #include "wx/filefn.h"
 
- #include "wx/stdpaths.h"
 
- #include "wx/fswatcher.h"
 
- #include "testfile.h"
 
- // ----------------------------------------------------------------------------
 
- // local functions
 
- // ----------------------------------------------------------------------------
 
- // class generating file system events
 
- class EventGenerator
 
- {
 
- public:
 
-     static EventGenerator& Get()
 
-     {
 
-         if (!ms_instance)
 
-             ms_instance = new EventGenerator(GetWatchDir());
 
-         return *ms_instance;
 
-     }
 
-     EventGenerator(const wxFileName& path) : m_base(path)
 
-     {
 
-         m_old = wxFileName();
 
-         m_file = RandomName();
 
-         m_new = RandomName();
 
-     }
 
-     // operations
 
-     bool CreateFile()
 
-     {
 
-         wxFile file(m_file.GetFullPath(), wxFile::write);
 
-         return file.IsOpened() && m_file.FileExists();
 
-     }
 
-     bool RenameFile()
 
-     {
 
-         CPPUNIT_ASSERT(m_file.FileExists());
 
-         wxLogDebug("Renaming %s=>%s", m_file.GetFullPath(), m_new.GetFullPath());
 
-         bool ret = wxRenameFile(m_file.GetFullPath(), m_new.GetFullPath());
 
-         if (ret)
 
-         {
 
-             m_old = m_file;
 
-             m_file = m_new;
 
-             m_new = RandomName();
 
-         }
 
-         return ret;
 
-     }
 
-     bool DeleteFile()
 
-     {
 
-         CPPUNIT_ASSERT(m_file.FileExists());
 
-         bool ret =  wxRemoveFile(m_file.GetFullPath());
 
-         if (ret)
 
-         {
 
-             m_old = m_file;
 
-             m_file = m_new;
 
-             m_new = RandomName();
 
-         }
 
-         return ret;
 
-     }
 
-     bool TouchFile()
 
-     {
 
-         return m_file.Touch();
 
-     }
 
-     bool ReadFile()
 
-     {
 
-         wxFile f(m_file.GetFullPath());
 
-         CPPUNIT_ASSERT(f.IsOpened());
 
-         char buf[1];
 
-         ssize_t count = f.Read(buf, sizeof(buf));
 
-         CPPUNIT_ASSERT(count > 0);
 
-         return true;
 
-     }
 
-     bool ModifyFile()
 
-     {
 
-         CPPUNIT_ASSERT(m_file.FileExists());
 
-         wxFile file(m_file.GetFullPath(), wxFile::write_append);
 
-         CPPUNIT_ASSERT(file.IsOpened());
 
-         CPPUNIT_ASSERT(file.Write("Words of Wisdom, Lloyd. Words of wisdom\n"));
 
-         return file.Close();
 
-     }
 
-     // helpers
 
-     wxFileName RandomName(int length = 10)
 
-     {
 
-         return RandomName(m_base, length);
 
-     }
 
-     // static helpers
 
-     static const wxFileName& GetWatchDir()
 
-     {
 
-         static wxFileName dir;
 
-         if (dir.DirExists())
 
-             return dir;
 
-         wxString tmp = wxStandardPaths::Get().GetTempDir();
 
-         dir.AssignDir(tmp);
 
-         // XXX look for more unique name? there is no function to generate
 
-         // unique filename, the file always get created...
 
-         dir.AppendDir("fswatcher_test");
 
-         CPPUNIT_ASSERT(!dir.DirExists());
 
-         CPPUNIT_ASSERT(dir.Mkdir());
 
-         return dir;
 
-     }
 
-     static void RemoveWatchDir()
 
-     {
 
-         wxFileName dir = GetWatchDir();
 
-         CPPUNIT_ASSERT(dir.DirExists());
 
-         // just to be really sure we know what we remove
 
-         CPPUNIT_ASSERT_EQUAL( "fswatcher_test", dir.GetDirs().Last() );
 
-         // FIXME-VC6: using non-static Rmdir() results in ICE
 
-         CPPUNIT_ASSERT( wxFileName::Rmdir(dir.GetFullPath(), wxPATH_RMDIR_RECURSIVE) );
 
-     }
 
-     static wxFileName RandomName(const wxFileName& base, int length = 10)
 
-     {
 
-         static int ALFA_CNT = 'z' - 'a';
 
-         wxString s;
 
-         for (int i = 0 ; i < length; ++i)
 
-         {
 
-             char c = 'a' + (rand() % ALFA_CNT);
 
-             s += c;
 
-         }
 
-         return wxFileName(base.GetFullPath(), s);
 
-     }
 
- public:
 
-     wxFileName m_base;     // base dir for doing operations
 
-     wxFileName m_file;     // current file name
 
-     wxFileName m_old;      // previous file name
 
-     wxFileName m_new;      // name after renaming
 
- protected:
 
-     static EventGenerator* ms_instance;
 
- };
 
- EventGenerator* EventGenerator::ms_instance = 0;
 
- // custom event handler
 
- class EventHandler : public wxEvtHandler
 
- {
 
- public:
 
-     enum { WAIT_DURATION = 3 };
 
-     EventHandler(int types = wxFSW_EVENT_ALL) :
 
-         eg(EventGenerator::Get()), m_loop(0), m_count(0), m_watcher(0),
 
-         m_eventTypes(types)
 
-     {
 
-         m_loop = new wxEventLoop();
 
-         Connect(wxEVT_IDLE, wxIdleEventHandler(EventHandler::OnIdle));
 
-         Connect(wxEVT_FSWATCHER, wxFileSystemWatcherEventHandler(
 
-                                             EventHandler::OnFileSystemEvent));
 
-     }
 
-     virtual ~EventHandler()
 
-     {
 
-         delete m_watcher;
 
-         if (m_loop)
 
-         {
 
-             if (m_loop->IsRunning())
 
-                 m_loop->Exit();
 
-             delete m_loop;
 
-         }
 
-     }
 
-     void Exit()
 
-     {
 
-         m_loop->Exit();
 
-     }
 
-     // sends idle event, so we get called in a moment
 
-     void SendIdle()
 
-     {
 
-         wxIdleEvent* e = new wxIdleEvent();
 
-         QueueEvent(e);
 
-     }
 
-     void Run()
 
-     {
 
-         SendIdle();
 
-         m_loop->Run();
 
-     }
 
-     void OnIdle(wxIdleEvent& /*evt*/)
 
-     {
 
-         bool more = Action();
 
-         m_count++;
 
-         if (more)
 
-         {
 
-             SendIdle();
 
-         }
 
-     }
 
-     // returns whether we should produce more idle events
 
-     virtual bool Action()
 
-     {
 
-         switch (m_count)
 
-         {
 
-         case 0:
 
-             CPPUNIT_ASSERT(Init());
 
-             break;
 
-         case 1:
 
-             GenerateEvent();
 
-             break;
 
-         case 2:
 
-             // actual test
 
-             CheckResult();
 
-             Exit();
 
-             break;
 
-         // TODO a mechanism that will break the loop in case we
 
-         // don't receive a file system event
 
-         // this below doesn't quite work, so all tests must pass :-)
 
- #if 0
 
-         case 2:
 
-             m_loop.Yield();
 
-             m_loop.WakeUp();
 
-             CPPUNIT_ASSERT(KeepWaiting());
 
-             m_loop.Yield();
 
-             break;
 
-         case 3:
 
-             break;
 
-         case 4:
 
-             CPPUNIT_ASSERT(AfterWait());
 
-             break;
 
- #endif
 
-         } // switch (m_count)
 
-         return m_count <= 0;
 
-     }
 
-     virtual bool Init()
 
-     {
 
-         // test we're good to go
 
-         CPPUNIT_ASSERT(wxEventLoopBase::GetActive());
 
-         // XXX only now can we construct Watcher, because we need
 
-         // active loop here
 
-         m_watcher = new wxFileSystemWatcher();
 
-         m_watcher->SetOwner(this);
 
-         // add dir to be watched
 
-         wxFileName dir = EventGenerator::GetWatchDir();
 
-         CPPUNIT_ASSERT(m_watcher->Add(dir, m_eventTypes));
 
-         return true;
 
-     }
 
-     virtual bool KeepWaiting()
 
-     {
 
-         // did we receive event already?
 
-         if (!tested)
 
-         {
 
-             // well, let's wait a bit more
 
-             wxSleep(WAIT_DURATION);
 
-         }
 
-         return true;
 
-     }
 
-     virtual bool AfterWait()
 
-     {
 
-         // fail if still no events
 
-         WX_ASSERT_MESSAGE
 
-         (
 
-              ("No events during %d seconds!", static_cast<int>(WAIT_DURATION)),
 
-              tested
 
-         );
 
-         return true;
 
-     }
 
-     virtual void OnFileSystemEvent(wxFileSystemWatcherEvent& evt)
 
-     {
 
-         wxLogDebug("--- %s ---", evt.ToString());
 
-         m_lastEvent = wxDynamicCast(evt.Clone(), wxFileSystemWatcherEvent);
 
-         m_events.Add(m_lastEvent);
 
-         // test finished
 
-         SendIdle();
 
-         tested = true;
 
-     }
 
-     virtual void CheckResult()
 
-     {
 
-         CPPUNIT_ASSERT_MESSAGE( "No events received", !m_events.empty() );
 
-         const wxFileSystemWatcherEvent * const e = m_events.front();
 
-         // this is our "reference event"
 
-         const wxFileSystemWatcherEvent expected = ExpectedEvent();
 
-         CPPUNIT_ASSERT_EQUAL( expected.GetChangeType(), e->GetChangeType() );
 
-         CPPUNIT_ASSERT_EQUAL((int)wxEVT_FSWATCHER, e->GetEventType());
 
-         // XXX this needs change
 
-         CPPUNIT_ASSERT_EQUAL(wxEVT_CATEGORY_UNKNOWN, e->GetEventCategory());
 
-         CPPUNIT_ASSERT_EQUAL(expected.GetPath(), e->GetPath());
 
-         CPPUNIT_ASSERT_EQUAL(expected.GetNewPath(), e->GetNewPath());
 
-         // Under MSW extra modification events are sometimes reported after a
 
-         // rename and we just can't get rid of them, so ignore them in this
 
-         // test if they do happen.
 
-         if ( e->GetChangeType() == wxFSW_EVENT_RENAME &&
 
-                 m_events.size() == 2 )
 
-         {
 
-             const wxFileSystemWatcherEvent* const e2 = m_events.back();
 
-             if ( e2->GetChangeType() == wxFSW_EVENT_MODIFY &&
 
-                     e2->GetPath() == e->GetNewPath() )
 
-             {
 
-                 // This is a modify event for the new file, ignore it.
 
-                 return;
 
-             }
 
-         }
 
-         WX_ASSERT_EQUAL_MESSAGE
 
-         (
 
-             (
 
-                 "Extra events received, last one is of type %x, path=\"%s\" "
 
-                 "(the original event was for \"%s\" (\"%s\")",
 
-                 m_events.back()->GetChangeType(),
 
-                 m_events.back()->GetPath().GetFullPath(),
 
-                 e->GetPath().GetFullPath(),
 
-                 e->GetNewPath().GetFullPath()
 
-             ),
 
-             1, m_events.size()
 
-         );
 
-     }
 
-     virtual void GenerateEvent() = 0;
 
-     virtual wxFileSystemWatcherEvent ExpectedEvent() = 0;
 
- protected:
 
-     EventGenerator& eg;
 
-     wxEventLoopBase* m_loop;    // loop reference
 
-     int m_count;                // idle events count
 
-     wxFileSystemWatcher* m_watcher;
 
-     int m_eventTypes;  // Which event-types to watch. Normally all of them
 
-     bool tested;  // indicates, whether we have already passed the test
 
-     #include "wx/arrimpl.cpp"
 
-     WX_DEFINE_ARRAY_PTR(wxFileSystemWatcherEvent*, wxArrayEvent);
 
-     wxArrayEvent m_events;
 
-     wxFileSystemWatcherEvent* m_lastEvent;
 
- };
 
- // ----------------------------------------------------------------------------
 
- // test class
 
- // ----------------------------------------------------------------------------
 
- class FileSystemWatcherTestCase : public CppUnit::TestCase
 
- {
 
- public:
 
-     FileSystemWatcherTestCase() { }
 
-     virtual void setUp();
 
-     virtual void tearDown();
 
- protected:
 
-     wxEventLoopBase* m_loop;
 
- private:
 
-     CPPUNIT_TEST_SUITE( FileSystemWatcherTestCase );
 
-         CPPUNIT_TEST( TestEventCreate );
 
-         CPPUNIT_TEST( TestEventDelete );
 
- #if !defined(__VISUALC__) || wxCHECK_VISUALC_VERSION(7)
 
-         CPPUNIT_TEST( TestTrees );
 
- #endif
 
-         // kqueue-based implementation doesn't collapse create/delete pairs in
 
-         // renames and doesn't detect neither modifications nor access to the
 
-         // files reliably currently so disable these tests
 
-         //
 
-         // FIXME: fix the code and reenable them
 
- #ifndef wxHAS_KQUEUE
 
-         CPPUNIT_TEST( TestEventRename );
 
-         CPPUNIT_TEST( TestEventModify );
 
-         // MSW implementation doesn't detect file access events currently
 
- #ifndef __WINDOWS__
 
-         CPPUNIT_TEST( TestEventAccess );
 
- #endif // __WINDOWS__
 
- #endif // !wxHAS_KQUEUE
 
- #ifdef wxHAS_INOTIFY
 
-         CPPUNIT_TEST( TestEventAttribute );
 
-         CPPUNIT_TEST( TestSingleWatchtypeEvent );
 
- #endif // wxHAS_INOTIFY
 
-         CPPUNIT_TEST( TestNoEventsAfterRemove );
 
-     CPPUNIT_TEST_SUITE_END();
 
-     void TestEventCreate();
 
-     void TestEventDelete();
 
-     void TestEventRename();
 
-     void TestEventModify();
 
-     void TestEventAccess();
 
- #ifdef wxHAS_INOTIFY
 
-     void TestEventAttribute();
 
-     void TestSingleWatchtypeEvent();
 
- #endif // wxHAS_INOTIFY
 
- #if !defined(__VISUALC__) || wxCHECK_VISUALC_VERSION(7)
 
-     void TestTrees();   // Visual C++ 6 can't build this
 
- #endif
 
-     void TestNoEventsAfterRemove();
 
-     DECLARE_NO_COPY_CLASS(FileSystemWatcherTestCase)
 
- };
 
- // the test currently hangs under OS X for some reason and this prevents tests
 
- // ran by buildbot from completing so disable it until someone has time to
 
- // debug it
 
- //
 
- // FIXME: debug and fix this!
 
- #ifndef __WXOSX__
 
- // register in the unnamed registry so that these tests are run by default
 
- CPPUNIT_TEST_SUITE_REGISTRATION( FileSystemWatcherTestCase );
 
- #endif
 
- // also include in its own registry so that these tests can be run alone
 
- CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( FileSystemWatcherTestCase,
 
-                                         "FileSystemWatcherTestCase" );
 
- void FileSystemWatcherTestCase::setUp()
 
- {
 
-     wxLog::AddTraceMask(wxTRACE_FSWATCHER);
 
-     EventGenerator::Get().GetWatchDir();
 
- }
 
- void FileSystemWatcherTestCase::tearDown()
 
- {
 
-     EventGenerator::Get().RemoveWatchDir();
 
- }
 
- // ----------------------------------------------------------------------------
 
- // TestEventCreate
 
- // ----------------------------------------------------------------------------
 
- void FileSystemWatcherTestCase::TestEventCreate()
 
- {
 
-     wxLogDebug("TestEventCreate()");
 
-     class EventTester : public EventHandler
 
-     {
 
-     public:
 
-         virtual void GenerateEvent()
 
-         {
 
-             CPPUNIT_ASSERT(eg.CreateFile());
 
-         }
 
-         virtual wxFileSystemWatcherEvent ExpectedEvent()
 
-         {
 
-             wxFileSystemWatcherEvent event(wxFSW_EVENT_CREATE);
 
-             event.SetPath(eg.m_file);
 
-             event.SetNewPath(eg.m_file);
 
-             return event;
 
-         }
 
-     };
 
-     EventTester tester;
 
-     wxLogTrace(wxTRACE_FSWATCHER, "TestEventCreate tester created()");
 
-     tester.Run();
 
- }
 
- // ----------------------------------------------------------------------------
 
- // TestEventDelete
 
- // ----------------------------------------------------------------------------
 
- void FileSystemWatcherTestCase::TestEventDelete()
 
- {
 
-     wxLogDebug("TestEventDelete()");
 
-     class EventTester : public EventHandler
 
-     {
 
-     public:
 
-         virtual void GenerateEvent()
 
-         {
 
-             CPPUNIT_ASSERT(eg.DeleteFile());
 
-         }
 
-         virtual wxFileSystemWatcherEvent ExpectedEvent()
 
-         {
 
-             wxFileSystemWatcherEvent event(wxFSW_EVENT_DELETE);
 
-             event.SetPath(eg.m_old);
 
-             // CHECK maybe new path here could be NULL or sth?
 
-             event.SetNewPath(eg.m_old);
 
-             return event;
 
-         }
 
-     };
 
-     // we need to create a file now, so we can delete it
 
-     EventGenerator::Get().CreateFile();
 
-     EventTester tester;
 
-     tester.Run();
 
- }
 
- // ----------------------------------------------------------------------------
 
- // TestEventRename
 
- // ----------------------------------------------------------------------------
 
- void FileSystemWatcherTestCase::TestEventRename()
 
- {
 
-     wxLogDebug("TestEventRename()");
 
-     class EventTester : public EventHandler
 
-     {
 
-     public:
 
-         virtual void GenerateEvent()
 
-         {
 
-             CPPUNIT_ASSERT(eg.RenameFile());
 
-         }
 
-         virtual wxFileSystemWatcherEvent ExpectedEvent()
 
-         {
 
-             wxFileSystemWatcherEvent event(wxFSW_EVENT_RENAME);
 
-             event.SetPath(eg.m_old);
 
-             event.SetNewPath(eg.m_file);
 
-             return event;
 
-         }
 
-     };
 
-     // need a file to rename later
 
-     EventGenerator::Get().CreateFile();
 
-     EventTester tester;
 
-     tester.Run();
 
- }
 
- // ----------------------------------------------------------------------------
 
- // TestEventModify
 
- // ----------------------------------------------------------------------------
 
- void FileSystemWatcherTestCase::TestEventModify()
 
- {
 
-     wxLogDebug("TestEventModify()");
 
-     class EventTester : public EventHandler
 
-     {
 
-     public:
 
-         virtual void GenerateEvent()
 
-         {
 
-             CPPUNIT_ASSERT(eg.ModifyFile());
 
-         }
 
-         virtual wxFileSystemWatcherEvent ExpectedEvent()
 
-         {
 
-             wxFileSystemWatcherEvent event(wxFSW_EVENT_MODIFY);
 
-             event.SetPath(eg.m_file);
 
-             event.SetNewPath(eg.m_file);
 
-             return event;
 
-         }
 
-     };
 
-     // we need to create a file to modify
 
-     EventGenerator::Get().CreateFile();
 
-     EventTester tester;
 
-     tester.Run();
 
- }
 
- // ----------------------------------------------------------------------------
 
- // TestEventAccess
 
- // ----------------------------------------------------------------------------
 
- void FileSystemWatcherTestCase::TestEventAccess()
 
- {
 
-     wxLogDebug("TestEventAccess()");
 
-     class EventTester : public EventHandler
 
-     {
 
-     public:
 
-         virtual void GenerateEvent()
 
-         {
 
-             CPPUNIT_ASSERT(eg.ReadFile());
 
-         }
 
-         virtual wxFileSystemWatcherEvent ExpectedEvent()
 
-         {
 
-             wxFileSystemWatcherEvent event(wxFSW_EVENT_ACCESS);
 
-             event.SetPath(eg.m_file);
 
-             event.SetNewPath(eg.m_file);
 
-             return event;
 
-         }
 
-     };
 
-     // we need to create a file to read from it and write sth to it
 
-     EventGenerator::Get().CreateFile();
 
-     EventGenerator::Get().ModifyFile();
 
-     EventTester tester;
 
-     tester.Run();
 
- }
 
- #ifdef wxHAS_INOTIFY
 
- // ----------------------------------------------------------------------------
 
- // TestEventAttribute
 
- // ----------------------------------------------------------------------------
 
- void FileSystemWatcherTestCase::TestEventAttribute()
 
- {
 
-     wxLogDebug("TestEventAttribute()");
 
-     class EventTester : public EventHandler
 
-     {
 
-     public:
 
-         virtual void GenerateEvent()
 
-         {
 
-             CPPUNIT_ASSERT(eg.TouchFile());
 
-         }
 
-         virtual wxFileSystemWatcherEvent ExpectedEvent()
 
-         {
 
-             wxFileSystemWatcherEvent event(wxFSW_EVENT_ATTRIB);
 
-             event.SetPath(eg.m_file);
 
-             event.SetNewPath(eg.m_file);
 
-             return event;
 
-         }
 
-     };
 
-     // we need to create a file to touch
 
-     EventGenerator::Get().CreateFile();
 
-     EventTester tester;
 
-     tester.Run();
 
- }
 
- // ----------------------------------------------------------------------------
 
- // TestSingleWatchtypeEvent: Watch only wxFSW_EVENT_ACCESS
 
- // ----------------------------------------------------------------------------
 
- void FileSystemWatcherTestCase::TestSingleWatchtypeEvent()
 
- {
 
-     wxLogDebug("TestSingleWatchtypeEvent()");
 
-     class EventTester : public EventHandler
 
-     {
 
-     public:
 
-         // We could pass wxFSW_EVENT_CREATE or MODIFY instead, but not RENAME or
 
-         // DELETE as the event path fields would be wrong in CheckResult()
 
-         EventTester() : EventHandler(wxFSW_EVENT_ACCESS) {}
 
-         virtual void GenerateEvent()
 
-         {
 
-             // As wxFSW_EVENT_ACCESS is passed to the ctor only ReadFile() will
 
-             // generate an event. Without it they all will, and the test fails
 
-             CPPUNIT_ASSERT(eg.CreateFile());
 
-             CPPUNIT_ASSERT(eg.ModifyFile());
 
-             CPPUNIT_ASSERT(eg.ReadFile());
 
-         }
 
-         virtual wxFileSystemWatcherEvent ExpectedEvent()
 
-         {
 
-             wxFileSystemWatcherEvent event(wxFSW_EVENT_ACCESS);
 
-             event.SetPath(eg.m_file);
 
-             event.SetNewPath(eg.m_file);
 
-             return event;
 
-         }
 
-     };
 
-     EventTester tester;
 
-     tester.Run();
 
- }
 
- #endif // wxHAS_INOTIFY
 
- // ----------------------------------------------------------------------------
 
- // TestTrees
 
- // ----------------------------------------------------------------------------
 
- #if !defined(__VISUALC__) || wxCHECK_VISUALC_VERSION(7)
 
- void FileSystemWatcherTestCase::TestTrees()
 
- {
 
-     class TreeTester : public EventHandler
 
-     {
 
-         const size_t subdirs;
 
-         const size_t files;
 
-     public:
 
-         TreeTester() : subdirs(5), files(3) {}
 
-         void GrowTree(wxFileName dir
 
- #ifdef __UNIX__
 
-                       , bool withSymlinks = false
 
- #endif
 
-                       )
 
-         {
 
-             CPPUNIT_ASSERT(dir.Mkdir());
 
-             // Now add a subdir with an easy name to remember in WatchTree()
 
-             dir.AppendDir("child");
 
-             CPPUNIT_ASSERT(dir.Mkdir());
 
-             wxFileName child(dir);  // Create a copy to which to symlink
 
-             // Create a branch of 5 numbered subdirs, each containing 3
 
-             // numbered files
 
-             for ( unsigned d = 0; d < subdirs; ++d )
 
-             {
 
-                 dir.AppendDir(wxString::Format("subdir%u", d+1));
 
-                 CPPUNIT_ASSERT(dir.Mkdir());
 
-                 const wxString prefix = dir.GetPathWithSep();
 
-                 const wxString ext[] = { ".txt", ".log", "" };
 
-                 for ( unsigned f = 0; f < files; ++f )
 
-                 {
 
-                     // Just create the files.
 
-                     wxFile(prefix + wxString::Format("file%u", f+1) + ext[f],
 
-                            wxFile::write);
 
-                 }
 
- #if defined(__UNIX__)
 
-                 if ( withSymlinks )
 
-                 {
 
-                     // Create a symlink to a files, and another to 'child'
 
-                     CPPUNIT_ASSERT_EQUAL(0,
 
-                         symlink(wxString(prefix + "file1").c_str(),
 
-                         wxString(prefix + "file.lnk").c_str()));
 
-                     CPPUNIT_ASSERT_EQUAL(0,
 
-                         symlink(child.GetFullPath().c_str(),
 
-                         wxString(prefix + "dir.lnk").c_str()));
 
-                 }
 
- #endif // __UNIX__
 
-             }
 
-         }
 
-         void RmDir(wxFileName dir)
 
-         {
 
-             CPPUNIT_ASSERT(dir.DirExists());
 
-             CPPUNIT_ASSERT(dir.Rmdir(wxPATH_RMDIR_RECURSIVE));
 
-         }
 
-         void WatchDir(wxFileName dir)
 
-         {
 
-             CPPUNIT_ASSERT(m_watcher);
 
-             // Store the initial count; there may already be some watches
 
-             const int initial = m_watcher->GetWatchedPathsCount();
 
-             m_watcher->Add(dir);
 
-             CPPUNIT_ASSERT_EQUAL(initial + 1,
 
-                                  m_watcher->GetWatchedPathsCount());
 
-         }
 
-         void RemoveSingleWatch(wxFileName dir)
 
-         {
 
-             CPPUNIT_ASSERT(m_watcher);
 
-             const int initial = m_watcher->GetWatchedPathsCount();
 
-             m_watcher->Remove(dir);
 
-             CPPUNIT_ASSERT_EQUAL(initial - 1,
 
-                                  m_watcher->GetWatchedPathsCount());
 
-         }
 
-         void WatchTree(const wxFileName& dir)
 
-         {
 
-             CPPUNIT_ASSERT(m_watcher);
 
-             size_t treeitems = 1; // the trunk
 
- #ifndef __WINDOWS__
 
-             // When there's no file mask, wxMSW sets a single watch
 
-             // on the trunk which is implemented recursively.
 
-             // wxGTK always sets an additional watch for each subdir
 
-             treeitems += subdirs + 1; // +1 for 'child'
 
- #endif // __WINDOWS__
 
-             // Store the initial count; there may already be some watches
 
-             const int initial = m_watcher->GetWatchedPathsCount();
 
-             GrowTree(dir);
 
-             m_watcher->AddTree(dir);
 
-             const int plustree = m_watcher->GetWatchedPathsCount();
 
-             CPPUNIT_ASSERT_EQUAL(initial + treeitems, plustree);
 
-             m_watcher->RemoveTree(dir);
 
-             CPPUNIT_ASSERT_EQUAL(initial, m_watcher->GetWatchedPathsCount());
 
-             // Now test the refcount mechanism by watching items more than once
 
-             wxFileName child(dir);
 
-             child.AppendDir("child");
 
-             m_watcher->AddTree(child);
 
-             // Check some watches were added; we don't care about the number
 
-             CPPUNIT_ASSERT(initial < m_watcher->GetWatchedPathsCount());
 
-             // Now watch the whole tree and check that the count is the same
 
-             // as it was the first time, despite also adding 'child' separately
 
-             // Except that in wxMSW this isn't true: each watch will be a
 
-             // single, recursive dir; so fudge the count
 
-             size_t fudge = 0;
 
- #ifdef __WINDOWS__
 
-             fudge = 1;
 
- #endif // __WINDOWS__
 
-             m_watcher->AddTree(dir);
 
-             CPPUNIT_ASSERT_EQUAL(plustree + fudge, m_watcher->GetWatchedPathsCount());
 
-             m_watcher->RemoveTree(child);
 
-             CPPUNIT_ASSERT(initial < m_watcher->GetWatchedPathsCount());
 
-             m_watcher->RemoveTree(dir);
 
-             CPPUNIT_ASSERT_EQUAL(initial, m_watcher->GetWatchedPathsCount());
 
- #if defined(__UNIX__)
 
-             // Finally, test a tree containing internal symlinks
 
-             RmDir(dir);
 
-             GrowTree(dir, true /* test symlinks */);
 
-             // Without the DontFollowLink() call AddTree() would now assert
 
-             // (and without the assert, it would infinitely loop)
 
-             wxFileName fn = dir;
 
-             fn.DontFollowLink();
 
-             CPPUNIT_ASSERT(m_watcher->AddTree(fn));
 
-             CPPUNIT_ASSERT(m_watcher->RemoveTree(fn));
 
-             // Regrow the tree without symlinks, ready for the next test
 
-             RmDir(dir);
 
-             GrowTree(dir, false);
 
- #endif // __UNIX__
 
-         }
 
-         void WatchTreeWithFilespec(const wxFileName& dir)
 
-         {
 
-             CPPUNIT_ASSERT(m_watcher);
 
-             CPPUNIT_ASSERT(dir.DirExists()); // Was built in WatchTree()
 
-             // Store the initial count; there may already be some watches
 
-             const int initial = m_watcher->GetWatchedPathsCount();
 
-             // When we use a filter, both wxMSW and wxGTK implementations set
 
-             // an additional watch for each subdir (+1 for the root dir itself
 
-             // and another +1 for "child").
 
-             const size_t treeitems = subdirs + 2;
 
-             m_watcher->AddTree(dir, wxFSW_EVENT_ALL, "*.txt");
 
-             const int plustree = m_watcher->GetWatchedPathsCount();
 
-             CPPUNIT_ASSERT_EQUAL(initial + treeitems, plustree);
 
-             // RemoveTree should try to remove only those files that were added
 
-             m_watcher->RemoveTree(dir);
 
-             CPPUNIT_ASSERT_EQUAL(initial, m_watcher->GetWatchedPathsCount());
 
-         }
 
-         void RemoveAllWatches()
 
-         {
 
-             CPPUNIT_ASSERT(m_watcher);
 
-             m_watcher->RemoveAll();
 
-             CPPUNIT_ASSERT_EQUAL(0, m_watcher->GetWatchedPathsCount());
 
-         }
 
-         virtual void GenerateEvent()
 
-         {
 
-             // We don't use this function for events. Just run the tests
 
-             wxFileName watchdir = EventGenerator::GetWatchDir();
 
-             CPPUNIT_ASSERT(watchdir.DirExists());
 
-             wxFileName treedir(watchdir);
 
-             treedir.AppendDir("treetrunk");
 
-             CPPUNIT_ASSERT(!treedir.DirExists());
 
-             wxFileName singledir(watchdir);
 
-             singledir.AppendDir("single");
 
-             CPPUNIT_ASSERT(!singledir.DirExists());
 
-             CPPUNIT_ASSERT(singledir.Mkdir());
 
-             WatchDir(singledir);
 
-             WatchTree(treedir);
 
-             // Now test adding and removing a tree using a filespec
 
-             // wxMSW uses the generic method to add matching files; which fails
 
-             // as it doesn't support adding files :/ So disable the test
 
- #ifndef __WINDOWS__
 
-             WatchTreeWithFilespec(treedir);
 
- #endif // __WINDOWS__
 
-             RemoveSingleWatch(singledir);
 
-             // Add it back again, ready to test RemoveAll()
 
-             WatchDir(singledir);
 
-             RemoveAllWatches();
 
-             // Clean up
 
-             RmDir(singledir);
 
-             RmDir(treedir);
 
-             Exit();
 
-         }
 
-         virtual wxFileSystemWatcherEvent ExpectedEvent()
 
-         {
 
-             CPPUNIT_FAIL("Shouldn't be called");
 
-             return wxFileSystemWatcherEvent(wxFSW_EVENT_ERROR);
 
-         }
 
-         virtual void CheckResult()
 
-         {
 
-             // Do nothing. We override this to prevent receiving events in
 
-             // ExpectedEvent()
 
-         }
 
-     };
 
-     TreeTester tester;
 
-     tester.Run();
 
- }
 
- #endif // !defined(__VISUALC__) || wxCHECK_VISUALC_VERSION(7)
 
- namespace
 
- {
 
- // We can't define this class locally inside TestNoEventsAfterRemove() for some
 
- // reason with g++ 4.0 under OS X 10.5, it results in the following mysterious
 
- // error:
 
- //
 
- // /var/tmp//ccTkNCkc.s:unknown:Non-global symbol:
 
- // __ZThn80_ZN25FileSystemWatcherTestCase23TestNoEventsAfterRemoveEvEN11EventTester6NotifyEv.eh
 
- // can't be a weak_definition
 
- //
 
- // So define this class outside the function instead.
 
- class NoEventsAfterRemoveEventTester : public EventHandler,
 
-                                        public wxTimer
 
- {
 
- public:
 
-     NoEventsAfterRemoveEventTester()
 
-     {
 
-         // We need to use an inactivity timer as we never get any file
 
-         // system events in this test, so we consider that the test is
 
-         // finished when this 1s timeout expires instead of, as usual,
 
-         // stopping after getting the file system events.
 
-         Start(1000, true);
 
-     }
 
-     virtual void GenerateEvent()
 
-     {
 
-         m_watcher->Remove(EventGenerator::GetWatchDir());
 
-         CPPUNIT_ASSERT(eg.CreateFile());
 
-     }
 
-     virtual void CheckResult()
 
-     {
 
-         CPPUNIT_ASSERT( m_events.empty() );
 
-     }
 
-     virtual wxFileSystemWatcherEvent ExpectedEvent()
 
-     {
 
-         CPPUNIT_FAIL( "Shouldn't be called" );
 
-         return wxFileSystemWatcherEvent(wxFSW_EVENT_ERROR);
 
-     }
 
-     virtual void Notify()
 
-     {
 
-         SendIdle();
 
-     }
 
- };
 
- } // anonymous namespace
 
- void FileSystemWatcherTestCase::TestNoEventsAfterRemove()
 
- {
 
-     NoEventsAfterRemoveEventTester tester;
 
-     tester.Run();
 
- }
 
 
  |