Add a C unit testing framework and tests for OpenSRF
authordbs <dbs@9efc2488-bf62-4759-914b-345cdb29e865>
Sun, 8 May 2011 15:38:58 +0000 (15:38 +0000)
committerdbs <dbs@9efc2488-bf62-4759-914b-345cdb29e865>
Sun, 8 May 2011 15:38:58 +0000 (15:38 +0000)
The unit testing framework is "Check" - http://check.sourceforge.net/

These tests can be executed by running 'make check' after you
configure and compile the OpenSRF code.

To run them, you must have the 'check' package installed.

Author: Kevin Beswick <kevinbeswick00@gmail.com>
Signed-off-by: Dan Scott <dan@coffeecode.net>
Signed-off-by: Kevin Beswick <kevinbeswick00@gmail.com>

git-svn-id: svn://svn.open-ils.org/OpenSRF/branches/rel_2_0@2240 9efc2488-bf62-4759-914b-345cdb29e865

12 files changed:
Makefile.am
configure.ac
src/extras/Makefile.install
tests/Makefile.am [new file with mode: 0644]
tests/check_osrf_json_object.c [new file with mode: 0644]
tests/check_osrf_list.c [new file with mode: 0644]
tests/check_osrf_message.c [new file with mode: 0644]
tests/check_osrf_stack.c [new file with mode: 0644]
tests/check_transport_client.c [new file with mode: 0644]
tests/check_transport_message.c [new file with mode: 0644]
tests/testsuite.c [new file with mode: 0644]
tests/testsuite.h [new file with mode: 0644]

index 6e6f5d1..048b766 100644 (file)
@@ -115,7 +115,7 @@ opensrfinclude_HEADERS = $(OSRFINC)/log.h \
        src/gateway/apachetools.h
 endif
 
-SUBDIRS = src
+SUBDIRS = src tests
 
 jserver:
        make -s -C src jserver
index 6cc828c..2b60acb 100644 (file)
@@ -294,6 +294,15 @@ if test "x$OSRF_INSTALL_CORE" = "xtrue"; then
        AC_SUBST(memcached_CFLAGS)
        AC_SUBST(memcached_LIBS)
 
+    # Check Unit test framework
+    PKG_CHECK_MODULES([CHECK], [check >= 0.9.0], [enable_tests=yes],
+                      [enable_tests=no])
+    AM_CONDITIONAL(CHECK_TESTS, test x$enable_tests = xyes)
+
+    if test "x$enable_tests" = "xno"; then
+      AC_MSG_WARN(Check unit testing framwork not found.)
+    fi
+
        #-----------------------------
        # Checks for header files.
        #-----------------------------
@@ -312,6 +321,7 @@ if test "x$OSRF_INSTALL_CORE" = "xtrue"; then
        AC_TYPE_SIZE_T
        AC_HEADER_TIME
        AC_STRUCT_TM
+    AM_PROG_CC_C_O
 
        #----------------------------------
        # Checks for library functions.
@@ -343,6 +353,7 @@ if test "x$OSRF_INSTALL_CORE" = "xtrue"; then
                         src/python/opensrf.py
                         src/router/Makefile
                         src/srfsh/Makefile
+             tests/Makefile
                         bin/opensrf-perl.pl
                         bin/osrf_config
                         bin/osrf_ctl.sh])
index 5cc4252..9bcf60e 100644 (file)
@@ -81,6 +81,7 @@ DEBS =  \
        autoconf\
        automake\
        build-essential\
+       check\
        ejabberd\
        less\
        libapache2-mod-perl2\
diff --git a/tests/Makefile.am b/tests/Makefile.am
new file mode 100644 (file)
index 0000000..107872d
--- /dev/null
@@ -0,0 +1,32 @@
+COMMON = testsuite.c
+OSRF_INC = $(top_srcdir)/include/opensrf
+AM_LDFLAGS = $(DEF_LDFLAGS) -R $(libdir)
+
+TESTS = check_osrf_message check_osrf_json_object check_osrf_list check_osrf_stack check_transport_client \
+               check_transport_message
+check_PROGRAMS = check_osrf_message check_osrf_json_object check_osrf_list check_osrf_stack check_transport_client \
+                                check_transport_message
+
+check_osrf_message_SOURCES = $(COMMON) $(OSRF_INC)/osrf_message.h check_osrf_message.c
+check_osrf_message_CFLAGS = @CHECK_CFLAGS@ $(DEF_CFLAGS)
+check_osrf_message_LDADD = @CHECK_LIBS@ $(top_builddir)/src/libopensrf/libopensrf.la
+
+check_osrf_json_object_SOURCES = $(COMMON) $(OSRF_INC)/osrf_json_object.h check_osrf_json_object.c
+check_osrf_json_object_CFLAGS = @CHECK_CFLAGS@ $(DEF_CFLAGS)
+check_osrf_json_object_LDADD = @CHECK_LIBS@ $(top_builddir)/src/libopensrf/libopensrf.la
+
+check_osrf_list_SOURCES = $(COMMON) $(OSRF_INC)/osrf_list.h check_osrf_list.c
+check_osrf_list_CFLAGS = @CHECK_CFLAGS@ $(DEF_CFLAGS)
+check_osrf_list_LDADD = @CHECK_LIBS@ $(top_builddir)/src/libopensrf/libopensrf.la
+
+check_osrf_stack_SOURCES = $(COMMON) $(OSRF_INC)/osrf_stack.h check_osrf_stack.c
+check_osrf_stack_CFLAGS = @CHECK_CFLAGS@ $(DEF_CFLAGS)
+check_osrf_stack_LDADD = @CHECK_LIBS@ $(top_builddir)/src/libopensrf/libopensrf.la
+
+check_transport_client_SOURCES = $(COMMON) $(OSRF_INC)/transport_client.h check_transport_client.c
+check_transport_client_CFLAGS = @CHECK_CFLAGS@ $(DEF_CFLAGS)
+check_transport_client_LDADD = @CHECK_LIBS@ $(top_builddir)/src/libopensrf/libopensrf.la
+
+check_transport_message_SOURCES = $(COMMON) $(OSRF_INC)/transport_message.h check_transport_message.c
+check_transport_message_CFLAGS = @CHECK_CFLAGS@ $(DEF_CFLAGS)
+check_transport_message_LDADD = @CHECK_LIBS@ $(top_builddir)/src/libopensrf/libopensrf.la
diff --git a/tests/check_osrf_json_object.c b/tests/check_osrf_json_object.c
new file mode 100644 (file)
index 0000000..bd0bd37
--- /dev/null
@@ -0,0 +1,347 @@
+#include <check.h>
+#include "opensrf/osrf_json.h"
+
+jsonObject *jsonObj;
+jsonObject *jsonHash;
+jsonObject *jsonNumber;
+jsonObject *jsonBool;
+jsonObject *jsonArray;
+
+//Set up the test fixture
+void setup (void) {
+  jsonObj = jsonNewObject("test");
+  jsonHash = jsonNewObject(NULL);
+  jsonNumber = jsonNewNumberObject(123.456);
+  jsonBool = jsonNewBoolObject(0);
+  jsonArray = jsonNewObjectType(JSON_ARRAY);
+}
+
+//Clean up the test fixture
+void teardown (void) {
+  jsonObjectFree(jsonObj);
+  jsonObjectFree(jsonHash);
+  jsonObjectFree(jsonNumber);
+  jsonObjectFree(jsonBool);
+  jsonObjectFree(jsonArray);
+}
+
+//Tests
+
+START_TEST(test_osrf_json_object_jsonNewObject)
+  fail_if(jsonObj == NULL, "jsonObject not created");
+END_TEST
+
+START_TEST(test_osrf_json_object_jsonNewObjectFmt)
+  jsonObject *fmtObj;
+  jsonObject *nullObj;
+  fmtObj = jsonNewObjectFmt("string %d %d", 10, 20);
+  nullObj = jsonNewObjectFmt(NULL);
+
+  fail_if(fmtObj == NULL, "jsonObject not created");
+  fail_unless(strcmp(fmtObj->value.s, "string 10 20") == 0,
+      "jsonObject->value.s should contain the formatted string passed to jsonNewObjectFmt()");
+  fail_unless(fmtObj->type == JSON_STRING,
+      "jsonNewObjectFmt should set the jsonObject->type to JSON_STRING");
+  fail_unless(nullObj->value.s == NULL,
+      "jsonNewObjectFmt should set jsonObject->value.s to NULL if passed a NULL arg");
+  fail_unless(nullObj->type == JSON_NULL,
+      "jsonNewObjectFmt should set jsonObject->type to JSON_NULL if passed a NULL arg");
+END_TEST
+
+START_TEST(test_osrf_json_object_jsonNewNumberObject)
+  jsonObject *numObj;
+  numObj = jsonNewNumberObject(123);
+
+  fail_if(numObj == NULL, "jsonObject not created");
+  fail_unless(strcmp(numObj->value.s, "123") == 0,
+      "jsonNewNumberObject should set jsonObject->value.s to the string value of the num arg");
+  fail_unless(numObj->type == JSON_NUMBER,
+      "jsonNewNumberObject should set jsonObject->type to JSON_NUMBER");
+END_TEST
+
+START_TEST(test_osrf_json_object_jsonNewNumberStringObject)
+  jsonObject *nullobj = jsonNewNumberStringObject(NULL);
+  fail_unless(strcmp(nullobj->value.s, "0") == 0,
+      "jsonNewNumberStringObject should return a jsonObject with a value of 0 if passed a NULL numstr arg");
+  fail_unless(nullobj->type == JSON_NUMBER,
+      "jsonNewNumberStringObject should return a jsonObject with type JSON_NUMBER");
+  jsonObject *notnumobj = jsonNewNumberStringObject("not a number");
+  fail_unless(notnumobj == NULL,
+      "jsonNewNumberStringObject should return NULL if passed an arg that is not a number string");
+  jsonObject *numstrobj = jsonNewNumberStringObject("123");
+  fail_unless(strcmp(numstrobj->value.s, "123") == 0,
+      "jsonNewNumberStringObject should return a jsonObject with value.s = the value of the numstr arg");
+  fail_unless(numstrobj->type == JSON_NUMBER,
+      "jsonNewNumberStringObject should return a jsonObject of type JSON_NUMBER");
+END_TEST
+
+START_TEST(test_osrf_json_object_jsonNewBoolObject)
+  fail_unless(jsonBool->type == JSON_BOOL,
+      "jsonNewBoolObject should return a jsonObject of type JSON_BOOL");
+  fail_unless(jsonBool->value.b == 0,
+      "jsonNewBoolObject should return an object with a value of the val arg");
+END_TEST
+
+START_TEST(test_osrf_json_object_jsonSetBool)
+  jsonSetBool(jsonBool, -1);
+  fail_unless(jsonBool->value.b == -1,
+      "jsonSetBool should set jsonObject->value.b to the value of the val arg");
+END_TEST
+
+START_TEST(test_osrf_json_object_jsonObjectSetKey)
+  fail_unless(jsonObjectSetKey(NULL, "key1", NULL) == -1);
+  fail_unless(jsonObjectSetKey(jsonHash, "key1", NULL) == 1);
+  fail_unless(jsonObjectSetKey(jsonHash, "key2", jsonNewObject("test2")) == 2);
+  fail_unless(jsonObjectGetKey(jsonHash, "key1")->value.s == NULL);
+  fail_unless(strcmp(jsonObjectGetKey(jsonHash, "key2")->value.s, "test2") == 0);
+END_TEST
+
+START_TEST(test_osrf_json_object_jsonObjectRemoveKey)
+  jsonObjectSetKey(jsonHash, "key1", jsonNewObject("value"));
+  fail_unless(jsonObjectRemoveKey(jsonHash, NULL) == -1);
+  fail_unless(jsonObjectRemoveKey(jsonHash, "key1") == 1);
+END_TEST
+
+START_TEST(test_osrf_json_object_jsonObjectGetKey)
+  jsonObjectSetKey(jsonHash, "key1", jsonNewObject("value"));
+  fail_unless(strcmp(jsonObjectGetKey(jsonHash, "key1")->value.s, "value") == 0);
+END_TEST
+
+START_TEST(test_osrf_json_object_jsonObjectSetClass)
+  jsonObjectSetClass(jsonObj, NULL);
+  fail_unless(jsonObj->classname == NULL);
+  jsonObjectSetClass(jsonObj, "aClass");
+  fail_unless(strcmp(jsonObj->classname, "aClass") == 0);
+END_TEST
+
+START_TEST(test_osrf_json_object_jsonObjectGetClass)
+  fail_unless(jsonObjectGetClass(NULL) == NULL);
+  jsonObjectSetClass(jsonObj, "aClass");
+  fail_unless(strcmp(jsonObjectGetClass(jsonObj), "aClass") == 0);
+END_TEST
+
+START_TEST(test_osrf_json_object_jsonObjectSetIndex)
+  jsonObject *jsonArrayValue = jsonNewObject("value");
+  fail_unless(jsonObjectSetIndex(NULL, 0, jsonArrayValue) == -1,
+      "jsonObjectSetIndex should return -1 if dest arg is NULL");
+  fail_unless(jsonObjectSetIndex(jsonArray, 0, NULL) == 1,
+      "jsonObjectSetIndex should return the size of the json array after setting the new index");
+  fail_unless(jsonObjectSetIndex(jsonArray, 1, jsonArrayValue) == 2,
+      "jsonObjectSetIndex should return the size of the json array after setting the new index");
+  jsonObject *jsonArrayResult = jsonObjectGetIndex(jsonArray, 1);
+  fail_unless(strcmp(jsonArrayResult->value.s, "value") == 0,
+      "the value inserted into the jsonArray should be the value of the newObj arg");
+  fail_unless(jsonArrayResult->parent == jsonArray,
+      "the parent of the element inserted should be equal to the newObj arg");
+END_TEST
+
+START_TEST(test_osrf_json_object_jsonObjectGetIndex)
+  jsonObject *jsonArrayValue = jsonNewObject("value");
+  jsonObjectSetIndex(jsonArray, 0, jsonArrayValue);
+  fail_unless(jsonObjectGetIndex(NULL, 0) == NULL,
+      "if no obj arg is passed to jsonObjectGetIndex, it should return NULL");
+  fail_unless(jsonObjectGetIndex(jsonArray, 2) == NULL,
+      "if the index in the jsonArray is NULL, jsonObjectGetIndex should return NULL");
+  fail_unless(jsonObjectGetIndex(jsonNumber, 0) == NULL,
+      "if the obj arg isn't of type JSON_ARRAY, return NULL");
+  jsonObject *getIndexValue = jsonObjectGetIndex(jsonArray, 0);
+  fail_unless(strcmp(getIndexValue->value.s, "value") == 0,
+      "jsonObjectGetIndex should return the jsonObject at the index given");
+END_TEST
+
+START_TEST(test_osrf_json_object_jsonObjectToJSONRaw)
+  fail_unless(jsonObjectToJSONRaw(NULL) == NULL,
+      "when passed NULL, jsonObjectToJSONRaw should return NULL");
+
+  jsonObject *val1 = jsonNewObject("value1");
+  jsonObject *val2 = jsonNewObject("value2");
+  jsonObjectSetClass(val1, "class1");
+  jsonObjectSetClass(val2, "class2");
+  jsonObjectSetKey(jsonHash, "key1", val1);
+  jsonObjectSetKey(jsonHash, "key2", val2);
+
+  fail_unless(strcmp(jsonObjectToJSONRaw(jsonHash),
+      "{\"key1\":\"value1\",\"key2\":\"value2\"}") == 0,
+      "jsonObjectToJSONRaw should return a string of raw JSON, without expanding\
+      class names, built from the obj arg");
+END_TEST
+
+START_TEST(test_osrf_json_object_jsonObjectToJSON)
+  fail_unless(jsonObjectToJSON(NULL) == NULL,
+      "jsonObjectToJSON should return NULL if passed a NULL obj arg");
+  jsonObject *val1 = jsonNewObject("value1");
+  jsonObject *val2 = jsonNewObject("value2");
+  jsonObjectSetClass(val1, "class1");
+  jsonObjectSetClass(val2, "class2");
+
+  jsonObjectSetKey(jsonHash, "key1", val1);
+  jsonObjectSetKey(jsonHash, "key2", val2);
+  fail_unless(strcmp(jsonObjectToJSON(jsonHash),
+      "{\"key1\":{\"__c\":\"class1\",\"__p\":\"value1\"},\"key2\":{\"__c\":\"class2\",\"__p\":\"value2\"}}") == 0,
+      "jsonObjectToJSON should return the obj arg as raw json, expanding class names");
+END_TEST
+
+START_TEST(test_osrf_json_object_doubleToString)
+  fail_unless(strcmp(doubleToString(123.456),
+      "123.456000000000003069544618484") == 0,
+      "doubleToString should return a string version of the given double, with a precision of 30 digits");
+END_TEST
+
+START_TEST(test_osrf_json_object_jsonObjectGetString)
+  fail_unless(strcmp(jsonObjectGetString(jsonObj), "test") == 0,
+      "jsonObjectGetString should return the value of the given object, if it is of type JSON_STRING");
+  fail_unless(strcmp(jsonObjectGetString(jsonNumber),
+      "123.456000000000003069544618484") == 0,
+      "jsonObjectGetString should return the value of the given JSON_NUMBER object if it is not NULL");
+  jsonObject *jsonNullNumber = jsonNewNumberObject(0);
+  jsonObjectSetNumberString(jsonNullNumber, "NaN"); //set jsonNullNumber->value to NULL
+  fail_unless(strcmp(jsonObjectGetString(jsonNullNumber), "0") == 0,
+      "jsonObjectGetString should return 0 if value of the given JSON_NUMBER object is NULL");
+  fail_unless(jsonObjectGetString(jsonHash) == NULL,
+      "jsonObjectGetString should return NULL if the given arg is not of type JSON_NUMBER or JSON_STRING");
+  fail_unless(jsonObjectGetString(NULL) == NULL,
+      "jsonObjectGetString should return NULL if the given arg is NULL");
+END_TEST
+
+START_TEST(test_osrf_json_object_jsonObjectGetNumber)
+  fail_unless(jsonObjectGetNumber(NULL) == 0,
+      "jsonObjectGetNumber should return 0 if given arg is NULL");
+  fail_unless(jsonObjectGetNumber(jsonHash) == 0,
+      "jsonObjectGetNumber should return 0 if given arg is not of type JSON_NUMBER");
+  jsonObject *jsonNullNumber = jsonNewNumberObject(0);
+  jsonObjectSetNumberString(jsonNullNumber, "NaN");
+  fail_unless(jsonObjectGetNumber(jsonNullNumber) == 0,
+      "jsonObjectGetNumber should return 0 if given args value is NULL");
+  fail_unless(jsonObjectGetNumber(jsonNumber) == 123.456000000000003069544618484,
+      "jsonObjectGetNumber should return the value of the given obj in double form");
+END_TEST
+
+START_TEST(test_osrf_json_object_jsonObjectSetString)
+  jsonObjectSetString(jsonObj, NULL);
+  fail_unless(strcmp(jsonObj->value.s, "test") == 0,
+      "jsonObjectSetString should not change the value of the dest arg if passed a NULL string arg");
+  jsonObjectSetString(jsonObj, "changed");
+  fail_unless(strcmp(jsonObj->value.s, "changed") == 0,
+      "jsonObjectSetString should change the value of the dest arg to the value of the string arg");
+END_TEST
+
+START_TEST(test_osrf_json_object_jsonObjectSetNumberString)
+  fail_unless(jsonObjectSetNumberString(NULL, "asdf") == -1,
+      "jsonObjectSetNumberString should return -1 when dest arg is NULL");
+  fail_unless(jsonObjectSetNumberString(jsonNumber, NULL) == -1,
+      "jsonObjectSetNumberString should return -1 when string arg is NULL");
+  fail_unless(jsonObjectSetNumberString(jsonNumber, "111.111") == 0,
+      "jsonObjectSetNumberString should return 0 upon success");
+  fail_unless(strcmp(jsonNumber->value.s, "111.111") == 0,
+      "jsonObjectSetNumberString should set the value of the dest arg to the value of the string arg");
+  fail_unless(jsonObjectSetNumberString(jsonNumber, "not a number") == -1,
+      "jsonObjectSetNumber should return -1 if the string arg is not numeric");
+  fail_unless(jsonNumber->value.s == NULL,
+      "when the string arg is not numeric, dest->value.s should be set to NULL");
+END_TEST
+
+START_TEST(test_osrf_json_object_jsonObjectSetNumber)
+  jsonObjectSetNumber(jsonNumber, 999.999);
+  fail_unless(strcmp(jsonNumber->value.s, "999.999000000000023646862246096") == 0,
+      "jsonObjectSetNumber should set dest->value.s to the stringified version of the num arg");
+END_TEST
+
+START_TEST(test_osrf_json_object_jsonObjectClone)
+  jsonObject *nullClone = jsonObjectClone(NULL);
+  fail_unless(nullClone->type == JSON_NULL && nullClone->value.s == NULL,
+      "when passed a NULL arg, jsonObjectClone should return a jsonObject of type JSON_NULL with a value of NULL ");
+
+  jsonObject *anotherNullClone = jsonObjectClone(nullClone);
+  fail_unless(anotherNullClone->type == JSON_NULL && anotherNullClone->value.s == NULL,
+      "jsonObjectClone should return a clone of an object with type JSON_NULL");
+
+  jsonObject *stringClone = jsonObjectClone(jsonObj);
+  fail_unless(stringClone->type == JSON_STRING && strcmp(stringClone->value.s, "test") == 0,
+      "jsonObjectClone should return a clone of an object with type JSON_STRING");
+
+  jsonObject *numberClone = jsonObjectClone(jsonNumber);
+  fail_unless(numberClone->type == JSON_NUMBER,
+      "jsonObjectClone should return a clone of a JSON_NUMBER object");
+  fail_unless(strcmp(numberClone->value.s, "123.456000000000003069544618484") == 0,
+      "jsonObjectClone should return a clone of a JSON_NUMBER object");
+
+  jsonObject *boolClone = jsonObjectClone(jsonBool);
+  fail_unless(boolClone->type == JSON_BOOL && boolClone->value.b == 0,
+      "jsonObjectClone should return a clone of a JSON_BOOL object");
+
+  //Array
+  jsonObject *arrayVal1 = jsonNewObject("arrayval1");
+  jsonObject *arrayVal2 = jsonNewObject("arrayval2");
+  jsonObjectSetIndex(jsonArray, 0, arrayVal1);
+  jsonObjectSetIndex(jsonArray, 0, arrayVal2);
+  jsonObject *arrayClone = jsonObjectClone(jsonArray);
+  fail_unless(strcmp(jsonObjectToJSON(arrayClone), jsonObjectToJSON(jsonArray)) == 0,
+      "jsonObjectClone should return a clone of a JSON_ARRAY object");
+
+  //Hash
+  jsonObject *val1 = jsonNewObject("value1");
+  jsonObject *val2 = jsonNewObject("value2");
+  jsonObjectSetClass(val1, "class1");
+  jsonObjectSetClass(val2, "class2");
+  jsonObjectSetKey(jsonHash, "key1", val1);
+  jsonObjectSetKey(jsonHash, "key2", val2);
+  jsonObject *hashClone = jsonObjectClone(jsonHash);
+  fail_unless(strcmp(jsonObjectToJSON(hashClone), jsonObjectToJSON(jsonHash)) == 0,
+      "jsonObjectClone should return a clone of a JSON_HASH object");
+END_TEST
+
+START_TEST(test_osrf_json_object_jsonBoolIsTrue)
+  fail_unless(jsonBoolIsTrue(NULL) == 0,
+      "jsonBoolIsTrue should return 0 if a NULL arg is passed");
+  fail_unless(jsonBoolIsTrue(jsonObj) == 0,
+      "jsonBoolIsTrue should return 0 if a non JSON_BOOL arg is passed");
+  fail_unless(jsonBoolIsTrue(jsonBool) == 0,
+      "jsonBoolIsTrue should return 0 if the value of boolObj is 0");
+  jsonObject *newBool = jsonNewBoolObject(123);
+  fail_unless(jsonBoolIsTrue(newBool) == 1,
+      "jsonBoolIsTrue should return 1 if the value of boolObj is not 0");
+END_TEST
+
+//END Tests
+
+
+Suite *osrf_json_object_suite (void) {
+  //Create test suite, test case, initialize fixture
+  Suite *s = suite_create("osrf_json_object");
+  TCase *tc_core = tcase_create("Core");
+  tcase_add_checked_fixture(tc_core, setup, teardown);
+
+  //Add tests to test case
+  tcase_add_test(tc_core, test_osrf_json_object_jsonNewObject);
+  tcase_add_test(tc_core, test_osrf_json_object_jsonNewObjectFmt);
+  tcase_add_test(tc_core, test_osrf_json_object_jsonNewBoolObject);
+  tcase_add_test(tc_core, test_osrf_json_object_jsonSetBool);
+  tcase_add_test(tc_core, test_osrf_json_object_jsonObjectToJSONRaw);
+  tcase_add_test(tc_core, test_osrf_json_object_jsonObjectToJSON);
+  tcase_add_test(tc_core, test_osrf_json_object_jsonObjectSetKey);
+  tcase_add_test(tc_core, test_osrf_json_object_jsonObjectGetKey);
+  tcase_add_test(tc_core, test_osrf_json_object_jsonObjectSetClass);
+  tcase_add_test(tc_core, test_osrf_json_object_jsonObjectGetClass);
+  tcase_add_test(tc_core, test_osrf_json_object_jsonNewNumberObject);
+  tcase_add_test(tc_core, test_osrf_json_object_jsonNewNumberStringObject);
+  tcase_add_test(tc_core, test_osrf_json_object_jsonObjectRemoveKey);
+  tcase_add_test(tc_core, test_osrf_json_object_doubleToString);
+  tcase_add_test(tc_core, test_osrf_json_object_jsonObjectGetString);
+  tcase_add_test(tc_core, test_osrf_json_object_jsonObjectGetNumber);
+  tcase_add_test(tc_core, test_osrf_json_object_jsonObjectSetString);
+  tcase_add_test(tc_core, test_osrf_json_object_jsonObjectSetNumberString);
+  tcase_add_test(tc_core, test_osrf_json_object_jsonObjectSetNumber);
+  tcase_add_test(tc_core, test_osrf_json_object_jsonBoolIsTrue);
+  tcase_add_test(tc_core, test_osrf_json_object_jsonObjectSetIndex);
+  tcase_add_test(tc_core, test_osrf_json_object_jsonObjectGetIndex);
+  tcase_add_test(tc_core, test_osrf_json_object_jsonObjectClone);
+
+  //Add test case to test suite
+  suite_add_tcase(s, tc_core);
+
+  return s;
+}
+
+void run_tests (SRunner *sr) {
+  srunner_add_suite (sr, osrf_json_object_suite());
+}
diff --git a/tests/check_osrf_list.c b/tests/check_osrf_list.c
new file mode 100644 (file)
index 0000000..40d7a5b
--- /dev/null
@@ -0,0 +1,383 @@
+#include <check.h>
+#include "opensrf/osrf_list.h"
+
+osrfList *testOsrfList;
+
+//Keep track of how many items have been freed using osrfCustomListFree
+unsigned int freedItemsSize;
+
+//Define a custom freeing function for list items
+void osrfCustomListFree() {
+  freedItemsSize++;
+}
+
+//Set up the test fixture
+void setup(void) {
+  freedItemsSize = 0;
+  //Set up a list of size 10, define the freeing function, add some items to test with
+  testOsrfList = osrfNewListSize(10);
+  testOsrfList->freeItem = (void(*)(void*)) osrfCustomListFree;
+
+  int item1 = 7;
+  int item3 = 15;
+
+  osrfListPush(testOsrfList, (int *)item1);
+  osrfListPush(testOsrfList, NULL);
+  osrfListPush(testOsrfList, (int *)item3);
+}
+
+//Clean up the test fixture
+void teardown(void) {
+  osrfListFree(testOsrfList);
+}
+
+// BEGIN TESTS
+
+START_TEST(test_osrf_list_osrfNewList)
+  osrfList *newList = osrfNewList();
+  fail_if(newList == NULL, "osrfList object not successfully created");
+  fail_unless(newList->arrsize == 48, "the osrfList is not the default size of 48");
+END_TEST
+
+START_TEST(test_osrf_list_osrfNewListSize)
+  osrfList *smallList = osrfNewListSize(5);
+  fail_if(smallList == NULL, "smallList not successfully created");
+  fail_unless(smallList->arrsize == 5, "smallList wasn't created with the size 5");
+  fail_unless(smallList->freeItem == NULL, "freeItem should be null by default");
+  int i;
+  for (i = 0 ; i < smallList->arrsize ; i++) {
+    fail_if(smallList->arrlist[i] != NULL, "Every value in smallList->arrlist should be null");
+  }
+
+  //List created with size <= 0
+  osrfList *sizelessList = osrfNewListSize(0);
+  fail_unless(sizelessList->arrsize == 16,
+      "osrfNewListSize called with a size of 0 or less should have an array size of 16");
+END_TEST
+
+START_TEST(test_osrf_list_osrfListPush)
+  fail_unless(osrfListPush(NULL, NULL) == -1,
+      "Passing a null list to osrfListPush should return -1");
+  int listItem = 111;
+  fail_unless(osrfListPush(testOsrfList, (int *) listItem) == 0,
+      "osrfListPush should return 0 if successful");
+  fail_unless(testOsrfList->size == 4,
+      "testOsrfList->size did not update correctly, should be 4");
+  fail_unless(osrfListGetIndex(testOsrfList, 3) == (int *) listItem,
+      "listItem did not add to the end of testOsrfList");
+END_TEST
+
+START_TEST(test_osrf_list_osrfListPushFirst)
+  fail_unless(osrfListPushFirst(NULL, NULL) == -1,
+      "Passing a null list to osrfListPushFirst should return -1");
+  int listItem = 123;
+  fail_unless(osrfListPushFirst(testOsrfList, (int *) listItem) == 3,
+      "osrfListPushFirst should return a size of 3");
+  fail_unless(osrfListGetIndex(testOsrfList, 1) == (int *) listItem,
+      "listItem should be in index 1 because it is the first that is null");
+END_TEST
+
+START_TEST(test_osrf_list_osrfListSet)
+  //Null argument check
+  fail_unless(osrfListSet(NULL, NULL, 1) == NULL,
+      "Given a null list arg, osrfListSet should return null");
+
+  //Adding an item to an existing, NULL position in the list
+  int listItem = 456;
+  fail_unless(osrfListSet(testOsrfList, (int *) listItem, 4) == NULL,
+      "Calling osrfListSet on an empty index should return NULL");
+  fail_unless(osrfListGetIndex(testOsrfList, 4) == (int *) listItem,
+      "osrfListSet is not assigning item pointer to the correct position");
+  fail_unless(testOsrfList->size == 5,
+      "osrfListSet should update a lists size after adding an item to that list");
+
+  //Adding an item to an exisiting, occupied position in the
+  //list when there is a freeing function defined on the list
+  int listItem2 = 789;
+  fail_unless(osrfListSet(testOsrfList, (int *) listItem2, 4) == NULL,
+      "Calling osrfListSet on an index that held a value, \
+       on a list that has a custom freeing function, should return NULL");
+  fail_unless(osrfListGetIndex(testOsrfList, 4) == (int *) listItem2,
+      "When called on a position that already has a value, \
+       osrfListSet should replace that value with the new item");
+  fail_unless(testOsrfList->size == 5,
+      "osrfListSet shouldn't update a lists size if the item is \
+       not added beyond the current size");
+
+  //Adding an item to an exisiting, occupied position in the list
+  //when there is NOT a freeing function defined on the list
+  testOsrfList->freeItem = NULL;
+  int listItem3 = 111;
+  fail_unless(osrfListSet(testOsrfList, (int *) listItem3, 4) == (int *) listItem2,
+      "Calling osrfListSet on an index that held a value should \
+       return the reference to that value");
+  fail_unless(osrfListGetIndex(testOsrfList, 4) == (int *) listItem3,
+      "When called on a position that already has a value, \
+       osrfListSet should replace that value with the new item");
+  fail_unless(testOsrfList->size == 5,
+      "osrfListSet shouldn't update a lists size if the item is \
+       not added beyond the current size");
+
+  //Adding an item to a position outside of the current array size
+  int listItem4 = 444;
+  fail_unless(osrfListSet(testOsrfList, (int *) listItem4, 18) == NULL,
+      "Calling osrfListSet on an empty index should return NULL, \
+       even if the index does not exist yet");
+  fail_unless(testOsrfList->arrsize == 266,
+      "New arrsize should be 266 since it was 10 before, and grows \
+       in increments of 256 when expanded");
+  fail_unless(testOsrfList->size == 19,
+      "List should have a size value of 19");
+  fail_unless(osrfListGetIndex(testOsrfList, 18) == (int *) listItem4,
+      "Value not added to correct index of list");
+END_TEST
+
+START_TEST(test_osrf_list_osrfListGetIndex)
+  fail_unless(osrfListGetIndex(NULL, 1) == NULL,
+      "Calling osrfListGetIndex with a null list should return null");
+  fail_unless(osrfListGetIndex(testOsrfList, 8) == NULL,
+      "Calling osrfListGetIndex with a value outside the range of \
+       occupied indexes should return NULL");
+  fail_unless(osrfListGetIndex(testOsrfList, 2) == (int *) 15,
+      "osrfListGetIndex should return the value of the list at the given index");
+END_TEST
+
+START_TEST(test_osrf_list_osrfListFree)
+  //Set up a new list to be freed
+  osrfList *myList = osrfNewList();
+  myList->freeItem = (void(*)(void*)) osrfCustomListFree;
+  int myListItem1 = 123;
+  int myListItem2 = 456;
+  osrfListSet(myList, (int *) myListItem1, 0);
+  osrfListSet(myList, (int *) myListItem2, 1);
+  osrfListFree(myList);
+  fail_unless(freedItemsSize == 2,
+      "osrfListFree should free each item in the list if there is a custom \
+      freeing function defined");
+END_TEST
+
+START_TEST(test_osrf_list_osrfListClear)
+  //Set up a new list with items to be freed
+  osrfList *myList = osrfNewList();
+  myList->freeItem = (void(*)(void*)) osrfCustomListFree;
+  int myListItem1 = 123;
+  int myListItem2 = 456;
+  osrfListSet(myList, (int *) myListItem1, 0);
+  osrfListSet(myList, (int *) myListItem2, 1);
+  osrfListClear(myList);
+
+  fail_unless(freedItemsSize == 2,
+      "osrfListClear should free each item in the list if there is a custom \
+       freeing function defined");
+  fail_unless(myList->arrlist[0] == NULL && myList->arrlist[1] == NULL,
+      "osrfListClear should make all previously used slots in the list NULL");
+  fail_unless(myList->size == 0,
+      "osrfListClear should set the list's size to 0");
+END_TEST
+
+START_TEST(test_osrf_list_osrfListSwap)
+  //Prepare a second list to swap
+  osrfList *secondOsrfList = osrfNewListSize(7);
+  int item2 = 8;
+  int item3 = 16;
+  osrfListPush(secondOsrfList, NULL);
+  osrfListPush(secondOsrfList, (int *) item2);
+  osrfListPush(secondOsrfList, (int *) item3);
+
+  osrfListSwap(testOsrfList, secondOsrfList);
+  fail_unless(
+    osrfListGetIndex(testOsrfList, 0) == NULL &&
+    osrfListGetIndex(testOsrfList, 1) == (int *) 8 &&
+    osrfListGetIndex(testOsrfList, 2) == (int *) 16,
+    "After osrfListSwap, first list should now contain \
+    the contents of the second list"
+  );
+  fail_unless(
+    osrfListGetIndex(secondOsrfList, 0) == (int *) 7 &&
+    osrfListGetIndex(secondOsrfList, 1) == NULL &&
+    osrfListGetIndex(secondOsrfList, 2) == (int *) 15,
+    "After osrfListSwap, second list should now contain \
+    the contents of the first list"
+  );
+END_TEST
+
+START_TEST(test_osrf_list_osrfListRemove)
+  fail_unless(osrfListRemove(NULL, 2) == NULL,
+      "osrfListRemove should return NULL when not given a list");
+  fail_unless(osrfListRemove(testOsrfList, 1000) == NULL,
+      "osrfListRemove should return NULL when given a position \
+       exceeding the size of the list");
+  fail_unless(osrfListRemove(testOsrfList, 2) == NULL,
+      "osrfListRemove should return NULL if there is a custom freeing \
+       function defined on the list");
+  fail_unless(osrfListGetIndex(testOsrfList, 2) == NULL,
+      "osrfListRemove should remove the value from the list");
+  fail_unless(testOsrfList->size == 2,
+      "osrfListRemove should adjust the size of the list if the last \
+       element is removed");
+  fail_unless(freedItemsSize == 1,
+      "osrfListRemove should call a custom item freeing function if \
+       defined");
+  testOsrfList->freeItem = NULL;
+  fail_unless(osrfListRemove(testOsrfList, 0) == (int *) 7,
+      "osrfListRemove should return the value that it has removed from \
+      the list if no custom freeing function is defined on the list");
+  fail_unless(osrfListGetIndex(testOsrfList, 0) == NULL,
+      "osrfListRemove should remove the value from the list and make \
+       the position NULL");
+  fail_unless(testOsrfList->size == 2, "osrfListRemove should not touch \
+      the size of the list if it isn't removing the last element in the \
+      list");
+END_TEST
+
+START_TEST(test_osrf_list_osrfListExtract)
+  fail_unless(osrfListExtract(NULL, 2) == NULL,
+      "osrfListExtract should return NULL when not given a list");
+  fail_unless(osrfListExtract(testOsrfList, 1000) == NULL,
+      "osrfListExtract should return NULL when given a position \
+       exceeding the size of the list");
+  fail_unless(osrfListExtract(testOsrfList, 2) == (int *) 15,
+      "osrfListExtract should return the value that it has removed \
+       from the list");
+  fail_unless(osrfListGetIndex(testOsrfList, 2) == NULL,
+      "osrfListExtract should remove the value from the list and \
+       make the position NULL");
+  fail_unless(testOsrfList->size == 2,
+      "osrfListExtract should adjust the size of the list if the \
+       last element is removed");
+  fail_unless(osrfListExtract(testOsrfList, 0) == (int *) 7,
+      "osrfListExtract should return the value that it has removed \
+       from the list");
+  fail_unless(osrfListGetIndex(testOsrfList, 0) == NULL,
+      "osrfListExtract should remove the value from the list and \
+       make the position NULL");
+  fail_unless(testOsrfList->size == 2,
+      "osrfListExtract should not touch the size of the list if it \
+       isn't removing the last element in the list");
+END_TEST
+
+START_TEST(test_osrf_list_osrfListFind)
+  fail_unless(osrfListFind(NULL, (int *) 2) == -1,
+      "osrfListFind should return -1 when not given a list");
+  fail_unless(osrfListFind(testOsrfList, NULL) == -1,
+      "osrfListFind should return -1 when not given an addr");
+  fail_unless(osrfListFind(testOsrfList, (int *) 15) == 2,
+      "osrfListFind should return the index where the first instance \
+       of addr is located");
+  fail_unless(osrfListFind(testOsrfList, (int *) 199) == -1,
+      "osrfListFind should return -1 when the addr does not exist in \
+       the list");
+END_TEST
+
+START_TEST(test_osrf_list_osrfListGetCount)
+  fail_unless(osrfListGetCount(NULL) == -1,
+      "osrfListGetCount should return -1 when no list is given");
+  fail_unless(osrfListGetCount(testOsrfList) == 3,
+      "osrfListGetCount should return list->size when given a list");
+END_TEST
+
+START_TEST(test_osrf_list_osrfListPop)
+  fail_unless(osrfListPop(NULL) == NULL,
+      "osrfListPop should return NULL when no list is given");
+  fail_unless(osrfListPop(testOsrfList) == NULL,
+      "osrfListPop should return NULL if there is a custom freeing \
+       function defined on the list");
+  fail_unless(testOsrfList->arrlist[2] == NULL,
+      "osrfListPop should remove the last item from the list");
+  testOsrfList->freeItem = NULL;
+  int item = 10;
+  osrfListPush(testOsrfList, (int *) item);
+  fail_unless(osrfListPop(testOsrfList) == (int *) 10,
+      "osrfListPop should return the last item from the list");
+  fail_unless(testOsrfList->arrlist[2] == NULL,
+      "osrfListPop should remove the last item from the list");
+END_TEST
+
+START_TEST(test_osrf_list_osrfNewListIterator)
+  fail_unless(osrfNewListIterator(NULL) == NULL,
+      "osrfNewListIterator should return NULL when no list is given");
+  osrfListIterator *testListItr = osrfNewListIterator(testOsrfList);
+  fail_if(testListItr == NULL,
+      "osrfNewListIterator should create a osrfListIterator object");
+  fail_unless(testListItr->list == testOsrfList,
+      "osrfNewListIterator should set the osrfListIterator->list \
+       attribute to the given list");
+  fail_unless(testListItr->current == 0,
+      "osrfNewListIterator should set its current position to 0 by \
+       default");
+END_TEST
+
+START_TEST(test_osrf_list_osrfListIteratorNext)
+  fail_unless(osrfListIteratorNext(NULL) == NULL,
+      "osrfListIteratorNext should return NULL when no list given");
+  osrfListIterator *testListItr = osrfNewListIterator(testOsrfList);
+  fail_unless(osrfListIteratorNext(testListItr) == (int *) 7,
+      "osrfListIteratorNext should return the value stored at the current \
+       index in the list, then increment");
+  fail_unless(osrfListIteratorNext(testListItr) == NULL,
+      "osrfListIteratorNext should return the value stored at the current \
+       index in the list, then increment");
+  fail_unless(osrfListIteratorNext(testListItr) == (int *) 15,
+      "osrfListIteratorNext should return the value stored at the current \
+       index in the list, then increment");
+  fail_unless(osrfListIteratorNext(testListItr) == NULL,
+      "osrfListIteratorNext should return NULL when it reaches the end of \
+       the list");
+  testListItr->list = NULL;
+  fail_unless(osrfListIteratorNext(testListItr) == NULL,
+      "osrfListIteratorNext should return NULL if osrfListIterator->list \
+       is NULL");
+END_TEST
+
+START_TEST(test_osrf_list_osrfListIteratorFree)
+END_TEST
+
+START_TEST(test_osrf_list_osrfListIteratorReset)
+  osrfListIterator *testListItr = osrfNewListIterator(testOsrfList);
+  osrfListIteratorNext(testListItr);
+  osrfListIteratorReset(testListItr);
+  fail_unless(testListItr->current == 0,
+      "osrfListIteratorReset should reset the iterator's current position to 0");
+END_TEST
+
+START_TEST(test_osrf_list_osrfListSetDefaultFree)
+END_TEST
+
+//END TESTS
+
+Suite *osrf_list_suite(void) {
+  //Create test suite, test case, initialize fixture
+  Suite *s = suite_create("osrf_list");
+  TCase *tc_core = tcase_create("Core");
+  tcase_add_checked_fixture(tc_core, setup, teardown);
+
+  //Add tests to test case
+  tcase_add_test(tc_core, test_osrf_list_osrfNewList);
+  tcase_add_test(tc_core, test_osrf_list_osrfNewListSize);
+  tcase_add_test(tc_core, test_osrf_list_osrfListPush);
+  tcase_add_test(tc_core, test_osrf_list_osrfListPushFirst);
+  tcase_add_test(tc_core, test_osrf_list_osrfListSet);
+  tcase_add_test(tc_core, test_osrf_list_osrfListGetIndex);
+  tcase_add_test(tc_core, test_osrf_list_osrfListFree);
+  tcase_add_test(tc_core, test_osrf_list_osrfListClear);
+  tcase_add_test(tc_core, test_osrf_list_osrfListSwap);
+  tcase_add_test(tc_core, test_osrf_list_osrfListRemove);
+  tcase_add_test(tc_core, test_osrf_list_osrfListExtract);
+  tcase_add_test(tc_core, test_osrf_list_osrfListFind);
+  tcase_add_test(tc_core, test_osrf_list_osrfListGetCount);
+  tcase_add_test(tc_core, test_osrf_list_osrfListPop);
+  tcase_add_test(tc_core, test_osrf_list_osrfNewListIterator);
+  tcase_add_test(tc_core, test_osrf_list_osrfListIteratorNext);
+  tcase_add_test(tc_core, test_osrf_list_osrfListIteratorFree);
+  tcase_add_test(tc_core, test_osrf_list_osrfListIteratorReset);
+  tcase_add_test(tc_core, test_osrf_list_osrfListSetDefaultFree);
+
+  //Add test case to test suite
+  suite_add_tcase(s, tc_core);
+
+  return s;
+}
+
+void run_tests(SRunner *sr) {
+  srunner_add_suite(sr, osrf_list_suite());
+}
diff --git a/tests/check_osrf_message.c b/tests/check_osrf_message.c
new file mode 100644 (file)
index 0000000..1a8f9a7
--- /dev/null
@@ -0,0 +1,98 @@
+#include <check.h>
+#include "opensrf/osrf_json.h"
+#include "opensrf/osrf_message.h"
+
+osrfMessage *o;
+
+//Set up the test fixture
+void setup(void) {
+  o = osrf_message_init(CONNECT, 1, 1);
+}
+
+//Clean up the test fixture
+void teardown(void) {
+  osrfMessageFree(o);
+}
+
+//Tests
+
+START_TEST(test_osrf_message_init)
+  fail_if (o == NULL, "osrfMessage not created");
+END_TEST
+
+START_TEST(test_osrf_message_get_last_locale)
+    fail_unless(osrf_message_get_last_locale() == NULL,
+        "osrf_message_get_last_locale should return the value of current_locale");
+END_TEST
+
+START_TEST(test_osrf_message_set_locale)
+  const char* new_locale = "en-CA";
+  fail_unless(osrf_message_set_locale(o, NULL) == NULL,
+      "osrf_message_set_locale should return NULL if locale is NULL");
+  fail_unless(osrf_message_set_locale(NULL, new_locale) == NULL,
+      "osrf_message_set_locale should return NULL if msg is NULL");
+  char* l = osrf_message_set_locale(o, new_locale);
+  fail_unless(strcmp(l, "en-CA") == 0,
+      "osrf_message_set_locale should return the new locale");
+  fail_unless(strcmp(o->sender_locale, "en-CA") == 0,
+      "osrf_message_set_locale should set osrfMessage->sender_locale to the new locale");
+END_TEST
+
+START_TEST(test_osrf_message_set_default_locale)
+  fail_unless(osrf_message_set_default_locale(NULL) == NULL,
+      "osrf_message_set_default_locale should return NULL if given a NULL arg");
+  fail_unless(osrf_message_set_default_locale("This string is \
+        longer than 16 characters for sure") == NULL,
+      "osrf_message_set_default_locale should return NULL if locale arg is longer than 16 chars");
+  fail_unless(strcmp(osrf_message_set_default_locale("fr-CA"),
+      "fr-CA") == 0,
+      "osrf_message_set_default_locale should return the new default locale if successful");
+END_TEST
+
+START_TEST(test_osrf_message_set_method)
+  osrf_message_set_method(o, NULL);
+  fail_unless(o->method_name == NULL,
+      "osrf_message_set_method should return NULL if given a NULL method_name arg");
+  osrf_message_set_method(o, "add");
+  fail_unless(strcmp(o->method_name, "add") == 0,
+      "osrf_message_set_method should set osrfMessage->method_name if successful");
+END_TEST
+
+START_TEST(test_osrf_message_set_params)
+  osrf_message_set_params(o, NULL);
+  fail_unless(o->_params == NULL,
+      "osrf_message_set_params should set msg->_params to NULL when passed a NULL o arg");
+  jsonObject *testJSONObject;
+  testJSONObject = jsonNewObject("test");
+  osrf_message_set_params(o, testJSONObject);
+  fail_unless(strcmp(jsonObjectGetIndex(o->_params, 0)->value.s, "test") == 0,
+      "osrf_message_set_params should set msg->_params to an array containing the\
+      jsonObject passed");
+  jsonObjectFree(testJSONObject);
+END_TEST
+
+//END Tests
+
+Suite *osrf_message_suite(void) {
+  //Create test suite, test case, initialize fixture
+  Suite *s = suite_create("osrf_message");
+  TCase *tc_core = tcase_create("Core");
+  tcase_add_checked_fixture (tc_core, setup, teardown);
+
+  //Add tests to test case
+  tcase_add_test(tc_core, test_osrf_message_init);
+  tcase_add_test(tc_core, test_osrf_message_get_last_locale);
+  tcase_add_test(tc_core, test_osrf_message_set_locale);
+  tcase_add_test(tc_core, test_osrf_message_set_default_locale);
+  tcase_add_test(tc_core, test_osrf_message_set_method);
+  tcase_add_test(tc_core, test_osrf_message_set_params);
+
+  //Add test case to test suite
+  suite_add_tcase(s, tc_core);
+
+  return s;
+}
+
+void run_tests(SRunner *sr) {
+  srunner_add_suite(sr, osrf_message_suite());
+}
diff --git a/tests/check_osrf_stack.c b/tests/check_osrf_stack.c
new file mode 100644 (file)
index 0000000..3657488
--- /dev/null
@@ -0,0 +1,41 @@
+#include <check.h>
+#include "opensrf/osrf_stack.h"
+
+
+
+//Set up the test fixture
+void setup(void){
+}
+
+//Clean up the test fixture
+void teardown(void){
+}
+
+// BEGIN TESTS
+
+START_TEST(test_osrf_stack_process)
+  int *mr = 0;
+  fail_unless(osrf_stack_process(NULL, 10, mr) == -1,
+      "osrf_stack_process should return -1 if client arg is NULL");
+END_TEST
+
+//END TESTS
+
+Suite *osrf_stack_suite(void) {
+  //Create test suite, test case, initialize fixture
+  Suite *s = suite_create("osrf_stack");
+  TCase *tc_core = tcase_create("Core");
+  tcase_add_checked_fixture(tc_core, setup, teardown);
+
+  //Add tests to test case
+  tcase_add_test(tc_core, test_osrf_stack_process);
+
+  //Add test case to test suite
+  suite_add_tcase(s, tc_core);
+
+  return s;
+}
+
+void run_tests(SRunner *sr) {
+  srunner_add_suite(sr, osrf_stack_suite());
+}
diff --git a/tests/check_transport_client.c b/tests/check_transport_client.c
new file mode 100644 (file)
index 0000000..741263f
--- /dev/null
@@ -0,0 +1,248 @@
+#include <check.h>
+#include "opensrf/transport_client.h"
+
+transport_client *a_client;
+transport_message *a_message; 
+
+//Set up the test fixture
+void setup(void) {
+  a_client = client_init("server", 1234, "unixpath", 123);
+  a_message = message_init("body", "subject", "thread", "recipient", "sender");
+}
+
+//Clean up the test fixture
+void teardown(void) {
+  free(a_client);
+  free(a_message);
+}
+
+// Stub functions to simulate behavior of transport_session functions used in
+// transport_client.c (to isolate system under test)
+
+/*
+ * init_transport() returns a new transport_session object - just return an
+ * empty one for the purpose of testing transport_client
+*/
+transport_session* init_transport(const char* server, int port, 
+    const char* unix_path, void* user_data, int component) {
+
+  transport_session* session = (transport_session*) safe_malloc(sizeof(transport_session));
+  return session;
+}
+
+/*
+ * va_list_to_string takes a format and any number of arguments, and returns
+ * a formatted string of those args. Its only used once here, return what is
+ * expected.
+*/
+char* va_list_to_string(const char* format, ...) {
+  return "user@server/resource";
+}
+
+/* The rest of these functions return 1 or 0 depending on the result.
+ * The transport_client functions that call these are just wrappers for
+ * functions in transport_session.c
+*/
+
+int session_connect(transport_session* session, 
+          const char* username, const char* password, 
+          const char* resource, int connect_timeout, enum TRANSPORT_AUTH_TYPE auth_type ) {
+
+  return 1;
+}
+
+int session_disconnect(transport_session* session) {
+  return 1;
+}
+
+int session_connected(transport_session* session) {
+  return 1;
+}
+
+int session_send_msg(transport_session* session, transport_message* message) {
+  return 0;
+}
+
+int session_wait(transport_session* session, int timeout) {
+  if (session == a_client->session && timeout == -1) {
+    transport_message* recvd_msg = message_init("body1", "subject1", "thread1", "recipient1", "sender1");
+    a_client->msg_q_head = recvd_msg;
+    return 0;
+  }
+  else if (session == a_client->session && timeout > 0) {
+    return 0;
+  }
+  else
+    return 1;
+}
+
+//End Stubs
+
+// BEGIN TESTS
+
+START_TEST(test_transport_client_init)
+  fail_unless(client_init(NULL, 1234, "some_path", 123) == NULL,
+      "When given a NULL client arg, client_init should return NULL");
+  transport_client *test_client = client_init("server", 1234, "unixpath", 123);
+  fail_unless(test_client->msg_q_head == NULL,
+      "client->msg_q_head should be NULL on new client creation");
+  fail_unless(test_client->msg_q_tail == NULL,
+      "client->msg_q_tail should be NULL on new client creation");
+  fail_if(test_client->session == NULL,
+      "client->session should not be NULL - it is initialized by a call to init_transport");
+  //fail_unless(test_client->session->message_callback == client_message_handler,
+  //  "The default message_callback function should be client_message_handler");
+  fail_unless(test_client->error == 0, "client->error should be false on new client creation");
+  fail_unless(strcmp(test_client->host, "server") == 0, "client->host should be set to the host arg");
+  fail_unless(test_client->xmpp_id == NULL, "xmpp_id should be NULL on new client creation");
+END_TEST
+
+START_TEST(test_transport_client_connect)
+  fail_unless(client_connect(NULL, "user", "password", "resource", 10, AUTH_PLAIN) == 0,
+      "Passing a NULL client to client_connect should return a failure");
+  fail_unless(client_connect(a_client, "user", "password", "resource", 10, AUTH_PLAIN) == 1,
+      "A successful call to client_connect should return a 1, provided session_connect is successful");
+  fail_unless(strcmp(a_client->xmpp_id, "user@server/resource") == 0,
+      "A successful call to client_connect should set the correct xmpp_id in the client");
+END_TEST
+
+START_TEST(test_transport_client_disconnect)
+  fail_unless(client_disconnect(NULL) == 0,
+      "client_disconnect should return 0 if no client arg is passed");
+  fail_unless(client_disconnect(a_client) == 1,
+      "client_disconnect should return 1 if successful");
+END_TEST
+
+START_TEST(test_transport_client_connected)
+  fail_unless(client_connected(NULL) == 0,
+      "client_connected should return 0 if no client arg is passed");
+  fail_unless(client_connected(a_client) == 1,
+      "client_connected should return 1 if successful");
+END_TEST
+
+START_TEST(test_transport_client_send_message)
+  fail_unless(client_send_message(NULL, a_message) == -1,
+      "client_send_message should return -1 if client arg is NULL");
+  a_client->error = 1;
+  //fail_unless(client_send_message(a_client->session, a_message") == -1,
+  //"client_send_message should return -1 if client->error is true");
+  a_client->error = 0;
+  //fail_unless(client_send_message(a_client->session, a_message) == 0,
+  //"client_send_message should return 0 on success");
+  //fail_unless(strcmp(a_message->sender, "user") == 0,
+  //"client_send_message shoud set msg->sender to the value of client->xmpp_id");
+END_TEST
+
+START_TEST(test_transport_client_recv)
+  //NULL client case
+  fail_unless(client_recv(NULL, 10) == NULL,
+      "client_recv should return NULL if the client arg is NULL");
+
+  //Message at head of queue
+  a_client->msg_q_head = a_message; //put a message at the head of the queue
+  transport_message *msg = client_recv(a_client, 10);
+  fail_if(msg == NULL,
+      "client_recv should return a transport_message on success");
+  fail_unless(a_client->msg_q_head == NULL,
+      "client_recv should remove the message from client->msg_q_head if it is successful");
+  fail_unless(msg->next == NULL,
+      "client_recv should set msg->next to NULL");
+  fail_unless(a_client->msg_q_tail == NULL,
+      "client_recv should set client->msg_q_tail to NULL if there was only one message in the queue");
+
+  //session_wait failure with no timeout
+  transport_client* other_client = client_init("server2", 4321, "unixpath2", 321);
+  transport_message *msg2 = client_recv(other_client, -1);
+  fail_unless(msg2 == NULL,
+      "client_recv should return NULL if the call to session_wait() returns an error");
+  fail_unless(other_client->error == 1,
+      "client_recv should set client->error to true if an error has occured");
+
+  //message in queue with no timeout
+  transport_message *msg3 = client_recv(a_client, -1);
+  fail_unless(msg3->next == NULL,
+      "client_recv should set msg->next to NULL");
+  fail_unless(a_client->msg_q_head == NULL,
+      "client_recv should set client->msg_q_head to NULL if there are no more queued messages");
+  fail_unless(a_client->msg_q_tail == NULL,
+      "client_recv should set client->msg_q_tail to NULL if client->msg_q_head was NULL");
+  fail_unless(strcmp(msg3->body, "body1") == 0,
+      "the message returned by client_recv should contain the contents of the message that was received");
+  fail_unless(strcmp(msg3->subject, "subject1") == 0,
+      "the message returned by client_recv should contain the contents of the message that was received");
+  fail_unless(strcmp(msg3->thread, "thread1") == 0,
+      "the message returned by client_recv should contain the contents of the message that was received");
+  fail_unless(strcmp(msg3->recipient, "recipient1") == 0,
+      "the message returned by client_recv should contain the contents of the message that was received");
+  fail_unless(strcmp(msg3->sender, "sender1") == 0,
+      "the message returned by client_recv should contain the contents of the message that was received");
+
+  //No message in queue with timeout
+  a_client->error = 0;
+  transport_message *msg4 = client_recv(a_client, 1); //only 1 sec timeout so we dont slow down testing
+  fail_unless(msg4 == NULL,
+      "client_recv should return NULL if there is no message in queue to receive");
+  fail_unless(a_client->error == 0,
+      "client->error should be 0 since there was no error");
+
+  //session_wait failure with timeout
+  other_client->error = 0;
+  transport_message *msg5 = client_recv(other_client, 1); //only 1 sec again...
+  fail_unless(msg5 == NULL,
+      "client_recv should return NULL if there is an error");
+  fail_unless(other_client->error == 1,
+      "client_recv should set client->error to 1 if there is an error");
+END_TEST
+
+START_TEST(test_transport_client_free)
+  fail_unless(client_free(NULL) == 0,
+      "client_free should retun 0 if passed a NULL arg");
+  transport_client* client1 = client_init("server", 1234, "unixpath", 123);
+  fail_unless(client_free(client1) == 1,
+      "client_free should return 0 if successful");
+END_TEST
+
+START_TEST(test_transport_client_discard)
+  fail_unless(client_discard(NULL) == 0,
+      "client_discard should return 0 if passed a NULL arg");
+  transport_client* client1 = client_init("server", 1234, "unixpath", 123);
+  fail_unless(client_discard(client1) == 1,
+      "client_discard should return 1 if successful");
+END_TEST
+
+START_TEST(test_transport_client_sock_fd)
+  fail_unless(client_sock_fd(NULL) == 0,
+      "client_sock_fd should return 0 if passed a NULL arg");
+  a_client->session->sock_id = 1;
+  fail_unless(client_sock_fd(a_client) == 1,
+      "client_sock_fd should return client->session->sock_id");
+END_TEST
+
+//END TESTS
+
+Suite *transport_client_suite(void) {
+  //Create test suite, test case, initialize fixture
+  Suite *s = suite_create("transport_client");
+  TCase *tc_core = tcase_create("Core");
+  tcase_add_checked_fixture(tc_core, setup, teardown);
+
+  //Add tests to test case
+  tcase_add_test(tc_core, test_transport_client_init);
+  tcase_add_test(tc_core, test_transport_client_connect);
+  tcase_add_test(tc_core, test_transport_client_disconnect);
+  tcase_add_test(tc_core, test_transport_client_connected);
+  tcase_add_test(tc_core, test_transport_client_send_message);
+  tcase_add_test(tc_core, test_transport_client_recv);
+  tcase_add_test(tc_core, test_transport_client_free);
+  tcase_add_test(tc_core, test_transport_client_discard);
+  tcase_add_test(tc_core, test_transport_client_sock_fd);
+
+  //Add test case to test suite
+  suite_add_tcase(s, tc_core);
+
+  return s;
+}
+
+void run_tests(SRunner *sr) {
+  srunner_add_suite(sr, transport_client_suite());
+}
diff --git a/tests/check_transport_message.c b/tests/check_transport_message.c
new file mode 100644 (file)
index 0000000..293ba5d
--- /dev/null
@@ -0,0 +1,279 @@
+#include <check.h>
+#include "opensrf/transport_message.h"
+
+transport_message *a_message; 
+
+//Set up the test fixture
+void setup(void) {
+  a_message = message_init("body", "subject", "thread", "recipient", "sender");
+}
+
+//Clean up the test fixture
+void teardown(void) {
+  message_free(a_message);
+}
+
+//BEGIN TESTS
+
+START_TEST(test_transport_message_init_empty)
+  transport_message* empty_message = message_init(NULL, NULL, NULL, NULL, NULL);
+  fail_if(empty_message == NULL, "transport_message wasn't created");
+  fail_unless(strcmp(empty_message->body, "") == 0,
+      "When calling message_init, an NULL body arg should yield an empty string");
+  fail_unless(strcmp(empty_message->thread, "") == 0,
+      "When calling message_init, an NULL thread arg should yield an empty string");
+  fail_unless(strcmp(empty_message->subject, "") == 0,
+      "When calling message_init, an NULL subject arg should yield an empty string");
+  fail_unless(strcmp(empty_message->recipient, "") == 0,
+      "When calling message_init, an NULL recipient arg should yield an empty string");
+  fail_unless(strcmp(empty_message->sender, "") == 0,
+      "When calling message_init, an NULL sender arg should yield an empty string");
+  fail_unless(empty_message->router_from == NULL,
+      "message_init should set the router_from field to NULL");
+  fail_unless(empty_message->router_to == NULL,
+      "message_init should set the router_to field to NULL");
+  fail_unless(empty_message->router_class == NULL,
+      "message_init should set the router_class field to NULL");
+  fail_unless(empty_message->router_command == NULL,
+      "message_init should set the router_command field to NULL");
+  fail_unless(empty_message->osrf_xid == NULL,
+      "message_init should set the osrf_xid field to NULL");
+  fail_unless(empty_message->is_error == 0,
+      "message_init should set the is_error field to 0");
+  fail_unless(empty_message->error_type == NULL,
+      "message_init should set the error_type field to NULL");
+  fail_unless(empty_message->error_code == 0,
+      "message_init should set the error_code field to 0");
+  fail_unless(empty_message->broadcast == 0,
+      "message_init should set the broadcast field to 0");
+  fail_unless(empty_message->msg_xml == NULL,
+      "message_init should set the msg_xml field to NULL");
+  fail_unless(empty_message->next == NULL,
+      "message_init should set the next field to NULL");
+END_TEST
+
+START_TEST(test_transport_message_init_populated)
+  fail_if(a_message == NULL, "transport_message wasn't created");
+  fail_unless(strcmp(a_message->body, "body") == 0,
+      "When calling message_init, an body arg should be stored in the body field");
+  fail_unless(strcmp(a_message->thread, "thread") == 0,
+      "When calling message_init, an thread arg should be stored in the thread field");
+  fail_unless(strcmp(a_message->subject, "subject") == 0,
+      "When calling message_init, a subject arg should be stored in the subject field");
+  fail_unless(strcmp(a_message->recipient, "recipient") == 0,
+      "When calling message_init, a recipient arg should be stored in the recipient field");
+  fail_unless(strcmp(a_message->sender, "sender") == 0,
+      "When calling message_init, a sender arg should be stored in the sender field");
+END_TEST
+
+START_TEST(test_transport_message_new_message_from_xml_empty)
+  fail_unless(new_message_from_xml(NULL) == NULL,
+      "Passing NULL to new_message_from_xml should return NULL");
+  fail_unless(new_message_from_xml("\0") == NULL,
+      "Passing a NULL string to new_message_from_xml should return NULL");
+
+  const char* empty_msg = "<message/>";
+  transport_message* t_msg = new_message_from_xml(empty_msg);
+  fail_if(t_msg == NULL,
+      "new_message_from_xml should create a new transport_message");
+  fail_unless(strcmp(t_msg->thread, "") == 0,
+      "When passed no thread, msg->thread should be set to an empty string");
+  fail_unless(strcmp(t_msg->subject, "") == 0,
+      "When passed no subject, msg->subject should be set to an empty string");
+  fail_unless(strcmp(t_msg->body, "") == 0,
+      "When passed no body, msg->body should be set to an empty string");
+  fail_unless(t_msg->recipient == NULL,
+      "When passed no recipient, msg->recipient should be NULL");
+  fail_unless(t_msg->sender == NULL,
+      "When passed no sender, msg->sender should be NULL");
+  fail_unless(t_msg->router_from == NULL,
+      "When passed no router_from, msg->router_from should be NULL");
+  fail_unless(t_msg->router_to == NULL,
+      "When passed no router_to, msg->router_to should be NULL");
+  fail_unless(t_msg->router_class == NULL,
+      "When passed no router_class, msg->router_class should be NULL");
+  fail_unless(t_msg->router_command == NULL,
+      "router_command should never be passed, and therefore should be NULL");
+  fail_unless(t_msg->osrf_xid == NULL,
+      "When passed no osrf_xid, msg->osrf_xid should be NULL");
+  fail_unless(t_msg->is_error == 0,
+      "is_error should never be passed, and msg->is_error should be set to 0");
+  fail_unless(t_msg->error_type == NULL,
+      "error_type should never be passed, and should be NULL");
+  fail_unless(t_msg->error_code == 0,
+      "error_code should never be passed, and msg->error_code should be set to 0");
+  fail_unless(t_msg->broadcast == 0,
+      "When passed no broadcast, msg->broadcast should be set to 0");
+  fail_unless(strcmp(t_msg->msg_xml, "<message/>") == 0,
+      "msg->msg_xml should contain the contents of the original xml message");
+  fail_unless(t_msg->next == NULL, "msg->next should be set to NULL");
+END_TEST
+
+START_TEST(test_transport_message_new_message_from_xml_populated)
+  const char* xml_jabber_msg =
+    "<message from=\"sender\" to=\"receiver\" router_from=\"routerfrom\" router_to=\"routerto\" router_class=\"class\" broadcast=\"1\" osrf_xid=\"xid\"><thread>thread_value</thread><subject>subject_value</subject><body>body_value</body></message>";
+
+  transport_message *my_msg = new_message_from_xml(xml_jabber_msg);
+  fail_if(my_msg == NULL, "new_message_from_xml failed to create a transport_message");
+  fail_unless(strcmp(my_msg->sender, "routerfrom") == 0,
+      "new_message_from_xml should populate the sender field");
+  fail_unless(strcmp(my_msg->recipient, "receiver") == 0,
+      "new_message_from_xml should populate the receiver field");
+  fail_unless(strcmp(my_msg->osrf_xid, "xid") == 0,
+      "new_message_from_xml should populate the osrf_xid field");
+  fail_unless(strcmp(my_msg->router_from, "routerfrom") == 0,
+      "new_message_from_xml should populate the router_from field");
+  fail_unless(strcmp(my_msg->subject, "subject_value") == 0,
+      "new_message_from_xml should populate the subject field");
+  fail_unless(strcmp(my_msg->thread, "thread_value") == 0,
+      "new_message_from_xml should populate the thread field");
+  fail_unless(strcmp(my_msg->router_to, "routerto") == 0,
+      "new_message_from_xml should populate the router_to field");
+  fail_unless(strcmp(my_msg->router_class, "class") == 0,
+      "new_message_from_xml should populate the router_class field");
+  fail_unless(my_msg->broadcast == 1,
+      "new_message_from_xml should populate the broadcast field");
+  fail_unless(strcmp(my_msg->msg_xml, xml_jabber_msg) == 0,
+      "new_message_from_xml should store the original xml msg in msg_xml");
+END_TEST
+
+START_TEST(test_transport_message_set_osrf_xid)
+  message_set_osrf_xid(a_message, "abcd");
+  fail_unless(strcmp(a_message->osrf_xid, "abcd") == 0,
+      "message_set_osrf_xid should set msg->osrf_xid to the value of the osrf_xid arg");
+  message_set_osrf_xid(a_message, NULL);
+  fail_unless(strcmp(a_message->osrf_xid, "") == 0,
+      "message_set_osrf_xid should set msg->osrf_xid to an empty string if osrf_xid arg is NULL");
+END_TEST
+
+START_TEST(test_transport_message_set_router_info_empty)
+  message_set_router_info(a_message, NULL, NULL, NULL, NULL, 0);
+  fail_unless(strcmp(a_message->router_from, "") == 0,
+      "message_set_router_info should set msg->router_from to empty string if NULL router_from arg is passed");
+  fail_unless(strcmp(a_message->router_to, "") == 0,
+      "message_set_router_info should set msg->router_to to empty string if NULL router_to arg is passed");
+  fail_unless(strcmp(a_message->router_class, "") == 0,
+      "message_set_router_info should set msg->router_class to empty string if NULL router_class arg is passed");
+  fail_unless(strcmp(a_message->router_command, "") == 0,
+      "message_set_router_info should set msg->router_command to empty string if NULL router_command arg is passed");
+  fail_unless(a_message->broadcast == 0,
+      "message_set_router_info should set msg->broadcast to the content of the broadcast_enabled arg");
+END_TEST
+
+START_TEST(test_transport_message_set_router_info_populated)
+  message_set_router_info(a_message, "routerfrom", "routerto", "routerclass", "routercmd", 1);
+  fail_unless(strcmp(a_message->router_from, "routerfrom") == 0,
+      "message_set_router_info should set msg->router_from to the value of the router_from arg");
+  fail_unless(strcmp(a_message->router_to, "routerto") == 0,
+      "message_set_router_info should set msg->router_to to the value of the router_to arg");
+  fail_unless(strcmp(a_message->router_class, "routerclass") == 0,
+      "message_set_router_info should set msg->router_class to the value of the router_class arg");
+  fail_unless(strcmp(a_message->router_command, "routercmd") == 0,
+      "message_set_router_info should set msg->router_command to the value of the router_command arg");
+  fail_unless(a_message->broadcast == 1,
+      "message_set_router_info should set msg->broadcast to the value of the broadcast_enabled arg");
+END_TEST
+
+START_TEST(test_transport_message_free)
+  fail_unless(message_free(NULL) == 0,
+      "message_free should return 0 if passed a NULL msg arg");
+  transport_message *msg = message_init("one", "two", "three", "four", "five");
+  fail_unless(message_free(msg) == 1,
+      "message_free should return 1 if successful");
+END_TEST
+
+START_TEST(test_transport_message_prepare_xml)
+  fail_unless(message_prepare_xml(NULL) == 0,
+      "Passing a NULL msg arg to message_prepare_xml should return 0");
+
+  transport_message *msg = message_init(NULL,NULL,NULL,NULL,NULL);
+  msg->msg_xml = "somevalue";
+  fail_unless(message_prepare_xml(msg) == 1,
+      "If msg->msg_xml is already populated, message_prepare_xml should return 1");
+
+  message_set_router_info(a_message, "routerfrom", "routerto", "routerclass", "routercommand", 1);
+  message_set_osrf_xid(a_message, "osrfxid");
+  set_msg_error(a_message, "errortype", 123);
+
+  fail_unless(message_prepare_xml(a_message) == 1,
+      "message_prepare_xml should return 1 upon success");
+  fail_if(a_message->msg_xml == NULL,
+      "message_prepare_xml should store the returned xml in msg->msg_xml");
+  fail_unless(strcmp(a_message->msg_xml, "<message to=\"recipient\" from=\"sender\" router_from=\"routerfrom\" router_to=\"routerto\" router_class=\"routerclass\" router_command=\"routercommand\" osrf_xid=\"osrfxid\" broadcast=\"1\"><error type=\"errortype\" code=\"123\"/><thread>thread</thread><subject>subject</subject><body>body</body></message>") == 0,
+      "message_prepare_xml should store the correct xml in msg->msg_xml");
+END_TEST
+
+START_TEST(test_transport_message_jid_get_username)
+  int buf_size = 15;
+  char buffer[buf_size];
+  jid_get_username("testuser@domain.com/stuff", buffer, buf_size);
+  fail_unless(strcmp(buffer, "testuser") == 0,
+      "jid_get_username should set the buffer to the username extracted from the jid arg");
+END_TEST
+
+START_TEST(test_transport_message_jid_get_resource)
+  char buf_size = 15;
+  char buffer[buf_size];
+  jid_get_resource("testuser@domain.com/stuff", buffer, buf_size);
+  fail_unless(strcmp(buffer, "stuff") == 0,
+      "jid_get_resource should set the buffer to the resource extracted from the jid arg");
+  jid_get_resource("testuser@domain.com", buffer, buf_size);
+  fail_unless(strcmp(buffer, "") == 0,
+      "jid_get_resource should set the buffer to an empty string if there is no resource");
+END_TEST
+
+START_TEST(test_transport_message_jid_get_domain)
+  char buf_size = 15;
+  char buffer[buf_size];
+  jid_get_domain("testuser@domain.com/stuff", buffer, buf_size);
+  fail_unless(strcmp(buffer, "domain.com") == 0,
+      "jid_get_domain should set the buffer to the domain extracted from the jid arg");
+  jid_get_domain("ksdljflksd",  buffer, buf_size);
+  fail_unless(strcmp(buffer, "") == 0,
+      "jid_get_domain should set the buffer to an empty string if the jid is malformed");
+END_TEST
+
+START_TEST(test_transport_message_set_msg_error)
+  set_msg_error(a_message, NULL, 111);
+  fail_unless(a_message->is_error == 1,
+      "set_msg_error called with a NULL error type should only set msg->is_error to 1");
+  set_msg_error(a_message, "fatal", 123);
+  fail_unless(a_message->is_error == 1,
+      "set_msg_error should set msg->is_error to 1");
+  fail_unless(strcmp(a_message->error_type, "fatal") == 0,
+      "set_msg_error should set msg->error_type if error_type arg is passed");
+  fail_unless(a_message->error_code == 123,
+      "set_msg_error should set msg->error_code to the value of the err_code arg");
+END_TEST
+//END TESTS
+
+Suite *transport_message_suite(void) {
+  //Create test suite, test case, initialize fixture
+  Suite *s = suite_create("transport_message");
+  TCase *tc_core = tcase_create("Core");
+  tcase_add_checked_fixture(tc_core, setup, teardown);
+
+  //Add tests to test case
+  tcase_add_test(tc_core, test_transport_message_init_empty);
+  tcase_add_test(tc_core, test_transport_message_init_populated);
+  tcase_add_test(tc_core, test_transport_message_new_message_from_xml_empty);
+  tcase_add_test(tc_core, test_transport_message_new_message_from_xml_populated);
+  tcase_add_test(tc_core, test_transport_message_set_osrf_xid);
+  tcase_add_test(tc_core, test_transport_message_set_router_info_empty);
+  tcase_add_test(tc_core, test_transport_message_set_router_info_populated);
+  tcase_add_test(tc_core, test_transport_message_free);
+  tcase_add_test(tc_core, test_transport_message_prepare_xml);
+  tcase_add_test(tc_core, test_transport_message_jid_get_username);
+  tcase_add_test(tc_core, test_transport_message_jid_get_resource);
+  tcase_add_test(tc_core, test_transport_message_jid_get_domain);
+  tcase_add_test(tc_core, test_transport_message_set_msg_error);
+
+  //Add test case to test suite
+  suite_add_tcase(s, tc_core);
+
+  return s;
+}
+
+void run_tests(SRunner *sr) {
+  srunner_add_suite(sr, transport_message_suite());
+}
diff --git a/tests/testsuite.c b/tests/testsuite.c
new file mode 100644 (file)
index 0000000..e3fcae0
--- /dev/null
@@ -0,0 +1,15 @@
+#include <stdlib.h>
+#include <check.h>
+#include "testsuite.h"
+
+extern void run_tests(SRunner *sr);
+
+int main (int argc, char **argv)
+{
+  SRunner *sr = srunner_create(NULL);
+  run_tests(sr);
+  srunner_run_all(sr, CK_NORMAL);
+  int failed = srunner_ntests_failed(sr);
+  srunner_free(sr);
+  return (failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
+}
diff --git a/tests/testsuite.h b/tests/testsuite.h
new file mode 100644 (file)
index 0000000..b6ef586
--- /dev/null
@@ -0,0 +1,4 @@
+#ifndef __OPENSRF_CHECK_H__
+#define __OPENSRF_CHECK_H__
+
+#endif /* __OPENSRF_CHECK_H__ */