|
|
#include "../../unity/unity.h" |
|
|
|
|
|
#include <stdio.h> |
|
|
#include <stdlib.h> |
|
|
#include <string.h> |
|
|
#include <unistd.h> |
|
|
#include <fcntl.h> |
|
|
#include <errno.h> |
|
|
|
|
|
|
|
|
static FILE *test_last_stream_seen = NULL; |
|
|
static int test_callback_invoked = 0; |
|
|
static size_t test_bytes_read = 0; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static char *make_temp_file_with_content(const char *content) |
|
|
{ |
|
|
char tmp_template[] = "/tmp/cut_ut_XXXXXX"; |
|
|
int fd = mkstemp(tmp_template); |
|
|
TEST_ASSERT_MESSAGE(fd >= 0, "mkstemp failed"); |
|
|
size_t len = strlen(content); |
|
|
if (len > 0) |
|
|
{ |
|
|
ssize_t w = write(fd, content, len); |
|
|
TEST_ASSERT_MESSAGE(w == (ssize_t)len, "write failed to write all content"); |
|
|
} |
|
|
int rc = close(fd); |
|
|
TEST_ASSERT_MESSAGE(rc == 0, "close(temp file) failed"); |
|
|
|
|
|
|
|
|
char *path = (char *)malloc(strlen(tmp_template) + 1); |
|
|
TEST_ASSERT_NOT_NULL(path); |
|
|
strcpy(path, tmp_template); |
|
|
return path; |
|
|
} |
|
|
|
|
|
|
|
|
static void reopen_stdin_from_path(const char *path) |
|
|
{ |
|
|
FILE *f = freopen(path, "r", stdin); |
|
|
TEST_ASSERT_MESSAGE(f != NULL, "freopen on stdin failed"); |
|
|
} |
|
|
|
|
|
|
|
|
static void test_cut_stream_read_all(FILE *s) |
|
|
{ |
|
|
test_callback_invoked++; |
|
|
test_last_stream_seen = s; |
|
|
test_bytes_read = 0; |
|
|
int ch; |
|
|
while ((ch = getc(s)) != EOF) |
|
|
{ |
|
|
test_bytes_read++; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
static void test_cut_stream_noop(FILE *s) |
|
|
{ |
|
|
(void)s; |
|
|
test_callback_invoked++; |
|
|
test_last_stream_seen = s; |
|
|
} |
|
|
|
|
|
|
|
|
void setUp(void) |
|
|
{ |
|
|
test_last_stream_seen = NULL; |
|
|
test_callback_invoked = 0; |
|
|
test_bytes_read = 0; |
|
|
errno = 0; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
extern bool have_read_stdin; |
|
|
have_read_stdin = false; |
|
|
|
|
|
|
|
|
clearerr(stdin); |
|
|
} |
|
|
|
|
|
void tearDown(void) |
|
|
{ |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
static void test_cut_file_stdin_reads_and_clears_eof(void) |
|
|
{ |
|
|
|
|
|
char *p = make_temp_file_with_content("ABC"); |
|
|
reopen_stdin_from_path(p); |
|
|
|
|
|
extern bool have_read_stdin; |
|
|
|
|
|
bool ok = cut_file("-", test_cut_stream_read_all); |
|
|
TEST_ASSERT_TRUE(ok); |
|
|
TEST_ASSERT_TRUE(have_read_stdin); |
|
|
TEST_ASSERT_EQUAL_INT(1, test_callback_invoked); |
|
|
TEST_ASSERT_EQUAL_PTR(stdin, test_last_stream_seen); |
|
|
TEST_ASSERT_EQUAL_UINT32(3u, (unsigned) test_bytes_read); |
|
|
|
|
|
|
|
|
TEST_ASSERT_FALSE(feof(stdin)); |
|
|
|
|
|
free(p); |
|
|
} |
|
|
|
|
|
|
|
|
static void test_cut_file_regular_file_success(void) |
|
|
{ |
|
|
char *p = make_temp_file_with_content("xyz123"); |
|
|
extern bool have_read_stdin; |
|
|
|
|
|
bool ok = cut_file(p, test_cut_stream_read_all); |
|
|
TEST_ASSERT_TRUE(ok); |
|
|
TEST_ASSERT_FALSE(have_read_stdin); |
|
|
TEST_ASSERT_EQUAL_INT(1, test_callback_invoked); |
|
|
TEST_ASSERT_NOT_NULL(test_last_stream_seen); |
|
|
|
|
|
TEST_ASSERT_NOT_EQUAL_PTR(stdin, test_last_stream_seen); |
|
|
TEST_ASSERT_EQUAL_UINT32(6u, (unsigned) test_bytes_read); |
|
|
|
|
|
|
|
|
int rc = unlink(p); |
|
|
(void)rc; |
|
|
free(p); |
|
|
} |
|
|
|
|
|
|
|
|
static void test_cut_file_nonexistent_returns_false(void) |
|
|
{ |
|
|
const char *nonexistent = "/tmp/cut_ut_no_such_file____XXXX"; |
|
|
extern bool have_read_stdin; |
|
|
|
|
|
bool ok = cut_file(nonexistent, test_cut_stream_noop); |
|
|
TEST_ASSERT_FALSE(ok); |
|
|
TEST_ASSERT_EQUAL_INT(0, test_callback_invoked); |
|
|
TEST_ASSERT_FALSE(have_read_stdin); |
|
|
} |
|
|
|
|
|
|
|
|
static void test_cut_file_stdin_no_read_sets_flag(void) |
|
|
{ |
|
|
|
|
|
char *p = make_temp_file_with_content(""); |
|
|
reopen_stdin_from_path(p); |
|
|
|
|
|
extern bool have_read_stdin; |
|
|
|
|
|
bool ok = cut_file("-", test_cut_stream_noop); |
|
|
TEST_ASSERT_TRUE(ok); |
|
|
TEST_ASSERT_TRUE(have_read_stdin); |
|
|
TEST_ASSERT_EQUAL_INT(1, test_callback_invoked); |
|
|
TEST_ASSERT_EQUAL_PTR(stdin, test_last_stream_seen); |
|
|
|
|
|
TEST_ASSERT_FALSE(feof(stdin)); |
|
|
|
|
|
free(p); |
|
|
} |
|
|
|
|
|
int main(void) |
|
|
{ |
|
|
UNITY_BEGIN(); |
|
|
|
|
|
RUN_TEST(test_cut_file_stdin_reads_and_clears_eof); |
|
|
RUN_TEST(test_cut_file_regular_file_success); |
|
|
RUN_TEST(test_cut_file_nonexistent_returns_false); |
|
|
RUN_TEST(test_cut_file_stdin_no_read_sets_flag); |
|
|
|
|
|
return UNITY_END(); |
|
|
} |