Final assignment for the course "Real Time and Embedded Systems" of THMMY in AUTH university.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

193 lines
5.8 KiB

# ==========================================
# CMock Project - Automatic Mock Generation for C
# Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams
# [Released under MIT License. Please refer to license.txt for details]
# ==========================================
require 'yaml'
SYS_TEST_GEN_ROOT = File.expand_path( File.dirname( __FILE__ ) ) + '/'
GENERATED_PATH = SYS_TEST_GEN_ROOT + 'generated/'
BUILD_PATH = SYS_TEST_GEN_ROOT + 'build/'
CASES_PATH = SYS_TEST_GEN_ROOT + 'cases/'
TYPES_H = 'types.h'
UNITY_H = 'unity.h'
CMOCK_H = 'cmock.h'
UNITY_HELPER_H = 'unity_helper.h'
UNITY_HELPER_C = 'unity_helper.c'
MOCKABLE_H = 'mockable.h'
YAML_EXTENSION = '.yml'
TEST_PREFIX = 'test_'
MOCK_PREFIX = 'mock_'
H_EXTENSION = '.h'
C_EXTENSION = '.c'
class SystemTestGenerator
def generate_files(test_cases)
test_cases.each do |filename|
yaml_hash = YAML.load_file(filename)
name = File.basename(filename, YAML_EXTENSION)
namix = "#{name}_"
generate_cmock_config(yaml_hash, namix)
generate_code(yaml_hash, namix, name)
end
end
private
def generate_cmock_config(yaml_hash, namix)
cmock_yaml = yaml_hash.clone
cmock_yaml.delete(:systest)
cmock = cmock_yaml[:cmock]
cmock[:mock_path] = GENERATED_PATH
cmock[:includes] = (cmock[:includes] || []) + [namix + TYPES_H]
cmock[:mock_prefix] = MOCK_PREFIX
if not yaml_hash[:systest][:unity_helper].nil?
cmock[:includes] << namix + UNITY_HELPER_H
cmock[:unity_helper_path] = GENERATED_PATH + namix + UNITY_HELPER_H
end
File.open(GENERATED_PATH + namix + 'cmock' + YAML_EXTENSION, 'w') do |out|
YAML.dump(cmock_yaml, out)
end
end
def generate_code(yaml_hash, namix, name)
generate_types_file(yaml_hash, namix)
generate_mockable_file(yaml_hash, namix)
generate_unity_helper_files(yaml_hash, namix)
generate_test_file(yaml_hash, namix, name)
generate_source_file(yaml_hash, namix, name)
end
def generate_types_file(yaml_hash, namix)
types = yaml_hash[:systest][:types]
return if types.nil?
write_header_file(GENERATED_PATH + namix + TYPES_H, namix.upcase + 'TYPES_H') do |out|
out.puts(types)
end
end
def generate_mockable_file(yaml_hash, namix)
mockable = yaml_hash[:systest][:mockable]
return if mockable.nil?
write_header_file(GENERATED_PATH + namix + MOCKABLE_H, namix.upcase + 'MOCKABLE_H', [namix + TYPES_H]) do |out|
out.puts(mockable)
end
end
def generate_unity_helper_files(yaml_hash, namix)
unity_helper = yaml_hash[:systest][:unity_helper]
return if unity_helper.nil?
write_header_file(GENERATED_PATH + namix + UNITY_HELPER_H, namix.upcase + 'UNITY_HELPER_H', [namix + TYPES_H]) do |out|
out.puts(unity_helper[:header])
end
write_source_file(GENERATED_PATH + namix + UNITY_HELPER_C, ["unity.h", namix + UNITY_HELPER_H]) do |out|
out.puts(unity_helper[:code])
end
end
def generate_test_file(yaml_hash, namix, name)
tests = yaml_hash[:systest][:tests]
return if tests.nil?
includes = [UNITY_H, CMOCK_H]
includes << [MOCK_PREFIX + namix + MOCKABLE_H]
includes << [name + H_EXTENSION]
write_source_file(GENERATED_PATH + TEST_PREFIX + name + C_EXTENSION, includes.flatten) do |out|
out.puts(tests[:common])
out.puts('')
tests[:units].each_with_index do |test, index|
out.puts('// should ' + test[:should])
out.puts(test[:code].gsub!(/test\(\)/, "void test#{index+1}(void)"))
out.puts('')
end
end
end
def generate_source_file(yaml_hash, namix, name)
source = yaml_hash[:systest][:source]
return if source.nil?
header_file = name + H_EXTENSION
includes = yaml_hash[:systest][:types].nil? ? [] : [(namix + TYPES_H)]
write_header_file(GENERATED_PATH + header_file, name.upcase, includes) do |out|
out.puts(source[:header])
end
includes = []
includes << (namix + TYPES_H) if not yaml_hash[:systest][:types].nil?
includes << (namix + MOCKABLE_H) if not yaml_hash[:systest][:mockable].nil?
includes << header_file
write_source_file(GENERATED_PATH + name + C_EXTENSION, includes.flatten) do |out|
out.puts(source[:code])
end
end
def write_header_file(filename, upcase_name, include_list=[])
File.open(filename, 'w') do |out|
out.puts("#ifndef _#{upcase_name}")
out.puts("#define _#{upcase_name}")
out.puts('')
include_list.each do |include|
out.puts("#include \"#{include}\"")
end
out.puts('')
out.puts("#if defined(__GNUC__) && !defined(__ICC)")
out.puts("#if !defined(__clang__)")
out.puts("#pragma GCC diagnostic ignored \"-Wpragmas\"")
out.puts("#endif")
out.puts('#pragma GCC diagnostic ignored "-Wunknown-pragmas"')
out.puts('#pragma GCC diagnostic ignored "-Wduplicate-decl-specifier"')
out.puts("#endif")
out.puts('')
yield(out)
out.puts('')
out.puts("#endif // _#{upcase_name}")
out.puts('')
end
end
def write_source_file(filename, include_list=[])
File.open(filename, 'w') do |out|
include_list.each do |include|
out.puts("#include \"#{include}\"")
end
out.puts('')
out.puts("#if defined(__GNUC__) && !defined(__ICC)")
out.puts("#if !defined(__clang__)")
out.puts("#pragma GCC diagnostic ignored \"-Wpragmas\"")
out.puts("#endif")
out.puts('#pragma GCC diagnostic ignored "-Wunknown-pragmas"')
out.puts('#pragma GCC diagnostic ignored "-Wduplicate-decl-specifier"')
out.puts("#endif")
out.puts('')
yield(out)
out.puts('')
end
end
end
if ($0 == __FILE__)
SystemTestGenerator.new.generate_files(Dir[CASES_PATH + "*#{YAML_EXTENSION}"])
end