1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251
|
///////////////////////////////////////////////////////////////////////////////
// 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)
:
ArchiveTestCase<wxZipClassFactory>(name, new wxZipClassFactory,
options, archiver, unarchiver),
m_count(0)
{ }
protected:
void OnCreateArchive(wxZipOutputStream& zip) wxOVERRIDE;
void OnArchiveExtracted(wxZipInputStream& zip, int expectedTotal) wxOVERRIDE;
void OnCreateEntry(wxZipOutputStream& zip,
TestEntry& testEntry,
wxZipEntry *entry) wxOVERRIDE;
void OnEntryExtracted(wxZipEntry& entry,
const TestEntry& testEntry,
wxZipInputStream *arc) wxOVERRIDE;
void OnSetNotifier(EntryT& entry) wxOVERRIDE;
int m_count;
wxString m_comment;
};
void ZipTestCase::OnCreateArchive(wxZipOutputStream& zip)
{
m_comment << wxT("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 = wxT("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 = wxT(" '") + entry.GetName() + wxT("'");
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());
INFO("Extra/LocalExtra mismatch for entry" + error_entry);
if ( entry.GetExtraLen() )
CHECK( entry.GetLocalExtraLen() != 0 );
else
CHECK( 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) wxOVERRIDE;
};
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(TestId::MakeId() + name),
m_options(options),
m_id(TestId::GetId())
{ }
protected:
void runTest() wxOVERRIDE;
int m_options;
int m_id;
};
void ZipPipeTestCase::runTest()
{
TestOutputStream out(m_options);
wxString testdata = wxT("test data to pipe through zip");
wxString cmd = wxT("echo ") + testdata + wxT(" | zip -q - -");
{
PFileInputStream in(cmd);
if (in.IsOk())
out.Write(in);
}
TestInputStream in(out, m_id % ((m_options & PipeIn) ? 4 : 3));
wxZipInputStream zip(in);
wxScopedPtr<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();
void runTest() wxOVERRIDE { DoRunTest(); }
protected:
CppUnit::Test *makeTest(string descr, int options,
bool genericInterface, const wxString& archiver,
const wxString& unarchiver) wxOVERRIDE;
};
ziptest::ziptest()
: ArchiveTestSuite("zip")
{
AddArchiver(wxT("zip -qr %s *"));
AddUnArchiver(wxT("unzip -q %s"));
}
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)
{
return new ArchiveTestCase<wxArchiveClassFactory>(
descr, new wxZipClassFactory,
options, archiver, unarchiver);
}
return new ZipTestCase(descr, options, archiver, unarchiver);
}
CPPUNIT_TEST_SUITE_REGISTRATION(ziptest);
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(ziptest, "archive/zip");
#endif // wxUSE_STREAMS && wxUSE_ZIPSTREAM
|