diff --git a/lib/cmock_function_prototype_node_classes.rb b/lib/cmock_function_prototype_node_classes.rb index 1b2e5d8..c59f2ce 100644 --- a/lib/cmock_function_prototype_node_classes.rb +++ b/lib/cmock_function_prototype_node_classes.rb @@ -31,7 +31,7 @@ module CMockFunctionPrototype # preformatted string for _Return statements e.g. "int toReturn" def get_return_type_with_name - return "#{return_type.text_value} #{CMOCK_RETURN_PARAM_NAME}" + return "#{return_type.text_value} toReturn" end def get_function_name @@ -69,7 +69,7 @@ module CMockFunctionPrototype # preformatted string for _Return statements e.g. "void (*toReturn)(void)" def get_return_type_with_name - return "#{return_type.text_value} (*#{CMOCK_RETURN_PARAM_NAME})#{function_return_arglist.normalized_argument_list}" + return "#{return_type.text_value} (*toReturn)#{function_return_arglist.normalized_argument_list}" end def get_function_name diff --git a/lib/cmock_generator.rb b/lib/cmock_generator.rb index 9e487f1..7110920 100644 --- a/lib/cmock_generator.rb +++ b/lib/cmock_generator.rb @@ -1,7 +1,5 @@ $here = File.dirname __FILE__ -CMOCK_RETURN_PARAM_NAME = 'toReturn' - class CMockGenerator attr_reader :config, :file_writer, :tab, :module_name, :mock_name, :utils, :plugins @@ -118,7 +116,9 @@ class CMockGenerator file << functions.collect {|function| @plugins.run(:mock_verify, function)}.join if (@ordered) file << "#{@tab}if (GlobalOrderError)\n" + file << "#{@tab}{\n" file << "#{@tab}#{@tab}TEST_FAIL(GlobalOrderError);\n" + file << "#{@tab}}\n" end file << "}\n\n" end diff --git a/lib/cmock_generator_plugin_cexception.rb b/lib/cmock_generator_plugin_cexception.rb index 2cff595..5bf35ad 100644 --- a/lib/cmock_generator_plugin_cexception.rb +++ b/lib/cmock_generator_plugin_cexception.rb @@ -62,11 +62,14 @@ class CMockGeneratorPluginCException "{\n", @utils.code_add_base_expectation(function[:name]), @utils.code_insert_item_into_expect_array(call_count_type, "Mock.#{function[:name]}_ThrowOnCallCount_Head", "Mock.#{function[:name]}_CallsExpected"), - "#{@tab}Mock.#{function[:name]}_ThrowOnCallCount = Mock.#{function[:name]}_ThrowOnCallCount_Head;\n", - "#{@tab}Mock.#{function[:name]}_ThrowOnCallCount += Mock.#{function[:name]}_CallCount;\n", @utils.code_insert_item_into_expect_array(throw_type, "Mock.#{function[:name]}_ThrowValue_Head", "toThrow"), "#{@tab}Mock.#{function[:name]}_ThrowValue = Mock.#{function[:name]}_ThrowValue_Head;\n", - "#{@tab}Mock.#{function[:name]}_ThrowValue += Mock.#{function[:name]}_CallCount;\n", + "#{@tab}Mock.#{function[:name]}_ThrowOnCallCount = Mock.#{function[:name]}_ThrowOnCallCount_Head;\n", + "#{@tab}while ((*Mock.#{function[:name]}_ThrowOnCallCount <= Mock.#{function[:name]}_CallCount) && (Mock.#{function[:name]}_ThrowOnCallCount < Mock.#{function[:name]}_ThrowOnCallCount_Tail))\n", + "#{@tab}{\n", + "#{@tab}#{@tab}Mock.#{function[:name]}_ThrowValue++;\n", + "#{@tab}#{@tab}Mock.#{function[:name]}_ThrowOnCallCount++;\n", + "#{@tab}}\n", (function[:args_string] != "void") ? "#{@tab}ExpectParameters_#{function[:name]}(#{@utils.create_call_list(function)});\n" : nil, "}\n\n" ].compact end @@ -75,14 +78,17 @@ class CMockGeneratorPluginCException [ "#{@tab}if(Mock.#{function[:name]}_ThrowOnCallCount_Head)\n", "#{@tab}{\n", "#{@tab}#{@tab}free(Mock.#{function[:name]}_ThrowOnCallCount_Head);\n", - "#{@tab}#{@tab}Mock.#{function[:name]}_ThrowOnCallCount_Head=NULL;\n", - "#{@tab}#{@tab}Mock.#{function[:name]}_ThrowOnCallCount_Tail=NULL;\n", "#{@tab}}\n", + "#{@tab}Mock.#{function[:name]}_ThrowOnCallCount=NULL;\n", + "#{@tab}Mock.#{function[:name]}_ThrowOnCallCount_Head=NULL;\n", + "#{@tab}Mock.#{function[:name]}_ThrowOnCallCount_Tail=NULL;\n", "#{@tab}if(Mock.#{function[:name]}_ThrowValue_Head)\n", "#{@tab}{\n", "#{@tab}#{@tab}free(Mock.#{function[:name]}_ThrowValue_Head);\n", - "#{@tab}#{@tab}Mock.#{function[:name]}_ThrowValue_Head=NULL;\n", - "#{@tab}#{@tab}Mock.#{function[:name]}_ThrowValue_Tail=NULL;\n", - "#{@tab}}\n" ] + "#{@tab}}\n", + "#{@tab}Mock.#{function[:name]}_ThrowValue=NULL;\n", + "#{@tab}Mock.#{function[:name]}_ThrowValue_Head=NULL;\n", + "#{@tab}Mock.#{function[:name]}_ThrowValue_Tail=NULL;\n" + ] end end diff --git a/lib/cmock_generator_plugin_expect.rb b/lib/cmock_generator_plugin_expect.rb index 9bf21ec..b3bbb04 100644 --- a/lib/cmock_generator_plugin_expect.rb +++ b/lib/cmock_generator_plugin_expect.rb @@ -57,20 +57,20 @@ class CMockGeneratorPluginExpect lines = [ "#{@tab}Mock.#{function[:name]}_CallCount++;\n", "#{@tab}if (Mock.#{function[:name]}_CallCount > Mock.#{function[:name]}_CallsExpected)\n", "#{@tab}{\n", - "#{@tab}#{@tab}TEST_FAIL(\"#{function[:name]} Called More Times Than Expected\");\n", + "#{@tab}#{@tab}TEST_FAIL(\"Function '#{function[:name]}' called more times than expected\");\n", "#{@tab}}\n" ] if (@ordered) + err_msg = "Out of order function calls. Function '#{function[:name]}'" #" expected to be call %i but was call %i" lines << [ "#{@tab}{\n", "#{@tab}#{@tab}int* p_expected = Mock.#{function[:name]}_CallOrder;\n", "#{@tab}#{@tab}++GlobalVerifyOrder;\n", "#{@tab}#{@tab}if (Mock.#{function[:name]}_CallOrder != Mock.#{function[:name]}_CallOrder_Tail)\n", "#{@tab}#{@tab}#{@tab}Mock.#{function[:name]}_CallOrder++;\n", - #@utils.expect_helper('int', '*p_expected', 'GlobalVerifyOrder', "\"Function '#{function[:name]}' Called Out Of Order.\"","#{@tab}#{@tab}"), "#{@tab}#{@tab}if ((*p_expected != GlobalVerifyOrder) && (GlobalOrderError == NULL))\n", "#{@tab}#{@tab}{\n", - "#{@tab}#{@tab}#{@tab}const char* ErrStr = \"Function '#{function[:name]}' Called Out Of Order.\";\n", - "#{@tab}#{@tab}#{@tab}GlobalOrderError = malloc(#{"Function '#{function[:name]}' Called Out Of Order.".size+1});\n", + "#{@tab}#{@tab}#{@tab}const char* ErrStr = \"#{err_msg}\";\n", + "#{@tab}#{@tab}#{@tab}GlobalOrderError = malloc(#{err_msg.size + 1});\n", "#{@tab}#{@tab}#{@tab}if (GlobalOrderError)\n", "#{@tab}#{@tab}#{@tab}#{@tab}strcpy(GlobalOrderError, ErrStr);\n", "#{@tab}#{@tab}}\n", @@ -114,7 +114,7 @@ class CMockGeneratorPluginExpect end if (function[:return_type] != "void") - lines << @utils.code_insert_item_into_expect_array(function[:return_type], "Mock.#{function[:name]}_Return_Head", CMOCK_RETURN_PARAM_NAME) + lines << @utils.code_insert_item_into_expect_array(function[:return_type], "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 @@ -131,25 +131,31 @@ class CMockGeneratorPluginExpect lines << [ "#{@tab}if (Mock.#{function[:name]}_Return_Head)\n", "#{@tab}{\n", "#{@tab}#{@tab}free(Mock.#{function[:name]}_Return_Head);\n", - "#{@tab}#{@tab}Mock.#{function[:name]}_Return_Head=NULL;\n", - "#{@tab}#{@tab}Mock.#{function[:name]}_Return_Tail=NULL;\n", - "#{@tab}}\n" ] + "#{@tab}}\n", + "#{@tab}Mock.#{function[:name]}_Return=NULL;\n", + "#{@tab}Mock.#{function[:name]}_Return_Head=NULL;\n", + "#{@tab}Mock.#{function[:name]}_Return_Tail=NULL;\n" + ] end if (@ordered) lines << [ "#{@tab}if (Mock.#{function[:name]}_CallOrder_Head)\n", "#{@tab}{\n", "#{@tab}#{@tab}free(Mock.#{function[:name]}_CallOrder_Head);\n", - "#{@tab}#{@tab}Mock.#{function[:name]}_CallOrder_Head=NULL;\n", - "#{@tab}#{@tab}Mock.#{function[:name]}_CallOrder_Tail=NULL;\n", - "#{@tab}}\n" ] + "#{@tab}}\n", + "#{@tab}Mock.#{function[:name]}_CallOrder=NULL;\n", + "#{@tab}Mock.#{function[:name]}_CallOrder_Head=NULL;\n", + "#{@tab}Mock.#{function[:name]}_CallOrder_Tail=NULL;\n" + ] end function[:args].each do |arg| lines << [ "#{@tab}if (Mock.#{function[:name]}_Expected_#{arg[:name]}_Head)\n", "#{@tab}{\n", "#{@tab}#{@tab}free(Mock.#{function[:name]}_Expected_#{arg[:name]}_Head);\n", - "#{@tab}#{@tab}Mock.#{function[:name]}_Expected_#{arg[:name]}_Head=NULL;\n", - "#{@tab}#{@tab}Mock.#{function[:name]}_Expected_#{arg[:name]}_Tail=NULL;\n", - "#{@tab}}\n" ] + "#{@tab}}\n", + "#{@tab}Mock.#{function[:name]}_Expected_#{arg[:name]}=NULL;\n", + "#{@tab}Mock.#{function[:name]}_Expected_#{arg[:name]}_Head=NULL;\n", + "#{@tab}Mock.#{function[:name]}_Expected_#{arg[:name]}_Tail=NULL;\n" + ] end lines.flatten end diff --git a/lib/cmock_generator_plugin_ignore.rb b/lib/cmock_generator_plugin_ignore.rb index d8eee3e..de7940d 100644 --- a/lib/cmock_generator_plugin_ignore.rb +++ b/lib/cmock_generator_plugin_ignore.rb @@ -26,10 +26,28 @@ class CMockGeneratorPluginIgnore end def mock_implementation_prefix(function) - [ "#{@tab}if (Mock.#{function[:name]}_IgnoreBool)\n", - "#{@tab}{\n", - (function[:return_type] == "void") ? "#{@tab}#{@tab}return;\n" : @utils.code_handle_return_value(function, "#{@tab}#{@tab}"), - "#{@tab}}\n" ] + lines = [ "#{@tab}if (Mock.#{function[:name]}_IgnoreBool)\n", + "#{@tab}{\n" + ] + if (function[:return_type] == "void") + lines << ["#{@tab*2}return;\n"] + else + lines << [ "#{@tab*2}if (Mock.#{function[:name]}_Return != Mock.#{function[:name]}_Return_Tail)\n", + "#{@tab*2}{\n", + "#{@tab*3}#{function[:return_type]} toReturn = *Mock.#{function[:name]}_Return;\n", + "#{@tab*3}Mock.#{function[:name]}_Return++;\n", + "#{@tab*3}Mock.#{function[:name]}_CallCount++;\n", + "#{@tab*3}Mock.#{function[:name]}_CallsExpected++;\n", + "#{@tab*3}return toReturn;\n", + "#{@tab*2}}\n", + "#{@tab*2}else\n", + "#{@tab*2}{\n", + "#{@tab*3}return *(Mock.#{function[:name]}_Return_Tail - 1);\n", + "#{@tab*2}}\n" + ] + end + lines << [ "#{@tab}}\n" ] + lines.flatten end def mock_interfaces(function) @@ -42,7 +60,7 @@ class CMockGeneratorPluginIgnore [ "void #{function[:name]}_IgnoreAndReturn(#{function[:return_string]})\n", "{\n", "#{@tab}Mock.#{function[:name]}_IgnoreBool = (unsigned char)1;\n", - @utils.code_insert_item_into_expect_array(function[:return_type], "Mock.#{function[:name]}_Return_Head", CMOCK_RETURN_PARAM_NAME), + @utils.code_insert_item_into_expect_array(function[:return_type], "Mock.#{function[:name]}_Return_Head", 'toReturn'), "#{@tab}Mock.#{function[:name]}_Return = Mock.#{function[:name]}_Return_Head;\n", "#{@tab}Mock.#{function[:name]}_Return += Mock.#{function[:name]}_CallCount;\n", "}\n\n" ] diff --git a/lib/cmock_generator_utils.rb b/lib/cmock_generator_utils.rb index aac79be..890b107 100644 --- a/lib/cmock_generator_utils.rb +++ b/lib/cmock_generator_utils.rb @@ -96,18 +96,18 @@ class CMockGeneratorUtils return "#{indent}#{unity_func}(#{expected}, #{actual}#{unity_msg});\n" end end - + def code_handle_return_value(function, indent) [ "\n", "#{indent}if (Mock.#{function[:name]}_Return != Mock.#{function[:name]}_Return_Tail)\n", "#{indent}{\n", - "#{indent}#{@tab}#{function[:return_type]} #{CMOCK_RETURN_PARAM_NAME} = *Mock.#{function[:name]}_Return;\n", + "#{indent}#{@tab}#{function[:return_type]} toReturn = *Mock.#{function[:name]}_Return;\n", "#{indent}#{@tab}Mock.#{function[:name]}_Return++;\n", - "#{indent}#{@tab}return #{CMOCK_RETURN_PARAM_NAME};\n", + "#{indent}#{@tab}return toReturn;\n", "#{indent}}\n", "#{indent}else\n", "#{indent}{\n", - "#{indent}#{@tab}return *Mock.#{function[:name]}_Return_Head;\n", + "#{indent}#{@tab}return *(Mock.#{function[:name]}_Return_Tail - 1);\n", "#{indent}}\n" ] end end \ No newline at end of file diff --git a/test/system/test_interactions/basic_expect_and_return.yml b/test/system/test_interactions/basic_expect_and_return.yml index 790ec8a..ecd6b2c 100644 --- a/test/system/test_interactions/basic_expect_and_return.yml +++ b/test/system/test_interactions/basic_expect_and_return.yml @@ -91,5 +91,33 @@ foo_char_strings_ExpectAndReturn("larry", "curly", "moe"); TEST_ASSERT_EQUAL_STRING("moe", function_d("larry", "curly")); } + + - :pass: TRUE + :should: 'successfully exercise multiple cycles of expecting and mocking and pass' + :code: | + test() + { + foo_ExpectAndReturn((custom_type)1, 10); + bar_ExpectAndReturn((custom_type)2, 20); + TEST_ASSERT_EQUAL(30, function_a(1, 2)); + + foo_ExpectAndReturn((custom_type)3, 30); + bar_ExpectAndReturn((custom_type)4, 40); + TEST_ASSERT_EQUAL(70, function_a(3, 4)); + } + + - :pass: FALSE + :should: 'successfully exercise multiple cycles of expecting and mocking and fail' + :code: | + test() + { + foo_ExpectAndReturn((custom_type)1, 10); + bar_ExpectAndReturn((custom_type)2, 20); + TEST_ASSERT_EQUAL(30, function_a(1, 2)); + + foo_ExpectAndReturn((custom_type)3, 30); + bar_ExpectAndReturn((custom_type)4, 40); + TEST_ASSERT_EQUAL(70, function_a(3, 5)); + } ... diff --git a/test/system/test_interactions/enforce_strict_ordering.yml b/test/system/test_interactions/enforce_strict_ordering.yml index ed48a1e..d344112 100644 --- a/test/system/test_interactions/enforce_strict_ordering.yml +++ b/test/system/test_interactions/enforce_strict_ordering.yml @@ -90,7 +90,7 @@ - :pass: FALSE :should: 'fail because bar() is called but is not expected' - :verify_error: 'Called More Times Than Expected' + :verify_error: 'called more times than expected' :code: | test() { @@ -112,7 +112,7 @@ - :pass: FALSE :should: 'fail because bar and foo called in reverse order' - :verify_error: 'Called Out Of Order' + :verify_error: 'Out of order function calls' :code: | test() { @@ -207,4 +207,41 @@ foo_ExpectAndReturn((custom_type)3, 10); function_d(); } + + - :pass: TRUE + :should: 'successfully handle back to back ExpectAndReturn setup and mock calls' + :code: | + test() + { + foo_ExpectAndReturn((custom_type)1, 10); + bar_ExpectAndReturn((custom_type)2, 20); + TEST_ASSERT_EQUAL(30, function_a(1, 2)); + + foo_ExpectAndReturn((custom_type)3, 30); + bar_ExpectAndReturn((custom_type)4, 40); + TEST_ASSERT_EQUAL(70, function_a(3, 4)); + + foo_ExpectAndReturn((custom_type)1, 50); + bar_ExpectAndReturn((custom_type)9, 60); + TEST_ASSERT_EQUAL(110, function_a(1, 9)); + } + + - :pass: FALSE + :should: 'successfully catch errors during back to back ExpectAndReturn setup and mock calls' + :verify_error: 'Out of order function calls' + :code: | + test() + { + foo_ExpectAndReturn((custom_type)1, 10); + bar_ExpectAndReturn((custom_type)2, 20); + TEST_ASSERT_EQUAL(30, function_a(1, 2)); + + foo_ExpectAndReturn((custom_type)3, 30); + bar_ExpectAndReturn((custom_type)4, 40); + TEST_ASSERT_EQUAL(70, function_a(3, 4)); + + bar_ExpectAndReturn((custom_type)9, 60); + foo_ExpectAndReturn((custom_type)1, 50); + TEST_ASSERT_EQUAL(110, function_a(1, 9)); + } ... diff --git a/test/system/test_interactions/expect_and_throw.yml b/test/system/test_interactions/expect_and_throw.yml index 6b55350..f1d6f42 100644 --- a/test/system/test_interactions/expect_and_throw.yml +++ b/test/system/test_interactions/expect_and_throw.yml @@ -76,11 +76,13 @@ test() { foo_ExpectAndReturn((custom_type)1, 10); - foo_ExpectAndReturn((custom_type)1, 20); - foo_ExpectAndThrow((custom_type)1, 15); + foo_ExpectAndReturn((custom_type)2, 20); + foo_ExpectAndThrow((custom_type)3, 15); + foo_ExpectAndReturn((custom_type)4, 40); TEST_ASSERT_EQUAL(10, function_a(1)); - TEST_ASSERT_EQUAL(20, function_a(1)); - TEST_ASSERT_EQUAL(30, function_a(1)); + TEST_ASSERT_EQUAL(20, function_a(2)); + TEST_ASSERT_EQUAL(30, function_a(3)); + TEST_ASSERT_EQUAL(40, function_a(4)); } - :pass: TRUE @@ -115,5 +117,54 @@ TEST_ASSERT_EQUAL(3, e); } } + + - :pass: TRUE + :should: 'successfully throw an error on consecutive calls' + :code: | + test() + { + foo_ExpectAndReturn((custom_type)1, 10); + foo_ExpectAndReturn((custom_type)1, 20); + foo_ExpectAndThrow((custom_type)1, 15); + foo_ExpectAndThrow((custom_type)3, 40); + TEST_ASSERT_EQUAL(10, function_a(1)); + TEST_ASSERT_EQUAL(20, function_a(1)); + TEST_ASSERT_EQUAL(30, function_a(1)); + TEST_ASSERT_EQUAL(80, function_a(3)); + } + + - :pass: TRUE + :should: 'successfully throw an error on later calls and after a previous mock call' + :code: | + test() + { + foo_ExpectAndReturn((custom_type)1, 10); + foo_ExpectAndReturn((custom_type)1, 20); + foo_ExpectAndThrow((custom_type)1, 15); + TEST_ASSERT_EQUAL(10, function_a(1)); + TEST_ASSERT_EQUAL(20, function_a(1)); + TEST_ASSERT_EQUAL(30, function_a(1)); + + foo_ExpectAndReturn((custom_type)2, 20); + foo_ExpectAndThrow((custom_type)3, 40); + TEST_ASSERT_EQUAL(20, function_a(2)); + TEST_ASSERT_EQUAL(80, function_a(3)); + } + + - :pass: TRUE + :should: 'successfully throw an error if expects and mocks called before it' + :code: | + test() + { + foo_ExpectAndReturn((custom_type)1, 10); + foo_ExpectAndReturn((custom_type)1, 20); + TEST_ASSERT_EQUAL(10, function_a(1)); + TEST_ASSERT_EQUAL(20, function_a(1)); + + foo_ExpectAndReturn((custom_type)2, 20); + foo_ExpectAndThrow((custom_type)3, 40); + TEST_ASSERT_EQUAL(20, function_a(2)); + TEST_ASSERT_EQUAL(80, function_a(3)); + } ... diff --git a/test/system/test_interactions/ignore_and_return.yml b/test/system/test_interactions/ignore_and_return.yml index d53426f..281efd0 100644 --- a/test/system/test_interactions/ignore_and_return.yml +++ b/test/system/test_interactions/ignore_and_return.yml @@ -12,12 +12,12 @@ :source: :header: | - int function(int a, int b); + int function(int a, int b, int c); :code: | - int function(int a, int b) + int function(int a, int b, int c) { bar(b); - return foo(a) + foo(b); + return foo(a) + foo(b) + foo(c); } :tests: @@ -33,7 +33,8 @@ bar_Expect(2); foo_ExpectAndReturn(1, 10); foo_ExpectAndReturn(2, 20); - TEST_ASSERT_EQUAL(30, function(1, 2)); + foo_ExpectAndReturn(3, 30); + TEST_ASSERT_EQUAL(60, function(1, 2, 3)); } - :pass: TRUE @@ -43,7 +44,30 @@ { bar_Expect(4); foo_IgnoreAndReturn(10); - TEST_ASSERT_EQUAL(20, function(3, 4)); + foo_IgnoreAndReturn(40); + foo_IgnoreAndReturn(80); + TEST_ASSERT_EQUAL(130, function(3, 4, 3)); + } + + - :pass: TRUE + :should: 'ignore foo() calls and always return last item if we run out' + :code: | + test() + { + bar_Expect(4); + foo_IgnoreAndReturn(20); + foo_IgnoreAndReturn(30); + TEST_ASSERT_EQUAL(80, function(3, 4, 9)); + } + + - :pass: TRUE + :should: 'ignore foo() calls and always return only item if only one specified' + :code: | + test() + { + bar_Expect(4); + foo_IgnoreAndReturn(20); + TEST_ASSERT_EQUAL(60, function(3, 4, 9)); } - :pass: TRUE @@ -53,7 +77,77 @@ { bar_Ignore(); foo_IgnoreAndReturn(50); - TEST_ASSERT_EQUAL(100, function(0, 0)); + TEST_ASSERT_EQUAL(150, function(0, 0, 0)); + } + + - :pass: TRUE + :should: 'ignore foo() calls over multiple mock calls' + :code: | + test() + { + bar_Ignore(); + foo_IgnoreAndReturn(50); + foo_IgnoreAndReturn(60); + foo_IgnoreAndReturn(70); + TEST_ASSERT_EQUAL(180, function(0, 0, 0)); + + bar_Ignore(); + foo_IgnoreAndReturn(30); + foo_IgnoreAndReturn(80); + foo_IgnoreAndReturn(10); + TEST_ASSERT_EQUAL(120, function(0, 0, 0)); + + foo_IgnoreAndReturn(70); + foo_IgnoreAndReturn(20); + TEST_ASSERT_EQUAL(110, function(0, 0, 0)); + } + + - :pass: TRUE + :should: 'multiple cycles of expects still pass when ignores enabled' + :code: | + test() + { + bar_Expect(2); + foo_ExpectAndReturn(1, 50); + foo_ExpectAndReturn(2, 60); + foo_ExpectAndReturn(3, 70); + TEST_ASSERT_EQUAL(180, function(1, 2, 3)); + + bar_Expect(5); + foo_ExpectAndReturn(4, 30); + foo_ExpectAndReturn(5, 80); + foo_ExpectAndReturn(6, 10); + TEST_ASSERT_EQUAL(120, function(4, 5, 6)); + + bar_Expect(8); + foo_ExpectAndReturn(7, 70); + foo_ExpectAndReturn(8, 20); + foo_ExpectAndReturn(9, 20); + TEST_ASSERT_EQUAL(110, function(7, 8, 9)); + } + + - :pass: FALSE + :should: 'multiple cycles of expects still fail when ignores enabled' + :code: | + test() + { + bar_Expect(2); + foo_ExpectAndReturn(1, 50); + foo_ExpectAndReturn(2, 60); + foo_ExpectAndReturn(3, 70); + TEST_ASSERT_EQUAL(180, function(1, 2, 3)); + + bar_Expect(5); + foo_ExpectAndReturn(4, 30); + foo_ExpectAndReturn(5, 80); + foo_ExpectAndReturn(6, 10); + TEST_ASSERT_EQUAL(120, function(4, 5, 6)); + + bar_Expect(8); + foo_ExpectAndReturn(7, 70); + foo_ExpectAndReturn(8, 20); + foo_ExpectAndReturn(9, 20); + TEST_ASSERT_EQUAL(110, function(0, 8, 9)); } ... diff --git a/test/unit/cmock_function_prototype_parser_test.rb b/test/unit/cmock_function_prototype_parser_test.rb index 6e59dbe..8f22ac4 100644 --- a/test/unit/cmock_function_prototype_parser_test.rb +++ b/test/unit/cmock_function_prototype_parser_test.rb @@ -194,19 +194,19 @@ class CMockFunctionPrototypeParserTest < Test::Unit::TestCase parsed = @parser.parse("void * foo_bar(void)") assert_equal('void*', parsed.get_return_type) - assert_equal("void* #{CMOCK_RETURN_PARAM_NAME}", parsed.get_return_type_with_name) + assert_equal("void* toReturn", parsed.get_return_type_with_name) parsed = @parser.parse("unsigned int foo_bar(void)") assert_equal('unsigned int', parsed.get_return_type) - assert_equal("unsigned int #{CMOCK_RETURN_PARAM_NAME}", parsed.get_return_type_with_name) + assert_equal("unsigned int toReturn", parsed.get_return_type_with_name) parsed = @parser.parse("unsigned long int foo_bar(void)") assert_equal('unsigned long int', parsed.get_return_type) - assert_equal("unsigned long int #{CMOCK_RETURN_PARAM_NAME}", parsed.get_return_type_with_name) + assert_equal("unsigned long int toReturn", parsed.get_return_type_with_name) parsed = @parser.parse("CUSTOM_TYPE foo_bar(void)") assert_equal('CUSTOM_TYPE', parsed.get_return_type) - assert_equal("CUSTOM_TYPE #{CMOCK_RETURN_PARAM_NAME}", parsed.get_return_type_with_name) + assert_equal("CUSTOM_TYPE toReturn", parsed.get_return_type_with_name) end @@ -285,17 +285,17 @@ class CMockFunctionPrototypeParserTest < Test::Unit::TestCase parsed = @parser.parse("float (*func(const char opCode))(float, float)") assert_equal('float (*func( const char opCode ))( float, float )', parsed.get_declaration) assert_equal('FUNC_PTR_FUNC_RETURN_T', parsed.get_return_type) - assert_equal("float (*#{CMOCK_RETURN_PARAM_NAME})( float, float )", parsed.get_return_type_with_name) + assert_equal("float (*toReturn)( float, float )", parsed.get_return_type_with_name) parsed = @parser.parse("void (* func (void))(void)") assert_equal('void (*func(void))(void)', parsed.get_declaration) assert_equal('FUNC_PTR_FUNC_RETURN_T', parsed.get_return_type) - assert_equal("void (*#{CMOCK_RETURN_PARAM_NAME})(void)", parsed.get_return_type_with_name) + assert_equal("void (*toReturn)(void)", parsed.get_return_type_with_name) parsed = @parser.parse("unsigned int * (* func(double foo, THING bar))(unsigned int)") assert_equal('unsigned int* (*func( double foo, THING bar ))( unsigned int )', parsed.get_declaration) assert_equal('FUNC_PTR_FUNC_RETURN_T', parsed.get_return_type) - assert_equal("unsigned int* (*#{CMOCK_RETURN_PARAM_NAME})( unsigned int )", parsed.get_return_type_with_name) + assert_equal("unsigned int* (*toReturn)( unsigned int )", parsed.get_return_type_with_name) end diff --git a/test/unit/cmock_generator_plugin_cexception_test.rb b/test/unit/cmock_generator_plugin_cexception_test.rb index ee7f55c..8b7f784 100644 --- a/test/unit/cmock_generator_plugin_cexception_test.rb +++ b/test/unit/cmock_generator_plugin_cexception_test.rb @@ -104,11 +104,14 @@ class CMockGeneratorPluginCExceptionTest < Test::Unit::TestCase "{\n", "mock_retval_0", "mock_return_1", - " Mock.Pear_ThrowOnCallCount = Mock.Pear_ThrowOnCallCount_Head;\n", - " Mock.Pear_ThrowOnCallCount += Mock.Pear_CallCount;\n", "mock_return_2", " Mock.Pear_ThrowValue = Mock.Pear_ThrowValue_Head;\n", - " Mock.Pear_ThrowValue += Mock.Pear_CallCount;\n", + " Mock.Pear_ThrowOnCallCount = Mock.Pear_ThrowOnCallCount_Head;\n", + " while ((*Mock.Pear_ThrowOnCallCount <= Mock.Pear_CallCount) && (Mock.Pear_ThrowOnCallCount < Mock.Pear_ThrowOnCallCount_Tail))\n", + " {\n", + " Mock.Pear_ThrowValue++;\n", + " Mock.Pear_ThrowOnCallCount++;\n", + " }\n", "}\n\n" ] returned = @cmock_generator_plugin_cexception.mock_interfaces(function) @@ -128,11 +131,14 @@ class CMockGeneratorPluginCExceptionTest < Test::Unit::TestCase "{\n", "mock_retval_0", "mock_return_1", - " Mock.Pear_ThrowOnCallCount = Mock.Pear_ThrowOnCallCount_Head;\n", - " Mock.Pear_ThrowOnCallCount += Mock.Pear_CallCount;\n", "mock_return_2", " Mock.Pear_ThrowValue = Mock.Pear_ThrowValue_Head;\n", - " Mock.Pear_ThrowValue += Mock.Pear_CallCount;\n", + " Mock.Pear_ThrowOnCallCount = Mock.Pear_ThrowOnCallCount_Head;\n", + " while ((*Mock.Pear_ThrowOnCallCount <= Mock.Pear_CallCount) && (Mock.Pear_ThrowOnCallCount < Mock.Pear_ThrowOnCallCount_Tail))\n", + " {\n", + " Mock.Pear_ThrowValue++;\n", + " Mock.Pear_ThrowOnCallCount++;\n", + " }\n", " ExpectParameters_Pear(mock_return_3);\n", "}\n\n" ] @@ -149,15 +155,17 @@ class CMockGeneratorPluginCExceptionTest < Test::Unit::TestCase expected = [" if(Mock.Banana_ThrowOnCallCount_Head)\n", " {\n", " free(Mock.Banana_ThrowOnCallCount_Head);\n", - " Mock.Banana_ThrowOnCallCount_Head=NULL;\n", - " Mock.Banana_ThrowOnCallCount_Tail=NULL;\n", " }\n", + " Mock.Banana_ThrowOnCallCount=NULL;\n", + " Mock.Banana_ThrowOnCallCount_Head=NULL;\n", + " Mock.Banana_ThrowOnCallCount_Tail=NULL;\n", " if(Mock.Banana_ThrowValue_Head)\n", " {\n", " free(Mock.Banana_ThrowValue_Head);\n", - " Mock.Banana_ThrowValue_Head=NULL;\n", - " Mock.Banana_ThrowValue_Tail=NULL;\n", - " }\n" + " }\n", + " Mock.Banana_ThrowValue=NULL;\n", + " Mock.Banana_ThrowValue_Head=NULL;\n", + " Mock.Banana_ThrowValue_Tail=NULL;\n" ] returned = @cmock_generator_plugin_cexception.mock_destroy(function) assert_equal(expected, returned) diff --git a/test/unit/cmock_generator_plugin_expect_test.rb b/test/unit/cmock_generator_plugin_expect_test.rb index fa5f534..7de01cf 100644 --- a/test/unit/cmock_generator_plugin_expect_test.rb +++ b/test/unit/cmock_generator_plugin_expect_test.rb @@ -122,7 +122,7 @@ class CMockGeneratorPluginExpectTest < Test::Unit::TestCase end should "add mock function declaration for functions of style 'int func(void)'" do - function = {:name => "Spruce", :args_string => "void", :return_string => "int #{CMOCK_RETURN_PARAM_NAME}"} + function = {:name => "Spruce", :args_string => "void", :return_string => "int toReturn"} expected = ["void #{function[:name]}_ExpectAndReturn(#{function[:return_string]});\n"] returned = @cmock_generator_plugin_expect.mock_function_declarations(function) @@ -130,7 +130,7 @@ class CMockGeneratorPluginExpectTest < Test::Unit::TestCase end should "add mock function declaration for functions of style 'const char* func(int tofu)'" do - function = {:name => "Pine", :args_string => "int tofu", :return_string => "const char* #{CMOCK_RETURN_PARAM_NAME}"} + function = {:name => "Pine", :args_string => "int tofu", :return_string => "const char* toReturn"} expected = ["void #{function[:name]}_ExpectAndReturn(#{function[:args_string]}, #{function[:return_string]});\n"] returned = @cmock_generator_plugin_expect.mock_function_declarations(function) @@ -146,7 +146,7 @@ class CMockGeneratorPluginExpectTest < Test::Unit::TestCase expected = [" Mock.Apple_CallCount++;\n", " if (Mock.Apple_CallCount > Mock.Apple_CallsExpected)\n", " {\n", - " TEST_FAIL(\"Apple Called More Times Than Expected\");\n", + " TEST_FAIL(\"Function 'Apple' called more times than expected\");\n", " }\n" ] returned = @cmock_generator_plugin_expect.mock_implementation(function) @@ -162,7 +162,7 @@ class CMockGeneratorPluginExpectTest < Test::Unit::TestCase expected = [" Mock.Cherry_CallCount++;\n", " if (Mock.Cherry_CallCount > Mock.Cherry_CallsExpected)\n", " {\n", - " TEST_FAIL(\"Cherry Called More Times Than Expected\");\n", + " TEST_FAIL(\"Function 'Cherry' called more times than expected\");\n", " }\n", "mocked_retval_1", "mocked_retval_2" @@ -176,7 +176,7 @@ class CMockGeneratorPluginExpectTest < Test::Unit::TestCase expected = [" Mock.Apple_CallCount++;\n", " if (Mock.Apple_CallCount > Mock.Apple_CallsExpected)\n", " {\n", - " TEST_FAIL(\"Apple Called More Times Than Expected\");\n", + " TEST_FAIL(\"Function 'Apple' called more times than expected\");\n", " }\n", " {\n", " int* p_expected = Mock.Apple_CallOrder;\n", @@ -185,8 +185,8 @@ class CMockGeneratorPluginExpectTest < Test::Unit::TestCase " Mock.Apple_CallOrder++;\n", " if ((*p_expected != GlobalVerifyOrder) && (GlobalOrderError == NULL))\n", " {\n", - " const char* ErrStr = \"Function 'Apple' Called Out Of Order.\";\n", - " GlobalOrderError = malloc(38);\n", + " const char* ErrStr = \"Out of order function calls. Function 'Apple'\";\n", + " GlobalOrderError = malloc(46);\n", " if (GlobalOrderError)\n", " strcpy(GlobalOrderError, ErrStr);\n", " }\n", @@ -202,7 +202,7 @@ class CMockGeneratorPluginExpectTest < Test::Unit::TestCase expected = [" Mock.Apple_CallCount++;\n", " if (Mock.Apple_CallCount > Mock.Apple_CallsExpected)\n", " {\n", - " TEST_FAIL(\"Apple Called More Times Than Expected\");\n", + " TEST_FAIL(\"Function 'Apple' called more times than expected\");\n", " }\n", " {\n", " int* p_expected = Mock.Apple_CallOrder;\n", @@ -211,8 +211,8 @@ class CMockGeneratorPluginExpectTest < Test::Unit::TestCase " Mock.Apple_CallOrder++;\n", " if ((*p_expected != GlobalVerifyOrder) && (GlobalOrderError == NULL))\n", " {\n", - " const char* ErrStr = \"Function 'Apple' Called Out Of Order.\";\n", - " GlobalOrderError = malloc(38);\n", + " const char* ErrStr = \"Out of order function calls. Function 'Apple'\";\n", + " GlobalOrderError = malloc(46);\n", " if (GlobalOrderError)\n", " strcpy(GlobalOrderError, ErrStr);\n", " }\n", @@ -235,11 +235,11 @@ class CMockGeneratorPluginExpectTest < Test::Unit::TestCase end should "add mock interfaces for functions of style 'unsigned short func(void)'" do - function = {:name => "Orange", :args => [], :args_string => "void", :return_type => "unsigned short", :return_string => "unsigned short #{CMOCK_RETURN_PARAM_NAME}"} + function = {:name => "Orange", :args => [], :args_string => "void", :return_type => "unsigned short", :return_string => "unsigned short toReturn"} @utils.expect.code_add_base_expectation("Orange").returns("mock_retval_0") @utils.expect.code_insert_item_into_expect_array(function[:return_type], "Mock.Orange_Return_Head","toReturn").returns("mock_retval_1") - expected = ["void Orange_ExpectAndReturn(unsigned short #{CMOCK_RETURN_PARAM_NAME})\n", + expected = ["void Orange_ExpectAndReturn(unsigned short toReturn)\n", "{\n", "mock_retval_0", "mock_retval_1", @@ -252,17 +252,17 @@ class CMockGeneratorPluginExpectTest < Test::Unit::TestCase end 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", :return_type => "int", :return_string => "int #{CMOCK_RETURN_PARAM_NAME}"} + function = {:name => "Lemon", :args => [{ :type => "char*", :name => "pescado"}], :args_string => "char* pescado", :return_type => "int", :return_string => "int toReturn"} @utils.expect.code_add_an_arg_expectation(function, "char*", "pescado").returns("mock_retval_2") @utils.expect.code_add_base_expectation("Lemon").returns("mock_retval_0") @utils.expect.create_call_list(function).returns("mock_retval_3") - @utils.expect.code_insert_item_into_expect_array(function[:return_type], "Mock.Lemon_Return_Head", CMOCK_RETURN_PARAM_NAME).returns("mock_retval_1") + @utils.expect.code_insert_item_into_expect_array(function[:return_type], "Mock.Lemon_Return_Head", 'toReturn').returns("mock_retval_1") expected = ["void ExpectParameters_Lemon(char* pescado)\n", "{\n", "mock_retval_2", "}\n\n", - "void Lemon_ExpectAndReturn(char* pescado, int #{CMOCK_RETURN_PARAM_NAME})\n", + "void Lemon_ExpectAndReturn(char* pescado, int toReturn)\n", "{\n", "mock_retval_0", " ExpectParameters_Lemon(mock_retval_3);\n", @@ -308,9 +308,10 @@ class CMockGeneratorPluginExpectTest < Test::Unit::TestCase expected = [" if (Mock.Palm_Return_Head)\n", " {\n", " free(Mock.Palm_Return_Head);\n", - " Mock.Palm_Return_Head=NULL;\n", - " Mock.Palm_Return_Tail=NULL;\n", - " }\n" + " }\n", + " Mock.Palm_Return=NULL;\n", + " Mock.Palm_Return_Head=NULL;\n", + " Mock.Palm_Return_Tail=NULL;\n" ] returned = @cmock_generator_plugin_expect.mock_destroy(function) assert_equal(expected, returned) @@ -321,15 +322,17 @@ class CMockGeneratorPluginExpectTest < Test::Unit::TestCase expected = [" if (Mock.Coconut_Return_Head)\n", " {\n", " free(Mock.Coconut_Return_Head);\n", - " Mock.Coconut_Return_Head=NULL;\n", - " Mock.Coconut_Return_Tail=NULL;\n", " }\n", + " Mock.Coconut_Return=NULL;\n", + " Mock.Coconut_Return_Head=NULL;\n", + " Mock.Coconut_Return_Tail=NULL;\n", " if (Mock.Coconut_Expected_grease_Head)\n", " {\n", " free(Mock.Coconut_Expected_grease_Head);\n", - " Mock.Coconut_Expected_grease_Head=NULL;\n", - " Mock.Coconut_Expected_grease_Tail=NULL;\n", - " }\n" + " }\n", + " Mock.Coconut_Expected_grease=NULL;\n", + " Mock.Coconut_Expected_grease_Head=NULL;\n", + " Mock.Coconut_Expected_grease_Tail=NULL;\n" ] returned = @cmock_generator_plugin_expect.mock_destroy(function) assert_equal(expected, returned) @@ -340,9 +343,11 @@ class CMockGeneratorPluginExpectTest < Test::Unit::TestCase expected = [ " if (Mock.Peach_CallOrder_Head)\n", " {\n", " free(Mock.Peach_CallOrder_Head);\n", - " Mock.Peach_CallOrder_Head=NULL;\n", - " Mock.Peach_CallOrder_Tail=NULL;\n", - " }\n" ] + " }\n", + " Mock.Peach_CallOrder=NULL;\n", + " Mock.Peach_CallOrder_Head=NULL;\n", + " Mock.Peach_CallOrder_Tail=NULL;\n" + ] returned = @cmock_generator_plugin_expect_strict.mock_destroy(function) 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 72aeb47..57bd560 100644 --- a/test/unit/cmock_generator_plugin_ignore_test.rb +++ b/test/unit/cmock_generator_plugin_ignore_test.rb @@ -39,8 +39,8 @@ class CMockGeneratorPluginIgnoreTest < Test::Unit::TestCase end should "handle function declarations for functions that returns something" do - function = {:name => "Fungus", :args_string => "void", :return_type => "const char*", :return_string => "const char* #{CMOCK_RETURN_PARAM_NAME}"} - expected = ["void Fungus_IgnoreAndReturn(const char* #{CMOCK_RETURN_PARAM_NAME});\n"] + function = {:name => "Fungus", :args_string => "void", :return_type => "const char*", :return_string => "const char* toReturn"} + expected = ["void Fungus_IgnoreAndReturn(const char* toReturn);\n"] returned = @cmock_generator_plugin_ignore.mock_function_declarations(function) assert_equal(expected, returned) end @@ -58,11 +58,20 @@ class CMockGeneratorPluginIgnoreTest < Test::Unit::TestCase should "add required code to implementation prefix with return functions" do function = {:name => "Fungus", :args_string => "void", :return_type => "int"} - @utils.expect.code_handle_return_value(function, " ").returns(" mock_return_1") - expected = [" if (Mock.Fungus_IgnoreBool)\n", " {\n", - " mock_return_1", + " if (Mock.Fungus_Return != Mock.Fungus_Return_Tail)\n", + " {\n", + " int toReturn = *Mock.Fungus_Return;\n", + " Mock.Fungus_Return++;\n", + " Mock.Fungus_CallCount++;\n", + " Mock.Fungus_CallsExpected++;\n", + " return toReturn;\n", + " }\n", + " else\n", + " {\n", + " return *(Mock.Fungus_Return_Tail - 1);\n", + " }\n", " }\n" ] returned = @cmock_generator_plugin_ignore.mock_implementation_prefix(function) @@ -85,10 +94,10 @@ class CMockGeneratorPluginIgnoreTest < Test::Unit::TestCase end should "add a new mock interface for ignoring when function has return value" do - function = {:name => "Slime", :args => [], :args_string => "void", :return_type => "uint32", :return_string => "uint32 #{CMOCK_RETURN_PARAM_NAME}"} + function = {:name => "Slime", :args => [], :args_string => "void", :return_type => "uint32", :return_string => "uint32 toReturn"} @utils.expect.code_insert_item_into_expect_array("uint32", "Mock.Slime_Return_Head", "toReturn").returns("mock_return_1") - expected = ["void Slime_IgnoreAndReturn(uint32 #{CMOCK_RETURN_PARAM_NAME})\n", + expected = ["void Slime_IgnoreAndReturn(uint32 toReturn)\n", "{\n", " Mock.Slime_IgnoreBool = (unsigned char)1;\n", "mock_return_1", diff --git a/test/unit/cmock_generator_utils_test.rb b/test/unit/cmock_generator_utils_test.rb index fb625f6..fb4fc4a 100644 --- a/test/unit/cmock_generator_utils_test.rb +++ b/test/unit/cmock_generator_utils_test.rb @@ -94,7 +94,7 @@ class CMockGeneratorUtilsTest < Test::Unit::TestCase "[tab]}\n", "[tab]else\n", "[tab]{\n", - "[tab] return *Mock.Spatula_Return_Head;\n", + "[tab] return *(Mock.Spatula_Return_Tail - 1);\n", "[tab]}\n" ] returned = @cmock_generator_utils.code_handle_return_value(function, indent)