From d6efa5b88a7194ebf72c3fa93a37c9d881aa5e28 Mon Sep 17 00:00:00 2001 From: Mark VanderVoord Date: Thu, 7 Jan 2016 13:38:59 -0500 Subject: [PATCH] Fix numerous small errors concerning precedence of plugins, particularly related to callbacks, return_thru_ptr, and expect_any_args --- lib/cmock.rb | 178 ++-- lib/cmock_generator.rb | 1 - lib/cmock_generator_plugin_callback.rb | 32 +- lib/cmock_generator_plugin_expect.rb | 18 +- lib/cmock_generator_plugin_expect_any_args.rb | 24 +- lib/cmock_generator_plugin_return_thru_ptr.rb | 2 +- .../test_interactions/all_plugins_coexist.yml | 848 ++++++++++-------- .../doesnt_leave_details_behind.yml | 4 +- .../cmock_generator_plugin_callback_test.rb | 94 +- .../cmock_generator_plugin_expect_a_test.rb | 186 ++++ ...k_generator_plugin_expect_any_args_test.rb | 25 +- ...> cmock_generator_plugin_expect_b_test.rb} | 44 +- ...k_generator_plugin_return_thru_ptr_test.rb | 2 +- 13 files changed, 893 insertions(+), 565 deletions(-) create mode 100644 test/unit/cmock_generator_plugin_expect_a_test.rb rename test/unit/{cmock_generator_plugin_expect_test.rb => cmock_generator_plugin_expect_b_test.rb} (90%) diff --git a/lib/cmock.rb b/lib/cmock.rb index 1727815..b6ee7a9 100644 --- a/lib/cmock.rb +++ b/lib/cmock.rb @@ -1,89 +1,89 @@ -# ========================================== -# CMock Project - Automatic Mock Generation for C -# Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams -# [Released under MIT License. Please refer to license.txt for details] -# ========================================== - -[ "../config/production_environment", - "cmock_header_parser", - "cmock_generator", - "cmock_file_writer", - "cmock_config", - "cmock_plugin_manager", - "cmock_generator_utils", - "cmock_unityhelper_parser"].each {|req| require "#{File.expand_path(File.dirname(__FILE__))}/#{req}"} - - -$QUICK_RUBY_VERSION = RUBY_VERSION.split('.').inject(0){|vv,v| vv * 100 + v.to_i } - -class CMock - - def initialize(options=nil) - cm_config = CMockConfig.new(options) - cm_unityhelper = CMockUnityHelperParser.new(cm_config) - cm_writer = CMockFileWriter.new(cm_config) - cm_gen_utils = CMockGeneratorUtils.new(cm_config, {:unity_helper => cm_unityhelper}) - cm_gen_plugins = CMockPluginManager.new(cm_config, cm_gen_utils) - @cm_parser = CMockHeaderParser.new(cm_config) - @cm_generator = CMockGenerator.new(cm_config, cm_writer, cm_gen_utils, cm_gen_plugins) - @silent = (cm_config.verbosity < 2) - end - - def setup_mocks(files) - [files].flatten.each do |src| - generate_mock src - end - end - - private ############################### - - def generate_mock(src) - name = File.basename(src, '.h') - puts "Creating mock for #{name}..." unless @silent - @cm_generator.create_mock(name, @cm_parser.parse(name, File.read(src))) - end -end - -def option_maker(options, key, val) - options = options || {} - options[key.to_sym] = - if val.chr == ":" - val[1..-1].to_sym - elsif val.include? ";" - val.split(';') - elsif val == 'true' - true - elsif val == 'false' - false - elsif val =~ /^\d+$/ - val.to_i - else - val - end - options -end - - # Command Line Support ############################### - -if ($0 == __FILE__) - usage = "usage: ruby #{__FILE__} (-oOptionsFile) File(s)ToMock" - - if (!ARGV[0]) - puts usage - exit 1 - end - - options = {} - filelist = [] - ARGV.each do |arg| - if (arg =~ /^-o\"?([a-zA-Z0-9._\\\/:\s]+)\"?/) - options.merge! CMockConfig.load_config_file_from_yaml( arg.gsub(/^-o/,'') ) - elsif (arg =~ /^--([a-zA-Z0-9._\\\/:\s]+)=\"?([a-zA-Z0-9._\-\\\/:\s\;]+)\"?/) - options = option_maker(options, $1, $2) - else - filelist << arg - end - end - - CMock.new(options).setup_mocks(filelist) -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] +# ========================================== + +[ "../config/production_environment", + "cmock_header_parser", + "cmock_generator", + "cmock_file_writer", + "cmock_config", + "cmock_plugin_manager", + "cmock_generator_utils", + "cmock_unityhelper_parser"].each {|req| require "#{File.expand_path(File.dirname(__FILE__))}/#{req}"} + + +$QUICK_RUBY_VERSION = RUBY_VERSION.split('.').inject(0){|vv,v| vv * 100 + v.to_i } + +class CMock + + def initialize(options=nil) + cm_config = CMockConfig.new(options) + cm_unityhelper = CMockUnityHelperParser.new(cm_config) + cm_writer = CMockFileWriter.new(cm_config) + cm_gen_utils = CMockGeneratorUtils.new(cm_config, {:unity_helper => cm_unityhelper}) + cm_gen_plugins = CMockPluginManager.new(cm_config, cm_gen_utils) + @cm_parser = CMockHeaderParser.new(cm_config) + @cm_generator = CMockGenerator.new(cm_config, cm_writer, cm_gen_utils, cm_gen_plugins) + @silent = (cm_config.verbosity < 2) + end + + def setup_mocks(files) + [files].flatten.each do |src| + generate_mock src + end + end + + private ############################### + + def generate_mock(src) + name = File.basename(src, '.h') + puts "Creating mock for #{name}..." unless @silent + @cm_generator.create_mock(name, @cm_parser.parse(name, File.read(src))) + end +end + +def option_maker(options, key, val) + options = options || {} + options[key.to_sym] = + if val.chr == ":" + val[1..-1].to_sym + elsif val.include? ";" + val.split(';') + elsif val == 'true' + true + elsif val == 'false' + false + elsif val =~ /^\d+$/ + val.to_i + else + val + end + options +end + + # Command Line Support ############################### + +if ($0 == __FILE__) + usage = "usage: ruby #{__FILE__} (-oOptionsFile) File(s)ToMock" + + if (!ARGV[0]) + puts usage + exit 1 + end + + options = {} + filelist = [] + ARGV.each do |arg| + if (arg =~ /^-o\"?([a-zA-Z0-9._\\\/:\s]+)\"?/) + options.merge! CMockConfig.load_config_file_from_yaml( arg.gsub(/^-o/,'') ) + elsif (arg =~ /^--([a-zA-Z0-9._\\\/:\s]+)=\"?([a-zA-Z0-9._\-\\\/:\s\;]+)\"?/) + options = option_maker(options, $1, $2) + else + filelist << arg + end + end + + CMock.new(options).setup_mocks(filelist) +end diff --git a/lib/cmock_generator.rb b/lib/cmock_generator.rb index f2a1e13..495398e 100644 --- a/lib/cmock_generator.rb +++ b/lib/cmock_generator.rb @@ -219,7 +219,6 @@ class CMockGenerator 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) diff --git a/lib/cmock_generator_plugin_callback.rb b/lib/cmock_generator_plugin_callback.rb index 3a41ac0..761b3f4 100644 --- a/lib/cmock_generator_plugin_callback.rb +++ b/lib/cmock_generator_plugin_callback.rb @@ -17,10 +17,10 @@ class CMockGeneratorPluginCallback @include_count = @config.callback_include_count if (@config.callback_after_arg_check) - alias :mock_implementation :mock_implementation_for_callbacks + alias :mock_implementation :mock_implementation_for_callbacks_after_arg_check alias :mock_implementation_precheck :nothing else - alias :mock_implementation_precheck :mock_implementation_for_callbacks + alias :mock_implementation_precheck :mock_implementation_for_callbacks_without_arg_check alias :mock_implementation :nothing end end @@ -39,8 +39,26 @@ class CMockGeneratorPluginCallback "typedef #{return_type} (* CMOCK_#{func_name}_CALLBACK)(#{styles[style]});\nvoid #{func_name}_StubWithCallback(CMOCK_#{func_name}_CALLBACK Callback);\n" end - def mock_implementation_for_callbacks(function) + def mock_implementation_for_callbacks_after_arg_check(function) func_name = function[:name] + return_cast = function[:return][:const?] ? "(#{function[:return][:type]})" : "" + style = (@include_count ? 1 : 0) | (function[:args].empty? ? 0 : 2) | (function[:return][:void?] ? 0 : 4) + " if (Mock.#{func_name}_CallbackFunctionPointer != NULL)\n {\n" + + case(style) + when 0 then " Mock.#{func_name}_CallbackFunctionPointer();\n }\n" + when 1 then " Mock.#{func_name}_CallbackFunctionPointer(Mock.#{func_name}_CallbackCalls++);\n }\n" + when 2 then " Mock.#{func_name}_CallbackFunctionPointer(#{function[:args].map{|m| m[:name]}.join(', ')});\n }\n" + when 3 then " Mock.#{func_name}_CallbackFunctionPointer(#{function[:args].map{|m| m[:name]}.join(', ')}, Mock.#{func_name}_CallbackCalls++);\n }\n" + when 4 then " cmock_call_instance->ReturnVal = #{return_cast}Mock.#{func_name}_CallbackFunctionPointer();\n }\n" + when 5 then " cmock_call_instance->ReturnVal = #{return_cast}Mock.#{func_name}_CallbackFunctionPointer(Mock.#{func_name}_CallbackCalls++);\n }\n" + when 6 then " cmock_call_instance->ReturnVal = #{return_cast}Mock.#{func_name}_CallbackFunctionPointer(#{function[:args].map{|m| m[:name]}.join(', ')});\n }\n" + when 7 then " cmock_call_instance->ReturnVal = #{return_cast}Mock.#{func_name}_CallbackFunctionPointer(#{function[:args].map{|m| m[:name]}.join(', ')}, Mock.#{func_name}_CallbackCalls++);\n }\n" + end + end + + def mock_implementation_for_callbacks_without_arg_check(function) + func_name = function[:name] + return_cast = function[:return][:const?] ? "(#{function[:return][:type]})" : "" style = (@include_count ? 1 : 0) | (function[:args].empty? ? 0 : 2) | (function[:return][:void?] ? 0 : 4) " if (Mock.#{func_name}_CallbackFunctionPointer != NULL)\n {\n" + case(style) @@ -48,10 +66,10 @@ class CMockGeneratorPluginCallback when 1 then " Mock.#{func_name}_CallbackFunctionPointer(Mock.#{func_name}_CallbackCalls++);\n return;\n }\n" when 2 then " Mock.#{func_name}_CallbackFunctionPointer(#{function[:args].map{|m| m[:name]}.join(', ')});\n return;\n }\n" when 3 then " Mock.#{func_name}_CallbackFunctionPointer(#{function[:args].map{|m| m[:name]}.join(', ')}, Mock.#{func_name}_CallbackCalls++);\n return;\n }\n" - when 4 then " return Mock.#{func_name}_CallbackFunctionPointer();\n }\n" - when 5 then " return Mock.#{func_name}_CallbackFunctionPointer(Mock.#{func_name}_CallbackCalls++);\n }\n" - when 6 then " return Mock.#{func_name}_CallbackFunctionPointer(#{function[:args].map{|m| m[:name]}.join(', ')});\n }\n" - when 7 then " return Mock.#{func_name}_CallbackFunctionPointer(#{function[:args].map{|m| m[:name]}.join(', ')}, Mock.#{func_name}_CallbackCalls++);\n }\n" + when 4 then " return #{return_cast}Mock.#{func_name}_CallbackFunctionPointer();\n }\n" + when 5 then " return #{return_cast}Mock.#{func_name}_CallbackFunctionPointer(Mock.#{func_name}_CallbackCalls++);\n }\n" + when 6 then " return #{return_cast}Mock.#{func_name}_CallbackFunctionPointer(#{function[:args].map{|m| m[:name]}.join(', ')});\n }\n" + when 7 then " return #{return_cast}Mock.#{func_name}_CallbackFunctionPointer(#{function[:args].map{|m| m[:name]}.join(', ')}, Mock.#{func_name}_CallbackCalls++);\n }\n" end end diff --git a/lib/cmock_generator_plugin_expect.rb b/lib/cmock_generator_plugin_expect.rb index b0e3aa8..07079d3 100644 --- a/lib/cmock_generator_plugin_expect.rb +++ b/lib/cmock_generator_plugin_expect.rb @@ -16,6 +16,12 @@ class CMockGeneratorPluginExpect @utils = utils @unity_helper = @utils.helpers[:unity_helper] @priority = 5 + + if (@config.plugins.include? :expect_any_args) + alias :mock_implementation :mock_implementation_might_check_args + else + alias :mock_implementation :mock_implementation_always_check_args + end end def instance_typedefs(function) @@ -48,7 +54,7 @@ class CMockGeneratorPluginExpect end end - def mock_implementation(function) + def mock_implementation_always_check_args(function) lines = "" function[:args].each do |arg| lines << @utils.code_verify_an_arg_expectation(function, arg) @@ -56,6 +62,16 @@ class CMockGeneratorPluginExpect lines end + def mock_implementation_might_check_args(function) + return "" if (function[:args].empty?) + lines = " if (cmock_call_instance->IgnoreMode != CMOCK_ARG_NONE)\n {\n" + function[:args].each do |arg| + lines << @utils.code_verify_an_arg_expectation(function, arg) + end + lines << "\n }\n" + lines + end + def mock_interfaces(function) lines = "" func_name = function[:name] diff --git a/lib/cmock_generator_plugin_expect_any_args.rb b/lib/cmock_generator_plugin_expect_any_args.rb index 11be7d3..31752ba 100644 --- a/lib/cmock_generator_plugin_expect_any_args.rb +++ b/lib/cmock_generator_plugin_expect_any_args.rb @@ -38,18 +38,18 @@ class CMockGeneratorPluginExpectAnyArgs end end - def mock_implementation(function) - lines = " if (cmock_call_instance->IgnoreMode == CMOCK_ARG_NONE)\n {\n" - if (function[:return][:void?]) - lines << " return;\n }\n" - else - retval = function[:return].merge( { :name => "cmock_call_instance->ReturnVal"} ) - lines << " " + @utils.code_assign_argument_quickly("Mock.#{function[:name]}_FinalReturn", retval) unless (retval[:void?]) - return_type = function[:return][:const?] ? "(const #{function[:return][:type]})" : ((function[:return][:type] =~ /cmock/) ? "(#{function[:return][:type]})" : '') - lines << " return #{return_type}cmock_call_instance->ReturnVal;\n }\n" - end - lines - end + # def mock_implementation(function) + # lines = " if (cmock_call_instance->IgnoreMode == CMOCK_ARG_NONE)\n {\n" + # if (function[:return][:void?]) + # lines << " return;\n }\n" + # else + # retval = function[:return].merge( { :name => "cmock_call_instance->ReturnVal"} ) + # lines << " " + @utils.code_assign_argument_quickly("Mock.#{function[:name]}_FinalReturn", retval) unless (retval[:void?]) + # return_type = function[:return][:const?] ? "(const #{function[:return][:type]})" : ((function[:return][:type] =~ /cmock/) ? "(#{function[:return][:type]})" : '') + # lines << " return #{return_type}cmock_call_instance->ReturnVal;\n }\n" + # end + # lines + # end def mock_interfaces(function) lines = "" diff --git a/lib/cmock_generator_plugin_return_thru_ptr.rb b/lib/cmock_generator_plugin_return_thru_ptr.rb index 67935b4..e1a0cbb 100644 --- a/lib/cmock_generator_plugin_return_thru_ptr.rb +++ b/lib/cmock_generator_plugin_return_thru_ptr.rb @@ -4,7 +4,7 @@ class CMockGeneratorPluginReturnThruPtr def initialize(config, utils) @utils = utils - @priority = 1 #TODO: it's 1 to come before ignore_arg returns... but should be after expects otherwise (like 9) + @priority = 9 end def instance_typedefs(function) diff --git a/test/system/test_interactions/all_plugins_coexist.yml b/test/system/test_interactions/all_plugins_coexist.yml index 566641e..ad73661 100644 --- a/test/system/test_interactions/all_plugins_coexist.yml +++ b/test/system/test_interactions/all_plugins_coexist.yml @@ -1,389 +1,459 @@ ---- -:cmock: - :enforce_strict_ordering: 1 - :plugins: - - :array - - :cexception - - :ignore - - :callback - - :return_thru_ptr - - :ignore_arg - - :expect_any_args - :callback_after_arg_check: true - :callback_include_count: false - :treat_externs: :include - -:systest: - :types: | - typedef struct _POINT_T { - int x; - int y; - } POINT_T; - - :mockable: | - #include "CException.h" - extern void foo(POINT_T* a); - POINT_T* bar(void); - void fooa(POINT_T a[]); - void foos(const char * a); - const char * bars(void); - void no_pointers(int a, const char* b); - int mixed(int a, int* b, int c); - void no_args(void); - - :source: - :header: | - #include "CException.h" - void function_a(void); - void function_b(void); - void function_c(void); - int function_d(void); - void function_e(void); - - :code: | - void function_a(void) - { - foo(bar()); - } - - void function_b(void) { - fooa(bar()); - } - - void function_c(void) { - CEXCEPTION_T e; - Try { - foos(bars()); - } Catch(e) { foos("err"); } - } - - int function_d(void) { - int test_list[] = { 1, 2, 3, 4, 5 }; - no_pointers(1, "silly"); - return mixed(6, test_list, 7); - } - - void function_e(void) { - foos("Hello"); - foos("Tuna"); - foos("Oranges"); - } - - :tests: - :common: | - #include "CException.h" - void setUp(void) {} - void tearDown(void) {} - void my_foo_callback(POINT_T* a) { TEST_ASSERT_EQUAL_INT(2, a->x); } - - :units: - - :pass: TRUE - :should: 'handle the situation where we pass nulls to pointers' - :code: | - test() - { - bar_ExpectAndReturn(NULL); - foo_Expect(NULL); - - function_a(); - } - - - :pass: FALSE - :should: 'handle the situation where we expected nulls to pointers but did not get that' - :code: | - test() - { - POINT_T pt = {1, 2}; - bar_ExpectAndReturn(&pt); - foo_Expect(NULL); - - function_a(); - } - - - :pass: FALSE - :should: 'handle the situation where we did not expect nulls to pointers but got null' - :code: | - test() - { - POINT_T ex = {1, 2}; - bar_ExpectAndReturn(NULL); - foo_Expect(&ex); - - function_a(); - } - - - :pass: FALSE - :should: 'handle the situation where we pass single object with expect and it is wrong' - :code: | - test() - { - POINT_T pt = {1, 2}; - POINT_T ex = {1, 3}; - bar_ExpectAndReturn(&pt); - foo_Expect(&ex); - - function_a(); - } - - - :pass: TRUE - :should: 'handle the situation where we pass single object with expect and use array handler' - :code: | - test() - { - POINT_T pt = {1, 2}; - POINT_T ex = {1, 2}; - bar_ExpectAndReturn(&pt); - foo_ExpectWithArray(&ex, 1); - - function_a(); - } - - - :pass: FALSE - :should: 'handle the situation where we pass single object with expect and use array handler and it is wrong' - :code: | - test() - { - POINT_T pt = {1, 2}; - POINT_T ex = {1, 3}; - bar_ExpectAndReturn(&pt); - foo_ExpectWithArray(&ex, 1); - - function_a(); - } - - - :pass: TRUE - :should: 'handle the situation where we pass multiple objects with expect and use array handler' - :code: | - test() - { - POINT_T pt[] = {{1, 2}, {3, 4}, {5, 6}}; - POINT_T ex[] = {{1, 2}, {3, 4}, {5, 6}}; - bar_ExpectAndReturn(pt); - foo_ExpectWithArray(ex, 3); - - function_a(); - } - - - :pass: FALSE - :should: 'handle the situation where we pass multiple objects with expect and use array handler and it is wrong at end' - :code: | - test() - { - POINT_T pt[] = {{1, 2}, {3, 4}, {5, 6}}; - POINT_T ex[] = {{1, 2}, {3, 4}, {5, 9}}; - bar_ExpectAndReturn(pt); - foo_ExpectWithArray(ex, 3); - - function_a(); - } - - - :pass: TRUE - :should: 'handle the situation where we pass single array element with expect' - :code: | - test() - { - POINT_T pt = {1, 2}; - POINT_T ex = {1, 2}; - bar_ExpectAndReturn(&pt); - fooa_Expect(&ex); - - function_b(); - } - - - :pass: TRUE - :should: 'handle standard c string as null terminated and not do crappy memory compares of a byte, passing' - :code: | - test() - { - const char* retval = "This is a\0 silly string"; - bars_ExpectAndReturn((char*)retval); - foos_Expect("This is a\0 wacky string"); - - function_c(); - } - - - :pass: FALSE - :should: 'handle standard c string as null terminated and not do crappy memory compares of a byte, finding failures' - :code: | - test() - { - const char* retval = "This is a silly string"; - bars_ExpectAndReturn((char*)retval); - foos_Expect("This is a wacky string"); - - function_c(); - } - - - :pass: TRUE - :should: 'handle creating array expects when we have mixed arguments for single object' - :code: | - test() - { - int expect_list[] = { 1, 9 }; - no_pointers_Expect(1, "silly"); - mixed_ExpectAndReturn(6, expect_list, 7, 13); - - TEST_ASSERT_EQUAL(13, function_d()); - } - - - :pass: FALSE - :should: 'handle creating array expects when we have mixed arguments and handle failures for single object' - :code: | - test() - { - int expect_list[] = { 9, 1 }; - no_pointers_Expect(1, "silly"); - mixed_ExpectAndReturn(6, expect_list, 7, 13); - - TEST_ASSERT_EQUAL(13, function_d()); - } - - - :pass: TRUE - :should: 'handle creating array expects when we have mixed arguments for multiple objects' - :code: | - test() - { - int expect_list[] = { 1, 2, 3, 4, 6 }; - no_pointers_Expect(1, "silly"); - mixed_ExpectWithArrayAndReturn(6, expect_list, 4, 7, 13); - - TEST_ASSERT_EQUAL(13, function_d()); - } - - - :pass: FALSE - :should: 'handle creating array expects when we have mixed arguments and handle failures for multiple objects' - :code: | - test() - { - int expect_list[] = { 1, 2, 3, 4, 6 }; - no_pointers_Expect(1, "silly"); - mixed_ExpectWithArrayAndReturn(6, expect_list, 5, 7, 13); - - TEST_ASSERT_EQUAL(13, function_d()); - } - - - :pass: TRUE - :should: 'handle an exception being caught' - :code: | - test() - { - const char* retval = "This is a\0 silly string"; - bars_ExpectAndReturn((char*)retval); - foos_ExpectAndThrow("This is a\0 wacky string", 55); - foos_Expect("err"); - - function_c(); - } - - - :pass: FALSE - :should: 'handle an exception being caught but still catch following errors' - :code: | - test() - { - const char* retval = "This is a\0 silly string"; - bars_ExpectAndReturn((char*)retval); - foos_ExpectAndThrow("This is a\0 wacky string", 55); - foos_Expect("wrong error"); - - function_c(); - } - - - :pass: FALSE - :should: 'fail strict ordering problems even though we would otherwise have passed' - :code: | - test() - { - int expect_list[] = { 1, 2, 3, 4, 6 }; - mixed_ExpectWithArrayAndReturn(6, expect_list, 4, 7, 13); - no_pointers_Expect(1, "silly"); - - TEST_ASSERT_EQUAL(13, function_d()); - } - - - :pass: TRUE - :should: 'that we can properly ignore last function but the other will work properly' - :code: | - test() - { - int expect_list[] = { 1, 2, 3, 4, 6 }; - mixed_ExpectWithArrayAndReturn(6, expect_list, 4, 7, 13); - no_pointers_Ignore(); - - TEST_ASSERT_EQUAL(13, function_d()); - } - - - :pass: TRUE - :should: 'that we can properly ignore first function but the other will work properly' - :code: | - test() - { - mixed_IgnoreAndReturn(13); - no_pointers_Expect(1, "silly"); - - TEST_ASSERT_EQUAL(13, function_d()); - } - - - :pass: TRUE - :should: 'that we just have to ignore a call once because we are not counting calls' - :code: | - test() - { - foos_Ignore(); - - function_e(); - } - - - :pass: TRUE - :should: 'that we can use a callback and an expect' - :code: | - test() - { - POINT_T pt1 = {2, 3}; - POINT_T pt2 = {2, 3}; - bar_ExpectAndReturn(&pt1); - foo_Expect(&pt2); - foo_StubWithCallback((CMOCK_foo_CALLBACK)my_foo_callback); - - function_a(); - } - - - :pass: FALSE - :should: 'that we can fail even when using a callback if we want to expect call but did not and we are checking that' - :code: | - test() - { - POINT_T pt = {2, 3}; - bar_ExpectAndReturn(&pt); - foo_StubWithCallback((CMOCK_foo_CALLBACK)my_foo_callback); - - function_a(); - } - - - :pass: FALSE - :should: 'that we can fail even when using a callback if args are wrong and we are checking those' - :code: | - test() - { - POINT_T pt1 = {2, 3}; - POINT_T pt2 = {1, 3}; - bar_ExpectAndReturn(&pt1); - foo_Expect(&pt2); - foo_StubWithCallback((CMOCK_foo_CALLBACK)my_foo_callback); - - function_a(); - } - - - :pass: FALSE - :should: 'that we can fail from the callback itself' - :code: | - test() - { - POINT_T pt = {3, 3}; - bar_ExpectAndReturn(&pt); - foo_Expect(&pt); - foo_StubWithCallback((CMOCK_foo_CALLBACK)my_foo_callback); - - function_a(); - } - -... +--- +:cmock: + :enforce_strict_ordering: 1 + :plugins: + - :array + - :cexception + - :ignore + - :callback + - :return_thru_ptr + - :ignore_arg + - :expect_any_args + :callback_after_arg_check: true + :callback_include_count: false + :treat_externs: :include + +:systest: + :types: | + typedef struct _POINT_T { + int x; + int y; + } POINT_T; + + :mockable: | + #include "CException.h" + extern void foo(POINT_T* a); + POINT_T* bar(void); + void fooa(POINT_T a[]); + void foos(const char * a); + const char * bars(void); + void no_pointers(int a, const char* b); + int mixed(int a, int* b, int c); + void no_args(void); + + :source: + :header: | + #include "CException.h" + void function_a(void); + void function_b(void); + void function_c(void); + int function_d(void); + void function_e(void); + int function_f(void); + + :code: | + void function_a(void) + { + foo(bar()); + } + + void function_b(void) { + fooa(bar()); + } + + void function_c(void) { + CEXCEPTION_T e; + Try { + foos(bars()); + } Catch(e) { foos("err"); } + } + + int function_d(void) { + int test_list[] = { 1, 2, 3, 4, 5 }; + no_pointers(1, "silly"); + return mixed(6, test_list, 7); + } + + void function_e(void) { + foos("Hello"); + foos("Tuna"); + foos("Oranges"); + } + + int function_f(void) { + int a = 1; + int b = 2; + int c; + POINT_T* pt = bar(); + c = pt->x; + c = mixed(a, &b, c); + return b + c; + } + + :tests: + :common: | + #include "CException.h" + void setUp(void) {} + void tearDown(void) {} + void my_foo_callback(POINT_T* a) { TEST_ASSERT_EQUAL_INT(2, a->x); } + int my_mixed_callback(int a, int* b, int c) { return a + *b + c; } + + :units: + - :pass: TRUE + :should: 'handle the situation where we pass nulls to pointers' + :code: | + test() + { + bar_ExpectAndReturn(NULL); + foo_Expect(NULL); + + function_a(); + } + + - :pass: FALSE + :should: 'handle the situation where we expected nulls to pointers but did not get that' + :code: | + test() + { + POINT_T pt = {1, 2}; + bar_ExpectAndReturn(&pt); + foo_Expect(NULL); + + function_a(); + } + + - :pass: FALSE + :should: 'handle the situation where we did not expect nulls to pointers but got null' + :code: | + test() + { + POINT_T ex = {1, 2}; + bar_ExpectAndReturn(NULL); + foo_Expect(&ex); + + function_a(); + } + + - :pass: FALSE + :should: 'handle the situation where we pass single object with expect and it is wrong' + :code: | + test() + { + POINT_T pt = {1, 2}; + POINT_T ex = {1, 3}; + bar_ExpectAndReturn(&pt); + foo_Expect(&ex); + + function_a(); + } + + - :pass: TRUE + :should: 'handle the situation where we pass single object with expect and use array handler' + :code: | + test() + { + POINT_T pt = {1, 2}; + POINT_T ex = {1, 2}; + bar_ExpectAndReturn(&pt); + foo_ExpectWithArray(&ex, 1); + + function_a(); + } + + - :pass: FALSE + :should: 'handle the situation where we pass single object with expect and use array handler and it is wrong' + :code: | + test() + { + POINT_T pt = {1, 2}; + POINT_T ex = {1, 3}; + bar_ExpectAndReturn(&pt); + foo_ExpectWithArray(&ex, 1); + + function_a(); + } + + - :pass: TRUE + :should: 'handle the situation where we pass multiple objects with expect and use array handler' + :code: | + test() + { + POINT_T pt[] = {{1, 2}, {3, 4}, {5, 6}}; + POINT_T ex[] = {{1, 2}, {3, 4}, {5, 6}}; + bar_ExpectAndReturn(pt); + foo_ExpectWithArray(ex, 3); + + function_a(); + } + + - :pass: FALSE + :should: 'handle the situation where we pass multiple objects with expect and use array handler and it is wrong at end' + :code: | + test() + { + POINT_T pt[] = {{1, 2}, {3, 4}, {5, 6}}; + POINT_T ex[] = {{1, 2}, {3, 4}, {5, 9}}; + bar_ExpectAndReturn(pt); + foo_ExpectWithArray(ex, 3); + + function_a(); + } + + - :pass: TRUE + :should: 'handle the situation where we pass single array element with expect' + :code: | + test() + { + POINT_T pt = {1, 2}; + POINT_T ex = {1, 2}; + bar_ExpectAndReturn(&pt); + fooa_Expect(&ex); + + function_b(); + } + + - :pass: TRUE + :should: 'handle standard c string as null terminated and not do crappy memory compares of a byte, passing' + :code: | + test() + { + const char* retval = "This is a\0 silly string"; + bars_ExpectAndReturn((char*)retval); + foos_Expect("This is a\0 wacky string"); + + function_c(); + } + + - :pass: FALSE + :should: 'handle standard c string as null terminated and not do crappy memory compares of a byte, finding failures' + :code: | + test() + { + const char* retval = "This is a silly string"; + bars_ExpectAndReturn((char*)retval); + foos_Expect("This is a wacky string"); + + function_c(); + } + + - :pass: TRUE + :should: 'handle creating array expects when we have mixed arguments for single object' + :code: | + test() + { + int expect_list[] = { 1, 9 }; + no_pointers_Expect(1, "silly"); + mixed_ExpectAndReturn(6, expect_list, 7, 13); + + TEST_ASSERT_EQUAL(13, function_d()); + } + + - :pass: FALSE + :should: 'handle creating array expects when we have mixed arguments and handle failures for single object' + :code: | + test() + { + int expect_list[] = { 9, 1 }; + no_pointers_Expect(1, "silly"); + mixed_ExpectAndReturn(6, expect_list, 7, 13); + + TEST_ASSERT_EQUAL(13, function_d()); + } + + - :pass: TRUE + :should: 'handle creating array expects when we have mixed arguments for multiple objects' + :code: | + test() + { + int expect_list[] = { 1, 2, 3, 4, 6 }; + no_pointers_Expect(1, "silly"); + mixed_ExpectWithArrayAndReturn(6, expect_list, 4, 7, 13); + + TEST_ASSERT_EQUAL(13, function_d()); + } + + - :pass: FALSE + :should: 'handle creating array expects when we have mixed arguments and handle failures for multiple objects' + :code: | + test() + { + int expect_list[] = { 1, 2, 3, 4, 6 }; + no_pointers_Expect(1, "silly"); + mixed_ExpectWithArrayAndReturn(6, expect_list, 5, 7, 13); + + TEST_ASSERT_EQUAL(13, function_d()); + } + + - :pass: TRUE + :should: 'handle an exception being caught' + :code: | + test() + { + const char* retval = "This is a\0 silly string"; + bars_ExpectAndReturn((char*)retval); + foos_ExpectAndThrow("This is a\0 wacky string", 55); + foos_Expect("err"); + + function_c(); + } + + - :pass: FALSE + :should: 'handle an exception being caught but still catch following errors' + :code: | + test() + { + const char* retval = "This is a\0 silly string"; + bars_ExpectAndReturn((char*)retval); + foos_ExpectAndThrow("This is a\0 wacky string", 55); + foos_Expect("wrong error"); + + function_c(); + } + + - :pass: FALSE + :should: 'fail strict ordering problems even though we would otherwise have passed' + :code: | + test() + { + int expect_list[] = { 1, 2, 3, 4, 6 }; + mixed_ExpectWithArrayAndReturn(6, expect_list, 4, 7, 13); + no_pointers_Expect(1, "silly"); + + TEST_ASSERT_EQUAL(13, function_d()); + } + + - :pass: TRUE + :should: 'that we can properly ignore last function but the other will work properly' + :code: | + test() + { + int expect_list[] = { 1, 2, 3, 4, 6 }; + mixed_ExpectWithArrayAndReturn(6, expect_list, 4, 7, 13); + no_pointers_Ignore(); + + TEST_ASSERT_EQUAL(13, function_d()); + } + + - :pass: TRUE + :should: 'that we can properly ignore first function but the other will work properly' + :code: | + test() + { + mixed_IgnoreAndReturn(13); + no_pointers_Expect(1, "silly"); + + TEST_ASSERT_EQUAL(13, function_d()); + } + + - :pass: TRUE + :should: 'that we just have to ignore a call once because we are not counting calls' + :code: | + test() + { + foos_Ignore(); + + function_e(); + } + + - :pass: TRUE + :should: 'that we can use a callback and an expect' + :code: | + test() + { + POINT_T pt1 = {2, 3}; + POINT_T pt2 = {2, 3}; + bar_ExpectAndReturn(&pt1); + foo_Expect(&pt2); + foo_StubWithCallback((CMOCK_foo_CALLBACK)my_foo_callback); + + function_a(); + } + + - :pass: FALSE + :should: 'that we can fail even when using a callback if we want to expect call but did not and we are checking that' + :code: | + test() + { + POINT_T pt = {2, 3}; + bar_ExpectAndReturn(&pt); + foo_StubWithCallback((CMOCK_foo_CALLBACK)my_foo_callback); + + function_a(); + } + + - :pass: FALSE + :should: 'that we can fail even when using a callback if args are wrong and we are checking those' + :code: | + test() + { + POINT_T pt1 = {2, 3}; + POINT_T pt2 = {1, 3}; + bar_ExpectAndReturn(&pt1); + foo_Expect(&pt2); + foo_StubWithCallback((CMOCK_foo_CALLBACK)my_foo_callback); + + function_a(); + } + + - :pass: FALSE + :should: 'that we can fail from the callback itself' + :code: | + test() + { + POINT_T pt = {3, 3}; + bar_ExpectAndReturn(&pt); + foo_Expect(&pt); + foo_StubWithCallback((CMOCK_foo_CALLBACK)my_foo_callback); + + function_a(); + } + + - :pass: TRUE + :should: 'that a callback return value overrides the one from ExpectAndReturn' + :code: | + test() + { + int b = 2; + POINT_T pt1 = {3, 4}; + bar_ExpectAndReturn(&pt1); + mixed_StubWithCallback((CMOCK_mixed_CALLBACK)my_mixed_callback); + mixed_ExpectAndReturn(1,&b,3,100); + + TEST_ASSERT_EQUAL(8, function_f()); + } + + - :pass: TRUE + :should: 'that a callback return value overrides the one from ExpectAndReturn AND ReturnThruPtr still works' + :code: | + test() + { + int b_in = 2; + int b_out = 3; + POINT_T pt1 = {3, 4}; + bar_ExpectAndReturn(&pt1); + mixed_StubWithCallback((CMOCK_mixed_CALLBACK)my_mixed_callback); + mixed_ExpectAndReturn(1,&b_in,3,100); + mixed_ReturnThruPtr_b(&b_out); + + TEST_ASSERT_EQUAL(9, function_f()); // (a=1, bin=2, c=pt.x=3, bout=3, sum=9) + } + + - :pass: TRUE + :should: 'that a callback return value overrides the one from ExpectAnyArgs' + :code: | + test() + { + POINT_T pt1 = {5, 4}; + bar_ExpectAndReturn(&pt1); + mixed_StubWithCallback((CMOCK_mixed_CALLBACK)my_mixed_callback); + mixed_ExpectAnyArgsAndReturn(100); + + TEST_ASSERT_EQUAL(10, function_f()); // (a=1, bin=2, c=pt.x=5, bout=2, sum=10) + } + + - :pass: TRUE + :should: 'that a callback return value overrides the one from ExpectAnyArgs AND ReturnThruPtr still works' + :code: | + test() + { + int b_out = 3; + POINT_T pt1 = {5, 4}; + bar_ExpectAndReturn(&pt1); + mixed_StubWithCallback((CMOCK_mixed_CALLBACK)my_mixed_callback); + mixed_ExpectAnyArgsAndReturn(100); + mixed_ReturnThruPtr_b(&b_out); + + TEST_ASSERT_EQUAL(11, function_f()); // (a=1, bin=2, c=pt.x=5, bout=3, sum=11) + } + +... diff --git a/test/system/test_interactions/doesnt_leave_details_behind.yml b/test/system/test_interactions/doesnt_leave_details_behind.yml index ce15a63..a077839 100644 --- a/test/system/test_interactions/doesnt_leave_details_behind.yml +++ b/test/system/test_interactions/doesnt_leave_details_behind.yml @@ -292,7 +292,7 @@ - :pass: FALSE :should: 'not contain mock details in failed assertion after mock which used a return thru ptr' - #:verify_error: 'FAIL: Expected 3 Was 7. CustomFail' #TODO: put back in once ReturnThruPtr fixed + :verify_error: 'FAIL: Expected 3 Was 7. CustomFail' :code: | test() { @@ -302,7 +302,7 @@ foo_Expect(&pt1); foo_ReturnThruPtr_a(&pt2); - TEST_ASSERT_EQUAL_INT(3, function_b()); + TEST_ASSERT_EQUAL_INT_MESSAGE(3, function_b(), "CustomFail"); } ... diff --git a/test/unit/cmock_generator_plugin_callback_test.rb b/test/unit/cmock_generator_plugin_callback_test.rb index 7934fe6..e38ccf1 100644 --- a/test/unit/cmock_generator_plugin_callback_test.rb +++ b/test/unit/cmock_generator_plugin_callback_test.rb @@ -79,19 +79,87 @@ describe CMockGeneratorPluginCallback, "Verify CMockGeneratorPluginCallback Modu assert_equal(expected, returned) end - it "add mock function implementation for functions of style 'void func(void)'" do + it "add mock function implementation for functions with no arg check and of style 'void func(void)'" do function = {:name => "Apple", :args => [], :args_string => "void", :return => test_return[:void]} expected = [" if (Mock.Apple_CallbackFunctionPointer != NULL)\n", " {\n", " Mock.Apple_CallbackFunctionPointer(Mock.Apple_CallbackCalls++);\n", - " return;\n", " }\n" ].join - returned = @cmock_generator_plugin_callback.mock_implementation_precheck(function) + returned = @cmock_generator_plugin_callback.mock_implementation_for_callbacks_after_arg_check(function) assert_equal(expected, returned) end - it "add mock function implementation for functions of style 'void func(void)' when count turned off" do + it "add mock function implementation for functions with no arg check and of style 'void func(void)' when count turned off" do + function = {:name => "Apple", :args => [], :args_string => "void", :return => test_return[:void]} + expected = [" if (Mock.Apple_CallbackFunctionPointer != NULL)\n", + " {\n", + " Mock.Apple_CallbackFunctionPointer();\n", + " }\n" + ].join + @cmock_generator_plugin_callback.include_count = false + returned = @cmock_generator_plugin_callback.mock_implementation_for_callbacks_after_arg_check(function) + assert_equal(expected, returned) + end + + it "add mock function implementation for functions with no arg check and of style 'int func(void)'" do + function = {:name => "Apple", :args => [], :args_string => "void", :return => test_return[:int]} + expected = [" if (Mock.Apple_CallbackFunctionPointer != NULL)\n", + " {\n", + " cmock_call_instance->ReturnVal = Mock.Apple_CallbackFunctionPointer(Mock.Apple_CallbackCalls++);\n", + " }\n" + ].join + returned = @cmock_generator_plugin_callback.mock_implementation_for_callbacks_after_arg_check(function) + assert_equal(expected, returned) + end + + it "add mock function implementation for functions with no arg check and of style 'void func(int* steak, uint8_t flag)'" do + function = {:name => "Apple", + :args => [ { :type => 'int*', :name => 'steak', :ptr? => true}, + { :type => 'uint8_t', :name => 'flag', :ptr? => false} ], + :args_string => "int* steak, uint8_t flag", + :return=> test_return[:void]} + expected = [" if (Mock.Apple_CallbackFunctionPointer != NULL)\n", + " {\n", + " Mock.Apple_CallbackFunctionPointer(steak, flag, Mock.Apple_CallbackCalls++);\n", + " }\n" + ].join + returned = @cmock_generator_plugin_callback.mock_implementation_for_callbacks_after_arg_check(function) + assert_equal(expected, returned) + end + + it "add mock function implementation for functions with no arg check and of style 'void func(int* steak, uint8_t flag)' when count turned off" do + function = {:name => "Apple", + :args => [ { :type => 'int*', :name => 'steak', :ptr? => true}, + { :type => 'uint8_t', :name => 'flag', :ptr? => false} ], + :args_string => "int* steak, uint8_t flag", + :return=> test_return[:void]} + expected = [" if (Mock.Apple_CallbackFunctionPointer != NULL)\n", + " {\n", + " Mock.Apple_CallbackFunctionPointer(steak, flag);\n", + " }\n" + ].join + @cmock_generator_plugin_callback.include_count = false + returned = @cmock_generator_plugin_callback.mock_implementation_for_callbacks_after_arg_check(function) + assert_equal(expected, returned) + end + + it "add mock function implementation for functions with no arg check and of style 'int16_t func(int* steak, uint8_t flag)'" do + function = {:name => "Apple", + :args => [ { :type => 'int*', :name => 'steak', :ptr? => true}, + { :type => 'uint8_t', :name => 'flag', :ptr? => false} ], + :args_string => "int* steak, uint8_t flag", + :return => test_return[:int]} + expected = [" if (Mock.Apple_CallbackFunctionPointer != NULL)\n", + " {\n", + " cmock_call_instance->ReturnVal = Mock.Apple_CallbackFunctionPointer(steak, flag, Mock.Apple_CallbackCalls++);\n", + " }\n" + ].join + returned = @cmock_generator_plugin_callback.mock_implementation_for_callbacks_after_arg_check(function) + assert_equal(expected, returned) + end + + it "add mock function implementation for functions without arg check and of style 'void func(void)' when count turned off" do function = {:name => "Apple", :args => [], :args_string => "void", :return => test_return[:void]} expected = [" if (Mock.Apple_CallbackFunctionPointer != NULL)\n", " {\n", @@ -100,22 +168,22 @@ describe CMockGeneratorPluginCallback, "Verify CMockGeneratorPluginCallback Modu " }\n" ].join @cmock_generator_plugin_callback.include_count = false - returned = @cmock_generator_plugin_callback.mock_implementation_precheck(function) + returned = @cmock_generator_plugin_callback.mock_implementation_for_callbacks_without_arg_check(function) assert_equal(expected, returned) end - it "add mock function implementation for functions of style 'int func(void)'" do + it "add mock function implementation for functions without arg check and of style 'int func(void)'" do function = {:name => "Apple", :args => [], :args_string => "void", :return => test_return[:int]} expected = [" if (Mock.Apple_CallbackFunctionPointer != NULL)\n", " {\n", " return Mock.Apple_CallbackFunctionPointer(Mock.Apple_CallbackCalls++);\n", " }\n" ].join - returned = @cmock_generator_plugin_callback.mock_implementation_precheck(function) + returned = @cmock_generator_plugin_callback.mock_implementation_for_callbacks_without_arg_check(function) assert_equal(expected, returned) end - it "add mock function implementation for functions of style 'void func(int* steak, uint8_t flag)'" do + it "add mock function implementation for functions without arg check and of style 'void func(int* steak, uint8_t flag)'" do function = {:name => "Apple", :args => [ { :type => 'int*', :name => 'steak', :ptr? => true}, { :type => 'uint8_t', :name => 'flag', :ptr? => false} ], @@ -127,11 +195,11 @@ describe CMockGeneratorPluginCallback, "Verify CMockGeneratorPluginCallback Modu " return;\n", " }\n" ].join - returned = @cmock_generator_plugin_callback.mock_implementation_precheck(function) + returned = @cmock_generator_plugin_callback.mock_implementation_for_callbacks_without_arg_check(function) assert_equal(expected, returned) end - it "add mock function implementation for functions of style 'void func(int* steak, uint8_t flag)' when count turned off" do + it "add mock function implementation for functions without arg check and of style 'void func(int* steak, uint8_t flag)' when count turned off" do function = {:name => "Apple", :args => [ { :type => 'int*', :name => 'steak', :ptr? => true}, { :type => 'uint8_t', :name => 'flag', :ptr? => false} ], @@ -144,11 +212,11 @@ describe CMockGeneratorPluginCallback, "Verify CMockGeneratorPluginCallback Modu " }\n" ].join @cmock_generator_plugin_callback.include_count = false - returned = @cmock_generator_plugin_callback.mock_implementation_precheck(function) + returned = @cmock_generator_plugin_callback.mock_implementation_for_callbacks_without_arg_check(function) assert_equal(expected, returned) end - it "add mock function implementation for functions of style 'int16_t func(int* steak, uint8_t flag)'" do + it "add mock function implementation for functions without arg check and of style 'int16_t func(int* steak, uint8_t flag)'" do function = {:name => "Apple", :args => [ { :type => 'int*', :name => 'steak', :ptr? => true}, { :type => 'uint8_t', :name => 'flag', :ptr? => false} ], @@ -159,7 +227,7 @@ describe CMockGeneratorPluginCallback, "Verify CMockGeneratorPluginCallback Modu " return Mock.Apple_CallbackFunctionPointer(steak, flag, Mock.Apple_CallbackCalls++);\n", " }\n" ].join - returned = @cmock_generator_plugin_callback.mock_implementation_precheck(function) + returned = @cmock_generator_plugin_callback.mock_implementation_for_callbacks_without_arg_check(function) assert_equal(expected, returned) end diff --git a/test/unit/cmock_generator_plugin_expect_a_test.rb b/test/unit/cmock_generator_plugin_expect_a_test.rb new file mode 100644 index 0000000..a694f3b --- /dev/null +++ b/test/unit/cmock_generator_plugin_expect_a_test.rb @@ -0,0 +1,186 @@ +# ========================================== +# CMock Project - Automatic Mock Generation for C +# Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams +# [Released under MIT License. Please refer to license.txt for details] +# ========================================== + +require File.expand_path(File.dirname(__FILE__)) + "/../test_helper" +require 'cmock_generator_plugin_expect' + +describe CMockGeneratorPluginExpect, "Verify CMockGeneratorPluginExpect Module Without Global Ordering" do + + before do + create_mocks :config, :utils + + @config = create_stub( + :when_ptr => :compare_data, + :enforce_strict_ordering => false, + :respond_to? => true, + :plugins => [ :expect ] ) + + @utils.expect :helpers, {} + @cmock_generator_plugin_expect = CMockGeneratorPluginExpect.new(@config, @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 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 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_expect_any_args_test.rb b/test/unit/cmock_generator_plugin_expect_any_args_test.rb index 08432ed..4bfe1a7 100644 --- a/test/unit/cmock_generator_plugin_expect_any_args_test.rb +++ b/test/unit/cmock_generator_plugin_expect_any_args_test.rb @@ -41,29 +41,8 @@ describe CMockGeneratorPluginExpectAnyArgs, "Verify CMockGeneratorPluginExpectAn assert_equal(expected, returned) end - it "add required code to implementation with void function" do - function = {:name => "Mold", :args_string => "void", :return => test_return[:void]} - expected = [" if (cmock_call_instance->IgnoreMode == CMOCK_ARG_NONE)\n", - " {\n", - " return;\n", - " }\n" - ].join - returned = @cmock_generator_plugin_expect_any_args.mock_implementation(function) - assert_equal(expected, returned) - end - - it "add required code to implementation 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 (cmock_call_instance->IgnoreMode == CMOCK_ARG_NONE)\n", - " {\n", - " mock_retval_0", - " return cmock_call_instance->ReturnVal;\n", - " }\n" - ].join - returned = @cmock_generator_plugin_expect_any_args.mock_implementation(function) - assert_equal(expected, returned) + it "should not respond to implementation requests" do + assert(!@cmock_generator_plugin_expect_any_args.respond_to?(:mock_implementation)) end it "add a new mock interface for ignoring when function had no return value" do diff --git a/test/unit/cmock_generator_plugin_expect_test.rb b/test/unit/cmock_generator_plugin_expect_b_test.rb similarity index 90% rename from test/unit/cmock_generator_plugin_expect_test.rb rename to test/unit/cmock_generator_plugin_expect_b_test.rb index bf77d23..460b6b1 100644 --- a/test/unit/cmock_generator_plugin_expect_test.rb +++ b/test/unit/cmock_generator_plugin_expect_b_test.rb @@ -7,26 +7,19 @@ require File.expand_path(File.dirname(__FILE__)) + "/../test_helper" require 'cmock_generator_plugin_expect' -describe CMockGeneratorPluginExpect, "Verify CMockGeneratorPluginExpect Module" do +describe CMockGeneratorPluginExpect, "Verify CMockGeneratorPluginExpect Module with Global Ordering" do before do create_mocks :config, :utils @config = create_stub( :when_ptr => :compare_data, - :enforce_strict_ordering => false, - :respond_to? => true ) + :enforce_strict_ordering => true, + :respond_to? => true, + :plugins => [ :expect, :expect_any_args ] ) @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 @@ -41,41 +34,34 @@ describe CMockGeneratorPluginExpect, "Verify CMockGeneratorPluginExpect Module" 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 + 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 = "" + expected = " int CallOrder;\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(void)'" do function = {:name => "Elm", :args => [], :return => test_return[:int]} - expected = " int ReturnVal;\n" + expected = " int ReturnVal;\n int CallOrder;\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" + expected = " int CallOrder;\n 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" + expected = " int ReturnVal;\n int CallOrder;\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" + @@ -112,7 +98,10 @@ describe CMockGeneratorPluginExpect, "Verify CMockGeneratorPluginExpect Module" @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" + expected = " if (cmock_call_instance->IgnoreMode != CMOCK_ARG_NONE)\n" + + " {\n" + + " mocked_retval_1 mocked_retval_2\n" + + " }\n" returned = @cmock_generator_plugin_expect.mock_implementation(function) assert_equal(expected, returned) end @@ -128,9 +117,12 @@ describe CMockGeneratorPluginExpect, "Verify CMockGeneratorPluginExpect Module" 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" + expected = " if (cmock_call_instance->IgnoreMode != CMOCK_ARG_NONE)\n" + + " {\n" + + "mocked_retval_0\n" + + " }\n" @cmock_generator_plugin_expect.ordered = true - returned = @cmock_generator_plugin_expect_strict.mock_implementation(function) + returned = @cmock_generator_plugin_expect.mock_implementation(function) assert_equal(expected, returned) 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 832474c..016e7fe 100644 --- a/test/unit/cmock_generator_plugin_return_thru_ptr_test.rb +++ b/test/unit/cmock_generator_plugin_return_thru_ptr_test.rb @@ -57,7 +57,7 @@ describe CMockGeneratorPluginReturnThruPtr, "Verify CMockGeneratorPluginReturnTh end it "have set up internal priority correctly on init" do - assert_equal(1, @cmock_generator_plugin_return_thru_ptr.priority) + assert_equal(9, @cmock_generator_plugin_return_thru_ptr.priority) end it "not include any additional include files" do