feat(core): split library layout and add tests
All checks were successful
Build / linux-build-and-test (push) Successful in 46s
All checks were successful
Build / linux-build-and-test (push) Successful in 46s
This commit is contained in:
39
demo/build.bat
Normal file
39
demo/build.bat
Normal file
@@ -0,0 +1,39 @@
|
||||
@echo off
|
||||
setlocal
|
||||
|
||||
set ROOT_DIR=%~dp0..
|
||||
set OUT_DIR=%~dp0build
|
||||
set DEMO_EXE=%OUT_DIR%\ikv_demo.exe
|
||||
set TEST_EXE=%OUT_DIR%\ikv_tests.exe
|
||||
|
||||
if not exist "%OUT_DIR%" mkdir "%OUT_DIR%"
|
||||
|
||||
gcc -std=c11 -Wall -Wextra -pedantic ^
|
||||
-I"%ROOT_DIR%\include" ^
|
||||
"%~dp0main.c" ^
|
||||
"%ROOT_DIR%\src\ikv.c" ^
|
||||
"%ROOT_DIR%\src\loaders\ikv1.c" ^
|
||||
"%ROOT_DIR%\src\loaders\ikv2.c" ^
|
||||
-o "%DEMO_EXE%"
|
||||
|
||||
if errorlevel 1 (
|
||||
echo demo build failed
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
gcc -std=c11 -Wall -Wextra -pedantic ^
|
||||
-I"%ROOT_DIR%\include" ^
|
||||
"%~dp0unit_test.c" ^
|
||||
"%ROOT_DIR%\src\ikv.c" ^
|
||||
"%ROOT_DIR%\src\loaders\ikv1.c" ^
|
||||
"%ROOT_DIR%\src\loaders\ikv2.c" ^
|
||||
-o "%TEST_EXE%"
|
||||
|
||||
if errorlevel 1 (
|
||||
echo unit test build failed
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
echo built "%DEMO_EXE%"
|
||||
echo built "%TEST_EXE%"
|
||||
endlocal
|
||||
72
demo/main.c
Normal file
72
demo/main.c
Normal file
@@ -0,0 +1,72 @@
|
||||
#include "ikv.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
ikv_node_t *root = ikv_create_object("demo");
|
||||
ikv_node_t *player = NULL;
|
||||
ikv_node_t *inventory = NULL;
|
||||
ikv_node_t *loaded = NULL;
|
||||
uint8_t *binary = NULL;
|
||||
uint32_t binary_size = 0u;
|
||||
|
||||
if (!root)
|
||||
{
|
||||
fputs("failed to create root\n", stderr);
|
||||
return 1;
|
||||
}
|
||||
|
||||
ikv_object_set_string(root, "title", "iKv demo");
|
||||
ikv_object_set_int(root, "version", 2);
|
||||
|
||||
player = ikv_object_add_object(root, "player");
|
||||
inventory = ikv_object_add_array(root, "inventory", IKV_STRING);
|
||||
if (!player || !inventory)
|
||||
{
|
||||
ikv_free(root);
|
||||
fputs("failed to build demo tree\n", stderr);
|
||||
return 1;
|
||||
}
|
||||
|
||||
ikv_object_set_string(player, "name", "jondoe");
|
||||
ikv_object_set_bool(player, "alive", true);
|
||||
ikv_object_set_float(player, "speed", 12.5);
|
||||
|
||||
ikv_array_add_string(inventory, "wrench");
|
||||
ikv_array_add_string(inventory, "battery");
|
||||
ikv_array_add_string(inventory, "map");
|
||||
|
||||
if (!ikv_write_file("demo_output.ikv", root))
|
||||
{
|
||||
ikv_free(root);
|
||||
fputs("failed to write demo_output.ikv\n", stderr);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!ikvb_write_memory(root, &binary, &binary_size))
|
||||
{
|
||||
ikv_free(root);
|
||||
fputs("failed to write binary output\n", stderr);
|
||||
return 1;
|
||||
}
|
||||
|
||||
loaded = ikvb_parse_memory(binary, binary_size);
|
||||
if (!loaded)
|
||||
{
|
||||
free(binary);
|
||||
ikv_free(root);
|
||||
fputs("failed to parse binary output\n", stderr);
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("title: %s\n", ikv_as_string(ikv_object_get(loaded, "title")));
|
||||
printf("version: %lld\n", (long long)ikv_as_int(ikv_object_get(loaded, "version")));
|
||||
printf("inventory items: %u\n", ikv_array_size(ikv_object_get(loaded, "inventory")));
|
||||
|
||||
ikv_free(loaded);
|
||||
free(binary);
|
||||
ikv_free(root);
|
||||
return 0;
|
||||
}
|
||||
128
demo/unit_test.c
Normal file
128
demo/unit_test.c
Normal file
@@ -0,0 +1,128 @@
|
||||
#include "ikv.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
static int fail(const char *message)
|
||||
{
|
||||
fputs(message, stderr);
|
||||
fputc('\n', stderr);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int test_text_roundtrip(void)
|
||||
{
|
||||
const char *src =
|
||||
"ikv1 \"root\"\n"
|
||||
"{\n"
|
||||
" \"name\" \"legacy\"\n"
|
||||
" \"count\" 7\n"
|
||||
"}\n";
|
||||
ikv_node_t *root = ikv_parse_string(src);
|
||||
|
||||
if (!root)
|
||||
return fail("text parse failed");
|
||||
if (ikv_node_type(root) != IKV_OBJECT)
|
||||
return fail("text root type mismatch");
|
||||
if (strcmp(ikv_as_string(ikv_object_get(root, "name")), "legacy") != 0)
|
||||
return fail("text string value mismatch");
|
||||
if (ikv_as_int(ikv_object_get(root, "count")) != 7)
|
||||
return fail("text int value mismatch");
|
||||
|
||||
ikv_free(root);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int test_binary_v1_roundtrip(void)
|
||||
{
|
||||
ikv_node_t *root = ikv_create_object("root");
|
||||
ikv_node_t *loaded = NULL;
|
||||
uint8_t *data = NULL;
|
||||
uint32_t size = 0u;
|
||||
int status = 0;
|
||||
|
||||
if (!root)
|
||||
return fail("v1 root allocation failed");
|
||||
|
||||
ikv_object_set_int(root, "value", 11);
|
||||
if (!ikvb_write_memory_version(root, &data, &size, IKV_VERSION_1))
|
||||
status = fail("v1 binary write failed");
|
||||
else
|
||||
{
|
||||
loaded = ikvb_parse_memory(data, size);
|
||||
if (!loaded)
|
||||
status = fail("v1 binary parse failed");
|
||||
else if (ikv_as_int(ikv_object_get(loaded, "value")) != 11)
|
||||
status = fail("v1 binary value mismatch");
|
||||
}
|
||||
|
||||
ikv_free(loaded);
|
||||
free(data);
|
||||
ikv_free(root);
|
||||
return status;
|
||||
}
|
||||
|
||||
static int test_binary_v2_lazy_root(void)
|
||||
{
|
||||
ikv_node_t *root = ikv_create_object("root");
|
||||
ikv_node_t *nested = NULL;
|
||||
ikv_node_t *loaded = NULL;
|
||||
ikv_node_t *loaded_nested = NULL;
|
||||
uint8_t *data = NULL;
|
||||
uint32_t size = 0u;
|
||||
int status = 0;
|
||||
|
||||
if (!root)
|
||||
return fail("v2 root allocation failed");
|
||||
|
||||
ikv_object_set_string(root, "title", "fast");
|
||||
nested = ikv_object_add_object(root, "nested");
|
||||
if (!nested)
|
||||
{
|
||||
ikv_free(root);
|
||||
return fail("v2 nested allocation failed");
|
||||
}
|
||||
|
||||
ikv_object_set_bool(nested, "flag", true);
|
||||
ikv_object_set_float(nested, "speed", 9.25);
|
||||
|
||||
if (!ikvb_write_memory_version(root, &data, &size, IKV_VERSION_2))
|
||||
status = fail("v2 binary write failed");
|
||||
else
|
||||
{
|
||||
loaded = ikvb_parse_memory(data, size);
|
||||
if (!loaded)
|
||||
status = fail("v2 binary parse failed");
|
||||
else if (ikv_object_size(loaded) != 2u)
|
||||
status = fail("v2 root key count mismatch");
|
||||
else if (strcmp(ikv_as_string(ikv_object_get(loaded, "title")), "fast") != 0)
|
||||
status = fail("v2 root lazy lookup failed");
|
||||
else
|
||||
{
|
||||
loaded_nested = ikv_object_get(loaded, "nested");
|
||||
if (!loaded_nested)
|
||||
status = fail("v2 nested lazy lookup failed");
|
||||
else if (!ikv_as_bool(ikv_object_get(loaded_nested, "flag")))
|
||||
status = fail("v2 nested bool mismatch");
|
||||
}
|
||||
}
|
||||
|
||||
ikv_free(loaded);
|
||||
free(data);
|
||||
ikv_free(root);
|
||||
return status;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
if (test_text_roundtrip() != 0)
|
||||
return 1;
|
||||
if (test_binary_v1_roundtrip() != 0)
|
||||
return 1;
|
||||
if (test_binary_v2_lazy_root() != 0)
|
||||
return 1;
|
||||
|
||||
puts("all tests passed");
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user