2005-02-10 09:06:08 -05:00
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Name: tests/archive/ziptest.cpp
|
|
|
|
// Purpose: Test the zip classes
|
|
|
|
// Author: Mike Wetherell
|
|
|
|
// Copyright: (c) 2004 Mike Wetherell
|
|
|
|
// Licence: wxWindows licence
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
#include "testprec.h"
|
|
|
|
|
|
|
|
#ifndef WX_PRECOMP
|
|
|
|
# include "wx/wx.h"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if wxUSE_STREAMS && wxUSE_ZIPSTREAM
|
|
|
|
|
|
|
|
#include "archivetest.h"
|
|
|
|
#include "wx/zipstrm.h"
|
|
|
|
|
|
|
|
using std::string;
|
|
|
|
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
// 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 options,
|
|
|
|
const wxString& archiver = wxEmptyString,
|
|
|
|
const wxString& unarchiver = wxEmptyString)
|
|
|
|
:
|
2005-12-18 08:58:55 -05:00
|
|
|
ArchiveTestCase<wxZipClassFactory>(name, new wxZipClassFactory,
|
2005-02-10 09:06:08 -05:00
|
|
|
options, archiver, unarchiver),
|
|
|
|
m_count(0)
|
|
|
|
{ }
|
|
|
|
|
|
|
|
protected:
|
2018-09-21 13:46:49 -04:00
|
|
|
void OnCreateArchive(wxZipOutputStream& zip) wxOVERRIDE;
|
2018-07-29 05:09:17 -04:00
|
|
|
|
2018-09-21 13:46:49 -04:00
|
|
|
void OnArchiveExtracted(wxZipInputStream& zip, int expectedTotal) wxOVERRIDE;
|
2018-07-29 05:09:17 -04:00
|
|
|
|
2005-02-10 09:06:08 -05:00
|
|
|
void OnCreateEntry(wxZipOutputStream& zip,
|
|
|
|
TestEntry& testEntry,
|
2018-09-21 13:46:49 -04:00
|
|
|
wxZipEntry *entry) wxOVERRIDE;
|
2018-07-29 05:09:17 -04:00
|
|
|
|
2005-02-10 09:06:08 -05:00
|
|
|
void OnEntryExtracted(wxZipEntry& entry,
|
|
|
|
const TestEntry& testEntry,
|
2018-09-21 13:46:49 -04:00
|
|
|
wxZipInputStream *arc) wxOVERRIDE;
|
2005-02-10 09:06:08 -05:00
|
|
|
|
2018-09-21 13:46:49 -04:00
|
|
|
void OnSetNotifier(EntryT& entry) wxOVERRIDE;
|
2005-02-10 09:06:08 -05:00
|
|
|
|
|
|
|
int m_count;
|
|
|
|
wxString m_comment;
|
|
|
|
};
|
|
|
|
|
|
|
|
void ZipTestCase::OnCreateArchive(wxZipOutputStream& zip)
|
|
|
|
{
|
2009-07-23 16:30:22 -04:00
|
|
|
m_comment << wxT("Comment for test ") << m_id;
|
2005-02-10 09:06:08 -05:00
|
|
|
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:
|
|
|
|
{
|
2009-07-23 16:30:22 -04:00
|
|
|
wxString comment = wxT("Comment for ") + entry->GetName();
|
2005-02-10 09:06:08 -05:00
|
|
|
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
|
2009-07-23 16:30:22 -04:00
|
|
|
wxString name = wxT(" '") + entry.GetName() + wxT("'");
|
2005-02-10 09:06:08 -05:00
|
|
|
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());
|
|
|
|
|
Replace CppUnit with Catch for unit tests
Drop the legacy CppUnit testing framework used for the unit tests.
Replacing it with Catch has the advantage of not requiring CppUnit
libraries to be installed on the system in order to be able to run
tests (Catch is header-only and a copy of it is now included in the
main repository itself) and, in the future, of being able to write
the tests in a much more natural way.
For now, however, avoid changing the existing tests code as much as
[reasonably] possible to avoid introducing bugs in them and provide
the CppUnit compatibility macros in the new wx/catch_cppunit.h header
which allow to preserve the 99% of the existing code unchanged. Some
of the required changes are:
- Decompose asserts using "a && b" conditions into multiple asserts
checking "a" and "b" independently. This would have been better
even with CppUnit (to know which part of condition exactly failed)
and is required with Catch.
- Use extra parentheses around such conditions when they can't be
easily decomposed in the arrays test, due to the use of macros.
This is not ideal from the point of view of messages given when
the tests fail but will do for now.
- Rewrite asserts using "a || b" as a combination of condition
checks and assert macros. Again, this is better anyhow, and is
required with Catch. Incidentally, this allowed to fix a bug in
the "exec" unit test which didn't leave enough time for the new
process to be launched before trying to kill it.
- Remove multiple CPPUNIT_TEST_SUITE_NAMED_REGISTRATION() macros,
our emulation of this macro can be used only once.
- Provide string conversions using Catch-specific StringMaker for
a couple of types.
- Replace custom wxImage comparison with a Catch-specific matcher
class.
- Remove most of test running logic from test.cpp, in particular don't
parse command line ourselves any longer but use Catch built-in
command line parser. This is a source of a minor regression:
previously, both "Foo" and "FooTestCase" could be used as the name of
the test to run, but now only the latter is accepted.
2017-11-01 14:15:24 -04:00
|
|
|
INFO("Extra/LocalExtra mismatch for entry" + error_entry);
|
|
|
|
if ( entry.GetExtraLen() )
|
|
|
|
CHECK( entry.GetLocalExtraLen() != 0 );
|
|
|
|
else
|
|
|
|
CHECK( entry.GetLocalExtraLen() == 0 );
|
2005-02-10 09:06:08 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
// check the notifier mechanism by using it to fold the entry comments to
|
|
|
|
// lowercase
|
|
|
|
//
|
|
|
|
class ZipNotifier : public wxZipNotifier
|
|
|
|
{
|
|
|
|
public:
|
2018-09-21 13:46:49 -04:00
|
|
|
void OnEntryUpdated(wxZipEntry& entry) wxOVERRIDE;
|
2005-02-10 09:06:08 -05:00
|
|
|
};
|
|
|
|
|
|
|
|
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) :
|
2005-12-18 08:58:55 -05:00
|
|
|
CppUnit::TestCase(TestId::MakeId() + name),
|
|
|
|
m_options(options),
|
|
|
|
m_id(TestId::GetId())
|
|
|
|
{ }
|
2005-02-10 09:06:08 -05:00
|
|
|
|
|
|
|
protected:
|
2018-09-21 13:46:49 -04:00
|
|
|
void runTest() wxOVERRIDE;
|
2005-02-10 09:06:08 -05:00
|
|
|
int m_options;
|
2005-12-18 08:58:55 -05:00
|
|
|
int m_id;
|
2005-02-10 09:06:08 -05:00
|
|
|
};
|
|
|
|
|
|
|
|
void ZipPipeTestCase::runTest()
|
|
|
|
{
|
|
|
|
TestOutputStream out(m_options);
|
|
|
|
|
2009-07-23 16:30:22 -04:00
|
|
|
wxString testdata = wxT("test data to pipe through zip");
|
|
|
|
wxString cmd = wxT("echo ") + testdata + wxT(" | zip -q - -");
|
2005-02-10 09:06:08 -05:00
|
|
|
|
|
|
|
{
|
|
|
|
PFileInputStream in(cmd);
|
2011-05-03 12:29:04 -04:00
|
|
|
if (in.IsOk())
|
2005-02-10 09:06:08 -05:00
|
|
|
out.Write(in);
|
|
|
|
}
|
|
|
|
|
2005-12-18 08:58:55 -05:00
|
|
|
TestInputStream in(out, m_id % ((m_options & PipeIn) ? 4 : 3));
|
2005-02-10 09:06:08 -05:00
|
|
|
wxZipInputStream zip(in);
|
|
|
|
|
2017-10-31 16:14:05 -04:00
|
|
|
wxScopedPtr<wxZipEntry> entry(zip.GetNextEntry());
|
2005-02-10 09:06:08 -05:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
2018-07-29 05:09:17 -04:00
|
|
|
// Zip suite
|
2005-02-10 09:06:08 -05:00
|
|
|
|
|
|
|
class ziptest : public ArchiveTestSuite
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
ziptest();
|
|
|
|
|
2017-11-07 07:50:47 -05:00
|
|
|
void runTest() wxOVERRIDE { DoRunTest(); }
|
2005-02-10 09:06:08 -05:00
|
|
|
|
2017-11-07 07:50:47 -05:00
|
|
|
protected:
|
2005-12-18 08:58:55 -05:00
|
|
|
CppUnit::Test *makeTest(string descr, int options,
|
2005-02-10 09:06:08 -05:00
|
|
|
bool genericInterface, const wxString& archiver,
|
2018-07-29 05:09:17 -04:00
|
|
|
const wxString& unarchiver) wxOVERRIDE;
|
2005-02-10 09:06:08 -05:00
|
|
|
};
|
|
|
|
|
|
|
|
ziptest::ziptest()
|
|
|
|
: ArchiveTestSuite("zip")
|
|
|
|
{
|
2009-07-23 16:30:22 -04:00
|
|
|
AddArchiver(wxT("zip -qr %s *"));
|
|
|
|
AddUnArchiver(wxT("unzip -q %s"));
|
2005-02-10 09:06:08 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
CppUnit::Test *ziptest::makeTest(
|
|
|
|
string descr,
|
|
|
|
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)
|
2009-06-06 19:04:50 -04:00
|
|
|
{
|
2005-02-10 09:06:08 -05:00
|
|
|
return new ArchiveTestCase<wxArchiveClassFactory>(
|
2005-12-18 08:58:55 -05:00
|
|
|
descr, new wxZipClassFactory,
|
2005-02-10 09:06:08 -05:00
|
|
|
options, archiver, unarchiver);
|
2009-06-06 19:04:50 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
return new ZipTestCase(descr, options, archiver, unarchiver);
|
2005-02-10 09:06:08 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
CPPUNIT_TEST_SUITE_REGISTRATION(ziptest);
|
|
|
|
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(ziptest, "archive/zip");
|
|
|
|
|
|
|
|
#endif // wxUSE_STREAMS && wxUSE_ZIPSTREAM
|