Separate out zip specific parts of the archive test suite
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@31892 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -44,6 +44,7 @@ TEST_CXXFLAGS = $(__test_PCH_INC) -D__WX$(TOOLKIT)__ $(__WXUNIV_DEFINE_p) \
|
|||||||
TEST_OBJECTS = \
|
TEST_OBJECTS = \
|
||||||
test_test.o \
|
test_test.o \
|
||||||
test_archivetest.o \
|
test_archivetest.o \
|
||||||
|
test_ziptest.o \
|
||||||
test_arrays.o \
|
test_arrays.o \
|
||||||
test_datetimetest.o \
|
test_datetimetest.o \
|
||||||
test_fileconftest.o \
|
test_fileconftest.o \
|
||||||
@@ -240,6 +241,9 @@ test_test.o: $(srcdir)/test.cpp $(TEST_ODEP)
|
|||||||
test_archivetest.o: $(srcdir)/archive/archivetest.cpp $(TEST_ODEP)
|
test_archivetest.o: $(srcdir)/archive/archivetest.cpp $(TEST_ODEP)
|
||||||
$(CXXC) -c -o $@ $(TEST_CXXFLAGS) $(srcdir)/archive/archivetest.cpp
|
$(CXXC) -c -o $@ $(TEST_CXXFLAGS) $(srcdir)/archive/archivetest.cpp
|
||||||
|
|
||||||
|
test_ziptest.o: $(srcdir)/archive/ziptest.cpp $(TEST_ODEP)
|
||||||
|
$(CXXC) -c -o $@ $(TEST_CXXFLAGS) $(srcdir)/archive/ziptest.cpp
|
||||||
|
|
||||||
test_arrays.o: $(srcdir)/arrays/arrays.cpp $(TEST_ODEP)
|
test_arrays.o: $(srcdir)/arrays/arrays.cpp $(TEST_ODEP)
|
||||||
$(CXXC) -c -o $@ $(TEST_CXXFLAGS) $(srcdir)/arrays/arrays.cpp
|
$(CXXC) -c -o $@ $(TEST_CXXFLAGS) $(srcdir)/arrays/arrays.cpp
|
||||||
|
|
||||||
|
@@ -17,9 +17,7 @@
|
|||||||
# include "wx/wx.h"
|
# include "wx/wx.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if wxUSE_STREAMS
|
#if wxUSE_STREAMS && wxUSE_ARCSTREAM
|
||||||
|
|
||||||
#define WX_TEST_ARCHIVE_ITERATOR
|
|
||||||
|
|
||||||
// VC++ 6 warns that the list iterator's '->' operator will not work whenever
|
// VC++ 6 warns that the list iterator's '->' operator will not work whenever
|
||||||
// std::list is used with a non-pointer, so switch it off.
|
// std::list is used with a non-pointer, so switch it off.
|
||||||
@@ -27,9 +25,7 @@
|
|||||||
#pragma warning (disable:4284)
|
#pragma warning (disable:4284)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "wx/zipstrm.h"
|
#include "archivetest.h"
|
||||||
#include "wx/mstream.h"
|
|
||||||
#include "wx/wfstream.h"
|
|
||||||
#include "wx/dir.h"
|
#include "wx/dir.h"
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <list>
|
#include <list>
|
||||||
@@ -66,74 +62,9 @@ using std::auto_ptr;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Bit flags for options for the tests
|
|
||||||
|
|
||||||
enum Options
|
|
||||||
{
|
|
||||||
PipeIn = 0x01, // input streams are non-seekable
|
|
||||||
PipeOut = 0x02, // output streams are non-seekable
|
|
||||||
Stub = 0x04, // the archive should be appended to a stub
|
|
||||||
AllOptions = 0x07
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
// These structs are passed as the template parameter of the test case to
|
|
||||||
// specify a set of classes to use in the test. This allows either the generic
|
|
||||||
// wxArchiveXXX interface to be exercised or the specific interface for a
|
|
||||||
// particular archive format e.g. wxZipXXX.
|
|
||||||
|
|
||||||
struct ArchiveClasses
|
|
||||||
{
|
|
||||||
typedef wxArchiveEntry EntryT;
|
|
||||||
typedef wxArchiveInputStream InputStreamT;
|
|
||||||
typedef wxArchiveOutputStream OutputStreamT;
|
|
||||||
typedef wxArchiveClassFactory ClassFactoryT;
|
|
||||||
typedef wxArchiveNotifier NotifierT;
|
|
||||||
typedef wxArchiveIter IterT;
|
|
||||||
typedef wxArchivePairIter PairIterT;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ZipClasses
|
|
||||||
{
|
|
||||||
typedef wxZipEntry EntryT;
|
|
||||||
typedef wxZipInputStream InputStreamT;
|
|
||||||
typedef wxZipOutputStream OutputStreamT;
|
|
||||||
typedef wxZipClassFactory ClassFactoryT;
|
|
||||||
typedef wxZipNotifier NotifierT;
|
|
||||||
typedef wxZipIter IterT;
|
|
||||||
typedef wxZipPairIter PairIterT;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
// A class to hold a test entry
|
// A class to hold a test entry
|
||||||
|
|
||||||
class TestEntry
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
TestEntry(const wxDateTime& dt, int len, const char *data);
|
|
||||||
~TestEntry() { delete [] m_data; }
|
|
||||||
|
|
||||||
wxDateTime GetDateTime() const { return m_dt; }
|
|
||||||
wxFileOffset GetLength() const { return m_len; }
|
|
||||||
size_t GetSize() const { return m_len; }
|
|
||||||
const char *GetData() const { return m_data; }
|
|
||||||
wxString GetComment() const { return m_comment; }
|
|
||||||
bool IsText() const { return m_isText; }
|
|
||||||
|
|
||||||
void SetComment(const wxString& comment) { m_comment = comment; }
|
|
||||||
void SetDateTime(const wxDateTime& dt) { m_dt = dt; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
wxDateTime m_dt;
|
|
||||||
size_t m_len;
|
|
||||||
char *m_data;
|
|
||||||
wxString m_comment;
|
|
||||||
bool m_isText;
|
|
||||||
};
|
|
||||||
|
|
||||||
TestEntry::TestEntry(const wxDateTime& dt, int len, const char *data)
|
TestEntry::TestEntry(const wxDateTime& dt, int len, const char *data)
|
||||||
: m_dt(dt),
|
: m_dt(dt),
|
||||||
m_len(len),
|
m_len(len),
|
||||||
@@ -151,34 +82,9 @@ TestEntry::TestEntry(const wxDateTime& dt, int len, const char *data)
|
|||||||
// TestOutputStream and TestInputStream are memory streams which can be
|
// TestOutputStream and TestInputStream are memory streams which can be
|
||||||
// seekable or non-seekable.
|
// seekable or non-seekable.
|
||||||
|
|
||||||
class TestOutputStream : public wxOutputStream
|
const size_t STUB_SIZE = 2048;
|
||||||
{
|
const size_t INITIAL_SIZE = 0x18000;
|
||||||
public:
|
const wxFileOffset SEEK_LIMIT = 0x100000;
|
||||||
TestOutputStream(int options);
|
|
||||||
|
|
||||||
~TestOutputStream() { delete [] m_data; }
|
|
||||||
|
|
||||||
int GetOptions() const { return m_options; }
|
|
||||||
wxFileOffset GetLength() const { return m_size; }
|
|
||||||
|
|
||||||
// gives away the data, this stream is then empty, and can be reused
|
|
||||||
void GetData(char*& data, size_t& size);
|
|
||||||
|
|
||||||
enum { STUB_SIZE = 2048, INITIAL_SIZE = 0x18000, SEEK_LIMIT = 0x100000 };
|
|
||||||
|
|
||||||
private:
|
|
||||||
void Init();
|
|
||||||
|
|
||||||
wxFileOffset OnSysSeek(wxFileOffset pos, wxSeekMode mode);
|
|
||||||
wxFileOffset OnSysTell() const;
|
|
||||||
size_t OnSysWrite(const void *buffer, size_t size);
|
|
||||||
|
|
||||||
int m_options;
|
|
||||||
size_t m_pos;
|
|
||||||
size_t m_capacity;
|
|
||||||
size_t m_size;
|
|
||||||
char *m_data;
|
|
||||||
};
|
|
||||||
|
|
||||||
TestOutputStream::TestOutputStream(int options)
|
TestOutputStream::TestOutputStream(int options)
|
||||||
: m_options(options)
|
: m_options(options)
|
||||||
@@ -231,7 +137,7 @@ size_t TestOutputStream::OnSysWrite(const void *buffer, size_t size)
|
|||||||
wxCHECK(newsize > m_pos, 0);
|
wxCHECK(newsize > m_pos, 0);
|
||||||
|
|
||||||
if (m_capacity < newsize) {
|
if (m_capacity < newsize) {
|
||||||
size_t capacity = m_capacity ? m_capacity : (size_t)INITIAL_SIZE;
|
size_t capacity = m_capacity ? m_capacity : INITIAL_SIZE;
|
||||||
|
|
||||||
while (capacity < newsize) {
|
while (capacity < newsize) {
|
||||||
capacity <<= 1;
|
capacity <<= 1;
|
||||||
@@ -281,29 +187,10 @@ void TestOutputStream::GetData(char*& data, size_t& size)
|
|||||||
Reset();
|
Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
class TestInputStream : public wxInputStream
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
// ctor takes the data from the output stream, which is then empty
|
|
||||||
TestInputStream(TestOutputStream& out) : m_data(NULL) { SetData(out); }
|
|
||||||
// this ctor 'dups'
|
|
||||||
TestInputStream(const TestInputStream& in);
|
|
||||||
~TestInputStream() { delete [] m_data; }
|
|
||||||
|
|
||||||
void Rewind();
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
wxFileOffset GetLength() const { return m_size; }
|
// TestOutputStream and TestInputStream are memory streams which can be
|
||||||
void SetData(TestOutputStream& out);
|
// seekable or non-seekable.
|
||||||
|
|
||||||
private:
|
|
||||||
wxFileOffset OnSysSeek(wxFileOffset pos, wxSeekMode mode);
|
|
||||||
wxFileOffset OnSysTell() const;
|
|
||||||
size_t OnSysRead(void *buffer, size_t size);
|
|
||||||
|
|
||||||
int m_options;
|
|
||||||
size_t m_pos;
|
|
||||||
size_t m_size;
|
|
||||||
char *m_data;
|
|
||||||
};
|
|
||||||
|
|
||||||
TestInputStream::TestInputStream(const TestInputStream& in)
|
TestInputStream::TestInputStream(const TestInputStream& in)
|
||||||
: wxInputStream(),
|
: wxInputStream(),
|
||||||
@@ -318,7 +205,7 @@ TestInputStream::TestInputStream(const TestInputStream& in)
|
|||||||
void TestInputStream::Rewind()
|
void TestInputStream::Rewind()
|
||||||
{
|
{
|
||||||
if ((m_options & Stub) && (m_options & PipeIn))
|
if ((m_options & Stub) && (m_options & PipeIn))
|
||||||
m_pos = TestOutputStream::STUB_SIZE * 2;
|
m_pos = STUB_SIZE * 2;
|
||||||
else
|
else
|
||||||
m_pos = 0;
|
m_pos = 0;
|
||||||
|
|
||||||
@@ -347,7 +234,7 @@ wxFileOffset TestInputStream::OnSysSeek(wxFileOffset pos, wxSeekMode mode)
|
|||||||
case wxFromCurrent: pos += m_pos; break;
|
case wxFromCurrent: pos += m_pos; break;
|
||||||
case wxFromEnd: pos += m_size; break;
|
case wxFromEnd: pos += m_size; break;
|
||||||
}
|
}
|
||||||
if (pos < 0 || pos > TestOutputStream::SEEK_LIMIT)
|
if (pos < 0 || pos > SEEK_LIMIT)
|
||||||
return wxInvalidOffset;
|
return wxInvalidOffset;
|
||||||
m_pos = (size_t)pos;
|
m_pos = (size_t)pos;
|
||||||
return m_pos;
|
return m_pos;
|
||||||
@@ -510,126 +397,43 @@ void TempDir::RemoveDir(wxString& path)
|
|||||||
# define WXARC_b
|
# define WXARC_b
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
class PFileInputStream : public wxFFileInputStream
|
PFileInputStream::PFileInputStream(const wxString& cmd)
|
||||||
|
: wxFFileInputStream(WXARC_popen(cmd.mb_str(), "r" WXARC_b))
|
||||||
{
|
{
|
||||||
public:
|
}
|
||||||
PFileInputStream(const wxString& cmd) :
|
|
||||||
wxFFileInputStream(WXARC_popen(cmd.mb_str(), "r" WXARC_b)) { }
|
|
||||||
~PFileInputStream()
|
|
||||||
{ WXARC_pclose(m_file->fp()); m_file->Detach(); }
|
|
||||||
};
|
|
||||||
|
|
||||||
class PFileOutputStream : public wxFFileOutputStream
|
PFileInputStream::~PFileInputStream()
|
||||||
{
|
{
|
||||||
public:
|
WXARC_pclose(m_file->fp()); m_file->Detach();
|
||||||
PFileOutputStream(const wxString& cmd) :
|
}
|
||||||
wxFFileOutputStream(WXARC_popen(cmd.mb_str(), "w" WXARC_b)) { }
|
|
||||||
~PFileOutputStream()
|
PFileOutputStream::PFileOutputStream(const wxString& cmd)
|
||||||
{ WXARC_pclose(m_file->fp()); m_file->Detach(); }
|
: wxFFileOutputStream(WXARC_popen(cmd.mb_str(), "w" WXARC_b))
|
||||||
};
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
PFileOutputStream::~PFileOutputStream()
|
||||||
|
{
|
||||||
|
WXARC_pclose(m_file->fp()); m_file->Detach();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
// The test case
|
// The test case
|
||||||
|
|
||||||
template <class Classes>
|
template <class ClassFactoryT>
|
||||||
class ArchiveTestCase : public CppUnit::TestCase
|
ArchiveTestCase<ClassFactoryT>::ArchiveTestCase(
|
||||||
{
|
|
||||||
public:
|
|
||||||
ArchiveTestCase(string name,
|
|
||||||
int id,
|
|
||||||
wxArchiveClassFactory *factory,
|
|
||||||
int options,
|
|
||||||
const wxString& archiver = wxEmptyString,
|
|
||||||
const wxString& unarchiver = wxEmptyString);
|
|
||||||
|
|
||||||
~ArchiveTestCase();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
// the classes to test
|
|
||||||
typedef typename Classes::EntryT EntryT;
|
|
||||||
typedef typename Classes::InputStreamT InputStreamT;
|
|
||||||
typedef typename Classes::OutputStreamT OutputStreamT;
|
|
||||||
typedef typename Classes::ClassFactoryT ClassFactoryT;
|
|
||||||
typedef typename Classes::NotifierT NotifierT;
|
|
||||||
typedef typename Classes::IterT IterT;
|
|
||||||
typedef typename Classes::PairIterT PairIterT;
|
|
||||||
|
|
||||||
// the entry point for the test
|
|
||||||
void runTest();
|
|
||||||
|
|
||||||
// create the test data
|
|
||||||
void CreateTestData();
|
|
||||||
TestEntry& Add(const char *name, const char *data, int len = -1);
|
|
||||||
TestEntry& Add(const char *name, int len = 0, int value = EOF);
|
|
||||||
|
|
||||||
// 'archive up' the test data
|
|
||||||
void CreateArchive(wxOutputStream& out);
|
|
||||||
void CreateArchive(wxOutputStream& out, const wxString& archiver);
|
|
||||||
|
|
||||||
// perform various modifications on the archive
|
|
||||||
void ModifyArchive(wxInputStream& in, wxOutputStream& out);
|
|
||||||
|
|
||||||
// extract the archive and verify its contents
|
|
||||||
void ExtractArchive(wxInputStream& in);
|
|
||||||
void ExtractArchive(wxInputStream& in, const wxString& unarchiver);
|
|
||||||
void VerifyDir(wxString& path, size_t rootlen = 0);
|
|
||||||
|
|
||||||
// tests for the iterators
|
|
||||||
void TestIterator(wxInputStream& in);
|
|
||||||
void TestPairIterator(wxInputStream& in);
|
|
||||||
void TestSmartIterator(wxInputStream& in);
|
|
||||||
void TestSmartPairIterator(wxInputStream& in);
|
|
||||||
|
|
||||||
// try reading two entries at the same time
|
|
||||||
void ReadSimultaneous(TestInputStream& in);
|
|
||||||
|
|
||||||
// overridables
|
|
||||||
virtual void OnCreateArchive(OutputStreamT& WXUNUSED(arc)) { }
|
|
||||||
virtual void OnSetNotifier(EntryT& entry);
|
|
||||||
|
|
||||||
virtual void OnArchiveExtracted(InputStreamT& WXUNUSED(arc),
|
|
||||||
int WXUNUSED(expectedTotal)) { }
|
|
||||||
|
|
||||||
virtual void OnCreateEntry( OutputStreamT& WXUNUSED(arc),
|
|
||||||
TestEntry& WXUNUSED(testEntry),
|
|
||||||
EntryT *entry = NULL) { (void)entry; }
|
|
||||||
|
|
||||||
virtual void OnEntryExtracted( EntryT& WXUNUSED(entry),
|
|
||||||
const TestEntry& WXUNUSED(testEntry),
|
|
||||||
InputStreamT *arc = NULL) { (void)arc; }
|
|
||||||
|
|
||||||
typedef std::map<wxString, TestEntry*> TestEntries;
|
|
||||||
TestEntries m_testEntries; // test data
|
|
||||||
auto_ptr<ClassFactoryT> m_factory; // factory to make classes
|
|
||||||
int m_options; // test options
|
|
||||||
wxDateTime m_timeStamp; // timestamp to give test entries
|
|
||||||
int m_id; // select between the possibilites
|
|
||||||
wxString m_archiver; // external archiver
|
|
||||||
wxString m_unarchiver; // external unarchiver
|
|
||||||
};
|
|
||||||
|
|
||||||
// Constructor
|
|
||||||
// The only way I could get this to compile on VC++ 5.0 was to pass 'factory'
|
|
||||||
// as a wxArchiveFactory* then cast it, even then only with some ifdefing.
|
|
||||||
//
|
|
||||||
template <class Classes>
|
|
||||||
ArchiveTestCase<Classes>::ArchiveTestCase(
|
|
||||||
string name,
|
string name,
|
||||||
int id,
|
int id,
|
||||||
wxArchiveClassFactory *factory,
|
ClassFactoryT *factory,
|
||||||
int options,
|
int options,
|
||||||
const wxString& archiver,
|
const wxString& archiver,
|
||||||
const wxString& unarchiver)
|
const wxString& unarchiver)
|
||||||
:
|
:
|
||||||
CppUnit::TestCase(name),
|
CppUnit::TestCase(name),
|
||||||
#if defined _MSC_VER && _MSC_VER < 1300
|
m_factory(factory),
|
||||||
m_factory(dynamic_cast<Classes::ClassFactoryT*>(factory)),
|
|
||||||
#else
|
|
||||||
m_factory(dynamic_cast<typename Classes::ClassFactoryT*>(factory)),
|
|
||||||
#endif
|
|
||||||
m_options(options),
|
m_options(options),
|
||||||
m_timeStamp(1, wxDateTime::Mar, 2005, 12, 0),
|
m_timeStamp(1, wxDateTime::Mar, 2004, 12, 0),
|
||||||
m_id(id),
|
m_id(id),
|
||||||
m_archiver(archiver),
|
m_archiver(archiver),
|
||||||
m_unarchiver(unarchiver)
|
m_unarchiver(unarchiver)
|
||||||
@@ -637,16 +441,16 @@ ArchiveTestCase<Classes>::ArchiveTestCase(
|
|||||||
wxASSERT(m_factory.get() != NULL);
|
wxASSERT(m_factory.get() != NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Classes>
|
template <class ClassFactoryT>
|
||||||
ArchiveTestCase<Classes>::~ArchiveTestCase()
|
ArchiveTestCase<ClassFactoryT>::~ArchiveTestCase()
|
||||||
{
|
{
|
||||||
TestEntries::iterator it;
|
TestEntries::iterator it;
|
||||||
for (it = m_testEntries.begin(); it != m_testEntries.end(); ++it)
|
for (it = m_testEntries.begin(); it != m_testEntries.end(); ++it)
|
||||||
delete it->second;
|
delete it->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Classes>
|
template <class ClassFactoryT>
|
||||||
void ArchiveTestCase<Classes>::runTest()
|
void ArchiveTestCase<ClassFactoryT>::runTest()
|
||||||
{
|
{
|
||||||
TestOutputStream out(m_options);
|
TestOutputStream out(m_options);
|
||||||
|
|
||||||
@@ -688,8 +492,8 @@ void ArchiveTestCase<Classes>::runTest()
|
|||||||
CPPUNIT_ASSERT(m_testEntries.empty());
|
CPPUNIT_ASSERT(m_testEntries.empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Classes>
|
template <class ClassFactoryT>
|
||||||
void ArchiveTestCase<Classes>::CreateTestData()
|
void ArchiveTestCase<ClassFactoryT>::CreateTestData()
|
||||||
{
|
{
|
||||||
Add("text/");
|
Add("text/");
|
||||||
Add("text/empty", "");
|
Add("text/empty", "");
|
||||||
@@ -712,8 +516,8 @@ void ArchiveTestCase<Classes>::CreateTestData()
|
|||||||
Add("empty/");
|
Add("empty/");
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Classes>
|
template <class ClassFactoryT>
|
||||||
TestEntry& ArchiveTestCase<Classes>::Add(const char *name,
|
TestEntry& ArchiveTestCase<ClassFactoryT>::Add(const char *name,
|
||||||
const char *data,
|
const char *data,
|
||||||
int len /*=-1*/)
|
int len /*=-1*/)
|
||||||
{
|
{
|
||||||
@@ -726,8 +530,8 @@ TestEntry& ArchiveTestCase<Classes>::Add(const char *name,
|
|||||||
return *entry;
|
return *entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Classes>
|
template <class ClassFactoryT>
|
||||||
TestEntry& ArchiveTestCase<Classes>::Add(const char *name,
|
TestEntry& ArchiveTestCase<ClassFactoryT>::Add(const char *name,
|
||||||
int len /*=0*/,
|
int len /*=0*/,
|
||||||
int value /*=EOF*/)
|
int value /*=EOF*/)
|
||||||
{
|
{
|
||||||
@@ -739,8 +543,8 @@ TestEntry& ArchiveTestCase<Classes>::Add(const char *name,
|
|||||||
|
|
||||||
// Create an archive using the wx archive classes, write it to 'out'
|
// Create an archive using the wx archive classes, write it to 'out'
|
||||||
//
|
//
|
||||||
template <class Classes>
|
template <class ClassFactoryT>
|
||||||
void ArchiveTestCase<Classes>::CreateArchive(wxOutputStream& out)
|
void ArchiveTestCase<ClassFactoryT>::CreateArchive(wxOutputStream& out)
|
||||||
{
|
{
|
||||||
auto_ptr<OutputStreamT> arc(m_factory->NewStream(out));
|
auto_ptr<OutputStreamT> arc(m_factory->NewStream(out));
|
||||||
TestEntries::iterator it;
|
TestEntries::iterator it;
|
||||||
@@ -792,7 +596,7 @@ void ArchiveTestCase<Classes>::CreateArchive(wxOutputStream& out)
|
|||||||
testEntry.GetLength()));
|
testEntry.GetLength()));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (name.Last() != _T('/')) {
|
if (it->first.Last() != _T('/')) {
|
||||||
// for non-dirs write the data
|
// for non-dirs write the data
|
||||||
arc->Write(testEntry.GetData(), testEntry.GetSize());
|
arc->Write(testEntry.GetData(), testEntry.GetSize());
|
||||||
CPPUNIT_ASSERT_MESSAGE("LastWrite check" + error_context,
|
CPPUNIT_ASSERT_MESSAGE("LastWrite check" + error_context,
|
||||||
@@ -813,8 +617,8 @@ void ArchiveTestCase<Classes>::CreateArchive(wxOutputStream& out)
|
|||||||
|
|
||||||
// Create an archive using an external archive program
|
// Create an archive using an external archive program
|
||||||
//
|
//
|
||||||
template <class Classes>
|
template <class ClassFactoryT>
|
||||||
void ArchiveTestCase<Classes>::CreateArchive(wxOutputStream& out,
|
void ArchiveTestCase<ClassFactoryT>::CreateArchive(wxOutputStream& out,
|
||||||
const wxString& archiver)
|
const wxString& archiver)
|
||||||
{
|
{
|
||||||
// for an external archiver the test data need to be written to
|
// for an external archiver the test data need to be written to
|
||||||
@@ -851,7 +655,7 @@ void ArchiveTestCase<Classes>::CreateArchive(wxOutputStream& out,
|
|||||||
if ((m_options & PipeOut) == 0) {
|
if ((m_options & PipeOut) == 0) {
|
||||||
wxFileName fn(tmpdir.GetName());
|
wxFileName fn(tmpdir.GetName());
|
||||||
fn.SetExt(_T("arc"));
|
fn.SetExt(_T("arc"));
|
||||||
wxString tmparc = fn.GetFullPath();
|
wxString tmparc = fn.GetPath(wxPATH_GET_SEPARATOR) + fn.GetFullName();
|
||||||
|
|
||||||
// call the archiver to create an archive file
|
// call the archiver to create an archive file
|
||||||
system(wxString::Format(archiver, tmparc.c_str()).mb_str());
|
system(wxString::Format(archiver, tmparc.c_str()).mb_str());
|
||||||
@@ -877,8 +681,8 @@ void ArchiveTestCase<Classes>::CreateArchive(wxOutputStream& out,
|
|||||||
// Do a standard set of modification on an archive, delete an entry,
|
// Do a standard set of modification on an archive, delete an entry,
|
||||||
// rename an entry and add an entry
|
// rename an entry and add an entry
|
||||||
//
|
//
|
||||||
template <class Classes>
|
template <class ClassFactoryT>
|
||||||
void ArchiveTestCase<Classes>::ModifyArchive(wxInputStream& in,
|
void ArchiveTestCase<ClassFactoryT>::ModifyArchive(wxInputStream& in,
|
||||||
wxOutputStream& out)
|
wxOutputStream& out)
|
||||||
{
|
{
|
||||||
auto_ptr<InputStreamT> arcIn(m_factory->NewStream(in));
|
auto_ptr<InputStreamT> arcIn(m_factory->NewStream(in));
|
||||||
@@ -955,8 +759,8 @@ void ArchiveTestCase<Classes>::ModifyArchive(wxInputStream& in,
|
|||||||
|
|
||||||
// Extract an archive using the wx archive classes
|
// Extract an archive using the wx archive classes
|
||||||
//
|
//
|
||||||
template <class Classes>
|
template <class ClassFactoryT>
|
||||||
void ArchiveTestCase<Classes>::ExtractArchive(wxInputStream& in)
|
void ArchiveTestCase<ClassFactoryT>::ExtractArchive(wxInputStream& in)
|
||||||
{
|
{
|
||||||
typedef Ptr<EntryT> EntryPtr;
|
typedef Ptr<EntryT> EntryPtr;
|
||||||
typedef std::list<EntryPtr> Entries;
|
typedef std::list<EntryPtr> Entries;
|
||||||
@@ -1050,8 +854,8 @@ void ArchiveTestCase<Classes>::ExtractArchive(wxInputStream& in)
|
|||||||
|
|
||||||
// Extract an archive using an external unarchive program
|
// Extract an archive using an external unarchive program
|
||||||
//
|
//
|
||||||
template <class Classes>
|
template <class ClassFactoryT>
|
||||||
void ArchiveTestCase<Classes>::ExtractArchive(wxInputStream& in,
|
void ArchiveTestCase<ClassFactoryT>::ExtractArchive(wxInputStream& in,
|
||||||
const wxString& unarchiver)
|
const wxString& unarchiver)
|
||||||
{
|
{
|
||||||
// for an external unarchiver, unarchive to a tempdir
|
// for an external unarchiver, unarchive to a tempdir
|
||||||
@@ -1060,10 +864,10 @@ void ArchiveTestCase<Classes>::ExtractArchive(wxInputStream& in,
|
|||||||
if ((m_options & PipeIn) == 0) {
|
if ((m_options & PipeIn) == 0) {
|
||||||
wxFileName fn(tmpdir.GetName());
|
wxFileName fn(tmpdir.GetName());
|
||||||
fn.SetExt(_T("arc"));
|
fn.SetExt(_T("arc"));
|
||||||
wxString tmparc = fn.GetFullPath();
|
wxString tmparc = fn.GetPath(wxPATH_GET_SEPARATOR) + fn.GetFullName();
|
||||||
|
|
||||||
if (m_options & Stub)
|
if (m_options & Stub)
|
||||||
in.SeekI(TestOutputStream::STUB_SIZE * 2);
|
in.SeekI(STUB_SIZE * 2);
|
||||||
|
|
||||||
// write the archive to a temporary file
|
// write the archive to a temporary file
|
||||||
{
|
{
|
||||||
@@ -1090,8 +894,9 @@ void ArchiveTestCase<Classes>::ExtractArchive(wxInputStream& in,
|
|||||||
|
|
||||||
// Verifies the files produced by an external unarchiver are as expected
|
// Verifies the files produced by an external unarchiver are as expected
|
||||||
//
|
//
|
||||||
template <class Classes>
|
template <class ClassFactoryT>
|
||||||
void ArchiveTestCase<Classes>::VerifyDir(wxString& path, size_t rootlen /*=0*/)
|
void ArchiveTestCase<ClassFactoryT>::VerifyDir(wxString& path,
|
||||||
|
size_t rootlen /*=0*/)
|
||||||
{
|
{
|
||||||
wxDir dir;
|
wxDir dir;
|
||||||
path += wxFileName::GetPathSeparator();
|
path += wxFileName::GetPathSeparator();
|
||||||
@@ -1156,8 +961,8 @@ void ArchiveTestCase<Classes>::VerifyDir(wxString& path, size_t rootlen /*=0*/)
|
|||||||
|
|
||||||
// test the simple iterators that give away ownership of an entry
|
// test the simple iterators that give away ownership of an entry
|
||||||
//
|
//
|
||||||
template <class Classes>
|
template <class ClassFactoryT>
|
||||||
void ArchiveTestCase<Classes>::TestIterator(wxInputStream& in)
|
void ArchiveTestCase<ClassFactoryT>::TestIterator(wxInputStream& in)
|
||||||
{
|
{
|
||||||
typedef std::list<EntryT*> ArchiveCatalog;
|
typedef std::list<EntryT*> ArchiveCatalog;
|
||||||
typedef typename ArchiveCatalog::iterator CatalogIter;
|
typedef typename ArchiveCatalog::iterator CatalogIter;
|
||||||
@@ -1185,8 +990,8 @@ void ArchiveTestCase<Classes>::TestIterator(wxInputStream& in)
|
|||||||
// test the pair iterators that can be used to load a std::map or wxHashMap
|
// test the pair iterators that can be used to load a std::map or wxHashMap
|
||||||
// these also give away ownership of entries
|
// these also give away ownership of entries
|
||||||
//
|
//
|
||||||
template <class Classes>
|
template <class ClassFactoryT>
|
||||||
void ArchiveTestCase<Classes>::TestPairIterator(wxInputStream& in)
|
void ArchiveTestCase<ClassFactoryT>::TestPairIterator(wxInputStream& in)
|
||||||
{
|
{
|
||||||
typedef std::map<wxString, EntryT*> ArchiveCatalog;
|
typedef std::map<wxString, EntryT*> ArchiveCatalog;
|
||||||
typedef typename ArchiveCatalog::iterator CatalogIter;
|
typedef typename ArchiveCatalog::iterator CatalogIter;
|
||||||
@@ -1213,8 +1018,8 @@ void ArchiveTestCase<Classes>::TestPairIterator(wxInputStream& in)
|
|||||||
|
|
||||||
// simple iterators using smart pointers, no need to worry about ownership
|
// simple iterators using smart pointers, no need to worry about ownership
|
||||||
//
|
//
|
||||||
template <class Classes>
|
template <class ClassFactoryT>
|
||||||
void ArchiveTestCase<Classes>::TestSmartIterator(wxInputStream& in)
|
void ArchiveTestCase<ClassFactoryT>::TestSmartIterator(wxInputStream& in)
|
||||||
{
|
{
|
||||||
typedef std::list<Ptr<EntryT> > ArchiveCatalog;
|
typedef std::list<Ptr<EntryT> > ArchiveCatalog;
|
||||||
typedef typename ArchiveCatalog::iterator CatalogIter;
|
typedef typename ArchiveCatalog::iterator CatalogIter;
|
||||||
@@ -1238,8 +1043,8 @@ void ArchiveTestCase<Classes>::TestSmartIterator(wxInputStream& in)
|
|||||||
|
|
||||||
// pair iterator using smart pointers
|
// pair iterator using smart pointers
|
||||||
//
|
//
|
||||||
template <class Classes>
|
template <class ClassFactoryT>
|
||||||
void ArchiveTestCase<Classes>::TestSmartPairIterator(wxInputStream& in)
|
void ArchiveTestCase<ClassFactoryT>::TestSmartPairIterator(wxInputStream& in)
|
||||||
{
|
{
|
||||||
#if defined _MSC_VER && defined _MSC_VER < 1200
|
#if defined _MSC_VER && defined _MSC_VER < 1200
|
||||||
// With VC++ 5.0 the '=' operator of std::pair breaks when the second
|
// With VC++ 5.0 the '=' operator of std::pair breaks when the second
|
||||||
@@ -1270,8 +1075,8 @@ void ArchiveTestCase<Classes>::TestSmartPairIterator(wxInputStream& in)
|
|||||||
|
|
||||||
// try reading two entries at the same time
|
// try reading two entries at the same time
|
||||||
//
|
//
|
||||||
template <class Classes>
|
template <class ClassFactoryT>
|
||||||
void ArchiveTestCase<Classes>::ReadSimultaneous(TestInputStream& in)
|
void ArchiveTestCase<ClassFactoryT>::ReadSimultaneous(TestInputStream& in)
|
||||||
{
|
{
|
||||||
typedef std::map<wxString, Ptr<EntryT> > ArchiveCatalog;
|
typedef std::map<wxString, Ptr<EntryT> > ArchiveCatalog;
|
||||||
typedef wxArchiveIterator<InputStreamT,
|
typedef wxArchiveIterator<InputStreamT,
|
||||||
@@ -1343,8 +1148,8 @@ public:
|
|||||||
void OnEntryUpdated(EntryT& WXUNUSED(entry)) { }
|
void OnEntryUpdated(EntryT& WXUNUSED(entry)) { }
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class Classes>
|
template <class ClassFactoryT>
|
||||||
void ArchiveTestCase<Classes>::OnSetNotifier(EntryT& entry)
|
void ArchiveTestCase<ClassFactoryT>::OnSetNotifier(EntryT& entry)
|
||||||
{
|
{
|
||||||
static ArchiveNotifier<NotifierT, EntryT> notifier;
|
static ArchiveNotifier<NotifierT, EntryT> notifier;
|
||||||
entry.SetNotifier(notifier);
|
entry.SetNotifier(notifier);
|
||||||
@@ -1352,211 +1157,17 @@ void ArchiveTestCase<Classes>::OnSetNotifier(EntryT& entry)
|
|||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
// ArchiveTestCase<ZipClasses> could be used directly, but instead this
|
// Suite base
|
||||||
// derived class is used so that zip specific features can be tested.
|
|
||||||
|
|
||||||
class ZipTestCase : public ArchiveTestCase<ZipClasses>
|
ArchiveTestSuite::ArchiveTestSuite(string name)
|
||||||
{
|
: CppUnit::TestSuite("archive/" + name),
|
||||||
public:
|
m_id(0),
|
||||||
ZipTestCase(string name,
|
m_name(name.c_str(), *wxConvCurrent)
|
||||||
int id,
|
|
||||||
int options,
|
|
||||||
const wxString& archiver = wxEmptyString,
|
|
||||||
const wxString& unarchiver = wxEmptyString)
|
|
||||||
:
|
|
||||||
ArchiveTestCase<ZipClasses>(name, id, new wxZipClassFactory,
|
|
||||||
options, archiver, unarchiver),
|
|
||||||
m_count(0)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void OnCreateArchive(wxZipOutputStream& zip);
|
|
||||||
|
|
||||||
void OnArchiveExtracted(wxZipInputStream& zip, int expectedTotal);
|
|
||||||
|
|
||||||
void OnCreateEntry(wxZipOutputStream& zip,
|
|
||||||
TestEntry& testEntry,
|
|
||||||
wxZipEntry *entry);
|
|
||||||
|
|
||||||
void OnEntryExtracted(wxZipEntry& entry,
|
|
||||||
const TestEntry& testEntry,
|
|
||||||
wxZipInputStream *arc);
|
|
||||||
|
|
||||||
void OnSetNotifier(EntryT& entry);
|
|
||||||
|
|
||||||
int m_count;
|
|
||||||
wxString m_comment;
|
|
||||||
};
|
|
||||||
|
|
||||||
void ZipTestCase::OnCreateArchive(wxZipOutputStream& zip)
|
|
||||||
{
|
|
||||||
m_comment << _T("Comment for test ") << m_id;
|
|
||||||
zip.SetComment(m_comment);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ZipTestCase::OnArchiveExtracted(wxZipInputStream& zip, int expectedTotal)
|
|
||||||
{
|
|
||||||
CPPUNIT_ASSERT(zip.GetComment() == m_comment);
|
|
||||||
CPPUNIT_ASSERT(zip.GetTotalEntries() == expectedTotal);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ZipTestCase::OnCreateEntry(wxZipOutputStream& zip,
|
|
||||||
TestEntry& testEntry,
|
|
||||||
wxZipEntry *entry)
|
|
||||||
{
|
|
||||||
zip.SetLevel((m_id + m_count) % 10);
|
|
||||||
|
|
||||||
if (entry) {
|
|
||||||
switch ((m_id + m_count) % 5) {
|
|
||||||
case 0:
|
|
||||||
{
|
|
||||||
wxString comment = _T("Comment for ") + entry->GetName();
|
|
||||||
entry->SetComment(comment);
|
|
||||||
// lowercase the expected result, and the notifier should do
|
|
||||||
// the same for the zip entries when ModifyArchive() runs
|
|
||||||
testEntry.SetComment(comment.Lower());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 2:
|
|
||||||
entry->SetMethod(wxZIP_METHOD_STORE);
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
entry->SetMethod(wxZIP_METHOD_DEFLATE);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
entry->SetIsText(testEntry.IsText());
|
|
||||||
}
|
|
||||||
|
|
||||||
m_count++;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ZipTestCase::OnEntryExtracted(wxZipEntry& entry,
|
|
||||||
const TestEntry& testEntry,
|
|
||||||
wxZipInputStream *arc)
|
|
||||||
{
|
|
||||||
// provide some context for the error message so that we know which
|
|
||||||
// iteration of the loop we were on
|
|
||||||
wxString name = _T(" '") + entry.GetName() + _T("'");
|
|
||||||
string error_entry(name.mb_str());
|
|
||||||
string error_context(" failed for entry" + error_entry);
|
|
||||||
|
|
||||||
CPPUNIT_ASSERT_MESSAGE("GetComment" + error_context,
|
|
||||||
entry.GetComment() == testEntry.GetComment());
|
|
||||||
|
|
||||||
// for seekable streams, GetNextEntry() doesn't read the local header so
|
|
||||||
// call OpenEntry() to do it
|
|
||||||
if (arc && (m_options & PipeIn) == 0 && entry.IsDir())
|
|
||||||
arc->OpenEntry(entry);
|
|
||||||
|
|
||||||
CPPUNIT_ASSERT_MESSAGE("IsText" + error_context,
|
|
||||||
entry.IsText() == testEntry.IsText());
|
|
||||||
|
|
||||||
CPPUNIT_ASSERT_MESSAGE("Extra/LocalExtra mismatch for entry" + error_entry,
|
|
||||||
(entry.GetExtraLen() != 0 && entry.GetLocalExtraLen() != 0) ||
|
|
||||||
(entry.GetExtraLen() == 0 && entry.GetLocalExtraLen() == 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
// check the notifier mechanism by using it to fold the entry comments to
|
|
||||||
// lowercase
|
|
||||||
//
|
|
||||||
class ZipNotifier : public wxZipNotifier
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
void OnEntryUpdated(wxZipEntry& entry);
|
|
||||||
};
|
|
||||||
|
|
||||||
void ZipNotifier::OnEntryUpdated(wxZipEntry& entry)
|
|
||||||
{
|
|
||||||
entry.SetComment(entry.GetComment().Lower());
|
|
||||||
}
|
|
||||||
|
|
||||||
void ZipTestCase::OnSetNotifier(EntryT& entry)
|
|
||||||
{
|
|
||||||
static ZipNotifier notifier;
|
|
||||||
entry.SetNotifier(notifier);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
// 'zip - -' produces local headers without the size field set. This is a
|
|
||||||
// case not covered by all the other tests, so this class tests it as a
|
|
||||||
// special case
|
|
||||||
|
|
||||||
class ZipPipeTestCase : public CppUnit::TestCase
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
ZipPipeTestCase(string name, int options) :
|
|
||||||
CppUnit::TestCase(name), m_options(options) { }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void runTest();
|
|
||||||
int m_options;
|
|
||||||
};
|
|
||||||
|
|
||||||
void ZipPipeTestCase::runTest()
|
|
||||||
{
|
|
||||||
TestOutputStream out(m_options);
|
|
||||||
|
|
||||||
wxString testdata = _T("test data to pipe through zip");
|
|
||||||
wxString cmd = _T("echo ") + testdata + _T(" | zip -q - -");
|
|
||||||
|
|
||||||
{
|
|
||||||
PFileInputStream in(cmd);
|
|
||||||
if (in.Ok())
|
|
||||||
out.Write(in);
|
|
||||||
}
|
|
||||||
|
|
||||||
TestInputStream in(out);
|
|
||||||
wxZipInputStream zip(in);
|
|
||||||
|
|
||||||
auto_ptr<wxZipEntry> entry(zip.GetNextEntry());
|
|
||||||
CPPUNIT_ASSERT(entry.get() != NULL);
|
|
||||||
|
|
||||||
if ((m_options & PipeIn) == 0)
|
|
||||||
CPPUNIT_ASSERT(entry->GetSize() != wxInvalidOffset);
|
|
||||||
|
|
||||||
char buf[64];
|
|
||||||
size_t len = zip.Read(buf, sizeof(buf) - 1).LastRead();
|
|
||||||
|
|
||||||
while (len > 0 && buf[len - 1] <= 32)
|
|
||||||
--len;
|
|
||||||
buf[len] = 0;
|
|
||||||
|
|
||||||
CPPUNIT_ASSERT(zip.Eof());
|
|
||||||
CPPUNIT_ASSERT(wxString(buf, *wxConvCurrent) == testdata);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
// The suite
|
|
||||||
|
|
||||||
class ArchiveTestSuite : public CppUnit::TestSuite
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
ArchiveTestSuite();
|
|
||||||
static CppUnit::Test *suite()
|
|
||||||
{ return (new ArchiveTestSuite)->makeSuite(); }
|
|
||||||
|
|
||||||
private:
|
|
||||||
int m_id;
|
|
||||||
wxPathList m_path;
|
|
||||||
|
|
||||||
ArchiveTestSuite *makeSuite();
|
|
||||||
void AddCmd(wxArrayString& cmdlist, const wxString& cmd);
|
|
||||||
bool IsInPath(const wxString& cmd);
|
|
||||||
|
|
||||||
string Description(const wxString& type,
|
|
||||||
int options,
|
|
||||||
bool genericInterface = false,
|
|
||||||
const wxString& archiver = wxEmptyString,
|
|
||||||
const wxString& unarchiver = wxEmptyString);
|
|
||||||
};
|
|
||||||
|
|
||||||
ArchiveTestSuite::ArchiveTestSuite()
|
|
||||||
: CppUnit::TestSuite("ArchiveTestSuite"),
|
|
||||||
m_id(0)
|
|
||||||
{
|
{
|
||||||
|
m_name = _T("wx") + m_name.Left(1).Upper() + m_name.Mid(1).Lower();
|
||||||
m_path.AddEnvList(_T("PATH"));
|
m_path.AddEnvList(_T("PATH"));
|
||||||
|
m_archivers.push_back(_T(""));
|
||||||
|
m_unarchivers.push_back(_T(""));
|
||||||
}
|
}
|
||||||
|
|
||||||
// add the command for an external archiver to the list, testing for it in
|
// add the command for an external archiver to the list, testing for it in
|
||||||
@@ -1564,8 +1175,6 @@ ArchiveTestSuite::ArchiveTestSuite()
|
|||||||
//
|
//
|
||||||
void ArchiveTestSuite::AddCmd(wxArrayString& cmdlist, const wxString& cmd)
|
void ArchiveTestSuite::AddCmd(wxArrayString& cmdlist, const wxString& cmd)
|
||||||
{
|
{
|
||||||
if (cmdlist.empty())
|
|
||||||
cmdlist.push_back(_T(""));
|
|
||||||
if (IsInPath(cmd))
|
if (IsInPath(cmd))
|
||||||
cmdlist.push_back(cmd);
|
cmdlist.push_back(cmd);
|
||||||
}
|
}
|
||||||
@@ -1584,52 +1193,45 @@ bool ArchiveTestSuite::IsInPath(const wxString& cmd)
|
|||||||
ArchiveTestSuite *ArchiveTestSuite::makeSuite()
|
ArchiveTestSuite *ArchiveTestSuite::makeSuite()
|
||||||
{
|
{
|
||||||
typedef wxArrayString::iterator Iter;
|
typedef wxArrayString::iterator Iter;
|
||||||
wxArrayString zippers;
|
|
||||||
wxArrayString unzippers;
|
|
||||||
|
|
||||||
AddCmd(zippers, _T("zip -qr %s *"));
|
for (int generic = 0; generic < 2; generic++)
|
||||||
AddCmd(unzippers, _T("unzip -q %s"));
|
for (Iter i = m_unarchivers.begin(); i != m_unarchivers.end(); ++i)
|
||||||
|
for (Iter j = m_archivers.begin(); j != m_archivers.end(); ++j)
|
||||||
for (int genInterface = 0; genInterface < 2; genInterface++)
|
|
||||||
for (Iter i = unzippers.begin(); i != unzippers.end(); ++i)
|
|
||||||
for (Iter j = zippers.begin(); j != zippers.end(); ++j)
|
|
||||||
for (int options = 0; options <= AllOptions; options++)
|
for (int options = 0; options <= AllOptions; options++)
|
||||||
{
|
{
|
||||||
// unzip doesn't support piping in the zip
|
#ifdef WXARC_NO_POPEN
|
||||||
|
// if no popen then can't pipe in/out of archiver
|
||||||
if ((options & PipeIn) && !i->empty())
|
if ((options & PipeIn) && !i->empty())
|
||||||
continue;
|
continue;
|
||||||
#ifdef WXARC_NO_POPEN
|
|
||||||
// if no popen then can use piped output of zip
|
|
||||||
if ((options & PipeOut) && !j->empty())
|
if ((options & PipeOut) && !j->empty())
|
||||||
continue;
|
continue;
|
||||||
#endif
|
#endif
|
||||||
string name = Description(_T("wxZip"), options,
|
string descr = Description(m_name, options,
|
||||||
genInterface != 0, *j, *i);
|
generic != 0, *j, *i);
|
||||||
|
|
||||||
if (genInterface)
|
CppUnit::Test *test = makeTest(descr, m_id, options,
|
||||||
addTest(new ArchiveTestCase<ArchiveClasses>(
|
generic != 0, *j, *i);
|
||||||
name, m_id,
|
|
||||||
new wxZipClassFactory,
|
|
||||||
options, *j, *i));
|
|
||||||
else
|
|
||||||
addTest(new ZipTestCase(name, m_id, options, *j, *i));
|
|
||||||
|
|
||||||
|
if (test) {
|
||||||
|
addTest(test);
|
||||||
m_id++;
|
m_id++;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef WXARC_NO_POPEN
|
|
||||||
// if have popen then can check the piped output of 'zip - -'
|
|
||||||
if (IsInPath(_T("zip")))
|
|
||||||
for (int options = 0; options <= PipeIn; options += PipeIn) {
|
|
||||||
string name = Description(_T("ZipPipeTestCase"), options);
|
|
||||||
addTest(new ZipPipeTestCase(name, options));
|
|
||||||
m_id++;
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CppUnit::Test *ArchiveTestSuite::makeTest(
|
||||||
|
string WXUNUSED(descr),
|
||||||
|
int WXUNUSED(id),
|
||||||
|
int WXUNUSED(options),
|
||||||
|
bool WXUNUSED(genericInterface),
|
||||||
|
const wxString& WXUNUSED(archiver),
|
||||||
|
const wxString& WXUNUSED(unarchiver))
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
// make a display string for the option bits
|
// make a display string for the option bits
|
||||||
//
|
//
|
||||||
string ArchiveTestSuite::Description(const wxString& type,
|
string ArchiveTestSuite::Description(const wxString& type,
|
||||||
@@ -1646,10 +1248,14 @@ string ArchiveTestSuite::Description(const wxString& type,
|
|||||||
else
|
else
|
||||||
descr << type;
|
descr << type;
|
||||||
|
|
||||||
if (!archiver.empty())
|
if (!archiver.empty()) {
|
||||||
descr << _T(" ") << archiver.BeforeFirst(_T(' '));
|
const wxChar *fn = (options & PipeOut) != 0 ? _T("-") : _T("file");
|
||||||
if (!unarchiver.empty())
|
descr << _T(" (") << wxString::Format(archiver, fn) << _T(")");
|
||||||
descr << _T(" ") << unarchiver.BeforeFirst(_T(' '));
|
}
|
||||||
|
if (!unarchiver.empty()) {
|
||||||
|
const wxChar *fn = (options & PipeIn) != 0 ? _T("-") : _T("file");
|
||||||
|
descr << _T(" (") << wxString::Format(unarchiver, fn) << _T(")");
|
||||||
|
}
|
||||||
|
|
||||||
wxString optstr;
|
wxString optstr;
|
||||||
|
|
||||||
@@ -1667,10 +1273,15 @@ string ArchiveTestSuite::Description(const wxString& type,
|
|||||||
return (const char*)descr.mb_str();
|
return (const char*)descr.mb_str();
|
||||||
}
|
}
|
||||||
|
|
||||||
// register in the unnamed registry so that these tests are run by default
|
|
||||||
CPPUNIT_TEST_SUITE_REGISTRATION(ArchiveTestSuite);
|
|
||||||
|
|
||||||
// also include in it's own registry so that these tests can be run alone
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(ArchiveTestSuite, "ArchiveTestSuite");
|
// Instantiations
|
||||||
|
|
||||||
#endif // wxUSE_STREAMS
|
template class ArchiveTestCase<wxArchiveClassFactory>;
|
||||||
|
|
||||||
|
#if wxUSE_ZIPSTREAM
|
||||||
|
#include "wx/zipstrm.h"
|
||||||
|
template class ArchiveTestCase<wxZipClassFactory>;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // wxUSE_STREAMS && wxUSE_ARCSTREAM
|
||||||
|
247
tests/archive/archivetest.h
Normal file
247
tests/archive/archivetest.h
Normal file
@@ -0,0 +1,247 @@
|
|||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Name: tests/archive/archivetest.h
|
||||||
|
// Purpose: Test the archive classes
|
||||||
|
// Author: Mike Wetherell
|
||||||
|
// RCS-ID: $Id$
|
||||||
|
// Copyright: (c) 2004 Mike Wetherell
|
||||||
|
// Licence: wxWindows licence
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#define WX_TEST_ARCHIVE_ITERATOR
|
||||||
|
|
||||||
|
#include "wx/archive.h"
|
||||||
|
#include "wx/wfstream.h"
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Bit flags for options for the tests
|
||||||
|
|
||||||
|
enum Options
|
||||||
|
{
|
||||||
|
PipeIn = 0x01, // input streams are non-seekable
|
||||||
|
PipeOut = 0x02, // output streams are non-seekable
|
||||||
|
Stub = 0x04, // the archive should be appended to a stub
|
||||||
|
AllOptions = 0x07
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// TestOutputStream and TestInputStream are memory streams which can be
|
||||||
|
// seekable or non-seekable.
|
||||||
|
|
||||||
|
class TestOutputStream : public wxOutputStream
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TestOutputStream(int options);
|
||||||
|
|
||||||
|
~TestOutputStream() { delete [] m_data; }
|
||||||
|
|
||||||
|
int GetOptions() const { return m_options; }
|
||||||
|
wxFileOffset GetLength() const { return m_size; }
|
||||||
|
|
||||||
|
// gives away the data, this stream is then empty, and can be reused
|
||||||
|
void GetData(char*& data, size_t& size);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void Init();
|
||||||
|
|
||||||
|
wxFileOffset OnSysSeek(wxFileOffset pos, wxSeekMode mode);
|
||||||
|
wxFileOffset OnSysTell() const;
|
||||||
|
size_t OnSysWrite(const void *buffer, size_t size);
|
||||||
|
|
||||||
|
int m_options;
|
||||||
|
size_t m_pos;
|
||||||
|
size_t m_capacity;
|
||||||
|
size_t m_size;
|
||||||
|
char *m_data;
|
||||||
|
};
|
||||||
|
|
||||||
|
class TestInputStream : public wxInputStream
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// ctor takes the data from the output stream, which is then empty
|
||||||
|
TestInputStream(TestOutputStream& out) : m_data(NULL) { SetData(out); }
|
||||||
|
// this ctor 'dups'
|
||||||
|
TestInputStream(const TestInputStream& in);
|
||||||
|
~TestInputStream() { delete [] m_data; }
|
||||||
|
|
||||||
|
void Rewind();
|
||||||
|
wxFileOffset GetLength() const { return m_size; }
|
||||||
|
void SetData(TestOutputStream& out);
|
||||||
|
|
||||||
|
private:
|
||||||
|
wxFileOffset OnSysSeek(wxFileOffset pos, wxSeekMode mode);
|
||||||
|
wxFileOffset OnSysTell() const;
|
||||||
|
size_t OnSysRead(void *buffer, size_t size);
|
||||||
|
|
||||||
|
int m_options;
|
||||||
|
size_t m_pos;
|
||||||
|
size_t m_size;
|
||||||
|
char *m_data;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// wxFFile streams for piping to/from an external program
|
||||||
|
|
||||||
|
class PFileInputStream : public wxFFileInputStream
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PFileInputStream(const wxString& cmd);
|
||||||
|
~PFileInputStream();
|
||||||
|
};
|
||||||
|
|
||||||
|
class PFileOutputStream : public wxFFileOutputStream
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PFileOutputStream(const wxString& cmd);
|
||||||
|
~PFileOutputStream();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// A class to hold a test entry
|
||||||
|
|
||||||
|
class TestEntry
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TestEntry(const wxDateTime& dt, int len, const char *data);
|
||||||
|
~TestEntry() { delete [] m_data; }
|
||||||
|
|
||||||
|
wxDateTime GetDateTime() const { return m_dt; }
|
||||||
|
wxFileOffset GetLength() const { return m_len; }
|
||||||
|
size_t GetSize() const { return m_len; }
|
||||||
|
const char *GetData() const { return m_data; }
|
||||||
|
wxString GetComment() const { return m_comment; }
|
||||||
|
bool IsText() const { return m_isText; }
|
||||||
|
|
||||||
|
void SetComment(const wxString& comment) { m_comment = comment; }
|
||||||
|
void SetDateTime(const wxDateTime& dt) { m_dt = dt; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
wxDateTime m_dt;
|
||||||
|
size_t m_len;
|
||||||
|
char *m_data;
|
||||||
|
wxString m_comment;
|
||||||
|
bool m_isText;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// The test case
|
||||||
|
|
||||||
|
template <class ClassFactoryT>
|
||||||
|
class ArchiveTestCase : public CppUnit::TestCase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ArchiveTestCase(std::string name,
|
||||||
|
int id,
|
||||||
|
ClassFactoryT *factory,
|
||||||
|
int options,
|
||||||
|
const wxString& archiver = wxEmptyString,
|
||||||
|
const wxString& unarchiver = wxEmptyString);
|
||||||
|
|
||||||
|
~ArchiveTestCase();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// the classes to test
|
||||||
|
typedef typename ClassFactoryT::entry_type EntryT;
|
||||||
|
typedef typename ClassFactoryT::instream_type InputStreamT;
|
||||||
|
typedef typename ClassFactoryT::outstream_type OutputStreamT;
|
||||||
|
typedef typename ClassFactoryT::notifier_type NotifierT;
|
||||||
|
typedef typename ClassFactoryT::iter_type IterT;
|
||||||
|
typedef typename ClassFactoryT::pairiter_type PairIterT;
|
||||||
|
|
||||||
|
// the entry point for the test
|
||||||
|
void runTest();
|
||||||
|
|
||||||
|
// create the test data
|
||||||
|
void CreateTestData();
|
||||||
|
TestEntry& Add(const char *name, const char *data, int len = -1);
|
||||||
|
TestEntry& Add(const char *name, int len = 0, int value = EOF);
|
||||||
|
|
||||||
|
// 'archive up' the test data
|
||||||
|
void CreateArchive(wxOutputStream& out);
|
||||||
|
void CreateArchive(wxOutputStream& out, const wxString& archiver);
|
||||||
|
|
||||||
|
// perform various modifications on the archive
|
||||||
|
void ModifyArchive(wxInputStream& in, wxOutputStream& out);
|
||||||
|
|
||||||
|
// extract the archive and verify its contents
|
||||||
|
void ExtractArchive(wxInputStream& in);
|
||||||
|
void ExtractArchive(wxInputStream& in, const wxString& unarchiver);
|
||||||
|
void VerifyDir(wxString& path, size_t rootlen = 0);
|
||||||
|
|
||||||
|
// tests for the iterators
|
||||||
|
void TestIterator(wxInputStream& in);
|
||||||
|
void TestPairIterator(wxInputStream& in);
|
||||||
|
void TestSmartIterator(wxInputStream& in);
|
||||||
|
void TestSmartPairIterator(wxInputStream& in);
|
||||||
|
|
||||||
|
// try reading two entries at the same time
|
||||||
|
void ReadSimultaneous(TestInputStream& in);
|
||||||
|
|
||||||
|
// overridables
|
||||||
|
virtual void OnCreateArchive(OutputStreamT& WXUNUSED(arc)) { }
|
||||||
|
virtual void OnSetNotifier(EntryT& entry);
|
||||||
|
|
||||||
|
virtual void OnArchiveExtracted(InputStreamT& WXUNUSED(arc),
|
||||||
|
int WXUNUSED(expectedTotal)) { }
|
||||||
|
|
||||||
|
virtual void OnCreateEntry( OutputStreamT& WXUNUSED(arc),
|
||||||
|
TestEntry& WXUNUSED(testEntry),
|
||||||
|
EntryT *entry = NULL) { (void)entry; }
|
||||||
|
|
||||||
|
virtual void OnEntryExtracted( EntryT& WXUNUSED(entry),
|
||||||
|
const TestEntry& WXUNUSED(testEntry),
|
||||||
|
InputStreamT *arc = NULL) { (void)arc; }
|
||||||
|
|
||||||
|
typedef std::map<wxString, TestEntry*> TestEntries;
|
||||||
|
TestEntries m_testEntries; // test data
|
||||||
|
std::auto_ptr<ClassFactoryT> m_factory; // factory to make classes
|
||||||
|
int m_options; // test options
|
||||||
|
wxDateTime m_timeStamp; // timestamp to give test entries
|
||||||
|
int m_id; // select between the possibilites
|
||||||
|
wxString m_archiver; // external archiver
|
||||||
|
wxString m_unarchiver; // external unarchiver
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Base class for the archive test suites
|
||||||
|
|
||||||
|
class ArchiveTestSuite : public CppUnit::TestSuite
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ArchiveTestSuite(std::string name);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
int m_id;
|
||||||
|
|
||||||
|
virtual ArchiveTestSuite *makeSuite();
|
||||||
|
|
||||||
|
virtual CppUnit::Test *makeTest(std::string descr,
|
||||||
|
int id,
|
||||||
|
int options,
|
||||||
|
bool genericInterface,
|
||||||
|
const wxString& archiver,
|
||||||
|
const wxString& unarchiver);
|
||||||
|
|
||||||
|
void AddArchiver(const wxString& cmd) { AddCmd(m_archivers, cmd); }
|
||||||
|
void AddUnArchiver(const wxString &cmd) { AddCmd(m_unarchivers, cmd); }
|
||||||
|
bool IsInPath(const wxString& cmd);
|
||||||
|
|
||||||
|
std::string Description(const wxString& type,
|
||||||
|
int options,
|
||||||
|
bool genericInterface = false,
|
||||||
|
const wxString& archiver = wxEmptyString,
|
||||||
|
const wxString& unarchiver = wxEmptyString);
|
||||||
|
|
||||||
|
private:
|
||||||
|
wxString m_name;
|
||||||
|
wxPathList m_path;
|
||||||
|
wxArrayString m_archivers;
|
||||||
|
wxArrayString m_unarchivers;
|
||||||
|
|
||||||
|
void AddCmd(wxArrayString& cmdlist, const wxString& cmd);
|
||||||
|
};
|
271
tests/archive/ziptest.cpp
Normal file
271
tests/archive/ziptest.cpp
Normal file
@@ -0,0 +1,271 @@
|
|||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Name: tests/archive/ziptest.cpp
|
||||||
|
// Purpose: Test the zip classes
|
||||||
|
// Author: Mike Wetherell
|
||||||
|
// RCS-ID: $Id$
|
||||||
|
// Copyright: (c) 2004 Mike Wetherell
|
||||||
|
// Licence: wxWindows licence
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "testprec.h"
|
||||||
|
|
||||||
|
#ifdef __BORLANDC__
|
||||||
|
# pragma hdrstop
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef WX_PRECOMP
|
||||||
|
# include "wx/wx.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if wxUSE_STREAMS && wxUSE_ZIPSTREAM
|
||||||
|
|
||||||
|
#include "archivetest.h"
|
||||||
|
#include "wx/zipstrm.h"
|
||||||
|
|
||||||
|
using std::string;
|
||||||
|
using std::auto_ptr;
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// ArchiveTestCase<wxZipClassFactory> could be used directly, but instead this
|
||||||
|
// derived class is used so that zip specific features can be tested.
|
||||||
|
|
||||||
|
class ZipTestCase : public ArchiveTestCase<wxZipClassFactory>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ZipTestCase(string name,
|
||||||
|
int id,
|
||||||
|
int options,
|
||||||
|
const wxString& archiver = wxEmptyString,
|
||||||
|
const wxString& unarchiver = wxEmptyString)
|
||||||
|
:
|
||||||
|
ArchiveTestCase<wxZipClassFactory>(name, id, new wxZipClassFactory,
|
||||||
|
options, archiver, unarchiver),
|
||||||
|
m_count(0)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void OnCreateArchive(wxZipOutputStream& zip);
|
||||||
|
|
||||||
|
void OnArchiveExtracted(wxZipInputStream& zip, int expectedTotal);
|
||||||
|
|
||||||
|
void OnCreateEntry(wxZipOutputStream& zip,
|
||||||
|
TestEntry& testEntry,
|
||||||
|
wxZipEntry *entry);
|
||||||
|
|
||||||
|
void OnEntryExtracted(wxZipEntry& entry,
|
||||||
|
const TestEntry& testEntry,
|
||||||
|
wxZipInputStream *arc);
|
||||||
|
|
||||||
|
void OnSetNotifier(EntryT& entry);
|
||||||
|
|
||||||
|
int m_count;
|
||||||
|
wxString m_comment;
|
||||||
|
};
|
||||||
|
|
||||||
|
void ZipTestCase::OnCreateArchive(wxZipOutputStream& zip)
|
||||||
|
{
|
||||||
|
m_comment << _T("Comment for test ") << m_id;
|
||||||
|
zip.SetComment(m_comment);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ZipTestCase::OnArchiveExtracted(wxZipInputStream& zip, int expectedTotal)
|
||||||
|
{
|
||||||
|
CPPUNIT_ASSERT(zip.GetComment() == m_comment);
|
||||||
|
CPPUNIT_ASSERT(zip.GetTotalEntries() == expectedTotal);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ZipTestCase::OnCreateEntry(wxZipOutputStream& zip,
|
||||||
|
TestEntry& testEntry,
|
||||||
|
wxZipEntry *entry)
|
||||||
|
{
|
||||||
|
zip.SetLevel((m_id + m_count) % 10);
|
||||||
|
|
||||||
|
if (entry) {
|
||||||
|
switch ((m_id + m_count) % 5) {
|
||||||
|
case 0:
|
||||||
|
{
|
||||||
|
wxString comment = _T("Comment for ") + entry->GetName();
|
||||||
|
entry->SetComment(comment);
|
||||||
|
// lowercase the expected result, and the notifier should do
|
||||||
|
// the same for the zip entries when ModifyArchive() runs
|
||||||
|
testEntry.SetComment(comment.Lower());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 2:
|
||||||
|
entry->SetMethod(wxZIP_METHOD_STORE);
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
entry->SetMethod(wxZIP_METHOD_DEFLATE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
entry->SetIsText(testEntry.IsText());
|
||||||
|
}
|
||||||
|
|
||||||
|
m_count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ZipTestCase::OnEntryExtracted(wxZipEntry& entry,
|
||||||
|
const TestEntry& testEntry,
|
||||||
|
wxZipInputStream *arc)
|
||||||
|
{
|
||||||
|
// provide some context for the error message so that we know which
|
||||||
|
// iteration of the loop we were on
|
||||||
|
wxString name = _T(" '") + entry.GetName() + _T("'");
|
||||||
|
string error_entry(name.mb_str());
|
||||||
|
string error_context(" failed for entry" + error_entry);
|
||||||
|
|
||||||
|
CPPUNIT_ASSERT_MESSAGE("GetComment" + error_context,
|
||||||
|
entry.GetComment() == testEntry.GetComment());
|
||||||
|
|
||||||
|
// for seekable streams, GetNextEntry() doesn't read the local header so
|
||||||
|
// call OpenEntry() to do it
|
||||||
|
if (arc && (m_options & PipeIn) == 0 && entry.IsDir())
|
||||||
|
arc->OpenEntry(entry);
|
||||||
|
|
||||||
|
CPPUNIT_ASSERT_MESSAGE("IsText" + error_context,
|
||||||
|
entry.IsText() == testEntry.IsText());
|
||||||
|
|
||||||
|
CPPUNIT_ASSERT_MESSAGE("Extra/LocalExtra mismatch for entry" + error_entry,
|
||||||
|
(entry.GetExtraLen() != 0 && entry.GetLocalExtraLen() != 0) ||
|
||||||
|
(entry.GetExtraLen() == 0 && entry.GetLocalExtraLen() == 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
// check the notifier mechanism by using it to fold the entry comments to
|
||||||
|
// lowercase
|
||||||
|
//
|
||||||
|
class ZipNotifier : public wxZipNotifier
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void OnEntryUpdated(wxZipEntry& entry);
|
||||||
|
};
|
||||||
|
|
||||||
|
void ZipNotifier::OnEntryUpdated(wxZipEntry& entry)
|
||||||
|
{
|
||||||
|
entry.SetComment(entry.GetComment().Lower());
|
||||||
|
}
|
||||||
|
|
||||||
|
void ZipTestCase::OnSetNotifier(EntryT& entry)
|
||||||
|
{
|
||||||
|
static ZipNotifier notifier;
|
||||||
|
entry.SetNotifier(notifier);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// 'zip - -' produces local headers without the size field set. This is a
|
||||||
|
// case not covered by all the other tests, so this class tests it as a
|
||||||
|
// special case
|
||||||
|
|
||||||
|
class ZipPipeTestCase : public CppUnit::TestCase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ZipPipeTestCase(string name, int options) :
|
||||||
|
CppUnit::TestCase(name), m_options(options) { }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void runTest();
|
||||||
|
int m_options;
|
||||||
|
};
|
||||||
|
|
||||||
|
void ZipPipeTestCase::runTest()
|
||||||
|
{
|
||||||
|
TestOutputStream out(m_options);
|
||||||
|
|
||||||
|
wxString testdata = _T("test data to pipe through zip");
|
||||||
|
wxString cmd = _T("echo ") + testdata + _T(" | zip -q - -");
|
||||||
|
|
||||||
|
{
|
||||||
|
PFileInputStream in(cmd);
|
||||||
|
if (in.Ok())
|
||||||
|
out.Write(in);
|
||||||
|
}
|
||||||
|
|
||||||
|
TestInputStream in(out);
|
||||||
|
wxZipInputStream zip(in);
|
||||||
|
|
||||||
|
auto_ptr<wxZipEntry> entry(zip.GetNextEntry());
|
||||||
|
CPPUNIT_ASSERT(entry.get() != NULL);
|
||||||
|
|
||||||
|
if ((m_options & PipeIn) == 0)
|
||||||
|
CPPUNIT_ASSERT(entry->GetSize() != wxInvalidOffset);
|
||||||
|
|
||||||
|
char buf[64];
|
||||||
|
size_t len = zip.Read(buf, sizeof(buf) - 1).LastRead();
|
||||||
|
|
||||||
|
while (len > 0 && buf[len - 1] <= 32)
|
||||||
|
--len;
|
||||||
|
buf[len] = 0;
|
||||||
|
|
||||||
|
CPPUNIT_ASSERT(zip.Eof());
|
||||||
|
CPPUNIT_ASSERT(wxString(buf, *wxConvCurrent) == testdata);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Zip suite
|
||||||
|
|
||||||
|
class ziptest : public ArchiveTestSuite
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ziptest();
|
||||||
|
static CppUnit::Test *suite() { return (new ziptest)->makeSuite(); }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
ArchiveTestSuite *makeSuite();
|
||||||
|
|
||||||
|
CppUnit::Test *makeTest(string descr, int id, int options,
|
||||||
|
bool genericInterface, const wxString& archiver,
|
||||||
|
const wxString& unarchiver);
|
||||||
|
};
|
||||||
|
|
||||||
|
ziptest::ziptest()
|
||||||
|
: ArchiveTestSuite("zip")
|
||||||
|
{
|
||||||
|
AddArchiver(_T("zip -qr %s *"));
|
||||||
|
AddUnArchiver(_T("unzip -q %s"));
|
||||||
|
}
|
||||||
|
|
||||||
|
ArchiveTestSuite *ziptest::makeSuite()
|
||||||
|
{
|
||||||
|
ArchiveTestSuite::makeSuite();
|
||||||
|
|
||||||
|
#ifndef WXARC_NO_POPEN
|
||||||
|
// if have popen then can check the piped output of 'zip - -'
|
||||||
|
if (IsInPath(_T("zip")))
|
||||||
|
for (int options = 0; options <= PipeIn; options += PipeIn) {
|
||||||
|
string name = Description(_T("ZipPipeTestCase"), options,
|
||||||
|
false, _T(""), _T("zip -q - -"));
|
||||||
|
addTest(new ZipPipeTestCase(name, options));
|
||||||
|
m_id++;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
CppUnit::Test *ziptest::makeTest(
|
||||||
|
string descr,
|
||||||
|
int id,
|
||||||
|
int options,
|
||||||
|
bool genericInterface,
|
||||||
|
const wxString& archiver,
|
||||||
|
const wxString& unarchiver)
|
||||||
|
{
|
||||||
|
// unzip doesn't support piping in the zip
|
||||||
|
if ((options & PipeIn) && !unarchiver.empty())
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (genericInterface)
|
||||||
|
return new ArchiveTestCase<wxArchiveClassFactory>(
|
||||||
|
descr, id, new wxZipClassFactory,
|
||||||
|
options, archiver, unarchiver);
|
||||||
|
else
|
||||||
|
return new ZipTestCase(descr, id, options, archiver, unarchiver);
|
||||||
|
}
|
||||||
|
|
||||||
|
CPPUNIT_TEST_SUITE_REGISTRATION(ziptest);
|
||||||
|
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(ziptest, "archive");
|
||||||
|
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(ziptest, "archive/zip");
|
||||||
|
|
||||||
|
#endif // wxUSE_STREAMS && wxUSE_ZIPSTREAM
|
@@ -35,6 +35,7 @@ TEST_OBJECTS = \
|
|||||||
$(OBJS)\test_dummy.obj \
|
$(OBJS)\test_dummy.obj \
|
||||||
$(OBJS)\test_test.obj \
|
$(OBJS)\test_test.obj \
|
||||||
$(OBJS)\test_archivetest.obj \
|
$(OBJS)\test_archivetest.obj \
|
||||||
|
$(OBJS)\test_ziptest.obj \
|
||||||
$(OBJS)\test_arrays.obj \
|
$(OBJS)\test_arrays.obj \
|
||||||
$(OBJS)\test_datetimetest.obj \
|
$(OBJS)\test_datetimetest.obj \
|
||||||
$(OBJS)\test_fileconftest.obj \
|
$(OBJS)\test_fileconftest.obj \
|
||||||
@@ -252,6 +253,9 @@ $(OBJS)\test_test.obj: .\test.cpp
|
|||||||
$(OBJS)\test_archivetest.obj: .\archive\archivetest.cpp
|
$(OBJS)\test_archivetest.obj: .\archive\archivetest.cpp
|
||||||
$(CXX) -q -c -P -o$@ $(TEST_CXXFLAGS) $**
|
$(CXX) -q -c -P -o$@ $(TEST_CXXFLAGS) $**
|
||||||
|
|
||||||
|
$(OBJS)\test_ziptest.obj: .\archive\ziptest.cpp
|
||||||
|
$(CXX) -q -c -P -o$@ $(TEST_CXXFLAGS) $**
|
||||||
|
|
||||||
$(OBJS)\test_arrays.obj: .\arrays\arrays.cpp
|
$(OBJS)\test_arrays.obj: .\arrays\arrays.cpp
|
||||||
$(CXX) -q -c -P -o$@ $(TEST_CXXFLAGS) $**
|
$(CXX) -q -c -P -o$@ $(TEST_CXXFLAGS) $**
|
||||||
|
|
||||||
|
@@ -27,6 +27,7 @@ TEST_OBJECTS = \
|
|||||||
$(OBJS)\test_dummy.o \
|
$(OBJS)\test_dummy.o \
|
||||||
$(OBJS)\test_test.o \
|
$(OBJS)\test_test.o \
|
||||||
$(OBJS)\test_archivetest.o \
|
$(OBJS)\test_archivetest.o \
|
||||||
|
$(OBJS)\test_ziptest.o \
|
||||||
$(OBJS)\test_arrays.o \
|
$(OBJS)\test_arrays.o \
|
||||||
$(OBJS)\test_datetimetest.o \
|
$(OBJS)\test_datetimetest.o \
|
||||||
$(OBJS)\test_fileconftest.o \
|
$(OBJS)\test_fileconftest.o \
|
||||||
@@ -242,6 +243,9 @@ $(OBJS)\test_test.o: ./test.cpp
|
|||||||
$(OBJS)\test_archivetest.o: ./archive/archivetest.cpp
|
$(OBJS)\test_archivetest.o: ./archive/archivetest.cpp
|
||||||
$(CXX) -c -o $@ $(TEST_CXXFLAGS) $<
|
$(CXX) -c -o $@ $(TEST_CXXFLAGS) $<
|
||||||
|
|
||||||
|
$(OBJS)\test_ziptest.o: ./archive/ziptest.cpp
|
||||||
|
$(CXX) -c -o $@ $(TEST_CXXFLAGS) $<
|
||||||
|
|
||||||
$(OBJS)\test_arrays.o: ./arrays/arrays.cpp
|
$(OBJS)\test_arrays.o: ./arrays/arrays.cpp
|
||||||
$(CXX) -c -o $@ $(TEST_CXXFLAGS) $<
|
$(CXX) -c -o $@ $(TEST_CXXFLAGS) $<
|
||||||
|
|
||||||
|
@@ -28,6 +28,7 @@ TEST_OBJECTS = \
|
|||||||
$(OBJS)\test_dummy.obj \
|
$(OBJS)\test_dummy.obj \
|
||||||
$(OBJS)\test_test.obj \
|
$(OBJS)\test_test.obj \
|
||||||
$(OBJS)\test_archivetest.obj \
|
$(OBJS)\test_archivetest.obj \
|
||||||
|
$(OBJS)\test_ziptest.obj \
|
||||||
$(OBJS)\test_arrays.obj \
|
$(OBJS)\test_arrays.obj \
|
||||||
$(OBJS)\test_datetimetest.obj \
|
$(OBJS)\test_datetimetest.obj \
|
||||||
$(OBJS)\test_fileconftest.obj \
|
$(OBJS)\test_fileconftest.obj \
|
||||||
@@ -353,6 +354,9 @@ $(OBJS)\test_test.obj: .\test.cpp
|
|||||||
$(OBJS)\test_archivetest.obj: .\archive\archivetest.cpp
|
$(OBJS)\test_archivetest.obj: .\archive\archivetest.cpp
|
||||||
$(CXX) /c /nologo /TP /Fo$@ $(TEST_CXXFLAGS) $**
|
$(CXX) /c /nologo /TP /Fo$@ $(TEST_CXXFLAGS) $**
|
||||||
|
|
||||||
|
$(OBJS)\test_ziptest.obj: .\archive\ziptest.cpp
|
||||||
|
$(CXX) /c /nologo /TP /Fo$@ $(TEST_CXXFLAGS) $**
|
||||||
|
|
||||||
$(OBJS)\test_arrays.obj: .\arrays\arrays.cpp
|
$(OBJS)\test_arrays.obj: .\arrays\arrays.cpp
|
||||||
$(CXX) /c /nologo /TP /Fo$@ $(TEST_CXXFLAGS) $**
|
$(CXX) /c /nologo /TP /Fo$@ $(TEST_CXXFLAGS) $**
|
||||||
|
|
||||||
|
@@ -206,6 +206,7 @@ TEST_OBJECTS = &
|
|||||||
$(OBJS)\test_dummy.obj &
|
$(OBJS)\test_dummy.obj &
|
||||||
$(OBJS)\test_test.obj &
|
$(OBJS)\test_test.obj &
|
||||||
$(OBJS)\test_archivetest.obj &
|
$(OBJS)\test_archivetest.obj &
|
||||||
|
$(OBJS)\test_ziptest.obj &
|
||||||
$(OBJS)\test_arrays.obj &
|
$(OBJS)\test_arrays.obj &
|
||||||
$(OBJS)\test_datetimetest.obj &
|
$(OBJS)\test_datetimetest.obj &
|
||||||
$(OBJS)\test_fileconftest.obj &
|
$(OBJS)\test_fileconftest.obj &
|
||||||
@@ -301,6 +302,9 @@ $(OBJS)\test_test.obj : .AUTODEPEND .\test.cpp
|
|||||||
$(OBJS)\test_archivetest.obj : .AUTODEPEND .\archive\archivetest.cpp
|
$(OBJS)\test_archivetest.obj : .AUTODEPEND .\archive\archivetest.cpp
|
||||||
$(CXX) -zq -fo=$^@ $(TEST_CXXFLAGS) $<
|
$(CXX) -zq -fo=$^@ $(TEST_CXXFLAGS) $<
|
||||||
|
|
||||||
|
$(OBJS)\test_ziptest.obj : .AUTODEPEND .\archive\ziptest.cpp
|
||||||
|
$(CXX) -zq -fo=$^@ $(TEST_CXXFLAGS) $<
|
||||||
|
|
||||||
$(OBJS)\test_arrays.obj : .AUTODEPEND .\arrays\arrays.cpp
|
$(OBJS)\test_arrays.obj : .AUTODEPEND .\arrays\arrays.cpp
|
||||||
$(CXX) -zq -fo=$^@ $(TEST_CXXFLAGS) $<
|
$(CXX) -zq -fo=$^@ $(TEST_CXXFLAGS) $<
|
||||||
|
|
||||||
|
@@ -25,6 +25,7 @@
|
|||||||
<sources>
|
<sources>
|
||||||
test.cpp
|
test.cpp
|
||||||
archive/archivetest.cpp
|
archive/archivetest.cpp
|
||||||
|
archive/ziptest.cpp
|
||||||
arrays/arrays.cpp
|
arrays/arrays.cpp
|
||||||
datetime/datetimetest.cpp
|
datetime/datetimetest.cpp
|
||||||
fileconf/fileconftest.cpp
|
fileconf/fileconftest.cpp
|
||||||
|
@@ -553,6 +553,10 @@ SOURCE=.\regex\wxregextest.cpp
|
|||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\archive\ziptest.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=.\streams\zlibstream.cpp
|
SOURCE=.\streams\zlibstream.cpp
|
||||||
# End Source File
|
# End Source File
|
||||||
# End Group
|
# End Group
|
||||||
|
Reference in New Issue
Block a user