aboutsummaryrefslogtreecommitdiff
path: root/flatcc/test/reflection_test
diff options
context:
space:
mode:
authorToni Uhlig <matzeton@googlemail.com>2023-07-16 02:03:33 +0200
committerToni Uhlig <matzeton@googlemail.com>2023-07-16 02:03:33 +0200
commitb31e4bc16d1df62b50c6f77a77041f9e7b6c906d (patch)
tree024c74c13d918aa6bde302aab6836fa33607613c /flatcc/test/reflection_test
parentba6815ef8fb8ae472412b5af2837a7caba2799c2 (diff)
parent5a40295c4cf0af5ea8da9ced04a4ce7d3621a080 (diff)
Merge commit '5a40295c4cf0af5ea8da9ced04a4ce7d3621a080' as 'flatcc'
Diffstat (limited to 'flatcc/test/reflection_test')
-rw-r--r--flatcc/test/reflection_test/CMakeLists.txt20
-rw-r--r--flatcc/test/reflection_test/reflection_test.c196
-rwxr-xr-xflatcc/test/reflection_test/reflection_test.sh24
3 files changed, 240 insertions, 0 deletions
diff --git a/flatcc/test/reflection_test/CMakeLists.txt b/flatcc/test/reflection_test/CMakeLists.txt
new file mode 100644
index 0000000..f82d1f5
--- /dev/null
+++ b/flatcc/test/reflection_test/CMakeLists.txt
@@ -0,0 +1,20 @@
+include(CTest)
+
+set(INC_DIR "${PROJECT_SOURCE_DIR}/include")
+set(GEN_DIR "${CMAKE_CURRENT_BINARY_DIR}/generated")
+set(FBS_DIR "${PROJECT_SOURCE_DIR}/test/monster_test")
+
+include_directories("${GEN_DIR}" "${INC_DIR}")
+
+add_custom_target(gen_reflection_test ALL)
+add_custom_command (
+ TARGET gen_reflection_test
+ COMMAND ${CMAKE_COMMAND} -E make_directory "${GEN_DIR}"
+ COMMAND flatcc_cli --schema -o "${GEN_DIR}" "${FBS_DIR}/monster_test.fbs"
+ DEPENDS flatcc_cli "${FBS_DIR}/monster_test.fbs" "${FBS_DIR}/include_test1.fbs" "${FBS_DIR}/include_test2.fbs"
+)
+add_executable(reflection_test reflection_test.c)
+add_dependencies(reflection_test gen_reflection_test)
+target_link_libraries(reflection_test flatccrt)
+
+add_test(reflection_test reflection_test${CMAKE_EXECUTABLE_SUFFIX})
diff --git a/flatcc/test/reflection_test/reflection_test.c b/flatcc/test/reflection_test/reflection_test.c
new file mode 100644
index 0000000..eef0bd1
--- /dev/null
+++ b/flatcc/test/reflection_test/reflection_test.c
@@ -0,0 +1,196 @@
+#include "flatcc/support/readfile.h"
+#include "flatcc/reflection/reflection_reader.h"
+#include "flatcc/portable/pcrt.h"
+
+/* -DFLATCC_PORTABLE may help if inttypes.h is missing. */
+#ifndef PRId64
+#include <inttypes.h>
+#endif
+
+
+/* This is not an exhaustive test. */
+int test_schema(const char *monster_bfbs)
+{
+ void *buffer;
+ size_t size;
+ int ret = -1;
+ reflection_Schema_table_t S;
+ reflection_Object_vec_t Objs;
+ reflection_Object_table_t Obj;
+ reflection_Field_vec_t Flds;
+ reflection_Field_table_t F;
+ reflection_Type_table_t T;
+ size_t k, monster_index;
+ reflection_Service_vec_t Svcs;
+ reflection_Service_table_t Svc;
+ reflection_RPCCall_vec_t Calls;
+ reflection_RPCCall_table_t Call;
+ size_t call_index;
+ const char *strval;
+
+ buffer = readfile(monster_bfbs, 100000, &size);
+ if (!buffer) {
+ printf("failed to load binary schema\n");
+ goto done;
+ }
+ S = reflection_Schema_as_root(buffer);
+ Objs = reflection_Schema_objects(S);
+ for (k = 0; k < reflection_Object_vec_len(Objs); ++k) {
+ printf("dbg: obj #%d : %s\n", (int)k,
+ reflection_Object_name(reflection_Object_vec_at(Objs, k)));
+ }
+ k = reflection_Object_vec_find(Objs, "MyGame.Example.Monster");
+ if (k == flatbuffers_not_found) {
+ printf("Could not find monster in schema\n");
+ goto done;
+ }
+ monster_index = k;
+ Obj = reflection_Object_vec_at(Objs, k);
+ if (strcmp(reflection_Object_name(Obj), "MyGame.Example.Monster")) {
+ printf("Found wrong object in schema\n");
+ goto done;
+ }
+ Flds = reflection_Object_fields(Obj);
+ k = reflection_Field_vec_find(Flds, "mana");
+ if (k == flatbuffers_not_found) {
+ printf("Did not find mana field in Monster schema\n");
+ goto done;
+ }
+ F = reflection_Field_vec_at(Flds, k);
+ if (reflection_Field_default_integer(F) != 150) {
+ printf("mana field has wrong default value\n");
+ printf("field name: %s\n", reflection_Field_name(F));
+ printf("%"PRId64"\n", (int64_t)reflection_Field_default_integer(F));
+ goto done;
+ }
+ T = reflection_Field_type(F);
+ if (reflection_Type_base_type(T) != reflection_BaseType_Short) {
+ printf("mana field has wrong type\n");
+ goto done;
+ }
+ if (reflection_Field_optional(F)) {
+ printf("mana field is not optional\n");
+ goto done;
+ }
+ k = reflection_Field_vec_find(Flds, "enemy");
+ if (k == flatbuffers_not_found) {
+ printf("enemy field not found\n");
+ goto done;
+ }
+ T = reflection_Field_type(reflection_Field_vec_at(Flds, k));
+ if (reflection_Type_base_type(T) != reflection_BaseType_Obj) {
+ printf("enemy is not an object\n");
+ goto done;
+ }
+ if (reflection_Type_index(T) != (int32_t)monster_index) {
+ printf("enemy is not a monster\n");
+ goto done;
+ }
+ k = reflection_Field_vec_find(Flds, "testarrayoftables");
+ if (k == flatbuffers_not_found) {
+ printf("array of tables not found\n");
+ goto done;
+ }
+ T = reflection_Field_type(reflection_Field_vec_at(Flds, k));
+ if (reflection_Type_base_type(T) != reflection_BaseType_Vector) {
+ printf("array of tables is not of vector type\n");
+ goto done;
+ }
+ if (reflection_Type_element(T) != reflection_BaseType_Obj) {
+ printf("array of tables is not a vector of table type\n");
+ goto done;
+ }
+ if (reflection_Type_index(T) != (int32_t)monster_index) {
+ printf("array of tables is not a monster vector\n");
+ goto done;
+ }
+ /* list services and calls */
+ Svcs = reflection_Schema_services(S);
+ for (k = 0; k < reflection_Service_vec_len(Svcs); ++k) {
+ Svc = reflection_Service_vec_at(Svcs, k);
+ printf("dbg: svc #%d : %s\n", (int)k,
+ reflection_Service_name(Svc));
+ Calls = reflection_Service_calls(Svc);
+ for (call_index = 0 ;
+ call_index < reflection_RPCCall_vec_len(Calls) ;
+ call_index++) {
+ Call = reflection_RPCCall_vec_at(Calls, call_index);
+ printf("dbg: call %d : %s\n", (int)call_index,
+ reflection_RPCCall_name(Call));
+ }
+ }
+ /* Within service MyGame.Example.MonsterStorage ... */
+ k = reflection_Service_vec_find(Svcs, "MyGame.Example.MonsterStorage");
+ if (k == flatbuffers_not_found) {
+ printf("Could not find MonsterStorage service in schema\n");
+ goto done;
+ }
+ Svc = reflection_Service_vec_at(Svcs, k);
+ /* ... search the RPC call Store */
+ Calls = reflection_Service_calls(Svc);
+ k = reflection_RPCCall_vec_find(Calls, "Store");
+ if (k == flatbuffers_not_found) {
+ printf("Could not find call Store in service\n");
+ goto done;
+ }
+ Call = reflection_RPCCall_vec_at(Calls, k);
+ /* Ensure request type is MyGame.Example.Monster */
+ Obj = reflection_Object_vec_at(Objs, monster_index);
+ if (Obj != reflection_RPCCall_request(Call)) {
+ printf("Wrong request type of rpc call\n");
+ goto done;
+ }
+ /* Ensure response type is MyGame.Example.Stat */
+ k = reflection_Object_vec_find(Objs, "MyGame.Example.Stat");
+ if (k == flatbuffers_not_found) {
+ printf("Could not find Stat in schema\n");
+ goto done;
+ }
+ Obj = reflection_Object_vec_at(Objs, k);
+ if (Obj != reflection_RPCCall_response(Call)) {
+ printf("Wrong response type of rpc call\n");
+ goto done;
+ }
+ /* check the call has an attribute "streaming" */
+ k = reflection_KeyValue_vec_scan(reflection_RPCCall_attributes(Call), "streaming");
+ if (k == flatbuffers_not_found) {
+ printf("Could not find attribute in call\n");
+ goto done;
+ }
+ /* check the attribute value is "none" */
+ strval = reflection_KeyValue_value(
+ reflection_KeyValue_vec_at(reflection_RPCCall_attributes(Call), k));
+ if (!strval || 0 != strcmp("none", strval)) {
+ printf("Wrong attribute value in call\n");
+ goto done;
+ }
+ ret = 0;
+done:
+ if (buffer) {
+ free(buffer);
+ }
+ return ret;
+}
+
+/* We take arguments so test can run without copying sources. */
+#define usage \
+"wrong number of arguments:\n" \
+"usage: <program> [<output-filename>]\n"
+
+const char *filename = "generated/monster_test.bfbs";
+
+int main(int argc, char *argv[])
+{
+ /* Avoid assert dialogs on Windows. */
+ init_headless_crt();
+
+ if (argc != 1 && argc != 2) {
+ fprintf(stderr, usage);
+ exit(1);
+ }
+ if (argc == 2) {
+ filename = argv[1];
+ }
+
+ return test_schema(filename);
+}
diff --git a/flatcc/test/reflection_test/reflection_test.sh b/flatcc/test/reflection_test/reflection_test.sh
new file mode 100755
index 0000000..f1ad69c
--- /dev/null
+++ b/flatcc/test/reflection_test/reflection_test.sh
@@ -0,0 +1,24 @@
+#!/usr/bin/env bash
+
+set -e
+cd `dirname $0`/../..
+ROOT=`pwd`
+TMP=${ROOT}/build/tmp/test/reflection_test
+
+CC=${CC:-cc}
+${ROOT}/scripts/build.sh
+mkdir -p ${TMP}/generated
+rm -rf ${TMP}/generated/*
+bin/flatcc --schema -o ${TMP}/generated test/monster_test/monster_test.fbs
+
+cp test/reflection_test/*.c ${TMP}
+cd ${TMP}
+
+$CC -g -I ${ROOT}/include reflection_test.c \
+ ${ROOT}/lib/libflatccrt.a -o reflection_test_d
+$CC -O3 -DNDEBUG -I ${ROOT}/include reflection_test.c \
+ ${ROOT}/lib/libflatccrt.a -o reflection_test
+echo "running reflection test debug"
+./reflection_test_d
+echo "running reflection test optimized"
+./reflection_test