From 3fa4de14be12887f4c4bcee3137324619c64624c Mon Sep 17 00:00:00 2001 From: Mark VanderVoord Date: Mon, 4 Jan 2016 19:27:48 -0500 Subject: [PATCH] -fix whitespace --- Rakefile | 212 ++-- lib/cmock_generator.rb | 470 ++++---- lib/cmock_generator_plugin_cexception.rb | 104 +- lib/cmock_generator_plugin_expect.rb | 176 +-- lib/cmock_generator_plugin_ignore.rb | 144 +-- lib/cmock_generator_utils.rb | 456 ++++---- src/cmock.c | 406 +++---- src/cmock.h | 76 +- targets/clang_strict.yml | 180 +-- targets/gcc.yml | 116 +- targets/gcc_64.yml | 116 +- targets/gcc_tiny.yml | 160 +-- targets/iar_arm_v4.yml | 220 ++-- targets/iar_arm_v5.yml | 190 +-- test/c/TestCMockC.c | 646 +++++------ test/unit/cmock_generator_main_test.rb | 1014 ++++++++--------- .../cmock_generator_plugin_cexception_test.rb | 192 ++-- .../cmock_generator_plugin_expect_test.rb | 420 +++---- .../cmock_generator_plugin_ignore_arg_test.rb | 232 ++-- .../cmock_generator_plugin_ignore_test.rb | 210 ++-- ...k_generator_plugin_return_thru_ptr_test.rb | 268 ++--- test/unit/cmock_generator_utils_test.rb | 754 ++++++------ 22 files changed, 3381 insertions(+), 3381 deletions(-) diff --git a/Rakefile b/Rakefile index 34ffdb5..bf7302c 100644 --- a/Rakefile +++ b/Rakefile @@ -1,106 +1,106 @@ -# ============================================================================== -# CMock Project - Automatic Mock Generation for C -# Copyright (c) 2007-2014 Mike Karlesky, Mark VanderVoord, Greg Williams -# [Released under MIT License. Please refer to license.txt for details] -# ============================================================================== - -require './config/test_environment' -require 'rake' -require 'rake/clean' -require 'rake/testtask' -require './rakefile_helper' - -include RakefileHelpers - -DEFAULT_CONFIG_FILE = 'gcc.yml' -CMOCK_ROOT = File.expand_path(File.dirname(__FILE__)) - -SYSTEM_TEST_SUPPORT_DIRS = [ - File.join(CMOCK_ROOT, 'test/system/generated'), - File.join(CMOCK_ROOT, 'test/system/build') -] - -SYSTEM_TEST_SUPPORT_DIRS.each do |dir| - directory(dir) - CLOBBER.include(dir) -end - - -task :prep_system_tests => SYSTEM_TEST_SUPPORT_DIRS - -configure_clean -configure_toolchain(DEFAULT_CONFIG_FILE) - -task :default => [:test] -task :ci => [:no_color, :default] -task :cruise => :ci - -desc "Load configuration" -task :config, :config_file do |t, args| - args = {:config_file => DEFAULT_CONFIG_FILE} if args[:config_file].nil? - args = {:config_file => args[:config_file] + '.yml'} unless args[:config_file] =~ /\.yml$/i - configure_toolchain(args[:config_file]) -end - -desc "Run all unit, c, and system tests" -task :test => [:clobber, :prep_system_tests, 'test:units', 'test:c', 'test:system'] - -namespace :test do - desc "Run Unit Tests" - Rake::TestTask.new('units') do |t| - t.pattern = 'test/unit/*_test.rb' - t.verbose = true - end - - #individual unit tests - FileList['test/unit/*_test.rb'].each do |test| - Rake::TestTask.new(File.basename(test,'.*').sub('_test','')) do |t| - t.pattern = test - t.verbose = true - end - end - - desc "Run C Unit Tests" - task :c => [:prep_system_tests] do - unless ($cfg['unsupported'].include? "C") - build_and_test_c_files - end - end - - desc "Run System Tests" - task :system => [:clobber, :prep_system_tests] do - #get a list of all system tests, removing unsupported tests for this compiler - sys_unsupported = $cfg['unsupported'].map {|a| 'test/system/test_interactions/'+a+'.yml'} - sys_tests_to_run = FileList['test/system/test_interactions/*.yml'] - sys_unsupported - compile_unsupported = $cfg['unsupported'].map {|a| SYSTEST_COMPILE_MOCKABLES_PATH+a+'.h'} - compile_tests_to_run = FileList[SYSTEST_COMPILE_MOCKABLES_PATH + '*.h'] - compile_unsupported - unless (sys_unsupported.empty? and compile_unsupported.empty?) - report "\nIgnoring these system tests..." - sys_unsupported.each {|a| report a} - compile_unsupported.each {|a| report a} - end - report "\nRunning system tests..." - tests_failed = run_system_test_interactions(sys_tests_to_run) - raise "System tests failed." if (tests_failed > 0) - - run_system_test_compilations(compile_tests_to_run) - end - - #individual system tests - FileList['test/system/test_interactions/*.yml'].each do |test| - basename = File.basename(test,'.*') - desc "Run system test #{basename}" - task basename do - run_system_test_interactions([test]) - end - end - - desc "Profile Mock Generation" - task :profile => [:clobber, :prep_system_tests] do - run_system_test_profiles(FileList[SYSTEST_COMPILE_MOCKABLES_PATH + '*.h']) - end -end - -task :no_color do - $colour_output = false -end +# ============================================================================== +# CMock Project - Automatic Mock Generation for C +# Copyright (c) 2007-2014 Mike Karlesky, Mark VanderVoord, Greg Williams +# [Released under MIT License. Please refer to license.txt for details] +# ============================================================================== + +require './config/test_environment' +require 'rake' +require 'rake/clean' +require 'rake/testtask' +require './rakefile_helper' + +include RakefileHelpers + +DEFAULT_CONFIG_FILE = 'gcc.yml' +CMOCK_ROOT = File.expand_path(File.dirname(__FILE__)) + +SYSTEM_TEST_SUPPORT_DIRS = [ + File.join(CMOCK_ROOT, 'test/system/generated'), + File.join(CMOCK_ROOT, 'test/system/build') +] + +SYSTEM_TEST_SUPPORT_DIRS.each do |dir| + directory(dir) + CLOBBER.include(dir) +end + + +task :prep_system_tests => SYSTEM_TEST_SUPPORT_DIRS + +configure_clean +configure_toolchain(DEFAULT_CONFIG_FILE) + +task :default => [:test] +task :ci => [:no_color, :default] +task :cruise => :ci + +desc "Load configuration" +task :config, :config_file do |t, args| + args = {:config_file => DEFAULT_CONFIG_FILE} if args[:config_file].nil? + args = {:config_file => args[:config_file] + '.yml'} unless args[:config_file] =~ /\.yml$/i + configure_toolchain(args[:config_file]) +end + +desc "Run all unit, c, and system tests" +task :test => [:clobber, :prep_system_tests, 'test:units', 'test:c', 'test:system'] + +namespace :test do + desc "Run Unit Tests" + Rake::TestTask.new('units') do |t| + t.pattern = 'test/unit/*_test.rb' + t.verbose = true + end + + #individual unit tests + FileList['test/unit/*_test.rb'].each do |test| + Rake::TestTask.new(File.basename(test,'.*').sub('_test','')) do |t| + t.pattern = test + t.verbose = true + end + end + + desc "Run C Unit Tests" + task :c => [:prep_system_tests] do + unless ($cfg['unsupported'].include? "C") + build_and_test_c_files + end + end + + desc "Run System Tests" + task :system => [:clobber, :prep_system_tests] do + #get a list of all system tests, removing unsupported tests for this compiler + sys_unsupported = $cfg['unsupported'].map {|a| 'test/system/test_interactions/'+a+'.yml'} + sys_tests_to_run = FileList['test/system/test_interactions/*.yml'] - sys_unsupported + compile_unsupported = $cfg['unsupported'].map {|a| SYSTEST_COMPILE_MOCKABLES_PATH+a+'.h'} + compile_tests_to_run = FileList[SYSTEST_COMPILE_MOCKABLES_PATH + '*.h'] - compile_unsupported + unless (sys_unsupported.empty? and compile_unsupported.empty?) + report "\nIgnoring these system tests..." + sys_unsupported.each {|a| report a} + compile_unsupported.each {|a| report a} + end + report "\nRunning system tests..." + tests_failed = run_system_test_interactions(sys_tests_to_run) + raise "System tests failed." if (tests_failed > 0) + + run_system_test_compilations(compile_tests_to_run) + end + + #individual system tests + FileList['test/system/test_interactions/*.yml'].each do |test| + basename = File.basename(test,'.*') + desc "Run system test #{basename}" + task basename do + run_system_test_interactions([test]) + end + end + + desc "Profile Mock Generation" + task :profile => [:clobber, :prep_system_tests] do + run_system_test_profiles(FileList[SYSTEST_COMPILE_MOCKABLES_PATH + '*.h']) + end +end + +task :no_color do + $colour_output = false +end diff --git a/lib/cmock_generator.rb b/lib/cmock_generator.rb index ad7220e..f2a1e13 100644 --- a/lib/cmock_generator.rb +++ b/lib/cmock_generator.rb @@ -1,235 +1,235 @@ -# ========================================== -# 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 CMockGenerator - - attr_accessor :config, :file_writer, :module_name, :clean_mock_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 - - @subdir = @config.subdir - - @includes_h_pre_orig_header = (@config.includes || @config.includes_h_pre_orig_header || []).map{|h| h =~ /\n" - file << "#include \n" - file << "#include \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" - strs = [] - functions.each do |func| - strs << func[:name] - func[:args].each {|arg| strs << arg[:name] } - end - strs.uniq.sort.each do |str| - file << "static const char* CMockString_#{str} = \"#{str}\";\n" - end - 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 #{@clean_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 #{@clean_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 #{@clean_mock_name}_Init(void)\n{\n" - file << " #{@clean_mock_name}_Destroy();\n" - file << "}\n\n" - end - - def create_mock_destroy_function(file, functions) - file << "void #{@clean_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 << " UNITY_SET_DETAIL(CMockString_#{function[:name]});\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, CMockStringCalledMore);\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, CMockStringCalledEarly);\n" - file << " if (cmock_call_instance->CallOrder < GlobalVerifyOrder)\n" - file << " UNITY_TEST_FAIL(cmock_line, CMockStringCalledLate);\n" - # file << " UNITY_TEST_ASSERT((cmock_call_instance->CallOrder == ++GlobalVerifyOrder), cmock_line, CMockStringCallOrder);\n" - end - return_type = function[:return][:const?] ? "(const #{function[:return][:type]})" : ((function[:return][:type] =~ /cmock/) ? "(#{function[:return][:type]})" : '') - file << @plugins.run(:mock_implementation, function) - file << " UNITY_CLR_DETAILS();\n" - file << " return #{return_type}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 +# ========================================== +# 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 CMockGenerator + + attr_accessor :config, :file_writer, :module_name, :clean_mock_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 + + @subdir = @config.subdir + + @includes_h_pre_orig_header = (@config.includes || @config.includes_h_pre_orig_header || []).map{|h| h =~ /\n" + file << "#include \n" + file << "#include \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" + strs = [] + functions.each do |func| + strs << func[:name] + func[:args].each {|arg| strs << arg[:name] } + end + strs.uniq.sort.each do |str| + file << "static const char* CMockString_#{str} = \"#{str}\";\n" + end + 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 #{@clean_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 #{@clean_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 #{@clean_mock_name}_Init(void)\n{\n" + file << " #{@clean_mock_name}_Destroy();\n" + file << "}\n\n" + end + + def create_mock_destroy_function(file, functions) + file << "void #{@clean_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 << " UNITY_SET_DETAIL(CMockString_#{function[:name]});\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, CMockStringCalledMore);\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, CMockStringCalledEarly);\n" + file << " if (cmock_call_instance->CallOrder < GlobalVerifyOrder)\n" + file << " UNITY_TEST_FAIL(cmock_line, CMockStringCalledLate);\n" + # file << " UNITY_TEST_ASSERT((cmock_call_instance->CallOrder == ++GlobalVerifyOrder), cmock_line, CMockStringCallOrder);\n" + end + return_type = function[:return][:const?] ? "(const #{function[:return][:type]})" : ((function[:return][:type] =~ /cmock/) ? "(#{function[:return][:type]})" : '') + file << @plugins.run(:mock_implementation, function) + file << " UNITY_CLR_DETAILS();\n" + file << " return #{return_type}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 diff --git a/lib/cmock_generator_plugin_cexception.rb b/lib/cmock_generator_plugin_cexception.rb index abd9059..7a1905a 100644 --- a/lib/cmock_generator_plugin_cexception.rb +++ b/lib/cmock_generator_plugin_cexception.rb @@ -1,52 +1,52 @@ -# ========================================== -# 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" + - " UNITY_CLR_DETAILS();\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 +# ========================================== +# 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" + + " UNITY_CLR_DETAILS();\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 diff --git a/lib/cmock_generator_plugin_expect.rb b/lib/cmock_generator_plugin_expect.rb index bfa506f..b0e3aa8 100644 --- a/lib/cmock_generator_plugin_expect.rb +++ b/lib/cmock_generator_plugin_expect.rb @@ -1,88 +1,88 @@ -# ========================================== -# 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 << " UNITY_CLR_DETAILS();\n" - lines << "}\n\n" - end - - def mock_verify(function) - func_name = function[:name] - " UNITY_SET_DETAIL(CMockString_#{function[:name]});\n" + - " UNITY_TEST_ASSERT(CMOCK_GUTS_NONE == Mock.#{func_name}_CallInstance, cmock_line, CMockStringCalledLess);\n" - end - -end +# ========================================== +# 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 << " UNITY_CLR_DETAILS();\n" + lines << "}\n\n" + end + + def mock_verify(function) + func_name = function[:name] + " UNITY_SET_DETAIL(CMockString_#{function[:name]});\n" + + " UNITY_TEST_ASSERT(CMOCK_GUTS_NONE == Mock.#{func_name}_CallInstance, cmock_line, CMockStringCalledLess);\n" + end + +end diff --git a/lib/cmock_generator_plugin_ignore.rb b/lib/cmock_generator_plugin_ignore.rb index 26ad90f..bf1bac2 100644 --- a/lib/cmock_generator_plugin_ignore.rb +++ b/lib/cmock_generator_plugin_ignore.rb @@ -1,72 +1,72 @@ -# ========================================== -# 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 - @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?]) - return "#define #{function[:name]}_Ignore() #{function[:name]}_CMockIgnore()\n" + - "void #{function[:name]}_CMockIgnore(void);\n" - 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_precheck(function) - lines = " if (Mock.#{function[:name]}_IgnoreBool)\n {\n" - lines << " UNITY_CLR_DETAILS();\n" - if (function[:return][:void?]) - lines << " return;\n }\n" - else - retval = function[:return].merge( { :name => "cmock_call_instance->ReturnVal"} ) - return_type = function[:return][:const?] ? "(const #{function[:return][:type]})" : ((function[:return][:type] =~ /cmock/) ? "(#{function[:return][:type]})" : '') - lines << " if (cmock_call_instance == NULL)\n return #{return_type}Mock.#{function[:name]}_FinalReturn;\n" - lines << " " + @utils.code_assign_argument_quickly("Mock.#{function[:name]}_FinalReturn", retval) unless (retval[:void?]) - lines << " return #{return_type}cmock_call_instance->ReturnVal;\n }\n" - end - lines - end - - def mock_interfaces(function) - lines = "" - if (function[:return][:void?]) - lines << "void #{function[:name]}_CMockIgnore(void)\n{\n" - else - lines << "void #{function[:name]}_CMockIgnoreAndReturn(UNITY_LINE_TYPE cmock_line, #{function[:return][:str]})\n{\n" - end - if (!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_verify(function) - func_name = function[:name] - " if (Mock.#{func_name}_IgnoreBool)\n Mock.#{func_name}_CallInstance = CMOCK_GUTS_NONE;\n" - end -end +# ========================================== +# 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 + @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?]) + return "#define #{function[:name]}_Ignore() #{function[:name]}_CMockIgnore()\n" + + "void #{function[:name]}_CMockIgnore(void);\n" + 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_precheck(function) + lines = " if (Mock.#{function[:name]}_IgnoreBool)\n {\n" + lines << " UNITY_CLR_DETAILS();\n" + if (function[:return][:void?]) + lines << " return;\n }\n" + else + retval = function[:return].merge( { :name => "cmock_call_instance->ReturnVal"} ) + return_type = function[:return][:const?] ? "(const #{function[:return][:type]})" : ((function[:return][:type] =~ /cmock/) ? "(#{function[:return][:type]})" : '') + lines << " if (cmock_call_instance == NULL)\n return #{return_type}Mock.#{function[:name]}_FinalReturn;\n" + lines << " " + @utils.code_assign_argument_quickly("Mock.#{function[:name]}_FinalReturn", retval) unless (retval[:void?]) + lines << " return #{return_type}cmock_call_instance->ReturnVal;\n }\n" + end + lines + end + + def mock_interfaces(function) + lines = "" + if (function[:return][:void?]) + lines << "void #{function[:name]}_CMockIgnore(void)\n{\n" + else + lines << "void #{function[:name]}_CMockIgnoreAndReturn(UNITY_LINE_TYPE cmock_line, #{function[:return][:str]})\n{\n" + end + if (!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_verify(function) + func_name = function[:name] + " if (Mock.#{func_name}_IgnoreBool)\n Mock.#{func_name}_CallInstance = CMOCK_GUTS_NONE;\n" + end +end diff --git a/lib/cmock_generator_utils.rb b/lib/cmock_generator_utils.rb index 8ad43b6..86729b6 100644 --- a/lib/cmock_generator_utils.rb +++ b/lib/cmock_generator_utils.rb @@ -1,228 +1,228 @@ -# ========================================== -# 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 - @expect_any = @config.plugins.include? :expect_any_args - @return_thru_ptr = @config.plugins.include? :return_thru_ptr - @ignore_arg = @config.plugins.include? :ignore_arg - @ignore = @config.plugins.include? :ignore - @treat_as = @config.treat_as - @helpers = helpers - end - - def code_verify_an_arg_expectation(function, arg) - if (@arrays) - case(@ptr_handling) - when :smart then code_verify_an_arg_expectation_with_smart_arrays(function, arg) - when :compare_data then code_verify_an_arg_expectation_with_normal_arrays(function, arg) - when :compare_ptr then raise "ERROR: the array plugin doesn't enjoy working with :compare_ptr only. Disable one option." - end - else - code_verify_an_arg_expectation_with_no_arrays(function, arg) - 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, CMockStringOutOfMemory);\n" - lines << " memset(cmock_call_instance, 0, sizeof(*cmock_call_instance));\n" - lines << " Mock.#{func_name}_CallInstance = CMock_Guts_MemChain(Mock.#{func_name}_CallInstance, cmock_guts_index);\n" - lines << " Mock.#{func_name}_IgnoreBool = (int)0;\n" if (@ignore) - 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 << " cmock_call_instance->IgnoreMode = CMOCK_ARG_ALL;\n" if (@expect_any) - 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 << " cmock_call_instance->IgnoreArg_#{arg[:name]} = 0;\n" if (@ignore_arg) - lines << " cmock_call_instance->ReturnThruPtr_#{arg[:name]}_Used = 0;\n" if (@return_thru_ptr and ptr_or_str?(arg[:type]) and not arg[:const?]) - lines - end - - 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 - - def ptr_or_str?(arg_type) - return (arg_type.include? '*' or - @treat_as.fetch(arg_type, "").include? '*') - end - - #private ###################### - - def lookup_expect_type(function, arg) - c_type = arg[:type] - arg_name = arg[:name] - expected = "cmock_call_instance->Expected_#{arg_name}" - ignore = "cmock_call_instance->IgnoreArg_#{arg_name}" - unity_func = if ((arg[:ptr?]) and ((c_type =~ /\*\*/) or (@ptr_handling == :compare_ptr))) - ['UNITY_TEST_ASSERT_EQUAL_PTR', ''] - else - (@helpers.nil? or @helpers[:unity_helper].nil?) ? ["UNITY_TEST_ASSERT_EQUAL",''] : @helpers[:unity_helper].get_helper(c_type) - end - unity_msg = "Function '#{function[:name]}' called with unexpected value for argument '#{arg_name}'." - return c_type, arg_name, expected, ignore, unity_func[0], unity_func[1], unity_msg - end - - def code_verify_an_arg_expectation_with_no_arrays(function, arg) - c_type, arg_name, expected, ignore, unity_func, pre, unity_msg = lookup_expect_type(function, arg) - lines = "" - lines << " if (!#{ignore})\n" if @ignore_arg - lines << " {\n" - lines << " UNITY_SET_DETAILS(CMockString_#{function[:name]},CMockString_#{arg_name});\n" - case(unity_func) - when "UNITY_TEST_ASSERT_EQUAL_MEMORY" - c_type_local = c_type.gsub(/\*$/,'') - lines << " UNITY_TEST_ASSERT_EQUAL_MEMORY((void*)(#{pre}#{expected}), (void*)(#{pre}#{arg_name}), sizeof(#{c_type_local}), cmock_line, CMockStringMismatch);\n" - when "UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY" - if (pre == '&') - lines << " UNITY_TEST_ASSERT_EQUAL_MEMORY((void*)(#{pre}#{expected}), (void*)(#{pre}#{arg_name}), sizeof(#{c_type.sub('*','')}), cmock_line, CMockStringMismatch);\n" - else - lines << " if (#{pre}#{expected} == NULL)\n" - lines << " { UNITY_TEST_ASSERT_NULL(#{pre}#{arg_name}, cmock_line, CMockStringExpNULL); }\n" - lines << " else\n" - lines << " { UNITY_TEST_ASSERT_EQUAL_MEMORY((void*)(#{pre}#{expected}), (void*)(#{pre}#{arg_name}), sizeof(#{c_type.sub('*','')}), cmock_line, CMockStringMismatch); }\n" - end - when /_ARRAY/ - if (pre == '&') - lines << " #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, 1, cmock_line, CMockStringMismatch);\n" - else - lines << " if (#{pre}#{expected} == NULL)\n" - lines << " { UNITY_TEST_ASSERT_NULL(#{pre}#{arg_name}, cmock_line, CMockStringExpNULL); }\n" - lines << " else\n" - lines << " { #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, 1, cmock_line, CMockStringMismatch); }\n" - end - else - lines << " #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, cmock_line, CMockStringMismatch);\n" - end - lines << " }\n" - lines - end - - def code_verify_an_arg_expectation_with_normal_arrays(function, arg) - c_type, arg_name, expected, ignore, unity_func, pre, unity_msg = lookup_expect_type(function, arg) - depth_name = (arg[:ptr?]) ? "cmock_call_instance->Expected_#{arg_name}_Depth" : 1 - lines = "" - lines << " if (!#{ignore})\n" if @ignore_arg - lines << " {\n" - lines << " UNITY_SET_DETAILS(CMockString_#{function[:name]},CMockString_#{arg_name});\n" - case(unity_func) - when "UNITY_TEST_ASSERT_EQUAL_MEMORY" - c_type_local = c_type.gsub(/\*$/,'') - lines << " UNITY_TEST_ASSERT_EQUAL_MEMORY((void*)(#{pre}#{expected}), (void*)(#{pre}#{arg_name}), sizeof(#{c_type_local}), cmock_line, CMockStringMismatch);\n" - when "UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY" - if (pre == '&') - lines << " UNITY_TEST_ASSERT_EQUAL_MEMORY((void*)(#{pre}#{expected}), (void*)(#{pre}#{arg_name}), sizeof(#{c_type.sub('*','')}), cmock_line, CMockStringMismatch);\n" - else - lines << " if (#{pre}#{expected} == NULL)\n" - lines << " { UNITY_TEST_ASSERT_NULL(#{pre}#{arg_name}, cmock_line, CMockStringExpNULL); }\n" - lines << " else\n" - lines << " { UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY((void*)(#{pre}#{expected}), (void*)(#{pre}#{arg_name}), sizeof(#{c_type.sub('*','')}), #{depth_name}, cmock_line, CMockStringMismatch); }\n" - end - when /_ARRAY/ - if (pre == '&') - lines << " #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, #{depth_name}, cmock_line, CMockStringMismatch);\n" - else - lines << " if (#{pre}#{expected} == NULL)\n" - lines << " { UNITY_TEST_ASSERT_NULL(#{pre}#{arg_name}, cmock_line, CMockStringExpNULL); }\n" - lines << " else\n" - lines << " { #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, #{depth_name}, cmock_line, CMockStringMismatch); }\n" - end - else - lines << " #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, cmock_line, CMockStringMismatch);\n" - end - lines << " }\n" - lines - end - - def code_verify_an_arg_expectation_with_smart_arrays(function, arg) - c_type, arg_name, expected, ignore, unity_func, pre, unity_msg = lookup_expect_type(function, arg) - depth_name = (arg[:ptr?]) ? "cmock_call_instance->Expected_#{arg_name}_Depth" : 1 - lines = "" - lines << " if (!#{ignore})\n" if @ignore_arg - lines << " {\n" - lines << " UNITY_SET_DETAILS(CMockString_#{function[:name]},CMockString_#{arg_name});\n" - case(unity_func) - when "UNITY_TEST_ASSERT_EQUAL_MEMORY" - c_type_local = c_type.gsub(/\*$/,'') - lines << " UNITY_TEST_ASSERT_EQUAL_MEMORY((void*)(#{pre}#{expected}), (void*)(#{pre}#{arg_name}), sizeof(#{c_type_local}), cmock_line, CMockStringMismatch);\n" - when "UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY" - if (pre == '&') - lines << " UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY((void*)(#{pre}#{expected}), (void*)(#{pre}#{arg_name}), sizeof(#{c_type.sub('*','')}), #{depth_name}, cmock_line, CMockStringMismatch);\n" - else - lines << " if (#{pre}#{expected} == NULL)\n" - lines << " { UNITY_TEST_ASSERT_NULL(#{arg_name}, cmock_line, CMockStringExpNULL); }\n" - lines << ((depth_name != 1) ? " else if (#{depth_name} == 0)\n { UNITY_TEST_ASSERT_EQUAL_PTR(#{pre}#{expected}, #{pre}#{arg_name}, cmock_line, CMockStringMismatch); }\n" : "") - lines << " else\n" - lines << " { UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY((void*)(#{pre}#{expected}), (void*)(#{pre}#{arg_name}), sizeof(#{c_type.sub('*','')}), #{depth_name}, cmock_line, CMockStringMismatch); }\n" - end - when /_ARRAY/ - if (pre == '&') - lines << " #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, #{depth_name}, cmock_line, CMockStringMismatch);\n" - else - lines << " if (#{pre}#{expected} == NULL)\n" - lines << " { UNITY_TEST_ASSERT_NULL(#{pre}#{arg_name}, cmock_line, CMockStringExpNULL); }\n" - lines << ((depth_name != 1) ? " else if (#{depth_name} == 0)\n { UNITY_TEST_ASSERT_EQUAL_PTR(#{pre}#{expected}, #{pre}#{arg_name}, cmock_line, CMockStringMismatch); }\n" : "") - lines << " else\n" - lines << " { #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, #{depth_name}, cmock_line, CMockStringMismatch); }\n" - end - else - lines << " #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, cmock_line, CMockStringMismatch);\n" - end - lines << " }\n" - lines - end - -end +# ========================================== +# 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 + @expect_any = @config.plugins.include? :expect_any_args + @return_thru_ptr = @config.plugins.include? :return_thru_ptr + @ignore_arg = @config.plugins.include? :ignore_arg + @ignore = @config.plugins.include? :ignore + @treat_as = @config.treat_as + @helpers = helpers + end + + def code_verify_an_arg_expectation(function, arg) + if (@arrays) + case(@ptr_handling) + when :smart then code_verify_an_arg_expectation_with_smart_arrays(function, arg) + when :compare_data then code_verify_an_arg_expectation_with_normal_arrays(function, arg) + when :compare_ptr then raise "ERROR: the array plugin doesn't enjoy working with :compare_ptr only. Disable one option." + end + else + code_verify_an_arg_expectation_with_no_arrays(function, arg) + 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, CMockStringOutOfMemory);\n" + lines << " memset(cmock_call_instance, 0, sizeof(*cmock_call_instance));\n" + lines << " Mock.#{func_name}_CallInstance = CMock_Guts_MemChain(Mock.#{func_name}_CallInstance, cmock_guts_index);\n" + lines << " Mock.#{func_name}_IgnoreBool = (int)0;\n" if (@ignore) + 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 << " cmock_call_instance->IgnoreMode = CMOCK_ARG_ALL;\n" if (@expect_any) + 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 << " cmock_call_instance->IgnoreArg_#{arg[:name]} = 0;\n" if (@ignore_arg) + lines << " cmock_call_instance->ReturnThruPtr_#{arg[:name]}_Used = 0;\n" if (@return_thru_ptr and ptr_or_str?(arg[:type]) and not arg[:const?]) + lines + end + + 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 + + def ptr_or_str?(arg_type) + return (arg_type.include? '*' or + @treat_as.fetch(arg_type, "").include? '*') + end + + #private ###################### + + def lookup_expect_type(function, arg) + c_type = arg[:type] + arg_name = arg[:name] + expected = "cmock_call_instance->Expected_#{arg_name}" + ignore = "cmock_call_instance->IgnoreArg_#{arg_name}" + unity_func = if ((arg[:ptr?]) and ((c_type =~ /\*\*/) or (@ptr_handling == :compare_ptr))) + ['UNITY_TEST_ASSERT_EQUAL_PTR', ''] + else + (@helpers.nil? or @helpers[:unity_helper].nil?) ? ["UNITY_TEST_ASSERT_EQUAL",''] : @helpers[:unity_helper].get_helper(c_type) + end + unity_msg = "Function '#{function[:name]}' called with unexpected value for argument '#{arg_name}'." + return c_type, arg_name, expected, ignore, unity_func[0], unity_func[1], unity_msg + end + + def code_verify_an_arg_expectation_with_no_arrays(function, arg) + c_type, arg_name, expected, ignore, unity_func, pre, unity_msg = lookup_expect_type(function, arg) + lines = "" + lines << " if (!#{ignore})\n" if @ignore_arg + lines << " {\n" + lines << " UNITY_SET_DETAILS(CMockString_#{function[:name]},CMockString_#{arg_name});\n" + case(unity_func) + when "UNITY_TEST_ASSERT_EQUAL_MEMORY" + c_type_local = c_type.gsub(/\*$/,'') + lines << " UNITY_TEST_ASSERT_EQUAL_MEMORY((void*)(#{pre}#{expected}), (void*)(#{pre}#{arg_name}), sizeof(#{c_type_local}), cmock_line, CMockStringMismatch);\n" + when "UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY" + if (pre == '&') + lines << " UNITY_TEST_ASSERT_EQUAL_MEMORY((void*)(#{pre}#{expected}), (void*)(#{pre}#{arg_name}), sizeof(#{c_type.sub('*','')}), cmock_line, CMockStringMismatch);\n" + else + lines << " if (#{pre}#{expected} == NULL)\n" + lines << " { UNITY_TEST_ASSERT_NULL(#{pre}#{arg_name}, cmock_line, CMockStringExpNULL); }\n" + lines << " else\n" + lines << " { UNITY_TEST_ASSERT_EQUAL_MEMORY((void*)(#{pre}#{expected}), (void*)(#{pre}#{arg_name}), sizeof(#{c_type.sub('*','')}), cmock_line, CMockStringMismatch); }\n" + end + when /_ARRAY/ + if (pre == '&') + lines << " #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, 1, cmock_line, CMockStringMismatch);\n" + else + lines << " if (#{pre}#{expected} == NULL)\n" + lines << " { UNITY_TEST_ASSERT_NULL(#{pre}#{arg_name}, cmock_line, CMockStringExpNULL); }\n" + lines << " else\n" + lines << " { #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, 1, cmock_line, CMockStringMismatch); }\n" + end + else + lines << " #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, cmock_line, CMockStringMismatch);\n" + end + lines << " }\n" + lines + end + + def code_verify_an_arg_expectation_with_normal_arrays(function, arg) + c_type, arg_name, expected, ignore, unity_func, pre, unity_msg = lookup_expect_type(function, arg) + depth_name = (arg[:ptr?]) ? "cmock_call_instance->Expected_#{arg_name}_Depth" : 1 + lines = "" + lines << " if (!#{ignore})\n" if @ignore_arg + lines << " {\n" + lines << " UNITY_SET_DETAILS(CMockString_#{function[:name]},CMockString_#{arg_name});\n" + case(unity_func) + when "UNITY_TEST_ASSERT_EQUAL_MEMORY" + c_type_local = c_type.gsub(/\*$/,'') + lines << " UNITY_TEST_ASSERT_EQUAL_MEMORY((void*)(#{pre}#{expected}), (void*)(#{pre}#{arg_name}), sizeof(#{c_type_local}), cmock_line, CMockStringMismatch);\n" + when "UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY" + if (pre == '&') + lines << " UNITY_TEST_ASSERT_EQUAL_MEMORY((void*)(#{pre}#{expected}), (void*)(#{pre}#{arg_name}), sizeof(#{c_type.sub('*','')}), cmock_line, CMockStringMismatch);\n" + else + lines << " if (#{pre}#{expected} == NULL)\n" + lines << " { UNITY_TEST_ASSERT_NULL(#{pre}#{arg_name}, cmock_line, CMockStringExpNULL); }\n" + lines << " else\n" + lines << " { UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY((void*)(#{pre}#{expected}), (void*)(#{pre}#{arg_name}), sizeof(#{c_type.sub('*','')}), #{depth_name}, cmock_line, CMockStringMismatch); }\n" + end + when /_ARRAY/ + if (pre == '&') + lines << " #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, #{depth_name}, cmock_line, CMockStringMismatch);\n" + else + lines << " if (#{pre}#{expected} == NULL)\n" + lines << " { UNITY_TEST_ASSERT_NULL(#{pre}#{arg_name}, cmock_line, CMockStringExpNULL); }\n" + lines << " else\n" + lines << " { #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, #{depth_name}, cmock_line, CMockStringMismatch); }\n" + end + else + lines << " #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, cmock_line, CMockStringMismatch);\n" + end + lines << " }\n" + lines + end + + def code_verify_an_arg_expectation_with_smart_arrays(function, arg) + c_type, arg_name, expected, ignore, unity_func, pre, unity_msg = lookup_expect_type(function, arg) + depth_name = (arg[:ptr?]) ? "cmock_call_instance->Expected_#{arg_name}_Depth" : 1 + lines = "" + lines << " if (!#{ignore})\n" if @ignore_arg + lines << " {\n" + lines << " UNITY_SET_DETAILS(CMockString_#{function[:name]},CMockString_#{arg_name});\n" + case(unity_func) + when "UNITY_TEST_ASSERT_EQUAL_MEMORY" + c_type_local = c_type.gsub(/\*$/,'') + lines << " UNITY_TEST_ASSERT_EQUAL_MEMORY((void*)(#{pre}#{expected}), (void*)(#{pre}#{arg_name}), sizeof(#{c_type_local}), cmock_line, CMockStringMismatch);\n" + when "UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY" + if (pre == '&') + lines << " UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY((void*)(#{pre}#{expected}), (void*)(#{pre}#{arg_name}), sizeof(#{c_type.sub('*','')}), #{depth_name}, cmock_line, CMockStringMismatch);\n" + else + lines << " if (#{pre}#{expected} == NULL)\n" + lines << " { UNITY_TEST_ASSERT_NULL(#{arg_name}, cmock_line, CMockStringExpNULL); }\n" + lines << ((depth_name != 1) ? " else if (#{depth_name} == 0)\n { UNITY_TEST_ASSERT_EQUAL_PTR(#{pre}#{expected}, #{pre}#{arg_name}, cmock_line, CMockStringMismatch); }\n" : "") + lines << " else\n" + lines << " { UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY((void*)(#{pre}#{expected}), (void*)(#{pre}#{arg_name}), sizeof(#{c_type.sub('*','')}), #{depth_name}, cmock_line, CMockStringMismatch); }\n" + end + when /_ARRAY/ + if (pre == '&') + lines << " #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, #{depth_name}, cmock_line, CMockStringMismatch);\n" + else + lines << " if (#{pre}#{expected} == NULL)\n" + lines << " { UNITY_TEST_ASSERT_NULL(#{pre}#{arg_name}, cmock_line, CMockStringExpNULL); }\n" + lines << ((depth_name != 1) ? " else if (#{depth_name} == 0)\n { UNITY_TEST_ASSERT_EQUAL_PTR(#{pre}#{expected}, #{pre}#{arg_name}, cmock_line, CMockStringMismatch); }\n" : "") + lines << " else\n" + lines << " { #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, #{depth_name}, cmock_line, CMockStringMismatch); }\n" + end + else + lines << " #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, cmock_line, CMockStringMismatch);\n" + end + lines << " }\n" + lines + end + +end diff --git a/src/cmock.c b/src/cmock.c index ba8a8bd..b2d85f5 100644 --- a/src/cmock.c +++ b/src/cmock.c @@ -1,203 +1,203 @@ -/* ========================================== - 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" - -//public constants to be used by mocks -const char* CMockStringOutOfMemory = "CMock has run out of memory. Please allocate more."; -const char* CMockStringCalledMore = "Called more times than expected."; -const char* CMockStringCalledLess = "Called less times than expected."; -const char* CMockStringCalledEarly = "Called earlier than expected."; -const char* CMockStringCalledLate = "Called later than expected."; -const char* CMockStringCallOrder = "Called out of order."; -const char* CMockStringIgnPreExp = "IgnoreArg called before Expect."; -const char* CMockStringPtrPreExp = "ReturnThruPtr called before Expect."; -const char* CMockStringExpNULL = "Expected NULL."; -const char* CMockStringMismatch = "Function called with unexpected argument value."; - -//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, (size_t)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_INDEX_TYPE)((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_Guts_MemEndOfChain -//------------------------------------------------------- -CMOCK_MEM_INDEX_TYPE CMock_Guts_MemEndOfChain(CMOCK_MEM_INDEX_TYPE root_index) -{ - CMOCK_MEM_INDEX_TYPE index = root_index; - CMOCK_MEM_INDEX_TYPE next_index; - - for (next_index = root_index; - next_index != CMOCK_GUTS_NONE; - next_index = CMock_Guts_MemNext(index)) - { - index = next_index; - } - - return index; -} - -//------------------------------------------------------- -// CMock_GetAddressFor -//------------------------------------------------------- -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 -} - -//------------------------------------------------------- -// CMock_Guts_MemFreeFinal -//------------------------------------------------------- -void CMock_Guts_MemFreeFinal(void) -{ - CMock_Guts_FreePtr = CMOCK_MEM_ALIGN_SIZE; -#ifdef CMOCK_MEM_DYNAMIC - if (CMock_Guts_Buffer) - { - free(CMock_Guts_Buffer); - CMock_Guts_Buffer = NULL; - } -#endif -} - +/* ========================================== + 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" + +//public constants to be used by mocks +const char* CMockStringOutOfMemory = "CMock has run out of memory. Please allocate more."; +const char* CMockStringCalledMore = "Called more times than expected."; +const char* CMockStringCalledLess = "Called less times than expected."; +const char* CMockStringCalledEarly = "Called earlier than expected."; +const char* CMockStringCalledLate = "Called later than expected."; +const char* CMockStringCallOrder = "Called out of order."; +const char* CMockStringIgnPreExp = "IgnoreArg called before Expect."; +const char* CMockStringPtrPreExp = "ReturnThruPtr called before Expect."; +const char* CMockStringExpNULL = "Expected NULL."; +const char* CMockStringMismatch = "Function called with unexpected argument value."; + +//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, (size_t)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_INDEX_TYPE)((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_Guts_MemEndOfChain +//------------------------------------------------------- +CMOCK_MEM_INDEX_TYPE CMock_Guts_MemEndOfChain(CMOCK_MEM_INDEX_TYPE root_index) +{ + CMOCK_MEM_INDEX_TYPE index = root_index; + CMOCK_MEM_INDEX_TYPE next_index; + + for (next_index = root_index; + next_index != CMOCK_GUTS_NONE; + next_index = CMock_Guts_MemNext(index)) + { + index = next_index; + } + + return index; +} + +//------------------------------------------------------- +// CMock_GetAddressFor +//------------------------------------------------------- +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 +} + +//------------------------------------------------------- +// CMock_Guts_MemFreeFinal +//------------------------------------------------------- +void CMock_Guts_MemFreeFinal(void) +{ + CMock_Guts_FreePtr = CMOCK_MEM_ALIGN_SIZE; +#ifdef CMOCK_MEM_DYNAMIC + if (CMock_Guts_Buffer) + { + free(CMock_Guts_Buffer); + CMock_Guts_Buffer = NULL; + } +#endif +} + diff --git a/src/cmock.h b/src/cmock.h index af960a3..d566375 100644 --- a/src/cmock.h +++ b/src/cmock.h @@ -1,38 +1,38 @@ -/* ========================================== - 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 - -#include "cmock_internals.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) - -#define CMOCK_ARG_MODE CMOCK_MEM_INDEX_TYPE -#define CMOCK_ARG_ALL 0 -#define CMOCK_ARG_NONE ((CMOCK_MEM_INDEX_TYPE)(~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); -CMOCK_MEM_INDEX_TYPE CMock_Guts_MemEndOfChain(CMOCK_MEM_INDEX_TYPE root_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); -void CMock_Guts_MemFreeFinal(void); - -#endif //CMOCK_FRAMEWORK +/* ========================================== + 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 + +#include "cmock_internals.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) + +#define CMOCK_ARG_MODE CMOCK_MEM_INDEX_TYPE +#define CMOCK_ARG_ALL 0 +#define CMOCK_ARG_NONE ((CMOCK_MEM_INDEX_TYPE)(~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); +CMOCK_MEM_INDEX_TYPE CMock_Guts_MemEndOfChain(CMOCK_MEM_INDEX_TYPE root_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); +void CMock_Guts_MemFreeFinal(void); + +#endif //CMOCK_FRAMEWORK diff --git a/targets/clang_strict.yml b/targets/clang_strict.yml index b552694..2438f96 100644 --- a/targets/clang_strict.yml +++ b/targets/clang_strict.yml @@ -1,90 +1,90 @@ ---- -compiler: - path: clang - source_path: &systest_generated_path 'test/system/generated/' - unit_tests_path: &unit_tests_path 'examples/test/' - mocks_path: &systest_mocks_path 'test/system/generated/' - build_path: &systest_build_path 'test/system/build/' - options: - - '-c' - - '-Wall' - - '-Wextra' - - '-Werror' - - '-Wcast-qual' - - '-Wconversion' - - '-Wtautological-compare' - #- '-Wtautological-pointer-compare' - - '-Wdisabled-optimization' - - '-Wformat=2' - - '-Winit-self' - - '-Winline' - - '-Winvalid-pch' - - '-Wmissing-declarations' - - '-Wmissing-include-dirs' - - '-Wmissing-prototypes' - - '-Wnonnull' - - '-Wpacked' - - '-Wpointer-arith' - - '-Wredundant-decls' - - '-Wswitch-default' - - '-Wstrict-aliasing=2' - - '-Wstrict-overflow=5' - - '-Wuninitialized' - - '-Wunused' - - '-Wunreachable-code' - - '-Wreturn-type' - - '-Wshadow' - - '-Wundef' - - '-Wwrite-strings' - - '-Wbad-function-cast' - - '-Wno-missing-prototypes' #we've been lazy about things like setUp and tearDown - - '-Wno-invalid-token-paste' - - '-fms-extensions' - - '-fno-omit-frame-pointer' - - '-ffloat-store' - - '-fno-common' - - '-fstrict-aliasing' - - '-std=gnu99' - - '-pedantic' - - '-O0' - includes: - prefix: '-I' - items: - - *systest_generated_path - - *unit_tests_path - - *systest_mocks_path - - 'src/' - - 'vendor/unity/src/' - - 'vendor/c_exception/lib/' - - 'test/system/test_compilation/' - - 'test/' - defines: - prefix: '-D' - items: - - CMOCK - - 'UNITY_SUPPORT_64' - - 'UNITY_POINTER_WIDTH=64' - object_files: - prefix: '-o' - extension: '.o' - destination: *systest_build_path - -linker: - path: gcc - options: - - -lm - includes: - prefix: '-I' - object_files: - path: *systest_build_path - extension: '.o' - bin_files: - prefix: '-o' - extension: '.exe' - destination: *systest_build_path - -unsupported: - - out_of_memory - - callingconv - -colour: true +--- +compiler: + path: clang + source_path: &systest_generated_path 'test/system/generated/' + unit_tests_path: &unit_tests_path 'examples/test/' + mocks_path: &systest_mocks_path 'test/system/generated/' + build_path: &systest_build_path 'test/system/build/' + options: + - '-c' + - '-Wall' + - '-Wextra' + - '-Werror' + - '-Wcast-qual' + - '-Wconversion' + - '-Wtautological-compare' + #- '-Wtautological-pointer-compare' + - '-Wdisabled-optimization' + - '-Wformat=2' + - '-Winit-self' + - '-Winline' + - '-Winvalid-pch' + - '-Wmissing-declarations' + - '-Wmissing-include-dirs' + - '-Wmissing-prototypes' + - '-Wnonnull' + - '-Wpacked' + - '-Wpointer-arith' + - '-Wredundant-decls' + - '-Wswitch-default' + - '-Wstrict-aliasing=2' + - '-Wstrict-overflow=5' + - '-Wuninitialized' + - '-Wunused' + - '-Wunreachable-code' + - '-Wreturn-type' + - '-Wshadow' + - '-Wundef' + - '-Wwrite-strings' + - '-Wbad-function-cast' + - '-Wno-missing-prototypes' #we've been lazy about things like setUp and tearDown + - '-Wno-invalid-token-paste' + - '-fms-extensions' + - '-fno-omit-frame-pointer' + - '-ffloat-store' + - '-fno-common' + - '-fstrict-aliasing' + - '-std=gnu99' + - '-pedantic' + - '-O0' + includes: + prefix: '-I' + items: + - *systest_generated_path + - *unit_tests_path + - *systest_mocks_path + - 'src/' + - 'vendor/unity/src/' + - 'vendor/c_exception/lib/' + - 'test/system/test_compilation/' + - 'test/' + defines: + prefix: '-D' + items: + - CMOCK + - 'UNITY_SUPPORT_64' + - 'UNITY_POINTER_WIDTH=64' + object_files: + prefix: '-o' + extension: '.o' + destination: *systest_build_path + +linker: + path: gcc + options: + - -lm + includes: + prefix: '-I' + object_files: + path: *systest_build_path + extension: '.o' + bin_files: + prefix: '-o' + extension: '.exe' + destination: *systest_build_path + +unsupported: + - out_of_memory + - callingconv + +colour: true diff --git a/targets/gcc.yml b/targets/gcc.yml index 13fff4c..0ce91bd 100644 --- a/targets/gcc.yml +++ b/targets/gcc.yml @@ -1,58 +1,58 @@ ---- -compiler: - path: gcc - source_path: &systest_generated_path 'test/system/generated/' - unit_tests_path: &unit_tests_path 'examples/test/' - mocks_path: &systest_mocks_path 'test/system/generated/' - build_path: &systest_build_path 'test/system/build/' - options: - - '-c' - - '-Wall' - - '-Wextra' - - '-Wunused-parameter' - - '-Wno-address' - - '-Wno-invalid-token-paste' - - '-std=c99' - - '-pedantic' - - '-O0' - includes: - prefix: '-I' - items: - - *systest_generated_path - - *unit_tests_path - - *systest_mocks_path - - 'src/' - - 'vendor/unity/src/' - - 'vendor/c_exception/lib/' - - 'test/system/test_compilation/' - - 'test/' - defines: - prefix: '-D' - items: - - CMOCK - - 'UNITY_SUPPORT_64' - object_files: - prefix: '-o' - extension: '.o' - destination: *systest_build_path - -linker: - path: gcc - options: - - -lm - includes: - prefix: '-I' - object_files: - path: *systest_build_path - extension: '.o' - bin_files: - prefix: '-o' - extension: '.exe' - destination: *systest_build_path - -unsupported: - - out_of_memory - - unity_64bit_support - - callingconv - -colour: true +--- +compiler: + path: gcc + source_path: &systest_generated_path 'test/system/generated/' + unit_tests_path: &unit_tests_path 'examples/test/' + mocks_path: &systest_mocks_path 'test/system/generated/' + build_path: &systest_build_path 'test/system/build/' + options: + - '-c' + - '-Wall' + - '-Wextra' + - '-Wunused-parameter' + - '-Wno-address' + - '-Wno-invalid-token-paste' + - '-std=c99' + - '-pedantic' + - '-O0' + includes: + prefix: '-I' + items: + - *systest_generated_path + - *unit_tests_path + - *systest_mocks_path + - 'src/' + - 'vendor/unity/src/' + - 'vendor/c_exception/lib/' + - 'test/system/test_compilation/' + - 'test/' + defines: + prefix: '-D' + items: + - CMOCK + - 'UNITY_SUPPORT_64' + object_files: + prefix: '-o' + extension: '.o' + destination: *systest_build_path + +linker: + path: gcc + options: + - -lm + includes: + prefix: '-I' + object_files: + path: *systest_build_path + extension: '.o' + bin_files: + prefix: '-o' + extension: '.exe' + destination: *systest_build_path + +unsupported: + - out_of_memory + - unity_64bit_support + - callingconv + +colour: true diff --git a/targets/gcc_64.yml b/targets/gcc_64.yml index 354b9e9..22ec016 100644 --- a/targets/gcc_64.yml +++ b/targets/gcc_64.yml @@ -1,58 +1,58 @@ ---- -compiler: - path: gcc - source_path: &systest_generated_path 'test/system/generated/' - unit_tests_path: &unit_tests_path 'examples/test/' - mocks_path: &systest_mocks_path 'test/system/generated/' - build_path: &systest_build_path 'test/system/build/' - options: - - '-c' - - '-m64' - - '-Wall' - - '-Wunused-parameter' - - '-Wno-address' - - '-Wno-invalid-token-paste' - - '-std=c99' - - '-pedantic' - includes: - prefix: '-I' - items: - - *systest_generated_path - - *unit_tests_path - - *systest_mocks_path - - 'src/' - - 'vendor/unity/src/' - - 'vendor/c_exception/lib/' - - 'test/system/test_compilation/' - - 'test/' - defines: - prefix: '-D' - items: - - CMOCK - - 'UNITY_SUPPORT_64' - - 'UNITY_POINTER_WIDTH=64' - object_files: - prefix: '-o' - extension: '.o' - destination: *systest_build_path - -linker: - path: gcc - options: - - -lm - - '-m64' - includes: - prefix: '-I' - object_files: - path: *systest_build_path - extension: '.o' - bin_files: - prefix: '-o' - extension: '.exe' - destination: *systest_build_path - -unsupported: - - out_of_memory - - callingconv - -colour: true +--- +compiler: + path: gcc + source_path: &systest_generated_path 'test/system/generated/' + unit_tests_path: &unit_tests_path 'examples/test/' + mocks_path: &systest_mocks_path 'test/system/generated/' + build_path: &systest_build_path 'test/system/build/' + options: + - '-c' + - '-m64' + - '-Wall' + - '-Wunused-parameter' + - '-Wno-address' + - '-Wno-invalid-token-paste' + - '-std=c99' + - '-pedantic' + includes: + prefix: '-I' + items: + - *systest_generated_path + - *unit_tests_path + - *systest_mocks_path + - 'src/' + - 'vendor/unity/src/' + - 'vendor/c_exception/lib/' + - 'test/system/test_compilation/' + - 'test/' + defines: + prefix: '-D' + items: + - CMOCK + - 'UNITY_SUPPORT_64' + - 'UNITY_POINTER_WIDTH=64' + object_files: + prefix: '-o' + extension: '.o' + destination: *systest_build_path + +linker: + path: gcc + options: + - -lm + - '-m64' + includes: + prefix: '-I' + object_files: + path: *systest_build_path + extension: '.o' + bin_files: + prefix: '-o' + extension: '.exe' + destination: *systest_build_path + +unsupported: + - out_of_memory + - callingconv + +colour: true diff --git a/targets/gcc_tiny.yml b/targets/gcc_tiny.yml index 7965349..20343fb 100644 --- a/targets/gcc_tiny.yml +++ b/targets/gcc_tiny.yml @@ -1,80 +1,80 @@ ---- -compiler: - path: gcc - source_path: &systest_generated_path 'test/system/generated/' - unit_tests_path: &unit_tests_path 'examples/test/' - mocks_path: &systest_mocks_path 'test/system/generated/' - build_path: &systest_build_path 'test/system/build/' - options: - - '-c' - - '-Wall' - - '-Wextra' - - '-Wunused-parameter' - - '-Wno-address' - - '-Wno-invalid-token-paste' - - '-std=c99' - - '-pedantic' - - '-O0' - includes: - prefix: '-I' - items: - - *systest_generated_path - - *unit_tests_path - - *systest_mocks_path - - 'src/' - - 'vendor/unity/src/' - - 'vendor/c_exception/lib/' - - 'test/system/test_compilation/' - - 'test/' - defines: - prefix: '-D' - items: - - CMOCK - - 'CMOCK_MEM_STATIC' - - 'CMOCK_MEM_SIZE=1024' - object_files: - prefix: '-o' - extension: '.o' - destination: *systest_build_path - -linker: - path: gcc - options: - - -lm - includes: - prefix: '-I' - object_files: - path: *systest_build_path - extension: '.o' - bin_files: - prefix: '-o' - extension: '.exe' - destination: *systest_build_path - -unsupported: - - all_plugins_but_other_limits - - all_plugins_coexist - - array_and_pointer_handling - - const_primitives_handling - - enforce_strict_ordering - - expect_and_return_custom_types - - expect_and_return_treat_as - - expect_and_throw - - expect_any_args - - fancy_pointer_handling - - function_pointer_handling - - newer_standards_stuff1 - - nonstandard_pased_stuff_1 - - nonstandard_pased_stuff_2 - - parsing_challenges - - return_thru_ptr_and_expect_any_args - - return_thru_ptr_ignore_arg - - struct_union_enum_expect_and_return - - struct_union_enum_expect_and_return_with_plugins - - stubs_with_callbacks - - unity_64bit_support - - unity_ignores - - callingconv - - C - -colour: true +--- +compiler: + path: gcc + source_path: &systest_generated_path 'test/system/generated/' + unit_tests_path: &unit_tests_path 'examples/test/' + mocks_path: &systest_mocks_path 'test/system/generated/' + build_path: &systest_build_path 'test/system/build/' + options: + - '-c' + - '-Wall' + - '-Wextra' + - '-Wunused-parameter' + - '-Wno-address' + - '-Wno-invalid-token-paste' + - '-std=c99' + - '-pedantic' + - '-O0' + includes: + prefix: '-I' + items: + - *systest_generated_path + - *unit_tests_path + - *systest_mocks_path + - 'src/' + - 'vendor/unity/src/' + - 'vendor/c_exception/lib/' + - 'test/system/test_compilation/' + - 'test/' + defines: + prefix: '-D' + items: + - CMOCK + - 'CMOCK_MEM_STATIC' + - 'CMOCK_MEM_SIZE=1024' + object_files: + prefix: '-o' + extension: '.o' + destination: *systest_build_path + +linker: + path: gcc + options: + - -lm + includes: + prefix: '-I' + object_files: + path: *systest_build_path + extension: '.o' + bin_files: + prefix: '-o' + extension: '.exe' + destination: *systest_build_path + +unsupported: + - all_plugins_but_other_limits + - all_plugins_coexist + - array_and_pointer_handling + - const_primitives_handling + - enforce_strict_ordering + - expect_and_return_custom_types + - expect_and_return_treat_as + - expect_and_throw + - expect_any_args + - fancy_pointer_handling + - function_pointer_handling + - newer_standards_stuff1 + - nonstandard_pased_stuff_1 + - nonstandard_pased_stuff_2 + - parsing_challenges + - return_thru_ptr_and_expect_any_args + - return_thru_ptr_ignore_arg + - struct_union_enum_expect_and_return + - struct_union_enum_expect_and_return_with_plugins + - stubs_with_callbacks + - unity_64bit_support + - unity_ignores + - callingconv + - C + +colour: true diff --git a/targets/iar_arm_v4.yml b/targets/iar_arm_v4.yml index dae46b9..b645522 100644 --- a/targets/iar_arm_v4.yml +++ b/targets/iar_arm_v4.yml @@ -1,110 +1,110 @@ -tools_root: &tools_root 'C:\Program Files\IAR Systems\Embedded Workbench 4.0\' -compiler: - path: [*tools_root, 'arm\bin\iccarm.exe'] - source_path: &systest_generated_path 'test/system/generated/' - unit_tests_path: &unit_tests_path 'examples/test/' - mocks_path: &systest_mocks_path 'test/system/generated/' - build_path: &systest_build_path 'test/system/build/' - options: - - --dlib_config - - [*tools_root, 'arm\lib\dl4tptinl8n.h'] - - -z3 - - --no_cse - - --no_unroll - - --no_inline - - --no_code_motion - - --no_tbaa - - --no_clustering - - --no_scheduling - - --debug - - --cpu_mode thumb - - --endian little - - --cpu ARM7TDMI - - --stack_align 4 - - --interwork - - -e - - --silent - - --warnings_are_errors - - --fpu None - #We are supressing some warnings here because we test CMock against some questionable code to make sure it still works - - --diag_suppress Pa050 - - --diag_suppress Pe191 - - --diag_suppress=Pe494 - - --diag_suppress=Pe083 - includes: - prefix: '-I' - items: - - [*tools_root, 'arm\inc\'] - - *systest_generated_path - - *unit_tests_path - - *systest_mocks_path - - 'src/' - - 'vendor/unity/src/' - - 'vendor/c_exception/lib/' - - 'test/system/test_compilation/' - - 'test\' - defines: - prefix: '-D' - items: - - CMOCK - object_files: - prefix: '-o' - extension: '.r79' - destination: *systest_build_path - -linker: - path: [*tools_root, 'common\bin\xlink.exe'] - options: - - -rt - - [*tools_root, 'arm\lib\dl4tptinl8n.r79'] - - -D_L_EXTMEM_START=0 - - -D_L_EXTMEM_SIZE=0 - - -D_L_HEAP_SIZE=120 - - -D_L_STACK_SIZE=32 - - -e_small_write=_formatted_write - - -s - - __program_start - - '-f iar\iar_v4\Resource\at91SAM7X256_FLASH.xcl' - includes: - prefix: '-I' - items: - - *systest_generated_path - - *unit_tests_path - - *systest_mocks_path - - 'vendor/unity/src/' - - [*tools_root, 'arm\config\'] - - [*tools_root, 'arm\lib\'] - object_files: - path: *systest_build_path - extension: '.r79' - bin_files: - prefix: '-o' - extension: '.d79' - destination: *systest_build_path - -simulator: - path: [*tools_root, 'common\bin\CSpyBat.exe'] - pre_support: - - --silent - - [*tools_root, 'arm\bin\armproc.dll'] - - [*tools_root, 'arm\bin\armsim.dll'] - post_support: - - --plugin - - [*tools_root, 'arm\bin\armbat.dll'] - - --macro - - 'iar\iar_v4\Resource\SAM7_SIM.mac' - - --backend - - -B - - -p - - [*tools_root, 'arm\config\ioat91sam7X256.ddf'] - - -d - - sim - -unsupported: - - out_of_memory - - nonstandard_parsed_stuff_1 - - const - - callingconv - - unity_64bit_support - -colour: true +tools_root: &tools_root 'C:\Program Files\IAR Systems\Embedded Workbench 4.0\' +compiler: + path: [*tools_root, 'arm\bin\iccarm.exe'] + source_path: &systest_generated_path 'test/system/generated/' + unit_tests_path: &unit_tests_path 'examples/test/' + mocks_path: &systest_mocks_path 'test/system/generated/' + build_path: &systest_build_path 'test/system/build/' + options: + - --dlib_config + - [*tools_root, 'arm\lib\dl4tptinl8n.h'] + - -z3 + - --no_cse + - --no_unroll + - --no_inline + - --no_code_motion + - --no_tbaa + - --no_clustering + - --no_scheduling + - --debug + - --cpu_mode thumb + - --endian little + - --cpu ARM7TDMI + - --stack_align 4 + - --interwork + - -e + - --silent + - --warnings_are_errors + - --fpu None + #We are supressing some warnings here because we test CMock against some questionable code to make sure it still works + - --diag_suppress Pa050 + - --diag_suppress Pe191 + - --diag_suppress=Pe494 + - --diag_suppress=Pe083 + includes: + prefix: '-I' + items: + - [*tools_root, 'arm\inc\'] + - *systest_generated_path + - *unit_tests_path + - *systest_mocks_path + - 'src/' + - 'vendor/unity/src/' + - 'vendor/c_exception/lib/' + - 'test/system/test_compilation/' + - 'test\' + defines: + prefix: '-D' + items: + - CMOCK + object_files: + prefix: '-o' + extension: '.r79' + destination: *systest_build_path + +linker: + path: [*tools_root, 'common\bin\xlink.exe'] + options: + - -rt + - [*tools_root, 'arm\lib\dl4tptinl8n.r79'] + - -D_L_EXTMEM_START=0 + - -D_L_EXTMEM_SIZE=0 + - -D_L_HEAP_SIZE=120 + - -D_L_STACK_SIZE=32 + - -e_small_write=_formatted_write + - -s + - __program_start + - '-f iar\iar_v4\Resource\at91SAM7X256_FLASH.xcl' + includes: + prefix: '-I' + items: + - *systest_generated_path + - *unit_tests_path + - *systest_mocks_path + - 'vendor/unity/src/' + - [*tools_root, 'arm\config\'] + - [*tools_root, 'arm\lib\'] + object_files: + path: *systest_build_path + extension: '.r79' + bin_files: + prefix: '-o' + extension: '.d79' + destination: *systest_build_path + +simulator: + path: [*tools_root, 'common\bin\CSpyBat.exe'] + pre_support: + - --silent + - [*tools_root, 'arm\bin\armproc.dll'] + - [*tools_root, 'arm\bin\armsim.dll'] + post_support: + - --plugin + - [*tools_root, 'arm\bin\armbat.dll'] + - --macro + - 'iar\iar_v4\Resource\SAM7_SIM.mac' + - --backend + - -B + - -p + - [*tools_root, 'arm\config\ioat91sam7X256.ddf'] + - -d + - sim + +unsupported: + - out_of_memory + - nonstandard_parsed_stuff_1 + - const + - callingconv + - unity_64bit_support + +colour: true diff --git a/targets/iar_arm_v5.yml b/targets/iar_arm_v5.yml index 886faff..137f31a 100644 --- a/targets/iar_arm_v5.yml +++ b/targets/iar_arm_v5.yml @@ -1,95 +1,95 @@ -tools_root: &tools_root 'C:\Program Files\IAR Systems\Embedded Workbench 5.3\' -compiler: - path: [*tools_root, 'arm\bin\iccarm.exe'] - source_path: &systest_generated_path 'test/system/generated/' - unit_tests_path: &unit_tests_path 'examples/test/' - mocks_path: &systest_mocks_path 'test/system/generated/' - build_path: &systest_build_path 'test/system/build/' - options: - - --dlib_config - - [*tools_root, 'arm\inc\DLib_Config_Normal.h'] - - --no_cse - - --no_unroll - - --no_inline - - --no_code_motion - - --no_tbaa - - --no_clustering - - --no_scheduling - - --debug - - --cpu_mode thumb - - --endian=little - - --cpu=ARM7TDMI - - --interwork - - --warnings_are_errors - - --fpu=None - - -e - - -On - #We are supressing some warnings here because we test CMock against some questionable code to make sure it still works - - --diag_suppress=Pa050 - - --diag_suppress=Pe191 - - --diag_suppress=Pe494 - - --diag_suppress=Pe083 - includes: - prefix: '-I' - items: - - [*tools_root, 'arm\inc\'] - - *systest_generated_path - - *unit_tests_path - - *systest_mocks_path - - 'src/' - - 'vendor/unity/src/' - - 'vendor/c_exception/lib/' - - 'iar\iar_v5\incIAR\' - - 'test\system\test_compilation\' - - 'test\' - defines: - prefix: '-D' - items: - - CMOCK - object_files: - prefix: '-o' - extension: '.r79' - destination: *systest_build_path - -linker: - path: [*tools_root, 'arm\bin\ilinkarm.exe'] - options: - - --redirect _Printf=_PrintfLarge - - --redirect _Scanf=_ScanfSmall - - --semihosting - - --entry __iar_program_start - - --config iar\iar_v5\Resource\at91SAM7X256_RAM.icf - object_files: - path: *systest_build_path - extension: '.o' - bin_files: - prefix: '-o' - extension: '.out' - destination: *systest_build_path - -simulator: - path: [*tools_root, 'common\bin\CSpyBat.exe'] - pre_support: - - --silent - - [*tools_root, 'arm\bin\armproc.dll'] - - [*tools_root, 'arm\bin\armsim.dll'] - post_support: - - --plugin - - [*tools_root, 'arm\bin\armbat.dll'] - - --macro - - 'iar\iar_v5\Resource\SAM7_SIM.mac' - - --backend - - -B - - -p - - [*tools_root, 'arm\config\debugger\Atmel\ioat91sam7X256.ddf'] - - -d - - sim - -unsupported: - - out_of_memory - - nonstandard_parsed_stuff_1 - - const - - callingconv - - unity_64bit_support - -colour: true +tools_root: &tools_root 'C:\Program Files\IAR Systems\Embedded Workbench 5.3\' +compiler: + path: [*tools_root, 'arm\bin\iccarm.exe'] + source_path: &systest_generated_path 'test/system/generated/' + unit_tests_path: &unit_tests_path 'examples/test/' + mocks_path: &systest_mocks_path 'test/system/generated/' + build_path: &systest_build_path 'test/system/build/' + options: + - --dlib_config + - [*tools_root, 'arm\inc\DLib_Config_Normal.h'] + - --no_cse + - --no_unroll + - --no_inline + - --no_code_motion + - --no_tbaa + - --no_clustering + - --no_scheduling + - --debug + - --cpu_mode thumb + - --endian=little + - --cpu=ARM7TDMI + - --interwork + - --warnings_are_errors + - --fpu=None + - -e + - -On + #We are supressing some warnings here because we test CMock against some questionable code to make sure it still works + - --diag_suppress=Pa050 + - --diag_suppress=Pe191 + - --diag_suppress=Pe494 + - --diag_suppress=Pe083 + includes: + prefix: '-I' + items: + - [*tools_root, 'arm\inc\'] + - *systest_generated_path + - *unit_tests_path + - *systest_mocks_path + - 'src/' + - 'vendor/unity/src/' + - 'vendor/c_exception/lib/' + - 'iar\iar_v5\incIAR\' + - 'test\system\test_compilation\' + - 'test\' + defines: + prefix: '-D' + items: + - CMOCK + object_files: + prefix: '-o' + extension: '.r79' + destination: *systest_build_path + +linker: + path: [*tools_root, 'arm\bin\ilinkarm.exe'] + options: + - --redirect _Printf=_PrintfLarge + - --redirect _Scanf=_ScanfSmall + - --semihosting + - --entry __iar_program_start + - --config iar\iar_v5\Resource\at91SAM7X256_RAM.icf + object_files: + path: *systest_build_path + extension: '.o' + bin_files: + prefix: '-o' + extension: '.out' + destination: *systest_build_path + +simulator: + path: [*tools_root, 'common\bin\CSpyBat.exe'] + pre_support: + - --silent + - [*tools_root, 'arm\bin\armproc.dll'] + - [*tools_root, 'arm\bin\armsim.dll'] + post_support: + - --plugin + - [*tools_root, 'arm\bin\armbat.dll'] + - --macro + - 'iar\iar_v5\Resource\SAM7_SIM.mac' + - --backend + - -B + - -p + - [*tools_root, 'arm\config\debugger\Atmel\ioat91sam7X256.ddf'] + - -d + - sim + +unsupported: + - out_of_memory + - nonstandard_parsed_stuff_1 + - const + - callingconv + - unity_64bit_support + +colour: true diff --git a/test/c/TestCMockC.c b/test/c/TestCMockC.c index 385c177..782b3bc 100644 --- a/test/c/TestCMockC.c +++ b/test/c/TestCMockC.c @@ -1,323 +1,323 @@ -/* ========================================== - 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 TEST_MEM_INDEX_SIZE (sizeof(CMOCK_MEM_INDEX_TYPE)) - -void setUp(void) -{ - CMock_Guts_MemFreeAll(); -} - -void tearDown(void) -{ -} - -void test_MemNewWillReturnNullIfGivenIllegalSizes(void) -{ - TEST_ASSERT_EQUAL_HEX( CMOCK_GUTS_NONE, CMock_Guts_MemNew(0) ); - TEST_ASSERT_EQUAL_HEX( CMOCK_GUTS_NONE, CMock_Guts_MemNew(CMOCK_MEM_SIZE - TEST_MEM_INDEX_SIZE + 1) ); - TEST_ASSERT_NULL( CMock_Guts_GetAddressFor(CMOCK_GUTS_NONE) ); - - //verify we're cleared still - TEST_ASSERT_EQUAL(0, CMock_Guts_MemBytesUsed()); - TEST_ASSERT_EQUAL(CMOCK_MEM_SIZE, CMock_Guts_MemBytesFree()); -} - -void test_MemChainWillReturnNullAndDoNothingIfGivenIllegalInformation(void) -{ - CMOCK_MEM_INDEX_TYPE next = CMock_Guts_MemNew(4); - TEST_ASSERT_EQUAL(4 + TEST_MEM_INDEX_SIZE, CMock_Guts_MemBytesUsed()); - TEST_ASSERT_EQUAL(CMOCK_MEM_SIZE - 4 - TEST_MEM_INDEX_SIZE, CMock_Guts_MemBytesFree()); - - TEST_ASSERT_EQUAL_HEX( CMOCK_GUTS_NONE, CMock_Guts_MemChain(next + CMOCK_MEM_SIZE, next) ); - TEST_ASSERT_EQUAL_HEX( CMOCK_GUTS_NONE, CMock_Guts_MemChain(next, next + CMOCK_MEM_SIZE) ); - - //verify we're still the same - TEST_ASSERT_EQUAL(4 + TEST_MEM_INDEX_SIZE, CMock_Guts_MemBytesUsed()); - TEST_ASSERT_EQUAL(CMOCK_MEM_SIZE - 4 - TEST_MEM_INDEX_SIZE, CMock_Guts_MemBytesFree()); -} - -void test_MemNextWillReturnNullIfGivenABadRoot(void) -{ - TEST_ASSERT_EQUAL_HEX( CMOCK_GUTS_NONE, CMock_Guts_MemNext(0) ); - TEST_ASSERT_EQUAL_HEX( CMOCK_GUTS_NONE, CMock_Guts_MemNext(2) ); - TEST_ASSERT_EQUAL_HEX( CMOCK_GUTS_NONE, CMock_Guts_MemNext(CMOCK_MEM_SIZE - 4) ); - - //verify we're cleared still - TEST_ASSERT_EQUAL(0, CMock_Guts_MemBytesUsed()); - TEST_ASSERT_EQUAL(CMOCK_MEM_SIZE, CMock_Guts_MemBytesFree()); -} - -void test_ThatWeCanClaimAndChainAFewElementsTogether(void) -{ - unsigned int i; - CMOCK_MEM_INDEX_TYPE next; - CMOCK_MEM_INDEX_TYPE first = CMOCK_GUTS_NONE; - CMOCK_MEM_INDEX_TYPE element[4]; - - //verify we're cleared first - TEST_ASSERT_EQUAL(0, CMock_Guts_MemBytesUsed()); - TEST_ASSERT_EQUAL(CMOCK_MEM_SIZE, CMock_Guts_MemBytesFree()); - - //first element - element[0] = CMock_Guts_MemNew(sizeof(unsigned int)); - TEST_ASSERT_MESSAGE(element[0] != CMOCK_GUTS_NONE, "Should Not Have Returned CMOCK_GUTS_NONE"); - first = CMock_Guts_MemChain(first, element[0]); - TEST_ASSERT_EQUAL(element[0], first); - *((unsigned int*)CMock_Guts_GetAddressFor(element[0])) = 0; - - //verify we're using the right amount of memory - TEST_ASSERT_EQUAL(1 * (TEST_MEM_INDEX_SIZE + sizeof(unsigned int)), CMock_Guts_MemBytesUsed()); - TEST_ASSERT_EQUAL(CMOCK_MEM_SIZE - 1 * (TEST_MEM_INDEX_SIZE + sizeof(unsigned int)), CMock_Guts_MemBytesFree()); - - //second element - element[1] = CMock_Guts_MemNew(sizeof(unsigned int)); - TEST_ASSERT_MESSAGE(element[1] != CMOCK_GUTS_NONE, "Should Not Have Returned CMOCK_GUTS_NONE"); - TEST_ASSERT_NOT_EQUAL(element[0], element[1]); - TEST_ASSERT_EQUAL(first, CMock_Guts_MemChain(first, element[1])); - *((unsigned int*)CMock_Guts_GetAddressFor(element[1])) = 1; - - //verify we're using the right amount of memory - TEST_ASSERT_EQUAL(2 * (TEST_MEM_INDEX_SIZE + sizeof(unsigned int)), CMock_Guts_MemBytesUsed()); - TEST_ASSERT_EQUAL(CMOCK_MEM_SIZE - 2 * (TEST_MEM_INDEX_SIZE + sizeof(unsigned int)), CMock_Guts_MemBytesFree()); - - //third element - element[2] = CMock_Guts_MemNew(sizeof(unsigned int)); - TEST_ASSERT_MESSAGE(element[2] != CMOCK_GUTS_NONE, "Should Not Have Returned CMOCK_GUTS_NONE"); - TEST_ASSERT_NOT_EQUAL(element[0], element[2]); - TEST_ASSERT_NOT_EQUAL(element[1], element[2]); - TEST_ASSERT_EQUAL(first, CMock_Guts_MemChain(first, element[2])); - *((unsigned int*)CMock_Guts_GetAddressFor(element[2])) = 2; - - //verify we're using the right amount of memory - TEST_ASSERT_EQUAL(3 * (TEST_MEM_INDEX_SIZE + sizeof(unsigned int)), CMock_Guts_MemBytesUsed()); - TEST_ASSERT_EQUAL(CMOCK_MEM_SIZE - 3 * (TEST_MEM_INDEX_SIZE + sizeof(unsigned int)), CMock_Guts_MemBytesFree()); - - //fourth element - element[3] = CMock_Guts_MemNew(sizeof(unsigned int)); - TEST_ASSERT_MESSAGE(element[3] != CMOCK_GUTS_NONE, "Should Not Have Returned CMOCK_GUTS_NONE"); - TEST_ASSERT_NOT_EQUAL(element[0], element[3]); - TEST_ASSERT_NOT_EQUAL(element[1], element[3]); - TEST_ASSERT_NOT_EQUAL(element[2], element[3]); - TEST_ASSERT_EQUAL(first, CMock_Guts_MemChain(first, element[3])); - *((unsigned int*)CMock_Guts_GetAddressFor(element[3])) = 3; - - //verify we're using the right amount of memory - TEST_ASSERT_EQUAL(4 * (TEST_MEM_INDEX_SIZE + sizeof(unsigned int)), CMock_Guts_MemBytesUsed()); - TEST_ASSERT_EQUAL(CMOCK_MEM_SIZE - 4 * (TEST_MEM_INDEX_SIZE + sizeof(unsigned int)), CMock_Guts_MemBytesFree()); - - //traverse list - next = first; - for (i = 0; i < 4; i++) - { - TEST_ASSERT_EQUAL(element[i], next); - TEST_ASSERT_EQUAL(i, *((unsigned int*)CMock_Guts_GetAddressFor(element[i]))); - next = CMock_Guts_MemNext(next); - } - - //verify we get a null at the end of the list - TEST_ASSERT_EQUAL_HEX(CMOCK_GUTS_NONE, next); - - //verify we're using the right amount of memory - TEST_ASSERT_EQUAL(4 * (TEST_MEM_INDEX_SIZE + sizeof(unsigned int)), CMock_Guts_MemBytesUsed()); - TEST_ASSERT_EQUAL(CMOCK_MEM_SIZE - 4 * (TEST_MEM_INDEX_SIZE + sizeof(unsigned int)), CMock_Guts_MemBytesFree()); - - //Free it all - CMock_Guts_MemFreeAll(); - - //verify we're cleared - TEST_ASSERT_EQUAL(0, CMock_Guts_MemBytesUsed()); - TEST_ASSERT_EQUAL(CMOCK_MEM_SIZE, CMock_Guts_MemBytesFree()); -} - -void test_ThatCMockStopsReturningMoreDataWhenItRunsOutOfMemory(void) -{ - unsigned int i; - CMOCK_MEM_INDEX_TYPE first = CMOCK_GUTS_NONE; - CMOCK_MEM_INDEX_TYPE next; - - //even though we are asking for one byte, we've told it to align to closest CMOCK_MEM_ALIGN_SIZE bytes, therefore it will waste a byte each time - //so each call will use (CMOCK_MEM_INDEX_SIZE + CMOCK_MEM_ALIGN_SIZE) bytes (CMOCK_MEM_INDEX_SIZE for the index, 1 for the data, and (CMOCK_MEM_ALIGN_SIZE - 1) wasted). - //therefore we can safely allocated total/(CMOCK_MEM_INDEX_SIZE + CMOCK_MEM_ALIGN_SIZE) times. - for (i = 0; i < (CMOCK_MEM_SIZE / (CMOCK_MEM_INDEX_SIZE + CMOCK_MEM_ALIGN_SIZE)); i++) - { - TEST_ASSERT_EQUAL(i*(CMOCK_MEM_INDEX_SIZE + CMOCK_MEM_ALIGN_SIZE), CMock_Guts_MemBytesUsed()); - TEST_ASSERT_EQUAL(CMOCK_MEM_SIZE - i*(CMOCK_MEM_INDEX_SIZE + CMOCK_MEM_ALIGN_SIZE), CMock_Guts_MemBytesFree()); - - next = CMock_Guts_MemNew(1); - TEST_ASSERT_MESSAGE(next != CMOCK_GUTS_NONE, "Should Not Have Returned CMOCK_GUTS_NONE"); - - first = CMock_Guts_MemChain(first, next); - TEST_ASSERT_MESSAGE(first != CMOCK_GUTS_NONE, "Should Not Have Returned CMOCK_GUTS_NONE"); - } - - //verify we're at top of memory - TEST_ASSERT_EQUAL(CMOCK_MEM_SIZE, CMock_Guts_MemBytesUsed()); - TEST_ASSERT_EQUAL(0, CMock_Guts_MemBytesFree()); - - //The very next call will return a NULL, and any after that - TEST_ASSERT_EQUAL_HEX(CMOCK_GUTS_NONE, CMock_Guts_MemNew(1)); - TEST_ASSERT_EQUAL_HEX(CMOCK_GUTS_NONE, CMock_Guts_MemNew(1)); - TEST_ASSERT_EQUAL_HEX(CMOCK_GUTS_NONE, CMock_Guts_MemNew(1)); - - //verify nothing has changed - TEST_ASSERT_EQUAL(CMOCK_MEM_SIZE, CMock_Guts_MemBytesUsed()); - TEST_ASSERT_EQUAL(0, CMock_Guts_MemBytesFree()); - - //verify we can still walk through the elements allocated - next = first; - for (i = 0; i < (CMOCK_MEM_SIZE / (CMOCK_MEM_INDEX_SIZE + CMOCK_MEM_ALIGN_SIZE)); i++) - { - TEST_ASSERT_MESSAGE(next != CMOCK_GUTS_NONE, "Should Not Have Returned CMOCK_GUTS_NONE"); - next = CMock_Guts_MemNext(next); - } - - //there aren't any after that - TEST_ASSERT_EQUAL_HEX(CMOCK_GUTS_NONE, (_UU32)next); -} - -void test_ThatCMockStopsReturningMoreDataWhenAskForMoreThanItHasLeftEvenIfNotAtExactEnd(void) -{ - unsigned int i; - CMOCK_MEM_INDEX_TYPE first = CMOCK_GUTS_NONE; - CMOCK_MEM_INDEX_TYPE next; - - //we're asking for (CMOCK_MEM_INDEX_SIZE + 8) bytes each time now (CMOCK_MEM_INDEX_SIZE for index, 8 for data). - //CMOCK_MEM_SIZE/(CMOCK_MEM_INDEX_SIZE + 8) requests will request as much data as possible, while ensuring that there isn't enough - //memory for the next request - for (i = 0; i < CMOCK_MEM_SIZE/(CMOCK_MEM_INDEX_SIZE + 8); i++) - { - TEST_ASSERT_EQUAL(i*(CMOCK_MEM_INDEX_SIZE + 8), CMock_Guts_MemBytesUsed()); - TEST_ASSERT_EQUAL(CMOCK_MEM_SIZE - i*(CMOCK_MEM_INDEX_SIZE + 8), CMock_Guts_MemBytesFree()); - - next = CMock_Guts_MemNew(8); - TEST_ASSERT_MESSAGE(next != CMOCK_GUTS_NONE, "Should Not Have Returned CMOCK_GUTS_NONE"); - - first = CMock_Guts_MemChain(first, next); - TEST_ASSERT_MESSAGE(first != CMOCK_GUTS_NONE, "Should Not Have Returned CMOCK_GUTS_NONE"); - - //verify writing data won't screw us up - *((unsigned int*)CMock_Guts_GetAddressFor(next)) = i; - } - - //verify we're at top of memory - TEST_ASSERT_EQUAL(CMOCK_MEM_SIZE - CMOCK_MEM_SIZE % (CMOCK_MEM_INDEX_SIZE + 8), CMock_Guts_MemBytesUsed()); - TEST_ASSERT_EQUAL(CMOCK_MEM_SIZE % (CMOCK_MEM_INDEX_SIZE + 8), CMock_Guts_MemBytesFree()); - - //The very next call will return a NONE, and any after that - TEST_ASSERT_EQUAL_HEX(CMOCK_GUTS_NONE, CMock_Guts_MemNew(8)); - TEST_ASSERT_EQUAL_HEX(CMOCK_GUTS_NONE, CMock_Guts_MemNew(5)); - - //verify nothing has changed - TEST_ASSERT_EQUAL(CMOCK_MEM_SIZE - CMOCK_MEM_SIZE % (CMOCK_MEM_INDEX_SIZE + 8), CMock_Guts_MemBytesUsed()); - TEST_ASSERT_EQUAL(CMOCK_MEM_SIZE % (CMOCK_MEM_INDEX_SIZE + 8), CMock_Guts_MemBytesFree()); - - //verify we can still walk through the elements allocated - next = first; - for (i = 0; i < CMOCK_MEM_SIZE/(CMOCK_MEM_INDEX_SIZE + 8); i++) - { - TEST_ASSERT_MESSAGE(next != CMOCK_GUTS_NONE, "Should Not Have Returned CMOCK_GUTS_NONE"); - TEST_ASSERT_EQUAL(i, *((unsigned int*)CMock_Guts_GetAddressFor(next))); - next = CMock_Guts_MemNext(next); - } - - //there aren't any after that - TEST_ASSERT_EQUAL_HEX(CMOCK_GUTS_NONE, next); -} - -void test_ThatWeCanAskForAllSortsOfSizes(void) -{ -#if CMOCK_MEM_ALIGN != 2 - TEST_IGNORE_MESSAGE("Test relies on a particular environmental setup, which is not present"); -#else - - unsigned int i; - CMOCK_MEM_INDEX_TYPE first = CMOCK_GUTS_NONE; - CMOCK_MEM_INDEX_TYPE next; - CMOCK_MEM_INDEX_TYPE sizes[5] = {3, 1, 80, 5, 4}; - CMOCK_MEM_INDEX_TYPE sizes_buffered[5] = {4, 4, 80, 8, 4}; - CMOCK_MEM_INDEX_TYPE sum = 0; - - for (i = 0; i < 5; i++) - { - next = CMock_Guts_MemNew(sizes[i]); - TEST_ASSERT_MESSAGE(next != CMOCK_GUTS_NONE, "Should Not Have Returned CMOCK_GUTS_NONE"); - - first = CMock_Guts_MemChain(first, next); - TEST_ASSERT_MESSAGE(first != CMOCK_GUTS_NONE, "Should Not Have Returned CMOCK_GUTS_NONE"); - - sum += sizes_buffered[i] + 4; - TEST_ASSERT_EQUAL(sum, CMock_Guts_MemBytesUsed()); - TEST_ASSERT_EQUAL(CMOCK_MEM_SIZE - sum, CMock_Guts_MemBytesFree()); - } - - //show that we can't ask for too much memory - TEST_ASSERT_EQUAL_HEX(CMOCK_GUTS_NONE, CMock_Guts_MemNew(12)); - TEST_ASSERT_EQUAL_HEX(CMOCK_GUTS_NONE, CMock_Guts_MemNew(5)); - - //but we CAN ask for something that will still fit - next = CMock_Guts_MemNew(4); - TEST_ASSERT_MESSAGE(next != CMOCK_GUTS_NONE, "Should Not Have Returned CMOCK_GUTS_NONE"); - - first = CMock_Guts_MemChain(first, next); - TEST_ASSERT_MESSAGE(first != CMOCK_GUTS_NONE, "Should Not Have Returned CMOCK_GUTS_NONE"); - - //verify we're used up now - TEST_ASSERT_EQUAL(CMOCK_MEM_SIZE, CMock_Guts_MemBytesUsed()); - TEST_ASSERT_EQUAL(0, CMock_Guts_MemBytesFree()); - - //verify we can still walk through the elements allocated - next = first; - for (i = 0; i < 6; i++) - { - TEST_ASSERT_MESSAGE(next != CMOCK_GUTS_NONE, "Should Not Have Returned CMOCK_GUTS_NONE"); - next = CMock_Guts_MemNext(next); - } - - //there aren't any after that - TEST_ASSERT_EQUAL_HEX(CMOCK_GUTS_NONE, next); -#endif -} - -void test_MemEndOfChain(void) -{ - CMOCK_MEM_INDEX_TYPE first = CMOCK_GUTS_NONE; - CMOCK_MEM_INDEX_TYPE element[4]; - - //verify we're cleared first - TEST_ASSERT_EQUAL(0, CMock_Guts_MemBytesUsed()); - TEST_ASSERT_EQUAL(CMOCK_MEM_SIZE, CMock_Guts_MemBytesFree()); - - //first element - element[0] = CMock_Guts_MemNew(sizeof(unsigned int)); - first = CMock_Guts_MemChain(first, element[0]); - TEST_ASSERT_MESSAGE(element[0] == CMock_Guts_MemEndOfChain(first), "Should have returned element[0]"); - - //second element - element[1] = CMock_Guts_MemNew(sizeof(unsigned int)); - CMock_Guts_MemChain(first, element[1]); - TEST_ASSERT_MESSAGE(element[1] == CMock_Guts_MemEndOfChain(first), "Should have returned element[1]"); - - //third element - element[2] = CMock_Guts_MemNew(sizeof(unsigned int)); - CMock_Guts_MemChain(first, element[2]); - TEST_ASSERT_MESSAGE(element[2] == CMock_Guts_MemEndOfChain(first), "Should have returned element[2]"); - - //fourth element - element[3] = CMock_Guts_MemNew(sizeof(unsigned int)); - CMock_Guts_MemChain(first, element[3]); - TEST_ASSERT_MESSAGE(element[3] == CMock_Guts_MemEndOfChain(first), "Should have returned element[3]"); - - //Free it all - CMock_Guts_MemFreeAll(); - - //verify we're cleared - TEST_ASSERT_EQUAL(0, CMock_Guts_MemBytesUsed()); - TEST_ASSERT_EQUAL(CMOCK_MEM_SIZE, CMock_Guts_MemBytesFree()); -} +/* ========================================== + 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 TEST_MEM_INDEX_SIZE (sizeof(CMOCK_MEM_INDEX_TYPE)) + +void setUp(void) +{ + CMock_Guts_MemFreeAll(); +} + +void tearDown(void) +{ +} + +void test_MemNewWillReturnNullIfGivenIllegalSizes(void) +{ + TEST_ASSERT_EQUAL_HEX( CMOCK_GUTS_NONE, CMock_Guts_MemNew(0) ); + TEST_ASSERT_EQUAL_HEX( CMOCK_GUTS_NONE, CMock_Guts_MemNew(CMOCK_MEM_SIZE - TEST_MEM_INDEX_SIZE + 1) ); + TEST_ASSERT_NULL( CMock_Guts_GetAddressFor(CMOCK_GUTS_NONE) ); + + //verify we're cleared still + TEST_ASSERT_EQUAL(0, CMock_Guts_MemBytesUsed()); + TEST_ASSERT_EQUAL(CMOCK_MEM_SIZE, CMock_Guts_MemBytesFree()); +} + +void test_MemChainWillReturnNullAndDoNothingIfGivenIllegalInformation(void) +{ + CMOCK_MEM_INDEX_TYPE next = CMock_Guts_MemNew(4); + TEST_ASSERT_EQUAL(4 + TEST_MEM_INDEX_SIZE, CMock_Guts_MemBytesUsed()); + TEST_ASSERT_EQUAL(CMOCK_MEM_SIZE - 4 - TEST_MEM_INDEX_SIZE, CMock_Guts_MemBytesFree()); + + TEST_ASSERT_EQUAL_HEX( CMOCK_GUTS_NONE, CMock_Guts_MemChain(next + CMOCK_MEM_SIZE, next) ); + TEST_ASSERT_EQUAL_HEX( CMOCK_GUTS_NONE, CMock_Guts_MemChain(next, next + CMOCK_MEM_SIZE) ); + + //verify we're still the same + TEST_ASSERT_EQUAL(4 + TEST_MEM_INDEX_SIZE, CMock_Guts_MemBytesUsed()); + TEST_ASSERT_EQUAL(CMOCK_MEM_SIZE - 4 - TEST_MEM_INDEX_SIZE, CMock_Guts_MemBytesFree()); +} + +void test_MemNextWillReturnNullIfGivenABadRoot(void) +{ + TEST_ASSERT_EQUAL_HEX( CMOCK_GUTS_NONE, CMock_Guts_MemNext(0) ); + TEST_ASSERT_EQUAL_HEX( CMOCK_GUTS_NONE, CMock_Guts_MemNext(2) ); + TEST_ASSERT_EQUAL_HEX( CMOCK_GUTS_NONE, CMock_Guts_MemNext(CMOCK_MEM_SIZE - 4) ); + + //verify we're cleared still + TEST_ASSERT_EQUAL(0, CMock_Guts_MemBytesUsed()); + TEST_ASSERT_EQUAL(CMOCK_MEM_SIZE, CMock_Guts_MemBytesFree()); +} + +void test_ThatWeCanClaimAndChainAFewElementsTogether(void) +{ + unsigned int i; + CMOCK_MEM_INDEX_TYPE next; + CMOCK_MEM_INDEX_TYPE first = CMOCK_GUTS_NONE; + CMOCK_MEM_INDEX_TYPE element[4]; + + //verify we're cleared first + TEST_ASSERT_EQUAL(0, CMock_Guts_MemBytesUsed()); + TEST_ASSERT_EQUAL(CMOCK_MEM_SIZE, CMock_Guts_MemBytesFree()); + + //first element + element[0] = CMock_Guts_MemNew(sizeof(unsigned int)); + TEST_ASSERT_MESSAGE(element[0] != CMOCK_GUTS_NONE, "Should Not Have Returned CMOCK_GUTS_NONE"); + first = CMock_Guts_MemChain(first, element[0]); + TEST_ASSERT_EQUAL(element[0], first); + *((unsigned int*)CMock_Guts_GetAddressFor(element[0])) = 0; + + //verify we're using the right amount of memory + TEST_ASSERT_EQUAL(1 * (TEST_MEM_INDEX_SIZE + sizeof(unsigned int)), CMock_Guts_MemBytesUsed()); + TEST_ASSERT_EQUAL(CMOCK_MEM_SIZE - 1 * (TEST_MEM_INDEX_SIZE + sizeof(unsigned int)), CMock_Guts_MemBytesFree()); + + //second element + element[1] = CMock_Guts_MemNew(sizeof(unsigned int)); + TEST_ASSERT_MESSAGE(element[1] != CMOCK_GUTS_NONE, "Should Not Have Returned CMOCK_GUTS_NONE"); + TEST_ASSERT_NOT_EQUAL(element[0], element[1]); + TEST_ASSERT_EQUAL(first, CMock_Guts_MemChain(first, element[1])); + *((unsigned int*)CMock_Guts_GetAddressFor(element[1])) = 1; + + //verify we're using the right amount of memory + TEST_ASSERT_EQUAL(2 * (TEST_MEM_INDEX_SIZE + sizeof(unsigned int)), CMock_Guts_MemBytesUsed()); + TEST_ASSERT_EQUAL(CMOCK_MEM_SIZE - 2 * (TEST_MEM_INDEX_SIZE + sizeof(unsigned int)), CMock_Guts_MemBytesFree()); + + //third element + element[2] = CMock_Guts_MemNew(sizeof(unsigned int)); + TEST_ASSERT_MESSAGE(element[2] != CMOCK_GUTS_NONE, "Should Not Have Returned CMOCK_GUTS_NONE"); + TEST_ASSERT_NOT_EQUAL(element[0], element[2]); + TEST_ASSERT_NOT_EQUAL(element[1], element[2]); + TEST_ASSERT_EQUAL(first, CMock_Guts_MemChain(first, element[2])); + *((unsigned int*)CMock_Guts_GetAddressFor(element[2])) = 2; + + //verify we're using the right amount of memory + TEST_ASSERT_EQUAL(3 * (TEST_MEM_INDEX_SIZE + sizeof(unsigned int)), CMock_Guts_MemBytesUsed()); + TEST_ASSERT_EQUAL(CMOCK_MEM_SIZE - 3 * (TEST_MEM_INDEX_SIZE + sizeof(unsigned int)), CMock_Guts_MemBytesFree()); + + //fourth element + element[3] = CMock_Guts_MemNew(sizeof(unsigned int)); + TEST_ASSERT_MESSAGE(element[3] != CMOCK_GUTS_NONE, "Should Not Have Returned CMOCK_GUTS_NONE"); + TEST_ASSERT_NOT_EQUAL(element[0], element[3]); + TEST_ASSERT_NOT_EQUAL(element[1], element[3]); + TEST_ASSERT_NOT_EQUAL(element[2], element[3]); + TEST_ASSERT_EQUAL(first, CMock_Guts_MemChain(first, element[3])); + *((unsigned int*)CMock_Guts_GetAddressFor(element[3])) = 3; + + //verify we're using the right amount of memory + TEST_ASSERT_EQUAL(4 * (TEST_MEM_INDEX_SIZE + sizeof(unsigned int)), CMock_Guts_MemBytesUsed()); + TEST_ASSERT_EQUAL(CMOCK_MEM_SIZE - 4 * (TEST_MEM_INDEX_SIZE + sizeof(unsigned int)), CMock_Guts_MemBytesFree()); + + //traverse list + next = first; + for (i = 0; i < 4; i++) + { + TEST_ASSERT_EQUAL(element[i], next); + TEST_ASSERT_EQUAL(i, *((unsigned int*)CMock_Guts_GetAddressFor(element[i]))); + next = CMock_Guts_MemNext(next); + } + + //verify we get a null at the end of the list + TEST_ASSERT_EQUAL_HEX(CMOCK_GUTS_NONE, next); + + //verify we're using the right amount of memory + TEST_ASSERT_EQUAL(4 * (TEST_MEM_INDEX_SIZE + sizeof(unsigned int)), CMock_Guts_MemBytesUsed()); + TEST_ASSERT_EQUAL(CMOCK_MEM_SIZE - 4 * (TEST_MEM_INDEX_SIZE + sizeof(unsigned int)), CMock_Guts_MemBytesFree()); + + //Free it all + CMock_Guts_MemFreeAll(); + + //verify we're cleared + TEST_ASSERT_EQUAL(0, CMock_Guts_MemBytesUsed()); + TEST_ASSERT_EQUAL(CMOCK_MEM_SIZE, CMock_Guts_MemBytesFree()); +} + +void test_ThatCMockStopsReturningMoreDataWhenItRunsOutOfMemory(void) +{ + unsigned int i; + CMOCK_MEM_INDEX_TYPE first = CMOCK_GUTS_NONE; + CMOCK_MEM_INDEX_TYPE next; + + //even though we are asking for one byte, we've told it to align to closest CMOCK_MEM_ALIGN_SIZE bytes, therefore it will waste a byte each time + //so each call will use (CMOCK_MEM_INDEX_SIZE + CMOCK_MEM_ALIGN_SIZE) bytes (CMOCK_MEM_INDEX_SIZE for the index, 1 for the data, and (CMOCK_MEM_ALIGN_SIZE - 1) wasted). + //therefore we can safely allocated total/(CMOCK_MEM_INDEX_SIZE + CMOCK_MEM_ALIGN_SIZE) times. + for (i = 0; i < (CMOCK_MEM_SIZE / (CMOCK_MEM_INDEX_SIZE + CMOCK_MEM_ALIGN_SIZE)); i++) + { + TEST_ASSERT_EQUAL(i*(CMOCK_MEM_INDEX_SIZE + CMOCK_MEM_ALIGN_SIZE), CMock_Guts_MemBytesUsed()); + TEST_ASSERT_EQUAL(CMOCK_MEM_SIZE - i*(CMOCK_MEM_INDEX_SIZE + CMOCK_MEM_ALIGN_SIZE), CMock_Guts_MemBytesFree()); + + next = CMock_Guts_MemNew(1); + TEST_ASSERT_MESSAGE(next != CMOCK_GUTS_NONE, "Should Not Have Returned CMOCK_GUTS_NONE"); + + first = CMock_Guts_MemChain(first, next); + TEST_ASSERT_MESSAGE(first != CMOCK_GUTS_NONE, "Should Not Have Returned CMOCK_GUTS_NONE"); + } + + //verify we're at top of memory + TEST_ASSERT_EQUAL(CMOCK_MEM_SIZE, CMock_Guts_MemBytesUsed()); + TEST_ASSERT_EQUAL(0, CMock_Guts_MemBytesFree()); + + //The very next call will return a NULL, and any after that + TEST_ASSERT_EQUAL_HEX(CMOCK_GUTS_NONE, CMock_Guts_MemNew(1)); + TEST_ASSERT_EQUAL_HEX(CMOCK_GUTS_NONE, CMock_Guts_MemNew(1)); + TEST_ASSERT_EQUAL_HEX(CMOCK_GUTS_NONE, CMock_Guts_MemNew(1)); + + //verify nothing has changed + TEST_ASSERT_EQUAL(CMOCK_MEM_SIZE, CMock_Guts_MemBytesUsed()); + TEST_ASSERT_EQUAL(0, CMock_Guts_MemBytesFree()); + + //verify we can still walk through the elements allocated + next = first; + for (i = 0; i < (CMOCK_MEM_SIZE / (CMOCK_MEM_INDEX_SIZE + CMOCK_MEM_ALIGN_SIZE)); i++) + { + TEST_ASSERT_MESSAGE(next != CMOCK_GUTS_NONE, "Should Not Have Returned CMOCK_GUTS_NONE"); + next = CMock_Guts_MemNext(next); + } + + //there aren't any after that + TEST_ASSERT_EQUAL_HEX(CMOCK_GUTS_NONE, (_UU32)next); +} + +void test_ThatCMockStopsReturningMoreDataWhenAskForMoreThanItHasLeftEvenIfNotAtExactEnd(void) +{ + unsigned int i; + CMOCK_MEM_INDEX_TYPE first = CMOCK_GUTS_NONE; + CMOCK_MEM_INDEX_TYPE next; + + //we're asking for (CMOCK_MEM_INDEX_SIZE + 8) bytes each time now (CMOCK_MEM_INDEX_SIZE for index, 8 for data). + //CMOCK_MEM_SIZE/(CMOCK_MEM_INDEX_SIZE + 8) requests will request as much data as possible, while ensuring that there isn't enough + //memory for the next request + for (i = 0; i < CMOCK_MEM_SIZE/(CMOCK_MEM_INDEX_SIZE + 8); i++) + { + TEST_ASSERT_EQUAL(i*(CMOCK_MEM_INDEX_SIZE + 8), CMock_Guts_MemBytesUsed()); + TEST_ASSERT_EQUAL(CMOCK_MEM_SIZE - i*(CMOCK_MEM_INDEX_SIZE + 8), CMock_Guts_MemBytesFree()); + + next = CMock_Guts_MemNew(8); + TEST_ASSERT_MESSAGE(next != CMOCK_GUTS_NONE, "Should Not Have Returned CMOCK_GUTS_NONE"); + + first = CMock_Guts_MemChain(first, next); + TEST_ASSERT_MESSAGE(first != CMOCK_GUTS_NONE, "Should Not Have Returned CMOCK_GUTS_NONE"); + + //verify writing data won't screw us up + *((unsigned int*)CMock_Guts_GetAddressFor(next)) = i; + } + + //verify we're at top of memory + TEST_ASSERT_EQUAL(CMOCK_MEM_SIZE - CMOCK_MEM_SIZE % (CMOCK_MEM_INDEX_SIZE + 8), CMock_Guts_MemBytesUsed()); + TEST_ASSERT_EQUAL(CMOCK_MEM_SIZE % (CMOCK_MEM_INDEX_SIZE + 8), CMock_Guts_MemBytesFree()); + + //The very next call will return a NONE, and any after that + TEST_ASSERT_EQUAL_HEX(CMOCK_GUTS_NONE, CMock_Guts_MemNew(8)); + TEST_ASSERT_EQUAL_HEX(CMOCK_GUTS_NONE, CMock_Guts_MemNew(5)); + + //verify nothing has changed + TEST_ASSERT_EQUAL(CMOCK_MEM_SIZE - CMOCK_MEM_SIZE % (CMOCK_MEM_INDEX_SIZE + 8), CMock_Guts_MemBytesUsed()); + TEST_ASSERT_EQUAL(CMOCK_MEM_SIZE % (CMOCK_MEM_INDEX_SIZE + 8), CMock_Guts_MemBytesFree()); + + //verify we can still walk through the elements allocated + next = first; + for (i = 0; i < CMOCK_MEM_SIZE/(CMOCK_MEM_INDEX_SIZE + 8); i++) + { + TEST_ASSERT_MESSAGE(next != CMOCK_GUTS_NONE, "Should Not Have Returned CMOCK_GUTS_NONE"); + TEST_ASSERT_EQUAL(i, *((unsigned int*)CMock_Guts_GetAddressFor(next))); + next = CMock_Guts_MemNext(next); + } + + //there aren't any after that + TEST_ASSERT_EQUAL_HEX(CMOCK_GUTS_NONE, next); +} + +void test_ThatWeCanAskForAllSortsOfSizes(void) +{ +#if CMOCK_MEM_ALIGN != 2 + TEST_IGNORE_MESSAGE("Test relies on a particular environmental setup, which is not present"); +#else + + unsigned int i; + CMOCK_MEM_INDEX_TYPE first = CMOCK_GUTS_NONE; + CMOCK_MEM_INDEX_TYPE next; + CMOCK_MEM_INDEX_TYPE sizes[5] = {3, 1, 80, 5, 4}; + CMOCK_MEM_INDEX_TYPE sizes_buffered[5] = {4, 4, 80, 8, 4}; + CMOCK_MEM_INDEX_TYPE sum = 0; + + for (i = 0; i < 5; i++) + { + next = CMock_Guts_MemNew(sizes[i]); + TEST_ASSERT_MESSAGE(next != CMOCK_GUTS_NONE, "Should Not Have Returned CMOCK_GUTS_NONE"); + + first = CMock_Guts_MemChain(first, next); + TEST_ASSERT_MESSAGE(first != CMOCK_GUTS_NONE, "Should Not Have Returned CMOCK_GUTS_NONE"); + + sum += sizes_buffered[i] + 4; + TEST_ASSERT_EQUAL(sum, CMock_Guts_MemBytesUsed()); + TEST_ASSERT_EQUAL(CMOCK_MEM_SIZE - sum, CMock_Guts_MemBytesFree()); + } + + //show that we can't ask for too much memory + TEST_ASSERT_EQUAL_HEX(CMOCK_GUTS_NONE, CMock_Guts_MemNew(12)); + TEST_ASSERT_EQUAL_HEX(CMOCK_GUTS_NONE, CMock_Guts_MemNew(5)); + + //but we CAN ask for something that will still fit + next = CMock_Guts_MemNew(4); + TEST_ASSERT_MESSAGE(next != CMOCK_GUTS_NONE, "Should Not Have Returned CMOCK_GUTS_NONE"); + + first = CMock_Guts_MemChain(first, next); + TEST_ASSERT_MESSAGE(first != CMOCK_GUTS_NONE, "Should Not Have Returned CMOCK_GUTS_NONE"); + + //verify we're used up now + TEST_ASSERT_EQUAL(CMOCK_MEM_SIZE, CMock_Guts_MemBytesUsed()); + TEST_ASSERT_EQUAL(0, CMock_Guts_MemBytesFree()); + + //verify we can still walk through the elements allocated + next = first; + for (i = 0; i < 6; i++) + { + TEST_ASSERT_MESSAGE(next != CMOCK_GUTS_NONE, "Should Not Have Returned CMOCK_GUTS_NONE"); + next = CMock_Guts_MemNext(next); + } + + //there aren't any after that + TEST_ASSERT_EQUAL_HEX(CMOCK_GUTS_NONE, next); +#endif +} + +void test_MemEndOfChain(void) +{ + CMOCK_MEM_INDEX_TYPE first = CMOCK_GUTS_NONE; + CMOCK_MEM_INDEX_TYPE element[4]; + + //verify we're cleared first + TEST_ASSERT_EQUAL(0, CMock_Guts_MemBytesUsed()); + TEST_ASSERT_EQUAL(CMOCK_MEM_SIZE, CMock_Guts_MemBytesFree()); + + //first element + element[0] = CMock_Guts_MemNew(sizeof(unsigned int)); + first = CMock_Guts_MemChain(first, element[0]); + TEST_ASSERT_MESSAGE(element[0] == CMock_Guts_MemEndOfChain(first), "Should have returned element[0]"); + + //second element + element[1] = CMock_Guts_MemNew(sizeof(unsigned int)); + CMock_Guts_MemChain(first, element[1]); + TEST_ASSERT_MESSAGE(element[1] == CMock_Guts_MemEndOfChain(first), "Should have returned element[1]"); + + //third element + element[2] = CMock_Guts_MemNew(sizeof(unsigned int)); + CMock_Guts_MemChain(first, element[2]); + TEST_ASSERT_MESSAGE(element[2] == CMock_Guts_MemEndOfChain(first), "Should have returned element[2]"); + + //fourth element + element[3] = CMock_Guts_MemNew(sizeof(unsigned int)); + CMock_Guts_MemChain(first, element[3]); + TEST_ASSERT_MESSAGE(element[3] == CMock_Guts_MemEndOfChain(first), "Should have returned element[3]"); + + //Free it all + CMock_Guts_MemFreeAll(); + + //verify we're cleared + TEST_ASSERT_EQUAL(0, CMock_Guts_MemBytesUsed()); + TEST_ASSERT_EQUAL(CMOCK_MEM_SIZE, CMock_Guts_MemBytesFree()); +} diff --git a/test/unit/cmock_generator_main_test.rb b/test/unit/cmock_generator_main_test.rb index e2d9988..77d0922 100644 --- a/test/unit/cmock_generator_main_test.rb +++ b/test/unit/cmock_generator_main_test.rb @@ -1,507 +1,507 @@ -# ========================================== -# 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] -# ========================================== - -$ThisIsOnlyATest = true - -require File.expand_path(File.dirname(__FILE__)) + "/../test_helper" -require 'cmock_generator' - -class MockedPluginHelper - def initialize return_this - @return_this = return_this - end - - def include_files - return @return_this - end - - def instance_structure( name, args, rettype ) - return " #{@return_this}_#{name}(#{args}, #{rettype})" - end - - def mock_verify( name ) - return " #{@return_this}_#{name}" - end - - def mock_destroy( name, args, rettype ) - return " #{@return_this}_#{name}(#{args}, #{rettype})" - end - - def mock_implementation(name, args) - return " Mock#{name}#{@return_this}(#{args.join(", ")})" - end -end - -describe CMockGenerator, "Verify CMockGenerator Module" do - - before do - create_mocks :config, :file_writer, :utils, :plugins - @module_name = "PoutPoutFish" - - #no strict handling - @config.expect :mock_prefix, "Mock" - @config.expect :enforce_strict_ordering, nil - @config.expect :framework, :unity - @config.expect :includes, ["ConfigRequiredHeader1.h","ConfigRequiredHeader2.h"] - #@config.expect :includes_h_pre_orig_header, nil #not called because includes called - @config.expect :includes_h_post_orig_header, nil - @config.expect :includes_c_pre_header, nil - @config.expect :includes_c_post_header, nil - @config.expect :subdir, nil - @cmock_generator = CMockGenerator.new(@config, @file_writer, @utils, @plugins) - @cmock_generator.module_name = @module_name - @cmock_generator.mock_name = "Mock#{@module_name}" - @cmock_generator.clean_mock_name = "Mock#{@module_name}" - - #strict handling - @config.expect :mock_prefix, "Mock" - @config.expect :enforce_strict_ordering, true - @config.expect :framework, :unity - @config.expect :includes, nil - @config.expect :includes_h_pre_orig_header, nil - @config.expect :includes_h_post_orig_header, nil - @config.expect :includes_c_pre_header, nil - @config.expect :includes_c_post_header, nil - @config.expect :subdir, nil - @cmock_generator_strict = CMockGenerator.new(@config, @file_writer, @utils, @plugins) - @cmock_generator_strict.module_name = @module_name - @cmock_generator_strict.mock_name = "Mock#{@module_name}" - @cmock_generator_strict.clean_mock_name = "Mock#{@module_name}" - end - - after do - end - - it "create the top of a header file with optional include files from config and include file from plugin" do - @config.expect :mock_prefix, "Mock" - orig_filename = "PoutPoutFish.h" - define_name = "MOCKPOUTPOUTFISH_H" - mock_name = "MockPoutPoutFish" - output = [] - expected = [ - "/* AUTOGENERATED FILE. DO NOT EDIT. */\n", - "#ifndef _#{define_name}\n", - "#define _#{define_name}\n\n", - "#include \"ConfigRequiredHeader1.h\"\n", - "#include \"ConfigRequiredHeader2.h\"\n", - "#include \"#{orig_filename}\"\n", - "#include \"PluginRequiredHeader.h\"\n", - "\n", - "/* Ignore the following warnings, since we are copying code */\n", - "#if defined(__GNUC__) && !defined(__ICC)\n", - "#if !defined(__clang__)\n", - "#pragma GCC diagnostic ignored \"-Wpragmas\"\n", - "#endif\n", - "#pragma GCC diagnostic ignored \"-Wunknown-pragmas\"\n", - "#pragma GCC diagnostic ignored \"-Wduplicate-decl-specifier\"\n", - "#endif\n", - "\n", - ] - - @config.expect :orig_header_include_fmt, "#include \"%s\"" - @plugins.expect :run, "#include \"PluginRequiredHeader.h\"\n", [:include_files] - - @cmock_generator.create_mock_header_header(output, "MockPoutPoutFish.h") - - assert_equal(expected, output) - end - - it "handle dashes and spaces in the module name" do - #no strict handling - @config.expect :mock_prefix, "Mock" - @config.expect :enforce_strict_ordering, nil - @config.expect :framework, :unity - @config.expect :includes, ["ConfigRequiredHeader1.h","ConfigRequiredHeader2.h"] - @config.expect :includes_h_post_orig_header, nil - @config.expect :includes_c_pre_header, nil - @config.expect :includes_c_post_header, nil - @config.expect :subdir, nil - @cmock_generator2 = CMockGenerator.new(@config, @file_writer, @utils, @plugins) - @cmock_generator2.module_name = "Pout-Pout Fish" - @cmock_generator2.mock_name = "MockPout-Pout Fish" - @cmock_generator2.clean_mock_name = "MockPout_Pout_Fish" - - @config.expect :mock_prefix, "Mock" - orig_filename = "Pout-Pout Fish.h" - define_name = "MOCKPOUT_POUT_FISH_H" - mock_name = "MockPout_Pout_Fish" - output = [] - expected = [ - "/* AUTOGENERATED FILE. DO NOT EDIT. */\n", - "#ifndef _#{define_name}\n", - "#define _#{define_name}\n\n", - "#include \"ConfigRequiredHeader1.h\"\n", - "#include \"ConfigRequiredHeader2.h\"\n", - "#include \"#{orig_filename}\"\n", - "#include \"PluginRequiredHeader.h\"\n", - "\n", - "/* Ignore the following warnings, since we are copying code */\n", - "#if defined(__GNUC__) && !defined(__ICC)\n", - "#if !defined(__clang__)\n", - "#pragma GCC diagnostic ignored \"-Wpragmas\"\n", - "#endif\n", - "#pragma GCC diagnostic ignored \"-Wunknown-pragmas\"\n", - "#pragma GCC diagnostic ignored \"-Wduplicate-decl-specifier\"\n", - "#endif\n", - "\n", - ] - - @config.expect :orig_header_include_fmt, "#include \"%s\"" - @plugins.expect :run, "#include \"PluginRequiredHeader.h\"\n", [:include_files] - - @cmock_generator2.create_mock_header_header(output, "MockPout-Pout Fish.h") - - assert_equal(expected, output) - end - - it "create the top of a header file with optional include files from config" do - @config.expect :mock_prefix, "Mock" - orig_filename = "PoutPoutFish.h" - define_name = "MOCKPOUTPOUTFISH_H" - mock_name = "MockPoutPoutFish" - output = [] - expected = [ - "/* AUTOGENERATED FILE. DO NOT EDIT. */\n", - "#ifndef _#{define_name}\n", - "#define _#{define_name}\n\n", - "#include \"ConfigRequiredHeader1.h\"\n", - "#include \"ConfigRequiredHeader2.h\"\n", - "#include \"#{orig_filename}\"\n", - "\n", - "/* Ignore the following warnings, since we are copying code */\n", - "#if defined(__GNUC__) && !defined(__ICC)\n", - "#if !defined(__clang__)\n", - "#pragma GCC diagnostic ignored \"-Wpragmas\"\n", - "#endif\n", - "#pragma GCC diagnostic ignored \"-Wunknown-pragmas\"\n", - "#pragma GCC diagnostic ignored \"-Wduplicate-decl-specifier\"\n", - "#endif\n", - "\n", - ] - - @config.expect :orig_header_include_fmt, "#include \"%s\"" - @plugins.expect :run, '', [:include_files] - - @cmock_generator.create_mock_header_header(output, "MockPoutPoutFish.h") - - assert_equal(expected, output) - end - - it "create the top of a header file with include file from plugin" do - @config.expect :mock_prefix, "Mock" - orig_filename = "PoutPoutFish.h" - define_name = "MOCKPOUTPOUTFISH_H" - mock_name = "MockPoutPoutFish" - output = [] - expected = [ - "/* AUTOGENERATED FILE. DO NOT EDIT. */\n", - "#ifndef _#{define_name}\n", - "#define _#{define_name}\n\n", - "#include \"ConfigRequiredHeader1.h\"\n", - "#include \"ConfigRequiredHeader2.h\"\n", - "#include \"#{orig_filename}\"\n", - "#include \"PluginRequiredHeader.h\"\n", - "\n", - "/* Ignore the following warnings, since we are copying code */\n", - "#if defined(__GNUC__) && !defined(__ICC)\n", - "#if !defined(__clang__)\n", - "#pragma GCC diagnostic ignored \"-Wpragmas\"\n", - "#endif\n", - "#pragma GCC diagnostic ignored \"-Wunknown-pragmas\"\n", - "#pragma GCC diagnostic ignored \"-Wduplicate-decl-specifier\"\n", - "#endif\n", - "\n", - ] - - @config.expect :orig_header_include_fmt, "#include \"%s\"" - @plugins.expect :run, "#include \"PluginRequiredHeader.h\"\n", [:include_files] - - @cmock_generator.create_mock_header_header(output, "MockPoutPoutFish.h") - - assert_equal(expected, output) - end - - it "write typedefs" do - typedefs = [ 'typedef unsigned char U8;', - 'typedef char S8;', - 'typedef unsigned long U32;' - ] - output = [] - expected = [ "\n", - "typedef unsigned char U8;\n", - "typedef char S8;\n", - "typedef unsigned long U32;\n", - "\n\n" - ] - - @cmock_generator.create_typedefs(output, typedefs) - - assert_equal(expected, output.flatten) - end - - it "create the header file service call declarations" do - mock_name = "MockPoutPoutFish" - - output = [] - expected = [ "void #{mock_name}_Init(void);\n", - "void #{mock_name}_Destroy(void);\n", - "void #{mock_name}_Verify(void);\n\n" - ] - - @cmock_generator.create_mock_header_service_call_declarations(output) - - assert_equal(expected, output) - end - - it "append the proper footer to the header file" do - output = [] - expected = ["\n#endif\n"] - - @cmock_generator.create_mock_header_footer(output) - - assert_equal(expected, output) - end - - it "create a proper heading for a source file" do - output = [] - functions = [ { :name => "uno", :args => [ { :name => "arg1" }, { :name => "arg2" } ] }, - { :name => "dos", :args => [ { :name => "arg3" }, { :name => "arg2" } ] }, - { :name => "tres", :args => [] } - ] - expected = [ "/* AUTOGENERATED FILE. DO NOT EDIT. */\n", - "#include \n", - "#include \n", - "#include \n", - "#include \"unity.h\"\n", - "#include \"cmock.h\"\n", - "#include \"MockPoutPoutFish.h\"\n", - "\n", - "static const char* CMockString_arg1 = \"arg1\";\n", - "static const char* CMockString_arg2 = \"arg2\";\n", - "static const char* CMockString_arg3 = \"arg3\";\n", - "static const char* CMockString_dos = \"dos\";\n", - "static const char* CMockString_tres = \"tres\";\n", - "static const char* CMockString_uno = \"uno\";\n", - "\n" - ] - - @cmock_generator.create_source_header_section(output, "MockPoutPoutFish.c", functions) - - assert_equal(expected, output) - end - - it "create the instance structure where it is needed when no functions" do - output = [] - functions = [] - expected = [ "static struct MockPoutPoutFishInstance\n", - "{\n", - " unsigned char placeHolder;\n", - "} Mock;\n\n" - ].join - - @cmock_generator.create_instance_structure(output, functions) - - assert_equal(expected, output.join) - end - - it "create the instance structure where it is needed when functions required" do - output = [] - functions = [ { :name => "First", :args => "int Candy", :return => test_return[:int] }, - { :name => "Second", :args => "bool Smarty", :return => test_return[:string] } - ] - expected = [ "typedef struct _CMOCK_First_CALL_INSTANCE\n{\n", - " UNITY_LINE_TYPE LineNumber;\n", - " b1 b2", - "\n} CMOCK_First_CALL_INSTANCE;\n\n", - "typedef struct _CMOCK_Second_CALL_INSTANCE\n{\n", - " UNITY_LINE_TYPE LineNumber;\n", - "\n} CMOCK_Second_CALL_INSTANCE;\n\n", - "static struct MockPoutPoutFishInstance\n{\n", - " d1", - " CMOCK_MEM_INDEX_TYPE First_CallInstance;\n", - " e1 e2 e3", - " CMOCK_MEM_INDEX_TYPE Second_CallInstance;\n", - "} Mock;\n\n" - ].join - @plugins.expect :run, [" b1"," b2"], [:instance_typedefs, functions[0]] - @plugins.expect :run, [], [:instance_typedefs, functions[1]] - - @plugins.expect :run, [" d1"], [:instance_structure, functions[0]] - @plugins.expect :run, [" e1"," e2"," e3"], [:instance_structure, functions[1]] - - @cmock_generator.create_instance_structure(output, functions) - - assert_equal(expected, output.join) - end - - it "create extern declarations for source file" do - output = [] - expected = [ "extern jmp_buf AbortFrame;\n", - "\n" ] - - @cmock_generator.create_extern_declarations(output) - - assert_equal(expected, output.flatten) - end - - it "create extern declarations for source file when using strict ordering" do - output = [] - expected = [ "extern jmp_buf AbortFrame;\n", - "extern int GlobalExpectCount;\n", - "extern int GlobalVerifyOrder;\n", - "\n" ] - - @cmock_generator_strict.create_extern_declarations(output) - - assert_equal(expected, output.flatten) - end - - it "create mock verify functions in source file when no functions specified" do - functions = [] - output = [] - expected = "void MockPoutPoutFish_Verify(void)\n{\n}\n\n" - - @cmock_generator.create_mock_verify_function(output, functions) - - assert_equal(expected, output.join) - end - - it "create mock verify functions in source file when extra functions specified" do - functions = [ { :name => "First", :args => "int Candy", :return => test_return[:int] }, - { :name => "Second", :args => "bool Smarty", :return => test_return[:string] } - ] - output = [] - expected = [ "void MockPoutPoutFish_Verify(void)\n{\n", - " UNITY_LINE_TYPE cmock_line = TEST_LINE_NUM;\n", - " Uno_First" + - " Dos_First" + - " Uno_Second" + - " Dos_Second", - "}\n\n" - ] - @plugins.expect :run, [" Uno_First"," Dos_First"], [:mock_verify, functions[0]] - @plugins.expect :run, [" Uno_Second"," Dos_Second"], [:mock_verify, functions[1]] - - @cmock_generator.ordered = true - @cmock_generator.create_mock_verify_function(output, functions) - - assert_equal(expected, output.flatten) - end - - it "create mock init functions in source file" do - output = [] - expected = [ "void MockPoutPoutFish_Init(void)\n{\n", - " MockPoutPoutFish_Destroy();\n", - "}\n\n" - ] - - @cmock_generator.create_mock_init_function(output) - - assert_equal(expected.join, output.join) - end - - it "create mock destroy functions in source file" do - functions = [] - output = [] - expected = [ "void MockPoutPoutFish_Destroy(void)\n{\n", - " CMock_Guts_MemFreeAll();\n", - " memset(&Mock, 0, sizeof(Mock));\n", - "}\n\n" - ] - - @cmock_generator.create_mock_destroy_function(output, functions) - - assert_equal(expected.join, output.join) - end - - it "create mock destroy functions in source file when specified with strict ordering" do - functions = [ { :name => "First", :args => "int Candy", :return => test_return[:int] }, - { :name => "Second", :args => "bool Smarty", :return => test_return[:string] } - ] - output = [] - expected = [ "void MockPoutPoutFish_Destroy(void)\n{\n", - " CMock_Guts_MemFreeAll();\n", - " memset(&Mock, 0, sizeof(Mock));\n", - " uno", - " GlobalExpectCount = 0;\n", - " GlobalVerifyOrder = 0;\n", - "}\n\n" - ] - @plugins.expect :run, [], [:mock_destroy, functions[0]] - @plugins.expect :run, [" uno"], [:mock_destroy, functions[1]] - - @cmock_generator_strict.create_mock_destroy_function(output, functions) - - assert_equal(expected.join, output.join) - end - - it "create mock implementation functions in source file" do - function = { :modifier => "static", - :return => test_return[:int], - :args_string => "uint32 sandwiches, const char* named", - :args => ["uint32 sandwiches", "const char* named"], - :var_arg => nil, - :name => "SupaFunction", - :attributes => "__inline" - } - output = [] - expected = [ "static int SupaFunction(uint32 sandwiches, const char* named)\n", - "{\n", - " UNITY_LINE_TYPE cmock_line = TEST_LINE_NUM;\n", - " UNITY_SET_DETAIL(CMockString_SupaFunction);\n", - " CMOCK_SupaFunction_CALL_INSTANCE* cmock_call_instance = (CMOCK_SupaFunction_CALL_INSTANCE*)CMock_Guts_GetAddressFor(Mock.SupaFunction_CallInstance);\n", - " Mock.SupaFunction_CallInstance = CMock_Guts_MemNext(Mock.SupaFunction_CallInstance);\n", - " uno", - " UNITY_TEST_ASSERT_NOT_NULL(cmock_call_instance, cmock_line, CMockStringCalledMore);\n", - " cmock_line = cmock_call_instance->LineNumber;\n", - " dos", - " tres", - " UNITY_CLR_DETAILS();\n", - " return cmock_call_instance->ReturnVal;\n", - "}\n\n" - ] - @plugins.expect :run, [" uno"], [:mock_implementation_precheck, function] - @plugins.expect :run, [" dos"," tres"], [:mock_implementation, function] - - @cmock_generator.create_mock_implementation(output, function) - - assert_equal(expected.join, output.join) - end - - it "create mock implementation functions in source file with different options" do - function = { :modifier => "", - :c_calling_convention => "__stdcall", - :return => test_return[:int], - :args_string => "uint32 sandwiches", - :args => ["uint32 sandwiches"], - :var_arg => "corn ...", - :name => "SupaFunction", - :attributes => nil - } - output = [] - expected = [ "int __stdcall SupaFunction(uint32 sandwiches, corn ...)\n", - "{\n", - " UNITY_LINE_TYPE cmock_line = TEST_LINE_NUM;\n", - " UNITY_SET_DETAIL(CMockString_SupaFunction);\n", - " CMOCK_SupaFunction_CALL_INSTANCE* cmock_call_instance = (CMOCK_SupaFunction_CALL_INSTANCE*)CMock_Guts_GetAddressFor(Mock.SupaFunction_CallInstance);\n", - " Mock.SupaFunction_CallInstance = CMock_Guts_MemNext(Mock.SupaFunction_CallInstance);\n", - " uno", - " UNITY_TEST_ASSERT_NOT_NULL(cmock_call_instance, cmock_line, CMockStringCalledMore);\n", - " cmock_line = cmock_call_instance->LineNumber;\n", - " dos", - " tres", - " UNITY_CLR_DETAILS();\n", - " return cmock_call_instance->ReturnVal;\n", - "}\n\n" - ] - @plugins.expect :run, [" uno"], [:mock_implementation_precheck, function] - @plugins.expect :run, [" dos"," tres"], [:mock_implementation, function] - - @cmock_generator.create_mock_implementation(output, function) - - assert_equal(expected.join, output.join) - end -end +# ========================================== +# 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] +# ========================================== + +$ThisIsOnlyATest = true + +require File.expand_path(File.dirname(__FILE__)) + "/../test_helper" +require 'cmock_generator' + +class MockedPluginHelper + def initialize return_this + @return_this = return_this + end + + def include_files + return @return_this + end + + def instance_structure( name, args, rettype ) + return " #{@return_this}_#{name}(#{args}, #{rettype})" + end + + def mock_verify( name ) + return " #{@return_this}_#{name}" + end + + def mock_destroy( name, args, rettype ) + return " #{@return_this}_#{name}(#{args}, #{rettype})" + end + + def mock_implementation(name, args) + return " Mock#{name}#{@return_this}(#{args.join(", ")})" + end +end + +describe CMockGenerator, "Verify CMockGenerator Module" do + + before do + create_mocks :config, :file_writer, :utils, :plugins + @module_name = "PoutPoutFish" + + #no strict handling + @config.expect :mock_prefix, "Mock" + @config.expect :enforce_strict_ordering, nil + @config.expect :framework, :unity + @config.expect :includes, ["ConfigRequiredHeader1.h","ConfigRequiredHeader2.h"] + #@config.expect :includes_h_pre_orig_header, nil #not called because includes called + @config.expect :includes_h_post_orig_header, nil + @config.expect :includes_c_pre_header, nil + @config.expect :includes_c_post_header, nil + @config.expect :subdir, nil + @cmock_generator = CMockGenerator.new(@config, @file_writer, @utils, @plugins) + @cmock_generator.module_name = @module_name + @cmock_generator.mock_name = "Mock#{@module_name}" + @cmock_generator.clean_mock_name = "Mock#{@module_name}" + + #strict handling + @config.expect :mock_prefix, "Mock" + @config.expect :enforce_strict_ordering, true + @config.expect :framework, :unity + @config.expect :includes, nil + @config.expect :includes_h_pre_orig_header, nil + @config.expect :includes_h_post_orig_header, nil + @config.expect :includes_c_pre_header, nil + @config.expect :includes_c_post_header, nil + @config.expect :subdir, nil + @cmock_generator_strict = CMockGenerator.new(@config, @file_writer, @utils, @plugins) + @cmock_generator_strict.module_name = @module_name + @cmock_generator_strict.mock_name = "Mock#{@module_name}" + @cmock_generator_strict.clean_mock_name = "Mock#{@module_name}" + end + + after do + end + + it "create the top of a header file with optional include files from config and include file from plugin" do + @config.expect :mock_prefix, "Mock" + orig_filename = "PoutPoutFish.h" + define_name = "MOCKPOUTPOUTFISH_H" + mock_name = "MockPoutPoutFish" + output = [] + expected = [ + "/* AUTOGENERATED FILE. DO NOT EDIT. */\n", + "#ifndef _#{define_name}\n", + "#define _#{define_name}\n\n", + "#include \"ConfigRequiredHeader1.h\"\n", + "#include \"ConfigRequiredHeader2.h\"\n", + "#include \"#{orig_filename}\"\n", + "#include \"PluginRequiredHeader.h\"\n", + "\n", + "/* Ignore the following warnings, since we are copying code */\n", + "#if defined(__GNUC__) && !defined(__ICC)\n", + "#if !defined(__clang__)\n", + "#pragma GCC diagnostic ignored \"-Wpragmas\"\n", + "#endif\n", + "#pragma GCC diagnostic ignored \"-Wunknown-pragmas\"\n", + "#pragma GCC diagnostic ignored \"-Wduplicate-decl-specifier\"\n", + "#endif\n", + "\n", + ] + + @config.expect :orig_header_include_fmt, "#include \"%s\"" + @plugins.expect :run, "#include \"PluginRequiredHeader.h\"\n", [:include_files] + + @cmock_generator.create_mock_header_header(output, "MockPoutPoutFish.h") + + assert_equal(expected, output) + end + + it "handle dashes and spaces in the module name" do + #no strict handling + @config.expect :mock_prefix, "Mock" + @config.expect :enforce_strict_ordering, nil + @config.expect :framework, :unity + @config.expect :includes, ["ConfigRequiredHeader1.h","ConfigRequiredHeader2.h"] + @config.expect :includes_h_post_orig_header, nil + @config.expect :includes_c_pre_header, nil + @config.expect :includes_c_post_header, nil + @config.expect :subdir, nil + @cmock_generator2 = CMockGenerator.new(@config, @file_writer, @utils, @plugins) + @cmock_generator2.module_name = "Pout-Pout Fish" + @cmock_generator2.mock_name = "MockPout-Pout Fish" + @cmock_generator2.clean_mock_name = "MockPout_Pout_Fish" + + @config.expect :mock_prefix, "Mock" + orig_filename = "Pout-Pout Fish.h" + define_name = "MOCKPOUT_POUT_FISH_H" + mock_name = "MockPout_Pout_Fish" + output = [] + expected = [ + "/* AUTOGENERATED FILE. DO NOT EDIT. */\n", + "#ifndef _#{define_name}\n", + "#define _#{define_name}\n\n", + "#include \"ConfigRequiredHeader1.h\"\n", + "#include \"ConfigRequiredHeader2.h\"\n", + "#include \"#{orig_filename}\"\n", + "#include \"PluginRequiredHeader.h\"\n", + "\n", + "/* Ignore the following warnings, since we are copying code */\n", + "#if defined(__GNUC__) && !defined(__ICC)\n", + "#if !defined(__clang__)\n", + "#pragma GCC diagnostic ignored \"-Wpragmas\"\n", + "#endif\n", + "#pragma GCC diagnostic ignored \"-Wunknown-pragmas\"\n", + "#pragma GCC diagnostic ignored \"-Wduplicate-decl-specifier\"\n", + "#endif\n", + "\n", + ] + + @config.expect :orig_header_include_fmt, "#include \"%s\"" + @plugins.expect :run, "#include \"PluginRequiredHeader.h\"\n", [:include_files] + + @cmock_generator2.create_mock_header_header(output, "MockPout-Pout Fish.h") + + assert_equal(expected, output) + end + + it "create the top of a header file with optional include files from config" do + @config.expect :mock_prefix, "Mock" + orig_filename = "PoutPoutFish.h" + define_name = "MOCKPOUTPOUTFISH_H" + mock_name = "MockPoutPoutFish" + output = [] + expected = [ + "/* AUTOGENERATED FILE. DO NOT EDIT. */\n", + "#ifndef _#{define_name}\n", + "#define _#{define_name}\n\n", + "#include \"ConfigRequiredHeader1.h\"\n", + "#include \"ConfigRequiredHeader2.h\"\n", + "#include \"#{orig_filename}\"\n", + "\n", + "/* Ignore the following warnings, since we are copying code */\n", + "#if defined(__GNUC__) && !defined(__ICC)\n", + "#if !defined(__clang__)\n", + "#pragma GCC diagnostic ignored \"-Wpragmas\"\n", + "#endif\n", + "#pragma GCC diagnostic ignored \"-Wunknown-pragmas\"\n", + "#pragma GCC diagnostic ignored \"-Wduplicate-decl-specifier\"\n", + "#endif\n", + "\n", + ] + + @config.expect :orig_header_include_fmt, "#include \"%s\"" + @plugins.expect :run, '', [:include_files] + + @cmock_generator.create_mock_header_header(output, "MockPoutPoutFish.h") + + assert_equal(expected, output) + end + + it "create the top of a header file with include file from plugin" do + @config.expect :mock_prefix, "Mock" + orig_filename = "PoutPoutFish.h" + define_name = "MOCKPOUTPOUTFISH_H" + mock_name = "MockPoutPoutFish" + output = [] + expected = [ + "/* AUTOGENERATED FILE. DO NOT EDIT. */\n", + "#ifndef _#{define_name}\n", + "#define _#{define_name}\n\n", + "#include \"ConfigRequiredHeader1.h\"\n", + "#include \"ConfigRequiredHeader2.h\"\n", + "#include \"#{orig_filename}\"\n", + "#include \"PluginRequiredHeader.h\"\n", + "\n", + "/* Ignore the following warnings, since we are copying code */\n", + "#if defined(__GNUC__) && !defined(__ICC)\n", + "#if !defined(__clang__)\n", + "#pragma GCC diagnostic ignored \"-Wpragmas\"\n", + "#endif\n", + "#pragma GCC diagnostic ignored \"-Wunknown-pragmas\"\n", + "#pragma GCC diagnostic ignored \"-Wduplicate-decl-specifier\"\n", + "#endif\n", + "\n", + ] + + @config.expect :orig_header_include_fmt, "#include \"%s\"" + @plugins.expect :run, "#include \"PluginRequiredHeader.h\"\n", [:include_files] + + @cmock_generator.create_mock_header_header(output, "MockPoutPoutFish.h") + + assert_equal(expected, output) + end + + it "write typedefs" do + typedefs = [ 'typedef unsigned char U8;', + 'typedef char S8;', + 'typedef unsigned long U32;' + ] + output = [] + expected = [ "\n", + "typedef unsigned char U8;\n", + "typedef char S8;\n", + "typedef unsigned long U32;\n", + "\n\n" + ] + + @cmock_generator.create_typedefs(output, typedefs) + + assert_equal(expected, output.flatten) + end + + it "create the header file service call declarations" do + mock_name = "MockPoutPoutFish" + + output = [] + expected = [ "void #{mock_name}_Init(void);\n", + "void #{mock_name}_Destroy(void);\n", + "void #{mock_name}_Verify(void);\n\n" + ] + + @cmock_generator.create_mock_header_service_call_declarations(output) + + assert_equal(expected, output) + end + + it "append the proper footer to the header file" do + output = [] + expected = ["\n#endif\n"] + + @cmock_generator.create_mock_header_footer(output) + + assert_equal(expected, output) + end + + it "create a proper heading for a source file" do + output = [] + functions = [ { :name => "uno", :args => [ { :name => "arg1" }, { :name => "arg2" } ] }, + { :name => "dos", :args => [ { :name => "arg3" }, { :name => "arg2" } ] }, + { :name => "tres", :args => [] } + ] + expected = [ "/* AUTOGENERATED FILE. DO NOT EDIT. */\n", + "#include \n", + "#include \n", + "#include \n", + "#include \"unity.h\"\n", + "#include \"cmock.h\"\n", + "#include \"MockPoutPoutFish.h\"\n", + "\n", + "static const char* CMockString_arg1 = \"arg1\";\n", + "static const char* CMockString_arg2 = \"arg2\";\n", + "static const char* CMockString_arg3 = \"arg3\";\n", + "static const char* CMockString_dos = \"dos\";\n", + "static const char* CMockString_tres = \"tres\";\n", + "static const char* CMockString_uno = \"uno\";\n", + "\n" + ] + + @cmock_generator.create_source_header_section(output, "MockPoutPoutFish.c", functions) + + assert_equal(expected, output) + end + + it "create the instance structure where it is needed when no functions" do + output = [] + functions = [] + expected = [ "static struct MockPoutPoutFishInstance\n", + "{\n", + " unsigned char placeHolder;\n", + "} Mock;\n\n" + ].join + + @cmock_generator.create_instance_structure(output, functions) + + assert_equal(expected, output.join) + end + + it "create the instance structure where it is needed when functions required" do + output = [] + functions = [ { :name => "First", :args => "int Candy", :return => test_return[:int] }, + { :name => "Second", :args => "bool Smarty", :return => test_return[:string] } + ] + expected = [ "typedef struct _CMOCK_First_CALL_INSTANCE\n{\n", + " UNITY_LINE_TYPE LineNumber;\n", + " b1 b2", + "\n} CMOCK_First_CALL_INSTANCE;\n\n", + "typedef struct _CMOCK_Second_CALL_INSTANCE\n{\n", + " UNITY_LINE_TYPE LineNumber;\n", + "\n} CMOCK_Second_CALL_INSTANCE;\n\n", + "static struct MockPoutPoutFishInstance\n{\n", + " d1", + " CMOCK_MEM_INDEX_TYPE First_CallInstance;\n", + " e1 e2 e3", + " CMOCK_MEM_INDEX_TYPE Second_CallInstance;\n", + "} Mock;\n\n" + ].join + @plugins.expect :run, [" b1"," b2"], [:instance_typedefs, functions[0]] + @plugins.expect :run, [], [:instance_typedefs, functions[1]] + + @plugins.expect :run, [" d1"], [:instance_structure, functions[0]] + @plugins.expect :run, [" e1"," e2"," e3"], [:instance_structure, functions[1]] + + @cmock_generator.create_instance_structure(output, functions) + + assert_equal(expected, output.join) + end + + it "create extern declarations for source file" do + output = [] + expected = [ "extern jmp_buf AbortFrame;\n", + "\n" ] + + @cmock_generator.create_extern_declarations(output) + + assert_equal(expected, output.flatten) + end + + it "create extern declarations for source file when using strict ordering" do + output = [] + expected = [ "extern jmp_buf AbortFrame;\n", + "extern int GlobalExpectCount;\n", + "extern int GlobalVerifyOrder;\n", + "\n" ] + + @cmock_generator_strict.create_extern_declarations(output) + + assert_equal(expected, output.flatten) + end + + it "create mock verify functions in source file when no functions specified" do + functions = [] + output = [] + expected = "void MockPoutPoutFish_Verify(void)\n{\n}\n\n" + + @cmock_generator.create_mock_verify_function(output, functions) + + assert_equal(expected, output.join) + end + + it "create mock verify functions in source file when extra functions specified" do + functions = [ { :name => "First", :args => "int Candy", :return => test_return[:int] }, + { :name => "Second", :args => "bool Smarty", :return => test_return[:string] } + ] + output = [] + expected = [ "void MockPoutPoutFish_Verify(void)\n{\n", + " UNITY_LINE_TYPE cmock_line = TEST_LINE_NUM;\n", + " Uno_First" + + " Dos_First" + + " Uno_Second" + + " Dos_Second", + "}\n\n" + ] + @plugins.expect :run, [" Uno_First"," Dos_First"], [:mock_verify, functions[0]] + @plugins.expect :run, [" Uno_Second"," Dos_Second"], [:mock_verify, functions[1]] + + @cmock_generator.ordered = true + @cmock_generator.create_mock_verify_function(output, functions) + + assert_equal(expected, output.flatten) + end + + it "create mock init functions in source file" do + output = [] + expected = [ "void MockPoutPoutFish_Init(void)\n{\n", + " MockPoutPoutFish_Destroy();\n", + "}\n\n" + ] + + @cmock_generator.create_mock_init_function(output) + + assert_equal(expected.join, output.join) + end + + it "create mock destroy functions in source file" do + functions = [] + output = [] + expected = [ "void MockPoutPoutFish_Destroy(void)\n{\n", + " CMock_Guts_MemFreeAll();\n", + " memset(&Mock, 0, sizeof(Mock));\n", + "}\n\n" + ] + + @cmock_generator.create_mock_destroy_function(output, functions) + + assert_equal(expected.join, output.join) + end + + it "create mock destroy functions in source file when specified with strict ordering" do + functions = [ { :name => "First", :args => "int Candy", :return => test_return[:int] }, + { :name => "Second", :args => "bool Smarty", :return => test_return[:string] } + ] + output = [] + expected = [ "void MockPoutPoutFish_Destroy(void)\n{\n", + " CMock_Guts_MemFreeAll();\n", + " memset(&Mock, 0, sizeof(Mock));\n", + " uno", + " GlobalExpectCount = 0;\n", + " GlobalVerifyOrder = 0;\n", + "}\n\n" + ] + @plugins.expect :run, [], [:mock_destroy, functions[0]] + @plugins.expect :run, [" uno"], [:mock_destroy, functions[1]] + + @cmock_generator_strict.create_mock_destroy_function(output, functions) + + assert_equal(expected.join, output.join) + end + + it "create mock implementation functions in source file" do + function = { :modifier => "static", + :return => test_return[:int], + :args_string => "uint32 sandwiches, const char* named", + :args => ["uint32 sandwiches", "const char* named"], + :var_arg => nil, + :name => "SupaFunction", + :attributes => "__inline" + } + output = [] + expected = [ "static int SupaFunction(uint32 sandwiches, const char* named)\n", + "{\n", + " UNITY_LINE_TYPE cmock_line = TEST_LINE_NUM;\n", + " UNITY_SET_DETAIL(CMockString_SupaFunction);\n", + " CMOCK_SupaFunction_CALL_INSTANCE* cmock_call_instance = (CMOCK_SupaFunction_CALL_INSTANCE*)CMock_Guts_GetAddressFor(Mock.SupaFunction_CallInstance);\n", + " Mock.SupaFunction_CallInstance = CMock_Guts_MemNext(Mock.SupaFunction_CallInstance);\n", + " uno", + " UNITY_TEST_ASSERT_NOT_NULL(cmock_call_instance, cmock_line, CMockStringCalledMore);\n", + " cmock_line = cmock_call_instance->LineNumber;\n", + " dos", + " tres", + " UNITY_CLR_DETAILS();\n", + " return cmock_call_instance->ReturnVal;\n", + "}\n\n" + ] + @plugins.expect :run, [" uno"], [:mock_implementation_precheck, function] + @plugins.expect :run, [" dos"," tres"], [:mock_implementation, function] + + @cmock_generator.create_mock_implementation(output, function) + + assert_equal(expected.join, output.join) + end + + it "create mock implementation functions in source file with different options" do + function = { :modifier => "", + :c_calling_convention => "__stdcall", + :return => test_return[:int], + :args_string => "uint32 sandwiches", + :args => ["uint32 sandwiches"], + :var_arg => "corn ...", + :name => "SupaFunction", + :attributes => nil + } + output = [] + expected = [ "int __stdcall SupaFunction(uint32 sandwiches, corn ...)\n", + "{\n", + " UNITY_LINE_TYPE cmock_line = TEST_LINE_NUM;\n", + " UNITY_SET_DETAIL(CMockString_SupaFunction);\n", + " CMOCK_SupaFunction_CALL_INSTANCE* cmock_call_instance = (CMOCK_SupaFunction_CALL_INSTANCE*)CMock_Guts_GetAddressFor(Mock.SupaFunction_CallInstance);\n", + " Mock.SupaFunction_CallInstance = CMock_Guts_MemNext(Mock.SupaFunction_CallInstance);\n", + " uno", + " UNITY_TEST_ASSERT_NOT_NULL(cmock_call_instance, cmock_line, CMockStringCalledMore);\n", + " cmock_line = cmock_call_instance->LineNumber;\n", + " dos", + " tres", + " UNITY_CLR_DETAILS();\n", + " return cmock_call_instance->ReturnVal;\n", + "}\n\n" + ] + @plugins.expect :run, [" uno"], [:mock_implementation_precheck, function] + @plugins.expect :run, [" dos"," tres"], [:mock_implementation, function] + + @cmock_generator.create_mock_implementation(output, function) + + assert_equal(expected.join, output.join) + end +end diff --git a/test/unit/cmock_generator_plugin_cexception_test.rb b/test/unit/cmock_generator_plugin_cexception_test.rb index 931d9c0..7e8abc1 100644 --- a/test/unit/cmock_generator_plugin_cexception_test.rb +++ b/test/unit/cmock_generator_plugin_cexception_test.rb @@ -1,96 +1,96 @@ -# ========================================== -# CMock Project - Automatic Mock Generation for C -# Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams -# [Released under MIT License. Please refer to license.txt for details] -# ========================================== - -require File.expand_path(File.dirname(__FILE__)) + "/../test_helper" -require 'cmock_generator_plugin_cexception' - -describe CMockGeneratorPluginCexception, "Verify CMockGeneratorPluginCexception Module" do - - before do - create_mocks :config, :utils - @cmock_generator_plugin_cexception = CMockGeneratorPluginCexception.new(@config, @utils) - end - - after do - end - - it "have set up internal priority" do - assert_equal(7, @cmock_generator_plugin_cexception.priority) - end - - it "include the cexception library" do - expected = "#include \"CException.h\"\n" - returned = @cmock_generator_plugin_cexception.include_files - assert_equal(expected, returned) - end - - it "add to typedef structure mock needs" do - function = { :name => "Oak", :args => [], :return => test_return[:void] } - expected = " CEXCEPTION_T ExceptionToThrow;\n" - returned = @cmock_generator_plugin_cexception.instance_typedefs(function) - assert_equal(expected, returned) - end - - it "add mock function declarations for functions without arguments" do - function = { :name => "Spruce", :args_string => "void", :return => test_return[:void] } - expected = "#define Spruce_ExpectAndThrow(cmock_to_throw) Spruce_CMockExpectAndThrow(__LINE__, cmock_to_throw)\n"+ - "void Spruce_CMockExpectAndThrow(UNITY_LINE_TYPE cmock_line, CEXCEPTION_T cmock_to_throw);\n" - returned = @cmock_generator_plugin_cexception.mock_function_declarations(function) - assert_equal(expected, returned) - end - - it "add mock function declarations for functions with arguments" do - function = { :name => "Spruce", :args_string => "const char* Petunia, uint32_t Lily", :args_call => "Petunia, Lily", :return => test_return[:void] } - expected = "#define Spruce_ExpectAndThrow(Petunia, Lily, cmock_to_throw) Spruce_CMockExpectAndThrow(__LINE__, Petunia, Lily, cmock_to_throw)\n" + - "void Spruce_CMockExpectAndThrow(UNITY_LINE_TYPE cmock_line, const char* Petunia, uint32_t Lily, CEXCEPTION_T cmock_to_throw);\n" - returned = @cmock_generator_plugin_cexception.mock_function_declarations(function) - assert_equal(expected, returned) - end - - it "add a mock implementation" do - function = {:name => "Cherry", :args => [], :return => test_return[:void]} - expected = " if (cmock_call_instance->ExceptionToThrow != CEXCEPTION_NONE)\n" + - " {\n" + - " UNITY_CLR_DETAILS();\n" + - " Throw(cmock_call_instance->ExceptionToThrow);\n" + - " }\n" - returned = @cmock_generator_plugin_cexception.mock_implementation(function) - assert_equal(expected, returned) - end - - it "add mock interfaces for functions without arguments" do - function = {:name => "Pear", :args_string => "void", :args => [], :return => test_return[:void]} - @utils.expect :code_add_base_expectation, "mock_retval_0", ["Pear"] - @utils.expect :code_call_argument_loader, "", [function] - - expected = ["void Pear_CMockExpectAndThrow(UNITY_LINE_TYPE cmock_line, CEXCEPTION_T cmock_to_throw)\n", - "{\n", - "mock_retval_0", - "", - " cmock_call_instance->ExceptionToThrow = cmock_to_throw;\n", - "}\n\n" - ].join - returned = @cmock_generator_plugin_cexception.mock_interfaces(function) - assert_equal(expected, returned) - end - - it "add a mock interfaces for functions with arguments" do - function = {:name => "Pear", :args_string => "int blah", :args => [{ :type => "int", :name => "blah" }], :return => test_return[:void]} - @utils.expect :code_add_base_expectation, "mock_retval_0", ["Pear"] - @utils.expect :code_call_argument_loader, "mock_return_1", [function] - - expected = ["void Pear_CMockExpectAndThrow(UNITY_LINE_TYPE cmock_line, int blah, CEXCEPTION_T cmock_to_throw)\n", - "{\n", - "mock_retval_0", - "mock_return_1", - " cmock_call_instance->ExceptionToThrow = cmock_to_throw;\n", - "}\n\n" - ].join - returned = @cmock_generator_plugin_cexception.mock_interfaces(function) - assert_equal(expected, returned) - end - -end +# ========================================== +# CMock Project - Automatic Mock Generation for C +# Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams +# [Released under MIT License. Please refer to license.txt for details] +# ========================================== + +require File.expand_path(File.dirname(__FILE__)) + "/../test_helper" +require 'cmock_generator_plugin_cexception' + +describe CMockGeneratorPluginCexception, "Verify CMockGeneratorPluginCexception Module" do + + before do + create_mocks :config, :utils + @cmock_generator_plugin_cexception = CMockGeneratorPluginCexception.new(@config, @utils) + end + + after do + end + + it "have set up internal priority" do + assert_equal(7, @cmock_generator_plugin_cexception.priority) + end + + it "include the cexception library" do + expected = "#include \"CException.h\"\n" + returned = @cmock_generator_plugin_cexception.include_files + assert_equal(expected, returned) + end + + it "add to typedef structure mock needs" do + function = { :name => "Oak", :args => [], :return => test_return[:void] } + expected = " CEXCEPTION_T ExceptionToThrow;\n" + returned = @cmock_generator_plugin_cexception.instance_typedefs(function) + assert_equal(expected, returned) + end + + it "add mock function declarations for functions without arguments" do + function = { :name => "Spruce", :args_string => "void", :return => test_return[:void] } + expected = "#define Spruce_ExpectAndThrow(cmock_to_throw) Spruce_CMockExpectAndThrow(__LINE__, cmock_to_throw)\n"+ + "void Spruce_CMockExpectAndThrow(UNITY_LINE_TYPE cmock_line, CEXCEPTION_T cmock_to_throw);\n" + returned = @cmock_generator_plugin_cexception.mock_function_declarations(function) + assert_equal(expected, returned) + end + + it "add mock function declarations for functions with arguments" do + function = { :name => "Spruce", :args_string => "const char* Petunia, uint32_t Lily", :args_call => "Petunia, Lily", :return => test_return[:void] } + expected = "#define Spruce_ExpectAndThrow(Petunia, Lily, cmock_to_throw) Spruce_CMockExpectAndThrow(__LINE__, Petunia, Lily, cmock_to_throw)\n" + + "void Spruce_CMockExpectAndThrow(UNITY_LINE_TYPE cmock_line, const char* Petunia, uint32_t Lily, CEXCEPTION_T cmock_to_throw);\n" + returned = @cmock_generator_plugin_cexception.mock_function_declarations(function) + assert_equal(expected, returned) + end + + it "add a mock implementation" do + function = {:name => "Cherry", :args => [], :return => test_return[:void]} + expected = " if (cmock_call_instance->ExceptionToThrow != CEXCEPTION_NONE)\n" + + " {\n" + + " UNITY_CLR_DETAILS();\n" + + " Throw(cmock_call_instance->ExceptionToThrow);\n" + + " }\n" + returned = @cmock_generator_plugin_cexception.mock_implementation(function) + assert_equal(expected, returned) + end + + it "add mock interfaces for functions without arguments" do + function = {:name => "Pear", :args_string => "void", :args => [], :return => test_return[:void]} + @utils.expect :code_add_base_expectation, "mock_retval_0", ["Pear"] + @utils.expect :code_call_argument_loader, "", [function] + + expected = ["void Pear_CMockExpectAndThrow(UNITY_LINE_TYPE cmock_line, CEXCEPTION_T cmock_to_throw)\n", + "{\n", + "mock_retval_0", + "", + " cmock_call_instance->ExceptionToThrow = cmock_to_throw;\n", + "}\n\n" + ].join + returned = @cmock_generator_plugin_cexception.mock_interfaces(function) + assert_equal(expected, returned) + end + + it "add a mock interfaces for functions with arguments" do + function = {:name => "Pear", :args_string => "int blah", :args => [{ :type => "int", :name => "blah" }], :return => test_return[:void]} + @utils.expect :code_add_base_expectation, "mock_retval_0", ["Pear"] + @utils.expect :code_call_argument_loader, "mock_return_1", [function] + + expected = ["void Pear_CMockExpectAndThrow(UNITY_LINE_TYPE cmock_line, int blah, CEXCEPTION_T cmock_to_throw)\n", + "{\n", + "mock_retval_0", + "mock_return_1", + " cmock_call_instance->ExceptionToThrow = cmock_to_throw;\n", + "}\n\n" + ].join + returned = @cmock_generator_plugin_cexception.mock_interfaces(function) + assert_equal(expected, returned) + end + +end diff --git a/test/unit/cmock_generator_plugin_expect_test.rb b/test/unit/cmock_generator_plugin_expect_test.rb index 38ffd1d..bf77d23 100644 --- a/test/unit/cmock_generator_plugin_expect_test.rb +++ b/test/unit/cmock_generator_plugin_expect_test.rb @@ -1,210 +1,210 @@ -# ========================================== -# CMock Project - Automatic Mock Generation for C -# Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams -# [Released under MIT License. Please refer to license.txt for details] -# ========================================== - -require File.expand_path(File.dirname(__FILE__)) + "/../test_helper" -require 'cmock_generator_plugin_expect' - -describe CMockGeneratorPluginExpect, "Verify CMockGeneratorPluginExpect Module" do - - before do - create_mocks :config, :utils - - @config = create_stub( - :when_ptr => :compare_data, - :enforce_strict_ordering => false, - :respond_to? => true ) - - @utils.expect :helpers, {} - @cmock_generator_plugin_expect = CMockGeneratorPluginExpect.new(@config, @utils) - - @config_strict = create_stub( - :when_ptr => :compare_data, - :enforce_strict_ordering => true, - :respond_to? => true ) - - @utils.expect :helpers, {} - @cmock_generator_plugin_expect_strict = CMockGeneratorPluginExpect.new(@config_strict, @utils) - end - - after do - end - - it "have set up internal priority on init" do - assert_equal(nil, @cmock_generator_plugin_expect.unity_helper) - assert_equal(5, @cmock_generator_plugin_expect.priority) - end - - it "not include any additional include files" do - assert(!@cmock_generator_plugin_expect.respond_to?(:include_files)) - end - - it "add to typedef structure mock needs of functions of style 'void func(void)'" do - function = {:name => "Oak", :args => [], :return => test_return[:void]} - expected = "" - returned = @cmock_generator_plugin_expect.instance_typedefs(function) - assert_equal(expected, returned) - end - - it "add to typedef structure mock needs of functions of style 'int func(void)'" do - function = {:name => "Elm", :args => [], :return => test_return[:int]} - expected = " int ReturnVal;\n" - returned = @cmock_generator_plugin_expect.instance_typedefs(function) - assert_equal(expected, returned) - end - - it "add to typedef structure mock needs of functions of style 'void func(int chicken, char* pork)'" do - function = {:name => "Cedar", :args => [{ :name => "chicken", :type => "int"}, { :name => "pork", :type => "char*"}], :return => test_return[:void]} - expected = " int Expected_chicken;\n char* Expected_pork;\n" - returned = @cmock_generator_plugin_expect.instance_typedefs(function) - assert_equal(expected, returned) - end - - it "add to typedef structure mock needs of functions of style 'int func(float beef)'" do - function = {:name => "Birch", :args => [{ :name => "beef", :type => "float"}], :return => test_return[:int]} - expected = " int ReturnVal;\n float Expected_beef;\n" - returned = @cmock_generator_plugin_expect.instance_typedefs(function) - assert_equal(expected, returned) - end - - it "add to typedef structure mock needs of functions of style 'void func(void)' and global ordering" do - function = {:name => "Oak", :args => [], :return => test_return[:void]} - expected = " int CallOrder;\n" - returned = @cmock_generator_plugin_expect_strict.instance_typedefs(function) - assert_equal(expected, returned) - end - - it "add mock function declaration for functions of style 'void func(void)'" do - function = {:name => "Maple", :args => [], :return => test_return[:void]} - expected = "#define Maple_Expect() Maple_CMockExpect(__LINE__)\n" + - "void Maple_CMockExpect(UNITY_LINE_TYPE cmock_line);\n" - returned = @cmock_generator_plugin_expect.mock_function_declarations(function) - assert_equal(expected, returned) - end - - it "add mock function declaration for functions of style 'int func(void)'" do - function = {:name => "Spruce", :args => [], :return => test_return[:int]} - expected = "#define Spruce_ExpectAndReturn(cmock_retval) Spruce_CMockExpectAndReturn(__LINE__, cmock_retval)\n" + - "void Spruce_CMockExpectAndReturn(UNITY_LINE_TYPE cmock_line, int cmock_to_return);\n" - returned = @cmock_generator_plugin_expect.mock_function_declarations(function) - assert_equal(expected, returned) - end - - it "add mock function declaration for functions of style 'const char* func(int tofu)'" do - function = {:name => "Pine", :args => ["int tofu"], :args_string => "int tofu", :args_call => 'tofu', :return => test_return[:string]} - expected = "#define Pine_ExpectAndReturn(tofu, cmock_retval) Pine_CMockExpectAndReturn(__LINE__, tofu, cmock_retval)\n" + - "void Pine_CMockExpectAndReturn(UNITY_LINE_TYPE cmock_line, int tofu, const char* cmock_to_return);\n" - returned = @cmock_generator_plugin_expect.mock_function_declarations(function) - assert_equal(expected, returned) - end - - it "add mock function implementation for functions of style 'void func(void)'" do - function = {:name => "Apple", :args => [], :return => test_return[:void]} - expected = "" - returned = @cmock_generator_plugin_expect.mock_implementation(function) - assert_equal(expected, returned) - end - - it "add mock function implementation for functions of style 'int func(int veal, unsigned int sushi)'" do - function = {:name => "Cherry", :args => [ { :type => "int", :name => "veal" }, { :type => "unsigned int", :name => "sushi" } ], :return => test_return[:int]} - - @utils.expect :code_verify_an_arg_expectation, " mocked_retval_1", [function, function[:args][0]] - @utils.expect :code_verify_an_arg_expectation, " mocked_retval_2", [function, function[:args][1]] - expected = " mocked_retval_1 mocked_retval_2" - returned = @cmock_generator_plugin_expect.mock_implementation(function) - assert_equal(expected, returned) - end - - it "add mock function implementation using ordering if needed" do - function = {:name => "Apple", :args => [], :return => test_return[:void]} - expected = "" - @cmock_generator_plugin_expect.ordered = true - returned = @cmock_generator_plugin_expect.mock_implementation(function) - assert_equal(expected, returned) - end - - it "add mock function implementation for functions of style 'void func(int worm)' and strict ordering" do - function = {:name => "Apple", :args => [{ :type => "int", :name => "worm" }], :return => test_return[:void]} - @utils.expect :code_verify_an_arg_expectation, "mocked_retval_0", [function, function[:args][0]] - expected = "mocked_retval_0" - @cmock_generator_plugin_expect.ordered = true - returned = @cmock_generator_plugin_expect_strict.mock_implementation(function) - assert_equal(expected, returned) - end - - it "add mock interfaces for functions of style 'void func(void)'" do - function = {:name => "Pear", :args => [], :args_string => "void", :return => test_return[:void]} - @utils.expect :code_add_base_expectation, "mock_retval_0 ", ["Pear"] - @utils.expect :code_call_argument_loader, "mock_retval_1 ", [function] - expected = ["void Pear_CMockExpect(UNITY_LINE_TYPE cmock_line)\n", - "{\n", - "mock_retval_0 ", - "mock_retval_1 ", - " UNITY_CLR_DETAILS();\n", - "}\n\n" - ].join - returned = @cmock_generator_plugin_expect.mock_interfaces(function) - assert_equal(expected, returned) - end - - it "add mock interfaces for functions of style 'int func(void)'" do - function = {:name => "Orange", :args => [], :args_string => "void", :return => test_return[:int]} - @utils.expect :code_add_base_expectation, "mock_retval_0 ", ["Orange"] - @utils.expect :code_call_argument_loader, "mock_retval_1 ", [function] - @utils.expect :code_assign_argument_quickly, "mock_retval_2", ["cmock_call_instance->ReturnVal", function[:return]] - expected = ["void Orange_CMockExpectAndReturn(UNITY_LINE_TYPE cmock_line, int cmock_to_return)\n", - "{\n", - "mock_retval_0 ", - "mock_retval_1 ", - "mock_retval_2", - " UNITY_CLR_DETAILS();\n", - "}\n\n" - ].join - returned = @cmock_generator_plugin_expect.mock_interfaces(function) - assert_equal(expected, returned) - end - - it "add mock interfaces for functions of style 'int func(char* pescado)'" do - function = {:name => "Lemon", :args => [{ :type => "char*", :name => "pescado"}], :args_string => "char* pescado", :return => test_return[:int]} - @utils.expect :code_add_base_expectation, "mock_retval_0 ", ["Lemon"] - @utils.expect :code_call_argument_loader, "mock_retval_1 ", [function] - @utils.expect :code_assign_argument_quickly, "mock_retval_2", ["cmock_call_instance->ReturnVal", function[:return]] - expected = ["void Lemon_CMockExpectAndReturn(UNITY_LINE_TYPE cmock_line, char* pescado, int cmock_to_return)\n", - "{\n", - "mock_retval_0 ", - "mock_retval_1 ", - "mock_retval_2", - " UNITY_CLR_DETAILS();\n", - "}\n\n" - ].join - returned = @cmock_generator_plugin_expect.mock_interfaces(function) - assert_equal(expected, returned) - end - - it "add mock interfaces for functions when using ordering" do - function = {:name => "Pear", :args => [], :args_string => "void", :return => test_return[:void]} - @utils.expect :code_add_base_expectation, "mock_retval_0 ", ["Pear"] - @utils.expect :code_call_argument_loader, "mock_retval_1 ", [function] - expected = ["void Pear_CMockExpect(UNITY_LINE_TYPE cmock_line)\n", - "{\n", - "mock_retval_0 ", - "mock_retval_1 ", - " UNITY_CLR_DETAILS();\n", - "}\n\n" - ].join - @cmock_generator_plugin_expect.ordered = true - returned = @cmock_generator_plugin_expect.mock_interfaces(function) - assert_equal(expected, returned) - end - - it "add mock verify lines" do - function = {:name => "Banana" } - expected = " UNITY_SET_DETAIL(CMockString_Banana);\n" + - " UNITY_TEST_ASSERT(CMOCK_GUTS_NONE == Mock.Banana_CallInstance, cmock_line, CMockStringCalledLess);\n" - returned = @cmock_generator_plugin_expect.mock_verify(function) - assert_equal(expected, returned) - end - -end +# ========================================== +# CMock Project - Automatic Mock Generation for C +# Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams +# [Released under MIT License. Please refer to license.txt for details] +# ========================================== + +require File.expand_path(File.dirname(__FILE__)) + "/../test_helper" +require 'cmock_generator_plugin_expect' + +describe CMockGeneratorPluginExpect, "Verify CMockGeneratorPluginExpect Module" do + + before do + create_mocks :config, :utils + + @config = create_stub( + :when_ptr => :compare_data, + :enforce_strict_ordering => false, + :respond_to? => true ) + + @utils.expect :helpers, {} + @cmock_generator_plugin_expect = CMockGeneratorPluginExpect.new(@config, @utils) + + @config_strict = create_stub( + :when_ptr => :compare_data, + :enforce_strict_ordering => true, + :respond_to? => true ) + + @utils.expect :helpers, {} + @cmock_generator_plugin_expect_strict = CMockGeneratorPluginExpect.new(@config_strict, @utils) + end + + after do + end + + it "have set up internal priority on init" do + assert_equal(nil, @cmock_generator_plugin_expect.unity_helper) + assert_equal(5, @cmock_generator_plugin_expect.priority) + end + + it "not include any additional include files" do + assert(!@cmock_generator_plugin_expect.respond_to?(:include_files)) + end + + it "add to typedef structure mock needs of functions of style 'void func(void)'" do + function = {:name => "Oak", :args => [], :return => test_return[:void]} + expected = "" + returned = @cmock_generator_plugin_expect.instance_typedefs(function) + assert_equal(expected, returned) + end + + it "add to typedef structure mock needs of functions of style 'int func(void)'" do + function = {:name => "Elm", :args => [], :return => test_return[:int]} + expected = " int ReturnVal;\n" + returned = @cmock_generator_plugin_expect.instance_typedefs(function) + assert_equal(expected, returned) + end + + it "add to typedef structure mock needs of functions of style 'void func(int chicken, char* pork)'" do + function = {:name => "Cedar", :args => [{ :name => "chicken", :type => "int"}, { :name => "pork", :type => "char*"}], :return => test_return[:void]} + expected = " int Expected_chicken;\n char* Expected_pork;\n" + returned = @cmock_generator_plugin_expect.instance_typedefs(function) + assert_equal(expected, returned) + end + + it "add to typedef structure mock needs of functions of style 'int func(float beef)'" do + function = {:name => "Birch", :args => [{ :name => "beef", :type => "float"}], :return => test_return[:int]} + expected = " int ReturnVal;\n float Expected_beef;\n" + returned = @cmock_generator_plugin_expect.instance_typedefs(function) + assert_equal(expected, returned) + end + + it "add to typedef structure mock needs of functions of style 'void func(void)' and global ordering" do + function = {:name => "Oak", :args => [], :return => test_return[:void]} + expected = " int CallOrder;\n" + returned = @cmock_generator_plugin_expect_strict.instance_typedefs(function) + assert_equal(expected, returned) + end + + it "add mock function declaration for functions of style 'void func(void)'" do + function = {:name => "Maple", :args => [], :return => test_return[:void]} + expected = "#define Maple_Expect() Maple_CMockExpect(__LINE__)\n" + + "void Maple_CMockExpect(UNITY_LINE_TYPE cmock_line);\n" + returned = @cmock_generator_plugin_expect.mock_function_declarations(function) + assert_equal(expected, returned) + end + + it "add mock function declaration for functions of style 'int func(void)'" do + function = {:name => "Spruce", :args => [], :return => test_return[:int]} + expected = "#define Spruce_ExpectAndReturn(cmock_retval) Spruce_CMockExpectAndReturn(__LINE__, cmock_retval)\n" + + "void Spruce_CMockExpectAndReturn(UNITY_LINE_TYPE cmock_line, int cmock_to_return);\n" + returned = @cmock_generator_plugin_expect.mock_function_declarations(function) + assert_equal(expected, returned) + end + + it "add mock function declaration for functions of style 'const char* func(int tofu)'" do + function = {:name => "Pine", :args => ["int tofu"], :args_string => "int tofu", :args_call => 'tofu', :return => test_return[:string]} + expected = "#define Pine_ExpectAndReturn(tofu, cmock_retval) Pine_CMockExpectAndReturn(__LINE__, tofu, cmock_retval)\n" + + "void Pine_CMockExpectAndReturn(UNITY_LINE_TYPE cmock_line, int tofu, const char* cmock_to_return);\n" + returned = @cmock_generator_plugin_expect.mock_function_declarations(function) + assert_equal(expected, returned) + end + + it "add mock function implementation for functions of style 'void func(void)'" do + function = {:name => "Apple", :args => [], :return => test_return[:void]} + expected = "" + returned = @cmock_generator_plugin_expect.mock_implementation(function) + assert_equal(expected, returned) + end + + it "add mock function implementation for functions of style 'int func(int veal, unsigned int sushi)'" do + function = {:name => "Cherry", :args => [ { :type => "int", :name => "veal" }, { :type => "unsigned int", :name => "sushi" } ], :return => test_return[:int]} + + @utils.expect :code_verify_an_arg_expectation, " mocked_retval_1", [function, function[:args][0]] + @utils.expect :code_verify_an_arg_expectation, " mocked_retval_2", [function, function[:args][1]] + expected = " mocked_retval_1 mocked_retval_2" + returned = @cmock_generator_plugin_expect.mock_implementation(function) + assert_equal(expected, returned) + end + + it "add mock function implementation using ordering if needed" do + function = {:name => "Apple", :args => [], :return => test_return[:void]} + expected = "" + @cmock_generator_plugin_expect.ordered = true + returned = @cmock_generator_plugin_expect.mock_implementation(function) + assert_equal(expected, returned) + end + + it "add mock function implementation for functions of style 'void func(int worm)' and strict ordering" do + function = {:name => "Apple", :args => [{ :type => "int", :name => "worm" }], :return => test_return[:void]} + @utils.expect :code_verify_an_arg_expectation, "mocked_retval_0", [function, function[:args][0]] + expected = "mocked_retval_0" + @cmock_generator_plugin_expect.ordered = true + returned = @cmock_generator_plugin_expect_strict.mock_implementation(function) + assert_equal(expected, returned) + end + + it "add mock interfaces for functions of style 'void func(void)'" do + function = {:name => "Pear", :args => [], :args_string => "void", :return => test_return[:void]} + @utils.expect :code_add_base_expectation, "mock_retval_0 ", ["Pear"] + @utils.expect :code_call_argument_loader, "mock_retval_1 ", [function] + expected = ["void Pear_CMockExpect(UNITY_LINE_TYPE cmock_line)\n", + "{\n", + "mock_retval_0 ", + "mock_retval_1 ", + " UNITY_CLR_DETAILS();\n", + "}\n\n" + ].join + returned = @cmock_generator_plugin_expect.mock_interfaces(function) + assert_equal(expected, returned) + end + + it "add mock interfaces for functions of style 'int func(void)'" do + function = {:name => "Orange", :args => [], :args_string => "void", :return => test_return[:int]} + @utils.expect :code_add_base_expectation, "mock_retval_0 ", ["Orange"] + @utils.expect :code_call_argument_loader, "mock_retval_1 ", [function] + @utils.expect :code_assign_argument_quickly, "mock_retval_2", ["cmock_call_instance->ReturnVal", function[:return]] + expected = ["void Orange_CMockExpectAndReturn(UNITY_LINE_TYPE cmock_line, int cmock_to_return)\n", + "{\n", + "mock_retval_0 ", + "mock_retval_1 ", + "mock_retval_2", + " UNITY_CLR_DETAILS();\n", + "}\n\n" + ].join + returned = @cmock_generator_plugin_expect.mock_interfaces(function) + assert_equal(expected, returned) + end + + it "add mock interfaces for functions of style 'int func(char* pescado)'" do + function = {:name => "Lemon", :args => [{ :type => "char*", :name => "pescado"}], :args_string => "char* pescado", :return => test_return[:int]} + @utils.expect :code_add_base_expectation, "mock_retval_0 ", ["Lemon"] + @utils.expect :code_call_argument_loader, "mock_retval_1 ", [function] + @utils.expect :code_assign_argument_quickly, "mock_retval_2", ["cmock_call_instance->ReturnVal", function[:return]] + expected = ["void Lemon_CMockExpectAndReturn(UNITY_LINE_TYPE cmock_line, char* pescado, int cmock_to_return)\n", + "{\n", + "mock_retval_0 ", + "mock_retval_1 ", + "mock_retval_2", + " UNITY_CLR_DETAILS();\n", + "}\n\n" + ].join + returned = @cmock_generator_plugin_expect.mock_interfaces(function) + assert_equal(expected, returned) + end + + it "add mock interfaces for functions when using ordering" do + function = {:name => "Pear", :args => [], :args_string => "void", :return => test_return[:void]} + @utils.expect :code_add_base_expectation, "mock_retval_0 ", ["Pear"] + @utils.expect :code_call_argument_loader, "mock_retval_1 ", [function] + expected = ["void Pear_CMockExpect(UNITY_LINE_TYPE cmock_line)\n", + "{\n", + "mock_retval_0 ", + "mock_retval_1 ", + " UNITY_CLR_DETAILS();\n", + "}\n\n" + ].join + @cmock_generator_plugin_expect.ordered = true + returned = @cmock_generator_plugin_expect.mock_interfaces(function) + assert_equal(expected, returned) + end + + it "add mock verify lines" do + function = {:name => "Banana" } + expected = " UNITY_SET_DETAIL(CMockString_Banana);\n" + + " UNITY_TEST_ASSERT(CMOCK_GUTS_NONE == Mock.Banana_CallInstance, cmock_line, CMockStringCalledLess);\n" + returned = @cmock_generator_plugin_expect.mock_verify(function) + assert_equal(expected, returned) + end + +end diff --git a/test/unit/cmock_generator_plugin_ignore_arg_test.rb b/test/unit/cmock_generator_plugin_ignore_arg_test.rb index f5329d3..7588559 100644 --- a/test/unit/cmock_generator_plugin_ignore_arg_test.rb +++ b/test/unit/cmock_generator_plugin_ignore_arg_test.rb @@ -1,116 +1,116 @@ -# ========================================== -# CMock Project - Automatic Mock Generation for C -# Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams -# [Released under MIT License. Please refer to license.txt for details] -# ========================================== - -require File.expand_path(File.dirname(__FILE__)) + "/../test_helper" -require 'cmock_generator_plugin_ignore_arg' - -describe CMockGeneratorPluginIgnoreArg, "Verify CMockGeneratorPluginIgnoreArg Module" do - - before do - create_mocks :config, :utils - - # int *Oak(void)" - @void_func = {:name => "Oak", :args => [], :return => test_return[:int_ptr]} - - # void Pine(int chicken, const int beef, int *tofu) - @complex_func = {:name => "Pine", - :args => [{ :type => "int", - :name => "chicken", - :ptr? => false, - }, - { :type => "int*", - :name => "beef", - :ptr? => true, - :const? => true, - }, - { :type => "int*", - :name => "tofu", - :ptr? => true, - }], - :return => test_return[:void], - :contains_ptr? => true } - - #no strict ordering - @cmock_generator_plugin_ignore_arg = CMockGeneratorPluginIgnoreArg.new(@config, @utils) - end - - after do - end - - it "have set up internal priority correctly on init" do - assert_equal(10, @cmock_generator_plugin_ignore_arg.priority) - end - - it "not include any additional include files" do - assert(!@cmock_generator_plugin_ignore_arg.respond_to?(:include_files)) - end - - it "not add to typedef structure for functions with no args" do - returned = @cmock_generator_plugin_ignore_arg.instance_typedefs(@void_func) - assert_equal("", returned) - end - - it "add to tyepdef structure mock needs of functions of style 'void func(int chicken, int* pork)'" do - expected = " int IgnoreArg_chicken;\n" + - " int IgnoreArg_beef;\n" + - " int IgnoreArg_tofu;\n" - returned = @cmock_generator_plugin_ignore_arg.instance_typedefs(@complex_func) - assert_equal(expected, returned) - end - - it "add mock function declarations for all arguments" do - expected = - "#define Pine_IgnoreArg_chicken()" + - " Pine_CMockIgnoreArg_chicken(__LINE__)\n" + - "void Pine_CMockIgnoreArg_chicken(UNITY_LINE_TYPE cmock_line);\n" + - - "#define Pine_IgnoreArg_beef()" + - " Pine_CMockIgnoreArg_beef(__LINE__)\n" + - "void Pine_CMockIgnoreArg_beef(UNITY_LINE_TYPE cmock_line);\n" + - - "#define Pine_IgnoreArg_tofu()" + - " Pine_CMockIgnoreArg_tofu(__LINE__)\n" + - "void Pine_CMockIgnoreArg_tofu(UNITY_LINE_TYPE cmock_line);\n" - - returned = @cmock_generator_plugin_ignore_arg.mock_function_declarations(@complex_func) - assert_equal(expected, returned) - end - - it "add mock interfaces for all arguments" do - expected = - "void Pine_CMockIgnoreArg_chicken(UNITY_LINE_TYPE cmock_line)\n" + - "{\n" + - " CMOCK_Pine_CALL_INSTANCE* cmock_call_instance = " + - "(CMOCK_Pine_CALL_INSTANCE*)CMock_Guts_GetAddressFor(CMock_Guts_MemEndOfChain(Mock.Pine_CallInstance));\n" + - " UNITY_TEST_ASSERT_NOT_NULL(cmock_call_instance, cmock_line, CMockStringIgnPreExp);\n" + - " cmock_call_instance->IgnoreArg_chicken = 1;\n" + - "}\n\n" + - - "void Pine_CMockIgnoreArg_beef(UNITY_LINE_TYPE cmock_line)\n" + - "{\n" + - " CMOCK_Pine_CALL_INSTANCE* cmock_call_instance = " + - "(CMOCK_Pine_CALL_INSTANCE*)CMock_Guts_GetAddressFor(CMock_Guts_MemEndOfChain(Mock.Pine_CallInstance));\n" + - " UNITY_TEST_ASSERT_NOT_NULL(cmock_call_instance, cmock_line, CMockStringIgnPreExp);\n" + - " cmock_call_instance->IgnoreArg_beef = 1;\n" + - "}\n\n" + - - "void Pine_CMockIgnoreArg_tofu(UNITY_LINE_TYPE cmock_line)\n" + - "{\n" + - " CMOCK_Pine_CALL_INSTANCE* cmock_call_instance = " + - "(CMOCK_Pine_CALL_INSTANCE*)CMock_Guts_GetAddressFor(CMock_Guts_MemEndOfChain(Mock.Pine_CallInstance));\n" + - " UNITY_TEST_ASSERT_NOT_NULL(cmock_call_instance, cmock_line, CMockStringIgnPreExp);\n" + - " cmock_call_instance->IgnoreArg_tofu = 1;\n" + - "}\n\n" - - returned = @cmock_generator_plugin_ignore_arg.mock_interfaces(@complex_func).join("") - assert_equal(expected, returned) - end - - it "not add a mock implementation" do - assert(!@cmock_generator_plugin_ignore_arg.respond_to?(:mock_implementation)) - end - -end +# ========================================== +# CMock Project - Automatic Mock Generation for C +# Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams +# [Released under MIT License. Please refer to license.txt for details] +# ========================================== + +require File.expand_path(File.dirname(__FILE__)) + "/../test_helper" +require 'cmock_generator_plugin_ignore_arg' + +describe CMockGeneratorPluginIgnoreArg, "Verify CMockGeneratorPluginIgnoreArg Module" do + + before do + create_mocks :config, :utils + + # int *Oak(void)" + @void_func = {:name => "Oak", :args => [], :return => test_return[:int_ptr]} + + # void Pine(int chicken, const int beef, int *tofu) + @complex_func = {:name => "Pine", + :args => [{ :type => "int", + :name => "chicken", + :ptr? => false, + }, + { :type => "int*", + :name => "beef", + :ptr? => true, + :const? => true, + }, + { :type => "int*", + :name => "tofu", + :ptr? => true, + }], + :return => test_return[:void], + :contains_ptr? => true } + + #no strict ordering + @cmock_generator_plugin_ignore_arg = CMockGeneratorPluginIgnoreArg.new(@config, @utils) + end + + after do + end + + it "have set up internal priority correctly on init" do + assert_equal(10, @cmock_generator_plugin_ignore_arg.priority) + end + + it "not include any additional include files" do + assert(!@cmock_generator_plugin_ignore_arg.respond_to?(:include_files)) + end + + it "not add to typedef structure for functions with no args" do + returned = @cmock_generator_plugin_ignore_arg.instance_typedefs(@void_func) + assert_equal("", returned) + end + + it "add to tyepdef structure mock needs of functions of style 'void func(int chicken, int* pork)'" do + expected = " int IgnoreArg_chicken;\n" + + " int IgnoreArg_beef;\n" + + " int IgnoreArg_tofu;\n" + returned = @cmock_generator_plugin_ignore_arg.instance_typedefs(@complex_func) + assert_equal(expected, returned) + end + + it "add mock function declarations for all arguments" do + expected = + "#define Pine_IgnoreArg_chicken()" + + " Pine_CMockIgnoreArg_chicken(__LINE__)\n" + + "void Pine_CMockIgnoreArg_chicken(UNITY_LINE_TYPE cmock_line);\n" + + + "#define Pine_IgnoreArg_beef()" + + " Pine_CMockIgnoreArg_beef(__LINE__)\n" + + "void Pine_CMockIgnoreArg_beef(UNITY_LINE_TYPE cmock_line);\n" + + + "#define Pine_IgnoreArg_tofu()" + + " Pine_CMockIgnoreArg_tofu(__LINE__)\n" + + "void Pine_CMockIgnoreArg_tofu(UNITY_LINE_TYPE cmock_line);\n" + + returned = @cmock_generator_plugin_ignore_arg.mock_function_declarations(@complex_func) + assert_equal(expected, returned) + end + + it "add mock interfaces for all arguments" do + expected = + "void Pine_CMockIgnoreArg_chicken(UNITY_LINE_TYPE cmock_line)\n" + + "{\n" + + " CMOCK_Pine_CALL_INSTANCE* cmock_call_instance = " + + "(CMOCK_Pine_CALL_INSTANCE*)CMock_Guts_GetAddressFor(CMock_Guts_MemEndOfChain(Mock.Pine_CallInstance));\n" + + " UNITY_TEST_ASSERT_NOT_NULL(cmock_call_instance, cmock_line, CMockStringIgnPreExp);\n" + + " cmock_call_instance->IgnoreArg_chicken = 1;\n" + + "}\n\n" + + + "void Pine_CMockIgnoreArg_beef(UNITY_LINE_TYPE cmock_line)\n" + + "{\n" + + " CMOCK_Pine_CALL_INSTANCE* cmock_call_instance = " + + "(CMOCK_Pine_CALL_INSTANCE*)CMock_Guts_GetAddressFor(CMock_Guts_MemEndOfChain(Mock.Pine_CallInstance));\n" + + " UNITY_TEST_ASSERT_NOT_NULL(cmock_call_instance, cmock_line, CMockStringIgnPreExp);\n" + + " cmock_call_instance->IgnoreArg_beef = 1;\n" + + "}\n\n" + + + "void Pine_CMockIgnoreArg_tofu(UNITY_LINE_TYPE cmock_line)\n" + + "{\n" + + " CMOCK_Pine_CALL_INSTANCE* cmock_call_instance = " + + "(CMOCK_Pine_CALL_INSTANCE*)CMock_Guts_GetAddressFor(CMock_Guts_MemEndOfChain(Mock.Pine_CallInstance));\n" + + " UNITY_TEST_ASSERT_NOT_NULL(cmock_call_instance, cmock_line, CMockStringIgnPreExp);\n" + + " cmock_call_instance->IgnoreArg_tofu = 1;\n" + + "}\n\n" + + returned = @cmock_generator_plugin_ignore_arg.mock_interfaces(@complex_func).join("") + assert_equal(expected, returned) + end + + it "not add a mock implementation" do + assert(!@cmock_generator_plugin_ignore_arg.respond_to?(:mock_implementation)) + end + +end diff --git a/test/unit/cmock_generator_plugin_ignore_test.rb b/test/unit/cmock_generator_plugin_ignore_test.rb index 2933b02..47582b0 100644 --- a/test/unit/cmock_generator_plugin_ignore_test.rb +++ b/test/unit/cmock_generator_plugin_ignore_test.rb @@ -1,105 +1,105 @@ -# ========================================== -# CMock Project - Automatic Mock Generation for C -# Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams -# [Released under MIT License. Please refer to license.txt for details] -# ========================================== - -require File.expand_path(File.dirname(__FILE__)) + "/../test_helper" -require 'cmock_generator_plugin_ignore' - -describe CMockGeneratorPluginIgnore, "Verify CMockGeneratorPluginIgnore Module" do - - before do - create_mocks :config, :utils - @config = create_stub(:respond_to? => true) - @cmock_generator_plugin_ignore = CMockGeneratorPluginIgnore.new(@config, @utils) - end - - after do - end - - it "have set up internal priority" do - assert_equal(2, @cmock_generator_plugin_ignore.priority) - end - - it "not have any additional include file requirements" do - assert(!@cmock_generator_plugin_ignore.respond_to?(:include_files)) - end - - it "add a required variable to the instance structure" do - function = {:name => "Grass", :args => [], :return => test_return[:void]} - expected = " int Grass_IgnoreBool;\n" - returned = @cmock_generator_plugin_ignore.instance_structure(function) - assert_equal(expected, returned) - end - - it "handle function declarations for functions without return values" do - function = {:name => "Mold", :args_string => "void", :return => test_return[:void]} - expected = "#define Mold_Ignore() Mold_CMockIgnore()\nvoid Mold_CMockIgnore(void);\n" - returned = @cmock_generator_plugin_ignore.mock_function_declarations(function) - assert_equal(expected, returned) - end - - it "handle function declarations for functions that returns something" do - function = {:name => "Fungus", :args_string => "void", :return => test_return[:string]} - expected = "#define Fungus_IgnoreAndReturn(cmock_retval) Fungus_CMockIgnoreAndReturn(__LINE__, cmock_retval)\n"+ - "void Fungus_CMockIgnoreAndReturn(UNITY_LINE_TYPE cmock_line, const char* cmock_to_return);\n" - returned = @cmock_generator_plugin_ignore.mock_function_declarations(function) - assert_equal(expected, returned) - end - - it "add required code to implementation precheck with void function" do - function = {:name => "Mold", :args_string => "void", :return => test_return[:void]} - expected = [" if (Mock.Mold_IgnoreBool)\n", - " {\n", - " UNITY_CLR_DETAILS();\n", - " return;\n", - " }\n" - ].join - returned = @cmock_generator_plugin_ignore.mock_implementation_precheck(function) - assert_equal(expected, returned) - end - - it "add required code to implementation precheck with return functions" do - function = {:name => "Fungus", :args_string => "void", :return => test_return[:int]} - retval = test_return[:int].merge({ :name => "cmock_call_instance->ReturnVal"}) - @utils.expect :code_assign_argument_quickly, ' mock_retval_0', ["Mock.Fungus_FinalReturn", retval] - expected = [" if (Mock.Fungus_IgnoreBool)\n", - " {\n", - " UNITY_CLR_DETAILS();\n", - " if (cmock_call_instance == NULL)\n", - " return Mock.Fungus_FinalReturn;\n", - " mock_retval_0", - " return cmock_call_instance->ReturnVal;\n", - " }\n" - ].join - returned = @cmock_generator_plugin_ignore.mock_implementation_precheck(function) - assert_equal(expected, returned) - end - - it "add a new mock interface for ignoring when function had no return value" do - function = {:name => "Slime", :args => [], :args_string => "void", :return => test_return[:void]} - expected = ["void Slime_CMockIgnore(void)\n", - "{\n", - " Mock.Slime_IgnoreBool = (int)1;\n", - "}\n\n" - ].join - returned = @cmock_generator_plugin_ignore.mock_interfaces(function) - assert_equal(expected, returned) - end - - it "add a new mock interface for ignoring when function has return value" do - function = {:name => "Slime", :args => [], :args_string => "void", :return => test_return[:int]} - @utils.expect :code_add_base_expectation, "mock_return_1", ["Slime", false] - expected = ["void Slime_CMockIgnoreAndReturn(UNITY_LINE_TYPE cmock_line, int cmock_to_return)\n", - "{\n", - "mock_return_1", - " cmock_call_instance->ReturnVal = cmock_to_return;\n", - " Mock.Slime_IgnoreBool = (int)1;\n", - "}\n\n" - ].join - returned = @cmock_generator_plugin_ignore.mock_interfaces(function) - assert_equal(expected, returned) - end - -end +# ========================================== +# CMock Project - Automatic Mock Generation for C +# Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams +# [Released under MIT License. Please refer to license.txt for details] +# ========================================== + +require File.expand_path(File.dirname(__FILE__)) + "/../test_helper" +require 'cmock_generator_plugin_ignore' + +describe CMockGeneratorPluginIgnore, "Verify CMockGeneratorPluginIgnore Module" do + + before do + create_mocks :config, :utils + @config = create_stub(:respond_to? => true) + @cmock_generator_plugin_ignore = CMockGeneratorPluginIgnore.new(@config, @utils) + end + + after do + end + + it "have set up internal priority" do + assert_equal(2, @cmock_generator_plugin_ignore.priority) + end + + it "not have any additional include file requirements" do + assert(!@cmock_generator_plugin_ignore.respond_to?(:include_files)) + end + + it "add a required variable to the instance structure" do + function = {:name => "Grass", :args => [], :return => test_return[:void]} + expected = " int Grass_IgnoreBool;\n" + returned = @cmock_generator_plugin_ignore.instance_structure(function) + assert_equal(expected, returned) + end + + it "handle function declarations for functions without return values" do + function = {:name => "Mold", :args_string => "void", :return => test_return[:void]} + expected = "#define Mold_Ignore() Mold_CMockIgnore()\nvoid Mold_CMockIgnore(void);\n" + returned = @cmock_generator_plugin_ignore.mock_function_declarations(function) + assert_equal(expected, returned) + end + + it "handle function declarations for functions that returns something" do + function = {:name => "Fungus", :args_string => "void", :return => test_return[:string]} + expected = "#define Fungus_IgnoreAndReturn(cmock_retval) Fungus_CMockIgnoreAndReturn(__LINE__, cmock_retval)\n"+ + "void Fungus_CMockIgnoreAndReturn(UNITY_LINE_TYPE cmock_line, const char* cmock_to_return);\n" + returned = @cmock_generator_plugin_ignore.mock_function_declarations(function) + assert_equal(expected, returned) + end + + it "add required code to implementation precheck with void function" do + function = {:name => "Mold", :args_string => "void", :return => test_return[:void]} + expected = [" if (Mock.Mold_IgnoreBool)\n", + " {\n", + " UNITY_CLR_DETAILS();\n", + " return;\n", + " }\n" + ].join + returned = @cmock_generator_plugin_ignore.mock_implementation_precheck(function) + assert_equal(expected, returned) + end + + it "add required code to implementation precheck with return functions" do + function = {:name => "Fungus", :args_string => "void", :return => test_return[:int]} + retval = test_return[:int].merge({ :name => "cmock_call_instance->ReturnVal"}) + @utils.expect :code_assign_argument_quickly, ' mock_retval_0', ["Mock.Fungus_FinalReturn", retval] + expected = [" if (Mock.Fungus_IgnoreBool)\n", + " {\n", + " UNITY_CLR_DETAILS();\n", + " if (cmock_call_instance == NULL)\n", + " return Mock.Fungus_FinalReturn;\n", + " mock_retval_0", + " return cmock_call_instance->ReturnVal;\n", + " }\n" + ].join + returned = @cmock_generator_plugin_ignore.mock_implementation_precheck(function) + assert_equal(expected, returned) + end + + it "add a new mock interface for ignoring when function had no return value" do + function = {:name => "Slime", :args => [], :args_string => "void", :return => test_return[:void]} + expected = ["void Slime_CMockIgnore(void)\n", + "{\n", + " Mock.Slime_IgnoreBool = (int)1;\n", + "}\n\n" + ].join + returned = @cmock_generator_plugin_ignore.mock_interfaces(function) + assert_equal(expected, returned) + end + + it "add a new mock interface for ignoring when function has return value" do + function = {:name => "Slime", :args => [], :args_string => "void", :return => test_return[:int]} + @utils.expect :code_add_base_expectation, "mock_return_1", ["Slime", false] + expected = ["void Slime_CMockIgnoreAndReturn(UNITY_LINE_TYPE cmock_line, int cmock_to_return)\n", + "{\n", + "mock_return_1", + " cmock_call_instance->ReturnVal = cmock_to_return;\n", + " Mock.Slime_IgnoreBool = (int)1;\n", + "}\n\n" + ].join + returned = @cmock_generator_plugin_ignore.mock_interfaces(function) + assert_equal(expected, returned) + end + +end diff --git a/test/unit/cmock_generator_plugin_return_thru_ptr_test.rb b/test/unit/cmock_generator_plugin_return_thru_ptr_test.rb index 7b93f00..832474c 100644 --- a/test/unit/cmock_generator_plugin_return_thru_ptr_test.rb +++ b/test/unit/cmock_generator_plugin_return_thru_ptr_test.rb @@ -1,134 +1,134 @@ -# ========================================== -# CMock Project - Automatic Mock Generation for C -# Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams -# [Released under MIT License. Please refer to license.txt for details] -# ========================================== - -require File.expand_path(File.dirname(__FILE__)) + "/../test_helper" -require 'cmock_generator_plugin_return_thru_ptr' - -describe CMockGeneratorPluginReturnThruPtr, "Verify CMockGeneratorPluginReturnThruPtr Module" do - - before do - create_mocks :config, :utils - - # int *Oak(void)" - @void_func = {:name => "Oak", :args => [], :return => test_return[:int_ptr]} - - # char *Maple(int blah) - @simple_func = {:name => "Maple", - :args => [{:name => "blah", :type => "int", :ptr? => false}], - :return => test_return[:string], - :contains_ptr? => false} - - # void Pine(int chicken, const int beef, int *tofu) - @complex_func = {:name => "Pine", - :args => [{ :type => "int", - :name => "chicken", - :ptr? => false, - }, - { :type => "int*", - :name => "beef", - :ptr? => true, - :const? => true, - }, - { :type => "int*", - :name => "tofu", - :ptr? => true, - }], - :return => test_return[:void], - :contains_ptr? => true } - - #no strict ordering - @cmock_generator_plugin_return_thru_ptr = CMockGeneratorPluginReturnThruPtr.new(@config, @utils) - end - - after do - end - - def simple_func_expect - @utils.expect :ptr_or_str?, false, ['int'] - end - - def complex_func_expect - @utils.expect :ptr_or_str?, false, ['int'] - @utils.expect :ptr_or_str?, true, ['int*'] - @utils.expect :ptr_or_str?, true, ['int*'] - end - - it "have set up internal priority correctly on init" do - assert_equal(1, @cmock_generator_plugin_return_thru_ptr.priority) - end - - it "not include any additional include files" do - assert(!@cmock_generator_plugin_return_thru_ptr.respond_to?(:include_files)) - end - - it "not add to typedef structure for functions of style 'int* func(void)'" do - returned = @cmock_generator_plugin_return_thru_ptr.instance_typedefs(@void_func) - assert_equal("", returned) - end - - it "add to tyepdef structure mock needs of functions of style 'void func(int chicken, int* pork)'" do - complex_func_expect() - expected = " int ReturnThruPtr_tofu_Used;\n" + - " int* ReturnThruPtr_tofu_Val;\n" + - " int ReturnThruPtr_tofu_Size;\n" - returned = @cmock_generator_plugin_return_thru_ptr.instance_typedefs(@complex_func) - assert_equal(expected, returned) - end - - it "not add an additional mock interface for functions not containing pointers" do - simple_func_expect() - returned = @cmock_generator_plugin_return_thru_ptr.mock_function_declarations(@simple_func) - assert_equal("", returned) - end - - it "add a mock function declaration only for non-const pointer arguments" do - complex_func_expect(); - - expected = - "#define Pine_ReturnThruPtr_tofu(tofu)" + - " Pine_CMockReturnMemThruPtr_tofu(__LINE__, tofu, sizeof(*tofu))\n" + - "#define Pine_ReturnArrayThruPtr_tofu(tofu, cmock_len)" + - " Pine_CMockReturnMemThruPtr_tofu(__LINE__, tofu, (int)(cmock_len * (int)sizeof(*tofu)))\n" + - "#define Pine_ReturnMemThruPtr_tofu(tofu, cmock_size)" + - " Pine_CMockReturnMemThruPtr_tofu(__LINE__, tofu, cmock_size)\n" + - "void Pine_CMockReturnMemThruPtr_tofu(UNITY_LINE_TYPE cmock_line, int* tofu, int cmock_size);\n" - - returned = @cmock_generator_plugin_return_thru_ptr.mock_function_declarations(@complex_func) - assert_equal(expected, returned) - end - - it "add mock interfaces only for non-const pointer arguments" do - complex_func_expect(); - - expected = - "void Pine_CMockReturnMemThruPtr_tofu(UNITY_LINE_TYPE cmock_line, int* tofu, int cmock_size)\n" + - "{\n" + - " CMOCK_Pine_CALL_INSTANCE* cmock_call_instance = " + - "(CMOCK_Pine_CALL_INSTANCE*)CMock_Guts_GetAddressFor(CMock_Guts_MemEndOfChain(Mock.Pine_CallInstance));\n" + - " UNITY_TEST_ASSERT_NOT_NULL(cmock_call_instance, cmock_line, CMockStringPtrPreExp);\n" + - " cmock_call_instance->ReturnThruPtr_tofu_Used = 1;\n" + - " cmock_call_instance->ReturnThruPtr_tofu_Val = tofu;\n" + - " cmock_call_instance->ReturnThruPtr_tofu_Size = cmock_size;\n" + - "}\n\n" - - returned = @cmock_generator_plugin_return_thru_ptr.mock_interfaces(@complex_func).join("") - assert_equal(expected, returned) - end - - it "add mock implementations only for non-const pointer arguments" do - complex_func_expect() - - expected = - " if (cmock_call_instance->ReturnThruPtr_tofu_Used)\n" + - " {\n" + - " memcpy(tofu, cmock_call_instance->ReturnThruPtr_tofu_Val,\n" + - " cmock_call_instance->ReturnThruPtr_tofu_Size);\n" + - " }\n" + - - returned = @cmock_generator_plugin_return_thru_ptr.mock_implementation(@complex_func).join("") - end - -end +# ========================================== +# CMock Project - Automatic Mock Generation for C +# Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams +# [Released under MIT License. Please refer to license.txt for details] +# ========================================== + +require File.expand_path(File.dirname(__FILE__)) + "/../test_helper" +require 'cmock_generator_plugin_return_thru_ptr' + +describe CMockGeneratorPluginReturnThruPtr, "Verify CMockGeneratorPluginReturnThruPtr Module" do + + before do + create_mocks :config, :utils + + # int *Oak(void)" + @void_func = {:name => "Oak", :args => [], :return => test_return[:int_ptr]} + + # char *Maple(int blah) + @simple_func = {:name => "Maple", + :args => [{:name => "blah", :type => "int", :ptr? => false}], + :return => test_return[:string], + :contains_ptr? => false} + + # void Pine(int chicken, const int beef, int *tofu) + @complex_func = {:name => "Pine", + :args => [{ :type => "int", + :name => "chicken", + :ptr? => false, + }, + { :type => "int*", + :name => "beef", + :ptr? => true, + :const? => true, + }, + { :type => "int*", + :name => "tofu", + :ptr? => true, + }], + :return => test_return[:void], + :contains_ptr? => true } + + #no strict ordering + @cmock_generator_plugin_return_thru_ptr = CMockGeneratorPluginReturnThruPtr.new(@config, @utils) + end + + after do + end + + def simple_func_expect + @utils.expect :ptr_or_str?, false, ['int'] + end + + def complex_func_expect + @utils.expect :ptr_or_str?, false, ['int'] + @utils.expect :ptr_or_str?, true, ['int*'] + @utils.expect :ptr_or_str?, true, ['int*'] + end + + it "have set up internal priority correctly on init" do + assert_equal(1, @cmock_generator_plugin_return_thru_ptr.priority) + end + + it "not include any additional include files" do + assert(!@cmock_generator_plugin_return_thru_ptr.respond_to?(:include_files)) + end + + it "not add to typedef structure for functions of style 'int* func(void)'" do + returned = @cmock_generator_plugin_return_thru_ptr.instance_typedefs(@void_func) + assert_equal("", returned) + end + + it "add to tyepdef structure mock needs of functions of style 'void func(int chicken, int* pork)'" do + complex_func_expect() + expected = " int ReturnThruPtr_tofu_Used;\n" + + " int* ReturnThruPtr_tofu_Val;\n" + + " int ReturnThruPtr_tofu_Size;\n" + returned = @cmock_generator_plugin_return_thru_ptr.instance_typedefs(@complex_func) + assert_equal(expected, returned) + end + + it "not add an additional mock interface for functions not containing pointers" do + simple_func_expect() + returned = @cmock_generator_plugin_return_thru_ptr.mock_function_declarations(@simple_func) + assert_equal("", returned) + end + + it "add a mock function declaration only for non-const pointer arguments" do + complex_func_expect(); + + expected = + "#define Pine_ReturnThruPtr_tofu(tofu)" + + " Pine_CMockReturnMemThruPtr_tofu(__LINE__, tofu, sizeof(*tofu))\n" + + "#define Pine_ReturnArrayThruPtr_tofu(tofu, cmock_len)" + + " Pine_CMockReturnMemThruPtr_tofu(__LINE__, tofu, (int)(cmock_len * (int)sizeof(*tofu)))\n" + + "#define Pine_ReturnMemThruPtr_tofu(tofu, cmock_size)" + + " Pine_CMockReturnMemThruPtr_tofu(__LINE__, tofu, cmock_size)\n" + + "void Pine_CMockReturnMemThruPtr_tofu(UNITY_LINE_TYPE cmock_line, int* tofu, int cmock_size);\n" + + returned = @cmock_generator_plugin_return_thru_ptr.mock_function_declarations(@complex_func) + assert_equal(expected, returned) + end + + it "add mock interfaces only for non-const pointer arguments" do + complex_func_expect(); + + expected = + "void Pine_CMockReturnMemThruPtr_tofu(UNITY_LINE_TYPE cmock_line, int* tofu, int cmock_size)\n" + + "{\n" + + " CMOCK_Pine_CALL_INSTANCE* cmock_call_instance = " + + "(CMOCK_Pine_CALL_INSTANCE*)CMock_Guts_GetAddressFor(CMock_Guts_MemEndOfChain(Mock.Pine_CallInstance));\n" + + " UNITY_TEST_ASSERT_NOT_NULL(cmock_call_instance, cmock_line, CMockStringPtrPreExp);\n" + + " cmock_call_instance->ReturnThruPtr_tofu_Used = 1;\n" + + " cmock_call_instance->ReturnThruPtr_tofu_Val = tofu;\n" + + " cmock_call_instance->ReturnThruPtr_tofu_Size = cmock_size;\n" + + "}\n\n" + + returned = @cmock_generator_plugin_return_thru_ptr.mock_interfaces(@complex_func).join("") + assert_equal(expected, returned) + end + + it "add mock implementations only for non-const pointer arguments" do + complex_func_expect() + + expected = + " if (cmock_call_instance->ReturnThruPtr_tofu_Used)\n" + + " {\n" + + " memcpy(tofu, cmock_call_instance->ReturnThruPtr_tofu_Val,\n" + + " cmock_call_instance->ReturnThruPtr_tofu_Size);\n" + + " }\n" + + + returned = @cmock_generator_plugin_return_thru_ptr.mock_implementation(@complex_func).join("") + end + +end diff --git a/test/unit/cmock_generator_utils_test.rb b/test/unit/cmock_generator_utils_test.rb index 4bf253b..a233007 100644 --- a/test/unit/cmock_generator_utils_test.rb +++ b/test/unit/cmock_generator_utils_test.rb @@ -1,377 +1,377 @@ -# ========================================== -# CMock Project - Automatic Mock Generation for C -# Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams -# [Released under MIT License. Please refer to license.txt for details] -# ========================================== - -require File.expand_path(File.dirname(__FILE__)) + "/../test_helper" -require 'cmock_generator_utils' - -describe CMockGeneratorUtils, "Verify CMockGeneratorUtils Module" do - - before do - create_mocks :config, :unity_helper, :unity_helper - - @config.expect :when_ptr, :compare_ptr - @config.expect :enforce_strict_ordering, false - @config.expect :plugins, [] - @config.expect :plugins, [] - @config.expect :plugins, [] - @config.expect :plugins, [] - @config.expect :plugins, [] - @config.expect :plugins, [] - @config.expect :treat_as, {'int' => 'INT','short' => 'INT16','long' => 'INT','char' => 'INT8','char*' => 'STRING'} - @cmock_generator_utils_simple = CMockGeneratorUtils.new(@config, {:unity_helper => @unity_helper}) - - @config.expect :when_ptr, :smart - @config.expect :enforce_strict_ordering, true - @config.expect :plugins, [:array, :cexception, :return_thru_ptr, :ignore_arg, :ignore] - @config.expect :plugins, [:array, :cexception, :return_thru_ptr, :ignore_arg, :ignore] - @config.expect :plugins, [:array, :cexception, :return_thru_ptr, :ignore_arg, :ignore] - @config.expect :plugins, [:array, :cexception, :return_thru_ptr, :ignore_arg, :ignore] - @config.expect :plugins, [:array, :cexception, :return_thru_ptr, :ignore_arg, :ignore] - @config.expect :plugins, [:array, :cexception, :return_thru_ptr, :ignore_arg, :ignore] - @config.expect :treat_as, {'int' => 'INT','short' => 'INT16','long' => 'INT','char' => 'INT8','uint32_t' => 'HEX32','char*' => 'STRING'} - @cmock_generator_utils_complex = CMockGeneratorUtils.new(@config, {:unity_helper => @unity_helper, :A=>1, :B=>2}) - end - - after do - end - - it "have set up internal accessors correctly on init" do - assert_equal(false, @cmock_generator_utils_simple.arrays) - assert_equal(false, @cmock_generator_utils_simple.cexception) - end - - it "have set up internal accessors correctly on init, complete with passed helpers" do - assert_equal(true, @cmock_generator_utils_complex.arrays) - assert_equal(true, @cmock_generator_utils_complex.cexception) - end - - it "detect pointers and strings" do - assert_equal(false, @cmock_generator_utils_simple.ptr_or_str?('int')) - assert_equal(true, @cmock_generator_utils_simple.ptr_or_str?('int*')) - assert_equal(true, @cmock_generator_utils_simple.ptr_or_str?('char*')) - end - - it "add code for a base expectation with no plugins" do - expected = - " CMOCK_MEM_INDEX_TYPE cmock_guts_index = CMock_Guts_MemNew(sizeof(CMOCK_Apple_CALL_INSTANCE));\n" + - " CMOCK_Apple_CALL_INSTANCE* cmock_call_instance = (CMOCK_Apple_CALL_INSTANCE*)CMock_Guts_GetAddressFor(cmock_guts_index);\n" + - " UNITY_TEST_ASSERT_NOT_NULL(cmock_call_instance, cmock_line, CMockStringOutOfMemory);\n" + - " memset(cmock_call_instance, 0, sizeof(*cmock_call_instance));\n" + - " Mock.Apple_CallInstance = CMock_Guts_MemChain(Mock.Apple_CallInstance, cmock_guts_index);\n" + - " cmock_call_instance->LineNumber = cmock_line;\n" - output = @cmock_generator_utils_simple.code_add_base_expectation("Apple") - assert_equal(expected, output) - end - - it "add code for a base expectation with all plugins" do - expected = - " CMOCK_MEM_INDEX_TYPE cmock_guts_index = CMock_Guts_MemNew(sizeof(CMOCK_Apple_CALL_INSTANCE));\n" + - " CMOCK_Apple_CALL_INSTANCE* cmock_call_instance = (CMOCK_Apple_CALL_INSTANCE*)CMock_Guts_GetAddressFor(cmock_guts_index);\n" + - " UNITY_TEST_ASSERT_NOT_NULL(cmock_call_instance, cmock_line, CMockStringOutOfMemory);\n" + - " memset(cmock_call_instance, 0, sizeof(*cmock_call_instance));\n" + - " Mock.Apple_CallInstance = CMock_Guts_MemChain(Mock.Apple_CallInstance, cmock_guts_index);\n" + - " Mock.Apple_IgnoreBool = (int)0;\n" + - " cmock_call_instance->LineNumber = cmock_line;\n" + - " cmock_call_instance->CallOrder = ++GlobalExpectCount;\n" + - " cmock_call_instance->ExceptionToThrow = CEXCEPTION_NONE;\n" - output = @cmock_generator_utils_complex.code_add_base_expectation("Apple", true) - assert_equal(expected, output) - end - - it "add code for a base expectation with all plugins and ordering not supported" do - expected = - " CMOCK_MEM_INDEX_TYPE cmock_guts_index = CMock_Guts_MemNew(sizeof(CMOCK_Apple_CALL_INSTANCE));\n" + - " CMOCK_Apple_CALL_INSTANCE* cmock_call_instance = (CMOCK_Apple_CALL_INSTANCE*)CMock_Guts_GetAddressFor(cmock_guts_index);\n" + - " UNITY_TEST_ASSERT_NOT_NULL(cmock_call_instance, cmock_line, CMockStringOutOfMemory);\n" + - " memset(cmock_call_instance, 0, sizeof(*cmock_call_instance));\n" + - " Mock.Apple_CallInstance = CMock_Guts_MemChain(Mock.Apple_CallInstance, cmock_guts_index);\n" + - " Mock.Apple_IgnoreBool = (int)0;\n" + - " cmock_call_instance->LineNumber = cmock_line;\n" + - " cmock_call_instance->ExceptionToThrow = CEXCEPTION_NONE;\n" - output = @cmock_generator_utils_complex.code_add_base_expectation("Apple", false) - assert_equal(expected, output) - end - - it "add argument expectations for values when no array plugin" do - arg1 = { :name => "Orange", :const? => false, :type => 'int', :ptr? => false } - expected1 = " cmock_call_instance->Expected_Orange = Orange;\n" - - arg2 = { :name => "Lemon", :const? => true, :type => 'const char*', :ptr? => true } - expected2 = " cmock_call_instance->Expected_Lemon = (const char*)Lemon;\n" - - arg3 = { :name => "Kiwi", :const? => false, :type => 'KIWI_T*', :ptr? => true } - expected3 = " cmock_call_instance->Expected_Kiwi = Kiwi;\n" - - arg4 = { :name => "Lime", :const? => false, :type => 'LIME_T', :ptr? => false } - expected4 = " memcpy(&cmock_call_instance->Expected_Lime, &Lime, sizeof(LIME_T));\n" - - assert_equal(expected1, @cmock_generator_utils_simple.code_add_an_arg_expectation(arg1)) - assert_equal(expected2, @cmock_generator_utils_simple.code_add_an_arg_expectation(arg2)) - assert_equal(expected3, @cmock_generator_utils_simple.code_add_an_arg_expectation(arg3)) - assert_equal(expected4, @cmock_generator_utils_simple.code_add_an_arg_expectation(arg4)) - end - - it "add argument expectations for values when array plugin enabled" do - arg1 = { :name => "Orange", :const? => false, :type => 'int', :ptr? => false } - expected1 = " cmock_call_instance->Expected_Orange = Orange;\n" + - " cmock_call_instance->IgnoreArg_Orange = 0;\n" - - arg2 = { :name => "Lemon", :const? => true, :type => 'const char*', :ptr? => true } - expected2 = " cmock_call_instance->Expected_Lemon = (const char*)Lemon;\n" + - " cmock_call_instance->Expected_Lemon_Depth = Lemon_Depth;\n" + - " cmock_call_instance->IgnoreArg_Lemon = 0;\n" - - arg3 = { :name => "Kiwi", :const? => false, :type => 'KIWI_T*', :ptr? => true } - expected3 = " cmock_call_instance->Expected_Kiwi = Kiwi;\n" + - " cmock_call_instance->Expected_Kiwi_Depth = Kiwi_Depth;\n" + - " cmock_call_instance->IgnoreArg_Kiwi = 0;\n" + - " cmock_call_instance->ReturnThruPtr_Kiwi_Used = 0;\n" - - arg4 = { :name => "Lime", :const? => false, :type => 'LIME_T', :ptr? => false } - expected4 = " memcpy(&cmock_call_instance->Expected_Lime, &Lime, sizeof(LIME_T));\n" + - " cmock_call_instance->IgnoreArg_Lime = 0;\n" - - assert_equal(expected1, @cmock_generator_utils_complex.code_add_an_arg_expectation(arg1)) - assert_equal(expected2, @cmock_generator_utils_complex.code_add_an_arg_expectation(arg2, 'Lemon_Depth')) - assert_equal(expected3, @cmock_generator_utils_complex.code_add_an_arg_expectation(arg3, 'Lemon_Depth')) - assert_equal(expected4, @cmock_generator_utils_complex.code_add_an_arg_expectation(arg4)) - end - - it 'not have an argument loader when the function has no arguments' do - function = { :name => "Melon", :args_string => "void" } - - assert_equal("", @cmock_generator_utils_complex.code_add_argument_loader(function)) - end - - it 'create an argument loader when the function has arguments' do - function = { :name => "Melon", - :args_string => "stuff", - :args => [test_arg[:int_ptr], test_arg[:mytype], test_arg[:string]] - } - expected = "void CMockExpectParameters_Melon(CMOCK_Melon_CALL_INSTANCE* cmock_call_instance, stuff)\n{\n" + - " cmock_call_instance->Expected_MyIntPtr = MyIntPtr;\n" + - " memcpy(&cmock_call_instance->Expected_MyMyType, &MyMyType, sizeof(MY_TYPE));\n" + - " cmock_call_instance->Expected_MyStr = (char*)MyStr;\n" + - "}\n\n" - assert_equal(expected, @cmock_generator_utils_simple.code_add_argument_loader(function)) - end - - it 'create an argument loader when the function has arguments supporting arrays' do - function = { :name => "Melon", - :args_string => "stuff", - :args => [test_arg[:int_ptr], test_arg[:mytype], test_arg[:string]] - } - expected = "void CMockExpectParameters_Melon(CMOCK_Melon_CALL_INSTANCE* cmock_call_instance, int* MyIntPtr, int MyIntPtr_Depth, const MY_TYPE MyMyType, const char* MyStr)\n{\n" + - " cmock_call_instance->Expected_MyIntPtr = MyIntPtr;\n" + - " cmock_call_instance->Expected_MyIntPtr_Depth = MyIntPtr_Depth;\n" + - " cmock_call_instance->IgnoreArg_MyIntPtr = 0;\n" + - " cmock_call_instance->ReturnThruPtr_MyIntPtr_Used = 0;\n" + - " memcpy(&cmock_call_instance->Expected_MyMyType, &MyMyType, sizeof(MY_TYPE));\n" + - " cmock_call_instance->IgnoreArg_MyMyType = 0;\n" + - " cmock_call_instance->Expected_MyStr = (char*)MyStr;\n" + - " cmock_call_instance->IgnoreArg_MyStr = 0;\n" + - "}\n\n" - assert_equal(expected, @cmock_generator_utils_complex.code_add_argument_loader(function)) - end - - it "not call argument loader if there are no arguments to actually use for this function" do - function = { :name => "Pineapple", :args_string => "void" } - - assert_equal("", @cmock_generator_utils_complex.code_call_argument_loader(function)) - end - - it 'call an argument loader when the function has arguments' do - function = { :name => "Pineapple", - :args_string => "stuff", - :args => [test_arg[:int_ptr], test_arg[:mytype], test_arg[:string]] - } - expected = " CMockExpectParameters_Pineapple(cmock_call_instance, MyIntPtr, MyMyType, MyStr);\n" - assert_equal(expected, @cmock_generator_utils_simple.code_call_argument_loader(function)) - end - - it 'call an argument loader when the function has arguments with arrays' do - function = { :name => "Pineapple", - :args_string => "stuff", - :args => [test_arg[:int_ptr], test_arg[:mytype], test_arg[:string]] - } - expected = " CMockExpectParameters_Pineapple(cmock_call_instance, MyIntPtr, 1, MyMyType, MyStr);\n" - assert_equal(expected, @cmock_generator_utils_complex.code_call_argument_loader(function)) - end - - it 'handle a simple assert when requested' do - function = { :name => 'Pear' } - arg = test_arg[:int] - expected = " {\n" + - " UNITY_SET_DETAILS(CMockString_Pear,CMockString_MyInt);\n" + - " UNITY_TEST_ASSERT_EQUAL_INT(cmock_call_instance->Expected_MyInt, MyInt, cmock_line, CMockStringMismatch);\n" + - " }\n" - @unity_helper.expect :nil?, false - @unity_helper.expect :get_helper, ['UNITY_TEST_ASSERT_EQUAL_INT', ''], ['int'] - assert_equal(expected, @cmock_generator_utils_simple.code_verify_an_arg_expectation(function, arg)) - end - - it 'handle a pointer comparison when configured to do so' do - function = { :name => 'Pear' } - arg = test_arg[:int_ptr] - expected = " {\n" + - " UNITY_SET_DETAILS(CMockString_Pear,CMockString_MyIntPtr);\n" + - " UNITY_TEST_ASSERT_EQUAL_PTR(cmock_call_instance->Expected_MyIntPtr, MyIntPtr, cmock_line, CMockStringMismatch);\n" + - " }\n" - assert_equal(expected, @cmock_generator_utils_simple.code_verify_an_arg_expectation(function, arg)) - end - - it 'handle const char as string compares ' do - function = { :name => 'Pear' } - arg = test_arg[:string] - expected = " {\n" + - " UNITY_SET_DETAILS(CMockString_Pear,CMockString_MyStr);\n" + - " UNITY_TEST_ASSERT_EQUAL_STRING(cmock_call_instance->Expected_MyStr, MyStr, cmock_line, CMockStringMismatch);\n" + - " }\n" - @unity_helper.expect :nil?, false - @unity_helper.expect :get_helper, ['UNITY_TEST_ASSERT_EQUAL_STRING',''], ['char*'] - assert_equal(expected, @cmock_generator_utils_simple.code_verify_an_arg_expectation(function, arg)) - end - - it 'handle custom types as memory compares when we have no better way to do it' do - function = { :name => 'Pear' } - arg = test_arg[:mytype] - expected = " {\n" + - " UNITY_SET_DETAILS(CMockString_Pear,CMockString_MyMyType);\n" + - " UNITY_TEST_ASSERT_EQUAL_MEMORY((void*)(&cmock_call_instance->Expected_MyMyType), (void*)(&MyMyType), sizeof(MY_TYPE), cmock_line, CMockStringMismatch);\n" + - " }\n" - @unity_helper.expect :nil?, false - @unity_helper.expect :get_helper, ['UNITY_TEST_ASSERT_EQUAL_MEMORY','&'], ['MY_TYPE'] - assert_equal(expected, @cmock_generator_utils_simple.code_verify_an_arg_expectation(function, arg)) - end - - it 'handle custom types with custom handlers when available, even if they do not support the extra message' do - function = { :name => 'Pear' } - arg = test_arg[:mytype] - expected = " {\n" + - " UNITY_SET_DETAILS(CMockString_Pear,CMockString_MyMyType);\n" + - " UNITY_TEST_ASSERT_EQUAL_MY_TYPE(cmock_call_instance->Expected_MyMyType, MyMyType, cmock_line, CMockStringMismatch);\n" + - " }\n" - @unity_helper.expect :nil?, false - @unity_helper.expect :get_helper, ['UNITY_TEST_ASSERT_EQUAL_MY_TYPE',''], ['MY_TYPE'] - assert_equal(expected, @cmock_generator_utils_simple.code_verify_an_arg_expectation(function, arg)) - end - - it 'handle pointers to custom types with array handlers, even if the array extension is turned off' do - function = { :name => 'Pear' } - arg = test_arg[:mytype] - expected = " {\n" + - " UNITY_SET_DETAILS(CMockString_Pear,CMockString_MyMyType);\n" + - " UNITY_TEST_ASSERT_EQUAL_MY_TYPE_ARRAY(&cmock_call_instance->Expected_MyMyType, &MyMyType, 1, cmock_line, CMockStringMismatch);\n" + - " }\n" - @unity_helper.expect :nil?, false - @unity_helper.expect :get_helper, ['UNITY_TEST_ASSERT_EQUAL_MY_TYPE_ARRAY','&'], ['MY_TYPE'] - assert_equal(expected, @cmock_generator_utils_simple.code_verify_an_arg_expectation(function, arg)) - end - - it 'handle a simple assert when requested with array plugin enabled' do - function = { :name => 'Pear' } - arg = test_arg[:int] - expected = " if (!cmock_call_instance->IgnoreArg_MyInt)\n" + - " {\n" + - " UNITY_SET_DETAILS(CMockString_Pear,CMockString_MyInt);\n" + - " UNITY_TEST_ASSERT_EQUAL_INT(cmock_call_instance->Expected_MyInt, MyInt, cmock_line, CMockStringMismatch);\n" + - " }\n" - @unity_helper.expect :nil?, false - @unity_helper.expect :get_helper, ['UNITY_TEST_ASSERT_EQUAL_INT',''], ['int'] - assert_equal(expected, @cmock_generator_utils_complex.code_verify_an_arg_expectation(function, arg)) - end - - it 'handle an array comparison with array plugin enabled' do - function = { :name => 'Pear' } - arg = test_arg[:int_ptr] - expected = " if (!cmock_call_instance->IgnoreArg_MyIntPtr)\n" + - " {\n" + - " UNITY_SET_DETAILS(CMockString_Pear,CMockString_MyIntPtr);\n" + - " if (cmock_call_instance->Expected_MyIntPtr == NULL)\n" + - " { UNITY_TEST_ASSERT_NULL(MyIntPtr, cmock_line, CMockStringExpNULL); }\n" + - " else if (cmock_call_instance->Expected_MyIntPtr_Depth == 0)\n" + - " { UNITY_TEST_ASSERT_EQUAL_PTR(cmock_call_instance->Expected_MyIntPtr, MyIntPtr, cmock_line, CMockStringMismatch); }\n" + - " else\n" + - " { UNITY_TEST_ASSERT_EQUAL_INT_ARRAY(cmock_call_instance->Expected_MyIntPtr, MyIntPtr, cmock_call_instance->Expected_MyIntPtr_Depth, cmock_line, CMockStringMismatch); }\n" + - " }\n" - @unity_helper.expect :nil?, false - @unity_helper.expect :get_helper, ['UNITY_TEST_ASSERT_EQUAL_INT_ARRAY',''], ['int*'] - assert_equal(expected, @cmock_generator_utils_complex.code_verify_an_arg_expectation(function, arg)) - end - - it 'handle const char as string compares with array plugin enabled' do - function = { :name => 'Pear' } - arg = test_arg[:string] - expected = " if (!cmock_call_instance->IgnoreArg_MyStr)\n" + - " {\n" + - " UNITY_SET_DETAILS(CMockString_Pear,CMockString_MyStr);\n" + - " UNITY_TEST_ASSERT_EQUAL_STRING(cmock_call_instance->Expected_MyStr, MyStr, cmock_line, CMockStringMismatch);\n" + - " }\n" - @unity_helper.expect :nil?, false - @unity_helper.expect :get_helper, ['UNITY_TEST_ASSERT_EQUAL_STRING',''], ['char*'] - assert_equal(expected, @cmock_generator_utils_complex.code_verify_an_arg_expectation(function, arg)) - end - - it 'handle custom types as memory compares when we have no better way to do it with array plugin enabled' do - function = { :name => 'Pear' } - arg = test_arg[:mytype] - expected = " if (!cmock_call_instance->IgnoreArg_MyMyType)\n" + - " {\n" + - " UNITY_SET_DETAILS(CMockString_Pear,CMockString_MyMyType);\n" + - " if (cmock_call_instance->Expected_MyMyType == NULL)\n" + - " { UNITY_TEST_ASSERT_NULL(MyMyType, cmock_line, CMockStringExpNULL); }\n" + - " else\n" + - " { UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY((void*)(cmock_call_instance->Expected_MyMyType), (void*)(MyMyType), sizeof(MY_TYPE), 1, cmock_line, CMockStringMismatch); }\n" + - " }\n" - @unity_helper.expect :nil?, false - @unity_helper.expect :get_helper, ['UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY', ''], ['MY_TYPE'] - assert_equal(expected, @cmock_generator_utils_complex.code_verify_an_arg_expectation(function, arg)) - end - - it 'handle custom types with custom handlers when available, even if they do not support the extra message with array plugin enabled' do - function = { :name => 'Pear' } - arg = test_arg[:mytype] - expected = " if (!cmock_call_instance->IgnoreArg_MyMyType)\n" + - " {\n" + - " UNITY_SET_DETAILS(CMockString_Pear,CMockString_MyMyType);\n" + - " UNITY_TEST_ASSERT_EQUAL_MY_TYPE(cmock_call_instance->Expected_MyMyType, MyMyType, cmock_line, CMockStringMismatch);\n" + - " }\n" - @unity_helper.expect :nil?, false - @unity_helper.expect :get_helper, ['UNITY_TEST_ASSERT_EQUAL_MY_TYPE', ''], ['MY_TYPE'] - assert_equal(expected, @cmock_generator_utils_complex.code_verify_an_arg_expectation(function, arg)) - end - - it 'handle custom types with array handlers when array plugin is enabled' do - function = { :name => 'Pear' } - arg = test_arg[:mytype_ptr] - expected = " if (!cmock_call_instance->IgnoreArg_MyMyTypePtr)\n" + - " {\n" + - " UNITY_SET_DETAILS(CMockString_Pear,CMockString_MyMyTypePtr);\n" + - " if (cmock_call_instance->Expected_MyMyTypePtr == NULL)\n" + - " { UNITY_TEST_ASSERT_NULL(MyMyTypePtr, cmock_line, CMockStringExpNULL); }\n" + - " else if (cmock_call_instance->Expected_MyMyTypePtr_Depth == 0)\n" + - " { UNITY_TEST_ASSERT_EQUAL_PTR(cmock_call_instance->Expected_MyMyTypePtr, MyMyTypePtr, cmock_line, CMockStringMismatch); }\n" + - " else\n" + - " { UNITY_TEST_ASSERT_EQUAL_MY_TYPE_ARRAY(cmock_call_instance->Expected_MyMyTypePtr, MyMyTypePtr, cmock_call_instance->Expected_MyMyTypePtr_Depth, cmock_line, CMockStringMismatch); }\n" + - " }\n" - @unity_helper.expect :nil?, false - @unity_helper.expect :get_helper, ['UNITY_TEST_ASSERT_EQUAL_MY_TYPE_ARRAY', ''], ['MY_TYPE*'] - assert_equal(expected, @cmock_generator_utils_complex.code_verify_an_arg_expectation(function, arg)) - end - - it 'handle custom types with array handlers when array plugin is enabled for non-array types' do - function = { :name => 'Pear' } - arg = test_arg[:mytype] - expected = " if (!cmock_call_instance->IgnoreArg_MyMyType)\n" + - " {\n" + - " UNITY_SET_DETAILS(CMockString_Pear,CMockString_MyMyType);\n" + - " UNITY_TEST_ASSERT_EQUAL_MY_TYPE_ARRAY(&cmock_call_instance->Expected_MyMyType, &MyMyType, 1, cmock_line, CMockStringMismatch);\n" + - " }\n" - @unity_helper.expect :nil?, false - @unity_helper.expect :get_helper, ['UNITY_TEST_ASSERT_EQUAL_MY_TYPE_ARRAY', '&'], ['MY_TYPE'] - assert_equal(expected, @cmock_generator_utils_complex.code_verify_an_arg_expectation(function, arg)) - end -end +# ========================================== +# CMock Project - Automatic Mock Generation for C +# Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams +# [Released under MIT License. Please refer to license.txt for details] +# ========================================== + +require File.expand_path(File.dirname(__FILE__)) + "/../test_helper" +require 'cmock_generator_utils' + +describe CMockGeneratorUtils, "Verify CMockGeneratorUtils Module" do + + before do + create_mocks :config, :unity_helper, :unity_helper + + @config.expect :when_ptr, :compare_ptr + @config.expect :enforce_strict_ordering, false + @config.expect :plugins, [] + @config.expect :plugins, [] + @config.expect :plugins, [] + @config.expect :plugins, [] + @config.expect :plugins, [] + @config.expect :plugins, [] + @config.expect :treat_as, {'int' => 'INT','short' => 'INT16','long' => 'INT','char' => 'INT8','char*' => 'STRING'} + @cmock_generator_utils_simple = CMockGeneratorUtils.new(@config, {:unity_helper => @unity_helper}) + + @config.expect :when_ptr, :smart + @config.expect :enforce_strict_ordering, true + @config.expect :plugins, [:array, :cexception, :return_thru_ptr, :ignore_arg, :ignore] + @config.expect :plugins, [:array, :cexception, :return_thru_ptr, :ignore_arg, :ignore] + @config.expect :plugins, [:array, :cexception, :return_thru_ptr, :ignore_arg, :ignore] + @config.expect :plugins, [:array, :cexception, :return_thru_ptr, :ignore_arg, :ignore] + @config.expect :plugins, [:array, :cexception, :return_thru_ptr, :ignore_arg, :ignore] + @config.expect :plugins, [:array, :cexception, :return_thru_ptr, :ignore_arg, :ignore] + @config.expect :treat_as, {'int' => 'INT','short' => 'INT16','long' => 'INT','char' => 'INT8','uint32_t' => 'HEX32','char*' => 'STRING'} + @cmock_generator_utils_complex = CMockGeneratorUtils.new(@config, {:unity_helper => @unity_helper, :A=>1, :B=>2}) + end + + after do + end + + it "have set up internal accessors correctly on init" do + assert_equal(false, @cmock_generator_utils_simple.arrays) + assert_equal(false, @cmock_generator_utils_simple.cexception) + end + + it "have set up internal accessors correctly on init, complete with passed helpers" do + assert_equal(true, @cmock_generator_utils_complex.arrays) + assert_equal(true, @cmock_generator_utils_complex.cexception) + end + + it "detect pointers and strings" do + assert_equal(false, @cmock_generator_utils_simple.ptr_or_str?('int')) + assert_equal(true, @cmock_generator_utils_simple.ptr_or_str?('int*')) + assert_equal(true, @cmock_generator_utils_simple.ptr_or_str?('char*')) + end + + it "add code for a base expectation with no plugins" do + expected = + " CMOCK_MEM_INDEX_TYPE cmock_guts_index = CMock_Guts_MemNew(sizeof(CMOCK_Apple_CALL_INSTANCE));\n" + + " CMOCK_Apple_CALL_INSTANCE* cmock_call_instance = (CMOCK_Apple_CALL_INSTANCE*)CMock_Guts_GetAddressFor(cmock_guts_index);\n" + + " UNITY_TEST_ASSERT_NOT_NULL(cmock_call_instance, cmock_line, CMockStringOutOfMemory);\n" + + " memset(cmock_call_instance, 0, sizeof(*cmock_call_instance));\n" + + " Mock.Apple_CallInstance = CMock_Guts_MemChain(Mock.Apple_CallInstance, cmock_guts_index);\n" + + " cmock_call_instance->LineNumber = cmock_line;\n" + output = @cmock_generator_utils_simple.code_add_base_expectation("Apple") + assert_equal(expected, output) + end + + it "add code for a base expectation with all plugins" do + expected = + " CMOCK_MEM_INDEX_TYPE cmock_guts_index = CMock_Guts_MemNew(sizeof(CMOCK_Apple_CALL_INSTANCE));\n" + + " CMOCK_Apple_CALL_INSTANCE* cmock_call_instance = (CMOCK_Apple_CALL_INSTANCE*)CMock_Guts_GetAddressFor(cmock_guts_index);\n" + + " UNITY_TEST_ASSERT_NOT_NULL(cmock_call_instance, cmock_line, CMockStringOutOfMemory);\n" + + " memset(cmock_call_instance, 0, sizeof(*cmock_call_instance));\n" + + " Mock.Apple_CallInstance = CMock_Guts_MemChain(Mock.Apple_CallInstance, cmock_guts_index);\n" + + " Mock.Apple_IgnoreBool = (int)0;\n" + + " cmock_call_instance->LineNumber = cmock_line;\n" + + " cmock_call_instance->CallOrder = ++GlobalExpectCount;\n" + + " cmock_call_instance->ExceptionToThrow = CEXCEPTION_NONE;\n" + output = @cmock_generator_utils_complex.code_add_base_expectation("Apple", true) + assert_equal(expected, output) + end + + it "add code for a base expectation with all plugins and ordering not supported" do + expected = + " CMOCK_MEM_INDEX_TYPE cmock_guts_index = CMock_Guts_MemNew(sizeof(CMOCK_Apple_CALL_INSTANCE));\n" + + " CMOCK_Apple_CALL_INSTANCE* cmock_call_instance = (CMOCK_Apple_CALL_INSTANCE*)CMock_Guts_GetAddressFor(cmock_guts_index);\n" + + " UNITY_TEST_ASSERT_NOT_NULL(cmock_call_instance, cmock_line, CMockStringOutOfMemory);\n" + + " memset(cmock_call_instance, 0, sizeof(*cmock_call_instance));\n" + + " Mock.Apple_CallInstance = CMock_Guts_MemChain(Mock.Apple_CallInstance, cmock_guts_index);\n" + + " Mock.Apple_IgnoreBool = (int)0;\n" + + " cmock_call_instance->LineNumber = cmock_line;\n" + + " cmock_call_instance->ExceptionToThrow = CEXCEPTION_NONE;\n" + output = @cmock_generator_utils_complex.code_add_base_expectation("Apple", false) + assert_equal(expected, output) + end + + it "add argument expectations for values when no array plugin" do + arg1 = { :name => "Orange", :const? => false, :type => 'int', :ptr? => false } + expected1 = " cmock_call_instance->Expected_Orange = Orange;\n" + + arg2 = { :name => "Lemon", :const? => true, :type => 'const char*', :ptr? => true } + expected2 = " cmock_call_instance->Expected_Lemon = (const char*)Lemon;\n" + + arg3 = { :name => "Kiwi", :const? => false, :type => 'KIWI_T*', :ptr? => true } + expected3 = " cmock_call_instance->Expected_Kiwi = Kiwi;\n" + + arg4 = { :name => "Lime", :const? => false, :type => 'LIME_T', :ptr? => false } + expected4 = " memcpy(&cmock_call_instance->Expected_Lime, &Lime, sizeof(LIME_T));\n" + + assert_equal(expected1, @cmock_generator_utils_simple.code_add_an_arg_expectation(arg1)) + assert_equal(expected2, @cmock_generator_utils_simple.code_add_an_arg_expectation(arg2)) + assert_equal(expected3, @cmock_generator_utils_simple.code_add_an_arg_expectation(arg3)) + assert_equal(expected4, @cmock_generator_utils_simple.code_add_an_arg_expectation(arg4)) + end + + it "add argument expectations for values when array plugin enabled" do + arg1 = { :name => "Orange", :const? => false, :type => 'int', :ptr? => false } + expected1 = " cmock_call_instance->Expected_Orange = Orange;\n" + + " cmock_call_instance->IgnoreArg_Orange = 0;\n" + + arg2 = { :name => "Lemon", :const? => true, :type => 'const char*', :ptr? => true } + expected2 = " cmock_call_instance->Expected_Lemon = (const char*)Lemon;\n" + + " cmock_call_instance->Expected_Lemon_Depth = Lemon_Depth;\n" + + " cmock_call_instance->IgnoreArg_Lemon = 0;\n" + + arg3 = { :name => "Kiwi", :const? => false, :type => 'KIWI_T*', :ptr? => true } + expected3 = " cmock_call_instance->Expected_Kiwi = Kiwi;\n" + + " cmock_call_instance->Expected_Kiwi_Depth = Kiwi_Depth;\n" + + " cmock_call_instance->IgnoreArg_Kiwi = 0;\n" + + " cmock_call_instance->ReturnThruPtr_Kiwi_Used = 0;\n" + + arg4 = { :name => "Lime", :const? => false, :type => 'LIME_T', :ptr? => false } + expected4 = " memcpy(&cmock_call_instance->Expected_Lime, &Lime, sizeof(LIME_T));\n" + + " cmock_call_instance->IgnoreArg_Lime = 0;\n" + + assert_equal(expected1, @cmock_generator_utils_complex.code_add_an_arg_expectation(arg1)) + assert_equal(expected2, @cmock_generator_utils_complex.code_add_an_arg_expectation(arg2, 'Lemon_Depth')) + assert_equal(expected3, @cmock_generator_utils_complex.code_add_an_arg_expectation(arg3, 'Lemon_Depth')) + assert_equal(expected4, @cmock_generator_utils_complex.code_add_an_arg_expectation(arg4)) + end + + it 'not have an argument loader when the function has no arguments' do + function = { :name => "Melon", :args_string => "void" } + + assert_equal("", @cmock_generator_utils_complex.code_add_argument_loader(function)) + end + + it 'create an argument loader when the function has arguments' do + function = { :name => "Melon", + :args_string => "stuff", + :args => [test_arg[:int_ptr], test_arg[:mytype], test_arg[:string]] + } + expected = "void CMockExpectParameters_Melon(CMOCK_Melon_CALL_INSTANCE* cmock_call_instance, stuff)\n{\n" + + " cmock_call_instance->Expected_MyIntPtr = MyIntPtr;\n" + + " memcpy(&cmock_call_instance->Expected_MyMyType, &MyMyType, sizeof(MY_TYPE));\n" + + " cmock_call_instance->Expected_MyStr = (char*)MyStr;\n" + + "}\n\n" + assert_equal(expected, @cmock_generator_utils_simple.code_add_argument_loader(function)) + end + + it 'create an argument loader when the function has arguments supporting arrays' do + function = { :name => "Melon", + :args_string => "stuff", + :args => [test_arg[:int_ptr], test_arg[:mytype], test_arg[:string]] + } + expected = "void CMockExpectParameters_Melon(CMOCK_Melon_CALL_INSTANCE* cmock_call_instance, int* MyIntPtr, int MyIntPtr_Depth, const MY_TYPE MyMyType, const char* MyStr)\n{\n" + + " cmock_call_instance->Expected_MyIntPtr = MyIntPtr;\n" + + " cmock_call_instance->Expected_MyIntPtr_Depth = MyIntPtr_Depth;\n" + + " cmock_call_instance->IgnoreArg_MyIntPtr = 0;\n" + + " cmock_call_instance->ReturnThruPtr_MyIntPtr_Used = 0;\n" + + " memcpy(&cmock_call_instance->Expected_MyMyType, &MyMyType, sizeof(MY_TYPE));\n" + + " cmock_call_instance->IgnoreArg_MyMyType = 0;\n" + + " cmock_call_instance->Expected_MyStr = (char*)MyStr;\n" + + " cmock_call_instance->IgnoreArg_MyStr = 0;\n" + + "}\n\n" + assert_equal(expected, @cmock_generator_utils_complex.code_add_argument_loader(function)) + end + + it "not call argument loader if there are no arguments to actually use for this function" do + function = { :name => "Pineapple", :args_string => "void" } + + assert_equal("", @cmock_generator_utils_complex.code_call_argument_loader(function)) + end + + it 'call an argument loader when the function has arguments' do + function = { :name => "Pineapple", + :args_string => "stuff", + :args => [test_arg[:int_ptr], test_arg[:mytype], test_arg[:string]] + } + expected = " CMockExpectParameters_Pineapple(cmock_call_instance, MyIntPtr, MyMyType, MyStr);\n" + assert_equal(expected, @cmock_generator_utils_simple.code_call_argument_loader(function)) + end + + it 'call an argument loader when the function has arguments with arrays' do + function = { :name => "Pineapple", + :args_string => "stuff", + :args => [test_arg[:int_ptr], test_arg[:mytype], test_arg[:string]] + } + expected = " CMockExpectParameters_Pineapple(cmock_call_instance, MyIntPtr, 1, MyMyType, MyStr);\n" + assert_equal(expected, @cmock_generator_utils_complex.code_call_argument_loader(function)) + end + + it 'handle a simple assert when requested' do + function = { :name => 'Pear' } + arg = test_arg[:int] + expected = " {\n" + + " UNITY_SET_DETAILS(CMockString_Pear,CMockString_MyInt);\n" + + " UNITY_TEST_ASSERT_EQUAL_INT(cmock_call_instance->Expected_MyInt, MyInt, cmock_line, CMockStringMismatch);\n" + + " }\n" + @unity_helper.expect :nil?, false + @unity_helper.expect :get_helper, ['UNITY_TEST_ASSERT_EQUAL_INT', ''], ['int'] + assert_equal(expected, @cmock_generator_utils_simple.code_verify_an_arg_expectation(function, arg)) + end + + it 'handle a pointer comparison when configured to do so' do + function = { :name => 'Pear' } + arg = test_arg[:int_ptr] + expected = " {\n" + + " UNITY_SET_DETAILS(CMockString_Pear,CMockString_MyIntPtr);\n" + + " UNITY_TEST_ASSERT_EQUAL_PTR(cmock_call_instance->Expected_MyIntPtr, MyIntPtr, cmock_line, CMockStringMismatch);\n" + + " }\n" + assert_equal(expected, @cmock_generator_utils_simple.code_verify_an_arg_expectation(function, arg)) + end + + it 'handle const char as string compares ' do + function = { :name => 'Pear' } + arg = test_arg[:string] + expected = " {\n" + + " UNITY_SET_DETAILS(CMockString_Pear,CMockString_MyStr);\n" + + " UNITY_TEST_ASSERT_EQUAL_STRING(cmock_call_instance->Expected_MyStr, MyStr, cmock_line, CMockStringMismatch);\n" + + " }\n" + @unity_helper.expect :nil?, false + @unity_helper.expect :get_helper, ['UNITY_TEST_ASSERT_EQUAL_STRING',''], ['char*'] + assert_equal(expected, @cmock_generator_utils_simple.code_verify_an_arg_expectation(function, arg)) + end + + it 'handle custom types as memory compares when we have no better way to do it' do + function = { :name => 'Pear' } + arg = test_arg[:mytype] + expected = " {\n" + + " UNITY_SET_DETAILS(CMockString_Pear,CMockString_MyMyType);\n" + + " UNITY_TEST_ASSERT_EQUAL_MEMORY((void*)(&cmock_call_instance->Expected_MyMyType), (void*)(&MyMyType), sizeof(MY_TYPE), cmock_line, CMockStringMismatch);\n" + + " }\n" + @unity_helper.expect :nil?, false + @unity_helper.expect :get_helper, ['UNITY_TEST_ASSERT_EQUAL_MEMORY','&'], ['MY_TYPE'] + assert_equal(expected, @cmock_generator_utils_simple.code_verify_an_arg_expectation(function, arg)) + end + + it 'handle custom types with custom handlers when available, even if they do not support the extra message' do + function = { :name => 'Pear' } + arg = test_arg[:mytype] + expected = " {\n" + + " UNITY_SET_DETAILS(CMockString_Pear,CMockString_MyMyType);\n" + + " UNITY_TEST_ASSERT_EQUAL_MY_TYPE(cmock_call_instance->Expected_MyMyType, MyMyType, cmock_line, CMockStringMismatch);\n" + + " }\n" + @unity_helper.expect :nil?, false + @unity_helper.expect :get_helper, ['UNITY_TEST_ASSERT_EQUAL_MY_TYPE',''], ['MY_TYPE'] + assert_equal(expected, @cmock_generator_utils_simple.code_verify_an_arg_expectation(function, arg)) + end + + it 'handle pointers to custom types with array handlers, even if the array extension is turned off' do + function = { :name => 'Pear' } + arg = test_arg[:mytype] + expected = " {\n" + + " UNITY_SET_DETAILS(CMockString_Pear,CMockString_MyMyType);\n" + + " UNITY_TEST_ASSERT_EQUAL_MY_TYPE_ARRAY(&cmock_call_instance->Expected_MyMyType, &MyMyType, 1, cmock_line, CMockStringMismatch);\n" + + " }\n" + @unity_helper.expect :nil?, false + @unity_helper.expect :get_helper, ['UNITY_TEST_ASSERT_EQUAL_MY_TYPE_ARRAY','&'], ['MY_TYPE'] + assert_equal(expected, @cmock_generator_utils_simple.code_verify_an_arg_expectation(function, arg)) + end + + it 'handle a simple assert when requested with array plugin enabled' do + function = { :name => 'Pear' } + arg = test_arg[:int] + expected = " if (!cmock_call_instance->IgnoreArg_MyInt)\n" + + " {\n" + + " UNITY_SET_DETAILS(CMockString_Pear,CMockString_MyInt);\n" + + " UNITY_TEST_ASSERT_EQUAL_INT(cmock_call_instance->Expected_MyInt, MyInt, cmock_line, CMockStringMismatch);\n" + + " }\n" + @unity_helper.expect :nil?, false + @unity_helper.expect :get_helper, ['UNITY_TEST_ASSERT_EQUAL_INT',''], ['int'] + assert_equal(expected, @cmock_generator_utils_complex.code_verify_an_arg_expectation(function, arg)) + end + + it 'handle an array comparison with array plugin enabled' do + function = { :name => 'Pear' } + arg = test_arg[:int_ptr] + expected = " if (!cmock_call_instance->IgnoreArg_MyIntPtr)\n" + + " {\n" + + " UNITY_SET_DETAILS(CMockString_Pear,CMockString_MyIntPtr);\n" + + " if (cmock_call_instance->Expected_MyIntPtr == NULL)\n" + + " { UNITY_TEST_ASSERT_NULL(MyIntPtr, cmock_line, CMockStringExpNULL); }\n" + + " else if (cmock_call_instance->Expected_MyIntPtr_Depth == 0)\n" + + " { UNITY_TEST_ASSERT_EQUAL_PTR(cmock_call_instance->Expected_MyIntPtr, MyIntPtr, cmock_line, CMockStringMismatch); }\n" + + " else\n" + + " { UNITY_TEST_ASSERT_EQUAL_INT_ARRAY(cmock_call_instance->Expected_MyIntPtr, MyIntPtr, cmock_call_instance->Expected_MyIntPtr_Depth, cmock_line, CMockStringMismatch); }\n" + + " }\n" + @unity_helper.expect :nil?, false + @unity_helper.expect :get_helper, ['UNITY_TEST_ASSERT_EQUAL_INT_ARRAY',''], ['int*'] + assert_equal(expected, @cmock_generator_utils_complex.code_verify_an_arg_expectation(function, arg)) + end + + it 'handle const char as string compares with array plugin enabled' do + function = { :name => 'Pear' } + arg = test_arg[:string] + expected = " if (!cmock_call_instance->IgnoreArg_MyStr)\n" + + " {\n" + + " UNITY_SET_DETAILS(CMockString_Pear,CMockString_MyStr);\n" + + " UNITY_TEST_ASSERT_EQUAL_STRING(cmock_call_instance->Expected_MyStr, MyStr, cmock_line, CMockStringMismatch);\n" + + " }\n" + @unity_helper.expect :nil?, false + @unity_helper.expect :get_helper, ['UNITY_TEST_ASSERT_EQUAL_STRING',''], ['char*'] + assert_equal(expected, @cmock_generator_utils_complex.code_verify_an_arg_expectation(function, arg)) + end + + it 'handle custom types as memory compares when we have no better way to do it with array plugin enabled' do + function = { :name => 'Pear' } + arg = test_arg[:mytype] + expected = " if (!cmock_call_instance->IgnoreArg_MyMyType)\n" + + " {\n" + + " UNITY_SET_DETAILS(CMockString_Pear,CMockString_MyMyType);\n" + + " if (cmock_call_instance->Expected_MyMyType == NULL)\n" + + " { UNITY_TEST_ASSERT_NULL(MyMyType, cmock_line, CMockStringExpNULL); }\n" + + " else\n" + + " { UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY((void*)(cmock_call_instance->Expected_MyMyType), (void*)(MyMyType), sizeof(MY_TYPE), 1, cmock_line, CMockStringMismatch); }\n" + + " }\n" + @unity_helper.expect :nil?, false + @unity_helper.expect :get_helper, ['UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY', ''], ['MY_TYPE'] + assert_equal(expected, @cmock_generator_utils_complex.code_verify_an_arg_expectation(function, arg)) + end + + it 'handle custom types with custom handlers when available, even if they do not support the extra message with array plugin enabled' do + function = { :name => 'Pear' } + arg = test_arg[:mytype] + expected = " if (!cmock_call_instance->IgnoreArg_MyMyType)\n" + + " {\n" + + " UNITY_SET_DETAILS(CMockString_Pear,CMockString_MyMyType);\n" + + " UNITY_TEST_ASSERT_EQUAL_MY_TYPE(cmock_call_instance->Expected_MyMyType, MyMyType, cmock_line, CMockStringMismatch);\n" + + " }\n" + @unity_helper.expect :nil?, false + @unity_helper.expect :get_helper, ['UNITY_TEST_ASSERT_EQUAL_MY_TYPE', ''], ['MY_TYPE'] + assert_equal(expected, @cmock_generator_utils_complex.code_verify_an_arg_expectation(function, arg)) + end + + it 'handle custom types with array handlers when array plugin is enabled' do + function = { :name => 'Pear' } + arg = test_arg[:mytype_ptr] + expected = " if (!cmock_call_instance->IgnoreArg_MyMyTypePtr)\n" + + " {\n" + + " UNITY_SET_DETAILS(CMockString_Pear,CMockString_MyMyTypePtr);\n" + + " if (cmock_call_instance->Expected_MyMyTypePtr == NULL)\n" + + " { UNITY_TEST_ASSERT_NULL(MyMyTypePtr, cmock_line, CMockStringExpNULL); }\n" + + " else if (cmock_call_instance->Expected_MyMyTypePtr_Depth == 0)\n" + + " { UNITY_TEST_ASSERT_EQUAL_PTR(cmock_call_instance->Expected_MyMyTypePtr, MyMyTypePtr, cmock_line, CMockStringMismatch); }\n" + + " else\n" + + " { UNITY_TEST_ASSERT_EQUAL_MY_TYPE_ARRAY(cmock_call_instance->Expected_MyMyTypePtr, MyMyTypePtr, cmock_call_instance->Expected_MyMyTypePtr_Depth, cmock_line, CMockStringMismatch); }\n" + + " }\n" + @unity_helper.expect :nil?, false + @unity_helper.expect :get_helper, ['UNITY_TEST_ASSERT_EQUAL_MY_TYPE_ARRAY', ''], ['MY_TYPE*'] + assert_equal(expected, @cmock_generator_utils_complex.code_verify_an_arg_expectation(function, arg)) + end + + it 'handle custom types with array handlers when array plugin is enabled for non-array types' do + function = { :name => 'Pear' } + arg = test_arg[:mytype] + expected = " if (!cmock_call_instance->IgnoreArg_MyMyType)\n" + + " {\n" + + " UNITY_SET_DETAILS(CMockString_Pear,CMockString_MyMyType);\n" + + " UNITY_TEST_ASSERT_EQUAL_MY_TYPE_ARRAY(&cmock_call_instance->Expected_MyMyType, &MyMyType, 1, cmock_line, CMockStringMismatch);\n" + + " }\n" + @unity_helper.expect :nil?, false + @unity_helper.expect :get_helper, ['UNITY_TEST_ASSERT_EQUAL_MY_TYPE_ARRAY', '&'], ['MY_TYPE'] + assert_equal(expected, @cmock_generator_utils_complex.code_verify_an_arg_expectation(function, arg)) + end +end