Add a C unit testing framework and tests for OpenSRF
[opensrf-equinox.git] / tests / check_osrf_json_object.c
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());
+}