From 5f4577faedb377ebe450898b4940aaced371ee81 Mon Sep 17 00:00:00 2001 From: Timm Fitschen <t.fitschen@indiscale.com> Date: Mon, 12 Jul 2021 13:35:31 +0200 Subject: [PATCH] WIP: first c-interface stub --- CMakeLists.txt | 99 ++++++++++++------- include/caosdb/constants.h.in | 10 +- include/caosdb/utils.h | 47 +++++++-- include/ccaosdb.h | 97 ++++++++++++++++++ src/ccaosdb.cpp | 25 +++++ src/ccaosdbcli.c | 20 ++++ src/{caosdbcli.cpp => cxxcaosdbcli.cpp} | 13 +-- test/CMakeLists.txt | 18 +++- ...est_utility.h => caosdb_test_utility.h.in} | 2 + test/test_ccaosdb.cpp | 33 +++++++ test/test_data/test.json | 8 ++ test/test_utils.cpp | 38 +++++-- 12 files changed, 348 insertions(+), 62 deletions(-) create mode 100644 include/ccaosdb.h create mode 100644 src/ccaosdb.cpp create mode 100644 src/ccaosdbcli.c rename src/{caosdbcli.cpp => cxxcaosdbcli.cpp} (89%) rename test/{caosdb_test_utility.h => caosdb_test_utility.h.in} (97%) create mode 100644 test/test_ccaosdb.cpp create mode 100644 test/test_data/test.json diff --git a/CMakeLists.txt b/CMakeLists.txt index eb3340b..e00824a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -24,8 +24,8 @@ set(libcaosdb_VERSION 0.0.4) project(libcaosdb VERSION ${libcaosdb_VERSION} - DESCRIPTION "C++ client libraries for CaosDB" - LANGUAGES CXX) + DESCRIPTION "C and C++ client libraries for CaosDB" + LANGUAGES CXX C) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) @@ -116,28 +116,76 @@ add_custom_command( ${PROTO_FILES} DEPENDS ${PROTO_FILES}) +############################################################################### +### Set up main targets +### * [caosdb_grpc] - only in Debug builds. Otherwise this library is compiled +### into caosdb libraray +### * caosdb (links to caosdb_grpc) - The main library. +### * cxxcaosdbcli - A C++ test client. +### * ccaosdb - A C-Wrapper of the C++ caosdb library. +### * ccaosdbcli - A plain C test client. +############################################################################### if("${CMAKE_BUILD_TYPE}" MATCHES "Debug") add_library(caosdb_grpc STATIC ${GRPC_GENERATED}) add_library(caosdb STATIC ${libcaosdb_INCL} ${libcaosdb_SRC}) target_link_libraries(caosdb caosdb_grpc) set(LIBCAOSDB caosdb caosdb_grpc) + + target_include_directories(caosdb_grpc PUBLIC + $<BUILD_INTERFACE:${libcaosdb_SOURCE_DIR}/include> + $<BUILD_INTERFACE:${libcaosdb_BINARY_DIR}/include> + + $<INSTALL_INTERFACE:include> + ${CONAN_INCLUDE_DIRS} + ) else() add_library(caosdb STATIC ${libcaosdb_INCL} ${libcaosdb_SRC} ${GRPC_GENERATED}) set(LIBCAOSDB caosdb) endif() -add_executable(caosdbcli src/caosdbcli.cpp) - target_link_libraries(caosdb ${CONAN_LIBS} ) +target_include_directories(caosdb PUBLIC + $<BUILD_INTERFACE:${libcaosdb_SOURCE_DIR}/include> + $<BUILD_INTERFACE:${libcaosdb_BINARY_DIR}/include> + $<INSTALL_INTERFACE:include> + ${CONAN_INCLUDE_DIRS} +) + +add_library(ccaosdb STATIC src/ccaosdb.cpp) +target_link_libraries(ccaosdb + ${LIBCAOSDB} + ${CONAN_LIBS} +) + +add_executable(ccaosdbcli src/ccaosdbcli.c) +target_include_directories(ccaosdbcli PUBLIC + $<BUILD_INTERFACE:${libcaosdb_SOURCE_DIR}/include> + $<BUILD_INTERFACE:${libcaosdb_BINARY_DIR}/include> + $<INSTALL_INTERFACE:include> + ${CONAN_INCLUDE_DIRS} +) +target_link_libraries(ccaosdbcli + ccaosdb + ${CONAN_LIBS} +) -target_link_libraries(caosdbcli +add_executable(cxxcaosdbcli src/cxxcaosdbcli.cpp) +target_include_directories(cxxcaosdbcli PUBLIC + $<BUILD_INTERFACE:${libcaosdb_SOURCE_DIR}/include> + $<BUILD_INTERFACE:${libcaosdb_BINARY_DIR}/include> + $<INSTALL_INTERFACE:include> + ${CONAN_INCLUDE_DIRS} +) +target_link_libraries(cxxcaosdbcli ${LIBCAOSDB} ${CONAN_LIBS} ) + + ####################################################### ### LINTING with CLANG-TIDY and INCLUDE-WHAT-YOU-USE ####################################################### @@ -165,9 +213,12 @@ if(_LINTING) set_target_properties(caosdb PROPERTIES CXX_INCLUDE_WHAT_YOU_USE "${_CMAKE_CXX_INCLUDE_WHAT_YOU_USE}" ) - set_target_properties(caosdbcli PROPERTIES + set_target_properties(cxxcaosdbcli PROPERTIES CXX_INCLUDE_WHAT_YOU_USE "${_CMAKE_CXX_INCLUDE_WHAT_YOU_USE}" ) + set_target_properties(ccaosdbcli PROPERTIES + C_INCLUDE_WHAT_YOU_USE "${_CMAKE_CXX_INCLUDE_WHAT_YOU_USE}" + ) endif() find_program(clang_tidy NAMES clang-tidy clang-tidy-11) @@ -189,9 +240,12 @@ if(_LINTING) set_target_properties(caosdb PROPERTIES CXX_CLANG_TIDY "${_CMAKE_CXX_CLANG_TIDY};${_CMAKE_CXX_CLANG_TIDY_CHECKS}" ) - set_target_properties(caosdbcli PROPERTIES + set_target_properties(cxxcaosdbcli PROPERTIES CXX_CLANG_TIDY "${_CMAKE_CXX_CLANG_TIDY};${_CMAKE_CXX_CLANG_TIDY_CHECKS}" ) + set_target_properties(ccaosdbcli PROPERTIES + C_CLANG_TIDY "${_CMAKE_CXX_CLANG_TIDY};${_CMAKE_CXX_CLANG_TIDY_CHECKS}" + ) endif() endif() @@ -212,32 +266,6 @@ endif() set(libcaosdb_INCLUDE_DEST "include/caosdb") set(libcaosdb_LIB_DEST "lib") -target_include_directories(caosdb PUBLIC - # headers to include when building from source - $<BUILD_INTERFACE:${libcaosdb_SOURCE_DIR}/include> - $<BUILD_INTERFACE:${libcaosdb_BINARY_DIR}/include> - - # headers to include when installing (implicitly prefixes with ${CMAKE_INSTALL_PREFIX}). - $<INSTALL_INTERFACE:include> -) - -if("${CMAKE_BUILD_TYPE}" MATCHES "Debug") - target_include_directories(caosdb_grpc PUBLIC - # headers to include when building from source - $<BUILD_INTERFACE:${libcaosdb_SOURCE_DIR}/include> - $<BUILD_INTERFACE:${libcaosdb_BINARY_DIR}/include> - - # headers to include when installing (implicitly prefixes with ${CMAKE_INSTALL_PREFIX}). - $<INSTALL_INTERFACE:include> - ) -endif() - -target_include_directories(caosdbcli PUBLIC - ${libcaosdb_SOURCE_DIR}/include> - ${libcaosdb_BINARY_DIR}/include> - ${CONAN_INCLUDE_DIRS} -) - set(CMAKE_INSTALL_PREFIX "$ENV{HOME}/.local/") install( # targets to install @@ -290,7 +318,10 @@ if(AUTOFORMATTING) file(GLOB format_test_sources test/*.cpp test/*.h) execute_process(COMMAND clang-format -i --verbose ${libcaosdb_INCL} ${libcaosdb_SRC} ${libcaosdb_TEST_SRC} - ${PROJECT_SOURCE_DIR}/src/caosdbcli.cpp + ${PROJECT_SOURCE_DIR}/src/cxxcaosdbcli.cpp + ${PROJECT_SOURCE_DIR}/src/ccaosdbcli.c + ${PROJECT_SOURCE_DIR}/src/ccaosdb.cpp + ${PROJECT_SOURCE_DIR}/include/ccaosdb.h ${format_test_sources} WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}) endif() diff --git a/include/caosdb/constants.h.in b/include/caosdb/constants.h.in index 02c0341..566cbb1 100644 --- a/include/caosdb/constants.h.in +++ b/include/caosdb/constants.h.in @@ -22,11 +22,15 @@ #ifndef CAOSDB_CONSTANTS_H #define CAOSDB_CONSTANTS_H +#ifdef __cplusplus namespace caosdb { +#endif // clang-format off -constexpr int LIBCAOSDB_VERSION_MAJOR = @libcaosdb_VERSION_MAJOR@; -constexpr int LIBCAOSDB_VERSION_MINOR = @libcaosdb_VERSION_MINOR@; -constexpr int LIBCAOSDB_VERSION_PATCH = @libcaosdb_VERSION_PATCH@; +const int LIBCAOSDB_VERSION_MAJOR = @libcaosdb_VERSION_MAJOR@; +const int LIBCAOSDB_VERSION_MINOR = @libcaosdb_VERSION_MINOR@; +const int LIBCAOSDB_VERSION_PATCH = @libcaosdb_VERSION_PATCH@; // clang-format on +#ifdef __cplusplus } // namespace caosdb #endif +#endif diff --git a/include/caosdb/utils.h b/include/caosdb/utils.h index 20aebbf..78d388a 100644 --- a/include/caosdb/utils.h +++ b/include/caosdb/utils.h @@ -21,14 +21,23 @@ #ifndef CAOSDB_UTILS_H #define CAOSDB_UTILS_H +#include <cassert> #include <iostream> #include <string_view> #include <fstream> #include <string> #include <cstdlib> +#include <boost/json.hpp> #include <boost/beast/core/detail/base64.hpp> +#include <boost/filesystem.hpp> +#include <boost/filesystem/fstream.hpp> namespace caosdb::utils { +using boost::filesystem::exists; +using boost::filesystem::ifstream; +using boost::filesystem::path; +using boost::json::stream_parser; +using boost::json::value; /** * @brief Read a text file into a string and return the file's content. @@ -50,18 +59,25 @@ inline auto load_string_file(const std::string &path) -> std::string { return result; } +inline auto get_env_var(const char *key, const char *fall_back) -> const + char * { + const char *val = getenv(key); + if (val == nullptr) { + return fall_back; + } else { + return val; + } +} + /** * @brief Return the value of an environment variable or - if undefined - the * fall_back value. */ inline auto get_env_var(const std::string &key, const std::string &fall_back) - -> std::string { - const char *val = getenv(key.c_str()); - if (val == nullptr) { - return fall_back; - } + -> const std::string { + const char *val = get_env_var(key.c_str(), fall_back.c_str()); - auto result = std::string(val); + auto const result = std::string(val); return result; } @@ -79,5 +95,24 @@ inline auto base64_encode(const std::string &plain) -> std::string { return std::string(encoded, encoded + size_encoded); } +inline auto load_json_file(const path &json_file) -> value { + assert(exists(json_file)); + + constexpr auto buffer_size = std::size_t(4096); + auto stream = ifstream(json_file); + stream.exceptions(std::ios_base::badbit); + + stream_parser parser; + auto result = std::string(); + auto buffer = std::string(buffer_size, '\0'); + while (stream.read(&buffer[0], buffer_size)) { + parser.write(buffer.c_str(), stream.gcount()); + } + parser.write(buffer.c_str(), stream.gcount()); + + assert(parser.done()); + return parser.release(); +} + } // namespace caosdb::utils #endif diff --git a/include/ccaosdb.h b/include/ccaosdb.h new file mode 100644 index 0000000..382364f --- /dev/null +++ b/include/ccaosdb.h @@ -0,0 +1,97 @@ +#ifdef __cplusplus +extern "C" { +#else +#include <stdbool.h> +#endif + +/** + * A wrapper of the C++ CaosDBConnection class. + * + * We use a wrapper for future extensibility and in order to have a minimal + * capability for type checking in C even though the C++ class + * CaosDBConnection is opaque in C. + */ +typedef struct { + void *wrapped_connection; +} caosdb_connection_connection; + +/** + * A wrapper of the C++ CaosDBConnectionConfig class. + * + * We use a wrapper for future extensibility and in order to have a minimal + * capability for type checking in C even though the C++ class + * CaosDBConnection is opaque in C. + */ +typedef struct { + void *wrapped_connection_config; +} caosdb_connection_connection_config; + +/** + * A wrapper of the C++ VersionInfo class. + * + * We use a wrapper for future extensibility and in order to have a minimal + * capability for type checking in C even though the C++ class + * CaosDBConnection is opaque in C. + */ +typedef struct { + void *wrapped_version_info; +} caosdb_info_version_info; + +/** + * Return the environment variable of the given name. + * + * If the environment variable is not set, return the fall_back instead. + */ +const char *caosdb_utils_get_env_var(const char *name, const char *fall_back); + +/** + * Create a connection config. + * + * The config is needed to instantiate a connection. + * + * The config is ready to be used but you might want use + * caosdb_connection_config_add_cacert and + * caosdb_connection_config_add_plain_authenticator to specify more options of + * the connection. + */ +int caosdb_connection_create_config(caosdb_connection_connection_config *config, + const char *host, const int port, + const bool tls); + +/** + * Add a public certificate of a trusted certificate authority to an + * existing, tls-enabled connection configuration. + * + * @param cacert path to a pem-file. + */ +int caosdb_connection_config_add_cacert( + caosdb_connection_connection_config *config, const char *cacert); + +/** + * Add a plain text authenticator to an existing, tls enabled connection + * configuration. + */ +int caosdb_connection_config_add_plain_authenticator( + caosdb_connection_connection_config *config, const char *username, + const char *password); + +/** + * Create a connection instance. + * + * The connection is needed to create transactions and to initiate any other + * interaction with a CaosDB server. + */ +int caosdb_connection_create_connection( + caosdb_connection_connection *connection, + const caosdb_connection_connection_config *config); + +/** + * Request the version of the server. + */ +int caosdb_connection_get_version_info( + caosdb_info_version_info *version_info, + const caosdb_connection_connection *connection); + +#ifdef __cplusplus +} +#endif diff --git a/src/ccaosdb.cpp b/src/ccaosdb.cpp new file mode 100644 index 0000000..28ea242 --- /dev/null +++ b/src/ccaosdb.cpp @@ -0,0 +1,25 @@ +#include "caosdb/utils.h" +#include "caosdb/constants.h" +#include "ccaosdb.h" + +extern "C" { +const int LIBCAOSDB_VERSION_MINOR = caosdb::LIBCAOSDB_VERSION_MAJOR; +const int LIBCAOSDB_VERSION_MAJOR = caosdb::LIBCAOSDB_VERSION_MINOR; +const int LIBCAOSDB_VERSION_PATCH = caosdb::LIBCAOSDB_VERSION_PATCH; + +const char *caosdb_utils_get_env_var(const char *name, const char *fall_back) { + return caosdb::utils::get_env_var(name, fall_back); +} + +// int caosdb_connection_create_config(caosdb_connection_config *config, const +// char *host, const int port, const bool tls); + +// int caosdb_connection_config_add_cacert(caosdb_connection_config *config, +// const char *cacert); + +// int caosdb_connection_config_add_plain_authenticator(caosdb_connection_config +// *config, const char *username, const char *password); + +// int caosdb_connection_create_connection(caosdb_connection *connection, const +// caosdb_connection_config *config); +} diff --git a/src/ccaosdbcli.c b/src/ccaosdbcli.c new file mode 100644 index 0000000..3ba70bc --- /dev/null +++ b/src/ccaosdbcli.c @@ -0,0 +1,20 @@ +#include "ccaosdb.h" +#include "caosdb/constants.h" +#include <stdio.h> +#include <stdlib.h> + +int main(void) { + printf( + "CaosDB C client (libcaosdb %d.%d.%d)\nWe don't miss the H of caos.\n\n", + LIBCAOSDB_VERSION_MAJOR, LIBCAOSDB_VERSION_MINOR, LIBCAOSDB_VERSION_PATCH); + + const char *host = + caosdb_utils_get_env_var("CAOSDB_SERVER_HOST", "localhost"); + const char *port_str = caosdb_utils_get_env_var("CAOSDB_SERVER_HOST", "8443"); + char *end = NULL; + const int port = (int)strtol(port_str, &end, 10); + + printf("Connecting to host: %s:%d\n", host, port); + + return 0; +} diff --git a/src/caosdbcli.cpp b/src/cxxcaosdbcli.cpp similarity index 89% rename from src/caosdbcli.cpp rename to src/cxxcaosdbcli.cpp index a128887..443c071 100644 --- a/src/caosdbcli.cpp +++ b/src/cxxcaosdbcli.cpp @@ -33,8 +33,8 @@ #include "caosdb/transaction.h" // for Transaction, UniqueResult auto main() -> int { - - std::cout << "CaosDB (libcaosdb " << caosdb::LIBCAOSDB_VERSION_MINOR << "." + std::cout << "CaosDB C++ client (libcaosdb " + << caosdb::LIBCAOSDB_VERSION_MINOR << "." << caosdb::LIBCAOSDB_VERSION_MINOR << "." << caosdb::LIBCAOSDB_VERSION_PATCH << ")\n" << "We don't miss the H of caos.\n" @@ -42,13 +42,14 @@ auto main() -> int { const auto pem_file = caosdb::utils::get_env_var("CAOSDB_SERVER_CERT", std::string()); - const auto host = + const auto *const host = caosdb::utils::get_env_var("CAOSDB_SERVER_HOST", "localhost"); - const auto port_str = + const auto *const port_str = caosdb::utils::get_env_var("CAOSDB_SERVER_GRPC_PORT_HTTPS", "8443"); const auto port = std::stoi(port_str); - const auto user = caosdb::utils::get_env_var("CAOSDB_USER", "admin"); - const auto password = caosdb::utils::get_env_var("CAOSDB_PASSWORD", "caosdb"); + const auto *const user = caosdb::utils::get_env_var("CAOSDB_USER", "admin"); + const auto *const password = + caosdb::utils::get_env_var("CAOSDB_PASSWORD", "caosdb"); // setup the connection auto auth = diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 2616296..0273078 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -24,6 +24,7 @@ set(test_cases test_info test_transaction test_utils + test_ccaosdb ) ################################################### @@ -38,6 +39,7 @@ set(_CMAKE_CXX_CLANG_TIDY_TEST_CHECKS # add special cmake functions for gtest include(GoogleTest) + # loop over all test cases and add them to the test runner list(LENGTH test_cases len_test_cases) math(EXPR len_test_cases "${len_test_cases} - 1") @@ -47,9 +49,9 @@ foreach (i RANGE "${len_test_cases}") set(libcaosdb_TEST_SRC "${CMAKE_CURRENT_SOURCE_DIR}/${test_case_name}.cpp ${libcaosdb_TEST_SRC}") target_link_libraries(${test_case_name} - PRIVATE ${LIBCAOSDB} ${CONAN_LIBS_GTEST} ${CONAN_LIBS_BOOST}) + PRIVATE ${LIBCAOSDB} ccaosdb ${CONAN_LIBS_GTEST} ${CONAN_LIBS_BOOST}) target_include_directories(${test_case_name} - PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) + PUBLIC ${CMAKE_CURRENT_BINARY_DIR}) if(_LINTING) set_target_properties(${test_case_name} PROPERTIES @@ -57,10 +59,18 @@ foreach (i RANGE "${len_test_cases}") CXX_INCLUDE_WHAT_YOU_USE "${_CMAKE_CXX_INCLUDE_WHAT_YOU_USE}") endif() gtest_discover_tests(${test_case_name} + WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" PROPERTIES LABELS "caosdb-cpplib-unit-tests") endforeach () +# copy test data to build dir +set(TEST_DATA_DIR "${CMAKE_CURRENT_SOURCE_DIR}/test_data") +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/caosdb_test_utility.h.in + ${CMAKE_CURRENT_BINARY_DIR}/caosdb_test_utility.h) + + + ################################################### ### Set up test coverage repor (Gcov + Lcov) @@ -75,12 +85,12 @@ if (LCOV_PATH) NAME unit_test_coverage EXECUTABLE ctest -L caosdb-cpplib-unit-tests EXCLUDE "${CMAKE_BINARY_DIR}/*" - DEPENDENCIES caosdb ${test_cases} + DEPENDENCIES caosdb ccaosdb ${test_cases} LCOV_ARGS --rc lcov_branch_coverage=1 --no-external GENHTML_ARGS --rc lcov_branch_coverage=1 ) message(STATUS "Adding COMPILE_FLAGS for coverage: ${COVERAGE_COMPILER_FLAGS}") - set_target_properties(caosdb PROPERTIES + set_target_properties(caosdb ccaosdb PROPERTIES COMPILE_FLAGS "${CMAKE_CXX_FLAGS} ${COVERAGE_COMPILER_FLAGS}") else () message(WARNING "Could not generate code coverage report. Please install lcov.") diff --git a/test/caosdb_test_utility.h b/test/caosdb_test_utility.h.in similarity index 97% rename from test/caosdb_test_utility.h rename to test/caosdb_test_utility.h.in index 981c458..8493a89 100644 --- a/test/caosdb_test_utility.h +++ b/test/caosdb_test_utility.h.in @@ -43,3 +43,5 @@ }, \ exeption_type) #endif + +const std::string TEST_DATA_DIR = "@TEST_DATA_DIR@"; diff --git a/test/test_ccaosdb.cpp b/test/test_ccaosdb.cpp new file mode 100644 index 0000000..bdec5b6 --- /dev/null +++ b/test/test_ccaosdb.cpp @@ -0,0 +1,33 @@ +/* + * + * This file is a part of the CaosDB Project. + * + * Copyright (C) 2021 Timm Fitschen <t.fitschen@indiscale.com> + * Copyright (C) 2021 IndiScale GmbH <info@indiscale.com> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + */ + +#include <gtest/gtest-message.h> // for Message +#include <gtest/gtest-test-part.h> // for SuiteApiResolver, TestFactoryImpl +#include <gtest/gtest_pred_impl.h> // for Test, TestInfo, EXPECT_EQ, TEST +#include <string> // for allocator +#include "ccaosdb.h" // for caosdb_utils_get_env_var + +TEST(test_ccaosdb, test_get_env_var) { + const char *const some_var = + caosdb_utils_get_env_var("SOME_ENV_VAR", "fall-back"); + EXPECT_EQ("fall-back", some_var); +} diff --git a/test/test_data/test.json b/test/test_data/test.json new file mode 100644 index 0000000..9f938f4 --- /dev/null +++ b/test/test_data/test.json @@ -0,0 +1,8 @@ +{ + "this": [ "is", "a", "test" ], + "it" : "tests", + "numbers": [ 1, 2, 3.3 ], + "null values": null, + "arrays and objects": + { "see?": [ true, false ] } +} diff --git a/test/test_utils.cpp b/test/test_utils.cpp index 619caee..c8b5dc8 100644 --- a/test/test_utils.cpp +++ b/test/test_utils.cpp @@ -20,17 +20,37 @@ * */ -#include "caosdb/utils.h" -#include <string> -#include <gtest/gtest-message.h> -#include <gtest/gtest-test-part.h> -#include "gtest/gtest_pred_impl.h" -#include <boost/beast/core/detail/base64.hpp> +#include <gtest/gtest-message.h> // for Message +#include <gtest/gtest-test-part.h> // for TestPartResult, SuiteA... +#include <gtest/gtest_pred_impl.h> // for Test, EXPECT_EQ, TestInfo +#include <boost/beast/core/detail/base64.hpp> // for encoded_size +#include <string> // for allocator, string, ope... +#include "boost/json/object.hpp" // for object +#include "boost/json/value.hpp" // for value +#include "caosdb/utils.h" // for base64_encode, load_js... +#include "caosdb_test_utility.h" // for TEST_DATA_DIR +#include "gmock/gmock-matchers.h" // for ElementsAre, EXPECT_THAT + +namespace caosdb::utils { +using ::testing::ElementsAre; TEST(test_utils, base64_encode) { auto test_plain = std::string("admin:caosdb"); auto test_encoded = std::string("YWRtaW46Y2Fvc2Ri"); - ASSERT_EQ(12, test_plain.size()); - ASSERT_EQ(16, boost::beast::detail::base64::encoded_size(test_plain.size())); - ASSERT_EQ(test_encoded, caosdb::utils::base64_encode(test_plain)); + EXPECT_EQ(12, test_plain.size()); + EXPECT_EQ(16, boost::beast::detail::base64::encoded_size(test_plain.size())); + EXPECT_EQ(test_encoded, base64_encode(test_plain)); } + +TEST(test_utils, test_load_json_file) { + auto json = load_json_file(TEST_DATA_DIR + "/test.json").as_object(); + + EXPECT_EQ(json["it"], "tests"); + EXPECT_EQ(json["null values"], nullptr); + EXPECT_THAT(json["this"].as_array(), ElementsAre("is", "a", "test")); + EXPECT_THAT(json["numbers"].as_array(), ElementsAre(1, 2, 3.3)); + auto sub = json["arrays and objects"].as_object(); + EXPECT_THAT(sub["see?"].as_array(), ElementsAre(true, false)); +} + +} // namespace caosdb::utils -- GitLab