mirror of
https://github.com/DaveGamble/cJSON.git
synced 2023-08-10 21:13:26 +03:00
Update Unity to release 2.4.1
This commit is contained in:
commit
18b4e2f941
@ -12,7 +12,9 @@ matrix:
|
|||||||
before_install:
|
before_install:
|
||||||
- if [ "$TRAVIS_OS_NAME" == "osx" ]; then rvm install 2.1 && rvm use 2.1 && ruby -v; fi
|
- if [ "$TRAVIS_OS_NAME" == "osx" ]; then rvm install 2.1 && rvm use 2.1 && ruby -v; fi
|
||||||
- if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo apt-get install --assume-yes --quiet gcc-multilib; fi
|
- if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo apt-get install --assume-yes --quiet gcc-multilib; fi
|
||||||
install: gem install rspec
|
install:
|
||||||
|
- gem install rspec
|
||||||
|
- gem install rubocop
|
||||||
script:
|
script:
|
||||||
- cd test && rake ci
|
- cd test && rake ci
|
||||||
- make -s
|
- make -s
|
||||||
|
@ -2,7 +2,7 @@ Unity Test API
|
|||||||
==============
|
==============
|
||||||
|
|
||||||
[](https://travis-ci.org/ThrowTheSwitch/Unity)
|
[](https://travis-ci.org/ThrowTheSwitch/Unity)
|
||||||
__Copyright (c) 2007 - 2014 Unity Project by Mike Karlesky, Mark VanderVoord, and Greg Williams__
|
__Copyright (c) 2007 - 2017 Unity Project by Mike Karlesky, Mark VanderVoord, and Greg Williams__
|
||||||
|
|
||||||
Running Tests
|
Running Tests
|
||||||
-------------
|
-------------
|
||||||
@ -109,14 +109,6 @@ Compares two integers for equality and display errors as hexadecimal. Like the
|
|||||||
you can specify the size... here the size will also effect how many nibbles are shown (for example, `HEX16`
|
you can specify the size... here the size will also effect how many nibbles are shown (for example, `HEX16`
|
||||||
will show 4 nibbles).
|
will show 4 nibbles).
|
||||||
|
|
||||||
_ARRAY
|
|
||||||
|
|
||||||
You can append `_ARRAY` to any of these macros to make an array comparison of that type. Here you will
|
|
||||||
need to care a bit more about the actual size of the value being checked. You will also specify an
|
|
||||||
additional argument which is the number of elements to compare. For example:
|
|
||||||
|
|
||||||
TEST_ASSERT_EQUAL_HEX8_ARRAY(expected, actual, elements)
|
|
||||||
|
|
||||||
TEST_ASSERT_EQUAL(expected, actual)
|
TEST_ASSERT_EQUAL(expected, actual)
|
||||||
|
|
||||||
Another way of calling TEST_ASSERT_EQUAL_INT
|
Another way of calling TEST_ASSERT_EQUAL_INT
|
||||||
@ -126,6 +118,23 @@ Another way of calling TEST_ASSERT_EQUAL_INT
|
|||||||
Asserts that the actual value is within plus or minus delta of the expected value. This also comes in
|
Asserts that the actual value is within plus or minus delta of the expected value. This also comes in
|
||||||
size specific variants.
|
size specific variants.
|
||||||
|
|
||||||
|
Arrays
|
||||||
|
------
|
||||||
|
|
||||||
|
_ARRAY
|
||||||
|
|
||||||
|
You can append `_ARRAY` to any of these macros to make an array comparison of that type. Here you will
|
||||||
|
need to care a bit more about the actual size of the value being checked. You will also specify an
|
||||||
|
additional argument which is the number of elements to compare. For example:
|
||||||
|
|
||||||
|
TEST_ASSERT_EQUAL_HEX8_ARRAY(expected, actual, elements)
|
||||||
|
|
||||||
|
_EACH_EQUAL
|
||||||
|
|
||||||
|
Another array comparison option is to check that EVERY element of an array is equal to a single expected
|
||||||
|
value. You do this by specifying the EACH_EQUAL macro. For example:
|
||||||
|
|
||||||
|
TEST_ASSERT_EACH_EQUAL_INT32(expected, actual, elements)
|
||||||
|
|
||||||
Numerical Assertions: Bitwise
|
Numerical Assertions: Bitwise
|
||||||
-----------------------------
|
-----------------------------
|
||||||
|
@ -4,63 +4,62 @@
|
|||||||
# [Released under MIT License. Please refer to license.txt for details]
|
# [Released under MIT License. Please refer to license.txt for details]
|
||||||
# ==========================================
|
# ==========================================
|
||||||
|
|
||||||
if RUBY_PLATFORM =~/(win|w)32$/
|
if RUBY_PLATFORM =~ /(win|w)32$/
|
||||||
begin
|
begin
|
||||||
require 'Win32API'
|
require 'Win32API'
|
||||||
rescue LoadError
|
rescue LoadError
|
||||||
puts "ERROR! \"Win32API\" library not found"
|
puts 'ERROR! "Win32API" library not found'
|
||||||
puts "\"Win32API\" is required for colour on a windows machine"
|
puts '"Win32API" is required for colour on a windows machine'
|
||||||
puts " try => \"gem install Win32API\" on the command line"
|
puts ' try => "gem install Win32API" on the command line'
|
||||||
puts
|
puts
|
||||||
end
|
end
|
||||||
# puts
|
# puts
|
||||||
# puts 'Windows Environment Detected...'
|
# puts 'Windows Environment Detected...'
|
||||||
# puts 'Win32API Library Found.'
|
# puts 'Win32API Library Found.'
|
||||||
# puts
|
# puts
|
||||||
end
|
end
|
||||||
|
|
||||||
class ColourCommandLine
|
class ColourCommandLine
|
||||||
def initialize
|
def initialize
|
||||||
if RUBY_PLATFORM =~/(win|w)32$/
|
return unless RUBY_PLATFORM =~ /(win|w)32$/
|
||||||
get_std_handle = Win32API.new("kernel32", "GetStdHandle", ['L'], 'L')
|
get_std_handle = Win32API.new('kernel32', 'GetStdHandle', ['L'], 'L')
|
||||||
@set_console_txt_attrb =
|
@set_console_txt_attrb =
|
||||||
Win32API.new("kernel32","SetConsoleTextAttribute",['L','N'], 'I')
|
Win32API.new('kernel32', 'SetConsoleTextAttribute', %w(L N), 'I')
|
||||||
@hout = get_std_handle.call(-11)
|
@hout = get_std_handle.call(-11)
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def change_to(new_colour)
|
def change_to(new_colour)
|
||||||
if RUBY_PLATFORM =~/(win|w)32$/
|
if RUBY_PLATFORM =~ /(win|w)32$/
|
||||||
@set_console_txt_attrb.call(@hout,self.win32_colour(new_colour))
|
@set_console_txt_attrb.call(@hout, win32_colour(new_colour))
|
||||||
else
|
else
|
||||||
"\033[30;#{posix_colour(new_colour)};22m"
|
"\033[30;#{posix_colour(new_colour)};22m"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def win32_colour(colour)
|
def win32_colour(colour)
|
||||||
case colour
|
case colour
|
||||||
when :black then 0
|
when :black then 0
|
||||||
when :dark_blue then 1
|
when :dark_blue then 1
|
||||||
when :dark_green then 2
|
when :dark_green then 2
|
||||||
when :dark_cyan then 3
|
when :dark_cyan then 3
|
||||||
when :dark_red then 4
|
when :dark_red then 4
|
||||||
when :dark_purple then 5
|
when :dark_purple then 5
|
||||||
when :dark_yellow, :narrative then 6
|
when :dark_yellow, :narrative then 6
|
||||||
when :default_white, :default, :dark_white then 7
|
when :default_white, :default, :dark_white then 7
|
||||||
when :silver then 8
|
when :silver then 8
|
||||||
when :blue then 9
|
when :blue then 9
|
||||||
when :green, :success then 10
|
when :green, :success then 10
|
||||||
when :cyan, :output then 11
|
when :cyan, :output then 11
|
||||||
when :red, :failure then 12
|
when :red, :failure then 12
|
||||||
when :purple then 13
|
when :purple then 13
|
||||||
when :yellow then 14
|
when :yellow then 14
|
||||||
when :white then 15
|
when :white then 15
|
||||||
else
|
else
|
||||||
0
|
0
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def posix_colour(colour)
|
def posix_colour(colour)
|
||||||
# ANSI Escape Codes - Foreground colors
|
# ANSI Escape Codes - Foreground colors
|
||||||
# | Code | Color |
|
# | Code | Color |
|
||||||
# | 39 | Default foreground color |
|
# | 39 | Default foreground color |
|
||||||
@ -81,35 +80,39 @@ class ColourCommandLine
|
|||||||
# | 96 | Light cyan |
|
# | 96 | Light cyan |
|
||||||
# | 97 | White |
|
# | 97 | White |
|
||||||
|
|
||||||
case colour
|
case colour
|
||||||
when :black then 30
|
when :black then 30
|
||||||
when :red, :failure then 31
|
when :red, :failure then 31
|
||||||
when :green, :success then 32
|
when :green, :success then 32
|
||||||
when :yellow then 33
|
when :yellow then 33
|
||||||
when :blue, :narrative then 34
|
when :blue, :narrative then 34
|
||||||
when :purple, :magenta then 35
|
when :purple, :magenta then 35
|
||||||
when :cyan, :output then 36
|
when :cyan, :output then 36
|
||||||
when :white, :default_white then 37
|
when :white, :default_white then 37
|
||||||
when :default then 39
|
when :default then 39
|
||||||
else
|
else
|
||||||
39
|
39
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def out_c(mode, colour, str)
|
def out_c(mode, colour, str)
|
||||||
case RUBY_PLATFORM
|
case RUBY_PLATFORM
|
||||||
when /(win|w)32$/
|
when /(win|w)32$/
|
||||||
change_to(colour)
|
change_to(colour)
|
||||||
$stdout.puts str if mode == :puts
|
$stdout.puts str if mode == :puts
|
||||||
$stdout.print str if mode == :print
|
$stdout.print str if mode == :print
|
||||||
change_to(:default_white)
|
change_to(:default_white)
|
||||||
else
|
else
|
||||||
$stdout.puts("#{change_to(colour)}#{str}\033[0m") if mode == :puts
|
$stdout.puts("#{change_to(colour)}#{str}\033[0m") if mode == :puts
|
||||||
$stdout.print("#{change_to(colour)}#{str}\033[0m") if mode == :print
|
$stdout.print("#{change_to(colour)}#{str}\033[0m") if mode == :print
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end # ColourCommandLine
|
end # ColourCommandLine
|
||||||
|
|
||||||
def colour_puts(role,str) ColourCommandLine.new.out_c(:puts, role, str) end
|
def colour_puts(role, str)
|
||||||
def colour_print(role,str) ColourCommandLine.new.out_c(:print, role, str) end
|
ColourCommandLine.new.out_c(:puts, role, str)
|
||||||
|
end
|
||||||
|
|
||||||
|
def colour_print(role, str)
|
||||||
|
ColourCommandLine.new.out_c(:print, role, str)
|
||||||
|
end
|
||||||
|
@ -2,38 +2,38 @@
|
|||||||
# Unity Project - A Test Framework for C
|
# Unity Project - A Test Framework for C
|
||||||
# Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams
|
# Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams
|
||||||
# [Released under MIT License. Please refer to license.txt for details]
|
# [Released under MIT License. Please refer to license.txt for details]
|
||||||
# ==========================================
|
# ==========================================
|
||||||
|
|
||||||
require "#{File.expand_path(File.dirname(__FILE__))}/colour_prompt"
|
require "#{File.expand_path(File.dirname(__FILE__))}/colour_prompt"
|
||||||
|
|
||||||
$colour_output = true
|
$colour_output = true
|
||||||
|
|
||||||
def report(message)
|
def report(message)
|
||||||
if not $colour_output
|
if !$colour_output
|
||||||
$stdout.puts(message)
|
$stdout.puts(message)
|
||||||
else
|
else
|
||||||
message = message.join('\n') if (message.class == Array)
|
message = message.join('\n') if message.class == Array
|
||||||
message.each_line do |line|
|
message.each_line do |line|
|
||||||
line.chomp!
|
line.chomp!
|
||||||
colour = case(line)
|
colour = case line
|
||||||
when /(?:total\s+)?tests:?\s+(\d+)\s+(?:total\s+)?failures:?\s+\d+\s+Ignored:?/i
|
when /(?:total\s+)?tests:?\s+(\d+)\s+(?:total\s+)?failures:?\s+\d+\s+Ignored:?/i
|
||||||
($1.to_i == 0) ? :green : :red
|
Regexp.last_match(1).to_i.zero? ? :green : :red
|
||||||
when /PASS/
|
when /PASS/
|
||||||
:green
|
:green
|
||||||
when /^OK$/
|
when /^OK$/
|
||||||
:green
|
:green
|
||||||
when /(?:FAIL|ERROR)/
|
when /(?:FAIL|ERROR)/
|
||||||
:red
|
:red
|
||||||
when /IGNORE/
|
when /IGNORE/
|
||||||
:yellow
|
:yellow
|
||||||
when /^(?:Creating|Compiling|Linking)/
|
when /^(?:Creating|Compiling|Linking)/
|
||||||
:white
|
:white
|
||||||
else
|
else
|
||||||
:silver
|
:silver
|
||||||
end
|
end
|
||||||
colour_puts(colour, line)
|
colour_puts(colour, line)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
$stdout.flush
|
$stdout.flush
|
||||||
$stderr.flush
|
$stderr.flush
|
||||||
end
|
end
|
||||||
|
@ -12,8 +12,8 @@ require 'rubygems'
|
|||||||
require 'fileutils'
|
require 'fileutils'
|
||||||
require 'pathname'
|
require 'pathname'
|
||||||
|
|
||||||
#TEMPLATE_TST
|
# TEMPLATE_TST
|
||||||
TEMPLATE_TST ||= %q[#include "unity.h"
|
TEMPLATE_TST ||= '#include "unity.h"
|
||||||
%2$s#include "%1$s.h"
|
%2$s#include "%1$s.h"
|
||||||
|
|
||||||
void setUp(void)
|
void setUp(void)
|
||||||
@ -28,115 +28,118 @@ void test_%1$s_NeedToImplement(void)
|
|||||||
{
|
{
|
||||||
TEST_IGNORE_MESSAGE("Need to Implement %1$s");
|
TEST_IGNORE_MESSAGE("Need to Implement %1$s");
|
||||||
}
|
}
|
||||||
]
|
'.freeze
|
||||||
|
|
||||||
#TEMPLATE_SRC
|
# TEMPLATE_SRC
|
||||||
TEMPLATE_SRC ||= %q[%2$s#include "%1$s.h"
|
TEMPLATE_SRC ||= '%2$s#include "%1$s.h"
|
||||||
]
|
'.freeze
|
||||||
|
|
||||||
#TEMPLATE_INC
|
# TEMPLATE_INC
|
||||||
TEMPLATE_INC ||= %q[#ifndef _%3$s_H
|
TEMPLATE_INC ||= '#ifndef _%3$s_H
|
||||||
#define _%3$s_H
|
#define _%3$s_H
|
||||||
%2$s
|
%2$s
|
||||||
|
|
||||||
#endif // _%3$s_H
|
#endif // _%3$s_H
|
||||||
]
|
'.freeze
|
||||||
|
|
||||||
class UnityModuleGenerator
|
class UnityModuleGenerator
|
||||||
|
|
||||||
############################
|
############################
|
||||||
def initialize(options=nil)
|
def initialize(options = nil)
|
||||||
|
|
||||||
here = File.expand_path(File.dirname(__FILE__)) + '/'
|
here = File.expand_path(File.dirname(__FILE__)) + '/'
|
||||||
|
|
||||||
@options = UnityModuleGenerator.default_options
|
@options = UnityModuleGenerator.default_options
|
||||||
case(options)
|
case options
|
||||||
when NilClass then @options
|
when NilClass then @options
|
||||||
when String then @options.merge!(UnityModuleGenerator.grab_config(options))
|
when String then @options.merge!(UnityModuleGenerator.grab_config(options))
|
||||||
when Hash then @options.merge!(options)
|
when Hash then @options.merge!(options)
|
||||||
else raise "If you specify arguments, it should be a filename or a hash of options"
|
else raise 'If you specify arguments, it should be a filename or a hash of options'
|
||||||
end
|
end
|
||||||
|
|
||||||
# Create default file paths if none were provided
|
# Create default file paths if none were provided
|
||||||
@options[:path_src] = here + "../src/" if @options[:path_src].nil?
|
@options[:path_src] = here + '../src/' if @options[:path_src].nil?
|
||||||
@options[:path_inc] = @options[:path_src] if @options[:path_inc].nil?
|
@options[:path_inc] = @options[:path_src] if @options[:path_inc].nil?
|
||||||
@options[:path_tst] = here + "../test/" if @options[:path_tst].nil?
|
@options[:path_tst] = here + '../test/' if @options[:path_tst].nil?
|
||||||
@options[:path_src] += '/' unless (@options[:path_src][-1] == 47)
|
@options[:path_src] += '/' unless @options[:path_src][-1] == 47
|
||||||
@options[:path_inc] += '/' unless (@options[:path_inc][-1] == 47)
|
@options[:path_inc] += '/' unless @options[:path_inc][-1] == 47
|
||||||
@options[:path_tst] += '/' unless (@options[:path_tst][-1] == 47)
|
@options[:path_tst] += '/' unless @options[:path_tst][-1] == 47
|
||||||
|
|
||||||
#Built in patterns
|
# Built in patterns
|
||||||
@patterns = { 'src' => {'' => { :inc => [] } },
|
@patterns = {
|
||||||
'test'=> {'' => { :inc => [] } },
|
'src' => {
|
||||||
'dh' => {'Driver' => { :inc => [create_filename('%1$s','Hardware.h')] },
|
'' => { inc: [] }
|
||||||
'Hardware' => { :inc => [] }
|
},
|
||||||
},
|
'test' => {
|
||||||
'dih' => {'Driver' => { :inc => [create_filename('%1$s','Hardware.h'), create_filename('%1$s','Interrupt.h')] },
|
'' => { inc: [] }
|
||||||
'Interrupt'=> { :inc => [create_filename('%1$s','Hardware.h')] },
|
},
|
||||||
'Hardware' => { :inc => [] }
|
'dh' => {
|
||||||
},
|
'Driver' => { inc: [create_filename('%1$s', 'Hardware.h')] },
|
||||||
'mch' => {'Model' => { :inc => [] },
|
'Hardware' => { inc: [] }
|
||||||
'Conductor'=> { :inc => [create_filename('%1$s','Model.h'), create_filename('%1$s','Hardware.h')] },
|
},
|
||||||
'Hardware' => { :inc => [] }
|
'dih' => {
|
||||||
},
|
'Driver' => { inc: [create_filename('%1$s', 'Hardware.h'), create_filename('%1$s', 'Interrupt.h')] },
|
||||||
'mvp' => {'Model' => { :inc => [] },
|
'Interrupt' => { inc: [create_filename('%1$s', 'Hardware.h')] },
|
||||||
'Presenter'=> { :inc => [create_filename('%1$s','Model.h'), create_filename('%1$s','View.h')] },
|
'Hardware' => { inc: [] }
|
||||||
'View' => { :inc => [] }
|
},
|
||||||
}
|
'mch' => {
|
||||||
}
|
'Model' => { inc: [] },
|
||||||
|
'Conductor' => { inc: [create_filename('%1$s', 'Model.h'), create_filename('%1$s', 'Hardware.h')] },
|
||||||
|
'Hardware' => { inc: [] }
|
||||||
|
},
|
||||||
|
'mvp' => {
|
||||||
|
'Model' => { inc: [] },
|
||||||
|
'Presenter' => { inc: [create_filename('%1$s', 'Model.h'), create_filename('%1$s', 'View.h')] },
|
||||||
|
'View' => { inc: [] }
|
||||||
|
}
|
||||||
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
############################
|
############################
|
||||||
def self.default_options
|
def self.default_options
|
||||||
{
|
{
|
||||||
:pattern => "src",
|
pattern: 'src',
|
||||||
:includes =>
|
includes: {
|
||||||
{
|
src: [],
|
||||||
:src => [],
|
inc: [],
|
||||||
:inc => [],
|
tst: []
|
||||||
:tst => [],
|
|
||||||
},
|
},
|
||||||
:update_svn => false,
|
update_svn: false,
|
||||||
:boilerplates => {},
|
boilerplates: {},
|
||||||
:test_prefix => 'Test',
|
test_prefix: 'Test',
|
||||||
:mock_prefix => 'Mock',
|
mock_prefix: 'Mock'
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
############################
|
############################
|
||||||
def self.grab_config(config_file)
|
def self.grab_config(config_file)
|
||||||
options = self.default_options
|
options = default_options
|
||||||
unless (config_file.nil? or config_file.empty?)
|
unless config_file.nil? || config_file.empty?
|
||||||
require 'yaml'
|
require 'yaml'
|
||||||
yaml_guts = YAML.load_file(config_file)
|
yaml_guts = YAML.load_file(config_file)
|
||||||
options.merge!(yaml_guts[:unity] || yaml_guts[:cmock])
|
options.merge!(yaml_guts[:unity] || yaml_guts[:cmock])
|
||||||
raise "No :unity or :cmock section found in #{config_file}" unless options
|
raise "No :unity or :cmock section found in #{config_file}" unless options
|
||||||
end
|
end
|
||||||
return(options)
|
options
|
||||||
end
|
end
|
||||||
|
|
||||||
############################
|
############################
|
||||||
def files_to_operate_on(module_name, pattern=nil)
|
def files_to_operate_on(module_name, pattern = nil)
|
||||||
#strip any leading path information from the module name and save for later
|
# strip any leading path information from the module name and save for later
|
||||||
subfolder = File.dirname(module_name)
|
subfolder = File.dirname(module_name)
|
||||||
module_name = File.basename(module_name)
|
module_name = File.basename(module_name)
|
||||||
|
|
||||||
#create triad definition
|
# create triad definition
|
||||||
prefix = @options[:test_prefix] || 'Test'
|
prefix = @options[:test_prefix] || 'Test'
|
||||||
triad = [ { :ext => '.c', :path => @options[:path_src], :prefix => "", :template => TEMPLATE_SRC, :inc => :src, :boilerplate => @options[:boilerplates][:src] },
|
triad = [{ ext: '.c', path: @options[:path_src], prefix: '', template: TEMPLATE_SRC, inc: :src, boilerplate: @options[:boilerplates][:src] },
|
||||||
{ :ext => '.h', :path => @options[:path_inc], :prefix => "", :template => TEMPLATE_INC, :inc => :inc, :boilerplate => @options[:boilerplates][:inc] },
|
{ ext: '.h', path: @options[:path_inc], prefix: '', template: TEMPLATE_INC, inc: :inc, boilerplate: @options[:boilerplates][:inc] },
|
||||||
{ :ext => '.c', :path => @options[:path_tst], :prefix => prefix, :template => TEMPLATE_TST, :inc => :tst, :boilerplate => @options[:boilerplates][:tst] },
|
{ ext: '.c', path: @options[:path_tst], prefix: prefix, template: TEMPLATE_TST, inc: :tst, boilerplate: @options[:boilerplates][:tst] }]
|
||||||
]
|
|
||||||
|
|
||||||
#prepare the pattern for use
|
# prepare the pattern for use
|
||||||
pattern = (pattern || @options[:pattern] || 'src').downcase
|
pattern = (pattern || @options[:pattern] || 'src').downcase
|
||||||
patterns = @patterns[pattern]
|
patterns = @patterns[pattern]
|
||||||
raise "ERROR: The design pattern '#{pattern}' specified isn't one that I recognize!" if patterns.nil?
|
raise "ERROR: The design pattern '#{pattern}' specified isn't one that I recognize!" if patterns.nil?
|
||||||
|
|
||||||
#single file patterns (currently just 'test') can reject the other parts of the triad
|
# single file patterns (currently just 'test') can reject the other parts of the triad
|
||||||
if (pattern == 'test')
|
triad.select! { |v| v[:inc] == :tst } if pattern == 'test'
|
||||||
triad.reject!{|v| v[:inc] != :tst }
|
|
||||||
end
|
|
||||||
|
|
||||||
# Assemble the path/names of the files we need to work with.
|
# Assemble the path/names of the files we need to work with.
|
||||||
files = []
|
files = []
|
||||||
@ -145,26 +148,26 @@ class UnityModuleGenerator
|
|||||||
submodule_name = create_filename(module_name, pattern_file)
|
submodule_name = create_filename(module_name, pattern_file)
|
||||||
filename = cfg[:prefix] + submodule_name + cfg[:ext]
|
filename = cfg[:prefix] + submodule_name + cfg[:ext]
|
||||||
files << {
|
files << {
|
||||||
:path => (Pathname.new("#{cfg[:path]}#{subfolder}") + filename).cleanpath,
|
path: (Pathname.new("#{cfg[:path]}#{subfolder}") + filename).cleanpath,
|
||||||
:name => submodule_name,
|
name: submodule_name,
|
||||||
:template => cfg[:template],
|
template: cfg[:template],
|
||||||
:boilerplate => cfg[:boilerplate],
|
boilerplate: cfg[:boilerplate],
|
||||||
:includes => case(cfg[:inc])
|
includes: case (cfg[:inc])
|
||||||
when :src then (@options[:includes][:src] || []) | pattern_traits[:inc].map{|f| f % [module_name]}
|
when :src then (@options[:includes][:src] || []) | (pattern_traits[:inc].map { |f| format(f, module_name) })
|
||||||
when :inc then (@options[:includes][:inc] || [])
|
when :inc then (@options[:includes][:inc] || [])
|
||||||
when :tst then (@options[:includes][:tst] || []) | pattern_traits[:inc].map{|f| "#{@options[:mock_prefix]}#{f}" % [module_name]}
|
when :tst then (@options[:includes][:tst] || []) | (pattern_traits[:inc].map { |f| format("#{@options[:mock_prefix]}#{f}", module_name) })
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
return files
|
files
|
||||||
end
|
end
|
||||||
|
|
||||||
############################
|
############################
|
||||||
def create_filename(part1, part2="")
|
def create_filename(part1, part2 = '')
|
||||||
if part2.empty?
|
if part2.empty?
|
||||||
case(@options[:naming])
|
case (@options[:naming])
|
||||||
when 'bumpy' then part1
|
when 'bumpy' then part1
|
||||||
when 'camel' then part1
|
when 'camel' then part1
|
||||||
when 'snake' then part1.downcase
|
when 'snake' then part1.downcase
|
||||||
@ -172,49 +175,45 @@ class UnityModuleGenerator
|
|||||||
else part1.downcase
|
else part1.downcase
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
case(@options[:naming])
|
case (@options[:naming])
|
||||||
when 'bumpy' then part1 + part2
|
when 'bumpy' then part1 + part2
|
||||||
when 'camel' then part1 + part2
|
when 'camel' then part1 + part2
|
||||||
when 'snake' then part1.downcase + "_" + part2.downcase
|
when 'snake' then part1.downcase + '_' + part2.downcase
|
||||||
when 'caps' then part1.upcase + "_" + part2.upcase
|
when 'caps' then part1.upcase + '_' + part2.upcase
|
||||||
else part1.downcase + "_" + part2.downcase
|
else part1.downcase + '_' + part2.downcase
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
############################
|
############################
|
||||||
def generate(module_name, pattern=nil)
|
def generate(module_name, pattern = nil)
|
||||||
|
|
||||||
files = files_to_operate_on(module_name, pattern)
|
files = files_to_operate_on(module_name, pattern)
|
||||||
|
|
||||||
#Abort if all of the module files already exist
|
# Abort if all of the module files already exist
|
||||||
all_files_exist = true
|
all_files_exist = true
|
||||||
files.each do |file|
|
files.each do |file|
|
||||||
if not File.exist?(file[:path])
|
all_files_exist = false unless File.exist?(file[:path])
|
||||||
all_files_exist = false
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
raise "ERROR: File #{files[0][:name]} already exists. Exiting." if all_files_exist
|
raise "ERROR: File #{files[0][:name]} already exists. Exiting." if all_files_exist
|
||||||
|
|
||||||
# Create Source Modules
|
# Create Source Modules
|
||||||
files.each_with_index do |file, i|
|
files.each_with_index do |file, _i|
|
||||||
# If this file already exists, don't overwrite it.
|
# If this file already exists, don't overwrite it.
|
||||||
if File.exist?(file[:path])
|
if File.exist?(file[:path])
|
||||||
puts "File #{file[:path]} already exists!"
|
puts "File #{file[:path]} already exists!"
|
||||||
next
|
next
|
||||||
end
|
end
|
||||||
# Create the path first if necessary.
|
# Create the path first if necessary.
|
||||||
FileUtils.mkdir_p(File.dirname(file[:path]), :verbose => false)
|
FileUtils.mkdir_p(File.dirname(file[:path]), verbose: false)
|
||||||
File.open(file[:path], 'w') do |f|
|
File.open(file[:path], 'w') do |f|
|
||||||
f.write("#{file[:boilerplate]}\n" % [file[:name]]) unless file[:boilerplate].nil?
|
f.write("#{file[:boilerplate]}\n" % [file[:name]]) unless file[:boilerplate].nil?
|
||||||
f.write(file[:template] % [ file[:name],
|
f.write(file[:template] % [file[:name],
|
||||||
file[:includes].map{|f| "#include \"#{f}\"\n"}.join,
|
file[:includes].map { |ff| "#include \"#{ff}\"\n" }.join,
|
||||||
file[:name].upcase ]
|
file[:name].upcase])
|
||||||
)
|
|
||||||
end
|
end
|
||||||
if (@options[:update_svn])
|
if @options[:update_svn]
|
||||||
`svn add \"#{file[:path]}\"`
|
`svn add \"#{file[:path]}\"`
|
||||||
if $?.exitstatus == 0
|
if $!.exitstatus.zero?
|
||||||
puts "File #{file[:path]} created and added to source control"
|
puts "File #{file[:path]} created and added to source control"
|
||||||
else
|
else
|
||||||
puts "File #{file[:path]} created but FAILED adding to source control!"
|
puts "File #{file[:path]} created but FAILED adding to source control!"
|
||||||
@ -227,8 +226,7 @@ class UnityModuleGenerator
|
|||||||
end
|
end
|
||||||
|
|
||||||
############################
|
############################
|
||||||
def destroy(module_name, pattern=nil)
|
def destroy(module_name, pattern = nil)
|
||||||
|
|
||||||
files_to_operate_on(module_name, pattern).each do |filespec|
|
files_to_operate_on(module_name, pattern).each do |filespec|
|
||||||
file = filespec[:path]
|
file = filespec[:path]
|
||||||
if File.exist?(file)
|
if File.exist?(file)
|
||||||
@ -243,66 +241,65 @@ class UnityModuleGenerator
|
|||||||
puts "File #{file} does not exist so cannot be removed."
|
puts "File #{file} does not exist so cannot be removed."
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
puts "Destroy Complete"
|
puts 'Destroy Complete'
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
############################
|
############################
|
||||||
#Handle As Command Line If Called That Way
|
# Handle As Command Line If Called That Way
|
||||||
if ($0 == __FILE__)
|
if $0 == __FILE__
|
||||||
destroy = false
|
destroy = false
|
||||||
options = { }
|
options = {}
|
||||||
module_name = nil
|
module_name = nil
|
||||||
|
|
||||||
# Parse the command line parameters.
|
# Parse the command line parameters.
|
||||||
ARGV.each do |arg|
|
ARGV.each do |arg|
|
||||||
case(arg)
|
case arg
|
||||||
when /^-d/ then destroy = true
|
when /^-d/ then destroy = true
|
||||||
when /^-u/ then options[:update_svn] = true
|
when /^-u/ then options[:update_svn] = true
|
||||||
when /^-p\"?(\w+)\"?/ then options[:pattern] = $1
|
when /^-p\"?(\w+)\"?/ then options[:pattern] = Regexp.last_match(1)
|
||||||
when /^-s\"?(.+)\"?/ then options[:path_src] = $1
|
when /^-s\"?(.+)\"?/ then options[:path_src] = Regexp.last_match(1)
|
||||||
when /^-i\"?(.+)\"?/ then options[:path_inc] = $1
|
when /^-i\"?(.+)\"?/ then options[:path_inc] = Regexp.last_match(1)
|
||||||
when /^-t\"?(.+)\"?/ then options[:path_tst] = $1
|
when /^-t\"?(.+)\"?/ then options[:path_tst] = Regexp.last_match(1)
|
||||||
when /^-n\"?(.+)\"?/ then options[:naming] = $1
|
when /^-n\"?(.+)\"?/ then options[:naming] = Regexp.last_match(1)
|
||||||
when /^-y\"?(.+)\"?/ then options = UnityModuleGenerator.grab_config($1)
|
when /^-y\"?(.+)\"?/ then options = UnityModuleGenerator.grab_config(Regexp.last_match(1))
|
||||||
when /^(\w+)/
|
when /^(\w+)/
|
||||||
raise "ERROR: You can't have more than one Module name specified!" unless module_name.nil?
|
raise "ERROR: You can't have more than one Module name specified!" unless module_name.nil?
|
||||||
module_name = arg
|
module_name = arg
|
||||||
when /^-(h|-help)/
|
when /^-(h|-help)/
|
||||||
ARGV = []
|
ARGV = [].freeze
|
||||||
else
|
else
|
||||||
raise "ERROR: Unknown option specified '#{arg}'"
|
raise "ERROR: Unknown option specified '#{arg}'"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if (!ARGV[0])
|
unless ARGV[0]
|
||||||
puts [ "\nGENERATE MODULE\n-------- ------",
|
puts ["\nGENERATE MODULE\n-------- ------",
|
||||||
"\nUsage: ruby generate_module [options] module_name",
|
"\nUsage: ruby generate_module [options] module_name",
|
||||||
" -i\"include\" sets the path to output headers to 'include' (DEFAULT ../src)",
|
" -i\"include\" sets the path to output headers to 'include' (DEFAULT ../src)",
|
||||||
" -s\"../src\" sets the path to output source to '../src' (DEFAULT ../src)",
|
" -s\"../src\" sets the path to output source to '../src' (DEFAULT ../src)",
|
||||||
" -t\"C:/test\" sets the path to output source to 'C:/test' (DEFAULT ../test)",
|
" -t\"C:/test\" sets the path to output source to 'C:/test' (DEFAULT ../test)",
|
||||||
" -p\"MCH\" sets the output pattern to MCH.",
|
' -p"MCH" sets the output pattern to MCH.',
|
||||||
" dh - driver hardware.",
|
' dh - driver hardware.',
|
||||||
" dih - driver interrupt hardware.",
|
' dih - driver interrupt hardware.',
|
||||||
" mch - model conductor hardware.",
|
' mch - model conductor hardware.',
|
||||||
" mvp - model view presenter.",
|
' mvp - model view presenter.',
|
||||||
" src - just a source module, header and test. (DEFAULT)",
|
' src - just a source module, header and test. (DEFAULT)',
|
||||||
" test - just a test file.",
|
' test - just a test file.',
|
||||||
" -d destroy module instead of creating it.",
|
' -d destroy module instead of creating it.',
|
||||||
" -n\"camel\" sets the file naming convention.",
|
' -n"camel" sets the file naming convention.',
|
||||||
" bumpy - BumpyCaseFilenames.",
|
' bumpy - BumpyCaseFilenames.',
|
||||||
" camel - camelCaseFilenames.",
|
' camel - camelCaseFilenames.',
|
||||||
" snake - snake_case_filenames. (DEFAULT)",
|
' snake - snake_case_filenames. (DEFAULT)',
|
||||||
" caps - CAPS_CASE_FILENAMES.",
|
' caps - CAPS_CASE_FILENAMES.',
|
||||||
" -u update subversion too (requires subversion command line)",
|
' -u update subversion too (requires subversion command line)',
|
||||||
" -y\"my.yml\" selects a different yaml config file for module generation",
|
' -y"my.yml" selects a different yaml config file for module generation',
|
||||||
"" ].join("\n")
|
''].join("\n")
|
||||||
exit
|
exit
|
||||||
end
|
end
|
||||||
|
|
||||||
raise "ERROR: You must have a Module name specified! (use option -h for help)" if module_name.nil?
|
raise 'ERROR: You must have a Module name specified! (use option -h for help)' if module_name.nil?
|
||||||
if (destroy)
|
if destroy
|
||||||
UnityModuleGenerator.new(options).destroy(module_name)
|
UnityModuleGenerator.new(options).destroy(module_name)
|
||||||
else
|
else
|
||||||
UnityModuleGenerator.new(options).generate(module_name)
|
UnityModuleGenerator.new(options).generate(module_name)
|
||||||
|
@ -4,75 +4,70 @@
|
|||||||
# [Released under MIT License. Please refer to license.txt for details]
|
# [Released under MIT License. Please refer to license.txt for details]
|
||||||
# ==========================================
|
# ==========================================
|
||||||
|
|
||||||
$QUICK_RUBY_VERSION = RUBY_VERSION.split('.').inject(0){|vv,v| vv * 100 + v.to_i }
|
File.expand_path(File.join(File.dirname(__FILE__), 'colour_prompt'))
|
||||||
File.expand_path(File.join(File.dirname(__FILE__),'colour_prompt'))
|
|
||||||
|
|
||||||
class UnityTestRunnerGenerator
|
class UnityTestRunnerGenerator
|
||||||
|
|
||||||
def initialize(options = nil)
|
def initialize(options = nil)
|
||||||
@options = UnityTestRunnerGenerator.default_options
|
@options = UnityTestRunnerGenerator.default_options
|
||||||
case(options)
|
case options
|
||||||
when NilClass then @options
|
when NilClass then @options
|
||||||
when String then @options.merge!(UnityTestRunnerGenerator.grab_config(options))
|
when String then @options.merge!(UnityTestRunnerGenerator.grab_config(options))
|
||||||
when Hash then @options.merge!(options)
|
when Hash then @options.merge!(options)
|
||||||
else raise "If you specify arguments, it should be a filename or a hash of options"
|
else raise 'If you specify arguments, it should be a filename or a hash of options'
|
||||||
end
|
end
|
||||||
require "#{File.expand_path(File.dirname(__FILE__))}/type_sanitizer"
|
require "#{File.expand_path(File.dirname(__FILE__))}/type_sanitizer"
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.default_options
|
def self.default_options
|
||||||
{
|
{
|
||||||
:includes => [],
|
includes: [],
|
||||||
:defines => [],
|
defines: [],
|
||||||
:plugins => [],
|
plugins: [],
|
||||||
:framework => :unity,
|
framework: :unity,
|
||||||
:test_prefix => "test|spec|should",
|
test_prefix: 'test|spec|should',
|
||||||
:setup_name => "setUp",
|
mock_prefix: 'Mock',
|
||||||
:teardown_name => "tearDown",
|
setup_name: 'setUp',
|
||||||
:main_name => "main", #set to :auto to automatically generate each time
|
teardown_name: 'tearDown',
|
||||||
:main_export_decl => "",
|
main_name: 'main', # set to :auto to automatically generate each time
|
||||||
:cmdline_args => false,
|
main_export_decl: '',
|
||||||
:use_param_tests => false,
|
cmdline_args: false,
|
||||||
|
use_param_tests: false
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.grab_config(config_file)
|
def self.grab_config(config_file)
|
||||||
options = self.default_options
|
options = default_options
|
||||||
unless (config_file.nil? or config_file.empty?)
|
unless config_file.nil? || config_file.empty?
|
||||||
require 'yaml'
|
require 'yaml'
|
||||||
yaml_guts = YAML.load_file(config_file)
|
yaml_guts = YAML.load_file(config_file)
|
||||||
options.merge!(yaml_guts[:unity] || yaml_guts[:cmock])
|
options.merge!(yaml_guts[:unity] || yaml_guts[:cmock])
|
||||||
raise "No :unity or :cmock section found in #{config_file}" unless options
|
raise "No :unity or :cmock section found in #{config_file}" unless options
|
||||||
end
|
end
|
||||||
return(options)
|
options
|
||||||
end
|
end
|
||||||
|
|
||||||
def run(input_file, output_file, options=nil)
|
def run(input_file, output_file, options = nil)
|
||||||
tests = []
|
|
||||||
testfile_includes = []
|
|
||||||
used_mocks = []
|
|
||||||
|
|
||||||
@options.merge!(options) unless options.nil?
|
@options.merge!(options) unless options.nil?
|
||||||
module_name = File.basename(input_file)
|
|
||||||
|
|
||||||
#pull required data from source file
|
# pull required data from source file
|
||||||
source = File.read(input_file)
|
source = File.read(input_file)
|
||||||
source = source.force_encoding("ISO-8859-1").encode("utf-8", :replace => nil) if ($QUICK_RUBY_VERSION > 10900)
|
source = source.force_encoding('ISO-8859-1').encode('utf-8', replace: nil)
|
||||||
tests = find_tests(source)
|
tests = find_tests(source)
|
||||||
headers = find_includes(source)
|
headers = find_includes(source)
|
||||||
testfile_includes = (headers[:local] + headers[:system])
|
testfile_includes = (headers[:local] + headers[:system])
|
||||||
used_mocks = find_mocks(testfile_includes)
|
used_mocks = find_mocks(testfile_includes)
|
||||||
testfile_includes = (testfile_includes - used_mocks)
|
testfile_includes = (testfile_includes - used_mocks)
|
||||||
testfile_includes.delete_if{|inc| inc =~ /(unity|cmock)/}
|
testfile_includes.delete_if { |inc| inc =~ /(unity|cmock)/ }
|
||||||
|
|
||||||
#build runner file
|
# build runner file
|
||||||
generate(input_file, output_file, tests, used_mocks, testfile_includes)
|
generate(input_file, output_file, tests, used_mocks, testfile_includes)
|
||||||
|
|
||||||
#determine which files were used to return them
|
# determine which files were used to return them
|
||||||
all_files_used = [input_file, output_file]
|
all_files_used = [input_file, output_file]
|
||||||
all_files_used += testfile_includes.map {|filename| filename + '.c'} unless testfile_includes.empty?
|
all_files_used += testfile_includes.map { |filename| filename + '.c' } unless testfile_includes.empty?
|
||||||
all_files_used += @options[:includes] unless @options[:includes].empty?
|
all_files_used += @options[:includes] unless @options[:includes].empty?
|
||||||
return all_files_used.uniq
|
all_files_used += headers[:linkonly] unless headers[:linkonly].empty?
|
||||||
|
all_files_used.uniq
|
||||||
end
|
end
|
||||||
|
|
||||||
def generate(input_file, output_file, tests, used_mocks, testfile_includes)
|
def generate(input_file, output_file, tests, used_mocks, testfile_includes)
|
||||||
@ -80,15 +75,16 @@ class UnityTestRunnerGenerator
|
|||||||
create_header(output, used_mocks, testfile_includes)
|
create_header(output, used_mocks, testfile_includes)
|
||||||
create_externs(output, tests, used_mocks)
|
create_externs(output, tests, used_mocks)
|
||||||
create_mock_management(output, used_mocks)
|
create_mock_management(output, used_mocks)
|
||||||
create_suite_setup_and_teardown(output)
|
create_suite_setup(output)
|
||||||
|
create_suite_teardown(output)
|
||||||
create_reset(output, used_mocks)
|
create_reset(output, used_mocks)
|
||||||
create_main(output, input_file, tests, used_mocks)
|
create_main(output, input_file, tests, used_mocks)
|
||||||
end
|
end
|
||||||
|
|
||||||
if (@options[:header_file] && !@options[:header_file].empty?)
|
return unless @options[:header_file] && !@options[:header_file].empty?
|
||||||
File.open(@options[:header_file], 'w') do |output|
|
|
||||||
create_h_file(output, @options[:header_file], tests, testfile_includes, used_mocks)
|
File.open(@options[:header_file], 'w') do |output|
|
||||||
end
|
create_h_file(output, @options[:header_file], tests, testfile_includes, used_mocks)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -96,103 +92,102 @@ class UnityTestRunnerGenerator
|
|||||||
tests_and_line_numbers = []
|
tests_and_line_numbers = []
|
||||||
|
|
||||||
source_scrubbed = source.clone
|
source_scrubbed = source.clone
|
||||||
source_scrubbed = source_scrubbed.gsub(/"[^"\n]*"/, '') # remove things in strings
|
source_scrubbed = source_scrubbed.gsub(/"[^"\n]*"/, '') # remove things in strings
|
||||||
source_scrubbed = source_scrubbed.gsub(/\/\/.*$/, '') # remove line comments
|
source_scrubbed = source_scrubbed.gsub(/\/\/.*$/, '') # remove line comments
|
||||||
source_scrubbed = source_scrubbed.gsub(/\/\*.*?\*\//m, '') # remove block comments
|
source_scrubbed = source_scrubbed.gsub(/\/\*.*?\*\//m, '') # remove block comments
|
||||||
lines = source_scrubbed.split(/(^\s*\#.*$) # Treat preprocessor directives as a logical line
|
lines = source_scrubbed.split(/(^\s*\#.*$) # Treat preprocessor directives as a logical line
|
||||||
| (;|\{|\}) /x) # Match ;, {, and } as end of lines
|
| (;|\{|\}) /x) # Match ;, {, and } as end of lines
|
||||||
|
|
||||||
lines.each_with_index do |line, index|
|
lines.each_with_index do |line, _index|
|
||||||
#find tests
|
# find tests
|
||||||
if line =~ /^((?:\s*TEST_CASE\s*\(.*?\)\s*)*)\s*void\s+((?:#{@options[:test_prefix]}).*)\s*\(\s*(.*)\s*\)/
|
next unless line =~ /^((?:\s*TEST_CASE\s*\(.*?\)\s*)*)\s*void\s+((?:#{@options[:test_prefix]}).*)\s*\(\s*(.*)\s*\)/
|
||||||
arguments = $1
|
arguments = Regexp.last_match(1)
|
||||||
name = $2
|
name = Regexp.last_match(2)
|
||||||
call = $3
|
call = Regexp.last_match(3)
|
||||||
params = $4
|
params = Regexp.last_match(4)
|
||||||
args = nil
|
args = nil
|
||||||
if (@options[:use_param_tests] and !arguments.empty?)
|
if @options[:use_param_tests] && !arguments.empty?
|
||||||
args = []
|
args = []
|
||||||
arguments.scan(/\s*TEST_CASE\s*\((.*)\)\s*$/) {|a| args << a[0]}
|
arguments.scan(/\s*TEST_CASE\s*\((.*)\)\s*$/) { |a| args << a[0] }
|
||||||
end
|
|
||||||
tests_and_line_numbers << { :test => name, :args => args, :call => call, :params => params, :line_number => 0 }
|
|
||||||
end
|
end
|
||||||
|
tests_and_line_numbers << { test: name, args: args, call: call, params: params, line_number: 0 }
|
||||||
end
|
end
|
||||||
tests_and_line_numbers.uniq! {|v| v[:test] }
|
tests_and_line_numbers.uniq! { |v| v[:test] }
|
||||||
|
|
||||||
#determine line numbers and create tests to run
|
# determine line numbers and create tests to run
|
||||||
source_lines = source.split("\n")
|
source_lines = source.split("\n")
|
||||||
source_index = 0;
|
source_index = 0
|
||||||
tests_and_line_numbers.size.times do |i|
|
tests_and_line_numbers.size.times do |i|
|
||||||
source_lines[source_index..-1].each_with_index do |line, index|
|
source_lines[source_index..-1].each_with_index do |line, index|
|
||||||
if (line =~ /#{tests_and_line_numbers[i][:test]}/)
|
next unless line =~ /#{tests_and_line_numbers[i][:test]}/
|
||||||
source_index += index
|
source_index += index
|
||||||
tests_and_line_numbers[i][:line_number] = source_index + 1
|
tests_and_line_numbers[i][:line_number] = source_index + 1
|
||||||
break
|
break
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
return tests_and_line_numbers
|
tests_and_line_numbers
|
||||||
end
|
end
|
||||||
|
|
||||||
def find_includes(source)
|
def find_includes(source)
|
||||||
|
# remove comments (block and line, in three steps to ensure correct precedence)
|
||||||
#remove comments (block and line, in three steps to ensure correct precedence)
|
|
||||||
source.gsub!(/\/\/(?:.+\/\*|\*(?:$|[^\/])).*$/, '') # remove line comments that comment out the start of blocks
|
source.gsub!(/\/\/(?:.+\/\*|\*(?:$|[^\/])).*$/, '') # remove line comments that comment out the start of blocks
|
||||||
source.gsub!(/\/\*.*?\*\//m, '') # remove block comments
|
source.gsub!(/\/\*.*?\*\//m, '') # remove block comments
|
||||||
source.gsub!(/\/\/.*$/, '') # remove line comments (all that remain)
|
source.gsub!(/\/\/.*$/, '') # remove line comments (all that remain)
|
||||||
|
|
||||||
#parse out includes
|
# parse out includes
|
||||||
includes = {
|
includes = {
|
||||||
:local => source.scan(/^\s*#include\s+\"\s*(.+)\.[hH]\s*\"/).flatten,
|
local: source.scan(/^\s*#include\s+\"\s*(.+)\.[hH]\s*\"/).flatten,
|
||||||
:system => source.scan(/^\s*#include\s+<\s*(.+)\s*>/).flatten.map { |inc| "<#{inc}>" }
|
system: source.scan(/^\s*#include\s+<\s*(.+)\s*>/).flatten.map { |inc| "<#{inc}>" },
|
||||||
|
linkonly: source.scan(/^TEST_FILE\(\s*\"\s*(.+)\.[cC]\w*\s*\"/).flatten
|
||||||
}
|
}
|
||||||
return includes
|
includes
|
||||||
end
|
end
|
||||||
|
|
||||||
def find_mocks(includes)
|
def find_mocks(includes)
|
||||||
mock_headers = []
|
mock_headers = []
|
||||||
includes.each do |include_path|
|
includes.each do |include_path|
|
||||||
include_file = File.basename(include_path)
|
include_file = File.basename(include_path)
|
||||||
mock_headers << include_path if (include_file =~ /^mock/i)
|
mock_headers << include_path if include_file =~ /^#{@options[:mock_prefix]}/i
|
||||||
end
|
end
|
||||||
return mock_headers
|
mock_headers
|
||||||
end
|
end
|
||||||
|
|
||||||
def create_header(output, mocks, testfile_includes=[])
|
def create_header(output, mocks, testfile_includes = [])
|
||||||
output.puts('/* AUTOGENERATED FILE. DO NOT EDIT. */')
|
output.puts('/* AUTOGENERATED FILE. DO NOT EDIT. */')
|
||||||
create_runtest(output, mocks)
|
create_runtest(output, mocks)
|
||||||
output.puts("\n/*=======Automagically Detected Files To Include=====*/")
|
output.puts("\n/*=======Automagically Detected Files To Include=====*/")
|
||||||
output.puts("#include \"#{@options[:framework].to_s}.h\"")
|
output.puts("#include \"#{@options[:framework]}.h\"")
|
||||||
output.puts('#include "cmock.h"') unless (mocks.empty?)
|
output.puts('#include "cmock.h"') unless mocks.empty?
|
||||||
output.puts('#include <setjmp.h>')
|
output.puts('#include <setjmp.h>')
|
||||||
output.puts('#include <stdio.h>')
|
output.puts('#include <stdio.h>')
|
||||||
output.puts('#include "CException.h"') if @options[:plugins].include?(:cexception)
|
if @options[:defines] && !@options[:defines].empty?
|
||||||
if (@options[:defines] && !@options[:defines].empty?)
|
@options[:defines].each { |d| output.puts("#define #{d}") }
|
||||||
@options[:defines].each {|d| output.puts("#define #{d}")}
|
|
||||||
end
|
end
|
||||||
if (@options[:header_file] && !@options[:header_file].empty?)
|
if @options[:header_file] && !@options[:header_file].empty?
|
||||||
output.puts("#include \"#{File.basename(@options[:header_file])}\"")
|
output.puts("#include \"#{File.basename(@options[:header_file])}\"")
|
||||||
else
|
else
|
||||||
@options[:includes].flatten.uniq.compact.each do |inc|
|
@options[:includes].flatten.uniq.compact.each do |inc|
|
||||||
output.puts("#include #{inc.include?('<') ? inc : "\"#{inc.gsub('.h','')}.h\""}")
|
output.puts("#include #{inc.include?('<') ? inc : "\"#{inc.gsub('.h', '')}.h\""}")
|
||||||
end
|
end
|
||||||
testfile_includes.each do |inc|
|
testfile_includes.each do |inc|
|
||||||
output.puts("#include #{inc.include?('<') ? inc : "\"#{inc.gsub('.h','')}.h\""}")
|
output.puts("#include #{inc.include?('<') ? inc : "\"#{inc.gsub('.h', '')}.h\""}")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
mocks.each do |mock|
|
mocks.each do |mock|
|
||||||
output.puts("#include \"#{mock.gsub('.h','')}.h\"")
|
output.puts("#include \"#{mock.gsub('.h', '')}.h\"")
|
||||||
end
|
|
||||||
if @options[:enforce_strict_ordering]
|
|
||||||
output.puts('')
|
|
||||||
output.puts('int GlobalExpectCount;')
|
|
||||||
output.puts('int GlobalVerifyOrder;')
|
|
||||||
output.puts('char* GlobalOrderError;')
|
|
||||||
end
|
end
|
||||||
|
output.puts('#include "CException.h"') if @options[:plugins].include?(:cexception)
|
||||||
|
|
||||||
|
return unless @options[:enforce_strict_ordering]
|
||||||
|
|
||||||
|
output.puts('')
|
||||||
|
output.puts('int GlobalExpectCount;')
|
||||||
|
output.puts('int GlobalVerifyOrder;')
|
||||||
|
output.puts('char* GlobalOrderError;')
|
||||||
end
|
end
|
||||||
|
|
||||||
def create_externs(output, tests, mocks)
|
def create_externs(output, tests, _mocks)
|
||||||
output.puts("\n/*=======External Functions This Runner Calls=====*/")
|
output.puts("\n/*=======External Functions This Runner Calls=====*/")
|
||||||
output.puts("extern void #{@options[:setup_name]}(void);")
|
output.puts("extern void #{@options[:setup_name]}(void);")
|
||||||
output.puts("extern void #{@options[:teardown_name]}(void);")
|
output.puts("extern void #{@options[:teardown_name]}(void);")
|
||||||
@ -203,55 +198,60 @@ class UnityTestRunnerGenerator
|
|||||||
end
|
end
|
||||||
|
|
||||||
def create_mock_management(output, mock_headers)
|
def create_mock_management(output, mock_headers)
|
||||||
unless (mock_headers.empty?)
|
return if mock_headers.empty?
|
||||||
output.puts("\n/*=======Mock Management=====*/")
|
|
||||||
output.puts("static void CMock_Init(void)")
|
|
||||||
output.puts("{")
|
|
||||||
if @options[:enforce_strict_ordering]
|
|
||||||
output.puts(" GlobalExpectCount = 0;")
|
|
||||||
output.puts(" GlobalVerifyOrder = 0;")
|
|
||||||
output.puts(" GlobalOrderError = NULL;")
|
|
||||||
end
|
|
||||||
mocks = mock_headers.map {|mock| File.basename(mock)}
|
|
||||||
mocks.each do |mock|
|
|
||||||
mock_clean = TypeSanitizer.sanitize_c_identifier(mock)
|
|
||||||
output.puts(" #{mock_clean}_Init();")
|
|
||||||
end
|
|
||||||
output.puts("}\n")
|
|
||||||
|
|
||||||
output.puts("static void CMock_Verify(void)")
|
output.puts("\n/*=======Mock Management=====*/")
|
||||||
output.puts("{")
|
output.puts('static void CMock_Init(void)')
|
||||||
mocks.each do |mock|
|
output.puts('{')
|
||||||
mock_clean = TypeSanitizer.sanitize_c_identifier(mock)
|
|
||||||
output.puts(" #{mock_clean}_Verify();")
|
|
||||||
end
|
|
||||||
output.puts("}\n")
|
|
||||||
|
|
||||||
output.puts("static void CMock_Destroy(void)")
|
if @options[:enforce_strict_ordering]
|
||||||
output.puts("{")
|
output.puts(' GlobalExpectCount = 0;')
|
||||||
mocks.each do |mock|
|
output.puts(' GlobalVerifyOrder = 0;')
|
||||||
mock_clean = TypeSanitizer.sanitize_c_identifier(mock)
|
output.puts(' GlobalOrderError = NULL;')
|
||||||
output.puts(" #{mock_clean}_Destroy();")
|
|
||||||
end
|
|
||||||
output.puts("}\n")
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
mocks = mock_headers.map { |mock| File.basename(mock) }
|
||||||
|
mocks.each do |mock|
|
||||||
|
mock_clean = TypeSanitizer.sanitize_c_identifier(mock)
|
||||||
|
output.puts(" #{mock_clean}_Init();")
|
||||||
|
end
|
||||||
|
output.puts("}\n")
|
||||||
|
|
||||||
|
output.puts('static void CMock_Verify(void)')
|
||||||
|
output.puts('{')
|
||||||
|
mocks.each do |mock|
|
||||||
|
mock_clean = TypeSanitizer.sanitize_c_identifier(mock)
|
||||||
|
output.puts(" #{mock_clean}_Verify();")
|
||||||
|
end
|
||||||
|
output.puts("}\n")
|
||||||
|
|
||||||
|
output.puts('static void CMock_Destroy(void)')
|
||||||
|
output.puts('{')
|
||||||
|
mocks.each do |mock|
|
||||||
|
mock_clean = TypeSanitizer.sanitize_c_identifier(mock)
|
||||||
|
output.puts(" #{mock_clean}_Destroy();")
|
||||||
|
end
|
||||||
|
output.puts("}\n")
|
||||||
end
|
end
|
||||||
|
|
||||||
def create_suite_setup_and_teardown(output)
|
def create_suite_setup(output)
|
||||||
unless (@options[:suite_setup].nil?)
|
return if @options[:suite_setup].nil?
|
||||||
output.puts("\n/*=======Suite Setup=====*/")
|
|
||||||
output.puts("static void suite_setup(void)")
|
output.puts("\n/*=======Suite Setup=====*/")
|
||||||
output.puts("{")
|
output.puts('static void suite_setup(void)')
|
||||||
output.puts(@options[:suite_setup])
|
output.puts('{')
|
||||||
output.puts("}")
|
output.puts(@options[:suite_setup])
|
||||||
end
|
output.puts('}')
|
||||||
unless (@options[:suite_teardown].nil?)
|
end
|
||||||
output.puts("\n/*=======Suite Teardown=====*/")
|
|
||||||
output.puts("static int suite_teardown(int num_failures)")
|
def create_suite_teardown(output)
|
||||||
output.puts("{")
|
return if @options[:suite_teardown].nil?
|
||||||
output.puts(@options[:suite_teardown])
|
|
||||||
output.puts("}")
|
output.puts("\n/*=======Suite Teardown=====*/")
|
||||||
end
|
output.puts('static int suite_teardown(int num_failures)')
|
||||||
|
output.puts('{')
|
||||||
|
output.puts(@options[:suite_teardown])
|
||||||
|
output.puts('}')
|
||||||
end
|
end
|
||||||
|
|
||||||
def create_runtest(output, used_mocks)
|
def create_runtest(output, used_mocks)
|
||||||
@ -259,124 +259,124 @@ class UnityTestRunnerGenerator
|
|||||||
va_args1 = @options[:use_param_tests] ? ', ...' : ''
|
va_args1 = @options[:use_param_tests] ? ', ...' : ''
|
||||||
va_args2 = @options[:use_param_tests] ? '__VA_ARGS__' : ''
|
va_args2 = @options[:use_param_tests] ? '__VA_ARGS__' : ''
|
||||||
output.puts("\n/*=======Test Runner Used To Run Each Test Below=====*/")
|
output.puts("\n/*=======Test Runner Used To Run Each Test Below=====*/")
|
||||||
output.puts("#define RUN_TEST_NO_ARGS") if @options[:use_param_tests]
|
output.puts('#define RUN_TEST_NO_ARGS') if @options[:use_param_tests]
|
||||||
output.puts("#define RUN_TEST(TestFunc, TestLineNum#{va_args1}) \\")
|
output.puts("#define RUN_TEST(TestFunc, TestLineNum#{va_args1}) \\")
|
||||||
output.puts("{ \\")
|
output.puts('{ \\')
|
||||||
output.puts(" Unity.CurrentTestName = #TestFunc#{va_args2.empty? ? '' : " \"(\" ##{va_args2} \")\""}; \\")
|
output.puts(" Unity.CurrentTestName = #TestFunc#{va_args2.empty? ? '' : " \"(\" ##{va_args2} \")\""}; \\")
|
||||||
output.puts(" Unity.CurrentTestLineNumber = TestLineNum; \\")
|
output.puts(' Unity.CurrentTestLineNumber = TestLineNum; \\')
|
||||||
output.puts(" if (UnityTestMatches()) { \\") if (@options[:cmdline_args])
|
output.puts(' if (UnityTestMatches()) { \\') if @options[:cmdline_args]
|
||||||
output.puts(" Unity.NumberOfTests++; \\")
|
output.puts(' Unity.NumberOfTests++; \\')
|
||||||
output.puts(" CMock_Init(); \\") unless (used_mocks.empty?)
|
output.puts(' CMock_Init(); \\') unless used_mocks.empty?
|
||||||
output.puts(" UNITY_CLR_DETAILS(); \\") unless (used_mocks.empty?)
|
output.puts(' UNITY_CLR_DETAILS(); \\') unless used_mocks.empty?
|
||||||
output.puts(" if (TEST_PROTECT()) \\")
|
output.puts(' if (TEST_PROTECT()) \\')
|
||||||
output.puts(" { \\")
|
output.puts(' { \\')
|
||||||
output.puts(" CEXCEPTION_T e; \\") if cexception
|
output.puts(' CEXCEPTION_T e; \\') if cexception
|
||||||
output.puts(" Try { \\") if cexception
|
output.puts(' Try { \\') if cexception
|
||||||
output.puts(" #{@options[:setup_name]}(); \\")
|
output.puts(" #{@options[:setup_name]}(); \\")
|
||||||
output.puts(" TestFunc(#{va_args2}); \\")
|
output.puts(" TestFunc(#{va_args2}); \\")
|
||||||
output.puts(" } Catch(e) { TEST_ASSERT_EQUAL_HEX32_MESSAGE(CEXCEPTION_NONE, e, \"Unhandled Exception!\"); } \\") if cexception
|
output.puts(' } Catch(e) { TEST_ASSERT_EQUAL_HEX32_MESSAGE(CEXCEPTION_NONE, e, "Unhandled Exception!"); } \\') if cexception
|
||||||
output.puts(" } \\")
|
output.puts(' } \\')
|
||||||
output.puts(" if (TEST_PROTECT()) \\")
|
output.puts(' if (TEST_PROTECT()) \\')
|
||||||
output.puts(" { \\")
|
output.puts(' { \\')
|
||||||
output.puts(" #{@options[:teardown_name]}(); \\")
|
output.puts(" #{@options[:teardown_name]}(); \\")
|
||||||
output.puts(" CMock_Verify(); \\") unless (used_mocks.empty?)
|
output.puts(' CMock_Verify(); \\') unless used_mocks.empty?
|
||||||
output.puts(" } \\")
|
output.puts(' } \\')
|
||||||
output.puts(" CMock_Destroy(); \\") unless (used_mocks.empty?)
|
output.puts(' CMock_Destroy(); \\') unless used_mocks.empty?
|
||||||
output.puts(" UnityConcludeTest(); \\")
|
output.puts(' UnityConcludeTest(); \\')
|
||||||
output.puts(" } \\") if (@options[:cmdline_args])
|
output.puts(' } \\') if @options[:cmdline_args]
|
||||||
output.puts("}\n")
|
output.puts("}\n")
|
||||||
end
|
end
|
||||||
|
|
||||||
def create_reset(output, used_mocks)
|
def create_reset(output, used_mocks)
|
||||||
output.puts("\n/*=======Test Reset Option=====*/")
|
output.puts("\n/*=======Test Reset Option=====*/")
|
||||||
output.puts("void resetTest(void);")
|
output.puts('void resetTest(void);')
|
||||||
output.puts("void resetTest(void)")
|
output.puts('void resetTest(void)')
|
||||||
output.puts("{")
|
output.puts('{')
|
||||||
output.puts(" CMock_Verify();") unless (used_mocks.empty?)
|
output.puts(' CMock_Verify();') unless used_mocks.empty?
|
||||||
output.puts(" CMock_Destroy();") unless (used_mocks.empty?)
|
output.puts(' CMock_Destroy();') unless used_mocks.empty?
|
||||||
output.puts(" #{@options[:teardown_name]}();")
|
output.puts(" #{@options[:teardown_name]}();")
|
||||||
output.puts(" CMock_Init();") unless (used_mocks.empty?)
|
output.puts(' CMock_Init();') unless used_mocks.empty?
|
||||||
output.puts(" #{@options[:setup_name]}();")
|
output.puts(" #{@options[:setup_name]}();")
|
||||||
output.puts("}")
|
output.puts('}')
|
||||||
end
|
end
|
||||||
|
|
||||||
def create_main(output, filename, tests, used_mocks)
|
def create_main(output, filename, tests, used_mocks)
|
||||||
output.puts("\n\n/*=======MAIN=====*/")
|
output.puts("\n\n/*=======MAIN=====*/")
|
||||||
main_name = (@options[:main_name].to_sym == :auto) ? "main_#{filename.gsub('.c','')}" : "#{@options[:main_name]}"
|
main_name = @options[:main_name].to_sym == :auto ? "main_#{filename.gsub('.c', '')}" : (@options[:main_name]).to_s
|
||||||
if (@options[:cmdline_args])
|
if @options[:cmdline_args]
|
||||||
if (main_name != "main")
|
if main_name != 'main'
|
||||||
output.puts("#{@options[:main_export_decl]} int #{main_name}(int argc, char** argv);")
|
output.puts("#{@options[:main_export_decl]} int #{main_name}(int argc, char** argv);")
|
||||||
end
|
end
|
||||||
output.puts("#{@options[:main_export_decl]} int #{main_name}(int argc, char** argv)")
|
output.puts("#{@options[:main_export_decl]} int #{main_name}(int argc, char** argv)")
|
||||||
output.puts("{")
|
output.puts('{')
|
||||||
output.puts(" int parse_status = UnityParseOptions(argc, argv);")
|
output.puts(' int parse_status = UnityParseOptions(argc, argv);')
|
||||||
output.puts(" if (parse_status != 0)")
|
output.puts(' if (parse_status != 0)')
|
||||||
output.puts(" {")
|
output.puts(' {')
|
||||||
output.puts(" if (parse_status < 0)")
|
output.puts(' if (parse_status < 0)')
|
||||||
output.puts(" {")
|
output.puts(' {')
|
||||||
output.puts(" UnityPrint(\"#{filename.gsub('.c','')}.\");")
|
output.puts(" UnityPrint(\"#{filename.gsub('.c', '')}.\");")
|
||||||
output.puts(" UNITY_PRINT_EOL();")
|
output.puts(' UNITY_PRINT_EOL();')
|
||||||
if (@options[:use_param_tests])
|
if @options[:use_param_tests]
|
||||||
tests.each do |test|
|
tests.each do |test|
|
||||||
if ((test[:args].nil?) or (test[:args].empty?))
|
if test[:args].nil? || test[:args].empty?
|
||||||
output.puts(" UnityPrint(\" #{test[:test]}(RUN_TEST_NO_ARGS)\");")
|
output.puts(" UnityPrint(\" #{test[:test]}(RUN_TEST_NO_ARGS)\");")
|
||||||
output.puts(" UNITY_PRINT_EOL();")
|
output.puts(' UNITY_PRINT_EOL();')
|
||||||
else
|
else
|
||||||
test[:args].each do |args|
|
test[:args].each do |args|
|
||||||
output.puts(" UnityPrint(\" #{test[:test]}(#{args})\");")
|
output.puts(" UnityPrint(\" #{test[:test]}(#{args})\");")
|
||||||
output.puts(" UNITY_PRINT_EOL();")
|
output.puts(' UNITY_PRINT_EOL();')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
tests.each { |test| output.puts(" UnityPrint(\" #{test[:test]}\");\n UNITY_PRINT_EOL();")}
|
tests.each { |test| output.puts(" UnityPrint(\" #{test[:test]}\");\n UNITY_PRINT_EOL();") }
|
||||||
end
|
end
|
||||||
output.puts(" return 0;")
|
output.puts(' return 0;')
|
||||||
output.puts(" }")
|
output.puts(' }')
|
||||||
output.puts(" return parse_status;")
|
output.puts(' return parse_status;')
|
||||||
output.puts(" }")
|
output.puts(' }')
|
||||||
else
|
else
|
||||||
if (main_name != "main")
|
if main_name != 'main'
|
||||||
output.puts("#{@options[:main_export_decl]} int #{main_name}(void);")
|
output.puts("#{@options[:main_export_decl]} int #{main_name}(void);")
|
||||||
end
|
end
|
||||||
output.puts("int #{main_name}(void)")
|
output.puts("int #{main_name}(void)")
|
||||||
output.puts("{")
|
output.puts('{')
|
||||||
end
|
end
|
||||||
output.puts(" suite_setup();") unless @options[:suite_setup].nil?
|
output.puts(' suite_setup();') unless @options[:suite_setup].nil?
|
||||||
output.puts(" UnityBegin(\"#{filename.gsub(/\\/,'\\\\\\')}\");")
|
output.puts(" UnityBegin(\"#{filename.gsub(/\\/, '\\\\\\')}\");")
|
||||||
if (@options[:use_param_tests])
|
if @options[:use_param_tests]
|
||||||
tests.each do |test|
|
tests.each do |test|
|
||||||
if ((test[:args].nil?) or (test[:args].empty?))
|
if test[:args].nil? || test[:args].empty?
|
||||||
output.puts(" RUN_TEST(#{test[:test]}, #{test[:line_number]}, RUN_TEST_NO_ARGS);")
|
output.puts(" RUN_TEST(#{test[:test]}, #{test[:line_number]}, RUN_TEST_NO_ARGS);")
|
||||||
else
|
else
|
||||||
test[:args].each {|args| output.puts(" RUN_TEST(#{test[:test]}, #{test[:line_number]}, #{args});")}
|
test[:args].each { |args| output.puts(" RUN_TEST(#{test[:test]}, #{test[:line_number]}, #{args});") }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
tests.each { |test| output.puts(" RUN_TEST(#{test[:test]}, #{test[:line_number]});") }
|
tests.each { |test| output.puts(" RUN_TEST(#{test[:test]}, #{test[:line_number]});") }
|
||||||
end
|
end
|
||||||
output.puts()
|
output.puts
|
||||||
output.puts(" CMock_Guts_MemFreeFinal();") unless used_mocks.empty?
|
output.puts(' CMock_Guts_MemFreeFinal();') unless used_mocks.empty?
|
||||||
output.puts(" return #{@options[:suite_teardown].nil? ? "" : "suite_teardown"}(UnityEnd());")
|
output.puts(" return #{@options[:suite_teardown].nil? ? '' : 'suite_teardown'}(UnityEnd());")
|
||||||
output.puts("}")
|
output.puts('}')
|
||||||
end
|
end
|
||||||
|
|
||||||
def create_h_file(output, filename, tests, testfile_includes, used_mocks)
|
def create_h_file(output, filename, tests, testfile_includes, used_mocks)
|
||||||
filename = File.basename(filename).gsub(/[-\/\\\.\,\s]/, "_").upcase
|
filename = File.basename(filename).gsub(/[-\/\\\.\,\s]/, '_').upcase
|
||||||
output.puts("/* AUTOGENERATED FILE. DO NOT EDIT. */")
|
output.puts('/* AUTOGENERATED FILE. DO NOT EDIT. */')
|
||||||
output.puts("#ifndef _#{filename}")
|
output.puts("#ifndef _#{filename}")
|
||||||
output.puts("#define _#{filename}\n\n")
|
output.puts("#define _#{filename}\n\n")
|
||||||
output.puts("#include \"#{@options[:framework].to_s}.h\"")
|
output.puts("#include \"#{@options[:framework]}.h\"")
|
||||||
output.puts('#include "cmock.h"') unless (used_mocks.empty?)
|
output.puts('#include "cmock.h"') unless used_mocks.empty?
|
||||||
@options[:includes].flatten.uniq.compact.each do |inc|
|
@options[:includes].flatten.uniq.compact.each do |inc|
|
||||||
output.puts("#include #{inc.include?('<') ? inc : "\"#{inc.gsub('.h','')}.h\""}")
|
output.puts("#include #{inc.include?('<') ? inc : "\"#{inc.gsub('.h', '')}.h\""}")
|
||||||
end
|
end
|
||||||
testfile_includes.each do |inc|
|
testfile_includes.each do |inc|
|
||||||
output.puts("#include #{inc.include?('<') ? inc : "\"#{inc.gsub('.h','')}.h\""}")
|
output.puts("#include #{inc.include?('<') ? inc : "\"#{inc.gsub('.h', '')}.h\""}")
|
||||||
end
|
end
|
||||||
output.puts "\n"
|
output.puts "\n"
|
||||||
tests.each do |test|
|
tests.each do |test|
|
||||||
if ((test[:params].nil?) or (test[:params].empty?))
|
if test[:params].nil? || test[:params].empty?
|
||||||
output.puts("void #{test[:test]}(void);")
|
output.puts("void #{test[:test]}(void);")
|
||||||
else
|
else
|
||||||
output.puts("void #{test[:test]}(#{test[:params]});")
|
output.puts("void #{test[:test]}(#{test[:params]});")
|
||||||
@ -386,50 +386,52 @@ class UnityTestRunnerGenerator
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if ($0 == __FILE__)
|
if $0 == __FILE__
|
||||||
options = { :includes => [] }
|
options = { includes: [] }
|
||||||
yaml_file = nil
|
|
||||||
|
|
||||||
#parse out all the options first (these will all be removed as we go)
|
# parse out all the options first (these will all be removed as we go)
|
||||||
ARGV.reject! do |arg|
|
ARGV.reject! do |arg|
|
||||||
case(arg)
|
case arg
|
||||||
when '-cexception'
|
when '-cexception'
|
||||||
options[:plugins] = [:cexception]; true
|
options[:plugins] = [:cexception]
|
||||||
when /\.*\.ya?ml/
|
true
|
||||||
options = UnityTestRunnerGenerator.grab_config(arg); true
|
when /\.*\.ya?ml/
|
||||||
when /--(\w+)=\"?(.*)\"?/
|
options = UnityTestRunnerGenerator.grab_config(arg)
|
||||||
options[$1.to_sym] = $2; true
|
true
|
||||||
when /\.*\.h/
|
when /--(\w+)=\"?(.*)\"?/
|
||||||
options[:includes] << arg; true
|
options[Regexp.last_match(1).to_sym] = Regexp.last_match(2)
|
||||||
else false
|
true
|
||||||
|
when /\.*\.h/
|
||||||
|
options[:includes] << arg
|
||||||
|
true
|
||||||
|
else false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
#make sure there is at least one parameter left (the input file)
|
# make sure there is at least one parameter left (the input file)
|
||||||
if !ARGV[0]
|
unless ARGV[0]
|
||||||
puts ["\nusage: ruby #{__FILE__} (files) (options) input_test_file (output)",
|
puts ["\nusage: ruby #{__FILE__} (files) (options) input_test_file (output)",
|
||||||
"\n input_test_file - this is the C file you want to create a runner for",
|
"\n input_test_file - this is the C file you want to create a runner for",
|
||||||
" output - this is the name of the runner file to generate",
|
' output - this is the name of the runner file to generate',
|
||||||
" defaults to (input_test_file)_Runner",
|
' defaults to (input_test_file)_Runner',
|
||||||
" files:",
|
' files:',
|
||||||
" *.yml / *.yaml - loads configuration from here in :unity or :cmock",
|
' *.yml / *.yaml - loads configuration from here in :unity or :cmock',
|
||||||
" *.h - header files are added as #includes in runner",
|
' *.h - header files are added as #includes in runner',
|
||||||
" options:",
|
' options:',
|
||||||
" -cexception - include cexception support",
|
' -cexception - include cexception support',
|
||||||
" --setup_name=\"\" - redefine setUp func name to something else",
|
' --setup_name="" - redefine setUp func name to something else',
|
||||||
" --teardown_name=\"\" - redefine tearDown func name to something else",
|
' --teardown_name="" - redefine tearDown func name to something else',
|
||||||
" --main_name=\"\" - redefine main func name to something else",
|
' --main_name="" - redefine main func name to something else',
|
||||||
" --test_prefix=\"\" - redefine test prefix from default test|spec|should",
|
' --test_prefix="" - redefine test prefix from default test|spec|should',
|
||||||
" --suite_setup=\"\" - code to execute for setup of entire suite",
|
' --suite_setup="" - code to execute for setup of entire suite',
|
||||||
" --suite_teardown=\"\" - code to execute for teardown of entire suite",
|
' --suite_teardown="" - code to execute for teardown of entire suite',
|
||||||
" --use_param_tests=1 - enable parameterized tests (disabled by default)",
|
' --use_param_tests=1 - enable parameterized tests (disabled by default)',
|
||||||
" --header_file=\"\" - path/name of test header file to generate too"
|
' --header_file="" - path/name of test header file to generate too'].join("\n")
|
||||||
].join("\n")
|
|
||||||
exit 1
|
exit 1
|
||||||
end
|
end
|
||||||
|
|
||||||
#create the default test runner name if not specified
|
# create the default test runner name if not specified
|
||||||
ARGV[1] = ARGV[0].gsub(".c","_Runner.c") if (!ARGV[1])
|
ARGV[1] = ARGV[0].gsub('.c', '_Runner.c') unless ARGV[1]
|
||||||
|
|
||||||
UnityTestRunnerGenerator.new(options).run(ARGV[0], ARGV[1])
|
UnityTestRunnerGenerator.new(options).run(ARGV[0], ARGV[1])
|
||||||
end
|
end
|
||||||
|
@ -1,224 +0,0 @@
|
|||||||
#============================================================
|
|
||||||
# Author: John Theofanopoulos
|
|
||||||
# A simple parser. Takes the output files generated during the build process and
|
|
||||||
# extracts information relating to the tests.
|
|
||||||
#
|
|
||||||
# Notes:
|
|
||||||
# To capture an output file under VS builds use the following:
|
|
||||||
# devenv [build instructions] > Output.txt & type Output.txt
|
|
||||||
#
|
|
||||||
# To capture an output file under GCC/Linux builds use the following:
|
|
||||||
# make | tee Output.txt
|
|
||||||
#
|
|
||||||
# To use this parser use the following command
|
|
||||||
# ruby parseOutput.rb [options] [file]
|
|
||||||
# options: -xml : produce a JUnit compatible XML file
|
|
||||||
# file : file to scan for results
|
|
||||||
#============================================================
|
|
||||||
|
|
||||||
|
|
||||||
class ParseOutput
|
|
||||||
# The following flag is set to true when a test is found or false otherwise.
|
|
||||||
@testFlag
|
|
||||||
@xmlOut
|
|
||||||
@arrayList
|
|
||||||
@totalTests
|
|
||||||
@classIndex
|
|
||||||
|
|
||||||
# Set the flag to indicate if there will be an XML output file or not
|
|
||||||
def setXmlOutput()
|
|
||||||
@xmlOut = true
|
|
||||||
end
|
|
||||||
|
|
||||||
# if write our output to XML
|
|
||||||
def writeXmlOuput()
|
|
||||||
output = File.open("report.xml", "w")
|
|
||||||
output << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
|
|
||||||
@arrayList.each do |item|
|
|
||||||
output << item << "\n"
|
|
||||||
end
|
|
||||||
output << "</testsuite>\n"
|
|
||||||
end
|
|
||||||
|
|
||||||
# This function will try and determine when the suite is changed. This is
|
|
||||||
# is the name that gets added to the classname parameter.
|
|
||||||
def testSuiteVerify(testSuiteName)
|
|
||||||
if @testFlag == false
|
|
||||||
@testFlag = true;
|
|
||||||
# Split the path name
|
|
||||||
testName = testSuiteName.split("/")
|
|
||||||
# Remove the extension
|
|
||||||
baseName = testName[testName.size - 1].split(".")
|
|
||||||
@testSuite = "test." + baseName[0]
|
|
||||||
printf "New Test: %s\n", @testSuite
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
# Test was flagged as having passed so format the output
|
|
||||||
def testPassed(array)
|
|
||||||
lastItem = array.length - 1
|
|
||||||
testName = array[lastItem - 1]
|
|
||||||
testSuiteVerify(array[@className])
|
|
||||||
printf "%-40s PASS\n", testName
|
|
||||||
if @xmlOut == true
|
|
||||||
@arrayList.push " <testcase classname=\"" + @testSuite + "\" name=\"" + testName + "\"/>"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# Test was flagged as having passed so format the output.
|
|
||||||
# This is using the Unity fixture output and not the original Unity output.
|
|
||||||
def testPassedUnityFixture(array)
|
|
||||||
testSuite = array[0].sub("TEST(", "")
|
|
||||||
testSuite = testSuite.sub(",", "")
|
|
||||||
testName = array[1].sub(")", "")
|
|
||||||
if @xmlOut == true
|
|
||||||
@arrayList.push " <testcase classname=\"" + testSuite + "\" name=\"" + testName + "\"/>"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# Test was flagged as being ingored so format the output
|
|
||||||
def testIgnored(array)
|
|
||||||
lastItem = array.length - 1
|
|
||||||
testName = array[lastItem - 2]
|
|
||||||
reason = array[lastItem].chomp
|
|
||||||
testSuiteVerify(array[@className])
|
|
||||||
printf "%-40s IGNORED\n", testName
|
|
||||||
|
|
||||||
if testName.start_with? "TEST("
|
|
||||||
array2 = testName.split(" ")
|
|
||||||
@testSuite = array2[0].sub("TEST(", "")
|
|
||||||
@testSuite = @testSuite.sub(",", "")
|
|
||||||
testName = array2[1].sub(")", "")
|
|
||||||
end
|
|
||||||
|
|
||||||
if @xmlOut == true
|
|
||||||
@arrayList.push " <testcase classname=\"" + @testSuite + "\" name=\"" + testName + "\">"
|
|
||||||
@arrayList.push " <skipped type=\"TEST IGNORED\"> " + reason + " </skipped>"
|
|
||||||
@arrayList.push " </testcase>"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# Test was flagged as having failed so format the line
|
|
||||||
def testFailed(array)
|
|
||||||
lastItem = array.length - 1
|
|
||||||
testName = array[lastItem - 2]
|
|
||||||
reason = array[lastItem].chomp + " at line: " + array[lastItem - 3]
|
|
||||||
testSuiteVerify(array[@className])
|
|
||||||
printf "%-40s FAILED\n", testName
|
|
||||||
|
|
||||||
if testName.start_with? "TEST("
|
|
||||||
array2 = testName.split(" ")
|
|
||||||
@testSuite = array2[0].sub("TEST(", "")
|
|
||||||
@testSuite = @testSuite.sub(",", "")
|
|
||||||
testName = array2[1].sub(")", "")
|
|
||||||
end
|
|
||||||
|
|
||||||
if @xmlOut == true
|
|
||||||
@arrayList.push " <testcase classname=\"" + @testSuite + "\" name=\"" + testName + "\">"
|
|
||||||
@arrayList.push " <failure type=\"ASSERT FAILED\"> " + reason + " </failure>"
|
|
||||||
@arrayList.push " </testcase>"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
# Figure out what OS we are running on. For now we are assuming if it's not Windows it must
|
|
||||||
# be Unix based.
|
|
||||||
def detectOS()
|
|
||||||
myOS = RUBY_PLATFORM.split("-")
|
|
||||||
if myOS.size == 2
|
|
||||||
if myOS[1] == "mingw32"
|
|
||||||
@className = 1
|
|
||||||
else
|
|
||||||
@className = 0
|
|
||||||
end
|
|
||||||
else
|
|
||||||
@className = 0
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
# Main function used to parse the file that was captured.
|
|
||||||
def process(name)
|
|
||||||
@testFlag = false
|
|
||||||
@arrayList = Array.new
|
|
||||||
|
|
||||||
detectOS()
|
|
||||||
|
|
||||||
puts "Parsing file: " + name
|
|
||||||
|
|
||||||
|
|
||||||
testPass = 0
|
|
||||||
testFail = 0
|
|
||||||
testIgnore = 0
|
|
||||||
puts ""
|
|
||||||
puts "=================== RESULTS ====================="
|
|
||||||
puts ""
|
|
||||||
File.open(name).each do |line|
|
|
||||||
# Typical test lines look like this:
|
|
||||||
# <path>/<test_file>.c:36:test_tc1000_opsys:FAIL: Expected 1 Was 0
|
|
||||||
# <path>/<test_file>.c:112:test_tc5004_initCanChannel:IGNORE: Not Yet Implemented
|
|
||||||
# <path>/<test_file>.c:115:test_tc5100_initCanVoidPtrs:PASS
|
|
||||||
#
|
|
||||||
# where path is different on Unix vs Windows devices (Windows leads with a drive letter)
|
|
||||||
lineArray = line.split(":")
|
|
||||||
lineSize = lineArray.size
|
|
||||||
# If we were able to split the line then we can look to see if any of our target words
|
|
||||||
# were found. Case is important.
|
|
||||||
if ((lineSize >= 4) || (line.start_with? "TEST("))
|
|
||||||
# Determine if this test passed
|
|
||||||
if line.include? ":PASS"
|
|
||||||
testPassed(lineArray)
|
|
||||||
testPass += 1
|
|
||||||
elsif line.include? ":FAIL:"
|
|
||||||
testFailed(lineArray)
|
|
||||||
testFail += 1
|
|
||||||
elsif line.include? ":IGNORE:"
|
|
||||||
testIgnored(lineArray)
|
|
||||||
testIgnore += 1
|
|
||||||
elsif line.start_with? "TEST("
|
|
||||||
if line.include? " PASS"
|
|
||||||
lineArray = line.split(" ")
|
|
||||||
testPassedUnityFixture(lineArray)
|
|
||||||
testPass += 1
|
|
||||||
end
|
|
||||||
# If none of the keywords are found there are no more tests for this suite so clear
|
|
||||||
# the test flag
|
|
||||||
else
|
|
||||||
@testFlag = false
|
|
||||||
end
|
|
||||||
else
|
|
||||||
@testFlag = false
|
|
||||||
end
|
|
||||||
end
|
|
||||||
puts ""
|
|
||||||
puts "=================== SUMMARY ====================="
|
|
||||||
puts ""
|
|
||||||
puts "Tests Passed : " + testPass.to_s
|
|
||||||
puts "Tests Failed : " + testFail.to_s
|
|
||||||
puts "Tests Ignored : " + testIgnore.to_s
|
|
||||||
@totalTests = testPass + testFail + testIgnore
|
|
||||||
if @xmlOut == true
|
|
||||||
heading = "<testsuite tests=\"" + @totalTests.to_s + "\" failures=\"" + testFail.to_s + "\"" + " skips=\"" + testIgnore.to_s + "\">"
|
|
||||||
@arrayList.insert(0, heading)
|
|
||||||
writeXmlOuput()
|
|
||||||
end
|
|
||||||
|
|
||||||
# return result
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
# If the command line has no values in, used a default value of Output.txt
|
|
||||||
parseMyFile = ParseOutput.new
|
|
||||||
|
|
||||||
if ARGV.size >= 1
|
|
||||||
ARGV.each do |a|
|
|
||||||
if a == "-xml"
|
|
||||||
parseMyFile.setXmlOutput();
|
|
||||||
else
|
|
||||||
parseMyFile.process(a)
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
220
tests/unity/auto/parse_output.rb
Normal file
220
tests/unity/auto/parse_output.rb
Normal file
@ -0,0 +1,220 @@
|
|||||||
|
#============================================================
|
||||||
|
# Author: John Theofanopoulos
|
||||||
|
# A simple parser. Takes the output files generated during the build process and
|
||||||
|
# extracts information relating to the tests.
|
||||||
|
#
|
||||||
|
# Notes:
|
||||||
|
# To capture an output file under VS builds use the following:
|
||||||
|
# devenv [build instructions] > Output.txt & type Output.txt
|
||||||
|
#
|
||||||
|
# To capture an output file under GCC/Linux builds use the following:
|
||||||
|
# make | tee Output.txt
|
||||||
|
#
|
||||||
|
# To use this parser use the following command
|
||||||
|
# ruby parseOutput.rb [options] [file]
|
||||||
|
# options: -xml : produce a JUnit compatible XML file
|
||||||
|
# file : file to scan for results
|
||||||
|
#============================================================
|
||||||
|
|
||||||
|
class ParseOutput
|
||||||
|
def initialize
|
||||||
|
@test_flag = false
|
||||||
|
@xml_out = false
|
||||||
|
@array_list = false
|
||||||
|
@total_tests = false
|
||||||
|
@class_index = false
|
||||||
|
end
|
||||||
|
|
||||||
|
# Set the flag to indicate if there will be an XML output file or not
|
||||||
|
def set_xml_output
|
||||||
|
@xml_out = true
|
||||||
|
end
|
||||||
|
|
||||||
|
# if write our output to XML
|
||||||
|
def write_xml_output
|
||||||
|
output = File.open('report.xml', 'w')
|
||||||
|
output << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
|
||||||
|
@array_list.each do |item|
|
||||||
|
output << item << "\n"
|
||||||
|
end
|
||||||
|
output << "</testsuite>\n"
|
||||||
|
end
|
||||||
|
|
||||||
|
# This function will try and determine when the suite is changed. This is
|
||||||
|
# is the name that gets added to the classname parameter.
|
||||||
|
def test_suite_verify(test_suite_name)
|
||||||
|
return if @test_flag
|
||||||
|
|
||||||
|
@test_flag = true
|
||||||
|
# Split the path name
|
||||||
|
test_name = test_suite_name.split('/')
|
||||||
|
# Remove the extension
|
||||||
|
base_name = test_name[test_name.size - 1].split('.')
|
||||||
|
@test_suite = 'test.' + base_name[0]
|
||||||
|
printf "New Test: %s\n", @test_suite
|
||||||
|
end
|
||||||
|
|
||||||
|
# Test was flagged as having passed so format the output
|
||||||
|
def test_passed(array)
|
||||||
|
last_item = array.length - 1
|
||||||
|
test_name = array[last_item - 1]
|
||||||
|
test_suite_verify(array[@class_name])
|
||||||
|
printf "%-40s PASS\n", test_name
|
||||||
|
|
||||||
|
return unless @xml_out
|
||||||
|
|
||||||
|
@array_list.push ' <testcase classname="' + @test_suite + '" name="' + test_name + '"/>'
|
||||||
|
end
|
||||||
|
|
||||||
|
# Test was flagged as having passed so format the output.
|
||||||
|
# This is using the Unity fixture output and not the original Unity output.
|
||||||
|
def test_passed_unity_fixture(array)
|
||||||
|
test_suite = array[0].sub('TEST(', '')
|
||||||
|
test_suite = test_suite.sub(',', '')
|
||||||
|
test_name = array[1].sub(')', '')
|
||||||
|
|
||||||
|
return unless @xml_out
|
||||||
|
|
||||||
|
@array_list.push ' <testcase classname="' + test_suite + '" name="' + test_name + '"/>'
|
||||||
|
end
|
||||||
|
|
||||||
|
# Test was flagged as being ingored so format the output
|
||||||
|
def test_ignored(array)
|
||||||
|
last_item = array.length - 1
|
||||||
|
test_name = array[last_item - 2]
|
||||||
|
reason = array[last_item].chomp
|
||||||
|
test_suite_verify(array[@class_name])
|
||||||
|
printf "%-40s IGNORED\n", test_name
|
||||||
|
|
||||||
|
if test_name.start_with? 'TEST('
|
||||||
|
array2 = test_name.split(' ')
|
||||||
|
@test_suite = array2[0].sub('TEST(', '')
|
||||||
|
@test_suite = @test_suite.sub(',', '')
|
||||||
|
test_name = array2[1].sub(')', '')
|
||||||
|
end
|
||||||
|
|
||||||
|
return unless @xml_out
|
||||||
|
|
||||||
|
@array_list.push ' <testcase classname="' + @test_suite + '" name="' + test_name + '">'
|
||||||
|
@array_list.push ' <skipped type="TEST IGNORED"> ' + reason + ' </skipped>'
|
||||||
|
@array_list.push ' </testcase>'
|
||||||
|
end
|
||||||
|
|
||||||
|
# Test was flagged as having failed so format the line
|
||||||
|
def test_failed(array)
|
||||||
|
last_item = array.length - 1
|
||||||
|
test_name = array[last_item - 2]
|
||||||
|
reason = array[last_item].chomp + ' at line: ' + array[last_item - 3]
|
||||||
|
test_suite_verify(array[@class_name])
|
||||||
|
printf "%-40s FAILED\n", test_name
|
||||||
|
|
||||||
|
if test_name.start_with? 'TEST('
|
||||||
|
array2 = test_name.split(' ')
|
||||||
|
@test_suite = array2[0].sub('TEST(', '')
|
||||||
|
@test_suite = @test_suite.sub(',', '')
|
||||||
|
test_name = array2[1].sub(')', '')
|
||||||
|
end
|
||||||
|
|
||||||
|
return unless @xml_out
|
||||||
|
|
||||||
|
@array_list.push ' <testcase classname="' + @test_suite + '" name="' + test_name + '">'
|
||||||
|
@array_list.push ' <failure type="ASSERT FAILED"> ' + reason + ' </failure>'
|
||||||
|
@array_list.push ' </testcase>'
|
||||||
|
end
|
||||||
|
|
||||||
|
# Figure out what OS we are running on. For now we are assuming if it's not Windows it must
|
||||||
|
# be Unix based.
|
||||||
|
def detect_os
|
||||||
|
os = RUBY_PLATFORM.split('-')
|
||||||
|
@class_name = if os.size == 2
|
||||||
|
if os[1] == 'mingw32'
|
||||||
|
1
|
||||||
|
else
|
||||||
|
0
|
||||||
|
end
|
||||||
|
else
|
||||||
|
0
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Main function used to parse the file that was captured.
|
||||||
|
def process(name)
|
||||||
|
@test_flag = false
|
||||||
|
@array_list = []
|
||||||
|
|
||||||
|
detect_os
|
||||||
|
|
||||||
|
puts 'Parsing file: ' + name
|
||||||
|
|
||||||
|
test_pass = 0
|
||||||
|
test_fail = 0
|
||||||
|
test_ignore = 0
|
||||||
|
puts ''
|
||||||
|
puts '=================== RESULTS ====================='
|
||||||
|
puts ''
|
||||||
|
File.open(name).each do |line|
|
||||||
|
# Typical test lines look like this:
|
||||||
|
# <path>/<test_file>.c:36:test_tc1000_opsys:FAIL: Expected 1 Was 0
|
||||||
|
# <path>/<test_file>.c:112:test_tc5004_initCanChannel:IGNORE: Not Yet Implemented
|
||||||
|
# <path>/<test_file>.c:115:test_tc5100_initCanVoidPtrs:PASS
|
||||||
|
#
|
||||||
|
# where path is different on Unix vs Windows devices (Windows leads with a drive letter)
|
||||||
|
line_array = line.split(':')
|
||||||
|
|
||||||
|
# If we were able to split the line then we can look to see if any of our target words
|
||||||
|
# were found. Case is important.
|
||||||
|
if (line_array.size >= 4) || (line.start_with? 'TEST(')
|
||||||
|
# Determine if this test passed
|
||||||
|
if line.include? ':PASS'
|
||||||
|
test_passed(line_array)
|
||||||
|
test_pass += 1
|
||||||
|
elsif line.include? ':FAIL:'
|
||||||
|
test_failed(line_array)
|
||||||
|
test_fail += 1
|
||||||
|
elsif line.include? ':IGNORE:'
|
||||||
|
test_ignored(line_array)
|
||||||
|
test_ignore += 1
|
||||||
|
elsif line.start_with? 'TEST('
|
||||||
|
if line.include? ' PASS'
|
||||||
|
line_array = line.split(' ')
|
||||||
|
test_passed_unity_fixture(line_array)
|
||||||
|
test_pass += 1
|
||||||
|
end
|
||||||
|
# If none of the keywords are found there are no more tests for this suite so clear
|
||||||
|
# the test flag
|
||||||
|
else
|
||||||
|
@test_flag = false
|
||||||
|
end
|
||||||
|
else
|
||||||
|
@test_flag = false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
puts ''
|
||||||
|
puts '=================== SUMMARY ====================='
|
||||||
|
puts ''
|
||||||
|
puts 'Tests Passed : ' + test_pass.to_s
|
||||||
|
puts 'Tests Failed : ' + test_fail.to_s
|
||||||
|
puts 'Tests Ignored : ' + test_ignore.to_s
|
||||||
|
@total_tests = test_pass + test_fail + test_ignore
|
||||||
|
|
||||||
|
return unless @xml_out
|
||||||
|
|
||||||
|
heading = '<testsuite tests="' + @total_tests.to_s + '" failures="' + test_fail.to_s + '"' + ' skips="' + test_ignore.to_s + '">'
|
||||||
|
@array_list.insert(0, heading)
|
||||||
|
write_xml_output
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# If the command line has no values in, used a default value of Output.txt
|
||||||
|
parse_my_file = ParseOutput.new
|
||||||
|
|
||||||
|
if ARGV.size >= 1
|
||||||
|
ARGV.each do |a|
|
||||||
|
if a == '-xml'
|
||||||
|
parse_my_file.set_xml_output
|
||||||
|
else
|
||||||
|
parse_my_file.process(a)
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
@ -12,7 +12,6 @@ require 'pp'
|
|||||||
VERSION = 1.0
|
VERSION = 1.0
|
||||||
|
|
||||||
class ArgvParser
|
class ArgvParser
|
||||||
|
|
||||||
#
|
#
|
||||||
# Return a structure describing the options.
|
# Return a structure describing the options.
|
||||||
#
|
#
|
||||||
@ -20,41 +19,41 @@ class ArgvParser
|
|||||||
# The options specified on the command line will be collected in *options*.
|
# The options specified on the command line will be collected in *options*.
|
||||||
# We set default values here.
|
# We set default values here.
|
||||||
options = OpenStruct.new
|
options = OpenStruct.new
|
||||||
options.results_dir = "."
|
options.results_dir = '.'
|
||||||
options.root_path = "."
|
options.root_path = '.'
|
||||||
options.out_file = "results.xml"
|
options.out_file = 'results.xml'
|
||||||
|
|
||||||
opts = OptionParser.new do |opts|
|
opts = OptionParser.new do |o|
|
||||||
opts.banner = "Usage: unity_to_junit.rb [options]"
|
o.banner = 'Usage: unity_to_junit.rb [options]'
|
||||||
|
|
||||||
opts.separator ""
|
o.separator ''
|
||||||
opts.separator "Specific options:"
|
o.separator 'Specific options:'
|
||||||
|
|
||||||
opts.on("-r", "--results <dir>", "Look for Unity Results files here.") do |results|
|
o.on('-r', '--results <dir>', 'Look for Unity Results files here.') do |results|
|
||||||
#puts "results #{results}"
|
# puts "results #{results}"
|
||||||
options.results_dir = results
|
options.results_dir = results
|
||||||
end
|
end
|
||||||
|
|
||||||
opts.on("-p", "--root_path <path>", "Prepend this path to files in results.") do |root_path|
|
o.on('-p', '--root_path <path>', 'Prepend this path to files in results.') do |root_path|
|
||||||
options.root_path = root_path
|
options.root_path = root_path
|
||||||
end
|
end
|
||||||
|
|
||||||
opts.on("-o", "--output <filename>", "XML file to generate.") do |out_file|
|
o.on('-o', '--output <filename>', 'XML file to generate.') do |out_file|
|
||||||
#puts "out_file: #{out_file}"
|
# puts "out_file: #{out_file}"
|
||||||
options.out_file = out_file
|
options.out_file = out_file
|
||||||
end
|
end
|
||||||
|
|
||||||
opts.separator ""
|
o.separator ''
|
||||||
opts.separator "Common options:"
|
o.separator 'Common options:'
|
||||||
|
|
||||||
# No argument, shows at tail. This will print an options summary.
|
# No argument, shows at tail. This will print an options summary.
|
||||||
opts.on_tail("-h", "--help", "Show this message") do
|
o.on_tail('-h', '--help', 'Show this message') do
|
||||||
puts opts
|
puts o
|
||||||
exit
|
exit
|
||||||
end
|
end
|
||||||
|
|
||||||
# Another typical switch to print the version.
|
# Another typical switch to print the version.
|
||||||
opts.on_tail("--version", "Show version") do
|
o.on_tail('--version', 'Show version') do
|
||||||
puts "unity_to_junit.rb version #{VERSION}"
|
puts "unity_to_junit.rb version #{VERSION}"
|
||||||
exit
|
exit
|
||||||
end
|
end
|
||||||
@ -62,13 +61,13 @@ class ArgvParser
|
|||||||
|
|
||||||
opts.parse!(args)
|
opts.parse!(args)
|
||||||
options
|
options
|
||||||
end # parse()
|
end # parse()
|
||||||
|
end # class OptparseExample
|
||||||
end # class OptparseExample
|
|
||||||
|
|
||||||
class UnityToJUnit
|
class UnityToJUnit
|
||||||
include FileUtils::Verbose
|
include FileUtils::Verbose
|
||||||
attr_reader :report, :total_tests, :failures, :ignored
|
attr_reader :report, :total_tests, :failures, :ignored
|
||||||
|
attr_writer :targets, :root, :out_file
|
||||||
|
|
||||||
def initialize
|
def initialize
|
||||||
@report = ''
|
@report = ''
|
||||||
@ -77,125 +76,115 @@ class UnityToJUnit
|
|||||||
|
|
||||||
def run
|
def run
|
||||||
# Clean up result file names
|
# Clean up result file names
|
||||||
results = @targets.map {|target| target.gsub(/\\/,"/")}
|
results = @targets.map { |target| target.tr('\\', '/') }
|
||||||
#puts "Output File: #{@out_file}"
|
# puts "Output File: #{@out_file}"
|
||||||
f = File.new(@out_file, "w")
|
f = File.new(@out_file, 'w')
|
||||||
write_xml_header(f)
|
write_xml_header(f)
|
||||||
write_suites_header( f )
|
write_suites_header(f)
|
||||||
results.each do |result_file|
|
results.each do |result_file|
|
||||||
lines = File.readlines(result_file).map { |line| line.chomp }
|
lines = File.readlines(result_file).map(&:chomp)
|
||||||
if lines.length == 0
|
|
||||||
raise "Empty test result file: #{result_file}"
|
raise "Empty test result file: #{result_file}" if lines.empty?
|
||||||
else
|
|
||||||
result_output = get_details(result_file, lines)
|
result_output = get_details(result_file, lines)
|
||||||
tests,failures,ignored = parse_test_summary(lines)
|
tests, failures, ignored = parse_test_summary(lines)
|
||||||
result_output[:counts][:total] = tests
|
result_output[:counts][:total] = tests
|
||||||
result_output[:counts][:failed] = failures
|
result_output[:counts][:failed] = failures
|
||||||
result_output[:counts][:ignored] = ignored
|
result_output[:counts][:ignored] = ignored
|
||||||
result_output[:counts][:passed] = (result_output[:counts][:total] - result_output[:counts][:failed] - result_output[:counts][:ignored])
|
result_output[:counts][:passed] = (result_output[:counts][:total] - result_output[:counts][:failed] - result_output[:counts][:ignored])
|
||||||
end
|
|
||||||
#use line[0] from the test output to get the test_file path and name
|
# use line[0] from the test output to get the test_file path and name
|
||||||
test_file_str = lines[0].gsub("\\","/")
|
test_file_str = lines[0].tr('\\', '/')
|
||||||
test_file_str = test_file_str.split(":")
|
test_file_str = test_file_str.split(':')
|
||||||
test_file = if (test_file_str.length < 2)
|
test_file = if test_file_str.length < 2
|
||||||
result_file
|
result_file
|
||||||
else
|
else
|
||||||
test_file_str[0] + ':' + test_file_str[1]
|
test_file_str[0] + ':' + test_file_str[1]
|
||||||
end
|
end
|
||||||
result_output[:source][:path] = File.dirname(test_file)
|
result_output[:source][:path] = File.dirname(test_file)
|
||||||
result_output[:source][:file] = File.basename(test_file)
|
result_output[:source][:file] = File.basename(test_file)
|
||||||
|
|
||||||
# save result_output
|
# save result_output
|
||||||
@unit_name = File.basename(test_file, ".*")
|
@unit_name = File.basename(test_file, '.*')
|
||||||
|
|
||||||
write_suite_header( result_output[:counts], f)
|
write_suite_header(result_output[:counts], f)
|
||||||
write_failures( result_output, f )
|
write_failures(result_output, f)
|
||||||
write_tests( result_output, f )
|
write_tests(result_output, f)
|
||||||
write_ignored( result_output, f )
|
write_ignored(result_output, f)
|
||||||
write_suite_footer( f )
|
write_suite_footer(f)
|
||||||
end
|
end
|
||||||
write_suites_footer( f )
|
write_suites_footer(f)
|
||||||
f.close
|
f.close
|
||||||
end
|
end
|
||||||
|
|
||||||
def set_targets(target_array)
|
def usage(err_msg = nil)
|
||||||
@targets = target_array
|
|
||||||
end
|
|
||||||
|
|
||||||
def set_root_path(path)
|
|
||||||
@root = path
|
|
||||||
end
|
|
||||||
def set_out_file(filename)
|
|
||||||
@out_file = filename
|
|
||||||
end
|
|
||||||
def usage(err_msg=nil)
|
|
||||||
puts "\nERROR: "
|
puts "\nERROR: "
|
||||||
puts err_msg if err_msg
|
puts err_msg if err_msg
|
||||||
puts "Usage: unity_to_junit.rb [options]"
|
puts 'Usage: unity_to_junit.rb [options]'
|
||||||
puts ""
|
puts ''
|
||||||
puts "Specific options:"
|
puts 'Specific options:'
|
||||||
puts " -r, --results <dir> Look for Unity Results files here."
|
puts ' -r, --results <dir> Look for Unity Results files here.'
|
||||||
puts " -p, --root_path <path> Prepend this path to files in results."
|
puts ' -p, --root_path <path> Prepend this path to files in results.'
|
||||||
puts " -o, --output <filename> XML file to generate."
|
puts ' -o, --output <filename> XML file to generate.'
|
||||||
puts ""
|
puts ''
|
||||||
puts "Common options:"
|
puts 'Common options:'
|
||||||
puts " -h, --help Show this message"
|
puts ' -h, --help Show this message'
|
||||||
puts " --version Show version"
|
puts ' --version Show version'
|
||||||
|
|
||||||
exit 1
|
exit 1
|
||||||
end
|
end
|
||||||
|
|
||||||
protected
|
protected
|
||||||
def get_details(result_file, lines)
|
|
||||||
results = get_results_structure
|
def get_details(_result_file, lines)
|
||||||
|
results = results_structure
|
||||||
lines.each do |line|
|
lines.each do |line|
|
||||||
line = line.gsub("\\","/")
|
line = line.tr('\\', '/')
|
||||||
src_file,src_line,test_name,status,msg = line.split(/:/)
|
_src_file, src_line, test_name, status, msg = line.split(/:/)
|
||||||
line_out = ((@root and (@root != 0)) ? "#{@root}#{line}" : line ).gsub(/\//, "\\")
|
case status
|
||||||
case(status)
|
when 'IGNORE' then results[:ignores] << { test: test_name, line: src_line, message: msg }
|
||||||
when 'IGNORE' then results[:ignores] << {:test => test_name, :line => src_line, :message => msg}
|
when 'FAIL' then results[:failures] << { test: test_name, line: src_line, message: msg }
|
||||||
when 'FAIL' then results[:failures] << {:test => test_name, :line => src_line, :message => msg}
|
when 'PASS' then results[:successes] << { test: test_name, line: src_line, message: msg }
|
||||||
when 'PASS' then results[:successes] << {:test => test_name, :line => src_line, :message => msg}
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return results
|
results
|
||||||
end
|
end
|
||||||
|
|
||||||
def parse_test_summary(summary)
|
def parse_test_summary(summary)
|
||||||
if summary.find { |v| v =~ /(\d+) Tests (\d+) Failures (\d+) Ignored/ }
|
raise "Couldn't parse test results: #{summary}" unless summary.find { |v| v =~ /(\d+) Tests (\d+) Failures (\d+) Ignored/ }
|
||||||
[$1.to_i,$2.to_i,$3.to_i]
|
[Regexp.last_match(1).to_i, Regexp.last_match(2).to_i, Regexp.last_match(3).to_i]
|
||||||
else
|
end
|
||||||
raise "Couldn't parse test results: #{summary}"
|
|
||||||
end
|
def here
|
||||||
|
File.expand_path(File.dirname(__FILE__))
|
||||||
end
|
end
|
||||||
def here; File.expand_path(File.dirname(__FILE__)); end
|
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def get_results_structure
|
def results_structure
|
||||||
return {
|
{
|
||||||
:source => {:path => '', :file => ''},
|
source: { path: '', file: '' },
|
||||||
:successes => [],
|
successes: [],
|
||||||
:failures => [],
|
failures: [],
|
||||||
:ignores => [],
|
ignores: [],
|
||||||
:counts => {:total => 0, :passed => 0, :failed => 0, :ignored => 0},
|
counts: { total: 0, passed: 0, failed: 0, ignored: 0 },
|
||||||
:stdout => [],
|
stdout: []
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
def write_xml_header( stream )
|
def write_xml_header(stream)
|
||||||
stream.puts "<?xml version='1.0' encoding='utf-8' ?>"
|
stream.puts "<?xml version='1.0' encoding='utf-8' ?>"
|
||||||
end
|
end
|
||||||
|
|
||||||
def write_suites_header( stream )
|
def write_suites_header(stream)
|
||||||
stream.puts "<testsuites>"
|
stream.puts '<testsuites>'
|
||||||
end
|
end
|
||||||
|
|
||||||
def write_suite_header( counts, stream )
|
def write_suite_header(counts, stream)
|
||||||
stream.puts "\t<testsuite errors=\"0\" skipped=\"#{counts[:ignored]}\" failures=\"#{counts[:failed]}\" tests=\"#{counts[:total]}\" name=\"unity\">"
|
stream.puts "\t<testsuite errors=\"0\" skipped=\"#{counts[:ignored]}\" failures=\"#{counts[:failed]}\" tests=\"#{counts[:total]}\" name=\"unity\">"
|
||||||
end
|
end
|
||||||
|
|
||||||
def write_failures( results, stream )
|
def write_failures(results, stream)
|
||||||
result = results[:failures]
|
result = results[:failures]
|
||||||
result.each do |item|
|
result.each do |item|
|
||||||
filename = File.join(results[:source][:path], File.basename(results[:source][:file], '.*'))
|
filename = File.join(results[:source][:path], File.basename(results[:source][:file], '.*'))
|
||||||
@ -206,15 +195,14 @@ class UnityToJUnit
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def write_tests( results, stream )
|
def write_tests(results, stream)
|
||||||
result = results[:successes]
|
result = results[:successes]
|
||||||
result.each do |item|
|
result.each do |item|
|
||||||
filename = File.join(results[:source][:path], File.basename(results[:source][:file], '.*'))
|
|
||||||
stream.puts "\t\t<testcase classname=\"#{@unit_name}\" name=\"#{item[:test]}\" time=\"0\" />"
|
stream.puts "\t\t<testcase classname=\"#{@unit_name}\" name=\"#{item[:test]}\" time=\"0\" />"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def write_ignored( results, stream )
|
def write_ignored(results, stream)
|
||||||
result = results[:ignores]
|
result = results[:ignores]
|
||||||
result.each do |item|
|
result.each do |item|
|
||||||
filename = File.join(results[:source][:path], File.basename(results[:source][:file], '.*'))
|
filename = File.join(results[:source][:path], File.basename(results[:source][:file], '.*'))
|
||||||
@ -226,39 +214,39 @@ class UnityToJUnit
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def write_suite_footer( stream )
|
def write_suite_footer(stream)
|
||||||
stream.puts "\t</testsuite>"
|
stream.puts "\t</testsuite>"
|
||||||
end
|
end
|
||||||
|
|
||||||
def write_suites_footer( stream )
|
def write_suites_footer(stream)
|
||||||
stream.puts "</testsuites>"
|
stream.puts '</testsuites>'
|
||||||
end
|
end
|
||||||
end #UnityToJUnit
|
end # UnityToJUnit
|
||||||
|
|
||||||
if __FILE__ == $0
|
if __FILE__ == $0
|
||||||
#parse out the command options
|
# parse out the command options
|
||||||
options = ArgvParser.parse(ARGV)
|
options = ArgvParser.parse(ARGV)
|
||||||
|
|
||||||
#create an instance to work with
|
# create an instance to work with
|
||||||
utj = UnityToJUnit.new
|
utj = UnityToJUnit.new
|
||||||
begin
|
begin
|
||||||
#look in the specified or current directory for result files
|
# look in the specified or current directory for result files
|
||||||
targets = "#{options.results_dir.gsub(/\\/, '/')}**/*.test*"
|
targets = "#{options.results_dir.tr('\\', '/')}**/*.test*"
|
||||||
|
|
||||||
results = Dir[targets]
|
results = Dir[targets]
|
||||||
raise "No *.testpass, *.testfail, or *.testresults files found in '#{targets}'" if results.empty?
|
raise "No *.testpass, *.testfail, or *.testresults files found in '#{targets}'" if results.empty?
|
||||||
utj.set_targets(results)
|
utj.targets = results
|
||||||
|
|
||||||
#set the root path
|
# set the root path
|
||||||
utj.set_root_path(options.root_path)
|
utj.root = options.root_path
|
||||||
|
|
||||||
#set the output XML file name
|
# set the output XML file name
|
||||||
#puts "Output File from options: #{options.out_file}"
|
# puts "Output File from options: #{options.out_file}"
|
||||||
utj.set_out_file(options.out_file)
|
utj.out_file = options.out_file
|
||||||
|
|
||||||
#run the summarizer
|
# run the summarizer
|
||||||
puts utj.run
|
puts utj.run
|
||||||
rescue Exception => e
|
rescue StandardError => e
|
||||||
utj.usage e.message
|
utj.usage e.message
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
# Unity Project - A Test Framework for C
|
# Unity Project - A Test Framework for C
|
||||||
# Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams
|
# Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams
|
||||||
# [Released under MIT License. Please refer to license.txt for details]
|
# [Released under MIT License. Please refer to license.txt for details]
|
||||||
# ==========================================
|
# ==========================================
|
||||||
|
|
||||||
require'yaml'
|
require'yaml'
|
||||||
|
|
||||||
@ -10,14 +10,16 @@ module RakefileHelpers
|
|||||||
class TestFileFilter
|
class TestFileFilter
|
||||||
def initialize(all_files = false)
|
def initialize(all_files = false)
|
||||||
@all_files = all_files
|
@all_files = all_files
|
||||||
if not @all_files == true
|
|
||||||
if File.exist?('test_file_filter.yml')
|
return false unless @all_files
|
||||||
filters = YAML.load_file( 'test_file_filter.yml' )
|
return false unless File.exist?('test_file_filter.yml')
|
||||||
@all_files, @only_files, @exclude_files =
|
|
||||||
filters[:all_files], filters[:only_files], filters[:exclude_files]
|
filters = YAML.load_file('test_file_filter.yml')
|
||||||
end
|
@all_files = filters[:all_files]
|
||||||
end
|
@only_files = filters[:only_files]
|
||||||
end
|
@exclude_files = filters[:exclude_files]
|
||||||
|
end
|
||||||
|
|
||||||
attr_accessor :all_files, :only_files, :exclude_files
|
attr_accessor :all_files, :only_files, :exclude_files
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
module TypeSanitizer
|
module TypeSanitizer
|
||||||
|
|
||||||
def self.sanitize_c_identifier(unsanitized)
|
def self.sanitize_c_identifier(unsanitized)
|
||||||
# convert filename to valid C identifier by replacing invalid chars with '_'
|
# convert filename to valid C identifier by replacing invalid chars with '_'
|
||||||
return unsanitized.gsub(/[-\/\\\.\,\s]/, "_")
|
unsanitized.gsub(/[-\/\\\.\,\s]/, '_')
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
# [Released under MIT License. Please refer to license.txt for details]
|
# [Released under MIT License. Please refer to license.txt for details]
|
||||||
# ==========================================
|
# ==========================================
|
||||||
|
|
||||||
#!/usr/bin/ruby
|
# !/usr/bin/ruby
|
||||||
#
|
#
|
||||||
# unity_test_summary.rb
|
# unity_test_summary.rb
|
||||||
#
|
#
|
||||||
@ -15,37 +15,35 @@ class UnityTestSummary
|
|||||||
include FileUtils::Verbose
|
include FileUtils::Verbose
|
||||||
|
|
||||||
attr_reader :report, :total_tests, :failures, :ignored
|
attr_reader :report, :total_tests, :failures, :ignored
|
||||||
|
attr_writer :targets, :root
|
||||||
|
|
||||||
def initialize(opts = {})
|
def initialize(_opts = {})
|
||||||
@report = ''
|
@report = ''
|
||||||
@total_tests = 0
|
@total_tests = 0
|
||||||
@failures = 0
|
@failures = 0
|
||||||
@ignored = 0
|
@ignored = 0
|
||||||
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def run
|
def run
|
||||||
# Clean up result file names
|
# Clean up result file names
|
||||||
results = @targets.map {|target| target.gsub(/\\/,'/')}
|
results = @targets.map { |target| target.tr('\\', '/') }
|
||||||
|
|
||||||
# Dig through each result file, looking for details on pass/fail:
|
# Dig through each result file, looking for details on pass/fail:
|
||||||
failure_output = []
|
failure_output = []
|
||||||
ignore_output = []
|
ignore_output = []
|
||||||
|
|
||||||
results.each do |result_file|
|
results.each do |result_file|
|
||||||
lines = File.readlines(result_file).map { |line| line.chomp }
|
lines = File.readlines(result_file).map(&:chomp)
|
||||||
if lines.length == 0
|
|
||||||
raise "Empty test result file: #{result_file}"
|
raise "Empty test result file: #{result_file}" if lines.empty?
|
||||||
else
|
|
||||||
output = get_details(result_file, lines)
|
output = get_details(result_file, lines)
|
||||||
failure_output << output[:failures] unless output[:failures].empty?
|
failure_output << output[:failures] unless output[:failures].empty?
|
||||||
ignore_output << output[:ignores] unless output[:ignores].empty?
|
ignore_output << output[:ignores] unless output[:ignores].empty?
|
||||||
tests,failures,ignored = parse_test_summary(lines)
|
tests, failures, ignored = parse_test_summary(lines)
|
||||||
@total_tests += tests
|
@total_tests += tests
|
||||||
@failures += failures
|
@failures += failures
|
||||||
@ignored += ignored
|
@ignored += ignored
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
if @ignored > 0
|
if @ignored > 0
|
||||||
@ -72,77 +70,67 @@ class UnityTestSummary
|
|||||||
@report += "\n"
|
@report += "\n"
|
||||||
end
|
end
|
||||||
|
|
||||||
def set_targets(target_array)
|
def usage(err_msg = nil)
|
||||||
@targets = target_array
|
|
||||||
end
|
|
||||||
|
|
||||||
def set_root_path(path)
|
|
||||||
@root = path
|
|
||||||
end
|
|
||||||
|
|
||||||
def usage(err_msg=nil)
|
|
||||||
puts "\nERROR: "
|
puts "\nERROR: "
|
||||||
puts err_msg if err_msg
|
puts err_msg if err_msg
|
||||||
puts "\nUsage: unity_test_summary.rb result_file_directory/ root_path/"
|
puts "\nUsage: unity_test_summary.rb result_file_directory/ root_path/"
|
||||||
puts " result_file_directory - The location of your results files."
|
puts ' result_file_directory - The location of your results files.'
|
||||||
puts " Defaults to current directory if not specified."
|
puts ' Defaults to current directory if not specified.'
|
||||||
puts " Should end in / if specified."
|
puts ' Should end in / if specified.'
|
||||||
puts " root_path - Helpful for producing more verbose output if using relative paths."
|
puts ' root_path - Helpful for producing more verbose output if using relative paths.'
|
||||||
exit 1
|
exit 1
|
||||||
end
|
end
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
|
||||||
def get_details(result_file, lines)
|
def get_details(_result_file, lines)
|
||||||
results = { :failures => [], :ignores => [], :successes => [] }
|
results = { failures: [], ignores: [], successes: [] }
|
||||||
lines.each do |line|
|
lines.each do |line|
|
||||||
src_file,src_line,test_name,status,msg = line.split(/:/)
|
_src_file, _src_line, _test_name, status, _msg = line.split(/:/)
|
||||||
line_out = ((@root && (@root != 0)) ? "#{@root}#{line}" : line ).gsub(/\//, "\\")
|
line_out = (@root && (@root != 0) ? "#{@root}#{line}" : line).gsub(/\//, '\\')
|
||||||
case(status)
|
case status
|
||||||
when 'IGNORE' then results[:ignores] << line_out
|
when 'IGNORE' then results[:ignores] << line_out
|
||||||
when 'FAIL' then results[:failures] << line_out
|
when 'FAIL' then results[:failures] << line_out
|
||||||
when 'PASS' then results[:successes] << line_out
|
when 'PASS' then results[:successes] << line_out
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return results
|
results
|
||||||
end
|
end
|
||||||
|
|
||||||
def parse_test_summary(summary)
|
def parse_test_summary(summary)
|
||||||
if summary.find { |v| v =~ /(\d+) Tests (\d+) Failures (\d+) Ignored/ }
|
raise "Couldn't parse test results: #{summary}" unless summary.find { |v| v =~ /(\d+) Tests (\d+) Failures (\d+) Ignored/ }
|
||||||
[$1.to_i,$2.to_i,$3.to_i]
|
[Regexp.last_match(1).to_i, Regexp.last_match(2).to_i, Regexp.last_match(3).to_i]
|
||||||
else
|
|
||||||
raise "Couldn't parse test results: #{summary}"
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def here; File.expand_path(File.dirname(__FILE__)); end
|
def here
|
||||||
|
File.expand_path(File.dirname(__FILE__))
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if $0 == __FILE__
|
if $0 == __FILE__
|
||||||
|
|
||||||
#parse out the command options
|
# parse out the command options
|
||||||
opts, args = ARGV.partition {|v| v =~ /^--\w+/}
|
opts, args = ARGV.partition { |v| v =~ /^--\w+/ }
|
||||||
opts.map! {|v| v[2..-1].to_sym }
|
opts.map! { |v| v[2..-1].to_sym }
|
||||||
|
|
||||||
#create an instance to work with
|
# create an instance to work with
|
||||||
uts = UnityTestSummary.new(opts)
|
uts = UnityTestSummary.new(opts)
|
||||||
|
|
||||||
begin
|
begin
|
||||||
#look in the specified or current directory for result files
|
# look in the specified or current directory for result files
|
||||||
args[0] ||= './'
|
args[0] ||= './'
|
||||||
targets = "#{ARGV[0].gsub(/\\/, '/')}**/*.test*"
|
targets = "#{ARGV[0].tr('\\', '/')}**/*.test*"
|
||||||
results = Dir[targets]
|
results = Dir[targets]
|
||||||
raise "No *.testpass, *.testfail, or *.testresults files found in '#{targets}'" if results.empty?
|
raise "No *.testpass, *.testfail, or *.testresults files found in '#{targets}'" if results.empty?
|
||||||
uts.set_targets(results)
|
uts.targets = results
|
||||||
|
|
||||||
#set the root path
|
# set the root path
|
||||||
args[1] ||= Dir.pwd + '/'
|
args[1] ||= Dir.pwd + '/'
|
||||||
uts.set_root_path(ARGV[1])
|
uts.root = ARGV[1]
|
||||||
|
|
||||||
#run the summarizer
|
# run the summarizer
|
||||||
puts uts.run
|
puts uts.run
|
||||||
rescue Exception => e
|
rescue StandardError => e
|
||||||
uts.usage e.message
|
uts.usage e.message
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
207
tests/unity/docs/ThrowTheSwitchCodingStandard.md
Normal file
207
tests/unity/docs/ThrowTheSwitchCodingStandard.md
Normal file
@ -0,0 +1,207 @@
|
|||||||
|
# ThrowTheSwitch.org Coding Standard
|
||||||
|
|
||||||
|
Hi. Welcome to the coding standard for ThrowTheSwitch.org. For the most part,
|
||||||
|
we try to follow these standards to unify our contributors' code into a cohesive
|
||||||
|
unit (puns intended). You might find places where these standards aren't
|
||||||
|
followed. We're not perfect. Please be polite where you notice these discrepancies
|
||||||
|
and we'll try to be polite when we notice yours.
|
||||||
|
|
||||||
|
;)
|
||||||
|
|
||||||
|
|
||||||
|
## Why Have A Coding Standard?
|
||||||
|
|
||||||
|
Being consistent makes code easier to understand. We've made an attempt to keep
|
||||||
|
our standard simple because we also believe that we can only expect someone to
|
||||||
|
follow something that is understandable. Please do your best.
|
||||||
|
|
||||||
|
|
||||||
|
## Our Philosophy
|
||||||
|
|
||||||
|
Before we get into details on syntax, let's take a moment to talk about our
|
||||||
|
vision for these tools. We're C developers and embedded software developers.
|
||||||
|
These tools are great to test any C code, but catering to embedded software has
|
||||||
|
made us more tolerant of compiler quirks. There are a LOT of quirky compilers
|
||||||
|
out there. By quirky I mean "doesn't follow standards because they feel like
|
||||||
|
they have a license to do as they wish."
|
||||||
|
|
||||||
|
Our philosophy is "support every compiler we can". Most often, this means that
|
||||||
|
we aim for writing C code that is standards compliant (often C89... that seems
|
||||||
|
to be a sweet spot that is almost always compatible). But it also means these
|
||||||
|
tools are tolerant of things that aren't common. Some that aren't even
|
||||||
|
compliant. There are configuration options to override the size of standard
|
||||||
|
types. There are configuration options to force Unity to not use certain
|
||||||
|
standard library functions. A lot of Unity is configurable and we have worked
|
||||||
|
hard to make it not TOO ugly in the process.
|
||||||
|
|
||||||
|
Similarly, our tools that parse C do their best. They aren't full C parsers
|
||||||
|
(yet) and, even if they were, they would still have to accept non-standard
|
||||||
|
additions like gcc extensions or specifying `@0x1000` to force a variable to
|
||||||
|
compile to a particular location. It's just what we do, because we like
|
||||||
|
everything to Just Work™.
|
||||||
|
|
||||||
|
Speaking of having things Just Work™, that's our second philosophy. By that, we
|
||||||
|
mean that we do our best to have EVERY configuration option have a logical
|
||||||
|
default. We believe that if you're working with a simple compiler and target,
|
||||||
|
you shouldn't need to configure very much... we try to make the tools guess as
|
||||||
|
much as they can, but give the user the power to override it when it's wrong.
|
||||||
|
|
||||||
|
|
||||||
|
## Naming Things
|
||||||
|
|
||||||
|
Let's talk about naming things. Programming is all about naming things. We name
|
||||||
|
files, functions, variables, and so much more. While we're not always going to
|
||||||
|
find the best name for something, we actually put quite a bit of effort into
|
||||||
|
finding *What Something WANTS to be Called*™.
|
||||||
|
|
||||||
|
When naming things, we more or less follow this hierarchy, the first being the
|
||||||
|
most important to us (but we do all four whenever possible):
|
||||||
|
1. Readable
|
||||||
|
2. Descriptive
|
||||||
|
3. Consistent
|
||||||
|
4. Memorable
|
||||||
|
|
||||||
|
|
||||||
|
#### Readable
|
||||||
|
|
||||||
|
We want to read our code. This means we like names and flow that are more
|
||||||
|
naturally read. We try to avoid double negatives. We try to avoid cryptic
|
||||||
|
abbreviations (sticking to ones we feel are common).
|
||||||
|
|
||||||
|
|
||||||
|
#### Descriptive
|
||||||
|
|
||||||
|
We like descriptive names for things, especially functions and variables.
|
||||||
|
Finding the right name for something is an important endeavor. You might notice
|
||||||
|
from poking around our code that this often results in names that are a little
|
||||||
|
longer than the average. Guilty. We're okay with a tiny bit more typing if it
|
||||||
|
means our code is easier to understand.
|
||||||
|
|
||||||
|
There are two exceptions to this rule that we also stick to as religiously as
|
||||||
|
possible:
|
||||||
|
|
||||||
|
First, while we realize hungarian notation (and similar systems for encoding
|
||||||
|
type information into variable names) is providing a more descriptive name, we
|
||||||
|
feel that (for the average developer) it takes away from readability and
|
||||||
|
therefore is to be avoided.
|
||||||
|
|
||||||
|
Second, loop counters and other local throw-away variables often have a purpose
|
||||||
|
which is obvious. There's no need, therefore, to get carried away with complex
|
||||||
|
naming. We find i, j, and k are better loop counters than loopCounterVar or
|
||||||
|
whatnot. We only break this rule when we see that more description could improve
|
||||||
|
understanding of an algorithm.
|
||||||
|
|
||||||
|
|
||||||
|
#### Consistent
|
||||||
|
|
||||||
|
We like consistency, but we're not really obsessed with it. We try to name our
|
||||||
|
configuration macros in a consistent fashion... you'll notice a repeated use of
|
||||||
|
UNITY_EXCLUDE_BLAH or UNITY_USES_BLAH macros. This helps users avoid having to
|
||||||
|
remember each macro's details.
|
||||||
|
|
||||||
|
|
||||||
|
#### Memorable
|
||||||
|
|
||||||
|
Where ever it doesn't violate the above principles, we try to apply memorable
|
||||||
|
names. Sometimes this means using something that is simply descriptive, but
|
||||||
|
often we strive for descriptive AND unique... we like quirky names that stand
|
||||||
|
out in our memory and are easier to search for. Take a look through the file
|
||||||
|
names in Ceedling and you'll get a good idea of what we are talking about here.
|
||||||
|
Why use preprocess when you can use preprocessinator? Or what better describes a
|
||||||
|
module in charge of invoking tasks during releases than release_invoker? Don't
|
||||||
|
get carried away. The names are still descriptive and fulfill the above
|
||||||
|
requirements, but they don't feel stale.
|
||||||
|
|
||||||
|
|
||||||
|
## C and C++ Details
|
||||||
|
|
||||||
|
We don't really want to add to the style battles out there. Tabs or spaces?
|
||||||
|
How many spaces? Where do the braces go? These are age-old questions that will
|
||||||
|
never be answered... or at least not answered in a way that will make everyone
|
||||||
|
happy.
|
||||||
|
|
||||||
|
We've decided on our own style preferences. If you'd like to contribute to these
|
||||||
|
projects (and we hope that you do), then we ask if you do your best to follow
|
||||||
|
the same. It will only hurt a little. We promise.
|
||||||
|
|
||||||
|
|
||||||
|
#### Whitespace
|
||||||
|
|
||||||
|
Our C-style is to use spaces and to use 4 of them per indent level. It's a nice
|
||||||
|
power-of-2 number that looks decent on a wide screen. We have no more reason
|
||||||
|
than that. We break that rule when we have lines that wrap (macros or function
|
||||||
|
arguments or whatnot). When that happens, we like to indent further to line
|
||||||
|
things up in nice tidy columns.
|
||||||
|
|
||||||
|
```C
|
||||||
|
if (stuff_happened)
|
||||||
|
{
|
||||||
|
do_something();
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
#### Case
|
||||||
|
|
||||||
|
- Files - all lower case with underscores.
|
||||||
|
- Variables - all lower case with underscores
|
||||||
|
- Macros - all caps with underscores.
|
||||||
|
- Typedefs - all caps with underscores. (also ends with _T).
|
||||||
|
- Functions - camel cased. Usually named ModuleName_FuncName
|
||||||
|
- Constants and Globals - camel cased.
|
||||||
|
|
||||||
|
|
||||||
|
#### Braces
|
||||||
|
|
||||||
|
The left brace is on the next line after the declaration. The right brace is
|
||||||
|
directly below that. Everything in between in indented one level. If you're
|
||||||
|
catching an error and you have a one-line, go ahead and to it on the same line.
|
||||||
|
|
||||||
|
```C
|
||||||
|
while (blah)
|
||||||
|
{
|
||||||
|
//Like so. Even if only one line, we use braces.
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
#### Comments
|
||||||
|
|
||||||
|
Do you know what we hate? Old-school C block comments. BUT, we're using them
|
||||||
|
anyway. As we mentioned, our goal is to support every compiler we can,
|
||||||
|
especially embedded compilers. There are STILL C compilers out there that only
|
||||||
|
support old-school block comments. So that is what we're using. We apologize. We
|
||||||
|
think they are ugly too.
|
||||||
|
|
||||||
|
|
||||||
|
## Ruby Details
|
||||||
|
|
||||||
|
Is there really such thing as a Ruby coding standard? Ruby is such a free form
|
||||||
|
language, it seems almost sacrilegious to suggest that people should comply to
|
||||||
|
one method! We'll keep it really brief!
|
||||||
|
|
||||||
|
|
||||||
|
#### Whitespace
|
||||||
|
|
||||||
|
Our Ruby style is to use spaces and to use 2 of them per indent level. It's a
|
||||||
|
nice power-of-2 number that really grooves with Ruby's compact style. We have no
|
||||||
|
more reason than that. We break that rule when we have lines that wrap. When
|
||||||
|
that happens, we like to indent further to line things up in nice tidy columns.
|
||||||
|
|
||||||
|
|
||||||
|
#### Case
|
||||||
|
|
||||||
|
- Files - all lower case with underscores.
|
||||||
|
- Variables - all lower case with underscores
|
||||||
|
- Classes, Modules, etc - Camel cased.
|
||||||
|
- Functions - all lower case with underscores
|
||||||
|
- Constants - all upper case with underscores
|
||||||
|
|
||||||
|
|
||||||
|
## Documentation
|
||||||
|
|
||||||
|
Egad. Really? We use markdown and we like pdf files because they can be made to
|
||||||
|
look nice while still being portable. Good enough?
|
||||||
|
|
||||||
|
|
||||||
|
*Find The Latest of This And More at [ThrowTheSwitch.org](https://throwtheswitch.org)*
|
Binary file not shown.
716
tests/unity/docs/UnityAssertionsReference.md
Normal file
716
tests/unity/docs/UnityAssertionsReference.md
Normal file
@ -0,0 +1,716 @@
|
|||||||
|
# Unity Assertions Reference
|
||||||
|
|
||||||
|
## Background and Overview
|
||||||
|
|
||||||
|
### Super Condensed Version
|
||||||
|
|
||||||
|
- An assertion establishes truth (i.e. boolean True) for a single condition.
|
||||||
|
Upon boolean False, an assertion stops execution and reports the failure.
|
||||||
|
- Unity is mainly a rich collection of assertions and the support to gather up
|
||||||
|
and easily execute those assertions.
|
||||||
|
- The structure of Unity allows you to easily separate test assertions from
|
||||||
|
source code in, well, test code.
|
||||||
|
- Unity's assertions:
|
||||||
|
- Come in many, many flavors to handle different C types and assertion cases.
|
||||||
|
- Use context to provide detailed and helpful failure messages.
|
||||||
|
- Document types, expected values, and basic behavior in your source code for
|
||||||
|
free.
|
||||||
|
|
||||||
|
|
||||||
|
### Unity Is Several Things But Mainly It's Assertions
|
||||||
|
|
||||||
|
One way to think of Unity is simply as a rich collection of assertions you can
|
||||||
|
use to establish whether your source code behaves the way you think it does.
|
||||||
|
Unity provides a framework to easily organize and execute those assertions in
|
||||||
|
test code separate from your source code.
|
||||||
|
|
||||||
|
|
||||||
|
### What's an Assertion?
|
||||||
|
|
||||||
|
At their core, assertions are an establishment of truth - boolean truth. Was this
|
||||||
|
thing equal to that thing? Does that code doohickey have such-and-such property
|
||||||
|
or not? You get the idea. Assertions are executable code (to appreciate the big
|
||||||
|
picture on this read up on the difference between
|
||||||
|
[link:Dynamic Verification and Static Analysis]). A failing assertion stops
|
||||||
|
execution and reports an error through some appropriate I/O channel (e.g.
|
||||||
|
stdout, GUI, file, blinky light).
|
||||||
|
|
||||||
|
Fundamentally, for dynamic verification all you need is a single assertion
|
||||||
|
mechanism. In fact, that's what the [assert() macro in C's standard library](http://en.wikipedia.org/en/wiki/Assert.h)
|
||||||
|
is for. So why not just use it? Well, we can do far better in the reporting
|
||||||
|
department. C's `assert()` is pretty dumb as-is and is particularly poor for
|
||||||
|
handling common data types like arrays, structs, etc. And, without some other
|
||||||
|
support, it's far too tempting to litter source code with C's `assert()`'s. It's
|
||||||
|
generally much cleaner, manageable, and more useful to separate test and source
|
||||||
|
code in the way Unity facilitates.
|
||||||
|
|
||||||
|
|
||||||
|
### Unity's Assertions: Helpful Messages _and_ Free Source Code Documentation
|
||||||
|
|
||||||
|
Asserting a simple truth condition is valuable, but using the context of the
|
||||||
|
assertion is even more valuable. For instance, if you know you're comparing bit
|
||||||
|
flags and not just integers, then why not use that context to give explicit,
|
||||||
|
readable, bit-level feedback when an assertion fails?
|
||||||
|
|
||||||
|
That's what Unity's collection of assertions do - capture context to give you
|
||||||
|
helpful, meaningful assertion failure messages. In fact, the assertions
|
||||||
|
themselves also serve as executable documentation about types and values in your
|
||||||
|
source code. So long as your tests remain current with your source and all those
|
||||||
|
tests pass, you have a detailed, up-to-date view of the intent and mechanisms in
|
||||||
|
your source code. And due to a wondrous mystery, well-tested code usually tends
|
||||||
|
to be well designed code.
|
||||||
|
|
||||||
|
|
||||||
|
## Assertion Conventions and Configurations
|
||||||
|
|
||||||
|
### Naming and Parameter Conventions
|
||||||
|
|
||||||
|
The convention of assertion parameters generally follows this order:
|
||||||
|
|
||||||
|
TEST_ASSERT_X( {modifiers}, {expected}, actual, {size/count} )
|
||||||
|
|
||||||
|
The very simplest assertion possible uses only a single "actual" parameter (e.g.
|
||||||
|
a simple null check).
|
||||||
|
|
||||||
|
"Actual" is the value being tested and unlike the other parameters in an
|
||||||
|
assertion construction is the only parameter present in all assertion variants.
|
||||||
|
"Modifiers" are masks, ranges, bit flag specifiers, floating point deltas.
|
||||||
|
"Expected" is your expected value (duh) to compare to an "actual" value; it's
|
||||||
|
marked as an optional parameter because some assertions only need a single
|
||||||
|
"actual" parameter (e.g. null check).
|
||||||
|
"Size/count" refers to string lengths, number of array elements, etc.
|
||||||
|
|
||||||
|
Many of Unity's assertions are apparent duplications in that the same data type
|
||||||
|
is handled by several assertions. The differences among these are in how failure
|
||||||
|
messages are presented. For instance, a `_HEX` variant of an assertion prints
|
||||||
|
the expected and actual values of that assertion formatted as hexadecimal.
|
||||||
|
|
||||||
|
|
||||||
|
#### TEST_ASSERT_X_MESSAGE Variants
|
||||||
|
|
||||||
|
_All_ assertions are complemented with a variant that includes a simple string
|
||||||
|
message as a final parameter. The string you specify is appended to an assertion
|
||||||
|
failure message in Unity output.
|
||||||
|
|
||||||
|
For brevity, the assertion variants with a message parameter are not listed
|
||||||
|
below. Just tack on `_MESSAGE` as the final component to any assertion name in
|
||||||
|
the reference list below and add a string as the final parameter.
|
||||||
|
|
||||||
|
_Example:_
|
||||||
|
|
||||||
|
TEST_ASSERT_X( {modifiers}, {expected}, actual, {size/count} )
|
||||||
|
|
||||||
|
becomes messageified like thus...
|
||||||
|
|
||||||
|
TEST_ASSERT_X_MESSAGE( {modifiers}, {expected}, actual, {size/count}, message )
|
||||||
|
|
||||||
|
|
||||||
|
#### TEST_ASSERT_X_ARRAY Variants
|
||||||
|
|
||||||
|
Unity provides a collection of assertions for arrays containing a variety of
|
||||||
|
types. These are documented in the Array section below. These are almost on par
|
||||||
|
with the `_MESSAGE`variants of Unity's Asserts in that for pretty much any Unity
|
||||||
|
type assertion you can tack on `_ARRAY` and run assertions on an entire block of
|
||||||
|
memory.
|
||||||
|
|
||||||
|
TEST_ASSERT_EQUAL_TYPEX_ARRAY( expected, actual, {size/count} )
|
||||||
|
|
||||||
|
"Expected" is an array itself.
|
||||||
|
"Size/count" is one or two parameters necessary to establish the number of array
|
||||||
|
elements and perhaps the length of elements within the array.
|
||||||
|
|
||||||
|
Notes:
|
||||||
|
- The `_MESSAGE` variant convention still applies here to array assertions. The
|
||||||
|
`_MESSAGE` variants of the `_ARRAY` assertions have names ending with
|
||||||
|
`_ARRAY_MESSAGE`.
|
||||||
|
- Assertions for handling arrays of floating point values are grouped with float
|
||||||
|
and double assertions (see immediately following section).
|
||||||
|
|
||||||
|
|
||||||
|
### TEST_ASSERT_EACH_EQUAL_X Variants
|
||||||
|
|
||||||
|
Unity provides a collection of assertions for arrays containing a variety of
|
||||||
|
types which can be compared to a single value as well. These are documented in
|
||||||
|
the Each Equal section below. these are almost on par with the `_MESSAGE`
|
||||||
|
variants of Unity's Asserts in that for pretty much any Unity type assertion you
|
||||||
|
can inject _EACH_EQUAL and run assertions on an entire block of memory.
|
||||||
|
|
||||||
|
TEST_ASSERT_EACH_EQUAL_TYPEX( expected, actual, {size/count} )
|
||||||
|
|
||||||
|
"Expected" is a single value to compare to.
|
||||||
|
"Actual" is an array where each element will be compared to the expected value.
|
||||||
|
"Size/count" is one of two parameters necessary to establish the number of array
|
||||||
|
elements and perhaps the length of elements within the array.
|
||||||
|
|
||||||
|
Notes:
|
||||||
|
- The `_MESSAGE` variant convention still applies here to Each Equal assertions.
|
||||||
|
- Assertions for handling Each Equal of floating point values are grouped with
|
||||||
|
float and double assertions (see immediately following section).
|
||||||
|
|
||||||
|
|
||||||
|
### Configuration
|
||||||
|
|
||||||
|
#### Floating Point Support Is Optional
|
||||||
|
|
||||||
|
Support for floating point types is configurable. That is, by defining the
|
||||||
|
appropriate preprocessor symbols, floats and doubles can be individually enabled
|
||||||
|
or disabled in Unity code. This is useful for embedded targets with no floating
|
||||||
|
point math support (i.e. Unity compiles free of errors for fixed point only
|
||||||
|
platforms). See Unity documentation for specifics.
|
||||||
|
|
||||||
|
|
||||||
|
#### Maximum Data Type Width Is Configurable
|
||||||
|
|
||||||
|
Not all targets support 64 bit wide types or even 32 bit wide types. Define the
|
||||||
|
appropriate preprocessor symbols and Unity will omit all operations from
|
||||||
|
compilation that exceed the maximum width of your target. See Unity
|
||||||
|
documentation for specifics.
|
||||||
|
|
||||||
|
|
||||||
|
## The Assertions in All Their Blessed Glory
|
||||||
|
|
||||||
|
### Basic Fail and Ignore
|
||||||
|
|
||||||
|
##### `TEST_FAIL()`
|
||||||
|
|
||||||
|
This fella is most often used in special conditions where your test code is
|
||||||
|
performing logic beyond a simple assertion. That is, in practice, `TEST_FAIL()`
|
||||||
|
will always be found inside a conditional code block.
|
||||||
|
|
||||||
|
_Examples:_
|
||||||
|
- Executing a state machine multiple times that increments a counter your test
|
||||||
|
code then verifies as a final step.
|
||||||
|
- Triggering an exception and verifying it (as in Try / Catch / Throw - see the
|
||||||
|
[CException](https://github.com/ThrowTheSwitch/CException) project).
|
||||||
|
|
||||||
|
##### `TEST_IGNORE()`
|
||||||
|
|
||||||
|
Marks a test case (i.e. function meant to contain test assertions) as ignored.
|
||||||
|
Usually this is employed as a breadcrumb to come back and implement a test case.
|
||||||
|
An ignored test case has effects if other assertions are in the enclosing test
|
||||||
|
case (see Unity documentation for more).
|
||||||
|
|
||||||
|
### Boolean
|
||||||
|
|
||||||
|
##### `TEST_ASSERT (condition)`
|
||||||
|
|
||||||
|
##### `TEST_ASSERT_TRUE (condition)`
|
||||||
|
|
||||||
|
##### `TEST_ASSERT_FALSE (condition)`
|
||||||
|
|
||||||
|
##### `TEST_ASSERT_UNLESS (condition)`
|
||||||
|
|
||||||
|
A simple wording variation on `TEST_ASSERT_FALSE`.The semantics of
|
||||||
|
`TEST_ASSERT_UNLESS` aid readability in certain test constructions or
|
||||||
|
conditional statements.
|
||||||
|
|
||||||
|
##### `TEST_ASSERT_NULL (pointer)`
|
||||||
|
|
||||||
|
##### `TEST_ASSERT_NOT_NULL (pointer)`
|
||||||
|
|
||||||
|
|
||||||
|
### Signed and Unsigned Integers (of all sizes)
|
||||||
|
|
||||||
|
Large integer sizes can be disabled for build targets that do not support them.
|
||||||
|
For example, if your target only supports up to 16 bit types, by defining the
|
||||||
|
appropriate symbols Unity can be configured to omit 32 and 64 bit operations
|
||||||
|
that would break compilation (see Unity documentation for more). Refer to
|
||||||
|
Advanced Asserting later in this document for advice on dealing with other word
|
||||||
|
sizes.
|
||||||
|
|
||||||
|
##### `TEST_ASSERT_EQUAL_INT (expected, actual)`
|
||||||
|
|
||||||
|
##### `TEST_ASSERT_EQUAL_INT8 (expected, actual)`
|
||||||
|
|
||||||
|
##### `TEST_ASSERT_EQUAL_INT16 (expected, actual)`
|
||||||
|
|
||||||
|
##### `TEST_ASSERT_EQUAL_INT32 (expected, actual)`
|
||||||
|
|
||||||
|
##### `TEST_ASSERT_EQUAL_INT64 (expected, actual)`
|
||||||
|
|
||||||
|
##### `TEST_ASSERT_EQUAL (expected, actual)`
|
||||||
|
|
||||||
|
##### `TEST_ASSERT_NOT_EQUAL (expected, actual)`
|
||||||
|
|
||||||
|
##### `TEST_ASSERT_EQUAL_UINT (expected, actual)`
|
||||||
|
|
||||||
|
##### `TEST_ASSERT_EQUAL_UINT8 (expected, actual)`
|
||||||
|
|
||||||
|
##### `TEST_ASSERT_EQUAL_UINT16 (expected, actual)`
|
||||||
|
|
||||||
|
##### `TEST_ASSERT_EQUAL_UINT32 (expected, actual)`
|
||||||
|
|
||||||
|
##### `TEST_ASSERT_EQUAL_UINT64 (expected, actual)`
|
||||||
|
|
||||||
|
|
||||||
|
### Unsigned Integers (of all sizes) in Hexadecimal
|
||||||
|
|
||||||
|
All `_HEX` assertions are identical in function to unsigned integer assertions
|
||||||
|
but produce failure messages with the `expected` and `actual` values formatted
|
||||||
|
in hexadecimal. Unity output is big endian.
|
||||||
|
|
||||||
|
##### `TEST_ASSERT_EQUAL_HEX (expected, actual)`
|
||||||
|
|
||||||
|
##### `TEST_ASSERT_EQUAL_HEX8 (expected, actual)`
|
||||||
|
|
||||||
|
##### `TEST_ASSERT_EQUAL_HEX16 (expected, actual)`
|
||||||
|
|
||||||
|
##### `TEST_ASSERT_EQUAL_HEX32 (expected, actual)`
|
||||||
|
|
||||||
|
##### `TEST_ASSERT_EQUAL_HEX64 (expected, actual)`
|
||||||
|
|
||||||
|
|
||||||
|
### Masked and Bit-level Assertions
|
||||||
|
|
||||||
|
Masked and bit-level assertions produce output formatted in hexadecimal. Unity
|
||||||
|
output is big endian.
|
||||||
|
|
||||||
|
|
||||||
|
##### `TEST_ASSERT_BITS (mask, expected, actual)`
|
||||||
|
|
||||||
|
Only compares the masked (i.e. high) bits of `expected` and `actual` parameters.
|
||||||
|
|
||||||
|
|
||||||
|
##### `TEST_ASSERT_BITS_HIGH (mask, actual)`
|
||||||
|
|
||||||
|
Asserts the masked bits of the `actual` parameter are high.
|
||||||
|
|
||||||
|
|
||||||
|
##### `TEST_ASSERT_BITS_LOW (mask, actual)`
|
||||||
|
|
||||||
|
Asserts the masked bits of the `actual` parameter are low.
|
||||||
|
|
||||||
|
|
||||||
|
##### `TEST_ASSERT_BIT_HIGH (bit, actual)`
|
||||||
|
|
||||||
|
Asserts the specified bit of the `actual` parameter is high.
|
||||||
|
|
||||||
|
|
||||||
|
##### `TEST_ASSERT_BIT_LOW (bit, actual)`
|
||||||
|
|
||||||
|
Asserts the specified bit of the `actual` parameter is low.
|
||||||
|
|
||||||
|
|
||||||
|
### Integer Ranges (of all sizes)
|
||||||
|
|
||||||
|
These assertions verify that the `expected` parameter is within +/- `delta`
|
||||||
|
(inclusive) of the `actual` parameter. For example, if the expected value is 10
|
||||||
|
and the delta is 3 then the assertion will fail for any value outside the range
|
||||||
|
of 7 - 13.
|
||||||
|
|
||||||
|
##### `TEST_ASSERT_INT_WITHIN (delta, expected, actual)`
|
||||||
|
|
||||||
|
##### `TEST_ASSERT_INT8_WITHIN (delta, expected, actual)`
|
||||||
|
|
||||||
|
##### `TEST_ASSERT_INT16_WITHIN (delta, expected, actual)`
|
||||||
|
|
||||||
|
##### `TEST_ASSERT_INT32_WITHIN (delta, expected, actual)`
|
||||||
|
|
||||||
|
##### `TEST_ASSERT_INT64_WITHIN (delta, expected, actual)`
|
||||||
|
|
||||||
|
##### `TEST_ASSERT_UINT_WITHIN (delta, expected, actual)`
|
||||||
|
|
||||||
|
##### `TEST_ASSERT_UINT8_WITHIN (delta, expected, actual)`
|
||||||
|
|
||||||
|
##### `TEST_ASSERT_UINT16_WITHIN (delta, expected, actual)`
|
||||||
|
|
||||||
|
##### `TEST_ASSERT_UINT32_WITHIN (delta, expected, actual)`
|
||||||
|
|
||||||
|
##### `TEST_ASSERT_UINT64_WITHIN (delta, expected, actual)`
|
||||||
|
|
||||||
|
##### `TEST_ASSERT_HEX_WITHIN (delta, expected, actual)`
|
||||||
|
|
||||||
|
##### `TEST_ASSERT_HEX8_WITHIN (delta, expected, actual)`
|
||||||
|
|
||||||
|
##### `TEST_ASSERT_HEX16_WITHIN (delta, expected, actual)`
|
||||||
|
|
||||||
|
##### `TEST_ASSERT_HEX32_WITHIN (delta, expected, actual)`
|
||||||
|
|
||||||
|
##### `TEST_ASSERT_HEX64_WITHIN (delta, expected, actual)`
|
||||||
|
|
||||||
|
|
||||||
|
### Structs and Strings
|
||||||
|
|
||||||
|
##### `TEST_ASSERT_EQUAL_PTR (expected, actual)`
|
||||||
|
|
||||||
|
Asserts that the pointers point to the same memory location.
|
||||||
|
|
||||||
|
|
||||||
|
##### `TEST_ASSERT_EQUAL_STRING (expected, actual)`
|
||||||
|
|
||||||
|
Asserts that the null terminated (`'\0'`)strings are identical. If strings are
|
||||||
|
of different lengths or any portion of the strings before their terminators
|
||||||
|
differ, the assertion fails. Two NULL strings (i.e. zero length) are considered
|
||||||
|
equivalent.
|
||||||
|
|
||||||
|
|
||||||
|
##### `TEST_ASSERT_EQUAL_MEMORY (expected, actual, len)`
|
||||||
|
|
||||||
|
Asserts that the contents of the memory specified by the `expected` and `actual`
|
||||||
|
pointers is identical. The size of the memory blocks in bytes is specified by
|
||||||
|
the `len` parameter.
|
||||||
|
|
||||||
|
|
||||||
|
### Arrays
|
||||||
|
|
||||||
|
`expected` and `actual` parameters are both arrays. `num_elements` specifies the
|
||||||
|
number of elements in the arrays to compare.
|
||||||
|
|
||||||
|
`_HEX` assertions produce failure messages with expected and actual array
|
||||||
|
contents formatted in hexadecimal.
|
||||||
|
|
||||||
|
For array of strings comparison behavior, see comments for
|
||||||
|
`TEST_ASSERT_EQUAL_STRING` in the preceding section.
|
||||||
|
|
||||||
|
Assertions fail upon the first element in the compared arrays found not to
|
||||||
|
match. Failure messages specify the array index of the failed comparison.
|
||||||
|
|
||||||
|
##### `TEST_ASSERT_EQUAL_INT_ARRAY (expected, actual, num_elements)`
|
||||||
|
|
||||||
|
##### `TEST_ASSERT_EQUAL_INT8_ARRAY (expected, actual, num_elements)`
|
||||||
|
|
||||||
|
##### `TEST_ASSERT_EQUAL_INT16_ARRAY (expected, actual, num_elements)`
|
||||||
|
|
||||||
|
##### `TEST_ASSERT_EQUAL_INT32_ARRAY (expected, actual, num_elements)`
|
||||||
|
|
||||||
|
##### `TEST_ASSERT_EQUAL_INT64_ARRAY (expected, actual, num_elements)`
|
||||||
|
|
||||||
|
##### `TEST_ASSERT_EQUAL_UINT_ARRAY (expected, actual, num_elements)`
|
||||||
|
|
||||||
|
##### `TEST_ASSERT_EQUAL_UINT8_ARRAY (expected, actual, num_elements)`
|
||||||
|
|
||||||
|
##### `TEST_ASSERT_EQUAL_UINT16_ARRAY (expected, actual, num_elements)`
|
||||||
|
|
||||||
|
##### `TEST_ASSERT_EQUAL_UINT32_ARRAY (expected, actual, num_elements)`
|
||||||
|
|
||||||
|
##### `TEST_ASSERT_EQUAL_UINT64_ARRAY (expected, actual, num_elements)`
|
||||||
|
|
||||||
|
##### `TEST_ASSERT_EQUAL_HEX_ARRAY (expected, actual, num_elements)`
|
||||||
|
|
||||||
|
##### `TEST_ASSERT_EQUAL_HEX8_ARRAY (expected, actual, num_elements)`
|
||||||
|
|
||||||
|
##### `TEST_ASSERT_EQUAL_HEX16_ARRAY (expected, actual, num_elements)`
|
||||||
|
|
||||||
|
##### `TEST_ASSERT_EQUAL_HEX32_ARRAY (expected, actual, num_elements)`
|
||||||
|
|
||||||
|
##### `TEST_ASSERT_EQUAL_HEX64_ARRAY (expected, actual, num_elements)`
|
||||||
|
|
||||||
|
##### `TEST_ASSERT_EQUAL_PTR_ARRAY (expected, actual, num_elements)`
|
||||||
|
|
||||||
|
##### `TEST_ASSERT_EQUAL_STRING_ARRAY (expected, actual, num_elements)`
|
||||||
|
|
||||||
|
##### `TEST_ASSERT_EQUAL_MEMORY_ARRAY (expected, actual, len, num_elements)`
|
||||||
|
|
||||||
|
`len` is the memory in bytes to be compared at each array element.
|
||||||
|
|
||||||
|
|
||||||
|
### Each Equal (Arrays to Single Value)
|
||||||
|
|
||||||
|
`expected` are single values and `actual` are arrays. `num_elements` specifies
|
||||||
|
the number of elements in the arrays to compare.
|
||||||
|
|
||||||
|
`_HEX` assertions produce failure messages with expected and actual array
|
||||||
|
contents formatted in hexadecimal.
|
||||||
|
|
||||||
|
Assertions fail upon the first element in the compared arrays found not to
|
||||||
|
match. Failure messages specify the array index of the failed comparison.
|
||||||
|
|
||||||
|
#### `TEST_ASSERT_EACH_EQUAL_INT (expected, actual, num_elements)`
|
||||||
|
|
||||||
|
#### `TEST_ASSERT_EACH_EQUAL_INT8 (expected, actual, num_elements)`
|
||||||
|
|
||||||
|
#### `TEST_ASSERT_EACH_EQUAL_INT16 (expected, actual, num_elements)`
|
||||||
|
|
||||||
|
#### `TEST_ASSERT_EACH_EQUAL_INT32 (expected, actual, num_elements)`
|
||||||
|
|
||||||
|
#### `TEST_ASSERT_EACH_EQUAL_INT64 (expected, actual, num_elements)`
|
||||||
|
|
||||||
|
#### `TEST_ASSERT_EACH_EQUAL_UINT (expected, actual, num_elements)`
|
||||||
|
|
||||||
|
#### `TEST_ASSERT_EACH_EQUAL_UINT8 (expected, actual, num_elements)`
|
||||||
|
|
||||||
|
#### `TEST_ASSERT_EACH_EQUAL_UINT16 (expected, actual, num_elements)`
|
||||||
|
|
||||||
|
#### `TEST_ASSERT_EACH_EQUAL_UINT32 (expected, actual, num_elements)`
|
||||||
|
|
||||||
|
#### `TEST_ASSERT_EACH_EQUAL_UINT64 (expected, actual, num_elements)`
|
||||||
|
|
||||||
|
#### `TEST_ASSERT_EACH_EQUAL_HEX (expected, actual, num_elements)`
|
||||||
|
|
||||||
|
#### `TEST_ASSERT_EACH_EQUAL_HEX8 (expected, actual, num_elements)`
|
||||||
|
|
||||||
|
#### `TEST_ASSERT_EACH_EQUAL_HEX16 (expected, actual, num_elements)`
|
||||||
|
|
||||||
|
#### `TEST_ASSERT_EACH_EQUAL_HEX32 (expected, actual, num_elements)`
|
||||||
|
|
||||||
|
#### `TEST_ASSERT_EACH_EQUAL_HEX64 (expected, actual, num_elements)`
|
||||||
|
|
||||||
|
#### `TEST_ASSERT_EACH_EQUAL_PTR (expected, actual, num_elements)`
|
||||||
|
|
||||||
|
#### `TEST_ASSERT_EACH_EQUAL_STRING (expected, actual, num_elements)`
|
||||||
|
|
||||||
|
#### `TEST_ASSERT_EACH_EQUAL_MEMORY (expected, actual, len, num_elements)`
|
||||||
|
|
||||||
|
`len` is the memory in bytes to be compared at each array element.
|
||||||
|
|
||||||
|
|
||||||
|
### Floating Point (If enabled)
|
||||||
|
|
||||||
|
##### `TEST_ASSERT_FLOAT_WITHIN (delta, expected, actual)`
|
||||||
|
|
||||||
|
Asserts that the `actual` value is within +/- `delta` of the `expected` value.
|
||||||
|
The nature of floating point representation is such that exact evaluations of
|
||||||
|
equality are not guaranteed.
|
||||||
|
|
||||||
|
|
||||||
|
##### `TEST_ASSERT_EQUAL_FLOAT (expected, actual)`
|
||||||
|
|
||||||
|
Asserts that the ?actual?value is "close enough to be considered equal" to the
|
||||||
|
`expected` value. If you are curious about the details, refer to the Advanced
|
||||||
|
Asserting section for more details on this. Omitting a user-specified delta in a
|
||||||
|
floating point assertion is both a shorthand convenience and a requirement of
|
||||||
|
code generation conventions for CMock.
|
||||||
|
|
||||||
|
|
||||||
|
##### `TEST_ASSERT_EQUAL_FLOAT_ARRAY (expected, actual, num_elements)`
|
||||||
|
|
||||||
|
See Array assertion section for details. Note that individual array element
|
||||||
|
float comparisons are executed using T?EST_ASSERT_EQUAL_FLOAT?.That is, user
|
||||||
|
specified delta comparison values requires a custom-implemented floating point
|
||||||
|
array assertion.
|
||||||
|
|
||||||
|
|
||||||
|
##### `TEST_ASSERT_FLOAT_IS_INF (actual)`
|
||||||
|
|
||||||
|
Asserts that `actual` parameter is equivalent to positive infinity floating
|
||||||
|
point representation.
|
||||||
|
|
||||||
|
|
||||||
|
##### `TEST_ASSERT_FLOAT_IS_NEG_INF (actual)`
|
||||||
|
|
||||||
|
Asserts that `actual` parameter is equivalent to negative infinity floating
|
||||||
|
point representation.
|
||||||
|
|
||||||
|
|
||||||
|
##### `TEST_ASSERT_FLOAT_IS_NAN (actual)`
|
||||||
|
|
||||||
|
Asserts that `actual` parameter is a Not A Number floating point representation.
|
||||||
|
|
||||||
|
|
||||||
|
##### `TEST_ASSERT_FLOAT_IS_DETERMINATE (actual)`
|
||||||
|
|
||||||
|
Asserts that ?actual?parameter is a floating point representation usable for
|
||||||
|
mathematical operations. That is, the `actual` parameter is neither positive
|
||||||
|
infinity nor negative infinity nor Not A Number floating point representations.
|
||||||
|
|
||||||
|
|
||||||
|
##### `TEST_ASSERT_FLOAT_IS_NOT_INF (actual)`
|
||||||
|
|
||||||
|
Asserts that `actual` parameter is a value other than positive infinity floating
|
||||||
|
point representation.
|
||||||
|
|
||||||
|
|
||||||
|
##### `TEST_ASSERT_FLOAT_IS_NOT_NEG_INF (actual)`
|
||||||
|
|
||||||
|
Asserts that `actual` parameter is a value other than negative infinity floating
|
||||||
|
point representation.
|
||||||
|
|
||||||
|
|
||||||
|
##### `TEST_ASSERT_FLOAT_IS_NOT_NAN (actual)`
|
||||||
|
|
||||||
|
Asserts that `actual` parameter is a value other than Not A Number floating
|
||||||
|
point representation.
|
||||||
|
|
||||||
|
|
||||||
|
##### `TEST_ASSERT_FLOAT_IS_NOT_DETERMINATE (actual)`
|
||||||
|
|
||||||
|
Asserts that `actual` parameter is not usable for mathematical operations. That
|
||||||
|
is, the `actual` parameter is either positive infinity or negative infinity or
|
||||||
|
Not A Number floating point representations.
|
||||||
|
|
||||||
|
|
||||||
|
### Double (If enabled)
|
||||||
|
|
||||||
|
##### `TEST_ASSERT_DOUBLE_WITHIN (delta, expected, actual)`
|
||||||
|
|
||||||
|
Asserts that the `actual` value is within +/- `delta` of the `expected` value.
|
||||||
|
The nature of floating point representation is such that exact evaluations of
|
||||||
|
equality are not guaranteed.
|
||||||
|
|
||||||
|
|
||||||
|
##### `TEST_ASSERT_EQUAL_DOUBLE (expected, actual)`
|
||||||
|
|
||||||
|
Asserts that the `actual` value is "close enough to be considered equal" to the
|
||||||
|
`expected` value. If you are curious about the details, refer to the Advanced
|
||||||
|
Asserting section for more details. Omitting a user-specified delta in a
|
||||||
|
floating point assertion is both a shorthand convenience and a requirement of
|
||||||
|
code generation conventions for CMock.
|
||||||
|
|
||||||
|
|
||||||
|
##### `TEST_ASSERT_EQUAL_DOUBLE_ARRAY (expected, actual, num_elements)`
|
||||||
|
|
||||||
|
See Array assertion section for details. Note that individual array element
|
||||||
|
double comparisons are executed using `TEST_ASSERT_EQUAL_DOUBLE`.That is, user
|
||||||
|
specified delta comparison values requires a custom implemented double array
|
||||||
|
assertion.
|
||||||
|
|
||||||
|
|
||||||
|
##### `TEST_ASSERT_DOUBLE_IS_INF (actual)`
|
||||||
|
|
||||||
|
Asserts that `actual` parameter is equivalent to positive infinity floating
|
||||||
|
point representation.
|
||||||
|
|
||||||
|
|
||||||
|
##### `TEST_ASSERT_DOUBLE_IS_NEG_INF (actual)`
|
||||||
|
|
||||||
|
Asserts that `actual` parameter is equivalent to negative infinity floating point
|
||||||
|
representation.
|
||||||
|
|
||||||
|
|
||||||
|
##### `TEST_ASSERT_DOUBLE_IS_NAN (actual)`
|
||||||
|
|
||||||
|
Asserts that `actual` parameter is a Not A Number floating point representation.
|
||||||
|
|
||||||
|
|
||||||
|
##### `TEST_ASSERT_DOUBLE_IS_DETERMINATE (actual)`
|
||||||
|
|
||||||
|
Asserts that `actual` parameter is a floating point representation usable for
|
||||||
|
mathematical operations. That is, the ?actual?parameter is neither positive
|
||||||
|
infinity nor negative infinity nor Not A Number floating point representations.
|
||||||
|
|
||||||
|
|
||||||
|
##### `TEST_ASSERT_DOUBLE_IS_NOT_INF (actual)`
|
||||||
|
|
||||||
|
Asserts that `actual` parameter is a value other than positive infinity floating
|
||||||
|
point representation.
|
||||||
|
|
||||||
|
|
||||||
|
##### `TEST_ASSERT_DOUBLE_IS_NOT_NEG_INF (actual)`
|
||||||
|
|
||||||
|
Asserts that `actual` parameter is a value other than negative infinity floating
|
||||||
|
point representation.
|
||||||
|
|
||||||
|
|
||||||
|
##### `TEST_ASSERT_DOUBLE_IS_NOT_NAN (actual)`
|
||||||
|
|
||||||
|
Asserts that `actual` parameter is a value other than Not A Number floating
|
||||||
|
point representation.
|
||||||
|
|
||||||
|
|
||||||
|
##### `TEST_ASSERT_DOUBLE_IS_NOT_DETERMINATE (actual)`
|
||||||
|
|
||||||
|
Asserts that `actual` parameter is not usable for mathematical operations. That
|
||||||
|
is, the `actual` parameter is either positive infinity or negative infinity or
|
||||||
|
Not A Number floating point representations.
|
||||||
|
|
||||||
|
|
||||||
|
## Advanced Asserting: Details On Tricky Assertions
|
||||||
|
|
||||||
|
This section helps you understand how to deal with some of the trickier
|
||||||
|
assertion situations you may run into. It will give you a glimpse into some of
|
||||||
|
the under-the-hood details of Unity's assertion mechanisms. If you're one of
|
||||||
|
those people who likes to know what is going on in the background, read on. If
|
||||||
|
not, feel free to ignore the rest of this document until you need it.
|
||||||
|
|
||||||
|
|
||||||
|
### How do the EQUAL assertions work for FLOAT and DOUBLE?
|
||||||
|
|
||||||
|
As you may know, directly checking for equality between a pair of floats or a
|
||||||
|
pair of doubles is sloppy at best and an outright no-no at worst. Floating point
|
||||||
|
values can often be represented in multiple ways, particularly after a series of
|
||||||
|
operations on a value. Initializing a variable to the value of 2.0 is likely to
|
||||||
|
result in a floating point representation of 2 x 20,but a series of
|
||||||
|
mathematical operations might result in a representation of 8 x 2-2
|
||||||
|
that also evaluates to a value of 2. At some point repeated operations cause
|
||||||
|
equality checks to fail.
|
||||||
|
|
||||||
|
So Unity doesn't do direct floating point comparisons for equality. Instead, it
|
||||||
|
checks if two floating point values are "really close." If you leave Unity
|
||||||
|
running with defaults, "really close" means "within a significant bit or two."
|
||||||
|
Under the hood, `TEST_ASSERT_EQUAL_FLOAT` is really `TEST_ASSERT_FLOAT_WITHIN`
|
||||||
|
with the `delta` parameter calculated on the fly. For single precision, delta is
|
||||||
|
the expected value multiplied by 0.00001, producing a very small proportional
|
||||||
|
range around the expected value.
|
||||||
|
|
||||||
|
If you are expecting a value of 20,000.0 the delta is calculated to be 0.2. So
|
||||||
|
any value between 19,999.8 and 20,000.2 will satisfy the equality check. This
|
||||||
|
works out to be roughly a single bit of range for a single-precision number, and
|
||||||
|
that's just about as tight a tolerance as you can reasonably get from a floating
|
||||||
|
point value.
|
||||||
|
|
||||||
|
So what happens when it's zero? Zero - even more than other floating point
|
||||||
|
values - can be represented many different ways. It doesn't matter if you have
|
||||||
|
0 x 20or 0 x 263.It's still zero, right? Luckily, if you
|
||||||
|
subtract these values from each other, they will always produce a difference of
|
||||||
|
zero, which will still fall between 0 plus or minus a delta of 0. So it still
|
||||||
|
works!
|
||||||
|
|
||||||
|
Double precision floating point numbers use a much smaller multiplier, again
|
||||||
|
approximating a single bit of error.
|
||||||
|
|
||||||
|
If you don't like these ranges and you want to make your floating point equality
|
||||||
|
assertions less strict, you can change these multipliers to whatever you like by
|
||||||
|
defining UNITY_FLOAT_PRECISION and UNITY_DOUBLE_PRECISION. See Unity
|
||||||
|
documentation for more.
|
||||||
|
|
||||||
|
|
||||||
|
### How do we deal with targets with non-standard int sizes?
|
||||||
|
|
||||||
|
It's "fun" that C is a standard where something as fundamental as an integer
|
||||||
|
varies by target. According to the C standard, an `int` is to be the target's
|
||||||
|
natural register size, and it should be at least 16-bits and a multiple of a
|
||||||
|
byte. It also guarantees an order of sizes:
|
||||||
|
|
||||||
|
```C
|
||||||
|
char <= short <= int <= long <= long long
|
||||||
|
```
|
||||||
|
|
||||||
|
Most often, `int` is 32-bits. In many cases in the embedded world, `int` is
|
||||||
|
16-bits. There are rare microcontrollers out there that have 24-bit integers,
|
||||||
|
and this remains perfectly standard C.
|
||||||
|
|
||||||
|
To make things even more interesting, there are compilers and targets out there
|
||||||
|
that have a hard choice to make. What if their natural register size is 10-bits
|
||||||
|
or 12-bits? Clearly they can't fulfill _both_ the requirement to be at least
|
||||||
|
16-bits AND the requirement to match the natural register size. In these
|
||||||
|
situations, they often choose the natural register size, leaving us with
|
||||||
|
something like this:
|
||||||
|
|
||||||
|
```C
|
||||||
|
char (8 bit) <= short (12 bit) <= int (12 bit) <= long (16 bit)
|
||||||
|
```
|
||||||
|
|
||||||
|
Um... yikes. It's obviously breaking a rule or two... but they had to break SOME
|
||||||
|
rules, so they made a choice.
|
||||||
|
|
||||||
|
When the C99 standard rolled around, it introduced alternate standard-size types.
|
||||||
|
It also introduced macros for pulling in MIN/MAX values for your integer types.
|
||||||
|
It's glorious! Unfortunately, many embedded compilers can't be relied upon to
|
||||||
|
use the C99 types (Sometimes because they have weird register sizes as described
|
||||||
|
above. Sometimes because they don't feel like it?).
|
||||||
|
|
||||||
|
A goal of Unity from the beginning was to support every combination of
|
||||||
|
microcontroller or microprocessor and C compiler. Over time, we've gotten really
|
||||||
|
close to this. There are a few tricks that you should be aware of, though, if
|
||||||
|
you're going to do this effectively on some of these more idiosyncratic targets.
|
||||||
|
|
||||||
|
First, when setting up Unity for a new target, you're going to want to pay
|
||||||
|
special attention to the macros for automatically detecting types
|
||||||
|
(where available) or manually configuring them yourself. You can get information
|
||||||
|
on both of these in Unity's documentation.
|
||||||
|
|
||||||
|
What about the times where you suddenly need to deal with something odd, like a
|
||||||
|
24-bit `int`? The simplest solution is to use the next size up. If you have a
|
||||||
|
24-bit `int`, configure Unity to use 32-bit integers. If you have a 12-bit
|
||||||
|
`int`, configure Unity to use 16 bits. There are two ways this is going to
|
||||||
|
affect you:
|
||||||
|
|
||||||
|
1. When Unity displays errors for you, it's going to pad the upper unused bits
|
||||||
|
with zeros.
|
||||||
|
2. You're going to have to be careful of assertions that perform signed
|
||||||
|
operations, particularly `TEST_ASSERT_INT_WITHIN`.Such assertions might wrap
|
||||||
|
your `int` in the wrong place, and you could experience false failures. You can
|
||||||
|
always back down to a simple `TEST_ASSERT` and do the operations yourself.
|
||||||
|
|
||||||
|
|
||||||
|
*Find The Latest of This And More at [ThrowTheSwitch.org](https://throwtheswitch.org)*
|
Binary file not shown.
398
tests/unity/docs/UnityConfigurationGuide.md
Normal file
398
tests/unity/docs/UnityConfigurationGuide.md
Normal file
@ -0,0 +1,398 @@
|
|||||||
|
# Unity Configuration Guide
|
||||||
|
|
||||||
|
## C Standards, Compilers and Microcontrollers
|
||||||
|
|
||||||
|
The embedded software world contains its challenges. Compilers support different
|
||||||
|
revisions of the C Standard. They ignore requirements in places, sometimes to
|
||||||
|
make the language more usable in some special regard. Sometimes it's to simplify
|
||||||
|
their support. Sometimes it's due to specific quirks of the microcontroller they
|
||||||
|
are targeting. Simulators add another dimension to this menagerie.
|
||||||
|
|
||||||
|
Unity is designed to run on almost anything that is targeted by a C compiler. It
|
||||||
|
would be awesome if this could be done with zero configuration. While there are
|
||||||
|
some targets that come close to this dream, it is sadly not universal. It is
|
||||||
|
likely that you are going to need at least a couple of the configuration options
|
||||||
|
described in this document.
|
||||||
|
|
||||||
|
All of Unity's configuration options are `#defines`. Most of these are simple
|
||||||
|
definitions. A couple are macros with arguments. They live inside the
|
||||||
|
unity_internals.h header file. We don't necessarily recommend opening that file
|
||||||
|
unless you really need to. That file is proof that a cross-platform library is
|
||||||
|
challenging to build. From a more positive perspective, it is also proof that a
|
||||||
|
great deal of complexity can be centralized primarily to one place in order to
|
||||||
|
provide a more consistent and simple experience elsewhere.
|
||||||
|
|
||||||
|
|
||||||
|
### Using These Options
|
||||||
|
|
||||||
|
It doesn't matter if you're using a target-specific compiler and a simulator or
|
||||||
|
a native compiler. In either case, you've got a couple choices for configuring
|
||||||
|
these options:
|
||||||
|
|
||||||
|
1. Because these options are specified via C defines, you can pass most of these
|
||||||
|
options to your compiler through command line compiler flags. Even if you're
|
||||||
|
using an embedded target that forces you to use their overbearing IDE for all
|
||||||
|
configuration, there will be a place somewhere in your project to configure
|
||||||
|
defines for your compiler.
|
||||||
|
2. You can create a custom `unity_config.h` configuration file (present in your
|
||||||
|
toolchain's search paths). In this file, you will list definitions and macros
|
||||||
|
specific to your target. All you must do is define `UNITY_INCLUDE_CONFIG_H` and
|
||||||
|
Unity will rely on `unity_config.h` for any further definitions it may need.
|
||||||
|
|
||||||
|
|
||||||
|
## The Options
|
||||||
|
|
||||||
|
### Integer Types
|
||||||
|
|
||||||
|
If you've been a C developer for long, you probably already know that C's
|
||||||
|
concept of an integer varies from target to target. The C Standard has rules
|
||||||
|
about the `int` matching the register size of the target microprocessor. It has
|
||||||
|
rules about the `int` and how its size relates to other integer types. An `int`
|
||||||
|
on one target might be 16 bits while on another target it might be 64. There are
|
||||||
|
more specific types in compilers compliant with C99 or later, but that's
|
||||||
|
certainly not every compiler you are likely to encounter. Therefore, Unity has a
|
||||||
|
number of features for helping to adjust itself to match your required integer
|
||||||
|
sizes. It starts off by trying to do it automatically.
|
||||||
|
|
||||||
|
|
||||||
|
##### `UNITY_EXCLUDE_STDINT_H`
|
||||||
|
|
||||||
|
The first thing that Unity does to guess your types is check `stdint.h`.
|
||||||
|
This file includes defines like `UINT_MAX` that Unity can make use of to
|
||||||
|
learn a lot about your system. It's possible you don't want it to do this
|
||||||
|
(um. why not?) or (more likely) it's possible that your system doesn't
|
||||||
|
support `stdint.h`. If that's the case, you're going to want to define this.
|
||||||
|
That way, Unity will know to skip the inclusion of this file and you won't
|
||||||
|
be left with a compiler error.
|
||||||
|
|
||||||
|
_Example:_
|
||||||
|
#define UNITY_EXCLUDE_STDINT_H
|
||||||
|
|
||||||
|
|
||||||
|
##### `UNITY_EXCLUDE_LIMITS_H`
|
||||||
|
|
||||||
|
The second attempt to guess your types is to check `limits.h`. Some compilers
|
||||||
|
that don't support `stdint.h` could include `limits.h` instead. If you don't
|
||||||
|
want Unity to check this file either, define this to make it skip the inclusion.
|
||||||
|
|
||||||
|
_Example:_
|
||||||
|
#define UNITY_EXCLUDE_LIMITS_H
|
||||||
|
|
||||||
|
|
||||||
|
##### `UNITY_EXCLUDE_SIZEOF`
|
||||||
|
|
||||||
|
The third and final attempt to guess your types is to use the `sizeof()`
|
||||||
|
operator. Even if the first two options don't work, this one covers most cases.
|
||||||
|
There _is_ a rare compiler or two out there that doesn't support sizeof() in the
|
||||||
|
preprocessing stage, though. For these, you have the ability to disable this
|
||||||
|
feature as well.
|
||||||
|
|
||||||
|
_Example:_
|
||||||
|
#define UNITY_EXCLUDE_SIZEOF
|
||||||
|
|
||||||
|
If you've disabled all of the automatic options above, you're going to have to
|
||||||
|
do the configuration yourself. Don't worry. Even this isn't too bad... there are
|
||||||
|
just a handful of defines that you are going to specify if you don't like the
|
||||||
|
defaults.
|
||||||
|
|
||||||
|
|
||||||
|
##### `UNITY_INT_WIDTH`
|
||||||
|
|
||||||
|
Define this to be the number of bits an `int` takes up on your system. The
|
||||||
|
default, if not autodetected, is 32 bits.
|
||||||
|
|
||||||
|
_Example:_
|
||||||
|
#define UNITY_INT_WIDTH 16
|
||||||
|
|
||||||
|
|
||||||
|
##### `UNITY_LONG_WIDTH`
|
||||||
|
|
||||||
|
Define this to be the number of bits a `long` takes up on your system. The
|
||||||
|
default, if not autodetected, is 32 bits. This is used to figure out what kind
|
||||||
|
of 64-bit support your system can handle. Does it need to specify a `long` or a
|
||||||
|
`long long` to get a 64-bit value. On 16-bit systems, this option is going to be
|
||||||
|
ignored.
|
||||||
|
|
||||||
|
_Example:_
|
||||||
|
#define UNITY_LONG_WIDTH 16
|
||||||
|
|
||||||
|
|
||||||
|
##### `UNITY_POINTER_WIDTH`
|
||||||
|
|
||||||
|
Define this to be the number of bits a pointer takes up on your system. The
|
||||||
|
default, if not autodetected, is 32-bits. If you're getting ugly compiler
|
||||||
|
warnings about casting from pointers, this is the one to look at.
|
||||||
|
|
||||||
|
_Example:_
|
||||||
|
#define UNITY_POINTER_WIDTH 64
|
||||||
|
|
||||||
|
|
||||||
|
##### `UNITY_INCLUDE_64`
|
||||||
|
|
||||||
|
Unity will automatically include 64-bit support if it auto-detects it, or if
|
||||||
|
your `int`, `long`, or pointer widths are greater than 32-bits. Define this to
|
||||||
|
enable 64-bit support if none of the other options already did it for you. There
|
||||||
|
can be a significant size and speed impact to enabling 64-bit support on small
|
||||||
|
targets, so don't define it if you don't need it.
|
||||||
|
|
||||||
|
_Example:_
|
||||||
|
#define UNITY_INCLUDE_64
|
||||||
|
|
||||||
|
|
||||||
|
### Floating Point Types
|
||||||
|
|
||||||
|
In the embedded world, it's not uncommon for targets to have no support for
|
||||||
|
floating point operations at all or to have support that is limited to only
|
||||||
|
single precision. We are able to guess integer sizes on the fly because integers
|
||||||
|
are always available in at least one size. Floating point, on the other hand, is
|
||||||
|
sometimes not available at all. Trying to include `float.h` on these platforms
|
||||||
|
would result in an error. This leaves manual configuration as the only option.
|
||||||
|
|
||||||
|
|
||||||
|
##### `UNITY_INCLUDE_FLOAT`
|
||||||
|
|
||||||
|
##### `UNITY_EXCLUDE_FLOAT`
|
||||||
|
|
||||||
|
##### `UNITY_INCLUDE_DOUBLE`
|
||||||
|
|
||||||
|
##### `UNITY_EXCLUDE_DOUBLE`
|
||||||
|
|
||||||
|
By default, Unity guesses that you will want single precision floating point
|
||||||
|
support, but not double precision. It's easy to change either of these using the
|
||||||
|
include and exclude options here. You may include neither, either, or both, as
|
||||||
|
suits your needs. For features that are enabled, the following floating point
|
||||||
|
options also become available.
|
||||||
|
|
||||||
|
_Example:_
|
||||||
|
|
||||||
|
//what manner of strange processor is this?
|
||||||
|
#define UNITY_EXCLUDE_FLOAT
|
||||||
|
#define UNITY_INCLUDE_DOUBLE
|
||||||
|
|
||||||
|
|
||||||
|
##### `UNITY_FLOAT_VERBOSE`
|
||||||
|
|
||||||
|
##### `UNITY_DOUBLE_VERBOSE`
|
||||||
|
|
||||||
|
Unity aims for as small of a footprint as possible and avoids most standard
|
||||||
|
library calls (some embedded platforms don't have a standard library!). Because
|
||||||
|
of this, its routines for printing integer values are minimalist and hand-coded.
|
||||||
|
To keep Unity universal, though, we chose to _not_ develop our own floating
|
||||||
|
point print routines. Instead, the display of floating point values during a
|
||||||
|
failure are optional. By default, Unity will not print the actual results of
|
||||||
|
floating point assertion failure. So a failed assertion will produce a message
|
||||||
|
like `"Values Not Within Delta"`. If you would like verbose failure messages for
|
||||||
|
floating point assertions, use these options to give more explicit failure
|
||||||
|
messages (e.g. `"Expected 4.56 Was 4.68"`). Note that this feature requires the
|
||||||
|
use of `sprintf` so might not be desirable in all cases.
|
||||||
|
|
||||||
|
_Example:_
|
||||||
|
#define UNITY_DOUBLE_VERBOSE
|
||||||
|
|
||||||
|
|
||||||
|
##### `UNITY_FLOAT_TYPE`
|
||||||
|
|
||||||
|
If enabled, Unity assumes you want your `FLOAT` asserts to compare standard C
|
||||||
|
floats. If your compiler supports a specialty floating point type, you can
|
||||||
|
always override this behavior by using this definition.
|
||||||
|
|
||||||
|
_Example:_
|
||||||
|
#define UNITY_FLOAT_TYPE float16_t
|
||||||
|
|
||||||
|
|
||||||
|
##### `UNITY_DOUBLE_TYPE`
|
||||||
|
|
||||||
|
If enabled, Unity assumes you want your `DOUBLE` asserts to compare standard C
|
||||||
|
doubles. If you would like to change this, you can specify something else by
|
||||||
|
using this option. For example, defining `UNITY_DOUBLE_TYPE` to `long double`
|
||||||
|
could enable gargantuan floating point types on your 64-bit processor instead of
|
||||||
|
the standard `double`.
|
||||||
|
|
||||||
|
_Example:_
|
||||||
|
#define UNITY_DOUBLE_TYPE long double
|
||||||
|
|
||||||
|
|
||||||
|
##### `UNITY_FLOAT_PRECISION`
|
||||||
|
|
||||||
|
##### `UNITY_DOUBLE_PRECISION`
|
||||||
|
|
||||||
|
If you look up `UNITY_ASSERT_EQUAL_FLOAT` and `UNITY_ASSERT_EQUAL_DOUBLE` as
|
||||||
|
documented in the big daddy Unity Assertion Guide, you will learn that they are
|
||||||
|
not really asserting that two values are equal but rather that two values are
|
||||||
|
"close enough" to equal. "Close enough" is controlled by these precision
|
||||||
|
configuration options. If you are working with 32-bit floats and/or 64-bit
|
||||||
|
doubles (the normal on most processors), you should have no need to change these
|
||||||
|
options. They are both set to give you approximately 1 significant bit in either
|
||||||
|
direction. The float precision is 0.00001 while the double is 10-12.
|
||||||
|
For further details on how this works, see the appendix of the Unity Assertion
|
||||||
|
Guide.
|
||||||
|
|
||||||
|
_Example:_
|
||||||
|
#define UNITY_FLOAT_PRECISION 0.001f
|
||||||
|
|
||||||
|
|
||||||
|
### Toolset Customization
|
||||||
|
|
||||||
|
In addition to the options listed above, there are a number of other options
|
||||||
|
which will come in handy to customize Unity's behavior for your specific
|
||||||
|
toolchain. It is possible that you may not need to touch any of these... but
|
||||||
|
certain platforms, particularly those running in simulators, may need to jump
|
||||||
|
through extra hoops to operate properly. These macros will help in those
|
||||||
|
situations.
|
||||||
|
|
||||||
|
|
||||||
|
##### `UNITY_OUTPUT_CHAR(a)`
|
||||||
|
|
||||||
|
##### `UNITY_OUTPUT_FLUSH()`
|
||||||
|
|
||||||
|
##### `UNITY_OUTPUT_START()`
|
||||||
|
|
||||||
|
##### `UNITY_OUTPUT_COMPLETE()`
|
||||||
|
|
||||||
|
By default, Unity prints its results to `stdout` as it runs. This works
|
||||||
|
perfectly fine in most situations where you are using a native compiler for
|
||||||
|
testing. It works on some simulators as well so long as they have `stdout`
|
||||||
|
routed back to the command line. There are times, however, where the simulator
|
||||||
|
will lack support for dumping results or you will want to route results
|
||||||
|
elsewhere for other reasons. In these cases, you should define the
|
||||||
|
`UNITY_OUTPUT_CHAR` macro. This macro accepts a single character at a time (as
|
||||||
|
an `int`, since this is the parameter type of the standard C `putchar` function
|
||||||
|
most commonly used). You may replace this with whatever function call you like.
|
||||||
|
|
||||||
|
_Example:_
|
||||||
|
Say you are forced to run your test suite on an embedded processor with no
|
||||||
|
`stdout` option. You decide to route your test result output to a custom serial
|
||||||
|
`RS232_putc()` function you wrote like thus:
|
||||||
|
|
||||||
|
#define UNITY_OUTPUT_CHAR(a) RS232_putc(a)
|
||||||
|
#define UNITY_OUTPUT_START() RS232_config(115200,1,8,0)
|
||||||
|
#define UNITY_OUTPUT_FLUSH() RS232_flush()
|
||||||
|
#define UNITY_OUTPUT_COMPLETE() RS232_close()
|
||||||
|
|
||||||
|
_Note:_
|
||||||
|
`UNITY_OUTPUT_FLUSH()` can be set to the standard out flush function simply by
|
||||||
|
specifying `UNITY_USE_FLUSH_STDOUT`. No other defines are required. If you
|
||||||
|
specify a custom flush function instead with `UNITY_OUTPUT_FLUSH` directly, it
|
||||||
|
will declare an instance of your function by default. If you want to disable
|
||||||
|
this behavior, add `UNITY_OMIT_OUTPUT_FLUSH_HEADER_DECLARATION`.
|
||||||
|
|
||||||
|
|
||||||
|
##### `UNITY_SUPPORT_WEAK`
|
||||||
|
|
||||||
|
For some targets, Unity can make the otherwise required `setUp()` and
|
||||||
|
`tearDown()` functions optional. This is a nice convenience for test writers
|
||||||
|
since `setUp` and `tearDown` don't often actually _do_ anything. If you're using
|
||||||
|
gcc or clang, this option is automatically defined for you. Other compilers can
|
||||||
|
also support this behavior, if they support a C feature called weak functions. A
|
||||||
|
weak function is a function that is compiled into your executable _unless_ a
|
||||||
|
non-weak version of the same function is defined elsewhere. If a non-weak
|
||||||
|
version is found, the weak version is ignored as if it never existed. If your
|
||||||
|
compiler supports this feature, you can let Unity know by defining
|
||||||
|
`UNITY_SUPPORT_WEAK` as the function attributes that would need to be applied to
|
||||||
|
identify a function as weak. If your compiler lacks support for weak functions,
|
||||||
|
you will always need to define `setUp` and `tearDown` functions (though they can
|
||||||
|
be and often will be just empty). The most common options for this feature are:
|
||||||
|
|
||||||
|
_Example:_
|
||||||
|
#define UNITY_SUPPORT_WEAK weak
|
||||||
|
#define UNITY_SUPPORT_WEAK __attribute__((weak))
|
||||||
|
|
||||||
|
|
||||||
|
##### `UNITY_PTR_ATTRIBUTE`
|
||||||
|
|
||||||
|
Some compilers require a custom attribute to be assigned to pointers, like
|
||||||
|
`near` or `far`. In these cases, you can give Unity a safe default for these by
|
||||||
|
defining this option with the attribute you would like.
|
||||||
|
|
||||||
|
_Example:_
|
||||||
|
#define UNITY_PTR_ATTRIBUTE __attribute__((far))
|
||||||
|
#define UNITY_PTR_ATTRIBUTE near
|
||||||
|
|
||||||
|
|
||||||
|
## Getting Into The Guts
|
||||||
|
|
||||||
|
There will be cases where the options above aren't quite going to get everything
|
||||||
|
perfect. They are likely sufficient for any situation where you are compiling
|
||||||
|
and executing your tests with a native toolchain (e.g. clang on Mac). These
|
||||||
|
options may even get you through the majority of cases encountered in working
|
||||||
|
with a target simulator run from your local command line. But especially if you
|
||||||
|
must run your test suite on your target hardware, your Unity configuration will
|
||||||
|
require special help. This special help will usually reside in one of two
|
||||||
|
places: the `main()` function or the `RUN_TEST` macro. Let's look at how these
|
||||||
|
work.
|
||||||
|
|
||||||
|
|
||||||
|
##### `main()`
|
||||||
|
|
||||||
|
Each test module is compiled and run on its own, separate from the other test
|
||||||
|
files in your project. Each test file, therefore, has a `main` function. This
|
||||||
|
`main` function will need to contain whatever code is necessary to initialize
|
||||||
|
your system to a workable state. This is particularly true for situations where
|
||||||
|
you must set up a memory map or initialize a communication channel for the
|
||||||
|
output of your test results.
|
||||||
|
|
||||||
|
A simple main function looks something like this:
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
UNITY_BEGIN();
|
||||||
|
RUN_TEST(test_TheFirst);
|
||||||
|
RUN_TEST(test_TheSecond);
|
||||||
|
RUN_TEST(test_TheThird);
|
||||||
|
return UNITY_END();
|
||||||
|
}
|
||||||
|
|
||||||
|
You can see that our main function doesn't bother taking any arguments. For our
|
||||||
|
most barebones case, we'll never have arguments because we just run all the
|
||||||
|
tests each time. Instead, we start by calling `UNITY_BEGIN`. We run each test
|
||||||
|
(in whatever order we wish). Finally, we call `UNITY_END`, returning its return
|
||||||
|
value (which is the total number of failures).
|
||||||
|
|
||||||
|
It should be easy to see that you can add code before any test cases are run or
|
||||||
|
after all the test cases have completed. This allows you to do any needed
|
||||||
|
system-wide setup or teardown that might be required for your special
|
||||||
|
circumstances.
|
||||||
|
|
||||||
|
|
||||||
|
##### `RUN_TEST`
|
||||||
|
|
||||||
|
The `RUN_TEST` macro is called with each test case function. Its job is to
|
||||||
|
perform whatever setup and teardown is necessary for executing a single test
|
||||||
|
case function. This includes catching failures, calling the test module's
|
||||||
|
`setUp()` and `tearDown()` functions, and calling `UnityConcludeTest()`. If
|
||||||
|
using CMock or test coverage, there will be additional stubs in use here. A
|
||||||
|
simple minimalist RUN_TEST macro looks something like this:
|
||||||
|
|
||||||
|
#define RUN_TEST(testfunc) \
|
||||||
|
UNITY_NEW_TEST(#testfunc) \
|
||||||
|
if (TEST_PROTECT()) { \
|
||||||
|
setUp(); \
|
||||||
|
testfunc(); \
|
||||||
|
} \
|
||||||
|
if (TEST_PROTECT() && (!TEST_IS_IGNORED)) \
|
||||||
|
tearDown(); \
|
||||||
|
UnityConcludeTest();
|
||||||
|
|
||||||
|
So that's quite a macro, huh? It gives you a glimpse of what kind of stuff Unity
|
||||||
|
has to deal with for every single test case. For each test case, we declare that
|
||||||
|
it is a new test. Then we run `setUp` and our test function. These are run
|
||||||
|
within a `TEST_PROTECT` block, the function of which is to handle failures that
|
||||||
|
occur during the test. Then, assuming our test is still running and hasn't been
|
||||||
|
ignored, we run `tearDown`. No matter what, our last step is to conclude this
|
||||||
|
test before moving on to the next.
|
||||||
|
|
||||||
|
Let's say you need to add a call to `fsync` to force all of your output data to
|
||||||
|
flush to a file after each test. You could easily insert this after your
|
||||||
|
`UnityConcludeTest` call. Maybe you want to write an xml tag before and after
|
||||||
|
each result set. Again, you could do this by adding lines to this macro. Updates
|
||||||
|
to this macro are for the occasions when you need an action before or after
|
||||||
|
every single test case throughout your entire suite of tests.
|
||||||
|
|
||||||
|
|
||||||
|
## Happy Porting
|
||||||
|
|
||||||
|
The defines and macros in this guide should help you port Unity to just about
|
||||||
|
any C target we can imagine. If you run into a snag or two, don't be afraid of
|
||||||
|
asking for help on the forums. We love a good challenge!
|
||||||
|
|
||||||
|
|
||||||
|
*Find The Latest of This And More at [ThrowTheSwitch.org](https://throwtheswitch.org)*
|
Binary file not shown.
191
tests/unity/docs/UnityGettingStartedGuide.md
Normal file
191
tests/unity/docs/UnityGettingStartedGuide.md
Normal file
@ -0,0 +1,191 @@
|
|||||||
|
# Unity - Getting Started
|
||||||
|
|
||||||
|
## Welcome
|
||||||
|
|
||||||
|
Congratulations. You're now the proud owner of your very own pile of bits! What
|
||||||
|
are you going to do with all these ones and zeros? This document should be able
|
||||||
|
to help you decide just that.
|
||||||
|
|
||||||
|
Unity is a unit test framework. The goal has been to keep it small and
|
||||||
|
functional. The core Unity test framework is three files: a single C file and a
|
||||||
|
couple header files. These team up to provide functions and macros to make
|
||||||
|
testing easier.
|
||||||
|
|
||||||
|
Unity was designed to be cross platform. It works hard to stick with C standards
|
||||||
|
while still providing support for the many embedded C compilers that bend the
|
||||||
|
rules. Unity has been used with many compilers, including GCC, IAR, Clang,
|
||||||
|
Green Hills, Microchip, and MS Visual Studio. It's not much work to get it to
|
||||||
|
work with a new target.
|
||||||
|
|
||||||
|
|
||||||
|
### Overview of the Documents
|
||||||
|
|
||||||
|
#### Unity Assertions reference
|
||||||
|
|
||||||
|
This document will guide you through all the assertion options provided by
|
||||||
|
Unity. This is going to be your unit testing bread and butter. You'll spend more
|
||||||
|
time with assertions than any other part of Unity.
|
||||||
|
|
||||||
|
|
||||||
|
#### Unity Assertions Cheat Sheet
|
||||||
|
|
||||||
|
This document contains an abridged summary of the assertions described in the
|
||||||
|
previous document. It's perfect for printing and referencing while you
|
||||||
|
familiarize yourself with Unity's options.
|
||||||
|
|
||||||
|
|
||||||
|
#### Unity Configuration Guide
|
||||||
|
|
||||||
|
This document is the one to reference when you are going to use Unity with a new
|
||||||
|
target or compiler. It'll guide you through the configuration options and will
|
||||||
|
help you customize your testing experience to meet your needs.
|
||||||
|
|
||||||
|
|
||||||
|
#### Unity Helper Scripts
|
||||||
|
|
||||||
|
This document describes the helper scripts that are available for simplifying
|
||||||
|
your testing workflow. It describes the collection of optional Ruby scripts
|
||||||
|
included in the auto directory of your Unity installation. Neither Ruby nor
|
||||||
|
these scripts are necessary for using Unity. They are provided as a convenience
|
||||||
|
for those who wish to use them.
|
||||||
|
|
||||||
|
|
||||||
|
#### Unity License
|
||||||
|
|
||||||
|
What's an open source project without a license file? This brief document
|
||||||
|
describes the terms you're agreeing to when you use this software. Basically, we
|
||||||
|
want it to be useful to you in whatever context you want to use it, but please
|
||||||
|
don't blame us if you run into problems.
|
||||||
|
|
||||||
|
|
||||||
|
### Overview of the Folders
|
||||||
|
|
||||||
|
If you have obtained Unity through Github or something similar, you might be
|
||||||
|
surprised by just how much stuff you suddenly have staring you in the face.
|
||||||
|
Don't worry, Unity itself is very small. The rest of it is just there to make
|
||||||
|
your life easier. You can ignore it or use it at your convenience. Here's an
|
||||||
|
overview of everything in the project.
|
||||||
|
|
||||||
|
- `src` - This is the code you care about! This folder contains a C file and two
|
||||||
|
header files. These three files _are_ Unity.
|
||||||
|
- `docs` - You're reading this document, so it's possible you have found your way
|
||||||
|
into this folder already. This is where all the handy documentation can be
|
||||||
|
found.
|
||||||
|
- `examples` - This contains a few examples of using Unity.
|
||||||
|
- `extras` - These are optional add ons to Unity that are not part of the core
|
||||||
|
project. If you've reached us through James Grenning's book, you're going to
|
||||||
|
want to look here.
|
||||||
|
- `test` - This is how Unity and its scripts are all tested. If you're just using
|
||||||
|
Unity, you'll likely never need to go in here. If you are the lucky team member
|
||||||
|
who gets to port Unity to a new toolchain, this is a good place to verify
|
||||||
|
everything is configured properly.
|
||||||
|
- `auto` - Here you will find helpful Ruby scripts for simplifying your test
|
||||||
|
workflow. They are purely optional and are not required to make use of Unity.
|
||||||
|
|
||||||
|
|
||||||
|
## How to Create A Test File
|
||||||
|
|
||||||
|
Test files are C files. Most often you will create a single test file for each C
|
||||||
|
module that you want to test. The test file should include unity.h and the
|
||||||
|
header for your C module to be tested.
|
||||||
|
|
||||||
|
Next, a test file will include a `setUp()` and `tearDown()` function. The setUp
|
||||||
|
function can contain anything you would like to run before each test. The
|
||||||
|
tearDown function can contain anything you would like to run after each test.
|
||||||
|
Both functions accept no arguments and return nothing. You may leave either or
|
||||||
|
both of these blank if you have no need for them. If you're using a compiler
|
||||||
|
that is configured to make these functions optional, you may leave them off
|
||||||
|
completely. Not sure? Give it a try. If you compiler complains that it can't
|
||||||
|
find setUp or tearDown when it links, you'll know you need to at least include
|
||||||
|
an empty function for these.
|
||||||
|
|
||||||
|
The majority of the file will be a series of test functions. Test functions
|
||||||
|
follow the convention of starting with the word "test" or "spec". You don't HAVE
|
||||||
|
to name them this way, but it makes it clear what functions are tests for other
|
||||||
|
developers. Test functions take no arguments and return nothing. All test
|
||||||
|
accounting is handled internally in Unity.
|
||||||
|
|
||||||
|
Finally, at the bottom of your test file, you will write a `main()` function.
|
||||||
|
This function will call `UNITY_BEGIN()`, then `RUN_TEST` for each test, and
|
||||||
|
finally `UNITY_END()`.This is what will actually trigger each of those test
|
||||||
|
functions to run, so it is important that each function gets its own `RUN_TEST`
|
||||||
|
call.
|
||||||
|
|
||||||
|
Remembering to add each test to the main function can get to be tedious. If you
|
||||||
|
enjoy using helper scripts in your build process, you might consider making use
|
||||||
|
of our handy generate_test_runner.rb script. This will create the main function
|
||||||
|
and all the calls for you, assuming that you have followed the suggested naming
|
||||||
|
conventions. In this case, there is no need for you to include the main function
|
||||||
|
in your test file at all.
|
||||||
|
|
||||||
|
When you're done, your test file will look something like this:
|
||||||
|
|
||||||
|
```C
|
||||||
|
#include "unity.h"
|
||||||
|
#include "file_to_test.h"
|
||||||
|
|
||||||
|
void setUp(void) {
|
||||||
|
// set stuff up here
|
||||||
|
}
|
||||||
|
|
||||||
|
void tearDown(void) {
|
||||||
|
// clean stuff up here
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_function_should_doBlahAndBlah(void) {
|
||||||
|
//test stuff
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_function_should_doAlsoDoBlah(void) {
|
||||||
|
//more test stuff
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
UNITY_BEGIN();
|
||||||
|
RUN_TEST(test_function_should_doBlahAndBlah);
|
||||||
|
RUN_TEST(test_function_should_doAlsoDoBlah);
|
||||||
|
return UNITY_END();
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
It's possible that you will require more customization than this, eventually.
|
||||||
|
For that sort of thing, you're going to want to look at the configuration guide.
|
||||||
|
This should be enough to get you going, though.
|
||||||
|
|
||||||
|
|
||||||
|
## How to Build and Run A Test File
|
||||||
|
|
||||||
|
This is the single biggest challenge to picking up a new unit testing framework,
|
||||||
|
at least in a language like C or C++. These languages are REALLY good at getting
|
||||||
|
you "close to the metal" (why is the phrase metal? Wouldn't it be more accurate
|
||||||
|
to say "close to the silicon"?). While this feature is usually a good thing, it
|
||||||
|
can make testing more challenging.
|
||||||
|
|
||||||
|
You have two really good options for toolchains. Depending on where you're
|
||||||
|
coming from, it might surprise you that neither of these options is running the
|
||||||
|
unit tests on your hardware.
|
||||||
|
There are many reasons for this, but here's a short version:
|
||||||
|
- On hardware, you have too many constraints (processing power, memory, etc),
|
||||||
|
- On hardware, you don't have complete control over all registers,
|
||||||
|
- On hardware, unit testing is more challenging,
|
||||||
|
- Unit testing isn't System testing. Keep them separate.
|
||||||
|
|
||||||
|
Instead of running your tests on your actual hardware, most developers choose to
|
||||||
|
develop them as native applications (using gcc or MSVC for example) or as
|
||||||
|
applications running on a simulator. Either is a good option. Native apps have
|
||||||
|
the advantages of being faster and easier to set up. Simulator apps have the
|
||||||
|
advantage of working with the same compiler as your target application. The
|
||||||
|
options for configuring these are discussed in the configuration guide.
|
||||||
|
|
||||||
|
To get either to work, you might need to make a few changes to the file
|
||||||
|
containing your register set (discussed later).
|
||||||
|
|
||||||
|
In either case, a test is built by linking unity, the test file, and the C
|
||||||
|
file(s) being tested. These files create an executable which can be run as the
|
||||||
|
test set for that module. Then, this process is repeated for the next test file.
|
||||||
|
This flexibility of separating tests into individual executables allows us to
|
||||||
|
much more thoroughly unit test our system and it keeps all the test code out of
|
||||||
|
our final release!
|
||||||
|
|
||||||
|
|
||||||
|
*Find The Latest of This And More at [ThrowTheSwitch.org](https://throwtheswitch.org)*
|
Binary file not shown.
242
tests/unity/docs/UnityHelperScriptsGuide.md
Normal file
242
tests/unity/docs/UnityHelperScriptsGuide.md
Normal file
@ -0,0 +1,242 @@
|
|||||||
|
# Unity Helper Scripts
|
||||||
|
|
||||||
|
## With a Little Help From Our Friends
|
||||||
|
|
||||||
|
Sometimes what it takes to be a really efficient C programmer is a little non-C.
|
||||||
|
The Unity project includes a couple Ruby scripts for making your life just a tad
|
||||||
|
easier. They are completely optional. If you choose to use them, you'll need a
|
||||||
|
copy of Ruby, of course. Just install whatever the latest version is, and it is
|
||||||
|
likely to work. You can find Ruby at [ruby-lang.org](https://ruby-labg.org/).
|
||||||
|
|
||||||
|
|
||||||
|
### `generate_test_runner.rb`
|
||||||
|
|
||||||
|
Are you tired of creating your own `main` function in your test file? Do you
|
||||||
|
keep forgetting to add a `RUN_TEST` call when you add a new test case to your
|
||||||
|
suite? Do you want to use CMock or other fancy add-ons but don't want to figure
|
||||||
|
out how to create your own `RUN_TEST` macro?
|
||||||
|
|
||||||
|
Well then we have the perfect script for you!
|
||||||
|
|
||||||
|
The `generate_test_runner` script processes a given test file and automatically
|
||||||
|
creates a separate test runner file that includes ?main?to execute the test
|
||||||
|
cases within the scanned test file. All you do then is add the generated runner
|
||||||
|
to your list of files to be compiled and linked, and presto you're done!
|
||||||
|
|
||||||
|
This script searches your test file for void function signatures having a
|
||||||
|
function name beginning with "test" or "spec". It treats each of these
|
||||||
|
functions as a test case and builds up a test suite of them. For example, the
|
||||||
|
following includes three test cases:
|
||||||
|
|
||||||
|
```C
|
||||||
|
void testVerifyThatUnityIsAwesomeAndWillMakeYourLifeEasier(void)
|
||||||
|
{
|
||||||
|
ASSERT_TRUE(1);
|
||||||
|
}
|
||||||
|
void test_FunctionName_should_WorkProperlyAndReturn8(void) {
|
||||||
|
ASSERT_EQUAL_INT(8, FunctionName());
|
||||||
|
}
|
||||||
|
void spec_Function_should_DoWhatItIsSupposedToDo(void) {
|
||||||
|
ASSERT_NOT_NULL(Function(5));
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
You can run this script a couple of ways. The first is from the command line:
|
||||||
|
|
||||||
|
```Shell
|
||||||
|
ruby generate_test_runner.rb TestFile.c NameOfRunner.c
|
||||||
|
```
|
||||||
|
|
||||||
|
Alternatively, if you include only the test file parameter, the script will copy
|
||||||
|
the name of the test file and automatically append "_Runner" to the name of the
|
||||||
|
generated file. The example immediately below will create TestFile_Runner.c.
|
||||||
|
|
||||||
|
```Shell
|
||||||
|
ruby generate_test_runner.rb TestFile.c
|
||||||
|
```
|
||||||
|
|
||||||
|
You can also add a [YAML](http://www.yaml.org/) file to configure extra options.
|
||||||
|
Conveniently, this YAML file is of the same format as that used by Unity and
|
||||||
|
CMock. So if you are using YAML files already, you can simply pass the very same
|
||||||
|
file into the generator script.
|
||||||
|
|
||||||
|
```Shell
|
||||||
|
ruby generate_test_runner.rb TestFile.c my_config.yml
|
||||||
|
```
|
||||||
|
|
||||||
|
The contents of the YAML file `my_config.yml` could look something like the
|
||||||
|
example below. If you're wondering what some of these options do, you're going
|
||||||
|
to love the next section of this document.
|
||||||
|
|
||||||
|
```YAML
|
||||||
|
:unity:
|
||||||
|
:includes:
|
||||||
|
- stdio.h
|
||||||
|
- microdefs.h
|
||||||
|
:cexception: 1
|
||||||
|
:suit_setup: "blah = malloc(1024);"
|
||||||
|
:suite_teardown: "free(blah);"
|
||||||
|
```
|
||||||
|
|
||||||
|
If you would like to force your generated test runner to include one or more
|
||||||
|
header files, you can just include those at the command line too. Just make sure
|
||||||
|
these are _after_ the YAML file, if you are using one:
|
||||||
|
|
||||||
|
```Shell
|
||||||
|
ruby generate_test_runner.rb TestFile.c my_config.yml extras.h
|
||||||
|
```
|
||||||
|
|
||||||
|
Another option, particularly if you are already using Ruby to orchestrate your
|
||||||
|
builds - or more likely the Ruby-based build tool Rake - is requiring this
|
||||||
|
script directly. Anything that you would have specified in a YAML file can be
|
||||||
|
passed to the script as part of a hash. Let's push the exact same requirement
|
||||||
|
set as we did above but this time through Ruby code directly:
|
||||||
|
|
||||||
|
```Ruby
|
||||||
|
require "generate_test_runner.rb"
|
||||||
|
options = {
|
||||||
|
:includes => ["stdio.h", "microdefs.h"],
|
||||||
|
:cexception => 1,
|
||||||
|
:suite_setup => "blah = malloc(1024);",
|
||||||
|
:suite_teardown => "free(blah);"
|
||||||
|
}
|
||||||
|
UnityTestRunnerGenerator.new.run(testfile, runner_name, options)
|
||||||
|
```
|
||||||
|
|
||||||
|
If you have multiple files to generate in a build script (such as a Rakefile),
|
||||||
|
you might want to instantiate a generator object with your options and call it
|
||||||
|
to generate each runner thereafter. Like thus:
|
||||||
|
|
||||||
|
```Ruby
|
||||||
|
gen = UnityTestRunnerGenerator.new(options)
|
||||||
|
test_files.each do |f|
|
||||||
|
gen.run(f, File.basename(f,'.c')+"Runner.c"
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Options accepted by generate_test_runner.rb:
|
||||||
|
|
||||||
|
The following options are available when executing `generate_test_runner`. You
|
||||||
|
may pass these as a Ruby hash directly or specify them in a YAML file, both of
|
||||||
|
which are described above. In the `examples` directory, Example 3's Rakefile
|
||||||
|
demonstrates using a Ruby hash.
|
||||||
|
|
||||||
|
|
||||||
|
##### `:includes`
|
||||||
|
|
||||||
|
This option specifies an array of file names to be ?#include?'d at the top of
|
||||||
|
your runner C file. You might use it to reference custom types or anything else
|
||||||
|
universally needed in your generated runners.
|
||||||
|
|
||||||
|
|
||||||
|
##### `:suite_setup`
|
||||||
|
|
||||||
|
Define this option with C code to be executed _before any_ test cases are run.
|
||||||
|
|
||||||
|
|
||||||
|
##### `:suite_teardown`
|
||||||
|
|
||||||
|
Define this option with C code to be executed ?after all?test cases have
|
||||||
|
finished.
|
||||||
|
|
||||||
|
|
||||||
|
##### `:enforce_strict_ordering`
|
||||||
|
|
||||||
|
This option should be defined if you have the strict order feature enabled in
|
||||||
|
CMock (see CMock documentation). This generates extra variables required for
|
||||||
|
everything to run smoothly. If you provide the same YAML to the generator as
|
||||||
|
used in CMock's configuration, you've already configured the generator properly.
|
||||||
|
|
||||||
|
|
||||||
|
##### `:plugins`
|
||||||
|
|
||||||
|
This option specifies an array of plugins to be used (of course, the array can
|
||||||
|
contain only a single plugin). This is your opportunity to enable support for
|
||||||
|
CException support, which will add a check for unhandled exceptions in each
|
||||||
|
test, reporting a failure if one is detected. To enable this feature using Ruby:
|
||||||
|
|
||||||
|
```Ruby
|
||||||
|
:plugins => [ :cexception ]
|
||||||
|
```
|
||||||
|
|
||||||
|
Or as a yaml file:
|
||||||
|
|
||||||
|
```YAML
|
||||||
|
:plugins:
|
||||||
|
-:cexception
|
||||||
|
```
|
||||||
|
|
||||||
|
If you are using CMock, it is very likely that you are already passing an array
|
||||||
|
of plugins to CMock. You can just use the same array here. This script will just
|
||||||
|
ignore the plugins that don't require additional support.
|
||||||
|
|
||||||
|
|
||||||
|
### `unity_test_summary.rb`
|
||||||
|
|
||||||
|
A Unity test file contains one or more test case functions. Each test case can
|
||||||
|
pass, fail, or be ignored. Each test file is run individually producing results
|
||||||
|
for its collection of test cases. A given project will almost certainly be
|
||||||
|
composed of multiple test files. Therefore, the suite of tests is comprised of
|
||||||
|
one or more test cases spread across one or more test files. This script
|
||||||
|
aggregates individual test file results to generate a summary of all executed
|
||||||
|
test cases. The output includes how many tests were run, how many were ignored,
|
||||||
|
and how many failed. In addition, the output includes a listing of which
|
||||||
|
specific tests were ignored and failed. A good example of the breadth and
|
||||||
|
details of these results can be found in the `examples` directory. Intentionally
|
||||||
|
ignored and failing tests in this project generate corresponding entries in the
|
||||||
|
summary report.
|
||||||
|
|
||||||
|
If you're interested in other (prettier?) output formats, check into the
|
||||||
|
Ceedling build tool project (ceedling.sourceforge.net) that works with Unity and
|
||||||
|
CMock and supports xunit-style xml as well as other goodies.
|
||||||
|
|
||||||
|
This script assumes the existence of files ending with the extensions
|
||||||
|
`.testpass` and `.testfail`.The contents of these files includes the test
|
||||||
|
results summary corresponding to each test file executed with the extension set
|
||||||
|
according to the presence or absence of failures for that test file. The script
|
||||||
|
searches a specified path for these files, opens each one it finds, parses the
|
||||||
|
results, and aggregates and prints a summary. Calling it from the command line
|
||||||
|
looks like this:
|
||||||
|
|
||||||
|
```Shell
|
||||||
|
ruby unity_test_summary.rb build/test/
|
||||||
|
```
|
||||||
|
|
||||||
|
You can optionally specify a root path as well. This is really helpful when you
|
||||||
|
are using relative paths in your tools' setup, but you want to pull the summary
|
||||||
|
into an IDE like Eclipse for clickable shortcuts.
|
||||||
|
|
||||||
|
```Shell
|
||||||
|
ruby unity_test_summary.rb build/test/ ~/projects/myproject/
|
||||||
|
```
|
||||||
|
|
||||||
|
Or, if you're more of a Windows sort of person:
|
||||||
|
|
||||||
|
```Shell
|
||||||
|
ruby unity_test_summary.rb build\teat\ C:\projects\myproject\
|
||||||
|
```
|
||||||
|
|
||||||
|
When configured correctly, you'll see a final summary, like so:
|
||||||
|
|
||||||
|
```Shell
|
||||||
|
--------------------------
|
||||||
|
UNITY IGNORED TEST SUMMARY
|
||||||
|
--------------------------
|
||||||
|
blah.c:22:test_sandwiches_should_HaveBreadOnTwoSides:IGNORE
|
||||||
|
|
||||||
|
-------------------------
|
||||||
|
UNITY FAILED TEST SUMMARY
|
||||||
|
-------------------------
|
||||||
|
blah.c:87:test_sandwiches_should_HaveCondiments:FAIL:Expected 1 was 0
|
||||||
|
meh.c:38:test_soda_should_BeCalledPop:FAIL:Expected "pop" was "coke"
|
||||||
|
|
||||||
|
--------------------------
|
||||||
|
OVERALL UNITY TEST SUMMARY
|
||||||
|
--------------------------
|
||||||
|
45 TOTAL TESTS 2 TOTAL FAILURES 1 IGNORED
|
||||||
|
```
|
||||||
|
|
||||||
|
How convenient is that?
|
||||||
|
|
||||||
|
|
||||||
|
*Find The Latest of This And More at [ThrowTheSwitch.org](https://throwtheswitch.org)*
|
Binary file not shown.
@ -3,41 +3,41 @@ UNITY_ROOT = File.expand_path(File.dirname(__FILE__)) + '/../..'
|
|||||||
|
|
||||||
require 'rake'
|
require 'rake'
|
||||||
require 'rake/clean'
|
require 'rake/clean'
|
||||||
require HERE+'rakefile_helper'
|
require HERE + 'rakefile_helper'
|
||||||
|
|
||||||
TEMP_DIRS = [
|
TEMP_DIRS = [
|
||||||
File.join(HERE, 'build')
|
File.join(HERE, 'build')
|
||||||
]
|
].freeze
|
||||||
|
|
||||||
TEMP_DIRS.each do |dir|
|
TEMP_DIRS.each do |dir|
|
||||||
directory(dir)
|
directory(dir)
|
||||||
CLOBBER.include(dir)
|
CLOBBER.include(dir)
|
||||||
end
|
end
|
||||||
|
|
||||||
task :prepare_for_tests => TEMP_DIRS
|
task prepare_for_tests: TEMP_DIRS
|
||||||
|
|
||||||
include RakefileHelpers
|
include RakefileHelpers
|
||||||
|
|
||||||
# Load default configuration, for now
|
# Load default configuration, for now
|
||||||
DEFAULT_CONFIG_FILE = 'target_gcc_32.yml'
|
DEFAULT_CONFIG_FILE = 'target_gcc_32.yml'.freeze
|
||||||
configure_toolchain(DEFAULT_CONFIG_FILE)
|
configure_toolchain(DEFAULT_CONFIG_FILE)
|
||||||
|
|
||||||
task :unit => [:prepare_for_tests] do
|
task unit: [:prepare_for_tests] do
|
||||||
run_tests get_unit_test_files
|
run_tests unit_test_files
|
||||||
end
|
end
|
||||||
|
|
||||||
desc "Generate test summary"
|
desc 'Generate test summary'
|
||||||
task :summary do
|
task :summary do
|
||||||
report_summary
|
report_summary
|
||||||
end
|
end
|
||||||
|
|
||||||
desc "Build and test Unity"
|
desc 'Build and test Unity'
|
||||||
task :all => [:clean, :unit, :summary]
|
task all: %i(clean unit summary)
|
||||||
task :default => [:clobber, :all]
|
task default: %i(clobber all)
|
||||||
task :ci => [:default]
|
task ci: [:default]
|
||||||
task :cruise => [:default]
|
task cruise: [:default]
|
||||||
|
|
||||||
desc "Load configuration"
|
desc 'Load configuration'
|
||||||
task :config, :config_file do |t, args|
|
task :config, :config_file do |_t, args|
|
||||||
configure_toolchain(args[:config_file])
|
configure_toolchain(args[:config_file])
|
||||||
end
|
end
|
||||||
|
@ -1,12 +1,11 @@
|
|||||||
require 'yaml'
|
require 'yaml'
|
||||||
require 'fileutils'
|
require 'fileutils'
|
||||||
require UNITY_ROOT+'/auto/unity_test_summary'
|
require UNITY_ROOT + '/auto/unity_test_summary'
|
||||||
require UNITY_ROOT+'/auto/generate_test_runner'
|
require UNITY_ROOT + '/auto/generate_test_runner'
|
||||||
require UNITY_ROOT+'/auto/colour_reporter'
|
require UNITY_ROOT + '/auto/colour_reporter'
|
||||||
|
|
||||||
module RakefileHelpers
|
module RakefileHelpers
|
||||||
|
C_EXTENSION = '.c'.freeze
|
||||||
C_EXTENSION = '.c'
|
|
||||||
|
|
||||||
def load_configuration(config_file)
|
def load_configuration(config_file)
|
||||||
$cfg_file = config_file
|
$cfg_file = config_file
|
||||||
@ -17,22 +16,22 @@ module RakefileHelpers
|
|||||||
CLEAN.include($cfg['compiler']['build_path'] + '*.*') unless $cfg['compiler']['build_path'].nil?
|
CLEAN.include($cfg['compiler']['build_path'] + '*.*') unless $cfg['compiler']['build_path'].nil?
|
||||||
end
|
end
|
||||||
|
|
||||||
def configure_toolchain(config_file=DEFAULT_CONFIG_FILE)
|
def configure_toolchain(config_file = DEFAULT_CONFIG_FILE)
|
||||||
config_file += '.yml' unless config_file =~ /\.yml$/
|
config_file += '.yml' unless config_file =~ /\.yml$/
|
||||||
load_configuration(config_file)
|
load_configuration(config_file)
|
||||||
configure_clean
|
configure_clean
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_unit_test_files
|
def unit_test_files
|
||||||
path = $cfg['compiler']['unit_tests_path'] + 'Test*' + C_EXTENSION
|
path = $cfg['compiler']['unit_tests_path'] + 'Test*' + C_EXTENSION
|
||||||
path.gsub!(/\\/, '/')
|
path.tr!('\\', '/')
|
||||||
FileList.new(path)
|
FileList.new(path)
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_local_include_dirs
|
def local_include_dirs
|
||||||
include_dirs = $cfg['compiler']['includes']['items'].dup
|
include_dirs = $cfg['compiler']['includes']['items'].dup
|
||||||
include_dirs.delete_if {|dir| dir.is_a?(Array)}
|
include_dirs.delete_if { |dir| dir.is_a?(Array) }
|
||||||
return include_dirs
|
include_dirs
|
||||||
end
|
end
|
||||||
|
|
||||||
def extract_headers(filename)
|
def extract_headers(filename)
|
||||||
@ -40,129 +39,126 @@ module RakefileHelpers
|
|||||||
lines = File.readlines(filename)
|
lines = File.readlines(filename)
|
||||||
lines.each do |line|
|
lines.each do |line|
|
||||||
m = line.match(/^\s*#include\s+\"\s*(.+\.[hH])\s*\"/)
|
m = line.match(/^\s*#include\s+\"\s*(.+\.[hH])\s*\"/)
|
||||||
if not m.nil?
|
includes << m[1] unless m.nil?
|
||||||
includes << m[1]
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
return includes
|
includes
|
||||||
end
|
end
|
||||||
|
|
||||||
def find_source_file(header, paths)
|
def find_source_file(header, paths)
|
||||||
paths.each do |dir|
|
paths.each do |dir|
|
||||||
src_file = dir + header.ext(C_EXTENSION)
|
src_file = dir + header.ext(C_EXTENSION)
|
||||||
if (File.exists?(src_file))
|
return src_file if File.exist?(src_file)
|
||||||
return src_file
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
return nil
|
nil
|
||||||
end
|
end
|
||||||
|
|
||||||
def tackit(strings)
|
def tackit(strings)
|
||||||
if strings.is_a?(Array)
|
result = if strings.is_a?(Array)
|
||||||
result = "\"#{strings.join}\""
|
"\"#{strings.join}\""
|
||||||
else
|
else
|
||||||
result = strings
|
strings
|
||||||
end
|
end
|
||||||
return result
|
result
|
||||||
end
|
end
|
||||||
|
|
||||||
def squash(prefix, items)
|
def squash(prefix, items)
|
||||||
result = ''
|
result = ''
|
||||||
items.each { |item| result += " #{prefix}#{tackit(item)}" }
|
items.each { |item| result += " #{prefix}#{tackit(item)}" }
|
||||||
return result
|
result
|
||||||
end
|
end
|
||||||
|
|
||||||
def build_compiler_fields
|
def build_compiler_fields
|
||||||
command = tackit($cfg['compiler']['path'])
|
command = tackit($cfg['compiler']['path'])
|
||||||
if $cfg['compiler']['defines']['items'].nil?
|
defines = if $cfg['compiler']['defines']['items'].nil?
|
||||||
defines = ''
|
''
|
||||||
else
|
else
|
||||||
defines = squash($cfg['compiler']['defines']['prefix'], $cfg['compiler']['defines']['items'])
|
squash($cfg['compiler']['defines']['prefix'], $cfg['compiler']['defines']['items'])
|
||||||
end
|
end
|
||||||
options = squash('', $cfg['compiler']['options'])
|
options = squash('', $cfg['compiler']['options'])
|
||||||
includes = squash($cfg['compiler']['includes']['prefix'], $cfg['compiler']['includes']['items'])
|
includes = squash($cfg['compiler']['includes']['prefix'], $cfg['compiler']['includes']['items'])
|
||||||
includes = includes.gsub(/\\ /, ' ').gsub(/\\\"/, '"').gsub(/\\$/, '') # Remove trailing slashes (for IAR)
|
includes = includes.gsub(/\\ /, ' ').gsub(/\\\"/, '"').gsub(/\\$/, '') # Remove trailing slashes (for IAR)
|
||||||
return {:command => command, :defines => defines, :options => options, :includes => includes}
|
|
||||||
|
{ command: command, defines: defines, options: options, includes: includes }
|
||||||
end
|
end
|
||||||
|
|
||||||
def compile(file, defines=[])
|
def compile(file, _defines = [])
|
||||||
compiler = build_compiler_fields
|
compiler = build_compiler_fields
|
||||||
cmd_str = "#{compiler[:command]}#{compiler[:defines]}#{compiler[:options]}#{compiler[:includes]} #{file} " +
|
cmd_str = "#{compiler[:command]}#{compiler[:defines]}#{compiler[:options]}#{compiler[:includes]} #{file} " \
|
||||||
"#{$cfg['compiler']['object_files']['prefix']}#{$cfg['compiler']['object_files']['destination']}"
|
"#{$cfg['compiler']['object_files']['prefix']}#{$cfg['compiler']['object_files']['destination']}"
|
||||||
obj_file = "#{File.basename(file, C_EXTENSION)}#{$cfg['compiler']['object_files']['extension']}"
|
obj_file = "#{File.basename(file, C_EXTENSION)}#{$cfg['compiler']['object_files']['extension']}"
|
||||||
execute(cmd_str + obj_file)
|
execute(cmd_str + obj_file)
|
||||||
return obj_file
|
obj_file
|
||||||
end
|
end
|
||||||
|
|
||||||
def build_linker_fields
|
def build_linker_fields
|
||||||
command = tackit($cfg['linker']['path'])
|
command = tackit($cfg['linker']['path'])
|
||||||
if $cfg['linker']['options'].nil?
|
options = if $cfg['linker']['options'].nil?
|
||||||
options = ''
|
''
|
||||||
else
|
else
|
||||||
options = squash('', $cfg['linker']['options'])
|
squash('', $cfg['linker']['options'])
|
||||||
end
|
end
|
||||||
if ($cfg['linker']['includes'].nil? || $cfg['linker']['includes']['items'].nil?)
|
includes = if $cfg['linker']['includes'].nil? || $cfg['linker']['includes']['items'].nil?
|
||||||
includes = ''
|
''
|
||||||
else
|
else
|
||||||
includes = squash($cfg['linker']['includes']['prefix'], $cfg['linker']['includes']['items'])
|
squash($cfg['linker']['includes']['prefix'], $cfg['linker']['includes']['items'])
|
||||||
end
|
end.gsub(/\\ /, ' ').gsub(/\\\"/, '"').gsub(/\\$/, '') # Remove trailing slashes (for IAR)
|
||||||
includes = includes.gsub(/\\ /, ' ').gsub(/\\\"/, '"').gsub(/\\$/, '') # Remove trailing slashes (for IAR)
|
|
||||||
return {:command => command, :options => options, :includes => includes}
|
{ command: command, options: options, includes: includes }
|
||||||
end
|
end
|
||||||
|
|
||||||
def link_it(exe_name, obj_list)
|
def link_it(exe_name, obj_list)
|
||||||
linker = build_linker_fields
|
linker = build_linker_fields
|
||||||
cmd_str = "#{linker[:command]}#{linker[:options]}#{linker[:includes]} " +
|
cmd_str = "#{linker[:command]}#{linker[:options]}#{linker[:includes]} " +
|
||||||
(obj_list.map{|obj|"#{$cfg['linker']['object_files']['path']}#{obj} "}).join +
|
(obj_list.map { |obj| "#{$cfg['linker']['object_files']['path']}#{obj} " }).join +
|
||||||
$cfg['linker']['bin_files']['prefix'] + ' ' +
|
$cfg['linker']['bin_files']['prefix'] + ' ' +
|
||||||
$cfg['linker']['bin_files']['destination'] +
|
$cfg['linker']['bin_files']['destination'] +
|
||||||
exe_name + $cfg['linker']['bin_files']['extension']
|
exe_name + $cfg['linker']['bin_files']['extension']
|
||||||
execute(cmd_str)
|
execute(cmd_str)
|
||||||
end
|
end
|
||||||
|
|
||||||
def build_simulator_fields
|
def build_simulator_fields
|
||||||
return nil if $cfg['simulator'].nil?
|
return nil if $cfg['simulator'].nil?
|
||||||
if $cfg['simulator']['path'].nil?
|
command = if $cfg['simulator']['path'].nil?
|
||||||
command = ''
|
''
|
||||||
else
|
else
|
||||||
command = (tackit($cfg['simulator']['path']) + ' ')
|
(tackit($cfg['simulator']['path']) + ' ')
|
||||||
end
|
end
|
||||||
if $cfg['simulator']['pre_support'].nil?
|
pre_support = if $cfg['simulator']['pre_support'].nil?
|
||||||
pre_support = ''
|
''
|
||||||
else
|
else
|
||||||
pre_support = squash('', $cfg['simulator']['pre_support'])
|
squash('', $cfg['simulator']['pre_support'])
|
||||||
end
|
end
|
||||||
if $cfg['simulator']['post_support'].nil?
|
post_support = if $cfg['simulator']['post_support'].nil?
|
||||||
post_support = ''
|
''
|
||||||
else
|
else
|
||||||
post_support = squash('', $cfg['simulator']['post_support'])
|
squash('', $cfg['simulator']['post_support'])
|
||||||
end
|
end
|
||||||
return {:command => command, :pre_support => pre_support, :post_support => post_support}
|
|
||||||
|
{ command: command, pre_support: pre_support, post_support: post_support }
|
||||||
end
|
end
|
||||||
|
|
||||||
def execute(command_string, verbose=true, raise_on_fail=true)
|
def execute(command_string, verbose = true, raise_on_fail = true)
|
||||||
report command_string
|
report command_string
|
||||||
output = `#{command_string}`.chomp
|
output = `#{command_string}`.chomp
|
||||||
report(output) if (verbose && !output.nil? && (output.length > 0))
|
report(output) if verbose && !output.nil? && !output.empty?
|
||||||
if (($?.exitstatus != 0) and (raise_on_fail))
|
if !$?.exitstatus.zero? && raise_on_fail
|
||||||
raise "Command failed. (Returned #{$?.exitstatus})"
|
raise "Command failed. (Returned #{$?.exitstatus})"
|
||||||
end
|
end
|
||||||
return output
|
output
|
||||||
end
|
end
|
||||||
|
|
||||||
def report_summary
|
def report_summary
|
||||||
summary = UnityTestSummary.new
|
summary = UnityTestSummary.new
|
||||||
summary.set_root_path(HERE)
|
summary.root = HERE
|
||||||
results_glob = "#{$cfg['compiler']['build_path']}*.test*"
|
results_glob = "#{$cfg['compiler']['build_path']}*.test*"
|
||||||
results_glob.gsub!(/\\/, '/')
|
results_glob.tr!('\\', '/')
|
||||||
results = Dir[results_glob]
|
results = Dir[results_glob]
|
||||||
summary.set_targets(results)
|
summary.targets = results
|
||||||
summary.run
|
summary.run
|
||||||
fail_out "FAIL: There were failures" if (summary.failures > 0)
|
fail_out 'FAIL: There were failures' if summary.failures > 0
|
||||||
end
|
end
|
||||||
|
|
||||||
def run_tests(test_files)
|
def run_tests(test_files)
|
||||||
|
|
||||||
report 'Running system tests...'
|
report 'Running system tests...'
|
||||||
|
|
||||||
# Tack on TEST define for compiling unit tests
|
# Tack on TEST define for compiling unit tests
|
||||||
@ -171,7 +167,7 @@ module RakefileHelpers
|
|||||||
$cfg['compiler']['defines']['items'] = [] if $cfg['compiler']['defines']['items'].nil?
|
$cfg['compiler']['defines']['items'] = [] if $cfg['compiler']['defines']['items'].nil?
|
||||||
$cfg['compiler']['defines']['items'] << 'TEST'
|
$cfg['compiler']['defines']['items'] << 'TEST'
|
||||||
|
|
||||||
include_dirs = get_local_include_dirs
|
include_dirs = local_include_dirs
|
||||||
|
|
||||||
# Build and execute each unit test
|
# Build and execute each unit test
|
||||||
test_files.each do |test|
|
test_files.each do |test|
|
||||||
@ -181,9 +177,7 @@ module RakefileHelpers
|
|||||||
extract_headers(test).each do |header|
|
extract_headers(test).each do |header|
|
||||||
# Compile corresponding source file if it exists
|
# Compile corresponding source file if it exists
|
||||||
src_file = find_source_file(header, include_dirs)
|
src_file = find_source_file(header, include_dirs)
|
||||||
if !src_file.nil?
|
obj_list << compile(src_file, test_defines) unless src_file.nil?
|
||||||
obj_list << compile(src_file, test_defines)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Build the test runner (generate if configured to do so)
|
# Build the test runner (generate if configured to do so)
|
||||||
@ -208,25 +202,24 @@ module RakefileHelpers
|
|||||||
# Execute unit test and generate results file
|
# Execute unit test and generate results file
|
||||||
simulator = build_simulator_fields
|
simulator = build_simulator_fields
|
||||||
executable = $cfg['linker']['bin_files']['destination'] + test_base + $cfg['linker']['bin_files']['extension']
|
executable = $cfg['linker']['bin_files']['destination'] + test_base + $cfg['linker']['bin_files']['extension']
|
||||||
if simulator.nil?
|
cmd_str = if simulator.nil?
|
||||||
cmd_str = executable
|
executable
|
||||||
else
|
else
|
||||||
cmd_str = "#{simulator[:command]} #{simulator[:pre_support]} #{executable} #{simulator[:post_support]}"
|
"#{simulator[:command]} #{simulator[:pre_support]} #{executable} #{simulator[:post_support]}"
|
||||||
end
|
end
|
||||||
output = execute(cmd_str, true, false)
|
output = execute(cmd_str, true, false)
|
||||||
test_results = $cfg['compiler']['build_path'] + test_base
|
test_results = $cfg['compiler']['build_path'] + test_base
|
||||||
if output.match(/OK$/m).nil?
|
test_results += if output.match(/OK$/m).nil?
|
||||||
test_results += '.testfail'
|
'.testfail'
|
||||||
else
|
else
|
||||||
test_results += '.testpass'
|
'.testpass'
|
||||||
end
|
end
|
||||||
File.open(test_results, 'w') { |f| f.print output }
|
File.open(test_results, 'w') { |f| f.print output }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def build_application(main)
|
def build_application(main)
|
||||||
|
report 'Building application...'
|
||||||
report "Building application..."
|
|
||||||
|
|
||||||
obj_list = []
|
obj_list = []
|
||||||
load_configuration($cfg_file)
|
load_configuration($cfg_file)
|
||||||
@ -236,9 +229,7 @@ module RakefileHelpers
|
|||||||
include_dirs = get_local_include_dirs
|
include_dirs = get_local_include_dirs
|
||||||
extract_headers(main_path).each do |header|
|
extract_headers(main_path).each do |header|
|
||||||
src_file = find_source_file(header, include_dirs)
|
src_file = find_source_file(header, include_dirs)
|
||||||
if !src_file.nil?
|
obj_list << compile(src_file) unless src_file.nil?
|
||||||
obj_list << compile(src_file)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Build the main source file
|
# Build the main source file
|
||||||
@ -251,8 +242,8 @@ module RakefileHelpers
|
|||||||
|
|
||||||
def fail_out(msg)
|
def fail_out(msg)
|
||||||
puts msg
|
puts msg
|
||||||
puts "Not returning exit code so continuous integration can pass"
|
puts 'Not returning exit code so continuous integration can pass'
|
||||||
# exit(-1) # Only removed to pass example_3, which has failing tests on purpose.
|
# exit(-1) # Only removed to pass example_3, which has failing tests on purpose.
|
||||||
# Still fail if the build fails for any other reason.
|
# Still fail if the build fails for any other reason.
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -12,34 +12,34 @@ require 'rake/testtask'
|
|||||||
require HERE + 'rakefile_helper'
|
require HERE + 'rakefile_helper'
|
||||||
|
|
||||||
TEMP_DIRS = [
|
TEMP_DIRS = [
|
||||||
File.join(HERE, 'build')
|
File.join(HERE, 'build')
|
||||||
]
|
].freeze
|
||||||
|
|
||||||
TEMP_DIRS.each do |dir|
|
TEMP_DIRS.each do |dir|
|
||||||
directory(dir)
|
directory(dir)
|
||||||
CLOBBER.include(dir)
|
CLOBBER.include(dir)
|
||||||
end
|
end
|
||||||
|
|
||||||
task :prepare_for_tests => TEMP_DIRS
|
task prepare_for_tests: TEMP_DIRS
|
||||||
|
|
||||||
include RakefileHelpers
|
include RakefileHelpers
|
||||||
|
|
||||||
# Load default configuration, for now
|
# Load default configuration, for now
|
||||||
DEFAULT_CONFIG_FILE = 'gcc_auto_stdint.yml'
|
DEFAULT_CONFIG_FILE = 'gcc_auto_stdint.yml'.freeze
|
||||||
configure_toolchain(DEFAULT_CONFIG_FILE)
|
configure_toolchain(DEFAULT_CONFIG_FILE)
|
||||||
|
|
||||||
task :unit => [:prepare_for_tests] do
|
task unit: [:prepare_for_tests] do
|
||||||
run_tests
|
run_tests
|
||||||
end
|
end
|
||||||
|
|
||||||
desc "Build and test Unity Framework"
|
desc 'Build and test Unity Framework'
|
||||||
task :all => [:clean, :unit]
|
task all: %i(clean unit)
|
||||||
task :default => [:clobber, :all]
|
task default: %i(clobber all)
|
||||||
task :ci => [:no_color, :default]
|
task ci: %i(no_color default)
|
||||||
task :cruise => [:no_color, :default]
|
task cruise: %i(no_color default)
|
||||||
|
|
||||||
desc "Load configuration"
|
desc 'Load configuration'
|
||||||
task :config, :config_file do |t, args|
|
task :config, :config_file do |_t, args|
|
||||||
configure_toolchain(args[:config_file])
|
configure_toolchain(args[:config_file])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -6,28 +6,27 @@
|
|||||||
|
|
||||||
require 'yaml'
|
require 'yaml'
|
||||||
require 'fileutils'
|
require 'fileutils'
|
||||||
require HERE+'../../auto/unity_test_summary'
|
require HERE + '../../auto/unity_test_summary'
|
||||||
require HERE+'../../auto/generate_test_runner'
|
require HERE + '../../auto/generate_test_runner'
|
||||||
require HERE+'../../auto/colour_reporter'
|
require HERE + '../../auto/colour_reporter'
|
||||||
|
|
||||||
module RakefileHelpers
|
module RakefileHelpers
|
||||||
|
C_EXTENSION = '.c'.freeze
|
||||||
C_EXTENSION = '.c'
|
|
||||||
|
|
||||||
def load_configuration(config_file)
|
def load_configuration(config_file)
|
||||||
unless ($configured)
|
return if $configured
|
||||||
$cfg_file = HERE+"../../test/targets/#{config_file}" unless (config_file =~ /[\\|\/]/)
|
|
||||||
$cfg = YAML.load(File.read($cfg_file))
|
$cfg_file = HERE + "../../test/targets/#{config_file}" unless config_file =~ /[\\|\/]/
|
||||||
$colour_output = false unless $cfg['colour']
|
$cfg = YAML.load(File.read($cfg_file))
|
||||||
$configured = true if (config_file != DEFAULT_CONFIG_FILE)
|
$colour_output = false unless $cfg['colour']
|
||||||
end
|
$configured = true if config_file != DEFAULT_CONFIG_FILE
|
||||||
end
|
end
|
||||||
|
|
||||||
def configure_clean
|
def configure_clean
|
||||||
CLEAN.include($cfg['compiler']['build_path'] + '*.*') unless $cfg['compiler']['build_path'].nil?
|
CLEAN.include($cfg['compiler']['build_path'] + '*.*') unless $cfg['compiler']['build_path'].nil?
|
||||||
end
|
end
|
||||||
|
|
||||||
def configure_toolchain(config_file=DEFAULT_CONFIG_FILE)
|
def configure_toolchain(config_file = DEFAULT_CONFIG_FILE)
|
||||||
config_file += '.yml' unless config_file =~ /\.yml$/
|
config_file += '.yml' unless config_file =~ /\.yml$/
|
||||||
config_file = config_file unless config_file =~ /[\\|\/]/
|
config_file = config_file unless config_file =~ /[\\|\/]/
|
||||||
load_configuration(config_file)
|
load_configuration(config_file)
|
||||||
@ -35,105 +34,105 @@ module RakefileHelpers
|
|||||||
end
|
end
|
||||||
|
|
||||||
def tackit(strings)
|
def tackit(strings)
|
||||||
if strings.is_a?(Array)
|
result = if strings.is_a?(Array)
|
||||||
result = "\"#{strings.join}\""
|
"\"#{strings.join}\""
|
||||||
else
|
else
|
||||||
result = strings
|
strings
|
||||||
end
|
end
|
||||||
return result
|
result
|
||||||
end
|
end
|
||||||
|
|
||||||
def squash(prefix, items)
|
def squash(prefix, items)
|
||||||
result = ''
|
result = ''
|
||||||
items.each { |item| result += " #{prefix}#{tackit(item)}" }
|
items.each { |item| result += " #{prefix}#{tackit(item)}" }
|
||||||
return result
|
result
|
||||||
end
|
end
|
||||||
|
|
||||||
def build_compiler_fields
|
def build_compiler_fields
|
||||||
command = tackit($cfg['compiler']['path'])
|
command = tackit($cfg['compiler']['path'])
|
||||||
if $cfg['compiler']['defines']['items'].nil?
|
defines = if $cfg['compiler']['defines']['items'].nil?
|
||||||
defines = ''
|
''
|
||||||
else
|
else
|
||||||
defines = squash($cfg['compiler']['defines']['prefix'], $cfg['compiler']['defines']['items'] + ['UNITY_OUTPUT_CHAR=UnityOutputCharSpy_OutputChar'])
|
squash($cfg['compiler']['defines']['prefix'], $cfg['compiler']['defines']['items'] + ['UNITY_OUTPUT_CHAR=UnityOutputCharSpy_OutputChar'])
|
||||||
end
|
end
|
||||||
options = squash('', $cfg['compiler']['options'])
|
options = squash('', $cfg['compiler']['options'])
|
||||||
includes = squash($cfg['compiler']['includes']['prefix'], $cfg['compiler']['includes']['items'])
|
includes = squash($cfg['compiler']['includes']['prefix'], $cfg['compiler']['includes']['items'])
|
||||||
includes = includes.gsub(/\\ /, ' ').gsub(/\\\"/, '"').gsub(/\\$/, '') # Remove trailing slashes (for IAR)
|
includes = includes.gsub(/\\ /, ' ').gsub(/\\\"/, '"').gsub(/\\$/, '') # Remove trailing slashes (for IAR)
|
||||||
return {:command => command, :defines => defines, :options => options, :includes => includes}
|
|
||||||
|
{ command: command, defines: defines, options: options, includes: includes }
|
||||||
end
|
end
|
||||||
|
|
||||||
def compile(file, defines=[])
|
def compile(file, _defines = [])
|
||||||
compiler = build_compiler_fields
|
compiler = build_compiler_fields
|
||||||
unity_include = $cfg['compiler']['includes']['prefix']+'../../src'
|
unity_include = $cfg['compiler']['includes']['prefix'] + '../../src'
|
||||||
cmd_str = "#{compiler[:command]}#{compiler[:defines]}#{compiler[:options]}#{compiler[:includes]} #{unity_include} #{file} " +
|
cmd_str = "#{compiler[:command]}#{compiler[:defines]}#{compiler[:options]}#{compiler[:includes]} #{unity_include} #{file} " \
|
||||||
"#{$cfg['compiler']['object_files']['prefix']}#{$cfg['compiler']['object_files']['destination']}" +
|
"#{$cfg['compiler']['object_files']['prefix']}#{$cfg['compiler']['object_files']['destination']}" \
|
||||||
"#{File.basename(file, C_EXTENSION)}#{$cfg['compiler']['object_files']['extension']}"
|
"#{File.basename(file, C_EXTENSION)}#{$cfg['compiler']['object_files']['extension']}"
|
||||||
|
|
||||||
execute(cmd_str)
|
execute(cmd_str)
|
||||||
end
|
end
|
||||||
|
|
||||||
def build_linker_fields
|
def build_linker_fields
|
||||||
command = tackit($cfg['linker']['path'])
|
command = tackit($cfg['linker']['path'])
|
||||||
if $cfg['linker']['options'].nil?
|
options = if $cfg['linker']['options'].nil?
|
||||||
options = ''
|
''
|
||||||
else
|
else
|
||||||
options = squash('', $cfg['linker']['options'])
|
squash('', $cfg['linker']['options'])
|
||||||
end
|
end
|
||||||
if ($cfg['linker']['includes'].nil? || $cfg['linker']['includes']['items'].nil?)
|
includes = if $cfg['linker']['includes'].nil? || $cfg['linker']['includes']['items'].nil?
|
||||||
includes = ''
|
''
|
||||||
else
|
else
|
||||||
includes = squash($cfg['linker']['includes']['prefix'], $cfg['linker']['includes']['items'])
|
squash($cfg['linker']['includes']['prefix'], $cfg['linker']['includes']['items'])
|
||||||
end
|
end.gsub(/\\ /, ' ').gsub(/\\\"/, '"').gsub(/\\$/, '') # Remove trailing slashes (for IAR)
|
||||||
includes = includes.gsub(/\\ /, ' ').gsub(/\\\"/, '"').gsub(/\\$/, '') # Remove trailing slashes (for IAR)
|
|
||||||
return {:command => command, :options => options, :includes => includes}
|
{ command: command, options: options, includes: includes }
|
||||||
end
|
end
|
||||||
|
|
||||||
def link_it(exe_name, obj_list)
|
def link_it(exe_name, obj_list)
|
||||||
linker = build_linker_fields
|
linker = build_linker_fields
|
||||||
cmd_str = "#{linker[:command]}#{linker[:options]}#{linker[:includes]} " +
|
cmd_str = "#{linker[:command]}#{linker[:options]}#{linker[:includes]} " +
|
||||||
(obj_list.map{|obj|"#{$cfg['linker']['object_files']['path']}#{obj} "}).join +
|
(obj_list.map { |obj| "#{$cfg['linker']['object_files']['path']}#{obj} " }).join +
|
||||||
$cfg['linker']['bin_files']['prefix'] + ' ' +
|
$cfg['linker']['bin_files']['prefix'] + ' ' +
|
||||||
$cfg['linker']['bin_files']['destination'] +
|
$cfg['linker']['bin_files']['destination'] +
|
||||||
exe_name + $cfg['linker']['bin_files']['extension']
|
exe_name + $cfg['linker']['bin_files']['extension']
|
||||||
execute(cmd_str)
|
execute(cmd_str)
|
||||||
end
|
end
|
||||||
|
|
||||||
def build_simulator_fields
|
def build_simulator_fields
|
||||||
return nil if $cfg['simulator'].nil?
|
return nil if $cfg['simulator'].nil?
|
||||||
if $cfg['simulator']['path'].nil?
|
command = if $cfg['simulator']['path'].nil?
|
||||||
command = ''
|
''
|
||||||
else
|
else
|
||||||
command = (tackit($cfg['simulator']['path']) + ' ')
|
(tackit($cfg['simulator']['path']) + ' ')
|
||||||
end
|
end
|
||||||
if $cfg['simulator']['pre_support'].nil?
|
pre_support = if $cfg['simulator']['pre_support'].nil?
|
||||||
pre_support = ''
|
''
|
||||||
else
|
else
|
||||||
pre_support = squash('', $cfg['simulator']['pre_support'])
|
squash('', $cfg['simulator']['pre_support'])
|
||||||
end
|
end
|
||||||
if $cfg['simulator']['post_support'].nil?
|
post_support = if $cfg['simulator']['post_support'].nil?
|
||||||
post_support = ''
|
''
|
||||||
else
|
else
|
||||||
post_support = squash('', $cfg['simulator']['post_support'])
|
squash('', $cfg['simulator']['post_support'])
|
||||||
end
|
end
|
||||||
return {:command => command, :pre_support => pre_support, :post_support => post_support}
|
{ command: command, pre_support: pre_support, post_support: post_support }
|
||||||
end
|
end
|
||||||
|
|
||||||
def execute(command_string, verbose=true)
|
def execute(command_string, verbose = true)
|
||||||
report command_string
|
report command_string
|
||||||
output = `#{command_string}`.chomp
|
output = `#{command_string}`.chomp
|
||||||
report(output) if (verbose && !output.nil? && (output.length > 0))
|
report(output) if verbose && !output.nil? && !output.empty?
|
||||||
if ($?.exitstatus != 0)
|
raise "Command failed. (Returned #{$?.exitstatus})" if $?.exitstatus != 0
|
||||||
raise "Command failed. (Returned #{$?.exitstatus})"
|
output
|
||||||
end
|
|
||||||
return output
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def report_summary
|
def report_summary
|
||||||
summary = UnityTestSummary.new
|
summary = UnityTestSummary.new
|
||||||
summary.set_root_path(HERE)
|
summary.root = HERE
|
||||||
results_glob = "#{$cfg['compiler']['build_path']}*.test*"
|
results_glob = "#{$cfg['compiler']['build_path']}*.test*"
|
||||||
results_glob.gsub!(/\\/, '/')
|
results_glob.tr!('\\', '/')
|
||||||
results = Dir[results_glob]
|
results = Dir[results_glob]
|
||||||
summary.set_targets(results)
|
summary.targets = results
|
||||||
summary.run
|
summary.run
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -146,34 +145,34 @@ module RakefileHelpers
|
|||||||
$cfg['compiler']['defines']['items'] = [] if $cfg['compiler']['defines']['items'].nil?
|
$cfg['compiler']['defines']['items'] = [] if $cfg['compiler']['defines']['items'].nil?
|
||||||
|
|
||||||
# Get a list of all source files needed
|
# Get a list of all source files needed
|
||||||
src_files = Dir[HERE+'src/*.c']
|
src_files = Dir[HERE + 'src/*.c']
|
||||||
src_files += Dir[HERE+'test/*.c']
|
src_files += Dir[HERE + 'test/*.c']
|
||||||
src_files += Dir[HERE+'test/main/*.c']
|
src_files += Dir[HERE + 'test/main/*.c']
|
||||||
src_files << '../../src/unity.c'
|
src_files << '../../src/unity.c'
|
||||||
|
|
||||||
# Build object files
|
# Build object files
|
||||||
src_files.each { |f| compile(f, test_defines) }
|
src_files.each { |f| compile(f, test_defines) }
|
||||||
obj_list = src_files.map {|f| File.basename(f.ext($cfg['compiler']['object_files']['extension'])) }
|
obj_list = src_files.map { |f| File.basename(f.ext($cfg['compiler']['object_files']['extension'])) }
|
||||||
|
|
||||||
# Link the test executable
|
# Link the test executable
|
||||||
test_base = "framework_test"
|
test_base = 'framework_test'
|
||||||
link_it(test_base, obj_list)
|
link_it(test_base, obj_list)
|
||||||
|
|
||||||
# Execute unit test and generate results file
|
# Execute unit test and generate results file
|
||||||
simulator = build_simulator_fields
|
simulator = build_simulator_fields
|
||||||
executable = $cfg['linker']['bin_files']['destination'] + test_base + $cfg['linker']['bin_files']['extension']
|
executable = $cfg['linker']['bin_files']['destination'] + test_base + $cfg['linker']['bin_files']['extension']
|
||||||
if simulator.nil?
|
cmd_str = if simulator.nil?
|
||||||
cmd_str = executable + " -v -r"
|
executable + ' -v -r'
|
||||||
else
|
else
|
||||||
cmd_str = "#{simulator[:command]} #{simulator[:pre_support]} #{executable} #{simulator[:post_support]}"
|
"#{simulator[:command]} #{simulator[:pre_support]} #{executable} #{simulator[:post_support]}"
|
||||||
end
|
end
|
||||||
output = execute(cmd_str)
|
output = execute(cmd_str)
|
||||||
test_results = $cfg['compiler']['build_path'] + test_base
|
test_results = $cfg['compiler']['build_path'] + test_base
|
||||||
if output.match(/OK$/m).nil?
|
test_results += if output.match(/OK$/m).nil?
|
||||||
test_results += '.testfail'
|
'.testfail'
|
||||||
else
|
else
|
||||||
test_results += '.testpass'
|
'.testpass'
|
||||||
end
|
end
|
||||||
File.open(test_results, 'w') { |f| f.print output }
|
File.open(test_results, 'w') { |f| f.print output }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
* For example, when using FreeRTOS UNITY_FIXTURE_MALLOC becomes pvPortMalloc()
|
* For example, when using FreeRTOS UNITY_FIXTURE_MALLOC becomes pvPortMalloc()
|
||||||
* and UNITY_FIXTURE_FREE becomes vPortFree(). */
|
* and UNITY_FIXTURE_FREE becomes vPortFree(). */
|
||||||
#if !defined(UNITY_FIXTURE_MALLOC) || !defined(UNITY_FIXTURE_FREE)
|
#if !defined(UNITY_FIXTURE_MALLOC) || !defined(UNITY_FIXTURE_FREE)
|
||||||
|
#include <stdlib.h>
|
||||||
#define UNITY_FIXTURE_MALLOC(size) malloc(size)
|
#define UNITY_FIXTURE_MALLOC(size) malloc(size)
|
||||||
#define UNITY_FIXTURE_FREE(ptr) free(ptr)
|
#define UNITY_FIXTURE_FREE(ptr) free(ptr)
|
||||||
#else
|
#else
|
||||||
|
@ -1,2 +1,2 @@
|
|||||||
2.4.0
|
2.4.1
|
||||||
|
|
||||||
|
@ -539,7 +539,8 @@ void UnityAssertEqualIntArray(UNITY_INTERNAL_PTR expected,
|
|||||||
const UNITY_UINT32 num_elements,
|
const UNITY_UINT32 num_elements,
|
||||||
const char* msg,
|
const char* msg,
|
||||||
const UNITY_LINE_TYPE lineNumber,
|
const UNITY_LINE_TYPE lineNumber,
|
||||||
const UNITY_DISPLAY_STYLE_T style)
|
const UNITY_DISPLAY_STYLE_T style,
|
||||||
|
const UNITY_FLAGS_T flags)
|
||||||
{
|
{
|
||||||
UNITY_UINT32 elements = num_elements;
|
UNITY_UINT32 elements = num_elements;
|
||||||
unsigned int length = style & 0xF;
|
unsigned int length = style & 0xF;
|
||||||
@ -569,17 +570,17 @@ void UnityAssertEqualIntArray(UNITY_INTERNAL_PTR expected,
|
|||||||
expect_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT16*)expected;
|
expect_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT16*)expected;
|
||||||
actual_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT16*)actual;
|
actual_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT16*)actual;
|
||||||
break;
|
break;
|
||||||
default: /* length 4 bytes */
|
|
||||||
expect_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT32*)expected;
|
|
||||||
actual_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT32*)actual;
|
|
||||||
length = 4;
|
|
||||||
break;
|
|
||||||
#ifdef UNITY_SUPPORT_64
|
#ifdef UNITY_SUPPORT_64
|
||||||
case 8:
|
case 8:
|
||||||
expect_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT64*)expected;
|
expect_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT64*)expected;
|
||||||
actual_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT64*)actual;
|
actual_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT64*)actual;
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
default: /* length 4 bytes */
|
||||||
|
expect_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT32*)expected;
|
||||||
|
actual_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT32*)actual;
|
||||||
|
length = 4;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (expect_val != actual_val)
|
if (expect_val != actual_val)
|
||||||
@ -601,7 +602,10 @@ void UnityAssertEqualIntArray(UNITY_INTERNAL_PTR expected,
|
|||||||
UnityAddMsgIfSpecified(msg);
|
UnityAddMsgIfSpecified(msg);
|
||||||
UNITY_FAIL_AND_BAIL;
|
UNITY_FAIL_AND_BAIL;
|
||||||
}
|
}
|
||||||
expected = (UNITY_INTERNAL_PTR)(length + (const char*)expected);
|
if (flags == UNITY_ARRAY_TO_ARRAY)
|
||||||
|
{
|
||||||
|
expected = (UNITY_INTERNAL_PTR)(length + (const char*)expected);
|
||||||
|
}
|
||||||
actual = (UNITY_INTERNAL_PTR)(length + (const char*)actual);
|
actual = (UNITY_INTERNAL_PTR)(length + (const char*)actual);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -645,7 +649,8 @@ void UnityAssertEqualFloatArray(UNITY_PTR_ATTRIBUTE const UNITY_FLOAT* expected,
|
|||||||
UNITY_PTR_ATTRIBUTE const UNITY_FLOAT* actual,
|
UNITY_PTR_ATTRIBUTE const UNITY_FLOAT* actual,
|
||||||
const UNITY_UINT32 num_elements,
|
const UNITY_UINT32 num_elements,
|
||||||
const char* msg,
|
const char* msg,
|
||||||
const UNITY_LINE_TYPE lineNumber)
|
const UNITY_LINE_TYPE lineNumber,
|
||||||
|
const UNITY_FLAGS_T flags)
|
||||||
{
|
{
|
||||||
UNITY_UINT32 elements = num_elements;
|
UNITY_UINT32 elements = num_elements;
|
||||||
UNITY_PTR_ATTRIBUTE const UNITY_FLOAT* ptr_expected = expected;
|
UNITY_PTR_ATTRIBUTE const UNITY_FLOAT* ptr_expected = expected;
|
||||||
@ -673,7 +678,10 @@ void UnityAssertEqualFloatArray(UNITY_PTR_ATTRIBUTE const UNITY_FLOAT* expected,
|
|||||||
UnityAddMsgIfSpecified(msg);
|
UnityAddMsgIfSpecified(msg);
|
||||||
UNITY_FAIL_AND_BAIL;
|
UNITY_FAIL_AND_BAIL;
|
||||||
}
|
}
|
||||||
ptr_expected++;
|
if (flags == UNITY_ARRAY_TO_ARRAY)
|
||||||
|
{
|
||||||
|
ptr_expected++;
|
||||||
|
}
|
||||||
ptr_actual++;
|
ptr_actual++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -771,7 +779,8 @@ void UnityAssertEqualDoubleArray(UNITY_PTR_ATTRIBUTE const UNITY_DOUBLE* expecte
|
|||||||
UNITY_PTR_ATTRIBUTE const UNITY_DOUBLE* actual,
|
UNITY_PTR_ATTRIBUTE const UNITY_DOUBLE* actual,
|
||||||
const UNITY_UINT32 num_elements,
|
const UNITY_UINT32 num_elements,
|
||||||
const char* msg,
|
const char* msg,
|
||||||
const UNITY_LINE_TYPE lineNumber)
|
const UNITY_LINE_TYPE lineNumber,
|
||||||
|
const UNITY_FLAGS_T flags)
|
||||||
{
|
{
|
||||||
UNITY_UINT32 elements = num_elements;
|
UNITY_UINT32 elements = num_elements;
|
||||||
UNITY_PTR_ATTRIBUTE const UNITY_DOUBLE* ptr_expected = expected;
|
UNITY_PTR_ATTRIBUTE const UNITY_DOUBLE* ptr_expected = expected;
|
||||||
@ -799,7 +808,10 @@ void UnityAssertEqualDoubleArray(UNITY_PTR_ATTRIBUTE const UNITY_DOUBLE* expecte
|
|||||||
UnityAddMsgIfSpecified(msg);
|
UnityAddMsgIfSpecified(msg);
|
||||||
UNITY_FAIL_AND_BAIL;
|
UNITY_FAIL_AND_BAIL;
|
||||||
}
|
}
|
||||||
ptr_expected++;
|
if (flags == UNITY_ARRAY_TO_ARRAY)
|
||||||
|
{
|
||||||
|
ptr_expected++;
|
||||||
|
}
|
||||||
ptr_actual++;
|
ptr_actual++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -898,16 +910,16 @@ void UnityAssertNumbersWithin(const UNITY_UINT delta,
|
|||||||
if ((style & UNITY_DISPLAY_RANGE_INT) == UNITY_DISPLAY_RANGE_INT)
|
if ((style & UNITY_DISPLAY_RANGE_INT) == UNITY_DISPLAY_RANGE_INT)
|
||||||
{
|
{
|
||||||
if (actual > expected)
|
if (actual > expected)
|
||||||
Unity.CurrentTestFailed = ((UNITY_UINT)(actual - expected) > delta);
|
Unity.CurrentTestFailed = (UNITY_UINT)((UNITY_UINT)(actual - expected) > delta);
|
||||||
else
|
else
|
||||||
Unity.CurrentTestFailed = ((UNITY_UINT)(expected - actual) > delta);
|
Unity.CurrentTestFailed = (UNITY_UINT)((UNITY_UINT)(expected - actual) > delta);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ((UNITY_UINT)actual > (UNITY_UINT)expected)
|
if ((UNITY_UINT)actual > (UNITY_UINT)expected)
|
||||||
Unity.CurrentTestFailed = ((UNITY_UINT)(actual - expected) > delta);
|
Unity.CurrentTestFailed = (UNITY_UINT)((UNITY_UINT)(actual - expected) > delta);
|
||||||
else
|
else
|
||||||
Unity.CurrentTestFailed = ((UNITY_UINT)(expected - actual) > delta);
|
Unity.CurrentTestFailed = (UNITY_UINT)((UNITY_UINT)(expected - actual) > delta);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Unity.CurrentTestFailed)
|
if (Unity.CurrentTestFailed)
|
||||||
@ -1004,13 +1016,17 @@ void UnityAssertEqualStringLen(const char* expected,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*-----------------------------------------------*/
|
/*-----------------------------------------------*/
|
||||||
void UnityAssertEqualStringArray(const char** expected,
|
void UnityAssertEqualStringArray(UNITY_INTERNAL_PTR expected,
|
||||||
const char** actual,
|
const char** actual,
|
||||||
const UNITY_UINT32 num_elements,
|
const UNITY_UINT32 num_elements,
|
||||||
const char* msg,
|
const char* msg,
|
||||||
const UNITY_LINE_TYPE lineNumber)
|
const UNITY_LINE_TYPE lineNumber,
|
||||||
|
const UNITY_FLAGS_T flags)
|
||||||
{
|
{
|
||||||
UNITY_UINT32 i, j = 0;
|
UNITY_UINT32 i = 0;
|
||||||
|
UNITY_UINT32 j = 0;
|
||||||
|
const char* exp = NULL;
|
||||||
|
const char* act = NULL;
|
||||||
|
|
||||||
RETURN_IF_FAIL_OR_IGNORE;
|
RETURN_IF_FAIL_OR_IGNORE;
|
||||||
|
|
||||||
@ -1020,18 +1036,35 @@ void UnityAssertEqualStringArray(const char** expected,
|
|||||||
UnityPrintPointlessAndBail();
|
UnityPrintPointlessAndBail();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (expected == actual) return; /* Both are NULL or same pointer */
|
if ((const void*)expected == (const void*)actual)
|
||||||
|
{
|
||||||
|
return; /* Both are NULL or same pointer */
|
||||||
|
}
|
||||||
|
|
||||||
if (UnityIsOneArrayNull((UNITY_INTERNAL_PTR)expected, (UNITY_INTERNAL_PTR)actual, lineNumber, msg))
|
if (UnityIsOneArrayNull((UNITY_INTERNAL_PTR)expected, (UNITY_INTERNAL_PTR)actual, lineNumber, msg))
|
||||||
|
{
|
||||||
UNITY_FAIL_AND_BAIL;
|
UNITY_FAIL_AND_BAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flags != UNITY_ARRAY_TO_ARRAY)
|
||||||
|
{
|
||||||
|
exp = (const char*)expected;
|
||||||
|
}
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
/* if both pointers not null compare the strings */
|
act = actual[j];
|
||||||
if (expected[j] && actual[j])
|
if (flags == UNITY_ARRAY_TO_ARRAY)
|
||||||
{
|
{
|
||||||
for (i = 0; expected[j][i] || actual[j][i]; i++)
|
exp = ((const char* const*)expected)[j];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if both pointers not null compare the strings */
|
||||||
|
if (exp && act)
|
||||||
|
{
|
||||||
|
for (i = 0; exp[i] || act[i]; i++)
|
||||||
{
|
{
|
||||||
if (expected[j][i] != actual[j][i])
|
if (exp[i] != act[i])
|
||||||
{
|
{
|
||||||
Unity.CurrentTestFailed = 1;
|
Unity.CurrentTestFailed = 1;
|
||||||
break;
|
break;
|
||||||
@ -1040,7 +1073,7 @@ void UnityAssertEqualStringArray(const char** expected,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{ /* handle case of one pointers being null (if both null, test should pass) */
|
{ /* handle case of one pointers being null (if both null, test should pass) */
|
||||||
if (expected[j] != actual[j])
|
if (exp != act)
|
||||||
{
|
{
|
||||||
Unity.CurrentTestFailed = 1;
|
Unity.CurrentTestFailed = 1;
|
||||||
}
|
}
|
||||||
@ -1054,7 +1087,7 @@ void UnityAssertEqualStringArray(const char** expected,
|
|||||||
UnityPrint(UnityStrElement);
|
UnityPrint(UnityStrElement);
|
||||||
UnityPrintNumberUnsigned(j);
|
UnityPrintNumberUnsigned(j);
|
||||||
}
|
}
|
||||||
UnityPrintExpectedAndActualStrings((const char*)(expected[j]), (const char*)(actual[j]));
|
UnityPrintExpectedAndActualStrings(exp, act);
|
||||||
UnityAddMsgIfSpecified(msg);
|
UnityAddMsgIfSpecified(msg);
|
||||||
UNITY_FAIL_AND_BAIL;
|
UNITY_FAIL_AND_BAIL;
|
||||||
}
|
}
|
||||||
@ -1067,7 +1100,8 @@ void UnityAssertEqualMemory(UNITY_INTERNAL_PTR expected,
|
|||||||
const UNITY_UINT32 length,
|
const UNITY_UINT32 length,
|
||||||
const UNITY_UINT32 num_elements,
|
const UNITY_UINT32 num_elements,
|
||||||
const char* msg,
|
const char* msg,
|
||||||
const UNITY_LINE_TYPE lineNumber)
|
const UNITY_LINE_TYPE lineNumber,
|
||||||
|
const UNITY_FLAGS_T flags)
|
||||||
{
|
{
|
||||||
UNITY_PTR_ATTRIBUTE const unsigned char* ptr_exp = (UNITY_PTR_ATTRIBUTE const unsigned char*)expected;
|
UNITY_PTR_ATTRIBUTE const unsigned char* ptr_exp = (UNITY_PTR_ATTRIBUTE const unsigned char*)expected;
|
||||||
UNITY_PTR_ATTRIBUTE const unsigned char* ptr_act = (UNITY_PTR_ATTRIBUTE const unsigned char*)actual;
|
UNITY_PTR_ATTRIBUTE const unsigned char* ptr_act = (UNITY_PTR_ATTRIBUTE const unsigned char*)actual;
|
||||||
@ -1111,9 +1145,70 @@ void UnityAssertEqualMemory(UNITY_INTERNAL_PTR expected,
|
|||||||
ptr_exp++;
|
ptr_exp++;
|
||||||
ptr_act++;
|
ptr_act++;
|
||||||
}
|
}
|
||||||
|
if (flags == UNITY_ARRAY_TO_VAL)
|
||||||
|
{
|
||||||
|
ptr_exp = (UNITY_PTR_ATTRIBUTE const unsigned char*)expected;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*-----------------------------------------------*/
|
||||||
|
|
||||||
|
static union
|
||||||
|
{
|
||||||
|
UNITY_INT8 i8;
|
||||||
|
UNITY_INT16 i16;
|
||||||
|
UNITY_INT32 i32;
|
||||||
|
#ifdef UNITY_SUPPORT_64
|
||||||
|
UNITY_INT64 i64;
|
||||||
|
#endif
|
||||||
|
#ifndef UNITY_EXCLUDE_FLOAT
|
||||||
|
float f;
|
||||||
|
#endif
|
||||||
|
#ifndef UNITY_EXCLUDE_DOUBLE
|
||||||
|
double d;
|
||||||
|
#endif
|
||||||
|
} UnityQuickCompare;
|
||||||
|
|
||||||
|
UNITY_INTERNAL_PTR UnityNumToPtr(const UNITY_INT num, const UNITY_UINT8 size)
|
||||||
|
{
|
||||||
|
switch(size)
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
UnityQuickCompare.i8 = (UNITY_INT8)num;
|
||||||
|
return (UNITY_INTERNAL_PTR)(&UnityQuickCompare.i8);
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
UnityQuickCompare.i16 = (UNITY_INT16)num;
|
||||||
|
return (UNITY_INTERNAL_PTR)(&UnityQuickCompare.i16);
|
||||||
|
|
||||||
|
#ifdef UNITY_SUPPORT_64
|
||||||
|
case 8:
|
||||||
|
UnityQuickCompare.i64 = (UNITY_INT64)num;
|
||||||
|
return (UNITY_INTERNAL_PTR)(&UnityQuickCompare.i64);
|
||||||
|
#endif
|
||||||
|
default: /* 4 bytes */
|
||||||
|
UnityQuickCompare.i32 = (UNITY_INT32)num;
|
||||||
|
return (UNITY_INTERNAL_PTR)(&UnityQuickCompare.i32);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef UNITY_EXCLUDE_FLOAT
|
||||||
|
UNITY_INTERNAL_PTR UnityFloatToPtr(const float num)
|
||||||
|
{
|
||||||
|
UnityQuickCompare.f = num;
|
||||||
|
return (UNITY_INTERNAL_PTR)(&UnityQuickCompare.f);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef UNITY_EXCLUDE_DOUBLE
|
||||||
|
UNITY_INTERNAL_PTR UnityDoubleToPtr(const double num)
|
||||||
|
{
|
||||||
|
UnityQuickCompare.d = num;
|
||||||
|
return (UNITY_INTERNAL_PTR)(&UnityQuickCompare.d);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*-----------------------------------------------
|
/*-----------------------------------------------
|
||||||
* Control Functions
|
* Control Functions
|
||||||
*-----------------------------------------------*/
|
*-----------------------------------------------*/
|
||||||
@ -1177,6 +1272,7 @@ void UnityIgnore(const char* msg, const UNITY_LINE_TYPE line)
|
|||||||
#pragma weak tearDown
|
#pragma weak tearDown
|
||||||
void tearDown(void) { }
|
void tearDown(void) { }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*-----------------------------------------------*/
|
/*-----------------------------------------------*/
|
||||||
void UnityDefaultTestRun(UnityTestFunction Func, const char* FuncName, const int FuncLineNum)
|
void UnityDefaultTestRun(UnityTestFunction Func, const char* FuncName, const int FuncLineNum)
|
||||||
{
|
{
|
||||||
@ -1309,9 +1405,9 @@ int UnityParseOptions(int argc, char** argv)
|
|||||||
|
|
||||||
int IsStringInBiggerString(const char* longstring, const char* shortstring)
|
int IsStringInBiggerString(const char* longstring, const char* shortstring)
|
||||||
{
|
{
|
||||||
char* lptr = (char*)longstring;
|
const char* lptr = longstring;
|
||||||
char* sptr = (char*)shortstring;
|
const char* sptr = shortstring;
|
||||||
char* lnext = lptr;
|
const char* lnext = lptr;
|
||||||
|
|
||||||
if (*sptr == '*')
|
if (*sptr == '*')
|
||||||
return 1;
|
return 1;
|
||||||
@ -1343,7 +1439,7 @@ int IsStringInBiggerString(const char* longstring, const char* shortstring)
|
|||||||
|
|
||||||
/* Otherwise we start in the long pointer 1 character further and try again */
|
/* Otherwise we start in the long pointer 1 character further and try again */
|
||||||
lptr = lnext;
|
lptr = lnext;
|
||||||
sptr = (char*)shortstring;
|
sptr = shortstring;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -74,6 +74,10 @@ void tearDown(void);
|
|||||||
* This method allows you to abort a test immediately with a PASS state, ignoring the remainder of the test. */
|
* This method allows you to abort a test immediately with a PASS state, ignoring the remainder of the test. */
|
||||||
#define TEST_PASS() TEST_ABORT()
|
#define TEST_PASS() TEST_ABORT()
|
||||||
|
|
||||||
|
/* This macro does nothing, but it is useful for build tools (like Ceedling) to make use of this to figure out
|
||||||
|
* which files should be linked to in order to perform a test. Use it like TEST_FILE("sandwiches.c") */
|
||||||
|
#define TEST_FILE(a)
|
||||||
|
|
||||||
/*-------------------------------------------------------
|
/*-------------------------------------------------------
|
||||||
* Test Asserts (simple)
|
* Test Asserts (simple)
|
||||||
*-------------------------------------------------------*/
|
*-------------------------------------------------------*/
|
||||||
@ -153,10 +157,31 @@ void tearDown(void);
|
|||||||
#define TEST_ASSERT_EQUAL_STRING_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_STRING_ARRAY((expected), (actual), (num_elements), __LINE__, NULL)
|
#define TEST_ASSERT_EQUAL_STRING_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_STRING_ARRAY((expected), (actual), (num_elements), __LINE__, NULL)
|
||||||
#define TEST_ASSERT_EQUAL_MEMORY_ARRAY(expected, actual, len, num_elements) UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY((expected), (actual), (len), (num_elements), __LINE__, NULL)
|
#define TEST_ASSERT_EQUAL_MEMORY_ARRAY(expected, actual, len, num_elements) UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY((expected), (actual), (len), (num_elements), __LINE__, NULL)
|
||||||
|
|
||||||
|
/* Arrays Compared To Single Value */
|
||||||
|
#define TEST_ASSERT_EACH_EQUAL_INT(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_INT((expected), (actual), (num_elements), __LINE__, NULL)
|
||||||
|
#define TEST_ASSERT_EACH_EQUAL_INT8(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_INT8((expected), (actual), (num_elements), __LINE__, NULL)
|
||||||
|
#define TEST_ASSERT_EACH_EQUAL_INT16(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_INT16((expected), (actual), (num_elements), __LINE__, NULL)
|
||||||
|
#define TEST_ASSERT_EACH_EQUAL_INT32(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_INT32((expected), (actual), (num_elements), __LINE__, NULL)
|
||||||
|
#define TEST_ASSERT_EACH_EQUAL_INT64(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_INT64((expected), (actual), (num_elements), __LINE__, NULL)
|
||||||
|
#define TEST_ASSERT_EACH_EQUAL_UINT(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_UINT((expected), (actual), (num_elements), __LINE__, NULL)
|
||||||
|
#define TEST_ASSERT_EACH_EQUAL_UINT8(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_UINT8((expected), (actual), (num_elements), __LINE__, NULL)
|
||||||
|
#define TEST_ASSERT_EACH_EQUAL_UINT16(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_UINT16((expected), (actual), (num_elements), __LINE__, NULL)
|
||||||
|
#define TEST_ASSERT_EACH_EQUAL_UINT32(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_UINT32((expected), (actual), (num_elements), __LINE__, NULL)
|
||||||
|
#define TEST_ASSERT_EACH_EQUAL_UINT64(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_UINT64((expected), (actual), (num_elements), __LINE__, NULL)
|
||||||
|
#define TEST_ASSERT_EACH_EQUAL_HEX(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_HEX32((expected), (actual), (num_elements), __LINE__, NULL)
|
||||||
|
#define TEST_ASSERT_EACH_EQUAL_HEX8(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_HEX8((expected), (actual), (num_elements), __LINE__, NULL)
|
||||||
|
#define TEST_ASSERT_EACH_EQUAL_HEX16(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_HEX16((expected), (actual), (num_elements), __LINE__, NULL)
|
||||||
|
#define TEST_ASSERT_EACH_EQUAL_HEX32(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_HEX32((expected), (actual), (num_elements), __LINE__, NULL)
|
||||||
|
#define TEST_ASSERT_EACH_EQUAL_HEX64(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_HEX64((expected), (actual), (num_elements), __LINE__, NULL)
|
||||||
|
#define TEST_ASSERT_EACH_EQUAL_PTR(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_PTR((expected), (actual), (num_elements), __LINE__, NULL)
|
||||||
|
#define TEST_ASSERT_EACH_EQUAL_STRING(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_STRING((expected), (actual), (num_elements), __LINE__, NULL)
|
||||||
|
#define TEST_ASSERT_EACH_EQUAL_MEMORY(expected, actual, len, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_MEMORY((expected), (actual), (len), (num_elements), __LINE__, NULL)
|
||||||
|
|
||||||
/* Floating Point (If Enabled) */
|
/* Floating Point (If Enabled) */
|
||||||
#define TEST_ASSERT_FLOAT_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_FLOAT_WITHIN((delta), (expected), (actual), __LINE__, NULL)
|
#define TEST_ASSERT_FLOAT_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_FLOAT_WITHIN((delta), (expected), (actual), __LINE__, NULL)
|
||||||
#define TEST_ASSERT_EQUAL_FLOAT(expected, actual) UNITY_TEST_ASSERT_EQUAL_FLOAT((expected), (actual), __LINE__, NULL)
|
#define TEST_ASSERT_EQUAL_FLOAT(expected, actual) UNITY_TEST_ASSERT_EQUAL_FLOAT((expected), (actual), __LINE__, NULL)
|
||||||
#define TEST_ASSERT_EQUAL_FLOAT_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_FLOAT_ARRAY((expected), (actual), (num_elements), __LINE__, NULL)
|
#define TEST_ASSERT_EQUAL_FLOAT_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_FLOAT_ARRAY((expected), (actual), (num_elements), __LINE__, NULL)
|
||||||
|
#define TEST_ASSERT_EACH_EQUAL_FLOAT(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_FLOAT((expected), (actual), (num_elements), __LINE__, NULL)
|
||||||
#define TEST_ASSERT_FLOAT_IS_INF(actual) UNITY_TEST_ASSERT_FLOAT_IS_INF((actual), __LINE__, NULL)
|
#define TEST_ASSERT_FLOAT_IS_INF(actual) UNITY_TEST_ASSERT_FLOAT_IS_INF((actual), __LINE__, NULL)
|
||||||
#define TEST_ASSERT_FLOAT_IS_NEG_INF(actual) UNITY_TEST_ASSERT_FLOAT_IS_NEG_INF((actual), __LINE__, NULL)
|
#define TEST_ASSERT_FLOAT_IS_NEG_INF(actual) UNITY_TEST_ASSERT_FLOAT_IS_NEG_INF((actual), __LINE__, NULL)
|
||||||
#define TEST_ASSERT_FLOAT_IS_NAN(actual) UNITY_TEST_ASSERT_FLOAT_IS_NAN((actual), __LINE__, NULL)
|
#define TEST_ASSERT_FLOAT_IS_NAN(actual) UNITY_TEST_ASSERT_FLOAT_IS_NAN((actual), __LINE__, NULL)
|
||||||
@ -170,6 +195,7 @@ void tearDown(void);
|
|||||||
#define TEST_ASSERT_DOUBLE_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_DOUBLE_WITHIN((delta), (expected), (actual), __LINE__, NULL)
|
#define TEST_ASSERT_DOUBLE_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_DOUBLE_WITHIN((delta), (expected), (actual), __LINE__, NULL)
|
||||||
#define TEST_ASSERT_EQUAL_DOUBLE(expected, actual) UNITY_TEST_ASSERT_EQUAL_DOUBLE((expected), (actual), __LINE__, NULL)
|
#define TEST_ASSERT_EQUAL_DOUBLE(expected, actual) UNITY_TEST_ASSERT_EQUAL_DOUBLE((expected), (actual), __LINE__, NULL)
|
||||||
#define TEST_ASSERT_EQUAL_DOUBLE_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_DOUBLE_ARRAY((expected), (actual), (num_elements), __LINE__, NULL)
|
#define TEST_ASSERT_EQUAL_DOUBLE_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_DOUBLE_ARRAY((expected), (actual), (num_elements), __LINE__, NULL)
|
||||||
|
#define TEST_ASSERT_EACH_EQUAL_DOUBLE(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_DOUBLE((expected), (actual), (num_elements), __LINE__, NULL)
|
||||||
#define TEST_ASSERT_DOUBLE_IS_INF(actual) UNITY_TEST_ASSERT_DOUBLE_IS_INF((actual), __LINE__, NULL)
|
#define TEST_ASSERT_DOUBLE_IS_INF(actual) UNITY_TEST_ASSERT_DOUBLE_IS_INF((actual), __LINE__, NULL)
|
||||||
#define TEST_ASSERT_DOUBLE_IS_NEG_INF(actual) UNITY_TEST_ASSERT_DOUBLE_IS_NEG_INF((actual), __LINE__, NULL)
|
#define TEST_ASSERT_DOUBLE_IS_NEG_INF(actual) UNITY_TEST_ASSERT_DOUBLE_IS_NEG_INF((actual), __LINE__, NULL)
|
||||||
#define TEST_ASSERT_DOUBLE_IS_NAN(actual) UNITY_TEST_ASSERT_DOUBLE_IS_NAN((actual), __LINE__, NULL)
|
#define TEST_ASSERT_DOUBLE_IS_NAN(actual) UNITY_TEST_ASSERT_DOUBLE_IS_NAN((actual), __LINE__, NULL)
|
||||||
@ -258,10 +284,31 @@ void tearDown(void);
|
|||||||
#define TEST_ASSERT_EQUAL_STRING_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_STRING_ARRAY((expected), (actual), (num_elements), __LINE__, (message))
|
#define TEST_ASSERT_EQUAL_STRING_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_STRING_ARRAY((expected), (actual), (num_elements), __LINE__, (message))
|
||||||
#define TEST_ASSERT_EQUAL_MEMORY_ARRAY_MESSAGE(expected, actual, len, num_elements, message) UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY((expected), (actual), (len), (num_elements), __LINE__, (message))
|
#define TEST_ASSERT_EQUAL_MEMORY_ARRAY_MESSAGE(expected, actual, len, num_elements, message) UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY((expected), (actual), (len), (num_elements), __LINE__, (message))
|
||||||
|
|
||||||
|
/* Arrays Compared To Single Value*/
|
||||||
|
#define TEST_ASSERT_EACH_EQUAL_INT_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_INT((expected), (actual), (num_elements), __LINE__, (message))
|
||||||
|
#define TEST_ASSERT_EACH_EQUAL_INT8_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_INT8((expected), (actual), (num_elements), __LINE__, (message))
|
||||||
|
#define TEST_ASSERT_EACH_EQUAL_INT16_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_INT16((expected), (actual), (num_elements), __LINE__, (message))
|
||||||
|
#define TEST_ASSERT_EACH_EQUAL_INT32_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_INT32((expected), (actual), (num_elements), __LINE__, (message))
|
||||||
|
#define TEST_ASSERT_EACH_EQUAL_INT64_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_INT64((expected), (actual), (num_elements), __LINE__, (message))
|
||||||
|
#define TEST_ASSERT_EACH_EQUAL_UINT_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_UINT((expected), (actual), (num_elements), __LINE__, (message))
|
||||||
|
#define TEST_ASSERT_EACH_EQUAL_UINT8_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_UINT8((expected), (actual), (num_elements), __LINE__, (message))
|
||||||
|
#define TEST_ASSERT_EACH_EQUAL_UINT16_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_UINT16((expected), (actual), (num_elements), __LINE__, (message))
|
||||||
|
#define TEST_ASSERT_EACH_EQUAL_UINT32_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_UINT32((expected), (actual), (num_elements), __LINE__, (message))
|
||||||
|
#define TEST_ASSERT_EACH_EQUAL_UINT64_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_UINT64((expected), (actual), (num_elements), __LINE__, (message))
|
||||||
|
#define TEST_ASSERT_EACH_EQUAL_HEX32_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_HEX32((expected), (actual), (num_elements), __LINE__, (message))
|
||||||
|
#define TEST_ASSERT_EACH_EQUAL_HEX8_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_HEX8((expected), (actual), (num_elements), __LINE__, (message))
|
||||||
|
#define TEST_ASSERT_EACH_EQUAL_HEX16_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_HEX16((expected), (actual), (num_elements), __LINE__, (message))
|
||||||
|
#define TEST_ASSERT_EACH_EQUAL_HEX32_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_HEX32((expected), (actual), (num_elements), __LINE__, (message))
|
||||||
|
#define TEST_ASSERT_EACH_EQUAL_HEX64_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_HEX64((expected), (actual), (num_elements), __LINE__, (message))
|
||||||
|
#define TEST_ASSERT_EACH_EQUAL_PTR_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_PTR((expected), (actual), (num_elements), __LINE__, (message))
|
||||||
|
#define TEST_ASSERT_EACH_EQUAL_STRING_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_STRING((expected), (actual), (num_elements), __LINE__, (message))
|
||||||
|
#define TEST_ASSERT_EACH_EQUAL_MEMORY_MESSAGE(expected, actual, len, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_MEMORY((expected), (actual), (len), (num_elements), __LINE__, (message))
|
||||||
|
|
||||||
/* Floating Point (If Enabled) */
|
/* Floating Point (If Enabled) */
|
||||||
#define TEST_ASSERT_FLOAT_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_FLOAT_WITHIN((delta), (expected), (actual), __LINE__, (message))
|
#define TEST_ASSERT_FLOAT_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_FLOAT_WITHIN((delta), (expected), (actual), __LINE__, (message))
|
||||||
#define TEST_ASSERT_EQUAL_FLOAT_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_FLOAT((expected), (actual), __LINE__, (message))
|
#define TEST_ASSERT_EQUAL_FLOAT_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_FLOAT((expected), (actual), __LINE__, (message))
|
||||||
#define TEST_ASSERT_EQUAL_FLOAT_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_FLOAT_ARRAY((expected), (actual), (num_elements), __LINE__, (message))
|
#define TEST_ASSERT_EQUAL_FLOAT_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_FLOAT_ARRAY((expected), (actual), (num_elements), __LINE__, (message))
|
||||||
|
#define TEST_ASSERT_EACH_EQUAL_FLOAT_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_FLOAT((expected), (actual), (num_elements), __LINE__, (message))
|
||||||
#define TEST_ASSERT_FLOAT_IS_INF_MESSAGE(actual, message) UNITY_TEST_ASSERT_FLOAT_IS_INF((actual), __LINE__, (message))
|
#define TEST_ASSERT_FLOAT_IS_INF_MESSAGE(actual, message) UNITY_TEST_ASSERT_FLOAT_IS_INF((actual), __LINE__, (message))
|
||||||
#define TEST_ASSERT_FLOAT_IS_NEG_INF_MESSAGE(actual, message) UNITY_TEST_ASSERT_FLOAT_IS_NEG_INF((actual), __LINE__, (message))
|
#define TEST_ASSERT_FLOAT_IS_NEG_INF_MESSAGE(actual, message) UNITY_TEST_ASSERT_FLOAT_IS_NEG_INF((actual), __LINE__, (message))
|
||||||
#define TEST_ASSERT_FLOAT_IS_NAN_MESSAGE(actual, message) UNITY_TEST_ASSERT_FLOAT_IS_NAN((actual), __LINE__, (message))
|
#define TEST_ASSERT_FLOAT_IS_NAN_MESSAGE(actual, message) UNITY_TEST_ASSERT_FLOAT_IS_NAN((actual), __LINE__, (message))
|
||||||
@ -275,6 +322,7 @@ void tearDown(void);
|
|||||||
#define TEST_ASSERT_DOUBLE_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_DOUBLE_WITHIN((delta), (expected), (actual), __LINE__, (message))
|
#define TEST_ASSERT_DOUBLE_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_DOUBLE_WITHIN((delta), (expected), (actual), __LINE__, (message))
|
||||||
#define TEST_ASSERT_EQUAL_DOUBLE_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_DOUBLE((expected), (actual), __LINE__, (message))
|
#define TEST_ASSERT_EQUAL_DOUBLE_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_DOUBLE((expected), (actual), __LINE__, (message))
|
||||||
#define TEST_ASSERT_EQUAL_DOUBLE_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_DOUBLE_ARRAY((expected), (actual), (num_elements), __LINE__, (message))
|
#define TEST_ASSERT_EQUAL_DOUBLE_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_DOUBLE_ARRAY((expected), (actual), (num_elements), __LINE__, (message))
|
||||||
|
#define TEST_ASSERT_EACH_EQUAL_DOUBLE_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_DOUBLE((expected), (actual), (num_elements), __LINE__, (message))
|
||||||
#define TEST_ASSERT_DOUBLE_IS_INF_MESSAGE(actual, message) UNITY_TEST_ASSERT_DOUBLE_IS_INF((actual), __LINE__, (message))
|
#define TEST_ASSERT_DOUBLE_IS_INF_MESSAGE(actual, message) UNITY_TEST_ASSERT_DOUBLE_IS_INF((actual), __LINE__, (message))
|
||||||
#define TEST_ASSERT_DOUBLE_IS_NEG_INF_MESSAGE(actual, message) UNITY_TEST_ASSERT_DOUBLE_IS_NEG_INF((actual), __LINE__, (message))
|
#define TEST_ASSERT_DOUBLE_IS_NEG_INF_MESSAGE(actual, message) UNITY_TEST_ASSERT_DOUBLE_IS_NEG_INF((actual), __LINE__, (message))
|
||||||
#define TEST_ASSERT_DOUBLE_IS_NAN_MESSAGE(actual, message) UNITY_TEST_ASSERT_DOUBLE_IS_NAN((actual), __LINE__, (message))
|
#define TEST_ASSERT_DOUBLE_IS_NAN_MESSAGE(actual, message) UNITY_TEST_ASSERT_DOUBLE_IS_NAN((actual), __LINE__, (message))
|
||||||
|
@ -250,14 +250,19 @@ extern void UNITY_OUTPUT_CHAR(int);
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef UNITY_OUTPUT_FLUSH
|
#ifndef UNITY_OUTPUT_FLUSH
|
||||||
/* Default to using fflush, which is defined in stdio.h */
|
#ifdef UNITY_USE_FLUSH_STDOUT
|
||||||
|
/* We want to use the stdout flush utility */
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#define UNITY_OUTPUT_FLUSH (void)fflush(stdout)
|
#define UNITY_OUTPUT_FLUSH (void)fflush(stdout)
|
||||||
#else
|
#else
|
||||||
/* If defined as something else, make sure we declare it here so it's ready for use */
|
/* We've specified nothing, therefore flush should just be ignored */
|
||||||
#ifndef UNITY_OMIT_OUTPUT_FLUSH_HEADER_DECLARATION
|
#define UNITY_OUTPUT_FLUSH
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
/* We've defined flush as something else, so make sure we declare it here so it's ready for use */
|
||||||
|
#ifndef UNITY_OMIT_OUTPUT_FLUSH_HEADER_DECLARATION
|
||||||
extern void UNITY_OUTPUT_FLUSH(void);
|
extern void UNITY_OUTPUT_FLUSH(void);
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef UNITY_OUTPUT_FLUSH
|
#ifndef UNITY_OUTPUT_FLUSH
|
||||||
@ -360,6 +365,12 @@ typedef enum UNITY_FLOAT_TRAIT
|
|||||||
} UNITY_FLOAT_TRAIT_T;
|
} UNITY_FLOAT_TRAIT_T;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
UNITY_ARRAY_TO_VAL = 0,
|
||||||
|
UNITY_ARRAY_TO_ARRAY
|
||||||
|
} UNITY_FLAGS_T;
|
||||||
|
|
||||||
struct UNITY_STORAGE_T
|
struct UNITY_STORAGE_T
|
||||||
{
|
{
|
||||||
const char* TestFile;
|
const char* TestFile;
|
||||||
@ -447,7 +458,8 @@ void UnityAssertEqualIntArray(UNITY_INTERNAL_PTR expected,
|
|||||||
const UNITY_UINT32 num_elements,
|
const UNITY_UINT32 num_elements,
|
||||||
const char* msg,
|
const char* msg,
|
||||||
const UNITY_LINE_TYPE lineNumber,
|
const UNITY_LINE_TYPE lineNumber,
|
||||||
const UNITY_DISPLAY_STYLE_T style);
|
const UNITY_DISPLAY_STYLE_T style,
|
||||||
|
const UNITY_FLAGS_T flags);
|
||||||
|
|
||||||
void UnityAssertBits(const UNITY_INT mask,
|
void UnityAssertBits(const UNITY_INT mask,
|
||||||
const UNITY_INT expected,
|
const UNITY_INT expected,
|
||||||
@ -466,18 +478,20 @@ void UnityAssertEqualStringLen(const char* expected,
|
|||||||
const char* msg,
|
const char* msg,
|
||||||
const UNITY_LINE_TYPE lineNumber);
|
const UNITY_LINE_TYPE lineNumber);
|
||||||
|
|
||||||
void UnityAssertEqualStringArray( const char** expected,
|
void UnityAssertEqualStringArray( UNITY_INTERNAL_PTR expected,
|
||||||
const char** actual,
|
const char** actual,
|
||||||
const UNITY_UINT32 num_elements,
|
const UNITY_UINT32 num_elements,
|
||||||
const char* msg,
|
const char* msg,
|
||||||
const UNITY_LINE_TYPE lineNumber);
|
const UNITY_LINE_TYPE lineNumber,
|
||||||
|
const UNITY_FLAGS_T flags);
|
||||||
|
|
||||||
void UnityAssertEqualMemory( UNITY_INTERNAL_PTR expected,
|
void UnityAssertEqualMemory( UNITY_INTERNAL_PTR expected,
|
||||||
UNITY_INTERNAL_PTR actual,
|
UNITY_INTERNAL_PTR actual,
|
||||||
const UNITY_UINT32 length,
|
const UNITY_UINT32 length,
|
||||||
const UNITY_UINT32 num_elements,
|
const UNITY_UINT32 num_elements,
|
||||||
const char* msg,
|
const char* msg,
|
||||||
const UNITY_LINE_TYPE lineNumber);
|
const UNITY_LINE_TYPE lineNumber,
|
||||||
|
const UNITY_FLAGS_T flags);
|
||||||
|
|
||||||
void UnityAssertNumbersWithin(const UNITY_UINT delta,
|
void UnityAssertNumbersWithin(const UNITY_UINT delta,
|
||||||
const UNITY_INT expected,
|
const UNITY_INT expected,
|
||||||
@ -501,7 +515,8 @@ void UnityAssertEqualFloatArray(UNITY_PTR_ATTRIBUTE const UNITY_FLOAT* expected,
|
|||||||
UNITY_PTR_ATTRIBUTE const UNITY_FLOAT* actual,
|
UNITY_PTR_ATTRIBUTE const UNITY_FLOAT* actual,
|
||||||
const UNITY_UINT32 num_elements,
|
const UNITY_UINT32 num_elements,
|
||||||
const char* msg,
|
const char* msg,
|
||||||
const UNITY_LINE_TYPE lineNumber);
|
const UNITY_LINE_TYPE lineNumber,
|
||||||
|
const UNITY_FLAGS_T flags);
|
||||||
|
|
||||||
void UnityAssertFloatSpecial(const UNITY_FLOAT actual,
|
void UnityAssertFloatSpecial(const UNITY_FLOAT actual,
|
||||||
const char* msg,
|
const char* msg,
|
||||||
@ -520,7 +535,8 @@ void UnityAssertEqualDoubleArray(UNITY_PTR_ATTRIBUTE const UNITY_DOUBLE* expecte
|
|||||||
UNITY_PTR_ATTRIBUTE const UNITY_DOUBLE* actual,
|
UNITY_PTR_ATTRIBUTE const UNITY_DOUBLE* actual,
|
||||||
const UNITY_UINT32 num_elements,
|
const UNITY_UINT32 num_elements,
|
||||||
const char* msg,
|
const char* msg,
|
||||||
const UNITY_LINE_TYPE lineNumber);
|
const UNITY_LINE_TYPE lineNumber,
|
||||||
|
const UNITY_FLAGS_T flags);
|
||||||
|
|
||||||
void UnityAssertDoubleSpecial(const UNITY_DOUBLE actual,
|
void UnityAssertDoubleSpecial(const UNITY_DOUBLE actual,
|
||||||
const char* msg,
|
const char* msg,
|
||||||
@ -528,6 +544,18 @@ void UnityAssertDoubleSpecial(const UNITY_DOUBLE actual,
|
|||||||
const UNITY_FLOAT_TRAIT_T style);
|
const UNITY_FLOAT_TRAIT_T style);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*-------------------------------------------------------
|
||||||
|
* Helpers
|
||||||
|
*-------------------------------------------------------*/
|
||||||
|
|
||||||
|
UNITY_INTERNAL_PTR UnityNumToPtr(const UNITY_INT num, const UNITY_UINT8 size);
|
||||||
|
#ifndef UNITY_EXCLUDE_FLOAT
|
||||||
|
UNITY_INTERNAL_PTR UnityFloatToPtr(const float num);
|
||||||
|
#endif
|
||||||
|
#ifndef UNITY_EXCLUDE_DOUBLE
|
||||||
|
UNITY_INTERNAL_PTR UnityDoubleToPtr(const double num);
|
||||||
|
#endif
|
||||||
|
|
||||||
/*-------------------------------------------------------
|
/*-------------------------------------------------------
|
||||||
* Error Strings We Might Need
|
* Error Strings We Might Need
|
||||||
*-------------------------------------------------------*/
|
*-------------------------------------------------------*/
|
||||||
@ -637,30 +665,48 @@ int UnityTestMatches(void);
|
|||||||
#define UNITY_TEST_ASSERT_EQUAL_PTR(expected, actual, line, message) UnityAssertEqualNumber((UNITY_PTR_TO_INT)(expected), (UNITY_PTR_TO_INT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_POINTER)
|
#define UNITY_TEST_ASSERT_EQUAL_PTR(expected, actual, line, message) UnityAssertEqualNumber((UNITY_PTR_TO_INT)(expected), (UNITY_PTR_TO_INT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_POINTER)
|
||||||
#define UNITY_TEST_ASSERT_EQUAL_STRING(expected, actual, line, message) UnityAssertEqualString((const char*)(expected), (const char*)(actual), (message), (UNITY_LINE_TYPE)(line))
|
#define UNITY_TEST_ASSERT_EQUAL_STRING(expected, actual, line, message) UnityAssertEqualString((const char*)(expected), (const char*)(actual), (message), (UNITY_LINE_TYPE)(line))
|
||||||
#define UNITY_TEST_ASSERT_EQUAL_STRING_LEN(expected, actual, len, line, message) UnityAssertEqualStringLen((const char*)(expected), (const char*)(actual), (UNITY_UINT32)(len), (message), (UNITY_LINE_TYPE)(line))
|
#define UNITY_TEST_ASSERT_EQUAL_STRING_LEN(expected, actual, len, line, message) UnityAssertEqualStringLen((const char*)(expected), (const char*)(actual), (UNITY_UINT32)(len), (message), (UNITY_LINE_TYPE)(line))
|
||||||
#define UNITY_TEST_ASSERT_EQUAL_MEMORY(expected, actual, len, line, message) UnityAssertEqualMemory((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(len), 1, (message), (UNITY_LINE_TYPE)(line))
|
#define UNITY_TEST_ASSERT_EQUAL_MEMORY(expected, actual, len, line, message) UnityAssertEqualMemory((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(len), 1, (message), (UNITY_LINE_TYPE)(line), UNITY_ARRAY_TO_ARRAY)
|
||||||
|
|
||||||
#define UNITY_TEST_ASSERT_EQUAL_INT_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT)
|
#define UNITY_TEST_ASSERT_EQUAL_INT_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT, UNITY_ARRAY_TO_ARRAY)
|
||||||
#define UNITY_TEST_ASSERT_EQUAL_INT8_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT8)
|
#define UNITY_TEST_ASSERT_EQUAL_INT8_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT8, UNITY_ARRAY_TO_ARRAY)
|
||||||
#define UNITY_TEST_ASSERT_EQUAL_INT16_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT16)
|
#define UNITY_TEST_ASSERT_EQUAL_INT16_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT16, UNITY_ARRAY_TO_ARRAY)
|
||||||
#define UNITY_TEST_ASSERT_EQUAL_INT32_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT32)
|
#define UNITY_TEST_ASSERT_EQUAL_INT32_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT32, UNITY_ARRAY_TO_ARRAY)
|
||||||
#define UNITY_TEST_ASSERT_EQUAL_UINT_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT)
|
#define UNITY_TEST_ASSERT_EQUAL_UINT_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT, UNITY_ARRAY_TO_ARRAY)
|
||||||
#define UNITY_TEST_ASSERT_EQUAL_UINT8_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT8)
|
#define UNITY_TEST_ASSERT_EQUAL_UINT8_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT8, UNITY_ARRAY_TO_ARRAY)
|
||||||
#define UNITY_TEST_ASSERT_EQUAL_UINT16_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT16)
|
#define UNITY_TEST_ASSERT_EQUAL_UINT16_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT16, UNITY_ARRAY_TO_ARRAY)
|
||||||
#define UNITY_TEST_ASSERT_EQUAL_UINT32_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT32)
|
#define UNITY_TEST_ASSERT_EQUAL_UINT32_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT32, UNITY_ARRAY_TO_ARRAY)
|
||||||
#define UNITY_TEST_ASSERT_EQUAL_HEX8_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX8)
|
#define UNITY_TEST_ASSERT_EQUAL_HEX8_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX8, UNITY_ARRAY_TO_ARRAY)
|
||||||
#define UNITY_TEST_ASSERT_EQUAL_HEX16_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX16)
|
#define UNITY_TEST_ASSERT_EQUAL_HEX16_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX16, UNITY_ARRAY_TO_ARRAY)
|
||||||
#define UNITY_TEST_ASSERT_EQUAL_HEX32_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX32)
|
#define UNITY_TEST_ASSERT_EQUAL_HEX32_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX32, UNITY_ARRAY_TO_ARRAY)
|
||||||
#define UNITY_TEST_ASSERT_EQUAL_PTR_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_POINTER)
|
#define UNITY_TEST_ASSERT_EQUAL_PTR_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_POINTER, UNITY_ARRAY_TO_ARRAY)
|
||||||
#define UNITY_TEST_ASSERT_EQUAL_STRING_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualStringArray((const char**)(expected), (const char**)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line))
|
#define UNITY_TEST_ASSERT_EQUAL_STRING_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualStringArray((UNITY_INTERNAL_PTR)(expected), (const char**)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_ARRAY_TO_ARRAY)
|
||||||
#define UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY(expected, actual, len, num_elements, line, message) UnityAssertEqualMemory((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(len), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line))
|
#define UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY(expected, actual, len, num_elements, line, message) UnityAssertEqualMemory((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(len), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_ARRAY_TO_ARRAY)
|
||||||
|
|
||||||
|
#define UNITY_TEST_ASSERT_EACH_EQUAL_INT(expected, actual, num_elements, line, message) UnityAssertEqualIntArray(UnityNumToPtr((UNITY_INT) expected, sizeof(int)), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT, UNITY_ARRAY_TO_VAL)
|
||||||
|
#define UNITY_TEST_ASSERT_EACH_EQUAL_INT8(expected, actual, num_elements, line, message) UnityAssertEqualIntArray(UnityNumToPtr((UNITY_INT)(UNITY_INT8 )expected, 1), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT8, UNITY_ARRAY_TO_VAL)
|
||||||
|
#define UNITY_TEST_ASSERT_EACH_EQUAL_INT16(expected, actual, num_elements, line, message) UnityAssertEqualIntArray(UnityNumToPtr((UNITY_INT)(UNITY_INT16 )expected, 2), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT16, UNITY_ARRAY_TO_VAL)
|
||||||
|
#define UNITY_TEST_ASSERT_EACH_EQUAL_INT32(expected, actual, num_elements, line, message) UnityAssertEqualIntArray(UnityNumToPtr((UNITY_INT)(UNITY_INT32 )expected, 4), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT32, UNITY_ARRAY_TO_VAL)
|
||||||
|
#define UNITY_TEST_ASSERT_EACH_EQUAL_UINT(expected, actual, num_elements, line, message) UnityAssertEqualIntArray(UnityNumToPtr((UNITY_INT) expected, sizeof(unsigned int)), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT, UNITY_ARRAY_TO_VAL)
|
||||||
|
#define UNITY_TEST_ASSERT_EACH_EQUAL_UINT8(expected, actual, num_elements, line, message) UnityAssertEqualIntArray(UnityNumToPtr((UNITY_INT)(UNITY_UINT8 )expected, 1), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT8, UNITY_ARRAY_TO_VAL)
|
||||||
|
#define UNITY_TEST_ASSERT_EACH_EQUAL_UINT16(expected, actual, num_elements, line, message) UnityAssertEqualIntArray(UnityNumToPtr((UNITY_INT)(UNITY_UINT16)expected, 2), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT16, UNITY_ARRAY_TO_VAL)
|
||||||
|
#define UNITY_TEST_ASSERT_EACH_EQUAL_UINT32(expected, actual, num_elements, line, message) UnityAssertEqualIntArray(UnityNumToPtr((UNITY_INT)(UNITY_UINT32)expected, 4), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT32, UNITY_ARRAY_TO_VAL)
|
||||||
|
#define UNITY_TEST_ASSERT_EACH_EQUAL_HEX8(expected, actual, num_elements, line, message) UnityAssertEqualIntArray(UnityNumToPtr((UNITY_INT)(UNITY_INT8 )expected, 1), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX8, UNITY_ARRAY_TO_VAL)
|
||||||
|
#define UNITY_TEST_ASSERT_EACH_EQUAL_HEX16(expected, actual, num_elements, line, message) UnityAssertEqualIntArray(UnityNumToPtr((UNITY_INT)(UNITY_INT16 )expected, 2), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX16, UNITY_ARRAY_TO_VAL)
|
||||||
|
#define UNITY_TEST_ASSERT_EACH_EQUAL_HEX32(expected, actual, num_elements, line, message) UnityAssertEqualIntArray(UnityNumToPtr((UNITY_INT)(UNITY_INT32 )expected, 4), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX32, UNITY_ARRAY_TO_VAL)
|
||||||
|
#define UNITY_TEST_ASSERT_EACH_EQUAL_PTR(expected, actual, num_elements, line, message) UnityAssertEqualIntArray(UnityNumToPtr((UNITY_PTR_TO_INT) expected, sizeof(int*)), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_POINTER, UNITY_ARRAY_TO_VAL)
|
||||||
|
#define UNITY_TEST_ASSERT_EACH_EQUAL_STRING(expected, actual, num_elements, line, message) UnityAssertEqualStringArray((UNITY_INTERNAL_PTR)(expected), (const char**)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_ARRAY_TO_VAL)
|
||||||
|
#define UNITY_TEST_ASSERT_EACH_EQUAL_MEMORY(expected, actual, len, num_elements, line, message) UnityAssertEqualMemory((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(len), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_ARRAY_TO_VAL)
|
||||||
|
|
||||||
#ifdef UNITY_SUPPORT_64
|
#ifdef UNITY_SUPPORT_64
|
||||||
#define UNITY_TEST_ASSERT_EQUAL_INT64(expected, actual, line, message) UnityAssertEqualNumber((UNITY_INT)(expected), (UNITY_INT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT64)
|
#define UNITY_TEST_ASSERT_EQUAL_INT64(expected, actual, line, message) UnityAssertEqualNumber((UNITY_INT)(expected), (UNITY_INT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT64)
|
||||||
#define UNITY_TEST_ASSERT_EQUAL_UINT64(expected, actual, line, message) UnityAssertEqualNumber((UNITY_INT)(expected), (UNITY_INT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT64)
|
#define UNITY_TEST_ASSERT_EQUAL_UINT64(expected, actual, line, message) UnityAssertEqualNumber((UNITY_INT)(expected), (UNITY_INT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT64)
|
||||||
#define UNITY_TEST_ASSERT_EQUAL_HEX64(expected, actual, line, message) UnityAssertEqualNumber((UNITY_INT)(expected), (UNITY_INT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX64)
|
#define UNITY_TEST_ASSERT_EQUAL_HEX64(expected, actual, line, message) UnityAssertEqualNumber((UNITY_INT)(expected), (UNITY_INT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX64)
|
||||||
#define UNITY_TEST_ASSERT_EQUAL_INT64_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT64)
|
#define UNITY_TEST_ASSERT_EQUAL_INT64_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT64, UNITY_ARRAY_TO_ARRAY)
|
||||||
#define UNITY_TEST_ASSERT_EQUAL_UINT64_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT64)
|
#define UNITY_TEST_ASSERT_EQUAL_UINT64_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT64, UNITY_ARRAY_TO_ARRAY)
|
||||||
#define UNITY_TEST_ASSERT_EQUAL_HEX64_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX64)
|
#define UNITY_TEST_ASSERT_EQUAL_HEX64_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX64, UNITY_ARRAY_TO_ARRAY)
|
||||||
|
#define UNITY_TEST_ASSERT_EACH_EQUAL_INT64(expected, actual, num_elements, line, message) UnityAssertEqualIntArray(UnityNumToPtr((UNITY_INT)(UNITY_INT64)expected, 8), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT64, UNITY_ARRAY_TO_ARRAY)
|
||||||
|
#define UNITY_TEST_ASSERT_EACH_EQUAL_UINT64(expected, actual, num_elements, line, message) UnityAssertEqualIntArray(UnityNumToPtr((UNITY_INT)(UNITY_INT64)expected, 8), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT64, UNITY_ARRAY_TO_ARRAY)
|
||||||
|
#define UNITY_TEST_ASSERT_EACH_EQUAL_HEX64(expected, actual, num_elements, line, message) UnityAssertEqualIntArray(UnityNumToPtr((UNITY_INT)(UNITY_INT64)expected, 8), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX64, UNITY_ARRAY_TO_ARRAY)
|
||||||
#define UNITY_TEST_ASSERT_INT64_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((delta), (UNITY_INT)(expected), (UNITY_INT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT64)
|
#define UNITY_TEST_ASSERT_INT64_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((delta), (UNITY_INT)(expected), (UNITY_INT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT64)
|
||||||
#define UNITY_TEST_ASSERT_UINT64_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((delta), (UNITY_INT)(expected), (UNITY_INT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT64)
|
#define UNITY_TEST_ASSERT_UINT64_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((delta), (UNITY_INT)(expected), (UNITY_INT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT64)
|
||||||
#define UNITY_TEST_ASSERT_HEX64_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((delta), (UNITY_INT)(expected), (UNITY_INT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX64)
|
#define UNITY_TEST_ASSERT_HEX64_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((delta), (UNITY_INT)(expected), (UNITY_INT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX64)
|
||||||
@ -680,6 +726,7 @@ int UnityTestMatches(void);
|
|||||||
#define UNITY_TEST_ASSERT_FLOAT_WITHIN(delta, expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrFloat)
|
#define UNITY_TEST_ASSERT_FLOAT_WITHIN(delta, expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrFloat)
|
||||||
#define UNITY_TEST_ASSERT_EQUAL_FLOAT(expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrFloat)
|
#define UNITY_TEST_ASSERT_EQUAL_FLOAT(expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrFloat)
|
||||||
#define UNITY_TEST_ASSERT_EQUAL_FLOAT_ARRAY(expected, actual, num_elements, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrFloat)
|
#define UNITY_TEST_ASSERT_EQUAL_FLOAT_ARRAY(expected, actual, num_elements, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrFloat)
|
||||||
|
#define UNITY_TEST_ASSERT_EACH_EQUAL_FLOAT(expected, actual, num_elements, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrFloat)
|
||||||
#define UNITY_TEST_ASSERT_FLOAT_IS_INF(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrFloat)
|
#define UNITY_TEST_ASSERT_FLOAT_IS_INF(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrFloat)
|
||||||
#define UNITY_TEST_ASSERT_FLOAT_IS_NEG_INF(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrFloat)
|
#define UNITY_TEST_ASSERT_FLOAT_IS_NEG_INF(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrFloat)
|
||||||
#define UNITY_TEST_ASSERT_FLOAT_IS_NAN(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrFloat)
|
#define UNITY_TEST_ASSERT_FLOAT_IS_NAN(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrFloat)
|
||||||
@ -691,7 +738,8 @@ int UnityTestMatches(void);
|
|||||||
#else
|
#else
|
||||||
#define UNITY_TEST_ASSERT_FLOAT_WITHIN(delta, expected, actual, line, message) UnityAssertFloatsWithin((UNITY_FLOAT)(delta), (UNITY_FLOAT)(expected), (UNITY_FLOAT)(actual), (message), (UNITY_LINE_TYPE)(line))
|
#define UNITY_TEST_ASSERT_FLOAT_WITHIN(delta, expected, actual, line, message) UnityAssertFloatsWithin((UNITY_FLOAT)(delta), (UNITY_FLOAT)(expected), (UNITY_FLOAT)(actual), (message), (UNITY_LINE_TYPE)(line))
|
||||||
#define UNITY_TEST_ASSERT_EQUAL_FLOAT(expected, actual, line, message) UNITY_TEST_ASSERT_FLOAT_WITHIN((UNITY_FLOAT)(expected) * (UNITY_FLOAT)UNITY_FLOAT_PRECISION, (UNITY_FLOAT)(expected), (UNITY_FLOAT)(actual), (UNITY_LINE_TYPE)(line), (message))
|
#define UNITY_TEST_ASSERT_EQUAL_FLOAT(expected, actual, line, message) UNITY_TEST_ASSERT_FLOAT_WITHIN((UNITY_FLOAT)(expected) * (UNITY_FLOAT)UNITY_FLOAT_PRECISION, (UNITY_FLOAT)(expected), (UNITY_FLOAT)(actual), (UNITY_LINE_TYPE)(line), (message))
|
||||||
#define UNITY_TEST_ASSERT_EQUAL_FLOAT_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualFloatArray((UNITY_FLOAT*)(expected), (UNITY_FLOAT*)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line))
|
#define UNITY_TEST_ASSERT_EQUAL_FLOAT_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualFloatArray((UNITY_FLOAT*)(expected), (UNITY_FLOAT*)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_ARRAY_TO_ARRAY)
|
||||||
|
#define UNITY_TEST_ASSERT_EACH_EQUAL_FLOAT(expected, actual, num_elements, line, message) UnityAssertEqualFloatArray(UnityFloatToPtr(expected), (UNITY_FLOAT*)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_ARRAY_TO_VAL)
|
||||||
#define UNITY_TEST_ASSERT_FLOAT_IS_INF(actual, line, message) UnityAssertFloatSpecial((UNITY_FLOAT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_INF)
|
#define UNITY_TEST_ASSERT_FLOAT_IS_INF(actual, line, message) UnityAssertFloatSpecial((UNITY_FLOAT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_INF)
|
||||||
#define UNITY_TEST_ASSERT_FLOAT_IS_NEG_INF(actual, line, message) UnityAssertFloatSpecial((UNITY_FLOAT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_NEG_INF)
|
#define UNITY_TEST_ASSERT_FLOAT_IS_NEG_INF(actual, line, message) UnityAssertFloatSpecial((UNITY_FLOAT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_NEG_INF)
|
||||||
#define UNITY_TEST_ASSERT_FLOAT_IS_NAN(actual, line, message) UnityAssertFloatSpecial((UNITY_FLOAT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_NAN)
|
#define UNITY_TEST_ASSERT_FLOAT_IS_NAN(actual, line, message) UnityAssertFloatSpecial((UNITY_FLOAT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_NAN)
|
||||||
@ -706,6 +754,7 @@ int UnityTestMatches(void);
|
|||||||
#define UNITY_TEST_ASSERT_DOUBLE_WITHIN(delta, expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrDouble)
|
#define UNITY_TEST_ASSERT_DOUBLE_WITHIN(delta, expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrDouble)
|
||||||
#define UNITY_TEST_ASSERT_EQUAL_DOUBLE(expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrDouble)
|
#define UNITY_TEST_ASSERT_EQUAL_DOUBLE(expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrDouble)
|
||||||
#define UNITY_TEST_ASSERT_EQUAL_DOUBLE_ARRAY(expected, actual, num_elements, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrDouble)
|
#define UNITY_TEST_ASSERT_EQUAL_DOUBLE_ARRAY(expected, actual, num_elements, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrDouble)
|
||||||
|
#define UNITY_TEST_ASSERT_EACH_EQUAL_DOUBLE(expected, actual, num_elements, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrDouble)
|
||||||
#define UNITY_TEST_ASSERT_DOUBLE_IS_INF(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrDouble)
|
#define UNITY_TEST_ASSERT_DOUBLE_IS_INF(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrDouble)
|
||||||
#define UNITY_TEST_ASSERT_DOUBLE_IS_NEG_INF(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrDouble)
|
#define UNITY_TEST_ASSERT_DOUBLE_IS_NEG_INF(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrDouble)
|
||||||
#define UNITY_TEST_ASSERT_DOUBLE_IS_NAN(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrDouble)
|
#define UNITY_TEST_ASSERT_DOUBLE_IS_NAN(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrDouble)
|
||||||
@ -717,7 +766,8 @@ int UnityTestMatches(void);
|
|||||||
#else
|
#else
|
||||||
#define UNITY_TEST_ASSERT_DOUBLE_WITHIN(delta, expected, actual, line, message) UnityAssertDoublesWithin((UNITY_DOUBLE)(delta), (UNITY_DOUBLE)(expected), (UNITY_DOUBLE)(actual), (message), (UNITY_LINE_TYPE)line)
|
#define UNITY_TEST_ASSERT_DOUBLE_WITHIN(delta, expected, actual, line, message) UnityAssertDoublesWithin((UNITY_DOUBLE)(delta), (UNITY_DOUBLE)(expected), (UNITY_DOUBLE)(actual), (message), (UNITY_LINE_TYPE)line)
|
||||||
#define UNITY_TEST_ASSERT_EQUAL_DOUBLE(expected, actual, line, message) UNITY_TEST_ASSERT_DOUBLE_WITHIN((UNITY_DOUBLE)(expected) * (UNITY_DOUBLE)UNITY_DOUBLE_PRECISION, (UNITY_DOUBLE)expected, (UNITY_DOUBLE)actual, (UNITY_LINE_TYPE)(line), message)
|
#define UNITY_TEST_ASSERT_EQUAL_DOUBLE(expected, actual, line, message) UNITY_TEST_ASSERT_DOUBLE_WITHIN((UNITY_DOUBLE)(expected) * (UNITY_DOUBLE)UNITY_DOUBLE_PRECISION, (UNITY_DOUBLE)expected, (UNITY_DOUBLE)actual, (UNITY_LINE_TYPE)(line), message)
|
||||||
#define UNITY_TEST_ASSERT_EQUAL_DOUBLE_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualDoubleArray((UNITY_DOUBLE*)(expected), (UNITY_DOUBLE*)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)line)
|
#define UNITY_TEST_ASSERT_EQUAL_DOUBLE_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualDoubleArray((UNITY_DOUBLE*)(expected), (UNITY_DOUBLE*)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)line, UNITY_ARRAY_TO_ARRAY)
|
||||||
|
#define UNITY_TEST_ASSERT_EACH_EQUAL_DOUBLE(expected, actual, num_elements, line, message) UnityAssertEqualDoubleArray(UnityDoubleToPtr(expected), (UNITY_DOUBLE*)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)line, UNITY_ARRAY_TO_VAL)
|
||||||
#define UNITY_TEST_ASSERT_DOUBLE_IS_INF(actual, line, message) UnityAssertDoubleSpecial((UNITY_DOUBLE)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_INF)
|
#define UNITY_TEST_ASSERT_DOUBLE_IS_INF(actual, line, message) UnityAssertDoubleSpecial((UNITY_DOUBLE)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_INF)
|
||||||
#define UNITY_TEST_ASSERT_DOUBLE_IS_NEG_INF(actual, line, message) UnityAssertDoubleSpecial((UNITY_DOUBLE)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_NEG_INF)
|
#define UNITY_TEST_ASSERT_DOUBLE_IS_NEG_INF(actual, line, message) UnityAssertDoubleSpecial((UNITY_DOUBLE)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_NEG_INF)
|
||||||
#define UNITY_TEST_ASSERT_DOUBLE_IS_NAN(actual, line, message) UnityAssertDoubleSpecial((UNITY_DOUBLE)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_NAN)
|
#define UNITY_TEST_ASSERT_DOUBLE_IS_NAN(actual, line, message) UnityAssertDoubleSpecial((UNITY_DOUBLE)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_NAN)
|
||||||
|
58
tests/unity/test/.rubocop.yml
Normal file
58
tests/unity/test/.rubocop.yml
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
# This is the configuration used to check the rubocop source code.
|
||||||
|
|
||||||
|
#inherit_from: .rubocop_todo.yml
|
||||||
|
|
||||||
|
AllCops:
|
||||||
|
TargetRubyVersion: 2.1
|
||||||
|
|
||||||
|
# These are areas where ThrowTheSwitch's coding style diverges from the Ruby standard
|
||||||
|
Style/SpecialGlobalVars:
|
||||||
|
EnforcedStyle: use_perl_names
|
||||||
|
Style/FormatString:
|
||||||
|
Enabled: false
|
||||||
|
Style/GlobalVars:
|
||||||
|
Enabled: false
|
||||||
|
Style/RegexpLiteral:
|
||||||
|
AllowInnerSlashes: true
|
||||||
|
Style/HashSyntax:
|
||||||
|
EnforcedStyle: no_mixed_keys
|
||||||
|
|
||||||
|
# This is disabled because it seems to get confused over nested hashes
|
||||||
|
Style/AlignHash:
|
||||||
|
Enabled: false
|
||||||
|
EnforcedHashRocketStyle: table
|
||||||
|
EnforcedColonStyle: table
|
||||||
|
|
||||||
|
# We purposefully use these insecure features because they're what makes Ruby awesome
|
||||||
|
Security/Eval:
|
||||||
|
Enabled: false
|
||||||
|
Security/YAMLLoad:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
|
# At this point, we're not ready to enforce inline documentation requirements
|
||||||
|
Style/Documentation:
|
||||||
|
Enabled: false
|
||||||
|
Style/DocumentationMethod:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
|
# At this point, we're not ready to enforce any metrics
|
||||||
|
Metrics/AbcSize:
|
||||||
|
Enabled: false
|
||||||
|
Metrics/BlockLength:
|
||||||
|
Enabled: false
|
||||||
|
Metrics/BlockNesting:
|
||||||
|
Enabled: false
|
||||||
|
Metrics/ClassLength:
|
||||||
|
Enabled: false
|
||||||
|
Metrics/CyclomaticComplexity:
|
||||||
|
Enabled: false
|
||||||
|
Metrics/LineLength:
|
||||||
|
Enabled: false
|
||||||
|
Metrics/MethodLength:
|
||||||
|
Enabled: false
|
||||||
|
Metrics/ModuleLength:
|
||||||
|
Enabled: false
|
||||||
|
Metrics/ParameterLists:
|
||||||
|
Enabled: false
|
||||||
|
Metrics/PerceivedComplexity:
|
||||||
|
Enabled: false
|
@ -32,7 +32,7 @@ configure_toolchain(DEFAULT_CONFIG_FILE)
|
|||||||
|
|
||||||
desc "Test unity with its own unit tests"
|
desc "Test unity with its own unit tests"
|
||||||
task :unit => [:prepare_for_tests] do
|
task :unit => [:prepare_for_tests] do
|
||||||
run_tests get_unit_test_files
|
run_tests unit_test_files
|
||||||
end
|
end
|
||||||
|
|
||||||
desc "Test unity's helper scripts"
|
desc "Test unity's helper scripts"
|
||||||
@ -53,7 +53,7 @@ task :summary do
|
|||||||
end
|
end
|
||||||
|
|
||||||
desc "Build and test Unity"
|
desc "Build and test Unity"
|
||||||
task :all => [:clean, :prepare_for_tests, :scripts, :unit, :summary]
|
task :all => [:clean, :prepare_for_tests, :scripts, :unit, :style, :summary]
|
||||||
task :default => [:clobber, :all]
|
task :default => [:clobber, :all]
|
||||||
task :ci => [:no_color, :default]
|
task :ci => [:no_color, :default]
|
||||||
task :cruise => [:no_color, :default]
|
task :cruise => [:no_color, :default]
|
||||||
@ -70,3 +70,56 @@ end
|
|||||||
task :verbose do
|
task :verbose do
|
||||||
$verbose = true
|
$verbose = true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
namespace :style do
|
||||||
|
desc "Check style"
|
||||||
|
task :check do
|
||||||
|
report "\nVERIFYING RUBY STYLE"
|
||||||
|
report execute("rubocop ../auto ../examples ../extras --config .rubocop.yml", true)
|
||||||
|
report "Styling Ruby:PASS"
|
||||||
|
end
|
||||||
|
|
||||||
|
namespace :check do
|
||||||
|
Dir['../**/*.rb'].each do |f|
|
||||||
|
filename = File.basename(f, '.rb')
|
||||||
|
desc "Check Style of #{filename}"
|
||||||
|
task filename.to_sym => ['style:clean'] do
|
||||||
|
report execute("rubocop #{f} --color --config .rubocop.yml", true)
|
||||||
|
report "Style Checked for #{f}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
desc "Fix Style of all C Code"
|
||||||
|
task :c do
|
||||||
|
run_astyle("../src/*.* ../extras/fixture/src/*.*")
|
||||||
|
end
|
||||||
|
|
||||||
|
namespace :c do
|
||||||
|
Dir['../{src,extras/**}/*.{c,h}'].each do |f|
|
||||||
|
filename = File.basename(f)[0..-3]
|
||||||
|
desc "Check Style of #{filename}"
|
||||||
|
task filename.to_sym do
|
||||||
|
run_astyle f
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
desc "Attempt to Autocorrect style"
|
||||||
|
task :auto => ['style:clean'] do
|
||||||
|
execute("rubocop ../auto ../examples ../extras --auto-correct --config .rubocop.yml")
|
||||||
|
report "Autocorrected What We Could."
|
||||||
|
end
|
||||||
|
|
||||||
|
desc "Update style todo list"
|
||||||
|
task :todo => ['style:clean'] do
|
||||||
|
execute("rubocop ../auto ../examples ../extras --auto-gen-config --config .rubocop.yml")
|
||||||
|
report "Updated Style TODO List."
|
||||||
|
end
|
||||||
|
|
||||||
|
task :clean do
|
||||||
|
File.delete(".rubocop_todo.yml") if File.exists?(".rubocop_todo.yml")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
task :style => ['style:check']
|
||||||
|
@ -11,39 +11,37 @@ require UNITY_ROOT + '../auto/generate_test_runner'
|
|||||||
require UNITY_ROOT + '../auto/colour_reporter'
|
require UNITY_ROOT + '../auto/colour_reporter'
|
||||||
|
|
||||||
module RakefileHelpers
|
module RakefileHelpers
|
||||||
|
C_EXTENSION = '.c'.freeze
|
||||||
C_EXTENSION = '.c'
|
|
||||||
|
|
||||||
def load_configuration(config_file)
|
def load_configuration(config_file)
|
||||||
unless ($configured)
|
return if $configured
|
||||||
$cfg_file = "targets/#{config_file}" unless (config_file =~ /[\\|\/]/)
|
|
||||||
$cfg = YAML.load(File.read($cfg_file))
|
$cfg_file = "targets/#{config_file}" unless config_file =~ /[\\|\/]/
|
||||||
$colour_output = false unless $cfg['colour']
|
$cfg = YAML.load(File.read($cfg_file))
|
||||||
$configured = true if (config_file != DEFAULT_CONFIG_FILE)
|
$colour_output = false unless $cfg['colour']
|
||||||
end
|
$configured = true if config_file != DEFAULT_CONFIG_FILE
|
||||||
end
|
end
|
||||||
|
|
||||||
def configure_clean
|
def configure_clean
|
||||||
CLEAN.include($cfg['compiler']['build_path'] + '*.*') unless $cfg['compiler']['build_path'].nil?
|
CLEAN.include($cfg['compiler']['build_path'] + '*.*') unless $cfg['compiler']['build_path'].nil?
|
||||||
end
|
end
|
||||||
|
|
||||||
def configure_toolchain(config_file=DEFAULT_CONFIG_FILE)
|
def configure_toolchain(config_file = DEFAULT_CONFIG_FILE)
|
||||||
config_file += '.yml' unless config_file =~ /\.yml$/
|
config_file += '.yml' unless config_file =~ /\.yml$/
|
||||||
config_file = config_file unless config_file =~ /[\\|\/]/
|
config_file = config_file unless config_file =~ /[\\|\/]/
|
||||||
load_configuration(config_file)
|
load_configuration(config_file)
|
||||||
configure_clean
|
configure_clean
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_unit_test_files
|
def unit_test_files
|
||||||
path = $cfg['compiler']['unit_tests_path'] + 'test*' + C_EXTENSION
|
path = $cfg['compiler']['unit_tests_path'] + 'test*' + C_EXTENSION
|
||||||
path.gsub!(/\\/, '/')
|
path.tr!('\\', '/')
|
||||||
FileList.new(path)
|
FileList.new(path)
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_local_include_dirs
|
def local_include_dirs
|
||||||
include_dirs = $cfg['compiler']['includes']['items'].dup
|
include_dirs = $cfg['compiler']['includes']['items'].dup
|
||||||
include_dirs.delete_if {|dir| dir.is_a?(Array)}
|
include_dirs.delete_if { |dir| dir.is_a?(Array) }
|
||||||
return include_dirs
|
include_dirs
|
||||||
end
|
end
|
||||||
|
|
||||||
def extract_headers(filename)
|
def extract_headers(filename)
|
||||||
@ -51,41 +49,37 @@ module RakefileHelpers
|
|||||||
lines = File.readlines(filename)
|
lines = File.readlines(filename)
|
||||||
lines.each do |line|
|
lines.each do |line|
|
||||||
m = line.match(/^\s*#include\s+\"\s*(.+\.[hH])\s*\"/)
|
m = line.match(/^\s*#include\s+\"\s*(.+\.[hH])\s*\"/)
|
||||||
if not m.nil?
|
includes << m[1] unless m.nil?
|
||||||
includes << m[1]
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
return includes
|
includes
|
||||||
end
|
end
|
||||||
|
|
||||||
def find_source_file(header, paths)
|
def find_source_file(header, paths)
|
||||||
paths.each do |dir|
|
paths.each do |dir|
|
||||||
src_file = dir + header.ext(C_EXTENSION)
|
src_file = dir + header.ext(C_EXTENSION)
|
||||||
if (File.exists?(src_file))
|
return src_file if File.exist?(src_file)
|
||||||
return src_file
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
return nil
|
nil
|
||||||
end
|
end
|
||||||
|
|
||||||
def tackit(strings)
|
def tackit(strings)
|
||||||
if strings.is_a?(Array)
|
result = if strings.is_a?(Array)
|
||||||
result = "\"#{strings.join}\""
|
"\"#{strings.join}\""
|
||||||
else
|
else
|
||||||
result = strings
|
strings
|
||||||
end
|
end
|
||||||
return result
|
result
|
||||||
end
|
end
|
||||||
|
|
||||||
def squash(prefix, items)
|
def squash(prefix, items)
|
||||||
result = ''
|
result = ''
|
||||||
items.each { |item| result += " #{prefix}#{tackit(item)}" }
|
items.each { |item| result += " #{prefix}#{tackit(item)}" }
|
||||||
return result
|
result
|
||||||
end
|
end
|
||||||
|
|
||||||
def should(behave, &block)
|
def should(behave, &block)
|
||||||
if block
|
if block
|
||||||
puts "Should " + behave
|
puts 'Should ' + behave
|
||||||
yield block
|
yield block
|
||||||
else
|
else
|
||||||
puts "UNIMPLEMENTED CASE: Should #{behave}"
|
puts "UNIMPLEMENTED CASE: Should #{behave}"
|
||||||
@ -93,91 +87,103 @@ module RakefileHelpers
|
|||||||
end
|
end
|
||||||
|
|
||||||
def build_compiler_fields(inject_defines)
|
def build_compiler_fields(inject_defines)
|
||||||
command = tackit($cfg['compiler']['path'])
|
command = tackit($cfg['compiler']['path'])
|
||||||
if $cfg['compiler']['defines']['items'].nil?
|
defines = if $cfg['compiler']['defines']['items'].nil?
|
||||||
defines = ''
|
''
|
||||||
else
|
else
|
||||||
defines = squash($cfg['compiler']['defines']['prefix'], $cfg['compiler']['defines']['items'] + ['UNITY_OUTPUT_CHAR=putcharSpy'] + inject_defines)
|
squash($cfg['compiler']['defines']['prefix'], $cfg['compiler']['defines']['items'] + ['UNITY_OUTPUT_CHAR=putcharSpy'] + inject_defines)
|
||||||
end
|
end
|
||||||
options = squash('', $cfg['compiler']['options'])
|
options = squash('', $cfg['compiler']['options'])
|
||||||
includes = squash($cfg['compiler']['includes']['prefix'], $cfg['compiler']['includes']['items'])
|
includes = squash($cfg['compiler']['includes']['prefix'], $cfg['compiler']['includes']['items'])
|
||||||
includes = includes.gsub(/\\ /, ' ').gsub(/\\\"/, '"').gsub(/\\$/, '') # Remove trailing slashes (for IAR)
|
includes = includes.gsub(/\\ /, ' ').gsub(/\\\"/, '"').gsub(/\\$/, '') # Remove trailing slashes (for IAR)
|
||||||
return {:command => command, :defines => defines, :options => options, :includes => includes}
|
|
||||||
|
{ :command => command, :defines => defines, :options => options, :includes => includes }
|
||||||
end
|
end
|
||||||
|
|
||||||
def compile(file, defines=[])
|
def compile(file, defines = [])
|
||||||
compiler = build_compiler_fields(defines)
|
compiler = build_compiler_fields(defines)
|
||||||
defines =
|
cmd_str = "#{compiler[:command]}#{compiler[:defines]}#{compiler[:options]}#{compiler[:includes]} #{file} " \
|
||||||
cmd_str = "#{compiler[:command]}#{compiler[:defines]}#{compiler[:options]}#{compiler[:includes]} #{file} " +
|
|
||||||
"#{$cfg['compiler']['object_files']['prefix']}#{$cfg['compiler']['object_files']['destination']}"
|
"#{$cfg['compiler']['object_files']['prefix']}#{$cfg['compiler']['object_files']['destination']}"
|
||||||
obj_file = "#{File.basename(file, C_EXTENSION)}#{$cfg['compiler']['object_files']['extension']}"
|
obj_file = "#{File.basename(file, C_EXTENSION)}#{$cfg['compiler']['object_files']['extension']}"
|
||||||
execute(cmd_str + obj_file)
|
execute(cmd_str + obj_file)
|
||||||
return obj_file
|
|
||||||
|
obj_file
|
||||||
end
|
end
|
||||||
|
|
||||||
def build_linker_fields
|
def build_linker_fields
|
||||||
command = tackit($cfg['linker']['path'])
|
command = tackit($cfg['linker']['path'])
|
||||||
if $cfg['linker']['options'].nil?
|
options = if $cfg['linker']['options'].nil?
|
||||||
options = ''
|
''
|
||||||
else
|
else
|
||||||
options = squash('', $cfg['linker']['options'])
|
squash('', $cfg['linker']['options'])
|
||||||
end
|
end
|
||||||
if ($cfg['linker']['includes'].nil? || $cfg['linker']['includes']['items'].nil?)
|
includes = if $cfg['linker']['includes'].nil? || $cfg['linker']['includes']['items'].nil?
|
||||||
includes = ''
|
''
|
||||||
else
|
else
|
||||||
includes = squash($cfg['linker']['includes']['prefix'], $cfg['linker']['includes']['items'])
|
squash($cfg['linker']['includes']['prefix'], $cfg['linker']['includes']['items'])
|
||||||
end
|
end.gsub(/\\ /, ' ').gsub(/\\\"/, '"').gsub(/\\$/, '') # Remove trailing slashes (for IAR)
|
||||||
includes = includes.gsub(/\\ /, ' ').gsub(/\\\"/, '"').gsub(/\\$/, '') # Remove trailing slashes (for IAR)
|
|
||||||
return {:command => command, :options => options, :includes => includes}
|
{ :command => command, :options => options, :includes => includes }
|
||||||
end
|
end
|
||||||
|
|
||||||
def link_it(exe_name, obj_list)
|
def link_it(exe_name, obj_list)
|
||||||
linker = build_linker_fields
|
linker = build_linker_fields
|
||||||
cmd_str = "#{linker[:command]}#{linker[:options]}#{linker[:includes]} " +
|
cmd_str = "#{linker[:command]}#{linker[:options]}#{linker[:includes]} " +
|
||||||
(obj_list.map{|obj|"#{$cfg['linker']['object_files']['path']}#{obj} "}).join +
|
(obj_list.map { |obj| "#{$cfg['linker']['object_files']['path']}#{obj} " }).join +
|
||||||
$cfg['linker']['bin_files']['prefix'] + ' ' +
|
$cfg['linker']['bin_files']['prefix'] + ' ' +
|
||||||
$cfg['linker']['bin_files']['destination'] +
|
$cfg['linker']['bin_files']['destination'] +
|
||||||
exe_name + $cfg['linker']['bin_files']['extension']
|
exe_name + $cfg['linker']['bin_files']['extension']
|
||||||
execute(cmd_str)
|
execute(cmd_str)
|
||||||
end
|
end
|
||||||
|
|
||||||
def build_simulator_fields
|
def build_simulator_fields
|
||||||
return nil if $cfg['simulator'].nil?
|
return nil if $cfg['simulator'].nil?
|
||||||
if $cfg['simulator']['path'].nil?
|
command = if $cfg['simulator']['path'].nil?
|
||||||
command = ''
|
''
|
||||||
else
|
else
|
||||||
command = (tackit($cfg['simulator']['path']) + ' ')
|
(tackit($cfg['simulator']['path']) + ' ')
|
||||||
end
|
end
|
||||||
if $cfg['simulator']['pre_support'].nil?
|
pre_support = if $cfg['simulator']['pre_support'].nil?
|
||||||
pre_support = ''
|
''
|
||||||
else
|
else
|
||||||
pre_support = squash('', $cfg['simulator']['pre_support'])
|
squash('', $cfg['simulator']['pre_support'])
|
||||||
end
|
end
|
||||||
if $cfg['simulator']['post_support'].nil?
|
post_support = if $cfg['simulator']['post_support'].nil?
|
||||||
post_support = ''
|
''
|
||||||
else
|
else
|
||||||
post_support = squash('', $cfg['simulator']['post_support'])
|
squash('', $cfg['simulator']['post_support'])
|
||||||
end
|
end
|
||||||
return {:command => command, :pre_support => pre_support, :post_support => post_support}
|
|
||||||
|
{ :command => command, :pre_support => pre_support, :post_support => post_support }
|
||||||
end
|
end
|
||||||
|
|
||||||
def execute(command_string, ok_to_fail=false)
|
def run_astyle(style_what)
|
||||||
|
report "Styling C Code..."
|
||||||
|
command = "AStyle " \
|
||||||
|
"--style=allman --indent=spaces=4 --indent-switches --indent-preproc-define --indent-preproc-block " \
|
||||||
|
"--pad-oper --pad-comma --unpad-paren --pad-header " \
|
||||||
|
"--align-pointer=type --align-reference=name " \
|
||||||
|
"--add-brackets --mode=c --suffix=none " \
|
||||||
|
"#{style_what}"
|
||||||
|
execute(command, false)
|
||||||
|
report "Styling C:PASS"
|
||||||
|
end
|
||||||
|
|
||||||
|
def execute(command_string, ok_to_fail = false)
|
||||||
report command_string if $verbose
|
report command_string if $verbose
|
||||||
output = `#{command_string}`.chomp
|
output = `#{command_string}`.chomp
|
||||||
report(output) if ($verbose && !output.nil? && (output.length > 0))
|
report(output) if $verbose && !output.nil? && !output.empty?
|
||||||
if (($?.exitstatus != 0) && !ok_to_fail)
|
raise "Command failed. (Returned #{$?.exitstatus})" if !$?.exitstatus.zero? && !ok_to_fail
|
||||||
raise "Command failed. (Returned #{$?.exitstatus})"
|
output
|
||||||
end
|
|
||||||
return output
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def report_summary
|
def report_summary
|
||||||
summary = UnityTestSummary.new
|
summary = UnityTestSummary.new
|
||||||
summary.set_root_path(UNITY_ROOT)
|
summary.root = UNITY_ROOT
|
||||||
results_glob = "#{$cfg['compiler']['build_path']}*.test*"
|
results_glob = "#{$cfg['compiler']['build_path']}*.test*"
|
||||||
results_glob.gsub!(/\\/, '/')
|
results_glob.tr!('\\', '/')
|
||||||
results = Dir[results_glob]
|
results = Dir[results_glob]
|
||||||
summary.set_targets(results)
|
summary.targets = results
|
||||||
report summary.run
|
report summary.run
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -187,16 +193,16 @@ module RakefileHelpers
|
|||||||
# Tack on TEST define for compiling unit tests
|
# Tack on TEST define for compiling unit tests
|
||||||
load_configuration($cfg_file)
|
load_configuration($cfg_file)
|
||||||
test_defines = ['TEST']
|
test_defines = ['TEST']
|
||||||
$cfg['compiler']['defines']['items'] = [] if $cfg['compiler']['defines']['items'].nil?
|
$cfg['compiler']['defines']['items'] ||= []
|
||||||
$cfg['compiler']['defines']['items'] << 'TEST'
|
$cfg['compiler']['defines']['items'] << 'TEST'
|
||||||
|
|
||||||
include_dirs = get_local_include_dirs
|
include_dirs = local_include_dirs
|
||||||
|
|
||||||
# Build and execute each unit test
|
# Build and execute each unit test
|
||||||
test_files.each do |test|
|
test_files.each do |test|
|
||||||
obj_list = []
|
obj_list = []
|
||||||
|
|
||||||
if !$cfg['compiler']['aux_sources'].nil?
|
unless $cfg['compiler']['aux_sources'].nil?
|
||||||
$cfg['compiler']['aux_sources'].each do |aux|
|
$cfg['compiler']['aux_sources'].each do |aux|
|
||||||
obj_list << compile(aux, test_defines)
|
obj_list << compile(aux, test_defines)
|
||||||
end
|
end
|
||||||
@ -206,25 +212,23 @@ module RakefileHelpers
|
|||||||
extract_headers(test).each do |header|
|
extract_headers(test).each do |header|
|
||||||
# Compile corresponding source file if it exists
|
# Compile corresponding source file if it exists
|
||||||
src_file = find_source_file(header, include_dirs)
|
src_file = find_source_file(header, include_dirs)
|
||||||
if !src_file.nil?
|
|
||||||
obj_list << compile(src_file, test_defines)
|
obj_list << compile(src_file, test_defines) unless src_file.nil?
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Build the test runner (generate if configured to do so)
|
# Build the test runner (generate if configured to do so)
|
||||||
test_base = File.basename(test, C_EXTENSION)
|
test_base = File.basename(test, C_EXTENSION)
|
||||||
|
|
||||||
runner_name = test_base + '_Runner.c'
|
runner_name = test_base + '_Runner.c'
|
||||||
runner_path = ''
|
|
||||||
|
|
||||||
if $cfg['compiler']['runner_path'].nil?
|
runner_path = if $cfg['compiler']['runner_path'].nil?
|
||||||
runner_path = $cfg['compiler']['build_path'] + runner_name
|
$cfg['compiler']['build_path'] + runner_name
|
||||||
else
|
else
|
||||||
runner_path = $cfg['compiler']['runner_path'] + runner_name
|
$cfg['compiler']['runner_path'] + runner_name
|
||||||
end
|
end
|
||||||
|
|
||||||
options = $cfg[:unity]
|
options = $cfg[:unity]
|
||||||
options[:use_param_tests] = (test =~ /parameterized/) ? true : false
|
options[:use_param_tests] = test =~ /parameterized/ ? true : false
|
||||||
UnityTestRunnerGenerator.new(options).run(test, runner_path)
|
UnityTestRunnerGenerator.new(options).run(test, runner_path)
|
||||||
obj_list << compile(runner_path, test_defines)
|
obj_list << compile(runner_path, test_defines)
|
||||||
|
|
||||||
@ -237,21 +241,20 @@ module RakefileHelpers
|
|||||||
# Execute unit test and generate results file
|
# Execute unit test and generate results file
|
||||||
simulator = build_simulator_fields
|
simulator = build_simulator_fields
|
||||||
executable = $cfg['linker']['bin_files']['destination'] + test_base + $cfg['linker']['bin_files']['extension']
|
executable = $cfg['linker']['bin_files']['destination'] + test_base + $cfg['linker']['bin_files']['extension']
|
||||||
if simulator.nil?
|
cmd_str = if simulator.nil?
|
||||||
cmd_str = executable
|
executable
|
||||||
else
|
else
|
||||||
cmd_str = "#{simulator[:command]} #{simulator[:pre_support]} #{executable} #{simulator[:post_support]}"
|
"#{simulator[:command]} #{simulator[:pre_support]} #{executable} #{simulator[:post_support]}"
|
||||||
end
|
end
|
||||||
output = execute(cmd_str)
|
output = execute(cmd_str)
|
||||||
test_results = $cfg['compiler']['build_path'] + test_base
|
test_results = $cfg['compiler']['build_path'] + test_base
|
||||||
if output.match(/OK$/m).nil?
|
if output.match(/OK$/m).nil?
|
||||||
test_results += '.testfail'
|
test_results += '.testfail'
|
||||||
else
|
else
|
||||||
report output if (!$verbose) #verbose already prints this line, as does a failure
|
report output unless $verbose # Verbose already prints this line, as does a failure
|
||||||
test_results += '.testpass'
|
test_results += '.testpass'
|
||||||
end
|
end
|
||||||
File.open(test_results, 'w') { |f| f.print output }
|
File.open(test_results, 'w') { |f| f.print output }
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -36,7 +36,7 @@ compiler:
|
|||||||
- '-Wbad-function-cast'
|
- '-Wbad-function-cast'
|
||||||
- '-fms-extensions'
|
- '-fms-extensions'
|
||||||
- '-fno-omit-frame-pointer'
|
- '-fno-omit-frame-pointer'
|
||||||
- '-ffloat-store'
|
#- '-ffloat-store'
|
||||||
- '-fno-common'
|
- '-fno-common'
|
||||||
- '-fstrict-aliasing'
|
- '-fstrict-aliasing'
|
||||||
- '-std=gnu99'
|
- '-std=gnu99'
|
||||||
@ -55,8 +55,6 @@ compiler:
|
|||||||
- UNITY_INCLUDE_DOUBLE
|
- UNITY_INCLUDE_DOUBLE
|
||||||
- UNITY_SUPPORT_TEST_CASES
|
- UNITY_SUPPORT_TEST_CASES
|
||||||
- UNITY_SUPPORT_64
|
- UNITY_SUPPORT_64
|
||||||
- UNITY_OUTPUT_FLUSH
|
|
||||||
- UNITY_OMIT_OUTPUT_FLUSH_HEADER_DECLARATION
|
|
||||||
object_files:
|
object_files:
|
||||||
prefix: '-o'
|
prefix: '-o'
|
||||||
extension: '.o'
|
extension: '.o'
|
||||||
|
@ -4,6 +4,8 @@
|
|||||||
#include "unity.h"
|
#include "unity.h"
|
||||||
#include "Defs.h"
|
#include "Defs.h"
|
||||||
|
|
||||||
|
TEST_FILE("some_file.c")
|
||||||
|
|
||||||
/* Notes about prefixes:
|
/* Notes about prefixes:
|
||||||
test - normal default prefix. these are "always run" tests for this procedure
|
test - normal default prefix. these are "always run" tests for this procedure
|
||||||
spec - normal default prefix. required to run default setup/teardown calls.
|
spec - normal default prefix. required to run default setup/teardown calls.
|
||||||
|
@ -1170,11 +1170,11 @@ def runner_test(test, runner, expected, test_defines, cmdline_args)
|
|||||||
simulator = build_simulator_fields
|
simulator = build_simulator_fields
|
||||||
cmdline_args ||= ""
|
cmdline_args ||= ""
|
||||||
executable = $cfg['linker']['bin_files']['destination'] + test_base + $cfg['linker']['bin_files']['extension'] + " #{cmdline_args}"
|
executable = $cfg['linker']['bin_files']['destination'] + test_base + $cfg['linker']['bin_files']['extension'] + " #{cmdline_args}"
|
||||||
if simulator.nil?
|
cmd_str = if simulator.nil?
|
||||||
cmd_str = executable
|
executable
|
||||||
else
|
else
|
||||||
cmd_str = "#{simulator[:command]} #{simulator[:pre_support]} #{executable} #{simulator[:post_support]}"
|
"#{simulator[:command]} #{simulator[:pre_support]} #{executable} #{simulator[:post_support]}"
|
||||||
end
|
end
|
||||||
output = execute(cmd_str, true)
|
output = execute(cmd_str, true)
|
||||||
|
|
||||||
#compare to the expected pass/fail
|
#compare to the expected pass/fail
|
||||||
|
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user