summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark VanderVoord <mvandervoord@gmail.com>2023-11-13 17:06:15 -0500
committerGitHub <noreply@github.com>2023-11-13 17:06:15 -0500
commitbf560290f6020737eafaa8b5cbd2177c3956c03f (patch)
tree20804f31674c85b2e86fb352ce7f40ba1db12f78
parent8b0daf153f03ef234386027d30cfa64a37a18d4d (diff)
parenta1b1600e4361cdf98bdb57e7d32a1cafa6eb90bf (diff)
downloadThrowTheSwitch-Unity-bf560290f6020737eafaa8b5cbd2177c3956c03f.tar.gz
Merge pull request #656 from ThrowTheSwitch/platform_matrix
unity 2.6 release candidate
-rw-r--r--.github/workflows/main.yml3
-rw-r--r--LICENSE.txt2
-rw-r--r--README.md14
-rw-r--r--auto/colour_reporter.rb2
-rw-r--r--auto/generate_module.rb36
-rwxr-xr-xauto/generate_test_runner.rb32
-rw-r--r--auto/parse_output.rb38
-rwxr-xr-xauto/stylize_as_junit.rb2
-rw-r--r--auto/test_file_filter.rb1
-rw-r--r--auto/type_sanitizer.rb2
-rw-r--r--auto/unity_test_summary.rb10
-rw-r--r--auto/yaml_helper.rb7
-rw-r--r--docs/UnityChangeLog.md93
-rw-r--r--docs/UnityConfigurationGuide.md11
-rw-r--r--docs/UnityKnownIssues.md13
-rw-r--r--examples/example_3/rakefile_helper.rb35
-rw-r--r--library.json2
-rw-r--r--src/unity.c43
-rw-r--r--src/unity.h4
-rw-r--r--src/unity_internals.h23
-rw-r--r--test/.rubocop.yml10
21 files changed, 262 insertions, 121 deletions
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index fcae2ad..ce948bd 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -15,6 +15,9 @@ jobs:
unit-tests:
name: "Unit Tests"
runs-on: ubuntu-latest
+ strategy:
+ matrix:
+ ruby: ['2.7', '3.0', '3.1', '3.2']
steps:
# Install Ruby Testing Tools
- name: Setup Ruby Testing Tools
diff --git a/LICENSE.txt b/LICENSE.txt
index b9a329d..a541b84 100644
--- a/LICENSE.txt
+++ b/LICENSE.txt
@@ -1,6 +1,6 @@
The MIT License (MIT)
-Copyright (c) <year> 2007-21 Mike Karlesky, Mark VanderVoord, Greg Williams
+Copyright (c) <year> 2007-23 Mike Karlesky, Mark VanderVoord, Greg Williams
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/README.md b/README.md
index b5b723b..71488b3 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
# Unity Test ![CI][]
-__Copyright (c) 2007 - 2021 Unity Project by Mike Karlesky, Mark VanderVoord, and Greg Williams__
+__Copyright (c) 2007 - 2023 Unity Project by Mike Karlesky, Mark VanderVoord, and Greg Williams__
Welcome to the Unity Test Project, one of the main projects of ThrowTheSwitch.org.
Unity Test is a unit testing framework built for C, with a focus on working with embedded toolchains.
@@ -12,6 +12,8 @@ If you'd like to leave the hard work to us, you might be interested in Ceedling,
If you're new to Unity, we encourage you to tour the [getting started guide][].
+You can also find the [change log][] and [known issues][] in our documentation.
+
## Getting Started
The [docs][] folder contains a [getting started guide][] and much more tips about using Unity.
@@ -54,7 +56,7 @@ The message is output stating why.
Compare two integers for equality and display errors as signed integers.
A cast will be performed to your natural integer size so often this can just be used.
-When you need to specify the exact size, like when comparing arrays, you can use a specific version:
+When you need to specify the exact size, you can use a specific version.
TEST_ASSERT_EQUAL_UINT(expected, actual)
TEST_ASSERT_EQUAL_UINT8(expected, actual)
@@ -72,7 +74,8 @@ Like INT, there are variants for different sizes also.
TEST_ASSERT_EQUAL_HEX64(expected, actual)
Compares two integers for equality and display errors as hexadecimal.
-Like the other integer comparisons, you can specify the size... here the size will also effect how many nibbles are shown (for example, `HEX16` will show 4 nibbles).
+Like the other integer comparisons, you can specify the size...
+here the size will also effect how many nibbles are shown (for example, `HEX16` will show 4 nibbles).
TEST_ASSERT_EQUAL(expected, actual)
@@ -214,7 +217,8 @@ Fails if the pointer is equal to NULL
TEST_ASSERT_EQUAL_MEMORY(expected, actual, len)
Compare two blocks of memory.
-This is a good generic assertion for types that can't be coerced into acting like standard types... but since it's a memory compare, you have to be careful that your data types are packed.
+This is a good generic assertion for types that can't be coerced into acting like standard types...
+but since it's a memory compare, you have to be careful that your data types are packed.
### \_MESSAGE
@@ -224,5 +228,7 @@ This is useful for specifying more information about the problem.
[CI]: https://github.com/ThrowTheSwitch/Unity/workflows/CI/badge.svg
[getting started guide]: docs/UnityGettingStartedGuide.md
+[change log]: docs/UnityChangeLog.md
+[known issues]: docs/UnityKnownIssues.md
[docs]: docs/
[UnityAssertionsReference.md]: docs/UnityAssertionsReference.md
diff --git a/auto/colour_reporter.rb b/auto/colour_reporter.rb
index 1c3bc21..b86b76c 100644
--- a/auto/colour_reporter.rb
+++ b/auto/colour_reporter.rb
@@ -12,7 +12,7 @@ def report(message)
if !$colour_output
$stdout.puts(message)
else
- message = message.join('\n') if message.class == Array
+ message = message.join('\n') if message.instance_of?(Array)
message.each_line do |line|
line.chomp!
colour = case line
diff --git a/auto/generate_module.rb b/auto/generate_module.rb
index 7151586..7b33c72 100644
--- a/auto/generate_module.rb
+++ b/auto/generate_module.rb
@@ -13,7 +13,7 @@ require 'fileutils'
require 'pathname'
# TEMPLATE_TST
-TEMPLATE_TST ||= '#ifdef TEST
+TEMPLATE_TST ||= '#ifdef %5$s
#include "unity.h"
@@ -32,7 +32,7 @@ void test_%4$s_NeedToImplement(void)
TEST_IGNORE_MESSAGE("Need to Implement %1$s");
}
-#endif // TEST
+#endif // %5$s
'.freeze
# TEMPLATE_SRC
@@ -108,7 +108,8 @@ class UnityModuleGenerator
update_svn: false,
boilerplates: {},
test_prefix: 'Test',
- mock_prefix: 'Mock'
+ mock_prefix: 'Mock',
+ test_define: 'TEST'
}
end
@@ -132,9 +133,9 @@ class UnityModuleGenerator
# create triad definition
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: '.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], test_define: @options[:test_define] }]
# prepare the pattern for use
pattern = (pattern || @options[:pattern] || 'src').downcase
@@ -154,6 +155,7 @@ class UnityModuleGenerator
path: (Pathname.new("#{cfg[:path]}#{subfolder}") + filename).cleanpath,
name: submodule_name,
template: cfg[:template],
+ test_define: cfg[:test_define],
boilerplate: cfg[:boilerplate],
includes: case (cfg[:inc])
when :src then (@options[:includes][:src] || []) | (pattern_traits[:inc].map { |f| format(f, module_name) })
@@ -168,18 +170,19 @@ class UnityModuleGenerator
end
############################
- def neutralize_filename(name, start_cap = true)
+ def neutralize_filename(name, start_cap: true)
return name if name.empty?
+
name = name.split(/(?:\s+|_|(?=[A-Z][a-z]))|(?<=[a-z])(?=[A-Z])/).map(&:capitalize).join('_')
- name = name[0].downcase + name[1..-1] unless start_cap
+ name = name[0].downcase + name[1..] unless start_cap
name
end
############################
def create_filename(part1, part2 = '')
- name = part2.empty? ? part1 : part1 + '_' + part2
+ name = part2.empty? ? part1 : "#{part1}_#{part2}"
case (@options[:naming])
- when 'bumpy' then neutralize_filename(name, false).delete('_')
+ when 'bumpy' then neutralize_filename(name, start_cap: false).delete('_')
when 'camel' then neutralize_filename(name).delete('_')
when 'snake' then neutralize_filename(name).downcase
when 'caps' then neutralize_filename(name).upcase
@@ -212,7 +215,8 @@ class UnityModuleGenerator
f.write(file[:template] % [file[:name],
file[:includes].map { |ff| "#include \"#{ff}\"\n" }.join,
file[:name].upcase.tr('-', '_'),
- file[:name].tr('-', '_')])
+ file[:name].tr('-', '_'),
+ file[:test_define]])
end
if @options[:update_svn]
`svn add \"#{file[:path]}\"`
@@ -260,12 +264,12 @@ if $0 == __FILE__
case arg
when /^-d/ then destroy = true
when /^-u/ then options[:update_svn] = true
- when /^-p\"?(\w+)\"?/ then options[:pattern] = Regexp.last_match(1)
- when /^-s\"?(.+)\"?/ then options[:path_src] = Regexp.last_match(1)
- when /^-i\"?(.+)\"?/ then options[:path_inc] = Regexp.last_match(1)
- when /^-t\"?(.+)\"?/ then options[:path_tst] = Regexp.last_match(1)
- when /^-n\"?(.+)\"?/ then options[:naming] = Regexp.last_match(1)
- when /^-y\"?(.+)\"?/ then options = UnityModuleGenerator.grab_config(Regexp.last_match(1))
+ when /^-p"?(\w+)"?/ then options[:pattern] = Regexp.last_match(1)
+ when /^-s"?(.+)"?/ then options[:path_src] = Regexp.last_match(1)
+ when /^-i"?(.+)"?/ then options[:path_inc] = Regexp.last_match(1)
+ when /^-t"?(.+)"?/ then options[:path_tst] = Regexp.last_match(1)
+ when /^-n"?(.+)"?/ then options[:naming] = Regexp.last_match(1)
+ when /^-y"?(.+)"?/ then options = UnityModuleGenerator.grab_config(Regexp.last_match(1))
when /^(\w+)/
raise "ERROR: You can't have more than one Module name specified!" unless module_name.nil?
diff --git a/auto/generate_test_runner.rb b/auto/generate_test_runner.rb
index 69f3ff5..057c02f 100755
--- a/auto/generate_test_runner.rb
+++ b/auto/generate_test_runner.rb
@@ -45,6 +45,7 @@ class UnityTestRunnerGenerator
cmdline_args: false,
omit_begin_end: false,
use_param_tests: false,
+ use_system_files: true,
include_extensions: '(?:hpp|hh|H|h)',
source_extensions: '(?:cpp|cc|ino|C|c)'
}
@@ -69,7 +70,7 @@ class UnityTestRunnerGenerator
source = source.force_encoding('ISO-8859-1').encode('utf-8', replace: nil)
tests = find_tests(source)
headers = find_includes(source)
- testfile_includes = (headers[:local] + headers[:system])
+ testfile_includes = @options[:use_system_files] ? (headers[:local] + headers[:system]) : (headers[:local])
used_mocks = find_mocks(testfile_includes)
testfile_includes = (testfile_includes - used_mocks)
testfile_includes.delete_if { |inc| inc =~ /(unity|cmock)/ }
@@ -80,7 +81,7 @@ class UnityTestRunnerGenerator
# determine which files were used to return them
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 += headers[:linkonly] unless headers[:linkonly].empty?
all_files_used.uniq
@@ -144,12 +145,12 @@ class UnityTestRunnerGenerator
if @options[:use_param_tests] && !arguments.empty?
args = []
type_and_args = arguments.split(/TEST_(CASE|RANGE|MATRIX)/)
- for i in (1...type_and_args.length).step(2)
+ (1...type_and_args.length).step(2).each do |i|
case type_and_args[i]
- when "CASE"
+ when 'CASE'
args << type_and_args[i + 1].sub(/^\s*\(\s*(.*?)\s*\)\s*$/m, '\1')
- when "RANGE"
+ when 'RANGE'
args += type_and_args[i + 1].scan(/(\[|<)\s*(-?\d+.?\d*)\s*,\s*(-?\d+.?\d*)\s*,\s*(-?\d+.?\d*)\s*(\]|>)/m).map do |arg_values_str|
exclude_end = arg_values_str[0] == '<' && arg_values_str[-1] == '>'
arg_values_str[1...-1].map do |arg_value_str|
@@ -163,13 +164,13 @@ class UnityTestRunnerGenerator
arg_combinations.flatten.join(', ')
end
- when "MATRIX"
- single_arg_regex_string = /(?:(?:"(?:\\"|[^\\])*?")+|(?:'\\?.')+|(?:[^\s\]\["'\,]|\[[\d\S_-]+\])+)/.source
+ when 'MATRIX'
+ single_arg_regex_string = /(?:(?:"(?:\\"|[^\\])*?")+|(?:'\\?.')+|(?:[^\s\]\["',]|\[[\d\S_-]+\])+)/.source
args_regex = /\[((?:\s*#{single_arg_regex_string}\s*,?)*(?:\s*#{single_arg_regex_string})?\s*)\]/m
arg_elements_regex = /\s*(#{single_arg_regex_string})\s*,\s*/m
args += type_and_args[i + 1].scan(args_regex).flatten.map do |arg_values_str|
- (arg_values_str + ',').scan(arg_elements_regex)
+ ("#{arg_values_str},").scan(arg_elements_regex)
end.reduce do |result, arg_range_expanded|
result.product(arg_range_expanded)
end.map do |arg_combinations|
@@ -188,7 +189,7 @@ class UnityTestRunnerGenerator
source_lines = source.split("\n")
source_index = 0
tests_and_line_numbers.size.times do |i|
- source_lines[source_index..-1].each_with_index do |line, index|
+ source_lines[source_index..].each_with_index do |line, index|
next unless line =~ /\s+#{tests_and_line_numbers[i][:test]}(?:\s|\()/
source_index += index
@@ -207,12 +208,11 @@ class UnityTestRunnerGenerator
source.gsub!(/\/\/.*$/, '') # remove line comments (all that remain)
# parse out includes
- includes = {
- local: source.scan(/^\s*#include\s+\"\s*(.+\.#{@options[:include_extensions]})\s*\"/).flatten,
+ {
+ local: source.scan(/^\s*#include\s+"\s*(.+\.#{@options[:include_extensions]})\s*"/).flatten,
system: source.scan(/^\s*#include\s+<\s*(.+)\s*>/).flatten.map { |inc| "<#{inc}>" },
- linkonly: source.scan(/^TEST_SOURCE_FILE\(\s*\"\s*(.+\.#{@options[:source_extensions]})\s*\"/).flatten
+ linkonly: source.scan(/^TEST_SOURCE_FILE\(\s*"\s*(.+\.#{@options[:source_extensions]})\s*"/).flatten
}
- includes
end
def find_mocks(includes)
@@ -369,7 +369,7 @@ class UnityTestRunnerGenerator
require 'erb'
file = File.read(File.join(__dir__, 'run_test.erb'))
template = ERB.new(file, trim_mode: '<>')
- output.puts("\n" + template.result(binding))
+ output.puts("\n#{template.result(binding)}")
end
def create_args_wrappers(output, tests)
@@ -459,7 +459,7 @@ class UnityTestRunnerGenerator
end
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("#ifndef _#{filename}")
output.puts("#define _#{filename}\n\n")
@@ -498,7 +498,7 @@ if $0 == __FILE__
when /\.*\.ya?ml$/
options = UnityTestRunnerGenerator.grab_config(arg)
true
- when /--(\w+)=\"?(.*)\"?/
+ when /--(\w+)="?(.*)"?/
options[Regexp.last_match(1).to_sym] = Regexp.last_match(2)
true
when /\.*\.(?:hpp|hh|H|h)$/
diff --git a/auto/parse_output.rb b/auto/parse_output.rb
index 864104b..aa306e2 100644
--- a/auto/parse_output.rb
+++ b/auto/parse_output.rb
@@ -56,7 +56,7 @@ class ParseOutput
# Set the flag to indicate if there will be an XML output file or not
def test_suite_name=(cli_arg)
@real_test_suite_name = cli_arg
- puts 'Real test suite name will be \'' + @real_test_suite_name + '\''
+ puts "Real test suite name will be '#{@real_test_suite_name}'"
end
def xml_encode_s(str)
@@ -75,7 +75,7 @@ class ParseOutput
# Pushes the suite info as xml to the array list, which will be written later
def push_xml_output_suite_info
# Insert opening tag at front
- heading = '<testsuite name=' + xml_encode_s(@real_test_suite_name) + ' tests="' + @total_tests.to_s + '" failures="' + @test_failed.to_s + '"' + ' skips="' + @test_ignored.to_s + '">'
+ heading = "<testsuite name=#{xml_encode_s(@real_test_suite_name)} tests=\"#{@total_tests}\" failures=\"#{@test_failed}\" skips=\"#{@test_ignored}\">"
@array_list.insert(0, heading)
# Push back the closing tag
@array_list.push '</testsuite>'
@@ -83,20 +83,20 @@ class ParseOutput
# Pushes xml output data to the array list, which will be written later
def push_xml_output_passed(test_name, execution_time = 0)
- @array_list.push ' <testcase classname=' + xml_encode_s(@test_suite) + ' name=' + xml_encode_s(test_name) + ' time=' + xml_encode_s((execution_time / 1000.0).to_s) + ' />'
+ @array_list.push " <testcase classname=#{xml_encode_s(@test_suite)} name=#{xml_encode_s(test_name)} time=#{xml_encode_s((execution_time / 1000.0).to_s)} />"
end
# Pushes xml output data to the array list, which will be written later
def push_xml_output_failed(test_name, reason, execution_time = 0)
- @array_list.push ' <testcase classname=' + xml_encode_s(@test_suite) + ' name=' + xml_encode_s(test_name) + ' time=' + xml_encode_s((execution_time / 1000.0).to_s) + '>'
- @array_list.push ' <failure type="ASSERT FAILED">' + reason + '</failure>'
+ @array_list.push " <testcase classname=#{xml_encode_s(@test_suite)} name=#{xml_encode_s(test_name)} time=#{xml_encode_s((execution_time / 1000.0).to_s)} >"
+ @array_list.push " <failure type=\"ASSERT FAILED\">#{reason}</failure>"
@array_list.push ' </testcase>'
end
# Pushes xml output data to the array list, which will be written later
def push_xml_output_ignored(test_name, reason, execution_time = 0)
- @array_list.push ' <testcase classname=' + xml_encode_s(@test_suite) + ' name=' + xml_encode_s(test_name) + ' time=' + xml_encode_s((execution_time / 1000.0).to_s) + '>'
- @array_list.push ' <skipped type="TEST IGNORED">' + reason + '</skipped>'
+ @array_list.push " <testcase classname=#{xml_encode_s(@test_suite)} name=#{xml_encode_s(test_name)} time=#{xml_encode_s((execution_time / 1000.0).to_s)} >"
+ @array_list.push " <skipped type=\"TEST IGNORED\">#{reason}</skipped>"
@array_list.push ' </testcase>'
end
@@ -144,7 +144,7 @@ class ParseOutput
test_name = array[1]
test_suite_verify(class_name)
reason_array = array[2].split(':')
- reason = reason_array[-1].lstrip.chomp + ' at line: ' + reason_array[-4]
+ reason = "#{reason_array[-1].lstrip.chomp} at line: #{reason_array[-4]}"
printf "%-40s FAILED\n", test_name
@@ -189,12 +189,12 @@ class ParseOutput
def test_failed(array)
# ':' symbol will be valid in function args now
real_method_name = array[@result_usual_idx - 1..-3].join(':')
- array = array[0..@result_usual_idx - 3] + [real_method_name] + array[-2..-1]
+ array = array[0..@result_usual_idx - 3] + [real_method_name] + array[-2..]
last_item = array.length - 1
test_time = get_test_time(array[last_item])
test_name = array[last_item - 2]
- reason = array[last_item].chomp.lstrip + ' at line: ' + array[last_item - 3]
+ reason = "#{array[last_item].chomp.lstrip} at line: #{array[last_item - 3]}"
class_name = array[@class_name_idx]
if test_name.start_with? 'TEST('
@@ -217,7 +217,7 @@ class ParseOutput
def test_ignored(array)
# ':' symbol will be valid in function args now
real_method_name = array[@result_usual_idx - 1..-3].join(':')
- array = array[0..@result_usual_idx - 3] + [real_method_name] + array[-2..-1]
+ array = array[0..@result_usual_idx - 3] + [real_method_name] + array[-2..]
last_item = array.length - 1
test_time = get_test_time(array[last_item])
@@ -268,7 +268,7 @@ class ParseOutput
def process(file_name)
@array_list = []
- puts 'Parsing file: ' + file_name
+ puts "Parsing file: #{file_name}"
@test_passed = 0
@test_failed = 0
@@ -333,17 +333,17 @@ class ParseOutput
@test_ignored += 1
elsif line_array.size >= 4
# We will check output from color compilation
- if line_array[@result_usual_idx..-1].any? { |l| l.include? 'PASS' }
+ if line_array[@result_usual_idx..].any? { |l| l.include? 'PASS' }
test_passed(line_array)
@test_passed += 1
- elsif line_array[@result_usual_idx..-1].any? { |l| l.include? 'FAIL' }
+ elsif line_array[@result_usual_idx..].any? { |l| l.include? 'FAIL' }
test_failed(line_array)
@test_failed += 1
elsif line_array[@result_usual_idx..-2].any? { |l| l.include? 'IGNORE' }
test_ignored(line_array)
@test_ignored += 1
- elsif line_array[@result_usual_idx..-1].any? { |l| l.include? 'IGNORE' }
- line_array.push('No reason given (' + get_test_time(line_array[@result_usual_idx..-1]).to_s + ' ms)')
+ elsif line_array[@result_usual_idx..].any? { |l| l.include? 'IGNORE' }
+ line_array.push("No reason given (#{get_test_time(line_array[@result_usual_idx..])} ms)")
test_ignored(line_array)
@test_ignored += 1
end
@@ -353,9 +353,9 @@ class ParseOutput
puts ''
puts '=================== SUMMARY ====================='
puts ''
- puts 'Tests Passed : ' + @test_passed.to_s
- puts 'Tests Failed : ' + @test_failed.to_s
- puts 'Tests Ignored : ' + @test_ignored.to_s
+ puts "Tests Passed : #{@test_passed}"
+ puts "Tests Failed : #{@test_failed}"
+ puts "Tests Ignored : #{@test_ignored}"
return unless @xml_out
diff --git a/auto/stylize_as_junit.rb b/auto/stylize_as_junit.rb
index e01f791..e4b911e 100755
--- a/auto/stylize_as_junit.rb
+++ b/auto/stylize_as_junit.rb
@@ -99,7 +99,7 @@ class UnityToJUnit
test_file = if test_file_str.length < 2
result_file
else
- test_file_str[0] + ':' + test_file_str[1]
+ "#{test_file_str[0]}:#{test_file_str[1]}"
end
result_output[:source][:path] = File.dirname(test_file)
result_output[:source][:file] = File.basename(test_file)
diff --git a/auto/test_file_filter.rb b/auto/test_file_filter.rb
index 3cc32de..f4834a1 100644
--- a/auto/test_file_filter.rb
+++ b/auto/test_file_filter.rb
@@ -15,6 +15,7 @@ module RakefileHelpers
file = 'test_file_filter.yml'
return unless File.exist?(file)
+
filters = YamlHelper.load_file(file)
@all_files = filters[:all_files]
@only_files = filters[:only_files]
diff --git a/auto/type_sanitizer.rb b/auto/type_sanitizer.rb
index dafb882..3d1db09 100644
--- a/auto/type_sanitizer.rb
+++ b/auto/type_sanitizer.rb
@@ -1,6 +1,6 @@
module TypeSanitizer
def self.sanitize_c_identifier(unsanitized)
# convert filename to valid C identifier by replacing invalid chars with '_'
- unsanitized.gsub(/[-\/\\\.\,\s]/, '_')
+ unsanitized.gsub(/[-\/\\.,\s]/, '_')
end
end
diff --git a/auto/unity_test_summary.rb b/auto/unity_test_summary.rb
index b3fe8a6..03d67a6 100644
--- a/auto/unity_test_summary.rb
+++ b/auto/unity_test_summary.rb
@@ -86,7 +86,11 @@ class UnityTestSummary
def get_details(_result_file, lines)
results = { failures: [], ignores: [], successes: [] }
lines.each do |line|
- _src_file, _src_line, _test_name, status, _msg = line.split(/:/)
+ status_match = line.match(/^[^:]+:[^:]+:\w+(?:\([^)]*\))?:([^:]+):?/)
+ next unless status_match
+
+ status = status_match.captures[0]
+
line_out = (@root && (@root != 0) ? "#{@root}#{line}" : line).gsub(/\//, '\\')
case status
when 'IGNORE' then results[:ignores] << line_out
@@ -108,7 +112,7 @@ if $0 == __FILE__
# parse out the command options
opts, args = ARGV.partition { |v| v =~ /^--\w+/ }
- opts.map! { |v| v[2..-1].to_sym }
+ opts.map! { |v| v[2..].to_sym }
# create an instance to work with
uts = UnityTestSummary.new(opts)
@@ -124,7 +128,7 @@ if $0 == __FILE__
uts.targets = results
# set the root path
- args[1] ||= Dir.pwd + '/'
+ args[1] ||= "#{Dir.pwd}/"
uts.root = ARGV[1]
# run the summarizer
diff --git a/auto/yaml_helper.rb b/auto/yaml_helper.rb
index e5a0865..3296ba0 100644
--- a/auto/yaml_helper.rb
+++ b/auto/yaml_helper.rb
@@ -8,8 +8,11 @@ require 'yaml'
module YamlHelper
def self.load(body)
- YAML.respond_to?(:unsafe_load) ?
- YAML.unsafe_load(body) : YAML.load(body)
+ if YAML.respond_to?(:unsafe_load)
+ YAML.unsafe_load(body)
+ else
+ YAML.load(body)
+ end
end
def self.load_file(file)
diff --git a/docs/UnityChangeLog.md b/docs/UnityChangeLog.md
new file mode 100644
index 0000000..9c3bb7b
--- /dev/null
+++ b/docs/UnityChangeLog.md
@@ -0,0 +1,93 @@
+# Unity Test - Change Log
+
+## A Note
+
+This document captures significant features and fixes to the Unity project core source files
+and scripts. More detail can be found in the history on Github.
+
+This project is now tracking changes in more detail. Previous releases get less detailed as
+we move back in histroy.
+
+Prior to 2012, the project was hosted on SourceForge.net
+Prior to 2008, the project was an internal project and not released to the public.
+
+## Log
+
+### Unity 2.6.0 ()
+
+New Features:
+
+ - Fill out missing variations of arrays, within, etc.
+ - Add `TEST_PRINTF()`
+ - Add `TEST_MATRIX()` and `TEST_RANGE()` options and documentation
+ - Add support for searching `TEST_SOURCE_FILE()` for determining test dependencies
+ - Add Unity BDD plugin
+ - Add `UNITY_INCLUDE_EXEC_TIME` option to report test times
+ - Allow user to override test abort underlying mechanism
+
+Significant Bugfixes:
+
+ - More portable validation of NaN and Infinity. Added `UNITY_IS_NAN` and `UNITY_IS_INF` options
+ - Add `UNITY_PROGMEM` configuration option
+ - Fix overflow detection of hex values when using arrays
+ - Fix scripts broken by Ruby standard changes
+
+Other:
+
+ - Avoid pointer comparison when one is null to avoid compiler warnings
+ - Significant improvements to documentation
+ - Updates to match latest Ruby style specification
+ - Meson, CMake, PlatformIO builds
+
+### Unity 2.5.2 (January 2021)
+
+ - improvements to RUN_TEST macro and generated RUN_TEST
+ - Fix `UNITY_TEST_ASSERT_BIT(S)_HIGH`
+ - Cleaner handling of details tracking by CMock
+
+### Unity 2.5.1 (May 2020)
+
+Mostly a bugfix and stability release.
+Bonus Features:
+
+ - Optional TEST_PRINTF macro
+ - Improve self-testing procedures.
+
+### Unity 2.5.0 (October 2019)
+
+It's been a LONG time since the last release of Unity. Finally, here it is!
+There are too many updates to list here, so some highlights:
+
+ - more standards compliant (without giving up on supporting ALL compilers, no matter how quirky)
+ - many more specialized assertions for better test feedback
+ - more examples for integrating into your world
+ - many many bugfixes and tweaks
+
+### Unity 2.4.3 (November 2017)
+
+ - Allow suiteSetUp() and suiteTearDown() to be povided as normal C functions
+ - Fix & Expand Greater Than / Less Than assertions for integers
+ - Built-in option to colorize test results
+ - Documentation updates
+
+### Unity 2.4.2 (September 2017)
+
+ - Fixed bug in UNTY_TEST_ASSERT_EACH_EQUAL_*
+ - Added TEST_ASSERT_GREATER_THAN and TEST_ASSERT_LESS_THAN
+ - Updated Module Generator to stop changing names when no style given
+ - Cleanup to custom float printing for accuracy
+ - Cleanup incorrect line numbers are partial name matching
+ - Reduce warnings from using popular function names as variable names
+
+### Unity 2.4.1 (April 2017)
+
+ - test runner generator can inject defines as well as headers
+ - added a built-in floating point print routine instead of relying on printf
+ - updated to new coding and naming standard
+ - updated documentation to be markdown instead of pdf
+ - fixed many many little bugs, most of which were supplied by the community (you people are awesome!)
+ - coding standard actually enforced in CI
+
+### Unity 2.4.0 (October, 2016)
+
+ - port from SourceForge and numerous bugfixes
diff --git a/docs/UnityConfigurationGuide.md b/docs/UnityConfigurationGuide.md
index e56b4a4..953851f 100644
--- a/docs/UnityConfigurationGuide.md
+++ b/docs/UnityConfigurationGuide.md
@@ -222,6 +222,17 @@ _Example:_
#define UNITY_FLOAT_PRECISION 0.001f
```
+#### `UNITY_IS_NAN` and `UNITY_IS_INF`
+
+If your toolchain defines `isnan` and `isinf` in `math.h` as macros, nothing needs to be done. If your toolchain doesn't define these, Unity
+will create these macros itself. You may override either or both of these defines to specify how you want to evaluate if a number is NaN or Infinity.
+
+_Example:_
+
+```C
+#define UNITY_IS_NAN(n) ((n != n) ? 1 : 0)
+```
+
### Miscellaneous
#### `UNITY_EXCLUDE_STDDEF_H`
diff --git a/docs/UnityKnownIssues.md b/docs/UnityKnownIssues.md
new file mode 100644
index 0000000..3449319
--- /dev/null
+++ b/docs/UnityKnownIssues.md
@@ -0,0 +1,13 @@
+# Unity Test - Known Issues
+
+## A Note
+
+This project will do its best to keep track of significant bugs that might effect your usage of this
+project and its supporting scripts. A more detailed and up-to-date list for cutting edge Unity can
+be found on our Github repository.
+
+## Issues
+
+ - No built-in validation of no-return functions
+ - Incomplete support for Printf-style formatting
+ - Incomplete support for VarArgs
diff --git a/examples/example_3/rakefile_helper.rb b/examples/example_3/rakefile_helper.rb
index 4906075..cbc4549 100644
--- a/examples/example_3/rakefile_helper.rb
+++ b/examples/example_3/rakefile_helper.rb
@@ -17,7 +17,7 @@ def load_configuration(config_file)
end
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
def configure_toolchain(config_file = DEFAULT_CONFIG_FILE)
@@ -27,7 +27,7 @@ def configure_toolchain(config_file = DEFAULT_CONFIG_FILE)
end
def unit_test_files
- path = $cfg['compiler']['unit_tests_path'] + 'Test*' + C_EXTENSION
+ path = "#{$cfg['compiler']['unit_tests_path']}Test*#{C_EXTENSION}"
path.tr!('\\', '/')
FileList.new(path)
end
@@ -42,7 +42,7 @@ def extract_headers(filename)
includes = []
lines = File.readlines(filename)
lines.each do |line|
- m = line.match(/^\s*#include\s+\"\s*(.+\.[hH])\s*\"/)
+ m = line.match(/^\s*#include\s+"\s*(.+\.[hH])\s*"/)
includes << m[1] unless m.nil?
end
includes
@@ -57,12 +57,11 @@ def find_source_file(header, paths)
end
def tackit(strings)
- result = if strings.is_a?(Array)
- "\"#{strings.join}\""
- else
- strings
- end
- result
+ if strings.is_a?(Array)
+ "\"#{strings.join}\""
+ else
+ strings
+ end
end
def squash(prefix, items)
@@ -80,7 +79,7 @@ def build_compiler_fields
end
options = squash('', $cfg['compiler']['options'])
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)
{ command: command, defines: defines, options: options, includes: includes }
end
@@ -105,18 +104,18 @@ def build_linker_fields
''
else
squash($cfg['linker']['includes']['prefix'], $cfg['linker']['includes']['items'])
- end.gsub(/\\ /, ' ').gsub(/\\\"/, '"').gsub(/\\$/, '') # Remove trailing slashes (for IAR)
+ end.gsub(/\\ /, ' ').gsub(/\\"/, '"').gsub(/\\$/, '') # Remove trailing slashes (for IAR)
{ command: command, options: options, includes: includes }
end
def link_it(exe_name, obj_list)
linker = build_linker_fields
- cmd_str = "#{linker[:command]}#{linker[:options]}#{linker[:includes]} " +
- (obj_list.map { |obj| "#{$cfg['linker']['object_files']['path']}#{obj} " }).join +
- $cfg['linker']['bin_files']['prefix'] + ' ' +
- $cfg['linker']['bin_files']['destination'] +
- exe_name + $cfg['linker']['bin_files']['extension']
+ cmd_str = "#{linker[:command]}#{linker[:options]}#{linker[:includes]}"
+ cmd_str += " #{(obj_list.map { |obj| "#{$cfg['linker']['object_files']['path']}#{obj}" }).join(' ')}"
+ cmd_str += " #{$cfg['linker']['bin_files']['prefix']} "
+ cmd_str += $cfg['linker']['bin_files']['destination']
+ cmd_str += exe_name + $cfg['linker']['bin_files']['extension']
execute(cmd_str)
end
@@ -126,7 +125,7 @@ def build_simulator_fields
command = if $cfg['simulator']['path'].nil?
''
else
- (tackit($cfg['simulator']['path']) + ' ')
+ "#{tackit($cfg['simulator']['path'])} "
end
pre_support = if $cfg['simulator']['pre_support'].nil?
''
@@ -189,7 +188,7 @@ def run_tests(test_files)
# Build the test runner (generate if configured to do so)
test_base = File.basename(test, C_EXTENSION)
- runner_name = test_base + '_Runner.c'
+ runner_name = "#{test_base}_Runner.c"
if $cfg['compiler']['runner_path'].nil?
runner_path = $cfg['compiler']['build_path'] + runner_name
test_gen = UnityTestRunnerGenerator.new($cfg_file)
diff --git a/library.json b/library.json
index b571294..914f5f6 100644
--- a/library.json
+++ b/library.json
@@ -1,6 +1,6 @@
{
"name": "Unity",
- "version": "2.5.2",
+ "version": "2.6.0",
"keywords": "unit-testing, testing, tdd, testing-framework",
"description": "Simple Unit Testing for C",
"homepage": "http://www.throwtheswitch.org/unity",
diff --git a/src/unity.c b/src/unity.c
index e455f57..cc2e5ce 100644
--- a/src/unity.c
+++ b/src/unity.c
@@ -356,11 +356,11 @@ void UnityPrintFloat(const UNITY_DOUBLE input_number)
{
UnityPrint("0");
}
- else if (isnan(number))
+ else if (UNITY_IS_NAN(number))
{
UnityPrint("nan");
}
- else if (isinf(number))
+ else if (UNITY_IS_INF(number))
{
UnityPrint("inf");
}
@@ -895,15 +895,15 @@ void UnityAssertEqualIntArray(UNITY_INTERNAL_PTR expected,
#ifndef UNITY_EXCLUDE_FLOAT
/* Wrap this define in a function with variable types as float or double */
#define UNITY_FLOAT_OR_DOUBLE_WITHIN(delta, expected, actual, diff) \
- if (isinf(expected) && isinf(actual) && (((expected) < 0) == ((actual) < 0))) return 1; \
+ if (UNITY_IS_INF(expected) && UNITY_IS_INF(actual) && (((expected) < 0) == ((actual) < 0))) return 1; \
if (UNITY_NAN_CHECK) return 1; \
(diff) = (actual) - (expected); \
if ((diff) < 0) (diff) = -(diff); \
if ((delta) < 0) (delta) = -(delta); \
- return !(isnan(diff) || isinf(diff) || ((diff) > (delta)))
+ return !(UNITY_IS_NAN(diff) || UNITY_IS_INF(diff) || ((diff) > (delta)))
/* This first part of this condition will catch any NaN or Infinite values */
#ifndef UNITY_NAN_NOT_EQUAL_NAN
- #define UNITY_NAN_CHECK isnan(expected) && isnan(actual)
+ #define UNITY_NAN_CHECK UNITY_IS_NAN(expected) && UNITY_IS_NAN(actual)
#else
#define UNITY_NAN_CHECK 0
#endif
@@ -954,12 +954,12 @@ void UnityAssertWithinFloatArray(const UNITY_FLOAT delta,
#endif
}
- if (isinf(in_delta))
+ if (UNITY_IS_INF(in_delta))
{
return; /* Arrays will be force equal with infinite delta */
}
- if (isnan(in_delta))
+ if (UNITY_IS_NAN(in_delta))
{
/* Delta must be correct number */
UnityPrintPointlessAndBail();
@@ -1098,21 +1098,21 @@ void UnityAssertFloatSpecial(const UNITY_FLOAT actual,
{
case UNITY_FLOAT_IS_INF:
case UNITY_FLOAT_IS_NOT_INF:
- is_trait = isinf(actual) && (actual > 0);
+ is_trait = UNITY_IS_INF(actual) && (actual > 0);
break;
case UNITY_FLOAT_IS_NEG_INF:
case UNITY_FLOAT_IS_NOT_NEG_INF:
- is_trait = isinf(actual) && (actual < 0);
+ is_trait = UNITY_IS_INF(actual) && (actual < 0);
break;
case UNITY_FLOAT_IS_NAN:
case UNITY_FLOAT_IS_NOT_NAN:
- is_trait = isnan(actual) ? 1 : 0;
+ is_trait = UNITY_IS_NAN(actual) ? 1 : 0;
break;
case UNITY_FLOAT_IS_DET: /* A determinate number is non infinite and not NaN. */
case UNITY_FLOAT_IS_NOT_DET:
- is_trait = !isinf(actual) && !isnan(actual);
+ is_trait = !UNITY_IS_INF(actual) && !UNITY_IS_NAN(actual);
break;
case UNITY_FLOAT_INVALID_TRAIT: /* Supress warning */
@@ -1182,12 +1182,12 @@ void UnityAssertWithinDoubleArray(const UNITY_DOUBLE delta,
#endif
}
- if (isinf(in_delta))
+ if (UNITY_IS_INF(in_delta))
{
return; /* Arrays will be force equal with infinite delta */
}
- if (isnan(in_delta))
+ if (UNITY_IS_NAN(in_delta))
{
/* Delta must be correct number */
UnityPrintPointlessAndBail();
@@ -1325,21 +1325,21 @@ void UnityAssertDoubleSpecial(const UNITY_DOUBLE actual,
{
case UNITY_FLOAT_IS_INF:
case UNITY_FLOAT_IS_NOT_INF:
- is_trait = isinf(actual) && (actual > 0);
+ is_trait = UNITY_IS_INF(actual) && (actual > 0);
break;
case UNITY_FLOAT_IS_NEG_INF:
case UNITY_FLOAT_IS_NOT_NEG_INF:
- is_trait = isinf(actual) && (actual < 0);
+ is_trait = UNITY_IS_INF(actual) && (actual < 0);
break;
case UNITY_FLOAT_IS_NAN:
case UNITY_FLOAT_IS_NOT_NAN:
- is_trait = isnan(actual) ? 1 : 0;
+ is_trait = UNITY_IS_NAN(actual) ? 1 : 0;
break;
case UNITY_FLOAT_IS_DET: /* A determinate number is non infinite and not NaN. */
case UNITY_FLOAT_IS_NOT_DET:
- is_trait = !isinf(actual) && !isnan(actual);
+ is_trait = !UNITY_IS_INF(actual) && !UNITY_IS_NAN(actual);
break;
case UNITY_FLOAT_INVALID_TRAIT: /* Supress warning */
@@ -2031,14 +2031,7 @@ static void UnityPrintFVA(const char* format, va_list va)
UNITY_EXTRACT_ARG(UNITY_UINT, number, length_mod, va, unsigned int);
UNITY_OUTPUT_CHAR('0');
UNITY_OUTPUT_CHAR('x');
- if (length_mod == UNITY_LENGTH_MODIFIER_LONG_LONG)
- {
- UnityPrintNumberHex(number, 16);
- }
- else
- {
- UnityPrintNumberHex(number, 8);
- }
+ UnityPrintNumberHex(number, UNITY_MAX_NIBBLES);
break;
}
case 'p':
diff --git a/src/unity.h b/src/unity.h
index 2785c72..265e548 100644
--- a/src/unity.h
+++ b/src/unity.h
@@ -9,8 +9,8 @@
#define UNITY
#define UNITY_VERSION_MAJOR 2
-#define UNITY_VERSION_MINOR 5
-#define UNITY_VERSION_BUILD 4
+#define UNITY_VERSION_MINOR 6
+#define UNITY_VERSION_BUILD 0
#define UNITY_VERSION ((UNITY_VERSION_MAJOR << 16) | (UNITY_VERSION_MINOR << 8) | UNITY_VERSION_BUILD)
#ifdef __cplusplus
diff --git a/src/unity_internals.h b/src/unity_internals.h
index 11d9abb..65938ff 100644
--- a/src/unity_internals.h
+++ b/src/unity_internals.h
@@ -241,16 +241,25 @@
#endif
typedef UNITY_FLOAT_TYPE UNITY_FLOAT;
-/* isinf & isnan macros should be provided by math.h */
-#ifndef isinf
-/* The value of Inf - Inf is NaN */
-#define isinf(n) (isnan((n) - (n)) && !isnan(n))
-#endif
-
+/* isnan macro should be provided by math.h. Override if not macro */
+#ifndef UNITY_IS_NAN
#ifndef isnan
/* NaN is the only floating point value that does NOT equal itself.
* Therefore if n != n, then it is NaN. */
-#define isnan(n) ((n != n) ? 1 : 0)
+#define UNITY_IS_NAN(n) ((n != n) ? 1 : 0)
+#else
+#define UNITY_IS_NAN(n) isnan(n)
+#endif
+#endif
+
+/* isinf macro should be provided by math.h. Override if not macro */
+#ifndef UNITY_IS_INF
+#ifndef isinf
+/* The value of Inf - Inf is NaN */
+#define UNITY_IS_INF(n) (UNITY_IS_NAN((n) - (n)) && !UNITY_IS_NAN(n))
+#else
+#define UNITY_IS_INF(n) isinf(n)
+#endif
#endif
#endif
diff --git a/test/.rubocop.yml b/test/.rubocop.yml
index 6c9542f..a3b811b 100644
--- a/test/.rubocop.yml
+++ b/test/.rubocop.yml
@@ -3,7 +3,7 @@
#inherit_from: .rubocop_todo.yml
AllCops:
- TargetRubyVersion: 2.3
+ TargetRubyVersion: 3.0
# These are areas where ThrowTheSwitch's coding style diverges from the Ruby standard
Style/SpecialGlobalVars:
@@ -28,6 +28,8 @@ Style/EvalWithLocation:
Enabled: false
Style/MixinUsage:
Enabled: false
+Style/OptionalBooleanParameter:
+ Enabled: false
# These are also places we diverge... but we will likely comply down the road
Style/IfUnlessModifier:
@@ -36,10 +38,12 @@ Style/FormatStringToken:
Enabled: false
# This is disabled because it seems to get confused over nested hashes
-Layout/AlignHash:
+Layout/HashAlignment:
Enabled: false
EnforcedHashRocketStyle: table
EnforcedColonStyle: table
+Layout/LineLength:
+ Enabled: false
# We purposefully use these insecure features because they're what makes Ruby awesome
Security/Eval:
@@ -64,8 +68,6 @@ Metrics/ClassLength:
Enabled: false
Metrics/CyclomaticComplexity:
Enabled: false
-Metrics/LineLength:
- Enabled: false
Metrics/MethodLength:
Enabled: false
Metrics/ModuleLength: