mirror of
https://github.com/meekrosoft/fff
synced 2026-01-23 08:25:59 +01:00
Renamed to fff and added function call history
This commit is contained in:
25
README
25
README
@@ -1,10 +1,25 @@
|
||||
Fake Function Framework (fff)
|
||||
-----------------------------
|
||||
|
||||
cmock is a micro-framework for creating fake C functions for tests.
|
||||
fff is a micro-framework for creating fake C functions for tests.
|
||||
|
||||
Here are some cmock truths:
|
||||
* It maintains a call count and will capture the arguments sent
|
||||
* It can be used in C or C++ tests
|
||||
So whats the point?
|
||||
* To make it easy to create fake functions for testing C code.
|
||||
* To be simple
|
||||
* To work in both C and C++ tests
|
||||
|
||||
What can it do?
|
||||
* It maintains a call count for each fake function
|
||||
* It captures the arguments sent in each function call
|
||||
* It captures a call history
|
||||
* It is simple - just include a header file and you are good to go.
|
||||
|
||||
What I'd like to add:
|
||||
Under the hood:
|
||||
* The fff.h header file is generated by a ruby script
|
||||
* There are tests under src/test
|
||||
* There are examples for testing an embedded UI under src/examples
|
||||
|
||||
Still Todo:
|
||||
* Function argument history
|
||||
* Proper mock - setting expectations, etc
|
||||
|
||||
|
||||
@@ -4,6 +4,9 @@
|
||||
|
||||
|
||||
$cpp_output = true
|
||||
$MAX_ARGS = 10
|
||||
$MAX_ARG_HISTORY = 10
|
||||
$MAX_CALL_HISTORY = 10
|
||||
|
||||
def output_macro(args, is_value_function)
|
||||
|
||||
@@ -20,13 +23,13 @@ def output_macro(args, is_value_function)
|
||||
puts "{ \\"
|
||||
output_function_body(args, is_value_function)
|
||||
puts " } \\"
|
||||
output_reset_function(args)
|
||||
output_reset_function(args, is_value_function)
|
||||
}
|
||||
puts "STATIC_INIT(FUNCNAME) \\" if $cpp_output
|
||||
puts ""
|
||||
end
|
||||
|
||||
def output_reset_code
|
||||
def output_cpp_reset_code
|
||||
puts <<-REGISTRATION
|
||||
#include <vector>
|
||||
typedef void (*void_fptr)();
|
||||
@@ -44,7 +47,7 @@ void RESET_FAKES()
|
||||
REGISTRATION
|
||||
end
|
||||
|
||||
def output_static_initializer
|
||||
def output_cpp_static_initializer
|
||||
puts <<-MY_STATIC_INITIALIZER
|
||||
#define STATIC_INIT(FUNCNAME) \\
|
||||
class StaticInitializer_##FUNCNAME \\
|
||||
@@ -83,13 +86,21 @@ def output_macro_name(macro_name, args, return_type)
|
||||
puts ") \\"
|
||||
end
|
||||
|
||||
def output_variables(args, is_value_function)
|
||||
args.times { |i| puts " static ARG#{i}_TYPE FUNCNAME##_arg#{i}_val; \\" }
|
||||
def output_argument_capture_variables(i)
|
||||
# last argument
|
||||
puts " static ARG#{i}_TYPE FUNCNAME##_arg#{i}_val; \\"
|
||||
# argument history array
|
||||
# puts " static ARG#{i}_TYPE FUNCNAME##_arg#{i}_history[];"
|
||||
# puts " static int FUNCNAME##_arg#{i}_history_idx;"
|
||||
end
|
||||
|
||||
def output_variables(arg_count, is_value_function)
|
||||
arg_count.times { |i| output_argument_capture_variables(i) }
|
||||
puts " static RETURN_TYPE FUNCNAME##_return_val; \\" unless not is_value_function
|
||||
puts " static int FUNCNAME##_call_count = 0; \\"
|
||||
end
|
||||
|
||||
def output_function_signature(args, is_value_function)
|
||||
def output_function_signature(args_count, is_value_function)
|
||||
if is_value_function
|
||||
print " RETURN_TYPE FUNCNAME("
|
||||
else
|
||||
@@ -97,27 +108,28 @@ def output_function_signature(args, is_value_function)
|
||||
end
|
||||
|
||||
arguments = []
|
||||
args.times { |i| arguments << "ARG#{i}_TYPE arg#{i}" }
|
||||
args_count.times { |i| arguments << "ARG#{i}_TYPE arg#{i}" }
|
||||
print arguments.join(", ")
|
||||
|
||||
print ")"
|
||||
end
|
||||
|
||||
def output_function_body(args, is_value_function)
|
||||
def output_function_body(arg_count, is_value_function)
|
||||
# capture arguments
|
||||
args.times { |i| puts " FUNCNAME##_arg#{i}_val = arg#{i}; \\" }
|
||||
arg_count.times { |i| puts " FUNCNAME##_arg#{i}_val = arg#{i}; \\" }
|
||||
# update call count
|
||||
puts " FUNCNAME##_call_count++; \\"
|
||||
# return something if value function
|
||||
puts " return FUNCNAME##_return_val; \\" unless not is_value_function
|
||||
end
|
||||
|
||||
def output_reset_function(args)
|
||||
def output_reset_function(arg_count, is_value_function)
|
||||
puts " void FUNCNAME##_reset(){ \\"
|
||||
args.times { |i|
|
||||
arg_count.times { |i|
|
||||
puts " FUNCNAME##_arg#{i}_val = (ARG#{i}_TYPE) 0; \\"
|
||||
}
|
||||
puts " FUNCNAME##_call_count = 0; \\"
|
||||
puts " FUNCNAME##_return_val = 0; \\" unless not is_value_function
|
||||
puts " } \\"
|
||||
end
|
||||
|
||||
@@ -130,6 +142,19 @@ def define_reset_fake
|
||||
puts ""
|
||||
end
|
||||
|
||||
def define_call_history
|
||||
puts "#define MAX_CALL_HISTORY #{$MAX_CALL_HISTORY}u"
|
||||
puts "static void * call_history[MAX_CALL_HISTORY];"
|
||||
puts "static unsigned int call_history_idx;"
|
||||
puts "void RESET_HISTORY() { "
|
||||
puts " call_history_idx = 0; "
|
||||
puts "}"
|
||||
|
||||
puts "#define REGISTER_CALL(function) \\"
|
||||
puts " if(call_history_idx < MAX_CALL_HISTORY) call_history[call_history_idx++] = (void *)function;"
|
||||
end
|
||||
|
||||
|
||||
def extern_c
|
||||
puts "extern \"C\"{ \\" unless !$cpp_output
|
||||
yield
|
||||
@@ -166,9 +191,10 @@ end
|
||||
|
||||
# lets generate!!
|
||||
output_c_and_cpp{
|
||||
output_reset_code if $cpp_output
|
||||
output_static_initializer if $cpp_output
|
||||
output_cpp_reset_code if $cpp_output
|
||||
output_cpp_static_initializer if $cpp_output
|
||||
10.times {|arg_count| output_macro(arg_count, false)}
|
||||
10.times {|arg_count| output_macro(arg_count, true)}
|
||||
define_reset_fake
|
||||
define_call_history
|
||||
}
|
||||
@@ -313,6 +313,7 @@ extern "C"{ \
|
||||
} \
|
||||
void FUNCNAME##_reset(){ \
|
||||
FUNCNAME##_call_count = 0; \
|
||||
FUNCNAME##_return_val = 0; \
|
||||
} \
|
||||
} \
|
||||
STATIC_INIT(FUNCNAME) \
|
||||
@@ -332,6 +333,7 @@ extern "C"{ \
|
||||
void FUNCNAME##_reset(){ \
|
||||
FUNCNAME##_arg0_val = (ARG0_TYPE) 0; \
|
||||
FUNCNAME##_call_count = 0; \
|
||||
FUNCNAME##_return_val = 0; \
|
||||
} \
|
||||
} \
|
||||
STATIC_INIT(FUNCNAME) \
|
||||
@@ -354,6 +356,7 @@ extern "C"{ \
|
||||
FUNCNAME##_arg0_val = (ARG0_TYPE) 0; \
|
||||
FUNCNAME##_arg1_val = (ARG1_TYPE) 0; \
|
||||
FUNCNAME##_call_count = 0; \
|
||||
FUNCNAME##_return_val = 0; \
|
||||
} \
|
||||
} \
|
||||
STATIC_INIT(FUNCNAME) \
|
||||
@@ -379,6 +382,7 @@ extern "C"{ \
|
||||
FUNCNAME##_arg1_val = (ARG1_TYPE) 0; \
|
||||
FUNCNAME##_arg2_val = (ARG2_TYPE) 0; \
|
||||
FUNCNAME##_call_count = 0; \
|
||||
FUNCNAME##_return_val = 0; \
|
||||
} \
|
||||
} \
|
||||
STATIC_INIT(FUNCNAME) \
|
||||
@@ -407,6 +411,7 @@ extern "C"{ \
|
||||
FUNCNAME##_arg2_val = (ARG2_TYPE) 0; \
|
||||
FUNCNAME##_arg3_val = (ARG3_TYPE) 0; \
|
||||
FUNCNAME##_call_count = 0; \
|
||||
FUNCNAME##_return_val = 0; \
|
||||
} \
|
||||
} \
|
||||
STATIC_INIT(FUNCNAME) \
|
||||
@@ -438,6 +443,7 @@ extern "C"{ \
|
||||
FUNCNAME##_arg3_val = (ARG3_TYPE) 0; \
|
||||
FUNCNAME##_arg4_val = (ARG4_TYPE) 0; \
|
||||
FUNCNAME##_call_count = 0; \
|
||||
FUNCNAME##_return_val = 0; \
|
||||
} \
|
||||
} \
|
||||
STATIC_INIT(FUNCNAME) \
|
||||
@@ -472,6 +478,7 @@ extern "C"{ \
|
||||
FUNCNAME##_arg4_val = (ARG4_TYPE) 0; \
|
||||
FUNCNAME##_arg5_val = (ARG5_TYPE) 0; \
|
||||
FUNCNAME##_call_count = 0; \
|
||||
FUNCNAME##_return_val = 0; \
|
||||
} \
|
||||
} \
|
||||
STATIC_INIT(FUNCNAME) \
|
||||
@@ -509,6 +516,7 @@ extern "C"{ \
|
||||
FUNCNAME##_arg5_val = (ARG5_TYPE) 0; \
|
||||
FUNCNAME##_arg6_val = (ARG6_TYPE) 0; \
|
||||
FUNCNAME##_call_count = 0; \
|
||||
FUNCNAME##_return_val = 0; \
|
||||
} \
|
||||
} \
|
||||
STATIC_INIT(FUNCNAME) \
|
||||
@@ -549,6 +557,7 @@ extern "C"{ \
|
||||
FUNCNAME##_arg6_val = (ARG6_TYPE) 0; \
|
||||
FUNCNAME##_arg7_val = (ARG7_TYPE) 0; \
|
||||
FUNCNAME##_call_count = 0; \
|
||||
FUNCNAME##_return_val = 0; \
|
||||
} \
|
||||
} \
|
||||
STATIC_INIT(FUNCNAME) \
|
||||
@@ -592,6 +601,7 @@ extern "C"{ \
|
||||
FUNCNAME##_arg7_val = (ARG7_TYPE) 0; \
|
||||
FUNCNAME##_arg8_val = (ARG8_TYPE) 0; \
|
||||
FUNCNAME##_call_count = 0; \
|
||||
FUNCNAME##_return_val = 0; \
|
||||
} \
|
||||
} \
|
||||
STATIC_INIT(FUNCNAME) \
|
||||
@@ -602,6 +612,14 @@ STATIC_INIT(FUNCNAME) \
|
||||
FUNCNAME##_reset(); \
|
||||
} \
|
||||
|
||||
#define MAX_CALL_HISTORY 10u
|
||||
static void * call_history[MAX_CALL_HISTORY];
|
||||
static unsigned int call_history_idx;
|
||||
void RESET_HISTORY() {
|
||||
call_history_idx = 0;
|
||||
}
|
||||
#define REGISTER_CALL(function) \
|
||||
if(call_history_idx < MAX_CALL_HISTORY) call_history[call_history_idx++] = (void *)function;
|
||||
#else /* ansi c */
|
||||
|
||||
/* Defining a void function with 0 parameters*/
|
||||
@@ -859,6 +877,7 @@ STATIC_INIT(FUNCNAME) \
|
||||
} \
|
||||
void FUNCNAME##_reset(){ \
|
||||
FUNCNAME##_call_count = 0; \
|
||||
FUNCNAME##_return_val = 0; \
|
||||
} \
|
||||
|
||||
|
||||
@@ -875,6 +894,7 @@ STATIC_INIT(FUNCNAME) \
|
||||
void FUNCNAME##_reset(){ \
|
||||
FUNCNAME##_arg0_val = (ARG0_TYPE) 0; \
|
||||
FUNCNAME##_call_count = 0; \
|
||||
FUNCNAME##_return_val = 0; \
|
||||
} \
|
||||
|
||||
|
||||
@@ -894,6 +914,7 @@ STATIC_INIT(FUNCNAME) \
|
||||
FUNCNAME##_arg0_val = (ARG0_TYPE) 0; \
|
||||
FUNCNAME##_arg1_val = (ARG1_TYPE) 0; \
|
||||
FUNCNAME##_call_count = 0; \
|
||||
FUNCNAME##_return_val = 0; \
|
||||
} \
|
||||
|
||||
|
||||
@@ -916,6 +937,7 @@ STATIC_INIT(FUNCNAME) \
|
||||
FUNCNAME##_arg1_val = (ARG1_TYPE) 0; \
|
||||
FUNCNAME##_arg2_val = (ARG2_TYPE) 0; \
|
||||
FUNCNAME##_call_count = 0; \
|
||||
FUNCNAME##_return_val = 0; \
|
||||
} \
|
||||
|
||||
|
||||
@@ -941,6 +963,7 @@ STATIC_INIT(FUNCNAME) \
|
||||
FUNCNAME##_arg2_val = (ARG2_TYPE) 0; \
|
||||
FUNCNAME##_arg3_val = (ARG3_TYPE) 0; \
|
||||
FUNCNAME##_call_count = 0; \
|
||||
FUNCNAME##_return_val = 0; \
|
||||
} \
|
||||
|
||||
|
||||
@@ -969,6 +992,7 @@ STATIC_INIT(FUNCNAME) \
|
||||
FUNCNAME##_arg3_val = (ARG3_TYPE) 0; \
|
||||
FUNCNAME##_arg4_val = (ARG4_TYPE) 0; \
|
||||
FUNCNAME##_call_count = 0; \
|
||||
FUNCNAME##_return_val = 0; \
|
||||
} \
|
||||
|
||||
|
||||
@@ -1000,6 +1024,7 @@ STATIC_INIT(FUNCNAME) \
|
||||
FUNCNAME##_arg4_val = (ARG4_TYPE) 0; \
|
||||
FUNCNAME##_arg5_val = (ARG5_TYPE) 0; \
|
||||
FUNCNAME##_call_count = 0; \
|
||||
FUNCNAME##_return_val = 0; \
|
||||
} \
|
||||
|
||||
|
||||
@@ -1034,6 +1059,7 @@ STATIC_INIT(FUNCNAME) \
|
||||
FUNCNAME##_arg5_val = (ARG5_TYPE) 0; \
|
||||
FUNCNAME##_arg6_val = (ARG6_TYPE) 0; \
|
||||
FUNCNAME##_call_count = 0; \
|
||||
FUNCNAME##_return_val = 0; \
|
||||
} \
|
||||
|
||||
|
||||
@@ -1071,6 +1097,7 @@ STATIC_INIT(FUNCNAME) \
|
||||
FUNCNAME##_arg6_val = (ARG6_TYPE) 0; \
|
||||
FUNCNAME##_arg7_val = (ARG7_TYPE) 0; \
|
||||
FUNCNAME##_call_count = 0; \
|
||||
FUNCNAME##_return_val = 0; \
|
||||
} \
|
||||
|
||||
|
||||
@@ -1111,6 +1138,7 @@ STATIC_INIT(FUNCNAME) \
|
||||
FUNCNAME##_arg7_val = (ARG7_TYPE) 0; \
|
||||
FUNCNAME##_arg8_val = (ARG8_TYPE) 0; \
|
||||
FUNCNAME##_call_count = 0; \
|
||||
FUNCNAME##_return_val = 0; \
|
||||
} \
|
||||
|
||||
|
||||
@@ -1119,6 +1147,14 @@ STATIC_INIT(FUNCNAME) \
|
||||
FUNCNAME##_reset(); \
|
||||
} \
|
||||
|
||||
#define MAX_CALL_HISTORY 10u
|
||||
static void * call_history[MAX_CALL_HISTORY];
|
||||
static unsigned int call_history_idx;
|
||||
void RESET_HISTORY() {
|
||||
call_history_idx = 0;
|
||||
}
|
||||
#define REGISTER_CALL(function) \
|
||||
if(call_history_idx < MAX_CALL_HISTORY) call_history[call_history_idx++] = (void *)function;
|
||||
#endif /* cpp/ansi c */
|
||||
|
||||
#endif // FAKE_FUNCTIONS
|
||||
@@ -6,7 +6,7 @@
|
||||
*/
|
||||
|
||||
#include "embedded.h"
|
||||
#include "../cmock.h"
|
||||
#include "../fff.h"
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
// Description : Hello World in C++, Ansi-style
|
||||
//============================================================================
|
||||
|
||||
#include "../cmock.h"
|
||||
#include "../fff.h"
|
||||
|
||||
extern "C"{
|
||||
#include "embedded.h"
|
||||
|
||||
Reference in New Issue
Block a user