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 <[email protected]>
This commit is contained in:
Michael Karlesky
2026-10-08 13:11:40 -04:00
co-authored by Claude Opus 5.5
parent f2a70b41bb
commit 0e0ce46d8d
5 changed files with 49 additions and 2 deletions
+11
View File
@@ -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.
+1
View File
@@ -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],
+5 -1
View File
@@ -22,6 +22,7 @@ class CMockGenerator
@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 =~ /</ ? h : "\"#{h}\"" }
@@ -62,12 +63,15 @@ class CMockGenerator
# adds a trailing slash to the folder output
mock_folder = File.join(mock_folder, '') if mock_folder
# optionally fold the folder into the mock name to keep same-named headers distinct
identity = @name_include_folder && mock_folder ? mock_folder.sub(/\A(?:\.[\/\\])+/, '') + mock_name : mock_name
# create out mock project from incoming data
mock_project = {
:module_name => 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
+31
View File
@@ -47,6 +47,7 @@ describe CMockGenerator, "Verify CMockGenerator Module" do
@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 @@ describe CMockGenerator, "Verify CMockGenerator Module" do
@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 @@ describe CMockGenerator, "Verify CMockGenerator Module" do
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 = []
+1 -1