mirror of
https://github.com/json-c/json-c.git
synced 2026-03-27 08:59:07 +08:00
Move the rest of the tests into the tests subdirectory.
This commit is contained in:
@@ -1,17 +1,25 @@
|
||||
|
||||
include ../Makefile.am.inc
|
||||
|
||||
#lib_LTLIBRARIES = ../libjson.la
|
||||
lib_LTLIBRARIES = $(top_builddir)/libjson.la
|
||||
|
||||
#check_PROGRAMS = test1 test2 test4 test_parse_int64 test_null test_cast test_parse
|
||||
check_PROGRAMS = test1
|
||||
check_PROGRAMS = test1 test2 test4 test_parse_int64 test_null test_cast test_parse
|
||||
|
||||
#test1_SOURCES = test1.c
|
||||
#test1_LDADD = $(lib_LTLIBRARIES)
|
||||
test1_LDADD = $(top_builddir)/libjson.la
|
||||
test1_LDADD = $(lib_LTLIBRARIES)
|
||||
|
||||
#TESTS = test1.test test2.test test4.test parse_int64.test test_null.test test_cast.test test_parse.test
|
||||
TESTS = test1.test
|
||||
test2_LDADD = $(lib_LTLIBRARIES)
|
||||
|
||||
test4_LDADD = $(lib_LTLIBRARIES)
|
||||
|
||||
test_parse_int64_LDADD = $(lib_LTLIBRARIES)
|
||||
|
||||
test_null_LDADD = $(lib_LTLIBRARIES)
|
||||
|
||||
test_cast_LDADD = $(lib_LTLIBRARIES)
|
||||
|
||||
test_parse_LDADD = $(lib_LTLIBRARIES)
|
||||
|
||||
TESTS = test1.test test2.test test4.test parse_int64.test test_null.test test_cast.test test_parse.test
|
||||
EXTRA_DIST=
|
||||
EXTRA_DIST += $(TESTS)
|
||||
|
||||
|
||||
12
tests/parse_int64.test
Executable file
12
tests/parse_int64.test
Executable file
@@ -0,0 +1,12 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Common definitions
|
||||
if test -z "$srcdir"; then
|
||||
srcdir="${0%/*}"
|
||||
test "$srcdir" = "$0" && srcdir=.
|
||||
test -z "$srcdir" && srcdir=.
|
||||
fi
|
||||
. "$srcdir/test-defs.sh"
|
||||
|
||||
run_output_test test_parse_int64
|
||||
exit $?
|
||||
115
tests/test-defs.sh
Executable file
115
tests/test-defs.sh
Executable file
@@ -0,0 +1,115 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Make sure srcdir is an absolute path. Supply the variable
|
||||
# if it does not exist. We want to be able to run the tests
|
||||
# stand-alone!!
|
||||
#
|
||||
srcdir=${srcdir-.}
|
||||
if test ! -d $srcdir ; then
|
||||
echo "test-defs.sh: installation error" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Use absolute paths
|
||||
case "$srcdir" in
|
||||
/* | [A-Za-z]:\\*) ;;
|
||||
*) srcdir=`\cd $srcdir && pwd` ;;
|
||||
esac
|
||||
|
||||
case "$top_builddir" in
|
||||
/* | [A-Za-z]:\\*) ;;
|
||||
*) top_builddir=`\cd ${top_builddir-..} && pwd` ;;
|
||||
esac
|
||||
|
||||
top_builddir=${top_builddir}/tests
|
||||
|
||||
progname=`echo "$0" | sed 's,^.*/,,'`
|
||||
testname=`echo "$progname" | sed 's,-.*$,,'`
|
||||
testsubdir=${testsubdir-testSubDir}
|
||||
|
||||
# User can set VERBOSE to cause output redirection
|
||||
case "$VERBOSE" in
|
||||
[Nn]|[Nn][Oo]|0|"")
|
||||
VERBOSE=0
|
||||
exec > /dev/null 2>&1
|
||||
;;
|
||||
[Yy]|[Yy][Ee][Ss])
|
||||
VERBOSE=1
|
||||
;;
|
||||
esac
|
||||
|
||||
rm -rf "$testsubdir/$progname" > /dev/null 2>&1
|
||||
mkdir -p "$testsubdir/$progname"
|
||||
cd "$testsubdir/$progname" \
|
||||
|| { echo "Cannot make or change into $testsubdir/$progname"; exit 1; }
|
||||
|
||||
echo "=== Running test $progname"
|
||||
|
||||
CMP="${CMP-cmp}"
|
||||
|
||||
use_valgrind=${USE_VALGRIND-1}
|
||||
valgrind_path=$(which valgrind 2> /dev/null)
|
||||
if [ -z "${valgrind_path}" -o ! -x "${valgrind_path}" ] ; then
|
||||
use_valgrind=0
|
||||
fi
|
||||
|
||||
#
|
||||
# This is a common function to check the results of a test program
|
||||
# that is intended to generate consistent output across runs.
|
||||
#
|
||||
# ${top_builddir} must be set to the top level build directory.
|
||||
#
|
||||
# Output will be written to the current directory.
|
||||
#
|
||||
# It must be passed the name of the test command to run, which must be present
|
||||
# in the ${top_builddir} directory.
|
||||
#
|
||||
# It will compare the output of running that against <name of command>.expected
|
||||
#
|
||||
run_output_test()
|
||||
{
|
||||
TEST_COMMAND="$1"
|
||||
|
||||
REDIR_OUTPUT="> \"${TEST_COMMAND}.out\""
|
||||
if [ $VERBOSE -gt 1 ] ; then
|
||||
REDIR_OUTPUT="| tee \"${TEST_COMMAND}.out\""
|
||||
fi
|
||||
|
||||
if [ $use_valgrind -eq 1 ] ; then
|
||||
eval valgrind --tool=memcheck \
|
||||
--trace-children=yes \
|
||||
--demangle=yes \
|
||||
--log-file=vg.out \
|
||||
--leak-check=full \
|
||||
--show-reachable=yes \
|
||||
--run-libc-freeres=yes \
|
||||
"\"${top_builddir}/${TEST_COMMAND}\"" ${REDIR_OUTPUT}
|
||||
err=$?
|
||||
|
||||
else
|
||||
eval "\"${top_builddir}/${TEST_COMMAND}"\" ${REDIR_OUTPUT}
|
||||
err=$?
|
||||
fi
|
||||
|
||||
if [ $err -ne 0 ] ; then
|
||||
echo "ERROR: ${TEST_COMMAND} exited with non-zero exit status: $err" 1>&2
|
||||
fi
|
||||
|
||||
if [ $use_valgrind -eq 1 ] ; then
|
||||
if ! tail -1 "vg.out" | grep -q "ERROR SUMMARY: 0 errors" ; then
|
||||
echo "ERROR: valgrind found errors during execution:" 1>&2
|
||||
cat vg.out
|
||||
err=1
|
||||
fi
|
||||
fi
|
||||
|
||||
if ! "$CMP" -s "${top_builddir}/${TEST_COMMAND}.expected" "${TEST_COMMAND}.out" ; then
|
||||
echo "ERROR: ${TEST_COMMAND} failed:" 1>&2
|
||||
diff "${top_builddir}/${TEST_COMMAND}.expected" "${TEST_COMMAND}.out" 1>&2
|
||||
err=1
|
||||
fi
|
||||
|
||||
return $err
|
||||
}
|
||||
|
||||
|
||||
20
tests/test2.c
Normal file
20
tests/test2.c
Normal file
@@ -0,0 +1,20 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "json.h"
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
json_object *new_obj;
|
||||
|
||||
MC_SET_DEBUG(1);
|
||||
|
||||
new_obj = json_tokener_parse("/* more difficult test case */ { \"glossary\": { \"title\": \"example glossary\", \"GlossDiv\": { \"title\": \"S\", \"GlossList\": [ { \"ID\": \"SGML\", \"SortAs\": \"SGML\", \"GlossTerm\": \"Standard Generalized Markup Language\", \"Acronym\": \"SGML\", \"Abbrev\": \"ISO 8879:1986\", \"GlossDef\": \"A meta-markup language, used to create markup languages such as DocBook.\", \"GlossSeeAlso\": [\"GML\", \"XML\", \"markup\"] } ] } } }");
|
||||
printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
|
||||
json_object_put(new_obj);
|
||||
|
||||
return 0;
|
||||
}
|
||||
1
tests/test2.expected
Normal file
1
tests/test2.expected
Normal file
@@ -0,0 +1 @@
|
||||
new_obj.to_string()={ "glossary": { "title": "example glossary", "GlossDiv": { "title": "S", "GlossList": [ { "ID": "SGML", "SortAs": "SGML", "GlossTerm": "Standard Generalized Markup Language", "Acronym": "SGML", "Abbrev": "ISO 8879:1986", "GlossDef": "A meta-markup language, used to create markup languages such as DocBook.", "GlossSeeAlso": [ "GML", "XML", "markup" ] } ] } } }
|
||||
12
tests/test2.test
Executable file
12
tests/test2.test
Executable file
@@ -0,0 +1,12 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Common definitions
|
||||
if test -z "$srcdir"; then
|
||||
srcdir="${0%/*}"
|
||||
test "$srcdir" = "$0" && srcdir=.
|
||||
test -z "$srcdir" && srcdir=.
|
||||
fi
|
||||
. "$srcdir/test-defs.sh"
|
||||
|
||||
run_output_test test2
|
||||
exit $?
|
||||
49
tests/test4.c
Normal file
49
tests/test4.c
Normal file
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* gcc -o utf8 utf8.c -I/home/y/include -L./.libs -ljson
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "config.h"
|
||||
|
||||
#include "json_inttypes.h"
|
||||
#include "json_object.h"
|
||||
#include "json_tokener.h"
|
||||
|
||||
void print_hex( const char* s) {
|
||||
const char *iter = s;
|
||||
unsigned char ch;
|
||||
while ((ch = *iter++) != 0) {
|
||||
if( ',' != ch)
|
||||
printf("%x ", ch);
|
||||
else
|
||||
printf( ",");
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
int main() {
|
||||
const char *input = "\"\\ud840\\udd26,\\ud840\\udd27,\\ud800\\udd26,\\ud800\\udd27\"";
|
||||
const char *expected = "\xF0\xA0\x84\xA6,\xF0\xA0\x84\xA7,\xF0\x90\x84\xA6,\xF0\x90\x84\xA7";
|
||||
struct json_object *parse_result = json_tokener_parse((char*)input);
|
||||
const char *unjson = json_object_get_string(parse_result);
|
||||
|
||||
printf("input: %s\n", input);
|
||||
|
||||
int strings_match = !strcmp( expected, unjson);
|
||||
int retval = 0;
|
||||
if (strings_match) {
|
||||
printf("JSON parse result is correct: %s\n", unjson);
|
||||
printf("PASS\n");
|
||||
} else {
|
||||
printf("JSON parse result doesn't match expected string\n");
|
||||
printf("expected string bytes: ");
|
||||
print_hex( expected);
|
||||
printf("parsed string bytes: ");
|
||||
print_hex( unjson);
|
||||
printf("FAIL\n");
|
||||
retval = 1;
|
||||
}
|
||||
json_object_put(parse_result);
|
||||
return retval;
|
||||
}
|
||||
3
tests/test4.expected
Normal file
3
tests/test4.expected
Normal file
@@ -0,0 +1,3 @@
|
||||
input: "\ud840\udd26,\ud840\udd27,\ud800\udd26,\ud800\udd27"
|
||||
JSON parse result is correct: 𠄦,𠄧,𐄦,𐄧
|
||||
PASS
|
||||
12
tests/test4.test
Executable file
12
tests/test4.test
Executable file
@@ -0,0 +1,12 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Common definitions
|
||||
if test -z "$srcdir"; then
|
||||
srcdir="${0%/*}"
|
||||
test "$srcdir" = "$0" && srcdir=.
|
||||
test -z "$srcdir" && srcdir=.
|
||||
fi
|
||||
. "$srcdir/test-defs.sh"
|
||||
|
||||
run_output_test test4
|
||||
exit $?
|
||||
106
tests/test_cast.c
Normal file
106
tests/test_cast.c
Normal file
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
* Tests if casting within the json_object_get_* functions work correctly.
|
||||
* Also checks the json_object_get_type and json_object_is_type functions.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "config.h"
|
||||
|
||||
#include "json_inttypes.h"
|
||||
#include "json_object.h"
|
||||
#include "json_tokener.h"
|
||||
#include "json_util.h"
|
||||
|
||||
static void getit(struct json_object *new_obj, const char *field);
|
||||
static void checktype_header(void);
|
||||
static void checktype(struct json_object *new_obj, const char *field);
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const char *input = "{\n\
|
||||
\"string_of_digits\": \"123\",\n\
|
||||
\"regular_number\": 222,\n\
|
||||
\"decimal_number\": 99.55,\n\
|
||||
\"boolean_true\": true,\n\
|
||||
\"boolean_false\": false,\n\
|
||||
\"big_number\": 2147483649,\n\
|
||||
\"a_null\": null,\n\
|
||||
}";
|
||||
/* Note: 2147483649 = INT_MAX + 2 */
|
||||
|
||||
struct json_object *new_obj;
|
||||
|
||||
new_obj = json_tokener_parse(input);
|
||||
printf("Parsed input: %s\n", input);
|
||||
printf("Result is %s\n", (new_obj == NULL) ? "NULL (error!)" : "not NULL");
|
||||
if (!new_obj)
|
||||
return 1; // oops, we failed.
|
||||
|
||||
getit(new_obj, "string_of_digits");
|
||||
getit(new_obj, "regular_number");
|
||||
getit(new_obj, "decimal_number");
|
||||
getit(new_obj, "boolean_true");
|
||||
getit(new_obj, "boolean_false");
|
||||
getit(new_obj, "big_number");
|
||||
getit(new_obj, "a_null");
|
||||
|
||||
// Now check the behaviour of the json_object_is_type() function.
|
||||
printf("\n================================\n");
|
||||
checktype_header();
|
||||
checktype(new_obj, NULL);
|
||||
checktype(new_obj, "string_of_digits");
|
||||
checktype(new_obj, "regular_number");
|
||||
checktype(new_obj, "decimal_number");
|
||||
checktype(new_obj, "boolean_true");
|
||||
checktype(new_obj, "boolean_false");
|
||||
checktype(new_obj, "big_number");
|
||||
checktype(new_obj, "a_null");
|
||||
|
||||
json_object_put(new_obj);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void getit(struct json_object *new_obj, const char *field)
|
||||
{
|
||||
struct json_object *o = json_object_object_get(new_obj, field);
|
||||
|
||||
enum json_type o_type = json_object_get_type(o);
|
||||
printf("new_obj.%s json_object_get_type()=%s\n", field,
|
||||
json_type_to_name(o_type));
|
||||
printf("new_obj.%s json_object_get_int()=%d\n", field,
|
||||
json_object_get_int(o));
|
||||
printf("new_obj.%s json_object_get_int64()=%" PRId64 "\n", field,
|
||||
json_object_get_int64(o));
|
||||
printf("new_obj.%s json_object_get_boolean()=%d\n", field,
|
||||
json_object_get_boolean(o));
|
||||
printf("new_obj.%s json_object_get_double()=%f\n", field,
|
||||
json_object_get_double(o));
|
||||
}
|
||||
|
||||
static void checktype_header()
|
||||
{
|
||||
printf("json_object_is_type: %s,%s,%s,%s,%s,%s,%s\n",
|
||||
json_type_to_name(json_type_null),
|
||||
json_type_to_name(json_type_boolean),
|
||||
json_type_to_name(json_type_double),
|
||||
json_type_to_name(json_type_int),
|
||||
json_type_to_name(json_type_object),
|
||||
json_type_to_name(json_type_array),
|
||||
json_type_to_name(json_type_string));
|
||||
}
|
||||
static void checktype(struct json_object *new_obj, const char *field)
|
||||
{
|
||||
struct json_object *o = field ? json_object_object_get(new_obj, field) : new_obj;
|
||||
printf("new_obj%s%-18s: %d,%d,%d,%d,%d,%d,%d\n",
|
||||
field ? "." : " ", field ? field : "",
|
||||
json_object_is_type(o, json_type_null),
|
||||
json_object_is_type(o, json_type_boolean),
|
||||
json_object_is_type(o, json_type_double),
|
||||
json_object_is_type(o, json_type_int),
|
||||
json_object_is_type(o, json_type_object),
|
||||
json_object_is_type(o, json_type_array),
|
||||
json_object_is_type(o, json_type_string));
|
||||
}
|
||||
56
tests/test_cast.expected
Normal file
56
tests/test_cast.expected
Normal file
@@ -0,0 +1,56 @@
|
||||
Parsed input: {
|
||||
"string_of_digits": "123",
|
||||
"regular_number": 222,
|
||||
"decimal_number": 99.55,
|
||||
"boolean_true": true,
|
||||
"boolean_false": false,
|
||||
"big_number": 2147483649,
|
||||
"a_null": null,
|
||||
}
|
||||
Result is not NULL
|
||||
new_obj.string_of_digits json_object_get_type()=string
|
||||
new_obj.string_of_digits json_object_get_int()=123
|
||||
new_obj.string_of_digits json_object_get_int64()=123
|
||||
new_obj.string_of_digits json_object_get_boolean()=1
|
||||
new_obj.string_of_digits json_object_get_double()=123.000000
|
||||
new_obj.regular_number json_object_get_type()=int
|
||||
new_obj.regular_number json_object_get_int()=222
|
||||
new_obj.regular_number json_object_get_int64()=222
|
||||
new_obj.regular_number json_object_get_boolean()=1
|
||||
new_obj.regular_number json_object_get_double()=222.000000
|
||||
new_obj.decimal_number json_object_get_type()=double
|
||||
new_obj.decimal_number json_object_get_int()=99
|
||||
new_obj.decimal_number json_object_get_int64()=99
|
||||
new_obj.decimal_number json_object_get_boolean()=1
|
||||
new_obj.decimal_number json_object_get_double()=99.550000
|
||||
new_obj.boolean_true json_object_get_type()=boolean
|
||||
new_obj.boolean_true json_object_get_int()=1
|
||||
new_obj.boolean_true json_object_get_int64()=1
|
||||
new_obj.boolean_true json_object_get_boolean()=1
|
||||
new_obj.boolean_true json_object_get_double()=1.000000
|
||||
new_obj.boolean_false json_object_get_type()=boolean
|
||||
new_obj.boolean_false json_object_get_int()=0
|
||||
new_obj.boolean_false json_object_get_int64()=0
|
||||
new_obj.boolean_false json_object_get_boolean()=0
|
||||
new_obj.boolean_false json_object_get_double()=0.000000
|
||||
new_obj.big_number json_object_get_type()=int
|
||||
new_obj.big_number json_object_get_int()=2147483647
|
||||
new_obj.big_number json_object_get_int64()=2147483649
|
||||
new_obj.big_number json_object_get_boolean()=1
|
||||
new_obj.big_number json_object_get_double()=2147483649.000000
|
||||
new_obj.a_null json_object_get_type()=null
|
||||
new_obj.a_null json_object_get_int()=0
|
||||
new_obj.a_null json_object_get_int64()=0
|
||||
new_obj.a_null json_object_get_boolean()=0
|
||||
new_obj.a_null json_object_get_double()=0.000000
|
||||
|
||||
================================
|
||||
json_object_is_type: null,boolean,double,int,object,array,string
|
||||
new_obj : 0,0,0,0,1,0,0
|
||||
new_obj.string_of_digits : 0,0,0,0,0,0,1
|
||||
new_obj.regular_number : 0,0,0,1,0,0,0
|
||||
new_obj.decimal_number : 0,0,1,0,0,0,0
|
||||
new_obj.boolean_true : 0,1,0,0,0,0,0
|
||||
new_obj.boolean_false : 0,1,0,0,0,0,0
|
||||
new_obj.big_number : 0,0,0,1,0,0,0
|
||||
new_obj.a_null : 1,0,0,0,0,0,0
|
||||
12
tests/test_cast.test
Executable file
12
tests/test_cast.test
Executable file
@@ -0,0 +1,12 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Common definitions
|
||||
if test -z "$srcdir"; then
|
||||
srcdir="${0%/*}"
|
||||
test "$srcdir" = "$0" && srcdir=.
|
||||
test -z "$srcdir" && srcdir=.
|
||||
fi
|
||||
. "$srcdir/test-defs.sh"
|
||||
|
||||
run_output_test test_cast
|
||||
exit $?
|
||||
35
tests/test_null.c
Normal file
35
tests/test_null.c
Normal file
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Tests if binary strings are supported.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "config.h"
|
||||
|
||||
#include "json_inttypes.h"
|
||||
#include "json_object.h"
|
||||
|
||||
int main() {
|
||||
// this test has a space after the null character. check that it's still included
|
||||
const char *input = " \0 ";
|
||||
const char *expected = "\" \\u0000 \"";
|
||||
struct json_object *string = json_object_new_string_len(input, 3);
|
||||
const char *json = json_object_to_json_string(string);
|
||||
|
||||
int strings_match = !strcmp( expected, json);
|
||||
int retval = 0;
|
||||
if (strings_match) {
|
||||
printf("JSON write result is correct: %s\n", json);
|
||||
printf("PASS\n");
|
||||
} else {
|
||||
printf("JSON write result doesn't match expected string\n");
|
||||
printf("expected string: ");
|
||||
printf("%s\n", expected);
|
||||
printf("parsed string: ");
|
||||
printf("%s\n", json);
|
||||
printf("FAIL\n");
|
||||
retval=1;
|
||||
}
|
||||
json_object_put(string);
|
||||
return retval;
|
||||
}
|
||||
2
tests/test_null.expected
Normal file
2
tests/test_null.expected
Normal file
@@ -0,0 +1,2 @@
|
||||
JSON write result is correct: " \u0000 "
|
||||
PASS
|
||||
12
tests/test_null.test
Executable file
12
tests/test_null.test
Executable file
@@ -0,0 +1,12 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Common definitions
|
||||
if test -z "$srcdir"; then
|
||||
srcdir="${0%/*}"
|
||||
test "$srcdir" = "$0" && srcdir=.
|
||||
test -z "$srcdir" && srcdir=.
|
||||
fi
|
||||
. "$srcdir/test-defs.sh"
|
||||
|
||||
run_output_test test_null
|
||||
exit $?
|
||||
270
tests/test_parse.c
Normal file
270
tests/test_parse.c
Normal file
@@ -0,0 +1,270 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "json.h"
|
||||
#include "json_tokener.h"
|
||||
|
||||
static void test_basic_parse(void);
|
||||
static void test_verbose_parse(void);
|
||||
static void test_incremental_parse(void);
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
MC_SET_DEBUG(1);
|
||||
|
||||
test_basic_parse();
|
||||
printf("==================================\n");
|
||||
test_verbose_parse();
|
||||
printf("==================================\n");
|
||||
test_incremental_parse();
|
||||
printf("==================================\n");
|
||||
}
|
||||
|
||||
static void test_basic_parse()
|
||||
{
|
||||
json_object *new_obj;
|
||||
|
||||
new_obj = json_tokener_parse("\"\003\"");
|
||||
printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
|
||||
json_object_put(new_obj);
|
||||
|
||||
new_obj = json_tokener_parse("/* hello */\"foo\"");
|
||||
printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
|
||||
json_object_put(new_obj);
|
||||
|
||||
new_obj = json_tokener_parse("// hello\n\"foo\"");
|
||||
printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
|
||||
json_object_put(new_obj);
|
||||
|
||||
new_obj = json_tokener_parse("\"\\u0041\\u0042\\u0043\"");
|
||||
printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
|
||||
json_object_put(new_obj);
|
||||
|
||||
new_obj = json_tokener_parse("null");
|
||||
printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
|
||||
json_object_put(new_obj);
|
||||
|
||||
new_obj = json_tokener_parse("True");
|
||||
printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
|
||||
json_object_put(new_obj);
|
||||
|
||||
new_obj = json_tokener_parse("12");
|
||||
printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
|
||||
json_object_put(new_obj);
|
||||
|
||||
new_obj = json_tokener_parse("12.3");
|
||||
printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
|
||||
json_object_put(new_obj);
|
||||
|
||||
new_obj = json_tokener_parse("[\"\\n\"]");
|
||||
printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
|
||||
json_object_put(new_obj);
|
||||
|
||||
new_obj = json_tokener_parse("[\"\\nabc\\n\"]");
|
||||
printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
|
||||
json_object_put(new_obj);
|
||||
|
||||
new_obj = json_tokener_parse("[null]");
|
||||
printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
|
||||
json_object_put(new_obj);
|
||||
|
||||
new_obj = json_tokener_parse("[]");
|
||||
printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
|
||||
json_object_put(new_obj);
|
||||
|
||||
new_obj = json_tokener_parse("[false]");
|
||||
printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
|
||||
json_object_put(new_obj);
|
||||
|
||||
new_obj = json_tokener_parse("[\"abc\",null,\"def\",12]");
|
||||
printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
|
||||
json_object_put(new_obj);
|
||||
|
||||
new_obj = json_tokener_parse("{}");
|
||||
printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
|
||||
json_object_put(new_obj);
|
||||
|
||||
new_obj = json_tokener_parse("{ \"foo\": \"bar\" }");
|
||||
printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
|
||||
json_object_put(new_obj);
|
||||
|
||||
new_obj = json_tokener_parse("{ \"foo\": \"bar\", \"baz\": null, \"bool0\": true }");
|
||||
printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
|
||||
json_object_put(new_obj);
|
||||
|
||||
new_obj = json_tokener_parse("{ \"foo\": [null, \"foo\"] }");
|
||||
printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
|
||||
json_object_put(new_obj);
|
||||
|
||||
new_obj = json_tokener_parse("{ \"abc\": 12, \"foo\": \"bar\", \"bool0\": false, \"bool1\": true, \"arr\": [ 1, 2, 3, null, 5 ] }");
|
||||
printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
|
||||
json_object_put(new_obj);
|
||||
}
|
||||
|
||||
static void test_verbose_parse()
|
||||
{
|
||||
json_object *new_obj;
|
||||
enum json_tokener_error error = json_tokener_success;
|
||||
|
||||
new_obj = json_tokener_parse_verbose("{ foo }", &error);
|
||||
assert (error == json_tokener_error_parse_object_key_name);
|
||||
assert (new_obj == NULL);
|
||||
|
||||
new_obj = json_tokener_parse("{ foo }");
|
||||
assert (new_obj == NULL);
|
||||
|
||||
new_obj = json_tokener_parse("foo");
|
||||
assert (new_obj == NULL);
|
||||
new_obj = json_tokener_parse_verbose("foo", &error);
|
||||
assert (new_obj == NULL);
|
||||
|
||||
/* b/c the string starts with 'f' parsing return a boolean error */
|
||||
assert (error == json_tokener_error_parse_boolean);
|
||||
|
||||
printf("json_tokener_parse_versbose() OK\n");
|
||||
}
|
||||
|
||||
struct incremental_step {
|
||||
const char *string_to_parse;
|
||||
int length;
|
||||
int char_offset;
|
||||
enum json_tokener_error expected_error;
|
||||
int reset_tokener;
|
||||
} incremental_steps[] = {
|
||||
|
||||
/* Check that full json messages can be parsed, both w/ and w/o a reset */
|
||||
{ "{ \"foo\": 123 }", -1, -1, json_tokener_success, 0 },
|
||||
{ "{ \"foo\": 456 }", -1, -1, json_tokener_success, 1 },
|
||||
{ "{ \"foo\": 789 }", -1, -1, json_tokener_success, 1 },
|
||||
|
||||
/* Check a basic incremental parse */
|
||||
{ "{ \"foo", -1, -1, json_tokener_continue, 0 },
|
||||
{ "\": {\"bar", -1, -1, json_tokener_continue, 0 },
|
||||
{ "\":13}}", -1, -1, json_tokener_success, 1 },
|
||||
|
||||
/* Check that json_tokener_reset actually resets */
|
||||
{ "{ \"foo", -1, -1, json_tokener_continue, 1 },
|
||||
{ ": \"bar\"}", -1, 0, json_tokener_error_parse_unexpected, 1 },
|
||||
|
||||
/* Check incremental parsing with trailing characters */
|
||||
{ "{ \"foo", -1, -1, json_tokener_continue, 0 },
|
||||
{ "\": {\"bar", -1, -1, json_tokener_continue, 0 },
|
||||
{ "\":13}}XXXX", 10, 6, json_tokener_success, 0 },
|
||||
{ "XXXX", 4, 0, json_tokener_error_parse_unexpected, 1 },
|
||||
|
||||
/* Check that trailing characters can change w/o a reset */
|
||||
{ "{\"x\": 123 }\"X\"", -1, 11, json_tokener_success, 0 },
|
||||
{ "\"Y\"", -1, -1, json_tokener_success, 1 },
|
||||
|
||||
/* To stop parsing a number we need to reach a non-digit, e.g. a \0 */
|
||||
{ "1", 1, 1, json_tokener_continue, 0 },
|
||||
{ "2", 2, 1, json_tokener_success, 0 },
|
||||
|
||||
/* Strings have a well defined end point, so we can stop at the quote */
|
||||
{ "\"blue\"", -1, -1, json_tokener_success, 0 },
|
||||
|
||||
{ "[1,2,3]", -1, -1, json_tokener_success, 0 },
|
||||
|
||||
/* This behaviour doesn't entirely follow the json spec, but until we have
|
||||
a way to specify how strict to be we follow Postel's Law and be liberal
|
||||
in what we accept (up to a point). */
|
||||
{ "[1,2,3,]", -1, -1, json_tokener_success, 0 },
|
||||
{ "[1,2,,3,]", -1, 5, json_tokener_error_parse_unexpected, 0 },
|
||||
|
||||
{ NULL, json_tokener_success },
|
||||
};
|
||||
|
||||
static void test_incremental_parse()
|
||||
{
|
||||
json_object *new_obj;
|
||||
enum json_tokener_error jerr;
|
||||
json_tokener *tok;
|
||||
const char *string_to_parse;
|
||||
int ii;
|
||||
int num_ok, num_error;
|
||||
|
||||
num_ok = 0;
|
||||
num_error = 0;
|
||||
|
||||
printf("Starting incremental tests.\n");
|
||||
|
||||
string_to_parse = "{ \"foo"; /* } */
|
||||
printf("json_tokener_parse(%s) ... ", string_to_parse);
|
||||
new_obj = json_tokener_parse(string_to_parse);
|
||||
if (new_obj == NULL) printf("got error as expected\n");
|
||||
|
||||
/* test incremental parsing in various forms */
|
||||
tok = json_tokener_new();
|
||||
for (ii = 0; incremental_steps[ii].string_to_parse != NULL; ii++)
|
||||
{
|
||||
int this_step_ok = 0;
|
||||
struct incremental_step *step = &incremental_steps[ii];
|
||||
int length = step->length;
|
||||
int expected_char_offset = step->char_offset;
|
||||
if (length == -1)
|
||||
length = strlen(step->string_to_parse);
|
||||
if (expected_char_offset == -1)
|
||||
expected_char_offset = length;
|
||||
|
||||
printf("json_tokener_parse_ex(tok, %-12s, %3d) ... ",
|
||||
step->string_to_parse, length);
|
||||
new_obj = json_tokener_parse_ex(tok, step->string_to_parse, length);
|
||||
|
||||
jerr = json_tokener_get_error(tok);
|
||||
if (step->expected_error != json_tokener_success)
|
||||
{
|
||||
if (new_obj != NULL)
|
||||
printf("ERROR: invalid object returned: %s\n",
|
||||
json_object_to_json_string(new_obj));
|
||||
else if (jerr != step->expected_error)
|
||||
printf("ERROR: got wrong error: %s\n",
|
||||
json_tokener_error_desc(jerr));
|
||||
else if (tok->char_offset != expected_char_offset)
|
||||
printf("ERROR: wrong char_offset %d != expected %d\n",
|
||||
tok->char_offset,
|
||||
expected_char_offset);
|
||||
else
|
||||
{
|
||||
printf("OK: got correct error: %s\n", json_tokener_error_desc(jerr));
|
||||
this_step_ok = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (new_obj == NULL)
|
||||
printf("ERROR: expected valid object, instead: %s\n",
|
||||
json_tokener_error_desc(jerr));
|
||||
else if (tok->char_offset != expected_char_offset)
|
||||
printf("ERROR: wrong char_offset %d != expected %d\n",
|
||||
tok->char_offset,
|
||||
expected_char_offset);
|
||||
else
|
||||
{
|
||||
printf("OK: got object of type [%s]: %s\n",
|
||||
json_type_to_name(json_object_get_type(new_obj)),
|
||||
json_object_to_json_string(new_obj));
|
||||
this_step_ok = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (new_obj)
|
||||
json_object_put(new_obj);
|
||||
|
||||
if (step->reset_tokener)
|
||||
json_tokener_reset(tok);
|
||||
|
||||
if (this_step_ok)
|
||||
num_ok++;
|
||||
else
|
||||
num_error++;
|
||||
}
|
||||
|
||||
json_tokener_free(tok);
|
||||
|
||||
printf("End Incremental Tests OK=%d ERROR=%d\n", num_ok, num_error);
|
||||
|
||||
return;
|
||||
}
|
||||
46
tests/test_parse.expected
Normal file
46
tests/test_parse.expected
Normal file
@@ -0,0 +1,46 @@
|
||||
new_obj.to_string()="\u0003"
|
||||
new_obj.to_string()="foo"
|
||||
new_obj.to_string()="foo"
|
||||
new_obj.to_string()="ABC"
|
||||
new_obj.to_string()=null
|
||||
new_obj.to_string()=true
|
||||
new_obj.to_string()=12
|
||||
new_obj.to_string()=12.300000
|
||||
new_obj.to_string()=[ "\n" ]
|
||||
new_obj.to_string()=[ "\nabc\n" ]
|
||||
new_obj.to_string()=[ null ]
|
||||
new_obj.to_string()=[ ]
|
||||
new_obj.to_string()=[ false ]
|
||||
new_obj.to_string()=[ "abc", null, "def", 12 ]
|
||||
new_obj.to_string()={ }
|
||||
new_obj.to_string()={ "foo": "bar" }
|
||||
new_obj.to_string()={ "foo": "bar", "baz": null, "bool0": true }
|
||||
new_obj.to_string()={ "foo": [ null, "foo" ] }
|
||||
new_obj.to_string()={ "abc": 12, "foo": "bar", "bool0": false, "bool1": true, "arr": [ 1, 2, 3, null, 5 ] }
|
||||
==================================
|
||||
json_tokener_parse_versbose() OK
|
||||
==================================
|
||||
Starting incremental tests.
|
||||
json_tokener_parse({ "foo) ... got error as expected
|
||||
json_tokener_parse_ex(tok, { "foo": 123 }, 14) ... OK: got object of type [object]: { "foo": 123 }
|
||||
json_tokener_parse_ex(tok, { "foo": 456 }, 14) ... OK: got object of type [object]: { "foo": 456 }
|
||||
json_tokener_parse_ex(tok, { "foo": 789 }, 14) ... OK: got object of type [object]: { "foo": 789 }
|
||||
json_tokener_parse_ex(tok, { "foo , 6) ... OK: got correct error: continue
|
||||
json_tokener_parse_ex(tok, ": {"bar , 8) ... OK: got correct error: continue
|
||||
json_tokener_parse_ex(tok, ":13}} , 6) ... OK: got object of type [object]: { "foo": { "bar": 13 } }
|
||||
json_tokener_parse_ex(tok, { "foo , 6) ... OK: got correct error: continue
|
||||
json_tokener_parse_ex(tok, : "bar"} , 8) ... OK: got correct error: unexpected character
|
||||
json_tokener_parse_ex(tok, { "foo , 6) ... OK: got correct error: continue
|
||||
json_tokener_parse_ex(tok, ": {"bar , 8) ... OK: got correct error: continue
|
||||
json_tokener_parse_ex(tok, ":13}}XXXX , 10) ... OK: got object of type [object]: { "foo": { "bar": 13 } }
|
||||
json_tokener_parse_ex(tok, XXXX , 4) ... OK: got correct error: unexpected character
|
||||
json_tokener_parse_ex(tok, {"x": 123 }"X", 14) ... OK: got object of type [object]: { "x": 123 }
|
||||
json_tokener_parse_ex(tok, "Y" , 3) ... OK: got object of type [string]: "Y"
|
||||
json_tokener_parse_ex(tok, 1 , 1) ... OK: got correct error: continue
|
||||
json_tokener_parse_ex(tok, 2 , 2) ... OK: got object of type [int]: 12
|
||||
json_tokener_parse_ex(tok, "blue" , 6) ... OK: got object of type [string]: "blue"
|
||||
json_tokener_parse_ex(tok, [1,2,3] , 7) ... OK: got object of type [array]: [ 1, 2, 3 ]
|
||||
json_tokener_parse_ex(tok, [1,2,3,] , 8) ... OK: got object of type [array]: [ 1, 2, 3 ]
|
||||
json_tokener_parse_ex(tok, [1,2,,3,] , 9) ... OK: got correct error: unexpected character
|
||||
End Incremental Tests OK=20 ERROR=0
|
||||
==================================
|
||||
12
tests/test_parse.test
Executable file
12
tests/test_parse.test
Executable file
@@ -0,0 +1,12 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Common definitions
|
||||
if test -z "$srcdir"; then
|
||||
srcdir="${0%/*}"
|
||||
test "$srcdir" = "$0" && srcdir=.
|
||||
test -z "$srcdir" && srcdir=.
|
||||
fi
|
||||
. "$srcdir/test-defs.sh"
|
||||
|
||||
run_output_test test_parse
|
||||
exit $?
|
||||
105
tests/test_parse_int64.c
Normal file
105
tests/test_parse_int64.c
Normal file
@@ -0,0 +1,105 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "json_inttypes.h"
|
||||
#include "json_util.h"
|
||||
|
||||
void checkit(const char *buf)
|
||||
{
|
||||
int64_t cint64 = -666;
|
||||
|
||||
int retval = json_parse_int64(buf, &cint64);
|
||||
printf("buf=%s parseit=%d, value=%" PRId64 " \n", buf, retval, cint64);
|
||||
}
|
||||
|
||||
/**
|
||||
* This test calls json_parse_int64 with a variety of different strings.
|
||||
* It's purpose is to ensure that the results are consistent across all
|
||||
* different environments that it might be executed in.
|
||||
*
|
||||
* This always exits with a 0 exit value. The output should be compared
|
||||
* against previously saved expected output.
|
||||
*/
|
||||
int main()
|
||||
{
|
||||
char buf[100];
|
||||
|
||||
checkit("x");
|
||||
|
||||
checkit("0");
|
||||
checkit("-0");
|
||||
|
||||
checkit("00000000");
|
||||
checkit("-00000000");
|
||||
|
||||
checkit("1");
|
||||
|
||||
strcpy(buf, "2147483647"); // aka INT32_MAX
|
||||
checkit(buf);
|
||||
|
||||
strcpy(buf, "-1");
|
||||
checkit(buf);
|
||||
|
||||
strcpy(buf, " -1");
|
||||
checkit(buf);
|
||||
|
||||
strcpy(buf, "00001234");
|
||||
checkit(buf);
|
||||
|
||||
strcpy(buf, "0001234x");
|
||||
checkit(buf);
|
||||
|
||||
strcpy(buf, "-00001234");
|
||||
checkit(buf);
|
||||
|
||||
strcpy(buf, "-00001234x");
|
||||
checkit(buf);
|
||||
|
||||
strcpy(buf, "4294967295"); // aka UINT32_MAX
|
||||
|
||||
sprintf(buf, "4294967296"); // aka UINT32_MAX + 1
|
||||
|
||||
strcpy(buf, "21474836470"); // INT32_MAX * 10
|
||||
checkit(buf);
|
||||
|
||||
strcpy(buf, "31474836470"); // INT32_MAX * 10 + a bunch
|
||||
checkit(buf);
|
||||
|
||||
strcpy(buf, "-2147483647"); // INT32_MIN + 1
|
||||
checkit(buf);
|
||||
|
||||
strcpy(buf, "-2147483648"); // INT32_MIN
|
||||
checkit(buf);
|
||||
|
||||
strcpy(buf, "-2147483649"); // INT32_MIN - 1
|
||||
checkit(buf);
|
||||
|
||||
strcpy(buf, "-21474836480"); // INT32_MIN * 10
|
||||
checkit(buf);
|
||||
|
||||
strcpy(buf, "9223372036854775807"); // INT64_MAX
|
||||
checkit(buf);
|
||||
|
||||
strcpy(buf, "9223372036854775808"); // INT64_MAX + 1
|
||||
checkit(buf);
|
||||
|
||||
strcpy(buf, "-9223372036854775808"); // INT64_MIN
|
||||
checkit(buf);
|
||||
|
||||
strcpy(buf, "-9223372036854775809"); // INT64_MIN - 1
|
||||
checkit(buf);
|
||||
|
||||
strcpy(buf, "18446744073709551615"); // UINT64_MAX
|
||||
checkit(buf);
|
||||
|
||||
strcpy(buf, "18446744073709551616"); // UINT64_MAX + 1
|
||||
checkit(buf);
|
||||
|
||||
strcpy(buf, "-18446744073709551616"); // -UINT64_MAX
|
||||
checkit(buf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
26
tests/test_parse_int64.expected
Normal file
26
tests/test_parse_int64.expected
Normal file
@@ -0,0 +1,26 @@
|
||||
buf=x parseit=1, value=-666
|
||||
buf=0 parseit=0, value=0
|
||||
buf=-0 parseit=0, value=0
|
||||
buf=00000000 parseit=0, value=0
|
||||
buf=-00000000 parseit=0, value=0
|
||||
buf=1 parseit=0, value=1
|
||||
buf=2147483647 parseit=0, value=2147483647
|
||||
buf=-1 parseit=0, value=-1
|
||||
buf= -1 parseit=0, value=-1
|
||||
buf=00001234 parseit=0, value=1234
|
||||
buf=0001234x parseit=0, value=1234
|
||||
buf=-00001234 parseit=0, value=-1234
|
||||
buf=-00001234x parseit=0, value=-1234
|
||||
buf=21474836470 parseit=0, value=21474836470
|
||||
buf=31474836470 parseit=0, value=31474836470
|
||||
buf=-2147483647 parseit=0, value=-2147483647
|
||||
buf=-2147483648 parseit=0, value=-2147483648
|
||||
buf=-2147483649 parseit=0, value=-2147483649
|
||||
buf=-21474836480 parseit=0, value=-21474836480
|
||||
buf=9223372036854775807 parseit=0, value=9223372036854775807
|
||||
buf=9223372036854775808 parseit=0, value=9223372036854775807
|
||||
buf=-9223372036854775808 parseit=0, value=-9223372036854775808
|
||||
buf=-9223372036854775809 parseit=0, value=-9223372036854775808
|
||||
buf=18446744073709551615 parseit=0, value=9223372036854775807
|
||||
buf=18446744073709551616 parseit=0, value=9223372036854775807
|
||||
buf=-18446744073709551616 parseit=0, value=-9223372036854775808
|
||||
Reference in New Issue
Block a user