I'm just an IT-circle Porter, project site HTTPS://GITHUB.COM/MEEKROSOFT/FFF
FFF is a macro implementation of the small framework, only need a header file fff.h, no other dependencies, very concise.
The core of FFF is three macros:
Fake_void_func (FN [, arg_types*]);
Defines a pile function named FN, with a null return value and N parameters.
Fake_value_func (Return_type, FN [, arg_types*]);
Defines a pile function named FN with a return value of type Return_type and N parameters.
Reset_fake (FN);
Resets the call information for the pile function fn.
Implementation, FFF generates a series of variables for the pile. Take the example of a pile function with a return value and a parameter:
#define  DECLARE_FAKE_VALUE_FUNC1 (Return_type, funcname, arg0_type) extern_c typedef struct funcname# #_Fake { declare_arg (ARG0_TYPE, 0, funcname) declare_ All_func_common declare_value_ Function_variables (return_type) Return_type (*custom_fake) (arg0_type arg0); } funcname# #_Fake, extern funcname# #_Fake funcname# #_ fake; void funcname# #_reset (); end_extern_c \
Declare_arg generates a variable that stores the value of the current parameter and an array of stored historical parameter values.
#define DECLARE_ARG (type, n, FUNCNAME) type arg# #n # #_val; Type arg# #n # #_history [Fff_arg_history_len];
Declare_all_func_common defines the number of times a pile is called, the length of the parameter history array, and the number of times the history_dropped is called.
#define Declare_all_func_common unsigned int call_count; unsigned int arg_history_len; unsigned int arg_histories_dropped; \
Declare_value_function_variables defines the data related to the return value of the pile function.
Custom_fake provides a callback interface that can be used to construct the return value using its own function.
Instance:
#include "UI.h" #include "... /.. /fff.h "#include SYSTEM.h" #include "DISPLAY.h" #include <assert.h> #include < stdio.h> #include <string.h>/* Test Framework :-) */void setup (); #define test_f (Suite, name) void name () #define &NBSP;RUN_TEST (Suite, testname) printf (" running %s.%s: \n ", #SUITE, #TESTNAME); setup (); testname (); printf (" success\n ");D Efine_fff_globals;/* system.h */fake_void_func2 (system_register_irq, irq_ Func_t, unsigned int);/* display.h */fake_void_func (Display_init); Fake_void_func (display_clear); Fake_void_func (display_output, char *); Fake_value_func (unsigned int, display_get_line_capacity); Fake_value_func (Unsigned int, display_get_line_insert_index); FAKE_VOID_FUNC0 (BUTTON_PRESS_CBK);/* initialializers called for every test */ void Setup () {reset_fake (SYSTEM_REGISTER_IRQ); Reset_fake (Display_init) reset_fake (display_clear) reset_fake (display_output) Reset_fake (DISPLAY_get_line_ capacity) Reset_fake (Display_get_line_insert_index); Reset_fake (BUTTON_PRESS_CBK); Fff_reset_history ();D isplay_get_line_capacity_fake.return_val = 2;} /* tests go here */test_f (Uitests, init_will_initialise_display) {UI_init (); Assert ( DISPLAY_INIT_FAKE.CALL_COUNT&NBSP;==&NBSP;1);} Test_f (Uitests, init_will_register_interrupt_gpio2) {ui_init (); assert (SYSTEM_ register_irq_fake.call_count == 1); assert (System_register_irq_fake.arg0_val == ui_button_irq_handler); assert (system_register_irq_fake.arg1_val == irq_gpio_2);} Test_f (Uitests, when_no_irq_then_missed_irq_counter_zero) { assert (UI_get_missed_ IRQs () == 0);} Test_f (Uitests, when_one_irq_and_no_handler_then_missed_irq_counter_One) {Ui_button_irq_handler (); assert (Ui_get_missed_irqs () == 1);} Test_f (Uitests, when_one_irq_and_valid_callback_then_missed_irq_counter_zero) {UI_init (); UI_REGISTER_BUTTON_CBK (BUTTON_PRESS_CBK); Ui_button_irq_handler (); assert (Ui_get_missed_irqs () == 0); Test_f (uitests, when_one_irq_and_valid_callback_then_callback_called) {UI_REGISTER_BUTTON_CBK (button_press _CBK); Ui_button_irq_handler (); assert (button_press_cbk_fake.call_count == 1);} Test_f (Uitests, write_line_outputs_lines_to_display) {char msg[] = "HelloWorld"; Ui_write_line (msg); assert (display_output_fake.call_count == 1); Assert (STRNCMP (display_output_ FAKE.ARG0_VAL,&NBSP;MSG,&NBSP;26) == 0);} Test_f (uitests, when_no_empty_lines_write_line_clears_screen_and_outputs_lines_to_display) {DISPLAY_get_ line_insert_index_fake.return_val = 2;char msg[] = "HelloWorld"; Ui_write_line (msg); Assert (DISPLAY_CLEAR_FAKE.CALL_COUNT&NBSP;==&NBSP;1); assert (display_output_fake.call_count == 1);// Check the order of the calls: don ' t care about the First two:// display_get_line_capacity and display_get_line_insert_indexassert (Fff.call_ HISTORY_IDX&NBSP;==&NBSP;4); Assert (fff.call_history[2] == (void *) display_clear); Assert ( fff.call_history[3] == (void *) display_output);} Test_f (uitests, when_empty_lines_write_line_doesnt_clear_screen) {// givendisplay_get_line_insert_ index_fake.return_val = 1;char msg[] = "HelloWorld";// whenui_write_line (msg);// thenassert (display_clear_fake.call_count == 0);} Test_f (uitests, when_string_longer_than_26_then_truncated_string_output) {// givenchar input[] = "abcdefghijklmnopqrstuvwxyz0123456789";char expected[] = " Abcdefghijklmnopqrstuvwxyz";// whenui_write_line (input);// thenassert (strncmp (Expected, display_output_fake.arg0_val, 37) == 0);} Test_f (uitests, when_outputting_to_full_display_then_previous_inserted) {// givendisplay_get_line_ insert_index_fake.return_val = 1;char oldest[] = "Oldest"; char newest[] = "Newest";// whenui_write_line (oldest); Ui_write_line (newest);// thenassert (display_output_fake.call_count == 2);// fills Last lineassert (strncmp (oldest, display_output_fake.arg0_history[0], 37) == 0);// Clearsassert (display_clear_fake.call_count == 1);// inserts old line at Firstassert (strncmp (oldest, display_output_fake.arg0_history[1], 37) == 0);// then inserts new lineassert (strncmp (newest, display_output_fake.arg0_history[2], 37) == 0);} Int main () {setbuf (stdout, null); fprintf (stdout, "-------------\ n"), fprintf (stdout, "running tests\n"), fprintf (stdout, "-------------\ N\n "); fflush (0);/* run tests */ run_test (UITests , init_will_initialise_display); run_test (Uitests, init_will_register_ Interrupt_gpio2); run_test (Uitests, when_no_irq_then_missed_irq_counter_zero); run_test (Uitests, when_one_irq_and_no_handler_then_missed_irq_counter_one); run_test (Uitests, when_one_irq_and_valid_callback_then_missed_irq_counter_zero); run_test (uitests, when_one_irq_and_valid_callback_then_callback_called); run_test (Uitests, write_line_outputs_lines_to_display); run_test ( Uitests, when_no_empty_lines_write_line_clears_screen_and_outputs_lines_to_display); run_test (Uitests, when_empty_lines_write_line_doesnt_clear_screen); run_test (UITests, when_string_longer _than_26_then_truncated_string_output) printf ("\ n-------------\ n"); printf ("complete\n");p rintf ("-------------\ n"); return 0;}
C-code Piling frame-FFF (Fake Function framework)