Merge pull request #299 from jkankiewicz/c_api_exp
Enable unit testing of the C API
This commit is contained in:
commit
e82a7cc78e
6 changed files with 125 additions and 62 deletions
9
.github/workflows/ci.yaml
vendored
9
.github/workflows/ci.yaml
vendored
|
@ -72,7 +72,14 @@ jobs:
|
|||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Update CMake
|
||||
- uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
profile: minimal
|
||||
toolchain: stable
|
||||
- uses: Swatinem/rust-cache@v1
|
||||
- name: Install CMocka
|
||||
run: sudo apt-get install -y libcmocka-dev
|
||||
- name: Install/update CMake
|
||||
uses: jwlawson/actions-setup-cmake@v1.12
|
||||
with:
|
||||
cmake-version: latest
|
||||
|
|
|
@ -53,24 +53,20 @@ endforeach()
|
|||
|
||||
project(${CARGO_PKG_NAME} VERSION ${CARGO_PKG_VERSION} LANGUAGES C DESCRIPTION "C bindings for the Automerge Rust backend.")
|
||||
|
||||
option(BUILD_SHARED_LIBS "Enable the choice of a shared or static library.")
|
||||
include(CTest)
|
||||
|
||||
option(BUILD_TESTING "Enable the choice of testing the build." ON)
|
||||
option(BUILD_SHARED_LIBS "Enable the choice of a shared or static library.")
|
||||
|
||||
include(CMakePackageConfigHelpers)
|
||||
|
||||
include(GNUInstallDirs)
|
||||
|
||||
if(BUILD_TESTING)
|
||||
include(CTest)
|
||||
|
||||
enable_testing()
|
||||
endif()
|
||||
|
||||
string(MAKE_C_IDENTIFIER ${PROJECT_NAME} SYMBOL_PREFIX)
|
||||
|
||||
string(TOUPPER ${SYMBOL_PREFIX} SYMBOL_PREFIX)
|
||||
|
||||
set(CARGO_TARGET_DIR "${CMAKE_CURRENT_BINARY_DIR}/Cargo/target")
|
||||
|
||||
add_subdirectory(src)
|
||||
|
||||
# Generate and install the configuration header.
|
||||
|
@ -94,6 +90,12 @@ install(
|
|||
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME}
|
||||
)
|
||||
|
||||
if(BUILD_TESTING)
|
||||
add_subdirectory(test)
|
||||
|
||||
enable_testing()
|
||||
endif()
|
||||
|
||||
# Generate and install .cmake files
|
||||
set(PROJECT_CONFIG_NAME "${PROJECT_NAME}-config")
|
||||
|
||||
|
|
|
@ -23,8 +23,6 @@ else()
|
|||
set(CARGO_FLAG "--release")
|
||||
endif()
|
||||
|
||||
set(CARGO_TARGET_DIR "${CMAKE_CURRENT_BINARY_DIR}/Cargo/target")
|
||||
|
||||
set(CARGO_CURRENT_BINARY_DIR "${CARGO_TARGET_DIR}/${CARGO_BUILD_TYPE}")
|
||||
|
||||
set(
|
||||
|
@ -58,6 +56,14 @@ add_custom_command(
|
|||
VERBATIM
|
||||
)
|
||||
|
||||
# \note This target is only necessary because cbindgen won't allow the
|
||||
# generated header to be listed in the Cargo command's output, being
|
||||
# another target's source file would've been enough otherwise.
|
||||
add_custom_target(
|
||||
${LIBRARY_NAME}_artifacts
|
||||
DEPENDS ${CARGO_OUTPUT}
|
||||
)
|
||||
|
||||
if(BUILD_SHARED_LIBS)
|
||||
if(WIN32)
|
||||
set(LIBRARY_DESTINATION "${CMAKE_INSTALL_BINDIR}")
|
||||
|
@ -96,7 +102,7 @@ endif()
|
|||
|
||||
add_library(${LIBRARY_NAME} ${LIBRARY_TYPE} IMPORTED GLOBAL)
|
||||
|
||||
target_sources(${LIBRARY_NAME} INTERFACE ${CARGO_OUTPUT})
|
||||
add_dependencies(${LIBRARY_NAME} ${LIBRARY_NAME}_artifacts)
|
||||
|
||||
set_target_properties(
|
||||
${LIBRARY_NAME}
|
||||
|
@ -163,43 +169,6 @@ install(
|
|||
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME}
|
||||
)
|
||||
|
||||
if(BUILD_TESTING)
|
||||
add_executable(test_${LIBRARY_NAME} ${CMAKE_SOURCE_DIR}/${LIBRARY_NAME}.c)
|
||||
|
||||
set_target_properties(test_${LIBRARY_NAME} PROPERTIES LINKER_LANGUAGE C)
|
||||
|
||||
# \note An imported library's INTERFACE_INCLUDE_DIRECTORIES property can't
|
||||
# contain a non-existent path so its build-time include directory
|
||||
# must be specified for all of its dependent targets instead.
|
||||
target_include_directories(test_${LIBRARY_NAME} PRIVATE "$<BUILD_INTERFACE:${CARGO_TARGET_DIR}>")
|
||||
|
||||
target_link_libraries(test_${LIBRARY_NAME} PRIVATE ${LIBRARY_NAME})
|
||||
|
||||
add_test(NAME "test_${LIBRARY_NAME}" COMMAND test_${LIBRARY_NAME})
|
||||
|
||||
if(BUILD_SHARED_LIBS AND WIN32)
|
||||
add_custom_command(
|
||||
TARGET test_${LIBRARY_NAME}
|
||||
POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||
${CARGO_CURRENT_BINARY_DIR}/${CMAKE_SHARED_LIBRARY_PREFIX}${LIBRARY_NAME}${CMAKE_${CMAKE_BUILD_TYPE}_POSTFIX}${CMAKE_SHARED_LIBRARY_SUFFIX}
|
||||
${CMAKE_CURRENT_BINARY_DIR}
|
||||
COMMENT "Copying the DLL built by Cargo into the test directory..."
|
||||
VERBATIM
|
||||
)
|
||||
endif()
|
||||
|
||||
add_custom_command(
|
||||
TARGET test_${LIBRARY_NAME}
|
||||
POST_BUILD
|
||||
COMMAND
|
||||
ctest -C $<CONFIGURATION> --output-on-failure
|
||||
COMMENT
|
||||
"Running the test(s)..."
|
||||
VERBATIM
|
||||
)
|
||||
endif()
|
||||
|
||||
find_package(Doxygen OPTIONAL_COMPONENTS dot)
|
||||
|
||||
if(DOXYGEN_FOUND)
|
||||
|
@ -211,14 +180,6 @@ if(DOXYGEN_FOUND)
|
|||
|
||||
set(DOXYGEN_USE_MDFILE_AS_MAINPAGE "${CMAKE_SOURCE_DIR}/README.md")
|
||||
|
||||
# \note This target is only necessary because cbindgen won't allow the
|
||||
# generated header to be listed in the Cargo command's output, being
|
||||
# Doxygen's input would've been enough otherwise.
|
||||
add_custom_target(
|
||||
${LIBRARY_NAME}_header
|
||||
DEPENDS ${CARGO_OUTPUT}
|
||||
)
|
||||
|
||||
doxygen_add_docs(
|
||||
${LIBRARY_NAME}_docs
|
||||
"${CARGO_TARGET_DIR}/${LIBRARY_NAME}.h"
|
||||
|
@ -227,6 +188,5 @@ if(DOXYGEN_FOUND)
|
|||
COMMENT "Producing documentation with Doxygen..."
|
||||
)
|
||||
|
||||
add_dependencies(${LIBRARY_NAME}_docs ${LIBRARY_NAME}_header)
|
||||
|
||||
add_dependencies(${LIBRARY_NAME}_docs ${LIBRARY_NAME}_artifacts)
|
||||
endif()
|
||||
|
|
|
@ -13,11 +13,11 @@ use result::AMresult;
|
|||
/// \enum AmObjType
|
||||
#[repr(u8)]
|
||||
pub enum AmObjType {
|
||||
/// a key value map
|
||||
/// A key/value map.
|
||||
Map,
|
||||
/// a list
|
||||
/// A list.
|
||||
List,
|
||||
/// a list of unicode graphememes
|
||||
/// A list of Unicode graphemes.
|
||||
Text,
|
||||
}
|
||||
|
||||
|
|
43
automerge-c/test/CMakeLists.txt
Normal file
43
automerge-c/test/CMakeLists.txt
Normal file
|
@ -0,0 +1,43 @@
|
|||
cmake_minimum_required(VERSION 3.18 FATAL_ERROR)
|
||||
|
||||
find_package(cmocka REQUIRED)
|
||||
|
||||
add_executable(test_${LIBRARY_NAME} main.c)
|
||||
|
||||
set_target_properties(test_${LIBRARY_NAME} PROPERTIES LINKER_LANGUAGE C)
|
||||
|
||||
# \note An imported library's INTERFACE_INCLUDE_DIRECTORIES property can't
|
||||
# contain a non-existent path so its build-time include directory
|
||||
# must be specified for all of its dependent targets instead.
|
||||
target_include_directories(
|
||||
test_${LIBRARY_NAME}
|
||||
PRIVATE "$<BUILD_INTERFACE:${CARGO_TARGET_DIR}>"
|
||||
)
|
||||
|
||||
target_link_libraries(test_${LIBRARY_NAME} PRIVATE cmocka ${LIBRARY_NAME})
|
||||
|
||||
add_dependencies(test_${LIBRARY_NAME} ${LIBRARY_NAME}_artifacts)
|
||||
|
||||
if(BUILD_SHARED_LIBS AND WIN32)
|
||||
add_custom_command(
|
||||
TARGET test_${LIBRARY_NAME}
|
||||
POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||
${CARGO_CURRENT_BINARY_DIR}/${CMAKE_SHARED_LIBRARY_PREFIX}${LIBRARY_NAME}${CMAKE_${CMAKE_BUILD_TYPE}_POSTFIX}${CMAKE_SHARED_LIBRARY_SUFFIX}
|
||||
${CMAKE_CURRENT_BINARY_DIR}
|
||||
COMMENT "Copying the DLL built by Cargo into the test directory..."
|
||||
VERBATIM
|
||||
)
|
||||
endif()
|
||||
|
||||
add_test(NAME test_${LIBRARY_NAME} COMMAND test_${LIBRARY_NAME})
|
||||
|
||||
add_custom_command(
|
||||
TARGET test_${LIBRARY_NAME}
|
||||
POST_BUILD
|
||||
COMMAND
|
||||
${CMAKE_CTEST_COMMAND} --config $<CONFIG> --output-on-failure
|
||||
COMMENT
|
||||
"Running the test(s)..."
|
||||
VERBATIM
|
||||
)
|
51
automerge-c/test/main.c
Normal file
51
automerge-c/test/main.c
Normal file
|
@ -0,0 +1,51 @@
|
|||
#include <stdarg.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <setjmp.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/* third-party */
|
||||
#include <cmocka.h>
|
||||
|
||||
/* local */
|
||||
#include "automerge.h"
|
||||
|
||||
typedef struct {
|
||||
AMdoc* doc;
|
||||
} GroupState;
|
||||
|
||||
static int group_setup(void** state) {
|
||||
GroupState* group_state = calloc(1, sizeof(GroupState));
|
||||
group_state->doc = AMcreate();
|
||||
*state = group_state;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int group_teardown(void** state) {
|
||||
GroupState* group_state = *state;
|
||||
AMdestroy(group_state->doc);
|
||||
free(group_state);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void test_AMconfig(void **state) {
|
||||
GroupState* group_state = *state;
|
||||
AMconfig(group_state->doc, "actor", "aabbcc");
|
||||
}
|
||||
|
||||
static void test_AMmapSetStr(void **state) {
|
||||
GroupState* group_state = *state;
|
||||
AMresult* res = AMmapSetStr(group_state->doc, NULL, "string", "hello world");
|
||||
if (AMresultStatus(res) != AM_STATUS_COMMAND_OK) {
|
||||
fail_msg("%s", AMerrorMessage(res));
|
||||
}
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
const struct CMUnitTest tests[] = {
|
||||
cmocka_unit_test(test_AMconfig),
|
||||
cmocka_unit_test(test_AMmapSetStr),
|
||||
};
|
||||
|
||||
return cmocka_run_group_tests(tests, group_setup, group_teardown);
|
||||
}
|
Loading…
Add table
Reference in a new issue