From 720acfbb953a6f23803d0242d23fde65b6d131fd Mon Sep 17 00:00:00 2001 From: greg-williams Date: Thu, 7 Feb 2008 03:00:54 +0000 Subject: [PATCH] Initial project population git-svn-id: http://unity.svn.sourceforge.net/svnroot/unity/trunk@1 e7d17a6e-8845-0410-bbbc-c8efb4fdad7e --- auto/unity_test_summary.rb | 203 +++++++++++ docs/Unity Summary.odt | Bin 0 -> 18359 bytes docs/Unity Summary.pdf | Bin 0 -> 99972 bytes docs/Unity Summary.txt | 202 +++++++++++ makefile | 13 + rakefile | 72 ++++ rakefile_helper.rb | 93 ++++++ src/unity.c | 336 +++++++++++++++++++ src/unity.h | 206 ++++++++++++ test/testunity.c | 669 +++++++++++++++++++++++++++++++++++++ test/testunity_Runner.c | 111 ++++++ 11 files changed, 1905 insertions(+) create mode 100644 auto/unity_test_summary.rb create mode 100644 docs/Unity Summary.odt create mode 100644 docs/Unity Summary.pdf create mode 100644 docs/Unity Summary.txt create mode 100644 makefile create mode 100644 rakefile create mode 100644 rakefile_helper.rb create mode 100644 src/unity.c create mode 100644 src/unity.h create mode 100644 test/testunity.c create mode 100644 test/testunity_Runner.c diff --git a/auto/unity_test_summary.rb b/auto/unity_test_summary.rb new file mode 100644 index 0000000..b8fdb61 --- /dev/null +++ b/auto/unity_test_summary.rb @@ -0,0 +1,203 @@ +#!/usr/bin/ruby +# +# unity_test_summary.rb +# +require 'fileutils' +require 'set' + +class UnityTestSummary + + include FileUtils::Verbose + + def run + + $stderr.flush + $stdout.flush + + # Clean up result file names + results = @targets.map {|target| target.gsub(/\\/,'/')} + + # Dig through each result file, looking for details on pass/fail: + total_tests = 0 + total_failures = 0 + total_ignored = 0 + + failure_output = "" + ignore_output = "" + + results.each do |result_file| + lines = File.readlines(result_file).map { |line| line.chomp } + if lines.length == 0 + puts "Empty test result file: #{result_file}" + else + summary_line = -2 + output = get_details(result_file, lines) + failure_output += output[:failures] if !output[:failures].empty? + ignore_output += output[:ignores] if !output[:ignores].empty? + tests,failures,ignored = parse_test_summary(lines[summary_line]) + total_tests += tests + total_failures += failures + total_ignored += ignored + end + end + + if total_ignored > 0 + puts "\n" + puts "--------------------------\n" + puts "UNITY IGNORED TEST SUMMARY\n" + puts "--------------------------\n" + puts ignore_output + end + + if total_failures > 0 + puts "\n" + puts "--------------------------\n" + puts "UNITY FAILED TEST SUMMARY\n" + puts "--------------------------\n" + puts failure_output + end + + puts "\n" + puts "--------------------------\n" + puts "OVERALL UNITY TEST SUMMARY\n" + puts "--------------------------\n" + puts "TOTAL TESTS: #{total_tests} TOTAL FAILURES: #{total_failures} IGNORED: #{total_ignored}\n" + puts "\n" + + return total_failures + end + + def usage(err_msg=nil) + puts err_msg if err_msg + puts "Usage: unity_test_summary.rb" + exit 1 + end + + def set_targets(target_array) + @targets = target_array + end + + def set_root_path(path) + @root = path + puts "root_path = " + @root + end + + protected + + @@targets=nil + @@path=nil + @@root=nil + + def get_details(result_file, lines) + fail_lines = [] # indices of lines with failures + ignore_lines = [] # indices of lines with ignores + lines.each_with_index do |line,i| + if (i < (lines.length - 2) && !(line =~ /PASS$/)) + if line =~ /(^.*\.c):(\d+)/ + if line =~ /IGNORED$/ + ignore_lines << i + else + fail_lines << i + end + elsif line =~ /IGNORED$/ + ignore_lines << i + end + end + end + + failures = [] + fail_lines.each do |fail_line| + if lines[fail_line] =~ /\w:/ + src_file,src_line,test_name,msg = lines[fail_line].split(/:/) + src_file = "#{@root}#{src_file}" unless @root == nil || @root.length == 0 + detail = "#{src_file}:#{src_line}:#{test_name}:: #{msg}" + failures << detail.gsub(/\//, "\\") + end + end + if failures.length == 0 + failure_results = "" + else + failure_results = failures.join("\n") + "\n" + end + + ignores = [] + ignore_lines.each do |ignore_line| + if lines[ignore_line] =~ /\w:/ + src_file,src_line,test_name,msg = lines[ignore_line].split(/:/) + src_file = "#{@root}#{src_file}" unless @root == nil || @root.length == 0 + detail = "#{src_file}:#{src_line}:#{test_name}:: #{msg}" + ignores << detail.gsub(/\//, "\\") + end + end + if ignores.length == 0 + ignore_results = "" + else + ignore_results = ignores.join("\n") + "\n" + end + + results = {:failures => failure_results, :ignores => ignore_results} + end + + def parse_test_summary(summary) + if summary =~ /(\d+) Tests (\d+) Failures (\d+) Ignored/ + [$1.to_i,$2.to_i,$3.to_i] + else + raise "Couldn't parse test results: #{summary}" + end + end + + def here; File.expand_path(File.dirname(__FILE__)); end + + def valid_file(fname) + raise "Can't find file #{fname}" unless File.exists?(fname) + fname + end + + def valid_dir(dirname) + raise "Can't find dir #{dirname}" unless File.exists?(dirname) + dirname + end + + def search_file_and_replace(file_name, pattern, replacement) + text = File.read(valid_file(file_name)) + text.gsub!(pattern, replacement) + File.open(file_name, "w") do |f| f.write text end + end + + def create_file_from_template(dest_file, template_file) + raise "#{dest_file} already exists; remove it first" if File.exists?(dest_file) + + template_file = valid_file("#{here}/rscript_template.rb") + template = ERB.new(File.read(template_file)) + + File.open(dest_file,"w") do |f| + f.write template.result(binding) + end + end + + def humanize(lower_case_and_underscored_word) + lower_case_and_underscored_word.to_s.gsub(/_id$/, "").gsub(/_/, " ").capitalize + end + + def camelize(lower_case_and_underscored_word) + lower_case_and_underscored_word.to_s.gsub(/\/(.?)/) { "::" + $1.upcase }.gsub(/(^|_)(.)/) { $2.upcase } + end + + def titleize(word) + humanize(underscore(word)).gsub(/\b([a-z])/) { $1.capitalize } + end + + def underscore(camel_cased_word) + camel_cased_word.to_s.gsub(/::/, '/').gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').gsub(/([a-z\d])([A-Z])/,'\1_\2').downcase + end + +end + +if $0 == __FILE__ + script = UnityTestSummary.new + begin + script.run + rescue Exception => e + script.usage e.message + end +end diff --git a/docs/Unity Summary.odt b/docs/Unity Summary.odt new file mode 100644 index 0000000000000000000000000000000000000000..fb5745e86cdd6cce3ae0767f8be381ee9658bca1 GIT binary patch literal 18359 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 literal 0 HcmV?d00001 diff --git a/docs/Unity Summary.pdf b/docs/Unity Summary.pdf new file mode 100644 index 0000000000000000000000000000000000000000..2ddf129c954e10a62c5d30c1612ebb25db1751f7 GIT binary patch literal 99972 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 literal 0 HcmV?d00001 diff --git a/docs/Unity Summary.txt b/docs/Unity Summary.txt new file mode 100644 index 0000000..6b5a64e --- /dev/null +++ b/docs/Unity Summary.txt @@ -0,0 +1,202 @@ +Unity Test API +============== + +------------- +Running Tests +------------- + +RUN_TEST(func) + +Each Test is run within the macro RUN_TEST. This macro performs necessary setup before the test is called and handles cleanup and result tabulation afterwards. + +TEST_WRAP(function) + +If the test functions call helper functions and those helper functions have the ability to make assertions, calls to those helpers should be wrapped in a TEST_WRAP macro. This macro aborts the test if the helper triggered a failure. + +-------------- +Ignoring Tests +-------------- + +There are times when a test is incomplete or not valid for some reason. At these times, TEST_IGNORE can be called. Control will immediately be returned to the caller of the test, and no failures will be returned. + +TEST_IGNORE() + +Ignore this test and return immediately + +TEST_IGNORE_MESSAGE (message) + +Ignore this test and return immediately. Output a message stating why the test was ignored. + +-------------- +Aborting Tests +-------------- + +There are times when a test will contain an infinite loop on error conditions, or there may be reason to escape from the test early without executing the rest of the test. A pair of macros support this functionality in Unity. The first (TEST_PROTECT) sets up the feature, and handles emergency abort cases. TEST_THROW can then be used at any time within the tests to return to the last TEST_PROTECT call. + +TEST_PROTECT() + +Setup and Catch macro + +TEST_THROW (message) + +Abort Test macro + +Example: + +main() +{ + if (TEST_PROTECT() == 0) + { + MyTest(); + } +} + +If MyTest calls TEST_THROW, a failure with the message provided will be inserted, and program control will immediately return to TEST_PROTECT with a non-zero return value. +Unity Assertion Summary + +-------------------- +Basic Validity Tests +-------------------- + +TEST_ASSERT_TRUE(condition) + +Evaluates whatever code is in condition and fails if it evaluates to false + +TEST_ASSERT_FALSE(condition) + +Evaluates whatever code is in condition and fails if it evaluates to true + +TEST_ASSERT(condition) + +Another way of calling TEST_ASSERT_TRUE + +TEST_ASSERT_UNLESS(condition) + +Another way of calling TEST_ASSERT_FALSE + +TEST_FAIL(message) + +This test is automatically marked as a failure. The message is output stating why. + +------------------------------ +Numerical Assertions: Integers +------------------------------ + +TEST_ASSERT_EQUAL(expected, actual) + +Another way of calling TEST_ASSERT_EQUAL_INT + +TEST_ASSERT_EQUAL_INT(expected, actual) + +Compare two integers for equality and display errors as signed integers. + +TEST_ASSERT_EQUAL_UINT(expected, actual) + +Compare two integers for equality and display errors as unsigned integers. + +TEST_ASSERT_EQUAL_HEX8(expected, actual) + +Compare two integers for equality and display errors as an 8-bit hex value + +TEST_ASSERT_EQUAL_HEX16(expected, actual) + +Compare two integers for equality and display errors as an 16-bit hex value + +TEST_ASSERT_EQUAL_HEX32(expected, actual) + +Compare two integers for equality and display errors as an 32-bit hex value + +TEST_ASSERT_EQUAL_HEX(expected, actual) + +Another way of calling TEST_ASSERT_EQUAL_HEX32 + +TEST_ASSERT_INT_WITHIN(delta, expected, actual) + +Asserts that the actual value is within plus or minus delta of the expected value. + +TEST_ASSERT_EQUAL_MESSAGE(expected, actual, message) + +Another way of calling TEST_ASSERT_EQUAL_INT_MESSAGE + +TEST_ASSERT_EQUAL_INT_MESSAGE(expected, actual, message) + +Compare two integers for equality and display errors as signed integers. Outputs a custom message on failure. + +TEST_ASSERT_EQUAL_UINT_MESSAGE(expected, actual, message) + +Compare two integers for equality and display errors as unsigned integers. Outputs a custom message on failure. + +TEST_ASSERT_EQUAL_HEX8_MESSAGE(expected, actual, message) + +Compare two integers for equality and display errors as an 8-bit hex value. Outputs a custom message on failure. + +TEST_ASSERT_EQUAL_HEX16_MESSAGE(expected, actual, message) + +Compare two integers for equality and display errors as an 16-bit hex value. Outputs a custom message on failure. + +TEST_ASSERT_EQUAL_HEX32_MESSAGE(expected, actual, message) + +Compare two integers for equality and display errors as an 32-bit hex value. Outputs a custom message on failure. + +TEST_ASSERT_EQUAL_HEX_MESSAGE(expected, actual, message) + +Another way of calling TEST_ASSERT_EQUAL_HEX32_MESSAGE + +----------------------------- +Numerical Assertions: Bitwise +----------------------------- + +TEST_ASSERT_BITS(mask, expected, actual) + +Use an integer mask to specify which bits should be compared between two other integers. High bits in the mask are compared, low bits ignored. + +TEST_ASSERT_BITS_HIGH(mask, actual) + +Use an integer mask to specify which bits should be inspected to determine if they are all set high. High bits in the mask are compared, low bits ignored. + +TEST_ASSERT_BITS_LOW(mask, actual) + +Use an integer mask to specify which bits should be inspected to determine if they are all set low. High bits in the mask are compared, low bits ignored. + +TEST_ASSERT_BIT_HIGH(bit, actual) + +Test a single bit and verify that it is high. The bit is specified 0-31 for a 32-bit integer. + +TEST_ASSERT_BIT_LOW(bit, actual) + +Test a single bit and verify that it is low. The bit is specified 0-31 for a 32-bit integer. + +---------------------------- +Numerical Assertions: Floats +---------------------------- + +TEST_ASSERT_FLOAT_WITHIN(delta, expected, actual) + +Asserts that the actual value is within plus or minus delta of the expected value. + +----------------- +String Assertions +----------------- + +TEST_ASSERT_EQUAL_STRING(expected, actual) + +Compare two null-terminate strings. Fail if any character is different or if the lengths are different. + +TEST_ASSERT_EQUAL_STRING_MESSAGE(expected, actual, message) + +Compare two null-terminate strings. Fail if any character is different or if the lengths are different. Output a custom message on failure. + +------------------ +Pointer Assertions +------------------ + +Most pointer operations can be performed by simply using the integer comparisons above. However, a couple of special cases are added for clarity. + +TEST_ASSERT_NULL(pointer) + +Fails if the pointer is not equal to NULL + +TEST_ASSERT_NOT_NULL(pointer) + +Fails if the pointer is equal to NULL + diff --git a/makefile b/makefile new file mode 100644 index 0000000..6e95a28 --- /dev/null +++ b/makefile @@ -0,0 +1,13 @@ +C_COMPILER=gcc +OUT_FILE=-o testunity +ifeq ($(OS),Windows_NT) +OUT_EXTENSION=.exe +else +OUT_EXTENSION=.out +endif +SRC_FILES=src/unity.c test/testunity.c test/testunity_Runner.c +INC_DIRS=-Isrc +SYMBOLS=-DTEST + +default: + $(C_COMPILER) $(INC_DIRS) $(SYMBOLS) $(SRC_FILES) $(OUT_FILE)$(OUT_EXTENSION) diff --git a/rakefile b/rakefile new file mode 100644 index 0000000..6e43ec6 --- /dev/null +++ b/rakefile @@ -0,0 +1,72 @@ +$here = File.expand_path( File.dirname( __FILE__ ) ) + +require 'rake/clean' +require 'rake/loaders/makefile' +require 'fileutils' +require 'set' +require 'auto/unity_test_summary' +require 'rakefile_helper' + +include RakefileHelpers + +CLEAN.include('bin/*') + +desc "Build Unity and run tests." +task :default => [:clobber, :all] + +desc "Build Unity object file." +task :build_unity => [:clobber, UNITY_OBJ] + +task :run_test => [TEST_RESULTS, :summary].flatten + +task :all => [UNITY_TEST_EXEC, :run_test] + +task :summary do + flush_output + summary = UnityTestSummary.new + summary.set_root_path($here) + summary.set_targets(Dir["bin/*.test*"]) + summary.run +end + +file UNITY_OBJ => [UNITY_SRC, UNITY_HDR] do |obj| + compile UNITY_SRC, obj.name +end + +file UNITY_TEST_OBJ => [UNITY_TEST_SRC, UNITY_SRC, UNITY_HDR] do |obj| + compile UNITY_TEST_SRC, obj.name +end + +file UNITY_TEST_RUNNER_OBJ => [UNITY_TEST_RUNNER_SRC, UNITY_TEST_SRC, UNITY_SRC, UNITY_HDR] do |obj| + compile UNITY_TEST_RUNNER_SRC, obj.name +end + +file UNITY_TEST_EXEC => [UNITY_OBJ, UNITY_TEST_OBJ, UNITY_TEST_RUNNER_OBJ] do |bin| + link bin.prerequisites, bin.name +end + +rule /.*\.test/ => [BIN_EXTENSION] do |file| + bin = file.name.ext BIN_EXTENSION + test_results = 'bin\sim.txt' + fail_file = file.name.ext 'testfail' + if File.exist?(fail_file) + rm_f fail_file + end + rm_f test_results + rm_f file.name + output = run_test bin + if !File.file?(test_results) + File.open(test_results, 'w') do |f| + f.print output + end + end + open test_results, 'r' do |f| + testoutput = f.read + if testoutput.index 'OK' + cp test_results, file.name + else + cp test_results, fail_file + end + end +end + diff --git a/rakefile_helper.rb b/rakefile_helper.rb new file mode 100644 index 0000000..fd3cb33 --- /dev/null +++ b/rakefile_helper.rb @@ -0,0 +1,93 @@ +HERE = File.expand_path( File.dirname( __FILE__ ) ).gsub(/\//, '\\') + +module RakefileConstants + + PROGRAM_FILES_PATH = ENV['ProgramFiles'] + begin + Dir.new PROGRAM_FILES_PATH + '\IAR Systems\Embedded Workbench 4.0\arm' + IAR_ROOT = PROGRAM_FILES_PATH + '\IAR Systems\Embedded Workbench 4.0' + rescue + Dir.new PROGRAM_FILES_PATH + '\IAR Systems\Embedded Workbench 4.0 Kickstart\arm' + IAR_ROOT = PROGRAM_FILES_PATH + '\IAR Systems\Embedded Workbench 4.0 Kickstart' + end + + C_EXTENSION = '.c' + OBJ_EXTENSION = '.r79' + BIN_EXTENSION = '.d79' + + UNIT_TEST_PATH = 'test' + SOURCE_PATH = 'src' + BIN_PATH = 'bin' + IAR_PATH = IAR_ROOT + '\common' + IAR_BIN = IAR_PATH + '\bin' + IAR_INCLUDE = IAR_PATH + '\inc' + IAR_CORE_PATH = IAR_ROOT + '\arm' + IAR_CORE_BIN = IAR_CORE_PATH + '\bin' + IAR_CORE_CONFIG = IAR_CORE_PATH + '\config' + IAR_CORE_INCLUDE = IAR_CORE_PATH + '\inc' + IAR_CORE_INCLUDE_DLIB = IAR_CORE_INCLUDE + '\lib' + IAR_CORE_LIB = IAR_CORE_PATH + '\lib' + IAR_CORE_DLIB = IAR_CORE_LIB + '\dl5tpannl8n.r79' + IAR_CORE_DLIB_CONFIG = IAR_CORE_LIB + '\dl5tpannl8n.h' + IAR_PROCESSOR_SPECIFIC_PATH = HERE + '\proc' + SIMULATOR_PROCESSOR = IAR_CORE_BIN + '\armproc.dll' + SIMULATOR_DRIVER = IAR_CORE_BIN + '\armsim.dll' + SIMULATOR_PLUGIN = IAR_CORE_BIN + '\armbat.dll' + SIMULATOR_BACKEND_DDF = IAR_CORE_CONFIG + '\ioat91sam9261.ddf' + PROCESSOR_TYPE = "ARM926EJ-S" + LINKER_CONFIG = IAR_CORE_CONFIG + '\lnkarm.xcl' + + UNITY_SRC = SOURCE_PATH + '\unity.c' + UNITY_HDR = SOURCE_PATH + '\unity.h' + UNITY_TEST_SRC = UNIT_TEST_PATH + '\testunity.c' + UNITY_TEST_RUNNER_SRC = UNIT_TEST_PATH + '\testunity_Runner.c' + UNITY_OBJ = BIN_PATH + '\unity' + OBJ_EXTENSION + UNITY_TEST_OBJ = BIN_PATH + '\testunity' + OBJ_EXTENSION + UNITY_TEST_RUNNER_OBJ = BIN_PATH + '\testunity_Runner' + OBJ_EXTENSION + UNITY_TEST_EXEC = UNITY_TEST_OBJ.ext BIN_EXTENSION + TEST_RESULTS = UNITY_TEST_OBJ.ext '.testpass' + + COMPILER = IAR_CORE_BIN + '\iccarm.exe' + LINKER = IAR_BIN + '\xlink.exe' + SIMULATOR = IAR_BIN + '\CSpyBat.exe' + +end + +module RakefileHelpers + include RakefileConstants + + def flush_output + $stderr.flush + $stdout.flush + end + + def report message + puts message + flush_output + end + + def compile src, obj + execute "#{COMPILER} --dlib_config \"#{IAR_CORE_DLIB_CONFIG}\" -z3 --no_cse --no_unroll --no_inline --no_code_motion --no_tbaa --no_clustering --no_scheduling --debug --cpu_mode arm --endian little --cpu #{PROCESSOR_TYPE} --stack_align 4 -e --fpu None --diag_suppress Pa050 --diag_suppress Pe111 -I\"#{IAR_CORE_INCLUDE}\" -Isrc -Itest #{src} -o#{obj}" + end + + def link prerequisites, executable + execute "\"#{LINKER}\" -rt \"#{IAR_CORE_DLIB}\" -B -s __program_start -I\"#{IAR_CORE_CONFIG}\" -I\"#{IAR_CORE_LIB}\" -f \"#{LINKER_CONFIG}\" #{prerequisites.join(' ')} -o #{executable}" + end + + def run_test executable + execute "\"#{SIMULATOR}\" --silent \"#{SIMULATOR_PROCESSOR}\" \"#{SIMULATOR_DRIVER}\" #{executable} --plugin \"#{SIMULATOR_PLUGIN}\" --backend -B --cpu #{PROCESSOR_TYPE} -p \"#{SIMULATOR_BACKEND_DDF}\" -d sim" + end + +private + + def execute command_string + report command_string + output = `#{command_string}` + report output + if $?.exitstatus != 0 + raise "Command failed. (Returned #{$?.exitstatus})" + end + output + end + +end diff --git a/src/unity.c b/src/unity.c new file mode 100644 index 0000000..549ae3d --- /dev/null +++ b/src/unity.c @@ -0,0 +1,336 @@ +#include "unity.h" +#include + + +struct _Unity Unity = +{ + NULL, + 0, + 0, + 0, + 0, + 0, + NULL, + 1e-4f, +}; + +void UnityPrintChar(char ch) +{ + putchar(ch); +} + +void UnityPrint(const char *string) +{ + unsigned char * pch = (unsigned char *)string; + + if (pch != NULL) + { + while (*pch) + { + UnityPrintChar(*pch); + pch++; + } + } +} + +void UnityPrintNumberByStyle(long number, UNITY_DISPLAY_STYLE_T style) +{ + switch (style) + { + case UNITY_DISPLAY_STYLE_HEX8: UnityPrintNumberHex(number,2); break; + case UNITY_DISPLAY_STYLE_HEX16: UnityPrintNumberHex(number,4); break; + case UNITY_DISPLAY_STYLE_HEX32: UnityPrintNumberHex(number,8); break; + case UNITY_DISPLAY_STYLE_UINT: UnityPrintNumberUnsigned(number); break; + default: UnityPrintNumber(number); break; + } +} + +/// basically do an itoa using as little ram as possible +void UnityPrintNumber(long number) +{ + unsigned long divisor = 10; + + if (number < 0) + { + UnityPrintChar('-'); + number = -number; + } + + // figure out initial divisor + while (number / divisor) + { + divisor *= 10; + } + + // now divide number by divisor, mod and print, then divide divisor + do + { + divisor /= 10; + UnityPrintChar((char)('0' + (number / divisor % 10))); + } + while (divisor > 1U); +} + +/// basically do an itoa using as little ram as possible +void UnityPrintNumberUnsigned(unsigned long number) +{ + unsigned long divisor = 10; + + // figure out initial divisor + while (number / divisor) + { + divisor *= 10; + } + + // now divide number by divisor, mod and print, then divide divisor + do + { + divisor /= 10; + UnityPrintChar((char)('0' + (number / divisor % 10))); + } + while (divisor > 1U); +} + +void UnityPrintNumberHex(unsigned long number, char nibbles) +{ + unsigned long nibble; + UnityPrint("0x"); + + while (nibbles > 0) + { + nibble = (number >> (--nibbles << 2)) & 0x0000000F; + if (nibble <= 9) + { + UnityPrintChar((char)('0' + nibble)); + } + else + { + UnityPrintChar((char)('A' - 10 + nibble)); + } + } +} + +void UnityPrintMask(unsigned long mask, unsigned long number) +{ + unsigned long bit = 0x00000001; + int i; + + for (i = 0; i < 32; i++) + { + if (bit & mask) + { + if (bit & number) + { + UnityPrintChar('1'); + } + else + { + UnityPrintChar('0'); + } + } + else + { + UnityPrintChar('X'); + } + bit = bit << 1; + } +} + +void UnityTestResultsBegin(int line) +{ + UnityPrint(Unity.TestFile); + UnityPrintChar(':'); + UnityPrintNumber(line); + UnityPrintChar(':'); + UnityPrint(Unity.CurrentTestName); + UnityPrintChar(':'); +} + +void UnityConcludeTest() +{ + if (Unity.CurrentTestIgnored) + { + Unity.TestIgnores++; + } + else if (!Unity.CurrentTestFailed) + { + UnityPrint(Unity.CurrentTestName); + UnityPrint("::: PASS\n"); + } + else + { + Unity.TestFailures++; + } + + Unity.CurrentTestFailed = 0; + Unity.CurrentTestIgnored = 0; +} + +void UnityAssertBits(int mask, int expected, int actual, const char *msg, unsigned short lineNumber) +{ + if ((mask & expected) != (mask & actual)) + { + Unity.CurrentTestFailed = 1; + + UnityTestResultsBegin(lineNumber); + UnityPrint("Expected "); + UnityPrintMask(mask, expected); + UnityPrint(" was "); + UnityPrintMask(mask, actual); + UnityPrintChar('.'); + if (msg) + { + UnityPrintChar(' '); + UnityPrint(msg); + } + UnityPrintChar('\n'); + } +} + +void UnityAssertEqualInt(int expected, int actual, const char *msg, unsigned short lineNumber, UNITY_DISPLAY_STYLE_T style) +{ + if (expected != actual) + { + Unity.CurrentTestFailed = 1; + + UnityTestResultsBegin(lineNumber); + UnityPrint("Expected "); + UnityPrintNumberByStyle(expected, style); + UnityPrint(" was "); + UnityPrintNumberByStyle(actual, style); + UnityPrintChar('.'); + if (msg) + { + UnityPrintChar(' '); + UnityPrint(msg); + } + UnityPrintChar('\n'); + } +} + +void UnityAssertFloatsWithin(float delta, float expected, float actual, const char *msg, unsigned short lineNumber) +{ + float diff = actual - expected; + + if (diff < 0) + { + diff = -diff; + } + + if (delta < diff) + { + Unity.CurrentTestFailed = 1; + UnityTestResultsBegin(lineNumber); + UnityPrint("Floats not within delta."); + if (msg) + { + UnityPrintChar(' '); + UnityPrint(msg); + } + UnityPrintChar('\n'); + } +} + +void UnityAssertIntsWithin(int delta, int expected, int actual, const char *msg, unsigned short lineNumber) +{ + int diff = actual - expected; + + if (diff < 0) + { + diff = -diff; + } + + if (delta < diff) + { + Unity.CurrentTestFailed = 1; + UnityTestResultsBegin(lineNumber); + UnityPrint("Ints not within delta."); + if (msg) + { + UnityPrintChar(' '); + UnityPrint(msg); + } + UnityPrintChar('\n'); + } +} + +void UnityAssertEqualString(const char *expected, const char *actual, const char *msg, unsigned short lineNumber) +{ + unsigned int i; + + // if both pointers not null compare the strings + if (expected && actual) + { + for (i = 0; expected[i] || actual[i]; i++) + { + if (expected[i] != actual[i]) + { + Unity.CurrentTestFailed = 1; + } + } + } + else + { // handle case of one pointers being null (if both null, test should pass) + if (expected != actual) + { + Unity.CurrentTestFailed = 1; + } + } + + if (Unity.CurrentTestFailed) + { + UnityTestResultsBegin(lineNumber); + UnityPrint("Expected '"); + UnityPrint(expected); + UnityPrint("' was '"); + UnityPrint(actual); + UnityPrintChar('\''); + UnityPrintChar('.'); + if (msg) + { + UnityPrintChar(' '); + UnityPrint(msg); + } + UnityPrintChar('\n'); + } +} + +void UnityFail(const char *message, int line) +{ + Unity.CurrentTestFailed = 1; + UnityTestResultsBegin(line); + UnityPrint(message); + UnityPrintChar('\n'); +} + +void UnityIgnore(const char *message, int line) +{ + Unity.CurrentTestIgnored = 1; + UnityTestResultsBegin(line); + UnityPrint(message); + UnityPrint(" IGNORED\n"); +} + +void UnityBegin() +{ + Unity.NumberOfTests = 0; +} + +void UnityEnd(void) +{ + UnityPrintNumber(Unity.NumberOfTests); + UnityPrint(" Tests "); + UnityPrintNumber(Unity.TestFailures); + UnityPrint(" Failures "); + UnityPrintNumber(Unity.TestIgnores); + UnityPrint(" Ignored\n"); + if (Unity.TestFailures == 0U) + { + UnityPrint("OK\n"); + } + else + { + UnityPrint("FAIL\n"); + } +} + diff --git a/src/unity.h b/src/unity.h new file mode 100644 index 0000000..c089ee6 --- /dev/null +++ b/src/unity.h @@ -0,0 +1,206 @@ +#ifndef UNITY_FRAMEWORK_H +#define UNITY_FRAMEWORK_H + +#define UNITY + +#include + +typedef void (*UnityTestFunction)(void); + +typedef enum +{ + UNITY_DISPLAY_STYLE_INT, + UNITY_DISPLAY_STYLE_UINT, + UNITY_DISPLAY_STYLE_HEX8, + UNITY_DISPLAY_STYLE_HEX16, + UNITY_DISPLAY_STYLE_HEX32 +} UNITY_DISPLAY_STYLE_T; + +struct _Unity +{ + char* CurrentTestName; + unsigned char NumberOfTests; + unsigned char TestFailures; + unsigned char TestIgnores; + unsigned char CurrentTestFailed; + unsigned char CurrentTestIgnored; + const char *TestFile; + float DefaultDelta; +}; + +extern struct _Unity Unity; + +void CreateResults(); + +void UnityBegin(); +void UnityEnd(void); + +void UnityPrintChar(char ch); +void UnityPrint(const char *string); +void UnityPrintMask(unsigned long mask, unsigned long number); +void UnityPrintNumberByStyle(long number, UNITY_DISPLAY_STYLE_T style); +void UnityPrintNumber(long number); +void UnityPrintNumberUnsigned(unsigned long number); +void UnityPrintNumberHex(unsigned long number, char nibbles); +void UnityConcludeTest(); + +void UnityAssertEqualInt(int expected, int actual, +const char *msg, unsigned short lineNumber, UNITY_DISPLAY_STYLE_T style); + +void UnityAssertBits(int mask, int expected, int actual, +const char *msg, unsigned short lineNumber); + +void UnityAssertEqualString(const char *expected, const char *actual, +const char *msg, unsigned short lineNumber ); + +void UnityAssertFloatsWithin(float delta, float expected, float actual, +const char *msg, unsigned short lineNumber); + +void UnityAssertIntsWithin(int delta, int expected, int actual, +const char *msg, unsigned short lineNumber); + +void UnityFail(const char *message, int line); + +void UnityIgnore(const char *message, int line); + +#define EXIT_WRAPPED_TEST(exprString) \ +if( Unity.CurrentTestFailed ) {\ + UnityPrint(__FILE__); \ + UnityPrint(":"); \ + UnityPrintNumber(__LINE__); \ + UnityPrint(":REDIRECTED:"); \ + UnityPrint(exprString); \ + UnityPrintChar('\n'); \ +} + +#define RETURN_IF_NECESSARY() \ + if( Unity.CurrentTestFailed || Unity.CurrentTestIgnored ) {return;} + +#define TEST_WRAP_NO_RETURN(function) \ +{\ + function; \ + EXIT_WRAPPED_TEST(#function); \ +} + +#define RUN_TEST(func) \ + Unity.CurrentTestName = #func; \ + Unity.NumberOfTests ++; \ + runTest(func); \ + UnityConcludeTest(); + +#define TEST_WRAP(function) \ +{\ + TEST_WRAP_NO_RETURN(function); \ + Unity.TestFile=__FILE__; \ + RETURN_IF_NECESSARY(); \ +} + +#define TEST_ASSERT_MESSAGE(condition, message) if (condition) {} else {TEST_FAIL(message);} +#define TEST_ASSERT(condition) TEST_ASSERT_MESSAGE(condition, NULL) + +#define TEST_ASSERT_TRUE_MESSAGE(condition) TEST_ASSERT_MESSAGE(condition, message) +#define TEST_ASSERT_TRUE(condition) TEST_ASSERT(condition) + +#define TEST_ASSERT_UNLESS_MESSAGE(condition) TEST_ASSERT_MESSAGE(!(condition), message) +#define TEST_ASSERT_UNLESS(condition) TEST_ASSERT(!(condition)) + +#define TEST_ASSERT_FALSE_MESSAGE(condition) TEST_ASSERT_MESSAGE(!(condition), message) +#define TEST_ASSERT_FALSE(condition) TEST_ASSERT(!(condition)) + +#define TEST_ASSERT_NULL(pointer) TEST_ASSERT_MESSAGE(pointer == NULL, #pointer " was not null.") + +#define TEST_ASSERT_NOT_NULL(pointer) TEST_ASSERT_MESSAGE(pointer != NULL, #pointer " was null.") + +#define TEST_ASSERT_EQUAL_INT_MESSAGE(expected, actual, message) \ + Unity.TestFile=__FILE__; \ + UnityAssertEqualInt((int)(expected), (int)(actual), (message), (unsigned short)__LINE__, UNITY_DISPLAY_STYLE_INT); \ + RETURN_IF_NECESSARY(); +#define TEST_ASSERT_EQUAL_INT(expected, actual) TEST_ASSERT_EQUAL_INT_MESSAGE(expected, actual, NULL) + +#define TEST_ASSERT_EQUAL_MESSAGE(expected, actual, message) TEST_ASSERT_EQUAL_INT_MESSAGE((expected), (actual), (message)) +#define TEST_ASSERT_EQUAL(expected, actual) TEST_ASSERT_EQUAL_INT(expected, actual) + +#define TEST_ASSERT_INT_WITHIN_MESSAGE(delta, expected, actual, message) \ + Unity.TestFile=__FILE__; \ + UnityAssertIntsWithin((delta), (expected), (actual), NULL, (unsigned short)__LINE__); \ + RETURN_IF_NECESSARY(); +#define TEST_ASSERT_INT_WITHIN(delta, expected, actual) TEST_ASSERT_INT_WITHIN_MESSAGE(delta, expected, actual, NULL) + +#define TEST_ASSERT_EQUAL_UINT_MESSAGE(expected, actual, message) \ + Unity.TestFile=__FILE__; \ + UnityAssertEqualInt((int)(expected), (int)(actual), (message), (unsigned short)__LINE__, UNITY_DISPLAY_STYLE_UINT); \ + RETURN_IF_NECESSARY(); +#define TEST_ASSERT_EQUAL_UINT(expected, actual) TEST_ASSERT_EQUAL_UINT_MESSAGE(expected, actual, NULL) + +#define TEST_ASSERT_EQUAL_HEX8_MESSAGE(expected, actual, message) \ + Unity.TestFile=__FILE__; \ + UnityAssertEqualInt((int)(expected), (int)(actual), (message), (unsigned short)__LINE__, UNITY_DISPLAY_STYLE_HEX8); \ + RETURN_IF_NECESSARY(); +#define TEST_ASSERT_EQUAL_HEX8(expected, actual) TEST_ASSERT_EQUAL_HEX8_MESSAGE(expected, actual, NULL) + +#define TEST_ASSERT_EQUAL_HEX16_MESSAGE(expected, actual, message) \ + Unity.TestFile=__FILE__; \ + UnityAssertEqualInt((int)(expected), (int)(actual), (message), (unsigned short)__LINE__, UNITY_DISPLAY_STYLE_HEX16); \ + RETURN_IF_NECESSARY(); +#define TEST_ASSERT_EQUAL_HEX16(expected, actual) TEST_ASSERT_EQUAL_HEX16_MESSAGE(expected, actual, NULL) + +#define TEST_ASSERT_EQUAL_HEX32_MESSAGE(expected, actual, message) \ + Unity.TestFile=__FILE__; \ + UnityAssertEqualInt((int)(expected), (int)(actual), (message), (unsigned short)__LINE__, UNITY_DISPLAY_STYLE_HEX32); \ + RETURN_IF_NECESSARY(); +#define TEST_ASSERT_EQUAL_HEX32(expected, actual) TEST_ASSERT_EQUAL_HEX32_MESSAGE(expected, actual, NULL) + +#define TEST_ASSERT_EQUAL_HEX_MESSAGE(expected, actual, message) TEST_ASSERT_EQUAL_HEX32_MESSAGE(expected, actual, message) +#define TEST_ASSERT_EQUAL_HEX(expected, actual) TEST_ASSERT_EQUAL_HEX32(expected, message) + +#define TEST_ASSERT_BITS_MESSAGE(mask, expected, actual, message) \ + Unity.TestFile=__FILE__; \ + UnityAssertBits((mask), (expected), (actual), (message), (unsigned short)__LINE__); \ + RETURN_IF_NECESSARY(); +#define TEST_ASSERT_BITS(mask, expected, actual) TEST_ASSERT_BITS_MESSAGE(mask, expected, actual, NULL) + +#define TEST_ASSERT_BITS_HIGH_MESSAGE(mask, actual, message) \ + Unity.TestFile=__FILE__; \ + UnityAssertBits((mask), (-1), (actual), (message), (unsigned short)__LINE__); \ + RETURN_IF_NECESSARY(); +#define TEST_ASSERT_BITS_HIGH(mask, actual) TEST_ASSERT_BITS_HIGH_MESSAGE(mask, actual, NULL) + +#define TEST_ASSERT_BITS_LOW_MESSAGE(mask, actual, message) \ + Unity.TestFile=__FILE__; \ + UnityAssertBits((mask), (0), (actual), (message), (unsigned short)__LINE__); \ + RETURN_IF_NECESSARY(); +#define TEST_ASSERT_BITS_LOW(mask, actual) TEST_ASSERT_BITS_LOW_MESSAGE(mask, actual, NULL) + +#define TEST_ASSERT_BIT_HIGH_MESSAGE(bit, actual, message) \ + Unity.TestFile=__FILE__; \ + UnityAssertBits((1 << bit), (-1), (actual), (message), (unsigned short)__LINE__); \ + RETURN_IF_NECESSARY(); +#define TEST_ASSERT_BIT_HIGH(bit, actual) TEST_ASSERT_BIT_HIGH_MESSAGE(bit, actual, NULL) + +#define TEST_ASSERT_BIT_LOW_MESSAGE(bit, actual, message) \ + Unity.TestFile=__FILE__; \ + UnityAssertBits((1 << bit), (0), (actual), (message), (unsigned short)__LINE__); \ + RETURN_IF_NECESSARY(); +#define TEST_ASSERT_BIT_LOW(bit, actual) TEST_ASSERT_BIT_LOW_MESSAGE(bit, actual, NULL) + +#define TEST_ASSERT_FLOAT_WITHIN_MESSAGE(delta, expected, actual, message) \ + Unity.TestFile=__FILE__; \ + UnityAssertFloatsWithin((delta), (expected), (actual), (message), (unsigned short)__LINE__); \ + RETURN_IF_NECESSARY(); +#define TEST_ASSERT_FLOAT_WITHIN(delta, expected, actual) TEST_ASSERT_FLOAT_WITHIN_MESSAGE(delta, expected, actual, NULL) + +#define TEST_ASSERT_EQUAL_STRING_MESSAGE(expected, actual, message) \ + Unity.TestFile=__FILE__; \ + UnityAssertEqualString((expected), (actual), (message), (unsigned short)__LINE__); \ + RETURN_IF_NECESSARY(); +#define TEST_ASSERT_EQUAL_STRING(expected, actual) TEST_ASSERT_EQUAL_STRING_MESSAGE(expected, actual, NULL) + +#define TEST_FAIL(message) { Unity.TestFile=__FILE__; UnityFail((message), (unsigned short)__LINE__); return; } +#define TEST_IGNORE_MESSAGE(message) { Unity.TestFile=__FILE__; UnityIgnore((message), (unsigned short)__LINE__); return; } +#define TEST_IGNORE() TEST_IGNORE_MESSAGE("") + +#define TEST_PROTECT() (setjmp(AbortFrame) == 0) +#define TEST_THROW(message) { Unity.TestFile=__FILE__; UnityFail((message), (unsigned short)__LINE__); longjmp(AbortFrame, 1); } + +#endif + diff --git a/test/testunity.c b/test/testunity.c new file mode 100644 index 0000000..f90b86f --- /dev/null +++ b/test/testunity.c @@ -0,0 +1,669 @@ +#define UNITY_ENABLE_EXTERNAL_ASSERTIONS + +#include +#include "unity.h" + +void setUp(void) +{ +} + +void tearDown(void) +{ +} + +void testTrue(void) +{ + TEST_ASSERT(1); + + TEST_ASSERT_TRUE(1); +} + +void testFalse(void) +{ + TEST_ASSERT_FALSE(0); + + TEST_ASSERT_UNLESS(0); +} + +void testPreviousPass(void) +{ + TEST_ASSERT_EQUAL_INT(0U, Unity.TestFailures); +} + +void vanilla_asserter(int val) +{ + TEST_ASSERT(val); +} + +void testNotVanilla(void) +{ + int failed; + vanilla_asserter(0); + + failed = Unity.CurrentTestFailed; + Unity.CurrentTestFailed = 0; + + TEST_ASSERT_EQUAL_INT(1U, failed); + TEST_ASSERT_EQUAL_INT(0U, Unity.TestFailures); +} + +void true_asserter(int val) +{ + TEST_ASSERT_TRUE(val); +} + +void testNotTrue(void) +{ + int failed; + true_asserter(0); + + failed = Unity.CurrentTestFailed; + Unity.CurrentTestFailed = 0; + + TEST_ASSERT_EQUAL_INT(1U, failed); + TEST_ASSERT_EQUAL_INT(0U, Unity.TestFailures); +} + +void false_asserter(int val) +{ + TEST_ASSERT_FALSE(val); +} + +void testNotFalse(void) +{ + int failed; + false_asserter(1); + + failed = Unity.CurrentTestFailed; + Unity.CurrentTestFailed = 0; + + TEST_ASSERT_EQUAL_INT(1U, failed); + TEST_ASSERT_EQUAL_INT(0U, Unity.TestFailures); +} + +void unless_asserter(int val) +{ + TEST_ASSERT_UNLESS(val); +} + +void testNotUnless(void) +{ + int failed; + unless_asserter(1); + + failed = Unity.CurrentTestFailed; + Unity.CurrentTestFailed = 0; + + TEST_ASSERT_EQUAL_INT(1U, failed); + TEST_ASSERT_EQUAL_INT(0U, Unity.TestFailures); +} + +void failer(void) +{ + TEST_FAIL("Expected for testing"); +} + +void testFail(void) +{ + int failed; + failer(); + + failed = Unity.CurrentTestFailed; + Unity.CurrentTestFailed = 0; + + TEST_ASSERT_EQUAL_INT(1U, failed); + TEST_ASSERT_EQUAL_INT(0U, Unity.TestFailures); +} + +void ignorer(void) +{ + TEST_IGNORE(); + TEST_FAIL("This should not be reached"); +} + +void assertIgnoreInWrapper(void) +{ + TEST_WRAP(ignorer()); + TEST_FAIL("This should not be reached"); +} + +void testIgnoreInWrapper(void) +{ + unsigned char ignored; + assertIgnoreInWrapper(); + ignored = Unity.CurrentTestIgnored; + Unity.CurrentTestIgnored = 0; + TEST_ASSERT_EQUAL_INT(1, ignored); +} + +void testIgnore(void) +{ + int ignored; + ignorer(); + + ignored = Unity.CurrentTestIgnored; + Unity.CurrentTestIgnored = 0; + + TEST_ASSERT(ignored); +} + +void ignorerWithMessage(void) +{ + TEST_IGNORE_MESSAGE("This is an expected TEST_IGNORE_MESSAGE string!"); + TEST_FAIL("This should not be reached"); +} + +void testIgnoreMessage(void) +{ + int ignored; + ignorerWithMessage(); + + ignored = Unity.CurrentTestIgnored; + Unity.CurrentTestIgnored = 0; + + TEST_ASSERT(ignored); +} + +void assertIgnoreWithMessageInWrapper(void) +{ + TEST_WRAP(ignorerWithMessage()); + TEST_FAIL("This should not be reached"); +} + +void testIgnoreMessageInWrapper(void) +{ + unsigned char ignored; + assertIgnoreWithMessageInWrapper(); + ignored = Unity.CurrentTestIgnored; + Unity.CurrentTestIgnored = 0; + TEST_ASSERT_EQUAL_INT(1, ignored); +} + +void wrapper(void) +{ + TEST_WRAP(failer()); // if this doesn't force a return, then the failures will be incorrectly reset + Unity.CurrentTestFailed = 0; +} + +void testWrap(void) +{ + int failed; + wrapper(); + failed = Unity.CurrentTestFailed; + Unity.CurrentTestFailed = 0U; + + TEST_ASSERT_EQUAL_INT(1U, failed); +} + +void intFailer(void) +{ + TEST_ASSERT_EQUAL_INT(3982, 3983); +} + +void testNotEqualInts(void) +{ + int failed; + intFailer(); + + failed = Unity.CurrentTestFailed; + Unity.CurrentTestFailed = 0; + + TEST_ASSERT_MESSAGE(1U == failed, "This is expected"); +} + +void bitFailer(void) +{ + TEST_ASSERT_BITS(0xFF00, 0x5555, 0x5A55); +} + +void testNotEqualBits(void) +{ + int failed; + bitFailer(); + + failed = Unity.CurrentTestFailed; + Unity.CurrentTestFailed = 0; + + TEST_ASSERT_MESSAGE(1U == failed, "This is expected"); +} + +void uintFailer(void) +{ + TEST_ASSERT_EQUAL_UINT(900000, 900001); +} + +void testNotEqualUInts(void) +{ + int failed; + uintFailer(); + + failed = Unity.CurrentTestFailed; + Unity.CurrentTestFailed = 0; + + TEST_ASSERT_MESSAGE(1U == failed, "This is expected"); +} + +void hex8Failer(void) +{ + TEST_ASSERT_EQUAL_HEX8(0x23,0x22); +} + +void testNotEqualHex8s(void) +{ + int failed; + hex8Failer(); + + failed = Unity.CurrentTestFailed; + Unity.CurrentTestFailed = 0; + + TEST_ASSERT_MESSAGE(1U == failed, "This is expected"); +} + +void hex16Failer(void) +{ + TEST_ASSERT_EQUAL_HEX16(0x1234, 0x1235); +} + +void testNotEqualHex16s(void) +{ + int failed; + hex16Failer(); + + failed = Unity.CurrentTestFailed; + Unity.CurrentTestFailed = 0; + + TEST_ASSERT_MESSAGE(1U == failed, "This is expected"); +} + +void hex32Failer(void) +{ + TEST_ASSERT_EQUAL_HEX32(900000, 900001); +} + +void testNotEqualHex32s(void) +{ + int failed; + hex32Failer(); + + failed = Unity.CurrentTestFailed; + Unity.CurrentTestFailed = 0; + + TEST_ASSERT_MESSAGE(1U == failed, "This is expected"); +} + +void UnwrappedAssertion(int expected, int actual) +{ + TEST_ASSERT_EQUAL(expected,actual); +} + +void testMultipleUnwrappedAssertionsHandledAppropriately(void) +{ + int failed; + + UnwrappedAssertion(4,5); + UnwrappedAssertion(6,6); + UnwrappedAssertion(19,19); + + failed = Unity.CurrentTestFailed; + Unity.CurrentTestFailed = 0; + + TEST_ASSERT_MESSAGE(1U == failed, "This is expected"); +} + +void testEqualInts(void) +{ + int v0, v1; + int *p0, *p1; + v0 = 19467; + v1 = 19467; + p0 = &v0; + p1 = &v1; + + TEST_ASSERT_EQUAL_INT(1837, 1837); + TEST_ASSERT_EQUAL_INT(-27365, -27365); + TEST_ASSERT_EQUAL_INT(v0, v1); + TEST_ASSERT_EQUAL_INT(19467, v1); + TEST_ASSERT_EQUAL_INT(v0, 19467); + TEST_ASSERT_EQUAL_INT(*p0, v1); + TEST_ASSERT_EQUAL_INT(*p0, *p1); + TEST_ASSERT_EQUAL_INT(*p0, 19467); +} + +void testEqualUints(void) +{ + unsigned int v0, v1; + unsigned int *p0, *p1; + v0 = 19467; + v1 = 19467; + p0 = &v0; + p1 = &v1; + + TEST_ASSERT_EQUAL_UINT(1837, 1837); + TEST_ASSERT_EQUAL_UINT(v0, v1); + TEST_ASSERT_EQUAL_UINT(19467, v1); + TEST_ASSERT_EQUAL_UINT(v0, 19467); + TEST_ASSERT_EQUAL_UINT(*p0, v1); + TEST_ASSERT_EQUAL_UINT(*p0, *p1); + TEST_ASSERT_EQUAL_UINT(*p0, 19467); +} + +void testEqualHex8s(void) +{ + unsigned int v0, v1; + unsigned int *p0, *p1; + v0 = 0x22; + v1 = 0x22; + p0 = &v0; + p1 = &v1; + + TEST_ASSERT_EQUAL_HEX8(0x22, 0x22); + TEST_ASSERT_EQUAL_HEX8(v0, v1); + TEST_ASSERT_EQUAL_HEX8(0x22, v1); + TEST_ASSERT_EQUAL_HEX8(v0, 0x22); + TEST_ASSERT_EQUAL_HEX8(*p0, v1); + TEST_ASSERT_EQUAL_HEX8(*p0, *p1); + TEST_ASSERT_EQUAL_HEX8(*p0, 0x22); +} + +void testEqualHex16s(void) +{ + unsigned int v0, v1; + unsigned int *p0, *p1; + v0 = 0x9876; + v1 = 0x9876; + p0 = &v0; + p1 = &v1; + + TEST_ASSERT_EQUAL_HEX16(0x9876, 0x9876); + TEST_ASSERT_EQUAL_HEX16(v0, v1); + TEST_ASSERT_EQUAL_HEX16(0x9876, v1); + TEST_ASSERT_EQUAL_HEX16(v0, 0x9876); + TEST_ASSERT_EQUAL_HEX16(*p0, v1); + TEST_ASSERT_EQUAL_HEX16(*p0, *p1); + TEST_ASSERT_EQUAL_HEX16(*p0, 0x9876); +} + +void testEqualHex32s(void) +{ + unsigned int v0, v1; + unsigned int *p0, *p1; + v0 = 0x98765432; + v1 = 0x98765432; + p0 = &v0; + p1 = &v1; + + TEST_ASSERT_EQUAL_HEX32(0x98765432, 0x98765432); + TEST_ASSERT_EQUAL_HEX32(v0, v1); + TEST_ASSERT_EQUAL_HEX32(0x98765432, v1); + TEST_ASSERT_EQUAL_HEX32(v0, 0x98765432); + TEST_ASSERT_EQUAL_HEX32(*p0, v1); + TEST_ASSERT_EQUAL_HEX32(*p0, *p1); + TEST_ASSERT_EQUAL_HEX32(*p0, 0x98765432); +} + +void testEqualBits(void) +{ + unsigned int v0 = 0xFF55AA00; + unsigned int v1 = 0x55550000; + + TEST_ASSERT_BITS(v1, v0, 0x55550000); + TEST_ASSERT_BITS(v1, v0, 0xFF55CC00); + TEST_ASSERT_BITS(0xFFFFFFFF, v0, 0xFF55AA00); + TEST_ASSERT_BITS(0xFFFFFFFF, v0, v0); + TEST_ASSERT_BITS(0xF0F0F0F0, v0, 0xFC5DAE0F); + TEST_ASSERT_BITS_HIGH(v1, v0); + TEST_ASSERT_BITS_LOW(0x000055FF, v0); + TEST_ASSERT_BIT_HIGH(30, v0); + TEST_ASSERT_BIT_LOW(5, v0); +} + +void testEqualShorts(void) +{ + short v0, v1; + short *p0, *p1; + v0 = 19467; + v1 = 19467; + p0 = &v0; + p1 = &v1; + + TEST_ASSERT_EQUAL_INT(1837, 1837); + TEST_ASSERT_EQUAL_INT(-2987, -2987); + TEST_ASSERT_EQUAL_INT(v0, v1); + TEST_ASSERT_EQUAL_INT(19467, v1); + TEST_ASSERT_EQUAL_INT(v0, 19467); + TEST_ASSERT_EQUAL_INT(*p0, v1); + TEST_ASSERT_EQUAL_INT(*p0, *p1); + TEST_ASSERT_EQUAL_INT(*p0, 19467); +} + +void testEqualUShorts(void) +{ + unsigned short v0, v1; + unsigned short *p0, *p1; + v0 = 19467; + v1 = 19467; + p0 = &v0; + p1 = &v1; + + TEST_ASSERT_EQUAL_INT(1837, 1837); + TEST_ASSERT_EQUAL_INT(-2987, -2987); + TEST_ASSERT_EQUAL_INT(v0, v1); + TEST_ASSERT_EQUAL_INT(19467, v1); + TEST_ASSERT_EQUAL_INT(v0, 19467); + TEST_ASSERT_EQUAL_INT(*p0, v1); + TEST_ASSERT_EQUAL_INT(*p0, *p1); + TEST_ASSERT_EQUAL_INT(*p0, 19467); +} + +void testEqualChars(void) +{ + signed char v0, v1; + signed char *p0, *p1; + v0 = 109; + v1 = 109; + p0 = &v0; + p1 = &v1; + + TEST_ASSERT_EQUAL_INT(42, 42); + TEST_ASSERT_EQUAL_INT(-116, -116); + TEST_ASSERT_EQUAL_INT(v0, v1); + TEST_ASSERT_EQUAL_INT(109, v1); + TEST_ASSERT_EQUAL_INT(v0, 109); + TEST_ASSERT_EQUAL_INT(*p0, v1); + TEST_ASSERT_EQUAL_INT(*p0, *p1); + TEST_ASSERT_EQUAL_INT(*p0, 109); +} + +void testEqualUChars(void) +{ + unsigned char v0, v1; + unsigned char *p0, *p1; + v0 = 251; + v1 = 251; + p0 = &v0; + p1 = &v1; + + TEST_ASSERT_EQUAL_INT(42, 42); + TEST_ASSERT_EQUAL_INT(v0, v1); + TEST_ASSERT_EQUAL_INT(251, v1); + TEST_ASSERT_EQUAL_INT(v0, 251); + TEST_ASSERT_EQUAL_INT(*p0, v1); + TEST_ASSERT_EQUAL_INT(*p0, *p1); + TEST_ASSERT_EQUAL_INT(*p0, 251); +} + +void testEqualPointers(void) +{ + int v0, v1; + int *p0, *p1, *p2; + v0 = 19467; + v1 = 80080; + p0 = &v0; + p1 = &v1; + p2 = &v1; + + TEST_ASSERT_EQUAL_INT(p0, &v0); + TEST_ASSERT_EQUAL_INT(&v1, p1); + TEST_ASSERT_EQUAL_INT(p2, p1); + TEST_ASSERT_EQUAL_INT(&v0, &v0); +} + +void testFloatsWithinDelta(void) +{ + TEST_ASSERT_FLOAT_WITHIN(0.00003f, 187245.03485f, 187245.03488f); + TEST_ASSERT_FLOAT_WITHIN(1.0f, 187245.0f, 187246.0f); + TEST_ASSERT_FLOAT_WITHIN(0.05f, 9273.2549f, 9273.2049f); + TEST_ASSERT_FLOAT_WITHIN(0.007f, -726.93724f, -726.94424f); +} + +void floatWithinFailer(void) +{ + TEST_ASSERT_FLOAT_WITHIN(0.05f, 9273.2649f, 9273.2049f); +} + +void testFloatsNotWithinDelta(void) +{ + int failed; + floatWithinFailer(); + + failed = Unity.CurrentTestFailed; + Unity.CurrentTestFailed = 0; + + TEST_ASSERT_MESSAGE(1U == failed, "This is also expected"); +} + +void testIntsWithinDelta(void) +{ + TEST_ASSERT_INT_WITHIN(1, 5000, 5001); + TEST_ASSERT_INT_WITHIN(5, 5000, 4996); + TEST_ASSERT_INT_WITHIN(5, 5000, 5005); + TEST_ASSERT_INT_WITHIN(500, 50, -440); +} + +void intWithinFailer(void) +{ + TEST_ASSERT_INT_WITHIN(5, 5000, 5006); +} + +void testIntsNotWithinDelta(void) +{ + int failed; + intWithinFailer(); + + failed = Unity.CurrentTestFailed; + Unity.CurrentTestFailed = 0; + + TEST_ASSERT_MESSAGE(1U == failed, "This is also expected"); +} + +void testEqualStrings(void) +{ + const char *testString = "foo"; + + TEST_ASSERT_EQUAL_STRING(testString, testString); + TEST_ASSERT_EQUAL_STRING("foo", "foo"); + TEST_ASSERT_EQUAL_STRING("foo", testString); + TEST_ASSERT_EQUAL_STRING(testString, "foo"); + TEST_ASSERT_EQUAL_STRING("", ""); + TEST_ASSERT_EQUAL_INT(0U, Unity.TestFailures); +} + +void stringFailer1(void) +{ + TEST_ASSERT_EQUAL_STRING("foo", "bar"); +} + +void stringFailer2(void) +{ + TEST_ASSERT_EQUAL_STRING("foo", ""); +} + +void stringFailer3(void) +{ + TEST_ASSERT_EQUAL_STRING("", "bar"); +} + +void testNotEqualString1(void) +{ + int failed; + stringFailer1(); + + failed = Unity.CurrentTestFailed; + Unity.CurrentTestFailed = 0; + + TEST_ASSERT_MESSAGE(1U == failed, "This is also expected"); +} + +void testNotEqualString2(void) +{ + int failed; + stringFailer2(); + + failed = Unity.CurrentTestFailed; + Unity.CurrentTestFailed = 0; + + TEST_ASSERT_MESSAGE(1U == failed, "This is also expected"); +} + +void testNotEqualString3(void) +{ + int failed; + stringFailer3(); + + failed = Unity.CurrentTestFailed; + Unity.CurrentTestFailed = 0; + + TEST_ASSERT_MESSAGE(1U == failed, "This is also expected"); +} + +void stringFailer_ExpectedStringIsNull(void) +{ + TEST_ASSERT_EQUAL_STRING(NULL, "bar"); +} + +void testNotEqualString_ExpectedStringIsNull(void) +{ + int failed; + stringFailer_ExpectedStringIsNull(); + + failed = Unity.CurrentTestFailed; + Unity.CurrentTestFailed = 0; + + TEST_ASSERT_MESSAGE(1U == failed, "This is also expected"); +} + +void stringFailer_ActualStringIsNull(void) +{ + TEST_ASSERT_EQUAL_STRING("foo", NULL); +} + +void testNotEqualString_ActualStringIsNull(void) +{ + int failed; + stringFailer_ActualStringIsNull(); + + failed = Unity.CurrentTestFailed; + Unity.CurrentTestFailed = 0; + + TEST_ASSERT_MESSAGE(1U == failed, "This is also expected"); +} + +void testProtection(void) +{ + volatile int mask = 0; + jmp_buf AbortFrame; + + if (TEST_PROTECT()) + { + mask |= 1; + TEST_THROW("This throw was expected"); + } + else + { + Unity.CurrentTestFailed = 0; + mask |= 2; + } + + TEST_ASSERT_EQUAL(3, mask); +} + diff --git a/test/testunity_Runner.c b/test/testunity_Runner.c new file mode 100644 index 0000000..8850b94 --- /dev/null +++ b/test/testunity_Runner.c @@ -0,0 +1,111 @@ +#define UNITY_ENABLE_EXTERNAL_ASSERTIONS + +#include +#include "unity.h" + +void setUp(void); +void tearDown(void); + +void testTrue(void); +void testFalse(void); +void testPreviousPass(void); +void testNotVanilla(void); +void testNotTrue(void); +void testNotFalse(void); +void testNotUnless(void); +void testFail(void); +void testIgnoreInWrapper(void); +void testIgnore(void); +void testIgnoreMessage(void); +void testIgnoreMessageInWrapper(void); +void testWrap(void); +void testNotEqualInts(void); +void testNotEqualBits(void); +void testNotEqualUInts(void); +void testNotEqualHex8s(void); +void testNotEqualHex16s(void); +void testNotEqualHex32s(void); +void testMultipleUnwrappedAssertionsHandledAppropriately(void); +void testEqualInts(void); +void testEqualUints(void); +void testEqualHex8s(void); +void testEqualHex16s(void); +void testEqualHex32s(void); +void testEqualBits(void); +void testEqualShorts(void); +void testEqualUShorts(void); +void testEqualChars(void); +void testEqualUChars(void); +void testEqualPointers(void); +void testFloatsWithinDelta(void); +void testFloatsNotWithinDelta(void); +void testIntsWithinDelta(void); +void testIntsNotWithinDelta(void); +void testEqualStrings(void); +void testNotEqualString1(void); +void testNotEqualString2(void); +void testNotEqualString3(void); +void testNotEqualString_ExpectedStringIsNull(void); +void testNotEqualString_ActualStringIsNull(void); +void testProtection(void); + + +static void runTest(UnityTestFunction test) +{ + setUp(); + test(); + tearDown(); +} + +int main(void) +{ + Unity.TestFile = __FILE__; + UnityBegin(); + + // RUN_TEST calls runTest + RUN_TEST(testTrue); + RUN_TEST(testFalse); + RUN_TEST(testNotVanilla); + RUN_TEST(testNotTrue); + RUN_TEST(testNotFalse); + RUN_TEST(testNotUnless); + RUN_TEST(testPreviousPass); + RUN_TEST(testFail); + RUN_TEST(testWrap); + RUN_TEST(testIgnoreInWrapper); + RUN_TEST(testIgnore); + RUN_TEST(testIgnoreMessage); + RUN_TEST(testIgnoreMessageInWrapper); + RUN_TEST(testNotEqualBits); + RUN_TEST(testNotEqualInts); + RUN_TEST(testNotEqualUInts); + RUN_TEST(testNotEqualHex8s); + RUN_TEST(testNotEqualHex16s); + RUN_TEST(testNotEqualHex32s); + RUN_TEST(testMultipleUnwrappedAssertionsHandledAppropriately); + RUN_TEST(testEqualBits); + RUN_TEST(testEqualInts); + RUN_TEST(testEqualUints); + RUN_TEST(testEqualHex8s); + RUN_TEST(testEqualHex16s); + RUN_TEST(testEqualHex32s); + RUN_TEST(testEqualShorts); + RUN_TEST(testEqualUShorts); + RUN_TEST(testEqualChars); + RUN_TEST(testEqualUChars); + RUN_TEST(testEqualPointers); + RUN_TEST(testEqualStrings); + RUN_TEST(testIntsWithinDelta); + RUN_TEST(testIntsNotWithinDelta); + RUN_TEST(testFloatsWithinDelta); + RUN_TEST(testFloatsNotWithinDelta); + RUN_TEST(testNotEqualString1); + RUN_TEST(testNotEqualString2); + RUN_TEST(testNotEqualString3); + RUN_TEST(testNotEqualString_ExpectedStringIsNull); + RUN_TEST(testNotEqualString_ActualStringIsNull); + RUN_TEST(testProtection); + + UnityEnd(); + return 0; +}