From 492e319e11ac1888819b08d14c83ac33901a5921 Mon Sep 17 00:00:00 2001 From: mvandervoord Date: Thu, 19 Feb 2009 03:28:53 +0000 Subject: [PATCH] * major changes to Expects to support structs, etc... not recommended for general consumption yet. git-svn-id: http://cmock.svn.sourceforge.net/svnroot/cmock/trunk@56 bf332499-1b4d-0410-844d-d2d48d5cc64c --- examples/src/AdcConductor.c | 9 ++ examples/src/AdcConductor.h | 2 + examples/src/AdcHardwareConfigurator.c | 1 - examples/src/AdcModel.c | 4 + examples/src/AdcModel.h | 2 + examples/src/Types.h | 8 +- examples/test/TestAdcConductor.c | 35 ++++++++ gcc.yml | 10 ++- iar_v4.yml | 10 ++- iar_v5.yml | 10 ++- lib/cmock.rb | 4 +- lib/cmock_config.rb | 40 +++++++-- lib/cmock_generator.rb | 2 +- lib/cmock_generator_plugin_cexception.rb | 4 +- lib/cmock_generator_plugin_expect.rb | 9 +- lib/cmock_generator_plugin_ignore.rb | 4 +- lib/cmock_generator_utils.rb | 44 ++++++---- test/unit/cmock_config_test.rb | 42 +++++----- test/unit/cmock_config_test.yml | 4 +- test/unit/cmock_generator_main_test.rb | 4 +- .../cmock_generator_plugin_cexception_test.rb | 8 +- .../cmock_generator_plugin_expect_test.rb | 12 +-- .../cmock_generator_plugin_ignore_test.rb | 4 +- test/unit/cmock_generator_utils_test.rb | 84 +++++++++++++++---- test/unit/cmock_plugin_manager_test.rb | 4 + 25 files changed, 259 insertions(+), 101 deletions(-) diff --git a/examples/src/AdcConductor.c b/examples/src/AdcConductor.c index 36bdfe7..cc2a609 100644 --- a/examples/src/AdcConductor.c +++ b/examples/src/AdcConductor.c @@ -16,3 +16,12 @@ void AdcConductor_Run(void) AdcHardware_StartConversion(); } } + +bool AdcConductor_JustHereToTest(void) +{ + EXAMPLE_STRUCT_T ExampleStruct; + ExampleStruct.x = 5; + ExampleStruct.y = 7; + + return AdcModel_DoNothingExceptTestASpecialType(ExampleStruct); +} diff --git a/examples/src/AdcConductor.h b/examples/src/AdcConductor.h index ec02733..4b3e05a 100644 --- a/examples/src/AdcConductor.h +++ b/examples/src/AdcConductor.h @@ -4,4 +4,6 @@ void AdcConductor_Init(void); void AdcConductor_Run(void); +bool AdcConductor_JustHereToTest(void); + #endif // _ADCCONDUCTOR_H diff --git a/examples/src/AdcHardwareConfigurator.c b/examples/src/AdcHardwareConfigurator.c index 4cf8616..ff53dd5 100644 --- a/examples/src/AdcHardwareConfigurator.c +++ b/examples/src/AdcHardwareConfigurator.c @@ -16,4 +16,3 @@ void Adc_EnableTemperatureChannel(void) { AT91C_BASE_ADC->ADC_CHER = 0x10; } - diff --git a/examples/src/AdcModel.c b/examples/src/AdcModel.c index 2ca4510..6be56d7 100644 --- a/examples/src/AdcModel.c +++ b/examples/src/AdcModel.c @@ -14,3 +14,7 @@ void AdcModel_ProcessInput(uint16 millivolts) TemperatureFilter_ProcessInput(TemperatureCalculator_Calculate(millivolts)); } +bool AdcModel_DoNothingExceptTestASpecialType(EXAMPLE_STRUCT_T ExampleStruct) +{ + //This doesn't really do anything. it's only here to make sure I can compare a struct. +} diff --git a/examples/src/AdcModel.h b/examples/src/AdcModel.h index b17699c..9e0e42b 100644 --- a/examples/src/AdcModel.h +++ b/examples/src/AdcModel.h @@ -4,4 +4,6 @@ bool AdcModel_DoGetSample(void); void AdcModel_ProcessInput(uint16 millivolts); +bool AdcModel_DoNothingExceptTestASpecialType(EXAMPLE_STRUCT_T ExampleStruct); + #endif // _ADCMODEL_H diff --git a/examples/src/Types.h b/examples/src/Types.h index 67f91a1..891df51 100644 --- a/examples/src/Types.h +++ b/examples/src/Types.h @@ -21,7 +21,7 @@ typedef int int32; typedef unsigned short uint16; typedef short int16; typedef unsigned char uint8; -typedef char int8; +typedef char int8; typedef char bool; // Application Special Value Definitions @@ -85,4 +85,10 @@ typedef char bool; #define UINT32_MIN 0x00000000U #endif +typedef struct _EXAMPLE_STRUCT_T +{ + int x; + int y; +} EXAMPLE_STRUCT_T; + #endif // _MYTYPES_H_ diff --git a/examples/test/TestAdcConductor.c b/examples/test/TestAdcConductor.c index 7b8aa8b..39c455f 100644 --- a/examples/test/TestAdcConductor.c +++ b/examples/test/TestAdcConductor.c @@ -1,4 +1,5 @@ #include "unity.h" +#include "UnityHelper.h" #include "Types.h" #include "Types.h" #include "AdcConductor.h" @@ -44,3 +45,37 @@ void testRunShouldGetLatestSampleFromAdcAndPassItToModelAndStartNewConversionWhe AdcConductor_Run(); } + +void testJustHereToTest_Should_ProperlyPassAStructAndVerifyIt(void) +{ + EXAMPLE_STRUCT_T TestStruct; + TestStruct.x = 5; + TestStruct.y = 7; + + AdcModel_DoNothingExceptTestASpecialType_ExpectAndReturn(TestStruct, TRUE); + + TEST_ASSERT_TRUE(AdcConductor_JustHereToTest()); +} + +//void testJustHereToTest_Should_FailThisTestIfYouUncommentXIsBecauseItsWrong(void) +//{ +// EXAMPLE_STRUCT_T TestStruct; +// TestStruct.x = 6; +// TestStruct.y = 7; +// +// AdcModel_DoNothingExceptTestASpecialType_ExpectAndReturn(TestStruct, TRUE); +// +// TEST_ASSERT_TRUE(AdcConductor_JustHereToTest()); +//} +// +//void testJustHereToTest_Should_FailThisTestIfYouUncommentYIsBecauseItsWrong(void) +//{ +// EXAMPLE_STRUCT_T TestStruct; +// TestStruct.x = 5; +// TestStruct.y = 8; +// +// AdcModel_DoNothingExceptTestASpecialType_ExpectAndReturn(TestStruct, TRUE); +// +// TEST_ASSERT_TRUE(AdcConductor_JustHereToTest()); +//} + diff --git a/gcc.yml b/gcc.yml index 93b42d6..e19551f 100644 --- a/gcc.yml +++ b/gcc.yml @@ -33,8 +33,10 @@ linker: extension: '.exe' destination: *build_path cmock: - mock_path: 'examples/mocks/' - includes: + :mock_path: 'examples/mocks/' + :includes: - 'Types.h' - plugins: - - 'ignore' \ No newline at end of file + - 'UnityHelper.h' + :plugins: + - 'ignore' + :unity_helper: 'vendor/unity/src/UnityHelper.h' \ No newline at end of file diff --git a/iar_v4.yml b/iar_v4.yml index 8b94294..498e952 100644 --- a/iar_v4.yml +++ b/iar_v4.yml @@ -85,8 +85,10 @@ simulator: - -d - sim cmock: - mock_path: 'examples/mocks/' - includes: + :mock_path: 'examples/mocks/' + :includes: - 'Types.h' - plugins: - - 'ignore' \ No newline at end of file + - 'UnityHelper.h' + :plugins: + - 'ignore' + :unity_helper: 'vendor/unity/src/UnityHelper.h' \ No newline at end of file diff --git a/iar_v5.yml b/iar_v5.yml index 0374c34..7b6fe2c 100644 --- a/iar_v5.yml +++ b/iar_v5.yml @@ -74,8 +74,10 @@ simulator: - -d - sim cmock: - mock_path: 'examples/mocks/' - includes: + :mock_path: 'examples/mocks/' + :includes: - 'Types.h' - plugins: - - 'ignore' \ No newline at end of file + - 'UnityHelper.h' + :plugins: + - 'ignore' + :unity_helper: 'vendor/unity/src/UnityHelper.h' \ No newline at end of file diff --git a/lib/cmock.rb b/lib/cmock.rb index 234fcd0..d2628d9 100644 --- a/lib/cmock.rb +++ b/lib/cmock.rb @@ -5,6 +5,7 @@ require "#{$here}/cmock_file_writer" require "#{$here}/cmock_config" require "#{$here}/cmock_plugin_manager" require "#{$here}/cmock_generator_utils" +require "#{$here}/cmock_unityhelper_parser" class CMock @@ -26,8 +27,9 @@ class CMock @cfg.set_path(path) cm_parser = CMockHeaderParser.new(File.read(src)) + cm_unityhelper = CMockUnityHelperParser.new(@cfg) cm_writer = CMockFileWriter.new(@cfg) - cm_gen_utils = CMockGeneratorUtils.new(@cfg) + cm_gen_utils = CMockGeneratorUtils.new(@cfg, {:unity_helper => cm_unityhelper}) cm_gen_plugins = CMockPluginManager.new(@cfg, cm_gen_utils) cm_generator = CMockGenerator.new(@cfg, name, cm_writer, cm_gen_utils, cm_gen_plugins) diff --git a/lib/cmock_config.rb b/lib/cmock_config.rb index defd105..76e2897 100644 --- a/lib/cmock_config.rb +++ b/lib/cmock_config.rb @@ -1,16 +1,33 @@ class CMockConfig + CMockTreatAsDefaults = + { + 'INT' => ['int','char','short','long','int8','int16','int32', + 'int8_t','int16_t','int32_t', 'bool','bool_t','BOOL','BOOL_T', + 'INT8','INT16','INT32','INT8_T','INT16_T','INT32_T'], + 'HEX32' => ['unsigned int', 'unsigned long', 'uint32', 'uint32_t', 'UINT32','UINT32_T'], + 'HEX16' => ['unsigned short', 'uint16', 'uint16_t', 'UINT16', 'UINT16_T'], + 'HEX8' => ['unsigned char', 'uint8', 'uint8_t', 'UINT8', 'UINT8_T'], + 'STRING'=> ['char*', 'const char*', 'pCHAR', 'cstring', 'CSTRING'] + } + CMockDefaultOptions = { - 'mock_path' => 'mocks', - 'includes' => [], - 'plugins' => ['cexception', 'ignore'], - 'tab' => ' ', - 'expect_call_count_type' => 'unsigned short', - 'ignore_bool_type' => 'unsigned char', - 'cexception_include' => nil, - 'cexception_throw_type' => 'int', + :mock_path => 'mocks', + :includes => [], + :plugins => ['cexception', 'ignore'], + :tab => ' ', + :expect_call_count_type => 'unsigned short', + :enforce_strict_ordering => false, + :ignore_bool_type => 'unsigned char', + :cexception_include => nil, + :cexception_throw_type => 'int', + :unity_helper => false, + :treat_as => CMockTreatAsDefaults, + :memcpy_if_unknown => true, + :when_ptr_star =>:compare_data, + :when_ptr_brackets => :compare_array, } def initialize(options=nil) @@ -21,7 +38,7 @@ class CMockConfig else raise "If you specify parameters, it should be a filename or a hash of options" end @options = options - @options.each_key { |key| eval("def #{key}() return @options['#{key}'] end") } + @options.each_key { |key| eval("def #{key}() return @options[:#{key}] end") } end def load_config_file_from_yaml yaml_filename @@ -33,4 +50,9 @@ class CMockConfig def set_path(path) @src_path = path end + + def load_unity_helper + return File.new(@options[:unity_helper]).read if (@options[:unity_helper]) + return nil + end end diff --git a/lib/cmock_generator.rb b/lib/cmock_generator.rb index fb588a6..dc8a74d 100644 --- a/lib/cmock_generator.rb +++ b/lib/cmock_generator.rb @@ -143,7 +143,7 @@ class CMockGenerator # Return expected value, if necessary if (function[:rettype] != "void") - file << @utils.make_handle_return(function, "#{@tab}") + file << @utils.code_handle_return_value(function, "#{@tab}") end # Close out the function diff --git a/lib/cmock_generator_plugin_cexception.rb b/lib/cmock_generator_plugin_cexception.rb index 525d2b0..d45e5e3 100644 --- a/lib/cmock_generator_plugin_cexception.rb +++ b/lib/cmock_generator_plugin_cexception.rb @@ -63,10 +63,10 @@ class CMockGeneratorPluginCException lines << "void #{function[:name]}_ExpectAndThrow(#{arg_insert}#{throw_type} toThrow)\n" lines << "{\n" lines << "#{@tab}Mock.#{function[:name]}_CallsExpected++;\n" - lines << @utils.make_expand_array(call_count_type, "Mock.#{function[:name]}_ThrowOnCallCount_Head", "Mock.#{function[:name]}_CallsExpected") + lines << @utils.code_insert_item_into_expect_array(call_count_type, "Mock.#{function[:name]}_ThrowOnCallCount_Head", "Mock.#{function[:name]}_CallsExpected") lines << "#{@tab}Mock.#{function[:name]}_ThrowOnCallCount = Mock.#{function[:name]}_ThrowOnCallCount_Head;\n" lines << "#{@tab}Mock.#{function[:name]}_ThrowOnCallCount += Mock.#{function[:name]}_CallCount;\n" - lines << @utils.make_expand_array(throw_type, "Mock.#{function[:name]}_ThrowValue_Head", "toThrow") + lines << @utils.code_insert_item_into_expect_array(throw_type, "Mock.#{function[:name]}_ThrowValue_Head", "toThrow") lines << "#{@tab}Mock.#{function[:name]}_ThrowValue = Mock.#{function[:name]}_ThrowValue_Head;\n" lines << "#{@tab}Mock.#{function[:name]}_ThrowValue += Mock.#{function[:name]}_CallCount;\n" lines << "#{@tab}ExpectParameters_#{function[:name]}(#{@utils.create_call_list(function)});\n" if (function[:args_string] != "void") diff --git a/lib/cmock_generator_plugin_expect.rb b/lib/cmock_generator_plugin_expect.rb index 1fce09e..d16ab87 100644 --- a/lib/cmock_generator_plugin_expect.rb +++ b/lib/cmock_generator_plugin_expect.rb @@ -1,12 +1,13 @@ class CMockGeneratorPluginExpect - attr_reader :config, :utils, :tab + attr_reader :config, :utils, :tab, :unity_helper def initialize(config, utils) @config = config @tab = @config.tab @utils = utils + @unity_helper = @utils.helpers[:unity_helper] end def instance_structure(function) @@ -55,7 +56,7 @@ class CMockGeneratorPluginExpect lines << "#{@tab}}\n" function[:args].each do |arg| arg_return_type = arg[:type].sub(/const/, '').strip - lines << @utils.make_handle_expected(function, arg_return_type, arg[:name]) + lines << @utils.code_verify_an_arg_expectation(function, arg_return_type, arg[:name]) end lines end @@ -69,7 +70,7 @@ class CMockGeneratorPluginExpect lines << "{\n" function[:args].each do |arg| type = arg[:type].sub(/const/, '').strip - lines << @utils.make_add_new_expected(function, type, arg[:name]) + lines << @utils.code_add_an_arg_expectation(function, type, arg[:name]) end lines << "}\n\n" end @@ -92,7 +93,7 @@ class CMockGeneratorPluginExpect end if (function[:rettype] != "void") - lines << @utils.make_expand_array(function[:rettype], "Mock.#{function[:name]}_Return_Head", "toReturn") + lines << @utils.code_insert_item_into_expect_array(function[:rettype], "Mock.#{function[:name]}_Return_Head", "toReturn") lines << "#{@tab}Mock.#{function[:name]}_Return = Mock.#{function[:name]}_Return_Head;\n" lines << "#{@tab}Mock.#{function[:name]}_Return += Mock.#{function[:name]}_CallCount;\n" end diff --git a/lib/cmock_generator_plugin_ignore.rb b/lib/cmock_generator_plugin_ignore.rb index 6d92026..273a29b 100644 --- a/lib/cmock_generator_plugin_ignore.rb +++ b/lib/cmock_generator_plugin_ignore.rb @@ -32,7 +32,7 @@ class CMockGeneratorPluginIgnore if (function[:rettype] == "void") lines << "#{@tab}#{@tab}return;\n" else - lines << @utils.make_handle_return(function, "#{@tab}#{@tab}") + lines << @utils.code_handle_return_value(function, "#{@tab}#{@tab}") end lines << "#{@tab}}\n" end @@ -48,7 +48,7 @@ class CMockGeneratorPluginIgnore lines << "void #{function[:name]}_IgnoreAndReturn(#{function[:rettype]} toReturn)\n" lines << "{\n" lines << "#{@tab}Mock.#{function[:name]}_IgnoreBool = (unsigned char)1;\n" - lines << @utils.make_expand_array(function[:rettype], "Mock.#{function[:name]}_Return_Head", "toReturn") + lines << @utils.code_insert_item_into_expect_array(function[:rettype], "Mock.#{function[:name]}_Return_Head", "toReturn") lines << "#{@tab}Mock.#{function[:name]}_Return = Mock.#{function[:name]}_Return_Head;\n" lines << "#{@tab}Mock.#{function[:name]}_Return += Mock.#{function[:name]}_CallCount;\n" lines << "}\n\n" diff --git a/lib/cmock_generator_utils.rb b/lib/cmock_generator_utils.rb index 63b0303..d80ef32 100644 --- a/lib/cmock_generator_utils.rb +++ b/lib/cmock_generator_utils.rb @@ -1,11 +1,12 @@ class CMockGeneratorUtils - attr_reader :config, :tab + attr_accessor :config, :tab, :helpers - def initialize(config) + def initialize(config, helpers={}) @config = config @tab = @config.tab + @helpers = helpers end def create_call_list(function) @@ -20,7 +21,7 @@ class CMockGeneratorUtils return call_list end - def make_expand_array(type, array, newValue) + def code_insert_item_into_expect_array(type, array, newValue) lines = ["\n"] lines << "#{@tab}{\n" lines << "#{@tab}#{@tab}int sz = 0;\n" @@ -45,37 +46,46 @@ class CMockGeneratorUtils lines << "#{@tab}}\n" end - def make_handle_return(function, indent) + def code_handle_return_value(function, indent) lines = ["\n"] - lines << "#{indent}if(Mock.#{function[:name]}_Return != Mock.#{function[:name]}_Return_HeadTail)\n" + lines << "#{indent}#{function[:rettype]} toReturn;\n" + lines << "#{indent}if (Mock.#{function[:name]}_Return != Mock.#{function[:name]}_Return_HeadTail)\n" lines << "#{indent}{\n" - lines << "#{indent}#{@tab}#{function[:rettype]} toReturn = *Mock.#{function[:name]}_Return;\n" + lines << "#{indent}#{@tab}memcpy(&toReturn, Mock.#{function[:name]}_Return, sizeof(#{function[:rettype]}));\n" lines << "#{indent}#{@tab}Mock.#{function[:name]}_Return++;\n" - lines << "#{indent}#{@tab}return toReturn;\n" lines << "#{indent}}\n" lines << "#{indent}else\n" lines << "#{indent}{\n" - lines << "#{indent}#{@tab}return *Mock.#{function[:name]}_Return_Head;\n" + lines << "#{indent}#{@tab}memcpy(&toReturn, Mock.#{function[:name]}_Return_Head, sizeof(#{function[:rettype]}));\n" lines << "#{indent}}\n" + lines << "#{indent}return toReturn;\n" end - def make_add_new_expected(function, arg_type, expected) - lines = make_expand_array(arg_type, "Mock.#{function[:name]}_Expected_#{expected}_Head", expected) + def code_add_an_arg_expectation(function, arg_type, expected) + lines = code_insert_item_into_expect_array(arg_type, "Mock.#{function[:name]}_Expected_#{expected}_Head", expected) lines << "#{@tab}Mock.#{function[:name]}_Expected_#{expected} = Mock.#{function[:name]}_Expected_#{expected}_Head;\n" lines << "#{@tab}Mock.#{function[:name]}_Expected_#{expected} += Mock.#{function[:name]}_CallCount;\n" end - def make_handle_expected(function, arg_type, actual) + def code_verify_an_arg_expectation(function, arg_type, actual) + expect = expect_helper(arg_type, '*p_expected', actual, "\"Function '#{function[:name]}' called with unexpected value for parameter '#{actual}'.\"") lines = ["\n"] - lines << "#{@tab}if(Mock.#{function[:name]}_Expected_#{actual} != Mock.#{function[:name]}_Expected_#{actual}_HeadTail)\n" + lines << "#{@tab}if (Mock.#{function[:name]}_Expected_#{actual} != Mock.#{function[:name]}_Expected_#{actual}_HeadTail)\n" lines << "#{@tab}{\n" lines << "#{@tab}#{@tab}#{arg_type}* p_expected = Mock.#{function[:name]}_Expected_#{actual};\n" lines << "#{@tab}#{@tab}Mock.#{function[:name]}_Expected_#{actual}++;\n" - if (arg_type == "char*" || arg_type == "const char*") - lines << "#{@tab}#{@tab}TEST_ASSERT_EQUAL_STRING_MESSAGE(*p_expected, #{actual}, \"Function '#{function[:name]}' called with unexpected string for parameter '#{actual}'.\");\n" - else - lines << "#{@tab}#{@tab}TEST_ASSERT_EQUAL_MESSAGE(*p_expected, #{actual}, \"Function '#{function[:name]}' called with unexpected value for parameter '#{actual}'.\");\n" - end + lines << "#{@tab}#{@tab}#{expect};\n" lines << "#{@tab}}\n" end + + def expect_helper(c_type, expected, actual, msg) + unity_func = (@helpers.nil? or @helpers[:unity_helper].nil?) ? "TEST_ASSERT_EQUAL_MESSAGE" : @helpers[:unity_helper].get_helper(c_type) + unity_msg = (unity_func =~ /_MESSAGE/) ? ", #{msg}" : '' + if (unity_func == "TEST_ASSERT_EQUAL_MEMORY_MESSAGE") + full_expected = (expected.strip[0] == 42) ? expected.slice(1..-1) : "&(#{expected})" + return "#{unity_func}(#{full_expected}, &(#{actual}), sizeof(#{c_type})#{unity_msg})" + else + return "#{unity_func}(#{expected}, #{actual}#{unity_msg})" + end + end end \ No newline at end of file diff --git a/test/unit/cmock_config_test.rb b/test/unit/cmock_config_test.rb index f30bf14..e4de22f 100644 --- a/test/unit/cmock_config_test.rb +++ b/test/unit/cmock_config_test.rb @@ -10,41 +10,41 @@ class CMockConfigTest < Test::Unit::TestCase should "use default settings when no parameters are specified" do config = CMockConfig.new - assert_equal(CMockConfig::CMockDefaultOptions['mock_path'], config.mock_path) - assert_equal(CMockConfig::CMockDefaultOptions['includes'], config.includes) - assert_equal(CMockConfig::CMockDefaultOptions['plugins'], config.plugins) - assert_equal(CMockConfig::CMockDefaultOptions['tab'], config.tab) - assert_equal(CMockConfig::CMockDefaultOptions['expect_call_count_type'],config.expect_call_count_type) - assert_equal(CMockConfig::CMockDefaultOptions['ignore_bool_type'], config.ignore_bool_type) - assert_equal(CMockConfig::CMockDefaultOptions['cexception_include'], config.cexception_include) - assert_equal(CMockConfig::CMockDefaultOptions['cexception_throw_type'], config.cexception_throw_type) + assert_equal(CMockConfig::CMockDefaultOptions[:mock_path], config.mock_path) + assert_equal(CMockConfig::CMockDefaultOptions[:includes], config.includes) + assert_equal(CMockConfig::CMockDefaultOptions[:plugins], config.plugins) + assert_equal(CMockConfig::CMockDefaultOptions[:tab], config.tab) + assert_equal(CMockConfig::CMockDefaultOptions[:expect_call_count_type],config.expect_call_count_type) + assert_equal(CMockConfig::CMockDefaultOptions[:ignore_bool_type], config.ignore_bool_type) + assert_equal(CMockConfig::CMockDefaultOptions[:cexception_include], config.cexception_include) + assert_equal(CMockConfig::CMockDefaultOptions[:cexception_throw_type], config.cexception_throw_type) end should "replace only options specified in a hash" do test_includes = ['hello'] test_bool_type = 'bool' - config = CMockConfig.new('includes' => test_includes, 'ignore_bool_type' => test_bool_type) - assert_equal(CMockConfig::CMockDefaultOptions['mock_path'], config.mock_path) + config = CMockConfig.new(:includes => test_includes, :ignore_bool_type => test_bool_type) + assert_equal(CMockConfig::CMockDefaultOptions[:mock_path], config.mock_path) assert_equal(test_includes, config.includes) - assert_equal(CMockConfig::CMockDefaultOptions['plugins'], config.plugins) - assert_equal(CMockConfig::CMockDefaultOptions['tab'], config.tab) - assert_equal(CMockConfig::CMockDefaultOptions['expect_call_count_type'],config.expect_call_count_type) + assert_equal(CMockConfig::CMockDefaultOptions[:plugins], config.plugins) + assert_equal(CMockConfig::CMockDefaultOptions[:tab], config.tab) + assert_equal(CMockConfig::CMockDefaultOptions[:expect_call_count_type], config.expect_call_count_type) assert_equal(test_bool_type, config.ignore_bool_type) - assert_equal(CMockConfig::CMockDefaultOptions['cexception_include'], config.cexception_include) - assert_equal(CMockConfig::CMockDefaultOptions['cexception_throw_type'], config.cexception_throw_type) + assert_equal(CMockConfig::CMockDefaultOptions[:cexception_include], config.cexception_include) + assert_equal(CMockConfig::CMockDefaultOptions[:cexception_throw_type], config.cexception_throw_type) end should "replace only options specified in a yaml file" do test_plugins = ['soda','pizza'] test_throw_type = 'uint32' config = CMockConfig.new("#{File.expand_path(File.dirname(__FILE__))}/cmock_config_test.yml") - assert_equal(CMockConfig::CMockDefaultOptions['mock_path'], config.mock_path) - assert_equal(CMockConfig::CMockDefaultOptions['includes'], config.includes) + assert_equal(CMockConfig::CMockDefaultOptions[:mock_path], config.mock_path) + assert_equal(CMockConfig::CMockDefaultOptions[:includes], config.includes) assert_equal(test_plugins, config.plugins) - assert_equal(CMockConfig::CMockDefaultOptions['tab'], config.tab) - assert_equal(CMockConfig::CMockDefaultOptions['expect_call_count_type'],config.expect_call_count_type) - assert_equal(CMockConfig::CMockDefaultOptions['ignore_bool_type'], config.ignore_bool_type) - assert_equal(CMockConfig::CMockDefaultOptions['cexception_include'], config.cexception_include) + assert_equal(CMockConfig::CMockDefaultOptions[:tab], config.tab) + assert_equal(CMockConfig::CMockDefaultOptions[:expect_call_count_type], config.expect_call_count_type) + assert_equal(CMockConfig::CMockDefaultOptions[:ignore_bool_type], config.ignore_bool_type) + assert_equal(CMockConfig::CMockDefaultOptions[:cexception_include], config.cexception_include) assert_equal(test_throw_type, config.cexception_throw_type) end end diff --git a/test/unit/cmock_config_test.yml b/test/unit/cmock_config_test.yml index c07c19d..183666c 100644 --- a/test/unit/cmock_config_test.yml +++ b/test/unit/cmock_config_test.yml @@ -1,5 +1,5 @@ cmock: - plugins: + :plugins: - 'soda' - 'pizza' - cexception_throw_type: 'uint32' \ No newline at end of file + :cexception_throw_type: 'uint32' \ No newline at end of file diff --git a/test/unit/cmock_generator_main_test.rb b/test/unit/cmock_generator_main_test.rb index 6aea1de..81c2a09 100644 --- a/test/unit/cmock_generator_main_test.rb +++ b/test/unit/cmock_generator_main_test.rb @@ -283,7 +283,7 @@ class CMockGeneratorTest < Test::Unit::TestCase ] @plugins.expect.run(:mock_implementation_prefix, function).returns([" PreSupaFunctionUno.bool"," PreSupaFunctionDos.bool"]) @plugins.expect.run(:mock_implementation, function).returns([" MockSupaFunctionUno(uint32 sandwiches, const char* named)"," MockSupaFunctionDos(uint32 sandwiches, const char* named)"]) - @utils.expect.make_handle_return(function," ").returns(" UtilsSupaFunction.bool") + @utils.expect.code_handle_return_value(function," ").returns(" UtilsSupaFunction.bool") @cmock_generator.create_mock_implementation(output, function) @@ -311,7 +311,7 @@ class CMockGeneratorTest < Test::Unit::TestCase ] @plugins.expect.run(:mock_implementation_prefix, function).returns([" PreSupaFunctionUno.int"," PreSupaFunctionDos.int"]) @plugins.expect.run(:mock_implementation, function).returns([" MockSupaFunctionUno(uint32 sandwiches)"," MockSupaFunctionDos(uint32 sandwiches)"]) - @utils.expect.make_handle_return(function," ").returns(" UtilsSupaFunction.int") + @utils.expect.code_handle_return_value(function," ").returns(" UtilsSupaFunction.int") @cmock_generator.create_mock_implementation(output, function) diff --git a/test/unit/cmock_generator_plugin_cexception_test.rb b/test/unit/cmock_generator_plugin_cexception_test.rb index 00cc660..1140923 100644 --- a/test/unit/cmock_generator_plugin_cexception_test.rb +++ b/test/unit/cmock_generator_plugin_cexception_test.rb @@ -96,8 +96,8 @@ class CMockGeneratorPluginCExceptionTest < Test::Unit::TestCase function = {:name => "Pear", :args_string => "void", :args => [], :rettype => "void"} @config.expect.cexception_call_count_type.returns("uint32") @config.expect.cexception_throw_type.returns("EXCEPTION_TYPE") - @utils.expect.make_expand_array("uint32", "Mock.Pear_ThrowOnCallCount_Head", "Mock.Pear_CallsExpected").returns("mock_return_1") - @utils.expect.make_expand_array("EXCEPTION_TYPE", "Mock.Pear_ThrowValue_Head", "toThrow").returns("mock_return_2") + @utils.expect.code_insert_item_into_expect_array("uint32", "Mock.Pear_ThrowOnCallCount_Head", "Mock.Pear_CallsExpected").returns("mock_return_1") + @utils.expect.code_insert_item_into_expect_array("EXCEPTION_TYPE", "Mock.Pear_ThrowValue_Head", "toThrow").returns("mock_return_2") expected = ["void Pear_ExpectAndThrow(EXCEPTION_TYPE toThrow)\n", "{\n", @@ -118,8 +118,8 @@ class CMockGeneratorPluginCExceptionTest < Test::Unit::TestCase function = {:name => "Pear", :args_string => "int blah", :args => [{ :type => "int", :name => "blah" }], :rettype => "void"} @config.expect.cexception_call_count_type.returns("uint32") @config.expect.cexception_throw_type.returns("EXCEPTION_TYPE") - @utils.expect.make_expand_array("uint32", "Mock.Pear_ThrowOnCallCount_Head", "Mock.Pear_CallsExpected").returns("mock_return_1") - @utils.expect.make_expand_array("EXCEPTION_TYPE", "Mock.Pear_ThrowValue_Head", "toThrow").returns("mock_return_2") + @utils.expect.code_insert_item_into_expect_array("uint32", "Mock.Pear_ThrowOnCallCount_Head", "Mock.Pear_CallsExpected").returns("mock_return_1") + @utils.expect.code_insert_item_into_expect_array("EXCEPTION_TYPE", "Mock.Pear_ThrowValue_Head", "toThrow").returns("mock_return_2") @utils.expect.create_call_list(function).returns("mock_return_3") expected = ["void Pear_ExpectAndThrow(int blah, EXCEPTION_TYPE toThrow)\n", diff --git a/test/unit/cmock_generator_plugin_expect_test.rb b/test/unit/cmock_generator_plugin_expect_test.rb index a084d50..7cc8a1a 100644 --- a/test/unit/cmock_generator_plugin_expect_test.rb +++ b/test/unit/cmock_generator_plugin_expect_test.rb @@ -6,6 +6,7 @@ class CMockGeneratorPluginExpectTest < Test::Unit::TestCase create_mocks :config, :utils @config.expect.tab.returns(" ") @config.stubs!(:respond_to?).returns(true) + @utils.expect.helpers.returns({}) @cmock_generator_plugin_expect = CMockGeneratorPluginExpect.new(@config, @utils) end @@ -16,6 +17,7 @@ class CMockGeneratorPluginExpectTest < Test::Unit::TestCase assert_equal(@config, @cmock_generator_plugin_expect.config) assert_equal(@utils, @cmock_generator_plugin_expect.utils) assert_equal(" ", @cmock_generator_plugin_expect.tab) + assert_equal(nil, @cmock_generator_plugin_expect.unity_helper) end should "not include any additional include files" do @@ -127,8 +129,8 @@ class CMockGeneratorPluginExpectTest < Test::Unit::TestCase should "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" } ], :rettype => "int"} - @utils.expect.make_handle_expected(function, function[:args][0][:type], function[:args][0][:name]).returns("mocked_retval_1") - @utils.expect.make_handle_expected(function, function[:args][1][:type], function[:args][1][:name]).returns("mocked_retval_2") + @utils.expect.code_verify_an_arg_expectation(function, function[:args][0][:type], function[:args][0][:name]).returns("mocked_retval_1") + @utils.expect.code_verify_an_arg_expectation(function, function[:args][1][:type], function[:args][1][:name]).returns("mocked_retval_2") expected = [" Mock.Cherry_CallCount++;\n", " if (Mock.Cherry_CallCount > Mock.Cherry_CallsExpected)\n", @@ -155,7 +157,7 @@ class CMockGeneratorPluginExpectTest < Test::Unit::TestCase should "add mock interfaces for functions of style 'unsigned short func(void)'" do function = {:name => "Orange", :args => [], :args_string => "void", :rettype => "unsigned short"} - @utils.expect.make_expand_array(function[:rettype], "Mock.Orange_Return_Head","toReturn").returns("mock_retval_1") + @utils.expect.code_insert_item_into_expect_array(function[:rettype], "Mock.Orange_Return_Head","toReturn").returns("mock_retval_1") expected = ["void Orange_ExpectAndReturn(unsigned short toReturn)\n", "{\n", @@ -171,9 +173,9 @@ class CMockGeneratorPluginExpectTest < Test::Unit::TestCase should "add mock interfaces for functions of style 'int func(char* pescado)'" do function = {:name => "Lemon", :args => [{ :type => "char*", :name => "pescado"}], :args_string => "char* pescado", :rettype => "int"} - @utils.expect.make_add_new_expected(function, "char*", "pescado").returns("mock_retval_2") + @utils.expect.code_add_an_arg_expectation(function, "char*", "pescado").returns("mock_retval_2") @utils.expect.create_call_list(function).returns("mock_retval_3") - @utils.expect.make_expand_array(function[:rettype], "Mock.Lemon_Return_Head","toReturn").returns("mock_retval_1") + @utils.expect.code_insert_item_into_expect_array(function[:rettype], "Mock.Lemon_Return_Head","toReturn").returns("mock_retval_1") expected = ["void ExpectParameters_Lemon(char* pescado)\n", "{\n", diff --git a/test/unit/cmock_generator_plugin_ignore_test.rb b/test/unit/cmock_generator_plugin_ignore_test.rb index ba4d24b..a55f46c 100644 --- a/test/unit/cmock_generator_plugin_ignore_test.rb +++ b/test/unit/cmock_generator_plugin_ignore_test.rb @@ -58,7 +58,7 @@ class CMockGeneratorPluginIgnoreTest < Test::Unit::TestCase should "add required code to implementation prefix with return functions" do function = {:name => "Fungus", :args_string => "void", :rettype => "int"} - @utils.expect.make_handle_return(function, " ").returns(" mock_return_1") + @utils.expect.code_handle_return_value(function, " ").returns(" mock_return_1") expected = [" if (Mock.Fungus_IgnoreBool)\n", " {\n", @@ -86,7 +86,7 @@ class CMockGeneratorPluginIgnoreTest < Test::Unit::TestCase should "add a new mock interface for ignoring when function has return value" do function = {:name => "Slime", :args => [], :args_string => "void", :rettype => "uint32"} - @utils.expect.make_expand_array("uint32", "Mock.Slime_Return_Head", "toReturn").returns("mock_return_1") + @utils.expect.code_insert_item_into_expect_array("uint32", "Mock.Slime_Return_Head", "toReturn").returns("mock_return_1") expected = ["void Slime_IgnoreAndReturn(uint32 toReturn)\n", "{\n", diff --git a/test/unit/cmock_generator_utils_test.rb b/test/unit/cmock_generator_utils_test.rb index 3645aff..45a2f44 100644 --- a/test/unit/cmock_generator_utils_test.rb +++ b/test/unit/cmock_generator_utils_test.rb @@ -3,7 +3,7 @@ require File.expand_path(File.dirname(__FILE__)) + "/../../lib/cmock_generator_u class CMockGeneratorUtilsTest < Test::Unit::TestCase def setup - create_mocks :config + create_mocks :config, :unity_helper @config.expect.tab.returns(" ") @cmock_generator_utils = CMockGeneratorUtils.new(@config) end @@ -14,6 +14,16 @@ class CMockGeneratorUtilsTest < Test::Unit::TestCase should "have set up internal accessors correctly on init" do assert_equal(@config, @cmock_generator_utils.config) assert_equal(" ", @cmock_generator_utils.tab) + assert_equal({}, @cmock_generator_utils.helpers) + end + + should "have set up internal accessors correctly on init, complete with passed helpers" do + create_mocks :config + @config.expect.tab.returns(" ") + @cmock_generator_utils = CMockGeneratorUtils.new(@config, {:A, :B}) + assert_equal(@config, @cmock_generator_utils.config) + assert_equal(" ", @cmock_generator_utils.tab) + assert_equal({:A, :B},@cmock_generator_utils.helpers) end should "set up an empty call list if no arguments passed" do @@ -64,7 +74,7 @@ class CMockGeneratorUtilsTest < Test::Unit::TestCase " arrayTail = &array[sz+1];\n", " }\n" ] - returned = @cmock_generator_utils.make_expand_array(the_type, the_array, new_value) + returned = @cmock_generator_utils.code_insert_item_into_expect_array(the_type, the_array, new_value) assert_equal(expected, returned) end @@ -72,18 +82,19 @@ class CMockGeneratorUtilsTest < Test::Unit::TestCase function = { :name => "Spatula", :rettype => "uint64"} indent = "[tab]" expected = ["\n", - "[tab]if(Mock.Spatula_Return != Mock.Spatula_Return_HeadTail)\n", + "[tab]uint64 toReturn;\n", + "[tab]if (Mock.Spatula_Return != Mock.Spatula_Return_HeadTail)\n", "[tab]{\n", - "[tab] uint64 toReturn = *Mock.Spatula_Return;\n", + "[tab] memcpy(&toReturn, Mock.Spatula_Return, sizeof(uint64));\n", "[tab] Mock.Spatula_Return++;\n", - "[tab] return toReturn;\n", "[tab]}\n", "[tab]else\n", "[tab]{\n", - "[tab] return *Mock.Spatula_Return_Head;\n", - "[tab]}\n" + "[tab] memcpy(&toReturn, Mock.Spatula_Return_Head, sizeof(uint64));\n", + "[tab]}\n", + "[tab]return toReturn;\n" ] - returned = @cmock_generator_utils.make_handle_return(function, indent) + returned = @cmock_generator_utils.code_handle_return_value(function, indent) assert_equal(expected, returned) end @@ -117,7 +128,7 @@ class CMockGeneratorUtilsTest < Test::Unit::TestCase " Mock.PizzaCutter_Expected_Spork = Mock.PizzaCutter_Expected_Spork_Head;\n", " Mock.PizzaCutter_Expected_Spork += Mock.PizzaCutter_CallCount;\n" ] - returned = @cmock_generator_utils.make_add_new_expected(function, var_type, var_name) + returned = @cmock_generator_utils.code_add_an_arg_expectation(function, var_type, var_name) assert_equal(expected, returned) end @@ -127,31 +138,74 @@ class CMockGeneratorUtilsTest < Test::Unit::TestCase var_name = "CorkScrew" expected = ["\n", - " if(Mock.CanOpener_Expected_CorkScrew != Mock.CanOpener_Expected_CorkScrew_HeadTail)\n", + " if (Mock.CanOpener_Expected_CorkScrew != Mock.CanOpener_Expected_CorkScrew_HeadTail)\n", " {\n", " uint16* p_expected = Mock.CanOpener_Expected_CorkScrew;\n", " Mock.CanOpener_Expected_CorkScrew++;\n", " TEST_ASSERT_EQUAL_MESSAGE(*p_expected, CorkScrew, \"Function 'CanOpener' called with unexpected value for parameter 'CorkScrew'.\");\n", " }\n" ] - returned = @cmock_generator_utils.make_handle_expected(function, var_type, var_name) + returned = @cmock_generator_utils.code_verify_an_arg_expectation(function, var_type, var_name) assert_equal(expected, returned) end - + should "make handle expected for character strings" do function = { :name => "MeasureCup", :rettype => "uint64"} var_type = "const char*" var_name = "TeaSpoon" + @cmock_generator_utils.helpers = {:unity_helper => @unity_helper} + @unity_helper.expect.get_helper(var_type).returns("TEST_ASSERT_EQUAL_STRING_MESSAGE") + expected = ["\n", - " if(Mock.MeasureCup_Expected_TeaSpoon != Mock.MeasureCup_Expected_TeaSpoon_HeadTail)\n", + " if (Mock.MeasureCup_Expected_TeaSpoon != Mock.MeasureCup_Expected_TeaSpoon_HeadTail)\n", " {\n", " const char** p_expected = Mock.MeasureCup_Expected_TeaSpoon;\n", " Mock.MeasureCup_Expected_TeaSpoon++;\n", - " TEST_ASSERT_EQUAL_STRING_MESSAGE(*p_expected, TeaSpoon, \"Function 'MeasureCup' called with unexpected string for parameter 'TeaSpoon'.\");\n", + " TEST_ASSERT_EQUAL_STRING_MESSAGE(*p_expected, TeaSpoon, \"Function 'MeasureCup' called with unexpected value for parameter 'TeaSpoon'.\");\n", " }\n" ] - returned = @cmock_generator_utils.make_handle_expected(function, var_type, var_name) + returned = @cmock_generator_utils.code_verify_an_arg_expectation(function, var_type, var_name) + assert_equal(expected, returned) + end + + should "make handle expected for custom types" do + function = { :name => "TeaPot", :rettype => "uint64"} + var_type = "MANDELBROT_SET_T" + var_name = "TeaSpoon" + + @cmock_generator_utils.helpers = {:unity_helper => @unity_helper} + @unity_helper.expect.get_helper(var_type).returns("TEST_ASSERT_EQUAL_MANDELBROT_SET_T_MESSAGE") + + expected = ["\n", + " if (Mock.TeaPot_Expected_TeaSpoon != Mock.TeaPot_Expected_TeaSpoon_HeadTail)\n", + " {\n", + " MANDELBROT_SET_T* p_expected = Mock.TeaPot_Expected_TeaSpoon;\n", + " Mock.TeaPot_Expected_TeaSpoon++;\n", + " TEST_ASSERT_EQUAL_MANDELBROT_SET_T_MESSAGE(*p_expected, TeaSpoon, \"Function 'TeaPot' called with unexpected value for parameter 'TeaSpoon'.\");\n", + " }\n" + ] + returned = @cmock_generator_utils.code_verify_an_arg_expectation(function, var_type, var_name) + assert_equal(expected, returned) + end + + should "make handle default types with memory compares, which involves extra work" do + function = { :name => "Toaster", :rettype => "uint64"} + var_type = "SOME_STRUCT" + var_name = "Bread" + + @cmock_generator_utils.helpers = {:unity_helper => @unity_helper} + @unity_helper.expect.get_helper(var_type).returns("TEST_ASSERT_EQUAL_MEMORY_MESSAGE") + + expected = ["\n", + " if (Mock.Toaster_Expected_Bread != Mock.Toaster_Expected_Bread_HeadTail)\n", + " {\n", + " SOME_STRUCT* p_expected = Mock.Toaster_Expected_Bread;\n", + " Mock.Toaster_Expected_Bread++;\n", + " TEST_ASSERT_EQUAL_MEMORY_MESSAGE(p_expected, &(Bread), sizeof(SOME_STRUCT), \"Function 'Toaster' called with unexpected value for parameter 'Bread'.\");\n", + " }\n" + ] + returned = @cmock_generator_utils.code_verify_an_arg_expectation(function, var_type, var_name) assert_equal(expected, returned) end end diff --git a/test/unit/cmock_plugin_manager_test.rb b/test/unit/cmock_plugin_manager_test.rb index 769671a..74d08ce 100644 --- a/test/unit/cmock_plugin_manager_test.rb +++ b/test/unit/cmock_plugin_manager_test.rb @@ -13,6 +13,7 @@ class CMockPluginManagerTest < Test::Unit::TestCase should "return all plugins by default" do @config.stubs!(:tab).returns(" ") @config.expect.plugins.returns(['cexception','ignore']) + @utils.expect.helpers.returns({}) @cmock_plugins = CMockPluginManager.new(@config, @utils) @@ -31,6 +32,7 @@ class CMockPluginManagerTest < Test::Unit::TestCase should "return restricted plugins based on config" do @config.stubs!(:tab).returns(" ") @config.expect.plugins.returns([]) + @utils.expect.helpers.returns({}) @cmock_plugins = CMockPluginManager.new(@config, @utils) @@ -49,6 +51,7 @@ class CMockPluginManagerTest < Test::Unit::TestCase should "run a desired method over each plugin requested and return the results" do @config.stubs!(:tab).returns(" ") @config.expect.plugins.returns([]) + @utils.expect.helpers.returns({}) @cmock_plugins = CMockPluginManager.new(@config, @utils) @cmock_plugins.plugins = [@pluginA, @pluginB] @@ -63,6 +66,7 @@ class CMockPluginManagerTest < Test::Unit::TestCase should "run a desired method and arg list over each plugin requested and return the results" do @config.stubs!(:tab).returns(" ") @config.expect.plugins.returns([]) + @utils.expect.helpers.returns({}) @cmock_plugins = CMockPluginManager.new(@config, @utils) @cmock_plugins.plugins = [@pluginA, @pluginB]