From 8f6a0d2dc74d41d50ba03ec386e447a7a4814410 Mon Sep 17 00:00:00 2001 From: Marc Ransome Date: Sat, 28 Sep 2024 23:11:53 +0100 Subject: [PATCH 1/4] Add config test for reading message from stream --- test/test_config.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/test/test_config.c b/test/test_config.c index 44f7d34..33d6de6 100644 --- a/test/test_config.c +++ b/test/test_config.c @@ -681,6 +681,35 @@ flog_config_new_with_long_append_opt_and_path_succeeds(void **state) { flog_config_free(config); } +static void +flog_config_new_with_message_from_stream_succeeds(void **state) { + UNUSED(state); + + FlogError error = TEST_ERROR; + MOCK_ARGS( + TEST_PROGRAM_NAME, + TEST_MESSAGE + ) + + char *message = "0123456789ABCDEF"; + + FILE *saved_stdin = stdin; + stdin = fmemopen(message, strlen(message), "r"); + + FlogConfig *config = flog_config_new(mock_argc, mock_argv, &error); + + // Ensure stdin stream is restored before making assertions in order to avoid impacting + // other tests if an assertion fails and leaves stdin pointing to the in-memory buffer + fclose(stdin); + stdin = saved_stdin; + + assert_non_null(config); + assert_int_equal(error, FLOG_ERROR_NONE); + assert_string_equal(flog_config_get_message(config), message); + + flog_config_free(config); +} + static void flog_config_new_with_long_version_opt_succeeds(void **state) { UNUSED(state); @@ -1359,6 +1388,7 @@ int main(void) { cmocka_unit_test(flog_config_new_with_long_level_opt_and_fault_value_succeeds), cmocka_unit_test(flog_config_new_with_long_private_opt_and_message_succeeds), cmocka_unit_test(flog_config_new_with_long_append_opt_and_path_succeeds), + cmocka_unit_test(flog_config_new_with_message_from_stream_succeeds), cmocka_unit_test(flog_config_new_with_short_version_opt_succeeds), cmocka_unit_test(flog_config_new_with_long_version_opt_succeeds), cmocka_unit_test(flog_config_new_with_short_help_opt_succeeds), From 08d863767f7af91b34dca13fad4da71760b9dcf5 Mon Sep 17 00:00:00 2001 From: Marc Ransome Date: Sat, 28 Sep 2024 23:19:55 +0100 Subject: [PATCH 2/4] Remove argc precondition to permit no arg operation with stream --- src/config.c | 1 - test/test_config.c | 21 ++++----------------- 2 files changed, 4 insertions(+), 18 deletions(-) diff --git a/src/config.c b/src/config.c index d316886..73032ec 100644 --- a/src/config.c +++ b/src/config.c @@ -70,7 +70,6 @@ struct FlogConfigData { FlogConfig * flog_config_new(int argc, char *argv[], FlogError *error) { - assert(argc > 1); assert(argv != NULL); assert(error != NULL); diff --git a/test/test_config.c b/test/test_config.c index 33d6de6..a644d22 100644 --- a/test/test_config.c +++ b/test/test_config.c @@ -78,24 +78,13 @@ #define UNUSED(x) (void)(x) -static void -flog_config_new_with_zero_arg_count_fails(void **state) { - UNUSED(state); - - FlogError error; // should pass non-null assertion (&error) - int mock_argc = 0; // should fail >1 assertion - char *mock_argv[] = {}; // should pass non-null assertion - - expect_assert_failure(flog_config_new(mock_argc, mock_argv, &error)); -} - static void flog_config_new_with_null_arg_values_fails(void **state) { UNUSED(state); - FlogError error; // should pass non-null assertion (&error) - int mock_argc = 2; // should pass >1 assertion + int mock_argc = 0; char **mock_argv = NULL; // should fail non-null assertion + FlogError error; // should pass non-null assertion (&error) expect_assert_failure(flog_config_new(mock_argc, mock_argv, &error)); } @@ -103,7 +92,7 @@ flog_config_new_with_null_arg_values_fails(void **state) { static void test_new_config_with_no_error_ptr_calls_assert(void **state) { UNUSED(state); - int mock_argc = 2; // should pass >1 assertion + int mock_argc = 0; char *mock_argv[] = {}; // should pass non-null assertion expect_assert_failure(flog_config_new(mock_argc, mock_argv, NULL)); @@ -687,8 +676,7 @@ flog_config_new_with_message_from_stream_succeeds(void **state) { FlogError error = TEST_ERROR; MOCK_ARGS( - TEST_PROGRAM_NAME, - TEST_MESSAGE + TEST_PROGRAM_NAME ) char *message = "0123456789ABCDEF"; @@ -1354,7 +1342,6 @@ int main(void) { const struct CMUnitTest tests[] = { // flog_config_new() precondition tests - cmocka_unit_test(flog_config_new_with_zero_arg_count_fails), cmocka_unit_test(flog_config_new_with_null_arg_values_fails), // flog_config_new() failure tests From 5930d91fb676775838d52d7fd9613f0cb52b8ad2 Mon Sep 17 00:00:00 2001 From: Marc Ransome Date: Sat, 28 Sep 2024 23:26:42 +0100 Subject: [PATCH 3/4] Show usage when stdin is a tty and no args provided --- src/main.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main.c b/src/main.c index 3e63ac5..8378df6 100644 --- a/src/main.c +++ b/src/main.c @@ -22,13 +22,14 @@ #include #include +#include #include "flog.h" #include "common.h" int main(int argc, char *argv[]) { - if (argc == 1 ) { + if (argc == 1 && isatty(fileno(stdin))) { flog_usage(); return 1; } From 4a4c0b85377dad891eaab7e8045b2348684d86a6 Mon Sep 17 00:00:00 2001 From: Marc Ransome Date: Sun, 29 Sep 2024 00:38:12 +0100 Subject: [PATCH 4/4] Update flog_config_new documentation --- src/config.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/config.h b/src/config.h index d8d845b..9daceb5 100644 --- a/src/config.h +++ b/src/config.h @@ -68,7 +68,6 @@ typedef struct FlogConfigData FlogConfig; * \param[out] error A pointer to a FlogError object that will be used to represent * an error condition on failure * - * \pre \c argc is greater than \c 1 * \pre \c argv is \e not \c NULL * \pre \c error is \e not \c NULL *