Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
271d456
adding test for mock io redirect
dreamer-coding May 19, 2025
7119439
ensure io streams are in common source
dreamer-coding May 19, 2025
d5f53bd
add mock io
dreamer-coding May 19, 2025
40e8f68
add macro for posix source
dreamer-coding May 19, 2025
f8ec949
make mock function request for params optional
dreamer-coding May 19, 2025
6d31610
do a magic trick to allow void no args list
dreamer-coding May 19, 2025
2767d89
give mac a slice of types
dreamer-coding May 19, 2025
325ce01
adding another macro code
dreamer-coding May 19, 2025
c1f3d21
apply simple change
dreamer-coding May 19, 2025
2dff9a8
testing
dreamer-coding May 19, 2025
e48883c
clang compiler
dreamer-coding May 19, 2025
4334eac
fix ci file format
dreamer-coding May 19, 2025
da8298f
revert
dreamer-coding May 19, 2025
194c23e
revert change to mock func
dreamer-coding May 19, 2025
cd89bca
update macro logic
dreamer-coding May 19, 2025
3d10e35
fix macro and cheese
dreamer-coding May 19, 2025
8c2f1a5
test
dreamer-coding May 19, 2025
8f74467
Update common.h
dreamer-coding May 21, 2025
2ed669d
Update common.h
dreamer-coding May 21, 2025
b033bd6
Update test_mock.c
dreamer-coding May 21, 2025
f40ad22
Update test_mock.cpp
dreamer-coding May 21, 2025
0febec0
Update mock.h
dreamer-coding May 21, 2025
9b8edc1
Update test_mock.c
dreamer-coding May 21, 2025
6c762a4
Update mock.c
dreamer-coding May 21, 2025
2dbe8ef
Update mock.h
dreamer-coding May 21, 2025
d2909a5
Update mock.h
dreamer-coding May 21, 2025
2d76755
Update test_mock.c
dreamer-coding May 21, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions code/logic/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -1205,6 +1205,10 @@ bool pizza_sys_memory_is_valid(const pizza_sys_memory_t ptr) {
// output management
// *****************************************************************************

pizza_fstream_t *PIZZA_STDIN;
pizza_fstream_t *PIZZA_STDOUT;
pizza_fstream_t *PIZZA_STDERR;

int32_t PIZZA_IO_COLOR_ENABLE = 1; // Flag to enable/disable color output
int32_t FOSSIL_IO_ATTR_ENABLE = 1; // Flag to enable/disable attribute output

Expand Down
7 changes: 3 additions & 4 deletions code/logic/fossil/pizza/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,21 +19,21 @@
#include <stdlib.h>
#include <stdint.h>
#include <stdarg.h>
#include <unistd.h>
#include <string.h>
#include <time.h>
#include <stdio.h>
#include <float.h>
#include <ctype.h>
#include <math.h>
#include <unistd.h> // Only include once

#ifdef _WIN32
#include <windows.h>
#include <sys/stat.h>
#elif defined(__APPLE__)
#define _DARWIN_C_SOURCE
#include <sys/utsname.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/types.h> // Before sysctl.h
#include <sys/sysctl.h>
#include <sys/stat.h>
#include <mach/mach_time.h>
Expand All @@ -43,7 +43,6 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <unistd.h>
#endif

#ifndef _POSIX_C_SOURCE
Expand Down
69 changes: 69 additions & 0 deletions code/logic/fossil/pizza/mock.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,25 @@ void fossil_mock_add_call(fossil_mock_calllist_t *list, const char *function_nam
*/
void fossil_mock_print(fossil_mock_calllist_t *list);

/**
* Captures the output of a function to a buffer for testing purposes.
*
* @param buffer The buffer to store the captured output.
* @param size The size of the buffer.
* @param function The function whose output is to be captured.
* @return The number of characters captured.
*/
int fossil_mock_capture_output(char *buffer, size_t size, void (*function)(void));

/**
* Compares the captured output with the expected output.
*
* @param captured The captured output.
* @param expected The expected output.
* @return True if the captured output matches the expected output, false otherwise.
*/
bool fossil_mock_compare_output(const char *captured, const char *expected);

#ifdef __cplusplus
}
#endif
Expand Down Expand Up @@ -211,6 +230,30 @@ void fossil_mock_print(fossil_mock_calllist_t *list);
typedef struct name
#endif

/**
* @def _FOSSIL_MOCK_REDIRECT_STDOUT
* @brief Macro for redirecting stdout to a buffer.
*
* This macro redirects stdout to a buffer for capturing output.
*
* @param buffer The buffer to capture the output.
* @param size The size of the buffer.
*/
#define _FOSSIL_MOCK_CAPTURE_OUTPUT(buffer, size, function) \
fossil_mock_capture_output(buffer, size, function)

/**
* @def _FOSSIL_MOCK_REDIRECT_STDOUT
* @brief Macro for redirecting stdout to a buffer.
*
* This macro redirects stdout to a buffer for capturing output.
*
* @param buffer The buffer to capture the output.
* @param size The size of the buffer.
*/
#define _FOSSIL_MOCK_COMPARE_OUTPUT(captured, expected) \
fossil_mock_compare_output(captured, expected)

// *****************************************************************************
// Public API Macros
// *****************************************************************************
Expand Down Expand Up @@ -299,4 +342,30 @@ void fossil_mock_print(fossil_mock_calllist_t *list);
#define FOSSIL_MOCK_STRUCT(name) \
_FOSSIL_MOCK_STRUCT(name)

/**
* @def FOSSIL_MOCK_REDIRECT_STDOUT
* @brief Macro for redirecting stdout to a buffer.
*
* This macro redirects stdout to a buffer for capturing output.
*
* @param buffer The buffer to capture the output.
* @param size The size of the buffer.
*/
#define FOSSIL_MOCK_REDIRECT_STDOUT(buffer, size, function) \
_FOSSIL_MOCK_CAPTURE_OUTPUT(buffer, size, function)

/**
* @def FOSSIL_MOCK_COMPARE_OUTPUT
* @brief Macro for comparing captured output with expected output.
*
* This macro compares the captured output with the expected output.
*
* @param captured The captured output.
* @param expected The expected output.
* @return True if the captured output matches the expected output, false otherwise.
*/
#define FOSSIL_MOCK_COMPARE_OUTPUT(captured, expected) \
_FOSSIL_MOCK_COMPARE_OUTPUT(captured, expected)

#endif // FOSSIL_MOCK_FRAMEWORK_H

45 changes: 44 additions & 1 deletion code/logic/mock.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
* Copyright (C) 2014-2025 Fossil Logic. All rights reserved.
* -----------------------------------------------------------------------------
*/
#define _POSIX_C_SOURCE 200809L
#include "fossil/pizza/mock.h"
#include "fossil/pizza/common.h"

// *****************************************************************************
// Function declarations
Expand Down Expand Up @@ -134,3 +134,46 @@ void fossil_mock_print(fossil_mock_calllist_t *list) {
current = current->next;
}
}

int fossil_mock_capture_output(char *buffer, size_t size, void (*function)(void)) {
if (!buffer || size == 0 || !function) {
return -1;
}

FILE *temp_file = tmpfile();
if (!temp_file) {
return -1;
}

int original_stdout_fd = dup(STDOUT_FILENO);
if (original_stdout_fd == -1) {
fclose(temp_file);
return -1;
}
fflush(stdout);
if (dup2(fileno(temp_file), STDOUT_FILENO) == -1) {
fclose(temp_file);
close(original_stdout_fd);
return -1;
}

function(); // no arguments passed

fflush(stdout);
dup2(original_stdout_fd, STDOUT_FILENO);
close(original_stdout_fd);

rewind(temp_file);
size_t read_size = fread(buffer, 1, size - 1, temp_file);
buffer[read_size] = '\0';

fclose(temp_file);
return (int)read_size;
}

bool fossil_mock_compare_output(const char *captured, const char *expected) {
if (!captured || !expected) {
return false;
}
return strcmp(captured, expected) == 0;
}
61 changes: 61 additions & 0 deletions code/tests/cases/test_mock.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,14 @@ FOSSIL_MOCK_FUNC(int, c_mock_function, int a, int b) {
return a + b;
}

FOSSIL_MOCK_FUNC(void, c_mock_function_with_output, void) {
pizza_io_printf("Hello, Fossil Logic!");
}

FOSSIL_MOCK_FUNC(void, mock_function_redirection, void) {
pizza_io_printf("Testing macro redirection!");
}

// * * * * * * * * * * * * * * * * * * * * * * * *
// * Fossil Logic Test Cases
// * * * * * * * * * * * * * * * * * * * * * * * *
Expand Down Expand Up @@ -323,6 +331,53 @@ FOSSIL_TEST(c_mock_macro_destruction) {
FOSSIL_TEST_ASSUME(list.size == 0, "fossil_mock_calllist_t size should be 0 after destruction using macro");
} // end case

FOSSIL_TEST(c_mock_io_capture_output) {
// Buffer to capture output
char buffer[256];

// Capture the output of the mock function
int captured_size = fossil_mock_capture_output(buffer, sizeof(buffer), fossil_mockup_c_mock_function_with_output);

// Test cases
FOSSIL_TEST_ASSUME(captured_size > 0, "Captured size should be greater than 0");
FOSSIL_TEST_ASSUME(strcmp(buffer, "Hello, Fossil Logic!") == 0, "Captured output should match expected output");
} // end case

FOSSIL_TEST(c_mock_io_compare_output) {
// Captured and expected outputs
const char *captured = "Hello, Fossil Logic!";
const char *expected = "Hello, Fossil Logic!";

// Compare the outputs
bool result = fossil_mock_compare_output(captured, expected);

// Test cases
FOSSIL_TEST_ASSUME(result == true, "Captured output should match expected output");
} // end case

FOSSIL_TEST(c_mock_io_redirect_stdout_macro) {
// Buffer to capture output
char buffer[256];

// Use the macro to redirect stdout and capture output
FOSSIL_MOCK_REDIRECT_STDOUT(buffer, sizeof(buffer), fossil_mockup_mock_function_redirection);

// Test cases
FOSSIL_TEST_ASSUME(strcmp(buffer, "Testing macro redirection!") == 0, "Captured output should match expected output");
} // end case

FOSSIL_TEST(c_mock_io_compare_output_macro) {
// Captured and expected outputs
const char *captured = "Macro comparison test!";
const char *expected = "Macro comparison test!";

// Use the macro to compare outputs
bool result = FOSSIL_MOCK_COMPARE_OUTPUT(captured, expected);

// Test cases
FOSSIL_TEST_ASSUME(result == true, "Captured output should match expected output using macro");
} // end case

// * * * * * * * * * * * * * * * * * * * * * * * *
// * Fossil Logic Test Pool
// * * * * * * * * * * * * * * * * * * * * * * * *
Expand All @@ -341,5 +396,11 @@ FOSSIL_TEST_GROUP(c_mock_test_cases) {
FOSSIL_TEST_ADD(c_mock_suite, c_mock_macro_addition);
FOSSIL_TEST_ADD(c_mock_suite, c_mock_macro_destruction);

FOSSIL_TEST_ADD(c_mock_suite, c_mock_io_capture_output);
FOSSIL_TEST_ADD(c_mock_suite, c_mock_io_compare_output);
FOSSIL_TEST_ADD(c_mock_suite, c_mock_io_redirect_stdout_macro);
FOSSIL_TEST_ADD(c_mock_suite, c_mock_io_compare_output_macro);
FOSSIL_TEST_ADD(c_mock_suite, c_mock_io_compare_output);

FOSSIL_TEST_REGISTER(c_mock_suite);
} // end of group
75 changes: 68 additions & 7 deletions code/tests/cases/test_mock.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,14 @@ FOSSIL_MOCK_FUNC(int, cpp_mock_function, int a, int b) {
return a + b;
}

FOSSIL_MOCK_FUNC(void, cpp_mock_function_with_output, void) {
pizza_io_printf("Hello, Fossil Logic!");
}

FOSSIL_MOCK_FUNC(void, mock_function_redirection, void) {
pizza_io_printf("Testing macro redirection!");
}

// * * * * * * * * * * * * * * * * * * * * * * * *
// * Fossil Logic Test Cases
// * * * * * * * * * * * * * * * * * * * * * * * *
Expand All @@ -62,8 +70,8 @@ FOSSIL_TEST(cpp_mock_call_list_initialization) {
fossil_mock_init(&list);

// Test cases
FOSSIL_TEST_ASSUME(list.head == nullptr, "fossil_mock_calllist_t head should be nullptr after initialization");
FOSSIL_TEST_ASSUME(list.tail == nullptr, "fossil_mock_calllist_t tail should be nullptr after initialization");
FOSSIL_TEST_ASSUME(list.head == NULL, "fossil_mock_calllist_t head should be NULL after initialization");
FOSSIL_TEST_ASSUME(list.tail == NULL, "fossil_mock_calllist_t tail should be NULL after initialization");
FOSSIL_TEST_ASSUME(list.size == 0, "fossil_mock_calllist_t size should be 0 after initialization");
} // end case

Expand Down Expand Up @@ -208,7 +216,7 @@ FOSSIL_TEST(cpp_mock_call_list_edge_cases) {
fossil_mock_init(&list);

// Add a call with no arguments
fossil_mock_add_call(&list, "no_args_function", nullptr, 0);
fossil_mock_add_call(&list, "no_args_function", NULL, 0);

// Test cases
FOSSIL_TEST_ASSUME(list.size == 1, "fossil_mock_calllist_t size should be 1 after adding a call with no arguments");
Expand Down Expand Up @@ -253,8 +261,8 @@ FOSSIL_TEST(cpp_mock_macro_initialization) {
MOCK_INIT(list);

// Test cases
FOSSIL_TEST_ASSUME(list.head == nullptr, "fossil_mock_calllist_t head should be nullptr after initialization using macro");
FOSSIL_TEST_ASSUME(list.tail == nullptr, "fossil_mock_calllist_t tail should be nullptr after initialization using macro");
FOSSIL_TEST_ASSUME(list.head == NULL, "fossil_mock_calllist_t head should be NULL after initialization using macro");
FOSSIL_TEST_ASSUME(list.tail == NULL, "fossil_mock_calllist_t tail should be NULL after initialization using macro");
FOSSIL_TEST_ASSUME(list.size == 0, "fossil_mock_calllist_t size should be 0 after initialization using macro");
} // end case

Expand Down Expand Up @@ -318,11 +326,58 @@ FOSSIL_TEST(cpp_mock_macro_destruction) {
MOCK_DESTROY(list);

// Test cases
FOSSIL_TEST_ASSUME(list.head == nullptr, "fossil_mock_calllist_t head should be nullptr after destruction using macro");
FOSSIL_TEST_ASSUME(list.tail == nullptr, "fossil_mock_calllist_t tail should be nullptr after destruction using macro");
FOSSIL_TEST_ASSUME(list.head == NULL, "fossil_mock_calllist_t head should be NULL after destruction using macro");
FOSSIL_TEST_ASSUME(list.tail == NULL, "fossil_mock_calllist_t tail should be NULL after destruction using macro");
FOSSIL_TEST_ASSUME(list.size == 0, "fossil_mock_calllist_t size should be 0 after destruction using macro");
} // end case

FOSSIL_TEST(cpp_mock_io_capture_output) {
// Buffer to capture output
char buffer[256];

// Capture the output of the mock function
int captured_size = fossil_mock_capture_output(buffer, sizeof(buffer), fossil_mockup_cpp_mock_function_with_output);

// Test cases
FOSSIL_TEST_ASSUME(captured_size > 0, "Captured size should be greater than 0");
FOSSIL_TEST_ASSUME(strcmp(buffer, "Hello, Fossil Logic!") == 0, "Captured output should match expected output");
} // end case

FOSSIL_TEST(cpp_mock_io_compare_output) {
// Captured and expected outputs
const char *captured = "Hello, Fossil Logic!";
const char *expected = "Hello, Fossil Logic!";

// Compare the outputs
bool result = fossil_mock_compare_output(captured, expected);

// Test cases
FOSSIL_TEST_ASSUME(result == true, "Captured output should match expected output");
} // end case

FOSSIL_TEST(cpp_mock_io_redirect_stdout_macro) {
// Buffer to capture output
char buffer[256];

// Use the macro to redirect stdout and capture output
FOSSIL_MOCK_REDIRECT_STDOUT(buffer, sizeof(buffer), fossil_mockup_mock_function_redirection);

// Test cases
FOSSIL_TEST_ASSUME(strcmp(buffer, "Testing macro redirection!") == 0, "Captured output should match expected output");
} // end case

FOSSIL_TEST(cpp_mock_io_compare_output_macro) {
// Captured and expected outputs
const char *captured = "Macro comparison test!";
const char *expected = "Macro comparison test!";

// Use the macro to compare outputs
bool result = FOSSIL_MOCK_COMPARE_OUTPUT(captured, expected);

// Test cases
FOSSIL_TEST_ASSUME(result == true, "Captured output should match expected output using macro");
} // end case

// * * * * * * * * * * * * * * * * * * * * * * * *
// * Fossil Logic Test Pool
// * * * * * * * * * * * * * * * * * * * * * * * *
Expand All @@ -341,5 +396,11 @@ FOSSIL_TEST_GROUP(cpp_mock_test_cases) {
FOSSIL_TEST_ADD(cpp_mock_suite, cpp_mock_macro_addition);
FOSSIL_TEST_ADD(cpp_mock_suite, cpp_mock_macro_destruction);

FOSSIL_TEST_ADD(cpp_mock_suite, cpp_mock_io_capture_output);
FOSSIL_TEST_ADD(cpp_mock_suite, cpp_mock_io_compare_output);
FOSSIL_TEST_ADD(cpp_mock_suite, cpp_mock_io_redirect_stdout_macro);
FOSSIL_TEST_ADD(cpp_mock_suite, cpp_mock_io_compare_output_macro);
FOSSIL_TEST_ADD(cpp_mock_suite, cpp_mock_io_compare_output);

FOSSIL_TEST_REGISTER(cpp_mock_suite);
} // end of group