Skip to content

Commit

Permalink
Merge eac0953 into 35b2687
Browse files Browse the repository at this point in the history
  • Loading branch information
oliviera9 authored Dec 5, 2018
2 parents 35b2687 + eac0953 commit dadd606
Show file tree
Hide file tree
Showing 8 changed files with 841 additions and 86 deletions.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -432,6 +432,9 @@ could call the real `fprintf()` like this:
return vfprintf(stream, format, ap);
}
Just like [return value delegates](#custom-return-value-delegate-sequences), you can also specify sequences for variadic functions using `SET_CUSTOM_FAKE_SEQ`.
See the test files for examples.
## How do I specify calling conventions for my fake functions?
fff has a limited capability for enabling specification of Microsoft's Visual C/C++ calling conventions, but this support must be enabled when generating fff's header file `fff.h`.
Expand Down
29 changes: 29 additions & 0 deletions fakegen.rb
Original file line number Diff line number Diff line change
Expand Up @@ -408,6 +408,35 @@ def output_function_body(arg_count, has_varargs, is_value_function)
putd_backslash "REGISTER_CALL(FUNCNAME);"

if has_varargs
return_type = is_value_function ? "return " : ""
putd_backslash "if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */"
indent {
putd_backslash "if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){"
indent {
putd_backslash "va_list ap;"
putd_backslash "va_start(ap, arg#{arg_count-1});"
putd_backslash "RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](#{arg_list(arg_count)}, ap);" unless not is_value_function
putd_backslash "SAVE_RET_HISTORY(FUNCNAME, ret);" unless not is_value_function
putd_backslash "va_end(ap);" unless not is_value_function
putd_backslash "return ret;" unless not is_value_function
putd_backslash "#{return_type}FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](#{arg_list(arg_count)}, ap);" unless is_value_function
putd_backslash "va_end(ap);" unless is_value_function
}
putd_backslash "}"
putd_backslash "else{"
indent {
putd_backslash "va_list ap;"
putd_backslash "va_start(ap, arg#{arg_count-1});"
putd_backslash "RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](#{arg_list(arg_count)}, ap);" unless not is_value_function
putd_backslash "SAVE_RET_HISTORY(FUNCNAME, ret);" unless not is_value_function
putd_backslash "va_end(ap);" unless not is_value_function
putd_backslash "return ret;" unless not is_value_function
putd_backslash "#{return_type}FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](#{arg_list(arg_count)}, ap);"
putd_backslash "va_end(ap);" unless is_value_function
}
putd_backslash "}"
}
putd_backslash "}"
putd_backslash "if(FUNCNAME##_fake.custom_fake){"
indent {
putd_backslash "RETURN_TYPE ret;" if is_value_function
Expand Down
787 changes: 707 additions & 80 deletions fff.h

Large diffs are not rendered by default.

8 changes: 6 additions & 2 deletions test/fff_test_c.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ FAKE_VOID_FUNC(voidfunc1outparam, char *);
FAKE_VALUE_FUNC(long, longfunc0);
FAKE_VALUE_FUNC(enum MYBOOL, enumfunc0);
FAKE_VALUE_FUNC(struct MyStruct, structfunc0);
FAKE_VOID_FUNC_VARARG(voidfunc3var, char *, int, ...);
FAKE_VALUE_FUNC_VARARG(int, valuefunc3var, char *, int, ...);
FAKE_VOID_FUNC_VARARG(voidfunc3var, const char *, int, ...);
FAKE_VALUE_FUNC_VARARG(int, valuefunc3var, const char *, int, ...);
FAKE_VALUE_FUNC(int, strlcpy3, char* const, const char* const, const size_t);
FAKE_VOID_FUNC(voidfunc20, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int);
FAKE_VALUE_FUNC(int, valuefunc20, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int);
Expand Down Expand Up @@ -116,6 +116,10 @@ int main()

RUN_TEST(FFFTestSuite, use_void_vararg_fake_with_different_number_of_arguments);
RUN_TEST(FFFTestSuite, use_value_vararg_fake_with_different_number_of_arguments);
RUN_TEST(FFFTestSuite, vararg_custom_fake_sequence_not_exhausted);
RUN_TEST(FFFTestSuite, vararg_custom_fake_seq_return_values_saved_in_history);
RUN_TEST(FFFTestSuite, vararg_custom_fake_sequence_exhausted);
RUN_TEST(FFFTestSuite, vararg_custom_fake_sequence_reset);

RUN_TEST(FFFTestSuite, can_capture_upto_20_arguments_correctly);
RUN_TEST(FFFTestSuite, value_func_can_capture_upto_20_arguments_correctly);
Expand Down
6 changes: 6 additions & 0 deletions test/fff_test_cpp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,17 @@ FAKE_VOID_FUNC(voidfunc1, int);
FAKE_VOID_FUNC(voidfunc2, char, char);
FAKE_VOID_FUNC(voidfunc1outparam, char *);
FAKE_VALUE_FUNC(long, longfunc0);
FAKE_VOID_FUNC_VARARG(voidfunc3var, const char *, int, ...);
FAKE_VALUE_FUNC_VARARG(int, valuefunc3var, const char *, int, ...);
FAKE_VOID_FUNC(voidfunc20, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int);
FAKE_VALUE_FUNC(int, valuefunc20, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int);
#else
FAKE_VOID_FUNC(__cdecl, voidfunc1, int);
FAKE_VOID_FUNC(__cdecl, voidfunc2, char, char);
FAKE_VOID_FUNC(__cdecl, voidfunc1outparam, char *);
FAKE_VALUE_FUNC(long, __cdecl, longfunc0);
FAKE_VOID_FUNC_VARARG(__cdecl, voidfunc3var, const char *, int, ...);
FAKE_VALUE_FUNC_VARARG(int, __cdecl, valuefunc3var, const char *, int, ...);
FAKE_VOID_FUNC(__cdecl, voidfunc20, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int);
FAKE_VALUE_FUNC(int, __cdecl, valuefunc20, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int);
#endif
Expand All @@ -42,6 +46,8 @@ class FFFTestSuite: public testing::Test
RESET_FAKE(voidfunc2);
RESET_FAKE(longfunc0);
RESET_FAKE(voidfunc1outparam);
RESET_FAKE(voidfunc3var);
RESET_FAKE(valuefunc3var);
FFF_RESET_HISTORY();
}
};
Expand Down
4 changes: 4 additions & 0 deletions test/fff_test_global_c.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,10 @@ int main()

RUN_TEST(FFFTestSuite, use_void_vararg_fake_with_different_number_of_arguments);
RUN_TEST(FFFTestSuite, use_value_vararg_fake_with_different_number_of_arguments);
RUN_TEST(FFFTestSuite, vararg_custom_fake_sequence_not_exhausted);
RUN_TEST(FFFTestSuite, vararg_custom_fake_seq_return_values_saved_in_history);
RUN_TEST(FFFTestSuite, vararg_custom_fake_sequence_exhausted);
RUN_TEST(FFFTestSuite, vararg_custom_fake_sequence_reset);

RUN_TEST(FFFTestSuite, can_capture_upto_20_arguments_correctly);
RUN_TEST(FFFTestSuite, value_func_can_capture_upto_20_arguments_correctly);
Expand Down
2 changes: 2 additions & 0 deletions test/fff_test_global_cpp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ class FFFTestSuite: public testing::Test
RESET_FAKE(voidfunc2);
RESET_FAKE(longfunc0);
RESET_FAKE(voidfunc1outparam);
RESET_FAKE(voidfunc3var);
RESET_FAKE(valuefunc3var);
FFF_RESET_HISTORY();
}
};
Expand Down
88 changes: 84 additions & 4 deletions test/test_cases.include
Original file line number Diff line number Diff line change
Expand Up @@ -354,15 +354,96 @@ TEST_F(FFFTestSuite, when_value_custom_fake_called_THEN_it_returns_custom_return
ASSERT_EQ(MEANING_OF_LIFE, retval);
}

#ifndef __cplusplus
int valuefunc3var_custom_fake1(const char *str, int a, va_list vl)
{
int arg;
while ((arg = va_arg(vl, int)) != 0)
a += arg;
return a;
}

int valuefunc3var_custom_fake2(const char *str, int a, va_list vl)
{
int arg;
while ((arg = va_arg(vl, int)) != 0)
a -= arg;
return a;
}

int valuefunc3var_custom_fake3(const char *str, int a, va_list vl)
{
int arg;
while ((arg = va_arg(vl, int)) != 0)
a *= arg;
return a;
}

TEST_F(FFFTestSuite, vararg_custom_fake_sequence_not_exhausted)
{
int (*custom_fakes[])(const char *, int, va_list) = {valuefunc3var_custom_fake1,
valuefunc3var_custom_fake2,
valuefunc3var_custom_fake3};
SET_CUSTOM_FAKE_SEQ(valuefunc3var, custom_fakes, 3);
int a = 1;
ASSERT_EQ(valuefunc3var("a", a, 2, 3, 4, 0), 10);
ASSERT_EQ(valuefunc3var("aa", a, 2, 3, 4, 2, 0), -10);
ASSERT_EQ(valuefunc3var("aaa", a, 2, 3, 0), 6);
}

TEST_F(FFFTestSuite, vararg_custom_fake_seq_return_values_saved_in_history)
{
int (*custom_fakes[])(const char *, int, va_list) = {valuefunc3var_custom_fake1,
valuefunc3var_custom_fake2,
valuefunc3var_custom_fake3};
SET_CUSTOM_FAKE_SEQ(valuefunc3var, custom_fakes, 3);
int a = 1;
valuefunc3var("a", a, 2, 3, 4, 0);
valuefunc3var("aa", a, 2, 3, 4, 2, 0);
valuefunc3var("aaa", a, 2, 3, 0);
ASSERT_EQ(10, valuefunc3var_fake.return_val_history[0]);
ASSERT_EQ(-10, valuefunc3var_fake.return_val_history[1]);
ASSERT_EQ(6, valuefunc3var_fake.return_val_history[2]);
}

TEST_F(FFFTestSuite, vararg_custom_fake_sequence_exhausted)
{
int (*custom_fakes[])(const char *, int, va_list) = {valuefunc3var_custom_fake1,
valuefunc3var_custom_fake2,
valuefunc3var_custom_fake3};
SET_CUSTOM_FAKE_SEQ(valuefunc3var, custom_fakes, 3);
int a = 1;
ASSERT_EQ(valuefunc3var("a", a, 2, 3, 4, 0), 10);
ASSERT_EQ(valuefunc3var("aa", a, 2, 3, 4, 2, 0), -10);
ASSERT_EQ(valuefunc3var("aaa", a, 2, 3, 0), 6);
ASSERT_EQ(valuefunc3var("aaa", a, 4, 5, 1, 0), 20);
ASSERT_EQ(valuefunc3var("aaa", a, 4, 0), 4);
}

TEST_F(FFFTestSuite, vararg_custom_fake_sequence_reset)
{
int (*custom_fakes[])(const char *, int, va_list) = {valuefunc3var_custom_fake1,
valuefunc3var_custom_fake2,
valuefunc3var_custom_fake3};
SET_CUSTOM_FAKE_SEQ(valuefunc3var, custom_fakes, 3);
int a = 1;
ASSERT_EQ(valuefunc3var("a", a, 2, 3, 4, 0), 10);
ASSERT_EQ(valuefunc3var("aa", a, 2, 3, 4, 2, 0), -10);
RESET_FAKE(valuefunc3var);
ASSERT_EQ(0, valuefunc3var("b", 7, 4, 5));
valuefunc3var_fake.return_val = 1;
ASSERT_EQ(1, valuefunc3var("c", 5, 4, 4));
valuefunc3var_fake.return_val = 2;
ASSERT_EQ(2, valuefunc3var("d", 6, 3, 5));
}

TEST_F(FFFTestSuite, use_void_vararg_fake_with_different_number_of_arguments)
{
voidfunc3var("0 parameters", 0);
voidfunc3var("1 parameter", 1, 10);
voidfunc3var("2 parameters", 2, 10, 20);
voidfunc3var("3 parameters", 3, 10, 20, 30);

ASSERT_EQ(voidfunc3var_fake.call_count, 4);
ASSERT_EQ(voidfunc3var_fake.call_count, 4u);
char msg[] = "3 parameters";
ASSERT_EQ(strcmp(voidfunc3var_fake.arg0_val, msg), 0);
ASSERT_EQ(3, voidfunc3var_fake.arg1_val);
Expand All @@ -375,12 +456,11 @@ TEST_F(FFFTestSuite, use_value_vararg_fake_with_different_number_of_arguments)
valuefunc3var("2 parameters", 2, 10, 20);
valuefunc3var("3 parameters", 3, 10, 20, 30);

ASSERT_EQ(valuefunc3var_fake.call_count, 4);
ASSERT_EQ(valuefunc3var_fake.call_count, 4u);
char msg[] = "3 parameters";
ASSERT_EQ(strcmp(valuefunc3var_fake.arg0_val, msg), 0);
ASSERT_EQ(3, valuefunc3var_fake.arg1_val);
}
#endif /* __cplusplus */

TEST_F(FFFTestSuite, can_capture_upto_20_arguments_correctly)
{
Expand Down

0 comments on commit dadd606

Please sign in to comment.