diff --git a/Makefile.am b/Makefile.am index af437a6..b4b5bc3 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1 +1 @@ -SUBDIRS = src +SUBDIRS = src test diff --git a/configure.ac b/configure.ac index 178c387..5d9200c 100644 --- a/configure.ac +++ b/configure.ac @@ -21,5 +21,6 @@ AC_PROG_LIBTOOL AC_CONFIG_FILES([ Makefile src/Makefile + test/Makefile ]) AC_OUTPUT diff --git a/test/.gitignore b/test/.gitignore new file mode 100644 index 0000000..5147f3a --- /dev/null +++ b/test/.gitignore @@ -0,0 +1,4 @@ +load_dump +loadf_dumpf +loadfd_dumpfd +loads_dumps diff --git a/test/Makefile.am b/test/Makefile.am new file mode 100644 index 0000000..132c133 --- /dev/null +++ b/test/Makefile.am @@ -0,0 +1,7 @@ +check_PROGRAMS = load_dump loadf_dumpf loadfd_dumpfd loads_dumps + +AM_CPPFLAGS = -I$(top_srcdir)/src +AM_CFLAGS = -Wall -Werror +LDADD = ../src/libjansson.la + +TESTS = test-invalid test-valid diff --git a/test/json-compare.py b/test/json-compare.py new file mode 100755 index 0000000..cb5cee6 --- /dev/null +++ b/test/json-compare.py @@ -0,0 +1,37 @@ +#!/usr/bin/python + +import simplejson +import sys + +def load(filename): + try: + jsonfile = open(filename) + except IOError, err: + print >>sys.stderr, "unable to load %s: %s" % \ + (filename, err.strerror) + sys.exit(1) + + try: + json = simplejson.load(jsonfile) + except ValueError, err: + print "%s is malformed: %s" % (filename, err) + sys.exit(1) + finally: + jsonfile.close() + + return json + +def main(): + if len(sys.argv) != 3: + print >>sys.stderr, "usage: %s json1 json2" % sys.argv[0] + return 2 + + json1 = load(sys.argv[1]) + json2 = load(sys.argv[2]) + if json1 == json2: + return 0 + else: + return 1 + +if __name__ == '__main__': + sys.exit(main() or 0) diff --git a/test/load_dump.c b/test/load_dump.c new file mode 100644 index 0000000..96995e5 --- /dev/null +++ b/test/load_dump.c @@ -0,0 +1,24 @@ +#include +#include + +int main(int argc, char *argv[]) +{ + json_t *json; + json_error_t error; + + if(argc != 3) { + fprintf(stderr, "usage: %s infile outfile\n", argv[0]); + return 2; + } + + json = json_load(argv[1], &error); + if(!json) { + fprintf(stderr, "%d\n%s\n", error.line, error.text); + return 1; + } + + json_dump(json, argv[2], 0); + json_decref(json); + + return 0; +} diff --git a/test/loadf_dumpf.c b/test/loadf_dumpf.c new file mode 100644 index 0000000..5d42156 --- /dev/null +++ b/test/loadf_dumpf.c @@ -0,0 +1,24 @@ +#include +#include + +int main(int argc, char *argv[]) +{ + json_t *json; + json_error_t error; + + if(argc != 1) { + fprintf(stderr, "usage: %s\n", argv[0]); + return 2; + } + + json = json_loadf(stdin, &error); + if(!json) { + fprintf(stderr, "%d\n%s\n", error.line, error.text); + return 1; + } + + json_dumpf(json, stdout, 0); + json_decref(json); + + return 0; +} diff --git a/test/loadfd_dumpfd.c b/test/loadfd_dumpfd.c new file mode 100644 index 0000000..0faf0c6 --- /dev/null +++ b/test/loadfd_dumpfd.c @@ -0,0 +1,25 @@ +#include +#include +#include + +int main(int argc, char *argv[]) +{ + json_t *json; + json_error_t error; + + if(argc != 1) { + fprintf(stderr, "usage: %s\n", argv[0]); + return 2; + } + + json = json_loadfd(STDIN_FILENO, &error); + if(!json) { + fprintf(stderr, "%d\n%s\n", error.line, error.text); + return 1; + } + + json_dumpfd(json, STDOUT_FILENO, 0); + json_decref(json); + + return 0; +} diff --git a/test/loads_dumps.c b/test/loads_dumps.c new file mode 100644 index 0000000..ab8db1a --- /dev/null +++ b/test/loads_dumps.c @@ -0,0 +1,40 @@ +#include +#include +#include + +#define BUFFER_SIZE (256 * 1024) + +int main(int argc, char *argv[]) +{ + json_t *json; + json_error_t error; + int count; + char buffer[BUFFER_SIZE]; + char *result; + + if(argc != 1) { + fprintf(stderr, "usage: %s\n", argv[0]); + return 2; + } + + count = fread(buffer, 1, BUFFER_SIZE, stdin); + if(count < 0 || count >= BUFFER_SIZE) { + fprintf(stderr, "unable to read input\n"); + return 1; + } + buffer[count] = '\0'; + + json = json_loads(buffer, &error); + if(!json) { + fprintf(stderr, "%d\n%s\n", error.line, error.text); + return 1; + } + + result = json_dumps(json, 0); + json_decref(json); + + puts(result); + free(result); + + return 0; +} diff --git a/test/run-test b/test/run-test new file mode 100644 index 0000000..79d955a --- /dev/null +++ b/test/run-test @@ -0,0 +1,31 @@ +cleanup() { + rm -rf $TMPDIR +} +trap cleanup 0 + +run_testprog() { + local prog=$1 + local input=$2 + case "$prog" in + load_dump) + ./$prog $input $TMPDIR/output 2>$TMPDIR/error + ;; + *) + ./$prog <$input >$TMPDIR/output 2>$TMPDIR/error + ;; + esac +} + +if [ ! -f $TESTFILE ]; then + echo "$TESTFILE cannot be found" >&2 + exit 1 +fi + +mkdir -p $TMPDIR +${srcdir}/split-testfile.py $TESTFILE $TMPDIR | \ +while read input output; do + run_test load_dump $input $output + run_test loadf_dumpf $input $output + run_test loadfd_dumpfd $input $output + run_test loads_dumps $input $output +done diff --git a/test/split-testfile.py b/test/split-testfile.py new file mode 100755 index 0000000..ef9cc40 --- /dev/null +++ b/test/split-testfile.py @@ -0,0 +1,46 @@ +#!/usr/bin/python + +import os +import sys + +def open_files(outdir, i): + return (open(os.path.join(outdir, 'test%02d.in' % i), 'w'), + open(os.path.join(outdir, 'test%02d.out' % i), 'w')) + +def close_files(input, output): + print os.path.basename(input.name), os.path.basename(output.name) + input.close() + output.close() + +def main(): + if len(sys.argv) != 3: + print 'usage: %s input-file output-directory' % sys.argv[0] + return 2 + + infile = sys.argv[1] + outdir = sys.argv[2] + + if not os.path.exists(outdir): + print >>sys.stderr, 'output directory %r does not exist!' % outdir + return 1 + + i = 0 + input, output = open_files(outdir, i) + current = input + + for line in open(infile): + if line == '====\n': + current = output + elif line == '========\n': + close_files(input, output) + i += 1 + input, output = open_files(outdir, i) + current = input + else: + current.write(line) + + close_files(input, output) + print >>sys.stderr, "%d test cases" % (i + 1) + +if __name__ == '__main__': + sys.exit(main() or 0) diff --git a/test/test-invalid b/test/test-invalid new file mode 100755 index 0000000..b949caf --- /dev/null +++ b/test/test-invalid @@ -0,0 +1,22 @@ +#!/bin/sh + +TESTFILE="${srcdir}/testdata/invalid" +TMPDIR="tmp" + +run_test() { + local prog=$1 + local input=$2 + local output=$3 + run_testprog $prog $TMPDIR/$input + if ! cmp $TMPDIR/$output $TMPDIR/error >/dev/null; then + echo "### $input ($prog) failed:" >&2 + cat $TMPDIR/$input >&2 + echo "### expected output:" >&2 + cat $TMPDIR/$output >&2 + echo "### actual output:" >&2 + cat $TMPDIR/error >&2 + exit 1 + fi +} + +. ${srcdir}/run-test diff --git a/test/test-valid b/test/test-valid new file mode 100755 index 0000000..15fd92d --- /dev/null +++ b/test/test-valid @@ -0,0 +1,30 @@ +#!/bin/sh + +TESTFILE="${srcdir}/testdata/valid" +TMPDIR="tmp" + +run_test() { + local prog=$1 + local input=$2 + local output=$3 + run_testprog $prog $TMPDIR/$input + if ! ${srcdir}/json-compare.py $TMPDIR/$input $TMPDIR/output \ + >$TMPDIR/cmp-output + then + echo "### $input ($prog) failed:" >&2 + cat $TMPDIR/$input >&2 + if [ -f $TMPDIR/output ]; then + echo "### output:" >&2 + cat $TMPDIR/output >&2 + fi + if [ -s $TMPDIR/cmp-output ]; then + echo "### compare output:" >&2 + cat $TMPDIR/cmp-output >&2 + fi + exit 1 + fi + rm -f $TMPDIR/output + rm -f $TMPDIR/cmp-output +} + +. ${srcdir}/run-test diff --git a/test/testdata/invalid b/test/testdata/invalid new file mode 100644 index 0000000..2ee6b7b --- /dev/null +++ b/test/testdata/invalid @@ -0,0 +1,138 @@ +==== +1 +'[' or '{' expected near end of file +======== +null +==== +1 +'[' or '{' expected near 'null' +======== +{ +==== +2 +'}' expected near end of file +======== +[ +==== +2 +']' expected near end of file +======== +[, +==== +1 +unexpected token near ',' +======== +[1, +==== +2 +']' expected near end of file +======== +["a +==== +1 +invalid token near '"a' +======== +["a" +==== +2 +']' expected near end of file +======== +[' +==== +1 +invalid token near ''' +======== +{, +==== +1 +string expected near ',' +======== +{" +==== +1 +string expected near '"' +======== +{"a +==== +1 +string expected near '"a' +======== +{"a" +==== +2 +':' expected near end of file +======== +{'a' +==== +1 +string expected near ''' +======== +{"a": +==== +2 +unexpected token near end of file +======== +{"a":"a +==== +1 +invalid token near '"a' +======== +{[ +==== +1 +string expected near '[' +======== +[{ +==== +2 +'}' expected near end of file +======== +[{} +==== +2 +']' expected near end of file +======== +[1,] +==== +1 +unexpected token near ']' +======== +[1, +2, +3, +4, +5, +] +==== +6 +unexpected token near ']' +======== +[1.] +==== +1 +invalid token near '1.' +======== +[1e] +==== +1 +invalid token near '1e' +======== +[1ea] +==== +1 +invalid token near '1e' +======== +[012] +==== +1 +invalid token near '0' +======== +[-012] +==== +1 +invalid token near '-0' +======== +[" <-- tab character"] +==== +1 +invalid token near '"' diff --git a/test/testdata/valid b/test/testdata/valid new file mode 100644 index 0000000..863933d --- /dev/null +++ b/test/testdata/valid @@ -0,0 +1,57 @@ +[""] +======== +["a"] +======== +["abcdefghijklmnopqrstuvwxyz1234567890 "] +======== +["€þıœəßð some utf-8 ĸʒ×ŋµåäö"] +======== +["\"\\\/\b\f\n\r\t"] +======== +[0] +======== +[1] +======== +[123] +======== +[-0] +======== +[-1] +======== +[-123] +======== +[123.456789] +======== +[123e45] +======== +[1E22] +======== +[1e+2] +======== +[1e-2] +======== +[1E+2] +======== +[1E-2] +======== +[123.456e78] +======== +[true] +======== +[false] +======== +[null] +======== +[] +======== +[{}] +======== +[1,2,3,4, +"a", "b", "c", +{"foo": "bar", "core": "dump"}, +true, false, true, true, null, false +] +======== +{} +======== +{"a":[]}