mirror of
https://github.com/ThrowTheSwitch/CMock.git
synced 2026-07-31 16:27:49 +00:00
git-svn-id: http://cmock.svn.sourceforge.net/svnroot/cmock/trunk@16 bf332499-1b4d-0410-844d-d2d48d5cc64c
This commit is contained in:
@@ -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
@@ -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
|
||||
|
||||
|
||||
@@ -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
@@ -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}..."
|
||||
|
||||
|
||||
Reference in New Issue
Block a user