From: Michael D. Lowis Date: Tue, 29 Jul 2014 00:39:31 +0000 (-0400) Subject: Added example tests X-Git-Url: https://git.mdlowis.com/?a=commitdiff_plain;h=0110dca83199322915e157fc1278ee6b58dfb4f8;p=projs%2Fatf.git Added example tests --- diff --git a/Gemfile b/Gemfile new file mode 100644 index 0000000..33d8a5b --- /dev/null +++ b/Gemfile @@ -0,0 +1,4 @@ +source "http://rubygems.org" + +gem "rscons" +gem "rake" diff --git a/Gemfile.lock b/Gemfile.lock new file mode 100644 index 0000000..b932f82 --- /dev/null +++ b/Gemfile.lock @@ -0,0 +1,14 @@ +GEM + remote: http://rubygems.org/ + specs: + json (1.8.1) + rake (10.3.2) + rscons (1.6.0) + json (~> 1.0) + +PLATFORMS + ruby + +DEPENDENCIES + rake + rscons diff --git a/Rakefile b/Rakefile new file mode 100644 index 0000000..c8a57e2 --- /dev/null +++ b/Rakefile @@ -0,0 +1,58 @@ +#------------------------------------------------------------------------------ +# Bundler Setup +#------------------------------------------------------------------------------ +require "bundler" +begin + Bundler.setup(:default, :development) +rescue Bundler::BundlerError => e + raise LoadError.new("Unable to Bundler.setup(): You probably need to run `bundle install`: #{e.message}") +end +require 'rscons' + +#------------------------------------------------------------------------------ +# Envrionment Definitions +#------------------------------------------------------------------------------ +# Define the compiler environment +Env = Rscons::Environment.new do |env| + env.build_dir('source/','build/obj/source') + env["CFLAGS"] += ['-Wall', '-Wextra', '-Werror', '-pedantic', '--std=c89'] + env['CPPPATH'] += Dir['source/**/'] +end + +# Define the test environment +TestEnv = Env.clone do |env| + env.build_dir('source','build/obj/test_source') + env.build_dir('tests','build/obj/tests/source') + env['CPPPATH'] += Dir['tests/'] +end + +# Make sure the environment is processed before we quit +at_exit { Env.process; TestEnv.process} + +#------------------------------------------------------------------------------ +# Main Build Targets +#------------------------------------------------------------------------------ +task :default => [:test, :build] + +desc "Build the C Data Structures static library" +task :build do + Env.Library('build/libatf.a', Dir['source/**/*.c']) + Env.process +end + +#------------------------------------------------------------------------------ +# Unit Testing Targets +#------------------------------------------------------------------------------ +desc "Run all unit tests" +task :test do + TestEnv.Program('build/test_libatf', Dir['source/**/*.c', 'tests/**/*.c']) + TestEnv.process + sh "build/test_libatf" +end + +#------------------------------------------------------------------------------ +# Cleanup Target +#------------------------------------------------------------------------------ +desc "Clean all generated files and directories" +task(:clean) { Rscons.clean } + diff --git a/source/atf.c b/source/atf.c index 14a972a..992f681 100755 --- a/source/atf.c +++ b/source/atf.c @@ -3,25 +3,81 @@ @brief See header for details $Revision$ $HeadURL$ - */ +*/ #include "atf.h" +#include +#include +#include +#ifndef NO_SIGNALS +#include +#endif char* Curr_Test = NULL; +char* Curr_File = NULL; +unsigned int Curr_Line = 0; static unsigned int Total = 0; static unsigned int Failed = 0; +#ifndef NO_SIGNALS +static void handle_signal(int sig) { + /* Determine the signal name */ + char* sig_name = NULL; + switch(sig) { + case SIGABRT: sig_name = "SIGABRT"; break; + case SIGBUS: sig_name = "SIGBUS"; break; + case SIGFPE: sig_name = "SIGFPE"; break; + case SIGILL: sig_name = "SIGILL"; break; + case SIGSEGV: sig_name = "SIGSEGV"; break; + case SIGSYS: sig_name = "SIGSYS"; break; + /* If we don't recognize it then just return and let the default handler + catch it. */ + default: return; + } + /* Error and exit. No summary will be printed but the user will know which + test has crashed. */ + fprintf(stderr,"%s:%d:0:%s:CRASH (signal: %d)\n", Curr_File, Curr_Line, Curr_Test, sig); + Failed++; + (void)atf_print_results(); + exit(1); +} +#endif + +void atf_init(int argc, char** argv) { + /* I reserve the right to use these later */ + (void)argc; + (void)argv; + +#ifndef NO_SIGNALS + /* Init signal handler */ + signal(SIGABRT, handle_signal); + signal(SIGBUS, handle_signal); + signal(SIGFPE, handle_signal); + signal(SIGILL, handle_signal); + signal(SIGSEGV, handle_signal); + signal(SIGSYS, handle_signal); +#endif +} + void atf_run_suite(suite_t suite) { suite(); } -void atf_test_start(char* p_test_name) { - Curr_Test = p_test_name; +void atf_test_start(char* file, unsigned int line, char* name) { + Curr_File = file; + Curr_Line = line; + Curr_Test = name; Total++; } +bool atf_test_assert(bool success, char* expr, char* file, int line) { + bool failed = !success; + if (failed) atf_test_fail(expr,file,line); + return failed; +} + void atf_test_fail(char* expr, char* file, int line) { Failed++; - printf("%s:%d:0:%s:FAIL\n\t%s\n", file, line, Curr_Test, expr); \ + printf("%s:%d:0:%s:FAIL:( %s )\n", file, line, Curr_Test, expr); \ } int atf_print_results(void) { diff --git a/source/atf.h b/source/atf.h index f24b31a..0e2d2f1 100755 --- a/source/atf.h +++ b/source/atf.h @@ -1,40 +1,45 @@ /** - @file test.h - @brief TODO: Describe this file + @file atf.h + @brief Aardvark Test Framework main interface file. $Revision$ $HeadURL$ - */ +*/ #ifndef TEST_H #define TEST_H -#include +#include +#include + +typedef void (*suite_t)(void); + +extern char* Curr_Test; + +void atf_init(int argc, char** argv); + +void atf_run_suite(suite_t suite); + +void atf_test_start(char* file, unsigned int line, char* name); + +bool atf_test_assert(bool success, char* expr_str, char* file, int line); + +void atf_test_fail(char* expr, char* file, int line); + +int atf_print_results(void); #define CHECK(expr) \ - if (!(expr)) { atf_test_fail(#expr,__FILE__,__LINE__-1); break; } + if(atf_test_assert((expr), #expr, __FILE__, __LINE__)) break #define TEST_SUITE(name) void name(void) #define TEST(desc) \ - for(atf_test_start(#desc); Curr_Test != NULL; Curr_Test = NULL) + for(atf_test_start(__FILE__,__LINE__,#desc); Curr_Test != NULL; Curr_Test = NULL) #define RUN_EXTERN_TEST_SUITE(name) \ do { extern TEST_SUITE(name); atf_run_suite(&name); } while(0) #define RUN_TEST_SUITE(name) \ - do { atf_run_suite(&name) } while(0) + atf_run_suite(&name) #define PRINT_TEST_RESULTS atf_print_results -typedef void (*suite_t)(void); - -extern char* Curr_Test; - -void atf_run_suite(suite_t suite); - -void atf_test_start(char* p_test_name); - -void atf_test_fail(char* expr, char* file, int line); - -int atf_print_results(void); - #endif /* TEST_H */ diff --git a/tests/main.c b/tests/main.c new file mode 100644 index 0000000..3938272 --- /dev/null +++ b/tests/main.c @@ -0,0 +1,18 @@ +#include "atf.h" + +TEST_SUITE(Local_Suite) { + TEST(Passing_Test) { + CHECK(true); + } + + TEST(Failing_Test) { + CHECK(false); + } +} + +int main(int argc, char** argv) { + atf_init(argc,argv); + RUN_TEST_SUITE(Local_Suite); + RUN_EXTERN_TEST_SUITE(External_Suite); + return atf_print_results(); +} diff --git a/tests/test_signals.c b/tests/test_signals.c new file mode 100644 index 0000000..7b8cacf --- /dev/null +++ b/tests/test_signals.c @@ -0,0 +1,8 @@ +#include "atf.h" +#include + +TEST_SUITE(External_Suite) { + TEST(Should_handle_SIGABRT) { + raise(SIGABRT); + } +}