Expand value test coverage
authorPetri Lehtinen <petri@digip.org>
Tue, 18 Aug 2009 18:33:45 +0000 (21:33 +0300)
committerPetri Lehtinen <petri@digip.org>
Sun, 23 Aug 2009 10:34:12 +0000 (13:34 +0300)
test/.gitignore
test/Makefile.am
test/test-api [new file with mode: 0755]
test/testprogs/test_array.c [new file with mode: 0644]
test/testprogs/test_object.c [new file with mode: 0644]
test/testprogs/util.h [new file with mode: 0644]

index 9a580ba..f2f34d3 100644 (file)
@@ -2,3 +2,5 @@ loadf_dumpf
 loads_dumps
 load_file_dump_file
 testlogs
+testprogs/test_array
+testprogs/test_object
index 16c5fd2..9789365 100644 (file)
@@ -1,11 +1,13 @@
-check_PROGRAMS = loadf_dumpf loads_dumps load_file_dump_file
+check_PROGRAMS = \
+       loadf_dumpf loads_dumps load_file_dump_file \
+       testprogs/test_object testprogs/test_array
 
 AM_CPPFLAGS = -I$(top_srcdir)/src
 AM_CFLAGS = -Wall -Werror
 LDFLAGS = -static  # for speed and Valgrind
 LDADD = ../src/libjansson.la
 
-TESTS = test-invalid test-valid
+TESTS = test-api test-invalid test-valid
 
 clean-local:
        rm -rf testlogs
diff --git a/test/test-api b/test/test-api
new file mode 100755 (executable)
index 0000000..04018c1
--- /dev/null
@@ -0,0 +1,46 @@
+#!/bin/sh
+#
+# Copyright (c) 2009 Petri Lehtinen <petri@digip.org>
+#
+# Jansson is free software; you can redistribute it and/or modify
+# it under the terms of the MIT license. See LICENSE for details.
+
+VALGRIND_CMDLINE="valgrind --leak-check=full --show-reachable=yes --track-origins=yes -q"
+LOGDIR="testlogs/api"
+N=`find testprogs -type f -executable | wc -l`
+
+echo "testprogs: $N tests"
+
+rm -rf $LOGDIR
+mkdir -p $LOGDIR
+
+if [ -n "$VALGRIND" ]; then
+    runner="$VALGRIND_CMDLINE "
+fi
+
+i=1
+failed=
+for prog in testprogs/*; do
+    [ -x $prog ] || continue
+    t=`basename $prog`
+    logbase="testlogs/api/`printf '%02d-%s' $i $t`"
+    if ! $runner./$prog >$logbase.stdout 2>$logbase.stderr; then
+        echo >&2
+        echo "### $prog failed:" >&2
+        cat $logbase.stderr
+        exit 1
+    fi
+    if [ -n "$VALGRIND" ]; then
+        # Check for Valgrind error output. The valgrind option
+        # --error-exitcode is not enough because Valgrind doesn't
+        # think unfreed allocs are errors.
+        if grep -E -q '^==[0-9]+== ' $logbase.stderr; then
+            echo "### $prog failed:" >&2
+            echo "valgrind detected an error" >&2
+            echo "for details, see test/$logbase.stderr" >&2
+            exit 1
+        fi
+    fi
+    echo -n '.'
+done
+echo
diff --git a/test/testprogs/test_array.c b/test/testprogs/test_array.c
new file mode 100644 (file)
index 0000000..0ebc3d5
--- /dev/null
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2009 Petri Lehtinen <petri@digip.org>
+ *
+ * Jansson is free software; you can redistribute it and/or modify
+ * it under the terms of the MIT license. See LICENSE for details.
+ */
+
+#include <jansson.h>
+#include "util.h"
+
+int main()
+{
+    json_t *array, *five, *seven, *value;
+    int i;
+
+    array = json_array();
+    five = json_integer(5);
+    seven = json_integer(7);
+
+    if(!array)
+        fail("unable to create array");
+    if(!five)
+        fail("unable to create integer");
+    if(!seven)
+        fail("unable to create integer");
+
+    if(json_array_size(array) != 0)
+        fail("empty array has nonzero size");
+
+    if(json_array_append(array, five))
+        fail("unable to append");
+
+    if(json_array_size(array) != 1)
+        fail("wrong array size");
+
+    value = json_array_get(array, 0);
+    if(!value)
+        fail("unable to get item");
+    if(value != five)
+        fail("got wrong value");
+
+    if(json_array_append(array, seven))
+        fail("unable to append value");
+
+    if(json_array_size(array) != 2)
+        fail("wrong array size");
+
+    value = json_array_get(array, 1);
+    if(!value)
+        fail("unable to get item");
+    if(value != seven)
+        fail("got wrong value");
+
+    if(json_array_set(array, 0, seven))
+        fail("unable to set value");
+
+    if(json_array_size(array) != 2)
+        fail("wrong array size");
+
+    value = json_array_get(array, 0);
+    if(!value)
+        fail("unable to get item");
+    if(value != seven)
+        fail("got wrong value");
+
+    if(json_array_get(array, 2) != NULL)
+        fail("able to get value out of bounds");
+
+    if(!json_array_set(array, 2, seven))
+        fail("able to set value out of bounds");
+
+    for(i = 2; i < 30; i++) {
+        if(json_array_append(array, seven))
+            fail("unable to append value");
+
+        if(json_array_size(array) != i + 1)
+            fail("wrong array size");
+    }
+
+    for(i = 0; i < 30; i++) {
+        value = json_array_get(array, i);
+        if(!value)
+            fail("unable to get item");
+        if(value != seven)
+            fail("got wrong value");
+    }
+
+    json_decref(five);
+    json_decref(seven);
+    json_decref(array);
+
+    return 0;
+}
diff --git a/test/testprogs/test_object.c b/test/testprogs/test_object.c
new file mode 100644 (file)
index 0000000..9f72374
--- /dev/null
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2009 Petri Lehtinen <petri@digip.org>
+ *
+ * Jansson is free software; you can redistribute it and/or modify
+ * it under the terms of the MIT license. See LICENSE for details.
+ */
+
+#include <jansson.h>
+#include "util.h"
+
+int main()
+{
+    json_t *object, *string, *other_string, *value;
+
+    object = json_object();
+    string = json_string("test");
+    other_string = json_string("other");
+
+    if(!object)
+        fail("unable to create object");
+    if(!string)
+        fail("unable to create string");
+    if(!other_string)
+        fail("unable to create string");
+
+    if(json_object_get(object, "a"))
+        fail("value for nonexisting key");
+
+    if(json_object_set(object, "a", string))
+        fail("unable to set value");
+
+    /* invalid UTF-8 in key */
+    if(!json_object_set(object, "a\xefz", string))
+        fail("able to set invalid unicode key");
+
+    value = json_object_get(object, "a");
+    if(!value)
+        fail("no value for existing key");
+    if(value != string)
+        fail("got different value than what was added");
+
+    /* "a", "lp" and "px" collide with a five-bucket hashtable */
+    if(json_object_set(object, "b", string) ||
+       json_object_set(object, "lp", string) ||
+       json_object_set(object, "px", string))
+        fail("unable to set value");
+
+    value = json_object_get(object, "a");
+    if(!value)
+        fail("no value for existing key");
+    if(value != string)
+        fail("got different value than what was added");
+
+    if(json_object_set(object, "a", other_string))
+        fail("unable to replace an existing key");
+
+    value = json_object_get(object, "a");
+    if(!value)
+        fail("no value for existing key");
+    if(value != other_string)
+        fail("got different value than what was set");
+
+    if(!json_object_del(object, "nonexisting"))
+        fail("able to delete a nonexisting key");
+
+    if(json_object_del(object, "px"))
+        fail("unable to delete an existing key");
+
+    if(json_object_del(object, "a"))
+        fail("unable to delete an existing key");
+
+    if(json_object_del(object, "lp"))
+        fail("unable to delete an existing key");
+
+
+    /* add many keys to  rehashing */
+
+    if(json_object_set(object, "a", string))
+        fail("unable to set value");
+
+    if(json_object_set(object, "lp", string))
+        fail("unable to set value");
+
+    if(json_object_set(object, "px", string))
+        fail("unable to set value");
+
+    if(json_object_set(object, "c", string))
+        fail("unable to set value");
+
+    if(json_object_set(object, "d", string))
+        fail("unable to set value");
+
+    if(json_object_set(object, "e", string))
+        fail("unable to set value");
+
+    json_decref(string);
+    json_decref(other_string);
+    json_decref(object);
+
+    return 0;
+}
diff --git a/test/testprogs/util.h b/test/testprogs/util.h
new file mode 100644 (file)
index 0000000..684b604
--- /dev/null
@@ -0,0 +1,10 @@
+#ifndef TESTPROGS_UTIL_H
+#define TESTPROGS_UTIL_H
+
+#define fail(msg)                                                \
+    do {                                                         \
+        fprintf(stderr, "%s:%d: %s\n", __FILE__, __LINE__, msg); \
+        return 1;                                                \
+    } while(0)
+
+#endif