diff --git a/gcc.yml b/gcc.yml index d8a6d3a..93b42d6 100644 --- a/gcc.yml +++ b/gcc.yml @@ -31,4 +31,10 @@ linker: bin_files: prefix: '-o' extension: '.exe' - destination: *build_path \ No newline at end of file + destination: *build_path +cmock: + mock_path: 'examples/mocks/' + includes: + - 'Types.h' + plugins: + - 'ignore' \ No newline at end of file diff --git a/iar_v4.yml b/iar_v4.yml index b2ceca8..8b94294 100644 --- a/iar_v4.yml +++ b/iar_v4.yml @@ -83,4 +83,10 @@ simulator: - -p - [*tools_root, 'arm\config\ioat91sam7X256.ddf'] - -d - - sim \ No newline at end of file + - sim +cmock: + mock_path: 'examples/mocks/' + includes: + - 'Types.h' + plugins: + - 'ignore' \ No newline at end of file diff --git a/iar_v5.yml b/iar_v5.yml index 0106a88..0374c34 100644 --- a/iar_v5.yml +++ b/iar_v5.yml @@ -72,4 +72,10 @@ simulator: - -p - [*tools_root, 'arm\config\debugger\Atmel\ioat91sam7X256.ddf'] - -d - - sim \ No newline at end of file + - sim +cmock: + mock_path: 'examples/mocks/' + includes: + - 'Types.h' + plugins: + - 'ignore' \ No newline at end of file diff --git a/lib/cmock.rb b/lib/cmock.rb index 8ca98c7..ff0e42b 100644 --- a/lib/cmock.rb +++ b/lib/cmock.rb @@ -7,12 +7,9 @@ require "#{$here}/cmock_plugin_manager" require "#{$here}/cmock_generator_utils" class CMock - - def initialize(mocks_path='mocks', includes=[], use_cexception=false, allow_ignore_mock=false) - @mocks_path = mocks_path - @includes = includes - @use_cexception = use_cexception - @allow_ignore_mock = allow_ignore_mock + + def initialize(options=nil) + @cfg = CMockConfig.new(options) end def setup_mocks(files) @@ -26,13 +23,13 @@ class CMock def generate_mock(src) name = File.basename(src, '.h') path = File.dirname(src) + @cfg.set_path(path) - cm_config = CMockConfig.new(path, @mocks_path, @includes, @use_cexception, @allow_ignore_mock) cm_parser = CMockHeaderParser.new(File.read(src)) - cm_writer = CMockFileWriter.new(cm_config) - cm_gen_utils = CMockGeneratorUtils.new(cm_config) - cm_gen_plugins = CMockPluginManager.new(cm_config, cm_gen_utils).get_generator_plugins - cm_generator = CMockGenerator.new(cm_config, name, cm_writer, cm_gen_utils, cm_gen_plugins) + cm_writer = CMockFileWriter.new(@cfg) + cm_gen_utils = CMockGeneratorUtils.new(@cfg) + cm_gen_plugins = CMockPluginManager.new(@cfg, cm_gen_utils).get_generator_plugins + cm_generator = CMockGenerator.new(@cfg, name, cm_writer, cm_gen_utils, cm_gen_plugins) puts "Creating mock for #{name}..." diff --git a/lib/cmock_config.rb b/lib/cmock_config.rb index 9b76707..74ebd3b 100644 --- a/lib/cmock_config.rb +++ b/lib/cmock_config.rb @@ -1,18 +1,47 @@ class CMockConfig - attr_accessor :src_path, :mock_path, :tab, :includes, :use_cexception, :allow_ignore_mock, :call_count_type, :ignore_bool_type + attr_accessor :src_path, :mock_path, :tab, :includes, :plugins, :call_count_type, :ignore_bool_type, :cexception_include attr_accessor :throw_type - def initialize(src_path='src', mock_path='mocks', includes=[], use_cexception=true, allow_ignore_mock=false, tab=' ') - @src_path = src_path - @mock_path = mock_path - @tab = tab - @throw_type = 'int' - @call_count_type = 'unsigned short' - @ignore_bool_type = 'unsigned char' - @includes = includes - @use_cexception = use_cexception - @allow_ignore_mock = allow_ignore_mock + 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', + } + + def initialize(options=nil) + + case(options) + when NilClass then options = CMockDefaultOptions.clone + when String then options = CMockDefaultOptions.clone.merge(load_config_file_from_yaml(options)) + when Hash then options = CMockDefaultOptions.clone.merge(options) + else raise "If you specify parameters, it should be a filename or a hash of options" + end + + @mock_path = options['mock_path'] + @tab = options['tab'] + @includes = options['includes'] + @plugins = options['plugins'] + @call_count_type = options['expect_call_count_type'] + @ignore_bool_type = options['ignore_bool_type'] + @cexception_include = options['cexception_include'] + @throw_type = options['cexception_throw_type'] + end + + def load_config_file_from_yaml yaml_filename + require 'yaml' + require 'fileutils' + YAML.load(File.read(yaml_filename))['cmock'] + end + + def set_path(path) + @src_path = path end end diff --git a/lib/cmock_generator_plugin_cexception.rb b/lib/cmock_generator_plugin_cexception.rb index 6821480..6265dbd 100644 --- a/lib/cmock_generator_plugin_cexception.rb +++ b/lib/cmock_generator_plugin_cexception.rb @@ -10,7 +10,9 @@ class CMockGeneratorPluginCException end def include_files - return "#include \"Exception.h\"\n" + include = @config.cexception_include + include = "Exception.h" if (include.nil?) + return "#include \"#{include}\"\n" end def instance_structure(function_name, function_args_as_array, function_return_type) diff --git a/lib/cmock_generator_plugin_ignore.rb b/lib/cmock_generator_plugin_ignore.rb index 08715e0..bb8b947 100644 --- a/lib/cmock_generator_plugin_ignore.rb +++ b/lib/cmock_generator_plugin_ignore.rb @@ -27,9 +27,13 @@ class CMockGeneratorPluginIgnore def mock_implementation_prefix(function_name, function_return_type) lines = [] - lines << "#{@tab}if (!Mock.#{function_name}_IgnoreBool)\n" + lines << "#{@tab}if (Mock.#{function_name}_IgnoreBool)\n" lines << "#{@tab}{\n" - lines << @utils.make_handle_return(function_name, function_return_type, "#{@tab}#{@tab}") + if (function_return_type == "void") + lines << "#{@tab}#{@tab}return;\n" + else + lines << @utils.make_handle_return(function_name, function_return_type, "#{@tab}#{@tab}") + end lines << "#{@tab}}\n" end diff --git a/lib/cmock_plugin_manager.rb b/lib/cmock_plugin_manager.rb index f794868..e160ac0 100644 --- a/lib/cmock_plugin_manager.rb +++ b/lib/cmock_plugin_manager.rb @@ -13,10 +13,11 @@ class CMockPluginManager end def get_generator_plugins + plugins_to_load = @config.plugins @plugins = [] @plugins << CMockGeneratorPluginExpect.new( @config, @utils ) - @plugins << CMockGeneratorPluginCException.new( @config, @utils ) if @config.use_cexception - @plugins << CMockGeneratorPluginIgnore.new( @config, @utils ) if @config.allow_ignore_mock + @plugins << CMockGeneratorPluginCException.new( @config, @utils ) if plugins_to_load.include? 'cexception' + @plugins << CMockGeneratorPluginIgnore.new( @config, @utils ) if plugins_to_load.include? 'ignore' return @plugins end end diff --git a/rakefile_helper.rb b/rakefile_helper.rb index 67fa90d..9c1db40 100644 --- a/rakefile_helper.rb +++ b/rakefile_helper.rb @@ -187,7 +187,7 @@ module RakefileHelpers # Generate mock if a mock was included if header =~ /^Mock(.*)\.h/i module_name = $1 - cmock = CMock.new($cfg['compiler']['mocks_path'], ['Types.h']) + cmock = CMock.new($cfg_file) cmock.setup_mocks("#{$cfg['compiler']['source_path']}#{module_name}.h") end # Compile corresponding source file if it exists diff --git a/test/unit/cmock_config_test.rb b/test/unit/cmock_config_test.rb new file mode 100644 index 0000000..9fe4e74 --- /dev/null +++ b/test/unit/cmock_config_test.rb @@ -0,0 +1,50 @@ +require File.expand_path(File.dirname(__FILE__)) + "/../test_helper" +require File.expand_path(File.dirname(__FILE__)) + "/../../lib/cmock_config" + +class CMockConfigTest < Test::Unit::TestCase + def setup + end + + def teardown + end + + 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.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.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) + 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.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.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(test_plugins, config.plugins) + assert_equal(CMockConfig::CMockDefaultOptions['tab'], config.tab) + assert_equal(CMockConfig::CMockDefaultOptions['expect_call_count_type'],config.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.throw_type) + end +end diff --git a/test/unit/cmock_config_test.yml b/test/unit/cmock_config_test.yml new file mode 100644 index 0000000..c07c19d --- /dev/null +++ b/test/unit/cmock_config_test.yml @@ -0,0 +1,5 @@ +cmock: + plugins: + - 'soda' + - 'pizza' + cexception_throw_type: 'uint32' \ No newline at end of file diff --git a/test/unit/cmock_generator_plugin_cexception_test.rb b/test/unit/cmock_generator_plugin_cexception_test.rb index 3c187c2..ee45f0e 100644 --- a/test/unit/cmock_generator_plugin_cexception_test.rb +++ b/test/unit/cmock_generator_plugin_cexception_test.rb @@ -19,6 +19,14 @@ class CMockGeneratorPluginCExceptionTest < Test::Unit::TestCase should "include the cexception library" do expected = "#include \"Exception.h\"\n" + @config.expect.cexception_include.returns(nil) + returned = @cmock_generator_plugin_cexception.include_files + assert_equal(expected, returned) + end + + should "include the cexception library with a custom path if specified" do + expected = "#include \"../cexception/lib/Exception.h\"\n" + @config.expect.cexception_include.returns("../cexception/lib/Exception.h") returned = @cmock_generator_plugin_cexception.include_files assert_equal(expected, returned) end diff --git a/test/unit/cmock_generator_plugin_ignore_test.rb b/test/unit/cmock_generator_plugin_ignore_test.rb index 6869303..fa43f7d 100644 --- a/test/unit/cmock_generator_plugin_ignore_test.rb +++ b/test/unit/cmock_generator_plugin_ignore_test.rb @@ -53,14 +53,28 @@ class CMockGeneratorPluginIgnoreTest < Test::Unit::TestCase assert_equal(expected, returned) end - should "add required code to implementation prefix" do + should "add required code to implementation prefix with void function" do function_name = "Mold" function_args = "void" function_return_type = "void" + + expected = [" if (Mock.Mold_IgnoreBool)\n", + " {\n", + " return;\n", + " }\n" + ] + returned = @cmock_generator_plugin_ignore.mock_implementation_prefix(function_name, function_return_type) + assert_equal(expected, returned) + end + + should "add required code to implementation prefix with return functions" do + function_name = "Mold" + function_args = "void" + function_return_type = "int" @utils.expect.make_handle_return(function_name, function_return_type, " ").returns(" mock_return_1") - expected = [" if (!Mock.Mold_IgnoreBool)\n", + expected = [" if (Mock.Mold_IgnoreBool)\n", " {\n", " mock_return_1", " }\n" diff --git a/test/unit/cmock_plugin_manager_test.rb b/test/unit/cmock_plugin_manager_test.rb index c4b335b..81f04e0 100644 --- a/test/unit/cmock_plugin_manager_test.rb +++ b/test/unit/cmock_plugin_manager_test.rb @@ -17,8 +17,7 @@ class CMockPluginManagerTest < Test::Unit::TestCase should "return all plugins by default" do @config.stubs!(:tab).returns(" ") - @config.expect.use_cexception.returns(true) - @config.expect.allow_ignore_mock.returns(true) + @config.expect.plugins.returns(['cexception','ignore']) test_plugins = @cmock_plugins.get_generator_plugins contained = { :expect => false, :ignore => false, :cexception => false } test_plugins.each do |plugin| @@ -33,8 +32,7 @@ class CMockPluginManagerTest < Test::Unit::TestCase should "return restricted plugins based on config" do @config.stubs!(:tab).returns(" ") - @config.expect.use_cexception.returns(false) - @config.expect.allow_ignore_mock.returns(false) + @config.expect.plugins.returns([]) test_plugins = @cmock_plugins.get_generator_plugins contained = { :expect => false, :ignore => false, :cexception => false } test_plugins.each do |plugin|