بنقرة واحدة
mocking
Mocking skill for the ikigai project
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
القائمة
Mocking skill for the ikigai project
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
استنادا إلى تصنيف SOC المهني
Automated quality check loops with escalation and fix sub-agents
JSON-based end-to-end test format, runner, and mock provider
Jujutsu (jj) skill for the ikigai project
How to write effective Ralph goals for Ikigai-driven workflows
Create and manage Ralph goals from Ikigai using the real ralph-pipeline scripts
Create repositories using the real ralph-pipeline repo-create script
| name | mocking |
| description | Mocking skill for the ikigai project |
MOCKABLE wrapper patterns for testing external dependencies.
Mock external dependencies, never our own code. External means: libraries (talloc, yyjson, curl), system calls (open, read, write, stat), and vendor inline functions.
wrapper.h provides zero-overhead mocking via weak symbols:
// wrapper.h
#ifdef NDEBUG
#define MOCKABLE static inline // Release: zero overhead
#else
#define MOCKABLE __attribute__((weak)) // Debug: overridable
#endif
MOCKABLE int posix_write_(int fd, const void *buf, size_t count);
Override the weak symbol in your test file:
// test_file.c
#include "wrapper.h"
// Override - this replaces the weak symbol
int posix_write_(int fd, const void *buf, size_t count) {
return -1; // Simulate write failure
}
void test_write_error_handling(void) {
// Now any code calling posix_write_() gets our mock
res_t r = save_file("test.txt", "content");
assert(IS_ERR(r));
}
| Wrapper | Wraps |
|---|---|
posix_open_() | open() |
posix_close_() | close() |
posix_read_() | read() |
posix_write_() | write() |
posix_stat_() | stat() |
posix_mkdir_() | mkdir() |
posix_access_() | access() |
posix_rename_() | rename() |
posix_getcwd_() | getcwd() |
posix_pipe_() | pipe() |
posix_fcntl_() | fcntl() |
posix_select_() | select() |
posix_sigaction_() | sigaction() |
posix_ioctl_() | ioctl() |
posix_tcgetattr_() | tcgetattr() |
posix_tcsetattr_() | tcsetattr() |
posix_tcflush_() | tcflush() |
| Wrapper | Wraps |
|---|---|
fopen_() | fopen() |
fclose_() | fclose() |
fread_() | fread() |
fwrite_() | fwrite() |
fseek_() | fseek() |
ftell_() | ftell() |
posix_fdopen_() | fdopen() |
popen_() | popen() |
pclose_() | pclose() |
opendir_() | opendir() |
| Wrapper | Wraps |
|---|---|
snprintf_() | snprintf() |
vsnprintf_() | vsnprintf() |
gmtime_() | gmtime() |
strftime_() | strftime() |
| Wrapper | Wraps |
|---|---|
talloc_zero_() | talloc_zero_size() |
talloc_strdup_() | talloc_strdup() |
talloc_array_() | talloc_zero_size() |
talloc_realloc_() | talloc_realloc_size() |
talloc_asprintf_() | talloc_vasprintf() |
| Wrapper | Wraps |
|---|---|
yyjson_read_file_() | yyjson_read_file() |
yyjson_mut_write_file_() | yyjson_mut_write_file() |
yyjson_read_() | yyjson_read() |
yyjson_doc_get_root_() | yyjson_doc_get_root() |
yyjson_obj_get_() | yyjson_obj_get() |
yyjson_get_sint_() | yyjson_get_sint() |
yyjson_get_str_() | yyjson_get_str() |
yyjson_mut_obj_add_str_() | yyjson_mut_obj_add_str() |
yyjson_mut_obj_add_int_() | yyjson_mut_obj_add_int() |
yyjson_mut_obj_add_uint_() | yyjson_mut_obj_add_uint() |
yyjson_mut_obj_() | yyjson_mut_obj() |
yyjson_mut_arr_() | yyjson_mut_arr() |
yyjson_mut_obj_add_val_() | yyjson_mut_obj_add_val() |
yyjson_mut_arr_add_val_() | yyjson_mut_arr_add_val() |
yyjson_mut_obj_add_bool_() | yyjson_mut_obj_add_bool() |
yyjson_val_mut_copy_() | yyjson_val_mut_copy() |
| Wrapper | Wraps |
|---|---|
curl_easy_init_() | curl_easy_init() |
curl_easy_cleanup_() | curl_easy_cleanup() |
curl_easy_perform_() | curl_easy_perform() |
curl_easy_setopt_() | curl_easy_setopt() |
curl_easy_getinfo_() | curl_easy_getinfo() |
curl_easy_strerror_() | curl_easy_strerror() |
curl_slist_append_() | curl_slist_append() |
curl_slist_free_all_() | curl_slist_free_all() |
| Wrapper | Wraps |
|---|---|
curl_multi_init_() | curl_multi_init() |
curl_multi_cleanup_() | curl_multi_cleanup() |
curl_multi_add_handle_() | curl_multi_add_handle() |
curl_multi_remove_handle_() | curl_multi_remove_handle() |
curl_multi_perform_() | curl_multi_perform() |
curl_multi_fdset_() | curl_multi_fdset() |
curl_multi_timeout_() | curl_multi_timeout() |
curl_multi_info_read_() | curl_multi_info_read() |
curl_multi_strerror_() | curl_multi_strerror() |
| Wrapper | Wraps |
|---|---|
PQgetvalue_() | PQgetvalue() |
pq_exec_() | PQexec() |
pq_exec_params_() | PQexecParams() |
PQresultStatus_() | PQresultStatus() |
| Wrapper | Wraps |
|---|---|
pthread_mutex_init_() | pthread_mutex_init() |
pthread_mutex_destroy_() | pthread_mutex_destroy() |
pthread_mutex_lock_() | pthread_mutex_lock() |
pthread_mutex_unlock_() | pthread_mutex_unlock() |
pthread_create_() | pthread_create() |
pthread_join_() | pthread_join() |
| Wrapper | Wraps |
|---|---|
ik_db_init_() | ik_db_init() |
ik_db_message_insert_() | ik_db_message_insert() |
ik_scrollback_append_line_() | ik_scrollback_append_line() |
ik_repl_render_frame_() | ik_repl_render_frame() |
ik_agent_get_provider_() | ik_agent_get_provider() |
ik_request_build_from_conversation_() | ik_request_build_from_conversation() |
ik_http_multi_create_() | ik_http_multi_create() |
ik_http_multi_info_read_() | ik_http_multi_info_read() |
ik_agent_start_tool_execution_() | ik_agent_start_tool_execution() |
ik_agent_should_continue_tool_loop_() | ik_agent_should_continue_tool_loop() |
ik_repl_submit_tool_loop_continuation_() | ik_repl_submit_tool_loop_continuation() |
ik_agent_add_message_() | ik_agent_add_message() |
ik_agent_transition_to_idle_() | ik_agent_transition_to_idle() |
When you need to mock a new external dependency:
wrapper.h:MOCKABLE return_type function_name_(args);
wrapper.c:return_type function_name_(args) {
return original_function(args);
}
Replace direct calls in production code with the wrapper
Override in tests to inject failures
Problem: Inline functions like yyjson_doc_get_root() expand at every call site, creating untestable branches.
Solution: Wrap once, use wrapper everywhere:
// sse_parser.h
yyjson_val *yyjson_doc_get_root_wrapper(yyjson_doc *doc);
// sse_parser.c
yyjson_val *yyjson_doc_get_root_wrapper(yyjson_doc *doc) {
return yyjson_doc_get_root(doc); // Inline expands here only
}
// Test both branches once
void test_wrapper_null(void) {
assert(yyjson_doc_get_root_wrapper(NULL) == NULL);
}
void test_wrapper_valid(void) {
yyjson_doc *doc = create_test_doc();
assert(yyjson_doc_get_root_wrapper(doc) != NULL);
}
src/wrapper.h - MOCKABLE declarationssrc/wrapper.c - Wrapper implementationssrc/openai/sse_parser.h - Inline wrapper example