wxWidgets/tests/file/filefn.cpp

516 lines
17 KiB
C++
Raw Normal View History

///////////////////////////////////////////////////////////////////////////////
// Name: tests/file/filefn.cpp
// Purpose: generic file functions unit test
// Author: Francesco Montorsi (extracted from console sample)
// Created: 2010-06-13
// Copyright: (c) 2010 wxWidgets team
///////////////////////////////////////////////////////////////////////////////
// ----------------------------------------------------------------------------
// headers
// ----------------------------------------------------------------------------
#include "testprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
#if wxUSE_FILE
#include "wx/ffile.h"
#include "wx/filefn.h"
#include "wx/textfile.h"
#include "wx/filesys.h"
#include "testfile.h"
// ----------------------------------------------------------------------------
// test class
// ----------------------------------------------------------------------------
class FileFunctionsTestCase : public CppUnit::TestCase
{
public:
FileFunctionsTestCase() { }
void setUp();
void tearDown();
private:
CPPUNIT_TEST_SUITE( FileFunctionsTestCase );
CPPUNIT_TEST( GetTempFolder );
CPPUNIT_TEST( CopyFile );
CPPUNIT_TEST( CreateFile );
CPPUNIT_TEST( FileExists );
CPPUNIT_TEST( FindFile );
CPPUNIT_TEST( FindFileNext );
CPPUNIT_TEST( RemoveFile );
CPPUNIT_TEST( RenameFile );
CPPUNIT_TEST( ConcatenateFiles );
CPPUNIT_TEST( GetCwd );
CPPUNIT_TEST( FileEof );
CPPUNIT_TEST( FileError );
CPPUNIT_TEST_SUITE_END();
void GetTempFolder();
void CopyFile();
void CreateFile();
void FileExists();
void FindFile();
void FindFileNext();
void RemoveFile();
void RenameFile();
void ConcatenateFiles();
void GetCwd();
void FileEof();
void FileError();
// Helper methods
void DoCreateFile(const wxString& filePath);
void DoFileExists(const wxString& filePath);
void DoFindFile(const wxString& filePath);
void DoRemoveFile(const wxString& filePath);
void DoRenameFile(const wxString& oldFilePath,
const wxString& newFilePath,
bool overwrite,
bool withNew);
void DoConcatFile(const wxString& filePath1,
const wxString& filePath2,
const wxString& destFilePath);
wxString m_fileNameASCII;
wxString m_fileNameNonASCII;
wxString m_fileNameWork;
wxDECLARE_NO_COPY_CLASS(FileFunctionsTestCase);
};
// ----------------------------------------------------------------------------
// CppUnit macros
// ----------------------------------------------------------------------------
CPPUNIT_TEST_SUITE_REGISTRATION( FileFunctionsTestCase );
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( FileFunctionsTestCase, "FileFunctionsTestCase" );
// ----------------------------------------------------------------------------
// tests implementation
// ----------------------------------------------------------------------------
void FileFunctionsTestCase::setUp()
{
// Initialize local data
wxFileName fn1(wxFileName::GetTempDir(), wxT("wx_file_mask.txt"));
m_fileNameASCII = fn1.GetFullPath();
// This file name is 'wx_file_mask.txt' in Russian.
wxFileName fn2(wxFileName::GetTempDir(),
wxT("wx_\u043C\u0430\u0441\u043A\u0430_\u0444\u0430\u0439\u043B\u0430.txt"));
m_fileNameNonASCII = fn2.GetFullPath();
wxFileName fn3(wxFileName::GetTempDir(), wxT("wx_test_copy"));
m_fileNameWork = fn3.GetFullPath();
}
void FileFunctionsTestCase::tearDown()
{
// Remove all remaining temporary files
if ( wxFileExists(m_fileNameASCII) )
{
wxRemoveFile(m_fileNameASCII);
}
if ( wxFileExists(m_fileNameNonASCII) )
{
wxRemoveFile(m_fileNameNonASCII);
}
if ( wxFileExists(m_fileNameWork) )
{
wxRemoveFile(m_fileNameWork);
}
}
void FileFunctionsTestCase::GetTempFolder()
{
// Verify that obtained temporary folder is not empty.
wxString tmpDir = wxFileName::GetTempDir();
CPPUNIT_ASSERT( !tmpDir.IsEmpty() );
}
void FileFunctionsTestCase::CopyFile()
{
const wxString filename1(wxT("horse.bmp"));
const wxString& filename2 = m_fileNameWork;
const wxString msg = wxString::Format(wxT("File 1: %s File 2:%s"),
filename1.c_str(), filename2.c_str());
const char *pUnitMsg = (const char*)msg.mb_str(wxConvUTF8);
CPPUNIT_ASSERT_MESSAGE( pUnitMsg, wxCopyFile(filename1, filename2) );
// verify that the two files have the same contents!
wxFFile f1(filename1, wxT("rb")),
f2(filename2, wxT("rb"));
CPPUNIT_ASSERT_MESSAGE( pUnitMsg, f1.IsOpened() && f2.IsOpened() );
wxString s1, s2;
CPPUNIT_ASSERT_MESSAGE( pUnitMsg, f1.ReadAll(&s1) && f2.ReadAll(&s2) );
CPPUNIT_ASSERT_MESSAGE( pUnitMsg, (s1.length() == s2.length()) &&
(memcmp(s1.c_str(), s2.c_str(), s1.length()) == 0) );
CPPUNIT_ASSERT_MESSAGE( pUnitMsg, f1.Close() && f2.Close() );
CPPUNIT_ASSERT_MESSAGE( pUnitMsg, wxRemoveFile(filename2) );
}
void FileFunctionsTestCase::CreateFile()
{
// Create file name containing ASCII characters only.
DoCreateFile(m_fileNameASCII);
// Create file name containing non-ASCII characters.
DoCreateFile(m_fileNameNonASCII);
}
void FileFunctionsTestCase::DoCreateFile(const wxString& filePath)
{
const wxString msg = wxString::Format(wxT("File: %s"),
filePath.c_str());
const char *pUnitMsg = (const char*)msg.mb_str(wxConvUTF8);
// Create temporary file.
wxTextFile file;
CPPUNIT_ASSERT_MESSAGE( pUnitMsg, file.Create(filePath) );
CPPUNIT_ASSERT_MESSAGE( pUnitMsg, file.Close() );
wxRemoveFile(filePath);
}
void FileFunctionsTestCase::FileExists()
{
CPPUNIT_ASSERT( wxFileExists(wxT("horse.png")) );
CPPUNIT_ASSERT( !wxFileExists(wxT("horse.___")) );
// Check file name containing ASCII characters only.
DoFileExists(m_fileNameASCII);
// Check file name containing non-ASCII characters.
DoFileExists(m_fileNameNonASCII);
}
void FileFunctionsTestCase::DoFileExists(const wxString& filePath)
{
const wxString msg = wxString::Format(wxT("File: %s"),
filePath.c_str());
const char *pUnitMsg = (const char*)msg.mb_str(wxConvUTF8);
// Create temporary file.
wxTextFile file;
CPPUNIT_ASSERT_MESSAGE( pUnitMsg, file.Create(filePath) );
CPPUNIT_ASSERT_MESSAGE( pUnitMsg, file.Close() );
// Verify that file exists with 2 methods.
CPPUNIT_ASSERT_MESSAGE( pUnitMsg, file.Exists() );
CPPUNIT_ASSERT_MESSAGE( pUnitMsg, wxFileExists(filePath) );
wxRemoveFile(filePath);
}
void FileFunctionsTestCase::FindFile()
{
// Find file name containing ASCII characters only.
DoFindFile(m_fileNameASCII);
// Find file name containing non-ASCII characters.
DoFindFile(m_fileNameNonASCII);
}
void FileFunctionsTestCase::DoFindFile(const wxString& filePath)
{
const wxString msg = wxString::Format(wxT("File: %s"),
filePath.c_str());
const char *pUnitMsg = (const char*)msg.mb_str(wxConvUTF8);
// Create temporary file.
wxTextFile file;
CPPUNIT_ASSERT_MESSAGE( pUnitMsg, file.Create(filePath) );
CPPUNIT_ASSERT_MESSAGE( pUnitMsg, file.Close() );
// Check if file can be found (method 1).
wxString foundFile = wxFindFirstFile(filePath, wxFILE);
CPPUNIT_ASSERT_MESSAGE( pUnitMsg, foundFile == filePath );
// Check if file can be found (method 2).
wxFileSystem fs;
wxString furl = fs.FindFirst(filePath, wxFILE);
wxFileName fname = wxFileSystem::URLToFileName(furl);
foundFile = fname.GetFullPath();
CPPUNIT_ASSERT_MESSAGE( pUnitMsg, foundFile == filePath );
wxRemoveFile(filePath);
}
void FileFunctionsTestCase::FindFileNext()
{
// Construct file name containing ASCII characters only.
const wxString fileMask(wxT("horse.*"));
// Check using method 1.
wxString foundFile1 = wxFindFirstFile(fileMask, wxFILE);
wxString foundFile2 = wxFindNextFile();
wxFileName fn1(foundFile1);
wxFileName fn2(foundFile2);
// Full names must be different.
CPPUNIT_ASSERT( foundFile1 != foundFile2 );
// Base names must be the same.
CPPUNIT_ASSERT( fn1.GetName() == fn2.GetName() );
// Check using method 2.
wxFileSystem fs;
wxString furl = fs.FindFirst(fileMask, wxFILE);
fn1 = wxFileSystem::URLToFileName(furl);
foundFile1 = fn1.GetFullPath();
furl = fs.FindNext();
fn2 = wxFileSystem::URLToFileName(furl);
foundFile2 = fn2.GetFullPath();
// Full names must be different.
CPPUNIT_ASSERT( fn1.GetFullPath() != fn2.GetFullPath() );
// Base names must be the same.
CPPUNIT_ASSERT( fn1.GetName() == fn2.GetName() );
}
void FileFunctionsTestCase::RemoveFile()
{
// Create & remove file with name containing ASCII characters only.
DoRemoveFile(m_fileNameASCII);
// Create & remove file with name containing non-ASCII characters.
DoRemoveFile(m_fileNameNonASCII);
}
void FileFunctionsTestCase::DoRemoveFile(const wxString& filePath)
{
const wxString msg = wxString::Format(wxT("File: %s"),
filePath.c_str());
const char *pUnitMsg = (const char*)msg.mb_str(wxConvUTF8);
// Create temporary file.
wxTextFile file;
CPPUNIT_ASSERT_MESSAGE( pUnitMsg, file.Create(filePath) );
CPPUNIT_ASSERT_MESSAGE( pUnitMsg, file.Close() );
CPPUNIT_ASSERT_MESSAGE( pUnitMsg, file.Exists() );
CPPUNIT_ASSERT_MESSAGE( pUnitMsg, wxRemoveFile(filePath) );
CPPUNIT_ASSERT_MESSAGE( pUnitMsg, !file.Exists() );
}
void FileFunctionsTestCase::RenameFile()
{
// Verify renaming file with/without overwriting
// when new file already exist/don't exist.
DoRenameFile(m_fileNameASCII, m_fileNameNonASCII, false, false);
DoRenameFile(m_fileNameASCII, m_fileNameNonASCII, false, true);
DoRenameFile(m_fileNameASCII, m_fileNameNonASCII, true, false);
DoRenameFile(m_fileNameASCII, m_fileNameNonASCII, true, true);
DoRenameFile(m_fileNameNonASCII, m_fileNameASCII, false, false);
DoRenameFile(m_fileNameNonASCII, m_fileNameASCII, false, true);
DoRenameFile(m_fileNameNonASCII, m_fileNameASCII, true, false);
DoRenameFile(m_fileNameNonASCII, m_fileNameASCII, true, true);
}
void
FileFunctionsTestCase::DoRenameFile(const wxString& oldFilePath,
const wxString& newFilePath,
bool overwrite,
bool withNew)
{
const wxString msg = wxString::Format(wxT("File 1: %s File 2: %s"),
oldFilePath.c_str(), newFilePath.c_str());
const char *pUnitMsg = (const char*)msg.mb_str(wxConvUTF8);
// Create temporary source file.
wxTextFile file;
CPPUNIT_ASSERT_MESSAGE( pUnitMsg, file.Create(oldFilePath) );
CPPUNIT_ASSERT_MESSAGE( pUnitMsg, file.Close() );
if ( withNew )
{
// Create destination file to test overwriting.
wxTextFile file2;
CPPUNIT_ASSERT_MESSAGE( pUnitMsg, file2.Create(newFilePath) );
CPPUNIT_ASSERT_MESSAGE( pUnitMsg, file2.Close() );
CPPUNIT_ASSERT_MESSAGE( pUnitMsg, wxFileExists(newFilePath) );
}
else
{
// Remove destination file
if ( wxFileExists(newFilePath) )
{
wxRemoveFile(newFilePath);
}
CPPUNIT_ASSERT_MESSAGE( pUnitMsg, !wxFileExists(newFilePath) );
}
CPPUNIT_ASSERT_MESSAGE( pUnitMsg, wxFileExists(oldFilePath) );
CPPUNIT_ASSERT_MESSAGE( pUnitMsg, wxFileExists(oldFilePath) );
CPPUNIT_ASSERT_MESSAGE( pUnitMsg, wxFileExists(oldFilePath) );
bool shouldFail = !overwrite && withNew;
if ( shouldFail )
{
CPPUNIT_ASSERT_MESSAGE( pUnitMsg, !wxRenameFile(oldFilePath, newFilePath, overwrite));
// Verify that file has not been renamed.
CPPUNIT_ASSERT_MESSAGE( pUnitMsg, wxFileExists(oldFilePath) );
CPPUNIT_ASSERT_MESSAGE( pUnitMsg, wxFileExists(newFilePath) );
// Cleanup.
wxRemoveFile(oldFilePath);
}
else
{
CPPUNIT_ASSERT_MESSAGE( pUnitMsg, wxRenameFile(oldFilePath, newFilePath, overwrite) );
// Verify that file has been renamed.
CPPUNIT_ASSERT_MESSAGE( pUnitMsg, !wxFileExists(oldFilePath) );
CPPUNIT_ASSERT_MESSAGE( pUnitMsg, wxFileExists(newFilePath) );
}
// Cleanup.
wxRemoveFile(newFilePath);
}
void FileFunctionsTestCase::ConcatenateFiles()
{
DoConcatFile(m_fileNameASCII, m_fileNameNonASCII, m_fileNameWork);
DoConcatFile(m_fileNameNonASCII, m_fileNameASCII, m_fileNameWork);
}
void FileFunctionsTestCase::DoConcatFile(const wxString& filePath1,
const wxString& filePath2,
const wxString& destFilePath)
{
const wxString msg = wxString::Format(wxT("File 1: %s File 2: %s File 3: %s"),
filePath1.c_str(), filePath2.c_str(), destFilePath.c_str());
const char *pUnitMsg = (const char*)msg.mb_str(wxConvUTF8);
// Prepare source data
wxFFile f1(filePath1, wxT("wb")),
f2(filePath2, wxT("wb"));
CPPUNIT_ASSERT_MESSAGE( pUnitMsg, f1.IsOpened() && f2.IsOpened() );
wxString s1(wxT("1234567890"));
wxString s2(wxT("abcdefghij"));
CPPUNIT_ASSERT_MESSAGE( pUnitMsg, f1.Write(s1) );
CPPUNIT_ASSERT_MESSAGE( pUnitMsg, f2.Write(s2) );
CPPUNIT_ASSERT_MESSAGE( pUnitMsg, f1.Close() && f2.Close() );
// Concatenate source files
CPPUNIT_ASSERT_MESSAGE( pUnitMsg, wxConcatFiles(filePath1, filePath2, destFilePath) );
// Verify content of destination file
CPPUNIT_ASSERT_MESSAGE( pUnitMsg, wxFileExists(destFilePath) );
wxString sSrc = s1 + s2;
wxString s3;
wxFFile f3(destFilePath, wxT("rb"));
CPPUNIT_ASSERT_MESSAGE( pUnitMsg, f3.ReadAll(&s3) );
CPPUNIT_ASSERT_MESSAGE( pUnitMsg, (sSrc.length() == s3.length()) &&
(memcmp(sSrc.c_str(), s3.c_str(), sSrc.length()) == 0) );
CPPUNIT_ASSERT_MESSAGE( pUnitMsg, f3.Close() );
CPPUNIT_ASSERT_MESSAGE( pUnitMsg, wxRemoveFile(filePath1) );
CPPUNIT_ASSERT_MESSAGE( pUnitMsg, wxRemoveFile(filePath2) );
CPPUNIT_ASSERT_MESSAGE( pUnitMsg, wxRemoveFile(destFilePath) );
}
void FileFunctionsTestCase::GetCwd()
{
// Verify that obtained working directory is not empty.
wxString cwd = wxGetCwd();
CPPUNIT_ASSERT( !cwd.IsEmpty() );
}
void FileFunctionsTestCase::FileEof()
{
const wxString filename(wxT("horse.bmp"));
const wxString msg = wxString::Format(wxT("File: %s"), filename.c_str());
const char *pUnitMsg = (const char*) msg.mb_str(wxConvUTF8);
wxFFile file(filename, wxT("r"));
// wxFFile::Eof must be false at start
CPPUNIT_ASSERT_MESSAGE( pUnitMsg, !file.Eof() );
CPPUNIT_ASSERT_MESSAGE( pUnitMsg, file.SeekEnd() );
// wxFFile::Eof returns true only after attempt to read last byte
char array[1];
CPPUNIT_ASSERT_MESSAGE( pUnitMsg, file.Read(array, 1) == 0 );
CPPUNIT_ASSERT_MESSAGE( pUnitMsg, file.Eof() );
CPPUNIT_ASSERT_MESSAGE( pUnitMsg, file.Close() );
// wxFFile::Eof after close should not cause crash but fail instead
bool failed = true;
try
{
file.Eof();
failed = false;
}
catch (...)
{
}
CPPUNIT_ASSERT_MESSAGE( pUnitMsg, failed );
}
void FileFunctionsTestCase::FileError()
{
const wxString filename(wxT("horse.bmp"));
const wxString msg = wxString::Format(wxT("File: %s"), filename.c_str());
const char *pUnitMsg = (const char*) msg.mb_str(wxConvUTF8);
wxFFile file(filename, wxT("r"));
// wxFFile::Error must be false at start assuming file "horse.bmp" exists.
CPPUNIT_ASSERT_MESSAGE( pUnitMsg, !file.Error() );
// Attempt to write to file opened in readonly mode should cause error
CPPUNIT_ASSERT_MESSAGE( pUnitMsg, !file.Write(filename) );
CPPUNIT_ASSERT_MESSAGE( pUnitMsg, file.Error() );
CPPUNIT_ASSERT_MESSAGE( pUnitMsg, file.Close() );
// wxFFile::Error after close should not cause crash but fail instead
bool failed = true;
try
{
file.Error();
failed = false;
}
catch (...)
{
}
CPPUNIT_ASSERT_MESSAGE( pUnitMsg, failed );
}
/*
TODO: other file functions to test:
bool wxDirExists(const wxString& pathName);
bool wxIsAbsolutePath(const wxString& filename);
wxChar* wxFileNameFromPath(wxChar *path);
wxString wxFileNameFromPath(const wxString& path);
wxString wxPathOnly(const wxString& path);
bool wxIsWild(const wxString& pattern);
bool wxMatchWild(const wxString& pattern, const wxString& text, bool dot_special = true);
bool wxSetWorkingDirectory(const wxString& d);
bool wxMkdir(const wxString& dir, int perm = wxS_DIR_DEFAULT);
bool wxRmdir(const wxString& dir, int flags = 0);
wxFileKind wxGetFileKind(int fd);
wxFileKind wxGetFileKind(FILE *fp);
bool wxIsWritable(const wxString &path);
bool wxIsReadable(const wxString &path);
bool wxIsExecutable(const wxString &path);
*/
#endif // wxUSE_FILE