Merge pull request from jkankiewicz/c_api_exp

Enable unit testing of the C API
This commit is contained in:
Orion Henry 2022-03-07 11:55:32 -05:00 committed by GitHub
commit e82a7cc78e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 125 additions and 62 deletions

View file

@ -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

View file

@ -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")

View file

@ -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()

View file

@ -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,
}

View 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
View 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);
}