- add ceedling/cmock/unity as testing framework and support

- unified makefile project for the whole repos
- new separate project for tests
This commit is contained in:
hathach
2012-12-27 02:52:40 +07:00
parent f4fa62e032
commit bc735bbe22
157 changed files with 12981 additions and 292 deletions
@@ -0,0 +1,43 @@
#include "CException.h"
volatile CEXCEPTION_FRAME_T CExceptionFrames[CEXCEPTION_NUM_ID] = { 0 };
//------------------------------------------------------------------------------------------
// Throw
//------------------------------------------------------------------------------------------
void Throw(CEXCEPTION_T ExceptionID)
{
unsigned int MY_ID = CEXCEPTION_GET_ID;
CExceptionFrames[MY_ID].Exception = ExceptionID;
if (CExceptionFrames[MY_ID].pFrame)
{
longjmp(*CExceptionFrames[MY_ID].pFrame, 1);
}
CEXCEPTION_NO_CATCH_HANDLER(MY_ID);
}
//------------------------------------------------------------------------------------------
// Explanation of what it's all for:
//------------------------------------------------------------------------------------------
/*
#define Try
{ <- give us some local scope. most compilers are happy with this
jmp_buf *PrevFrame, NewFrame; <- prev frame points to the last try block's frame. new frame gets created on stack for this Try block
unsigned int MY_ID = CEXCEPTION_GET_ID; <- look up this task's id for use in frame array. always 0 if single-tasking
PrevFrame = CExceptionFrames[CEXCEPTION_GET_ID].pFrame; <- set pointer to point at old frame (which array is currently pointing at)
CExceptionFrames[MY_ID].pFrame = &NewFrame; <- set array to point at my new frame instead, now
CExceptionFrames[MY_ID].Exception = CEXCEPTION_NONE; <- initialize my exception id to be NONE
if (setjmp(NewFrame) == 0) { <- do setjmp. it returns 1 if longjump called, otherwise 0
if (&PrevFrame) <- this is here to force proper scoping. it requires braces or a single line to be but after Try, otherwise won't compile. This is always true at this point.
#define Catch(e)
else { } <- this also forces proper scoping. Without this they could stick their own 'else' in and it would get ugly
CExceptionFrames[MY_ID].Exception = CEXCEPTION_NONE; <- no errors happened, so just set the exception id to NONE (in case it was corrupted)
}
else <- an exception occurred
{ e = CExceptionFrames[MY_ID].Exception; e=e;} <- assign the caught exception id to the variable passed in.
CExceptionFrames[MY_ID].pFrame = PrevFrame; <- make the pointer in the array point at the previous frame again, as if NewFrame never existed.
} <- finish off that local scope we created to have our own variables
if (CExceptionFrames[CEXCEPTION_GET_ID].Exception != CEXCEPTION_NONE) <- start the actual 'catch' processing if we have an exception id saved away
*/
@@ -0,0 +1,86 @@
#ifndef _CEXCEPTION_H
#define _CEXCEPTION_H
#include <setjmp.h>
#ifdef __cplusplus
extern "C"
{
#endif
//To Use CException, you have a number of options:
//1. Just include it and run with the defaults
//2. Define any of the following symbols at the command line to override them
//3. Include a header file before CException.h everywhere which defines any of these
//4. Create an Exception.h in your path, and just define EXCEPTION_USE_CONFIG_FILE first
#ifdef CEXCEPTION_USE_CONFIG_FILE
#include "CExceptionConfig.h"
#endif
//This is the value to assign when there isn't an exception
#ifndef CEXCEPTION_NONE
#define CEXCEPTION_NONE (0x5A5A5A5A)
#endif
//This is number of exception stacks to keep track of (one per task)
#ifndef CEXCEPTION_NUM_ID
#define CEXCEPTION_NUM_ID (1) //there is only the one stack by default
#endif
//This is the method of getting the current exception stack index (0 if only one stack)
#ifndef CEXCEPTION_GET_ID
#define CEXCEPTION_GET_ID (0) //use the first index always because there is only one anyway
#endif
//The type to use to store the exception values.
#ifndef CEXCEPTION_T
#define CEXCEPTION_T unsigned int
#endif
//This is an optional special handler for when there is no global Catch
#ifndef CEXCEPTION_NO_CATCH_HANDLER
#define CEXCEPTION_NO_CATCH_HANDLER(id)
#endif
//exception frame structures
typedef struct {
jmp_buf* pFrame;
CEXCEPTION_T volatile Exception;
} CEXCEPTION_FRAME_T;
//actual root frame storage (only one if single-tasking)
extern volatile CEXCEPTION_FRAME_T CExceptionFrames[];
//Try (see C file for explanation)
#define Try \
{ \
jmp_buf *PrevFrame, NewFrame; \
unsigned int MY_ID = CEXCEPTION_GET_ID; \
PrevFrame = CExceptionFrames[CEXCEPTION_GET_ID].pFrame; \
CExceptionFrames[MY_ID].pFrame = (jmp_buf*)(&NewFrame); \
CExceptionFrames[MY_ID].Exception = CEXCEPTION_NONE; \
if (setjmp(NewFrame) == 0) { \
if (&PrevFrame)
//Catch (see C file for explanation)
#define Catch(e) \
else { } \
CExceptionFrames[MY_ID].Exception = CEXCEPTION_NONE; \
} \
else \
{ e = CExceptionFrames[MY_ID].Exception; e=e; } \
CExceptionFrames[MY_ID].pFrame = PrevFrame; \
} \
if (CExceptionFrames[CEXCEPTION_GET_ID].Exception != CEXCEPTION_NONE)
//Throw an Error
void Throw(CEXCEPTION_T ExceptionID);
#ifdef __cplusplus
} // extern "C"
#endif
#endif // _CEXCEPTION_H
@@ -0,0 +1,2 @@
16
@@ -0,0 +1,2 @@
1.2
@@ -0,0 +1,14 @@
# ==========================================
# CMock Project - Automatic Mock Generation for C
# Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams
# [Released under MIT License. Please refer to license.txt for details]
# ==========================================
# Setup our load path:
[
'lib',
].each do |dir|
$LOAD_PATH.unshift( File.join( File.expand_path(File.dirname(__FILE__)) + '/../', dir) )
end
@@ -0,0 +1,16 @@
# ==========================================
# CMock Project - Automatic Mock Generation for C
# Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams
# [Released under MIT License. Please refer to license.txt for details]
# ==========================================
# Setup our load path:
[
'lib',
'vendor/behaviors/lib',
'vendor/hardmock/lib',
'vendor/unity/auto/',
'test/system/'
].each do |dir|
$LOAD_PATH.unshift( File.join( File.expand_path(File.dirname(__FILE__) + "/../"), dir) )
end
+65
View File
@@ -0,0 +1,65 @@
# ==========================================
# CMock Project - Automatic Mock Generation for C
# Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams
# [Released under MIT License. Please refer to license.txt for details]
# ==========================================
[ "../config/production_environment",
"cmock_header_parser",
"cmock_generator",
"cmock_file_writer",
"cmock_config",
"cmock_plugin_manager",
"cmock_generator_utils",
"cmock_unityhelper_parser"].each {|req| require "#{File.expand_path(File.dirname(__FILE__))}/#{req}"}
class CMock
def initialize(options=nil)
cm_config = CMockConfig.new(options)
cm_unityhelper = CMockUnityHelperParser.new(cm_config)
cm_writer = CMockFileWriter.new(cm_config)
cm_gen_utils = CMockGeneratorUtils.new(cm_config, {:unity_helper => cm_unityhelper})
cm_gen_plugins = CMockPluginManager.new(cm_config, cm_gen_utils)
@cm_parser = CMockHeaderParser.new(cm_config)
@cm_generator = CMockGenerator.new(cm_config, cm_writer, cm_gen_utils, cm_gen_plugins)
@silent = (cm_config.verbosity < 2)
end
def setup_mocks(files)
[files].flatten.each do |src|
generate_mock src
end
end
private ###############################
def generate_mock(src)
name = File.basename(src, '.h')
puts "Creating mock for #{name}..." unless @silent
@cm_generator.create_mock(name, @cm_parser.parse(name, File.read(src)))
end
end
# Command Line Support ###############################
if ($0 == __FILE__)
usage = "usage: ruby #{__FILE__} (-oOptionsFile) File(s)ToMock"
if (!ARGV[0])
puts usage
exit 1
end
options = nil
filelist = []
ARGV.each do |arg|
if (arg =~ /^-o(\w*)/)
options = arg.gsub(/^-o/,'')
else
filelist << arg
end
end
CMock.new(options).setup_mocks(filelist)
end
+129
View File
@@ -0,0 +1,129 @@
# ==========================================
# CMock Project - Automatic Mock Generation for C
# Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams
# [Released under MIT License. Please refer to license.txt for details]
# ==========================================
class CMockConfig
CMockDefaultOptions =
{
:framework => :unity,
:mock_path => 'mocks',
:mock_prefix => 'Mock',
:plugins => [],
:strippables => ['(?:__attribute__\s*\(+.*?\)+)'],
:attributes => ['__ramfunc', '__irq', '__fiq', 'register', 'extern'],
:c_calling_conventions => ['__stdcall', '__cdecl', '__fastcall'],
:enforce_strict_ordering => false,
:unity_helper_path => false,
:treat_as => {},
:treat_as_void => [],
:memcmp_if_unknown => true,
:when_no_prototypes => :warn, #the options being :ignore, :warn, or :error
:when_ptr => :compare_data, #the options being :compare_ptr, :compare_data, or :smart
:verbosity => 2, #the options being 0 errors only, 1 warnings and errors, 2 normal info, 3 verbose
:treat_externs => :exclude, #the options being :include or :exclude
:ignore => :args_and_calls, #the options being :args_and_calls or :args_only
:callback_include_count => true,
:callback_after_arg_check => false,
:includes => nil,
:includes_h_pre_orig_header => nil,
:includes_h_post_orig_header => nil,
:includes_c_pre_header => nil,
:includes_c_post_header => nil
}
def initialize(options=nil)
case(options)
when NilClass then options = CMockDefaultOptions.clone
when String then options = CMockDefaultOptions.clone.merge(load_config_file_from_yaml(options))
when Hash then options = CMockDefaultOptions.clone.merge(options)
else raise "If you specify arguments, it should be a filename or a hash of options"
end
#do some quick type verification
[:plugins, :attributes, :treat_as_void].each do |opt|
unless (options[opt].class == Array)
options[opt] = []
puts "WARNING: :#{opt.to_s} should be an array." unless (options[:verbosity] < 1)
end
end
[:includes, :includes_h_pre_orig_header, :includes_h_post_orig_header, :includes_c_pre_header, :includes_c_post_header].each do |opt|
unless (options[opt].nil? or (options[opt].class == Array))
options[opt] = []
puts "WARNING: :#{opt.to_s} should be an array." unless (options[:verbosity] < 1)
end
end
options[:unity_helper_path] ||= options[:unity_helper]
options[:plugins].compact!
options[:plugins].map! {|p| p.to_sym}
@options = options
treat_as_map = standard_treat_as_map()#.clone
treat_as_map.merge!(@options[:treat_as])
@options[:treat_as] = treat_as_map
@options.each_key { |key| eval("def #{key.to_s}() return @options[:#{key.to_s}] end") }
end
def load_config_file_from_yaml yaml_filename
require 'yaml'
require 'fileutils'
YAML.load_file(yaml_filename)[:cmock]
end
def set_path(path)
@src_path = path
end
def load_unity_helper
return File.new(@options[:unity_helper_path]).read if (@options[:unity_helper_path])
return nil
end
def standard_treat_as_map
{
'int' => 'INT',
'char' => 'INT8',
'short' => 'INT16',
'long' => 'INT',
'int8' => 'INT8',
'int16' => 'INT16',
'int32' => 'INT',
'int8_t' => 'INT8',
'int16_t' => 'INT16',
'int32_t' => 'INT',
'INT8_T' => 'INT8',
'INT16_T' => 'INT16',
'INT32_T' => 'INT',
'bool' => 'INT',
'bool_t' => 'INT',
'BOOL' => 'INT',
'BOOL_T' => 'INT',
'unsigned int' => 'HEX32',
'unsigned long' => 'HEX32',
'uint32' => 'HEX32',
'uint32_t' => 'HEX32',
'UINT32' => 'HEX32',
'UINT32_T' => 'HEX32',
'void*' => 'PTR',
'unsigned short' => 'HEX16',
'uint16' => 'HEX16',
'uint16_t' => 'HEX16',
'UINT16' => 'HEX16',
'UINT16_T' => 'HEX16',
'unsigned char' => 'HEX8',
'uint8' => 'HEX8',
'uint8_t' => 'HEX8',
'UINT8' => 'HEX8',
'UINT8_T' => 'HEX8',
'char*' => 'STRING',
'pCHAR' => 'STRING',
'cstring' => 'STRING',
'CSTRING' => 'STRING',
'float' => 'FLOAT',
'double' => 'FLOAT'
}
end
end
@@ -0,0 +1,33 @@
# ==========================================
# CMock Project - Automatic Mock Generation for C
# Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams
# [Released under MIT License. Please refer to license.txt for details]
# ==========================================
class CMockFileWriter
attr_reader :config
def initialize(config)
@config = config
end
def create_file(filename)
raise "Where's the block of data to create?" unless block_given?
full_file_name_temp = "#{@config.mock_path}/#{filename}.new"
full_file_name_done = "#{@config.mock_path}/#{filename}"
File.open(full_file_name_temp, 'w') do |file|
yield(file, filename)
end
update_file(full_file_name_done, full_file_name_temp)
end
private ###################################
def update_file(dest, src)
require 'fileutils'
FileUtils.rm(dest) if (File.exist?(dest))
FileUtils.cp(src, dest)
FileUtils.rm(src)
end
end
@@ -0,0 +1,194 @@
# ==========================================
# CMock Project - Automatic Mock Generation for C
# Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams
# [Released under MIT License. Please refer to license.txt for details]
# ==========================================
$here = File.dirname __FILE__
class CMockGenerator
attr_accessor :config, :file_writer, :module_name, :mock_name, :utils, :plugins, :ordered
def initialize(config, file_writer, utils, plugins)
@file_writer = file_writer
@utils = utils
@plugins = plugins
@config = config
@prefix = @config.mock_prefix
@ordered = @config.enforce_strict_ordering
@framework = @config.framework.to_s
@includes_h_pre_orig_header = (@config.includes || @config.includes_h_pre_orig_header || []).map{|h| h =~ /</ ? h : "\"#{h}\""}
@includes_h_post_orig_header = (@config.includes_h_post_orig_header || []).map{|h| h =~ /</ ? h : "\"#{h}\""}
@includes_c_pre_header = (@config.includes_c_pre_header || []).map{|h| h =~ /</ ? h : "\"#{h}\""}
@includes_c_post_header = (@config.includes_c_post_header || []).map{|h| h =~ /</ ? h : "\"#{h}\""}
end
def create_mock(module_name, parsed_stuff)
@module_name = module_name
@mock_name = @prefix + @module_name
create_mock_header_file(parsed_stuff)
create_mock_source_file(parsed_stuff)
end
private if $ThisIsOnlyATest.nil? ##############################
def create_mock_header_file(parsed_stuff)
@file_writer.create_file(@mock_name + ".h") do |file, filename|
create_mock_header_header(file, filename)
create_mock_header_service_call_declarations(file)
create_typedefs(file, parsed_stuff[:typedefs])
parsed_stuff[:functions].each do |function|
file << @plugins.run(:mock_function_declarations, function)
end
create_mock_header_footer(file)
end
end
def create_mock_source_file(parsed_stuff)
@file_writer.create_file(@mock_name + ".c") do |file, filename|
create_source_header_section(file, filename)
create_instance_structure(file, parsed_stuff[:functions])
create_extern_declarations(file)
create_mock_verify_function(file, parsed_stuff[:functions])
create_mock_init_function(file)
create_mock_destroy_function(file, parsed_stuff[:functions])
parsed_stuff[:functions].each do |function|
create_mock_implementation(file, function)
create_mock_interfaces(file, function)
end
end
end
def create_mock_header_header(file, filename)
define_name = filename.gsub(/\.h/, "_h").upcase
orig_filename = filename.gsub(@config.mock_prefix, "")
file << "/* AUTOGENERATED FILE. DO NOT EDIT. */\n"
file << "#ifndef _#{define_name}\n"
file << "#define _#{define_name}\n\n"
@includes_h_pre_orig_header.each {|inc| file << "#include #{inc}\n"}
file << "#include \"#{orig_filename}\"\n"
@includes_h_post_orig_header.each {|inc| file << "#include #{inc}\n"}
plugin_includes = @plugins.run(:include_files)
file << plugin_includes if (!plugin_includes.empty?)
file << "\n"
end
def create_typedefs(file, typedefs)
file << "\n"
typedefs.each {|typedef| file << "#{typedef}\n" }
file << "\n\n"
end
def create_mock_header_service_call_declarations(file)
file << "void #{@mock_name}_Init(void);\n"
file << "void #{@mock_name}_Destroy(void);\n"
file << "void #{@mock_name}_Verify(void);\n\n"
end
def create_mock_header_footer(header)
header << "\n#endif\n"
end
def create_source_header_section(file, filename)
header_file = filename.gsub(".c",".h")
file << "/* AUTOGENERATED FILE. DO NOT EDIT. */\n"
file << "#include <string.h>\n"
file << "#include <stdlib.h>\n"
file << "#include <setjmp.h>\n"
file << "#include \"#{@framework}.h\"\n"
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"
end
def create_instance_structure(file, functions)
functions.each do |function|
file << "typedef struct _CMOCK_#{function[:name]}_CALL_INSTANCE\n{\n"
file << " UNITY_LINE_TYPE LineNumber;\n"
file << @plugins.run(:instance_typedefs, function)
file << "\n} CMOCK_#{function[:name]}_CALL_INSTANCE;\n\n"
end
file << "static struct #{@mock_name}Instance\n{\n"
if (functions.size == 0)
file << " unsigned char placeHolder;\n"
end
functions.each do |function|
file << @plugins.run(:instance_structure, function)
file << " CMOCK_MEM_INDEX_TYPE #{function[:name]}_CallInstance;\n"
end
file << "} Mock;\n\n"
end
def create_extern_declarations(file)
file << "extern jmp_buf AbortFrame;\n"
if (@ordered)
file << "extern int GlobalExpectCount;\n"
file << "extern int GlobalVerifyOrder;\n"
end
file << "\n"
end
def create_mock_verify_function(file, functions)
file << "void #{@mock_name}_Verify(void)\n{\n"
verifications = functions.collect {|function| @plugins.run(:mock_verify, function)}.join
file << " UNITY_LINE_TYPE cmock_line = TEST_LINE_NUM;\n" unless verifications.empty?
file << verifications
file << "}\n\n"
end
def create_mock_init_function(file)
file << "void #{@mock_name}_Init(void)\n{\n"
file << " #{@mock_name}_Destroy();\n"
file << "}\n\n"
end
def create_mock_destroy_function(file, functions)
file << "void #{@mock_name}_Destroy(void)\n{\n"
file << " CMock_Guts_MemFreeAll();\n"
file << " memset(&Mock, 0, sizeof(Mock));\n"
file << functions.collect {|function| @plugins.run(:mock_destroy, function)}.join
if (@ordered)
file << " GlobalExpectCount = 0;\n"
file << " GlobalVerifyOrder = 0;\n"
end
file << "}\n\n"
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]}" : '')
args_string = function[:args_string]
args_string += (", " + function[:var_arg]) unless (function[:var_arg].nil?)
# Create mock function
file << "#{function_mod_and_rettype} #{function[:name]}(#{args_string})\n"
file << "{\n"
file << " UNITY_LINE_TYPE cmock_line = TEST_LINE_NUM;\n"
file << " CMOCK_#{function[:name]}_CALL_INSTANCE* cmock_call_instance = (CMOCK_#{function[:name]}_CALL_INSTANCE*)CMock_Guts_GetAddressFor(Mock.#{function[:name]}_CallInstance);\n"
file << " Mock.#{function[:name]}_CallInstance = CMock_Guts_MemNext(Mock.#{function[:name]}_CallInstance);\n"
file << @plugins.run(:mock_implementation_precheck, function)
file << " UNITY_TEST_ASSERT_NOT_NULL(cmock_call_instance, cmock_line, \"Function '#{function[:name]}' called more times than expected.\");\n"
file << " cmock_line = cmock_call_instance->LineNumber;\n"
if (@ordered)
file << " if (cmock_call_instance->CallOrder > ++GlobalVerifyOrder)\n"
file << " UNITY_TEST_FAIL(cmock_line, \"Function '#{function[:name]}' called earlier than expected.\");\n"
file << " if (cmock_call_instance->CallOrder < GlobalVerifyOrder)\n"
file << " UNITY_TEST_FAIL(cmock_line, \"Function '#{function[:name]}' called later than expected.\");\n"
# file << " UNITY_TEST_ASSERT((cmock_call_instance->CallOrder == ++GlobalVerifyOrder), cmock_line, \"Out of order function calls. Function '#{function[:name]}'\");\n"
end
file << @plugins.run(:mock_implementation, function)
file << " return cmock_call_instance->ReturnVal;\n" unless (function[:return][:void?])
file << "}\n\n"
end
def create_mock_interfaces(file, function)
file << @utils.code_add_argument_loader(function)
file << @plugins.run(:mock_interfaces, function)
end
end
@@ -0,0 +1,57 @@
# ==========================================
# CMock Project - Automatic Mock Generation for C
# Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams
# [Released under MIT License. Please refer to license.txt for details]
# ==========================================
class CMockGeneratorPluginArray
attr_reader :priority
attr_accessor :config, :utils, :unity_helper, :ordered
def initialize(config, utils)
@config = config
@ptr_handling = @config.when_ptr
@ordered = @config.enforce_strict_ordering
@utils = utils
@unity_helper = @utils.helpers[:unity_helper]
@priority = 8
end
def instance_typedefs(function)
function[:args].inject("") do |all, arg|
(arg[:ptr?]) ? all + " int Expected_#{arg[:name]}_Depth;\n" : all
end
end
def mock_function_declarations(function)
return nil unless function[:contains_ptr?]
args_call = function[:args].map{|m| m[:ptr?] ? "#{m[:name]}, #{m[:name]}_Depth" : "#{m[:name]}"}.join(', ')
args_string = function[:args].map{|m| m[:ptr?] ? "#{m[:type]} #{m[:name]}, int #{m[:name]}_Depth" : "#{m[:type]} #{m[:name]}"}.join(', ')
if (function[:return][:void?])
return "#define #{function[:name]}_ExpectWithArray(#{args_call}) #{function[:name]}_CMockExpectWithArray(__LINE__, #{args_call})\n" +
"void #{function[:name]}_CMockExpectWithArray(UNITY_LINE_TYPE cmock_line, #{args_string});\n"
else
return "#define #{function[:name]}_ExpectWithArrayAndReturn(#{args_call}, cmock_retval) #{function[:name]}_CMockExpectWithArrayAndReturn(__LINE__, #{args_call}, cmock_retval)\n" +
"void #{function[:name]}_CMockExpectWithArrayAndReturn(UNITY_LINE_TYPE cmock_line, #{args_string}, #{function[:return][:str]});\n"
end
end
def mock_interfaces(function)
return nil unless function[:contains_ptr?]
lines = []
func_name = function[:name]
args_string = function[:args].map{|m| m[:ptr?] ? "#{m[:type]} #{m[:name]}, int #{m[:name]}_Depth" : "#{m[:type]} #{m[:name]}"}.join(', ')
call_string = function[:args].map{|m| m[:ptr?] ? "#{m[:name]}, #{m[:name]}_Depth" : m[:name]}.join(', ')
if (function[:return][:void?])
lines << "void #{func_name}_CMockExpectWithArray(UNITY_LINE_TYPE cmock_line, #{args_string})\n"
else
lines << "void #{func_name}_CMockExpectWithArrayAndReturn(UNITY_LINE_TYPE cmock_line, #{args_string}, #{function[:return][:str]})\n"
end
lines << "{\n"
lines << @utils.code_add_base_expectation(func_name)
lines << " CMockExpectParameters_#{func_name}(cmock_call_instance, #{call_string});\n"
lines << " cmock_call_instance->ReturnVal = cmock_to_return;\n" unless (function[:return][:void?])
lines << "}\n\n"
end
end
@@ -0,0 +1,78 @@
# ==========================================
# CMock Project - Automatic Mock Generation for C
# Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams
# [Released under MIT License. Please refer to license.txt for details]
# ==========================================
class CMockGeneratorPluginCallback
attr_accessor :include_count
attr_reader :priority
attr_reader :config, :utils
def initialize(config, utils)
@config = config
@utils = utils
@priority = 6
@include_count = @config.callback_include_count
if (@config.callback_after_arg_check)
alias :mock_implementation :mock_implementation_for_callbacks
alias :mock_implementation_precheck :nothing
else
alias :mock_implementation_precheck :mock_implementation_for_callbacks
alias :mock_implementation :nothing
end
end
def instance_structure(function)
func_name = function[:name]
" CMOCK_#{func_name}_CALLBACK #{func_name}_CallbackFunctionPointer;\n" +
" int #{func_name}_CallbackCalls;\n"
end
def mock_function_declarations(function)
func_name = function[:name]
return_type = function[:return][:const?] ? "const #{function[:return][:type]}" : function[:return][:type]
style = (@include_count ? 1 : 0) | (function[:args].empty? ? 0 : 2)
styles = [ "void", "int cmock_num_calls", function[:args_string], "#{function[:args_string]}, int cmock_num_calls" ]
"typedef #{return_type} (* CMOCK_#{func_name}_CALLBACK)(#{styles[style]});\nvoid #{func_name}_StubWithCallback(CMOCK_#{func_name}_CALLBACK Callback);\n"
end
def mock_implementation_for_callbacks(function)
func_name = function[:name]
style = (@include_count ? 1 : 0) | (function[:args].empty? ? 0 : 2) | (function[:return][:void?] ? 0 : 4)
" if (Mock.#{func_name}_CallbackFunctionPointer != NULL)\n {\n" +
case(style)
when 0 then " Mock.#{func_name}_CallbackFunctionPointer();\n return;\n }\n"
when 1 then " Mock.#{func_name}_CallbackFunctionPointer(Mock.#{func_name}_CallbackCalls++);\n return;\n }\n"
when 2 then " Mock.#{func_name}_CallbackFunctionPointer(#{function[:args].map{|m| m[:name]}.join(', ')});\n return;\n }\n"
when 3 then " Mock.#{func_name}_CallbackFunctionPointer(#{function[:args].map{|m| m[:name]}.join(', ')}, Mock.#{func_name}_CallbackCalls++);\n return;\n }\n"
when 4 then " return Mock.#{func_name}_CallbackFunctionPointer();\n }\n"
when 5 then " return Mock.#{func_name}_CallbackFunctionPointer(Mock.#{func_name}_CallbackCalls++);\n }\n"
when 6 then " return Mock.#{func_name}_CallbackFunctionPointer(#{function[:args].map{|m| m[:name]}.join(', ')});\n }\n"
when 7 then " return Mock.#{func_name}_CallbackFunctionPointer(#{function[:args].map{|m| m[:name]}.join(', ')}, Mock.#{func_name}_CallbackCalls++);\n }\n"
end
end
def nothing(function)
return ""
end
def mock_interfaces(function)
func_name = function[:name]
"void #{func_name}_StubWithCallback(CMOCK_#{func_name}_CALLBACK Callback)\n{\n" +
" Mock.#{func_name}_CallbackFunctionPointer = Callback;\n}\n\n"
end
def mock_destroy(function)
" Mock.#{function[:name]}_CallbackFunctionPointer = NULL;\n" +
" Mock.#{function[:name]}_CallbackCalls = 0;\n"
end
def mock_verify(function)
func_name = function[:name]
" if (Mock.#{func_name}_CallbackFunctionPointer != NULL)\n Mock.#{func_name}_CallInstance = CMOCK_GUTS_NONE;\n"
end
end
@@ -0,0 +1,51 @@
# ==========================================
# CMock Project - Automatic Mock Generation for C
# Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams
# [Released under MIT License. Please refer to license.txt for details]
# ==========================================
class CMockGeneratorPluginCexception
attr_reader :priority
attr_reader :config, :utils
def initialize(config, utils)
@config = config
@utils = utils
@priority = 7
end
def include_files
return "#include \"CException.h\"\n"
end
def instance_typedefs(function)
" CEXCEPTION_T ExceptionToThrow;\n"
end
def mock_function_declarations(function)
if (function[:args_string] == "void")
return "#define #{function[:name]}_ExpectAndThrow(cmock_to_throw) #{function[:name]}_CMockExpectAndThrow(__LINE__, cmock_to_throw)\n" +
"void #{function[:name]}_CMockExpectAndThrow(UNITY_LINE_TYPE cmock_line, CEXCEPTION_T cmock_to_throw);\n"
else
return "#define #{function[:name]}_ExpectAndThrow(#{function[:args_call]}, cmock_to_throw) #{function[:name]}_CMockExpectAndThrow(__LINE__, #{function[:args_call]}, cmock_to_throw)\n" +
"void #{function[:name]}_CMockExpectAndThrow(UNITY_LINE_TYPE cmock_line, #{function[:args_string]}, CEXCEPTION_T cmock_to_throw);\n"
end
end
def mock_implementation(function)
" if (cmock_call_instance->ExceptionToThrow != CEXCEPTION_NONE)\n {\n" +
" Throw(cmock_call_instance->ExceptionToThrow);\n }\n"
end
def mock_interfaces(function)
arg_insert = (function[:args_string] == "void") ? "" : "#{function[:args_string]}, "
call_string = function[:args].map{|m| m[:name]}.join(', ')
[ "void #{function[:name]}_CMockExpectAndThrow(UNITY_LINE_TYPE cmock_line, #{arg_insert}CEXCEPTION_T cmock_to_throw)\n{\n",
@utils.code_add_base_expectation(function[:name]),
@utils.code_call_argument_loader(function),
" cmock_call_instance->ExceptionToThrow = cmock_to_throw;\n",
"}\n\n" ].join
end
end
@@ -0,0 +1,86 @@
# ==========================================
# CMock Project - Automatic Mock Generation for C
# Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams
# [Released under MIT License. Please refer to license.txt for details]
# ==========================================
class CMockGeneratorPluginExpect
attr_reader :priority
attr_accessor :config, :utils, :unity_helper, :ordered
def initialize(config, utils)
@config = config
@ptr_handling = @config.when_ptr
@ordered = @config.enforce_strict_ordering
@utils = utils
@unity_helper = @utils.helpers[:unity_helper]
@priority = 5
end
def instance_typedefs(function)
lines = ""
lines << " #{function[:return][:type]} ReturnVal;\n" unless (function[:return][:void?])
lines << " int CallOrder;\n" if (@ordered)
function[:args].each do |arg|
lines << " #{arg[:type]} Expected_#{arg[:name]};\n"
end
lines
end
def mock_function_declarations(function)
if (function[:args].empty?)
if (function[:return][:void?])
return "#define #{function[:name]}_Expect() #{function[:name]}_CMockExpect(__LINE__)\n" +
"void #{function[:name]}_CMockExpect(UNITY_LINE_TYPE cmock_line);\n"
else
return "#define #{function[:name]}_ExpectAndReturn(cmock_retval) #{function[:name]}_CMockExpectAndReturn(__LINE__, cmock_retval)\n" +
"void #{function[:name]}_CMockExpectAndReturn(UNITY_LINE_TYPE cmock_line, #{function[:return][:str]});\n"
end
else
if (function[:return][:void?])
return "#define #{function[:name]}_Expect(#{function[:args_call]}) #{function[:name]}_CMockExpect(__LINE__, #{function[:args_call]})\n" +
"void #{function[:name]}_CMockExpect(UNITY_LINE_TYPE cmock_line, #{function[:args_string]});\n"
else
return "#define #{function[:name]}_ExpectAndReturn(#{function[:args_call]}, cmock_retval) #{function[:name]}_CMockExpectAndReturn(__LINE__, #{function[:args_call]}, cmock_retval)\n" +
"void #{function[:name]}_CMockExpectAndReturn(UNITY_LINE_TYPE cmock_line, #{function[:args_string]}, #{function[:return][:str]});\n"
end
end
end
def mock_implementation(function)
lines = ""
function[:args].each do |arg|
lines << @utils.code_verify_an_arg_expectation(function, arg)
end
lines
end
def mock_interfaces(function)
lines = ""
func_name = function[:name]
if (function[:return][:void?])
if (function[:args_string] == "void")
lines << "void #{func_name}_CMockExpect(UNITY_LINE_TYPE cmock_line)\n{\n"
else
lines << "void #{func_name}_CMockExpect(UNITY_LINE_TYPE cmock_line, #{function[:args_string]})\n{\n"
end
else
if (function[:args_string] == "void")
lines << "void #{func_name}_CMockExpectAndReturn(UNITY_LINE_TYPE cmock_line, #{function[:return][:str]})\n{\n"
else
lines << "void #{func_name}_CMockExpectAndReturn(UNITY_LINE_TYPE cmock_line, #{function[:args_string]}, #{function[:return][:str]})\n{\n"
end
end
lines << @utils.code_add_base_expectation(func_name)
lines << @utils.code_call_argument_loader(function)
lines << @utils.code_assign_argument_quickly("cmock_call_instance->ReturnVal", function[:return]) unless (function[:return][:void?])
lines << "}\n\n"
end
def mock_verify(function)
func_name = function[:name]
" UNITY_TEST_ASSERT(CMOCK_GUTS_NONE == Mock.#{func_name}_CallInstance, cmock_line, \"Function '#{func_name}' called less times than expected.\");\n"
end
end
@@ -0,0 +1,95 @@
# ==========================================
# CMock Project - Automatic Mock Generation for C
# Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams
# [Released under MIT License. Please refer to license.txt for details]
# ==========================================
class CMockGeneratorPluginIgnore
attr_reader :priority
attr_reader :config, :utils
def initialize(config, utils)
@config = config
if (@config.ignore == :args_and_calls)
alias :mock_implementation_precheck :mock_implementation_for_ignores
alias :mock_implementation :nothing
alias :mock_verify :mock_conditionally_verify_counts
else
alias :mock_implementation :mock_implementation_for_ignores
alias :mock_implementation_precheck :nothing
alias :mock_verify :nothing
end
@utils = utils
@priority = 2
end
def instance_structure(function)
if (function[:return][:void?])
" int #{function[:name]}_IgnoreBool;\n"
else
" int #{function[:name]}_IgnoreBool;\n #{function[:return][:type]} #{function[:name]}_FinalReturn;\n"
end
end
def mock_function_declarations(function)
if (function[:return][:void?])
if (@config.ignore == :args_only)
return "#define #{function[:name]}_Ignore() #{function[:name]}_CMockIgnore(__LINE__)\n" +
"void #{function[:name]}_CMockIgnore(UNITY_LINE_TYPE cmock_line);\n"
else
return "#define #{function[:name]}_Ignore() #{function[:name]}_CMockIgnore()\n" +
"void #{function[:name]}_CMockIgnore(void);\n"
end
else
return "#define #{function[:name]}_IgnoreAndReturn(cmock_retval) #{function[:name]}_CMockIgnoreAndReturn(__LINE__, cmock_retval)\n" +
"void #{function[:name]}_CMockIgnoreAndReturn(UNITY_LINE_TYPE cmock_line, #{function[:return][:str]});\n"
end
end
def mock_implementation_for_ignores(function)
lines = " if (Mock.#{function[:name]}_IgnoreBool)\n {\n"
if (function[:return][:void?])
lines << " return;\n }\n"
else
retval = function[:return].merge( { :name => "cmock_call_instance->ReturnVal"} )
lines << " if (cmock_call_instance == NULL)\n return Mock.#{function[:name]}_FinalReturn;\n"
lines << " " + @utils.code_assign_argument_quickly("Mock.#{function[:name]}_FinalReturn", retval) unless (retval[:void?])
lines << " return cmock_call_instance->ReturnVal;\n }\n"
end
lines
end
def mock_interfaces(function)
lines = ""
args_only = (@config.ignore == :args_only)
if (function[:return][:void?])
if (args_only)
lines << "void #{function[:name]}_CMockIgnore(UNITY_LINE_TYPE cmock_line)\n{\n"
else
lines << "void #{function[:name]}_CMockIgnore(void)\n{\n"
end
else
lines << "void #{function[:name]}_CMockIgnoreAndReturn(UNITY_LINE_TYPE cmock_line, #{function[:return][:str]})\n{\n"
end
if (args_only)
lines << @utils.code_add_base_expectation(function[:name], true)
elsif (!function[:return][:void?])
lines << @utils.code_add_base_expectation(function[:name], false)
end
unless (function[:return][:void?])
lines << " cmock_call_instance->ReturnVal = cmock_to_return;\n"
end
lines << " Mock.#{function[:name]}_IgnoreBool = (int)1;\n"
lines << "}\n\n"
end
def mock_conditionally_verify_counts(function)
func_name = function[:name]
" if (Mock.#{func_name}_IgnoreBool)\n Mock.#{func_name}_CallInstance = CMOCK_GUTS_NONE;\n"
end
def nothing(function)
return ""
end
end
@@ -0,0 +1,177 @@
# ==========================================
# CMock Project - Automatic Mock Generation for C
# Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams
# [Released under MIT License. Please refer to license.txt for details]
# ==========================================
class CMockGeneratorUtils
attr_accessor :config, :helpers, :ordered, :ptr_handling, :arrays, :cexception
def initialize(config, helpers={})
@config = config
@ptr_handling = @config.when_ptr
@ordered = @config.enforce_strict_ordering
@arrays = @config.plugins.include? :array
@cexception = @config.plugins.include? :cexception
@treat_as = @config.treat_as
@helpers = helpers
if (@arrays)
case(@ptr_handling)
when :smart then alias :code_verify_an_arg_expectation :code_verify_an_arg_expectation_with_smart_arrays
when :compare_data then alias :code_verify_an_arg_expectation :code_verify_an_arg_expectation_with_normal_arrays
when :compare_ptr then raise "ERROR: the array plugin doesn't enjoy working with :compare_ptr only. Disable one option."
end
else
alias :code_verify_an_arg_expectation :code_verify_an_arg_expectation_with_no_arrays
end
end
def code_add_base_expectation(func_name, global_ordering_supported=true)
lines = " CMOCK_MEM_INDEX_TYPE cmock_guts_index = CMock_Guts_MemNew(sizeof(CMOCK_#{func_name}_CALL_INSTANCE));\n"
lines << " CMOCK_#{func_name}_CALL_INSTANCE* cmock_call_instance = (CMOCK_#{func_name}_CALL_INSTANCE*)CMock_Guts_GetAddressFor(cmock_guts_index);\n"
lines << " UNITY_TEST_ASSERT_NOT_NULL(cmock_call_instance, cmock_line, \"CMock has run out of memory. Please allocate more.\");\n"
lines << " Mock.#{func_name}_CallInstance = CMock_Guts_MemChain(Mock.#{func_name}_CallInstance, cmock_guts_index);\n"
lines << " cmock_call_instance->LineNumber = cmock_line;\n"
lines << " cmock_call_instance->CallOrder = ++GlobalExpectCount;\n" if (@ordered and global_ordering_supported)
lines << " cmock_call_instance->ExceptionToThrow = CEXCEPTION_NONE;\n" if (@cexception)
lines
end
def code_add_an_arg_expectation(arg, depth=1)
lines = code_assign_argument_quickly("cmock_call_instance->Expected_#{arg[:name]}", arg)
lines << " cmock_call_instance->Expected_#{arg[:name]}_Depth = #{arg[:name]}_Depth;\n" if (@arrays and (depth.class == String))
lines
end
def code_assign_argument_quickly(dest, arg)
if (arg[:ptr?] or @treat_as.include?(arg[:type]))
" #{dest} = #{arg[:const?] ? "(#{arg[:type]})" : ''}#{arg[:name]};\n"
else
" memcpy(&#{dest}, &#{arg[:name]}, sizeof(#{arg[:type]}));\n"
end
end
def code_add_argument_loader(function)
if (function[:args_string] != "void")
if (@arrays)
args_string = function[:args].map do |m|
const_str = m[ :const? ] ? 'const ' : ''
m[:ptr?] ? "#{const_str}#{m[:type]} #{m[:name]}, int #{m[:name]}_Depth" : "#{const_str}#{m[:type]} #{m[:name]}"
end.join(', ')
"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) ) } +
"}\n\n"
else
"void CMockExpectParameters_#{function[:name]}(CMOCK_#{function[:name]}_CALL_INSTANCE* cmock_call_instance, #{function[:args_string]})\n{\n" +
function[:args].inject("") { |all, arg| all + code_add_an_arg_expectation(arg) } +
"}\n\n"
end
else
""
end
end
def code_call_argument_loader(function)
if (function[:args_string] != "void")
args = function[:args].map do |m|
(@arrays and m[:ptr?]) ? "#{m[:name]}, 1" : m[:name]
end
" CMockExpectParameters_#{function[:name]}(cmock_call_instance, #{args.join(', ')});\n"
else
""
end
end
#private ######################
def lookup_expect_type(function, arg)
c_type = arg[:type]
arg_name = arg[:name]
expected = "cmock_call_instance->Expected_#{arg_name}"
unity_func = if ((arg[:ptr?]) and ((c_type =~ /\*\*/) or (@ptr_handling == :compare_ptr)))
['UNITY_TEST_ASSERT_EQUAL_PTR', '']
else
(@helpers.nil? or @helpers[:unity_helper].nil?) ? ["UNITY_TEST_ASSERT_EQUAL",''] : @helpers[:unity_helper].get_helper(c_type)
end
unity_msg = "Function '#{function[:name]}' called with unexpected value for argument '#{arg_name}'."
return c_type, arg_name, expected, unity_func[0], unity_func[1], unity_msg
end
def code_verify_an_arg_expectation_with_no_arrays(function, arg)
c_type, arg_name, expected, unity_func, pre, unity_msg = lookup_expect_type(function, arg)
case(unity_func)
when "UNITY_TEST_ASSERT_EQUAL_MEMORY"
c_type_local = c_type.gsub(/\*$/,'')
return " UNITY_TEST_ASSERT_EQUAL_MEMORY((void*)(#{pre}#{expected}), (void*)(#{pre}#{arg_name}), sizeof(#{c_type_local}), cmock_line, \"#{unity_msg}\");\n"
when "UNITY_TEST_ASSERT_EQUAL_MEMORY"
[ " if (#{pre}#{expected} == NULL)",
" { UNITY_TEST_ASSERT_NULL(#{pre}#{arg_name}, cmock_line, \"Expected NULL. #{unity_msg}\"); }",
" else",
" { UNITY_TEST_ASSERT_EQUAL_MEMORY((void*)(#{pre}#{expected}), (void*)(#{pre}#{arg_name}), sizeof(#{c_type.sub('*','')}), cmock_line, \"#{unity_msg}\"); }\n"].join("\n")
when /_ARRAY/
[ " if (#{pre}#{expected} == NULL)",
" { UNITY_TEST_ASSERT_NULL(#{pre}#{arg_name}, cmock_line, \"Expected NULL. #{unity_msg}\"); }",
" else",
" { #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, 1, cmock_line, \"#{unity_msg}\"); }\n"].join("\n")
else
return " #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, cmock_line, \"#{unity_msg}\");\n"
end
end
def code_verify_an_arg_expectation_with_normal_arrays(function, arg)
c_type, arg_name, expected, unity_func, pre, unity_msg = lookup_expect_type(function, arg)
depth_name = (arg[:ptr?]) ? "cmock_call_instance->Expected_#{arg_name}_Depth" : 1
case(unity_func)
when "UNITY_TEST_ASSERT_EQUAL_MEMORY"
c_type_local = c_type.gsub(/\*$/,'')
return " UNITY_TEST_ASSERT_EQUAL_MEMORY((void*)(#{pre}#{expected}), (void*)(#{pre}#{arg_name}), sizeof(#{c_type_local}), cmock_line, \"#{unity_msg}\");\n"
when "UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY"
[ " if (#{pre}#{expected} == NULL)",
" { UNITY_TEST_ASSERT_NULL(#{pre}#{arg_name}, cmock_line, \"Expected NULL. #{unity_msg}\"); }",
" else",
" { UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY((void*)(#{pre}#{expected}), (void*)(#{pre}#{arg_name}), sizeof(#{c_type.sub('*','')}), #{depth_name}, cmock_line, \"#{unity_msg}\"); }\n"].compact.join("\n")
when /_ARRAY/
if (pre == '&')
" #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, #{depth_name}, cmock_line, \"#{unity_msg}\");\n"
else
[ " if (#{pre}#{expected} == NULL)",
" { UNITY_TEST_ASSERT_NULL(#{pre}#{arg_name}, cmock_line, \"Expected NULL. #{unity_msg}\"); }",
" else",
" { #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, #{depth_name}, cmock_line, \"#{unity_msg}\"); }\n"].compact.join("\n")
end
else
return " #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, cmock_line, \"#{unity_msg}\");\n"
end
end
def code_verify_an_arg_expectation_with_smart_arrays(function, arg)
c_type, arg_name, expected, unity_func, pre, unity_msg = lookup_expect_type(function, arg)
depth_name = (arg[:ptr?]) ? "cmock_call_instance->Expected_#{arg_name}_Depth" : 1
case(unity_func)
when "UNITY_TEST_ASSERT_EQUAL_MEMORY"
c_type_local = c_type.gsub(/\*$/,'')
return " UNITY_TEST_ASSERT_EQUAL_MEMORY((void*)(#{pre}#{expected}), (void*)(#{pre}#{arg_name}), sizeof(#{c_type_local}), cmock_line, \"#{unity_msg}\");\n"
when "UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY"
[ " if (#{pre}#{expected} == NULL)",
" { UNITY_TEST_ASSERT_NULL(#{arg_name}, cmock_line, \"Expected NULL. #{unity_msg}\"); }",
((depth_name != 1) ? " else if (#{depth_name} == 0)\n { UNITY_TEST_ASSERT_EQUAL_PTR(#{pre}#{expected}, #{pre}#{arg_name}, cmock_line, \"#{unity_msg}\"); }" : nil),
" else",
" { UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY((void*)(#{pre}#{expected}), (void*)(#{pre}#{arg_name}), sizeof(#{c_type.sub('*','')}), #{depth_name}, cmock_line, \"#{unity_msg}\"); }\n"].compact.join("\n")
when /_ARRAY/
if (pre == '&')
" #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, #{depth_name}, cmock_line, \"#{unity_msg}\");\n"
else
[ " if (#{pre}#{expected} == NULL)",
" { UNITY_TEST_ASSERT_NULL(#{pre}#{arg_name}, cmock_line, \"Expected NULL. #{unity_msg}\"); }",
((depth_name != 1) ? " else if (#{depth_name} == 0)\n { UNITY_TEST_ASSERT_EQUAL_PTR(#{pre}#{expected}, #{pre}#{arg_name}, cmock_line, \"#{unity_msg}\"); }" : nil),
" else",
" { #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, #{depth_name}, cmock_line, \"#{unity_msg}\"); }\n"].compact.join("\n")
end
else
return " #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, cmock_line, \"#{unity_msg}\");\n"
end
end
end
@@ -0,0 +1,277 @@
# ==========================================
# CMock Project - Automatic Mock Generation for C
# Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams
# [Released under MIT License. Please refer to license.txt for details]
# ==========================================
class CMockHeaderParser
attr_accessor :funcs, :c_attributes, :treat_as_void, :treat_externs
def initialize(cfg)
@funcs = []
@c_strippables = cfg.strippables
@c_attributes = (['const'] + cfg.attributes).uniq
@c_calling_conventions = cfg.c_calling_conventions.uniq
@treat_as_void = (['void'] + cfg.treat_as_void).uniq
@declaration_parse_matcher = /([\d\w\s\*\(\),\[\]]+??)\(([\d\w\s\*\(\),\.\[\]+-]*)\)$/m
@standards = (['int','short','char','long','unsigned','signed'] + cfg.treat_as.keys).uniq
@when_no_prototypes = cfg.when_no_prototypes
@local_as_void = @treat_as_void
@verbosity = cfg.verbosity
@treat_externs = cfg.treat_externs
@c_strippables += ['extern'] if (@treat_externs == :include) #we'll need to remove the attribute if we're allowing externs
end
def parse(name, source)
@module_name = name.gsub(/\W/,'')
@typedefs = []
@funcs = []
function_names = []
parse_functions( import_source(source) ).map do |decl|
func = parse_declaration(decl)
unless (function_names.include? func[:name])
@funcs << func
function_names << func[:name]
end
end
{ :includes => nil,
:functions => @funcs,
:typedefs => @typedefs
}
end
private if $ThisIsOnlyATest.nil? ################
def import_source(source)
# void must be void for cmock _ExpectAndReturn calls to process properly, not some weird typedef which equates to void
# to a certain extent, this action assumes we're chewing on pre-processed header files, otherwise we'll most likely just get stuff from @treat_as_void
@local_as_void = @treat_as_void
void_types = source.scan(/typedef\s+(?:\(\s*)?void(?:\s*\))?\s+([\w\d]+)\s*;/)
if void_types
@local_as_void += void_types.flatten.uniq.compact
end
# smush multiline macros into single line (checking for continuation character at end of line '\')
source.gsub!(/\s*\\\s*/m, ' ')
#remove comments (block and line, in three steps to ensure correct precedence)
source.gsub!(/\/\/(?:.+\/\*|\*(?:$|[^\/])).*$/, '') # remove line comments that comment out the start of blocks
source.gsub!(/\/\*.*?\*\//m, '') # remove block comments
source.gsub!(/\/\/.*$/, '') # remove line comments (all that remain)
# remove assembler pragma sections
source.gsub!(/^\s*#\s*pragma\s+asm\s+.*?#\s*pragma\s+endasm/m, '')
# remove gcc's __attribute__ tags
source.gsub(/__attrbute__\s*\(\(\.*\)\)/, '')
# remove preprocessor statements and extern "C"
source.gsub!(/^\s*#.*/, '')
source.gsub!(/extern\s+\"C\"\s+\{/, '')
# 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|typepdef)[\w\s]*\{[^\}]+\}[\w\s\*\,]*;/m, '') # remove struct, union, and enum definitions and typedefs with braces
source.gsub!(/(\W)(?:register|auto|static|restrict)(\W)/, '\1\2') # remove problem keywords
source.gsub!(/\s*=\s*['"a-zA-Z0-9_\.]+\s*/, '') # remove default value statements from argument lists
source.gsub!(/^(?:[\w\s]*\W)?typedef\W.*/, '') # remove typedef statements
source.gsub!(/(^|\W+)(?:#{@c_strippables.join('|')})(?=$|\W+)/,'\1') unless @c_strippables.empty? # remove known attributes slated to be stripped
#scan for functions which return function pointers, because they are a pain
source.gsub!(/([\w\s\*]+)\(*\(\s*\*([\w\s\*]+)\s*\(([\w\s\*,]*)\)\)\s*\(([\w\s\*,]*)\)\)*/) do |m|
functype = "cmock_#{@module_name}_func_ptr#{@typedefs.size + 1}"
@typedefs << "typedef #{$1.strip}(*#{functype})(#{$4});"
"#{functype} #{$2.strip}(#{$3});"
end
#drop extra white space to make the rest go faster
source.gsub!(/^\s+/, '') # remove extra white space from beginning of line
source.gsub!(/\s+$/, '') # remove extra white space from end of line
source.gsub!(/\s*\(\s*/, '(') # remove extra white space from before left parens
source.gsub!(/\s*\)\s*/, ')') # remove extra white space from before right parens
source.gsub!(/\s+/, ' ') # remove remaining extra white space
#split lines on semicolons and remove things that are obviously not what we are looking for
src_lines = source.split(/\s*;\s*/)
src_lines.delete_if {|line| line.strip.length == 0} # remove blank lines
src_lines.delete_if {|line| !(line =~ /[\w\s\*]+\(+\s*\*[\*\s]*[\w\s]+(?:\[[\w\s]*\]\s*)+\)+\s*\((?:[\w\s\*]*,?)*\s*\)/).nil?} #remove function pointer arrays
if (@treat_externs == :include)
src_lines.delete_if {|line| !(line =~ /(?:^|\s+)(?:inline)\s+/).nil?} # remove inline functions
else
src_lines.delete_if {|line| !(line =~ /(?:^|\s+)(?:extern|inline)\s+/).nil?} # remove inline and extern functions
end
end
def parse_functions(source)
funcs = []
source.each {|line| funcs << line.strip.gsub(/\s+/, ' ') if (line =~ @declaration_parse_matcher)}
if funcs.empty?
case @when_no_prototypes
when :error
raise "ERROR: No function prototypes found!"
when :warn
puts "WARNING: No function prototypes found!" unless (@verbosity < 1)
end
end
return funcs
end
def parse_args(arg_list)
args = []
arg_list.split(',').each do |arg|
arg.strip!
return args if (arg =~ /^\s*((\.\.\.)|(void))\s*$/) # we're done if we reach void by itself or ...
arg_array = arg.split
arg_elements = arg_array - @c_attributes # split up words and remove known attributes
args << { :type => (arg_type =arg_elements[0..-2].join(' ')),
:name => arg_elements[-1],
:ptr? => divine_ptr(arg_type),
:const? => arg_array.include?('const')
}
end
return args
end
def divine_ptr(arg_type)
return false unless arg_type.include? '*'
return false if arg_type.gsub(/(const|char|\*|\s)+/,'').empty?
return true
end
def clean_args(arg_list)
if ((@local_as_void.include?(arg_list.strip)) or (arg_list.empty?))
return 'void'
else
c=0
arg_list.gsub!(/(\w+)(?:\s*\[[\s\d\w+-]*\])+/,'*\1') # magically turn brackets into asterisks
arg_list.gsub!(/\s+\*/,'*') # remove space to place asterisks with type (where they belong)
arg_list.gsub!(/\*(\w)/,'* \1') # pull asterisks away from arg to place asterisks with type (where they belong)
#scan argument list for function pointers and replace them with custom types
arg_list.gsub!(/([\w\s\*]+)\(+\s*\*[\*\s]*([\w\s]*)\s*\)+\s*\(((?:[\w\s\*]*,?)*)\s*\)*/) do |m|
functype = "cmock_#{@module_name}_func_ptr#{@typedefs.size + 1}"
funcret = $1.strip
funcname = $2.strip
funcargs = $3.strip
funconst = ''
if (funcname.include? 'const')
funcname.gsub!('const','').strip!
funconst = 'const '
end
@typedefs << "typedef #{funcret}(*#{functype})(#{funcargs});"
funcname = "cmock_arg#{c+=1}" if (funcname.empty?)
"#{functype} #{funconst}#{funcname}"
end
#automatically name unnamed arguments (those that only had a type)
arg_list.split(/\s*,\s*/).map { |arg|
parts = (arg.split - ['struct', 'union', 'enum', 'const', 'const*'])
if ((parts.size < 2) or (parts[-1][-1].chr == '*') or (@standards.include?(parts[-1])))
"#{arg} cmock_arg#{c+=1}"
else
arg
end
}.join(', ')
end
end
def parse_declaration(declaration)
decl = {}
regex_match = @declaration_parse_matcher.match(declaration)
raise "Failed parsing function declaration: '#{declaration}'" if regex_match.nil?
#grab argument list
args = regex_match[2].strip
#process function attributes, return type, and name
descriptors = regex_match[1]
descriptors.gsub!(/\s+\*/,'*') #remove space to place asterisks with return type (where they belong)
descriptors.gsub!(/\*(\w)/,'* \1') #pull asterisks away from function name to place asterisks with return type (where they belong)
descriptors = descriptors.split #array of all descriptor strings
#grab name
decl[:name] = descriptors[-1] #snag name as last array item
#build attribute and return type strings
decl[:modifier] = []
rettype = []
descriptors[0..-2].each do |word|
if @c_attributes.include?(word)
decl[:modifier] << word
elsif @c_calling_conventions.include?(word)
decl[:c_calling_convention] = word
else
rettype << word
end
end
decl[:modifier] = decl[:modifier].join(' ')
rettype = rettype.join(' ')
rettype = 'void' if (@local_as_void.include?(rettype.strip))
decl[:return] = { :type => rettype,
:name => 'cmock_to_return',
:ptr? => divine_ptr(rettype),
:const? => rettype.split(/\s/).include?('const'),
:str => "#{rettype} cmock_to_return",
:void? => (rettype == 'void')
}
#remove default argument statements from mock definitions
args.gsub!(/=\s*[a-zA-Z0-9_\.]+\s*/, ' ')
#check for var args
if (args =~ /\.\.\./)
decl[:var_arg] = args.match( /[\w\s]*\.\.\./ ).to_s.strip
if (args =~ /\,[\w\s]*\.\.\./)
args = args.gsub!(/\,[\w\s]*\.\.\./,'')
else
args = 'void'
end
else
decl[:var_arg] = nil
end
args = clean_args(args)
decl[:args_string] = args
decl[:args] = parse_args(args)
decl[:args_call] = decl[:args].map{|a| a[:name]}.join(', ')
decl[:contains_ptr?] = decl[:args].inject(false) {|ptr, arg| arg[:ptr?] ? true : ptr }
if (decl[:return][:type].nil? or decl[:name].nil? or decl[:args].nil? or
decl[:return][:type].empty? or decl[:name].empty?)
raise "Failed Parsing Declaration Prototype!\n" +
" declaration: '#{declaration}'\n" +
" modifier: '#{decl[:modifier]}'\n" +
" return: #{prototype_inspect_hash(decl[:return])}\n" +
" function: '#{decl[:name]}'\n" +
" args: #{prototype_inspect_array_of_hashes(decl[:args])}\n"
end
return decl
end
def prototype_inspect_hash(hash)
pairs = []
hash.each_pair { |name, value| pairs << ":#{name} => #{"'" if (value.class == String)}#{value}#{"'" if (value.class == String)}" }
return "{#{pairs.join(', ')}}"
end
def prototype_inspect_array_of_hashes(array)
hashes = []
array.each { |hash| hashes << prototype_inspect_hash(hash) }
case (array.size)
when 0
return "[]"
when 1
return "[#{hashes[0]}]"
else
return "[\n #{hashes.join("\n ")}\n ]\n"
end
end
end
@@ -0,0 +1,40 @@
# ==========================================
# CMock Project - Automatic Mock Generation for C
# Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams
# [Released under MIT License. Please refer to license.txt for details]
# ==========================================
class CMockPluginManager
attr_accessor :plugins
def initialize(config, utils)
@plugins = []
plugins_to_load = [:expect, config.plugins].flatten.uniq.compact
plugins_to_load.each do |plugin|
plugin_name = plugin.to_s
object_name = "CMockGeneratorPlugin" + camelize(plugin_name)
begin
unless (Object.const_defined? object_name)
require "#{File.expand_path(File.dirname(__FILE__))}/cmock_generator_plugin_#{plugin_name.downcase}.rb"
end
@plugins << eval("#{object_name}.new(config, utils)")
rescue
raise "ERROR: CMock unable to load plugin '#{plugin_name}'"
end
end
@plugins.sort! {|a,b| a.priority <=> b.priority }
end
def run(method, args=nil)
if args.nil?
return @plugins.collect{ |plugin| plugin.send(method) if plugin.respond_to?(method) }.flatten.join
else
return @plugins.collect{ |plugin| plugin.send(method, args) if plugin.respond_to?(method) }.flatten.join
end
end
def camelize(lower_case_and_underscored_word)
lower_case_and_underscored_word.gsub(/\/(.?)/) { "::" + $1.upcase }.gsub(/(^|_)(.)/) { $2.upcase }
end
end
@@ -0,0 +1,75 @@
# ==========================================
# CMock Project - Automatic Mock Generation for C
# Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams
# [Released under MIT License. Please refer to license.txt for details]
# ==========================================
class CMockUnityHelperParser
attr_accessor :c_types
def initialize(config)
@config = config
@fallback = @config.plugins.include?(:array) ? 'UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY' : 'UNITY_TEST_ASSERT_EQUAL_MEMORY'
@c_types = map_C_types.merge(import_source)
end
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 (lookup =~ /\*$/)
lookup = lookup.gsub(/\*$/,'')
return [@c_types[lookup], '*'] if (@c_types[lookup])
else
lookup = lookup + '*'
return [@c_types[lookup], '&'] if (@c_types[lookup])
end
return ['UNITY_TEST_ASSERT_EQUAL_PTR', ''] if (ctype =~ /cmock_\w+_ptr\d+/)
raise("Don't know how to test #{ctype} and memory tests are disabled!") unless @config.memcmp_if_unknown
return (lookup =~ /\*$/) ? [@fallback, '&'] : [@fallback, '']
end
private ###########################
def map_C_types
c_types = {}
@config.treat_as.each_pair do |ctype, expecttype|
c_type = ctype.gsub(/\s+/,'_')
if (expecttype =~ /\*/)
c_types[c_type] = "UNITY_TEST_ASSERT_EQUAL_#{expecttype.gsub(/\*/,'')}_ARRAY"
else
c_types[c_type] = "UNITY_TEST_ASSERT_EQUAL_#{expecttype}"
c_types[c_type+'*'] ||= "UNITY_TEST_ASSERT_EQUAL_#{expecttype}_ARRAY"
end
end
c_types
end
def import_source
source = @config.load_unity_helper
return {} if source.nil?
c_types = {}
source = source.gsub(/\/\/.*$/, '') #remove line comments
source = source.gsub(/\/\*.*?\*\//m, '') #remove block comments
#scan for comparison helpers
match_regex = Regexp.new('^\s*#define\s+(UNITY_TEST_ASSERT_EQUAL_(\w+))\s*\(' + Array.new(4,'\s*\w+\s*').join(',') + '\)')
pairs = source.scan(match_regex).flatten.compact
(pairs.size/2).times do |i|
expect = pairs[i*2]
ctype = pairs[(i*2)+1]
c_types[ctype] = expect unless expect.include?("_ARRAY")
end
#scan for array variants of those helpers
match_regex = Regexp.new('^\s*#define\s+(UNITY_TEST_ASSERT_EQUAL_(\w+_ARRAY))\s*\(' + Array.new(5,'\s*\w+\s*').join(',') + '\)')
pairs = source.scan(match_regex).flatten.compact
(pairs.size/2).times do |i|
expect = pairs[i*2]
ctype = pairs[(i*2)+1]
c_types[ctype.gsub('_ARRAY','*')] = expect
end
c_types
end
end
+2
View File
@@ -0,0 +1,2 @@
212
@@ -0,0 +1,2 @@
2.0
+186
View File
@@ -0,0 +1,186 @@
/* ==========================================
CMock Project - Automatic Mock Generation for C
Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams
[Released under MIT License. Please refer to license.txt for details]
========================================== */
#include "unity.h"
#include "cmock.h"
//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
#endif
#ifdef CMOCK_MEM_DYNAMIC
#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
#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
#define CMOCK_MEM_ALIGN (2)
#endif
//amount of memory to allow cmock to use in its internal heap
#ifndef CMOCK_MEM_SIZE
#define CMOCK_MEM_SIZE (32768)
#endif
//automatically calculated defs for easier reading
#define CMOCK_MEM_ALIGN_SIZE (1u << CMOCK_MEM_ALIGN)
#define CMOCK_MEM_ALIGN_MASK (CMOCK_MEM_ALIGN_SIZE - 1)
#define CMOCK_MEM_INDEX_SIZE ((sizeof(CMOCK_MEM_INDEX_TYPE) > CMOCK_MEM_ALIGN_SIZE) ? sizeof(CMOCK_MEM_INDEX_TYPE) : CMOCK_MEM_ALIGN_SIZE)
//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;
#else
static unsigned char CMock_Guts_Buffer[CMOCK_MEM_SIZE + CMOCK_MEM_ALIGN_SIZE];
static CMOCK_MEM_INDEX_TYPE CMock_Guts_BufferSize = CMOCK_MEM_SIZE + CMOCK_MEM_ALIGN_SIZE;
static CMOCK_MEM_INDEX_TYPE CMock_Guts_FreePtr;
#endif
//-------------------------------------------------------
// CMock_Guts_MemNew
//-------------------------------------------------------
CMOCK_MEM_INDEX_TYPE CMock_Guts_MemNew(CMOCK_MEM_INDEX_TYPE size)
{
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 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)
{
#ifdef CMOCK_MEM_DYNAMIC
CMock_Guts_BufferSize += CMOCK_MEM_SIZE + size;
CMock_Guts_Buffer = realloc(CMock_Guts_Buffer, CMock_Guts_BufferSize);
if (CMock_Guts_Buffer == NULL)
#endif //yes that if will continue to the return below if TRUE
return CMOCK_GUTS_NONE;
}
//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;
}
//-------------------------------------------------------
// CMock_Guts_MemChain
//-------------------------------------------------------
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;
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))
{
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_PTR_AS_INT)obj - (CMOCK_MEM_PTR_AS_INT)CMock_Guts_Buffer);
return root_index;
}
}
//-------------------------------------------------------
// CMock_Guts_MemNext
//-------------------------------------------------------
CMOCK_MEM_INDEX_TYPE CMock_Guts_MemNext(CMOCK_MEM_INDEX_TYPE previous_item_index)
{
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]);
//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;
}
//-------------------------------------------------------
// CMock_GetAddressFor
//-------------------------------------------------------
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;
}
}
//-------------------------------------------------------
// CMock_Guts_MemBytesFree
//-------------------------------------------------------
CMOCK_MEM_INDEX_TYPE CMock_Guts_MemBytesFree(void)
{
return CMock_Guts_BufferSize - CMock_Guts_FreePtr;
}
//-------------------------------------------------------
// CMock_Guts_MemBytesUsed
//-------------------------------------------------------
CMOCK_MEM_INDEX_TYPE CMock_Guts_MemBytesUsed(void)
{
return CMock_Guts_FreePtr - CMOCK_MEM_ALIGN_SIZE;
}
//-------------------------------------------------------
// CMock_Guts_MemFreeAll
//-------------------------------------------------------
void CMock_Guts_MemFreeAll(void)
{
CMock_Guts_FreePtr = CMOCK_MEM_ALIGN_SIZE; //skip the very beginning
}
+30
View File
@@ -0,0 +1,30 @@
/* ==========================================
CMock Project - Automatic Mock Generation for C
Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams
[Released under MIT License. Please refer to license.txt for details]
========================================== */
#ifndef CMOCK_FRAMEWORK_H
#define CMOCK_FRAMEWORK_H
//should be big enough to index full range of CMOCK_MEM_MAX
#ifndef CMOCK_MEM_INDEX_TYPE
#define CMOCK_MEM_INDEX_TYPE unsigned int
#endif
#define CMOCK_GUTS_NONE (0)
//-------------------------------------------------------
// Memory API
//-------------------------------------------------------
CMOCK_MEM_INDEX_TYPE CMock_Guts_MemNew(CMOCK_MEM_INDEX_TYPE size);
CMOCK_MEM_INDEX_TYPE CMock_Guts_MemChain(CMOCK_MEM_INDEX_TYPE root_index, CMOCK_MEM_INDEX_TYPE obj_index);
CMOCK_MEM_INDEX_TYPE CMock_Guts_MemNext(CMOCK_MEM_INDEX_TYPE previous_item_index);
void* CMock_Guts_GetAddressFor(CMOCK_MEM_INDEX_TYPE index);
CMOCK_MEM_INDEX_TYPE CMock_Guts_MemBytesFree(void);
CMOCK_MEM_INDEX_TYPE CMock_Guts_MemBytesUsed(void);
void CMock_Guts_MemFreeAll(void);
#endif //CMOCK_FRAMEWORK
@@ -0,0 +1,127 @@
CONSTRUCTOR_VERSION = '1.0.4' #:nodoc:#
class Class #:nodoc:#
def constructor(*attrs, &block)
call_block = ''
if block_given?
@constructor_block = block
call_block = 'self.instance_eval(&self.class.constructor_block)'
end
# Look for embedded options in the listing:
opts = attrs.find { |a| a.kind_of?(Hash) and attrs.delete(a) }
do_acc = opts.nil? ? false : opts[:accessors] == true
do_reader = opts.nil? ? false : opts[:readers] == true
require_args = opts.nil? ? true : opts[:strict] != false
super_args = opts.nil? ? nil : opts[:super]
# Incorporate superclass's constructor keys, if our superclass
if superclass.constructor_keys
similar_keys = superclass.constructor_keys & attrs
raise "Base class already has keys #{similar_keys.inspect}" unless similar_keys.empty?
attrs = [attrs,superclass.constructor_keys].flatten
end
# Generate ivar assigner code lines
assigns = ''
attrs.each do |k|
assigns += "@#{k.to_s} = args[:#{k.to_s}]\n"
end
# If accessors option is on, declare accessors for the attributes:
if do_acc
add_accessors = "attr_accessor " + attrs.reject {|x| superclass.constructor_keys.include?(x.to_sym)}.map {|x| ":#{x.to_s}"}.join(',')
#add_accessors = "attr_accessor " + attrs.map {|x| ":#{x.to_s}"}.join(',')
self.class_eval add_accessors
end
# If readers option is on, declare readers for the attributes:
if do_reader
self.class_eval "attr_reader " + attrs.reject {|x| superclass.constructor_keys.include?(x.to_sym)}.map {|x| ":#{x.to_s}"}.join(',')
end
# If user supplied super-constructor hints:
super_call = ''
if super_args
list = super_args.map do |a|
case a
when String
%|"#{a}"|
when Symbol
%|:#{a}|
end
end
super_call = %|super(#{list.join(',')})|
end
# If strict is on, define the constructor argument validator method,
# and setup the initializer to invoke the validator method.
# Otherwise, insert lax code into the initializer.
validation_code = "return if args.nil?"
if require_args
self.class_eval do
def _validate_constructor_args(args)
# First, make sure we've got args of some kind
unless args and args.keys and args.keys.size > 0
raise ConstructorArgumentError.new(self.class.constructor_keys)
end
# Scan for missing keys in the argument hash
a_keys = args.keys
missing = []
self.class.constructor_keys.each do |ck|
unless a_keys.member?(ck)
missing << ck
end
a_keys.delete(ck) # Delete inbound keys as we address them
end
if missing.size > 0 || a_keys.size > 0
raise ConstructorArgumentError.new(missing,a_keys)
end
end
end
# Setup the code to insert into the initializer:
validation_code = "_validate_constructor_args args "
end
# Generate the initializer code
self.class_eval %{
def initialize(args=nil)
#{super_call}
#{validation_code}
#{assigns}
setup if respond_to?(:setup)
#{call_block}
end
}
# Remember our constructor keys
@_ctor_keys = attrs
end
# Access the constructor keys for this class
def constructor_keys; @_ctor_keys ||=[]; end
def constructor_block #:nodoc:#
@constructor_block
end
end
# Fancy validation exception, based on missing and extraneous keys.
class ConstructorArgumentError < RuntimeError #:nodoc:#
def initialize(missing,rejected=[])
err_msg = ''
if missing.size > 0
err_msg = "Missing constructor args [#{missing.join(',')}]"
end
if rejected.size > 0
# Some inbound keys were not addressed earlier; this means they're unwanted
if err_msg
err_msg << "; " # Appending to earlier message about missing items
else
err_msg = ''
end
# Enumerate the rejected key names
err_msg << "Rejected constructor args [#{rejected.join(',')}]"
end
super err_msg
end
end
@@ -0,0 +1,33 @@
class ConstructorStruct
def self.new(*accessors, &block)
defaults = {:accessors => true, :strict => false}
accessor_names = accessors.dup
if accessors.last.is_a? Hash
accessor_names.pop
user_opts = accessors.last
user_opts.delete(:accessors)
defaults.each do |k,v|
user_opts[k] ||= v
end
else
accessors << defaults
end
Class.new do
constructor *accessors
class_eval(&block) if block
comparator_code = accessor_names.map { |fname| "self.#{fname} == o.#{fname}" }.join(" && ")
eval %|
def ==(o)
(self.class == o.class) && #{comparator_code}
end
def eql?(o)
(self.class == o.class) && #{comparator_code}
end
|
end
end
end
@@ -0,0 +1,211 @@
module DeepMerge
MAJOR_VERSION = 0
MINOR_VERSION = 1
FIX_VERSION = 0
VERSION = "#{MAJOR_VERSION}.#{MINOR_VERSION}.#{FIX_VERSION}"
class InvalidParameter < StandardError; end
DEFAULT_FIELD_KNOCKOUT_PREFIX = '--'
module DeepMergeHash
# ko_hash_merge! will merge and knockout elements prefixed with DEFAULT_FIELD_KNOCKOUT_PREFIX
def ko_deep_merge!(source, options = {})
default_opts = {:knockout_prefix => "--", :preserve_unmergeables => false}
DeepMerge::deep_merge!(source, self, default_opts.merge(options))
end
# deep_merge! will merge and overwrite any unmergeables in destination hash
def deep_merge!(source, options = {})
default_opts = {:preserve_unmergeables => false}
DeepMerge::deep_merge!(source, self, default_opts.merge(options))
end
# deep_merge will merge and skip any unmergeables in destination hash
def deep_merge(source, options = {})
default_opts = {:preserve_unmergeables => true}
DeepMerge::deep_merge!(source, self, default_opts.merge(options))
end
end # DeepMergeHashExt
# Deep Merge core documentation.
# deep_merge! method permits merging of arbitrary child elements. The two top level
# elements must be hashes. These hashes can contain unlimited (to stack limit) levels
# of child elements. These child elements to not have to be of the same types.
# Where child elements are of the same type, deep_merge will attempt to merge them together.
# Where child elements are not of the same type, deep_merge will skip or optionally overwrite
# the destination element with the contents of the source element at that level.
# So if you have two hashes like this:
# source = {:x => [1,2,3], :y => 2}
# dest = {:x => [4,5,'6'], :y => [7,8,9]}
# dest.deep_merge!(source)
# Results: {:x => [1,2,3,4,5,'6'], :y => 2}
# By default, "deep_merge!" will overwrite any unmergeables and merge everything else.
# To avoid this, use "deep_merge" (no bang/exclamation mark)
#
# Options:
# Options are specified in the last parameter passed, which should be in hash format:
# hash.deep_merge!({:x => [1,2]}, {:knockout_prefix => '--'})
# :preserve_unmergeables DEFAULT: false
# Set to true to skip any unmergeable elements from source
# :knockout_prefix DEFAULT: nil
# Set to string value to signify prefix which deletes elements from existing element
# :sort_merged_arrays DEFAULT: false
# Set to true to sort all arrays that are merged together
# :unpack_arrays DEFAULT: nil
# Set to string value to run "Array::join" then "String::split" against all arrays
# :merge_debug DEFAULT: false
# Set to true to get console output of merge process for debugging
#
# Selected Options Details:
# :knockout_prefix => The purpose of this is to provide a way to remove elements
# from existing Hash by specifying them in a special way in incoming hash
# source = {:x => ['--1', '2']}
# dest = {:x => ['1', '3']}
# dest.ko_deep_merge!(source)
# Results: {:x => ['2','3']}
# Additionally, if the knockout_prefix is passed alone as a string, it will cause
# the entire element to be removed:
# source = {:x => '--'}
# dest = {:x => [1,2,3]}
# dest.ko_deep_merge!(source)
# Results: {:x => ""}
# :unpack_arrays => The purpose of this is to permit compound elements to be passed
# in as strings and to be converted into discrete array elements
# irsource = {:x => ['1,2,3', '4']}
# dest = {:x => ['5','6','7,8']}
# dest.deep_merge!(source, {:unpack_arrays => ','})
# Results: {:x => ['1','2','3','4','5','6','7','8'}
# Why: If receiving data from an HTML form, this makes it easy for a checkbox
# to pass multiple values from within a single HTML element
#
# There are many tests for this library - and you can learn more about the features
# and usages of deep_merge! by just browsing the test examples
def DeepMerge.deep_merge!(source, dest, options = {})
# turn on this line for stdout debugging text
merge_debug = options[:merge_debug] || false
overwrite_unmergeable = !options[:preserve_unmergeables]
knockout_prefix = options[:knockout_prefix] || nil
if knockout_prefix == "" then raise InvalidParameter, "knockout_prefix cannot be an empty string in deep_merge!"; end
if knockout_prefix && !overwrite_unmergeable then raise InvalidParameter, "overwrite_unmergeable must be true if knockout_prefix is specified in deep_merge!"; end
# if present: we will split and join arrays on this char before merging
array_split_char = options[:unpack_arrays] || false
# request that we sort together any arrays when they are merged
sort_merged_arrays = options[:sort_merged_arrays] || false
di = options[:debug_indent] || ''
# do nothing if source is nil
if source.nil? || (source.respond_to?(:blank?) && source.blank?) then return dest; end
# if dest doesn't exist, then simply copy source to it
if dest.nil? && overwrite_unmergeable then dest = source; return dest; end
puts "#{di}Source class: #{source.class.inspect} :: Dest class: #{dest.class.inspect}" if merge_debug
if source.kind_of?(Hash)
puts "#{di}Hashes: #{source.inspect} :: #{dest.inspect}" if merge_debug
source.each do |src_key, src_value|
if dest.kind_of?(Hash)
puts "#{di} looping: #{src_key.inspect} => #{src_value.inspect} :: #{dest.inspect}" if merge_debug
if not dest[src_key].nil?
puts "#{di} ==>merging: #{src_key.inspect} => #{src_value.inspect} :: #{dest[src_key].inspect}" if merge_debug
dest[src_key] = deep_merge!(src_value, dest[src_key], options.merge(:debug_indent => di + ' '))
else # dest[src_key] doesn't exist so we want to create and overwrite it (but we do this via deep_merge!)
puts "#{di} ==>merging over: #{src_key.inspect} => #{src_value.inspect}" if merge_debug
# note: we rescue here b/c some classes respond to "dup" but don't implement it (Numeric, TrueClass, FalseClass, NilClass among maybe others)
begin
src_dup = src_value.dup # we dup src_value if possible because we're going to merge into it (since dest is empty)
rescue TypeError
src_dup = src_value
end
dest[src_key] = deep_merge!(src_value, src_dup, options.merge(:debug_indent => di + ' '))
end
else # dest isn't a hash, so we overwrite it completely (if permitted)
if overwrite_unmergeable
puts "#{di} overwriting dest: #{src_key.inspect} => #{src_value.inspect} -over-> #{dest.inspect}" if merge_debug
dest = overwrite_unmergeables(source, dest, options)
end
end
end
elsif source.kind_of?(Array)
puts "#{di}Arrays: #{source.inspect} :: #{dest.inspect}" if merge_debug
# if we are instructed, join/split any source arrays before processing
if array_split_char
puts "#{di} split/join on source: #{source.inspect}" if merge_debug
source = source.join(array_split_char).split(array_split_char)
if dest.kind_of?(Array) then dest = dest.join(array_split_char).split(array_split_char); end
end
# if there's a naked knockout_prefix in source, that means we are to truncate dest
if source.index(knockout_prefix) then dest = clear_or_nil(dest); source.delete(knockout_prefix); end
if dest.kind_of?(Array)
if knockout_prefix
print "#{di} knocking out: " if merge_debug
# remove knockout prefix items from both source and dest
source.delete_if do |ko_item|
retval = false
item = ko_item.respond_to?(:gsub) ? ko_item.gsub(%r{^#{knockout_prefix}}, "") : ko_item
if item != ko_item
print "#{ko_item} - " if merge_debug
dest.delete(item)
dest.delete(ko_item)
retval = true
end
retval
end
puts if merge_debug
end
puts "#{di} merging arrays: #{source.inspect} :: #{dest.inspect}" if merge_debug
dest = dest | source
if sort_merged_arrays then dest.sort!; end
elsif overwrite_unmergeable
puts "#{di} overwriting dest: #{source.inspect} -over-> #{dest.inspect}" if merge_debug
dest = overwrite_unmergeables(source, dest, options)
end
else # src_hash is not an array or hash, so we'll have to overwrite dest
puts "#{di}Others: #{source.inspect} :: #{dest.inspect}" if merge_debug
dest = overwrite_unmergeables(source, dest, options)
end
puts "#{di}Returning #{dest.inspect}" if merge_debug
dest
end # deep_merge!
# allows deep_merge! to uniformly handle overwriting of unmergeable entities
def DeepMerge::overwrite_unmergeables(source, dest, options)
merge_debug = options[:merge_debug] || false
overwrite_unmergeable = !options[:preserve_unmergeables]
knockout_prefix = options[:knockout_prefix] || false
di = options[:debug_indent] || ''
if knockout_prefix && overwrite_unmergeable
if source.kind_of?(String) # remove knockout string from source before overwriting dest
src_tmp = source.gsub(%r{^#{knockout_prefix}},"")
elsif source.kind_of?(Array) # remove all knockout elements before overwriting dest
src_tmp = source.delete_if {|ko_item| ko_item.kind_of?(String) && ko_item.match(%r{^#{knockout_prefix}}) }
else
src_tmp = source
end
if src_tmp == source # if we didn't find a knockout_prefix then we just overwrite dest
puts "#{di}#{src_tmp.inspect} -over-> #{dest.inspect}" if merge_debug
dest = src_tmp
else # if we do find a knockout_prefix, then we just delete dest
puts "#{di}\"\" -over-> #{dest.inspect}" if merge_debug
dest = ""
end
elsif overwrite_unmergeable
dest = source
end
dest
end
def DeepMerge::clear_or_nil(obj)
if obj.respond_to?(:clear)
obj.clear
else
obj = nil
end
obj
end
end # module DeepMerge
class Hash
include DeepMerge::DeepMergeHash
end
+403
View File
@@ -0,0 +1,403 @@
require 'diy/factory.rb'
require 'yaml'
require 'set'
module DIY #:nodoc:#
VERSION = '1.1.2'
class Context
class << self
# Enable / disable automatic requiring of libraries. Default: true
attr_accessor :auto_require
end
@auto_require = true
# Accepts a Hash defining the object context (usually loaded from objects.yml), and an additional
# Hash containing objects to inject into the context.
def initialize(context_hash, extra_inputs={})
raise "Nil context hash" unless context_hash
raise "Need a hash" unless context_hash.kind_of?(Hash)
[ "[]", "keys" ].each do |mname|
unless extra_inputs.respond_to?(mname)
raise "Extra inputs must respond to hash-like [] operator and methods #keys and #each"
end
end
# store extra inputs
if extra_inputs.kind_of?(Hash)
@extra_inputs= {}
extra_inputs.each { |k,v| @extra_inputs[k.to_s] = v } # smooth out the names
else
@extra_inputs = extra_inputs
end
collect_object_and_subcontext_defs context_hash
# init the cache
@cache = {}
@cache['this_context'] = self
end
# Convenience: create a new DIY::Context by loading from a String (or open file handle.)
def self.from_yaml(io_or_string, extra_inputs={})
raise "nil input to YAML" unless io_or_string
Context.new(YAML.load(io_or_string), extra_inputs)
end
# Convenience: create a new DIY::Context by loading from the named file.
def self.from_file(fname, extra_inputs={})
raise "nil file name" unless fname
self.from_yaml(File.read(fname), extra_inputs)
end
# Return a reference to the object named. If necessary, the object will
# be instantiated on first use. If the object is non-singleton, a new
# object will be produced each time.
def get_object(obj_name)
key = obj_name.to_s
obj = @cache[key]
unless obj
if extra_inputs_has(key)
obj = @extra_inputs[key]
else
case @defs[key]
when MethodDef
obj = construct_method(key)
when FactoryDef
obj = construct_factory(key)
@cache[key] = obj
else
obj = construct_object(key)
@cache[key] = obj if @defs[key].singleton?
end
end
end
obj
end
alias :[] :get_object
# Inject a named object into the Context. This must be done before the Context has instantiated the
# object in question.
def set_object(obj_name,obj)
key = obj_name.to_s
raise "object '#{key}' already exists in context" if @cache.keys.include?(key)
@cache[key] = obj
end
alias :[]= :set_object
# Provide a listing of object names
def keys
(@defs.keys.to_set + @extra_inputs.keys.to_set).to_a
end
# Instantiate and yield the named subcontext
def within(sub_context_name)
# Find the subcontext definitaion:
context_def = @sub_context_defs[sub_context_name.to_s]
raise "No sub-context named #{sub_context_name}" unless context_def
# Instantiate a new context using self as parent:
context = Context.new( context_def, self )
yield context
end
# Returns true if the context contains an object with the given name
def contains_object(obj_name)
key = obj_name.to_s
@defs.keys.member?(key) or extra_inputs_has(key)
end
# Every top level object in the Context is instantiated. This is especially useful for
# systems that have "floating observers"... objects that are never directly accessed, who
# would thus never be instantiated by coincedence. This does not build any subcontexts
# that may exist.
def build_everything
@defs.keys.each { |k| self[k] }
end
alias :build_all :build_everything
alias :preinstantiate_singletons :build_everything
private
def collect_object_and_subcontext_defs(context_hash)
@defs = {}
@sub_context_defs = {}
get_defs_from context_hash
end
def get_defs_from(hash, namespace=nil)
hash.each do |name,info|
# we modify the info hash below so it's important to have a new
# instance to play with
info = info.dup if info
# see if we are building a factory
if info and info.has_key?('builds')
unless info.has_key?('auto_require')
info['auto_require'] = self.class.auto_require
end
if namespace
info['builds'] = namespace.build_classname(info['builds'])
end
@defs[name] = FactoryDef.new({:name => name,
:target => info['builds'],
:library => info['library'],
:auto_require => info['auto_require']})
next
end
name = name.to_s
case name
when /^\+/
# subcontext
@sub_context_defs[name.gsub(/^\+/,'')] = info
when /^using_namespace/
# namespace: use a module(s) prefix for the classname of contained object defs
# NOTE: namespacing is NOT scope... it's just a convenient way to setup class names for a group of objects.
get_defs_from info, parse_namespace(name)
when /^method\s/
key_name = name.gsub(/^method\s/, "")
@defs[key_name] = MethodDef.new(:name => key_name,
:object => info['object'],
:method => info['method'],
:attach => info['attach'])
else
# Normal object def
info ||= {}
if extra_inputs_has(name)
raise ConstructionError.new(name, "Object definition conflicts with parent context")
end
unless info.has_key?('auto_require')
info['auto_require'] = self.class.auto_require
end
if namespace
if info['class']
info['class'] = namespace.build_classname(info['class'])
else
info['class'] = namespace.build_classname(name)
end
end
@defs[name] = ObjectDef.new(:name => name, :info => info)
end
end
end
def construct_method(key)
method_definition = @defs[key]
object = get_object(method_definition.object)
method = object.method(method_definition.method)
unless method_definition.attach.nil?
instance_var_name = "@__diy_#{method_definition.object}"
method_definition.attach.each do |object_key|
get_object(object_key).instance_eval do
instance_variable_set(instance_var_name, object)
eval %|def #{key}(*args)
#{instance_var_name}.#{method_definition.method}(*args)
end|
end
end
end
return method
rescue Exception => oops
build_and_raise_construction_error(key, oops)
end
def construct_object(key)
# Find the object definition
obj_def = @defs[key]
raise "No object definition for '#{key}'" unless obj_def
# If object def mentions a library, load it
require obj_def.library if obj_def.library
# Resolve all components for the object
arg_hash = {}
obj_def.components.each do |name,value|
case value
when Lookup
arg_hash[name.to_sym] = get_object(value.name)
when StringValue
arg_hash[name.to_sym] = value.literal_value
else
raise "Cannot cope with component definition '#{value.inspect}'"
end
end
# Get a reference to the class for the object
big_c = get_class_for_name_with_module_delimeters(obj_def.class_name)
# Make and return the instance
if obj_def.use_class_directly?
return big_c
elsif arg_hash.keys.size > 0
return big_c.new(arg_hash)
else
return big_c.new
end
rescue Exception => oops
build_and_raise_construction_error(key, oops)
end
def build_and_raise_construction_error(key, oops)
cerr = ConstructionError.new(key,oops)
cerr.set_backtrace(oops.backtrace)
raise cerr
end
def get_class_for_name_with_module_delimeters(class_name)
class_name.split(/::/).inject(Object) do |mod,const_name| mod.const_get(const_name) end
end
def extra_inputs_has(key)
if key.nil? or key.strip == ''
raise ArgumentError.new("Cannot lookup objects with nil keys")
end
@extra_inputs.keys.member?(key) or @extra_inputs.keys.member?(key.to_sym)
end
def parse_namespace(str)
Namespace.new(str)
end
end
class Namespace #:nodoc:#
def initialize(str)
# 'using_namespace Animal Reptile'
parts = str.split(/\s+/)
raise "Namespace definitions must begin with 'using_namespace'" unless parts[0] == 'using_namespace'
parts.shift
if parts.length > 0 and parts[0] =~ /::/
parts = parts[0].split(/::/)
end
raise NamespaceError, "Namespace needs to indicate a module" if parts.empty?
@module_nest = parts
end
def build_classname(name)
[ @module_nest, Infl.camelize(name) ].flatten.join("::")
end
end
class Lookup #:nodoc:
attr_reader :name
def initialize(obj_name)
@name = obj_name
end
end
class MethodDef #:nodoc:
attr_accessor :name, :object, :method, :attach
def initialize(opts)
@name, @object, @method, @attach = opts[:name], opts[:object], opts[:method], opts[:attach]
end
end
class ObjectDef #:nodoc:
attr_accessor :name, :class_name, :library, :components
def initialize(opts)
name = opts[:name]
raise "Can't make an ObjectDef without a name" if name.nil?
info = opts[:info] || {}
info = info.clone
@components = {}
# Object name
@name = name
# Class name
@class_name = info.delete 'class'
@class_name ||= info.delete 'type'
@class_name ||= Infl.camelize(@name)
# Auto Require
@auto_require = info.delete 'auto_require'
# Library
@library = info.delete 'library'
@library ||= info.delete 'lib'
@library ||= Infl.underscore(@class_name) if @auto_require
# Use Class Directly
@use_class_directly = info.delete 'use_class_directly'
# Auto-compose
compose = info.delete 'compose'
if compose
case compose
when Array
auto_names = compose.map { |x| x.to_s }
when String
auto_names = compose.split(',').map { |x| x.to_s.strip }
when Symbol
auto_names = [ compose.to_s ]
else
raise "Cannot auto compose object #{@name}, bad 'compose' format: #{compose.inspect}"
end
end
auto_names ||= []
auto_names.each do |cname|
@components[cname] = Lookup.new(cname)
end
# Singleton status
if info['singleton'].nil?
@singleton = true
else
@singleton = info['singleton']
end
info.delete 'singleton'
# Remaining keys
info.each do |key,val|
@components[key.to_s] = Lookup.new(val.to_s)
end
end
def singleton?
@singleton
end
def use_class_directly?
@use_class_directly == true
end
end
class ConstructionError < RuntimeError #:nodoc:#
def initialize(object_name, cause=nil)
object_name = object_name
cause = cause
m = "Failed to construct '#{object_name}'"
if cause
m << "\n ...caused by:\n >>> #{cause}"
end
super m
end
end
class NamespaceError < RuntimeError #:nodoc:#
end
module Infl #:nodoc:#
# Ganked this from Inflector:
def self.camelize(lower_case_and_underscored_word)
lower_case_and_underscored_word.to_s.gsub(/\/(.?)/) { "::" + $1.upcase }.gsub(/(^|_)(.)/) { $2.upcase }
end
# Ganked this from Inflector:
def self.underscore(camel_cased_word)
camel_cased_word.to_s.gsub(/::/, '/').gsub(/([A-Z]+)([A-Z])/,'\1_\2').gsub(/([a-z\d])([A-Z])/,'\1_\2').downcase
end
end
end
+36
View File
@@ -0,0 +1,36 @@
module DIY #:nodoc:#
class FactoryDef #:nodoc:
attr_accessor :name, :target, :class_name, :library
def initialize(opts)
@name, @target, @library, @auto_require =
opts[:name], opts[:target], opts[:library], opts[:auto_require]
@class_name = Infl.camelize(@target)
@library ||= Infl.underscore(@class_name) if @auto_require
end
end
class Context
def construct_factory(key)
factory_def = @defs[key]
# puts "requiring #{factory_def.library}"
require factory_def.library if factory_def.library
big_c = get_class_for_name_with_module_delimeters(factory_def.class_name)
FactoryFactory.new(big_c)
end
end
class FactoryFactory
def initialize(clazz)
@class_to_create = clazz
end
def create(*args)
@class_to_create.new(*args)
end
end
end
@@ -0,0 +1,94 @@
# ==========================================
# Unity Project - A Test Framework for C
# Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams
# [Released under MIT License. Please refer to license.txt for details]
# ==========================================
if RUBY_PLATFORM =~/(win|w)32$/
begin
require 'Win32API'
rescue LoadError
puts "ERROR! \"Win32API\" library not found"
puts "\"Win32API\" is required for colour on a windows machine"
puts " try => \"gem install Win32API\" on the command line"
puts
end
# puts
# puts 'Windows Environment Detected...'
# puts 'Win32API Library Found.'
# puts
end
class ColourCommandLine
def initialize
if RUBY_PLATFORM =~/(win|w)32$/
get_std_handle = Win32API.new("kernel32", "GetStdHandle", ['L'], 'L')
@set_console_txt_attrb =
Win32API.new("kernel32","SetConsoleTextAttribute",['L','N'], 'I')
@hout = get_std_handle.call(-11)
end
end
def change_to(new_colour)
if RUBY_PLATFORM =~/(win|w)32$/
@set_console_txt_attrb.call(@hout,self.win32_colour(new_colour))
else
"\033[30;#{posix_colour(new_colour)};22m"
end
end
def win32_colour(colour)
case colour
when :black then 0
when :dark_blue then 1
when :dark_green then 2
when :dark_cyan then 3
when :dark_red then 4
when :dark_purple then 5
when :dark_yellow, :narrative then 6
when :default_white, :default, :dark_white then 7
when :silver then 8
when :blue then 9
when :green, :success then 10
when :cyan, :output then 11
when :red, :failure then 12
when :purple then 13
when :yellow then 14
when :white then 15
else
0
end
end
def posix_colour(colour)
case colour
when :black then 30
when :red, :failure then 31
when :green, :success then 32
when :yellow then 33
when :blue, :narrative then 34
when :purple, :magenta then 35
when :cyan, :output then 36
when :white, :default_white, :default then 37
else
30
end
end
def out_c(mode, colour, str)
case RUBY_PLATFORM
when /(win|w)32$/
change_to(colour)
$stdout.puts str if mode == :puts
$stdout.print str if mode == :print
change_to(:default_white)
else
$stdout.puts("#{change_to(colour)}#{str}\033[0m") if mode == :puts
$stdout.print("#{change_to(colour)}#{str}\033[0m") if mode == :print
end
end
end # ColourCommandLine
def colour_puts(role,str) ColourCommandLine.new.out_c(:puts, role, str) end
def colour_print(role,str) ColourCommandLine.new.out_c(:print, role, str) end
@@ -0,0 +1,39 @@
# ==========================================
# Unity Project - A Test Framework for C
# Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams
# [Released under MIT License. Please refer to license.txt for details]
# ==========================================
require "#{File.expand_path(File.dirname(__FILE__))}/colour_prompt"
$colour_output = true
def report(message)
if not $colour_output
$stdout.puts(message)
else
message = message.join('\n') if (message.class == Array)
message.each_line do |line|
line.chomp!
colour = case(line)
when /(?:total\s+)?tests:?\s+(\d+)\s+(?:total\s+)?failures:?\s+\d+\s+Ignored:?/i
($1.to_i == 0) ? :green : :red
when /PASS/
:green
when /^OK$/
:green
when /(?:FAIL|ERROR)/
:red
when /IGNORE/
:yellow
when /^(?:Creating|Compiling|Linking)/
:white
else
:silver
end
colour_puts(colour, line)
end
end
$stdout.flush
$stderr.flush
end
@@ -0,0 +1,36 @@
#this is a sample configuration file for generate_module
#you would use it by calling generate_module with the -ygenerate_config.yml option
#files like this are useful for customizing generate_module to your environment
:generate_module:
:defaults:
#these defaults are used in place of any missing options at the command line
:path_src: ../src/
:path_inc: ../src/
:path_tst: ../test/
:update_svn: true
:includes:
#use [] for no additional includes, otherwise list the includes on separate lines
:src:
- Defs.h
- Board.h
:inc: []
:tst:
- Defs.h
- Board.h
- Exception.h
:boilerplates:
#these are inserted at the top of generated files.
#just comment out or remove if not desired.
#use %1$s where you would like the file name to appear (path/extension not included)
:src: |
//-------------------------------------------
// %1$s.c
//-------------------------------------------
:inc: |
//-------------------------------------------
// %1$s.h
//-------------------------------------------
:tst: |
//-------------------------------------------
// Test%1$s.c : Units tests for %1$s.c
//-------------------------------------------
@@ -0,0 +1,202 @@
# ==========================================
# Unity Project - A Test Framework for C
# Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams
# [Released under MIT License. Please refer to license.txt for details]
# ==========================================
# This script creates all the files with start code necessary for a new module.
# A simple module only requires a source file, header file, and test file.
# Triad modules require a source, header, and test file for each triad type (like model, conductor, and hardware).
require 'rubygems'
require 'fileutils'
HERE = File.expand_path(File.dirname(__FILE__)) + '/'
#help text when requested
HELP_TEXT = [ "\nGENERATE MODULE\n-------- ------",
"\nUsage: ruby generate_module [options] module_name",
" -i\"include\" sets the path to output headers to 'include' (DEFAULT ../src)",
" -s\"../src\" sets the path to output source to '../src' (DEFAULT ../src)",
" -t\"C:/test\" sets the path to output source to 'C:/test' (DEFAULT ../test)",
" -p\"MCH\" sets the output pattern to MCH.",
" dh - driver hardware.",
" dih - driver interrupt hardware.",
" mch - model conductor hardware.",
" mvp - model view presenter.",
" src - just a single source module. (DEFAULT)",
" -d destroy module instead of creating it.",
" -u update subversion too (requires subversion command line)",
" -y\"my.yml\" selects a different yaml config file for module generation",
"" ].join("\n")
#Built in patterns
PATTERNS = { 'src' => {'' => { :inc => [] } },
'dh' => {'Driver' => { :inc => ['%1$sHardware.h'] },
'Hardware' => { :inc => [] }
},
'dih' => {'Driver' => { :inc => ['%1$sHardware.h', '%1$sInterrupt.h'] },
'Interrupt'=> { :inc => ['%1$sHardware.h'] },
'Hardware' => { :inc => [] }
},
'mch' => {'Model' => { :inc => [] },
'Conductor'=> { :inc => ['%1$sModel.h', '%1$sHardware.h'] },
'Hardware' => { :inc => [] }
},
'mvp' => {'Model' => { :inc => [] },
'Presenter'=> { :inc => ['%1$sModel.h', '%1$sView.h'] },
'View' => { :inc => [] }
}
}
#TEMPLATE_TST
TEMPLATE_TST = %q[#include "unity.h"
%2$s#include "%1$s.h"
void setUp(void)
{
}
void tearDown(void)
{
}
void test_%1$s_NeedToImplement(void)
{
TEST_IGNORE();
}
]
#TEMPLATE_SRC
TEMPLATE_SRC = %q[%2$s#include "%1$s.h"
]
#TEMPLATE_INC
TEMPLATE_INC = %q[#ifndef _%3$s_H
#define _%3$s_H%2$s
#endif // _%3$s_H
]
# Parse the command line parameters.
ARGV.each do |arg|
case(arg)
when /^-d/ then @destroy = true
when /^-u/ then @update_svn = true
when /^-p(\w+)/ then @pattern = $1
when /^-s(.+)/ then @path_src = $1
when /^-i(.+)/ then @path_inc = $1
when /^-t(.+)/ then @path_tst = $1
when /^-y(.+)/ then @yaml_config = $1
when /^(\w+)/
raise "ERROR: You can't have more than one Module name specified!" unless @module_name.nil?
@module_name = arg
when /^-(h|-help)/
puts HELP_TEXT
exit
else
raise "ERROR: Unknown option specified '#{arg}'"
end
end
raise "ERROR: You must have a Module name specified! (use option -h for help)" if @module_name.nil?
#load yaml file if one was requested
if @yaml_config
require 'yaml'
cfg = YAML.load_file(HERE + @yaml_config)[:generate_module]
@path_src = cfg[:defaults][:path_src] if @path_src.nil?
@path_inc = cfg[:defaults][:path_inc] if @path_inc.nil?
@path_tst = cfg[:defaults][:path_tst] if @path_tst.nil?
@update_svn = cfg[:defaults][:update_svn] if @update_svn.nil?
@extra_inc = cfg[:includes]
@boilerplates = cfg[:boilerplates]
else
@boilerplates = {}
end
# Create default file paths if none were provided
@path_src = HERE + "../src/" if @path_src.nil?
@path_inc = @path_src if @path_inc.nil?
@path_tst = HERE + "../test/" if @path_tst.nil?
@path_src += '/' unless (@path_src[-1] == 47)
@path_inc += '/' unless (@path_inc[-1] == 47)
@path_tst += '/' unless (@path_tst[-1] == 47)
@pattern = 'src' if @pattern.nil?
@includes = { :src => [], :inc => [], :tst => [] }
@includes.merge!(@extra_inc) unless @extra_inc.nil?
#create triad definition
TRIAD = [ { :ext => '.c', :path => @path_src, :template => TEMPLATE_SRC, :inc => :src, :boilerplate => @boilerplates[:src] },
{ :ext => '.h', :path => @path_inc, :template => TEMPLATE_INC, :inc => :inc, :boilerplate => @boilerplates[:inc] },
{ :ext => '.c', :path => @path_tst+'Test', :template => TEMPLATE_TST, :inc => :tst, :boilerplate => @boilerplates[:tst] },
]
#prepare the pattern for use
@patterns = PATTERNS[@pattern.downcase]
raise "ERROR: The design pattern specified isn't one that I recognize!" if @patterns.nil?
# Assemble the path/names of the files we need to work with.
files = []
TRIAD.each do |triad|
@patterns.each_pair do |pattern_file, pattern_traits|
files << {
:path => "#{triad[:path]}#{@module_name}#{pattern_file}#{triad[:ext]}",
:name => "#{@module_name}#{pattern_file}",
:template => triad[:template],
:boilerplate => triad[:boilerplate],
:includes => case(triad[:inc])
when :src then @includes[:src] | pattern_traits[:inc].map{|f| f % [@module_name]}
when :inc then @includes[:inc]
when :tst then @includes[:tst] | pattern_traits[:inc].map{|f| "Mock#{f}"% [@module_name]}
end
}
end
end
# destroy files if that was what was requested
if @destroy
files.each do |filespec|
file = filespec[:path]
if File.exist?(file)
if @update_svn
`svn delete \"#{file}\" --force`
puts "File #{file} deleted and removed from source control"
else
FileUtils.remove(file)
puts "File #{file} deleted"
end
else
puts "File #{file} does not exist so cannot be removed."
end
end
puts "Destroy Complete"
exit
end
#Abort if any module already exists
files.each do |file|
raise "ERROR: File #{file[:name]} already exists. Exiting." if File.exist?(file[:path])
end
# Create Source Modules
files.each_with_index do |file, i|
File.open(file[:path], 'w') do |f|
f.write(file[:boilerplate] % [file[:name]]) unless file[:boilerplate].nil?
f.write(file[:template] % [ file[:name],
file[:includes].map{|f| "#include \"#{f}\"\n"}.join,
file[:name].upcase ]
)
end
if (@update_svn)
`svn add \"#{file[:path]}\"`
if $?.exitstatus == 0
puts "File #{file[:path]} created and added to source control"
else
puts "File #{file[:path]} created but FAILED adding to source control!"
end
else
puts "File #{file[:path]} created"
end
end
puts 'Generate Complete'
@@ -0,0 +1,313 @@
# ==========================================
# Unity Project - A Test Framework for C
# Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams
# [Released under MIT License. Please refer to license.txt for details]
# ==========================================
File.expand_path(File.join(File.dirname(__FILE__),'colour_prompt'))
class UnityTestRunnerGenerator
def initialize(options = nil)
@options = { :includes => [], :plugins => [], :framework => :unity }
case(options)
when NilClass then @options
when String then @options.merge!(UnityTestRunnerGenerator.grab_config(options))
when Hash then @options.merge!(options)
else raise "If you specify arguments, it should be a filename or a hash of options"
end
end
def self.grab_config(config_file)
options = { :includes => [], :plugins => [], :framework => :unity }
unless (config_file.nil? or config_file.empty?)
require 'yaml'
yaml_guts = YAML.load_file(config_file)
options.merge!(yaml_guts[:unity] ? yaml_guts[:unity] : yaml_guts[:cmock])
raise "No :unity or :cmock section found in #{config_file}" unless options
end
return(options)
end
def run(input_file, output_file, options=nil)
tests = []
testfile_includes = []
used_mocks = []
@options.merge!(options) unless options.nil?
module_name = File.basename(input_file)
#pull required data from source file
File.open(input_file, 'r') do |input|
tests = find_tests(input)
testfile_includes = find_includes(input)
used_mocks = find_mocks(testfile_includes)
end
#build runner file
generate(input_file, output_file, tests, used_mocks)
#determine which files were used to return them
all_files_used = [input_file, output_file]
all_files_used += testfile_includes.map {|filename| filename + '.c'} unless testfile_includes.empty?
all_files_used += @options[:includes] unless @options[:includes].empty?
return all_files_used.uniq
end
def generate(input_file, output_file, tests, used_mocks)
File.open(output_file, 'w') do |output|
create_header(output, used_mocks)
create_externs(output, tests, used_mocks)
create_mock_management(output, used_mocks)
create_suite_setup_and_teardown(output)
create_reset(output, used_mocks)
create_main(output, input_file, tests)
end
end
def find_tests(input_file)
tests_raw = []
tests_args = []
tests_and_line_numbers = []
input_file.rewind
source_raw = input_file.read
source_scrubbed = source_raw.gsub(/\/\/.*$/, '') # remove line comments
source_scrubbed = source_scrubbed.gsub(/\/\*.*?\*\//m, '') # remove block comments
lines = source_scrubbed.split(/(^\s*\#.*$) # Treat preprocessor directives as a logical line
| (;|\{|\}) /x) # Match ;, {, and } as end of lines
lines.each_with_index do |line, index|
#find tests
if line =~ /^((?:\s*TEST_CASE\s*\(.*?\)\s*)*)\s*void\s+(test.*?)\s*\(\s*(.*)\s*\)/
arguments = $1
name = $2
call = $3
args = nil
if (@options[:use_param_tests] and !arguments.empty?)
args = []
arguments.scan(/\s*TEST_CASE\s*\((.*)\)\s*$/) {|a| args << a[0]}
end
tests_and_line_numbers << { :test => name, :args => args, :call => call, :line_number => 0 }
tests_args = []
end
end
#determine line numbers and create tests to run
source_lines = source_raw.split("\n")
source_index = 0;
tests_and_line_numbers.size.times do |i|
source_lines[source_index..-1].each_with_index do |line, index|
if (line =~ /#{tests_and_line_numbers[i][:test]}/)
source_index += index
tests_and_line_numbers[i][:line_number] = source_index + 1
break
end
end
end
return tests_and_line_numbers
end
def find_includes(input_file)
input_file.rewind
#read in file
source = input_file.read
#remove comments (block and line, in three steps to ensure correct precedence)
source.gsub!(/\/\/(?:.+\/\*|\*(?:$|[^\/])).*$/, '') # remove line comments that comment out the start of blocks
source.gsub!(/\/\*.*?\*\//m, '') # remove block comments
source.gsub!(/\/\/.*$/, '') # remove line comments (all that remain)
#parse out includes
return source.scan(/^\s*#include\s+\"\s*(.+)\.[hH]\s*\"/).flatten
end
def find_mocks(includes)
mock_headers = []
includes.each do |include_file|
mock_headers << File.basename(include_file) if (include_file =~ /^mock/i)
end
return mock_headers
end
def create_header(output, mocks)
output.puts('/* AUTOGENERATED FILE. DO NOT EDIT. */')
create_runtest(output, mocks)
output.puts("\n//=======Automagically Detected Files To Include=====")
output.puts("#include \"#{@options[:framework].to_s}.h\"")
output.puts('#include "cmock.h"') unless (mocks.empty?)
@options[:includes].flatten.uniq.compact.each do |inc|
output.puts("#include #{inc.include?('<') ? inc : "\"#{inc.gsub('.h','')}.h\""}")
end
output.puts('#include <setjmp.h>')
output.puts('#include <stdio.h>')
output.puts('#include "CException.h"') if @options[:plugins].include?(:cexception)
mocks.each do |mock|
output.puts("#include \"#{mock.gsub('.h','')}.h\"")
end
if @options[:enforce_strict_ordering]
output.puts('')
output.puts('int GlobalExpectCount;')
output.puts('int GlobalVerifyOrder;')
output.puts('char* GlobalOrderError;')
end
end
def create_externs(output, tests, mocks)
output.puts("\n//=======External Functions This Runner Calls=====")
output.puts("extern void setUp(void);")
output.puts("extern void tearDown(void);")
tests.each do |test|
output.puts("extern void #{test[:test]}(#{test[:call] || 'void'});")
end
output.puts('')
end
def create_mock_management(output, mocks)
unless (mocks.empty?)
output.puts("\n//=======Mock Management=====")
output.puts("static void CMock_Init(void)")
output.puts("{")
if @options[:enforce_strict_ordering]
output.puts(" GlobalExpectCount = 0;")
output.puts(" GlobalVerifyOrder = 0;")
output.puts(" GlobalOrderError = NULL;")
end
mocks.each do |mock|
output.puts(" #{mock}_Init();")
end
output.puts("}\n")
output.puts("static void CMock_Verify(void)")
output.puts("{")
mocks.each do |mock|
output.puts(" #{mock}_Verify();")
end
output.puts("}\n")
output.puts("static void CMock_Destroy(void)")
output.puts("{")
mocks.each do |mock|
output.puts(" #{mock}_Destroy();")
end
output.puts("}\n")
end
end
def create_suite_setup_and_teardown(output)
unless (@options[:suite_setup].nil?)
output.puts("\n//=======Suite Setup=====")
output.puts("static int suite_setup(void)")
output.puts("{")
output.puts(@options[:suite_setup])
output.puts("}")
end
unless (@options[:suite_teardown].nil?)
output.puts("\n//=======Suite Teardown=====")
output.puts("static int suite_teardown(int num_failures)")
output.puts("{")
output.puts(@options[:suite_teardown])
output.puts("}")
end
end
def create_runtest(output, used_mocks)
cexception = @options[:plugins].include? :cexception
va_args1 = @options[:use_param_tests] ? ', ...' : ''
va_args2 = @options[:use_param_tests] ? '__VA_ARGS__' : ''
output.puts("\n//=======Test Runner Used To Run Each Test Below=====")
output.puts("#define RUN_TEST_NO_ARGS") if @options[:use_param_tests]
output.puts("#define RUN_TEST(TestFunc, TestLineNum#{va_args1}) \\")
output.puts("{ \\")
output.puts(" Unity.CurrentTestName = #TestFunc#{va_args2.empty? ? '' : " \"(\" ##{va_args2} \")\""}; \\")
output.puts(" Unity.CurrentTestLineNumber = TestLineNum; \\")
output.puts(" Unity.NumberOfTests++; \\")
output.puts(" if (TEST_PROTECT()) \\")
output.puts(" { \\")
output.puts(" CEXCEPTION_T e; \\") if cexception
output.puts(" Try { \\") if cexception
output.puts(" CMock_Init(); \\") unless (used_mocks.empty?)
output.puts(" setUp(); \\")
output.puts(" TestFunc(#{va_args2}); \\")
output.puts(" CMock_Verify(); \\") unless (used_mocks.empty?)
output.puts(" } Catch(e) { TEST_ASSERT_EQUAL_HEX32_MESSAGE(CEXCEPTION_NONE, e, \"Unhandled Exception!\"); } \\") if cexception
output.puts(" } \\")
output.puts(" CMock_Destroy(); \\") unless (used_mocks.empty?)
output.puts(" if (TEST_PROTECT() && !TEST_IS_IGNORED) \\")
output.puts(" { \\")
output.puts(" tearDown(); \\")
output.puts(" } \\")
output.puts(" UnityConcludeTest(); \\")
output.puts("}\n")
end
def create_reset(output, used_mocks)
output.puts("\n//=======Test Reset Option=====")
output.puts("void resetTest()")
output.puts("{")
output.puts(" CMock_Verify();") unless (used_mocks.empty?)
output.puts(" CMock_Destroy();") unless (used_mocks.empty?)
output.puts(" tearDown();")
output.puts(" CMock_Init();") unless (used_mocks.empty?)
output.puts(" setUp();")
output.puts("}")
end
def create_main(output, filename, tests)
output.puts("\n\n//=======MAIN=====")
output.puts("int main(void)")
output.puts("{")
output.puts(" suite_setup();") unless @options[:suite_setup].nil?
output.puts(" Unity.TestFile = \"#{filename}\";")
output.puts(" UnityBegin();")
if (@options[:use_param_tests])
tests.each do |test|
if ((test[:args].nil?) or (test[:args].empty?))
output.puts(" RUN_TEST(#{test[:test]}, #{test[:line_number]}, RUN_TEST_NO_ARGS);")
else
test[:args].each {|args| output.puts(" RUN_TEST(#{test[:test]}, #{test[:line_number]}, #{args});")}
end
end
else
tests.each { |test| output.puts(" RUN_TEST(#{test[:test]}, #{test[:line_number]});") }
end
output.puts()
output.puts(" return #{@options[:suite_teardown].nil? ? "" : "suite_teardown"}(UnityEnd());")
output.puts("}")
end
end
if ($0 == __FILE__)
options = { :includes => [] }
yaml_file = nil
#parse out all the options first
ARGV.reject! do |arg|
case(arg)
when '-cexception'
options[:plugins] = [:cexception]; true
when /\.*\.yml/
options = UnityTestRunnerGenerator.grab_config(arg); true
else false
end
end
#make sure there is at least one parameter left (the input file)
if !ARGV[0]
puts ["usage: ruby #{__FILE__} (yaml) (options) input_test_file output_test_runner (includes)",
" blah.yml - will use config options in the yml file (see docs)",
" -cexception - include cexception support"].join("\n")
exit 1
end
#create the default test runner name if not specified
ARGV[1] = ARGV[0].gsub(".c","_Runner.c") if (!ARGV[1])
#everything else is an include file
options[:includes] ||= (ARGV.slice(2..-1).flatten.compact) if (ARGV.size > 2)
UnityTestRunnerGenerator.new(options).run(ARGV[0], ARGV[1])
end
@@ -0,0 +1,23 @@
# ==========================================
# Unity Project - A Test Framework for C
# Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams
# [Released under MIT License. Please refer to license.txt for details]
# ==========================================
require'yaml'
module RakefileHelpers
class TestFileFilter
def initialize(all_files = false)
@all_files = all_files
if not @all_files == true
if File.exist?('test_file_filter.yml')
filters = YAML.load_file( 'test_file_filter.yml' )
@all_files, @only_files, @exclude_files =
filters[:all_files], filters[:only_files], filters[:exclude_files]
end
end
end
attr_accessor :all_files, :only_files, :exclude_files
end
end
@@ -0,0 +1,139 @@
# ==========================================
# Unity Project - A Test Framework for C
# Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams
# [Released under MIT License. Please refer to license.txt for details]
# ==========================================
#!/usr/bin/ruby
#
# unity_test_summary.rb
#
require 'fileutils'
require 'set'
class UnityTestSummary
include FileUtils::Verbose
attr_reader :report, :total_tests, :failures, :ignored
def initialize
@report = ''
@total_tests = 0
@failures = 0
@ignored = 0
end
def run
# Clean up result file names
results = @targets.map {|target| target.gsub(/\\/,'/')}
# Dig through each result file, looking for details on pass/fail:
failure_output = []
ignore_output = []
results.each do |result_file|
lines = File.readlines(result_file).map { |line| line.chomp }
if lines.length == 0
raise "Empty test result file: #{result_file}"
else
output = get_details(result_file, lines)
failure_output << output[:failures] unless output[:failures].empty?
ignore_output << output[:ignores] unless output[:ignores].empty?
tests,failures,ignored = parse_test_summary(lines)
@total_tests += tests
@failures += failures
@ignored += ignored
end
end
if @ignored > 0
@report += "\n"
@report += "--------------------------\n"
@report += "UNITY IGNORED TEST SUMMARY\n"
@report += "--------------------------\n"
@report += ignore_output.flatten.join("\n")
end
if @failures > 0
@report += "\n"
@report += "--------------------------\n"
@report += "UNITY FAILED TEST SUMMARY\n"
@report += "--------------------------\n"
@report += failure_output.flatten.join("\n")
end
@report += "\n"
@report += "--------------------------\n"
@report += "OVERALL UNITY TEST SUMMARY\n"
@report += "--------------------------\n"
@report += "#{@total_tests} TOTAL TESTS #{@failures} TOTAL FAILURES #{@ignored} IGNORED\n"
@report += "\n"
end
def set_targets(target_array)
@targets = target_array
end
def set_root_path(path)
@root = path
end
def usage(err_msg=nil)
puts "\nERROR: "
puts err_msg if err_msg
puts "\nUsage: unity_test_summary.rb result_file_directory/ root_path/"
puts " result_file_directory - The location of your results files."
puts " Defaults to current directory if not specified."
puts " Should end in / if specified."
puts " root_path - Helpful for producing more verbose output if using relative paths."
exit 1
end
protected
def get_details(result_file, lines)
results = { :failures => [], :ignores => [], :successes => [] }
lines.each do |line|
src_file,src_line,test_name,status,msg = line.split(/:/)
line_out = ((@root and (@root != 0)) ? "#{@root}#{line}" : line ).gsub(/\//, "\\")
case(status)
when 'IGNORE' then results[:ignores] << line_out
when 'FAIL' then results[:failures] << line_out
when 'PASS' then results[:successes] << line_out
end
end
return results
end
def parse_test_summary(summary)
if summary.find { |v| v =~ /(\d+) Tests (\d+) Failures (\d+) Ignored/ }
[$1.to_i,$2.to_i,$3.to_i]
else
raise "Couldn't parse test results: #{summary}"
end
end
def here; File.expand_path(File.dirname(__FILE__)); end
end
if $0 == __FILE__
uts = UnityTestSummary.new
begin
#look in the specified or current directory for result files
ARGV[0] ||= './'
targets = "#{ARGV[0].gsub(/\\/, '/')}*.test*"
results = Dir[targets]
raise "No *.testpass or *.testfail files found in '#{targets}'" if results.empty?
uts.set_targets(results)
#set the root path
ARGV[1] ||= File.expand_path(File.dirname(__FILE__)) + '/'
uts.set_root_path(ARGV[1])
#run the summarizer
puts uts.run
rescue Exception => e
uts.usage e.message
end
end
@@ -0,0 +1,9 @@
Copyright (c) 2010 James Grenning and Contributed to Unity Project
Unity Project - A Test Framework for C
Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams
[Released under MIT License. Please refer to license.txt for details]
This Framework is an optional add-on to Unity. By including unity_framework.h in place of unity.h,
you may now work with Unity in a manner similar to CppUTest. This framework adds the concepts of
test groups and gives finer control of your tests over the command line.
@@ -0,0 +1,377 @@
//- Copyright (c) 2010 James Grenning and Contributed to Unity Project
/* ==========================================
Unity Project - A Test Framework for C
Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams
[Released under MIT License. Please refer to license.txt for details]
========================================== */
#include "unity_fixture.h"
#include "unity_internals.h"
#include <string.h>
UNITY_FIXTURE_T UnityFixture;
//If you decide to use the function pointer approach.
int (*outputChar)(int) = putchar;
int verbose = 0;
void setUp(void) { /*does nothing*/ }
void tearDown(void) { /*does nothing*/ }
void announceTestRun(unsigned int runNumber)
{
UnityPrint("Unity test run ");
UnityPrintNumber(runNumber+1);
UnityPrint(" of ");
UnityPrintNumber(UnityFixture.RepeatCount);
UNITY_OUTPUT_CHAR('\n');
}
int UnityMain(int argc, char* argv[], void (*runAllTests)())
{
int result = UnityGetCommandLineOptions(argc, argv);
unsigned int r;
if (result != 0)
return result;
for (r = 0; r < UnityFixture.RepeatCount; r++)
{
announceTestRun(r);
UnityBegin();
runAllTests();
UNITY_OUTPUT_CHAR('\n');
UnityEnd();
}
return UnityFailureCount();
}
static int selected(const char * filter, const char * name)
{
if (filter == 0)
return 1;
return strstr(name, filter) ? 1 : 0;
}
static int testSelected(const char* test)
{
return selected(UnityFixture.NameFilter, test);
}
static int groupSelected(const char* group)
{
return selected(UnityFixture.GroupFilter, group);
}
static void runTestCase()
{
}
void UnityTestRunner(unityfunction* setup,
unityfunction* testBody,
unityfunction* teardown,
const char * printableName,
const char * group,
const char * name,
const char * file, int line)
{
if (testSelected(name) && groupSelected(group))
{
Unity.CurrentTestFailed = 0;
Unity.TestFile = file;
Unity.CurrentTestName = printableName;
Unity.CurrentTestLineNumber = line;
if (!UnityFixture.Verbose)
UNITY_OUTPUT_CHAR('.');
else
UnityPrint(printableName);
Unity.NumberOfTests++;
UnityMalloc_StartTest();
UnityPointer_Init();
runTestCase();
if (TEST_PROTECT())
{
setup();
testBody();
}
if (TEST_PROTECT())
{
teardown();
}
if (TEST_PROTECT())
{
UnityPointer_UndoAllSets();
if (!Unity.CurrentTestFailed)
UnityMalloc_EndTest();
}
UnityConcludeFixtureTest();
}
}
void UnityIgnoreTest()
{
Unity.NumberOfTests++;
Unity.CurrentTestIgnored = 1;
UNITY_OUTPUT_CHAR('!');
}
//-------------------------------------------------
//Malloc and free stuff
//
#define MALLOC_DONT_FAIL -1
static int malloc_count;
static int malloc_fail_countdown = MALLOC_DONT_FAIL;
void UnityMalloc_StartTest()
{
malloc_count = 0;
malloc_fail_countdown = MALLOC_DONT_FAIL;
}
void UnityMalloc_EndTest()
{
malloc_fail_countdown = MALLOC_DONT_FAIL;
if (malloc_count != 0)
{
TEST_FAIL_MESSAGE("This test leaks!");
}
}
void UnityMalloc_MakeMallocFailAfterCount(int countdown)
{
malloc_fail_countdown = countdown;
}
#ifdef malloc
#undef malloc
#endif
#ifdef free
#undef free
#endif
#include <stdlib.h>
#include <string.h>
typedef struct GuardBytes
{
int size;
char guard[sizeof(int)];
} Guard;
static const char * end = "END";
void * unity_malloc(size_t size)
{
char* mem;
Guard* guard;
if (malloc_fail_countdown != MALLOC_DONT_FAIL)
{
if (malloc_fail_countdown == 0)
return 0;
malloc_fail_countdown--;
}
malloc_count++;
guard = (Guard*)malloc(size + sizeof(Guard) + 4);
guard->size = size;
mem = (char*)&(guard[1]);
memcpy(&mem[size], end, strlen(end) + 1);
return (void*)mem;
}
static int isOverrun(void * mem)
{
Guard* guard = (Guard*)mem;
char* memAsChar = (char*)mem;
guard--;
return strcmp(&memAsChar[guard->size], end) != 0;
}
static void release_memory(void * mem)
{
Guard* guard = (Guard*)mem;
guard--;
malloc_count--;
free(guard);
}
void unity_free(void * mem)
{
int overrun = isOverrun(mem);//strcmp(&memAsChar[guard->size], end) != 0;
release_memory(mem);
if (overrun)
{
TEST_FAIL_MESSAGE("Buffer overrun detected during free()");
}
}
void* unity_calloc(size_t num, size_t size)
{
void* mem = unity_malloc(num * size);
memset(mem, 0, num*size);
return mem;
}
void* unity_realloc(void * oldMem, size_t size)
{
Guard* guard = (Guard*)oldMem;
// char* memAsChar = (char*)oldMem;
void* newMem;
if (oldMem == 0)
return unity_malloc(size);
guard--;
if (isOverrun(oldMem))
{
release_memory(oldMem);
TEST_FAIL_MESSAGE("Buffer overrun detected during realloc()");
}
if (size == 0)
{
release_memory(oldMem);
return 0;
}
if (guard->size >= size)
return oldMem;
newMem = unity_malloc(size);
memcpy(newMem, oldMem, guard->size);
unity_free(oldMem);
return newMem;
}
//--------------------------------------------------------
//Automatic pointer restoration functions
typedef struct _PointerPair
{
struct _PointerPair * next;
void ** pointer;
void * old_value;
} PointerPair;
enum {MAX_POINTERS=50};
static PointerPair pointer_store[MAX_POINTERS];
static int pointer_index = 0;
void UnityPointer_Init()
{
pointer_index = 0;
}
void UnityPointer_Set(void ** pointer, void * newValue)
{
if (pointer_index >= MAX_POINTERS)
TEST_FAIL_MESSAGE("Too many pointers set");
pointer_store[pointer_index].pointer = pointer;
pointer_store[pointer_index].old_value = *pointer;
*pointer = newValue;
pointer_index++;
}
void UnityPointer_UndoAllSets()
{
while (pointer_index > 0)
{
pointer_index--;
*(pointer_store[pointer_index].pointer) =
pointer_store[pointer_index].old_value;
}
}
int UnityFailureCount()
{
return Unity.TestFailures;
}
int UnityGetCommandLineOptions(int argc, char* argv[])
{
int i;
UnityFixture.Verbose = 0;
UnityFixture.GroupFilter = 0;
UnityFixture.NameFilter = 0;
UnityFixture.RepeatCount = 1;
if (argc == 1)
return 0;
for (i = 1; i < argc; )
{
if (strcmp(argv[i], "-v") == 0)
{
UnityFixture.Verbose = 1;
i++;
}
else if (strcmp(argv[i], "-g") == 0)
{
i++;
if (i >= argc)
return 1;
UnityFixture.GroupFilter = argv[i];
i++;
}
else if (strcmp(argv[i], "-n") == 0)
{
i++;
if (i >= argc)
return 1;
UnityFixture.NameFilter = argv[i];
i++;
}
else if (strcmp(argv[i], "-r") == 0)
{
UnityFixture.RepeatCount = 2;
i++;
if (i < argc)
{
if (*(argv[i]) >= '0' && *(argv[i]) <= '9')
{
UnityFixture.RepeatCount = atoi(argv[i]);
i++;
}
}
}
}
return 0;
}
void UnityConcludeFixtureTest()
{
if (Unity.CurrentTestIgnored)
{
Unity.TestIgnores++;
}
else if (!Unity.CurrentTestFailed)
{
if (UnityFixture.Verbose)
{
UnityPrint(" PASS");
UNITY_OUTPUT_CHAR('\n');
}
}
else if (Unity.CurrentTestFailed)
{
Unity.TestFailures++;
}
Unity.CurrentTestFailed = 0;
Unity.CurrentTestIgnored = 0;
}
@@ -0,0 +1,81 @@
//- Copyright (c) 2010 James Grenning and Contributed to Unity Project
/* ==========================================
Unity Project - A Test Framework for C
Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams
[Released under MIT License. Please refer to license.txt for details]
========================================== */
#ifndef UNITY_FIXTURE_H_
#define UNITY_FIXTURE_H_
#include "unity.h"
#include "unity_internals.h"
#include "unity_fixture_malloc_overrides.h"
#include "unity_fixture_internals.h"
int UnityMain(int argc, char* argv[], void (*runAllTests)());
#define TEST_GROUP(group)\
int TEST_GROUP_##group = 0
#define TEST_SETUP(group) void TEST_##group##_SETUP()
#define TEST_TEAR_DOWN(group) void TEST_##group##_TEAR_DOWN()
#define TEST(group, name) \
void TEST_##group##_##name##_();\
void TEST_##group##_##name##_run()\
{\
UnityTestRunner(TEST_##group##_SETUP,\
TEST_##group##_##name##_,\
TEST_##group##_TEAR_DOWN,\
"TEST(" #group ", " #name ")",\
#group, #name,\
__FILE__, __LINE__);\
}\
void TEST_##group##_##name##_()
#define IGNORE_TEST(group, name) \
void TEST_##group##_##name##_();\
void TEST_##group##_##name##_run()\
{\
UnityIgnoreTest();\
}\
void TEST_##group##_##name##_()
#define DECLARE_TEST_CASE(group, name) \
void TEST_##group##_##name##_run()
#define RUN_TEST_CASE(group, name) \
DECLARE_TEST_CASE(group, name);\
TEST_##group##_##name##_run();
//This goes at the bottom of each test file or in a separate c file
#define TEST_GROUP_RUNNER(group)\
void TEST_##group##_GROUP_RUNNER_runAll();\
void TEST_##group##_GROUP_RUNNER()\
{\
TEST_##group##_GROUP_RUNNER_runAll();\
}\
void TEST_##group##_GROUP_RUNNER_runAll()
//Call this from main
#define RUN_TEST_GROUP(group)\
void TEST_##group##_GROUP_RUNNER();\
TEST_##group##_GROUP_RUNNER();
//CppUTest Compatibility Macros
#define UT_PTR_SET(ptr, newPointerValue) UnityPointer_Set((void**)&ptr, (void*)newPointerValue)
#define TEST_ASSERT_POINTERS_EQUAL(expected, actual) TEST_ASSERT_EQUAL_PTR(expected, actual)
#define TEST_ASSERT_BYTES_EQUAL(expected, actual) TEST_ASSERT_EQUAL_HEX8(0xff & (expected), 0xff & (actual))
#define FAIL(message) TEST_FAIL((message))
#define CHECK(condition) TEST_ASSERT_TRUE((condition))
#define LONGS_EQUAL(expected, actual) TEST_ASSERT_EQUAL_INT((expected), (actual))
#define STRCMP_EQUAL(expected, actual) TEST_ASSERT_EQUAL_STRING((expected), (actual))
#define DOUBLES_EQUAL(expected, actual, delta) TEST_ASSERT_FLOAT_WITHIN(((expected), (actual), (delta))
void UnityMalloc_MakeMallocFailAfterCount(int count);
#endif /* UNITY_FIXTURE_H_ */
@@ -0,0 +1,44 @@
//- Copyright (c) 2010 James Grenning and Contributed to Unity Project
/* ==========================================
Unity Project - A Test Framework for C
Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams
[Released under MIT License. Please refer to license.txt for details]
========================================== */
#ifndef UNITY_FIXTURE_INTERNALS_H_
#define UNITY_FIXTURE_INTERNALS_H_
typedef struct _UNITY_FIXTURE_T
{
int Verbose;
unsigned int RepeatCount;
const char* NameFilter;
const char* GroupFilter;
} UNITY_FIXTURE_T;
typedef void unityfunction();
void UnityTestRunner(unityfunction * setup,
unityfunction * body,
unityfunction * teardown,
const char * printableName,
const char * group,
const char * name,
const char * file, int line);
void UnityIgnoreTest();
void UnityMalloc_StartTest();
void UnityMalloc_EndTest();
int UnityFailureCount();
int UnityGetCommandLineOptions(int argc, char* argv[]);
void UnityConcludeFixtureTest();
void UnityPointer_Set(void ** ptr, void * newValue);
void UnityPointer_UndoAllSets();
void UnityPointer_Init();
void UnityAssertEqualPointer(const void * expected,
const void * actual,
const char* msg,
const UNITY_LINE_TYPE lineNumber);
#endif /* UNITY_FIXTURE_INTERNALS_H_ */
@@ -0,0 +1,16 @@
//- Copyright (c) 2010 James Grenning and Contributed to Unity Project
/* ==========================================
Unity Project - A Test Framework for C
Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams
[Released under MIT License. Please refer to license.txt for details]
========================================== */
#ifndef UNITY_FIXTURE_MALLOC_OVERRIDES_H_
#define UNITY_FIXTURE_MALLOC_OVERRIDES_H_
#define malloc unity_malloc
#define calloc unity_calloc
#define realloc unity_realloc
#define free unity_free
#endif /* UNITY_FIXTURE_MALLOC_OVERRIDES_H_ */
+2
View File
@@ -0,0 +1,2 @@
118
@@ -0,0 +1,2 @@
2.1.0
+979
View File
@@ -0,0 +1,979 @@
/* ==========================================
Unity Project - A Test Framework for C
Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams
[Released under MIT License. Please refer to license.txt for details]
========================================== */
#include "unity.h"
#include <stdio.h>
#include <string.h>
#define UNITY_FAIL_AND_BAIL { Unity.CurrentTestFailed = 1; UNITY_OUTPUT_CHAR('\n'); longjmp(Unity.AbortFrame, 1); }
#define UNITY_IGNORE_AND_BAIL { Unity.CurrentTestIgnored = 1; UNITY_OUTPUT_CHAR('\n'); longjmp(Unity.AbortFrame, 1); }
/// return prematurely if we are already in failure or ignore state
#define UNITY_SKIP_EXECUTION { if ((Unity.CurrentTestFailed != 0) || (Unity.CurrentTestIgnored != 0)) {return;} }
#define UNITY_PRINT_EOL { UNITY_OUTPUT_CHAR('\n'); }
struct _Unity Unity = { 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , { 0 } };
const char* UnityStrNull = "NULL";
const char* UnityStrSpacer = ". ";
const char* UnityStrExpected = " Expected ";
const char* UnityStrWas = " Was ";
const char* UnityStrTo = " To ";
const char* UnityStrElement = " Element ";
const char* UnityStrByte = " Byte ";
const char* UnityStrMemory = " Memory Mismatch.";
const char* UnityStrDelta = " Values Not Within Delta ";
const char* UnityStrPointless= " You Asked Me To Compare Nothing, Which Was Pointless.";
const char* UnityStrNullPointerForExpected= " Expected pointer to be NULL";
const char* UnityStrNullPointerForActual = " Actual pointer was NULL";
// compiler-generic print formatting masks
const _U_UINT UnitySizeMask[] =
{
255u, // 0xFF
65535u, // 0xFFFF
65535u,
4294967295u, // 0xFFFFFFFF
4294967295u,
4294967295u,
4294967295u
#ifdef UNITY_SUPPORT_64
,0xFFFFFFFFFFFFFFFF
#endif
};
void UnityPrintFail(void);
void UnityPrintOk(void);
//-----------------------------------------------
// Pretty Printers & Test Result Output Handlers
//-----------------------------------------------
void UnityPrint(const char* string)
{
const char* pch = string;
if (pch != NULL)
{
while (*pch)
{
// printable characters plus CR & LF are printed
if ((*pch <= 126) && (*pch >= 32))
{
UNITY_OUTPUT_CHAR(*pch);
}
//write escaped carriage returns
else if (*pch == 13)
{
UNITY_OUTPUT_CHAR('\\');
UNITY_OUTPUT_CHAR('r');
}
//write escaped line feeds
else if (*pch == 10)
{
UNITY_OUTPUT_CHAR('\\');
UNITY_OUTPUT_CHAR('n');
}
// unprintable characters are shown as codes
else
{
UNITY_OUTPUT_CHAR('\\');
UnityPrintNumberHex((_U_SINT)*pch, 2);
}
pch++;
}
}
}
//-----------------------------------------------
void UnityPrintNumberByStyle(const _U_SINT number, const UNITY_DISPLAY_STYLE_T style)
{
if ((style & UNITY_DISPLAY_RANGE_INT) == UNITY_DISPLAY_RANGE_INT)
{
UnityPrintNumber(number);
}
else if ((style & UNITY_DISPLAY_RANGE_UINT) == UNITY_DISPLAY_RANGE_UINT)
{
UnityPrintNumberUnsigned( (_U_UINT)number & UnitySizeMask[((_U_UINT)style & (_U_UINT)0x0F) - 1] );
}
else
{
UnityPrintNumberHex((_U_UINT)number, (style & 0x000F) << 1);
}
}
//-----------------------------------------------
/// basically do an itoa using as little ram as possible
void UnityPrintNumber(const _U_SINT number_to_print)
{
_U_SINT divisor = 1;
_U_SINT next_divisor;
_U_SINT number = number_to_print;
if (number < 0)
{
UNITY_OUTPUT_CHAR('-');
number = -number;
}
// figure out initial divisor
while (number / divisor > 9)
{
next_divisor = divisor * 10;
if (next_divisor > divisor)
divisor = next_divisor;
else
break;
}
// now mod and print, then divide divisor
do
{
UNITY_OUTPUT_CHAR((char)('0' + (number / divisor % 10)));
divisor /= 10;
}
while (divisor > 0);
}
//-----------------------------------------------
/// basically do an itoa using as little ram as possible
void UnityPrintNumberUnsigned(const _U_UINT number)
{
_U_UINT divisor = 1;
_U_UINT next_divisor;
// figure out initial divisor
while (number / divisor > 9)
{
next_divisor = divisor * 10;
if (next_divisor > divisor)
divisor = next_divisor;
else
break;
}
// now mod and print, then divide divisor
do
{
UNITY_OUTPUT_CHAR((char)('0' + (number / divisor % 10)));
divisor /= 10;
}
while (divisor > 0);
}
//-----------------------------------------------
void UnityPrintNumberHex(const _U_UINT number, const char nibbles_to_print)
{
_U_UINT nibble;
char nibbles = nibbles_to_print;
UNITY_OUTPUT_CHAR('0');
UNITY_OUTPUT_CHAR('x');
while (nibbles > 0)
{
nibble = (number >> (--nibbles << 2)) & 0x0000000F;
if (nibble <= 9)
{
UNITY_OUTPUT_CHAR((char)('0' + nibble));
}
else
{
UNITY_OUTPUT_CHAR((char)('A' - 10 + nibble));
}
}
}
//-----------------------------------------------
void UnityPrintMask(const _U_UINT mask, const _U_UINT number)
{
_U_UINT current_bit = (_U_UINT)1 << (UNITY_INT_WIDTH - 1);
_US32 i;
for (i = 0; i < UNITY_INT_WIDTH; i++)
{
if (current_bit & mask)
{
if (current_bit & number)
{
UNITY_OUTPUT_CHAR('1');
}
else
{
UNITY_OUTPUT_CHAR('0');
}
}
else
{
UNITY_OUTPUT_CHAR('X');
}
current_bit = current_bit >> 1;
}
}
//-----------------------------------------------
#ifdef UNITY_FLOAT_VERBOSE
void UnityPrintFloat(_UF number)
{
char TempBuffer[32];
sprintf(TempBuffer, "%.6f", number);
UnityPrint(TempBuffer);
}
#endif
//-----------------------------------------------
void UnityPrintFail(void)
{
UnityPrint("FAIL");
}
void UnityPrintOk(void)
{
UnityPrint("OK");
}
//-----------------------------------------------
void UnityTestResultsBegin(const char* file, const UNITY_LINE_TYPE line)
{
UnityPrint(file);
UNITY_OUTPUT_CHAR(':');
UnityPrintNumber(line);
UNITY_OUTPUT_CHAR(':');
UnityPrint(Unity.CurrentTestName);
UNITY_OUTPUT_CHAR(':');
}
//-----------------------------------------------
void UnityTestResultsFailBegin(const UNITY_LINE_TYPE line)
{
UnityTestResultsBegin(Unity.TestFile, line);
UnityPrint("FAIL:");
}
//-----------------------------------------------
void UnityConcludeTest(void)
{
if (Unity.CurrentTestIgnored)
{
Unity.TestIgnores++;
}
else if (!Unity.CurrentTestFailed)
{
UnityTestResultsBegin(Unity.TestFile, Unity.CurrentTestLineNumber);
UnityPrint("PASS");
UNITY_PRINT_EOL;
}
else
{
Unity.TestFailures++;
}
Unity.CurrentTestFailed = 0;
Unity.CurrentTestIgnored = 0;
}
//-----------------------------------------------
void UnityAddMsgIfSpecified(const char* msg)
{
if (msg)
{
UnityPrint(UnityStrSpacer);
UnityPrint(msg);
}
}
//-----------------------------------------------
void UnityPrintExpectedAndActualStrings(const char* expected, const char* actual)
{
UnityPrint(UnityStrExpected);
if (expected != NULL)
{
UNITY_OUTPUT_CHAR('\'');
UnityPrint(expected);
UNITY_OUTPUT_CHAR('\'');
}
else
{
UnityPrint(UnityStrNull);
}
UnityPrint(UnityStrWas);
if (actual != NULL)
{
UNITY_OUTPUT_CHAR('\'');
UnityPrint(actual);
UNITY_OUTPUT_CHAR('\'');
}
else
{
UnityPrint(UnityStrNull);
}
}
//-----------------------------------------------
// Assertion & Control Helpers
//-----------------------------------------------
int UnityCheckArraysForNull(const void* expected, const void* actual, const UNITY_LINE_TYPE lineNumber, const char* msg)
{
//return true if they are both NULL
if ((expected == NULL) && (actual == NULL))
return 1;
//throw error if just expected is NULL
if (expected == NULL)
{
UnityTestResultsFailBegin(lineNumber);
UnityPrint(UnityStrNullPointerForExpected);
UnityAddMsgIfSpecified(msg);
UNITY_FAIL_AND_BAIL;
}
//throw error if just actual is NULL
if (actual == NULL)
{
UnityTestResultsFailBegin(lineNumber);
UnityPrint(UnityStrNullPointerForActual);
UnityAddMsgIfSpecified(msg);
UNITY_FAIL_AND_BAIL;
}
//return false if neither is NULL
return 0;
}
//-----------------------------------------------
// Assertion Functions
//-----------------------------------------------
void UnityAssertBits(const _U_SINT mask,
const _U_SINT expected,
const _U_SINT actual,
const char* msg,
const UNITY_LINE_TYPE lineNumber)
{
UNITY_SKIP_EXECUTION;
if ((mask & expected) != (mask & actual))
{
UnityTestResultsFailBegin(lineNumber);
UnityPrint(UnityStrExpected);
UnityPrintMask(mask, expected);
UnityPrint(UnityStrWas);
UnityPrintMask(mask, actual);
UnityAddMsgIfSpecified(msg);
UNITY_FAIL_AND_BAIL;
}
}
//-----------------------------------------------
void UnityAssertEqualNumber(const _U_SINT expected,
const _U_SINT actual,
const char* msg,
const UNITY_LINE_TYPE lineNumber,
const UNITY_DISPLAY_STYLE_T style)
{
UNITY_SKIP_EXECUTION;
if (expected != actual)
{
UnityTestResultsFailBegin(lineNumber);
UnityPrint(UnityStrExpected);
UnityPrintNumberByStyle(expected, style);
UnityPrint(UnityStrWas);
UnityPrintNumberByStyle(actual, style);
UnityAddMsgIfSpecified(msg);
UNITY_FAIL_AND_BAIL;
}
}
//-----------------------------------------------
void UnityAssertEqualIntArray(const _U_SINT* expected,
const _U_SINT* actual,
const _UU32 num_elements,
const char* msg,
const UNITY_LINE_TYPE lineNumber,
const UNITY_DISPLAY_STYLE_T style)
{
_UU32 elements = num_elements;
const _US8* ptr_exp = (_US8*)expected;
const _US8* ptr_act = (_US8*)actual;
UNITY_SKIP_EXECUTION;
if (elements == 0)
{
UnityTestResultsFailBegin(lineNumber);
UnityPrint(UnityStrPointless);
UnityAddMsgIfSpecified(msg);
UNITY_FAIL_AND_BAIL;
}
if (UnityCheckArraysForNull((void*)expected, (void*)actual, lineNumber, msg) == 1)
return;
switch(style)
{
case UNITY_DISPLAY_STYLE_HEX8:
case UNITY_DISPLAY_STYLE_INT8:
case UNITY_DISPLAY_STYLE_UINT8:
while (elements--)
{
if (*ptr_exp != *ptr_act)
{
UnityTestResultsFailBegin(lineNumber);
UnityPrint(UnityStrElement);
UnityPrintNumberByStyle((num_elements - elements - 1), UNITY_DISPLAY_STYLE_UINT);
UnityPrint(UnityStrExpected);
UnityPrintNumberByStyle(*ptr_exp, style);
UnityPrint(UnityStrWas);
UnityPrintNumberByStyle(*ptr_act, style);
UnityAddMsgIfSpecified(msg);
UNITY_FAIL_AND_BAIL;
}
ptr_exp += 1;
ptr_act += 1;
}
break;
case UNITY_DISPLAY_STYLE_HEX16:
case UNITY_DISPLAY_STYLE_INT16:
case UNITY_DISPLAY_STYLE_UINT16:
while (elements--)
{
if (*(_US16*)ptr_exp != *(_US16*)ptr_act)
{
UnityTestResultsFailBegin(lineNumber);
UnityPrint(UnityStrElement);
UnityPrintNumberByStyle((num_elements - elements - 1), UNITY_DISPLAY_STYLE_UINT);
UnityPrint(UnityStrExpected);
UnityPrintNumberByStyle(*(_US16*)ptr_exp, style);
UnityPrint(UnityStrWas);
UnityPrintNumberByStyle(*(_US16*)ptr_act, style);
UnityAddMsgIfSpecified(msg);
UNITY_FAIL_AND_BAIL;
}
ptr_exp += 2;
ptr_act += 2;
}
break;
#ifdef UNITY_SUPPORT_64
case UNITY_DISPLAY_STYLE_HEX64:
case UNITY_DISPLAY_STYLE_INT64:
case UNITY_DISPLAY_STYLE_UINT64:
while (elements--)
{
if (*(_US64*)ptr_exp != *(_US64*)ptr_act)
{
UnityTestResultsFailBegin(lineNumber);
UnityPrint(UnityStrElement);
UnityPrintNumberByStyle((num_elements - elements - 1), UNITY_DISPLAY_STYLE_UINT);
UnityPrint(UnityStrExpected);
UnityPrintNumberByStyle(*(_US64*)ptr_exp, style);
UnityPrint(UnityStrWas);
UnityPrintNumberByStyle(*(_US64*)ptr_act, style);
UnityAddMsgIfSpecified(msg);
UNITY_FAIL_AND_BAIL;
}
ptr_exp += 8;
ptr_act += 8;
}
break;
#endif
default:
while (elements--)
{
if (*(_US32*)ptr_exp != *(_US32*)ptr_act)
{
UnityTestResultsFailBegin(lineNumber);
UnityPrint(UnityStrElement);
UnityPrintNumberByStyle((num_elements - elements - 1), UNITY_DISPLAY_STYLE_UINT);
UnityPrint(UnityStrExpected);
UnityPrintNumberByStyle(*(_US32*)ptr_exp, style);
UnityPrint(UnityStrWas);
UnityPrintNumberByStyle(*(_US32*)ptr_act, style);
UnityAddMsgIfSpecified(msg);
UNITY_FAIL_AND_BAIL;
}
ptr_exp += 4;
ptr_act += 4;
}
break;
}
}
//-----------------------------------------------
#ifndef UNITY_EXCLUDE_FLOAT
void UnityAssertEqualFloatArray(const _UF* expected,
const _UF* actual,
const _UU32 num_elements,
const char* msg,
const UNITY_LINE_TYPE lineNumber)
{
_UU32 elements = num_elements;
const _UF* ptr_expected = expected;
const _UF* ptr_actual = actual;
_UF diff, tol;
UNITY_SKIP_EXECUTION;
if (elements == 0)
{
UnityTestResultsFailBegin(lineNumber);
UnityPrint(UnityStrPointless);
UnityAddMsgIfSpecified(msg);
UNITY_FAIL_AND_BAIL;
}
if (UnityCheckArraysForNull((void*)expected, (void*)actual, lineNumber, msg) == 1)
return;
while (elements--)
{
diff = *ptr_expected - *ptr_actual;
if (diff < 0.0)
diff = 0.0 - diff;
tol = UNITY_FLOAT_PRECISION * *ptr_expected;
if (tol < 0.0)
tol = 0.0 - tol;
if (diff > tol)
{
UnityTestResultsFailBegin(lineNumber);
UnityPrint(UnityStrElement);
UnityPrintNumberByStyle((num_elements - elements - 1), UNITY_DISPLAY_STYLE_UINT);
#ifdef UNITY_FLOAT_VERBOSE
UnityPrint(UnityStrExpected);
UnityPrintFloat(*ptr_expected);
UnityPrint(UnityStrWas);
UnityPrintFloat(*ptr_actual);
#else
UnityPrint(UnityStrDelta);
#endif
UnityAddMsgIfSpecified(msg);
UNITY_FAIL_AND_BAIL;
}
ptr_expected++;
ptr_actual++;
}
}
//-----------------------------------------------
void UnityAssertFloatsWithin(const _UF delta,
const _UF expected,
const _UF actual,
const char* msg,
const UNITY_LINE_TYPE lineNumber)
{
_UF diff = actual - expected;
_UF pos_delta = delta;
UNITY_SKIP_EXECUTION;
if (diff < 0)
{
diff = 0.0f - diff;
}
if (pos_delta < 0)
{
pos_delta = 0.0f - pos_delta;
}
if (pos_delta < diff)
{
UnityTestResultsFailBegin(lineNumber);
#ifdef UNITY_FLOAT_VERBOSE
UnityPrint(UnityStrExpected);
UnityPrintFloat(expected);
UnityPrint(UnityStrWas);
UnityPrintFloat(actual);
#else
UnityPrint(UnityStrDelta);
#endif
UnityAddMsgIfSpecified(msg);
UNITY_FAIL_AND_BAIL;
}
}
#endif //not UNITY_EXCLUDE_FLOAT
//-----------------------------------------------
#ifndef UNITY_EXCLUDE_DOUBLE
void UnityAssertEqualDoubleArray(const _UD* expected,
const _UD* actual,
const _UU32 num_elements,
const char* msg,
const UNITY_LINE_TYPE lineNumber)
{
_UU32 elements = num_elements;
const _UD* ptr_expected = expected;
const _UD* ptr_actual = actual;
_UD diff, tol;
UNITY_SKIP_EXECUTION;
if (elements == 0)
{
UnityTestResultsFailBegin(lineNumber);
UnityPrint(UnityStrPointless);
UnityAddMsgIfSpecified(msg);
UNITY_FAIL_AND_BAIL;
}
if (UnityCheckArraysForNull((void*)expected, (void*)actual, lineNumber, msg) == 1)
return;
while (elements--)
{
diff = *ptr_expected - *ptr_actual;
if (diff < 0.0)
diff = 0.0 - diff;
tol = UNITY_DOUBLE_PRECISION * *ptr_expected;
if (tol < 0.0)
tol = 0.0 - tol;
if (diff > tol)
{
UnityTestResultsFailBegin(lineNumber);
UnityPrint(UnityStrElement);
UnityPrintNumberByStyle((num_elements - elements - 1), UNITY_DISPLAY_STYLE_UINT);
#ifdef UNITY_DOUBLE_VERBOSE
UnityPrint(UnityStrExpected);
UnityPrintFloat((float)(*ptr_expected));
UnityPrint(UnityStrWas);
UnityPrintFloat((float)(*ptr_actual));
#else
UnityPrint(UnityStrDelta);
#endif
UnityAddMsgIfSpecified(msg);
UNITY_FAIL_AND_BAIL;
}
ptr_expected++;
ptr_actual++;
}
}
//-----------------------------------------------
void UnityAssertDoublesWithin(const _UD delta,
const _UD expected,
const _UD actual,
const char* msg,
const UNITY_LINE_TYPE lineNumber)
{
_UD diff = actual - expected;
_UD pos_delta = delta;
UNITY_SKIP_EXECUTION;
if (diff < 0)
{
diff = 0.0f - diff;
}
if (pos_delta < 0)
{
pos_delta = 0.0f - pos_delta;
}
if (pos_delta < diff)
{
UnityTestResultsFailBegin(lineNumber);
#ifdef UNITY_DOUBLE_VERBOSE
UnityPrint(UnityStrExpected);
UnityPrintFloat((float)expected);
UnityPrint(UnityStrWas);
UnityPrintFloat((float)actual);
#else
UnityPrint(UnityStrDelta);
#endif
UnityAddMsgIfSpecified(msg);
UNITY_FAIL_AND_BAIL;
}
}
#endif // not UNITY_EXCLUDE_DOUBLE
//-----------------------------------------------
void UnityAssertNumbersWithin( const _U_SINT delta,
const _U_SINT expected,
const _U_SINT actual,
const char* msg,
const UNITY_LINE_TYPE lineNumber,
const UNITY_DISPLAY_STYLE_T style)
{
UNITY_SKIP_EXECUTION;
if ((style & UNITY_DISPLAY_RANGE_INT) == UNITY_DISPLAY_RANGE_INT)
{
if (actual > expected)
Unity.CurrentTestFailed = ((actual - expected) > delta);
else
Unity.CurrentTestFailed = ((expected - actual) > delta);
}
else
{
if ((_U_UINT)actual > (_U_UINT)expected)
Unity.CurrentTestFailed = ((_U_UINT)(actual - expected) > (_U_UINT)delta);
else
Unity.CurrentTestFailed = ((_U_UINT)(expected - actual) > (_U_UINT)delta);
}
if (Unity.CurrentTestFailed)
{
UnityTestResultsFailBegin(lineNumber);
UnityPrint(UnityStrDelta);
UnityPrintNumberByStyle(delta, style);
UnityPrint(UnityStrExpected);
UnityPrintNumberByStyle(expected, style);
UnityPrint(UnityStrWas);
UnityPrintNumberByStyle(actual, style);
UnityAddMsgIfSpecified(msg);
UNITY_FAIL_AND_BAIL;
}
}
//-----------------------------------------------
void UnityAssertEqualString(const char* expected,
const char* actual,
const char* msg,
const UNITY_LINE_TYPE lineNumber)
{
_UU32 i;
UNITY_SKIP_EXECUTION;
// if both pointers not null compare the strings
if (expected && actual)
{
for (i = 0; expected[i] || actual[i]; i++)
{
if (expected[i] != actual[i])
{
Unity.CurrentTestFailed = 1;
break;
}
}
}
else
{ // handle case of one pointers being null (if both null, test should pass)
if (expected != actual)
{
Unity.CurrentTestFailed = 1;
}
}
if (Unity.CurrentTestFailed)
{
UnityTestResultsFailBegin(lineNumber);
UnityPrintExpectedAndActualStrings(expected, actual);
UnityAddMsgIfSpecified(msg);
UNITY_FAIL_AND_BAIL;
}
}
//-----------------------------------------------
void UnityAssertEqualStringArray( const char** expected,
const char** actual,
const _UU32 num_elements,
const char* msg,
const UNITY_LINE_TYPE lineNumber)
{
_UU32 i, j = 0;
UNITY_SKIP_EXECUTION;
// if no elements, it's an error
if (num_elements == 0)
{
UnityTestResultsFailBegin(lineNumber);
UnityPrint(UnityStrPointless);
UnityAddMsgIfSpecified(msg);
UNITY_FAIL_AND_BAIL;
}
if (UnityCheckArraysForNull((void*)expected, (void*)actual, lineNumber, msg) == 1)
return;
do
{
// if both pointers not null compare the strings
if (expected[j] && actual[j])
{
for (i = 0; expected[j][i] || actual[j][i]; i++)
{
if (expected[j][i] != actual[j][i])
{
Unity.CurrentTestFailed = 1;
break;
}
}
}
else
{ // handle case of one pointers being null (if both null, test should pass)
if (expected[j] != actual[j])
{
Unity.CurrentTestFailed = 1;
}
}
if (Unity.CurrentTestFailed)
{
UnityTestResultsFailBegin(lineNumber);
if (num_elements > 1)
{
UnityPrint(UnityStrElement);
UnityPrintNumberByStyle((num_elements - j - 1), UNITY_DISPLAY_STYLE_UINT);
}
UnityPrintExpectedAndActualStrings((const char*)(expected[j]), (const char*)(actual[j]));
UnityAddMsgIfSpecified(msg);
UNITY_FAIL_AND_BAIL;
}
} while (++j < num_elements);
}
//-----------------------------------------------
void UnityAssertEqualMemory( const void* expected,
const void* actual,
const _UU32 length,
const _UU32 num_elements,
const char* msg,
const UNITY_LINE_TYPE lineNumber)
{
unsigned char* ptr_exp = (unsigned char*)expected;
unsigned char* ptr_act = (unsigned char*)actual;
_UU32 elements = num_elements;
_UU32 bytes;
UNITY_SKIP_EXECUTION;
if ((elements == 0) || (length == 0))
{
UnityTestResultsFailBegin(lineNumber);
UnityPrint(UnityStrPointless);
UnityAddMsgIfSpecified(msg);
UNITY_FAIL_AND_BAIL;
}
if (UnityCheckArraysForNull((void*)expected, (void*)actual, lineNumber, msg) == 1)
return;
while (elements--)
{
/////////////////////////////////////
bytes = length;
while (bytes--)
{
if (*ptr_exp != *ptr_act)
{
UnityTestResultsFailBegin(lineNumber);
UnityPrint(UnityStrMemory);
if (num_elements > 1)
{
UnityPrint(UnityStrElement);
UnityPrintNumberByStyle((num_elements - elements - 1), UNITY_DISPLAY_STYLE_UINT);
}
UnityPrint(UnityStrByte);
UnityPrintNumberByStyle((length - bytes - 1), UNITY_DISPLAY_STYLE_UINT);
UnityPrint(UnityStrExpected);
UnityPrintNumberByStyle(*ptr_exp, UNITY_DISPLAY_STYLE_HEX8);
UnityPrint(UnityStrWas);
UnityPrintNumberByStyle(*ptr_act, UNITY_DISPLAY_STYLE_HEX8);
UnityAddMsgIfSpecified(msg);
UNITY_FAIL_AND_BAIL;
}
ptr_exp += 1;
ptr_act += 1;
}
/////////////////////////////////////
}
}
//-----------------------------------------------
// Control Functions
//-----------------------------------------------
void UnityFail(const char* msg, const UNITY_LINE_TYPE line)
{
UNITY_SKIP_EXECUTION;
UnityTestResultsBegin(Unity.TestFile, line);
UnityPrintFail();
if (msg != NULL)
{
UNITY_OUTPUT_CHAR(':');
if (msg[0] != ' ')
{
UNITY_OUTPUT_CHAR(' ');
}
UnityPrint(msg);
}
UNITY_FAIL_AND_BAIL;
}
//-----------------------------------------------
void UnityIgnore(const char* msg, const UNITY_LINE_TYPE line)
{
UNITY_SKIP_EXECUTION;
UnityTestResultsBegin(Unity.TestFile, line);
UnityPrint("IGNORE");
if (msg != NULL)
{
UNITY_OUTPUT_CHAR(':');
UNITY_OUTPUT_CHAR(' ');
UnityPrint(msg);
}
UNITY_IGNORE_AND_BAIL;
}
//-----------------------------------------------
void setUp(void);
void tearDown(void);
void UnityDefaultTestRun(UnityTestFunction Func, const char* FuncName, const int FuncLineNum)
{
Unity.CurrentTestName = FuncName;
Unity.CurrentTestLineNumber = FuncLineNum;
Unity.NumberOfTests++;
if (TEST_PROTECT())
{
setUp();
Func();
}
if (TEST_PROTECT() && !(Unity.CurrentTestIgnored))
{
tearDown();
}
UnityConcludeTest();
}
//-----------------------------------------------
void UnityBegin(void)
{
Unity.NumberOfTests = 0;
Unity.TestFailures = 0;
Unity.TestIgnores = 0;
Unity.CurrentTestFailed = 0;
Unity.CurrentTestIgnored = 0;
}
//-----------------------------------------------
int UnityEnd(void)
{
UnityPrint("-----------------------");
UNITY_PRINT_EOL;
UnityPrintNumber(Unity.NumberOfTests);
UnityPrint(" Tests ");
UnityPrintNumber(Unity.TestFailures);
UnityPrint(" Failures ");
UnityPrintNumber(Unity.TestIgnores);
UnityPrint(" Ignored");
UNITY_PRINT_EOL;
if (Unity.TestFailures == 0U)
{
UnityPrintOk();
}
else
{
UnityPrintFail();
}
UNITY_PRINT_EOL;
return Unity.TestFailures;
}
+232
View File
@@ -0,0 +1,232 @@
/* ==========================================
Unity Project - A Test Framework for C
Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams
[Released under MIT License. Please refer to license.txt for details]
========================================== */
#ifndef UNITY_FRAMEWORK_H
#define UNITY_FRAMEWORK_H
#define UNITY
#include "unity_internals.h"
//-------------------------------------------------------
// Configuration Options
//-------------------------------------------------------
// Integers
// - Unity assumes 32 bit integers by default
// - If your compiler treats ints of a different size, define UNITY_INT_WIDTH
// Floats
// - define UNITY_EXCLUDE_FLOAT to disallow floating point comparisons
// - define UNITY_FLOAT_PRECISION to specify the precision to use when doing TEST_ASSERT_EQUAL_FLOAT
// - define UNITY_FLOAT_TYPE to specify doubles instead of single precision floats
// - define UNITY_FLOAT_VERBOSE to print floating point values in errors (uses sprintf)
// - define UNITY_INCLUDE_DOUBLE to allow double floating point comparisons
// - define UNITY_EXCLUDE_DOUBLE to disallow double floating point comparisons (default)
// - define UNITY_DOUBLE_PRECISION to specify the precision to use when doing TEST_ASSERT_EQUAL_DOUBLE
// - define UNITY_DOUBLE_TYPE to specify something other than double
// - define UNITY_DOUBLE_VERBOSE to print floating point values in errors (uses sprintf)
// Output
// - by default, Unity prints to standard out with putchar. define UNITY_OUTPUT_CHAR(a) with a different function if desired
// Optimization
// - by default, line numbers are stored in unsigned shorts. Define UNITY_LINE_TYPE with a different type if your files are huge
// - by default, test and failure counters are unsigned shorts. Define UNITY_COUNTER_TYPE with a different type if you want to save space or have more than 65535 Tests.
// Test Cases
// - define UNITY_SUPPORT_TEST_CASES to include the TEST_CASE macro, though really it's mostly about the runner generator script
// Parameterized Tests
// - you'll want to create a define of TEST_CASE(...) which basically evaluates to nothing
//-------------------------------------------------------
// Test Running Macros
//-------------------------------------------------------
#define TEST_PROTECT() (setjmp(Unity.AbortFrame) == 0)
#define TEST_ABORT() {longjmp(Unity.AbortFrame, 1);}
#ifndef RUN_TEST
#define RUN_TEST(func, line_num) UnityDefaultTestRun(func, #func, line_num)
#endif
#define TEST_LINE_NUM (Unity.CurrentTestLineNumber)
#define TEST_IS_IGNORED (Unity.CurrentTestIgnored)
//-------------------------------------------------------
// Basic Fail and Ignore
//-------------------------------------------------------
#define TEST_FAIL_MESSAGE(message) UNITY_TEST_FAIL(__LINE__, message)
#define TEST_FAIL() UNITY_TEST_FAIL(__LINE__, NULL)
#define TEST_IGNORE_MESSAGE(message) UNITY_TEST_IGNORE(__LINE__, message)
#define TEST_IGNORE() UNITY_TEST_IGNORE(__LINE__, NULL)
#define TEST_ONLY()
//-------------------------------------------------------
// Test Asserts (simple)
//-------------------------------------------------------
//Boolean
#define TEST_ASSERT(condition) UNITY_TEST_ASSERT( (condition), __LINE__, " Expression Evaluated To FALSE")
#define TEST_ASSERT_TRUE(condition) UNITY_TEST_ASSERT( (condition), __LINE__, " Expected TRUE Was FALSE")
#define TEST_ASSERT_UNLESS(condition) UNITY_TEST_ASSERT( !(condition), __LINE__, " Expression Evaluated To TRUE")
#define TEST_ASSERT_FALSE(condition) UNITY_TEST_ASSERT( !(condition), __LINE__, " Expected FALSE Was TRUE")
#define TEST_ASSERT_NULL(pointer) UNITY_TEST_ASSERT_NULL( (pointer), __LINE__, " Expected NULL")
#define TEST_ASSERT_NOT_NULL(pointer) UNITY_TEST_ASSERT_NOT_NULL((pointer), __LINE__, " Expected Non-NULL")
//Integers (of all sizes)
#define TEST_ASSERT_EQUAL_INT(expected, actual) UNITY_TEST_ASSERT_EQUAL_INT((expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_EQUAL_INT8(expected, actual) UNITY_TEST_ASSERT_EQUAL_INT8((expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_EQUAL_INT16(expected, actual) UNITY_TEST_ASSERT_EQUAL_INT16((expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_EQUAL_INT32(expected, actual) UNITY_TEST_ASSERT_EQUAL_INT32((expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_EQUAL_INT64(expected, actual) UNITY_TEST_ASSERT_EQUAL_INT64((expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_EQUAL(expected, actual) UNITY_TEST_ASSERT_EQUAL_INT((expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_NOT_EQUAL(expected, actual) UNITY_TEST_ASSERT(((expected) != (actual)), __LINE__, " Expected Not-Equal")
#define TEST_ASSERT_EQUAL_UINT(expected, actual) UNITY_TEST_ASSERT_EQUAL_UINT( (expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_EQUAL_UINT8(expected, actual) UNITY_TEST_ASSERT_EQUAL_UINT8( (expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_EQUAL_UINT16(expected, actual) UNITY_TEST_ASSERT_EQUAL_UINT16( (expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_EQUAL_UINT32(expected, actual) UNITY_TEST_ASSERT_EQUAL_UINT32( (expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_EQUAL_UINT64(expected, actual) UNITY_TEST_ASSERT_EQUAL_UINT64( (expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_EQUAL_HEX(expected, actual) UNITY_TEST_ASSERT_EQUAL_HEX32((expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_EQUAL_HEX8(expected, actual) UNITY_TEST_ASSERT_EQUAL_HEX8( (expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_EQUAL_HEX16(expected, actual) UNITY_TEST_ASSERT_EQUAL_HEX16((expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_EQUAL_HEX32(expected, actual) UNITY_TEST_ASSERT_EQUAL_HEX32((expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_EQUAL_HEX64(expected, actual) UNITY_TEST_ASSERT_EQUAL_HEX64((expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_BITS(mask, expected, actual) UNITY_TEST_ASSERT_BITS((mask), (expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_BITS_HIGH(mask, actual) UNITY_TEST_ASSERT_BITS((mask), (_UU32)(-1), (actual), __LINE__, NULL)
#define TEST_ASSERT_BITS_LOW(mask, actual) UNITY_TEST_ASSERT_BITS((mask), (_UU32)(0), (actual), __LINE__, NULL)
#define TEST_ASSERT_BIT_HIGH(bit, actual) UNITY_TEST_ASSERT_BITS(((_UU32)1 << bit), (_UU32)(-1), (actual), __LINE__, NULL)
#define TEST_ASSERT_BIT_LOW(bit, actual) UNITY_TEST_ASSERT_BITS(((_UU32)1 << bit), (_UU32)(0), (actual), __LINE__, NULL)
//Integer Ranges (of all sizes)
#define TEST_ASSERT_INT_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_INT_WITHIN(delta, expected, actual, __LINE__, NULL)
#define TEST_ASSERT_UINT_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_UINT_WITHIN(delta, expected, actual, __LINE__, NULL)
#define TEST_ASSERT_HEX_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_HEX32_WITHIN(delta, expected, actual, __LINE__, NULL)
#define TEST_ASSERT_HEX8_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_HEX8_WITHIN(delta, expected, actual, __LINE__, NULL)
#define TEST_ASSERT_HEX16_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_HEX16_WITHIN(delta, expected, actual, __LINE__, NULL)
#define TEST_ASSERT_HEX32_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_HEX32_WITHIN(delta, expected, actual, __LINE__, NULL)
#define TEST_ASSERT_HEX64_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_HEX64_WITHIN(delta, expected, actual, __LINE__, NULL)
//Structs and Strings
#define TEST_ASSERT_EQUAL_PTR(expected, actual) UNITY_TEST_ASSERT_EQUAL_PTR((expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_EQUAL_STRING(expected, actual) UNITY_TEST_ASSERT_EQUAL_STRING(expected, actual, __LINE__, NULL)
#define TEST_ASSERT_EQUAL_MEMORY(expected, actual, len) UNITY_TEST_ASSERT_EQUAL_MEMORY(expected, actual, len, __LINE__, NULL)
//Arrays
#define TEST_ASSERT_EQUAL_INT_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_INT_ARRAY(expected, actual, num_elements, __LINE__, NULL)
#define TEST_ASSERT_EQUAL_INT8_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_INT8_ARRAY(expected, actual, num_elements, __LINE__, NULL)
#define TEST_ASSERT_EQUAL_INT16_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_INT16_ARRAY(expected, actual, num_elements, __LINE__, NULL)
#define TEST_ASSERT_EQUAL_INT32_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_INT32_ARRAY(expected, actual, num_elements, __LINE__, NULL)
#define TEST_ASSERT_EQUAL_INT64_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_INT64_ARRAY(expected, actual, num_elements, __LINE__, NULL)
#define TEST_ASSERT_EQUAL_UINT_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_UINT_ARRAY(expected, actual, num_elements, __LINE__, NULL)
#define TEST_ASSERT_EQUAL_UINT8_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_UINT8_ARRAY(expected, actual, num_elements, __LINE__, NULL)
#define TEST_ASSERT_EQUAL_UINT16_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_UINT16_ARRAY(expected, actual, num_elements, __LINE__, NULL)
#define TEST_ASSERT_EQUAL_UINT32_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_UINT32_ARRAY(expected, actual, num_elements, __LINE__, NULL)
#define TEST_ASSERT_EQUAL_UINT64_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_UINT64_ARRAY(expected, actual, num_elements, __LINE__, NULL)
#define TEST_ASSERT_EQUAL_HEX_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_HEX32_ARRAY(expected, actual, num_elements, __LINE__, NULL)
#define TEST_ASSERT_EQUAL_HEX8_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_HEX8_ARRAY(expected, actual, num_elements, __LINE__, NULL)
#define TEST_ASSERT_EQUAL_HEX16_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_HEX16_ARRAY(expected, actual, num_elements, __LINE__, NULL)
#define TEST_ASSERT_EQUAL_HEX32_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_HEX32_ARRAY(expected, actual, num_elements, __LINE__, NULL)
#define TEST_ASSERT_EQUAL_HEX64_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_HEX64_ARRAY(expected, actual, num_elements, __LINE__, NULL)
#define TEST_ASSERT_EQUAL_PTR_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_PTR_ARRAY(expected, actual, num_elements, __LINE__, NULL)
#define TEST_ASSERT_EQUAL_STRING_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_STRING_ARRAY(expected, actual, num_elements, __LINE__, NULL)
#define TEST_ASSERT_EQUAL_MEMORY_ARRAY(expected, actual, len, num_elements) UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY(expected, actual, len, num_elements, __LINE__, NULL)
//Floating Point (If Enabled)
#define TEST_ASSERT_FLOAT_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_FLOAT_WITHIN(delta, expected, actual, __LINE__, NULL)
#define TEST_ASSERT_EQUAL_FLOAT(expected, actual) UNITY_TEST_ASSERT_EQUAL_FLOAT(expected, actual, __LINE__, NULL)
#define TEST_ASSERT_EQUAL_FLOAT_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_FLOAT_ARRAY(expected, actual, num_elements, __LINE__, NULL)
//Double (If Enabled)
#define TEST_ASSERT_DOUBLE_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_DOUBLE_WITHIN(delta, expected, actual, __LINE__, NULL)
#define TEST_ASSERT_EQUAL_DOUBLE(expected, actual) UNITY_TEST_ASSERT_EQUAL_DOUBLE(expected, actual, __LINE__, NULL)
#define TEST_ASSERT_EQUAL_DOUBLE_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_DOUBLE_ARRAY(expected, actual, num_elements, __LINE__, NULL)
//-------------------------------------------------------
// Test Asserts (with additional messages)
//-------------------------------------------------------
//Boolean
#define TEST_ASSERT_MESSAGE(condition, message) UNITY_TEST_ASSERT( (condition), __LINE__, message)
#define TEST_ASSERT_TRUE_MESSAGE(condition, message) UNITY_TEST_ASSERT( (condition), __LINE__, message)
#define TEST_ASSERT_UNLESS_MESSAGE(condition, message) UNITY_TEST_ASSERT( !(condition), __LINE__, message)
#define TEST_ASSERT_FALSE_MESSAGE(condition, message) UNITY_TEST_ASSERT( !(condition), __LINE__, message)
#define TEST_ASSERT_NULL_MESSAGE(pointer, message) UNITY_TEST_ASSERT_NULL( (pointer), __LINE__, message)
#define TEST_ASSERT_NOT_NULL_MESSAGE(pointer, message) UNITY_TEST_ASSERT_NOT_NULL((pointer), __LINE__, message)
//Integers (of all sizes)
#define TEST_ASSERT_EQUAL_INT_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_INT((expected), (actual), __LINE__, message)
#define TEST_ASSERT_EQUAL_INT8_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_INT8((expected), (actual), __LINE__, message)
#define TEST_ASSERT_EQUAL_INT16_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_INT16((expected), (actual), __LINE__, message)
#define TEST_ASSERT_EQUAL_INT32_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_INT32((expected), (actual), __LINE__, message)
#define TEST_ASSERT_EQUAL_INT64_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_INT64((expected), (actual), __LINE__, message)
#define TEST_ASSERT_EQUAL_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_INT((expected), (actual), __LINE__, message)
#define TEST_ASSERT_NOT_EQUAL_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT(((expected) != (actual)), __LINE__, message)
#define TEST_ASSERT_EQUAL_UINT_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_UINT( (expected), (actual), __LINE__, message)
#define TEST_ASSERT_EQUAL_UINT8_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_UINT8( (expected), (actual), __LINE__, message)
#define TEST_ASSERT_EQUAL_UINT16_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_UINT16( (expected), (actual), __LINE__, message)
#define TEST_ASSERT_EQUAL_UINT32_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_UINT32( (expected), (actual), __LINE__, message)
#define TEST_ASSERT_EQUAL_UINT64_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_UINT64( (expected), (actual), __LINE__, message)
#define TEST_ASSERT_EQUAL_HEX_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_HEX32((expected), (actual), __LINE__, message)
#define TEST_ASSERT_EQUAL_HEX8_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_HEX8( (expected), (actual), __LINE__, message)
#define TEST_ASSERT_EQUAL_HEX16_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_HEX16((expected), (actual), __LINE__, message)
#define TEST_ASSERT_EQUAL_HEX32_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_HEX32((expected), (actual), __LINE__, message)
#define TEST_ASSERT_EQUAL_HEX64_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_HEX64((expected), (actual), __LINE__, message)
#define TEST_ASSERT_BITS_MESSAGE(mask, expected, actual, message) UNITY_TEST_ASSERT_BITS((mask), (expected), (actual), __LINE__, message)
#define TEST_ASSERT_BITS_HIGH_MESSAGE(mask, actual, message) UNITY_TEST_ASSERT_BITS((mask), (_UU32)(-1), (actual), __LINE__, message)
#define TEST_ASSERT_BITS_LOW_MESSAGE(mask, actual, message) UNITY_TEST_ASSERT_BITS((mask), (_UU32)(0), (actual), __LINE__, message)
#define TEST_ASSERT_BIT_HIGH_MESSAGE(bit, actual, message) UNITY_TEST_ASSERT_BITS(((_UU32)1 << bit), (_UU32)(-1), (actual), __LINE__, message)
#define TEST_ASSERT_BIT_LOW_MESSAGE(bit, actual, message) UNITY_TEST_ASSERT_BITS(((_UU32)1 << bit), (_UU32)(0), (actual), __LINE__, message)
//Integer Ranges (of all sizes)
#define TEST_ASSERT_INT_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_INT_WITHIN(delta, expected, actual, __LINE__, message)
#define TEST_ASSERT_UINT_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_UINT_WITHIN(delta, expected, actual, __LINE__, message)
#define TEST_ASSERT_HEX_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_HEX32_WITHIN(delta, expected, actual, __LINE__, message)
#define TEST_ASSERT_HEX8_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_HEX8_WITHIN(delta, expected, actual, __LINE__, message)
#define TEST_ASSERT_HEX16_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_HEX16_WITHIN(delta, expected, actual, __LINE__, message)
#define TEST_ASSERT_HEX32_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_HEX32_WITHIN(delta, expected, actual, __LINE__, message)
#define TEST_ASSERT_HEX64_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_HEX64_WITHIN(delta, expected, actual, __LINE__, message)
//Structs and Strings
#define TEST_ASSERT_EQUAL_PTR_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_PTR(expected, actual, __LINE__, message)
#define TEST_ASSERT_EQUAL_STRING_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_STRING(expected, actual, __LINE__, message)
#define TEST_ASSERT_EQUAL_MEMORY_MESSAGE(expected, actual, len, message) UNITY_TEST_ASSERT_EQUAL_MEMORY(expected, actual, len, __LINE__, message)
//Arrays
#define TEST_ASSERT_EQUAL_INT_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_INT_ARRAY(expected, actual, num_elements, __LINE__, message)
#define TEST_ASSERT_EQUAL_INT8_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_INT8_ARRAY(expected, actual, num_elements, __LINE__, message)
#define TEST_ASSERT_EQUAL_INT16_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_INT16_ARRAY(expected, actual, num_elements, __LINE__, message)
#define TEST_ASSERT_EQUAL_INT32_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_INT32_ARRAY(expected, actual, num_elements, __LINE__, message)
#define TEST_ASSERT_EQUAL_INT64_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_INT64_ARRAY(expected, actual, num_elements, __LINE__, message)
#define TEST_ASSERT_EQUAL_UINT_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_UINT_ARRAY(expected, actual, num_elements, __LINE__, message)
#define TEST_ASSERT_EQUAL_UINT8_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_UINT8_ARRAY(expected, actual, num_elements, __LINE__, message)
#define TEST_ASSERT_EQUAL_UINT16_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_UINT16_ARRAY(expected, actual, num_elements, __LINE__, message)
#define TEST_ASSERT_EQUAL_UINT32_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_UINT32_ARRAY(expected, actual, num_elements, __LINE__, message)
#define TEST_ASSERT_EQUAL_UINT64_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_UINT64_ARRAY(expected, actual, num_elements, __LINE__, message)
#define TEST_ASSERT_EQUAL_HEX_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_HEX32_ARRAY(expected, actual, num_elements, __LINE__, message)
#define TEST_ASSERT_EQUAL_HEX8_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_HEX8_ARRAY(expected, actual, num_elements, __LINE__, message)
#define TEST_ASSERT_EQUAL_HEX16_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_HEX16_ARRAY(expected, actual, num_elements, __LINE__, message)
#define TEST_ASSERT_EQUAL_HEX32_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_HEX32_ARRAY(expected, actual, num_elements, __LINE__, message)
#define TEST_ASSERT_EQUAL_HEX64_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_HEX64_ARRAY(expected, actual, num_elements, __LINE__, message)
#define TEST_ASSERT_EQUAL_PTR_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_PTR_ARRAY(expected, actual, num_elements, __LINE__, message)
#define TEST_ASSERT_EQUAL_STRING_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_STRING_ARRAY(expected, actual, num_elements, __LINE__, message)
#define TEST_ASSERT_EQUAL_MEMORY_ARRAY_MESSAGE(expected, actual, len, num_elements, message) UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY(expected, actual, len, num_elements, __LINE__, message)
//Floating Point (If Enabled)
#define TEST_ASSERT_FLOAT_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_FLOAT_WITHIN(delta, expected, actual, __LINE__, message)
#define TEST_ASSERT_EQUAL_FLOAT_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_FLOAT(expected, actual, __LINE__, message)
#define TEST_ASSERT_EQUAL_FLOAT_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_FLOAT_ARRAY(expected, actual, num_elements, __LINE__, message)
//Double (If Enabled)
#define TEST_ASSERT_DOUBLE_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_DOUBLE_WITHIN(delta, expected, actual, __LINE__, message)
#define TEST_ASSERT_EQUAL_DOUBLE_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_DOUBLE(expected, actual, __LINE__, message)
#define TEST_ASSERT_EQUAL_DOUBLE_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_DOUBLE_ARRAY(expected, actual, num_elements, __LINE__, message)
#endif
+512
View File
@@ -0,0 +1,512 @@
/* ==========================================
Unity Project - A Test Framework for C
Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams
[Released under MIT License. Please refer to license.txt for details]
========================================== */
#ifndef UNITY_INTERNALS_H
#define UNITY_INTERNALS_H
#include <stdio.h>
#include <setjmp.h>
//stdint.h is often automatically included.
//Unity uses it to guess at the sizes of integer types, etc.
#ifdef UNITY_USE_LIMITS_H
#include <limits.h>
#endif
#ifndef UNITY_EXCLUDE_STDINT_H
#include <stdint.h>
#endif
//-------------------------------------------------------
// Guess Widths If Not Specified
//-------------------------------------------------------
// If the INT Width hasn't been specified,
// We first try to guess based on UINT_MAX (if it exists)
// Otherwise we fall back on assuming 32-bit
#ifndef UNITY_INT_WIDTH
#ifdef UINT_MAX
#if (UINT_MAX == 0xFFFF)
#define UNITY_INT_WIDTH (16)
#elif (UINT_MAX == 0xFFFFFFFF)
#define UNITY_INT_WIDTH (32)
#elif (UINT_MAX == 0xFFFFFFFFFFFFFFFF)
#define UNITY_INT_WIDTH (64)
#ifndef UNITY_SUPPORT_64
#define UNITY_SUPPORT_64
#endif
#else
#define UNITY_INT_WIDTH (32)
#endif
#else
#define UNITY_INT_WIDTH (32)
#endif
#endif
// If the Long Width hasn't been specified,
// We first try to guess based on ULONG_MAX (if it exists)
// Otherwise we fall back on assuming 32-bit
#ifndef UNITY_LONG_WIDTH
#ifdef ULONG_MAX
#if (ULONG_MAX == 0xFFFF)
#define UNITY_LONG_WIDTH (16)
#elif (ULONG_MAX == 0xFFFFFFFF)
#define UNITY_LONG_WIDTH (32)
#elif (ULONG_MAX == 0xFFFFFFFFFFFFFFFF)
#define UNITY_LONG_WIDTH (64)
#else
#define UNITY_LONG_WIDTH (32)
#ifndef UNITY_SUPPORT_64
#define UNITY_SUPPORT_64
#endif
#endif
#else
#define UNITY_LONG_WIDTH (32)
#endif
#endif
// If the Pointer Width hasn't been specified,
// We first try to guess based on INTPTR_MAX (if it exists)
// Otherwise we fall back on assuming 32-bit
#ifndef UNITY_POINTER_WIDTH
#ifdef UINTPTR_MAX
#if (UINTPTR_MAX <= 0xFFFF)
#define UNITY_POINTER_WIDTH (16)
#elif (UINTPTR_MAX <= 0xFFFFFFFF)
#define UNITY_POINTER_WIDTH (32)
#elif (UINTPTR_MAX <= 0xFFFFFFFFFFFFFFFF)
#define UNITY_POINTER_WIDTH (64)
#ifndef UNITY_SUPPORT_64
#define UNITY_SUPPORT_64
#endif
#endif
#endif
#endif
#ifndef UNITY_POINTER_WIDTH
#ifdef INTPTR_MAX
#if (INTPTR_MAX <= 0x7FFF)
#define UNITY_POINTER_WIDTH (16)
#elif (INTPTR_MAX <= 0x7FFFFFFF)
#define UNITY_POINTER_WIDTH (32)
#elif (INTPTR_MAX <= 0x7FFFFFFFFFFFFFFF)
#define UNITY_POINTER_WIDTH (64)
#ifndef UNITY_SUPPORT_64
#define UNITY_SUPPORT_64
#endif
#endif
#endif
#endif
#ifndef UNITY_POINTER_WIDTH
#define UNITY_POINTER_WIDTH (32)
#endif
//-------------------------------------------------------
// Int Support
//-------------------------------------------------------
#if (UNITY_INT_WIDTH == 32)
typedef unsigned char _UU8;
typedef unsigned short _UU16;
typedef unsigned int _UU32;
typedef signed char _US8;
typedef signed short _US16;
typedef signed int _US32;
#elif (UNITY_INT_WIDTH == 16)
typedef unsigned char _UU8;
typedef unsigned int _UU16;
typedef unsigned long _UU32;
typedef signed char _US8;
typedef signed int _US16;
typedef signed long _US32;
#else
#error Invalid UNITY_INT_WIDTH specified! (16 or 32 are supported)
#endif
//-------------------------------------------------------
// 64-bit Support
//-------------------------------------------------------
#ifndef UNITY_SUPPORT_64
//No 64-bit Support
typedef _UU32 _U_UINT;
typedef _US32 _U_SINT;
#else
//64-bit Support
#if (UNITY_LONG_WIDTH == 32)
typedef unsigned long long _UU64;
typedef signed long long _US64;
#elif (UNITY_LONG_WIDTH == 64)
typedef unsigned long _UU64;
typedef signed long _US64;
#else
#error Invalid UNITY_LONG_WIDTH specified! (32 or 64 are supported)
#endif
typedef _UU64 _U_UINT;
typedef _US64 _U_SINT;
#endif
//-------------------------------------------------------
// Pointer Support
//-------------------------------------------------------
#ifndef UNITY_POINTER_WIDTH
#define UNITY_POINTER_WIDTH (32)
#endif /* UNITY_POINTER_WIDTH */
#if (UNITY_POINTER_WIDTH == 32)
typedef _UU32 _UP;
#define UNITY_DISPLAY_STYLE_POINTER UNITY_DISPLAY_STYLE_HEX32
#elif (UNITY_POINTER_WIDTH == 64)
#ifndef UNITY_SUPPORT_64
#error "You've Specified 64-bit pointers without enabling 64-bit Support. Define UNITY_SUPPORT_64"
#endif
typedef _UU64 _UP;
#define UNITY_DISPLAY_STYLE_POINTER UNITY_DISPLAY_STYLE_HEX64
#elif (UNITY_POINTER_WIDTH == 16)
typedef _UU16 _UP;
#define UNITY_DISPLAY_STYLE_POINTER UNITY_DISPLAY_STYLE_HEX16
#else
#error Invalid UNITY_POINTER_WIDTH specified! (16, 32 or 64 are supported)
#endif
//-------------------------------------------------------
// Float Support
//-------------------------------------------------------
#ifdef UNITY_EXCLUDE_FLOAT
//No Floating Point Support
#undef UNITY_FLOAT_PRECISION
#undef UNITY_FLOAT_TYPE
#undef UNITY_FLOAT_VERBOSE
#else
//Floating Point Support
#ifndef UNITY_FLOAT_PRECISION
#define UNITY_FLOAT_PRECISION (0.00001f)
#endif
#ifndef UNITY_FLOAT_TYPE
#define UNITY_FLOAT_TYPE float
#endif
typedef UNITY_FLOAT_TYPE _UF;
#endif
//-------------------------------------------------------
// Double Float Support
//-------------------------------------------------------
//unlike FLOAT, we DON'T include by default
#ifndef UNITY_EXCLUDE_DOUBLE
#ifndef UNITY_INCLUDE_DOUBLE
#define UNITY_EXCLUDE_DOUBLE
#endif
#endif
#ifdef UNITY_EXCLUDE_DOUBLE
//No Floating Point Support
#undef UNITY_DOUBLE_PRECISION
#undef UNITY_DOUBLE_TYPE
#undef UNITY_DOUBLE_VERBOSE
#else
//Floating Point Support
#ifndef UNITY_DOUBLE_PRECISION
#define UNITY_DOUBLE_PRECISION (1e-12f)
#endif
#ifndef UNITY_DOUBLE_TYPE
#define UNITY_DOUBLE_TYPE double
#endif
typedef UNITY_DOUBLE_TYPE _UD;
#endif
//-------------------------------------------------------
// Output Method
//-------------------------------------------------------
#ifndef UNITY_OUTPUT_CHAR
//Default to using putchar, which is defined in stdio.h above
#define UNITY_OUTPUT_CHAR(a) putchar(a)
#else
//If defined as something else, make sure we declare it here so it's ready for use
extern int UNITY_OUTPUT_CHAR(int);
#endif
//-------------------------------------------------------
// Footprint
//-------------------------------------------------------
#ifndef UNITY_LINE_TYPE
#define UNITY_LINE_TYPE _U_UINT
#endif
#ifndef UNITY_COUNTER_TYPE
#define UNITY_COUNTER_TYPE _U_UINT
#endif
//-------------------------------------------------------
// Internal Structs Needed
//-------------------------------------------------------
typedef void (*UnityTestFunction)(void);
#define UNITY_DISPLAY_RANGE_INT (0x10)
#define UNITY_DISPLAY_RANGE_UINT (0x20)
#define UNITY_DISPLAY_RANGE_HEX (0x40)
#define UNITY_DISPLAY_RANGE_AUTO (0x80)
typedef enum
{
#if (UNITY_INT_WIDTH == 16)
UNITY_DISPLAY_STYLE_INT = 2 + UNITY_DISPLAY_RANGE_INT + UNITY_DISPLAY_RANGE_AUTO,
#elif (UNITY_INT_WIDTH == 32)
UNITY_DISPLAY_STYLE_INT = 4 + UNITY_DISPLAY_RANGE_INT + UNITY_DISPLAY_RANGE_AUTO,
#elif (UNITY_INT_WIDTH == 64)
UNITY_DISPLAY_STYLE_INT = 8 + UNITY_DISPLAY_RANGE_INT + UNITY_DISPLAY_RANGE_AUTO,
#endif
UNITY_DISPLAY_STYLE_INT8 = 1 + UNITY_DISPLAY_RANGE_INT,
UNITY_DISPLAY_STYLE_INT16 = 2 + UNITY_DISPLAY_RANGE_INT,
UNITY_DISPLAY_STYLE_INT32 = 4 + UNITY_DISPLAY_RANGE_INT,
#ifdef UNITY_SUPPORT_64
UNITY_DISPLAY_STYLE_INT64 = 8 + UNITY_DISPLAY_RANGE_INT,
#endif
#if (UNITY_INT_WIDTH == 16)
UNITY_DISPLAY_STYLE_UINT = 2 + UNITY_DISPLAY_RANGE_UINT + UNITY_DISPLAY_RANGE_AUTO,
#elif (UNITY_INT_WIDTH == 32)
UNITY_DISPLAY_STYLE_UINT = 4 + UNITY_DISPLAY_RANGE_UINT + UNITY_DISPLAY_RANGE_AUTO,
#elif (UNITY_INT_WIDTH == 64)
UNITY_DISPLAY_STYLE_UINT = 8 + UNITY_DISPLAY_RANGE_UINT + UNITY_DISPLAY_RANGE_AUTO,
#endif
UNITY_DISPLAY_STYLE_UINT8 = 1 + UNITY_DISPLAY_RANGE_UINT,
UNITY_DISPLAY_STYLE_UINT16 = 2 + UNITY_DISPLAY_RANGE_UINT,
UNITY_DISPLAY_STYLE_UINT32 = 4 + UNITY_DISPLAY_RANGE_UINT,
#ifdef UNITY_SUPPORT_64
UNITY_DISPLAY_STYLE_UINT64 = 8 + UNITY_DISPLAY_RANGE_UINT,
#endif
UNITY_DISPLAY_STYLE_HEX8 = 1 + UNITY_DISPLAY_RANGE_HEX,
UNITY_DISPLAY_STYLE_HEX16 = 2 + UNITY_DISPLAY_RANGE_HEX,
UNITY_DISPLAY_STYLE_HEX32 = 4 + UNITY_DISPLAY_RANGE_HEX,
#ifdef UNITY_SUPPORT_64
UNITY_DISPLAY_STYLE_HEX64 = 8 + UNITY_DISPLAY_RANGE_HEX,
#endif
UNITY_DISPLAY_STYLE_UNKNOWN
} UNITY_DISPLAY_STYLE_T;
struct _Unity
{
const char* TestFile;
const char* CurrentTestName;
UNITY_LINE_TYPE CurrentTestLineNumber;
UNITY_COUNTER_TYPE NumberOfTests;
UNITY_COUNTER_TYPE TestFailures;
UNITY_COUNTER_TYPE TestIgnores;
UNITY_COUNTER_TYPE CurrentTestFailed;
UNITY_COUNTER_TYPE CurrentTestIgnored;
jmp_buf AbortFrame;
};
extern struct _Unity Unity;
//-------------------------------------------------------
// Test Suite Management
//-------------------------------------------------------
void UnityBegin(void);
int UnityEnd(void);
void UnityConcludeTest(void);
void UnityDefaultTestRun(UnityTestFunction Func, const char* FuncName, const int FuncLineNum);
//-------------------------------------------------------
// Test Output
//-------------------------------------------------------
void UnityPrint(const char* string);
void UnityPrintMask(const _U_UINT mask, const _U_UINT number);
void UnityPrintNumberByStyle(const _U_SINT number, const UNITY_DISPLAY_STYLE_T style);
void UnityPrintNumber(const _U_SINT number);
void UnityPrintNumberUnsigned(const _U_UINT number);
void UnityPrintNumberHex(const _U_UINT number, const char nibbles);
#ifdef UNITY_FLOAT_VERBOSE
void UnityPrintFloat(const _UF number);
#endif
//-------------------------------------------------------
// Test Assertion Fuctions
//-------------------------------------------------------
// Use the macros below this section instead of calling
// these directly. The macros have a consistent naming
// convention and will pull in file and line information
// for you.
void UnityAssertEqualNumber(const _U_SINT expected,
const _U_SINT actual,
const char* msg,
const UNITY_LINE_TYPE lineNumber,
const UNITY_DISPLAY_STYLE_T style);
void UnityAssertEqualIntArray(const _U_SINT* expected,
const _U_SINT* actual,
const _UU32 num_elements,
const char* msg,
const UNITY_LINE_TYPE lineNumber,
const UNITY_DISPLAY_STYLE_T style);
void UnityAssertBits(const _U_SINT mask,
const _U_SINT expected,
const _U_SINT actual,
const char* msg,
const UNITY_LINE_TYPE lineNumber);
void UnityAssertEqualString(const char* expected,
const char* actual,
const char* msg,
const UNITY_LINE_TYPE lineNumber);
void UnityAssertEqualStringArray( const char** expected,
const char** actual,
const _UU32 num_elements,
const char* msg,
const UNITY_LINE_TYPE lineNumber);
void UnityAssertEqualMemory( const void* expected,
const void* actual,
const _UU32 length,
const _UU32 num_elements,
const char* msg,
const UNITY_LINE_TYPE lineNumber);
void UnityAssertNumbersWithin(const _U_SINT delta,
const _U_SINT expected,
const _U_SINT actual,
const char* msg,
const UNITY_LINE_TYPE lineNumber,
const UNITY_DISPLAY_STYLE_T style);
void UnityFail(const char* message, const UNITY_LINE_TYPE line);
void UnityIgnore(const char* message, const UNITY_LINE_TYPE line);
#ifndef UNITY_EXCLUDE_FLOAT
void UnityAssertFloatsWithin(const _UF delta,
const _UF expected,
const _UF actual,
const char* msg,
const UNITY_LINE_TYPE lineNumber);
void UnityAssertEqualFloatArray(const _UF* expected,
const _UF* actual,
const _UU32 num_elements,
const char* msg,
const UNITY_LINE_TYPE lineNumber);
#endif
#ifndef UNITY_EXCLUDE_DOUBLE
void UnityAssertDoublesWithin(const _UD delta,
const _UD expected,
const _UD actual,
const char* msg,
const UNITY_LINE_TYPE lineNumber);
void UnityAssertEqualDoubleArray(const _UD* expected,
const _UD* actual,
const _UU32 num_elements,
const char* msg,
const UNITY_LINE_TYPE lineNumber);
#endif
//-------------------------------------------------------
// Basic Fail and Ignore
//-------------------------------------------------------
#define UNITY_TEST_FAIL(line, message) UnityFail( (message), (UNITY_LINE_TYPE)line);
#define UNITY_TEST_IGNORE(line, message) UnityIgnore( (message), (UNITY_LINE_TYPE)line);
//-------------------------------------------------------
// Test Asserts
//-------------------------------------------------------
#define UNITY_TEST_ASSERT(condition, line, message) if (condition) {} else {UNITY_TEST_FAIL((UNITY_LINE_TYPE)line, message);}
#define UNITY_TEST_ASSERT_NULL(pointer, line, message) UNITY_TEST_ASSERT(((pointer) == NULL), (UNITY_LINE_TYPE)line, message)
#define UNITY_TEST_ASSERT_NOT_NULL(pointer, line, message) UNITY_TEST_ASSERT(((pointer) != NULL), (UNITY_LINE_TYPE)line, message)
#define UNITY_TEST_ASSERT_EQUAL_INT(expected, actual, line, message) UnityAssertEqualNumber((_U_SINT)(expected), (_U_SINT)(actual), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_INT)
#define UNITY_TEST_ASSERT_EQUAL_INT8(expected, actual, line, message) UnityAssertEqualNumber((_U_SINT)(_US8 )(expected), (_U_SINT)(_US8 )(actual), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_INT)
#define UNITY_TEST_ASSERT_EQUAL_INT16(expected, actual, line, message) UnityAssertEqualNumber((_U_SINT)(_US16)(expected), (_U_SINT)(_US16)(actual), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_INT)
#define UNITY_TEST_ASSERT_EQUAL_INT32(expected, actual, line, message) UnityAssertEqualNumber((_U_SINT)(_US32)(expected), (_U_SINT)(_US32)(actual), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_INT)
#define UNITY_TEST_ASSERT_EQUAL_UINT(expected, actual, line, message) UnityAssertEqualNumber((_U_SINT)(expected), (_U_SINT)(actual), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_UINT)
#define UNITY_TEST_ASSERT_EQUAL_UINT8(expected, actual, line, message) UnityAssertEqualNumber((_U_SINT)(_US8 )(expected), (_U_SINT)(_US8 )(actual), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_UINT)
#define UNITY_TEST_ASSERT_EQUAL_UINT16(expected, actual, line, message) UnityAssertEqualNumber((_U_SINT)(_US16)(expected), (_U_SINT)(_US16)(actual), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_UINT)
#define UNITY_TEST_ASSERT_EQUAL_UINT32(expected, actual, line, message) UnityAssertEqualNumber((_U_SINT)(_US32)(expected), (_U_SINT)(_US32)(actual), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_UINT)
#define UNITY_TEST_ASSERT_EQUAL_HEX8(expected, actual, line, message) UnityAssertEqualNumber((_U_SINT)(_US8 )(expected), (_U_SINT)(_US8 )(actual), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_HEX8)
#define UNITY_TEST_ASSERT_EQUAL_HEX16(expected, actual, line, message) UnityAssertEqualNumber((_U_SINT)(_US16)(expected), (_U_SINT)(_US16)(actual), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_HEX16)
#define UNITY_TEST_ASSERT_EQUAL_HEX32(expected, actual, line, message) UnityAssertEqualNumber((_U_SINT)(_US32)(expected), (_U_SINT)(_US32)(actual), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_HEX32)
#define UNITY_TEST_ASSERT_BITS(mask, expected, actual, line, message) UnityAssertBits((_U_SINT)(mask), (_U_SINT)(expected), (_U_SINT)(actual), (message), (UNITY_LINE_TYPE)line)
#define UNITY_TEST_ASSERT_INT_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((_U_SINT)(delta), (_U_SINT)(expected), (_U_SINT)(actual), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_INT)
#define UNITY_TEST_ASSERT_UINT_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((_U_SINT)(delta), (_U_SINT)(expected), (_U_SINT)(actual), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_UINT)
#define UNITY_TEST_ASSERT_HEX8_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((_U_SINT)(_U_UINT)(_UU8 )(delta), (_U_SINT)(_U_UINT)(_UU8 )(expected), (_U_SINT)(_U_UINT)(_UU8 )(actual), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_HEX8)
#define UNITY_TEST_ASSERT_HEX16_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((_U_SINT)(_U_UINT)(_UU16)(delta), (_U_SINT)(_U_UINT)(_UU16)(expected), (_U_SINT)(_U_UINT)(_UU16)(actual), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_HEX16)
#define UNITY_TEST_ASSERT_HEX32_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((_U_SINT)(_U_UINT)(_UU32)(delta), (_U_SINT)(_U_UINT)(_UU32)(expected), (_U_SINT)(_U_UINT)(_UU32)(actual), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_HEX32)
#define UNITY_TEST_ASSERT_EQUAL_PTR(expected, actual, line, message) UnityAssertEqualNumber((_U_SINT)(_UP)(expected), (_U_SINT)(_UP)(actual), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_POINTER)
#define UNITY_TEST_ASSERT_EQUAL_STRING(expected, actual, line, message) UnityAssertEqualString((const char*)(expected), (const char*)(actual), (message), (UNITY_LINE_TYPE)line)
#define UNITY_TEST_ASSERT_EQUAL_MEMORY(expected, actual, len, line, message) UnityAssertEqualMemory((void*)(expected), (void*)(actual), (_UU32)(len), 1, (message), (UNITY_LINE_TYPE)line)
#define UNITY_TEST_ASSERT_EQUAL_INT_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((const _U_SINT*)(expected), (const _U_SINT*)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_INT)
#define UNITY_TEST_ASSERT_EQUAL_INT8_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((const _U_SINT*)(expected), (const _U_SINT*)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_INT8)
#define UNITY_TEST_ASSERT_EQUAL_INT16_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((const _U_SINT*)(expected), (const _U_SINT*)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_INT16)
#define UNITY_TEST_ASSERT_EQUAL_INT32_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((const _U_SINT*)(expected), (const _U_SINT*)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_INT32)
#define UNITY_TEST_ASSERT_EQUAL_UINT_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((const _U_SINT*)(expected), (const _U_SINT*)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_UINT)
#define UNITY_TEST_ASSERT_EQUAL_UINT8_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((const _U_SINT*)(expected), (const _U_SINT*)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_UINT8)
#define UNITY_TEST_ASSERT_EQUAL_UINT16_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((const _U_SINT*)(expected), (const _U_SINT*)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_UINT16)
#define UNITY_TEST_ASSERT_EQUAL_UINT32_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((const _U_SINT*)(expected), (const _U_SINT*)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_UINT32)
#define UNITY_TEST_ASSERT_EQUAL_HEX8_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((const _U_SINT*)(expected), (const _U_SINT*)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_HEX8)
#define UNITY_TEST_ASSERT_EQUAL_HEX16_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((const _U_SINT*)(expected), (const _U_SINT*)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_HEX16)
#define UNITY_TEST_ASSERT_EQUAL_HEX32_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((const _U_SINT*)(expected), (const _U_SINT*)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_HEX32)
#define UNITY_TEST_ASSERT_EQUAL_PTR_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((const _U_SINT*)(_UP*)(expected), (const _U_SINT*)(_UP*)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_POINTER)
#define UNITY_TEST_ASSERT_EQUAL_STRING_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualStringArray((const char**)(expected), (const char**)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)line)
#define UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY(expected, actual, len, num_elements, line, message) UnityAssertEqualMemory((void*)(expected), (void*)(actual), (_UU32)(len), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)line)
#ifdef UNITY_SUPPORT_64
#define UNITY_TEST_ASSERT_EQUAL_INT64(expected, actual, line, message) UnityAssertEqualNumber((_U_SINT)(expected), (_U_SINT)(actual), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_INT64)
#define UNITY_TEST_ASSERT_EQUAL_UINT64(expected, actual, line, message) UnityAssertEqualNumber((_U_SINT)(expected), (_U_SINT)(actual), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_UINT64)
#define UNITY_TEST_ASSERT_EQUAL_HEX64(expected, actual, line, message) UnityAssertEqualNumber((_U_SINT)(expected), (_U_SINT)(actual), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_HEX64)
#define UNITY_TEST_ASSERT_EQUAL_INT64_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((const _U_SINT*)(expected), (const _U_SINT*)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_INT64)
#define UNITY_TEST_ASSERT_EQUAL_UINT64_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((const _U_SINT*)(expected), (const _U_SINT*)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_UINT64)
#define UNITY_TEST_ASSERT_EQUAL_HEX64_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((const _U_SINT*)(expected), (const _U_SINT*)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_HEX64)
#define UNITY_TEST_ASSERT_HEX64_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((_U_SINT)(delta), (_U_SINT)(expected), (_U_SINT)(actual), NULL, (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_HEX64)
#endif
#ifdef UNITY_EXCLUDE_FLOAT
#define UNITY_TEST_ASSERT_FLOAT_WITHIN(delta, expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)line, "Unity Floating Point Disabled")
#define UNITY_TEST_ASSERT_EQUAL_FLOAT(expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)line, "Unity Floating Point Disabled")
#define UNITY_TEST_ASSERT_EQUAL_FLOAT_ARRAY(expected, actual, num_elements, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)line, "Unity Floating Point Disabled")
#else
#define UNITY_TEST_ASSERT_FLOAT_WITHIN(delta, expected, actual, line, message) UnityAssertFloatsWithin((_UF)(delta), (_UF)(expected), (_UF)(actual), (message), (UNITY_LINE_TYPE)line)
#define UNITY_TEST_ASSERT_EQUAL_FLOAT(expected, actual, line, message) UNITY_TEST_ASSERT_FLOAT_WITHIN((_UF)(expected) * (_UF)UNITY_FLOAT_PRECISION, (_UF)expected, (_UF)actual, (UNITY_LINE_TYPE)line, message)
#define UNITY_TEST_ASSERT_EQUAL_FLOAT_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualFloatArray((_UF*)(expected), (_UF*)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)line)
#endif
#ifdef UNITY_EXCLUDE_DOUBLE
#define UNITY_TEST_ASSERT_DOUBLE_WITHIN(delta, expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)line, "Unity Double Precision Disabled")
#define UNITY_TEST_ASSERT_EQUAL_DOUBLE(expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)line, "Unity Double Precision Disabled")
#define UNITY_TEST_ASSERT_EQUAL_DOUBLE_ARRAY(expected, actual, num_elements, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)line, "Unity Double Precision Disabled")
#else
#define UNITY_TEST_ASSERT_DOUBLE_WITHIN(delta, expected, actual, line, message) UnityAssertDoublesWithin((_UD)(delta), (_UD)(expected), (_UD)(actual), (message), (UNITY_LINE_TYPE)line)
#define UNITY_TEST_ASSERT_EQUAL_DOUBLE(expected, actual, line, message) UNITY_TEST_ASSERT_DOUBLE_WITHIN((_UF)(expected) * (_UD)UNITY_DOUBLE_PRECISION, (_UD)expected, (_UD)actual, (UNITY_LINE_TYPE)line, message)
#define UNITY_TEST_ASSERT_EQUAL_DOUBLE_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualDoubleArray((_UD*)(expected), (_UD*)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)line)
#endif
#endif