1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: tests/fswatcher/fswatchertest.cpp
3 // Purpose: wxFileSystemWatcher unit test
4 // Author: Bartosz Bekier
7 // Copyright: (c) 2009 Bartosz Bekier
8 ///////////////////////////////////////////////////////////////////////////////
10 // ----------------------------------------------------------------------------
12 // ----------------------------------------------------------------------------
24 #include "wx/evtloop.h"
25 #include "wx/filename.h"
26 #include "wx/filefn.h"
27 #include "wx/stdpaths.h"
28 #include "wx/fswatcher.h"
32 // ----------------------------------------------------------------------------
34 // ----------------------------------------------------------------------------
36 // class generating file system events
40 static EventGenerator
& Get()
43 ms_instance
= new EventGenerator(GetWatchDir());
48 EventGenerator(const wxFileName
& path
) : m_base(path
)
51 m_file
= RandomName();
58 wxFile
file(m_file
.GetFullPath(), wxFile
::write
);
59 return file
.IsOpened() && m_file
.FileExists();
64 CPPUNIT_ASSERT(m_file
.FileExists());
66 wxLogDebug("Renaming %s=>%s", m_file
.GetFullPath(), m_new
.GetFullPath());
68 bool ret
= wxRenameFile(m_file
.GetFullPath(), m_new
.GetFullPath());
81 CPPUNIT_ASSERT(m_file
.FileExists());
83 bool ret
= wxRemoveFile(m_file
.GetFullPath());
96 return m_file
.Touch();
101 wxFile
f(m_file
.GetFullPath());
102 CPPUNIT_ASSERT(f
.IsOpened());
105 ssize_t count
= f
.Read(buf
, sizeof(buf
));
106 CPPUNIT_ASSERT(count
> 0);
113 CPPUNIT_ASSERT(m_file
.FileExists());
115 wxFile
file(m_file
.GetFullPath(), wxFile
::write_append
);
116 CPPUNIT_ASSERT(file
.IsOpened());
118 CPPUNIT_ASSERT(file
.Write("Words of Wisdom, Lloyd. Words of wisdom\n"));
123 wxFileName
RandomName(int length
= 10)
125 return RandomName(m_base
, length
);
129 static const wxFileName
& GetWatchDir()
131 static wxFileName dir
;
136 wxString tmp
= wxStandardPaths
::Get().GetTempDir();
139 // XXX look for more unique name? there is no function to generate
140 // unique filename, the file always get created...
141 dir
.AppendDir("fswatcher_test");
142 CPPUNIT_ASSERT(!dir
.DirExists());
143 CPPUNIT_ASSERT(dir
.Mkdir());
148 static void RemoveWatchDir()
150 wxFileName dir
= GetWatchDir();
151 CPPUNIT_ASSERT(dir
.DirExists());
153 // just to be really sure we know what we remove
154 CPPUNIT_ASSERT_EQUAL( "fswatcher_test", dir
.GetDirs().Last() );
156 // FIXME-VC6: using non-static Rmdir() results in ICE
157 CPPUNIT_ASSERT( wxFileName
::Rmdir(dir
.GetFullPath(), wxPATH_RMDIR_RECURSIVE
) );
160 static wxFileName
RandomName(const wxFileName
& base
, int length
= 10)
162 static int ALFA_CNT
= 'z' - 'a';
165 for (int i
= 0 ; i
< length
; ++i
)
167 char c
= 'a' + (rand() % ALFA_CNT
);
171 return wxFileName(base
.GetFullPath(), s
);
175 wxFileName m_base
; // base dir for doing operations
176 wxFileName m_file
; // current file name
177 wxFileName m_old
; // previous file name
178 wxFileName m_new
; // name after renaming
181 static EventGenerator
* ms_instance
;
184 EventGenerator
* EventGenerator
::ms_instance
= 0;
187 // custom event handler
188 class EventHandler
: public wxEvtHandler
191 enum { WAIT_DURATION
= 3 };
193 EventHandler(int types
= wxFSW_EVENT_ALL
) :
194 eg(EventGenerator
::Get()), m_loop(0), m_count(0), m_watcher(0),
197 m_loop
= new wxEventLoop();
198 Connect(wxEVT_IDLE
, wxIdleEventHandler(EventHandler
::OnIdle
));
199 Connect(wxEVT_FSWATCHER
, wxFileSystemWatcherEventHandler(
200 EventHandler
::OnFileSystemEvent
));
203 virtual ~EventHandler()
208 if (m_loop
->IsRunning())
219 // sends idle event, so we get called in a moment
222 wxIdleEvent
* e
= new wxIdleEvent();
232 void OnIdle(wxIdleEvent
& /*evt*/)
234 bool more
= Action();
243 // returns whether we should produce more idle events
244 virtual bool Action()
249 CPPUNIT_ASSERT(Init());
260 // TODO a mechanism that will break the loop in case we
261 // don't receive a file system event
262 // this below doesn't quite work, so all tests must pass :-)
267 CPPUNIT_ASSERT(KeepWaiting());
273 CPPUNIT_ASSERT(AfterWait());
276 } // switch (m_count)
283 // test we're good to go
284 CPPUNIT_ASSERT(wxEventLoopBase
::GetActive());
286 // XXX only now can we construct Watcher, because we need
288 m_watcher
= new wxFileSystemWatcher();
289 m_watcher
->SetOwner(this);
291 // add dir to be watched
292 wxFileName dir
= EventGenerator
::GetWatchDir();
293 CPPUNIT_ASSERT(m_watcher
->Add(dir
, m_eventTypes
));
298 virtual bool KeepWaiting()
300 // did we receive event already?
303 // well, let's wait a bit more
304 wxSleep(WAIT_DURATION
);
310 virtual bool AfterWait()
312 // fail if still no events
315 ("No events during %d seconds!", static_cast<int>(WAIT_DURATION
)),
322 virtual void OnFileSystemEvent(wxFileSystemWatcherEvent
& evt
)
324 wxLogDebug("--- %s ---", evt
.ToString());
325 m_lastEvent
= wxDynamicCast(evt
.Clone(), wxFileSystemWatcherEvent
);
326 m_events
.Add(m_lastEvent
);
333 virtual void CheckResult()
335 CPPUNIT_ASSERT_MESSAGE( "No events received", !m_events
.empty() );
337 const wxFileSystemWatcherEvent
* const e
= m_events
.front();
339 // this is our "reference event"
340 const wxFileSystemWatcherEvent expected
= ExpectedEvent();
342 CPPUNIT_ASSERT_EQUAL( expected
.GetChangeType(), e
->GetChangeType() );
344 CPPUNIT_ASSERT_EQUAL((int)wxEVT_FSWATCHER
, e
->GetEventType());
346 // XXX this needs change
347 CPPUNIT_ASSERT_EQUAL(wxEVT_CATEGORY_UNKNOWN
, e
->GetEventCategory());
349 CPPUNIT_ASSERT_EQUAL(expected
.GetPath(), e
->GetPath());
350 CPPUNIT_ASSERT_EQUAL(expected
.GetNewPath(), e
->GetNewPath());
352 // Under MSW extra modification events are sometimes reported after a
353 // rename and we just can't get rid of them, so ignore them in this
354 // test if they do happen.
355 if ( e
->GetChangeType() == wxFSW_EVENT_RENAME
&&
356 m_events
.size() == 2 )
358 const wxFileSystemWatcherEvent
* const e2
= m_events
.back();
359 if ( e2
->GetChangeType() == wxFSW_EVENT_MODIFY
&&
360 e2
->GetPath() == e
->GetNewPath() )
362 // This is a modify event for the new file, ignore it.
367 WX_ASSERT_EQUAL_MESSAGE
370 "Extra events received, last one is of type %x, path=\"%s\" "
371 "(the original event was for \"%s\" (\"%s\")",
372 m_events
.back()->GetChangeType(),
373 m_events
.back()->GetPath().GetFullPath(),
374 e
->GetPath().GetFullPath(),
375 e
->GetNewPath().GetFullPath()
382 virtual void GenerateEvent() = 0;
384 virtual wxFileSystemWatcherEvent
ExpectedEvent() = 0;
389 wxEventLoopBase
* m_loop
; // loop reference
390 int m_count
; // idle events count
392 wxFileSystemWatcher
* m_watcher
;
393 int m_eventTypes
; // Which event-types to watch. Normally all of them
394 bool tested
; // indicates, whether we have already passed the test
396 #include "wx/arrimpl.cpp"
397 WX_DEFINE_ARRAY_PTR(wxFileSystemWatcherEvent
*, wxArrayEvent
);
398 wxArrayEvent m_events
;
399 wxFileSystemWatcherEvent
* m_lastEvent
;
403 // ----------------------------------------------------------------------------
405 // ----------------------------------------------------------------------------
407 class FileSystemWatcherTestCase
: public CppUnit
::TestCase
410 FileSystemWatcherTestCase() { }
412 virtual void setUp();
413 virtual void tearDown();
416 wxEventLoopBase
* m_loop
;
419 CPPUNIT_TEST_SUITE( FileSystemWatcherTestCase
);
420 CPPUNIT_TEST( TestEventCreate
);
421 CPPUNIT_TEST( TestEventDelete
);
422 #if !defined(__VISUALC__) || wxCHECK_VISUALC_VERSION(7)
423 CPPUNIT_TEST( TestTrees
);
426 // kqueue-based implementation doesn't collapse create/delete pairs in
427 // renames and doesn't detect neither modifications nor access to the
428 // files reliably currently so disable these tests
430 // FIXME: fix the code and reenable them
432 CPPUNIT_TEST( TestEventRename
);
433 CPPUNIT_TEST( TestEventModify
);
435 // MSW implementation doesn't detect file access events currently
437 CPPUNIT_TEST( TestEventAccess
);
438 #endif // __WINDOWS__
439 #endif // !wxHAS_KQUEUE
442 CPPUNIT_TEST( TestSingleWatchtypeEvent
);
443 #endif // wxHAS_INOTIFY
445 CPPUNIT_TEST( TestNoEventsAfterRemove
);
446 CPPUNIT_TEST_SUITE_END();
448 void TestEventCreate();
449 void TestEventDelete();
450 void TestEventRename();
451 void TestEventModify();
452 void TestEventAccess();
454 void TestSingleWatchtypeEvent();
455 #endif // wxHAS_INOTIFY
456 #if !defined(__VISUALC__) || wxCHECK_VISUALC_VERSION(7)
457 void TestTrees(); // Visual C++ 6 can't build this
459 void TestNoEventsAfterRemove();
461 DECLARE_NO_COPY_CLASS(FileSystemWatcherTestCase
)
464 // the test currently hangs under OS X for some reason and this prevents tests
465 // ran by buildbot from completing so disable it until someone has time to
468 // FIXME: debug and fix this!
470 // register in the unnamed registry so that these tests are run by default
471 CPPUNIT_TEST_SUITE_REGISTRATION( FileSystemWatcherTestCase
);
474 // also include in its own registry so that these tests can be run alone
475 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( FileSystemWatcherTestCase
,
476 "FileSystemWatcherTestCase" );
478 void FileSystemWatcherTestCase
::setUp()
480 wxLog
::AddTraceMask(wxTRACE_FSWATCHER
);
481 EventGenerator
::Get().GetWatchDir();
484 void FileSystemWatcherTestCase
::tearDown()
486 EventGenerator
::Get().RemoveWatchDir();
489 // ----------------------------------------------------------------------------
491 // ----------------------------------------------------------------------------
492 void FileSystemWatcherTestCase
::TestEventCreate()
494 wxLogDebug("TestEventCreate()");
496 class EventTester
: public EventHandler
499 virtual void GenerateEvent()
501 CPPUNIT_ASSERT(eg
.CreateFile());
504 virtual wxFileSystemWatcherEvent
ExpectedEvent()
506 wxFileSystemWatcherEvent
event(wxFSW_EVENT_CREATE
);
507 event
.SetPath(eg
.m_file
);
508 event
.SetNewPath(eg
.m_file
);
515 wxLogTrace(wxTRACE_FSWATCHER
, "TestEventCreate tester created()");
520 // ----------------------------------------------------------------------------
522 // ----------------------------------------------------------------------------
523 void FileSystemWatcherTestCase
::TestEventDelete()
525 wxLogDebug("TestEventDelete()");
527 class EventTester
: public EventHandler
530 virtual void GenerateEvent()
532 CPPUNIT_ASSERT(eg
.DeleteFile());
535 virtual wxFileSystemWatcherEvent
ExpectedEvent()
537 wxFileSystemWatcherEvent
event(wxFSW_EVENT_DELETE
);
538 event
.SetPath(eg
.m_old
);
540 // CHECK maybe new path here could be NULL or sth?
541 event
.SetNewPath(eg
.m_old
);
546 // we need to create a file now, so we can delete it
547 EventGenerator
::Get().CreateFile();
553 // ----------------------------------------------------------------------------
555 // ----------------------------------------------------------------------------
556 void FileSystemWatcherTestCase
::TestEventRename()
558 wxLogDebug("TestEventRename()");
560 class EventTester
: public EventHandler
563 virtual void GenerateEvent()
565 CPPUNIT_ASSERT(eg
.RenameFile());
568 virtual wxFileSystemWatcherEvent
ExpectedEvent()
570 wxFileSystemWatcherEvent
event(wxFSW_EVENT_RENAME
);
571 event
.SetPath(eg
.m_old
);
572 event
.SetNewPath(eg
.m_file
);
577 // need a file to rename later
578 EventGenerator
::Get().CreateFile();
584 // ----------------------------------------------------------------------------
586 // ----------------------------------------------------------------------------
587 void FileSystemWatcherTestCase
::TestEventModify()
589 wxLogDebug("TestEventModify()");
591 class EventTester
: public EventHandler
594 virtual void GenerateEvent()
596 CPPUNIT_ASSERT(eg
.ModifyFile());
599 virtual wxFileSystemWatcherEvent
ExpectedEvent()
601 wxFileSystemWatcherEvent
event(wxFSW_EVENT_MODIFY
);
602 event
.SetPath(eg
.m_file
);
603 event
.SetNewPath(eg
.m_file
);
608 // we need to create a file to modify
609 EventGenerator
::Get().CreateFile();
615 // ----------------------------------------------------------------------------
617 // ----------------------------------------------------------------------------
618 void FileSystemWatcherTestCase
::TestEventAccess()
620 wxLogDebug("TestEventAccess()");
622 class EventTester
: public EventHandler
625 virtual void GenerateEvent()
627 CPPUNIT_ASSERT(eg
.ReadFile());
630 virtual wxFileSystemWatcherEvent
ExpectedEvent()
632 wxFileSystemWatcherEvent
event(wxFSW_EVENT_ACCESS
);
633 event
.SetPath(eg
.m_file
);
634 event
.SetNewPath(eg
.m_file
);
639 // we need to create a file to read from it and write sth to it
640 EventGenerator
::Get().CreateFile();
641 EventGenerator
::Get().ModifyFile();
648 // ----------------------------------------------------------------------------
649 // TestSingleWatchtypeEvent: Watch only wxFSW_EVENT_ACCESS
650 // ----------------------------------------------------------------------------
651 void FileSystemWatcherTestCase
::TestSingleWatchtypeEvent()
653 wxLogDebug("TestSingleWatchtypeEvent()");
655 class EventTester
: public EventHandler
658 // We could pass wxFSW_EVENT_CREATE or MODIFY instead, but not RENAME or
659 // DELETE as the event path fields would be wrong in CheckResult()
660 EventTester() : EventHandler(wxFSW_EVENT_ACCESS
) {}
662 virtual void GenerateEvent()
664 // As wxFSW_EVENT_ACCESS is passed to the ctor only ReadFile() will
665 // generate an event. Without it they all will, and the test fails
666 CPPUNIT_ASSERT(eg
.CreateFile());
667 CPPUNIT_ASSERT(eg
.ModifyFile());
668 CPPUNIT_ASSERT(eg
.ReadFile());
671 virtual wxFileSystemWatcherEvent
ExpectedEvent()
673 wxFileSystemWatcherEvent
event(wxFSW_EVENT_ACCESS
);
674 event
.SetPath(eg
.m_file
);
675 event
.SetNewPath(eg
.m_file
);
683 #endif // wxHAS_INOTIFY
685 // ----------------------------------------------------------------------------
687 // ----------------------------------------------------------------------------
689 #if !defined(__VISUALC__) || wxCHECK_VISUALC_VERSION(7)
690 void FileSystemWatcherTestCase
::TestTrees()
692 class TreeTester
: public EventHandler
694 const size_t subdirs
;
698 TreeTester() : subdirs(5), files(3) {}
700 void GrowTree(wxFileName dir
702 , bool withSymlinks
= false
706 CPPUNIT_ASSERT(dir
.Mkdir());
707 // Now add a subdir with an easy name to remember in WatchTree()
708 dir
.AppendDir("child");
709 CPPUNIT_ASSERT(dir
.Mkdir());
710 wxFileName
child(dir
); // Create a copy to which to symlink
712 // Create a branch of 5 numbered subdirs, each containing 3
714 for ( unsigned d
= 0; d
< subdirs
; ++d
)
716 dir
.AppendDir(wxString
::Format("subdir%u", d
+1));
717 CPPUNIT_ASSERT(dir
.Mkdir());
719 const wxString prefix
= dir
.GetPathWithSep();
720 const wxString ext
[] = { ".txt", ".log", "" };
721 for ( unsigned f
= 0; f
< files
; ++f
)
723 // Just create the files.
724 wxFile(prefix
+ wxString
::Format("file%u", f
+1) + ext
[f
],
727 #if defined(__UNIX__)
730 // Create a symlink to a files, and another to 'child'
731 CPPUNIT_ASSERT_EQUAL(0,
732 symlink(wxString(prefix
+ "file1").c_str(),
733 wxString(prefix
+ "file.lnk").c_str()));
734 CPPUNIT_ASSERT_EQUAL(0,
735 symlink(child
.GetFullPath().c_str(),
736 wxString(prefix
+ "dir.lnk").c_str()));
742 void RmDir(wxFileName dir
)
744 CPPUNIT_ASSERT(dir
.DirExists());
746 CPPUNIT_ASSERT(dir
.Rmdir(wxPATH_RMDIR_RECURSIVE
));
749 void WatchDir(wxFileName dir
)
751 CPPUNIT_ASSERT(m_watcher
);
753 // Store the initial count; there may already be some watches
754 const int initial
= m_watcher
->GetWatchedPathsCount();
757 CPPUNIT_ASSERT_EQUAL(initial
+ 1,
758 m_watcher
->GetWatchedPathsCount());
761 void RemoveSingleWatch(wxFileName dir
)
763 CPPUNIT_ASSERT(m_watcher
);
765 const int initial
= m_watcher
->GetWatchedPathsCount();
767 m_watcher
->Remove(dir
);
768 CPPUNIT_ASSERT_EQUAL(initial
- 1,
769 m_watcher
->GetWatchedPathsCount());
772 void WatchTree(const wxFileName
& dir
)
774 CPPUNIT_ASSERT(m_watcher
);
776 size_t treeitems
= 1; // the trunk
778 // When there's no file mask, wxMSW sets a single watch
779 // on the trunk which is implemented recursively.
780 // wxGTK always sets an additional watch for each subdir
781 treeitems
+= subdirs
+ 1; // +1 for 'child'
782 #endif // __WINDOWS__
784 // Store the initial count; there may already be some watches
785 const int initial
= m_watcher
->GetWatchedPathsCount();
789 m_watcher
->AddTree(dir
);
790 const int plustree
= m_watcher
->GetWatchedPathsCount();
792 CPPUNIT_ASSERT_EQUAL(initial
+ treeitems
, plustree
);
794 m_watcher
->RemoveTree(dir
);
795 CPPUNIT_ASSERT_EQUAL(initial
, m_watcher
->GetWatchedPathsCount());
797 // Now test the refcount mechanism by watching items more than once
798 wxFileName
child(dir
);
799 child
.AppendDir("child");
800 m_watcher
->AddTree(child
);
801 // Check some watches were added; we don't care about the number
802 CPPUNIT_ASSERT(initial
< m_watcher
->GetWatchedPathsCount());
803 // Now watch the whole tree and check that the count is the same
804 // as it was the first time, despite also adding 'child' separately
805 // Except that in wxMSW this isn't true: each watch will be a
806 // single, recursive dir; so fudge the count
810 #endif // __WINDOWS__
811 m_watcher
->AddTree(dir
);
812 CPPUNIT_ASSERT_EQUAL(plustree
+ fudge
, m_watcher
->GetWatchedPathsCount());
813 m_watcher
->RemoveTree(child
);
814 CPPUNIT_ASSERT(initial
< m_watcher
->GetWatchedPathsCount());
815 m_watcher
->RemoveTree(dir
);
816 CPPUNIT_ASSERT_EQUAL(initial
, m_watcher
->GetWatchedPathsCount());
817 #if defined(__UNIX__)
818 // Finally, test a tree containing internal symlinks
820 GrowTree(dir
, true /* test symlinks */);
822 // Without the DontFollowLink() call AddTree() would now assert
823 // (and without the assert, it would infinitely loop)
826 CPPUNIT_ASSERT(m_watcher
->AddTree(fn
));
827 CPPUNIT_ASSERT(m_watcher
->RemoveTree(fn
));
829 // Regrow the tree without symlinks, ready for the next test
831 GrowTree(dir
, false);
835 void WatchTreeWithFilespec(const wxFileName
& dir
)
837 CPPUNIT_ASSERT(m_watcher
);
838 CPPUNIT_ASSERT(dir
.DirExists()); // Was built in WatchTree()
840 // Store the initial count; there may already be some watches
841 const int initial
= m_watcher
->GetWatchedPathsCount();
843 // When we use a filter, both wxMSW and wxGTK implementations set
844 // an additional watch for each subdir (+1 for the root dir itself
845 // and another +1 for "child").
846 const size_t treeitems
= subdirs
+ 2;
847 m_watcher
->AddTree(dir
, wxFSW_EVENT_ALL
, "*.txt");
849 const int plustree
= m_watcher
->GetWatchedPathsCount();
850 CPPUNIT_ASSERT_EQUAL(initial
+ treeitems
, plustree
);
852 // RemoveTree should try to remove only those files that were added
853 m_watcher
->RemoveTree(dir
);
854 CPPUNIT_ASSERT_EQUAL(initial
, m_watcher
->GetWatchedPathsCount());
857 void RemoveAllWatches()
859 CPPUNIT_ASSERT(m_watcher
);
861 m_watcher
->RemoveAll();
862 CPPUNIT_ASSERT_EQUAL(0, m_watcher
->GetWatchedPathsCount());
865 virtual void GenerateEvent()
867 // We don't use this function for events. Just run the tests
869 wxFileName watchdir
= EventGenerator
::GetWatchDir();
870 CPPUNIT_ASSERT(watchdir
.DirExists());
872 wxFileName
treedir(watchdir
);
873 treedir
.AppendDir("treetrunk");
874 CPPUNIT_ASSERT(!treedir
.DirExists());
876 wxFileName
singledir(watchdir
);
877 singledir
.AppendDir("single");
878 CPPUNIT_ASSERT(!singledir
.DirExists());
879 CPPUNIT_ASSERT(singledir
.Mkdir());
883 // Now test adding and removing a tree using a filespec
884 // wxMSW uses the generic method to add matching files; which fails
885 // as it doesn't support adding files :/ So disable the test
887 WatchTreeWithFilespec(treedir
);
888 #endif // __WINDOWS__
890 RemoveSingleWatch(singledir
);
891 // Add it back again, ready to test RemoveAll()
903 virtual wxFileSystemWatcherEvent
ExpectedEvent()
905 CPPUNIT_FAIL("Shouldn't be called");
907 return wxFileSystemWatcherEvent(wxFSW_EVENT_ERROR
);
910 virtual void CheckResult()
912 // Do nothing. We override this to prevent receiving events in
920 #endif // !defined(__VISUALC__) || wxCHECK_VISUALC_VERSION(7)
926 // We can't define this class locally inside TestNoEventsAfterRemove() for some
927 // reason with g++ 4.0 under OS X 10.5, it results in the following mysterious
930 // /var/tmp//ccTkNCkc.s:unknown:Non-global symbol:
931 // __ZThn80_ZN25FileSystemWatcherTestCase23TestNoEventsAfterRemoveEvEN11EventTester6NotifyEv.eh
932 // can't be a weak_definition
934 // So define this class outside the function instead.
935 class NoEventsAfterRemoveEventTester
: public EventHandler
,
939 NoEventsAfterRemoveEventTester()
941 // We need to use an inactivity timer as we never get any file
942 // system events in this test, so we consider that the test is
943 // finished when this 1s timeout expires instead of, as usual,
944 // stopping after getting the file system events.
948 virtual void GenerateEvent()
950 m_watcher
->Remove(EventGenerator
::GetWatchDir());
951 CPPUNIT_ASSERT(eg
.CreateFile());
954 virtual void CheckResult()
956 CPPUNIT_ASSERT( m_events
.empty() );
959 virtual wxFileSystemWatcherEvent
ExpectedEvent()
961 CPPUNIT_FAIL( "Shouldn't be called" );
963 return wxFileSystemWatcherEvent(wxFSW_EVENT_ERROR
);
966 virtual void Notify()
972 } // anonymous namespace
974 void FileSystemWatcherTestCase
::TestNoEventsAfterRemove()
976 NoEventsAfterRemoveEventTester tester
;