mirror of
https://github.com/QuasarApp/zip.git
synced 2025-04-27 04:54:30 +00:00
Use minunit for testing (#173)
This commit is contained in:
parent
b38024b5dc
commit
9cf2857e82
@ -45,7 +45,7 @@ if (MSVC)
|
||||
elseif ("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU" OR
|
||||
"${CMAKE_C_COMPILER_ID}" STREQUAL "Clang" OR
|
||||
"${CMAKE_C_COMPILER_ID}" STREQUAL "AppleClang")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu99 -Wall -Wextra -Werror -pedantic")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu99 -Wall -Wextra -Werror -pedantic -Wno-deprecated")
|
||||
endif (MSVC)
|
||||
|
||||
####
|
||||
|
68
src/zip.h
68
src/zip.h
@ -270,36 +270,17 @@ zip_entry_extract(struct zip_t *zip,
|
||||
*/
|
||||
extern int zip_total_entries(struct zip_t *zip);
|
||||
|
||||
/**
|
||||
* Creates a new archive and puts files into a single zip archive.
|
||||
*
|
||||
* @param zipname zip archive file.
|
||||
* @param filenames input files.
|
||||
* @param len: number of input files.
|
||||
*
|
||||
* @return the return code - 0 on success, negative number (< 0) on error.
|
||||
*/
|
||||
extern int zip_create(const char *zipname, const char *filenames[], size_t len);
|
||||
|
||||
/**
|
||||
* Extracts a zip archive file into directory.
|
||||
* Deletes zip archive entries.
|
||||
*
|
||||
* If on_extract_entry is not NULL, the callback will be called after
|
||||
* successfully extracted each zip entry.
|
||||
* Returning a negative value from the callback will cause abort and return an
|
||||
* error. The last argument (void *arg) is optional, which you can use to pass
|
||||
* data to the on_extract_entry callback.
|
||||
*
|
||||
* @param zipname zip archive file.
|
||||
* @param dir output directory.
|
||||
* @param on_extract_entry on extract callback.
|
||||
* @param arg opaque pointer.
|
||||
*
|
||||
* @return the return code - 0 on success, negative number (< 0) on error.
|
||||
* @param zip zip archive handler.
|
||||
* @param entries array of zip archive entries to be deleted.
|
||||
* @param len the number of entries to be deleted.
|
||||
* @return the number of deleted entries, or negative number (< 0) on error.
|
||||
*/
|
||||
extern int zip_extract(const char *zipname, const char *dir,
|
||||
int (*on_extract_entry)(const char *filename, void *arg),
|
||||
void *arg);
|
||||
extern int zip_entries_delete(struct zip_t *zip, char *const entries[],
|
||||
size_t len);
|
||||
|
||||
/**
|
||||
* Extracts a zip archive stream into directory.
|
||||
@ -355,15 +336,36 @@ extern ssize_t zip_stream_copy(struct zip_t *zip, void **buf, ssize_t *bufsize);
|
||||
extern void zip_stream_close(struct zip_t *zip);
|
||||
|
||||
/**
|
||||
* Deletes zip archive entries.
|
||||
* Creates a new archive and puts files into a single zip archive.
|
||||
*
|
||||
* @param zip zip archive handler.
|
||||
* @param entries array of zip archive entries to be deleted.
|
||||
* @param len the number of entries to be deleted.
|
||||
* @return the number of deleted entries, or negative number (< 0) on error.
|
||||
* @param zipname zip archive file.
|
||||
* @param filenames input files.
|
||||
* @param len: number of input files.
|
||||
*
|
||||
* @return the return code - 0 on success, negative number (< 0) on error.
|
||||
*/
|
||||
extern int zip_entries_delete(struct zip_t *zip, char *const entries[],
|
||||
size_t len);
|
||||
extern int zip_create(const char *zipname, const char *filenames[], size_t len);
|
||||
|
||||
/**
|
||||
* Extracts a zip archive file into directory.
|
||||
*
|
||||
* If on_extract_entry is not NULL, the callback will be called after
|
||||
* successfully extracted each zip entry.
|
||||
* Returning a negative value from the callback will cause abort and return an
|
||||
* error. The last argument (void *arg) is optional, which you can use to pass
|
||||
* data to the on_extract_entry callback.
|
||||
*
|
||||
* @param zipname zip archive file.
|
||||
* @param dir output directory.
|
||||
* @param on_extract_entry on extract callback.
|
||||
* @param arg opaque pointer.
|
||||
*
|
||||
* @return the return code - 0 on success, negative number (< 0) on error.
|
||||
*/
|
||||
extern int zip_extract(const char *zipname, const char *dir,
|
||||
int (*on_extract_entry)(const char *filename, void *arg),
|
||||
void *arg);
|
||||
|
||||
/** @} */
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -1,11 +1,38 @@
|
||||
cmake_minimum_required(VERSION 3.4)
|
||||
|
||||
# test
|
||||
set(test_out test.out)
|
||||
# tests
|
||||
set(test_write_out test_write.out)
|
||||
add_executable(${test_write_out} test_write.c)
|
||||
target_link_libraries(${test_write_out} zip)
|
||||
add_test(NAME ${test_write_out} COMMAND ${test_write_out})
|
||||
set(test_write_out ${test_write_out} PARENT_SCOPE)
|
||||
|
||||
add_executable(${test_out} test.c)
|
||||
target_link_libraries(${test_out} zip)
|
||||
set(test_append_out test_append.out)
|
||||
add_executable(${test_append_out} test_append.c)
|
||||
target_link_libraries(${test_append_out} zip)
|
||||
add_test(NAME ${test_append_out} COMMAND ${test_append_out})
|
||||
set(test_append_out ${test_append_out} PARENT_SCOPE)
|
||||
|
||||
add_test(NAME ${test_out} COMMAND ${test_out})
|
||||
set(test_read_out test_read.out)
|
||||
add_executable(${test_read_out} test_read.c)
|
||||
target_link_libraries(${test_read_out} zip)
|
||||
add_test(NAME ${test_read_out} COMMAND ${test_read_out})
|
||||
set(test_read_out ${test_read_out} PARENT_SCOPE)
|
||||
|
||||
set(test_out ${test_out} PARENT_SCOPE)
|
||||
set(test_extract_out test_extract.out)
|
||||
add_executable(${test_extract_out} test_extract.c)
|
||||
target_link_libraries(${test_extract_out} zip)
|
||||
add_test(NAME ${test_extract_out} COMMAND ${test_extract_out})
|
||||
set(test_extract_out ${test_extract_out} PARENT_SCOPE)
|
||||
|
||||
set(test_entry_out test_entry.out)
|
||||
add_executable(${test_entry_out} test_entry.c)
|
||||
target_link_libraries(${test_entry_out} zip)
|
||||
add_test(NAME ${test_entry_out} COMMAND ${test_entry_out})
|
||||
set(test_entry_out ${test_entry_out} PARENT_SCOPE)
|
||||
|
||||
set(test_permissions_out test_permissions.out)
|
||||
add_executable(${test_permissions_out} test_permissions.c)
|
||||
target_link_libraries(${test_permissions_out} zip)
|
||||
add_test(NAME ${test_permissions_out} COMMAND ${test_permissions_out})
|
||||
set(test_permissions_out ${test_permissions_out} PARENT_SCOPE)
|
||||
|
370
test/minunit.h
Normal file
370
test/minunit.h
Normal file
@ -0,0 +1,370 @@
|
||||
/*
|
||||
* Copyright (c) 2012 David Siñuela Pastor, siu.4coders@gmail.com
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#ifndef MINUNIT_MINUNIT_H
|
||||
#define MINUNIT_MINUNIT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32)
|
||||
#include <Windows.h>
|
||||
#if defined(_MSC_VER) && _MSC_VER < 1900
|
||||
#define snprintf _snprintf
|
||||
#define __func__ __FUNCTION__
|
||||
#endif
|
||||
|
||||
#elif defined(__unix__) || defined(__unix) || defined(unix) || \
|
||||
(defined(__APPLE__) && defined(__MACH__))
|
||||
|
||||
/* Change POSIX C SOURCE version for pure c99 compilers */
|
||||
#if !defined(_POSIX_C_SOURCE) || _POSIX_C_SOURCE < 200112L
|
||||
#undef _POSIX_C_SOURCE
|
||||
#define _POSIX_C_SOURCE 200112L
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
#include <sys/resource.h>
|
||||
#include <sys/time.h> /* gethrtime(), gettimeofday() */
|
||||
#include <sys/times.h>
|
||||
#include <time.h> /* clock_gettime(), time() */
|
||||
#include <unistd.h> /* POSIX flags */
|
||||
|
||||
#if defined(__MACH__) && defined(__APPLE__)
|
||||
#include <mach/mach.h>
|
||||
#include <mach/mach_time.h>
|
||||
#endif
|
||||
|
||||
#if __GNUC__ >= 5 && !defined(__STDC_VERSION__)
|
||||
#define __func__ __extension__ __FUNCTION__
|
||||
#endif
|
||||
|
||||
#else
|
||||
#error "Unable to define timers for an unknown OS."
|
||||
#endif
|
||||
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/* Maximum length of last message */
|
||||
#define MINUNIT_MESSAGE_LEN 1024
|
||||
/* Accuracy with which floats are compared */
|
||||
#define MINUNIT_EPSILON 1E-12
|
||||
|
||||
/* Misc. counters */
|
||||
static int minunit_run = 0;
|
||||
static int minunit_assert = 0;
|
||||
static int minunit_fail = 0;
|
||||
static int minunit_status = 0;
|
||||
|
||||
/* Timers */
|
||||
static double minunit_real_timer = 0;
|
||||
static double minunit_proc_timer = 0;
|
||||
|
||||
/* Last message */
|
||||
static char minunit_last_message[MINUNIT_MESSAGE_LEN];
|
||||
|
||||
/* Test setup and teardown function pointers */
|
||||
static void (*minunit_setup)(void) = NULL;
|
||||
static void (*minunit_teardown)(void) = NULL;
|
||||
|
||||
/* Definitions */
|
||||
#define MU_TEST(method_name) static void method_name(void)
|
||||
#define MU_TEST_SUITE(suite_name) static void suite_name(void)
|
||||
|
||||
#define MU__SAFE_BLOCK(block) \
|
||||
do { \
|
||||
block \
|
||||
} while (0)
|
||||
|
||||
/* Run test suite and unset setup and teardown functions */
|
||||
#define MU_RUN_SUITE(suite_name) \
|
||||
MU__SAFE_BLOCK(suite_name(); minunit_setup = NULL; minunit_teardown = NULL;)
|
||||
|
||||
/* Configure setup and teardown functions */
|
||||
#define MU_SUITE_CONFIGURE(setup_fun, teardown_fun) \
|
||||
MU__SAFE_BLOCK(minunit_setup = setup_fun; minunit_teardown = teardown_fun;)
|
||||
|
||||
/* Test runner */
|
||||
#define MU_RUN_TEST(test) \
|
||||
MU__SAFE_BLOCK( \
|
||||
if (minunit_real_timer == 0 && minunit_proc_timer == 0) { \
|
||||
minunit_real_timer = mu_timer_real(); \
|
||||
minunit_proc_timer = mu_timer_cpu(); \
|
||||
} if (minunit_setup) (*minunit_setup)(); \
|
||||
minunit_status = 0; test(); minunit_run++; if (minunit_status) { \
|
||||
minunit_fail++; \
|
||||
printf("F"); \
|
||||
printf("\n%s\n", minunit_last_message); \
|
||||
} fflush(stdout); \
|
||||
if (minunit_teardown)(*minunit_teardown)();)
|
||||
|
||||
/* Report */
|
||||
#define MU_REPORT() \
|
||||
MU__SAFE_BLOCK( \
|
||||
double minunit_end_real_timer; double minunit_end_proc_timer; \
|
||||
printf("\n\n%d tests, %d assertions, %d failures\n", minunit_run, \
|
||||
minunit_assert, minunit_fail); \
|
||||
minunit_end_real_timer = mu_timer_real(); \
|
||||
minunit_end_proc_timer = mu_timer_cpu(); \
|
||||
printf("\nFinished in %.8f seconds (real) %.8f seconds (proc)\n\n", \
|
||||
minunit_end_real_timer - minunit_real_timer, \
|
||||
minunit_end_proc_timer - minunit_proc_timer);)
|
||||
#define MU_EXIT_CODE minunit_fail
|
||||
|
||||
/* Assertions */
|
||||
#define mu_check(test) \
|
||||
MU__SAFE_BLOCK( \
|
||||
minunit_assert++; if (!(test)) { \
|
||||
snprintf(minunit_last_message, MINUNIT_MESSAGE_LEN, \
|
||||
"%s failed:\n\t%s:%d: %s", __func__, __FILE__, __LINE__, \
|
||||
#test); \
|
||||
minunit_status = 1; \
|
||||
return; \
|
||||
} else { printf("."); })
|
||||
|
||||
#define mu_fail(message) \
|
||||
MU__SAFE_BLOCK(minunit_assert++; \
|
||||
snprintf(minunit_last_message, MINUNIT_MESSAGE_LEN, \
|
||||
"%s failed:\n\t%s:%d: %s", __func__, __FILE__, \
|
||||
__LINE__, message); \
|
||||
minunit_status = 1; return;)
|
||||
|
||||
#define mu_assert(test, message) \
|
||||
MU__SAFE_BLOCK( \
|
||||
minunit_assert++; if (!(test)) { \
|
||||
snprintf(minunit_last_message, MINUNIT_MESSAGE_LEN, \
|
||||
"%s failed:\n\t%s:%d: %s", __func__, __FILE__, __LINE__, \
|
||||
message); \
|
||||
minunit_status = 1; \
|
||||
return; \
|
||||
} else { printf("."); })
|
||||
|
||||
#define mu_assert_int_eq(expected, result) \
|
||||
MU__SAFE_BLOCK( \
|
||||
int minunit_tmp_e; int minunit_tmp_r; minunit_assert++; \
|
||||
minunit_tmp_e = (expected); minunit_tmp_r = (result); \
|
||||
if (minunit_tmp_e != minunit_tmp_r) { \
|
||||
snprintf(minunit_last_message, MINUNIT_MESSAGE_LEN, \
|
||||
"%s failed:\n\t%s:%d: %d expected but was %d", __func__, \
|
||||
__FILE__, __LINE__, minunit_tmp_e, minunit_tmp_r); \
|
||||
minunit_status = 1; \
|
||||
return; \
|
||||
} else { printf("."); })
|
||||
|
||||
#define mu_assert_double_eq(expected, result) \
|
||||
MU__SAFE_BLOCK( \
|
||||
double minunit_tmp_e; double minunit_tmp_r; minunit_assert++; \
|
||||
minunit_tmp_e = (expected); minunit_tmp_r = (result); \
|
||||
if (fabs(minunit_tmp_e - minunit_tmp_r) > MINUNIT_EPSILON) { \
|
||||
int minunit_significant_figures = 1 - log10(MINUNIT_EPSILON); \
|
||||
snprintf(minunit_last_message, MINUNIT_MESSAGE_LEN, \
|
||||
"%s failed:\n\t%s:%d: %.*g expected but was %.*g", __func__, \
|
||||
__FILE__, __LINE__, minunit_significant_figures, \
|
||||
minunit_tmp_e, minunit_significant_figures, minunit_tmp_r); \
|
||||
minunit_status = 1; \
|
||||
return; \
|
||||
} else { printf("."); })
|
||||
|
||||
#define mu_assert_string_eq(expected, result) \
|
||||
MU__SAFE_BLOCK( \
|
||||
const char *minunit_tmp_e = expected; \
|
||||
const char *minunit_tmp_r = result; minunit_assert++; \
|
||||
if (!minunit_tmp_e) { \
|
||||
minunit_tmp_e = "<null pointer>"; \
|
||||
} if (!minunit_tmp_r) { \
|
||||
minunit_tmp_r = "<null pointer>"; \
|
||||
} if (strcmp(minunit_tmp_e, minunit_tmp_r)) { \
|
||||
snprintf(minunit_last_message, MINUNIT_MESSAGE_LEN, \
|
||||
"%s failed:\n\t%s:%d: '%s' expected but was '%s'", __func__, \
|
||||
__FILE__, __LINE__, minunit_tmp_e, minunit_tmp_r); \
|
||||
minunit_status = 1; \
|
||||
return; \
|
||||
} else { printf("."); })
|
||||
|
||||
/*
|
||||
* The following two functions were written by David Robert Nadeau
|
||||
* from http://NadeauSoftware.com/ and distributed under the
|
||||
* Creative Commons Attribution 3.0 Unported License
|
||||
*/
|
||||
|
||||
/**
|
||||
* Returns the real time, in seconds, or -1.0 if an error occurred.
|
||||
*
|
||||
* Time is measured since an arbitrary and OS-dependent start time.
|
||||
* The returned real time is only useful for computing an elapsed time
|
||||
* between two calls to this function.
|
||||
*/
|
||||
static double mu_timer_real(void) {
|
||||
#if defined(_WIN32)
|
||||
/* Windows 2000 and later. ---------------------------------- */
|
||||
LARGE_INTEGER Time;
|
||||
LARGE_INTEGER Frequency;
|
||||
|
||||
QueryPerformanceFrequency(&Frequency);
|
||||
QueryPerformanceCounter(&Time);
|
||||
|
||||
Time.QuadPart *= 1000000;
|
||||
Time.QuadPart /= Frequency.QuadPart;
|
||||
|
||||
return (double)Time.QuadPart / 1000000.0;
|
||||
|
||||
#elif (defined(__hpux) || defined(hpux)) || \
|
||||
((defined(__sun__) || defined(__sun) || defined(sun)) && \
|
||||
(defined(__SVR4) || defined(__svr4__)))
|
||||
/* HP-UX, Solaris. ------------------------------------------ */
|
||||
return (double)gethrtime() / 1000000000.0;
|
||||
|
||||
#elif defined(__MACH__) && defined(__APPLE__)
|
||||
/* OSX. ----------------------------------------------------- */
|
||||
static double timeConvert = 0.0;
|
||||
if (timeConvert == 0.0) {
|
||||
mach_timebase_info_data_t timeBase;
|
||||
(void)mach_timebase_info(&timeBase);
|
||||
timeConvert =
|
||||
(double)timeBase.numer / (double)timeBase.denom / 1000000000.0;
|
||||
}
|
||||
return (double)mach_absolute_time() * timeConvert;
|
||||
|
||||
#elif defined(_POSIX_VERSION)
|
||||
/* POSIX. --------------------------------------------------- */
|
||||
struct timeval tm;
|
||||
#if defined(_POSIX_TIMERS) && (_POSIX_TIMERS > 0)
|
||||
{
|
||||
struct timespec ts;
|
||||
#if defined(CLOCK_MONOTONIC_PRECISE)
|
||||
/* BSD. --------------------------------------------- */
|
||||
const clockid_t id = CLOCK_MONOTONIC_PRECISE;
|
||||
#elif defined(CLOCK_MONOTONIC_RAW)
|
||||
/* Linux. ------------------------------------------- */
|
||||
const clockid_t id = CLOCK_MONOTONIC_RAW;
|
||||
#elif defined(CLOCK_HIGHRES)
|
||||
/* Solaris. ----------------------------------------- */
|
||||
const clockid_t id = CLOCK_HIGHRES;
|
||||
#elif defined(CLOCK_MONOTONIC)
|
||||
/* AIX, BSD, Linux, POSIX, Solaris. ----------------- */
|
||||
const clockid_t id = CLOCK_MONOTONIC;
|
||||
#elif defined(CLOCK_REALTIME)
|
||||
/* AIX, BSD, HP-UX, Linux, POSIX. ------------------- */
|
||||
const clockid_t id = CLOCK_REALTIME;
|
||||
#else
|
||||
const clockid_t id = (clockid_t)-1; /* Unknown. */
|
||||
#endif /* CLOCK_* */
|
||||
if (id != (clockid_t)-1 && clock_gettime(id, &ts) != -1)
|
||||
return (double)ts.tv_sec + (double)ts.tv_nsec / 1000000000.0;
|
||||
/* Fall thru. */
|
||||
}
|
||||
#endif /* _POSIX_TIMERS */
|
||||
|
||||
/* AIX, BSD, Cygwin, HP-UX, Linux, OSX, POSIX, Solaris. ----- */
|
||||
gettimeofday(&tm, NULL);
|
||||
return (double)tm.tv_sec + (double)tm.tv_usec / 1000000.0;
|
||||
#else
|
||||
return -1.0; /* Failed. */
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the amount of CPU time used by the current process,
|
||||
* in seconds, or -1.0 if an error occurred.
|
||||
*/
|
||||
static double mu_timer_cpu(void) {
|
||||
#if defined(_WIN32)
|
||||
/* Windows -------------------------------------------------- */
|
||||
FILETIME createTime;
|
||||
FILETIME exitTime;
|
||||
FILETIME kernelTime;
|
||||
FILETIME userTime;
|
||||
|
||||
/* This approach has a resolution of 1/64 second. Unfortunately, Windows' API
|
||||
* does not offer better */
|
||||
if (GetProcessTimes(GetCurrentProcess(), &createTime, &exitTime, &kernelTime,
|
||||
&userTime) != 0) {
|
||||
ULARGE_INTEGER userSystemTime;
|
||||
memcpy(&userSystemTime, &userTime, sizeof(ULARGE_INTEGER));
|
||||
return (double)userSystemTime.QuadPart / 10000000.0;
|
||||
}
|
||||
|
||||
#elif defined(__unix__) || defined(__unix) || defined(unix) || \
|
||||
(defined(__APPLE__) && defined(__MACH__))
|
||||
/* AIX, BSD, Cygwin, HP-UX, Linux, OSX, and Solaris --------- */
|
||||
|
||||
#if defined(_POSIX_TIMERS) && (_POSIX_TIMERS > 0)
|
||||
/* Prefer high-res POSIX timers, when available. */
|
||||
{
|
||||
clockid_t id;
|
||||
struct timespec ts;
|
||||
#if _POSIX_CPUTIME > 0
|
||||
/* Clock ids vary by OS. Query the id, if possible. */
|
||||
if (clock_getcpuclockid(0, &id) == -1)
|
||||
#endif
|
||||
#if defined(CLOCK_PROCESS_CPUTIME_ID)
|
||||
/* Use known clock id for AIX, Linux, or Solaris. */
|
||||
id = CLOCK_PROCESS_CPUTIME_ID;
|
||||
#elif defined(CLOCK_VIRTUAL)
|
||||
/* Use known clock id for BSD or HP-UX. */
|
||||
id = CLOCK_VIRTUAL;
|
||||
#else
|
||||
id = (clockid_t)-1;
|
||||
#endif
|
||||
if (id != (clockid_t)-1 && clock_gettime(id, &ts) != -1)
|
||||
return (double)ts.tv_sec + (double)ts.tv_nsec / 1000000000.0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(RUSAGE_SELF)
|
||||
{
|
||||
struct rusage rusage;
|
||||
if (getrusage(RUSAGE_SELF, &rusage) != -1)
|
||||
return (double)rusage.ru_utime.tv_sec +
|
||||
(double)rusage.ru_utime.tv_usec / 1000000.0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(_SC_CLK_TCK)
|
||||
{
|
||||
const double ticks = (double)sysconf(_SC_CLK_TCK);
|
||||
struct tms tms;
|
||||
if (times(&tms) != (clock_t)-1)
|
||||
return (double)tms.tms_utime / ticks;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(CLOCKS_PER_SEC)
|
||||
{
|
||||
clock_t cl = clock();
|
||||
if (cl != (clock_t)-1)
|
||||
return (double)cl / (double)CLOCKS_PER_SEC;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
return -1; /* Failed. */
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* MINUNIT_MINUNIT_H */
|
698
test/test.c
698
test/test.c
@ -1,698 +0,0 @@
|
||||
#include <zip.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#if defined(_MSC_VER) || defined(__MINGW64__) || defined(__MINGW32__)
|
||||
#define MZ_FILE_STAT_STRUCT _stat
|
||||
#define MZ_FILE_STAT _stat
|
||||
#else
|
||||
#define MZ_FILE_STAT_STRUCT stat
|
||||
#define MZ_FILE_STAT stat
|
||||
#endif
|
||||
|
||||
#define ZIPNAME "test.zip\0"
|
||||
#define TESTDATA1 "Some test data 1...\0"
|
||||
#define CRC32DATA1 2220805626
|
||||
#define TESTDATA2 "Some test data 2...\0"
|
||||
#define CRC32DATA2 2532008468
|
||||
|
||||
#define RFILE "4.txt\0"
|
||||
#define RMODE 0100444
|
||||
|
||||
#define WFILE "6.txt\0"
|
||||
#define WMODE 0100666
|
||||
|
||||
#define XFILE "7.txt\0"
|
||||
#define XMODE 0100777
|
||||
|
||||
#define UNIXMODE 0100644
|
||||
|
||||
#define UNUSED(x) (void)x
|
||||
|
||||
static int total_entries = 0;
|
||||
|
||||
static void test_write(void) {
|
||||
struct zip_t *zip = zip_open(ZIPNAME, ZIP_DEFAULT_COMPRESSION_LEVEL, 'w');
|
||||
assert(zip != NULL);
|
||||
|
||||
assert(0 == zip_entry_open(zip, "test/test-1.txt"));
|
||||
assert(0 == zip_entry_write(zip, TESTDATA1, strlen(TESTDATA1)));
|
||||
assert(0 == strcmp(zip_entry_name(zip), "test/test-1.txt"));
|
||||
assert(total_entries == zip_entry_index(zip));
|
||||
assert(strlen(TESTDATA1) == zip_entry_size(zip));
|
||||
assert(CRC32DATA1 == zip_entry_crc32(zip));
|
||||
++total_entries;
|
||||
assert(0 == zip_entry_close(zip));
|
||||
assert(0 == zip_is64(zip));
|
||||
zip_close(zip);
|
||||
}
|
||||
|
||||
static void test_append(void) {
|
||||
struct zip_t *zip = zip_open(ZIPNAME, ZIP_DEFAULT_COMPRESSION_LEVEL, 'a');
|
||||
assert(zip != NULL);
|
||||
|
||||
assert(0 == zip_entry_open(zip, "test\\test-2.txt"));
|
||||
assert(0 == strcmp(zip_entry_name(zip), "test/test-2.txt"));
|
||||
assert(total_entries == zip_entry_index(zip));
|
||||
assert(0 == zip_entry_write(zip, TESTDATA2, strlen(TESTDATA2)));
|
||||
assert(strlen(TESTDATA2) == zip_entry_size(zip));
|
||||
assert(CRC32DATA2 == zip_entry_crc32(zip));
|
||||
|
||||
++total_entries;
|
||||
assert(0 == zip_entry_close(zip));
|
||||
|
||||
assert(0 == zip_entry_open(zip, "test\\empty/"));
|
||||
assert(0 == strcmp(zip_entry_name(zip), "test/empty/"));
|
||||
assert(0 == zip_entry_size(zip));
|
||||
assert(0 == zip_entry_crc32(zip));
|
||||
|
||||
assert(total_entries == zip_entry_index(zip));
|
||||
++total_entries;
|
||||
assert(0 == zip_entry_close(zip));
|
||||
|
||||
assert(0 == zip_entry_open(zip, "empty/"));
|
||||
assert(0 == strcmp(zip_entry_name(zip), "empty/"));
|
||||
assert(0 == zip_entry_size(zip));
|
||||
assert(0 == zip_entry_crc32(zip));
|
||||
|
||||
assert(total_entries == zip_entry_index(zip));
|
||||
++total_entries;
|
||||
assert(0 == zip_entry_close(zip));
|
||||
|
||||
assert(0 == zip_entry_open(zip, "dotfiles/.test"));
|
||||
assert(0 == strcmp(zip_entry_name(zip), "dotfiles/.test"));
|
||||
assert(0 == zip_entry_size(zip));
|
||||
assert(0 == zip_entry_crc32(zip));
|
||||
assert(0 == zip_entry_write(zip, TESTDATA2, strlen(TESTDATA2)));
|
||||
assert(strlen(TESTDATA2) == zip_entry_size(zip));
|
||||
assert(CRC32DATA2 == zip_entry_crc32(zip));
|
||||
|
||||
assert(total_entries == zip_entry_index(zip));
|
||||
++total_entries;
|
||||
assert(0 == zip_entry_close(zip));
|
||||
|
||||
zip_close(zip);
|
||||
}
|
||||
|
||||
static void test_read(void) {
|
||||
char *buf = NULL;
|
||||
ssize_t bufsize;
|
||||
size_t buftmp;
|
||||
struct zip_t *zip = zip_open(ZIPNAME, 0, 'r');
|
||||
assert(zip != NULL);
|
||||
assert(0 == zip_is64(zip));
|
||||
|
||||
assert(0 == zip_entry_open(zip, "test\\test-1.txt"));
|
||||
assert(strlen(TESTDATA1) == zip_entry_size(zip));
|
||||
assert(CRC32DATA1 == zip_entry_crc32(zip));
|
||||
|
||||
bufsize = zip_entry_read(zip, (void **)&buf, &buftmp);
|
||||
assert(bufsize == strlen(TESTDATA1));
|
||||
assert((size_t)bufsize == buftmp);
|
||||
assert(0 == strncmp(buf, TESTDATA1, bufsize));
|
||||
assert(0 == zip_entry_close(zip));
|
||||
free(buf);
|
||||
buf = NULL;
|
||||
|
||||
assert(0 == zip_entry_open(zip, "test/test-2.txt"));
|
||||
assert(strlen(TESTDATA2) == zip_entry_size(zip));
|
||||
assert(CRC32DATA2 == zip_entry_crc32(zip));
|
||||
|
||||
bufsize = zip_entry_read(zip, (void **)&buf, NULL);
|
||||
assert((size_t)bufsize == strlen(TESTDATA2));
|
||||
assert(0 == strncmp(buf, TESTDATA2, (size_t)bufsize));
|
||||
assert(0 == zip_entry_close(zip));
|
||||
free(buf);
|
||||
buf = NULL;
|
||||
|
||||
assert(0 == zip_entry_open(zip, "test\\empty/"));
|
||||
assert(0 == strcmp(zip_entry_name(zip), "test/empty/"));
|
||||
assert(0 == zip_entry_size(zip));
|
||||
assert(0 == zip_entry_crc32(zip));
|
||||
assert(0 == zip_entry_close(zip));
|
||||
|
||||
buftmp = strlen(TESTDATA2);
|
||||
buf = calloc(buftmp, sizeof(char));
|
||||
assert(0 == zip_entry_open(zip, "test/test-2.txt"));
|
||||
|
||||
bufsize = zip_entry_noallocread(zip, (void *)buf, buftmp);
|
||||
assert(buftmp == (size_t)bufsize);
|
||||
assert(0 == strncmp(buf, TESTDATA2, buftmp));
|
||||
assert(0 == zip_entry_close(zip));
|
||||
free(buf);
|
||||
buf = NULL;
|
||||
|
||||
buftmp = strlen(TESTDATA1);
|
||||
buf = calloc(buftmp, sizeof(char));
|
||||
assert(0 == zip_entry_open(zip, "test/test-1.txt"));
|
||||
|
||||
bufsize = zip_entry_noallocread(zip, (void *)buf, buftmp);
|
||||
assert(buftmp == (size_t)bufsize);
|
||||
assert(0 == strncmp(buf, TESTDATA1, buftmp));
|
||||
assert(0 == zip_entry_close(zip));
|
||||
free(buf);
|
||||
buf = NULL;
|
||||
|
||||
buftmp = strlen(TESTDATA2);
|
||||
buf = calloc(buftmp, sizeof(char));
|
||||
assert(0 == zip_entry_open(zip, "dotfiles/.test"));
|
||||
|
||||
bufsize = zip_entry_noallocread(zip, (void *)buf, buftmp);
|
||||
assert(buftmp == (size_t)bufsize);
|
||||
assert(0 == strncmp(buf, TESTDATA2, buftmp));
|
||||
assert(0 == zip_entry_close(zip));
|
||||
free(buf);
|
||||
buf = NULL;
|
||||
|
||||
zip_close(zip);
|
||||
}
|
||||
|
||||
struct buffer_t {
|
||||
char *data;
|
||||
size_t size;
|
||||
};
|
||||
|
||||
static size_t on_extract(void *arg, unsigned long long offset, const void *data,
|
||||
size_t size) {
|
||||
UNUSED(offset);
|
||||
|
||||
struct buffer_t *buf = (struct buffer_t *)arg;
|
||||
buf->data = realloc(buf->data, buf->size + size + 1);
|
||||
assert(NULL != buf->data);
|
||||
|
||||
memcpy(&(buf->data[buf->size]), data, size);
|
||||
buf->size += size;
|
||||
buf->data[buf->size] = 0;
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
static void test_extract(void) {
|
||||
struct buffer_t buf;
|
||||
|
||||
struct zip_t *zip = zip_open(ZIPNAME, 0, 'r');
|
||||
assert(zip != NULL);
|
||||
|
||||
memset((void *)&buf, 0, sizeof(struct buffer_t));
|
||||
assert(0 == zip_entry_open(zip, "test/test-1.txt"));
|
||||
assert(0 == zip_entry_extract(zip, on_extract, &buf));
|
||||
assert(buf.size == strlen(TESTDATA1));
|
||||
assert(0 == strncmp(buf.data, TESTDATA1, buf.size));
|
||||
assert(0 == zip_entry_close(zip));
|
||||
free(buf.data);
|
||||
buf.data = NULL;
|
||||
buf.size = 0;
|
||||
|
||||
memset((void *)&buf, 0, sizeof(struct buffer_t));
|
||||
assert(0 == zip_entry_open(zip, "dotfiles/.test"));
|
||||
assert(0 == zip_entry_extract(zip, on_extract, &buf));
|
||||
assert(buf.size == strlen(TESTDATA2));
|
||||
assert(0 == strncmp(buf.data, TESTDATA2, buf.size));
|
||||
assert(0 == zip_entry_close(zip));
|
||||
free(buf.data);
|
||||
buf.data = NULL;
|
||||
buf.size = 0;
|
||||
|
||||
zip_close(zip);
|
||||
}
|
||||
|
||||
static void test_total_entries(void) {
|
||||
struct zip_t *zip = zip_open(ZIPNAME, 0, 'r');
|
||||
assert(zip != NULL);
|
||||
|
||||
int n = zip_total_entries(zip);
|
||||
zip_close(zip);
|
||||
|
||||
assert(n == total_entries);
|
||||
}
|
||||
|
||||
static void test_entry_name(void) {
|
||||
struct zip_t *zip = zip_open(ZIPNAME, 0, 'r');
|
||||
assert(zip != NULL);
|
||||
|
||||
assert(zip_entry_name(zip) == NULL);
|
||||
|
||||
assert(0 == zip_entry_open(zip, "test\\test-1.txt"));
|
||||
assert(NULL != zip_entry_name(zip));
|
||||
assert(0 == strcmp(zip_entry_name(zip), "test/test-1.txt"));
|
||||
assert(strlen(TESTDATA1) == zip_entry_size(zip));
|
||||
assert(CRC32DATA1 == zip_entry_crc32(zip));
|
||||
assert(0 == zip_entry_index(zip));
|
||||
|
||||
assert(0 == zip_entry_close(zip));
|
||||
|
||||
assert(0 == zip_entry_open(zip, "test/test-2.txt"));
|
||||
assert(NULL != zip_entry_name(zip));
|
||||
assert(0 == strcmp(zip_entry_name(zip), "test/test-2.txt"));
|
||||
assert(strlen(TESTDATA2) == zip_entry_size(zip));
|
||||
assert(CRC32DATA2 == zip_entry_crc32(zip));
|
||||
assert(1 == zip_entry_index(zip));
|
||||
|
||||
assert(0 == zip_entry_close(zip));
|
||||
|
||||
zip_close(zip);
|
||||
}
|
||||
|
||||
static void test_entry_index(void) {
|
||||
struct zip_t *zip = zip_open(ZIPNAME, 0, 'r');
|
||||
assert(zip != NULL);
|
||||
|
||||
assert(0 == zip_entry_open(zip, "test\\test-1.txt"));
|
||||
assert(0 == zip_entry_index(zip));
|
||||
assert(0 == strcmp(zip_entry_name(zip), "test/test-1.txt"));
|
||||
assert(strlen(TESTDATA1) == zip_entry_size(zip));
|
||||
assert(CRC32DATA1 == zip_entry_crc32(zip));
|
||||
assert(0 == zip_entry_close(zip));
|
||||
|
||||
assert(0 == zip_entry_open(zip, "test/test-2.txt"));
|
||||
assert(1 == zip_entry_index(zip));
|
||||
assert(0 == strcmp(zip_entry_name(zip), "test/test-2.txt"));
|
||||
assert(strlen(TESTDATA2) == zip_entry_size(zip));
|
||||
assert(CRC32DATA2 == zip_entry_crc32(zip));
|
||||
assert(0 == zip_entry_close(zip));
|
||||
|
||||
zip_close(zip);
|
||||
}
|
||||
|
||||
static void test_entry_openbyindex(void) {
|
||||
struct zip_t *zip = zip_open(ZIPNAME, 0, 'r');
|
||||
assert(zip != NULL);
|
||||
|
||||
assert(0 == zip_entry_openbyindex(zip, 1));
|
||||
assert(1 == zip_entry_index(zip));
|
||||
assert(strlen(TESTDATA2) == zip_entry_size(zip));
|
||||
assert(CRC32DATA2 == zip_entry_crc32(zip));
|
||||
assert(0 == strcmp(zip_entry_name(zip), "test/test-2.txt"));
|
||||
assert(0 == zip_entry_close(zip));
|
||||
|
||||
assert(0 == zip_entry_openbyindex(zip, 0));
|
||||
assert(0 == zip_entry_index(zip));
|
||||
assert(strlen(TESTDATA1) == zip_entry_size(zip));
|
||||
assert(CRC32DATA1 == zip_entry_crc32(zip));
|
||||
assert(0 == strcmp(zip_entry_name(zip), "test/test-1.txt"));
|
||||
assert(0 == zip_entry_close(zip));
|
||||
|
||||
zip_close(zip);
|
||||
}
|
||||
|
||||
static void test_list_entries(void) {
|
||||
struct zip_t *zip = zip_open(ZIPNAME, 0, 'r');
|
||||
assert(zip != NULL);
|
||||
|
||||
int i = 0, n = zip_total_entries(zip);
|
||||
for (; i < n; ++i) {
|
||||
assert(0 == zip_entry_openbyindex(zip, i));
|
||||
fprintf(stdout, "[%d]: %s", i, zip_entry_name(zip));
|
||||
if (zip_entry_isdir(zip)) {
|
||||
fprintf(stdout, " (DIR)");
|
||||
}
|
||||
fprintf(stdout, "\n");
|
||||
assert(0 == zip_entry_close(zip));
|
||||
}
|
||||
|
||||
zip_close(zip);
|
||||
}
|
||||
|
||||
static void test_fwrite(void) {
|
||||
const char *filename = WFILE;
|
||||
FILE *stream = NULL;
|
||||
struct zip_t *zip = NULL;
|
||||
#if defined(_MSC_VER)
|
||||
if (0 != fopen_s(&stream, filename, "w+"))
|
||||
#else
|
||||
if (!(stream = fopen(filename, "w+")))
|
||||
#endif
|
||||
{
|
||||
// Cannot open filename
|
||||
fprintf(stdout, "Cannot open filename\n");
|
||||
assert(0 == -1);
|
||||
}
|
||||
fwrite(TESTDATA1, sizeof(char), strlen(TESTDATA1), stream);
|
||||
assert(0 == fclose(stream));
|
||||
|
||||
zip = zip_open(ZIPNAME, 9, 'w');
|
||||
assert(zip != NULL);
|
||||
assert(0 == zip_entry_open(zip, WFILE));
|
||||
assert(0 == zip_entry_fwrite(zip, WFILE));
|
||||
assert(0 == zip_entry_close(zip));
|
||||
assert(0 == zip_is64(zip));
|
||||
|
||||
zip_close(zip);
|
||||
remove(WFILE);
|
||||
remove(ZIPNAME);
|
||||
}
|
||||
|
||||
static void test_exe_permissions(void) {
|
||||
#if defined(_WIN32) || defined(__WIN32__)
|
||||
#else
|
||||
struct MZ_FILE_STAT_STRUCT file_stats;
|
||||
const char *filenames[] = {XFILE};
|
||||
FILE *f = fopen(XFILE, "w");
|
||||
fclose(f);
|
||||
chmod(XFILE, XMODE);
|
||||
|
||||
remove(ZIPNAME);
|
||||
|
||||
assert(0 == zip_create(ZIPNAME, filenames, 1));
|
||||
|
||||
remove(XFILE);
|
||||
|
||||
assert(0 == zip_extract(ZIPNAME, ".", NULL, NULL));
|
||||
|
||||
assert(0 == MZ_FILE_STAT(XFILE, &file_stats));
|
||||
assert(XMODE == file_stats.st_mode);
|
||||
|
||||
remove(XFILE);
|
||||
remove(ZIPNAME);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void test_read_permissions(void) {
|
||||
#if defined(_MSC_VER)
|
||||
#else
|
||||
|
||||
struct MZ_FILE_STAT_STRUCT file_stats;
|
||||
const char *filenames[] = {RFILE};
|
||||
FILE *f = fopen(RFILE, "w");
|
||||
fclose(f);
|
||||
chmod(RFILE, RMODE);
|
||||
|
||||
remove(ZIPNAME);
|
||||
|
||||
assert(0 == zip_create(ZIPNAME, filenames, 1));
|
||||
|
||||
// chmod from 444 to 666 to be able delete the file on windows
|
||||
chmod(RFILE, WMODE);
|
||||
remove(RFILE);
|
||||
|
||||
assert(0 == zip_extract(ZIPNAME, ".", NULL, NULL));
|
||||
|
||||
assert(0 == MZ_FILE_STAT(RFILE, &file_stats));
|
||||
assert(RMODE == file_stats.st_mode);
|
||||
|
||||
chmod(RFILE, WMODE);
|
||||
remove(RFILE);
|
||||
remove(ZIPNAME);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void test_write_permissions(void) {
|
||||
#if defined(_MSC_VER)
|
||||
#else
|
||||
|
||||
struct MZ_FILE_STAT_STRUCT file_stats;
|
||||
const char *filenames[] = {WFILE};
|
||||
FILE *f = fopen(WFILE, "w");
|
||||
fclose(f);
|
||||
chmod(WFILE, WMODE);
|
||||
|
||||
remove(ZIPNAME);
|
||||
|
||||
assert(0 == zip_create(ZIPNAME, filenames, 1));
|
||||
|
||||
remove(WFILE);
|
||||
|
||||
assert(0 == zip_extract(ZIPNAME, ".", NULL, NULL));
|
||||
|
||||
assert(0 == MZ_FILE_STAT(WFILE, &file_stats));
|
||||
assert(WMODE == file_stats.st_mode);
|
||||
|
||||
remove(WFILE);
|
||||
remove(ZIPNAME);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void test_mtime(void) {
|
||||
struct MZ_FILE_STAT_STRUCT file_stat1, file_stat2;
|
||||
|
||||
const char *filename = WFILE;
|
||||
FILE *stream = NULL;
|
||||
struct zip_t *zip = NULL;
|
||||
#if defined(_MSC_VER)
|
||||
if (0 != fopen_s(&stream, filename, "w+"))
|
||||
#else
|
||||
if (!(stream = fopen(filename, "w+")))
|
||||
#endif
|
||||
{
|
||||
// Cannot open filename
|
||||
fprintf(stdout, "Cannot open filename\n");
|
||||
assert(0 == -1);
|
||||
}
|
||||
fwrite(TESTDATA1, sizeof(char), strlen(TESTDATA1), stream);
|
||||
assert(0 == fclose(stream));
|
||||
|
||||
memset(&file_stat1, 0, sizeof(file_stat1));
|
||||
memset(&file_stat2, 0, sizeof(file_stat2));
|
||||
zip = zip_open(ZIPNAME, ZIP_DEFAULT_COMPRESSION_LEVEL, 'w');
|
||||
assert(zip != NULL);
|
||||
assert(0 == zip_entry_open(zip, filename));
|
||||
assert(0 == zip_entry_fwrite(zip, filename));
|
||||
assert(0 == zip_entry_close(zip));
|
||||
zip_close(zip);
|
||||
|
||||
assert(0 == MZ_FILE_STAT(filename, &file_stat1));
|
||||
|
||||
remove(filename);
|
||||
assert(0 == zip_extract(ZIPNAME, ".", NULL, NULL));
|
||||
assert(0 == MZ_FILE_STAT(filename, &file_stat2));
|
||||
fprintf(stdout, "file_stat1.st_mtime: %lu\n", file_stat1.st_mtime);
|
||||
fprintf(stdout, "file_stat2.st_mtime: %lu\n", file_stat2.st_mtime);
|
||||
assert(labs(file_stat1.st_mtime - file_stat2.st_mtime) <= 1);
|
||||
|
||||
remove(filename);
|
||||
remove(ZIPNAME);
|
||||
}
|
||||
|
||||
static void test_unix_permissions(void) {
|
||||
#if defined(_WIN64) || defined(_WIN32) || defined(__WIN32__)
|
||||
#else
|
||||
// UNIX or APPLE
|
||||
struct MZ_FILE_STAT_STRUCT file_stats;
|
||||
|
||||
remove(ZIPNAME);
|
||||
|
||||
struct zip_t *zip = zip_open(ZIPNAME, ZIP_DEFAULT_COMPRESSION_LEVEL, 'w');
|
||||
assert(zip != NULL);
|
||||
|
||||
assert(0 == zip_entry_open(zip, RFILE));
|
||||
assert(0 == zip_entry_write(zip, TESTDATA1, strlen(TESTDATA1)));
|
||||
assert(0 == zip_entry_close(zip));
|
||||
|
||||
zip_close(zip);
|
||||
|
||||
remove(RFILE);
|
||||
|
||||
assert(0 == zip_extract(ZIPNAME, ".", NULL, NULL));
|
||||
|
||||
assert(0 == MZ_FILE_STAT(RFILE, &file_stats));
|
||||
assert(UNIXMODE == file_stats.st_mode);
|
||||
|
||||
remove(RFILE);
|
||||
remove(ZIPNAME);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void test_extract_stream(void) {
|
||||
assert(0 > zip_extract("non_existing_directory/non_existing_archive.zip", ".",
|
||||
NULL, NULL));
|
||||
assert(0 > zip_stream_extract("", 0, ".", NULL, NULL));
|
||||
|
||||
remove(ZIPNAME);
|
||||
|
||||
struct zip_t *zip = zip_open(ZIPNAME, ZIP_DEFAULT_COMPRESSION_LEVEL, 'w');
|
||||
assert(zip != NULL);
|
||||
|
||||
assert(0 == zip_entry_open(zip, RFILE));
|
||||
assert(0 == zip_entry_write(zip, TESTDATA1, strlen(TESTDATA1)));
|
||||
assert(0 == zip_entry_close(zip));
|
||||
|
||||
assert(0 == zip_entry_open(zip, "dotfiles/.test\0"));
|
||||
assert(0 == zip_entry_write(zip, TESTDATA2, strlen(TESTDATA2)));
|
||||
assert(0 == zip_entry_close(zip));
|
||||
|
||||
zip_close(zip);
|
||||
|
||||
remove(RFILE);
|
||||
remove("dotfiles/.test\0");
|
||||
|
||||
FILE *fp = NULL;
|
||||
fp = fopen(ZIPNAME, "rb+");
|
||||
assert(fp != NULL);
|
||||
|
||||
fseek(fp, 0L, SEEK_END);
|
||||
size_t filesize = ftell(fp);
|
||||
fseek(fp, 0L, SEEK_SET);
|
||||
|
||||
char *stream = (char *)malloc(filesize * sizeof(char));
|
||||
memset(stream, 0, filesize);
|
||||
|
||||
size_t size = fread(stream, sizeof(char), filesize, fp);
|
||||
assert(filesize == size);
|
||||
|
||||
assert(0 == zip_stream_extract(stream, size, ".", NULL, NULL));
|
||||
|
||||
free(stream);
|
||||
fclose(fp);
|
||||
remove(RFILE);
|
||||
remove("dotfiles/.test\0");
|
||||
remove(ZIPNAME);
|
||||
}
|
||||
|
||||
static void test_open_stream(void) {
|
||||
remove(ZIPNAME);
|
||||
/* COMPRESS MEM TO MEM */
|
||||
struct zip_t *zip =
|
||||
zip_stream_open(NULL, 0, ZIP_DEFAULT_COMPRESSION_LEVEL, 'w');
|
||||
assert(zip != NULL);
|
||||
|
||||
assert(0 == zip_entry_open(zip, "test/test-1.txt"));
|
||||
assert(0 == zip_entry_write(zip, TESTDATA1, strlen(TESTDATA1)));
|
||||
assert(0 == zip_entry_close(zip));
|
||||
|
||||
/* write compressed mem to file */
|
||||
char *buf_encode1 = NULL;
|
||||
char *buf_encode2 = NULL;
|
||||
ssize_t n = zip_stream_copy(zip, (void **)&buf_encode1, NULL);
|
||||
zip_stream_copy(zip, (void **)&buf_encode2, &n);
|
||||
assert(0 == strncmp(buf_encode1, buf_encode2, (size_t)n));
|
||||
|
||||
zip_stream_close(zip);
|
||||
/* DECOMPRESS MEM TO MEM */
|
||||
struct zip_t *zipStream = zip_stream_open(buf_encode1, n, 0, 'r');
|
||||
assert(zipStream != NULL);
|
||||
|
||||
assert(0 == zip_entry_open(zipStream, "test/test-1.txt"));
|
||||
|
||||
char *buf = NULL;
|
||||
ssize_t bufsize;
|
||||
bufsize = zip_entry_read(zipStream, (void **)&buf, NULL);
|
||||
assert(0 == strncmp(buf, TESTDATA1, (size_t)bufsize));
|
||||
assert(0 == zip_entry_close(zipStream));
|
||||
zip_stream_close(zipStream);
|
||||
|
||||
free(buf);
|
||||
free(buf_encode1);
|
||||
free(buf_encode2);
|
||||
remove(ZIPNAME);
|
||||
}
|
||||
|
||||
static int create_zip_file(const char *filename) {
|
||||
struct zip_t *zip = zip_open(filename, ZIP_DEFAULT_COMPRESSION_LEVEL, 'w');
|
||||
assert(zip != NULL);
|
||||
|
||||
assert(0 == zip_entry_open(zip, "file.txt"));
|
||||
assert(0 == zip_entry_write(zip, TESTDATA1, strlen(TESTDATA1)));
|
||||
assert(0 == zip_entry_close(zip));
|
||||
|
||||
assert(0 == zip_entry_open(zip, "a"));
|
||||
assert(0 == zip_entry_write(zip, TESTDATA2, strlen(TESTDATA2)));
|
||||
assert(0 == zip_entry_close(zip));
|
||||
|
||||
assert(0 == zip_entry_open(zip, "directory/file.1"));
|
||||
assert(0 == zip_entry_write(zip, TESTDATA1, strlen(TESTDATA1)));
|
||||
assert(0 == zip_entry_close(zip));
|
||||
|
||||
assert(0 == zip_entry_open(zip, "otherdirectory/file.3"));
|
||||
assert(0 == zip_entry_write(zip, TESTDATA2, strlen(TESTDATA2)));
|
||||
assert(0 == zip_entry_close(zip));
|
||||
|
||||
assert(0 == zip_entry_open(zip, "directory/file.2"));
|
||||
assert(0 == zip_entry_write(zip, TESTDATA1, strlen(TESTDATA1)));
|
||||
assert(0 == zip_entry_close(zip));
|
||||
|
||||
assert(0 == zip_entry_open(zip, "directory/file.4"));
|
||||
assert(0 == zip_entry_write(zip, TESTDATA1, strlen(TESTDATA1)));
|
||||
assert(0 == zip_entry_close(zip));
|
||||
|
||||
assert(6 == zip_total_entries(zip));
|
||||
zip_close(zip);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void test_entries_delete() {
|
||||
remove(ZIPNAME);
|
||||
assert(0 == create_zip_file(ZIPNAME));
|
||||
|
||||
struct zip_t *zip = zip_open(ZIPNAME, 0, 'r');
|
||||
assert(0 == zip_entry_open(zip, "file.txt"));
|
||||
assert(0 == zip_entry_close(zip));
|
||||
assert(0 == zip_entry_open(zip, "a"));
|
||||
assert(0 == zip_entry_close(zip));
|
||||
assert(0 == zip_entry_open(zip, "directory/file.1"));
|
||||
assert(0 == zip_entry_close(zip));
|
||||
assert(0 == zip_entry_open(zip, "otherdirectory/file.3"));
|
||||
assert(0 == zip_entry_close(zip));
|
||||
assert(0 == zip_entry_open(zip, "directory/file.2"));
|
||||
assert(0 == zip_entry_close(zip));
|
||||
assert(0 == zip_entry_open(zip, "directory/file.4"));
|
||||
assert(0 == zip_entry_close(zip));
|
||||
zip_close(zip);
|
||||
|
||||
char *entries[] = {"file.txt", "a", "directory/file.1",
|
||||
"otherdirectory/file.3", "directory/file.2"};
|
||||
zip = zip_open(ZIPNAME, 0, 'd');
|
||||
assert(5 == zip_entries_delete(zip, entries, 5));
|
||||
zip_close(zip);
|
||||
|
||||
zip = zip_open(ZIPNAME, 0, 'r');
|
||||
assert(-1 == zip_entry_open(zip, "file.txt"));
|
||||
assert(0 == zip_entry_close(zip));
|
||||
assert(-1 == zip_entry_open(zip, "a"));
|
||||
assert(0 == zip_entry_close(zip));
|
||||
assert(-1 == zip_entry_open(zip, "directory/file.1"));
|
||||
assert(0 == zip_entry_close(zip));
|
||||
assert(-1 == zip_entry_open(zip, "otherdirectory/file.3"));
|
||||
assert(0 == zip_entry_close(zip));
|
||||
assert(-1 == zip_entry_open(zip, "directory/file.2"));
|
||||
assert(0 == zip_entry_close(zip));
|
||||
|
||||
assert(1 == zip_total_entries(zip));
|
||||
assert(0 == zip_entry_open(zip, "directory/file.4"));
|
||||
size_t buftmp = 0;
|
||||
char *buf = NULL;
|
||||
ssize_t bufsize = zip_entry_read(zip, (void **)&buf, &buftmp);
|
||||
assert(bufsize == strlen(TESTDATA1));
|
||||
assert((size_t)bufsize == buftmp);
|
||||
assert(0 == strncmp(buf, TESTDATA1, bufsize));
|
||||
assert(0 == zip_entry_close(zip));
|
||||
free(buf);
|
||||
buf = NULL;
|
||||
|
||||
zip_close(zip);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
UNUSED(argc);
|
||||
UNUSED(argv);
|
||||
|
||||
remove(ZIPNAME);
|
||||
|
||||
test_write();
|
||||
test_append();
|
||||
test_read();
|
||||
test_extract();
|
||||
test_total_entries();
|
||||
test_entry_name();
|
||||
test_entry_index();
|
||||
test_entry_openbyindex();
|
||||
test_list_entries();
|
||||
test_fwrite();
|
||||
test_read_permissions();
|
||||
test_write_permissions();
|
||||
test_exe_permissions();
|
||||
test_mtime();
|
||||
test_unix_permissions();
|
||||
test_extract_stream();
|
||||
test_open_stream();
|
||||
test_entries_delete();
|
||||
|
||||
remove(ZIPNAME);
|
||||
|
||||
fprintf(stdout, "ALL TEST SUCCESS!\n");
|
||||
|
||||
return 0;
|
||||
}
|
94
test/test_append.c
Normal file
94
test/test_append.c
Normal file
@ -0,0 +1,94 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <zip.h>
|
||||
|
||||
#include "minunit.h"
|
||||
|
||||
static char *ZIPNAME = NULL;
|
||||
static int total_entries = 0;
|
||||
|
||||
#define TESTDATA1 "Some test data 1...\0"
|
||||
|
||||
void test_setup(void) {
|
||||
ZIPNAME = tempnam(NULL, "z-");
|
||||
|
||||
struct zip_t *zip = zip_open(ZIPNAME, ZIP_DEFAULT_COMPRESSION_LEVEL, 'w');
|
||||
|
||||
zip_entry_open(zip, "test/test-1.txt");
|
||||
zip_entry_write(zip, TESTDATA1, strlen(TESTDATA1));
|
||||
zip_entry_close(zip);
|
||||
++total_entries;
|
||||
|
||||
zip_close(zip);
|
||||
}
|
||||
|
||||
void test_teardown(void) {
|
||||
remove(ZIPNAME);
|
||||
free(ZIPNAME);
|
||||
}
|
||||
|
||||
#define TESTDATA2 "Some test data 2...\0"
|
||||
#define CRC32DATA2 2532008468
|
||||
|
||||
MU_TEST(test_append) {
|
||||
struct zip_t *zip = zip_open(ZIPNAME, ZIP_DEFAULT_COMPRESSION_LEVEL, 'a');
|
||||
mu_check(zip != NULL);
|
||||
|
||||
mu_assert_int_eq(0, zip_entry_open(zip, "test\\test-2.txt"));
|
||||
mu_assert_int_eq(0, strcmp(zip_entry_name(zip), "test/test-2.txt"));
|
||||
mu_assert_int_eq(total_entries, zip_entry_index(zip));
|
||||
mu_assert_int_eq(0, zip_entry_write(zip, TESTDATA2, strlen(TESTDATA2)));
|
||||
mu_assert_int_eq(strlen(TESTDATA2), zip_entry_size(zip));
|
||||
mu_check(CRC32DATA2 == zip_entry_crc32(zip));
|
||||
mu_assert_int_eq(0, zip_entry_close(zip));
|
||||
++total_entries;
|
||||
|
||||
mu_assert_int_eq(0, zip_entry_open(zip, "test\\empty/"));
|
||||
mu_assert_int_eq(0, strcmp(zip_entry_name(zip), "test/empty/"));
|
||||
mu_assert_int_eq(0, zip_entry_size(zip));
|
||||
mu_check(0 == zip_entry_crc32(zip));
|
||||
mu_assert_int_eq(total_entries, zip_entry_index(zip));
|
||||
mu_assert_int_eq(0, zip_entry_close(zip));
|
||||
++total_entries;
|
||||
|
||||
mu_assert_int_eq(0, zip_entry_open(zip, "empty/"));
|
||||
mu_assert_int_eq(0, strcmp(zip_entry_name(zip), "empty/"));
|
||||
mu_assert_int_eq(0, zip_entry_size(zip));
|
||||
mu_check(0 == zip_entry_crc32(zip));
|
||||
mu_assert_int_eq(total_entries, zip_entry_index(zip));
|
||||
mu_assert_int_eq(0, zip_entry_close(zip));
|
||||
++total_entries;
|
||||
|
||||
mu_assert_int_eq(0, zip_entry_open(zip, "dotfiles/.test"));
|
||||
mu_assert_int_eq(0, strcmp(zip_entry_name(zip), "dotfiles/.test"));
|
||||
mu_assert_int_eq(0, zip_entry_size(zip));
|
||||
mu_check(0 == zip_entry_crc32(zip));
|
||||
mu_assert_int_eq(0, zip_entry_write(zip, TESTDATA2, strlen(TESTDATA2)));
|
||||
mu_assert_int_eq(strlen(TESTDATA2), zip_entry_size(zip));
|
||||
mu_check(CRC32DATA2 == zip_entry_crc32(zip));
|
||||
mu_assert_int_eq(total_entries, zip_entry_index(zip));
|
||||
mu_assert_int_eq(0, zip_entry_close(zip));
|
||||
++total_entries;
|
||||
|
||||
mu_assert_int_eq(total_entries, zip_total_entries(zip));
|
||||
|
||||
zip_close(zip);
|
||||
}
|
||||
|
||||
MU_TEST_SUITE(test_append_suite) {
|
||||
MU_SUITE_CONFIGURE(&test_setup, &test_teardown);
|
||||
|
||||
MU_RUN_TEST(test_append);
|
||||
}
|
||||
|
||||
#define UNUSED(x) (void)x
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
UNUSED(argc);
|
||||
UNUSED(argv);
|
||||
|
||||
MU_RUN_SUITE(test_append_suite);
|
||||
MU_REPORT();
|
||||
return MU_EXIT_CODE;
|
||||
}
|
274
test/test_entry.c
Normal file
274
test/test_entry.c
Normal file
@ -0,0 +1,274 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <zip.h>
|
||||
|
||||
#include "minunit.h"
|
||||
|
||||
static char *ZIPNAME = NULL;
|
||||
|
||||
#define CRC32DATA1 2220805626
|
||||
#define TESTDATA1 "Some test data 1...\0"
|
||||
|
||||
#define TESTDATA2 "Some test data 2...\0"
|
||||
#define CRC32DATA2 2532008468
|
||||
|
||||
static int total_entries = 0;
|
||||
|
||||
void test_setup(void) {
|
||||
ZIPNAME = tempnam(NULL, "z-");
|
||||
|
||||
struct zip_t *zip = zip_open(ZIPNAME, ZIP_DEFAULT_COMPRESSION_LEVEL, 'w');
|
||||
|
||||
zip_entry_open(zip, "test/test-1.txt");
|
||||
zip_entry_write(zip, TESTDATA1, strlen(TESTDATA1));
|
||||
zip_entry_close(zip);
|
||||
++total_entries;
|
||||
|
||||
zip_entry_open(zip, "test\\test-2.txt");
|
||||
zip_entry_write(zip, TESTDATA2, strlen(TESTDATA2));
|
||||
zip_entry_close(zip);
|
||||
++total_entries;
|
||||
|
||||
zip_entry_open(zip, "test\\empty/");
|
||||
zip_entry_close(zip);
|
||||
++total_entries;
|
||||
|
||||
zip_entry_open(zip, "empty/");
|
||||
zip_entry_close(zip);
|
||||
++total_entries;
|
||||
|
||||
zip_entry_open(zip, "dotfiles/.test");
|
||||
zip_entry_write(zip, TESTDATA2, strlen(TESTDATA2));
|
||||
zip_entry_close(zip);
|
||||
++total_entries;
|
||||
|
||||
zip_entry_open(zip, "delete.me");
|
||||
zip_entry_write(zip, TESTDATA1, strlen(TESTDATA1));
|
||||
zip_entry_close(zip);
|
||||
++total_entries;
|
||||
|
||||
zip_entry_open(zip, "_");
|
||||
zip_entry_write(zip, TESTDATA2, strlen(TESTDATA2));
|
||||
zip_entry_close(zip);
|
||||
++total_entries;
|
||||
|
||||
zip_entry_open(zip, "delete/file.1");
|
||||
zip_entry_write(zip, TESTDATA1, strlen(TESTDATA1));
|
||||
zip_entry_close(zip);
|
||||
++total_entries;
|
||||
|
||||
zip_entry_open(zip, "delete/file.2");
|
||||
zip_entry_write(zip, TESTDATA2, strlen(TESTDATA2));
|
||||
zip_entry_close(zip);
|
||||
++total_entries;
|
||||
|
||||
zip_entry_open(zip, "deleteme/file.3");
|
||||
zip_entry_write(zip, TESTDATA1, strlen(TESTDATA1));
|
||||
zip_entry_close(zip);
|
||||
++total_entries;
|
||||
|
||||
zip_entry_open(zip, "delete/file.4");
|
||||
zip_entry_write(zip, TESTDATA2, strlen(TESTDATA2));
|
||||
zip_entry_close(zip);
|
||||
++total_entries;
|
||||
|
||||
zip_close(zip);
|
||||
}
|
||||
|
||||
void test_teardown(void) {
|
||||
total_entries = 0;
|
||||
|
||||
remove(ZIPNAME);
|
||||
free(ZIPNAME);
|
||||
}
|
||||
|
||||
MU_TEST(test_entry_name) {
|
||||
struct zip_t *zip = zip_open(ZIPNAME, 0, 'r');
|
||||
mu_check(zip != NULL);
|
||||
|
||||
mu_check(zip_entry_name(zip) == NULL);
|
||||
|
||||
mu_check(0 == zip_entry_open(zip, "test\\test-1.txt"));
|
||||
mu_check(NULL != zip_entry_name(zip));
|
||||
mu_check(0 == strcmp(zip_entry_name(zip), "test/test-1.txt"));
|
||||
mu_assert_int_eq(strlen(TESTDATA1), zip_entry_size(zip));
|
||||
mu_check(CRC32DATA1 == zip_entry_crc32(zip));
|
||||
mu_assert_int_eq(0, zip_entry_index(zip));
|
||||
|
||||
mu_check(0 == zip_entry_close(zip));
|
||||
|
||||
mu_check(0 == zip_entry_open(zip, "test/test-2.txt"));
|
||||
mu_check(NULL != zip_entry_name(zip));
|
||||
mu_check(0 == strcmp(zip_entry_name(zip), "test/test-2.txt"));
|
||||
mu_assert_int_eq(strlen(TESTDATA2), zip_entry_size(zip));
|
||||
mu_check(CRC32DATA2 == zip_entry_crc32(zip));
|
||||
mu_assert_int_eq(1, zip_entry_index(zip));
|
||||
mu_check(0 == zip_entry_close(zip));
|
||||
|
||||
zip_close(zip);
|
||||
}
|
||||
|
||||
MU_TEST(test_entry_index) {
|
||||
struct zip_t *zip = zip_open(ZIPNAME, 0, 'r');
|
||||
mu_check(zip != NULL);
|
||||
|
||||
mu_check(0 == zip_entry_open(zip, "test\\test-1.txt"));
|
||||
mu_assert_int_eq(0, zip_entry_index(zip));
|
||||
mu_check(0 == strcmp(zip_entry_name(zip), "test/test-1.txt"));
|
||||
mu_assert_int_eq(strlen(TESTDATA1), zip_entry_size(zip));
|
||||
mu_check(CRC32DATA1 == zip_entry_crc32(zip));
|
||||
mu_check(0 == zip_entry_close(zip));
|
||||
|
||||
mu_check(0 == zip_entry_open(zip, "test/test-2.txt"));
|
||||
mu_assert_int_eq(1, zip_entry_index(zip));
|
||||
mu_check(0 == strcmp(zip_entry_name(zip), "test/test-2.txt"));
|
||||
mu_assert_int_eq(strlen(TESTDATA2), zip_entry_size(zip));
|
||||
mu_check(CRC32DATA2 == zip_entry_crc32(zip));
|
||||
mu_check(0 == zip_entry_close(zip));
|
||||
|
||||
zip_close(zip);
|
||||
}
|
||||
|
||||
MU_TEST(test_entry_openbyindex) {
|
||||
struct zip_t *zip = zip_open(ZIPNAME, 0, 'r');
|
||||
mu_check(zip != NULL);
|
||||
|
||||
mu_check(0 == zip_entry_openbyindex(zip, 1));
|
||||
mu_assert_int_eq(1, zip_entry_index(zip));
|
||||
mu_assert_int_eq(strlen(TESTDATA2), zip_entry_size(zip));
|
||||
mu_check(CRC32DATA2 == zip_entry_crc32(zip));
|
||||
mu_check(0 == strcmp(zip_entry_name(zip), "test/test-2.txt"));
|
||||
mu_check(0 == zip_entry_close(zip));
|
||||
|
||||
mu_check(0 == zip_entry_openbyindex(zip, 0));
|
||||
mu_assert_int_eq(0, zip_entry_index(zip));
|
||||
mu_assert_int_eq(strlen(TESTDATA1), zip_entry_size(zip));
|
||||
mu_check(CRC32DATA1 == zip_entry_crc32(zip));
|
||||
mu_check(0 == strcmp(zip_entry_name(zip), "test/test-1.txt"));
|
||||
mu_check(0 == zip_entry_close(zip));
|
||||
|
||||
zip_close(zip);
|
||||
}
|
||||
|
||||
MU_TEST(test_entry_read) {
|
||||
char *bufencode1 = NULL;
|
||||
char *bufencode2 = NULL;
|
||||
char *buf = NULL;
|
||||
ssize_t bufsize;
|
||||
|
||||
struct zip_t *zip =
|
||||
zip_stream_open(NULL, 0, ZIP_DEFAULT_COMPRESSION_LEVEL, 'w');
|
||||
mu_check(zip != NULL);
|
||||
|
||||
mu_check(0 == zip_entry_open(zip, "test/test-1.txt"));
|
||||
mu_check(0 == zip_entry_write(zip, TESTDATA1, strlen(TESTDATA1)));
|
||||
mu_check(0 == zip_entry_close(zip));
|
||||
|
||||
ssize_t n = zip_stream_copy(zip, (void **)&bufencode1, NULL);
|
||||
zip_stream_copy(zip, (void **)&bufencode2, &n);
|
||||
mu_check(0 == strncmp(bufencode1, bufencode2, (size_t)n));
|
||||
|
||||
zip_stream_close(zip);
|
||||
|
||||
struct zip_t *zipstream = zip_stream_open(bufencode1, n, 0, 'r');
|
||||
mu_check(zipstream != NULL);
|
||||
|
||||
mu_check(0 == zip_entry_open(zipstream, "test/test-1.txt"));
|
||||
bufsize = zip_entry_read(zipstream, (void **)&buf, NULL);
|
||||
mu_check(0 == strncmp(buf, TESTDATA1, (size_t)bufsize));
|
||||
mu_check(0 == zip_entry_close(zipstream));
|
||||
|
||||
zip_stream_close(zipstream);
|
||||
|
||||
free(buf);
|
||||
free(bufencode1);
|
||||
free(bufencode2);
|
||||
}
|
||||
|
||||
MU_TEST(test_list_entries) {
|
||||
struct zip_t *zip = zip_open(ZIPNAME, 0, 'r');
|
||||
mu_check(zip != NULL);
|
||||
|
||||
int i = 0, n = zip_total_entries(zip);
|
||||
for (; i < n; ++i) {
|
||||
mu_check(0 == zip_entry_openbyindex(zip, i));
|
||||
fprintf(stdout, "[%d]: %s", i, zip_entry_name(zip));
|
||||
if (zip_entry_isdir(zip)) {
|
||||
fprintf(stdout, " (DIR)");
|
||||
}
|
||||
fprintf(stdout, "\n");
|
||||
mu_check(0 == zip_entry_close(zip));
|
||||
}
|
||||
|
||||
zip_close(zip);
|
||||
}
|
||||
|
||||
MU_TEST(test_entries_delete) {
|
||||
char *entries[] = {"delete.me", "_", "delete/file.1", "deleteme/file.3",
|
||||
"delete/file.2"};
|
||||
|
||||
struct zip_t *zip = zip_open(ZIPNAME, 0, 'd');
|
||||
mu_check(zip != NULL);
|
||||
|
||||
mu_assert_int_eq(5, zip_entries_delete(zip, entries, 5));
|
||||
|
||||
zip_close(zip);
|
||||
|
||||
zip = zip_open(ZIPNAME, 0, 'r');
|
||||
mu_check(zip != NULL);
|
||||
|
||||
mu_check(0 > zip_entry_open(zip, "delete.me"));
|
||||
mu_check(0 == zip_entry_close(zip));
|
||||
|
||||
mu_check(0 > zip_entry_open(zip, "_"));
|
||||
mu_check(0 == zip_entry_close(zip));
|
||||
|
||||
mu_check(0 > zip_entry_open(zip, "delete/file.1"));
|
||||
mu_check(0 == zip_entry_close(zip));
|
||||
|
||||
mu_check(0 > zip_entry_open(zip, "deleteme/file.3"));
|
||||
mu_check(0 == zip_entry_close(zip));
|
||||
mu_check(0 > zip_entry_open(zip, "delete/file.2"));
|
||||
mu_check(0 == zip_entry_close(zip));
|
||||
|
||||
mu_assert_int_eq(total_entries - 5, zip_total_entries(zip));
|
||||
|
||||
mu_check(0 == zip_entry_open(zip, "delete/file.4"));
|
||||
|
||||
size_t buftmp = 0;
|
||||
char *buf = NULL;
|
||||
ssize_t bufsize = zip_entry_read(zip, (void **)&buf, &buftmp);
|
||||
|
||||
mu_assert_int_eq(bufsize, strlen(TESTDATA2));
|
||||
mu_assert_int_eq((size_t)bufsize, buftmp);
|
||||
mu_check(0 == strncmp(buf, TESTDATA2, bufsize));
|
||||
mu_check(0 == zip_entry_close(zip));
|
||||
|
||||
free(buf);
|
||||
buf = NULL;
|
||||
|
||||
zip_close(zip);
|
||||
}
|
||||
|
||||
MU_TEST_SUITE(test_entry_suite) {
|
||||
MU_SUITE_CONFIGURE(&test_setup, &test_teardown);
|
||||
|
||||
MU_RUN_TEST(test_entry_name);
|
||||
MU_RUN_TEST(test_entry_index);
|
||||
MU_RUN_TEST(test_entry_openbyindex);
|
||||
MU_RUN_TEST(test_entry_read);
|
||||
MU_RUN_TEST(test_list_entries);
|
||||
MU_RUN_TEST(test_entries_delete);
|
||||
}
|
||||
|
||||
#define UNUSED(x) (void)x
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
UNUSED(argc);
|
||||
UNUSED(argv);
|
||||
|
||||
MU_RUN_SUITE(test_entry_suite);
|
||||
MU_REPORT();
|
||||
return MU_EXIT_CODE;
|
||||
}
|
150
test/test_extract.c
Normal file
150
test/test_extract.c
Normal file
@ -0,0 +1,150 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <zip.h>
|
||||
|
||||
#include "minunit.h"
|
||||
|
||||
static char *ZIPNAME = NULL;
|
||||
|
||||
#define TESTDATA1 "Some test data 1...\0"
|
||||
#define TESTDATA2 "Some test data 2...\0"
|
||||
|
||||
void test_setup(void) {
|
||||
ZIPNAME = tempnam(".", "z-");
|
||||
|
||||
struct zip_t *zip = zip_open(ZIPNAME, ZIP_DEFAULT_COMPRESSION_LEVEL, 'w');
|
||||
|
||||
zip_entry_open(zip, "test/test-1.txt");
|
||||
zip_entry_write(zip, TESTDATA1, strlen(TESTDATA1));
|
||||
zip_entry_close(zip);
|
||||
|
||||
zip_entry_open(zip, "test\\test-2.txt");
|
||||
zip_entry_write(zip, TESTDATA2, strlen(TESTDATA2));
|
||||
zip_entry_close(zip);
|
||||
|
||||
zip_entry_open(zip, "test\\empty/");
|
||||
zip_entry_close(zip);
|
||||
|
||||
zip_entry_open(zip, "empty/");
|
||||
zip_entry_close(zip);
|
||||
|
||||
zip_entry_open(zip, "dotfiles/.test");
|
||||
zip_entry_write(zip, TESTDATA2, strlen(TESTDATA2));
|
||||
zip_entry_close(zip);
|
||||
|
||||
zip_close(zip);
|
||||
}
|
||||
|
||||
void test_teardown(void) {
|
||||
remove("test/test-1.txt");
|
||||
remove("test/test-2.txt");
|
||||
remove("test/empty");
|
||||
remove("test");
|
||||
remove("empty");
|
||||
remove("dotfiles/.test");
|
||||
remove("dotfiles");
|
||||
remove(ZIPNAME);
|
||||
free(ZIPNAME);
|
||||
}
|
||||
|
||||
#define UNUSED(x) (void)x
|
||||
|
||||
struct buffer_t {
|
||||
char *data;
|
||||
size_t size;
|
||||
};
|
||||
|
||||
static size_t on_extract(void *arg, unsigned long long offset, const void *data,
|
||||
size_t size) {
|
||||
UNUSED(offset);
|
||||
|
||||
struct buffer_t *buf = (struct buffer_t *)arg;
|
||||
buf->data = realloc(buf->data, buf->size + size + 1);
|
||||
|
||||
memcpy(&(buf->data[buf->size]), data, size);
|
||||
buf->size += size;
|
||||
buf->data[buf->size] = 0;
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
MU_TEST(test_extract) {
|
||||
struct buffer_t buf;
|
||||
|
||||
struct zip_t *zip = zip_open(ZIPNAME, 0, 'r');
|
||||
mu_check(zip != NULL);
|
||||
|
||||
memset((void *)&buf, 0, sizeof(struct buffer_t));
|
||||
|
||||
mu_check(0 == zip_entry_open(zip, "test/test-1.txt"));
|
||||
mu_check(0 == zip_entry_extract(zip, on_extract, &buf));
|
||||
mu_assert_int_eq(strlen(TESTDATA1), buf.size);
|
||||
mu_check(0 == strncmp(buf.data, TESTDATA1, buf.size));
|
||||
mu_check(0 == zip_entry_close(zip));
|
||||
|
||||
free(buf.data);
|
||||
buf.data = NULL;
|
||||
buf.size = 0;
|
||||
|
||||
memset((void *)&buf, 0, sizeof(struct buffer_t));
|
||||
|
||||
mu_check(0 == zip_entry_open(zip, "dotfiles/.test"));
|
||||
mu_check(0 == zip_entry_extract(zip, on_extract, &buf));
|
||||
mu_assert_int_eq(strlen(TESTDATA2), buf.size);
|
||||
mu_check(0 == strncmp(buf.data, TESTDATA2, buf.size));
|
||||
mu_check(0 == zip_entry_close(zip));
|
||||
|
||||
free(buf.data);
|
||||
buf.data = NULL;
|
||||
buf.size = 0;
|
||||
|
||||
zip_close(zip);
|
||||
}
|
||||
|
||||
MU_TEST(test_extract_stream) {
|
||||
mu_check(0 > zip_extract("non_existing_directory/non_existing_archive.zip",
|
||||
".", NULL, NULL));
|
||||
mu_check(0 > zip_stream_extract("", 0, ".", NULL, NULL));
|
||||
|
||||
FILE *fp = NULL;
|
||||
#if defined(_MSC_VER)
|
||||
if (0 != fopen_s(&fp, ZIPNAME, "rb+"))
|
||||
#else
|
||||
if (!(fp = fopen(ZIPNAME, "rb+")))
|
||||
#endif
|
||||
{
|
||||
mu_fail("Cannot open filename\n");
|
||||
}
|
||||
|
||||
fseek(fp, 0L, SEEK_END);
|
||||
size_t filesize = ftell(fp);
|
||||
fseek(fp, 0L, SEEK_SET);
|
||||
|
||||
char *stream = (char *)malloc(filesize * sizeof(char));
|
||||
memset(stream, 0, filesize);
|
||||
|
||||
size_t size = fread(stream, sizeof(char), filesize, fp);
|
||||
mu_assert_int_eq(filesize, size);
|
||||
|
||||
mu_assert_int_eq(0, zip_stream_extract(stream, size, ".", NULL, NULL));
|
||||
|
||||
free(stream);
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
MU_TEST_SUITE(test_extract_suite) {
|
||||
MU_SUITE_CONFIGURE(&test_setup, &test_teardown);
|
||||
|
||||
MU_RUN_TEST(test_extract);
|
||||
MU_RUN_TEST(test_extract_stream);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
UNUSED(argc);
|
||||
UNUSED(argv);
|
||||
|
||||
MU_RUN_SUITE(test_extract_suite);
|
||||
MU_REPORT();
|
||||
return MU_EXIT_CODE;
|
||||
}
|
185
test/test_permissions.c
Normal file
185
test/test_permissions.c
Normal file
@ -0,0 +1,185 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <zip.h>
|
||||
|
||||
#include "minunit.h"
|
||||
|
||||
static char *ZIPNAME = NULL;
|
||||
static char *XFILE = NULL;
|
||||
static char *RFILE = NULL;
|
||||
static char *WFILE = NULL;
|
||||
|
||||
void test_setup(void) {
|
||||
ZIPNAME = tempnam(".", "z-");
|
||||
XFILE = tempnam(".", "x-");
|
||||
RFILE = tempnam(".", "r-");
|
||||
WFILE = tempnam(".", "w-");
|
||||
}
|
||||
|
||||
void test_teardown(void) {
|
||||
remove(WFILE);
|
||||
free(WFILE);
|
||||
|
||||
remove(RFILE);
|
||||
free(RFILE);
|
||||
|
||||
remove(XFILE);
|
||||
free(XFILE);
|
||||
|
||||
remove(ZIPNAME);
|
||||
free(ZIPNAME);
|
||||
}
|
||||
|
||||
#if defined(_MSC_VER) || defined(__MINGW64__) || defined(__MINGW32__)
|
||||
#define MZ_FILE_STAT_STRUCT _stat
|
||||
#define MZ_FILE_STAT _stat
|
||||
#else
|
||||
#define MZ_FILE_STAT_STRUCT stat
|
||||
#define MZ_FILE_STAT stat
|
||||
#endif
|
||||
|
||||
#define XMODE 0100777
|
||||
#define RMODE 0100444
|
||||
#define WMODE 0100666
|
||||
#define UNIXMODE 0100644
|
||||
|
||||
MU_TEST(test_exe_permissions) {
|
||||
struct MZ_FILE_STAT_STRUCT file_stats;
|
||||
|
||||
const char *filenames[] = {XFILE};
|
||||
FILE *f = fopen(XFILE, "w");
|
||||
fclose(f);
|
||||
chmod(XFILE, XMODE);
|
||||
|
||||
mu_check(0 == zip_create(ZIPNAME, filenames, 1));
|
||||
remove(XFILE);
|
||||
|
||||
mu_check(0 == zip_extract(ZIPNAME, ".", NULL, NULL));
|
||||
|
||||
mu_check(0 == MZ_FILE_STAT(XFILE, &file_stats));
|
||||
mu_assert_int_eq(XMODE, file_stats.st_mode);
|
||||
}
|
||||
|
||||
MU_TEST(test_read_permissions) {
|
||||
struct MZ_FILE_STAT_STRUCT file_stats;
|
||||
|
||||
const char *filenames[] = {RFILE};
|
||||
FILE *f = fopen(RFILE, "w");
|
||||
fclose(f);
|
||||
chmod(RFILE, RMODE);
|
||||
|
||||
mu_assert_int_eq(0, zip_create(ZIPNAME, filenames, 1));
|
||||
remove(RFILE);
|
||||
|
||||
mu_check(0 == zip_extract(ZIPNAME, ".", NULL, NULL));
|
||||
mu_check(0 == MZ_FILE_STAT(RFILE, &file_stats));
|
||||
mu_assert_int_eq(RMODE, file_stats.st_mode);
|
||||
|
||||
// chmod from 444 to 666 to be able delete the file on windows
|
||||
chmod(RFILE, WMODE);
|
||||
}
|
||||
|
||||
MU_TEST(test_write_permissions) {
|
||||
struct MZ_FILE_STAT_STRUCT file_stats;
|
||||
|
||||
const char *filenames[] = {WFILE};
|
||||
FILE *f = fopen(WFILE, "w");
|
||||
fclose(f);
|
||||
chmod(WFILE, WMODE);
|
||||
|
||||
mu_check(0 == zip_create(ZIPNAME, filenames, 1));
|
||||
remove(WFILE);
|
||||
|
||||
mu_check(0 == zip_extract(ZIPNAME, ".", NULL, NULL));
|
||||
mu_check(0 == MZ_FILE_STAT(WFILE, &file_stats));
|
||||
mu_assert_int_eq(WMODE, file_stats.st_mode);
|
||||
}
|
||||
|
||||
#define TESTDATA1 "Some test data 1...\0"
|
||||
|
||||
MU_TEST(test_unix_permissions) {
|
||||
// UNIX or APPLE
|
||||
struct MZ_FILE_STAT_STRUCT file_stats;
|
||||
|
||||
struct zip_t *zip = zip_open(ZIPNAME, ZIP_DEFAULT_COMPRESSION_LEVEL, 'w');
|
||||
mu_check(zip != NULL);
|
||||
|
||||
mu_check(0 == zip_entry_open(zip, RFILE));
|
||||
mu_check(0 == zip_entry_write(zip, TESTDATA1, strlen(TESTDATA1)));
|
||||
mu_check(0 == zip_entry_close(zip));
|
||||
|
||||
zip_close(zip);
|
||||
|
||||
mu_assert_int_eq(0, zip_extract(ZIPNAME, ".", NULL, NULL));
|
||||
|
||||
mu_check(0 == MZ_FILE_STAT(RFILE, &file_stats));
|
||||
|
||||
mu_assert_int_eq(UNIXMODE, file_stats.st_mode);
|
||||
}
|
||||
|
||||
MU_TEST(test_mtime) {
|
||||
struct MZ_FILE_STAT_STRUCT file_stat1, file_stat2;
|
||||
|
||||
const char *filename = "test.data";
|
||||
FILE *stream = NULL;
|
||||
struct zip_t *zip = NULL;
|
||||
#if defined(_MSC_VER)
|
||||
if (0 != fopen_s(&stream, filename, "w+"))
|
||||
#else
|
||||
if (!(stream = fopen(filename, "w+")))
|
||||
#endif
|
||||
{
|
||||
mu_fail("Cannot open filename\n");
|
||||
}
|
||||
fwrite(TESTDATA1, sizeof(char), strlen(TESTDATA1), stream);
|
||||
mu_check(0 == fclose(stream));
|
||||
|
||||
memset(&file_stat1, 0, sizeof(file_stat1));
|
||||
memset(&file_stat2, 0, sizeof(file_stat2));
|
||||
|
||||
zip = zip_open(ZIPNAME, ZIP_DEFAULT_COMPRESSION_LEVEL, 'w');
|
||||
mu_check(zip != NULL);
|
||||
|
||||
mu_check(0 == zip_entry_open(zip, filename));
|
||||
mu_check(0 == zip_entry_fwrite(zip, filename));
|
||||
mu_check(0 == zip_entry_close(zip));
|
||||
|
||||
zip_close(zip);
|
||||
|
||||
mu_check(0 == MZ_FILE_STAT(filename, &file_stat1));
|
||||
remove(filename);
|
||||
|
||||
mu_assert_int_eq(0, zip_extract(ZIPNAME, ".", NULL, NULL));
|
||||
mu_check(0 == MZ_FILE_STAT(filename, &file_stat2));
|
||||
remove(filename);
|
||||
|
||||
fprintf(stdout, "file_stat1.st_mtime: %lu\n", file_stat1.st_mtime);
|
||||
fprintf(stdout, "file_stat2.st_mtime: %lu\n", file_stat2.st_mtime);
|
||||
mu_check(labs(file_stat1.st_mtime - file_stat2.st_mtime) <= 1);
|
||||
}
|
||||
|
||||
MU_TEST_SUITE(test_permissions_suite) {
|
||||
MU_SUITE_CONFIGURE(&test_setup, &test_teardown);
|
||||
|
||||
#if defined(_WIN32) || defined(__WIN32__)
|
||||
#else
|
||||
MU_RUN_TEST(test_exe_permissions);
|
||||
MU_RUN_TEST(test_read_permissions);
|
||||
MU_RUN_TEST(test_write_permissions);
|
||||
MU_RUN_TEST(test_unix_permissions);
|
||||
#endif
|
||||
MU_RUN_TEST(test_mtime);
|
||||
}
|
||||
|
||||
#define UNUSED(x) (void)x
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
UNUSED(argc);
|
||||
UNUSED(argv);
|
||||
|
||||
MU_RUN_SUITE(test_permissions_suite);
|
||||
MU_REPORT();
|
||||
return MU_EXIT_CODE;
|
||||
}
|
142
test/test_read.c
Normal file
142
test/test_read.c
Normal file
@ -0,0 +1,142 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <zip.h>
|
||||
|
||||
#include "minunit.h"
|
||||
|
||||
static char *ZIPNAME = NULL;
|
||||
|
||||
#define CRC32DATA1 2220805626
|
||||
#define TESTDATA1 "Some test data 1...\0"
|
||||
|
||||
#define TESTDATA2 "Some test data 2...\0"
|
||||
#define CRC32DATA2 2532008468
|
||||
|
||||
void test_setup(void) {
|
||||
ZIPNAME = tempnam(NULL, "z-");
|
||||
|
||||
struct zip_t *zip = zip_open(ZIPNAME, ZIP_DEFAULT_COMPRESSION_LEVEL, 'w');
|
||||
|
||||
zip_entry_open(zip, "test/test-1.txt");
|
||||
zip_entry_write(zip, TESTDATA1, strlen(TESTDATA1));
|
||||
zip_entry_close(zip);
|
||||
|
||||
zip_entry_open(zip, "test\\test-2.txt");
|
||||
zip_entry_write(zip, TESTDATA2, strlen(TESTDATA2));
|
||||
zip_entry_close(zip);
|
||||
|
||||
zip_entry_open(zip, "test\\empty/");
|
||||
zip_entry_close(zip);
|
||||
|
||||
zip_entry_open(zip, "empty/");
|
||||
zip_entry_close(zip);
|
||||
|
||||
zip_entry_open(zip, "dotfiles/.test");
|
||||
zip_entry_write(zip, TESTDATA2, strlen(TESTDATA2));
|
||||
zip_entry_close(zip);
|
||||
|
||||
zip_close(zip);
|
||||
}
|
||||
|
||||
void test_teardown(void) {
|
||||
remove(ZIPNAME);
|
||||
free(ZIPNAME);
|
||||
}
|
||||
|
||||
MU_TEST(test_read) {
|
||||
char *buf = NULL;
|
||||
ssize_t bufsize;
|
||||
size_t buftmp;
|
||||
|
||||
struct zip_t *zip = zip_open(ZIPNAME, 0, 'r');
|
||||
mu_check(zip != NULL);
|
||||
mu_assert_int_eq(0, zip_is64(zip));
|
||||
|
||||
mu_assert_int_eq(0, zip_entry_open(zip, "test\\test-1.txt"));
|
||||
mu_assert_int_eq(strlen(TESTDATA1), zip_entry_size(zip));
|
||||
mu_check(CRC32DATA1 == zip_entry_crc32(zip));
|
||||
bufsize = zip_entry_read(zip, (void **)&buf, &buftmp);
|
||||
mu_assert_int_eq(strlen(TESTDATA1), bufsize);
|
||||
mu_assert_int_eq((size_t)bufsize, buftmp);
|
||||
mu_assert_int_eq(0, strncmp(buf, TESTDATA1, bufsize));
|
||||
mu_assert_int_eq(0, zip_entry_close(zip));
|
||||
free(buf);
|
||||
buf = NULL;
|
||||
|
||||
mu_assert_int_eq(0, zip_entry_open(zip, "test/test-2.txt"));
|
||||
mu_assert_int_eq(strlen(TESTDATA2), zip_entry_size(zip));
|
||||
mu_check(CRC32DATA2 == zip_entry_crc32(zip));
|
||||
bufsize = zip_entry_read(zip, (void **)&buf, NULL);
|
||||
mu_assert_int_eq(strlen(TESTDATA2), (size_t)bufsize);
|
||||
mu_check(0 == strncmp(buf, TESTDATA2, (size_t)bufsize));
|
||||
mu_check(0 == zip_entry_close(zip));
|
||||
free(buf);
|
||||
buf = NULL;
|
||||
|
||||
mu_check(0 == zip_entry_open(zip, "test\\empty/"));
|
||||
mu_check(0 == strcmp(zip_entry_name(zip), "test/empty/"));
|
||||
mu_check(0 == zip_entry_size(zip));
|
||||
mu_check(0 == zip_entry_crc32(zip));
|
||||
mu_check(0 == zip_entry_close(zip));
|
||||
|
||||
zip_close(zip);
|
||||
}
|
||||
|
||||
MU_TEST(test_noallocread) {
|
||||
ssize_t bufsize;
|
||||
size_t buftmp = strlen(TESTDATA2);
|
||||
char *buf = calloc(buftmp, sizeof(char));
|
||||
|
||||
struct zip_t *zip = zip_open(ZIPNAME, 0, 'r');
|
||||
mu_check(zip != NULL);
|
||||
mu_assert_int_eq(0, zip_is64(zip));
|
||||
|
||||
mu_assert_int_eq(0, zip_entry_open(zip, "test/test-2.txt"));
|
||||
bufsize = zip_entry_noallocread(zip, (void *)buf, buftmp);
|
||||
mu_assert_int_eq(buftmp, (size_t)bufsize);
|
||||
mu_check(0 == strncmp(buf, TESTDATA2, buftmp));
|
||||
mu_check(0 == zip_entry_close(zip));
|
||||
free(buf);
|
||||
buf = NULL;
|
||||
|
||||
buftmp = strlen(TESTDATA1);
|
||||
buf = calloc(buftmp, sizeof(char));
|
||||
mu_check(0 == zip_entry_open(zip, "test/test-1.txt"));
|
||||
bufsize = zip_entry_noallocread(zip, (void *)buf, buftmp);
|
||||
mu_assert_int_eq(buftmp, (size_t)bufsize);
|
||||
mu_check(0 == strncmp(buf, TESTDATA1, buftmp));
|
||||
mu_check(0 == zip_entry_close(zip));
|
||||
free(buf);
|
||||
buf = NULL;
|
||||
|
||||
buftmp = strlen(TESTDATA2);
|
||||
buf = calloc(buftmp, sizeof(char));
|
||||
mu_check(0 == zip_entry_open(zip, "dotfiles/.test"));
|
||||
bufsize = zip_entry_noallocread(zip, (void *)buf, buftmp);
|
||||
mu_assert_int_eq(buftmp, (size_t)bufsize);
|
||||
mu_check(0 == strncmp(buf, TESTDATA2, buftmp));
|
||||
mu_check(0 == zip_entry_close(zip));
|
||||
free(buf);
|
||||
buf = NULL;
|
||||
|
||||
zip_close(zip);
|
||||
}
|
||||
|
||||
MU_TEST_SUITE(test_read_suite) {
|
||||
MU_SUITE_CONFIGURE(&test_setup, &test_teardown);
|
||||
|
||||
MU_RUN_TEST(test_read);
|
||||
MU_RUN_TEST(test_noallocread);
|
||||
}
|
||||
|
||||
#define UNUSED(x) (void)x
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
UNUSED(argc);
|
||||
UNUSED(argv);
|
||||
|
||||
MU_RUN_SUITE(test_read_suite);
|
||||
MU_REPORT();
|
||||
return MU_EXIT_CODE;
|
||||
}
|
86
test/test_write.c
Normal file
86
test/test_write.c
Normal file
@ -0,0 +1,86 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <zip.h>
|
||||
|
||||
#include "minunit.h"
|
||||
|
||||
static char *ZIPNAME = NULL;
|
||||
static char *WFILE = NULL;
|
||||
|
||||
void test_setup(void) {
|
||||
ZIPNAME = tempnam(NULL, "z-");
|
||||
WFILE = tempnam(NULL, "w-");
|
||||
}
|
||||
|
||||
void test_teardown(void) {
|
||||
remove(WFILE);
|
||||
free(WFILE);
|
||||
|
||||
remove(ZIPNAME);
|
||||
free(ZIPNAME);
|
||||
}
|
||||
|
||||
#define CRC32DATA1 2220805626
|
||||
#define TESTDATA1 "Some test data 1...\0"
|
||||
|
||||
MU_TEST(test_write) {
|
||||
struct zip_t *zip = zip_open(ZIPNAME, ZIP_DEFAULT_COMPRESSION_LEVEL, 'w');
|
||||
mu_check(zip != NULL);
|
||||
|
||||
mu_assert_int_eq(0, zip_entry_open(zip, "test/test-1.txt"));
|
||||
mu_assert_int_eq(0, zip_entry_write(zip, TESTDATA1, strlen(TESTDATA1)));
|
||||
mu_assert_int_eq(0, strcmp(zip_entry_name(zip), "test/test-1.txt"));
|
||||
mu_assert_int_eq(0, zip_entry_index(zip));
|
||||
mu_assert_int_eq(strlen(TESTDATA1), zip_entry_size(zip));
|
||||
mu_check(CRC32DATA1 == zip_entry_crc32(zip));
|
||||
mu_assert_int_eq(0, zip_entry_close(zip));
|
||||
|
||||
mu_assert_int_eq(0, zip_is64(zip));
|
||||
|
||||
zip_close(zip);
|
||||
}
|
||||
|
||||
MU_TEST(test_fwrite) {
|
||||
const char *filename = WFILE;
|
||||
FILE *stream = NULL;
|
||||
struct zip_t *zip = NULL;
|
||||
#if defined(_MSC_VER)
|
||||
if (0 != fopen_s(&stream, filename, "w+"))
|
||||
#else
|
||||
if (!(stream = fopen(filename, "w+")))
|
||||
#endif
|
||||
{
|
||||
// Cannot open filename
|
||||
mu_fail("Cannot open filename\n");
|
||||
}
|
||||
fwrite(TESTDATA1, sizeof(char), strlen(TESTDATA1), stream);
|
||||
mu_check(0 == fclose(stream));
|
||||
|
||||
zip = zip_open(ZIPNAME, 9, 'w');
|
||||
mu_check(zip != NULL);
|
||||
mu_check(0 == zip_entry_open(zip, WFILE));
|
||||
mu_check(0 == zip_entry_fwrite(zip, WFILE));
|
||||
mu_check(0 == zip_entry_close(zip));
|
||||
mu_check(0 == zip_is64(zip));
|
||||
|
||||
zip_close(zip);
|
||||
}
|
||||
|
||||
MU_TEST_SUITE(test_write_suite) {
|
||||
MU_SUITE_CONFIGURE(&test_setup, &test_teardown);
|
||||
|
||||
MU_RUN_TEST(test_write);
|
||||
MU_RUN_TEST(test_fwrite);
|
||||
}
|
||||
|
||||
#define UNUSED(x) (void)x
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
UNUSED(argc);
|
||||
UNUSED(argv);
|
||||
|
||||
MU_RUN_SUITE(test_write_suite);
|
||||
MU_REPORT();
|
||||
return MU_EXIT_CODE;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user