From 932785fd713c88dfcd307ce79bf3d3c3b14295aa Mon Sep 17 00:00:00 2001 From: Dennis Lambe Jr Date: Wed, 19 Dec 2012 19:06:10 -0500 Subject: [PATCH 1/7] Added the return_thru_ptr and ignore_arg plugins --- lib/cmock_generator_plugin_ignore_arg.rb | 47 ++++++++ lib/cmock_generator_plugin_return_thru_ptr.rb | 77 +++++++++++++ lib/cmock_generator_utils.rb | 109 +++++++++++------- src/cmock.c | 18 +++ src/cmock.h | 1 + 5 files changed, 210 insertions(+), 42 deletions(-) create mode 100644 lib/cmock_generator_plugin_ignore_arg.rb create mode 100644 lib/cmock_generator_plugin_return_thru_ptr.rb diff --git a/lib/cmock_generator_plugin_ignore_arg.rb b/lib/cmock_generator_plugin_ignore_arg.rb new file mode 100644 index 0000000..e71b707 --- /dev/null +++ b/lib/cmock_generator_plugin_ignore_arg.rb @@ -0,0 +1,47 @@ +class CMockGeneratorPluginIgnoreArg + attr_reader :priority + attr_accessor :config, :utils, :unity_helper, :ordered + + def initialize(config, utils) + @config = config + @ordered = @config.enforce_strict_ordering + @utils = utils + @unity_helper = @utils.helpers[:unity_helper] + @priority = 10 + end + + def instance_typedefs(function) + lines = "" + function[:args].each do |arg| + lines << " int IgnoreArg_#{arg[:name]};\n" + end + lines + end + + def mock_function_declarations(function) + lines = "" + function[:args].each do |arg| + lines << "#define #{function[:name]}_IgnoreArg_#{arg[:name]}()" + lines << " #{function[:name]}_CMockIgnoreArg_#{arg[:name]}(__LINE__)\n" + lines << "void #{function[:name]}_CMockIgnoreArg_#{arg[:name]}(UNITY_LINE_TYPE cmock_line);\n" + end + lines + end + + def mock_interfaces(function) + lines = [] + func_name = function[:name] + function[:args].each do |arg| + arg_name = arg[:name] + arg_type = arg[:type] + lines << "void #{function[:name]}_CMockIgnoreArg_#{arg[:name]}(UNITY_LINE_TYPE cmock_line)\n" + lines << "{\n" + lines << " CMOCK_#{func_name}_CALL_INSTANCE* cmock_call_instance = " + + "cmock_call_instance = (CMOCK_#{func_name}_CALL_INSTANCE*)CMock_Guts_GetAddressFor(CMock_Guts_MemEndOfChain(Mock.#{func_name}_CallInstance));\n" + lines << " UNITY_TEST_ASSERT_NOT_NULL(cmock_call_instance, cmock_line, \"#{arg_name} IgnoreArg called before Expect on '#{func_name}'.\");\n" + lines << " cmock_call_instance->IgnoreArg_#{arg_name} = 1;\n" + lines << "}\n\n" + end + lines + end +end diff --git a/lib/cmock_generator_plugin_return_thru_ptr.rb b/lib/cmock_generator_plugin_return_thru_ptr.rb new file mode 100644 index 0000000..8ba4fdb --- /dev/null +++ b/lib/cmock_generator_plugin_return_thru_ptr.rb @@ -0,0 +1,77 @@ +class CMockGeneratorPluginReturnThruPtr + attr_reader :priority + attr_accessor :config, :utils, :unity_helper, :ordered + + def initialize(config, utils) + @config = config + @ordered = @config.enforce_strict_ordering + @utils = utils + @unity_helper = @utils.helpers[:unity_helper] + @priority = 9 + end + + def instance_typedefs(function) + lines = "" + function[:args].each do |arg| + if (@utils.ptr_or_str?(arg[:type]) and not arg[:const?]) + lines << " int ReturnThruPtr_#{arg[:name]}_Used;\n" + lines << " #{arg[:type]} ReturnThruPtr_#{arg[:name]}_Val;\n" + lines << " int ReturnThruPtr_#{arg[:name]}_Size;\n" + end + end + lines + end + + def mock_function_declarations(function) + lines = "" + function[:args].each do |arg| + if (@utils.ptr_or_str?(arg[:type]) and not arg[:const?]) + lines << "#define #{function[:name]}_ReturnThruPtr_#{arg[:name]}(#{arg[:name]})" + lines << " #{function[:name]}_CMockReturnMemThruPtr_#{arg[:name]}(__LINE__, #{arg[:name]}, sizeof(*#{arg[:name]}))\n" + lines << "#define #{function[:name]}_ReturnArrayThruPtr_#{arg[:name]}(#{arg[:name]}, cmock_len)" + lines << " #{function[:name]}_CMockReturnMemThruPtr_#{arg[:name]}(__LINE__, #{arg[:name]}, cmock_len * sizeof(*#{arg[:name]}))\n" + lines << "#define #{function[:name]}_ReturnMemThruPtr_#{arg[:name]}(#{arg[:name]}, cmock_size)" + lines << " #{function[:name]}_CMockReturnMemThruPtr_#{arg[:name]}(__LINE__, #{arg[:name]}, cmock_size)\n" + lines << "void #{function[:name]}_CMockReturnMemThruPtr_#{arg[:name]}(UNITY_LINE_TYPE cmock_line, #{arg[:type]} #{arg[:name]}, int cmock_size);\n" + end + end + lines + end + + def mock_interfaces(function) + lines = [] + func_name = function[:name] + function[:args].each do |arg| + arg_name = arg[:name] + arg_type = arg[:type] + if (@utils.ptr_or_str?(arg[:type]) and not arg[:const?]) + lines << "void #{func_name}_CMockReturnMemThruPtr_#{arg_name}(UNITY_LINE_TYPE cmock_line, #{arg[:type]} #{arg_name}, int cmock_size)\n" + lines << "{\n" + lines << " CMOCK_#{func_name}_CALL_INSTANCE* cmock_call_instance = " + + "cmock_call_instance = (CMOCK_#{func_name}_CALL_INSTANCE*)CMock_Guts_GetAddressFor(CMock_Guts_MemEndOfChain(Mock.#{func_name}_CallInstance));\n" + lines << " UNITY_TEST_ASSERT_NOT_NULL(cmock_call_instance, cmock_line, \"#{arg_name} ReturnThruPtr called before Expect on '#{func_name}'.\");\n" + lines << " cmock_call_instance->ReturnThruPtr_#{arg_name}_Used = 1;\n" + lines << " cmock_call_instance->ReturnThruPtr_#{arg_name}_Val = #{arg_name};\n" + lines << " cmock_call_instance->ReturnThruPtr_#{arg_name}_Size = cmock_size;\n" + lines << "}\n\n" + end + end + lines + end + + def mock_implementation(function) + lines = [] + function[:args].each do |arg| + arg_name = arg[:name] + arg_type = arg[:type] + if (@utils.ptr_or_str?(arg[:type]) and not arg[:const?]) + lines << " if (cmock_call_instance->ReturnThruPtr_#{arg_name}_Used)\n" + lines << " {\n" + lines << " memcpy(#{arg_name}, cmock_call_instance->ReturnThruPtr_#{arg_name}_Val,\n" + lines << " cmock_call_instance->ReturnThruPtr_#{arg_name}_Size);\n" + lines << " }\n" + end + end + lines + end +end diff --git a/lib/cmock_generator_utils.rb b/lib/cmock_generator_utils.rb index 043ff2d..a4d2f69 100644 --- a/lib/cmock_generator_utils.rb +++ b/lib/cmock_generator_utils.rb @@ -14,6 +14,8 @@ class CMockGeneratorUtils @ordered = @config.enforce_strict_ordering @arrays = @config.plugins.include? :array @cexception = @config.plugins.include? :cexception + @return_thru_ptr = @config.plugins.include? :return_thru_ptr + @ignore_arg = @config.plugins.include? :ignore_arg @treat_as = @config.treat_as @helpers = helpers @@ -28,7 +30,7 @@ class CMockGeneratorUtils end end - def code_add_base_expectation(func_name, global_ordering_supported=true) + def code_add_base_expectation(func_name, global_ordering_supported=true) lines = " CMOCK_MEM_INDEX_TYPE cmock_guts_index = CMock_Guts_MemNew(sizeof(CMOCK_#{func_name}_CALL_INSTANCE));\n" lines << " CMOCK_#{func_name}_CALL_INSTANCE* cmock_call_instance = (CMOCK_#{func_name}_CALL_INSTANCE*)CMock_Guts_GetAddressFor(cmock_guts_index);\n" lines << " UNITY_TEST_ASSERT_NOT_NULL(cmock_call_instance, cmock_line, \"CMock has run out of memory. Please allocate more.\");\n" @@ -42,6 +44,8 @@ class CMockGeneratorUtils def code_add_an_arg_expectation(arg, depth=1) lines = code_assign_argument_quickly("cmock_call_instance->Expected_#{arg[:name]}", arg) lines << " cmock_call_instance->Expected_#{arg[:name]}_Depth = #{arg[:name]}_Depth;\n" if (@arrays and (depth.class == String)) + lines << " cmock_call_instance->IgnoreArg_#{arg[:name]} = 0;\n" if (@ignore_arg) + lines << " cmock_call_instance->ReturnThruPtr_#{arg[:name]}_Used = 0;\n" if (@return_thru_ptr and ptr_or_str?(arg[:type]) and not arg[:const?]) lines end @@ -84,94 +88,115 @@ class CMockGeneratorUtils end end + def ptr_or_str?(arg_type) + return (arg_type.include? '*' or + @treat_as.fetch(arg_type, "").include? '*') + end + #private ###################### def lookup_expect_type(function, arg) c_type = arg[:type] arg_name = arg[:name] - expected = "cmock_call_instance->Expected_#{arg_name}" + expected = "cmock_call_instance->Expected_#{arg_name}" + ignore = "cmock_call_instance->IgnoreArg_#{arg_name}" unity_func = if ((arg[:ptr?]) and ((c_type =~ /\*\*/) or (@ptr_handling == :compare_ptr))) ['UNITY_TEST_ASSERT_EQUAL_PTR', ''] else (@helpers.nil? or @helpers[:unity_helper].nil?) ? ["UNITY_TEST_ASSERT_EQUAL",''] : @helpers[:unity_helper].get_helper(c_type) end unity_msg = "Function '#{function[:name]}' called with unexpected value for argument '#{arg_name}'." - return c_type, arg_name, expected, unity_func[0], unity_func[1], unity_msg + return c_type, arg_name, expected, ignore, unity_func[0], unity_func[1], unity_msg end def code_verify_an_arg_expectation_with_no_arrays(function, arg) - c_type, arg_name, expected, unity_func, pre, unity_msg = lookup_expect_type(function, arg) + c_type, arg_name, expected, ignore, unity_func, pre, unity_msg = lookup_expect_type(function, arg) + lines = "" + lines << " if (!#{ignore})\n" if @ignore_arg + lines << " {\n" case(unity_func) when "UNITY_TEST_ASSERT_EQUAL_MEMORY" c_type_local = c_type.gsub(/\*$/,'') - return " UNITY_TEST_ASSERT_EQUAL_MEMORY((void*)(#{pre}#{expected}), (void*)(#{pre}#{arg_name}), sizeof(#{c_type_local}), cmock_line, \"#{unity_msg}\");\n" + lines << " UNITY_TEST_ASSERT_EQUAL_MEMORY((void*)(#{pre}#{expected}), (void*)(#{pre}#{arg_name}), sizeof(#{c_type_local}), cmock_line, \"#{unity_msg}\");\n" when "UNITY_TEST_ASSERT_EQUAL_MEMORY" - [ " if (#{pre}#{expected} == NULL)", - " { UNITY_TEST_ASSERT_NULL(#{pre}#{arg_name}, cmock_line, \"Expected NULL. #{unity_msg}\"); }", - " else", - " { UNITY_TEST_ASSERT_EQUAL_MEMORY((void*)(#{pre}#{expected}), (void*)(#{pre}#{arg_name}), sizeof(#{c_type.sub('*','')}), cmock_line, \"#{unity_msg}\"); }\n"].join("\n") + lines << " if (#{pre}#{expected} == NULL)\n" + lines << " { UNITY_TEST_ASSERT_NULL(#{pre}#{arg_name}, cmock_line, \"Expected NULL. #{unity_msg}\"); }\n" + lines << " else\n" + lines << " { UNITY_TEST_ASSERT_EQUAL_MEMORY((void*)(#{pre}#{expected}), (void*)(#{pre}#{arg_name}), sizeof(#{c_type.sub('*','')}), cmock_line, \"#{unity_msg}\"); }\n" when /_ARRAY/ - [ " if (#{pre}#{expected} == NULL)", - " { UNITY_TEST_ASSERT_NULL(#{pre}#{arg_name}, cmock_line, \"Expected NULL. #{unity_msg}\"); }", - " else", - " { #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, 1, cmock_line, \"#{unity_msg}\"); }\n"].join("\n") + lines << " if (#{pre}#{expected} == NULL)\n" + lines << " { UNITY_TEST_ASSERT_NULL(#{pre}#{arg_name}, cmock_line, \"Expected NULL. #{unity_msg}\"); }\n" + lines << " else\n" + lines << " { #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, 1, cmock_line, \"#{unity_msg}\"); }\n" else - return " #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, cmock_line, \"#{unity_msg}\");\n" - end + lines << " #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, cmock_line, \"#{unity_msg}\");\n" + end + lines << " }\n" + lines end def code_verify_an_arg_expectation_with_normal_arrays(function, arg) - c_type, arg_name, expected, unity_func, pre, unity_msg = lookup_expect_type(function, arg) + c_type, arg_name, expected, ignore, unity_func, pre, unity_msg = lookup_expect_type(function, arg) depth_name = (arg[:ptr?]) ? "cmock_call_instance->Expected_#{arg_name}_Depth" : 1 + lines = "" + lines << " if (!#{ignore})\n" if @ignore_arg + lines << " {\n" case(unity_func) when "UNITY_TEST_ASSERT_EQUAL_MEMORY" c_type_local = c_type.gsub(/\*$/,'') - return " UNITY_TEST_ASSERT_EQUAL_MEMORY((void*)(#{pre}#{expected}), (void*)(#{pre}#{arg_name}), sizeof(#{c_type_local}), cmock_line, \"#{unity_msg}\");\n" + lines << " UNITY_TEST_ASSERT_EQUAL_MEMORY((void*)(#{pre}#{expected}), (void*)(#{pre}#{arg_name}), sizeof(#{c_type_local}), cmock_line, \"#{unity_msg}\");\n" when "UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY" - [ " if (#{pre}#{expected} == NULL)", - " { UNITY_TEST_ASSERT_NULL(#{pre}#{arg_name}, cmock_line, \"Expected NULL. #{unity_msg}\"); }", - " else", - " { UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY((void*)(#{pre}#{expected}), (void*)(#{pre}#{arg_name}), sizeof(#{c_type.sub('*','')}), #{depth_name}, cmock_line, \"#{unity_msg}\"); }\n"].compact.join("\n") + lines << " if (#{pre}#{expected} == NULL)\n" + lines << " { UNITY_TEST_ASSERT_NULL(#{pre}#{arg_name}, cmock_line, \"Expected NULL. #{unity_msg}\"); }\n" + lines << " else\n" + lines << " { UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY((void*)(#{pre}#{expected}), (void*)(#{pre}#{arg_name}), sizeof(#{c_type.sub('*','')}), #{depth_name}, cmock_line, \"#{unity_msg}\"); }\n" when /_ARRAY/ if (pre == '&') - " #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, #{depth_name}, cmock_line, \"#{unity_msg}\");\n" + lines << " #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, #{depth_name}, cmock_line, \"#{unity_msg}\");\n" else - [ " if (#{pre}#{expected} == NULL)", - " { UNITY_TEST_ASSERT_NULL(#{pre}#{arg_name}, cmock_line, \"Expected NULL. #{unity_msg}\"); }", - " else", - " { #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, #{depth_name}, cmock_line, \"#{unity_msg}\"); }\n"].compact.join("\n") + lines << " if (#{pre}#{expected} == NULL)\n" + lines << " { UNITY_TEST_ASSERT_NULL(#{pre}#{arg_name}, cmock_line, \"Expected NULL. #{unity_msg}\"); }\n" + lines << " else\n" + lines << " { #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, #{depth_name}, cmock_line, \"#{unity_msg}\"); }\n" end else - return " #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, cmock_line, \"#{unity_msg}\");\n" + lines << " #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, cmock_line, \"#{unity_msg}\");\n" end + lines << " }\n" + lines end def code_verify_an_arg_expectation_with_smart_arrays(function, arg) - c_type, arg_name, expected, unity_func, pre, unity_msg = lookup_expect_type(function, arg) + c_type, arg_name, expected, ignore, unity_func, pre, unity_msg = lookup_expect_type(function, arg) depth_name = (arg[:ptr?]) ? "cmock_call_instance->Expected_#{arg_name}_Depth" : 1 + lines = "" + lines << " if (!#{ignore})\n" if @ignore_arg + lines << " {\n" case(unity_func) when "UNITY_TEST_ASSERT_EQUAL_MEMORY" c_type_local = c_type.gsub(/\*$/,'') - return " UNITY_TEST_ASSERT_EQUAL_MEMORY((void*)(#{pre}#{expected}), (void*)(#{pre}#{arg_name}), sizeof(#{c_type_local}), cmock_line, \"#{unity_msg}\");\n" + lines << " UNITY_TEST_ASSERT_EQUAL_MEMORY((void*)(#{pre}#{expected}), (void*)(#{pre}#{arg_name}), sizeof(#{c_type_local}), cmock_line, \"#{unity_msg}\");\n" when "UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY" - [ " if (#{pre}#{expected} == NULL)", - " { UNITY_TEST_ASSERT_NULL(#{arg_name}, cmock_line, \"Expected NULL. #{unity_msg}\"); }", - ((depth_name != 1) ? " else if (#{depth_name} == 0)\n { UNITY_TEST_ASSERT_EQUAL_PTR(#{pre}#{expected}, #{pre}#{arg_name}, cmock_line, \"#{unity_msg}\"); }" : nil), - " else", - " { UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY((void*)(#{pre}#{expected}), (void*)(#{pre}#{arg_name}), sizeof(#{c_type.sub('*','')}), #{depth_name}, cmock_line, \"#{unity_msg}\"); }\n"].compact.join("\n") + lines << " if (#{pre}#{expected} == NULL)\n" + lines << " { UNITY_TEST_ASSERT_NULL(#{arg_name}, cmock_line, \"Expected NULL. #{unity_msg}\"); }\n" + lines << ((depth_name != 1) ? " else if (#{depth_name} == 0)\n { UNITY_TEST_ASSERT_EQUAL_PTR(#{pre}#{expected}, #{pre}#{arg_name}, cmock_line, \"#{unity_msg}\"); }\n" : "") + lines << " else\n" + lines << " { UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY((void*)(#{pre}#{expected}), (void*)(#{pre}#{arg_name}), sizeof(#{c_type.sub('*','')}), #{depth_name}, cmock_line, \"#{unity_msg}\"); }\n" when /_ARRAY/ if (pre == '&') - " #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, #{depth_name}, cmock_line, \"#{unity_msg}\");\n" + lines << " #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, #{depth_name}, cmock_line, \"#{unity_msg}\");\n" else - [ " if (#{pre}#{expected} == NULL)", - " { UNITY_TEST_ASSERT_NULL(#{pre}#{arg_name}, cmock_line, \"Expected NULL. #{unity_msg}\"); }", - ((depth_name != 1) ? " else if (#{depth_name} == 0)\n { UNITY_TEST_ASSERT_EQUAL_PTR(#{pre}#{expected}, #{pre}#{arg_name}, cmock_line, \"#{unity_msg}\"); }" : nil), - " else", - " { #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, #{depth_name}, cmock_line, \"#{unity_msg}\"); }\n"].compact.join("\n") + lines << " if (#{pre}#{expected} == NULL)\n" + lines << " { UNITY_TEST_ASSERT_NULL(#{pre}#{arg_name}, cmock_line, \"Expected NULL. #{unity_msg}\"); }\n" + lines << ((depth_name != 1) ? " else if (#{depth_name} == 0)\n { UNITY_TEST_ASSERT_EQUAL_PTR(#{pre}#{expected}, #{pre}#{arg_name}, cmock_line, \"#{unity_msg}\"); }\n" : "") + lines << " else\n" + lines << " { #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, #{depth_name}, cmock_line, \"#{unity_msg}\"); }\n" end else - return " #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, cmock_line, \"#{unity_msg}\");\n" + lines << " #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, cmock_line, \"#{unity_msg}\");\n" end + lines << " }\n" + lines end -end \ No newline at end of file +end diff --git a/src/cmock.c b/src/cmock.c index e26243a..40a4ef6 100644 --- a/src/cmock.c +++ b/src/cmock.c @@ -146,6 +146,24 @@ CMOCK_MEM_INDEX_TYPE CMock_Guts_MemNext(CMOCK_MEM_INDEX_TYPE previous_item_index return CMOCK_GUTS_NONE; } +//------------------------------------------------------- +// CMock_Guts_MemEndOfChain +//------------------------------------------------------- +CMOCK_MEM_INDEX_TYPE CMock_Guts_MemEndOfChain(CMOCK_MEM_INDEX_TYPE root_index) +{ + CMOCK_MEM_INDEX_TYPE index = root_index; + CMOCK_MEM_INDEX_TYPE next_index; + + for (next_index = root_index; + next_index != CMOCK_GUTS_NONE; + next_index = CMock_Guts_MemNext(index)) + { + index = next_index; + } + + return index; +} + //------------------------------------------------------- // CMock_GetAddressFor //------------------------------------------------------- diff --git a/src/cmock.h b/src/cmock.h index 084a828..4dcfc1f 100644 --- a/src/cmock.h +++ b/src/cmock.h @@ -20,6 +20,7 @@ CMOCK_MEM_INDEX_TYPE CMock_Guts_MemNew(CMOCK_MEM_INDEX_TYPE size); CMOCK_MEM_INDEX_TYPE CMock_Guts_MemChain(CMOCK_MEM_INDEX_TYPE root_index, CMOCK_MEM_INDEX_TYPE obj_index); CMOCK_MEM_INDEX_TYPE CMock_Guts_MemNext(CMOCK_MEM_INDEX_TYPE previous_item_index); +CMOCK_MEM_INDEX_TYPE CMock_Guts_MemEndOfChain(CMOCK_MEM_INDEX_TYPE root_index); void* CMock_Guts_GetAddressFor(CMOCK_MEM_INDEX_TYPE index); From 7239d815af33ee30348ec61c78b2d1dc5abe6e6f Mon Sep 17 00:00:00 2001 From: Dennis Lambe Jr Date: Wed, 19 Dec 2012 20:19:17 -0500 Subject: [PATCH 2/7] Ensure tests pass after adding return_thru_ptr and ignore_arg plugins --- lib/cmock_generator_utils.rb | 4 +- test/unit/cmock_generator_utils_test.rb | 56 ++++++++++++++----------- 2 files changed, 34 insertions(+), 26 deletions(-) diff --git a/lib/cmock_generator_utils.rb b/lib/cmock_generator_utils.rb index a4d2f69..ce8bf91 100644 --- a/lib/cmock_generator_utils.rb +++ b/lib/cmock_generator_utils.rb @@ -175,7 +175,7 @@ class CMockGeneratorUtils case(unity_func) when "UNITY_TEST_ASSERT_EQUAL_MEMORY" c_type_local = c_type.gsub(/\*$/,'') - lines << " UNITY_TEST_ASSERT_EQUAL_MEMORY((void*)(#{pre}#{expected}), (void*)(#{pre}#{arg_name}), sizeof(#{c_type_local}), cmock_line, \"#{unity_msg}\");\n" + lines << " UNITY_TEST_ASSERT_EQUAL_MEMORY((void*)(#{pre}#{expected}), (void*)(#{pre}#{arg_name}), sizeof(#{c_type_local}), cmock_line, \"#{unity_msg}\");\n" when "UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY" lines << " if (#{pre}#{expected} == NULL)\n" lines << " { UNITY_TEST_ASSERT_NULL(#{arg_name}, cmock_line, \"Expected NULL. #{unity_msg}\"); }\n" @@ -188,7 +188,7 @@ class CMockGeneratorUtils else lines << " if (#{pre}#{expected} == NULL)\n" lines << " { UNITY_TEST_ASSERT_NULL(#{pre}#{arg_name}, cmock_line, \"Expected NULL. #{unity_msg}\"); }\n" - lines << ((depth_name != 1) ? " else if (#{depth_name} == 0)\n { UNITY_TEST_ASSERT_EQUAL_PTR(#{pre}#{expected}, #{pre}#{arg_name}, cmock_line, \"#{unity_msg}\"); }\n" : "") + lines << ((depth_name != 1) ? " else if (#{depth_name} == 0)\n { UNITY_TEST_ASSERT_EQUAL_PTR(#{pre}#{expected}, #{pre}#{arg_name}, cmock_line, \"#{unity_msg}\"); }\n" : "") lines << " else\n" lines << " { #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, #{depth_name}, cmock_line, \"#{unity_msg}\"); }\n" end diff --git a/test/unit/cmock_generator_utils_test.rb b/test/unit/cmock_generator_utils_test.rb index b5f7dcf..5721475 100644 --- a/test/unit/cmock_generator_utils_test.rb +++ b/test/unit/cmock_generator_utils_test.rb @@ -15,6 +15,8 @@ class CMockGeneratorUtilsTest < Test::Unit::TestCase @config.expect.enforce_strict_ordering.returns(false) @config.expect.plugins.returns([]) @config.expect.plugins.returns([]) + @config.expect.plugins.returns([]) + @config.expect.plugins.returns([]) @config.expect.treat_as.returns(['int','short','long','char','char*']) @cmock_generator_utils_simple = CMockGeneratorUtils.new(@config, {:unity_helper => @unity_helper}) @@ -22,6 +24,8 @@ class CMockGeneratorUtilsTest < Test::Unit::TestCase @config.expect.enforce_strict_ordering.returns(true) @config.expect.plugins.returns([:array, :cexception]) @config.expect.plugins.returns([:array, :cexception]) + @config.expect.plugins.returns([:array, :cexception]) + @config.expect.plugins.returns([:array, :cexception]) @config.expect.treat_as.returns(['int','short','long','char','uint32_t','char*']) @cmock_generator_utils_complex = CMockGeneratorUtils.new(@config, {:unity_helper => @unity_helper, :A=>1, :B=>2}) end @@ -44,7 +48,7 @@ class CMockGeneratorUtilsTest < Test::Unit::TestCase end should "add code for a base expectation with no plugins" do - expected = + expected = " CMOCK_MEM_INDEX_TYPE cmock_guts_index = CMock_Guts_MemNew(sizeof(CMOCK_Apple_CALL_INSTANCE));\n" + " CMOCK_Apple_CALL_INSTANCE* cmock_call_instance = (CMOCK_Apple_CALL_INSTANCE*)CMock_Guts_GetAddressFor(cmock_guts_index);\n" + " UNITY_TEST_ASSERT_NOT_NULL(cmock_call_instance, cmock_line, \"CMock has run out of memory. Please allocate more.\");\n" + @@ -179,7 +183,7 @@ class CMockGeneratorUtilsTest < Test::Unit::TestCase should 'handle a simple assert when requested' do function = { :name => 'Pear' } arg = test_arg[:int] - expected = " UNITY_TEST_ASSERT_EQUAL_INT(cmock_call_instance->Expected_MyInt, MyInt, cmock_line, \"Function 'Pear' called with unexpected value for argument 'MyInt'.\");\n" + expected = " {\n UNITY_TEST_ASSERT_EQUAL_INT(cmock_call_instance->Expected_MyInt, MyInt, cmock_line, \"Function 'Pear' called with unexpected value for argument 'MyInt'.\");\n }\n" @unity_helper.expect.get_helper('int').returns(['UNITY_TEST_ASSERT_EQUAL_INT','']) assert_equal(expected, @cmock_generator_utils_simple.code_verify_an_arg_expectation(function, arg)) end @@ -187,14 +191,14 @@ class CMockGeneratorUtilsTest < Test::Unit::TestCase should 'handle a pointer comparison when configured to do so' do function = { :name => 'Pear' } arg = test_arg[:int_ptr] - expected = " UNITY_TEST_ASSERT_EQUAL_PTR(cmock_call_instance->Expected_MyIntPtr, MyIntPtr, cmock_line, \"Function 'Pear' called with unexpected value for argument 'MyIntPtr'.\");\n" + expected = " {\n UNITY_TEST_ASSERT_EQUAL_PTR(cmock_call_instance->Expected_MyIntPtr, MyIntPtr, cmock_line, \"Function 'Pear' called with unexpected value for argument 'MyIntPtr'.\");\n }\n" assert_equal(expected, @cmock_generator_utils_simple.code_verify_an_arg_expectation(function, arg)) end should 'handle const char as string compares ' do function = { :name => 'Pear' } arg = test_arg[:string] - expected = " UNITY_TEST_ASSERT_EQUAL_STRING(cmock_call_instance->Expected_MyStr, MyStr, cmock_line, \"Function 'Pear' called with unexpected value for argument 'MyStr'.\");\n" + expected = " {\n UNITY_TEST_ASSERT_EQUAL_STRING(cmock_call_instance->Expected_MyStr, MyStr, cmock_line, \"Function 'Pear' called with unexpected value for argument 'MyStr'.\");\n }\n" @unity_helper.expect.get_helper('char*').returns(['UNITY_TEST_ASSERT_EQUAL_STRING','']) assert_equal(expected, @cmock_generator_utils_simple.code_verify_an_arg_expectation(function, arg)) end @@ -202,7 +206,7 @@ class CMockGeneratorUtilsTest < Test::Unit::TestCase should 'handle custom types as memory compares when we have no better way to do it' do function = { :name => 'Pear' } arg = test_arg[:mytype] - expected = " UNITY_TEST_ASSERT_EQUAL_MEMORY((void*)(&cmock_call_instance->Expected_MyMyType), (void*)(&MyMyType), sizeof(MY_TYPE), cmock_line, \"Function 'Pear' called with unexpected value for argument 'MyMyType'.\");\n" + expected = " {\n UNITY_TEST_ASSERT_EQUAL_MEMORY((void*)(&cmock_call_instance->Expected_MyMyType), (void*)(&MyMyType), sizeof(MY_TYPE), cmock_line, \"Function 'Pear' called with unexpected value for argument 'MyMyType'.\");\n }\n" @unity_helper.expect.get_helper('MY_TYPE').returns(['UNITY_TEST_ASSERT_EQUAL_MEMORY','&']) assert_equal(expected, @cmock_generator_utils_simple.code_verify_an_arg_expectation(function, arg)) end @@ -210,7 +214,7 @@ class CMockGeneratorUtilsTest < Test::Unit::TestCase should 'handle custom types with custom handlers when available, even if they do not support the extra message' do function = { :name => 'Pear' } arg = test_arg[:mytype] - expected = " UNITY_TEST_ASSERT_EQUAL_MY_TYPE(cmock_call_instance->Expected_MyMyType, MyMyType, cmock_line, \"Function 'Pear' called with unexpected value for argument 'MyMyType'.\");\n" + expected = " {\n UNITY_TEST_ASSERT_EQUAL_MY_TYPE(cmock_call_instance->Expected_MyMyType, MyMyType, cmock_line, \"Function 'Pear' called with unexpected value for argument 'MyMyType'.\");\n }\n" @unity_helper.expect.get_helper('MY_TYPE').returns(['UNITY_TEST_ASSERT_EQUAL_MY_TYPE','']) assert_equal(expected, @cmock_generator_utils_simple.code_verify_an_arg_expectation(function, arg)) end @@ -218,7 +222,7 @@ class CMockGeneratorUtilsTest < Test::Unit::TestCase should 'handle pointers to custom types with array handlers, even if the array extension is turned off' do function = { :name => 'Pear' } arg = test_arg[:mytype] - expected = " UNITY_TEST_ASSERT_EQUAL_MY_TYPE_ARRAY(&cmock_call_instance->Expected_MyMyType, &MyMyType, 1, cmock_line, \"Function 'Pear' called with unexpected value for argument 'MyMyType'.\");\n" + expected = " {\n UNITY_TEST_ASSERT_EQUAL_MY_TYPE_ARRAY(&cmock_call_instance->Expected_MyMyType, &MyMyType, 1, cmock_line, \"Function 'Pear' called with unexpected value for argument 'MyMyType'.\");\n }\n" @unity_helper.expect.get_helper('MY_TYPE').returns(['UNITY_TEST_ASSERT_EQUAL_MY_TYPE_ARRAY','&']) assert_equal(expected, @cmock_generator_utils_simple.code_verify_an_arg_expectation(function, arg)) end @@ -226,7 +230,7 @@ class CMockGeneratorUtilsTest < Test::Unit::TestCase should 'handle a simple assert when requested with array plugin enabled' do function = { :name => 'Pear' } arg = test_arg[:int] - expected = " UNITY_TEST_ASSERT_EQUAL_INT(cmock_call_instance->Expected_MyInt, MyInt, cmock_line, \"Function 'Pear' called with unexpected value for argument 'MyInt'.\");\n" + expected = " {\n UNITY_TEST_ASSERT_EQUAL_INT(cmock_call_instance->Expected_MyInt, MyInt, cmock_line, \"Function 'Pear' called with unexpected value for argument 'MyInt'.\");\n }\n" @unity_helper.expect.get_helper('int').returns(['UNITY_TEST_ASSERT_EQUAL_INT','']) assert_equal(expected, @cmock_generator_utils_complex.code_verify_an_arg_expectation(function, arg)) end @@ -234,12 +238,14 @@ class CMockGeneratorUtilsTest < Test::Unit::TestCase should 'handle an array comparison with array plugin enabled' do function = { :name => 'Pear' } arg = test_arg[:int_ptr] - expected = " if (cmock_call_instance->Expected_MyIntPtr == NULL)\n" + - " { UNITY_TEST_ASSERT_NULL(MyIntPtr, cmock_line, \"Expected NULL. Function 'Pear' called with unexpected value for argument 'MyIntPtr'.\"); }\n" + - " else if (cmock_call_instance->Expected_MyIntPtr_Depth == 0)\n" + - " { UNITY_TEST_ASSERT_EQUAL_PTR(cmock_call_instance->Expected_MyIntPtr, MyIntPtr, cmock_line, \"Function 'Pear' called with unexpected value for argument 'MyIntPtr'.\"); }\n" + - " else\n" + - " { UNITY_TEST_ASSERT_EQUAL_INT_ARRAY(cmock_call_instance->Expected_MyIntPtr, MyIntPtr, cmock_call_instance->Expected_MyIntPtr_Depth, cmock_line, \"Function 'Pear' called with unexpected value for argument 'MyIntPtr'.\"); }\n" + expected = " {\n" + + " if (cmock_call_instance->Expected_MyIntPtr == NULL)\n" + + " { UNITY_TEST_ASSERT_NULL(MyIntPtr, cmock_line, \"Expected NULL. Function 'Pear' called with unexpected value for argument 'MyIntPtr'.\"); }\n" + + " else if (cmock_call_instance->Expected_MyIntPtr_Depth == 0)\n" + + " { UNITY_TEST_ASSERT_EQUAL_PTR(cmock_call_instance->Expected_MyIntPtr, MyIntPtr, cmock_line, \"Function 'Pear' called with unexpected value for argument 'MyIntPtr'.\"); }\n" + + " else\n" + + " { UNITY_TEST_ASSERT_EQUAL_INT_ARRAY(cmock_call_instance->Expected_MyIntPtr, MyIntPtr, cmock_call_instance->Expected_MyIntPtr_Depth, cmock_line, \"Function 'Pear' called with unexpected value for argument 'MyIntPtr'.\"); }\n" + + " }\n" @unity_helper.expect.get_helper('int*').returns(['UNITY_TEST_ASSERT_EQUAL_INT_ARRAY','']) assert_equal(expected, @cmock_generator_utils_complex.code_verify_an_arg_expectation(function, arg)) end @@ -247,7 +253,7 @@ class CMockGeneratorUtilsTest < Test::Unit::TestCase should 'handle const char as string compares with array plugin enabled' do function = { :name => 'Pear' } arg = test_arg[:string] - expected = " UNITY_TEST_ASSERT_EQUAL_STRING(cmock_call_instance->Expected_MyStr, MyStr, cmock_line, \"Function 'Pear' called with unexpected value for argument 'MyStr'.\");\n" + expected = " {\n UNITY_TEST_ASSERT_EQUAL_STRING(cmock_call_instance->Expected_MyStr, MyStr, cmock_line, \"Function 'Pear' called with unexpected value for argument 'MyStr'.\");\n }\n" @unity_helper.expect.get_helper('char*').returns(['UNITY_TEST_ASSERT_EQUAL_STRING','']) assert_equal(expected, @cmock_generator_utils_complex.code_verify_an_arg_expectation(function, arg)) end @@ -255,7 +261,7 @@ class CMockGeneratorUtilsTest < Test::Unit::TestCase should 'handle custom types as memory compares when we have no better way to do it with array plugin enabled' do function = { :name => 'Pear' } arg = test_arg[:mytype] - expected = " UNITY_TEST_ASSERT_EQUAL_MEMORY((void*)(&cmock_call_instance->Expected_MyMyType), (void*)(&MyMyType), sizeof(MY_TYPE), cmock_line, \"Function 'Pear' called with unexpected value for argument 'MyMyType'.\");\n" + expected = " {\n UNITY_TEST_ASSERT_EQUAL_MEMORY((void*)(&cmock_call_instance->Expected_MyMyType), (void*)(&MyMyType), sizeof(MY_TYPE), cmock_line, \"Function 'Pear' called with unexpected value for argument 'MyMyType'.\");\n }\n" @unity_helper.expect.get_helper('MY_TYPE').returns(['UNITY_TEST_ASSERT_EQUAL_MEMORY','&']) assert_equal(expected, @cmock_generator_utils_complex.code_verify_an_arg_expectation(function, arg)) end @@ -263,7 +269,7 @@ class CMockGeneratorUtilsTest < Test::Unit::TestCase should 'handle custom types with custom handlers when available, even if they do not support the extra message with array plugin enabled' do function = { :name => 'Pear' } arg = test_arg[:mytype] - expected = " UNITY_TEST_ASSERT_EQUAL_MY_TYPE(cmock_call_instance->Expected_MyMyType, MyMyType, cmock_line, \"Function 'Pear' called with unexpected value for argument 'MyMyType'.\");\n" + expected = " {\n UNITY_TEST_ASSERT_EQUAL_MY_TYPE(cmock_call_instance->Expected_MyMyType, MyMyType, cmock_line, \"Function 'Pear' called with unexpected value for argument 'MyMyType'.\");\n }\n" @unity_helper.expect.get_helper('MY_TYPE').returns(['UNITY_TEST_ASSERT_EQUAL_MY_TYPE','']) assert_equal(expected, @cmock_generator_utils_complex.code_verify_an_arg_expectation(function, arg)) end @@ -271,12 +277,14 @@ class CMockGeneratorUtilsTest < Test::Unit::TestCase should 'handle custom types with array handlers when array plugin is enabled' do function = { :name => 'Pear' } arg = test_arg[:mytype_ptr] - expected = " if (cmock_call_instance->Expected_MyMyTypePtr == NULL)\n" + - " { UNITY_TEST_ASSERT_NULL(MyMyTypePtr, cmock_line, \"Expected NULL. Function 'Pear' called with unexpected value for argument 'MyMyTypePtr'.\"); }\n" + - " else if (cmock_call_instance->Expected_MyMyTypePtr_Depth == 0)\n" + - " { UNITY_TEST_ASSERT_EQUAL_PTR(cmock_call_instance->Expected_MyMyTypePtr, MyMyTypePtr, cmock_line, \"Function 'Pear' called with unexpected value for argument 'MyMyTypePtr'.\"); }\n" + - " else\n" + - " { UNITY_TEST_ASSERT_EQUAL_MY_TYPE_ARRAY(cmock_call_instance->Expected_MyMyTypePtr, MyMyTypePtr, cmock_call_instance->Expected_MyMyTypePtr_Depth, cmock_line, \"Function 'Pear' called with unexpected value for argument 'MyMyTypePtr'.\"); }\n" + expected = " {\n" + + " if (cmock_call_instance->Expected_MyMyTypePtr == NULL)\n" + + " { UNITY_TEST_ASSERT_NULL(MyMyTypePtr, cmock_line, \"Expected NULL. Function 'Pear' called with unexpected value for argument 'MyMyTypePtr'.\"); }\n" + + " else if (cmock_call_instance->Expected_MyMyTypePtr_Depth == 0)\n" + + " { UNITY_TEST_ASSERT_EQUAL_PTR(cmock_call_instance->Expected_MyMyTypePtr, MyMyTypePtr, cmock_line, \"Function 'Pear' called with unexpected value for argument 'MyMyTypePtr'.\"); }\n" + + " else\n" + + " { UNITY_TEST_ASSERT_EQUAL_MY_TYPE_ARRAY(cmock_call_instance->Expected_MyMyTypePtr, MyMyTypePtr, cmock_call_instance->Expected_MyMyTypePtr_Depth, cmock_line, \"Function 'Pear' called with unexpected value for argument 'MyMyTypePtr'.\"); }\n" + + " }\n" @unity_helper.expect.get_helper('MY_TYPE*').returns(['UNITY_TEST_ASSERT_EQUAL_MY_TYPE_ARRAY','']) assert_equal(expected, @cmock_generator_utils_complex.code_verify_an_arg_expectation(function, arg)) end @@ -284,7 +292,7 @@ class CMockGeneratorUtilsTest < Test::Unit::TestCase should 'handle custom types with array handlers when array plugin is enabled for non-array types' do function = { :name => 'Pear' } arg = test_arg[:mytype] - expected = " UNITY_TEST_ASSERT_EQUAL_MY_TYPE_ARRAY(&cmock_call_instance->Expected_MyMyType, &MyMyType, 1, cmock_line, \"Function 'Pear' called with unexpected value for argument 'MyMyType'.\");\n" + expected = " {\n UNITY_TEST_ASSERT_EQUAL_MY_TYPE_ARRAY(&cmock_call_instance->Expected_MyMyType, &MyMyType, 1, cmock_line, \"Function 'Pear' called with unexpected value for argument 'MyMyType'.\");\n }\n" @unity_helper.expect.get_helper('MY_TYPE').returns(['UNITY_TEST_ASSERT_EQUAL_MY_TYPE_ARRAY','&']) assert_equal(expected, @cmock_generator_utils_complex.code_verify_an_arg_expectation(function, arg)) end From 861cf071949db387446fbbf37d17fff99064a888 Mon Sep 17 00:00:00 2001 From: Dennis Lambe Jr Date: Thu, 20 Dec 2012 14:33:54 -0500 Subject: [PATCH 3/7] Added testing for return_thru_ptr and ignore_arg support in cmock_generator_utils.rb --- test/unit/cmock_generator_utils_test.rb | 47 +++++++++++++++---------- 1 file changed, 29 insertions(+), 18 deletions(-) diff --git a/test/unit/cmock_generator_utils_test.rb b/test/unit/cmock_generator_utils_test.rb index 5721475..b2a32a0 100644 --- a/test/unit/cmock_generator_utils_test.rb +++ b/test/unit/cmock_generator_utils_test.rb @@ -17,16 +17,16 @@ class CMockGeneratorUtilsTest < Test::Unit::TestCase @config.expect.plugins.returns([]) @config.expect.plugins.returns([]) @config.expect.plugins.returns([]) - @config.expect.treat_as.returns(['int','short','long','char','char*']) + @config.expect.treat_as.returns({'int' => 'INT','short' => 'INT16','long' => 'INT','char' => 'INT8','char*' => 'STRING'}) @cmock_generator_utils_simple = CMockGeneratorUtils.new(@config, {:unity_helper => @unity_helper}) @config.expect.when_ptr.returns(:smart) @config.expect.enforce_strict_ordering.returns(true) - @config.expect.plugins.returns([:array, :cexception]) - @config.expect.plugins.returns([:array, :cexception]) - @config.expect.plugins.returns([:array, :cexception]) - @config.expect.plugins.returns([:array, :cexception]) - @config.expect.treat_as.returns(['int','short','long','char','uint32_t','char*']) + @config.expect.plugins.returns([:array, :cexception, :return_thru_ptr, :ignore_arg]) + @config.expect.plugins.returns([:array, :cexception, :return_thru_ptr, :ignore_arg]) + @config.expect.plugins.returns([:array, :cexception, :return_thru_ptr, :ignore_arg]) + @config.expect.plugins.returns([:array, :cexception, :return_thru_ptr, :ignore_arg]) + @config.expect.treat_as.returns({'int' => 'INT','short' => 'INT16','long' => 'INT','char' => 'INT8','uint32_t' => 'HEX32','char*' => 'STRING'}) @cmock_generator_utils_complex = CMockGeneratorUtils.new(@config, {:unity_helper => @unity_helper, :A=>1, :B=>2}) end @@ -94,7 +94,7 @@ class CMockGeneratorUtilsTest < Test::Unit::TestCase expected3 = " cmock_call_instance->Expected_Kiwi = Kiwi;\n" arg4 = { :name => "Lime", :const? => false, :type => 'LIME_T', :ptr? => false } - expected4 = " memcpy(&cmock_call_instance->Expected_Lime, &Lime, sizeof(LIME_T));\n" + expected4 = " memcpy(&cmock_call_instance->Expected_Lime, &Lime, sizeof(LIME_T));\n" assert_equal(expected1, @cmock_generator_utils_simple.code_add_an_arg_expectation(arg1)) assert_equal(expected2, @cmock_generator_utils_simple.code_add_an_arg_expectation(arg2)) @@ -104,18 +104,23 @@ class CMockGeneratorUtilsTest < Test::Unit::TestCase should "add argument expectations for values when array plugin enabled" do arg1 = { :name => "Orange", :const? => false, :type => 'int', :ptr? => false } - expected1 = " cmock_call_instance->Expected_Orange = Orange;\n" + expected1 = " cmock_call_instance->Expected_Orange = Orange;\n" + + " cmock_call_instance->IgnoreArg_Orange = 0;\n" arg2 = { :name => "Lemon", :const? => true, :type => 'const char*', :ptr? => true } expected2 = " cmock_call_instance->Expected_Lemon = (const char*)Lemon;\n" + - " cmock_call_instance->Expected_Lemon_Depth = Lemon_Depth;\n" + " cmock_call_instance->Expected_Lemon_Depth = Lemon_Depth;\n" + + " cmock_call_instance->IgnoreArg_Lemon = 0;\n" arg3 = { :name => "Kiwi", :const? => false, :type => 'KIWI_T*', :ptr? => true } expected3 = " cmock_call_instance->Expected_Kiwi = Kiwi;\n" + - " cmock_call_instance->Expected_Kiwi_Depth = Kiwi_Depth;\n" + " cmock_call_instance->Expected_Kiwi_Depth = Kiwi_Depth;\n" + + " cmock_call_instance->IgnoreArg_Kiwi = 0;\n" + + " cmock_call_instance->ReturnThruPtr_Kiwi_Used = 0;\n" arg4 = { :name => "Lime", :const? => false, :type => 'LIME_T', :ptr? => false } - expected4 = " memcpy(&cmock_call_instance->Expected_Lime, &Lime, sizeof(LIME_T));\n" + expected4 = " memcpy(&cmock_call_instance->Expected_Lime, &Lime, sizeof(LIME_T));\n" + + " cmock_call_instance->IgnoreArg_Lime = 0;\n" assert_equal(expected1, @cmock_generator_utils_complex.code_add_an_arg_expectation(arg1)) assert_equal(expected2, @cmock_generator_utils_complex.code_add_an_arg_expectation(arg2, 'Lemon_Depth')) @@ -150,8 +155,12 @@ class CMockGeneratorUtilsTest < Test::Unit::TestCase expected = "void CMockExpectParameters_Melon(CMOCK_Melon_CALL_INSTANCE* cmock_call_instance, int* MyIntPtr, int MyIntPtr_Depth, const MY_TYPE MyMyType, const char* MyStr)\n{\n" + " cmock_call_instance->Expected_MyIntPtr = MyIntPtr;\n" + " cmock_call_instance->Expected_MyIntPtr_Depth = MyIntPtr_Depth;\n" + + " cmock_call_instance->IgnoreArg_MyIntPtr = 0;\n" + + " cmock_call_instance->ReturnThruPtr_MyIntPtr_Used = 0;\n" + " memcpy(&cmock_call_instance->Expected_MyMyType, &MyMyType, sizeof(MY_TYPE));\n" + + " cmock_call_instance->IgnoreArg_MyMyType = 0;\n" + " cmock_call_instance->Expected_MyStr = (char*)MyStr;\n" + + " cmock_call_instance->IgnoreArg_MyStr = 0;\n" + "}\n\n" assert_equal(expected, @cmock_generator_utils_complex.code_add_argument_loader(function)) end @@ -230,7 +239,7 @@ class CMockGeneratorUtilsTest < Test::Unit::TestCase should 'handle a simple assert when requested with array plugin enabled' do function = { :name => 'Pear' } arg = test_arg[:int] - expected = " {\n UNITY_TEST_ASSERT_EQUAL_INT(cmock_call_instance->Expected_MyInt, MyInt, cmock_line, \"Function 'Pear' called with unexpected value for argument 'MyInt'.\");\n }\n" + expected = " if (!cmock_call_instance->IgnoreArg_MyInt)\n {\n UNITY_TEST_ASSERT_EQUAL_INT(cmock_call_instance->Expected_MyInt, MyInt, cmock_line, \"Function 'Pear' called with unexpected value for argument 'MyInt'.\");\n }\n" @unity_helper.expect.get_helper('int').returns(['UNITY_TEST_ASSERT_EQUAL_INT','']) assert_equal(expected, @cmock_generator_utils_complex.code_verify_an_arg_expectation(function, arg)) end @@ -238,7 +247,8 @@ class CMockGeneratorUtilsTest < Test::Unit::TestCase should 'handle an array comparison with array plugin enabled' do function = { :name => 'Pear' } arg = test_arg[:int_ptr] - expected = " {\n" + + expected = " if (!cmock_call_instance->IgnoreArg_MyIntPtr)\n" + + " {\n" + " if (cmock_call_instance->Expected_MyIntPtr == NULL)\n" + " { UNITY_TEST_ASSERT_NULL(MyIntPtr, cmock_line, \"Expected NULL. Function 'Pear' called with unexpected value for argument 'MyIntPtr'.\"); }\n" + " else if (cmock_call_instance->Expected_MyIntPtr_Depth == 0)\n" + @@ -253,7 +263,7 @@ class CMockGeneratorUtilsTest < Test::Unit::TestCase should 'handle const char as string compares with array plugin enabled' do function = { :name => 'Pear' } arg = test_arg[:string] - expected = " {\n UNITY_TEST_ASSERT_EQUAL_STRING(cmock_call_instance->Expected_MyStr, MyStr, cmock_line, \"Function 'Pear' called with unexpected value for argument 'MyStr'.\");\n }\n" + expected = " if (!cmock_call_instance->IgnoreArg_MyStr)\n {\n UNITY_TEST_ASSERT_EQUAL_STRING(cmock_call_instance->Expected_MyStr, MyStr, cmock_line, \"Function 'Pear' called with unexpected value for argument 'MyStr'.\");\n }\n" @unity_helper.expect.get_helper('char*').returns(['UNITY_TEST_ASSERT_EQUAL_STRING','']) assert_equal(expected, @cmock_generator_utils_complex.code_verify_an_arg_expectation(function, arg)) end @@ -261,7 +271,7 @@ class CMockGeneratorUtilsTest < Test::Unit::TestCase should 'handle custom types as memory compares when we have no better way to do it with array plugin enabled' do function = { :name => 'Pear' } arg = test_arg[:mytype] - expected = " {\n UNITY_TEST_ASSERT_EQUAL_MEMORY((void*)(&cmock_call_instance->Expected_MyMyType), (void*)(&MyMyType), sizeof(MY_TYPE), cmock_line, \"Function 'Pear' called with unexpected value for argument 'MyMyType'.\");\n }\n" + expected = " if (!cmock_call_instance->IgnoreArg_MyMyType)\n {\n UNITY_TEST_ASSERT_EQUAL_MEMORY((void*)(&cmock_call_instance->Expected_MyMyType), (void*)(&MyMyType), sizeof(MY_TYPE), cmock_line, \"Function 'Pear' called with unexpected value for argument 'MyMyType'.\");\n }\n" @unity_helper.expect.get_helper('MY_TYPE').returns(['UNITY_TEST_ASSERT_EQUAL_MEMORY','&']) assert_equal(expected, @cmock_generator_utils_complex.code_verify_an_arg_expectation(function, arg)) end @@ -269,7 +279,7 @@ class CMockGeneratorUtilsTest < Test::Unit::TestCase should 'handle custom types with custom handlers when available, even if they do not support the extra message with array plugin enabled' do function = { :name => 'Pear' } arg = test_arg[:mytype] - expected = " {\n UNITY_TEST_ASSERT_EQUAL_MY_TYPE(cmock_call_instance->Expected_MyMyType, MyMyType, cmock_line, \"Function 'Pear' called with unexpected value for argument 'MyMyType'.\");\n }\n" + expected = " if (!cmock_call_instance->IgnoreArg_MyMyType)\n {\n UNITY_TEST_ASSERT_EQUAL_MY_TYPE(cmock_call_instance->Expected_MyMyType, MyMyType, cmock_line, \"Function 'Pear' called with unexpected value for argument 'MyMyType'.\");\n }\n" @unity_helper.expect.get_helper('MY_TYPE').returns(['UNITY_TEST_ASSERT_EQUAL_MY_TYPE','']) assert_equal(expected, @cmock_generator_utils_complex.code_verify_an_arg_expectation(function, arg)) end @@ -277,7 +287,8 @@ class CMockGeneratorUtilsTest < Test::Unit::TestCase should 'handle custom types with array handlers when array plugin is enabled' do function = { :name => 'Pear' } arg = test_arg[:mytype_ptr] - expected = " {\n" + + expected = " if (!cmock_call_instance->IgnoreArg_MyMyTypePtr)\n" + + " {\n" + " if (cmock_call_instance->Expected_MyMyTypePtr == NULL)\n" + " { UNITY_TEST_ASSERT_NULL(MyMyTypePtr, cmock_line, \"Expected NULL. Function 'Pear' called with unexpected value for argument 'MyMyTypePtr'.\"); }\n" + " else if (cmock_call_instance->Expected_MyMyTypePtr_Depth == 0)\n" + @@ -292,7 +303,7 @@ class CMockGeneratorUtilsTest < Test::Unit::TestCase should 'handle custom types with array handlers when array plugin is enabled for non-array types' do function = { :name => 'Pear' } arg = test_arg[:mytype] - expected = " {\n UNITY_TEST_ASSERT_EQUAL_MY_TYPE_ARRAY(&cmock_call_instance->Expected_MyMyType, &MyMyType, 1, cmock_line, \"Function 'Pear' called with unexpected value for argument 'MyMyType'.\");\n }\n" + expected = " if (!cmock_call_instance->IgnoreArg_MyMyType)\n {\n UNITY_TEST_ASSERT_EQUAL_MY_TYPE_ARRAY(&cmock_call_instance->Expected_MyMyType, &MyMyType, 1, cmock_line, \"Function 'Pear' called with unexpected value for argument 'MyMyType'.\");\n }\n" @unity_helper.expect.get_helper('MY_TYPE').returns(['UNITY_TEST_ASSERT_EQUAL_MY_TYPE_ARRAY','&']) assert_equal(expected, @cmock_generator_utils_complex.code_verify_an_arg_expectation(function, arg)) end From b2bdc5f476646b58afcf2cfe7e52fa9d41265b61 Mon Sep 17 00:00:00 2001 From: Dennis Lambe Jr Date: Thu, 20 Dec 2012 15:14:43 -0500 Subject: [PATCH 4/7] Added tests for new generator_util function ptr_or_str? --- test/unit/cmock_generator_utils_test.rb | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/test/unit/cmock_generator_utils_test.rb b/test/unit/cmock_generator_utils_test.rb index b2a32a0..94bd6cf 100644 --- a/test/unit/cmock_generator_utils_test.rb +++ b/test/unit/cmock_generator_utils_test.rb @@ -46,6 +46,12 @@ class CMockGeneratorUtilsTest < Test::Unit::TestCase assert_equal(true, @cmock_generator_utils_complex.arrays) assert_equal(true, @cmock_generator_utils_complex.cexception) end + + should "detect pointers and strings" do + assert_equal(false, @cmock_generator_utils_simple.ptr_or_str?('int')) + assert_equal(true, @cmock_generator_utils_simple.ptr_or_str?('int*')) + assert_equal(true, @cmock_generator_utils_simple.ptr_or_str?('char*')) + end should "add code for a base expectation with no plugins" do expected = From 08c1216eab7097e1f377608fb56469d95819d9c2 Mon Sep 17 00:00:00 2001 From: Dennis Lambe Jr Date: Thu, 20 Dec 2012 17:26:38 -0500 Subject: [PATCH 5/7] Added unit tests for return_thru_ptr and ignore_arg plugins --- lib/cmock_generator_plugin_ignore_arg.rb | 5 +- lib/cmock_generator_plugin_return_thru_ptr.rb | 5 +- .../cmock_generator_plugin_ignore_arg_test.rb | 116 +++++++++++++++ ...k_generator_plugin_return_thru_ptr_test.rb | 134 ++++++++++++++++++ 4 files changed, 252 insertions(+), 8 deletions(-) create mode 100644 test/unit/cmock_generator_plugin_ignore_arg_test.rb create mode 100644 test/unit/cmock_generator_plugin_return_thru_ptr_test.rb diff --git a/lib/cmock_generator_plugin_ignore_arg.rb b/lib/cmock_generator_plugin_ignore_arg.rb index e71b707..7086422 100644 --- a/lib/cmock_generator_plugin_ignore_arg.rb +++ b/lib/cmock_generator_plugin_ignore_arg.rb @@ -1,12 +1,9 @@ class CMockGeneratorPluginIgnoreArg attr_reader :priority - attr_accessor :config, :utils, :unity_helper, :ordered + attr_accessor :utils def initialize(config, utils) - @config = config - @ordered = @config.enforce_strict_ordering @utils = utils - @unity_helper = @utils.helpers[:unity_helper] @priority = 10 end diff --git a/lib/cmock_generator_plugin_return_thru_ptr.rb b/lib/cmock_generator_plugin_return_thru_ptr.rb index 8ba4fdb..4a72265 100644 --- a/lib/cmock_generator_plugin_return_thru_ptr.rb +++ b/lib/cmock_generator_plugin_return_thru_ptr.rb @@ -1,12 +1,9 @@ class CMockGeneratorPluginReturnThruPtr attr_reader :priority - attr_accessor :config, :utils, :unity_helper, :ordered + attr_accessor :utils def initialize(config, utils) - @config = config - @ordered = @config.enforce_strict_ordering @utils = utils - @unity_helper = @utils.helpers[:unity_helper] @priority = 9 end diff --git a/test/unit/cmock_generator_plugin_ignore_arg_test.rb b/test/unit/cmock_generator_plugin_ignore_arg_test.rb new file mode 100644 index 0000000..9fcab0c --- /dev/null +++ b/test/unit/cmock_generator_plugin_ignore_arg_test.rb @@ -0,0 +1,116 @@ +# ========================================== +# CMock Project - Automatic Mock Generation for C +# Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams +# [Released under MIT License. Please refer to license.txt for details] +# ========================================== + +require File.expand_path(File.dirname(__FILE__)) + "/../test_helper" +require 'cmock_generator_plugin_ignore_arg' + +class CMockGeneratorPluginIgnoreArgTest < Test::Unit::TestCase + def setup + create_mocks :config, :utils + + # int *Oak(void)" + @void_func = {:name => "Oak", :args => [], :return => test_return[:int_ptr]} + + # void Pine(int chicken, const int beef, int *tofu) + @complex_func = {:name => "Pine", + :args => [{ :type => "int", + :name => "chicken", + :ptr? => false, + }, + { :type => "int*", + :name => "beef", + :ptr? => true, + :const? => true, + }, + { :type => "int*", + :name => "tofu", + :ptr? => true, + }], + :return => test_return[:void], + :contains_ptr? => true } + + #no strict ordering + @cmock_generator_plugin_ignore_arg = CMockGeneratorPluginIgnoreArg.new(@config, @utils) + end + + def teardown + end + + should "have set up internal accessors correctly on init" do + assert_equal(@utils, @cmock_generator_plugin_ignore_arg.utils) + assert_equal(10, @cmock_generator_plugin_ignore_arg.priority) + end + + should "not include any additional include files" do + assert(!@cmock_generator_plugin_ignore_arg.respond_to?(:include_files)) + end + + should "not add to typedef structure for functions with no args" do + returned = @cmock_generator_plugin_ignore_arg.instance_typedefs(@void_func) + assert_equal("", returned) + end + + should "add to tyepdef structure mock needs of functions of style 'void func(int chicken, int* pork)'" do + expected = " int IgnoreArg_chicken;\n" + + " int IgnoreArg_beef;\n" + + " int IgnoreArg_tofu;\n" + returned = @cmock_generator_plugin_ignore_arg.instance_typedefs(@complex_func) + assert_equal(expected, returned) + end + + should "add mock function declarations for all arguments" do + expected = + "#define Pine_IgnoreArg_chicken()" + + " Pine_CMockIgnoreArg_chicken(__LINE__)\n" + + "void Pine_CMockIgnoreArg_chicken(UNITY_LINE_TYPE cmock_line);\n" + + + "#define Pine_IgnoreArg_beef()" + + " Pine_CMockIgnoreArg_beef(__LINE__)\n" + + "void Pine_CMockIgnoreArg_beef(UNITY_LINE_TYPE cmock_line);\n" + + + "#define Pine_IgnoreArg_tofu()" + + " Pine_CMockIgnoreArg_tofu(__LINE__)\n" + + "void Pine_CMockIgnoreArg_tofu(UNITY_LINE_TYPE cmock_line);\n" + + returned = @cmock_generator_plugin_ignore_arg.mock_function_declarations(@complex_func) + assert_equal(expected, returned) + end + + should "add mock interfaces for all arguments" do + expected = + "void Pine_CMockIgnoreArg_chicken(UNITY_LINE_TYPE cmock_line)\n" + + "{\n" + + " CMOCK_Pine_CALL_INSTANCE* cmock_call_instance = " + + "cmock_call_instance = (CMOCK_Pine_CALL_INSTANCE*)CMock_Guts_GetAddressFor(CMock_Guts_MemEndOfChain(Mock.Pine_CallInstance));\n" + + " UNITY_TEST_ASSERT_NOT_NULL(cmock_call_instance, cmock_line, \"chicken IgnoreArg called before Expect on 'Pine'.\");\n" + + " cmock_call_instance->IgnoreArg_chicken = 1;\n" + + "}\n\n" + + + "void Pine_CMockIgnoreArg_beef(UNITY_LINE_TYPE cmock_line)\n" + + "{\n" + + " CMOCK_Pine_CALL_INSTANCE* cmock_call_instance = " + + "cmock_call_instance = (CMOCK_Pine_CALL_INSTANCE*)CMock_Guts_GetAddressFor(CMock_Guts_MemEndOfChain(Mock.Pine_CallInstance));\n" + + " UNITY_TEST_ASSERT_NOT_NULL(cmock_call_instance, cmock_line, \"beef IgnoreArg called before Expect on 'Pine'.\");\n" + + " cmock_call_instance->IgnoreArg_beef = 1;\n" + + "}\n\n" + + + "void Pine_CMockIgnoreArg_tofu(UNITY_LINE_TYPE cmock_line)\n" + + "{\n" + + " CMOCK_Pine_CALL_INSTANCE* cmock_call_instance = " + + "cmock_call_instance = (CMOCK_Pine_CALL_INSTANCE*)CMock_Guts_GetAddressFor(CMock_Guts_MemEndOfChain(Mock.Pine_CallInstance));\n" + + " UNITY_TEST_ASSERT_NOT_NULL(cmock_call_instance, cmock_line, \"tofu IgnoreArg called before Expect on 'Pine'.\");\n" + + " cmock_call_instance->IgnoreArg_tofu = 1;\n" + + "}\n\n" + + returned = @cmock_generator_plugin_ignore_arg.mock_interfaces(@complex_func).join("") + assert_equal(expected, returned) + end + + should "not add a mock implementation" do + assert(!@cmock_generator_plugin_ignore_arg.respond_to?(:mock_implementation)) + end + +end diff --git a/test/unit/cmock_generator_plugin_return_thru_ptr_test.rb b/test/unit/cmock_generator_plugin_return_thru_ptr_test.rb new file mode 100644 index 0000000..db97701 --- /dev/null +++ b/test/unit/cmock_generator_plugin_return_thru_ptr_test.rb @@ -0,0 +1,134 @@ +# ========================================== +# CMock Project - Automatic Mock Generation for C +# Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams +# [Released under MIT License. Please refer to license.txt for details] +# ========================================== + +require File.expand_path(File.dirname(__FILE__)) + "/../test_helper" +require 'cmock_generator_plugin_return_thru_ptr' + +class CMockGeneratorPluginReturnThruPtrTest < Test::Unit::TestCase + def setup + create_mocks :config, :utils + + # int *Oak(void)" + @void_func = {:name => "Oak", :args => [], :return => test_return[:int_ptr]} + + # char *Maple(int blah) + @simple_func = {:name => "Maple", + :args => [{:name => "blah", :type => "int", :ptr? => false}], + :return => test_return[:string], + :contains_ptr? => false} + + # void Pine(int chicken, const int beef, int *tofu) + @complex_func = {:name => "Pine", + :args => [{ :type => "int", + :name => "chicken", + :ptr? => false, + }, + { :type => "int*", + :name => "beef", + :ptr? => true, + :const? => true, + }, + { :type => "int*", + :name => "tofu", + :ptr? => true, + }], + :return => test_return[:void], + :contains_ptr? => true } + + #no strict ordering + @cmock_generator_plugin_return_thru_ptr = CMockGeneratorPluginReturnThruPtr.new(@config, @utils) + end + + def teardown + end + + def simple_func_expect + @utils.expect.ptr_or_str?('int').returns(false) + end + + def complex_func_expect + @utils.expect.ptr_or_str?('int').returns(false) + @utils.expect.ptr_or_str?('int*').returns(true) + @utils.expect.ptr_or_str?('int*').returns(true) + end + + should "have set up internal accessors correctly on init" do + assert_equal(@utils, @cmock_generator_plugin_return_thru_ptr.utils) + assert_equal(9, @cmock_generator_plugin_return_thru_ptr.priority) + end + + should "not include any additional include files" do + assert(!@cmock_generator_plugin_return_thru_ptr.respond_to?(:include_files)) + end + + should "not add to typedef structure for functions of style 'int* func(void)'" do + returned = @cmock_generator_plugin_return_thru_ptr.instance_typedefs(@void_func) + assert_equal("", returned) + end + + should "add to tyepdef structure mock needs of functions of style 'void func(int chicken, int* pork)'" do + complex_func_expect() + expected = " int ReturnThruPtr_tofu_Used;\n" + + " int* ReturnThruPtr_tofu_Val;\n" + + " int ReturnThruPtr_tofu_Size;\n" + returned = @cmock_generator_plugin_return_thru_ptr.instance_typedefs(@complex_func) + assert_equal(expected, returned) + end + + should "not add an additional mock interface for functions not containing pointers" do + simple_func_expect() + returned = @cmock_generator_plugin_return_thru_ptr.mock_function_declarations(@simple_func) + assert_equal("", returned) + end + + should "add a mock function declaration only for non-const pointer arguments" do + complex_func_expect(); + + expected = + "#define Pine_ReturnThruPtr_tofu(tofu)" + + " Pine_CMockReturnMemThruPtr_tofu(__LINE__, tofu, sizeof(*tofu))\n" + + "#define Pine_ReturnArrayThruPtr_tofu(tofu, cmock_len)" + + " Pine_CMockReturnMemThruPtr_tofu(__LINE__, tofu, cmock_len * sizeof(*tofu))\n" + + "#define Pine_ReturnMemThruPtr_tofu(tofu, cmock_size)" + + " Pine_CMockReturnMemThruPtr_tofu(__LINE__, tofu, cmock_size)\n" + + "void Pine_CMockReturnMemThruPtr_tofu(UNITY_LINE_TYPE cmock_line, int* tofu, int cmock_size);\n" + + returned = @cmock_generator_plugin_return_thru_ptr.mock_function_declarations(@complex_func) + assert_equal(expected, returned) + end + + should "add mock interfaces only for non-const pointer arguments" do + complex_func_expect(); + + expected = + "void Pine_CMockReturnMemThruPtr_tofu(UNITY_LINE_TYPE cmock_line, int* tofu, int cmock_size)\n" + + "{\n" + + " CMOCK_Pine_CALL_INSTANCE* cmock_call_instance = " + + "cmock_call_instance = (CMOCK_Pine_CALL_INSTANCE*)CMock_Guts_GetAddressFor(CMock_Guts_MemEndOfChain(Mock.Pine_CallInstance));\n" + + " UNITY_TEST_ASSERT_NOT_NULL(cmock_call_instance, cmock_line, \"tofu ReturnThruPtr called before Expect on 'Pine'.\");\n" + + " cmock_call_instance->ReturnThruPtr_tofu_Used = 1;\n" + + " cmock_call_instance->ReturnThruPtr_tofu_Val = tofu;\n" + + " cmock_call_instance->ReturnThruPtr_tofu_Size = cmock_size;\n" + + "}\n\n" + + returned = @cmock_generator_plugin_return_thru_ptr.mock_interfaces(@complex_func).join("") + assert_equal(expected, returned) + end + + should "add mock implementations only for non-const pointer arguments" do + complex_func_expect() + + expected = + " if (cmock_call_instance->ReturnThruPtr_tofu_Used)\n" + + " {\n" + + " memcpy(tofu, cmock_call_instance->ReturnThruPtr_tofu_Val,\n" + + " cmock_call_instance->ReturnThruPtr_tofu_Size);\n" + + " }\n" + + + returned = @cmock_generator_plugin_return_thru_ptr.mock_implementation(@complex_func).join("") + end + +end From 86a664e4f667b97b8ee924c373f1842b7090f878 Mon Sep 17 00:00:00 2001 From: Dennis Lambe Jr Date: Thu, 20 Dec 2012 18:06:48 -0500 Subject: [PATCH 6/7] Added unit test for new CMock_Guts_MemEndOfChain() C function --- test/c/TestCMockC.c | 37 +++++++++++++++++++++++++++++++++++++ test/c/TestCMockC_Runner.c | 2 ++ 2 files changed, 39 insertions(+) diff --git a/test/c/TestCMockC.c b/test/c/TestCMockC.c index 8289141..ef076fe 100644 --- a/test/c/TestCMockC.c +++ b/test/c/TestCMockC.c @@ -278,3 +278,40 @@ void test_ThatWeCanAskForAllSortsOfSizes(void) //there aren't any after that TEST_ASSERT_EQUAL_HEX(CMOCK_GUTS_NONE, next); } + +void test_MemEndOfChain(void) +{ + CMOCK_MEM_INDEX_TYPE first = CMOCK_GUTS_NONE; + CMOCK_MEM_INDEX_TYPE element[4]; + + //verify we're cleared first + TEST_ASSERT_EQUAL(0, CMock_Guts_MemBytesUsed()); + TEST_ASSERT_EQUAL(CMOCK_MEM_SIZE, CMock_Guts_MemBytesFree()); + + //first element + element[0] = CMock_Guts_MemNew(sizeof(unsigned int)); + first = CMock_Guts_MemChain(first, element[0]); + TEST_ASSERT_MESSAGE(element[0] == CMock_Guts_MemEndOfChain(first), "Should have returned element[0]"); + + //second element + element[1] = CMock_Guts_MemNew(sizeof(unsigned int)); + CMock_Guts_MemChain(first, element[1]); + TEST_ASSERT_MESSAGE(element[1] == CMock_Guts_MemEndOfChain(first), "Should have returned element[1]"); + + //third element + element[2] = CMock_Guts_MemNew(sizeof(unsigned int)); + CMock_Guts_MemChain(first, element[2]); + TEST_ASSERT_MESSAGE(element[2] == CMock_Guts_MemEndOfChain(first), "Should have returned element[2]"); + + //fourth element + element[3] = CMock_Guts_MemNew(sizeof(unsigned int)); + CMock_Guts_MemChain(first, element[3]); + TEST_ASSERT_MESSAGE(element[3] == CMock_Guts_MemEndOfChain(first), "Should have returned element[3]"); + + //Free it all + CMock_Guts_MemFreeAll(); + + //verify we're cleared + TEST_ASSERT_EQUAL(0, CMock_Guts_MemBytesUsed()); + TEST_ASSERT_EQUAL(CMOCK_MEM_SIZE, CMock_Guts_MemBytesFree()); +} diff --git a/test/c/TestCMockC_Runner.c b/test/c/TestCMockC_Runner.c index 918f355..7699975 100644 --- a/test/c/TestCMockC_Runner.c +++ b/test/c/TestCMockC_Runner.c @@ -15,6 +15,7 @@ extern void test_MemNewWillReturnNullIfGivenIllegalSizes(void); extern void test_MemChainWillReturnNullAndDoNothingIfGivenIllegalInformation(void); extern void test_MemNextWillReturnNullIfGivenABadRoot(void); extern void test_ThatWeCanClaimAndChainAFewElementsTogether(void); +extern void test_MemEndOfChain(void); extern void test_ThatCMockStopsReturningMoreDataWhenItRunsOutOfMemory(void); extern void test_ThatCMockStopsReturningMoreDataWhenAskForMoreThanItHasLeftEvenIfNotAtExactEnd(void); extern void test_ThatWeCanAskForAllSortsOfSizes(void); @@ -28,6 +29,7 @@ int main(void) RUN_TEST(test_MemChainWillReturnNullAndDoNothingIfGivenIllegalInformation, 32); RUN_TEST(test_MemNextWillReturnNullIfGivenABadRoot, 46); RUN_TEST(test_ThatWeCanClaimAndChainAFewElementsTogether, 57); + RUN_TEST(test_MemEndOfChain, 282); RUN_TEST(test_ThatCMockStopsReturningMoreDataWhenItRunsOutOfMemory, 139); RUN_TEST(test_ThatCMockStopsReturningMoreDataWhenAskForMoreThanItHasLeftEvenIfNotAtExactEnd, 185); RUN_TEST(test_ThatWeCanAskForAllSortsOfSizes, 233); From 1547097028f2b261353730f0ea7f1e0fb11e0be1 Mon Sep 17 00:00:00 2001 From: Dennis Lambe Jr Date: Thu, 20 Dec 2012 23:59:14 -0500 Subject: [PATCH 7/7] Added system integration tests for return_thru_ptr and ignore_arg plugins --- .../test_interactions/all_plugins_coexist.yml | 2 + .../return_thru_ptr_ignore_arg.yml | 235 ++++++++++++++++++ 2 files changed, 237 insertions(+) create mode 100644 test/system/test_interactions/return_thru_ptr_ignore_arg.yml diff --git a/test/system/test_interactions/all_plugins_coexist.yml b/test/system/test_interactions/all_plugins_coexist.yml index 5acd214..6a84d7d 100644 --- a/test/system/test_interactions/all_plugins_coexist.yml +++ b/test/system/test_interactions/all_plugins_coexist.yml @@ -6,6 +6,8 @@ - :cexception - :ignore - :callback + - :return_thru_ptr + - :ignore_arg :callback_after_arg_check: true :callback_include_count: false :treat_externs: :include diff --git a/test/system/test_interactions/return_thru_ptr_ignore_arg.yml b/test/system/test_interactions/return_thru_ptr_ignore_arg.yml new file mode 100644 index 0000000..031df9f --- /dev/null +++ b/test/system/test_interactions/return_thru_ptr_ignore_arg.yml @@ -0,0 +1,235 @@ +--- +:cmock: + :mock_path: test/mocks + :mock_prefix: mock_ + :treat_as: + abs_struct: PTR + intptr: INT* + :when_ptr: :smart + :plugins: + - :array + - :ignore_arg + - :return_thru_ptr + +:systest: + :types: | + typedef int *intptr; + + struct a_struct + { + int i1; + int i2; + int i3; + }; + + struct _abs_struct + { + int abs_i1; + int abs_i2; + }; + + typedef struct _abs_struct abs_struct; + + :mockable: | + void ptr_ret_int(int *r); + void ptr_ret_ints(int *r, int *s); + void ptr_ret_array(char r[], int len); + void ptr_ret_typedef(intptr r); + void ptr_ret_struct(struct a_struct *r); + void ptr_ret_abstract(abs_struct *r); + void ptr_ret_abstract_array(abs_struct *r, int len); + void ptr_ret_const_int(int *r, const int *s); + void ptr_ret_string(char *s); + + :source: + :header: | + #include + #define lengthof(x) (sizeof(x)/sizeof((x)[0])) + + :code: | + + :tests: + :common: | + void setUp(void) {} + void tearDown(void) {} + + :units: + - :pass: TRUE + :should: "handle a single int* argument" + :code: | + test() + { + int r = 1; + int res = 4; + + ptr_ret_int_Expect(&r); + ptr_ret_int_ReturnThruPtr_r(&res); + ptr_ret_int(&r); + TEST_ASSERT_EQUAL(4, r); + } + + - :pass: TRUE + :should: "handle multiple calls" + :code: | + test() + { + int r = 1; + int res1 = 4; + int res2 = 8; + int res3 = 16; + + ptr_ret_int_Expect(&r); + ptr_ret_int_ReturnThruPtr_r(&res1); + ptr_ret_int_Expect(&r); + ptr_ret_int_ReturnThruPtr_r(&res2); + ptr_ret_int_Expect(&r); + ptr_ret_int_ReturnThruPtr_r(&res3); + + ptr_ret_int(&r); + TEST_ASSERT_EQUAL(4, r); + ptr_ret_int(&r); + TEST_ASSERT_EQUAL(8, r); + ptr_ret_int(&r); + TEST_ASSERT_EQUAL(16, r); + + } + + - :pass: TRUE + :should: "ignore an argument" + :code: | + test() + { + int r = 1, s = 2; + int res = 4; + + ptr_ret_int_Expect(&r); + ptr_ret_int_IgnoreArg_r(); + ptr_ret_int_ReturnThruPtr_r(&res); + ptr_ret_int(&s); + TEST_ASSERT_EQUAL(4, s); + } + + - :pass: TRUE + :should: "ignore a null pointer argument" + :code: | + test() + { + int r = 1; + int res = 4; + + ptr_ret_int_Expect(NULL); + ptr_ret_int_IgnoreArg_r(); + ptr_ret_int_ReturnThruPtr_r(&res); + ptr_ret_int(&r); + TEST_ASSERT_EQUAL(4, r); + } + + - :pass: TRUE + :should: "handle multiple int* arguments" + :code: | + test() + { + int r, s = 0x0880AA55; + int r_res = 4; + int s_res = 6; + + ptr_ret_ints_Expect(&r, &s); + ptr_ret_ints_ReturnThruPtr_r(&r_res); + ptr_ret_ints_ReturnThruPtr_s(&s_res); + ptr_ret_ints(&r, &s); + TEST_ASSERT_EQUAL(4, r); + TEST_ASSERT_EQUAL(6, s); + } + + - :pass: TRUE + :should: "only return through pointer when asked to" + :code: | + test() + { + int r = 0x0880AA55; + int s = 0xAA55; + int r_res = 4; + + ptr_ret_ints_Expect(&r, &s); + ptr_ret_ints_ReturnThruPtr_r(&r_res); + ptr_ret_ints(&r, &s); + TEST_ASSERT_EQUAL(4, r); + TEST_ASSERT_EQUAL(0xAA55, s); + } + + - :pass: TRUE + :should: "return an array through a pointer correctly" + :code: | + test() + { + char r_a[] = "booboorooboo"; + char r_a_ret[] = "FEEFI"; + + ptr_ret_array_Expect(r_a, lengthof(r_a)); + ptr_ret_array_ReturnArrayThruPtr_r(r_a_ret, strlen(r_a_ret)); + ptr_ret_array(r_a, lengthof(r_a)); + TEST_ASSERT_EQUAL_STRING("FEEFIorooboo", r_a); + } + + - :pass: TRUE + :should: "handle structs" + :code: | + test() + { + struct a_struct r_s = { .i1 = 2, .i2 = 3, .i3 = 4, }; + struct a_struct r_s_ret = { .i1 = 8, .i2 = 16, .i3 = 32, }; + + ptr_ret_struct_Expect(&r_s); + ptr_ret_struct_ReturnThruPtr_r(&r_s_ret); + ptr_ret_struct(&r_s); + TEST_ASSERT_EQUAL_MEMORY(&r_s_ret, &r_s, sizeof(struct a_struct)); + } + + - :pass: TRUE + :should: "handle typedefs" + :code: | + test() + { + abs_struct r_as = {.abs_i1 = 0x1234, .abs_i2 = 0x4567}; + abs_struct r_as_ret = {.abs_i1 = 0xFFAA55, .abs_i2 = 0xAAFFAA}; + ptr_ret_abstract_Expect(&r_as); + ptr_ret_abstract_ReturnMemThruPtr_r(&r_as_ret, sizeof(abs_struct)); + ptr_ret_abstract(&r_as); + TEST_ASSERT_EQUAL_MEMORY(&r_as_ret, &r_as, sizeof(abs_struct)); + } + + - :pass: TRUE + :should: "only generate ReturnThruPtr definitions for non-const arguments" + :code: | + test() + { + #if !defined(ptr_ret_const_int_ReturnThruPtr_r) + TEST_FAIL_MESSAGE("ReturnThruPtr not defined for a pointer argument."); + #endif + + #if defined(ptr_ret_const_int_ReturnThruPtr_s) + TEST_FAIL_MESSAGE("ReturnThruPtr defined for a const pointer argument."); + #endif + } + + - :pass: TRUE + :should: "generate ReturnThruPtr definitions for string arguments" + :code: | + test() + { + #if !defined(ptr_ret_string_ReturnThruPtr_s) + TEST_FAIL_MESSAGE("ReturnThruPtr not defined for a string argument."); + #endif + } + + - :pass: TRUE + :should: "generate IgnoreArg definitions" + :code: | + test() + { + #if !defined(ptr_ret_array_IgnoreArg_r) \ + || !defined(ptr_ret_array_IgnoreArg_len) \ + || !defined(ptr_ret_const_int_IgnoreArg_s) + TEST_FAIL_MESSAGE("IgnoreArg not defined for an argument."); + #endif + }