esp32-s2_dfu/test/vendor/ceedling/plugins/fake_function_framework/lib/fff_mock_generator.rb

164 lines
4.9 KiB
Ruby

# Creates mock files from parsed header files that can be linked into applications.
# The mocks created are compatible with CMock for use with Ceedling.
class FffMockGenerator
def self.create_mock_header(module_name, mock_name, parsed_header, pre_includes=nil,
post_includes=nil)
output = StringIO.new
write_opening_include_guard(mock_name, output)
output.puts
write_extra_includes(pre_includes, output)
write_header_includes(module_name, output)
write_extra_includes(post_includes, output)
output.puts
write_typedefs(parsed_header, output)
output.puts
write_function_declarations(parsed_header, output)
output.puts
write_control_function_prototypes(mock_name, output)
output.puts
write_closing_include_guard(mock_name, output)
output.string
end
def self.create_mock_source (mock_name, parsed_header, pre_includes=nil,
post_includes=nil)
output = StringIO.new
write_extra_includes(pre_includes, output)
write_source_includes(mock_name, output)
write_extra_includes(post_includes, output)
output.puts
write_function_definitions(parsed_header, output)
output.puts
write_control_function_definitions(mock_name, parsed_header, output)
output.string
end
private
# Header file generation functions.
def self.write_opening_include_guard(mock_name, output)
output.puts "#ifndef #{mock_name}_H"
output.puts "#define #{mock_name}_H"
end
def self.write_header_includes(module_name, output)
output.puts %{#include "fff.h"}
output.puts %{#include "fff_unity_helper.h"}
output.puts %{#include "#{module_name}.h"}
end
def self.write_typedefs(parsed_header, output)
return unless parsed_header.key?(:typedefs)
parsed_header[:typedefs].each do |typedef|
output.puts typedef
end
end
def self.write_function_declarations(parsed_header, output)
write_function_macros("DECLARE", parsed_header, output)
end
def self.write_control_function_prototypes(mock_name, output)
output.puts "void #{mock_name}_Init(void);"
output.puts "void #{mock_name}_Verify(void);"
output.puts "void #{mock_name}_Destroy(void);"
end
def self.write_closing_include_guard(mock_name, output)
output.puts "#endif // #{mock_name}_H"
end
# Source file generation functions.
def self.write_source_includes (mock_name, output)
output.puts "#include <string.h>"
output.puts %{#include "fff.h"}
output.puts %{#include "#{mock_name}.h"}
end
def self.write_function_definitions(parsed_header, output)
write_function_macros("DEFINE", parsed_header, output)
end
def self.write_control_function_definitions(mock_name, parsed_header, output)
output.puts "void #{mock_name}_Init(void)"
output.puts "{"
# In the init function, reset the FFF globals. These are used for things
# like the call history.
output.puts " FFF_RESET_HISTORY();"
# Also, reset all of the fakes.
if parsed_header[:functions]
parsed_header[:functions].each do |function|
output.puts " RESET_FAKE(#{function[:name]})"
end
end
output.puts "}"
output.puts "void #{mock_name}_Verify(void)"
output.puts "{"
output.puts "}"
output.puts "void #{mock_name}_Destroy(void)"
output.puts "{"
output.puts "}"
end
# Shared functions.
def self.write_extra_includes(includes, output)
if includes
includes.each {|inc| output.puts "#include #{inc}\n"}
end
end
def self.write_function_macros(macro_type, parsed_header, output)
return unless parsed_header.key?(:functions)
parsed_header[:functions].each do |function|
name = function[:name]
return_type = function[:return][:type]
if function.has_key? :modifier
# Prepend any modifier. If there isn't one, trim any leading whitespace.
return_type = "#{function[:modifier]} #{return_type}".lstrip
end
arg_count = function[:args].size
# Check for variable arguments.
var_arg_suffix = ""
if function[:var_arg]
# If there are are variable arguments, then we need to add this argument
# to the count, update the suffix that will get added to the macro.
arg_count += 1
var_arg_suffix = "_VARARG"
end
# Generate the correct macro.
if return_type == 'void'
output.print "#{macro_type}_FAKE_VOID_FUNC#{arg_count}#{var_arg_suffix}(#{name}"
else
output.print "#{macro_type}_FAKE_VALUE_FUNC#{arg_count}#{var_arg_suffix}(#{return_type}, #{name}"
end
# Append each argument type.
function[:args].each do |arg|
output.print ", "
if arg[:const?]
output.print "const "
end
output.print "#{arg[:type]}"
end
# If this argument list ends with a variable argument, add it here at the end.
if function[:var_arg]
output.print ", ..."
end
# Close the declaration.
output.puts ");"
end
end
end