Renamed to fff and added function call history

This commit is contained in:
Mike Long
2010-12-21 22:35:16 +01:00
parent 98cde86ef8
commit e4ffef00fc
5 changed files with 97 additions and 20 deletions

25
README
View File

@@ -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: So whats the point?
* It maintains a call count and will capture the arguments sent * To make it easy to create fake functions for testing C code.
* It can be used in C or C++ tests * 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. * 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 * Proper mock - setting expectations, etc

View File

@@ -4,6 +4,9 @@
$cpp_output = true $cpp_output = true
$MAX_ARGS = 10
$MAX_ARG_HISTORY = 10
$MAX_CALL_HISTORY = 10
def output_macro(args, is_value_function) def output_macro(args, is_value_function)
@@ -20,13 +23,13 @@ def output_macro(args, is_value_function)
puts "{ \\" puts "{ \\"
output_function_body(args, is_value_function) output_function_body(args, is_value_function)
puts " } \\" puts " } \\"
output_reset_function(args) output_reset_function(args, is_value_function)
} }
puts "STATIC_INIT(FUNCNAME) \\" if $cpp_output puts "STATIC_INIT(FUNCNAME) \\" if $cpp_output
puts "" puts ""
end end
def output_reset_code def output_cpp_reset_code
puts <<-REGISTRATION puts <<-REGISTRATION
#include <vector> #include <vector>
typedef void (*void_fptr)(); typedef void (*void_fptr)();
@@ -44,7 +47,7 @@ void RESET_FAKES()
REGISTRATION REGISTRATION
end end
def output_static_initializer def output_cpp_static_initializer
puts <<-MY_STATIC_INITIALIZER puts <<-MY_STATIC_INITIALIZER
#define STATIC_INIT(FUNCNAME) \\ #define STATIC_INIT(FUNCNAME) \\
class StaticInitializer_##FUNCNAME \\ class StaticInitializer_##FUNCNAME \\
@@ -83,13 +86,21 @@ def output_macro_name(macro_name, args, return_type)
puts ") \\" puts ") \\"
end end
def output_variables(args, is_value_function) def output_argument_capture_variables(i)
args.times { |i| puts " static ARG#{i}_TYPE FUNCNAME##_arg#{i}_val; \\" } # 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 RETURN_TYPE FUNCNAME##_return_val; \\" unless not is_value_function
puts " static int FUNCNAME##_call_count = 0; \\" puts " static int FUNCNAME##_call_count = 0; \\"
end end
def output_function_signature(args, is_value_function) def output_function_signature(args_count, is_value_function)
if is_value_function if is_value_function
print " RETURN_TYPE FUNCNAME(" print " RETURN_TYPE FUNCNAME("
else else
@@ -97,27 +108,28 @@ def output_function_signature(args, is_value_function)
end end
arguments = [] arguments = []
args.times { |i| arguments << "ARG#{i}_TYPE arg#{i}" } args_count.times { |i| arguments << "ARG#{i}_TYPE arg#{i}" }
print arguments.join(", ") print arguments.join(", ")
print ")" print ")"
end end
def output_function_body(args, is_value_function) def output_function_body(arg_count, is_value_function)
# capture arguments # 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 # update call count
puts " FUNCNAME##_call_count++; \\" puts " FUNCNAME##_call_count++; \\"
# return something if value function # return something if value function
puts " return FUNCNAME##_return_val; \\" unless not is_value_function puts " return FUNCNAME##_return_val; \\" unless not is_value_function
end end
def output_reset_function(args) def output_reset_function(arg_count, is_value_function)
puts " void FUNCNAME##_reset(){ \\" puts " void FUNCNAME##_reset(){ \\"
args.times { |i| arg_count.times { |i|
puts " FUNCNAME##_arg#{i}_val = (ARG#{i}_TYPE) 0; \\" puts " FUNCNAME##_arg#{i}_val = (ARG#{i}_TYPE) 0; \\"
} }
puts " FUNCNAME##_call_count = 0; \\" puts " FUNCNAME##_call_count = 0; \\"
puts " FUNCNAME##_return_val = 0; \\" unless not is_value_function
puts " } \\" puts " } \\"
end end
@@ -130,6 +142,19 @@ def define_reset_fake
puts "" puts ""
end 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 def extern_c
puts "extern \"C\"{ \\" unless !$cpp_output puts "extern \"C\"{ \\" unless !$cpp_output
yield yield
@@ -166,9 +191,10 @@ end
# lets generate!! # lets generate!!
output_c_and_cpp{ output_c_and_cpp{
output_reset_code if $cpp_output output_cpp_reset_code if $cpp_output
output_static_initializer 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, false)}
10.times {|arg_count| output_macro(arg_count, true)} 10.times {|arg_count| output_macro(arg_count, true)}
define_reset_fake define_reset_fake
define_call_history
} }

View File

@@ -313,6 +313,7 @@ extern "C"{ \
} \ } \
void FUNCNAME##_reset(){ \ void FUNCNAME##_reset(){ \
FUNCNAME##_call_count = 0; \ FUNCNAME##_call_count = 0; \
FUNCNAME##_return_val = 0; \
} \ } \
} \ } \
STATIC_INIT(FUNCNAME) \ STATIC_INIT(FUNCNAME) \
@@ -332,6 +333,7 @@ extern "C"{ \
void FUNCNAME##_reset(){ \ void FUNCNAME##_reset(){ \
FUNCNAME##_arg0_val = (ARG0_TYPE) 0; \ FUNCNAME##_arg0_val = (ARG0_TYPE) 0; \
FUNCNAME##_call_count = 0; \ FUNCNAME##_call_count = 0; \
FUNCNAME##_return_val = 0; \
} \ } \
} \ } \
STATIC_INIT(FUNCNAME) \ STATIC_INIT(FUNCNAME) \
@@ -354,6 +356,7 @@ extern "C"{ \
FUNCNAME##_arg0_val = (ARG0_TYPE) 0; \ FUNCNAME##_arg0_val = (ARG0_TYPE) 0; \
FUNCNAME##_arg1_val = (ARG1_TYPE) 0; \ FUNCNAME##_arg1_val = (ARG1_TYPE) 0; \
FUNCNAME##_call_count = 0; \ FUNCNAME##_call_count = 0; \
FUNCNAME##_return_val = 0; \
} \ } \
} \ } \
STATIC_INIT(FUNCNAME) \ STATIC_INIT(FUNCNAME) \
@@ -379,6 +382,7 @@ extern "C"{ \
FUNCNAME##_arg1_val = (ARG1_TYPE) 0; \ FUNCNAME##_arg1_val = (ARG1_TYPE) 0; \
FUNCNAME##_arg2_val = (ARG2_TYPE) 0; \ FUNCNAME##_arg2_val = (ARG2_TYPE) 0; \
FUNCNAME##_call_count = 0; \ FUNCNAME##_call_count = 0; \
FUNCNAME##_return_val = 0; \
} \ } \
} \ } \
STATIC_INIT(FUNCNAME) \ STATIC_INIT(FUNCNAME) \
@@ -407,6 +411,7 @@ extern "C"{ \
FUNCNAME##_arg2_val = (ARG2_TYPE) 0; \ FUNCNAME##_arg2_val = (ARG2_TYPE) 0; \
FUNCNAME##_arg3_val = (ARG3_TYPE) 0; \ FUNCNAME##_arg3_val = (ARG3_TYPE) 0; \
FUNCNAME##_call_count = 0; \ FUNCNAME##_call_count = 0; \
FUNCNAME##_return_val = 0; \
} \ } \
} \ } \
STATIC_INIT(FUNCNAME) \ STATIC_INIT(FUNCNAME) \
@@ -438,6 +443,7 @@ extern "C"{ \
FUNCNAME##_arg3_val = (ARG3_TYPE) 0; \ FUNCNAME##_arg3_val = (ARG3_TYPE) 0; \
FUNCNAME##_arg4_val = (ARG4_TYPE) 0; \ FUNCNAME##_arg4_val = (ARG4_TYPE) 0; \
FUNCNAME##_call_count = 0; \ FUNCNAME##_call_count = 0; \
FUNCNAME##_return_val = 0; \
} \ } \
} \ } \
STATIC_INIT(FUNCNAME) \ STATIC_INIT(FUNCNAME) \
@@ -472,6 +478,7 @@ extern "C"{ \
FUNCNAME##_arg4_val = (ARG4_TYPE) 0; \ FUNCNAME##_arg4_val = (ARG4_TYPE) 0; \
FUNCNAME##_arg5_val = (ARG5_TYPE) 0; \ FUNCNAME##_arg5_val = (ARG5_TYPE) 0; \
FUNCNAME##_call_count = 0; \ FUNCNAME##_call_count = 0; \
FUNCNAME##_return_val = 0; \
} \ } \
} \ } \
STATIC_INIT(FUNCNAME) \ STATIC_INIT(FUNCNAME) \
@@ -509,6 +516,7 @@ extern "C"{ \
FUNCNAME##_arg5_val = (ARG5_TYPE) 0; \ FUNCNAME##_arg5_val = (ARG5_TYPE) 0; \
FUNCNAME##_arg6_val = (ARG6_TYPE) 0; \ FUNCNAME##_arg6_val = (ARG6_TYPE) 0; \
FUNCNAME##_call_count = 0; \ FUNCNAME##_call_count = 0; \
FUNCNAME##_return_val = 0; \
} \ } \
} \ } \
STATIC_INIT(FUNCNAME) \ STATIC_INIT(FUNCNAME) \
@@ -549,6 +557,7 @@ extern "C"{ \
FUNCNAME##_arg6_val = (ARG6_TYPE) 0; \ FUNCNAME##_arg6_val = (ARG6_TYPE) 0; \
FUNCNAME##_arg7_val = (ARG7_TYPE) 0; \ FUNCNAME##_arg7_val = (ARG7_TYPE) 0; \
FUNCNAME##_call_count = 0; \ FUNCNAME##_call_count = 0; \
FUNCNAME##_return_val = 0; \
} \ } \
} \ } \
STATIC_INIT(FUNCNAME) \ STATIC_INIT(FUNCNAME) \
@@ -592,6 +601,7 @@ extern "C"{ \
FUNCNAME##_arg7_val = (ARG7_TYPE) 0; \ FUNCNAME##_arg7_val = (ARG7_TYPE) 0; \
FUNCNAME##_arg8_val = (ARG8_TYPE) 0; \ FUNCNAME##_arg8_val = (ARG8_TYPE) 0; \
FUNCNAME##_call_count = 0; \ FUNCNAME##_call_count = 0; \
FUNCNAME##_return_val = 0; \
} \ } \
} \ } \
STATIC_INIT(FUNCNAME) \ STATIC_INIT(FUNCNAME) \
@@ -602,6 +612,14 @@ STATIC_INIT(FUNCNAME) \
FUNCNAME##_reset(); \ 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 */ #else /* ansi c */
/* Defining a void function with 0 parameters*/ /* Defining a void function with 0 parameters*/
@@ -859,6 +877,7 @@ STATIC_INIT(FUNCNAME) \
} \ } \
void FUNCNAME##_reset(){ \ void FUNCNAME##_reset(){ \
FUNCNAME##_call_count = 0; \ FUNCNAME##_call_count = 0; \
FUNCNAME##_return_val = 0; \
} \ } \
@@ -875,6 +894,7 @@ STATIC_INIT(FUNCNAME) \
void FUNCNAME##_reset(){ \ void FUNCNAME##_reset(){ \
FUNCNAME##_arg0_val = (ARG0_TYPE) 0; \ FUNCNAME##_arg0_val = (ARG0_TYPE) 0; \
FUNCNAME##_call_count = 0; \ FUNCNAME##_call_count = 0; \
FUNCNAME##_return_val = 0; \
} \ } \
@@ -894,6 +914,7 @@ STATIC_INIT(FUNCNAME) \
FUNCNAME##_arg0_val = (ARG0_TYPE) 0; \ FUNCNAME##_arg0_val = (ARG0_TYPE) 0; \
FUNCNAME##_arg1_val = (ARG1_TYPE) 0; \ FUNCNAME##_arg1_val = (ARG1_TYPE) 0; \
FUNCNAME##_call_count = 0; \ FUNCNAME##_call_count = 0; \
FUNCNAME##_return_val = 0; \
} \ } \
@@ -916,6 +937,7 @@ STATIC_INIT(FUNCNAME) \
FUNCNAME##_arg1_val = (ARG1_TYPE) 0; \ FUNCNAME##_arg1_val = (ARG1_TYPE) 0; \
FUNCNAME##_arg2_val = (ARG2_TYPE) 0; \ FUNCNAME##_arg2_val = (ARG2_TYPE) 0; \
FUNCNAME##_call_count = 0; \ FUNCNAME##_call_count = 0; \
FUNCNAME##_return_val = 0; \
} \ } \
@@ -941,6 +963,7 @@ STATIC_INIT(FUNCNAME) \
FUNCNAME##_arg2_val = (ARG2_TYPE) 0; \ FUNCNAME##_arg2_val = (ARG2_TYPE) 0; \
FUNCNAME##_arg3_val = (ARG3_TYPE) 0; \ FUNCNAME##_arg3_val = (ARG3_TYPE) 0; \
FUNCNAME##_call_count = 0; \ FUNCNAME##_call_count = 0; \
FUNCNAME##_return_val = 0; \
} \ } \
@@ -969,6 +992,7 @@ STATIC_INIT(FUNCNAME) \
FUNCNAME##_arg3_val = (ARG3_TYPE) 0; \ FUNCNAME##_arg3_val = (ARG3_TYPE) 0; \
FUNCNAME##_arg4_val = (ARG4_TYPE) 0; \ FUNCNAME##_arg4_val = (ARG4_TYPE) 0; \
FUNCNAME##_call_count = 0; \ FUNCNAME##_call_count = 0; \
FUNCNAME##_return_val = 0; \
} \ } \
@@ -1000,6 +1024,7 @@ STATIC_INIT(FUNCNAME) \
FUNCNAME##_arg4_val = (ARG4_TYPE) 0; \ FUNCNAME##_arg4_val = (ARG4_TYPE) 0; \
FUNCNAME##_arg5_val = (ARG5_TYPE) 0; \ FUNCNAME##_arg5_val = (ARG5_TYPE) 0; \
FUNCNAME##_call_count = 0; \ FUNCNAME##_call_count = 0; \
FUNCNAME##_return_val = 0; \
} \ } \
@@ -1034,6 +1059,7 @@ STATIC_INIT(FUNCNAME) \
FUNCNAME##_arg5_val = (ARG5_TYPE) 0; \ FUNCNAME##_arg5_val = (ARG5_TYPE) 0; \
FUNCNAME##_arg6_val = (ARG6_TYPE) 0; \ FUNCNAME##_arg6_val = (ARG6_TYPE) 0; \
FUNCNAME##_call_count = 0; \ FUNCNAME##_call_count = 0; \
FUNCNAME##_return_val = 0; \
} \ } \
@@ -1071,6 +1097,7 @@ STATIC_INIT(FUNCNAME) \
FUNCNAME##_arg6_val = (ARG6_TYPE) 0; \ FUNCNAME##_arg6_val = (ARG6_TYPE) 0; \
FUNCNAME##_arg7_val = (ARG7_TYPE) 0; \ FUNCNAME##_arg7_val = (ARG7_TYPE) 0; \
FUNCNAME##_call_count = 0; \ FUNCNAME##_call_count = 0; \
FUNCNAME##_return_val = 0; \
} \ } \
@@ -1111,6 +1138,7 @@ STATIC_INIT(FUNCNAME) \
FUNCNAME##_arg7_val = (ARG7_TYPE) 0; \ FUNCNAME##_arg7_val = (ARG7_TYPE) 0; \
FUNCNAME##_arg8_val = (ARG8_TYPE) 0; \ FUNCNAME##_arg8_val = (ARG8_TYPE) 0; \
FUNCNAME##_call_count = 0; \ FUNCNAME##_call_count = 0; \
FUNCNAME##_return_val = 0; \
} \ } \
@@ -1119,6 +1147,14 @@ STATIC_INIT(FUNCNAME) \
FUNCNAME##_reset(); \ 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 /* cpp/ansi c */
#endif // FAKE_FUNCTIONS #endif // FAKE_FUNCTIONS

View File

@@ -6,7 +6,7 @@
*/ */
#include "embedded.h" #include "embedded.h"
#include "../cmock.h" #include "../fff.h"
#include <assert.h> #include <assert.h>
#include <stdio.h> #include <stdio.h>

View File

@@ -6,7 +6,7 @@
// Description : Hello World in C++, Ansi-style // Description : Hello World in C++, Ansi-style
//============================================================================ //============================================================================
#include "../cmock.h" #include "../fff.h"
extern "C"{ extern "C"{
#include "embedded.h" #include "embedded.h"