1
0
mirror of https://github.com/ThrowTheSwitch/CMock synced 2025-05-25 02:59:33 -04:00

brought expectations out to a plugin also

git-svn-id: http://cmock.svn.sourceforge.net/svnroot/cmock/trunk@20 bf332499-1b4d-0410-844d-d2d48d5cc64c
This commit is contained in:
mvandervoord 2008-07-19 19:00:44 +00:00
parent 56d13b90f6
commit b1a290ea7a
6 changed files with 173 additions and 182 deletions

@ -26,7 +26,7 @@ class CMockGenerator
create_mock_header_header(file, filename)
create_mock_header_externs(file, parsed_stuff)
parsed_stuff[:functions].each do |function|
create_mock_header_function_declaration(file, function)
@plugins.each { |plugin| file << plugin.mock_function_declarations(function[:name], function[:args_string_without_varargs], function[:rettype]) }
end
create_mock_header_footer(file)
end
@ -42,7 +42,6 @@ class CMockGenerator
create_mock_destroy_function(file, parsed_stuff[:functions])
parsed_stuff[:functions].each do |function|
create_mock_implementation(file, function)
create_mock_function_expectation(file, function)
@plugins.each { |plugin| file << plugin.mock_interfaces( function[:name], function[:args_string_without_varargs], function[:args], function[:rettype]) }
end
end
@ -71,26 +70,6 @@ class CMockGenerator
end
end
def create_mock_header_function_declaration(header, function)
if (function[:args].empty?)
if (function[:rettype] == 'void')
header << "void #{function[:name]}_Expect(void);\n"
else
header << "void #{function[:name]}_ExpectAndReturn(#{function[:rettype]} toReturn);\n"
end
else
if (function[:rettype] == 'void')
header << "void #{function[:name]}_Expect(#{function[:args_string_without_varargs]});\n"
else
header << "void #{function[:name]}_ExpectAndReturn(#{function[:args_string_without_varargs]}, #{function[:rettype]} toReturn);\n"
end
end
@plugins.each { |plugin| header << plugin.mock_function_declarations(function[:name], function[:args_string_without_varargs], function[:rettype]) }
end
def create_mock_header_footer(header)
header << "\n#endif\n"
end
@ -120,25 +99,7 @@ class CMockGenerator
file << "#{@tab}unsigned char allocFailure;\n"
functions.each do |function|
file << "#{@tab}#{@config.call_count_type} #{function[:name]}_CallCount;\n"
file << "#{@tab}#{@config.call_count_type} #{function[:name]}_CallsExpected;\n"
@plugins.each { |plugin| file << plugin.instance_structure( function[:name] ) }
if (function[:rettype] != "void")
file << "#{@tab}#{function[:rettype]} *#{function[:name]}_Return;\n"
file << "#{@tab}#{function[:rettype]} *#{function[:name]}_Return_Head;\n"
file << "#{@tab}#{function[:rettype]} *#{function[:name]}_Return_HeadTail;\n"
end
function[:args].each do |arg|
type = arg[:type].sub(/const/, '').strip
file << "#{@tab}#{type} *#{function[:name]}_Expected_#{arg[:name]};\n"
file << "#{@tab}#{type} *#{function[:name]}_Expected_#{arg[:name]}_Head;\n"
file << "#{@tab}#{type} *#{function[:name]}_Expected_#{arg[:name]}_HeadTail;\n"
end
@plugins.each { |plugin| file << plugin.instance_structure( function[:name], function[:args], function[:rettype] ) }
end
file << "} Mock;\n\n"
end
@ -155,7 +116,7 @@ class CMockGenerator
file << "void #{@mock_name}_Verify(void)\n{\n"
file << "#{@tab}TEST_ASSERT_EQUAL(0, Mock.allocFailure);\n"
functions.each do |function|
file << "#{@tab}TEST_ASSERT_EQUAL_MESSAGE(Mock.#{function[:name]}_CallsExpected, Mock.#{function[:name]}_CallCount, \"Function '#{function[:name]}' called unexpected number of times.\");\n"
@plugins.each { |plugin| file << plugin.mock_verify(function[:name]) }
end
file << "}\n\n"
end
@ -169,46 +130,13 @@ class CMockGenerator
def create_mock_destroy_function(file, functions)
file << "void #{@mock_name}_Destroy(void)\n{\n"
functions.each do |function|
if function[:rettype] != "void"
file << "#{@tab}if(Mock.#{function[:name]}_Return_Head)\n"
file << "#{@tab}{\n"
file << "#{@tab}#{@tab}free(Mock.#{function[:name]}_Return_Head);\n"
file << "#{@tab}#{@tab}Mock.#{function[:name]}_Return_Head=NULL;\n"
file << "#{@tab}#{@tab}Mock.#{function[:name]}_Return_HeadTail=NULL;\n"
file << "#{@tab}}\n"
end
function[:args].each do |arg|
file << "#{@tab}if(Mock.#{function[:name]}_Expected_#{arg[:name]}_Head)\n"
file << "#{@tab}{\n"
file << "#{@tab}#{@tab}free(Mock.#{function[:name]}_Expected_#{arg[:name]}_Head);\n"
file << "#{@tab}#{@tab}Mock.#{function[:name]}_Expected_#{arg[:name]}_Head=NULL;\n"
file << "#{@tab}#{@tab}Mock.#{function[:name]}_Expected_#{arg[:name]}_HeadTail=NULL;\n"
file << "#{@tab}}\n"
end
@plugins.each { |plugin| file << plugin.mock_destroy(function[:name]) }
@plugins.each { |plugin| file << plugin.mock_destroy(function[:name], function[:args], function[:rettype]) }
end
file << "#{@tab}memset(&Mock, 0, sizeof(Mock));\n"
file << "}\n\n"
end
def create_mock_argument_verifier(file, function)
file << "void AssertParameters_#{function[:name]}(#{function[:args_string_without_varargs]})\n{\n"
function[:args].each do |arg|
type = arg[:type].sub(/const/, '').strip
file << make_handle_expected(function, type, arg[:name])
end
file << "}\n\n"
end
def create_mock_implementation(file, function)
newtab = "#{@tab}"
# Create mock argument verifier, if necessary
unless function[:args].empty?
create_mock_argument_verifier(file, function)
end
# create return value combo
if (function[:modifier].empty?)
@ -223,22 +151,7 @@ class CMockGenerator
file << "{\n"
@plugins.each { |plugin| file << plugin.mock_implementation_prefix(function[:name], function[:rettype]) }
file << "#{newtab}Mock.#{function[:name]}_CallCount++;\n"
#create overcall protection
exp = "Mock.#{function[:name]}_CallsExpected"
file << "#{newtab}if (Mock.#{function[:name]}_CallCount > Mock.#{function[:name]}_CallsExpected)\n"
file << "#{newtab}{\n"
file << "#{newtab}#{@tab}TEST_THROW(\"#{function[:name]} Called More Times Than Expected\");\n"
file << "#{newtab}}\n"
# Create call to argument verifier, if necessary
unless function[:args].empty?
file << "#{newtab}AssertParameters_#{function[:name]}(#{@utils.create_call_list(function[:args])});\n"
end
@plugins.each { |plugin| file << plugin.mock_implementation(function[:name]) }
@plugins.each { |plugin| file << plugin.mock_implementation(function[:name], function[:args]) }
# Return expected value, if necessary
if (function[:rettype] != "void")
@ -248,88 +161,4 @@ class CMockGenerator
# Close out the function
file << "}\n\n"
end
def create_mock_function_expectation(file, function)
if (function[:args].empty?)
# Function has void return type with no arguments
if (function[:rettype] == "void")
file << "void #{function[:name]}_Expect(void)\n"
file << "{\n"
file << "#{@tab}Mock.#{function[:name]}_CallsExpected++;\n"
file << "}\n\n"
# Function has non-void return type with no arguments
else
file << "void #{function[:name]}_ExpectAndReturn(#{function[:rettype]} toReturn)\n"
file << "{\n"
file << "#{@tab}Mock.#{function[:name]}_CallsExpected++;\n"
file << @utils.make_expand_array(function[:rettype], "Mock.#{function[:name]}_Return_Head", "toReturn")
file << "#{@tab}Mock.#{function[:name]}_Return = Mock.#{function[:name]}_Return_Head;\n"
file << "#{@tab}Mock.#{function[:name]}_Return += Mock.#{function[:name]}_CallCount;\n"
file << "}\n\n"
end
else
# Create parameter expectation function
file << "void ExpectParameters_#{function[:name]}(#{function[:args_string_without_varargs]})\n"
file << "{\n"
function[:args].each do |arg|
type = arg[:type].sub(/const/, '').strip
file << make_add_new_expected(function, type, arg[:name])
end
file << "}\n\n"
# Function has void return type with arguments
if function[:rettype] == "void"
file << "void #{function[:name]}_Expect(#{function[:args_string_without_varargs]})\n"
file << "{\n"
file << "#{@tab}Mock.#{function[:name]}_CallsExpected++;\n"
file << "#{@tab}ExpectParameters_#{function[:name]}(#{@utils.create_call_list(function[:args])});\n"
file << "}\n\n"
# Function has non-void return type with arguments
else
file << "void #{function[:name]}_ExpectAndReturn(#{function[:args_string_without_varargs]}, #{function[:rettype]} toReturn)\n{\n"
file << "#{@tab}Mock.#{function[:name]}_CallsExpected++;\n"
file << "#{@tab}ExpectParameters_#{function[:name]}(#{@utils.create_call_list(function[:args])});\n"
file << @utils.make_expand_array(function[:rettype], "Mock.#{function[:name]}_Return_Head", "toReturn")
file << "#{@tab}Mock.#{function[:name]}_Return = Mock.#{function[:name]}_Return_Head;\n"
file << "#{@tab}Mock.#{function[:name]}_Return += Mock.#{function[:name]}_CallCount;\n"
file << "}\n\n"
end
end
end
def make_add_new_expected(function, type, expected)
method = function[:name]
array = @utils.make_expand_array(type, "Mock.#{method}_Expected_#{expected}_Head", expected)
array = "#{array}" + "#{@tab}Mock.#{method}_Expected_#{expected} = Mock.#{method}_Expected_#{expected}_Head;\n"
return "#{array}" + "#{@tab}Mock.#{method}_Expected_#{expected} += Mock.#{function[:name]}_CallCount;\n"
end
def make_handle_expected(function, type, actual)
method = function[:name]
if (type == "char*" || type == "const char*")
code_block = <<EOS
#{@tab}if(Mock.#{method}_Expected_#{actual} != Mock.#{method}_Expected_#{actual}_HeadTail)
#{@tab}{
#{@tab}#{@tab}#{type}* p_expected = Mock.#{method}_Expected_#{actual};
#{@tab}#{@tab}Mock.#{method}_Expected_#{actual}++;
#{@tab}#{@tab}TEST_ASSERT_EQUAL_STRING_MESSAGE(*p_expected, #{actual}, \"Function '#{method}' called with unexpected string for parameter '#{actual}'.\");
#{@tab}}
EOS
else
code_block = <<EOS
#{@tab}if(Mock.#{method}_Expected_#{actual} != Mock.#{method}_Expected_#{actual}_HeadTail)
#{@tab}{
#{@tab}#{@tab}#{type}* p_expected = Mock.#{method}_Expected_#{actual};
#{@tab}#{@tab}Mock.#{method}_Expected_#{actual}++;
#{@tab}#{@tab}TEST_ASSERT_EQUAL_MESSAGE(*p_expected, #{actual}, \"Function '#{method}' called with unexpected value for parameter '#{actual}'.\");
#{@tab}}
EOS
end
return code_block
end
end

@ -11,7 +11,7 @@ class CMockGeneratorPluginCException
return "#include \"Exception.h\"\n"
end
def instance_structure(function_name)
def instance_structure(function_name, function_args_as_array, function_return_type)
lines = []
lines << "#{@tab}#{@config.call_count_type} *#{function_name}_ThrowOnCallCount;\n"
lines << "#{@tab}#{@config.call_count_type} *#{function_name}_ThrowOnCallCount_Head;\n"
@ -33,7 +33,7 @@ class CMockGeneratorPluginCException
[]
end
def mock_implementation(function_name)
def mock_implementation(function_name, function_args_as_array)
lines = ["\n"]
lines << "#{@tab}if((Mock.#{function_name}_ThrowOnCallCount != Mock.#{function_name}_ThrowOnCallCount_HeadTail) &&\n"
lines << "#{@tab}#{@tab}(Mock.#{function_name}_ThrowValue != Mock.#{function_name}_ThrowValue_HeadTail))\n"
@ -65,7 +65,11 @@ class CMockGeneratorPluginCException
lines << "}\n\n"
end
def mock_destroy(function_name)
def mock_verify(function_name)
[]
end
def mock_destroy(function_name, function_args_as_array, function_return_type)
lines = []
lines << "#{@tab}if(Mock.#{function_name}_ThrowOnCallCount_Head)\n"
lines << "#{@tab}{\n"

@ -0,0 +1,131 @@
class CMockGeneratorPluginExpect
def initialize(config, utils)
@config = config
@tab = @config.tab
@utils = utils
end
def include_files
[]
end
def instance_structure(function_name, function_args_as_array, function_return_type)
lines = []
lines << "#{@tab}#{@config.call_count_type} #{function_name}_CallCount;\n"
lines << "#{@tab}#{@config.call_count_type} #{function_name}_CallsExpected;\n"
if (function_return_type != "void")
lines << "#{@tab}#{function_return_type} *#{function_name}_Return;\n"
lines << "#{@tab}#{function_return_type} *#{function_name}_Return_Head;\n"
lines << "#{@tab}#{function_return_type} *#{function_name}_Return_HeadTail;\n"
end
function_args_as_array.each do |arg|
type = arg[:type].sub(/const/, '').strip
lines << "#{@tab}#{type} *#{function_name}_Expected_#{arg[:name]};\n"
lines << "#{@tab}#{type} *#{function_name}_Expected_#{arg[:name]}_Head;\n"
lines << "#{@tab}#{type} *#{function_name}_Expected_#{arg[:name]}_HeadTail;\n"
end
lines
end
def mock_function_declarations(function_name, function_args, function_return_type)
if (function_args == "void")
if (function_return_type == 'void')
return "void #{function_name}_Expect(void);\n"
else
return "void #{function_name}_ExpectAndReturn(#{function_return_type} toReturn);\n"
end
else
if (function_return_type == 'void')
return "void #{function_name}_Expect(#{function_args});\n"
else
return "void #{function_name}_ExpectAndReturn(#{function_args}, #{function_return_type} toReturn);\n"
end
end
end
def mock_implementation_prefix(function_name, function_return_type)
[]
end
def mock_implementation(function_name, function_args_as_array)
lines = []
lines << "#{@tab}Mock.#{function_name}_CallCount++;\n"
lines << "#{@tab}if (Mock.#{function_name}_CallCount > Mock.#{function_name}_CallsExpected)\n"
lines << "#{@tab}{\n"
lines << "#{@tab}#{@tab}TEST_THROW(\"#{function_name} Called More Times Than Expected\");\n"
lines << "#{@tab}}\n"
function_args_as_array.each do |arg|
function_return_type = arg[:type].sub(/const/, '').strip
lines << @utils.make_handle_expected(function_name, function_return_type, arg[:name])
end
lines
end
def mock_interfaces(function_name, function_args, function_args_as_array, function_return_type)
lines = []
# Parameter Helper Function
if (function_args != "void")
lines << "void ExpectParameters_#{function_name}(#{function_args})\n"
lines << "{\n"
function_args_as_array.each do |arg|
type = arg[:type].sub(/const/, '').strip
lines << @utils.make_add_new_expected(function_name, type, arg[:name])
end
lines << "}\n\n"
end
#Main Mock Interface
if (function_return_type == "void")
lines << "void #{function_name}_Expect(#{function_args})\n"
else
if (function_args == "void")
lines << "void #{function_name}_ExpectAndReturn(#{function_return_type} toReturn)\n"
else
lines << "void #{function_name}_ExpectAndReturn(#{function_args}, #{function_return_type} toReturn)\n"
end
end
lines << "{\n"
lines << "#{@tab}Mock.#{function_name}_CallsExpected++;\n"
if (function_args != "void")
lines << "#{@tab}ExpectParameters_#{function_name}(#{@utils.create_call_list(function_args_as_array)});\n"
end
if (function_return_type != "void")
lines << @utils.make_expand_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
lines << "}\n\n"
end
def mock_verify(function_name)
return "#{@tab}TEST_ASSERT_EQUAL_MESSAGE(Mock.#{function_name}_CallsExpected, Mock.#{function_name}_CallCount, \"Function '#{function_name}' called unexpected number of times.\");\n"
end
def mock_destroy(function_name, function_args_as_array, function_return_type)
lines = []
if (function_return_type != "void")
lines << "#{@tab}if (Mock.#{function_name}_Return_Head)\n"
lines << "#{@tab}{\n"
lines << "#{@tab}#{@tab}free(Mock.#{function_name}_Return_Head);\n"
lines << "#{@tab}#{@tab}Mock.#{function_name}_Return_Head=NULL;\n"
lines << "#{@tab}#{@tab}Mock.#{function_name}_Return_HeadTail=NULL;\n"
lines << "#{@tab}}\n"
end
function_args_as_array.each do |arg|
lines << "#{@tab}if (Mock.#{function_name}_Expected_#{arg[:name]}_Head)\n"
lines << "#{@tab}{\n"
lines << "#{@tab}#{@tab}free(Mock.#{function_name}_Expected_#{arg[:name]}_Head);\n"
lines << "#{@tab}#{@tab}Mock.#{function_name}_Expected_#{arg[:name]}_Head=NULL;\n"
lines << "#{@tab}#{@tab}Mock.#{function_name}_Expected_#{arg[:name]}_HeadTail=NULL;\n"
lines << "#{@tab}}\n"
end
lines
end
end

@ -11,7 +11,7 @@ class CMockGeneratorPluginIgnore
[]
end
def instance_structure(function_name)
def instance_structure(function_name, function_args_as_array, function_return_type)
return "#{@tab}#{@config.ignore_bool_type} #{function_name}_IgnoreBool;\n"
end
@ -31,7 +31,7 @@ class CMockGeneratorPluginIgnore
lines << "#{@tab}}\n"
end
def mock_implementation(function_name)
def mock_implementation(function_name, function_args_as_array)
[]
end
@ -54,7 +54,11 @@ class CMockGeneratorPluginIgnore
return lines
end
def mock_destroy(function_name)
def mock_verify(function_name)
[]
end
def mock_destroy(function_name, function_args_as_array, function_return_type)
[]
end
end

@ -56,4 +56,25 @@ class CMockGeneratorUtils
lines << "#{indent}#{@tab}return *Mock.#{function_name}_Return_Head;\n"
lines << "#{indent}}\n"
end
def make_add_new_expected(function_name, arg_type, expected)
lines = []
lines << make_expand_array(arg_type, "Mock.#{function_name}_Expected_#{expected}_Head", expected)
lines << "#{@tab}Mock.#{function_name}_Expected_#{expected} = Mock.#{function_name}_Expected_#{expected}_Head;\n"
lines << "#{@tab}Mock.#{function_name}_Expected_#{expected} += Mock.#{function_name}_CallCount;\n"
end
def make_handle_expected(function_name, arg_type, actual)
lines = ["\n"]
lines << "#{@tab}if(Mock.#{function_name}_Expected_#{actual} != Mock.#{function_name}_Expected_#{actual}_HeadTail)\n"
lines << "#{@tab}{\n"
lines << "#{@tab}#{@tab}#{arg_type}* p_expected = Mock.#{function_name}_Expected_#{actual};\n"
lines << "#{@tab}#{@tab}Mock.#{function_name}_Expected_#{actual}++;\n"
if (arg_type == "char*" || arg_type == "const char*")
lines << "#{@tab}#{@tab}TEST_ASSERT_EQUAL_STRING_MESSAGE(*p_expected, #{actual}, \"Function '#{function_name}' called with unexpected string for parameter '#{actual}'.\");\n"
else
lines << "#{@tab}#{@tab}TEST_ASSERT_EQUAL_MESSAGE(*p_expected, #{actual}, \"Function '#{function_name}' called with unexpected value for parameter '#{actual}'.\");\n"
end
lines << "#{@tab}}\n"
end
end

@ -1,4 +1,5 @@
require "#{$here}/cmock_generator_plugin_expect.rb"
require "#{$here}/cmock_generator_plugin_ignore.rb"
require "#{$here}/cmock_generator_plugin_cexception.rb"
@ -11,6 +12,7 @@ class CMockPluginManager
def get_generator_plugins
@plugins = []
@plugins << CMockGeneratorPluginExpect.new( @config, @utils )
@plugins << CMockGeneratorPluginCException.new( @config, @utils ) if @config.use_cexception
@plugins << CMockGeneratorPluginIgnore.new( @config, @utils ) if @config.allow_ignore_mock
return @plugins