From 0e0ce46d8d2d95556503610446d79b3c242842ea Mon Sep 17 00:00:00 2001 From: Michael Karlesky Date: Thu, 8 Oct 2026 13:11:40 -0400 Subject: [PATCH] Add :mock_name_include_folder option CMock names a mock's include guard and its Init, Verify and Destroy functions by the mock's filename alone. Two mocks sharing a filename in different folders therefore share a guard and define the same symbols. With :mock_name_include_folder enabled the generator folds the folder a mock is generated into below :mock_path into that name, so a mock of config.h in uart/ becomes uart_Mockconfig. The option defaults to off and leaves existing mocks unchanged. Unity's test runner generator gains a matching option, and vendor/unity moves to that commit. Co-Authored-By: Claude Opus 5.5 --- docs/CMock_Summary.md | 11 +++++++++ lib/cmock_config.rb | 1 + lib/cmock_generator.rb | 6 ++++- test/unit/cmock_generator_main_test.rb | 31 ++++++++++++++++++++++++++ vendor/unity | 2 +- 5 files changed, 49 insertions(+), 2 deletions(-) diff --git a/docs/CMock_Summary.md b/docs/CMock_Summary.md index 7e799dbc..455fdc74 100644 --- a/docs/CMock_Summary.md +++ b/docs/CMock_Summary.md @@ -547,6 +547,17 @@ from the defaults. We've tried to specify what the defaults are below. * default: true +* `:mock_name_include_folder`: + Name a mock by the folder it is generated into as well as its filename. The + folder is the path below `:mock_path`, built from `:subdir` and any folder + given to `setup_mocks`. A mock of "config.h" generated into `uart/` gets an + include guard and Init, Verify and Destroy functions named `uart_Mockconfig` + rather than `Mockconfig`. This lets two mocks of the same filename coexist in + one test. A test should include such a mock by that same folder, and Unity's + test runner generator needs its option of the same name enabled to match. + + * default: false + * `:mock_path`: The directory where you would like the mock files generated to be placed. diff --git a/lib/cmock_config.rb b/lib/cmock_config.rb index 1129a7fe..9df16c93 100644 --- a/lib/cmock_config.rb +++ b/lib/cmock_config.rb @@ -15,6 +15,7 @@ class CMockConfig :skeleton_path => '', :weak => '', :subdir => nil, + :mock_name_include_folder => false, :plugins => [], :strippables => ['(?:__attribute__\s*\([ (]*.*?[ )]*\)+)'], :attributes => %w[__ramfunc __irq __fiq register extern], diff --git a/lib/cmock_generator.rb b/lib/cmock_generator.rb index 41d30cce..f9eb3544 100644 --- a/lib/cmock_generator.rb +++ b/lib/cmock_generator.rb @@ -22,6 +22,7 @@ def initialize(config, file_writer, utils, plugins) @fail_on_unexpected_calls = @config.fail_on_unexpected_calls @exclude_setjmp_h = @config.exclude_setjmp_h @subdir = @config.subdir + @name_include_folder = @config.mock_name_include_folder @debug_output = @config.debug_output @includes_h_pre_orig_header = ((@config.includes || []) + (@config.includes_h_pre_orig_header || [])).uniq.map { |h| h =~ / module_name, :module_ext => (module_ext || '.h'), :mock_name => mock_name, - :clean_name => TypeSanitizer.sanitize_c_identifier(mock_name), + :clean_name => TypeSanitizer.sanitize_c_identifier(identity), :folder => mock_folder, :parsed_stuff => parsed_stuff, :skeleton => false diff --git a/test/unit/cmock_generator_main_test.rb b/test/unit/cmock_generator_main_test.rb index c5f20775..565afe79 100644 --- a/test/unit/cmock_generator_main_test.rb +++ b/test/unit/cmock_generator_main_test.rb @@ -47,6 +47,7 @@ def mock_implementation(name, args) @config.expect :includes_c_pre_header, nil @config.expect :includes_c_post_header, nil @config.expect :subdir, nil + @config.expect :mock_name_include_folder, false @config.expect :fail_on_unexpected_calls, true @config.expect :treat_inlines, :exclude @config.expect :exclude_setjmp_h, false @@ -69,6 +70,7 @@ def mock_implementation(name, args) @config.expect :includes_c_pre_header, nil @config.expect :includes_c_post_header, nil @config.expect :subdir, nil + @config.expect :mock_name_include_folder, false @config.expect :fail_on_unexpected_calls, true @config.expect :treat_inlines, :exclude @config.expect :exclude_setjmp_h, false @@ -426,6 +428,35 @@ def helper_create_header_top_with_opt_includes_form_config_and_plugin(ext) assert_equal(expected, output.flatten) end + def capture_mock_project(generator, folder) + captured = nil + generator.define_singleton_method(:create_mock_subdir) { |project| captured = project } + generator.define_singleton_method(:create_mock_header_file) { |_project| } + generator.define_singleton_method(:create_mock_source_file) { |_project| } + generator.create_mock("config", {}, ".h", folder) + captured + end + + it "name a mock by its filename alone by default" do + project = capture_mock_project(@cmock_generator, "drivers/uart") + + assert_equal("Mockconfig", project[:clean_name]) + assert_equal("drivers/uart/", project[:folder]) + end + + it "name a mock by its folder when configured to" do + @cmock_generator.instance_variable_set(:@name_include_folder, true) + + assert_equal("drivers_uart_Mockconfig", capture_mock_project(@cmock_generator, "drivers/uart")[:clean_name]) + assert_equal("drivers_uart_Mockconfig", capture_mock_project(@cmock_generator, "./drivers/uart")[:clean_name]) + end + + it "name a mock by its filename when configured to use a folder but given none" do + @cmock_generator.instance_variable_set(:@name_include_folder, true) + + assert_equal("Mockconfig", capture_mock_project(@cmock_generator, nil)[:clean_name]) + end + it "create mock verify functions in source file when no functions specified" do functions = [] output = [] diff --git a/vendor/unity b/vendor/unity index 2b67b99a..15e20f4a 160000 --- a/vendor/unity +++ b/vendor/unity @@ -1 +1 @@ -Subproject commit 2b67b99a4a87db87ff8c28a3b7e405c3e56d65f0 +Subproject commit 15e20f4a160af082f1b2435a3bc8ff4c023fdcef