]> git.mdlowis.com Git - projs/atf.git/commitdiff
Added example tests
authorMichael D. Lowis <mike@mdlowis.com>
Tue, 29 Jul 2014 00:39:31 +0000 (20:39 -0400)
committerMichael D. Lowis <mike@mdlowis.com>
Tue, 29 Jul 2014 00:39:31 +0000 (20:39 -0400)
Gemfile [new file with mode: 0644]
Gemfile.lock [new file with mode: 0644]
Rakefile [new file with mode: 0644]
source/atf.c
source/atf.h
tests/main.c [new file with mode: 0644]
tests/test_signals.c [new file with mode: 0644]

diff --git a/Gemfile b/Gemfile
new file mode 100644 (file)
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 (file)
index 0000000..b932f82
--- /dev/null
@@ -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 (file)
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 }
+
index 14a972a0de00edf7ad094ea8c62b1f21c6086390..992f68165e733ded46c405763533f942cad8142f 100755 (executable)
@@ -3,25 +3,81 @@
   @brief See header for details
   $Revision$
   $HeadURL$
-  */
+*/
 #include "atf.h"
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifndef NO_SIGNALS
+#include <signal.h>
+#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) {
index f24b31a9bbb6f69f5200ae6d3d561459351b225a..0e2d2f196517a7fcf52bf5237fbee9a157e39e3f 100755 (executable)
@@ -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 <stdio.h>
+#include <stddef.h>
+#include <stdbool.h>
+
+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 (file)
index 0000000..3938272
--- /dev/null
@@ -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 (file)
index 0000000..7b8cacf
--- /dev/null
@@ -0,0 +1,8 @@
+#include "atf.h"
+#include <signal.h>
+
+TEST_SUITE(External_Suite) {
+    TEST(Should_handle_SIGABRT) {
+        raise(SIGABRT);
+    }
+}