From 348fd58242441fa42ae48f4d26e08679baddb9b2 Mon Sep 17 00:00:00 2001 From: rafagafe Date: Mon, 3 Apr 2017 02:43:31 +0200 Subject: [PATCH] Added unit test. --- makefile | 11 ++- tests.c | 228 ++++++++++++++++++++++++++++++++++++++++++++++++++++ tiny-json.h | 5 +- 3 files changed, 241 insertions(+), 3 deletions(-) create mode 100644 tests.c diff --git a/makefile b/makefile index d184496..4616b92 100644 --- a/makefile +++ b/makefile @@ -1,6 +1,6 @@ -build: example-01.exe example-02.exe +build: example-01.exe example-02.exe test.exe clean: rm -rf *.o @@ -8,12 +8,18 @@ clean: all: clean build +test: test.exe + ./test.exe + example-01.exe: example-01.o tiny-json.o gcc -o example-01.exe example-01.o tiny-json.o example-02.exe: example-02.o tiny-json.o gcc -o example-02.exe example-02.o tiny-json.o +test.exe: tests.o tiny-json.o + gcc -o test.exe tests.o tiny-json.o + tiny-json.o: tiny-json.c tiny-json.h gcc -c tiny-json.c @@ -22,3 +28,6 @@ example-01.o: example-01.c tiny-json.h example-02.o: example-02.c tiny-json.h gcc -c example-02.c + +tests.o: tests.c tiny-json.h + gcc -c tests.c diff --git a/tests.c b/tests.c new file mode 100644 index 0000000..1fae31b --- /dev/null +++ b/tests.c @@ -0,0 +1,228 @@ + + +#include +#include +#include +#include +#include "tiny-json.h" + +#define done() return 0 +#define fail() return __LINE__ +static unsigned int checkqty = 0; +#define check( x ) do { ++checkqty; if (!(x)) fail(); } while ( 0 ) + +static int empty( void ) { + json_t pool[6]; + unsigned const qty = sizeof pool / sizeof *pool; + { + char str[] = "{}"; + json_t const* json = json_create( str, pool, qty ); + check( json ); + json_t const* child = json_getChild( json ); + check( child == NULL ); + } + { + char str[] = "{\"a\":[]}"; + json_t const* json = json_create( str, pool, qty ); + check( json ); + json_t const* child = json_getChild( json ); + check( child ); + char const* childname = json_getName( child ); + check( childname ); + check( !strcmp( childname, "a" ) ); + check( json_getType( child ) == JSON_ARRAY ); + check( !json_getChild( child ) ); + } + { + char str[] = "{\"a\":[{},{}]}"; + json_t const* json = json_create( str, pool, qty ); + check( json ); + json_t const* child = json_getChild( json ); + check( child ); + char const* childname = json_getName( child ); + check( childname ); + check( !strcmp( childname, "a" ) ); + check( json_getType( child ) == JSON_ARRAY ); + int num = 0; + for( json_t const* i = json_getChild( child ); i; ++num, i = json_getSibling( i ) ) { + check( i ); + check( json_getType( i ) == JSON_OBJ ); + check( !json_getChild( i ) ); + } + check( num == 2 ); + } + done(); +} + +static int primitive( void ) { + json_t pool[8]; + unsigned const qty = sizeof pool / sizeof *pool; + { + char str[] = "{" + "\"boolvar0\": false," + "\"boolvar1\": true," + "\"nullvar\": null," + "\"max\": 9223372036854775807," + "\"min\": -9223372036854775808," + "\"real\": -0.004," + "\"scientific\": 5368.32e-3," + "}"; + + json_t const* json = json_create( str, pool, qty ); + check( json ); + + json_t const* boolvar0 = json_getProperty( json, "boolvar0" ); + check( boolvar0 ); + check( JSON_BOOLEAN == json_getType( boolvar0 ) ); + check( !strcmp( "false", json_getValue( boolvar0 ) ) ); + check( false == json_getBoolean( boolvar0 ) ); + + json_t const* boolvar1 = json_getProperty( json, "boolvar1" ); + check( boolvar1 ); + check( JSON_BOOLEAN == json_getType( boolvar1 ) ); + check( !strcmp( "true", json_getValue( boolvar1 ) ) ); + check( true == json_getBoolean( boolvar1 ) ); + + json_t const* nullvar = json_getProperty( json, "nullvar" ); + check( nullvar ); + check( JSON_NULL == json_getType( nullvar ) ); + check( !strcmp( "null", json_getValue( nullvar ) ) ); + + json_t const* max = json_getProperty( json, "max" ); + check( max ); + check( JSON_INTEGER == json_getType( max ) ); + check( !strcmp( "9223372036854775807", json_getValue( max ) ) ); + check( INT64_MAX == json_getInteger( max ) ); + + json_t const* min = json_getProperty( json, "min" ); + check( max ); + check( JSON_INTEGER == json_getType( max ) ); + check( !strcmp( "-9223372036854775808", json_getValue( min ) ) ); + check( INT64_MIN == json_getInteger( min ) ); + + json_t const* real = json_getProperty( json, "real" ); + check( real ); + check( JSON_REAL == json_getType( real ) ); + check( !strcmp( "-0.004", json_getValue( real ) ) ); + check( -0.004 == json_getReal( real ) ); + + json_t const* scientific = json_getProperty( json, "scientific" ); + check( scientific ); + check( JSON_SCIENTIFIC == json_getType( scientific ) ); + check( !strcmp( "5368.32e-3", json_getValue( scientific ) ) ); + check( 5368.32e-3 == json_getReal( scientific ) ); + + } + + done(); +} + +static int text( void ) { + json_t pool[2]; + unsigned const qty = sizeof pool / sizeof *pool; + + char str[] = "{\"a\":\"\\tThis text: \\\"Hello\\\".\\n\"}"; + + json_t const* json = json_create( str, pool, qty ); + check( json ); + + json_t const* a = json_getProperty( json, "a" ); + check( a ); + check( JSON_TEXT == json_getType( a ) ); + check( !strcmp( "\tThis text: \"Hello\".\n", json_getValue( a ) ) ); + + + done(); +} + +static int array( void ) { + json_t pool[7]; + unsigned const qty = sizeof pool / sizeof *pool; + + char str[] = "{\"array\":[ 1, true, null, \"Text\", 0.3232 ]}"; + + json_t const* json = json_create( str, pool, qty ); + check( json ); + + json_t const* array = json_getProperty( json, "array" ); + check( array ); + check( JSON_ARRAY == json_getType( array ) ); + + static struct { jsonType_t type; char const* value; } const pairs[] = { + { JSON_INTEGER, "1" }, { JSON_BOOLEAN, "true" }, { JSON_NULL, "null" }, + { JSON_TEXT, "Text" }, { JSON_REAL, "0.3232" } + }; + unsigned const len = sizeof pairs / sizeof *pairs; + json_t const* element = json_getChild( array ); + for( unsigned int i = 0; i < len; ++i, element = json_getSibling( element ) ) { + check( element ); + check( pairs[i].type == json_getType( element ) ); + check( !strcmp( pairs[i].value, json_getValue( element ) ) ); + } + check( !element ); + + done(); +} + +int badformat( void ) { + json_t pool[2]; + unsigned const qty = sizeof pool / sizeof *pool; + { + char str[] = "{\"var:true}"; + json_t const* json = json_create( str, pool, qty ); + check( !json ); + } + { + char str[] = "{\"var\":tr}"; + json_t const* json = json_create( str, pool, qty ); + check( !json ); + } + { + char str[] = "{\"var\":true"; + json_t const* json = json_create( str, pool, qty ); + check( !json ); + } + { + char str[] = "{\"var\":true} text outside json"; + json_t const* json = json_create( str, pool, qty ); + check( json ); + json_t const* var = json_getProperty( json, "var" ); + check( var ); + check( JSON_BOOLEAN == json_getType( var ) ); + check( !strcmp( "true", json_getValue( var ) ) ); + check( true == json_getBoolean( var ) ); + } + done(); +} + +struct test { + int(*func)(void); + char const* name; +}; + +static int test_exec( struct test const* test ) { + int const err = test->func(); + if ( err ) { + fprintf( stderr, "%s%s%s%d%s", "Failed test: '", test->name, "' Line: ", err, ".\n" ); + return 1; + } + return 0; +} + +static struct test const tests[] = { + { empty, "Empty object and array" }, + { primitive, "Primitive properties" }, + { text, "Text" }, + { array, "Array" }, + { badformat, "Bad format" }, +}; + +int main( void ) { + int failed = 0; + unsigned int const qty = sizeof tests / sizeof *tests; + for( unsigned int i = 0; i < qty; ++i ) + failed += test_exec( tests + i ); + unsigned int const percent = 100.0 * ( qty - failed ) / qty; + printf( "%d%s%d%s", percent, "%. ", checkqty, " checks.\n" ); + return failed; +} \ No newline at end of file diff --git a/tiny-json.h b/tiny-json.h index a74aa6f..db5053e 100644 --- a/tiny-json.h +++ b/tiny-json.h @@ -119,8 +119,9 @@ static inline int64_t json_getInteger( json_t const* property ) { } /** Get the value of a json real property. - * @param property A valid handler of a json object. Its type must be JSON_REAL. - * @return The value stdint. */ + * @param property A valid handler of a json object. + * Its type must be JSON_REAL or JSON_SCIENTIFIC. + * @return The value. */ static inline double json_getReal( json_t const* property ) { return atof( property->u.value ); }