mirror of
https://github.com/ThrowTheSwitch/CMock.git
synced 2026-06-23 05:50:32 +00:00
Compare commits
28 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| d482f56066 | |||
| 1ef72ca854 | |||
| 85058d1407 | |||
| 411f6852f9 | |||
| 383c43246c | |||
| 990954c548 | |||
| de4e53cd7b | |||
| 84705b2e84 | |||
| 336a52bf57 | |||
| aaf9559a57 | |||
| 8c1f88fb82 | |||
| a0207f3800 | |||
| bad95c5f54 | |||
| f756eeaf55 | |||
| 82ef7e53cf | |||
| af610445b3 | |||
| a0de150635 | |||
| 3d4ddfdc4c | |||
| 29ef16e54b | |||
| 725e2d90ef | |||
| c06bbe791c | |||
| c40a6e08c6 | |||
| 5f0296eb0a | |||
| 165de30b7d | |||
| 04b5b21ffd | |||
| f20c59b029 | |||
| 6a9e3afe14 | |||
| 13da43dc95 |
+63
-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:
|
||||
-------
|
||||
@@ -357,6 +378,23 @@ generate a skeleton instead:
|
||||
ruby cmock.rb --skeleton ../create/c/for/this.h
|
||||
```
|
||||
|
||||
Using CMock Without Ceedling
|
||||
----------------------------
|
||||
|
||||
CMock depends on the Unity test framework, but it does not *require* Ceedling. You can use the
|
||||
generated mocks directly with the Unity test framework in whatever build system you prefer. One
|
||||
important thing to remember when doing this is that you will need to call the `_Init` function
|
||||
for each of your mocks BEFORE the tests and the `_Verify` function for each mock AFTER each test.
|
||||
This allows CMock to perform all of its internal accounting. If you're running into problems where
|
||||
some errors aren't getting caught, this is likely what you are missing.
|
||||
|
||||
There are many ways to accomplish this. Any is valid:
|
||||
|
||||
- These actions can be performed as part of `setUp` and `tearDown` in each test file
|
||||
- You can hand-write your own RUN_TEST macro. If so, protect `_Verify` calls in `TEST_PROTECT`
|
||||
- You can use Unity's test runner generator and it will automatically take care of this for you.
|
||||
- You can use Ceedling and it will automatically take care of this for you.
|
||||
|
||||
Config Options:
|
||||
---------------
|
||||
|
||||
@@ -722,11 +760,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 +775,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
|
||||
|
||||
@@ -14,7 +14,7 @@ all: setup test ${BUILD_DIR}/main run
|
||||
setup:
|
||||
mkdir -p ${BUILD_DIR}
|
||||
mkdir -p ${OBJ}
|
||||
ruby ../../scripts/create_makefile.rb --silent
|
||||
ruby ../../scripts/create_makefile.rb
|
||||
|
||||
clean:
|
||||
rm -rf ${BUILD_DIR}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
========================================================================= */
|
||||
|
||||
#include "unity.h"
|
||||
#include "mock_foo.h"
|
||||
#include "Mockfoo.h"
|
||||
|
||||
void setUp(void)
|
||||
{
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
:executable: '.exe'
|
||||
|
||||
:defines:
|
||||
:common:
|
||||
:test:
|
||||
- __monitor
|
||||
- UNITY_SUPPORT_64
|
||||
|
||||
|
||||
@@ -39,24 +39,38 @@ module RakefileHelpers
|
||||
$cfg_file = config_file
|
||||
$proj = load_yaml(File.read('./project.yml'))
|
||||
|
||||
unity_target = "../../vendor/unity/test/targets/#{$cfg_file}"
|
||||
unity_targets_dir = '../../vendor/unity/test/targets'
|
||||
cmock_targets_dir = '../../test/targets'
|
||||
config_basename = File.basename(config_file)
|
||||
path_specified = File.dirname(config_file) != '.'
|
||||
|
||||
# Resolve the target file location:
|
||||
# - path specified → use only that location
|
||||
# - no path → check current directory first, then vendor unity targets
|
||||
unity_target = if path_specified
|
||||
config_file
|
||||
elsif File.exist?("./#{config_file}")
|
||||
"./#{config_file}"
|
||||
else
|
||||
"#{unity_targets_dir}/#{config_file}"
|
||||
end
|
||||
|
||||
if File.exist?(unity_target)
|
||||
puts "Loading Unity target: #{unity_target}"
|
||||
$unity_cfg = load_yaml(File.read(unity_target))
|
||||
|
||||
cmock_file = cmock_overlay || find_cmock_target(cmock_targets_dir, $cfg_file)
|
||||
cmock_file = cmock_overlay || find_cmock_target(cmock_targets_dir, config_basename)
|
||||
if cmock_file
|
||||
puts "Loading CMock overlay: #{cmock_targets_dir}/#{cmock_file}"
|
||||
$cmock_cfg = load_yaml(File.read("#{cmock_targets_dir}/#{cmock_file}"))
|
||||
else
|
||||
puts "No CMock overlay found for #{$cfg_file}"
|
||||
puts "No CMock overlay found for #{config_file}"
|
||||
$cmock_cfg = {}
|
||||
end
|
||||
else
|
||||
puts "Loading CMock-only target: #{cmock_targets_dir}/#{$cfg_file}"
|
||||
$unity_cfg = load_yaml(File.read("#{cmock_targets_dir}/#{$cfg_file}"))
|
||||
# CMock-only target (no Unity equivalent); it uses Unity format directly
|
||||
puts "Loading CMock-only target: #{cmock_targets_dir}/#{config_basename}"
|
||||
$unity_cfg = load_yaml(File.read("#{cmock_targets_dir}/#{config_basename}"))
|
||||
$cmock_cfg = {}
|
||||
end
|
||||
|
||||
@@ -118,7 +132,7 @@ module RakefileHelpers
|
||||
|
||||
# All defines: project common + Unity target + CMock overlay + any extras
|
||||
def all_defines(extra = [])
|
||||
(($proj[:defines][:common] || []) +
|
||||
(($proj[:defines][:test] || []) +
|
||||
($unity_cfg[:defines][:test] || []) +
|
||||
(($cmock_cfg[:defines] || {})[:test] || []) +
|
||||
extra).uniq
|
||||
@@ -133,12 +147,23 @@ module RakefileHelpers
|
||||
end
|
||||
end
|
||||
|
||||
# Resolve Unity's argument template tokens into a flat argument string.
|
||||
# Resolve argument template tokens into a flat argument string.
|
||||
# Supports Ceedling-style positional tokens and legacy Unity COLLECTION_* tokens.
|
||||
# ${5} → expands to one arg per include path (toolchain paths + project paths combined)
|
||||
# ${6} → expands to one arg per define
|
||||
# ${1} → input file(s)
|
||||
# ${2} → output file
|
||||
def build_argument_list(raw_args, toolchain_paths, project_paths, defines, input, output)
|
||||
result = []
|
||||
raw_args.each do |arg|
|
||||
if arg.is_a?(Array)
|
||||
result << arg.join
|
||||
elsif arg.include?('${5}')
|
||||
(toolchain_paths + project_paths).each do |p|
|
||||
result << arg.gsub('${5}', p.is_a?(Array) ? p.join : p.to_s)
|
||||
end
|
||||
elsif arg.include?('${6}')
|
||||
defines.each { |d| result << arg.gsub('${6}', d) }
|
||||
elsif arg.include?('COLLECTION_PATHS_TEST_TOOLCHAIN_INCLUDE')
|
||||
toolchain_paths.each { |p| result << "-I\"#{p.is_a?(Array) ? p.join : p}\"" }
|
||||
elsif arg.include?('COLLECTION_PATHS_TEST_SUPPORT_SOURCE_INCLUDE_VENDOR')
|
||||
@@ -154,8 +179,8 @@ module RakefileHelpers
|
||||
|
||||
def compile(file, extra_defines = [])
|
||||
tool = $unity_cfg[:tools][:test_compiler]
|
||||
ext = $unity_cfg[:extension][:object]
|
||||
build_root = $proj[:project][:build_root]
|
||||
ext = $unity_cfg[:extension][:object] || '.o'
|
||||
build_root = $proj[:project][:build_root] || 'build/'
|
||||
obj_file = build_root + File.basename(file, C_EXTENSION) + ext
|
||||
|
||||
cmd_str = "#{tackit(tool[:executable])} #{
|
||||
@@ -170,8 +195,8 @@ module RakefileHelpers
|
||||
|
||||
def link_it(exe_name, obj_list)
|
||||
tool = $unity_cfg[:tools][:test_linker]
|
||||
ext = $unity_cfg[:extension][:executable]
|
||||
build_root = $proj[:project][:build_root]
|
||||
ext = $unity_cfg[:extension][:executable] || ''
|
||||
build_root = $proj[:project][:build_root] || 'build/'
|
||||
|
||||
input_files = obj_list.uniq.map { |obj| build_root + obj }.join(' ')
|
||||
output_file = build_root + exe_name + ext
|
||||
@@ -263,7 +288,7 @@ module RakefileHelpers
|
||||
# Execute unit test and generate results file
|
||||
simulator = build_simulator_fields
|
||||
build_root = $proj[:project][:build_root]
|
||||
executable = build_root + test_base + $unity_cfg[:extension][:executable]
|
||||
executable = build_root + test_base + ($unity_cfg[:extension][:executable] || '')
|
||||
cmd_str = if simulator.nil?
|
||||
executable
|
||||
else
|
||||
|
||||
@@ -16,6 +16,17 @@ class CMockFileWriter
|
||||
require 'fileutils'
|
||||
FileUtils.mkdir_p "#{@config.mock_path}/" unless Dir.exist?("#{@config.mock_path}/")
|
||||
FileUtils.mkdir_p "#{@config.mock_path}/#{"#{subdir}/" if subdir}" if subdir && !Dir.exist?("#{@config.mock_path}/#{"#{subdir}/" if subdir}")
|
||||
rescue SystemCallError => e
|
||||
raise "Unable to create mock output directory: #{e.message}. Check :mock_path ('#{@config.mock_path}') configuration."
|
||||
end
|
||||
|
||||
def create_skeleton_subdir(subdir)
|
||||
require 'fileutils'
|
||||
base = effective_skeleton_path
|
||||
FileUtils.mkdir_p base
|
||||
FileUtils.mkdir_p "#{base}/#{subdir}" if subdir
|
||||
rescue SystemCallError => e
|
||||
raise "Unable to create skeleton output directory: #{e.message}. Check :skeleton_path ('#{base}') configuration."
|
||||
end
|
||||
|
||||
def create_file(filename, subdir)
|
||||
@@ -27,6 +38,27 @@ class CMockFileWriter
|
||||
yield(file, filename)
|
||||
end
|
||||
update_file(full_file_name_done, full_file_name_temp)
|
||||
rescue SystemCallError => e
|
||||
raise "Unable to write mock file '#{full_file_name_done}': #{e.message}. Check :mock_path ('#{@config.mock_path}') and :subdir ('#{subdir}') configuration."
|
||||
end
|
||||
|
||||
def create_skeleton_file(filename, subdir)
|
||||
raise "Where's the block of data to create?" unless block_given?
|
||||
|
||||
base = effective_skeleton_path
|
||||
full_file_name_temp = "#{base}/#{"#{subdir}/" if subdir}#{filename}.new"
|
||||
full_file_name_done = "#{base}/#{"#{subdir}/" if subdir}#{filename}"
|
||||
File.open(full_file_name_temp, 'w') do |file|
|
||||
yield(file, filename)
|
||||
end
|
||||
update_file(full_file_name_done, full_file_name_temp)
|
||||
rescue SystemCallError => e
|
||||
raise "Unable to write skeleton file '#{full_file_name_done}': #{e.message}. Check :skeleton_path ('#{base}') and :subdir ('#{subdir}') configuration."
|
||||
end
|
||||
|
||||
def skeleton_file_path(filename, subdir)
|
||||
base = effective_skeleton_path
|
||||
"#{base}/#{"#{subdir}/" if subdir}#{filename}"
|
||||
end
|
||||
|
||||
def append_file(filename, subdir)
|
||||
@@ -40,6 +72,11 @@ class CMockFileWriter
|
||||
|
||||
private ###################################
|
||||
|
||||
def effective_skeleton_path
|
||||
path = @config.skeleton_path
|
||||
path.nil? || path.empty? ? @config.mock_path : path
|
||||
end
|
||||
|
||||
def update_file(dest, src)
|
||||
require 'fileutils'
|
||||
FileUtils.rm(dest, :force => true)
|
||||
|
||||
+40
-26
@@ -85,6 +85,7 @@ class CMockGenerator
|
||||
:skeleton => true
|
||||
}
|
||||
|
||||
@file_writer.create_skeleton_subdir(@subdir)
|
||||
create_skeleton_source_file(mock_project)
|
||||
end
|
||||
|
||||
@@ -133,9 +134,9 @@ class CMockGenerator
|
||||
end
|
||||
|
||||
def create_skeleton_source_file(mock_project)
|
||||
filename = "#{@config.mock_path}/#{"#{@subdir}/" if @subdir}#{mock_project[:module_name]}.c"
|
||||
filename = @file_writer.skeleton_file_path("#{mock_project[:module_name]}.c", @subdir)
|
||||
existing = File.exist?(filename) ? File.read(filename) : ''
|
||||
@file_writer.create_file("#{mock_project[:module_name]}.c", @subdir) do |file, fullname|
|
||||
@file_writer.create_skeleton_file("#{mock_project[:module_name]}.c", @subdir) do |file, fullname|
|
||||
blank_project = mock_project.clone
|
||||
blank_project[:parsed_stuff] = { :functions => [] }
|
||||
if existing.empty?
|
||||
@@ -210,24 +211,30 @@ class CMockGenerator
|
||||
|
||||
def create_source_header_section(file, filename, mock_project)
|
||||
header_file = (mock_project[:folder] || '') + filename.sub(/.*\K\.c/, mock_project[:module_ext])
|
||||
file << "/* AUTOGENERATED FILE. DO NOT EDIT. */\n" unless mock_project[:parsed_stuff][:functions].empty?
|
||||
file << "#include <string.h>\n"
|
||||
file << "#include <stdlib.h>\n"
|
||||
unless @exclude_setjmp_h
|
||||
file << "#include <setjmp.h>\n"
|
||||
end
|
||||
file << "#include \"cmock.h\"\n"
|
||||
@includes_c_pre_header.each { |inc| file << "#include #{inc}\n" }
|
||||
file << "#include \"#{header_file}\"\n"
|
||||
@includes_c_post_header.each { |inc| file << "#include #{inc}\n" }
|
||||
file << "\n"
|
||||
strs = []
|
||||
mock_project[:parsed_stuff][:functions].each do |func|
|
||||
strs << func[:name]
|
||||
func[:args].each { |arg| strs << arg[:name] }
|
||||
end
|
||||
strs.uniq.sort.each do |str|
|
||||
file << "static const char* CMockString_#{str} = \"#{str}\";\n"
|
||||
if mock_project[:skeleton]
|
||||
@includes_c_pre_header.each { |inc| file << "#include #{inc}\n" }
|
||||
file << "#include \"#{header_file}\"\n"
|
||||
@includes_c_post_header.each { |inc| file << "#include #{inc}\n" }
|
||||
else
|
||||
file << "/* AUTOGENERATED FILE. DO NOT EDIT. */\n" unless mock_project[:parsed_stuff][:functions].empty?
|
||||
file << "#include <string.h>\n"
|
||||
file << "#include <stdlib.h>\n"
|
||||
unless @exclude_setjmp_h
|
||||
file << "#include <setjmp.h>\n"
|
||||
end
|
||||
file << "#include \"cmock.h\"\n"
|
||||
@includes_c_pre_header.each { |inc| file << "#include #{inc}\n" }
|
||||
file << "#include \"#{header_file}\"\n"
|
||||
@includes_c_post_header.each { |inc| file << "#include #{inc}\n" }
|
||||
file << "\n"
|
||||
strs = []
|
||||
mock_project[:parsed_stuff][:functions].each do |func|
|
||||
strs << func[:name]
|
||||
func[:args].each { |arg| strs << arg[:name] }
|
||||
end
|
||||
strs.uniq.sort.each do |str|
|
||||
file << "static const char* CMockString_#{str} = \"#{str}\";\n"
|
||||
end
|
||||
end
|
||||
file << "\n"
|
||||
end
|
||||
@@ -296,11 +303,20 @@ class CMockGenerator
|
||||
file << "}\n\n"
|
||||
end
|
||||
|
||||
def function_return_type(function)
|
||||
# When const_ptr? is true, the "const" in :modifier belongs after the asterisk (e.g. "int* const"),
|
||||
# not as a prefix (which would incorrectly produce "const int*").
|
||||
ret = if function[:return][:const_ptr?]
|
||||
"#{function[:return][:type]} const"
|
||||
else
|
||||
(function[:modifier].empty? ? '' : "#{function[:modifier]} ") + function[:return][:type]
|
||||
end
|
||||
ret + (function[:c_calling_convention] ? " #{function[:c_calling_convention]}" : '')
|
||||
end
|
||||
|
||||
def create_mock_implementation(file, function)
|
||||
# prepare return value and arguments
|
||||
function_mod_and_rettype = (function[:modifier].empty? ? '' : "#{function[:modifier]} ") +
|
||||
(function[:return][:type]) +
|
||||
(function[:c_calling_convention] ? " #{function[:c_calling_convention]}" : '')
|
||||
function_mod_and_rettype = function_return_type(function)
|
||||
args_string = function[:args_string]
|
||||
args_string += ", #{function[:var_arg]}" unless function[:var_arg].nil?
|
||||
|
||||
@@ -359,9 +375,7 @@ class CMockGenerator
|
||||
|
||||
def create_function_skeleton(file, function, existing)
|
||||
# prepare return value and arguments
|
||||
function_mod_and_rettype = (function[:modifier].empty? ? '' : "#{function[:modifier]} ") +
|
||||
(function[:return][:type]) +
|
||||
(function[:c_calling_convention] ? " #{function[:c_calling_convention]}" : '')
|
||||
function_mod_and_rettype = function_return_type(function)
|
||||
args_string = function[:args_string]
|
||||
args_string += ", #{function[:var_arg]}" unless function[:var_arg].nil?
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
+121
-13
@@ -253,12 +253,23 @@ class CMockHeaderParser
|
||||
# enums, unions, structs, and typedefs can all contain things (e.g. function pointers) that parse like function prototypes, so yank them
|
||||
# forward declared structs are removed before struct definitions so they don't mess up real thing later. we leave structs keywords in function prototypes
|
||||
source.gsub!(/^[\w\s]*struct[^;{}()]+;/m, '') # remove forward declared structs
|
||||
source.gsub!(/^[\w\s]*(enum|union|struct|typedef)[\w\s]*\{[^}]+\}[\w\s*,]*;/m, '') # remove struct, union, and enum definitions and typedefs with braces
|
||||
source.gsub!(/^[\w\s]*(enum|union|struct|typedef)[\w\s()]*\{[^}]+\}[\w\s*,]*;/m, '') # remove struct, union, and enum definitions and typedefs with braces
|
||||
# remove problem keywords
|
||||
source.gsub!(/(\W)(?:register|auto|restrict)(\W)/, '\1\2')
|
||||
source.gsub!(/(\W)(?:static)(\W)/, '\1\2') unless cpp
|
||||
|
||||
source.gsub!(/\s*=\s*['"a-zA-Z0-9_.]+\s*/, '') # remove default value statements from argument lists
|
||||
|
||||
# strip macro decorator patterns that cannot be C function prototypes.
|
||||
# must run after default-value removal so "= \"str\"" doesn't trigger string detection.
|
||||
# neutralize string literals (never valid in C prototype args), eliminating any parentheses
|
||||
# inside string content (e.g. "msg()") that would fool subsequent brace-matching.
|
||||
source.gsub!(/"[^"]*"/, '""')
|
||||
# strip WORD("") -- any call with a string literal arg cannot be a C function prototype
|
||||
source.gsub!(/\b\w+\s*\([^)]*""[^)]*\)/, '')
|
||||
# strip WORD(N...) -- any call whose first arg starts with a digit cannot be a C prototype
|
||||
source.gsub!(/\b\w+\s*\(\s*\d[^)]*\)/, '')
|
||||
|
||||
source.gsub!(/^(?:[\w\s]*\W)?typedef\W[^;]*/m, '') # remove typedef statements
|
||||
source.gsub!(/\)(\w)/, ') \1') # add space between parenthese and alphanumeric
|
||||
source.gsub!(/(^|\W+)(?:#{@c_strippables.join('|')})(?=$|\W+)/, '\1') unless @c_strippables.empty? # remove known attributes slated to be stripped
|
||||
@@ -408,7 +419,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 +447,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 +467,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 +544,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
|
||||
@@ -567,9 +647,11 @@ class CMockHeaderParser
|
||||
|
||||
rettype = parsed[:type]
|
||||
rettype = 'void' if @local_as_void.include?(rettype.strip)
|
||||
rettype = 'void' if rettype.empty? && !(@standards + @local_as_void).include?(parsed[:name]) # all return-type tokens were stripped (e.g. bare decorator macros)
|
||||
retstr = parsed[:const_ptr?] ? "#{rettype} const" : rettype
|
||||
decl[:return] = { :type => rettype,
|
||||
:name => 'cmock_to_return',
|
||||
:str => "#{rettype} cmock_to_return",
|
||||
:str => "#{retstr} cmock_to_return",
|
||||
:void? => (rettype == 'void'),
|
||||
:ptr? => parsed[:ptr?] || false,
|
||||
:const? => parsed[:const?] || false,
|
||||
@@ -590,12 +672,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(/\*$/, '')
|
||||
|
||||
@@ -24,10 +24,12 @@ CMOCK_OBJ = File.join(OBJ_DIR, 'cmock.o')
|
||||
RUNNERS_DIR = File.join(TEST_BUILD_DIR, 'runners')
|
||||
MOCKS_DIR = File.join(TEST_BUILD_DIR, 'mocks')
|
||||
TEST_BIN_DIR = TEST_BUILD_DIR
|
||||
MOCK_PREFIX = ENV.fetch('TEST_MOCK_PREFIX', 'mock_')
|
||||
MOCK_PREFIX = ENV.fetch('TEST_MOCK_PREFIX', 'Mock')
|
||||
MOCK_SUFFIX = ENV.fetch('TEST_MOCK_SUFFIX', '')
|
||||
TEST_MAKEFILE = ENV.fetch('TEST_MAKEFILE', File.join(TEST_BUILD_DIR, 'MakefileTestSupport'))
|
||||
MOCK_MATCHER = /#{MOCK_PREFIX}[A-Za-z_][A-Za-z0-9_\-.]+#{MOCK_SUFFIX}/
|
||||
OPTION_FILE = ENV.fetch('TEST_OPTION_YML_FILE', '')
|
||||
OPTION_FILE_FLAG = OPTION_FILE.empty? ? '' : "-o#{OPTION_FILE}"
|
||||
|
||||
[TEST_BUILD_DIR, OBJ_DIR, RUNNERS_DIR, MOCKS_DIR, TEST_BIN_DIR].each do |dir|
|
||||
FileUtils.mkdir_p dir
|
||||
@@ -126,7 +128,7 @@ File.open(TEST_MAKEFILE, 'w') do |mkfile|
|
||||
|
||||
# Create runners
|
||||
mkfile.puts "#{runner_source}: #{test}"
|
||||
mkfile.puts "\t@UNITY_DIR=${UNITY_DIR} ruby ${CMOCK_DIR}/scripts/create_runner.rb #{test} #{runner_source}"
|
||||
mkfile.puts "\truby #{UNITY_DIR}/auto/generate_test_runner.rb #{OPTION_FILE} #{test} #{runner_source}"
|
||||
mkfile.puts ''
|
||||
|
||||
# Build runner
|
||||
@@ -189,7 +191,7 @@ File.open(TEST_MAKEFILE, 'w') do |mkfile|
|
||||
mock_obj = File.join(MOCKS_DIR, "#{mock_name}.o")
|
||||
|
||||
mkfile.puts "#{mock_src}: #{hdr}"
|
||||
mkfile.puts "\t@CMOCK_DIR=${CMOCK_DIR} ruby ${CMOCK_DIR}/scripts/create_mock.rb #{hdr}"
|
||||
mkfile.puts "\truby #{CMOCK_DIR}/lib/cmock.rb #{hdr} --mock_path=#{MOCKS_DIR} #{OPTION_FILE_FLAG}"
|
||||
mkfile.puts ''
|
||||
|
||||
mkfile.puts "#{mock_obj}: #{mock_src} #{mock_header}"
|
||||
@@ -199,7 +201,7 @@ File.open(TEST_MAKEFILE, 'w') do |mkfile|
|
||||
|
||||
# Create test summary task
|
||||
mkfile.puts 'test_summary:'
|
||||
mkfile.puts "\t@UNITY_DIR=${UNITY_DIR} ruby ${CMOCK_DIR}/scripts/test_summary.rb #{suppress_error ? '--silent' : ''}"
|
||||
mkfile.puts "\truby #{UNITY_DIR}/auto/unity_test_summary.rb #{suppress_error ? '--silent' : ''} #{TEST_BUILD_DIR}"
|
||||
mkfile.puts ''
|
||||
mkfile.puts '.PHONY: test_summary'
|
||||
mkfile.puts ''
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
# =========================================================================
|
||||
# CMock - Automatic Mock Generation for C
|
||||
# ThrowTheSwitch.org
|
||||
# Copyright (c) 2007-26 Mike Karlesky, Mark VanderVoord, & Greg Williams
|
||||
# SPDX-License-Identifier: MIT
|
||||
# =========================================================================
|
||||
|
||||
require "#{ENV['CMOCK_DIR']}/lib/cmock"
|
||||
|
||||
raise 'Header file to mock must be specified!' unless ARGV.length >= 1
|
||||
|
||||
mock_out = ENV.fetch('MOCK_OUT', './build/test/mocks')
|
||||
mock_prefix = ENV.fetch('MOCK_PREFIX', 'mock_')
|
||||
cmock = CMock.new(:plugins => %i[ignore return_thru_ptr], :mock_prefix => mock_prefix, :mock_path => mock_out)
|
||||
cmock.setup_mocks(ARGV[0])
|
||||
@@ -1,25 +0,0 @@
|
||||
# =========================================================================
|
||||
# CMock - Automatic Mock Generation for C
|
||||
# ThrowTheSwitch.org
|
||||
# Copyright (c) 2007-26 Mike Karlesky, Mark VanderVoord, & Greg Williams
|
||||
# SPDX-License-Identifier: MIT
|
||||
# =========================================================================
|
||||
|
||||
if $0 == __FILE__
|
||||
|
||||
# make sure there is at least one parameter left (the input file)
|
||||
if ARGV.length < 2
|
||||
puts ["\nusage: ruby #{__FILE__} input_test_file (output)",
|
||||
'',
|
||||
' input_test_file - this is the C file you want to create a runner for',
|
||||
' output - this is the name of the runner file to generate',
|
||||
' defaults to (input_test_file)_Runner'].join("\n")
|
||||
exit 1
|
||||
end
|
||||
|
||||
require "#{ENV['UNITY_DIR']}/auto/generate_test_runner"
|
||||
|
||||
test = ARGV[0]
|
||||
runner = ARGV[1]
|
||||
UnityTestRunnerGenerator.new.run(test, runner)
|
||||
end
|
||||
@@ -1,25 +0,0 @@
|
||||
# =========================================================================
|
||||
# CMock - Automatic Mock Generation for C
|
||||
# ThrowTheSwitch.org
|
||||
# Copyright (c) 2007-26 Mike Karlesky, Mark VanderVoord, & Greg Williams
|
||||
# SPDX-License-Identifier: MIT
|
||||
# =========================================================================
|
||||
|
||||
suppress_error = !ARGV.nil? && !ARGV.empty? && (ARGV[0].casecmp('--SILENT') == 0)
|
||||
|
||||
begin
|
||||
require "#{ENV['UNITY_DIR']}/auto/unity_test_summary.rb"
|
||||
|
||||
build_dir = ENV.fetch('BUILD_DIR', './build')
|
||||
test_build_dir = ENV.fetch('TEST_BUILD_DIR', File.join(build_dir, 'test'))
|
||||
|
||||
results = Dir["#{test_build_dir}/*.testresult"]
|
||||
parser = UnityTestSummary.new
|
||||
parser.targets = results
|
||||
parser.run
|
||||
puts parser.report
|
||||
rescue StandardError => e
|
||||
raise e unless suppress_error
|
||||
end
|
||||
|
||||
exit(parser.failures) unless suppress_error
|
||||
+119
-117
@@ -22,14 +22,14 @@ const char* CMockStringMismatch = "Function called with unexpected argument v
|
||||
|
||||
/* private variables */
|
||||
#ifdef CMOCK_MEM_DYNAMIC
|
||||
static unsigned char* CMock_Guts_Buffer = NULL;
|
||||
static CMOCK_MEM_INDEX_TYPE CMock_Guts_BufferSize = CMOCK_MEM_ALIGN_SIZE;
|
||||
static CMOCK_MEM_INDEX_TYPE CMock_Guts_FreePtr = CMOCK_MEM_ALIGN_SIZE;
|
||||
static unsigned char* CMock_Guts_Buffer = NULL;
|
||||
static CMOCK_MEM_INDEX_TYPE CMock_Guts_BufferSize = CMOCK_MEM_ALIGN_SIZE;
|
||||
static CMOCK_MEM_INDEX_TYPE CMock_Guts_FreePtr = CMOCK_MEM_ALIGN_SIZE;
|
||||
#else
|
||||
static long long CMock_Guts_Space[(CMOCK_MEM_SIZE + CMOCK_MEM_ALIGN_SIZE + sizeof(long long) - 1) / sizeof(long long)];
|
||||
static unsigned char* CMock_Guts_Buffer = (unsigned char *)CMock_Guts_Space;
|
||||
static CMOCK_MEM_INDEX_TYPE CMock_Guts_BufferSize = CMOCK_MEM_SIZE + CMOCK_MEM_ALIGN_SIZE;//sizeof(CMock_Guts_Space);
|
||||
static CMOCK_MEM_INDEX_TYPE CMock_Guts_FreePtr = CMOCK_MEM_ALIGN_SIZE;
|
||||
static long long CMock_Guts_Space[(CMOCK_MEM_SIZE + CMOCK_MEM_ALIGN_SIZE + sizeof(long long) - 1) / sizeof(long long)];
|
||||
static unsigned char* CMock_Guts_Buffer = (unsigned char*)CMock_Guts_Space;
|
||||
static CMOCK_MEM_INDEX_TYPE CMock_Guts_BufferSize = CMOCK_MEM_SIZE + CMOCK_MEM_ALIGN_SIZE;//sizeof(CMock_Guts_Space);
|
||||
static CMOCK_MEM_INDEX_TYPE CMock_Guts_FreePtr = CMOCK_MEM_ALIGN_SIZE;
|
||||
#endif
|
||||
|
||||
/*-------------------------------------------------------
|
||||
@@ -37,41 +37,41 @@ static CMOCK_MEM_INDEX_TYPE CMock_Guts_FreePtr = CMOCK_MEM_ALIGN_SIZE;
|
||||
*-------------------------------------------------------*/
|
||||
CMOCK_MEM_INDEX_TYPE CMock_Guts_MemNew(CMOCK_MEM_INDEX_TYPE size)
|
||||
{
|
||||
CMOCK_MEM_INDEX_TYPE index;
|
||||
CMOCK_MEM_INDEX_TYPE index;
|
||||
|
||||
/* verify arguments valid (we must be allocating space for at least 1 byte, and the existing chain must be in memory somewhere) */
|
||||
if (size < 1)
|
||||
{
|
||||
return CMOCK_GUTS_NONE;
|
||||
}
|
||||
/* verify arguments valid (we must be allocating space for at least 1 byte, and the existing chain must be in memory somewhere) */
|
||||
if (size < 1)
|
||||
{
|
||||
return CMOCK_GUTS_NONE;
|
||||
}
|
||||
|
||||
/* verify we have enough room */
|
||||
size = size + CMOCK_MEM_INDEX_SIZE;
|
||||
if (size & CMOCK_MEM_ALIGN_MASK)
|
||||
{
|
||||
size = (size + CMOCK_MEM_ALIGN_MASK) & ~CMOCK_MEM_ALIGN_MASK;
|
||||
}
|
||||
if ((CMock_Guts_BufferSize - CMock_Guts_FreePtr) < size)
|
||||
{
|
||||
/* verify we have enough room */
|
||||
size = size + CMOCK_MEM_INDEX_SIZE;
|
||||
if (size & CMOCK_MEM_ALIGN_MASK)
|
||||
{
|
||||
size = (size + CMOCK_MEM_ALIGN_MASK) & ~CMOCK_MEM_ALIGN_MASK;
|
||||
}
|
||||
if ((CMock_Guts_BufferSize - CMock_Guts_FreePtr) < size)
|
||||
{
|
||||
#ifndef CMOCK_MEM_DYNAMIC
|
||||
return CMOCK_GUTS_NONE; /* nothing we can do; our static buffer is out of memory */
|
||||
return CMOCK_GUTS_NONE; /* nothing we can do; our static buffer is out of memory */
|
||||
#else
|
||||
/* our dynamic buffer does not have enough room; request more via realloc() */
|
||||
CMOCK_MEM_INDEX_TYPE new_buffersize = CMock_Guts_BufferSize + CMOCK_MEM_SIZE + size;
|
||||
unsigned char* new_buffer = realloc(CMock_Guts_Buffer, (size_t)new_buffersize);
|
||||
if (new_buffer == NULL)
|
||||
return CMOCK_GUTS_NONE; /* realloc() failed; out of memory */
|
||||
CMock_Guts_Buffer = new_buffer;
|
||||
CMock_Guts_BufferSize = new_buffersize;
|
||||
/* our dynamic buffer does not have enough room; request more via realloc() */
|
||||
CMOCK_MEM_INDEX_TYPE new_buffersize = CMock_Guts_BufferSize + CMOCK_MEM_SIZE + size;
|
||||
unsigned char* new_buffer = realloc(CMock_Guts_Buffer, (size_t)new_buffersize);
|
||||
if (new_buffer == NULL)
|
||||
return CMOCK_GUTS_NONE; /* realloc() failed; out of memory */
|
||||
CMock_Guts_Buffer = new_buffer;
|
||||
CMock_Guts_BufferSize = new_buffersize;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/* determine where we're putting this new block, and init its pointer to be the end of the line */
|
||||
index = CMock_Guts_FreePtr + CMOCK_MEM_INDEX_SIZE;
|
||||
*(CMOCK_MEM_INDEX_TYPE*)(&CMock_Guts_Buffer[CMock_Guts_FreePtr]) = CMOCK_GUTS_NONE;
|
||||
CMock_Guts_FreePtr += size;
|
||||
/* determine where we're putting this new block, and init its pointer to be the end of the line */
|
||||
index = CMock_Guts_FreePtr + CMOCK_MEM_INDEX_SIZE;
|
||||
*(CMOCK_MEM_INDEX_TYPE*)(&CMock_Guts_Buffer[CMock_Guts_FreePtr]) = CMOCK_GUTS_NONE;
|
||||
CMock_Guts_FreePtr += size;
|
||||
|
||||
return index;
|
||||
return index;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------
|
||||
@@ -79,47 +79,49 @@ CMOCK_MEM_INDEX_TYPE CMock_Guts_MemNew(CMOCK_MEM_INDEX_TYPE size)
|
||||
*-------------------------------------------------------*/
|
||||
CMOCK_MEM_INDEX_TYPE CMock_Guts_MemChain(CMOCK_MEM_INDEX_TYPE root_index, CMOCK_MEM_INDEX_TYPE obj_index)
|
||||
{
|
||||
CMOCK_MEM_INDEX_TYPE index;
|
||||
void* root;
|
||||
void* obj;
|
||||
void* next;
|
||||
CMOCK_MEM_INDEX_TYPE index;
|
||||
void* root;
|
||||
void* obj;
|
||||
void* next;
|
||||
|
||||
if (root_index == CMOCK_GUTS_NONE)
|
||||
{
|
||||
/* if there is no root currently, we return this object as the root of the chain */
|
||||
return obj_index;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* reject illegal nodes */
|
||||
if ((root_index < CMOCK_MEM_ALIGN_SIZE) || (root_index >= CMock_Guts_FreePtr))
|
||||
if (root_index == CMOCK_GUTS_NONE)
|
||||
{
|
||||
return CMOCK_GUTS_NONE;
|
||||
/* if there is no root currently, we return this object as the root of the chain */
|
||||
return obj_index;
|
||||
}
|
||||
if ((obj_index < CMOCK_MEM_ALIGN_SIZE) || (obj_index >= CMock_Guts_FreePtr))
|
||||
else
|
||||
{
|
||||
return CMOCK_GUTS_NONE;
|
||||
/* reject illegal nodes */
|
||||
if ((root_index < CMOCK_MEM_ALIGN_SIZE) || (root_index >= CMock_Guts_FreePtr))
|
||||
{
|
||||
return CMOCK_GUTS_NONE;
|
||||
}
|
||||
if ((obj_index < CMOCK_MEM_ALIGN_SIZE) || (obj_index >= CMock_Guts_FreePtr))
|
||||
{
|
||||
return CMOCK_GUTS_NONE;
|
||||
}
|
||||
|
||||
root = (void*)(&CMock_Guts_Buffer[root_index]);
|
||||
obj = (void*)(&CMock_Guts_Buffer[obj_index]);
|
||||
|
||||
/* find the end of the existing chain and add us */
|
||||
next = root;
|
||||
do
|
||||
{
|
||||
index = *(CMOCK_MEM_INDEX_TYPE*)((CMOCK_MEM_PTR_AS_INT)next - CMOCK_MEM_INDEX_SIZE);
|
||||
if (index >= CMock_Guts_FreePtr)
|
||||
{
|
||||
return CMOCK_GUTS_NONE;
|
||||
}
|
||||
if (index > 0)
|
||||
{
|
||||
next = (void*)(&CMock_Guts_Buffer[index]);
|
||||
}
|
||||
}
|
||||
while (index > 0);
|
||||
*(CMOCK_MEM_INDEX_TYPE*)((CMOCK_MEM_PTR_AS_INT)next - CMOCK_MEM_INDEX_SIZE) = (CMOCK_MEM_INDEX_TYPE)((CMOCK_MEM_PTR_AS_INT)obj - (CMOCK_MEM_PTR_AS_INT)CMock_Guts_Buffer);
|
||||
return root_index;
|
||||
}
|
||||
|
||||
root = (void*)(&CMock_Guts_Buffer[root_index]);
|
||||
obj = (void*)(&CMock_Guts_Buffer[obj_index]);
|
||||
|
||||
/* find the end of the existing chain and add us */
|
||||
next = root;
|
||||
do {
|
||||
index = *(CMOCK_MEM_INDEX_TYPE*)((CMOCK_MEM_PTR_AS_INT)next - CMOCK_MEM_INDEX_SIZE);
|
||||
if (index >= CMock_Guts_FreePtr)
|
||||
{
|
||||
return CMOCK_GUTS_NONE;
|
||||
}
|
||||
if (index > 0)
|
||||
{
|
||||
next = (void*)(&CMock_Guts_Buffer[index]);
|
||||
}
|
||||
} while (index > 0);
|
||||
*(CMOCK_MEM_INDEX_TYPE*)((CMOCK_MEM_PTR_AS_INT)next - CMOCK_MEM_INDEX_SIZE) = (CMOCK_MEM_INDEX_TYPE)((CMOCK_MEM_PTR_AS_INT)obj - (CMOCK_MEM_PTR_AS_INT)CMock_Guts_Buffer);
|
||||
return root_index;
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------
|
||||
@@ -127,27 +129,27 @@ CMOCK_MEM_INDEX_TYPE CMock_Guts_MemChain(CMOCK_MEM_INDEX_TYPE root_index, CMOCK_
|
||||
*-------------------------------------------------------*/
|
||||
CMOCK_MEM_INDEX_TYPE CMock_Guts_MemNext(CMOCK_MEM_INDEX_TYPE previous_item_index)
|
||||
{
|
||||
CMOCK_MEM_INDEX_TYPE index;
|
||||
void* previous_item;
|
||||
CMOCK_MEM_INDEX_TYPE index;
|
||||
void* previous_item;
|
||||
|
||||
/* There is nothing "next" if the pointer isn't from our buffer */
|
||||
if ((previous_item_index < CMOCK_MEM_ALIGN_SIZE) || (previous_item_index >= CMock_Guts_FreePtr))
|
||||
{
|
||||
return CMOCK_GUTS_NONE;
|
||||
}
|
||||
previous_item = (void*)(&CMock_Guts_Buffer[previous_item_index]);
|
||||
/* There is nothing "next" if the pointer isn't from our buffer */
|
||||
if ((previous_item_index < CMOCK_MEM_ALIGN_SIZE) || (previous_item_index >= CMock_Guts_FreePtr))
|
||||
{
|
||||
return CMOCK_GUTS_NONE;
|
||||
}
|
||||
previous_item = (void*)(&CMock_Guts_Buffer[previous_item_index]);
|
||||
|
||||
/* if the pointer is good, then use it to look up the next index
|
||||
* (we know the first element always goes in zero, so NEXT must always be > 1) */
|
||||
index = *(CMOCK_MEM_INDEX_TYPE*)((CMOCK_MEM_PTR_AS_INT)previous_item - CMOCK_MEM_INDEX_SIZE);
|
||||
if ((index > 1) && (index < CMock_Guts_FreePtr))
|
||||
{
|
||||
return index;
|
||||
}
|
||||
else
|
||||
{
|
||||
return CMOCK_GUTS_NONE;
|
||||
}
|
||||
/* if the pointer is good, then use it to look up the next index
|
||||
* (we know the first element always goes in zero, so NEXT must always be > 1) */
|
||||
index = *(CMOCK_MEM_INDEX_TYPE*)((CMOCK_MEM_PTR_AS_INT)previous_item - CMOCK_MEM_INDEX_SIZE);
|
||||
if ((index > 1) && (index < CMock_Guts_FreePtr))
|
||||
{
|
||||
return index;
|
||||
}
|
||||
else
|
||||
{
|
||||
return CMOCK_GUTS_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------
|
||||
@@ -155,17 +157,17 @@ CMOCK_MEM_INDEX_TYPE CMock_Guts_MemNext(CMOCK_MEM_INDEX_TYPE previous_item_index
|
||||
*-------------------------------------------------------*/
|
||||
CMOCK_MEM_INDEX_TYPE CMock_Guts_MemEndOfChain(CMOCK_MEM_INDEX_TYPE root_index)
|
||||
{
|
||||
CMOCK_MEM_INDEX_TYPE index = root_index;
|
||||
CMOCK_MEM_INDEX_TYPE next_index;
|
||||
CMOCK_MEM_INDEX_TYPE index = root_index;
|
||||
CMOCK_MEM_INDEX_TYPE next_index;
|
||||
|
||||
for (next_index = root_index;
|
||||
next_index != CMOCK_GUTS_NONE;
|
||||
next_index = CMock_Guts_MemNext(index))
|
||||
{
|
||||
index = next_index;
|
||||
}
|
||||
for (next_index = root_index;
|
||||
next_index != CMOCK_GUTS_NONE;
|
||||
next_index = CMock_Guts_MemNext(index))
|
||||
{
|
||||
index = next_index;
|
||||
}
|
||||
|
||||
return index;
|
||||
return index;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------
|
||||
@@ -173,14 +175,14 @@ CMOCK_MEM_INDEX_TYPE CMock_Guts_MemEndOfChain(CMOCK_MEM_INDEX_TYPE root_index)
|
||||
*-------------------------------------------------------*/
|
||||
void* CMock_Guts_GetAddressFor(CMOCK_MEM_INDEX_TYPE index)
|
||||
{
|
||||
if ((index >= CMOCK_MEM_ALIGN_SIZE) && (index < CMock_Guts_FreePtr))
|
||||
{
|
||||
return (void*)(&CMock_Guts_Buffer[index]);
|
||||
}
|
||||
else
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
if ((index >= CMOCK_MEM_ALIGN_SIZE) && (index < CMock_Guts_FreePtr))
|
||||
{
|
||||
return (void*)(&CMock_Guts_Buffer[index]);
|
||||
}
|
||||
else
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------
|
||||
@@ -188,7 +190,7 @@ void* CMock_Guts_GetAddressFor(CMOCK_MEM_INDEX_TYPE index)
|
||||
*-------------------------------------------------------*/
|
||||
CMOCK_MEM_INDEX_TYPE CMock_Guts_MemBytesCapacity(void)
|
||||
{
|
||||
return (sizeof(CMock_Guts_Buffer) - CMOCK_MEM_ALIGN_SIZE);
|
||||
return (sizeof(CMock_Guts_Buffer) - CMOCK_MEM_ALIGN_SIZE);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------
|
||||
@@ -196,7 +198,7 @@ CMOCK_MEM_INDEX_TYPE CMock_Guts_MemBytesCapacity(void)
|
||||
*-------------------------------------------------------*/
|
||||
CMOCK_MEM_INDEX_TYPE CMock_Guts_MemBytesFree(void)
|
||||
{
|
||||
return CMock_Guts_BufferSize - CMock_Guts_FreePtr;
|
||||
return CMock_Guts_BufferSize - CMock_Guts_FreePtr;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------
|
||||
@@ -204,7 +206,7 @@ CMOCK_MEM_INDEX_TYPE CMock_Guts_MemBytesFree(void)
|
||||
*-------------------------------------------------------*/
|
||||
CMOCK_MEM_INDEX_TYPE CMock_Guts_MemBytesUsed(void)
|
||||
{
|
||||
return CMock_Guts_FreePtr - CMOCK_MEM_ALIGN_SIZE;
|
||||
return CMock_Guts_FreePtr - CMOCK_MEM_ALIGN_SIZE;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------
|
||||
@@ -212,7 +214,7 @@ CMOCK_MEM_INDEX_TYPE CMock_Guts_MemBytesUsed(void)
|
||||
*-------------------------------------------------------*/
|
||||
void CMock_Guts_MemFreeAll(void)
|
||||
{
|
||||
CMock_Guts_FreePtr = CMOCK_MEM_ALIGN_SIZE; /* skip the very beginning */
|
||||
CMock_Guts_FreePtr = CMOCK_MEM_ALIGN_SIZE; /* skip the very beginning */
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------
|
||||
@@ -220,13 +222,13 @@ void CMock_Guts_MemFreeAll(void)
|
||||
*-------------------------------------------------------*/
|
||||
void CMock_Guts_MemFreeFinal(void)
|
||||
{
|
||||
CMock_Guts_FreePtr = CMOCK_MEM_ALIGN_SIZE;
|
||||
CMock_Guts_FreePtr = CMOCK_MEM_ALIGN_SIZE;
|
||||
#ifdef CMOCK_MEM_DYNAMIC
|
||||
if (CMock_Guts_Buffer)
|
||||
{
|
||||
free(CMock_Guts_Buffer);
|
||||
CMock_Guts_Buffer = NULL;
|
||||
}
|
||||
if (CMock_Guts_Buffer)
|
||||
{
|
||||
free(CMock_Guts_Buffer);
|
||||
CMock_Guts_Buffer = NULL;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
+6
-6
@@ -12,21 +12,21 @@
|
||||
|
||||
#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 */
|
||||
#ifndef CMOCK_MEM_INDEX_TYPE
|
||||
#include <stddef.h>
|
||||
#define CMOCK_MEM_INDEX_TYPE size_t
|
||||
#include <stddef.h>
|
||||
#define CMOCK_MEM_INDEX_TYPE size_t
|
||||
#endif
|
||||
|
||||
#define CMOCK_GUTS_NONE (0)
|
||||
|
||||
#if defined __GNUC__
|
||||
# define CMOCK_FUNCTION_ATTR(a) __attribute__((a))
|
||||
#define CMOCK_FUNCTION_ATTR(a) __attribute__((a))
|
||||
#else
|
||||
# define CMOCK_FUNCTION_ATTR(a) /* ignore */
|
||||
#define CMOCK_FUNCTION_ATTR(a) /* ignore */
|
||||
#endif
|
||||
|
||||
/*-------------------------------------------------------
|
||||
@@ -39,7 +39,7 @@ CMOCK_MEM_INDEX_TYPE CMock_Guts_MemEndOfChain(CMOCK_MEM_INDEX_TYPE root_index)
|
||||
|
||||
void* CMock_Guts_GetAddressFor(CMOCK_MEM_INDEX_TYPE index) CMOCK_FUNCTION_ATTR(pure);
|
||||
|
||||
CMOCK_MEM_INDEX_TYPE CMock_Guts_MemBytesCapacity(void) CMOCK_FUNCTION_ATTR(const);
|
||||
CMOCK_MEM_INDEX_TYPE CMock_Guts_MemBytesCapacity(void) CMOCK_FUNCTION_ATTR(const);
|
||||
CMOCK_MEM_INDEX_TYPE CMock_Guts_MemBytesFree(void) CMOCK_FUNCTION_ATTR(pure);
|
||||
CMOCK_MEM_INDEX_TYPE CMock_Guts_MemBytesUsed(void) CMOCK_FUNCTION_ATTR(pure);
|
||||
void CMock_Guts_MemFreeAll(void);
|
||||
|
||||
+32
-32
@@ -26,61 +26,61 @@ extern const char* CMockStringMismatch;
|
||||
/* define CMOCK_MEM_DYNAMIC to grab memory as needed with malloc
|
||||
* when you do that, CMOCK_MEM_SIZE is used for incremental size instead of total */
|
||||
#ifdef CMOCK_MEM_STATIC
|
||||
#undef CMOCK_MEM_DYNAMIC
|
||||
#undef CMOCK_MEM_DYNAMIC
|
||||
#endif
|
||||
|
||||
#ifdef CMOCK_MEM_DYNAMIC
|
||||
#include <stdlib.h>
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
/* this is used internally during pointer arithmetic. make sure this type is the same size as the target's pointer type */
|
||||
#ifndef CMOCK_MEM_PTR_AS_INT
|
||||
#ifdef UNITY_POINTER_WIDTH
|
||||
#ifdef UNITY_INT_WIDTH
|
||||
#if UNITY_POINTER_WIDTH == UNITY_INT_WIDTH
|
||||
#define CMOCK_MEM_PTR_AS_INT unsigned int
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#ifdef UNITY_POINTER_WIDTH
|
||||
#ifdef UNITY_INT_WIDTH
|
||||
#if UNITY_POINTER_WIDTH == UNITY_INT_WIDTH
|
||||
#define CMOCK_MEM_PTR_AS_INT unsigned int
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef CMOCK_MEM_PTR_AS_INT
|
||||
#ifdef UNITY_POINTER_WIDTH
|
||||
#ifdef UNITY_LONG_WIDTH
|
||||
#if UNITY_POINTER_WIDTH == UNITY_LONG_WIDTH
|
||||
#define CMOCK_MEM_PTR_AS_INT unsigned long
|
||||
#endif
|
||||
#if UNITY_POINTER_WIDTH > UNITY_LONG_WIDTH
|
||||
#define CMOCK_MEM_PTR_AS_INT unsigned long long
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#ifdef UNITY_POINTER_WIDTH
|
||||
#ifdef UNITY_LONG_WIDTH
|
||||
#if UNITY_POINTER_WIDTH == UNITY_LONG_WIDTH
|
||||
#define CMOCK_MEM_PTR_AS_INT unsigned long
|
||||
#endif
|
||||
#if UNITY_POINTER_WIDTH > UNITY_LONG_WIDTH
|
||||
#define CMOCK_MEM_PTR_AS_INT unsigned long long
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef CMOCK_MEM_PTR_AS_INT
|
||||
#define CMOCK_MEM_PTR_AS_INT unsigned long
|
||||
#define CMOCK_MEM_PTR_AS_INT unsigned long
|
||||
#endif
|
||||
|
||||
/* 0 for no alignment, 1 for 16-bit, 2 for 32-bit, 3 for 64-bit */
|
||||
#ifndef CMOCK_MEM_ALIGN
|
||||
#ifdef UNITY_LONG_WIDTH
|
||||
#if (UNITY_LONG_WIDTH == 16)
|
||||
#define CMOCK_MEM_ALIGN (1)
|
||||
#elif (UNITY_LONG_WIDTH == 32)
|
||||
#define CMOCK_MEM_ALIGN (2)
|
||||
#elif (UNITY_LONG_WIDTH == 64)
|
||||
#define CMOCK_MEM_ALIGN (3)
|
||||
#ifdef UNITY_LONG_WIDTH
|
||||
#if (UNITY_LONG_WIDTH == 16)
|
||||
#define CMOCK_MEM_ALIGN (1)
|
||||
#elif (UNITY_LONG_WIDTH == 32)
|
||||
#define CMOCK_MEM_ALIGN (2)
|
||||
#elif (UNITY_LONG_WIDTH == 64)
|
||||
#define CMOCK_MEM_ALIGN (3)
|
||||
#else
|
||||
#define CMOCK_MEM_ALIGN (2)
|
||||
#endif
|
||||
#else
|
||||
#define CMOCK_MEM_ALIGN (2)
|
||||
#define CMOCK_MEM_ALIGN (2)
|
||||
#endif
|
||||
#else
|
||||
#define CMOCK_MEM_ALIGN (2)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* amount of memory to allow cmock to use in its internal heap */
|
||||
#ifndef CMOCK_MEM_SIZE
|
||||
#define CMOCK_MEM_SIZE (32768)
|
||||
#define CMOCK_MEM_SIZE (32768)
|
||||
#endif
|
||||
|
||||
/* automatically calculated defs for easier reading */
|
||||
|
||||
+1
-1
@@ -28,6 +28,6 @@
|
||||
:executable: '.exe'
|
||||
|
||||
:defines:
|
||||
:common:
|
||||
:test:
|
||||
- CMOCK
|
||||
|
||||
|
||||
+48
-42
@@ -27,18 +27,22 @@ SYSTEM_TEST_SUPPORT_DIRS.each do |dir|
|
||||
CLOBBER.include(dir)
|
||||
end
|
||||
|
||||
$cmock_test_config_file = DEFAULT_CONFIG_FILE
|
||||
$cmock_test_overlay_file = nil
|
||||
|
||||
task :prep_system_tests => SYSTEM_TEST_SUPPORT_DIRS
|
||||
|
||||
configure_toolchain(DEFAULT_CONFIG_FILE)
|
||||
|
||||
task :default => [:test]
|
||||
task :ci => [:no_color, :default, 'test:examples', 'style:check', 'test:summary']
|
||||
task :cruise => :ci
|
||||
|
||||
desc "Load configuration"
|
||||
task :config, [:config_file, :cmock_overlay] do |t, args|
|
||||
configure_toolchain(args[:config_file], args[:cmock_overlay])
|
||||
$cmock_test_config_file = args[:config_file]
|
||||
$cmock_test_overlay_file = args[:cmock_overlay]
|
||||
end
|
||||
|
||||
task :config_toolchains do
|
||||
configure_toolchain($cmock_test_config_file, $cmock_test_overlay_file)
|
||||
end
|
||||
|
||||
# Still support testing everything with just 'test' but switch default to ceedling-like test:all
|
||||
@@ -46,63 +50,65 @@ task :test => ['test:all']
|
||||
|
||||
namespace :test do
|
||||
desc "Run all unit, c, and system tests"
|
||||
task :all => [:clobber, :prep_system_tests, 'test:units', 'test:c', 'test:system']
|
||||
task :all => [:config_toolchains, :clobber, :prep_system_tests, 'test:unit', 'test:c', 'test:system']
|
||||
|
||||
desc "Run Unit Tests"
|
||||
task :units => [:prep_system_tests] do
|
||||
task :unit => [:config_toolchains, :prep_system_tests] do
|
||||
run_ruby_unit_tests
|
||||
end
|
||||
|
||||
#individual unit tests
|
||||
FileList['unit/*_test.rb'].each do |test|
|
||||
Rake::TestTask.new(File.basename(test,'.*').sub('_test','')) do |t|
|
||||
t.pattern = test
|
||||
t.verbose = true
|
||||
namespace :unit do
|
||||
FileList['unit/*_test.rb'].each do |test|
|
||||
desc "Run unit test #{File.basename(test,'.*')}"
|
||||
Rake::TestTask.new(File.basename(test,'.*').sub('_test','') => [:config_toolchains]) do |t|
|
||||
t.pattern = test
|
||||
t.verbose = true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
desc "Run C Unit Tests"
|
||||
task :c => [:prep_system_tests] do
|
||||
task :c => [:config_toolchains, :prep_system_tests] do
|
||||
unless (unsupported_tests.include? "C")
|
||||
build_and_test_c_files
|
||||
end
|
||||
end
|
||||
|
||||
desc "Run System Tests"
|
||||
task :system => [:clobber, :prep_system_tests] do
|
||||
#get a list of all system tests, removing unsupported tests for this compiler
|
||||
sys_unsupported = unsupported_tests.map {|a| 'system/test_interactions/'+a+'.yml'}
|
||||
sys_tests_to_run = FileList['system/test_interactions/*.yml'] - sys_unsupported
|
||||
compile_unsupported = unsupported_tests.map {|a| SYSTEST_COMPILE_MOCKABLES_PATH+a+'.h'}
|
||||
compile_tests_to_run = FileList[SYSTEST_COMPILE_MOCKABLES_PATH + '*.h'] - compile_unsupported
|
||||
unless (sys_unsupported.empty? and compile_unsupported.empty?)
|
||||
report "\nIgnoring these system tests..."
|
||||
sys_unsupported.each {|a| report a}
|
||||
compile_unsupported.each {|a| report a}
|
||||
end
|
||||
task :system => [:config_toolchains, :clobber, :prep_system_tests] do
|
||||
report "\nRunning system tests..."
|
||||
tests_failed = run_system_test_interactions(sys_tests_to_run)
|
||||
tests_failed = run_system_test_interactions(FileList['system/test_interactions/*.yml'])
|
||||
raise "System tests failed." if (tests_failed > 0)
|
||||
|
||||
run_system_test_compilations(compile_tests_to_run)
|
||||
end
|
||||
|
||||
desc "Test cmock examples"
|
||||
task :examples => [:prep_system_tests] do
|
||||
run_examples(true)
|
||||
run_system_test_compilations(FileList[SYSTEST_COMPILE_MOCKABLES_PATH + '*.h'])
|
||||
end
|
||||
|
||||
#individual system tests
|
||||
FileList['system/test_interactions/*.yml'].each do |test|
|
||||
basename = File.basename(test,'.*')
|
||||
#desc "Run system test #{basename}"
|
||||
task basename do
|
||||
run_system_test_interactions([test])
|
||||
namespace :system do
|
||||
FileList['system/test_interactions/*.yml'].each do |test|
|
||||
basename = File.basename(test,'.*')
|
||||
desc "Run system test #{basename}"
|
||||
task basename => [:config_toolchains, :prep_system_tests] do
|
||||
run_system_test_interactions([test])
|
||||
end
|
||||
end
|
||||
FileList[SYSTEST_COMPILE_MOCKABLES_PATH + '*.h'].each do |test|
|
||||
basename = File.basename(test,'.*')
|
||||
desc "Run system test #{basename}"
|
||||
task basename => [:config_toolchains, :prep_system_tests] do
|
||||
run_system_test_compilations([test])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
desc "Test cmock examples"
|
||||
task :examples => [:config_toolchains, :prep_system_tests] do
|
||||
run_examples()
|
||||
end
|
||||
|
||||
desc "Profile Mock Generation"
|
||||
task :profile => [:clobber, :prep_system_tests] do
|
||||
task :profile => [:config_toolchains, :clobber, :prep_system_tests] do
|
||||
run_system_test_profiles(FileList[SYSTEST_COMPILE_MOCKABLES_PATH + '*.h'])
|
||||
end
|
||||
|
||||
@@ -119,7 +125,7 @@ end
|
||||
################### CODING STYLE VALIDATION
|
||||
namespace :style do
|
||||
desc "Check style"
|
||||
task :check do
|
||||
task :check => [:config_toolchains] do
|
||||
report "\n"
|
||||
report "--------------------\n"
|
||||
report "VERIFYING RUBY STYLE\n"
|
||||
@@ -129,25 +135,25 @@ namespace :style do
|
||||
end
|
||||
|
||||
desc "Fix Style of all C Code"
|
||||
task :c do
|
||||
run_astyle("../src/*.* ../extras/fixture/src/*.*")
|
||||
task :c => [:config_toolchains]do
|
||||
run_astyle("../src/*.*")
|
||||
end
|
||||
|
||||
desc "Attempt to Autocorrect style"
|
||||
task :auto => ['style:clean'] do
|
||||
task :auto => [:config_toolchains, 'style:clean'] do
|
||||
execute("rubocop ../lib ../examples ../config ../scripts --autocorrect --config ../vendor/unity/test/.rubocop.yml", true)
|
||||
report "Autocorrected What We Could."
|
||||
end
|
||||
|
||||
desc "Update style todo list"
|
||||
task :todo => ['style:clean'] do
|
||||
task :todo => [:config_toolchains, 'style:clean'] do
|
||||
execute("rubocop ../lib ../examples ../config ../scripts --auto-gen-config --config ../vendor/unity/test/.rubocop.yml", true)
|
||||
report "Updated Style TODO List."
|
||||
end
|
||||
|
||||
task :clean do
|
||||
task :clean => [:config_toolchains] do
|
||||
File.delete(".rubocop_todo.yml") if File.exist?(".rubocop_todo.yml")
|
||||
end
|
||||
end
|
||||
|
||||
task :style => ['style:check']
|
||||
task :style => [:config_toolchains, 'style:check']
|
||||
+116
-50
@@ -44,29 +44,40 @@ 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_target = "../vendor/unity/test/targets/#{$cfg_file}"
|
||||
unity_targets_dir = '../vendor/unity/test/targets'
|
||||
cmock_targets_dir = './targets'
|
||||
config_basename = File.basename(config_file)
|
||||
path_specified = File.dirname(config_file) != '.'
|
||||
|
||||
if File.exist?(unity_target)
|
||||
# Resolve the target file location:
|
||||
# - path specified → use only that location
|
||||
# - no path → check current directory first, then vendor unity targets
|
||||
config_target = if path_specified
|
||||
config_file
|
||||
elsif File.exist?("./#{config_file}")
|
||||
"./#{config_file}"
|
||||
else
|
||||
"#{unity_targets_dir}/#{config_file}"
|
||||
end
|
||||
|
||||
if File.exist?(config_target)
|
||||
# Load Unity base target, then CMock overlay (unsupported list, extra defines)
|
||||
puts "Loading Unity target: #{unity_target}"
|
||||
$unity_cfg = load_yaml(unity_target)
|
||||
puts "Loading Toolchain target: #{config_target}"
|
||||
$unity_cfg = load_yaml(config_target)
|
||||
|
||||
cmock_file = cmock_overlay || find_cmock_target(cmock_targets_dir, $cfg_file)
|
||||
cmock_file = cmock_overlay || find_cmock_target(cmock_targets_dir, config_basename)
|
||||
if cmock_file
|
||||
puts "Loading CMock overlay: #{cmock_targets_dir}/#{cmock_file}"
|
||||
puts "Loading Toolchain overlay: #{cmock_targets_dir}/#{cmock_file}"
|
||||
$cmock_cfg = load_yaml("#{cmock_targets_dir}/#{cmock_file}")
|
||||
else
|
||||
puts "No CMock overlay found for #{$cfg_file}"
|
||||
puts "No Toolchain overlay found for #{config_file}"
|
||||
$cmock_cfg = {}
|
||||
end
|
||||
else
|
||||
# CMock-only target (no Unity equivalent); it uses Unity format directly
|
||||
puts "Loading CMock-only target: #{cmock_targets_dir}/#{$cfg_file}"
|
||||
$unity_cfg = load_yaml("#{cmock_targets_dir}/#{$cfg_file}")
|
||||
$cmock_cfg = {}
|
||||
raise "Cannot find Config File #{config_target}"
|
||||
end
|
||||
|
||||
$colour_output = $proj[:project][:colour]
|
||||
@@ -79,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
|
||||
@@ -122,7 +132,7 @@ module RakefileHelpers
|
||||
|
||||
# All defines: project common + Unity target + CMock overlay + any extras
|
||||
def all_defines(extra = [])
|
||||
(($proj[:defines][:common] || []) +
|
||||
(($proj[:defines][:test] || []) +
|
||||
($unity_cfg[:defines][:test] || []) +
|
||||
(($cmock_cfg[:defines] || {})[:test] || []) +
|
||||
extra).uniq
|
||||
@@ -131,26 +141,46 @@ module RakefileHelpers
|
||||
# Toolchain-specific include paths: Array items in Unity's :paths: :test:
|
||||
# (e.g., IAR compiler include directories encoded as path-concatenation arrays)
|
||||
def toolchain_include_paths
|
||||
($unity_cfg[:paths][:test] || []).select { |p| p.is_a?(Array) }
|
||||
(($unity_cfg[:paths] || {})[:test] || []).select { |p| p.is_a?(Array) }
|
||||
end
|
||||
|
||||
# Returns the unsupported test list, regardless of whether it came from
|
||||
# a CMock overlay or a CMock-only target file.
|
||||
# Returns the full unsupported test list for the current toolchain, combining:
|
||||
# - explicit :unsupported lists from the CMock overlay and Unity target files
|
||||
# - implicit criteria (tests that require defines not present in the toolchain)
|
||||
UNSUPPORTED_CRITERIA = {
|
||||
'out_of_memory' => { :defines => ['CMOCK_MEM_STATIC'] },
|
||||
'unity_64bit_support' => { :defines => ['UNITY_SUPPORT_64'] }
|
||||
}.freeze
|
||||
|
||||
def unsupported_tests
|
||||
$cmock_cfg[:unsupported] || $unity_cfg[:unsupported] || []
|
||||
result = ($cmock_cfg[:unsupported] || []) | ($unity_cfg[:unsupported] || [])
|
||||
conf_defs = all_defines
|
||||
UNSUPPORTED_CRITERIA.each_pair do |name, crit|
|
||||
result |= [name] if (crit[:defines] & conf_defs).empty?
|
||||
end
|
||||
result
|
||||
end
|
||||
|
||||
# Resolve Unity's argument template tokens and produce a flat argument string.
|
||||
# COLLECTION_PATHS_TEST_TOOLCHAIN_INCLUDE → -I per toolchain path (Arrays from :paths: :test:)
|
||||
# COLLECTION_PATHS_TEST_SUPPORT_SOURCE_INCLUDE_VENDOR → -I per project include path
|
||||
# COLLECTION_DEFINES_TEST_AND_VENDOR → -D per define
|
||||
# Resolve argument template tokens and produce a flat argument string.
|
||||
# Supports Ceedling-style positional tokens and legacy Unity COLLECTION_* tokens.
|
||||
# ${5} → expands to one arg per include path (toolchain paths + project paths combined)
|
||||
# ${6} → expands to one arg per define
|
||||
# ${1} → input file(s)
|
||||
# ${2} → output file
|
||||
# COLLECTION_PATHS_TEST_TOOLCHAIN_INCLUDE → (legacy) -I per toolchain path
|
||||
# COLLECTION_PATHS_TEST_SUPPORT_SOURCE_INCLUDE_VENDOR → (legacy) -I per project include path
|
||||
# COLLECTION_DEFINES_TEST_AND_VENDOR → (legacy) -D per define
|
||||
def build_argument_list(raw_args, toolchain_paths, project_paths, defines, input, output)
|
||||
result = []
|
||||
raw_args.each do |arg|
|
||||
if arg.is_a?(Array)
|
||||
result << arg.join
|
||||
elsif arg.include?('${5}')
|
||||
(toolchain_paths + project_paths).each do |p|
|
||||
result << arg.gsub('${5}', p.is_a?(Array) ? p.join : p.to_s)
|
||||
end
|
||||
elsif arg.include?('${6}')
|
||||
defines.each { |d| result << arg.gsub('${6}', d) }
|
||||
elsif arg.include?('COLLECTION_PATHS_TEST_TOOLCHAIN_INCLUDE')
|
||||
toolchain_paths.each { |p| result << "-I\"#{p.is_a?(Array) ? p.join : p}\"" }
|
||||
elsif arg.include?('COLLECTION_PATHS_TEST_SUPPORT_SOURCE_INCLUDE_VENDOR')
|
||||
@@ -166,8 +196,8 @@ module RakefileHelpers
|
||||
|
||||
def compile(file, extra_defines = [])
|
||||
tool = $unity_cfg[:tools][:test_compiler]
|
||||
ext = $unity_cfg[:extension][:object]
|
||||
build_root = $proj[:project][:build_root]
|
||||
ext = $unity_cfg[:extension][:object] || '.o'
|
||||
build_root = $proj[:project][:build_root] || 'build/'
|
||||
obj_file = build_root + File.basename(file, C_EXTENSION) + ext
|
||||
|
||||
cmd_str = tackit(tool[:executable]) + ' ' +
|
||||
@@ -181,8 +211,8 @@ module RakefileHelpers
|
||||
end
|
||||
|
||||
def link_it(exe_name, obj_list)
|
||||
tool = $unity_cfg[:tools][:test_linker]
|
||||
ext = $unity_cfg[:extension][:executable]
|
||||
tool = $unity_cfg[:tools][:test_linker]
|
||||
ext = $unity_cfg[:extension][:executable] || ''
|
||||
build_root = $proj[:project][:build_root]
|
||||
|
||||
input_files = obj_list.uniq.map { |obj| build_root + obj }.join(' ')
|
||||
@@ -209,7 +239,8 @@ module RakefileHelpers
|
||||
{ command: "#{executable} ", pre_support: pre, post_support: post }
|
||||
end
|
||||
|
||||
def execute(command_string, verbose=true, raise_on_failure=true)
|
||||
def execute(command_string, verbose=false, raise_on_failure=true)
|
||||
report(command_string) if verbose
|
||||
output = `#{command_string}`.chomp
|
||||
report(output) if (verbose && !output.nil? && (output.length > 0))
|
||||
if ($?.exitstatus != 0) and (raise_on_failure)
|
||||
@@ -224,7 +255,7 @@ module RakefileHelpers
|
||||
"--style=allman --indent=spaces=4 --indent-switches --indent-preproc-define --indent-preproc-block " \
|
||||
"--pad-oper --pad-comma --unpad-paren --pad-header " \
|
||||
"--align-pointer=type --align-reference=name " \
|
||||
"--add-brackets --mode=c --suffix=none " \
|
||||
"--mode=c --suffix=none " \
|
||||
"#{style_what}"
|
||||
execute(command, false)
|
||||
report "Styling C:PASS"
|
||||
@@ -269,7 +300,7 @@ module RakefileHelpers
|
||||
total_runs = total_failures = total_errors = total_skips = 0
|
||||
Dir['unit/*_test.rb'].sort.each do |tst|
|
||||
report "\nRunning #{tst.to_s}"
|
||||
output = execute("ruby -I. #{tst}", true, false)
|
||||
output = execute("ruby -I. #{tst} -v", true, false)
|
||||
output.each_line do |line|
|
||||
if line =~ /(\d+) runs, \d+ assertions, (\d+) failures, (\d+) errors, (\d+) skips/
|
||||
total_runs += Regexp.last_match(1).to_i
|
||||
@@ -300,20 +331,30 @@ module RakefileHelpers
|
||||
def run_system_test_interactions(test_case_files)
|
||||
load '../lib/cmock.rb'
|
||||
|
||||
SystemTestGenerator.new.generate_files(test_case_files)
|
||||
test_files = FileList.new(SYSTEST_GENERATED_FILES_PATH + 'test*.c')
|
||||
unsupported = unsupported_tests
|
||||
test_case_files = test_case_files.reject do |f|
|
||||
name = File.basename(f, YAML_EXTENSION)
|
||||
if unsupported.include?(name)
|
||||
report "Ignoring system test: #{name}"
|
||||
true
|
||||
end
|
||||
end
|
||||
|
||||
load_configuration($cfg_file)
|
||||
SystemTestGenerator.new.generate_files(test_case_files)
|
||||
|
||||
load_configuration($cfg_file, $cmock_test_overlay_file)
|
||||
|
||||
include_dirs = get_local_include_dirs
|
||||
|
||||
# Build and execute each unit test
|
||||
test_files.each do |test|
|
||||
test_case_files.each do |yaml|
|
||||
|
||||
obj_list = []
|
||||
|
||||
test_base = File.basename(test, C_EXTENSION)
|
||||
cmock_config = test_base.gsub(/test_/, '') + '_cmock.yml'
|
||||
name = File.basename(yaml, YAML_EXTENSION)
|
||||
test_base = 'test_' + name
|
||||
test = SYSTEST_GENERATED_FILES_PATH + test_base + C_EXTENSION
|
||||
cmock_config = name + '_cmock.yml'
|
||||
|
||||
report "Executing system tests in #{File.basename(test)}..."
|
||||
|
||||
@@ -345,7 +386,7 @@ module RakefileHelpers
|
||||
|
||||
# Execute unit test and generate results file
|
||||
simulator = build_simulator_fields
|
||||
ext = $unity_cfg[:extension][:executable]
|
||||
ext = $unity_cfg[:extension][:executable] || ''
|
||||
build_root = $proj[:project][:build_root]
|
||||
executable = build_root + test_base + ext
|
||||
cmd_str = if simulator.nil?
|
||||
@@ -363,6 +404,7 @@ module RakefileHelpers
|
||||
total_failures = 0
|
||||
failure_messages = []
|
||||
|
||||
report "\n\nSystem Testing Results: "
|
||||
test_case_files.each do |test_case|
|
||||
tests = (load_yaml(test_case))[:systest][:tests][:units]
|
||||
total_tests += tests.size
|
||||
@@ -382,11 +424,16 @@ module RakefileHelpers
|
||||
if (this_failed)
|
||||
total_failures += 1
|
||||
test_results[index] =~ /test#{index+1}:(.+)/
|
||||
failure_messages << "#{test_file}:test#{index+1}:should #{test[:should]}:#{$1}"
|
||||
end
|
||||
if (test[:verify_error]) and not (test_results[index] =~ /test#{index+1}:.*#{test[:verify_error]}/)
|
||||
new_msg = "#{test_file}:test#{index+1}:should #{test[:should]}:#{$1}"
|
||||
failure_messages << new_msg
|
||||
report new_msg
|
||||
elsif (test[:verify_error]) and not (test_results[index] =~ /test#{index+1}:.*#{test[:verify_error]}/)
|
||||
total_failures += 1
|
||||
failure_messages << "#{test_file}:test#{index+1}:should #{test[:should]}:should have output matching '#{test[:verify_error]}' but was '#{test_results[index]}'"
|
||||
new_msg = "#{test_file}:test#{index+1}:should #{test[:should]}:should have output matching '#{test[:verify_error]}' but was '#{test_results[index]}'"
|
||||
failure_messages << new_msg
|
||||
report new_msg
|
||||
else
|
||||
report "#{test_file}:test#{index+1}:should #{test[:should]}:PASS"
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -433,7 +480,16 @@ 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|
|
||||
name = File.basename(f, '.h')
|
||||
if unsupported.include?(name)
|
||||
report "Ignoring system test compilation: #{name}"
|
||||
true
|
||||
end
|
||||
end
|
||||
|
||||
report "\n"
|
||||
report "------------------------------------\n"
|
||||
@@ -453,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"
|
||||
@@ -476,7 +532,7 @@ module RakefileHelpers
|
||||
report "----------------\n"
|
||||
report "UNIT TEST C CODE\n"
|
||||
report "----------------\n"
|
||||
ext = $unity_cfg[:extension][:executable]
|
||||
ext = $unity_cfg[:extension][:executable] || ''
|
||||
build_root = $proj[:project][:build_root]
|
||||
combined_output = ''
|
||||
FileList.new("c/*.yml").each do |yaml_file|
|
||||
@@ -484,7 +540,7 @@ module RakefileHelpers
|
||||
report "\nTesting #{yaml_file.sub('.yml','')}"
|
||||
report "(#{test[:options].join(', ')})"
|
||||
test[:files].each { |f| compile(f, test[:options]) }
|
||||
obj_files = test[:files].map { |f| f.gsub!(/.*\//,'').gsub!(C_EXTENSION, $unity_cfg[:extension][:object]) }
|
||||
obj_files = test[:files].map { |f| f.gsub!(/.*\//,'').gsub!(C_EXTENSION, $unity_cfg[:extension][:object] || '.o') }
|
||||
link_it('TestCMockC', obj_files)
|
||||
simulator = build_simulator_fields
|
||||
executable = build_root + 'TestCMockC' + ext
|
||||
@@ -496,7 +552,7 @@ module RakefileHelpers
|
||||
raise "C unit tests failed." if result =~ /FAILED/
|
||||
end
|
||||
|
||||
def run_examples(verbose=false, raise_on_failure=true)
|
||||
def run_examples()
|
||||
report "\n"
|
||||
report "-----------------\n"
|
||||
report "VALIDATE EXAMPLES\n"
|
||||
@@ -504,11 +560,19 @@ module RakefileHelpers
|
||||
total_tests = 0
|
||||
total_failures = 0
|
||||
total_ignored = 0
|
||||
[ "cd #{File.join("..", "examples", "make_example")} && make clean && make setup && make test",
|
||||
"cd #{File.join("..", "examples", "temp_sensor")} && rake ci"
|
||||
].each do |cmd|
|
||||
report "Testing '#{cmd}'"
|
||||
execute(cmd, verbose, false).each_line do |line|
|
||||
cfg_file = "#{($cmock_test_config_file =~ /[\\\/]/) ? '../' : ''}#{$cmock_test_config_file}"
|
||||
|
||||
# Determine which examples are valid for this platform
|
||||
examples = {
|
||||
:make_example => "cd #{File.join("..", "examples", "make_example")} && make clean && make setup && make test",
|
||||
:rake_example => "cd #{File.join("..", "examples", "temp_sensor")} && rake config[\"#{cfg_file}\"] ci"
|
||||
}
|
||||
examples.delete(:make_example) unless ($cmock_test_config_file =~ /gcc/)
|
||||
|
||||
# Run the examples
|
||||
examples.each_pair do |key, cmd|
|
||||
report "Testing Example: '#{key}'"
|
||||
execute(cmd, true, false).each_line do |line|
|
||||
if line =~ /(\d+) TOTAL TESTS (\d+) TOTAL FAILURES (\d+) IGNORED/
|
||||
total_tests += Regexp.last_match(1).to_i
|
||||
total_failures += Regexp.last_match(2).to_i
|
||||
@@ -516,10 +580,12 @@ module RakefileHelpers
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Report the results from the examples
|
||||
result = "#{total_tests} Tests #{total_failures} Failures #{total_ignored} Ignored\n"
|
||||
result += total_failures > 0 ? "FAILED\n" : "OK\n"
|
||||
save_test_results('examples', result)
|
||||
raise "Examples failed." if total_failures > 0 && raise_on_failure
|
||||
raise "Examples failed." if total_failures > 0
|
||||
end
|
||||
|
||||
def fail_out(msg)
|
||||
|
||||
@@ -15,3 +15,6 @@
|
||||
:treat_as_void:
|
||||
- OSEK_TASK
|
||||
- VOID_TYPE_CRAZINESS
|
||||
:strippables:
|
||||
- SAMPLE_EXTERN
|
||||
- SAMPLE_MODE
|
||||
|
||||
@@ -24,15 +24,15 @@ void const_variants2(
|
||||
|
||||
const int * const_retval1(void); /* nicety version for pointer to constant int */
|
||||
int const * const_retval2(void); /* formal version for pointer to constant int */
|
||||
//int * const const_retval3(void); /* formal version for constant pointer to int */
|
||||
//int const * const const_retval4(void); /* formal version for constant pointer to constant int */
|
||||
int * const const_retval3(void); /* formal version for constant pointer to int */
|
||||
int const * const const_retval4(void); /* formal version for constant pointer to constant int */
|
||||
|
||||
const int* const_retval5(void); /* sticky-left nicety version for pointer to constant int */
|
||||
int const* const_retval6(void); /* sticky-left formal version for pointer to constant int */
|
||||
//int* const const_retval7(void); /* sticky-left formal version for constant pointer to int */
|
||||
//int const* const const_retval8(void); /* sticky-left formal version for constant pointer to constant int */
|
||||
int* const const_retval7(void); /* sticky-left formal version for constant pointer to int */
|
||||
int const* const const_retval8(void); /* sticky-left formal version for constant pointer to constant int */
|
||||
|
||||
const int *const_retval9(void); /* sticky-right nicety version for pointer to constant int */
|
||||
int const *const_retvalA(void); /* sticky-right formal version for pointer to constant int */
|
||||
//int *const const_retvalB(void); /* sticky-right formal version for constant pointer to int */
|
||||
//int const *const const_retvalC(void); /* sticky-right formal version for constant pointer to constant int */
|
||||
int *const const_retvalB(void); /* sticky-right formal version for constant pointer to int */
|
||||
int const *const const_retvalC(void); /* sticky-right formal version for constant pointer to constant int */
|
||||
|
||||
@@ -18,6 +18,16 @@ typedef struct _POINT_T
|
||||
int y;
|
||||
} POINT_T;
|
||||
|
||||
/* The comments in the following enum are important, as are the newlines and commas */
|
||||
/* This combination caused a curious bug when used together. Make sure it doesn't come back. */
|
||||
typedef enum
|
||||
{
|
||||
MY_ERROR_ID = -18,/**< Driver not ready */
|
||||
MY_OTHER_ID = -19 /**< Node-id is in LSS unconfigured
|
||||
state. If objects are handled properly,
|
||||
his may not be an error. */
|
||||
} MY_STATE_ID_T;
|
||||
|
||||
/* typedef edge case;
|
||||
not ANSI C but it has been done and will break cmock if not handled */
|
||||
typedef void VOID_TYPE_CRAZINESS;
|
||||
@@ -101,3 +111,19 @@ inline int stuff(int num)
|
||||
}
|
||||
return reg;
|
||||
}
|
||||
|
||||
/* it seems like CMock didn't love a func-looking struct before a func */
|
||||
#define FOO_TYPE(a) foo_##a
|
||||
struct FOO_TYPE(bar) { int baz; };
|
||||
char b(void);
|
||||
|
||||
/* Here are more macros that sorta look like functions. Only sample_func is real */
|
||||
#define SAMPLE_EXTERN
|
||||
#define SAMPLE_MODE
|
||||
#define SAMPLE_DEPRECATED(a,b)
|
||||
struct struct_a;
|
||||
struct struct_b;
|
||||
SAMPLE_EXTERN SAMPLE_MODE SAMPLE_DEPRECATED(1.1.2, "It was bad. real bad()")
|
||||
void sample_func(struct struct_a **a,
|
||||
struct struct_b **b,
|
||||
...);
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
@@ -110,7 +110,7 @@
|
||||
}
|
||||
|
||||
- :pass: TRUE
|
||||
:should: 'handle floating point numbers with Unity support: pass'
|
||||
:should: 'handle floating point numbers with Unity support to pass'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
@@ -119,7 +119,7 @@
|
||||
}
|
||||
|
||||
- :pass: FALSE
|
||||
:should: 'handle floating point numbers with Unity support: fail'
|
||||
:should: 'handle floating point numbers with Unity support to fail'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
const char const * bars(void);
|
||||
|
||||
:source:
|
||||
:header: |
|
||||
:header: |
|
||||
#include "CException.h"
|
||||
void function_a(void);
|
||||
void function_b(void);
|
||||
|
||||
@@ -7,19 +7,22 @@
|
||||
|
||||
---
|
||||
:cmock:
|
||||
:plugins: []
|
||||
:plugins: [ignore, expect_any_args, array]
|
||||
:treat_as:
|
||||
custom_type: INT
|
||||
|
||||
:systest:
|
||||
:types: |
|
||||
#define BIG_FAT_STRUCT_SIZE (512)
|
||||
typedef struct _BIG_FAT_STRUCT_T
|
||||
{
|
||||
char bytes[512];
|
||||
char bytes[BIG_FAT_STRUCT_SIZE];
|
||||
} BIG_FAT_STRUCT_T;
|
||||
|
||||
:mockable: |
|
||||
void foo(BIG_FAT_STRUCT_T a);
|
||||
int get_result(void);
|
||||
void process_data(int* data, int count);
|
||||
|
||||
:source:
|
||||
:header: |
|
||||
@@ -52,21 +55,75 @@
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
int i=0;
|
||||
BIG_FAT_STRUCT_T expected = { { 8, 0 } };
|
||||
foo_Expect(expected);
|
||||
function_a();
|
||||
// Fill expectations until there is not enough room for more.
|
||||
// We know we can ask one more when there is only enough room for 2 blocks, ignoring overhead.
|
||||
while (CMock_Guts_MemBytesFree() > (CMOCK_MEM_SIZE*2)) {
|
||||
i++;
|
||||
foo_Expect(expected);
|
||||
}
|
||||
for (; i>0; i--) {
|
||||
function_a();
|
||||
}
|
||||
}
|
||||
|
||||
- :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()
|
||||
{
|
||||
int i=0;
|
||||
BIG_FAT_STRUCT_T expected1 = { { 9, 1, 0 } };
|
||||
BIG_FAT_STRUCT_T expected2 = { { 9, 2, 0 } };
|
||||
foo_Expect(expected1);
|
||||
foo_Expect(expected2);
|
||||
function_b();
|
||||
// Ask for more room than we have
|
||||
while (CMock_Guts_MemBytesFree() > 0) {
|
||||
foo_Expect(expected1);
|
||||
foo_Expect(expected2);
|
||||
}
|
||||
|
||||
// It should not actually get here
|
||||
for (i=0; i < (CMOCK_MEM_SIZE/BIG_FAT_STRUCT_SIZE - 1); i++) {
|
||||
function_b();
|
||||
}
|
||||
}
|
||||
|
||||
- :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);
|
||||
}
|
||||
...
|
||||
@@ -1,12 +0,0 @@
|
||||
# =========================================================================
|
||||
# CMock - Automatic Mock Generation for C
|
||||
# ThrowTheSwitch.org
|
||||
# Copyright (c) 2007-26 Mike Karlesky, Mark VanderVoord, & Greg Williams
|
||||
# SPDX-License-Identifier: MIT
|
||||
# =========================================================================
|
||||
|
||||
# CMock overlay for vendor/unity/test/targets/clang_strict.yml
|
||||
# Only contains additions not present in the Unity base target.
|
||||
:unsupported:
|
||||
- out_of_memory
|
||||
- callingconv
|
||||
@@ -1,14 +0,0 @@
|
||||
# =========================================================================
|
||||
# CMock - Automatic Mock Generation for C
|
||||
# ThrowTheSwitch.org
|
||||
# Copyright (c) 2007-26 Mike Karlesky, Mark VanderVoord, & Greg Williams
|
||||
# SPDX-License-Identifier: MIT
|
||||
# =========================================================================
|
||||
|
||||
# CMock overlay for vendor/unity/test/targets/gcc_32.yml
|
||||
# Only contains additions not present in the Unity base target.
|
||||
---
|
||||
:unsupported:
|
||||
- out_of_memory
|
||||
- unity_64bit_support
|
||||
- callingconv
|
||||
@@ -1,12 +0,0 @@
|
||||
# =========================================================================
|
||||
# CMock - Automatic Mock Generation for C
|
||||
# ThrowTheSwitch.org
|
||||
# Copyright (c) 2007-26 Mike Karlesky, Mark VanderVoord, & Greg Williams
|
||||
# SPDX-License-Identifier: MIT
|
||||
# =========================================================================
|
||||
|
||||
# CMock overlay for vendor/unity/test/targets/gcc_64.yml
|
||||
# Only contains additions not present in the Unity base target.
|
||||
:unsupported:
|
||||
- out_of_memory
|
||||
- callingconv
|
||||
@@ -9,8 +9,6 @@
|
||||
# Only contains additions not present in the Unity base target.
|
||||
|
||||
:unsupported:
|
||||
- out_of_memory
|
||||
- nonstandard_parsed_stuff_1
|
||||
- const
|
||||
- callingconv
|
||||
- unity_64bit_support
|
||||
|
||||
@@ -31,7 +31,6 @@
|
||||
- struct_union_enum_expect_and_return
|
||||
- struct_union_enum_expect_and_return_with_plugins
|
||||
- stubs_with_callbacks
|
||||
- unity_64bit_support
|
||||
- unity_ignores
|
||||
- callingconv
|
||||
- C
|
||||
|
||||
@@ -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"
|
||||
@@ -1038,7 +1038,7 @@ describe CMockHeaderParser, "Verify CMockHeaderParser Module" do
|
||||
:ptr? => true,
|
||||
:const? => false,
|
||||
:const_ptr? => true,
|
||||
:str => "int* cmock_to_return",
|
||||
:str => "int* const cmock_to_return",
|
||||
:void? => false
|
||||
},
|
||||
:modifier=>"const",
|
||||
@@ -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
|
||||
|
||||
Vendored
+1
-1
Submodule vendor/unity updated: c7b0faabdc...bbf8f3728a
Reference in New Issue
Block a user