[v2.2.0] Merge branch 'bleeding' (Version release)
This commit is contained in:
commit
65aa79dd52
150 changed files with 13155 additions and 1949 deletions
|
@ -1,5 +1,5 @@
|
|||
[bumpversion]
|
||||
current_version = 2.1.0
|
||||
current_version = 2.2.0
|
||||
commit = False
|
||||
|
||||
[bumpversion:file:CMakeLists.txt]
|
||||
|
|
12
.cmake/Modules/Capabilities.cmake
Normal file
12
.cmake/Modules/Capabilities.cmake
Normal file
|
@ -0,0 +1,12 @@
|
|||
# Copyright (C) 2015 Franklin "Snaipe" Mathieu.
|
||||
# Redistribution and use of this file is allowed according to the terms of the MIT license.
|
||||
# For details see the LICENSE file distributed with Criterion.
|
||||
|
||||
include(CheckPrototypeDefinition)
|
||||
|
||||
check_prototype_definition(
|
||||
strtok_s
|
||||
"char *strtok_s(char *strToken, const char *strDelimit, char **context)"
|
||||
NULL
|
||||
"string.h"
|
||||
HAVE_STRTOK_S)
|
42
.cmake/Modules/DebConfig.cmake
Normal file
42
.cmake/Modules/DebConfig.cmake
Normal file
|
@ -0,0 +1,42 @@
|
|||
# build a Debian package for Launchpad
|
||||
set(CPACK_DEBIAN_PACKAGE_NAME "criterion")
|
||||
set(CPACK_DEBIAN_PACKAGE_PRIORITY "optional")
|
||||
set(CPACK_DEBIAN_PACKAGE_SECTION "libs")
|
||||
set(CPACK_DEBIAN_PACKAGE_HOMEPAGE "https://github.com/Snaipe/Criterion")
|
||||
set(CPACK_DEBIAN_BUILD_DEPENDS
|
||||
debhelper
|
||||
cmake
|
||||
gettext
|
||||
libpcre3-dev
|
||||
)
|
||||
|
||||
set(CPACK_DEBIAN_PACKAGE_DEPENDS
|
||||
libpcre3
|
||||
)
|
||||
|
||||
set(CPACK_DEBIAN_CMAKE_OPTIONS)
|
||||
set(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_SOURCE_DIR}/description.txt")
|
||||
|
||||
set(CPACK_DEBIAN_PACKAGE_SOURCE_COPY "${CMAKE_SOURCE_DIR}/.cmake/copy-source.sh")
|
||||
|
||||
set(CPACK_DEBIAN_DISTRIBUTION_NAME ubuntu)
|
||||
set(CPACK_DEBIAN_DISTRIBUTION_RELEASES precise trusty vivid wily xenial)
|
||||
|
||||
set(DPUT_HOST "snaipewastaken-ppa")
|
||||
set(DPUT_SNAPSHOT_HOST "snaipewastaken-ppa")
|
||||
set(CPACK_DEBIAN_PACKAGE_DOCS "")
|
||||
set(CPACK_DEBIAN_PACKAGE_INSTALL
|
||||
"/usr/lib/*.so"
|
||||
"/usr/lib/*.so.*"
|
||||
"/usr/share/locale/*"
|
||||
)
|
||||
|
||||
set(CPACK_COMPONENTS_ALL "dev")
|
||||
set(CPACK_COMPONENT_DEV_DISPLAY_NAME "Criterion library development files")
|
||||
set(CPACK_COMPONENT_DEV_DESCRIPTION "These are the development files.")
|
||||
set(CPACK_COMPONENT_DEV_SECTION "devel")
|
||||
|
||||
set(CPACK_COMPONENT_DEV_DOCS "")
|
||||
set(CPACK_COMPONENT_DEV_INSTALL "/usr/include")
|
||||
|
||||
include (DebSourcePPA)
|
347
.cmake/Modules/DebSourcePPA.cmake
Normal file
347
.cmake/Modules/DebSourcePPA.cmake
Normal file
|
@ -0,0 +1,347 @@
|
|||
## Debian Source Package Generator
|
||||
#
|
||||
# Copyright (c) 2010 Daniel Pfeifer <daniel@pfeifer-mail.de>
|
||||
# Many modifications by Rosen Diankov <rosen.diankov@gmail.com>
|
||||
#
|
||||
# Creates source debian files and manages library dependencies
|
||||
#
|
||||
# Features:
|
||||
#
|
||||
# - Automatically generates symbols and run-time dependencies from the build dependencies
|
||||
# - Custom copy of source directory via CPACK_DEBIAN_PACKAGE_SOURCE_COPY
|
||||
# - Simultaneous output of multiple debian source packages for each distribution
|
||||
# - Can specificy distribution-specific dependencies by suffixing DEPENDS with _${DISTRO_NAME}, for example: CPACK_DEBIAN_PACKAGE_DEPENDS_LUCID, CPACK_COMPONENT_MYCOMP0_DEPENDS_LUCID
|
||||
#
|
||||
# Usage:
|
||||
#
|
||||
# set(CPACK_DEBIAN_BUILD_DEPENDS debhelper cmake)
|
||||
# set(CPACK_DEBIAN_PACKAGE_PRIORITY optional)
|
||||
# set(CPACK_DEBIAN_PACKAGE_SECTION devel)
|
||||
# set(CPACK_DEBIAN_CMAKE_OPTIONS "-DMYOPTION=myvalue")
|
||||
# set(CPACK_DEBIAN_PACKAGE_DEPENDS mycomp0 mycomp1 some_ubuntu_package)
|
||||
# set(CPACK_DEBIAN_PACKAGE_DEPENDS_UBUNTU_LUCID mycomp0 mycomp1 lucid_specific_package)
|
||||
# set(CPACK_DEBIAN_PACKAGE_NAME mypackage)
|
||||
# set(CPACK_DEBIAN_PACKAGE_REMOVE_SOURCE_FILES unnecessary_file unnecessary_dir/file0)
|
||||
# set(CPACK_DEBIAN_PACKAGE_SOURCE_COPY svn export --force) # if using subversion
|
||||
# set(CPACK_DEBIAN_DISTRIBUTION_NAME ubuntu)
|
||||
# set(CPACK_DEBIAN_DISTRIBUTION_RELEASES karmic lucid maverick natty)
|
||||
# set(CPACK_DEBIAN_CHANGELOG " * Extra change log lines")
|
||||
# set(CPACK_DEBIAN_PACKAGE_SUGGESTS "ipython")
|
||||
# set(CPACK_COMPONENT_X_RECOMMENDS "recommended-package")
|
||||
##
|
||||
|
||||
find_program(DEBUILD_EXECUTABLE debuild)
|
||||
find_program(DPUT_EXECUTABLE dput)
|
||||
|
||||
if(NOT DEBUILD_EXECUTABLE OR NOT DPUT_EXECUTABLE)
|
||||
return()
|
||||
endif(NOT DEBUILD_EXECUTABLE OR NOT DPUT_EXECUTABLE)
|
||||
|
||||
# DEBIAN/control
|
||||
# debian policy enforce lower case for package name
|
||||
# Package: (mandatory)
|
||||
IF(NOT CPACK_DEBIAN_PACKAGE_NAME)
|
||||
STRING(TOLOWER "${CPACK_PACKAGE_NAME}" CPACK_DEBIAN_PACKAGE_NAME)
|
||||
ENDIF(NOT CPACK_DEBIAN_PACKAGE_NAME)
|
||||
|
||||
# Section: (recommended)
|
||||
IF(NOT CPACK_DEBIAN_PACKAGE_SECTION)
|
||||
SET(CPACK_DEBIAN_PACKAGE_SECTION "devel")
|
||||
ENDIF(NOT CPACK_DEBIAN_PACKAGE_SECTION)
|
||||
|
||||
# Priority: (recommended)
|
||||
IF(NOT CPACK_DEBIAN_PACKAGE_PRIORITY)
|
||||
SET(CPACK_DEBIAN_PACKAGE_PRIORITY "optional")
|
||||
ENDIF(NOT CPACK_DEBIAN_PACKAGE_PRIORITY)
|
||||
|
||||
file(STRINGS ${CPACK_PACKAGE_DESCRIPTION_FILE} DESC_LINES)
|
||||
foreach(LINE ${DESC_LINES})
|
||||
set(DEB_LONG_DESCRIPTION "${DEB_LONG_DESCRIPTION} ${LINE}\n")
|
||||
endforeach(LINE ${DESC_LINES})
|
||||
|
||||
file(REMOVE_RECURSE "${CMAKE_BINARY_DIR}/Debian")
|
||||
file(MAKE_DIRECTORY "${CMAKE_BINARY_DIR}/Debian")
|
||||
set(DEBIAN_SOURCE_ORIG_DIR "${CMAKE_BINARY_DIR}/Debian/${CPACK_DEBIAN_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}")
|
||||
|
||||
if( CPACK_DEBIAN_PACKAGE_SOURCE_COPY )
|
||||
execute_process(COMMAND ${CPACK_DEBIAN_PACKAGE_SOURCE_COPY} "${CMAKE_SOURCE_DIR}" "${DEBIAN_SOURCE_ORIG_DIR}.orig")
|
||||
else()
|
||||
execute_process(COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR} "${DEBIAN_SOURCE_ORIG_DIR}.orig")
|
||||
execute_process(COMMAND ${CMAKE_COMMAND} -E remove_directory "${DEBIAN_SOURCE_ORIG_DIR}.orig/.git")
|
||||
execute_process(COMMAND ${CMAKE_COMMAND} -E remove_directory "${DEBIAN_SOURCE_ORIG_DIR}.orig/.svn")
|
||||
endif()
|
||||
|
||||
# remove unnecessary folders
|
||||
foreach(REMOVE_DIR ${CPACK_DEBIAN_PACKAGE_REMOVE_SOURCE_FILES})
|
||||
file(REMOVE_RECURSE ${DEBIAN_SOURCE_ORIG_DIR}.orig/${REMOVE_DIR})
|
||||
endforeach()
|
||||
|
||||
# create the original source tar
|
||||
execute_process(COMMAND ${CMAKE_COMMAND} -E tar czf "${CPACK_DEBIAN_PACKAGE_NAME}_${CPACK_PACKAGE_VERSION}.orig.tar.gz" "${CPACK_DEBIAN_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}.orig" WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/Debian)
|
||||
|
||||
set(DEB_SOURCE_CHANGES)
|
||||
foreach(RELEASE ${CPACK_DEBIAN_DISTRIBUTION_RELEASES})
|
||||
set(DEBIAN_SOURCE_DIR "${DEBIAN_SOURCE_ORIG_DIR}-${CPACK_DEBIAN_DISTRIBUTION_NAME}1~${RELEASE}1")
|
||||
set(RELEASE_PACKAGE_VERSION "${CPACK_PACKAGE_VERSION}-${CPACK_DEBIAN_DISTRIBUTION_NAME}1~${RELEASE}1")
|
||||
string(TOUPPER ${RELEASE} RELEASE_UPPER)
|
||||
string(TOUPPER ${CPACK_DEBIAN_DISTRIBUTION_NAME} DISTRIBUTION_NAME_UPPER)
|
||||
file(MAKE_DIRECTORY ${DEBIAN_SOURCE_DIR}/debian)
|
||||
##############################################################################
|
||||
# debian/control
|
||||
set(DEBIAN_CONTROL ${DEBIAN_SOURCE_DIR}/debian/control)
|
||||
file(WRITE ${DEBIAN_CONTROL}
|
||||
"Source: ${CPACK_DEBIAN_PACKAGE_NAME}\n"
|
||||
"Section: ${CPACK_DEBIAN_PACKAGE_SECTION}\n"
|
||||
"Priority: ${CPACK_DEBIAN_PACKAGE_PRIORITY}\n"
|
||||
"DM-Upload-Allowed: yes\n"
|
||||
"Maintainer: ${CPACK_PACKAGE_CONTACT}\n"
|
||||
"Build-Depends: "
|
||||
)
|
||||
|
||||
if( CPACK_DEBIAN_BUILD_DEPENDS_${DISTRIBUTION_NAME_UPPER}_${RELEASE_UPPER} )
|
||||
foreach(DEP ${CPACK_DEBIAN_BUILD_DEPENDS_${DISTRIBUTION_NAME_UPPER}_${RELEASE_UPPER}})
|
||||
file(APPEND ${DEBIAN_CONTROL} "${DEP}, ")
|
||||
endforeach(DEP ${CPACK_DEBIAN_BUILD_DEPENDS_${DISTRIBUTION_NAME_UPPER}_${RELEASE_UPPER}})
|
||||
else( CPACK_DEBIAN_BUILD_DEPENDS_${DISTRIBUTION_NAME_UPPER}_${RELEASE_UPPER} )
|
||||
if( CPACK_DEBIAN_BUILD_DEPENDS_${DISTRIBUTION_NAME_UPPER} )
|
||||
foreach(DEP ${CPACK_DEBIAN_BUILD_DEPENDS_${DISTRIBUTION_NAME_UPPER}})
|
||||
file(APPEND ${DEBIAN_CONTROL} "${DEP}, ")
|
||||
endforeach(DEP ${CPACK_DEBIAN_BUILD_DEPENDS_${DISTRIBUTION_NAME_UPPER}})
|
||||
else( CPACK_DEBIAN_BUILD_DEPENDS_${DISTRIBUTION_NAME_UPPER} )
|
||||
foreach(DEP ${CPACK_DEBIAN_BUILD_DEPENDS})
|
||||
file(APPEND ${DEBIAN_CONTROL} "${DEP}, ")
|
||||
endforeach(DEP ${CPACK_DEBIAN_BUILD_DEPENDS})
|
||||
endif( CPACK_DEBIAN_BUILD_DEPENDS_${DISTRIBUTION_NAME_UPPER} )
|
||||
endif( CPACK_DEBIAN_BUILD_DEPENDS_${DISTRIBUTION_NAME_UPPER}_${RELEASE_UPPER} )
|
||||
|
||||
|
||||
file(APPEND ${DEBIAN_CONTROL} "\n"
|
||||
"Standards-Version: 3.8.4\n"
|
||||
"Homepage: ${CPACK_PACKAGE_VENDOR}\n"
|
||||
"\n"
|
||||
"Package: ${CPACK_DEBIAN_PACKAGE_NAME}\n"
|
||||
"Architecture: any\n"
|
||||
"Depends: "
|
||||
)
|
||||
|
||||
if( CPACK_DEBIAN_PACKAGE_DEPENDS_${DISTRIBUTION_NAME_UPPER}_${RELEASE_UPPER} )
|
||||
foreach(DEP ${CPACK_DEBIAN_PACKAGE_DEPENDS_${DISTRIBUTION_NAME_UPPER}_${RELEASE_UPPER}})
|
||||
file(APPEND ${DEBIAN_CONTROL} "${DEP}, ")
|
||||
endforeach(DEP ${CPACK_DEBIAN_PACKAGE_DEPENDS_${DISTRIBUTION_NAME_UPPER}_${RELEASE_UPPER}})
|
||||
else( CPACK_DEBIAN_PACKAGE_DEPENDS_${DISTRIBUTION_NAME_UPPER}_${RELEASE_UPPER} )
|
||||
if( CPACK_DEBIAN_PACKAGE_DEPENDS_${DISTRIBUTION_NAME_UPPER} )
|
||||
foreach(DEP ${CPACK_DEBIAN_PACKAGE_DEPENDS_${DISTRIBUTION_NAME_UPPER}})
|
||||
file(APPEND ${DEBIAN_CONTROL} "${DEP}, ")
|
||||
endforeach(DEP ${CPACK_DEBIAN_PACKAGE_DEPENDS_${DISTRIBUTION_NAME_UPPER}})
|
||||
else( CPACK_DEBIAN_PACKAGE_DEPENDS_${DISTRIBUTION_NAME_UPPER} )
|
||||
foreach(DEP ${CPACK_DEBIAN_PACKAGE_DEPENDS})
|
||||
file(APPEND ${DEBIAN_CONTROL} "${DEP}, ")
|
||||
endforeach(DEP ${CPACK_DEBIAN_PACKAGE_DEPENDS})
|
||||
endif( CPACK_DEBIAN_PACKAGE_DEPENDS_${DISTRIBUTION_NAME_UPPER} )
|
||||
endif( CPACK_DEBIAN_PACKAGE_DEPENDS_${DISTRIBUTION_NAME_UPPER}_${RELEASE_UPPER} )
|
||||
|
||||
file(APPEND ${DEBIAN_CONTROL} "\nRecommends: ")
|
||||
if( CPACK_DEBIAN_PACKAGE_RECOMMENDS_${DISTRIBUTION_NAME_UPPER}_${RELEASE_UPPER} )
|
||||
foreach(DEP ${CPACK_DEBIAN_PACKAGE_RECOMMENDS_${DISTRIBUTION_NAME_UPPER}_${RELEASE_UPPER}})
|
||||
file(APPEND ${DEBIAN_CONTROL} "${DEP}, ")
|
||||
endforeach(DEP ${CPACK_DEBIAN_PACKAGE_RECOMMENDS_${DISTRIBUTION_NAME_UPPER}_${RELEASE_UPPER}})
|
||||
else( CPACK_DEBIAN_PACKAGE_RECOMMENDS_${DISTRIBUTION_NAME_UPPER}_${RELEASE_UPPER} )
|
||||
if( CPACK_DEBIAN_PACKAGE_RECOMMENDS_${DISTRIBUTION_NAME_UPPER} )
|
||||
foreach(DEP ${CPACK_DEBIAN_PACKAGE_RECOMMENDS_${DISTRIBUTION_NAME_UPPER}})
|
||||
file(APPEND ${DEBIAN_CONTROL} "${DEP}, ")
|
||||
endforeach(DEP ${CPACK_DEBIAN_PACKAGE_RECOMMENDS_${DISTRIBUTION_NAME_UPPER}})
|
||||
else( CPACK_DEBIAN_PACKAGE_RECOMMENDS_${DISTRIBUTION_NAME_UPPER} )
|
||||
foreach(DEP ${CPACK_DEBIAN_PACKAGE_RECOMMENDS})
|
||||
file(APPEND ${DEBIAN_CONTROL} "${DEP}, ")
|
||||
endforeach(DEP ${CPACK_DEBIAN_PACKAGE_RECOMMENDS})
|
||||
endif( CPACK_DEBIAN_PACKAGE_RECOMMENDS_${DISTRIBUTION_NAME_UPPER} )
|
||||
endif( CPACK_DEBIAN_PACKAGE_RECOMMENDS_${DISTRIBUTION_NAME_UPPER}_${RELEASE_UPPER} )
|
||||
|
||||
file(APPEND ${DEBIAN_CONTROL} "\nSuggests: ")
|
||||
if( CPACK_DEBIAN_PACKAGE_SUGGESTS_${DISTRIBUTION_NAME_UPPER}_${RELEASE_UPPER} )
|
||||
foreach(DEP ${CPACK_DEBIAN_PACKAGE_SUGGESTS_${DISTRIBUTION_NAME_UPPER}_${RELEASE_UPPER}})
|
||||
file(APPEND ${DEBIAN_CONTROL} "${DEP}, ")
|
||||
endforeach(DEP ${CPACK_DEBIAN_PACKAGE_SUGGESTS_${DISTRIBUTION_NAME_UPPER}_${RELEASE_UPPER}})
|
||||
else( CPACK_DEBIAN_PACKAGE_SUGGESTS_${DISTRIBUTION_NAME_UPPER}_${RELEASE_UPPER} )
|
||||
if( CPACK_DEBIAN_PACKAGE_SUGGESTS_${DISTRIBUTION_NAME_UPPER} )
|
||||
foreach(DEP ${CPACK_DEBIAN_PACKAGE_SUGGESTS_${DISTRIBUTION_NAME_UPPER}})
|
||||
file(APPEND ${DEBIAN_CONTROL} "${DEP}, ")
|
||||
endforeach(DEP ${CPACK_DEBIAN_PACKAGE_SUGGESTS_${DISTRIBUTION_NAME_UPPER}})
|
||||
else( CPACK_DEBIAN_PACKAGE_SUGGESTS_${DISTRIBUTION_NAME_UPPER} )
|
||||
foreach(DEP ${CPACK_DEBIAN_PACKAGE_SUGGESTS})
|
||||
file(APPEND ${DEBIAN_CONTROL} "${DEP}, ")
|
||||
endforeach(DEP ${CPACK_DEBIAN_PACKAGE_SUGGESTS})
|
||||
endif( CPACK_DEBIAN_PACKAGE_SUGGESTS_${DISTRIBUTION_NAME_UPPER} )
|
||||
endif( CPACK_DEBIAN_PACKAGE_SUGGESTS_${DISTRIBUTION_NAME_UPPER}_${RELEASE_UPPER} )
|
||||
|
||||
file(APPEND ${DEBIAN_CONTROL} "\n"
|
||||
"Description: ${CPACK_PACKAGE_DISPLAY_NAME} ${CPACK_PACKAGE_DESCRIPTION_SUMMARY}\n"
|
||||
"${DEB_LONG_DESCRIPTION}"
|
||||
)
|
||||
|
||||
foreach(COMPONENT ${CPACK_COMPONENTS_ALL})
|
||||
string(TOUPPER ${COMPONENT} UPPER_COMPONENT)
|
||||
set(DEPENDS "\${shlibs:Depends}")
|
||||
if( CPACK_COMPONENT_${UPPER_COMPONENT}_DEPENDS_${DISTRIBUTION_NAME_UPPER}_${RELEASE_UPPER} )
|
||||
foreach(DEP ${CPACK_COMPONENT_${UPPER_COMPONENT}_DEPENDS_${DISTRIBUTION_NAME_UPPER}_${RELEASE_UPPER}})
|
||||
set(DEPENDS "${DEPENDS}, ${DEP}")
|
||||
endforeach(DEP ${CPACK_COMPONENT_${UPPER_COMPONENT}_DEPENDS_${DISTRIBUTION_NAME_UPPER}_${RELEASE_UPPER}})
|
||||
else( CPACK_COMPONENT_${UPPER_COMPONENT}_DEPENDS_${DISTRIBUTION_NAME_UPPER}_${RELEASE_UPPER} )
|
||||
if( CPACK_COMPONENT_${UPPER_COMPONENT}_DEPENDS_${DISTRIBUTION_NAME_UPPER} )
|
||||
foreach(DEP ${CPACK_COMPONENT_${UPPER_COMPONENT}_DEPENDS_${DISTRIBUTION_NAME_UPPER}})
|
||||
set(DEPENDS "${DEPENDS}, ${DEP}")
|
||||
endforeach(DEP ${CPACK_COMPONENT_${UPPER_COMPONENT}_DEPENDS_${DISTRIBUTION_NAME_UPPER}})
|
||||
else( CPACK_COMPONENT_${UPPER_COMPONENT}_DEPENDS_${DISTRIBUTION_NAME_UPPER} )
|
||||
foreach(DEP ${CPACK_COMPONENT_${UPPER_COMPONENT}_DEPENDS})
|
||||
set(DEPENDS "${DEPENDS}, ${DEP}")
|
||||
endforeach(DEP ${CPACK_COMPONENT_${UPPER_COMPONENT}_DEPENDS})
|
||||
endif( CPACK_COMPONENT_${UPPER_COMPONENT}_DEPENDS_${DISTRIBUTION_NAME_UPPER} )
|
||||
endif( CPACK_COMPONENT_${UPPER_COMPONENT}_DEPENDS_${DISTRIBUTION_NAME_UPPER}_${RELEASE_UPPER} )
|
||||
|
||||
set(RECOMMENDS)
|
||||
if( CPACK_COMPONENT_${UPPER_COMPONENT}_RECOMMENDS_${DISTRIBUTION_NAME_UPPER}_${RELEASE_UPPER} )
|
||||
foreach(DEP ${CPACK_COMPONENT_${UPPER_COMPONENT}_RECOMMENDS_${DISTRIBUTION_NAME_UPPER}_${RELEASE_UPPER}})
|
||||
set(RECOMMENDS "${RECOMMENDS} ${DEP}, ")
|
||||
endforeach(DEP ${CPACK_COMPONENT_${UPPER_COMPONENT}_RECOMMENDS_${DISTRIBUTION_NAME_UPPER}_${RELEASE_UPPER}})
|
||||
else( CPACK_COMPONENT_${UPPER_COMPONENT}_RECOMMENDS_${DISTRIBUTION_NAME_UPPER}_${RELEASE_UPPER} )
|
||||
if( CPACK_COMPONENT_${UPPER_COMPONENT}_RECOMMENDS_${DISTRIBUTION_NAME_UPPER} )
|
||||
foreach(DEP ${CPACK_COMPONENT_${UPPER_COMPONENT}_RECOMMENDS_${DISTRIBUTION_NAME_UPPER}})
|
||||
set(RECOMMENDS "${RECOMMENDS} ${DEP}, ")
|
||||
endforeach(DEP ${CPACK_COMPONENT_${UPPER_COMPONENT}_RECOMMENDS_${DISTRIBUTION_NAME_UPPER}})
|
||||
else( CPACK_COMPONENT_${UPPER_COMPONENT}_RECOMMENDS_${DISTRIBUTION_NAME_UPPER} )
|
||||
foreach(DEP ${CPACK_COMPONENT_${UPPER_COMPONENT}_RECOMMENDS})
|
||||
set(RECOMMENDS "${RECOMMENDS} ${DEP}, ")
|
||||
endforeach(DEP ${CPACK_COMPONENT_${UPPER_COMPONENT}_RECOMMENDS})
|
||||
endif( CPACK_COMPONENT_${UPPER_COMPONENT}_RECOMMENDS_${DISTRIBUTION_NAME_UPPER} )
|
||||
endif( CPACK_COMPONENT_${UPPER_COMPONENT}_RECOMMENDS_${DISTRIBUTION_NAME_UPPER}_${RELEASE_UPPER} )
|
||||
|
||||
set(SUGGESTS)
|
||||
if( CPACK_COMPONENT_${UPPER_COMPONENT}_SUGGESTS_${DISTRIBUTION_NAME_UPPER}_${RELEASE_UPPER} )
|
||||
foreach(DEP ${CPACK_COMPONENT_${UPPER_COMPONENT}_SUGGESTS_${DISTRIBUTION_NAME_UPPER}_${RELEASE_UPPER}})
|
||||
set(SUGGESTS "${SUGGESTS} ${DEP}, ")
|
||||
endforeach(DEP ${CPACK_COMPONENT_${UPPER_COMPONENT}_SUGGESTS_${DISTRIBUTION_NAME_UPPER}_${RELEASE_UPPER}})
|
||||
else( CPACK_COMPONENT_${UPPER_COMPONENT}_SUGGESTS_${DISTRIBUTION_NAME_UPPER}_${RELEASE_UPPER} )
|
||||
if( CPACK_COMPONENT_${UPPER_COMPONENT}_SUGGESTS_${DISTRIBUTION_NAME_UPPER} )
|
||||
foreach(DEP ${CPACK_COMPONENT_${UPPER_COMPONENT}_SUGGESTS_${DISTRIBUTION_NAME_UPPER}})
|
||||
set(SUGGESTS "${SUGGESTS} ${DEP}, ")
|
||||
endforeach(DEP ${CPACK_COMPONENT_${UPPER_COMPONENT}_SUGGESTS_${DISTRIBUTION_NAME_UPPER}})
|
||||
else( CPACK_COMPONENT_${UPPER_COMPONENT}_SUGGESTS_${DISTRIBUTION_NAME_UPPER} )
|
||||
foreach(DEP ${CPACK_COMPONENT_${UPPER_COMPONENT}_SUGGESTS})
|
||||
set(SUGGESTS "${SUGGESTS} ${DEP}, ")
|
||||
endforeach(DEP ${CPACK_COMPONENT_${UPPER_COMPONENT}_SUGGESTS})
|
||||
endif( CPACK_COMPONENT_${UPPER_COMPONENT}_SUGGESTS_${DISTRIBUTION_NAME_UPPER} )
|
||||
endif( CPACK_COMPONENT_${UPPER_COMPONENT}_SUGGESTS_${DISTRIBUTION_NAME_UPPER}_${RELEASE_UPPER} )
|
||||
|
||||
file(APPEND ${DEBIAN_CONTROL} "\n"
|
||||
"Package: ${CPACK_DEBIAN_PACKAGE_NAME}-${COMPONENT}\n"
|
||||
"Architecture: any\n"
|
||||
"Depends: ${DEPENDS}\n"
|
||||
"Recommends: ${RECOMMENDS}\n"
|
||||
"Suggests: ${SUGGESTS}\n"
|
||||
"Description: ${CPACK_PACKAGE_DISPLAY_NAME} ${CPACK_COMPONENT_${UPPER_COMPONENT}_DISPLAY_NAME}\n"
|
||||
"${DEB_LONG_DESCRIPTION}"
|
||||
" .\n"
|
||||
" ${CPACK_COMPONENT_${UPPER_COMPONENT}_DESCRIPTION}\n"
|
||||
)
|
||||
endforeach(COMPONENT ${CPACK_COMPONENTS_ALL})
|
||||
|
||||
##############################################################################
|
||||
# debian/copyright
|
||||
set(DEBIAN_COPYRIGHT ${DEBIAN_SOURCE_DIR}/debian/copyright)
|
||||
execute_process(COMMAND ${CMAKE_COMMAND} -E
|
||||
copy ${CPACK_RESOURCE_FILE_LICENSE} ${DEBIAN_COPYRIGHT}
|
||||
)
|
||||
|
||||
##############################################################################
|
||||
# debian/rules
|
||||
set(DEBIAN_RULES ${DEBIAN_SOURCE_DIR}/debian/rules)
|
||||
file(WRITE ${DEBIAN_RULES}
|
||||
"#!/usr/bin/make -f\n"
|
||||
"\n"
|
||||
"BUILDDIR = build_dir\n"
|
||||
"\n"
|
||||
"build:\n"
|
||||
" mkdir $(BUILDDIR)\n"
|
||||
" cd $(BUILDDIR); cmake -DCMAKE_BUILD_TYPE=Release ${CPACK_DEBIAN_CMAKE_OPTIONS} -DCMAKE_INSTALL_PREFIX=/usr ..\n"
|
||||
" $(MAKE) -C $(BUILDDIR) preinstall\n"
|
||||
" touch build\n"
|
||||
"\n"
|
||||
"binary: binary-indep binary-arch\n"
|
||||
"\n"
|
||||
"binary-indep: build\n"
|
||||
"\n"
|
||||
"binary-arch: build\n"
|
||||
" cd $(BUILDDIR); cmake -DCOMPONENT=Unspecified -DCMAKE_INSTALL_PREFIX=../debian/tmp/usr -P cmake_install.cmake\n"
|
||||
" mkdir -p debian/tmp/DEBIAN\n"
|
||||
" dpkg-gensymbols -p${CPACK_DEBIAN_PACKAGE_NAME}\n"
|
||||
)
|
||||
|
||||
foreach(COMPONENT ${CPACK_COMPONENTS_ALL})
|
||||
set(PATH debian/${COMPONENT})
|
||||
file(APPEND ${DEBIAN_RULES}
|
||||
" cd $(BUILDDIR); cmake -DCOMPONENT=${COMPONENT} -DCMAKE_INSTALL_PREFIX=../${PATH}/usr -P cmake_install.cmake\n"
|
||||
" mkdir -p ${PATH}/DEBIAN\n"
|
||||
" dpkg-gensymbols -p${CPACK_DEBIAN_PACKAGE_NAME}-${COMPONENT} -P${PATH}\n"
|
||||
)
|
||||
endforeach(COMPONENT ${CPACK_COMPONENTS_ALL})
|
||||
|
||||
file(APPEND ${DEBIAN_RULES}
|
||||
" dh_shlibdeps\n"
|
||||
" dh_strip\n" # for reducing size
|
||||
" dpkg-gencontrol -p${CPACK_DEBIAN_PACKAGE_NAME}\n"
|
||||
" dpkg --build debian/tmp ..\n"
|
||||
)
|
||||
|
||||
foreach(COMPONENT ${CPACK_COMPONENTS_ALL})
|
||||
set(PATH debian/${COMPONENT})
|
||||
file(APPEND ${DEBIAN_RULES}
|
||||
" dpkg-gencontrol -p${CPACK_DEBIAN_PACKAGE_NAME}-${COMPONENT} -P${PATH} -Tdebian/${COMPONENT}.substvars\n"
|
||||
" dpkg --build ${PATH} ..\n"
|
||||
)
|
||||
endforeach(COMPONENT ${CPACK_COMPONENTS_ALL})
|
||||
|
||||
file(APPEND ${DEBIAN_RULES}
|
||||
"\n"
|
||||
"clean:\n"
|
||||
" rm -f build\n"
|
||||
" rm -rf $(BUILDDIR)\n"
|
||||
"\n"
|
||||
".PHONY: binary binary-arch binary-indep clean\n"
|
||||
)
|
||||
|
||||
execute_process(COMMAND chmod +x ${DEBIAN_RULES})
|
||||
|
||||
##############################################################################
|
||||
# debian/compat
|
||||
file(WRITE ${DEBIAN_SOURCE_DIR}/debian/compat "7")
|
||||
|
||||
##############################################################################
|
||||
# debian/source/format
|
||||
file(WRITE ${DEBIAN_SOURCE_DIR}/debian/source/format "3.0 (quilt)")
|
||||
|
||||
##############################################################################
|
||||
# debian/changelog
|
||||
set(DEBIAN_CHANGELOG ${DEBIAN_SOURCE_DIR}/debian/changelog)
|
||||
execute_process(COMMAND date -R OUTPUT_VARIABLE DATE_TIME)
|
||||
file(WRITE ${DEBIAN_CHANGELOG}
|
||||
"${CPACK_DEBIAN_PACKAGE_NAME} (${RELEASE_PACKAGE_VERSION}) ${RELEASE}; urgency=medium\n\n"
|
||||
" * Package built with CMake\n\n"
|
||||
"${CPACK_DEBIAN_CHANGELOG}"
|
||||
" -- ${CPACK_PACKAGE_CONTACT} ${DATE_TIME}"
|
||||
)
|
||||
|
||||
##############################################################################
|
||||
# debuild -S
|
||||
if( DEB_SOURCE_CHANGES )
|
||||
set(DEBUILD_OPTIONS "-sd")
|
||||
else()
|
||||
set(DEBUILD_OPTIONS "-sa")
|
||||
endif()
|
||||
set(SOURCE_CHANGES_FILE "${CPACK_DEBIAN_PACKAGE_NAME}_${RELEASE_PACKAGE_VERSION}_source.changes")
|
||||
set(DEB_SOURCE_CHANGES ${DEB_SOURCE_CHANGES} "${SOURCE_CHANGES_FILE}")
|
||||
add_custom_command(OUTPUT "${SOURCE_CHANGES_FILE}" COMMAND ${DEBUILD_EXECUTABLE} -S ${DEBUILD_OPTIONS} WORKING_DIRECTORY ${DEBIAN_SOURCE_DIR})
|
||||
endforeach(RELEASE ${CPACK_DEBIAN_DISTRIBUTION_RELEASES})
|
||||
|
||||
##############################################################################
|
||||
# dput ppa:your-lp-id/ppa <source.changes>
|
||||
add_custom_target(dput ${DPUT_EXECUTABLE} ${DPUT_HOST} ${DEB_SOURCE_CHANGES} DEPENDS ${DEB_SOURCE_CHANGES} WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/Debian)
|
|
@ -252,13 +252,29 @@ macro(GettextTranslate)
|
|||
|
||||
else()
|
||||
|
||||
add_custom_target(${PO_TARGET}
|
||||
COMMAND ${GettextTranslate_MSGMERGE_EXECUTABLE} --lang=${lang}
|
||||
${PO_FILE_NAME} ${TEMPLATE_FILE_ABS}
|
||||
-o ${PO_FILE_NAME}.new
|
||||
COMMAND mv ${PO_FILE_NAME}.new ${PO_FILE_NAME}
|
||||
DEPENDS ${TEMPLATE_FILE_ABS}
|
||||
execute_process(
|
||||
COMMAND ${GettextTranslate_MSGMERGE_EXECUTABLE} --version
|
||||
OUTPUT_VARIABLE MSGMERGE_VERSION_MSG
|
||||
)
|
||||
string(REGEX MATCH "[0-9]+\\.[0-9]+(\\.[0-9]+)?" MSGMERGE_VERSION "${MSGMERGE_VERSION_MSG}")
|
||||
|
||||
if ("${MSGMERGE_VERSION}" VERSION_GREATER "0.17")
|
||||
add_custom_target(${PO_TARGET}
|
||||
COMMAND ${GettextTranslate_MSGMERGE_EXECUTABLE} --lang=${lang}
|
||||
${PO_FILE_NAME} ${TEMPLATE_FILE_ABS}
|
||||
-o ${PO_FILE_NAME}.new
|
||||
COMMAND mv ${PO_FILE_NAME}.new ${PO_FILE_NAME}
|
||||
DEPENDS ${TEMPLATE_FILE_ABS}
|
||||
)
|
||||
else ()
|
||||
add_custom_target(${PO_TARGET}
|
||||
COMMAND ${GettextTranslate_MSGMERGE_EXECUTABLE}
|
||||
${PO_FILE_NAME} ${TEMPLATE_FILE_ABS}
|
||||
-o ${PO_FILE_NAME}.new
|
||||
COMMAND mv ${PO_FILE_NAME}.new ${PO_FILE_NAME}
|
||||
DEPENDS ${TEMPLATE_FILE_ABS}
|
||||
)
|
||||
endif ()
|
||||
|
||||
endif()
|
||||
|
||||
|
@ -271,7 +287,7 @@ macro(GettextTranslate)
|
|||
add_dependencies(${PO_TARGET} ${MAKEVAR_DOMAIN}.pot-update)
|
||||
|
||||
install(FILES ${GMO_FILE_NAME} DESTINATION
|
||||
${LOCALEDIR}/${lang}/LC_MESSAGES
|
||||
${LOCALEDIR_REL}/${lang}/LC_MESSAGES
|
||||
RENAME ${MAKEVAR_DOMAIN}.mo
|
||||
)
|
||||
|
||||
|
|
79
.cmake/Modules/PackageConfig.cmake
Normal file
79
.cmake/Modules/PackageConfig.cmake
Normal file
|
@ -0,0 +1,79 @@
|
|||
|
||||
function(extract_version version major minor patch extra)
|
||||
string(REGEX MATCH "([0-9]+)\\.([0-9]+)\\.([0-9]+)(.*)?" version_valid ${version})
|
||||
if(version_valid)
|
||||
string(REGEX REPLACE "([0-9]+)\\.([0-9]+)\\.([0-9]+)(.*)?" "\\1;\\2;\\3;\\4" VERSION_MATCHES ${version})
|
||||
list(GET VERSION_MATCHES 0 version_major)
|
||||
set(${major} ${version_major} PARENT_SCOPE)
|
||||
list(GET VERSION_MATCHES 1 version_minor)
|
||||
set(${minor} ${version_minor} PARENT_SCOPE)
|
||||
list(GET VERSION_MATCHES 2 version_patch)
|
||||
set(${patch} ${version_patch} PARENT_SCOPE)
|
||||
list(GET VERSION_MATCHES 3 version_extra)
|
||||
set(${extra} ${version_extra} PARENT_SCOPE)
|
||||
else(version_valid)
|
||||
message(AUTHOR_WARNING "Bad version ${version}; falling back to 0 (have you made an initial release?)")
|
||||
set(${major} "0" PARENT_SCOPE)
|
||||
set(${minor} "" PARENT_SCOPE)
|
||||
set(${patch} "" PARENT_SCOPE)
|
||||
set(${extra} "" PARENT_SCOPE)
|
||||
endif(version_valid)
|
||||
endfunction(extract_version)
|
||||
|
||||
if (WIN32)
|
||||
set(CPACK_GENERATOR "ZIP")
|
||||
set(CPACK_SOURCE_GENERATOR "ZIP")
|
||||
else ()
|
||||
set(CPACK_GENERATOR "TGZ")
|
||||
set(CPACK_SOURCE_GENERATOR "TGZ")
|
||||
endif ()
|
||||
|
||||
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "A KISS, modern unit testing framework for C and C++.")
|
||||
set(CPACK_PACKAGE_FILE_NAME "${CMAKE_PROJECT_NAME}-binary-${PROJECT_VERSION}")
|
||||
set(CPACK_SOURCE_PACKAGE_FILE_NAME "${CMAKE_PROJECT_NAME}-${PROJECT_VERSION}")
|
||||
set(CPACK_PACKAGE_INSTALL_DIRECTORY "${CMAKE_PROJECT_NAME}-${PROJECT_VERSION}")
|
||||
set(CPACK_PACKAGE_VENDOR "Franklin \"Snaipe\" Mathieu")
|
||||
set(CPACK_PACKAGE_CONTACT "Franklin \"Snaipe\" Mathieu <franklinmathieu@gmail.com>")
|
||||
set(CPACK_PACKAGE_VERSION "${PROJECT_VERSION}")
|
||||
|
||||
if (WIN32)
|
||||
# add snapshot specific versioning information
|
||||
if (CPACK_DEBIAN_PACKAGE_TYPE STREQUAL "snapshot")
|
||||
execute_process(COMMAND date +%Y%m%d%0k%0M%0S%z OUTPUT_VARIABLE SNAPSHOT_DATE_TIME)
|
||||
set(CPACK_PACKAGE_VERSION "${PROJECT_VERSION}-snapshot-${SNAPSHOT_DATE_TIME}")
|
||||
STRING(REPLACE "\n" "" CPACK_PACKAGE_VERSION ${CPACK_PACKAGE_VERSION})
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_SOURCE_DIR}/debian.copyright")
|
||||
extract_version(${PROJECT_VERSION}
|
||||
CPACK_PACKAGE_VERSION_MAJOR
|
||||
CPACK_PACKAGE_VERSION_MINOR
|
||||
CPACK_PACKAGE_VERSION_PATCH
|
||||
VERSION_EXTRA
|
||||
)
|
||||
|
||||
set(CPACK_PACKAGE_VERSION ${PROJECT_VERSION})
|
||||
|
||||
file(GLOB TRASH_FILES "${CMAKE_SOURCE_DIR}/*")
|
||||
set(KEEP_FILES
|
||||
"${CMAKE_SOURCE_DIR}/.cmake"
|
||||
"${CMAKE_SOURCE_DIR}/src"
|
||||
"${CMAKE_SOURCE_DIR}/include"
|
||||
"${CMAKE_SOURCE_DIR}/doc"
|
||||
"${CMAKE_SOURCE_DIR}/dev"
|
||||
"${CMAKE_SOURCE_DIR}/po"
|
||||
"${CMAKE_SOURCE_DIR}/dependencies"
|
||||
"${CMAKE_SOURCE_DIR}/CMakeLists.txt"
|
||||
"${CMAKE_SOURCE_DIR}/README.md"
|
||||
"${CMAKE_SOURCE_DIR}/CONTRIBUTING.md"
|
||||
"${CMAKE_SOURCE_DIR}/LICENSE"
|
||||
"${CMAKE_SOURCE_DIR}/ChangeLog"
|
||||
"${CMAKE_SOURCE_DIR}/description.txt"
|
||||
)
|
||||
list(REMOVE_ITEM TRASH_FILES ${KEEP_FILES})
|
||||
# Escape any '.' characters
|
||||
string(REPLACE "." "\\\\." TRASH_FILES "${TRASH_FILES}")
|
||||
set(CPACK_SOURCE_IGNORE_FILES "${TRASH_FILES}")
|
||||
|
||||
include(CPack)
|
11
.cmake/copy-source.sh
Executable file
11
.cmake/copy-source.sh
Executable file
|
@ -0,0 +1,11 @@
|
|||
#!/bin/sh
|
||||
|
||||
CURDIR=$(dirname $0)
|
||||
SOURCE_DIR=$1; shift
|
||||
DEST_DIR=$1; shift
|
||||
|
||||
(
|
||||
cd "$SOURCE_DIR"
|
||||
mkdir -p "$DEST_DIR"
|
||||
"$CURDIR/git-archive-all.sh" --format tar -- - | tar -x -C "$DEST_DIR"
|
||||
)
|
302
.cmake/git-archive-all.sh
Executable file
302
.cmake/git-archive-all.sh
Executable file
|
@ -0,0 +1,302 @@
|
|||
#!/bin/bash -
|
||||
#
|
||||
# File: git-archive-all.sh
|
||||
#
|
||||
# Description: A utility script that builds an archive file(s) of all
|
||||
# git repositories and submodules in the current path.
|
||||
# Useful for creating a single tarfile of a git super-
|
||||
# project that contains other submodules.
|
||||
#
|
||||
# Examples: Use git-archive-all.sh to create archive distributions
|
||||
# from git repositories. To use, simply do:
|
||||
#
|
||||
# cd $GIT_DIR; git-archive-all.sh
|
||||
#
|
||||
# where $GIT_DIR is the root of your git superproject.
|
||||
#
|
||||
# License: GPL3+
|
||||
#
|
||||
###############################################################################
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU 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 General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
# DEBUGGING
|
||||
set -e
|
||||
set -C # noclobber
|
||||
|
||||
# TRAP SIGNALS
|
||||
trap 'cleanup' QUIT EXIT
|
||||
|
||||
# For security reasons, explicitly set the internal field separator
|
||||
# to newline, space, tab
|
||||
OLD_IFS=$IFS
|
||||
IFS='
|
||||
'
|
||||
|
||||
function cleanup () {
|
||||
rm -f $TMPFILE
|
||||
rm -f $TOARCHIVE
|
||||
IFS="$OLD_IFS"
|
||||
}
|
||||
|
||||
function usage () {
|
||||
echo "Usage is as follows:"
|
||||
echo
|
||||
echo "$PROGRAM <--version>"
|
||||
echo " Prints the program version number on a line by itself and exits."
|
||||
echo
|
||||
echo "$PROGRAM <--usage|--help|-?>"
|
||||
echo " Prints this usage output and exits."
|
||||
echo
|
||||
echo "$PROGRAM [--format <fmt>] [--prefix <path>] [--verbose|-v] [--separate|-s]"
|
||||
echo " [--tree-ish|-t <tree-ish>] [output_file]"
|
||||
echo " Creates an archive for the entire git superproject, and its submodules"
|
||||
echo " using the passed parameters, described below."
|
||||
echo
|
||||
echo " If '--format' is specified, the archive is created with the named"
|
||||
echo " git archiver backend. Obviously, this must be a backend that git archive"
|
||||
echo " understands. The format defaults to 'tar' if not specified."
|
||||
echo
|
||||
echo " If '--prefix' is specified, the archive's superproject and all submodules"
|
||||
echo " are created with the <path> prefix named. The default is to not use one."
|
||||
echo
|
||||
echo " If '--separate' or '-s' is specified, individual archives will be created"
|
||||
echo " for each of the superproject itself and its submodules. The default is to"
|
||||
echo " concatenate individual archives into one larger archive."
|
||||
echo
|
||||
echo " If '--tree-ish' is specified, the archive will be created based on whatever"
|
||||
echo " you define the tree-ish to be. Branch names, commit hash, etc. are acceptable."
|
||||
echo " Defaults to HEAD if not specified. See git archive's documentation for more"
|
||||
echo " information on what a tree-ish is."
|
||||
echo
|
||||
echo " If 'output_file' is specified, the resulting archive is created as the"
|
||||
echo " file named. This parameter is essentially a path that must be writeable."
|
||||
echo " When combined with '--separate' ('-s') this path must refer to a directory."
|
||||
echo " Without this parameter or when combined with '--separate' the resulting"
|
||||
echo " archive(s) are named with a dot-separated path of the archived directory and"
|
||||
echo " a file extension equal to their format (e.g., 'superdir.submodule1dir.tar')."
|
||||
echo
|
||||
echo " The special value '-' (single dash) is treated as STDOUT and, when used, the"
|
||||
echo " --separate option is ignored. Use a double-dash to separate the outfile from"
|
||||
echo " the value of previous options. For example, to write a .zip file to STDOUT:"
|
||||
echo
|
||||
echo " ./$PROGRAM --format zip -- -"
|
||||
echo
|
||||
echo " If '--verbose' or '-v' is specified, progress will be printed."
|
||||
}
|
||||
|
||||
function version () {
|
||||
echo "$PROGRAM version $VERSION"
|
||||
}
|
||||
|
||||
# Internal variables and initializations.
|
||||
readonly PROGRAM=`basename "$0"`
|
||||
readonly VERSION=0.3
|
||||
|
||||
SEPARATE=0
|
||||
VERBOSE=0
|
||||
|
||||
TARCMD=`command -v gnutar || command -v tar`
|
||||
FORMAT=tar
|
||||
PREFIX=
|
||||
TREEISH=HEAD
|
||||
|
||||
# RETURN VALUES/EXIT STATUS CODES
|
||||
readonly E_BAD_OPTION=254
|
||||
readonly E_UNKNOWN=255
|
||||
|
||||
# Process command-line arguments.
|
||||
while test $# -gt 0; do
|
||||
if [ x"$1" == x"--" ]; then
|
||||
# detect argument termination
|
||||
shift
|
||||
break
|
||||
fi
|
||||
case $1 in
|
||||
--format )
|
||||
shift
|
||||
FORMAT="$1"
|
||||
shift
|
||||
;;
|
||||
|
||||
--prefix )
|
||||
shift
|
||||
PREFIX="$1"
|
||||
shift
|
||||
;;
|
||||
|
||||
--separate | -s )
|
||||
shift
|
||||
SEPARATE=1
|
||||
;;
|
||||
|
||||
--tree-ish | -t )
|
||||
shift
|
||||
TREEISH="$1"
|
||||
shift
|
||||
;;
|
||||
|
||||
--version )
|
||||
version
|
||||
exit
|
||||
;;
|
||||
|
||||
--verbose | -v )
|
||||
shift
|
||||
VERBOSE=1
|
||||
;;
|
||||
|
||||
-? | --usage | --help )
|
||||
usage
|
||||
exit
|
||||
;;
|
||||
|
||||
-* )
|
||||
echo "Unrecognized option: $1" >&2
|
||||
usage
|
||||
exit $E_BAD_OPTION
|
||||
;;
|
||||
|
||||
* )
|
||||
break
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
OLD_PWD="`pwd`"
|
||||
TMPDIR=${TMPDIR:-/tmp}
|
||||
TMPFILE=`mktemp "$TMPDIR/$PROGRAM.XXXXXX"` # Create a place to store our work's progress
|
||||
TOARCHIVE=`mktemp "$TMPDIR/$PROGRAM.toarchive.XXXXXX"`
|
||||
OUT_FILE=$OLD_PWD # assume "this directory" without a name change by default
|
||||
|
||||
if [ ! -z "$1" ]; then
|
||||
OUT_FILE="$1"
|
||||
if [ "-" == $OUT_FILE ]; then
|
||||
SEPARATE=0
|
||||
fi
|
||||
shift
|
||||
fi
|
||||
|
||||
# Validate parameters; error early, error often.
|
||||
if [ "-" == $OUT_FILE -o $SEPARATE -ne 1 ] && [ "$FORMAT" == "tar" -a `$TARCMD --help | grep -q -- "--concatenate"; echo $?` -ne 0 ]; then
|
||||
echo "Your 'tar' does not support the '--concatenate' option, which we need"
|
||||
echo "to produce a single tarfile. Either install a compatible tar (such as"
|
||||
echo "gnutar), or invoke $PROGRAM with the '--separate' option."
|
||||
exit
|
||||
elif [ $SEPARATE -eq 1 -a ! -d $OUT_FILE ]; then
|
||||
echo "When creating multiple archives, your destination must be a directory."
|
||||
echo "If it's not, you risk being surprised when your files are overwritten."
|
||||
exit
|
||||
elif [ `git config -l | grep -q '^core\.bare=false'; echo $?` -ne 0 ]; then
|
||||
echo "$PROGRAM must be run from a git working copy (i.e., not a bare repository)."
|
||||
exit
|
||||
fi
|
||||
|
||||
# Create the superproject's git-archive
|
||||
if [ $VERBOSE -eq 1 ]; then
|
||||
echo -n "creating superproject archive..."
|
||||
fi
|
||||
git archive --format=$FORMAT --prefix="$PREFIX" $TREEISH > $TMPDIR/$(basename "$(pwd)").$FORMAT
|
||||
if [ $VERBOSE -eq 1 ]; then
|
||||
echo "done"
|
||||
fi
|
||||
echo $TMPDIR/$(basename "$(pwd)").$FORMAT >| $TMPFILE # clobber on purpose
|
||||
superfile=`head -n 1 $TMPFILE`
|
||||
|
||||
if [ $VERBOSE -eq 1 ]; then
|
||||
echo -n "looking for subprojects..."
|
||||
fi
|
||||
# find all '.git' dirs, these show us the remaining to-be-archived dirs
|
||||
# we only want directories that are below the current directory
|
||||
find . -mindepth 2 -name '.git' -type d -print | sed -e 's/^\.\///' -e 's/\.git$//' >> $TOARCHIVE
|
||||
# as of version 1.7.8, git places the submodule .git directories under the superprojects .git dir
|
||||
# the submodules get a .git file that points to their .git dir. we need to find all of these too
|
||||
find . -mindepth 2 -name '.git' -type f -print | xargs grep -l "gitdir" | sed -e 's/^\.\///' -e 's/\.git$//' >> $TOARCHIVE
|
||||
if [ $VERBOSE -eq 1 ]; then
|
||||
echo "done"
|
||||
echo " found:"
|
||||
cat $TOARCHIVE | while read arch
|
||||
do
|
||||
echo " $arch"
|
||||
done
|
||||
fi
|
||||
|
||||
if [ $VERBOSE -eq 1 ]; then
|
||||
echo -n "archiving submodules..."
|
||||
fi
|
||||
while read path; do
|
||||
TREEISH=$(git submodule | grep "^ .*${path%/} " | cut -d ' ' -f 2) # git submodule does not list trailing slashes in $path
|
||||
cd "$path"
|
||||
git archive --format=$FORMAT --prefix="${PREFIX}$path" ${TREEISH:-HEAD} > "$TMPDIR"/"$(echo "$path" | sed -e 's/\//./g')"$FORMAT
|
||||
if [ $FORMAT == 'zip' ]; then
|
||||
# delete the empty directory entry; zipped submodules won't unzip if we don't do this
|
||||
zip -d "$(tail -n 1 $TMPFILE)" "${PREFIX}${path%/}" >/dev/null # remove trailing '/'
|
||||
fi
|
||||
echo "$TMPDIR"/"$(echo "$path" | sed -e 's/\//./g')"$FORMAT >> $TMPFILE
|
||||
cd "$OLD_PWD"
|
||||
done < $TOARCHIVE
|
||||
if [ $VERBOSE -eq 1 ]; then
|
||||
echo "done"
|
||||
fi
|
||||
|
||||
if [ $VERBOSE -eq 1 ]; then
|
||||
echo -n "concatenating archives into single archive..."
|
||||
fi
|
||||
# Concatenate archives into a super-archive.
|
||||
if [ $SEPARATE -eq 0 -o "-" == $OUT_FILE ]; then
|
||||
if [ $FORMAT == 'tar.gz' ]; then
|
||||
gunzip $superfile
|
||||
superfile=${superfile:0: -3} # Remove '.gz'
|
||||
sed -e '1d' $TMPFILE | while read file; do
|
||||
gunzip $file
|
||||
file=${file:0: -3}
|
||||
$TARCMD --concatenate -f "$superfile" "$file" && rm -f "$file"
|
||||
done
|
||||
gzip $superfile
|
||||
superfile=$superfile.gz
|
||||
elif [ $FORMAT == 'tar' ]; then
|
||||
sed -e '1d' $TMPFILE | while read file; do
|
||||
$TARCMD --concatenate -f "$superfile" "$file" && rm -f "$file"
|
||||
done
|
||||
elif [ $FORMAT == 'zip' ]; then
|
||||
sed -e '1d' $TMPFILE | while read file; do
|
||||
# zip incorrectly stores the full path, so cd and then grow
|
||||
cd `dirname "$file"`
|
||||
zip -g "$superfile" `basename "$file"` && rm -f "$file"
|
||||
done
|
||||
cd "$OLD_PWD"
|
||||
fi
|
||||
|
||||
echo "$superfile" >| $TMPFILE # clobber on purpose
|
||||
fi
|
||||
if [ $VERBOSE -eq 1 ]; then
|
||||
echo "done"
|
||||
fi
|
||||
|
||||
if [ $VERBOSE -eq 1 ]; then
|
||||
echo -n "moving archive to $OUT_FILE..."
|
||||
fi
|
||||
while read file; do
|
||||
if [ "-" == $OUT_FILE ]; then
|
||||
cat "$file" && rm -f "$file"
|
||||
else
|
||||
mv "$file" "$OUT_FILE"
|
||||
fi
|
||||
done < $TMPFILE
|
||||
if [ $VERBOSE -eq 1 ]; then
|
||||
echo "done"
|
||||
fi
|
5
.gitignore
vendored
5
.gitignore
vendored
|
@ -10,13 +10,16 @@
|
|||
!doc/*
|
||||
|
||||
!*.c
|
||||
!*.m
|
||||
!*.cc
|
||||
!*.h
|
||||
!*.hxx
|
||||
!*.rst
|
||||
!*.po
|
||||
!*.in
|
||||
!.cmake/Modules/*.cmake
|
||||
!samples/tests/*.sh
|
||||
!samples/*.expected
|
||||
!samples/**/*.expected
|
||||
|
||||
!LICENSE
|
||||
!HEADER
|
||||
|
|
3
.gitmodules
vendored
3
.gitmodules
vendored
|
@ -7,3 +7,6 @@
|
|||
[submodule "dependencies/wingetopt"]
|
||||
path = dependencies/wingetopt
|
||||
url = https://github.com/alex85k/wingetopt.git
|
||||
[submodule "dependencies/klib"]
|
||||
path = dependencies/klib
|
||||
url = https://github.com/attractivechaos/klib.git
|
||||
|
|
143
.travis.yml
143
.travis.yml
|
@ -1,49 +1,130 @@
|
|||
language: c
|
||||
os:
|
||||
- linux
|
||||
- osx
|
||||
|
||||
compiler:
|
||||
- gcc-4.9
|
||||
|
||||
sudo: false
|
||||
|
||||
addons:
|
||||
apt:
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
packages:
|
||||
- gcc-4.9
|
||||
- g++-4.9
|
||||
env:
|
||||
global:
|
||||
GCOV: gcov-4.9
|
||||
CXX: g++-4.9
|
||||
matrix:
|
||||
- CONFIGURATION=Debug COVERAGE=ON
|
||||
- CONFIGURATION=Release COVERAGE=OFF
|
||||
- CONFIGURATION=RelWithDebInfo COVERAGE=OFF
|
||||
_anchors:
|
||||
- &gcc49-packages
|
||||
apt:
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
packages:
|
||||
- gcc-4.9
|
||||
- g++-4.9
|
||||
- gobjc-4.9
|
||||
- gnustep-devel
|
||||
|
||||
matrix:
|
||||
include:
|
||||
# Linux Debug, GCC 4.9
|
||||
- compiler: gcc-4.9
|
||||
addons: *gcc49-packages
|
||||
env:
|
||||
CONFIGURATION: Debug
|
||||
GCOV: gcov-4.9
|
||||
CMAKE_OPTS: -DLANG_OBJC=ON
|
||||
COVERAGE: "ON"
|
||||
# Linux Release, GCC 4.9
|
||||
- compiler: gcc-4.9
|
||||
addons: *gcc49-packages
|
||||
env:
|
||||
CONFIGURATION: Release
|
||||
CMAKE_OPTS: -DLANG_OBJC=ON
|
||||
# Linux RelWithDebInfo, GCC 4.9
|
||||
- compiler: gcc-4.9
|
||||
addons: *gcc49-packages
|
||||
env:
|
||||
CONFIGURATION: RelWithDebInfo
|
||||
CMAKE_OPTS: -DLANG_OBJC=ON
|
||||
DEPLOY: true
|
||||
# Linux Debug, GCC 4.6
|
||||
- compiler: gcc
|
||||
env: CONFIGURATION=Debug TESTS=OFF
|
||||
# Linux Release, GCC 4.6
|
||||
- compiler: gcc
|
||||
env: CONFIGURATION=Release TESTS=OFF
|
||||
# Linux RelWithDebInfo, GCC 4.6
|
||||
- compiler: gcc
|
||||
env: CONFIGURATION=RelWithDebInfo TESTS=OFF
|
||||
# OSX Debug, GCC 4.9
|
||||
- os: osx
|
||||
compiler: gcc-4.9
|
||||
env:
|
||||
CONFIGURATION: Debug
|
||||
GCOV: gcov-4.9
|
||||
COVERAGE: "ON"
|
||||
# OSX Release, GCC 4.9
|
||||
- os: osx
|
||||
compiler: gcc-4.9
|
||||
env: CONFIGURATION=Release
|
||||
# OSX RelWithDebInfo, GCC 4.9
|
||||
- os: osx
|
||||
compiler: gcc-4.9
|
||||
env: CONFIGURATION=RelWithDebInfo
|
||||
# OSX Debug, Clang
|
||||
- os: osx
|
||||
compiler: clang
|
||||
env:
|
||||
CONFIGURATION: Debug
|
||||
CMAKE_OPTS: -DLANG_OBJC=ON
|
||||
# OSX Release, Clang
|
||||
- os: osx
|
||||
compiler: clang
|
||||
env:
|
||||
CONFIGURATION: Release
|
||||
CMAKE_OPTS: -DLANG_OBJC=ON
|
||||
# OSX RelWithDebInfo, Clang
|
||||
- os: osx
|
||||
compiler: clang
|
||||
env:
|
||||
CONFIGURATION: RelWithDebInfo
|
||||
CMAKE_OPTS: -DLANG_OBJC=ON
|
||||
DEPLOY: true
|
||||
|
||||
allow_failures:
|
||||
- compiler: gcc
|
||||
|
||||
before_install:
|
||||
- |
|
||||
if [ "$TRAVIS_OS_NAME" = "osx" ] && [ "$CC" = "clang" ]; then
|
||||
brew update
|
||||
brew unlink cmake
|
||||
brew install llvm cmake
|
||||
fi
|
||||
- export CXX=${CC/gcc/g++}; export CXX=${CXX/clang/clang++}
|
||||
- $CC --version
|
||||
- $CXX --version
|
||||
|
||||
script:
|
||||
- mkdir -p build
|
||||
- cd build
|
||||
- mkdir -p build && cd $_
|
||||
- >
|
||||
cmake
|
||||
-Wno-dev
|
||||
-DCOVERALLS=${COVERAGE}
|
||||
-DCTESTS=${TESTS:-ON}
|
||||
-DCOVERALLS=${COVERAGE:-OFF}
|
||||
-DCMAKE_BUILD_TYPE=${CONFIGURATION}
|
||||
-DCMAKE_INSTALL_PREFIX=criterion-${TRAVIS_TAG}
|
||||
${CMAKE_OPTS}
|
||||
..
|
||||
- make
|
||||
- make criterion_tests
|
||||
- make test
|
||||
- |
|
||||
if [ "${TESTS:-ON}" = "ON" ]; then
|
||||
TERM=dumb cmake --build . --target criterion_tests -- -j4
|
||||
ctest -j4
|
||||
else
|
||||
TERM=dumb cmake --build . -- -j4
|
||||
fi
|
||||
|
||||
after_success:
|
||||
- make gcov
|
||||
- bash <(curl -s https://codecov.io/bash)
|
||||
- |
|
||||
if [ "$COVERAGE" = "ON" ]; then
|
||||
make gcov
|
||||
bash <(curl -s https://codecov.io/bash)
|
||||
fi
|
||||
|
||||
after_failure:
|
||||
- cat Testing/Temporary/LastTest.log samples/*.{out,err} ../samples/tests/*.{out,err}
|
||||
- |
|
||||
if [ "$TESTS" = "ON" ]; then
|
||||
cat Testing/Temporary/LastTest.log samples/*.{out,err} ../samples/tests/*.{out,err}
|
||||
fi
|
||||
|
||||
before_deploy:
|
||||
- make install
|
||||
|
@ -58,4 +139,4 @@ deploy:
|
|||
on:
|
||||
repo: Snaipe/Criterion
|
||||
tags: true
|
||||
condition: $CONFIGURATION = RelWithDebInfo
|
||||
condition: $DEPLOY = true
|
||||
|
|
163
CMakeLists.txt
163
CMakeLists.txt
|
@ -1,25 +1,41 @@
|
|||
cmake_minimum_required(VERSION 2.8)
|
||||
|
||||
project(Criterion C CXX)
|
||||
project(Criterion C)
|
||||
|
||||
set(MODULE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/.cmake/Modules")
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${MODULE_DIR})
|
||||
set(LIBCSPTR_DISABLE_TESTS ON)
|
||||
set(LIBCSPTR_DISABLE_COVERALLS ON)
|
||||
|
||||
# Content options
|
||||
|
||||
option(THEORIES "Activate the support for theories" ON)
|
||||
|
||||
# Initialization
|
||||
|
||||
include(Submodules)
|
||||
include(Capabilities)
|
||||
|
||||
if (MSVC)
|
||||
add_definitions(-D_CRT_SECURE_NO_WARNINGS=1)
|
||||
endif ()
|
||||
|
||||
add_subdirectory(dependencies/libcsptr/ EXCLUDE_FROM_ALL)
|
||||
add_subdirectory(dependencies/dyncall/ EXCLUDE_FROM_ALL)
|
||||
|
||||
if (THEORIES)
|
||||
add_subdirectory(dependencies/dyncall/ EXCLUDE_FROM_ALL)
|
||||
include_directories(dependencies/dyncall/dyncall/)
|
||||
endif ()
|
||||
|
||||
include_directories(SYSTEM
|
||||
/usr/local/include
|
||||
/usr/include/GNUstep
|
||||
)
|
||||
|
||||
include_directories(
|
||||
/usr/local/include/
|
||||
dependencies/libcsptr/include/
|
||||
dependencies/dyncall/dyncall/
|
||||
dependencies/valgrind/include/
|
||||
dependencies/klib/
|
||||
)
|
||||
|
||||
if (MSVC)
|
||||
|
@ -27,17 +43,45 @@ if (MSVC)
|
|||
include_directories(dependencies/wingetopt/src/)
|
||||
endif ()
|
||||
|
||||
# Check for C++11
|
||||
|
||||
option(LANG_CXX "Turn on C++ support" ON)
|
||||
if (LANG_CXX)
|
||||
enable_language(CXX)
|
||||
endif ()
|
||||
|
||||
if (NOT MSVC AND CMAKE_CXX_COMPILER_WORKS)
|
||||
include(CheckCXXCompilerFlag)
|
||||
CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11)
|
||||
CHECK_CXX_COMPILER_FLAG("-std=c++0x" COMPILER_SUPPORTS_CXX0X)
|
||||
|
||||
if(COMPILER_SUPPORTS_CXX11)
|
||||
set(CXX11_FLAG "-std=c++11")
|
||||
elseif(COMPILER_SUPPORTS_CXX0X)
|
||||
set(CXX11_FLAG "-std=c++0x")
|
||||
else()
|
||||
message(FATAL_ERROR "Compiler ${CMAKE_CXX_COMPILER} has no C++11 support.")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Project setup & environment variables
|
||||
|
||||
set(PROJECT_VERSION "2.1.0")
|
||||
set(LOCALEDIR ${CMAKE_INSTALL_PREFIX}/share/locale)
|
||||
set(PROJECT_VERSION "2.2.0")
|
||||
set(LOCALEDIR_REL "share/locale")
|
||||
set(LOCALEDIR "${CMAKE_INSTALL_PREFIX}/${LOCALEDIR_REL}")
|
||||
set(GettextTranslate_ALL 1)
|
||||
set(GettextTranslate_GMO_BINARY 1)
|
||||
|
||||
add_definitions(-DCRITERION_BUILDING_DLL=1)
|
||||
|
||||
set(CMAKE_C_FLAGS_DEFAULT "${CMAKE_C_FLAGS}")
|
||||
set(CMAKE_CXX_FLAGS_DEFAULT "${CMAKE_CXX_FLAGS}")
|
||||
|
||||
if (NOT MSVC)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Werror -g -std=gnu99")
|
||||
if (CMAKE_CXX_COMPILER_WORKS)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Werror -g ${CXX11_FLAG}")
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
if (MSVC)
|
||||
|
@ -48,10 +92,20 @@ if (WIN32 AND NOT MSVC)
|
|||
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-no-undefined")
|
||||
endif()
|
||||
|
||||
# Compilation options
|
||||
|
||||
option(MINGW_DEFINE_OFF_T "Define off_t and off64_t ourselves before including io.h" OFF)
|
||||
|
||||
# Setup coveralls
|
||||
|
||||
option(COVERALLS "Turn on coveralls support" OFF)
|
||||
option(COVERALLS_UPLOAD "Upload the generated coveralls json" ON)
|
||||
option(DEV_BUILD "Compile in developer mode" OFF)
|
||||
option(CTESTS "Turn on the samples and test" ${DEV_BUILD})
|
||||
|
||||
if (DEV_BUILD)
|
||||
set(ENABLE_VALGRIND_ERRORS 1)
|
||||
endif ()
|
||||
|
||||
if (COVERALLS)
|
||||
include(Coveralls)
|
||||
|
@ -60,12 +114,16 @@ endif()
|
|||
|
||||
# Find dependencies
|
||||
|
||||
find_package(Gettext)
|
||||
find_package(Libintl)
|
||||
if (GETTEXT_FOUND AND LIBINTL_LIB_FOUND)
|
||||
include(GettextTranslate)
|
||||
add_subdirectory(po)
|
||||
set(ENABLE_NLS 1)
|
||||
option(I18N "Turn on internationalization" ON)
|
||||
|
||||
if (I18N)
|
||||
find_package(Gettext)
|
||||
find_package(Libintl)
|
||||
if (GETTEXT_FOUND AND LIBINTL_LIB_FOUND)
|
||||
include(GettextTranslate)
|
||||
add_subdirectory(po)
|
||||
set(ENABLE_NLS 1)
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
include(CheckLibraryExists)
|
||||
|
@ -82,15 +140,19 @@ set(SOURCE_FILES
|
|||
src/core/report.h
|
||||
src/core/runner.c
|
||||
src/core/runner.h
|
||||
src/core/runner_coroutine.c
|
||||
src/core/runner_coroutine.h
|
||||
src/core/coroutine.h
|
||||
src/core/worker.c
|
||||
src/core/worker.h
|
||||
src/core/stats.c
|
||||
src/core/stats.h
|
||||
src/core/ordered-set.c
|
||||
src/core/theories.c
|
||||
src/core/test.c
|
||||
src/compat/internal.h
|
||||
src/compat/pipe.c
|
||||
src/compat/pipe.h
|
||||
src/compat/pipe-internal.h
|
||||
src/compat/section.c
|
||||
src/compat/section.h
|
||||
src/compat/process.c
|
||||
|
@ -103,21 +165,35 @@ set(SOURCE_FILES
|
|||
src/compat/posix.h
|
||||
src/compat/alloc.c
|
||||
src/compat/alloc.h
|
||||
src/compat/processor.c
|
||||
src/compat/processor.h
|
||||
src/io/redirect.c
|
||||
src/io/event.c
|
||||
src/io/event.h
|
||||
src/io/asprintf.c
|
||||
src/io/file.c
|
||||
src/io/output.c
|
||||
src/io/output.h
|
||||
src/io/tap.c
|
||||
src/io/xml.c
|
||||
src/io/json.c
|
||||
src/log/logging.c
|
||||
src/log/tap.c
|
||||
src/log/normal.c
|
||||
src/string/i18n.c
|
||||
src/string/i18n.h
|
||||
src/entry/options.c
|
||||
src/entry/main.c
|
||||
src/entry/params.c
|
||||
src/entry/entry.c
|
||||
src/common.h
|
||||
src/config.h
|
||||
)
|
||||
|
||||
if (THEORIES)
|
||||
set (SOURCE_FILES ${SOURCE_FILES}
|
||||
src/core/theories.c
|
||||
)
|
||||
endif ()
|
||||
|
||||
if (PCRE_FOUND)
|
||||
set (SOURCE_FILES ${SOURCE_FILES}
|
||||
src/string/extmatch.c
|
||||
|
@ -129,22 +205,39 @@ endif ()
|
|||
set(INTERFACE_FILES
|
||||
include/criterion/assert.h
|
||||
include/criterion/abort.h
|
||||
include/criterion/common.h
|
||||
include/criterion/criterion.h
|
||||
include/criterion/event.h
|
||||
include/criterion/hooks.h
|
||||
include/criterion/logging.h
|
||||
include/criterion/types.h
|
||||
include/criterion/options.h
|
||||
include/criterion/ordered-set.h
|
||||
include/criterion/stats.h
|
||||
include/criterion/theories.h
|
||||
include/criterion/asprintf-compat.h
|
||||
include/criterion/designated-initializer-compat.h
|
||||
include/criterion/preprocess.h
|
||||
include/criterion/alloc.h
|
||||
include/criterion/parameterized.h
|
||||
include/criterion/redirect.h
|
||||
include/criterion/output.h
|
||||
include/criterion/internal/assert.h
|
||||
include/criterion/internal/test.h
|
||||
include/criterion/internal/common.h
|
||||
include/criterion/internal/ordered-set.h
|
||||
include/criterion/internal/asprintf-compat.h
|
||||
include/criterion/internal/designated-initializer-compat.h
|
||||
include/criterion/internal/preprocess.h
|
||||
include/criterion/internal/parameterized.h
|
||||
include/criterion/internal/stdio_filebuf.hxx
|
||||
include/criterion/internal/stream.hxx
|
||||
include/criterion/internal/hooks.h
|
||||
include/criterion/internal/redirect.h
|
||||
include/criterion/internal/stdio_filebuf.hxx
|
||||
)
|
||||
|
||||
if (THEORIES)
|
||||
set(INTERFACE_FILES ${INTERFACE_FILES}
|
||||
include/criterion/theories.h
|
||||
include/criterion/internal/theories.h
|
||||
)
|
||||
endif()
|
||||
|
||||
# Generate the configure file
|
||||
|
||||
configure_file(
|
||||
|
@ -154,7 +247,11 @@ configure_file(
|
|||
|
||||
include_directories(include src)
|
||||
add_library(criterion SHARED ${SOURCE_FILES} ${INTERFACE_FILES})
|
||||
target_link_libraries(criterion csptr dyncall_s)
|
||||
target_link_libraries(criterion csptr)
|
||||
|
||||
if (THEORIES)
|
||||
target_link_libraries(criterion dyncall_s)
|
||||
endif ()
|
||||
|
||||
if (MSVC)
|
||||
target_link_libraries(criterion wingetopt)
|
||||
|
@ -170,17 +267,22 @@ endif()
|
|||
|
||||
if (LIBINTL_LIB_FOUND)
|
||||
target_link_libraries(criterion ${LIBINTL_LIBRARIES})
|
||||
include_directories(${LIBINTL_INCLUDE_DIR})
|
||||
endif()
|
||||
|
||||
if (COVERALLS)
|
||||
coveralls_setup("${SOURCE_FILES}" ${COVERALLS_UPLOAD})
|
||||
endif()
|
||||
|
||||
install(FILES ${INTERFACE_FILES} DESTINATION include/criterion)
|
||||
foreach (F ${INTERFACE_FILES})
|
||||
get_filename_component(DEST "${F}" PATH)
|
||||
install(FILES "${F}" DESTINATION "${DEST}" COMPONENT dev)
|
||||
endforeach ()
|
||||
|
||||
install(TARGETS criterion
|
||||
RUNTIME DESTINATION bin
|
||||
LIBRARY DESTINATION lib
|
||||
ARCHIVE DESTINATION lib
|
||||
ARCHIVE DESTINATION lib COMPONENT dev
|
||||
)
|
||||
|
||||
add_custom_target(criterion_tests)
|
||||
|
@ -192,6 +294,19 @@ add_custom_target(gcov
|
|||
-P "${CMAKE_MODULE_PATH}/Gcov.cmake"
|
||||
)
|
||||
|
||||
if (CTESTS)
|
||||
enable_testing()
|
||||
add_subdirectory(samples)
|
||||
add_subdirectory(test)
|
||||
endif ()
|
||||
|
||||
# Add toolchain patch number for incremental deb builds
|
||||
set(PROJECT_VERSION "${PROJECT_VERSION}-6")
|
||||
|
||||
include (PackageConfig)
|
||||
|
||||
option(UPLOAD_DEB "Upload package to launchpad" OFF)
|
||||
|
||||
if (UNIX AND UPLOAD_DEB)
|
||||
include (DebConfig)
|
||||
endif ()
|
||||
|
|
35
ChangeLog
35
ChangeLog
|
@ -1,3 +1,38 @@
|
|||
2015-12-08 Franklin "Snaipe" Mathieu <franklinmathieu@gmail.com>
|
||||
|
||||
* criterion: version 2.2.0
|
||||
* Breaking: Renamed all unprefixed internal macros and functions that were
|
||||
exposed in the API, and moved them to criterion/internal.
|
||||
This shouldn't break your code if you did not use these in the first
|
||||
place.
|
||||
* Change: Added language-specific wrapping logic to decouple the language
|
||||
the tests are written in from the test runner.
|
||||
* Change: Rewrote the reporting logic to allow multiple test reports to be
|
||||
written using any format.
|
||||
* Addition: Added parallel jobs for the test runner.
|
||||
* Addition: Added C++ allocator for STL collections based on
|
||||
cr_malloc/cr_free.
|
||||
* Addition: Added criterion::parameters in C++ for simpler parameter list
|
||||
generation.
|
||||
* Addition: Added saner defaults when the tests detect they run under
|
||||
valgrind.
|
||||
* Addition: Added basic Objective-C language support.
|
||||
* Addition: Added JUnit XML reporting.
|
||||
* Addition: Added JSON reporting.
|
||||
* Addition: Added dynamic reporter registration.
|
||||
* Addition: Added back support for GCC 4.6 when compiling C tests.
|
||||
* Addition: Added single test execution mode.
|
||||
* Removal: Removed all deprecated 1.x unprefixed assertion macros.
|
||||
* Fix: Fixed some memory corruption happening on rare occasions on assert
|
||||
messages.
|
||||
* Fix: Fixed deadlocks happening at random when a large quantity of assert
|
||||
is present.
|
||||
* Fix: Fixed the library not compiling with the intel compiler collection.
|
||||
* Deprecation: All cr_assume_strings_* macros are deprecated in favor of
|
||||
cr_assume_str_*.
|
||||
* Deprecation: All cr_assume_arrays_* macros are deprecated in favor of
|
||||
cr_assume_arr_*.
|
||||
|
||||
2015-11-25 Franklin "Snaipe" Mathieu <franklinmathieu@gmail.com>
|
||||
|
||||
* criterion: version 2.1.1
|
||||
|
|
39
README.md
39
README.md
|
@ -8,6 +8,8 @@
|
|||
[](https://github.com/Snaipe/Criterion/blob/master/LICENSE)
|
||||
[](https://github.com/Snaipe/Criterion/releases)
|
||||
|
||||

|
||||
|
||||
A dead-simple, yet extensible, C and C++ unit testing framework.
|
||||
|
||||

|
||||
|
@ -39,10 +41,19 @@ the user would have with other frameworks:
|
|||
|
||||
## Downloads
|
||||
|
||||
* [Linux (x86_64)](https://github.com/Snaipe/Criterion/releases/download/v2.1.0/criterion-v2.1.0-linux-x86_64.tar.bz2)
|
||||
* [OS X (x86_64)](https://github.com/Snaipe/Criterion/releases/download/v2.1.0/criterion-v2.1.0-osx-x86_64.tar.bz2)
|
||||
* [Windows (MSVC - x86_64)](https://github.com/Snaipe/Criterion/releases/download/v2.1.0/criterion-v2.1.0-windows-msvc-x86_64.tar.bz2)
|
||||
* [Windows (MinGW - x86_64)](https://github.com/Snaipe/Criterion/releases/download/v2.1.0/criterion-v2.1.0-windows-mingw-x86_64.tar.bz2)
|
||||
### Packages
|
||||
|
||||
* Mac OS X: `brew install snaipe/soft/criterion`
|
||||
* [AUR](https://aur.archlinux.org/packages/criterion/): `yaourt -S criterion`
|
||||
|
||||
### Binary archives
|
||||
|
||||
* [Linux (x86_64)](https://github.com/Snaipe/Criterion/releases/download/v2.2.0/criterion-v2.2.0-linux-x86_64.tar.bz2)
|
||||
* [OS X (x86_64)](https://github.com/Snaipe/Criterion/releases/download/v2.2.0/criterion-v2.2.0-osx-x86_64.tar.bz2)
|
||||
* [Windows (MSVC - x86_64)](https://github.com/Snaipe/Criterion/releases/download/v2.2.0/criterion-v2.2.0-windows-msvc-x86_64.tar.bz2)
|
||||
* [Windows (MinGW - x86_64)](https://github.com/Snaipe/Criterion/releases/download/v2.2.0/criterion-v2.2.0-windows-mingw-x86_64.tar.bz2)
|
||||
|
||||
[comment]: # (Don't forget to change x86_64 to x64 on windows links on the next release)
|
||||
|
||||
If you have a different platform, you can still [build the library from source](http://criterion.readthedocs.org/en/latest/setup.html#installation)
|
||||
|
||||
|
@ -66,27 +77,13 @@ Sample tests can be found in the [sample directory][samples].
|
|||
|
||||
### Getting help
|
||||
|
||||
Gitter.im chat room: [](https://gitter.im/Snaipe/Criterion?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
Gitter.im chat room: [](https://gitter.im/Snaipe/Criterion?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
IRC channel: [#criterion][irc-chan] on irc.freenode.net
|
||||
|
||||
### Misc
|
||||
|
||||
* [CMake find module for Criterion][find-module]
|
||||
|
||||
## F.A.Q.
|
||||
|
||||
**Q. What's wrong with other C test frameworks?**
|
||||
A. I worked with CUnit and Check, and I must say that they do their job
|
||||
very well -- the only thing that bugs me is that setting up a test
|
||||
suite from scratch is a pain, it should really be simpler. Most
|
||||
(if not all) high-level languages have test frameworks with automatic
|
||||
test registration, but all the ones for C require you to set up a
|
||||
main, manually register suites, then tests. Criterion tries to
|
||||
fix these shortcomings.
|
||||
|
||||
**Q. Where has this been tested?**
|
||||
A. Currently, on Linux 2.6.32 and Linux 3.15.7, although it should work on
|
||||
most \*nix systems; Mac OS X Yosemite 10.10, FreeBSD 10.0, Windows 7 and 2K.
|
||||
|
||||
## Credits
|
||||
|
||||
Logo done by [Greehm](http://www.cargocollective.com/pbouigue)
|
||||
|
@ -105,3 +102,5 @@ Logo done by [Greehm](http://www.cargocollective.com/pbouigue)
|
|||
[sample-report]: ./samples/report.c
|
||||
|
||||
[find-module]: ./dev/FindCriterion.cmake
|
||||
|
||||
[irc-chan]: http://webchat.freenode.net/?channels=%23criterion&uio=MTY9dHJ1ZSYyPXRydWUmOT10cnVlJjExPTE5NQ4e
|
||||
|
|
16
appveyor.yml
16
appveyor.yml
|
@ -1,4 +1,4 @@
|
|||
version: 2.1.0_b{build}-{branch}
|
||||
version: 2.2.0_b{build}-{branch}
|
||||
|
||||
os: Visual Studio 2015
|
||||
|
||||
|
@ -15,14 +15,17 @@ environment:
|
|||
matrix:
|
||||
- COMPILER: mingw
|
||||
GENERATOR: "MSYS Makefiles"
|
||||
CXXFLAGS: -D__NO_INLINE__
|
||||
- COMPILER: msvc
|
||||
GENERATOR: "Visual Studio 14 2015"
|
||||
CFLAGS: /MP
|
||||
CXXFLAGS: /MP
|
||||
|
||||
clone_depth: 5
|
||||
|
||||
platform:
|
||||
- x86
|
||||
- x86_64
|
||||
- x64
|
||||
|
||||
configuration:
|
||||
- Debug
|
||||
|
@ -38,8 +41,11 @@ install:
|
|||
- >
|
||||
cmake
|
||||
-Wno-dev
|
||||
-DCTESTS=ON
|
||||
-DI18N=OFF
|
||||
-DCMAKE_INSTALL_PREFIX="criterion-%RELEASE_NAME%"
|
||||
-DCMAKE_BUILD_TYPE="%CONFIGURATION%"
|
||||
%CMAKE_OPTS%
|
||||
-G "%GENERATOR%"
|
||||
..
|
||||
|
||||
|
@ -56,7 +62,11 @@ before_deploy:
|
|||
|
||||
test_script:
|
||||
- cmake --build . --target criterion_tests
|
||||
- ps: try { ctest } catch { type Testing/Temporary/LastTest.log }
|
||||
- ps: |
|
||||
ctest -j2
|
||||
if (-not $lastexitcode -eq 0) {
|
||||
type Testing/Temporary/LastTest.log
|
||||
}
|
||||
|
||||
#after_test:
|
||||
# - 'make coveralls'
|
||||
|
|
25
debian.copyright
Normal file
25
debian.copyright
Normal file
|
@ -0,0 +1,25 @@
|
|||
Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
|
||||
Upstream-Name: Criterion
|
||||
Upstream-Contact: Franklin "Snaipe" Mathieu <franklinmathieu@gmail.com>
|
||||
Source: http://github.com/Snaipe/Criterion
|
||||
|
||||
Files: *
|
||||
Copyright: 2015, Franklin "Snaipe" Mathieu <franklinmathieu@gmail.com>
|
||||
License: MIT
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
.
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
.
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
2
dependencies/dyncall
vendored
2
dependencies/dyncall
vendored
|
@ -1 +1 @@
|
|||
Subproject commit 68c57f664d4fabbc5b80327fbf5661a3a5a51e06
|
||||
Subproject commit 180a5b77ff95a17991afdc6e9be3501eca99ad36
|
1
dependencies/klib
vendored
Submodule
1
dependencies/klib
vendored
Submodule
|
@ -0,0 +1 @@
|
|||
Subproject commit cdb7e9236dc47abf8da7ebd702cc6f7f21f0c502
|
2
dependencies/libcsptr
vendored
2
dependencies/libcsptr
vendored
|
@ -1 +1 @@
|
|||
Subproject commit 2762164acfaa712fea7dec6ed760ff88f7d2e026
|
||||
Subproject commit 0d52904da5d7bd0a3eac3c47e9f9bb10cd78a26e
|
6588
dependencies/valgrind/include/valgrind/valgrind.h
vendored
Normal file
6588
dependencies/valgrind/include/valgrind/valgrind.h
vendored
Normal file
File diff suppressed because it is too large
Load diff
23
description.txt
Normal file
23
description.txt
Normal file
|
@ -0,0 +1,23 @@
|
|||
Criterion is a dead-simple, yet extensible, C and C++ unit testing framework.
|
||||
|
||||
Most test frameworks for C require a lot of boilerplate code to
|
||||
set up tests and test suites -- you need to create a main,
|
||||
then register new test suites, then register the tests within
|
||||
these suits, and finally call the right functions.
|
||||
|
||||
This gives the user great control, at the unfortunate cost of simplicity.
|
||||
|
||||
Criterion follows the KISS principle, while keeping the control
|
||||
the user would have with other frameworks:
|
||||
|
||||
* C99 and C++11 compatible.
|
||||
* Tests are automatically registered when declared.
|
||||
* Implements a xUnit framework structure.
|
||||
* A default entry point is provided, no need to declare a main
|
||||
unless you want to do special handling.
|
||||
* Test are isolated in their own process, crashes and signals can be
|
||||
reported and tested.
|
||||
* Unified interface between C and C++: include the criterion header and it *just* works.
|
||||
* Supports parameterized tests and theories.
|
||||
* Progress and statistics can be followed in real time with report hooks.
|
||||
* TAP output format can be enabled with an option.
|
217
doc/assert.rst
217
doc/assert.rst
|
@ -9,36 +9,39 @@ As each ``assert`` macros have an ``expect`` counterpart with the exact same
|
|||
number of parameters and name suffix, there is no benefit in adding ``expect``
|
||||
macros to this list. Hence only ``assert`` macros are represented here.
|
||||
|
||||
All ``assert`` macros may take an optional ``printf`` format string and
|
||||
parameters.
|
||||
|
||||
Common Assertions
|
||||
-----------------
|
||||
|
||||
======================================================================= =========================================================================== ===========================================
|
||||
Macro Passes if and only if Notes
|
||||
======================================================================= =========================================================================== ===========================================
|
||||
cr_assert(Condition, [Message, [Args...]]) ``Condition`` is true.
|
||||
----------------------------------------------------------------------- --------------------------------------------------------------------------- -------------------------------------------
|
||||
cr_assert_not(Condition, [Message, [Args...]]) ``Condition`` is false.
|
||||
----------------------------------------------------------------------- --------------------------------------------------------------------------- -------------------------------------------
|
||||
cr_assert_null(Value, [Message, [Args...]]) ``Value`` is ``NULL``.
|
||||
----------------------------------------------------------------------- --------------------------------------------------------------------------- -------------------------------------------
|
||||
cr_assert_not_null(Value, [Message, [Args...]]) ``Value`` is not ``NULL``.
|
||||
----------------------------------------------------------------------- --------------------------------------------------------------------------- -------------------------------------------
|
||||
cr_assert_eq(Actual, Expected, [Message, [Args...]]) ``Actual`` is equal to ``Expected``. Compatible with C++ operator overloading
|
||||
----------------------------------------------------------------------- --------------------------------------------------------------------------- -------------------------------------------
|
||||
cr_assert_neq(Actual, Unexpected, [Message, [Args...]]) ``Actual`` is not equal to ``Unexpected``. Compatible with C++ operator overloading
|
||||
----------------------------------------------------------------------- --------------------------------------------------------------------------- -------------------------------------------
|
||||
cr_assert_lt(Actual, Reference, [Message, [Args...]]) ``Actual`` is less than ``Reference``. Compatible with C++ operator overloading
|
||||
----------------------------------------------------------------------- --------------------------------------------------------------------------- -------------------------------------------
|
||||
cr_assert_leq(Actual, Reference, [Message, [Args...]]) ``Actual`` is less or equal to ``Reference``. Compatible with C++ operator overloading
|
||||
----------------------------------------------------------------------- --------------------------------------------------------------------------- -------------------------------------------
|
||||
cr_assert_gt(Actual, Reference, [Message, [Args...]]) ``Actual`` is greater than ``Reference``. Compatible with C++ operator overloading
|
||||
----------------------------------------------------------------------- --------------------------------------------------------------------------- -------------------------------------------
|
||||
cr_assert_geq(Actual, Reference, [Message, [Args...]]) ``Actual`` is greater or equal to ``Reference``. Compatible with C++ operator overloading
|
||||
----------------------------------------------------------------------- --------------------------------------------------------------------------- -------------------------------------------
|
||||
cr_assert_float_eq(Actual, Expected, Epsilon, [Message, [Args...]]) ``Actual`` is equal to ``Expected`` with a tolerance of ``Epsilon``. Use this to test equality between floats
|
||||
----------------------------------------------------------------------- --------------------------------------------------------------------------- -------------------------------------------
|
||||
cr_assert_float_neq(Actual, Unexpected, Epsilon, [Message, [Args...]]) ``Actual`` is not equal to ``Unexpected`` with a tolerance of ``Epsilon``. Use this to test inequality between floats
|
||||
======================================================================= =========================================================================== ===========================================
|
||||
=========================================================================== =========================================================================== ===========================================
|
||||
Macro Passes if and only if Notes
|
||||
=========================================================================== =========================================================================== ===========================================
|
||||
cr_assert(Condition, [FormatString, [Args...]]) ``Condition`` is true.
|
||||
--------------------------------------------------------------------------- --------------------------------------------------------------------------- -------------------------------------------
|
||||
cr_assert_not(Condition, [FormatString, [Args...]]) ``Condition`` is false.
|
||||
--------------------------------------------------------------------------- --------------------------------------------------------------------------- -------------------------------------------
|
||||
cr_assert_null(Value, [FormatString, [Args...]]) ``Value`` is ``NULL``.
|
||||
--------------------------------------------------------------------------- --------------------------------------------------------------------------- -------------------------------------------
|
||||
cr_assert_not_null(Value, [FormatString, [Args...]]) ``Value`` is not ``NULL``.
|
||||
--------------------------------------------------------------------------- --------------------------------------------------------------------------- -------------------------------------------
|
||||
cr_assert_eq(Actual, Expected, [FormatString, [Args...]]) ``Actual`` is equal to ``Expected``. Compatible with C++ operator overloading
|
||||
--------------------------------------------------------------------------- --------------------------------------------------------------------------- -------------------------------------------
|
||||
cr_assert_neq(Actual, Unexpected, [FormatString, [Args...]]) ``Actual`` is not equal to ``Unexpected``. Compatible with C++ operator overloading
|
||||
--------------------------------------------------------------------------- --------------------------------------------------------------------------- -------------------------------------------
|
||||
cr_assert_lt(Actual, Reference, [FormatString, [Args...]]) ``Actual`` is less than ``Reference``. Compatible with C++ operator overloading
|
||||
--------------------------------------------------------------------------- --------------------------------------------------------------------------- -------------------------------------------
|
||||
cr_assert_leq(Actual, Reference, [FormatString, [Args...]]) ``Actual`` is less or equal to ``Reference``. Compatible with C++ operator overloading
|
||||
--------------------------------------------------------------------------- --------------------------------------------------------------------------- -------------------------------------------
|
||||
cr_assert_gt(Actual, Reference, [FormatString, [Args...]]) ``Actual`` is greater than ``Reference``. Compatible with C++ operator overloading
|
||||
--------------------------------------------------------------------------- --------------------------------------------------------------------------- -------------------------------------------
|
||||
cr_assert_geq(Actual, Reference, [FormatString, [Args...]]) ``Actual`` is greater or equal to ``Reference``. Compatible with C++ operator overloading
|
||||
--------------------------------------------------------------------------- --------------------------------------------------------------------------- -------------------------------------------
|
||||
cr_assert_float_eq(Actual, Expected, Epsilon, [FormatString, [Args...]]) ``Actual`` is equal to ``Expected`` with a tolerance of ``Epsilon``. Use this to test equality between floats
|
||||
--------------------------------------------------------------------------- --------------------------------------------------------------------------- -------------------------------------------
|
||||
cr_assert_float_neq(Actual, Unexpected, Epsilon, [FormatString, [Args...]]) ``Actual`` is not equal to ``Unexpected`` with a tolerance of ``Epsilon``. Use this to test inequality between floats
|
||||
=========================================================================== =========================================================================== ===========================================
|
||||
|
||||
String Assertions
|
||||
-----------------
|
||||
|
@ -47,98 +50,98 @@ Note: these macros are meant to deal with *native* strings, i.e. char arrays.
|
|||
Most of them won't work on ``std::string`` in C++, with some exceptions -- for
|
||||
``std::string``, you should use regular comparison assersions, as listed above.
|
||||
|
||||
=========================================================== =================================================================== ===========================================
|
||||
Macro Passes if and only if Notes
|
||||
=========================================================== =================================================================== ===========================================
|
||||
cr_assert_str_empty(Value, [Message, [Args...]]) ``Value`` is an empty string. Also works on std::string
|
||||
----------------------------------------------------------- ------------------------------------------------------------------- -------------------------------------------
|
||||
cr_assert_str_not_empty(Value, [Message, [Args...]]) ``Value`` is not an empty string. Also works on std::string
|
||||
----------------------------------------------------------- ------------------------------------------------------------------- -------------------------------------------
|
||||
cr_assert_str_eq(Actual, Expected, [Message, [Args...]]) ``Actual`` is lexicographically equal to ``Expected``.
|
||||
----------------------------------------------------------- ------------------------------------------------------------------- -------------------------------------------
|
||||
cr_assert_str_neq(Actual, Unexpected, [Message, [Args...]]) ``Actual`` is not lexicographically equal to ``Unexpected``.
|
||||
----------------------------------------------------------- ------------------------------------------------------------------- -------------------------------------------
|
||||
cr_assert_str_lt(Actual, Reference, [Message, [Args...]]) ``Actual`` is lexicographically less than ``Reference``.
|
||||
----------------------------------------------------------- ------------------------------------------------------------------- -------------------------------------------
|
||||
cr_assert_str_leq(Actual, Reference, [Message, [Args...]]) ``Actual`` is lexicographically less or equal to ``Reference``.
|
||||
----------------------------------------------------------- ------------------------------------------------------------------- -------------------------------------------
|
||||
cr_assert_str_gt(Actual, Reference, [Message, [Args...]]) ``Actual`` is lexicographically greater than ``Reference``.
|
||||
----------------------------------------------------------- ------------------------------------------------------------------- -------------------------------------------
|
||||
cr_assert_str_geq(Actual, Reference, [Message, [Args...]]) ``Actual`` is lexicographically greater or equal to ``Reference``.
|
||||
=========================================================== =================================================================== ===========================================
|
||||
================================================================ =================================================================== ===========================================
|
||||
Macro Passes if and only if Notes
|
||||
================================================================ =================================================================== ===========================================
|
||||
cr_assert_str_empty(Value, [FormatString, [Args...]]) ``Value`` is an empty string. Also works on std::string
|
||||
---------------------------------------------------------------- ------------------------------------------------------------------- -------------------------------------------
|
||||
cr_assert_str_not_empty(Value, [FormatString, [Args...]]) ``Value`` is not an empty string. Also works on std::string
|
||||
---------------------------------------------------------------- ------------------------------------------------------------------- -------------------------------------------
|
||||
cr_assert_str_eq(Actual, Expected, [FormatString, [Args...]]) ``Actual`` is lexicographically equal to ``Expected``.
|
||||
---------------------------------------------------------------- ------------------------------------------------------------------- -------------------------------------------
|
||||
cr_assert_str_neq(Actual, Unexpected, [FormatString, [Args...]]) ``Actual`` is not lexicographically equal to ``Unexpected``.
|
||||
---------------------------------------------------------------- ------------------------------------------------------------------- -------------------------------------------
|
||||
cr_assert_str_lt(Actual, Reference, [FormatString, [Args...]]) ``Actual`` is lexicographically less than ``Reference``.
|
||||
---------------------------------------------------------------- ------------------------------------------------------------------- -------------------------------------------
|
||||
cr_assert_str_leq(Actual, Reference, [FormatString, [Args...]]) ``Actual`` is lexicographically less or equal to ``Reference``.
|
||||
---------------------------------------------------------------- ------------------------------------------------------------------- -------------------------------------------
|
||||
cr_assert_str_gt(Actual, Reference, [FormatString, [Args...]]) ``Actual`` is lexicographically greater than ``Reference``.
|
||||
---------------------------------------------------------------- ------------------------------------------------------------------- -------------------------------------------
|
||||
cr_assert_str_geq(Actual, Reference, [FormatString, [Args...]]) ``Actual`` is lexicographically greater or equal to ``Reference``.
|
||||
================================================================ =================================================================== ===========================================
|
||||
|
||||
Array Assertions
|
||||
-----------------
|
||||
|
||||
=========================================================================== =========================================================================== ===========================================
|
||||
Macro Passes if and only if Notes
|
||||
=========================================================================== =========================================================================== ===========================================
|
||||
cr_assert_arr_eq(Actual, Expected, [Message, [Args...]]) ``Actual`` is byte-to-byte equal to ``Expected``. This should not be used on struct arrays,
|
||||
consider using ``cr_assert_arr_eq_cmp``
|
||||
instead.
|
||||
--------------------------------------------------------------------------- --------------------------------------------------------------------------- -------------------------------------------
|
||||
cr_assert_arr_neq(Actual, Unexpected, [Message, [Args...]]) ``Actual`` is not byte-to-byte equal to ``Unexpected``. This should not be used on struct arrays,
|
||||
consider using ``cr_assert_arr_neq_cmp``
|
||||
instead.
|
||||
--------------------------------------------------------------------------- --------------------------------------------------------------------------- -------------------------------------------
|
||||
cr_assert_arr_eq_cmp(Actual, Expected, Size, Cmp, [Message, [Args...]]) ``Actual`` is comparatively equal to ``Expected`` Only available in C++ and GNU C99
|
||||
--------------------------------------------------------------------------- --------------------------------------------------------------------------- -------------------------------------------
|
||||
cr_assert_arr_neq_cmp(Actual, Unexpected, Size, Cmp, [Message, [Args...]]) ``Actual`` is not comparatively equal to ``Expected`` Only available in C++ and GNU C99
|
||||
--------------------------------------------------------------------------- --------------------------------------------------------------------------- -------------------------------------------
|
||||
cr_assert_arr_lt_cmp(Actual, Reference, Size, Cmp, [Message, [Args...]]) ``Actual`` is comparatively less than ``Reference`` Only available in C++ and GNU C99
|
||||
--------------------------------------------------------------------------- --------------------------------------------------------------------------- -------------------------------------------
|
||||
cr_assert_arr_leq_cmp(Actual, Reference, Size, Cmp, [Message, [Args...]]) ``Actual`` is comparatively less or equal to ``Reference`` Only available in C++ and GNU C99
|
||||
--------------------------------------------------------------------------- --------------------------------------------------------------------------- -------------------------------------------
|
||||
cr_assert_arr_gt_cmp(Actual, Reference, Size, Cmp, [Message, [Args...]]) ``Actual`` is comparatively greater than ``Reference`` Only available in C++ and GNU C99
|
||||
--------------------------------------------------------------------------- --------------------------------------------------------------------------- -------------------------------------------
|
||||
cr_assert_arr_geq_cmp(Actual, Reference, Size, Cmp, [Message, [Args...]]) ``Actual`` is comparatively greater or equal to ``Reference`` Only available in C++ and GNU C99
|
||||
=========================================================================== =========================================================================== ===========================================
|
||||
=============================================================================== =========================================================================== ===========================================
|
||||
Macro Passes if and only if Notes
|
||||
=============================================================================== =========================================================================== ===========================================
|
||||
cr_assert_arr_eq(Actual, Expected, [FormatString, [Args...]]) ``Actual`` is byte-to-byte equal to ``Expected``. This should not be used on struct arrays,
|
||||
consider using ``cr_assert_arr_eq_cmp``
|
||||
instead.
|
||||
------------------------------------------------------------------------------- --------------------------------------------------------------------------- -------------------------------------------
|
||||
cr_assert_arr_neq(Actual, Unexpected, [FormatString, [Args...]]) ``Actual`` is not byte-to-byte equal to ``Unexpected``. This should not be used on struct arrays,
|
||||
consider using ``cr_assert_arr_neq_cmp``
|
||||
instead.
|
||||
------------------------------------------------------------------------------- --------------------------------------------------------------------------- -------------------------------------------
|
||||
cr_assert_arr_eq_cmp(Actual, Expected, Size, Cmp, [FormatString, [Args...]]) ``Actual`` is comparatively equal to ``Expected`` Only available in C++ and GNU C99
|
||||
------------------------------------------------------------------------------- --------------------------------------------------------------------------- -------------------------------------------
|
||||
cr_assert_arr_neq_cmp(Actual, Unexpected, Size, Cmp, [FormatString, [Args...]]) ``Actual`` is not comparatively equal to ``Expected`` Only available in C++ and GNU C99
|
||||
------------------------------------------------------------------------------- --------------------------------------------------------------------------- -------------------------------------------
|
||||
cr_assert_arr_lt_cmp(Actual, Reference, Size, Cmp, [FormatString, [Args...]]) ``Actual`` is comparatively less than ``Reference`` Only available in C++ and GNU C99
|
||||
------------------------------------------------------------------------------- --------------------------------------------------------------------------- -------------------------------------------
|
||||
cr_assert_arr_leq_cmp(Actual, Reference, Size, Cmp, [FormatString, [Args...]]) ``Actual`` is comparatively less or equal to ``Reference`` Only available in C++ and GNU C99
|
||||
------------------------------------------------------------------------------- --------------------------------------------------------------------------- -------------------------------------------
|
||||
cr_assert_arr_gt_cmp(Actual, Reference, Size, Cmp, [FormatString, [Args...]]) ``Actual`` is comparatively greater than ``Reference`` Only available in C++ and GNU C99
|
||||
------------------------------------------------------------------------------- --------------------------------------------------------------------------- -------------------------------------------
|
||||
cr_assert_arr_geq_cmp(Actual, Reference, Size, Cmp, [FormatString, [Args...]]) ``Actual`` is comparatively greater or equal to ``Reference`` Only available in C++ and GNU C99
|
||||
=============================================================================== =========================================================================== ===========================================
|
||||
|
||||
Exception Assertions
|
||||
--------------------
|
||||
|
||||
The following assertion macros are only defined for C++.
|
||||
|
||||
=========================================================================== =========================================================================== ===========================================
|
||||
Macro Passes if and only if Notes
|
||||
=========================================================================== =========================================================================== ===========================================
|
||||
cr_assert_throw(Statement, Exception, [Message, [Args...]]) ``Statement`` throws an instance of ``Exception``.
|
||||
--------------------------------------------------------------------------- --------------------------------------------------------------------------- -------------------------------------------
|
||||
cr_assert_no_throw(Statement, Exception, [Message, [Args...]]) ``Statement`` does not throws an instance of ``Exception``.
|
||||
--------------------------------------------------------------------------- --------------------------------------------------------------------------- -------------------------------------------
|
||||
cr_assert_any_throw(Statement, [Message, [Args...]]) ``Statement`` throws any kind of exception.
|
||||
--------------------------------------------------------------------------- --------------------------------------------------------------------------- -------------------------------------------
|
||||
cr_assert_none_throw(Statement, [Message, [Args...]]) ``Statement`` does not throw any exception.
|
||||
=========================================================================== =========================================================================== ===========================================
|
||||
=============================================================================== =========================================================================== ===========================================
|
||||
Macro Passes if and only if Notes
|
||||
=============================================================================== =========================================================================== ===========================================
|
||||
cr_assert_throw(Statement, Exception, [FormatString, [Args...]]) ``Statement`` throws an instance of ``Exception``.
|
||||
------------------------------------------------------------------------------- --------------------------------------------------------------------------- -------------------------------------------
|
||||
cr_assert_no_throw(Statement, Exception, [FormatString, [Args...]]) ``Statement`` does not throws an instance of ``Exception``.
|
||||
------------------------------------------------------------------------------- --------------------------------------------------------------------------- -------------------------------------------
|
||||
cr_assert_any_throw(Statement, [FormatString, [Args...]]) ``Statement`` throws any kind of exception.
|
||||
------------------------------------------------------------------------------- --------------------------------------------------------------------------- -------------------------------------------
|
||||
cr_assert_none_throw(Statement, [FormatString, [Args...]]) ``Statement`` does not throw any exception.
|
||||
=============================================================================== =========================================================================== ===========================================
|
||||
|
||||
File Assertions
|
||||
---------------
|
||||
|
||||
=============================================================================== ============================================================================ ===========================================
|
||||
Macro Passes if and only if Notes
|
||||
=============================================================================== ============================================================================ ===========================================
|
||||
cr_assert_file_contents_eq_str(File, ExpectedContents, [Message, [Args...]]) The contents of ``File`` are equal to the string ``ExpectedContents``.
|
||||
------------------------------------------------------------------------------- ---------------------------------------------------------------------------- -------------------------------------------
|
||||
cr_assert_file_contents_neq_str(File, ExpectedContents, [Message, [Args...]]) The contents of ``File`` are not equal to the string ``ExpectedContents``.
|
||||
------------------------------------------------------------------------------- ---------------------------------------------------------------------------- -------------------------------------------
|
||||
cr_assert_stdout_eq_str(ExpectedContents, [Message, [Args...]]) The contents of ``stdout`` are equal to the string ``ExpectedContents``.
|
||||
------------------------------------------------------------------------------- ---------------------------------------------------------------------------- -------------------------------------------
|
||||
cr_assert_stdout_neq_str(ExpectedContents, [Message, [Args...]]) The contents of ``stdout`` are not equal to the string ``ExpectedContents``.
|
||||
------------------------------------------------------------------------------- ---------------------------------------------------------------------------- -------------------------------------------
|
||||
cr_assert_stderr_eq_str(ExpectedContents, [Message, [Args...]]) The contents of ``stderr`` are equal to the string ``ExpectedContents``.
|
||||
------------------------------------------------------------------------------- ---------------------------------------------------------------------------- -------------------------------------------
|
||||
cr_assert_stderr_neq_str(ExpectedContents, [Message, [Args...]]) The contents of ``stderr`` are not equal to the string ``ExpectedContents``.
|
||||
------------------------------------------------------------------------------- ---------------------------------------------------------------------------- -------------------------------------------
|
||||
cr_assert_file_contents_eq(File, RefFile, [Message, [Args...]]) The contents of ``File`` are equal to the contents of ``RefFile``.
|
||||
------------------------------------------------------------------------------- ---------------------------------------------------------------------------- -------------------------------------------
|
||||
cr_assert_file_contents_neq(File, RefFile, [Message, [Args...]]) The contents of ``File`` are not equal to the contents of ``RefFile``.
|
||||
------------------------------------------------------------------------------- ---------------------------------------------------------------------------- -------------------------------------------
|
||||
cr_assert_stdout_eq(RefFile, [Message, [Args...]]) The contents of ``stdout`` are equal to the contents of ``RefFile``.
|
||||
------------------------------------------------------------------------------- ---------------------------------------------------------------------------- -------------------------------------------
|
||||
cr_assert_stdout_neq(RefFile, [Message, [Args...]]) The contents of ``stdout`` are not equal to the contents of ``RefFile``.
|
||||
------------------------------------------------------------------------------- ---------------------------------------------------------------------------- -------------------------------------------
|
||||
cr_assert_stderr_eq(RefFile, [Message, [Args...]]) The contents of ``stderr`` are equal to the contents of ``RefFile``.
|
||||
------------------------------------------------------------------------------- ---------------------------------------------------------------------------- -------------------------------------------
|
||||
cr_assert_stderr_neq(RefFile, [Message, [Args...]]) The contents of ``stderr`` are not equal to the contents of ``RefFile``.
|
||||
=============================================================================== ============================================================================ ===========================================
|
||||
=================================================================================== ============================================================================ ===========================================
|
||||
Macro Passes if and only if Notes
|
||||
=================================================================================== ============================================================================ ===========================================
|
||||
cr_assert_file_contents_eq_str(File, ExpectedContents, [FormatString, [Args...]]) The contents of ``File`` are equal to the string ``ExpectedContents``.
|
||||
----------------------------------------------------------------------------------- ---------------------------------------------------------------------------- -------------------------------------------
|
||||
cr_assert_file_contents_neq_str(File, ExpectedContents, [FormatString, [Args...]]) The contents of ``File`` are not equal to the string ``ExpectedContents``.
|
||||
----------------------------------------------------------------------------------- ---------------------------------------------------------------------------- -------------------------------------------
|
||||
cr_assert_stdout_eq_str(ExpectedContents, [FormatString, [Args...]]) The contents of ``stdout`` are equal to the string ``ExpectedContents``.
|
||||
----------------------------------------------------------------------------------- ---------------------------------------------------------------------------- -------------------------------------------
|
||||
cr_assert_stdout_neq_str(ExpectedContents, [FormatString, [Args...]]) The contents of ``stdout`` are not equal to the string ``ExpectedContents``.
|
||||
----------------------------------------------------------------------------------- ---------------------------------------------------------------------------- -------------------------------------------
|
||||
cr_assert_stderr_eq_str(ExpectedContents, [FormatString, [Args...]]) The contents of ``stderr`` are equal to the string ``ExpectedContents``.
|
||||
----------------------------------------------------------------------------------- ---------------------------------------------------------------------------- -------------------------------------------
|
||||
cr_assert_stderr_neq_str(ExpectedContents, [FormatString, [Args...]]) The contents of ``stderr`` are not equal to the string ``ExpectedContents``.
|
||||
----------------------------------------------------------------------------------- ---------------------------------------------------------------------------- -------------------------------------------
|
||||
cr_assert_file_contents_eq(File, RefFile, [FormatString, [Args...]]) The contents of ``File`` are equal to the contents of ``RefFile``.
|
||||
----------------------------------------------------------------------------------- ---------------------------------------------------------------------------- -------------------------------------------
|
||||
cr_assert_file_contents_neq(File, RefFile, [FormatString, [Args...]]) The contents of ``File`` are not equal to the contents of ``RefFile``.
|
||||
----------------------------------------------------------------------------------- ---------------------------------------------------------------------------- -------------------------------------------
|
||||
cr_assert_stdout_eq(RefFile, [FormatString, [Args...]]) The contents of ``stdout`` are equal to the contents of ``RefFile``.
|
||||
----------------------------------------------------------------------------------- ---------------------------------------------------------------------------- -------------------------------------------
|
||||
cr_assert_stdout_neq(RefFile, [FormatString, [Args...]]) The contents of ``stdout`` are not equal to the contents of ``RefFile``.
|
||||
----------------------------------------------------------------------------------- ---------------------------------------------------------------------------- -------------------------------------------
|
||||
cr_assert_stderr_eq(RefFile, [FormatString, [Args...]]) The contents of ``stderr`` are equal to the contents of ``RefFile``.
|
||||
----------------------------------------------------------------------------------- ---------------------------------------------------------------------------- -------------------------------------------
|
||||
cr_assert_stderr_neq(RefFile, [FormatString, [Args...]]) The contents of ``stderr`` are not equal to the contents of ``RefFile``.
|
||||
=================================================================================== ============================================================================ ===========================================
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@ copyright = u'2015, Franklin "Snaipe" Mathieu'
|
|||
# built documents.
|
||||
#
|
||||
# The short X.Y version.
|
||||
version = '2.1.0'
|
||||
version = '2.2.0'
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
release = version
|
||||
|
||||
|
|
68
doc/env.rst
68
doc/env.rst
|
@ -8,11 +8,14 @@ Command line arguments
|
|||
----------------------
|
||||
|
||||
* ``-h or --help``: Show a help message with the available switches.
|
||||
* ``-q or --quiet``: Disables all logging.
|
||||
* ``-v or --version``: Prints the version of criterion that has been
|
||||
linked against.
|
||||
* ``-l or --list``: Print all the tests in a list.
|
||||
* ``-f or --fail-fast``: Exit after the first test failure.
|
||||
* ``--ascii``: Don't use fancy unicode symbols or colors in the output.
|
||||
* ``-jN or --jobs N``: Use ``N`` parallel jobs to run the tests. ``0`` picks
|
||||
a number of jobs ideal for your hardware configuration.
|
||||
* ``--pattern [PATTERN]``: Run tests whose string identifier matches
|
||||
the given shell wildcard pattern (see dedicated section below). (\*nix only)
|
||||
* ``--no-early-exit``: The test workers shall not prematurely exit when done and
|
||||
|
@ -20,30 +23,53 @@ Command line arguments
|
|||
This is useful when tracking memory leaks with ``valgrind --tool=memcheck``.
|
||||
* ``-S or --short-filename``: The filenames are displayed in their short form.
|
||||
* ``--always-succeed``: The process shall exit with a status of ``0``.
|
||||
* ``--tap``: Enables the TAP (Test Anything Protocol) output format.
|
||||
* ``--tap[=FILE]``: Writes a TAP (Test Anything Protocol) report to FILE.
|
||||
No file or ``"-"`` means ``stderr`` and implies ``--quiet``. This option is
|
||||
equivalent to ``--output=tap:FILE``.
|
||||
* ``--xml[=FILE]``: Writes JUnit4 XML report to FILE.
|
||||
No file or ``"-"`` means ``stderr`` and implies ``--quiet``. This option is
|
||||
equivalent to ``--output=tap:FILE``.
|
||||
* ``--json[=FILE]``: Writes a JSON report to FILE.
|
||||
No file or ``"-"`` means ``stderr`` and implies ``--quiet``. This option is
|
||||
equivalent to ``--output=tap:FILE``.
|
||||
* ``--verbose[=level]``: Makes the output verbose. When provided with an integer,
|
||||
sets the verbosity level to that integer.
|
||||
* ``-OPROVIDER:FILE or --output=PROVIDER:FILE``: Write a test report to FILE
|
||||
using the output provider named by PROVIDER.
|
||||
If FILE is ``"-"``, it implies ``--quiet``, and the report shall be written
|
||||
to ``stderr``.
|
||||
|
||||
Shell Wildcard Pattern
|
||||
----------------------
|
||||
|
||||
Patterns in criterion are matched against a test's string identifier with
|
||||
``fnmatch``. This feature is only available on \*nix systems where ``fnmatch``
|
||||
is provided.
|
||||
Extglob patterns in criterion are matched against a test's string identifier.
|
||||
This feature is only available on \*nix systems where ``PCRE`` is provided.
|
||||
|
||||
Special characters used in shell-style wildcard patterns are:
|
||||
In the table below, a ``pattern-list`` is a list of patterns separated by ``|``.
|
||||
Any extglob pattern can be constructed by combining any of the following
|
||||
sub-patterns:
|
||||
|
||||
=========== ===================================
|
||||
Pattern Meaning
|
||||
=========== ===================================
|
||||
``*`` matches everything
|
||||
----------- -----------------------------------
|
||||
``?`` matches any character
|
||||
----------- -----------------------------------
|
||||
``[seq]`` matches any character in *seq*
|
||||
----------- -----------------------------------
|
||||
``[!seq]`` matches any character not in *seq*
|
||||
=========== ===================================
|
||||
==================== ======================================================
|
||||
Pattern Meaning
|
||||
==================== ======================================================
|
||||
``*`` matches everything
|
||||
-------------------- ------------------------------------------------------
|
||||
``?`` matches any character
|
||||
-------------------- ------------------------------------------------------
|
||||
``[seq]`` matches any character in *seq*
|
||||
-------------------- ------------------------------------------------------
|
||||
``[!seq]`` matches any character not in *seq*
|
||||
-------------------- ------------------------------------------------------
|
||||
``?(pattern-list)`` Matches zero or one occurrence of the given patterns
|
||||
-------------------- ------------------------------------------------------
|
||||
``*(pattern-list)`` Matches zero or more occurrences of the given patterns
|
||||
-------------------- ------------------------------------------------------
|
||||
``+(pattern-list)`` Matches one or more occurrences of the given patterns
|
||||
-------------------- ------------------------------------------------------
|
||||
``@(pattern-list)`` Matches one of the given patterns
|
||||
-------------------- ------------------------------------------------------
|
||||
``!(pattern-list)`` Matches anything except one of the given patterns
|
||||
==================== ======================================================
|
||||
|
||||
A test string identifier is of the form ``suite-name/test-name``, so a pattern
|
||||
of ``simple/*`` matches every tests in the ``simple`` suite, ``*/passing``
|
||||
|
@ -57,11 +83,19 @@ Environment variables are alternatives to command line switches when set to 1.
|
|||
|
||||
* ``CRITERION_ALWAYS_SUCCEED``: Same as ``--always-succeed``.
|
||||
* ``CRITERION_NO_EARLY_EXIT``: Same as ``--no-early-exit``.
|
||||
* ``CRITERION_ENABLE_TAP``: Same as ``--tap``.
|
||||
* ``CRITERION_FAIL_FAST``: Same as ``--fail-fast``.
|
||||
* ``CRITERION_USE_ASCII``: Same as ``--ascii``.
|
||||
* ``CRITERION_JOBS``: Same as ``--jobs``. Sets the number of jobs to
|
||||
its value.
|
||||
* ``CRITERION_SHORT_FILENAME``: Same as ``--short-filename``.
|
||||
* ``CRITERION_VERBOSITY_LEVEL``: Same as ``--verbose``. Sets the verbosity level
|
||||
to its value.
|
||||
* ``CRITERION_TEST_PATTERN``: Same as ``--pattern``. Sets the test pattern
|
||||
to its value. (\*nix only)
|
||||
* ``CRITERION_DISABLE_TIME_MEASUREMENTS``: Disables any time measurements on
|
||||
the tests.
|
||||
* ``CRITERION_OUTPUTS``: Can be set to a comma-separated list of
|
||||
``PROVIDER:FILE`` entries. For instance, setting the variable to
|
||||
``tap:foo.tap,xml:bar.xml`` has the same effect as specifying ``--tap=foo.tap``
|
||||
and ``--xml=bar.xml`` at once.
|
||||
* ``CRITERION_ENABLE_TAP``: (Deprecated, use CRITERION_OUTPUTS) Same as ``--tap``.
|
||||
|
|
|
@ -10,6 +10,7 @@ Criterion
|
|||
assert
|
||||
hooks
|
||||
env
|
||||
output
|
||||
parameterized
|
||||
theories
|
||||
internal
|
||||
|
|
|
@ -28,7 +28,7 @@ Field Type Description
|
|||
=================== ================================== ==============================================================
|
||||
logging_threshold enum criterion_logging_level The logging level
|
||||
------------------- ---------------------------------- --------------------------------------------------------------
|
||||
output_provider struct criterion_output_provider * The output provider (see below)
|
||||
logger struct criterion_logger * The logger (see below)
|
||||
------------------- ---------------------------------- --------------------------------------------------------------
|
||||
no_early_exit bool True iff the test worker should exit early
|
||||
------------------- ---------------------------------- --------------------------------------------------------------
|
||||
|
@ -66,24 +66,23 @@ Example main
|
|||
int main(int argc, char *argv[]) {
|
||||
struct criterion_test_set *tests = criterion_initialize();
|
||||
|
||||
if (!criterion_handle_args(argc, argv, true))
|
||||
return 0;
|
||||
|
||||
int result = !criterion_run_all_tests(set);
|
||||
int result = 0;
|
||||
if (criterion_handle_args(argc, argv, true))
|
||||
result = !criterion_run_all_tests(set);
|
||||
|
||||
criterion_finalize(set);
|
||||
return result;
|
||||
}
|
||||
|
||||
Implementing your own output provider
|
||||
-------------------------------------
|
||||
Implementing your own logger
|
||||
----------------------------
|
||||
|
||||
In case you are not satisfied by the default output provider, you can implement
|
||||
yours. To do so, simply set the ``output_provider`` option to your custom
|
||||
output provider.
|
||||
In case you are not satisfied by the default logger, you can implement
|
||||
yours. To do so, simply set the ``logger`` option to your custom
|
||||
logger.
|
||||
|
||||
Each function contained in the structure is called during one of the standard
|
||||
phase of the criterion runner.
|
||||
|
||||
For more insight on how to implement this, see other existing output providers
|
||||
For more insight on how to implement this, see other existing loggers
|
||||
in ``src/log/``.
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
Introduction
|
||||
============
|
||||
|
||||
Criterion is a dead-simple, non-intrusive testing framework for the C
|
||||
programming language.
|
||||
Criterion is a dead-simple, non-intrusive unit testing framework for C and C++.
|
||||
|
||||
Philosophy
|
||||
----------
|
||||
|
@ -20,12 +19,15 @@ the user would have with other frameworks.
|
|||
Features
|
||||
--------
|
||||
|
||||
* C99 and C++11 compatible.
|
||||
* Tests are automatically registered when declared.
|
||||
* Implements a xUnit framework structure.
|
||||
* A default entry point is provided, no need to declare a main
|
||||
unless you want to do special handling.
|
||||
* Test are isolated in their own process, crashes and signals can be
|
||||
reported and tested.
|
||||
* Unified interface between C and C++: include the criterion header and it *just* works.
|
||||
* Supports parameterized tests and theories.
|
||||
* Progress and statistics can be followed in real time with report hooks.
|
||||
* TAP output format can be enabled with an option.
|
||||
* Runs on Linux, FreeBSD, Mac OS X, and Windows (Compiling with MinGW GCC).
|
||||
* xUnit framework structure
|
||||
* Runs on Linux, FreeBSD, Mac OS X, and Windows (Compiling with MinGW GCC and Visual Studio 2015+).
|
||||
|
|
44
doc/output.rst
Normal file
44
doc/output.rst
Normal file
|
@ -0,0 +1,44 @@
|
|||
Writing tests reports in a custom format
|
||||
========================================
|
||||
|
||||
Outputs providers are used to write tests reports in the format of your choice:
|
||||
for instance, TAP and XML reporting are implemented with output providers.
|
||||
|
||||
Adding a custom output provider
|
||||
-------------------------------
|
||||
|
||||
An output provider is a function with the following signature:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
void func(FILE *out, struct criterion_global_stats *stats);
|
||||
|
||||
Once implemented, you then need to register it as an output provider:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
criterion_register_output_provider("provider name", func);
|
||||
|
||||
This needs to be done before the test runner stops, so you may want to register
|
||||
it either in a self-provided main, or in a PRE_ALL or POST_ALL report hook.
|
||||
|
||||
Writing to a file with an output provider
|
||||
-----------------------------------------
|
||||
|
||||
To tell criterion to write a report to a specific file using the output provider
|
||||
of your choice, you can either pass ``--output`` as a command-line
|
||||
parameter:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
./my_tests --output="provider name":/path/to/file
|
||||
|
||||
Or, you can do so directly by calling ``criterion_add_output`` before the
|
||||
runner stops:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
criterion_add_output("provider name", "/path/to/file");
|
||||
|
||||
The path may be relative. If ``"-"`` is passed as a filename, the report will
|
||||
be written to ``stderr``.
|
|
@ -18,7 +18,7 @@ and the parameter generator function:
|
|||
|
||||
#include <criterion/parameterized.h>
|
||||
|
||||
ParameterizedTestParameter(suite_name, test_name) = {
|
||||
ParameterizedTestParameters(suite_name, test_name) {
|
||||
void *params;
|
||||
size_t nb_params;
|
||||
|
||||
|
@ -54,17 +54,12 @@ easily use a struct to hold the context as a workaround:
|
|||
...
|
||||
};
|
||||
|
||||
ParameterizedTestParameter(suite_name, test_name) = {
|
||||
size_t nb_params = 32;
|
||||
struct my_params *params = cr_malloc(sizeof (struct my_params) * nb_params);
|
||||
|
||||
// generate parameter set
|
||||
|
||||
params[0] = ...
|
||||
params[1] = ...
|
||||
|
||||
...
|
||||
ParameterizedTestParameters(suite_name, test_name) {
|
||||
struct my_params params[] = {
|
||||
// parameter set
|
||||
};
|
||||
|
||||
size_t nb_params = sizeof (params) / sizeof (struct my_params);
|
||||
return cr_make_param_array(struct my_params, params, nb_params);
|
||||
}
|
||||
|
||||
|
@ -72,8 +67,20 @@ easily use a struct to hold the context as a workaround:
|
|||
// access param.param0, param.param1, ...
|
||||
}
|
||||
|
||||
Dynamically allocating fields
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
C++ users can also use a simpler syntax before returning an array of parameters:
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
ParameterizedTestParameters(suite_name, test_name) {
|
||||
struct my_params params[] = {
|
||||
// parameter set
|
||||
};
|
||||
|
||||
return criterion_test_params(params);
|
||||
}
|
||||
|
||||
Dynamically allocating parameters
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Any dynamic memory allocation done from a ParameterizedTestParameter function
|
||||
**must** be done with ``cr_malloc``, ``cr_calloc``, or ``cr_realloc``.
|
||||
|
@ -100,6 +107,9 @@ use:
|
|||
``criterion::new_arr``.
|
||||
The function possess the exact same semantics as ``delete[] array``.
|
||||
|
||||
Furthermore, the ``criterion::allocator<T>`` allocator can be used with STL
|
||||
containers to allocate memory with the functions above.
|
||||
|
||||
Freeing dynamically allocated parameter fields
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
|
@ -118,15 +128,36 @@ the cleanup function that should be called on the generated parameter context:
|
|||
cr_free(((struct my_params *) ctp->params)->some_int_ptr);
|
||||
}
|
||||
|
||||
ParameterizedTestParameter(suite_name, test_name) = {
|
||||
static my_params param = {
|
||||
ParameterizedTestParameters(suite_name, test_name) {
|
||||
static my_params params[] = {{
|
||||
.some_int_ptr = cr_malloc(sizeof (int));
|
||||
};
|
||||
*param.some_int_ptr = 42;
|
||||
}};
|
||||
param[0].some_int_ptr = 42;
|
||||
|
||||
return cr_make_param_array(struct my_params, ¶m, 1, cleanup_params);
|
||||
return cr_make_param_array(struct my_params, params, 1, cleanup_params);
|
||||
}
|
||||
|
||||
C++ users can use a more convenient approach:
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
#include <criterion/parameterized.h>
|
||||
|
||||
struct my_params {
|
||||
std::unique_ptr<int, decltype(criterion::free)> some_int_ptr;
|
||||
|
||||
my_params(int *ptr) : some_int_ptr(ptr, criterion::free) {}
|
||||
};
|
||||
|
||||
ParameterizedTestParameters(suite_name, test_name) {
|
||||
static criterion::parameters<my_params> params;
|
||||
params.push_back(my_params(criterion::new_obj<int>(42)));
|
||||
|
||||
return params;
|
||||
}
|
||||
|
||||
``criterion::parameters<T>`` is typedef'd as ``std::vector<T, criterion::allocator<T>>``.
|
||||
|
||||
Configuring parameterized tests
|
||||
-------------------------------
|
||||
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 1.4 MiB After Width: | Height: | Size: 1.3 MiB |
|
@ -7,7 +7,8 @@ Prerequisites
|
|||
The library is supported on Linux, OS X, FreeBSD, and Windows.
|
||||
|
||||
The following compilers are supported to compile both the library and the tests:
|
||||
* GCC 4.9+
|
||||
|
||||
* GCC 4.9+ (Can be relaxed to GCC 4.6+ when not using C++)
|
||||
* Clang 3.4+
|
||||
* MSVC 14+ (Included in Visual Studio 2015 or later)
|
||||
|
||||
|
|
|
@ -78,26 +78,26 @@ Macro Description
|
|||
------------------------------------------------------- ----------------------------------------------------
|
||||
``cr_assume_float_neq(Actual, Unexpected, Epsilon)`` Assumes Actual != Expected with an error of Epsilon.
|
||||
------------------------------------------------------- ----------------------------------------------------
|
||||
``cr_assume_strings_eq(Actual, Expected)`` Assumes Actual and Expected are the same string.
|
||||
``cr_assume_str_eq(Actual, Expected)`` Assumes Actual and Expected are the same string.
|
||||
------------------------------------------------------- ----------------------------------------------------
|
||||
``cr_assume_strings_neq(Actual, Unexpected)`` Assumes Actual and Expected are not the same string.
|
||||
``cr_assume_str_neq(Actual, Unexpected)`` Assumes Actual and Expected are not the same string.
|
||||
------------------------------------------------------- ----------------------------------------------------
|
||||
``cr_assume_strings_lt(Actual, Expected)`` Assumes Actual is less than Expected
|
||||
``cr_assume_str_lt(Actual, Expected)`` Assumes Actual is less than Expected
|
||||
lexicographically.
|
||||
------------------------------------------------------- ----------------------------------------------------
|
||||
``cr_assume_strings_leq(Actual, Expected)`` Assumes Actual is less or equal to Expected
|
||||
``cr_assume_str_leq(Actual, Expected)`` Assumes Actual is less or equal to Expected
|
||||
lexicographically.
|
||||
------------------------------------------------------- ----------------------------------------------------
|
||||
``cr_assume_strings_gt(Actual, Expected)`` Assumes Actual is greater than Expected
|
||||
``cr_assume_str_gt(Actual, Expected)`` Assumes Actual is greater than Expected
|
||||
lexicographically.
|
||||
------------------------------------------------------- ----------------------------------------------------
|
||||
``cr_assume_strings_geq(Actual, Expected)`` Assumes Actual is greater or equal to Expected
|
||||
``cr_assume_str_geq(Actual, Expected)`` Assumes Actual is greater or equal to Expected
|
||||
lexicographically.
|
||||
------------------------------------------------------- ----------------------------------------------------
|
||||
``cr_assume_arrays_eq(Actual, Expected, Size)`` Assumes all elements of Actual (from 0 to Size - 1)
|
||||
``cr_assume_arr_eq(Actual, Expected, Size)`` Assumes all elements of Actual (from 0 to Size - 1)
|
||||
are equals to those of Expected.
|
||||
------------------------------------------------------- ----------------------------------------------------
|
||||
``cr_assume_arrays_neq(Actual, Unexpected, Size)`` Assumes one or more elements of Actual (from 0 to
|
||||
``cr_assume_arr_neq(Actual, Unexpected, Size)`` Assumes one or more elements of Actual (from 0 to
|
||||
Size - 1) differs from their counterpart in Expected.
|
||||
======================================================= ====================================================
|
||||
|
||||
|
|
|
@ -24,13 +24,26 @@
|
|||
#ifndef CRITERION_ABORT_H_
|
||||
# define CRITERION_ABORT_H_
|
||||
|
||||
# include "common.h"
|
||||
# include "internal/common.h"
|
||||
|
||||
CR_BEGIN_C_API
|
||||
|
||||
CR_API NORETURN void criterion_abort_test(void);
|
||||
/**
|
||||
* Aborts the current test, marking it as failed.
|
||||
*
|
||||
* This function does not return.
|
||||
*/
|
||||
CR_API CR_NORETURN void criterion_abort_test(void);
|
||||
|
||||
/**
|
||||
* Continues the current test.
|
||||
*
|
||||
* Used as a counterpart to criterion_abort_test.
|
||||
*/
|
||||
CR_INLINE static void criterion_continue_test(void) {}
|
||||
|
||||
CR_API void criterion_test_die(const char *msg, ...);
|
||||
|
||||
CR_END_C_API
|
||||
|
||||
#endif /* !CRITERION_ABORT_H_ */
|
||||
|
|
|
@ -24,14 +24,66 @@
|
|||
#ifndef CRITERION_ALLOC_H_
|
||||
# define CRITERION_ALLOC_H_
|
||||
|
||||
# include <stddef.h>
|
||||
# include "common.h"
|
||||
# ifdef __cplusplus
|
||||
# include <memory>
|
||||
# include <cstddef>
|
||||
using std::size_t;
|
||||
# else
|
||||
# include <stddef.h>
|
||||
# endif
|
||||
# include "internal/common.h"
|
||||
|
||||
CR_BEGIN_C_API
|
||||
|
||||
/**
|
||||
* Allocates a block of memory usable by the test.
|
||||
*
|
||||
* It is undefined behaviour to access a pointer returned by malloc(3)
|
||||
* inside a test or its setup and teardown functions; cr_malloc must
|
||||
* be use in its place for this purpose.
|
||||
*
|
||||
* This function is semantically identical to malloc(3).
|
||||
*
|
||||
* @param[in] size The minimal size in bytes of the newly allocated memory.
|
||||
* @returns The pointer to the start of the allocated memory.
|
||||
*/
|
||||
CR_API void *cr_malloc(size_t size);
|
||||
|
||||
/**
|
||||
* Allocates and zero-initialize a block of memory usable by the test.
|
||||
*
|
||||
* It is undefined behaviour to access a pointer returned by calloc(3)
|
||||
* inside a test or its setup and teardown functions; cr_calloc must
|
||||
* be use in its place for this purpose.
|
||||
*
|
||||
* This function is semantically identical to calloc(3).
|
||||
*
|
||||
* @param[in] nmemb The number of elements to allocate
|
||||
* @param[in] size The minimal size of each element.
|
||||
* @returns The pointer to the start of the allocated memory.
|
||||
*/
|
||||
CR_API void *cr_calloc(size_t nmemb, size_t size);
|
||||
|
||||
/**
|
||||
* Reallocates a block of memory usable by the test.
|
||||
*
|
||||
* It is undefined behaviour to access a pointer returned by realloc(3)
|
||||
* inside a test or its setup and teardown functions; cr_realloc must
|
||||
* be used in its place for this purpose.
|
||||
*
|
||||
* This function is semantically identical to realloc(3).
|
||||
*
|
||||
* @param[in] ptr A pointer to the memory that needs to be resized.
|
||||
* @param[in] size The minimal size of the reallocated memory.
|
||||
* @returns The pointer to the start of the reallocated memory.
|
||||
*/
|
||||
CR_API void *cr_realloc(void *ptr, size_t size);
|
||||
|
||||
/**
|
||||
* Free a block of memory allocated by cr_malloc, cr_free or cr_realloc.
|
||||
*
|
||||
* @param[in] ptr A pointer to the memory that needs to be freed.
|
||||
*/
|
||||
CR_API void cr_free(void *ptr);
|
||||
|
||||
CR_END_C_API
|
||||
|
@ -46,6 +98,19 @@ namespace criterion {
|
|||
void *(*const calloc)(size_t, size_t) = cr_calloc;
|
||||
void *(*const realloc)(void *, size_t) = cr_realloc;
|
||||
|
||||
/**
|
||||
* Allocates and construct a new object.
|
||||
*
|
||||
* It is undefined behaviour to access a pointer returned by the new
|
||||
* operator inside a test or its setup and teardown functions;
|
||||
* new_obj must be used in its place for this purpose.
|
||||
*
|
||||
* This function is semantically identical to the new operator.
|
||||
*
|
||||
* @tparam T The type of the object to construct
|
||||
* @param[in] params The constructor parameters of T.
|
||||
* @returns The pointer to the newly constructed object.
|
||||
*/
|
||||
template<typename T, typename... Params>
|
||||
T* new_obj(Params... params) {
|
||||
T* obj = static_cast<T*>(cr_malloc(sizeof (T)));
|
||||
|
@ -53,6 +118,19 @@ namespace criterion {
|
|||
return obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocates and construct a new array of primitive types
|
||||
*
|
||||
* It is undefined behaviour to access a pointer returned by the new[]
|
||||
* operator inside a test or its setup and teardown functions;
|
||||
* new_arr must be used in its place for this purpose.
|
||||
*
|
||||
* This function is semantically identical to the new[] operator.
|
||||
*
|
||||
* @tparam T The compound type of the array to construct
|
||||
* @param[in] len The length of the array.
|
||||
* @returns The pointer to the newly constructed array.
|
||||
*/
|
||||
template<typename T>
|
||||
typename std::enable_if<std::is_fundamental<T>::value>::type*
|
||||
new_arr(size_t len) {
|
||||
|
@ -62,6 +140,19 @@ namespace criterion {
|
|||
return arr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocates and construct a new array of object types
|
||||
*
|
||||
* It is undefined behaviour to access a pointer returned by the new[]
|
||||
* operator inside a test or its setup and teardown functions;
|
||||
* new_arr must be used in its place for this purpose.
|
||||
*
|
||||
* This function is semantically identical to the new[] operator.
|
||||
*
|
||||
* @tparam T The compound type of the array to construct
|
||||
* @param[in] len The length of the array.
|
||||
* @returns The pointer to the newly constructed array.
|
||||
*/
|
||||
template<typename T>
|
||||
T* new_arr(size_t len) {
|
||||
void *ptr = cr_malloc(sizeof (size_t) + sizeof (T) * len);
|
||||
|
@ -73,27 +164,100 @@ namespace criterion {
|
|||
return arr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroys and frees an object allocated by new_obj.
|
||||
*
|
||||
* This function is semantically identical to the delete operator.
|
||||
*
|
||||
* @tparam T The type of the object to construct
|
||||
* @param[in] ptr The object to destroy.
|
||||
*/
|
||||
template<typename T>
|
||||
void delete_obj(T* ptr) {
|
||||
ptr->~T();
|
||||
cr_free(ptr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroys and frees an array allocated by delete_arr.
|
||||
*
|
||||
* This function is semantically identical to the delete[] operator.
|
||||
*
|
||||
* @tparam T The type of the object to construct
|
||||
* @param[in] ptr The object to destroy.
|
||||
*/
|
||||
template<typename T>
|
||||
void delete_arr(typename std::enable_if<std::is_fundamental<T>::value>::type* ptr) {
|
||||
cr_free(ptr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroys and frees an array allocated by delete_arr.
|
||||
*
|
||||
* This function is semantically identical to the delete[] operator.
|
||||
*
|
||||
* @tparam T The type of the object to construct
|
||||
* @param[in] ptr The object to destroy.
|
||||
*/
|
||||
template<typename T>
|
||||
void delete_arr(T* ptr) {
|
||||
size_t len = *(reinterpret_cast<size_t*>(ptr));
|
||||
T* arr = reinterpret_cast<T*>(reinterpret_cast<size_t*>(ptr) + 1);
|
||||
for (int i = 0; i < len; ++i) {
|
||||
size_t *ptr_ = reinterpret_cast<size_t*>(ptr);
|
||||
size_t len = *(ptr_ - 1);
|
||||
T* arr = reinterpret_cast<T*>(ptr_);
|
||||
for (size_t i = 0; i < len; ++i)
|
||||
arr[i].~T();
|
||||
}
|
||||
cr_free(ptr);
|
||||
cr_free(ptr_ - 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocator for use in the STL.
|
||||
*
|
||||
* This internally uses calls to the cr_malloc function family, which
|
||||
* means that STL collections can be safely used inside tests or
|
||||
* setup/teardown functions if this allocator is used.
|
||||
*/
|
||||
template<typename T>
|
||||
struct allocator {
|
||||
typedef T value_type;
|
||||
typedef value_type* pointer;
|
||||
typedef const value_type* const_pointer;
|
||||
typedef value_type& reference;
|
||||
typedef const value_type& const_reference;
|
||||
typedef std::size_t size_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
|
||||
template<typename U>
|
||||
struct rebind {
|
||||
typedef allocator<U> other;
|
||||
};
|
||||
|
||||
inline explicit allocator() {}
|
||||
inline ~allocator() {}
|
||||
inline explicit allocator(allocator const&) {}
|
||||
template<typename U>
|
||||
inline explicit allocator(allocator<U> const&) {}
|
||||
|
||||
inline pointer address(reference r) { return &r; }
|
||||
inline const_pointer address(const_reference r) { return &r; }
|
||||
|
||||
inline pointer allocate(size_type cnt, typename std::allocator<void>::const_pointer = 0) {
|
||||
return reinterpret_cast<pointer>(cr_malloc(cnt * sizeof (T)));
|
||||
}
|
||||
|
||||
inline void deallocate(pointer p, size_type) { cr_free(p); }
|
||||
|
||||
inline size_type max_size() const {
|
||||
return size_type(-1) / sizeof(T);
|
||||
}
|
||||
|
||||
inline void construct(pointer p, const T& t) { new(p) T(t); }
|
||||
inline void construct(pointer p, T&& t) { new (p) T(std::move(t)); }
|
||||
inline void destroy(pointer p) { p->~T(); }
|
||||
|
||||
inline bool operator==(allocator const&) { return true; }
|
||||
inline bool operator!=(allocator const& a) { return !operator==(a); }
|
||||
};
|
||||
|
||||
}
|
||||
# endif
|
||||
|
||||
|
|
|
@ -24,210 +24,25 @@
|
|||
#ifndef CRITERION_ASSERT_H_
|
||||
# define CRITERION_ASSERT_H_
|
||||
|
||||
# include "preprocess.h"
|
||||
# include "asprintf-compat.h"
|
||||
|
||||
# ifdef __cplusplus
|
||||
# include <cstring>
|
||||
# include <cstdlib>
|
||||
# include <algorithm>
|
||||
# else
|
||||
# include <string.h>
|
||||
# include <stdlib.h>
|
||||
# include <stdbool.h>
|
||||
# endif
|
||||
# include "designated-initializer-compat.h"
|
||||
# include "types.h"
|
||||
# include "stats.h"
|
||||
# include "hooks.h"
|
||||
# include "event.h"
|
||||
# include "abort.h"
|
||||
|
||||
struct criterion_assert_args {
|
||||
const char *msg;
|
||||
int sentinel_;
|
||||
|
||||
#ifdef __cplusplus
|
||||
constexpr criterion_assert_args(const char *msg) : msg(msg), sentinel_(0) {}
|
||||
constexpr criterion_assert_args(const char *msg, int sentinel_) : msg(msg), sentinel_(sentinel_) {}
|
||||
#endif
|
||||
};
|
||||
|
||||
// Do NOT reorder unless you want to break the ABI
|
||||
enum criterion_assert_messages {
|
||||
CRITERION_ASSERT_MSG_FAIL,
|
||||
CRITERION_ASSERT_MSG_EXPR_FALSE,
|
||||
CRITERION_ASSERT_MSG_EXPR_AS_STRINGS_FALSE,
|
||||
CRITERION_ASSERT_MSG_IS_NULL,
|
||||
CRITERION_ASSERT_MSG_IS_NOT_NULL,
|
||||
CRITERION_ASSERT_MSG_IS_EMPTY,
|
||||
CRITERION_ASSERT_MSG_IS_NOT_EMPTY,
|
||||
CRITERION_ASSERT_MSG_FILE_STR_MATCH,
|
||||
CRITERION_ASSERT_MSG_FILE_MATCH,
|
||||
CRITERION_ASSERT_MSG_THROW,
|
||||
CRITERION_ASSERT_MSG_NO_THROW,
|
||||
CRITERION_ASSERT_MSG_ANY_THROW,
|
||||
CRITERION_ASSERT_MSG_NONE_THROW,
|
||||
};
|
||||
|
||||
CR_BEGIN_C_API
|
||||
|
||||
CR_API char *translate_assert_msg(int msg_index, ...);
|
||||
|
||||
CR_END_C_API
|
||||
|
||||
# define CR_GET_CONDITION(Condition, ...) Condition
|
||||
# define CR_GET_CONDITION_STR(Condition, ...) #Condition
|
||||
# define CR_VA_SKIP(_, ...) __VA_ARGS__
|
||||
|
||||
# ifdef __cplusplus
|
||||
# define CR_STDN std::
|
||||
# else
|
||||
# define CR_STDN
|
||||
# endif
|
||||
|
||||
# define CR_TRANSLATE_DEF_MSG__(Arg) \
|
||||
CR_IDENTITY Arg
|
||||
|
||||
# define CR_TRANSLATE_DEF_MSG_(...) \
|
||||
CR_EXPAND(translate_assert_msg( \
|
||||
CR_VA_HEAD(__VA_ARGS__), \
|
||||
"" CR_TRANSLATE_DEF_MSG__(CR_VA_HEAD(CR_VA_TAIL(__VA_ARGS__))) \
|
||||
))
|
||||
|
||||
# define CR_INIT_STATS_(BufSize, MsgVar, ...) CR_EXPAND( \
|
||||
do { \
|
||||
char *def_msg = CR_EXPAND(CR_TRANSLATE_DEF_MSG_(__VA_ARGS__)); \
|
||||
char *formatted_msg = NULL; \
|
||||
int msglen = cr_asprintf(&formatted_msg, \
|
||||
"" CR_VA_TAIL(CR_VA_TAIL(__VA_ARGS__))); \
|
||||
if (formatted_msg && *formatted_msg) { \
|
||||
MsgVar = formatted_msg; \
|
||||
CR_STDN free(def_msg); \
|
||||
} else { \
|
||||
MsgVar = def_msg; \
|
||||
msglen = strlen(def_msg); \
|
||||
CR_STDN free(formatted_msg); \
|
||||
} \
|
||||
\
|
||||
BufSize = sizeof(struct criterion_assert_stats) \
|
||||
+ sizeof (size_t) + msglen + 1; \
|
||||
\
|
||||
char *buf = (char*) CR_STDN malloc(BufSize); \
|
||||
stat = (struct criterion_assert_stats*) buf; \
|
||||
CR_STDN memset(buf, 0, sizeof (struct criterion_assert_stats)); \
|
||||
buf += sizeof (struct criterion_assert_stats); \
|
||||
*((size_t*) buf) = msglen + 1; \
|
||||
buf += sizeof (size_t); \
|
||||
CR_STDN strcpy(buf, MsgVar); \
|
||||
CR_STDN free(MsgVar); \
|
||||
} while (0))
|
||||
|
||||
# define CR_FAIL_ABORT_ criterion_abort_test
|
||||
# define CR_FAIL_CONTINUES_ criterion_continue_test
|
||||
|
||||
# ifdef __GNUC__
|
||||
// We disable the format-zero-length warning because we use the validity of
|
||||
// asprintf(out, "") for empty assertion messages
|
||||
# pragma GCC diagnostic ignored "-Wformat-zero-length"
|
||||
# endif
|
||||
|
||||
# define cr_assert_impl(Fail, Condition, ...) \
|
||||
do { \
|
||||
bool passed = !!(Condition); \
|
||||
\
|
||||
char *msg = NULL; \
|
||||
size_t bufsize; \
|
||||
\
|
||||
struct criterion_assert_stats *stat; \
|
||||
CR_EXPAND(CR_INIT_STATS_(bufsize, msg, CR_VA_TAIL(__VA_ARGS__))); \
|
||||
stat->passed = passed; \
|
||||
stat->file = __FILE__; \
|
||||
stat->line = __LINE__; \
|
||||
\
|
||||
send_event(ASSERT, stat, bufsize); \
|
||||
CR_STDN free(stat); \
|
||||
\
|
||||
if (!passed) \
|
||||
Fail(); \
|
||||
} while (0)
|
||||
# include "internal/assert.h"
|
||||
|
||||
// Base assertions
|
||||
|
||||
# define cr_fail(Fail, ...) \
|
||||
CR_EXPAND(cr_assert_impl( \
|
||||
Fail, \
|
||||
0, \
|
||||
dummy, \
|
||||
CRITERION_ASSERT_MSG_FAIL, \
|
||||
(), \
|
||||
__VA_ARGS__ \
|
||||
))
|
||||
|
||||
# define cr_assert_fail(...) CR_EXPAND(cr_fail(CR_FAIL_ABORT_, __VA_ARGS__))
|
||||
# define cr_expect_fail(...) CR_EXPAND(cr_fail(CR_FAIL_CONTINUES_, __VA_ARGS__))
|
||||
|
||||
# define cr_assert(...) \
|
||||
CR_EXPAND(cr_assert_impl( \
|
||||
CR_FAIL_ABORT_, \
|
||||
CR_VA_HEAD(__VA_ARGS__), \
|
||||
dummy, \
|
||||
CRITERION_ASSERT_MSG_EXPR_FALSE, \
|
||||
(CR_STR(CR_VA_HEAD(__VA_ARGS__))), \
|
||||
CR_VA_TAIL(__VA_ARGS__) \
|
||||
))
|
||||
# define cr_assert(...) CR_EXPAND(cr_assert_(__VA_ARGS__))
|
||||
# define cr_expect(...) CR_EXPAND(cr_expect_(__VA_ARGS__))
|
||||
|
||||
# define cr_expect(...) \
|
||||
CR_EXPAND(cr_assert_impl( \
|
||||
CR_FAIL_CONTINUES_, \
|
||||
CR_VA_HEAD(__VA_ARGS__), \
|
||||
dummy, \
|
||||
CRITERION_ASSERT_MSG_EXPR_FALSE, \
|
||||
(CR_STR(CR_VA_HEAD(__VA_ARGS__))), \
|
||||
CR_VA_TAIL(__VA_ARGS__) \
|
||||
))
|
||||
|
||||
# define cr_assert_not(...) \
|
||||
CR_EXPAND(cr_assert_impl( \
|
||||
CR_FAIL_ABORT_, \
|
||||
!(CR_VA_HEAD(__VA_ARGS__)), \
|
||||
dummy, \
|
||||
CRITERION_ASSERT_MSG_EXPR_FALSE, \
|
||||
(CR_STR(!(CR_VA_HEAD(__VA_ARGS__)))), \
|
||||
CR_VA_TAIL(__VA_ARGS__) \
|
||||
))
|
||||
|
||||
# define cr_expect_not(...) \
|
||||
CR_EXPAND(cr_assert_impl( \
|
||||
CR_FAIL_CONTINUES_, \
|
||||
!(CR_VA_HEAD(__VA_ARGS__)), \
|
||||
dummy, \
|
||||
CRITERION_ASSERT_MSG_EXPR_FALSE, \
|
||||
(CR_STR(!(CR_VA_HEAD(__VA_ARGS__)))), \
|
||||
CR_VA_TAIL(__VA_ARGS__) \
|
||||
))
|
||||
# define cr_assert_not(...) CR_EXPAND(cr_assert_not_(__VA_ARGS__))
|
||||
# define cr_expect_not(...) CR_EXPAND(cr_expect_not_(__VA_ARGS__))
|
||||
|
||||
// Common binary assertions
|
||||
|
||||
# define cr_assert_op_(Fail, Op, Actual, Expected, ...) \
|
||||
CR_EXPAND(cr_assert_impl( \
|
||||
Fail, \
|
||||
(Actual) Op (Expected), \
|
||||
dummy, \
|
||||
CRITERION_ASSERT_MSG_EXPR_FALSE, \
|
||||
(CR_STR((Actual) Op (Expected))), \
|
||||
__VA_ARGS__ \
|
||||
))
|
||||
|
||||
# define cr_assert_op_va_(Fail, Op, ...) \
|
||||
CR_EXPAND(cr_assert_op_( \
|
||||
Fail, \
|
||||
Op, \
|
||||
CR_VA_HEAD(__VA_ARGS__), \
|
||||
CR_VA_HEAD(CR_VA_TAIL(__VA_ARGS__)), \
|
||||
CR_VA_TAIL(CR_VA_TAIL(__VA_ARGS__)) \
|
||||
))
|
||||
|
||||
# define cr_assert_eq(...) CR_EXPAND(cr_assert_op_va_(CR_FAIL_ABORT_, ==, __VA_ARGS__))
|
||||
# define cr_expect_eq(...) CR_EXPAND(cr_assert_op_va_(CR_FAIL_CONTINUES_, ==, __VA_ARGS__))
|
||||
|
||||
|
@ -248,25 +63,6 @@ CR_END_C_API
|
|||
|
||||
// Common unary assertions
|
||||
|
||||
# define cr_assert_null_op_(Fail, Op, Msg, Value, ...) \
|
||||
CR_EXPAND(cr_assert_impl( \
|
||||
Fail, \
|
||||
(Value) Op NULL, \
|
||||
dummy, \
|
||||
Msg, \
|
||||
(CR_STR(Value)), \
|
||||
__VA_ARGS__ \
|
||||
))
|
||||
|
||||
# define cr_assert_null_op_va_(Fail, Op, Msg, ...) \
|
||||
CR_EXPAND(cr_assert_null_op_( \
|
||||
Fail, \
|
||||
Op, \
|
||||
Msg, \
|
||||
CR_VA_HEAD(__VA_ARGS__), \
|
||||
CR_VA_TAIL(__VA_ARGS__) \
|
||||
))
|
||||
|
||||
# define cr_assert_null(...) CR_EXPAND(cr_assert_null_op_va_(CR_FAIL_ABORT_, ==, CRITERION_ASSERT_MSG_IS_NOT_NULL, __VA_ARGS__))
|
||||
# define cr_expect_null(...) CR_EXPAND(cr_assert_null_op_va_(CR_FAIL_CONTINUES_, ==, CRITERION_ASSERT_MSG_IS_NOT_NULL, __VA_ARGS__))
|
||||
|
||||
|
@ -275,32 +71,6 @@ CR_END_C_API
|
|||
|
||||
// Floating-point assertions
|
||||
|
||||
# define cr_assert_float_eq_op_(Actual, Expected, Epsilon) \
|
||||
(Expected) - (Actual) <= (Epsilon) && (Actual) - (Expected) <= (Epsilon)
|
||||
|
||||
# define cr_assert_float_neq_op_(Actual, Expected, Epsilon) \
|
||||
(Expected) - (Actual) > (Epsilon) || (Actual) - (Expected) > (Epsilon)
|
||||
|
||||
# define cr_assert_float_op_(Fail, Op, Actual, Expected, Epsilon, ...) \
|
||||
CR_EXPAND(cr_assert_impl( \
|
||||
Fail, \
|
||||
Op(Actual, Expected, Epsilon), \
|
||||
dummy, \
|
||||
CRITERION_ASSERT_MSG_EXPR_FALSE, \
|
||||
(CR_STR(Op(Actual, Expected, Epsilon))), \
|
||||
__VA_ARGS__ \
|
||||
))
|
||||
|
||||
# define cr_assert_float_op_va_(Fail, Op, ...) \
|
||||
CR_EXPAND(cr_assert_float_op_( \
|
||||
Fail, \
|
||||
Op, \
|
||||
CR_VA_HEAD(__VA_ARGS__), \
|
||||
CR_VA_HEAD(CR_VA_TAIL(__VA_ARGS__)), \
|
||||
CR_VA_HEAD(CR_VA_TAIL(CR_VA_TAIL(__VA_ARGS__))), \
|
||||
CR_VA_TAIL(CR_VA_TAIL(CR_VA_TAIL(__VA_ARGS__))) \
|
||||
))
|
||||
|
||||
# define cr_assert_float_eq(...) CR_EXPAND(cr_assert_float_op_va_(CR_FAIL_ABORT_, cr_assert_float_eq_op_, __VA_ARGS__))
|
||||
# define cr_expect_float_eq(...) CR_EXPAND(cr_assert_float_op_va_(CR_FAIL_CONTINUES_, cr_assert_float_eq_op_, __VA_ARGS__))
|
||||
|
||||
|
@ -309,50 +79,12 @@ CR_END_C_API
|
|||
|
||||
// String assertions
|
||||
|
||||
# define cr_assert_str_op_empty_(Fail, Op, Msg, Value, ...) \
|
||||
CR_EXPAND(cr_assert_impl( \
|
||||
Fail, \
|
||||
(Value)[0] Op '\0', \
|
||||
dummy, \
|
||||
Msg, \
|
||||
(CR_STR(Value)), \
|
||||
__VA_ARGS__ \
|
||||
))
|
||||
|
||||
# define cr_assert_str_op_empty_va_(Fail, Op, Msg, ...) \
|
||||
CR_EXPAND(cr_assert_str_op_empty_( \
|
||||
Fail, \
|
||||
Op, \
|
||||
Msg, \
|
||||
CR_VA_HEAD(__VA_ARGS__), \
|
||||
CR_VA_TAIL(__VA_ARGS__) \
|
||||
))
|
||||
|
||||
# define cr_assert_str_empty(...) CR_EXPAND(cr_assert_str_op_empty_va_(CR_FAIL_ABORT_, ==, CRITERION_ASSERT_MSG_IS_NOT_EMPTY, __VA_ARGS__))
|
||||
# define cr_expect_str_empty(...) CR_EXPAND(cr_assert_str_op_empty_va_(CR_FAIL_CONTINUES_, ==, CRITERION_ASSERT_MSG_IS_NOT_EMPTY, __VA_ARGS__))
|
||||
|
||||
# define cr_assert_str_not_empty(...) CR_EXPAND(cr_assert_str_op_empty_va_(CR_FAIL_ABORT_, !=, CRITERION_ASSERT_MSG_IS_EMPTY, __VA_ARGS__))
|
||||
# define cr_expect_str_not_empty(...) CR_EXPAND(cr_assert_str_op_empty_va_(CR_FAIL_CONTINUES_, !=, CRITERION_ASSERT_MSG_IS_EMPTY, __VA_ARGS__))
|
||||
|
||||
# define cr_assert_str_op_(Fail, Op, Actual, Expected, ...) \
|
||||
CR_EXPAND(cr_assert_impl( \
|
||||
Fail, \
|
||||
CR_STDN strcmp((Actual), (Expected)) Op 0, \
|
||||
dummy, \
|
||||
CRITERION_ASSERT_MSG_EXPR_AS_STRINGS_FALSE, \
|
||||
(CR_STR((Actual) Op (Expected))), \
|
||||
__VA_ARGS__ \
|
||||
))
|
||||
|
||||
# define cr_assert_str_op_va_(Fail, Op, ...) \
|
||||
CR_EXPAND(cr_assert_str_op_( \
|
||||
Fail, \
|
||||
Op, \
|
||||
CR_VA_HEAD(__VA_ARGS__), \
|
||||
CR_VA_HEAD(CR_VA_TAIL(__VA_ARGS__)), \
|
||||
CR_VA_TAIL(CR_VA_TAIL(__VA_ARGS__)) \
|
||||
))
|
||||
|
||||
# define cr_assert_str_eq(...) CR_EXPAND(cr_assert_str_op_va_(CR_FAIL_ABORT_, ==, __VA_ARGS__))
|
||||
# define cr_expect_str_eq(...) CR_EXPAND(cr_assert_str_op_va_(CR_FAIL_CONTINUES_, ==, __VA_ARGS__))
|
||||
|
||||
|
@ -373,26 +105,6 @@ CR_END_C_API
|
|||
|
||||
// Array assertions
|
||||
|
||||
# define cr_assert_mem_op_(Fail, Op, Actual, Expected, Size, ...) \
|
||||
CR_EXPAND(cr_assert_impl( \
|
||||
Fail, \
|
||||
CR_STDN memcmp((Actual), (Expected), (Size)) Op 0, \
|
||||
dummy, \
|
||||
CRITERION_ASSERT_MSG_EXPR_FALSE, \
|
||||
(CR_STR((Actual)[0 .. Size] Op (Expected)[0 .. Size])), \
|
||||
__VA_ARGS__ \
|
||||
))
|
||||
|
||||
# define cr_assert_mem_op_va_(Fail, Op, ...) \
|
||||
CR_EXPAND(cr_assert_mem_op_( \
|
||||
Fail, \
|
||||
Op, \
|
||||
CR_VA_HEAD(__VA_ARGS__), \
|
||||
CR_VA_HEAD(CR_VA_TAIL(__VA_ARGS__)), \
|
||||
CR_VA_HEAD(CR_VA_TAIL(CR_VA_TAIL(__VA_ARGS__))), \
|
||||
CR_VA_TAIL(CR_VA_TAIL(CR_VA_TAIL(__VA_ARGS__))) \
|
||||
))
|
||||
|
||||
# define cr_assert_arr_eq(...) CR_EXPAND(cr_assert_mem_op_va_(CR_FAIL_ABORT_, ==, __VA_ARGS__))
|
||||
# define cr_expect_arr_eq(...) CR_EXPAND(cr_assert_mem_op_va_(CR_FAIL_CONTINUES_, ==, __VA_ARGS__))
|
||||
|
||||
|
@ -401,44 +113,7 @@ CR_END_C_API
|
|||
|
||||
// Safe array comparison assertions
|
||||
|
||||
# if defined(__GNUC__) || defined(__cplusplus)
|
||||
|
||||
# ifdef __cplusplus
|
||||
# define CR_ARR_COMPARE_(A, B, Size, Cmp, Result) \
|
||||
int Result = std::lexicographical_compare((A), (A) + Size, (B), (B) + Size, Cmp)
|
||||
# else
|
||||
# define CR_ARR_COMPARE_(A, B, Size, Cmp, Result) \
|
||||
__typeof__(&(A)[0]) first = (A); \
|
||||
__typeof__(&(B)[0]) second = (B); \
|
||||
int Result = 0; \
|
||||
size_t i, size; \
|
||||
for (i = 0, size = (Size); !Result && i < size; ++i) \
|
||||
Result = Cmp(first + i, second + i)
|
||||
# endif
|
||||
|
||||
# define cr_assert_arr_op_cmp_(Fail, Op, Actual, Expected, Size, Cmp, ...) \
|
||||
do { \
|
||||
CR_ARR_COMPARE_(Actual, Expected, Size, Cmp, order); \
|
||||
CR_EXPAND(cr_assert_impl( \
|
||||
Fail, \
|
||||
order Op 0, \
|
||||
dummy, \
|
||||
CRITERION_ASSERT_MSG_EXPR_FALSE, \
|
||||
(CR_STR((Actual)[0 .. Size] Op (Expected)[0 .. Size])), \
|
||||
__VA_ARGS__ \
|
||||
)); \
|
||||
} while (0)
|
||||
|
||||
# define cr_assert_arr_op_cmp_va_(Fail, Op, ...) \
|
||||
CR_EXPAND(cr_assert_arr_op_cmp_( \
|
||||
Fail, \
|
||||
Op, \
|
||||
CR_VA_HEAD(__VA_ARGS__), \
|
||||
CR_VA_HEAD(CR_VA_TAIL(__VA_ARGS__)), \
|
||||
CR_VA_HEAD(CR_VA_TAIL(CR_VA_TAIL(__VA_ARGS__))), \
|
||||
CR_VA_HEAD(CR_VA_TAIL(CR_VA_TAIL(CR_VA_TAIL(__VA_ARGS__)))), \
|
||||
CR_VA_TAIL(CR_VA_TAIL(CR_VA_TAIL(CR_VA_TAIL(__VA_ARGS__)))) \
|
||||
))
|
||||
# if defined(__GNUC__) || defined(__clang__) || defined(__cplusplus)
|
||||
|
||||
# define cr_assert_arr_eq_cmp(...) CR_EXPAND(cr_assert_arr_op_cmp_va_(CR_FAIL_ABORT_, ==, __VA_ARGS__))
|
||||
# define cr_expect_arr_eq_cmp(...) CR_EXPAND(cr_assert_arr_op_cmp_va_(CR_FAIL_CONTINUES_, ==, __VA_ARGS__))
|
||||
|
@ -460,14 +135,6 @@ CR_END_C_API
|
|||
|
||||
# else
|
||||
|
||||
# define CRITERION_GNUC_WARN__(Msg) \
|
||||
_Pragma(#Msg)
|
||||
|
||||
# define CRITERION_GNUC_WARN_(Name) CRITERION_GNUC_WARN__( \
|
||||
message \
|
||||
"The `" #Name "` macro is only available on GNU C compilers." \
|
||||
)
|
||||
|
||||
# define cr_assert_arr_eq_cmp(...) CRITERION_GNUC_WARN_(cr_assert_arr_eq_cmp) CR_NOOP
|
||||
# define cr_expect_arr_eq_cmp(...) CRITERION_GNUC_WARN_(cr_expect_arr_eq_cmp) CR_NOOP
|
||||
|
||||
|
@ -490,103 +157,15 @@ CR_END_C_API
|
|||
|
||||
# ifdef __cplusplus
|
||||
|
||||
# define cr_assert_throw_abort_(Fail, Msg, MsgArgs, ...) \
|
||||
CR_EXPAND(cr_assert_impl( \
|
||||
Fail, \
|
||||
0, \
|
||||
dummy, \
|
||||
Msg, \
|
||||
MsgArgs, \
|
||||
CR_VA_TAIL(__VA_ARGS__) \
|
||||
))
|
||||
|
||||
# define cr_assert_throw_(Fail, Statement, Exception, ...) \
|
||||
try { \
|
||||
Statement; \
|
||||
} catch (Exception const &) { \
|
||||
} catch (...) { \
|
||||
CR_EXPAND(cr_assert_throw_abort_( \
|
||||
Fail, \
|
||||
CRITERION_ASSERT_MSG_NO_THROW, \
|
||||
(CR_STR(Statement), CR_STR(Exception)), \
|
||||
__VA_ARGS__)); \
|
||||
}
|
||||
|
||||
# define cr_assert_throw_va_(...) \
|
||||
CR_EXPAND(cr_assert_throw_( \
|
||||
CR_VA_HEAD(__VA_ARGS__), \
|
||||
CR_VA_HEAD(CR_VA_TAIL(__VA_ARGS__)), \
|
||||
CR_VA_HEAD(CR_VA_TAIL(CR_VA_TAIL(__VA_ARGS__))), \
|
||||
dummy, \
|
||||
CR_VA_TAIL(CR_VA_TAIL(CR_VA_TAIL(__VA_ARGS__))) \
|
||||
))
|
||||
|
||||
# define cr_assert_throw(...) CR_EXPAND(cr_assert_throw_va_(CR_FAIL_ABORT_, __VA_ARGS__))
|
||||
# define cr_expect_throw(...) CR_EXPAND(cr_assert_throw_va_(CR_FAIL_CONTINUES_, __VA_ARGS__))
|
||||
|
||||
# define cr_assert_no_throw_(Fail, Statement, Exception, ...) \
|
||||
try { \
|
||||
Statement; \
|
||||
} catch (Exception const &) { \
|
||||
CR_EXPAND(cr_assert_throw_abort_( \
|
||||
Fail, \
|
||||
CRITERION_ASSERT_MSG_THROW, \
|
||||
(CR_STR(Statement), CR_STR(Exception)), \
|
||||
__VA_ARGS__)); \
|
||||
}
|
||||
|
||||
# define cr_assert_no_throw_va_(...) \
|
||||
CR_EXPAND(cr_assert_no_throw_( \
|
||||
CR_VA_HEAD(__VA_ARGS__), \
|
||||
CR_VA_HEAD(CR_VA_TAIL(__VA_ARGS__)), \
|
||||
CR_VA_HEAD(CR_VA_TAIL(CR_VA_TAIL(__VA_ARGS__))), \
|
||||
dummy, \
|
||||
CR_VA_TAIL(CR_VA_TAIL(CR_VA_TAIL(__VA_ARGS__))) \
|
||||
))
|
||||
|
||||
# define cr_assert_no_throw(...) CR_EXPAND(cr_assert_no_throw_va_(CR_FAIL_ABORT_, __VA_ARGS__))
|
||||
# define cr_expect_no_throw(...) CR_EXPAND(cr_assert_no_throw_va_(CR_FAIL_CONTINUES_, __VA_ARGS__))
|
||||
|
||||
# define cr_assert_any_throw_(Fail, Statement, ...) \
|
||||
try { \
|
||||
Statement; \
|
||||
CR_EXPAND(cr_assert_throw_abort_( \
|
||||
Fail, \
|
||||
CRITERION_ASSERT_MSG_ANY_THROW, \
|
||||
(CR_STR(Statement)), \
|
||||
__VA_ARGS__)); \
|
||||
} catch (...) {}
|
||||
|
||||
# define cr_assert_any_throw_va_(...) \
|
||||
CR_EXPAND(cr_assert_any_throw_( \
|
||||
CR_VA_HEAD(__VA_ARGS__), \
|
||||
CR_VA_HEAD(CR_VA_TAIL(__VA_ARGS__)), \
|
||||
dummy, \
|
||||
CR_VA_TAIL(CR_VA_TAIL(__VA_ARGS__)) \
|
||||
))
|
||||
|
||||
# define cr_assert_any_throw(...) CR_EXPAND(cr_assert_any_throw_va_(CR_FAIL_ABORT_, __VA_ARGS__))
|
||||
# define cr_expect_any_throw(...) CR_EXPAND(cr_assert_any_throw_va_(CR_FAIL_CONTINUES_, __VA_ARGS__))
|
||||
|
||||
# define cr_assert_none_throw_(Fail, Statement, ...) \
|
||||
try { \
|
||||
Statement; \
|
||||
} catch (...) { \
|
||||
CR_EXPAND(cr_assert_throw_abort_( \
|
||||
Fail, \
|
||||
CRITERION_ASSERT_MSG_NONE_THROW, \
|
||||
(CR_STR(Statement)), \
|
||||
__VA_ARGS__)); \
|
||||
}
|
||||
|
||||
# define cr_assert_none_throw_va_(...) \
|
||||
CR_EXPAND(cr_assert_none_throw_( \
|
||||
CR_VA_HEAD(__VA_ARGS__), \
|
||||
CR_VA_HEAD(CR_VA_TAIL(__VA_ARGS__)), \
|
||||
dummy, \
|
||||
CR_VA_TAIL(CR_VA_TAIL(__VA_ARGS__)) \
|
||||
))
|
||||
|
||||
# define cr_assert_none_throw(...) CR_EXPAND(cr_assert_none_throw_va_(CR_FAIL_ABORT_, __VA_ARGS__))
|
||||
# define cr_expect_none_throw(...) CR_EXPAND(cr_assert_none_throw_va_(CR_FAIL_CONTINUES_, __VA_ARGS__))
|
||||
|
||||
|
@ -596,12 +175,6 @@ CR_END_C_API
|
|||
// It shall be removed in the next major version of Criterion
|
||||
# ifndef CRITERION_NO_COMPAT
|
||||
|
||||
# define CRITERION_ASSERT_DEPRECATED_(Name) CRITERION_ASSERT_DEPRECATED__( \
|
||||
message \
|
||||
("The `" #Name "` macro is deprecated, " \
|
||||
"please use `cr_" #Name "` instead.") \
|
||||
)
|
||||
|
||||
# define CRITERION_ASSERT_DEPRECATED_B(Name, Newname) \
|
||||
CRITERION_ASSERT_DEPRECATED__( \
|
||||
message \
|
||||
|
@ -617,16 +190,6 @@ CR_END_C_API
|
|||
_Pragma(#Msg)
|
||||
# endif
|
||||
|
||||
# ifndef assert
|
||||
# define assert(...) CRITERION_ASSERT_DEPRECATED_(assert) cr_assert(__VA_ARGS__)
|
||||
|
||||
// this is needed to make the POSIX assert.h redefine assert if
|
||||
// subsequently included
|
||||
# ifndef _ASSERT_H
|
||||
# define _ASSERT_H 1
|
||||
# endif /* !_ASSERT_H */
|
||||
# endif /* !assert */
|
||||
|
||||
// scheduled for removal after 2.0
|
||||
# define cr_abort_test(Message) CRITERION_ASSERT_DEPRECATED_B(cr_abort_test, cr_assert_fail) cr_assert_fail(Message)
|
||||
# define cr_assert_strings_eq(...) CRITERION_ASSERT_DEPRECATED_B(cr_assert_strings_eq, cr_assert_str_eq) cr_assert_str_eq(__VA_ARGS__)
|
||||
|
@ -642,52 +205,6 @@ CR_END_C_API
|
|||
# define cr_assert_arrays_eq_cmp(...) CRITERION_ASSERT_DEPRECATED_B(cr_assert_arrays_eq_cmp, cr_assert_arr_eq_cmp) cr_assert_arr_eq_cmp(__VA_ARGS__)
|
||||
# define cr_assert_arrays_neq_cmp(...) CRITERION_ASSERT_DEPRECATED_B(cr_assert_arrays_neq_cmp, cr_assert_arr_neq_cmp) cr_assert_arr_neq_cmp(__VA_ARGS__)
|
||||
|
||||
// scheduled for removal at 2.0
|
||||
# define abort_test(Message) CRITERION_ASSERT_DEPRECATED_(abort_test) cr_abort_test(Message)
|
||||
# define expect(...) CRITERION_ASSERT_DEPRECATED_(expect) cr_expect(__VA_ARGS__)
|
||||
# define assert_not(...) CRITERION_ASSERT_DEPRECATED_(assert_not) cr_assert_not(__VA_ARGS__)
|
||||
# define expect_not(...) CRITERION_ASSERT_DEPRECATED_(expect_not) cr_expect_not(__VA_ARGS__)
|
||||
# define assert_eq(...) CRITERION_ASSERT_DEPRECATED_(assert_eq) cr_assert_eq(__VA_ARGS__)
|
||||
# define expect_eq(...) CRITERION_ASSERT_DEPRECATED_(expect_eq) cr_expect_eq(__VA_ARGS__)
|
||||
# define assert_neq(...) CRITERION_ASSERT_DEPRECATED_(assert_neq) cr_assert_neq(__VA_ARGS__)
|
||||
# define expect_neq(...) CRITERION_ASSERT_DEPRECATED_(expect_neq) cr_expect_neq(__VA_ARGS__)
|
||||
# define assert_lt(...) CRITERION_ASSERT_DEPRECATED_(assert_lt) cr_assert_lt(__VA_ARGS__)
|
||||
# define expect_lt(...) CRITERION_ASSERT_DEPRECATED_(expect_lt) cr_expect_lt(__VA_ARGS__)
|
||||
# define assert_gt(...) CRITERION_ASSERT_DEPRECATED_(assert_gt) cr_assert_gt(__VA_ARGS__)
|
||||
# define expect_gt(...) CRITERION_ASSERT_DEPRECATED_(expect_gt) cr_expect_gt(__VA_ARGS__)
|
||||
# define assert_leq(...) CRITERION_ASSERT_DEPRECATED_(assert_leq) cr_assert_leq(__VA_ARGS__)
|
||||
# define expect_leq(...) CRITERION_ASSERT_DEPRECATED_(expect_leq) cr_expect_leq(__VA_ARGS__)
|
||||
# define assert_geq(...) CRITERION_ASSERT_DEPRECATED_(assert_geq) cr_assert_geq(__VA_ARGS__)
|
||||
# define expect_geq(...) CRITERION_ASSERT_DEPRECATED_(expect_geq) cr_expect_geq(__VA_ARGS__)
|
||||
# define assert_null(...) CRITERION_ASSERT_DEPRECATED_(assert_null) cr_assert_null(__VA_ARGS__)
|
||||
# define expect_null(...) CRITERION_ASSERT_DEPRECATED_(expect_null) cr_expect_null(__VA_ARGS__)
|
||||
# define assert_not_null(...) CRITERION_ASSERT_DEPRECATED_(assert_not_null) cr_assert_not_null(__VA_ARGS__)
|
||||
# define expect_not_null(...) CRITERION_ASSERT_DEPRECATED_(expect_not_null) cr_expect_not_null(__VA_ARGS__)
|
||||
# define assert_float_eq(...) CRITERION_ASSERT_DEPRECATED_(assert_float_eq) cr_assert_float_eq(__VA_ARGS__)
|
||||
# define expect_float_eq(...) CRITERION_ASSERT_DEPRECATED_(expect_float_eq) cr_expect_float_eq(__VA_ARGS__)
|
||||
# define assert_float_neq(...) CRITERION_ASSERT_DEPRECATED_(assert_float_neq) cr_assert_float_neq(__VA_ARGS__)
|
||||
# define expect_float_neq(...) CRITERION_ASSERT_DEPRECATED_(expect_float_neq) cr_expect_float_neq(__VA_ARGS__)
|
||||
# define assert_strings_eq(...) CRITERION_ASSERT_DEPRECATED_(assert_strings_eq) cr_assert_strings_eq(__VA_ARGS__)
|
||||
# define expect_strings_eq(...) CRITERION_ASSERT_DEPRECATED_(expect_strings_eq) cr_expect_strings_eq(__VA_ARGS__)
|
||||
# define assert_strings_neq(...) CRITERION_ASSERT_DEPRECATED_(assert_strings_neq) cr_assert_strings_neq(__VA_ARGS__)
|
||||
# define expect_strings_neq(...) CRITERION_ASSERT_DEPRECATED_(expect_strings_neq) cr_expect_strings_neq(__VA_ARGS__)
|
||||
# define assert_strings_gt(...) CRITERION_ASSERT_DEPRECATED_(assert_strings_gt) cr_assert_strings_gt(__VA_ARGS__)
|
||||
# define expect_strings_gt(...) CRITERION_ASSERT_DEPRECATED_(expect_strings_gt) cr_expect_strings_gt(__VA_ARGS__)
|
||||
# define assert_strings_lt(...) CRITERION_ASSERT_DEPRECATED_(assert_strings_lt) cr_assert_strings_lt(__VA_ARGS__)
|
||||
# define expect_strings_lt(...) CRITERION_ASSERT_DEPRECATED_(expect_strings_lt) cr_expect_strings_lt(__VA_ARGS__)
|
||||
# define assert_strings_leq(...) CRITERION_ASSERT_DEPRECATED_(assert_strings_leq) cr_assert_strings_leq(__VA_ARGS__)
|
||||
# define expect_strings_leq(...) CRITERION_ASSERT_DEPRECATED_(expect_strings_leq) cr_expect_strings_leq(__VA_ARGS__)
|
||||
# define assert_strings_geq(...) CRITERION_ASSERT_DEPRECATED_(assert_strings_geq) cr_assert_strings_geq(__VA_ARGS__)
|
||||
# define expect_strings_geq(...) CRITERION_ASSERT_DEPRECATED_(expect_strings_geq) cr_expect_strings_geq(__VA_ARGS__)
|
||||
# define assert_arrays_eq(...) CRITERION_ASSERT_DEPRECATED_(assert_arrays_eq) cr_assert_arrays_eq(__VA_ARGS__)
|
||||
# define expect_arrays_eq(...) CRITERION_ASSERT_DEPRECATED_(expect_arrays_eq) cr_expect_arrays_eq(__VA_ARGS__)
|
||||
# define assert_arrays_neq(...) CRITERION_ASSERT_DEPRECATED_(assert_arrays_neq) cr_assert_arrays_neq(__VA_ARGS__)
|
||||
# define expect_arrays_neq(...) CRITERION_ASSERT_DEPRECATED_(expect_arrays_neq) cr_expect_arrays_neq(__VA_ARGS__)
|
||||
# define assert_arrays_eq_cmp(...) CRITERION_ASSERT_DEPRECATED_(assert_arrays_eq_cmp) cr_assert_arrays_eq_cmp(__VA_ARGS__)
|
||||
# define expect_arrays_eq_cmp(...) CRITERION_ASSERT_DEPRECATED_(expect_arrays_eq_cmp) cr_expect_arrays_eq_cmp(__VA_ARGS__)
|
||||
# define assert_arrays_neq_cmp(...) CRITERION_ASSERT_DEPRECATED_(assert_arrays_neq_cmp) cr_assert_arrays_neq_cmp(__VA_ARGS__)
|
||||
# define expect_arrays_neq_cmp(...) CRITERION_ASSERT_DEPRECATED_(expect_arrays_neq_cmp) cr_expect_arrays_neq_cmp(__VA_ARGS__)
|
||||
|
||||
# endif
|
||||
|
||||
#endif /* !CRITERION_ASSERT_H_ */
|
||||
|
|
|
@ -24,74 +24,98 @@
|
|||
#ifndef CRITERION_H_
|
||||
# define CRITERION_H_
|
||||
|
||||
# include "designated-initializer-compat.h"
|
||||
# include "common.h"
|
||||
# include "types.h"
|
||||
# include "assert.h"
|
||||
# include "alloc.h"
|
||||
|
||||
# define IDENTIFIER_(Category, Name, Suffix) \
|
||||
Category ## _ ## Name ## _ ## Suffix
|
||||
# include "internal/test.h"
|
||||
|
||||
# ifdef __cplusplus
|
||||
# define TEST_PROTOTYPE_(Category, Name) \
|
||||
extern "C" void IDENTIFIER_(Category, Name, impl)(void)
|
||||
# else
|
||||
# define TEST_PROTOTYPE_(Category, Name) \
|
||||
void IDENTIFIER_(Category, Name, impl)(void)
|
||||
# endif
|
||||
/**
|
||||
* Test(Suite, Name, [Options...]) { Function body }
|
||||
*
|
||||
* Defines a new test.
|
||||
*
|
||||
* @param Suite The name of the test suite containing this test.
|
||||
* @param Name The name of the test.
|
||||
* @param Options An optional sequence of designated initializer key/value
|
||||
* pairs as described in the `criterion_test_extra_data` structure
|
||||
* (see criterion/types.h).
|
||||
* Example: .exit_code = 1
|
||||
*/
|
||||
# define Test(...) CR_EXPAND(CR_TEST_BASE(__VA_ARGS__, .sentinel_ = 0))
|
||||
|
||||
# define SUITE_IDENTIFIER_(Name, Suffix) \
|
||||
suite_ ## Name ## _ ## Suffix
|
||||
|
||||
# define Test(...) CR_EXPAND(Test_(__VA_ARGS__, .sentinel_ = 0))
|
||||
# define Test_(Category, Name, ...) \
|
||||
TEST_PROTOTYPE_(Category, Name); \
|
||||
struct criterion_test_extra_data IDENTIFIER_(Category, Name, extra) = \
|
||||
CR_EXPAND(CRITERION_MAKE_STRUCT(struct criterion_test_extra_data, \
|
||||
.kind_ = CR_TEST_NORMAL, \
|
||||
.param_ = (struct criterion_test_params(*)(void)) NULL, \
|
||||
.identifier_ = #Category "/" #Name, \
|
||||
.file_ = __FILE__, \
|
||||
.line_ = __LINE__, \
|
||||
__VA_ARGS__ \
|
||||
)); \
|
||||
struct criterion_test IDENTIFIER_(Category, Name, meta) = { \
|
||||
#Name, \
|
||||
#Category, \
|
||||
IDENTIFIER_(Category, Name, impl), \
|
||||
&IDENTIFIER_(Category, Name, extra) \
|
||||
}; \
|
||||
SECTION_("cr_tst") \
|
||||
struct criterion_test *IDENTIFIER_(Category, Name, ptr) \
|
||||
= &IDENTIFIER_(Category, Name, meta) SECTION_SUFFIX_; \
|
||||
TEST_PROTOTYPE_(Category, Name)
|
||||
|
||||
# define TestSuite(...) CR_EXPAND(TestSuite_(__VA_ARGS__, .sentinel_ = 0))
|
||||
# define TestSuite_(Name, ...) \
|
||||
struct criterion_test_extra_data SUITE_IDENTIFIER_(Name, extra) = \
|
||||
CR_EXPAND(CRITERION_MAKE_STRUCT(struct criterion_test_extra_data, \
|
||||
.file_ = __FILE__, \
|
||||
.line_ = 0, \
|
||||
__VA_ARGS__ \
|
||||
)); \
|
||||
struct criterion_suite SUITE_IDENTIFIER_(Name, meta) = { \
|
||||
#Name, \
|
||||
&SUITE_IDENTIFIER_(Name, extra), \
|
||||
}; \
|
||||
SECTION_("cr_sts") \
|
||||
struct criterion_suite *SUITE_IDENTIFIER_(Name, ptr) \
|
||||
= &SUITE_IDENTIFIER_(Name, meta) SECTION_SUFFIX_
|
||||
/**
|
||||
* TestSuite(Name, [Options...]);
|
||||
*
|
||||
* Explicitely defines a test suite and its options.
|
||||
*
|
||||
* @param Name The name of the test suite.
|
||||
* @param Options An optional sequence of designated initializer key/value
|
||||
* pairs as described in the `criterion_test_extra_data` structure
|
||||
* (see criterion/types.h).
|
||||
* These options will provide the defaults for each test.
|
||||
*/
|
||||
# define TestSuite(...) CR_EXPAND(CR_SUITE_BASE(__VA_ARGS__, .sentinel_ = 0))
|
||||
|
||||
CR_BEGIN_C_API
|
||||
|
||||
/**
|
||||
* Initializes criterion and builds a set of all discovered tests.
|
||||
*
|
||||
* Using any of the functions and macros provided by criterion before calling
|
||||
* this results in undefined behaviour.
|
||||
*
|
||||
* @returns the set of tests
|
||||
*/
|
||||
CR_API struct criterion_test_set *criterion_initialize(void);
|
||||
|
||||
/**
|
||||
* Release all resources allocated by criterion.
|
||||
*
|
||||
* Using any of the functions and macros provided by criterion except
|
||||
* criterion_initialize after this function is called results in undefined
|
||||
* behaviour.
|
||||
*/
|
||||
CR_API void criterion_finalize(struct criterion_test_set *tests);
|
||||
|
||||
/**
|
||||
* Run all the tests in the test set.
|
||||
*
|
||||
* @param[in] tests The set of tests that are to be executed.
|
||||
*
|
||||
* @returns 1 if all tests succeeded or criterion_options.always_succeed
|
||||
* is true, 0 otherwise.
|
||||
*/
|
||||
CR_API int criterion_run_all_tests(struct criterion_test_set *tests);
|
||||
|
||||
/**
|
||||
* Handles all default command-line parameters, as documented in:
|
||||
* <http://criterion.readthedocs.org/en/latest/env.html>, and appropriately
|
||||
* sets criterion_options.
|
||||
*
|
||||
* @param[in] argc The number of arguments in argv.
|
||||
* @param[in] argv A null-terminated array of strings representing the arguments.
|
||||
* @param[in] handle_unknown_arg Whether the function should print a message
|
||||
* and exit when an unknown parameter is encountered. Use false if you want
|
||||
* to handle additional parameters yourself.
|
||||
*
|
||||
* @returns 0 if the process should exit immediately after, for instance after
|
||||
* printing the help message.
|
||||
*/
|
||||
CR_API int criterion_handle_args(int argc, char *argv[], bool handle_unknown_arg);
|
||||
|
||||
/**
|
||||
* Manually registers a new test within the specified test set.
|
||||
*
|
||||
* @param[in] tests The set of tests you want to insert the test in.
|
||||
* @param[in] test The newly created test.
|
||||
*/
|
||||
CR_API void criterion_register_test(struct criterion_test_set *tests,
|
||||
struct criterion_test *test);
|
||||
|
||||
extern const struct criterion_test *const criterion_current_test;
|
||||
extern const struct criterion_suite *const criterion_current_suite;
|
||||
|
||||
CR_END_C_API
|
||||
|
||||
#endif /* !CRITERION_H_ */
|
||||
|
|
|
@ -29,11 +29,11 @@
|
|||
# else
|
||||
# include <stddef.h>
|
||||
# endif
|
||||
# include "common.h"
|
||||
# include "internal/common.h"
|
||||
|
||||
CR_BEGIN_C_API
|
||||
|
||||
CR_API void send_event(int kind, void *data, size_t size);
|
||||
CR_API void criterion_send_event(int kind, void *data, size_t size);
|
||||
|
||||
CR_END_C_API
|
||||
|
||||
|
|
|
@ -24,9 +24,11 @@
|
|||
#ifndef CRITERION_HOOKS_H_
|
||||
# define CRITERION_HOOKS_H_
|
||||
|
||||
# include "common.h"
|
||||
# include "types.h"
|
||||
# include "internal/hooks.h"
|
||||
|
||||
/**
|
||||
* This enum lists all the phases of the runner lifecycle.
|
||||
*/
|
||||
typedef enum {
|
||||
PRE_ALL,
|
||||
PRE_SUITE,
|
||||
|
@ -43,57 +45,24 @@ typedef enum {
|
|||
|
||||
typedef void (*f_report_hook)();
|
||||
|
||||
# define HOOK_IDENTIFIER_(Suffix) HOOK_IDENTIFIER__(__LINE__, Suffix)
|
||||
# define HOOK_IDENTIFIER__(Line, Suffix) HOOK_IDENTIFIER___(Line, Suffix)
|
||||
# define HOOK_IDENTIFIER___(Line, Suffix) hook_l ## Line ## _ ## Suffix
|
||||
|
||||
# ifdef __cplusplus
|
||||
# define HOOK_PROTOTYPE_ \
|
||||
extern "C" void HOOK_IDENTIFIER_(impl)
|
||||
# else
|
||||
# define HOOK_PROTOTYPE_ \
|
||||
void HOOK_IDENTIFIER_(impl)
|
||||
# endif
|
||||
|
||||
// Section abbreviations
|
||||
# define HOOK_SECTION_PRE_ALL cr_pra
|
||||
# define HOOK_SECTION_PRE_SUITE cr_prs
|
||||
# define HOOK_SECTION_PRE_INIT cr_pri
|
||||
# define HOOK_SECTION_PRE_TEST cr_prt
|
||||
# define HOOK_SECTION_ASSERT cr_ast
|
||||
# define HOOK_SECTION_THEORY_FAIL cr_thf
|
||||
# define HOOK_SECTION_TEST_CRASH cr_tsc
|
||||
# define HOOK_SECTION_POST_TEST cr_pot
|
||||
# define HOOK_SECTION_POST_FINI cr_pof
|
||||
# define HOOK_SECTION_POST_SUITE cr_pos
|
||||
# define HOOK_SECTION_POST_ALL cr_poa
|
||||
|
||||
# define HOOK_SECTION(Kind) HOOK_SECTION_ ## Kind
|
||||
|
||||
# define HOOK_SECTION_STRINGIFY__(Sec) #Sec
|
||||
# define HOOK_SECTION_STRINGIFY_(Sec) HOOK_SECTION_STRINGIFY__(Sec)
|
||||
# define HOOK_SECTION_STRINGIFY(Kind) HOOK_SECTION_STRINGIFY_(HOOK_SECTION(Kind))
|
||||
|
||||
# define HOOK_PARAM_TYPE_PRE_ALL struct criterion_test_set *
|
||||
# define HOOK_PARAM_TYPE_PRE_SUITE struct criterion_suite_set *
|
||||
# define HOOK_PARAM_TYPE_PRE_INIT struct criterion_test *
|
||||
# define HOOK_PARAM_TYPE_PRE_TEST struct criterion_test *
|
||||
# define HOOK_PARAM_TYPE_ASSERT struct criterion_assert_stats *
|
||||
# define HOOK_PARAM_TYPE_THEORY_FAIL struct criterion_theory_stats *
|
||||
# define HOOK_PARAM_TYPE_TEST_CRASH struct criterion_test_stats *
|
||||
# define HOOK_PARAM_TYPE_POST_TEST struct criterion_test_stats *
|
||||
# define HOOK_PARAM_TYPE_POST_FINI struct criterion_test_stats *
|
||||
# define HOOK_PARAM_TYPE_POST_SUITE struct criterion_suite_stats *
|
||||
# define HOOK_PARAM_TYPE_POST_ALL struct criterion_global_stats *
|
||||
|
||||
# define HOOK_PARAM_TYPE(Kind) HOOK_PARAM_TYPE_ ## Kind
|
||||
|
||||
# define ReportHook(Kind) \
|
||||
HOOK_PROTOTYPE_(HOOK_PARAM_TYPE(Kind)); \
|
||||
SECTION_(HOOK_SECTION_STRINGIFY(Kind)) \
|
||||
f_report_hook HOOK_IDENTIFIER_(func) = \
|
||||
(f_report_hook) HOOK_IDENTIFIER_(impl) \
|
||||
SECTION_SUFFIX_; \
|
||||
HOOK_PROTOTYPE_
|
||||
/**
|
||||
* ReportHook(Kind)(Type *param) { Function Body }
|
||||
*
|
||||
* Defines a report hook for the phase defined by Kind.
|
||||
*
|
||||
* The type of the parameter depends on the phase:
|
||||
*
|
||||
* - struct criterion_test_set for PRE_ALL.
|
||||
* - struct criterion_suite_set for PRE_SUITE.
|
||||
* - struct criterion_test for PRE_INIT and PRE_TEST.
|
||||
* - struct criterion_assert_stats for ASSERT.
|
||||
* - struct criterion_theory_stats for THEORY_FAIL.
|
||||
* - struct criterion_test_stats for POST_TEST, POST_FINI, and TEST_CRASH.
|
||||
* - struct criterion_suite_stats for POST_SUITE.
|
||||
* - struct criterion_global_stats for POST_ALL.
|
||||
*
|
||||
* @param Kind The report phase to hook the function onto.
|
||||
*/
|
||||
# define ReportHook(Kind) CR_REPORT_HOOK_IMPL(Kind)
|
||||
|
||||
#endif /* !CRITERION_HOOKS_H_ */
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
|
||||
CR_BEGIN_C_API
|
||||
|
||||
FORMAT(printf, 2, 3)
|
||||
CR_FORMAT(printf, 2, 3)
|
||||
CR_API int cr_asprintf(char **strp, const char *fmt, ...);
|
||||
CR_API int cr_vasprintf(char **strp, const char *fmt, va_list ap);
|
||||
|
477
include/criterion/internal/assert.h
Normal file
477
include/criterion/internal/assert.h
Normal file
|
@ -0,0 +1,477 @@
|
|||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright © 2015 Franklin "Snaipe" Mathieu <http://snai.pe/>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
#ifndef CRITERION_INTERNAL_ASSERT_H_
|
||||
# define CRITERION_INTERNAL_ASSERT_H_
|
||||
|
||||
# include "common.h"
|
||||
# include "preprocess.h"
|
||||
# include "asprintf-compat.h"
|
||||
# include "designated-initializer-compat.h"
|
||||
|
||||
# ifdef __cplusplus
|
||||
# include <cstring>
|
||||
# include <cstdlib>
|
||||
# else
|
||||
# include <string.h>
|
||||
# include <stdlib.h>
|
||||
# include <stdbool.h>
|
||||
# endif
|
||||
# include "../types.h"
|
||||
# include "../stats.h"
|
||||
# include "../hooks.h"
|
||||
# include "../event.h"
|
||||
# include "../abort.h"
|
||||
|
||||
struct criterion_assert_args {
|
||||
const char *msg;
|
||||
int sentinel_;
|
||||
|
||||
#ifdef __cplusplus
|
||||
constexpr criterion_assert_args(const char *msg) : msg(msg), sentinel_(0) {}
|
||||
constexpr criterion_assert_args(const char *msg, int sentinel_) : msg(msg), sentinel_(sentinel_) {}
|
||||
#endif
|
||||
};
|
||||
|
||||
// Do NOT reorder unless you want to break the ABI
|
||||
enum criterion_assert_messages {
|
||||
CRITERION_ASSERT_MSG_FAIL,
|
||||
CRITERION_ASSERT_MSG_EXPR_FALSE,
|
||||
CRITERION_ASSERT_MSG_EXPR_AS_STRINGS_FALSE,
|
||||
CRITERION_ASSERT_MSG_IS_NULL,
|
||||
CRITERION_ASSERT_MSG_IS_NOT_NULL,
|
||||
CRITERION_ASSERT_MSG_IS_EMPTY,
|
||||
CRITERION_ASSERT_MSG_IS_NOT_EMPTY,
|
||||
CRITERION_ASSERT_MSG_FILE_STR_MATCH,
|
||||
CRITERION_ASSERT_MSG_FILE_MATCH,
|
||||
CRITERION_ASSERT_MSG_THROW,
|
||||
CRITERION_ASSERT_MSG_NO_THROW,
|
||||
CRITERION_ASSERT_MSG_ANY_THROW,
|
||||
CRITERION_ASSERT_MSG_NONE_THROW,
|
||||
};
|
||||
|
||||
CR_BEGIN_C_API
|
||||
|
||||
CR_API char *cr_translate_assert_msg(int msg_index, ...);
|
||||
|
||||
CR_END_C_API
|
||||
|
||||
# define CR_GET_CONDITION(Condition, ...) Condition
|
||||
# define CR_GET_CONDITION_STR(Condition, ...) #Condition
|
||||
# define CR_VA_SKIP(_, ...) __VA_ARGS__
|
||||
|
||||
# ifdef __cplusplus
|
||||
# define CR_STDN std::
|
||||
# else
|
||||
# define CR_STDN
|
||||
# endif
|
||||
|
||||
# define CR_TRANSLATE_DEF_MSG__(Arg) \
|
||||
CR_IDENTITY Arg
|
||||
|
||||
# define CR_TRANSLATE_DEF_MSG_(...) \
|
||||
CR_EXPAND(cr_translate_assert_msg( \
|
||||
CR_VA_HEAD(__VA_ARGS__), \
|
||||
"" CR_TRANSLATE_DEF_MSG__(CR_VA_HEAD(CR_VA_TAIL(__VA_ARGS__))) \
|
||||
))
|
||||
|
||||
# define CR_INIT_STATS_(BufSize, MsgVar, ...) CR_EXPAND( \
|
||||
do { \
|
||||
char *def_msg = CR_EXPAND(CR_TRANSLATE_DEF_MSG_(__VA_ARGS__)); \
|
||||
char *formatted_msg = NULL; \
|
||||
int msglen = cr_asprintf(&formatted_msg, \
|
||||
"" CR_VA_TAIL(CR_VA_TAIL(__VA_ARGS__))); \
|
||||
if (formatted_msg && *formatted_msg) { \
|
||||
MsgVar = formatted_msg; \
|
||||
CR_STDN free(def_msg); \
|
||||
} else { \
|
||||
MsgVar = def_msg; \
|
||||
msglen = strlen(def_msg); \
|
||||
CR_STDN free(formatted_msg); \
|
||||
} \
|
||||
\
|
||||
BufSize = sizeof(struct criterion_assert_stats) \
|
||||
+ sizeof (size_t) + msglen + 1; \
|
||||
\
|
||||
char *buf = (char*) CR_STDN malloc(BufSize); \
|
||||
stat = (struct criterion_assert_stats*) buf; \
|
||||
CR_STDN memset(buf, 0, sizeof (struct criterion_assert_stats)); \
|
||||
buf += sizeof (struct criterion_assert_stats); \
|
||||
*((size_t*) buf) = msglen + 1; \
|
||||
buf += sizeof (size_t); \
|
||||
CR_STDN strcpy(buf, MsgVar); \
|
||||
CR_STDN free(MsgVar); \
|
||||
} while (0))
|
||||
|
||||
# define CR_FAIL_ABORT_ criterion_abort_test
|
||||
# define CR_FAIL_CONTINUES_ criterion_continue_test
|
||||
|
||||
# if defined(__GNUC__) || defined(__clang__)
|
||||
// We disable the format-zero-length warning because we use the validity of
|
||||
// asprintf(out, "") for empty assertion messages
|
||||
# pragma GCC diagnostic ignored "-Wformat-zero-length"
|
||||
# endif
|
||||
|
||||
# define cr_assert_impl(Fail, Condition, ...) \
|
||||
do { \
|
||||
bool passed = !!(Condition); \
|
||||
\
|
||||
char *msg = NULL; \
|
||||
size_t bufsize; \
|
||||
\
|
||||
struct criterion_assert_stats *stat; \
|
||||
CR_EXPAND(CR_INIT_STATS_(bufsize, msg, CR_VA_TAIL(__VA_ARGS__))); \
|
||||
stat->passed = passed; \
|
||||
stat->file = __FILE__; \
|
||||
stat->line = __LINE__; \
|
||||
\
|
||||
criterion_send_event(ASSERT, stat, bufsize); \
|
||||
CR_STDN free(stat); \
|
||||
\
|
||||
if (!passed) \
|
||||
Fail(); \
|
||||
} while (0)
|
||||
|
||||
# define cr_fail(Fail, ...) \
|
||||
CR_EXPAND(cr_assert_impl( \
|
||||
Fail, \
|
||||
0, \
|
||||
dummy, \
|
||||
CRITERION_ASSERT_MSG_FAIL, \
|
||||
(), \
|
||||
__VA_ARGS__ \
|
||||
))
|
||||
|
||||
# define cr_assert_(...) \
|
||||
CR_EXPAND(cr_assert_impl( \
|
||||
CR_FAIL_ABORT_, \
|
||||
CR_VA_HEAD(__VA_ARGS__), \
|
||||
dummy, \
|
||||
CRITERION_ASSERT_MSG_EXPR_FALSE, \
|
||||
(CR_STR(CR_VA_HEAD(__VA_ARGS__))), \
|
||||
CR_VA_TAIL(__VA_ARGS__) \
|
||||
))
|
||||
|
||||
# define cr_expect_(...) \
|
||||
CR_EXPAND(cr_assert_impl( \
|
||||
CR_FAIL_CONTINUES_, \
|
||||
CR_VA_HEAD(__VA_ARGS__), \
|
||||
dummy, \
|
||||
CRITERION_ASSERT_MSG_EXPR_FALSE, \
|
||||
(CR_STR(CR_VA_HEAD(__VA_ARGS__))), \
|
||||
CR_VA_TAIL(__VA_ARGS__) \
|
||||
))
|
||||
|
||||
# define cr_assert_not_(...) \
|
||||
CR_EXPAND(cr_assert_impl( \
|
||||
CR_FAIL_ABORT_, \
|
||||
!(CR_VA_HEAD(__VA_ARGS__)), \
|
||||
dummy, \
|
||||
CRITERION_ASSERT_MSG_EXPR_FALSE, \
|
||||
(CR_STR(!(CR_VA_HEAD(__VA_ARGS__)))), \
|
||||
CR_VA_TAIL(__VA_ARGS__) \
|
||||
))
|
||||
|
||||
# define cr_expect_not_(...) \
|
||||
CR_EXPAND(cr_assert_impl( \
|
||||
CR_FAIL_CONTINUES_, \
|
||||
!(CR_VA_HEAD(__VA_ARGS__)), \
|
||||
dummy, \
|
||||
CRITERION_ASSERT_MSG_EXPR_FALSE, \
|
||||
(CR_STR(!(CR_VA_HEAD(__VA_ARGS__)))), \
|
||||
CR_VA_TAIL(__VA_ARGS__) \
|
||||
))
|
||||
|
||||
|
||||
// Binary
|
||||
|
||||
# define cr_assert_op_(Fail, Op, Actual, Expected, ...) \
|
||||
CR_EXPAND(cr_assert_impl( \
|
||||
Fail, \
|
||||
(Actual) Op (Expected), \
|
||||
dummy, \
|
||||
CRITERION_ASSERT_MSG_EXPR_FALSE, \
|
||||
(CR_STR((Actual) Op (Expected))), \
|
||||
__VA_ARGS__ \
|
||||
))
|
||||
|
||||
# define cr_assert_op_va_(Fail, Op, ...) \
|
||||
CR_EXPAND(cr_assert_op_( \
|
||||
Fail, \
|
||||
Op, \
|
||||
CR_VA_HEAD(__VA_ARGS__), \
|
||||
CR_VA_HEAD(CR_VA_TAIL(__VA_ARGS__)), \
|
||||
CR_VA_TAIL(CR_VA_TAIL(__VA_ARGS__)) \
|
||||
))
|
||||
|
||||
// Unary
|
||||
|
||||
# define cr_assert_null_op_(Fail, Op, Msg, Value, ...) \
|
||||
CR_EXPAND(cr_assert_impl( \
|
||||
Fail, \
|
||||
(Value) Op NULL, \
|
||||
dummy, \
|
||||
Msg, \
|
||||
(CR_STR(Value)), \
|
||||
__VA_ARGS__ \
|
||||
))
|
||||
|
||||
# define cr_assert_null_op_va_(Fail, Op, Msg, ...) \
|
||||
CR_EXPAND(cr_assert_null_op_( \
|
||||
Fail, \
|
||||
Op, \
|
||||
Msg, \
|
||||
CR_VA_HEAD(__VA_ARGS__), \
|
||||
CR_VA_TAIL(__VA_ARGS__) \
|
||||
))
|
||||
|
||||
// Floating point
|
||||
|
||||
# define cr_assert_float_eq_op_(Actual, Expected, Epsilon) \
|
||||
(Expected) - (Actual) <= (Epsilon) && (Actual) - (Expected) <= (Epsilon)
|
||||
|
||||
# define cr_assert_float_neq_op_(Actual, Expected, Epsilon) \
|
||||
(Expected) - (Actual) > (Epsilon) || (Actual) - (Expected) > (Epsilon)
|
||||
|
||||
# define cr_assert_float_op_(Fail, Op, Actual, Expected, Epsilon, ...) \
|
||||
CR_EXPAND(cr_assert_impl( \
|
||||
Fail, \
|
||||
Op(Actual, Expected, Epsilon), \
|
||||
dummy, \
|
||||
CRITERION_ASSERT_MSG_EXPR_FALSE, \
|
||||
(CR_STR(Op(Actual, Expected, Epsilon))), \
|
||||
__VA_ARGS__ \
|
||||
))
|
||||
|
||||
# define cr_assert_float_op_va_(Fail, Op, ...) \
|
||||
CR_EXPAND(cr_assert_float_op_( \
|
||||
Fail, \
|
||||
Op, \
|
||||
CR_VA_HEAD(__VA_ARGS__), \
|
||||
CR_VA_HEAD(CR_VA_TAIL(__VA_ARGS__)), \
|
||||
CR_VA_HEAD(CR_VA_TAIL(CR_VA_TAIL(__VA_ARGS__))), \
|
||||
CR_VA_TAIL(CR_VA_TAIL(CR_VA_TAIL(__VA_ARGS__))) \
|
||||
))
|
||||
|
||||
// String
|
||||
|
||||
# define cr_assert_str_op_empty_(Fail, Op, Msg, Value, ...) \
|
||||
CR_EXPAND(cr_assert_impl( \
|
||||
Fail, \
|
||||
(Value)[0] Op '\0', \
|
||||
dummy, \
|
||||
Msg, \
|
||||
(CR_STR(Value)), \
|
||||
__VA_ARGS__ \
|
||||
))
|
||||
|
||||
# define cr_assert_str_op_empty_va_(Fail, Op, Msg, ...) \
|
||||
CR_EXPAND(cr_assert_str_op_empty_( \
|
||||
Fail, \
|
||||
Op, \
|
||||
Msg, \
|
||||
CR_VA_HEAD(__VA_ARGS__), \
|
||||
CR_VA_TAIL(__VA_ARGS__) \
|
||||
))
|
||||
|
||||
# define cr_assert_str_op_(Fail, Op, Actual, Expected, ...) \
|
||||
CR_EXPAND(cr_assert_impl( \
|
||||
Fail, \
|
||||
CR_STDN strcmp((Actual), (Expected)) Op 0, \
|
||||
dummy, \
|
||||
CRITERION_ASSERT_MSG_EXPR_AS_STRINGS_FALSE, \
|
||||
(CR_STR((Actual) Op (Expected))), \
|
||||
__VA_ARGS__ \
|
||||
))
|
||||
|
||||
# define cr_assert_str_op_va_(Fail, Op, ...) \
|
||||
CR_EXPAND(cr_assert_str_op_( \
|
||||
Fail, \
|
||||
Op, \
|
||||
CR_VA_HEAD(__VA_ARGS__), \
|
||||
CR_VA_HEAD(CR_VA_TAIL(__VA_ARGS__)), \
|
||||
CR_VA_TAIL(CR_VA_TAIL(__VA_ARGS__)) \
|
||||
))
|
||||
|
||||
// Array
|
||||
|
||||
# define cr_assert_mem_op_(Fail, Op, Actual, Expected, Size, ...) \
|
||||
CR_EXPAND(cr_assert_impl( \
|
||||
Fail, \
|
||||
CR_STDN memcmp((Actual), (Expected), (Size)) Op 0, \
|
||||
dummy, \
|
||||
CRITERION_ASSERT_MSG_EXPR_FALSE, \
|
||||
(CR_STR((Actual)[0 .. Size] Op (Expected)[0 .. Size])), \
|
||||
__VA_ARGS__ \
|
||||
))
|
||||
|
||||
# define cr_assert_mem_op_va_(Fail, Op, ...) \
|
||||
CR_EXPAND(cr_assert_mem_op_( \
|
||||
Fail, \
|
||||
Op, \
|
||||
CR_VA_HEAD(__VA_ARGS__), \
|
||||
CR_VA_HEAD(CR_VA_TAIL(__VA_ARGS__)), \
|
||||
CR_VA_HEAD(CR_VA_TAIL(CR_VA_TAIL(__VA_ARGS__))), \
|
||||
CR_VA_TAIL(CR_VA_TAIL(CR_VA_TAIL(__VA_ARGS__))) \
|
||||
))
|
||||
|
||||
// Array comparisons
|
||||
|
||||
# ifdef __cplusplus
|
||||
# define CR_ARR_COMPARE_(A, B, Size, Cmp, Result) \
|
||||
int Result = std::lexicographical_compare((A), (A) + Size, (B), (B) + Size, Cmp)
|
||||
# else
|
||||
# define CR_ARR_COMPARE_(A, B, Size, Cmp, Result) \
|
||||
__typeof__(&(A)[0]) first = (A); \
|
||||
__typeof__(&(B)[0]) second = (B); \
|
||||
int Result = 0; \
|
||||
size_t i, size; \
|
||||
for (i = 0, size = (Size); !Result && i < size; ++i) \
|
||||
Result = Cmp(first + i, second + i)
|
||||
# endif
|
||||
|
||||
# define cr_assert_arr_op_cmp_(Fail, Op, Actual, Expected, Size, Cmp, ...) \
|
||||
do { \
|
||||
CR_ARR_COMPARE_(Actual, Expected, Size, Cmp, order); \
|
||||
CR_EXPAND(cr_assert_impl( \
|
||||
Fail, \
|
||||
order Op 0, \
|
||||
dummy, \
|
||||
CRITERION_ASSERT_MSG_EXPR_FALSE, \
|
||||
(CR_STR((Actual)[0 .. Size] Op (Expected)[0 .. Size])), \
|
||||
__VA_ARGS__ \
|
||||
)); \
|
||||
} while (0)
|
||||
|
||||
# define cr_assert_arr_op_cmp_va_(Fail, Op, ...) \
|
||||
CR_EXPAND(cr_assert_arr_op_cmp_( \
|
||||
Fail, \
|
||||
Op, \
|
||||
CR_VA_HEAD(__VA_ARGS__), \
|
||||
CR_VA_HEAD(CR_VA_TAIL(__VA_ARGS__)), \
|
||||
CR_VA_HEAD(CR_VA_TAIL(CR_VA_TAIL(__VA_ARGS__))), \
|
||||
CR_VA_HEAD(CR_VA_TAIL(CR_VA_TAIL(CR_VA_TAIL(__VA_ARGS__)))), \
|
||||
CR_VA_TAIL(CR_VA_TAIL(CR_VA_TAIL(CR_VA_TAIL(__VA_ARGS__)))) \
|
||||
))
|
||||
|
||||
// Exceptions
|
||||
|
||||
# define cr_assert_throw_abort_(Fail, Msg, MsgArgs, ...) \
|
||||
CR_EXPAND(cr_assert_impl( \
|
||||
Fail, \
|
||||
0, \
|
||||
dummy, \
|
||||
Msg, \
|
||||
MsgArgs, \
|
||||
CR_VA_TAIL(__VA_ARGS__) \
|
||||
))
|
||||
|
||||
# define cr_assert_throw_(Fail, Statement, Exception, ...) \
|
||||
try { \
|
||||
Statement; \
|
||||
} catch (Exception const &) { \
|
||||
} catch (...) { \
|
||||
CR_EXPAND(cr_assert_throw_abort_( \
|
||||
Fail, \
|
||||
CRITERION_ASSERT_MSG_NO_THROW, \
|
||||
(CR_STR(Statement), CR_STR(Exception)), \
|
||||
__VA_ARGS__)); \
|
||||
}
|
||||
|
||||
# define cr_assert_throw_va_(...) \
|
||||
CR_EXPAND(cr_assert_throw_( \
|
||||
CR_VA_HEAD(__VA_ARGS__), \
|
||||
CR_VA_HEAD(CR_VA_TAIL(__VA_ARGS__)), \
|
||||
CR_VA_HEAD(CR_VA_TAIL(CR_VA_TAIL(__VA_ARGS__))), \
|
||||
dummy, \
|
||||
CR_VA_TAIL(CR_VA_TAIL(CR_VA_TAIL(__VA_ARGS__))) \
|
||||
))
|
||||
|
||||
# define cr_assert_no_throw_(Fail, Statement, Exception, ...) \
|
||||
try { \
|
||||
Statement; \
|
||||
} catch (Exception const &) { \
|
||||
CR_EXPAND(cr_assert_throw_abort_( \
|
||||
Fail, \
|
||||
CRITERION_ASSERT_MSG_THROW, \
|
||||
(CR_STR(Statement), CR_STR(Exception)), \
|
||||
__VA_ARGS__)); \
|
||||
}
|
||||
|
||||
# define cr_assert_no_throw_va_(...) \
|
||||
CR_EXPAND(cr_assert_no_throw_( \
|
||||
CR_VA_HEAD(__VA_ARGS__), \
|
||||
CR_VA_HEAD(CR_VA_TAIL(__VA_ARGS__)), \
|
||||
CR_VA_HEAD(CR_VA_TAIL(CR_VA_TAIL(__VA_ARGS__))), \
|
||||
dummy, \
|
||||
CR_VA_TAIL(CR_VA_TAIL(CR_VA_TAIL(__VA_ARGS__))) \
|
||||
))
|
||||
|
||||
# define cr_assert_any_throw_(Fail, Statement, ...) \
|
||||
try { \
|
||||
Statement; \
|
||||
CR_EXPAND(cr_assert_throw_abort_( \
|
||||
Fail, \
|
||||
CRITERION_ASSERT_MSG_ANY_THROW, \
|
||||
(CR_STR(Statement)), \
|
||||
__VA_ARGS__)); \
|
||||
} catch (...) {}
|
||||
|
||||
# define cr_assert_any_throw_va_(...) \
|
||||
CR_EXPAND(cr_assert_any_throw_( \
|
||||
CR_VA_HEAD(__VA_ARGS__), \
|
||||
CR_VA_HEAD(CR_VA_TAIL(__VA_ARGS__)), \
|
||||
dummy, \
|
||||
CR_VA_TAIL(CR_VA_TAIL(__VA_ARGS__)) \
|
||||
))
|
||||
|
||||
# define cr_assert_none_throw_(Fail, Statement, ...) \
|
||||
try { \
|
||||
Statement; \
|
||||
} catch (...) { \
|
||||
CR_EXPAND(cr_assert_throw_abort_( \
|
||||
Fail, \
|
||||
CRITERION_ASSERT_MSG_NONE_THROW, \
|
||||
(CR_STR(Statement)), \
|
||||
__VA_ARGS__)); \
|
||||
}
|
||||
|
||||
# define cr_assert_none_throw_va_(...) \
|
||||
CR_EXPAND(cr_assert_none_throw_( \
|
||||
CR_VA_HEAD(__VA_ARGS__), \
|
||||
CR_VA_HEAD(CR_VA_TAIL(__VA_ARGS__)), \
|
||||
dummy, \
|
||||
CR_VA_TAIL(CR_VA_TAIL(__VA_ARGS__)) \
|
||||
))
|
||||
|
||||
// Messages
|
||||
|
||||
# define CRITERION_GNUC_WARN__(Msg) \
|
||||
_Pragma(#Msg)
|
||||
|
||||
# define CRITERION_GNUC_WARN_(Name) CRITERION_GNUC_WARN__( \
|
||||
message \
|
||||
"The `" #Name "` macro is only available on GNU C compilers." \
|
||||
)
|
||||
|
||||
#endif /* !CRITERION_INTERNAL_ASSERT_H_ */
|
|
@ -42,7 +42,11 @@
|
|||
# endif
|
||||
|
||||
# ifdef __cplusplus
|
||||
# define CR_ATTRIBUTE(Arg) [[gnu::Arg]]
|
||||
# ifdef __GNUC__
|
||||
# define CR_ATTRIBUTE(Arg) __attribute__((Arg))
|
||||
# else
|
||||
# define CR_ATTRIBUTE(Arg) [[gnu::Arg]]
|
||||
# endif
|
||||
# define CR_BEGIN_C_API extern "C" {
|
||||
# define CR_END_C_API }
|
||||
# else
|
||||
|
@ -52,74 +56,74 @@
|
|||
# endif
|
||||
|
||||
# ifdef __APPLE__
|
||||
# define SECTION_START_PREFIX __first
|
||||
# define SECTION_END_PREFIX __last
|
||||
# define SECTION_START_SUFFIX(Name) __asm("section$start$__DATA$" Name)
|
||||
# define SECTION_END_SUFFIX(Name) __asm("section$end$__DATA$" Name)
|
||||
# define SECTION_(Name) CR_ATTRIBUTE(section("__DATA," Name))
|
||||
# define SECTION_SUFFIX_
|
||||
# define CR_SECTION_START_PREFIX __first
|
||||
# define CR_SECTION_END_PREFIX __last
|
||||
# define CR_SECTION_START_SUFFIX(Name) __asm("section$start$__DATA$" Name)
|
||||
# define CR_SECTION_END_SUFFIX(Name) __asm("section$end$__DATA$" Name)
|
||||
# define CR_SECTION_(Name) CR_ATTRIBUTE(section("__DATA," Name))
|
||||
# define CR_SECTION_SUFFIX_
|
||||
# elif CR_IS_MSVC
|
||||
# define SECTION_START_PREFIX __start
|
||||
# define SECTION_END_PREFIX __stop
|
||||
# define SECTION_START_SUFFIX(Name)
|
||||
# define SECTION_END_SUFFIX(Name)
|
||||
# define SECTION_(Name) \
|
||||
# define CR_SECTION_START_PREFIX __start
|
||||
# define CR_SECTION_END_PREFIX __stop
|
||||
# define CR_SECTION_START_SUFFIX(Name)
|
||||
# define CR_SECTION_END_SUFFIX(Name)
|
||||
# define CR_SECTION_(Name) \
|
||||
__pragma(data_seg(push)) \
|
||||
__pragma(section(Name, read)) \
|
||||
__declspec(allocate(Name))
|
||||
# define SECTION_SUFFIX_ \
|
||||
# define CR_SECTION_SUFFIX_ \
|
||||
__pragma(data_seg(pop))
|
||||
# else
|
||||
# define SECTION_START_PREFIX __start
|
||||
# define SECTION_END_PREFIX __stop
|
||||
# define SECTION_START_SUFFIX(Name)
|
||||
# define SECTION_END_SUFFIX(Name)
|
||||
# define SECTION_(Name) CR_ATTRIBUTE(section(Name))
|
||||
# define SECTION_SUFFIX_
|
||||
# define CR_SECTION_START_PREFIX __start
|
||||
# define CR_SECTION_END_PREFIX __stop
|
||||
# define CR_SECTION_START_SUFFIX(Name)
|
||||
# define CR_SECTION_END_SUFFIX(Name)
|
||||
# define CR_SECTION_(Name) CR_ATTRIBUTE(section(Name))
|
||||
# define CR_SECTION_SUFFIX_
|
||||
# endif
|
||||
|
||||
# define MAKE_IDENTIFIER_(Prefix, Id) MAKE_IDENTIFIER__(Prefix, Id)
|
||||
# define MAKE_IDENTIFIER__(Prefix, Id) Prefix ## _ ## Id
|
||||
# define CR_MAKE_IDENTIFIER_(Prefix, Id) CR_MAKE_IDENTIFIER__(Prefix, Id)
|
||||
# define CR_MAKE_IDENTIFIER__(Prefix, Id) Prefix ## _ ## Id
|
||||
|
||||
# define SECTION_START_(Name) MAKE_IDENTIFIER_(SECTION_START_PREFIX, Name)
|
||||
# define SECTION_END_(Name) MAKE_IDENTIFIER_(SECTION_END_PREFIX, Name)
|
||||
# define CR_SECTION_START_(Name) CR_MAKE_IDENTIFIER_(CR_SECTION_START_PREFIX, Name)
|
||||
# define CR_SECTION_END_(Name) CR_MAKE_IDENTIFIER_(CR_SECTION_END_PREFIX, Name)
|
||||
|
||||
# define SECTION_START(Name) g_ ## Name ## _section_start
|
||||
# define SECTION_END(Name) g_ ## Name ## _section_end
|
||||
# define CR_SECTION_START(Name) g_ ## Name ## _section_start
|
||||
# define CR_SECTION_END(Name) g_ ## Name ## _section_end
|
||||
|
||||
# define DECL_SECTION_LIMITS(Type, Name) DECL_SECTION_LIMITS_(Type, Name)
|
||||
# define DECL_SECTION_LIMITS_(Type, Name) \
|
||||
extern Type SECTION_START_(Name) SECTION_START_SUFFIX(#Name); \
|
||||
extern Type SECTION_END_(Name) SECTION_END_SUFFIX(#Name)
|
||||
# define CR_DECL_SECTION_LIMITS(Type, Name) CR_DECL_SECTION_LIMITS_(Type, Name)
|
||||
# define CR_DECL_SECTION_LIMITS_(Type, Name) \
|
||||
extern Type CR_SECTION_START_(Name) CR_SECTION_START_SUFFIX(#Name); \
|
||||
extern Type CR_SECTION_END_(Name) CR_SECTION_END_SUFFIX(#Name)
|
||||
|
||||
# define IMPL_SECTION_LIMITS(Type, Name) \
|
||||
Type *const SECTION_START(Name) = &SECTION_START_(Name); \
|
||||
Type *const SECTION_END(Name) = &SECTION_END_(Name)
|
||||
# define CR_IMPL_SECTION_LIMITS(Type, Name) \
|
||||
Type *const CR_SECTION_START(Name) = &CR_SECTION_START_(Name); \
|
||||
Type *const CR_SECTION_END(Name) = &CR_SECTION_END_(Name)
|
||||
|
||||
# ifdef __GNUC__
|
||||
# define UNUSED CR_ATTRIBUTE(unused)
|
||||
# define NORETURN CR_ATTRIBUTE(noreturn)
|
||||
# define CR_UNUSED CR_ATTRIBUTE(unused)
|
||||
# define CR_NORETURN CR_ATTRIBUTE(noreturn)
|
||||
# define CR_INLINE CR_ATTRIBUTE(always_inline) inline
|
||||
# elif CR_IS_MSVC
|
||||
# define UNUSED
|
||||
# define NORETURN __declspec(noreturn)
|
||||
# define CR_UNUSED __pragma(warning(suppress:4100))
|
||||
# define CR_NORETURN __declspec(noreturn)
|
||||
# define CR_INLINE __forceinline
|
||||
# else
|
||||
# define UNUSED
|
||||
# define NORETURN
|
||||
# define CR_UNUSED
|
||||
# define CR_NORETURN
|
||||
# define CR_INLINE inline
|
||||
# endif
|
||||
|
||||
# ifdef _WIN32
|
||||
# define SIZE_T_FORMAT "%Iu"
|
||||
# define CR_SIZE_T_FORMAT "%Iu"
|
||||
# else
|
||||
# define SIZE_T_FORMAT "%zu"
|
||||
# define CR_SIZE_T_FORMAT "%zu"
|
||||
# endif
|
||||
|
||||
# ifdef __GNUC__
|
||||
# define FORMAT(Archetype, Index, Ftc) CR_ATTRIBUTE(format(Archetype, Index, Ftc))
|
||||
# define CR_FORMAT(Archetype, Index, Ftc) CR_ATTRIBUTE(format(Archetype, Index, Ftc))
|
||||
# else
|
||||
# define FORMAT(Archetype, Index, Ftc)
|
||||
# define CR_FORMAT(Archetype, Index, Ftc)
|
||||
# endif
|
||||
|
||||
# if defined _WIN32 || defined __CYGWIN__
|
|
@ -112,11 +112,11 @@
|
|||
CR_EXPAND(CRITERION_APPLY(CRITERION_ADD_PREFIX_ONCE, __VA_ARGS__))
|
||||
|
||||
# ifdef __cplusplus
|
||||
# define CRITERION_MAKE_STRUCT(Type, ...) []() { \
|
||||
Type t; \
|
||||
std::memset(&t, 0, sizeof (t)); \
|
||||
CR_EXPAND(CRITERION_ADD_PREFIX(t, __VA_ARGS__)) \
|
||||
return t; \
|
||||
# define CRITERION_MAKE_STRUCT(Type, ...) []() -> Type { \
|
||||
Type t; \
|
||||
std::memset(&t, 0, sizeof (t)); \
|
||||
CR_EXPAND(CRITERION_ADD_PREFIX(t, __VA_ARGS__)) \
|
||||
return t; \
|
||||
}()
|
||||
# else
|
||||
# define CRITERION_MAKE_STRUCT(Type, ...) { __VA_ARGS__ }
|
84
include/criterion/internal/hooks.h
Normal file
84
include/criterion/internal/hooks.h
Normal file
|
@ -0,0 +1,84 @@
|
|||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright © 2015 Franklin "Snaipe" Mathieu <http://snai.pe/>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
#ifndef CRITERION_INTERNAL_HOOKS_H_
|
||||
# define CRITERION_INTERNAL_HOOKS_H_
|
||||
|
||||
# include "common.h"
|
||||
# include "../types.h"
|
||||
|
||||
# define CR_HOOK_IDENTIFIER_(Suffix) CR_HOOK_IDENTIFIER__(__LINE__, Suffix)
|
||||
# define CR_HOOK_IDENTIFIER__(Line, Suffix) CR_HOOK_IDENTIFIER___(Line, Suffix)
|
||||
# define CR_HOOK_IDENTIFIER___(Line, Suffix) hook_l ## Line ## _ ## Suffix
|
||||
|
||||
# ifdef __cplusplus
|
||||
# define CR_HOOK_PROTOTYPE_ \
|
||||
extern "C" void CR_HOOK_IDENTIFIER_(impl)
|
||||
# else
|
||||
# define CR_HOOK_PROTOTYPE_ \
|
||||
void CR_HOOK_IDENTIFIER_(impl)
|
||||
# endif
|
||||
|
||||
// Section abbreviations
|
||||
# define CR_HOOK_SECTION_PRE_ALL cr_pra
|
||||
# define CR_HOOK_SECTION_PRE_SUITE cr_prs
|
||||
# define CR_HOOK_SECTION_PRE_INIT cr_pri
|
||||
# define CR_HOOK_SECTION_PRE_TEST cr_prt
|
||||
# define CR_HOOK_SECTION_ASSERT cr_ast
|
||||
# define CR_HOOK_SECTION_THEORY_FAIL cr_thf
|
||||
# define CR_HOOK_SECTION_TEST_CRASH cr_tsc
|
||||
# define CR_HOOK_SECTION_POST_TEST cr_pot
|
||||
# define CR_HOOK_SECTION_POST_FINI cr_pof
|
||||
# define CR_HOOK_SECTION_POST_SUITE cr_pos
|
||||
# define CR_HOOK_SECTION_POST_ALL cr_poa
|
||||
|
||||
# define CR_HOOK_SECTION(Kind) CR_HOOK_SECTION_ ## Kind
|
||||
|
||||
# define CR_HOOK_SECTION_STRINGIFY__(Sec) #Sec
|
||||
# define CR_HOOK_SECTION_STRINGIFY_(Sec) CR_HOOK_SECTION_STRINGIFY__(Sec)
|
||||
# define CR_HOOK_SECTION_STRINGIFY(Kind) CR_HOOK_SECTION_STRINGIFY_(CR_HOOK_SECTION(Kind))
|
||||
|
||||
# define CR_HOOK_PARAM_TYPE_PRE_ALL struct criterion_test_set *
|
||||
# define CR_HOOK_PARAM_TYPE_PRE_SUITE struct criterion_suite_set *
|
||||
# define CR_HOOK_PARAM_TYPE_PRE_INIT struct criterion_test *
|
||||
# define CR_HOOK_PARAM_TYPE_PRE_TEST struct criterion_test *
|
||||
# define CR_HOOK_PARAM_TYPE_ASSERT struct criterion_assert_stats *
|
||||
# define CR_HOOK_PARAM_TYPE_THEORY_FAIL struct criterion_theory_stats *
|
||||
# define CR_HOOK_PARAM_TYPE_TEST_CRASH struct criterion_test_stats *
|
||||
# define CR_HOOK_PARAM_TYPE_POST_TEST struct criterion_test_stats *
|
||||
# define CR_HOOK_PARAM_TYPE_POST_FINI struct criterion_test_stats *
|
||||
# define CR_HOOK_PARAM_TYPE_POST_SUITE struct criterion_suite_stats *
|
||||
# define CR_HOOK_PARAM_TYPE_POST_ALL struct criterion_global_stats *
|
||||
|
||||
# define CR_HOOK_PARAM_TYPE(Kind) CR_HOOK_PARAM_TYPE_ ## Kind
|
||||
|
||||
# define CR_REPORT_HOOK_IMPL(Kind) \
|
||||
CR_HOOK_PROTOTYPE_(CR_HOOK_PARAM_TYPE(Kind)); \
|
||||
CR_SECTION_(CR_HOOK_SECTION_STRINGIFY(Kind)) \
|
||||
f_report_hook CR_HOOK_IDENTIFIER_(func) = \
|
||||
(f_report_hook) CR_HOOK_IDENTIFIER_(impl) \
|
||||
CR_SECTION_SUFFIX_; \
|
||||
CR_HOOK_PROTOTYPE_
|
||||
|
||||
|
||||
#endif /* !CRITERION_INTERNAL_HOOKS_H_ */
|
|
@ -24,7 +24,7 @@
|
|||
#ifndef CRITERION_ORDERED_SET_H_
|
||||
# define CRITERION_ORDERED_SET_H_
|
||||
|
||||
# include "types.h"
|
||||
# include "../types.h"
|
||||
|
||||
typedef int (*f_criterion_cmp)(void *, void *);
|
||||
|
||||
|
@ -37,7 +37,6 @@ struct criterion_ordered_set {
|
|||
|
||||
struct criterion_ordered_set_node {
|
||||
struct criterion_ordered_set_node *next;
|
||||
char data[0];
|
||||
};
|
||||
|
||||
CR_BEGIN_C_API
|
||||
|
@ -54,6 +53,6 @@ CR_END_C_API
|
|||
# define FOREACH_SET(Elt, Set) \
|
||||
for (struct criterion_ordered_set_node *n = Set->first; n; n = n->next) \
|
||||
for (int cond = 1; cond;) \
|
||||
for (Elt = (void*) n->data; cond && (cond = 0, 1);)
|
||||
for (Elt = (void*) (n + 1); cond && (cond = 0, 1);)
|
||||
|
||||
#endif /* !CRITERION_ORDERED_SET_H_ */
|
115
include/criterion/internal/parameterized.h
Normal file
115
include/criterion/internal/parameterized.h
Normal file
|
@ -0,0 +1,115 @@
|
|||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright © 2015 Franklin "Snaipe" Mathieu <http://snai.pe/>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
#ifndef CRITERION_INTERNAL_PARAMETERIZED_H_
|
||||
# define CRITERION_INTERNAL_PARAMETERIZED_H_
|
||||
|
||||
# include "test.h"
|
||||
# include "../types.h"
|
||||
|
||||
struct criterion_test_params {
|
||||
size_t size;
|
||||
void *params;
|
||||
size_t length;
|
||||
void (*cleanup)(struct criterion_test_params *);
|
||||
|
||||
# ifdef __cplusplus
|
||||
constexpr criterion_test_params(size_t size, void *params, size_t length)
|
||||
: size(size)
|
||||
, params(params)
|
||||
, length(length)
|
||||
, cleanup(nullptr)
|
||||
{}
|
||||
|
||||
constexpr criterion_test_params(size_t size, void *params, size_t length,
|
||||
void (*cleanup)(struct criterion_test_params *))
|
||||
: size(size)
|
||||
, params(params)
|
||||
, length(length)
|
||||
, cleanup(cleanup)
|
||||
{}
|
||||
|
||||
template <typename T>
|
||||
constexpr criterion_test_params(std::vector<T, criterion::allocator<T>>& vec,
|
||||
void (*cleanup)(criterion_test_params *) = nullptr)
|
||||
: size(sizeof (T))
|
||||
, params(&vec[0])
|
||||
, length(vec.size())
|
||||
, cleanup(cleanup)
|
||||
{}
|
||||
|
||||
template <typename T, unsigned int N>
|
||||
constexpr criterion_test_params(T (&arr)[N],
|
||||
void (*cleanup)(criterion_test_params *) = nullptr)
|
||||
: size(sizeof (arr[0]))
|
||||
, params(static_cast<void*>(&arr))
|
||||
, length(N)
|
||||
, cleanup(cleanup)
|
||||
{}
|
||||
# endif
|
||||
};
|
||||
|
||||
# ifdef __cplusplus
|
||||
# define CR_PARAM_TEST_PROTOTYPE_(Param, Category, Name) \
|
||||
extern "C" void CR_IDENTIFIER_(Category, Name, impl)(Param)
|
||||
# else
|
||||
# define CR_PARAM_TEST_PROTOTYPE_(Param, Category, Name) \
|
||||
void CR_IDENTIFIER_(Category, Name, impl)(Param)
|
||||
# endif
|
||||
|
||||
# define CR_PARAM_TEST_BASE(Param, Category, Name, ...) \
|
||||
CR_PARAM_TEST_PROTOTYPE_(Param, Category, Name); \
|
||||
CR_TEST_TRAMPOLINE_(Category, Name) \
|
||||
struct criterion_test_extra_data CR_IDENTIFIER_(Category, Name, extra) = \
|
||||
CR_EXPAND(CRITERION_MAKE_STRUCT(criterion_test_extra_data, \
|
||||
.lang_ = CR_LANG, \
|
||||
.kind_ = CR_TEST_PARAMETERIZED, \
|
||||
.param_ = CR_IDENTIFIER_(Category, Name, param), \
|
||||
.identifier_ = #Category "/" #Name, \
|
||||
.file_ = __FILE__, \
|
||||
.line_ = __LINE__, \
|
||||
__VA_ARGS__ \
|
||||
)); \
|
||||
struct criterion_test CR_IDENTIFIER_(Category, Name, meta) = { \
|
||||
#Name, \
|
||||
#Category, \
|
||||
CR_IDENTIFIER_(Category, Name, jmp), \
|
||||
&CR_IDENTIFIER_(Category, Name, extra) \
|
||||
}; \
|
||||
CR_SECTION_("cr_tst") \
|
||||
struct criterion_test *CR_IDENTIFIER_(Category, Name, ptr) \
|
||||
= &CR_IDENTIFIER_(Category, Name, meta) CR_SECTION_SUFFIX_; \
|
||||
CR_PARAM_TEST_PROTOTYPE_(Param, Category, Name)
|
||||
|
||||
# define CR_PARAM_TEST_PARAMS(Category, Name) \
|
||||
static struct criterion_test_params CR_IDENTIFIER_(Category, Name, param)(void)
|
||||
|
||||
# ifdef __cplusplus
|
||||
# define cr_make_param_array_(Type, Array, ...) \
|
||||
criterion_test_params(sizeof (Type), (Array), __VA_ARGS__)
|
||||
# else
|
||||
# define cr_make_param_array_(Type, Array, ...) \
|
||||
(struct criterion_test_params) { .size = sizeof (Type), (void*)(Array), __VA_ARGS__ }
|
||||
# endif
|
||||
|
||||
#endif /* !CRITERION_INTERNAL_PARAMETERIZED_H_ */
|
71
include/criterion/internal/redirect.h
Normal file
71
include/criterion/internal/redirect.h
Normal file
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright © 2015 Franklin "Snaipe" Mathieu <http://snai.pe/>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
#ifndef CRITERION_INTERNAL_REDIRECT_H_
|
||||
# define CRITERION_INTERNAL_REDIRECT_H_
|
||||
|
||||
# include "common.h"
|
||||
# include "assert.h"
|
||||
|
||||
# define cr_assert_redir_op_(Fail, Fun, Op, File, Str, ...) \
|
||||
CR_EXPAND(cr_assert_impl( \
|
||||
Fail, \
|
||||
!(Fun((File), (Str)) Op 0), \
|
||||
dummy, \
|
||||
CRITERION_ASSERT_MSG_FILE_STR_MATCH, \
|
||||
(CR_STR(File), Str), \
|
||||
__VA_ARGS__ \
|
||||
))
|
||||
|
||||
# define cr_assert_redir_op_va_(Fail, Fun, Op, ...) \
|
||||
CR_EXPAND(cr_assert_redir_op_( \
|
||||
Fail, \
|
||||
Fun, \
|
||||
Op, \
|
||||
CR_VA_HEAD(__VA_ARGS__), \
|
||||
CR_VA_HEAD(CR_VA_TAIL(__VA_ARGS__)), \
|
||||
CR_VA_TAIL(CR_VA_TAIL(__VA_ARGS__)) \
|
||||
))
|
||||
|
||||
# define cr_assert_redir_f_op_(Fail, Fun, Op, File, Ref, ...) \
|
||||
CR_EXPAND(cr_assert_impl( \
|
||||
Fail, \
|
||||
!(Fun((File), (Ref)) Op 0), \
|
||||
dummy, \
|
||||
CRITERION_ASSERT_MSG_FILE_MATCH, \
|
||||
(CR_STR(File), CR_STR(Ref)), \
|
||||
__VA_ARGS__ \
|
||||
))
|
||||
|
||||
# define cr_assert_redir_f_op_va_(Fail, Fun, Op, ...) \
|
||||
CR_EXPAND(cr_assert_redir_op_( \
|
||||
Fail, \
|
||||
Fun, \
|
||||
Op, \
|
||||
CR_VA_HEAD(__VA_ARGS__), \
|
||||
CR_VA_HEAD(CR_VA_TAIL(__VA_ARGS__)), \
|
||||
CR_VA_TAIL(CR_VA_TAIL(__VA_ARGS__)) \
|
||||
))
|
||||
|
||||
|
||||
#endif /* !CRITERION_INTERNAL_REDIRECT_H_ */
|
138
include/criterion/internal/stdio_filebuf.hxx
Normal file
138
include/criterion/internal/stdio_filebuf.hxx
Normal file
|
@ -0,0 +1,138 @@
|
|||
#ifndef CRITERION_INTERNAL_STDIO_FILEBUF_HXX_
|
||||
# define CRITERION_INTERNAL_STDIO_FILEBUF_HXX_
|
||||
|
||||
# include <fstream>
|
||||
|
||||
namespace criterion { namespace internal {
|
||||
|
||||
template <typename CharT, typename Traits = std::char_traits<CharT>>
|
||||
class stdio_sync_filebuf : public std::basic_streambuf<CharT, Traits> {
|
||||
public:
|
||||
typedef Traits traits;
|
||||
typedef std::basic_filebuf<CharT, Traits> super;
|
||||
typedef typename Traits::int_type int_type;
|
||||
typedef typename Traits::pos_type pos_type;
|
||||
typedef typename Traits::off_type off_type;
|
||||
|
||||
stdio_sync_filebuf(std::FILE *file)
|
||||
: file(file)
|
||||
, lastchar(Traits::eof())
|
||||
{}
|
||||
|
||||
stdio_sync_filebuf(stdio_sync_filebuf&& other) = default;
|
||||
stdio_sync_filebuf& operator=(stdio_sync_filebuf&& other) = default;
|
||||
|
||||
void swap(stdio_sync_filebuf& other) {
|
||||
super::swap(other);
|
||||
std::swap(file, other.file);
|
||||
std::swap(lastchar, other.lastchar);
|
||||
}
|
||||
|
||||
protected:
|
||||
int_type syncgetc();
|
||||
int_type syncungetc(int_type);
|
||||
int_type syncputc(int_type);
|
||||
|
||||
virtual std::streampos seekoff(std::streamoff off,
|
||||
std::ios_base::seekdir dir,
|
||||
std::ios_base::openmode = std::ios_base::in | std::ios_base::out) {
|
||||
|
||||
int whence;
|
||||
if (dir == std::ios_base::beg)
|
||||
whence = SEEK_SET;
|
||||
else if (dir == std::ios_base::cur)
|
||||
whence = SEEK_CUR;
|
||||
else
|
||||
whence = SEEK_END;
|
||||
|
||||
if (!fseek(file, off, whence))
|
||||
return std::streampos(std::ftell(file));
|
||||
return std::streamoff(-1);
|
||||
}
|
||||
|
||||
virtual std::streampos seekpos(std::streampos pos,
|
||||
std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out) {
|
||||
return seekoff(std::streamoff(pos), std::ios_base::beg, mode);
|
||||
}
|
||||
|
||||
virtual std::streamsize xsgetn(CharT* s, std::streamsize n);
|
||||
virtual std::streamsize xsputn(const CharT* s, std::streamsize n);
|
||||
|
||||
virtual int sync() {
|
||||
return std::fflush(file);
|
||||
}
|
||||
|
||||
virtual int_type underflow() {
|
||||
int_type c = syncgetc();
|
||||
return syncungetc(c);
|
||||
}
|
||||
|
||||
virtual int_type uflow() {
|
||||
return lastchar = syncgetc();
|
||||
}
|
||||
|
||||
static inline bool is_eof(int_type c) {
|
||||
static const int_type eof = Traits::eof();
|
||||
return Traits::eq_int_type(c, eof);
|
||||
}
|
||||
|
||||
virtual int_type overflow(int_type c = Traits::eof()) {
|
||||
int_type ret;
|
||||
if (is_eof(c)) {
|
||||
if (std::fflush(file))
|
||||
ret = Traits::eof();
|
||||
else
|
||||
ret = Traits::not_eof(c);
|
||||
} else {
|
||||
ret = syncputc(c);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
virtual int_type pbackfail(int_type c = Traits::eof()) {
|
||||
int_type ret = syncungetc(is_eof(c) && !is_eof(lastchar) ? lastchar : c);
|
||||
lastchar = Traits::eof();
|
||||
return ret;
|
||||
}
|
||||
|
||||
private:
|
||||
std::FILE *file;
|
||||
bool file_open;
|
||||
int_type lastchar;
|
||||
};
|
||||
|
||||
template <>
|
||||
inline stdio_sync_filebuf<char>::int_type
|
||||
stdio_sync_filebuf<char>::syncgetc() {
|
||||
return std::getc(file);
|
||||
}
|
||||
|
||||
template <>
|
||||
inline stdio_sync_filebuf<char>::int_type
|
||||
stdio_sync_filebuf<char>::syncungetc(stdio_sync_filebuf<char>::int_type c) {
|
||||
return std::ungetc(c, file);
|
||||
}
|
||||
|
||||
template <>
|
||||
inline stdio_sync_filebuf<char>::int_type
|
||||
stdio_sync_filebuf<char>::syncputc(stdio_sync_filebuf<char>::int_type c) {
|
||||
return std::putc(c, file);
|
||||
}
|
||||
|
||||
template <>
|
||||
inline std::streamsize
|
||||
stdio_sync_filebuf<char>::xsgetn(char *s, std::streamsize n) {
|
||||
std::streamsize res = std::fread(s, 1, n, file);
|
||||
lastchar = res > 0 ? traits::to_int_type(s[res - 1]) : traits::eof();
|
||||
return res;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline std::streamsize
|
||||
stdio_sync_filebuf<char>::xsputn(const char *s, std::streamsize n) {
|
||||
return std::fwrite(s, 1, n, file);
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
#endif /* !CRITERION_INTERNAL_STDIO_FILEBUF_HXX_ */
|
110
include/criterion/internal/stream.hxx
Normal file
110
include/criterion/internal/stream.hxx
Normal file
|
@ -0,0 +1,110 @@
|
|||
#ifndef CRITERION_INTERNAL_STREAM_HXX_
|
||||
# define CRITERION_INTERNAL_STREAM_HXX_
|
||||
|
||||
# include <fstream>
|
||||
# include <cstdio>
|
||||
# include <memory>
|
||||
|
||||
# include "stdio_filebuf.hxx"
|
||||
|
||||
namespace criterion { namespace internal {
|
||||
|
||||
template <typename CharT, typename Super>
|
||||
class stream_mixin : public Super {
|
||||
public:
|
||||
stream_mixin(FILE* f)
|
||||
: Super()
|
||||
, fbuf(new stdio_sync_filebuf<CharT>(f))
|
||||
, file(f)
|
||||
{
|
||||
std::ios::rdbuf(&*fbuf);
|
||||
}
|
||||
|
||||
# if __cplusplus > 199711L
|
||||
stream_mixin(const stream_mixin& other) = delete;
|
||||
stream_mixin& operator=(const stream_mixin& other) = delete;
|
||||
# endif
|
||||
|
||||
stream_mixin(stream_mixin&& other) :
|
||||
fbuf(std::move(other.fbuf)),
|
||||
file(std::move(other.file))
|
||||
{}
|
||||
|
||||
stream_mixin& operator=(stream_mixin&& other) {
|
||||
fbuf = std::move(other.fbuf);
|
||||
file = std::move(other.file);
|
||||
}
|
||||
|
||||
void close(void) {
|
||||
Super::flush();
|
||||
Super::close();
|
||||
std::fclose(file);
|
||||
}
|
||||
|
||||
private:
|
||||
std::shared_ptr<stdio_sync_filebuf<CharT>> fbuf;
|
||||
std::FILE* file;
|
||||
};
|
||||
|
||||
template <typename CharT>
|
||||
class basic_ofstream : public stream_mixin<CharT, std::basic_ofstream<CharT>> {
|
||||
typedef stream_mixin<CharT, std::basic_ofstream<CharT>> super;
|
||||
public:
|
||||
basic_ofstream(FILE* f)
|
||||
: super(f)
|
||||
{}
|
||||
|
||||
basic_ofstream(basic_ofstream&& other)
|
||||
: super(std::move(other))
|
||||
{}
|
||||
};
|
||||
|
||||
template <typename CharT>
|
||||
class basic_ifstream : public stream_mixin<CharT, std::basic_ifstream<CharT>> {
|
||||
typedef stream_mixin<CharT, std::basic_ifstream<CharT>> super;
|
||||
public:
|
||||
basic_ifstream(FILE* f)
|
||||
: super(f)
|
||||
{}
|
||||
|
||||
basic_ifstream(basic_ifstream&& other)
|
||||
: super(std::move(other))
|
||||
{}
|
||||
};
|
||||
|
||||
template <typename CharT>
|
||||
class basic_fstream : public stream_mixin<CharT, std::basic_fstream<CharT>> {
|
||||
typedef stream_mixin<CharT, std::basic_fstream<CharT>> super;
|
||||
public:
|
||||
basic_fstream(FILE* f)
|
||||
: super(f)
|
||||
{}
|
||||
|
||||
basic_fstream(basic_fstream&& other)
|
||||
: super(std::move(other))
|
||||
{}
|
||||
};
|
||||
|
||||
struct get_redirected_out_stream_ {
|
||||
static inline basic_ofstream<char>& call(std::FILE* f) {
|
||||
static std::unique_ptr<basic_ofstream<char>> stream;
|
||||
|
||||
if (!stream)
|
||||
stream.reset(new basic_ofstream<char>(f));
|
||||
return *stream;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
struct get_redirected_in_stream_ {
|
||||
static inline basic_ifstream<char>& call(std::FILE* f) {
|
||||
static std::unique_ptr<basic_ifstream<char>> stream;
|
||||
if (!stream)
|
||||
stream.reset(new basic_ifstream<char>(f));
|
||||
return *stream;
|
||||
}
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif /* !CRITERION_INTERNAL_STREAM_HXX_ */
|
185
include/criterion/internal/test.h
Normal file
185
include/criterion/internal/test.h
Normal file
|
@ -0,0 +1,185 @@
|
|||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright © 2015 Franklin "Snaipe" Mathieu <http://snai.pe/>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
#ifndef CRITERION_INTERNAL_TEST_H_
|
||||
# define CRITERION_INTERNAL_TEST_H_
|
||||
|
||||
# include "designated-initializer-compat.h"
|
||||
# include "common.h"
|
||||
|
||||
# ifdef __OBJC__
|
||||
#import <Foundation/Foundation.h>
|
||||
# endif
|
||||
|
||||
# ifdef __cplusplus
|
||||
# include <exception>
|
||||
# endif
|
||||
|
||||
# define CR_IDENTIFIER_(Category, Name, Suffix) \
|
||||
Category ## _ ## Name ## _ ## Suffix
|
||||
|
||||
# ifdef __cplusplus
|
||||
# ifdef __OBJC__
|
||||
# define CR_LANG CR_LANG_OBJCXX
|
||||
# else
|
||||
# define CR_LANG CR_LANG_CXX
|
||||
# endif
|
||||
# else
|
||||
# ifdef __OBJC__
|
||||
# define CR_LANG CR_LANG_OBJC
|
||||
# else
|
||||
# define CR_LANG CR_LANG_C
|
||||
# endif
|
||||
# endif
|
||||
|
||||
# ifdef __cplusplus
|
||||
# define CR_TEST_PROTOTYPE_(Category, Name) \
|
||||
extern "C" void CR_IDENTIFIER_(Category, Name, impl)(void)
|
||||
# else
|
||||
# define CR_TEST_PROTOTYPE_(Category, Name) \
|
||||
void CR_IDENTIFIER_(Category, Name, impl)(void)
|
||||
# endif
|
||||
|
||||
# define CR_SUITE_IDENTIFIER_(Name, Suffix) \
|
||||
suite_ ## Name ## _ ## Suffix
|
||||
|
||||
CR_BEGIN_C_API
|
||||
|
||||
CR_API void criterion_internal_test_setup(void);
|
||||
CR_API void criterion_internal_test_main(void (*fn)(void));
|
||||
CR_API void criterion_internal_test_teardown(void);
|
||||
|
||||
CR_END_C_API
|
||||
|
||||
static const char *const cr_msg_test_init_std_exception = "Caught an unexpected exception during the test initialization: %s.";
|
||||
static const char *const cr_msg_test_init_other_exception = "Caught some unexpected exception during the test initialization.";
|
||||
static const char *const cr_msg_test_main_std_exception = "Caught an unexpected exception during the test execution: %s.";
|
||||
static const char *const cr_msg_test_main_other_exception = "Caught some unexpected exception during the test execution.";
|
||||
static const char *const cr_msg_test_fini_std_exception = "Caught an unexpected exception during the test finalization: %s.";
|
||||
static const char *const cr_msg_test_fini_other_exception = "Caught some unexpected exception during the test finalization.";
|
||||
|
||||
# ifdef __cplusplus
|
||||
# define CR_TEST_TRAMPOLINE_(Category, Name) \
|
||||
static inline void CR_IDENTIFIER_(Category, Name, jmp)(void) { \
|
||||
try { \
|
||||
criterion_internal_test_setup(); \
|
||||
} catch (const std::exception &e) { \
|
||||
criterion_test_die(cr_msg_test_init_std_exception, e.what()); \
|
||||
} catch (...) { \
|
||||
criterion_test_die(cr_msg_test_init_other_exception); \
|
||||
} \
|
||||
try { \
|
||||
criterion_internal_test_main((void(*)(void)) CR_IDENTIFIER_(Category, Name, impl)); \
|
||||
} catch (const std::exception &e) { \
|
||||
criterion_test_die(cr_msg_test_main_std_exception, e.what()); \
|
||||
} catch (...) { \
|
||||
criterion_test_die(cr_msg_test_main_other_exception); \
|
||||
} \
|
||||
try { \
|
||||
criterion_internal_test_teardown(); \
|
||||
} catch (const std::exception &e) { \
|
||||
criterion_test_die(cr_msg_test_fini_std_exception, e.what()); \
|
||||
} catch (...) { \
|
||||
criterion_test_die(cr_msg_test_fini_other_exception); \
|
||||
} \
|
||||
}
|
||||
# else
|
||||
# if defined(__OBJC__) && defined(__EXCEPTIONS)
|
||||
# define CR_TEST_TRAMPOLINE_(Category, Name) \
|
||||
static inline void CR_IDENTIFIER_(Category, Name, jmp)(void) { \
|
||||
@try { \
|
||||
criterion_internal_test_setup(); \
|
||||
} @catch (NSException *e) { \
|
||||
NSString *reason = [e reason]; \
|
||||
criterion_test_die(cr_msg_test_init_std_exception, [reason UTF8String]); \
|
||||
} @catch (...) { \
|
||||
criterion_test_die(cr_msg_test_init_other_exception); \
|
||||
} \
|
||||
@try { \
|
||||
criterion_internal_test_main((void(*)(void)) CR_IDENTIFIER_(Category, Name, impl)); \
|
||||
} @catch (NSException *e) { \
|
||||
NSString *reason = [e reason]; \
|
||||
criterion_test_die(cr_msg_test_main_std_exception, [reason UTF8String]); \
|
||||
} @catch (...) { \
|
||||
criterion_test_die(cr_msg_test_main_other_exception); \
|
||||
} \
|
||||
@try { \
|
||||
criterion_internal_test_teardown(); \
|
||||
} @catch (NSException *e) { \
|
||||
NSString *reason = [e reason]; \
|
||||
criterion_test_die(cr_msg_test_fini_std_exception, [reason UTF8String]); \
|
||||
} @catch (...) { \
|
||||
criterion_test_die(cr_msg_test_fini_other_exception); \
|
||||
} \
|
||||
}
|
||||
# else
|
||||
# define CR_TEST_TRAMPOLINE_(Category, Name) \
|
||||
static inline void CR_IDENTIFIER_(Category, Name, jmp)(void) { \
|
||||
criterion_internal_test_setup(); \
|
||||
criterion_internal_test_main((void(*)(void)) CR_IDENTIFIER_(Category, Name, impl)); \
|
||||
criterion_internal_test_teardown(); \
|
||||
}
|
||||
# endif
|
||||
# endif
|
||||
|
||||
# define CR_TEST_BASE(Category, Name, ...) \
|
||||
CR_TEST_PROTOTYPE_(Category, Name); \
|
||||
CR_TEST_TRAMPOLINE_(Category, Name) \
|
||||
struct criterion_test_extra_data CR_IDENTIFIER_(Category, Name, extra) = \
|
||||
CR_EXPAND(CRITERION_MAKE_STRUCT(criterion_test_extra_data, \
|
||||
.lang_ = CR_LANG, \
|
||||
.kind_ = CR_TEST_NORMAL, \
|
||||
.param_ = (struct criterion_test_params(*)(void)) NULL, \
|
||||
.identifier_ = #Category "/" #Name, \
|
||||
.file_ = __FILE__, \
|
||||
.line_ = __LINE__, \
|
||||
__VA_ARGS__ \
|
||||
)); \
|
||||
struct criterion_test CR_IDENTIFIER_(Category, Name, meta) = { \
|
||||
#Name, \
|
||||
#Category, \
|
||||
CR_IDENTIFIER_(Category, Name, jmp), \
|
||||
&CR_IDENTIFIER_(Category, Name, extra) \
|
||||
}; \
|
||||
CR_SECTION_("cr_tst") \
|
||||
struct criterion_test *CR_IDENTIFIER_(Category, Name, ptr) \
|
||||
= &CR_IDENTIFIER_(Category, Name, meta) CR_SECTION_SUFFIX_; \
|
||||
CR_TEST_PROTOTYPE_(Category, Name)
|
||||
|
||||
# define CR_SUITE_BASE(Name, ...) \
|
||||
struct criterion_test_extra_data CR_SUITE_IDENTIFIER_(Name, extra) = \
|
||||
CR_EXPAND(CRITERION_MAKE_STRUCT(criterion_test_extra_data, \
|
||||
.file_ = __FILE__, \
|
||||
.line_ = 0, \
|
||||
__VA_ARGS__ \
|
||||
)); \
|
||||
struct criterion_suite CR_SUITE_IDENTIFIER_(Name, meta) = { \
|
||||
#Name, \
|
||||
&CR_SUITE_IDENTIFIER_(Name, extra), \
|
||||
}; \
|
||||
CR_SECTION_("cr_sts") \
|
||||
struct criterion_suite *CR_SUITE_IDENTIFIER_(Name, ptr) \
|
||||
= &CR_SUITE_IDENTIFIER_(Name, meta) CR_SECTION_SUFFIX_
|
||||
|
||||
|
||||
#endif /* !CRITERION_INTERNAL_TEST_H_ */
|
94
include/criterion/internal/theories.h
Normal file
94
include/criterion/internal/theories.h
Normal file
|
@ -0,0 +1,94 @@
|
|||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright © 2015 Franklin "Snaipe" Mathieu <http://snai.pe/>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
#ifndef CRITERION_INTERNAL_THEORIES_H_
|
||||
# define CRITERION_INTERNAL_THEORIES_H_
|
||||
|
||||
# include "test.h"
|
||||
|
||||
# ifdef __cplusplus
|
||||
# include <cstddef>
|
||||
using std::size_t;
|
||||
# else
|
||||
# include <stddef.h>
|
||||
# endif
|
||||
|
||||
# ifdef __cplusplus
|
||||
template <typename... T>
|
||||
constexpr size_t criterion_va_num__(const T &...) {
|
||||
return sizeof...(T);
|
||||
}
|
||||
# endif
|
||||
|
||||
struct criterion_datapoints {
|
||||
size_t size;
|
||||
size_t len;
|
||||
const char *name;
|
||||
void *arr;
|
||||
};
|
||||
|
||||
CR_BEGIN_C_API
|
||||
|
||||
CR_API void cr_theory_main(struct criterion_datapoints *dps, size_t datapoints, void (*fnptr)(void));
|
||||
|
||||
CR_END_C_API
|
||||
|
||||
# ifdef __cplusplus
|
||||
# define CR_TH_VA_NUM(Type, ...) criterion_va_num__(__VA_ARGS__)
|
||||
# define CR_TH_TEMP_ARRAY(Type, ...) []() -> Type* { static Type arr[] = { __VA_ARGS__ }; return reinterpret_cast<Type*>(&arr); }()
|
||||
# else
|
||||
# define CR_TH_VA_NUM(Type, ...) sizeof ((Type[]) { __VA_ARGS__ }) / sizeof (Type)
|
||||
# define CR_TH_TEMP_ARRAY(Type, ...) &(Type[]) { __VA_ARGS__ }
|
||||
# endif
|
||||
|
||||
# define CR_TH_INTERNAL_TDPS(Category, Name) \
|
||||
static struct criterion_datapoints CR_IDENTIFIER_(Category, Name, dps)[]
|
||||
|
||||
# define CR_TH_INTERNAL_TDP(Category, Name) \
|
||||
(CR_IDENTIFIER_(Category, Name, dps))
|
||||
|
||||
# define CR_TH_INTERNAL_DP(Type, ...) { \
|
||||
sizeof (Type), \
|
||||
CR_EXPAND(CR_TH_VA_NUM(Type, __VA_ARGS__)), \
|
||||
#Type, \
|
||||
CR_EXPAND(CR_TH_TEMP_ARRAY(Type, __VA_ARGS__)), \
|
||||
}
|
||||
|
||||
# define CR_NB_DATAPOINTS(Var) \
|
||||
(sizeof (Var) / sizeof (struct criterion_datapoints))
|
||||
|
||||
# define CR_VAARG_ID(Suffix, Category, Name, ...) \
|
||||
CR_IDENTIFIER_(Category, Name, Suffix)
|
||||
|
||||
# define CR_THEORY_BASE(Args, ...) \
|
||||
void CR_EXPAND(CR_VAARG_ID(theory, __VA_ARGS__,))Args; \
|
||||
CR_EXPAND(CR_TEST_BASE(__VA_ARGS__, .sentinel_ = 0)) { \
|
||||
cr_theory_main( \
|
||||
CR_EXPAND(CR_VAARG_ID(dps, __VA_ARGS__,)), \
|
||||
CR_NB_DATAPOINTS(CR_EXPAND(CR_VAARG_ID(dps, __VA_ARGS__,))), \
|
||||
(void(*)(void)) CR_EXPAND(CR_VAARG_ID(theory, __VA_ARGS__,)) \
|
||||
); \
|
||||
} \
|
||||
void CR_EXPAND(CR_VAARG_ID(theory, __VA_ARGS__,))Args
|
||||
|
||||
#endif /* !CRITERION_INTERNAL_THEORIES_H_ */
|
|
@ -31,13 +31,15 @@ using std::va_list;
|
|||
# include <stdbool.h>
|
||||
# include <stdarg.h>
|
||||
# endif
|
||||
# include "common.h"
|
||||
# include "ordered-set.h"
|
||||
# include "internal/common.h"
|
||||
# include "internal/ordered-set.h"
|
||||
# include "stats.h"
|
||||
|
||||
enum criterion_logging_level {
|
||||
CRITERION_INFO = 1,
|
||||
CRITERION_IMPORTANT,
|
||||
|
||||
CRITERION_LOG_LEVEL_QUIET = 1 << 30,
|
||||
};
|
||||
|
||||
enum criterion_logging_prefix {
|
||||
|
@ -47,6 +49,7 @@ enum criterion_logging_prefix {
|
|||
CRITERION_LOGGING_PREFIX_SKIP,
|
||||
CRITERION_LOGGING_PREFIX_PASS,
|
||||
CRITERION_LOGGING_PREFIX_FAIL,
|
||||
CRITERION_LOGGING_PREFIX_ERR,
|
||||
};
|
||||
|
||||
struct criterion_prefix_data {
|
||||
|
@ -64,12 +67,12 @@ struct criterion_prefix_data {
|
|||
# define CRIT_FG_BLUE "\33[0;34m"
|
||||
# define CRIT_RESET "\33[0m"
|
||||
|
||||
# define FG_BOLD CRIT_COLOR_NORMALIZE(CRIT_FG_BOLD)
|
||||
# define FG_RED CRIT_COLOR_NORMALIZE(CRIT_FG_RED)
|
||||
# define FG_GREEN CRIT_COLOR_NORMALIZE(CRIT_FG_GREEN)
|
||||
# define FG_GOLD CRIT_COLOR_NORMALIZE(CRIT_FG_GOLD)
|
||||
# define FG_BLUE CRIT_COLOR_NORMALIZE(CRIT_FG_BLUE)
|
||||
# define RESET CRIT_COLOR_NORMALIZE(CRIT_RESET)
|
||||
# define CR_FG_BOLD CRIT_COLOR_NORMALIZE(CRIT_FG_BOLD)
|
||||
# define CR_FG_RED CRIT_COLOR_NORMALIZE(CRIT_FG_RED)
|
||||
# define CR_FG_GREEN CRIT_COLOR_NORMALIZE(CRIT_FG_GREEN)
|
||||
# define CR_FG_GOLD CRIT_COLOR_NORMALIZE(CRIT_FG_GOLD)
|
||||
# define CR_FG_BLUE CRIT_COLOR_NORMALIZE(CRIT_FG_BLUE)
|
||||
# define CR_RESET CRIT_COLOR_NORMALIZE(CRIT_RESET)
|
||||
# endif
|
||||
|
||||
CR_BEGIN_C_API
|
||||
|
@ -82,13 +85,14 @@ extern const struct criterion_prefix_data g_criterion_logging_prefixes[];
|
|||
# define CRITERION_PREFIX_SKIP (&g_criterion_logging_prefixes[CRITERION_LOGGING_PREFIX_SKIP ])
|
||||
# define CRITERION_PREFIX_PASS (&g_criterion_logging_prefixes[CRITERION_LOGGING_PREFIX_PASS ])
|
||||
# define CRITERION_PREFIX_FAIL (&g_criterion_logging_prefixes[CRITERION_LOGGING_PREFIX_FAIL ])
|
||||
# define CRITERION_PREFIX_ERR (&g_criterion_logging_prefixes[CRITERION_LOGGING_PREFIX_ERR ])
|
||||
|
||||
CR_API void criterion_vlog(enum criterion_logging_level level, const char *msg, va_list args);
|
||||
|
||||
FORMAT(printf, 3, 4)
|
||||
CR_FORMAT(printf, 3, 4)
|
||||
CR_API void criterion_plog(enum criterion_logging_level level, const struct criterion_prefix_data *prefix, const char *msg, ...);
|
||||
|
||||
FORMAT(printf, 2, 3)
|
||||
CR_FORMAT(printf, 2, 3)
|
||||
CR_API void criterion_log(enum criterion_logging_level level, const char *msg, ...);
|
||||
|
||||
# define criterion_info(...) criterion_log(CRITERION_INFO, __VA_ARGS__)
|
||||
|
@ -97,7 +101,9 @@ CR_API void criterion_log(enum criterion_logging_level level, const char *msg, .
|
|||
# define criterion_pinfo(...) criterion_plog(CRITERION_INFO, __VA_ARGS__)
|
||||
# define criterion_pimportant(...) criterion_plog(CRITERION_IMPORTANT, __VA_ARGS__)
|
||||
|
||||
struct criterion_output_provider {
|
||||
# define criterion_perror(...) criterion_plog(CRITERION_IMPORTANT, CRITERION_PREFIX_ERR, __VA_ARGS__)
|
||||
|
||||
struct criterion_logger {
|
||||
void (*log_pre_all )(struct criterion_test_set *set);
|
||||
void (*log_pre_suite )(struct criterion_suite_set *set);
|
||||
void (*log_pre_init )(struct criterion_test *test);
|
||||
|
@ -106,6 +112,7 @@ struct criterion_output_provider {
|
|||
void (*log_theory_fail )(struct criterion_theory_stats *stats);
|
||||
void (*log_test_timeout )(struct criterion_test_stats *stats);
|
||||
void (*log_test_crash )(struct criterion_test_stats *stats);
|
||||
void (*log_test_abort )(struct criterion_test_stats *stats, const char *msg);
|
||||
void (*log_other_crash )(struct criterion_test_stats *stats);
|
||||
void (*log_abnormal_exit)(struct criterion_test_stats *stats);
|
||||
void (*log_post_test )(struct criterion_test_stats *stats);
|
||||
|
@ -114,12 +121,10 @@ struct criterion_output_provider {
|
|||
void (*log_post_all )(struct criterion_global_stats *stats);
|
||||
};
|
||||
|
||||
extern struct criterion_output_provider normal_logging;
|
||||
extern struct criterion_output_provider tap_logging;
|
||||
extern struct criterion_logger normal_logging;
|
||||
|
||||
CR_END_C_API
|
||||
|
||||
#define NORMAL_LOGGING (&normal_logging)
|
||||
#define TAP_LOGGING (&tap_logging)
|
||||
#define CR_NORMAL_LOGGING (&normal_logging)
|
||||
|
||||
#endif /* !CRITERION_LOGGING_H_ */
|
||||
|
|
|
@ -28,18 +28,90 @@
|
|||
# include "logging.h"
|
||||
|
||||
struct criterion_options {
|
||||
|
||||
/**
|
||||
* The current logging threshold.
|
||||
*
|
||||
* default: 1
|
||||
*/
|
||||
enum criterion_logging_level logging_threshold;
|
||||
struct criterion_output_provider *output_provider;
|
||||
|
||||
/**
|
||||
* The logger that will be used during the execution of the runner.
|
||||
*
|
||||
* default: normal logger
|
||||
*/
|
||||
struct criterion_logger *logger;
|
||||
|
||||
/**
|
||||
* Don't exit the child immediately after finishing to run the test
|
||||
* function, and perform a full cleanup.
|
||||
*
|
||||
* Useful when tracking memory leaks, and is immediately implied when
|
||||
* running the process under valgrind.
|
||||
*
|
||||
* default: false
|
||||
*/
|
||||
bool no_early_exit;
|
||||
|
||||
/**
|
||||
* Always return a success from criterion_run_all_tests.
|
||||
*
|
||||
* default: false
|
||||
*/
|
||||
bool always_succeed;
|
||||
|
||||
/**
|
||||
* Disable unicode and ansi coloring from the logging system.
|
||||
*
|
||||
* default: false
|
||||
*/
|
||||
bool use_ascii;
|
||||
|
||||
/**
|
||||
* Exit immediately after the first test failure.
|
||||
*
|
||||
* default: false
|
||||
*/
|
||||
bool fail_fast;
|
||||
|
||||
/**
|
||||
* Disable all tests not matching this extglob pattern.
|
||||
* if NULL, don't filter tests.
|
||||
*
|
||||
* default: NULL
|
||||
*/
|
||||
const char *pattern;
|
||||
|
||||
/**
|
||||
* Only print the base file name compound of the source file containing
|
||||
* the tests during reporting.
|
||||
*
|
||||
* default: false
|
||||
*/
|
||||
bool short_filename;
|
||||
|
||||
/**
|
||||
* The maximum number of parallel jobs that the test runner will spawn.
|
||||
* 0 means that this number shall be the number of cores on your system.
|
||||
*
|
||||
* default: 0
|
||||
*/
|
||||
size_t jobs;
|
||||
|
||||
/**
|
||||
* Measure and report times.
|
||||
*
|
||||
* default: true
|
||||
*/
|
||||
bool measure_time;
|
||||
};
|
||||
|
||||
CR_BEGIN_C_API
|
||||
|
||||
/**
|
||||
* The runtime options for the test runner.
|
||||
*/
|
||||
extern struct criterion_options criterion_options;
|
||||
|
||||
CR_END_C_API
|
||||
|
|
50
include/criterion/output.h
Normal file
50
include/criterion/output.h
Normal file
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright © 2015 Franklin "Snaipe" Mathieu <http://snai.pe/>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
#ifndef CRITERION_OUTPUT_H_
|
||||
# define CRITERION_OUTPUT_H_
|
||||
|
||||
# include "stats.h"
|
||||
|
||||
typedef void criterion_reporter(FILE *stream, struct criterion_global_stats *);
|
||||
|
||||
/**
|
||||
* Register an output provider.
|
||||
*
|
||||
* @param[in] name The name the output provider shall be registered as.
|
||||
* @param[in] reporter The output reporting function.
|
||||
* @returns 1 if no output provider is registered at that name, 0 otherwise,
|
||||
* and -1 on error.
|
||||
*/
|
||||
int criterion_register_output_provider(const char *name, criterion_reporter *reporter);
|
||||
|
||||
/**
|
||||
* Use an output provider to write a report in a specific path.
|
||||
*
|
||||
* @param[in] provider The name of a registered output provider.
|
||||
* @param[in] path The path to the file to write the report to.
|
||||
* @returns -1 on error.
|
||||
*/
|
||||
int criterion_add_output(const char *provider, const char *path);
|
||||
|
||||
#endif /* !CRITERION_OUTPUT_H_ */
|
|
@ -1,50 +1,83 @@
|
|||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright © 2015 Franklin "Snaipe" Mathieu <http://snai.pe/>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
#ifndef CRITERION_PARAMETERIZED_H_
|
||||
# define CRITERION_PARAMETERIZED_H_
|
||||
|
||||
# include "criterion.h"
|
||||
# include "alloc.h"
|
||||
# include "assert.h"
|
||||
# include "internal/parameterized.h"
|
||||
|
||||
/**
|
||||
* ParameterizedTest(Type *param, Suite, Name, [Options...]) { Function Body }
|
||||
*
|
||||
* Defines a new parameterized test.
|
||||
*
|
||||
* A parameterized test only takes one parameter -- to pass multiple parameters,
|
||||
* use a structure type.
|
||||
*
|
||||
* @param Type The type of the parameter.
|
||||
* @param Suite The name of the test suite containing this test.
|
||||
* @param Name The name of the test.
|
||||
* @param Options An optional sequence of designated initializer key/value
|
||||
* pairs as described in the `criterion_test_extra_data` structure
|
||||
* (see criterion/types.h).
|
||||
* Example: .exit_code = 1
|
||||
*/
|
||||
# define ParameterizedTest(...) CR_EXPAND(CR_PARAM_TEST_BASE(__VA_ARGS__, .sentinel_ = 0))
|
||||
|
||||
/**
|
||||
* ParameterizedTestParameters(Suite, Test) { Function Body }
|
||||
*
|
||||
* Defines the parameter generator for the associated parameterized test.
|
||||
*
|
||||
* @param Suite The name of the test suite containing the test.
|
||||
* @param Test The name of the test.
|
||||
* @returns A constructed instance of criterion::parameters, or the result of
|
||||
* the cr_make_param_array macro.
|
||||
*/
|
||||
# define ParameterizedTestParameters(Suite, Name) CR_PARAM_TEST_PARAMS(Suite, Name)
|
||||
|
||||
/**
|
||||
* cr_make_param_array(Type, Array, Len, [Cleanup]);
|
||||
*
|
||||
* Constructs a parameter list used as a return value for a parameter generator.
|
||||
*
|
||||
* @param Type The type of the array subscript.
|
||||
* @param Array The array of parameters.
|
||||
* @param Len The length of the array.
|
||||
* @param Cleanup The optional cleanup function for the array.
|
||||
* @returns The parameter list.
|
||||
*/
|
||||
# define cr_make_param_array(...) CR_EXPAND(cr_make_param_array_(__VA_ARGS__))
|
||||
|
||||
# ifdef __cplusplus
|
||||
# define CR_PARAM_TEST_PROTOTYPE_(Param, Category, Name) \
|
||||
extern "C" void IDENTIFIER_(Category, Name, impl)(Param)
|
||||
# else
|
||||
# define CR_PARAM_TEST_PROTOTYPE_(Param, Category, Name) \
|
||||
void IDENTIFIER_(Category, Name, impl)(Param)
|
||||
# endif
|
||||
# include <vector>
|
||||
|
||||
# define ParameterizedTest(...) \
|
||||
CR_EXPAND(ParameterizedTest_(__VA_ARGS__, .sentinel_ = 0))
|
||||
|
||||
# define ParameterizedTest_(Param, Category, Name, ...) \
|
||||
CR_PARAM_TEST_PROTOTYPE_(Param, Category, Name); \
|
||||
struct criterion_test_extra_data IDENTIFIER_(Category, Name, extra) = \
|
||||
CR_EXPAND(CRITERION_MAKE_STRUCT(struct criterion_test_extra_data, \
|
||||
.kind_ = CR_TEST_PARAMETERIZED, \
|
||||
.param_ = IDENTIFIER_(Category, Name, param), \
|
||||
.identifier_ = #Category "/" #Name, \
|
||||
.file_ = __FILE__, \
|
||||
.line_ = __LINE__, \
|
||||
__VA_ARGS__ \
|
||||
)); \
|
||||
struct criterion_test IDENTIFIER_(Category, Name, meta) = { \
|
||||
#Name, \
|
||||
#Category, \
|
||||
(void(*)(void)) IDENTIFIER_(Category, Name, impl), \
|
||||
&IDENTIFIER_(Category, Name, extra) \
|
||||
}; \
|
||||
SECTION_("cr_tst") \
|
||||
struct criterion_test *IDENTIFIER_(Category, Name, ptr) \
|
||||
= &IDENTIFIER_(Category, Name, meta) SECTION_SUFFIX_; \
|
||||
CR_PARAM_TEST_PROTOTYPE_(Param, Category, Name)
|
||||
|
||||
# define ParameterizedTestParameters(Category, Name) \
|
||||
static struct criterion_test_params IDENTIFIER_(Category, Name, param)(void)
|
||||
|
||||
# ifdef __cplusplus
|
||||
# define cr_make_param_array(Type, Array, ...) \
|
||||
criterion_test_params(sizeof (Type), (Array), __VA_ARGS__)
|
||||
# else
|
||||
# define cr_make_param_array(Type, Array, ...) \
|
||||
(struct criterion_test_params) { .size = sizeof (Type), (void*)(Array), __VA_ARGS__ }
|
||||
namespace criterion {
|
||||
template <typename T>
|
||||
using parameters = std::vector<T, criterion::allocator<T>>;
|
||||
}
|
||||
# endif
|
||||
|
||||
#endif /* !CRITERION_PARAMETERIZED_H_ */
|
||||
|
|
|
@ -24,86 +24,82 @@
|
|||
#ifndef CRITERION_REDIRECT_H_
|
||||
# define CRITERION_REDIRECT_H_
|
||||
|
||||
# include "common.h"
|
||||
# include "assert.h"
|
||||
# include "internal/common.h"
|
||||
# include "internal/redirect.h"
|
||||
|
||||
# ifdef __cplusplus
|
||||
# include <cstdio>
|
||||
# include <memory>
|
||||
# include <fstream>
|
||||
|
||||
# ifdef __GNUC__
|
||||
# if defined(__MINGW32__) || defined(__MINGW64__)
|
||||
# define off_t _off_t
|
||||
# define off64_t _off64_t
|
||||
# endif
|
||||
# include <ext/stdio_sync_filebuf.h>
|
||||
# if defined(__MINGW32__) || defined(__MINGW64__)
|
||||
# undef off_t
|
||||
# undef off64_t
|
||||
# endif
|
||||
# endif
|
||||
# else
|
||||
# include <stdio.h>
|
||||
# endif
|
||||
|
||||
CR_BEGIN_C_API
|
||||
|
||||
/**
|
||||
* Redirect stdout for testing.
|
||||
*/
|
||||
CR_API void cr_redirect_stdout(void);
|
||||
|
||||
/**
|
||||
* Redirect stderr for testing.
|
||||
*/
|
||||
CR_API void cr_redirect_stderr(void);
|
||||
|
||||
/**
|
||||
* Redirect stdin for testing.
|
||||
* This is implicitely called before each test.
|
||||
*/
|
||||
CR_API void cr_redirect_stdin(void);
|
||||
|
||||
/**
|
||||
* Get a file handle representing the read-end of the redirected stdout.
|
||||
*
|
||||
* @returns the file handle.
|
||||
*/
|
||||
CR_API CR_STDN FILE* cr_get_redirected_stdout(void);
|
||||
|
||||
/**
|
||||
* Get a file handle representing the read-end of the redirected stderr.
|
||||
*
|
||||
* @returns the file handle.
|
||||
*/
|
||||
CR_API CR_STDN FILE* cr_get_redirected_stderr(void);
|
||||
|
||||
/**
|
||||
* Get a file handle representing the write-end of the redirected stdin.
|
||||
*
|
||||
* @returns the file handle.
|
||||
*/
|
||||
CR_API CR_STDN FILE* cr_get_redirected_stdin(void);
|
||||
|
||||
/**
|
||||
* Compare the contents of a file with a string.
|
||||
*
|
||||
* @param[in] f The file to compare the contents to.
|
||||
* @param[in] str The string to compare the contents to.
|
||||
* @returns 1 if the contents of the file is equal to the string, 0 otherwise.
|
||||
*/
|
||||
CR_API int cr_file_match_str(CR_STDN FILE* f, const char *str);
|
||||
|
||||
/**
|
||||
* Compare the contents of a file with the contents of another file.
|
||||
*
|
||||
* @param[in] f The first file to compare the contents to.
|
||||
* @param[in] ref The second file to compare the contents to.
|
||||
* @returns 1 if the contents of the files are equal, 0 otherwise.
|
||||
*/
|
||||
CR_API int cr_file_match_file(CR_STDN FILE* f, CR_STDN FILE* ref);
|
||||
|
||||
/**
|
||||
* Create a file mock.
|
||||
*
|
||||
* @param[in] max_size The maximum size in bytes of the file mock.
|
||||
* @returns the file handle representing the mock.
|
||||
*/
|
||||
CR_API CR_STDN FILE *cr_mock_file_size(size_t max_size);
|
||||
|
||||
CR_END_C_API
|
||||
|
||||
# define cr_assert_redir_op_(Fail, Fun, Op, File, Str, ...) \
|
||||
CR_EXPAND(cr_assert_impl( \
|
||||
Fail, \
|
||||
!(Fun((File), (Str)) Op 0), \
|
||||
dummy, \
|
||||
CRITERION_ASSERT_MSG_FILE_STR_MATCH, \
|
||||
(CR_STR(File), Str), \
|
||||
__VA_ARGS__ \
|
||||
))
|
||||
|
||||
# define cr_assert_redir_op_va_(Fail, Fun, Op, ...) \
|
||||
CR_EXPAND(cr_assert_redir_op_( \
|
||||
Fail, \
|
||||
Fun, \
|
||||
Op, \
|
||||
CR_VA_HEAD(__VA_ARGS__), \
|
||||
CR_VA_HEAD(CR_VA_TAIL(__VA_ARGS__)), \
|
||||
CR_VA_TAIL(CR_VA_TAIL(__VA_ARGS__)) \
|
||||
))
|
||||
|
||||
# define cr_assert_redir_f_op_(Fail, Fun, Op, File, Ref, ...) \
|
||||
CR_EXPAND(cr_assert_impl( \
|
||||
Fail, \
|
||||
!(Fun((File), (Ref)) Op 0), \
|
||||
dummy, \
|
||||
CRITERION_ASSERT_MSG_FILE_MATCH, \
|
||||
(CR_STR(File), CR_STR(Ref)), \
|
||||
__VA_ARGS__ \
|
||||
))
|
||||
|
||||
# define cr_assert_redir_f_op_va_(Fail, Fun, Op, ...) \
|
||||
CR_EXPAND(cr_assert_redir_op_( \
|
||||
Fail, \
|
||||
Fun, \
|
||||
Op, \
|
||||
CR_VA_HEAD(__VA_ARGS__), \
|
||||
CR_VA_HEAD(CR_VA_TAIL(__VA_ARGS__)), \
|
||||
CR_VA_TAIL(CR_VA_TAIL(__VA_ARGS__)) \
|
||||
))
|
||||
|
||||
# define cr_assert_file_contents_eq_str(...) CR_EXPAND(cr_assert_redir_op_va_(CR_FAIL_ABORT_, cr_file_match_str, ==, __VA_ARGS__))
|
||||
# define cr_expect_file_contents_eq_str(...) CR_EXPAND(cr_assert_redir_op_va_(CR_FAIL_CONTINUES_, cr_file_match_str, ==, __VA_ARGS__))
|
||||
|
||||
|
@ -141,134 +137,24 @@ CR_END_C_API
|
|||
# define cr_expect_stderr_neq(...) CR_EXPAND(cr_assert_redir_f_op_va_(CR_FAIL_CONTINUES_, cr_file_match_file, !=, cr_get_redirected_stderr(), __VA_ARGS__))
|
||||
|
||||
# ifdef __cplusplus
|
||||
# include "internal/stream.hxx"
|
||||
|
||||
namespace criterion {
|
||||
|
||||
template <typename CharT, typename Super>
|
||||
class stream_mixin : public Super {
|
||||
public:
|
||||
stream_mixin(FILE* f)
|
||||
# ifdef __GNUC__
|
||||
: Super()
|
||||
, fbuf(new ::__gnu_cxx::stdio_sync_filebuf<CharT>(f))
|
||||
# else
|
||||
: Super(f)
|
||||
# endif
|
||||
, file(f)
|
||||
{
|
||||
# ifdef __GNUC__
|
||||
std::ios::rdbuf(&*fbuf);
|
||||
# endif
|
||||
}
|
||||
|
||||
stream_mixin(const stream_mixin& other) = delete;
|
||||
stream_mixin& operator=(const stream_mixin& other) = delete;
|
||||
|
||||
stream_mixin(stream_mixin&& other) :
|
||||
# ifdef __GNUC__
|
||||
fbuf(std::move(other.fbuf)),
|
||||
# endif
|
||||
file(std::move(other.file))
|
||||
{}
|
||||
|
||||
stream_mixin& operator=(stream_mixin&& other) {
|
||||
# ifdef __GNUC__
|
||||
fbuf = std::move(other.fbuf);
|
||||
# endif
|
||||
file = std::move(other.file);
|
||||
}
|
||||
|
||||
void close(void) {
|
||||
Super::flush();
|
||||
Super::close();
|
||||
std::fclose(file);
|
||||
}
|
||||
|
||||
private:
|
||||
# ifdef __GNUC__
|
||||
std::shared_ptr<::__gnu_cxx::stdio_sync_filebuf<CharT>> fbuf;
|
||||
# endif
|
||||
std::FILE* file;
|
||||
};
|
||||
|
||||
template <typename CharT>
|
||||
using ofstream_mixin = stream_mixin<CharT, std::basic_ofstream<CharT>>;
|
||||
|
||||
template <typename CharT>
|
||||
using ifstream_mixin = stream_mixin<CharT, std::basic_ifstream<CharT>>;
|
||||
|
||||
template <typename CharT>
|
||||
using fstream_mixin = stream_mixin<CharT, std::basic_fstream<CharT>>;
|
||||
|
||||
template <typename CharT>
|
||||
class basic_ofstream : public ofstream_mixin<CharT> {
|
||||
public:
|
||||
basic_ofstream(FILE* f)
|
||||
: ofstream_mixin<CharT>(f)
|
||||
{}
|
||||
|
||||
basic_ofstream(basic_ofstream&& other)
|
||||
: ofstream_mixin<CharT>(std::move(other))
|
||||
{}
|
||||
};
|
||||
|
||||
template <typename CharT>
|
||||
class basic_ifstream : public ifstream_mixin<CharT> {
|
||||
public:
|
||||
basic_ifstream(FILE* f)
|
||||
: ifstream_mixin<CharT>(f)
|
||||
{}
|
||||
|
||||
basic_ifstream(basic_ifstream&& other)
|
||||
: ifstream_mixin<CharT>(std::move(other))
|
||||
{}
|
||||
};
|
||||
|
||||
template <typename CharT>
|
||||
class basic_fstream : public fstream_mixin<CharT> {
|
||||
public:
|
||||
basic_fstream(FILE* f)
|
||||
: fstream_mixin<CharT>(f)
|
||||
{}
|
||||
|
||||
basic_fstream(basic_fstream&& other)
|
||||
: fstream_mixin<CharT>(std::move(other))
|
||||
{}
|
||||
};
|
||||
|
||||
using ofstream = basic_ofstream<char>;
|
||||
using ifstream = basic_ifstream<char>;
|
||||
using fstream = basic_fstream<char>;
|
||||
|
||||
struct get_redirected_out_stream_ {
|
||||
static inline ofstream& call(std::FILE* f) {
|
||||
static std::unique_ptr<ofstream> stream;
|
||||
|
||||
if (!stream)
|
||||
stream.reset(new ofstream(f));
|
||||
return *stream;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
struct get_redirected_in_stream_ {
|
||||
static inline ifstream& call(std::FILE* f) {
|
||||
static std::unique_ptr<ifstream> stream;
|
||||
if (!stream)
|
||||
stream.reset(new ifstream(f));
|
||||
return *stream;
|
||||
}
|
||||
};
|
||||
typedef internal::basic_ofstream<char> ofstream;
|
||||
typedef internal::basic_ifstream<char> ifstream;
|
||||
typedef internal::basic_fstream<char> fstream;
|
||||
|
||||
static inline ofstream& get_redirected_cin(void) {
|
||||
return get_redirected_out_stream_::call(cr_get_redirected_stdin());
|
||||
return internal::get_redirected_out_stream_::call(cr_get_redirected_stdin());
|
||||
}
|
||||
|
||||
static inline ifstream& get_redirected_cout(void) {
|
||||
return get_redirected_in_stream_::call(cr_get_redirected_stdout());
|
||||
return internal::get_redirected_in_stream_::call(cr_get_redirected_stdout());
|
||||
}
|
||||
|
||||
static inline ifstream& get_redirected_cerr(void) {
|
||||
return get_redirected_in_stream_::call(cr_get_redirected_stderr());
|
||||
return internal::get_redirected_in_stream_::call(cr_get_redirected_stderr());
|
||||
}
|
||||
|
||||
# if __GNUC__ >= 5
|
||||
|
|
|
@ -45,6 +45,7 @@ struct criterion_test_stats {
|
|||
int exit_code;
|
||||
float elapsed_time;
|
||||
bool timed_out;
|
||||
bool crashed;
|
||||
unsigned progress;
|
||||
const char *file;
|
||||
|
||||
|
|
|
@ -24,71 +24,71 @@
|
|||
#ifndef CRITERION_THEORIES_H_
|
||||
# define CRITERION_THEORIES_H_
|
||||
|
||||
# ifdef __cplusplus
|
||||
# include <cstddef>
|
||||
using std::size_t;
|
||||
# else
|
||||
# include <stddef.h>
|
||||
# endif
|
||||
|
||||
# include "criterion.h"
|
||||
|
||||
# ifdef __cplusplus
|
||||
template <typename... T>
|
||||
constexpr size_t criterion_va_num__(const T &...) {
|
||||
return sizeof...(T);
|
||||
}
|
||||
# endif
|
||||
# include "internal/theories.h"
|
||||
|
||||
CR_BEGIN_C_API
|
||||
|
||||
struct criterion_theory_context;
|
||||
|
||||
CR_API struct criterion_theory_context* cr_theory_init(void);
|
||||
CR_API void cr_theory_push_arg(struct criterion_theory_context *ctx, bool is_float, size_t size, void *ptr);
|
||||
CR_API void cr_theory_free(struct criterion_theory_context *ctx);
|
||||
/**
|
||||
* Aborts the current theory iteration.
|
||||
* This function does not return.
|
||||
*/
|
||||
CR_API void cr_theory_abort(void);
|
||||
CR_API int cr_theory_mark(void);
|
||||
|
||||
CR_API void cr_theory_reset(struct criterion_theory_context *ctx);
|
||||
CR_API void cr_theory_call(struct criterion_theory_context *ctx, void (*fnptr)(void));
|
||||
CR_END_C_API
|
||||
|
||||
# define TheoryDataPoints(Category, Name) \
|
||||
static struct criterion_datapoints IDENTIFIER_(Category, Name, dps)[]
|
||||
// Theory and datapoint macros
|
||||
|
||||
# define TheoryDataPoint(Category, Name) \
|
||||
(IDENTIFIER_(Category, Name, dps))
|
||||
/**
|
||||
* Theory((Params...), Suite, Name, [Options...]) { Function Body }
|
||||
*
|
||||
* Defines a new theory test.
|
||||
*
|
||||
* The parameters are selected from a cartesian product defined by a
|
||||
* TheoryDataPoints macro.
|
||||
*
|
||||
* @param Params A list of function parameters.
|
||||
* @param Suite The name of the test suite containing this test.
|
||||
* @param Name The name of the test.
|
||||
* @param Options An optional sequence of designated initializer key/value
|
||||
* pairs as described in the `criterion_test_extra_data` structure
|
||||
* (see criterion/types.h).
|
||||
* Example: .exit_code = 1
|
||||
*/
|
||||
# define Theory(Args, ...) CR_EXPAND(CR_THEORY_BASE(Args, __VA_ARGS__))
|
||||
|
||||
# ifdef __cplusplus
|
||||
# define CR_TH_VA_NUM(Type, ...) criterion_va_num__(__VA_ARGS__)
|
||||
# define CR_TH_TEMP_ARRAY(Type, ...) []() { static Type arr[] = { __VA_ARGS__ }; return &arr; }()
|
||||
# else
|
||||
# define CR_TH_VA_NUM(Type, ...) sizeof ((Type[]) { __VA_ARGS__ }) / sizeof (Type)
|
||||
# define CR_TH_TEMP_ARRAY(Type, ...) &(Type[]) { __VA_ARGS__ }
|
||||
# endif
|
||||
/**
|
||||
* TheoryDataPoints(Suite, Name) = { Datapoints... };
|
||||
*
|
||||
* Defines an array of data points.
|
||||
*
|
||||
* The types of the specified data points *must* match the types of the
|
||||
* associated theory.
|
||||
*
|
||||
* Each entry in the array must be the result of the DataPoints macro.
|
||||
*
|
||||
* @param Suite The name of the test suite containing this test.
|
||||
* @param Name The name of the test.
|
||||
*/
|
||||
# define TheoryDataPoints(Category, Name) CR_TH_INTERNAL_TDPS(Category, Name)
|
||||
|
||||
# define DataPoints(Type, ...) { \
|
||||
sizeof (Type), \
|
||||
CR_EXPAND(CR_TH_VA_NUM(Type, __VA_ARGS__)), \
|
||||
#Type, \
|
||||
CR_EXPAND(CR_TH_TEMP_ARRAY(Type, __VA_ARGS__)), \
|
||||
}
|
||||
/**
|
||||
* DataPoints(Type, Values...)
|
||||
*
|
||||
* Defines a new set of data points.
|
||||
*
|
||||
* @param Type The type of each data point in the set.
|
||||
* @param Values The data points in the set.
|
||||
*/
|
||||
# define DataPoints(Type, ...) CR_EXPAND(CR_TH_INTERNAL_DP(Type, __VA_ARGS__))
|
||||
|
||||
struct criterion_datapoints {
|
||||
size_t size;
|
||||
size_t len;
|
||||
const char *name;
|
||||
void *arr;
|
||||
};
|
||||
|
||||
# define CR_NB_DATAPOINTS(Var) \
|
||||
(sizeof (Var) / sizeof (struct criterion_datapoints))
|
||||
// Theory invariants
|
||||
|
||||
# define cr_assume(Condition) \
|
||||
do { \
|
||||
if (!(Condition)) \
|
||||
cr_theory_abort(); \
|
||||
} while (0);
|
||||
} while (0)
|
||||
|
||||
# define cr_assume_not(Condition) cr_assume(!(Condition))
|
||||
|
||||
|
@ -111,35 +111,31 @@ struct criterion_datapoints {
|
|||
cr_assume((Expected) - (Actual) > (Epsilon) \
|
||||
|| (Actual) - (Expected) > (Epsilon))
|
||||
|
||||
# define cr_assume_strings_op_(Op, Actual, Expected) \
|
||||
# define cr_assume_str_op_(Op, Actual, Expected) \
|
||||
cr_assume(strcmp((Actual), (Expected)) Op 0)
|
||||
|
||||
# define cr_assume_strings_eq(Actual, Expected) cr_assume_strings_op_(==, Actual, Expected)
|
||||
# define cr_assume_strings_neq(Actual, Expected) cr_assume_strings_op_(!=, Actual, Expected)
|
||||
# define cr_assume_strings_lt(Actual, Expected) cr_assume_strings_op_(<, Actual, Expected)
|
||||
# define cr_assume_strings_leq(Actual, Expected) cr_assume_strings_op_(<=, Actual, Expected)
|
||||
# define cr_assume_strings_gt(Actual, Expected) cr_assume_strings_op_(>, Actual, Expected)
|
||||
# define cr_assume_strings_geq(Actual, Expected) cr_assume_strings_op_(>=, Actual, Expected)
|
||||
# define cr_assume_str_eq(Actual, Expected) cr_assume_str_op_(==, Actual, Expected)
|
||||
# define cr_assume_str_neq(Actual, Expected) cr_assume_str_op_(!=, Actual, Expected)
|
||||
# define cr_assume_str_lt(Actual, Expected) cr_assume_str_op_(<, Actual, Expected)
|
||||
# define cr_assume_str_leq(Actual, Expected) cr_assume_str_op_(<=, Actual, Expected)
|
||||
# define cr_assume_str_gt(Actual, Expected) cr_assume_str_op_(>, Actual, Expected)
|
||||
# define cr_assume_str_geq(Actual, Expected) cr_assume_str_op_(>=, Actual, Expected)
|
||||
|
||||
# define cr_assume_arrays_eq(Actual, Expected, Size) cr_assume(!memcmp((A), (B), (Size)))
|
||||
# define cr_assume_arrays_neq(Actual, Expected, Size) cr_assume(memcmp((A), (B), (Size)))
|
||||
# define cr_assume_arr_eq(Actual, Expected, Size) cr_assume(!memcmp((A), (B), (Size)))
|
||||
# define cr_assume_arr_neq(Actual, Expected, Size) cr_assume(memcmp((A), (B), (Size)))
|
||||
|
||||
CR_API void cr_theory_main(struct criterion_datapoints *dps, size_t datapoints, void (*fnptr)(void));
|
||||
// Deprecated
|
||||
|
||||
# define CR_VAARG_ID(Suffix, Category, Name, ...) \
|
||||
IDENTIFIER_(Category, Name, Suffix)
|
||||
# ifndef CRITERION_NO_COMPAT
|
||||
# define cr_assume_strings_eq(...) CRITERION_ASSERT_DEPRECATED_B(cr_assume_strings_eq, cr_assume_str_eq) cr_assume_str_eq(__VA_ARGS__)
|
||||
# define cr_assume_strings_neq(...) CRITERION_ASSERT_DEPRECATED_B(cr_assume_strings_neq, cr_assume_str_neq) cr_assume_str_neq(__VA_ARGS__)
|
||||
# define cr_assume_strings_lt(...) CRITERION_ASSERT_DEPRECATED_B(cr_assume_strings_lt, cr_assume_str_lt) cr_assume_str_lt(__VA_ARGS__)
|
||||
# define cr_assume_strings_leq(...) CRITERION_ASSERT_DEPRECATED_B(cr_assume_strings_leq, cr_assume_str_leq) cr_assume_str_leq(__VA_ARGS__)
|
||||
# define cr_assume_strings_gt(...) CRITERION_ASSERT_DEPRECATED_B(cr_assume_strings_gt, cr_assume_str_gt) cr_assume_str_gt(__VA_ARGS__)
|
||||
# define cr_assume_strings_geq(...) CRITERION_ASSERT_DEPRECATED_B(cr_assume_strings_geq, cr_assume_str_geq) cr_assume_str_geq(__VA_ARGS__)
|
||||
|
||||
# define Theory(Args, ...) \
|
||||
void CR_EXPAND(CR_VAARG_ID(theory, __VA_ARGS__,))Args; \
|
||||
CR_EXPAND(Test_(__VA_ARGS__, .sentinel_ = 0)) { \
|
||||
cr_theory_main( \
|
||||
CR_EXPAND(CR_VAARG_ID(dps, __VA_ARGS__,)), \
|
||||
CR_NB_DATAPOINTS(CR_EXPAND(CR_VAARG_ID(dps, __VA_ARGS__,))), \
|
||||
(void(*)(void)) CR_EXPAND(CR_VAARG_ID(theory, __VA_ARGS__,)) \
|
||||
); \
|
||||
} \
|
||||
void CR_EXPAND(CR_VAARG_ID(theory, __VA_ARGS__,))Args
|
||||
|
||||
CR_END_C_API
|
||||
# define cr_assume_arrays_eq(...) CRITERION_ASSERT_DEPRECATED_B(cr_assume_arrays_eq, cr_assume_arr_eq) cr_assume_arr_eq(__VA_ARGS__)
|
||||
# define cr_assume_arrays_neq(...) CRITERION_ASSERT_DEPRECATED_B(cr_assume_arrays_neq, cr_assume_arr_neq) cr_assume_arr_neq(__VA_ARGS__)
|
||||
# endif
|
||||
|
||||
#endif /* !CRITERION_THEORIES_H_ */
|
||||
|
|
|
@ -24,61 +24,78 @@
|
|||
#ifndef CRITERION_TYPES_H_
|
||||
# define CRITERION_TYPES_H_
|
||||
|
||||
# include "alloc.h"
|
||||
# ifdef __cplusplus
|
||||
# include <cstddef>
|
||||
# include <vector>
|
||||
using std::size_t;
|
||||
# else
|
||||
# include <stdbool.h>
|
||||
# include <stddef.h>
|
||||
# endif
|
||||
# include "common.h"
|
||||
# include "internal/common.h"
|
||||
|
||||
/**
|
||||
* Enumerates the supported languages for tests
|
||||
*/
|
||||
enum criterion_language {
|
||||
CR_LANG_C, /// C
|
||||
CR_LANG_CXX, /// C++
|
||||
CR_LANG_OBJC, /// Objective-C
|
||||
CR_LANG_OBJCXX, /// Objective-C++
|
||||
|
||||
CR_LANG_SIZE_ // leave this at the end
|
||||
};
|
||||
|
||||
extern const char *const cr_language_names[CR_LANG_SIZE_];
|
||||
|
||||
/**
|
||||
* Enumerates the supported kinds of tests
|
||||
*/
|
||||
enum criterion_test_kind {
|
||||
CR_TEST_NORMAL,
|
||||
CR_TEST_PARAMETERIZED,
|
||||
};
|
||||
|
||||
struct criterion_test_params {
|
||||
size_t size;
|
||||
void *params;
|
||||
size_t length;
|
||||
void (*cleanup)(struct criterion_test_params *);
|
||||
|
||||
# ifdef __cplusplus
|
||||
constexpr criterion_test_params(size_t size, void *params, size_t length)
|
||||
: size(size)
|
||||
, params(params)
|
||||
, length(length)
|
||||
, cleanup(nullptr)
|
||||
{}
|
||||
|
||||
constexpr criterion_test_params(size_t size, void *params, size_t length,
|
||||
void (*cleanup)(struct criterion_test_params *))
|
||||
: size(size)
|
||||
, params(params)
|
||||
, length(length)
|
||||
, cleanup(cleanup)
|
||||
{}
|
||||
# endif
|
||||
};
|
||||
/**
|
||||
* Represents a set of parameters for a parameterized test.
|
||||
*/
|
||||
struct criterion_test_params;
|
||||
|
||||
/**
|
||||
* Contains all the options that can be set for a test, through
|
||||
* the Test and TestSuite macros, or other means.
|
||||
*/
|
||||
struct criterion_test_extra_data {
|
||||
// Start of private API
|
||||
/*
|
||||
* Warning: the fields below are not meant to be set manually.
|
||||
* Setting them improperly *will* wreck havock in your tests.
|
||||
*
|
||||
* You've been warned.
|
||||
*/
|
||||
int sentinel_;
|
||||
enum criterion_language lang_;
|
||||
enum criterion_test_kind kind_;
|
||||
struct criterion_test_params (*param_)(void);
|
||||
const char *identifier_;
|
||||
const char *file_;
|
||||
unsigned line_;
|
||||
void (*init)(void);
|
||||
void (*fini)(void);
|
||||
int signal;
|
||||
int exit_code;
|
||||
bool disabled;
|
||||
const char *description;
|
||||
double timeout;
|
||||
void *data;
|
||||
// Enf of private API
|
||||
|
||||
void (*init)(void); /// The setup test fixture
|
||||
void (*fini)(void); /// The setup test fixture
|
||||
int signal; /// The expected signal raised by the test (or 0 if none)
|
||||
int exit_code; /// The expected exit code returned by the test
|
||||
bool disabled; /// Whether the test is disabled or not
|
||||
const char *description; /// The description of a test
|
||||
double timeout; /// A timeout for the test in seconds
|
||||
void *data; /// Extra user data
|
||||
};
|
||||
|
||||
/**
|
||||
* Represents a test
|
||||
*/
|
||||
struct criterion_test {
|
||||
const char *name;
|
||||
const char *category;
|
||||
|
@ -86,6 +103,9 @@ struct criterion_test {
|
|||
struct criterion_test_extra_data *data;
|
||||
};
|
||||
|
||||
/**
|
||||
* Represents a test suite
|
||||
*/
|
||||
struct criterion_suite {
|
||||
const char *name;
|
||||
struct criterion_test_extra_data *data;
|
||||
|
@ -103,6 +123,4 @@ struct criterion_test_set {
|
|||
size_t tests;
|
||||
};
|
||||
|
||||
typedef void (*f_worker_func)(struct criterion_test *, struct criterion_suite *);
|
||||
|
||||
#endif /* !CRITERION_TYPES_H_ */
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# List of source files which contain translatable strings.
|
||||
src/log/normal.c
|
||||
src/string/i18n.c
|
||||
src/core/runner.c
|
||||
src/io/output.c
|
||||
|
|
75
po/fr.po
75
po/fr.po
|
@ -8,7 +8,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: criterion 2.0.0\n"
|
||||
"Report-Msgid-Bugs-To: franklinmathieu+criterion@gmail.com\n"
|
||||
"POT-Creation-Date: 2015-09-16 21:18+0200\n"
|
||||
"POT-Creation-Date: 2015-11-27 12:24+0100\n"
|
||||
"PO-Revision-Date: 2015-04-03 17:58+0200\n"
|
||||
"Last-Translator: <franklinmathieu@gmail.com>\n"
|
||||
"Language-Team: French\n"
|
||||
|
@ -18,65 +18,70 @@ msgstr ""
|
|||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
||||
|
||||
#: src/log/normal.c:50
|
||||
#: src/log/normal.c:42
|
||||
#, c-format
|
||||
msgid "Criterion v%s\n"
|
||||
msgstr "Criterion v%s\n"
|
||||
|
||||
#: src/log/normal.c:51
|
||||
#: src/log/normal.c:43
|
||||
#, c-format
|
||||
msgid " %s\n"
|
||||
msgstr " %s\n"
|
||||
|
||||
#: src/log/normal.c:54 src/log/normal.c:56
|
||||
#: src/log/normal.c:46 src/log/normal.c:48
|
||||
#, c-format
|
||||
msgid "%1$s::%2$s\n"
|
||||
msgstr "%1$s::%2$s\n"
|
||||
|
||||
#: src/log/normal.c:55
|
||||
#: src/log/normal.c:47
|
||||
#, fuzzy, c-format
|
||||
msgid "%1$s::%2$s: (%3$3.2fs)\n"
|
||||
msgstr "%1$s::%2$s: (%3$3.2fs)\n"
|
||||
|
||||
#: src/log/normal.c:57
|
||||
#: src/log/normal.c:49
|
||||
#, c-format
|
||||
msgid "%1$s::%2$s: Test is disabled\n"
|
||||
msgstr "%1$s::%2$s: Le test est désactivé\n"
|
||||
|
||||
#: src/log/normal.c:58
|
||||
#: src/log/normal.c:50
|
||||
#, c-format
|
||||
msgid "%1$s::%2$s: Suite is disabled\n"
|
||||
msgstr "%1$s::%2$s: La suite est désactivée\n"
|
||||
|
||||
#: src/log/normal.c:59
|
||||
#: src/log/normal.c:51
|
||||
#, c-format
|
||||
msgid "%1$s%2$s%3$s:%4$s%5$d%6$s: Assertion failed: %7$s\n"
|
||||
msgstr "%1$s%2$s%3$s:%4$s%5$d%6$s: Échec d'assertion: %7$s\n"
|
||||
|
||||
#: src/log/normal.c:60
|
||||
#: src/log/normal.c:52
|
||||
#, fuzzy, c-format
|
||||
msgid " Theory %1$s::%2$s failed with the following parameters: (%3$s)\n"
|
||||
msgstr ""
|
||||
" La théorie %1$s::%2$s a échoué avec les paramètres suivants: (%3$s)\n"
|
||||
|
||||
#: src/log/normal.c:61
|
||||
#: src/log/normal.c:53
|
||||
#, fuzzy, c-format
|
||||
msgid "%1$s::%2$s: Timed out. (%3$3.2fs)\n"
|
||||
msgstr "%1$s::%2$s: Délai expiré. (%3$3.2fs)\n"
|
||||
|
||||
#: src/log/normal.c:62
|
||||
#: src/log/normal.c:54
|
||||
#, c-format
|
||||
msgid "%1$s%2$s%3$s:%4$s%5$u%6$s: Unexpected signal caught below this line!\n"
|
||||
msgstr ""
|
||||
"%1$s%2$s%3$s:%4$s%5$u%6$s: Un signal inattendu a été reçu après cette "
|
||||
"ligne!\n"
|
||||
|
||||
#: src/log/normal.c:63
|
||||
#: src/log/normal.c:55
|
||||
#, c-format
|
||||
msgid "%1$s::%2$s: CRASH!\n"
|
||||
msgstr "%1$s::%2$s: PLANTAGE!\n"
|
||||
|
||||
#: src/log/normal.c:64
|
||||
#: src/log/normal.c:56
|
||||
#, fuzzy, c-format
|
||||
msgid "%1$s::%2$s: %3$s\n"
|
||||
msgstr "%1$s::%2$s: (%3$3.2fs)\n"
|
||||
|
||||
#: src/log/normal.c:57
|
||||
#, fuzzy, c-format
|
||||
msgid ""
|
||||
"%1$sWarning! The test `%2$s::%3$s` crashed during its setup or teardown."
|
||||
|
@ -85,7 +90,7 @@ msgstr ""
|
|||
"%1$sAttention! Le test `%2$s::%3$s` a planté pendant son initialisation ou "
|
||||
"sa finalisation.%4$s\n"
|
||||
|
||||
#: src/log/normal.c:65
|
||||
#: src/log/normal.c:58
|
||||
#, fuzzy, c-format
|
||||
msgid ""
|
||||
"%1$sWarning! The test `%2$s::%3$s` exited during its setup or teardown.%4$s\n"
|
||||
|
@ -93,14 +98,14 @@ msgstr ""
|
|||
"%1$sAttention! Le test `%2$s::%3$s` a quitté pendant son initialisation ou "
|
||||
"sa finalisation.%4$s\n"
|
||||
|
||||
#: src/log/normal.c:66
|
||||
#: src/log/normal.c:59
|
||||
#, c-format
|
||||
msgid "Running %1$s%2$lu%3$s test from %4$s%5$s%6$s:\n"
|
||||
msgid_plural "Running %1$s%2$lu%3$s tests from %4$s%5$s%6$s:\n"
|
||||
msgstr[0] "Lancement de %1$s%2$lu%3$s test dans %4$s%5$s%6$s:\n"
|
||||
msgstr[1] "Lancement de %1$s%2$lu%3$s tests dans %4$s%5$s%6$s:\n"
|
||||
|
||||
#: src/log/normal.c:68
|
||||
#: src/log/normal.c:61
|
||||
#, c-format
|
||||
msgid ""
|
||||
"%1$sSynthesis: Tested: %2$s%3$lu%4$s | Passing: %5$s%6$lu%7$s | Failing: %8$s"
|
||||
|
@ -109,6 +114,11 @@ msgstr ""
|
|||
"%1$sSynthèse: Testés: %2$s%3$lu%4$s | Validés: %5$s%6$lu%7$s | Échoués: %8$s"
|
||||
"%9$lu%10$s | Plantages: %11$s%12$lu%13$s %14$s\n"
|
||||
|
||||
#: src/log/normal.c:77
|
||||
#, fuzzy, c-format
|
||||
msgid "%s::%s: %s\n"
|
||||
msgstr "%1$s::%2$s: (%3$3.2fs)\n"
|
||||
|
||||
#: src/string/i18n.c:13
|
||||
msgid "The conditions for this assertion were not met."
|
||||
msgstr "Les conditions de cette assertion n'ont pas été remplies."
|
||||
|
@ -174,3 +184,36 @@ msgstr "L'instruction `%1$s` a levé une instance de l'exception `%2$s`."
|
|||
#, c-format
|
||||
msgid "The statement `%1$s` did not throw an instance of the `%2$s` exception."
|
||||
msgstr "L'instruction `%1$s` n'a pas levé d'instance de l'exception `%2$s`."
|
||||
|
||||
#: src/core/runner.c:58
|
||||
#, c-format
|
||||
msgid ""
|
||||
"%1$sWarning! Criterion has detected that it is running under valgrind, but "
|
||||
"the no_early_exit option is explicitely disabled. Reports will not be "
|
||||
"accurate!%2$s\n"
|
||||
msgstr ""
|
||||
"%1$sAttention! Criterion a détecté qu'il a été lancé avec valgrind, mais "
|
||||
"l'option no_early_exit est explicitement désactivée. Les rapports d'erreur "
|
||||
"ne seront pas précis!%2$s\n"
|
||||
|
||||
#: src/core/runner.c:62
|
||||
#, c-format
|
||||
msgid ""
|
||||
"%1$sWarning! Criterion has detected that it is running under valgrind, but "
|
||||
"the number of jobs have been explicitely set. Reports might appear confusing!"
|
||||
"%2$s\n"
|
||||
msgstr ""
|
||||
"%1$sAttention! Criterion a détecté qu'il a été lancé avec valgrind, mais le "
|
||||
"nombre de tâches est explicitement défini. Les rapports d'erreur risquent "
|
||||
"d'être déroutants!%2$s\n"
|
||||
|
||||
#: src/io/output.c:13
|
||||
#, fuzzy, c-format
|
||||
msgid "Could not open the file @ `%1$s` for %2$s reporting: %3$s.\n"
|
||||
msgstr ""
|
||||
"Impossible d'ouvrir le fichier `%1$s` pour faire le rapport %2$s: %3$s.\n"
|
||||
|
||||
#: src/io/output.c:14
|
||||
#, c-format
|
||||
msgid "Writing %1$s report in `%2$s`.\n"
|
||||
msgstr "Écriture du rapport %1$s dans `%2$s`.\n"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
if (NOT MSVC)
|
||||
set(CMAKE_C_FLAGS "-std=c99 -Wall -Wextra -pedantic")
|
||||
set(CMAKE_CXX_FLAGS "-std=c++11 -Wall -Wextra -pedantic")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS_DEFAULT} -std=c99 -Wall -Wextra -pedantic")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS_DEFAULT} ${CXX11_FLAG} -Wall -Wextra -pedantic")
|
||||
endif ()
|
||||
|
||||
include_directories(../include)
|
||||
|
@ -14,25 +14,38 @@ set(SAMPLES
|
|||
more-suites.c
|
||||
description.c
|
||||
simple.c
|
||||
theories.c
|
||||
timeout.c
|
||||
redirect.c
|
||||
parameterized.c
|
||||
|
||||
signal.cc
|
||||
report.cc
|
||||
suites.cc
|
||||
fixtures.cc
|
||||
asserts.cc
|
||||
more-suites.cc
|
||||
description.cc
|
||||
simple.cc
|
||||
theories.cc
|
||||
redirect.cc
|
||||
)
|
||||
|
||||
if (CMAKE_CXX_COMPILER_WORKS)
|
||||
set(SAMPLES ${SAMPLES}
|
||||
signal.cc
|
||||
report.cc
|
||||
suites.cc
|
||||
fixtures.cc
|
||||
asserts.cc
|
||||
more-suites.cc
|
||||
description.cc
|
||||
simple.cc
|
||||
redirect.cc
|
||||
parameterized.cc
|
||||
)
|
||||
endif ()
|
||||
|
||||
if (THEORIES)
|
||||
set(SAMPLES ${SAMPLES} theories.c)
|
||||
if (CMAKE_CXX_COMPILER_WORKS)
|
||||
set(SAMPLES ${SAMPLES} theories.cc)
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
set(SCRIPTS
|
||||
tap_test
|
||||
xml_test
|
||||
json_test
|
||||
early_exit
|
||||
verbose
|
||||
list
|
||||
|
@ -65,6 +78,8 @@ macro(add_samples DIR_ SAMPLES_)
|
|||
ENVIRONMENT "CRITERION_ALWAYS_SUCCEED=1"
|
||||
ENVIRONMENT "CRITERION_SHORT_FILENAME=1"
|
||||
ENVIRONMENT "CRITERION_NO_EARLY_EXIT=1" # for coverage
|
||||
ENVIRONMENT "CRITERION_JOBS=1" # for output ordering
|
||||
ENVIRONMENT "CRITERION_DISABLE_TIME_MEASUREMENTS=1" # do not compare timings
|
||||
)
|
||||
endif ()
|
||||
endforeach()
|
||||
|
@ -75,18 +90,19 @@ add_samples("${CMAKE_CURRENT_LIST_DIR}/tests" "${SAMPLES}")
|
|||
if (NOT MSVC) # we disable the scripted tests when building with MSVC
|
||||
|
||||
foreach(script ${SCRIPTS})
|
||||
add_test(${script} sh ${CMAKE_CURRENT_LIST_DIR}/tests/${script}.sh)
|
||||
add_test(${script} sh "${CMAKE_CURRENT_LIST_DIR}/tests/${script}.sh")
|
||||
set_property(TEST ${script} PROPERTY
|
||||
ENVIRONMENT "CRITERION_ALWAYS_SUCCEED=1"
|
||||
ENVIRONMENT "CRITERION_NO_EARLY_EXIT=1" # for coverage
|
||||
)
|
||||
|
||||
add_test(${script}_compare sh ${CMAKE_CURRENT_LIST_DIR}/tests/run_test.sh "${CMAKE_CURRENT_LIST_DIR}" . "${CMAKE_CURRENT_LIST_DIR}" tests/${script})
|
||||
add_test(${script}_compare sh ${CMAKE_CURRENT_LIST_DIR}/tests/run_test.sh "${CMAKE_CURRENT_LIST_DIR}" . "${CMAKE_CURRENT_LIST_DIR}" "tests/${script}.sh")
|
||||
set_property(TEST ${script}_compare PROPERTY
|
||||
ENVIRONMENT "LC_ALL=en_US.utf8"
|
||||
ENVIRONMENT "CRITERION_ALWAYS_SUCCEED=1"
|
||||
ENVIRONMENT "CRITERION_SHORT_FILENAME=1"
|
||||
ENVIRONMENT "CRITERION_NO_EARLY_EXIT=1" # for coverage
|
||||
ENVIRONMENT "CRITERION_JOBS=1" # for output ordering
|
||||
)
|
||||
endforeach()
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
[[0;34m----[0m] [0;1masserts.c[0m:[0;31m11[0m: Assertion failed: assert is fatal, expect isn't
|
||||
[[0;34m----[0m] [0;1masserts.c[0m:[0;31m12[0m: Assertion failed: This assert runs
|
||||
[[0;31mFAIL[0m] asserts::base: (0.00s)
|
||||
[[0;31mFAIL[0m] asserts::base
|
||||
[[0;34m----[0m] [0;1masserts.c[0m:[0;31m17[0m: Assertion failed: You can fail an assertion with a message from anywhere
|
||||
[[0;34m----[0m] [0;1masserts.c[0m:[0;31m18[0m: Assertion failed: The conditions for this assertion were not met.
|
||||
[[0;31mFAIL[0m] asserts::old_school: (0.00s)
|
||||
[[0;31mFAIL[0m] asserts::old_school
|
||||
[[0;34m====[0m] [0;1mSynthesis: Tested: [0;34m6[0;1m | Passing: [0;32m4[0;1m | Failing: [0;31m2[0;1m | Crashing: [0;31m0[0;1m [0m
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
[[0;34m----[0m] [0;1masserts.cc[0m:[0;31m83[0m: Assertion failed: The expression (&s1)[0 .. 2] == (&s2)[0 .. 2] is false.
|
||||
[[0;31mFAIL[0m] asserts::array: (0.00s)
|
||||
[[0;31mFAIL[0m] asserts::array
|
||||
[[0;34m----[0m] [0;1masserts.cc[0m:[0;31m13[0m: Assertion failed: assert is fatal, expect isn't
|
||||
[[0;34m----[0m] [0;1masserts.cc[0m:[0;31m14[0m: Assertion failed: This assert runs
|
||||
[[0;31mFAIL[0m] asserts::base: (0.00s)
|
||||
[[0;31mFAIL[0m] asserts::base
|
||||
[[0;34m----[0m] [0;1masserts.cc[0m:[0;31m89[0m: Assertion failed: The statement `throw std::exception()` did not throw an instance of the `std::bad_alloc` exception.
|
||||
[[0;31mFAIL[0m] asserts::exception: (0.00s)
|
||||
[[0;31mFAIL[0m] asserts::exception
|
||||
[[0;34m----[0m] [0;1masserts.cc[0m:[0;31m19[0m: Assertion failed: You can fail an assertion with a message from anywhere
|
||||
[[0;34m----[0m] [0;1masserts.cc[0m:[0;31m20[0m: Assertion failed: The conditions for this assertion were not met.
|
||||
[[0;31mFAIL[0m] asserts::old_school: (0.00s)
|
||||
[[0;31mFAIL[0m] asserts::old_school
|
||||
[[0;34m====[0m] [0;1mSynthesis: Tested: [0;34m7[0;1m | Passing: [0;32m3[0;1m | Failing: [0;31m4[0;1m | Crashing: [0;31m0[0;1m [0m
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
[[0;34m----[0m] [0;1mdescription.c[0m:[0;31m4[0m: Assertion failed: The expression 0 is false.
|
||||
[[0;31mFAIL[0m] misc::failing: (0.00s)
|
||||
[[0;31mFAIL[0m] misc::failing
|
||||
[[0;34m====[0m] [0;1mSynthesis: Tested: [0;34m1[0;1m | Passing: [0;32m0[0;1m | Failing: [0;31m1[0;1m | Crashing: [0;31m0[0;1m [0m
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
[[0;34m----[0m] [0;1mdescription.cc[0m:[0;31m4[0m: Assertion failed: The expression 0 is false.
|
||||
[[0;31mFAIL[0m] misc::failing: (0.00s)
|
||||
[[0;31mFAIL[0m] misc::failing
|
||||
[[0;34m====[0m] [0;1mSynthesis: Tested: [0;34m1[0;1m | Passing: [0;32m0[0;1m | Failing: [0;31m1[0;1m | Crashing: [0;31m0[0;1m [0m
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
[[0;34m----[0m] [0;1mparameterized.c[0m:[0;31m76[0m: Assertion failed: Parameters: (1, 2.000000)
|
||||
[[0;31mFAIL[0m] params::cleanup: (0.00s)
|
||||
[[0;31mFAIL[0m] params::cleanup
|
||||
[[0;34m----[0m] [0;1mparameterized.c[0m:[0;31m76[0m: Assertion failed: Parameters: (3, 4.000000)
|
||||
[[0;31mFAIL[0m] params::cleanup: (0.00s)
|
||||
[[0;31mFAIL[0m] params::cleanup
|
||||
[[0;34m----[0m] [0;1mparameterized.c[0m:[0;31m76[0m: Assertion failed: Parameters: (5, 6.000000)
|
||||
[[0;31mFAIL[0m] params::cleanup: (0.00s)
|
||||
[[0;31mFAIL[0m] params::cleanup
|
||||
[[0;34m----[0m] [0;1mparameterized.c[0m:[0;31m36[0m: Assertion failed: Parameters: (1, 2.000000)
|
||||
[[0;31mFAIL[0m] params::multiple: (0.00s)
|
||||
[[0;31mFAIL[0m] params::multiple
|
||||
[[0;34m----[0m] [0;1mparameterized.c[0m:[0;31m36[0m: Assertion failed: Parameters: (3, 4.000000)
|
||||
[[0;31mFAIL[0m] params::multiple: (0.00s)
|
||||
[[0;31mFAIL[0m] params::multiple
|
||||
[[0;34m----[0m] [0;1mparameterized.c[0m:[0;31m36[0m: Assertion failed: Parameters: (5, 6.000000)
|
||||
[[0;31mFAIL[0m] params::multiple: (0.00s)
|
||||
[[0;31mFAIL[0m] params::multiple
|
||||
[[0;34m----[0m] [0;1mparameterized.c[0m:[0;31m15[0m: Assertion failed: Parameter: foo
|
||||
[[0;31mFAIL[0m] params::str: (0.00s)
|
||||
[[0;31mFAIL[0m] params::str
|
||||
[[0;34m----[0m] [0;1mparameterized.c[0m:[0;31m15[0m: Assertion failed: Parameter: bar
|
||||
[[0;31mFAIL[0m] params::str: (0.00s)
|
||||
[[0;31mFAIL[0m] params::str
|
||||
[[0;34m----[0m] [0;1mparameterized.c[0m:[0;31m15[0m: Assertion failed: Parameter: baz
|
||||
[[0;31mFAIL[0m] params::str: (0.00s)
|
||||
[[0;31mFAIL[0m] params::str
|
||||
[[0;34m====[0m] [0;1mSynthesis: Tested: [0;34m9[0;1m | Passing: [0;32m0[0;1m | Failing: [0;31m9[0;1m | Crashing: [0;31m0[0;1m [0m
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
[[0;34m----[0m] [0;1mreport.c[0m:[0;31m5[0m: Assertion failed: The expression 0 is false.
|
||||
[[0;31mFAIL[0m] sample::test: (0.00s)
|
||||
[[0;31mFAIL[0m] sample::test
|
||||
[[0;34m====[0m] [0;1mSynthesis: Tested: [0;34m1[0;1m | Passing: [0;32m0[0;1m | Failing: [0;31m1[0;1m | Crashing: [0;31m0[0;1m [0m
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
[[0;34m----[0m] [0;1mreport.cc[0m:[0;31m5[0m: Assertion failed: The expression 0 is false.
|
||||
[[0;31mFAIL[0m] sample::test: (0.00s)
|
||||
[[0;31mFAIL[0m] sample::test
|
||||
[[0;34m====[0m] [0;1mSynthesis: Tested: [0;34m1[0;1m | Passing: [0;32m0[0;1m | Failing: [0;31m1[0;1m | Crashing: [0;31m0[0;1m [0m
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
[[0;34m----[0m] [0;1msignal.c[0m:[0;31m16[0m: Unexpected signal caught below this line!
|
||||
[[0;31mFAIL[0m] simple::uncaught: CRASH!
|
||||
[[0;31mFAIL[0m] simple::wrong_signal: (0.00s)
|
||||
[[0;31mFAIL[0m] simple::wrong_signal
|
||||
[[0;34m====[0m] [0;1mSynthesis: Tested: [0;34m3[0;1m | Passing: [0;32m1[0;1m | Failing: [0;31m2[0;1m | Crashing: [0;31m1[0;1m [0m
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
[[0;34m----[0m] [0;1msignal.cc[0m:[0;31m16[0m: Unexpected signal caught below this line!
|
||||
[[0;31mFAIL[0m] simple::uncaught: CRASH!
|
||||
[[0;31mFAIL[0m] simple::wrong_signal: (0.00s)
|
||||
[[0;31mFAIL[0m] simple::wrong_signal
|
||||
[[0;34m====[0m] [0;1mSynthesis: Tested: [0;34m3[0;1m | Passing: [0;32m1[0;1m | Failing: [0;31m2[0;1m | Crashing: [0;31m1[0;1m [0m
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
[[0;34m----[0m] [0;1msimple.c[0m:[0;31m4[0m: Assertion failed: The expression 0 is false.
|
||||
[[0;31mFAIL[0m] misc::failing: (0.00s)
|
||||
[[0;31mFAIL[0m] misc::failing
|
||||
[[0;34m====[0m] [0;1mSynthesis: Tested: [0;34m2[0;1m | Passing: [0;32m1[0;1m | Failing: [0;31m1[0;1m | Crashing: [0;31m0[0;1m [0m
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
[[0;34m----[0m] [0;1msimple.cc[0m:[0;31m4[0m: Assertion failed: The expression 0 is false.
|
||||
[[0;31mFAIL[0m] misc::failing: (0.00s)
|
||||
[[0;31mFAIL[0m] misc::failing
|
||||
[[0;34m====[0m] [0;1mSynthesis: Tested: [0;34m2[0;1m | Passing: [0;32m1[0;1m | Failing: [0;31m1[0;1m | Crashing: [0;31m0[0;1m [0m
|
||||
|
|
75
samples/parameterized.cc
Normal file
75
samples/parameterized.cc
Normal file
|
@ -0,0 +1,75 @@
|
|||
#include <criterion/parameterized.h>
|
||||
|
||||
// Basic usage
|
||||
|
||||
ParameterizedTestParameters(params, str) {
|
||||
static const char *strings[] = {
|
||||
"foo", "bar", "baz"
|
||||
};
|
||||
|
||||
return cr_make_param_array(const char *, strings, sizeof (strings) / sizeof (const char *));
|
||||
}
|
||||
|
||||
ParameterizedTest(const char **str, params, str) {
|
||||
cr_assert_fail("Parameter: %s", *str);
|
||||
}
|
||||
|
||||
// Multiple parameters must be coalesced in a single parameter
|
||||
|
||||
struct parameter_tuple {
|
||||
int i;
|
||||
double d;
|
||||
};
|
||||
|
||||
ParameterizedTestParameters(params, multiple) {
|
||||
static struct parameter_tuple params[] = {
|
||||
{1, 2},
|
||||
{3, 4},
|
||||
{5, 6},
|
||||
};
|
||||
|
||||
return criterion_test_params(params);
|
||||
}
|
||||
|
||||
ParameterizedTest(struct parameter_tuple *tup, params, multiple) {
|
||||
cr_assert_fail("Parameters: (%d, %f)", tup->i, tup->d);
|
||||
}
|
||||
|
||||
// Using dynamically generated parameters
|
||||
|
||||
// you **MUST** use new_obj, new_arr, delete_obj, delete_arr instead of
|
||||
// the new, new[], delete and delete[] operators (respectively) to allocate and
|
||||
// deallocate dynamic memory in parameters, otherwise this will crash on
|
||||
// Windows builds of the test.
|
||||
|
||||
// the criterion::allocator<T> allocator may be used with STL containers to
|
||||
// allocate objects with the functions described above.
|
||||
|
||||
using criterion::new_obj;
|
||||
using criterion::new_arr;
|
||||
using criterion::delete_obj;
|
||||
using criterion::delete_arr;
|
||||
|
||||
struct parameter_tuple_dyn {
|
||||
int i;
|
||||
std::unique_ptr<double, decltype(criterion::free)> d;
|
||||
|
||||
parameter_tuple_dyn() : i(0), d(nullptr, criterion::free) {}
|
||||
parameter_tuple_dyn(int i, double *d) : i(i), d(d, criterion::free) {}
|
||||
};
|
||||
|
||||
ParameterizedTestParameters(params, cleanup) {
|
||||
static criterion::parameters<parameter_tuple_dyn> params;
|
||||
|
||||
params.push_back(parameter_tuple_dyn(1, new_obj<double>(2)));
|
||||
params.push_back(parameter_tuple_dyn(3, new_obj<double>(4)));
|
||||
params.push_back(parameter_tuple_dyn(5, new_obj<double>(6)));
|
||||
|
||||
// A criterion::parameters<T> can be returned in place of a
|
||||
// criterion_test_params.
|
||||
return params;
|
||||
}
|
||||
|
||||
ParameterizedTest(parameter_tuple_dyn *tup, params, cleanup) {
|
||||
cr_assert_fail("Parameters: (%d, %f)", tup->i, *tup->d);
|
||||
}
|
|
@ -4,10 +4,24 @@ set(SAMPLES
|
|||
long-messages.c
|
||||
other-crashes.c
|
||||
|
||||
failmessages.cc
|
||||
exit.cc
|
||||
long-messages.cc
|
||||
other-crashes.cc
|
||||
)
|
||||
|
||||
if (CMAKE_CXX_COMPILER_WORKS)
|
||||
set(SAMPLES ${SAMPLES}
|
||||
failmessages.cc
|
||||
exit.cc
|
||||
long-messages.cc
|
||||
other-crashes.cc
|
||||
|
||||
exception.cc
|
||||
)
|
||||
endif ()
|
||||
|
||||
if (THEORIES)
|
||||
set(SAMPLES ${SAMPLES} theories_regression.c)
|
||||
if (CMAKE_CXX_COMPILER_WORKS)
|
||||
set(SAMPLES ${SAMPLES} theories_regression.cc)
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
add_samples("${CMAKE_CURRENT_LIST_DIR}" "${SAMPLES}")
|
||||
|
|
18
samples/tests/exception.cc
Normal file
18
samples/tests/exception.cc
Normal file
|
@ -0,0 +1,18 @@
|
|||
#include <criterion/criterion.h>
|
||||
#include <stdexcept>
|
||||
|
||||
void raise_std(void) {
|
||||
throw std::invalid_argument("Some exception message");
|
||||
}
|
||||
|
||||
void raise_any(void) {
|
||||
throw 1;
|
||||
}
|
||||
|
||||
Test(exception, raise_std) { raise_std(); }
|
||||
Test(exception, raise_any) { raise_any(); }
|
||||
|
||||
Test(exception, raise_std_init, .init = raise_std) {}
|
||||
Test(exception, raise_any_init, .init = raise_any) {}
|
||||
Test(exception, raise_std_fini, .fini = raise_std) {}
|
||||
Test(exception, raise_any_fini, .fini = raise_any) {}
|
7
samples/tests/json_test.sh
Executable file
7
samples/tests/json_test.sh
Executable file
|
@ -0,0 +1,7 @@
|
|||
#!/bin/sh
|
||||
./simple.c.bin --json --always-succeed
|
||||
./signal.c.bin --json --always-succeed
|
||||
./asserts.c.bin --json --always-succeed
|
||||
./more-suites.c.bin --json --always-succeed
|
||||
./tests/long-messages.c.bin --json --always-succeed
|
||||
./description.c.bin --json --always-succeed
|
|
@ -17,7 +17,7 @@
|
|||
[[0;34m----[0m] [0;1mfailmessages.c[0m:[0;31m22[0m: Assertion failed: The expression (as strings) ("abc") <= ("aba") is false.
|
||||
[[0;34m----[0m] [0;1mfailmessages.c[0m:[0;31m23[0m: Assertion failed: The expression (as strings) ("abc") > ("abd") is false.
|
||||
[[0;34m----[0m] [0;1mfailmessages.c[0m:[0;31m24[0m: Assertion failed: The expression (as strings) ("abc") >= ("abd") is false.
|
||||
[[0;31mFAIL[0m] messages::default: (0.00s)
|
||||
[[0;31mFAIL[0m] messages::default
|
||||
[[0;34m----[0m] [0;1mfailmessages.c[0m:[0;31m28[0m: Assertion failed: foo bar
|
||||
[[0;34m----[0m] [0;1mfailmessages.c[0m:[0;31m29[0m: Assertion failed: foo bar
|
||||
[[0;34m----[0m] [0;1mfailmessages.c[0m:[0;31m30[0m: Assertion failed: foo bar
|
||||
|
@ -37,5 +37,5 @@
|
|||
[[0;34m----[0m] [0;1mfailmessages.c[0m:[0;31m46[0m: Assertion failed: foo bar
|
||||
[[0;34m----[0m] [0;1mfailmessages.c[0m:[0;31m47[0m: Assertion failed: foo bar
|
||||
[[0;34m----[0m] [0;1mfailmessages.c[0m:[0;31m48[0m: Assertion failed: foo bar
|
||||
[[0;31mFAIL[0m] messages::user: (0.00s)
|
||||
[[0;31mFAIL[0m] messages::user
|
||||
[[0;34m====[0m] [0;1mSynthesis: Tested: [0;34m2[0;1m | Passing: [0;32m0[0;1m | Failing: [0;31m2[0;1m | Crashing: [0;31m0[0;1m [0m
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
[[0;34m----[0m] [0;1mfailmessages.cc[0m:[0;31m28[0m: Assertion failed: The statement `throw std::exception()` did throw an instance of the `std::exception` exception.
|
||||
[[0;34m----[0m] [0;1mfailmessages.cc[0m:[0;31m29[0m: Assertion failed: The statement `{}` did not throw any exception.
|
||||
[[0;34m----[0m] [0;1mfailmessages.cc[0m:[0;31m30[0m: Assertion failed: The statement `throw std::exception()` threw some exception.
|
||||
[[0;31mFAIL[0m] messages::default: (0.00s)
|
||||
[[0;31mFAIL[0m] messages::default
|
||||
[[0;34m----[0m] [0;1mfailmessages.cc[0m:[0;31m34[0m: Assertion failed: foo bar
|
||||
[[0;34m----[0m] [0;1mfailmessages.cc[0m:[0;31m35[0m: Assertion failed: foo bar
|
||||
[[0;34m----[0m] [0;1mfailmessages.cc[0m:[0;31m36[0m: Assertion failed: foo bar
|
||||
|
@ -45,5 +45,5 @@
|
|||
[[0;34m----[0m] [0;1mfailmessages.cc[0m:[0;31m57[0m: Assertion failed: foo bar
|
||||
[[0;34m----[0m] [0;1mfailmessages.cc[0m:[0;31m58[0m: Assertion failed: foo bar
|
||||
[[0;34m----[0m] [0;1mfailmessages.cc[0m:[0;31m59[0m: Assertion failed: foo bar
|
||||
[[0;31mFAIL[0m] messages::user: (0.00s)
|
||||
[[0;31mFAIL[0m] messages::user
|
||||
[[0;34m====[0m] [0;1mSynthesis: Tested: [0;34m2[0;1m | Passing: [0;32m0[0;1m | Failing: [0;31m2[0;1m | Crashing: [0;31m0[0;1m [0m
|
||||
|
|
237
samples/tests/outputs/json_test.sh.err.expected
Normal file
237
samples/tests/outputs/json_test.sh.err.expected
Normal file
|
@ -0,0 +1,237 @@
|
|||
{
|
||||
"id": "Criterion v2.1.0",
|
||||
"passed": 1,
|
||||
"failed": 1,
|
||||
"errored": 0,
|
||||
"skipped": 0,
|
||||
"test_suites": [
|
||||
{
|
||||
"name": "misc",
|
||||
"passed": 1,
|
||||
"failed": 1,
|
||||
"errored": 0,
|
||||
"skipped": 0,
|
||||
"tests": [
|
||||
{
|
||||
"name": "passing",
|
||||
"assertions": 1,
|
||||
"status": "PASSED"
|
||||
},
|
||||
{
|
||||
"name": "failing",
|
||||
"assertions": 1,
|
||||
"status": "FAILED",
|
||||
"messages": [
|
||||
"simple.c:4: The expression 0 is false."
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
{
|
||||
"id": "Criterion v2.1.0",
|
||||
"passed": 1,
|
||||
"failed": 2,
|
||||
"errored": 1,
|
||||
"skipped": 0,
|
||||
"test_suites": [
|
||||
{
|
||||
"name": "simple",
|
||||
"passed": 1,
|
||||
"failed": 2,
|
||||
"errored": 1,
|
||||
"skipped": 0,
|
||||
"tests": [
|
||||
{
|
||||
"name": "wrong_signal",
|
||||
"assertions": 0,
|
||||
"status": "FAILED",
|
||||
"messages": [
|
||||
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "uncaught",
|
||||
"assertions": 0,
|
||||
"status": "ERRORED",
|
||||
"messages": ["The test crashed."]
|
||||
},
|
||||
{
|
||||
"name": "caught",
|
||||
"assertions": 0,
|
||||
"status": "PASSED"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
{
|
||||
"id": "Criterion v2.1.0",
|
||||
"passed": 4,
|
||||
"failed": 2,
|
||||
"errored": 0,
|
||||
"skipped": 0,
|
||||
"test_suites": [
|
||||
{
|
||||
"name": "asserts",
|
||||
"passed": 4,
|
||||
"failed": 2,
|
||||
"errored": 0,
|
||||
"skipped": 0,
|
||||
"tests": [
|
||||
{
|
||||
"name": "string",
|
||||
"assertions": 10,
|
||||
"status": "PASSED"
|
||||
},
|
||||
{
|
||||
"name": "old_school",
|
||||
"assertions": 2,
|
||||
"status": "FAILED",
|
||||
"messages": [
|
||||
"asserts.c:18: The conditions for this assertion were not met.",
|
||||
"asserts.c:17: You can fail an assertion with a message from anywhere"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "native",
|
||||
"assertions": 8,
|
||||
"status": "PASSED"
|
||||
},
|
||||
{
|
||||
"name": "float",
|
||||
"assertions": 2,
|
||||
"status": "PASSED"
|
||||
},
|
||||
{
|
||||
"name": "base",
|
||||
"assertions": 6,
|
||||
"status": "FAILED",
|
||||
"messages": [
|
||||
"asserts.c:12: This assert runs",
|
||||
"asserts.c:11: assert is fatal, expect isn't"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "array",
|
||||
"assertions": 3,
|
||||
"status": "PASSED"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
{
|
||||
"id": "Criterion v2.1.0",
|
||||
"passed": 2,
|
||||
"failed": 0,
|
||||
"errored": 0,
|
||||
"skipped": 1,
|
||||
"test_suites": [
|
||||
{
|
||||
"name": "suite2",
|
||||
"passed": 1,
|
||||
"failed": 0,
|
||||
"errored": 0,
|
||||
"skipped": 0,
|
||||
"tests": [
|
||||
{
|
||||
"name": "test",
|
||||
"assertions": 1,
|
||||
"status": "PASSED"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "suite1",
|
||||
"passed": 1,
|
||||
"failed": 0,
|
||||
"errored": 0,
|
||||
"skipped": 0,
|
||||
"tests": [
|
||||
{
|
||||
"name": "test",
|
||||
"assertions": 1,
|
||||
"status": "PASSED"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "disabled",
|
||||
"passed": 0,
|
||||
"failed": 0,
|
||||
"errored": 0,
|
||||
"skipped": 1,
|
||||
"tests": [
|
||||
{
|
||||
"name": "test",
|
||||
"assertions": 0,
|
||||
"status": "SKIPPED",
|
||||
"messages": ["The test was skipped."]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
{
|
||||
"id": "Criterion v2.1.0",
|
||||
"passed": 0,
|
||||
"failed": 1,
|
||||
"errored": 0,
|
||||
"skipped": 0,
|
||||
"test_suites": [
|
||||
{
|
||||
"name": "sample",
|
||||
"passed": 0,
|
||||
"failed": 1,
|
||||
"errored": 0,
|
||||
"skipped": 0,
|
||||
"tests": [
|
||||
{
|
||||
"name": "long_msg",
|
||||
"assertions": 1,
|
||||
"status": "FAILED",
|
||||
"messages": [
|
||||
"long-messages.c:4: This is",
|
||||
" A long message",
|
||||
" Spawning multiple lines.",
|
||||
" Formatting is respected."
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
{
|
||||
"id": "Criterion v2.1.0",
|
||||
"passed": 0,
|
||||
"failed": 1,
|
||||
"errored": 0,
|
||||
"skipped": 1,
|
||||
"test_suites": [
|
||||
{
|
||||
"name": "misc",
|
||||
"passed": 0,
|
||||
"failed": 1,
|
||||
"errored": 0,
|
||||
"skipped": 1,
|
||||
"tests": [
|
||||
{
|
||||
"name": "skipped",
|
||||
"assertions": 0,
|
||||
"status": "SKIPPED",
|
||||
"messages": ["The test was skipped."]
|
||||
},
|
||||
{
|
||||
"name": "failing",
|
||||
"assertions": 1,
|
||||
"status": "FAILED",
|
||||
"messages": [
|
||||
"description.c:4: The expression 0 is false."
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
0
samples/tests/outputs/json_test.sh.out.expected
Normal file
0
samples/tests/outputs/json_test.sh.out.expected
Normal file
|
@ -2,5 +2,5 @@
|
|||
[[0;34m----[0m] A long message
|
||||
[[0;34m----[0m] Spawning multiple lines.
|
||||
[[0;34m----[0m] Formatting is respected.
|
||||
[[0;31mFAIL[0m] sample::long_msg: (0.00s)
|
||||
[[0;31mFAIL[0m] sample::long_msg
|
||||
[[0;34m====[0m] [0;1mSynthesis: Tested: [0;34m1[0;1m | Passing: [0;32m0[0;1m | Failing: [0;31m1[0;1m | Crashing: [0;31m0[0;1m [0m
|
||||
|
|
|
@ -2,5 +2,5 @@
|
|||
[[0;34m----[0m] A long message
|
||||
[[0;34m----[0m] Spawning multiple lines.
|
||||
[[0;34m----[0m] Formatting is respected.
|
||||
[[0;31mFAIL[0m] sample::long_msg: (0.00s)
|
||||
[[0;31mFAIL[0m] sample::long_msg
|
||||
[[0;34m====[0m] [0;1mSynthesis: Tested: [0;34m1[0;1m | Passing: [0;32m0[0;1m | Failing: [0;31m1[0;1m | Crashing: [0;31m0[0;1m [0m
|
||||
|
|
61
samples/tests/outputs/tap_test.sh.err.expected
Normal file
61
samples/tests/outputs/tap_test.sh.err.expected
Normal file
|
@ -0,0 +1,61 @@
|
|||
TAP version 13
|
||||
1..2
|
||||
# Criterion v2.1.0
|
||||
|
||||
# Running 2 tests from misc
|
||||
ok - misc::passing (0.00s)
|
||||
not ok - misc::failing (0.00s)
|
||||
simple.c:4: Assertion failed: The expression 0 is false.
|
||||
TAP version 13
|
||||
1..3
|
||||
# Criterion v2.1.0
|
||||
|
||||
# Running 3 tests from simple
|
||||
not ok - simple::wrong_signal (0.00s)
|
||||
not ok - simple::uncaught unexpected signal after signal.c:16
|
||||
ok - simple::caught (0.00s)
|
||||
TAP version 13
|
||||
1..6
|
||||
# Criterion v2.1.0
|
||||
|
||||
# Running 6 tests from asserts
|
||||
ok - asserts::string (0.00s)
|
||||
not ok - asserts::old_school (0.00s)
|
||||
asserts.c:18: Assertion failed: The conditions for this assertion were not met.
|
||||
asserts.c:17: Assertion failed: You can fail an assertion with a message from anywhere
|
||||
ok - asserts::native (0.00s)
|
||||
ok - asserts::float (0.00s)
|
||||
not ok - asserts::base (0.00s)
|
||||
asserts.c:12: Assertion failed: This assert runs
|
||||
asserts.c:11: Assertion failed: assert is fatal, expect isn't
|
||||
ok - asserts::array (0.00s)
|
||||
TAP version 13
|
||||
1..3
|
||||
# Criterion v2.1.0
|
||||
|
||||
# Running 1 tests from suite2
|
||||
ok - suite2::test (0.00s)
|
||||
|
||||
# Running 1 tests from suite1
|
||||
ok - suite1::test (0.00s)
|
||||
|
||||
# Running 1 tests from disabled
|
||||
ok - disabled::test # SKIP suite is disabled
|
||||
TAP version 13
|
||||
1..1
|
||||
# Criterion v2.1.0
|
||||
|
||||
# Running 1 tests from sample
|
||||
not ok - sample::long_msg (0.00s)
|
||||
long-messages.c:4: Assertion failed: This is
|
||||
A long message
|
||||
Spawning multiple lines.
|
||||
Formatting is respected.
|
||||
TAP version 13
|
||||
1..2
|
||||
# Criterion v2.1.0
|
||||
|
||||
# Running 2 tests from misc
|
||||
ok - misc::skipped This one is skipped # SKIP test is disabled
|
||||
not ok - misc::failing Just a failing test (0.00s)
|
||||
description.c:4: Assertion failed: The expression 0 is false.
|
0
samples/tests/outputs/tap_test.sh.out.expected
Normal file
0
samples/tests/outputs/tap_test.sh.out.expected
Normal file
|
@ -0,0 +1,4 @@
|
|||
[[0;34m----[0m] [0;1mtheories_regression.c[0m:[0;31m34[0m: Assertion failed: The conditions for this assertion were not met.
|
||||
[[0;34m----[0m] Theory theory::misc failed with the following parameters: ('a', true, 1, 1, 3.14f, 3.14, "test", "other test")
|
||||
[[0;31mFAIL[0m] theory::misc
|
||||
[[0;34m====[0m] [0;1mSynthesis: Tested: [0;34m1[0;1m | Passing: [0;32m0[0;1m | Failing: [0;31m1[0;1m | Crashing: [0;31m0[0;1m [0m
|
|
@ -0,0 +1,4 @@
|
|||
[[0;34m----[0m] [0;1mtheories_regression.cc[0m:[0;31m36[0m: Assertion failed: The conditions for this assertion were not met.
|
||||
[[0;34m----[0m] Theory theory::misc failed with the following parameters: ('a', true, 1, 1, 3.14f, 3.14, "test", "other test")
|
||||
[[0;31mFAIL[0m] theory::misc
|
||||
[[0;34m====[0m] [0;1mSynthesis: Tested: [0;34m1[0;1m | Passing: [0;32m0[0;1m | Failing: [0;31m1[0;1m | Crashing: [0;31m0[0;1m [0m
|
82
samples/tests/outputs/xml_test.sh.err.expected
Normal file
82
samples/tests/outputs/xml_test.sh.err.expected
Normal file
|
@ -0,0 +1,82 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Tests compiled with Criterion v2.1.0 -->
|
||||
<testsuites name="Criterion Tests" tests="2" failures="1" errors="0" disabled="0">
|
||||
<testsuite name="misc" tests="2" failures="1" errors="0" disabled="0" skipped="0">
|
||||
<testcase name="passing" assertions="1" status="PASSED">
|
||||
</testcase>
|
||||
<testcase name="failing" assertions="1" status="FAILED">
|
||||
<failure type="assert" message="1 assertion(s) failed.">simple.c:4: The expression 0 is false. </failure>
|
||||
</testcase>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Tests compiled with Criterion v2.1.0 -->
|
||||
<testsuites name="Criterion Tests" tests="3" failures="2" errors="1" disabled="0">
|
||||
<testsuite name="simple" tests="3" failures="2" errors="1" disabled="0" skipped="0">
|
||||
<testcase name="wrong_signal" assertions="0" status="FAILED">
|
||||
<failure type="assert" message="0 assertion(s) failed."></failure>
|
||||
</testcase>
|
||||
<testcase name="uncaught" assertions="0" status="ERRORED">
|
||||
<error type="crash" message="The test crashed." /> </testcase>
|
||||
<testcase name="caught" assertions="0" status="PASSED">
|
||||
</testcase>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Tests compiled with Criterion v2.1.0 -->
|
||||
<testsuites name="Criterion Tests" tests="6" failures="2" errors="0" disabled="0">
|
||||
<testsuite name="asserts" tests="6" failures="2" errors="0" disabled="0" skipped="0">
|
||||
<testcase name="string" assertions="10" status="PASSED">
|
||||
</testcase>
|
||||
<testcase name="old_school" assertions="2" status="FAILED">
|
||||
<failure type="assert" message="2 assertion(s) failed.">asserts.c:18: The conditions for this assertion were not met. asserts.c:17: You can fail an assertion with a message from anywhere </failure>
|
||||
</testcase>
|
||||
<testcase name="native" assertions="8" status="PASSED">
|
||||
</testcase>
|
||||
<testcase name="float" assertions="2" status="PASSED">
|
||||
</testcase>
|
||||
<testcase name="base" assertions="6" status="FAILED">
|
||||
<failure type="assert" message="2 assertion(s) failed.">asserts.c:12: This assert runs asserts.c:11: assert is fatal, expect isn't </failure>
|
||||
</testcase>
|
||||
<testcase name="array" assertions="3" status="PASSED">
|
||||
</testcase>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Tests compiled with Criterion v2.1.0 -->
|
||||
<testsuites name="Criterion Tests" tests="3" failures="0" errors="0" disabled="1">
|
||||
<testsuite name="suite2" tests="1" failures="0" errors="0" disabled="0" skipped="0">
|
||||
<testcase name="test" assertions="1" status="PASSED">
|
||||
</testcase>
|
||||
</testsuite>
|
||||
<testsuite name="suite1" tests="1" failures="0" errors="0" disabled="0" skipped="0">
|
||||
<testcase name="test" assertions="1" status="PASSED">
|
||||
</testcase>
|
||||
</testsuite>
|
||||
<testsuite name="disabled" tests="1" failures="0" errors="0" disabled="1" skipped="1">
|
||||
<testcase name="test" assertions="0" status="SKIPPED">
|
||||
<skipped/>
|
||||
</testcase>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Tests compiled with Criterion v2.1.0 -->
|
||||
<testsuites name="Criterion Tests" tests="1" failures="1" errors="0" disabled="0">
|
||||
<testsuite name="sample" tests="1" failures="1" errors="0" disabled="0" skipped="0">
|
||||
<testcase name="long_msg" assertions="1" status="FAILED">
|
||||
<failure type="assert" message="1 assertion(s) failed.">long-messages.c:4: This is A long message Spawning multiple lines. Formatting is respected. </failure>
|
||||
</testcase>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Tests compiled with Criterion v2.1.0 -->
|
||||
<testsuites name="Criterion Tests" tests="2" failures="1" errors="0" disabled="1">
|
||||
<testsuite name="misc" tests="2" failures="1" errors="0" disabled="1" skipped="1">
|
||||
<testcase name="skipped" assertions="0" status="SKIPPED">
|
||||
<skipped/>
|
||||
</testcase>
|
||||
<testcase name="failing" assertions="1" status="FAILED">
|
||||
<failure type="assert" message="1 assertion(s) failed.">description.c:4: The expression 0 is false. </failure>
|
||||
</testcase>
|
||||
</testsuite>
|
||||
</testsuites>
|
0
samples/tests/outputs/xml_test.sh.out.expected
Normal file
0
samples/tests/outputs/xml_test.sh.out.expected
Normal file
|
@ -13,14 +13,14 @@ else
|
|||
sh -c "$bin_dir/$*" > $out_dir/$1.out 2> $out_dir/$1.err
|
||||
fi
|
||||
|
||||
dos2unix $out_dir/$1.err $out_dir/$1.out
|
||||
|
||||
if [ -f $cmp_dir/$1.out.expected ] && [ "$(md5sum $out_dir/$1.out | cut -d' ' -f1)" != "$(md5sum $cmp_dir/$1.out.expected | cut -d' ' -f1)" ]; then
|
||||
diff $out_dir/$1.out $cmp_dir/$1.out.expected
|
||||
exit 255
|
||||
if ! diff --strip-trailing-cr $out_dir/$1.out $cmp_dir/$1.out.expected ; then
|
||||
exit 255
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -f $cmp_dir/$1.err.expected ] && [ "$(md5sum $out_dir/$1.err | cut -d' ' -f1)" != "$(md5sum $cmp_dir/$1.err.expected | cut -d' ' -f1)" ]; then
|
||||
diff $out_dir/$1.err $cmp_dir/$1.err.expected
|
||||
exit 255
|
||||
if ! diff --strip-trailing-cr $out_dir/$1.err $cmp_dir/$1.err.expected ; then
|
||||
exit 255
|
||||
fi
|
||||
fi
|
||||
|
|
|
@ -3,5 +3,5 @@
|
|||
./signal.c.bin --tap --always-succeed
|
||||
./asserts.c.bin --tap --always-succeed
|
||||
./more-suites.c.bin --tap --always-succeed
|
||||
./long-messages.c.bin --tap --always-succeed
|
||||
./tests/long-messages.c.bin --tap --always-succeed
|
||||
./description.c.bin --tap --always-succeed
|
||||
|
|
35
samples/tests/theories_regression.c
Normal file
35
samples/tests/theories_regression.c
Normal file
|
@ -0,0 +1,35 @@
|
|||
#ifdef _MSC_VER
|
||||
#pragma warning(disable : 4090)
|
||||
#endif
|
||||
|
||||
#include <criterion/theories.h>
|
||||
|
||||
// Testing for various parameters
|
||||
|
||||
TheoryDataPoints(theory, misc) = {
|
||||
DataPoints(char, 'a'),
|
||||
DataPoints(bool, true),
|
||||
DataPoints(short, 1),
|
||||
DataPoints(int, 1),
|
||||
DataPoints(float, 3.14f),
|
||||
DataPoints(double, 3.14),
|
||||
DataPoints(char *, "test"),
|
||||
DataPoints(const char *, "other test"),
|
||||
};
|
||||
|
||||
Theory((char c, bool b, short s, int i, float f, double d, char *str, const char *cstr), theory, misc) {
|
||||
float reff = 3.14f;
|
||||
double refd = 3.14;
|
||||
|
||||
cr_assert(b);
|
||||
cr_assert_eq(c, 'a');
|
||||
cr_assert_eq(s, 1);
|
||||
cr_assert_eq(i, 1);
|
||||
cr_assert_eq(f, reff);
|
||||
cr_assert_eq(d, refd);
|
||||
cr_assert_str_eq(str, "test");
|
||||
cr_assert_str_eq(cstr, "other test");
|
||||
|
||||
// abort to see the formatted string of all parameters
|
||||
cr_assert_fail();
|
||||
}
|
37
samples/tests/theories_regression.cc
Normal file
37
samples/tests/theories_regression.cc
Normal file
|
@ -0,0 +1,37 @@
|
|||
#ifdef _MSC_VER
|
||||
#pragma warning(disable : 4090)
|
||||
#endif
|
||||
|
||||
#include <criterion/theories.h>
|
||||
|
||||
// Testing for various parameters
|
||||
|
||||
char test_str[] = {'t', 'e', 's', 't', '\0'};
|
||||
|
||||
TheoryDataPoints(theory, misc) = {
|
||||
DataPoints(char, 'a'),
|
||||
DataPoints(bool, true),
|
||||
DataPoints(short, 1),
|
||||
DataPoints(int, 1),
|
||||
DataPoints(float, 3.14f),
|
||||
DataPoints(double, 3.14),
|
||||
DataPoints(char *, test_str),
|
||||
DataPoints(const char *, "other test"),
|
||||
};
|
||||
|
||||
Theory((char c, bool b, short s, int i, float f, double d, char *str, const char *cstr), theory, misc) {
|
||||
float reff = 3.14f;
|
||||
double refd = 3.14;
|
||||
|
||||
cr_assert(b);
|
||||
cr_assert_eq(c, 'a');
|
||||
cr_assert_eq(s, 1);
|
||||
cr_assert_eq(i, 1);
|
||||
cr_assert_eq(f, reff);
|
||||
cr_assert_eq(d, refd);
|
||||
cr_assert_str_eq(str, "test");
|
||||
cr_assert_str_eq(cstr, "other test");
|
||||
|
||||
// abort to see the formatted string of all parameters
|
||||
cr_assert_fail();
|
||||
}
|
7
samples/tests/xml_test.sh
Executable file
7
samples/tests/xml_test.sh
Executable file
|
@ -0,0 +1,7 @@
|
|||
#!/bin/sh
|
||||
./simple.c.bin --xml --always-succeed
|
||||
./signal.c.bin --xml --always-succeed
|
||||
./asserts.c.bin --xml --always-succeed
|
||||
./more-suites.c.bin --xml --always-succeed
|
||||
./tests/long-messages.c.bin --xml --always-succeed
|
||||
./description.c.bin --xml --always-succeed
|
|
@ -87,14 +87,17 @@ TheoryDataPoints(theory, misc) = {
|
|||
};
|
||||
|
||||
Theory((char c, bool b, short s, int i, long l, long long ll, float f, double d, char *str, const char *cstr, struct my_object *obj), theory, misc) {
|
||||
float reff = 3.14f;
|
||||
double refd = 3.14;
|
||||
|
||||
cr_assert(b);
|
||||
cr_assert_eq(c, 'a');
|
||||
cr_assert_eq(s, 1);
|
||||
cr_assert_eq(i, 1);
|
||||
cr_assert_eq(l, 1);
|
||||
cr_assert_eq(ll, 1);
|
||||
cr_assert_eq(f, 3.14f);
|
||||
cr_assert_eq(d, 3.14);
|
||||
cr_assert_eq(f, reff);
|
||||
cr_assert_eq(d, refd);
|
||||
cr_assert_str_eq(str, "test");
|
||||
cr_assert_str_eq(cstr, "other test");
|
||||
cr_assert_eq(obj->foo, 42);
|
||||
|
@ -102,20 +105,3 @@ Theory((char c, bool b, short s, int i, long l, long long ll, float f, double d,
|
|||
// abort to see the formatted string of all parameters
|
||||
cr_assert_fail();
|
||||
}
|
||||
|
||||
// Manually generate datapoints
|
||||
|
||||
TheoryDataPoints(theory, gen) = {
|
||||
DataPoints(int, 0), // placeholder
|
||||
};
|
||||
|
||||
static void generate_datapoints(void) {
|
||||
static int arr[] = {1, 2, 3, 4, 5};
|
||||
TheoryDataPoint(theory, gen)[0].len = 5;
|
||||
TheoryDataPoint(theory, gen)[0].arr = &arr;
|
||||
}
|
||||
|
||||
Theory((int i), theory, gen, .init = generate_datapoints) {
|
||||
(void) i;
|
||||
cr_assert_fail(); // we fail to display the parameter
|
||||
}
|
||||
|
|
|
@ -95,14 +95,17 @@ TheoryDataPoints(theory, misc) = {
|
|||
};
|
||||
|
||||
Theory((char c, bool b, short s, int i, long l, long long ll, float f, double d, char *str, const char *cstr, struct my_object *obj), theory, misc) {
|
||||
float reff = 3.14f;
|
||||
double refd = 3.14;
|
||||
|
||||
cr_assert(b);
|
||||
cr_assert_eq(c, 'a');
|
||||
cr_assert_eq(s, 1);
|
||||
cr_assert_eq(i, 1);
|
||||
cr_assert_eq(l, 1);
|
||||
cr_assert_eq(ll, 1);
|
||||
cr_assert_eq(f, 3.14f);
|
||||
cr_assert_eq(d, 3.14);
|
||||
cr_assert_eq(f, reff);
|
||||
cr_assert_eq(d, refd);
|
||||
cr_assert_str_eq(str, "test");
|
||||
cr_assert_str_eq(cstr, "other test");
|
||||
cr_assert_eq(obj->foo, 42);
|
||||
|
@ -110,20 +113,3 @@ Theory((char c, bool b, short s, int i, long l, long long ll, float f, double d,
|
|||
// abort to see the formatted string of all parameters
|
||||
cr_assert_fail();
|
||||
}
|
||||
|
||||
// Manually generate datapoints
|
||||
|
||||
TheoryDataPoints(theory, gen) = {
|
||||
DataPoints(int, 0), // placeholder
|
||||
};
|
||||
|
||||
static void generate_datapoints(void) {
|
||||
static int arr[] = {1, 2, 3, 4, 5};
|
||||
TheoryDataPoint(theory, gen)[0].len = 5;
|
||||
TheoryDataPoint(theory, gen)[0].arr = &arr;
|
||||
}
|
||||
|
||||
Theory((int i), theory, gen, .init = generate_datapoints) {
|
||||
(void) i;
|
||||
cr_assert_fail(); // we fail to display the parameter
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
*/
|
||||
#include "alloc.h"
|
||||
#include "internal.h"
|
||||
#include "criterion/logging.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef VANILLA_WIN32
|
||||
|
@ -51,7 +52,7 @@ void init_inheritable_heap(void) {
|
|||
HeapDestroy(h->handle);
|
||||
|
||||
if (g_heap == (HANDLE) NULL) {
|
||||
fputs("Could not create the private inheritable heap.", stderr);
|
||||
criterion_perror("Could not create the private inheritable heap.\n");
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,7 +30,22 @@
|
|||
# undef _WIN32_WINNT
|
||||
# define _WIN32_WINNT 0x0502
|
||||
# include <windows.h>
|
||||
|
||||
# if defined(MINGW_DEFINE_OFF_T) && (defined(__MINGW32__) || defined(__MINGW64__))
|
||||
# include "off_t.h"
|
||||
|
||||
# if !defined(__MINGW64__)
|
||||
# define off_t cr_off32
|
||||
# else
|
||||
# define off_t cr_off64
|
||||
# endif
|
||||
# define off64_t cr_off64
|
||||
# endif
|
||||
# include <io.h>
|
||||
# if defined(MINGW_DEFINE_OFF_T) && (defined(__MINGW32__) || defined(__MINGW64__))
|
||||
# undef off_t
|
||||
# undef off64_t
|
||||
# endif
|
||||
# include <fcntl.h>
|
||||
# include <winnt.h>
|
||||
# include <stdint.h>
|
||||
|
@ -40,6 +55,15 @@
|
|||
# include <sys/wait.h>
|
||||
# include <sys/signal.h>
|
||||
# include <sys/fcntl.h>
|
||||
# include <sys/param.h>
|
||||
# ifdef BSD
|
||||
# include <sys/types.h>
|
||||
typedef unsigned long u_long;
|
||||
typedef unsigned int u_int;
|
||||
typedef unsigned short u_short;
|
||||
typedef unsigned char u_char;
|
||||
# include <sys/sysctl.h>
|
||||
# endif
|
||||
# endif
|
||||
|
||||
# include "posix.h"
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue