381 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
			
		
		
	
	
			381 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
require 'constants'
 | 
						|
require 'system_wrapper'
 | 
						|
require 'file_path_utils'
 | 
						|
 | 
						|
 | 
						|
DEFAULT_TEST_COMPILER_TOOL = {
 | 
						|
  :executable => FilePathUtils.os_executable_ext('gcc').freeze,
 | 
						|
  :name => 'default_test_compiler'.freeze,
 | 
						|
  :stderr_redirect => StdErrRedirect::NONE.freeze,
 | 
						|
  :background_exec => BackgroundExec::NONE.freeze,
 | 
						|
  :optional => false.freeze,
 | 
						|
  :arguments => [
 | 
						|
    {"-I\"$\"" => 'COLLECTION_PATHS_TEST_SUPPORT_SOURCE_INCLUDE_VENDOR'}.freeze,
 | 
						|
    {"-I\"$\"" => 'COLLECTION_PATHS_TEST_TOOLCHAIN_INCLUDE'}.freeze,
 | 
						|
    {"-D$" => 'COLLECTION_DEFINES_TEST_AND_VENDOR'}.freeze,
 | 
						|
    "-DGNU_COMPILER".freeze,
 | 
						|
    "-c \"${1}\"".freeze,
 | 
						|
    "-o \"${2}\"".freeze,
 | 
						|
    # gcc's list file output options are complex; no use of ${3} parameter in default config    
 | 
						|
    ].freeze
 | 
						|
  }
 | 
						|
 | 
						|
DEFAULT_TEST_LINKER_TOOL = {
 | 
						|
  :executable => FilePathUtils.os_executable_ext('gcc').freeze,
 | 
						|
  :name => 'default_test_linker'.freeze,
 | 
						|
  :stderr_redirect => StdErrRedirect::NONE.freeze,
 | 
						|
  :background_exec => BackgroundExec::NONE.freeze,
 | 
						|
  :optional => false.freeze,
 | 
						|
  :arguments => [
 | 
						|
    "\"${1}\"".freeze,
 | 
						|
    "-o \"${2}\"".freeze,
 | 
						|
    ].freeze
 | 
						|
  }
 | 
						|
  
 | 
						|
DEFAULT_TEST_FIXTURE_TOOL = {
 | 
						|
  :executable => '${1}'.freeze,
 | 
						|
  :name => 'default_test_fixture'.freeze,
 | 
						|
  :stderr_redirect => StdErrRedirect::AUTO.freeze,
 | 
						|
  :background_exec => BackgroundExec::NONE.freeze,
 | 
						|
  :optional => false.freeze,
 | 
						|
  :arguments => [].freeze
 | 
						|
  }
 | 
						|
 | 
						|
 | 
						|
 | 
						|
DEFAULT_TEST_INCLUDES_PREPROCESSOR_TOOL = {
 | 
						|
  :executable => FilePathUtils.os_executable_ext('cpp').freeze,
 | 
						|
  :name => 'default_test_includes_preprocessor'.freeze,
 | 
						|
  :stderr_redirect => StdErrRedirect::NONE.freeze,
 | 
						|
  :background_exec => BackgroundExec::NONE.freeze,
 | 
						|
  :optional => false.freeze,
 | 
						|
  :arguments => [
 | 
						|
    '-MM'.freeze,
 | 
						|
    '-MG'.freeze,
 | 
						|
    # avoid some possibility of deep system lib header file complications by omitting vendor paths
 | 
						|
    # if cpp is run on *nix system, escape spaces in paths; if cpp on windows just use the paths collection as is
 | 
						|
    {"-I\"$\"" => "{SystemWrapper.windows? ? COLLECTION_PATHS_TEST_SUPPORT_SOURCE_INCLUDE : COLLECTION_PATHS_TEST_SUPPORT_SOURCE_INCLUDE.map{|path| path.gsub(\/ \/, \'\\\\ \') }}"}.freeze,
 | 
						|
    {"-D$" => 'COLLECTION_DEFINES_TEST_AND_VENDOR'}.freeze,
 | 
						|
    {"-D$" => 'DEFINES_TEST_PREPROCESS'}.freeze,
 | 
						|
    "-DGNU_PREPROCESSOR".freeze,
 | 
						|
    '-w'.freeze,
 | 
						|
    '-nostdinc'.freeze,
 | 
						|
    "\"${1}\"".freeze
 | 
						|
    ].freeze
 | 
						|
  }
 | 
						|
 | 
						|
DEFAULT_TEST_FILE_PREPROCESSOR_TOOL = {
 | 
						|
  :executable => FilePathUtils.os_executable_ext('gcc').freeze,
 | 
						|
  :name => 'default_test_file_preprocessor'.freeze,
 | 
						|
  :stderr_redirect => StdErrRedirect::NONE.freeze,
 | 
						|
  :background_exec => BackgroundExec::NONE.freeze,
 | 
						|
  :optional => false.freeze,
 | 
						|
  :arguments => [
 | 
						|
    '-E'.freeze,
 | 
						|
    {"-I\"$\"" => 'COLLECTION_PATHS_TEST_SUPPORT_SOURCE_INCLUDE_VENDOR'}.freeze,
 | 
						|
    {"-I\"$\"" => 'COLLECTION_PATHS_TEST_TOOLCHAIN_INCLUDE'}.freeze,
 | 
						|
    {"-D$" => 'COLLECTION_DEFINES_TEST_AND_VENDOR'}.freeze,
 | 
						|
    {"-D$" => 'DEFINES_TEST_PREPROCESS'}.freeze,
 | 
						|
    "-DGNU_PREPROCESSOR".freeze,
 | 
						|
    "\"${1}\"".freeze,
 | 
						|
    "-o \"${2}\"".freeze
 | 
						|
    ].freeze
 | 
						|
  }
 | 
						|
 | 
						|
DEFAULT_TEST_DEPENDENCIES_GENERATOR_TOOL = {
 | 
						|
  :executable => FilePathUtils.os_executable_ext('gcc').freeze,
 | 
						|
  :name => 'default_test_dependencies_generator'.freeze,
 | 
						|
  :stderr_redirect => StdErrRedirect::NONE.freeze,
 | 
						|
  :background_exec => BackgroundExec::NONE.freeze,
 | 
						|
  :optional => false.freeze,
 | 
						|
  :arguments => [
 | 
						|
    {"-I\"$\"" => 'COLLECTION_PATHS_TEST_SUPPORT_SOURCE_INCLUDE_VENDOR'}.freeze,
 | 
						|
    {"-I\"$\"" => 'COLLECTION_PATHS_TEST_TOOLCHAIN_INCLUDE'}.freeze,
 | 
						|
    {"-D$" => 'COLLECTION_DEFINES_TEST_AND_VENDOR'}.freeze, 
 | 
						|
    {"-D$" => 'DEFINES_TEST_PREPROCESS'}.freeze,     
 | 
						|
    "-DGNU_PREPROCESSOR".freeze,
 | 
						|
    "-MT \"${3}\"".freeze,
 | 
						|
    '-MM'.freeze,
 | 
						|
    '-MD'.freeze,
 | 
						|
    '-MG'.freeze,
 | 
						|
    "-MF \"${2}\"".freeze,
 | 
						|
    "-c \"${1}\"".freeze,
 | 
						|
    ].freeze
 | 
						|
  }
 | 
						|
 | 
						|
DEFAULT_RELEASE_DEPENDENCIES_GENERATOR_TOOL = {
 | 
						|
  :executable => FilePathUtils.os_executable_ext('gcc').freeze,
 | 
						|
  :name => 'default_release_dependencies_generator'.freeze,
 | 
						|
  :stderr_redirect => StdErrRedirect::NONE.freeze,
 | 
						|
  :background_exec => BackgroundExec::NONE.freeze,
 | 
						|
  :optional => false.freeze,
 | 
						|
  :arguments => [
 | 
						|
    {"-I\"$\"" => 'COLLECTION_PATHS_SOURCE_INCLUDE_VENDOR'}.freeze,
 | 
						|
    {"-I\"$\"" => 'COLLECTION_PATHS_RELEASE_TOOLCHAIN_INCLUDE'}.freeze,
 | 
						|
    {"-D$" => 'COLLECTION_DEFINES_RELEASE_AND_VENDOR'}.freeze,
 | 
						|
    {"-D$" => 'DEFINES_RELEASE_PREPROCESS'}.freeze,
 | 
						|
    "-DGNU_PREPROCESSOR".freeze,
 | 
						|
    "-MT \"${3}\"".freeze,
 | 
						|
    '-MM'.freeze,
 | 
						|
    '-MD'.freeze,
 | 
						|
    '-MG'.freeze,
 | 
						|
    "-MF \"${2}\"".freeze,
 | 
						|
    "-c \"${1}\"".freeze,
 | 
						|
    ].freeze
 | 
						|
  }
 | 
						|
 | 
						|
 | 
						|
DEFAULT_RELEASE_COMPILER_TOOL = {
 | 
						|
  :executable => FilePathUtils.os_executable_ext('gcc').freeze,
 | 
						|
  :name => 'default_release_compiler'.freeze,
 | 
						|
  :stderr_redirect => StdErrRedirect::NONE.freeze,
 | 
						|
  :background_exec => BackgroundExec::NONE.freeze,
 | 
						|
  :optional => false.freeze,
 | 
						|
  :arguments => [
 | 
						|
    {"-I\"$\"" => 'COLLECTION_PATHS_SOURCE_INCLUDE_VENDOR'}.freeze,
 | 
						|
    {"-I\"$\"" => 'COLLECTION_PATHS_RELEASE_TOOLCHAIN_INCLUDE'}.freeze,
 | 
						|
    {"-D$" => 'COLLECTION_DEFINES_RELEASE_AND_VENDOR'}.freeze,
 | 
						|
    "-DGNU_COMPILER".freeze,
 | 
						|
    "-c \"${1}\"".freeze,
 | 
						|
    "-o \"${2}\"".freeze,
 | 
						|
    # gcc's list file output options are complex; no use of ${3} parameter in default config    
 | 
						|
    ].freeze
 | 
						|
  }
 | 
						|
 | 
						|
DEFAULT_RELEASE_ASSEMBLER_TOOL = {
 | 
						|
  :executable => FilePathUtils.os_executable_ext('as').freeze,
 | 
						|
  :name => 'default_release_assembler'.freeze,
 | 
						|
  :stderr_redirect => StdErrRedirect::NONE.freeze,
 | 
						|
  :background_exec => BackgroundExec::NONE.freeze,
 | 
						|
  :optional => false.freeze,
 | 
						|
  :arguments => [
 | 
						|
    {"-I\"$\"" => 'COLLECTION_PATHS_SOURCE_AND_INCLUDE'}.freeze,
 | 
						|
    "\"${1}\"".freeze,
 | 
						|
    "-o \"${2}\"".freeze,
 | 
						|
    ].freeze
 | 
						|
  }
 | 
						|
 | 
						|
DEFAULT_RELEASE_LINKER_TOOL = {
 | 
						|
  :executable => FilePathUtils.os_executable_ext('gcc').freeze,
 | 
						|
  :name => 'default_release_linker'.freeze,
 | 
						|
  :stderr_redirect => StdErrRedirect::NONE.freeze,
 | 
						|
  :background_exec => BackgroundExec::NONE.freeze,
 | 
						|
  :optional => false.freeze,
 | 
						|
  :arguments => [
 | 
						|
    "\"${1}\"".freeze,
 | 
						|
    "-o \"${2}\"".freeze,
 | 
						|
    ].freeze
 | 
						|
  }
 | 
						|
 | 
						|
  
 | 
						|
DEFAULT_TOOLS_TEST = {
 | 
						|
  :tools => {
 | 
						|
    :test_compiler => DEFAULT_TEST_COMPILER_TOOL,
 | 
						|
    :test_linker   => DEFAULT_TEST_LINKER_TOOL,
 | 
						|
    :test_fixture  => DEFAULT_TEST_FIXTURE_TOOL,
 | 
						|
    }
 | 
						|
  }
 | 
						|
  
 | 
						|
DEFAULT_TOOLS_TEST_PREPROCESSORS = {
 | 
						|
  :tools => {
 | 
						|
    :test_includes_preprocessor => DEFAULT_TEST_INCLUDES_PREPROCESSOR_TOOL,
 | 
						|
    :test_file_preprocessor     => DEFAULT_TEST_FILE_PREPROCESSOR_TOOL,
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
DEFAULT_TOOLS_TEST_DEPENDENCIES = {
 | 
						|
  :tools => {
 | 
						|
    :test_dependencies_generator => DEFAULT_TEST_DEPENDENCIES_GENERATOR_TOOL,
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
 | 
						|
DEFAULT_TOOLS_RELEASE = {
 | 
						|
  :tools => {
 | 
						|
    :release_compiler => DEFAULT_RELEASE_COMPILER_TOOL,
 | 
						|
    :release_linker   => DEFAULT_RELEASE_LINKER_TOOL,
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
DEFAULT_TOOLS_RELEASE_ASSEMBLER = {
 | 
						|
  :tools => {
 | 
						|
    :release_assembler => DEFAULT_RELEASE_ASSEMBLER_TOOL,
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
DEFAULT_TOOLS_RELEASE_DEPENDENCIES = {
 | 
						|
  :tools => {
 | 
						|
    :release_dependencies_generator => DEFAULT_RELEASE_DEPENDENCIES_GENERATOR_TOOL,
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  
 | 
						|
DEFAULT_RELEASE_TARGET_NAME = 'project'
 | 
						|
 | 
						|
DEFAULT_CEEDLING_CONFIG = {
 | 
						|
    :project => {
 | 
						|
      # :build_root must be set by user
 | 
						|
      :use_exceptions => true,
 | 
						|
      :use_mocks => true,
 | 
						|
      :compile_threads => 1,
 | 
						|
      :test_threads => 1,
 | 
						|
      :use_test_preprocessor => false,
 | 
						|
      :use_deep_dependencies => false,
 | 
						|
      :test_file_prefix => 'test_',
 | 
						|
      :options_paths => [],
 | 
						|
      :release_build => false,
 | 
						|
    },
 | 
						|
 | 
						|
    :release_build => {
 | 
						|
      # :output is set while building configuration -- allows smart default system-dependent file extension handling
 | 
						|
      :use_assembly => false,
 | 
						|
      :artifacts => [],
 | 
						|
    },
 | 
						|
 | 
						|
    :paths => {
 | 
						|
      :test => [],   # must be populated by user
 | 
						|
      :source => [], # must be populated by user
 | 
						|
      :support => [],
 | 
						|
      :include => [],
 | 
						|
      :test_toolchain_include => [],
 | 
						|
      :release_toolchain_include => [],
 | 
						|
    },
 | 
						|
    
 | 
						|
    :files => {
 | 
						|
      :test => [],
 | 
						|
      :source => [],
 | 
						|
      :assembly => [],
 | 
						|
      :support => [],
 | 
						|
      :include => [],
 | 
						|
    },
 | 
						|
    
 | 
						|
    # unlike other top-level entries, environment's value is an array to preserve order
 | 
						|
    :environment => [
 | 
						|
      # when evaluated, this provides wider text field for rake task comments
 | 
						|
      {:rake_columns => '120'},
 | 
						|
    ],
 | 
						|
    
 | 
						|
    :defines => {
 | 
						|
      :test => [],
 | 
						|
      :test_preprocess => [],
 | 
						|
      :release => [],
 | 
						|
      :release_preprocess => [],
 | 
						|
    },
 | 
						|
    
 | 
						|
    :flags => {},
 | 
						|
    
 | 
						|
    :extension => {
 | 
						|
      :header => '.h',
 | 
						|
      :source => '.c',
 | 
						|
      :assembly => '.s',
 | 
						|
      :object => '.o',
 | 
						|
      :executable => ( SystemWrapper.windows? ? EXTENSION_WIN_EXE : EXTENSION_NONWIN_EXE ),
 | 
						|
      :map => '.map',
 | 
						|
      :list => '.lst',
 | 
						|
      :testpass => '.pass',
 | 
						|
      :testfail => '.fail',
 | 
						|
      :dependencies => '.d',
 | 
						|
    },
 | 
						|
 | 
						|
    :unity => {
 | 
						|
      :defines => []
 | 
						|
    },
 | 
						|
 | 
						|
    :cmock => {
 | 
						|
      :defines => []
 | 
						|
    },
 | 
						|
 | 
						|
    :cexception => {
 | 
						|
      :defines => []
 | 
						|
    },
 | 
						|
 | 
						|
    :test_runner => {
 | 
						|
      :includes => [],
 | 
						|
      :file_suffix => '_runner',
 | 
						|
    },
 | 
						|
 | 
						|
    # all tools populated while building up config structure
 | 
						|
    :tools => {},
 | 
						|
 | 
						|
    # empty argument lists for default tools
 | 
						|
    # (these can be overridden in project file to add arguments to tools without totally redefining tools)
 | 
						|
    :test_compiler => { :arguments => [] },
 | 
						|
    :test_linker   => { :arguments => [] },
 | 
						|
    :test_fixture  => { 
 | 
						|
      :arguments => [],
 | 
						|
      :link_objects => [], # compiled object files to always be linked in (e.g. cmock.o if using mocks)
 | 
						|
    },
 | 
						|
    :test_includes_preprocessor  => { :arguments => [] },
 | 
						|
    :test_file_preprocessor      => { :arguments => [] },
 | 
						|
    :test_dependencies_generator => { :arguments => [] },
 | 
						|
    :release_compiler  => { :arguments => [] },
 | 
						|
    :release_linker    => { :arguments => [] },
 | 
						|
    :release_assembler => { :arguments => [] },
 | 
						|
    :release_dependencies_generator => { :arguments => [] },
 | 
						|
 | 
						|
    :plugins => {
 | 
						|
      :load_paths => [],
 | 
						|
      :enabled => [],
 | 
						|
    }
 | 
						|
  }.freeze
 | 
						|
 | 
						|
  
 | 
						|
DEFAULT_TESTS_RESULTS_REPORT_TEMPLATE = %q{
 | 
						|
% ignored        = hash[:results][:counts][:ignored]
 | 
						|
% failed         = hash[:results][:counts][:failed]
 | 
						|
% stdout_count   = hash[:results][:counts][:stdout]
 | 
						|
% header_prepend = ((hash[:header].length > 0) ? "#{hash[:header]}: " : '')
 | 
						|
% banner_width   = 25 + header_prepend.length # widest message
 | 
						|
 | 
						|
% if (ignored > 0)
 | 
						|
<%=@ceedling[:plugin_reportinator].generate_banner(header_prepend + 'IGNORED UNIT TEST SUMMARY')%>
 | 
						|
%   hash[:results][:ignores].each do |ignore|
 | 
						|
%     ignore[:collection].each do |item|
 | 
						|
<%=ignore[:source][:path]%><%=File::SEPARATOR%><%=ignore[:source][:file]%>:<%=item[:line]%>:<%=item[:test]%>
 | 
						|
% if (item[:message].length > 0)
 | 
						|
: "<%=item[:message]%>"
 | 
						|
% else
 | 
						|
<%="\n"%>
 | 
						|
% end
 | 
						|
%     end
 | 
						|
%   end
 | 
						|
 | 
						|
% end
 | 
						|
% if (failed > 0)
 | 
						|
<%=@ceedling[:plugin_reportinator].generate_banner(header_prepend + "\e[31m" 'FAILED UNIT TEST SUMMARY')%>
 | 
						|
%   hash[:results][:failures].each do |failure|
 | 
						|
%     failure[:collection].each do |item|
 | 
						|
<%=failure[:source][:path]%><%=File::SEPARATOR%><%=failure[:source][:file]%>:<%=item[:line]%>:<%=item[:test]%>
 | 
						|
% if (item[:message].length > 0)
 | 
						|
: "<%=item[:message]%>"
 | 
						|
% else
 | 
						|
<%="\n"%>
 | 
						|
% end
 | 
						|
%     end
 | 
						|
%   end
 | 
						|
 | 
						|
% end
 | 
						|
% if (stdout_count > 0)
 | 
						|
<%=@ceedling[:plugin_reportinator].generate_banner(header_prepend + 'UNIT TEST OTHER OUTPUT')%>
 | 
						|
%   hash[:results][:stdout].each do |string|
 | 
						|
%     string[:collection].each do |item|
 | 
						|
<%=string[:source][:path]%><%=File::SEPARATOR%><%=string[:source][:file]%>: "<%=item%>"
 | 
						|
%     end
 | 
						|
%   end
 | 
						|
 | 
						|
% end
 | 
						|
% total_string = hash[:results][:counts][:total].to_s
 | 
						|
% format_string = "%#{total_string.length}i"
 | 
						|
<%=@ceedling[:plugin_reportinator].generate_banner(header_prepend + 'OVERALL UNIT TEST SUMMARY')%>
 | 
						|
% if (hash[:results][:counts][:total] > 0)
 | 
						|
TESTED:  <%=hash[:results][:counts][:total].to_s%>
 | 
						|
PASSED:  <%=sprintf(format_string, hash[:results][:counts][:passed])%>
 | 
						|
FAILED:  <%=sprintf(format_string, failed)%>
 | 
						|
IGNORED: <%=sprintf(format_string, ignored)%>
 | 
						|
% else
 | 
						|
 | 
						|
No tests executed.
 | 
						|
% end
 | 
						|
 | 
						|
}
 |