commit 720acfbb953a6f23803d0242d23fde65b6d131fd Author: greg-williams Date: Thu Feb 7 03:00:54 2008 +0000 Initial project population git-svn-id: http://unity.svn.sourceforge.net/svnroot/unity/trunk@1 e7d17a6e-8845-0410-bbbc-c8efb4fdad7e 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 0000000..fb5745e Binary files /dev/null and b/docs/Unity Summary.odt differ diff --git a/docs/Unity Summary.pdf b/docs/Unity Summary.pdf new file mode 100644 index 0000000..2ddf129 Binary files /dev/null and b/docs/Unity Summary.pdf differ 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; +}