git-svn-id: http://cmock.svn.sourceforge.net/svnroot/cmock/trunk@16 bf332499-1b4d-0410-844d-d2d48d5cc64c

This commit is contained in:
mvandervoord
2008-06-15 19:06:26 +00:00
parent 0ac30876ef
commit c2d0eb4641
4 changed files with 94 additions and 107 deletions
+27
View File
@@ -0,0 +1,27 @@
class CMockFileWriter
require 'ftools'
def initialize(config)
@config = config
end
def create_file(filename)
raise "Where's the block of data to create?" unless block_given?
full_file_name_temp = "#{@config.mock_path}/#{filename}.new"
full_file_name_done = "#{@config.mock_path}/#{filename}"
File.open(full_file_name_temp, 'w') do |file|
yield(file, filename)
end
update_file(full_file_name_done, full_file_name_temp)
end
private ###################################
def update_file(dest, src)
File.delete(dest) if (File.exist?(dest))
File.copy(src, dest)
File.delete(src)
end
end
+64 -91
View File
@@ -4,73 +4,37 @@ class CMockGenerator
attr_accessor :module_name
require 'ftools'
def initialize(config, module_name)
def initialize(config, module_name, file_writer)
@config = config
@file_writer = file_writer
@tab = @config.tab
@module_name = module_name
###Most likely going to move again
@src_path = @config.src_path
@mock_path = @config.mock_path
@tab = @config.tab
@throw_type = @config.throw_type
@call_count_type = @config.call_count_type
@ignore_bool = @config.ignore_bool_type
@includes = @config.includes
@use_cexception = @config.use_cexception
@allow_ignore_mock = @config.allow_ignore_mock
@mock_name = "Mock" + @module_name
end
def create_mock(parsed_stuff)
update_vars
create_shortcuts(parsed_stuff)
parsed_stuff[:functions].each do |function|
function[:args_string_without_varargs] = function[:args_string].gsub(/\,[a-zA-Z0-9_\*\s]*\.\.\./,'')
end
create_mock_header_file(parsed_stuff)
create_mock_source_file(parsed_stuff)
end
def create_shortcuts(parsed_stuff)
parsed_stuff[:functions].each do |function|
function[:args_string_without_varargs] = function[:args_string].gsub(/\,[a-zA-Z0-9_\*\s]*\.\.\./,'')
if (function[:modifier].empty?)
function[:mod_and_rettype] = function[:rettype]
else
function[:mod_and_rettype] = function[:modifier] + ' ' + function[:rettype]
end
end
end
def update_vars
@mock_name = "Mock" + @module_name
@mock_header_name_dest = @mock_name + ".h"
@mock_imp_name_dest = @mock_name + ".c"
@mock_header_temp = @mock_name + ".h.new"
@mock_imp_temp = @mock_name + ".c.new"
@mock_header_file_path = "#{@mock_path}/#{@mock_header_name_dest}"
@mock_imp_file_path = "#{@mock_path}/#{@mock_imp_name_dest}"
end
def update_file(dest, src)
File.delete(dest) if (File.exist?(dest))
File.copy(src, dest)
File.delete(src)
end
def create_mock_header_file(parsed_stuff)
File.open(@mock_header_temp, 'w') do |header|
create_mock_header_header(header, @mock_header_name_dest.gsub(/\.h/, "_h").upcase)
create_mock_header_externs(header, parsed_stuff)
@file_writer.create_file(@mock_name + ".h") do |file, filename|
create_mock_header_header(file, filename)
create_mock_header_externs(file, parsed_stuff)
parsed_stuff[:functions].each do |function|
create_mock_header_function_declaration(header, function)
create_mock_header_function_declaration(file, function)
end
create_mock_header_footer(header)
create_mock_header_footer(file)
end
update_file(@mock_header_file_path, @mock_header_temp)
end
def create_mock_source_file(parsed_stuff)
File.open(@mock_imp_temp, 'w') do |file|
create_source_header_section(file, parsed_stuff[:includes])
@file_writer.create_file(@mock_name + ".c") do |file, filename|
create_source_header_section(file, filename, parsed_stuff[:includes])
create_instance_structure(file, parsed_stuff[:functions])
create_extern_declarations(file, parsed_stuff[:externs])
create_mock_verify_function(file, parsed_stuff[:functions])
@@ -79,23 +43,24 @@ class CMockGenerator
parsed_stuff[:functions].each do |function|
create_mock_implementation(file, function)
create_mock_function_expectation(file, function)
create_mock_function_expectation_with_throw(file, function) if (@use_cexception)
create_mock_function_ignore(file, function) if (@allow_ignore_mock)
create_mock_function_expectation_with_throw(file, function) if (@config.use_cexception)
create_mock_function_ignore(file, function) if (@config.allow_ignore_mock)
end
end
update_file(@mock_imp_file_path, @mock_imp_temp)
end
private ##############################
def create_mock_header_header(header, define_name)
header << "/* AUTOGENERATED FILE. DO NOT EDIT. */\n"
header << "#ifndef _#{define_name}\n"
header << "#define _#{define_name}\n\n"
header << "#include \"#{@mock_header_name_dest.gsub(/^Mock/, "")}\"\n\n"
header << "void #{@mock_name}_Init(void);\n"
header << "void #{@mock_name}_Destroy(void);\n"
header << "void #{@mock_name}_Verify(void);\n\n"
def create_mock_header_header(file, filename)
define_name = filename.gsub(/\.h/, "_h").upcase
orig_filename = filename.gsub("Mock", "")
file << "/* AUTOGENERATED FILE. DO NOT EDIT. */\n"
file << "#ifndef _#{define_name}\n"
file << "#define _#{define_name}\n\n"
file << "#include \"#{orig_filename}\"\n\n"
file << "void #{@mock_name}_Init(void);\n"
file << "void #{@mock_name}_Destroy(void);\n"
file << "void #{@mock_name}_Verify(void);\n\n"
end
def create_mock_header_externs(header, parsed_stuff)
@@ -123,7 +88,7 @@ class CMockGenerator
end
end
if (@use_cexception)
if (@config.use_cexception)
if (function[:args].empty?)
header << "void #{function[:name]}_ExpectAndThrow(int toThrow);\n"
else
@@ -131,7 +96,7 @@ class CMockGenerator
end
end
if (@allow_ignore_mock)
if (@config.allow_ignore_mock)
if (function[:args].empty?)
header << "void #{function[:name]}_Ignore(void);\n"
else
@@ -144,17 +109,18 @@ class CMockGenerator
header << "\n#endif\n"
end
def create_source_header_section(file, include_files)
def create_source_header_section(file, filename, include_files)
header_file = filename.gsub(".c",".h")
file << "/* AUTOGENERATED FILE. DO NOT EDIT. */\n"
file << "#include <string.h>\n"
file << "#include <stdlib.h>\n"
file << "#include <setjmp.h>\n"
file << "#include \"unity.h\"\n"
file << "#include \"Exception.h\"\n" if (@use_cexception) ####MSV : REMOVE ME
file << "#include \"Exception.h\"\n" if (@config.use_cexception) ####MSV : REMOVE ME
#(@includes + include_files).uniq.each {|include| file << "#include \"#{include}\"\n"} #### MSV This is what the comments said in original version, but it wasnt actually doing this
@includes.each {|include| file << "#include \"#{include}\"\n"}
file << "#include \"#{@mock_header_name_dest}\"\n\n"
#(@config.includes + include_files).uniq.each {|include| file << "#include \"#{include}\"\n"} #### MSV This is what the comments said in original version, but it wasnt actually doing this
@config.includes.each {|include| file << "#include \"#{include}\"\n"}
file << "#include \"#{header_file}\"\n\n"
end
def create_instance_structure(file, functions)
@@ -169,19 +135,19 @@ class CMockGenerator
functions.each do |function|
file << "#{@tab}#{@call_count_type} #{function[:name]}_CallCount;\n"
file << "#{@tab}#{@call_count_type} #{function[:name]}_CallsExpected;\n"
file << "#{@tab}#{@config.call_count_type} #{function[:name]}_CallCount;\n"
file << "#{@tab}#{@config.call_count_type} #{function[:name]}_CallsExpected;\n"
if (@allow_ignore_mock)
file << "#{@tab}#{@ignore_bool} #{function[:name]}_IgnoreBool;\n"
if (@config.allow_ignore_mock)
file << "#{@tab}#{@config.ignore_bool_type} #{function[:name]}_IgnoreBool;\n"
end
file << "#{@tab}#{@call_count_type} *#{function[:name]}_ThrowOnCallCount;\n"
file << "#{@tab}#{@call_count_type} *#{function[:name]}_ThrowOnCallCount_Head;\n"
file << "#{@tab}#{@call_count_type} *#{function[:name]}_ThrowOnCallCount_HeadTail;\n"
file << "#{@tab}#{@throw_type} *#{function[:name]}_ThrowValue;\n"
file << "#{@tab}#{@throw_type} *#{function[:name]}_ThrowValue_Head;\n"
file << "#{@tab}#{@throw_type} *#{function[:name]}_ThrowValue_HeadTail;\n"
file << "#{@tab}#{@config.call_count_type} *#{function[:name]}_ThrowOnCallCount;\n"
file << "#{@tab}#{@config.call_count_type} *#{function[:name]}_ThrowOnCallCount_Head;\n"
file << "#{@tab}#{@config.call_count_type} *#{function[:name]}_ThrowOnCallCount_HeadTail;\n"
file << "#{@tab}#{@config.throw_type} *#{function[:name]}_ThrowValue;\n"
file << "#{@tab}#{@config.throw_type} *#{function[:name]}_ThrowValue_Head;\n"
file << "#{@tab}#{@config.throw_type} *#{function[:name]}_ThrowValue_HeadTail;\n"
if (function[:rettype] != "void")
file << "#{@tab}#{function[:rettype]} *#{function[:name]}_Return;\n"
@@ -277,14 +243,21 @@ class CMockGenerator
unless function[:args].empty?
create_mock_argument_verifier(file, function)
end
# create return value combo
if (function[:modifier].empty?)
function_mod_and_rettype = function[:rettype]
else
function_mod_and_rettype = function[:modifier] + ' ' + function[:rettype]
end
# Create mock function
file << "#{function[:attributes]} " if (!function[:attributes].nil? && function[:attributes].length > 0)
file << "#{function[:mod_and_rettype]} #{function[:name]}(#{function[:args_string]})\n"
file << "#{function_mod_and_rettype} #{function[:name]}(#{function[:args_string]})\n"
file << "{\n"
# start ignore block
if (@allow_ignore_mock)
if (@config.allow_ignore_mock)
newtab = "#{@tab}#{@tab}"
file << "#{@tab}if (!Mock.#{function[:name]}_IgnoreBool)\n"
file << "#{@tab}{\n"
@@ -305,10 +278,10 @@ class CMockGenerator
end
# Throw exception, if appropriate
file << make_handle_throw(function, @throw_type) if (@use_cexception)
file << make_handle_throw(function, @config.throw_type) if (@config.use_cexception)
# end ignore block
if (@allow_ignore_mock)
if (@config.allow_ignore_mock)
file << "#{@tab}}\n"
end
@@ -374,24 +347,24 @@ class CMockGenerator
# function takes no arguments
if (function[:args].empty?)
file << "void #{function[:name]}_ExpectAndThrow(#{@throw_type} toThrow)\n"
file << "void #{function[:name]}_ExpectAndThrow(#{@config.throw_type} toThrow)\n"
file << "{\n"
file << "#{@tab}Mock.#{function[:name]}_CallsExpected++;\n"
file << make_expand_array(@call_count_type, "Mock.#{function[:name]}_ThrowOnCallCount_Head", "Mock.#{function[:name]}_CallsExpected")
file << make_expand_array(@config.call_count_type, "Mock.#{function[:name]}_ThrowOnCallCount_Head", "Mock.#{function[:name]}_CallsExpected")
file << "#{@tab}Mock.#{function[:name]}_ThrowOnCallCount = Mock.#{function[:name]}_ThrowOnCallCount_Head;\n"
file << "#{@tab}Mock.#{function[:name]}_ThrowOnCallCount += Mock.#{function[:name]}_CallCount;\n"
file << make_expand_array(@throw_type, "Mock.#{function[:name]}_ThrowValue_Head", "toThrow")
file << make_expand_array(@config.throw_type, "Mock.#{function[:name]}_ThrowValue_Head", "toThrow")
file << "#{@tab}Mock.#{function[:name]}_ThrowValue = Mock.#{function[:name]}_ThrowValue_Head;\n"
file << "#{@tab}Mock.#{function[:name]}_ThrowValue += Mock.#{function[:name]}_CallCount;\n"
file << "}\n\n"
else
file << "void #{function[:name]}_ExpectAndThrow(#{function[:args_string_without_varargs]}, #{@throw_type} toThrow)\n"
file << "void #{function[:name]}_ExpectAndThrow(#{function[:args_string_without_varargs]}, #{@config.throw_type} toThrow)\n"
file << "{\n"
file << "#{@tab}Mock.#{function[:name]}_CallsExpected++;\n"
file << make_expand_array(@call_count_type, "Mock.#{function[:name]}_ThrowOnCallCount_Head", "Mock.#{function[:name]}_CallsExpected")
file << make_expand_array(@config.call_count_type, "Mock.#{function[:name]}_ThrowOnCallCount_Head", "Mock.#{function[:name]}_CallsExpected")
file << "#{@tab}Mock.#{function[:name]}_ThrowOnCallCount = Mock.#{function[:name]}_ThrowOnCallCount_Head;\n"
file << "#{@tab}Mock.#{function[:name]}_ThrowOnCallCount += Mock.#{function[:name]}_CallCount;\n"
file << make_expand_array(@throw_type, "Mock.#{function[:name]}_ThrowValue_Head", "toThrow")
file << make_expand_array(@config.throw_type, "Mock.#{function[:name]}_ThrowValue_Head", "toThrow")
file << "#{@tab}Mock.#{function[:name]}_ThrowValue = Mock.#{function[:name]}_ThrowValue_Head;\n"
file << "#{@tab}Mock.#{function[:name]}_ThrowValue += Mock.#{function[:name]}_CallCount;\n"
file << "#{@tab}ExpectParameters_#{function[:name]}(#{create_call_list(function[:args])});\n"
@@ -462,7 +435,7 @@ EOS
newtab = "#{@tab}"
method = function[:name]
if (@allow_ignore_mock)
if (@config.allow_ignore_mock)
newtab = "#{@tab}#{@tab}"
end
-15
View File
@@ -1,15 +0,0 @@
class CMock
attr_accessor :mocks_path, :includes, :interface_parser
def initialize(mocks_path='mocks', includes=[], interface_parser=nil)
@mocks_path = mocks_path
@includes = includes
@interface_parser = interface_parser
end
def generate(module_header)
@interface_parser.extract_interface(module_header)
end
end
+3 -1
View File
@@ -1,6 +1,7 @@
$here = File.dirname __FILE__
require "#{$here}/cmock_header_parser"
require "#{$here}/cmock_generator"
require "#{$here}/cmock_file_writer"
require "#{$here}/cmock_config"
class CMockSetup
@@ -28,7 +29,8 @@ class CMockSetup
cmc = CMockConfig.new(path, @mocks_path, @includes, @use_cexception, @allow_ignore_mock)
cmp = CMockHeaderParser.new(File.read(src))
cmg = CMockGenerator.new(cmc, name)
cmf = CMockFileWriter.new(cmc)
cmg = CMockGenerator.new(cmc, name, cmf)
puts "Creating mock for #{name}..."