mirror of
https://github.com/thunderbrewhq/squall.git
synced 2026-05-04 06:33:50 +00:00
chore(file): add tests for SFile functions
This commit is contained in:
parent
1e86f98691
commit
40d58978e1
20 changed files with 567 additions and 18 deletions
|
|
@ -10,10 +10,12 @@
|
|||
#endif
|
||||
|
||||
#if defined(WHOA_SYSTEM_MAC) || defined(WHOA_SYSTEM_LINUX)
|
||||
#define ERROR_SUCCESS 0x0
|
||||
#define ERROR_INVALID_HANDLE 0x6
|
||||
#define ERROR_NOT_ENOUGH_MEMORY 0x8
|
||||
#define ERROR_INVALID_PARAMETER 0x57
|
||||
#define ERROR_SUCCESS 0
|
||||
#define ERROR_FILE_NOT_FOUND 2
|
||||
#define ERROR_INVALID_HANDLE 6
|
||||
#define ERROR_NOT_ENOUGH_MEMORY 8
|
||||
#define ERROR_HANDLE_EOF 38
|
||||
#define ERROR_INVALID_PARAMETER 87
|
||||
#endif
|
||||
|
||||
[[noreturn]] void STORMCDECL SErrDisplayAppFatal(const char* format, ...);
|
||||
|
|
|
|||
|
|
@ -12,18 +12,78 @@
|
|||
DECLARE_STORM_HANDLE(HSARCHIVE);
|
||||
DECLARE_STORM_HANDLE(HSFILE);
|
||||
|
||||
int32_t STORMAPI SFileOpenArchive(const char* archivename, int32_t priority, uint32_t flags, HSARCHIVE* handle);
|
||||
#define SFILE_ARCHIVE_READ_FROM_CD_ONLY 0x000001
|
||||
#define SFILE_ARCHIVE_ENABLE_OVERLAPPED 0x000002
|
||||
#define SFILE_ARCHIVE_DONT_CHECKDISK 0x000004
|
||||
#define SFILE_ARCHIVE_DONT_SEARCH 0x000008
|
||||
#define SFILE_ARCHIVE_ARC4_DECRYPT 0x000010
|
||||
#define SFILE_ARCHIVE_DECRYPTION_TYPES 0x000010
|
||||
#define SFILE_ARCHIVE_WRITE_PERMISSION 0x000010
|
||||
#define SFILE_ARCHIVE_OPEN_LAST_ARCHIVE 0x000020
|
||||
#define SFILE_ARCHIVE_LOAD_MD5_VALUES 0x000040
|
||||
#define SFILE_ARCHIVE_LOAD_CRC_VALUES 0x000080
|
||||
#define SFILE_ARCHIVE_LOAD_TIMESTAMPS 0x000100
|
||||
#define SFILE_ARCHIVE_CHECK_MD5_VALUES 0x000200
|
||||
#define SFILE_ARCHIVE_USE_NEW_BLOCK_HASH_FORMAT 0x000400
|
||||
#define SFILE_ARCHIVE_INIT_TABLE_ON_OPEN 0x000800
|
||||
#define SFILE_ARCHIVE_LOAD_DELTA_VALUES 0x001000
|
||||
#define SFILE_ARCHIVE_LOAD_DELTA_AS_RAW 0x002000
|
||||
#define SFILE_ARCHIVE_DONT_TRUNCATE 0x004000
|
||||
#define SFILE_ARCHIVE_DISK_DELETE_CAN_FAIL 0x010000
|
||||
#define SFILE_ARCHIVE_SC1161_PERMISSIVE 0x020000
|
||||
|
||||
#define SFILE_OPENFLAG_CHECKDISK 1
|
||||
#define SFILE_OPENFLAG_CHECKDISK_NOPATH 2
|
||||
#define SFILE_OPENFLAG_NATIVEHANDLE 4 // made up
|
||||
#define SFILE_OPENFLAG_PERM_SHARED_WRITE 0x8000
|
||||
#define SFILE_OPENFLAG_PRESERVE_PATH_SEPARATORS 0x10000
|
||||
|
||||
#define SFILE_BEGIN 0
|
||||
#define SFILE_CURRENT 1
|
||||
#define SFILE_END 2
|
||||
|
||||
/* // Leaving as documentation
|
||||
|
||||
#define SFILE_AUTH_UNABLETOAUTHENTICATE 0
|
||||
#define SFILE_AUTH_NOSIGNATURE 1
|
||||
#define SFILE_AUTH_BADSIGNATURE 2
|
||||
#define SFILE_AUTH_UNKNOWNSIGNATURE 3
|
||||
#define SFILE_AUTH_FIRSTAUTHENTIC 5
|
||||
#define SFILE_AUTH_AUTHENTICBLIZZARD 5
|
||||
|
||||
#define SFILE_DIRECT_ENABLE_RELATIVE 1
|
||||
#define SFILE_DIRECT_ENABLE_NOPATH 2
|
||||
|
||||
#define SFILE_PLATFORM_ANY 0
|
||||
#define SFILE_PLATFORM_WIN32 1
|
||||
#define SFILE_PLATFORM_MAC 2
|
||||
|
||||
enum SARCHIVE_TYPE {
|
||||
SARCHIVE_MPQ,
|
||||
SARCHIVE_ZIP,
|
||||
};
|
||||
|
||||
enum SFILE_TYPE {
|
||||
SFILE_PLAIN,
|
||||
SFILE_COMPRESSED,
|
||||
SFILE_PAQ,
|
||||
SFILE_OLD_SFILE,
|
||||
SFILE_ZIP_FILE,
|
||||
};
|
||||
*/
|
||||
|
||||
int32_t STORMAPI SFileCloseArchive(HSARCHIVE handle);
|
||||
|
||||
int32_t STORMAPI SFileCloseFile(HSFILE handle);
|
||||
|
||||
uint32_t STORMAPI SFileGetFileSize(HSFILE handle, uint32_t* filesizehigh = nullptr);
|
||||
|
||||
int32_t STORMAPI SFileOpenArchive(const char* archivename, int32_t priority, uint32_t flags, HSARCHIVE* handle);
|
||||
|
||||
int32_t STORMAPI SFileOpenFileEx(HSARCHIVE archivehandle, const char* filename, uint32_t flags, HSFILE* handle);
|
||||
|
||||
int32_t STORMAPI SFileReadFile(HSFILE handle, void* buffer, uint32_t bytestoread, uint32_t* bytesread, LPOVERLAPPED overlapped);
|
||||
|
||||
uint32_t STORMAPI SFileGetFileSize(HSFILE handle, uint32_t* filesizehigh);
|
||||
int32_t STORMAPI SFileReadFile(HSFILE handle, void* buffer, uint32_t bytestoread, uint32_t* bytesread = nullptr, LPOVERLAPPED overlapped = nullptr);
|
||||
|
||||
uint32_t STORMAPI SFileSetFilePointer(HSFILE handle, int32_t distancetomove, int32_t* distancetomovehigh, uint32_t movemethod);
|
||||
|
||||
int32_t STORMAPI SFileCloseFile(HSFILE handle);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@ if(WHOA_TEST_STORMDLL)
|
|||
Error.cpp
|
||||
Event.cpp
|
||||
EventTest.cpp
|
||||
File.cpp
|
||||
FileTest.cpp
|
||||
Memory.cpp
|
||||
Region.cpp
|
||||
String.cpp
|
||||
|
|
@ -24,6 +26,8 @@ else()
|
|||
)
|
||||
endif()
|
||||
|
||||
file(GLOB TEST_FILES "fixture/*")
|
||||
|
||||
if(WHOA_SYSTEM_MAC)
|
||||
set_source_files_properties(${TEST_SOURCES}
|
||||
PROPERTIES COMPILE_FLAGS "-x objective-c++"
|
||||
|
|
@ -54,6 +58,14 @@ target_include_directories(StormTest
|
|||
${PROJECT_SOURCE_DIR}
|
||||
)
|
||||
|
||||
file(GLOB TEST_FILES "fixture/*")
|
||||
|
||||
add_custom_target(copy_test_files ALL
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||
${TEST_FILES}
|
||||
$<TARGET_FILE_DIR:StormTest>
|
||||
)
|
||||
|
||||
# Debug build options
|
||||
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
# GCC debug build options
|
||||
|
|
|
|||
401
test/File.cpp
Normal file
401
test/File.cpp
Normal file
|
|
@ -0,0 +1,401 @@
|
|||
#include "FileTest.hpp"
|
||||
|
||||
// most of these only pass against storm.dll for now
|
||||
#if defined(WHOA_TEST_STORMDLL)
|
||||
TEST_CASE("SFileCloseArchive", "[file]") {
|
||||
HSARCHIVE archive = nullptr;
|
||||
|
||||
SECTION("closes an archive") {
|
||||
SFileOpenArchive("wowtest1.mpq", 0, 0, &archive);
|
||||
REQUIRE(archive != nullptr);
|
||||
|
||||
HSFILE file;
|
||||
CHECK(SFileOpenFileEx(nullptr, "test.txt", 0, &file));
|
||||
CHECK(SFileCloseFile(file));
|
||||
|
||||
CHECK(SFileCloseArchive(archive) == 1);
|
||||
|
||||
CHECK_FALSE(SFileOpenFileEx(nullptr, "test.txt", 0, &file));
|
||||
}
|
||||
|
||||
// TODO determine how to test this
|
||||
// SECTION("doesn't delete if there is more than one reference") {}
|
||||
}
|
||||
|
||||
TEST_CASE("SFileCloseFile", "[file]") {
|
||||
HSFILE file = nullptr;
|
||||
|
||||
SECTION("closes a MPQ file") {
|
||||
file = ReadTestFileFromMpq();
|
||||
CHECK(SFileCloseFile(file) == 1);
|
||||
}
|
||||
|
||||
SECTION("closes a filesystem file") {
|
||||
file = ReadTestFileFromDisk();
|
||||
CHECK(SFileCloseFile(file) == 1);
|
||||
}
|
||||
|
||||
// TODO determine how to test this
|
||||
// SECTION("doesn't delete if there is more than one reference") {}
|
||||
}
|
||||
|
||||
TEST_CASE("SFileGetFileSize", "[file]") {
|
||||
HSARCHIVE archive;
|
||||
HSFILE file;
|
||||
|
||||
SECTION("retrieves MPQ file size") {
|
||||
SFileOpenArchive("wowtest1.mpq", 0, 0, &archive);
|
||||
|
||||
REQUIRE(SFileOpenFileEx(archive, "test2.txt", 0, &file));
|
||||
CHECK(SFileGetFileSize(file) == 13);
|
||||
|
||||
REQUIRE(SFileOpenFileEx(archive, "empty.txt", 0, &file));
|
||||
CHECK(SFileGetFileSize(file) == 0);
|
||||
|
||||
uint32_t filesizehigh = 1234;
|
||||
REQUIRE(SFileOpenFileEx(archive, "test.txt", 0, &file));
|
||||
CHECK(SFileGetFileSize(file, &filesizehigh) == 6);
|
||||
CHECK(filesizehigh == 0);
|
||||
}
|
||||
|
||||
SECTION("retrieves filesystem file size") {
|
||||
REQUIRE(SFileOpenFileEx(nullptr, "empty_diskonly.txt", SFILE_OPENFLAG_CHECKDISK, &file));
|
||||
CHECK(SFileGetFileSize(file) == 0);
|
||||
|
||||
uint32_t filesizehigh = 1234;
|
||||
REQUIRE(SFileOpenFileEx(nullptr, "test_diskonly.txt", SFILE_OPENFLAG_CHECKDISK, &file));
|
||||
CHECK(SFileGetFileSize(file, &filesizehigh) == 6);
|
||||
CHECK(filesizehigh == 0);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("SFileOpenArchive", "[file]") {
|
||||
HSARCHIVE mpq = nullptr;
|
||||
SErrSetLastError(ERROR_SUCCESS);
|
||||
|
||||
SECTION("opens a MPQ archive") {
|
||||
CHECK(SFileOpenArchive("wowtest1.mpq", 0, 0, &mpq) == 1);
|
||||
CHECK(mpq != nullptr);
|
||||
}
|
||||
|
||||
// TODO determine how to test this (something about CD ROM drives)
|
||||
// SECTION("fails if drive is inaccessible") {}
|
||||
|
||||
SECTION("fails if archive file is nonexistent") {
|
||||
mpq = reinterpret_cast<HSARCHIVE>(1234);
|
||||
CHECK_FALSE(SFileOpenArchive("nice_try.mpq", 0, 0, &mpq));
|
||||
|
||||
CHECK(mpq == nullptr);
|
||||
CHECK(SErrGetLastError() == ERROR_SUCCESS);
|
||||
}
|
||||
|
||||
SECTION("fails if archive file is too small") {
|
||||
mpq = reinterpret_cast<HSARCHIVE>(1234);
|
||||
CHECK_FALSE(SFileOpenArchive("bad_toosmall.mpq", 0, 0, &mpq));
|
||||
CHECK(mpq == nullptr);
|
||||
|
||||
CHECK(SErrGetLastError() == STORM_ERROR_NOT_ARCHIVE);
|
||||
}
|
||||
|
||||
SECTION("fails if using a directory") {
|
||||
mpq = reinterpret_cast<HSARCHIVE>(1234);
|
||||
CHECK_FALSE(SFileOpenArchive("directorytest", 0, 0, &mpq));
|
||||
CHECK(mpq == nullptr);
|
||||
|
||||
CHECK(SErrGetLastError() == ERROR_SUCCESS);
|
||||
}
|
||||
|
||||
SECTION("fails if archive header magic doesn't match") {
|
||||
mpq = reinterpret_cast<HSARCHIVE>(1234);
|
||||
CHECK_FALSE(SFileOpenArchive("bad_nomagic.mpq", 0, 0, &mpq));
|
||||
CHECK(mpq == nullptr);
|
||||
|
||||
CHECK(SErrGetLastError() == STORM_ERROR_NOT_ARCHIVE);
|
||||
}
|
||||
|
||||
SECTION("fails if archive header size doesn't match") {
|
||||
mpq = reinterpret_cast<HSARCHIVE>(1234);
|
||||
CHECK_FALSE(SFileOpenArchive("bad_headertoosmall.mpq", 0, 0, &mpq));
|
||||
CHECK(mpq == nullptr);
|
||||
|
||||
CHECK(SErrGetLastError() == STORM_ERROR_NOT_ARCHIVE);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("SFileOpenFileEx", "[file]") {
|
||||
SECTION("shared testcases") {
|
||||
OpenFileTestCase testcase = GENERATE(OpenFromDiskCase, OpenFromMPQCase);
|
||||
|
||||
INFO(testcase.info);
|
||||
HSARCHIVE archive = testcase.OpenArchiveFn();
|
||||
HSFILE file = nullptr;
|
||||
|
||||
SECTION("opens a file") {
|
||||
CHECK(SFileOpenFileEx(archive, "test.txt", testcase.flags, &file) == 1);
|
||||
CHECK(file != nullptr);
|
||||
CHECK(file != reinterpret_cast<HSFILE>(1234));
|
||||
}
|
||||
|
||||
SECTION("fails if file not found") {
|
||||
SErrSetLastError(ERROR_SUCCESS);
|
||||
file = reinterpret_cast<HSFILE>(1234);
|
||||
CHECK_FALSE(SFileOpenFileEx(archive, "nice try buddy but your file is in another castle", testcase.flags, &file));
|
||||
CHECK(file == nullptr);
|
||||
CHECK(SErrGetLastError() == ERROR_FILE_NOT_FOUND);
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("fails when trying to open a directory") {
|
||||
SErrSetLastError(ERROR_SUCCESS);
|
||||
HSFILE file = reinterpret_cast<HSFILE>(1234);
|
||||
CHECK_FALSE(SFileOpenFileEx(nullptr, "directorytest", SFILE_OPENFLAG_CHECKDISK, &file));
|
||||
CHECK(file == nullptr);
|
||||
CHECK(SErrGetLastError() == ERROR_FILE_NOT_FOUND);
|
||||
}
|
||||
|
||||
SECTION("mpq testcases") {
|
||||
HSARCHIVE mpq1, mpq2, mpq3;
|
||||
HSFILE file;
|
||||
|
||||
SECTION("opens the highest priority file from all MPQs") {
|
||||
SFileOpenArchive("wowtest1.mpq", 100, 0, &mpq1);
|
||||
SFileOpenArchive("wowtest2.mpq", 500, 0, &mpq2);
|
||||
SFileOpenArchive("wowtest3.mpq", 400, 0, &mpq3);
|
||||
|
||||
CHECK(SFileOpenFileEx(nullptr, "test.txt", 0, &file) == 1);
|
||||
|
||||
char result[16] = {};
|
||||
SFileReadFile(file, result, sizeof(result));
|
||||
|
||||
CHECK(std::string(result) == "skibbidy");
|
||||
}
|
||||
|
||||
SECTION("opens the most recently opened file from same priority MPQs") {
|
||||
SFileOpenArchive("wowtest1.mpq", 100, 0, &mpq1);
|
||||
SFileOpenArchive("wowtest2.mpq", 500, 0, &mpq2);
|
||||
SFileOpenArchive("wowtest3.mpq", 500, 0, &mpq3);
|
||||
|
||||
CHECK(SFileOpenFileEx(nullptr, "test.txt", 0, &file) == 1);
|
||||
|
||||
char result[16] = {};
|
||||
SFileReadFile(file, result, sizeof(result));
|
||||
|
||||
CHECK(std::string(result) == "rizz");
|
||||
}
|
||||
|
||||
// TODO implement after adding SFileSetLocale
|
||||
// SECTION("opens the file for the currently selected locale") {}
|
||||
|
||||
SECTION("fails if file not found in target MPQ") {
|
||||
SFileOpenArchive("wowtest1.mpq", 100, 0, &mpq1);
|
||||
SFileOpenArchive("wowtest2.mpq", 500, 0, &mpq2);
|
||||
SFileOpenArchive("wowtest3.mpq", 400, 0, &mpq3);
|
||||
|
||||
CHECK(SFileOpenFileEx(nullptr, "test2.txt", 0, &file) == 1);
|
||||
SFileCloseFile(file);
|
||||
|
||||
SErrSetLastError(ERROR_SUCCESS);
|
||||
CHECK_FALSE(SFileOpenFileEx(mpq3, "test2.txt", 0, &file));
|
||||
CHECK(SErrGetLastError() == ERROR_FILE_NOT_FOUND);
|
||||
}
|
||||
|
||||
SECTION("fails if file not found in any MPQ") {
|
||||
SFileOpenArchive("wowtest1.mpq", 100, 0, &mpq1);
|
||||
SFileOpenArchive("wowtest2.mpq", 500, 0, &mpq2);
|
||||
SFileOpenArchive("wowtest3.mpq", 400, 0, &mpq3);
|
||||
|
||||
SErrSetLastError(ERROR_SUCCESS);
|
||||
CHECK_FALSE(SFileOpenFileEx(nullptr, "yep not here", 0, &file));
|
||||
CHECK(SErrGetLastError() == ERROR_FILE_NOT_FOUND);
|
||||
}
|
||||
|
||||
SECTION("can open attributes file") {
|
||||
SFileOpenArchive("wowtest1.mpq", 100, 0, &mpq1);
|
||||
CHECK(SFileOpenFileEx(nullptr, "(attributes)", 0, &file) == 1);
|
||||
}
|
||||
|
||||
SECTION("can open listfile") {
|
||||
SFileOpenArchive("wowtest1.mpq", 100, 0, &mpq1);
|
||||
CHECK(SFileOpenFileEx(nullptr, "(listfile)", 0, &file) == 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("SFileReadFile", "[file]") {
|
||||
SECTION("shared testcases") {
|
||||
ReadFileTestCase testcase = GENERATE(ReadFromDiskCase, ReadFromMPQCase);
|
||||
|
||||
INFO(testcase.info);
|
||||
HSFILE file = testcase.OpenFileFn();
|
||||
REQUIRE(file != nullptr);
|
||||
|
||||
SECTION("reads a file") {
|
||||
char buffer[32] = {};
|
||||
CHECK(SFileReadFile(file, buffer, 6, nullptr, nullptr) == 1);
|
||||
CHECK(std::string(buffer) == "catdog");
|
||||
}
|
||||
|
||||
SECTION("reads partial file if bytestoread is too small") {
|
||||
char buffer[4] = "";
|
||||
CHECK(SFileReadFile(file, &buffer, 3, nullptr, nullptr) == 1);
|
||||
CHECK(std::string(buffer) == "cat");
|
||||
}
|
||||
|
||||
SECTION("continues reading from the last stored position") {
|
||||
char buffer[4] = "";
|
||||
CHECK(SFileReadFile(file, &buffer, 3, nullptr, nullptr) == 1);
|
||||
CHECK(SFileReadFile(file, &buffer, 3, nullptr, nullptr) == 1);
|
||||
CHECK(std::string(buffer) == "dog");
|
||||
}
|
||||
|
||||
SECTION("continues reading from an explicitly set position") {
|
||||
char buffer[4] = "";
|
||||
SFileSetFilePointer(file, 3, nullptr, SFILE_BEGIN);
|
||||
CHECK(SFileReadFile(file, &buffer, 3, nullptr, nullptr) == 1);
|
||||
CHECK(std::string(buffer) == "dog");
|
||||
}
|
||||
|
||||
SECTION("succeeds if bytestoread is 0") {
|
||||
char buffer;
|
||||
CHECK(SFileReadFile(file, &buffer, 0, nullptr, nullptr) == 1);
|
||||
|
||||
uint32_t read = 42;
|
||||
CHECK(SFileReadFile(file, &buffer, 0, &read, nullptr) == 1);
|
||||
CHECK(read == 0);
|
||||
}
|
||||
|
||||
SECTION("succeeds if bytestoread is 0 past eof") {
|
||||
char buffer[8];
|
||||
CHECK_FALSE(SFileReadFile(file, &buffer, 8, nullptr, nullptr));
|
||||
|
||||
uint32_t read = 42;
|
||||
CHECK(SFileReadFile(file, &buffer, 0, &read, nullptr) == 1);
|
||||
CHECK(read == 0);
|
||||
}
|
||||
|
||||
SECTION("fails when reading past end of file") {
|
||||
char buffer[8] = "";
|
||||
CHECK(SFileReadFile(file, &buffer, 6, nullptr, nullptr) == 1);
|
||||
CHECK(std::string(buffer) == "catdog");
|
||||
|
||||
SErrSetLastError(0);
|
||||
CHECK_FALSE(SFileReadFile(file, &buffer, 1, nullptr, nullptr));
|
||||
CHECK(SErrGetLastError() == testcase.eofcode);
|
||||
|
||||
CHECK(std::string(buffer) == "catdog");
|
||||
}
|
||||
|
||||
SECTION("fails if bytestoread is larger than file size when reading from disk") {
|
||||
char buffer[32] = "";
|
||||
|
||||
SErrSetLastError(0);
|
||||
CHECK_FALSE(SFileReadFile(file, buffer, sizeof(buffer), nullptr, nullptr));
|
||||
CHECK(SErrGetLastError() == testcase.eofcode);
|
||||
|
||||
CHECK(std::string(buffer) == "catdog");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("SFileSetFilePointer", "[file]") {
|
||||
SECTION("shared testcases") {
|
||||
ReadFileTestCase testcase = GENERATE(ReadFromDiskCase, ReadFromMPQCase);
|
||||
|
||||
INFO(testcase.info);
|
||||
HSFILE file = testcase.OpenFileFn();
|
||||
REQUIRE(file != nullptr);
|
||||
|
||||
SECTION("sets position from beginning") {
|
||||
CHECK(SFileSetFilePointer(file, 2, nullptr, SFILE_BEGIN) == 2);
|
||||
CHECK(SFileSetFilePointer(file, 0, nullptr, SFILE_BEGIN) == 0);
|
||||
CHECK(SFileSetFilePointer(file, 5, nullptr, SFILE_BEGIN) == 5);
|
||||
}
|
||||
|
||||
SECTION("returns the cursor position") {
|
||||
CHECK(SFileSetFilePointer(file, 2, nullptr, SFILE_BEGIN) == 2);
|
||||
CHECK(SFileSetFilePointer(file, 1, nullptr, SFILE_BEGIN) == 1);
|
||||
CHECK(SFileSetFilePointer(file, 5, nullptr, SFILE_BEGIN) == 5);
|
||||
CHECK(SFileSetFilePointer(file, -4, nullptr, SFILE_CURRENT) == 1);
|
||||
CHECK(SFileSetFilePointer(file, 0, nullptr, SFILE_BEGIN) == 0);
|
||||
}
|
||||
|
||||
SECTION("sets position from current") {
|
||||
CHECK(SFileSetFilePointer(file, 0, nullptr, SFILE_CURRENT) == 0);
|
||||
CHECK(SFileSetFilePointer(file, 1, nullptr, SFILE_CURRENT) == 1);
|
||||
CHECK(SFileSetFilePointer(file, 1, nullptr, SFILE_CURRENT) == 2);
|
||||
CHECK(SFileSetFilePointer(file, 1, nullptr, SFILE_CURRENT) == 3);
|
||||
CHECK(SFileSetFilePointer(file, 0, nullptr, SFILE_CURRENT) == 3);
|
||||
CHECK(SFileSetFilePointer(file, -2, nullptr, SFILE_CURRENT) == 1);
|
||||
CHECK(SFileSetFilePointer(file, -1, nullptr, SFILE_CURRENT) == 0);
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("cases from filesystem") {
|
||||
// Probably Windows specific, return values are directly from WinAPI calls
|
||||
// TODO compare with Mac build results
|
||||
HSFILE file = ReadTestFileFromDisk();
|
||||
REQUIRE(file != nullptr);
|
||||
|
||||
SECTION("sets position from beginning out of bounds") {
|
||||
CHECK(SFileSetFilePointer(file, -1, nullptr, SFILE_BEGIN) == -1);
|
||||
CHECK(SFileSetFilePointer(file, -100, nullptr, SFILE_BEGIN) == -1);
|
||||
CHECK(SFileSetFilePointer(file, 6, nullptr, SFILE_BEGIN) == 6);
|
||||
CHECK(SFileSetFilePointer(file, 100, nullptr, SFILE_BEGIN) == 100);
|
||||
}
|
||||
|
||||
SECTION("sets position from current out of bounds") {
|
||||
CHECK(SFileSetFilePointer(file, -1, nullptr, SFILE_CURRENT) == -1);
|
||||
CHECK(SFileSetFilePointer(file, -100, nullptr, SFILE_CURRENT) == -1);
|
||||
CHECK(SFileSetFilePointer(file, 106, nullptr, SFILE_CURRENT) == 106);
|
||||
CHECK(SFileSetFilePointer(file, 100, nullptr, SFILE_CURRENT) == 206);
|
||||
}
|
||||
|
||||
SECTION("sets position from end") {
|
||||
CHECK(SFileSetFilePointer(file, -5, nullptr, SFILE_END) == 1);
|
||||
CHECK(SFileSetFilePointer(file, -2, nullptr, SFILE_END) == 4);
|
||||
CHECK(SFileSetFilePointer(file, -1, nullptr, SFILE_END) == 5);
|
||||
CHECK(SFileSetFilePointer(file, 0, nullptr, SFILE_END) == 6);
|
||||
}
|
||||
|
||||
SECTION("sets position from end out of bounds") {
|
||||
CHECK(SFileSetFilePointer(file, -100, nullptr, SFILE_END) == -1);
|
||||
CHECK(SFileSetFilePointer(file, -10, nullptr, SFILE_END) == -1);
|
||||
CHECK(SFileSetFilePointer(file, 1, nullptr, SFILE_END) == 7);
|
||||
CHECK(SFileSetFilePointer(file, 5, nullptr, SFILE_END) == 11);
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("cases from MPQ") {
|
||||
HSFILE file = ReadTestFileFromMpq();
|
||||
REQUIRE(file != nullptr);
|
||||
|
||||
SECTION("sets position from beginning out of bounds") {
|
||||
CHECK(SFileSetFilePointer(file, -1, nullptr, SFILE_BEGIN) == 5);
|
||||
CHECK(SFileSetFilePointer(file, -100, nullptr, SFILE_BEGIN) == 5);
|
||||
CHECK(SFileSetFilePointer(file, 6, nullptr, SFILE_BEGIN) == 5);
|
||||
CHECK(SFileSetFilePointer(file, 100, nullptr, SFILE_BEGIN) == 5);
|
||||
}
|
||||
|
||||
SECTION("sets position from current out of bounds") {
|
||||
CHECK(SFileSetFilePointer(file, -1, nullptr, SFILE_CURRENT) == 0);
|
||||
CHECK(SFileSetFilePointer(file, -100, nullptr, SFILE_CURRENT) == 0);
|
||||
CHECK(SFileSetFilePointer(file, 106, nullptr, SFILE_CURRENT) == 5);
|
||||
CHECK(SFileSetFilePointer(file, 100, nullptr, SFILE_CURRENT) == 5);
|
||||
}
|
||||
|
||||
SECTION("sets position from end") {
|
||||
CHECK(SFileSetFilePointer(file, -5, nullptr, SFILE_END) == 1);
|
||||
CHECK(SFileSetFilePointer(file, -2, nullptr, SFILE_END) == 4);
|
||||
CHECK(SFileSetFilePointer(file, -1, nullptr, SFILE_END) == 5);
|
||||
CHECK(SFileSetFilePointer(file, 0, nullptr, SFILE_END) == 5);
|
||||
}
|
||||
|
||||
SECTION("sets position from end out of bounds") {
|
||||
CHECK(SFileSetFilePointer(file, -100, nullptr, SFILE_END) == 0);
|
||||
CHECK(SFileSetFilePointer(file, -10, nullptr, SFILE_END) == 0);
|
||||
CHECK(SFileSetFilePointer(file, 1, nullptr, SFILE_END) == 5);
|
||||
CHECK(SFileSetFilePointer(file, 5, nullptr, SFILE_END) == 5);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
33
test/FileTest.cpp
Normal file
33
test/FileTest.cpp
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
#include "FileTest.hpp"
|
||||
|
||||
HSARCHIVE OpenNullArchive() {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
HSARCHIVE OpenTestArchive() {
|
||||
HSARCHIVE archive = nullptr;
|
||||
SFileOpenArchive("wowtest1.mpq", 0, 0, &archive);
|
||||
REQUIRE(archive != nullptr);
|
||||
return archive;
|
||||
}
|
||||
|
||||
HSFILE ReadTestFileFromDisk() {
|
||||
HSFILE file = nullptr;
|
||||
SFileOpenFileEx(nullptr, "test_diskonly.txt", SFILE_OPENFLAG_CHECKDISK, &file);
|
||||
return file;
|
||||
}
|
||||
|
||||
HSFILE ReadTestFileFromMpq() {
|
||||
HSARCHIVE archive = nullptr;
|
||||
SFileOpenArchive("wowtest1.mpq", 0, 0, &archive);
|
||||
|
||||
HSFILE file = nullptr;
|
||||
SFileOpenFileEx(archive, "test.txt", 0, &file);
|
||||
return file;
|
||||
}
|
||||
|
||||
OpenFileTestCase OpenFromDiskCase{ "file from disk", OpenNullArchive, SFILE_OPENFLAG_CHECKDISK };
|
||||
OpenFileTestCase OpenFromMPQCase{ "file from MPQ", OpenTestArchive, 0 };
|
||||
|
||||
ReadFileTestCase ReadFromDiskCase{ "file from disk", ReadTestFileFromDisk, ERROR_SUCCESS };
|
||||
ReadFileTestCase ReadFromMPQCase{ "file from MPQ", ReadTestFileFromMpq, ERROR_HANDLE_EOF };
|
||||
29
test/FileTest.hpp
Normal file
29
test/FileTest.hpp
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
#include "Test.hpp"
|
||||
#include "storm/Error.hpp"
|
||||
#include "storm/File.hpp"
|
||||
|
||||
#include <string>
|
||||
|
||||
struct OpenFileTestCase {
|
||||
std::string info;
|
||||
HSARCHIVE (*OpenArchiveFn)();
|
||||
uint32_t flags;
|
||||
};
|
||||
|
||||
struct ReadFileTestCase {
|
||||
std::string info;
|
||||
HSFILE (*OpenFileFn)();
|
||||
uint32_t eofcode;
|
||||
};
|
||||
|
||||
HSARCHIVE OpenNullArchive();
|
||||
HSARCHIVE OpenTestArchive();
|
||||
|
||||
HSFILE ReadTestFileFromDisk();
|
||||
HSFILE ReadTestFileFromMpq();
|
||||
|
||||
extern OpenFileTestCase OpenFromDiskCase;
|
||||
extern OpenFileTestCase OpenFromMPQCase;
|
||||
|
||||
extern ReadFileTestCase ReadFromDiskCase;
|
||||
extern ReadFileTestCase ReadFromMPQCase;
|
||||
BIN
test/fixture/bad_headertoosmall.mpq
Normal file
BIN
test/fixture/bad_headertoosmall.mpq
Normal file
Binary file not shown.
BIN
test/fixture/bad_nomagic.mpq
Normal file
BIN
test/fixture/bad_nomagic.mpq
Normal file
Binary file not shown.
BIN
test/fixture/bad_toosmall.mpq
Normal file
BIN
test/fixture/bad_toosmall.mpq
Normal file
Binary file not shown.
BIN
test/fixture/bad_wrongsizes.mpq
Normal file
BIN
test/fixture/bad_wrongsizes.mpq
Normal file
Binary file not shown.
BIN
test/fixture/broken4.mpq
Normal file
BIN
test/fixture/broken4.mpq
Normal file
Binary file not shown.
0
test/fixture/directorytest/.gitkeep
Normal file
0
test/fixture/directorytest/.gitkeep
Normal file
0
test/fixture/empty_diskonly.txt
Normal file
0
test/fixture/empty_diskonly.txt
Normal file
1
test/fixture/test.txt
Normal file
1
test/fixture/test.txt
Normal file
|
|
@ -0,0 +1 @@
|
|||
catdog
|
||||
1
test/fixture/test_diskonly.txt
Normal file
1
test/fixture/test_diskonly.txt
Normal file
|
|
@ -0,0 +1 @@
|
|||
catdog
|
||||
BIN
test/fixture/wowtest1.mpq
Normal file
BIN
test/fixture/wowtest1.mpq
Normal file
Binary file not shown.
BIN
test/fixture/wowtest2.mpq
Normal file
BIN
test/fixture/wowtest2.mpq
Normal file
Binary file not shown.
BIN
test/fixture/wowtest3.mpq
Normal file
BIN
test/fixture/wowtest3.mpq
Normal file
Binary file not shown.
|
|
@ -87,8 +87,8 @@ EXPORTS
|
|||
|
||||
; File
|
||||
;SFileAuthenticateArchive @251 NONAME
|
||||
;SFileCloseArchive @252 NONAME
|
||||
;SFileCloseFile @253 NONAME
|
||||
SFileCloseArchive @252 NONAME
|
||||
SFileCloseFile @253 NONAME
|
||||
;SFileDdaBegin @254 NONAME
|
||||
;SFileDdaBeginEx @255 NONAME
|
||||
;SFileDdaDestroy @256 NONAME
|
||||
|
|
@ -100,13 +100,13 @@ EXPORTS
|
|||
;SFileDestroy @262 NONAME
|
||||
;SFileEnableDirectAccess @263 NONAME
|
||||
;SFileGetFileArchive @264 NONAME
|
||||
;SFileGetFileSize @265 NONAME
|
||||
;SFileOpenArchive @266 NONAME
|
||||
SFileGetFileSize @265 NONAME
|
||||
SFileOpenArchive @266 NONAME
|
||||
;SFileOpenFile @267 NONAME
|
||||
;SFileOpenFileEx @268 NONAME
|
||||
;SFileReadFile @269 NONAME
|
||||
SFileOpenFileEx @268 NONAME
|
||||
SFileReadFile @269 NONAME
|
||||
;SFileSetBasePath @270 NONAME
|
||||
;SFileSetFilePointer @271 NONAME
|
||||
SFileSetFilePointer @271 NONAME
|
||||
;SFileSetLocale @272 NONAME
|
||||
;SFileGetBasePath @273 NONAME
|
||||
;SFileSetIoErrorMode @274 NONAME
|
||||
|
|
@ -280,7 +280,7 @@ EXPORTS
|
|||
;SErrGetErrorStr @462 NONAME
|
||||
SErrGetLastError @463 NONAME
|
||||
;SErrRegisterMessageSource @464 NONAME
|
||||
;SErrSetLastError @465 NONAME
|
||||
SErrSetLastError @465 NONAME
|
||||
;SErrReportNamedResourceLeak @466 NONAME
|
||||
;SErrReportResourceLeak @467 NONAME
|
||||
SErrSuppressErrors @468 NONAME
|
||||
|
|
|
|||
|
|
@ -55,6 +55,16 @@ int32_t STORMAPI SEvtRegisterHandler(uint32_t, uint32_t, uint32_t, uint32_t, SEV
|
|||
int32_t STORMAPI SEvtUnregisterHandler(uint32_t, uint32_t, uint32_t, SEVTHANDLER) { return 0; }
|
||||
int32_t STORMAPI SEvtUnregisterType(uint32_t, uint32_t) { return 0; }
|
||||
|
||||
#include <storm/File.hpp>
|
||||
|
||||
int32_t STORMAPI SFileCloseArchive(HSARCHIVE) { return 0; }
|
||||
int32_t STORMAPI SFileCloseFile(HSFILE) { return 0; }
|
||||
uint32_t STORMAPI SFileGetFileSize(HSFILE, uint32_t*) { return 0; }
|
||||
int32_t STORMAPI SFileOpenArchive(const char*, int32_t, uint32_t, HSARCHIVE*) { return 0; }
|
||||
int32_t STORMAPI SFileOpenFileEx(HSARCHIVE, const char*, uint32_t, HSFILE*) { return 0; }
|
||||
int32_t STORMAPI SFileReadFile(HSFILE, void*, uint32_t, uint32_t*, LPOVERLAPPED) { return 0; }
|
||||
uint32_t STORMAPI SFileSetFilePointer(HSFILE, int32_t, int32_t*, uint32_t) { return 0; }
|
||||
|
||||
#include <storm/Memory.hpp>
|
||||
|
||||
void* STORMAPI SMemAlloc(size_t, const char*, int32_t, uint32_t) { return 0; }
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue