diff --git a/docs/license.txt b/docs/license.txt index a5e9487..e2ef951 100644 --- a/docs/license.txt +++ b/docs/license.txt @@ -1,4 +1,4 @@ - Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams + Copyright (c) 2007-2010 Mike Karlesky, Mark VanderVoord, Greg Williams Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation diff --git a/extras/fixture/rakefile.rb b/extras/fixture/rakefile.rb new file mode 100644 index 0000000..fbff3bd --- /dev/null +++ b/extras/fixture/rakefile.rb @@ -0,0 +1,37 @@ +# ========================================== +# Unity Project - A Test Framework for C +# Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams +# [Released under MIT License. Please refer to license.txt for details] +# ========================================== + +HERE = File.expand_path(File.dirname(__FILE__)) + '/' + +require 'rake' +require 'rake/clean' +require 'rake/testtask' +require HERE + 'rakefile_helper' + +include RakefileHelpers + +# Load default configuration, for now +DEFAULT_CONFIG_FILE = 'gcc.yml' +configure_toolchain(DEFAULT_CONFIG_FILE) + +task :unit do + run_tests +end + +desc "Build and test Unity Framework" +task :all => [:clean, :unit] +task :default => [:clobber, :all] +task :ci => [:no_color, :default] +task :cruise => [:no_color, :default] + +desc "Load configuration" +task :config, :config_file do |t, args| + configure_toolchain(args[:config_file]) +end + +task :no_color do + $colour_output = false +end diff --git a/extras/fixture/rakefile_helper.rb b/extras/fixture/rakefile_helper.rb new file mode 100644 index 0000000..7e7c801 --- /dev/null +++ b/extras/fixture/rakefile_helper.rb @@ -0,0 +1,176 @@ +# ========================================== +# Unity Project - A Test Framework for C +# Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams +# [Released under MIT License. Please refer to license.txt for details] +# ========================================== + +require 'yaml' +require 'fileutils' +require HERE+'../../auto/unity_test_summary' +require HERE+'../../auto/generate_test_runner' +require HERE+'../../auto/colour_reporter' + +module RakefileHelpers + + C_EXTENSION = '.c' + + def load_configuration(config_file) + $cfg_file = HERE+"../../targets/#{config_file}" unless $cfg_file =~ /[\\|\/]/ + $cfg = YAML.load(File.read($cfg_file)) + $colour_output = false unless $cfg['colour'] + end + + def configure_clean + CLEAN.include($cfg['compiler']['build_path'] + '*.*') unless $cfg['compiler']['build_path'].nil? + end + + def configure_toolchain(config_file=DEFAULT_CONFIG_FILE) + config_file += '.yml' unless config_file =~ /\.yml$/ + config_file = config_file unless config_file =~ /[\\|\/]/ + load_configuration(config_file) + configure_clean + end + + def tackit(strings) + if strings.is_a?(Array) + result = "\"#{strings.join}\"" + else + result = strings + end + return result + end + + def squash(prefix, items) + result = '' + items.each { |item| result += " #{prefix}#{tackit(item)}" } + return result + end + + def build_compiler_fields + command = tackit($cfg['compiler']['path']) + if $cfg['compiler']['defines']['items'].nil? + defines = '' + else + defines = squash($cfg['compiler']['defines']['prefix'], $cfg['compiler']['defines']['items'] + ['UNITY_OUTPUT_CHAR=UnityOutputCharSpy_OutputChar']) + end + options = squash('', $cfg['compiler']['options']) + includes = squash($cfg['compiler']['includes']['prefix'], $cfg['compiler']['includes']['items']) + includes = includes.gsub(/\\ /, ' ').gsub(/\\\"/, '"').gsub(/\\$/, '') # Remove trailing slashes (for IAR) + return {:command => command, :defines => defines, :options => options, :includes => includes} + end + + def compile(file, defines=[]) + compiler = build_compiler_fields + unity_include = $cfg['compiler']['includes']['prefix']+'../../src' + cmd_str = "#{compiler[:command]}#{compiler[:defines]}#{compiler[:options]}#{compiler[:includes]} #{unity_include} #{file} " + + "#{$cfg['compiler']['object_files']['prefix']}#{$cfg['compiler']['object_files']['destination']}" + + "#{File.basename(file, C_EXTENSION)}#{$cfg['compiler']['object_files']['extension']}" + execute(cmd_str) + end + + def build_linker_fields + command = tackit($cfg['linker']['path']) + if $cfg['linker']['options'].nil? + options = '' + else + options = squash('', $cfg['linker']['options']) + end + if ($cfg['linker']['includes'].nil? || $cfg['linker']['includes']['items'].nil?) + includes = '' + else + includes = squash($cfg['linker']['includes']['prefix'], $cfg['linker']['includes']['items']) + end + includes = includes.gsub(/\\ /, ' ').gsub(/\\\"/, '"').gsub(/\\$/, '') # Remove trailing slashes (for IAR) + return {:command => command, :options => options, :includes => includes} + end + + def link(exe_name, obj_list) + linker = build_linker_fields + cmd_str = "#{linker[:command]}#{linker[:options]}#{linker[:includes]} " + + (obj_list.map{|obj|"#{$cfg['linker']['object_files']['path']}#{obj} "}).join + + $cfg['linker']['bin_files']['prefix'] + ' ' + + $cfg['linker']['bin_files']['destination'] + + exe_name + $cfg['linker']['bin_files']['extension'] + execute(cmd_str) + end + + def build_simulator_fields + return nil if $cfg['simulator'].nil? + if $cfg['simulator']['path'].nil? + command = '' + else + command = (tackit($cfg['simulator']['path']) + ' ') + end + if $cfg['simulator']['pre_support'].nil? + pre_support = '' + else + pre_support = squash('', $cfg['simulator']['pre_support']) + end + if $cfg['simulator']['post_support'].nil? + post_support = '' + else + post_support = squash('', $cfg['simulator']['post_support']) + end + return {:command => command, :pre_support => pre_support, :post_support => post_support} + end + + def execute(command_string, verbose=true) + report command_string + output = `#{command_string}`.chomp + report(output) if (verbose && !output.nil? && (output.length > 0)) + if ($?.exitstatus != 0) + raise "Command failed. (Returned #{$?.exitstatus})" + end + return output + end + + def report_summary + summary = UnityTestSummary.new + summary.set_root_path(HERE) + results_glob = "#{$cfg['compiler']['build_path']}*.test*" + results_glob.gsub!(/\\/, '/') + results = Dir[results_glob] + summary.set_targets(results) + summary.run + end + + def run_tests + report 'Running Unity system tests...' + + # Tack on TEST define for compiling unit tests + load_configuration($cfg_file) + test_defines = ['TEST'] + $cfg['compiler']['defines']['items'] = [] if $cfg['compiler']['defines']['items'].nil? + + # Get a list of all source files needed + src_files = Dir[HERE+'src/*.c'] + src_files += Dir[HERE+'test/*.c'] + src_files << '../../src/Unity.c' + + # Build object files + src_files.each { |f| compile(f, test_defines) } + obj_list = src_files.map {|f| File.basename(f.ext($cfg['compiler']['object_files']['extension'])) } + + # Link the test executable + test_base = "framework_test" + link(test_base, obj_list) + + # Execute unit test and generate results file + simulator = build_simulator_fields + executable = $cfg['linker']['bin_files']['destination'] + test_base + $cfg['linker']['bin_files']['extension'] + if simulator.nil? + cmd_str = executable + " -v -r 8" + else + cmd_str = "#{simulator[:command]} #{simulator[:pre_support]} #{executable} #{simulator[:post_support]}" + end + output = execute(cmd_str) + test_results = $cfg['compiler']['build_path'] + test_base + if output.match(/OK$/m).nil? + test_results += '.testfail' + else + test_results += '.testpass' + end + File.open(test_results, 'w') { |f| f.print output } + puts output + end +end diff --git a/extras/fixture/readme.txt b/extras/fixture/readme.txt new file mode 100644 index 0000000..6b9a78c --- /dev/null +++ b/extras/fixture/readme.txt @@ -0,0 +1,9 @@ +Copyright (c) 2010 James Grenning and Contributed to Unity Project + +Unity Project - A Test Framework for C +Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams +[Released under MIT License. Please refer to license.txt for details] + +This Framework is an optional add-on to Unity. By including unity_framework.h in place of unity.h, +you may now work with Unity in a manner similar to CppUTest. This framework adds the concepts of +test groups and gives finer control of your tests over the command line. \ No newline at end of file diff --git a/extras/fixture/src/unity_fixture.c b/extras/fixture/src/unity_fixture.c new file mode 100644 index 0000000..d4c6e82 --- /dev/null +++ b/extras/fixture/src/unity_fixture.c @@ -0,0 +1,359 @@ +//- Copyright (c) 2010 James Grenning and Contributed to Unity Project +/* ========================================== + Unity Project - A Test Framework for C + Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams + [Released under MIT License. Please refer to license.txt for details] +========================================== */ + +#include "unity_fixture.h" +#include "unity_internals.h" +#include + +UNITY_FIXTURE_T UnityFixture; + +//If you decide to use the function pointer approach. +int (*outputChar)(int) = putchar; + +int verbose = 0; + +void setUp(void) { /*does nothing*/ } +void tearDown(void) { /*does nothing*/ } + +void announceTestRun(int runNumber) +{ + UnityPrint("Unity test run "); + UnityPrintNumber(runNumber+1); + UnityPrint(" of "); + UnityPrintNumber(UnityFixture.RepeatCount); + UNITY_OUTPUT_CHAR('\n'); +} + +int UnityMain(int argc, char* argv[], void (*runAllTests)()) +{ + int result = UnityGetCommandLineOptions(argc, argv); + int r; + if (result != 0) + return result; + + for (r = 0; r < UnityFixture.RepeatCount; r++) + { + announceTestRun(r); + UnityBegin(); + runAllTests(); + UNITY_OUTPUT_CHAR('\n'); + UnityEnd(); + } + + return UnityFailureCount(); +} + +static int selected(const char * filter, const char * name) +{ + if (filter == 0) + return 1; + return strstr(name, filter) ? 1 : 0; +} + +static int testSelected(const char* test) +{ + return selected(UnityFixture.NameFilter, test); +} + +static int groupSelected(const char* group) +{ + return selected(UnityFixture.GroupFilter, group); +} + +static void runTestCase() +{ + +} + +void UnityTestRunner(unityfunction* setup, + unityfunction* testBody, + unityfunction* teardown, + const char * printableName, + const char * group, + const char * name, + const char * file, int line) +{ + if (testSelected(name) && groupSelected(group)) + { + Unity.CurrentTestFailed = 0; + Unity.TestFile = file; + Unity.CurrentTestName = printableName; + Unity.CurrentTestLineNumber = line; + if (!UnityFixture.Verbose) + UNITY_OUTPUT_CHAR('.'); + else + UnityPrint(printableName); + + Unity.NumberOfTests++; + UnityMalloc_StartTest(); + UnityPointer_Init(); + + runTestCase(); + if (TEST_PROTECT()) + { + setup(); + testBody(); + } + if (TEST_PROTECT()) + { + teardown(); + } + if (TEST_PROTECT()) + { + UnityPointer_UndoAllSets(); + if (!Unity.CurrentTestFailed) + UnityMalloc_EndTest(); + UnityConcludeFixtureTest(); + } + else + { + //aborting - jwg - di i need these for the other TEST_PROTECTS? + } + } +} + + +//------------------------------------------------- +//Malloc and free stuff +// +#define MALLOC_DONT_FAIL -1 +static int malloc_count; +static int malloc_fail_countdown = MALLOC_DONT_FAIL; + +void UnityMalloc_StartTest() +{ + malloc_count = 0; + malloc_fail_countdown = MALLOC_DONT_FAIL; +} + +void UnityMalloc_EndTest() +{ + malloc_fail_countdown = MALLOC_DONT_FAIL; + if (malloc_count != 0) + { + TEST_FAIL_MESSAGE("This test leaks!"); + } +} + +void UnityMalloc_MakeMallocFailAfterCount(int countdown) +{ + malloc_fail_countdown = countdown; +} + +#ifdef malloc +#undef malloc +#endif + +#ifdef free +#undef free +#endif + +#include +#include + +typedef struct GuardBytes +{ + int size; + char guard[sizeof(int)]; +} Guard; + + +static const char * end = "END"; + +void * unity_malloc(size_t size) +{ + char* mem; + Guard* guard; + + if (malloc_fail_countdown != MALLOC_DONT_FAIL) + { + if (malloc_fail_countdown == 0) + return 0; + malloc_fail_countdown--; + } + + malloc_count++; + + guard = (Guard*)malloc(size + sizeof(Guard) + 4); + guard->size = size; + mem = (char*)&(guard[1]); + memcpy(&mem[size], end, strlen(end) + 1); + + return (void*)mem; +} + +void unity_free(void * mem) +{ + Guard* guard = (Guard*)mem; + char* memAsChar = (char*)mem; + guard--; + if (strcmp(&memAsChar[guard->size], end) != 0) + { + TEST_FAIL_MESSAGE("Buffer overrun detected during free()"); + } + + malloc_count--; + free((void*)guard); +} + +void* unity_calloc(size_t num, size_t size) +{ + void* mem = unity_malloc(num * size); + memset(mem, 0, num*size); + return mem; +} + +void* unity_realloc(void * oldMem, size_t size) +{ + Guard* guard = (Guard*)oldMem; + char* memAsChar = (char*)oldMem; + void* newMem; + + if (oldMem == 0) + return unity_malloc(size); + + guard--; + if (strcmp(&memAsChar[guard->size], end) != 0) + { + TEST_FAIL_MESSAGE("Buffer overrun detected during realloc()"); + } + + if (size == 0) + { + unity_free(oldMem); + return 0; + } + + if (guard->size >= size) + return oldMem; + + newMem = unity_malloc(size); + memcpy(newMem, oldMem, size); + unity_free(oldMem); + return newMem; +} + + +//-------------------------------------------------------- +//Automatic pointer restoration functions +typedef struct _PointerPair +{ + struct _PointerPair * next; + void ** pointer; + void * old_value; +} PointerPair; + +enum {MAX_POINTERS=50}; +static PointerPair pointer_store[MAX_POINTERS]; +static int pointer_index = 0; + +void UnityPointer_Init() +{ + pointer_index = 0; +} + +void UnityPointer_Set(void ** pointer, void * newValue) +{ + if (pointer_index >= MAX_POINTERS) + TEST_FAIL_MESSAGE("Too many pointers set"); + + pointer_store[pointer_index].pointer = pointer; + pointer_store[pointer_index].old_value = *pointer; + *pointer = newValue; + pointer_index++; +} + +void UnityPointer_UndoAllSets() +{ + while (pointer_index > 0) + { + pointer_index--; + *(pointer_store[pointer_index].pointer) = + pointer_store[pointer_index].old_value; + + } +} + +int UnityFailureCount() +{ + return Unity.TestFailures; +} + +int UnityGetCommandLineOptions(int argc, char* argv[]) +{ + int i; + UnityFixture.Verbose = 0; + UnityFixture.GroupFilter = 0; + UnityFixture.NameFilter = 0; + UnityFixture.RepeatCount = 1; + + if (argc == 1) + return 0; + + for (i = 1; i < argc; ) + { + if (strcmp(argv[i], "-v") == 0) + { + UnityFixture.Verbose = 1; + i++; + } + else if (strcmp(argv[i], "-g") == 0) + { + i++; + if (i >= argc) + return 1; + UnityFixture.GroupFilter = argv[i]; + i++; + } + else if (strcmp(argv[i], "-n") == 0) + { + i++; + if (i >= argc) + return 1; + UnityFixture.NameFilter = argv[i]; + i++; + } + else if (strcmp(argv[i], "-r") == 0) + { + UnityFixture.RepeatCount = 2; + i++; + if (i < argc) + { + if (*(argv[i]) >= '0' && *(argv[i]) <= '9') + { + UnityFixture.RepeatCount = atoi(argv[i]); + i++; + } + } + } + } + return 0; +} + +void UnityConcludeFixtureTest() +{ + if (Unity.CurrentTestIgnored) + { + Unity.TestIgnores++; + } + else if (!Unity.CurrentTestFailed) + { + if (UnityFixture.Verbose) + { + UnityPrint(" PASS"); + UNITY_OUTPUT_CHAR('\n'); + } + } + else if (Unity.CurrentTestFailed) + { + Unity.TestFailures++; + } + + Unity.CurrentTestFailed = 0; + Unity.CurrentTestIgnored = 0; +} + diff --git a/extras/fixture/src/unity_fixture.h b/extras/fixture/src/unity_fixture.h new file mode 100644 index 0000000..34e62c6 --- /dev/null +++ b/extras/fixture/src/unity_fixture.h @@ -0,0 +1,80 @@ +//- Copyright (c) 2010 James Grenning and Contributed to Unity Project +/* ========================================== + Unity Project - A Test Framework for C + Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams + [Released under MIT License. Please refer to license.txt for details] +========================================== */ + +#ifndef UNITY_FIXTURE_H_ +#define UNITY_FIXTURE_H_ + +#include "unity.h" +#include "unity_internals.h" +#include "unity_fixture_malloc_overrides.h" +#include "unity_fixture_internals.h" + +int UnityMain(int argc, char* argv[], void (*runAllTests)()); + + +#define TEST_GROUP(group)\ + int TEST_GROUP_##group = 0 + +#define TEST_SETUP(group) void TEST_##group##_SETUP() + +#define TEST_TEAR_DOWN(group) void TEST_##group##_TEAR_DOWN() + + +#define TEST(group, name) \ + void TEST_##group##_##name##_testBody();\ + void TEST_##group##_##name##_run()\ + {\ + UnityTestRunner(TEST_##group##_SETUP,\ + TEST_##group##_##name##_testBody,\ + TEST_##group##_TEAR_DOWN,\ + "TEST(" #group ", " #name ")",\ + #group, #name,\ + __FILE__, __LINE__);\ + }\ + void TEST_##group##_##name##_testBody() + +#define IGNORE_TEST(group, name) \ + void TEST_##group##_##name##_testBody();\ + void TEST_##group##_##name##_run()\ + {\ + }\ + void TEST_##group##_##name##_testBody() + +#define DECLARE_TEST_CASE(group, name) \ + void TEST_##group##_##name##_run() + +#define RUN_TEST_CASE(group, name) \ + DECLARE_TEST_CASE(group, name);\ + TEST_##group##_##name##_run(); + +//This goes at the bottom of each test file or in a separate c file +#define TEST_GROUP_RUNNER(group)\ + void TEST_##group##_GROUP_RUNNER_runAll();\ + void TEST_##group##_GROUP_RUNNER()\ + {\ + TEST_##group##_GROUP_RUNNER_runAll();\ + }\ + void TEST_##group##_GROUP_RUNNER_runAll() + +//Call this from main +#define RUN_TEST_GROUP(group)\ + void TEST_##group##_GROUP_RUNNER();\ + TEST_##group##_GROUP_RUNNER(); + +//CppUTest Compatibility Macros +#define UT_PTR_SET(ptr, newPointerValue) UnityPointer_Set((void**)&ptr, (void*)newPointerValue) +#define TEST_ASSERT_POINTERS_EQUAL(expected, actual) TEST_ASSERT_EQUAL_PTR(expected, actual) +#define TEST_ASSERT_BYTES_EQUAL(expected, actual) TEST_ASSERT_EQUAL_HEX8(0xff & (expected), 0xff & (actual)) +#define FAIL(message) TEST_FAIL((message)) +#define CHECK(condition) TEST_ASSERT_TRUE((condition)) +#define LONGS_EQUAL(expected, actual) TEST_ASSERT_EQUAL_INT((expected), (actual)) +#define STRCMP_EQUAL(expected, actual) TEST_ASSERT_EQUAL_STRING((expected), (actual)) +#define DOUBLES_EQUAL(expected, actual, delta) TEST_ASSERT_FLOAT_WITHIN(((expected), (actual), (delta)) + +void UnityMalloc_MakeMallocFailAfterCount(int count); + +#endif /* UNITY_FIXTURE_H_ */ diff --git a/extras/fixture/src/unity_fixture_internals.h b/extras/fixture/src/unity_fixture_internals.h new file mode 100644 index 0000000..314ab0d --- /dev/null +++ b/extras/fixture/src/unity_fixture_internals.h @@ -0,0 +1,43 @@ +//- Copyright (c) 2010 James Grenning and Contributed to Unity Project +/* ========================================== + Unity Project - A Test Framework for C + Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams + [Released under MIT License. Please refer to license.txt for details] +========================================== */ + +#ifndef UNITY_FIXTURE_INTERNALS_H_ +#define UNITY_FIXTURE_INTERNALS_H_ + +typedef struct _UNITY_FIXTURE_T +{ + int Verbose; + unsigned int RepeatCount; + const char* NameFilter; + const char* GroupFilter; +} UNITY_FIXTURE_T; + +typedef void unityfunction(); +void UnityTestRunner(unityfunction * setup, + unityfunction * body, + unityfunction * teardown, + const char * printableName, + const char * group, + const char * name, + const char * file, int line); + +void UnityMalloc_StartTest(); +void UnityMalloc_EndTest(); +int UnityFailureCount(); +int UnityGetCommandLineOptions(int argc, char* argv[]); +void UnityConcludeFixtureTest(); + +void UnityPointer_Set(void ** ptr, void * newValue); +void UnityPointer_UndoAllSets(); +void UnityPointer_Init(); + +void UnityAssertEqualPointer(const void * expected, + const void * actual, + const char* msg, + const UNITY_LINE_TYPE lineNumber); + +#endif /* UNITY_FIXTURE_INTERNALS_H_ */ diff --git a/extras/fixture/src/unity_fixture_malloc_overrides.h b/extras/fixture/src/unity_fixture_malloc_overrides.h new file mode 100644 index 0000000..38f8e34 --- /dev/null +++ b/extras/fixture/src/unity_fixture_malloc_overrides.h @@ -0,0 +1,16 @@ +//- Copyright (c) 2010 James Grenning and Contributed to Unity Project +/* ========================================== + Unity Project - A Test Framework for C + Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams + [Released under MIT License. Please refer to license.txt for details] +========================================== */ + +#ifndef UNITY_FIXTURE_MALLOC_OVERRIDES_H_ +#define UNITY_FIXTURE_MALLOC_OVERRIDES_H_ + +#define malloc unity_malloc +#define calloc unity_calloc +#define realloc unity_realloc +#define free unity_free + +#endif /* UNITY_FIXTURE_MALLOC_OVERRIDES_H_ */ diff --git a/extras/fixture/test/AllTests.c b/extras/fixture/test/AllTests.c new file mode 100644 index 0000000..ccb775b --- /dev/null +++ b/extras/fixture/test/AllTests.c @@ -0,0 +1,21 @@ +//- Copyright (c) 2010 James Grenning and Contributed to Unity Project +/* ========================================== + Unity Project - A Test Framework for C + Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams + [Released under MIT License. Please refer to license.txt for details] +========================================== */ + +#include "unity_fixture.h" + +static void runAllTests() +{ + RUN_TEST_GROUP(UnityFixture); + RUN_TEST_GROUP(UnityCommandOptions); + RUN_TEST_GROUP(LeakDetection) +} + +int main(int argc, char* argv[]) +{ + return UnityMain(argc, argv, runAllTests); +} + diff --git a/extras/fixture/test/testunity_fixture.c b/extras/fixture/test/testunity_fixture.c new file mode 100644 index 0000000..de0c04c --- /dev/null +++ b/extras/fixture/test/testunity_fixture.c @@ -0,0 +1,39 @@ +//- Copyright (c) 2010 James Grenning and Contributed to Unity Project +/* ========================================== + Unity Project - A Test Framework for C + Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams + [Released under MIT License. Please refer to license.txt for details] +========================================== */ + +#include "unity_fixture.h" + +static int data = -1; + +TEST_GROUP(mygroup); + +TEST_SETUP(mygroup) +{ + data = 0; +} + +TEST_TEAR_DOWN(mygroup) +{ + data = -1; +} + +TEST(mygroup, test1) +{ + TEST_ASSERT_EQUAL_INT(0, data); +} + +TEST(mygroup, test2) +{ + TEST_ASSERT_EQUAL_INT(0, data); + data = 5; +} + +TEST(mygroup, test3) +{ + data = 7; + TEST_ASSERT_EQUAL_INT(7, data); +} diff --git a/extras/fixture/test/unity_fixture_Test.c b/extras/fixture/test/unity_fixture_Test.c new file mode 100644 index 0000000..915f6e8 --- /dev/null +++ b/extras/fixture/test/unity_fixture_Test.c @@ -0,0 +1,325 @@ +//- Copyright (c) 2010 James Grenning and Contributed to Unity Project +/* ========================================== + Unity Project - A Test Framework for C + Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams + [Released under MIT License. Please refer to license.txt for details] +========================================== */ + +#include "unity_fixture.h" +#include "unity_output_Spy.h" +#include +#include + +extern UNITY_FIXTURE_T UnityFixture; + +TEST_GROUP(UnityFixture); + +TEST_SETUP(UnityFixture) +{ +} + +TEST_TEAR_DOWN(UnityFixture) +{ +} + +int my_int; +int* pointer1 = 0; +int* pointer2 = (int*)2; +int* pointer3 = (int*)3; +int int1; +int int2; +int int3; +int int4; + +TEST(UnityFixture, PointerSetting) +{ + TEST_ASSERT_POINTERS_EQUAL(pointer1, 0); + UT_PTR_SET(pointer1, &int1); + UT_PTR_SET(pointer2, &int2); + UT_PTR_SET(pointer3, &int3); + TEST_ASSERT_POINTERS_EQUAL(pointer1, &int1); + TEST_ASSERT_POINTERS_EQUAL(pointer2, &int2); + TEST_ASSERT_POINTERS_EQUAL(pointer3, &int3); + UT_PTR_SET(pointer1, &int4); + UnityPointer_UndoAllSets(); + TEST_ASSERT_POINTERS_EQUAL(pointer1, 0); + TEST_ASSERT_POINTERS_EQUAL(pointer2, (int*)2); + TEST_ASSERT_POINTERS_EQUAL(pointer3, (int*)3); +} + +TEST(UnityFixture, ForceMallocFail) +{ + UnityMalloc_MakeMallocFailAfterCount(1); + void* m = malloc(10); + CHECK(m); + void* mfails = malloc(10); + TEST_ASSERT_POINTERS_EQUAL(0, mfails); + free(m); +} + +TEST(UnityFixture, ReallocSmallerIsUnchanged) +{ + void* m1 = malloc(10); + void* m2 = realloc(m1, 5); + TEST_ASSERT_POINTERS_EQUAL(m1, m2); + free(m2); +} + +TEST(UnityFixture, ReallocSameIsUnchanged) +{ + void* m1 = malloc(10); + void* m2 = realloc(m1, 10); + TEST_ASSERT_POINTERS_EQUAL(m1, m2); + free(m2); +} + +TEST(UnityFixture, ReallocLargerNeeded) +{ + void* m1 = malloc(10); + strcpy((char*)m1, "123456789"); + void* m2 = realloc(m1, 15); + CHECK(m1 != m2); + STRCMP_EQUAL("123456789", m2); + free(m2); +} + +TEST(UnityFixture, ReallocNullPointerIsLikeMalloc) +{ + void* m = realloc(0, 15); + CHECK(m != 0); + free(m); +} + +TEST(UnityFixture, ReallocSizeZeroFreesMemAndReturnsNullPointer) +{ + void* m1 = malloc(10); + void* m2 = realloc(m1, 0); + TEST_ASSERT_POINTERS_EQUAL(0, m2); +} + +TEST(UnityFixture, CallocFillsWithZero) +{ + void* m = calloc(3, sizeof(char)); + char* s = (char*)m; + TEST_ASSERT_BYTES_EQUAL(0, s[0]); + TEST_ASSERT_BYTES_EQUAL(0, s[1]); + TEST_ASSERT_BYTES_EQUAL(0, s[2]); + free(m); +} + +char *p1; +char *p2; + +TEST(UnityFixture, PointerSet) +{ + char c1; + char c2; + char newC1; + char newC2; + p1 = &c1; + p2 = &c2; + + UnityPointer_Init(10); + UT_PTR_SET(p1, &newC1); + UT_PTR_SET(p2, &newC2); + TEST_ASSERT_POINTERS_EQUAL(&newC1, p1); + TEST_ASSERT_POINTERS_EQUAL(&newC2, p2); + UnityPointer_UndoAllSets(); + TEST_ASSERT_POINTERS_EQUAL(&c1, p1); + TEST_ASSERT_POINTERS_EQUAL(&c2, p2); +} + +//------------------------------------------------------------ + +TEST_GROUP(UnityCommandOptions); + +int savedVerbose; +int savedRepeat; +const char* savedName; +const char* savedGroup; + +TEST_SETUP(UnityCommandOptions) +{ + savedVerbose = UnityFixture.Verbose; + savedRepeat = UnityFixture.RepeatCount; + savedName = UnityFixture.NameFilter; + savedGroup = UnityFixture.GroupFilter; +} + +TEST_TEAR_DOWN(UnityCommandOptions) +{ + UnityFixture.Verbose = savedVerbose; + UnityFixture.RepeatCount= savedRepeat; + UnityFixture.NameFilter = savedName; + UnityFixture.GroupFilter = savedGroup; +} + + +static char* noOptions[] = { + "testrunner.exe" +}; + +TEST(UnityCommandOptions, DefaultOptions) +{ + UnityGetCommandLineOptions(1, noOptions); + TEST_ASSERT_EQUAL(0, UnityFixture.Verbose); + TEST_ASSERT_POINTERS_EQUAL(0, UnityFixture.GroupFilter); + TEST_ASSERT_POINTERS_EQUAL(0, UnityFixture.NameFilter); + TEST_ASSERT_EQUAL(1, UnityFixture.RepeatCount); +} + +static char* verbose[] = { + "testrunner.exe", + "-v" +}; + +TEST(UnityCommandOptions, OptionVerbose) +{ + TEST_ASSERT_EQUAL(0, UnityGetCommandLineOptions(2, verbose)); + TEST_ASSERT_EQUAL(1, UnityFixture.Verbose); +} + +static char* group[] = { + "testrunner.exe", + "-g", "groupname" +}; + +TEST(UnityCommandOptions, OptionSelectTestByGroup) +{ + TEST_ASSERT_EQUAL(0, UnityGetCommandLineOptions(3, group)); + STRCMP_EQUAL("groupname", UnityFixture.GroupFilter); +} + +static char* name[] = { + "testrunner.exe", + "-n", "testname" +}; + +TEST(UnityCommandOptions, OptionSelectTestByName) +{ + TEST_ASSERT_EQUAL(0, UnityGetCommandLineOptions(3, name)); + STRCMP_EQUAL("testname", UnityFixture.NameFilter); +} + +static char* repeat[] = { + "testrunner.exe", + "-r", "99" +}; + +TEST(UnityCommandOptions, OptionSelectRepeatTestsDefaultCount) +{ + TEST_ASSERT_EQUAL(0, UnityGetCommandLineOptions(2, repeat)); + TEST_ASSERT_EQUAL(2, UnityFixture.RepeatCount); +} + +TEST(UnityCommandOptions, OptionSelectRepeatTestsSpecificCount) +{ + TEST_ASSERT_EQUAL(0, UnityGetCommandLineOptions(3, repeat)); + TEST_ASSERT_EQUAL(99, UnityFixture.RepeatCount); +} + +static char* multiple[] = { + "testrunner.exe", + "-v", + "-g", "groupname", + "-n", "testname", + "-r", "98" +}; + +TEST(UnityCommandOptions, MultipleOptions) +{ + TEST_ASSERT_EQUAL(0, UnityGetCommandLineOptions(8, multiple)); + TEST_ASSERT_EQUAL(1, UnityFixture.Verbose); + STRCMP_EQUAL("groupname", UnityFixture.GroupFilter); + STRCMP_EQUAL("testname", UnityFixture.NameFilter); + TEST_ASSERT_EQUAL(98, UnityFixture.RepeatCount); +} + +static char* dashRNotLast[] = { + "testrunner.exe", + "-v", + "-g", "gggg", + "-r", + "-n", "tttt", +}; + +TEST(UnityCommandOptions, MultipleOptionsDashRNotLastAndNoValueSpecified) +{ + TEST_ASSERT_EQUAL(0, UnityGetCommandLineOptions(7, dashRNotLast)); + TEST_ASSERT_EQUAL(1, UnityFixture.Verbose); + STRCMP_EQUAL("gggg", UnityFixture.GroupFilter); + STRCMP_EQUAL("tttt", UnityFixture.NameFilter); + TEST_ASSERT_EQUAL(2, UnityFixture.RepeatCount); +} + + +//------------------------------------------------------------ + +TEST_GROUP(LeakDetection); + +TEST_SETUP(LeakDetection) +{ + UnityOutputCharSpy_Create(1000); +} + +TEST_TEAR_DOWN(LeakDetection) +{ + UnityOutputCharSpy_Destroy(); +} + +#define EXPECT_ABORT_BEGIN \ + { \ + jmp_buf TestAbortFrame; \ + memcpy(TestAbortFrame, Unity.AbortFrame, sizeof(jmp_buf)); \ + if (TEST_PROTECT()) \ + { + +#define EXPECT_ABORT_END \ + } \ + memcpy(Unity.AbortFrame, TestAbortFrame, sizeof(jmp_buf)); \ + } + +TEST(LeakDetection, DetectsLeak) +{ + void* m = malloc(10); + UnityOutputCharSpy_Enable(1); + EXPECT_ABORT_BEGIN + UnityMalloc_EndTest(); + UnityPointer_UndoAllSets(); + EXPECT_ABORT_END + UnityOutputCharSpy_Enable(0); + CHECK(strstr(UnityOutputCharSpy_Get(), "This test leaks!")); + free(m); + Unity.CurrentTestFailed = 0; +} + +TEST(LeakDetection, BufferOverrunFoundDuringFree) +{ + void* m = malloc(10); + char* s = (char*)m; + s[10] = -1; + UnityOutputCharSpy_Enable(1); + EXPECT_ABORT_BEGIN + free(m); + EXPECT_ABORT_END + UnityOutputCharSpy_Enable(0); + UnityPointer_UndoAllSets(); + CHECK(strstr(UnityOutputCharSpy_Get(), "Buffer overrun detected during free()")); + Unity.CurrentTestFailed = 0; +} + +TEST(LeakDetection, BufferOverrunFoundDuringRealloc) +{ + void* m = malloc(10); + char* s = (char*)m; + s[10] = -1; + UnityOutputCharSpy_Enable(1); + EXPECT_ABORT_BEGIN + m = realloc(m, 100); + EXPECT_ABORT_END + UnityOutputCharSpy_Enable(0); + UnityPointer_UndoAllSets(); + CHECK(strstr(UnityOutputCharSpy_Get(), "Buffer overrun detected during realloc()")); + free(m); + Unity.CurrentTestFailed = 0; +} diff --git a/extras/fixture/test/unity_fixture_TestRunner.c b/extras/fixture/test/unity_fixture_TestRunner.c new file mode 100644 index 0000000..80fec09 --- /dev/null +++ b/extras/fixture/test/unity_fixture_TestRunner.c @@ -0,0 +1,40 @@ +//- Copyright (c) 2010 James Grenning and Contributed to Unity Project +/* ========================================== + Unity Project - A Test Framework for C + Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams + [Released under MIT License. Please refer to license.txt for details] +========================================== */ + +#include "unity_fixture.h" + +TEST_GROUP_RUNNER(UnityFixture) +{ + RUN_TEST_CASE(UnityFixture, PointerSetting); + RUN_TEST_CASE(UnityFixture, ForceMallocFail); + RUN_TEST_CASE(UnityFixture, ReallocSmallerIsUnchanged); + RUN_TEST_CASE(UnityFixture, ReallocSameIsUnchanged); + RUN_TEST_CASE(UnityFixture, ReallocLargerNeeded); + RUN_TEST_CASE(UnityFixture, ReallocNullPointerIsLikeMalloc); + RUN_TEST_CASE(UnityFixture, ReallocSizeZeroFreesMemAndReturnsNullPointer); + RUN_TEST_CASE(UnityFixture, CallocFillsWithZero); + RUN_TEST_CASE(UnityFixture, PointerSet); +} + +TEST_GROUP_RUNNER(UnityCommandOptions) +{ + RUN_TEST_CASE(UnityCommandOptions, DefaultOptions); + RUN_TEST_CASE(UnityCommandOptions, OptionVerbose); + RUN_TEST_CASE(UnityCommandOptions, OptionSelectTestByGroup); + RUN_TEST_CASE(UnityCommandOptions, OptionSelectTestByName); + RUN_TEST_CASE(UnityCommandOptions, OptionSelectRepeatTestsDefaultCount); + RUN_TEST_CASE(UnityCommandOptions, OptionSelectRepeatTestsSpecificCount); + RUN_TEST_CASE(UnityCommandOptions, MultipleOptions); + RUN_TEST_CASE(UnityCommandOptions, MultipleOptionsDashRNotLastAndNoValueSpecified); +} + +TEST_GROUP_RUNNER(LeakDetection) +{ + RUN_TEST_CASE(LeakDetection, DetectsLeak); + RUN_TEST_CASE(LeakDetection, BufferOverrunFoundDuringFree); + RUN_TEST_CASE(LeakDetection, BufferOverrunFoundDuringRealloc); +} diff --git a/extras/fixture/test/unity_output_Spy.c b/extras/fixture/test/unity_output_Spy.c new file mode 100644 index 0000000..764ee9f --- /dev/null +++ b/extras/fixture/test/unity_output_Spy.c @@ -0,0 +1,55 @@ +//- Copyright (c) 2010 James Grenning and Contributed to Unity Project +/* ========================================== + Unity Project - A Test Framework for C + Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams + [Released under MIT License. Please refer to license.txt for details] +========================================== */ + + +#include "unity_output_Spy.h" +#include +#include + +static int size; +static int count; +static char* buffer; +static int spy_enable; + +void UnityOutputCharSpy_Create(int s) +{ + size = s; + count = 0; + spy_enable = 0; + buffer = malloc(size); + memset(buffer, 0, size); +} + +void UnityOutputCharSpy_Destroy() +{ + size = 0; + free(buffer); +} + +int UnityOutputCharSpy_OutputChar(int c) +{ + if (spy_enable) + { + if (count < (size-1)) + buffer[count++] = c; + } + else + { + putchar(c); + } + return c; +} + +const char * UnityOutputCharSpy_Get() +{ + return buffer; +} + +void UnityOutputCharSpy_Enable(int enable) +{ + spy_enable = enable; +} diff --git a/extras/fixture/test/unity_output_Spy.h b/extras/fixture/test/unity_output_Spy.h new file mode 100644 index 0000000..7c1590e --- /dev/null +++ b/extras/fixture/test/unity_output_Spy.h @@ -0,0 +1,17 @@ +//- Copyright (c) 2010 James Grenning and Contributed to Unity Project +/* ========================================== + Unity Project - A Test Framework for C + Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams + [Released under MIT License. Please refer to license.txt for details] +========================================== */ + +#ifndef D_unity_output_Spy_H +#define D_unity_output_Spy_H + +void UnityOutputCharSpy_Create(int s); +void UnityOutputCharSpy_Destroy(); +int UnityOutputCharSpy_OutputChar(int c); +const char * UnityOutputCharSpy_Get(); +void UnityOutputCharSpy_Enable(int enable); + +#endif