mirror of
https://github.com/ThrowTheSwitch/CMock
synced 2026-07-04 10:46:01 -04:00
573 lines
33 KiB
Ruby
573 lines
33 KiB
Ruby
# =========================================================================
|
|
# CMock - Automatic Mock Generation for C
|
|
# ThrowTheSwitch.org
|
|
# Copyright (c) 2007-26 Mike Karlesky, Mark VanderVoord, & Greg Williams
|
|
# SPDX-License-Identifier: MIT
|
|
# =========================================================================
|
|
|
|
require File.expand_path(File.dirname(__FILE__)) + "/../test_helper"
|
|
require File.expand_path(File.dirname(__FILE__)) + '/../../lib/cmock_generator_utils'
|
|
|
|
describe CMockGeneratorUtils, "Verify CMockGeneratorUtils Module" do
|
|
|
|
before do
|
|
create_mocks :config, :unity_helper, :unity_helper
|
|
|
|
@config.expect :when_ptr, :compare_ptr
|
|
@config.expect :enforce_strict_ordering, false
|
|
@config.expect :plugins, []
|
|
@config.expect :plugins, []
|
|
@config.expect :plugins, []
|
|
@config.expect :plugins, []
|
|
@config.expect :plugins, []
|
|
@config.expect :plugins, []
|
|
@config.expect :plugins, []
|
|
@config.expect :treat_as, {'int' => 'INT','short' => 'INT16','long' => 'INT','char' => 'INT8','const char*' => 'STRING'}
|
|
@cmock_generator_utils_simple = CMockGeneratorUtils.new(@config, {:unity_helper => @unity_helper})
|
|
|
|
@config.expect :when_ptr, :smart
|
|
@config.expect :enforce_strict_ordering, true
|
|
@config.expect :plugins, [:array, :cexception, :return_thru_ptr, :ignore_arg, :ignore, :ignore_stateless]
|
|
@config.expect :plugins, [:array, :cexception, :return_thru_ptr, :ignore_arg, :ignore, :ignore_stateless]
|
|
@config.expect :plugins, [:array, :cexception, :return_thru_ptr, :ignore_arg, :ignore, :ignore_stateless]
|
|
@config.expect :plugins, [:array, :cexception, :return_thru_ptr, :ignore_arg, :ignore, :ignore_stateless]
|
|
@config.expect :plugins, [:array, :cexception, :return_thru_ptr, :ignore_arg, :ignore, :ignore_stateless]
|
|
@config.expect :plugins, [:array, :cexception, :return_thru_ptr, :ignore_arg, :ignore, :ignore_stateless]
|
|
@config.expect :plugins, [:array, :cexception, :return_thru_ptr, :ignore_arg, :ignore, :ignore_stateless]
|
|
@config.expect :treat_as, {'int' => 'INT','short' => 'INT16','long' => 'INT','char' => 'INT8','uint32_t' => 'HEX32','const char*' => 'STRING'}
|
|
@cmock_generator_utils_complex = CMockGeneratorUtils.new(@config, {:unity_helper => @unity_helper, :A=>1, :B=>2})
|
|
end
|
|
|
|
after do
|
|
end
|
|
|
|
it "have set up internal accessors correctly on init" do
|
|
assert_equal(false, @cmock_generator_utils_simple.arrays)
|
|
assert_equal(false, @cmock_generator_utils_simple.cexception)
|
|
end
|
|
|
|
it "have set up internal accessors correctly on init, complete with passed helpers" do
|
|
assert_equal(true, @cmock_generator_utils_complex.arrays)
|
|
assert_equal(true, @cmock_generator_utils_complex.cexception)
|
|
end
|
|
|
|
it "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
|
|
|
|
it "add code for a base expectation with no plugins" do
|
|
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, CMockStringOutOfMemory);\n" +
|
|
" memset(cmock_call_instance, 0, sizeof(*cmock_call_instance));\n" +
|
|
" Mock.Apple_CallInstance = CMock_Guts_MemChain(Mock.Apple_CallInstance, cmock_guts_index);\n" +
|
|
" cmock_call_instance->LineNumber = cmock_line;\n"
|
|
output = @cmock_generator_utils_simple.code_add_base_expectation("Apple")
|
|
assert_equal(expected, output)
|
|
end
|
|
|
|
it "add code for a base expectation with all plugins" do
|
|
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, CMockStringOutOfMemory);\n" +
|
|
" memset(cmock_call_instance, 0, sizeof(*cmock_call_instance));\n" +
|
|
" Mock.Apple_CallInstance = CMock_Guts_MemChain(Mock.Apple_CallInstance, cmock_guts_index);\n" +
|
|
" Mock.Apple_IgnoreBool = (char)0;\n" +
|
|
" cmock_call_instance->LineNumber = cmock_line;\n" +
|
|
" cmock_call_instance->CallOrder = ++GlobalExpectCount;\n" +
|
|
" cmock_call_instance->ExceptionToThrow = CEXCEPTION_NONE;\n"
|
|
output = @cmock_generator_utils_complex.code_add_base_expectation("Apple", true)
|
|
assert_equal(expected, output)
|
|
end
|
|
|
|
it "add code for a base expectation with all plugins and ordering not supported" do
|
|
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, CMockStringOutOfMemory);\n" +
|
|
" memset(cmock_call_instance, 0, sizeof(*cmock_call_instance));\n" +
|
|
" Mock.Apple_CallInstance = CMock_Guts_MemChain(Mock.Apple_CallInstance, cmock_guts_index);\n" +
|
|
" Mock.Apple_IgnoreBool = (char)0;\n" +
|
|
" cmock_call_instance->LineNumber = cmock_line;\n" +
|
|
" cmock_call_instance->ExceptionToThrow = CEXCEPTION_NONE;\n"
|
|
output = @cmock_generator_utils_complex.code_add_base_expectation("Apple", false)
|
|
assert_equal(expected, output)
|
|
end
|
|
|
|
it "add code for a base expectation with expect_any_args plugin" do
|
|
config = create_stub(
|
|
:when_ptr => :smart,
|
|
:enforce_strict_ordering => false,
|
|
:plugins => [:expect_any_args],
|
|
:treat_as => {},
|
|
:respond_to? => false
|
|
)
|
|
utils = CMockGeneratorUtils.new(config, {})
|
|
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, CMockStringOutOfMemory);\n" +
|
|
" memset(cmock_call_instance, 0, sizeof(*cmock_call_instance));\n" +
|
|
" Mock.Apple_CallInstance = CMock_Guts_MemChain(Mock.Apple_CallInstance, cmock_guts_index);\n" +
|
|
" cmock_call_instance->LineNumber = cmock_line;\n" +
|
|
" cmock_call_instance->ExpectAnyArgsBool = (char)0;\n"
|
|
assert_equal(expected, utils.code_add_base_expectation("Apple"))
|
|
end
|
|
|
|
it "add code for a base expectation with ignore_stateless plugin (without ignore)" do
|
|
config = create_stub(
|
|
:when_ptr => :smart,
|
|
:enforce_strict_ordering => false,
|
|
:plugins => [:ignore_stateless],
|
|
:treat_as => {},
|
|
:respond_to? => false
|
|
)
|
|
utils = CMockGeneratorUtils.new(config, {})
|
|
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, CMockStringOutOfMemory);\n" +
|
|
" memset(cmock_call_instance, 0, sizeof(*cmock_call_instance));\n" +
|
|
" Mock.Apple_CallInstance = CMock_Guts_MemChain(Mock.Apple_CallInstance, cmock_guts_index);\n" +
|
|
" Mock.Apple_IgnoreBool = (char)0;\n" +
|
|
" cmock_call_instance->LineNumber = cmock_line;\n"
|
|
assert_equal(expected, utils.code_add_base_expectation("Apple"))
|
|
end
|
|
|
|
it "add argument expectations for values when no array plugin" do
|
|
arg1 = { :name => "Orange", :const? => false, :type => 'int', :ptr? => false }
|
|
expected1 = " cmock_call_instance->Expected_Orange = Orange;\n"
|
|
|
|
arg2 = { :name => "Lemon", :const? => true, :type => 'const char*', :ptr? => false }
|
|
expected2 = " cmock_call_instance->Expected_Lemon = Lemon;\n"
|
|
|
|
arg3 = { :name => "Kiwi", :const? => false, :type => 'KIWI_T*', :ptr? => true }
|
|
expected3 = " cmock_call_instance->Expected_Kiwi = Kiwi;\n"
|
|
|
|
arg4 = { :name => "Lime", :const? => false, :type => 'LIME_T', :ptr? => false }
|
|
expected4 = " memcpy((void*)(&cmock_call_instance->Expected_Lime), (const void*)(&Lime),\n" +
|
|
" sizeof(LIME_T[sizeof(Lime) == sizeof(LIME_T) ? 1 : -1])); /* add LIME_T to :treat_as_array if this causes an error */\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))
|
|
assert_equal(expected3, @cmock_generator_utils_simple.code_add_an_arg_expectation(arg3))
|
|
assert_equal(expected4, @cmock_generator_utils_simple.code_add_an_arg_expectation(arg4))
|
|
end
|
|
|
|
it "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" +
|
|
" cmock_call_instance->IgnoreArg_Orange = 0;\n"
|
|
|
|
arg2 = { :name => "Lemon", :const? => true, :type => 'const char*', :ptr? => false }
|
|
expected2 = " cmock_call_instance->Expected_Lemon = Lemon;\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 = Mango_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((void*)(&cmock_call_instance->Expected_Lime), (const void*)(&Lime),\n" +
|
|
" sizeof(LIME_T[sizeof(Lime) == sizeof(LIME_T) ? 1 : -1])); /* add LIME_T to :treat_as_array if this causes an error */\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'))
|
|
assert_equal(expected3, @cmock_generator_utils_complex.code_add_an_arg_expectation(arg3, 'Mango_Depth'))
|
|
assert_equal(expected4, @cmock_generator_utils_complex.code_add_an_arg_expectation(arg4))
|
|
end
|
|
|
|
it 'not have an argument loader when the function has no arguments' do
|
|
function = { :name => "Melon", :args_string => "void" }
|
|
|
|
assert_equal("", @cmock_generator_utils_complex.code_add_argument_loader(function))
|
|
end
|
|
|
|
it 'create an argument loader when the function has arguments' do
|
|
function = { :name => "Melon",
|
|
:args_string => "stuff",
|
|
:args => [test_arg[:int_ptr], test_arg[:mytype], test_arg[:string]]
|
|
}
|
|
expected = "void CMockExpectParameters_Melon(CMOCK_Melon_CALL_INSTANCE* cmock_call_instance, stuff);\n" +
|
|
"void CMockExpectParameters_Melon(CMOCK_Melon_CALL_INSTANCE* cmock_call_instance, stuff)\n{\n" +
|
|
" cmock_call_instance->Expected_MyIntPtr = MyIntPtr;\n" +
|
|
" memcpy((void*)(&cmock_call_instance->Expected_MyMyType), (const void*)(&MyMyType),\n" +
|
|
" sizeof(MY_TYPE[sizeof(MyMyType) == sizeof(MY_TYPE) ? 1 : -1])); /* add MY_TYPE to :treat_as_array if this causes an error */\n" +
|
|
" cmock_call_instance->Expected_MyStr = MyStr;\n" +
|
|
"}\n\n"
|
|
assert_equal(expected, @cmock_generator_utils_simple.code_add_argument_loader(function))
|
|
end
|
|
|
|
it 'create an argument loader when the function has arguments supporting arrays' do
|
|
function = { :name => "Melon",
|
|
:args_string => "stuff",
|
|
:args => [test_arg[:int_ptr], test_arg[:mytype], test_arg[:string]]
|
|
}
|
|
expected = "void CMockExpectParameters_Melon(CMOCK_Melon_CALL_INSTANCE* cmock_call_instance, int* MyIntPtr, int MyIntPtr_Depth, const MY_TYPE MyMyType, const char* MyStr);\n" +
|
|
"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((void*)(&cmock_call_instance->Expected_MyMyType), (const void*)(&MyMyType),\n" +
|
|
" sizeof(MY_TYPE[sizeof(MyMyType) == sizeof(MY_TYPE) ? 1 : -1])); /* add MY_TYPE to :treat_as_array if this causes an error */\n" +
|
|
" cmock_call_instance->IgnoreArg_MyMyType = 0;\n" +
|
|
" cmock_call_instance->Expected_MyStr = MyStr;\n" +
|
|
" cmock_call_instance->IgnoreArg_MyStr = 0;\n" +
|
|
"}\n\n"
|
|
assert_equal(expected, @cmock_generator_utils_complex.code_add_argument_loader(function))
|
|
end
|
|
|
|
it 'create an argument loader when the function has pointer arguments supporting arrays' do
|
|
function = { :name => "Melon",
|
|
:args_string => "stuff",
|
|
:args => [test_arg[:const_ptr], test_arg[:double_ptr]]
|
|
}
|
|
expected = "void CMockExpectParameters_Melon(CMOCK_Melon_CALL_INSTANCE* cmock_call_instance, int* const MyConstPtr, int MyConstPtr_Depth, int const** MyDoublePtr, int MyDoublePtr_Depth);\n" +
|
|
"void CMockExpectParameters_Melon(CMOCK_Melon_CALL_INSTANCE* cmock_call_instance, int* const MyConstPtr, int MyConstPtr_Depth, int const** MyDoublePtr, int MyDoublePtr_Depth)\n{\n" +
|
|
" cmock_call_instance->Expected_MyConstPtr = MyConstPtr;\n" +
|
|
" cmock_call_instance->Expected_MyConstPtr_Depth = MyConstPtr_Depth;\n" +
|
|
" cmock_call_instance->IgnoreArg_MyConstPtr = 0;\n" +
|
|
" cmock_call_instance->ReturnThruPtr_MyConstPtr_Used = 0;\n" +
|
|
" cmock_call_instance->Expected_MyDoublePtr = MyDoublePtr;\n" +
|
|
" cmock_call_instance->Expected_MyDoublePtr_Depth = MyDoublePtr_Depth;\n" +
|
|
" cmock_call_instance->IgnoreArg_MyDoublePtr = 0;\n" +
|
|
"}\n\n"
|
|
assert_equal(expected, @cmock_generator_utils_complex.code_add_argument_loader(function))
|
|
end
|
|
|
|
it "not call argument loader if there are no arguments to actually use for this function" do
|
|
function = { :name => "Pineapple", :args_string => "void" }
|
|
|
|
assert_equal("", @cmock_generator_utils_complex.code_call_argument_loader(function))
|
|
end
|
|
|
|
it 'call an argument loader when the function has arguments' do
|
|
function = { :name => "Pineapple",
|
|
:args_string => "stuff",
|
|
:args => [test_arg[:int_ptr], test_arg[:mytype], test_arg[:string]]
|
|
}
|
|
expected = " CMockExpectParameters_Pineapple(cmock_call_instance, MyIntPtr, MyMyType, MyStr);\n"
|
|
assert_equal(expected, @cmock_generator_utils_simple.code_call_argument_loader(function))
|
|
end
|
|
|
|
it 'call an argument loader when the function has arguments with arrays' do
|
|
function = { :name => "Pineapple",
|
|
:args_string => "stuff",
|
|
:args => [test_arg[:int_ptr], test_arg[:mytype], test_arg[:string]]
|
|
}
|
|
expected = " CMockExpectParameters_Pineapple(cmock_call_instance, MyIntPtr, 1, MyMyType, MyStr);\n"
|
|
assert_equal(expected, @cmock_generator_utils_complex.code_call_argument_loader(function))
|
|
end
|
|
|
|
it 'handle a simple assert when requested' do
|
|
function = { :name => 'Pear' }
|
|
arg = test_arg[:int]
|
|
expected = " {\n" +
|
|
" UNITY_SET_DETAILS(CMockString_Pear,CMockString_MyInt);\n" +
|
|
" UNITY_TEST_ASSERT_EQUAL_INT(cmock_call_instance->Expected_MyInt, MyInt, cmock_line, CMockStringMismatch);\n" +
|
|
" }\n"
|
|
@unity_helper.expect :nil?, false
|
|
@unity_helper.expect :get_helper, ['UNITY_TEST_ASSERT_EQUAL_INT', ''], ['int']
|
|
assert_equal(expected, @cmock_generator_utils_simple.code_verify_an_arg_expectation(function, arg))
|
|
end
|
|
|
|
it 'handle a pointer comparison when configured to do so' do
|
|
function = { :name => 'Pear' }
|
|
arg = test_arg[:int_ptr]
|
|
expected = " {\n" +
|
|
" UNITY_SET_DETAILS(CMockString_Pear,CMockString_MyIntPtr);\n" +
|
|
" UNITY_TEST_ASSERT_EQUAL_PTR(cmock_call_instance->Expected_MyIntPtr, MyIntPtr, cmock_line, CMockStringMismatch);\n" +
|
|
" }\n"
|
|
assert_equal(expected, @cmock_generator_utils_simple.code_verify_an_arg_expectation(function, arg))
|
|
end
|
|
|
|
it 'handle const char as string compares ' do
|
|
function = { :name => 'Pear' }
|
|
arg = test_arg[:string]
|
|
expected = " {\n" +
|
|
" UNITY_SET_DETAILS(CMockString_Pear,CMockString_MyStr);\n" +
|
|
" UNITY_TEST_ASSERT_EQUAL_STRING(cmock_call_instance->Expected_MyStr, MyStr, cmock_line, CMockStringMismatch);\n" +
|
|
" }\n"
|
|
@unity_helper.expect :nil?, false
|
|
@unity_helper.expect :get_helper, ['UNITY_TEST_ASSERT_EQUAL_STRING',''], ['const char*']
|
|
assert_equal(expected, @cmock_generator_utils_simple.code_verify_an_arg_expectation(function, arg))
|
|
end
|
|
|
|
it 'handle custom types as memory compares when we have no better way to do it' do
|
|
function = { :name => 'Pear' }
|
|
arg = test_arg[:mytype]
|
|
expected = " {\n" +
|
|
" UNITY_SET_DETAILS(CMockString_Pear,CMockString_MyMyType);\n" +
|
|
" UNITY_TEST_ASSERT_EQUAL_MEMORY(&cmock_call_instance->Expected_MyMyType, &MyMyType, sizeof(MY_TYPE), cmock_line, CMockStringMismatch);\n" +
|
|
" }\n"
|
|
@unity_helper.expect :nil?, false
|
|
@unity_helper.expect :get_helper, ['UNITY_TEST_ASSERT_EQUAL_MEMORY','&'], ['MY_TYPE']
|
|
assert_equal(expected, @cmock_generator_utils_simple.code_verify_an_arg_expectation(function, arg))
|
|
end
|
|
|
|
it '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 = " {\n" +
|
|
" UNITY_SET_DETAILS(CMockString_Pear,CMockString_MyMyType);\n" +
|
|
" UNITY_TEST_ASSERT_EQUAL_MY_TYPE(cmock_call_instance->Expected_MyMyType, MyMyType, cmock_line, CMockStringMismatch);\n" +
|
|
" }\n"
|
|
@unity_helper.expect :nil?, false
|
|
@unity_helper.expect :get_helper, ['UNITY_TEST_ASSERT_EQUAL_MY_TYPE',''], ['MY_TYPE']
|
|
assert_equal(expected, @cmock_generator_utils_simple.code_verify_an_arg_expectation(function, arg))
|
|
end
|
|
|
|
it '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 = " {\n" +
|
|
" UNITY_SET_DETAILS(CMockString_Pear,CMockString_MyMyType);\n" +
|
|
" UNITY_TEST_ASSERT_EQUAL_MY_TYPE_ARRAY(&cmock_call_instance->Expected_MyMyType, &MyMyType, 1, cmock_line, CMockStringMismatch);\n" +
|
|
" }\n"
|
|
@unity_helper.expect :nil?, false
|
|
@unity_helper.expect :get_helper, ['UNITY_TEST_ASSERT_EQUAL_MY_TYPE_ARRAY','&'], ['MY_TYPE']
|
|
assert_equal(expected, @cmock_generator_utils_simple.code_verify_an_arg_expectation(function, arg))
|
|
end
|
|
|
|
it 'handle a simple assert when requested with array plugin enabled' do
|
|
function = { :name => 'Pear' }
|
|
arg = test_arg[:int]
|
|
expected = " if (!cmock_call_instance->IgnoreArg_MyInt)\n" +
|
|
" {\n" +
|
|
" UNITY_SET_DETAILS(CMockString_Pear,CMockString_MyInt);\n" +
|
|
" UNITY_TEST_ASSERT_EQUAL_INT(cmock_call_instance->Expected_MyInt, MyInt, cmock_line, CMockStringMismatch);\n" +
|
|
" }\n"
|
|
@unity_helper.expect :nil?, false
|
|
@unity_helper.expect :get_helper, ['UNITY_TEST_ASSERT_EQUAL_INT',''], ['int']
|
|
assert_equal(expected, @cmock_generator_utils_complex.code_verify_an_arg_expectation(function, arg))
|
|
end
|
|
|
|
it 'handle an array comparison with array plugin enabled' do
|
|
function = { :name => 'Pear' }
|
|
arg = test_arg[:int_ptr]
|
|
expected = " if (!cmock_call_instance->IgnoreArg_MyIntPtr)\n" +
|
|
" {\n" +
|
|
" UNITY_SET_DETAILS(CMockString_Pear,CMockString_MyIntPtr);\n" +
|
|
" if (cmock_call_instance->Expected_MyIntPtr == NULL)\n" +
|
|
" { UNITY_TEST_ASSERT_NULL(MyIntPtr, cmock_line, CMockStringExpNULL); }\n" +
|
|
" else if (cmock_call_instance->Expected_MyIntPtr_Depth == 0)\n" +
|
|
" { UNITY_TEST_ASSERT_EQUAL_PTR(cmock_call_instance->Expected_MyIntPtr, MyIntPtr, cmock_line, CMockStringMismatch); }\n" +
|
|
" else\n" +
|
|
" { UNITY_TEST_ASSERT_EQUAL_INT_ARRAY(cmock_call_instance->Expected_MyIntPtr, MyIntPtr, cmock_call_instance->Expected_MyIntPtr_Depth, cmock_line, CMockStringMismatch); }\n" +
|
|
" }\n"
|
|
@unity_helper.expect :nil?, false
|
|
@unity_helper.expect :get_helper, ['UNITY_TEST_ASSERT_EQUAL_INT_ARRAY',''], ['int*']
|
|
assert_equal(expected, @cmock_generator_utils_complex.code_verify_an_arg_expectation(function, arg))
|
|
end
|
|
|
|
it 'handle const char as string compares with array plugin enabled' do
|
|
function = { :name => 'Pear' }
|
|
arg = test_arg[:string]
|
|
expected = " if (!cmock_call_instance->IgnoreArg_MyStr)\n" +
|
|
" {\n" +
|
|
" UNITY_SET_DETAILS(CMockString_Pear,CMockString_MyStr);\n" +
|
|
" UNITY_TEST_ASSERT_EQUAL_STRING(cmock_call_instance->Expected_MyStr, MyStr, cmock_line, CMockStringMismatch);\n" +
|
|
" }\n"
|
|
@unity_helper.expect :nil?, false
|
|
@unity_helper.expect :get_helper, ['UNITY_TEST_ASSERT_EQUAL_STRING',''], ['const char*']
|
|
assert_equal(expected, @cmock_generator_utils_complex.code_verify_an_arg_expectation(function, arg))
|
|
end
|
|
|
|
it '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 = " if (!cmock_call_instance->IgnoreArg_MyMyType)\n" +
|
|
" {\n" +
|
|
" UNITY_SET_DETAILS(CMockString_Pear,CMockString_MyMyType);\n" +
|
|
" if (cmock_call_instance->Expected_MyMyType == NULL)\n" +
|
|
" { UNITY_TEST_ASSERT_NULL(MyMyType, cmock_line, CMockStringExpNULL); }\n" +
|
|
" else\n" +
|
|
" { UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY(cmock_call_instance->Expected_MyMyType, MyMyType, sizeof(MY_TYPE), 1, cmock_line, CMockStringMismatch); }\n" +
|
|
" }\n"
|
|
@unity_helper.expect :nil?, false
|
|
@unity_helper.expect :get_helper, ['UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY', ''], ['MY_TYPE']
|
|
assert_equal(expected, @cmock_generator_utils_complex.code_verify_an_arg_expectation(function, arg))
|
|
end
|
|
|
|
it '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 = " if (!cmock_call_instance->IgnoreArg_MyMyType)\n" +
|
|
" {\n" +
|
|
" UNITY_SET_DETAILS(CMockString_Pear,CMockString_MyMyType);\n" +
|
|
" UNITY_TEST_ASSERT_EQUAL_MY_TYPE(cmock_call_instance->Expected_MyMyType, MyMyType, cmock_line, CMockStringMismatch);\n" +
|
|
" }\n"
|
|
@unity_helper.expect :nil?, false
|
|
@unity_helper.expect :get_helper, ['UNITY_TEST_ASSERT_EQUAL_MY_TYPE', ''], ['MY_TYPE']
|
|
assert_equal(expected, @cmock_generator_utils_complex.code_verify_an_arg_expectation(function, arg))
|
|
end
|
|
|
|
it '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->IgnoreArg_MyMyTypePtr)\n" +
|
|
" {\n" +
|
|
" UNITY_SET_DETAILS(CMockString_Pear,CMockString_MyMyTypePtr);\n" +
|
|
" if (cmock_call_instance->Expected_MyMyTypePtr == NULL)\n" +
|
|
" { UNITY_TEST_ASSERT_NULL(MyMyTypePtr, cmock_line, CMockStringExpNULL); }\n" +
|
|
" else if (cmock_call_instance->Expected_MyMyTypePtr_Depth == 0)\n" +
|
|
" { UNITY_TEST_ASSERT_EQUAL_PTR(cmock_call_instance->Expected_MyMyTypePtr, MyMyTypePtr, cmock_line, CMockStringMismatch); }\n" +
|
|
" else\n" +
|
|
" { UNITY_TEST_ASSERT_EQUAL_MY_TYPE_ARRAY(cmock_call_instance->Expected_MyMyTypePtr, MyMyTypePtr, cmock_call_instance->Expected_MyMyTypePtr_Depth, cmock_line, CMockStringMismatch); }\n" +
|
|
" }\n"
|
|
@unity_helper.expect :nil?, false
|
|
@unity_helper.expect :get_helper, ['UNITY_TEST_ASSERT_EQUAL_MY_TYPE_ARRAY', ''], ['MY_TYPE*']
|
|
assert_equal(expected, @cmock_generator_utils_complex.code_verify_an_arg_expectation(function, arg))
|
|
end
|
|
|
|
it 'handle custom types with array handlers when array plugin is enabled for non-array types' do
|
|
function = { :name => 'Pear' }
|
|
arg = test_arg[:mytype]
|
|
expected = " if (!cmock_call_instance->IgnoreArg_MyMyType)\n" +
|
|
" {\n" +
|
|
" UNITY_SET_DETAILS(CMockString_Pear,CMockString_MyMyType);\n" +
|
|
" UNITY_TEST_ASSERT_EQUAL_MY_TYPE_ARRAY(&cmock_call_instance->Expected_MyMyType, &MyMyType, 1, cmock_line, CMockStringMismatch);\n" +
|
|
" }\n"
|
|
@unity_helper.expect :nil?, false
|
|
@unity_helper.expect :get_helper, ['UNITY_TEST_ASSERT_EQUAL_MY_TYPE_ARRAY', '&'], ['MY_TYPE']
|
|
assert_equal(expected, @cmock_generator_utils_complex.code_verify_an_arg_expectation(function, arg))
|
|
end
|
|
|
|
# void* tests without array plugin (when_ptr: :compare_data) - these must use pointer
|
|
# comparison because dereferencing void* is illegal in C
|
|
it 'handle void pointer comparison without array plugin by using pointer comparison' do
|
|
config_stub = create_stub({
|
|
when_ptr: :compare_data,
|
|
enforce_strict_ordering: false,
|
|
plugins: [],
|
|
treat_as: {'void*' => 'HEX8_ARRAY', 'void const*' => 'HEX8_ARRAY', 'const void*' => 'HEX8_ARRAY'},
|
|
treat_as_void: []
|
|
})
|
|
utils = CMockGeneratorUtils.new(config_stub, {:unity_helper => @unity_helper})
|
|
function = { :name => 'Pear' }
|
|
|
|
[
|
|
{:type => "void*", :name => 'MyVoidPtr', :ptr? => true, :const? => false, :const_ptr? => false},
|
|
{:type => "const void*", :name => 'MyConstVoidPtr', :ptr? => true, :const? => true, :const_ptr? => false},
|
|
{:type => "void const*", :name => 'MyVoidConstPtr', :ptr? => true, :const? => false, :const_ptr? => true},
|
|
].each do |arg|
|
|
expected = " {\n" +
|
|
" UNITY_SET_DETAILS(CMockString_Pear,CMockString_#{arg[:name]});\n" +
|
|
" UNITY_TEST_ASSERT_EQUAL_PTR(cmock_call_instance->Expected_#{arg[:name]}, #{arg[:name]}, cmock_line, CMockStringMismatch);\n" +
|
|
" }\n"
|
|
assert_equal(expected, utils.code_verify_an_arg_expectation(function, arg))
|
|
end
|
|
end
|
|
|
|
it 'handle treat_as_void alias pointer comparison without array plugin by using pointer comparison' do
|
|
config_stub = create_stub({
|
|
when_ptr: :compare_data,
|
|
enforce_strict_ordering: false,
|
|
plugins: [],
|
|
treat_as: {'MY_VOID*' => 'HEX8_ARRAY'},
|
|
treat_as_void: ['MY_VOID']
|
|
})
|
|
utils = CMockGeneratorUtils.new(config_stub, {:unity_helper => @unity_helper})
|
|
function = { :name => 'Pear' }
|
|
|
|
arg = {:type => "MY_VOID*", :name => 'MyVoidAliasPtr', :ptr? => true, :const? => false, :const_ptr? => false}
|
|
expected = " {\n" +
|
|
" UNITY_SET_DETAILS(CMockString_Pear,CMockString_MyVoidAliasPtr);\n" +
|
|
" UNITY_TEST_ASSERT_EQUAL_PTR(cmock_call_instance->Expected_MyVoidAliasPtr, MyVoidAliasPtr, cmock_line, CMockStringMismatch);\n" +
|
|
" }\n"
|
|
assert_equal(expected, utils.code_verify_an_arg_expectation(function, arg))
|
|
end
|
|
|
|
it 'handle treat_as_void alias pointer with array plugin using HEX8_ARRAY to avoid sizeof(void)' do
|
|
config_stub = create_stub({
|
|
when_ptr: :compare_data,
|
|
enforce_strict_ordering: false,
|
|
plugins: [:array],
|
|
treat_as: {},
|
|
treat_as_void: ['MY_VOID']
|
|
})
|
|
utils = CMockGeneratorUtils.new(config_stub, {:unity_helper => @unity_helper})
|
|
function = { :name => 'Pear' }
|
|
|
|
arg = {:type => "MY_VOID*", :name => 'MyVoidAliasPtr', :ptr? => true, :const? => false, :const_ptr? => false}
|
|
expected = " {\n" +
|
|
" UNITY_SET_DETAILS(CMockString_Pear,CMockString_MyVoidAliasPtr);\n" +
|
|
" if (cmock_call_instance->Expected_MyVoidAliasPtr == NULL)\n" +
|
|
" { UNITY_TEST_ASSERT_NULL(MyVoidAliasPtr, cmock_line, CMockStringExpNULL); }\n" +
|
|
" else\n" +
|
|
" { UNITY_TEST_ASSERT_EQUAL_HEX8_ARRAY(cmock_call_instance->Expected_MyVoidAliasPtr, MyVoidAliasPtr, cmock_call_instance->Expected_MyVoidAliasPtr_Depth, cmock_line, CMockStringMismatch); }\n" +
|
|
" }\n"
|
|
assert_equal(expected, utils.code_verify_an_arg_expectation(function, arg))
|
|
end
|
|
|
|
it 'correctly reconstruct type strings preserving const and pointer order' do
|
|
# non-pointer: no const
|
|
assert_equal("int", CMockGeneratorUtils.arg_type_with_const({:type => "int", :ptr? => false, :const? => false, :const_ptr? => false}))
|
|
# non-pointer: const (prepended)
|
|
assert_equal("const int", CMockGeneratorUtils.arg_type_with_const({:type => "int", :ptr? => false, :const? => true, :const_ptr? => false}))
|
|
|
|
# pointer to mutable: no const
|
|
assert_equal("int*", CMockGeneratorUtils.arg_type_with_const({:type => "int*", :ptr? => true, :const? => false, :const_ptr? => false}))
|
|
|
|
# pointer to const (const int*): const already in :type, no trailing const
|
|
assert_equal("const int*", CMockGeneratorUtils.arg_type_with_const({:type => "const int*", :ptr? => true, :const? => true, :const_ptr? => false}))
|
|
|
|
# const pointer (int* const): :type has no const, const_ptr? appends " const"
|
|
assert_equal("int* const", CMockGeneratorUtils.arg_type_with_const({:type => "int*", :ptr? => true, :const? => false, :const_ptr? => true}))
|
|
|
|
# const pointer to const (const int* const)
|
|
assert_equal("const int* const", CMockGeneratorUtils.arg_type_with_const({:type => "const int*", :ptr? => true, :const? => true, :const_ptr? => true}))
|
|
|
|
# trailing-const form: int const* (same semantics as const int* but different spelling)
|
|
assert_equal("int const*", CMockGeneratorUtils.arg_type_with_const({:type => "int const*", :ptr? => true, :const? => true, :const_ptr? => false}))
|
|
|
|
# trailing-const pointer to const: int const* const
|
|
assert_equal("int const* const", CMockGeneratorUtils.arg_type_with_const({:type => "int const*", :ptr? => true, :const? => true, :const_ptr? => true}))
|
|
|
|
# custom type pointer
|
|
assert_equal("MY_TYPE*", CMockGeneratorUtils.arg_type_with_const({:type => "MY_TYPE*", :ptr? => true, :const? => false, :const_ptr? => false}))
|
|
assert_equal("const MY_TYPE", CMockGeneratorUtils.arg_type_with_const({:type => "MY_TYPE", :ptr? => false, :const? => true, :const_ptr? => false}))
|
|
|
|
# double pointer: no const_ptr, so :type used as-is
|
|
assert_equal("int**", CMockGeneratorUtils.arg_type_with_const({:type => "int**", :ptr? => true, :const? => false, :const_ptr? => false}))
|
|
assert_equal("const int**", CMockGeneratorUtils.arg_type_with_const({:type => "const int**", :ptr? => true, :const? => true, :const_ptr? => false}))
|
|
# double pointer with const_ptr: appends " const" after last *
|
|
assert_equal("int** const", CMockGeneratorUtils.arg_type_with_const({:type => "int**", :ptr? => true, :const? => false, :const_ptr? => true}))
|
|
end
|
|
|
|
it 'produce correct C declarations preserving const and pointer order' do
|
|
# const pointer to mutable int: int* const p
|
|
arg = {:type => "int*", :name => "p", :ptr? => true, :const? => false, :const_ptr? => true}
|
|
assert_equal("int* const p", CMockGeneratorUtils.arg_declaration(arg))
|
|
|
|
# pointer to const int: const int* p
|
|
arg = {:type => "const int*", :name => "p", :ptr? => true, :const? => true, :const_ptr? => false}
|
|
assert_equal("const int* p", CMockGeneratorUtils.arg_declaration(arg))
|
|
|
|
# const pointer to const int: const int* const p
|
|
arg = {:type => "const int*", :name => "p", :ptr? => true, :const? => true, :const_ptr? => true}
|
|
assert_equal("const int* const p", CMockGeneratorUtils.arg_declaration(arg))
|
|
|
|
# trailing-const form: int const* const p
|
|
arg = {:type => "int const*", :name => "p", :ptr? => true, :const? => true, :const_ptr? => true}
|
|
assert_equal("int const* const p", CMockGeneratorUtils.arg_declaration(arg))
|
|
|
|
# plain pointer: int* p
|
|
arg = {:type => "int*", :name => "p", :ptr? => true, :const? => false, :const_ptr? => false}
|
|
assert_equal("int* p", CMockGeneratorUtils.arg_declaration(arg))
|
|
|
|
# non-pointer const: const MY_TYPE v
|
|
arg = {:type => "MY_TYPE", :name => "v", :ptr? => false, :const? => true, :const_ptr? => false}
|
|
assert_equal("const MY_TYPE v", CMockGeneratorUtils.arg_declaration(arg))
|
|
end
|
|
end
|