1# ========================================== 2# Unity Project - A Test Framework for C 3# Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams 4# [Released under MIT License. Please refer to license.txt for details] 5# ========================================== 6 7require 'yaml' 8require 'fileutils' 9require HERE + '../../auto/unity_test_summary' 10require HERE + '../../auto/generate_test_runner' 11require HERE + '../../auto/colour_reporter' 12 13module RakefileHelpers 14 C_EXTENSION = '.c'.freeze 15 16 def load_configuration(config_file) 17 return if $configured 18 19 $cfg_file = HERE + "../../test/targets/#{config_file}" unless config_file =~ /[\\|\/]/ 20 $cfg = YAML.load(File.read($cfg_file)) 21 $colour_output = false unless $cfg['colour'] 22 $configured = true if config_file != DEFAULT_CONFIG_FILE 23 end 24 25 def configure_clean 26 CLEAN.include($cfg['compiler']['build_path'] + '*.*') unless $cfg['compiler']['build_path'].nil? 27 end 28 29 def configure_toolchain(config_file = DEFAULT_CONFIG_FILE) 30 config_file += '.yml' unless config_file =~ /\.yml$/ 31 config_file = config_file unless config_file =~ /[\\|\/]/ 32 load_configuration(config_file) 33 configure_clean 34 end 35 36 def tackit(strings) 37 result = if strings.is_a?(Array) 38 "\"#{strings.join}\"" 39 else 40 strings 41 end 42 result 43 end 44 45 def squash(prefix, items) 46 result = '' 47 items.each { |item| result += " #{prefix}#{tackit(item)}" } 48 result 49 end 50 51 def build_compiler_fields 52 command = tackit($cfg['compiler']['path']) 53 defines = if $cfg['compiler']['defines']['items'].nil? 54 '' 55 else 56 squash($cfg['compiler']['defines']['prefix'], $cfg['compiler']['defines']['items'] + ['UNITY_OUTPUT_CHAR=UnityOutputCharSpy_OutputChar'] + ['UNITY_OUTPUT_CHAR_HEADER_DECLARATION=UnityOutputCharSpy_OutputChar\(int\)']) 57 end 58 options = squash('', $cfg['compiler']['options']) 59 includes = squash($cfg['compiler']['includes']['prefix'], $cfg['compiler']['includes']['items']) 60 includes = includes.gsub(/\\ /, ' ').gsub(/\\\"/, '"').gsub(/\\$/, '') # Remove trailing slashes (for IAR) 61 62 { command: command, defines: defines, options: options, includes: includes } 63 end 64 65 def compile(file, _defines = []) 66 compiler = build_compiler_fields 67 unity_include = $cfg['compiler']['includes']['prefix'] + '../../src' 68 cmd_str = "#{compiler[:command]}#{compiler[:defines]}#{compiler[:options]}#{compiler[:includes]} #{unity_include} #{file} " \ 69 "#{$cfg['compiler']['object_files']['prefix']}#{$cfg['compiler']['object_files']['destination']}" \ 70 "#{File.basename(file, C_EXTENSION)}#{$cfg['compiler']['object_files']['extension']}" 71 72 execute(cmd_str) 73 end 74 75 def build_linker_fields 76 command = tackit($cfg['linker']['path']) 77 options = if $cfg['linker']['options'].nil? 78 '' 79 else 80 squash('', $cfg['linker']['options']) 81 end 82 includes = if $cfg['linker']['includes'].nil? || $cfg['linker']['includes']['items'].nil? 83 '' 84 else 85 squash($cfg['linker']['includes']['prefix'], $cfg['linker']['includes']['items']) 86 end.gsub(/\\ /, ' ').gsub(/\\\"/, '"').gsub(/\\$/, '') # Remove trailing slashes (for IAR) 87 88 { command: command, options: options, includes: includes } 89 end 90 91 def link_it(exe_name, obj_list) 92 linker = build_linker_fields 93 cmd_str = "#{linker[:command]}#{linker[:options]}#{linker[:includes]} " + 94 (obj_list.map { |obj| "#{$cfg['linker']['object_files']['path']}#{obj} " }).join + 95 $cfg['linker']['bin_files']['prefix'] + ' ' + 96 $cfg['linker']['bin_files']['destination'] + 97 exe_name + $cfg['linker']['bin_files']['extension'] 98 execute(cmd_str) 99 end 100 101 def build_simulator_fields 102 return nil if $cfg['simulator'].nil? 103 command = if $cfg['simulator']['path'].nil? 104 '' 105 else 106 (tackit($cfg['simulator']['path']) + ' ') 107 end 108 pre_support = if $cfg['simulator']['pre_support'].nil? 109 '' 110 else 111 squash('', $cfg['simulator']['pre_support']) 112 end 113 post_support = if $cfg['simulator']['post_support'].nil? 114 '' 115 else 116 squash('', $cfg['simulator']['post_support']) 117 end 118 { command: command, pre_support: pre_support, post_support: post_support } 119 end 120 121 def execute(command_string, verbose = true) 122 report command_string 123 output = `#{command_string}`.chomp 124 report(output) if verbose && !output.nil? && !output.empty? 125 raise "Command failed. (Returned #{$?.exitstatus})" if $?.exitstatus != 0 126 output 127 end 128 129 def report_summary 130 summary = UnityTestSummary.new 131 summary.root = HERE 132 results_glob = "#{$cfg['compiler']['build_path']}*.test*" 133 results_glob.tr!('\\', '/') 134 results = Dir[results_glob] 135 summary.targets = results 136 summary.run 137 end 138 139 def run_tests 140 report 'Running Unity system tests...' 141 142 # Tack on TEST define for compiling unit tests 143 load_configuration($cfg_file) 144 test_defines = ['TEST'] 145 $cfg['compiler']['defines']['items'] = [] if $cfg['compiler']['defines']['items'].nil? 146 147 # Get a list of all source files needed 148 src_files = Dir[HERE + 'src/*.c'] 149 src_files += Dir[HERE + 'test/*.c'] 150 src_files += Dir[HERE + 'test/main/*.c'] 151 src_files << '../../src/unity.c' 152 153 # Build object files 154 src_files.each { |f| compile(f, test_defines) } 155 obj_list = src_files.map { |f| File.basename(f.ext($cfg['compiler']['object_files']['extension'])) } 156 157 # Link the test executable 158 test_base = 'framework_test' 159 link_it(test_base, obj_list) 160 161 # Execute unit test and generate results file 162 simulator = build_simulator_fields 163 executable = $cfg['linker']['bin_files']['destination'] + test_base + $cfg['linker']['bin_files']['extension'] 164 cmd_str = if simulator.nil? 165 executable + ' -v -r' 166 else 167 "#{simulator[:command]} #{simulator[:pre_support]} #{executable} #{simulator[:post_support]}" 168 end 169 output = execute(cmd_str) 170 test_results = $cfg['compiler']['build_path'] + test_base 171 test_results += if output.match(/OK$/m).nil? 172 '.testfail' 173 else 174 '.testpass' 175 end 176 File.open(test_results, 'w') { |f| f.print output } 177 end 178end 179