diff --git a/docs/CMock Summary.odt b/docs/CMock Summary.odt index a567741..4f054c1 100644 Binary files a/docs/CMock Summary.odt and b/docs/CMock Summary.odt differ diff --git a/docs/CMock Summary.pdf b/docs/CMock Summary.pdf index fc8c562..8cddcf1 100644 Binary files a/docs/CMock Summary.pdf and b/docs/CMock Summary.pdf differ diff --git a/lib/cmock_config.rb b/lib/cmock_config.rb index 06b103b..bf8e64c 100644 --- a/lib/cmock_config.rb +++ b/lib/cmock_config.rb @@ -8,23 +8,25 @@ class CMockConfig CMockDefaultOptions = { - :framework => :unity, - :mock_path => 'mocks', - :mock_prefix => 'Mock', - :plugins => [], - :includes => [], - :attributes => ['__ramfunc', '__irq', '__fiq', 'register', 'extern'], - :enforce_strict_ordering => false, - :cexception_include => nil, - :unity_helper => false, - :treat_as => {}, - :treat_as_void => [], - :memcmp_if_unknown => true, - :when_no_prototypes => :warn, #the options being :ignore, :warn, or :error - :when_ptr => :compare_data, #the options being :compare_ptr, :compare_data, or :smart - :verbosity => 2, #the options being 0 errors only, 1 warnings and errors, 2 normal info, 3 verbose - :treat_externs => :exclude, #the options being :include or :exclude - :ignore => :args_and_calls, #the options being :args_and_calls or :args_only + :framework => :unity, + :mock_path => 'mocks', + :mock_prefix => 'Mock', + :plugins => [], + :includes => [], + :attributes => ['__ramfunc', '__irq', '__fiq', 'register', 'extern'], + :enforce_strict_ordering => false, + :cexception_include => nil, + :unity_helper => false, + :treat_as => {}, + :treat_as_void => [], + :memcmp_if_unknown => true, + :when_no_prototypes => :warn, #the options being :ignore, :warn, or :error + :when_ptr => :compare_data, #the options being :compare_ptr, :compare_data, or :smart + :verbosity => 2, #the options being 0 errors only, 1 warnings and errors, 2 normal info, 3 verbose + :treat_externs => :exclude, #the options being :include or :exclude + :ignore => :args_and_calls, #the options being :args_and_calls or :args_only + :callback_include_count => true, + :callback_after_arg_check => false, } def initialize(options=nil) diff --git a/lib/cmock_generator_plugin_callback.rb b/lib/cmock_generator_plugin_callback.rb index ea0dbe7..6533eb5 100644 --- a/lib/cmock_generator_plugin_callback.rb +++ b/lib/cmock_generator_plugin_callback.rb @@ -6,6 +6,7 @@ class CMockGeneratorPluginCallback + attr_accessor :include_count attr_reader :priority attr_reader :config, :utils @@ -13,6 +14,13 @@ class CMockGeneratorPluginCallback @config = config @utils = utils @priority = 3 + + @include_count = @config.callback_include_count + if (@config.callback_after_arg_check) + alias :mock_implementation :mock_implementation_for_callbacks + else + alias :mock_implementation_precheck :mock_implementation_for_callbacks + end end def instance_structure(function) @@ -24,18 +32,24 @@ class CMockGeneratorPluginCallback def mock_function_declarations(function) func_name = function[:name] return_type = function[:return][:const?] ? "const #{function[:return][:type]}" : function[:return][:type] - "typedef #{return_type} (* CMOCK_#{func_name}_CALLBACK)(#{(function[:args_string] == "void") ? '' : function[:args_string] + ', '}int cmock_num_calls);\n" + - "void #{func_name}_StubWithCallback(CMOCK_#{func_name}_CALLBACK Callback);\n" + style = (@include_count ? 1 : 0) | (function[:args].empty? ? 0 : 2) + styles = [ "void", "int cmock_num_calls", function[:args_string], "#{function[:args_string]}, int cmock_num_calls" ] + "typedef #{return_type} (* CMOCK_#{func_name}_CALLBACK)(#{styles[style]});\nvoid #{func_name}_StubWithCallback(CMOCK_#{func_name}_CALLBACK Callback);\n" end - def mock_implementation_precheck(function) + def mock_implementation_for_callbacks(function) func_name = function[:name] - call_string = function[:args].empty? ? '' : function[:args].map{|m| m[:name]}.join(', ') + ', ' + style = (@include_count ? 1 : 0) | (function[:args].empty? ? 0 : 2) | (function[:return][:void?] ? 0 : 4) " if (Mock.#{func_name}_CallbackFunctionPointer != NULL)\n {\n" + - if (function[:return][:void?]) - " Mock.#{func_name}_CallbackFunctionPointer(#{call_string}Mock.#{func_name}_CallbackCalls++);\n return;\n }\n" - else - " return Mock.#{func_name}_CallbackFunctionPointer(#{call_string}Mock.#{func_name}_CallbackCalls++);\n }\n" + case(style) + when 0 then " Mock.#{func_name}_CallbackFunctionPointer();\n return;\n }\n" + when 1 then " Mock.#{func_name}_CallbackFunctionPointer(Mock.#{func_name}_CallbackCalls++);\n return;\n }\n" + when 2 then " Mock.#{func_name}_CallbackFunctionPointer(#{function[:args].map{|m| m[:name]}.join(', ')});\n return;\n }\n" + when 3 then " Mock.#{func_name}_CallbackFunctionPointer(#{function[:args].map{|m| m[:name]}.join(', ')}, Mock.#{func_name}_CallbackCalls++);\n return;\n }\n" + when 4 then " return Mock.#{func_name}_CallbackFunctionPointer(void);\n }\n" + when 5 then " return Mock.#{func_name}_CallbackFunctionPointer(Mock.#{func_name}_CallbackCalls++);\n }\n" + when 6 then " return Mock.#{func_name}_CallbackFunctionPointer(#{function[:args].map{|m| m[:name]}.join(', ')});\n }\n" + when 7 then " return Mock.#{func_name}_CallbackFunctionPointer(#{function[:args].map{|m| m[:name]}.join(', ')}, Mock.#{func_name}_CallbackCalls++);\n }\n" end end diff --git a/test/unit/cmock_generator_plugin_callback_test.rb b/test/unit/cmock_generator_plugin_callback_test.rb index 553664d..599c4fc 100644 --- a/test/unit/cmock_generator_plugin_callback_test.rb +++ b/test/unit/cmock_generator_plugin_callback_test.rb @@ -11,6 +11,9 @@ class CMockGeneratorPluginCallbackTest < Test::Unit::TestCase def setup create_mocks :config, :utils + @config.expect.callback_include_count.returns(true) + @config.expect.callback_after_arg_check.returns(false) + @cmock_generator_plugin_callback = CMockGeneratorPluginCallback.new(@config, @utils) end @@ -36,15 +39,24 @@ class CMockGeneratorPluginCallbackTest < Test::Unit::TestCase end should "add mock function declaration for function without arguments" do - function = {:name => "Maple", :args_string => "void", :return => test_return[:void]} + function = {:name => "Maple", :args_string => "void", :args => [], :return => test_return[:void]} expected = [ "typedef void (* CMOCK_Maple_CALLBACK)(int cmock_num_calls);\n", "void Maple_StubWithCallback(CMOCK_Maple_CALLBACK Callback);\n" ].join returned = @cmock_generator_plugin_callback.mock_function_declarations(function) assert_equal(expected, returned) end + should "add mock function declaration for function without arguments when count is also turned off" do + function = {:name => "Maple", :args_string => "void", :args => [], :return => test_return[:void]} + expected = [ "typedef void (* CMOCK_Maple_CALLBACK)(void);\n", + "void Maple_StubWithCallback(CMOCK_Maple_CALLBACK Callback);\n" ].join + @cmock_generator_plugin_callback.include_count = false + returned = @cmock_generator_plugin_callback.mock_function_declarations(function) + assert_equal(expected, returned) + end + should "add mock function declaration for function with arguments" do - function = {:name => "Maple", :args_string => "int* tofu", :return => test_return[:void]} + function = {:name => "Maple", :args_string => "int* tofu", :args => [1], :return => test_return[:void]} expected = [ "typedef void (* CMOCK_Maple_CALLBACK)(int* tofu, int cmock_num_calls);\n", "void Maple_StubWithCallback(CMOCK_Maple_CALLBACK Callback);\n" ].join returned = @cmock_generator_plugin_callback.mock_function_declarations(function) @@ -52,12 +64,21 @@ class CMockGeneratorPluginCallbackTest < Test::Unit::TestCase end should "add mock function declaration for function with return values" do - function = {:name => "Maple", :args_string => "int* tofu", :return => test_return[:string]} + function = {:name => "Maple", :args_string => "int* tofu", :args => [1], :return => test_return[:string]} expected = [ "typedef const char* (* CMOCK_Maple_CALLBACK)(int* tofu, int cmock_num_calls);\n", "void Maple_StubWithCallback(CMOCK_Maple_CALLBACK Callback);\n" ].join returned = @cmock_generator_plugin_callback.mock_function_declarations(function) assert_equal(expected, returned) end + + should "add mock function declaration for function with return values and count is turned off" do + function = {:name => "Maple", :args_string => "int* tofu", :args => [1], :return => test_return[:string]} + expected = [ "typedef const char* (* CMOCK_Maple_CALLBACK)(int* tofu);\n", + "void Maple_StubWithCallback(CMOCK_Maple_CALLBACK Callback);\n" ].join + @cmock_generator_plugin_callback.include_count = false + returned = @cmock_generator_plugin_callback.mock_function_declarations(function) + assert_equal(expected, returned) + end should "add mock function implementation for functions of style 'void func(void)'" do function = {:name => "Apple", :args => [], :args_string => "void", :return => test_return[:void]} @@ -71,6 +92,19 @@ class CMockGeneratorPluginCallbackTest < Test::Unit::TestCase assert_equal(expected, returned) end + should "add mock function implementation for functions 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", + " return;\n", + " }\n" + ].join + @cmock_generator_plugin_callback.include_count = false + returned = @cmock_generator_plugin_callback.mock_implementation_precheck(function) + assert_equal(expected, returned) + end + should "add mock function implementation for functions of style 'int func(void)'" do function = {:name => "Apple", :args => [], :args_string => "void", :return => test_return[:int]} expected = [" if (Mock.Apple_CallbackFunctionPointer != NULL)\n", @@ -98,6 +132,23 @@ class CMockGeneratorPluginCallbackTest < Test::Unit::TestCase assert_equal(expected, returned) end + should "add mock function implementation for functions 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", + " return;\n", + " }\n" + ].join + @cmock_generator_plugin_callback.include_count = false + returned = @cmock_generator_plugin_callback.mock_implementation_precheck(function) + assert_equal(expected, returned) + end + should "add mock function implementation for functions of style 'int16_t func(int* steak, uint8_t flag)'" do function = {:name => "Apple", :args => [ { :type => 'int*', :name => 'steak', :ptr? => true},