after, and also some streams give an error instead of Eof(). Test the archive streams work with parent streams that have any of these behaviours. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@36429 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
		
			
				
	
	
		
			271 lines
		
	
	
		
			8.6 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			271 lines
		
	
	
		
			8.6 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
///////////////////////////////////////////////////////////////////////////////
 | 
						|
// 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; }
 | 
						|
    bool IsSeekable() const { return (m_options & PipeOut) == 0; }
 | 
						|
 | 
						|
    // 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:
 | 
						|
    // various streams have implemented eof differently, so check the archive
 | 
						|
    // stream works with all the possibilities (bit flags that can be ORed)
 | 
						|
    enum EofTypes {
 | 
						|
        AtLast    = 0x01,   // eof before an attempt to read past the last byte
 | 
						|
        WithError = 0x02    // give an error instead of eof
 | 
						|
    };
 | 
						|
    
 | 
						|
    // ctor takes the data from the output stream, which is then empty
 | 
						|
    TestInputStream(TestOutputStream& out, int eoftype)
 | 
						|
        : m_data(NULL), m_eoftype(eoftype) { SetData(out); }
 | 
						|
    // this ctor 'dups'
 | 
						|
    TestInputStream(const TestInputStream& in);
 | 
						|
    ~TestInputStream() { delete [] m_data; }
 | 
						|
 | 
						|
    void Rewind();
 | 
						|
    wxFileOffset GetLength() const { return m_size; }
 | 
						|
    bool IsSeekable() const { return (m_options & PipeIn) == 0; }
 | 
						|
    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;
 | 
						|
    int m_eoftype;
 | 
						|
};
 | 
						|
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////////////////////////
 | 
						|
// 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,
 | 
						|
                    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
 | 
						|
};
 | 
						|
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////////////////////////
 | 
						|
// Make ids
 | 
						|
 | 
						|
class TestId
 | 
						|
{
 | 
						|
public:
 | 
						|
    // make a new id and return it as a string
 | 
						|
    static std::string MakeId();
 | 
						|
    // get the current id
 | 
						|
    static int GetId() { return m_seed; }
 | 
						|
private:
 | 
						|
    // seed for generating the ids
 | 
						|
    static int m_seed;
 | 
						|
};
 | 
						|
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////////////////////////
 | 
						|
// Base class for the archive test suites
 | 
						|
 | 
						|
class ArchiveTestSuite : public CppUnit::TestSuite
 | 
						|
{
 | 
						|
public:
 | 
						|
    ArchiveTestSuite(std::string name);
 | 
						|
 | 
						|
protected:
 | 
						|
    virtual ArchiveTestSuite *makeSuite();
 | 
						|
 | 
						|
    virtual CppUnit::Test *makeTest(std::string descr,
 | 
						|
                                    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);
 | 
						|
};
 |