mirror of
https://github.com/ThrowTheSwitch/CMock.git
synced 2026-09-12 13:19:57 +00:00
Merge pull request #531 from ThrowTheSwitch/feature/better_arrays
Feature/better arrays
This commit is contained in:
+46
-7
@@ -147,6 +147,27 @@ that they are pointing to the same memory address.
|
||||
* `retval func(void)` => (nothing. In fact, an additional function is only generated if the params list contains pointers)
|
||||
* `retval func(other, ptr* param)` => `void func_ExpectWithArrayAndReturn(other, ptr* param, int param_depth, retval_to_return)`
|
||||
|
||||
When the `:array_size_name` and `:array_size_type` options are configured, CMock
|
||||
can recognize that a scalar parameter is the size of an adjacent pointer parameter
|
||||
and pair them together. When a size parameter is paired with a pointer, the `_Expect`
|
||||
call automatically uses it as the array depth, and `_ExpectWithArray` preserves
|
||||
the original argument order without adding a separate depth argument.
|
||||
|
||||
When performing this type of automatic identification of arguments, CMock will also
|
||||
generate an additional `_ExpectWithArrayExtended`, which accepts an explicit
|
||||
depth for every pointer — allowing you to override the inferred depth when the
|
||||
pairing heuristic guesses wrong:
|
||||
|
||||
* `void func(int size, ptr* buf)` =>
|
||||
* `void func_ExpectWithArray(int size, ptr* buf)` _(depth inferred from `size`)_
|
||||
* `void func_ExpectWithArrayExtended(int size, ptr* buf, int buf_Depth)` _(explicit override)_
|
||||
|
||||
`_ExpectWithArrayExtended` is only generated for functions where at least one
|
||||
size parameter has been automatically identified. For all other functions the short
|
||||
`_ExpectWithArray` already gives full depth control. This function can be used to correct
|
||||
poor assumptions that CMock has made. It can also be used to separately verify a passed
|
||||
length, but compare the actual contents for a DIFFERENT number of elements.
|
||||
|
||||
|
||||
Ignore:
|
||||
-------
|
||||
@@ -722,11 +743,7 @@ from the defaults. We've tried to specify what the defaults are below.
|
||||
|
||||
* `void GoBananas(Banana * bananas, int num_bananas)`
|
||||
* `int write_data(int fd, const uint8_t * data, uint32_t size)`
|
||||
|
||||
To recognize functions like these, CMock looks for a parameter list
|
||||
containing a pointer (which could be an array) followed by something that
|
||||
could be an array size. "Something", by default, means an `int` or `size_t`
|
||||
parameter with a name containing "size" or "len".
|
||||
* `void store_data(int buf_size, uint8_t * buf)`
|
||||
|
||||
`:array_size_type` is a list of additional types (besides `int` and `size_t`)
|
||||
that could be used for an array size parameter. For example, to get CMock to
|
||||
@@ -741,8 +758,30 @@ from the defaults. We've tried to specify what the defaults are below.
|
||||
|
||||
cfg[:array_size_name] = 'size|len|num_'
|
||||
|
||||
Parameters must match *both* `:array_size_type` and `:array_size_name` (and
|
||||
must come right after a pointer parameter) to be treated as an array size.
|
||||
A parameter must match *both* `:array_size_type` and `:array_size_name` to be
|
||||
treated as an array size.
|
||||
|
||||
**Pairing heuristic:** CMock scores each candidate size parameter against each
|
||||
pointer parameter using name similarity. It strips size-words (e.g. "size",
|
||||
"len") from the size parameter's name to derive a root, then checks whether
|
||||
that root matches the pointer's name exactly (score 10), as a prefix or suffix
|
||||
(score 7), or as a substring (score 5). Adjacency in the argument list adds a
|
||||
small bonus (score +2). The highest-scoring pairing wins. This means CMock
|
||||
correctly pairs `buff_size` with `buffer` even when another pointer appears
|
||||
adjacent to `buff_size`.
|
||||
|
||||
Size parameters may appear either **before or after** the pointer they describe.
|
||||
CMock recognizes both orderings:
|
||||
|
||||
* Size after pointer: `void func(uint8_t* buf, int buf_size)` — the `_Expect`
|
||||
call uses `buf_size` as the depth automatically. `_ExpectWithArray` adds an
|
||||
explicit `buf_Depth` argument after `buf` for manual override.
|
||||
|
||||
* Size before pointer: `void func(int buf_size, uint8_t* buf)` — the `_Expect`
|
||||
call again uses `buf_size` as the depth automatically, and `_ExpectWithArray`
|
||||
keeps arguments in their original order with no extra depth argument added.
|
||||
An additional `_ExpectWithArrayExtended` variant is generated that does accept
|
||||
an explicit depth, allowing you to override the inferred value when needed.
|
||||
|
||||
Once you've told it how to recognize your arrays, CMock will give you `_Expect`
|
||||
calls that work more like `_ExpectWithArray`, and compare an array of objects
|
||||
|
||||
@@ -21,28 +21,66 @@ class CMockGeneratorPluginArray
|
||||
|
||||
def instance_typedefs(function)
|
||||
function[:args].inject('') do |all, arg|
|
||||
arg[:ptr?] ? all + " int Expected_#{arg[:name]}_Depth;\n" : all
|
||||
arg[:ptr?] || arg[:string?] ? all + " int Expected_#{arg[:name]}_Depth;\n" : all
|
||||
end
|
||||
end
|
||||
|
||||
def mock_function_declarations(function)
|
||||
return nil unless function[:contains_ptr?]
|
||||
|
||||
args_call_i = function[:args].map { |m| m[:ptr?] ? "#{m[:name]}, #{m[:name]}_Depth" : (m[:name]).to_s }.join(', ')
|
||||
args_call_o = function[:args].map { |m| m[:ptr?] ? "#{m[:name]}, (#{m[:name]}_Depth)" : (m[:name]).to_s }.join(', ')
|
||||
func_name = function[:name]
|
||||
|
||||
# C function signature: always explicit depth for every pointer/string arg
|
||||
args_string = function[:args].map do |m|
|
||||
type = @utils.arg_type_with_const(m)
|
||||
m[:ptr?] ? "#{type} #{m[:name]}, int #{m[:name]}_Depth" : "#{type} #{m[:name]}"
|
||||
m[:ptr?] || m[:string?] ? "#{@utils.arg_declaration(m)}, int #{m[:name]}_Depth" : @utils.arg_declaration(m)
|
||||
end.join(', ')
|
||||
|
||||
# Short macro params: paired ptrs (before OR after) omit _Depth (auto-filled from paired size arg)
|
||||
# string? args always need an explicit _Depth
|
||||
args_call_i = function[:args].map do |m|
|
||||
(m[:ptr?] || m[:string?]) && !m[:array_size_name] ? "#{m[:name]}, #{m[:name]}_Depth" : m[:name].to_s
|
||||
end.join(', ')
|
||||
|
||||
# Short macro call: paired ptrs pass paired size name as depth automatically
|
||||
args_call_o = function[:args].map do |m|
|
||||
if (m[:ptr?] || m[:string?]) && m[:array_size_name]
|
||||
"#{m[:name]}, (#{m[:array_size_name]})"
|
||||
elsif m[:ptr?] || m[:string?]
|
||||
"#{m[:name]}, (#{m[:name]}_Depth)"
|
||||
else
|
||||
m[:name].to_s
|
||||
end
|
||||
end.join(', ')
|
||||
|
||||
# Extended macro params: every ptr/string gets an explicit _Depth
|
||||
args_call_ext_i = function[:args].map do |m|
|
||||
m[:ptr?] || m[:string?] ? "#{m[:name]}, #{m[:name]}_Depth" : m[:name].to_s
|
||||
end.join(', ')
|
||||
|
||||
# Extended macro call: every ptr/string passes (name_Depth)
|
||||
args_call_ext_o = function[:args].map do |m|
|
||||
m[:ptr?] || m[:string?] ? "#{m[:name]}, (#{m[:name]}_Depth)" : m[:name].to_s
|
||||
end.join(', ')
|
||||
|
||||
has_paired = function[:args].any? { |m| m[:array_size_name] }
|
||||
|
||||
lines = ''
|
||||
if function[:return][:void?]
|
||||
lines << "#define #{function[:name]}_ExpectWithArrayAndReturn(#{args_call_i}, cmock_retval) TEST_FAIL_MESSAGE(\"#{function[:name]} requires _ExpectWithArray (not AndReturn)\");\n" if @error_stubs
|
||||
lines << "#define #{function[:name]}_ExpectWithArray(#{args_call_i}) #{function[:name]}_CMockExpectWithArray(__LINE__, #{args_call_o})\n"
|
||||
lines << "void #{function[:name]}_CMockExpectWithArray(UNITY_LINE_TYPE cmock_line, #{args_string});\n"
|
||||
if @error_stubs
|
||||
lines << "#define #{func_name}_ExpectWithArrayAndReturn(#{args_call_i}, cmock_retval) TEST_FAIL_MESSAGE(\"#{func_name} requires _ExpectWithArray (not AndReturn)\");\n"
|
||||
lines << "#define #{func_name}_ExpectWithArrayExtendedAndReturn(#{args_call_ext_i}, cmock_retval) TEST_FAIL_MESSAGE(\"#{func_name} requires _ExpectWithArrayExtended (not AndReturn)\");\n" if has_paired
|
||||
end
|
||||
lines << "#define #{func_name}_ExpectWithArray(#{args_call_i}) #{func_name}_CMockExpectWithArray(__LINE__, #{args_call_o})\n"
|
||||
lines << "#define #{func_name}_ExpectWithArrayExtended(#{args_call_ext_i}) #{func_name}_CMockExpectWithArray(__LINE__, #{args_call_ext_o})\n" if has_paired
|
||||
lines << "void #{func_name}_CMockExpectWithArray(UNITY_LINE_TYPE cmock_line, #{args_string});\n"
|
||||
else
|
||||
lines << "#define #{function[:name]}_ExpectWithArray(#{args_call_i}) TEST_FAIL_MESSAGE(\"#{function[:name]} requires _ExpectWithArrayAndReturn\");\n" if @error_stubs
|
||||
lines << "#define #{function[:name]}_ExpectWithArrayAndReturn(#{args_call_i}, cmock_retval) #{function[:name]}_CMockExpectWithArrayAndReturn(__LINE__, #{args_call_o}, cmock_retval)\n"
|
||||
lines << "void #{function[:name]}_CMockExpectWithArrayAndReturn(UNITY_LINE_TYPE cmock_line, #{args_string}, #{function[:return][:str]});\n"
|
||||
if @error_stubs
|
||||
lines << "#define #{func_name}_ExpectWithArray(#{args_call_i}) TEST_FAIL_MESSAGE(\"#{func_name} requires _ExpectWithArrayAndReturn\");\n"
|
||||
lines << "#define #{func_name}_ExpectWithArrayExtended(#{args_call_ext_i}) TEST_FAIL_MESSAGE(\"#{func_name} requires _ExpectWithArrayExtendedAndReturn\");\n" if has_paired
|
||||
end
|
||||
lines << "#define #{func_name}_ExpectWithArrayAndReturn(#{args_call_i}, cmock_retval) #{func_name}_CMockExpectWithArrayAndReturn(__LINE__, #{args_call_o}, cmock_retval)\n"
|
||||
lines << "#define #{func_name}_ExpectWithArrayExtendedAndReturn(#{args_call_ext_i}, cmock_retval) #{func_name}_CMockExpectWithArrayAndReturn(__LINE__, #{args_call_ext_o}, cmock_retval)\n" if has_paired
|
||||
lines << "void #{func_name}_CMockExpectWithArrayAndReturn(UNITY_LINE_TYPE cmock_line, #{args_string}, #{function[:return][:str]});\n"
|
||||
end
|
||||
lines
|
||||
end
|
||||
@@ -52,11 +90,18 @@ class CMockGeneratorPluginArray
|
||||
|
||||
lines = []
|
||||
func_name = function[:name]
|
||||
|
||||
# C function: always explicit depth for every pointer/string arg
|
||||
args_string = function[:args].map do |m|
|
||||
type = @utils.arg_type_with_const(m)
|
||||
m[:ptr?] ? "#{type} #{m[:name]}, int #{m[:name]}_Depth" : "#{type} #{m[:name]}"
|
||||
m[:ptr?] || m[:string?] ? "#{@utils.arg_declaration(m)}, int #{m[:name]}_Depth" : @utils.arg_declaration(m)
|
||||
end.join(', ')
|
||||
call_string = function[:args].map { |m| m[:ptr?] ? "#{m[:name]}, #{m[:name]}_Depth" : m[:name] }.join(', ')
|
||||
|
||||
# Call to CMockExpectParameters_: :before-paired ptrs pass only ptr name (their depth is set from paired size arg)
|
||||
# string? args always pass their depth explicitly
|
||||
call_string = function[:args].map do |m|
|
||||
(m[:ptr?] || m[:string?]) && m[:array_size_order] != :before ? "#{m[:name]}, #{m[:name]}_Depth" : m[:name]
|
||||
end.join(', ')
|
||||
|
||||
lines << if function[:return][:void?]
|
||||
"void #{func_name}_CMockExpectWithArray(UNITY_LINE_TYPE cmock_line, #{args_string})\n"
|
||||
else
|
||||
@@ -65,6 +110,11 @@ class CMockGeneratorPluginArray
|
||||
lines << "{\n"
|
||||
lines << @utils.code_add_base_expectation(func_name)
|
||||
lines << " CMockExpectParameters_#{func_name}(cmock_call_instance, #{call_string});\n"
|
||||
# Override depths for :before-paired pointers. CMockExpectParameters_ sets these from the paired
|
||||
# size arg; the explicit _Depth param here allows _ExpectWithArrayExtended to override that value.
|
||||
function[:args].each do |arg|
|
||||
lines << " cmock_call_instance->Expected_#{arg[:name]}_Depth = #{arg[:name]}_Depth;\n" if (arg[:ptr?] || arg[:string?]) && arg[:array_size_order] == :before
|
||||
end
|
||||
lines << " cmock_call_instance->ReturnVal = cmock_to_return;\n" unless function[:return][:void?]
|
||||
lines << "}\n\n"
|
||||
end
|
||||
|
||||
@@ -56,7 +56,12 @@ class CMockGeneratorPluginReturnThruPtr
|
||||
" #{function[:name]}_CMockReturnMemThruPtr_#{arg[:name]}(__LINE__, #{arg[:name]}, sizeof(*#{arg[:name]}))\n"
|
||||
end
|
||||
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"
|
||||
array_elem_size = if arg[:array_dims] && (arg[:type][-1] == '*') && !void_pointer?(arg[:type][0..-2])
|
||||
"sizeof(#{arg[:type][0..-2]})"
|
||||
else
|
||||
"sizeof(*#{arg[:name]})"
|
||||
end
|
||||
lines << " #{function[:name]}_CMockReturnMemThruPtr_#{arg[:name]}(__LINE__, #{arg[:name]}, (cmock_len * #{array_elem_size}))\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, #{ptr_to_const(arg[:type])} #{arg[:name]}, size_t cmock_size);\n"
|
||||
|
||||
+104
-17
@@ -20,6 +20,7 @@ class CMockGeneratorUtils
|
||||
@ignore = @config.plugins.include? :ignore
|
||||
@ignore_stateless = @config.plugins.include? :ignore_stateless
|
||||
@treat_as = @config.treat_as
|
||||
@treat_as_void = (['void'] + (@config.respond_to?(:treat_as_void) ? @config.treat_as_void : [])).uniq
|
||||
@helpers = helpers
|
||||
end
|
||||
|
||||
@@ -36,6 +37,24 @@ class CMockGeneratorUtils
|
||||
self.class.arg_type_with_const(arg)
|
||||
end
|
||||
|
||||
def self.arg_declaration(arg)
|
||||
if arg[:ptr_to_array?] && arg[:array_dims]
|
||||
base_type = arg_type_with_const(arg).sub(/\*$/, '').strip
|
||||
dims_str = arg[:array_dims].map { |d| "[#{d}]" }.join
|
||||
"#{base_type} (*#{arg[:name]})#{dims_str}"
|
||||
elsif arg[:array_dims]
|
||||
base_type = arg_type_with_const(arg).sub(/\*$/, '').strip
|
||||
dims_str = arg[:array_dims].map { |d| "[#{d}]" }.join
|
||||
"#{base_type} #{arg[:name]}#{dims_str}"
|
||||
else
|
||||
"#{arg_type_with_const(arg)} #{arg[:name]}"
|
||||
end
|
||||
end
|
||||
|
||||
def arg_declaration(arg)
|
||||
self.class.arg_declaration(arg)
|
||||
end
|
||||
|
||||
def code_verify_an_arg_expectation(function, arg)
|
||||
if @arrays
|
||||
case @ptr_handling
|
||||
@@ -64,7 +83,7 @@ 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 && depth.instance_of?(String)
|
||||
lines << " cmock_call_instance->Expected_#{arg[:name]}_Depth = #{depth};\n" if @arrays && depth.instance_of?(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 && ptr_or_str?(arg[:type]) && !(arg[:const?])
|
||||
lines
|
||||
@@ -72,7 +91,8 @@ class CMockGeneratorUtils
|
||||
|
||||
def code_assign_argument_quickly(dest, arg)
|
||||
if arg[:ptr?] || @treat_as.include?(arg[:type])
|
||||
" #{dest} = #{arg[:name]};\n"
|
||||
cast = arg[:array_dims] ? "(#{arg[:type]})" : ''
|
||||
" #{dest} = #{cast}#{arg[:name]};\n"
|
||||
else
|
||||
assert_expr = "sizeof(#{arg[:name]}) == sizeof(#{arg[:type]}) ? 1 : -1"
|
||||
comment = "/* add #{arg[:type]} to :treat_as_array if this causes an error */"
|
||||
@@ -85,12 +105,27 @@ class CMockGeneratorUtils
|
||||
if function[:args_string] != 'void'
|
||||
if @arrays
|
||||
args_string = function[:args].map do |m|
|
||||
type = arg_type_with_const(m)
|
||||
m[:ptr?] ? "#{type} #{m[:name]}, int #{m[:name]}_Depth" : "#{type} #{m[:name]}"
|
||||
if (m[:ptr?] || m[:string?]) && m[:array_size_order] == :before
|
||||
arg_declaration(m)
|
||||
elsif m[:ptr?] || m[:string?]
|
||||
"#{arg_declaration(m)}, int #{m[:name]}_Depth"
|
||||
else
|
||||
arg_declaration(m)
|
||||
end
|
||||
end.join(', ')
|
||||
body = function[:args].inject('') do |all, arg|
|
||||
depth = if (arg[:ptr?] || arg[:string?]) && arg[:array_size_order] == :before
|
||||
arg[:array_size_name]
|
||||
elsif arg[:ptr?] || arg[:string?]
|
||||
"#{arg[:name]}_Depth"
|
||||
else
|
||||
1
|
||||
end
|
||||
all + code_add_an_arg_expectation(arg, depth)
|
||||
end
|
||||
"void CMockExpectParameters_#{function[:name]}(CMOCK_#{function[:name]}_CALL_INSTANCE* cmock_call_instance, #{args_string});\n" \
|
||||
"void CMockExpectParameters_#{function[:name]}(CMOCK_#{function[:name]}_CALL_INSTANCE* cmock_call_instance, #{args_string})\n{\n" \
|
||||
"#{function[:args].inject('') { |all, arg| all + code_add_an_arg_expectation(arg, (arg[:ptr?] ? "#{arg[:name]}_Depth" : 1)) }}" \
|
||||
"#{body}" \
|
||||
"}\n\n"
|
||||
else
|
||||
"void CMockExpectParameters_#{function[:name]}(CMOCK_#{function[:name]}_CALL_INSTANCE* cmock_call_instance, #{function[:args_string]});\n" \
|
||||
@@ -106,10 +141,16 @@ class CMockGeneratorUtils
|
||||
def code_call_argument_loader(function)
|
||||
if function[:args_string] != 'void'
|
||||
args = function[:args].map do |m|
|
||||
if @arrays && m[:ptr?] && !(m[:array_data?])
|
||||
if @arrays && (m[:ptr?] || m[:string?]) && m[:array_size_order] == :after
|
||||
"#{m[:name]}, #{m[:array_size_name]}"
|
||||
elsif @arrays && (m[:ptr?] || m[:string?]) && m[:array_size_order] == :before
|
||||
m[:name]
|
||||
elsif @arrays && m[:ptr?]
|
||||
"#{m[:name]}, 1"
|
||||
elsif @arrays && m[:string?]
|
||||
"#{m[:name]}, 0"
|
||||
elsif @arrays && m[:array_size?]
|
||||
"#{m[:name]}, #{m[:name]}"
|
||||
m[:name]
|
||||
else
|
||||
m[:name]
|
||||
end
|
||||
@@ -132,16 +173,46 @@ class CMockGeneratorUtils
|
||||
arg_name = arg[:name]
|
||||
expected = "cmock_call_instance->Expected_#{arg_name}"
|
||||
ignore = "cmock_call_instance->IgnoreArg_#{arg_name}"
|
||||
# Pointer-to-array args (e.g., char (*buf)[N]) always compare by memory contents
|
||||
return [c_type, arg_name, expected, ignore, 'UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY', ''] if arg[:ptr_to_array?]
|
||||
|
||||
unity_func = if (arg[:ptr?]) && ((c_type =~ /\*\*/) || (@ptr_handling == :compare_ptr))
|
||||
['UNITY_TEST_ASSERT_EQUAL_PTR', '']
|
||||
elsif arg[:ptr?] && !@arrays && void_pointer_type?(c_type)
|
||||
# void* cannot be safely dereferenced; without the array plugin there's no way
|
||||
# to specify depth, so fall back to comparing the pointer value itself
|
||||
['UNITY_TEST_ASSERT_EQUAL_PTR', '']
|
||||
elsif arg[:ptr?] && @arrays && void_pointer_type?(c_type)
|
||||
# With the array plugin, treat_as_void aliases not in treat_as would fall back to
|
||||
# MEMORY_ARRAY with sizeof(void), which is illegal. Use HEX8_ARRAY (byte comparison)
|
||||
# to match what literal void* gets from the default treat_as entry.
|
||||
['UNITY_TEST_ASSERT_EQUAL_HEX8_ARRAY', '']
|
||||
else
|
||||
@helpers.nil? || @helpers[:unity_helper].nil? ? ['UNITY_TEST_ASSERT_EQUAL', ''] : @helpers[:unity_helper].get_helper(c_type)
|
||||
end
|
||||
[c_type, arg_name, expected, ignore, unity_func[0], unity_func[1]]
|
||||
end
|
||||
|
||||
def void_pointer_type?(c_type)
|
||||
base = c_type.gsub(/\bconst\b/, '').gsub(/\s+/, '')
|
||||
return false unless base.end_with?('*')
|
||||
|
||||
@treat_as_void.include?(base.chomp('*'))
|
||||
end
|
||||
|
||||
def ptr_to_array_elem_size(arg, c_type)
|
||||
# For pointer-to-array args (e.g., char (*buf)[10]), the element size is sizeof(base_type[dims])
|
||||
if arg[:ptr_to_array?] && arg[:array_dims]
|
||||
base_type = c_type.gsub(/\*+$/, '').strip
|
||||
"sizeof(#{base_type}#{arg[:array_dims].map { |d| "[#{d}]" }.join})"
|
||||
else
|
||||
"sizeof(#{c_type.sub('*', '')})"
|
||||
end
|
||||
end
|
||||
|
||||
def code_verify_an_arg_expectation_with_no_arrays(function, arg)
|
||||
c_type, arg_name, expected, ignore, unity_func, pre = lookup_expect_type(function, arg)
|
||||
elem_size = ptr_to_array_elem_size(arg, c_type)
|
||||
lines = ''
|
||||
lines << " if (!#{ignore})\n" if @ignore_arg
|
||||
lines << " {\n"
|
||||
@@ -152,12 +223,12 @@ class CMockGeneratorUtils
|
||||
lines << " UNITY_TEST_ASSERT_EQUAL_MEMORY(#{pre}#{expected}, #{pre}#{arg_name}, sizeof(#{c_type_local}), cmock_line, CMockStringMismatch);\n"
|
||||
when 'UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY'
|
||||
if pre == '&'
|
||||
lines << " UNITY_TEST_ASSERT_EQUAL_MEMORY(#{pre}#{expected}, #{pre}#{arg_name}, sizeof(#{c_type.sub('*', '')}), cmock_line, CMockStringMismatch);\n"
|
||||
lines << " UNITY_TEST_ASSERT_EQUAL_MEMORY(#{pre}#{expected}, #{pre}#{arg_name}, #{elem_size}, cmock_line, CMockStringMismatch);\n"
|
||||
else
|
||||
lines << " if (#{pre}#{expected} == NULL)\n"
|
||||
lines << " { UNITY_TEST_ASSERT_NULL(#{pre}#{arg_name}, cmock_line, CMockStringExpNULL); }\n"
|
||||
lines << " else\n"
|
||||
lines << " { UNITY_TEST_ASSERT_EQUAL_MEMORY(#{pre}#{expected}, #{pre}#{arg_name}, sizeof(#{c_type.sub('*', '')}), cmock_line, CMockStringMismatch); }\n"
|
||||
lines << " { UNITY_TEST_ASSERT_EQUAL_MEMORY(#{pre}#{expected}, #{pre}#{arg_name}, #{elem_size}, cmock_line, CMockStringMismatch); }\n"
|
||||
end
|
||||
when /_ARRAY/
|
||||
if pre == '&'
|
||||
@@ -177,7 +248,8 @@ class CMockGeneratorUtils
|
||||
|
||||
def code_verify_an_arg_expectation_with_normal_arrays(function, arg)
|
||||
c_type, arg_name, expected, ignore, unity_func, pre = lookup_expect_type(function, arg)
|
||||
depth_name = arg[:ptr?] ? "cmock_call_instance->Expected_#{arg_name}_Depth" : 1
|
||||
depth_name = arg[:ptr?] || arg[:string?] ? "cmock_call_instance->Expected_#{arg_name}_Depth" : 1
|
||||
elem_size = ptr_to_array_elem_size(arg, c_type)
|
||||
lines = ''
|
||||
lines << " if (!#{ignore})\n" if @ignore_arg
|
||||
lines << " {\n"
|
||||
@@ -188,12 +260,12 @@ class CMockGeneratorUtils
|
||||
lines << " UNITY_TEST_ASSERT_EQUAL_MEMORY(#{pre}#{expected}, #{pre}#{arg_name}, sizeof(#{c_type_local}), cmock_line, CMockStringMismatch);\n"
|
||||
when 'UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY'
|
||||
if pre == '&'
|
||||
lines << " UNITY_TEST_ASSERT_EQUAL_MEMORY(#{pre}#{expected}, #{pre}#{arg_name}, sizeof(#{c_type.sub('*', '')}), cmock_line, CMockStringMismatch);\n"
|
||||
lines << " UNITY_TEST_ASSERT_EQUAL_MEMORY(#{pre}#{expected}, #{pre}#{arg_name}, #{elem_size}, cmock_line, CMockStringMismatch);\n"
|
||||
else
|
||||
lines << " if (#{pre}#{expected} == NULL)\n"
|
||||
lines << " { UNITY_TEST_ASSERT_NULL(#{pre}#{arg_name}, cmock_line, CMockStringExpNULL); }\n"
|
||||
lines << " else\n"
|
||||
lines << " { UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY(#{pre}#{expected}, #{pre}#{arg_name}, sizeof(#{c_type.sub('*', '')}), #{depth_name}, cmock_line, CMockStringMismatch); }\n"
|
||||
lines << " { UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY(#{pre}#{expected}, #{pre}#{arg_name}, #{elem_size}, #{depth_name}, cmock_line, CMockStringMismatch); }\n"
|
||||
end
|
||||
when /_ARRAY/
|
||||
if pre == '&'
|
||||
@@ -205,7 +277,14 @@ class CMockGeneratorUtils
|
||||
lines << " { #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, #{depth_name}, cmock_line, CMockStringMismatch); }\n"
|
||||
end
|
||||
else
|
||||
lines << " #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, cmock_line, CMockStringMismatch);\n"
|
||||
if arg[:string?]
|
||||
lines << " if (#{depth_name} == 0)\n"
|
||||
lines << " { #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, cmock_line, CMockStringMismatch); }\n"
|
||||
lines << " else\n"
|
||||
lines << " { UNITY_TEST_ASSERT_EQUAL_MEMORY((const void*)(#{pre}#{expected}), (const void*)(#{pre}#{arg_name}), (UNITY_UINT32)(#{depth_name}), cmock_line, CMockStringMismatch); }\n"
|
||||
else
|
||||
lines << " #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, cmock_line, CMockStringMismatch);\n"
|
||||
end
|
||||
end
|
||||
lines << " }\n"
|
||||
lines
|
||||
@@ -213,7 +292,8 @@ class CMockGeneratorUtils
|
||||
|
||||
def code_verify_an_arg_expectation_with_smart_arrays(function, arg)
|
||||
c_type, arg_name, expected, ignore, unity_func, pre = lookup_expect_type(function, arg)
|
||||
depth_name = arg[:ptr?] ? "cmock_call_instance->Expected_#{arg_name}_Depth" : 1
|
||||
depth_name = arg[:ptr?] || arg[:string?] ? "cmock_call_instance->Expected_#{arg_name}_Depth" : 1
|
||||
elem_size = ptr_to_array_elem_size(arg, c_type)
|
||||
lines = ''
|
||||
lines << " if (!#{ignore})\n" if @ignore_arg
|
||||
lines << " {\n"
|
||||
@@ -224,13 +304,13 @@ class CMockGeneratorUtils
|
||||
lines << " UNITY_TEST_ASSERT_EQUAL_MEMORY(#{pre}#{expected}, #{pre}#{arg_name}, sizeof(#{c_type_local}), cmock_line, CMockStringMismatch);\n"
|
||||
when 'UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY'
|
||||
if pre == '&'
|
||||
lines << " UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY(#{pre}#{expected}, #{pre}#{arg_name}, sizeof(#{c_type.sub('*', '')}), #{depth_name}, cmock_line, CMockStringMismatch);\n"
|
||||
lines << " UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY(#{pre}#{expected}, #{pre}#{arg_name}, #{elem_size}, #{depth_name}, cmock_line, CMockStringMismatch);\n"
|
||||
else
|
||||
lines << " if (#{pre}#{expected} == NULL)\n"
|
||||
lines << " { UNITY_TEST_ASSERT_NULL(#{arg_name}, cmock_line, CMockStringExpNULL); }\n"
|
||||
lines << (depth_name != 1 ? " else if (#{depth_name} == 0)\n { UNITY_TEST_ASSERT_EQUAL_PTR(#{pre}#{expected}, #{pre}#{arg_name}, cmock_line, CMockStringMismatch); }\n" : '')
|
||||
lines << " else\n"
|
||||
lines << " { UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY(#{pre}#{expected}, #{pre}#{arg_name}, sizeof(#{c_type.sub('*', '')}), #{depth_name}, cmock_line, CMockStringMismatch); }\n"
|
||||
lines << " { UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY(#{pre}#{expected}, #{pre}#{arg_name}, #{elem_size}, #{depth_name}, cmock_line, CMockStringMismatch); }\n"
|
||||
end
|
||||
when /_ARRAY/
|
||||
if pre == '&'
|
||||
@@ -243,7 +323,14 @@ class CMockGeneratorUtils
|
||||
lines << " { #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, #{depth_name}, cmock_line, CMockStringMismatch); }\n"
|
||||
end
|
||||
else
|
||||
lines << " #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, cmock_line, CMockStringMismatch);\n"
|
||||
if arg[:string?]
|
||||
lines << " if (#{depth_name} == 0)\n"
|
||||
lines << " { #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, cmock_line, CMockStringMismatch); }\n"
|
||||
lines << " else\n"
|
||||
lines << " { UNITY_TEST_ASSERT_EQUAL_MEMORY((const void*)(#{pre}#{expected}), (const void*)(#{pre}#{arg_name}), (UNITY_UINT32)(#{depth_name}), cmock_line, CMockStringMismatch); }\n"
|
||||
else
|
||||
lines << " #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, cmock_line, CMockStringMismatch);\n"
|
||||
end
|
||||
end
|
||||
lines << " }\n"
|
||||
lines
|
||||
|
||||
+106
-11
@@ -408,7 +408,25 @@ class CMockHeaderParser
|
||||
arg_info
|
||||
end
|
||||
|
||||
def parse_args(arg_list)
|
||||
def extract_array_dims(arg_list)
|
||||
dims = {}
|
||||
arg_list.scan(/(\w+)\s*((?:\s*\[[^\[\]]*\])+)/) do |name, all_dims|
|
||||
dim_list = all_dims.scan(/\[([^\[\]]*)\]/).map { |d| d[0].strip }
|
||||
dims[name] = dim_list
|
||||
end
|
||||
dims
|
||||
end
|
||||
|
||||
def extract_ptr_to_array_dims(arg_list)
|
||||
dims = {}
|
||||
arg_list.scan(/\(\s*\*\s*(\w+)\s*\)((?:\s*\[[^\[\]]*\])+)/) do |name, all_dims|
|
||||
dim_list = all_dims.scan(/\[([^\[\]]*)\]/).map { |d| d[0].strip }
|
||||
dims[name] = dim_list
|
||||
end
|
||||
dims
|
||||
end
|
||||
|
||||
def parse_args(arg_list, array_dims_by_name = {}, ptr_to_array_dims_by_name = {})
|
||||
args = []
|
||||
arg_list.split(',').each do |arg|
|
||||
arg.strip!
|
||||
@@ -418,6 +436,15 @@ class CMockHeaderParser
|
||||
arg_info.delete(:modifier) # don't care about this
|
||||
arg_info.delete(:c_calling_convention) # don't care about this
|
||||
|
||||
arg_info[:array_dims] = array_dims_by_name[arg_info[:name]] if array_dims_by_name.key?(arg_info[:name])
|
||||
|
||||
# Handle pointer-to-array args: (*name)[dims] was rewritten to * name before clean_args
|
||||
if ptr_to_array_dims_by_name.key?(arg_info[:name])
|
||||
arg_info[:array_dims] = ptr_to_array_dims_by_name[arg_info[:name]]
|
||||
arg_info[:ptr_to_array?] = true
|
||||
arg_info[:ptr?] = true # force true even for types like char* that divine_ptr would otherwise treat as strings
|
||||
end
|
||||
|
||||
# in C, array arguments implicitly degrade to pointers
|
||||
# make the translation explicit here to simplify later logic
|
||||
if @treat_as_array[arg_info[:type]] && !(arg_info[:ptr?])
|
||||
@@ -429,20 +456,61 @@ class CMockHeaderParser
|
||||
args << arg_info
|
||||
end
|
||||
|
||||
# Try to find array pair in parameters following this pattern : <type> * <name>, <@array_size_type> <@array_size_name>
|
||||
args.each_with_index do |val, index|
|
||||
next_index = index + 1
|
||||
next unless args.length > next_index
|
||||
# Try to find array pairs using name-affinity scoring.
|
||||
# Pairs each size-candidate arg with the best-matching pointer arg.
|
||||
# Score: 10=exact root match, 7=prefix match, 5=substring match, +2 adjacency bonus (ptr immediately precedes size).
|
||||
# Falls back to adjacency alone (score 2) when no name affinity found, preserving original behavior.
|
||||
size_candidate_indices = args.each_index.select do |i|
|
||||
args[i][:name].match(@array_size_name) && @array_size_type.include?(args[i][:type])
|
||||
end
|
||||
|
||||
if (val[:ptr?] == true) && args[next_index][:name].match(@array_size_name) && @array_size_type.include?(args[next_index][:type])
|
||||
val[:array_data?] = true
|
||||
args[next_index][:array_size?] = true
|
||||
size_candidate_indices.each do |size_idx|
|
||||
best_score = 0
|
||||
best_ptr_idx = nil
|
||||
|
||||
args.each_with_index do |ptr_arg, ptr_idx|
|
||||
next unless (ptr_arg[:ptr?] || ptr_arg[:string?]) && !ptr_arg[:array_data?]
|
||||
|
||||
score = array_size_name_affinity(ptr_arg[:name], args[size_idx][:name])
|
||||
score += 2 if ptr_idx + 1 == size_idx
|
||||
|
||||
if score > best_score
|
||||
best_score = score
|
||||
best_ptr_idx = ptr_idx
|
||||
end
|
||||
end
|
||||
|
||||
next unless best_ptr_idx
|
||||
|
||||
args[best_ptr_idx][:array_size_name] = args[size_idx][:name]
|
||||
args[best_ptr_idx][:array_size_order] = size_idx < best_ptr_idx ? :before : :after
|
||||
args[size_idx][:array_size?] = true
|
||||
end
|
||||
|
||||
args
|
||||
end
|
||||
|
||||
def array_size_name_affinity(ptr_name, size_name)
|
||||
size_words = @array_size_name.to_s.split('|').select { |w| w.match?(/^\w+$/) }
|
||||
p_name = ptr_name.downcase
|
||||
s_name = size_name.downcase
|
||||
|
||||
roots = size_words.flat_map do |word|
|
||||
[
|
||||
s_name.sub(/_#{Regexp.escape(word)}$/, ''),
|
||||
s_name.sub(/^#{Regexp.escape(word)}_/, '')
|
||||
]
|
||||
end.uniq.reject { |r| r.empty? || r == s_name }
|
||||
|
||||
roots.each do |root|
|
||||
return 10 if root == p_name
|
||||
return 7 if p_name.start_with?(root) || root.start_with?(p_name)
|
||||
return 5 if p_name.include?(root) || root.include?(p_name)
|
||||
end
|
||||
|
||||
0
|
||||
end
|
||||
|
||||
def divine_ptr(arg)
|
||||
return false unless arg.include? '*'
|
||||
# treat "const char *" and similar as a string, not a pointer
|
||||
@@ -465,6 +533,7 @@ class CMockHeaderParser
|
||||
divination = {}
|
||||
|
||||
divination[:ptr?] = divine_ptr(arg)
|
||||
divination[:string?] = !divination[:ptr?] && (/(^|\s)(const\s+)?char(\s+const)?\s*\*(?!.*\*)/ =~ arg ? true : false)
|
||||
divination[:const?] = divine_const(arg)
|
||||
|
||||
# an arg containing "const" after the last * is a constant pointer
|
||||
@@ -591,12 +660,38 @@ class CMockHeaderParser
|
||||
decl[:var_arg] = nil
|
||||
end
|
||||
|
||||
# Extract pointer-to-array parameters (e.g., char (*buffer)[10]) and rewrite for normal processing
|
||||
ptr_to_array_dims = extract_ptr_to_array_dims(args)
|
||||
ptr_to_array_dims.each_key do |name|
|
||||
args.gsub!(/\(\s*\*\s*#{Regexp.escape(name)}\s*\)((?:\s*\[[^\[\]]*\])+)/, "* #{name}")
|
||||
end
|
||||
|
||||
# Extract array dimensions before cleaning converts them to pointer notation
|
||||
array_dims_by_name = extract_array_dims(args)
|
||||
|
||||
# parse out and clean up the remainder of the arguments
|
||||
args = clean_args(args, parse_project)
|
||||
decl[:args_string] = args
|
||||
decl[:args] = parse_args(args)
|
||||
decl[:args] = parse_args(args, array_dims_by_name, ptr_to_array_dims)
|
||||
# Rebuild args_string using original array notation where applicable
|
||||
if args == 'void'
|
||||
decl[:args_string] = args
|
||||
else
|
||||
arg_parts = args.split(/,\s*/)
|
||||
decl[:args].each_with_index do |arg, i|
|
||||
next unless arg[:array_dims]
|
||||
|
||||
base_type = arg[:type].sub(/\*$/, '').strip
|
||||
dims_str = arg[:array_dims].map { |d| "[#{d}]" }.join
|
||||
arg_parts[i] = if arg[:ptr_to_array?]
|
||||
"#{base_type} (*#{arg[:name]})#{dims_str}"
|
||||
else
|
||||
"#{base_type} #{arg[:name]}#{dims_str}"
|
||||
end
|
||||
end
|
||||
decl[:args_string] = arg_parts.join(', ')
|
||||
end
|
||||
decl[:args_call] = decl[:args].map { |a| a[:name] }.join(', ')
|
||||
decl[:contains_ptr?] = decl[:args].inject(false) { |ptr, arg| arg[:ptr?] ? true : ptr }
|
||||
decl[:contains_ptr?] = decl[:args].inject(false) { |ptr, arg| arg[:ptr?] || arg[:string?] ? true : ptr }
|
||||
|
||||
if decl[:return][:type].nil? || decl[:name].nil? || decl[:args].nil? ||
|
||||
decl[:return][:type].empty? || decl[:name].empty?
|
||||
|
||||
@@ -16,7 +16,12 @@ class CMockUnityHelperParser
|
||||
|
||||
def get_helper(ctype)
|
||||
lookup = ctype.gsub(/(?:^|(\S?)(\s*)|(\W))const(?:$|(\s*)(\S)|(\W))/, '\1\3\5\6').strip.gsub(/\s+/, '_')
|
||||
return [@c_types[lookup], ''] if @c_types[lookup]
|
||||
if @c_types[lookup]
|
||||
# _ARRAY_ARRAY variants don't exist in Unity; use memory fallback instead
|
||||
return [@fallback, ''] if @c_types[lookup].end_with?('_ARRAY_ARRAY')
|
||||
|
||||
return [@c_types[lookup], '']
|
||||
end
|
||||
|
||||
if lookup =~ /\*$/
|
||||
lookup = lookup.gsub(/\*$/, '')
|
||||
|
||||
+1
-1
@@ -12,7 +12,7 @@
|
||||
|
||||
#define CMOCK_VERSION_MAJOR 2
|
||||
#define CMOCK_VERSION_MINOR 6
|
||||
#define CMOCK_VERSION_BUILD 3
|
||||
#define CMOCK_VERSION_BUILD 4
|
||||
#define CMOCK_VERSION ((CMOCK_VERSION_MAJOR << 16) | (CMOCK_VERSION_MINOR << 8) | CMOCK_VERSION_BUILD)
|
||||
|
||||
/* should be big enough to index full range of CMOCK_MEM_MAX */
|
||||
|
||||
@@ -44,6 +44,7 @@ module RakefileHelpers
|
||||
|
||||
def load_configuration(config_file, cmock_overlay = nil)
|
||||
$cfg_file = config_file
|
||||
cmock_overlay += '.yml' if cmock_overlay && cmock_overlay !~ /\.yml$/i
|
||||
$proj = load_yaml('./project.yml')
|
||||
|
||||
unity_targets_dir = '../vendor/unity/test/targets'
|
||||
@@ -89,7 +90,6 @@ module RakefileHelpers
|
||||
def configure_toolchain(config_file = DEFAULT_CONFIG_FILE, cmock_overlay = nil)
|
||||
config_file = config_file || DEFAULT_CONFIG_FILE
|
||||
config_file += '.yml' unless config_file =~ /\.yml$/i
|
||||
cmock_overlay += '.yml' if cmock_overlay && cmock_overlay !~ /\.yml$/i
|
||||
load_configuration(config_file, cmock_overlay)
|
||||
configure_clean
|
||||
end
|
||||
@@ -154,8 +154,7 @@ module RakefileHelpers
|
||||
|
||||
def unsupported_tests
|
||||
result = ($cmock_cfg[:unsupported] || []) | ($unity_cfg[:unsupported] || [])
|
||||
test_defs = $unity_cfg.dig(:defines, :test)
|
||||
conf_defs = (test_defs.is_a?(Hash) ? test_defs['*'] : nil) || test_defs || []
|
||||
conf_defs = all_defines
|
||||
UNSUPPORTED_CRITERIA.each_pair do |name, crit|
|
||||
result |= [name] if (crit[:defines] & conf_defs).empty?
|
||||
end
|
||||
@@ -343,7 +342,7 @@ module RakefileHelpers
|
||||
|
||||
SystemTestGenerator.new.generate_files(test_case_files)
|
||||
|
||||
load_configuration($cfg_file)
|
||||
load_configuration($cfg_file, $cmock_test_overlay_file)
|
||||
|
||||
include_dirs = get_local_include_dirs
|
||||
|
||||
@@ -481,7 +480,7 @@ module RakefileHelpers
|
||||
|
||||
def run_system_test_compilations(mockables)
|
||||
load '../lib/cmock.rb'
|
||||
load_configuration($cfg_file)
|
||||
load_configuration($cfg_file, $cmock_test_overlay_file)
|
||||
|
||||
unsupported = unsupported_tests
|
||||
mockables = mockables.reject do |f|
|
||||
@@ -510,7 +509,7 @@ module RakefileHelpers
|
||||
|
||||
def run_system_test_profiles(mockables)
|
||||
load '../lib/cmock.rb'
|
||||
load_configuration($cfg_file)
|
||||
load_configuration($cfg_file, $cmock_test_overlay_file)
|
||||
|
||||
report "\n"
|
||||
report "--------------------------\n"
|
||||
@@ -561,7 +560,6 @@ module RakefileHelpers
|
||||
total_tests = 0
|
||||
total_failures = 0
|
||||
total_ignored = 0
|
||||
puts "DEBUG DIS #{$cmock_test_config_file}"
|
||||
cfg_file = "#{($cmock_test_config_file =~ /[\\\/]/) ? '../' : ''}#{$cmock_test_config_file}"
|
||||
|
||||
# Determine which examples are valid for this platform
|
||||
|
||||
@@ -0,0 +1,758 @@
|
||||
# =========================================================================
|
||||
# CMock - Automatic Mock Generation for C
|
||||
# ThrowTheSwitch.org
|
||||
# Copyright (c) 2007-26 Mike Karlesky, Mark VanderVoord, & Greg Williams
|
||||
# SPDX-License-Identifier: MIT
|
||||
# =========================================================================
|
||||
|
||||
---
|
||||
:cmock:
|
||||
:when_ptr: :smart
|
||||
:array_size_name: 'size|len|count'
|
||||
:plugins:
|
||||
- :array
|
||||
|
||||
:systest:
|
||||
:types: |
|
||||
typedef struct {
|
||||
int x;
|
||||
int y;
|
||||
} POINT_T;
|
||||
|
||||
typedef struct {
|
||||
int id;
|
||||
int value;
|
||||
} SENSOR_T;
|
||||
|
||||
typedef enum {
|
||||
STATUS_OK = 0,
|
||||
STATUS_ERROR = 1,
|
||||
STATUS_PENDING = 2
|
||||
} STATUS_E;
|
||||
|
||||
typedef union {
|
||||
int raw;
|
||||
unsigned char bytes[4];
|
||||
} SAMPLE_U;
|
||||
|
||||
#define ARRAY_A_SIZE (5)
|
||||
|
||||
:mockable: |
|
||||
POINT_T* bar(void);
|
||||
void fooa(POINT_T a[ARRAY_A_SIZE]);
|
||||
void no_pointers(int a, const char* b);
|
||||
int mixed(int a, int* b, int c);
|
||||
void process_sensors(SENSOR_T sensors[], int count);
|
||||
void process_statuses(STATUS_E statuses[], int count);
|
||||
void process_samples(SAMPLE_U samples[], int count);
|
||||
void fill_matrix(int matrix[13][4]);
|
||||
void transform_grid(int grid[][4], int rows);
|
||||
void write_buffer(char (*dest)[10]);
|
||||
void read_buffers(int count, char (*buffers)[8]);
|
||||
void process_handles(void *const handles[], int count);
|
||||
void store_data(int *written_count, int buf_size, int *buf);
|
||||
|
||||
:source:
|
||||
:header: |
|
||||
void function_a(void);
|
||||
int function_b(void);
|
||||
void function_c(void);
|
||||
void function_d(void);
|
||||
void function_e(void);
|
||||
void function_f(void);
|
||||
void function_g(void);
|
||||
void function_h(void);
|
||||
void function_i(void);
|
||||
void function_j(void);
|
||||
void function_k(void);
|
||||
|
||||
:code: |
|
||||
void function_a(void)
|
||||
{
|
||||
fooa(bar());
|
||||
}
|
||||
|
||||
int function_b(void)
|
||||
{
|
||||
int test_list[] = {1, 2, 3, 4, 5};
|
||||
no_pointers(1, "silly");
|
||||
return mixed(6, test_list, 7);
|
||||
}
|
||||
|
||||
void function_c(void)
|
||||
{
|
||||
SENSOR_T sensors[] = {{1, 100}, {2, 200}, {3, 300}};
|
||||
process_sensors(sensors, 3);
|
||||
}
|
||||
|
||||
void function_d(void)
|
||||
{
|
||||
STATUS_E statuses[] = {STATUS_OK, STATUS_ERROR, STATUS_PENDING};
|
||||
process_statuses(statuses, 3);
|
||||
}
|
||||
|
||||
void function_e(void)
|
||||
{
|
||||
SAMPLE_U samples[3];
|
||||
samples[0].raw = 111;
|
||||
samples[1].raw = 222;
|
||||
samples[2].raw = 333;
|
||||
process_samples(samples, 3);
|
||||
}
|
||||
|
||||
void function_f(void)
|
||||
{
|
||||
int matrix[13][4];
|
||||
int i, j;
|
||||
for (i = 0; i < 13; i++)
|
||||
for (j = 0; j < 4; j++)
|
||||
matrix[i][j] = i * 4 + j;
|
||||
fill_matrix(matrix);
|
||||
}
|
||||
|
||||
void function_g(void)
|
||||
{
|
||||
int grid[3][4] = {{1,2,3,4},{5,6,7,8},{9,10,11,12}};
|
||||
transform_grid(grid, 3);
|
||||
}
|
||||
|
||||
void function_h(void)
|
||||
{
|
||||
char buf[10] = {1,2,3,4,5,6,7,8,9,10};
|
||||
write_buffer(&buf);
|
||||
}
|
||||
|
||||
void function_i(void)
|
||||
{
|
||||
char bufs[3][8];
|
||||
int i, j;
|
||||
for (i = 0; i < 3; i++)
|
||||
for (j = 0; j < 8; j++)
|
||||
bufs[i][j] = (char)(i * 8 + j + 1);
|
||||
read_buffers((int)3, bufs);
|
||||
}
|
||||
|
||||
void function_j(void)
|
||||
{
|
||||
void *const ptrs[] = {(void*)1, (void*)2, (void*)3};
|
||||
process_handles(ptrs, 3);
|
||||
}
|
||||
|
||||
void function_k(void)
|
||||
{
|
||||
int count = 0;
|
||||
int data[] = {10, 20, 30};
|
||||
store_data(&count, 3, data);
|
||||
}
|
||||
|
||||
:tests:
|
||||
:common: |
|
||||
void setUp(void) {}
|
||||
void tearDown(void) {}
|
||||
|
||||
:units:
|
||||
- :pass: TRUE
|
||||
:should: 'handle passing null to an array parameter'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
bar_ExpectAndReturn(NULL);
|
||||
fooa_Expect(NULL);
|
||||
|
||||
function_a();
|
||||
}
|
||||
|
||||
- :pass: TRUE
|
||||
:should: 'compare a single struct array element and pass'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
POINT_T pt = {4, 8};
|
||||
POINT_T ex = {4, 8};
|
||||
bar_ExpectAndReturn(&pt);
|
||||
fooa_Expect(&ex);
|
||||
|
||||
function_a();
|
||||
}
|
||||
|
||||
- :pass: FALSE
|
||||
:should: 'detect mismatch in single struct array element'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
POINT_T pt = {4, 8};
|
||||
POINT_T ex = {4, 9};
|
||||
bar_ExpectAndReturn(&pt);
|
||||
fooa_Expect(&ex);
|
||||
|
||||
function_a();
|
||||
}
|
||||
|
||||
- :pass: FALSE
|
||||
:should: 'detect when null array is passed but non-null was expected'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
POINT_T pt = {4, 8};
|
||||
bar_ExpectAndReturn(&pt);
|
||||
fooa_Expect(NULL);
|
||||
|
||||
function_a();
|
||||
}
|
||||
|
||||
- :pass: TRUE
|
||||
:should: 'compare multiple struct array elements via ExpectWithArray and pass'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
POINT_T pt[] = {{1, 2}, {3, 4}, {5, 6}};
|
||||
POINT_T ex[] = {{1, 2}, {3, 4}, {5, 6}};
|
||||
bar_ExpectAndReturn(pt);
|
||||
fooa_ExpectWithArray(ex, 3);
|
||||
|
||||
function_a();
|
||||
}
|
||||
|
||||
- :pass: FALSE
|
||||
:should: 'detect mismatch in first struct array element via ExpectWithArray'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
POINT_T pt[] = {{1, 2}, {3, 4}, {5, 6}};
|
||||
POINT_T ex[] = {{9, 2}, {3, 4}, {5, 6}};
|
||||
bar_ExpectAndReturn(pt);
|
||||
fooa_ExpectWithArray(ex, 3);
|
||||
|
||||
function_a();
|
||||
}
|
||||
|
||||
- :pass: FALSE
|
||||
:should: 'detect mismatch in middle struct array element via ExpectWithArray'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
POINT_T pt[] = {{1, 2}, {3, 4}, {5, 6}};
|
||||
POINT_T ex[] = {{1, 2}, {3, 9}, {5, 6}};
|
||||
bar_ExpectAndReturn(pt);
|
||||
fooa_ExpectWithArray(ex, 3);
|
||||
|
||||
function_a();
|
||||
}
|
||||
|
||||
- :pass: FALSE
|
||||
:should: 'detect mismatch in last struct array element via ExpectWithArray'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
POINT_T pt[] = {{1, 2}, {3, 4}, {5, 6}};
|
||||
POINT_T ex[] = {{1, 2}, {3, 4}, {5, 9}};
|
||||
bar_ExpectAndReturn(pt);
|
||||
fooa_ExpectWithArray(ex, 3);
|
||||
|
||||
function_a();
|
||||
}
|
||||
|
||||
- :pass: TRUE
|
||||
:should: 'handle creating int array expects for mixed-argument function and pass'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
int expect_list[] = {1, 9};
|
||||
no_pointers_Expect(1, "silly");
|
||||
mixed_ExpectAndReturn(6, expect_list, 7, 13);
|
||||
|
||||
TEST_ASSERT_EQUAL(13, function_b());
|
||||
}
|
||||
|
||||
- :pass: FALSE
|
||||
:should: 'detect mismatch in int array for mixed-argument function'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
int expect_list[] = {9, 1};
|
||||
no_pointers_Expect(1, "silly");
|
||||
mixed_ExpectAndReturn(6, expect_list, 7, 13);
|
||||
|
||||
TEST_ASSERT_EQUAL(13, function_b());
|
||||
}
|
||||
|
||||
- :pass: TRUE
|
||||
:should: 'compare multiple int array elements for mixed-argument function and pass'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
int expect_list[] = {1, 2, 3, 4, 6};
|
||||
no_pointers_Expect(1, "silly");
|
||||
mixed_ExpectWithArrayAndReturn(6, expect_list, 4, 7, 13);
|
||||
|
||||
TEST_ASSERT_EQUAL(13, function_b());
|
||||
}
|
||||
|
||||
- :pass: FALSE
|
||||
:should: 'detect mismatch when checking too many int array elements'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
int expect_list[] = {1, 2, 3, 4, 6};
|
||||
no_pointers_Expect(1, "silly");
|
||||
mixed_ExpectWithArrayAndReturn(6, expect_list, 5, 7, 13);
|
||||
|
||||
TEST_ASSERT_EQUAL(13, function_b());
|
||||
}
|
||||
|
||||
- :pass: TRUE
|
||||
:should: 'compare an array of sensors (struct) and pass'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
SENSOR_T expected[] = {{1, 100}, {2, 200}, {3, 300}};
|
||||
process_sensors_Expect(expected, 3);
|
||||
|
||||
function_c();
|
||||
}
|
||||
|
||||
- :pass: FALSE
|
||||
:should: 'detect mismatch in sensor id field'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
SENSOR_T expected[] = {{9, 100}, {2, 200}, {3, 300}};
|
||||
process_sensors_Expect(expected, 3);
|
||||
|
||||
function_c();
|
||||
}
|
||||
|
||||
- :pass: FALSE
|
||||
:should: 'detect mismatch in sensor value field'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
SENSOR_T expected[] = {{1, 100}, {2, 999}, {3, 300}};
|
||||
process_sensors_Expect(expected, 3);
|
||||
|
||||
function_c();
|
||||
}
|
||||
|
||||
- :pass: TRUE
|
||||
:should: 'compare all sensor elements via collapsed ExpectWithArray and pass'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
SENSOR_T expected[] = {{1, 100}, {2, 200}, {3, 300}};
|
||||
process_sensors_ExpectWithArray(expected, 3);
|
||||
|
||||
function_c();
|
||||
}
|
||||
|
||||
- :pass: TRUE
|
||||
:should: 'compare a subset of sensor elements via ExpectWithArrayExtended and pass'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
SENSOR_T expected[] = {{1, 100}, {2, 200}};
|
||||
process_sensors_ExpectWithArrayExtended(expected, 2, 3);
|
||||
|
||||
function_c();
|
||||
}
|
||||
|
||||
- :pass: FALSE
|
||||
:should: 'detect mismatch when comparing sensor subset via ExpectWithArrayExtended'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
SENSOR_T expected[] = {{1, 100}, {2, 999}};
|
||||
process_sensors_ExpectWithArrayExtended(expected, 2, 3);
|
||||
|
||||
function_c();
|
||||
}
|
||||
|
||||
- :pass: TRUE
|
||||
:should: 'compare an array of statuses (enum) and pass'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
STATUS_E expected[] = {STATUS_OK, STATUS_ERROR, STATUS_PENDING};
|
||||
process_statuses_Expect(expected, 3);
|
||||
|
||||
function_d();
|
||||
}
|
||||
|
||||
- :pass: FALSE
|
||||
:should: 'detect mismatch in first status enum element'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
STATUS_E expected[] = {STATUS_ERROR, STATUS_ERROR, STATUS_PENDING};
|
||||
process_statuses_Expect(expected, 3);
|
||||
|
||||
function_d();
|
||||
}
|
||||
|
||||
- :pass: FALSE
|
||||
:should: 'detect mismatch in last status enum element'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
STATUS_E expected[] = {STATUS_OK, STATUS_ERROR, STATUS_OK};
|
||||
process_statuses_Expect(expected, 3);
|
||||
|
||||
function_d();
|
||||
}
|
||||
|
||||
- :pass: TRUE
|
||||
:should: 'compare a subset of status elements via ExpectWithArrayExtended and pass'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
STATUS_E expected[] = {STATUS_OK, STATUS_ERROR};
|
||||
process_statuses_ExpectWithArrayExtended(expected, 2, 3);
|
||||
|
||||
function_d();
|
||||
}
|
||||
|
||||
- :pass: FALSE
|
||||
:should: 'detect mismatch in status subset via ExpectWithArrayExtended'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
STATUS_E expected[] = {STATUS_OK, STATUS_PENDING};
|
||||
process_statuses_ExpectWithArrayExtended(expected, 2, 3);
|
||||
|
||||
function_d();
|
||||
}
|
||||
|
||||
- :pass: TRUE
|
||||
:should: 'compare an array of samples (union) and pass'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
SAMPLE_U expected[3];
|
||||
expected[0].raw = 111;
|
||||
expected[1].raw = 222;
|
||||
expected[2].raw = 333;
|
||||
process_samples_Expect(expected, 3);
|
||||
|
||||
function_e();
|
||||
}
|
||||
|
||||
- :pass: FALSE
|
||||
:should: 'detect mismatch in first sample union element'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
SAMPLE_U expected[3];
|
||||
expected[0].raw = 999;
|
||||
expected[1].raw = 222;
|
||||
expected[2].raw = 333;
|
||||
process_samples_Expect(expected, 3);
|
||||
|
||||
function_e();
|
||||
}
|
||||
|
||||
- :pass: FALSE
|
||||
:should: 'detect mismatch in last sample union element'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
SAMPLE_U expected[3];
|
||||
expected[0].raw = 111;
|
||||
expected[1].raw = 222;
|
||||
expected[2].raw = 999;
|
||||
process_samples_Expect(expected, 3);
|
||||
|
||||
function_e();
|
||||
}
|
||||
|
||||
- :pass: TRUE
|
||||
:should: 'compare a subset of sample elements via ExpectWithArrayExtended and pass'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
SAMPLE_U expected[3];
|
||||
expected[0].raw = 111;
|
||||
expected[1].raw = 222;
|
||||
process_samples_ExpectWithArrayExtended(expected, 2, 3);
|
||||
|
||||
function_e();
|
||||
}
|
||||
|
||||
- :pass: FALSE
|
||||
:should: 'detect mismatch in sample subset via ExpectWithArrayExtended'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
SAMPLE_U expected[3];
|
||||
expected[0].raw = 111;
|
||||
expected[1].raw = 999;
|
||||
process_samples_ExpectWithArrayExtended(expected, 2, 3);
|
||||
|
||||
function_e();
|
||||
}
|
||||
|
||||
- :pass: TRUE
|
||||
:should: 'compare a fully-specified 2D matrix [13][4] and pass'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
int expected[13][4];
|
||||
int i, j;
|
||||
for (i = 0; i < 13; i++)
|
||||
for (j = 0; j < 4; j++)
|
||||
expected[i][j] = i * 4 + j;
|
||||
fill_matrix_ExpectWithArray(expected, 13*4);
|
||||
|
||||
function_f();
|
||||
}
|
||||
|
||||
- :pass: FALSE
|
||||
:should: 'detect mismatch in a fully-specified 2D matrix [13][4]'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
int expected[13][4];
|
||||
int i, j;
|
||||
for (i = 0; i < 13; i++)
|
||||
for (j = 0; j < 4; j++)
|
||||
expected[i][j] = i * 4 + j;
|
||||
expected[6][2] = 999;
|
||||
fill_matrix_ExpectWithArray(expected, 13*4);
|
||||
|
||||
function_f();
|
||||
}
|
||||
|
||||
- :pass: TRUE
|
||||
:should: 'compare only the first row of a fully-specified 2D matrix [13][4]'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
int expected[13][4] = {{0,1,2,3}};
|
||||
fill_matrix_ExpectWithArray(expected, 4);
|
||||
|
||||
function_f();
|
||||
}
|
||||
|
||||
- :pass: TRUE
|
||||
:should: 'compare a partially-specified 2D grid [][4] and pass'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
int expected[3][4] = {{1,2,3,4},{5,6,7,8},{9,10,11,12}};
|
||||
transform_grid_ExpectWithArray(expected, 3*4, 3);
|
||||
|
||||
function_g();
|
||||
}
|
||||
|
||||
- :pass: FALSE
|
||||
:should: 'detect mismatch in a partially-specified 2D grid [][4]'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
int expected[3][4] = {{1,2,3,4},{5,6,7,99},{9,10,11,12}};
|
||||
transform_grid_ExpectWithArray(expected, 3*4, 3);
|
||||
|
||||
function_g();
|
||||
}
|
||||
|
||||
- :pass: TRUE
|
||||
:should: 'compare only the first two rows of a partially-specified 2D grid [][4]'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
int expected[3][4] = {{1,2,3,4},{5,6,7,8}};
|
||||
transform_grid_ExpectWithArray(expected, 2*4, 3);
|
||||
|
||||
function_g();
|
||||
}
|
||||
|
||||
- :pass: TRUE
|
||||
:should: 'pass when pointer-to-array argument contents match'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
char expected[10] = {1,2,3,4,5,6,7,8,9,10};
|
||||
write_buffer_Expect(&expected);
|
||||
|
||||
function_h();
|
||||
}
|
||||
|
||||
- :pass: FALSE
|
||||
:should: 'detect mismatch in pointer-to-array argument contents'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
char expected[10] = {1,2,3,4,5,6,7,8,9,99};
|
||||
write_buffer_Expect(&expected);
|
||||
|
||||
function_h();
|
||||
}
|
||||
|
||||
- :pass: TRUE
|
||||
:should: 'pass when passing null to pointer-to-array parameter'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
write_buffer_Expect(NULL);
|
||||
write_buffer(NULL);
|
||||
}
|
||||
|
||||
- :pass: TRUE
|
||||
:should: 'compare multiple pointer-to-array elements via ExpectWithArray and pass'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
char expected[3][8];
|
||||
int i, j;
|
||||
for (i = 0; i < 3; i++)
|
||||
for (j = 0; j < 8; j++)
|
||||
expected[i][j] = (char)(i * 8 + j + 1);
|
||||
read_buffers_ExpectWithArray(3, expected, 3);
|
||||
|
||||
function_i();
|
||||
}
|
||||
|
||||
- :pass: FALSE
|
||||
:should: 'detect mismatch when comparing multiple pointer-to-array elements'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
char expected[3][8];
|
||||
int i, j;
|
||||
for (i = 0; i < 3; i++)
|
||||
for (j = 0; j < 8; j++)
|
||||
expected[i][j] = (char)(i * 8 + j + 1);
|
||||
expected[1][3] = 99;
|
||||
read_buffers_ExpectWithArray(3, expected, 3);
|
||||
|
||||
function_i();
|
||||
}
|
||||
|
||||
- :pass: TRUE
|
||||
:should: 'pass when array of const void pointers matches expected'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
void *const expected[] = {(void*)1, (void*)2, (void*)3};
|
||||
process_handles_Expect(expected, 3);
|
||||
|
||||
function_j();
|
||||
}
|
||||
|
||||
- :pass: FALSE
|
||||
:should: 'detect mismatch in array of const void pointers'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
void *const expected[] = {(void*)1, (void*)2, (void*)9};
|
||||
process_handles_Expect(expected, 3);
|
||||
|
||||
function_j();
|
||||
}
|
||||
|
||||
- :pass: TRUE
|
||||
:should: 'pass when comparing subset of const void pointer array via ExpectWithArrayExtended'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
void *const expected[] = {(void*)1, (void*)2};
|
||||
process_handles_ExpectWithArrayExtended(expected, 2, 3);
|
||||
|
||||
function_j();
|
||||
}
|
||||
|
||||
- :pass: TRUE
|
||||
:should: 'pair buf_size with buf not written_count, and pass'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
int exp_count = 0;
|
||||
int exp_data[] = {10, 20, 30};
|
||||
store_data_Expect(&exp_count, 3, exp_data);
|
||||
|
||||
function_k();
|
||||
}
|
||||
|
||||
- :pass: FALSE
|
||||
:should: 'detect mismatch in buf array when buf_size is correctly paired with buf'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
int exp_count = 0;
|
||||
int exp_data[] = {10, 20, 99};
|
||||
store_data_Expect(&exp_count, 3, exp_data);
|
||||
|
||||
function_k();
|
||||
}
|
||||
|
||||
- :pass: TRUE
|
||||
:should: 'use ExpectWithArray with length before pointer order'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
int exp_count = 0;
|
||||
int exp_data[] = {10, 20, 30};
|
||||
store_data_ExpectWithArray(&exp_count, 1, 3, exp_data);
|
||||
|
||||
function_k();
|
||||
}
|
||||
|
||||
- :pass: FALSE
|
||||
:should: 'detect content mismatch in buf via ExpectWithArray'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
int exp_count = 0;
|
||||
int exp_data[] = {10, 99, 30};
|
||||
store_data_ExpectWithArray(&exp_count, 1, 3, exp_data);
|
||||
|
||||
function_k();
|
||||
}
|
||||
|
||||
- :pass: TRUE
|
||||
:should: 'pass using ExpectWithArrayExtended with explicit depth matching buf_size'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
int exp_count = 0;
|
||||
int exp_data[] = {10, 20, 30};
|
||||
store_data_ExpectWithArrayExtended(&exp_count, 1, 3, exp_data, 3);
|
||||
|
||||
function_k();
|
||||
}
|
||||
|
||||
- :pass: FALSE
|
||||
:should: 'detect content mismatch in buf via ExpectWithArrayExtended'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
int exp_count = 0;
|
||||
int exp_data[] = {10, 99, 30};
|
||||
store_data_ExpectWithArrayExtended(&exp_count, 1, 3, exp_data, 3);
|
||||
|
||||
function_k();
|
||||
}
|
||||
|
||||
- :pass: TRUE
|
||||
:should: 'pass using ExpectWithArrayExtended with depth override that skips mismatched last element'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
int exp_count = 0;
|
||||
int exp_data[] = {10, 20, 99};
|
||||
store_data_ExpectWithArrayExtended(&exp_count, 1, 3, exp_data, 2);
|
||||
|
||||
function_k();
|
||||
}
|
||||
|
||||
- :pass: FALSE
|
||||
:should: 'detect mismatch within overridden depth via ExpectWithArrayExtended'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
int exp_count = 0;
|
||||
int exp_data[] = {10, 99, 30};
|
||||
store_data_ExpectWithArrayExtended(&exp_count, 1, 3, exp_data, 2);
|
||||
|
||||
function_k();
|
||||
}
|
||||
|
||||
...
|
||||
@@ -0,0 +1,113 @@
|
||||
# =========================================================================
|
||||
# CMock - Automatic Mock Generation for C
|
||||
# ThrowTheSwitch.org
|
||||
# Copyright (c) 2007-26 Mike Karlesky, Mark VanderVoord, & Greg Williams
|
||||
# SPDX-License-Identifier: MIT
|
||||
# =========================================================================
|
||||
|
||||
---
|
||||
:cmock:
|
||||
:when_ptr: :smart
|
||||
:plugins:
|
||||
- :array
|
||||
|
||||
:systest:
|
||||
:types: |
|
||||
|
||||
:mockable: |
|
||||
void send_message(const char* msg);
|
||||
int process_command(const char* cmd, int len);
|
||||
|
||||
:source:
|
||||
:header: |
|
||||
void function_a(void);
|
||||
void function_b(void);
|
||||
void function_c(void);
|
||||
int function_d(void);
|
||||
int function_e(void);
|
||||
|
||||
:code: |
|
||||
void function_a(void)
|
||||
{
|
||||
send_message("hello");
|
||||
}
|
||||
|
||||
void function_b(void)
|
||||
{
|
||||
send_message("hello");
|
||||
}
|
||||
|
||||
void function_c(void)
|
||||
{
|
||||
send_message("hello");
|
||||
}
|
||||
|
||||
int function_d(void)
|
||||
{
|
||||
return process_command("hello", 5);
|
||||
}
|
||||
|
||||
int function_e(void)
|
||||
{
|
||||
return process_command("hello", 5);
|
||||
}
|
||||
|
||||
:tests:
|
||||
:common: |
|
||||
void setUp(void) {}
|
||||
void tearDown(void) {}
|
||||
|
||||
:units:
|
||||
- :pass: TRUE
|
||||
:should: 'compare char* args as strings using Expect (strcmp) when array plugin active'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
send_message_Expect("hello");
|
||||
function_a();
|
||||
}
|
||||
|
||||
- :pass: TRUE
|
||||
:should: 'compare char* args as byte array using ExpectWithArray and pass when bytes match'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
send_message_ExpectWithArray("hello", 5);
|
||||
function_b();
|
||||
}
|
||||
|
||||
- :pass: TRUE
|
||||
:should: 'compare char* args as byte array using ExpectWithArray and pass when brief bytes match'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
send_message_ExpectWithArray("heXXX", 2);
|
||||
function_b();
|
||||
}
|
||||
|
||||
- :pass: FALSE
|
||||
:should: 'detect mismatch in char* via ExpectWithArray byte comparison'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
send_message_ExpectWithArray("hXllo", 5);
|
||||
function_c();
|
||||
}
|
||||
|
||||
- :pass: TRUE
|
||||
:should: 'compare char* with ExpectWithArrayAndReturn and pass when bytes match'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
process_command_ExpectWithArrayAndReturn("hello", 5, 42);
|
||||
TEST_ASSERT_EQUAL(42, function_d());
|
||||
}
|
||||
|
||||
- :pass: FALSE
|
||||
:should: 'detect mismatch in char* via ExpectWithArrayAndReturn byte comparison'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
process_command_ExpectWithArrayAndReturn("world", 5, 42);
|
||||
TEST_ASSERT_EQUAL(42, function_e());
|
||||
}
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
---
|
||||
:cmock:
|
||||
:plugins: []
|
||||
:plugins: [ignore, expect_any_args, array]
|
||||
:treat_as:
|
||||
custom_type: INT
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
|
||||
:mockable: |
|
||||
void foo(BIG_FAT_STRUCT_T a);
|
||||
int get_result(void);
|
||||
void process_data(int* data, int count);
|
||||
|
||||
:source:
|
||||
:header: |
|
||||
@@ -68,6 +70,7 @@
|
||||
|
||||
- :pass: FALSE
|
||||
:should: 'should error out because we do not have eough memory to handle two of these structures'
|
||||
:verify_error: 'CMock has run out of memory. Please allocate more.'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
@@ -86,4 +89,41 @@
|
||||
}
|
||||
}
|
||||
|
||||
- :pass: FALSE
|
||||
:should: 'should error out on ExpectAnyArgs when memory is exhausted'
|
||||
:verify_error: 'CMock has run out of memory. Please allocate more.'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
// Fill all available memory with ExpectAnyArgs call instances
|
||||
while (CMock_Guts_MemBytesFree() > 0) {
|
||||
foo_ExpectAnyArgs();
|
||||
}
|
||||
}
|
||||
|
||||
- :pass: FALSE
|
||||
:should: 'should error out on IgnoreAndReturn when memory is exhausted'
|
||||
:verify_error: 'CMock has run out of memory. Please allocate more.'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
// Fill all available memory with IgnoreAndReturn call instances
|
||||
while (CMock_Guts_MemBytesFree() > 0) {
|
||||
get_result_IgnoreAndReturn(42);
|
||||
}
|
||||
}
|
||||
|
||||
- :pass: FALSE
|
||||
:should: 'should error out on ExpectWithArray when memory is exhausted'
|
||||
:verify_error: 'CMock has run out of memory. Please allocate more.'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
int data = 0;
|
||||
// Fill all available memory with ExpectWithArray call instances
|
||||
while (CMock_Guts_MemBytesFree() > 0) {
|
||||
process_data_ExpectWithArray(&data, 1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
...
|
||||
|
||||
+191
-179
@@ -13,21 +13,32 @@
|
||||
|
||||
:systest:
|
||||
:types: |
|
||||
typedef struct _POINT_T {
|
||||
typedef struct {
|
||||
int x;
|
||||
int y;
|
||||
} POINT_T;
|
||||
#define ARRAY_A_SIZE (5)
|
||||
|
||||
typedef enum {
|
||||
RED = 0,
|
||||
GREEN = 1,
|
||||
BLUE = 2
|
||||
} COLOR_E;
|
||||
|
||||
typedef union {
|
||||
int as_int;
|
||||
unsigned short as_shorts[2];
|
||||
} RESULT_U;
|
||||
|
||||
:mockable: |
|
||||
void foo(POINT_T* a);
|
||||
POINT_T* bar(void);
|
||||
void fooa(POINT_T a[ARRAY_A_SIZE+1-1]);
|
||||
void foos(const char * a);
|
||||
const char * bars(void);
|
||||
void no_pointers(int a, const char* b);
|
||||
int mixed(int a, int* b, int c);
|
||||
void potential_packing_problem(short *a);
|
||||
void foos(const char* a);
|
||||
const char* bars(void);
|
||||
void poke_color(COLOR_E* c);
|
||||
COLOR_E* peek_color(void);
|
||||
void poke_result(RESULT_U* r);
|
||||
RESULT_U* peek_result(void);
|
||||
void potential_packing_problem(short* a);
|
||||
void voidpointerfunc(void* a);
|
||||
|
||||
:source:
|
||||
@@ -35,7 +46,7 @@
|
||||
void function_a(void);
|
||||
void function_b(void);
|
||||
void function_c(void);
|
||||
int function_d(void);
|
||||
void function_d(void);
|
||||
void function_e(void);
|
||||
void function_f(void);
|
||||
|
||||
@@ -45,26 +56,29 @@
|
||||
foo(bar());
|
||||
}
|
||||
|
||||
void function_b(void) {
|
||||
fooa(bar());
|
||||
}
|
||||
|
||||
void function_c(void) {
|
||||
void function_b(void)
|
||||
{
|
||||
foos(bars());
|
||||
}
|
||||
|
||||
int function_d(void) {
|
||||
int test_list[] = { 1, 2, 3, 4, 5 };
|
||||
no_pointers(1, "silly");
|
||||
return mixed(6, test_list, 7);
|
||||
void function_c(void)
|
||||
{
|
||||
poke_color(peek_color());
|
||||
}
|
||||
|
||||
void function_e(void) {
|
||||
void function_d(void)
|
||||
{
|
||||
poke_result(peek_result());
|
||||
}
|
||||
|
||||
void function_e(void)
|
||||
{
|
||||
short test_list[] = {-1, -2, -3, -4};
|
||||
potential_packing_problem(&test_list[1]);
|
||||
}
|
||||
|
||||
void function_f(void) {
|
||||
void function_f(void)
|
||||
{
|
||||
char arg[6] = "hello";
|
||||
voidpointerfunc(arg);
|
||||
}
|
||||
@@ -76,7 +90,7 @@
|
||||
|
||||
:units:
|
||||
- :pass: TRUE
|
||||
:should: 'handle the situation where we pass nulls to pointers'
|
||||
:should: 'handle null struct pointers in both directions'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
@@ -87,7 +101,7 @@
|
||||
}
|
||||
|
||||
- :pass: FALSE
|
||||
:should: 'handle the situation where we expected nulls to pointers but did not get that'
|
||||
:should: 'detect mismatch when expecting null struct pointer but receiving non-null'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
@@ -99,7 +113,7 @@
|
||||
}
|
||||
|
||||
- :pass: FALSE
|
||||
:should: 'handle the situation where we did not expect nulls to pointers but got null'
|
||||
:should: 'detect mismatch when expecting non-null struct pointer but receiving null'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
@@ -111,7 +125,33 @@
|
||||
}
|
||||
|
||||
- :pass: TRUE
|
||||
:should: 'handle the situation where it falls back to pointers because you asked it to compare 0 elements'
|
||||
:should: 'compare struct pointer contents and pass when contents match'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
POINT_T pt = {3, 7};
|
||||
POINT_T ex = {3, 7};
|
||||
bar_ExpectAndReturn(&pt);
|
||||
foo_Expect(&ex);
|
||||
|
||||
function_a();
|
||||
}
|
||||
|
||||
- :pass: FALSE
|
||||
:should: 'compare struct pointer contents and fail when contents differ'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
POINT_T pt = {3, 7};
|
||||
POINT_T ex = {3, 9};
|
||||
bar_ExpectAndReturn(&pt);
|
||||
foo_Expect(&ex);
|
||||
|
||||
function_a();
|
||||
}
|
||||
|
||||
- :pass: TRUE
|
||||
:should: 'fall back to pointer comparison when depth is zero and pointers match'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
@@ -123,7 +163,7 @@
|
||||
}
|
||||
|
||||
- :pass: FALSE
|
||||
:should: 'handle the situation where it fails because you asked it to compare zero elements and the pointers do not match'
|
||||
:should: 'fail pointer comparison when depth is zero and pointers differ'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
@@ -136,59 +176,7 @@
|
||||
}
|
||||
|
||||
- :pass: TRUE
|
||||
:should: 'handle the situation where we pass single object with expect'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
POINT_T pt = {1, 2};
|
||||
POINT_T ex = {1, 2};
|
||||
bar_ExpectAndReturn(&pt);
|
||||
foo_Expect(&ex);
|
||||
|
||||
function_a();
|
||||
}
|
||||
|
||||
- :pass: FALSE
|
||||
:should: 'handle the situation where we pass single object with expect and it is wrong'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
POINT_T pt = {1, 2};
|
||||
POINT_T ex = {1, 3};
|
||||
bar_ExpectAndReturn(&pt);
|
||||
foo_Expect(&ex);
|
||||
|
||||
function_a();
|
||||
}
|
||||
|
||||
- :pass: TRUE
|
||||
:should: 'handle the situation where we pass single object with expect and use array handler'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
POINT_T pt = {1, 2};
|
||||
POINT_T ex = {1, 2};
|
||||
bar_ExpectAndReturn(&pt);
|
||||
foo_ExpectWithArray(&ex, 1);
|
||||
|
||||
function_a();
|
||||
}
|
||||
|
||||
- :pass: FALSE
|
||||
:should: 'handle the situation where we pass single object with expect and use array handler and it is wrong'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
POINT_T pt = {1, 2};
|
||||
POINT_T ex = {1, 3};
|
||||
bar_ExpectAndReturn(&pt);
|
||||
foo_ExpectWithArray(&ex, 1);
|
||||
|
||||
function_a();
|
||||
}
|
||||
|
||||
- :pass: TRUE
|
||||
:should: 'handle the situation where we pass multiple objects with expect and use array handler'
|
||||
:should: 'compare multiple struct elements via ExpectWithArray and pass'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
@@ -201,7 +189,7 @@
|
||||
}
|
||||
|
||||
- :pass: FALSE
|
||||
:should: 'handle the situation where we pass multiple objects with expect and use array handler and it is wrong at start'
|
||||
:should: 'detect mismatch in first element of struct array comparison'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
@@ -214,20 +202,7 @@
|
||||
}
|
||||
|
||||
- :pass: FALSE
|
||||
:should: 'handle the situation where we pass multiple objects with expect and use array handler and it is wrong at end'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
POINT_T pt[] = {{1, 2}, {3, 4}, {5, 6}};
|
||||
POINT_T ex[] = {{1, 2}, {3, 4}, {5, 9}};
|
||||
bar_ExpectAndReturn(pt);
|
||||
foo_ExpectWithArray(ex, 3);
|
||||
|
||||
function_a();
|
||||
}
|
||||
|
||||
- :pass: FALSE
|
||||
:should: 'handle the situation where we pass multiple objects with expect and use array handler and it is wrong in middle'
|
||||
:should: 'detect mismatch in middle element of struct array comparison'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
@@ -240,68 +215,20 @@
|
||||
}
|
||||
|
||||
- :pass: FALSE
|
||||
:should: 'handle the situation where we pass nulls to pointers and fail'
|
||||
:should: 'detect mismatch in last element of struct array comparison'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
POINT_T pt = {1, 2};
|
||||
bar_ExpectAndReturn(&pt);
|
||||
foo_Expect(NULL);
|
||||
POINT_T pt[] = {{1, 2}, {3, 4}, {5, 6}};
|
||||
POINT_T ex[] = {{1, 2}, {3, 4}, {5, 9}};
|
||||
bar_ExpectAndReturn(pt);
|
||||
foo_ExpectWithArray(ex, 3);
|
||||
|
||||
function_a();
|
||||
}
|
||||
|
||||
- :pass: TRUE
|
||||
:should: 'handle the situation where we pass nulls to arrays'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
bar_ExpectAndReturn(NULL);
|
||||
fooa_Expect(NULL);
|
||||
|
||||
function_b();
|
||||
}
|
||||
|
||||
- :pass: TRUE
|
||||
:should: 'handle the situation where we pass single array element with expect'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
POINT_T pt = {1, 2};
|
||||
POINT_T ex = {1, 2};
|
||||
bar_ExpectAndReturn(&pt);
|
||||
fooa_Expect(&ex);
|
||||
|
||||
function_b();
|
||||
}
|
||||
|
||||
- :pass: FALSE
|
||||
:should: 'handle the situation where we pass single array element with expect and it is wrong'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
POINT_T pt = {1, 2};
|
||||
POINT_T ex = {1, 3};
|
||||
bar_ExpectAndReturn(&pt);
|
||||
fooa_Expect(&ex);
|
||||
|
||||
function_b();
|
||||
}
|
||||
|
||||
- :pass: FALSE
|
||||
:should: 'handle the situation where we pass nulls to arrays and fail'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
POINT_T pt = {1, 2};
|
||||
bar_ExpectAndReturn(&pt);
|
||||
fooa_Expect(NULL);
|
||||
|
||||
function_b();
|
||||
}
|
||||
|
||||
- :pass: TRUE
|
||||
:should: 'handle standard c string as null terminated on not do crappy memory compares of a byte, passing'
|
||||
:should: 'handle string pointer matching on null-terminated content'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
@@ -309,11 +236,11 @@
|
||||
bars_ExpectAndReturn((char*)retval);
|
||||
foos_Expect("This is a\0 wacky string");
|
||||
|
||||
function_c();
|
||||
function_b();
|
||||
}
|
||||
|
||||
- :pass: FALSE
|
||||
:should: 'handle standard c string as null terminated on not do crappy memory compares of a byte, finding failures'
|
||||
:should: 'detect string pointer mismatch on content'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
@@ -321,81 +248,167 @@
|
||||
bars_ExpectAndReturn((char*)retval);
|
||||
foos_Expect("This is a wacky string");
|
||||
|
||||
function_b();
|
||||
}
|
||||
|
||||
- :pass: TRUE
|
||||
:should: 'handle null enum pointers in both directions'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
peek_color_ExpectAndReturn(NULL);
|
||||
poke_color_Expect(NULL);
|
||||
|
||||
function_c();
|
||||
}
|
||||
|
||||
- :pass: TRUE
|
||||
:should: 'handle creating array expects when we have mixed arguments for single object'
|
||||
:should: 'compare enum pointer contents and pass when contents match'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
int expect_list[] = { 1, 9 };
|
||||
no_pointers_Expect(1, "silly");
|
||||
mixed_ExpectAndReturn(6, expect_list, 7, 13);
|
||||
COLOR_E actual = GREEN;
|
||||
COLOR_E expected = GREEN;
|
||||
peek_color_ExpectAndReturn(&actual);
|
||||
poke_color_Expect(&expected);
|
||||
|
||||
TEST_ASSERT_EQUAL(13, function_d());
|
||||
function_c();
|
||||
}
|
||||
|
||||
- :pass: FALSE
|
||||
:should: 'handle creating array expects when we have mixed arguments and handle failures for single object'
|
||||
:should: 'detect mismatch in enum pointer contents'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
int expect_list[] = { 9, 1 };
|
||||
no_pointers_Expect(1, "silly");
|
||||
mixed_ExpectAndReturn(6, expect_list, 7, 13);
|
||||
COLOR_E actual = GREEN;
|
||||
COLOR_E expected = BLUE;
|
||||
peek_color_ExpectAndReturn(&actual);
|
||||
poke_color_Expect(&expected);
|
||||
|
||||
TEST_ASSERT_EQUAL(13, function_d());
|
||||
function_c();
|
||||
}
|
||||
|
||||
- :pass: TRUE
|
||||
:should: 'handle creating array expects when we have mixed arguments for multiple objects'
|
||||
:should: 'compare multiple enum elements via ExpectWithArray and pass'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
int expect_list[] = { 1, 2, 3, 4, 6 };
|
||||
no_pointers_Expect(1, "silly");
|
||||
mixed_ExpectWithArrayAndReturn(6, expect_list, 4, 7, 13);
|
||||
COLOR_E actual[] = {RED, GREEN, BLUE};
|
||||
COLOR_E expected[] = {RED, GREEN, BLUE};
|
||||
peek_color_ExpectAndReturn(actual);
|
||||
poke_color_ExpectWithArray(expected, 3);
|
||||
|
||||
TEST_ASSERT_EQUAL(13, function_d());
|
||||
function_c();
|
||||
}
|
||||
|
||||
- :pass: FALSE
|
||||
:should: 'handle creating array expects when we have mixed arguments and handle failures for multiple objects'
|
||||
:should: 'detect mismatch when comparing multiple enum elements'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
int expect_list[] = { 1, 2, 3, 4, 6 };
|
||||
no_pointers_Expect(1, "silly");
|
||||
mixed_ExpectWithArrayAndReturn(6, expect_list, 5, 7, 13);
|
||||
COLOR_E actual[] = {RED, GREEN, BLUE};
|
||||
COLOR_E expected[] = {RED, BLUE, BLUE};
|
||||
peek_color_ExpectAndReturn(actual);
|
||||
poke_color_ExpectWithArray(expected, 3);
|
||||
|
||||
TEST_ASSERT_EQUAL(13, function_d());
|
||||
function_c();
|
||||
}
|
||||
|
||||
- :pass: TRUE
|
||||
:should: 'handle a passing version of a potential packing problem (particularly try with ARM simulators)'
|
||||
:should: 'handle null union pointers in both directions'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
short expect_list[] = { -2, -3, -4 };
|
||||
peek_result_ExpectAndReturn(NULL);
|
||||
poke_result_Expect(NULL);
|
||||
|
||||
function_d();
|
||||
}
|
||||
|
||||
- :pass: TRUE
|
||||
:should: 'compare union pointer contents and pass when contents match'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
RESULT_U actual;
|
||||
RESULT_U expected;
|
||||
actual.as_int = 42;
|
||||
expected.as_int = 42;
|
||||
peek_result_ExpectAndReturn(&actual);
|
||||
poke_result_Expect(&expected);
|
||||
|
||||
function_d();
|
||||
}
|
||||
|
||||
- :pass: FALSE
|
||||
:should: 'detect mismatch in union pointer contents'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
RESULT_U actual;
|
||||
RESULT_U expected;
|
||||
actual.as_int = 42;
|
||||
expected.as_int = 99;
|
||||
peek_result_ExpectAndReturn(&actual);
|
||||
poke_result_Expect(&expected);
|
||||
|
||||
function_d();
|
||||
}
|
||||
|
||||
- :pass: TRUE
|
||||
:should: 'compare multiple union elements via ExpectWithArray and pass'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
RESULT_U actual[3];
|
||||
RESULT_U expected[3];
|
||||
actual[0].as_int = 1; actual[1].as_int = 2; actual[2].as_int = 3;
|
||||
expected[0].as_int = 1; expected[1].as_int = 2; expected[2].as_int = 3;
|
||||
peek_result_ExpectAndReturn(actual);
|
||||
poke_result_ExpectWithArray(expected, 3);
|
||||
|
||||
function_d();
|
||||
}
|
||||
|
||||
- :pass: FALSE
|
||||
:should: 'detect mismatch when comparing multiple union elements'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
RESULT_U actual[3];
|
||||
RESULT_U expected[3];
|
||||
actual[0].as_int = 1; actual[1].as_int = 2; actual[2].as_int = 3;
|
||||
expected[0].as_int = 1; expected[1].as_int = 9; expected[2].as_int = 3;
|
||||
peek_result_ExpectAndReturn(actual);
|
||||
poke_result_ExpectWithArray(expected, 3);
|
||||
|
||||
function_d();
|
||||
}
|
||||
|
||||
- :pass: TRUE
|
||||
:should: 'handle a passing packing problem comparison'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
short expect_list[] = {-2, -3, -4};
|
||||
potential_packing_problem_ExpectWithArray(expect_list, 3);
|
||||
|
||||
function_e();
|
||||
}
|
||||
|
||||
- :pass: FALSE
|
||||
:should: 'handle a failing version of a potential packing problem (particularly try with ARM simulators)'
|
||||
:should: 'detect a failing packing problem comparison'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
short expect_list[] = { -2, -3, 4 };
|
||||
short expect_list[] = {-2, -3, 4};
|
||||
potential_packing_problem_ExpectWithArray(expect_list, 3);
|
||||
|
||||
function_e();
|
||||
}
|
||||
|
||||
- :pass: TRUE
|
||||
:should: 'handle a void pointers as arguments and still be able to use the array plugin'
|
||||
:should: 'handle void pointer with array comparison passing'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
@@ -406,7 +419,7 @@
|
||||
}
|
||||
|
||||
- :pass: TRUE
|
||||
:should: 'handle a void pointers as arguments and still be able to use the array plugin (short)'
|
||||
:should: 'handle void pointer with partial array comparison passing'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
@@ -417,7 +430,7 @@
|
||||
}
|
||||
|
||||
- :pass: FALSE
|
||||
:should: 'handle a void pointers as arguments and still be able to use the array plugin (fail)'
|
||||
:should: 'detect void pointer content mismatch with array comparison'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
@@ -428,7 +441,7 @@
|
||||
}
|
||||
|
||||
- :pass: TRUE
|
||||
:should: 'handle a void pointer with a standard expectation (pass)'
|
||||
:should: 'handle void pointer with standard expect passing'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
@@ -439,7 +452,7 @@
|
||||
}
|
||||
|
||||
- :pass: FALSE
|
||||
:should: 'handle a void pointer with a standard expectation (fail)'
|
||||
:should: 'detect void pointer mismatch with standard expect'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
@@ -449,5 +462,4 @@
|
||||
function_f();
|
||||
}
|
||||
|
||||
|
||||
...
|
||||
+7
-11
@@ -15,7 +15,7 @@
|
||||
:when_ptr: :smart
|
||||
:plugins:
|
||||
- :array
|
||||
- :ignore_arg
|
||||
- :expect_any_args
|
||||
- :return_thru_ptr
|
||||
|
||||
:systest:
|
||||
@@ -106,11 +106,10 @@
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
int r = 1, s = 2;
|
||||
int s = 2;
|
||||
int res = 4;
|
||||
|
||||
ptr_ret_int_Expect(&r);
|
||||
ptr_ret_int_IgnoreArg_r();
|
||||
ptr_ret_int_ExpectAnyArgs();
|
||||
ptr_ret_int_ReturnThruPtr_r(&res);
|
||||
ptr_ret_int(&s);
|
||||
TEST_ASSERT_EQUAL(4, s);
|
||||
@@ -124,8 +123,7 @@
|
||||
int r = 1;
|
||||
int res = 4;
|
||||
|
||||
ptr_ret_int_Expect(NULL);
|
||||
ptr_ret_int_IgnoreArg_r();
|
||||
ptr_ret_int_ExpectAnyArgs();
|
||||
ptr_ret_int_ReturnThruPtr_r(&res);
|
||||
ptr_ret_int(&r);
|
||||
TEST_ASSERT_EQUAL(4, r);
|
||||
@@ -230,13 +228,11 @@
|
||||
}
|
||||
|
||||
- :pass: TRUE
|
||||
:should: "generate IgnoreArg definitions"
|
||||
:should: "generate ExpectAnyArgs 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.");
|
||||
#if !defined(ptr_ret_array_ExpectAnyArgs)
|
||||
TEST_FAIL_MESSAGE("ExpectAnyArgs not defined for an argument.");
|
||||
#endif
|
||||
}
|
||||
@@ -15,7 +15,7 @@
|
||||
:when_ptr: :smart
|
||||
:plugins:
|
||||
- :array
|
||||
- :expect_any_args
|
||||
- :ignore_arg
|
||||
- :return_thru_ptr
|
||||
|
||||
:systest:
|
||||
@@ -106,10 +106,11 @@
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
int s = 2;
|
||||
int r = 1, s = 2;
|
||||
int res = 4;
|
||||
|
||||
ptr_ret_int_ExpectAnyArgs();
|
||||
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);
|
||||
@@ -123,7 +124,8 @@
|
||||
int r = 1;
|
||||
int res = 4;
|
||||
|
||||
ptr_ret_int_ExpectAnyArgs();
|
||||
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);
|
||||
@@ -228,11 +230,13 @@
|
||||
}
|
||||
|
||||
- :pass: TRUE
|
||||
:should: "generate ExpectAnyArgs definitions"
|
||||
:should: "generate IgnoreArg definitions"
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
#if !defined(ptr_ret_array_ExpectAnyArgs)
|
||||
TEST_FAIL_MESSAGE("ExpectAnyArgs not defined for an argument.");
|
||||
#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
|
||||
}
|
||||
|
||||
@@ -0,0 +1,133 @@
|
||||
# =========================================================================
|
||||
# CMock - Automatic Mock Generation for C
|
||||
# ThrowTheSwitch.org
|
||||
# Copyright (c) 2007-26 Mike Karlesky, Mark VanderVoord, & Greg Williams
|
||||
# SPDX-License-Identifier: MIT
|
||||
# =========================================================================
|
||||
|
||||
---
|
||||
#The purpose of this test is to verify that void* arguments use pointer
|
||||
#comparison (not byte dereferencing) when the array plugin is not active.
|
||||
#Dereferencing void* is illegal in C, so the mock must fall back to
|
||||
#comparing pointer values via UNITY_TEST_ASSERT_EQUAL_PTR.
|
||||
:cmock:
|
||||
:plugins: []
|
||||
:treat_as_void:
|
||||
- MY_VOID
|
||||
|
||||
:systest:
|
||||
:types: |
|
||||
typedef void MY_VOID;
|
||||
|
||||
:mockable: |
|
||||
void get_v_ptr(void* ptr);
|
||||
void get_const_v_ptr(const void* ptr);
|
||||
void get_my_void_ptr(MY_VOID* ptr);
|
||||
|
||||
:source:
|
||||
:header: |
|
||||
void function_a(void* arg);
|
||||
void function_b(const void* arg);
|
||||
void function_c(MY_VOID* arg);
|
||||
|
||||
:code: |
|
||||
void function_a(void* arg) {
|
||||
get_v_ptr(arg);
|
||||
}
|
||||
|
||||
void function_b(const void* arg) {
|
||||
get_const_v_ptr(arg);
|
||||
}
|
||||
|
||||
void function_c(MY_VOID* arg) {
|
||||
get_my_void_ptr(arg);
|
||||
}
|
||||
|
||||
:tests:
|
||||
:common: |
|
||||
void setUp(void) {}
|
||||
void tearDown(void) {}
|
||||
|
||||
:units:
|
||||
- :pass: TRUE
|
||||
:should: 'handle void pointer expect passing when same pointer used'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
char* a = "Hello";
|
||||
get_v_ptr_Expect(a);
|
||||
function_a(a);
|
||||
}
|
||||
|
||||
- :pass: FALSE
|
||||
:should: 'detect void pointer mismatch when different pointers used even with same content'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
static char a[] = "Hello";
|
||||
static char b[] = "Hello";
|
||||
get_v_ptr_Expect(a);
|
||||
function_a(b);
|
||||
}
|
||||
|
||||
- :pass: TRUE
|
||||
:should: 'handle null void pointer expect passing'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
get_v_ptr_Expect(NULL);
|
||||
function_a(NULL);
|
||||
}
|
||||
|
||||
- :pass: FALSE
|
||||
:should: 'detect null vs non-null void pointer mismatch'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
char* a = "Hello";
|
||||
get_v_ptr_Expect(NULL);
|
||||
function_a(a);
|
||||
}
|
||||
|
||||
- :pass: TRUE
|
||||
:should: 'handle const void pointer expect passing when same pointer used'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
char* a = "Hello";
|
||||
get_const_v_ptr_Expect(a);
|
||||
function_b(a);
|
||||
}
|
||||
|
||||
- :pass: FALSE
|
||||
:should: 'detect const void pointer mismatch when different pointers used'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
static char a[] = "Hello";
|
||||
static char b[] = "Hello";
|
||||
get_const_v_ptr_Expect(a);
|
||||
function_b(b);
|
||||
}
|
||||
|
||||
- :pass: TRUE
|
||||
:should: 'handle treat_as_void alias pointer expect passing when same pointer used'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
char* a = "Hello";
|
||||
get_my_void_ptr_Expect(a);
|
||||
function_c(a);
|
||||
}
|
||||
|
||||
- :pass: FALSE
|
||||
:should: 'detect treat_as_void alias pointer mismatch when different pointers used'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
static char a[] = "Hello";
|
||||
static char b[] = "Hello";
|
||||
get_my_void_ptr_Expect(a);
|
||||
function_c(b);
|
||||
}
|
||||
...
|
||||
@@ -0,0 +1,102 @@
|
||||
# =========================================================================
|
||||
# CMock - Automatic Mock Generation for C
|
||||
# ThrowTheSwitch.org
|
||||
# Copyright (c) 2007-26 Mike Karlesky, Mark VanderVoord, & Greg Williams
|
||||
# SPDX-License-Identifier: MIT
|
||||
# =========================================================================
|
||||
|
||||
---
|
||||
#The purpose of this test is to verify that pointers to treat_as_void alias types
|
||||
#(e.g. MY_VOID*) use HEX8_ARRAY byte comparison when the array plugin is active,
|
||||
#rather than falling through to MEMORY_ARRAY which would emit sizeof(void) — illegal C.
|
||||
:cmock:
|
||||
:plugins:
|
||||
- :array
|
||||
:when_ptr: :smart
|
||||
:treat_as_void:
|
||||
- MY_VOID
|
||||
|
||||
:systest:
|
||||
:types: |
|
||||
typedef void MY_VOID;
|
||||
|
||||
:mockable: |
|
||||
void get_my_void_ptr(MY_VOID* ptr);
|
||||
|
||||
:source:
|
||||
:header: |
|
||||
void function_a(MY_VOID* arg);
|
||||
|
||||
:code: |
|
||||
void function_a(MY_VOID* arg) {
|
||||
get_my_void_ptr(arg);
|
||||
}
|
||||
|
||||
:tests:
|
||||
:common: |
|
||||
void setUp(void) {}
|
||||
void tearDown(void) {}
|
||||
|
||||
:units:
|
||||
- :pass: TRUE
|
||||
:should: 'handle treat_as_void pointer with same pointer using standard expect'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
char* a = "Hello";
|
||||
get_my_void_ptr_Expect(a);
|
||||
function_a(a);
|
||||
}
|
||||
|
||||
- :pass: TRUE
|
||||
:should: 'handle treat_as_void pointer with same content using ExpectWithArray'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
char* a = "Hello";
|
||||
char* b = "Hello";
|
||||
get_my_void_ptr_ExpectWithArray(a, 5);
|
||||
function_a(b);
|
||||
}
|
||||
|
||||
- :pass: FALSE
|
||||
:should: 'detect treat_as_void pointer content mismatch with ExpectWithArray'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
char* a = "Hello";
|
||||
char* b = "Jello";
|
||||
get_my_void_ptr_ExpectWithArray(a, 5);
|
||||
function_a(b);
|
||||
}
|
||||
|
||||
- :pass: TRUE
|
||||
:should: 'handle null treat_as_void pointer comparison'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
get_my_void_ptr_Expect(NULL);
|
||||
function_a(NULL);
|
||||
}
|
||||
|
||||
- :pass: TRUE
|
||||
:should: 'handle treat_as_void pointer comparison with depth 0 using smart ptr comparison'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
char* a = "Hello";
|
||||
get_my_void_ptr_ExpectWithArray(a, 0);
|
||||
function_a(a);
|
||||
}
|
||||
|
||||
- :pass: FALSE
|
||||
:should: 'detect treat_as_void pointer value mismatch with depth 0 in smart mode'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
static char a[] = "Hello";
|
||||
static char b[] = "Hello";
|
||||
get_my_void_ptr_ExpectWithArray(a, 0);
|
||||
function_a(b);
|
||||
}
|
||||
...
|
||||
@@ -16,6 +16,9 @@ class UtilsStub
|
||||
def arg_type_with_const(arg)
|
||||
CMockGeneratorUtils.arg_type_with_const(arg)
|
||||
end
|
||||
def arg_declaration(arg)
|
||||
CMockGeneratorUtils.arg_declaration(arg)
|
||||
end
|
||||
def code_add_base_expectation(func)
|
||||
"mock_retval_0"
|
||||
end
|
||||
|
||||
@@ -16,6 +16,9 @@ class UtilsStub
|
||||
def arg_type_with_const(arg)
|
||||
CMockGeneratorUtils.arg_type_with_const(arg)
|
||||
end
|
||||
def arg_declaration(arg)
|
||||
CMockGeneratorUtils.arg_declaration(arg)
|
||||
end
|
||||
def code_add_base_expectation(func)
|
||||
"mock_retval_0"
|
||||
end
|
||||
@@ -115,6 +118,42 @@ describe CMockGeneratorPluginArray, "Verify CMockPGeneratorluginArray Module" do
|
||||
assert_equal(expected, returned)
|
||||
end
|
||||
|
||||
it "add mock function declarations for functions with size arg after pointer, short macro auto-fills depth" do
|
||||
function = {:name => "Birch",
|
||||
:args => [
|
||||
{ :type => "int*", :name => "sensors", :ptr? => true, :array_size_order => :after, :array_size_name => "count" },
|
||||
{ :type => "int", :name => "count", :ptr? => false, :array_size? => true }
|
||||
],
|
||||
:return => test_return[:void],
|
||||
:contains_ptr? => true }
|
||||
|
||||
expected = "#define Birch_ExpectWithArrayAndReturn(sensors, count, cmock_retval) TEST_FAIL_MESSAGE(\"Birch requires _ExpectWithArray (not AndReturn)\");\n" +
|
||||
"#define Birch_ExpectWithArrayExtendedAndReturn(sensors, sensors_Depth, count, cmock_retval) TEST_FAIL_MESSAGE(\"Birch requires _ExpectWithArrayExtended (not AndReturn)\");\n" +
|
||||
"#define Birch_ExpectWithArray(sensors, count) Birch_CMockExpectWithArray(__LINE__, sensors, (count), count)\n" +
|
||||
"#define Birch_ExpectWithArrayExtended(sensors, sensors_Depth, count) Birch_CMockExpectWithArray(__LINE__, sensors, (sensors_Depth), count)\n" +
|
||||
"void Birch_CMockExpectWithArray(UNITY_LINE_TYPE cmock_line, int* sensors, int sensors_Depth, int count);\n"
|
||||
returned = @cmock_generator_plugin_array.mock_function_declarations(function)
|
||||
assert_equal(expected, returned)
|
||||
end
|
||||
|
||||
it "add mock function declarations for functions with size arg before pointer, short macro auto-fills depth" do
|
||||
function = {:name => "Willow",
|
||||
:args => [
|
||||
{ :type => "int", :name => "buf_size", :ptr? => false, :array_size? => true },
|
||||
{ :type => "int*", :name => "buf", :ptr? => true, :array_size_order => :before, :array_size_name => "buf_size" }
|
||||
],
|
||||
:return => test_return[:void],
|
||||
:contains_ptr? => true }
|
||||
|
||||
expected = "#define Willow_ExpectWithArrayAndReturn(buf_size, buf, cmock_retval) TEST_FAIL_MESSAGE(\"Willow requires _ExpectWithArray (not AndReturn)\");\n" +
|
||||
"#define Willow_ExpectWithArrayExtendedAndReturn(buf_size, buf, buf_Depth, cmock_retval) TEST_FAIL_MESSAGE(\"Willow requires _ExpectWithArrayExtended (not AndReturn)\");\n" +
|
||||
"#define Willow_ExpectWithArray(buf_size, buf) Willow_CMockExpectWithArray(__LINE__, buf_size, buf, (buf_size))\n" +
|
||||
"#define Willow_ExpectWithArrayExtended(buf_size, buf, buf_Depth) Willow_CMockExpectWithArray(__LINE__, buf_size, buf, (buf_Depth))\n" +
|
||||
"void Willow_CMockExpectWithArray(UNITY_LINE_TYPE cmock_line, int buf_size, int* buf, int buf_Depth);\n"
|
||||
returned = @cmock_generator_plugin_array.mock_function_declarations(function)
|
||||
assert_equal(expected, returned)
|
||||
end
|
||||
|
||||
it "not have a mock function implementation" do
|
||||
assert(!@cmock_generator_plugin_array.respond_to?(:mock_implementation))
|
||||
end
|
||||
@@ -143,4 +182,25 @@ describe CMockGeneratorPluginArray, "Verify CMockPGeneratorluginArray Module" do
|
||||
assert_equal(expected, returned)
|
||||
end
|
||||
|
||||
it "add mock interfaces with depth override line for :before-paired pointer" do
|
||||
function = {:name => "Willow",
|
||||
:args => [
|
||||
{ :type => "int", :name => "buf_size", :ptr? => false, :array_size? => true },
|
||||
{ :type => "int*", :name => "buf", :ptr? => true, :array_size_order => :before, :array_size_name => "buf_size" }
|
||||
],
|
||||
:args_string => "int buf_size, int* buf",
|
||||
:return => test_return[:void],
|
||||
:contains_ptr? => true }
|
||||
|
||||
expected = ["void Willow_CMockExpectWithArray(UNITY_LINE_TYPE cmock_line, int buf_size, int* buf, int buf_Depth)\n",
|
||||
"{\n",
|
||||
"mock_retval_0",
|
||||
" CMockExpectParameters_Willow(cmock_call_instance, buf_size, buf);\n",
|
||||
" cmock_call_instance->Expected_buf_Depth = buf_Depth;\n",
|
||||
"}\n\n"
|
||||
].join
|
||||
returned = @cmock_generator_plugin_array.mock_interfaces(function).join
|
||||
assert_equal(expected, returned)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -98,6 +98,46 @@ describe CMockGeneratorUtils, "Verify CMockGeneratorUtils Module" do
|
||||
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"
|
||||
@@ -130,7 +170,7 @@ describe CMockGeneratorUtils, "Verify CMockGeneratorUtils Module" do
|
||||
|
||||
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 = Mango_Depth;\n" +
|
||||
" cmock_call_instance->IgnoreArg_Kiwi = 0;\n" +
|
||||
" cmock_call_instance->ReturnThruPtr_Kiwi_Used = 0;\n"
|
||||
|
||||
@@ -141,7 +181,7 @@ describe CMockGeneratorUtils, "Verify CMockGeneratorUtils Module" do
|
||||
|
||||
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, '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
|
||||
|
||||
@@ -401,4 +441,71 @@ describe CMockGeneratorUtils, "Verify CMockGeneratorUtils Module" do
|
||||
@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
|
||||
end
|
||||
|
||||
@@ -597,7 +597,7 @@ describe CMockHeaderParser, "Verify CMockHeaderParser Module" do
|
||||
},
|
||||
:modifier=>"",
|
||||
:contains_ptr? => false,
|
||||
:args=>[{:type=>"int", :name=>"a", :ptr? => false, :const? => false, :const_ptr? => false}],
|
||||
:args=>[{:type=>"int", :name=>"a", :ptr? => false, :string? => false, :const? => false, :const_ptr? => false}],
|
||||
:args_string=>"int a",
|
||||
:args_call=>"a"}
|
||||
assert_equal(expected, @parser.parse_declaration(@test_project, source))
|
||||
@@ -643,7 +643,7 @@ describe CMockHeaderParser, "Verify CMockHeaderParser Module" do
|
||||
},
|
||||
:modifier=>"",
|
||||
:contains_ptr? => true,
|
||||
:args=>[{:type=>"MY_FUNKY_VOID*", :name=>"bluh", :ptr? => true, :const? => false, :const_ptr? => false}],
|
||||
:args=>[{:type=>"MY_FUNKY_VOID*", :name=>"bluh", :ptr? => true, :string? => false, :const? => false, :const_ptr? => false}],
|
||||
:args_string=>"MY_FUNKY_VOID* bluh",
|
||||
:args_call=>"bluh" }
|
||||
assert_equal(expected, @parser.parse_declaration(@test_project, source))
|
||||
@@ -745,8 +745,8 @@ describe CMockHeaderParser, "Verify CMockHeaderParser Module" do
|
||||
},
|
||||
:modifier=>"",
|
||||
:contains_ptr? => false,
|
||||
:args=>[ {:type=>"int", :name=>"a", :ptr? => false, :const? => false, :const_ptr? => false},
|
||||
{:type=>"unsigned int", :name=>"b", :ptr? => false, :const? => false, :const_ptr? => false}
|
||||
:args=>[ {:type=>"int", :name=>"a", :ptr? => false, :string? => false, :const? => false, :const_ptr? => false},
|
||||
{:type=>"unsigned int", :name=>"b", :ptr? => false, :string? => false, :const? => false, :const_ptr? => false}
|
||||
],
|
||||
:args_string=>"int a, unsigned int b",
|
||||
:args_call=>"a, b" }
|
||||
@@ -771,9 +771,9 @@ describe CMockHeaderParser, "Verify CMockHeaderParser Module" do
|
||||
:class=>nil,
|
||||
:modifier=>"",
|
||||
:contains_ptr? => false,
|
||||
:args=>[ {:type=>"uint", :name=>"la", :ptr? => false, :const? => false, :const_ptr? => false},
|
||||
{:type=>"int", :name=>"de", :ptr? => false, :const? => false, :const_ptr? => false},
|
||||
{:type=>"bool", :name=>"da", :ptr? => false, :const? => false, :const_ptr? => false}
|
||||
:args=>[ {:type=>"uint", :name=>"la", :ptr? => false, :string? => false, :const? => false, :const_ptr? => false},
|
||||
{:type=>"int", :name=>"de", :ptr? => false, :string? => false, :const? => false, :const_ptr? => false},
|
||||
{:type=>"bool", :name=>"da", :ptr? => false, :string? => false, :const? => false, :const_ptr? => false}
|
||||
],
|
||||
:args_string=>"uint la, int de, bool da",
|
||||
:args_call=>"la, de, da" }
|
||||
@@ -822,8 +822,8 @@ describe CMockHeaderParser, "Verify CMockHeaderParser Module" do
|
||||
:class=>nil,
|
||||
:modifier=>"const",
|
||||
:contains_ptr? => true,
|
||||
:args=>[ {:type=>"int", :name=>"Trinity", :ptr? => false, :const? => false, :const_ptr? => false},
|
||||
{:type=>"unsigned int*", :name=>"Neo", :ptr? => true, :const? => false, :const_ptr? => false}
|
||||
:args=>[ {:type=>"int", :name=>"Trinity", :ptr? => false, :string? => false, :const? => false, :const_ptr? => false},
|
||||
{:type=>"unsigned int*", :name=>"Neo", :ptr? => true, :string? => false, :const? => false, :const_ptr? => false}
|
||||
],
|
||||
:args_string=>"int Trinity, unsigned int* Neo",
|
||||
:args_call=>"Trinity, Neo" }
|
||||
@@ -849,8 +849,8 @@ describe CMockHeaderParser, "Verify CMockHeaderParser Module" do
|
||||
:modifier=>"const",
|
||||
:c_calling_convention=>"__stdcall",
|
||||
:contains_ptr? => true,
|
||||
:args=>[ {:type=>"int", :name=>"Trinity", :ptr? => false, :const? => false, :const_ptr? => false},
|
||||
{:type=>"unsigned int*", :name=>"Neo", :ptr? => true, :const? => false, :const_ptr? => false}
|
||||
:args=>[ {:type=>"int", :name=>"Trinity", :ptr? => false, :string? => false, :const? => false, :const_ptr? => false},
|
||||
{:type=>"unsigned int*", :name=>"Neo", :ptr? => true, :string? => false, :const? => false, :const_ptr? => false}
|
||||
],
|
||||
:args_string=>"int Trinity, unsigned int* Neo",
|
||||
:args_call=>"Trinity, Neo" }
|
||||
@@ -874,8 +874,8 @@ describe CMockHeaderParser, "Verify CMockHeaderParser Module" do
|
||||
},
|
||||
:modifier=>"",
|
||||
:contains_ptr? => false,
|
||||
:args=>[ {:type=>"int", :name=>"a", :ptr? => false, :const? => false, :const_ptr? => false},
|
||||
{:type=>"unsigned int", :name=>"b", :ptr? => false, :const? => false, :const_ptr? => false}
|
||||
:args=>[ {:type=>"int", :name=>"a", :ptr? => false, :string? => false, :const? => false, :const_ptr? => false},
|
||||
{:type=>"unsigned int", :name=>"b", :ptr? => false, :string? => false, :const? => false, :const_ptr? => false}
|
||||
],
|
||||
:args_string=>"int a, unsigned int b",
|
||||
:args_call=>"a, b" }
|
||||
@@ -902,8 +902,8 @@ describe CMockHeaderParser, "Verify CMockHeaderParser Module" do
|
||||
:class=>nil,
|
||||
:modifier=>"const",
|
||||
:contains_ptr? => true,
|
||||
:args=>[ {:type=>"int", :name=>"Trinity", :ptr? => false, :const? => false, :const_ptr? => false},
|
||||
{:type=>"unsigned int*", :name=>"Neo", :ptr? => true, :const? => false, :const_ptr? => false}
|
||||
:args=>[ {:type=>"int", :name=>"Trinity", :ptr? => false, :string? => false, :const? => false, :const_ptr? => false},
|
||||
{:type=>"unsigned int*", :name=>"Neo", :ptr? => true, :string? => false, :const? => false, :const_ptr? => false}
|
||||
],
|
||||
:args_string=>"int Trinity, unsigned int* Neo",
|
||||
:args_call=>"Trinity, Neo" },
|
||||
@@ -922,8 +922,8 @@ describe CMockHeaderParser, "Verify CMockHeaderParser Module" do
|
||||
:class=>nil,
|
||||
:modifier=>"",
|
||||
:contains_ptr? => true,
|
||||
:args=>[ {:type=>"int", :name=>"cmock_arg1", :ptr? => false, :const? => false, :const_ptr? => false},
|
||||
{:type=>"unsigned int*", :name=>"cmock_arg2", :ptr? => true, :const? => false, :const_ptr? => false}
|
||||
:args=>[ {:type=>"int", :name=>"cmock_arg1", :ptr? => false, :string? => false, :const? => false, :const_ptr? => false},
|
||||
{:type=>"unsigned int*", :name=>"cmock_arg2", :ptr? => true, :string? => false, :const? => false, :const_ptr? => false}
|
||||
],
|
||||
:args_string=>"int cmock_arg1, unsigned int* cmock_arg2",
|
||||
:args_call=>"cmock_arg1, cmock_arg2"
|
||||
@@ -951,8 +951,8 @@ describe CMockHeaderParser, "Verify CMockHeaderParser Module" do
|
||||
},
|
||||
:modifier=>"const",
|
||||
:contains_ptr? => true,
|
||||
:args=>[ {:type=>"int", :name=>"Trinity", :ptr? => false, :const? => false, :const_ptr? => false},
|
||||
{:type=>"unsigned int*", :name=>"Neo", :ptr? => true, :const? => false, :const_ptr? => false}
|
||||
:args=>[ {:type=>"int", :name=>"Trinity", :ptr? => false, :string? => false, :const? => false, :const_ptr? => false},
|
||||
{:type=>"unsigned int*", :name=>"Neo", :ptr? => true, :string? => false, :const? => false, :const_ptr? => false}
|
||||
],
|
||||
:args_string=>"int Trinity, unsigned int* Neo",
|
||||
:args_call=>"Trinity, Neo"
|
||||
@@ -1070,14 +1070,14 @@ describe CMockHeaderParser, "Verify CMockHeaderParser Module" do
|
||||
:var_arg => nil,
|
||||
:args_string => "int const* cmock_arg1, int* const cmock_arg2, const int* cmock_arg3, const int* const cmock_arg4, " +
|
||||
"int const* const cmock_arg5, int* cmock_arg6, int cmock_arg7, const int cmock_arg8",
|
||||
:args => [{ :type=>"int const*", :name => "cmock_arg1", :ptr? => true, :const? => true, :const_ptr? => false },
|
||||
{ :type=>"int*", :name => "cmock_arg2", :ptr? => true, :const? => false, :const_ptr? => true },
|
||||
{ :type=>"const int*", :name => "cmock_arg3", :ptr? => true, :const? => true, :const_ptr? => false },
|
||||
{ :type=>"const int*", :name => "cmock_arg4", :ptr? => true, :const? => true, :const_ptr? => true },
|
||||
{ :type=>"int const*", :name => "cmock_arg5", :ptr? => true, :const? => true, :const_ptr? => true },
|
||||
{ :type=>"int*", :name => "cmock_arg6", :ptr? => true, :const? => false, :const_ptr? => false },
|
||||
{ :type=>"int", :name => "cmock_arg7", :ptr? => false, :const? => false, :const_ptr? => false },
|
||||
{ :type=>"int", :name => "cmock_arg8", :ptr? => false, :const? => true, :const_ptr? => false }],
|
||||
:args => [{ :type=>"int const*", :name => "cmock_arg1", :ptr? => true, :string? => false, :const? => true, :const_ptr? => false },
|
||||
{ :type=>"int*", :name => "cmock_arg2", :ptr? => true, :string? => false, :const? => false, :const_ptr? => true },
|
||||
{ :type=>"const int*", :name => "cmock_arg3", :ptr? => true, :string? => false, :const? => true, :const_ptr? => false },
|
||||
{ :type=>"const int*", :name => "cmock_arg4", :ptr? => true, :string? => false, :const? => true, :const_ptr? => true },
|
||||
{ :type=>"int const*", :name => "cmock_arg5", :ptr? => true, :string? => false, :const? => true, :const_ptr? => true },
|
||||
{ :type=>"int*", :name => "cmock_arg6", :ptr? => true, :string? => false, :const? => false, :const_ptr? => false },
|
||||
{ :type=>"int", :name => "cmock_arg7", :ptr? => false, :string? => false, :const? => false, :const_ptr? => false },
|
||||
{ :type=>"int", :name => "cmock_arg8", :ptr? => false, :string? => false, :const? => true, :const_ptr? => false }],
|
||||
:args_call => "cmock_arg1, cmock_arg2, cmock_arg3, cmock_arg4, cmock_arg5, cmock_arg6, cmock_arg7, cmock_arg8",
|
||||
:contains_ptr? => true
|
||||
}]
|
||||
@@ -1105,14 +1105,14 @@ describe CMockHeaderParser, "Verify CMockHeaderParser Module" do
|
||||
:var_arg => nil,
|
||||
:args_string => "int const* param1, int* const param2, const int* param3, const int* const param4, " +
|
||||
"int const* const param5, int* param6, int param7, const int param8",
|
||||
:args => [{ :type=>"int const*", :name => "param1", :ptr? => true, :const? => true, :const_ptr? => false },
|
||||
{ :type=>"int*", :name => "param2", :ptr? => true, :const? => false, :const_ptr? => true },
|
||||
{ :type=>"const int*", :name => "param3", :ptr? => true, :const? => true, :const_ptr? => false },
|
||||
{ :type=>"const int*", :name => "param4", :ptr? => true, :const? => true, :const_ptr? => true },
|
||||
{ :type=>"int const*", :name => "param5", :ptr? => true, :const? => true, :const_ptr? => true },
|
||||
{ :type=>"int*", :name => "param6", :ptr? => true, :const? => false, :const_ptr? => false },
|
||||
{ :type=>"int", :name => "param7", :ptr? => false, :const? => false, :const_ptr? => false },
|
||||
{ :type=>"int", :name => "param8", :ptr? => false, :const? => true, :const_ptr? => false }],
|
||||
:args => [{ :type=>"int const*", :name => "param1", :ptr? => true, :string? => false, :const? => true, :const_ptr? => false },
|
||||
{ :type=>"int*", :name => "param2", :ptr? => true, :string? => false, :const? => false, :const_ptr? => true },
|
||||
{ :type=>"const int*", :name => "param3", :ptr? => true, :string? => false, :const? => true, :const_ptr? => false },
|
||||
{ :type=>"const int*", :name => "param4", :ptr? => true, :string? => false, :const? => true, :const_ptr? => true },
|
||||
{ :type=>"int const*", :name => "param5", :ptr? => true, :string? => false, :const? => true, :const_ptr? => true },
|
||||
{ :type=>"int*", :name => "param6", :ptr? => true, :string? => false, :const? => false, :const_ptr? => false },
|
||||
{ :type=>"int", :name => "param7", :ptr? => false, :string? => false, :const? => false, :const_ptr? => false },
|
||||
{ :type=>"int", :name => "param8", :ptr? => false, :string? => false, :const? => true, :const_ptr? => false }],
|
||||
:args_call => "param1, param2, param3, param4, param5, param6, param7, param8",
|
||||
:contains_ptr? => true
|
||||
}].freeze
|
||||
@@ -1137,8 +1137,8 @@ describe CMockHeaderParser, "Verify CMockHeaderParser Module" do
|
||||
:const_ptr? => false
|
||||
},
|
||||
:var_arg => nil,
|
||||
:args => [{ :type => "Page*", :name => "book", :ptr? => true, :const? => false, :const_ptr? => false },
|
||||
{ :type => "const int*", :name => "values", :ptr? => true, :const? => true, :const_ptr? => false }],
|
||||
:args => [{ :type => "Page*", :name => "book", :ptr? => true, :string? => false, :const? => false, :const_ptr? => false },
|
||||
{ :type => "const int*", :name => "values", :ptr? => true, :string? => false, :const? => true, :const_ptr? => false }],
|
||||
:args_string => "Book book, const IntArray values",
|
||||
:args_call => "book, values",
|
||||
:contains_ptr? => true
|
||||
@@ -1170,7 +1170,7 @@ describe CMockHeaderParser, "Verify CMockHeaderParser Module" do
|
||||
},
|
||||
:modifier=>"",
|
||||
:contains_ptr? => false,
|
||||
:args=>[ {:type=>"int", :name=>"SingAlong", :ptr? => false, :const? => false, :const_ptr? => false} ],
|
||||
:args=>[ {:type=>"int", :name=>"SingAlong", :ptr? => false, :string? => false, :const? => false, :const_ptr? => false} ],
|
||||
:args_string=>"int SingAlong",
|
||||
:args_call=>"SingAlong"
|
||||
},
|
||||
@@ -1217,7 +1217,7 @@ describe CMockHeaderParser, "Verify CMockHeaderParser Module" do
|
||||
:class=>nil,
|
||||
:modifier=>"",
|
||||
:contains_ptr? => false,
|
||||
:args=>[ {:type=>"struct SingAlong", :name=>"Blog", :ptr? => false, :const? => false, :const_ptr? => false} ],
|
||||
:args=>[ {:type=>"struct SingAlong", :name=>"Blog", :ptr? => false, :string? => false, :const? => false, :const_ptr? => false} ],
|
||||
:args_string=>"struct SingAlong Blog",
|
||||
:args_call=>"Blog"
|
||||
},
|
||||
@@ -1236,7 +1236,7 @@ describe CMockHeaderParser, "Verify CMockHeaderParser Module" do
|
||||
:class=>nil,
|
||||
:modifier=>"",
|
||||
:contains_ptr? => true,
|
||||
:args=>[ {:type=>"struct const _KeepYourHeadUp_*", :name=>"BillyBuddy", :ptr? => true, :const? => true, :const_ptr? => true} ],
|
||||
:args=>[ {:type=>"struct const _KeepYourHeadUp_*", :name=>"BillyBuddy", :ptr? => true, :string? => false, :const? => true, :const_ptr? => true} ],
|
||||
:args_string=>"struct const _KeepYourHeadUp_* const BillyBuddy",
|
||||
:args_call=>"BillyBuddy"
|
||||
},
|
||||
@@ -1279,8 +1279,8 @@ describe CMockHeaderParser, "Verify CMockHeaderParser Module" do
|
||||
:class=>nil,
|
||||
:modifier=>"",
|
||||
:contains_ptr? => true,
|
||||
:args=>[ {:type=>"union STARS_AND_STRIPES*", :name=>"a", :ptr? => true, :const? => false, :const_ptr? => false},
|
||||
{:type=>"union AFL_CIO", :name=>"b", :ptr? => false, :const? => false, :const_ptr? => false}
|
||||
:args=>[ {:type=>"union STARS_AND_STRIPES*", :name=>"a", :ptr? => true, :string? => false, :const? => false, :const_ptr? => false},
|
||||
{:type=>"union AFL_CIO", :name=>"b", :ptr? => false, :string? => false, :const? => false, :const_ptr? => false}
|
||||
],
|
||||
:args_string=>"union STARS_AND_STRIPES* a, union AFL_CIO b",
|
||||
:args_call=>"a, b" }]
|
||||
@@ -1305,11 +1305,11 @@ describe CMockHeaderParser, "Verify CMockHeaderParser Module" do
|
||||
:class=>nil,
|
||||
:modifier=>"",
|
||||
:contains_ptr? => true,
|
||||
:args=>[ {:type=> "unsigned int", :name=>"const_param", :ptr? => false, :const? => true, :const_ptr? => false},
|
||||
{:type=>"int", :name=>"int_param", :ptr? => false, :const? => false, :const_ptr? => false},
|
||||
{:type=>"int", :name=>"integer", :ptr? => false, :const? => false, :const_ptr? => false},
|
||||
{:type=>"char", :name=>"character", :ptr? => false, :const? => false, :const_ptr? => false},
|
||||
{:type=>"int*", :name=>"constant", :ptr? => true, :const? => false, :const_ptr? => true}
|
||||
:args=>[ {:type=> "unsigned int", :name=>"const_param", :ptr? => false, :string? => false, :const? => true, :const_ptr? => false},
|
||||
{:type=>"int", :name=>"int_param", :ptr? => false, :string? => false, :const? => false, :const_ptr? => false},
|
||||
{:type=>"int", :name=>"integer", :ptr? => false, :string? => false, :const? => false, :const_ptr? => false},
|
||||
{:type=>"char", :name=>"character", :ptr? => false, :string? => false, :const? => false, :const_ptr? => false},
|
||||
{:type=>"int*", :name=>"constant", :ptr? => true, :string? => false, :const? => false, :const_ptr? => true}
|
||||
],
|
||||
:args_string=>"const unsigned int const_param, int int_param, int integer, char character, int* const constant",
|
||||
:args_call=>"const_param, int_param, integer, character, constant" }]
|
||||
@@ -1334,11 +1334,11 @@ describe CMockHeaderParser, "Verify CMockHeaderParser Module" do
|
||||
:class=>nil,
|
||||
:modifier=>"",
|
||||
:contains_ptr? => true,
|
||||
:args=>[ {:type=>"integer", :name=>"param", :ptr? => false, :const? => false, :const_ptr? => false},
|
||||
{:type=>"character", :name=>"thing", :ptr? => false, :const? => false, :const_ptr? => false},
|
||||
{:type=>"longint*", :name=>"junk", :ptr? => true, :const? => false, :const_ptr? => false},
|
||||
{:type=>"constant", :name=>"value", :ptr? => false, :const? => false, :const_ptr? => false},
|
||||
{:type=>"int32_t", :name=>"number", :ptr? => false, :const? => true, :const_ptr? => false}
|
||||
:args=>[ {:type=>"integer", :name=>"param", :ptr? => false, :string? => false, :const? => false, :const_ptr? => false},
|
||||
{:type=>"character", :name=>"thing", :ptr? => false, :string? => false, :const? => false, :const_ptr? => false},
|
||||
{:type=>"longint*", :name=>"junk", :ptr? => true, :string? => false, :const? => false, :const_ptr? => false},
|
||||
{:type=>"constant", :name=>"value", :ptr? => false, :string? => false, :const? => false, :const_ptr? => false},
|
||||
{:type=>"int32_t", :name=>"number", :ptr? => false, :string? => false, :const? => true, :const_ptr? => false}
|
||||
],
|
||||
:args_string=>"integer param, character thing, longint* junk, constant value, int32_t const number",
|
||||
:args_call=>"param, thing, junk, value, number" }]
|
||||
@@ -1363,10 +1363,10 @@ describe CMockHeaderParser, "Verify CMockHeaderParser Module" do
|
||||
:class=>nil,
|
||||
:modifier=>"",
|
||||
:contains_ptr? => false,
|
||||
:args=>[ {:type=>"signed char", :name=>"abc", :ptr? => false, :const? => false, :const_ptr? => false},
|
||||
{:type=>"unsigned long int", :name=>"xyz_123", :ptr? => false, :const? => true, :const_ptr? => false},
|
||||
{:type=>"unsigned int", :name=>"abc_123", :ptr? => false, :const? => true, :const_ptr? => false},
|
||||
{:type=>"long long", :name=>"arm_of_the_law", :ptr? => false, :const? => false, :const_ptr? => false}
|
||||
:args=>[ {:type=>"signed char", :name=>"abc", :ptr? => false, :string? => false, :const? => false, :const_ptr? => false},
|
||||
{:type=>"unsigned long int", :name=>"xyz_123", :ptr? => false, :string? => false, :const? => true, :const_ptr? => false},
|
||||
{:type=>"unsigned int", :name=>"abc_123", :ptr? => false, :string? => false, :const? => true, :const_ptr? => false},
|
||||
{:type=>"long long", :name=>"arm_of_the_law", :ptr? => false, :string? => false, :const? => false, :const_ptr? => false}
|
||||
],
|
||||
:args_string=>"signed char abc, const unsigned long int xyz_123, unsigned int const abc_123, long long arm_of_the_law",
|
||||
:args_call=>"abc, xyz_123, abc_123, arm_of_the_law" }]
|
||||
@@ -1391,10 +1391,10 @@ describe CMockHeaderParser, "Verify CMockHeaderParser Module" do
|
||||
:class=>nil,
|
||||
:modifier=>"",
|
||||
:contains_ptr? => true,
|
||||
:args=>[ {:type=>"CUSTOM_TYPE", :name=>"abc", :ptr? => false, :const? => false, :const_ptr? => false},
|
||||
{:type=>"CUSTOM_TYPE*", :name=>"xyz_123", :ptr? => true, :const? => false, :const_ptr? => false},
|
||||
{:type=>"CUSTOM_TYPE", :name=>"abcxyz", :ptr? => false, :const? => true, :const_ptr? => false},
|
||||
{:type=>"struct CUSTOM_TYPE const*", :name=>"abc123", :ptr? => true, :const? => true, :const_ptr? => true}
|
||||
:args=>[ {:type=>"CUSTOM_TYPE", :name=>"abc", :ptr? => false, :string? => false, :const? => false, :const_ptr? => false},
|
||||
{:type=>"CUSTOM_TYPE*", :name=>"xyz_123", :ptr? => true, :string? => false, :const? => false, :const_ptr? => false},
|
||||
{:type=>"CUSTOM_TYPE", :name=>"abcxyz", :ptr? => false, :string? => false, :const? => true, :const_ptr? => false},
|
||||
{:type=>"struct CUSTOM_TYPE const*", :name=>"abc123", :ptr? => true, :string? => false, :const? => true, :const_ptr? => true}
|
||||
],
|
||||
:args_string=>"CUSTOM_TYPE abc, CUSTOM_TYPE* xyz_123, CUSTOM_TYPE const abcxyz, struct CUSTOM_TYPE const* const abc123",
|
||||
:args_call=>"abc, xyz_123, abcxyz, abc123" }]
|
||||
@@ -1406,13 +1406,11 @@ describe CMockHeaderParser, "Verify CMockHeaderParser Module" do
|
||||
source = 'void KeyOperated(CUSTOM_TYPE thing1[], int thing2 [ ], ' \
|
||||
'char thing3 [][2 ][ 3], int* thing4[4], u8 thing5[((u8)((5 + 5*2)/3))])'
|
||||
expected_args = [
|
||||
{ type: 'CUSTOM_TYPE*', name: 'thing1', ptr?: true, const?: false, const_ptr?: false },
|
||||
{ type: 'int*', name: 'thing2', ptr?: true, const?: false, const_ptr?: false },
|
||||
# this one will likely change in the future when we improve multidimensional array support
|
||||
{ type: 'char*', name: 'thing3', ptr?: false, const?: false, const_ptr?: false },
|
||||
# this one will likely change in the future when we improve multidimensional array support
|
||||
{ type: 'int**', name: 'thing4', ptr?: true, const?: false, const_ptr?: false },
|
||||
{ type: 'u8*', name: 'thing5', ptr?: true, const?: false, const_ptr?: false }
|
||||
{ type: 'CUSTOM_TYPE*', name: 'thing1', ptr?: true, string?: false, const?: false, const_ptr?: false, array_dims: [''] },
|
||||
{ type: 'int*', name: 'thing2', ptr?: true, string?: false, const?: false, const_ptr?: false, array_dims: [''] },
|
||||
{ type: 'char*', name: 'thing3', ptr?: false, string?: true, const?: false, const_ptr?: false, array_dims: ['', '2', '3'] },
|
||||
{ type: 'int**', name: 'thing4', ptr?: true, string?: false, const?: false, const_ptr?: false, array_dims: ['4'] },
|
||||
{ type: 'u8*', name: 'thing5', ptr?: true, string?: false, const?: false, const_ptr?: false, array_dims: ['((u8)((5 + 5*2)/3))'] }
|
||||
]
|
||||
expected = [{:var_arg=>nil,
|
||||
:return=>{ :type => "void",
|
||||
@@ -1430,8 +1428,7 @@ describe CMockHeaderParser, "Verify CMockHeaderParser Module" do
|
||||
:modifier=>"",
|
||||
:contains_ptr? => true,
|
||||
:args => expected_args,
|
||||
:args_string => 'CUSTOM_TYPE* thing1, int* thing2, ' \
|
||||
'char* thing3, int** thing4, u8* thing5',
|
||||
:args_string => 'CUSTOM_TYPE thing1[], int thing2[], char thing3[][2][3], int* thing4[4], u8 thing5[((u8)((5 + 5*2)/3))]',
|
||||
:args_call => 'thing1, thing2, thing3, thing4, thing5' }]
|
||||
result = @parser.parse("module", source)
|
||||
assert_equal(expected, result[:functions])
|
||||
@@ -1454,9 +1451,9 @@ describe CMockHeaderParser, "Verify CMockHeaderParser Module" do
|
||||
:class=>nil,
|
||||
:modifier=>"",
|
||||
:contains_ptr? => false,
|
||||
:args=>[ {:type=>"unsigned CUSTOM_TYPE", :name=>"abc", :ptr? => false, :const? => false, :const_ptr? => false},
|
||||
{:type=>"unsigned", :name=>"xyz", :ptr? => false, :const? => false, :const_ptr? => false},
|
||||
{:type=>"CUSTOM_TYPE1 CUSTOM_TYPE2", :name=>"pdq", :ptr? => false, :const? => false, :const_ptr? => false}
|
||||
:args=>[ {:type=>"unsigned CUSTOM_TYPE", :name=>"abc", :ptr? => false, :string? => false, :const? => false, :const_ptr? => false},
|
||||
{:type=>"unsigned", :name=>"xyz", :ptr? => false, :string? => false, :const? => false, :const_ptr? => false},
|
||||
{:type=>"CUSTOM_TYPE1 CUSTOM_TYPE2", :name=>"pdq", :ptr? => false, :string? => false, :const? => false, :const_ptr? => false}
|
||||
],
|
||||
:args_string=>"unsigned CUSTOM_TYPE abc, unsigned xyz, CUSTOM_TYPE1 CUSTOM_TYPE2 pdq",
|
||||
:args_call=>"abc, xyz, pdq" }]
|
||||
@@ -1481,7 +1478,7 @@ describe CMockHeaderParser, "Verify CMockHeaderParser Module" do
|
||||
:class=>nil,
|
||||
:modifier=>"",
|
||||
:contains_ptr? => false,
|
||||
:args=>[ {:type=>"cmock_module_func_ptr1", :name=>"func_ptr", :ptr? => false, :const? => false, :const_ptr? => false}
|
||||
:args=>[ {:type=>"cmock_module_func_ptr1", :name=>"func_ptr", :ptr? => false, :string? => false, :const? => false, :const_ptr? => false}
|
||||
],
|
||||
:args_string=>"cmock_module_func_ptr1 func_ptr",
|
||||
:args_call=>"func_ptr" }]
|
||||
@@ -1508,7 +1505,7 @@ describe CMockHeaderParser, "Verify CMockHeaderParser Module" do
|
||||
:class=>nil,
|
||||
:modifier=>"",
|
||||
:contains_ptr? => false,
|
||||
:args=>[ {:type=>"cmock_module_func_ptr1", :name=>"func_ptr", :ptr? => false, :const? => false, :const_ptr? => false}
|
||||
:args=>[ {:type=>"cmock_module_func_ptr1", :name=>"func_ptr", :ptr? => false, :string? => false, :const? => false, :const_ptr? => false}
|
||||
],
|
||||
:args_string=>"cmock_module_func_ptr1 func_ptr",
|
||||
:args_call=>"func_ptr" }]
|
||||
@@ -1535,7 +1532,7 @@ describe CMockHeaderParser, "Verify CMockHeaderParser Module" do
|
||||
:class=>nil,
|
||||
:modifier=>"",
|
||||
:contains_ptr? => false,
|
||||
:args=>[ {:type=>"cmock_module_func_ptr1", :name=>"func_ptr", :ptr? => false, :const? => false, :const_ptr? => false}
|
||||
:args=>[ {:type=>"cmock_module_func_ptr1", :name=>"func_ptr", :ptr? => false, :string? => false, :const? => false, :const_ptr? => false}
|
||||
],
|
||||
:args_string=>"cmock_module_func_ptr1 func_ptr",
|
||||
:args_call=>"func_ptr" }]
|
||||
@@ -1562,7 +1559,7 @@ describe CMockHeaderParser, "Verify CMockHeaderParser Module" do
|
||||
:class=>nil,
|
||||
:modifier=>"",
|
||||
:contains_ptr? => false,
|
||||
:args=>[ {:type=>"cmock_module_func_ptr1", :name=>"func_ptr", :ptr? => false, :const? => false, :const_ptr? => false}
|
||||
:args=>[ {:type=>"cmock_module_func_ptr1", :name=>"func_ptr", :ptr? => false, :string? => false, :const? => false, :const_ptr? => false}
|
||||
],
|
||||
:args_string=>"cmock_module_func_ptr1 func_ptr",
|
||||
:args_call=>"func_ptr" }]
|
||||
@@ -1589,7 +1586,7 @@ describe CMockHeaderParser, "Verify CMockHeaderParser Module" do
|
||||
:class=>nil,
|
||||
:modifier=>"",
|
||||
:contains_ptr? => false,
|
||||
:args=>[ {:type=>"cmock_module_func_ptr1", :name=>"func_ptr", :ptr? => false, :const? => true, :const_ptr? => false}
|
||||
:args=>[ {:type=>"cmock_module_func_ptr1", :name=>"func_ptr", :ptr? => false, :string? => false, :const? => true, :const_ptr? => false}
|
||||
],
|
||||
:args_string=>"cmock_module_func_ptr1 const func_ptr",
|
||||
:args_call=>"func_ptr" }]
|
||||
@@ -1604,7 +1601,7 @@ describe CMockHeaderParser, "Verify CMockHeaderParser Module" do
|
||||
# expected = [{ :var_arg=>nil,
|
||||
# :return=>{ :type => "void",
|
||||
# :name => 'cmock_to_return',
|
||||
# :ptr? => false,
|
||||
# :ptr? => false, :string? => false,
|
||||
# :const? => false,
|
||||
# :const_ptr? => false,
|
||||
# :str => "void cmock_to_return",
|
||||
@@ -1616,7 +1613,7 @@ describe CMockHeaderParser, "Verify CMockHeaderParser Module" do
|
||||
# :class=>nil,
|
||||
# :modifier=>"",
|
||||
# :contains_ptr? => false,
|
||||
# :args=>[ {:type=>"cmock_module_func_ptr1", :name=>"func_ptr", :ptr? => false, :const? => false, :const_ptr? => false}
|
||||
# :args=>[ {:type=>"cmock_module_func_ptr1", :name=>"func_ptr", :ptr? => false, :string? => false, :const? => false, :const_ptr? => false}
|
||||
# ],
|
||||
# :args_string=>"cmock_module_func_ptr1 func_ptr",
|
||||
# :args_call=>"func_ptr" }]
|
||||
@@ -1643,8 +1640,8 @@ describe CMockHeaderParser, "Verify CMockHeaderParser Module" do
|
||||
:class=>nil,
|
||||
:modifier=>"",
|
||||
:contains_ptr? => false,
|
||||
:args=>[ {:type=>"cmock_module_func_ptr1", :name=>"func_ptr1", :ptr? => false, :const? => false, :const_ptr? => false},
|
||||
{:type=>"cmock_module_func_ptr2", :name=>"func_ptr2", :ptr? => false, :const? => false, :const_ptr? => false}
|
||||
:args=>[ {:type=>"cmock_module_func_ptr1", :name=>"func_ptr1", :ptr? => false, :string? => false, :const? => false, :const_ptr? => false},
|
||||
{:type=>"cmock_module_func_ptr2", :name=>"func_ptr2", :ptr? => false, :string? => false, :const? => false, :const_ptr? => false}
|
||||
],
|
||||
:args_string=>"cmock_module_func_ptr1 func_ptr1, cmock_module_func_ptr2 func_ptr2",
|
||||
:args_call=>"func_ptr1, func_ptr2" }]
|
||||
@@ -1671,9 +1668,9 @@ describe CMockHeaderParser, "Verify CMockHeaderParser Module" do
|
||||
:class=>nil,
|
||||
:modifier=>"",
|
||||
:contains_ptr? => false,
|
||||
:args=>[ {:type=>"uint16_t", :name=>"num1", :ptr? => false, :const? => false, :const_ptr? => false},
|
||||
{:type=>"uint16_t", :name=>"num2", :ptr? => false, :const? => false, :const_ptr? => false},
|
||||
{:type=>"cmock_module_func_ptr1", :name=>"func_ptr1", :ptr? => false, :const? => false, :const_ptr? => false}
|
||||
:args=>[ {:type=>"uint16_t", :name=>"num1", :ptr? => false, :string? => false, :const? => false, :const_ptr? => false},
|
||||
{:type=>"uint16_t", :name=>"num2", :ptr? => false, :string? => false, :const? => false, :const_ptr? => false},
|
||||
{:type=>"cmock_module_func_ptr1", :name=>"func_ptr1", :ptr? => false, :string? => false, :const? => false, :const_ptr? => false}
|
||||
],
|
||||
:args_string=>"uint16_t num1, uint16_t num2, cmock_module_func_ptr1 func_ptr1",
|
||||
:args_call=>"num1, num2, func_ptr1" }]
|
||||
@@ -1700,7 +1697,7 @@ describe CMockHeaderParser, "Verify CMockHeaderParser Module" do
|
||||
:class=>nil,
|
||||
:modifier=>"",
|
||||
:contains_ptr? => false,
|
||||
:args=>[ {:type=>"cmock_module_func_ptr1", :name=>"cmock_arg1", :ptr? => false, :const? => true, :const_ptr? => false}
|
||||
:args=>[ {:type=>"cmock_module_func_ptr1", :name=>"cmock_arg1", :ptr? => false, :string? => false, :const? => true, :const_ptr? => false}
|
||||
],
|
||||
:args_string=>"cmock_module_func_ptr1 const cmock_arg1",
|
||||
:args_call=>"cmock_arg1" }]
|
||||
@@ -1727,7 +1724,7 @@ describe CMockHeaderParser, "Verify CMockHeaderParser Module" do
|
||||
:class=>nil,
|
||||
:modifier=>"",
|
||||
:contains_ptr? => false,
|
||||
:args=>[ {:type=>"char", :name=>"op_code", :ptr? => false, :const? => true, :const_ptr? => false}
|
||||
:args=>[ {:type=>"char", :name=>"op_code", :ptr? => false, :string? => false, :const? => true, :const_ptr? => false}
|
||||
],
|
||||
:args_string=>"const char op_code",
|
||||
:args_call=>"op_code" }]
|
||||
@@ -1806,8 +1803,8 @@ describe CMockHeaderParser, "Verify CMockHeaderParser Module" do
|
||||
:class=>nil,
|
||||
:modifier=>"",
|
||||
:contains_ptr? => true,
|
||||
:args=>[ {:type=>"double*", :name=>"foo", :ptr? => true, :const? => false, :const_ptr? => false},
|
||||
{:type=>"THING*", :name=>"bar", :ptr? => true, :const? => false, :const_ptr? => false}
|
||||
:args=>[ {:type=>"double*", :name=>"foo", :ptr? => true, :string? => false, :const? => false, :const_ptr? => false},
|
||||
{:type=>"THING*", :name=>"bar", :ptr? => true, :string? => false, :const? => false, :const_ptr? => false}
|
||||
],
|
||||
:args_string=>"double* foo, THING* bar",
|
||||
:args_call=>"foo, bar" }]
|
||||
@@ -1834,11 +1831,11 @@ describe CMockHeaderParser, "Verify CMockHeaderParser Module" do
|
||||
:class=>nil,
|
||||
:modifier=>"SQLITE_API",
|
||||
:contains_ptr? => true,
|
||||
:args=>[ {:type=>"sqlite3_stmt*", :name=>"cmock_arg2", :ptr? => true, :const? => false, :const_ptr? => false},
|
||||
{:type=>"int", :name=>"cmock_arg3", :ptr? => false, :const? => false, :const_ptr? => false},
|
||||
{:type=>"const char*", :name=>"cmock_arg4", :ptr? => false, :const? => true, :const_ptr? => false},
|
||||
{:type=>"int", :name=>"n", :ptr? => false, :const? => false, :const_ptr? => false},
|
||||
{:type=>"cmock_module_func_ptr1", :name=>"cmock_arg1", :ptr? => false, :const? => false, :const_ptr? => false}
|
||||
:args=>[ {:type=>"sqlite3_stmt*", :name=>"cmock_arg2", :ptr? => true, :string? => false, :const? => false, :const_ptr? => false},
|
||||
{:type=>"int", :name=>"cmock_arg3", :ptr? => false, :string? => false, :const? => false, :const_ptr? => false},
|
||||
{:type=>"const char*", :name=>"cmock_arg4", :ptr? => false, :string? => true, :const? => true, :const_ptr? => false},
|
||||
{:type=>"int", :name=>"n", :ptr? => false, :string? => false, :const? => false, :const_ptr? => false},
|
||||
{:type=>"cmock_module_func_ptr1", :name=>"cmock_arg1", :ptr? => false, :string? => false, :const? => false, :const_ptr? => false}
|
||||
],
|
||||
:args_string=>"sqlite3_stmt* cmock_arg2, int cmock_arg3, const char* cmock_arg4, int n, cmock_module_func_ptr1 cmock_arg1",
|
||||
:args_call=>"cmock_arg2, cmock_arg3, cmock_arg4, n, cmock_arg1" }]
|
||||
@@ -1865,8 +1862,8 @@ describe CMockHeaderParser, "Verify CMockHeaderParser Module" do
|
||||
:class=>nil,
|
||||
:modifier=>"",
|
||||
:contains_ptr? => false,
|
||||
:args=>[ {:type=>"int", :name=>"Scully", :ptr? => false, :const? => false, :const_ptr? => false},
|
||||
{:type=>"int", :name=>"Mulder", :ptr? => false, :const? => false, :const_ptr? => false}
|
||||
:args=>[ {:type=>"int", :name=>"Scully", :ptr? => false, :string? => false, :const? => false, :const_ptr? => false},
|
||||
{:type=>"int", :name=>"Mulder", :ptr? => false, :string? => false, :const? => false, :const_ptr? => false}
|
||||
],
|
||||
:args_string=>"int Scully, int Mulder",
|
||||
:args_call=>"Scully, Mulder"
|
||||
@@ -1891,7 +1888,7 @@ describe CMockHeaderParser, "Verify CMockHeaderParser Module" do
|
||||
:class=>nil,
|
||||
:modifier=>"",
|
||||
:contains_ptr? => true,
|
||||
:args=>[ {:type=>"void*", :name=>"stuff", :ptr? => true, :const? => false, :const_ptr? => false}
|
||||
:args=>[ {:type=>"void*", :name=>"stuff", :ptr? => true, :string? => false, :const? => false, :const_ptr? => false}
|
||||
],
|
||||
:args_string=>"void* stuff",
|
||||
:args_call=>"stuff"
|
||||
@@ -1916,8 +1913,8 @@ describe CMockHeaderParser, "Verify CMockHeaderParser Module" do
|
||||
:class=>nil,
|
||||
:modifier=>"",
|
||||
:contains_ptr? => false,
|
||||
:args=>[ {:type=>"int", :name=>"Lenny", :ptr? => false, :const? => false, :const_ptr? => false},
|
||||
{:type=>"int", :name=>"Squiggy", :ptr? => false, :const? => false, :const_ptr? => false}
|
||||
:args=>[ {:type=>"int", :name=>"Lenny", :ptr? => false, :string? => false, :const? => false, :const_ptr? => false},
|
||||
{:type=>"int", :name=>"Squiggy", :ptr? => false, :string? => false, :const? => false, :const_ptr? => false}
|
||||
],
|
||||
:args_string=>"int Lenny, int Squiggy",
|
||||
:args_call=>"Lenny, Squiggy"
|
||||
@@ -1942,8 +1939,8 @@ describe CMockHeaderParser, "Verify CMockHeaderParser Module" do
|
||||
:class=>nil,
|
||||
:modifier=>"",
|
||||
:contains_ptr? => false,
|
||||
:args=>[ {:type=>"int", :name=>"Cliff", :ptr? => false, :const? => false, :const_ptr? => false},
|
||||
{:type=>"int", :name=>"Claire", :ptr? => false, :const? => false, :const_ptr? => false}
|
||||
:args=>[ {:type=>"int", :name=>"Cliff", :ptr? => false, :string? => false, :const? => false, :const_ptr? => false},
|
||||
{:type=>"int", :name=>"Claire", :ptr? => false, :string? => false, :const? => false, :const_ptr? => false}
|
||||
],
|
||||
:args_string=>"int Cliff, int Claire",
|
||||
:args_call=>"Cliff, Claire"
|
||||
@@ -1981,7 +1978,7 @@ describe CMockHeaderParser, "Verify CMockHeaderParser Module" do
|
||||
assert_equal(@parser.divine_ptr(entry[0]), entry[1])
|
||||
assert_equal(@parser.divine_const(entry[0]), entry[2])
|
||||
assert_equal(@parser.divine_ptr_and_const(entry[0]),
|
||||
{ ptr?: entry[1], const?: entry[2], const_ptr?: entry[3] })
|
||||
{ ptr?: entry[1], string?: false, const?: entry[2], const_ptr?: entry[3] })
|
||||
end
|
||||
end
|
||||
|
||||
@@ -2348,8 +2345,8 @@ describe CMockHeaderParser, "Verify CMockHeaderParser Module" do
|
||||
:class=>nil,
|
||||
:modifier=>"",
|
||||
:contains_ptr? => false,
|
||||
:args=>[ {:type=>"int", :name=>"Lenny", :ptr? => false, :const? => false, :const_ptr? => false},
|
||||
{:type=>"int", :name=>"Squiggy", :ptr? => false, :const? => false, :const_ptr? => false}
|
||||
:args=>[ {:type=>"int", :name=>"Lenny", :ptr? => false, :string? => false, :const? => false, :const_ptr? => false},
|
||||
{:type=>"int", :name=>"Squiggy", :ptr? => false, :string? => false, :const? => false, :const_ptr? => false}
|
||||
],
|
||||
:args_string=>"int Lenny, int Squiggy",
|
||||
:args_call=>"Lenny, Squiggy"
|
||||
@@ -2592,7 +2589,7 @@ describe CMockHeaderParser, "Verify CMockHeaderParser Module" do
|
||||
:var_arg => nil,
|
||||
:args_string => "int a",
|
||||
:args => [
|
||||
{ :ptr? => false,
|
||||
{ :ptr? => false, :string? => false,
|
||||
:const? => false,
|
||||
:const_ptr? => false,
|
||||
:name => "a",
|
||||
@@ -2615,7 +2612,7 @@ describe CMockHeaderParser, "Verify CMockHeaderParser Module" do
|
||||
:var_arg => nil,
|
||||
:args_string => "int* a",
|
||||
:args => [
|
||||
{ :ptr? => true,
|
||||
{ :ptr? => true, :string? => false,
|
||||
:const? => false,
|
||||
:const_ptr? => false,
|
||||
:name => "a",
|
||||
@@ -2664,7 +2661,7 @@ describe CMockHeaderParser, "Verify CMockHeaderParser Module" do
|
||||
:var_arg => nil,
|
||||
:args_string => "int a",
|
||||
:args => [
|
||||
{ :ptr? => false,
|
||||
{ :ptr? => false, :string? => false,
|
||||
:const? => false,
|
||||
:const_ptr? => false,
|
||||
:name => "a",
|
||||
@@ -2687,7 +2684,7 @@ describe CMockHeaderParser, "Verify CMockHeaderParser Module" do
|
||||
:var_arg => nil,
|
||||
:args_string => "int* a",
|
||||
:args => [
|
||||
{ :ptr? => true,
|
||||
{ :ptr? => true, :string? => false,
|
||||
:const? => false,
|
||||
:const_ptr? => false,
|
||||
:name => "a",
|
||||
@@ -2882,5 +2879,128 @@ describe CMockHeaderParser, "Verify CMockHeaderParser Module" do
|
||||
assert_equal(expected, @parser.transform_inline_functions(source))
|
||||
end
|
||||
|
||||
it "pairs size arg with adjacent pointer when no name affinity exists" do
|
||||
source = "void process(int *data, int size)"
|
||||
|
||||
result = @parser.parse("module", source)
|
||||
args = result[:functions].first[:args]
|
||||
|
||||
data_arg = args.find { |a| a[:name] == 'data' }
|
||||
size_arg = args.find { |a| a[:name] == 'size' }
|
||||
|
||||
assert_equal(:after, data_arg[:array_size_order], "data should be paired with size (after)")
|
||||
assert_equal(true, size_arg[:array_size?], "size should be marked as array_size?")
|
||||
end
|
||||
|
||||
it "pairs size arg with the pointer whose name it matches, even when a different pointer is adjacent" do
|
||||
# buf_size is adjacent to status, but 'buf' root matches 'buf' exactly
|
||||
source = "void store(int *status, int buf_size, int *buf)"
|
||||
|
||||
result = @parser.parse("module", source)
|
||||
args = result[:functions].first[:args]
|
||||
|
||||
status_arg = args.find { |a| a[:name] == 'status' }
|
||||
buf_size_arg = args.find { |a| a[:name] == 'buf_size' }
|
||||
buf_arg = args.find { |a| a[:name] == 'buf' }
|
||||
|
||||
assert_nil(status_arg[:array_size_order], "status should NOT be paired")
|
||||
assert_equal(:before, buf_arg[:array_size_order], "buf should be paired with size (before)")
|
||||
assert_equal(true, buf_size_arg[:array_size?], "buf_size should be marked as array_size?")
|
||||
end
|
||||
|
||||
it "pairs size arg with pointer that comes after it when name affinity is stronger than adjacency" do
|
||||
# buff_size is adjacent to bytes_to_read, but 'buff' root is a prefix of 'buffer'
|
||||
source = "void read_interface(size_t *bytes_to_read, size_t buff_size, char **buffer)"
|
||||
|
||||
result = @parser.parse("module", source)
|
||||
args = result[:functions].first[:args]
|
||||
|
||||
bytes_arg = args.find { |a| a[:name] == 'bytes_to_read' }
|
||||
buff_size_arg = args.find { |a| a[:name] == 'buff_size' }
|
||||
buffer_arg = args.find { |a| a[:name] == 'buffer' }
|
||||
|
||||
assert_nil(bytes_arg[:array_size_order], "bytes_to_read should NOT be paired")
|
||||
assert_equal(:before, buffer_arg[:array_size_order], "buffer should be paired with size (before)")
|
||||
assert_equal(true, buff_size_arg[:array_size?], "buff_size should be marked as array_size?")
|
||||
end
|
||||
|
||||
it "pairs multiple size args each with their best-matched pointer" do
|
||||
source = "void copy(int *dst, int dst_len, int *src, int src_len)"
|
||||
|
||||
result = @parser.parse("module", source)
|
||||
args = result[:functions].first[:args]
|
||||
|
||||
dst_arg = args.find { |a| a[:name] == 'dst' }
|
||||
dst_len_arg = args.find { |a| a[:name] == 'dst_len' }
|
||||
src_arg = args.find { |a| a[:name] == 'src' }
|
||||
src_len_arg = args.find { |a| a[:name] == 'src_len' }
|
||||
|
||||
assert_equal(:after, dst_arg[:array_size_order], "dst should be paired with size (after)")
|
||||
assert_equal(true, dst_len_arg[:array_size?], "dst_len should be marked as array_size?")
|
||||
assert_equal(:after, src_arg[:array_size_order], "src should be paired with size (after)")
|
||||
assert_equal(true, src_len_arg[:array_size?], "src_len should be marked as array_size?")
|
||||
end
|
||||
|
||||
it "pairs size arg with adjacent array when no name affinity exists" do
|
||||
source = "void process(int data[], int size)"
|
||||
|
||||
result = @parser.parse("module", source)
|
||||
args = result[:functions].first[:args]
|
||||
|
||||
data_arg = args.find { |a| a[:name] == 'data' }
|
||||
size_arg = args.find { |a| a[:name] == 'size' }
|
||||
|
||||
assert_equal(:after, data_arg[:array_size_order], "data should be paired with size (after)")
|
||||
assert_equal(true, size_arg[:array_size?], "size should be marked as array_size?")
|
||||
end
|
||||
|
||||
it "pairs size arg with the array whose name it matches, even when a different pointer is adjacent" do
|
||||
# buf_size is adjacent to status, but 'buf' root matches 'buf' exactly
|
||||
source = "void store(int status[], int buf_size, int buf[])"
|
||||
|
||||
result = @parser.parse("module", source)
|
||||
args = result[:functions].first[:args]
|
||||
|
||||
status_arg = args.find { |a| a[:name] == 'status' }
|
||||
buf_size_arg = args.find { |a| a[:name] == 'buf_size' }
|
||||
buf_arg = args.find { |a| a[:name] == 'buf' }
|
||||
|
||||
assert_nil(status_arg[:array_size_order], "status should NOT be paired")
|
||||
assert_equal(:before, buf_arg[:array_size_order], "buf should be paired with size (before)")
|
||||
assert_equal(true, buf_size_arg[:array_size?], "buf_size should be marked as array_size?")
|
||||
end
|
||||
|
||||
it "pairs size arg with array that comes after it when name affinity is stronger than adjacency" do
|
||||
# buff_size is adjacent to bytes_to_read, but 'buff' root is a prefix of 'buffer'
|
||||
source = "void read_interface(size_t bytes_to_read[], size_t buff_size, char *buffer[])"
|
||||
|
||||
result = @parser.parse("module", source)
|
||||
args = result[:functions].first[:args]
|
||||
|
||||
bytes_arg = args.find { |a| a[:name] == 'bytes_to_read' }
|
||||
buff_size_arg = args.find { |a| a[:name] == 'buff_size' }
|
||||
buffer_arg = args.find { |a| a[:name] == 'buffer' }
|
||||
|
||||
assert_nil(bytes_arg[:array_size_order], "bytes_to_read should NOT be paired")
|
||||
assert_equal(:before, buffer_arg[:array_size_order], "buffer should be paired with size (before)")
|
||||
assert_equal(true, buff_size_arg[:array_size?], "buff_size should be marked as array_size?")
|
||||
end
|
||||
|
||||
it "pairs multiple size args each with their best-matched array" do
|
||||
source = "void copy(int dst[], int dst_len, int src[], int src_len)"
|
||||
|
||||
result = @parser.parse("module", source)
|
||||
args = result[:functions].first[:args]
|
||||
|
||||
dst_arg = args.find { |a| a[:name] == 'dst' }
|
||||
dst_len_arg = args.find { |a| a[:name] == 'dst_len' }
|
||||
src_arg = args.find { |a| a[:name] == 'src' }
|
||||
src_len_arg = args.find { |a| a[:name] == 'src_len' }
|
||||
|
||||
assert_equal(:after, dst_arg[:array_size_order], "dst should be paired with size (after)")
|
||||
assert_equal(true, dst_len_arg[:array_size?], "dst_len should be marked as array_size?")
|
||||
assert_equal(:after, src_arg[:array_size_order], "src should be paired with size (after)")
|
||||
assert_equal(true, src_len_arg[:array_size?], "src_len should be marked as array_size?")
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user