From f60fe4b80805494aaab3b712418fc73363046d7b Mon Sep 17 00:00:00 2001 From: Roland Stahn Date: Mon, 2 Jun 2025 11:44:37 +0200 Subject: [PATCH 01/11] Add option 'create_error_stubs' Proposal for issue #507 --- lib/cmock_config.rb | 1 + lib/cmock_generator_plugin_array.rb | 15 ++++++----- lib/cmock_generator_plugin_expect.rb | 27 ++++++++++--------- lib/cmock_generator_plugin_expect_any_args.rb | 17 +++++++----- lib/cmock_generator_plugin_ignore.rb | 20 +++++++------- ...cmock_generator_plugin_ignore_stateless.rb | 20 +++++++------- 6 files changed, 57 insertions(+), 43 deletions(-) diff --git a/lib/cmock_config.rb b/lib/cmock_config.rb index ccbf4dc5..118a0cbb 100644 --- a/lib/cmock_config.rb +++ b/lib/cmock_config.rb @@ -43,6 +43,7 @@ class CMockConfig :array_size_name => 'size|len', :skeleton => false, :exclude_setjmp_h => false, + :create_error_stubs => true, # Format to look for inline functions. # This is a combination of "static" and "inline" keywords ("static inline", "inline static", "inline", "static") diff --git a/lib/cmock_generator_plugin_array.rb b/lib/cmock_generator_plugin_array.rb index d8eaa840..a669414f 100644 --- a/lib/cmock_generator_plugin_array.rb +++ b/lib/cmock_generator_plugin_array.rb @@ -13,6 +13,7 @@ def initialize(config, utils) @config = config @ptr_handling = @config.when_ptr @ordered = @config.enforce_strict_ordering + @error_stubs = @config.create_error_stubs @utils = utils @unity_helper = @utils.helpers[:unity_helper] @priority = 8 @@ -33,15 +34,17 @@ def mock_function_declarations(function) type = @utils.arg_type_with_const(m) m[:ptr?] ? "#{type} #{m[:name]}, int #{m[:name]}_Depth" : "#{type} #{m[:name]}" end.join(', ') + lines = '' if function[:return][:void?] - "#define #{function[:name]}_ExpectWithArrayAndReturn(#{args_call_i}, cmock_retval) TEST_FAIL_MESSAGE(\"#{function[:name]} requires _ExpectWithArray (not AndReturn)\");\n" \ - "#define #{function[:name]}_ExpectWithArray(#{args_call_i}) #{function[:name]}_CMockExpectWithArray(__LINE__, #{args_call_o})\n" \ - "void #{function[:name]}_CMockExpectWithArray(UNITY_LINE_TYPE cmock_line, #{args_string});\n" + lines << "#define #{function[:name]}_ExpectWithArrayAndReturn(#{args_call_i}, cmock_retval) TEST_FAIL_MESSAGE(\"#{function[:name]} requires _ExpectWithArray (not AndReturn)\");\n" if @error_stubs + lines << "#define #{function[:name]}_ExpectWithArray(#{args_call_i}) #{function[:name]}_CMockExpectWithArray(__LINE__, #{args_call_o})\n" + lines << "void #{function[:name]}_CMockExpectWithArray(UNITY_LINE_TYPE cmock_line, #{args_string});\n" else - "#define #{function[:name]}_ExpectWithArray(#{args_call_i}) TEST_FAIL_MESSAGE(\"#{function[:name]} requires _ExpectWithArrayAndReturn\");\n" \ - "#define #{function[:name]}_ExpectWithArrayAndReturn(#{args_call_i}, cmock_retval) #{function[:name]}_CMockExpectWithArrayAndReturn(__LINE__, #{args_call_o}, cmock_retval)\n" \ - "void #{function[:name]}_CMockExpectWithArrayAndReturn(UNITY_LINE_TYPE cmock_line, #{args_string}, #{function[:return][:str]});\n" + lines << "#define #{function[:name]}_ExpectWithArray(#{args_call_i}) TEST_FAIL_MESSAGE(\"#{function[:name]} requires _ExpectWithArrayAndReturn\");\n" if @error_stubs + lines << "#define #{function[:name]}_ExpectWithArrayAndReturn(#{args_call_i}, cmock_retval) #{function[:name]}_CMockExpectWithArrayAndReturn(__LINE__, #{args_call_o}, cmock_retval)\n" + lines << "void #{function[:name]}_CMockExpectWithArrayAndReturn(UNITY_LINE_TYPE cmock_line, #{args_string}, #{function[:return][:str]});\n" end + lines end def mock_interfaces(function) diff --git a/lib/cmock_generator_plugin_expect.rb b/lib/cmock_generator_plugin_expect.rb index 2b3778e3..f6cd24d1 100644 --- a/lib/cmock_generator_plugin_expect.rb +++ b/lib/cmock_generator_plugin_expect.rb @@ -13,6 +13,7 @@ def initialize(config, utils) @config = config @ptr_handling = @config.when_ptr @ordered = @config.enforce_strict_ordering + @error_stubs = @config.create_error_stubs @utils = utils @unity_helper = @utils.helpers[:unity_helper] @priority = 5 @@ -35,25 +36,27 @@ def instance_typedefs(function) end def mock_function_declarations(function) + lines = '' if function[:args].empty? if function[:return][:void?] - "#define #{function[:name]}_ExpectAndReturn(cmock_retval) TEST_FAIL_MESSAGE(\"#{function[:name]} requires _Expect (not AndReturn)\");\n" \ - "#define #{function[:name]}_Expect() #{function[:name]}_CMockExpect(__LINE__)\n" \ - "void #{function[:name]}_CMockExpect(UNITY_LINE_TYPE cmock_line);\n" + lines << "#define #{function[:name]}_ExpectAndReturn(cmock_retval) TEST_FAIL_MESSAGE(\"#{function[:name]} requires _Expect (not AndReturn)\");\n" if @error_stubs + lines << "#define #{function[:name]}_Expect() #{function[:name]}_CMockExpect(__LINE__)\n" + lines << "void #{function[:name]}_CMockExpect(UNITY_LINE_TYPE cmock_line);\n" else - "#define #{function[:name]}_Expect() TEST_FAIL_MESSAGE(\"#{function[:name]} requires _ExpectAndReturn\");\n" \ - "#define #{function[:name]}_ExpectAndReturn(cmock_retval) #{function[:name]}_CMockExpectAndReturn(__LINE__, cmock_retval)\n" \ - "void #{function[:name]}_CMockExpectAndReturn(UNITY_LINE_TYPE cmock_line, #{function[:return][:str]});\n" + lines << "#define #{function[:name]}_Expect() TEST_FAIL_MESSAGE(\"#{function[:name]} requires _ExpectAndReturn\");\n" if @error_stubs + lines << "#define #{function[:name]}_ExpectAndReturn(cmock_retval) #{function[:name]}_CMockExpectAndReturn(__LINE__, cmock_retval)\n" + lines << "void #{function[:name]}_CMockExpectAndReturn(UNITY_LINE_TYPE cmock_line, #{function[:return][:str]});\n" end elsif function[:return][:void?] - "#define #{function[:name]}_ExpectAndReturn(#{function[:args_call]}, cmock_retval) TEST_FAIL_MESSAGE(\"#{function[:name]} requires _Expect (not AndReturn)\");\n" \ - "#define #{function[:name]}_Expect(#{function[:args_call]}) #{function[:name]}_CMockExpect(__LINE__, #{function[:args_call]})\n" \ - "void #{function[:name]}_CMockExpect(UNITY_LINE_TYPE cmock_line, #{function[:args_string]});\n" + lines << "#define #{function[:name]}_ExpectAndReturn(#{function[:args_call]}, cmock_retval) TEST_FAIL_MESSAGE(\"#{function[:name]} requires _Expect (not AndReturn)\");\n" if @error_stubs + lines << "#define #{function[:name]}_Expect(#{function[:args_call]}) #{function[:name]}_CMockExpect(__LINE__, #{function[:args_call]})\n" + lines << "void #{function[:name]}_CMockExpect(UNITY_LINE_TYPE cmock_line, #{function[:args_string]});\n" else - "#define #{function[:name]}_Expect(#{function[:args_call]}) TEST_FAIL_MESSAGE(\"#{function[:name]} requires _ExpectAndReturn\");\n" \ - "#define #{function[:name]}_ExpectAndReturn(#{function[:args_call]}, cmock_retval) #{function[:name]}_CMockExpectAndReturn(__LINE__, #{function[:args_call]}, cmock_retval)\n" \ - "void #{function[:name]}_CMockExpectAndReturn(UNITY_LINE_TYPE cmock_line, #{function[:args_string]}, #{function[:return][:str]});\n" + lines << "#define #{function[:name]}_Expect(#{function[:args_call]}) TEST_FAIL_MESSAGE(\"#{function[:name]} requires _ExpectAndReturn\");\n" if @error_stubs + lines << "#define #{function[:name]}_ExpectAndReturn(#{function[:args_call]}, cmock_retval) #{function[:name]}_CMockExpectAndReturn(__LINE__, #{function[:args_call]}, cmock_retval)\n" + lines << "void #{function[:name]}_CMockExpectAndReturn(UNITY_LINE_TYPE cmock_line, #{function[:args_string]}, #{function[:return][:str]});\n" end + lines end def mock_implementation_always_check_args(function) diff --git a/lib/cmock_generator_plugin_expect_any_args.rb b/lib/cmock_generator_plugin_expect_any_args.rb index 348c7df6..d2d47777 100644 --- a/lib/cmock_generator_plugin_expect_any_args.rb +++ b/lib/cmock_generator_plugin_expect_any_args.rb @@ -10,6 +10,7 @@ class CMockGeneratorPluginExpectAnyArgs def initialize(config, utils) @config = config + @error_stubs = @config.create_error_stubs @utils = utils @priority = 3 end @@ -19,17 +20,19 @@ def instance_typedefs(_function) end def mock_function_declarations(function) + lines = '' if function[:args].empty? - '' + lines << '' elsif function[:return][:void?] - "#define #{function[:name]}_ExpectAnyArgsAndReturn(cmock_retval) TEST_FAIL_MESSAGE(\"#{function[:name]} requires _ExpectAnyArgs (not AndReturn)\");\n" \ - "#define #{function[:name]}_ExpectAnyArgs() #{function[:name]}_CMockExpectAnyArgs(__LINE__)\n" \ - "void #{function[:name]}_CMockExpectAnyArgs(UNITY_LINE_TYPE cmock_line);\n" + lines << "#define #{function[:name]}_ExpectAnyArgsAndReturn(cmock_retval) TEST_FAIL_MESSAGE(\"#{function[:name]} requires _ExpectAnyArgs (not AndReturn)\");\n" if @error_stubs + lines << "#define #{function[:name]}_ExpectAnyArgs() #{function[:name]}_CMockExpectAnyArgs(__LINE__)\n" + lines << "void #{function[:name]}_CMockExpectAnyArgs(UNITY_LINE_TYPE cmock_line);\n" else - "#define #{function[:name]}_ExpectAnyArgs() TEST_FAIL_MESSAGE(\"#{function[:name]} requires _ExpectAnyArgsAndReturn\");\n" \ - "#define #{function[:name]}_ExpectAnyArgsAndReturn(cmock_retval) #{function[:name]}_CMockExpectAnyArgsAndReturn(__LINE__, cmock_retval)\n" \ - "void #{function[:name]}_CMockExpectAnyArgsAndReturn(UNITY_LINE_TYPE cmock_line, #{function[:return][:str]});\n" + lines << "#define #{function[:name]}_ExpectAnyArgs() TEST_FAIL_MESSAGE(\"#{function[:name]} requires _ExpectAnyArgsAndReturn\");\n" if @error_stubs + lines << "#define #{function[:name]}_ExpectAnyArgsAndReturn(cmock_retval) #{function[:name]}_CMockExpectAnyArgsAndReturn(__LINE__, cmock_retval)\n" + lines << "void #{function[:name]}_CMockExpectAnyArgsAndReturn(UNITY_LINE_TYPE cmock_line, #{function[:return][:str]});\n" end + lines end def mock_interfaces(function) diff --git a/lib/cmock_generator_plugin_ignore.rb b/lib/cmock_generator_plugin_ignore.rb index 467ca7aa..07773a9c 100644 --- a/lib/cmock_generator_plugin_ignore.rb +++ b/lib/cmock_generator_plugin_ignore.rb @@ -10,6 +10,7 @@ class CMockGeneratorPluginIgnore def initialize(config, utils) @config = config + @error_stubs = @config.create_error_stubs @utils = utils @priority = 2 end @@ -23,15 +24,16 @@ def instance_structure(function) end def mock_function_declarations(function) - lines = if function[:return][:void?] - "#define #{function[:name]}_IgnoreAndReturn(cmock_retval) TEST_FAIL_MESSAGE(\"#{function[:name]} requires _Ignore (not AndReturn)\");\n" \ - "#define #{function[:name]}_Ignore() #{function[:name]}_CMockIgnore()\n" \ - "void #{function[:name]}_CMockIgnore(void);\n" - else - "#define #{function[:name]}_Ignore() TEST_FAIL_MESSAGE(\"#{function[:name]} requires _IgnoreAndReturn\");\n" \ - "#define #{function[:name]}_IgnoreAndReturn(cmock_retval) #{function[:name]}_CMockIgnoreAndReturn(__LINE__, cmock_retval)\n" \ - "void #{function[:name]}_CMockIgnoreAndReturn(UNITY_LINE_TYPE cmock_line, #{function[:return][:str]});\n" - end + lines = '' + if function[:return][:void?] + lines << "#define #{function[:name]}_IgnoreAndReturn(cmock_retval) TEST_FAIL_MESSAGE(\"#{function[:name]} requires _Ignore (not AndReturn)\");\n" if @error_stubs + lines << "#define #{function[:name]}_Ignore() #{function[:name]}_CMockIgnore()\n" + lines << "void #{function[:name]}_CMockIgnore(void);\n" + else + lines << "#define #{function[:name]}_Ignore() TEST_FAIL_MESSAGE(\"#{function[:name]} requires _IgnoreAndReturn\");\n" if @error_stubs + lines << "#define #{function[:name]}_IgnoreAndReturn(cmock_retval) #{function[:name]}_CMockIgnoreAndReturn(__LINE__, cmock_retval)\n" + lines << "void #{function[:name]}_CMockIgnoreAndReturn(UNITY_LINE_TYPE cmock_line, #{function[:return][:str]});\n" + end # Add stop ignore function. it does not matter if there are any args lines << "#define #{function[:name]}_StopIgnore() #{function[:name]}_CMockStopIgnore()\n" \ diff --git a/lib/cmock_generator_plugin_ignore_stateless.rb b/lib/cmock_generator_plugin_ignore_stateless.rb index fb5ebc76..8febfb08 100644 --- a/lib/cmock_generator_plugin_ignore_stateless.rb +++ b/lib/cmock_generator_plugin_ignore_stateless.rb @@ -10,6 +10,7 @@ class CMockGeneratorPluginIgnoreStateless def initialize(config, utils) @config = config + @error_stubs = @config.create_error_stubs @utils = utils @priority = 2 end @@ -23,15 +24,16 @@ def instance_structure(function) end def mock_function_declarations(function) - lines = if function[:return][:void?] - "#define #{function[:name]}_IgnoreAndReturn(cmock_retval) TEST_FAIL_MESSAGE(\"#{function[:name]} requires _Ignore (not AndReturn)\");\n" \ - "#define #{function[:name]}_Ignore() #{function[:name]}_CMockIgnore()\n" \ - "void #{function[:name]}_CMockIgnore(void);\n" - else - "#define #{function[:name]}_Ignore() TEST_FAIL_MESSAGE(\"#{function[:name]} requires _IgnoreAndReturn\");\n" \ - "#define #{function[:name]}_IgnoreAndReturn(cmock_retval) #{function[:name]}_CMockIgnoreAndReturn(cmock_retval)\n" \ - "void #{function[:name]}_CMockIgnoreAndReturn(#{function[:return][:str]});\n" - end + lines = '' + if function[:return][:void?] + lines << "#define #{function[:name]}_IgnoreAndReturn(cmock_retval) TEST_FAIL_MESSAGE(\"#{function[:name]} requires _Ignore (not AndReturn)\");\n" if @error_stubs + lines << "#define #{function[:name]}_Ignore() #{function[:name]}_CMockIgnore()\n" + lines << "void #{function[:name]}_CMockIgnore(void);\n" + else + lines << "#define #{function[:name]}_Ignore() TEST_FAIL_MESSAGE(\"#{function[:name]} requires _IgnoreAndReturn\");\n" if @error_stubs + lines << "#define #{function[:name]}_IgnoreAndReturn(cmock_retval) #{function[:name]}_CMockIgnoreAndReturn(cmock_retval)\n" + lines << "void #{function[:name]}_CMockIgnoreAndReturn(#{function[:return][:str]});\n" + end # Add stop ignore function. it does not matter if there are any args lines << "#define #{function[:name]}_StopIgnore() #{function[:name]}_CMockStopIgnore()\n" \ From d20dca34abb97d674b3a63c2cf52fa5e2d180bb3 Mon Sep 17 00:00:00 2001 From: Roland Stahn Date: Tue, 3 Jun 2025 13:14:23 +0200 Subject: [PATCH 02/11] Add option 'create_error_stubs' in before --- test/unit/cmock_generator_plugin_array_test.rb | 3 ++- test/unit/cmock_generator_plugin_expect_a_test.rb | 1 + test/unit/cmock_generator_plugin_expect_any_args_test.rb | 2 +- test/unit/cmock_generator_plugin_expect_b_test.rb | 1 + test/unit/cmock_generator_plugin_ignore_stateless_test.rb | 2 +- test/unit/cmock_generator_plugin_ignore_test.rb | 2 +- 6 files changed, 7 insertions(+), 4 deletions(-) diff --git a/test/unit/cmock_generator_plugin_array_test.rb b/test/unit/cmock_generator_plugin_array_test.rb index 5af9eaa4..ab68d6ed 100644 --- a/test/unit/cmock_generator_plugin_array_test.rb +++ b/test/unit/cmock_generator_plugin_array_test.rb @@ -27,7 +27,8 @@ def code_add_base_expectation(func) @config = create_stub( :when_ptr => :compare_data, :enforce_strict_ordering => false, - :respond_to? => true ) + :respond_to? => true, + :create_error_stubs => true) @utils = UtilsStub.new diff --git a/test/unit/cmock_generator_plugin_expect_a_test.rb b/test/unit/cmock_generator_plugin_expect_a_test.rb index ec155ba7..c62e542d 100644 --- a/test/unit/cmock_generator_plugin_expect_a_test.rb +++ b/test/unit/cmock_generator_plugin_expect_a_test.rb @@ -17,6 +17,7 @@ :when_ptr => :compare_data, :enforce_strict_ordering => false, :respond_to? => true, + :create_error_stubs => true, :plugins => [ :expect ] ) @utils.expect :helpers, {} diff --git a/test/unit/cmock_generator_plugin_expect_any_args_test.rb b/test/unit/cmock_generator_plugin_expect_any_args_test.rb index 83aaf86f..2bc77053 100644 --- a/test/unit/cmock_generator_plugin_expect_any_args_test.rb +++ b/test/unit/cmock_generator_plugin_expect_any_args_test.rb @@ -12,7 +12,7 @@ before do create_mocks :config, :utils - @config = create_stub(:respond_to? => true) + @config = create_stub(:respond_to? => true, :create_error_stubs => true) @cmock_generator_plugin_expect_any_args = CMockGeneratorPluginExpectAnyArgs.new(@config, @utils) end diff --git a/test/unit/cmock_generator_plugin_expect_b_test.rb b/test/unit/cmock_generator_plugin_expect_b_test.rb index a33e1f08..17eb71cf 100644 --- a/test/unit/cmock_generator_plugin_expect_b_test.rb +++ b/test/unit/cmock_generator_plugin_expect_b_test.rb @@ -17,6 +17,7 @@ :when_ptr => :compare_data, :enforce_strict_ordering => true, :respond_to? => true, + :create_error_stubs => true, :plugins => [ :expect, :expect_any_args ] ) @utils.expect :helpers, {} diff --git a/test/unit/cmock_generator_plugin_ignore_stateless_test.rb b/test/unit/cmock_generator_plugin_ignore_stateless_test.rb index 5f3dc90c..69517d15 100644 --- a/test/unit/cmock_generator_plugin_ignore_stateless_test.rb +++ b/test/unit/cmock_generator_plugin_ignore_stateless_test.rb @@ -12,7 +12,7 @@ before do create_mocks :config, :utils - @config = create_stub(:respond_to? => true) + @config = create_stub(:respond_to? => true, :create_error_stubs => true) @cmock_generator_plugin_ignore_stateless = CMockGeneratorPluginIgnoreStateless.new(@config, @utils) end diff --git a/test/unit/cmock_generator_plugin_ignore_test.rb b/test/unit/cmock_generator_plugin_ignore_test.rb index b955d85c..ed073849 100644 --- a/test/unit/cmock_generator_plugin_ignore_test.rb +++ b/test/unit/cmock_generator_plugin_ignore_test.rb @@ -12,7 +12,7 @@ before do create_mocks :config, :utils - @config = create_stub(:respond_to? => true) + @config = create_stub(:respond_to? => true, :create_error_stubs => true) @cmock_generator_plugin_ignore = CMockGeneratorPluginIgnore.new(@config, @utils) end From b1d0e36aa380f04d5b3ca4bcd839ac889865d02f Mon Sep 17 00:00:00 2001 From: Roland Stahn Date: Tue, 3 Jun 2025 13:18:11 +0200 Subject: [PATCH 03/11] Update main.yml (run tests on branches) --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 9c89b144..f53eee3d 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -6,7 +6,7 @@ name: CI # Triggers the workflow on push or pull request events but only for the master branch on: push: - branches: [ master ] + branches: [ master, rstahn-patch-* ] pull_request: branches: [ master ] From bd41b3f939103b1d9b9360a37f9341cd73bccbc8 Mon Sep 17 00:00:00 2001 From: Roland Stahn Date: Tue, 3 Jun 2025 13:26:34 +0200 Subject: [PATCH 04/11] Add option create_error_stubs to testcase --- test/unit/cmock_plugin_manager_test.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/unit/cmock_plugin_manager_test.rb b/test/unit/cmock_plugin_manager_test.rb index b6faa17c..80e1093d 100644 --- a/test/unit/cmock_plugin_manager_test.rb +++ b/test/unit/cmock_plugin_manager_test.rb @@ -20,7 +20,8 @@ :when_ptr => :compare_data, :enforce_strict_ordering => false, :ignore => :args_and_calls, - :exclude_setjmp_h => false + :exclude_setjmp_h => false, + :create_error_stubs => true ) def @config.plugins From 3ba7de2cb784b477a6586edabaee2ce29cc75850 Mon Sep 17 00:00:00 2001 From: Roland Stahn Date: Tue, 3 Jun 2025 13:51:15 +0200 Subject: [PATCH 05/11] Style fixes --- lib/cmock_generator_plugin_array.rb | 2 +- lib/cmock_generator_plugin_expect.rb | 2 +- lib/cmock_generator_plugin_expect_any_args.rb | 2 +- lib/cmock_generator_plugin_ignore.rb | 2 +- lib/cmock_generator_plugin_ignore_stateless.rb | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/cmock_generator_plugin_array.rb b/lib/cmock_generator_plugin_array.rb index a669414f..286880a7 100644 --- a/lib/cmock_generator_plugin_array.rb +++ b/lib/cmock_generator_plugin_array.rb @@ -13,7 +13,7 @@ def initialize(config, utils) @config = config @ptr_handling = @config.when_ptr @ordered = @config.enforce_strict_ordering - @error_stubs = @config.create_error_stubs + @error_stubs = @config.create_error_stubs @utils = utils @unity_helper = @utils.helpers[:unity_helper] @priority = 8 diff --git a/lib/cmock_generator_plugin_expect.rb b/lib/cmock_generator_plugin_expect.rb index f6cd24d1..7cd4fd6a 100644 --- a/lib/cmock_generator_plugin_expect.rb +++ b/lib/cmock_generator_plugin_expect.rb @@ -53,7 +53,7 @@ def mock_function_declarations(function) lines << "void #{function[:name]}_CMockExpect(UNITY_LINE_TYPE cmock_line, #{function[:args_string]});\n" else lines << "#define #{function[:name]}_Expect(#{function[:args_call]}) TEST_FAIL_MESSAGE(\"#{function[:name]} requires _ExpectAndReturn\");\n" if @error_stubs - lines << "#define #{function[:name]}_ExpectAndReturn(#{function[:args_call]}, cmock_retval) #{function[:name]}_CMockExpectAndReturn(__LINE__, #{function[:args_call]}, cmock_retval)\n" + lines << "#define #{function[:name]}_ExpectAndReturn(#{function[:args_call]}, cmock_retval) #{function[:name]}_CMockExpectAndReturn(__LINE__, #{function[:args_call]}, cmock_retval)\n" lines << "void #{function[:name]}_CMockExpectAndReturn(UNITY_LINE_TYPE cmock_line, #{function[:args_string]}, #{function[:return][:str]});\n" end lines diff --git a/lib/cmock_generator_plugin_expect_any_args.rb b/lib/cmock_generator_plugin_expect_any_args.rb index d2d47777..48333700 100644 --- a/lib/cmock_generator_plugin_expect_any_args.rb +++ b/lib/cmock_generator_plugin_expect_any_args.rb @@ -10,7 +10,7 @@ class CMockGeneratorPluginExpectAnyArgs def initialize(config, utils) @config = config - @error_stubs = @config.create_error_stubs + @error_stubs = @config.create_error_stubs @utils = utils @priority = 3 end diff --git a/lib/cmock_generator_plugin_ignore.rb b/lib/cmock_generator_plugin_ignore.rb index 07773a9c..a58bf359 100644 --- a/lib/cmock_generator_plugin_ignore.rb +++ b/lib/cmock_generator_plugin_ignore.rb @@ -10,7 +10,7 @@ class CMockGeneratorPluginIgnore def initialize(config, utils) @config = config - @error_stubs = @config.create_error_stubs + @error_stubs = @config.create_error_stubs @utils = utils @priority = 2 end diff --git a/lib/cmock_generator_plugin_ignore_stateless.rb b/lib/cmock_generator_plugin_ignore_stateless.rb index 8febfb08..eb2561d9 100644 --- a/lib/cmock_generator_plugin_ignore_stateless.rb +++ b/lib/cmock_generator_plugin_ignore_stateless.rb @@ -10,7 +10,7 @@ class CMockGeneratorPluginIgnoreStateless def initialize(config, utils) @config = config - @error_stubs = @config.create_error_stubs + @error_stubs = @config.create_error_stubs @utils = utils @priority = 2 end From c9154a19dd17647ee8ffa34078c2f852962cd7aa Mon Sep 17 00:00:00 2001 From: Roland Stahn Date: Sun, 8 Jun 2025 22:57:20 +0200 Subject: [PATCH 06/11] Add description for 'create_error_stubs' --- docs/CMock_Summary.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/docs/CMock_Summary.md b/docs/CMock_Summary.md index 31836657..e8e02d49 100644 --- a/docs/CMock_Summary.md +++ b/docs/CMock_Summary.md @@ -420,6 +420,27 @@ from the defaults. We've tried to specify what the defaults are below. * default: *nil* +* `:create_error_stubs`: + New users of CMock sometimes struggle with the concept that CMock is + generating differently named interface functions for a mock depending + on whether a function to be mocked has a return value or not (see + description of the plugins *Expect*, *ExpectAnyArgs*, *Array*, *Ignore*, + *IgnoreStateless* above). They are looking e.g. for a function `func_Expect()` + while CMock generated the function `func_ExpectAndReturn()` instead. + This has proven to be a significant hurdle, because it is not easy to + spot the slightly different named function within the generated mock. + Therefore since release v2.6.0 CMock is generating *both* functions + per default, although one of them has only a "stub" functionality: + it is aborting the testcase when called with a helpful error message + pointing towards the correct function. + + Experienced CMock users on the other hand might prefer the original + behavior, where no additional error stubs are generated - e.g. to + ensure code completion offers only "real" functionality of the mock. + In this case the option `:create_error_stubs` should be set to false. + + * default: true + * `:enforce_strict_ordering`: CMock always enforces the order that you call a particular function, so if you expect GrabNabber(int size) to be called three times, it From 0cefcf05f96e162d825ba074be6b192fab71e1f9 Mon Sep 17 00:00:00 2001 From: Roland Stahn <23195933+rstahn@users.noreply.github.com> Date: Wed, 11 Jun 2025 12:55:28 +0200 Subject: [PATCH 07/11] Update description of 'create_error_stubs' Change-Id: Ica84be72a229a4fd90e3d5ce0b3449722699f637 --- .gitmodules | 8 ++++---- docs/CMock_Summary.md | 26 +++++++++++++------------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/.gitmodules b/.gitmodules index af418942..2fa5602c 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,8 +1,8 @@ -[submodule "vendor/unity"] - path = vendor/unity - url = https://github.com/throwtheswitch/unity.git - branch = master [submodule "vendor/c_exception"] path = vendor/c_exception url = https://github.com/throwtheswitch/cexception.git branch = master +[submodule "vendor/unity"] + path = vendor/unity + url = https://github.com/throwtheswitch/unity.git + branch = master diff --git a/docs/CMock_Summary.md b/docs/CMock_Summary.md index e8e02d49..e836e178 100644 --- a/docs/CMock_Summary.md +++ b/docs/CMock_Summary.md @@ -1,7 +1,7 @@ CMock: A Summary ================ -*[ThrowTheSwitch.org](http://throwtheswitch.org)* +*[ThrowTheSwitch.org](http://throwtheswitch.org)* *This documentation is released under a Creative Commons 3.0 Attribution Share-Alike License* @@ -138,7 +138,7 @@ that resembles a pointer or array, it breaks the argument into TWO arguments. The first is the original pointer. The second specify the number of elements it is to verify of that array. If you specify 1, it'll check one object. If 2, it'll assume your pointer is pointing at the first of two elements in an array. -If you specify zero elements and `UNITY_COMPARE_PTRS_ON_ZERO_ARRAY` is defined, +If you specify zero elements and `UNITY_COMPARE_PTRS_ON_ZERO_ARRAY` is defined, then this assertion can also be used to directly compare the pointers to verify that they are pointing to the same memory address. @@ -421,23 +421,23 @@ from the defaults. We've tried to specify what the defaults are below. * default: *nil* * `:create_error_stubs`: - New users of CMock sometimes struggle with the concept that CMock is - generating differently named interface functions for a mock depending + New users of CMock sometimes struggle with the concept that CMock is + generating differently named interface functions for a mock depending on whether a function to be mocked has a return value or not (see - description of the plugins *Expect*, *ExpectAnyArgs*, *Array*, *Ignore*, - *IgnoreStateless* above). They are looking e.g. for a function `func_Expect()` + description of the plugins `:Expect`, `:ExpectAnyArgs`, `:Array`, `:Ignore`, + `:IgnoreStateless` above). They are looking e.g. for a function `func_Expect()` while CMock generated the function `func_ExpectAndReturn()` instead. - This has proven to be a significant hurdle, because it is not easy to + This has proven to be a significant hurdle, because it is not easy to spot the slightly different named function within the generated mock. - Therefore since release v2.6.0 CMock is generating *both* functions + Therefore CMock (v2.6.0 and newer) is generating *both* functions per default, although one of them has only a "stub" functionality: - it is aborting the testcase when called with a helpful error message + on call it will always fail the test emitting a helpful error message pointing towards the correct function. - + Experienced CMock users on the other hand might prefer the original - behavior, where no additional error stubs are generated - e.g. to + behavior, where no additional error stubs are generated - e.g. to ensure code completion offers only "real" functionality of the mock. - In this case the option `:create_error_stubs` should be set to false. + In this case, the option `:create_error_stubs` can be set to false. * default: true @@ -658,7 +658,7 @@ from the defaults. We've tried to specify what the defaults are below. for the test code to also see the newly generated header ,and not the old header with inline functions, the build system has to add the mock folder to the include paths. - + Furthermore, we need to keep the order of include paths in mind. We have to set the mock folder before the other includes to avoid the test code including the original header instead of the newly From 16ec975a87d1d380c52bd476981043d2a405404f Mon Sep 17 00:00:00 2001 From: Roland Stahn <23195933+rstahn@users.noreply.github.com> Date: Thu, 12 Jun 2025 14:15:21 +0200 Subject: [PATCH 08/11] Add first testcase with 'create_error_stubs' set to false Change-Id: I33728023c1397e2bdbe62304638f578482ec8f58 --- .../cmock_generator_plugin_expect_c_test.rb | 187 ++++++++++++++++++ 1 file changed, 187 insertions(+) create mode 100644 test/unit/cmock_generator_plugin_expect_c_test.rb diff --git a/test/unit/cmock_generator_plugin_expect_c_test.rb b/test/unit/cmock_generator_plugin_expect_c_test.rb new file mode 100644 index 00000000..80d3a48c --- /dev/null +++ b/test/unit/cmock_generator_plugin_expect_c_test.rb @@ -0,0 +1,187 @@ +# ========================================================================= +# CMock - Automatic Mock Generation for C +# ThrowTheSwitch.org +# Copyright (c) 2007-25 Mike Karlesky, Mark VanderVoord, & Greg Williams +# SPDX-License-Identifier: MIT +# ========================================================================= + +require File.expand_path(File.dirname(__FILE__)) + "/../test_helper" +require File.expand_path(File.dirname(__FILE__)) + '/../../lib/cmock_generator_plugin_expect' + +describe CMockGeneratorPluginExpect, "Verify CMockGeneratorPluginExpect Module Without Global Ordering And Without Error Stubs" do + + before do + create_mocks :config, :utils + + @config = create_stub( + :when_ptr => :compare_data, + :enforce_strict_ordering => false, + :respond_to? => true, + :create_error_stubs => false, + :plugins => [ :expect ] ) + + @utils.expect :helpers, {} + @cmock_generator_plugin_expect = CMockGeneratorPluginExpect.new(@config, @utils) + end + + after do + end + + it "have set up internal priority on init" do + assert_nil(@cmock_generator_plugin_expect.unity_helper) + assert_equal(5, @cmock_generator_plugin_expect.priority) + end + + it "not include any additional include files" do + assert(!@cmock_generator_plugin_expect.respond_to?(:include_files)) + end + + it "add to typedef structure mock needs of functions of style 'void func(void)'" do + function = {:name => "Oak", :args => [], :return => test_return[:void]} + expected = "" + returned = @cmock_generator_plugin_expect.instance_typedefs(function) + assert_equal(expected, returned) + end + + it "add to typedef structure mock needs of functions of style 'int func(void)'" do + function = {:name => "Elm", :args => [], :return => test_return[:int]} + expected = " int ReturnVal;\n" + returned = @cmock_generator_plugin_expect.instance_typedefs(function) + assert_equal(expected, returned) + end + + it "add to typedef structure mock needs of functions of style 'void func(int chicken, char* pork)'" do + function = {:name => "Cedar", :args => [{ :name => "chicken", :type => "int"}, { :name => "pork", :type => "char*"}], :return => test_return[:void]} + expected = " int Expected_chicken;\n char* Expected_pork;\n" + returned = @cmock_generator_plugin_expect.instance_typedefs(function) + assert_equal(expected, returned) + end + + it "add to typedef structure mock needs of functions of style 'int func(float beef)'" do + function = {:name => "Birch", :args => [{ :name => "beef", :type => "float"}], :return => test_return[:int]} + expected = " int ReturnVal;\n float Expected_beef;\n" + returned = @cmock_generator_plugin_expect.instance_typedefs(function) + assert_equal(expected, returned) + end + + it "add mock function declaration for functions of style 'void func(void)'" do + function = {:name => "Maple", :args => [], :return => test_return[:void]} + expected = "#define Maple_Expect() Maple_CMockExpect(__LINE__)\n" + + "void Maple_CMockExpect(UNITY_LINE_TYPE cmock_line);\n" + returned = @cmock_generator_plugin_expect.mock_function_declarations(function) + assert_equal(expected, returned) + end + + it "add mock function declaration for functions of style 'int func(void)'" do + function = {:name => "Spruce", :args => [], :return => test_return[:int]} + expected = "#define Spruce_ExpectAndReturn(cmock_retval) Spruce_CMockExpectAndReturn(__LINE__, cmock_retval)\n" + + "void Spruce_CMockExpectAndReturn(UNITY_LINE_TYPE cmock_line, int cmock_to_return);\n" + returned = @cmock_generator_plugin_expect.mock_function_declarations(function) + assert_equal(expected, returned) + end + + it "add mock function declaration for functions of style 'const char* func(int tofu)'" do + function = {:name => "Pine", :args => ["int tofu"], :args_string => "int tofu", :args_call => 'tofu', :return => test_return[:string]} + expected = "#define Pine_ExpectAndReturn(tofu, cmock_retval) Pine_CMockExpectAndReturn(__LINE__, tofu, cmock_retval)\n" + + "void Pine_CMockExpectAndReturn(UNITY_LINE_TYPE cmock_line, int tofu, const char* cmock_to_return);\n" + returned = @cmock_generator_plugin_expect.mock_function_declarations(function) + assert_equal(expected, returned) + end + + it "add mock function implementation for functions of style 'void func(void)'" do + function = {:name => "Apple", :args => [], :return => test_return[:void]} + expected = "" + returned = @cmock_generator_plugin_expect.mock_implementation(function) + assert_equal(expected, returned) + end + + it "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" } ], :return => test_return[:int]} + + @utils.expect :code_verify_an_arg_expectation, " mocked_retval_1", [function, function[:args][0]] + @utils.expect :code_verify_an_arg_expectation, " mocked_retval_2", [function, function[:args][1]] + expected = " mocked_retval_1 mocked_retval_2" + returned = @cmock_generator_plugin_expect.mock_implementation(function) + assert_equal(expected, returned) + end + + it "add mock function implementation using ordering if needed" do + function = {:name => "Apple", :args => [], :return => test_return[:void]} + expected = "" + @cmock_generator_plugin_expect.ordered = true + returned = @cmock_generator_plugin_expect.mock_implementation(function) + assert_equal(expected, returned) + end + + it "add mock interfaces for functions of style 'void func(void)'" do + function = {:name => "Pear", :args => [], :args_string => "void", :return => test_return[:void]} + @utils.expect :code_add_base_expectation, "mock_retval_0 ", ["Pear"] + @utils.expect :code_call_argument_loader, "mock_retval_1 ", [function] + expected = ["void Pear_CMockExpect(UNITY_LINE_TYPE cmock_line)\n", + "{\n", + "mock_retval_0 ", + "mock_retval_1 ", + "}\n\n" + ].join + returned = @cmock_generator_plugin_expect.mock_interfaces(function) + assert_equal(expected, returned) + end + + it "add mock interfaces for functions of style 'int func(void)'" do + function = {:name => "Orange", :args => [], :args_string => "void", :return => test_return[:int]} + @utils.expect :code_add_base_expectation, "mock_retval_0 ", ["Orange"] + @utils.expect :code_call_argument_loader, "mock_retval_1 ", [function] + @utils.expect :code_assign_argument_quickly, "mock_retval_2", ["cmock_call_instance->ReturnVal", function[:return]] + expected = ["void Orange_CMockExpectAndReturn(UNITY_LINE_TYPE cmock_line, int cmock_to_return)\n", + "{\n", + "mock_retval_0 ", + "mock_retval_1 ", + "mock_retval_2", + "}\n\n" + ].join + returned = @cmock_generator_plugin_expect.mock_interfaces(function) + assert_equal(expected, returned) + end + + it "add mock interfaces for functions of style 'int func(char* pescado)'" do + function = {:name => "Lemon", :args => [{ :type => "char*", :name => "pescado"}], :args_string => "char* pescado", :return => test_return[:int]} + @utils.expect :code_add_base_expectation, "mock_retval_0 ", ["Lemon"] + @utils.expect :code_call_argument_loader, "mock_retval_1 ", [function] + @utils.expect :code_assign_argument_quickly, "mock_retval_2", ["cmock_call_instance->ReturnVal", function[:return]] + expected = ["void Lemon_CMockExpectAndReturn(UNITY_LINE_TYPE cmock_line, char* pescado, int cmock_to_return)\n", + "{\n", + "mock_retval_0 ", + "mock_retval_1 ", + "mock_retval_2", + "}\n\n" + ].join + returned = @cmock_generator_plugin_expect.mock_interfaces(function) + assert_equal(expected, returned) + end + + it "add mock interfaces for functions when using ordering" do + function = {:name => "Pear", :args => [], :args_string => "void", :return => test_return[:void]} + @utils.expect :code_add_base_expectation, "mock_retval_0 ", ["Pear"] + @utils.expect :code_call_argument_loader, "mock_retval_1 ", [function] + expected = ["void Pear_CMockExpect(UNITY_LINE_TYPE cmock_line)\n", + "{\n", + "mock_retval_0 ", + "mock_retval_1 ", + "}\n\n" + ].join + @cmock_generator_plugin_expect.ordered = true + returned = @cmock_generator_plugin_expect.mock_interfaces(function) + assert_equal(expected, returned) + end + + it "add mock verify lines" do + function = {:name => "Banana" } + expected = " if (CMOCK_GUTS_NONE != call_instance)\n" \ + " {\n" \ + " UNITY_SET_DETAIL(CMockString_Banana);\n" \ + " UNITY_TEST_FAIL(cmock_line, CMockStringCalledLess);\n" \ + " }\n" + returned = @cmock_generator_plugin_expect.mock_verify(function) + assert_equal(expected, returned) + end +end From 338279285b5549210ae9b299b90ebdcdb1ebe201 Mon Sep 17 00:00:00 2001 From: Roland Stahn Date: Fri, 13 Jun 2025 11:32:27 +0200 Subject: [PATCH 09/11] Delete test/unit/cmock_generator_plugin_expect_c_test.rb --- .../cmock_generator_plugin_expect_c_test.rb | 187 ------------------ 1 file changed, 187 deletions(-) delete mode 100644 test/unit/cmock_generator_plugin_expect_c_test.rb diff --git a/test/unit/cmock_generator_plugin_expect_c_test.rb b/test/unit/cmock_generator_plugin_expect_c_test.rb deleted file mode 100644 index 80d3a48c..00000000 --- a/test/unit/cmock_generator_plugin_expect_c_test.rb +++ /dev/null @@ -1,187 +0,0 @@ -# ========================================================================= -# CMock - Automatic Mock Generation for C -# ThrowTheSwitch.org -# Copyright (c) 2007-25 Mike Karlesky, Mark VanderVoord, & Greg Williams -# SPDX-License-Identifier: MIT -# ========================================================================= - -require File.expand_path(File.dirname(__FILE__)) + "/../test_helper" -require File.expand_path(File.dirname(__FILE__)) + '/../../lib/cmock_generator_plugin_expect' - -describe CMockGeneratorPluginExpect, "Verify CMockGeneratorPluginExpect Module Without Global Ordering And Without Error Stubs" do - - before do - create_mocks :config, :utils - - @config = create_stub( - :when_ptr => :compare_data, - :enforce_strict_ordering => false, - :respond_to? => true, - :create_error_stubs => false, - :plugins => [ :expect ] ) - - @utils.expect :helpers, {} - @cmock_generator_plugin_expect = CMockGeneratorPluginExpect.new(@config, @utils) - end - - after do - end - - it "have set up internal priority on init" do - assert_nil(@cmock_generator_plugin_expect.unity_helper) - assert_equal(5, @cmock_generator_plugin_expect.priority) - end - - it "not include any additional include files" do - assert(!@cmock_generator_plugin_expect.respond_to?(:include_files)) - end - - it "add to typedef structure mock needs of functions of style 'void func(void)'" do - function = {:name => "Oak", :args => [], :return => test_return[:void]} - expected = "" - returned = @cmock_generator_plugin_expect.instance_typedefs(function) - assert_equal(expected, returned) - end - - it "add to typedef structure mock needs of functions of style 'int func(void)'" do - function = {:name => "Elm", :args => [], :return => test_return[:int]} - expected = " int ReturnVal;\n" - returned = @cmock_generator_plugin_expect.instance_typedefs(function) - assert_equal(expected, returned) - end - - it "add to typedef structure mock needs of functions of style 'void func(int chicken, char* pork)'" do - function = {:name => "Cedar", :args => [{ :name => "chicken", :type => "int"}, { :name => "pork", :type => "char*"}], :return => test_return[:void]} - expected = " int Expected_chicken;\n char* Expected_pork;\n" - returned = @cmock_generator_plugin_expect.instance_typedefs(function) - assert_equal(expected, returned) - end - - it "add to typedef structure mock needs of functions of style 'int func(float beef)'" do - function = {:name => "Birch", :args => [{ :name => "beef", :type => "float"}], :return => test_return[:int]} - expected = " int ReturnVal;\n float Expected_beef;\n" - returned = @cmock_generator_plugin_expect.instance_typedefs(function) - assert_equal(expected, returned) - end - - it "add mock function declaration for functions of style 'void func(void)'" do - function = {:name => "Maple", :args => [], :return => test_return[:void]} - expected = "#define Maple_Expect() Maple_CMockExpect(__LINE__)\n" + - "void Maple_CMockExpect(UNITY_LINE_TYPE cmock_line);\n" - returned = @cmock_generator_plugin_expect.mock_function_declarations(function) - assert_equal(expected, returned) - end - - it "add mock function declaration for functions of style 'int func(void)'" do - function = {:name => "Spruce", :args => [], :return => test_return[:int]} - expected = "#define Spruce_ExpectAndReturn(cmock_retval) Spruce_CMockExpectAndReturn(__LINE__, cmock_retval)\n" + - "void Spruce_CMockExpectAndReturn(UNITY_LINE_TYPE cmock_line, int cmock_to_return);\n" - returned = @cmock_generator_plugin_expect.mock_function_declarations(function) - assert_equal(expected, returned) - end - - it "add mock function declaration for functions of style 'const char* func(int tofu)'" do - function = {:name => "Pine", :args => ["int tofu"], :args_string => "int tofu", :args_call => 'tofu', :return => test_return[:string]} - expected = "#define Pine_ExpectAndReturn(tofu, cmock_retval) Pine_CMockExpectAndReturn(__LINE__, tofu, cmock_retval)\n" + - "void Pine_CMockExpectAndReturn(UNITY_LINE_TYPE cmock_line, int tofu, const char* cmock_to_return);\n" - returned = @cmock_generator_plugin_expect.mock_function_declarations(function) - assert_equal(expected, returned) - end - - it "add mock function implementation for functions of style 'void func(void)'" do - function = {:name => "Apple", :args => [], :return => test_return[:void]} - expected = "" - returned = @cmock_generator_plugin_expect.mock_implementation(function) - assert_equal(expected, returned) - end - - it "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" } ], :return => test_return[:int]} - - @utils.expect :code_verify_an_arg_expectation, " mocked_retval_1", [function, function[:args][0]] - @utils.expect :code_verify_an_arg_expectation, " mocked_retval_2", [function, function[:args][1]] - expected = " mocked_retval_1 mocked_retval_2" - returned = @cmock_generator_plugin_expect.mock_implementation(function) - assert_equal(expected, returned) - end - - it "add mock function implementation using ordering if needed" do - function = {:name => "Apple", :args => [], :return => test_return[:void]} - expected = "" - @cmock_generator_plugin_expect.ordered = true - returned = @cmock_generator_plugin_expect.mock_implementation(function) - assert_equal(expected, returned) - end - - it "add mock interfaces for functions of style 'void func(void)'" do - function = {:name => "Pear", :args => [], :args_string => "void", :return => test_return[:void]} - @utils.expect :code_add_base_expectation, "mock_retval_0 ", ["Pear"] - @utils.expect :code_call_argument_loader, "mock_retval_1 ", [function] - expected = ["void Pear_CMockExpect(UNITY_LINE_TYPE cmock_line)\n", - "{\n", - "mock_retval_0 ", - "mock_retval_1 ", - "}\n\n" - ].join - returned = @cmock_generator_plugin_expect.mock_interfaces(function) - assert_equal(expected, returned) - end - - it "add mock interfaces for functions of style 'int func(void)'" do - function = {:name => "Orange", :args => [], :args_string => "void", :return => test_return[:int]} - @utils.expect :code_add_base_expectation, "mock_retval_0 ", ["Orange"] - @utils.expect :code_call_argument_loader, "mock_retval_1 ", [function] - @utils.expect :code_assign_argument_quickly, "mock_retval_2", ["cmock_call_instance->ReturnVal", function[:return]] - expected = ["void Orange_CMockExpectAndReturn(UNITY_LINE_TYPE cmock_line, int cmock_to_return)\n", - "{\n", - "mock_retval_0 ", - "mock_retval_1 ", - "mock_retval_2", - "}\n\n" - ].join - returned = @cmock_generator_plugin_expect.mock_interfaces(function) - assert_equal(expected, returned) - end - - it "add mock interfaces for functions of style 'int func(char* pescado)'" do - function = {:name => "Lemon", :args => [{ :type => "char*", :name => "pescado"}], :args_string => "char* pescado", :return => test_return[:int]} - @utils.expect :code_add_base_expectation, "mock_retval_0 ", ["Lemon"] - @utils.expect :code_call_argument_loader, "mock_retval_1 ", [function] - @utils.expect :code_assign_argument_quickly, "mock_retval_2", ["cmock_call_instance->ReturnVal", function[:return]] - expected = ["void Lemon_CMockExpectAndReturn(UNITY_LINE_TYPE cmock_line, char* pescado, int cmock_to_return)\n", - "{\n", - "mock_retval_0 ", - "mock_retval_1 ", - "mock_retval_2", - "}\n\n" - ].join - returned = @cmock_generator_plugin_expect.mock_interfaces(function) - assert_equal(expected, returned) - end - - it "add mock interfaces for functions when using ordering" do - function = {:name => "Pear", :args => [], :args_string => "void", :return => test_return[:void]} - @utils.expect :code_add_base_expectation, "mock_retval_0 ", ["Pear"] - @utils.expect :code_call_argument_loader, "mock_retval_1 ", [function] - expected = ["void Pear_CMockExpect(UNITY_LINE_TYPE cmock_line)\n", - "{\n", - "mock_retval_0 ", - "mock_retval_1 ", - "}\n\n" - ].join - @cmock_generator_plugin_expect.ordered = true - returned = @cmock_generator_plugin_expect.mock_interfaces(function) - assert_equal(expected, returned) - end - - it "add mock verify lines" do - function = {:name => "Banana" } - expected = " if (CMOCK_GUTS_NONE != call_instance)\n" \ - " {\n" \ - " UNITY_SET_DETAIL(CMockString_Banana);\n" \ - " UNITY_TEST_FAIL(cmock_line, CMockStringCalledLess);\n" \ - " }\n" - returned = @cmock_generator_plugin_expect.mock_verify(function) - assert_equal(expected, returned) - end -end From 6f2a234dcaf9e2c02e743ce048ab97ba4d571aff Mon Sep 17 00:00:00 2001 From: Roland Stahn Date: Fri, 13 Jun 2025 11:35:32 +0200 Subject: [PATCH 10/11] Add tests with 'create_error_stubs' set to false --- ...erator_no_error_stubs_plugin_array_test.rb | 87 +++++++++++++++++++ ...error_stubs_plugin_expect_any_args_test.rb | 38 ++++++++ ...rator_no_error_stubs_plugin_expect_test.rb | 54 ++++++++++++ ...rror_stubs_plugin_ignore_stateless_test.rb | 42 +++++++++ ...rator_no_error_stubs_plugin_ignore_test.rb | 42 +++++++++ 5 files changed, 263 insertions(+) create mode 100644 test/unit/cmock_generator_no_error_stubs_plugin_array_test.rb create mode 100644 test/unit/cmock_generator_no_error_stubs_plugin_expect_any_args_test.rb create mode 100644 test/unit/cmock_generator_no_error_stubs_plugin_expect_test.rb create mode 100644 test/unit/cmock_generator_no_error_stubs_plugin_ignore_stateless_test.rb create mode 100644 test/unit/cmock_generator_no_error_stubs_plugin_ignore_test.rb diff --git a/test/unit/cmock_generator_no_error_stubs_plugin_array_test.rb b/test/unit/cmock_generator_no_error_stubs_plugin_array_test.rb new file mode 100644 index 00000000..50ae54ae --- /dev/null +++ b/test/unit/cmock_generator_no_error_stubs_plugin_array_test.rb @@ -0,0 +1,87 @@ +# ========================================================================= +# CMock - Automatic Mock Generation for C +# ThrowTheSwitch.org +# Copyright (c) 2007-25 Mike Karlesky, Mark VanderVoord, & Greg Williams +# SPDX-License-Identifier: MIT +# ========================================================================= + +require File.expand_path(File.dirname(__FILE__)) + "/../test_helper" +require File.expand_path(File.dirname(__FILE__)) + '/../../lib/cmock_generator_plugin_array' +require File.expand_path(File.dirname(__FILE__)) + '/../../lib/cmock_generator_utils' + +class UtilsStub + def helpers + {} + end + def arg_type_with_const(arg) + CMockGeneratorUtils.arg_type_with_const(arg) + end + def code_add_base_expectation(func) + "mock_retval_0" + end +end + +describe CMockGeneratorPluginArray, "Verify Generation Of Mock Function Declarations Without Error Stubs By CMockPGeneratorluginArray Module" do + before do + #no strict ordering + @config = create_stub( + :when_ptr => :compare_data, + :enforce_strict_ordering => false, + :respond_to? => true, + :create_error_stubs => false) + + @utils = UtilsStub.new + + @cmock_generator_plugin_array = CMockGeneratorPluginArray.new(@config, @utils) + end + + after do + end + + it "add another mock function declaration for functions of style 'void func(int* tofu)'" do + function = {:name => "Pine", + :args => [{ :type => "int*", + :name => "tofu", + :ptr? => true, + }], + :return => test_return[:void], + :contains_ptr? => true } + + expected = "#define #{function[:name]}_ExpectWithArray(tofu, tofu_Depth) #{function[:name]}_CMockExpectWithArray(__LINE__, tofu, (tofu_Depth))\n" + + "void #{function[:name]}_CMockExpectWithArray(UNITY_LINE_TYPE cmock_line, int* tofu, int tofu_Depth);\n" + returned = @cmock_generator_plugin_array.mock_function_declarations(function) + assert_equal(expected, returned) + end + + it "add another mock function declaration for functions of style 'const char* func(int* tofu)'" do + function = {:name => "Pine", + :args => [{ :type => "int*", + :name => "tofu", + :ptr? => true, + }], + :return => test_return[:string], + :contains_ptr? => true } + + expected = "#define #{function[:name]}_ExpectWithArrayAndReturn(tofu, tofu_Depth, cmock_retval) #{function[:name]}_CMockExpectWithArrayAndReturn(__LINE__, tofu, (tofu_Depth), cmock_retval)\n" + + "void #{function[:name]}_CMockExpectWithArrayAndReturn(UNITY_LINE_TYPE cmock_line, int* tofu, int tofu_Depth, const char* cmock_to_return);\n" + returned = @cmock_generator_plugin_array.mock_function_declarations(function) + assert_equal(expected, returned) + end + + it "add another mock function declaration for functions of style 'const char* func(const int* tofu)'" do + function = {:name => "Pine", + :args => [{ :type => "const int*", + :name => "tofu", + :ptr? => true, + :const? => true, + }], + :return => test_return[:string], + :contains_ptr? => true } + + expected = "#define #{function[:name]}_ExpectWithArrayAndReturn(tofu, tofu_Depth, cmock_retval) #{function[:name]}_CMockExpectWithArrayAndReturn(__LINE__, tofu, (tofu_Depth), cmock_retval)\n" + + "void #{function[:name]}_CMockExpectWithArrayAndReturn(UNITY_LINE_TYPE cmock_line, const int* tofu, int tofu_Depth, const char* cmock_to_return);\n" + returned = @cmock_generator_plugin_array.mock_function_declarations(function) + assert_equal(expected, returned) + end + +end diff --git a/test/unit/cmock_generator_no_error_stubs_plugin_expect_any_args_test.rb b/test/unit/cmock_generator_no_error_stubs_plugin_expect_any_args_test.rb new file mode 100644 index 00000000..3de42265 --- /dev/null +++ b/test/unit/cmock_generator_no_error_stubs_plugin_expect_any_args_test.rb @@ -0,0 +1,38 @@ +# ========================================================================= +# CMock - Automatic Mock Generation for C +# ThrowTheSwitch.org +# Copyright (c) 2007-25 Mike Karlesky, Mark VanderVoord, & Greg Williams +# SPDX-License-Identifier: MIT +# ========================================================================= + +require File.expand_path(File.dirname(__FILE__)) + "/../test_helper" +require File.expand_path(File.dirname(__FILE__)) + '/../../lib/cmock_generator_plugin_expect_any_args.rb' + +describe CMockGeneratorPluginExpectAnyArgs, "Verify Generation Of Mock Function Declarations Without Error Stubs By CMockGeneratorPluginExpectAnyArgs Module" do + + before do + create_mocks :config, :utils + @config = create_stub(:respond_to? => true, :create_error_stubs => false) + @cmock_generator_plugin_expect_any_args = CMockGeneratorPluginExpectAnyArgs.new(@config, @utils) + end + + after do + end + + it "handle function declarations for functions without return values" do + function = {:name => "Mold", :args_string => "int meh", :args => [ :stuff ], :return => test_return[:void]} + expected = "#define Mold_ExpectAnyArgs() Mold_CMockExpectAnyArgs(__LINE__)\n"+ + "void Mold_CMockExpectAnyArgs(UNITY_LINE_TYPE cmock_line);\n" + returned = @cmock_generator_plugin_expect_any_args.mock_function_declarations(function) + assert_equal(expected, returned) + end + + it "handle function declarations for functions that returns something" do + function = {:name => "Fungus", :args_string => "int meh", :args => [ :stuff ], :return => test_return[:string]} + expected = "#define Fungus_ExpectAnyArgsAndReturn(cmock_retval) Fungus_CMockExpectAnyArgsAndReturn(__LINE__, cmock_retval)\n"+ + "void Fungus_CMockExpectAnyArgsAndReturn(UNITY_LINE_TYPE cmock_line, const char* cmock_to_return);\n" + returned = @cmock_generator_plugin_expect_any_args.mock_function_declarations(function) + assert_equal(expected, returned) + end + +end diff --git a/test/unit/cmock_generator_no_error_stubs_plugin_expect_test.rb b/test/unit/cmock_generator_no_error_stubs_plugin_expect_test.rb new file mode 100644 index 00000000..795fa579 --- /dev/null +++ b/test/unit/cmock_generator_no_error_stubs_plugin_expect_test.rb @@ -0,0 +1,54 @@ +# ========================================================================= +# CMock - Automatic Mock Generation for C +# ThrowTheSwitch.org +# Copyright (c) 2007-25 Mike Karlesky, Mark VanderVoord, & Greg Williams +# SPDX-License-Identifier: MIT +# ========================================================================= + +require File.expand_path(File.dirname(__FILE__)) + "/../test_helper" +require File.expand_path(File.dirname(__FILE__)) + '/../../lib/cmock_generator_plugin_expect' + +describe CMockGeneratorPluginExpect, "Verify Generation Of Mock Function Declarations Without Error Stubs By CMockGeneratorPluginExpect Module" do + + before do + create_mocks :config, :utils + + @config = create_stub( + :when_ptr => :compare_data, + :enforce_strict_ordering => false, + :respond_to? => true, + :create_error_stubs => false, + :plugins => [ :expect ] ) + + @utils.expect :helpers, {} + @cmock_generator_plugin_expect = CMockGeneratorPluginExpect.new(@config, @utils) + end + + after do + end + + it "add mock function declarations for functions of style 'void func(void)'" do + function = {:name => "Maple", :args => [], :return => test_return[:void]} + expected = "#define Maple_Expect() Maple_CMockExpect(__LINE__)\n" + + "void Maple_CMockExpect(UNITY_LINE_TYPE cmock_line);\n" + returned = @cmock_generator_plugin_expect.mock_function_declarations(function) + assert_equal(expected, returned) + end + + it "add mock function declarations for functions of style 'int func(void)'" do + function = {:name => "Spruce", :args => [], :return => test_return[:int]} + expected = "#define Spruce_ExpectAndReturn(cmock_retval) Spruce_CMockExpectAndReturn(__LINE__, cmock_retval)\n" + + "void Spruce_CMockExpectAndReturn(UNITY_LINE_TYPE cmock_line, int cmock_to_return);\n" + returned = @cmock_generator_plugin_expect.mock_function_declarations(function) + assert_equal(expected, returned) + end + + it "add mock function declarations for functions of style 'const char* func(int tofu)'" do + function = {:name => "Pine", :args => ["int tofu"], :args_string => "int tofu", :args_call => 'tofu', :return => test_return[:string]} + expected = "#define Pine_ExpectAndReturn(tofu, cmock_retval) Pine_CMockExpectAndReturn(__LINE__, tofu, cmock_retval)\n" + + "void Pine_CMockExpectAndReturn(UNITY_LINE_TYPE cmock_line, int tofu, const char* cmock_to_return);\n" + returned = @cmock_generator_plugin_expect.mock_function_declarations(function) + assert_equal(expected, returned) + end + +end diff --git a/test/unit/cmock_generator_no_error_stubs_plugin_ignore_stateless_test.rb b/test/unit/cmock_generator_no_error_stubs_plugin_ignore_stateless_test.rb new file mode 100644 index 00000000..62464aa6 --- /dev/null +++ b/test/unit/cmock_generator_no_error_stubs_plugin_ignore_stateless_test.rb @@ -0,0 +1,42 @@ +# ========================================================================= +# CMock - Automatic Mock Generation for C +# ThrowTheSwitch.org +# Copyright (c) 2007-25 Mike Karlesky, Mark VanderVoord, & Greg Williams +# SPDX-License-Identifier: MIT +# ========================================================================= + +require File.expand_path(File.dirname(__FILE__)) + "/../test_helper" +require File.expand_path(File.dirname(__FILE__)) + '/../../lib/cmock_generator_plugin_ignore_stateless' + +describe CMockGeneratorPluginIgnoreStateless, "Verify Generation Of Mock Function Declarations Without Error Stubs By CMockGeneratorPluginIgnoreStateless Module" do + + before do + create_mocks :config, :utils + @config = create_stub(:respond_to? => true, :create_error_stubs => false) + @cmock_generator_plugin_ignore_stateless = CMockGeneratorPluginIgnoreStateless.new(@config, @utils) + end + + after do + end + + it "handle function declarations for functions without return values" do + function = {:name => "Mold", :args_string => "void", :return => test_return[:void]} + expected = "#define Mold_Ignore() Mold_CMockIgnore()\n" + + "void Mold_CMockIgnore(void);\n" + + "#define Mold_StopIgnore() Mold_CMockStopIgnore()\n" + + "void Mold_CMockStopIgnore(void);\n" + returned = @cmock_generator_plugin_ignore_stateless.mock_function_declarations(function) + assert_equal(expected, returned) + end + + it "handle function declarations for functions that returns something" do + function = {:name => "Fungus", :args_string => "void", :return => test_return[:string]} + expected = "#define Fungus_IgnoreAndReturn(cmock_retval) Fungus_CMockIgnoreAndReturn(cmock_retval)\n"+ + "void Fungus_CMockIgnoreAndReturn(const char* cmock_to_return);\n" + + "#define Fungus_StopIgnore() Fungus_CMockStopIgnore()\n"+ + "void Fungus_CMockStopIgnore(void);\n" + returned = @cmock_generator_plugin_ignore_stateless.mock_function_declarations(function) + assert_equal(expected, returned) + end + +end diff --git a/test/unit/cmock_generator_no_error_stubs_plugin_ignore_test.rb b/test/unit/cmock_generator_no_error_stubs_plugin_ignore_test.rb new file mode 100644 index 00000000..97ed8d85 --- /dev/null +++ b/test/unit/cmock_generator_no_error_stubs_plugin_ignore_test.rb @@ -0,0 +1,42 @@ +# ========================================================================= +# CMock - Automatic Mock Generation for C +# ThrowTheSwitch.org +# Copyright (c) 2007-25 Mike Karlesky, Mark VanderVoord, & Greg Williams +# SPDX-License-Identifier: MIT +# ========================================================================= + +require File.expand_path(File.dirname(__FILE__)) + "/../test_helper" +require File.expand_path(File.dirname(__FILE__)) + '/../../lib/cmock_generator_plugin_ignore' + +describe CMockGeneratorPluginIgnore, "Verify Generation Of Mock Function Declarations Without Error Stubs By CMockGeneratorPluginIgnore Module" do + + before do + create_mocks :config, :utils + @config = create_stub(:respond_to? => true, :create_error_stubs => false) + @cmock_generator_plugin_ignore = CMockGeneratorPluginIgnore.new(@config, @utils) + end + + after do + end + + it "handle function declarations for functions without return values" do + function = {:name => "Mold", :args_string => "void", :return => test_return[:void]} + expected = "#define Mold_Ignore() Mold_CMockIgnore()\n" + + "void Mold_CMockIgnore(void);\n" + + "#define Mold_StopIgnore() Mold_CMockStopIgnore()\n" + + "void Mold_CMockStopIgnore(void);\n" + returned = @cmock_generator_plugin_ignore.mock_function_declarations(function) + assert_equal(expected, returned) + end + + it "handle function declarations for functions that returns something" do + function = {:name => "Fungus", :args_string => "void", :return => test_return[:string]} + expected = "#define Fungus_IgnoreAndReturn(cmock_retval) Fungus_CMockIgnoreAndReturn(__LINE__, cmock_retval)\n"+ + "void Fungus_CMockIgnoreAndReturn(UNITY_LINE_TYPE cmock_line, const char* cmock_to_return);\n" + + "#define Fungus_StopIgnore() Fungus_CMockStopIgnore()\n"+ + "void Fungus_CMockStopIgnore(void);\n" + returned = @cmock_generator_plugin_ignore.mock_function_declarations(function) + assert_equal(expected, returned) + end + +end From ad9ce635c3c30f1f9a331c56583518164ed15433 Mon Sep 17 00:00:00 2001 From: Roland Stahn Date: Fri, 13 Jun 2025 12:45:11 +0200 Subject: [PATCH 11/11] Update main.yml Remove trigger for branch rstahn-patch-1 for final PR --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index f53eee3d..9c89b144 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -6,7 +6,7 @@ name: CI # Triggers the workflow on push or pull request events but only for the master branch on: push: - branches: [ master, rstahn-patch-* ] + branches: [ master ] pull_request: branches: [ master ]