diff --git a/README.md b/README.md index 6be02aa5..ac0ac388 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Unity Test ![CI][] -__Copyright (c) 2007 - 2024 Unity Project by Mike Karlesky, Mark VanderVoord, and Greg Williams__ +__Copyright (c) 2007 - 2026 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. diff --git a/auto/colour_reporter.rb b/auto/colour_reporter.rb index 10a17d37..cb10f3f6 100644 --- a/auto/colour_reporter.rb +++ b/auto/colour_reporter.rb @@ -19,6 +19,12 @@ def report(message) colour = case line when /(?:total\s+)?tests:?\s+(\d+)\s+(?:total\s+)?failures:?\s+\d+\s+Ignored:?/i Regexp.last_match(1).to_i.zero? ? :green : :red + when /^\[FAIL\]/ + :red + when /^\[p \]/ + :green + when /^\[i---\]/ + :green when /PASS/ :green when /^OK$/ diff --git a/auto/generate_test_runner.rb b/auto/generate_test_runner.rb index 8f0826ff..c5db5ab5 100755 --- a/auto/generate_test_runner.rb +++ b/auto/generate_test_runner.rb @@ -239,17 +239,15 @@ def count_tests(tests) if @options[:use_param_tests] idx = 0 tests.each do |test| - if (test[:args].nil? || test[:args].empty?) + if test[:args].nil? || test[:args].empty? idx += 1 else - test[:args].each do |args| - idx += 1 - end + test[:args].each { idx += 1 } end end - return idx + idx else - return tests.size + tests.size end end diff --git a/auto/unity_test_summary.rb b/auto/unity_test_summary.rb old mode 100644 new mode 100755 diff --git a/src/unity.c b/src/unity.c index 4b1aea6c..7933eddf 100644 --- a/src/unity.c +++ b/src/unity.c @@ -197,41 +197,48 @@ void UnityPrintLen(const char* string, const UNITY_UINT32 length) /*-----------------------------------------------*/ void UnityPrintIntNumberByStyle(const UNITY_INT number, const UNITY_DISPLAY_STYLE_T style) { - if ((style & UNITY_DISPLAY_RANGE_INT) == UNITY_DISPLAY_RANGE_INT) + if (style == UNITY_DISPLAY_STYLE_CHAR) { - if (style == UNITY_DISPLAY_STYLE_CHAR) + /* printable characters plus CR & LF are printed */ + UNITY_OUTPUT_CHAR('\''); + if ((number <= 126) && (number >= 32)) { - /* printable characters plus CR & LF are printed */ - UNITY_OUTPUT_CHAR('\''); - if ((number <= 126) && (number >= 32)) - { - UNITY_OUTPUT_CHAR((int)number); - } - /* write escaped carriage returns */ - else if (number == 13) - { - UNITY_OUTPUT_CHAR('\\'); - UNITY_OUTPUT_CHAR('r'); - } - /* write escaped line feeds */ - else if (number == 10) - { - UNITY_OUTPUT_CHAR('\\'); - UNITY_OUTPUT_CHAR('n'); - } - /* unprintable characters are shown as codes */ - else - { - UNITY_OUTPUT_CHAR('\\'); - UNITY_OUTPUT_CHAR('x'); - UnityPrintNumberHex((UNITY_UINT)number, 2); - } - UNITY_OUTPUT_CHAR('\''); + UNITY_OUTPUT_CHAR((int)number); + } + /* write escaped carriage returns */ + else if (number == 13) + { + UNITY_OUTPUT_CHAR('\\'); + UNITY_OUTPUT_CHAR('r'); } + /* write escaped line feeds */ + else if (number == 10) + { + UNITY_OUTPUT_CHAR('\\'); + UNITY_OUTPUT_CHAR('n'); + } + /* unprintable characters are shown as codes */ else { - UnityPrintNumber(number); + UNITY_OUTPUT_CHAR('\\'); + UNITY_OUTPUT_CHAR('x'); + UnityPrintNumberHex((UNITY_UINT)number, 2); } + UNITY_OUTPUT_CHAR('\''); + } + else if ((style & UNITY_DISPLAY_RANGE_INT) == UNITY_DISPLAY_RANGE_INT) + { + UnityPrintNumber(number); + } + else if ((style & UNITY_DISPLAY_RANGE_UINT) == UNITY_DISPLAY_RANGE_UINT) + { + UnityPrintNumberUnsigned((UNITY_UINT)number); + } + else + { + UNITY_OUTPUT_CHAR('0'); + UNITY_OUTPUT_CHAR('x'); + UnityPrintNumberHex((UNITY_UINT)number, (char)((style & 0xF) * 2)); } } @@ -359,13 +366,6 @@ void UnityPrintFloat(const UNITY_DOUBLE input_number) UNITY_DOUBLE number = input_number; - /* print minus sign (does not handle negative zero) */ - if (number < 0.0f) - { - UNITY_OUTPUT_CHAR('-'); - number = -number; - } - /* handle zero, NaN, and +/- infinity */ if (number == 0.0f) { @@ -373,11 +373,18 @@ void UnityPrintFloat(const UNITY_DOUBLE input_number) } else if (UNITY_IS_NAN(number)) { - UnityPrint("nan"); + UnityPrint(UnityStrNaN); } else if (UNITY_IS_INF(number)) { - UnityPrint("inf"); + if (number < 0.0f) + { + UnityPrint(UnityStrNegInf); + } + else + { + UnityPrint(UnityStrInf); + } } else { @@ -388,6 +395,11 @@ void UnityPrintFloat(const UNITY_DOUBLE input_number) int digits; char buf[16] = {0}; + if (number < 0.0f) + { + UNITY_OUTPUT_CHAR('-'); + number = -number; + } /* * Scale up or down by powers of 10. To minimize rounding error, * start with a factor/divisor of 10^10, which is the largest @@ -868,6 +880,8 @@ void UnityAssertEqualIntArray(UNITY_INTERNAL_PTR expected, const UNITY_DISPLAY_STYLE_T style, const UNITY_FLAGS_T flags) { + UNITY_INT expect_val = 0; + UNITY_INT actual_val = 0; UNITY_UINT32 elements = num_elements; unsigned int length = style & 0xF; unsigned int increment = 0; @@ -895,9 +909,6 @@ void UnityAssertEqualIntArray(UNITY_INTERNAL_PTR expected, while ((elements > 0) && (elements--)) { - UNITY_INT expect_val; - UNITY_INT actual_val; - switch (length) { case 1: diff --git a/src/unity_internals.h b/src/unity_internals.h index da17059f..0ea22fbc 100644 --- a/src/unity_internals.h +++ b/src/unity_internals.h @@ -445,7 +445,7 @@ typedef UNITY_FLOAT_TYPE UNITY_FLOAT; #endif /*------------------------------------------------------- - * Internal Structs Needed + * Internal Types Needed *-------------------------------------------------------*/ typedef void (*UnityTestFunction)(void); @@ -528,6 +528,10 @@ typedef enum #endif #endif +#if defined(__GNUC__) || defined(__clang__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wpadded" +#endif struct UNITY_STORAGE_T { const char* TestFile; @@ -556,6 +560,9 @@ struct UNITY_STORAGE_T jmp_buf AbortFrame; #endif }; +#if defined(__GNUC__) || defined(__clang__) +#pragma GCC diagnostic pop +#endif extern struct UNITY_STORAGE_T Unity; @@ -857,6 +864,7 @@ extern const char UnityStrErrFloat[]; extern const char UnityStrErrDouble[]; extern const char UnityStrErr64[]; extern const char UnityStrErrShorthand[]; +extern const char UnityStrErrDetailStack[]; /*------------------------------------------------------- * Test Running Macros diff --git a/test/rakefile_helper.rb b/test/rakefile_helper.rb index cabcc995..6149b8dd 100644 --- a/test/rakefile_helper.rb +++ b/test/rakefile_helper.rb @@ -293,8 +293,68 @@ def run_tests(test_files) # Link the test executable link_it(test_base, obj_list) - # Execute unit test and generate results file + # Execute unit test output = runtest(test_base) + + # This is a list of all non-string valid outputs + # (in order) this is the following options: + # valid binary representations + # valid hexadecimal representation + # valid integer (signed or unsigned) or float values of any precision + # valid floating point special-case verbage + # valid boolean verbage + # valid pointer verbage + # string representations + # character representations + valid_vals_regexes = [ + /[01X]+/, + /0x[0-9A-Fa-f]+/, + /-?\d+(?:\.\d+)?/, + /(?:Not )?(?:Negative )?(?:Infinity|NaN|Determinate|Invalid Float Trait)/, + /TRUE|FALSE/, + /NULL/, + /"[^"]*"/, + /'[^']*'/ + ] + valid_vals = "(?:#{valid_vals_regexes.map(&:source).join('|')})" + + # Verify outputs seem to have happened + failures = 0 + output = output.each_line.map do |line| + if (line =~ /(?:Delta.*)?(?:Element.*)?Expected.*Was/) + if !(line =~ /(?:Delta \d+ )?(?:Element \d+ )?Expected #{valid_vals} Was #{valid_vals}/) + failures += 1 + "[FAIL] " + line.sub(/:PASS$/,":FAIL:Output Format Failure") + else + "[p ] " + line + end + elsif (line =~ /:PASS$/) + "[p ] " + line + elsif (line =~ /:FAIL(?:[^:])$/) || (line =~ /^FAILED$/) + #failure has already been counted therefore do not add + "[FAIL] " + line + elsif (line =~ /:IGNORE$/) + #ignore has already been counted therefore do not add + "[i---] " + line + else + "[ ] " + line + end + end.join + + # Update the final test summary + if failures > 0 + output.sub!(/^(?:\[ \] )?(\d+) Tests (\d+) Failures (\d+) Ignored/) do + tests = $1 + failures = $2.to_i + failures + ignored = $3 + "[ ] #{tests} Tests #{failures} Failures #{ignored} Ignored" + end + output.sub!(/\[ \] OK$/,"[FAIL] FAILED") + report output + raise "Command failed. (#{failures.to_s} Output Formatting Issues)" + end + + # Generate results file save_test_results(test_base, output) end end