Merge branch 'fswatcher-test-modernize'

Modernize and clean up wxFileSystemWatcher unit test.

See https://github.com/wxWidgets/wxWidgets/pull/1307
This commit is contained in:
Vadim Zeitlin
2019-04-26 23:35:23 +02:00

View File

@@ -25,20 +25,13 @@
#include "wx/evtloop.h"
#include "wx/filename.h"
#include "wx/filefn.h"
#include "wx/stdpaths.h"
#include "wx/fswatcher.h"
#include "wx/scopedptr.h"
#include "wx/stdpaths.h"
#include "wx/vector.h"
#include "testfile.h"
/*
This test used to be disabled on OS X as it hung. Work around the apparent
wxOSX differences between a non-GUI event loop and a GUI event loop (where
the tests do run fine) until this gets resolved.
*/
#ifdef __WXOSX__
#define OSX_EVENT_LOOP_WORKAROUND
#endif
// ----------------------------------------------------------------------------
// local functions
// ----------------------------------------------------------------------------
@@ -71,7 +64,7 @@ public:
bool RenameFile()
{
CPPUNIT_ASSERT(m_file.FileExists());
REQUIRE(m_file.FileExists());
wxLogDebug("Renaming %s=>%s", m_file.GetFullPath(), m_new.GetFullPath());
@@ -88,7 +81,7 @@ public:
bool DeleteFile()
{
CPPUNIT_ASSERT(m_file.FileExists());
REQUIRE(m_file.FileExists());
bool ret = wxRemoveFile(m_file.GetFullPath());
if (ret)
@@ -109,23 +102,23 @@ public:
bool ReadFile()
{
wxFile f(m_file.GetFullPath());
CPPUNIT_ASSERT(f.IsOpened());
REQUIRE(f.IsOpened());
char buf[1];
ssize_t count = f.Read(buf, sizeof(buf));
CPPUNIT_ASSERT(count > 0);
CHECK(count > 0);
return true;
}
bool ModifyFile()
{
CPPUNIT_ASSERT(m_file.FileExists());
REQUIRE(m_file.FileExists());
wxFile file(m_file.GetFullPath(), wxFile::write_append);
CPPUNIT_ASSERT(file.IsOpened());
REQUIRE(file.IsOpened());
CPPUNIT_ASSERT(file.Write("Words of Wisdom, Lloyd. Words of wisdom\n"));
CHECK(file.Write("Words of Wisdom, Lloyd. Words of wisdom\n"));
return file.Close();
}
@@ -149,8 +142,8 @@ public:
// 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());
REQUIRE(!dir.DirExists());
REQUIRE(dir.Mkdir());
return dir;
}
@@ -158,12 +151,12 @@ public:
static void RemoveWatchDir()
{
wxFileName dir = GetWatchDir();
CPPUNIT_ASSERT(dir.DirExists());
REQUIRE(dir.DirExists());
// just to be really sure we know what we remove
CPPUNIT_ASSERT_EQUAL( "fswatcher_test", dir.GetDirs().Last() );
REQUIRE( dir.GetDirs().Last() == "fswatcher_test" );
CPPUNIT_ASSERT( dir.Rmdir(wxPATH_RMDIR_RECURSIVE) );
CHECK( dir.Rmdir(wxPATH_RMDIR_RECURSIVE) );
}
static wxFileName RandomName(const wxFileName& base, int length = 10)
@@ -193,45 +186,34 @@ protected:
EventGenerator* EventGenerator::ms_instance = 0;
// custom event handler
class EventHandler : public wxEvtHandler
// Abstract base class from which concrete event tests inherit.
//
// This class provides the common test skeleton which various virtual hooks
// that should or can be reimplemented by the derived classes.
class FSWTesterBase : public wxEvtHandler
{
public:
enum { WAIT_DURATION = 3 };
EventHandler(int types = wxFSW_EVENT_ALL) :
eg(EventGenerator::Get()), m_loop(0),
#ifdef OSX_EVENT_LOOP_WORKAROUND
m_loopActivator(NULL),
#endif
m_count(0), m_watcher(0), m_eventTypes(types)
FSWTesterBase(int types = wxFSW_EVENT_ALL) :
eg(EventGenerator::Get()),
m_eventTypes(types)
{
m_loop = new wxEventLoop();
#ifdef OSX_EVENT_LOOP_WORKAROUND
m_loopActivator = new wxEventLoopActivator(m_loop);
#endif
Connect(wxEVT_IDLE, wxIdleEventHandler(EventHandler::OnIdle));
Connect(wxEVT_FSWATCHER, wxFileSystemWatcherEventHandler(
EventHandler::OnFileSystemEvent));
Bind(wxEVT_FSWATCHER, &FSWTesterBase::OnFileSystemEvent, this);
// wxFileSystemWatcher can be created only once the event loop is
// running, so we can't do it from here and will do it from inside the
// loop when this event handler is invoked.
CallAfter(&FSWTesterBase::OnIdleInit);
}
virtual ~EventHandler()
virtual ~FSWTesterBase()
{
delete m_watcher;
#ifdef OSX_EVENT_LOOP_WORKAROUND
delete m_loopActivator;
#endif
if (m_loop)
{
if (m_loop->IsRunning())
m_loop->Exit();
delete m_loop;
}
if (m_loop.IsRunning())
m_loop.Exit();
}
void Exit()
{
m_loop->Exit();
m_loop.Exit();
}
// sends idle event, so we get called in a moment
@@ -239,140 +221,73 @@ public:
{
wxIdleEvent* e = new wxIdleEvent();
QueueEvent(e);
#ifdef OSX_EVENT_LOOP_WORKAROUND
// The fs watcher test cases will hang on OS X if Yield() is not called.
// It seems that the OS X event loop and / or queueing behaves
// differently than on MSW and Linux.
m_loop->Yield(true);
#endif
}
void Run()
{
SendIdle();
m_loop->Run();
m_loop.Run();
}
void OnIdle(wxIdleEvent& /*evt*/)
void OnIdleInit()
{
bool more = Action();
m_count++;
REQUIRE(Init());
if (more)
{
SendIdle();
}
GenerateEvent();
// Check the result when the next idle event comes: note that we can't
// use CallAfter() here, unfortunately, because OnIdleCheckResult()
// would then be called immediately, from the same event loop iteration
// as we're called from, because the idle/pending events are processed
// for as long as there any. Instead, we need to return to the event
// loop itself to give it a chance to dispatch wxFileSystemWatcherEvent
// and wait until our handler for it calls SendIdle() which will then
// end up calling OnIdleCheckResult() afterwards.
Bind(wxEVT_IDLE, &FSWTesterBase::OnIdleCheckResult, this);
}
// returns whether we should produce more idle events
virtual bool Action()
void OnIdleCheckResult(wxIdleEvent& WXUNUSED(event))
{
switch (m_count)
{
case 0:
CPPUNIT_ASSERT(Init());
break;
case 1:
GenerateEvent();
break;
case 2:
// actual test
CheckResult();
Exit();
break;
Unbind(wxEVT_IDLE, &FSWTesterBase::OnIdleCheckResult, this);
// 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;
CheckResult();
Exit();
}
virtual bool Init()
{
// test we're good to go
CPPUNIT_ASSERT(wxEventLoopBase::GetActive());
CHECK(wxEventLoopBase::GetActive());
// XXX only now can we construct Watcher, because we need
// active loop here
m_watcher = new wxFileSystemWatcher();
m_watcher.reset(new wxFileSystemWatcher());
m_watcher->SetOwner(this);
// add dir to be watched
wxFileName dir = EventGenerator::GetWatchDir();
CPPUNIT_ASSERT(m_watcher->Add(dir, m_eventTypes));
CHECK(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() );
REQUIRE( !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() );
CHECK( e->GetChangeType() == expected.GetChangeType() );
CPPUNIT_ASSERT_EQUAL((int)wxEVT_FSWATCHER, e->GetEventType());
CHECK( e->GetEventType() == wxEVT_FSWATCHER );
// XXX this needs change
CPPUNIT_ASSERT_EQUAL(wxEVT_CATEGORY_UNKNOWN, e->GetEventCategory());
CHECK( e->GetEventCategory() == wxEVT_CATEGORY_UNKNOWN );
CPPUNIT_ASSERT_EQUAL(expected.GetPath(), e->GetPath());
CPPUNIT_ASSERT_EQUAL(expected.GetNewPath(), e->GetNewPath());
CHECK( e->GetPath() == expected.GetPath() );
CHECK( e->GetNewPath() == expected.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
@@ -412,121 +327,64 @@ public:
protected:
EventGenerator& eg;
wxEventLoopBase* m_loop; // loop reference
#ifdef OSX_EVENT_LOOP_WORKAROUND
wxEventLoopActivator* m_loopActivator;
#endif
int m_count; // idle events count
wxEventLoop m_loop; // loop reference
wxScopedPtr<wxFileSystemWatcher> m_watcher;
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() wxOVERRIDE;
virtual void tearDown() wxOVERRIDE;
protected:
wxEventLoopBase* m_loop;
wxVector<wxFileSystemWatcherEvent*> m_events;
private:
CPPUNIT_TEST_SUITE( FileSystemWatcherTestCase );
CPPUNIT_TEST( TestEventCreate );
CPPUNIT_TEST( TestEventDelete );
CPPUNIT_TEST( TestTrees );
void OnFileSystemEvent(wxFileSystemWatcherEvent& evt)
{
wxLogDebug("--- %s ---", evt.ToString());
m_events.push_back(wxDynamicCast(evt.Clone(), wxFileSystemWatcherEvent));
// 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
void TestTrees();
void TestNoEventsAfterRemove();
wxDECLARE_NO_COPY_CLASS(FileSystemWatcherTestCase);
// test finished
SendIdle();
}
};
// register in the unnamed registry so that these tests are run by default
CPPUNIT_TEST_SUITE_REGISTRATION( FileSystemWatcherTestCase );
// also include in its own registry so that these tests can be run alone
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( FileSystemWatcherTestCase,
"FileSystemWatcherTestCase" );
// ----------------------------------------------------------------------------
// test fixture
// ----------------------------------------------------------------------------
void FileSystemWatcherTestCase::setUp()
class FileSystemWatcherTestCase
{
wxLog::AddTraceMask(wxTRACE_FSWATCHER);
public:
FileSystemWatcherTestCase()
{
// Before each test, remove the dir if it exists.
// It would exist if the previous test run was aborted.
wxString tmp = wxStandardPaths::Get().GetTempDir();
wxFileName dir;
dir.AssignDir(tmp);
dir.AppendDir("fswatcher_test");
dir.Rmdir(wxPATH_RMDIR_RECURSIVE);
EventGenerator::Get().GetWatchDir();
}
// Before each test, remove the dir if it exists.
// It would exist if the previous test run was aborted.
wxString tmp = wxStandardPaths::Get().GetTempDir();
wxFileName dir;
dir.AssignDir(tmp);
dir.AppendDir("fswatcher_test");
dir.Rmdir(wxPATH_RMDIR_RECURSIVE);
EventGenerator::Get().GetWatchDir();
}
void FileSystemWatcherTestCase::tearDown()
{
EventGenerator::Get().RemoveWatchDir();
}
~FileSystemWatcherTestCase()
{
EventGenerator::Get().RemoveWatchDir();
}
};
// ----------------------------------------------------------------------------
// TestEventCreate
// ----------------------------------------------------------------------------
void FileSystemWatcherTestCase::TestEventCreate()
{
wxLogDebug("TestEventCreate()");
class EventTester : public EventHandler
TEST_CASE_METHOD(FileSystemWatcherTestCase,
"wxFileSystemWatcher::EventCreate", "[fsw]")
{
class EventTester : public FSWTesterBase
{
public:
virtual void GenerateEvent() wxOVERRIDE
{
CPPUNIT_ASSERT(eg.CreateFile());
CHECK(eg.CreateFile());
}
virtual wxFileSystemWatcherEvent ExpectedEvent() wxOVERRIDE
@@ -540,24 +398,22 @@ void FileSystemWatcherTestCase::TestEventCreate()
EventTester tester;
wxLogTrace(wxTRACE_FSWATCHER, "TestEventCreate tester created()");
tester.Run();
}
// ----------------------------------------------------------------------------
// TestEventDelete
// ----------------------------------------------------------------------------
void FileSystemWatcherTestCase::TestEventDelete()
{
wxLogDebug("TestEventDelete()");
class EventTester : public EventHandler
TEST_CASE_METHOD(FileSystemWatcherTestCase,
"wxFileSystemWatcher::EventDelete", "[fsw]")
{
class EventTester : public FSWTesterBase
{
public:
virtual void GenerateEvent() wxOVERRIDE
{
CPPUNIT_ASSERT(eg.DeleteFile());
CHECK(eg.DeleteFile());
}
virtual wxFileSystemWatcherEvent ExpectedEvent() wxOVERRIDE
@@ -578,19 +434,26 @@ void FileSystemWatcherTestCase::TestEventDelete()
tester.Run();
}
// 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
// ----------------------------------------------------------------------------
// TestEventRename
// ----------------------------------------------------------------------------
void FileSystemWatcherTestCase::TestEventRename()
{
wxLogDebug("TestEventRename()");
class EventTester : public EventHandler
TEST_CASE_METHOD(FileSystemWatcherTestCase,
"wxFileSystemWatcher::EventRename", "[fsw]")
{
class EventTester : public FSWTesterBase
{
public:
virtual void GenerateEvent() wxOVERRIDE
{
CPPUNIT_ASSERT(eg.RenameFile());
CHECK(eg.RenameFile());
}
virtual wxFileSystemWatcherEvent ExpectedEvent() wxOVERRIDE
@@ -612,16 +475,16 @@ void FileSystemWatcherTestCase::TestEventRename()
// ----------------------------------------------------------------------------
// TestEventModify
// ----------------------------------------------------------------------------
void FileSystemWatcherTestCase::TestEventModify()
{
wxLogDebug("TestEventModify()");
class EventTester : public EventHandler
TEST_CASE_METHOD(FileSystemWatcherTestCase,
"wxFileSystemWatcher::EventModify", "[fsw]")
{
class EventTester : public FSWTesterBase
{
public:
virtual void GenerateEvent() wxOVERRIDE
{
CPPUNIT_ASSERT(eg.ModifyFile());
CHECK(eg.ModifyFile());
}
virtual wxFileSystemWatcherEvent ExpectedEvent() wxOVERRIDE
@@ -640,19 +503,22 @@ void FileSystemWatcherTestCase::TestEventModify()
tester.Run();
}
// MSW implementation doesn't detect file access events currently
#ifndef __WINDOWS__
// ----------------------------------------------------------------------------
// TestEventAccess
// ----------------------------------------------------------------------------
void FileSystemWatcherTestCase::TestEventAccess()
{
wxLogDebug("TestEventAccess()");
class EventTester : public EventHandler
TEST_CASE_METHOD(FileSystemWatcherTestCase,
"wxFileSystemWatcher::EventAccess", "[fsw]")
{
class EventTester : public FSWTesterBase
{
public:
virtual void GenerateEvent() wxOVERRIDE
{
CPPUNIT_ASSERT(eg.ReadFile());
CHECK(eg.ReadFile());
}
virtual wxFileSystemWatcherEvent ExpectedEvent() wxOVERRIDE
@@ -672,20 +538,23 @@ void FileSystemWatcherTestCase::TestEventAccess()
tester.Run();
}
#endif // __WINDOWS__
#endif // !wxHAS_KQUEUE
#ifdef wxHAS_INOTIFY
// ----------------------------------------------------------------------------
// TestEventAttribute
// ----------------------------------------------------------------------------
void FileSystemWatcherTestCase::TestEventAttribute()
TEST_CASE_METHOD(FileSystemWatcherTestCase,
"wxFileSystemWatcher::EventAttribute", "[fsw]")
{
wxLogDebug("TestEventAttribute()");
class EventTester : public EventHandler
class EventTester : public FSWTesterBase
{
public:
virtual void GenerateEvent() wxOVERRIDE
{
CPPUNIT_ASSERT(eg.TouchFile());
CHECK(eg.TouchFile());
}
virtual wxFileSystemWatcherEvent ExpectedEvent() wxOVERRIDE
@@ -707,24 +576,24 @@ void FileSystemWatcherTestCase::TestEventAttribute()
// ----------------------------------------------------------------------------
// TestSingleWatchtypeEvent: Watch only wxFSW_EVENT_ACCESS
// ----------------------------------------------------------------------------
void FileSystemWatcherTestCase::TestSingleWatchtypeEvent()
{
wxLogDebug("TestSingleWatchtypeEvent()");
class EventTester : public EventHandler
TEST_CASE_METHOD(FileSystemWatcherTestCase,
"wxFileSystemWatcher::SingleWatchtypeEvent", "[fsw]")
{
class EventTester : public FSWTesterBase
{
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) {}
EventTester() : FSWTesterBase(wxFSW_EVENT_ACCESS) {}
virtual void GenerateEvent() wxOVERRIDE
{
// 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());
CHECK(eg.CreateFile());
CHECK(eg.ModifyFile());
CHECK(eg.ReadFile());
}
virtual wxFileSystemWatcherEvent ExpectedEvent() wxOVERRIDE
@@ -745,9 +614,10 @@ void FileSystemWatcherTestCase::TestSingleWatchtypeEvent()
// TestTrees
// ----------------------------------------------------------------------------
void FileSystemWatcherTestCase::TestTrees()
TEST_CASE_METHOD(FileSystemWatcherTestCase,
"wxFileSystemWatcher::Trees", "[fsw]")
{
class TreeTester : public EventHandler
class TreeTester : public FSWTesterBase
{
const size_t subdirs;
const size_t files;
@@ -761,10 +631,10 @@ void FileSystemWatcherTestCase::TestTrees()
#endif
)
{
CPPUNIT_ASSERT(dir.Mkdir());
REQUIRE(dir.Mkdir());
// Now add a subdir with an easy name to remember in WatchTree()
dir.AppendDir("child");
CPPUNIT_ASSERT(dir.Mkdir());
REQUIRE(dir.Mkdir());
wxFileName child(dir); // Create a copy to which to symlink
// Create a branch of 5 numbered subdirs, each containing 3
@@ -772,7 +642,7 @@ void FileSystemWatcherTestCase::TestTrees()
for ( unsigned d = 0; d < subdirs; ++d )
{
dir.AppendDir(wxString::Format("subdir%u", d+1));
CPPUNIT_ASSERT(dir.Mkdir());
REQUIRE(dir.Mkdir());
const wxString prefix = dir.GetPathWithSep();
const wxString ext[] = { ".txt", ".log", "" };
@@ -786,12 +656,17 @@ void FileSystemWatcherTestCase::TestTrees()
if ( withSymlinks )
{
// Create a symlink to a files, and another to 'child'
CPPUNIT_ASSERT_EQUAL(0,
CHECK
(
symlink(wxString(prefix + "file1").c_str(),
wxString(prefix + "file.lnk").c_str()));
CPPUNIT_ASSERT_EQUAL(0,
wxString(prefix + "file.lnk").c_str()) == 0
);
CHECK
(
symlink(child.GetFullPath().c_str(),
wxString(prefix + "dir.lnk").c_str()));
wxString(prefix + "dir.lnk").c_str()) == 0
);
}
#endif // __UNIX__
}
@@ -799,37 +674,35 @@ void FileSystemWatcherTestCase::TestTrees()
void RmDir(wxFileName dir)
{
CPPUNIT_ASSERT(dir.DirExists());
REQUIRE(dir.DirExists());
CPPUNIT_ASSERT(dir.Rmdir(wxPATH_RMDIR_RECURSIVE));
CHECK(dir.Rmdir(wxPATH_RMDIR_RECURSIVE));
}
void WatchDir(wxFileName dir)
{
CPPUNIT_ASSERT(m_watcher);
REQUIRE(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());
CHECK( m_watcher->GetWatchedPathsCount() == initial + 1 );
}
void RemoveSingleWatch(wxFileName dir)
{
CPPUNIT_ASSERT(m_watcher);
REQUIRE(m_watcher);
const int initial = m_watcher->GetWatchedPathsCount();
m_watcher->Remove(dir);
CPPUNIT_ASSERT_EQUAL(initial - 1,
m_watcher->GetWatchedPathsCount());
CHECK( m_watcher->GetWatchedPathsCount() == initial - 1 );
}
void WatchTree(const wxFileName& dir)
{
CPPUNIT_ASSERT(m_watcher);
REQUIRE(m_watcher);
int treeitems = 1; // the trunk
#if !defined(__WINDOWS__) && !defined(wxHAVE_FSEVENTS_FILE_NOTIFICATIONS)
@@ -847,17 +720,17 @@ void FileSystemWatcherTestCase::TestTrees()
m_watcher->AddTree(dir);
const int plustree = m_watcher->GetWatchedPathsCount();
CPPUNIT_ASSERT_EQUAL(initial + treeitems, plustree);
CHECK( plustree == initial + treeitems );
m_watcher->RemoveTree(dir);
CPPUNIT_ASSERT_EQUAL(initial, m_watcher->GetWatchedPathsCount());
CHECK( m_watcher->GetWatchedPathsCount() == initial );
// 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());
CHECK(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
@@ -867,11 +740,11 @@ void FileSystemWatcherTestCase::TestTrees()
fudge = 1;
#endif // __WINDOWS__ || wxHAVE_FSEVENTS_FILE_NOTIFICATIONS
m_watcher->AddTree(dir);
CPPUNIT_ASSERT_EQUAL(plustree + fudge, m_watcher->GetWatchedPathsCount());
CHECK( m_watcher->GetWatchedPathsCount() == plustree + fudge );
m_watcher->RemoveTree(child);
CPPUNIT_ASSERT(initial < m_watcher->GetWatchedPathsCount());
CHECK(initial < m_watcher->GetWatchedPathsCount());
m_watcher->RemoveTree(dir);
CPPUNIT_ASSERT_EQUAL(initial, m_watcher->GetWatchedPathsCount());
CHECK( m_watcher->GetWatchedPathsCount() == initial );
#if defined(__UNIX__)
// Finally, test a tree containing internal symlinks
RmDir(dir);
@@ -881,8 +754,8 @@ void FileSystemWatcherTestCase::TestTrees()
// (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));
CHECK(m_watcher->AddTree(fn));
CHECK(m_watcher->RemoveTree(fn));
// Regrow the tree without symlinks, ready for the next test
RmDir(dir);
@@ -892,8 +765,8 @@ void FileSystemWatcherTestCase::TestTrees()
void WatchTreeWithFilespec(const wxFileName& dir)
{
CPPUNIT_ASSERT(m_watcher);
CPPUNIT_ASSERT(dir.DirExists()); // Was built in WatchTree()
REQUIRE(m_watcher);
REQUIRE(dir.DirExists()); // Was built in WatchTree()
// Store the initial count; there may already be some watches
const int initial = m_watcher->GetWatchedPathsCount();
@@ -909,20 +782,19 @@ void FileSystemWatcherTestCase::TestTrees()
#endif
m_watcher->AddTree(dir, wxFSW_EVENT_ALL, "*.txt");
const int plustree = m_watcher->GetWatchedPathsCount();
CPPUNIT_ASSERT_EQUAL(initial + treeitems, plustree);
CHECK( m_watcher->GetWatchedPathsCount() == initial + treeitems );
// RemoveTree should try to remove only those files that were added
m_watcher->RemoveTree(dir);
CPPUNIT_ASSERT_EQUAL(initial, m_watcher->GetWatchedPathsCount());
CHECK( m_watcher->GetWatchedPathsCount() == initial );
}
void RemoveAllWatches()
{
CPPUNIT_ASSERT(m_watcher);
REQUIRE(m_watcher);
m_watcher->RemoveAll();
CPPUNIT_ASSERT_EQUAL(0, m_watcher->GetWatchedPathsCount());
CHECK( m_watcher->GetWatchedPathsCount() == 0 );
}
virtual void GenerateEvent() wxOVERRIDE
@@ -930,16 +802,16 @@ void FileSystemWatcherTestCase::TestTrees()
// We don't use this function for events. Just run the tests
wxFileName watchdir = EventGenerator::GetWatchDir();
CPPUNIT_ASSERT(watchdir.DirExists());
REQUIRE(watchdir.DirExists());
wxFileName treedir(watchdir);
treedir.AppendDir("treetrunk");
CPPUNIT_ASSERT(!treedir.DirExists());
CHECK(!treedir.DirExists());
wxFileName singledir(watchdir);
singledir.AppendDir("single");
CPPUNIT_ASSERT(!singledir.DirExists());
CPPUNIT_ASSERT(singledir.Mkdir());
CHECK(!singledir.DirExists());
CHECK(singledir.Mkdir());
WatchDir(singledir);
WatchTree(treedir);
@@ -965,7 +837,7 @@ void FileSystemWatcherTestCase::TestTrees()
virtual wxFileSystemWatcherEvent ExpectedEvent() wxOVERRIDE
{
CPPUNIT_FAIL("Shouldn't be called");
FAIL("Shouldn't be called");
return wxFileSystemWatcherEvent(wxFSW_EVENT_ERROR);
}
@@ -979,15 +851,7 @@ void FileSystemWatcherTestCase::TestTrees()
TreeTester tester;
// The fs watcher test cases will hang on OS X if we call Run().
// This is likely due to differences between the event loop
// between OS X and the other ports.
#ifdef OSX_EVENT_LOOP_WORKAROUND
tester.Init();
tester.GenerateEvent();
#else
tester.Run();
#endif
}
@@ -1003,7 +867,7 @@ namespace
// can't be a weak_definition
//
// So define this class outside the function instead.
class NoEventsAfterRemoveEventTester : public EventHandler,
class NoEventsAfterRemoveEventTester : public FSWTesterBase,
public wxTimer
{
public:
@@ -1019,17 +883,17 @@ public:
virtual void GenerateEvent() wxOVERRIDE
{
m_watcher->Remove(EventGenerator::GetWatchDir());
CPPUNIT_ASSERT(eg.CreateFile());
CHECK(eg.CreateFile());
}
virtual void CheckResult() wxOVERRIDE
{
CPPUNIT_ASSERT( m_events.empty() );
REQUIRE( m_events.empty() );
}
virtual wxFileSystemWatcherEvent ExpectedEvent() wxOVERRIDE
{
CPPUNIT_FAIL( "Shouldn't be called" );
FAIL( "Shouldn't be called" );
return wxFileSystemWatcherEvent(wxFSW_EVENT_ERROR);
}
@@ -1042,7 +906,8 @@ public:
} // anonymous namespace
void FileSystemWatcherTestCase::TestNoEventsAfterRemove()
TEST_CASE_METHOD(FileSystemWatcherTestCase,
"wxFileSystemWatcher::NoEventsAfterRemove", "[fsw]")
{
NoEventsAfterRemoveEventTester tester;
tester.Run();